diff --git a/.clang-format b/.clang-format index b01602a2b92af..07513306ec3a8 100644 --- a/.clang-format +++ b/.clang-format @@ -16,6 +16,19 @@ PointerAlignment: Right # of a comment block to protect comments as # per STYLE.md CommentPragmas: '(^ IWYU pragma:|^\*$|^-$)' +ForEachMacros: + - "OSSL_LIST_FOREACH" + - "OSSL_LIST_FOREACH_FROM" + - "OSSL_LIST_FOREACH_REV" + - "OSSL_LIST_FOREACH_REV_FROM" + - "OSSL_LIST_FOREACH_DELSAFE" + - "OSSL_LIST_FOREACH_DELSAFE_FROM" + - "OSSL_LIST_FOREACH_REV_DELSAFE" + - "OSSL_LIST_FOREACH_REV_DELSAFE_FROM" + - "OSSL_RBT_FOREACH" + - "OSSL_RBT_FOREACH_SAFE" + - "OSSL_RBT_FOREACH_REVERSE" + - "OSSL_RBT_FOREACH_REVERSE_SAFE" # OpenSSL uses typedefs extensively. Tell clang-format about them. TypeNames: - "ACCESS_DESCRIPTION" @@ -1129,7 +1142,14 @@ TypeNames: - "HASH_LONG" - "MD32_REG_T" # OpenSSL uses macros extensively. Tell clang-format about them. -TypenameMacros: ['LHASH_OF', 'STACK_OF'] +TypenameMacros: + - "LHASH_OF" + - "OSSL_LIST" + - "OSSL_RBT_ENTRY" + - "OSSL_RBT_HEAD" + - "PRIORITY_QUEUE_OF" + - "SPARSE_ARRAY_OF" + - "STACK_OF" StatementMacros: - "BLOCK_CIPHER_aead" - "BLOCK_CIPHER_generic" @@ -1365,6 +1385,7 @@ StatementMacros: - "ASN1_SEQUENCE_END_enc" - "ASN1_SEQUENCE_END_name" - "ASN1_SEQUENCE_END_ref" + - "k2d_NOCTX" - "make_dh" - "make_dh_bn" - "static_ASN1_CHOICE_END" diff --git a/.codespellrc b/.codespellrc index df3d6768436bf..4018a6a15bcdd 100644 --- a/.codespellrc +++ b/.codespellrc @@ -258,6 +258,7 @@ ignore-words-list = requestor, Requestor, requestors, + REQUIREDs, rewinded, roperties, sav, diff --git a/.github/workflows/aarch64-more-cross-compiles.yml b/.github/workflows/aarch64-more-cross-compiles.yml index 13fdef3925a8e..8f9ca5f6268dd 100644 --- a/.github/workflows/aarch64-more-cross-compiles.yml +++ b/.github/workflows/aarch64-more-cross-compiles.yml @@ -14,11 +14,42 @@ on: schedule: - cron: '05 03 * * *' workflow_dispatch: + inputs: + pr: + description: 'Internal: openssl-ci-bot PR number. Leave empty for a normal manual run.' + required: false + type: string + head_sha: + description: 'Internal: openssl-ci-bot commit SHA. Leave empty for a normal manual run.' + required: false + type: string + check_run_id: + description: 'Internal: openssl-ci-bot check-run ID. Leave empty for a normal manual run.' + required: false + type: string + +# Keep in sync with openssl-ci-bot's run-name parser, and with the Actions statistics +# collector that attributes CI load by parsing this same string. Both break silently. +run-name: >- + ${{ github.event.inputs.pr && format('ci-dispatch pr={0} head={1} check_run_id={2}', github.event.inputs.pr, github.event.inputs.head_sha, github.event.inputs.check_run_id) || github.workflow }} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.inputs.pr || github.run_id }} + cancel-in-progress: true permissions: contents: read jobs: + # Only a dispatch carries inputs, so this is skipped on every other trigger. + validate-dispatch-inputs: + if: inputs.pr != '' || inputs.head_sha != '' || inputs.check_run_id != '' + uses: ./.github/workflows/validate-dispatch-inputs.yml + with: + pr: ${{ inputs.pr }} + head_sha: ${{ inputs.head_sha }} + check_run_id: ${{ inputs.check_run_id }} + cross-compilation-aarch64: # pull request title contains 'aarch64' # pull request title contains 'arm64' @@ -26,7 +57,11 @@ jobs: # push event commit message contains '[aarch64 ci]' # cron job # manual dispatch - if: contains(github.event.pull_request.title, 'aarch64') || contains(github.event.pull_request.title, 'AArch64') || contains(github.event.pull_request.title, 'arm64') || contains(github.event.pull_request.body, '[aarch64 ci]') || contains(github.event.head_commit.message, '[aarch64 ci]') || (github.event_name == 'schedule' && github.repository == 'openssl/openssl') || github.event_name == 'workflow_dispatch' + needs: [validate-dispatch-inputs] + if: >- + (contains(github.event.pull_request.title, 'aarch64') || contains(github.event.pull_request.title, 'AArch64') || contains(github.event.pull_request.title, 'arm64') || contains(github.event.pull_request.body, '[aarch64 ci]') || contains(github.event.head_commit.message, '[aarch64 ci]') || (github.event_name == 'schedule' && github.repository == 'openssl/openssl') || github.event_name == 'workflow_dispatch') && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') strategy: fail-fast: false matrix: @@ -134,6 +169,7 @@ jobs: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora @@ -165,8 +201,8 @@ jobs: - name: Set OpenSSL caps environment if: matrix.platform.opensslcapsname != '' - run: echo "OPENSSL_${{ matrix.platform.opensslcapsname }}=\ - ${{ matrix.platform.opensslcaps }}" >> $GITHUB_ENV + run: | + echo "OPENSSL_${{ matrix.platform.opensslcapsname }}=${{ matrix.platform.opensslcaps }}" >> "$GITHUB_ENV" - name: get cpu info run: cat /proc/cpuinfo @@ -175,20 +211,24 @@ jobs: if: matrix.platform.tests != 'none' run: QEMU_LD_PREFIX=/usr/${{ matrix.platform.arch }} ./util/opensslwrap.sh info -cpusettings + # A dispatched run, and a pull request that opts in with `[aarch64 ci]` in its body, take the + # push tier: both exist to run pre-merge what otherwise only runs post-merge, and evp-only + # is the weaker signal. A pull request that only matches on its title keeps the evp tier. + # Legs setting `tests: none` stay build-only on every trigger, by design. - name: make all tests - if: github.event_name == 'push' && matrix.platform.tests == '' + if: (github.event_name == 'push' || inputs.pr != '' || contains(github.event.pull_request.body, '[aarch64 ci]')) && matrix.platform.tests == '' run: | .github/workflows/make-test \ TESTS="-test_afalg" \ QEMU_LD_PREFIX=/usr/${{ matrix.platform.arch }} - name: make some tests - if: github.event_name == 'push' && matrix.platform.tests != 'none' && matrix.platform.tests != '' + if: (github.event_name == 'push' || inputs.pr != '' || contains(github.event.pull_request.body, '[aarch64 ci]')) && matrix.platform.tests != 'none' && matrix.platform.tests != '' run: | .github/workflows/make-test \ TESTS="${{ matrix.platform.tests }} -test_afalg" \ QEMU_LD_PREFIX=/usr/${{ matrix.platform.arch }} - name: make evp tests - if: github.event_name == 'pull_request' && matrix.platform.tests != 'none' + if: github.event_name == 'pull_request' && !contains(github.event.pull_request.body, '[aarch64 ci]') && matrix.platform.tests != 'none' run: | .github/workflows/make-test \ TESTS="test_evp*" \ @@ -200,3 +240,35 @@ jobs: name: "cross-compiles-aarch64@${{ matrix.platform.capslabel }}" path: artifacts.tar.gz if-no-files-found: ignore + + gcs-validation-aarch64: + # pull request title contains 'aarch64' + # pull request title contains 'arm64' + # pull request body contains '[aarch64 ci]' + # push event commit message contains '[aarch64 ci]' + # cron job + # manual dispatch + needs: [validate-dispatch-inputs] + if: >- + (contains(github.event.pull_request.title, 'aarch64') || contains(github.event.pull_request.title, 'AArch64') || contains(github.event.pull_request.title, 'arm64') || contains(github.event.pull_request.body, '[aarch64 ci]') || contains(github.event.head_commit.message, '[aarch64 ci]') || (github.event_name == 'schedule' && github.repository == 'openssl/openssl') || github.event_name == 'workflow_dispatch') && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') + runs-on: ubuntu-26.04-arm + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} + - name: print tool versions + run: | + gcc --version + ld --version + - name: config + run: | + CFLAGS='-mbranch-protection=standard' \ + LDFLAGS='-Wl,-z,gcs=always -Wl,-z,gcs-report=error' \ + ./config --strict-warnings enable-demos enable-fips enable-lms enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-trace --banner=Configured + - name: config dump + run: ./configdata.pm --dump + - name: make + run: make -j4 diff --git a/.github/workflows/avx512-sde.yml b/.github/workflows/avx512-sde.yml index 1b94df992236c..db108cdc09188 100644 --- a/.github/workflows/avx512-sde.yml +++ b/.github/workflows/avx512-sde.yml @@ -22,6 +22,28 @@ on: schedule: - cron: '30 02 * * *' workflow_dispatch: + inputs: + pr: + description: 'Internal: openssl-ci-bot PR number. Leave empty for a normal manual run.' + required: false + type: string + head_sha: + description: 'Internal: openssl-ci-bot commit SHA. Leave empty for a normal manual run.' + required: false + type: string + check_run_id: + description: 'Internal: openssl-ci-bot check-run ID. Leave empty for a normal manual run.' + required: false + type: string + +# Keep in sync with openssl-ci-bot's run-name parser, and with the Actions statistics +# collector that attributes CI load by parsing this same string. Both break silently. +run-name: >- + ${{ github.event.inputs.pr && format('ci-dispatch pr={0} head={1} check_run_id={2}', github.event.inputs.pr, github.event.inputs.head_sha, github.event.inputs.check_run_id) || github.workflow }} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.inputs.pr || github.run_id }} + cancel-in-progress: true permissions: contents: read @@ -32,12 +54,26 @@ env: SDE_MIRROR_ID: 915934 jobs: + # Only a dispatch carries inputs, so this is skipped on the nightly cron. + validate-dispatch-inputs: + if: inputs.pr != '' || inputs.head_sha != '' || inputs.check_run_id != '' + uses: ./.github/workflows/validate-dispatch-inputs.yml + with: + pr: ${{ inputs.pr }} + head_sha: ${{ inputs.head_sha }} + check_run_id: ${{ inputs.check_run_id }} + linux: + needs: [validate-dispatch-inputs] + if: | + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: install NASM run: sudo apt-get install -y nasm @@ -71,10 +107,17 @@ jobs: - name: sha3_x4_internal_test (AVX512 via SDE) run: sde64 -icx -- ./test/sha3_x4_internal_test + - name: evp_extra_test (AVX512 via SDE) + run: sde64 -icx -- ./test/evp_extra_test + - name: fipsinstall (FIPS KAT via SDE) run: sde64 -icx -- ./apps/openssl fipsinstall -module ./providers/fips.so -out /tmp/fipsmodule.cnf -provider_name fips windows: + needs: [validate-dispatch-inputs] + if: | + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: windows-2022 env: VCVARS: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat @@ -82,6 +125,7 @@ jobs: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: install nasm if: github.repository == 'openssl/openssl' @@ -161,6 +205,11 @@ jobs: shell: cmd run: sde -icx -- test\sha3_x4_internal_test.exe + - name: evp_extra_test (AVX512 via SDE) + working-directory: _build + shell: cmd + run: sde -icx -- test\evp_extra_test.exe + - name: fipsinstall (FIPS KAT via SDE) working-directory: _build shell: cmd diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 86a53a2abaebb..dd9075f7b4047 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -7,11 +7,17 @@ name: Backports CI -on: [pull_request] +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] permissions: contents: read +concurrency: + group: backports-${{ github.event.pull_request.number }} + cancel-in-progress: true + jobs: check_backports: strategy: @@ -19,6 +25,9 @@ jobs: matrix: release: [ { + branch: '4.1', + cppflags: '' + }, { branch: '4.0', cppflags: '' }, { @@ -30,9 +39,6 @@ jobs: }, { branch: '3.4', cppflags: 'CPPFLAGS=-ansi' - }, { - branch: '3.0', - cppflags: 'CPPFLAGS=-ansi' } ] runs-on: ubuntu-latest diff --git a/.github/workflows/ci-doc-changes.yml b/.github/workflows/ci-doc-changes.yml new file mode 100644 index 0000000000000..08919fc323ecf --- /dev/null +++ b/.github/workflows/ci-doc-changes.yml @@ -0,0 +1,125 @@ +# Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +name: Documentation and Installability CI + +on: [pull_request, push] + +permissions: + contents: read + +env: + OSSL_RUN_CI_TESTS: 1 + +jobs: + check_docs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + - name: config + run: ./config --strict-warnings --banner=Configured enable-fips && perl configdata.pm --dump + - name: make build_generated + run: make -s build_generated + - name: make doc-nits + run: make doc-nits + - name: make help + run: make help + - name: make md-nits + run: | + sudo gem install mdl + make md-nits + + # out-of-source-and-install checks multiple things at the same time: + # - That building, testing and installing works from an out-of-source + # build tree + # - That building, testing and installing works with a read-only source + # tree + out-of-readonly-source-and-install-ubuntu: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + path: ./source + persist-credentials: false + - name: checkout fuzz/corpora submodule + run: git submodule update --init --depth 1 fuzz/corpora + working-directory: ./source + - name: make source read-only + run: chmod -R a-w ./source + - name: create build and install directories + run: | + mkdir ./build + mkdir ./install + - name: config + run: | + ../source/config --banner=Configured enable-demos enable-h3demo enable-fips enable-lms enable-quic enable-acvp-tests --strict-warnings --prefix=$(cd ../install; pwd) + perl configdata.pm --dump + working-directory: ./build + - name: make + run: make -s -j4 + working-directory: ./build + - name: get cpu info + run: | + cat /proc/cpuinfo + ./util/opensslwrap.sh version -c + working-directory: ./build + - name: make test + run: ../source/.github/workflows/make-test + working-directory: ./build + - name: save artifacts + if: success() || failure() + uses: actions/upload-artifact@v5 + with: + name: "ci@out-of-readonly-source-and-install-ubuntu" + path: build/artifacts.tar.gz + - name: make install + run: make install + working-directory: ./build + + out-of-readonly-source-and-install-macos: + runs-on: macos-15 + steps: + - uses: actions/checkout@v6 + with: + path: ./source + persist-credentials: false + - name: checkout fuzz/corpora submodule + run: git submodule update --init --depth 1 fuzz/corpora + working-directory: ./source + - name: make source read-only + run: chmod -R a-w ./source + - name: create build and install directories + run: | + mkdir ./build + mkdir ./install + - name: config + run: | + ../source/config --banner=Configured enable-fips enable-lms enable-demos enable-h3demo enable-quic enable-acvp-tests --strict-warnings --prefix=$(cd ../install; pwd) + perl configdata.pm --dump + working-directory: ./build + - name: make + run: make -s -j4 + working-directory: ./build + - name: get cpu info + run: | + sysctl machdep.cpu + ./util/opensslwrap.sh version -c + working-directory: ./build + - name: make test + run: ../source/.github/workflows/make-test + working-directory: ./build + - name: save artifacts + if: success() || failure() + uses: actions/upload-artifact@v5 + with: + name: "ci@out-of-readonly-source-and-install-macos-15" + path: build/artifacts.tar.gz + - name: make install + run: make install + working-directory: ./build diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 597501112fb41..8111bced097fd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,25 @@ name: GitHub CI -on: [pull_request, push] +on: + pull_request: + paths-ignore: + - 'doc/**' + - '*.md' + - '*.pod' + - 'README*' + - 'funding.json' + - 'LICENSE.txt' + - 'VERSION.dat' + push: + paths-ignore: + - 'doc/**' + - '*.md' + - '*.pod' + - 'README*' + - 'funding.json' + - 'LICENSE.txt' + - 'VERSION.dat' # for some reason, this does not work: # variables: @@ -45,25 +63,6 @@ jobs: - name: git diff run: git diff --exit-code - check_docs: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: config - run: ./config --strict-warnings --banner=Configured enable-fips && perl configdata.pm --dump - - name: make build_generated - run: make -s build_generated - - name: make doc-nits - run: make doc-nits - - name: make help - run: make help - - name: make md-nits - run: | - sudo gem install mdl - make md-nits - # This checks that we use ANSI C language syntax and semantics. # We are not as strict with libraries, but rather adapt to what's # expected to be available in a certain version of each platform. @@ -90,6 +89,17 @@ jobs: run: sudo locale-gen tr_TR.UTF-8 - name: cmocka run: sudo apt-get -y install libcmocka-dev + - name: install dependencies for perl Net::Curl + run: | + sudo apt-get update + sudo apt-get -y install libcurl4-openssl-dev cpanminus build-essential + - name: install Net::Curl + run: | + url=https://cpan.metacpan.org/authors/id/S/SY/SYP/Net-Curl-0.58.tar.gz + sha=37c1585cc70e21579c7c733e306e97a46adc093a3777af6d8ba37d73986d7f5a + curl -fsSL "$url" -o Net-Curl.tar.gz + echo "$sha Net-Curl.tar.gz" | sha256sum -c - + sudo cpanm --notest ./Net-Curl.tar.gz - name: fipsvendor # Make one fips build use a customized FIPS vendor run: echo "FIPS_VENDOR=CI" >> VERSION.dat @@ -237,33 +247,33 @@ jobs: with: persist-credentials: false - name: config - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 + uses: cross-platform-actions/action@faa0c6197e94aacf1c5956460152c8380d3560a5 #v1.5.0 with: operating_system: freebsd - version: "13.4" + version: "14.4" shutdown_vm: false run: | sudo pkg install -y gcc perl5 ./config --strict-warnings enable-fips enable-lms enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-trace - name: config dump - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 + uses: cross-platform-actions/action@faa0c6197e94aacf1c5956460152c8380d3560a5 #v1.5.0 with: operating_system: freebsd - version: "13.4" + version: "14.4" shutdown_vm: false run: ./configdata.pm --dump - name: make - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 + uses: cross-platform-actions/action@faa0c6197e94aacf1c5956460152c8380d3560a5 #v1.5.0 with: operating_system: freebsd - version: "13.4" + version: "14.4" shutdown_vm: false run: make -j4 - name: make test - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 + uses: cross-platform-actions/action@faa0c6197e94aacf1c5956460152c8380d3560a5 #v1.5.0 with: operating_system: freebsd - version: "13.4" + version: "14.4" run: | ./util/opensslwrap.sh version -c .github/workflows/make-test @@ -464,13 +474,20 @@ jobs: fuzz_tests_mfail: runs-on: ubuntu-latest - timeout-minutes: 30 + timeout-minutes: 15 steps: - uses: actions/checkout@v6 with: persist-credentials: false - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora + - name: trim corpora to a few seeds per fuzzer + env: + FUZZ_CORPUS_KEEP: 5 + run: | + for d in fuzz/corpora/*/; do + find "$d" -maxdepth 1 -type f | tail -n +$((FUZZ_CORPUS_KEEP + 1)) | xargs -r rm -f + done - name: Adjust ASLR for sanitizer run: sudo sysctl -w vm.mmap_rnd_bits=28 - name: config @@ -484,9 +501,6 @@ jobs: - name: make run: make -s -j4 - name: make test (fuzz with mfail) - env: - OSSL_FUZZ_TEST_BUDGET: 1200 - OSSL_FUZZ_TEST_JOBS: 4 run: .github/workflows/make-test OPENSSL_TEST_RAND_ORDER=0 TESTS="test_fuzz*" - name: save artifacts if: success() || failure() @@ -665,95 +679,6 @@ jobs: name: "ci@legacy" path: artifacts.tar.gz - # out-of-source-and-install checks multiple things at the same time: - # - That building, testing and installing works from an out-of-source - # build tree - # - That building, testing and installing works with a read-only source - # tree - out-of-readonly-source-and-install-ubuntu: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - path: ./source - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - working-directory: ./source - - name: make source read-only - run: chmod -R a-w ./source - - name: create build and install directories - run: | - mkdir ./build - mkdir ./install - - name: config - run: | - ../source/config --banner=Configured enable-demos enable-h3demo enable-fips enable-lms enable-quic enable-acvp-tests --strict-warnings --prefix=$(cd ../install; pwd) - perl configdata.pm --dump - working-directory: ./build - - name: make - run: make -s -j4 - working-directory: ./build - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - working-directory: ./build - - name: make test - run: ../source/.github/workflows/make-test - working-directory: ./build - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@out-of-readonly-source-and-install-ubuntu" - path: build/artifacts.tar.gz - - name: make install - run: make install - working-directory: ./build - - out-of-readonly-source-and-install-macos: - runs-on: macos-15 - steps: - - uses: actions/checkout@v6 - with: - path: ./source - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - working-directory: ./source - - name: make source read-only - run: chmod -R a-w ./source - - name: create build and install directories - run: | - mkdir ./build - mkdir ./install - - name: config - run: | - ../source/config --banner=Configured enable-fips enable-lms enable-demos enable-h3demo enable-quic enable-acvp-tests --strict-warnings --prefix=$(cd ../install; pwd) - perl configdata.pm --dump - working-directory: ./build - - name: make - run: make -s -j4 - working-directory: ./build - - name: get cpu info - run: | - sysctl machdep.cpu - ./util/opensslwrap.sh version -c - working-directory: ./build - - name: make test - run: ../source/.github/workflows/make-test - working-directory: ./build - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@out-of-readonly-source-and-install-macos-15" - path: build/artifacts.tar.gz - - name: make install - run: make install - working-directory: ./build - external-tests-misc: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/compiler-zoo.yml b/.github/workflows/compiler-zoo.yml index 6422733a4363d..72d42a9883bd7 100644 --- a/.github/workflows/compiler-zoo.yml +++ b/.github/workflows/compiler-zoo.yml @@ -7,13 +7,52 @@ name: Compiler Zoo CI -on: [push] +on: + push: + workflow_dispatch: + inputs: + pr: + description: 'Internal: openssl-ci-bot PR number. Leave empty for a normal manual run.' + required: false + type: string + head_sha: + description: 'Internal: openssl-ci-bot commit SHA. Leave empty for a normal manual run.' + required: false + type: string + check_run_id: + description: 'Internal: openssl-ci-bot check-run ID. Leave empty for a normal manual run.' + required: false + type: string + +# Keep in sync with openssl-ci-bot's run-name parser, and with the Actions statistics +# collector that attributes CI load by parsing this same string. Both break silently. +run-name: >- + ${{ github.event.inputs.pr && format('ci-dispatch pr={0} head={1} check_run_id={2}', github.event.inputs.pr, github.event.inputs.head_sha, github.event.inputs.check_run_id) || github.workflow }} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.inputs.pr || github.run_id }} + cancel-in-progress: true permissions: contents: read jobs: + # Only a dispatch carries inputs, so this is skipped on a push. No repository clause: + # the build jobs below keep running in forks on push, and the validator must not claim + # a boundary they do not have. + validate-dispatch-inputs: + if: inputs.pr != '' || inputs.head_sha != '' || inputs.check_run_id != '' + uses: ./.github/workflows/validate-dispatch-inputs.yml + with: + pr: ${{ inputs.pr }} + head_sha: ${{ inputs.head_sha }} + check_run_id: ${{ inputs.check_run_id }} + gcc: + needs: [validate-dispatch-inputs] + if: | + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') strategy: fail-fast: false matrix: @@ -27,6 +66,7 @@ jobs: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: config @@ -45,7 +85,71 @@ jobs: - name: make test run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} + vs2013: + needs: [validate-dispatch-inputs] + if: | + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') + strategy: + fail-fast: false + matrix: + include: + - arch: amd64 + target: VC-WIN64A-MSVC2013 + config: no-makedepend no-shared enable-fips -DOSSL_WINCTX=openssl + - arch: x86 + target: VC-WIN32-MSVC2013 + config: no-makedepend enable-fips -DOSSL_WINCTX=openssl + runs-on: windows-2022 + env: + IMAGE: ghcr.io/openssl/openssl-vs2013:latest + VCVARS: C:\vc12\vcvars_${{ matrix.arch }}.cmd + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} + - name: checkout fuzz/corpora submodule + run: git submodule update --init --depth 1 fuzz/corpora + - name: pull the VS2013 toolchain image + shell: cmd + run: docker pull %IMAGE% + - name: config + run: | + $chain = @( + # 'call', not a bare invocation: cmd does not necessarily return from a + # batch file run without it, which would skip the rest of the chain. + "call $env:VCVARS" + 'mkdir _build' + 'cd _build' + "perl ..\Configure ${{ matrix.target }} --banner=Configured ${{ matrix.config }}" + 'perl configdata.pm --dump' + ) -join ' && ' + docker run --rm --isolation=process -v "${env:GITHUB_WORKSPACE}:C:\src" ` + -w C:\src ${env:IMAGE} cmd /S /C $chain + - name: make + run: | + $chain = @( + "call $env:VCVARS" + 'jom /j4 /S' + 'apps\openssl.exe version -c' + ) -join ' && ' + docker run --rm --isolation=process -v "${env:GITHUB_WORKSPACE}:C:\src" ` + -w C:\src\_build ${env:IMAGE} cmd /S /C $chain + - name: make test + run: | + $chain = @( + "call $env:VCVARS" + 'jom test VERBOSE_FAILURE=yes TESTS=-test_fuzz* HARNESS_JOBS=4' + ) -join ' && ' + docker run --rm --isolation=process -v "${env:GITHUB_WORKSPACE}:C:\src" ` + -w C:\src\_build ${env:IMAGE} cmd /S /C $chain + clang: + needs: [validate-dispatch-inputs] + if: | + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') strategy: fail-fast: false matrix: @@ -63,6 +167,7 @@ jobs: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: config diff --git a/.github/workflows/coveralls.yml b/.github/workflows/coveralls.yml index 34075a356608e..181445b09d28f 100644 --- a/.github/workflows/coveralls.yml +++ b/.github/workflows/coveralls.yml @@ -48,6 +48,9 @@ jobs: [{ "branch": "master", "extra_config": "enable-fips enable-tfo enable-lms enable-crypto-mdebug enable-unit-tests" + }, { + "branch": "openssl-4.1", + "extra_config": "enable-fips enable-tfo enable-lms enable-crypto-mdebug enable-unit-tests" }, { "branch": "openssl-4.0", "extra_config": "enable-fips enable-tfo enable-lms enable-crypto-mdebug" @@ -60,9 +63,6 @@ jobs: },{ "branch": "openssl-3.4", "extra_config": "no-afalgeng enable-fips enable-tfo" - }, { - "branch": "openssl-3.0", - "extra_config": "no-afalgeng enable-fips" }] EOF ) @@ -111,7 +111,7 @@ jobs: cat /proc/cpuinfo ./util/opensslwrap.sh version -c - name: make test - run: make test TESTS='-test_external_krb5' EVP_TEST_EXTENDED=1 + run: make test TESTS='-test_external_krb5' EVP_TEST_EXTENDED=1 OPENSSL_TEST_TIMEOUT=0 - name: generate coverage info run: lcov -d . -c --exclude "${PWD}/test/*" diff --git a/.github/workflows/cross-compiles.yml b/.github/workflows/cross-compiles.yml index 3e1fbc142d87f..9f32de5232c1f 100644 --- a/.github/workflows/cross-compiles.yml +++ b/.github/workflows/cross-compiles.yml @@ -7,7 +7,26 @@ name: Cross Compile -on: [pull_request, push] +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + paths-ignore: + - 'doc/**' + - '*.md' + - '*.pod' + - 'README*' + - 'funding.json' + - 'LICENSE.txt' + - 'VERSION.dat' + push: + paths-ignore: + - 'doc/**' + - '*.md' + - '*.pod' + - 'README*' + - 'funding.json' + - 'LICENSE.txt' + - 'VERSION.dat' permissions: contents: read @@ -78,7 +97,7 @@ jobs: # with -O2 on this platform, reduce optimization to -01 arch: hppa-linux-gnu, libs: libc6-dev-hppa-cross, - target: -static -O1 linux-generic32, + target: -static -O1 -mlong-calls linux-generic32, fips: no, tests: -test_includes -test_store -test_x509_store }, { @@ -111,6 +130,10 @@ jobs: fips: no }, { arch: riscv64-linux-gnu, + # Pin the vector spec version, otherwise qemu-user emits a + # "vector version is not specified" warning on stderr at every + # process start, which upsets tests that parse or check stderr. + qemucpu: "rv64,v=true,vext_spec=v1.0", libs: libc6-dev-riscv64-cross, target: linux64-riscv64, fips: no @@ -206,8 +229,8 @@ jobs: - name: Set OpenSSL caps environment if: matrix.platform.opensslcapsname != '' - run: echo "OPENSSL_${{ matrix.platform.opensslcapsname }}=\ - ${{ matrix.platform.opensslcaps }}" >> $GITHUB_ENV + run: | + echo "OPENSSL_${{ matrix.platform.opensslcapsname }}=${{ matrix.platform.opensslcaps }}" >> "$GITHUB_ENV" - name: get cpu info if: matrix.platform.tests != 'none' diff --git a/.github/workflows/ct-validation-daily.yml b/.github/workflows/ct-validation-daily.yml index 18d8911fcb92f..4d88dfc9cfaba 100644 --- a/.github/workflows/ct-validation-daily.yml +++ b/.github/workflows/ct-validation-daily.yml @@ -40,13 +40,49 @@ on: schedule: - cron: '45 03 * * *' workflow_dispatch: + inputs: + pr: + description: 'Internal: openssl-ci-bot PR number. Leave empty for a normal manual run.' + required: false + type: string + head_sha: + description: 'Internal: openssl-ci-bot commit SHA. Leave empty for a normal manual run.' + required: false + type: string + check_run_id: + description: 'Internal: openssl-ci-bot check-run ID. Leave empty for a normal manual run.' + required: false + type: string + +# Keep in sync with openssl-ci-bot's run-name parser, and with the Actions statistics +# collector that attributes CI load by parsing this same string. Both break silently. +run-name: >- + ${{ github.event.inputs.pr && format('ci-dispatch pr={0} head={1} check_run_id={2}', github.event.inputs.pr, github.event.inputs.head_sha, github.event.inputs.check_run_id) || github.workflow }} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.inputs.pr || github.run_id }} + cancel-in-progress: true permissions: contents: read jobs: + validate-dispatch-inputs: + if: | + github.repository == 'openssl/openssl' && + (inputs.pr != '' || inputs.head_sha != '' || inputs.check_run_id != '') + uses: ./.github/workflows/validate-dispatch-inputs.yml + with: + pr: ${{ inputs.pr }} + head_sha: ${{ inputs.head_sha }} + check_run_id: ${{ inputs.check_run_id }} + ct-validation: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') strategy: fail-fast: false matrix: @@ -78,6 +114,7 @@ jobs: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: Install valgrind # On Debian/Ubuntu the main 'valgrind' package includes @@ -104,7 +141,14 @@ jobs: # - memcmp: test_crypto_memcmp # - ML-KEM: test_internal_ml_kem # - ML-DSA: test_internal_ml_dsa + # + # Also covered: + # - test_ct_validation_helpers: The Valgrind-based constant-time + # validation helpers from constant_time.h, like CONSTTIME_SECRET and + # CONSTTIME_DECLASSIFY + # - test_asn1_string_poison: memcheck reports C-string use of + # ASN1_STRING data, whose NUL terminator libcrypto marks inaccessible run: | - make TESTS="test_internal_ml_kem test_internal_ml_dsa test_crypto_memcmp" \ + make TESTS="test_internal_ml_kem test_internal_ml_dsa test_crypto_memcmp test_ct_validation_helpers test_asn1_string_poison" \ OSSL_VALGRIND_CT=yes \ test diff --git a/.github/workflows/deploy-docs-openssl-org.yml b/.github/workflows/deploy-docs-openssl-org.yml index e3fd909bc6c09..d03fbd087badf 100644 --- a/.github/workflows/deploy-docs-openssl-org.yml +++ b/.github/workflows/deploy-docs-openssl-org.yml @@ -3,7 +3,11 @@ name: "Trigger docs.openssl.org deployment" on: push: branches: - - "openssl-3.[0-9]+" + - "openssl-3.4" + - "openssl-3.5" + - "openssl-3.6" + - "openssl-4.0" + - "openssl-4.1" - "master" paths: - "doc/man*/**" diff --git a/.github/workflows/fips-checksums.yml b/.github/workflows/fips-checksums.yml index f82a604ab74ed..5fd96b31596c6 100644 --- a/.github/workflows/fips-checksums.yml +++ b/.github/workflows/fips-checksums.yml @@ -6,7 +6,16 @@ # https://www.openssl.org/source/license.html name: FIPS Check and ABIDIFF -on: [pull_request] +on: + pull_request: + paths-ignore: + - 'doc/**' + - '*.md' + - '*.pod' + - 'README*' + - 'funding.json' + - 'LICENSE.txt' + - 'VERSION.dat' permissions: contents: read diff --git a/.github/workflows/interop-tests.yml b/.github/workflows/interop-tests.yml index 65e273f0e08c0..0c8ce443acc4a 100644 --- a/.github/workflows/interop-tests.yml +++ b/.github/workflows/interop-tests.yml @@ -8,12 +8,51 @@ on: schedule: - cron: '55 02 * * *' workflow_dispatch: + inputs: + pr: + description: 'Internal: openssl-ci-bot PR number. Leave empty for a normal manual run.' + required: false + type: string + head_sha: + description: 'Internal: openssl-ci-bot commit SHA. Leave empty for a normal manual run.' + required: false + type: string + check_run_id: + description: 'Internal: openssl-ci-bot check-run ID. Leave empty for a normal manual run.' + required: false + type: string + +# Keep in sync with openssl-ci-bot's run-name parser, and with the Actions statistics +# collector that attributes CI load by parsing this same string. Both break silently. +run-name: >- + ${{ github.event.inputs.pr && format('ci-dispatch pr={0} head={1} check_run_id={2}', github.event.inputs.pr, github.event.inputs.head_sha, github.event.inputs.check_run_id) || github.workflow }} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.inputs.pr || github.run_id }} + cancel-in-progress: true permissions: {} jobs: + # Only a dispatch carries inputs, so this is skipped on the nightly cron. + validate-dispatch-inputs: + if: | + github.repository == 'openssl/openssl' && + (inputs.pr != '' || inputs.head_sha != '' || inputs.check_run_id != '') + uses: ./.github/workflows/validate-dispatch-inputs.yml + with: + pr: ${{ inputs.pr }} + head_sha: ${{ inputs.head_sha }} + check_run_id: ${{ inputs.check_run_id }} + test: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') + permissions: + contents: read runs-on: ubuntu-22.04 container: image: docker.io/fedora:43 @@ -29,6 +68,7 @@ jobs: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: Display environment run: export - name : Install needed tools @@ -57,22 +97,27 @@ jobs: - name: Run interop tests run: | cd interop - tmt run -av plans -n interop tests -f "tag: interop-openssl & tag: interop-$COMPONENT" provision -h local --feeling-safe execute -h tmt --interactive + tmt --feeling-safe run -av plans -n interop tests -f "tag: interop-openssl & tag: interop-$COMPONENT" provision -h local execute -h tmt --interactive openssl version echo "Finished - important to prevent unwanted output truncating" openssh_interop: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + inputs.pr == '' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') name: "openssh interop ${{ matrix.branch.openssl }}" strategy: fail-fast: false matrix: branch: [ { openssl: 'master', openssh: 'openssl-master', openssl_config: 'no-docs'}, + { openssl: 'openssl-4.1', openssh: 'openssl-4.1', openssl_config: 'no-docs'}, { openssl: 'openssl-4.0', openssh: 'openssl-4.0', openssl_config: 'no-docs'}, { openssl: 'openssl-3.6', openssh: 'openssl-3.6', openssl_config: 'no-docs'}, { openssl: 'openssl-3.5', openssh: 'openssl-3.5', openssl_config: 'no-docs'}, - { openssl: 'openssl-3.4', openssh: 'openssl-3.4', openssl_config: 'no-docs'}, - { openssl: 'openssl-3.0', openssh: 'openssl-3.0', openssl_config: ''} + { openssl: 'openssl-3.4', openssh: 'openssl-3.4', openssl_config: 'no-docs'} ] runs-on: ubuntu-latest env: diff --git a/.github/workflows/make-test b/.github/workflows/make-test index c38d0de3439b9..3203fae86c89f 100755 --- a/.github/workflows/make-test +++ b/.github/workflows/make-test @@ -17,6 +17,18 @@ fi mkdir -p "$OSSL_CI_ARTIFACTS_PATH" export OSSL_CI_ARTIFACTS_PATH="$(cd "$OSSL_CI_ARTIFACTS_PATH"; pwd)" +# Enable core dumps so a crashing test leaves a core with every thread's stack +# for diagnosis. Only a failing run produces one; green runs dump nothing. +# Linux only for now; best effort - a runner that disallows this just won't +# dump. +if [ "$(uname)" = Linux ]; then + ulimit -c unlimited 2>/dev/null || true + if command -v sudo >/dev/null 2>&1; then + sudo mkdir -p /tmp/cores && sudo chmod 1777 /tmp/cores || true + echo '/tmp/cores/core.%e.%p' | sudo tee /proc/sys/kernel/core_pattern >/dev/null 2>&1 || true + fi +fi + # Run the tests. This might fail, but we need to capture artifacts anyway. set +e make test HARNESS_JOBS=${HARNESS_JOBS:-4} LHASH_WORKERS=${LHASH_WORKERS:-16} "$@" @@ -31,6 +43,18 @@ for test_name in quic_multistream; do fi done +# Collect any core dumps together with the matching test binary, so the core is +# usable with gdb without a rebuild. The executable name is the %e field of the +# core file name. Only a failing run produces any. Linux only for now. +if [ "$(uname)" = Linux ]; then + for core in /tmp/cores/core.*; do + [ -f "$core" ] || continue + exe=$(basename "$core"); exe=${exe#core.}; exe=${exe%.*} + [ -f "test/$exe" ] && cp "test/$exe" "$OSSL_CI_ARTIFACTS_PATH/" || true + mv "$core" "$OSSL_CI_ARTIFACTS_PATH/" || true + done +fi + # Log the artifact tree. echo "::group::List of artifact files generated" echo "Test suite exited with $RESULT, artifacts path is $OSSL_CI_ARTIFACTS_PATH" diff --git a/.github/workflows/os-zoo-rolling.yml b/.github/workflows/os-zoo-rolling.yml new file mode 100644 index 0000000000000..2ae90743ab292 --- /dev/null +++ b/.github/workflows/os-zoo-rolling.yml @@ -0,0 +1,122 @@ +# Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +name: Rolling OS Zoo CI + +on: + schedule: + - cron: '50 03 * * 6' + workflow_dispatch: + inputs: + pr: + description: 'Internal: openssl-ci-bot PR number. Leave empty for a normal manual run.' + required: false + type: string + head_sha: + description: 'Internal: openssl-ci-bot commit SHA. Leave empty for a normal manual run.' + required: false + type: string + check_run_id: + description: 'Internal: openssl-ci-bot check-run ID. Leave empty for a normal manual run.' + required: false + type: string + +# Keep in sync with openssl-ci-bot's run-name parser, and with the Actions statistics +# collector that attributes CI load by parsing this same string. Both break silently. +run-name: >- + ${{ github.event.inputs.pr && format('ci-dispatch pr={0} head={1} check_run_id={2}', github.event.inputs.pr, github.event.inputs.head_sha, github.event.inputs.check_run_id) || github.workflow }} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.inputs.pr || github.run_id }} + +permissions: + contents: read + +jobs: + # Only a dispatch carries inputs, so this is skipped on the nightly cron. + validate-dispatch-inputs: + if: | + github.repository == 'openssl/openssl' && + (inputs.pr != '' || inputs.head_sha != '' || inputs.check_run_id != '') + uses: ./.github/workflows/validate-dispatch-inputs.yml + with: + pr: ${{ inputs.pr }} + head_sha: ${{ inputs.head_sha }} + check_run_id: ${{ inputs.check_run_id }} + + alpine: + if: github.repository == 'openssl/openssl' + strategy: + fail-fast: false + matrix: + tag: [edge] + cc: [gcc, clang] + runs-on: ubuntu-latest + container: + image: docker.io/library/alpine:${{ matrix.tag }} + env: + # See https://www.openwall.com/lists/musl/2022/02/16/14 + # for the reason why -Wno-sign-compare is needed with clang + # -Wno-stringop-overflow is needed to silence a bogus + # warning on new fortify-headers with gcc + EXTRA_CFLAGS: ${{ matrix.cc == 'clang' && '-Wno-sign-compare' || '-Wno-stringop-overflow' }} + CC: ${{ matrix.cc }} + steps: + - name: install packages + run: apk --no-cache add build-base perl linux-headers python3 ${{ matrix.cc }} + - uses: actions/checkout@v6 + with: + persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} + - name: config + run: | + ./config --strict-warnings --banner=Configured no-shared enable-fips \ + ${EXTRA_CFLAGS} + - name: config dump + run: ./configdata.pm --dump + - name: make + run: make -s -j4 -k + - name: get cpu info + run: | + cat /proc/cpuinfo + ./util/opensslwrap.sh version -c + - name: make test + run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} LHASH_WORKERS=${LHASH_WORKERS:-16} + + linux: + if: github.repository == 'openssl/openssl' + strategy: + fail-fast: false + matrix: + zoo: + - image: docker.io/library/debian:unstable + install: apt-get update && apt-get install -y gcc make perl libc6-dev + - image: docker.io/library/ubuntu:rolling + install: apt-get update && apt-get install -y gcc make perl + - image: docker.io/library/fedora:rawhide + install: dnf install -y gcc make perl-core + runs-on: ubuntu-latest + container: ${{ matrix.zoo.image }} + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} + - name: install packages + run: ${{ matrix.zoo.install }} + - name: config + run: ./config + - name: config dump + run: ./configdata.pm --dump + - name: make + run: make -s -j4 -k + - name: get cpu info + run: | + cat /proc/cpuinfo + ./util/opensslwrap.sh version -c + - name: make test + run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} LHASH_WORKERS=${LHASH_WORKERS:-16} diff --git a/.github/workflows/os-zoo.yml b/.github/workflows/os-zoo.yml index 1d8351b590744..f1c25bcfb78e1 100644 --- a/.github/workflows/os-zoo.yml +++ b/.github/workflows/os-zoo.yml @@ -11,17 +11,54 @@ on: schedule: - cron: '50 02 * * *' workflow_dispatch: + inputs: + pr: + description: 'Internal: openssl-ci-bot PR number. Leave empty for a normal manual run.' + required: false + type: string + head_sha: + description: 'Internal: openssl-ci-bot commit SHA. Leave empty for a normal manual run.' + required: false + type: string + check_run_id: + description: 'Internal: openssl-ci-bot check-run ID. Leave empty for a normal manual run.' + required: false + type: string + +# Keep in sync with openssl-ci-bot's run-name parser, and with the Actions statistics +# collector that attributes CI load by parsing this same string. Both break silently. +run-name: >- + ${{ github.event.inputs.pr && format('ci-dispatch pr={0} head={1} check_run_id={2}', github.event.inputs.pr, github.event.inputs.head_sha, github.event.inputs.check_run_id) || github.workflow }} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.inputs.pr || github.run_id }} + cancel-in-progress: true permissions: contents: read jobs: + # Only a dispatch carries inputs, so this is skipped on the nightly cron. + validate-dispatch-inputs: + if: | + github.repository == 'openssl/openssl' && + (inputs.pr != '' || inputs.head_sha != '' || inputs.check_run_id != '') + uses: ./.github/workflows/validate-dispatch-inputs.yml + with: + pr: ${{ inputs.pr }} + head_sha: ${{ inputs.head_sha }} + check_run_id: ${{ inputs.check_run_id }} + alpine: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') strategy: fail-fast: false matrix: - tag: [edge, latest] + tag: [3.24, 3.23, 3.22, 3.21] cc: [gcc, clang] runs-on: ubuntu-latest container: @@ -31,7 +68,7 @@ jobs: # for the reason why -Wno-sign-compare is needed with clang # -Wno-stringop-overflow is needed to silence a bogus # warning on new fortify-headers with gcc - EXTRA_CFLAGS: ${{ matrix.cc == 'clang' && '-Wno-sign-compare' || matrix.tag == 'edge' && '-Wno-stringop-overflow' || '' }} + EXTRA_CFLAGS: ${{ matrix.cc == 'clang' && '-Wno-sign-compare' || matrix.tag > '3.24' && '-Wno-stringop-overflow' || '' }} CC: ${{ matrix.cc }} steps: - name: install packages @@ -39,6 +76,7 @@ jobs: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: config run: | ./config --strict-warnings --banner=Configured no-shared enable-fips \ @@ -55,16 +93,27 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} LHASH_WORKERS=${LHASH_WORKERS:-16} linux: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') strategy: fail-fast: false matrix: zoo: - image: docker.io/library/debian:11 - install: apt-get update && apt-get install -y gcc make perl + # Debian 11 LTS ended 2026-08-31: bullseye-security metadata is + # expired and its pool has been pruned. Use the snapshot repos + # the image pins itself. + install: | + sed -i -e 's|^deb |#deb |' \ + -e 's|^# deb http://snapshot|deb http://snapshot|' /etc/apt/sources.list && \ + apt-get -o Acquire::Check-Valid-Until=false update && \ + apt-get install -y gcc make perl - image: docker.io/library/debian:12 install: apt-get update && apt-get install -y gcc make perl - - image: docker.io/library/debian:trixie + - image: docker.io/library/debian:13 install: apt-get update && apt-get install -y gcc make perl - image: docker.io/library/ubuntu:20.04 install: apt-get update && apt-get install -y gcc make perl @@ -72,18 +121,26 @@ jobs: install: apt-get update && apt-get install -y gcc make perl - image: docker.io/library/ubuntu:24.04 install: apt-get update && apt-get install -y gcc make perl - - image: docker.io/library/fedora:41 - install: dnf install -y gcc make perl-core + - image: docker.io/library/ubuntu:26.04 + install: apt-get update && apt-get install -y gcc make perl - image: docker.io/library/fedora:42 install: dnf install -y gcc make perl-core + - image: docker.io/library/fedora:43 + install: dnf install -y gcc make perl-core + - image: docker.io/library/fedora:44 + install: dnf install -y gcc make perl-core + - image: docker.io/library/fedora:45 + install: dnf install -y gcc make perl-core - image: docker.io/library/centos:8 install: | sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-* && \ sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-* && \ dnf install -y gcc make perl-core - - image: docker.io/library/rockylinux:8 + - image: docker.io/rockylinux/rockylinux:8 install: dnf install -y gcc make perl-core - - image: docker.io/library/rockylinux:9 + - image: docker.io/rockylinux/rockylinux:9 + install: dnf install -y gcc make perl-core + - image: docker.io/rockylinux/rockylinux:10 install: dnf install -y gcc make perl-core runs-on: ubuntu-latest container: ${{ matrix.zoo.image }} @@ -91,6 +148,7 @@ jobs: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: install packages run: ${{ matrix.zoo.install }} - name: config @@ -107,7 +165,11 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} LHASH_WORKERS=${LHASH_WORKERS:-16} macos: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') strategy: fail-fast: false matrix: @@ -117,6 +179,7 @@ jobs: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: config @@ -133,7 +196,11 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} LHASH_WORKERS=${LHASH_WORKERS:-16} windows: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') strategy: fail-fast: false matrix: @@ -147,6 +214,7 @@ jobs: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: install nasm @@ -198,12 +266,74 @@ jobs: call "${{ matrix.platform.vcvars }}" jom test VERBOSE_FAILURE=yes HARNESS_JOBS=4 LHASH_WORKERS=16 + windows-arm64: + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') + runs-on: windows-11-arm + env: + VCVARS: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsarm64.bat + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} + - name: checkout fuzz/corpora submodule + run: git submodule update --init --depth 1 fuzz/corpora + # no nasm: VC-WIN64-ARM has no asm_arch, so Configure disables asm + # here jom is an x86/x64 binary and Windows 11 on ARM runs it under emulation + - name: install jom + run: | + mkdir C:\jom + Invoke-WebRequest -Uri "https://openssl-library.org/ci-deps/jom-1.1.7.exe" -OutFile C:\jom\jom.exe + $expected = (Get-Content "$env:GITHUB_WORKSPACE\.github\ci-deps.json" -Raw | ConvertFrom-Json).'jom-1.1.7.exe' + $actual = (Get-FileHash C:\jom\jom.exe -Algorithm SHA256).Hash + if ($actual -ne $expected) { throw "SHA256 mismatch for jom.exe (expected $expected, got $actual)" } + "C:\jom" | Out-File -FilePath "$env:GITHUB_PATH" -Append + - name: prepare the build directory + run: mkdir _build + - name: config + working-directory: _build + shell: cmd + run: | + call "%VCVARS%" + perl ..\Configure VC-WIN64-ARM --banner=Configured --strict-warnings no-makedepend enable-fips + perl configdata.pm --dump + - name: build + working-directory: _build + shell: cmd + run: | + call "%VCVARS%" + jom /j4 /S + - name: get cpu info + working-directory: _build + shell: cmd + run: | + call "%VCVARS%" + apps\openssl.exe version -c + - name: test + working-directory: _build + shell: cmd + run: | + call "%VCVARS%" + jom test VERBOSE_FAILURE=yes HARNESS_JOBS=4 LHASH_WORKERS=16 + + # GitHub-hosted, so pull-request code may build here: coverage bought, not risked. The + # repository clause is new -- a cron in a fork expresses nobody's intent. linux-arm64: + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-24.04-arm steps: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: config run: ./config --strict-warnings enable-fips enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-trace - name: config dump @@ -216,11 +346,17 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} LHASH_WORKERS=${LHASH_WORKERS:-16} linux-x86: + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: run container run: | CONTAINER_ID=$(podman run -d -v $(pwd):/mnt -w /mnt --platform=linux/i386 docker.io/i386/debian:13 sleep infinity) @@ -258,11 +394,18 @@ jobs: linux-ppc64le: runs-on: linux-ppc64le - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + ( github.event_name == 'schedule' || + (github.event_name == 'workflow_dispatch' && inputs.pr == '') ) && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') steps: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: config run: ./config --strict-warnings enable-fips enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-trace - name: config dump @@ -278,11 +421,18 @@ jobs: linux-s390x: runs-on: linux-s390x - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + ( github.event_name == 'schedule' || + (github.event_name == 'workflow_dispatch' && inputs.pr == '') ) && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') steps: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: config run: ./config --strict-warnings enable-fips enable-md2 enable-rc5 enable-trace - name: config dump @@ -298,11 +448,18 @@ jobs: linux-riscv64: runs-on: linux-riscv64 - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + ( github.event_name == 'schedule' || + (github.event_name == 'workflow_dispatch' && inputs.pr == '') ) && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') steps: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: config run: ./config enable-fips enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-trace - name: config dump @@ -318,81 +475,93 @@ jobs: freebsd-x86_64: runs-on: ubuntu-latest - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') steps: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: config - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 + uses: cross-platform-actions/action@faa0c6197e94aacf1c5956460152c8380d3560a5 #v1.5.0 with: operating_system: freebsd - version: "13.4" + version: "14.4" shutdown_vm: false run: | sudo pkg install -y gcc perl5 ./config --strict-warnings enable-fips enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-trace - name: config dump - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 + uses: cross-platform-actions/action@faa0c6197e94aacf1c5956460152c8380d3560a5 #v1.5.0 with: operating_system: freebsd - version: "13.4" + version: "14.4" shutdown_vm: false run: ./configdata.pm --dump - name: make - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 + uses: cross-platform-actions/action@faa0c6197e94aacf1c5956460152c8380d3560a5 #v1.5.0 with: operating_system: freebsd - version: "13.4" + version: "14.4" shutdown_vm: false run: make -j4 - name: make test - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 + uses: cross-platform-actions/action@faa0c6197e94aacf1c5956460152c8380d3560a5 #v1.5.0 with: operating_system: freebsd - version: "13.4" + version: "14.4" run: | ./util/opensslwrap.sh version -c .github/workflows/make-test openbsd-x86_64: runs-on: ubuntu-latest - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: config - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 + uses: cross-platform-actions/action@faa0c6197e94aacf1c5956460152c8380d3560a5 #v1.5.0 with: operating_system: openbsd architecture: x86-64 - version: '7.7' + version: '7.9' shutdown_vm: false run: | ./config --strict-warnings enable-fips enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-trace - name: config dump - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 + uses: cross-platform-actions/action@faa0c6197e94aacf1c5956460152c8380d3560a5 #v1.5.0 with: operating_system: openbsd architecture: x86-64 - version: '7.7' + version: '7.9' shutdown_vm: false run: | ./configdata.pm --dump - name: make - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 + uses: cross-platform-actions/action@faa0c6197e94aacf1c5956460152c8380d3560a5 #v1.5.0 with: operating_system: openbsd architecture: x86-64 - version: '7.7' + version: '7.9' shutdown_vm: false run: | make -j4 - name: make test - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 + uses: cross-platform-actions/action@faa0c6197e94aacf1c5956460152c8380d3560a5 #v1.5.0 with: operating_system: openbsd architecture: x86-64 - version: '7.7' + version: '7.9' run: | ./util/opensslwrap.sh version -c .github/workflows/make-test diff --git a/.github/workflows/oss-fuzz.yml b/.github/workflows/oss-fuzz.yml index 33af299a84b81..0cdf1864bbc7c 100644 --- a/.github/workflows/oss-fuzz.yml +++ b/.github/workflows/oss-fuzz.yml @@ -10,12 +10,48 @@ on: schedule: - cron: '50 01 * * *' workflow_dispatch: + inputs: + pr: + description: 'Internal: openssl-ci-bot PR number. Leave empty for a normal manual run.' + required: false + type: string + head_sha: + description: 'Internal: openssl-ci-bot commit SHA. Leave empty for a normal manual run.' + required: false + type: string + check_run_id: + description: 'Internal: openssl-ci-bot check-run ID. Leave empty for a normal manual run.' + required: false + type: string + +# Keep in sync with openssl-ci-bot's run-name parser, and with the Actions statistics +# collector that attributes CI load by parsing this same string. Both break silently. +run-name: >- + ${{ github.event.inputs.pr && format('ci-dispatch pr={0} head={1} check_run_id={2}', github.event.inputs.pr, github.event.inputs.head_sha, github.event.inputs.check_run_id) || github.workflow }} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.inputs.pr || github.run_id }} + cancel-in-progress: true + permissions: contents: read jobs: + # Only a dispatch carries inputs, so this is skipped on the nightly cron. + validate-dispatch-inputs: + if: inputs.pr != '' || inputs.head_sha != '' || inputs.check_run_id != '' + uses: ./.github/workflows/validate-dispatch-inputs.yml + with: + pr: ${{ inputs.pr }} + head_sha: ${{ inputs.head_sha }} + check_run_id: ${{ inputs.check_run_id }} + Fuzzing: - if: github.event_name != 'schedule' || github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: >- + (github.event_name != 'schedule' || github.repository == 'openssl/openssl') && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-latest steps: - name: Clear unnecessary files @@ -23,15 +59,21 @@ jobs: df sudo rm -rf /usr/share/dotnet /usr/share/swift /usr/local/.ghcup /usr/local/share/powershell /usr/local/share/chromium /usr/local/lib/android /usr/local/lib/node_modules df + - uses: actions/checkout@v6 + with: + persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: Build Fuzzers uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master with: oss-fuzz-project-name: 'openssl' + project-src-path: ${{ github.workspace }} dry-run: false - name: Run Fuzzers uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master with: oss-fuzz-project-name: 'openssl' + project-src-path: ${{ github.workspace }} fuzz-seconds: 600 dry-run: false - name: Upload Crash diff --git a/.github/workflows/perl-minimal-checker.yml b/.github/workflows/perl-minimal-checker.yml index 9ca4e9b5092ec..97d33c3c0e855 100644 --- a/.github/workflows/perl-minimal-checker.yml +++ b/.github/workflows/perl-minimal-checker.yml @@ -7,7 +7,25 @@ # Jobs run per pull request submission name: Perl-minimal-checker CI -on: [pull_request, push] +on: + pull_request: + paths-ignore: + - 'doc/**' + - '*.md' + - '*.pod' + - 'README*' + - 'funding.json' + - 'LICENSE.txt' + - 'VERSION.dat' + push: + paths-ignore: + - 'doc/**' + - '*.md' + - '*.pod' + - 'README*' + - 'funding.json' + - 'LICENSE.txt' + - 'VERSION.dat' permissions: contents: read @@ -23,7 +41,7 @@ jobs: tar xf perl-5.10.1.tar.bz2 cd perl-5.10.1 ./Configure -des -Dprefix=/tmp/perl -A ccflags='-Wno-incompatible-pointer-types' -A define:malloctype='void *' -A define:freetype='void' -Dlibs='-ldl -lm -lutil -lc' - make -j $(nproc) perl + make -j1 perl make install popd - name: Install Test::More 0.96 diff --git a/.github/workflows/prov-compat-label.yml b/.github/workflows/prov-compat-label.yml index cf2b44e169e50..9a30874c0cc22 100644 --- a/.github/workflows/prov-compat-label.yml +++ b/.github/workflows/prov-compat-label.yml @@ -10,7 +10,17 @@ name: Provider compatibility for PRs -on: [pull_request] +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + paths-ignore: + - 'doc/**' + - '*.md' + - '*.pod' + - 'README*' + - 'funding.json' + - 'LICENSE.txt' + - 'VERSION.dat' permissions: contents: read @@ -110,11 +120,6 @@ jobs: dir: PR, tgz: PR.tar.gz, extra_config: "enable-lms enable-tls-deprecated-ec", - }, { - name: openssl-3.0, - dir: branch-3.0, - tgz: branch-3.0.tar.gz, - extra_config: "", }, { name: openssl-3.4, dir: branch-3.4, @@ -135,6 +140,11 @@ jobs: dir: branch-4.0, tgz: branch-4.0.tar.gz, extra_config: "enable-lms enable-tls-deprecated-ec", + }, { + name: openssl-4.1, + dir: branch-4.1, + tgz: branch-4.1.tar.gz, + extra_config: "enable-lms enable-tls-deprecated-ec", }, { name: master, dir: branch-master, @@ -205,12 +215,14 @@ jobs: # Note that releases are not used as a test environment for # later providers. Problems in these situations ought to be # caught by cross branch testing before the release. - tree_a: [ branch-4.0, branch-3.6, branch-3.5, branch-3.4, branch-3.0, + tree_a: [ branch-4.1, branch-4.0, branch-3.6, branch-3.5, branch-3.4, openssl-3.0.0, openssl-3.0.8, openssl-3.0.9, openssl-3.1.2 ] tree_b: [ PR ] include: - tree_a: PR tree_b: branch-master + - tree_a: PR + tree_b: branch-4.1 - tree_a: PR tree_b: branch-4.0 - tree_a: PR @@ -219,8 +231,6 @@ jobs: tree_b: branch-3.5 - tree_a: PR tree_b: branch-3.4 - - tree_a: PR - tree_b: branch-3.0 steps: - name: early exit checks id: early_exit @@ -256,8 +266,8 @@ jobs: - name: set up cross validation of FIPS from A with tree from B if: steps.early_exit.outputs.skip != 'true' run: | - cp providers/fips.so ../${{ matrix.tree_b }}/providers/ - cp providers/fipsmodule.cnf ../${{ matrix.tree_b }}/providers/ + cp -f providers/fips.so ../${{ matrix.tree_b }}/providers/ + cp -f providers/fipsmodule.cnf ../${{ matrix.tree_b }}/providers/ working-directory: ${{ matrix.tree_a }} - name: show module versions from cross validation diff --git a/.github/workflows/provider-compatibility.yml b/.github/workflows/provider-compatibility.yml index 806a61ad616e0..fa231ea52b633 100644 --- a/.github/workflows/provider-compatibility.yml +++ b/.github/workflows/provider-compatibility.yml @@ -115,11 +115,6 @@ jobs: # the build. # `extra_config` adds extra config build option for the branch. { - name: openssl-3.0, - dir: branch-3.0, - tgz: branch-3.0.tar.gz, - extra_config: "", - }, { name: openssl-3.4, dir: branch-3.4, tgz: branch-3.4.tar.gz, @@ -139,6 +134,11 @@ jobs: dir: branch-4.0, tgz: branch-4.0.tar.gz, extra_config: "enable-lms enable-tls-deprecated-ec", + }, { + name: openssl-4.1, + dir: branch-4.1, + tgz: branch-4.1.tar.gz, + extra_config: "enable-lms enable-tls-deprecated-ec", }, { name: master, dir: branch-master, @@ -213,11 +213,9 @@ jobs: # Note that releases are not used as a test environment for # later providers. Problems in these situations ought to be # caught by cross branch testing before the release. - tree_a: [ branch-master, branch-4.0, branch-3.6, branch-3.5, branch-3.4, - branch-3.0, + tree_a: [ branch-master, branch-4.1, branch-4.0, branch-3.6, branch-3.5, branch-3.4, openssl-3.0.0, openssl-3.0.8, openssl-3.0.9, openssl-3.1.2 ] - tree_b: [ branch-master, branch-4.0, branch-3.6, branch-3.5, branch-3.4, - branch-3.0 ] + tree_b: [ branch-master, branch-4.1, branch-4.0, branch-3.6, branch-3.5, branch-3.4 ] steps: - name: early exit checks id: early_exit @@ -248,8 +246,8 @@ jobs: - name: set up cross validation of FIPS from A with tree from B if: steps.early_exit.outputs.skip != 'true' run: | - cp providers/fips.so ../${{ matrix.tree_b }}/providers/ - cp providers/fipsmodule.cnf ../${{ matrix.tree_b }}/providers/ + cp -f providers/fips.so ../${{ matrix.tree_b }}/providers/ + cp -f providers/fipsmodule.cnf ../${{ matrix.tree_b }}/providers/ working-directory: ${{ matrix.tree_a }} - name: show module versions from cross validation diff --git a/.github/workflows/riscv-more-cross-compiles.yml b/.github/workflows/riscv-more-cross-compiles.yml index cac662b8d34fc..575586601381e 100644 --- a/.github/workflows/riscv-more-cross-compiles.yml +++ b/.github/workflows/riscv-more-cross-compiles.yml @@ -10,15 +10,54 @@ name: Cross Compile for RISC-V Extensions on: pull_request: types: [opened, reopened, edited, synchronize] + paths-ignore: + - 'doc/**' + - '*.md' + - '*.pod' + - 'README*' + - 'funding.json' + - 'LICENSE.txt' + - 'VERSION.dat' push: schedule: - cron: '35 02 * * *' workflow_dispatch: + inputs: + pr: + description: 'Internal: openssl-ci-bot PR number. Leave empty for a normal manual run.' + required: false + type: string + head_sha: + description: 'Internal: openssl-ci-bot commit SHA. Leave empty for a normal manual run.' + required: false + type: string + check_run_id: + description: 'Internal: openssl-ci-bot check-run ID. Leave empty for a normal manual run.' + required: false + type: string + +# Keep in sync with openssl-ci-bot's run-name parser, and with the Actions statistics +# collector that attributes CI load by parsing this same string. Both break silently. +run-name: >- + ${{ github.event.inputs.pr && format('ci-dispatch pr={0} head={1} check_run_id={2}', github.event.inputs.pr, github.event.inputs.head_sha, github.event.inputs.check_run_id) || github.workflow }} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.inputs.pr || github.run_id }} + cancel-in-progress: true permissions: contents: read jobs: + # Only a dispatch carries inputs, so this is skipped on every other trigger. + validate-dispatch-inputs: + if: inputs.pr != '' || inputs.head_sha != '' || inputs.check_run_id != '' + uses: ./.github/workflows/validate-dispatch-inputs.yml + with: + pr: ${{ inputs.pr }} + head_sha: ${{ inputs.head_sha }} + check_run_id: ${{ inputs.check_run_id }} + cross-compilation-riscv: # pull request title contains 'riscv' # pull request title contains 'RISC-V' @@ -26,7 +65,11 @@ jobs: # push event commit message contains '[riscv ci]' # cron job # manual dispatch - if: contains(github.event.pull_request.title, 'riscv') || contains(github.event.pull_request.title, 'RISC-V') || contains(github.event.pull_request.body, '[riscv ci]') || contains(github.event.head_commit.message, '[riscv ci]') || (github.event_name == 'schedule' && github.repository == 'openssl/openssl') || github.event_name == 'workflow_dispatch' + needs: [validate-dispatch-inputs] + if: >- + (contains(github.event.pull_request.title, 'riscv') || contains(github.event.pull_request.title, 'RISC-V') || contains(github.event.pull_request.body, '[riscv ci]') || contains(github.event.head_commit.message, '[riscv ci]') || (github.event_name == 'schedule' && github.repository == 'openssl/openssl') || github.event_name == 'workflow_dispatch') && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') strategy: fail-fast: false matrix: @@ -102,7 +145,7 @@ jobs: libs: libc6-dev-riscv64-cross, target: linux64-riscv64, fips: no, - qemucpu: "rv64,v=true,vlen=128,zbb=true,zvbb=false,zvkb=false", + qemucpu: "rv64,v=true,vext_spec=v1.0,vlen=128,zbb=true,zvbb=false,zvkb=false", opensslcapsname: riscvcap, # OPENSSL_riscvcap opensslcaps: "rv64gc_v_zbb" }, { @@ -115,7 +158,7 @@ jobs: # do not use zvkb flag for qemucpu as ubuntu-latest (24.04) uses QEMU 8.2.2 # see https://lists.nongnu.org/archive/html/qemu-devel/2024-05/msg02231.html # Should be zvkg=true,zvbb=false,zvkb=false - qemucpu: "rv64,v=true,vlen=128,zvkg=true,zvbb=false", + qemucpu: "rv64,v=true,vext_spec=v1.0,vlen=128,zvkg=true,zvbb=false", opensslcapsname: riscvcap, # OPENSSL_riscvcap opensslcaps: "rv64gc_v_zvkg" }, { @@ -128,7 +171,7 @@ jobs: # do not use zvkb flag for qemucpu as ubuntu-latest (24.04) uses QEMU 8.2.2 # see https://lists.nongnu.org/archive/html/qemu-devel/2024-05/msg02231.html # Should be zvkb=true,zvbc=true,zvkg=false - qemucpu: "rv64,v=true,vlen=128,zvbb=true,zvbc=true,zvkg=false", + qemucpu: "rv64,v=true,vext_spec=v1.0,vlen=128,zvbb=true,zvbc=true,zvkg=false", opensslcapsname: riscvcap, # OPENSSL_riscvcap opensslcaps: "rv64gc_v_zvkb_zvbc" }, { @@ -141,7 +184,7 @@ jobs: libs: libc6-dev-riscv64-cross, target: linux64-riscv64, fips: no, - qemucpu: "rv64,v=true,vlen=128,zvkned=true,zvbb=false,zvkb=false,zvkg=false", + qemucpu: "rv64,v=true,vext_spec=v1.0,vlen=128,zvkned=true,zvbb=false,zvkb=false,zvkg=false", opensslcapsname: riscvcap, # OPENSSL_riscvcap opensslcaps: "rv64gc_v_zvkned" }, { @@ -161,7 +204,7 @@ jobs: libs: libc6-dev-riscv64-cross, target: linux64-riscv64, fips: no, - qemucpu: "rv64,zba=true,zbb=true,zbc=true,zbs=true,zbkb=true,zbkc=true,zbkx=true,zknd=true,zkne=true,zknh=true,zksed=true,zksh=true,zkr=true,zkt=true,v=true,vlen=128,zvbb=true,zvbc=true,zvkb=true,zvkg=true,zvkned=true,zvknha=true,zvknhb=true,zvksed=true,zvksh=true", + qemucpu: "rv64,zba=true,zbb=true,zbc=true,zbs=true,zbkb=true,zbkc=true,zbkx=true,zknd=true,zkne=true,zknh=true,zksed=true,zksh=true,zkr=true,zkt=true,v=true,vext_spec=v1.0,vlen=128,zvbb=true,zvbc=true,zvkb=true,zvkg=true,zvkned=true,zvknha=true,zvknhb=true,zvksed=true,zvksh=true", opensslcapsname: riscvcap, # OPENSSL_riscvcap opensslcaps: "rv64gc_zba_zbb_zbc_zbs_zbkb_zbkc_zbkx_zknd_zkne_zknh_zksed_zksh_zkr_zkt_v_zvbb_zvbc_zvkb_zvkg_zvkned_zvknha_zvknhb_zvksed_zvksh" }, { @@ -172,7 +215,7 @@ jobs: libs: libc6-dev-riscv64-cross, target: linux64-riscv64, fips: no, - qemucpu: "rv64,zba=true,zbb=true,zbc=true,zbs=true,zbkb=true,zbkc=true,zbkx=true,zknd=true,zkne=true,zknh=true,zksed=true,zksh=true,zkr=true,zkt=true,v=true,vlen=256,zvbb=true,zvbc=true,zvkb=true,zvkg=true,zvkned=true,zvknha=true,zvknhb=true,zvksed=true,zvksh=true", + qemucpu: "rv64,zba=true,zbb=true,zbc=true,zbs=true,zbkb=true,zbkc=true,zbkx=true,zknd=true,zkne=true,zknh=true,zksed=true,zksh=true,zkr=true,zkt=true,v=true,vext_spec=v1.0,vlen=256,zvbb=true,zvbc=true,zvkb=true,zvkg=true,zvkned=true,zvknha=true,zvknhb=true,zvksed=true,zvksh=true", opensslcapsname: riscvcap, # OPENSSL_riscvcap opensslcaps: "rv64gc_zba_zbb_zbc_zbs_zbkb_zbkc_zbkx_zknd_zkne_zknh_zksed_zksh_zkr_zkt_v_zvbb_zvbc_zvkb_zvkg_zvkned_zvknha_zvknhb_zvksed_zvksh_zvl256" }, { @@ -183,7 +226,7 @@ jobs: libs: libc6-dev-riscv64-cross, target: linux64-riscv64, fips: no, - qemucpu: "rv64,zba=true,zbb=true,zbc=true,zbs=true,zbkb=true,zbkc=true,zbkx=true,zknd=true,zkne=true,zknh=true,zksed=true,zksh=true,zkr=true,zkt=true,v=true,vlen=512,zvbb=true,zvbc=true,zvkb=true,zvkg=true,zvkned=true,zvknha=true,zvknhb=true,zvksed=true,zvksh=true", + qemucpu: "rv64,zba=true,zbb=true,zbc=true,zbs=true,zbkb=true,zbkc=true,zbkx=true,zknd=true,zkne=true,zknh=true,zksed=true,zksh=true,zkr=true,zkt=true,v=true,vext_spec=v1.0,vlen=512,zvbb=true,zvbc=true,zvkb=true,zvkg=true,zvkned=true,zvknha=true,zvknhb=true,zvksed=true,zvksh=true", opensslcapsname: riscvcap, # OPENSSL_riscvcap opensslcaps: "rv64gc_zba_zbb_zbc_zbs_zbkb_zbkc_zbkx_zknd_zkne_zknh_zksed_zksh_zkr_zkt_v_zvbb_zvbc_zvkb_zvkg_zvkned_zvknha_zvknhb_zvksed_zvksh_zvl512" }, { @@ -227,7 +270,7 @@ jobs: libs: libc6-dev-riscv64-cross, target: linux64-riscv64, fips: no, - qemucpu: "rv64,v=true,vlen=128,zvkned=true", + qemucpu: "rv64,v=true,vext_spec=v1.0,vlen=128,zvkned=true", # No opensslcapsname: hwprobe is used for capability detection. opensslcaps: "rv64gc_v_zvkned_hwprobe", # V must be detected. ZVKNED is not reported by QEMU 8.2.2 (ubuntu-latest) @@ -251,6 +294,7 @@ jobs: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora @@ -282,8 +326,8 @@ jobs: - name: Set OpenSSL caps environment if: matrix.platform.opensslcapsname != '' - run: echo "OPENSSL_${{ matrix.platform.opensslcapsname }}=\ - ${{ matrix.platform.opensslcaps }}" >> $GITHUB_ENV + run: | + echo "OPENSSL_${{ matrix.platform.opensslcapsname }}=${{ matrix.platform.opensslcaps }}" >> "$GITHUB_ENV" - name: get cpu info run: cat /proc/cpuinfo @@ -299,20 +343,24 @@ jobs: ./util/opensslwrap.sh info -cpusettings | \ grep -qE "${{ matrix.platform.capscheck }}" + # A dispatched run, and a pull request that opts in with `[riscv ci]` in its body, take the + # push tier: both exist to run pre-merge what otherwise only runs post-merge, and evp-only + # is the weaker signal. A pull request that only matches on its title keeps the evp tier. + # Legs setting `tests: none` stay build-only on every trigger, by design. - name: make all tests - if: github.event_name == 'push' && matrix.platform.tests == '' + if: (github.event_name == 'push' || inputs.pr != '' || contains(github.event.pull_request.body, '[riscv ci]')) && matrix.platform.tests == '' run: | .github/workflows/make-test \ TESTS="-test_afalg" \ QEMU_LD_PREFIX=/usr/${{ matrix.platform.arch }} - name: make some tests - if: github.event_name == 'push' && matrix.platform.tests != 'none' && matrix.platform.tests != '' + if: (github.event_name == 'push' || inputs.pr != '' || contains(github.event.pull_request.body, '[riscv ci]')) && matrix.platform.tests != 'none' && matrix.platform.tests != '' run: | .github/workflows/make-test \ TESTS="${{ matrix.platform.tests }} -test_afalg" \ QEMU_LD_PREFIX=/usr/${{ matrix.platform.arch }} - name: make evp tests - if: github.event_name == 'pull_request' && matrix.platform.tests != 'none' + if: github.event_name == 'pull_request' && !contains(github.event.pull_request.body, '[riscv ci]') && matrix.platform.tests != 'none' run: | .github/workflows/make-test \ TESTS="test_evp*" \ diff --git a/.github/workflows/run-checker-ci.yml b/.github/workflows/run-checker-ci.yml index 70d105e3f2c00..89186ff03c22f 100644 --- a/.github/workflows/run-checker-ci.yml +++ b/.github/workflows/run-checker-ci.yml @@ -7,7 +7,25 @@ # Jobs run per pull request submission name: Run-checker CI -on: [pull_request, push] +on: + pull_request: + paths-ignore: + - 'doc/**' + - '*.md' + - '*.pod' + - 'README*' + - 'funding.json' + - 'LICENSE.txt' + - 'VERSION.dat' + push: + paths-ignore: + - 'doc/**' + - '*.md' + - '*.pod' + - 'README*' + - 'funding.json' + - 'LICENSE.txt' + - 'VERSION.dat' permissions: contents: read diff --git a/.github/workflows/run-checker-daily.yml b/.github/workflows/run-checker-daily.yml index 3d3688abca4f7..46f5cef26156e 100644 --- a/.github/workflows/run-checker-daily.yml +++ b/.github/workflows/run-checker-daily.yml @@ -12,13 +12,49 @@ on: schedule: - cron: '30 02 * * *' workflow_dispatch: + inputs: + pr: + description: 'Internal: openssl-ci-bot PR number. Leave empty for a normal manual run.' + required: false + type: string + head_sha: + description: 'Internal: openssl-ci-bot commit SHA. Leave empty for a normal manual run.' + required: false + type: string + check_run_id: + description: 'Internal: openssl-ci-bot check-run ID. Leave empty for a normal manual run.' + required: false + type: string + +# Keep in sync with openssl-ci-bot's run-name parser, and with the Actions statistics +# collector that attributes CI load by parsing this same string. Both break silently. +run-name: >- + ${{ github.event.inputs.pr && format('ci-dispatch pr={0} head={1} check_run_id={2}', github.event.inputs.pr, github.event.inputs.head_sha, github.event.inputs.check_run_id) || github.workflow }} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.inputs.pr || github.run_id }} + cancel-in-progress: true permissions: contents: read jobs: + validate-dispatch-inputs: + if: | + github.repository == 'openssl/openssl' && + (inputs.pr != '' || inputs.head_sha != '' || inputs.check_run_id != '') + uses: ./.github/workflows/validate-dispatch-inputs.yml + with: + pr: ${{ inputs.pr }} + head_sha: ${{ inputs.head_sha }} + check_run_id: ${{ inputs.check_run_id }} + run-checker: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') strategy: fail-fast: false matrix: @@ -28,6 +64,7 @@ jobs: no-argon2, no-aria, no-asan, + no-ascon128, no-asm, no-async, no-autoalginit, @@ -52,6 +89,7 @@ jobs: no-dsa, no-dtls1, no-dtls1_2, + no-dtls1_3, no-dtls1_2-method, no-dtls1-method, enable-ec_nistp_64_gcc_128, @@ -139,6 +177,7 @@ jobs: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: config @@ -155,12 +194,17 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} run-checker-sctp: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: Install Dependencies for sctp option @@ -197,7 +241,11 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} enable_brotli_dynamic: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-latest steps: - name: install brotli @@ -208,6 +256,7 @@ jobs: uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: config @@ -222,7 +271,11 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} enable_zstd_dynamic: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-latest steps: - name: install zstd @@ -233,6 +286,7 @@ jobs: uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: config @@ -247,7 +301,11 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} enable_brotli_and_zstd_dynamic: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-latest steps: - name: install brotli and zstd @@ -259,6 +317,7 @@ jobs: uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: config @@ -273,13 +332,18 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} malloc_failure_testing: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-latest steps: - name: checkout openssl uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: Adjust ASLR for sanitizer run: | sudo cat /proc/sys/vm/mmap_rnd_bits @@ -298,7 +362,11 @@ jobs: make TESTS="test_memfail" test enable_brotli_and_asan_ubsan: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-latest steps: - name: install brotli @@ -309,6 +377,7 @@ jobs: uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: Adjust ASLR for sanitizer @@ -327,7 +396,11 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} OPENSSL_TEST_RAND_ORDER=0 enable_zstd_and_asan_ubsan: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-latest steps: - name: install zstd @@ -338,6 +411,7 @@ jobs: uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: Adjust ASLR for sanitizer @@ -356,7 +430,11 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} OPENSSL_TEST_RAND_ORDER=0 enable_tfo: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') strategy: matrix: os: [ubuntu-latest, macos-15, macos-15-intel] @@ -365,6 +443,7 @@ jobs: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: config @@ -377,12 +456,17 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} enable_buildtest: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: config @@ -397,12 +481,17 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} memory_sanitizer_slh_dsa: - if: github.repository == 'openssl/openssl' + needs: [validate-dispatch-inputs] + if: | + github.repository == 'openssl/openssl' && + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: Adjust ASLR for sanitizer @@ -422,11 +511,16 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} OPENSSL_TEST_RAND_ORDER=0 bn_debug: + needs: [validate-dispatch-inputs] + if: | + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: config run: ./config --debug --strict-warnings -DBN_DEBUG --banner=Configured -DOPENSSL_NO_SECURE_MEMORY && perl configdata.pm --dump - name: make diff --git a/.github/workflows/run-checker-merge.yml b/.github/workflows/run-checker-merge.yml index 4342d97bb62c4..db40542ca1f1f 100644 --- a/.github/workflows/run-checker-merge.yml +++ b/.github/workflows/run-checker-merge.yml @@ -8,12 +8,52 @@ name: Run-checker merge # Jobs run per merge to master -on: [push] +on: + push: + workflow_dispatch: + inputs: + pr: + description: 'Internal: openssl-ci-bot PR number. Leave empty for a normal manual run.' + required: false + type: string + head_sha: + description: 'Internal: openssl-ci-bot commit SHA. Leave empty for a normal manual run.' + required: false + type: string + check_run_id: + description: 'Internal: openssl-ci-bot check-run ID. Leave empty for a normal manual run.' + required: false + type: string + +# Keep in sync with openssl-ci-bot's run-name parser, and with the Actions statistics +# collector that attributes CI load by parsing this same string. Both break silently. +run-name: >- + ${{ github.event.inputs.pr && format('ci-dispatch pr={0} head={1} check_run_id={2}', github.event.inputs.pr, github.event.inputs.head_sha, github.event.inputs.check_run_id) || github.workflow }} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.inputs.pr || github.run_id }} + cancel-in-progress: true + permissions: contents: read jobs: + # Only a dispatch carries inputs, so this is skipped on a push. No repository clause: + # the build jobs below keep running in forks on push, and the validator must not claim + # a boundary they do not have. + validate-dispatch-inputs: + if: inputs.pr != '' || inputs.head_sha != '' || inputs.check_run_id != '' + uses: ./.github/workflows/validate-dispatch-inputs.yml + with: + pr: ${{ inputs.pr }} + head_sha: ${{ inputs.head_sha }} + check_run_id: ${{ inputs.check_run_id }} + run-checker: + needs: [validate-dispatch-inputs] + if: | + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') strategy: fail-fast: false matrix: @@ -46,6 +86,7 @@ jobs: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: config @@ -62,12 +103,18 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} jitter: + needs: [validate-dispatch-inputs] + if: | + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-latest steps: - name: checkout openssl uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} + # Third-party, pinned to a release tag: not repointed at the pull request's choice. - name: checkout jitter uses: actions/checkout@v6 with: @@ -91,11 +138,16 @@ jobs: run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} threads_sanitizer_atomic_fallback: + needs: [validate-dispatch-inputs] + if: | + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || needs.validate-dispatch-inputs.result == 'skipped') runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: checkout fuzz/corpora submodule run: git submodule update --init --depth 1 fuzz/corpora - name: Adjust ASLR for sanitizer diff --git a/.github/workflows/style-checks.yml b/.github/workflows/style-checks.yml index b345ae5110998..d2440ab8fd277 100644 --- a/.github/workflows/style-checks.yml +++ b/.github/workflows/style-checks.yml @@ -7,7 +7,16 @@ name: Coding style validation -on: [pull_request] +on: + pull_request: + paths-ignore: + - 'doc/**' + - '*.md' + - '*.pod' + - 'README*' + - 'funding.json' + - 'LICENSE.txt' + - 'VERSION.dat' jobs: check-style: @@ -15,16 +24,16 @@ jobs: steps: - uses: actions/checkout@v6 - uses: actions/setup-python@v6 - - name: "Get changed files" - env: - NUMBER: ${{ github.event.pull_request.number }} - GH_TOKEN: ${{ github.token }} + - name: "Fetch the base commit" run: | - { - echo 'CHANGED_FILES<> "$GITHUB_ENV" + # actions/checkout fetches a single commit by default + # (fetch-depth: 1), so the pull request's base commit is not + # present and pre-commit cannot work out which files changed. + # Depth 1 is enough here: the diff needs the base commit's tree, + # not its history. + git fetch --depth=1 origin ${{ github.event.pull_request.base.sha }} - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd #v3.0.1 with: - extra_args: "--files $CHANGED_FILES" + extra_args: >- + --from-ref ${{ github.event.pull_request.base.sha }} + --to-ref HEAD diff --git a/.github/workflows/valgrind-daily.yml b/.github/workflows/valgrind-daily.yml index ac5f7e052ef85..9167256b9443f 100644 --- a/.github/workflows/valgrind-daily.yml +++ b/.github/workflows/valgrind-daily.yml @@ -12,17 +12,56 @@ on: schedule: - cron: '30 02 * * *' workflow_dispatch: + inputs: + pr: + description: 'Internal: openssl-ci-bot PR number. Leave empty for a normal manual run.' + required: false + type: string + head_sha: + description: 'Internal: openssl-ci-bot commit SHA. Leave empty for a normal manual run.' + required: false + type: string + check_run_id: + description: 'Internal: openssl-ci-bot check-run ID. Leave empty for a normal manual run.' + required: false + type: string + +# Keep in sync with openssl-ci-bot's run-name parser, and with the Actions statistics +# collector that attributes CI load by parsing this same string. Both break silently. +run-name: >- + ${{ github.event.inputs.pr && format('ci-dispatch pr={0} head={1} check_run_id={2}', github.event.inputs.pr, github.event.inputs.head_sha, github.event.inputs.check_run_id) || github.workflow }} + +concurrency: + group: ${{ github.workflow }}-${{ github.event.inputs.pr || github.run_id }} + cancel-in-progress: true permissions: contents: read jobs: + validate-dispatch-inputs: + if: | + github.repository == 'openssl/openssl' && + (inputs.pr != '' || inputs.head_sha != '' || inputs.check_run_id != '') + uses: ./.github/workflows/validate-dispatch-inputs.yml + with: + pr: ${{ inputs.pr }} + head_sha: ${{ inputs.head_sha }} + check_run_id: ${{ inputs.check_run_id }} + check-valgrind-suppressions: + needs: [validate-dispatch-inputs] + if: | + !cancelled() && + (needs.validate-dispatch-inputs.result == 'success' || + (needs.validate-dispatch-inputs.result == 'skipped' && + inputs.pr == '' && inputs.head_sha == '' && inputs.check_run_id == '')) runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: persist-credentials: false + ref: ${{ github.event.inputs.head_sha || github.sha }} - name: Install valgrind run: | sudo apt-get -y update diff --git a/.github/workflows/validate-dispatch-inputs.yml b/.github/workflows/validate-dispatch-inputs.yml new file mode 100644 index 0000000000000..54c6b5eb93620 --- /dev/null +++ b/.github/workflows/validate-dispatch-inputs.yml @@ -0,0 +1,37 @@ +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the LICENSE file in the source distribution or at +# https://www.openssl.org/source/license.html + +name: Validate CI bot dispatch inputs + +on: + workflow_call: + inputs: + pr: + required: true + type: string + head_sha: + required: true + type: string + check_run_id: + required: true + type: string + +permissions: {} + +jobs: + validate: + runs-on: ubuntu-latest + steps: + - name: Validate pr / head_sha / check_run_id + env: + PR: ${{ inputs.pr }} + HEAD_SHA: ${{ inputs.head_sha }} + CHECK_RUN_ID: ${{ inputs.check_run_id }} + run: | + [[ "$PR" =~ ^[1-9][0-9]*$ ]] || { echo "::error::pr must be a positive integer"; exit 1; } + [[ "$CHECK_RUN_ID" =~ ^[1-9][0-9]*$ ]] || { echo "::error::check_run_id must be a positive integer"; exit 1; } + [[ "$HEAD_SHA" =~ ^[0-9a-fA-F]{40}$ ]] || { echo "::error::head_sha must be a 40-character hex commit SHA"; exit 1; } diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 6d8ebe39b75d2..7222304e033b9 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -7,7 +7,26 @@ name: Windows GitHub CI -on: [pull_request, push] +on: + pull_request: + paths-ignore: + - 'doc/**' + - '*.md' + - '*.pod' + - 'README*' + - 'funding.json' + - 'LICENSE.txt' + - 'VERSION.dat' + push: + paths-ignore: + - 'doc/**' + - '*.md' + - '*.pod' + - 'README*' + - 'funding.json' + - 'LICENSE.txt' + - 'VERSION.dat' + permissions: contents: read @@ -300,6 +319,52 @@ jobs: call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" jom test VERBOSE_FAILURE=yes TESTS=-test_fuzz* HARNESS_JOBS=4 + nmake: + # The other Windows jobs build with jom, which spawns commands + # differently from Microsoft's nmake. Build once with the real + # nmake, in-tree as NOTES-WINDOWS.md describes, so that makefile + # rules nmake handles differently are exercised, including the + # perlasm/nasm generator rules. Build only: the tests are covered + # by the jom jobs and nmake builds serially. + runs-on: windows-2022 + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + - name: install nasm + if: github.repository == 'openssl/openssl' + run: | + $installer = "nasm-3.01-installer-x64.exe" + Invoke-WebRequest -Uri "https://openssl-library.org/ci-deps/$installer" -OutFile $installer + $expected = (Get-Content "$env:GITHUB_WORKSPACE\.github\ci-deps.json" -Raw | ConvertFrom-Json).$installer + $actual = (Get-FileHash $installer -Algorithm SHA256).Hash + if ($actual -ne $expected) { throw "SHA256 mismatch for $installer (expected $expected, got $actual)" } + Start-Process -FilePath ".\$installer" -ArgumentList '/S' -Wait + "C:\Program Files\NASM" | Out-File -FilePath "$env:GITHUB_PATH" -Append + - name: install nasm (forks) + if: github.repository != 'openssl/openssl' + run: | + $installer = "nasm-3.01-installer-x64.exe" + Invoke-WebRequest -Uri "https://www.nasm.us/pub/nasm/releasebuilds/3.01/win64/$installer" -OutFile $installer + Start-Process -FilePath ".\$installer" -ArgumentList '/S' -Wait + "C:\Program Files\NASM" | Out-File -FilePath "$env:GITHUB_PATH" -Append + - name: config + shell: cmd + run: | + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + perl Configure --banner=Configured --strict-warnings no-makedepend no-fips -DOSSL_WINCTX=openssl VC-WIN64A + perl configdata.pm --dump + - name: build + shell: cmd + run: | + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + nmake /S + - name: check the build + shell: cmd + run: | + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + apps\openssl.exe version -a + cygwin: # Run a job for each of the specified target architectures: strategy: diff --git a/.gitignore b/.gitignore index 2c221ee7bd589..308516c4a171a 100644 --- a/.gitignore +++ b/.gitignore @@ -29,8 +29,16 @@ # Auto generated headers /crypto/buildinf.h +/crypto/asn1/charmap.h +/crypto/bn/bn_prime.h +/crypto/conf/conf_def.h +/crypto/objects/obj_dat.h +/crypto/objects/obj_xref.h /include/crypto/*_conf.h +/include/crypto/ec_params.h +/include/crypto/rsa_params.h /include/openssl/asn1.h +/include/openssl/obj_mac.h /include/openssl/asn1t.h /include/openssl/bio.h /include/openssl/cmp.h @@ -43,6 +51,7 @@ /include/openssl/ct.h /include/openssl/err.h /include/openssl/ess.h +/include/openssl/evp.h /include/openssl/fipskey.h /include/openssl/lhash.h /include/openssl/ocsp.h @@ -77,6 +86,7 @@ providers/common/der/der_rsa_gen.c providers/common/der/der_wrap_gen.c providers/common/der/der_sm2_gen.c providers/common/der/der_ml_dsa_gen.c +providers/common/der/der_composite_gen.c providers/common/der/der_hkdf_gen.c providers/common/include/prov/der_slh_dsa.h providers/common/include/prov/der_dsa.h @@ -123,9 +133,6 @@ providers/implementations/kem/ec_kem.inc providers/implementations/kem/ecx_kem.inc providers/implementations/kem/ml_kem_kem.inc providers/implementations/kem/rsa_kem.inc -providers/implementations/keymgmt/ml_dsa_kmgmt.inc -providers/implementations/keymgmt/ml_kem_kmgmt.inc -providers/implementations/keymgmt/mlx_kmgmt.inc providers/implementations/signature/dsa_sig.inc providers/implementations/signature/ecdsa_sig.inc providers/implementations/keymgmt/dh_kmgmt.inc @@ -137,7 +144,9 @@ providers/implementations/keymgmt/ml_dsa_kmgmt.inc providers/implementations/keymgmt/ml_kem_kmgmt.inc providers/implementations/keymgmt/mlx_kmgmt.inc providers/implementations/keymgmt/slh_dsa_kmgmt.inc +providers/implementations/keymgmt/composite_kmgmt.inc providers/implementations/keymgmt/template_kmgmt.inc +providers/implementations/signature/composite_sig.inc providers/implementations/signature/eddsa_sig.inc providers/implementations/signature/mac_legacy_sig.inc providers/implementations/signature/ml_dsa_sig.inc @@ -155,15 +164,21 @@ providers/implementations/ciphers/cipher_aes_ocb.inc providers/implementations/ciphers/cipher_aes_siv.inc providers/implementations/ciphers/cipher_aes_wrp.inc providers/implementations/ciphers/cipher_aes_xts.inc +providers/implementations/ciphers/cipher_ascon_aead128.inc providers/implementations/ciphers/ciphercommon.inc providers/implementations/ciphers/ciphercommon_ccm.inc providers/implementations/ciphers/ciphercommon_gcm.inc providers/implementations/ciphers/cipher_chacha20.inc providers/implementations/ciphers/cipher_chacha20_poly1305.inc +providers/implementations/ciphers/cipher_cts.inc +providers/implementations/ciphers/cipher_des.inc providers/implementations/ciphers/cipher_null.inc +providers/implementations/ciphers/cipher_rc2.inc providers/implementations/ciphers/cipher_rc4_hmac_md5.inc +providers/implementations/ciphers/cipher_rc5.inc providers/implementations/ciphers/cipher_sm2_xts.c providers/implementations/ciphers/cipher_sm4_xts.inc +providers/implementations/ciphers/cipher_tdes.inc providers/implementations/digests/blake2_prov.inc providers/implementations/digests/digestcommon.inc providers/implementations/digests/mdc2_prov.inc @@ -188,6 +203,116 @@ providers/implementations/rands/test_rng.inc # error code files /crypto/err/openssl.txt.old +# Generated error code files (from crypto/err/openssl.txt) +/crypto/asn1/asn1_err.c +/crypto/async/async_err.c +/crypto/bio/bio_err.c +/crypto/bn/bn_err.c +/crypto/buffer/buf_err.c +/crypto/cmp/cmp_err.c +/crypto/cms/cms_err.c +/crypto/comp/comp_err.c +/crypto/conf/conf_err.c +/crypto/cpt_err.c +/crypto/crmf/crmf_err.c +/crypto/ct/ct_err.c +/crypto/dh/dh_err.c +/crypto/dsa/dsa_err.c +/crypto/dso/dso_err.c +/crypto/ec/ec_err.c +/crypto/encode_decode/decoder_err.c +/crypto/encode_decode/encoder_err.c +/crypto/ess/ess_err.c +/crypto/evp/evp_err.c +/crypto/http/http_err.c +/crypto/objects/obj_err.c +/crypto/ocsp/ocsp_err.c +/crypto/pem/pem_err.c +/crypto/pkcs12/pk12err.c +/crypto/pkcs7/pkcs7err.c +/crypto/property/property_err.c +/crypto/rand/rand_err.c +/crypto/rsa/rsa_err.c +/crypto/sm2/sm2_err.c +/crypto/ssl_err.c +/crypto/sslerr.h +/crypto/store/store_err.c +/crypto/ts/ts_err.c +/crypto/ui/ui_err.c +/crypto/x509/v3err.c +/crypto/x509/x509_err.c +/include/crypto/asn1err.h +/include/crypto/asyncerr.h +/include/crypto/bioerr.h +/include/crypto/bnerr.h +/include/crypto/buffererr.h +/include/crypto/cmperr.h +/include/crypto/cmserr.h +/include/crypto/comperr.h +/include/crypto/conferr.h +/include/crypto/crmferr.h +/include/crypto/cryptoerr.h +/include/crypto/cterr.h +/include/crypto/decodererr.h +/include/crypto/dherr.h +/include/crypto/dsaerr.h +/include/crypto/ecerr.h +/include/crypto/encodererr.h +/include/crypto/esserr.h +/include/crypto/evperr.h +/include/crypto/httperr.h +/include/crypto/objectserr.h +/include/crypto/ocsperr.h +/include/crypto/pemerr.h +/include/crypto/pkcs12err.h +/include/crypto/pkcs7err.h +/include/crypto/randerr.h +/include/crypto/rsaerr.h +/include/crypto/sm2err.h +/include/crypto/storeerr.h +/include/crypto/tserr.h +/include/crypto/uierr.h +/include/crypto/x509err.h +/include/crypto/x509v3err.h +/include/internal/dsoerr.h +/include/internal/propertyerr.h +/include/openssl/asn1err.h +/include/openssl/asyncerr.h +/include/openssl/bioerr.h +/include/openssl/bnerr.h +/include/openssl/buffererr.h +/include/openssl/cmperr.h +/include/openssl/cmserr.h +/include/openssl/comperr.h +/include/openssl/conferr.h +/include/openssl/crmferr.h +/include/openssl/cryptoerr.h +/include/openssl/cterr.h +/include/openssl/decodererr.h +/include/openssl/dherr.h +/include/openssl/dsaerr.h +/include/openssl/ecerr.h +/include/openssl/encodererr.h +/include/openssl/esserr.h +/include/openssl/evperr.h +/include/openssl/httperr.h +/include/openssl/objectserr.h +/include/openssl/ocsperr.h +/include/openssl/pemerr.h +/include/openssl/pkcs12err.h +/include/openssl/pkcs7err.h +/include/openssl/proverr.h +/include/openssl/randerr.h +/include/openssl/rsaerr.h +/include/openssl/sslerr.h +/include/openssl/storeerr.h +/include/openssl/tserr.h +/include/openssl/uierr.h +/include/openssl/x509err.h +/include/openssl/x509v3err.h +/providers/common/include/prov/proverr.h +/providers/common/provider_err.c +/crypto/err/openssl.txt.stamp /engines/e_afalg.txt.old /engines/e_capi.txt.old /engines/e_dasync.txt.old @@ -291,11 +416,14 @@ providers/implementations/rands/test_rng.inc /demos/smime/smsign2 /demos/smime/smver /demos/sslecho/sslecho +/demos/dtlsecho/dtlsecho # Certain files that get created by tests on the fly /test-runs /test/buildtest_* /test/provider_internal_test.cnf +/test/pathed.cnf +/test/nocache-and-default.cnf /test/fipsmodule.cnf /providers/fipsmodule.cnf diff --git a/CHANGES.md b/CHANGES.md index da1bfd15ec9d8..76ad3073fe0c5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,8 @@ appropriate release branch. OpenSSL Releases ---------------- + - [OpenSSL 4.2](#openssl-42) + - [OpenSSL 4.1](#openssl-41) - [OpenSSL 4.0](#openssl-40) - [OpenSSL 3.6](#openssl-36) - [OpenSSL 3.5](#openssl-35) @@ -27,26 +29,130 @@ OpenSSL Releases - [OpenSSL 1.0.0](#openssl-100) - [OpenSSL 0.9.x](#openssl-09x) +OpenSSL 4.2 + +### Changes between 4.1 and 4.2 [xx XXX xxxx] + + * Added the `MLKEM512X25519` and `SecP256r1MLKEM512` hybrid TLS KEMs for the + newly assigned IANA codepoints per [draft-rosomakho-tls-ecdhe-mlkem512-00]. + + *Viktor Dukhovni* + + * Added public API for `IPAddrBlocks` ([RFC 3779]), mirroring the existing + `ASIdentifiers` API: `IPAddrBlocks_new()`, `IPAddrBlocks_free()`, + `d2i_IPAddrBlocks()`, `i2d_IPAddrBlocks()`, and the exported + `IPAddrBlocks_it` ASN.1 item for use in custom ASN.1 templates + (e.g. RPKI Signed Checklist). + + + *John Claus* + + * Added AVX-512 and VAES optimizations for AES-CTR mode. Performance for + large inputs (1024 bytes or more) improved by 2.9x to 3.9x. + + + *Madan Mohan Manokar* + + * Added support for parsing Java-generated PKCS#12 files containing symmetric + keys. The `openssl pkcs12` command can now extract symmetric secret keys + from PKCS#12 files created by Java's keytool utility. New API functions + `PKCS12_parse_ex()` with `PKCS12_PARSE_CTX` for selective extraction of + keys, certificates, and symmetric keys from PKCS#12 files. + + + *Dmitry Belyavskiy* + + * Added the ASCON-AEAD128 cipher as specified in NIST SP 800-232. ASCON-AEAD128 + provides authenticated encryption with associated data (AEAD) using 128-bit + keys, nonces, and tags. The cipher is available through the EVP interface and + the default provider. This implementation only supports byte-aligned inputs + and full-length tags. + + *Dominic Cunningham, Billy Bob Brumley* + +OpenSSL 4.1 ----------- ### Changes between 4.0 and 4.1 [xx XXX xxxx] + * Added 18 composite post-quantum signature algorithms combining ML-DSA with a + classical algorithm (RSA, ECDSA, or EdDSA), as defined in + [draft-ietf-lamps-pq-composite-sigs](https://datatracker.ietf.org/doc/draft-ietf-lamps-pq-composite-sigs): + id-MLDSA44-RSA2048-PSS-SHA256, id-MLDSA44-RSA2048-PKCS15-SHA256, + id-MLDSA44-Ed25519-SHA512, id-MLDSA44-ECDSA-P256-SHA256, + id-MLDSA65-RSA3072-PSS-SHA512, id-MLDSA65-RSA3072-PKCS15-SHA512, + id-MLDSA65-RSA4096-PSS-SHA512, id-MLDSA65-RSA4096-PKCS15-SHA512, + id-MLDSA65-ECDSA-P256-SHA512, id-MLDSA65-ECDSA-P384-SHA512, + id-MLDSA65-ECDSA-brainpoolP256r1-SHA512, id-MLDSA65-Ed25519-SHA512, + id-MLDSA87-ECDSA-P384-SHA512, id-MLDSA87-ECDSA-brainpoolP384r1-SHA512, + id-MLDSA87-Ed448-SHAKE256, id-MLDSA87-RSA3072-PSS-SHA512, + id-MLDSA87-RSA4096-PSS-SHA512, id-MLDSA87-ECDSA-P521-SHA512. + These algorithms are available in the default provider only. + + *Felipe Ventura* + * Added AVX512 optimized SHAKE x4 operations for ML-DSA on x86_64. + * Added support for DTLS 1.3 ([RFC 9147]). + Refer to the `ossl-guide-dtlsv13(7)` manual page for details. - *Marcel Cornu and Tomasz Kantecki* + *Frederik Wedel-Heinen and Ryan Hooper* - * EC key point format simplification. + * Added support for [RFC 8701] GREASE (Generate Random Extensions And Sustain + Extensibility). When `SSL_OP_GREASE` is set, the TLS client injects + reserved GREASE values into cipher suites, supported versions, supported + groups, signature algorithms, key share, and extensions in the `ClientHello` + to prevent ecosystem ossification. + Added `-grease` option to `openssl s_client` to enable this. + + + *William McCormack* + + * Added support for Ed25519 and Ed448 certificates in DTLS 1.2. Previously, + these certificate types were only supported in TLS 1.2 and TLS 1.3. + + + *Adriano Sela Aviles* + + * Added DTLS support to the SSL listener API. `SSL_new_listener()` can now + create a DTLS listener that demultiplexes incoming datagrams into per-peer + connections accepted with `SSL_accept_connection()`. The listener performs + address validation (`HelloVerifyRequest` for DTLS 1.0/1.2, + `HelloRetryRequest` cookie for DTLS 1.3) by default; pass + `SSL_LISTENER_FLAG_NO_VALIDATE` to disable it. Refer + to the `SSL_new_listener(3)` manual page for details. + + *Ryan Hooper* + + * Added configurable values for DTLS listeners, accessed + via `SSL_get_value_uint()`/`SSL_set_value_uint()`: + `SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS`, + `SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT`, + and `SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE`. Refer + to the `SSL_get_value_uint(3)` manual page for details. + + *Ryan Hooper* + + * Implemented an ability to configure additional QUIC transport parameters + via the `SSL_get_value_uint()`/`SSL_set_value_uint()` functions: + `max_udp_payload_size`, `initial_max_data`, + `initial_max_stream_data_bidi_local`, `initial_max_stream_data_uni`, + `ack_delay_exponent`, and `max_ack_delay`. + + + *Nikolas Gauder* + + * Simplified EC key point format handling. The point conversion form (compressed, uncompressed, or hybrid) is now a single value on the `EC_GROUP` and round-trips unchanged through import and export of `EC_KEY` objects. - Freshly generated keys have their public point encoded in - uncompressed form. A `point-format` supplied at key generation - time via `OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT` is - validated (an invalid value is rejected) but otherwise ignored - on the generated key. EC parameter generation continues to - honour the requested form on the group's generator; imported + Freshly generated keys have their public point encoded + in uncompressed form. A `point-format` supplied at key generation + time via `OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT` + is validated (an invalid value is rejected) but otherwise ignored + on the generated key. EC parameter generation continues + to honour the requested form on the group's generator; imported keys keep their form. The `ec_point_formats` extension no longer affects TLS 1.2 @@ -55,227 +161,759 @@ OpenSSL Releases and sends any EC certificate it has regardless of point form. TLS 1.3 disregards the extension entirely. - The RFC 4492/8422 section 5.1.2 requirement that the peer's - point-format list contain "uncompressed" is now enforced on - both sides (previously client-only), and only when an ECC - TLS 1.2 ciphersuite is negotiated -- a missing "uncompressed" - is ignored under TLS 1.3 or with a non-ECC cipher. + The [RFC 4492][RFC 4492 Section 5.1.2]/[8422 section 5.1.2][RFC 8422 Section 5.1.2] + requirement that the peer's point-format list contain "uncompressed" is now + enforced on both sides (previously client-only), and only when an ECC TLS 1.2 + ciphersuite is negotiated—a missing "uncompressed" is ignored under TLS 1.3 + or with a non-ECC cipher. + *Viktor Dukhovni* - * Added unit tests setup activated via `enable-unit-tests` option. This works - only on platforms with ld `--wrap` support (Linux, BSD). + * Added a new verification error, `X509_V_ERR_DUPLICATE_EXTENSION`, + with a descriptive message for certificates containing duplicate X.509 + extensions, which are explicitly prohibited by [RFC 5280]. + - *Jakub Zelenka* + *Daniel Kubec* - * Deprecated the `enable-unit-test` configure option and the - `SSL_test_functions()` function. Both will be removed in OpenSSL 5.0. + * Implemented extended support of metadata for symmetric key objects + (`EVP_SKEY`). + + + *Dmitry Belyavskiy* + + * Added `CMS_VERIFY_PARTIAL` flag to `CMS_verify()`, `-verify_partial` + option to `openssl cms -verify` operation, + and `CMS_SignerInfo_get_verification_result()` + and `CMS_SignerInfo_get0_signer_cert()` functions. + + If the `CMS_VERIFY_PARTIAL` flag is set, the `CMS_verify()` call + is successful if at least one of the individual signatures can be verified + (as opposed to all of them), which may be useful to gracefully handle various + situations, like missing CAs, expired certificates, or unsupported + algorithms; applications can call `CMS_get0_signers()` to check if the set + of valid signatures satisfies its policy, or use + `CMS_SignerInfo_get_verification_result()` + and `CMS_SignerInfo_get0_signer_cert()` functions to access the detailed + verification results. + + + *Jan Lübbe* + + * Added `OSSL_CMP_OPT_NONMATCHED_ERROR_NONCES` option for `OSSL_CMP_CTX` + and a corresponding `-nonmatched_error_nonces` option for the `openssl cmp` + command. + + This work was sponsored by Siemens AG. + + + *David von Oheimb* + + * Changed the output of the `-disabled` option for the `openssl list` command + to display disabled features, protocols, and algorithms, in relevant + sections. + + + *Paul Louvel* + + * Added `-n` option for the `openssl rand` command to suppress the trailing + newline in hexadecimal output mode. + + + *Evy Garden* + + * Added `-testmode` option for the `openssl s_time` command. + *Jakub Zelenka* - * Added -testmode option for `s_time` app. + * Added ability to utilise memory-mapped I/O when reading raw input + from a file for one-shot sign/verify operations (such as Ed25519, + Ed448, and ML-DSA) to `openssl pkeyutl` command on platforms + that support it (Unix-like). The `openssl dgst` command uses the same + approach for one-shot sign/verify when the input is from a file, removing + the previous 16 MB limit for file-based input. This improves performance + and supports large files without doubling memory use. Other platforms + and `stdin` input continue to use the existing buffer-based implementation. + + + *John Claus, Viktor Dukhovni, and David von Oheimb* + + * Added a `seed_strict` option to the `random` configuration section, + which makes the configured random seed source strictly enforced when + a provider (such as the FIPS provider) requests entropy or a nonce. + + When a provider requests seeding material before the primary DRBG + has been created, the request falls back to the operating system entropy + sources, because the seed source only comes into existence as a side + effect of creating the primary DRBG. Whether a configured seed source + is used therefore depends on operation order. With `seed_strict` enabled, + the seed source is instead instantiated on demand and an error is reported + if it cannot be used. The option is off by default with two exceptions: + the `JITTER` seed source seeds strictly unless the option disables it, + and `enable-fips-jitter` builds always seed strictly. Additionally, + the property query used to fetch the default seed source can now be set + at build time with `-DOPENSSL_DEFAULT_SEED_PROPQ`. + *Jakub Zelenka* - * Added support for Ed25519 and Ed448 certificates in DTLS 1.2. Previously, - these certificate types were only supported in TLS 1.2 and TLS 1.3. + * Added IKEV2 KDF (`EVP_KDF-IKEV2KDF`) to `EVP_KDF`. + - *Adriano Sela Aviles* + *Helen Zhang* - * SubjectPublicKeyInfo blobs whose AlgorithmIdentifier uses id-RSAES-OAEP - (`NID_rsaesOaep`, 1.2.840.113549.1.1.7) with a plain RSAPublicKey body - are now decoded as RSA keys. This is required for interoperability - with TPM 1.2 Endorsement Key certificates per TCG Credential Profiles - V1.2 section 3.2.7. The OAEP AlgorithmIdentifier parameters are not - interpreted. + * Added `CRYPTO_atomic_load_ptr`, `CRYPTO_atomic_store_ptr`, + and `CRYPTO_atomic_cmp_exch_ptr` functions to `libcrypto`, that implement + the respective atomic operations with a locking-based fallback on platforms + that do not support them. + + + *Neil Horman* + + * Added `EVP_EC_affine2oct()` function, that converts the affine coordinates + of an EC point to an octet string conforming + to [Section 2.3.4 of SECG SEC 1][SECG SEC 1 Section 2.3.4] ("Elliptic Curve + Cryptography") standard. + + + *Igor Ustinov* + + * Added `EVP_KDF_CTX_get0_kdf()` and `EVP_KDF_CTX_get1_kdf()` functions + as a replacement for the now deprecated `EVP_KDF_CTX_kdf()`. + + + *Leon Timmermans* + + * Added `ASN1_STRING_new_not_owned()` function to `libcrypto`. It provides + the ability to construct an `ASN1_STRING` with data for which ownership + is not taken by the created `ASN1_STRING` object. + + + *Bob Beck* + + * Added `ASN1_STRING_set1_data()`, `ASN1_STRING_set1_string()`, + and `ASN1_STRING_get_length()` API functions, and deprecated + `ASN1_STRING_set()` and `ASN1_STRING_length()`. + + The new setter functions do not append a terminating NUL byte to the newly + allocated strings, contrary to historic `ASN1_STRING_set()`'s behaviour, + so `ASN1_STRING_get0_data()` may return data not followed + by an out-of-`ASN1_STRING_get_length()` bounds NUL byte (whose presence + has never been guaranteed there by API contract) in more cases + than it used to before. A future release will switch to the usage + of the new APIs internally. + + When OpenSSL is built with `AddressSanitizer` or `MemorySanitizer` support, + or is run under Valgrind having been built where the Valgrind headers + are installed, the added NUL byte is marked inaccessible, so treating + the result of `ASN1_STRING_get0_data()` as a C string (`strlen()`, `%s`, + `strdup()` and the like) is reported as an error. All such uses + must be changed to honour `ASN1_STRING_get_length()`. The Valgrind + check may be disabled by building with `-DOPENSSL_NO_VALGRIND_CHECK`. + + + + + *Bob Beck* + + * Added `CMS_add_standard_smimecap_ex()` API function, which populates + an `SMIMECapabilities` list using `EVP_CIPHER_fetch()` and `EVP_MD_fetch()` + so that only algorithms available in the active providers are advertised. + `PKCS7_sign_add_signer()` was updated in the same way, so that legacy + ciphers, such as RC2 and DES, are no longer included in `SMIMECapabilities` + by default when only the default provider is loaded. + + + *Todd Short* + + * Added `CTLOG_STORE_add0_log()` function to add individual CT logs + to a `CTLOG_STORE`. + + + *Tim Perry* + + * Added `FIPS_mode()` macro as a convenience alias + to `EVP_default_properties_is_fips_enabled(NULL)`, which is a shorthand + to check whether the `fips=yes` property is currently enabled in the default + library context. + + + *Dimitri John Ledkov* + + * Refactored remaining cipher `OSSL_PARAM` name parsing so that automatically + generated parsers are used instead of `OSSL_PARAM_locate()` calls. + This should ensure that the list of acceptable parameters better matches + those which are actually processed. It should also provide a small + performance improvement, because repeated iteration over passed parameter + arrays is avoided. + + + *Dr Paul Dale* + + * Improved interoperability with TPM 1.2 Endorsement Key certificates + per [TCG Credential Profiles specification Version 1.2, Section 3.2.7]: + `SubjectPublicKeyInfo` blobs whose `AlgorithmIdentifier` uses + `id-RSAES-OAEP` (`NID_rsaesOaep`, 1.2.840.113549.1.1.7) with a plain + `RSAPublicKey` body are now decoded as RSA keys. The OAEP + `AlgorithmIdentifier` parameters are not interpreted. + *Craig Lorentzen* - * Do not issue TLS1.3 session tickets if the server has explicitly disabled + * Do not issue TLS 1.3 session tickets if the server has explicitly disabled them via `SSL_OP_NO_TICKET` and also turned off the session cache with `SSL_SESS_CACHE_OFF`. Both conditions together indicate a clear intent to - suppress resumption, so sending NewSessionTicket messages would be wasteful - and misleading. TLS1.3 client that does not send the `psk_key_exchange_modes` + suppress resumption, so sending `NewSessionTicket` messages would be wasteful + and misleading. TLS 1.3 client that does not send the `psk_key_exchange_modes` extension, or that sends it together with [RFC 9149] parameters such as `new_session_count = 0` or `resumption_count = 0`, is effectively signaling no interest in session tickets and session resumption. + *Daniel Kubec* + * Improved DTLS handshake robustness under UDP reordering by buffering + and replaying early `ChangeCipherSpec` (CCS) records at the expected state. + + + *Tong Li* + + * Updated X.509 certificate verification to no longer consult the subject + distinguished name (DN) by default. Previously, when a certificate contained + no subject alternative name of the type being checked, the subject + `commonName` (for host name checks) or `emailAddress` (for email checks) + was matched instead. The subject DN is now checked only when + the `X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT` flag is set. Correspondingly, + during chain verification, DNS name constraints are applied to the subject + `commonName` of the leaf certificate only when that flag is set, rather than + whenever the leaf had no DNS subject alternative name. + + + *Bob Beck* + + * Added various optimizations for the Elbrus2000 architecture + in the cryptographic and BN code. + + + *Gleb Popov* + + * Declared support for AArch64 Guarded Control Stack (GCS) in assembly code. + + When building with compilers that support GCS (Clang 18+, GCC 15+), + assembly modules are marked as compatible when branch protection + is enabled (e.g. `-mbranch-protection=standard`). No functional changes + to the assembly implementations are required, but compliance ensures + correct operation with shadow stack enforcement. + + + *Guillaume Gardet and Gowtham Suresh Kumar* + + * Added optimized ML-DSA and ML-KEM NTT operations on `ppc64le`. + + + + *Danny Tsen* + + * Added optimized ML-DSA NTT operations on `s390x` + (or other architectures with 128 bit vector registers). + + + *Timo Keller* + + * Added AVX2-optimized ML-DSA NTT operations on `x86_64`. + + + *Marcel Cornu and Tomasz Kantecki* + + * Added AVX-512-optimized SHAKE x4 operations for ML-DSA on `x86_64`. + + + *Marcel Cornu and Tomasz Kantecki* + + * Added AVX-512 and VAES optimizations for AES-CBC decryption. Decryption + performance for large inputs (1024 bytes or more) improved by 3.5x to 3.8x. + + + *Madan Mohan Manokar* + + * Added `VC-WIN32-MSVC2013` and `VC-WIN64A-MSVC2013` build targets to provide + internal functions for bridging the gaps in C99 standard support + that are present in MSVC 2013. + + + + *Bob Beck* + + * Added support for the (BSD-specific) `mdoc` format for the manual pages + output, which can be selected via `--manpage-format=mdoc` configuration + option. It requires presence of `pod2mdoc` utility in order for it to work. + + + *Enji Cooper* + + * Added unit tests setup activated via `enable-unit-tests` option. This works + only on platforms with ld `--wrap` support (Linux, BSD). + + + *Jakub Zelenka* + * Added test framework for testing function memory allocation failures. + *Jakub Zelenka* - * Windows-on-Itanium (VC-WIN64I) support was dropped - the Itanium - architecture has been discontinued and the platform is no longer - supported or tested. + * Updated header files to reflect modern development practices: all include + files now have header guards and they are self-contained (they include all + dependencies they need to be included on their own). + *Bob Beck* - * Windows CE support was dropped - Windows CE has been unsupported since - 2018 and does not have a modern C99 toolchain. + * Fixed a bug where a TLS 1.3 session ticket could retain a stale ALPN + protocol from an earlier connection after a resumption negotiated + a different protocol (or none), on both the server and the client, + which could otherwise affect a later 0-RTT decision. + + + *Daniel Kubec and Viktor Dukhovni* + + * Fixed `SSL_listen_ex()` to correctly adopt a QUIC connection and to preserve + queued connections on allocation failure. Invalid arguments, including + non-QUIC SSL objects, and internal failures now return `-1`, reserving `0` + for "no connection available". + + + *Mounir IDRASSI* + + * Fixed QUIC child objects to inherit the effective flags of their explicit + event domain. `SSL_get0_domain()` now reports that domain for connections + and streams in the hierarchy. + + + *Mounir IDRASSI* + + * Added script to generate CMP test credentials. + + This work was sponsored by Siemens AG. + + *Rajeev Ranjan* + + * Fixed TLS 1.3 clients to encrypt 0-RTT early data with the first offered + PSK identity ([RFC 9846 Section 4.3.10]) when a 0-RTT-capable resumption + ticket has aged out and an external PSK is offered in its place. The early + data was being encrypted with the retired ticket's secret, rather than + the external PSK's, causing the server to reject it with a bad record MAC. + + + *Viktor Dukhovni* + + * Fixed TLS 1.3 servers to reject early data when a resumed PSK's + ticket age is outside tolerance, per [RFC 9846], instead of accepting + 0-RTT data from a ticket that has aged out. + + + *Daniel Kubec* + + * Fixed TLS 1.3 external PSK connections being wrongly rejected when + the client sets a non-empty session ID context. + + + *Viktor Dukhovni* + + * Fixed a TLS 1.3 server with no session ID context to accept external PSK + connections and to stop issuing unusable session tickets. + + + *Viktor Dukhovni* + + * Fixed TLS 1.3 servers to reject early data when the selected ciphersuite + differs from the ciphersuite associated with the selected PSK. Same-hash + PSK resumption can still continue without accepting 0-RTT data. + + + *Mounir IDRASSI* + + * Fixed X.509v3 extension configuration parsing to reject repeated fields + in the `basicConstraints`, `basicAttConstraints`, and `policyConstraints` + X.509v3 extension configurations, instead of silently using the last value. + + + *Adam Tabak* + + * Fixed X.509 verification of certificate chains that use DSA signatures + with SHA-384 or SHA-512 by registering `dsa_with_SHA384` and + `dsa_with_SHA512` in the signature-algorithm cross-reference table. + + + *John Claus* + + * Fixed `CMS_SignerInfo_verify()` to no longer accept signature algorithm + identifiers as valid `digestAlgorithms`, in violation of [RFC 5652]. + + + *Jakub Zelenka* + + * Fixed reading of binary data (for example, certificates in DER format) + by `openssl` command from `stdin` on Windows. + + + *Milan Brož* + + * Fixed CRL scope checking for certificates without a CRL distribution + points extension. A CRL having an issuing distribution point extension + including a name that matches the certificate issuer name or any + `issuerAltName` of the certificate is now accepted, as required + by the default distribution point rule at the end + of [RFC 5280 Section 6.3.3], instead of being rejected + with `X509_V_ERR_DIFFERENT_CRL_SCOPE`. + + *Paul Grubbs* + + * TLS clients no longer send the TLS padding extension ([RFC 7685]). It was + only ever sent when `SSL_OP_TLSEXT_PADDING` was set, to work around + a `ClientHello` length bug in F5 middleboxes; the fix shipped long ago + and the affected hardware is long out of support, so nothing should still + be running the problematic version. + `SSL_OP_TLSEXT_PADDING` is now a no-op retained for compatibility, + and is no longer included in `SSL_OP_ALL`. + *Bob Beck* - * Improved DTLS handshake robustness under UDP reordering by buffering and - replaying early ChangeCipherSpec (CCS) records at the expected state. + * Changed `tsget` utility to use `Net::Curl::Easy` (from the `Net-Curl` CPAN + distribution) instead of the abandoned `WWW::Curl::Easy`. Users who rely + on `tsget` should install `Net::Curl::Easy` before upgrading. + - *Tong Li* + *Shreenidhi Shedi* + + * Deprecated the `enable-unit-test` configure option and the + `SSL_test_functions()` function. Both will be removed in OpenSSL 5.0. + + + *Jakub Zelenka* - * Header files in OpenSSL are being changed to reflect modern development - practices - Include files should all be guarded for inclusion by a define - and must be self contained, meaning they include all dependencies they need - to compile on their own. Headers have been changed to include guards and - to include the dependencies they require. Doing this will help the - future use of more modern tooling. + * Deprecated `BIO_snprintf()` and `BIO_vsnprintf()`. `snprintf()`, being part + of C99 standard, that is the baseline for OpenSSL since version 3.6, + is now considered universally available; moreover, the fact that `BIO_*()` + functions return -1 on truncation, rather than the would-have-been length, + makes their usage error-prone. Use `snprintf()` and `vsnprintf()` directly. + *Bob Beck* - * `EVP_CIPHER_CTX_get_num()` and `EVP_CIPHER_CTX_set_num()' have been deprecated. + * Deprecated undocumented public functions `UTF8_putc()` and `UTF8_getc()`. + No public replacement is planned. + - Refer to ossl-migration-guide(7) for more info. + *Bob Beck* + + * Deprecated `EVP_CIPHER_CTX_get_num()` and `EVP_CIPHER_CTX_set_num()` + functions. Refer to `ossl-migration-guide(7)` for more info. + *Shane Lontis* - * The functions `ASN1_BIT_STRING_name_print()`, `ASN1_BIT_STRING_num_asc(), - and `ASN1_BIT_STRING_set_asc()`, have been deprecated. Refer to the manual + * Deprecated `ASN1_BIT_STRING_name_print()`, `ASN1_BIT_STRING_num_asc()`, + and `ASN1_BIT_STRING_set_asc()` functions. Refer to the manual pages for more information. + *Bob Beck* - * The API functions `CRYPTO_atomic_load_ptr`, `CRYPTO_atomic_store_ptr`, and - `CRYPTO_atomic_cmp_exch_ptr` have been added to libcrypto. + * Deprecated `ASN1_BIT_STRING_set()` function in favour + of `ASN1_BIT_STRING_set1()`. + - *Neil Horman* + *Norbert Pócs* - * The `openssl pkeyutl` command now uses memory-mapped I/O when reading - raw input from a file for oneshot sign/verify operations (such as Ed25519, - Ed448, and ML-DSA) on platforms that support it (Unix-like). The - `openssl dgst` command uses the same approach for one-shot sign/verify - when the input is from a file, removing the previous 16 MB limit for - file-based input. This improves performance and supports large files - without doubling memory use. Other platforms and stdin input continue to - use the existing buffer-based path. + * Deprecated `CMS_stream()` and `PKCS7_stream()` API functions. These + are internal plumbing that was unintentionally exposed as the public API, + and they no longer return a streaming boundary. Use `BIO_new_CMS()` + or `BIO_new_PKCS7()` to stream CMS and PKCS#7 content. + - *John Claus* + *Bob Beck* -* 'X509_check_host()', 'X509_check_email()', 'X509_check_ip()', and 'X509_check_ip_asc()' - have been deprecated. Applications should migrate to setting a reference identifier - to check using 'X509_VERIFY_PARAM_set1_host()', 'X509_VERIFY_PARAM_set1_email()', or - X509_VERIFY_PARAM_set1_ip_asc()', and using 'X509_verify_cert()'. + * Deprecated `X509_check_host()`, `X509_check_email()`, `X509_check_ip()`, + and `X509_check_ip_asc()` functions. Applications should migrate to setting + a reference identifier to check using `X509_VERIFY_PARAM_set1_host()`, + `X509_VERIFY_PARAM_set1_email()`, or `X509_VERIFY_PARAM_set1_ip_asc()`, + and using `X509_verify_cert()`. + *Bob Beck* - * The API function `ASN1_STRING_new_not_owned` has been added to the - libcrypto. It provides the ability to construct an ASN1_STRING with data - for which ownership is not taken by the created ASN1_STRING object. + * Dropped Windows-on-Itanium (`VC-WIN64I`) and Windows CE (`VC-CE`) targets + from Configurations. + + *Bob Beck* - * Added AVX2 optimized ML-DSA NTT operations on `x86_64`. + * Dropped `no-ecdsa` and `no-ecdh` options from `Configure`, as these options + did not really disable the implementations. Use `no-ec` to disable + the elliptic curve support. + - *Marcel Cornu and Tomasz Kantecki* + *Tomáš Mráz* - * Changed the output of the -disabled option for the list command. - Displaying disabled features, protocols, and algorithms, in relevant sections. - Disabled features are now generated at configuration time. +OpenSSL 4.0 +----------- - *Paul Louvel* +### Changes between 4.0.1 and 4.0.2 [25 Aug 2026] - * Added `CTLOG_STORE_add0_log()` to add individual CT logs to a `CTLOG_STORE`. + * Fixed QUIC server being able to trigger double free when processing `INITIAL` + packet. - *Tim Perry* + Severity: Moderate - * Dropped `no-ecdsa` and `no-ecdh` options from `Configure` as these options - did not really disable the implementations. Use `no-ec` to disable the - elliptic curve support. + Issue summary: QUIC server may double free QRX (QUIC record layer RX) object + when channel creation fails for initial packet. - *Tomáš Mráz* + Impact summary: Double free leads to heap corruption, which typically results + in termination of QUIC server process, leading to a Denial of Service. + There is so far no evidence that this double free is exploitable for remote + code execution, thus it is considered highly improbable. - * Added `EVP_EC_affine2oct()` that converts the affine coordinates of an - EC point to an octet string conforming to Sec. 2.3.4 of the SECG SEC 1 - ("Elliptic Curve Cryptography") standard. + Reported by: Fuzz0x (ZKSC Institute of Security Research), Emilio Galle, + and Feng Xue (ThreatBoon). - *Igor Ustinov* + ([CVE-2026-18798]) - * Made more QUIC transport parameters configurable via the - `SSL_get_value_uint`/`SSL_set_value_uint` functions. Now also configurable: - `max_udp_payload_size`, `initial_max_data`, - `initial_max_stream_data_bidi_local`, `initial_max_stream_data_uni`, - `ack_delay_exponent`, `max_ack_delay`. + *Alexandr Nedvědický* - *Nikolas Gauder* + * Fixed heap buffer overflow in CMS key unwrapping. + + Severity: Moderate + + Issue summary: OpenSSL CMS decryption sizes the key-unwrap output buffer + based on querying the unwrapped key size, but the AES-WRAP-PAD unwrap + primitive can write and cleanse more bytes than that query reports, causing + an 8-byte out-of-bounds heap write. + + Impact summary: An attacker who supplies a crafted CMS message can trigger + a deterministic 8-byte out-of-bounds heap write when the victim decrypts it + with `CMS_decrypt()`, corrupting the heap and typically resulting in a Denial + of Service. + + Reported by: Bhabani Sankar Das and Filipe Casal (Trail of Bits). - * Add new verification error `X509_V_ERR_DUPLICATE_EXTENSION` with descriptive - message for certificates containing duplicate X.509 extensions, which are - explicitly prohibited by [RFC 5280]. + ([CVE-2026-63072]) *Daniel Kubec* - * Added `OSSL_CMP_OPT_NONMATCHED_ERROR_NONCES` option for `OSSL_CMP_CTX` and - a corresponding `-nonmatched_error_nonces` option for the `openssl cmp` command. + * Fixed invalid pointer dereference in CMP server via crafted `protectionAlg`. - This work was sponsored by Siemens AG. + Severity: Moderate - *David von Oheimb* + Issue Summary: The OpenSSL Certificate Management Protocol (CMP) + password-based protection verification only checks whether + the `protectionAlg` parameter was not NULL and not its ASN.1 type, + before treating it as a `PBMParameter`. A crafted message can contain + a parameter of a different type, which is then dereferenced as an invalid + pointer. - * Added support for RFC 8701 GREASE (Generate Random Extensions And Sustain - Extensibility). When `SSL_OP_GREASE` is set, the TLS client injects - reserved GREASE values into cipher suites, supported versions, supported - groups, signature algorithms, key share, and extensions in the ClientHello - to prevent ecosystem ossification. The `openssl s_client` command gains a - `-grease` option to enable this. + Impact summary: A remote, unauthenticated attacker can crash an application + acting as a CMP server that accepts PBM-protected messages, or a CMP client + talking to a malicious or intercepted CMP server, resulting in a Denial + of Service. - *William McCormack* + Reported by: Ying Dong and Bhabani Sankar Das. - * The undocumented public functions `UTF8_putc()` and `UTF8_getc()` - were deprecated, and their functionality moved internal to the - library. No public replacement is planned. + ([CVE-2026-63076]) - *Bob Beck* + *Daniel Kubec* - * Added IKEV2 KDF (EVP_KDF-IKEV2KDF) implementation. + * Fixed unbounded memory growth in QUIC server incoming channel queue. - *Helen Zhang* + Severity: Low - * Deprecated `ASN1_BIT_STRING_set()` in favour of `ASN1_BIT_STRING_set1()`. + Issue summary: When an OpenSSL QUIC server (Listener SSL object) processes + valid QUIC Initial packets for unknown destination connection IDs, it can + allocate and queue new incoming channels without enforcing any limit. - *Norbert Pócs* + Impact summary: A remote peer that can make many `INITIAL` packets reach + the server listener faster than the application accepts connections can + cause the memory allocated to store the per-channel state to grow + without any limits, potentially making the QUIC listener unavailable + and causing a Denial of Service. - * Added optimized ML-DSA NTT operations on `s390x` - (or other architectures with 128 bit vector registers). + Reported by: Filipe Casal (Trail of Bits) in collaboration with OpenAI. - *Timo Keller* + ([CVE-2026-14456]) + - * Added `EVP_KDF_CTX_get0_kdf()` and `EVP_KDF_CTX_get1_kdf()` functions - as a replacement for the now deprecated `EVP_KDF_CTX_kdf()`. + *Filipe Casal* - *Leon Timmermans* + * Fixed RPK server signature algorithm selection being able to dereference + a missing certificate. - * Add `FIPS_mode()` as a convenience define to - `EVP_default_properties_is_fips_enabled(NULL)`, which is - shorthand to check whether the `fips=yes` property is currently enabled - in the default library context. + Severity: Low - *Dimitri John Ledkov* + Issue summary: In a server or client configuration with [RFC 7250] Raw Public + Keys (RPKs) enabled, and only the private key (with no associated + certificate) configured locally, a NULL pointer dereference may occur + when the remote peer solicits raw public keys and also sends the typically + omitted `signature_algorithms_cert` TLS extension. -OpenSSL 4.0 ------------ + Impact summary: The impact is limited to a possible Denial of Service + as a result of an application abort, no data disclosure or remote command + execution are possible. + + Reported by: Filipe Casal (Trail of Bits) in collaboration with OpenAI. + + ([CVE-2026-14457]) + + *Viktor Dukhovni* + + * Fixed excessive memory use buffering DTLS records for a future epoch. + + Severity: Low + + Issue summary: Receiving a DTLS record for a future epoch while a handshake + is in progress causes OpenSSL to buffer far more memory than the record + itself requires. + + Impact summary: A peer can use a small amount of network traffic to make + an OpenSSL DTLS endpoint retain a disproportionately large amount of memory, + which may lead to a Denial of Service. + + Reported by: Amazon Web Services. + + ([CVE-2026-54874]) + + *Matt Caswell* + + * Fixed client-side memory leak in OCSP response checking. + + Severity: Low + + Issue summary: A malicious TLS server can cause a memory leak in a TLS + client that has enabled OCSP response checking by sending an OCSP response + that contains no single response entries. + + Impact summary: An attacker can leak an attacker-tunable amount of memory + per TLS handshake in a victim client application. A long-running client + that repeatedly connects to a malicious server can have its memory + exhausted, resulting in a Denial of Service. + + Reported by: Bhabani Sankar Das and Zhenzhe Shao. + + ([CVE-2026-54876]) + + + *Mounir IDRASSI* + + * Fixed untrusted Sender DN being used as a format string in CMP response + validation. + + Severity: Low + + Issue Summary: The OpenSSL Certificate Management Protocol (CMP) response + validation passed an unexpected response sender distinguished name directly + as the format string to `ERR_raise_data()`. + + Impact summary: A malicious or intercepted CMP endpoint can crash a CMP + client that enforces an expected sender or uses a pinned server certificate + whose subject becomes the default expected sender. + + Reported by: Filipe Casal (Trail of Bits) in collaboration with OpenAI, + Brandon Luo, and TrendAI Zero Day Initiative. + + ([CVE-2026-63073]) + + *Filipe Casal* + + * Fixed CMP indefinite cache growth of `extraCerts`. + + Severity: Low + + Issue Summary: The OpenSSL Certificate Management Protocol (CMP) caches + additional certificates (`extraCerts`) sent in a CMP message, but never + expunges them (for instance, if they are invalid). If a server reuses + an `OSSL_CMP_CTX` object frequently, this cache of `extraCerts` may grow + unboundedly, and a malicious client may flood a CMP server with requests + driving this growth. + + Impact Summary: Users utilizing a CMP server that reuses a single + `OSSL_CMP_CTX` object for the lifetime of a server process may observe + unbounded memory growth in the event a malicious client repeatedly sends + requests containing unique extra certificates, which may lead to OOM + conditions. + + Reported by: Pavol Zacik (Red Hat). + + ([CVE-2026-63074]) + + *Neil Horman* + + * Fixed QUIC ACK-only packet retention being able to cause memory exhaustion. + + Severity: Low + + Issue Summary: When OpenSSL processes QUIC traffic from a peer + that repeatedly sends ACK-eliciting packets while not acknowledging ACK-only + responses, the QUIC stack can retain ACK-only packet metadata + for the lifetime of the connection. + + Impact Summary: A remote peer that can complete a QUIC handshake can cause + connection-scoped memory growth, which may lead to a Denial of Service + through memory exhaustion, especially with sustained traffic or many + concurrent QUIC connections. + + Reported by: Opal Wright (Trail of Bits). + + ([CVE-2026-63075]) + + *Neil Horman* + + * Fixed possibility of AEAD forgeries with empty ciphertext when using + `EVP_Cipher()`. -### Changes between 4.0.1 and 4.0.2 [xx XXX XXXX] + Severity: Low + + Issue summary: ChaCha20-Poly1305 and AES-OCB decryption with an empty + ciphertext can report success without verifying the supplied authentication + tag when the operation is finalized by calling the `EVP_Cipher()` function. + + Impact summary: Applications calling `EVP_Cipher()` on an empty ciphertext + and expecting the call to check the AEAD tag may accept forged messages. + + Reported by: Billy Brumley (Rochester Institute of Technology). + + ([CVE-2026-75803]) + + + *Billy Bob Brumley* + + * Added `OPENSSL_armcap(3)` documentation page. + + + *Paul Elliott* - * Add client-side validation for TLS 1.3 session ticket lifetimes. + * Added support for selecting assembly code paths for LLVM-based Intel's `icx` + compiler. + - In accordance with [RFC 8446 Section 4.6.1](https://datatracker.ietf.org/doc/html/rfc8446#section-4.6.1), - TLS 1.3 clients must not cache session tickets - for longer than 7 days (604800 seconds). - When processing a new session ticket message with a - `ticket_lifetime_hint` value greater than 7 days, - the client now caps the lifetime to the - maximum permitted value of 7 days (604800 seconds). + *Wolfgang Beck* + + * Updated compliance with TLS 1.3 session ticket lifetime requirements. + TLS 1.3 clients now cap `ticket_lifetime_hint` to 7 days (604800 seconds) + when processing new session ticket messages, in accordance + with [RFC 8446 Section 4.6.1]. + *Abel Thomas* + * Fixed checking of authentication tags for empty ciphertexts for AEAD ciphers + in CCM cipher mode. + + + *Mounir IDRASSI* + ### Changes between 4.0.0 and 4.0.1 [9 Jun 2026] * Fixed heap use-after-free in `PKCS7_verify()`. @@ -610,6 +1248,21 @@ OpenSSL 4.0 *Dmitry Belyavskiy (Red Hat)* + * Fixed excessive allocation of the handshake message buffer (aka HollowByte). + + Previously, we would allocate a buffer large enough to hold the full size of + an incoming handshake message as advertised by the peer. This could be quite + large (although it is bounded, e.g. for ClientHello this is approximately + 128 KiB). If the peer then fails to send the full handshake message, then the + endpoint is left waiting for the remainder of the message to arrive and the + memory is still allocated (i.e. a Slowloris attack). To prevent this, we + incrementally grow the buffer as we receive the data. + + This issue was reported by Okta Red Team. + + + *Matt Caswell* + * Fixed a regression introduced in 4.0.0 that led to a `openssl pkey` command crash when it was invoked to encrypt a private key with password being provided interactively. @@ -23541,6 +24194,9 @@ ndif [CVE-2026-2673]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-2673 [CVE-2026-7383]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-7383 [CVE-2026-9076]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-9076 +[CVE-2026-14456]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-14456 +[CVE-2026-14457]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-14457 +[CVE-2026-18798]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-18798 [CVE-2026-22795]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-22795 [CVE-2026-22796]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-22796 [CVE-2026-28386]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-28386 @@ -23566,18 +24222,42 @@ ndif [CVE-2026-45445]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-45445 [CVE-2026-45446]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-45446 [CVE-2026-45447]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-45447 +[CVE-2026-54874]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-54874 +[CVE-2026-54876]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-54876 +[CVE-2026-63072]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63072 +[CVE-2026-63073]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63073 +[CVE-2026-63074]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63074 +[CVE-2026-63075]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63075 +[CVE-2026-63076]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63076 +[CVE-2026-75803]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-75803 [ESV]: https://csrc.nist.gov/Projects/cryptographic-module-validation-program/entropy-validations [RFC 2578 (STD 58), section 3.5]: https://datatracker.ietf.org/doc/html/rfc2578#section-3.5 [RFC 3211]: https://datatracker.ietf.org/doc/html/rfc3211 +[RFC 3779]: https://datatracker.ietf.org/doc/html/rfc3779 +[RFC 4492 Section 5.1.2]: https://datatracker.ietf.org/doc/html/rfc4492#section-5.1.2 +[RFC 5280]: https://datatracker.ietf.org/doc/html/rfc5280 +[RFC 5280 Section 6.3.3]: https://datatracker.ietf.org/doc/html/rfc5280#section-6.3.3 [RFC 5297]: https://datatracker.ietf.org/doc/html/rfc5297 +[RFC 5652]: https://datatracker.ietf.org/doc/html/rfc5652 +[RFC 7250]: https://datatracker.ietf.org/doc/html/rfc7250 +[RFC 7685]: https://datatracker.ietf.org/doc/html/rfc7685 [RFC 7919]: https://datatracker.ietf.org/doc/html/rfc7919 [RFC 8422]: https://datatracker.ietf.org/doc/html/rfc8422 +[RFC 8422 Section 5.1.2]: https://datatracker.ietf.org/doc/html/rfc8422#section-5.1.2 [RFC 8446]: https://datatracker.ietf.org/doc/html/rfc8446 +[RFC 8446 Section 4.6.1]: https://datatracker.ietf.org/doc/html/rfc8446#section-4.6.1 [RFC 8452]: https://datatracker.ietf.org/doc/html/rfc8452 +[RFC 8701]: https://datatracker.ietf.org/doc/html/rfc8701 [RFC 8998]: https://datatracker.ietf.org/doc/html/rfc8998#name-iana-considerations +[RFC 9147]: https://datatracker.ietf.org/doc/html/rfc9147 [RFC 9149]: https://datatracker.ietf.org/doc/html/rfc9149 +[RFC 9846]: https://datatracker.ietf.org/doc/html/rfc9846 +[RFC 9846 Section 4.3.10]: https://datatracker.ietf.org/doc/html/rfc9846#section-4.3.10 [RFC 9849]: https://datatracker.ietf.org/doc/html/rfc9849 +[SECG SEC 1 Section 2.3.4]: https://www.secg.org/sec1-v2.pdf#subsubsection.2.3.4 [SP 800-132]: https://csrc.nist.gov/pubs/sp/800/132/final [SP 800-185]: https://csrc.nist.gov/pubs/sp/800/185/final [SP 800-208]: https://csrc.nist.gov/pubs/sp/800/208/final +[TCG Credential Profiles specification Version 1.2, Section 3.2.7]: https://trustedcomputinggroup.org/wp-content/uploads/Credential_Profiles_V1.2_Level2_Revision8.pdf#page=35 [tls-hybrid-sm2-mlkem]: https://datatracker.ietf.org/doc/html/draft-yang-tls-hybrid-sm2-mlkem-03#name-iana-considerations +[draft-rosomakho-tls-ecdhe-mlkem512-00]: https://datatracker.ietf.org/doc/html/draft-rosomakho-tls-ecdhe-mlkem512-00.html diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8101e47114384..e4ade85d9bf5e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,13 +19,40 @@ open an issue for it before starting work, to get comments from the community. Someone may be already working on the same thing, or there may be special reasons why a feature is not implemented. -Similarly, if you plan to submit many pull requests, please start with -a representative sample (no more than 3 or 4) and open an issue -explaining your process. The OpenSSL project has limited resources, -especially when it comes to reviewers, so we appreciate advanced -communication before submitting many pull requests. In addition, -contributors should personally evaluate potential patches generated by -automated tools. +Do not submit changes in bulk. Review, not authorship, is the scarce +resource in this project: every pull request consumes the attention of +at least two committers, and a batch of them submitted together does not get +reviewed any faster than the same batch submitted over months. It +merely displaces the review of everyone else's work, including security +fixes. + +Nor is the answer to bundle them together. A pull request carrying +twenty unrelated fixes is harder to review than any one of them alone, +cannot be merged a piece at a time, and leaves every change in it blocked +behind the one a reviewer disagrees with. Each pull request should address +one logical change (perhaps spread across multiple commits); what has to give +is how many you submit, not how much you put in each one. + +Keep to no more than three or four open pull requests at a time, and let +those be reviewed to completion before opening more. If you are working +through a list of candidate changes, then choose those three or four +deliberately: send us the ones you consider most important, rather than the +first on the list or the quickest to write, and explain in each why it +matters. You know your list; we do not, and without that ranking the +judgement of what to look at first falls on the reviewers. Pull requests +opened well in excess of this may be closed without review, with a request to +resubmit at a sustainable rate. + +This applies regardless of how good the individual changes are, and it +is not satisfied by spacing submissions out over a few hours or days. + +You are the author of everything you submit, whatever produced the first +draft of it. Before opening a pull request you must have read the +change in full, understood why it is correct, built and tested it +yourself, and satisfied yourself that the problem it fixes is real. You +must be prepared to answer a reviewer's questions about any line of it. The +`Assisted-by:` trailer (see below) discloses that a tool was used; it does not +transfer responsibility for the result. Provide a clear description of the issue or feature being addressed, including any relevant implementation details and, for performance diff --git a/Configurations/10-main.conf b/Configurations/10-main.conf index 9c7261c3f209e..3d044e8045f64 100644 --- a/Configurations/10-main.conf +++ b/Configurations/10-main.conf @@ -1498,7 +1498,7 @@ my %targets = ( template => 1, CFLAGS => add(picker(debug => '/Od', release => '/O2')), - cflags => add(picker(default => '/Gs0 /GF /Gy', + cflags => add(picker(default => '/GF /Gy', debug => sub { ($disabled{shared} ? "" : ($disabled{"static-vcruntime"} ? "/MDd" : ($disabled{threads} ? "" : "/MTd"))); diff --git a/Configurations/50-e2k.conf b/Configurations/50-e2k.conf new file mode 100644 index 0000000000000..8bcad65087ece --- /dev/null +++ b/Configurations/50-e2k.conf @@ -0,0 +1,20 @@ +## -*- mode: perl; -*- +( + "linux-e2k" => { + inherit_from => [ "linux-generic64" ], + cflags => add("-m64"), + cxxflags => add("-m64"), + lib_cppflags => add("-DL_ENDIAN"), + multilib => "64", + bn_ops => "SIXTY_FOUR_BIT_LONG", + asm_arch => "e2k", + }, + "linux-e2kv6" => { + inherit_from => [ "linux-e2k" ], + asm_arch => "e2kv6", + }, + "linux-e2kv7" => { + inherit_from => [ "linux-e2k" ], + asm_arch => "e2kv7", + }, +); diff --git a/Configurations/50-win-hybridcrt.conf b/Configurations/50-win-hybridcrt.conf index 242583c728171..ddd4636a628a1 100644 --- a/Configurations/50-win-hybridcrt.conf +++ b/Configurations/50-win-hybridcrt.conf @@ -34,4 +34,13 @@ my %targets = ( lflags => add(picker(debug => "/NODEFAULTLIB:libucrtd.lib /DEFAULTLIB:ucrtd.lib", release => "/NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib")), }, + "VC-WIN64-ARM-HYBRIDCRT" => { + inherit_from => [ "VC-WIN64-ARM" ], + cflags => sub { + remove_from_flags(qr/\/MDd?\s/, add(picker(debug => "/MTd", + release => "/MT"))->(@_)) + }, + lflags => add(picker(debug => "/NODEFAULTLIB:libucrtd.lib /DEFAULTLIB:ucrtd.lib", + release => "/NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib")), + }, ); diff --git a/Configurations/50-win-msvc2013.conf b/Configurations/50-win-msvc2013.conf new file mode 100644 index 0000000000000..755144376e446 --- /dev/null +++ b/Configurations/50-win-msvc2013.conf @@ -0,0 +1,19 @@ +## -*- mode: perl; -*- +# Windows MSVC 2013 compatibility targets. +# +# Visual Studio versions earlier than VS 2015 (_MSC_VER < 1900) do not +# provide the C99 snprintf or vsnprintf functions, and their +# _snprintf / _vsnprintf counterparts have non-C99 semantics. These +# target variants build in a small compatibility source file that +# supplies C99 snprintf and vsnprintf. + +my %targets = ( + "VC-WIN32-MSVC2013" => { + inherit_from => [ "VC-WIN32" ], + needs_c99_snprintf_compat => 1, + }, + "VC-WIN64A-MSVC2013" => { + inherit_from => [ "VC-WIN64A" ], + needs_c99_snprintf_compat => 1, + }, +); diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl index 0d4ec0f983f36..f8a5b1612ed13 100644 --- a/Configurations/unix-Makefile.tmpl +++ b/Configurations/unix-Makefile.tmpl @@ -241,18 +241,22 @@ MISC_SCRIPTS={- IMAGEDOCS1={- join(" \\\n" . ' ' x 10, fill_lines(" ", $COLUMNS - 10, + map { '$(SRCDIR)/'.$_ } @{$unified_info{imagedocs}->{man1}})) -} IMAGEDOCS3={- join(" \\\n" . ' ' x 10, fill_lines(" ", $COLUMNS - 10, + map { '$(SRCDIR)/'.$_ } @{$unified_info{imagedocs}->{man3}})) -} IMAGEDOCS5={- join(" \\\n" . ' ' x 10, fill_lines(" ", $COLUMNS - 10, + map { '$(SRCDIR)/'.$_ } @{$unified_info{imagedocs}->{man5}})) -} IMAGEDOCS7={- join(" \\\n" . ' ' x 10, fill_lines(" ", $COLUMNS - 10, + map { '$(SRCDIR)/'.$_ } @{$unified_info{imagedocs}->{man7}})) -} HTMLDOCS1={- join(" \\\n" . ' ' x 10, @@ -270,6 +274,17 @@ HTMLDOCS7={- join(" \\\n" . ' ' x 10, fill_lines(" ", $COLUMNS - 10, @{$unified_info{htmldocs}->{man7}})) -} + +# The pods every HTML page is made from, which is what the whole set is +# converted from in one go. Each page's pod is the first element of its +# generator, the same place generatesrc() below takes it from. +HTMLPODS={- + join(" \\\n" . ' ' x 9, + fill_lines(" ", $COLUMNS - 9, + map { $unified_info{generate}->{$_}->[0] } + map { @{$unified_info{htmldocs}->{$_} // []} } + qw(man1 man3 man5 man7))) -} + MANDOCS1={- join(" \\\n" . ' ' x 9, fill_lines(" ", $COLUMNS - 9, @@ -287,6 +302,16 @@ MANDOCS7={- fill_lines(" ", $COLUMNS - 9, @{$unified_info{mandocs}->{man7}})) -} +# The pods every manual page is made from, which is what the whole manual +# is formatted from in one go. Each page's pod is the first element of its +# generator, the same place generatesrc() below takes it from. +MANPODS={- + join(" \\\n" . ' ' x 8, + fill_lines(" ", $COLUMNS - 8, + map { $unified_info{generate}->{$_}->[0] } + map { @{$unified_info{mandocs}->{$_} // []} } + qw(man1 man3 man5 man7))) -} + APPS_OPENSSL="{- use File::Spec::Functions; catfile("apps","openssl") -}" @@ -553,8 +578,37 @@ cov-report: $(SHLIBS) ##@ Documentation build_generated_pods: $(GENERATED_PODS) build_docs: build_man_docs build_html_docs ## Create documentation -build_man_docs: $(MANDOCS1) $(MANDOCS3) $(MANDOCS5) $(MANDOCS7) ## Create manpages -build_html_docs: $(HTMLDOCS1) $(HTMLDOCS3) $(HTMLDOCS5) $(HTMLDOCS7) ## Create HTML documentation +build_man_docs: doc/man/.mandocs.stamp ## Create manpages + +# The whole manual is formatted in one run. pod2man is a perl program that +# compiles Pod::Man before it reads a single pod, so a process per page +# spends most of its time loading the same module over nine hundred times. +# No target depends on an individual page -- the install recipes take them +# as arguments -- so a stamp is enough to order the work, and the per-page +# rules below stay available for building one page by name. +doc/man/.mandocs.stamp: {- $config{manpage_format} eq "roff" + ? '$(MANPODS)' + : '$(MANDOCS1) $(MANDOCS3) $(MANDOCS5) $(MANDOCS7)' -} +{- $config{manpage_format} eq "roff" + ? "\t" . '@$(ECHO) "Formatting the manual pages"' + . "\n\t" . '@$(PERL) $(SRCDIR)/util/mkpod2man.pl -o doc/man \\' + . "\n\t\t" . '-m "$(MANSUFFIX)" -d "$(RELEASE_DATE)" -r "$(VERSION)" \\' + . "\n\t\t" . '$(MANPODS)' + . "\n\t" . '@touch $@' + : "\t" . '@touch $@' -} + +build_html_docs: doc/html/.htmldocs.stamp ## Create HTML documentation + +# As with the manual pages, Pod::Html is compiled before the first pod is +# read, so the whole set is converted in one invocation rather than in a +# process per page. Nothing depends on an individual page -- the install +# recipe takes them as arguments -- so a stamp is enough to order the work, +# and the per-page rules below stay available for one page by name. +doc/html/.htmldocs.stamp: $(HTMLPODS) + @$(ECHO) "Converting the manual pages to HTML" + @$(PERL) $(SRCDIR)/util/mkpod2html.pl -o doc/html \ + -r "$(SRCDIR)/doc" $(HTMLPODS) + @touch $@ build_generated: $(GENERATED_MANDATORY) build_libs_nodep: $(LIBS) {- join(" ",map { platform->sharedlib_simple($_) // platform->sharedlib_import($_) // platform->sharedlib($_) // () } @{$unified_info{libraries}}) -} @@ -638,10 +692,12 @@ clean: libclean ## Clean the workspace, keep the configuration $(RM) $(HTMLDOCS3) $(RM) $(HTMLDOCS5) $(RM) $(HTMLDOCS7) + $(RM) doc/html/.htmldocs.stamp $(RM) $(MANDOCS1) $(RM) $(MANDOCS3) $(RM) $(MANDOCS5) $(RM) $(MANDOCS7) + $(RM) doc/man/.mandocs.stamp $(RM) $(PROGRAMS) $(TESTPROGS) $(MODULES) $(FIPSMODULE) $(SCRIPTS) $(RM) $(GENERATED_MANDATORY) $(GENERATED) $(RM) core @@ -660,8 +716,8 @@ clean: libclean ## Clean the workspace, keep the configuration -o -path './python-ecdsa' \ -o -path './tlsfuzzer' \ -o -path './tlslite-ng' \ - -o -path './wycheproof' \ - -prune \) \ + -o -path './wycheproof' \) \ + -prune \ -o \! -type d \ \( -name '*{- platform->depext() -}' \ -o -name '*{- platform->objext() -}' \ @@ -692,7 +748,18 @@ install: Makefile ## Install software and documentation, create OpenSSL director uninstall: {- "uninstall_docs" if !$disabled{docs}; -} uninstall_sw {- $disabled{fips} ? "" : "uninstall_fips" -} ## Uninstall software and documentation -install_sw: install_dev install_modules install_runtime ## Install just the software and libraries +# install_dev, install_modules and install_runtime each reach the build +# through a recursive $(MAKE) of their own, and they do not build disjoint +# sets: apps/libapps.a is a member of $(LIBS) and also a prerequisite of the +# installable programs. Under "make -j" the prerequisites below run at the +# same time, so two of those sub-makes build the archive concurrently and one +# removes it while the other is running ranlib over it. Build everything in +# a single make first; the sub-makes then find their targets current and +# build nothing. +install_sw: build_inst_sw ## Install just the software and libraries + "$(MAKE)" _install_sw + +_install_sw: install_dev install_modules install_runtime uninstall_sw: uninstall_runtime uninstall_modules uninstall_dev ## Uninstall the software and libraries @@ -707,11 +774,16 @@ install_fips: build_inst_sw $(INSTALL_FIPSMODULECONF) @$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(MODULESDIR)" @$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(OPENSSLDIR)" @$(ECHO) "*** Installing FIPS module" - @$(ECHO) "install $(INSTALL_FIPSMODULE) -> $(DESTDIR)$(MODULESDIR)/$(FIPSMODULENAME)" @cp "$(INSTALL_FIPSMODULE)" "$(DESTDIR)$(MODULESDIR)/$(FIPSMODULENAME).new" @chmod 755 "$(DESTDIR)$(MODULESDIR)/$(FIPSMODULENAME).new" - @mv -f "$(DESTDIR)$(MODULESDIR)/$(FIPSMODULENAME).new" \ - "$(DESTDIR)$(MODULESDIR)/$(FIPSMODULENAME)" + @if cmp -s "$(DESTDIR)$(MODULESDIR)/$(FIPSMODULENAME).new" \ + "$(DESTDIR)$(MODULESDIR)/$(FIPSMODULENAME)"; then \ + $(RM) "$(DESTDIR)$(MODULESDIR)/$(FIPSMODULENAME).new"; \ + else \ + $(ECHO) "install $(INSTALL_FIPSMODULE) -> $(DESTDIR)$(MODULESDIR)/$(FIPSMODULENAME)"; \ + mv -f "$(DESTDIR)$(MODULESDIR)/$(FIPSMODULENAME).new" \ + "$(DESTDIR)$(MODULESDIR)/$(FIPSMODULENAME)"; \ + fi @$(ECHO) "*** Installing FIPS module configuration" @$(ECHO) "install $(INSTALL_FIPSMODULECONF) -> $(DESTDIR)$(OPENSSLDIR)/fipsmodule.cnf" @cp $(INSTALL_FIPSMODULECONF) "$(DESTDIR)$(OPENSSLDIR)/fipsmodule.cnf" @@ -739,11 +811,16 @@ install_ssldirs: x1=`echo "$$x" | cut -f1 -d:`; \ x2=`echo "$$x" | cut -f2 -d:`; \ fn=`basename $$x1`; \ - $(ECHO) "install $$x1 -> $(DESTDIR)$(OPENSSLDIR)/misc/$$fn"; \ cp $$x1 "$(DESTDIR)$(OPENSSLDIR)/misc/$$fn.new"; \ chmod 755 "$(DESTDIR)$(OPENSSLDIR)/misc/$$fn.new"; \ - mv -f "$(DESTDIR)$(OPENSSLDIR)/misc/$$fn.new" \ - "$(DESTDIR)$(OPENSSLDIR)/misc/$$fn"; \ + if cmp -s "$(DESTDIR)$(OPENSSLDIR)/misc/$$fn.new" \ + "$(DESTDIR)$(OPENSSLDIR)/misc/$$fn"; then \ + $(RM) "$(DESTDIR)$(OPENSSLDIR)/misc/$$fn.new"; \ + else \ + $(ECHO) "install $$x1 -> $(DESTDIR)$(OPENSSLDIR)/misc/$$fn"; \ + mv -f "$(DESTDIR)$(OPENSSLDIR)/misc/$$fn.new" \ + "$(DESTDIR)$(OPENSSLDIR)/misc/$$fn"; \ + fi; \ if [ "$$x1" != "$$x2" ]; then \ ln=`basename "$$x2"`; \ : {- output_off() unless windowsdll(); "" -}; \ @@ -756,19 +833,31 @@ install_ssldirs: : {- output_on() if windowsdll(); "" -}; \ fi; \ done - @$(ECHO) "install $(SRCDIR)/apps/openssl.cnf -> $(DESTDIR)$(OPENSSLDIR)/openssl.cnf.dist" @cp $(SRCDIR)/apps/openssl.cnf "$(DESTDIR)$(OPENSSLDIR)/openssl.cnf.new" @chmod 644 "$(DESTDIR)$(OPENSSLDIR)/openssl.cnf.new" - @mv -f "$(DESTDIR)$(OPENSSLDIR)/openssl.cnf.new" "$(DESTDIR)$(OPENSSLDIR)/openssl.cnf.dist" + @if cmp -s "$(DESTDIR)$(OPENSSLDIR)/openssl.cnf.new" \ + "$(DESTDIR)$(OPENSSLDIR)/openssl.cnf.dist"; then \ + $(RM) "$(DESTDIR)$(OPENSSLDIR)/openssl.cnf.new"; \ + else \ + $(ECHO) "install $(SRCDIR)/apps/openssl.cnf -> $(DESTDIR)$(OPENSSLDIR)/openssl.cnf.dist"; \ + mv -f "$(DESTDIR)$(OPENSSLDIR)/openssl.cnf.new" \ + "$(DESTDIR)$(OPENSSLDIR)/openssl.cnf.dist"; \ + fi @if [ ! -f "$(DESTDIR)$(OPENSSLDIR)/openssl.cnf" ]; then \ $(ECHO) "install $(SRCDIR)/apps/openssl.cnf -> $(DESTDIR)$(OPENSSLDIR)/openssl.cnf"; \ cp $(SRCDIR)/apps/openssl.cnf "$(DESTDIR)$(OPENSSLDIR)/openssl.cnf"; \ chmod 644 "$(DESTDIR)$(OPENSSLDIR)/openssl.cnf"; \ fi - @$(ECHO) "install $(SRCDIR)/apps/ct_log_list.cnf -> $(DESTDIR)$(OPENSSLDIR)/ct_log_list.cnf.dist" @cp $(SRCDIR)/apps/ct_log_list.cnf "$(DESTDIR)$(OPENSSLDIR)/ct_log_list.cnf.new" @chmod 644 "$(DESTDIR)$(OPENSSLDIR)/ct_log_list.cnf.new" - @mv -f "$(DESTDIR)$(OPENSSLDIR)/ct_log_list.cnf.new" "$(DESTDIR)$(OPENSSLDIR)/ct_log_list.cnf.dist" + @if cmp -s "$(DESTDIR)$(OPENSSLDIR)/ct_log_list.cnf.new" \ + "$(DESTDIR)$(OPENSSLDIR)/ct_log_list.cnf.dist"; then \ + $(RM) "$(DESTDIR)$(OPENSSLDIR)/ct_log_list.cnf.new"; \ + else \ + $(ECHO) "install $(SRCDIR)/apps/ct_log_list.cnf -> $(DESTDIR)$(OPENSSLDIR)/ct_log_list.cnf.dist"; \ + mv -f "$(DESTDIR)$(OPENSSLDIR)/ct_log_list.cnf.new" \ + "$(DESTDIR)$(OPENSSLDIR)/ct_log_list.cnf.dist"; \ + fi @if [ ! -f "$(DESTDIR)$(OPENSSLDIR)/ct_log_list.cnf" ]; then \ $(ECHO) "install $(SRCDIR)/apps/ct_log_list.cnf -> $(DESTDIR)$(OPENSSLDIR)/ct_log_list.cnf"; \ cp $(SRCDIR)/apps/ct_log_list.cnf "$(DESTDIR)$(OPENSSLDIR)/ct_log_list.cnf"; \ @@ -780,26 +869,26 @@ install_dev: install_runtime_libs @$(ECHO) "*** Installing development files" @$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(INSTALLTOP)/include/openssl" @ : {- output_off() if $disabled{uplink}; "" -} - @$(ECHO) "install $(SRCDIR)/ms/applink.c -> $(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c" - @cp $(SRCDIR)/ms/applink.c "$(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c" - @chmod 644 "$(DESTDIR)$(INSTALLTOP)/include/openssl/applink.c" + @$(PERL) $(SRCDIR)/util/install-files.pl 644 \ + "$(DESTDIR)$(INSTALLTOP)/include/openssl" $(SRCDIR)/ms/applink.c @ : {- output_on() if $disabled{uplink}; "" -} - @set -e; for i in $(SRCDIR)/include/openssl/*.h \ - $(BLDDIR)/include/openssl/*.h; do \ - fn=`basename $$i`; \ - $(ECHO) "install $$i -> $(DESTDIR)$(INSTALLTOP)/include/openssl/$$fn"; \ - cp $$i "$(DESTDIR)$(INSTALLTOP)/include/openssl/$$fn"; \ - chmod 644 "$(DESTDIR)$(INSTALLTOP)/include/openssl/$$fn"; \ - done + @$(PERL) $(SRCDIR)/util/install-files.pl 644 \ + "$(DESTDIR)$(INSTALLTOP)/include/openssl" \ + $(SRCDIR)/include/openssl/*.h $(BLDDIR)/include/openssl/*.h @$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(libdir)" @set -e; for l in $(INSTALL_LIBS); do \ fn=`basename $$l`; \ - $(ECHO) "install $$l -> $(DESTDIR)$(libdir)/$$fn"; \ cp $$l "$(DESTDIR)$(libdir)/$$fn.new"; \ $(RANLIB) "$(DESTDIR)$(libdir)/$$fn.new"; \ chmod 644 "$(DESTDIR)$(libdir)/$$fn.new"; \ - mv -f "$(DESTDIR)$(libdir)/$$fn.new" \ - "$(DESTDIR)$(libdir)/$$fn"; \ + if cmp -s "$(DESTDIR)$(libdir)/$$fn.new" \ + "$(DESTDIR)$(libdir)/$$fn"; then \ + $(RM) "$(DESTDIR)$(libdir)/$$fn.new"; \ + else \ + $(ECHO) "install $$l -> $(DESTDIR)$(libdir)/$$fn"; \ + mv -f "$(DESTDIR)$(libdir)/$$fn.new" \ + "$(DESTDIR)$(libdir)/$$fn"; \ + fi; \ done @ : {- output_off() if $disabled{shared}; "" -} @set -e; for s in $(INSTALL_SHLIB_INFO); do \ @@ -841,19 +930,11 @@ install_dev: install_runtime_libs done @ : {- output_on() if $disabled{shared}; "" -} @$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(PKGCONFIGDIR)" - @for e in $(INSTALL_EXPORTERS_PKGCONFIG); do \ - fn=`basename $$e`; \ - $(ECHO) "install $$e -> $(DESTDIR)$(PKGCONFIGDIR)/$$fn"; \ - cp $$e "$(DESTDIR)$(PKGCONFIGDIR)/$$fn"; \ - chmod 644 "$(DESTDIR)$(PKGCONFIGDIR)/$$fn"; \ - done + @$(PERL) $(SRCDIR)/util/install-files.pl 644 \ + "$(DESTDIR)$(PKGCONFIGDIR)" $(INSTALL_EXPORTERS_PKGCONFIG) @$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(CMAKECONFIGDIR)" - @for e in $(INSTALL_EXPORTERS_CMAKE); do \ - fn=`basename $$e`; \ - $(ECHO) "install $$e -> $(DESTDIR)$(CMAKECONFIGDIR)/$$fn"; \ - cp $$e "$(DESTDIR)$(CMAKECONFIGDIR)/$$fn"; \ - chmod 644 "$(DESTDIR)$(CMAKECONFIGDIR)/$$fn"; \ - done + @$(PERL) $(SRCDIR)/util/install-files.pl 644 \ + "$(DESTDIR)$(CMAKECONFIGDIR)" $(INSTALL_EXPORTERS_CMAKE) uninstall_dev: uninstall_runtime_libs @$(ECHO) "*** Uninstalling development files" @@ -919,11 +1000,16 @@ install_modules: _install_modules_deps @set -e; for e in dummy $(INSTALL_MODULES); do \ if [ "$$e" = "dummy" ]; then continue; fi; \ fn=`basename $$e`; \ - $(ECHO) "install $$e -> $(DESTDIR)$(MODULESDIR)/$$fn"; \ cp $$e "$(DESTDIR)$(MODULESDIR)/$$fn.new"; \ chmod 755 "$(DESTDIR)$(MODULESDIR)/$$fn.new"; \ - mv -f "$(DESTDIR)$(MODULESDIR)/$$fn.new" \ - "$(DESTDIR)$(MODULESDIR)/$$fn"; \ + if cmp -s "$(DESTDIR)$(MODULESDIR)/$$fn.new" \ + "$(DESTDIR)$(MODULESDIR)/$$fn"; then \ + $(RM) "$(DESTDIR)$(MODULESDIR)/$$fn.new"; \ + else \ + $(ECHO) "install $$e -> $(DESTDIR)$(MODULESDIR)/$$fn"; \ + mv -f "$(DESTDIR)$(MODULESDIR)/$$fn.new" \ + "$(DESTDIR)$(MODULESDIR)/$$fn"; \ + fi; \ done uninstall_modules: @@ -950,17 +1036,27 @@ install_runtime_libs: build_libs if [ "$$s" = "dummy" ]; then continue; fi; \ fn=`basename $$s`; \ : {- output_off() unless windowsdll(); "" -}; \ - $(ECHO) "install $$s -> $(DESTDIR)$(bindir)/$$fn"; \ cp $$s "$(DESTDIR)$(bindir)/$$fn.new"; \ chmod 755 "$(DESTDIR)$(bindir)/$$fn.new"; \ - mv -f "$(DESTDIR)$(bindir)/$$fn.new" \ - "$(DESTDIR)$(bindir)/$$fn"; \ + if cmp -s "$(DESTDIR)$(bindir)/$$fn.new" \ + "$(DESTDIR)$(bindir)/$$fn"; then \ + $(RM) "$(DESTDIR)$(bindir)/$$fn.new"; \ + else \ + $(ECHO) "install $$s -> $(DESTDIR)$(bindir)/$$fn"; \ + mv -f "$(DESTDIR)$(bindir)/$$fn.new" \ + "$(DESTDIR)$(bindir)/$$fn"; \ + fi; \ : {- output_on() unless windowsdll(); "" -}{- output_off() if windowsdll(); "" -}; \ - $(ECHO) "install $$s -> $(DESTDIR)$(libdir)/$$fn"; \ cp $$s "$(DESTDIR)$(libdir)/$$fn.new"; \ chmod 755 "$(DESTDIR)$(libdir)/$$fn.new"; \ - mv -f "$(DESTDIR)$(libdir)/$$fn.new" \ - "$(DESTDIR)$(libdir)/$$fn"; \ + if cmp -s "$(DESTDIR)$(libdir)/$$fn.new" \ + "$(DESTDIR)$(libdir)/$$fn"; then \ + $(RM) "$(DESTDIR)$(libdir)/$$fn.new"; \ + else \ + $(ECHO) "install $$s -> $(DESTDIR)$(libdir)/$$fn"; \ + mv -f "$(DESTDIR)$(libdir)/$$fn.new" \ + "$(DESTDIR)$(libdir)/$$fn"; \ + fi; \ : {- output_on() if windowsdll(); "" -}; \ done @@ -971,20 +1067,30 @@ install_programs: install_runtime_libs build_inst_programs @set -e; for x in dummy $(INSTALL_PROGRAMS); do \ if [ "$$x" = "dummy" ]; then continue; fi; \ fn=`basename $$x`; \ - $(ECHO) "install $$x -> $(DESTDIR)$(bindir)/$$fn"; \ cp $$x "$(DESTDIR)$(bindir)/$$fn.new"; \ chmod 755 "$(DESTDIR)$(bindir)/$$fn.new"; \ - mv -f "$(DESTDIR)$(bindir)/$$fn.new" \ - "$(DESTDIR)$(bindir)/$$fn"; \ + if cmp -s "$(DESTDIR)$(bindir)/$$fn.new" \ + "$(DESTDIR)$(bindir)/$$fn"; then \ + $(RM) "$(DESTDIR)$(bindir)/$$fn.new"; \ + else \ + $(ECHO) "install $$x -> $(DESTDIR)$(bindir)/$$fn"; \ + mv -f "$(DESTDIR)$(bindir)/$$fn.new" \ + "$(DESTDIR)$(bindir)/$$fn"; \ + fi; \ done @set -e; for x in dummy $(BIN_SCRIPTS); do \ if [ "$$x" = "dummy" ]; then continue; fi; \ fn=`basename $$x`; \ - $(ECHO) "install $$x -> $(DESTDIR)$(bindir)/$$fn"; \ cp $$x "$(DESTDIR)$(bindir)/$$fn.new"; \ chmod 755 "$(DESTDIR)$(bindir)/$$fn.new"; \ - mv -f "$(DESTDIR)$(bindir)/$$fn.new" \ - "$(DESTDIR)$(bindir)/$$fn"; \ + if cmp -s "$(DESTDIR)$(bindir)/$$fn.new" \ + "$(DESTDIR)$(bindir)/$$fn"; then \ + $(RM) "$(DESTDIR)$(bindir)/$$fn.new"; \ + else \ + $(ECHO) "install $$x -> $(DESTDIR)$(bindir)/$$fn"; \ + mv -f "$(DESTDIR)$(bindir)/$$fn.new" \ + "$(DESTDIR)$(bindir)/$$fn"; \ + fi; \ done uninstall_runtime: uninstall_programs uninstall_runtime_libs @@ -1026,69 +1132,33 @@ install_man_docs: build_man_docs @$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(MANDIR)/man5" @$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(MANDIR)/man7" @$(ECHO) "*** Installing manpages" - @set -e; for x in dummy $(MANDOCS1); do \ - if [ "$$x" = "dummy" ]; then continue; fi; \ - fn=`basename $$x`; \ - $(ECHO) "install $$x -> $(DESTDIR)$(MANDIR)/man1/$${fn}$(MANSUFFIX)"; \ - cp $$x "$(DESTDIR)$(MANDIR)/man1/$${fn}$(MANSUFFIX)"; \ - chmod 644 "$(DESTDIR)$(MANDIR)/man1/$${fn}$(MANSUFFIX)"; \ - $(PERL) $(SRCDIR)/util/write-man-symlinks install $(SRCDIR)/doc/man1 $(BLDDIR)/doc/man1 $${fn}$(MANSUFFIX) "$(DESTDIR)$(MANDIR)/man1"; \ - done - @set -e; for x in dummy $(MANDOCS3); do \ - if [ "$$x" = "dummy" ]; then continue; fi; \ - fn=`basename $$x`; \ - $(ECHO) "install $$x -> $(DESTDIR)$(MANDIR)/man3/$${fn}$(MANSUFFIX)"; \ - cp $$x "$(DESTDIR)$(MANDIR)/man3/$${fn}$(MANSUFFIX)"; \ - chmod 644 "$(DESTDIR)$(MANDIR)/man3/$${fn}$(MANSUFFIX)"; \ - $(PERL) $(SRCDIR)/util/write-man-symlinks install $(SRCDIR)/doc/man3 $(BLDDIR)/doc/man3 $${fn}$(MANSUFFIX) "$(DESTDIR)$(MANDIR)/man3"; \ - done - @set -e; for x in dummy $(MANDOCS5); do \ - if [ "$$x" = "dummy" ]; then continue; fi; \ - fn=`basename $$x`; \ - $(ECHO) "install $$x -> $(DESTDIR)$(MANDIR)/man5/$${fn}$(MANSUFFIX)"; \ - cp $$x "$(DESTDIR)$(MANDIR)/man5/$${fn}$(MANSUFFIX)"; \ - chmod 644 "$(DESTDIR)$(MANDIR)/man5/$${fn}$(MANSUFFIX)"; \ - $(PERL) $(SRCDIR)/util/write-man-symlinks install $(SRCDIR)/doc/man5 $(BLDDIR)/doc/man5 $${fn}$(MANSUFFIX) "$(DESTDIR)$(MANDIR)/man5"; \ - done - @set -e; for x in dummy $(MANDOCS7); do \ - if [ "$$x" = "dummy" ]; then continue; fi; \ - fn=`basename $$x`; \ - $(ECHO) "install $$x -> $(DESTDIR)$(MANDIR)/man7/$${fn}$(MANSUFFIX)"; \ - cp $$x "$(DESTDIR)$(MANDIR)/man7/$${fn}$(MANSUFFIX)"; \ - chmod 644 "$(DESTDIR)$(MANDIR)/man7/$${fn}$(MANSUFFIX)"; \ - $(PERL) $(SRCDIR)/util/write-man-symlinks install $(SRCDIR)/doc/man7 $(BLDDIR)/doc/man7 $${fn}$(MANSUFFIX) "$(DESTDIR)$(MANDIR)/man7"; \ - done + @$(PERL) $(SRCDIR)/util/install-man-pages.pl install \ + $(SRCDIR)/doc/man1 $(BLDDIR)/doc/man1 \ + "$(DESTDIR)$(MANDIR)/man1" "$(MANSUFFIX)" $(MANDOCS1) + @$(PERL) $(SRCDIR)/util/install-man-pages.pl install \ + $(SRCDIR)/doc/man3 $(BLDDIR)/doc/man3 \ + "$(DESTDIR)$(MANDIR)/man3" "$(MANSUFFIX)" $(MANDOCS3) + @$(PERL) $(SRCDIR)/util/install-man-pages.pl install \ + $(SRCDIR)/doc/man5 $(BLDDIR)/doc/man5 \ + "$(DESTDIR)$(MANDIR)/man5" "$(MANSUFFIX)" $(MANDOCS5) + @$(PERL) $(SRCDIR)/util/install-man-pages.pl install \ + $(SRCDIR)/doc/man7 $(BLDDIR)/doc/man7 \ + "$(DESTDIR)$(MANDIR)/man7" "$(MANSUFFIX)" $(MANDOCS7) uninstall_man_docs: build_man_docs @$(ECHO) "*** Uninstalling manpages" - @set -e; for x in dummy $(MANDOCS1); do \ - if [ "$$x" = "dummy" ]; then continue; fi; \ - fn=`basename $$x`; \ - $(ECHO) "$(RM) $(DESTDIR)$(MANDIR)/man1/$${fn}$(MANSUFFIX)"; \ - $(RM) "$(DESTDIR)$(MANDIR)/man1/$${fn}$(MANSUFFIX)"; \ - $(PERL) $(SRCDIR)/util/write-man-symlinks uninstall $(SRCDIR)/doc/man1 $(BLDDIR)/doc/man1 $${fn}$(MANSUFFIX) "$(DESTDIR)$(MANDIR)/man1"; \ - done - @set -e; for x in dummy $(MANDOCS3); do \ - if [ "$$x" = "dummy" ]; then continue; fi; \ - fn=`basename $$x`; \ - $(ECHO) "$(RM) $(DESTDIR)$(MANDIR)/man3/$${fn}$(MANSUFFIX)"; \ - $(RM) "$(DESTDIR)$(MANDIR)/man3/$${fn}$(MANSUFFIX)"; \ - $(PERL) $(SRCDIR)/util/write-man-symlinks uninstall $(SRCDIR)/doc/man3 $(BLDDIR)/doc/man3 $${fn}$(MANSUFFIX) "$(DESTDIR)$(MANDIR)/man3"; \ - done - @set -e; for x in dummy $(MANDOCS5); do \ - if [ "$$x" = "dummy" ]; then continue; fi; \ - fn=`basename $$x`; \ - $(ECHO) "$(RM) $(DESTDIR)$(MANDIR)/man5/$${fn}$(MANSUFFIX)"; \ - $(RM) "$(DESTDIR)$(MANDIR)/man5/$${fn}$(MANSUFFIX)"; \ - $(PERL) $(SRCDIR)/util/write-man-symlinks uninstall $(SRCDIR)/doc/man5 $(BLDDIR)/doc/man5 $${fn}$(MANSUFFIX) "$(DESTDIR)$(MANDIR)/man5"; \ - done - @set -e; for x in dummy $(MANDOCS7); do \ - if [ "$$x" = "dummy" ]; then continue; fi; \ - fn=`basename $$x`; \ - $(ECHO) "$(RM) $(DESTDIR)$(MANDIR)/man7/$${fn}$(MANSUFFIX)"; \ - $(RM) "$(DESTDIR)$(MANDIR)/man7/$${fn}$(MANSUFFIX)"; \ - $(PERL) $(SRCDIR)/util/write-man-symlinks uninstall $(SRCDIR)/doc/man7 $(BLDDIR)/doc/man7 $${fn}$(MANSUFFIX) "$(DESTDIR)$(MANDIR)/man7"; \ - done + @$(PERL) $(SRCDIR)/util/install-man-pages.pl uninstall \ + $(SRCDIR)/doc/man1 $(BLDDIR)/doc/man1 \ + "$(DESTDIR)$(MANDIR)/man1" "$(MANSUFFIX)" $(MANDOCS1) + @$(PERL) $(SRCDIR)/util/install-man-pages.pl uninstall \ + $(SRCDIR)/doc/man3 $(BLDDIR)/doc/man3 \ + "$(DESTDIR)$(MANDIR)/man3" "$(MANSUFFIX)" $(MANDOCS3) + @$(PERL) $(SRCDIR)/util/install-man-pages.pl uninstall \ + $(SRCDIR)/doc/man5 $(BLDDIR)/doc/man5 \ + "$(DESTDIR)$(MANDIR)/man5" "$(MANSUFFIX)" $(MANDOCS5) + @$(PERL) $(SRCDIR)/util/install-man-pages.pl uninstall \ + $(SRCDIR)/doc/man7 $(BLDDIR)/doc/man7 \ + "$(DESTDIR)$(MANDIR)/man7" "$(MANSUFFIX)" $(MANDOCS7) install_html_docs: install_image_docs build_html_docs @[ -n "$(INSTALLTOP)" ] || (echo INSTALLTOP should not be empty; exit 1) @@ -1097,34 +1167,14 @@ install_html_docs: install_image_docs build_html_docs @$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(HTMLDIR)/man5" @$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(HTMLDIR)/man7" @$(ECHO) "*** Installing HTML manpages" - @set -e; for x in dummy $(HTMLDOCS1); do \ - if [ "$$x" = "dummy" ]; then continue; fi; \ - fn=`basename $$x`; \ - $(ECHO) "install $$x -> $(DESTDIR)$(HTMLDIR)/man1/$$fn"; \ - cp $$x "$(DESTDIR)$(HTMLDIR)/man1/$$fn"; \ - chmod 644 "$(DESTDIR)$(HTMLDIR)/man1/$$fn"; \ - done - @set -e; for x in dummy $(HTMLDOCS3); do \ - if [ "$$x" = "dummy" ]; then continue; fi; \ - fn=`basename $$x`; \ - $(ECHO) "install $$x -> $(DESTDIR)$(HTMLDIR)/man3/$$fn"; \ - cp $$x "$(DESTDIR)$(HTMLDIR)/man3/$$fn"; \ - chmod 644 "$(DESTDIR)$(HTMLDIR)/man3/$$fn"; \ - done - @set -e; for x in dummy $(HTMLDOCS5); do \ - if [ "$$x" = "dummy" ]; then continue; fi; \ - fn=`basename $$x`; \ - $(ECHO) "install $$x -> $(DESTDIR)$(HTMLDIR)/man5/$$fn"; \ - cp $$x "$(DESTDIR)$(HTMLDIR)/man5/$$fn"; \ - chmod 644 "$(DESTDIR)$(HTMLDIR)/man5/$$fn"; \ - done - @set -e; for x in dummy $(HTMLDOCS7); do \ - if [ "$$x" = "dummy" ]; then continue; fi; \ - fn=`basename $$x`; \ - $(ECHO) "install $$x -> $(DESTDIR)$(HTMLDIR)/man7/$$fn"; \ - cp $$x "$(DESTDIR)$(HTMLDIR)/man7/$$fn"; \ - chmod 644 "$(DESTDIR)$(HTMLDIR)/man7/$$fn"; \ - done + @$(PERL) $(SRCDIR)/util/install-files.pl 644 \ + "$(DESTDIR)$(HTMLDIR)/man1" $(HTMLDOCS1) + @$(PERL) $(SRCDIR)/util/install-files.pl 644 \ + "$(DESTDIR)$(HTMLDIR)/man3" $(HTMLDOCS3) + @$(PERL) $(SRCDIR)/util/install-files.pl 644 \ + "$(DESTDIR)$(HTMLDIR)/man5" $(HTMLDOCS5) + @$(PERL) $(SRCDIR)/util/install-files.pl 644 \ + "$(DESTDIR)$(HTMLDIR)/man7" $(HTMLDOCS7) uninstall_html_docs: uninstall_image_docs @$(ECHO) "*** Uninstalling HTML manpages" @@ -1155,13 +1205,8 @@ uninstall_html_docs: uninstall_image_docs install_image_docs: @$(PERL) $(SRCDIR)/util/mkdir-p.pl "$(DESTDIR)$(HTMLDIR)/man7/img" - @set -e; for x in dummy $(IMAGEDOCS7); do \ - if [ "$$x" = "dummy" ]; then continue; fi; \ - fn=`basename $$x`; \ - $(ECHO) "install $$x -> $(DESTDIR)$(HTMLDIR)/man7/img/$$fn"; \ - cp $(SRCDIR)/$$x "$(DESTDIR)$(HTMLDIR)/man7/img/$$fn"; \ - chmod 644 "$(DESTDIR)$(HTMLDIR)/man7/img/$$fn"; \ - done + @$(PERL) $(SRCDIR)/util/install-files.pl 644 \ + "$(DESTDIR)$(HTMLDIR)/man7/img" $(IMAGEDOCS7) uninstall_image_docs: @set -e; for x in dummy $(IMAGEDOCS7); do \ @@ -1178,10 +1223,13 @@ uninstall_image_docs: # is sensitive to build.info changes. update: generate errors ordinals generate_buildinfo ## Update errors, ordinals and build info -.PHONY: generate generate_apps generate_crypto_bn generate_crypto_objects \ - generate_crypto_conf generate_crypto_asn1 generate_fuzz_oids -generate: generate_apps generate_crypto_bn generate_crypto_objects \ - generate_crypto_conf generate_crypto_asn1 generate_fuzz_oids +# $(UPTODATE) target input... succeeds when target exists and is strictly +# newer than every input, and fails otherwise; used to skip regeneration +# of a target that is already current. +UPTODATE=$(PERL) -e 'my $$o = shift; exit 1 unless -e $$o; -M $$o < -M $$_ or exit 1 for @ARGV' + +.PHONY: generate generate_apps generate_crypto_objects generate_fuzz_oids +generate: generate_apps generate_crypto_objects generate_fuzz_oids .PHONY: generate_buildinfo generate_doc_buildinfo generate_buildinfo: generate_doc_buildinfo @@ -1223,42 +1271,31 @@ check-format: check-clang-format-diff-cmd ## Evaluate C code according to OpenSS ( cd $(SRCDIR); git diff -U0 --no-prefix --no-color | $(CLANG_FORMAT_DIFF) ) generate_apps: - ( cd $(SRCDIR); $(PERL) VMS/VMSify-conf.pl \ + ( cd $(SRCDIR); \ + $(UPTODATE) apps/openssl-vms.cnf \ + apps/openssl.cnf VMS/VMSify-conf.pl || \ + $(PERL) VMS/VMSify-conf.pl \ < apps/openssl.cnf > apps/openssl-vms.cnf ) -generate_crypto_bn: - ( cd $(SRCDIR); $(PERL) crypto/bn/bn_prime.pl > crypto/bn/bn_prime.h ) - generate_crypto_objects: - ( cd $(SRCDIR); $(PERL) crypto/objects/objects.pl -n \ - crypto/objects/objects.txt \ - crypto/objects/obj_mac.num \ - > crypto/objects/obj_mac.new && \ - mv crypto/objects/obj_mac.new crypto/objects/obj_mac.num ) - ( cd $(SRCDIR); $(PERL) crypto/objects/objects.pl \ - crypto/objects/objects.txt \ - crypto/objects/obj_mac.num \ - > include/openssl/obj_mac.h ) - ( cd $(SRCDIR); $(PERL) crypto/objects/obj_dat.pl \ - include/openssl/obj_mac.h \ - > crypto/objects/obj_dat.h ) - ( cd $(SRCDIR); $(PERL) crypto/objects/objxref.pl \ - crypto/objects/obj_mac.num \ - crypto/objects/obj_xref.txt \ - > crypto/objects/obj_xref.h ) - ( cd $(SRCDIR); sed -e '1,8d' crypto/objects/obj_compat.h >> include/openssl/obj_mac.h ) - -generate_crypto_conf: - ( cd $(SRCDIR); $(PERL) crypto/conf/keysets.pl \ - > crypto/conf/conf_def.h ) - -generate_crypto_asn1: - ( cd $(SRCDIR); $(PERL) crypto/asn1/charmap.pl \ - > crypto/asn1/charmap.h ) - -generate_fuzz_oids: - ( cd $(SRCDIR); $(PERL) fuzz/mkfuzzoids.pl \ - crypto/objects/obj_dat.h \ + ( cd $(SRCDIR); set -e; \ + $(PERL) crypto/objects/objects.pl -n \ + crypto/objects/objects.txt \ + crypto/objects/obj_mac.num \ + > crypto/objects/obj_mac.num.new; \ + if cmp crypto/objects/obj_mac.num.new \ + crypto/objects/obj_mac.num > /dev/null 2>&1; then \ + rm crypto/objects/obj_mac.num.new; \ + else \ + mv crypto/objects/obj_mac.num.new crypto/objects/obj_mac.num; \ + fi ) + +generate_fuzz_oids: crypto/objects/obj_dat.h + ( b=`pwd`; cd $(SRCDIR); \ + $(UPTODATE) fuzz/oids.txt \ + $$b/crypto/objects/obj_dat.h fuzz/mkfuzzoids.pl || \ + $(PERL) fuzz/mkfuzzoids.pl \ + $$b/crypto/objects/obj_dat.h \ > fuzz/oids.txt ) generate_doc_buildinfo: @@ -1334,7 +1371,7 @@ ERROR_REBUILD= errors: ( b=`pwd`; set -e; cd $(SRCDIR); \ $(PERL) util/ck_errf.pl -strict -internal; \ - $(PERL) -I$$b util/mkerr.pl $(ERROR_REBUILD) -internal ) + $(PERL) -I$$b util/mkerr.pl $(ERROR_REBUILD) -internal -state ) {- use File::Basename; @@ -1565,6 +1602,18 @@ EOF my $defs = join("", map { " -D".$_ } @{$args{defs}}); my $deps = join(" ", compute_platform_depends(@{$args{generator_deps}}, @{$args{deps}})); + my $tofile = "\$(PERL) \$(SRCDIR)/util/file-from-stdout.pl"; + # A generator named for more than one target cannot be producing them + # on standard output; it writes them itself, so its output must not be + # captured. + our %gen_targets; + unless (%gen_targets) { + foreach my $t (keys %{$unified_info{generate}}) { + $gen_targets{join(" ", @{$unified_info{generate}->{$t}})}++; + } + } + my $writes_own_files = + $gen_targets{join(" ", @{$args{generator}})} > 1; if ($args{src} =~ /\.html$/) { # @@ -1583,12 +1632,27 @@ EOF my $section = $1; my $name = uc basename($args{src}, ".$section"); my $pod = $gen0; - return <<"EOF"; + + if ($config{manpage_format} eq "mdoc") { + return <<"EOF"; $args{src}: $pod - pod2man --name=$name --section=$section\$(MANSUFFIX) --center=OpenSSL \\ - --date=\$(RELEASE_DATE) --release=\$(VERSION) \\ - $pod >\$\@ + pod2mdoc -n $name -s $section\$(MANSUFFIX) \\ + -d \$(RELEASE_DATE) \\ + $pod >\$\@ EOF + } elsif ($config{manpage_format} eq "roff") { + # One page at a time, through the same script that formats + # the whole manual, so there is a single implementation. It + # does not fork for a single pod, and still beats pod2man, + # which has more of its own start-up to do. + return <<"EOF"; +$args{src}: $pod + \$(PERL) \$(SRCDIR)/util/mkpod2man.pl -o doc/man -m "\$(MANSUFFIX)" \\ + -d "\$(RELEASE_DATE)" -r "\$(VERSION)" $pod +EOF + } else { + die "Unhandled manpage format: $config{manpage_format}"; + } } elsif (platform->isdef($args{src})) { # # Linker script-ish generator @@ -1599,7 +1663,8 @@ EOF my $ord_name = $args{generator}->[1] || $args{product}; return <<"EOF"; $target: $gen0 $deps \$(SRCDIR)/util/mkdef.pl - \$(PERL) \$(SRCDIR)/util/mkdef.pl$ord_ver --type $args{intent} --ordinals $gen0 --name $ord_name --OS $mkdef_os > $target + $tofile $target \\ + \$(PERL) \$(SRCDIR)/util/mkdef.pl$ord_ver --type $args{intent} --ordinals $gen0 --name $ord_name --OS $mkdef_os EOF } elsif (platform->isasm($args{src}) || platform->iscppasm($args{src})) { @@ -1614,11 +1679,15 @@ EOF } -> {$args{intent}}; my $generator; + # The perlasm modules take the output name as their last argument; + # m4 writes to standard output. + my $to_stdout = 0; if ($gen0 =~ /\.pl$/) { $generator = 'CC="$(CC)" $(PERL)'.$gen_incs.' '.$gen0.$gen_args .' "$(PERLASM_SCHEME)"'.$incs.' '.$cppflags.$defs.' $(PROCESSOR)'; } elsif ($gen0 =~ /\.m4$/) { - $generator = 'm4 -B 8192'.$gen_incs.' '.$gen0.$gen_args.' >' + $generator = 'm4 -B 8192'.$gen_incs.' '.$gen0.$gen_args; + $to_stdout = 1; } elsif ($gen0 =~ /\.S$/) { $generator = undef; } else { @@ -1626,15 +1695,17 @@ EOF } if (defined($generator)) { + my $recipe = $to_stdout ? "$tofile \$\@ $generator" + : "$generator \$\@"; return <<"EOF"; $args{src}: $gen0 $deps - $generator \$@ + $recipe EOF } return <<"EOF"; $args{src}: $gen0 $deps \$(CC) $incs $cppflags $defs -E $gen0 | \\ - \$(PERL) -ne '/^#(line)?\\s*[0-9]+/ or print' > \$@ + $tofile \$@ \$(PERL) -ne '/^#(line)?\\s*[0-9]+/ or print' EOF } elsif ($gen0 =~ m|^.*\.in$|) { # @@ -1683,9 +1754,8 @@ EOF return <<"EOF"; $args{src}: $gen0 $deps - if [ -r "\$@" ]; then chmod u+w \$@; fi - \$(PERL)$perlmodules "$dofile" "-o$target{build_file}" $gen0$gen_args > \$@ - chmod a-w \$@ + $tofile \$@ \\ + \$(PERL)$perlmodules "$dofile" "-o$target{build_file}" $gen0$gen_args EOF } elsif (grep { $_ eq $gen0 } @{$unified_info{programs}}) { # @@ -1698,7 +1768,9 @@ EOF # Use $(PERL) to execute wrap.pl directly to avoid calling env return <<"EOF"; $args{src}: $gen0 $deps \$(BLDDIR)/util/wrap.pl - \$(PERL) \$(BLDDIR)/util/wrap.pl $gen0$gen_args > \$@ + @{[ $writes_own_files + ? "\$(PERL) \$(BLDDIR)/util/wrap.pl $gen0$gen_args > \$\@" + : "$tofile \$\@ \$(PERL) \$(BLDDIR)/util/wrap.pl $gen0$gen_args" ]} EOF } else { # @@ -1706,7 +1778,9 @@ EOF # return <<"EOF"; $args{src}: $gen0 $deps - \$(PERL)$gen_incs $gen0$gen_args > \$@ + @{[ $writes_own_files + ? "\$(PERL)$gen_incs $gen0$gen_args > \$\@" + : "$tofile \$\@ \$(PERL)$gen_incs $gen0$gen_args" ]} EOF } } @@ -2065,11 +2139,9 @@ EOF rel2abs($config{builddir})); return <<"EOF"; $script: $sources configdata.pm - if [ -r "$script" ]; then chmod u+w $script; fi - \$(RM) "$script" - \$(PERL) "-I\$(BLDDIR)" -Mconfigdata "$dofile" \\ - "-o$target{build_file}" $sources > "$script" - chmod a+x,a-w $script + \$(PERL) \$(SRCDIR)/util/file-from-stdout.pl -x "$script" \\ + \$(PERL) "-I\$(BLDDIR)" -Mconfigdata "$dofile" \\ + "-o$target{build_file}" $sources EOF } sub generatedir { diff --git a/Configurations/windows-makefile.tmpl b/Configurations/windows-makefile.tmpl index a7f2b6652b143..747d145d7f556 100644 --- a/Configurations/windows-makefile.tmpl +++ b/Configurations/windows-makefile.tmpl @@ -691,10 +691,26 @@ EOF # (in the build tree), but quotes paths of non-generated dependencies (in the # source tree). This is a workaround for a limitation of C++Builder's make.exe # in handling quoted paths: https://quality.embarcadero.com/browse/RSP-31756 + # Configure runs the generator script itself through cleanfile(), which + # yields native (backslash) paths on Windows, but the remaining generator + # arguments are carried over verbatim from build.info. Arguments written + # as $(SRCDIR)/... or $(BLDDIR)/... therefore arrive with forward slashes; + # convert those to backslashes and quote them so a path containing spaces + # survives the shell. Anything else is a flag or a bare file name and is + # left alone. + sub generatearg { + my $arg = shift; + if ($arg =~ /\$\((?:SRCDIR|BLDDIR)\)/) { + $arg =~ s|/|\\|g; + return "\"$arg\""; + } + return $arg; + } + sub generatesrc { my %args = @_; my $gen0 = $args{generator}->[0]; - my $gen_args = join('', map { " $_" } + my $gen_args = join('', map { " ".generatearg($_) } @{$args{generator}}[1..$#{$args{generator}}]); my $gen_incs = join("", map { " -I\"$_\"" } @{$args{generator_incs}}); my $incs = join("", map { " -I\"$_\"" } @{$args{incs}}); diff --git a/Configure b/Configure index 5ee8597f2eda5..71c79e13f0263 100755 --- a/Configure +++ b/Configure @@ -27,7 +27,7 @@ use OpenSSL::config; my $orig_death_handler = $SIG{__DIE__}; $SIG{__DIE__} = \&death_handler; -my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]thread-pool] [[no-]default-thread-pool] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] [--help] os/compiler[:flags]\n"; +my $usage="Usage: Configure [no- ...] [enable- ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]thread-pool] [[no-]default-thread-pool] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] [--manpage-format={roff,mdoc}] [--help] os/compiler[:flags]\n"; my $banner = <<"EOF"; @@ -295,6 +295,7 @@ my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl")); my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR'; +$config{manpage_format} = "roff"; $config{sourcedir} = abs2rel($srcdir, $blddir); $config{builddir} = abs2rel($blddir, $blddir); # echo -n 'holy hand grenade of antioch' | openssl sha256 @@ -421,7 +422,7 @@ my $default_ranlib; # Known TLS and DTLS protocols my @tls = qw(tls1 tls1_1 tls1_2 tls1_3); -my @dtls = qw(dtls1 dtls1_2); +my @dtls = qw(dtls1 dtls1_2 dtls1_3); # Explicitly known options that are possible to disable. They can # be regexps, and will be used like this: /^no-${option}$/ @@ -444,12 +445,13 @@ my @disablables_protocols = ( foreach my $proto ((@tls, @dtls)) { push(@disablables_protocols, $proto); - push(@disablables_protocols, "$proto-method") unless $proto eq "tls1_3"; + push(@disablables_protocols, "$proto-method") unless $proto eq "tls1_3" || $proto eq "dtls1_3"; } my @disablables_algorithms = ( "argon2", "aria", + "ascon128", "bf", "blake2", "brotli", @@ -477,6 +479,7 @@ my @disablables_algorithms = ( "mdc2", "ml-dsa", "ml-kem", + "composite", "lms", "ocb", "poly1305", @@ -667,14 +670,14 @@ our %disabled = ( # "what" => "comment" my @disable_cascades = ( # "what" => [ "cascade", ... ] "bulk" => [ "shared", "dso", - "argon2", "aria", "async", "autoload-config", + "argon2", "aria", "ascon128", "async", "autoload-config", "blake2", "bf", "camellia", "cast", "chacha", "cmac", "cms", "cmp", "comp", "ct", "des", "dgram", "dh", "dsa", "ec", "ech", "filenames", "hmac-drbg-kdf", "idea", "ikev2kdf", "kbkdf", "krb5kdf", "ktls", "lms", - "md4", "ml-dsa", "ml-kem", "multiblock", + "md4", "ml-dsa", "ml-kem", "composite", "multiblock", "nextprotoneg", "ocsp", "ocb", "poly1305", "psk", "pvkkdf", "rc2", "rc4", "rmd160", "scrypt", "seed", "siphash", "siv", @@ -691,6 +694,7 @@ my @disable_cascades = ( "brotli" => [ "brotli-dynamic" ], "zstd" => [ "zstd-dynamic" ], "des" => [ "mdc2" ], + "ml-dsa" => [ "composite" ], "deprecated" => [ "tls-deprecated-ec" ], "ec" => [ qw(ec2m ec_explicit_curves sm2 gost ecx tls-deprecated-ec) ], "dgram" => [ "dtls", "quic", "sctp" ], @@ -1044,6 +1048,10 @@ while (@argvcopy) { $config{build_type} = "release"; } + elsif (/^--manpage-format=(mdoc|roff)$/) + { + $config{manpage_format}="$1"; + } elsif (/^--pgo$/) { $config{build_type} = "pgo"; @@ -1413,7 +1421,8 @@ application. Instead of manually seeding, a different random generator can be set at runtime in openssl.cnf or configured at build time with --DOPENSSL_DEFAULT_SEED_SRC. +-DOPENSSL_DEFAULT_SEED_SRC. The property query used to fetch it can +be set with -DOPENSSL_DEFAULT_SEED_PROPQ if needed. Please read the 'Note on random number generation' section in the INSTALL.md instructions for more details. @@ -2034,6 +2043,7 @@ foreach my $what (sort keys %disabled) { # fix-up crypto/directory name(s) $skipdir = "ripemd" if $what eq "rmd160"; $skipdir = "whrlpool" if $what eq "whirlpool"; + $skipdir = "ascon" if $what eq "ascon128"; my $macro = $disabled_info{$what}->{macro} = "OPENSSL_NO_$WHAT"; push @{$config{openssl_feature_defines}}, $macro; @@ -2052,8 +2062,11 @@ foreach my $what (sort keys %disabled) { } } + # siphash is used internally by libcrypto (X509 fingerprints), so + # no-siphash only removes the provider algorithm. $skipdir{"crypto/$skipdir"} = $what - unless $what eq 'async' || $what eq 'err' || $what eq 'dso' || $what eq 'http'; + unless $what eq 'async' || $what eq 'err' || $what eq 'dso' + || $what eq 'http' || $what eq 'siphash'; } } diff --git a/INSTALL.md b/INSTALL.md index 51f74e70dd38b..3e0fd4e1c1d50 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -787,9 +787,9 @@ Enable legacy TLS EC groups that were deprecated in RFC8422. These are the Koblitz curves, B, B, B, B, and the binary Elliptic curves that would also be disabled by C. -### enable-ec_expicit_curves +### enable-ec_explicit_curves -Enable support for explictitly specified elliptic curves not matching the +Enable support for explicitly specified elliptic curves not matching the well-known ones. Until this option is on, such curves can't be instantiated from ASN.1 formats. @@ -1223,7 +1223,8 @@ Build without support for the specified algorithm. The `ripemd` algorithm is deprecated and if used is synonymous with `rmd160`. -### Compiler-specific options +Compiler-specific options +------------------------- -Dxxx, -Ixxx, -Wp, -lxxx, -Lxxx, -Wl, -rpath, -R, -framework, -static @@ -1254,7 +1255,17 @@ encoding. Take note of the [Environment Variables](#environment-variables) documentation below and how these flags interact with those variables. -### Environment Variables +Miscellaneous options +--------------------- + +### --manpage-format + +Specify a specific output manpage format. The supported output types are mandoc +and *roff. The *roff output format is the default for legacy and portability +reasons. + +Environment Variables +--------------------- VAR=value @@ -1331,10 +1342,18 @@ If `CC` is set, it is advisable to also set `CXX` to ensure both the C and C++ compiler are in the same "family". This becomes relevant with `enable-external-tests` and `enable-buildtest-c++`. -### Reconfigure +Reconfigure +----------- - reconf - reconfigure +### Make targets + + `$ make reconf` + +or + + `$ make reconfigure` + +### Description Reconfigure from earlier data. diff --git a/NEWS.md b/NEWS.md index 278ec1309dcaf..de0561eeb920f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -7,6 +7,7 @@ release. For more details please read the CHANGES file. OpenSSL Releases ---------------- + - [OpenSSL 4.2](#openssl-42) - [OpenSSL 4.1](#openssl-41) - [OpenSSL 4.0](#openssl-40) - [OpenSSL 3.6](#openssl-36) @@ -23,17 +24,109 @@ OpenSSL Releases - [OpenSSL 1.0.0](#openssl-100) - [OpenSSL 0.9.x](#openssl-09x) +OpenSSL 4.2 +----------- + +### Major changes between OpenSSL 4.1 and OpenSSL 4.2 [under development] + + * Added support for Java keytool PKCS#12 files with symmetric keys. + New API `PKCS12_parse_ex()` with `PKCS12_PARSE_CTX` has been added. + OpenSSL 4.1 ----------- ### Major changes between OpenSSL 4.0 and OpenSSL 4.1 [under development] - * API calls `CRYPTO_atomic_load_ptr`, `CRYPTO_atomic_store_ptr`, and - `CRYPTO_atomic_cmp_exch_ptr` have been added. +OpenSSL 4.1.0 is a feature release adding significant new functionality +to OpenSSL. + +This release incorporates the following potentially significant or incompatible +changes: + + * Added `VC-WIN32-MSVC2013` and `VC-WIN64A-MSVC2013` build targets to provide + internal functions for bridging the gaps in C99 standard support + that are present in MSVC 2013. + + * Added optimized ML-DSA and ML-KEM NTT operations on `ppc64le`; + optimized ML-DSA operations on `s390x`, and `x86_64`; + AVX-512-optimized SHAKE x4 operations for ML-DSA on `x86_64`; + AVX-512 and VAES optimizations for AES-CBC decryption on `x86_64`. + + * Changed `tsget` utility to use `Net::Curl::Easy` (from the `Net-Curl` CPAN + distribution) instead of the abandoned `WWW::Curl::Easy`. Users who rely + on `tsget` should install `Net::Curl::Easy` before upgrading. + + * Dropped Windows-on-Itanium (`VC-WIN64I`) and Windows CE (`VC-CE`) targets + from Configurations. + + * Dropped `no-ecdsa` and `no-ecdh` options from `Configure`, as these options + did not really disable the implementations. Use `no-ec` to disable + the elliptic curve support. + +This release adds the following new features: + + * Support for DTLS 1.3 ([RFC 9147]). + Refer to the `ossl-guide-dtlsv13(7)` manual page for details. + + * Support for [RFC 8701] GREASE (Generate Random Extensions And Sustain + Extensibility). + + * DTLS support in the SSL listener API. + + * Support for IKEV2 KDF. + + * Initial support for the Elbrus2000 (`e2k`) architecture. OpenSSL 4.0 ----------- +### Major changes between OpenSSL 4.0.1 and OpenSSL 4.0.2 [25 Aug 2026] + +OpenSSL 4.0.2 is a security patch release. The most severe CVE fixed +in this release is Moderate. + +This release incorporates the following bug fixes and mitigations: + + * Fixed QUIC server being able to trigger double free when processing + `INITIAL` packet. + ([CVE-2026-18798]) + + * Fixed heap buffer overflow in CMS key unwrapping. + ([CVE-2026-63072]) + + * Fixed invalid pointer dereference in CMP server via crafted `protectionAlg`. + ([CVE-2026-63076]) + + * Fixed unbounded memory growth in QUIC server incoming channel queue. + ([CVE-2026-14456]) + + * Fixed RPK server signature algorithm selection being able to dereference + a missing certificate. + ([CVE-2026-14457]) + + * Fixed excessive memory use buffering DTLS records for a future epoch. + ([CVE-2026-54874]) + + * Fixed client-side memory leak in OCSP response checking. + ([CVE-2026-54876]) + + * Fixed untrusted Sender DN being used as a format string in CMP response + validation. + ([CVE-2026-63073]) + + * Fixed CMP indefinite cache growth of `extraCerts`. + ([CVE-2026-63074]) + + * Fixed QUIC ACK-only packet retention being able to cause memory exhaustion. + ([CVE-2026-63075]) + + * Fixed possibility of AEAD forgeries with empty ciphertext when using + `EVP_Cipher()`. + ([CVE-2026-75803]) + + * Fixed checking of authentication tags for empty ciphertexts for AEAD ciphers + in CCM cipher mode. + ### Major changes between OpenSSL 4.0.0 and OpenSSL 4.0.1 [9 Jun 2026] OpenSSL 4.0.1 is a security patch release. The most severe CVE fixed @@ -98,6 +191,8 @@ This release incorporates the following bug fixes and mitigations: and AES-SIV modes. ([CVE-2026-45446]) + * Fixed excessive allocation of the handshake message buffer (aka HollowByte). + * Fixed a regression introduced in 4.0.0 that led to a `openssl pkey` command crash when it was invoked to encrypt a private key with password being provided interactively. @@ -2437,6 +2532,9 @@ OpenSSL 0.9.x [CVE-2026-2673]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-2673 [CVE-2026-7383]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-7383 [CVE-2026-9076]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-9076 +[CVE-2026-14456]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-14456 +[CVE-2026-14457]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-14457 +[CVE-2026-18798]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-18798 [CVE-2026-22795]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-22795 [CVE-2026-22796]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-22796 [CVE-2026-28386]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-28386 @@ -2462,12 +2560,22 @@ OpenSSL 0.9.x [CVE-2026-45445]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-45445 [CVE-2026-45446]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-45446 [CVE-2026-45447]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-45447 +[CVE-2026-54874]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-54874 +[CVE-2026-54876]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-54876 +[CVE-2026-63072]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63072 +[CVE-2026-63073]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63073 +[CVE-2026-63074]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63074 +[CVE-2026-63075]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63075 +[CVE-2026-63076]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-63076 +[CVE-2026-75803]: https://openssl-library.org/news/vulnerabilities/#CVE-2026-75803 [ESV]: https://csrc.nist.gov/Projects/cryptographic-module-validation-program/entropy-validations [OpenSSL Guide]: https://docs.openssl.org/master/man7/ossl-guide-introduction [README-QUIC.md]: ./README-QUIC.md [RFC 7919]: https://datatracker.ietf.org/doc/html/rfc7919 [RFC 8422]: https://datatracker.ietf.org/doc/html/rfc8422 +[RFC 8701]: https://datatracker.ietf.org/doc/html/rfc8701 [RFC 8998]: https://datatracker.ietf.org/doc/html/rfc8998#name-iana-considerations +[RFC 9147]: https://datatracker.ietf.org/doc/html/rfc9147 [RFC 9849]: https://datatracker.ietf.org/doc/html/rfc9849 [SP 800-185]: https://csrc.nist.gov/pubs/sp/800/185/final [SP 800-208]: https://csrc.nist.gov/pubs/sp/800/208/final diff --git a/NOTES-SANITIZERS.md b/NOTES-SANITIZERS.md new file mode 100644 index 0000000000000..854a95dd6ae3c --- /dev/null +++ b/NOTES-SANITIZERS.md @@ -0,0 +1,149 @@ +Notes on Sanitizers +=================== + +Compiler sanitizers are tools that can be enabled during compilation to detect +various types of bugs at runtime. OpenSSL supports three sanitizers: + +- **AddressSanitizer (ASan)**: Detects memory errors such as use-after-free, + buffer overflows, and memory leaks. +- **UndefinedBehaviorSanitizer (UBSan)**: Detects undefined behavior such as + integer overflow, null pointer dereference, and type mismatches. +- **MemorySanitizer (MSan)**: Detects use of uninitialized memory. + +Sanitizers are generally faster than Valgrind and can detect certain issues +that Valgrind cannot, making them a useful complement to Valgrind-based testing. + +Requirements +------------ + +1. GCC or Clang compiler with sanitizer support + - GCC 4.8+ or Clang 3.1+ for ASan and UBSan + - Clang only for MSan (GCC does not implement MemorySanitizer) +2. Linux, macOS, or other supported platform + - Note: MSan is only supported on Linux + - Note: Leak detection (LSan) is not yet supported on macOS + +Building with Sanitizers +------------------------ + +OpenSSL provides configuration options to enable sanitizers: + +### AddressSanitizer (ASan) + + $ ./config enable-asan + $ make + +### UndefinedBehaviorSanitizer (UBSan) + + $ ./config enable-ubsan + $ make + +### MemorySanitizer (MSan) + +MSan is only implemented by Clang, so the compiler must be set to clang: + + $ CC=clang ./config enable-msan + $ make + +Note: MSan requires that all code, including libraries, be compiled with MSan. +This makes it more difficult to use than ASan or UBSan. + +### Combining Sanitizers + +ASan and UBSan can be used together: + + $ ./config enable-asan enable-ubsan + $ make + +Note: ASan and MSan cannot be used together as they are mutually exclusive. + +Running Tests +------------- + +After building with sanitizers enabled, run the tests normally: + + $ make test + +The sanitizers will automatically detect issues during test execution and +report them to stderr. If a sanitizer detects an error, the test will fail. + +### Running Specific Tests + +To run a specific test with verbose output: + + $ make test TESTS=test_name VERBOSE=1 + +### Sanitizer Environment Variables + +Sanitizer behavior can be controlled via environment variables: + +#### ASAN_OPTIONS + +Controls AddressSanitizer behavior. Common options: + + # Allow malloc to return NULL instead of aborting + ASAN_OPTIONS=allocator_may_return_null=1 + + # Disable leak detection (LSan runs as part of ASan by default) + ASAN_OPTIONS=detect_leaks=0 + + # Get more detailed stack traces + ASAN_OPTIONS=fast_unwind_on_malloc=0 + +#### UBSAN_OPTIONS + +Controls UndefinedBehaviorSanitizer behavior: + + # Print stack traces for UBSan errors + UBSAN_OPTIONS=print_stacktrace=1 + +#### MSAN_OPTIONS + +Controls MemorySanitizer behavior: + + # Allow malloc to return NULL instead of aborting + MSAN_OPTIONS=allocator_may_return_null=1 + +Example with environment variables: + + $ ASAN_OPTIONS=detect_leaks=1 make test TESTS=test_name + +Interpreting Results +-------------------- + +When a sanitizer detects an issue, it will print a detailed error report +including: + +- The type of error (e.g., "heap-buffer-overflow", "use-after-free") +- Stack trace showing where the error occurred +- Stack trace showing where the memory was allocated (for memory errors) +- Information about the memory region involved + +Example ASan output: + + ==12345==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x... + #0 0x... in function_name file.c:123 + #1 0x... in caller_function file.c:456 + ... + +Comparison with Valgrind +------------------------ + +| Feature | Sanitizers | Valgrind | +|----------------------------|-------------------|-------------------| +| Performance | ~2x slowdown | ~10-50x slowdown | +| Requires recompilation | Yes | No | +| Memory leak detection | ASan (with LSan) | Yes | +| Uninitialized memory | MSan | Yes | +| Buffer overflow detection | ASan | Yes | +| Undefined behavior | UBSan | Limited | +| Platform support | Linux, macOS | Linux, macOS, etc | + +See Also +-------- + +- [NOTES-VALGRIND.md](NOTES-VALGRIND.md) - Running tests with Valgrind +- [test/README.md](test/README.md) - General test documentation +- [AddressSanitizer documentation](https://clang.llvm.org/docs/AddressSanitizer.html) +- [UndefinedBehaviorSanitizer documentation](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html) +- [MemorySanitizer documentation](https://clang.llvm.org/docs/MemorySanitizer.html) diff --git a/NOTES-WINDOWS.md b/NOTES-WINDOWS.md index 76371e529d19b..a7889cd3d200a 100644 --- a/NOTES-WINDOWS.md +++ b/NOTES-WINDOWS.md @@ -87,6 +87,8 @@ Quick start on the Universal CRT or - `perl Configure VC-WIN64A-HYBRIDCRT` if you want 64-bit OpenSSL dependent on the Universal CRT or + - `perl Configure VC-WIN64-ARM-HYBRIDCRT` if you want Windows on Arm + (win-arm64) OpenSSL dependent on the Universal CRT or - `perl Configure` to let Configure figure out the platform a. If you don't plan to develop OpenSSL yourself and don't need to rebuild, diff --git a/README-FIPS.md b/README-FIPS.md index 4e3e20cf4d5aa..8b923892bb54a 100644 --- a/README-FIPS.md +++ b/README-FIPS.md @@ -32,11 +32,15 @@ Installing the FIPS provider ============================ In order to be FIPS compliant you must only use FIPS validated source code. -Refer to for information related to +Refer to for information related to which versions are FIPS validated. The instructions given below build OpenSSL -just using the FIPS validated source code. Any FIPS validated version may be -used with any other openssl library. Please see -To determine which FIPS validated library version may be appropriate for you. +just using the FIPS validated source code. A FIPS provider built from any +validated version may be used together with an OpenSSL library built from any +supported release from OpenSSL 3.0 onwards; provider compatibility is +maintained backward and forward across these releases, including future major +release series, for as long as the module remains supported. Please see + +to determine which FIPS validated library version may be appropriate for you. If you want to use a validated FIPS provider, but also want to use the latest OpenSSL release to build everything else, then refer to the next section. diff --git a/README.md b/README.md index 2701f9004bf51..d009d8e42d5d6 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,10 @@ Welcome to the OpenSSL Project [![openssl logo]][www.openssl.org] [![github actions ci badge]][github actions ci] -[![Nightly OS Zoo ci badge](https://github.com/openssl/openssl/actions/workflows/os-zoo.yml/badge.svg)](https://github.com/openssl/openssl/actions/workflows/os-zoo.yml) +[![Nightly OS Zoo ci badge](https://github.com/openssl/openssl/actions/workflows/os-zoo.yml/badge.svg?event=schedule)](https://github.com/openssl/openssl/actions/workflows/os-zoo.yml) [![Provider Compatibility](https://github.com/openssl/openssl/actions/workflows/provider-compatibility.yml/badge.svg)](https://github.com/openssl/openssl/actions/workflows/provider-compatibility.yml) [![Quic Interop](https://github.com/openssl/openssl/actions/workflows/run_quic_interop.yml/badge.svg)](https://github.com/openssl/openssl/actions/workflows/run_quic_interop.yml) -[![Daily checks](https://github.com/openssl/openssl/actions/workflows/run-checker-daily.yml/badge.svg)](https://github.com/openssl/openssl/actions/workflows/run-checker-daily.yml) +[![Daily checks](https://github.com/openssl/openssl/actions/workflows/run-checker-daily.yml/badge.svg?event=schedule)](https://github.com/openssl/openssl/actions/workflows/run-checker-daily.yml) [![LFX Health Score](https://insights.linuxfoundation.org/api/badge/health-score?project=openssl)](https://insights.linuxfoundation.org/project/openssl) OpenSSL is a robust, commercial-grade, full-featured Open Source Toolkit @@ -49,7 +49,7 @@ The OpenSSL toolkit includes: basis of the TLS implementation, but can also be used independently. - **openssl** - the OpenSSL command line tool, a swiss army knife for cryptographic tasks, + the OpenSSL command line tool, a Swiss Army knife for cryptographic tasks, testing and analyzing. It can be used for - creation of key parameters - creation of X.509 certificates, CSRs and CRLs diff --git a/VERSION.dat b/VERSION.dat index d3538fb9e74d2..f94328c164321 100644 --- a/VERSION.dat +++ b/VERSION.dat @@ -1,5 +1,5 @@ MAJOR=4 -MINOR=1 +MINOR=2 PATCH=0 PRE_RELEASE_TAG=dev BUILD_METADATA= diff --git a/VMS/VMSify-conf.pl b/VMS/VMSify-conf.pl index bc7392fde3da0..231ef7d36d125 100644 --- a/VMS/VMSify-conf.pl +++ b/VMS/VMSify-conf.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2004-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/apps/asn1parse.c b/apps/asn1parse.c index ed5ebd076f083..3f8623edafab9 100644 --- a/apps/asn1parse.c +++ b/apps/asn1parse.c @@ -82,7 +82,8 @@ int asn1parse_main(int argc, char **argv) const unsigned char *ctmpbuf; int indent = 0, noout = 0, dump = 0, informat = FORMAT_PEM; int offset = 0, ret = 1, i, j; - long num, tmplen; + long num; + size_t tmplen; const unsigned char *tmpbuf; unsigned int length = 0; OPTION_CHOICE o; @@ -241,12 +242,12 @@ int asn1parse_main(int argc, char **argv) if (sk_OPENSSL_STRING_num(osk)) { tmpbuf = str; - tmplen = num; + tmplen = (size_t)num; for (i = 0; i < sk_OPENSSL_STRING_num(osk); i++) { ASN1_TYPE *atmp; int typ; j = strtol(sk_OPENSSL_STRING_value(osk, i), NULL, 0); - if (j <= 0 || j >= tmplen) { + if (j <= 0 || (size_t)j >= tmplen) { BIO_printf(bio_err, "'%s' is out of range\n", sk_OPENSSL_STRING_value(osk, i)); continue; @@ -255,7 +256,7 @@ int asn1parse_main(int argc, char **argv) tmplen -= j; atmp = at; ctmpbuf = tmpbuf; - at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen); + at = d2i_ASN1_TYPE(NULL, &ctmpbuf, (long)tmplen); ASN1_TYPE_free(atmp); if (!at) { BIO_puts(bio_err, "Error parsing structure\n"); @@ -272,11 +273,16 @@ int asn1parse_main(int argc, char **argv) } /* hmm... this is a little evil but it works */ tmpbuf = ASN1_STRING_get0_data(at->value.asn1_string); - tmplen = ASN1_STRING_length(at->value.asn1_string); + tmplen = ASN1_STRING_get_length(at->value.asn1_string); + if (tmplen > INT_MAX) { + BIO_puts(bio_err, "ASN.1 string length exceeds INT_MAX\n"); + ERR_print_errors(bio_err); + goto end; + } } /* XXX casts away const */ str = (unsigned char *)tmpbuf; - num = tmplen; + num = (int)tmplen; } if (offset < 0 || offset >= num) { diff --git a/apps/ca.c b/apps/ca.c index c0a58f4d168f7..15a8c6c354317 100644 --- a/apps/ca.c +++ b/apps/ca.c @@ -484,13 +484,16 @@ int ca_main(int argc, char **argv) crl_nextupdate = opt_arg(); break; case OPT_CRLDAYS: - crldays = atol(opt_arg()); + if (!opt_long(opt_arg(), &crldays)) + goto opthelp; break; case OPT_CRLHOURS: - crlhours = atol(opt_arg()); + if (!opt_long(opt_arg(), &crlhours)) + goto opthelp; break; case OPT_CRLSEC: - crlsec = atol(opt_arg()); + if (!opt_long(opt_arg(), &crlsec)) + goto opthelp; break; case OPT_INFILES: req = 1; @@ -1077,8 +1080,8 @@ int ca_main(int argc, char **argv) X509 *xi = sk_X509_value(cert_sk, i); const ASN1_INTEGER *serialNumber = X509_get0_serialNumber(xi); const unsigned char *psn = ASN1_STRING_get0_data(serialNumber); - const int snl = ASN1_STRING_length(serialNumber); - const int filen_len = 2 * (snl > 0 ? snl : 1) + sizeof(".pem"); + const size_t snl = ASN1_STRING_get_length(serialNumber); + const size_t filen_len = 2 * (snl > 0 ? snl : 1) + sizeof(".pem"); char *n = new_cert + outdirlen; if (outdirlen + filen_len > PATH_MAX) { @@ -1089,7 +1092,7 @@ int ca_main(int argc, char **argv) if (snl > 0) { static const char HEX_DIGITS[] = "0123456789ABCDEF"; - for (j = 0; j < snl; j++, psn++) { + for (j = 0; (size_t)j < snl; j++, psn++) { *n++ = HEX_DIGITS[*psn >> 4]; *n++ = HEX_DIGITS[*psn & 0x0F]; } @@ -1523,8 +1526,10 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, goto end; } if (type != V_ASN1_BMPSTRING && type != V_ASN1_UTF8STRING) { - j = ASN1_PRINTABLE_type(ASN1_STRING_get0_data(str), - ASN1_STRING_length(str)); + size_t tmp = ASN1_STRING_get_length(str); + if (tmp > INT_MAX) + goto end; + j = ASN1_PRINTABLE_type(ASN1_STRING_get0_data(str), (int)tmp); if ((j == V_ASN1_T61STRING && type != V_ASN1_T61STRING) || (j == V_ASN1_IA5STRING && type == V_ASN1_PRINTABLESTRING)) { BIO_puts(bio_err, @@ -1623,10 +1628,18 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, if (j < 0) { BIO_printf(bio_err, "The %s field is different between\n" - "CA certificate (%s) and the request (%s)\n", - cv->name, - ((str2 == NULL) ? "NULL" : (char *)ASN1_STRING_get0_data(str2)), - ((str == NULL) ? "NULL" : (char *)ASN1_STRING_get0_data(str))); + "CA certificate (", + cv->name); + if (str2 == NULL) + BIO_puts(bio_err, "NULL"); + else + ASN1_STRING_print_ex(bio_err, str2, ASN1_STRFLGS_RFC2253); + BIO_puts(bio_err, ") and the request ("); + if (str == NULL) + BIO_puts(bio_err, "NULL"); + else + ASN1_STRING_print_ex(bio_err, str, ASN1_STRFLGS_RFC2253); + BIO_puts(bio_err, ")\n"); goto end; } } else { @@ -1901,9 +1914,9 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509, /* We now just add it to the database as DB_TYPE_VAL('V') */ row[DB_type] = OPENSSL_strdup("V"); tm = X509_get0_notAfter(ret); - row[DB_exp_date] = app_malloc(ASN1_STRING_length(tm) + 1, "row expdate"); - memcpy(row[DB_exp_date], ASN1_STRING_get0_data(tm), ASN1_STRING_length(tm)); - row[DB_exp_date][ASN1_STRING_length(tm)] = '\0'; + row[DB_exp_date] = app_malloc(ASN1_STRING_get_length(tm) + 1, "row expdate"); + memcpy(row[DB_exp_date], ASN1_STRING_get0_data(tm), ASN1_STRING_get_length(tm)); + row[DB_exp_date][ASN1_STRING_get_length(tm)] = '\0'; row[DB_rev_date] = NULL; row[DB_file] = OPENSSL_strdup("unknown"); if ((row[DB_type] == NULL) || (row[DB_file] == NULL) @@ -2137,9 +2150,9 @@ static int do_revoke(X509 *x509, CA_DB *db, REVINFO_TYPE rev_type, /* We now just add it to the database as DB_TYPE_REV('V') */ row[DB_type] = OPENSSL_strdup("V"); tm = X509_get0_notAfter(x509); - row[DB_exp_date] = app_malloc(ASN1_STRING_length(tm) + 1, "row exp_data"); - memcpy(row[DB_exp_date], ASN1_STRING_get0_data(tm), ASN1_STRING_length(tm)); - row[DB_exp_date][ASN1_STRING_length(tm)] = '\0'; + row[DB_exp_date] = app_malloc(ASN1_STRING_get_length(tm) + 1, "row exp_data"); + memcpy(row[DB_exp_date], ASN1_STRING_get0_data(tm), ASN1_STRING_get_length(tm)); + row[DB_exp_date][ASN1_STRING_get_length(tm)] = '\0'; row[DB_rev_date] = NULL; row[DB_file] = OPENSSL_strdup("unknown"); @@ -2350,7 +2363,7 @@ static char *make_revocation_str(REVINFO_TYPE rev_type, const char *rev_arg) const char *reason = NULL, *other = NULL; ASN1_OBJECT *otmp; ASN1_UTCTIME *revtm = NULL; - int i; + size_t i; switch (rev_type) { case REV_NONE: @@ -2407,15 +2420,16 @@ static char *make_revocation_str(REVINFO_TYPE rev_type, const char *rev_arg) if (!revtm) return NULL; - i = ASN1_STRING_length(revtm) + 1; + i = ASN1_STRING_get_length(revtm) + 1; if (reason) - i += (int)(strlen(reason) + 1); + i += strlen(reason) + 1; if (other) - i += (int)(strlen(other) + 1); + i += strlen(other) + 1; str = app_malloc(i, "revocation reason"); - OPENSSL_strlcpy(str, (const char *)ASN1_STRING_get0_data(revtm), i); + snprintf(str, i, "%.*s", (int)ASN1_STRING_get_length(revtm), + (const char *)ASN1_STRING_get0_data(revtm)); if (reason) { OPENSSL_strlcat(str, ",", i); OPENSSL_strlcat(str, reason, i); @@ -2492,11 +2506,12 @@ static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str) { char buf[25], *pbuf; const char *p; - int j; + int i; + size_t j; - j = i2a_ASN1_OBJECT(bio_err, obj); + i = i2a_ASN1_OBJECT(bio_err, obj); pbuf = buf; - for (j = 22 - j; j > 0; j--) + for (i = 22 - i; i > 0; i--) *(pbuf++) = ' '; *(pbuf++) = ':'; *(pbuf++) = '\0'; @@ -2514,7 +2529,7 @@ static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str) BIO_printf(bio_err, "ASN.1 %2d:'", ASN1_STRING_type(str)); p = (const char *)ASN1_STRING_get0_data(str); - for (j = ASN1_STRING_length(str); j > 0; j--) { + for (j = ASN1_STRING_get_length(str); j > 0; j--) { if ((*p >= ' ') && (*p <= '~')) BIO_printf(bio_err, "%c", *p); else if (*p & 0x80) diff --git a/apps/cmp.c b/apps/cmp.c index a0770dcb97a47..f094b7f465ccc 100644 --- a/apps/cmp.c +++ b/apps/cmp.c @@ -12,8 +12,9 @@ /* This app is disabled when OPENSSL_NO_CMP is defined. */ #include "internal/e_os.h" -#include #include +#include +#include #include "apps.h" #include "http_server.h" @@ -2140,7 +2141,7 @@ static int add_certProfile(OSSL_CMP_CTX *ctx, const char *name) return 0; if ((utf8string = ASN1_UTF8STRING_new()) == NULL) goto err; - if (!ASN1_STRING_set(utf8string, name, (int)strlen(name))) { + if (!ASN1_STRING_set1_string(utf8string, name)) { ASN1_STRING_free(utf8string); goto err; } @@ -2215,7 +2216,7 @@ static int handle_opt_geninfo(OSSL_CMP_CTX *ctx) else *end++ = '\0'; if ((text = ASN1_UTF8STRING_new()) == NULL - || !ASN1_STRING_set(text, ptr, -1)) + || !ASN1_STRING_set1_string(text, ptr)) goto oom; ptr = end; ASN1_TYPE_set(type, V_ASN1_UTF8STRING, text); @@ -2302,7 +2303,7 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx) if (!OSSL_CMP_CTX_set_option(ctx, OSSL_CMP_OPT_USE_TLS, opt_tls_used)) goto err; - BIO_snprintf(server_port, sizeof(server_port), "%s", port); + snprintf(server_port, sizeof(server_port), "%s", port); if (opt_path == NULL) used_path = path; if (!OSSL_CMP_CTX_set1_server(ctx, host) @@ -2312,13 +2313,13 @@ static int setup_client_ctx(OSSL_CMP_CTX *ctx) goto oom; if (opt_no_proxy != NULL && !OSSL_CMP_CTX_set1_no_proxy(ctx, opt_no_proxy)) goto oom; - (void)BIO_snprintf(server_buf, sizeof(server_buf), "http%s://%s:%s/%s", + (void)snprintf(server_buf, sizeof(server_buf), "http%s://%s:%s/%s", opt_tls_used ? "s" : "", host, port, *used_path == '/' ? used_path + 1 : used_path); proxy_host = OSSL_HTTP_adapt_proxy(opt_proxy, opt_no_proxy, host, use_ssl); if (proxy_host != NULL) - (void)BIO_snprintf(proxy_buf, sizeof(proxy_buf), " via %s", proxy_host); + (void)snprintf(proxy_buf, sizeof(proxy_buf), " via %s", proxy_host); set_path: #endif @@ -2588,7 +2589,7 @@ static int save_cert_or_delete(X509 *cert, const char *file, const char *desc) if (cert == NULL) { char desc_cert[80]; - BIO_snprintf(desc_cert, sizeof(desc_cert), "%s certificate", desc); + snprintf(desc_cert, sizeof(desc_cert), "%s certificate", desc); return delete_file(file, desc_cert); } else { STACK_OF(X509) *certs = sk_X509_new_null(); @@ -2837,7 +2838,7 @@ static int read_config(void) char *conf_argv[3]; char arg1[82]; - BIO_snprintf(arg1, 81, "-%s", (char *)opt->name); + snprintf(arg1, 81, "-%s", (char *)opt->name); conf_argv[0] = prog; conf_argv[1] = arg1; if (opt->valtype == '-') { @@ -3706,9 +3707,13 @@ static int handle_opts_upfront(int argc, char **argv) opt_section = argv[++i]; else if (strcmp(argv[i] + 1, cmp_options[OPT_VERBOSITY - OPT_HELP].name) - == 0 - && !set_verbosity(atoi(argv[++i]))) - return 0; + == 0) { + int level; + + ++i; + if (!opt_int(argv[i], &level) || !set_verbosity(level)) + return 0; + } } } if (opt_section[0] == '\0') /* empty string */ diff --git a/apps/cms.c b/apps/cms.c index 46f9b3b11e328..ee59b9faa07ec 100644 --- a/apps/cms.c +++ b/apps/cms.c @@ -81,6 +81,7 @@ typedef enum OPTION_choice { OPT_SIGN_RECEIPT, OPT_RESIGN, OPT_VERIFY, + OPT_VERIFY_PARTIAL, OPT_VERIFY_RETCODE, OPT_VERIFY_RECEIPT, OPT_CMSOUT, @@ -225,8 +226,8 @@ const OPTIONS cms_options[] = { OPT_R_OPTIONS, OPT_SECTION("Encryption and decryption"), - { "originator", OPT_ORIGINATOR, 's', "Originator certificate file" }, - { "recip", OPT_RECIP, '<', "Recipient cert file" }, + { "originator", OPT_ORIGINATOR, 's', "Originator certificate" }, + { "recip", OPT_RECIP, '<', "Recipient cert" }, { "cert...", OPT_PARAM, '.', "Recipient certs (optional; used only when encrypting)" }, { "", OPT_CIPHER, '-', @@ -246,7 +247,7 @@ const OPTIONS cms_options[] = { OPT_SECTION("Signing"), { "md", OPT_MD, 's', "Digest algorithm to use" }, - { "signer", OPT_SIGNER, 's', "Signer certificate input file" }, + { "signer", OPT_SIGNER, 's', "Signer certificate input" }, { "certfile", OPT_CERTFILE, '<', "Extra signer and intermediate CA certificates to include when signing" }, { OPT_MORE_STR, 0, 0, @@ -282,8 +283,10 @@ const OPTIONS cms_options[] = { { "nointern", OPT_NOINTERN, '-', "Don't search certificates in message for signer" }, { "cades", OPT_DUP, '-', "Check signingCertificate (CAdES-BES)" }, + { "verify_partial", OPT_VERIFY_PARTIAL, '-', + "Return success if at least one signature can be verified" }, { "verify_retcode", OPT_VERIFY_RETCODE, '-', - "Exit non-zero on verification failure" }, + "Exit non-zero on verification failure (depends on -verify_partial etc.)" }, { "CAfile", OPT_CAFILE, '<', "File in PEM format with trusted CA certs" }, { "CApath", OPT_CAPATH, '/', "Dir with trusted CA cert files in PEM format" }, { "CAstore", OPT_CASTORE, ':', "URI of store with trusted CA certs" }, @@ -457,6 +460,9 @@ int cms_main(int argc, char **argv) operation = SMIME_VERIFY_RECEIPT; rctfile = opt_arg(); break; + case OPT_VERIFY_PARTIAL: + flags |= CMS_VERIFY_PARTIAL; + break; case OPT_VERIFY_RETCODE: verify_retcode = 1; break; @@ -508,6 +514,10 @@ int cms_main(int argc, char **argv) break; case OPT_NOCERTS: flags |= CMS_NOCERTS; + /* + * Note that this does not affect certificates in variable 'other' + * containing extra certs loaded according to the -certfile option. + */ break; case OPT_NOATTR: flags |= CMS_NOATTR; @@ -976,7 +986,7 @@ int cms_main(int argc, char **argv) for (; *argv != NULL; argv++) { cert = load_cert(*argv, FORMAT_UNDEF, - "recipient certificate file"); + "recipient certificate"); if (cert == NULL) goto end; if (!sk_X509_push(encerts, cert)) @@ -986,7 +996,7 @@ int cms_main(int argc, char **argv) } if (certfile != NULL - && !load_certs(certfile, 0, &other, NULL, "certificate file")) + && !load_certs(certfile, 0, &other, NULL, "extra certificates")) goto end; if (recipfile != NULL && (operation == SMIME_DECRYPT) @@ -1148,7 +1158,7 @@ int cms_main(int argc, char **argv) res = EVP_PKEY_CTX_ctrl(pctx, -1, -1, EVP_PKEY_CTRL_CIPHER, - EVP_CIPHER_get_nid(cipher), NULL); + EVP_CIPHER_get_nid(cipher), cipher); if (res <= 0 && res != -2) goto end; @@ -1391,6 +1401,35 @@ int cms_main(int argc, char **argv) ret = verify_err + 32; goto end; } + if ((flags & CMS_VERIFY_PARTIAL) != 0) { + int i; + STACK_OF(CMS_SignerInfo) *sinfos = CMS_get0_SignerInfos(cms); + + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + CMS_SignerInfo *si = sk_CMS_SignerInfo_value(sinfos, i); + X509 *si_signer = CMS_SignerInfo_get0_signer_cert(si); + const X509_NAME *si_subject = NULL; + + if (si_signer == NULL) { + BIO_printf(bio_err, "Signer %d: no certificate\n", i); + continue; + } + + si_subject = X509_get_subject_name(si_signer); + if (si_subject == NULL) { + BIO_printf(bio_err, "Signer %d: no subject name\n", i); + continue; + } + + BIO_printf(bio_err, "Signer %d: ", i); + X509_NAME_print_ex(bio_err, si_subject, 0, XN_FLAG_ONELINE); + BIO_printf(bio_err, "\n Verification %s (cert: %s, attrs: %s, content: %s)\n", + CMS_SignerInfo_get_verification_result(si, CMS_VERIFY_RESULT) ? "successful" : "failed", + CMS_SignerInfo_get_verification_result(si, CMS_VERIFY_CERT) ? "success" : "failure or not verified", + CMS_SignerInfo_get_verification_result(si, CMS_VERIFY_ATTR) ? "success" : "failure or not verified", + CMS_SignerInfo_get_verification_result(si, CMS_VERIFY_CONTENT) ? "success" : "failure or not verified"); + } + } if (signerfile != NULL) { STACK_OF(X509) *signers = CMS_get0_signers(cms); @@ -1580,13 +1619,15 @@ static void receipt_request_print(CMS_ContentInfo *cms) ERR_print_errors(bio_err); } else { const char *id; - int idlen; + size_t idlen; CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst, &rlist, &rto); BIO_puts(bio_err, " Signed Content ID:\n"); - idlen = ASN1_STRING_length(scid); + idlen = ASN1_STRING_get_length(scid); + if (idlen > INT_MAX) + idlen = INT_MAX; id = (const char *)ASN1_STRING_get0_data(scid); - BIO_dump_indent(bio_err, id, idlen, 4); + BIO_dump_indent(bio_err, id, (int)idlen, 4); BIO_puts(bio_err, " Receipts From"); if (rlist != NULL) { BIO_puts(bio_err, " List:\n"); diff --git a/apps/dsa.c b/apps/dsa.c index 95a1b432cc887..185465ba1944d 100644 --- a/apps/dsa.c +++ b/apps/dsa.c @@ -106,7 +106,6 @@ int dsa_main(int argc, char **argv) case OPT_EOF: case OPT_ERR: opthelp: - ret = 0; BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: diff --git a/apps/enc.c b/apps/enc.c index 3d06a6ef03313..87e6f9530ecf7 100644 --- a/apps/enc.c +++ b/apps/enc.c @@ -473,7 +473,7 @@ int enc_main(int argc, char **argv) for (;;) { char prompt[200]; - BIO_snprintf(prompt, sizeof(prompt), "enter %s %s password:", + snprintf(prompt, sizeof(prompt), "enter %s %s password:", EVP_CIPHER_get0_name(cipher), (enc) ? "encryption" : "decryption"); strbuf[0] = '\0'; diff --git a/apps/genrsa.c b/apps/genrsa.c index 9187fa9ce0fa7..6150f59a8710e 100644 --- a/apps/genrsa.c +++ b/apps/genrsa.c @@ -153,8 +153,12 @@ int genrsa_main(int argc, char **argv) argv = opt_rest(); if (argc == 1) { - if (!opt_int(argv[0], &num) || num <= 0) + if (!opt_int(argv[0], &num)) goto end; + if (num <= 0) { + BIO_printf(bio_err, "%s: Invalid number of bits: %d\n", prog, num); + goto end; + } if (num > OPENSSL_RSA_MAX_MODULUS_BITS) BIO_printf(bio_err, "Warning: It is not recommended to use more than %d bit for RSA keys.\n" diff --git a/apps/include/app_params.h b/apps/include/app_params.h index 5c8d22ced9fbb..c76323a007d4f 100644 --- a/apps/include/app_params.h +++ b/apps/include/app_params.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/apps/include/apps_ui.h b/apps/include/apps_ui.h index 66caca98ae0d2..a6ad39de461fb 100644 --- a/apps/include/apps_ui.h +++ b/apps/include/apps_ui.h @@ -1,5 +1,5 @@ /* - * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/apps/include/cmp_mock_srv.h b/apps/include/cmp_mock_srv.h index d05f99ea044f0..a6220cdea21a3 100644 --- a/apps/include/cmp_mock_srv.h +++ b/apps/include/cmp_mock_srv.h @@ -1,5 +1,5 @@ /* - * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright Siemens AG 2018-2020 * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/apps/include/ec_common.h b/apps/include/ec_common.h index ac160e507f1ed..ac050f2e219d4 100644 --- a/apps/include/ec_common.h +++ b/apps/include/ec_common.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/apps/include/names.h b/apps/include/names.h index c2a8c41dd726c..a9f81756f335e 100644 --- a/apps/include/names.h +++ b/apps/include/names.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/apps/include/opt.h b/apps/include/opt.h index 6b22f89adacff..1023bfe601fd4 100644 --- a/apps/include/opt.h +++ b/apps/include/opt.h @@ -1,5 +1,5 @@ /* - * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -220,12 +220,12 @@ "Groups to advertise (colon-separated list)" }, \ { "named_curve", OPT_S_NAMEDCURVE, 's', \ "Elliptic curve used for ECDHE (server-side only)" }, \ - { "cipher", OPT_S_CIPHER, 's', "Specify TLSv1.2 and below cipher list to be used" }, \ - { "ciphersuites", OPT_S_CIPHERSUITES, 's', "Specify TLSv1.3 ciphersuites to be used" }, \ + { "cipher", OPT_S_CIPHER, 's', "Specify (D)TLSv1.2 and below cipher list to be used" }, \ + { "ciphersuites", OPT_S_CIPHERSUITES, 's', "Specify (D)TLSv1.3 ciphersuites to be used" }, \ { "min_protocol", OPT_S_MINPROTO, 's', "Specify the minimum protocol version to be used" }, \ { "max_protocol", OPT_S_MAXPROTO, 's', "Specify the maximum protocol version to be used" }, \ { "record_padding", OPT_S_RECORD_PADDING, 's', \ - "Block size to pad TLS 1.3 records to." }, \ + "Block size to pad (D)TLS 1.3 records to." }, \ { "debug_broken_protocol", OPT_S_DEBUGBROKE, '-', \ "Perform all sorts of protocol violations for testing purposes" }, \ { "no_middlebox", OPT_S_NO_MIDDLEBOX, '-', \ diff --git a/apps/include/platform.h b/apps/include/platform.h index ec12a41af7c73..ca0d856e96bb8 100644 --- a/apps/include/platform.h +++ b/apps/include/platform.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -29,4 +29,18 @@ char **copy_argv(int *argc, char *argv[]); void win32_utf8argv(int *argc, char **argv[]); #endif +/* + * MSVC versions earlier than Visual Studio 2015 (_MSC_VER < 1900) do not + * declare or define C99 snprintf or vsnprintf. Definitions are supplied + * by crypto/msvc2013_snprintf.c, which is built only on the matching + * Configure target variants. + */ +#if defined(_MSC_VER) && _MSC_VER < 1900 +#include +int msvc_translate_printf_format(const char *format, const char **out, + char **tmp); +int snprintf(char *buf, size_t n, const char *fmt, ...); +int vsnprintf(char *buf, size_t n, const char *fmt, va_list args); +#endif + #endif diff --git a/apps/include/s_apps.h b/apps/include/s_apps.h index c46f6327e95d3..a8761e66963da 100644 --- a/apps/include/s_apps.h +++ b/apps/include/s_apps.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,8 +18,9 @@ #define PORT "4433" #define PROTOCOL "tcp" -#define SSL_VERSION_ALLOWS_RENEGOTIATION(s) \ - (SSL_is_dtls(s) || (SSL_version(s) < TLS1_3_VERSION)) +#define SSL_VERSION_ALLOWS_RENEGOTIATION(s) \ + ((SSL_is_dtls(s) && (SSL_version(s) > DTLS1_3_VERSION || SSL_version(s) == DTLS1_BAD_VER)) \ + || (!SSL_is_dtls(s) && SSL_version(s) < TLS1_3_VERSION)) typedef int (*do_server_cb)(int s, int stype, int prot, unsigned char *context); void get_sock_info_address(int asock, char **hostname, char **service); @@ -40,7 +41,7 @@ int ssl_print_tmp_key(BIO *out, SSL *s); int init_client(int *sock, const char *host, const char *port, const char *bindhost, const char *bindport, int family, int type, int protocol, int tfo, int doconn, - BIO_ADDR **ba_ret); + BIO_ADDR **ba_ret, int c_quiet); int should_retry(int i); void do_ssl_shutdown(SSL *ssl); diff --git a/apps/kdf.c b/apps/kdf.c index 7eaa1a19defae..c8674afec5354 100644 --- a/apps/kdf.c +++ b/apps/kdf.c @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ +#include #include #include "apps.h" @@ -65,7 +66,7 @@ static char *alloc_kdf_algorithm_name(STACK_OF(OPENSSL_STRING) **optp, return NULL; res = app_malloc(len, "algorithm name"); - BIO_snprintf(res, len, "%s:%s", name, arg); + snprintf(res, len, "%s:%s", name, arg); if (sk_OPENSSL_STRING_push(*optp, res)) return res; OPENSSL_free(res); diff --git a/apps/lib/app_params.c b/apps/lib/app_params.c index cb569bb0c980a..e9dee852af441 100644 --- a/apps/lib/app_params.c +++ b/apps/lib/app_params.c @@ -7,6 +7,8 @@ * https://www.openssl.org/source/license.html */ +#include + #include "apps.h" #include "app_params.h" @@ -45,29 +47,29 @@ static int describe_param_type(char *buf, size_t bufsz, const OSSL_PARAM *param) break; } - printed_len = BIO_snprintf(buf, bufsz, "%s: ", param->key); - if (printed_len > 0) { + printed_len = snprintf(buf, bufsz, "%s: ", param->key); + if (printed_len > 0 && (size_t)printed_len < bufsz) { buf += printed_len; bufsz -= printed_len; } - printed_len = BIO_snprintf(buf, bufsz, "%s%s", type_mod, type); - if (printed_len > 0) { + printed_len = snprintf(buf, bufsz, "%s%s", type_mod, type); + if (printed_len > 0 && (size_t)printed_len < bufsz) { buf += printed_len; bufsz -= printed_len; } if (show_type_number) { - printed_len = BIO_snprintf(buf, bufsz, " [%u]", param->data_type); - if (printed_len > 0) { + printed_len = snprintf(buf, bufsz, " [%u]", param->data_type); + if (printed_len > 0 && (size_t)printed_len < bufsz) { buf += printed_len; bufsz -= printed_len; } } if (param->data_size == 0) - printed_len = BIO_snprintf(buf, bufsz, " (arbitrary size)"); + printed_len = snprintf(buf, bufsz, " (arbitrary size)"); else - printed_len = BIO_snprintf(buf, bufsz, " (max %zu bytes large)", + printed_len = snprintf(buf, bufsz, " (max %zu bytes large)", param->data_size); - if (printed_len > 0) { + if (printed_len > 0 && (size_t)printed_len < bufsz) { buf += printed_len; bufsz -= printed_len; } diff --git a/apps/lib/app_provider.c b/apps/lib/app_provider.c index a245349d13353..3b66d048ea993 100644 --- a/apps/lib/app_provider.c +++ b/apps/lib/app_provider.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/apps/lib/apps.c b/apps/lib/apps.c index 36fcb20e2a4a7..f4584975c8d19 100644 --- a/apps/lib/apps.c +++ b/apps/lib/apps.c @@ -252,10 +252,8 @@ static char *app_get_pass(const char *arg, int keepbio) } else if (CHECK_AND_SKIP_PREFIX(arg, "fd:")) { BIO *btmp; - i = atoi(arg); - if (i >= 0) - pwdbio = BIO_new_fd(i, BIO_NOCLOSE); - if ((i < 0) || pwdbio == NULL) { + if (!opt_int(arg, &i) || i < 0 + || (pwdbio = BIO_new_fd(i, BIO_NOCLOSE)) == NULL) { BIO_printf(bio_err, "Can't access file descriptor %s\n", arg); return NULL; } @@ -1740,6 +1738,16 @@ BIGNUM *load_serial(const char *serialfile, int *exists, int create, return ret; } +/* + * Character that separates a filename from its suffix in the file-rotation + * helpers below. On VMS, '.' is structural so we use '-' instead. + */ +#ifndef OPENSSL_SYS_VMS +#define SUFFIX_SEP '.' +#else +#define SUFFIX_SEP '-' +#endif + int save_serial(const char *serialfile, const char *suffix, const BIGNUM *serial, ASN1_INTEGER **retai) { @@ -1747,25 +1755,16 @@ int save_serial(const char *serialfile, const char *suffix, BIO *out = NULL; int ret = 0; ASN1_INTEGER *ai = NULL; - size_t j; - - if (suffix == NULL) - j = strlen(serialfile); - else - j = strlen(serialfile) + strlen(suffix) + 1; - if (j >= BSIZE) { - BIO_puts(bio_err, "File name too long\n"); - goto err; - } if (suffix == NULL) { - OPENSSL_strlcpy(buf[0], serialfile, BSIZE); + if (OPENSSL_strlcpy(buf[0], serialfile, BSIZE) >= BSIZE) + goto too_long; } else { -#ifndef OPENSSL_SYS_VMS - BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", serialfile, suffix); -#else - BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", serialfile, suffix); -#endif + int n = snprintf(buf[0], sizeof(buf[0]), "%s%c%s", + serialfile, SUFFIX_SEP, suffix); + + if (n < 0 || (size_t)n >= sizeof(buf[0])) + goto too_long; } out = BIO_new_file(buf[0], "w"); if (out == NULL) { @@ -1783,6 +1782,9 @@ int save_serial(const char *serialfile, const char *suffix, *retai = ai; ai = NULL; } + goto err; +too_long: + BIO_puts(bio_err, "File name too long\n"); err: if (!ret) ERR_print_errors(bio_err); @@ -1795,23 +1797,16 @@ int rotate_serial(const char *serialfile, const char *new_suffix, const char *old_suffix) { char buf[2][BSIZE]; - size_t i, j; - - i = strlen(serialfile) + strlen(old_suffix); - j = strlen(serialfile) + strlen(new_suffix); - if (i > j) - j = i; - if (j + 1 >= BSIZE) { - BIO_puts(bio_err, "File name too long\n"); - goto err; - } -#ifndef OPENSSL_SYS_VMS - BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", serialfile, new_suffix); - BIO_snprintf(buf[1], sizeof(buf[1]), "%s.%s", serialfile, old_suffix); -#else - BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", serialfile, new_suffix); - BIO_snprintf(buf[1], sizeof(buf[1]), "%s-%s", serialfile, old_suffix); -#endif + int n; + + n = snprintf(buf[0], sizeof(buf[0]), "%s%c%s", + serialfile, SUFFIX_SEP, new_suffix); + if (n < 0 || (size_t)n >= sizeof(buf[0])) + goto too_long; + n = snprintf(buf[1], sizeof(buf[1]), "%s%c%s", + serialfile, SUFFIX_SEP, old_suffix); + if (n < 0 || (size_t)n >= sizeof(buf[1])) + goto too_long; if (rename(serialfile, buf[1]) < 0 && errno != ENOENT #ifdef ENOTDIR && errno != ENOTDIR @@ -1830,6 +1825,8 @@ int rotate_serial(const char *serialfile, const char *new_suffix, goto err; } return 1; +too_long: + BIO_puts(bio_err, "File name too long\n"); err: ERR_print_errors(bio_err); return 0; @@ -1894,11 +1891,7 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr) if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL) goto err; -#ifndef OPENSSL_SYS_VMS - BIO_snprintf(buf, sizeof(buf), "%s.attr", dbfile); -#else - BIO_snprintf(buf, sizeof(buf), "%s-attr", dbfile); -#endif + snprintf(buf, sizeof(buf), "%s%cattr", dbfile, SUFFIX_SEP); dbattr_conf = app_load_config_quiet(buf); retdb = app_malloc(sizeof(*retdb), "new DB"); @@ -1970,22 +1963,20 @@ int save_index(const char *dbfile, const char *suffix, CA_DB *db) { char buf[3][BSIZE]; BIO *out; - int j; - - j = (int)(strlen(dbfile) + strlen(suffix)); - if (j + 6 >= BSIZE) { - BIO_puts(bio_err, "File name too long\n"); - goto err; - } -#ifndef OPENSSL_SYS_VMS - BIO_snprintf(buf[2], sizeof(buf[2]), "%s.attr", dbfile); - BIO_snprintf(buf[1], sizeof(buf[1]), "%s.attr.%s", dbfile, suffix); - BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", dbfile, suffix); -#else - BIO_snprintf(buf[2], sizeof(buf[2]), "%s-attr", dbfile); - BIO_snprintf(buf[1], sizeof(buf[1]), "%s-attr-%s", dbfile, suffix); - BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", dbfile, suffix); -#endif + int j, n; + + n = snprintf(buf[2], sizeof(buf[2]), "%s%cattr", + dbfile, SUFFIX_SEP); + if (n < 0 || (size_t)n >= sizeof(buf[2])) + goto too_long; + n = snprintf(buf[1], sizeof(buf[1]), "%s%cattr%c%s", + dbfile, SUFFIX_SEP, SUFFIX_SEP, suffix); + if (n < 0 || (size_t)n >= sizeof(buf[1])) + goto too_long; + n = snprintf(buf[0], sizeof(buf[0]), "%s%c%s", + dbfile, SUFFIX_SEP, suffix); + if (n < 0 || (size_t)n >= sizeof(buf[0])) + goto too_long; out = BIO_new_file(buf[0], "w"); if (out == NULL) { perror(dbfile); @@ -2008,6 +1999,8 @@ int save_index(const char *dbfile, const char *suffix, CA_DB *db) BIO_free(out); return 1; +too_long: + BIO_puts(bio_err, "File name too long\n"); err: ERR_print_errors(bio_err); return 0; @@ -2017,29 +2010,28 @@ int rotate_index(const char *dbfile, const char *new_suffix, const char *old_suffix) { char buf[5][BSIZE]; - size_t i, j; - - i = strlen(dbfile) + strlen(old_suffix); - j = strlen(dbfile) + strlen(new_suffix); - if (i > j) - j = i; - if (j + 6 >= BSIZE) { - BIO_puts(bio_err, "File name too long\n"); - goto err; - } -#ifndef OPENSSL_SYS_VMS - BIO_snprintf(buf[4], sizeof(buf[4]), "%s.attr", dbfile); - BIO_snprintf(buf[3], sizeof(buf[3]), "%s.attr.%s", dbfile, old_suffix); - BIO_snprintf(buf[2], sizeof(buf[2]), "%s.attr.%s", dbfile, new_suffix); - BIO_snprintf(buf[1], sizeof(buf[1]), "%s.%s", dbfile, old_suffix); - BIO_snprintf(buf[0], sizeof(buf[0]), "%s.%s", dbfile, new_suffix); -#else - BIO_snprintf(buf[4], sizeof(buf[4]), "%s-attr", dbfile); - BIO_snprintf(buf[3], sizeof(buf[3]), "%s-attr-%s", dbfile, old_suffix); - BIO_snprintf(buf[2], sizeof(buf[2]), "%s-attr-%s", dbfile, new_suffix); - BIO_snprintf(buf[1], sizeof(buf[1]), "%s-%s", dbfile, old_suffix); - BIO_snprintf(buf[0], sizeof(buf[0]), "%s-%s", dbfile, new_suffix); -#endif + int n; + + n = snprintf(buf[4], sizeof(buf[4]), "%s%cattr", + dbfile, SUFFIX_SEP); + if (n < 0 || (size_t)n >= sizeof(buf[4])) + goto too_long; + n = snprintf(buf[3], sizeof(buf[3]), "%s%cattr%c%s", + dbfile, SUFFIX_SEP, SUFFIX_SEP, old_suffix); + if (n < 0 || (size_t)n >= sizeof(buf[3])) + goto too_long; + n = snprintf(buf[2], sizeof(buf[2]), "%s%cattr%c%s", + dbfile, SUFFIX_SEP, SUFFIX_SEP, new_suffix); + if (n < 0 || (size_t)n >= sizeof(buf[2])) + goto too_long; + n = snprintf(buf[1], sizeof(buf[1]), "%s%c%s", + dbfile, SUFFIX_SEP, old_suffix); + if (n < 0 || (size_t)n >= sizeof(buf[1])) + goto too_long; + n = snprintf(buf[0], sizeof(buf[0]), "%s%c%s", + dbfile, SUFFIX_SEP, new_suffix); + if (n < 0 || (size_t)n >= sizeof(buf[0])) + goto too_long; if (rename(dbfile, buf[1]) < 0 && errno != ENOENT #ifdef ENOTDIR && errno != ENOTDIR @@ -2075,6 +2067,8 @@ int rotate_index(const char *dbfile, const char *new_suffix, goto err; } return 1; +too_long: + BIO_puts(bio_err, "File name too long\n"); err: ERR_print_errors(bio_err); return 0; @@ -2551,7 +2545,6 @@ int check_cert_might_be_valid(BIO *bio, BIO *b_err, X509 *x, const char *checkho X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_PARTIAL_CHAIN); X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_IGNORE_CRITICAL); X509_VERIFY_PARAM_set_flags(vpm, X509_V_FLAG_ALLOW_PROXY_CERTS); - X509_VERIFY_PARAM_set_trust(vpm, X509_TRUST_OK_ANY_EKU); if (!X509_VERIFY_PARAM_set1_ip_asc(vpm, checkip)) { maybe_printf(b_err, "Invalid IP address: %s\n", checkip); @@ -2820,7 +2813,7 @@ int do_X509_REQ_verify(X509_REQ *x, EVP_PKEY *pkey, /* Get first http URL from a DIST_POINT structure */ -static const char *get_dp_url(DIST_POINT *dp) +static char *get_dp_url(DIST_POINT *dp) { GENERAL_NAMES *gens; GENERAL_NAME *gen; @@ -2833,11 +2826,13 @@ static const char *get_dp_url(DIST_POINT *dp) for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { gen = sk_GENERAL_NAME_value(gens, i); uri = GENERAL_NAME_get0_value(gen, >ype); - if (gtype == GEN_URI && ASN1_STRING_length(uri) > 6) { + if (gtype == GEN_URI && ASN1_STRING_get_length(uri) > 6) { const char *uptr = (const char *)ASN1_STRING_get0_data(uri); + char *ret = OPENSSL_strndup(uptr, ASN1_STRING_get_length(uri)); - if (IS_HTTP(uptr)) /* can/should not use HTTPS here */ - return uptr; + if (ret != NULL && IS_HTTP(ret)) + return ret; + OPENSSL_free(ret); } } return NULL; @@ -2851,14 +2846,18 @@ static const char *get_dp_url(DIST_POINT *dp) static X509_CRL *load_crl_crldp(STACK_OF(DIST_POINT) *crldp) { int i; - const char *urlptr = NULL; + char *urlptr = NULL; for (i = 0; i < sk_DIST_POINT_num(crldp); i++) { DIST_POINT *dp = sk_DIST_POINT_value(crldp, i); urlptr = get_dp_url(dp); - if (urlptr != NULL) - return load_crl(urlptr, FORMAT_UNDEF, 0, "CRL via CDP"); + if (urlptr != NULL) { + X509_CRL *crl = load_crl(urlptr, FORMAT_UNDEF, 0, "CRL via CDP"); + + OPENSSL_free(urlptr); + return crl; + } } return NULL; } @@ -3722,7 +3721,7 @@ int has_stdin_waiting(void) int corrupt_signature(ASN1_STRING *signature) { const unsigned char *valid = ASN1_STRING_get0_data(signature); - int length = ASN1_STRING_length(signature); + size_t length = ASN1_STRING_get_length(signature); unsigned char *s = OPENSSL_memdup(valid, length); if (s == NULL) @@ -3730,7 +3729,7 @@ int corrupt_signature(ASN1_STRING *signature) s[length - 1] ^= 0x1; - ASN1_STRING_set0(signature, s, length); + ASN1_STRING_set0(signature, s, (int)length); return 1; } diff --git a/apps/lib/build.info b/apps/lib/build.info index a781117264e8b..9512a43b7637a 100644 --- a/apps/lib/build.info +++ b/apps/lib/build.info @@ -21,3 +21,7 @@ ENDIF IF[{- !$disabled{srp} -}] SOURCE[../libapps.a]=tlssrp_depr.c ENDIF + +IF[{- $target{needs_c99_snprintf_compat} -}] + SOURCE[../libapps.a]=../../crypto/msvc2013_snprintf.c +ENDIF diff --git a/apps/lib/cmp_mock_srv.c b/apps/lib/cmp_mock_srv.c index 43cf6af314c3a..c538c04d28784 100644 --- a/apps/lib/cmp_mock_srv.c +++ b/apps/lib/cmp_mock_srv.c @@ -345,7 +345,7 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, STACK_OF(ASN1_UTF8STRING) *strs; ASN1_UTF8STRING *str; const char *data; - int len; + size_t len; if (OBJ_obj2nid(obj) == NID_id_it_certProfile) { if (!OSSL_CMP_ITAV_get0_certProfile(itav, &strs)) @@ -360,7 +360,7 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx, ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT); return NULL; } - if (((len = ASN1_STRING_length(str)) != (int)sizeof("profile1") - 1) + if (((len = ASN1_STRING_get_length(str)) != sizeof("profile1") - 1) || memcmp(data, "profile1", len) != 0) { ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CERTPROFILE); return NULL; diff --git a/apps/lib/http_server.c b/apps/lib/http_server.c index d470fb8c5817a..c4086e3ad458e 100644 --- a/apps/lib/http_server.c +++ b/apps/lib/http_server.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,6 +18,7 @@ #endif #include +#include #include "internal/e_os.h" #include "http_server.h" #include "internal/sockets.h" /* for openssl_fdset() */ @@ -197,7 +198,7 @@ BIO *http_server_init(const char *prog, const char *port, int verb) int port_num; char name[40]; - BIO_snprintf(name, sizeof(name), "*:%s", port); /* port may be "0" */ + snprintf(name, sizeof(name), "*:%s", port); /* port may be "0" */ if (verb >= 0 && !log_set_verbosity(prog, verb)) return NULL; bufbio = BIO_new(BIO_f_buffer()); @@ -506,9 +507,9 @@ int http_server_send_asn1_resp(const char *prog, BIO *cbio, int keep_alive, const ASN1_ITEM *it, const ASN1_VALUE *resp) { char buf[200], *p; - int ret = BIO_snprintf(buf, sizeof(buf), HTTP_1_0 " 200 OK\r\n%s" - "Content-type: %s\r\n" - "Content-Length: %d\r\n", + int ret = snprintf(buf, sizeof(buf), HTTP_1_0 " 200 OK\r\n%s" + "Content-type: %s\r\n" + "Content-Length: %d\r\n", keep_alive ? "Connection: keep-alive\r\n" : "", content_type, ASN1_item_i2d(resp, NULL, it)); @@ -532,7 +533,7 @@ int http_server_send_status(const char *prog, BIO *cbio, int status, const char *reason) { char buf[200]; - int ret = BIO_snprintf(buf, sizeof(buf), HTTP_1_0 " %d %s\r\n\r\n", + int ret = snprintf(buf, sizeof(buf), HTTP_1_0 " %d %s\r\n\r\n", /* This implicitly cancels keep-alive */ status, reason); diff --git a/apps/lib/log.c b/apps/lib/log.c index 8ed7a3bc2b8ea..63a7655df9a03 100644 --- a/apps/lib/log.c +++ b/apps/lib/log.c @@ -7,6 +7,8 @@ * https://www.openssl.org/source/license.html */ +#include + #include #include "apps.h" #include "log.h" @@ -49,7 +51,7 @@ static void log_with_prefix(const char *prog, const char *fmt, va_list ap) if (pre == NULL) return; - (void)BIO_snprintf(prefix, sizeof(prefix), "%s: ", prog); + (void)snprintf(prefix, sizeof(prefix), "%s: ", prog); (void)BIO_set_prefix(pre, prefix); bio = BIO_push(pre, bio_err); (void)BIO_vprintf(bio, fmt, ap); diff --git a/apps/lib/opt.c b/apps/lib/opt.c index d139346cc2eb7..f28eeaa4f0b41 100644 --- a/apps/lib/opt.c +++ b/apps/lib/opt.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -15,6 +15,7 @@ #include "app_libctx.h" #include "internal/nelem.h" #include "internal/numbers.h" +#include #include #if !defined(OPENSSL_SYS_MSDOS) #include @@ -36,7 +37,6 @@ const char OPT_PARAM_STR[] = "-P"; /* Our state */ static char **argv; -static int argc; static int opt_index; static char *arg; static char *flag; @@ -148,7 +148,7 @@ char *opt_appname(const char *argv0) size_t len = strlen(prog); if (argv0 != NULL) - BIO_snprintf(prog + len, sizeof(prog) - len - 1, " %s", argv0); + snprintf(prog + len, sizeof(prog) - len - 1, " %s", argv0); return prog; } @@ -161,7 +161,6 @@ char *opt_getprog(void) char *opt_init(int ac, char **av, const OPTIONS *o) { /* Store state. */ - argc = ac; argv = av; opt_begin(); opts = o; diff --git a/apps/lib/s_cb.c b/apps/lib/s_cb.c index 4f2503502b092..8c014fca8ca46 100644 --- a/apps/lib/s_cb.c +++ b/apps/lib/s_cb.c @@ -576,6 +576,8 @@ static STRINT_PAIR ssl_versions[] = { { "TLS 1.2", TLS1_2_VERSION }, { "TLS 1.3", TLS1_3_VERSION }, { "DTLS 1.0", DTLS1_VERSION }, + { "DTLS 1.2", DTLS1_2_VERSION }, + { "DTLS 1.3", DTLS1_3_VERSION }, { "DTLS 1.0 (bad)", DTLS1_BAD_VER }, { NULL } }; @@ -653,12 +655,16 @@ void msg_cb(int write_p, int version, int content_type, const void *buf, const char *str_version, *str_content_type = "", *str_details1 = "", *str_details2 = ""; const unsigned char *bp = buf; - if (version == TLS1_VERSION || version == TLS1_1_VERSION || version == TLS1_2_VERSION || version == TLS1_3_VERSION || version == DTLS1_VERSION || version == DTLS1_BAD_VER) { + if (version == TLS1_VERSION || version == TLS1_1_VERSION + || version == TLS1_2_VERSION || version == TLS1_3_VERSION + || version == DTLS1_VERSION || version == DTLS1_2_VERSION + || version == DTLS1_3_VERSION || version == DTLS1_BAD_VER) { str_version = lookup(version, ssl_versions, "???"); switch (content_type) { case SSL3_RT_CHANGE_CIPHER_SPEC: /* type 20 */ - str_content_type = ", ChangeCipherSpec"; + if (version != DTLS1_3_VERSION) + str_content_type = ", ChangeCipherSpec"; break; case SSL3_RT_ALERT: /* type 21 */ @@ -687,6 +693,11 @@ void msg_cb(int write_p, int version, int content_type, const void *buf, /* type 23 */ str_content_type = ", ApplicationData"; break; + case SSL3_RT_ACK: + /* type 26 */ + if (version == DTLS1_3_VERSION) + str_content_type = ", ACK"; + break; case SSL3_RT_HEADER: /* type 256 */ str_content_type = ", RecordHeader"; @@ -696,11 +707,15 @@ void msg_cb(int write_p, int version, int content_type, const void *buf, str_content_type = ", InnerContent"; break; default: - BIO_snprintf(tmpbuf, sizeof(tmpbuf) - 1, ", Unknown (content_type=%d)", content_type); + break; + } + + if (str_content_type[0] == '\0') { + snprintf(tmpbuf, sizeof(tmpbuf) - 1, ", Unknown (content_type=%d)", content_type); str_content_type = tmpbuf; } } else { - BIO_snprintf(tmpbuf, sizeof(tmpbuf) - 1, "Not TLS data or unknown version (version=%d, content_type=%d)", version, content_type); + snprintf(tmpbuf, sizeof(tmpbuf) - 1, "Not TLS data or unknown version (version=%d, content_type=%d)", version, content_type); str_version = tmpbuf; } diff --git a/apps/lib/s_socket.c b/apps/lib/s_socket.c index d8e67d64302b4..cfddd269072eb 100644 --- a/apps/lib/s_socket.c +++ b/apps/lib/s_socket.c @@ -75,7 +75,7 @@ BIO_ADDR *ourpeer = NULL; int init_client(int *sock, const char *host, const char *port, const char *bindhost, const char *bindport, int family, int type, int protocol, int tfo, int doconn, - BIO_ADDR **ba_ret) + BIO_ADDR **ba_ret, int c_quiet) { BIO_ADDRINFO *res = NULL; BIO_ADDRINFO *bindaddr = NULL; @@ -208,10 +208,12 @@ int init_client(int *sock, const char *host, const char *port, } else { char *hostname = NULL; - hostname = BIO_ADDR_hostname_string(BIO_ADDRINFO_address(ai), 1); - if (hostname != NULL) { - BIO_printf(bio_err, "Connecting to %s\n", hostname); - OPENSSL_free(hostname); + if (!c_quiet) { + hostname = BIO_ADDR_hostname_string(BIO_ADDRINFO_address(ai), 1); + if (hostname != NULL) { + BIO_printf(bio_err, "Connecting to %s\n", hostname); + OPENSSL_free(hostname); + } } /* Remove any stale errors from previous connection attempts */ ERR_clear_error(); diff --git a/apps/lib/vms_term_sock.c b/apps/lib/vms_term_sock.c index e60d7f0a1b7f1..b73393c80b670 100644 --- a/apps/lib/vms_term_sock.c +++ b/apps/lib/vms_term_sock.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2016 VMS Software, Inc. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -230,6 +230,7 @@ int TerminalSocket(int FunctionCode, int *ReturnSocket) LogMessage("TerminalSocket: SYS$QIO () - %08X", status); close(TerminalSocketPair[0]); close(TerminalSocketPair[1]); + sys$dassgn(TerminalDeviceChan); return TERM_SOCK_FAILURE; } @@ -248,6 +249,7 @@ int TerminalSocket(int FunctionCode, int *ReturnSocket) LogMessage("TerminalSocket: SYS$CANCEL () - %08X", status); close(TerminalSocketPair[0]); close(TerminalSocketPair[1]); + sys$dassgn(TerminalDeviceChan); return TERM_SOCK_FAILURE; } @@ -366,7 +368,7 @@ static int CreateSocketPair(int SocketFamily, /* ** Get the binary (64-bit) time of the specified timeout value */ - BIO_snprintf(AscTimeBuff, sizeof(AscTimeBuff), "0 0:0:%02d.00", SOCKET_PAIR_TIMEOUT_VALUE); + snprintf(AscTimeBuff, sizeof(AscTimeBuff), "0 0:0:%02d.00", SOCKET_PAIR_TIMEOUT_VALUE); AscTimeDesc.dsc$w_length = strlen(AscTimeBuff); AscTimeDesc.dsc$a_pointer = AscTimeBuff; status = sys$bintim(&AscTimeDesc, BinTimeBuff); @@ -577,7 +579,7 @@ static void LogMessage(char *msg, ...) /* ** Format the message buffer */ - BIO_snprintf(MsgBuff, sizeof(MsgBuff), "%02d-%s-%04d %02d:%02d:%02d [%08X] %s\n", + snprintf(MsgBuff, sizeof(MsgBuff), "%02d-%s-%04d %02d:%02d:%02d [%08X] %s\n", LocTime->tm_mday, Month[LocTime->tm_mon], (LocTime->tm_year + 1900), LocTime->tm_hour, LocTime->tm_min, LocTime->tm_sec, pid, msg); diff --git a/apps/mac.c b/apps/mac.c index 61044eb6331fe..daa22a3bd9479 100644 --- a/apps/mac.c +++ b/apps/mac.c @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ +#include #include #include "apps.h" @@ -68,7 +69,7 @@ static char *alloc_mac_algorithm_name(STACK_OF(OPENSSL_STRING) **optp, return NULL; res = app_malloc(len, "algorithm name"); - BIO_snprintf(res, len, "%s:%s", name, arg); + snprintf(res, len, "%s:%s", name, arg); if (sk_OPENSSL_STRING_push(*optp, res)) return res; OPENSSL_free(res); diff --git a/apps/ocsp.c b/apps/ocsp.c index 59d33e90f29b1..e302c1cf6b021 100644 --- a/apps/ocsp.c +++ b/apps/ocsp.c @@ -470,11 +470,15 @@ int ocsp_main(int argc, char **argv) if (issuer == NULL) goto end; if (issuers == NULL) { - if ((issuers = sk_X509_new_null()) == NULL) + if ((issuers = sk_X509_new_null()) == NULL) { + X509_free(issuer); goto end; + } } - if (!sk_X509_push(issuers, issuer)) + if (!sk_X509_push(issuers, issuer)) { + X509_free(issuer); goto end; + } break; case OPT_CERT: reset_unknown(); diff --git a/apps/openssl.c b/apps/openssl.c index 4df297e3c4e0c..1b48e63bdc685 100644 --- a/apps/openssl.c +++ b/apps/openssl.c @@ -123,7 +123,7 @@ static size_t internal_trace_cb(const char *buf, size_t cnt, tid = CRYPTO_THREAD_get_current_id(); hex = OPENSSL_buf2hexstr((const unsigned char *)&tid, sizeof(tid)); - BIO_snprintf(buffer, sizeof(buffer), "TRACE[%s]:%s: ", + snprintf(buffer, sizeof(buffer), "TRACE[%s]:%s: ", hex == NULL ? "" : hex, OSSL_trace_get_category_name(category)); OPENSSL_free(hex); diff --git a/apps/passwd.c b/apps/passwd.c index 1750f12f762e1..a2fff324aaf0d 100644 --- a/apps/passwd.c +++ b/apps/passwd.c @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ +#include #include #include "apps.h" @@ -594,7 +595,7 @@ static char *shacrypt(const char *passwd, const char *magic, const char *salt) if (rounds_custom) { char tmp_buf[80]; /* "rounds=999999999" */ - BIO_snprintf(tmp_buf, sizeof(tmp_buf), "rounds=%u", rounds); + snprintf(tmp_buf, sizeof(tmp_buf), "rounds=%u", rounds); #ifdef CHARSET_EBCDIC /* In case we're really on a ASCII based platform and just pretend */ if (tmp_buf[0] != 0x72) /* ASCII 'r' */ diff --git a/apps/pkcs12.c b/apps/pkcs12.c index f8179995629d8..2deb87a1f8721 100644 --- a/apps/pkcs12.c +++ b/apps/pkcs12.c @@ -833,7 +833,7 @@ int pkcs12_main(int argc, char **argv) ASN1_INTEGER_get(pbkdf2_param->iter)); BIO_printf(bio_err, "Key length: %ld, Salt length: %d\n", ASN1_INTEGER_get(pbkdf2_param->keylength), - ASN1_STRING_length(pbkdf2_param->salt->value.octet_string)); + (int)ASN1_STRING_get_length(pbkdf2_param->salt->value.octet_string)); if (pbkdf2_param->prf == NULL) { prfnid = NID_hmacWithSHA1; } else { @@ -847,8 +847,8 @@ int pkcs12_main(int argc, char **argv) BIO_printf(bio_err, ", Iteration %ld\n", tmaciter != NULL ? ASN1_INTEGER_get(tmaciter) : 1L); BIO_printf(bio_err, "MAC length: %ld, salt length: %ld\n", - tmac != NULL ? ASN1_STRING_length(tmac) : 0L, - tsalt != NULL ? ASN1_STRING_length(tsalt) : 0L); + tmac != NULL ? (long)ASN1_STRING_get_length(tmac) : 0L, + tsalt != NULL ? (long)ASN1_STRING_get_length(tsalt) : 0L); } } @@ -1231,7 +1231,7 @@ static int alg_print(const X509_ALGOR *alg) } BIO_printf(bio_err, ", Salt length: %d, Cost(N): %ld, " "Block size(r): %ld, Parallelism(p): %ld", - ASN1_STRING_length(kdf->salt), + (int)ASN1_STRING_get_length(kdf->salt), ASN1_INTEGER_get(kdf->costParameter), ASN1_INTEGER_get(kdf->blockSize), ASN1_INTEGER_get(kdf->parallelizationParameter)); @@ -1282,25 +1282,27 @@ void print_attribute(BIO *out, const ASN1_TYPE *av) switch (av->type) { case V_ASN1_BMPSTRING: value = OPENSSL_uni2asc(ASN1_STRING_get0_data(av->value.bmpstring), - ASN1_STRING_length(av->value.bmpstring)); + (int)ASN1_STRING_get_length(av->value.bmpstring)); BIO_printf(out, "%s\n", value); OPENSSL_free(value); break; case V_ASN1_UTF8STRING: - BIO_printf(out, "%.*s\n", ASN1_STRING_length(av->value.utf8string), - ASN1_STRING_get0_data(av->value.utf8string)); + BIO_printf(out, "%.*s\n", (int)ASN1_STRING_get_length(av->value.utf8string), + ASN1_STRING_get_length(av->value.utf8string) + ? ASN1_STRING_get0_data(av->value.utf8string) + : (const unsigned char *)""); break; case V_ASN1_OCTET_STRING: hex_print(out, ASN1_STRING_get0_data(av->value.octet_string), - ASN1_STRING_length(av->value.octet_string)); + (int)ASN1_STRING_get_length(av->value.octet_string)); BIO_puts(out, "\n"); break; case V_ASN1_BIT_STRING: hex_print(out, ASN1_STRING_get0_data(av->value.bit_string), - ASN1_STRING_length(av->value.bit_string)); + (int)ASN1_STRING_get_length(av->value.bit_string)); BIO_puts(out, "\n"); break; diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c index 5f9c3284f07a2..3d7cce54c1487 100644 --- a/apps/pkeyutl.c +++ b/apps/pkeyutl.c @@ -10,6 +10,7 @@ #include "apps.h" #include "progs.h" #include +#include #include #include #include @@ -400,7 +401,7 @@ int pkeyutl_main(int argc, char **argv) char passwd_buf[4096]; int r; - BIO_snprintf(passwd_buf, sizeof(passwd_buf), "Enter %s: ", opt); + snprintf(passwd_buf, sizeof(passwd_buf), "Enter %s: ", opt); r = EVP_read_pw_string(passwd_buf, sizeof(passwd_buf) - 1, passwd_buf, 0); if (r < 0) { diff --git a/apps/progs.pl b/apps/progs.pl index 01789b9058748..be796bf343dca 100644 --- a/apps/progs.pl +++ b/apps/progs.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/apps/rehash.c b/apps/rehash.c index 93e757faa94ad..5755d2b8a5ef0 100644 --- a/apps/rehash.c +++ b/apps/rehash.c @@ -408,7 +408,7 @@ static int do_dir(const char *dirname, enum Hash h) numfiles = sk_OPENSSL_STRING_num(files); for (n = 0; n < numfiles; ++n) { filename = sk_OPENSSL_STRING_value(files, n); - if (BIO_snprintf(buf, buflen, "%s%s%s", + if (snprintf(buf, buflen, "%s%s%s", dirname, pathsep, filename) >= buflen) continue; @@ -432,7 +432,7 @@ static int do_dir(const char *dirname, enum Hash h) nextep = ep->next; if (ep->old_id < bp->num_needed) { /* Link exists, and is used as-is */ - BIO_snprintf(buf, buflen, "%08x.%s%d", bp->hash, + snprintf(buf, buflen, "%08x.%s%d", bp->hash, suffixes[bp->type], ep->old_id); if (verbose) BIO_printf(bio_out, "link %s -> %s\n", @@ -442,7 +442,7 @@ static int do_dir(const char *dirname, enum Hash h) while (bit_isset(idmask, nextid)) nextid++; - BIO_snprintf(buf, buflen, "%s%s%08x.%s%d", + snprintf(buf, buflen, "%s%s%08x.%s%d", dirname, pathsep, bp->hash, suffixes[bp->type], nextid); if (verbose) @@ -464,7 +464,7 @@ static int do_dir(const char *dirname, enum Hash h) bit_set(idmask, nextid); } else if (remove_links) { /* Link to be deleted */ - BIO_snprintf(buf, buflen, "%s%s%08x.%s%d", + snprintf(buf, buflen, "%s%s%08x.%s%d", dirname, pathsep, bp->hash, suffixes[bp->type], ep->old_id); if (verbose) diff --git a/apps/req.c b/apps/req.c index 83ac38ef86401..19933ea35209f 100644 --- a/apps/req.c +++ b/apps/req.c @@ -1557,10 +1557,12 @@ static EVP_PKEY_CTX *set_keygen_ctx(const char *gstr, /* Treat the second part of gstr, if there is one */ if (gstr != NULL) { /* If the second part starts with a digit, we assume it's a size */ - if (!expect_paramfile && gstr[0] >= '0' && gstr[0] <= '9') - keylen = atol(gstr); - else + if (!expect_paramfile && gstr[0] >= '0' && gstr[0] <= '9') { + if (!opt_long(gstr, &keylen)) + return NULL; + } else { paramfile = gstr; + } } if (paramfile != NULL) { diff --git a/apps/s_client.c b/apps/s_client.c index d247cd836d6ae..9207230cec369 100644 --- a/apps/s_client.c +++ b/apps/s_client.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "internal/nelem.h" #include "internal/sockets.h" /* for openssl_fdset() */ @@ -171,8 +172,8 @@ static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity, /* * lookup PSK identity and PSK key based on the given identity hint here */ - ret = BIO_snprintf(identity, max_identity_len, "%s", psk_identity); - if (ret < 0 || (unsigned int)ret > max_identity_len) + ret = snprintf(identity, max_identity_len, "%s", psk_identity); + if (ret < 0 || (unsigned int)ret >= max_identity_len) goto out_err; if (c_debug) BIO_printf(bio_c_out, "created identity '%s' len=%d\n", identity, @@ -216,6 +217,7 @@ static int psk_use_session_cb(SSL *s, const EVP_MD *md, { SSL_SESSION *usesess = NULL; const SSL_CIPHER *cipher = NULL; + const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (psksess != NULL) { if (!SSL_SESSION_up_ref(psksess)) @@ -243,7 +245,7 @@ static int psk_use_session_cb(SSL *s, const EVP_MD *md, if (usesess == NULL || !SSL_SESSION_set1_master_key(usesess, key, key_len) || !SSL_SESSION_set_cipher(usesess, cipher) - || !SSL_SESSION_set_protocol_version(usesess, TLS1_3_VERSION)) { + || !SSL_SESSION_set_protocol_version(usesess, version1_3)) { OPENSSL_free(key); goto err; } @@ -341,7 +343,7 @@ static int serverinfo_cli_parse_cb(SSL *s, unsigned int ext_type, ext_buf[3] = (unsigned char)(inlen); memcpy(ext_buf + 4, in, inlen); - BIO_snprintf(pem_name, sizeof(pem_name), "SERVERINFO FOR EXTENSION %u", + snprintf(pem_name, sizeof(pem_name), "SERVERINFO FOR EXTENSION %u", ext_type); PEM_write_bio(bio_c_out, pem_name, "", ext_buf, (long)(4 + inlen)); return 1; @@ -552,6 +554,7 @@ typedef enum OPTION_choice { OPT_DTLS, OPT_DTLS1, OPT_DTLS1_2, + OPT_DTLS1_3, OPT_QUIC, OPT_SCTP, OPT_TIMEOUT, @@ -814,6 +817,9 @@ const OPTIONS s_client_options[] = { #ifndef OPENSSL_NO_DTLS1_2 { "dtls1_2", OPT_DTLS1_2, '-', "Just use DTLSv1.2" }, #endif +#ifndef OPENSSL_NO_DTLS1_3 + { "dtls1_3", OPT_DTLS1_3, '-', "Just use DTLSv1.3" }, +#endif #ifndef OPENSSL_NO_SCTP { "sctp", OPT_SCTP, '-', "Use SCTP" }, { "sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug" }, @@ -941,7 +947,7 @@ static const OPT_PAIR services[] = { #define IS_PROT_FLAG(o) \ (o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \ || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2 \ - || o == OPT_QUIC) + || o == OPT_DTLS1_3 || o == OPT_QUIC) /* Free |*dest| and optionally set it to a copy of |source|. */ static void freeandcopy(char **dest, const char *source) @@ -954,6 +960,7 @@ static void freeandcopy(char **dest, const char *source) static int new_session_cb(SSL *s, SSL_SESSION *sess) { + const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (sess_out != NULL) { BIO *stmp = BIO_new_file(sess_out, "w"); @@ -967,10 +974,10 @@ static int new_session_cb(SSL *s, SSL_SESSION *sess) } /* - * Session data gets dumped on connection for TLSv1.2 and below, and on - * arrival of the NewSessionTicket for TLSv1.3. + * Session data gets dumped on connection for (D)TLSv1.2 and below, and on + * arrival of the NewSessionTicket for (D)TLSv1.3. */ - if (SSL_version(s) == TLS1_3_VERSION) { + if (SSL_version(s) == version1_3) { BIO_puts(bio_c_out, "---\nPost-Handshake New Session Ticket arrived:\n"); SSL_SESSION_print(bio_c_out, sess); @@ -1075,6 +1082,9 @@ int s_client_main(int argc, char **argv) #ifndef OPENSSL_NO_CT char *ctlog_file = NULL; int ct_validation = 0; +#endif +#ifndef OPENSSL_NO_NEXTPROTONEG + int version1_3; #endif int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0; int async = 0; @@ -1299,7 +1309,7 @@ int s_client_main(int argc, char **argv) crlf = 1; break; case OPT_QUIET: - c_quiet = c_ign_eof = 1; + verify_args.quiet = c_quiet = c_ign_eof = 1; break; case OPT_NBIO: c_nbio = 1; @@ -1489,6 +1499,18 @@ int s_client_main(int argc, char **argv) socket_type = SOCK_DGRAM; isdtls = 1; isquic = 0; +#endif + break; + case OPT_DTLS1_3: +#ifndef OPENSSL_NO_DTLS1_3 + meth = DTLS_client_method(); + min_version = DTLS1_3_VERSION; + max_version = DTLS1_3_VERSION; + socket_type = SOCK_DGRAM; + isdtls = 1; +#ifndef OPENSS_NO_QUIC + isquic = 0; +#endif #endif break; case OPT_QUIC: @@ -1520,7 +1542,8 @@ int s_client_main(int argc, char **argv) break; case OPT_MTU: #ifndef OPENSSL_NO_DTLS - socket_mtu = atol(opt_arg()); + if (!opt_long(opt_arg(), &socket_mtu)) + goto opthelp; #endif break; case OPT_FALLBACKSCSV: @@ -1625,7 +1648,20 @@ int s_client_main(int argc, char **argv) len = (int)strlen(p); for (start = 0, i = 0; i <= len; ++i) { if (i == len || p[i] == ',') { - serverinfo_types[serverinfo_count] = atoi(p + start); + char *end; + unsigned long ul; + + /* + * Parse only the current comma-separated component. + * OPENSSL_strtoul() with an endptr consumes the leading + * digits; we require it to stop exactly at the delimiter + * (or NUL) and to fit in an unsigned short. + */ + if (!OPENSSL_strtoul(p + start, &end, 10, &ul) + || end != p + i + || ul > USHRT_MAX) + goto opthelp; + serverinfo_types[serverinfo_count] = (unsigned short)ul; if (++serverinfo_count == MAX_SI_TYPES) break; start = i + 1; @@ -1758,6 +1794,10 @@ int s_client_main(int argc, char **argv) } } +#ifndef OPENSSL_NO_NEXTPROTONEG + version1_3 = isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION; +#endif + /* Optional argument is connect string if -connect not used. */ if (opt_num_rest() == 1) { /* Don't allow -connect and a separate argument. */ @@ -1808,7 +1848,7 @@ int s_client_main(int argc, char **argv) } #endif #ifndef OPENSSL_NO_NEXTPROTONEG - if (min_version == TLS1_3_VERSION && next_proto_neg_in != NULL) { + if (min_version == version1_3 && next_proto_neg_in != NULL) { BIO_puts(bio_err, "Cannot supply -nextprotoneg with TLSv1.3\n"); goto opthelp; } @@ -2447,7 +2487,7 @@ int s_client_main(int argc, char **argv) BIO_ADDR_free(peer_addr); peer_addr = NULL; if (init_client(&sock, host, port, bindhost, bindport, socket_family, - socket_type, protocol, tfo, !isquic, &peer_addr) + socket_type, protocol, tfo, !isquic, &peer_addr, c_quiet) == 0) { BIO_printf(bio_err, "connect:errno=%d\n", get_last_socket_error()); BIO_closesocket(sock); @@ -3049,6 +3089,7 @@ int s_client_main(int argc, char **argv) ASN1_TYPE *atyp = NULL; BIO *ldapbio = BIO_new(BIO_s_mem()); CONF *cnf = NCONF_new(NULL); + size_t ssl_request_len; if (ldapbio == NULL || cnf == NULL) { BIO_free(ldapbio); @@ -3081,11 +3122,18 @@ int s_client_main(int argc, char **argv) BIO_puts(bio_err, "ASN1_generate_nconf failed\n"); goto end; } + ssl_request_len = ASN1_STRING_get_length(atyp->value.sequence); + if (ssl_request_len > INT_MAX) { + NCONF_free(cnf); + ASN1_TYPE_free(atyp); + BIO_puts(bio_err, "generated NCONF size is too large\n"); + goto end; + } NCONF_free(cnf); /* Send SSLRequest packet */ BIO_write(sbio, ASN1_STRING_get0_data(atyp->value.sequence), - ASN1_STRING_length(atyp->value.sequence)); + (int)ssl_request_len); (void)BIO_flush(sbio); ASN1_TYPE_free(atyp); @@ -3743,7 +3791,8 @@ static void print_stuff(BIO *bio, SSL *s, int full) X509 *peer = NULL; STACK_OF(X509) *sk; const SSL_CIPHER *c; - int i, istls13 = (SSL_version(s) == TLS1_3_VERSION); + const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + int i; long verify_result; #ifndef OPENSSL_NO_COMP const COMP_METHOD *comp, *expansion; @@ -3934,7 +3983,7 @@ static void print_stuff(BIO *bio, SSL *s, int full) } #endif - if (istls13) { + if (SSL_version(s) == version1_3) { switch (SSL_get_early_data_status(s)) { case SSL_EARLY_DATA_NOT_SENT: BIO_puts(bio, "Early data was not sent\n"); @@ -4011,7 +4060,8 @@ static int ocsp_resp_cb(SSL *s, void *arg) STACK_OF(OCSP_RESPONSE) *sk_resp = NULL; OCSP_RESPONSE *rsp; - if (SSL_version(s) >= TLS1_3_VERSION) { + if ((!SSL_is_dtls(s) && SSL_version(s) >= TLS1_3_VERSION) + || (SSL_is_dtls(s) && SSL_version(s) <= DTLS1_3_VERSION)) { (void)SSL_get0_tlsext_status_ocsp_resp_ex(s, &sk_resp); BIO_puts(arg, "OCSP responses: "); @@ -4243,6 +4293,8 @@ static int user_data_add(struct user_data_st *user_data, size_t i) static int user_data_execute(struct user_data_st *user_data, int cmd, char *arg) { + const int version1_3 = SSL_is_dtls(user_data->con) ? DTLS1_3_VERSION : TLS1_3_VERSION; + switch (cmd) { case USER_COMMAND_HELP: /* This only ever occurs in advanced mode, so just emit advanced help */ @@ -4255,7 +4307,7 @@ static int user_data_execute(struct user_data_st *user_data, int cmd, char *arg) " {reconnect}: Reconnect to the peer\n"); if (SSL_is_quic(user_data->con)) { BIO_puts(bio_err, " {fin}: Send FIN on the stream. No further writing is possible\n"); - } else if (SSL_version(user_data->con) == TLS1_3_VERSION) { + } else if (SSL_version(user_data->con) == version1_3) { BIO_puts(bio_err, " {keyup:req|noreq}: Send a Key Update message\n" " Arguments:\n" " req = peer update requested (default)\n" @@ -4317,6 +4369,7 @@ static int user_data_process(struct user_data_st *user_data, size_t *len, { char *buf_start = user_data->buf + user_data->bufoff; size_t outlen = user_data->buflen; + const int version1_3 = SSL_is_dtls(user_data->con) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (user_data->buflen == 0) { *len = 0; @@ -4403,7 +4456,7 @@ static int user_data_process(struct user_data_st *user_data, size_t *len, if (OPENSSL_strcasecmp(cmd_start, "fin") == 0) cmd = USER_COMMAND_FIN; } - if (SSL_version(user_data->con) == TLS1_3_VERSION) { + if (SSL_version(user_data->con) == version1_3) { if (OPENSSL_strcasecmp(cmd_start, "keyup") == 0) { cmd = USER_COMMAND_KEY_UPDATE; if (arg_start == NULL) diff --git a/apps/s_server.c b/apps/s_server.c index 4d99e5442b2cc..57c253d05a1bf 100644 --- a/apps/s_server.c +++ b/apps/s_server.c @@ -82,6 +82,7 @@ typedef unsigned int u_int; #endif #include "internal/sockets.h" #include "internal/statem.h" +#include "ssl/ssl_local.h" #ifndef OPENSSL_NO_ECH /* needed for X509_check_host in some CI builds "no-http" */ @@ -133,8 +134,10 @@ static int keymatexportlen = 20; static int async = 0; -static int use_sendfile = 0; -static int use_zc_sendfile = 0; +#ifndef OPENSSL_NO_KTLS +static int use_sendfile; +static int use_zc_sendfile; +#endif static const char *session_id_prefix = NULL; @@ -168,16 +171,17 @@ static unsigned int psk_server_cb(SSL *ssl, const char *identity, { long key_len = 0; unsigned char *key; + const int version1_3 = SSL_is_dtls(ssl) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (s_debug) BIO_puts(bio_s_out, "psk_server_cb\n"); - if (!SSL_is_dtls(ssl) && SSL_version(ssl) >= TLS1_3_VERSION) { + if (PROTOCOL_VERSION_CMP(SSL_is_dtls(ssl), SSL_version(ssl), version1_3) >= 0) { /* * This callback is designed for use in (D)TLSv1.2 (or below). It is * possible to use a single callback for all protocol versions - but it - * is preferred to use a dedicated callback for TLSv1.3. For TLSv1.3 we - * have psk_find_session_cb. + * is preferred to use a dedicated callback for (D)TLSv1.3. For + * (D)TLSv1.3 we have psk_find_session_cb. */ return 0; } @@ -849,10 +853,8 @@ static int bring_ocsp_resp_in_correct_order(SSL *s, tlsextstatusctx *srctx, sk_OCSP_RESPONSE_pop_free(*sk_resp, OCSP_RESPONSE_free); SSL_get0_chain_certs(s, &server_chain); - /* - * TODO(DTLS-1.3): in future DTLS should also be considered - */ - if (server_chain != NULL && srctx->status_all && !SSL_is_dtls(s) && SSL_version(s) >= TLS1_3_VERSION) { + + if (server_chain != NULL && srctx->status_all && ((!SSL_is_dtls(s) && SSL_version(s) >= TLS1_3_VERSION) || (SSL_is_dtls(s) && SSL_version(s) <= DTLS1_3_VERSION))) { /* certificate chain is available */ num = sk_X509_num(server_chain) + 1; } @@ -1007,10 +1009,7 @@ static int get_ocsp_resp_from_responder(SSL *s, tlsextstatusctx *srctx, SSL_get0_chain_certs(s, &server_chain); - /* - * TODO(DTLS-1.3): in future DTLS should also be considered - */ - if (server_chain != NULL && srctx->status_all && !SSL_is_dtls(s) && SSL_version(s) >= TLS1_3_VERSION) { + if (server_chain != NULL && srctx->status_all && ((!SSL_is_dtls(s) && SSL_version(s) >= TLS1_3_VERSION) || (SSL_is_dtls(s) && SSL_version(s) <= DTLS1_3_VERSION))) { /* certificate chain is available */ num = sk_X509_num(server_chain) + 1; } else { @@ -1266,6 +1265,7 @@ typedef enum OPTION_choice { OPT_DTLS, OPT_DTLS1, OPT_DTLS1_2, + OPT_DTLS1_3, OPT_SCTP, OPT_TIMEOUT, OPT_MTU, @@ -1510,7 +1510,7 @@ const OPTIONS s_server_options[] = { "The maximum number of bytes of early data (hard limit)" }, { "early_data", OPT_EARLY_DATA, '-', "Attempt to read early data" }, { "num_tickets", OPT_S_NUM_TICKETS, 'n', - "The number of TLSv1.3 session tickets that a server will automatically issue" }, + "The number of (D)TLSv1.3 session tickets that a server will automatically issue" }, { "anti_replay", OPT_ANTI_REPLAY, '-', "Switch on anti-replay protection (default)" }, { "no_anti_replay", OPT_NO_ANTI_REPLAY, '-', "Switch off anti-replay protection" }, { "http_server_binmode", OPT_HTTP_SERVER_BINMODE, '-', "opening files in binary mode when acting as http server (-WWW and -HTTP)" }, @@ -1540,6 +1540,9 @@ const OPTIONS s_server_options[] = { #ifndef OPENSSL_NO_DTLS1_2 { "dtls1_2", OPT_DTLS1_2, '-', "Just talk DTLSv1.2" }, #endif +#ifndef OPENSSL_NO_DTLS1_3 + { "dtls1_3", OPT_DTLS1_3, '-', "Just talk DTLSv1.3" }, +#endif #ifndef OPENSSL_NO_SCTP { "sctp", OPT_SCTP, '-', "Use SCTP" }, { "sctp_label_bug", OPT_SCTP_LABEL_BUG, '-', "Enable SCTP label length bug" }, @@ -1622,17 +1625,18 @@ static int ech_load_dir(SSL_CTX *lctx, const char *thedir, int r; #ifdef OPENSSL_SYS_VMS - r = BIO_snprintf(filepath, sizeof(filepath), "%s%s", thedir, thisfile); + r = snprintf(filepath, sizeof(filepath), "%s%s", thedir, thisfile); #else - r = BIO_snprintf(filepath, sizeof(filepath), "%s/%s", thedir, thisfile); + r = snprintf(filepath, sizeof(filepath), "%s/%s", thedir, thisfile); #endif + if (r < 0 || (size_t)r >= sizeof(filepath)) + continue; if (app_isdir(filepath) > 0) { if (s_debug) BIO_printf(bio_err, "Skipping directory: %s\n", filepath); continue; } - if (r < 0 - || (in = BIO_new_file(filepath, "r")) == NULL + if ((in = BIO_new_file(filepath, "r")) == NULL || OSSL_ECHSTORE_read_pem(es, in, for_retry) != 1) { BIO_printf(bio_err, "Failed reading from: %s\n", filepath); continue; @@ -1661,9 +1665,10 @@ static int ech_load_dir(SSL_CTX *lctx, const char *thedir, } #endif -#define IS_PROT_FLAG(o) \ - (o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \ - || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2) +#define IS_PROT_FLAG(o) \ + (o == OPT_TLS1 || o == OPT_TLS1_1 || o == OPT_TLS1_2 \ + || o == OPT_TLS1_3 || o == OPT_DTLS || o == OPT_DTLS1 || o == OPT_DTLS1_2 \ + || o == OPT_DTLS1_3) int s_server_main(int argc, char *argv[]) { @@ -1722,6 +1727,9 @@ int s_server_main(int argc, char *argv[]) #endif #ifndef OPENSSL_NO_SRTP char *srtp_profiles = NULL; +#endif +#if !(defined(OPENSSL_NO_NEXTPROTONEG) && defined(OPENSSL_NO_PSK)) + int version1_3; #endif int min_version = 0, max_version = 0, prot_opt = 0, no_prot_opt = 0; int s_server_verify = SSL_VERIFY_NONE; @@ -1772,8 +1780,10 @@ int s_server_main(int argc, char *argv[]) s_quiet = 0; s_brief = 0; async = 0; +#ifndef OPENSSL_NO_KTLS use_sendfile = 0; use_zc_sendfile = 0; +#endif port = OPENSSL_strdup(PORT); cctx = SSL_CONF_CTX_new(); @@ -1885,7 +1895,7 @@ int s_server_main(int argc, char *argv[]) break; #endif case OPT_NACCEPT: - naccept = atol(opt_arg()); + naccept = opt_int_arg(); break; case OPT_VERIFY: s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; @@ -2020,7 +2030,7 @@ int s_server_main(int argc, char *argv[]) goto end; break; case OPT_VERIFY_RET_ERROR: - s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; + s_server_verify |= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; verify_args.return_error = 1; break; case OPT_VERIFY_QUIET: @@ -2235,6 +2245,14 @@ int s_server_main(int argc, char *argv[]) min_version = DTLS1_2_VERSION; max_version = DTLS1_2_VERSION; socket_type = SOCK_DGRAM; +#endif + break; + case OPT_DTLS1_3: +#ifndef OPENSSL_NO_DTLS + meth = DTLS_server_method(); + min_version = DTLS1_3_VERSION; + max_version = DTLS1_3_VERSION; + socket_type = SOCK_DGRAM; #endif break; case OPT_SCTP: @@ -2254,7 +2272,8 @@ int s_server_main(int argc, char *argv[]) break; case OPT_MTU: #ifndef OPENSSL_NO_DTLS - socket_mtu = atol(opt_arg()); + if (!opt_long(opt_arg(), &socket_mtu)) + goto opthelp; #endif break; case OPT_LISTEN: @@ -2407,6 +2426,10 @@ int s_server_main(int argc, char *argv[]) } } +#if !(defined(OPENSSL_NO_NEXTPROTONEG) && defined(OPENSSL_NO_PSK)) + version1_3 = (socket_type == SOCK_DGRAM) ? DTLS1_3_VERSION : TLS1_3_VERSION; +#endif + /* No extra arguments. */ if (!opt_check_rest_arg(NULL)) goto opthelp; @@ -2415,7 +2438,7 @@ int s_server_main(int argc, char *argv[]) goto end; #ifndef OPENSSL_NO_NEXTPROTONEG - if (min_version == TLS1_3_VERSION && next_proto_neg_in != NULL) { + if (min_version == version1_3 && next_proto_neg_in != NULL) { BIO_puts(bio_err, "Cannot supply -nextprotoneg with TLSv1.3\n"); goto opthelp; } @@ -2985,7 +3008,7 @@ int s_server_main(int argc, char *argv[]) } if (psk_identity_hint != NULL) { - if (min_version == TLS1_3_VERSION) { + if (min_version == version1_3) { BIO_puts(bio_s_out, "PSK warning: there is NO identity hint in TLSv1.3\n"); } else { if (!SSL_CTX_use_psk_identity_hint(ctx, psk_identity_hint)) { diff --git a/apps/s_time.c b/apps/s_time.c index d68418445cd0a..9a2a967f5e39f 100644 --- a/apps/s_time.c +++ b/apps/s_time.c @@ -307,9 +307,10 @@ int s_time_main(int argc, char **argv) goto end; if (www_path != NULL) { - buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, + buf_len = snprintf(buf, sizeof(buf), fmt_http_get_cmd, www_path); - if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0) + if (buf_len <= 0 || (size_t)buf_len >= sizeof(buf) + || SSL_write(scon, buf, buf_len) <= 0) goto end; while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) bytes_read += i; @@ -360,8 +361,9 @@ int s_time_main(int argc, char **argv) } if (www_path != NULL) { - buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, www_path); - if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0) + buf_len = snprintf(buf, sizeof(buf), fmt_http_get_cmd, www_path); + if (buf_len <= 0 || (size_t)buf_len >= sizeof(buf) + || SSL_write(scon, buf, buf_len) <= 0) goto end; while (SSL_read(scon, buf, sizeof(buf)) > 0) continue; @@ -388,9 +390,10 @@ int s_time_main(int argc, char **argv) goto end; if (www_path != NULL) { - buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, + buf_len = snprintf(buf, sizeof(buf), fmt_http_get_cmd, www_path); - if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0) + if (buf_len <= 0 || (size_t)buf_len >= sizeof(buf) + || SSL_write(scon, buf, buf_len) <= 0) goto end; while ((i = SSL_read(scon, buf, sizeof(buf))) > 0) bytes_read += i; diff --git a/apps/skeyutl.c b/apps/skeyutl.c index 46461781ff57c..cb9a8131de0b8 100644 --- a/apps/skeyutl.c +++ b/apps/skeyutl.c @@ -102,6 +102,9 @@ int skeyutl_main(int argc, char **argv) goto end; params = app_params_new_from_opts(skeyopts, EVP_SKEYMGMT_get0_gen_settable_params(mgmt)); + /* A NULL return is an error only if key options were given */ + if (skeyopts != NULL && params == NULL) + goto end; skey = EVP_SKEY_generate(app_get0_libctx(), skeymgmt ? skeymgmt : EVP_CIPHER_name(cipher), diff --git a/apps/smime.c b/apps/smime.c index 7f639ebd5b8b9..fd817ca98bfb9 100644 --- a/apps/smime.c +++ b/apps/smime.c @@ -117,7 +117,7 @@ const OPTIONS smime_options[] = { { "nodetach", OPT_NODETACH, '-', "Use opaque signing" }, { "noattr", OPT_NOATTR, '-', "Don't include any signed attributes" }, { "binary", OPT_BINARY, '-', "Don't translate message to text" }, - { "signer", OPT_SIGNER, 's', "Signer certificate file" }, + { "signer", OPT_SIGNER, 's', "Signer certificate" }, { "content", OPT_CONTENT, '<', "Supply or override content for detached signature" }, { "nocerts", OPT_NOCERTS, '-', @@ -127,11 +127,7 @@ const OPTIONS smime_options[] = { { "nosigs", OPT_NOSIGS, '-', "Don't verify message signature" }, { "noverify", OPT_NOVERIFY, '-', "Don't verify signers certificate" }, - { "certfile", OPT_CERTFILE, '<', - "Extra signer and intermediate CA certificates to include when signing" }, - { OPT_MORE_STR, 0, 0, - "or to use as preferred signer certs and for chain building when verifying" }, - { "recip", OPT_RECIP, '<', "Recipient certificate file for decryption" }, + { "recip", OPT_RECIP, '<', "Recipient certificate for decryption" }, OPT_SECTION("Email"), { "to", OPT_TO, 's', "To address" }, @@ -141,6 +137,10 @@ const OPTIONS smime_options[] = { { "nosmimecap", OPT_NOSMIMECAP, '-', "Omit the SMIMECapabilities attribute" }, OPT_SECTION("Certificate chain"), + { "certfile", OPT_CERTFILE, '<', + "Extra signer and intermediate CA certificates to include when signing" }, + { OPT_MORE_STR, 0, 0, + "or to use as preferred signer certs and for chain building when verifying" }, { "CAfile", OPT_CAFILE, '<', "File in PEM format with trusted CA certs" }, { "CApath", OPT_CAPATH, '/', "Dir with trusted CA cert files in PEM format" }, { "CAstore", OPT_CASTORE, ':', "URI of store with trusted CA certs" }, @@ -151,8 +151,8 @@ const OPTIONS smime_options[] = { { "no-CAstore", OPT_NOCASTORE, '-', "Do not load certificates from the default certificates store" }, { "nochain", OPT_NOCHAIN, '-', - "set PKCS7_NOCHAIN so certificates contained in the message are not used as untrusted CAs" }, - { "crlfeol", OPT_CRLFEOL, '-', "Use CRLF as EOL termination instead of LF only" }, + "Do not use certs contained in the message as untrusted CAs for chain building" }, + { "crlfeol", OPT_CRLFEOL, '-', "Use CRLF as EOL termination (instead of LF only)" }, OPT_R_OPTIONS, OPT_V_OPTIONS, @@ -520,7 +520,7 @@ int smime_main(int argc, char **argv) } if (certfile != NULL) { - if (!load_certs(certfile, 0, &other, NULL, "certificates")) { + if (!load_certs(certfile, 0, &other, NULL, "extra certificates")) { ERR_print_errors(bio_err); goto end; } @@ -624,7 +624,7 @@ int smime_main(int argc, char **argv) p7 = PKCS7_sign_ex(NULL, NULL, other, in, flags, libctx, app_get0_propq()); if (p7 == NULL) goto end; - if (flags & PKCS7_NOCERTS) { + if ((flags & PKCS7_NOCERTS) != 0) { /* still add list given via -certfile */ for (i = 0; i < sk_X509_num(other); i++) { X509 *x = sk_X509_value(other, i); PKCS7_add_certificate(p7, x); diff --git a/apps/speed.c b/apps/speed.c index b1732744d3afb..d121dfe076ded 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -2622,7 +2622,7 @@ int speed_main(int argc, char **argv) if (evp_mac_mdname == NULL) goto end; evp_hmac_name = app_malloc(hmac_name_len, "HMAC name"); - BIO_snprintf(evp_hmac_name, hmac_name_len, "hmac(%s)", evp_mac_mdname); + snprintf(evp_hmac_name, hmac_name_len, "hmac(%s)", evp_mac_mdname); names[D_HMAC] = evp_hmac_name; params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, @@ -3030,7 +3030,7 @@ int speed_main(int argc, char **argv) goto end; } evp_cmac_name = app_malloc(len, "CMAC name"); - BIO_snprintf(evp_cmac_name, len, "cmac(%s)", evp_mac_ciphername); + snprintf(evp_cmac_name, len, "cmac(%s)", evp_mac_ciphername); names[D_EVP_CMAC] = evp_cmac_name; params[0] = OSSL_PARAM_construct_utf8_string(OSSL_ALG_PARAM_CIPHER, @@ -3946,11 +3946,15 @@ int speed_main(int argc, char **argv) } if (strncmp(sig_name, "dsa", 3) == 0) { + int dsa_nbits = 0; + + if (!opt_int(sig_name + 3, &dsa_nbits)) + goto sig_err_break; ctx_params = EVP_PKEY_CTX_new_id(EVP_PKEY_DSA, NULL); if (ctx_params == NULL || EVP_PKEY_paramgen_init(ctx_params) <= 0 || EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx_params, - atoi(sig_name + 3)) + dsa_nbits) <= 0 || EVP_PKEY_paramgen(ctx_params, &pkey_params) <= 0 || (sig_gen_ctx = EVP_PKEY_CTX_new(pkey_params, NULL)) == NULL diff --git a/apps/spkac.c b/apps/spkac.c index bcf5626277186..9f2d0d0d076f2 100644 --- a/apps/spkac.c +++ b/apps/spkac.c @@ -155,8 +155,8 @@ int spkac_main(int argc, char **argv) if (spki == NULL) goto end; if (challenge != NULL - && !ASN1_STRING_set(spki->spkac->challenge, - challenge, (int)strlen(challenge))) + && !ASN1_STRING_set1_string(spki->spkac->challenge, + challenge)) goto end; if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) { BIO_puts(bio_err, "Error setting public key\n"); diff --git a/apps/testdsa.h b/apps/testdsa.h index 48ff31309fcf3..120cdc8e9af30 100644 --- a/apps/testdsa.h +++ b/apps/testdsa.h @@ -1,5 +1,5 @@ /* - * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/apps/testrsa.h b/apps/testrsa.h index 0a9d5dda37af8..058471e4f7062 100644 --- a/apps/testrsa.h +++ b/apps/testrsa.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/apps/ts.c b/apps/ts.c index aaec526154c2c..4d5016fcca5de 100644 --- a/apps/ts.c +++ b/apps/ts.c @@ -583,7 +583,7 @@ static ASN1_INTEGER *create_nonce(int bits) if ((nonce = ASN1_INTEGER_new()) == NULL) goto err; - if (!ASN1_STRING_set(nonce, buf, len)) + if (!ASN1_STRING_set1_data(nonce, buf, len)) goto err; ret = nonce; diff --git a/apps/tsget.in b/apps/tsget.in index 8eab6a8f1f578..311ad2ed5ec60 100644 --- a/apps/tsget.in +++ b/apps/tsget.in @@ -1,5 +1,5 @@ #!{- $config{HASHBANGPERL} -} -# Copyright 2002-2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2002 The OpenTSA Project. All rights reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use @@ -8,58 +8,42 @@ # https://www.openssl.org/source/license.html use strict; +use warnings; use IO::Handle; use Getopt::Std; use File::Basename; -use WWW::Curl::Easy; +use File::Temp qw(tempfile); +use Net::Curl::Easy qw(:constants); use vars qw(%options); -# Callback for reading the body. -sub read_body { - my ($maxlength, $state) = @_; - my $return_data = ""; - my $data_len = length ${$state->{data}}; - if ($state->{bytes} < $data_len) { - $data_len = $data_len - $state->{bytes}; - $data_len = $maxlength if $data_len > $maxlength; - $return_data = substr ${$state->{data}}, $state->{bytes}, $data_len; - $state->{bytes} += $data_len; - } - return $return_data; +sub usage { + print STDERR "usage: $0 -h [-e ] [-o ] "; + print STDERR "[-v] [-d] [-k ] [-p ] "; + print STDERR "[-c ] [-C ] [-P ] "; + print STDERR "[-r ] [-g ] []...\n"; + exit 1; } -# Callback for writing the body into a variable. -sub write_body { - my ($data, $pointer) = @_; - ${$pointer} .= $data; - return length($data); +sub progress { + return unless $options{v}; + STDERR->printflush(@_); } # Initialise a new Curl object. sub create_curl { - my $url = shift; + my ($url) = @_; - # Create Curl object. - my $curl = WWW::Curl::Easy::new(); + my $curl = Net::Curl::Easy->new(); - # Error-handling related options. $curl->setopt(CURLOPT_VERBOSE, 1) if $options{d}; $curl->setopt(CURLOPT_FAILONERROR, 1); $curl->setopt(CURLOPT_USERAGENT, "OpenTSA tsget.pl/openssl-{- $config{full_version} -}"); - # Options for POST method. - $curl->setopt(CURLOPT_UPLOAD, 1); - $curl->setopt(CURLOPT_CUSTOMREQUEST, "POST"); $curl->setopt(CURLOPT_HTTPHEADER, ["Content-Type: application/timestamp-query", "Accept: application/timestamp-reply,application/timestamp-response"]); - $curl->setopt(CURLOPT_READFUNCTION, \&read_body); - $curl->setopt(CURLOPT_HEADERFUNCTION, sub { return length($_[0]); }); - - # Options for getting the result. - $curl->setopt(CURLOPT_WRITEFUNCTION, \&write_body); # SSL related options. $curl->setopt(CURLOPT_SSLKEYTYPE, "PEM"); @@ -70,6 +54,9 @@ sub create_curl { $curl->setopt(CURLOPT_SSLCERT, $options{c}) if defined($options{c}); $curl->setopt(CURLOPT_CAINFO, $options{C}) if defined($options{C}); $curl->setopt(CURLOPT_CAPATH, $options{P}) if defined($options{P}); + + # CURLOPT_RANDOM_FILE and CURLOPT_EGDSOCKET are deprecated no-ops in libcurl; + # they still exist as constants and return success, so no eval is needed. $curl->setopt(CURLOPT_RANDOM_FILE, $options{r}) if defined($options{r}); $curl->setopt(CURLOPT_EGDSOCKET, $options{g}) if defined($options{g}); @@ -79,122 +66,121 @@ sub create_curl { return $curl; } -# Send a request and returns the body back. -sub get_timestamp { - my $curl = shift; - my $body = shift; - my $ts_body; - local $::error_buf; - - # Error-handling related options. - $curl->setopt(CURLOPT_ERRORBUFFER, "::error_buf"); - - # Options for POST method. - $curl->setopt(CURLOPT_INFILE, {data => $body, bytes => 0}); - $curl->setopt(CURLOPT_INFILESIZE, length(${$body})); - - # Options for getting the result. - $curl->setopt(CURLOPT_FILE, \$ts_body); - - # Send the request... - my $error_code = $curl->perform(); - my $error_string; - if ($error_code != 0) { - my $http_code = $curl->getinfo(CURLINFO_HTTP_CODE); - $error_string = "could not get timestamp"; - $error_string .= ", http code: $http_code" unless $http_code == 0; - $error_string .= ", curl code: $error_code"; - $error_string .= " ($::error_buf)" if defined($::error_buf); - } else { - my $ct = $curl->getinfo(CURLINFO_CONTENT_TYPE); - if (lc($ct) ne "application/timestamp-reply" - && lc($ct) ne "application/timestamp-response") { - $error_string = "unexpected content type returned: $ct"; - } +# Send a request, writing the response to the given filehandle. +# Returns an error string on network/protocol failure, undef on success. +sub send_request { + my ($curl, $body, $out_fh) = @_; + + $curl->setopt(CURLOPT_POST, 1); + $curl->setopt(CURLOPT_POSTFIELDS, $body); + $curl->setopt(CURLOPT_POSTFIELDSIZE, length($body)); + $curl->setopt(CURLOPT_WRITEDATA, $out_fh); + + my $ok = eval { $curl->perform(); 1; }; + + if (!$ok) { + my $http_code = eval { $curl->getinfo(CURLINFO_HTTP_CODE) } // 0; + my $curl_err = eval { $curl->error() } // ""; + my $err = "could not get timestamp"; + $err .= ", http code: $http_code" if $http_code != 0; + $err .= " ($curl_err)" if length($curl_err); + return $err; } - return ($ts_body, $error_string); -} + my $downloaded = $curl->getinfo(CURLINFO_SIZE_DOWNLOAD); + if (!defined($downloaded) || $downloaded == 0) { + return "empty response received"; + } -# Print usage information and exists. -sub usage { + my $ct = $curl->getinfo(CURLINFO_CONTENT_TYPE); + if (!defined($ct) + || (lc($ct) ne "application/timestamp-reply" + && lc($ct) ne "application/timestamp-response")) { + return "unexpected content type returned: " + . (defined($ct) ? $ct : "(none)"); + } - print STDERR "usage: $0 -h [-e ] [-o ] "; - print STDERR "[-v] [-d] [-k ] [-p ] "; - print STDERR "[-c ] [-C ] [-P ] "; - print STDERR "[-r ] [-g ] []...\n"; - exit 1; + return undef; } -# ---------------------------------------------------------------------- -# Main program -# ---------------------------------------------------------------------- +my $getopt_arg = "h:e:o:vdk:p:c:C:P:r:g:"; # Getting command-line options (default comes from TSGET environment variable). -my $getopt_arg = "h:e:o:vdk:p:c:C:P:r:g:"; if (exists $ENV{TSGET}) { - my @old_argv = @ARGV; + my @saved_argv = @ARGV; @ARGV = split /\s+/, $ENV{TSGET}; getopts($getopt_arg, \%options) or usage; - @ARGV = @old_argv; + @ARGV = @saved_argv; } getopts($getopt_arg, \%options) or usage; -# Checking argument consistency. -if (!exists($options{h}) || (@ARGV == 0 && !exists($options{o})) - || (@ARGV > 1 && exists($options{o}))) { +if (!defined($options{h}) || (@ARGV == 0 && !defined($options{o})) + || (@ARGV > 1 && defined($options{o}))) { print STDERR "Inconsistent command line options.\n"; usage; } -# Setting defaults. -@ARGV = ("-") unless @ARGV != 0; +@ARGV = ("-") unless @ARGV; $options{e} = ".tsr" unless defined($options{e}); -# Processing requests. -my $curl = create_curl $options{h}; -undef $/; # For reading whole files. -REQUEST: foreach (@ARGV) { - my $input = $_; +my $curl = create_curl($options{h}); +undef $/; + +REQUEST: for my $input (@ARGV) { my ($base, $path) = fileparse($input, '\.[^.]*'); - my $output_base = $base . $options{e}; - my $output = defined($options{o}) ? $options{o} : $path . $output_base; + my $output = defined($options{o}) ? $options{o} : $path . $base . $options{e}; - STDERR->printflush("$input: ") if $options{v}; - # Read request. + progress("$input: "); my $body; if ($input eq "-") { - # Read the request from STDIN; + binmode STDIN; $body = ; } else { - # Read the request from file. - open INPUT, "<" . $input + open my $in, '<', $input or warn("$input: could not open input file: $!\n"), next REQUEST; - $body = ; - close INPUT + binmode $in; + $body = <$in>; + close $in or warn("$input: could not close input file: $!\n"), next REQUEST; } - # Send request. - STDERR->printflush("sending request") if $options{v}; - - my ($ts_body, $error) = get_timestamp $curl, \$body; - if (defined($error)) { - die "$input: fatal error: $error\n"; - } - STDERR->printflush(", reply received") if $options{v}; + progress("sending request"); - # Write response. + my $error; if ($output eq "-") { - # Write to STDOUT. - print $ts_body; + # Write to STDOUT directly. + binmode STDOUT; + $error = send_request($curl, $body, \*STDOUT); + die "$input: fatal error: $error\n" if defined($error); } else { - # Write to file. - open OUTPUT, ">", $output - or warn("$output: could not open output file: $!\n"), next REQUEST; - print OUTPUT $ts_body; - close OUTPUT - or warn("$output: could not close output file: $!\n"), next REQUEST; + # Write to a temp file first; rename to $output only on success so + # that a pre-existing output file is not clobbered on failure. + # Preserve the existing file's permissions; fall back to umask defaults. + my @st = stat($output); + my $mode = @st ? ($st[2] & 07777) : (0666 & ~umask()); + my ($tmp_fh, $tmp_path) = eval { + tempfile(DIR => dirname($output), UNLINK => 1); + }; + if (!defined($tmp_fh)) { + warn("$output: could not create temp file: $@\n"); + next REQUEST; + } + chmod($mode, $tmp_path); + binmode $tmp_fh; + + $error = send_request($curl, $body, $tmp_fh); + close $tmp_fh; + + if (defined($error)) { + unlink $tmp_path; + die "$input: fatal error: $error\n"; + } + + rename($tmp_path, $output) + or do { unlink $tmp_path; + warn("$output: could not rename temp file: $!\n"); + next REQUEST; }; } - STDERR->printflush(", $output written.\n") if $options{v}; + + progress(", reply received"); + progress(", $output written.\n"); } -$curl->cleanup(); diff --git a/apps/x509.c b/apps/x509.c index 867961e61d108..baf4da16f7107 100644 --- a/apps/x509.c +++ b/apps/x509.c @@ -713,7 +713,7 @@ int x509_main(int argc, char **argv) if (!opt_check_md(digest)) goto opthelp; - if (reqfile || newcert || privkey != NULL || CAfile != NULL) + if (reqfile || newcert || privkeyfile != NULL || CAfile != NULL) newout = 1; else if (sno != NULL || not_before != NULL @@ -1266,6 +1266,8 @@ int x509_main(int argc, char **argv) goto end; err: + /* Every path reaching this label is a failure path */ + ret = 1; ERR_print_errors(bio_err); end: diff --git a/build.info b/build.info index d7982a95536c3..fc4e4707bca0a 100644 --- a/build.info +++ b/build.info @@ -1,5 +1,35 @@ # Note that some of these directories are filtered in Configure. Look for # %skipdir there for further explanations. +{- use File::Spec::Functions; + + # The L table in crypto/err/openssl.ec names, for each error library, + # the files mkerr.pl emits for it: fields three onwards, with NONE + # where there is nothing to emit. + our @err_files = (); + my $ec = catfile($sourcedir, "crypto", "err", "openssl.ec"); + + open my $fh, "<", $ec or die "Can't read $ec, $!\n"; + while (<$fh>) { + s|\R$||; + next unless m|^L\s|; + my @field = split /\s+/; + push @err_files, grep { $_ ne "NONE" } @field[2 .. $#field]; + } + close $fh; + + our $err_headers = join(" \\\n ", grep { m|\.h$| } @err_files); + our $err_rules = + join("", map { + "GENERATE[$_]=util/mkerr.pl -internal \\\n" + . " -conf \$(SRCDIR)/crypto/err/openssl.ec -emit $_\n" + . "DEPEND[$_]=crypto/err/openssl.ec crypto/err/openssl.txt\n" + } @err_files); + + # Adding a library to the table above changes the rules below, so the + # configuration has to be redone when it changes. + push @{$config{build_infos}}, $ec; + "" +-} SUBDIRS=crypto ssl apps util fuzz providers doc IF[{- !$disabled{tests} -}] @@ -30,8 +60,11 @@ DEPEND[]=include/openssl/asn1.h \ include/openssl/ct.h \ include/openssl/err.h \ include/openssl/ess.h \ + include/openssl/evp.h \ include/openssl/fipskey.h \ include/openssl/lhash.h \ + {- $err_headers -} \ + include/openssl/obj_mac.h \ include/openssl/opensslv.h \ include/openssl/ocsp.h \ include/openssl/pkcs12.h \ @@ -45,6 +78,8 @@ DEPEND[]=include/openssl/asn1.h \ include/openssl/x509_acert.h \ include/openssl/x509_vfy.h \ include/crypto/dso_conf.h \ + include/crypto/ec_params.h \ + include/crypto/rsa_params.h \ providers/implementations/asymciphers/rsa_enc.inc \ providers/implementations/asymciphers/sm2_enc.inc \ providers/implementations/exchange/dh_exch.inc \ @@ -84,6 +119,7 @@ DEPEND[]=include/openssl/asn1.h \ providers/implementations/keymgmt/ecx_kmgmt.inc \ providers/implementations/keymgmt/lms_kmgmt.inc \ providers/implementations/keymgmt/mac_legacy_kmgmt.inc \ + providers/implementations/keymgmt/composite_kmgmt.inc \ providers/implementations/keymgmt/ml_dsa_kmgmt.inc \ providers/implementations/keymgmt/ml_kem_kmgmt.inc \ providers/implementations/keymgmt/mlx_kmgmt.inc \ @@ -94,6 +130,7 @@ DEPEND[]=include/openssl/asn1.h \ providers/implementations/signature/eddsa_sig.inc \ providers/implementations/signature/mac_legacy_sig.inc \ providers/implementations/signature/ml_dsa_sig.inc \ + providers/implementations/signature/composite_sig.inc \ providers/implementations/signature/rsa_sig.inc \ providers/implementations/signature/slh_dsa_sig.inc \ providers/implementations/signature/sm2_sig.inc \ @@ -108,14 +145,20 @@ DEPEND[]=include/openssl/asn1.h \ providers/implementations/ciphers/cipher_aes_siv.inc \ providers/implementations/ciphers/cipher_aes_wrp.inc \ providers/implementations/ciphers/cipher_aes_xts.inc \ + providers/implementations/ciphers/cipher_ascon_aead128.inc \ providers/implementations/ciphers/ciphercommon.inc \ providers/implementations/ciphers/ciphercommon_ccm.inc \ providers/implementations/ciphers/ciphercommon_gcm.inc \ providers/implementations/ciphers/cipher_chacha20.inc \ providers/implementations/ciphers/cipher_chacha20_poly1305.inc \ + providers/implementations/ciphers/cipher_cts.inc \ + providers/implementations/ciphers/cipher_des.inc \ providers/implementations/ciphers/cipher_null.inc \ + providers/implementations/ciphers/cipher_rc2.inc \ providers/implementations/ciphers/cipher_rc4_hmac_md5.inc \ + providers/implementations/ciphers/cipher_rc5.inc \ providers/implementations/ciphers/cipher_sm4_xts.inc \ + providers/implementations/ciphers/cipher_tdes.inc \ providers/implementations/digests/blake2_prov.inc \ providers/implementations/digests/digestcommon.inc \ providers/implementations/digests/mdc2_prov.inc \ @@ -139,6 +182,12 @@ DEPEND[]=include/openssl/asn1.h \ providers/implementations/rands/test_rng.inc GENERATE[include/openssl/asn1.h]=include/openssl/asn1.h.in + +{- $err_rules -}GENERATE[include/openssl/obj_mac.h]=crypto/objects/objects.pl \ + -a $(SRCDIR)/crypto/objects/obj_compat.h \ + $(SRCDIR)/crypto/objects/objects.txt $(SRCDIR)/crypto/objects/obj_mac.num +DEPEND[include/openssl/obj_mac.h]=crypto/objects/objects.txt \ + crypto/objects/obj_mac.num crypto/objects/obj_compat.h GENERATE[include/openssl/asn1t.h]=include/openssl/asn1t.h.in GENERATE[include/openssl/bio.h]=include/openssl/bio.h.in GENERATE[include/openssl/cmp.h]=include/openssl/cmp.h.in @@ -154,6 +203,7 @@ GENERATE[include/openssl/crypto.h]=include/openssl/crypto.h.in GENERATE[include/openssl/ct.h]=include/openssl/ct.h.in GENERATE[include/openssl/err.h]=include/openssl/err.h.in GENERATE[include/openssl/ess.h]=include/openssl/ess.h.in +GENERATE[include/openssl/evp.h]=include/openssl/evp.h.in GENERATE[include/openssl/fipskey.h]=include/openssl/fipskey.h.in GENERATE[include/openssl/lhash.h]=include/openssl/lhash.h.in GENERATE[include/openssl/ocsp.h]=include/openssl/ocsp.h.in @@ -209,6 +259,7 @@ DEPEND[providers/implementations/asymciphers/rsa_enc.inc \ providers/implementations/keymgmt/ecx_kmgmt.inc \ providers/implementations/keymgmt/lms_kmgmt.inc \ providers/implementations/keymgmt/mac_legacy_kmgmt.inc \ + providers/implementations/keymgmt/composite_kmgmt.inc \ providers/implementations/keymgmt/ml_dsa_kmgmt.inc \ providers/implementations/keymgmt/ml_kem_kmgmt.inc \ providers/implementations/keymgmt/mlx_kmgmt.inc \ @@ -219,6 +270,7 @@ DEPEND[providers/implementations/asymciphers/rsa_enc.inc \ providers/implementations/signature/eddsa_sig.inc \ providers/implementations/signature/mac_legacy_sig.inc \ providers/implementations/signature/ml_dsa_sig.inc \ + providers/implementations/signature/composite_sig.inc \ providers/implementations/signature/rsa_sig.inc \ providers/implementations/signature/slh_dsa_sig.inc \ providers/implementations/signature/sm2_sig.inc \ @@ -233,14 +285,20 @@ DEPEND[providers/implementations/asymciphers/rsa_enc.inc \ providers/implementations/ciphers/cipher_aes_siv.inc \ providers/implementations/ciphers/cipher_aes_wrp.inc \ providers/implementations/ciphers/cipher_aes_xts.inc \ + providers/implementations/ciphers/cipher_ascon_aead128.inc \ providers/implementations/ciphers/ciphercommon.inc \ providers/implementations/ciphers/ciphercommon_ccm.inc \ providers/implementations/ciphers/ciphercommon_gcm.inc \ providers/implementations/ciphers/cipher_chacha20.inc \ providers/implementations/ciphers/cipher_chacha20_poly1305.inc \ + providers/implementations/ciphers/cipher_cts.inc \ + providers/implementations/ciphers/cipher_des.inc \ providers/implementations/ciphers/cipher_null.inc \ + providers/implementations/ciphers/cipher_rc2.inc \ providers/implementations/ciphers/cipher_rc4_hmac_md5.inc \ + providers/implementations/ciphers/cipher_rc5.inc \ providers/implementations/ciphers/cipher_sm4_xts.inc \ + providers/implementations/ciphers/cipher_tdes.inc \ providers/implementations/digests/blake2_prov.inc \ providers/implementations/digests/ml_dsa_mu_prov.inc \ providers/implementations/digests/digestcommon.inc \ @@ -262,8 +320,14 @@ DEPEND[providers/implementations/asymciphers/rsa_enc.inc \ providers/implementations/rands/seed_src.inc \ providers/implementations/rands/seed_src_jitter.inc \ providers/implementations/rands/test_rng.inc \ + include/crypto/ec_params.h \ + include/crypto/rsa_params.h \ include/openssl/core_names.h]=util/perl|OpenSSL/paramnames.pm +GENERATE[include/crypto/ec_params.h]=\ + include/crypto/ec_params.h.in +GENERATE[include/crypto/rsa_params.h]=\ + include/crypto/rsa_params.h.in GENERATE[providers/implementations/asymciphers/rsa_enc.inc]=\ providers/implementations/asymciphers/rsa_enc.inc.in GENERATE[providers/implementations/asymciphers/sm2_enc.inc]=\ @@ -342,6 +406,8 @@ GENERATE[providers/implementations/keymgmt/lms_kmgmt.inc]=\ providers/implementations/keymgmt/lms_kmgmt.inc.in GENERATE[providers/implementations/keymgmt/mac_legacy_kmgmt.inc]=\ providers/implementations/keymgmt/mac_legacy_kmgmt.inc.in +GENERATE[providers/implementations/keymgmt/composite_kmgmt.inc]=\ + providers/implementations/keymgmt/composite_kmgmt.inc.in GENERATE[providers/implementations/keymgmt/ml_dsa_kmgmt.inc]=\ providers/implementations/keymgmt/ml_dsa_kmgmt.inc.in GENERATE[providers/implementations/keymgmt/ml_kem_kmgmt.inc]=\ @@ -362,6 +428,8 @@ GENERATE[providers/implementations/signature/mac_legacy_sig.inc]=\ providers/implementations/signature/mac_legacy_sig.inc.in GENERATE[providers/implementations/signature/ml_dsa_sig.inc]=\ providers/implementations/signature/ml_dsa_sig.inc.in +GENERATE[providers/implementations/signature/composite_sig.inc]=\ + providers/implementations/signature/composite_sig.inc.in GENERATE[providers/implementations/signature/rsa_sig.inc]=\ providers/implementations/signature/rsa_sig.inc.in GENERATE[providers/implementations/signature/slh_dsa_sig.inc]=\ @@ -390,6 +458,8 @@ GENERATE[providers/implementations/ciphers/cipher_aes_wrp.inc]=\ providers/implementations/ciphers/cipher_aes_wrp.inc.in GENERATE[providers/implementations/ciphers/cipher_aes_xts.inc]=\ providers/implementations/ciphers/cipher_aes_xts.inc.in +GENERATE[providers/implementations/ciphers/cipher_ascon_aead128.inc]=\ + providers/implementations/ciphers/cipher_ascon_aead128.inc.in GENERATE[providers/implementations/ciphers/ciphercommon.inc]=\ providers/implementations/ciphers/ciphercommon.inc.in GENERATE[providers/implementations/ciphers/ciphercommon_ccm.inc]=\ @@ -400,12 +470,22 @@ GENERATE[providers/implementations/ciphers/cipher_chacha20.inc]=\ providers/implementations/ciphers/cipher_chacha20.inc.in GENERATE[providers/implementations/ciphers/cipher_chacha20_poly1305.inc]=\ providers/implementations/ciphers/cipher_chacha20_poly1305.inc.in +GENERATE[providers/implementations/ciphers/cipher_cts.inc]=\ + providers/implementations/ciphers/cipher_cts.inc.in +GENERATE[providers/implementations/ciphers/cipher_des.inc]=\ + providers/implementations/ciphers/cipher_des.inc.in GENERATE[providers/implementations/ciphers/cipher_null.inc]=\ providers/implementations/ciphers/cipher_null.inc.in +GENERATE[providers/implementations/ciphers/cipher_rc2.inc]=\ + providers/implementations/ciphers/cipher_rc2.inc.in GENERATE[providers/implementations/ciphers/cipher_rc4_hmac_md5.inc]=\ providers/implementations/ciphers/cipher_rc4_hmac_md5.inc.in +GENERATE[providers/implementations/ciphers/cipher_rc5.inc]=\ + providers/implementations/ciphers/cipher_rc5.inc.in GENERATE[providers/implementations/ciphers/cipher_sm4_xts.inc]=\ providers/implementations/ciphers/cipher_sm4_xts.inc.in +GENERATE[providers/implementations/ciphers/cipher_tdes.inc]=\ + providers/implementations/ciphers/cipher_tdes.inc.in GENERATE[providers/implementations/digests/blake2_prov.inc]=\ providers/implementations/digests/blake2_prov.inc.in GENERATE[providers/implementations/digests/digestcommon.inc]=\ diff --git a/crypto/LPdir_win.c b/crypto/LPdir_win.c index 425a7962d0c19..2d05e93eb7d67 100644 --- a/crypto/LPdir_win.c +++ b/crypto/LPdir_win.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/aes_local.h b/crypto/aes/aes_local.h index 38c37537fc02a..12386b3b84e43 100644 --- a/crypto/aes/aes_local.h +++ b/crypto/aes/aes_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/aes_vaes512_intrinsics.c b/crypto/aes/aes_vaes512_intrinsics.c new file mode 100644 index 0000000000000..15bcb2bc4ec4c --- /dev/null +++ b/crypto/aes/aes_vaes512_intrinsics.c @@ -0,0 +1,721 @@ +/* + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (C) 2026, Advanced Micro Devices, all rights reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + * + * AVX-512/VAES-512 intrinsic implementations of AES modes. + * + * This translation unit gathers the VAES-accelerated AES mode + * implementations together with the shared 512-bit primitives they rely on: + * - portable compiler abstractions for ISA targeting and inlining, + * - a macro that emits 1x/2x/4x parallel 512-bit AES round functions, + * - macros to broadcast-load and securely scrub the round-key schedule, + * - a runtime CPU capability check. + * + * Currently implemented: AES-CTR encryption and AES-CBC decryption. + * + * CBC encryption is inherently serial (each ciphertext block depends on the + * previous one), so VAES provides no benefit there -- that path falls back to + * the aesni_cbc_encrypt assembly routine. CBC decryption is parallel: all + * blocks are decrypted independently, then XORed with the preceding ciphertext + * block (or the IV for the first). + */ + +#include "internal/deprecated.h" + +#include +#include "internal/cryptlib.h" +#include +#include "crypto/modes.h" +#include "crypto/aes_platform.h" + +#if VAES512_ELIGIBLE + +#include +#include +#include + +/* Function prototypes */ +void ossl_aes_ctr_vaes(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *counter, + unsigned char *ecount_buf, unsigned int *num); +int ossl_aes_ctr_vaes_eligible(void); +void ossl_aes_cbc_vaes_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int enc); +int ossl_aes_cbc_vaes_eligible(void); + +/* Forward declarations — defined in aesni-x86_64.pl assembly */ +void aesni_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key); +void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec, int enc); +void aesni_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +/* + * Keep the cleanup out of line in assembly. Its opacity to C and LTO + * optimizers is what prevents the cleanup call and stores from being + * eliminated as dead. Do not replace it with a compiler-visible C function. + */ +void ossl_aes_vaes_cleanup(void *key_schedule, size_t num_keys); +int ossl_aes_vaes_cleanup_eligible(void); + +/* Portable compiler abstractions for inlining and ISA target selection */ +#define OSSL_VAES512_STRINGIFY_IMPL_(a) #a +#define OSSL_VAES512_STRINGIFY_(a) OSSL_VAES512_STRINGIFY_IMPL_(a) + +#ifdef __clang__ +#define OPENSSL_TARGET_VAES512 \ + _Pragma(OSSL_VAES512_STRINGIFY_(clang attribute push( \ + __attribute__((target("avx512f,avx512dq,avx512bw,vaes,aes"))), \ + apply_to = function))) +#define OPENSSL_UNTARGET_VAES512 _Pragma("clang attribute pop") +#elif defined(__GNUC__) +#define OPENSSL_TARGET_VAES512 \ + _Pragma("GCC push_options") \ + _Pragma(OSSL_VAES512_STRINGIFY_(GCC target("avx512f,avx512dq,avx512bw,vaes,aes"))) +#define OPENSSL_UNTARGET_VAES512 _Pragma("GCC pop_options") +#else +/* MSVC: all intrinsics are always available via . */ +#define OPENSSL_TARGET_VAES512 +#define OPENSSL_UNTARGET_VAES512 +#endif + +#if defined(__GNUC__) || defined(__clang__) +#define OSSL_FUNC_ALWAYS_INLINE static inline __attribute__((always_inline)) +#define OSSL_FUNC_NOINLINE __attribute__((noinline)) +#elif defined(_MSC_VER) +#define OSSL_FUNC_ALWAYS_INLINE static __forceinline +#define OSSL_FUNC_NOINLINE __declspec(noinline) +#else +#define OSSL_FUNC_ALWAYS_INLINE static inline +#define OSSL_FUNC_NOINLINE +#endif + +/* + * Runtime CPU capability check shared by all VAES-512 mode helpers. + * Uses only OPENSSL_ia32cap_P bit tests, so it requires no special ISA + * target and is safe to define outside an OPENSSL_TARGET_VAES512 region. + */ +static ossl_inline int ossl_vaes512_cpu_capable(void) +{ + return (OPENSSL_ia32cap_P[2] & (1 << 16)) /* AVX512F */ + && (OPENSSL_ia32cap_P[2] & (1 << 17)) /* AVX512DQ */ + && (OPENSSL_ia32cap_P[2] & (1 << 30)) /* AVX512BW */ + && (OPENSSL_ia32cap_P[3] & (1 << 9)); /* AVX512VAES */ +} + +/* + * Emit the 1x/2x/4x parallel 512-bit AES round functions for a given round + * count. TAG names the generated functions (e.g. AesEnc, AesDec); AESOP and + * AESLAST select the middle-round and last-round intrinsics (encrypt vs + * decrypt). Each __m512i packs four independent 128-bit AES blocks, and + * always_inline keeps the round keys resident in ZMM registers. + * + * Must be expanded inside an OPENSSL_TARGET_VAES512 region. + */ +#define OSSL_VAES512_DEFINE_ROUNDS(TAG, ROUNDS, AESOP, AESLAST) \ + OSSL_FUNC_ALWAYS_INLINE \ + void TAG##_4x512_##ROUNDS( \ + __m512i *b1, __m512i *b2, __m512i *b3, __m512i *b4, \ + const __m512i *rk) \ + { \ + *b1 = _mm512_xor_si512(*b1, rk[0]); \ + *b2 = _mm512_xor_si512(*b2, rk[0]); \ + *b3 = _mm512_xor_si512(*b3, rk[0]); \ + *b4 = _mm512_xor_si512(*b4, rk[0]); \ + for (int i = 1; i < ROUNDS; i++) { \ + *b1 = AESOP(*b1, rk[i]); \ + *b2 = AESOP(*b2, rk[i]); \ + *b3 = AESOP(*b3, rk[i]); \ + *b4 = AESOP(*b4, rk[i]); \ + } \ + *b1 = AESLAST(*b1, rk[ROUNDS]); \ + *b2 = AESLAST(*b2, rk[ROUNDS]); \ + *b3 = AESLAST(*b3, rk[ROUNDS]); \ + *b4 = AESLAST(*b4, rk[ROUNDS]); \ + } \ + \ + OSSL_FUNC_ALWAYS_INLINE \ + void TAG##_2x512_##ROUNDS( \ + __m512i *b1, __m512i *b2, const __m512i *rk) \ + { \ + *b1 = _mm512_xor_si512(*b1, rk[0]); \ + *b2 = _mm512_xor_si512(*b2, rk[0]); \ + for (int i = 1; i < ROUNDS; i++) { \ + *b1 = AESOP(*b1, rk[i]); \ + *b2 = AESOP(*b2, rk[i]); \ + } \ + *b1 = AESLAST(*b1, rk[ROUNDS]); \ + *b2 = AESLAST(*b2, rk[ROUNDS]); \ + } \ + \ + OSSL_FUNC_ALWAYS_INLINE \ + void TAG##_1x512_##ROUNDS( \ + __m512i *b1, const __m512i *rk) \ + { \ + *b1 = _mm512_xor_si512(*b1, rk[0]); \ + for (int i = 1; i < ROUNDS; i++) \ + *b1 = AESOP(*b1, rk[i]); \ + *b1 = AESLAST(*b1, rk[ROUNDS]); \ + } + +/* Emit the AES encryption round helpers (used by CTR, CFB, GCM, ...). */ +#define OSSL_VAES512_DEFINE_ENCRYPT(ROUNDS) \ + OSSL_VAES512_DEFINE_ROUNDS(AesEnc, ROUNDS, \ + _mm512_aesenc_epi128, _mm512_aesenclast_epi128) + +/* Emit the AES decryption round helpers (used by CBC decrypt). */ +#define OSSL_VAES512_DEFINE_DECRYPT(ROUNDS) \ + OSSL_VAES512_DEFINE_ROUNDS(AesDec, ROUNDS, \ + _mm512_aesdec_epi128, _mm512_aesdeclast_epi128) + +/* + * Broadcast-load the AES round-key schedule into an array of ZMM registers, + * replicating each 128-bit round key across all four lanes. key is an + * AES_KEY *, rk an array of at least NR+1 __m512i. + * + * Must be expanded inside an OPENSSL_TARGET_VAES512 region. + */ +#define OSSL_VAES512_LOAD_ROUNDKEYS(rk, key, NR) \ + do { \ + const unsigned char *rk_bytes_ = (const unsigned char *)(key)->rd_key; \ + for (int i_ = 0; i_ <= (NR); i_++) { \ + __m128i t_ = _mm_loadu_si128( \ + (const __m128i *)(rk_bytes_ + i_ * 16)); \ + (rk)[i_] = _mm512_broadcast_i32x4(t_); \ + } \ + } while (0) + +OPENSSL_TARGET_VAES512 + +/* AES encryption round helpers (1x/2x/4x parallel 512-bit blocks). */ +OSSL_VAES512_DEFINE_ENCRYPT(10) /* AES-128 */ +OSSL_VAES512_DEFINE_ENCRYPT(12) /* AES-192 */ +OSSL_VAES512_DEFINE_ENCRYPT(14) /* AES-256 */ + +/*- + * Counter initialisation. + * + * Counters are kept in little-endian form (full 128-bit byte swap) and + * incremented with 64-bit arithmetic. This is safe for all practical + * counter values — encrypting data less than 2^68 bytes. + */ +static inline __m512i ctr_swap_mask(void) +{ + return _mm512_set_epi32(0x00010203, 0x04050607, + 0x08090a0b, 0x0c0d0e0f, + 0x00010203, 0x04050607, + 0x08090a0b, 0x0c0d0e0f, + 0x00010203, 0x04050607, + 0x08090a0b, 0x0c0d0e0f, + 0x00010203, 0x04050607, + 0x08090a0b, 0x0c0d0e0f); +} + +static inline __m512i ctr_init4(const unsigned char *iv, __m512i swap) +{ + /* unaligned 128-bit load for iv and broadcast */ + __m128i iv128 = _mm_loadu_si128((const __m128i *)iv); + __m512i c = _mm512_broadcast_i64x2(iv128); + c = _mm512_shuffle_epi8(c, swap); + c = _mm512_add_epi64(c, _mm512_set_epi64(0, 3, 0, 2, 0, 1, 0, 0)); + return c; +} + +/*- + * CTR-mode processing, templated per round count. + * + * Processes as many blocks as possible: + * 16 blocks at a time (4×zmm = 4×4 = 16 blocks) + * 8 blocks at a time (2×zmm) + * 4 blocks at a time (1×zmm) + * 0-3 tail blocks + partial residue via masked load/store + */ +#define DEFINE_CTR_BLOCK(NR) \ + OSSL_FUNC_NOINLINE \ + static void ctr_process_##NR( \ + const unsigned char *in, unsigned char *out, \ + size_t len, const AES_KEY *key, unsigned char *iv) \ + { \ + __m512i rk[NR + 1]; \ + OSSL_VAES512_LOAD_ROUNDKEYS(rk, key, NR); \ + \ + const __m512i *p_in = (const __m512i *)in; \ + __m512i *p_out = (__m512i *)out; \ + __m512i swap = ctr_swap_mask(); \ + __m512i c1 = ctr_init4(iv, swap); \ + \ + __m512i a1, a2, a3, a4; \ + __m512i b1, b2, b3, b4; \ + __m512i c2, c3, c4; \ + \ + size_t blocks = len / AES_BLOCK_SIZE; \ + size_t res = len % AES_BLOCK_SIZE; \ + \ + const __m512i inc4 = _mm512_set_epi64(0, 4, 0, 4, 0, 4, 0, 4); \ + const __m512i inc8 = _mm512_set_epi64(0, 8, 0, 8, 0, 8, 0, 8); \ + const __m512i inc12 = _mm512_set_epi64(0, 12, 0, 12, 0, 12, 0, 12); \ + const __m512i inc16 = _mm512_set_epi64(0, 16, 0, 16, 0, 16, 0, 16); \ + \ + /* --- 16-block (4×zmm) main loop --- */ \ + while (blocks >= 16) { \ + c2 = _mm512_add_epi64(c1, inc4); \ + c3 = _mm512_add_epi64(c1, inc8); \ + c4 = _mm512_add_epi64(c1, inc12); \ + \ + a1 = _mm512_loadu_si512(p_in); \ + a2 = _mm512_loadu_si512(p_in + 1); \ + a3 = _mm512_loadu_si512(p_in + 2); \ + a4 = _mm512_loadu_si512(p_in + 3); \ + \ + b1 = _mm512_shuffle_epi8(c1, swap); \ + b2 = _mm512_shuffle_epi8(c2, swap); \ + b3 = _mm512_shuffle_epi8(c3, swap); \ + b4 = _mm512_shuffle_epi8(c4, swap); \ + \ + AesEnc_4x512_##NR(&b1, &b2, &b3, &b4, rk); \ + \ + _mm512_storeu_si512(p_out, _mm512_xor_si512(b1, a1)); \ + _mm512_storeu_si512(p_out + 1, _mm512_xor_si512(b2, a2)); \ + _mm512_storeu_si512(p_out + 2, _mm512_xor_si512(b3, a3)); \ + _mm512_storeu_si512(p_out + 3, _mm512_xor_si512(b4, a4)); \ + \ + c1 = _mm512_add_epi64(c1, inc16); \ + p_in += 4; \ + p_out += 4; \ + blocks -= 16; \ + } \ + \ + /* --- 8-block (2×zmm) --- */ \ + if (blocks >= 8) { \ + c2 = _mm512_add_epi64(c1, inc4); \ + \ + a1 = _mm512_loadu_si512(p_in); \ + a2 = _mm512_loadu_si512(p_in + 1); \ + \ + b1 = _mm512_shuffle_epi8(c1, swap); \ + b2 = _mm512_shuffle_epi8(c2, swap); \ + \ + AesEnc_2x512_##NR(&b1, &b2, rk); \ + \ + _mm512_storeu_si512(p_out, _mm512_xor_si512(b1, a1)); \ + _mm512_storeu_si512(p_out + 1, _mm512_xor_si512(b2, a2)); \ + \ + c1 = _mm512_add_epi64(c1, inc8); \ + p_in += 2; \ + p_out += 2; \ + blocks -= 8; \ + } \ + \ + /* --- 4-block (1×zmm) --- */ \ + if (blocks >= 4) { \ + a1 = _mm512_loadu_si512(p_in); \ + b1 = _mm512_shuffle_epi8(c1, swap); \ + AesEnc_1x512_##NR(&b1, rk); \ + _mm512_storeu_si512(p_out, _mm512_xor_si512(b1, a1)); \ + \ + c1 = _mm512_add_epi64(c1, inc4); \ + p_in += 1; \ + p_out += 1; \ + blocks -= 4; \ + } \ + \ + /* --- Tail: 0-3 full blocks + residue partial block --- */ \ + { \ + size_t tail_bytes = (blocks * AES_BLOCK_SIZE) + res; \ + if (tail_bytes > 0) { \ + __mmask64 mask = (__mmask64)((1ULL << tail_bytes) - 1ULL); \ + a1 = _mm512_maskz_loadu_epi8(mask, p_in); \ + b1 = _mm512_shuffle_epi8(c1, swap); \ + AesEnc_1x512_##NR(&b1, rk); \ + _mm512_mask_storeu_epi8(p_out, mask, _mm512_xor_si512(b1, a1)); \ + \ + size_t adv = blocks + (res > 0 ? 1 : 0); \ + __m512i one_lo = _mm512_set_epi64(0, 0, 0, 0, 0, 0, 0, 1); \ + for (size_t i = 0; i < adv; i++) \ + c1 = _mm512_add_epi64(c1, one_lo); \ + } \ + } \ + \ + /* Write back updated counter (lane 0 only, byte-swapped to BE) */ \ + { \ + __m512i c_be = _mm512_shuffle_epi8(c1, swap); \ + _mm512_mask_storeu_epi64((__m128i *)iv, 0x03, c_be); \ + } \ + \ + /* Erase the broadcast schedule and the volatile vector register bank. */ \ + ossl_aes_vaes_cleanup(rk, NR + 1); \ + } + +DEFINE_CTR_BLOCK(10) /* AES-128 */ +DEFINE_CTR_BLOCK(12) /* AES-192 */ +DEFINE_CTR_BLOCK(14) /* AES-256 */ + +/* Public entry point. */ +void ossl_aes_ctr_vaes(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *counter, + unsigned char *ecount_buf, unsigned int *num) +{ + size_t n = *num; + size_t l = length; + int nr = key->rounds + 1; + + /* Drain leftover bytes from a previous partial block */ + if (n != 0) { + while (l > 0 && n < 16) { + *(out++) = *(in++) ^ ecount_buf[n]; + ++n; + l--; + } + *num = n % 16; + if (l == 0) + return; + } + + /* Process full 16-byte blocks with VAES. + * + * The VAES loop uses 64-bit counter arithmetic (no carry into the + * upper 64 bits). If processing all requested blocks would overflow + * the low 64 bits of the BE counter: + * Phase 1 — VAES processes the safe blocks before the boundary. + * Phase 2 — Scalar handles 1 block to cross the 64-bit carry. + * Phase 3 — VAES resumes for the remaining bulk (>= 512 bytes), + * since the counter low-64 is now near zero and safe. + * Any final partial block is always handled by the scalar path. + */ + { + size_t block_bytes = (l / 16) * 16; + if (block_bytes > 0) { + size_t total_blocks = block_bytes / 16; + /* Read low 64 bits of the big-endian counter (bytes 8..15) */ + uint64_t ctr_lo = ((uint64_t)counter[8] << 56) + | ((uint64_t)counter[9] << 48) + | ((uint64_t)counter[10] << 40) + | ((uint64_t)counter[11] << 32) + | ((uint64_t)counter[12] << 24) + | ((uint64_t)counter[13] << 16) + | ((uint64_t)counter[14] << 8) + | ((uint64_t)counter[15]); + + /* Clamp to the number of blocks safe for 64-bit arithmetic */ + size_t safe_blocks = (ctr_lo <= UINT64_MAX - total_blocks) + ? total_blocks + : (size_t)(UINT64_MAX - ctr_lo); + size_t safe_bytes = safe_blocks * 16; + + /* Phase 1: VAES for the safe portion before the boundary */ + if (safe_bytes > 0) { + switch (nr) { + case 10: + ctr_process_10(in, out, safe_bytes, key, counter); + break; + case 12: + ctr_process_12(in, out, safe_bytes, key, counter); + break; + case 14: + ctr_process_14(in, out, safe_bytes, key, counter); + break; + default: /* invalid key size */ + CRYPTO_ctr128_encrypt(in, out, safe_bytes, key, counter, + ecount_buf, num, + (block128_f)aesni_encrypt); + break; + } + in += safe_bytes; + out += safe_bytes; + l -= safe_bytes; + } + + /* Phase 2 & 3: only entered when clamping actually occurred */ + if (safe_blocks < total_blocks && l > 0) { + /* Phase 2: scalar encrypts 1 block across the carry */ + CRYPTO_ctr128_encrypt(in, out, 16, key, counter, + ecount_buf, num, + (block128_f)aesni_encrypt); + in += 16; + out += 16; + l -= 16; + + /* Phase 3: counter low-64 is now ~0 — VAES is safe again. + * Resume VAES if enough data remains (>= 512 bytes). */ + if (l >= 512) { + size_t resume_bytes = (l / 16) * 16; + switch (nr) { + case 10: + ctr_process_10(in, out, resume_bytes, key, counter); + break; + case 12: + ctr_process_12(in, out, resume_bytes, key, counter); + break; + case 14: + ctr_process_14(in, out, resume_bytes, key, counter); + break; + default: /* invalid key size */ + CRYPTO_ctr128_encrypt(in, out, resume_bytes, key, + counter, ecount_buf, num, + (block128_f)aesni_encrypt); + break; + } + in += resume_bytes; + out += resume_bytes; + l -= resume_bytes; + } + } + } + } + + /* Handle any remaining bytes (partial block or small tail) */ + if (l > 0) + CRYPTO_ctr128_encrypt(in, out, l, key, counter, + ecount_buf, num, (block128_f)aesni_encrypt); + else + *num = 0; +} + +/* CPU feature check. */ +int ossl_aes_ctr_vaes_eligible(void) +{ + return ossl_aes_vaes_cleanup_eligible() + && ossl_vaes512_cpu_capable(); +} + +/* AES decryption round helpers (1x/2x/4x parallel 512-bit blocks). */ +OSSL_VAES512_DEFINE_DECRYPT(10) /* AES-128 */ +OSSL_VAES512_DEFINE_DECRYPT(12) /* AES-192 */ +OSSL_VAES512_DEFINE_DECRYPT(14) /* AES-256 */ + +/*- + * CBC-mode decryption -- templated per round count. + * + * Processes as many full blocks as possible: + * 16 blocks at a time (4 x zmm = 4 x 4 = 16 blocks) + * 8 blocks at a time (2 x zmm) + * 4 blocks at a time (1 x zmm) + * 1 block at a time for the remaining 0-3 blocks + * + * The chaining vector b1 packs [prev_ct[last] | ct[0] | ct[1] | ct[2]] so + * that a single XOR after decryption applies the CBC feedback to all four + * lanes simultaneously. + */ +#define DEFINE_CBC_DECRYPT(NR) \ + OSSL_FUNC_NOINLINE \ + static void cbc_decrypt_##NR( \ + const unsigned char *in, unsigned char *out, size_t len, \ + const AES_KEY *key, unsigned char *iv) \ + { \ + __m512i rk[NR + 1]; \ + OSSL_VAES512_LOAD_ROUNDKEYS(rk, key, NR); \ + \ + __m512i a1, a2, a3, a4; \ + __m512i b1, b2, b3, b4; \ + \ + const __m128i *pa = (const __m128i *)in; \ + __m512i *po = (__m512i *)out; \ + size_t blocks = len / AES_BLOCK_SIZE; \ + \ + /* Save last ciphertext block for IV update (in-place safe) */ \ + __m128i saved_iv = _mm_setzero_si128(); \ + int has_blocks = (blocks > 0); \ + if (has_blocks) \ + saved_iv = _mm_loadu_si128(pa + blocks - 1); \ + \ + if (blocks >= 4) { \ + /* Build b1 = [IV | ct[0] | ct[1] | ct[2]] */ \ + __m512i idx = _mm512_set_epi64(5, 4, 3, 2, 1, 0, 0, 0); \ + __m512i ct0; \ + \ + /* CBC C[0]=IV; 0x03 loads one 128-bit block (two 64-bit lanes). */ \ + b1 = _mm512_maskz_loadu_epi64(0x03, iv); \ + ct0 = _mm512_loadu_si512(pa); \ + ct0 = _mm512_permutexvar_epi64(idx, ct0); \ + b1 = _mm512_mask_blend_epi64(0xFC, b1, ct0); \ + \ + /* --- 16-block (4 x zmm) main loop --- */ \ + while (blocks >= 16) { \ + __m128i last; \ + \ + a1 = _mm512_loadu_si512(pa); \ + a2 = _mm512_loadu_si512(pa + 4); \ + a3 = _mm512_loadu_si512(pa + 8); \ + a4 = _mm512_loadu_si512(pa + 12); \ + \ + b2 = _mm512_loadu_si512(pa + 3); \ + b3 = _mm512_loadu_si512(pa + 7); \ + b4 = _mm512_loadu_si512(pa + 11); \ + \ + last = _mm_loadu_si128(pa + 15); \ + \ + AesDec_4x512_##NR(&a1, &a2, &a3, &a4, rk); \ + \ + a1 = _mm512_xor_si512(a1, b1); \ + a2 = _mm512_xor_si512(a2, b2); \ + a3 = _mm512_xor_si512(a3, b3); \ + a4 = _mm512_xor_si512(a4, b4); \ + \ + _mm512_storeu_si512(po, a1); \ + _mm512_storeu_si512(po + 1, a2); \ + _mm512_storeu_si512(po + 2, a3); \ + _mm512_storeu_si512(po + 3, a4); \ + \ + /* Build next b1 from last ciphertext block */ \ + b1 = _mm512_maskz_loadu_epi64(0x03, &last); \ + if (blocks > 16) { \ + size_t rem = blocks - 16; \ + /* Load only available lookahead blocks to avoid OOB read. */ \ + /* One AES block is 16 bytes, it maps to two 64-bit lanes. */ \ + /* 0x03 (00000011) for 1 block (2 lanes), */ \ + /* 0x0F (00001111) for 2 blocks (4 lanes), */ \ + /* 0x3F (00111111) for 3 or more blocks (6 lanes). */ \ + __mmask8 nxmask = (rem >= 3) ? 0x3F : (rem == 2 ? 0x0F : 0x03); \ + __m512i nx = _mm512_maskz_loadu_epi64(nxmask, pa + 16); \ + nx = _mm512_permutexvar_epi64(idx, nx); \ + b1 = _mm512_mask_blend_epi64(0xFC, b1, nx); \ + } \ + \ + pa += 16; \ + po += 4; \ + blocks -= 16; \ + } \ + \ + /* --- 8-block (2 x zmm) --- */ \ + if (blocks >= 8) { \ + __m128i last8; \ + \ + a1 = _mm512_loadu_si512(pa); \ + a2 = _mm512_loadu_si512(pa + 4); \ + b2 = _mm512_loadu_si512(pa + 3); \ + last8 = _mm_loadu_si128(pa + 7); \ + \ + AesDec_2x512_##NR(&a1, &a2, rk); \ + a1 = _mm512_xor_si512(a1, b1); \ + a2 = _mm512_xor_si512(a2, b2); \ + \ + _mm512_storeu_si512(po, a1); \ + _mm512_storeu_si512(po + 1, a2); \ + \ + b1 = _mm512_maskz_loadu_epi64(0x03, &last8); \ + pa += 8; \ + po += 2; \ + blocks -= 8; \ + \ + if (blocks >= 4) { \ + __m512i nx = _mm512_loadu_si512(pa); \ + nx = _mm512_permutexvar_epi64(idx, nx); \ + b1 = _mm512_mask_blend_epi64(0xFC, b1, nx); \ + } \ + } \ + \ + /* --- 4-block (1 x zmm) --- */ \ + if (blocks >= 4) { \ + __m128i last4; \ + \ + a1 = _mm512_loadu_si512(pa); \ + last4 = _mm_loadu_si128(pa + 3); \ + \ + AesDec_1x512_##NR(&a1, rk); \ + a1 = _mm512_xor_si512(a1, b1); \ + _mm512_storeu_si512(po, a1); \ + \ + b1 = _mm512_maskz_loadu_epi64(0x03, &last4); \ + pa += 4; \ + po += 1; \ + blocks -= 4; \ + } \ + \ + /* --- Remaining 1-3 blocks --- */ \ + { \ + __m128i *po128 = (__m128i *)po; \ + while (blocks > 0) { \ + __m128i ct = _mm_loadu_si128(pa); \ + a1 = _mm512_maskz_loadu_epi64(0x03, pa); \ + AesDec_1x512_##NR(&a1, rk); \ + a1 = _mm512_xor_si512(a1, b1); \ + _mm512_mask_storeu_epi64(po128, 0x03, a1); \ + b1 = _mm512_maskz_loadu_epi64(0x03, &ct); \ + pa++; \ + po128++; \ + blocks--; \ + } \ + } \ + } else { \ + /* Less than 4 blocks -- process individually */ \ + __m128i *po128 = (__m128i *)po; \ + b1 = _mm512_maskz_loadu_epi64(0x03, iv); \ + while (blocks > 0) { \ + __m128i ct = _mm_loadu_si128(pa); \ + a1 = _mm512_maskz_loadu_epi64(0x03, pa); \ + AesDec_1x512_##NR(&a1, rk); \ + a1 = _mm512_xor_si512(a1, b1); \ + _mm512_mask_storeu_epi64(po128, 0x03, a1); \ + b1 = _mm512_maskz_loadu_epi64(0x03, &ct); \ + pa++; \ + po128++; \ + blocks--; \ + } \ + } \ + \ + if (has_blocks) \ + _mm_storeu_si128((__m128i *)iv, saved_iv); \ + \ + /* Erase the broadcast schedule and the volatile vector register bank. */ \ + ossl_aes_vaes_cleanup(rk, NR + 1); \ + } + +DEFINE_CBC_DECRYPT(10) /* AES-128 */ +DEFINE_CBC_DECRYPT(12) /* AES-192 */ +DEFINE_CBC_DECRYPT(14) /* AES-256 */ + +/* Public entry point. */ +void ossl_aes_cbc_vaes_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int enc) +{ + size_t full_bytes; + int nr = ((const AES_KEY *)key)->rounds + 1; + + if (len == 0) + return; + + /* VAES path only optimises decryption; encrypt falls back to asm */ + if (enc) { + aesni_cbc_encrypt(in, out, len, (const AES_KEY *)key, ivec, enc); + return; + } + + full_bytes = (len / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; + if (full_bytes > 0) { + switch (nr) { + case 10: + cbc_decrypt_10(in, out, full_bytes, (const AES_KEY *)key, ivec); + break; + case 12: + cbc_decrypt_12(in, out, full_bytes, (const AES_KEY *)key, ivec); + break; + case 14: + cbc_decrypt_14(in, out, full_bytes, (const AES_KEY *)key, ivec); + break; + default: /* invalid key size */ + aesni_cbc_encrypt(in, out, len, (const AES_KEY *)key, ivec, 0); + break; + } + } +} + +/* CPU feature check. */ +int ossl_aes_cbc_vaes_eligible(void) +{ + return ossl_aes_vaes_cleanup_eligible() + && ossl_vaes512_cpu_capable(); +} + +OPENSSL_UNTARGET_VAES512 + +#endif /* VAES512_ELIGIBLE */ diff --git a/crypto/aes/asm/aes-armv4.pl b/crypto/aes/asm/aes-armv4.pl index 641e45144eac2..a1c3397cb9dfc 100644 --- a/crypto/aes/asm/aes-armv4.pl +++ b/crypto/aes/asm/aes-armv4.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/asm/aes-cfb-avx512.pl b/crypto/aes/asm/aes-cfb-avx512.pl index d9e1815ee69c0..3a1b512c21426 100644 --- a/crypto/aes/asm/aes-cfb-avx512.pl +++ b/crypto/aes/asm/aes-cfb-avx512.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2025, Intel Corporation. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/aes/asm/aes-mips.pl b/crypto/aes/asm/aes-mips.pl index 28ca4d028b965..c58b76f0ea6ab 100644 --- a/crypto/aes/asm/aes-mips.pl +++ b/crypto/aes/asm/aes-mips.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2010-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2010-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/asm/aes-riscv32-zkn.pl b/crypto/aes/asm/aes-riscv32-zkn.pl index b57e10c485d6f..ed8f4a7f83aa4 100644 --- a/crypto/aes/asm/aes-riscv32-zkn.pl +++ b/crypto/aes/asm/aes-riscv32-zkn.pl @@ -2,7 +2,7 @@ # This file is dual-licensed, meaning that you can use it under your # choice of either of the following two licenses: # -# Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You can obtain # a copy in the file LICENSE in the source distribution or at diff --git a/crypto/aes/asm/aes-riscv64-zkn.pl b/crypto/aes/asm/aes-riscv64-zkn.pl index 34f71b2185011..68c213e43e349 100644 --- a/crypto/aes/asm/aes-riscv64-zkn.pl +++ b/crypto/aes/asm/aes-riscv64-zkn.pl @@ -2,7 +2,7 @@ # This file is dual-licensed, meaning that you can use it under your # choice of either of the following two licenses: # -# Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You can obtain # a copy in the file LICENSE in the source distribution or at diff --git a/crypto/aes/asm/aes-riscv64-zvkned.pl b/crypto/aes/asm/aes-riscv64-zvkned.pl index 45c2efde07647..f057b53ccf304 100644 --- a/crypto/aes/asm/aes-riscv64-zvkned.pl +++ b/crypto/aes/asm/aes-riscv64-zvkned.pl @@ -2,7 +2,7 @@ # This file is dual-licensed, meaning that you can use it under your # choice of either of the following two licenses: # -# Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You can obtain # a copy in the file LICENSE in the source distribution or at diff --git a/crypto/aes/asm/aes-riscv64.pl b/crypto/aes/asm/aes-riscv64.pl index 9c864dc6d8e1c..4bf9edae6858f 100644 --- a/crypto/aes/asm/aes-riscv64.pl +++ b/crypto/aes/asm/aes-riscv64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/asm/aes-s390x.pl b/crypto/aes/asm/aes-s390x.pl index 66529ad732f50..04a7a1cf616a7 100644 --- a/crypto/aes/asm/aes-s390x.pl +++ b/crypto/aes/asm/aes-s390x.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/asm/aes-sha1-armv8.pl b/crypto/aes/asm/aes-sha1-armv8.pl index 8f121274e98fb..65ee03a59f4dd 100644 --- a/crypto/aes/asm/aes-sha1-armv8.pl +++ b/crypto/aes/asm/aes-sha1-armv8.pl @@ -1,6 +1,6 @@ #! /usr/bin/env perl -# Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (C) Cavium networks Ltd. 2016. # # Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/aes/asm/aes-sha256-armv8.pl b/crypto/aes/asm/aes-sha256-armv8.pl index 9e403c3abfd46..51eba2e1adf5a 100644 --- a/crypto/aes/asm/aes-sha256-armv8.pl +++ b/crypto/aes/asm/aes-sha256-armv8.pl @@ -1,6 +1,6 @@ #! /usr/bin/env perl -# Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (C) Cavium networks Ltd. 2016. # # Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/aes/asm/aes-sha512-armv8.pl b/crypto/aes/asm/aes-sha512-armv8.pl index bae8f31c446ef..7d5385bbffcd7 100644 --- a/crypto/aes/asm/aes-sha512-armv8.pl +++ b/crypto/aes/asm/aes-sha512-armv8.pl @@ -1,6 +1,6 @@ #! /usr/bin/env perl -# Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/asm/aes-sparcv9.pl b/crypto/aes/asm/aes-sparcv9.pl index 9fbe7c7a7486e..26703760fb50c 100755 --- a/crypto/aes/asm/aes-sparcv9.pl +++ b/crypto/aes/asm/aes-sparcv9.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/asm/aes-vaes-x86_64.pl b/crypto/aes/asm/aes-vaes-x86_64.pl new file mode 100644 index 0000000000000..772c47924dde5 --- /dev/null +++ b/crypto/aes/asm/aes-vaes-x86_64.pl @@ -0,0 +1,184 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# Erase the temporary broadcast key schedule used by the AES VAES +# intrinsic implementations and clear their caller-clobbered register state. + +$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef; +$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef; + +$win64 = 0; +$win64 = 1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$avx512vaes = 0; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; +$dir = $1; +($xlate = "${dir}x86_64-xlate.pl" and -f $xlate) + or ($xlate = "${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) + or die "can't locate x86_64-xlate.pl"; + +if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` + =~ /GNU assembler version ([2-9]\.[0-9]+)/) { + $avx512vaes = ($1 >= 2.30); +} + +if (!$avx512vaes && $win64 + && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) + && `nasm -v 2>&1` + =~ /NASM version ([2-9]\.[0-9]+)(?:\.([0-9]+))?/) { + $avx512vaes = ($1 == 2.13 && $2 >= 3) + ($1 >= 2.14); +} + +if (!$avx512vaes && $win64 + && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) + && `ml64 2>&1` =~ /Version ([0-9]+\.[0-9]+)\./) { + $avx512vaes = ($1 >= 14.16); +} + +if (!$avx512vaes && `$ENV{CC} -v 2>&1` + =~ /(Apple)?\s*((?:clang|LLVM) version|.*based on LLVM) ([0-9]+)\.([0-9]+)\.([0-9]+)?/) { + $ver = $3 + $4 / 100.0 + $5 / 10000.0; + if ($1) { + $avx512vaes = ($ver >= 10.0001); + } else { + $avx512vaes = ($ver >= 7.0); + } +} + +if (!$avx512vaes && `$ENV{CC} -x c /dev/null -dM -E 2>/dev/null` + =~ /#define __clang_major__\s+([0-9]+)/) { + $avx512vaes = ($1 >= 11); # icx started with clang 11 +} + +open OUT, "| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; +*STDOUT = *OUT; + +$key_schedule = $win64 ? "%rcx" : "%rdi"; +$num_keys = $win64 ? "%rdx" : "%rsi"; + +$code = <<___; +.text + +.globl ossl_aes_vaes_cleanup_eligible +.hidden ossl_aes_vaes_cleanup_eligible +.type ossl_aes_vaes_cleanup_eligible,\@abi-omnipotent +.align 16 +ossl_aes_vaes_cleanup_eligible: +.cfi_startproc + endbranch +___ + +if ($avx512vaes) { + $code .= <<___; + mov \$1,%eax + ret +.cfi_endproc +.size ossl_aes_vaes_cleanup_eligible,.-ossl_aes_vaes_cleanup_eligible + +# void ossl_aes_vaes_cleanup(void *key_schedule, size_t num_keys); +# +# num_keys counts 64-byte broadcast round keys. The caller invokes this only +# after VAES use, so AVX-512 instructions are already safe to execute. +# On Win64, the caller's epilogue restores the ABI-preserved low 128 bits of +# XMM6-XMM15 if it used them. Their volatile upper lanes are cleared here. +.globl ossl_aes_vaes_cleanup +.hidden ossl_aes_vaes_cleanup +.type ossl_aes_vaes_cleanup,\@abi-omnipotent +.align 32 +ossl_aes_vaes_cleanup: +.cfi_startproc + endbranch + vpxord %zmm0,%zmm0,%zmm0 + test $num_keys,$num_keys + jz .Lvaes_clear_registers + +.Lvaes_clear_keys: + vmovdqu64 %zmm0,($key_schedule) + add \$64,$key_schedule + dec $num_keys + jnz .Lvaes_clear_keys + +.Lvaes_clear_registers: +___ + + if ($win64) { + $code .= <<___; + # The low 128 bits of XMM6-XMM15 are nonvolatile on Win64. Preserve + # them, while clearing all of ZMM0-ZMM5 here. +___ + for ($i = 0; $i <= 5; $i++) { + $code .= " vpxor %xmm$i,%xmm$i,%xmm$i\n"; + } + } + + for ($i = 16; $i <= 31; $i++) { + $code .= " vpxord %zmm$i,%zmm$i,%zmm$i\n"; + } + + if ($win64) { + $code .= <<___; + # Clear the volatile upper lanes of ZMM6-ZMM15 last. + vzeroupper + + # Clear the Win64 volatile general-purpose registers used by the caller. + xor %eax,%eax + xor %ecx,%ecx + xor %edx,%edx + xor %r8d,%r8d + xor %r9d,%r9d + xor %r10d,%r10d + xor %r11d,%r11d +___ + } else { + $code .= <<___; + # VZEROALL clears ZMM0-ZMM15, but does not affect ZMM16-ZMM31. + vzeroall + + # Clear the SysV volatile general-purpose registers used by the caller. + xor %eax,%eax + xor %ecx,%ecx + xor %edx,%edx + xor %esi,%esi + xor %edi,%edi + xor %r8d,%r8d + xor %r9d,%r9d + xor %r10d,%r10d + xor %r11d,%r11d +___ + } + + $code .= <<___; + ret +.cfi_endproc +.size ossl_aes_vaes_cleanup,.-ossl_aes_vaes_cleanup +___ +} else { + $code .= <<___; + xor %eax,%eax + ret +.cfi_endproc +.size ossl_aes_vaes_cleanup_eligible,.-ossl_aes_vaes_cleanup_eligible + +.globl ossl_aes_vaes_cleanup +.hidden ossl_aes_vaes_cleanup +.type ossl_aes_vaes_cleanup,\@abi-omnipotent +ossl_aes_vaes_cleanup: +.cfi_startproc + endbranch + .byte 0x0f,0x0b # ud2 + ret +.cfi_endproc +.size ossl_aes_vaes_cleanup,.-ossl_aes_vaes_cleanup +___ +} + +print $code; + +close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/aes/asm/aesfx-sparcv9.pl b/crypto/aes/asm/aesfx-sparcv9.pl index d19efa2f928f3..b02ebb2cb596e 100644 --- a/crypto/aes/asm/aesfx-sparcv9.pl +++ b/crypto/aes/asm/aesfx-sparcv9.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/asm/aesni-mb-x86_64.pl b/crypto/aes/asm/aesni-mb-x86_64.pl index 154f1bc70f1b4..ee425eea00f21 100644 --- a/crypto/aes/asm/aesni-mb-x86_64.pl +++ b/crypto/aes/asm/aesni-mb-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2013-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2013-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/asm/aesni-sha1-x86_64.pl b/crypto/aes/asm/aesni-sha1-x86_64.pl index 003c0e971662f..b2c6c71a6fb59 100644 --- a/crypto/aes/asm/aesni-sha1-x86_64.pl +++ b/crypto/aes/asm/aesni-sha1-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/asm/aesni-sha256-x86_64.pl b/crypto/aes/asm/aesni-sha256-x86_64.pl index aecd6e7b40cd3..fbf203489fbfd 100644 --- a/crypto/aes/asm/aesni-sha256-x86_64.pl +++ b/crypto/aes/asm/aesni-sha256-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2013-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2013-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/asm/aest4-sparcv9.pl b/crypto/aes/asm/aest4-sparcv9.pl index d867db183b16c..877d83ad94def 100644 --- a/crypto/aes/asm/aest4-sparcv9.pl +++ b/crypto/aes/asm/aest4-sparcv9.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2012-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2012-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/asm/aesv8-armx.pl b/crypto/aes/asm/aesv8-armx.pl index a9e272a91c056..1516ba115e6e4 100755 --- a/crypto/aes/asm/aesv8-armx.pl +++ b/crypto/aes/asm/aesv8-armx.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2014-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2014-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/asm/bsaes-armv7.pl b/crypto/aes/asm/bsaes-armv7.pl index ff9c2fa3b96e5..86d8cb5b7ce7b 100644 --- a/crypto/aes/asm/bsaes-armv7.pl +++ b/crypto/aes/asm/bsaes-armv7.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2012-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2012-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/asm/bsaes-armv8.pl b/crypto/aes/asm/bsaes-armv8.pl index fa64865ba6d95..6bd0a1e7373e4 100644 --- a/crypto/aes/asm/bsaes-armv8.pl +++ b/crypto/aes/asm/bsaes-armv8.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -32,7 +32,7 @@ sub data } __END__ -// Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved. +// Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. // // Licensed under the OpenSSL license (the "License"). You may not use // this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/asm/vpaes-armv8.pl b/crypto/aes/asm/vpaes-armv8.pl index e9bf163cac40a..cca6460a998d1 100755 --- a/crypto/aes/asm/vpaes-armv8.pl +++ b/crypto/aes/asm/vpaes-armv8.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/aes/build.info b/crypto/aes/build.info index cb3bb5f2deb6b..86640dadbfe1e 100644 --- a/crypto/aes/build.info +++ b/crypto/aes/build.info @@ -10,7 +10,7 @@ IF[{- !$disabled{asm} -}] $AESASM_x86_64=\ aes-x86_64.s vpaes-x86_64.s bsaes-x86_64.s aesni-x86_64.s \ aesni-sha1-x86_64.s aesni-sha256-x86_64.s aesni-mb-x86_64.s \ - aesni-xts-avx512.s aes-cfb-avx512.s + aesni-xts-avx512.s aes-cfb-avx512.s aes-vaes-x86_64.s $AESDEF_x86_64=AES_ASM VPAES_ASM BSAES_ASM $AESASM_ia64=aes_core.c aes_cbc.c aes-ia64.s @@ -74,11 +74,11 @@ IF[{- !$disabled{asm} -}] ENDIF $COMMON=aes_misc.c aes_ecb.c $AESASM -SOURCE[../../libcrypto]=$COMMON aes_cfb.c aes_ofb.c aes_wrap.c +SOURCE[../../libcrypto]=$COMMON aes_cfb.c aes_ofb.c aes_wrap.c aes_vaes512_intrinsics.c IF[{- !$disabled{'deprecated-3.0'} -}] SOURCE[../../libcrypto]=aes_ige.c ENDIF -SOURCE[../../providers/libfips.a]=$COMMON +SOURCE[../../providers/libfips.a]=$COMMON aes_vaes512_intrinsics.c # Implementations are now spread across several libraries, so the defines # need to be applied to all affected libraries and modules. @@ -108,6 +108,7 @@ GENERATE[vpaes-x86_64.s]=asm/vpaes-x86_64.pl GENERATE[bsaes-x86_64.s]=asm/bsaes-x86_64.pl GENERATE[aesni-x86_64.s]=asm/aesni-x86_64.pl GENERATE[aes-cfb-avx512.s]=asm/aes-cfb-avx512.pl +GENERATE[aes-vaes-x86_64.s]=asm/aes-vaes-x86_64.pl GENERATE[aesni-sha1-x86_64.s]=asm/aesni-sha1-x86_64.pl GENERATE[aesni-sha256-x86_64.s]=asm/aesni-sha256-x86_64.pl GENERATE[aesni-mb-x86_64.s]=asm/aesni-mb-x86_64.pl diff --git a/crypto/arm64cpuid.pl b/crypto/arm64cpuid.pl index d90289b6a9269..6a8700a633dfd 100755 --- a/crypto/arm64cpuid.pl +++ b/crypto/arm64cpuid.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/armcap.c b/crypto/armcap.c index 31b17f06a573d..f4f6b0d7f9b7e 100644 --- a/crypto/armcap.c +++ b/crypto/armcap.c @@ -429,7 +429,8 @@ void OPENSSL_cpuid_setup(void) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N3) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V3_AE) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V3) - || MIDR_IMPLEMENTER(OPENSSL_arm_midr) == ARM_CPU_IMP_AMPERE)) + || MIDR_IMPLEMENTER(OPENSSL_arm_midr) == ARM_CPU_IMP_AMPERE + || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_OLYMPUS))) OPENSSL_armcap_P |= ARMV8_UNROLL8_EOR3; if ((OPENSSL_armcap_P & ARMV8_SHA3) diff --git a/crypto/armv4cpuid.pl b/crypto/armv4cpuid.pl index 0d2b590ad3ba8..8441b7dde6219 100644 --- a/crypto/armv4cpuid.pl +++ b/crypto/armv4cpuid.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ascon/ascon_aead128.c b/crypto/ascon/ascon_aead128.c new file mode 100644 index 0000000000000..b3d3f02289b16 --- /dev/null +++ b/crypto/ascon/ascon_aead128.c @@ -0,0 +1,304 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "crypto/ascon.h" +#include +#include "internal/cryptlib.h" +#include +#include + +#define ROR64(x, i) ((x << (64 - i)) | (x >> i)) + +/** + * constant addition layer, NIST SP 800-232 Table 5 + * 3c 2d 1e 0f f0 e1 d2 c3 b4 a5 96 87 78 69 5a 4b + */ +#define ASCONPC(x0, x1, x2, x3, x4, rcon) \ + do { \ + x2 ^= rcon; \ + } while (0) + +/** + * nonlinear layer, lifted from p43 of + * https://csrc.nist.gov/CSRC/media/Projects/lightweight-cryptography/ + * documents/finalist-round/updated-spec-doc/ascon-spec-final.pdf + */ +#define ASCONPS(x0, x1, x2, x3, x4) \ + do { \ + uint64_t q0, q1; \ + \ + x0 ^= x4; \ + x4 ^= x3; \ + x2 ^= x1; \ + q0 = x0 & (~x4); \ + q1 = x2 & (~x1); \ + x0 ^= q1; \ + q1 = x4 & (~x3); \ + x2 ^= q1; \ + q1 = x1 & (~x0); \ + x4 ^= q1; \ + q1 = x3 & (~x2); \ + x1 ^= q1; \ + x3 ^= q0; \ + x1 ^= x0; \ + x3 ^= x2; \ + x0 ^= x4; \ + x2 = ~x2; \ + } while (0) + +/* linear layer, NIST SP 800-232 Figure 3 */ +#define ASCONPL(x0, x1, x2, x3, x4) \ + do { \ + x0 ^= ROR64(x0, 19) ^ ROR64(x0, 28); \ + x1 ^= ROR64(x1, 61) ^ ROR64(x1, 39); \ + x2 ^= ROR64(x2, 1) ^ ROR64(x2, 6); \ + x3 ^= ROR64(x3, 10) ^ ROR64(x3, 17); \ + x4 ^= ROR64(x4, 7) ^ ROR64(x4, 41); \ + } while (0) + +/* one round */ +#define ASCONP1(x0, x1, x2, x3, x4, rcon) \ + do { \ + ASCONPC(x0, x1, x2, x3, x4, rcon); \ + ASCONPS(x0, x1, x2, x3, x4); \ + ASCONPL(x0, x1, x2, x3, x4); \ + } while (0) + +/* 8 rounds */ +#define ASCONP8(x0, x1, x2, x3, x4) \ + do { \ + ASCONP1(x0, x1, x2, x3, x4, 0xB4ULL); \ + ASCONP1(x0, x1, x2, x3, x4, 0xA5ULL); \ + ASCONP1(x0, x1, x2, x3, x4, 0x96ULL); \ + ASCONP1(x0, x1, x2, x3, x4, 0x87ULL); \ + ASCONP1(x0, x1, x2, x3, x4, 0x78ULL); \ + ASCONP1(x0, x1, x2, x3, x4, 0x69ULL); \ + ASCONP1(x0, x1, x2, x3, x4, 0x5AULL); \ + ASCONP1(x0, x1, x2, x3, x4, 0x4BULL); \ + } while (0) + +/* 12 rounds */ +#define ASCONP12(x0, x1, x2, x3, x4) \ + do { \ + ASCONP1(x0, x1, x2, x3, x4, 0xF0ULL); \ + ASCONP1(x0, x1, x2, x3, x4, 0xE1ULL); \ + ASCONP1(x0, x1, x2, x3, x4, 0xD2ULL); \ + ASCONP1(x0, x1, x2, x3, x4, 0xC3ULL); \ + ASCONP8(x0, x1, x2, x3, x4); \ + } while (0) + +/* misc ascon flags for the context */ +#define ASCONFLG_AAD 0x0000000000000001ULL /* has AAD inputs? */ +#define ASCONFLG_DEC 0x0000000000000002ULL /* in decrypt mode? */ +#define ASCONFLG_DOMAINSEP 0x8000000000000000ULL /* ready to absorb non-AAD? */ + +static ossl_inline void ascon_aead128_update(ascon_aead128_ctx *ctx, + unsigned char *out, + const unsigned char *in, + size_t len) +{ + uint64_t s0, s1, s2, s3, s4, flags; + unsigned char pad = 0x01; + + if (ctx->flags & ASCONFLG_DOMAINSEP) { + flags = ctx->flags; + if (flags & ASCONFLG_AAD) { + ctx->flags = 0; + ascon_aead128_update(ctx, NULL, &pad, 1); + ASCONP8(ctx->state[0], ctx->state[1], ctx->state[2], ctx->state[3], ctx->state[4]); + flags ^= ASCONFLG_AAD; + ctx->offset = 0; + } + ctx->state[4] ^= ASCONFLG_DOMAINSEP; + flags ^= ASCONFLG_DOMAINSEP; + ctx->flags = flags; + } + + s0 = ctx->state[0]; + s1 = ctx->state[1]; + s2 = ctx->state[2]; + s3 = ctx->state[3]; + s4 = ctx->state[4]; + + while (len--) { + unsigned char ob, ib = *in++; + + if (ctx->offset >= 16) { + ASCONP8(s0, s1, s2, s3, s4); + ctx->offset = 0; + } + + if (ctx->flags & ASCONFLG_DEC) { + if (ctx->offset >= 8) { + ob = (unsigned char)(s1 >> 8 * (ctx->offset & 0x7)) ^ ib; + s1 ^= (uint64_t)(ob) << 8 * (ctx->offset & 0x7); + } else { + ob = (unsigned char)(s0 >> 8 * ctx->offset) ^ ib; + s0 ^= (uint64_t)(ob) << 8 * ctx->offset; + } + } else { + if (ctx->offset >= 8) { + s1 ^= (uint64_t)(ib) << 8 * (ctx->offset & 0x7); + ob = (unsigned char)(s1 >> 8 * (ctx->offset & 0x7)); + } else { + s0 ^= (uint64_t)(ib) << 8 * ctx->offset; + ob = (unsigned char)(s0 >> 8 * ctx->offset); + } + } + + if (out != NULL) + *out++ = ob; + + ctx->offset++; + } + + ctx->state[0] = s0; + ctx->state[1] = s1; + ctx->state[2] = s2; + ctx->state[3] = s3; + ctx->state[4] = s4; +} + +static void ascon_aead128_encrypt_update(ascon_aead128_ctx *ctx, unsigned char *ct, + const unsigned char *pt, size_t len) +{ + ascon_aead128_update(ctx, ct, pt, len); +} + +static void ascon_aead128_decrypt_update(ascon_aead128_ctx *ctx, unsigned char *pt, + const unsigned char *ct, size_t len) +{ + ctx->flags |= ASCONFLG_DEC; + ascon_aead128_update(ctx, pt, ct, len); +} + +static void ascon_aead128_init(ascon_aead128_ctx *ctx, const unsigned char *k, + const unsigned char *n) +{ + uint64_t s0, s1, s2, s3, s4, k0, k1; + + OPENSSL_load_u64_le(&s1, k); + OPENSSL_load_u64_le(&s2, k + 8); + OPENSSL_load_u64_le(&s3, n); + OPENSSL_load_u64_le(&s4, n + 8); + ctx->key[0] = k0 = s1; + ctx->key[1] = k1 = s2; + s0 = 0x00001000808C0001ULL; + ASCONP12(s0, s1, s2, s3, s4); + s3 ^= k0; + s4 ^= k1; + ctx->state[0] = s0; + ctx->state[1] = s1; + ctx->state[2] = s2; + ctx->state[3] = s3; + ctx->state[4] = s4; + ctx->offset = 0; + ctx->flags = ASCONFLG_DOMAINSEP; +} + +static void ascon_aead128_aad_update(ascon_aead128_ctx *ctx, const unsigned char *in, + size_t len) +{ + uint64_t flags; + + flags = ctx->flags; + ctx->flags = 0; + ascon_aead128_update(ctx, NULL, in, len); + ctx->flags = (len > 0) ? flags |= ASCONFLG_AAD : flags; +} + +static void ascon_aead128_final(ascon_aead128_ctx *ctx, unsigned char *tag) +{ + uint64_t s0, s1, s2, s3, s4, k0, k1; + unsigned char pad = 0x01; + + ascon_aead128_update(ctx, NULL, NULL, 0); + ctx->flags = 0; + ascon_aead128_update(ctx, NULL, &pad, 1); + + k0 = ctx->key[0]; + k1 = ctx->key[1]; + s0 = ctx->state[0]; + s1 = ctx->state[1]; + s2 = ctx->state[2] ^ k0; + s3 = ctx->state[3] ^ k1; + s4 = ctx->state[4]; + ASCONP12(s0, s1, s2, s3, s4); + s3 ^= k0; + s4 ^= k1; + OPENSSL_store_u64_le(tag, s3); + OPENSSL_store_u64_le(tag + 8, s4); +} + +/* Provider compatibility wrapper functions */ +void ossl_ascon_aead128_init(ASCON_AEAD_CTX *ctx, const unsigned char *k, + const unsigned char *n) +{ + ascon_aead128_init(ctx, k, n); +} + +void ossl_ascon_aead128_assoc_data_update(ASCON_AEAD_CTX *ctx, + const unsigned char *in, size_t inl) +{ + ascon_aead128_aad_update(ctx, in, inl); +} + +size_t ossl_ascon_aead128_encrypt_update(ASCON_AEAD_CTX *ctx, + unsigned char *out, + const unsigned char *in, size_t inl) +{ + ascon_aead128_encrypt_update(ctx, out, in, inl); + return inl; +} + +size_t ossl_ascon_aead128_decrypt_update(ASCON_AEAD_CTX *ctx, + unsigned char *out, + const unsigned char *in, size_t inl) +{ + ascon_aead128_decrypt_update(ctx, out, in, inl); + return inl; +} + +size_t ossl_ascon_aead128_encrypt_final(ASCON_AEAD_CTX *ctx, + unsigned char *out, + unsigned char *tag, size_t tag_len) +{ + unsigned char computed_tag[16]; + + ascon_aead128_final(ctx, computed_tag); + if (tag != NULL && tag_len >= 16) + memcpy(tag, computed_tag, 16); + if (out != NULL) { + /* No additional output for final */ + } + return 0; +} + +size_t ossl_ascon_aead128_decrypt_final(ASCON_AEAD_CTX *ctx, + unsigned char *out, + int *is_tag_valid, + const unsigned char *tag, + size_t tag_len) +{ + unsigned char computed_tag[16]; + + ascon_aead128_final(ctx, computed_tag); + if (is_tag_valid != NULL && tag != NULL && tag_len >= 16) { + *is_tag_valid = (CRYPTO_memcmp(computed_tag, tag, 16) == 0); + } else if (is_tag_valid != NULL) { + *is_tag_valid = 0; + } + return 0; +} + +void ossl_ascon_aead_cleanup(ASCON_AEAD_CTX *ctx) +{ + if (ctx != NULL) + OPENSSL_cleanse(ctx, sizeof(ASCON_AEAD_CTX)); +} diff --git a/crypto/ascon/build.info b/crypto/ascon/build.info new file mode 100644 index 0000000000000..bb0610218c143 --- /dev/null +++ b/crypto/ascon/build.info @@ -0,0 +1,4 @@ +# ASCON algorithm implementation +LIBS=../../libcrypto +SOURCE[../../libcrypto]=ascon_aead128.c +INCLUDE[../../libcrypto]=../include diff --git a/crypto/asn1/a_bitstr.c b/crypto/asn1/a_bitstr.c index 914ff98400617..02180541ea25c 100644 --- a/crypto/asn1/a_bitstr.c +++ b/crypto/asn1/a_bitstr.c @@ -18,7 +18,7 @@ #ifndef OPENSSL_NO_DEPRECATED_4_1 int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len) { - return ASN1_STRING_set(x, d, len); + return ossl_asn1_string_set_internal(x, d, len, /*add_nul_byte=*/0); } #endif @@ -32,7 +32,7 @@ int ossl_i2c_ASN1_BIT_STRING(const ASN1_BIT_STRING *a, unsigned char **pp) len = a->length; - if (len > INT_MAX - 1) + if (len > INT_MAX - 1 || len < 0) goto err; if ((len > 0) && (a->flags & ASN1_STRING_FLAG_BITS_LEFT)) @@ -224,7 +224,7 @@ int ASN1_BIT_STRING_get_length(const ASN1_BIT_STRING *abs, size_t *out_length, if (abs == NULL || abs->type != V_ASN1_BIT_STRING) return 0; - if (out_length == NULL || out_unused_bits == NULL) + if (out_length == NULL || out_unused_bits == NULL || abs->length < 0) return 0; length = abs->length; @@ -263,8 +263,9 @@ int ASN1_BIT_STRING_set1(ASN1_BIT_STRING *abs, const uint8_t *data, size_t lengt if (length > 0 && (data[length - 1] & ((1 << unused_bits) - 1)) != 0) return 0; - if (!ASN1_STRING_set(abs, data, (int)length)) + if (!ossl_asn1_string_set_internal(abs, data, (int)length, /*add_nul_byte=*/0)) return 0; + abs->type = V_ASN1_BIT_STRING; ossl_asn1_bit_string_set_unused_bits(abs, unused_bits); diff --git a/crypto/asn1/a_dup.c b/crypto/asn1/a_dup.c index 48f5b3f6a4c82..5c43ccdd03a43 100644 --- a/crypto/asn1/a_dup.c +++ b/crypto/asn1/a_dup.c @@ -82,10 +82,15 @@ void *ASN1_item_dup(const ASN1_ITEM *it, const void *x) p = b; ret = ASN1_item_d2i_ex(NULL, &p, i, it, libctx, propq); OPENSSL_free(b); + if (ret == NULL) + return NULL; if (asn1_cb != NULL - && !asn1_cb(ASN1_OP_DUP_POST, &ret, it, (void *)x)) - goto auxerr; + && !asn1_cb(ASN1_OP_DUP_POST, &ret, it, (void *)x)) { + ASN1_item_free(ret, it); + ERR_raise_data(ERR_LIB_ASN1, ASN1_R_AUX_ERROR, "Type=%s", it->sname); + return NULL; + } return ret; diff --git a/crypto/asn1/a_int.c b/crypto/asn1/a_int.c index 3b10ee99e51b2..5dd12058626c4 100644 --- a/crypto/asn1/a_int.c +++ b/crypto/asn1/a_int.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -316,7 +316,7 @@ ASN1_INTEGER *ossl_c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, } else ret = *a; - if (r > INT_MAX || ASN1_STRING_set(ret, NULL, (int)r) == 0) { + if (ossl_asn1_string_set1_data(ret, NULL, r) == 0) { ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; } @@ -371,7 +371,7 @@ static int asn1_string_set_int64(ASN1_STRING *a, int64_t r, int itype) off = asn1_put_uint64(tbuf, r); a->type &= ~V_ASN1_NEG; } - return ASN1_STRING_set(a, tbuf + off, (int)(sizeof(tbuf) - off)); + return ossl_asn1_string_set1_data(a, tbuf + off, (sizeof(tbuf) - off)); } static int asn1_string_get_uint64(uint64_t *pr, const ASN1_STRING *a, @@ -399,7 +399,7 @@ static int asn1_string_set_uint64(ASN1_STRING *a, uint64_t r, int itype) a->type = itype; off = asn1_put_uint64(tbuf, r); - return ASN1_STRING_set(a, tbuf + off, (int)(sizeof(tbuf) - off)); + return ossl_asn1_string_set1_data(a, tbuf + off, (sizeof(tbuf) - off)); } /* @@ -503,7 +503,7 @@ static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai, if (len == 0) len = 1; - if (ASN1_STRING_set(ret, NULL, len) == 0) { + if (ossl_asn1_string_set1_data(ret, NULL, len) == 0) { ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; } diff --git a/crypto/asn1/a_mbstr.c b/crypto/asn1/a_mbstr.c index 9329472e9beab..f4ec953f019b5 100644 --- a/crypto/asn1/a_mbstr.c +++ b/crypto/asn1/a_mbstr.c @@ -171,14 +171,18 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, } /* If both the same type just copy across */ if (inform == outform) { - if (!ASN1_STRING_set(dest, in, len)) { + if ((p = OPENSSL_malloc((size_t)len + 1)) == NULL) { if (free_out) { ASN1_STRING_free(dest); *out = NULL; } - ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); return -1; } + if (len > 0) + memcpy(p, in, (size_t)len); + p[len] = '\0'; + dest->data = p; + dest->length = len; return str_type; } diff --git a/crypto/asn1/a_octet.c b/crypto/asn1/a_octet.c index 4efb8ec5178c0..ebafaa72b4d8e 100644 --- a/crypto/asn1/a_octet.c +++ b/crypto/asn1/a_octet.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,6 +10,7 @@ #include #include "internal/cryptlib.h" #include +#include "crypto/asn1.h" ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x) { @@ -25,5 +26,11 @@ int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len) { - return ASN1_STRING_set(x, d, len); + if (len < -1) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL); + return 0; + } + if (len == -1) + return ossl_asn1_string_set1_string(x, (const char *)d); + return ossl_asn1_string_set1_data(x, d, len); } diff --git a/crypto/asn1/a_print.c b/crypto/asn1/a_print.c index 774d6b1383a67..2935c4008f020 100644 --- a/crypto/asn1/a_print.c +++ b/crypto/asn1/a_print.c @@ -14,20 +14,26 @@ #include -int ASN1_PRINTABLE_type(const unsigned char *s, int len) +/** + * @brief Determine the narrowest ASN.1 string type that can represent bytes. + * + * Unlike ASN1_PRINTABLE_type() this requires an explicit length and has no + * legacy path that treats its input as a NUL terminated C string, so it may + * be called on ASN1_STRING data. + * + * @param s pointer to the bytes to classify + * @param len the number of bytes available at s + * @returns V_ASN1_T61STRING, V_ASN1_IA5STRING or V_ASN1_PRINTABLESTRING + */ +static int printable_type(const unsigned char *s, size_t len) { - int c; int ia5 = 0; int t61 = 0; + size_t i; - if (s == NULL) - return V_ASN1_PRINTABLESTRING; - - if (len < 0) - len = (int)strlen((const char *)s); + for (i = 0; i < len; i++) { + int c = s[i]; - while (len-- > 0) { - c = *(s++); if (!ossl_isasn1print(c)) ia5 = 1; if (!ossl_isascii(c)) @@ -40,6 +46,17 @@ int ASN1_PRINTABLE_type(const unsigned char *s, int len) return V_ASN1_PRINTABLESTRING; } +int ASN1_PRINTABLE_type(const unsigned char *s, int len) +{ + if (s == NULL) + return V_ASN1_PRINTABLESTRING; + + if (len < 0) + len = (int)strlen((const char *)s); + + return printable_type(s, (size_t)len); +} + int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s) { int i; @@ -47,7 +64,7 @@ int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s) if (s->type != V_ASN1_UNIVERSALSTRING) return 0; - if ((s->length % 4) != 0) + if (s->length < 0 || (s->length % 4) != 0) return 0; p = s->data; for (i = 0; i < s->length; i += 4) { @@ -62,9 +79,10 @@ int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s) for (i = 3; i < s->length; i += 4) { *(p++) = s->data[i]; } - *(p) = '\0'; + if (s->length > 0) + *p = '\0'; s->length /= 4; - s->type = ASN1_PRINTABLE_type(s->data, s->length); + s->type = printable_type(s->data, (size_t)s->length); return 1; } diff --git a/crypto/asn1/a_sign.c b/crypto/asn1/a_sign.c index 58d58f81ffa64..3bfc32cd994f3 100644 --- a/crypto/asn1/a_sign.c +++ b/crypto/asn1/a_sign.c @@ -21,6 +21,7 @@ #include #include "crypto/asn1.h" #include "crypto/evp.h" +#include "asn1_local.h" #ifndef OPENSSL_NO_DEPRECATED_3_0 @@ -282,6 +283,14 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); goto err; } + /* Only a sequence item carries a cached encoding */ + if ((it->itype == ASN1_ITYPE_SEQUENCE + || it->itype == ASN1_ITYPE_NDEF_SEQUENCE) + && !ossl_asn1_enc_save((ASN1_VALUE **)&data, buf_in, buf_len, it)) { + outl = 0; + ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); + goto err; + } ASN1_STRING_set0(signature, buf_out, (int)outl); buf_out = NULL; /* diff --git a/crypto/asn1/a_strex.c b/crypto/asn1/a_strex.c index e488c87f5bce2..a6b022ad50bb6 100644 --- a/crypto/asn1/a_strex.c +++ b/crypto/asn1/a_strex.c @@ -12,6 +12,7 @@ #include "internal/cryptlib.h" #include "internal/sizes.h" #include "internal/unicode.h" +#include "internal/safe_math.h" #include "crypto/asn1.h" #include #include @@ -31,6 +32,8 @@ #define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | ASN1_STRFLGS_ESC_2254 | ASN1_STRFLGS_ESC_QUOTE | ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB) +OSSL_SAFE_MATH_SIGNED(int, int) + /* * Three IO functions for sending data to memory, a BIO and a FILE * pointer. @@ -73,13 +76,13 @@ static int do_esc_char(uint32_t c, unsigned short flags, char *do_quotes, if (c > UNICODE_MAX) return -1; if (c > 0xffff) { - BIO_snprintf(tmphex, sizeof(tmphex), "\\W%08" PRIX32, c); + snprintf(tmphex, sizeof(tmphex), "\\W%08" PRIX32, c); if (!io_ch(arg, tmphex, 10)) return -1; return 10; } if (c > 0xff) { - BIO_snprintf(tmphex, sizeof(tmphex), "\\U%04" PRIX32, c); + snprintf(tmphex, sizeof(tmphex), "\\U%04" PRIX32, c); if (!io_ch(arg, tmphex, 6)) return -1; return 6; @@ -105,7 +108,7 @@ static int do_esc_char(uint32_t c, unsigned short flags, char *do_quotes, return 2; } if (chflgs & (ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB | ASN1_STRFLGS_ESC_2254)) { - BIO_snprintf(tmphex, 11, "\\%02X", chtmp); + snprintf(tmphex, 11, "\\%02X", chtmp); if (!io_ch(arg, tmphex, 3)) return -1; return 3; @@ -142,6 +145,10 @@ static int do_buf(const unsigned char *buf, int buflen, const unsigned char *p, *q; uint32_t c; + if (buflen < 0) + return -1; + if (buflen == 0) + return 0; p = buf; q = buf + buflen; outlen = 0; @@ -236,6 +243,10 @@ static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, unsigned char *p, *q; char hextmp[2]; + if (buflen < 0) + return -1; + if (buflen == 0) + return 0; if (arg) { p = buf; q = buf + buflen; @@ -430,6 +441,7 @@ static int do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n, char objtmp[80]; const char *objbuf; int outlen, len; + int err = 0; char *sep_dn, *sep_mv, *sep_eq; int sep_dn_len, sep_mv_len, sep_eq_len; if (indent < 0) @@ -493,14 +505,20 @@ static int do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n, if (prev == X509_NAME_ENTRY_set(ent)) { if (!io_ch(arg, sep_mv, sep_mv_len)) return -1; - outlen += sep_mv_len; + outlen = safe_add_int(outlen, sep_mv_len, &err); + if (err != 0) + return -1; } else { if (!io_ch(arg, sep_dn, sep_dn_len)) return -1; - outlen += sep_dn_len; + outlen = safe_add_int(outlen, sep_dn_len, &err); + if (err != 0) + return -1; if (!do_indent(io_ch, arg, indent)) return -1; - outlen += indent; + outlen = safe_add_int(outlen, indent, &err); + if (err != 0) + return -1; } } prev = X509_NAME_ENTRY_set(ent); @@ -531,11 +549,18 @@ static int do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n, if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) { if (!do_indent(io_ch, arg, fld_len - objlen)) return -1; - outlen += fld_len - objlen; + outlen = safe_add_int(outlen, fld_len - objlen, &err); + if (err != 0) + return -1; } if (!io_ch(arg, sep_eq, sep_eq_len)) return -1; - outlen += objlen + sep_eq_len; + outlen = safe_add_int(outlen, objlen, &err); + if (err != 0) + return -1; + outlen = safe_add_int(outlen, sep_eq_len, &err); + if (err != 0) + return -1; } /* * If the field name is unknown then fix up the DER dump flag. We @@ -550,7 +575,9 @@ static int do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n, len = do_print_ex(io_ch, arg, flags | orflags, val); if (len < 0) return -1; - outlen += len; + outlen = safe_add_int(outlen, len, &err); + if (err != 0) + return -1; } return outlen; } @@ -620,6 +647,7 @@ int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in) B_ASN1_UTF8STRING); if (ret < 0) return ret; + /* ASN1_mbstring_copy() guarantees the data it produced is NUL terminated */ *out = stmp.data; return stmp.length; } diff --git a/crypto/asn1/a_strnid.c b/crypto/asn1/a_strnid.c index 54117d50eef1f..6895302705842 100644 --- a/crypto/asn1/a_strnid.c +++ b/crypto/asn1/a_strnid.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/asn1/a_time.c b/crypto/asn1/a_time.c index 56366fe531a4b..5a1207dc85fb4 100644 --- a/crypto/asn1/a_time.c +++ b/crypto/asn1/a_time.c @@ -251,6 +251,7 @@ ASN1_TIME *ossl_asn1_time_from_tm(ASN1_TIME *s, struct tm *ts, int type) char *p; ASN1_TIME *tmps = NULL; const int len = 20; + int ret; if (type == V_ASN1_UNDEF) { if (is_utc(ts->tm_year)) @@ -271,7 +272,7 @@ ASN1_TIME *ossl_asn1_time_from_tm(ASN1_TIME *s, struct tm *ts, int type) if (tmps == NULL) return NULL; - if (!ASN1_STRING_set(tmps, NULL, len)) + if (!ossl_asn1_string_set1_data(tmps, NULL, len)) goto err; tmps->type = type; @@ -283,16 +284,19 @@ ASN1_TIME *ossl_asn1_time_from_tm(ASN1_TIME *s, struct tm *ts, int type) if (type == V_ASN1_GENERALIZEDTIME) { if (ts->tm_year > INT_MAX - 1900) goto err; - tmps->length = BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", + ret = snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900, ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec); } else { - tmps->length = BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", + ret = snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100, ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, ts->tm_sec); } + if (ret < 0 || ret >= len) + goto err; + tmps->length = ret; #ifdef CHARSET_EBCDIC ebcdic2ascii(tmps->data, tmps->data, tmps->length); diff --git a/crypto/asn1/a_utf8.c b/crypto/asn1/a_utf8.c index 76f5ccbda4e21..2b479ea22ce29 100644 --- a/crypto/asn1/a_utf8.c +++ b/crypto/asn1/a_utf8.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/asn1/asn1_err.c b/crypto/asn1/asn1_err.c deleted file mode 100644 index 81ac09bba3c87..0000000000000 --- a/crypto/asn1/asn1_err.c +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/asn1err.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA ASN1_str_reasons[] = { - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ADDING_OBJECT), "adding object" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ASN1_PARSE_ERROR), "asn1 parse error" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ASN1_SIG_PARSE_ERROR), - "asn1 sig parse error" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_AUX_ERROR), "aux error" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BAD_OBJECT_HEADER), "bad object header" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BAD_TEMPLATE), "bad template" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BMPSTRING_IS_WRONG_LENGTH), - "bmpstring is wrong length" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BN_LIB), "bn lib" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BOOLEAN_IS_WRONG_LENGTH), - "boolean is wrong length" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_BUFFER_TOO_SMALL), "buffer too small" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER), - "cipher has no object identifier" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_CONTEXT_NOT_INITIALISED), - "context not initialised" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_DATA_IS_WRONG), "data is wrong" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_DECODE_ERROR), "decode error" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_DEPTH_EXCEEDED), "depth exceeded" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED), - "digest and key type not supported" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ENCODE_ERROR), "encode error" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ERROR_GETTING_TIME), - "error getting time" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ERROR_LOADING_SECTION), - "error loading section" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ERROR_SETTING_CIPHER_PARAMS), - "error setting cipher params" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_EXPECTING_AN_INTEGER), - "expecting an integer" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_EXPECTING_AN_OBJECT), - "expecting an object" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_EXPLICIT_LENGTH_MISMATCH), - "explicit length mismatch" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED), - "explicit tag not constructed" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_FIELD_MISSING), "field missing" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_FIRST_NUM_TOO_LARGE), - "first num too large" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_GENERALIZEDTIME_IS_TOO_SHORT), - "generalizedtime is too short" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_HEADER_TOO_LONG), "header too long" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_BITSTRING_FORMAT), - "illegal bitstring format" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_BOOLEAN), "illegal boolean" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_CHARACTERS), - "illegal characters" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_FORMAT), "illegal format" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_HEX), "illegal hex" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_IMPLICIT_TAG), - "illegal implicit tag" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_INTEGER), "illegal integer" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_NEGATIVE_VALUE), - "illegal negative value" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_NESTED_TAGGING), - "illegal nested tagging" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_NULL), "illegal null" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_NULL_VALUE), - "illegal null value" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_OBJECT), "illegal object" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_OPTIONAL_ANY), - "illegal optional any" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE), - "illegal options on item template" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_PADDING), "illegal padding" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_TAGGED_ANY), - "illegal tagged any" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_TIME_VALUE), - "illegal time value" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ILLEGAL_ZERO_CONTENT), - "illegal zero content" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INTEGER_NOT_ASCII_FORMAT), - "integer not ascii format" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG), - "integer too large for long" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_BIT_STRING_BITS_LEFT), - "invalid bit string bits left" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_BMPSTRING_LENGTH), - "invalid bmpstring length" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_DIGIT), "invalid digit" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_MIME_TYPE), "invalid mime type" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_MODIFIER), "invalid modifier" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_NUMBER), "invalid number" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_OBJECT_ENCODING), - "invalid object encoding" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_SCRYPT_PARAMETERS), - "invalid scrypt parameters" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_SEPARATOR), "invalid separator" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_STRING_TABLE_VALUE), - "invalid string table value" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH), - "invalid universalstring length" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_UTF8STRING), - "invalid utf8string" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_INVALID_VALUE), "invalid value" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_LENGTH_TOO_LONG), "length too long" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_LIST_ERROR), "list error" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MIME_NO_CONTENT_TYPE), - "mime no content type" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MIME_PARSE_ERROR), "mime parse error" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MIME_SIG_PARSE_ERROR), - "mime sig parse error" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MISSING_EOC), "missing eoc" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MISSING_SECOND_NUMBER), - "missing second number" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MISSING_VALUE), "missing value" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MSTRING_NOT_UNIVERSAL), - "mstring not universal" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_MSTRING_WRONG_TAG), "mstring wrong tag" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NESTED_ASN1_STRING), - "nested asn1 string" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NESTED_TOO_DEEP), "nested too deep" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NON_HEX_CHARACTERS), - "non hex characters" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NOT_ASCII_FORMAT), "not ascii format" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NOT_ENOUGH_DATA), "not enough data" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_CONTENT_TYPE), "no content type" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_MATCHING_CHOICE_TYPE), - "no matching choice type" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_MULTIPART_BODY_FAILURE), - "no multipart body failure" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_MULTIPART_BOUNDARY), - "no multipart boundary" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NO_SIG_CONTENT_TYPE), - "no sig content type" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_NULL_IS_WRONG_LENGTH), - "null is wrong length" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_OBJECT_NOT_ASCII_FORMAT), - "object not ascii format" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_ODD_NUMBER_OF_CHARS), - "odd number of chars" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SECOND_NUMBER_TOO_LARGE), - "second number too large" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SEQUENCE_LENGTH_MISMATCH), - "sequence length mismatch" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SEQUENCE_NOT_CONSTRUCTED), - "sequence not constructed" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG), - "sequence or set needs config" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SHORT_LINE), "short line" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_SIG_INVALID_MIME_TYPE), - "sig invalid mime type" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_STREAMING_NOT_SUPPORTED), - "streaming not supported" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_STRING_TOO_LONG), "string too long" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_STRING_TOO_SHORT), "string too short" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD), - "the asn1 object identifier is not known for this md" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TIME_NOT_ASCII_FORMAT), - "time not ascii format" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TOO_LARGE), "too large" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TOO_LONG), "too long" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TOO_SMALL), "too small" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TYPE_NOT_CONSTRUCTED), - "type not constructed" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_TYPE_NOT_PRIMITIVE), - "type not primitive" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNEXPECTED_EOC), "unexpected eoc" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH), - "universalstring is wrong length" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_DIGEST), "unknown digest" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_FORMAT), "unknown format" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM), - "unknown message digest algorithm" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_OBJECT_TYPE), - "unknown object type" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE), - "unknown public key type" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM), - "unknown signature algorithm" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNKNOWN_TAG), "unknown tag" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE), - "unsupported any defined by type" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_CIPHER), - "unsupported cipher" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE), - "unsupported public key type" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UNSUPPORTED_TYPE), "unsupported type" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_UTCTIME_IS_TOO_SHORT), - "utctime is too short" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_WRONG_INTEGER_TYPE), - "wrong integer type" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_WRONG_PUBLIC_KEY_TYPE), - "wrong public key type" }, - { ERR_PACK(ERR_LIB_ASN1, 0, ASN1_R_WRONG_TAG), "wrong tag" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_ASN1_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(ASN1_str_reasons[0].error) == NULL) - ERR_load_strings_const(ASN1_str_reasons); -#endif - return 1; -} diff --git a/crypto/asn1/asn1_gen.c b/crypto/asn1/asn1_gen.c index 35abf85ca4389..351bdafe7fba1 100644 --- a/crypto/asn1/asn1_gen.c +++ b/crypto/asn1/asn1_gen.c @@ -426,8 +426,11 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, depth + 1, perr); if (!typ) goto bad; - if (!sk_ASN1_TYPE_push(sk, typ)) + + if (!sk_ASN1_TYPE_push(sk, typ)) { + ASN1_TYPE_free(typ); goto bad; + } } } @@ -444,8 +447,11 @@ static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, goto bad; if ((ret = ASN1_TYPE_new()) == NULL) goto bad; - if ((ret->value.asn1_string = ASN1_STRING_type_new(utype)) == NULL) + if ((ret->value.asn1_string = ASN1_STRING_type_new(utype)) == NULL) { + ASN1_TYPE_free(ret); + ret = NULL; goto bad; + } ret->type = utype; ret->value.asn1_string->data = der; @@ -651,7 +657,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto bad_str; } - if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { + if (!ossl_asn1_string_set1_string(atmp->value.asn1_string, str)) { ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto bad_str; } @@ -706,7 +712,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) atmp->value.asn1_string->length = rdlen; atmp->value.asn1_string->type = utype; } else if (format == ASN1_GEN_FORMAT_ASCII) { - if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { + if (!ossl_asn1_string_set1_string(atmp->value.asn1_string, str)) { ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto bad_str; } diff --git a/crypto/asn1/asn1_item_list.c b/crypto/asn1/asn1_item_list.c index b01fb738acd92..0eaf5fa128425 100644 --- a/crypto/asn1/asn1_item_list.c +++ b/crypto/asn1/asn1_item_list.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/asn1/asn1_lib.c b/crypto/asn1/asn1_lib.c index 99903564e25b2..825886ecbf969 100644 --- a/crypto/asn1/asn1_lib.c +++ b/crypto/asn1/asn1_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -13,6 +13,32 @@ #include #include "asn1_local.h" +#if defined(__has_feature) +#if __has_feature(address_sanitizer) +#define ASN1_HAVE_ASAN 1 +#endif +#if __has_feature(memory_sanitizer) +#define ASN1_HAVE_MSAN 1 +#endif +#endif /* defined(__has_feature) */ +#if defined(__SANITIZE_ADDRESS__) && !defined(ASN1_HAVE_ASAN) +#define ASN1_HAVE_ASAN 1 +#endif +#if defined(ASN1_HAVE_ASAN) +#include +#endif +#if defined(ASN1_HAVE_MSAN) +#include +#endif +#if !defined OPENSSL_NO_VALGRIND_CHECK && defined __has_include +/* Any compiler you're going to run valgrind on has this */ +#if __has_include() +#include +#include "internal/thread_once.h" +#define ASN1_HAVE_VALGRIND 1 +#endif +#endif /* defined(__has_include) */ + static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, long max); static void asn1_put_length(unsigned char **pp, int length); @@ -262,10 +288,11 @@ void ossl_asn1_bit_string_set_unused_bits(ASN1_STRING *str, unsigned int num) int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str) { - if (str == NULL) + if (str == NULL || str->length < 0) return 0; dst->type = str->type; - if (!ASN1_STRING_set(dst, str->data, str->length)) + if (!ossl_asn1_string_set_internal(dst, str->data, str->length, + /*add_nul_byte=*/0)) return 0; /* Copy flags but preserve embed value */ dst->flags &= ASN1_STRING_FLAG_EMBED; @@ -289,12 +316,85 @@ ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str) return ret; } -int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in) +#if defined(ASN1_HAVE_VALGRIND) +static CRYPTO_ONCE valgrind_once = CRYPTO_ONCE_STATIC_INIT; +static int valgrind_present = 0; + +DEFINE_RUN_ONCE_STATIC(detect_valgrind) +{ + valgrind_present = RUNNING_ON_VALGRIND != 0; + return 1; +} + +static int under_valgrind(void) +{ + return RUN_ONCE(&valgrind_once, detect_valgrind) && valgrind_present; +} +#endif /* defined(ASN1_HAVE_VALGRIND) */ + +/** + * @brief Mark the NUL terminator at p as inaccessible to memory checkers. + * Under AddressSanitizer, MemorySanitizer and Valgrind memcheck a read of + * the byte is reported as an error, so C-string use of ASN1_STRING data is + * caught while the byte stays present for builds without a checker. The + * Valgrind client requests are compiled in wherever its header is found and + * are issued only when the process is running under Valgrind. + * A poisoned byte needs no unpoisoning before free(): every checker marks + * the whole block on free without regard to its previous state. + * @param p the terminator byte + */ +static void poison_terminator(uint8_t *p) +{ +#if defined(ASN1_HAVE_ASAN) + ASAN_POISON_MEMORY_REGION(p, 1); +#endif +#if defined(ASN1_HAVE_MSAN) + __msan_poison(p, 1); +#endif +#if defined(ASN1_HAVE_VALGRIND) + if (under_valgrind()) + VALGRIND_MAKE_MEM_NOACCESS(p, 1); +#endif +} + +/** + * @brief Make the byte at p accessible again before it is written. + * @param p the byte about to hold a NUL terminator + */ +static void unpoison_terminator(uint8_t *p) { - unsigned char *c; - const char *data = _data; - size_t len; +#if defined(ASN1_HAVE_ASAN) + ASAN_UNPOISON_MEMORY_REGION(p, 1); +#endif +#if defined(ASN1_HAVE_MSAN) + __msan_unpoison(p, 1); +#endif +#if defined(ASN1_HAVE_VALGRIND) + if (under_valgrind()) + VALGRIND_MAKE_MEM_UNDEFINED(p, 1); +#endif +} +static void unpoison_buffer(uint8_t *buf, size_t buf_len) +{ +#if defined(ASN1_HAVE_VALGRIND) + if (under_valgrind()) + VALGRIND_MAKE_MEM_UNDEFINED(buf, buf_len); +#endif +} + +int ossl_asn1_string_set_internal(ASN1_STRING *str, const uint8_t *data, + int len_in, int add_nul_byte) +{ + size_t len, alloc_len; + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* + * Force no NUL byte for callers that are requesting it + * 0 length object data will be NULL + */ + add_nul_byte = 0; +#endif if (len_in < -1) { ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL); return 0; @@ -302,16 +402,17 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in) if (len_in == -1) { if (data == NULL) return 0; - len = strlen(data); + len = strlen((const char *)data); } else { len = (size_t)len_in; } /* - * Verify that the length fits within an integer for assignment to - * str->length below. The additional 1 is subtracted to allow for the - * '\0' terminator even though this isn't strictly necessary. + * Add one to the length to allow for adding an a '\0' terminator + * "even though this isn't strictly necessary". */ - if (len > INT_MAX - 1) { + alloc_len = add_nul_byte ? len + 1 : len; + + if (alloc_len > INT_MAX) { ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE); return 0; } @@ -322,47 +423,103 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in) str->flags &= ~ASN1_STRING_FLAG_DATA_NOT_OWNED; } - if ((size_t)str->length <= len || str->data == NULL) { - c = str->data; -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - /* No NUL terminator in fuzzing builds */ - str->data = OPENSSL_realloc(c, len != 0 ? len : 1); -#else - str->data = OPENSSL_realloc(c, len + 1); -#endif - if (str->data == NULL) { - str->data = c; + /* Ensure copying a 0 length data field is defined. */ + if (alloc_len == 0) { + OPENSSL_free(str->data); + str->data = NULL; + str->length = 0; + return 1; + } + + if ((size_t)str->length != alloc_len) { + uint8_t *c; + c = OPENSSL_realloc(str->length == 0 ? NULL : str->data, alloc_len); + if (c == NULL) return 0; - } + str->data = c; + unpoison_buffer(str->data, alloc_len); } + /* length never includes the added \0 byte */ str->length = (int)len; - if (data != NULL) { + + if (data != NULL && str->data != NULL) memcpy(str->data, data, len); -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - /* Set the unused byte to something non NUL and printable. */ - if (len == 0) - str->data[len] = '~'; -#else + if (add_nul_byte) { /* - * Add a NUL terminator. This should not be necessary - but we add it as - * a safety precaution + * The terminator byte lies beyond str->length. It is written only + * when data is supplied, and is inaccessible to memory checkers + * either way; see poison_terminator(). */ - str->data[len] = '\0'; -#endif + unpoison_terminator(&str->data[len]); + if (data != NULL) + str->data[len] = '\0'; + poison_terminator(&str->data[len]); } ossl_asn1_bit_string_clear_unused_bits(str); return 1; } +#ifndef OPENSSL_NO_DEPRECATED_4_1 +int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in) +{ + return ossl_asn1_string_set_internal(str, (const uint8_t *)_data, len_in, + /*add_nul_byte=*/1); +} +#endif + void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len) { if (!(str->flags & ASN1_STRING_FLAG_DATA_NOT_OWNED)) { - OPENSSL_clear_free(str->data, str->length); + if (str->length > 0) + OPENSSL_clear_free(str->data, str->length); + else + OPENSSL_free(str->data); } str->flags &= ~ASN1_STRING_FLAG_DATA_NOT_OWNED; str->data = data; - str->length = len; + str->length = len < 0 ? 0 : len; +} + +int ASN1_STRING_set1_data(ASN1_STRING *str, const uint8_t *data, size_t len_in) +{ + if (str->type == V_ASN1_BIT_STRING) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT); + return 0; + } + /* This will go away once ASN1_STRING can size_t internally */ + if (len_in > INT_MAX) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE); + return 0; + } + return ossl_asn1_string_set_internal(str, data, (int)len_in, /*add_nul_byte=*/0); +} + +int ASN1_STRING_set1_string(ASN1_STRING *str, const char *c_string) +{ + return ASN1_STRING_set1_data(str, (const uint8_t *)c_string, + strlen(c_string)); +} + +int ossl_asn1_string_set1_data(ASN1_STRING *str, const uint8_t *data, + size_t len_in) +{ + if (str->type == V_ASN1_BIT_STRING) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT); + return 0; + } + /* This will go away once ASN1_STRING can size_t internally */ + if (len_in > INT_MAX) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE); + return 0; + } + return ossl_asn1_string_set_internal(str, data, (int)len_in, /*add_nul_byte=*/1); +} + +int ossl_asn1_string_set1_string(ASN1_STRING *str, const char *c_string) +{ + return ossl_asn1_string_set1_data(str, (const uint8_t *)c_string, + strlen(c_string)); } ASN1_STRING *ASN1_STRING_new(void) @@ -419,7 +576,7 @@ void ossl_asn1_string_free_internal(ASN1_STRING *a, int clear, int embed) } if (!(a->flags & ASN1_STRING_FLAG_NDEF)) { - if (clear) + if (clear && a->length > 0) OPENSSL_clear_free(a->data, a->length); else OPENSSL_free(a->data); @@ -469,10 +626,17 @@ int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) } } +#ifndef OPENSSL_NO_DEPRECATED_4_1 int ASN1_STRING_length(const ASN1_STRING *x) { return x->length; } +#endif + +size_t ASN1_STRING_get_length(const ASN1_STRING *x) +{ + return x->length >= 0 ? (size_t)x->length : 0U; +} #ifndef OPENSSL_NO_DEPRECATED_3_0 void ASN1_STRING_length_set(ASN1_STRING *x, int len) @@ -491,7 +655,6 @@ const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x) return x->data; } -/* |max_len| excludes NUL terminator and may be 0 to indicate no restriction */ char *ossl_sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text, const char *sep, size_t max_len) { @@ -509,7 +672,7 @@ char *ossl_sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text, current = sk_ASN1_UTF8STRING_value(text, i); if (i > 0) length += sep_len; - length += ASN1_STRING_length(current); + length += ASN1_STRING_get_length(current); if (max_len != 0 && length > max_len) return NULL; } @@ -519,13 +682,15 @@ char *ossl_sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text, p = result; for (i = 0; i < sk_ASN1_UTF8STRING_num(text); i++) { current = sk_ASN1_UTF8STRING_value(text, i); - length = ASN1_STRING_length(current); + length = ASN1_STRING_get_length(current); if (i > 0 && sep_len > 0) { - strncpy(p, sep, sep_len + 1); /* using + 1 to silence gcc warning */ + memcpy(p, sep, sep_len); p += sep_len; } - strncpy(p, (const char *)ASN1_STRING_get0_data(current), length); - p += length; + if (length > 0) { + memcpy(p, ASN1_STRING_get0_data(current), length); + p += length; + } } *p = '\0'; diff --git a/crypto/asn1/asn1_local.h b/crypto/asn1/asn1_local.h index 0fd1d0a842a1a..6f3ee7983cf79 100644 --- a/crypto/asn1/asn1_local.h +++ b/crypto/asn1/asn1_local.h @@ -102,5 +102,7 @@ int ossl_asn1_time_time_t_to_tm(const time_t *time, struct tm *out_tm); int ossl_asn1_time_tm_to_time_t(const struct tm *tm, time_t *out); int ossl_asn1_call_aux_cb(const ASN1_AUX *aux, int operation, const ASN1_VALUE **in, const ASN1_ITEM *it, void *exarg); +int ossl_asn1_string_set_internal(ASN1_STRING *str, const uint8_t *data, + int len_in, int add_nul_byte); #endif /* !defined(OSSL_LIBCRYPTO_ASN1_ASN1_LOCAL_H) */ diff --git a/crypto/asn1/asn1_parse.c b/crypto/asn1/asn1_parse.c index 27d09dc9fe24e..9a602267b7151 100644 --- a/crypto/asn1/asn1_parse.c +++ b/crypto/asn1/asn1_parse.c @@ -28,7 +28,7 @@ static int asn1_print_info(BIO *bp, long offset, int depth, int hl, long len, const char *p; int pop_f_prefix = 0; long saved_indent = -1; - int i = 0; + int i = 0, n; BIO *bio = NULL; if (constructed & V_ASN1_CONSTRUCTED) @@ -36,16 +36,14 @@ static int asn1_print_info(BIO *bp, long offset, int depth, int hl, long len, else p = "prim: "; if (constructed != (V_ASN1_CONSTRUCTED | 1)) { - if (BIO_snprintf(str, sizeof(str), "%5ld:d=%-2d hl=%ld l=%4ld %s", - offset, depth, (long)hl, len, p) - <= 0) - goto err; + n = snprintf(str, sizeof(str), "%5ld:d=%-2d hl=%ld l=%4ld %s", + offset, depth, (long)hl, len, p); } else { - if (BIO_snprintf(str, sizeof(str), "%5ld:d=%-2d hl=%ld l=inf %s", - offset, depth, (long)hl, p) - <= 0) - goto err; + n = snprintf(str, sizeof(str), "%5ld:d=%-2d hl=%ld l=inf %s", + offset, depth, (long)hl, p); } + if (n <= 0 || (size_t)n >= sizeof(str)) + goto err; if (bp != NULL) { if (BIO_set_prefix(bp, str) <= 0) { if ((bio = BIO_new(BIO_f_prefix())) == NULL @@ -64,13 +62,13 @@ static int asn1_print_info(BIO *bp, long offset, int depth, int hl, long len, */ p = str; if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE) - BIO_snprintf(str, sizeof(str), "priv [ %d ] ", tag); + snprintf(str, sizeof(str), "priv [ %d ] ", tag); else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC) - BIO_snprintf(str, sizeof(str), "cont [ %d ]", tag); + snprintf(str, sizeof(str), "cont [ %d ]", tag); else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION) - BIO_snprintf(str, sizeof(str), "appl [ %d ]", tag); + snprintf(str, sizeof(str), "appl [ %d ]", tag); else if (tag > 30) - BIO_snprintf(str, sizeof(str), "", tag); + snprintf(str, sizeof(str), "", tag); else p = ASN1_tag2str(tag); diff --git a/crypto/asn1/asn_mime.c b/crypto/asn1/asn_mime.c index af79f27bdafe5..2316618744db6 100644 --- a/crypto/asn1/asn_mime.c +++ b/crypto/asn1/asn_mime.c @@ -81,9 +81,9 @@ int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, } if (!SMIME_crlf_copy(in, bio, flags)) { rv = 0; + } else if (BIO_flush(bio) <= 0) { + rv = 0; } - - (void)BIO_flush(bio); /* Free up successive BIOs until we hit the old output BIO */ do { tbio = BIO_pop(bio); diff --git a/crypto/asn1/bio_ndef.c b/crypto/asn1/bio_ndef.c index 5c20a1bc8de76..9986affae3d4e 100644 --- a/crypto/asn1/bio_ndef.c +++ b/crypto/asn1/bio_ndef.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,6 +11,7 @@ #include #include #include +#include "crypto/asn1.h" #include @@ -36,8 +37,11 @@ typedef struct ndef_aux_st { BIO *ndef_bio; /* Output BIO */ BIO *out; - /* Boundary where content is inserted */ - unsigned char **boundary; + /* + * Content octet string in which the encoder records where the content + * belongs. Borrowed from the caller. + */ + ASN1_STRING *content; /* DER buffer start */ unsigned char *derbuf; } NDEF_SUPPORT; @@ -52,8 +56,6 @@ static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, /* * On success, the returned BIO owns the input BIO as part of its BIO chain. * On failure, NULL is returned and the input BIO is owned by the caller. - * - * Unfortunately cannot constify this due to CMS_stream() and PKCS7_stream() */ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) { @@ -62,6 +64,7 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) const ASN1_AUX *aux = it->funcs; ASN1_STREAM_ARG sarg; BIO *pop_bio = NULL; + ASN1_STRING *content = NULL; if (!aux || !aux->asn1_cb) { ERR_raise(ERR_LIB_ASN1, ASN1_R_STREAMING_NOT_SUPPORTED); @@ -105,6 +108,12 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) goto err; } + if (aux->asn1_cb(ASN1_OP_GET0_STREAM_CONTENT, &val, it, &content) > 0 + && content != NULL) + content->flags |= ASN1_STRING_FLAG_NDEF; + else + content = NULL; /* Don't leave a junk borrowed pointer to play with */ + /* * We must not fail now because the callback has prepended additional * BIOs to the chain @@ -113,7 +122,7 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) ndef_aux->val = val; ndef_aux->it = it; ndef_aux->ndef_bio = sarg.ndef_bio; - ndef_aux->boundary = sarg.boundary; + ndef_aux->content = content; ndef_aux->out = out; return sarg.ndef_bio; @@ -130,7 +139,7 @@ static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg) { NDEF_SUPPORT *ndef_aux; unsigned char *p; - int derlen; + int derlen, outlen; if (parg == NULL) return 0; @@ -145,12 +154,14 @@ static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg) ndef_aux->derbuf = p; *pbuf = p; - ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it); + outlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it); + if (outlen != derlen || p != *pbuf + derlen) + return 0; - if (*ndef_aux->boundary == NULL) + if (ndef_aux->content == NULL || ndef_aux->content->data == NULL) return 0; - *plen = (int)(*ndef_aux->boundary - *pbuf); + *plen = (int)(ndef_aux->content->data - *pbuf); return 1; } @@ -191,7 +202,7 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg) { NDEF_SUPPORT *ndef_aux; unsigned char *p; - int derlen; + int derlen, outlen; const ASN1_AUX *aux; ASN1_STREAM_ARG sarg; @@ -205,7 +216,7 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg) /* Finalize structures */ sarg.ndef_bio = ndef_aux->ndef_bio; sarg.out = ndef_aux->out; - sarg.boundary = ndef_aux->boundary; + sarg.boundary = NULL; if (aux->asn1_cb(ASN1_OP_STREAM_POST, &ndef_aux->val, ndef_aux->it, &sarg) <= 0) @@ -219,12 +230,14 @@ static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg) ndef_aux->derbuf = p; *pbuf = p; - derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it); + outlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it); + if (outlen != derlen || p != *pbuf + derlen) + return 0; - if (*ndef_aux->boundary == NULL) + if (ndef_aux->content == NULL || ndef_aux->content->data == NULL) return 0; - *pbuf = *ndef_aux->boundary; - *plen = derlen - (int)(*ndef_aux->boundary - ndef_aux->derbuf); + *pbuf = ndef_aux->content->data; + *plen = derlen - (int)(ndef_aux->content->data - ndef_aux->derbuf); return 1; } diff --git a/crypto/asn1/build.info b/crypto/asn1/build.info index 4256f80e10b2f..38e883174af40 100644 --- a/crypto/asn1/build.info +++ b/crypto/asn1/build.info @@ -21,3 +21,7 @@ ENDIF IF[{- !$disabled{'deprecated-3.0'} -}] SOURCE[../../libcrypto]=x_long.c ENDIF + +DEPEND[a_strex.o]=charmap.h +GENERATE[charmap.h]=charmap.pl +INCLUDE[a_strex.o]=. diff --git a/crypto/asn1/charmap.h b/crypto/asn1/charmap.h deleted file mode 100644 index ca99f05b32568..0000000000000 --- a/crypto/asn1/charmap.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * WARNING: do not edit! - * Generated by crypto/asn1/charmap.pl - * - * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#if !defined(OSSL_LIBCRYPTO_ASN1_CHARMAP_H) -#define OSSL_LIBCRYPTO_ASN1_CHARMAP_H - -/* clang-format off */ -#define CHARTYPE_HOST_ANY 4096 -#define CHARTYPE_HOST_DOT 8192 -#define CHARTYPE_HOST_HYPHEN 16384 -#define CHARTYPE_HOST_WILD 32768 - -/* - * Mask of various character properties - */ - -static const unsigned short char_type[] = { - 1026, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 120, 0, 1, 40, - 0, 0, 0, 16, 1040, 1040, 33792, 25, 25, 16400, 8208, 16, - 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 16, 9, - 9, 16, 9, 16, 0, 4112, 4112, 4112, 4112, 4112, 4112, 4112, - 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, - 4112, 4112, 4112, 4112, 4112, 4112, 4112, 0, 1025, 0, 0, 0, - 0, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, - 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, - 4112, 4112, 4112, 0, 0, 0, 0, 2 -}; -/* clang-format on */ - -#endif /* !defined(OSSL_LIBCRYPTO_ASN1_CHARMAP_H) */ diff --git a/crypto/asn1/charmap.pl b/crypto/asn1/charmap.pl index 53add528254ab..a2a03d76a8b66 100644 --- a/crypto/asn1/charmap.pl +++ b/crypto/asn1/charmap.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/asn1/evp_asn1.c b/crypto/asn1/evp_asn1.c index 2d50dc657baca..6edcfa7440a6e 100644 --- a/crypto/asn1/evp_asn1.c +++ b/crypto/asn1/evp_asn1.c @@ -34,6 +34,7 @@ int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len) int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_len) { int ret, num; + size_t tmp; const unsigned char *p; if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL)) { @@ -41,7 +42,13 @@ int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_l return -1; } p = ASN1_STRING_get0_data(a->value.octet_string); - ret = ASN1_STRING_length(a->value.octet_string); + tmp = ASN1_STRING_get_length(a->value.octet_string); + if (tmp > INT_MAX) { + ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE); + return -1; + } + ret = (int)tmp; + if (ret < max_len) num = ret; else @@ -69,17 +76,25 @@ static ossl_inline void asn1_type_init_oct(ASN1_OCTET_STRING *oct, static int asn1_type_get_int_oct(ASN1_OCTET_STRING *oct, int32_t anum, long *num, unsigned char *data, int max_len) { - int ret = ASN1_STRING_length(oct), n; + int ret, n; + size_t tmp; if (num != NULL) *num = anum; + tmp = ASN1_STRING_get_length(oct); + + if (tmp > INT_MAX) + tmp = INT_MAX; + + ret = (int)tmp; + if (max_len > ret) n = ret; else n = max_len; - if (data != NULL) + if (data != NULL && n > 0) memcpy(data, ASN1_STRING_get0_data(oct), n); return ret; diff --git a/crypto/asn1/p5_scrypt.c b/crypto/asn1/p5_scrypt.c index 64980a1a68495..6d4ef040d91f1 100644 --- a/crypto/asn1/p5_scrypt.c +++ b/crypto/asn1/p5_scrypt.c @@ -173,7 +173,7 @@ static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, int saltlen, saltlen = PKCS5_DEFAULT_PBE2_SALT_LEN; /* This will either copy salt or grow the buffer */ - if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0) { + if (ossl_asn1_string_set1_data(sparam->salt, salt, saltlen) == 0) { ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); goto err; } diff --git a/crypto/asn1/p8_pkey.c b/crypto/asn1/p8_pkey.c index 143f503dea344..e2f23f4e13cbf 100644 --- a/crypto/asn1/p8_pkey.c +++ b/crypto/asn1/p8_pkey.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -72,11 +72,13 @@ int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg, const unsigned char **pk, int *ppklen, const X509_ALGOR **pa, const PKCS8_PRIV_KEY_INFO *p8) { + if (ASN1_STRING_get_length(p8->pkey) > INT_MAX) + return 0; if (ppkalg) *ppkalg = p8->pkeyalg->algorithm; if (pk) { *pk = ASN1_STRING_get0_data(p8->pkey); - *ppklen = ASN1_STRING_length(p8->pkey); + *ppklen = (int)ASN1_STRING_get_length(p8->pkey); } if (pa) *pa = p8->pkeyalg; diff --git a/crypto/asn1/t_bitst.c b/crypto/asn1/t_bitst.c index 4d691b304cb85..6862c0f4c8144 100644 --- a/crypto/asn1/t_bitst.c +++ b/crypto/asn1/t_bitst.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/asn1/tasn_dec.c b/crypto/asn1/tasn_dec.c index 197fd24105465..f1a08d27b103f 100644 --- a/crypto/asn1/tasn_dec.c +++ b/crypto/asn1/tasn_dec.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -983,7 +983,7 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len, ASN1_STRING_set0(stmp, (unsigned char *)cont /* UGLY CAST! */, ilen); *free_cont = 0; } else { - if (!ASN1_STRING_set(stmp, cont, ilen)) { + if (!ossl_asn1_string_set1_data(stmp, cont, len)) { ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB); ASN1_STRING_free(stmp); *pval = NULL; diff --git a/crypto/asn1/tasn_enc.c b/crypto/asn1/tasn_enc.c index e489e29a0c086..3307392a84efa 100644 --- a/crypto/asn1/tasn_enc.c +++ b/crypto/asn1/tasn_enc.c @@ -57,7 +57,7 @@ static int asn1_item_flags_i2d(const ASN1_VALUE *val, unsigned char **out, { if (out != NULL && *out == NULL) { unsigned char *p, *buf; - int len; + int len, outlen; len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags); if (len <= 0) @@ -65,7 +65,11 @@ static int asn1_item_flags_i2d(const ASN1_VALUE *val, unsigned char **out, if ((buf = OPENSSL_malloc(len)) == NULL) return -1; p = buf; - ASN1_item_ex_i2d(&val, &p, it, -1, flags); + outlen = ASN1_item_ex_i2d(&val, &p, it, -1, flags); + if (outlen != len || p != buf + len) { + OPENSSL_free(buf); + return -1; + } *out = buf; return len; } @@ -172,7 +176,7 @@ int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, return 0; pseqval = ossl_asn1_get_const_field_ptr(pval, seqtt); tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, aclass); - if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen)) + if (tmplen < 0 || (tmplen > INT_MAX - seqcontlen)) return -1; seqcontlen += tmplen; } @@ -185,12 +189,15 @@ int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { const ASN1_TEMPLATE *seqtt; const ASN1_VALUE **pseqval; + int tmplen; + seqtt = ossl_asn1_do_adb(*pval, tt, 1); if (!seqtt) return 0; pseqval = ossl_asn1_get_const_field_ptr(pval, seqtt); - /* FIXME: check for errors in enhanced version */ - asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass); + tmplen = asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass); + if (tmplen < 0) + return -1; } if (ndef == 2) ASN1_put_eoc(out); @@ -210,6 +217,7 @@ static int asn1_template_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, const int flags = tt->flags; int i, ret, ttag, tclass, ndef, len; const ASN1_VALUE *tval; + unsigned char *p; /* * If field is embedded then val needs fixing so it is a pointer to @@ -297,7 +305,7 @@ static int asn1_template_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, skitem = sk_const_ASN1_VALUE_value(sk, i); len = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass); - if (len == -1 || (skcontlen > INT_MAX - len)) + if (len < 0 || (skcontlen > INT_MAX - len)) return -1; if (len == 0 && (tt->flags & ASN1_TFLG_OPTIONAL) == 0) { ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT); @@ -324,8 +332,9 @@ static int asn1_template_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, /* SET or SEQUENCE and IMPLICIT tag */ ASN1_put_object(out, ndef, skcontlen, sktag, skaclass); /* And the stuff itself */ - asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), - isset, iclass); + if (!asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), + isset, iclass)) + return -1; if (ndef == 2) { ASN1_put_eoc(out); if (flags & ASN1_TFLG_EXPTAG) @@ -339,6 +348,8 @@ static int asn1_template_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, /* EXPLICIT tagging */ /* Find length of tagged item */ i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass); + if (i < 0) + return -1; if (i == 0) { if ((tt->flags & ASN1_TFLG_OPTIONAL) == 0) { ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_ZERO_CONTENT); @@ -351,7 +362,11 @@ static int asn1_template_ex_i2d(const ASN1_VALUE **pval, unsigned char **out, if (out && ret != -1) { /* Output tag and item */ ASN1_put_object(out, ndef, i, ttag, tclass); - ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass); + p = *out; + len = ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, + iclass); + if (len != i || *out != p + i) + return -1; if (ndef == 2) ASN1_put_eoc(out); } @@ -417,7 +432,8 @@ static int asn1_set_seq_out(STACK_OF(const_ASN1_VALUE) *sk, if (!do_sort) { for (i = 0; i < sk_const_ASN1_VALUE_num(sk); i++) { skitem = sk_const_ASN1_VALUE_value(sk, i); - ASN1_item_ex_i2d(&skitem, out, item, -1, iclass); + if (ASN1_item_ex_i2d(&skitem, out, item, -1, iclass) <= 0) + return 0; } return 1; } @@ -428,6 +444,8 @@ static int asn1_set_seq_out(STACK_OF(const_ASN1_VALUE) *sk, skitem = sk_const_ASN1_VALUE_value(sk, i); tder->data = p; tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass); + if (tder->length <= 0) + goto err; tder->field = skitem; } diff --git a/crypto/asn1/tasn_fre.c b/crypto/asn1/tasn_fre.c index df2411157802c..711435dea26be 100644 --- a/crypto/asn1/tasn_fre.c +++ b/crypto/asn1/tasn_fre.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/asn1/tasn_prn.c b/crypto/asn1/tasn_prn.c index 72922c6530ab6..1cc548650b60a 100644 --- a/crypto/asn1/tasn_prn.c +++ b/crypto/asn1/tasn_prn.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/asn1/tasn_utl.c b/crypto/asn1/tasn_utl.c index a4ab762960193..e0bab2dec71dc 100644 --- a/crypto/asn1/tasn_utl.c +++ b/crypto/asn1/tasn_utl.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -169,11 +169,14 @@ int ossl_asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, long inlen, if (enc == NULL) return 1; + /* A failure below leaves the item without a cached encoding */ OPENSSL_free(enc->enc); - if (inlen <= 0) { - enc->enc = NULL; + enc->enc = NULL; + enc->len = 0; + enc->modified = 1; + + if (inlen <= 0) return 0; - } if ((enc->enc = OPENSSL_malloc(inlen)) == NULL) return 0; memcpy(enc->enc, in, inlen); diff --git a/crypto/asn1/tbl_standard.h b/crypto/asn1/tbl_standard.h index 41af74e27a1be..e08f3cd7611c3 100644 --- a/crypto/asn1/tbl_standard.h +++ b/crypto/asn1/tbl_standard.h @@ -1,5 +1,5 @@ /* - * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/asn1/x_algor.c b/crypto/asn1/x_algor.c index 5050adb8f15c6..4d7e5f6a0a2c0 100644 --- a/crypto/asn1/x_algor.c +++ b/crypto/asn1/x_algor.c @@ -87,12 +87,25 @@ void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, /* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */ int X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md) { - int type = md->flags & EVP_MD_FLAG_DIGALGID_ABSENT ? V_ASN1_UNDEF - : V_ASN1_NULL; - int md_type = EVP_MD_type(md); + int type, md_type; + ASN1_OBJECT *obj; - ASN1_OBJECT *obj = (md_type == NID_undef) ? OBJ_txt2obj(EVP_MD_get0_name(md), 0) : OBJ_nid2obj(md_type); - return X509_ALGOR_set0(alg, obj, type, NULL); + if (alg == NULL || md == NULL) + return 0; + + type = md->flags & EVP_MD_FLAG_DIGALGID_ABSENT ? V_ASN1_UNDEF + : V_ASN1_NULL; + md_type = EVP_MD_type(md); + + obj = (md_type == NID_undef) ? OBJ_txt2obj(EVP_MD_get0_name(md), 0) + : OBJ_nid2obj(md_type); + if (obj == NULL) + return 0; + if (!X509_ALGOR_set0(alg, obj, type, NULL)) { + ASN1_OBJECT_free(obj); + return 0; + } + return 1; } int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b) diff --git a/crypto/asn1/x_int64.c b/crypto/asn1/x_int64.c index 9f2a3aedc2ada..715e9fad42ce9 100644 --- a/crypto/asn1/x_int64.c +++ b/crypto/asn1/x_int64.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/async/arch/async_posix.c b/crypto/async/arch/async_posix.c index 46e2ce7559cd5..4f6db7e5be312 100644 --- a/crypto/async/arch/async_posix.c +++ b/crypto/async/arch/async_posix.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -116,7 +116,11 @@ int async_fibre_makecontext(async_fibre *fibre) if (fibre->fibre.uc_stack.ss_sp != NULL) { fibre->fibre.uc_stack.ss_size = num; fibre->fibre.uc_link = NULL; +#ifndef __e2k__ makecontext(&fibre->fibre, async_start_func, 0); +#else + makecontext_e2k(&fibre->fibre, async_start_func, 0); +#endif return 1; } } else { @@ -129,6 +133,9 @@ void async_fibre_free(async_fibre *fibre) { stack_free_impl(fibre->fibre.uc_stack.ss_sp); fibre->fibre.uc_stack.ss_sp = NULL; +#ifdef __e2k__ + freecontext_e2k(&fibre->fibre); +#endif } #endif diff --git a/crypto/async/arch/async_win.c b/crypto/async/arch/async_win.c index 2ca4ed6a93190..67137ce7f5156 100644 --- a/crypto/async/arch/async_win.c +++ b/crypto/async/arch/async_win.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/async/async_err.c b/crypto/async/async_err.c deleted file mode 100644 index 1e28eb78234bc..0000000000000 --- a/crypto/async/async_err.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/asyncerr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA ASYNC_str_reasons[] = { - { ERR_PACK(ERR_LIB_ASYNC, 0, ASYNC_R_FAILED_TO_SET_POOL), - "failed to set pool" }, - { ERR_PACK(ERR_LIB_ASYNC, 0, ASYNC_R_FAILED_TO_SWAP_CONTEXT), - "failed to swap context" }, - { ERR_PACK(ERR_LIB_ASYNC, 0, ASYNC_R_INIT_FAILED), "init failed" }, - { ERR_PACK(ERR_LIB_ASYNC, 0, ASYNC_R_INVALID_POOL_SIZE), - "invalid pool size" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_ASYNC_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(ASYNC_str_reasons[0].error) == NULL) - ERR_load_strings_const(ASYNC_str_reasons); -#endif - return 1; -} diff --git a/crypto/async/async_local.h b/crypto/async/async_local.h index f10a6745f8824..ce9e082fb85be 100644 --- a/crypto/async/async_local.h +++ b/crypto/async/async_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bf/bf_cfb64.c b/crypto/bf/bf_cfb64.c index cec20b9158480..f2d42eefba802 100644 --- a/crypto/bf/bf_cfb64.c +++ b/crypto/bf/bf_cfb64.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bf/bf_local.h b/crypto/bf/bf_local.h index c9c6d53f9ef86..8185dc6fc3618 100644 --- a/crypto/bf/bf_local.h +++ b/crypto/bf/bf_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bf/bf_ofb64.c b/crypto/bf/bf_ofb64.c index dbd60d18535c7..2cd339dd27eb6 100644 --- a/crypto/bf/bf_ofb64.c +++ b/crypto/bf/bf_ofb64.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bf/bf_pi.h b/crypto/bf/bf_pi.h index 1419a5cf4a7ac..1396a0e194b83 100644 --- a/crypto/bf/bf_pi.h +++ b/crypto/bf/bf_pi.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bio/bf_buff.c b/crypto/bio/bf_buff.c index c7d4c34f5070f..9ad00826ae23a 100644 --- a/crypto/bio/bf_buff.c +++ b/crypto/bio/bf_buff.c @@ -20,6 +20,12 @@ static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2); static int buffer_new(BIO *h); static int buffer_free(BIO *data); static long buffer_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp); +static int buffer_sendmmsg(BIO *b, BIO_MSG *msg, size_t stride, + size_t num_msg, uint64_t flags, + size_t *msgs_processed); +static int buffer_send_next(BIO *b, BIO_F_BUFFER_CTX *ctx, + const char *data, int len); + #define DEFAULT_BUFFER_SIZE 4096 static const BIO_METHOD methods_buffer = { @@ -35,6 +41,7 @@ static const BIO_METHOD methods_buffer = { buffer_new, buffer_free, buffer_callback_ctrl, + buffer_sendmmsg, }; const BIO_METHOD *BIO_f_buffer(void) @@ -77,6 +84,9 @@ static int buffer_free(BIO *a) b = (BIO_F_BUFFER_CTX *)a->ptr; OPENSSL_free(b->ibuf); OPENSSL_free(b->obuf); +#ifndef OPENSSL_NO_SOCK + BIO_ADDR_free(b->peer); +#endif OPENSSL_free(a->ptr); a->ptr = NULL; a->init = 0; @@ -187,7 +197,7 @@ static int buffer_write(BIO *b, const char *in, int inl) } /* we now have a full buffer needing flushing */ for (;;) { - i = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]), + i = buffer_send_next(b, ctx, &(ctx->obuf[ctx->obuf_off]), ctx->obuf_len); if (i <= 0) { BIO_copy_next_retry(b); @@ -211,7 +221,7 @@ static int buffer_write(BIO *b, const char *in, int inl) /* we now have inl bytes to write */ while (inl >= ctx->obuf_size) { - i = BIO_write(b->next_bio, in, inl); + i = buffer_send_next(b, ctx, in, inl); if (i <= 0) { BIO_copy_next_retry(b); if (i < 0) @@ -249,6 +259,10 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) ctx->ibuf_len = 0; ctx->obuf_off = 0; ctx->obuf_len = 0; +#ifndef OPENSSL_NO_SOCK + BIO_ADDR_free(ctx->peer); + ctx->peer = NULL; +#endif if (b->next_bio == NULL) return 0; ret = BIO_ctrl(b->next_bio, cmd, num, ptr); @@ -351,6 +365,10 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) ctx->obuf_off = 0; ctx->obuf_len = 0; ctx->obuf_size = obs; +#ifndef OPENSSL_NO_SOCK + BIO_ADDR_free(ctx->peer); + ctx->peer = NULL; +#endif } break; case BIO_C_DO_STATE_MACHINE: @@ -373,8 +391,8 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) for (;;) { BIO_clear_retry_flags(b); if (ctx->obuf_len > 0) { - r = BIO_write(b->next_bio, - &(ctx->obuf[ctx->obuf_off]), ctx->obuf_len); + r = buffer_send_next(b, ctx, &(ctx->obuf[ctx->obuf_off]), + ctx->obuf_len); BIO_copy_next_retry(b); if (r <= 0) return (long)r; @@ -388,6 +406,10 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) } ret = BIO_ctrl(b->next_bio, cmd, num, ptr); BIO_copy_next_retry(b); +#ifndef OPENSSL_NO_SOCK + BIO_ADDR_free(ctx->peer); + ctx->peer = NULL; +#endif break; case BIO_CTRL_DUP: dbio = (BIO *)ptr; @@ -476,3 +498,105 @@ static int buffer_puts(BIO *b, const char *str) return -1; return buffer_write(b, str, (int)len); } + +/* + * buffer_send_next - write one chunk of buffered output to the next BIO. + * + * For listener-created datagram connections a peer address has been recorded and + * such connections share a single network BIO, so the data must be sent with + * BIO_sendmmsg() carrying the explicit peer address rather than BIO_write(). + * + * Returns the number of bytes sent - the full len for the datagram case, which + * is all-or-nothing - or 0 / a negative value on a transient or fatal error. + */ +static int buffer_send_next(BIO *b, BIO_F_BUFFER_CTX *ctx, + const char *data, int len) +{ +#ifndef OPENSSL_NO_SOCK + if (ctx->peer != NULL) { + BIO_MSG msg; + size_t processed = 0; + + memset(&msg, 0, sizeof(msg)); + msg.data = (void *)data; + msg.data_len = (size_t)len; + msg.peer = ctx->peer; + + /* Datagrams are all-or-nothing: either the whole chunk goes or none. */ + if (!BIO_sendmmsg(b->next_bio, &msg, sizeof(msg), 1, 0, &processed) + || processed != 1) + return -1; + return len; + } +#endif + return BIO_write(b->next_bio, data, len); +} + +/* + * buffer_sendmmsg - accumulate a message into the buffer BIO. + * + * Listener-created DTLS connections share a single network BIO and so cannot + * use BIO_write(). Instead the record layer sends each record via BIO_sendmmsg(), + * which lands here. We record the peer address and then buffer the data exactly + * like buffer_write() does, so that multiple handshake records accumulate and are + * packed into a single datagram when the state machine flushes. + */ +static int buffer_sendmmsg(BIO *b, BIO_MSG *msg, size_t stride, + size_t num_msg, uint64_t flags, + size_t *msgs_processed) +{ +#ifndef OPENSSL_NO_SOCK + BIO_F_BUFFER_CTX *ctx; + size_t i; + + *msgs_processed = 0; + + if (b == NULL || b->next_bio == NULL) + return 0; + + ctx = (BIO_F_BUFFER_CTX *)b->ptr; + if (ctx == NULL || msg == NULL || num_msg == 0) + return 0; + + /* + * Record the peer address on the first write so the flush path knows + * where to send the accumulated data. The address is cleared after each + * flush so it can be set again for the next batch. + */ + if (ctx->peer == NULL) { + if (msg->peer == NULL) + return 0; + ctx->peer = BIO_ADDR_new(); + if (ctx->peer == NULL) + return 0; + if (!BIO_ADDR_copy(ctx->peer, msg->peer)) { + BIO_ADDR_free(ctx->peer); + ctx->peer = NULL; + return 0; + } + } + + for (i = 0; i < num_msg; i++) { + BIO_MSG *m = (BIO_MSG *)((char *)msg + i * stride); + int ret; + + /* + * Buffer the message data. buffer_write() takes an int length, so + * guard against an oversized datagram (this mirrors buffer_puts()). + */ + if (m->data_len > INT_MAX) + break; + + ret = buffer_write(b, m->data, (int)m->data_len); + if (ret <= 0) + break; + + ++(*msgs_processed); + } + + return (*msgs_processed > 0) ? 1 : 0; +#else + *msgs_processed = 0; + return 0; +#endif +} diff --git a/crypto/bio/bio_addr.c b/crypto/bio/bio_addr.c index a53ec7047f71f..f1adbf99b4479 100644 --- a/crypto/bio/bio_addr.c +++ b/crypto/bio/bio_addr.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -22,6 +22,7 @@ #undef UNICODE #include +#include #include #include "bio_local.h" @@ -265,7 +266,7 @@ static int addr_strings(const BIO_ADDR *ap, int numeric, * didn't go the way one might expect. */ if (serv[0] == '\0') { - BIO_snprintf(serv, sizeof(serv), "%d", + snprintf(serv, sizeof(serv), "%d", ntohs(BIO_ADDR_rawport(ap))); } @@ -279,7 +280,7 @@ static int addr_strings(const BIO_ADDR *ap, int numeric, *hostname = OPENSSL_strdup(inet_ntoa(ap->s_in.sin_addr)); if (service != NULL) { char serv[6]; /* port is 16 bits => max 5 decimal digits */ - BIO_snprintf(serv, sizeof(serv), "%d", ntohs(ap->s_in.sin_port)); + snprintf(serv, sizeof(serv), "%d", ntohs(ap->s_in.sin_port)); *service = OPENSSL_strdup(serv); } } @@ -629,7 +630,12 @@ static int addrinfo_wrap(int family, int socktype, all right. */ BIO_ADDR *addr = BIO_ADDR_new(); if (addr != NULL) { - BIO_ADDR_rawmake(addr, family, where, wherelen, port); + if (!BIO_ADDR_rawmake(addr, family, where, wherelen, port)) { + BIO_ADDR_free(addr); + BIO_ADDRINFO_free(*bai); + *bai = NULL; + return 0; + } (*bai)->bai_addr = BIO_ADDR_sockaddr_noconst(addr); } } diff --git a/crypto/bio/bio_cb.c b/crypto/bio/bio_cb.c index db7b6d1b2f774..c95545c91179a 100644 --- a/crypto/bio/bio_cb.c +++ b/crypto/bio/bio_cb.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -30,82 +30,82 @@ long BIO_debug_callback_ex(BIO *bio, int cmd, const char *argp, size_t len, if (processed != NULL) l = *processed; - left = BIO_snprintf(buf, sizeof(buf), "BIO[%p]: ", (void *)bio); + left = snprintf(buf, sizeof(buf), "BIO[%p]: ", (void *)bio); /* Ignore errors and continue printing the other information. */ - if (left < 0) + if (left < 0 || (size_t)left >= sizeof(buf)) left = 0; p = buf + left; left = sizeof(buf) - left; switch (cmd) { case BIO_CB_FREE: - BIO_snprintf(p, left, "Free - %s\n", bio->method->name); + snprintf(p, left, "Free - %s\n", bio->method->name); break; case BIO_CB_READ: if (bio->method->type & BIO_TYPE_DESCRIPTOR) - BIO_snprintf(p, left, "read(%d,%zu) - %s fd=%d\n", + snprintf(p, left, "read(%d,%zu) - %s fd=%d\n", bio->num, len, bio->method->name, bio->num); else - BIO_snprintf(p, left, "read(%d,%zu) - %s\n", + snprintf(p, left, "read(%d,%zu) - %s\n", bio->num, len, bio->method->name); break; case BIO_CB_WRITE: if (bio->method->type & BIO_TYPE_DESCRIPTOR) - BIO_snprintf(p, left, "write(%d,%zu) - %s fd=%d\n", + snprintf(p, left, "write(%d,%zu) - %s fd=%d\n", bio->num, len, bio->method->name, bio->num); else - BIO_snprintf(p, left, "write(%d,%zu) - %s\n", + snprintf(p, left, "write(%d,%zu) - %s\n", bio->num, len, bio->method->name); break; case BIO_CB_PUTS: - BIO_snprintf(p, left, "puts() - %s\n", bio->method->name); + snprintf(p, left, "puts() - %s\n", bio->method->name); break; case BIO_CB_GETS: - BIO_snprintf(p, left, "gets(%zu) - %s\n", len, + snprintf(p, left, "gets(%zu) - %s\n", len, bio->method->name); break; case BIO_CB_CTRL: - BIO_snprintf(p, left, "ctrl(%d) - %s\n", argi, + snprintf(p, left, "ctrl(%d) - %s\n", argi, bio->method->name); break; case BIO_CB_RECVMMSG: args = (BIO_MMSG_CB_ARGS *)argp; - BIO_snprintf(p, left, "recvmmsg(%zu) - %s", + snprintf(p, left, "recvmmsg(%zu) - %s", args->num_msg, bio->method->name); break; case BIO_CB_SENDMMSG: args = (BIO_MMSG_CB_ARGS *)argp; - BIO_snprintf(p, left, "sendmmsg(%zu) - %s", + snprintf(p, left, "sendmmsg(%zu) - %s", args->num_msg, bio->method->name); break; case BIO_CB_RETURN | BIO_CB_READ: - BIO_snprintf(p, left, "read return %d processed: %zu\n", ret, l); + snprintf(p, left, "read return %d processed: %zu\n", ret, l); break; case BIO_CB_RETURN | BIO_CB_WRITE: - BIO_snprintf(p, left, "write return %d processed: %zu\n", ret, l); + snprintf(p, left, "write return %d processed: %zu\n", ret, l); break; case BIO_CB_RETURN | BIO_CB_GETS: - BIO_snprintf(p, left, "gets return %d processed: %zu\n", ret, l); + snprintf(p, left, "gets return %d processed: %zu\n", ret, l); break; case BIO_CB_RETURN | BIO_CB_PUTS: - BIO_snprintf(p, left, "puts return %d processed: %zu\n", ret, l); + snprintf(p, left, "puts return %d processed: %zu\n", ret, l); break; case BIO_CB_RETURN | BIO_CB_CTRL: - BIO_snprintf(p, left, "ctrl return %d\n", ret); + snprintf(p, left, "ctrl return %d\n", ret); break; case BIO_CB_RETURN | BIO_CB_RECVMMSG: - BIO_snprintf(p, left, "recvmmsg processed: %zu\n", len); + snprintf(p, left, "recvmmsg processed: %zu\n", len); ret_ = (long)len; break; case BIO_CB_RETURN | BIO_CB_SENDMMSG: - BIO_snprintf(p, left, "sendmmsg processed: %zu\n", len); + snprintf(p, left, "sendmmsg processed: %zu\n", len); ret_ = (long)len; break; default: - BIO_snprintf(p, left, "bio callback - unknown type (%d)\n", cmd); + snprintf(p, left, "bio callback - unknown type (%d)\n", cmd); break; } diff --git a/crypto/bio/bio_dump.c b/crypto/bio/bio_dump.c index d03485c7978e5..aa1daf71efbcc 100644 --- a/crypto/bio/bio_dump.c +++ b/crypto/bio/bio_dump.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -45,9 +45,9 @@ int BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u), if ((rows * dump_width) < len) rows++; for (i = 0; i < rows; i++) { - n = BIO_snprintf(buf, sizeof(buf), "%*s%04x - ", indent, "", + n = snprintf(buf, sizeof(buf), "%*s%04x - ", indent, "", i * dump_width); - if (n < 0) + if (n < 0 || (size_t)n >= sizeof(buf)) return -1; for (j = 0; j < dump_width; j++) { if (SPACE(buf, n, 3)) { @@ -55,7 +55,7 @@ int BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u), strcpy(buf + n, " "); } else { ch = *(s + i * dump_width + j) & 0xff; - BIO_snprintf(buf + n, 4, "%02x%c", ch, + snprintf(buf + n, 4, "%02x%c", ch, j == 7 ? '-' : ' '); } n += 3; diff --git a/crypto/bio/bio_err.c b/crypto/bio/bio_err.c deleted file mode 100644 index e2ccb09eb35c8..0000000000000 --- a/crypto/bio/bio_err.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/bioerr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA BIO_str_reasons[] = { - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ACCEPT_ERROR), "accept error" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET), - "addrinfo addr is not af inet" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_AMBIGUOUS_HOST_OR_SERVICE), - "ambiguous host or service" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BAD_FOPEN_MODE), "bad fopen mode" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_BROKEN_PIPE), "broken pipe" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_ERROR), "connect error" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_CONNECT_TIMEOUT), "connect timeout" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET), - "gethostbyname addr is not af inet" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETSOCKNAME_ERROR), "getsockname error" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS), - "getsockname truncated address" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_GETTING_SOCKTYPE), "getting socktype" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_INVALID_ARGUMENT), "invalid argument" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_INVALID_SOCKET), "invalid socket" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_IN_USE), "in use" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_LENGTH_TOO_LONG), "length too long" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_LISTEN_V6_ONLY), "listen v6 only" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_LOOKUP_RETURNED_NOTHING), - "lookup returned nothing" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_MALFORMED_HOST_OR_SERVICE), - "malformed host or service" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NBIO_CONNECT_ERROR), "nbio connect error" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED), - "no accept addr or service specified" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED), - "no hostname or service specified" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_PORT_DEFINED), "no port defined" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NO_SUCH_FILE), "no such file" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_PORT_MISMATCH), "port mismatch" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TFO_DISABLED), "tfo disabled" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TFO_NO_KERNEL_SUPPORT), - "tfo no kernel support" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_ERROR), "transfer error" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_TRANSFER_TIMEOUT), "transfer timeout" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_BIND_SOCKET), - "unable to bind socket" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_CREATE_SOCKET), - "unable to create socket" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_KEEPALIVE), - "unable to keepalive" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_LISTEN_SOCKET), - "unable to listen socket" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_NODELAY), "unable to nodelay" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_REUSEADDR), - "unable to reuseaddr" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNABLE_TO_TFO), "unable to tfo" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNAVAILABLE_IP_FAMILY), - "unavailable ip family" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNINITIALIZED), "uninitialized" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNKNOWN_INFO_TYPE), "unknown info type" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNSUPPORTED_IP_FAMILY), - "unsupported ip family" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNSUPPORTED_METHOD), "unsupported method" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_UNSUPPORTED_PROTOCOL_FAMILY), - "unsupported protocol family" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_WRITE_TO_READ_ONLY_BIO), - "write to read only BIO" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_WSASTARTUP), "WSAStartup" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_LOCAL_ADDR_NOT_AVAILABLE), - "local address not available" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_PEER_ADDR_NOT_AVAILABLE), - "peer address not available" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_NON_FATAL), - "non-fatal or transient error" }, - { ERR_PACK(ERR_LIB_BIO, 0, BIO_R_PORT_MISMATCH), - "port mismatch" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_BIO_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(BIO_str_reasons[0].error) == NULL) - ERR_load_strings_const(BIO_str_reasons); -#endif - return 1; -} diff --git a/crypto/bio/bio_lib.c b/crypto/bio/bio_lib.c index dbd55c8b2f0aa..6066cc0d8c177 100644 --- a/crypto/bio/bio_lib.c +++ b/crypto/bio/bio_lib.c @@ -193,7 +193,7 @@ int BIO_up_ref(BIO *a) { int i; - if (CRYPTO_UP_REF(&a->references, &i) <= 0) + if (!CRYPTO_UP_REF(&a->references, &i)) return 0; REF_PRINT_COUNT("BIO", i, a); diff --git a/crypto/bio/bio_local.h b/crypto/bio/bio_local.h index 87227e4f8f2ef..d710b3a559d46 100644 --- a/crypto/bio/bio_local.h +++ b/crypto/bio/bio_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2005-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -97,6 +97,9 @@ typedef struct bio_f_buffer_ctx_struct { char *obuf; /* the char array */ int obuf_len; /* how many bytes are in it */ int obuf_off; /* write/read offset */ +#ifndef OPENSSL_NO_SOCK + BIO_ADDR *peer; +#endif } BIO_F_BUFFER_CTX; struct bio_st { diff --git a/crypto/bio/bio_print.c b/crypto/bio/bio_print.c index 5366587a2a22b..3585481ee4c29 100644 --- a/crypto/bio/bio_print.c +++ b/crypto/bio/bio_print.c @@ -28,88 +28,35 @@ int BIO_printf(BIO *bio, const char *format, ...) return ret; } -#if defined(_MSC_VER) && _MSC_VER < 1900 -/* - * _MSC_VER described here: - * https://learn.microsoft.com/en-us/cpp/overview/compiler-versions?view=msvc-170 - * - * Beginning with the UCRT in Visual Studio 2015 and Windows 10, snprintf is no - * longer identical to _snprintf. The snprintf behavior is now C99 standard - * conformant. The difference is that if you run out of buffer, snprintf - * null-terminates the end of the buffer and returns the number of characters - * that would have been required whereas _snprintf doesn't null-terminate the - * buffer and returns -1. Also, snprintf() includes one more character in the - * output because it doesn't null-terminate the buffer. - * [ https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/snprintf-snprintf-snprintf-l-snwprintf-snwprintf-l?view=msvc-170#remarks - * - * for older MSVC (older than 2015) we can use _vscprintf() and _vsnprintf() - * as suggested here: - * https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 - * - */ -static int msvc_bio_vprintf(BIO *bio, const char *format, va_list args) -{ - char buf[512]; - char *abuf; - int ret, sz; - - sz = _vsnprintf_s(buf, sizeof(buf), _TRUNCATE, format, args); - if (sz == -1) { - sz = _vscprintf(format, args) + 1; - abuf = (char *)OPENSSL_malloc(sz); - if (abuf == NULL) { - ret = -1; - } else { - sz = _vsnprintf(abuf, sz, format, args); - ret = BIO_write(bio, abuf, sz); - OPENSSL_free(abuf); - } - } else { - ret = BIO_write(bio, buf, sz); - } - - return ret; -} -#endif - -#ifdef _MSC_VER -/* - * This function is for unit test on windows only when built with Visual Studio - */ -int ossl_BIO_snprintf_msvc(char *buf, size_t n, const char *format, ...) -{ - va_list args; - int ret; - - va_start(args, format); - ret = _vsnprintf_s(buf, n, _TRUNCATE, format, args); - va_end(args); - - return ret; -} -#endif - int BIO_vprintf(BIO *bio, const char *format, va_list args) { va_list cp_args; -#if !defined(_MSC_VER) || _MSC_VER >= 1900 int sz; -#endif int ret = -1; + char buf[512]; + char *abuf; +#if defined(_MSC_VER) && _MSC_VER < 1900 + char *msvc_fmt_alloc = NULL; +#endif + const char *fmt; - va_copy(cp_args, args); #if defined(_MSC_VER) && _MSC_VER < 1900 - ret = msvc_bio_vprintf(bio, format, cp_args); + /* Fix MSVC 2013 format to accept C99 format strings */ + if (!msvc_translate_printf_format(format, &fmt, &msvc_fmt_alloc)) + goto done; #else - char buf[512]; - char *abuf; + fmt = format; +#endif + + va_copy(cp_args, args); + /* * some compilers modify va_list, hence each call to v*printf() * should operate with its own instance of va_list. The first * call to vsnprintf() here uses args we got in function argument. * The second call is going to use cp_args we made earlier. */ - sz = vsnprintf(buf, sizeof(buf), format, args); + sz = vsnprintf(buf, sizeof(buf), fmt, args); if (sz >= 0) { if ((size_t)sz >= sizeof(buf)) { sz += 1; @@ -117,7 +64,7 @@ int BIO_vprintf(BIO *bio, const char *format, va_list args) if (abuf == NULL) { ret = -1; } else { - sz = vsnprintf(abuf, sz, format, cp_args); + sz = vsnprintf(abuf, sz, fmt, cp_args); ret = BIO_write(bio, abuf, sz); OPENSSL_free(abuf); } @@ -126,17 +73,20 @@ int BIO_vprintf(BIO *bio, const char *format, va_list args) ret = BIO_write(bio, buf, sz); } } -#endif va_end(cp_args); +#if defined(_MSC_VER) && _MSC_VER < 1900 +done: + OPENSSL_free(msvc_fmt_alloc); +#endif return ret; } +#ifndef OPENSSL_NO_DEPRECATED_4_1 /* - * For historical reasons BIO_snprintf and friends return a failure for string - * truncation (-1) instead of the POSIX requirement of a success with the - * number of characters that would have been written. Upon seeing -1 on - * return, the caller must treat output buf as unsafe (as a buf with missing - * nul terminator). + * For historical reasons BIO_snprintf and friends return -1 on truncation + * instead of the C99 snprintf semantic of returning the number of characters + * that would have been written. Deprecated in 4.1; new code should call + * snprintf() / vsnprintf() directly. */ int BIO_snprintf(char *buf, size_t n, const char *format, ...) { @@ -145,13 +95,9 @@ int BIO_snprintf(char *buf, size_t n, const char *format, ...) va_start(args, format); -#if defined(_MSC_VER) && _MSC_VER < 1900 - ret = _vsnprintf_s(buf, n, _TRUNCATE, format, args); -#else ret = vsnprintf(buf, n, format, args); if ((size_t)ret >= n) ret = -1; -#endif va_end(args); return ret; @@ -161,12 +107,10 @@ int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) { int ret; -#if defined(_MSC_VER) && _MSC_VER < 1900 - ret = _vsnprintf_s(buf, n, _TRUNCATE, format, args); -#else ret = vsnprintf(buf, n, format, args); if ((size_t)ret >= n) ret = -1; -#endif + return ret; } +#endif /* OPENSSL_NO_DEPRECATED_4_1 */ diff --git a/crypto/bio/bio_sock.c b/crypto/bio/bio_sock.c index 44e8f622aefa6..ef8376eb1b86e 100644 --- a/crypto/bio/bio_sock.c +++ b/crypto/bio/bio_sock.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -437,7 +437,7 @@ int BIO_socket_wait(int fd, int for_read, time_t max_time) time_t now; #ifdef _WIN32 - if (fd == INVALID_SOCKET) + if (fd == (int)INVALID_SOCKET) #else if (fd < 0 || fd >= FD_SETSIZE) #endif @@ -473,4 +473,41 @@ int BIO_socket_wait(int fd, int for_read, time_t max_time) return poll(&confds, 1, (int)(max_time - now) * 1000); #endif } + +/* + * Check if fd is ready for reading or writing without blocking. + * If for_read == 0 then check for writing, else check for reading. + * Returns -1 on error, 0 if not ready, and 1 if ready. + */ +int BIO_socket_ready(int fd, int for_read) +{ +#if defined(OPENSSL_SYS_WINDOWS) || !defined(POLLIN) + fd_set confds; + struct timeval tv; + +#ifdef _WIN32 + if (fd == (int)INVALID_SOCKET) +#else + if (fd < 0 || fd >= FD_SETSIZE) +#endif + return -1; + + FD_ZERO(&confds); + openssl_fdset(fd, &confds); + tv.tv_sec = 0; + tv.tv_usec = 0; + return select(fd + 1, for_read ? &confds : NULL, + for_read ? NULL : &confds, NULL, &tv); +#else + struct pollfd confds; + + if (fd < 0) + return -1; + + confds.fd = fd; + confds.events = for_read ? POLLIN : POLLOUT; + confds.revents = 0; + return poll(&confds, 1, 0); +#endif +} #endif /* !defined(OPENSSL_NO_SOCK) */ diff --git a/crypto/bio/bss_dgram_pair.c b/crypto/bio/bss_dgram_pair.c index d0136b4afc6a1..4e631342ff757 100644 --- a/crypto/bio/bss_dgram_pair.c +++ b/crypto/bio/bss_dgram_pair.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,9 +12,12 @@ #include "bio_local.h" #include "internal/cryptlib.h" #include "internal/safe_math.h" +#include "internal/threads_common.h" #if !defined(OPENSSL_NO_DGRAM) && !defined(OPENSSL_NO_SOCK) +#define is_dgram_pair(b) (b->pair != NULL) + OSSL_SAFE_MATH_UNSIGNED(size_t, size_t) /* =========================================================================== @@ -191,7 +194,7 @@ static int dgram_pair_recvmmsg(BIO *b, BIO_MSG *msg, size_t stride, size_t *num_processed); static int dgram_pair_ctrl_destroy_bio_pair(BIO *bio1); -static size_t dgram_pair_read_inner(struct bio_dgram_pair_st *b, uint8_t *buf, +static size_t dgram_pair_read_inner(struct ring_buf *rbufptr, uint8_t *buf, size_t sz); #define BIO_MSG_N(array, n) (*(BIO_MSG *)((char *)(array) + (n) * stride)) @@ -245,9 +248,69 @@ struct dgram_hdr { BIO_ADDR src_addr, dst_addr; /* family == 0: not present */ }; +struct rbuf_map_st { + struct bio_dgram_pair_st *self; + struct ring_buf rbuf; + uint32_t cap; + CRYPTO_RWLOCK *lock; +}; + +/** + * \defgroup peer_state Peer pairing states + * + * State values describing whether a peer is still associated with its + * counterpart. Stored in the peer's state field and compared for + * equality; the values are not a bitmask and must not be OR'd + * together. + * + * @{ + */ + +/** Peer is associated with a live counterpart. */ +#define PEER_STATE_PAIRED 0 + +/** Peer's counterpart has gone away; the peer is unassociated. */ +#define PEER_STATE_ORPHANED 1 +/** + * \brief Shared state for a datagram BIO pair. + * + * Refcounted so that both ends of a pair (and any BIO holding a + * reference to the peer) can keep the structure alive independently. + * The object is freed when the last reference is dropped, and the peer_state + * is set to PEER_STATE_ORPHANED when either side leaves the pair, either + * via BIO_free() or BIO_destroy_dgram_pair() + * + * This structure is pointed to by each half of a BIO_dgram pair via the pair pointer + * It is only allocated and assigned when a pair is formed. + */ +struct bio_dgram_peer_st { + /** + * Reference count. Initialised with CRYPTO_NEW_REF() and + * released with CRYPTO_FREE_REF() once it reaches zero. + */ + CRYPTO_REF_COUNT ref_cnt; + + /** + * Current pairing state; one of \c PEER_STATE_PAIRED or + * \c PEER_STATE_ORPHANED (see \ref peer_state). + */ + int peer_state; + + /* + * Lock for peer_state atomic ops where needed + */ + CRYPTO_RWLOCK *peerlock; + + /** + * Ring buffer mappings for the two datagram directions, + * indexed one per direction. + */ + struct rbuf_map_st map[2]; +}; + struct bio_dgram_pair_st { - /* The other half of the BIO pair. NULL for dgram_mem. */ - BIO *peer; + /* Track out pairing state */ + struct bio_dgram_peer_st *pair; /* Writes are directed to our own ringbuf and reads to our peer. */ struct ring_buf rbuf; /* Requested size of rbuf buffer in bytes once we initialize. */ @@ -270,9 +333,78 @@ struct bio_dgram_pair_st { unsigned int grows_on_write : 1; /* Set for BIO_s_dgram_mem only */ }; -#define MIN_BUF_LEN (1024) +/* + * When operating as a pair, we use the shared structure to hold our ring buffers + * and locks to ensure that they remain allocated until the last half of a pair + * dissolves the pair. + */ +static struct rbuf_map_st *dgram_rbuf_map_get_self(struct bio_dgram_pair_st *self) +{ + if (self->pair->map[0].self == self) + return &self->pair->map[0]; + return &self->pair->map[1]; +} -#define is_dgram_pair(b) (b->peer != NULL) +static struct rbuf_map_st *dgram_rbuf_map_get_peer(struct bio_dgram_pair_st *self) +{ + if (self->pair->map[0].self == self) + return &self->pair->map[1]; + return &self->pair->map[0]; +} + +static void dgram_bio_get_self_data(struct bio_dgram_pair_st *self, struct ring_buf **rbufptr, + CRYPTO_RWLOCK **lock) +{ + struct rbuf_map_st *map; + CRYPTO_RWLOCK *mylock; + struct ring_buf *myrbuf; + + if (is_dgram_pair(self)) { + map = dgram_rbuf_map_get_self(self); + mylock = map->lock; + myrbuf = &map->rbuf; + } else { + mylock = self->lock; + myrbuf = &self->rbuf; + } + if (lock != NULL) + *lock = mylock; + if (rbufptr != NULL) + *rbufptr = myrbuf; +} + +static void dgram_bio_get_peer_data(struct bio_dgram_pair_st *self, struct ring_buf **rbufptr, + CRYPTO_RWLOCK **lock, uint32_t *caps, struct bio_dgram_pair_st **peer) +{ + struct rbuf_map_st *map; + CRYPTO_RWLOCK *mylock; + struct ring_buf *myrbuf; + struct bio_dgram_pair_st *mypeer; + uint32_t mycaps; + + if (is_dgram_pair(self)) { + map = dgram_rbuf_map_get_peer(self); + mylock = map->lock; + myrbuf = &map->rbuf; + mypeer = map->self; + mycaps = map->cap; + } else { + mylock = self->lock; + myrbuf = &self->rbuf; + mypeer = self; + mycaps = self->cap; + } + if (lock != NULL) + *lock = mylock; + if (rbufptr != NULL) + *rbufptr = myrbuf; + if (peer != NULL) + *peer = mypeer; + if (caps != NULL) + *caps = mycaps; +} + +#define MIN_BUF_LEN (1024) static int dgram_pair_init(BIO *bio) { @@ -330,6 +462,8 @@ static int dgram_pair_free(BIO *bio) /* We are being freed. Disconnect any peer and destroy buffers. */ dgram_pair_ctrl_destroy_bio_pair(bio); + ring_buf_destroy(&b->rbuf); + BIO_ADDR_free(b->local_addr); CRYPTO_THREAD_lock_free(b->lock); OPENSSL_free(b); return 1; @@ -339,6 +473,7 @@ static int dgram_pair_free(BIO *bio) static int dgram_pair_ctrl_make_bio_pair(BIO *bio1, BIO *bio2) { struct bio_dgram_pair_st *b1, *b2; + struct bio_dgram_peer_st *pair; /* peer must be non-NULL. */ if (bio1 == NULL || bio2 == NULL) { @@ -365,7 +500,7 @@ static int dgram_pair_ctrl_make_bio_pair(BIO *bio1, BIO *bio2) * This ctrl cannot be used to associate a BIO pair half which is already * associated. */ - if (b1->peer != NULL || b2->peer != NULL) { + if (b1->pair != NULL || b2->pair != NULL) { ERR_raise_data(ERR_LIB_BIO, BIO_R_IN_USE, "cannot associate a BIO_dgram_pair which is already in use"); return 0; @@ -377,21 +512,66 @@ static int dgram_pair_ctrl_make_bio_pair(BIO *bio1, BIO *bio2) return 0; } - if (b1->rbuf.len != b1->req_buf_len) - if (ring_buf_init(&b1->rbuf, b1->req_buf_len) == 0) { - ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB); - return 0; - } + /* + * Create a new pair structure, init it with appropriate + * ring buffers and lock, and assign it to each half of the + * pair. + * Once this is done, each half of the pair uses the shared + * ring buffers/lock available here instead of their own private copy + */ + pair = OPENSSL_zalloc(sizeof(*pair)); + if (pair == NULL) { + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return 0; + } + if (!CRYPTO_NEW_REF(&pair->ref_cnt, 2)) { + OPENSSL_free(pair); + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return 0; + } + pair->peerlock = CRYPTO_THREAD_lock_new(); + if (pair->peerlock == NULL) { + CRYPTO_FREE_REF(&pair->ref_cnt); + OPENSSL_free(pair->peerlock); + OPENSSL_free(pair); + return 0; + } - if (b2->rbuf.len != b2->req_buf_len) - if (ring_buf_init(&b2->rbuf, b2->req_buf_len) == 0) { - ERR_raise(ERR_LIB_BIO, ERR_R_BIO_LIB); - ring_buf_destroy(&b1->rbuf); - return 0; - } + if (ring_buf_init(&pair->map[0].rbuf, b1->req_buf_len) == 0) { + CRYPTO_FREE_REF(&pair->ref_cnt); + CRYPTO_THREAD_lock_free(pair->peerlock); + OPENSSL_free(pair); + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return 0; + } - b1->peer = bio2; - b2->peer = bio1; + if (ring_buf_init(&pair->map[1].rbuf, b2->req_buf_len) == 0) { + CRYPTO_FREE_REF(&pair->ref_cnt); + CRYPTO_THREAD_lock_free(pair->peerlock); + OPENSSL_free(pair); + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return 0; + } + ring_buf_destroy(&b1->rbuf); + ring_buf_destroy(&b2->rbuf); + pair->map[0].lock = CRYPTO_THREAD_lock_new(); + pair->map[1].lock = CRYPTO_THREAD_lock_new(); + if (pair->map[0].lock == NULL || pair->map[1].lock == NULL) { + CRYPTO_THREAD_lock_free(pair->map[0].lock); + CRYPTO_THREAD_lock_free(pair->map[1].lock); + CRYPTO_THREAD_lock_free(pair->peerlock); + CRYPTO_FREE_REF(&pair->ref_cnt); + OPENSSL_free(pair); + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return 0; + } + pair->map[0].self = b1; + pair->map[1].self = b2; + pair->map[0].cap = b1->cap; + pair->map[1].cap = b2->cap; + TSAN_BENIGN(pair, "publishing pair"); + b1->pair = pair; + b2->pair = pair; b1->role = 0; b2->role = 1; bio1->init = 1; @@ -402,38 +582,56 @@ static int dgram_pair_ctrl_make_bio_pair(BIO *bio1, BIO *bio2) /* BIO_destroy_bio_pair (BIO_C_DESTROY_BIO_PAIR) */ static int dgram_pair_ctrl_destroy_bio_pair(BIO *bio1) { - BIO *bio2; - struct bio_dgram_pair_st *b1 = bio1->ptr, *b2; - - ring_buf_destroy(&b1->rbuf); - bio1->init = 0; - - BIO_ADDR_free(b1->local_addr); + struct bio_dgram_pair_st *b1 = bio1->ptr; + int ref; + int newval = PEER_STATE_ORPHANED; /* Early return if we don't have a peer. */ - if (b1->peer == NULL) + if (b1->pair == NULL) return 1; - bio2 = b1->peer; - b2 = bio2->ptr; + ring_buf_destroy(&b1->rbuf); + bio1->init = 0; - /* Invariant. */ - if (!ossl_assert(b2->peer == bio1)) + if (ring_buf_init(&b1->rbuf, b1->req_buf_len) == 0) return 0; - /* Free buffers. */ - ring_buf_destroy(&b2->rbuf); + /* + * Since one half of the pair is going away, we are now + * orphaned + */ + if (!CRYPTO_atomic_store_int(&b1->pair->peer_state, newval, b1->pair->peerlock)) + return 0; - bio2->init = 0; - b1->peer = NULL; - b2->peer = NULL; + if (!CRYPTO_DOWN_REF(&b1->pair->ref_cnt, &ref)) + return 0; + if (ref == 0) { + /* + * The last half of the pair is leaving, clean up the + * shared data + */ + CRYPTO_FREE_REF(&b1->pair->ref_cnt); + CRYPTO_THREAD_lock_free(b1->pair->map[0].lock); + CRYPTO_THREAD_lock_free(b1->pair->map[1].lock); + CRYPTO_THREAD_lock_free(b1->pair->peerlock); + ring_buf_destroy(&b1->pair->map[0].rbuf); + ring_buf_destroy(&b1->pair->map[1].rbuf); + OPENSSL_free(b1->pair); + } + /* + * Make sure the leaving pair no longer references the shared peer data, + * since it is no longer part of the pair. + */ + TSAN_BENIGN(b1->pair, "b1 no longer accesses b1->pair"); + b1->pair = NULL; return 1; } /* BIO_eof (BIO_CTRL_EOF) */ static int dgram_pair_ctrl_eof(BIO *bio) { - struct bio_dgram_pair_st *b = bio->ptr, *peerb; + struct bio_dgram_pair_st *b = bio->ptr, *peerb = NULL; + int peer_state; if (!ossl_assert(b != NULL)) return -1; @@ -444,7 +642,16 @@ static int dgram_pair_ctrl_eof(BIO *bio) if (!is_dgram_pair(b)) return 0; - peerb = b->peer->ptr; + /* + * orphaned pairs always return EOF + */ + if (!CRYPTO_atomic_load_int(&b->pair->peer_state, &peer_state, b->pair->peerlock)) + return -1; + + if (peer_state == PEER_STATE_ORPHANED) + return 1; + + dgram_bio_get_peer_data(b, NULL, NULL, NULL, &peerb); if (!ossl_assert(peerb != NULL)) return -1; @@ -461,7 +668,7 @@ static int dgram_pair_ctrl_set_write_buf_size(BIO *bio, size_t len) struct bio_dgram_pair_st *b = bio->ptr; /* Changing buffer sizes is not permitted while a peer is connected. */ - if (b->peer != NULL) { + if (b->pair != NULL) { ERR_raise(ERR_LIB_BIO, BIO_R_IN_USE); return 0; } @@ -496,27 +703,35 @@ static size_t dgram_pair_ctrl_pending(BIO *bio) struct bio_dgram_pair_st *b = bio->ptr, *readb; struct dgram_hdr hdr; size_t l; + struct ring_buf *rbufptr; + CRYPTO_RWLOCK *lock; + int peer_state; /* Safe to check; init may not change during this call */ if (!bio->init) return 0; - if (is_dgram_pair(b)) - readb = b->peer->ptr; - else - readb = b; + if (is_dgram_pair(b)) { + if (!CRYPTO_atomic_load_int(&b->pair->peer_state, &peer_state, b->pair->peerlock)) + return 0; + + if (peer_state == PEER_STATE_ORPHANED) + return 0; + } + + dgram_bio_get_peer_data(b, &rbufptr, &lock, NULL, &readb); - if (CRYPTO_THREAD_write_lock(readb->lock) == 0) + if (CRYPTO_THREAD_write_lock(lock) == 0) return 0; - saved_idx = readb->rbuf.idx[1]; - saved_count = readb->rbuf.count; + saved_idx = rbufptr->idx[1]; + saved_count = rbufptr->count; - l = dgram_pair_read_inner(readb, (uint8_t *)&hdr, sizeof(hdr)); + l = dgram_pair_read_inner(rbufptr, (uint8_t *)&hdr, sizeof(hdr)); - readb->rbuf.idx[1] = saved_idx; - readb->rbuf.count = saved_count; + rbufptr->idx[1] = saved_idx; + rbufptr->count = saved_count; - CRYPTO_THREAD_unlock(readb->lock); + CRYPTO_THREAD_unlock(lock); if (!ossl_assert(l == 0 || l == sizeof(hdr))) return 0; @@ -529,11 +744,15 @@ static size_t dgram_pair_ctrl_get_write_guarantee(BIO *bio) { size_t l; struct bio_dgram_pair_st *b = bio->ptr; + struct ring_buf *rbufptr; + CRYPTO_RWLOCK *lock; + + dgram_bio_get_peer_data(b, &rbufptr, &lock, NULL, NULL); - if (CRYPTO_THREAD_read_lock(b->lock) == 0) + if (CRYPTO_THREAD_read_lock(lock) == 0) return 0; - l = b->rbuf.len - b->rbuf.count; + l = rbufptr->len - rbufptr->count; if (l >= sizeof(struct dgram_hdr)) l -= sizeof(struct dgram_hdr); @@ -544,7 +763,7 @@ static size_t dgram_pair_ctrl_get_write_guarantee(BIO *bio) if (l < b->mtu) l = 0; - CRYPTO_THREAD_unlock(b->lock); + CRYPTO_THREAD_unlock(lock); return l; } @@ -552,29 +771,44 @@ static size_t dgram_pair_ctrl_get_write_guarantee(BIO *bio) static int dgram_pair_ctrl_get_local_addr_cap(BIO *bio) { struct bio_dgram_pair_st *b = bio->ptr, *readb; + int peer_state; + uint32_t caps; if (!bio->init) return 0; - if (is_dgram_pair(b)) - readb = b->peer->ptr; - else - readb = b; + if (is_dgram_pair(b)) { + if (!CRYPTO_atomic_load_int(&b->pair->peer_state, &peer_state, b->pair->peerlock)) + return 0; - return (~readb->cap & (BIO_DGRAM_CAP_HANDLES_SRC_ADDR | BIO_DGRAM_CAP_PROVIDES_DST_ADDR)) == 0; + if (peer_state == PEER_STATE_ORPHANED) + return 0; + } + + dgram_bio_get_peer_data(b, NULL, NULL, &caps, &readb); + + return (~caps & (BIO_DGRAM_CAP_HANDLES_SRC_ADDR | BIO_DGRAM_CAP_PROVIDES_DST_ADDR)) == 0; } /* BIO_dgram_get_effective_caps (BIO_CTRL_DGRAM_GET_EFFECTIVE_CAPS) */ static int dgram_pair_ctrl_get_effective_caps(BIO *bio) { struct bio_dgram_pair_st *b = bio->ptr, *peerb; + int peer_state; + uint32_t caps; - if (b->peer == NULL) + if (b->pair == NULL) return 0; - peerb = b->peer->ptr; + if (!CRYPTO_atomic_load_int(&b->pair->peer_state, &peer_state, b->pair->peerlock)) + return 0; - return peerb->cap; + if (peer_state == PEER_STATE_ORPHANED) + return 0; + + dgram_bio_get_peer_data(b, NULL, NULL, &caps, &peerb); + + return caps; } /* BIO_dgram_get_caps (BIO_CTRL_DGRAM_GET_CAPS) */ @@ -589,8 +823,14 @@ static uint32_t dgram_pair_ctrl_get_caps(BIO *bio) static int dgram_pair_ctrl_set_caps(BIO *bio, uint32_t caps) { struct bio_dgram_pair_st *b = bio->ptr; + struct rbuf_map_st *map; b->cap = caps; + + if (is_dgram_pair(b)) { + map = dgram_rbuf_map_get_self(b); + map->cap = caps; + } return 1; } @@ -626,12 +866,18 @@ static int dgram_pair_ctrl_get_mtu(BIO *bio) static int dgram_pair_ctrl_set_mtu(BIO *bio, size_t mtu) { struct bio_dgram_pair_st *b = bio->ptr, *peerb; + int peer_state; b->mtu = mtu; - if (b->peer != NULL) { - peerb = b->peer->ptr; - peerb->mtu = mtu; + if (is_dgram_pair(b)) { + if (!CRYPTO_atomic_load_int(&b->pair->peer_state, &peer_state, b->pair->peerlock)) + return 0; + + if (peer_state == PEER_STATE_PAIRED) { + dgram_bio_get_peer_data(b, NULL, NULL, NULL, &peerb); + peerb->mtu = mtu; + } } return 1; @@ -848,7 +1094,7 @@ int BIO_new_bio_dgram_pair(BIO **pbio1, size_t writebuf1, } /* Must hold peer write lock */ -static size_t dgram_pair_read_inner(struct bio_dgram_pair_st *b, uint8_t *buf, size_t sz) +static size_t dgram_pair_read_inner(struct ring_buf *rbufptr, uint8_t *buf, size_t sz) { size_t total_read = 0; @@ -866,7 +1112,7 @@ static size_t dgram_pair_read_inner(struct bio_dgram_pair_st *b, uint8_t *buf, s * There are two BIO instances, each with a ringbuf. We read from the * peer ringbuf and write to our own ringbuf. */ - ring_buf_tail(&b->rbuf, &src_buf, &src_len); + ring_buf_tail(rbufptr, &src_buf, &src_len); if (src_len == 0) break; @@ -876,7 +1122,7 @@ static size_t dgram_pair_read_inner(struct bio_dgram_pair_st *b, uint8_t *buf, s if (buf != NULL) memcpy(buf, src_buf, src_len); - ring_buf_pop(&b->rbuf, src_len); + ring_buf_pop(rbufptr, src_len); if (buf != NULL) buf += src_len; @@ -896,8 +1142,9 @@ static ossl_ssize_t dgram_pair_read_actual(BIO *bio, char *buf, size_t sz, int is_multi) { size_t l, trunc = 0, saved_idx, saved_count; - struct bio_dgram_pair_st *b = bio->ptr, *readb; + struct bio_dgram_pair_st *b = bio->ptr; struct dgram_hdr hdr; + struct ring_buf *rbufptr; if (!is_multi) BIO_clear_retry_flags(bio); @@ -908,11 +1155,9 @@ static ossl_ssize_t dgram_pair_read_actual(BIO *bio, char *buf, size_t sz, if (!ossl_assert(b != NULL)) return -BIO_R_TRANSFER_ERROR; - if (is_dgram_pair(b)) - readb = b->peer->ptr; - else - readb = b; - if (!ossl_assert(readb != NULL && readb->rbuf.start != NULL)) + dgram_bio_get_peer_data(b, &rbufptr, NULL, NULL, NULL); + + if (!ossl_assert(rbufptr->start != NULL)) return -BIO_R_TRANSFER_ERROR; if (sz > 0 && buf == NULL) @@ -923,9 +1168,9 @@ static ossl_ssize_t dgram_pair_read_actual(BIO *bio, char *buf, size_t sz, return -BIO_R_LOCAL_ADDR_NOT_AVAILABLE; /* Read the header. */ - saved_idx = readb->rbuf.idx[1]; - saved_count = readb->rbuf.count; - l = dgram_pair_read_inner(readb, (uint8_t *)&hdr, sizeof(hdr)); + saved_idx = rbufptr->idx[1]; + saved_count = rbufptr->count; + l = dgram_pair_read_inner(rbufptr, (uint8_t *)&hdr, sizeof(hdr)); if (l == 0) { /* Buffer was empty. */ if (!is_multi) @@ -947,13 +1192,13 @@ static ossl_ssize_t dgram_pair_read_actual(BIO *bio, char *buf, size_t sz, trunc = hdr.len - sz; if (b->no_trunc) { /* Restore original state. */ - readb->rbuf.idx[1] = saved_idx; - readb->rbuf.count = saved_count; + rbufptr->idx[1] = saved_idx; + rbufptr->count = saved_count; return -BIO_R_NON_FATAL; } } - l = dgram_pair_read_inner(readb, (uint8_t *)buf, sz); + l = dgram_pair_read_inner(rbufptr, (uint8_t *)buf, sz); if (!ossl_assert(l == sz)) /* We were somehow not able to read the entire datagram. */ return -BIO_R_TRANSFER_ERROR; @@ -962,7 +1207,7 @@ static ossl_ssize_t dgram_pair_read_actual(BIO *bio, char *buf, size_t sz, * If the datagram was truncated due to an inadequate buffer, discard the * remainder. */ - if (trunc > 0 && !ossl_assert(dgram_pair_read_inner(readb, NULL, trunc) == trunc)) + if (trunc > 0 && !ossl_assert(dgram_pair_read_inner(rbufptr, NULL, trunc) == trunc)) /* We were somehow not able to read/skip the entire datagram. */ return -BIO_R_TRANSFER_ERROR; @@ -980,21 +1225,30 @@ static int dgram_pair_lock_both_write(struct bio_dgram_pair_st *a, { struct bio_dgram_pair_st *x, *y; - x = (a->role == 1) ? a : b; - y = (a->role == 1) ? b : a; + if (is_dgram_pair(b)) { + if (CRYPTO_THREAD_write_lock(b->pair->map[0].lock) == 0) + return 0; + if (CRYPTO_THREAD_write_lock(b->pair->map[1].lock) == 0) { + CRYPTO_THREAD_unlock(b->pair->map[0].lock); + return 0; + } + } else { + x = (a->role == 1) ? a : b; + y = (a->role == 1) ? b : a; - if (!ossl_assert(a->role != b->role)) - return 0; + if (!ossl_assert(a->role != b->role)) + return 0; - if (!ossl_assert(a != b && x != y)) - return 0; + if (!ossl_assert(a != b && x != y)) + return 0; - if (CRYPTO_THREAD_write_lock(x->lock) == 0) - return 0; + if (CRYPTO_THREAD_write_lock(x->lock) == 0) + return 0; - if (CRYPTO_THREAD_write_lock(y->lock) == 0) { - CRYPTO_THREAD_unlock(x->lock); - return 0; + if (CRYPTO_THREAD_write_lock(y->lock) == 0) { + CRYPTO_THREAD_unlock(x->lock); + return 0; + } } return 1; @@ -1003,8 +1257,13 @@ static int dgram_pair_lock_both_write(struct bio_dgram_pair_st *a, static void dgram_pair_unlock_both(struct bio_dgram_pair_st *a, struct bio_dgram_pair_st *b) { - CRYPTO_THREAD_unlock(a->lock); - CRYPTO_THREAD_unlock(b->lock); + if (is_dgram_pair(b)) { + CRYPTO_THREAD_unlock(b->pair->map[0].lock); + CRYPTO_THREAD_unlock(b->pair->map[1].lock); + } else { + CRYPTO_THREAD_unlock(a->lock); + CRYPTO_THREAD_unlock(b->lock); + } } /* Threadsafe */ @@ -1013,18 +1272,27 @@ static int dgram_pair_read(BIO *bio, char *buf, int sz_) int ret; ossl_ssize_t l; struct bio_dgram_pair_st *b = bio->ptr, *peerb; + int peer_state; if (sz_ < 0) { ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT); return -1; } - if (b->peer == NULL) { + if (b->pair == NULL) { + ERR_raise(ERR_LIB_BIO, BIO_R_UNINITIALIZED); + return -1; + } + + if (!CRYPTO_atomic_load_int(&b->pair->peer_state, &peer_state, b->pair->peerlock)) + return -1; + + if (peer_state == PEER_STATE_ORPHANED) { ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE); return -1; } - peerb = b->peer->ptr; + dgram_bio_get_peer_data(b, NULL, NULL, NULL, &peerb); /* * For BIO_read we have to acquire both locks because we touch the retry @@ -1060,6 +1328,8 @@ static int dgram_pair_recvmmsg(BIO *bio, BIO_MSG *msg, BIO_MSG *m; size_t i; struct bio_dgram_pair_st *b = bio->ptr, *readb; + CRYPTO_RWLOCK *lock; + int peer_state; if (num_msg == 0) { *num_processed = 0; @@ -1072,12 +1342,21 @@ static int dgram_pair_recvmmsg(BIO *bio, BIO_MSG *msg, return 0; } - if (is_dgram_pair(b)) - readb = b->peer->ptr; - else - readb = b; + if (is_dgram_pair(b)) { + if (!CRYPTO_atomic_load_int(&b->pair->peer_state, &peer_state, b->pair->peerlock)) { + *num_processed = 0; + return 0; + } + + if (peer_state == PEER_STATE_ORPHANED) { + *num_processed = 0; + ERR_raise(ERR_LIB_BIO, BIO_R_BROKEN_PIPE); + return 0; + } + } - if (CRYPTO_THREAD_write_lock(readb->lock) == 0) { + dgram_bio_get_peer_data(b, NULL, &lock, NULL, &readb); + if (CRYPTO_THREAD_write_lock(lock) == 0) { ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK); *num_processed = 0; return 0; @@ -1105,7 +1384,7 @@ static int dgram_pair_recvmmsg(BIO *bio, BIO_MSG *msg, *num_processed = i; ret = 1; out: - CRYPTO_THREAD_unlock(readb->lock); + CRYPTO_THREAD_unlock(lock); return ret; } @@ -1172,6 +1451,9 @@ static size_t dgram_pair_write_inner(struct bio_dgram_pair_st *b, const uint8_t *buf, size_t sz) { size_t total_written = 0; + struct ring_buf *rbufptr; + + dgram_bio_get_self_data(b, &rbufptr, NULL); /* * We repeat pushes to the ring buffer for as long as we have data until we @@ -1186,7 +1468,7 @@ static size_t dgram_pair_write_inner(struct bio_dgram_pair_st *b, * There are two BIO instances, each with a ringbuf. We write to our own * ringbuf and read from the peer ringbuf. */ - ring_buf_head(&b->rbuf, &dst_buf, &dst_len); + ring_buf_head(rbufptr, &dst_buf, &dst_len); if (dst_len == 0) { size_t new_len; @@ -1194,7 +1476,7 @@ static size_t dgram_pair_write_inner(struct bio_dgram_pair_st *b, break; /* increase the size */ new_len = compute_rbuf_growth(b->req_buf_len + sz, b->req_buf_len); - if (new_len == 0 || !ring_buf_resize(&b->rbuf, new_len)) + if (new_len == 0 || !ring_buf_resize(rbufptr, new_len)) break; b->req_buf_len = new_len; } @@ -1203,7 +1485,7 @@ static size_t dgram_pair_write_inner(struct bio_dgram_pair_st *b, dst_len = sz; memcpy(dst_buf, buf, dst_len); - ring_buf_push(&b->rbuf, dst_len); + ring_buf_push(rbufptr, dst_len); buf += dst_len; sz -= dst_len; @@ -1223,8 +1505,11 @@ static ossl_ssize_t dgram_pair_write_actual(BIO *bio, const char *buf, size_t sz { static const BIO_ADDR zero_addr; size_t saved_idx, saved_count; - struct bio_dgram_pair_st *b = bio->ptr, *readb; + struct bio_dgram_pair_st *b = bio->ptr; struct dgram_hdr hdr = { 0 }; + struct ring_buf *rbufptr; + int peer_state; + uint32_t caps; if (!is_multi) BIO_clear_retry_flags(bio); @@ -1232,7 +1517,16 @@ static ossl_ssize_t dgram_pair_write_actual(BIO *bio, const char *buf, size_t sz if (!bio->init) return -BIO_R_UNINITIALIZED; - if (!ossl_assert(b != NULL && b->rbuf.start != NULL)) + if (is_dgram_pair(b)) { + if (!CRYPTO_atomic_load_int(&b->pair->peer_state, &peer_state, b->pair->peerlock)) + return -BIO_R_UNINITIALIZED; + if (peer_state == PEER_STATE_ORPHANED) + return -BIO_R_BROKEN_PIPE; + } + + dgram_bio_get_self_data(b, &rbufptr, NULL); + + if (!ossl_assert(b != NULL && rbufptr->start != NULL)) return -BIO_R_TRANSFER_ERROR; if (sz > 0 && buf == NULL) @@ -1241,11 +1535,9 @@ static ossl_ssize_t dgram_pair_write_actual(BIO *bio, const char *buf, size_t sz if (local != NULL && b->local_addr_enable == 0) return -BIO_R_LOCAL_ADDR_NOT_AVAILABLE; - if (is_dgram_pair(b)) - readb = b->peer->ptr; - else - readb = b; - if (peer != NULL && (readb->cap & BIO_DGRAM_CAP_HANDLES_DST_ADDR) == 0) + dgram_bio_get_peer_data(b, NULL, NULL, &caps, NULL); + + if (peer != NULL && (caps & BIO_DGRAM_CAP_HANDLES_DST_ADDR) == 0) return -BIO_R_PEER_ADDR_NOT_AVAILABLE; hdr.len = sz; @@ -1254,16 +1546,16 @@ static ossl_ssize_t dgram_pair_write_actual(BIO *bio, const char *buf, size_t sz local = b->local_addr; hdr.src_addr = (local != NULL ? *local : zero_addr); - saved_idx = b->rbuf.idx[0]; - saved_count = b->rbuf.count; + saved_idx = rbufptr->idx[0]; + saved_count = rbufptr->count; if (dgram_pair_write_inner(b, (const uint8_t *)&hdr, sizeof(hdr)) != sizeof(hdr) || dgram_pair_write_inner(b, (const uint8_t *)buf, sz) != sz) { /* * We were not able to push the header and the entirety of the payload * onto the ring buffer, so abort and roll back the ring buffer state. */ - b->rbuf.idx[0] = saved_idx; - b->rbuf.count = saved_count; + rbufptr->idx[0] = saved_idx; + rbufptr->count = saved_count; if (!is_multi) BIO_set_retry_write(bio); return -BIO_R_NON_FATAL; @@ -1278,13 +1570,16 @@ static int dgram_pair_write(BIO *bio, const char *buf, int sz_) int ret; ossl_ssize_t l; struct bio_dgram_pair_st *b = bio->ptr; + CRYPTO_RWLOCK *lock; if (sz_ < 0) { ERR_raise(ERR_LIB_BIO, BIO_R_INVALID_ARGUMENT); return -1; } - if (CRYPTO_THREAD_write_lock(b->lock) == 0) { + dgram_bio_get_self_data(b, NULL, &lock); + + if (CRYPTO_THREAD_write_lock(lock) == 0) { ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK); return -1; } @@ -1297,7 +1592,7 @@ static int dgram_pair_write(BIO *bio, const char *buf, int sz_) ret = (int)l; } - CRYPTO_THREAD_unlock(b->lock); + CRYPTO_THREAD_unlock(lock); return ret; } @@ -1311,13 +1606,16 @@ static int dgram_pair_sendmmsg(BIO *bio, BIO_MSG *msg, size_t i; struct bio_dgram_pair_st *b = bio->ptr; int ret = 0; + CRYPTO_RWLOCK *lock; if (num_msg == 0) { *num_processed = 0; return 1; } - if (CRYPTO_THREAD_write_lock(b->lock) == 0) { + dgram_bio_get_self_data(b, NULL, &lock); + + if (CRYPTO_THREAD_write_lock(lock) == 0) { ERR_raise(ERR_LIB_BIO, ERR_R_UNABLE_TO_GET_WRITE_LOCK); *num_processed = 0; return 0; @@ -1343,7 +1641,7 @@ static int dgram_pair_sendmmsg(BIO *bio, BIO_MSG *msg, *num_processed = i; ret = 1; out: - CRYPTO_THREAD_unlock(b->lock); + CRYPTO_THREAD_unlock(lock); return ret; } diff --git a/crypto/bio/bss_file.c b/crypto/bio/bss_file.c index 7aed585342d09..e01cd3ba99844 100644 --- a/crypto/bio/bss_file.c +++ b/crypto/bio/bss_file.c @@ -182,6 +182,9 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) FILE **fpp; char p[4]; int st; +#if defined(OPENSSL_SYS_WINDOWS) + int oldErr; +#endif switch (cmd) { case BIO_C_FILE_SEEK: @@ -198,6 +201,10 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) * so we map the 0:non-0 return value here to 0:1 with a * double negation */ +#if defined(OPENSSL_SYS_WINDOWS) + oldErr = errno; + errno = 0; +#endif if (b->flags & BIO_FLAGS_UPLINK_INTERNAL) ret = !!(long)UP_feof(fp); else @@ -211,6 +218,8 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) */ if (ret == 0 && errno == EINVAL) ret = -EINVAL; + else if (errno == 0) + errno = oldErr; #endif break; case BIO_C_FILE_TELL: diff --git a/crypto/bio/bss_log.c b/crypto/bio/bss_log.c index 2928ae5c4199e..5eb5d9c130bda 100644 --- a/crypto/bio/bss_log.c +++ b/crypto/bio/bss_log.c @@ -240,7 +240,7 @@ static void xsyslog(BIO *bp, int priority, const char *string) break; } - BIO_snprintf(pidbuf, sizeof(pidbuf), "[%lu] ", GetCurrentProcessId()); + snprintf(pidbuf, sizeof(pidbuf), "[%lu] ", GetCurrentProcessId()); lpszStrings[0] = pidbuf; lpszStrings[1] = string; diff --git a/crypto/bn/asm/armv4-gf2m.pl b/crypto/bn/asm/armv4-gf2m.pl index f722804b2f02d..e1b0642275945 100644 --- a/crypto/bn/asm/armv4-gf2m.pl +++ b/crypto/bn/asm/armv4-gf2m.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/asm/armv4-mont.pl b/crypto/bn/asm/armv4-mont.pl index 9429440e87d73..08b7ab487c0f7 100644 --- a/crypto/bn/asm/armv4-mont.pl +++ b/crypto/bn/asm/armv4-mont.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/asm/armv8-mont.pl b/crypto/bn/asm/armv8-mont.pl index 9f0495f270b20..72839210398f7 100755 --- a/crypto/bn/asm/armv8-mont.pl +++ b/crypto/bn/asm/armv8-mont.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/asm/e2k-bn-asm.c b/crypto/bn/asm/e2k-bn-asm.c new file mode 100644 index 0000000000000..2a21a30af0117 --- /dev/null +++ b/crypto/bn/asm/e2k-bn-asm.c @@ -0,0 +1,825 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "../bn_local.h" + +#include +#include + +/* + * E2Kv5+ BIGNUM accelerator + * + * Implemented by Alexander Troosh + * + */ + +#undef mul_add +#undef mul +#undef sqr + +#if __iset__ < 5 +#define mul_add(r, a, w, c) \ + { \ + BN_ULONG high, low, ret, tmp = (a); \ + ret = (r); \ + high = __builtin_e2k_umulhd(w, tmp); \ + ret += (c); \ + low = (w) * tmp; \ + (c) = (ret < (c)) ? 1 : 0; \ + (c) += high; \ + ret += low; \ + (c) += (ret < low) ? 1 : 0; \ + (r) = ret; \ + } + +#define mul(r, a, w, c) \ + { \ + BN_ULONG high, low, ret, ta = (a); \ + low = (w) * ta; \ + high = __builtin_e2k_umulhd(w, ta); \ + ret = low + (c); \ + (c) = high; \ + (c) += (ret < low) ? 1 : 0; \ + (r) = ret; \ + } +#else +/* { c_out[64], r_out[64] } = (r[64] + c[64]) + a[64]*w[64] */ +#define mul_add(r, a, w, c) \ + { \ + BN_ULONG high, low, ret, ta = (a), tc = (c), q; \ + ret = (r); \ + high = __builtin_e2k_umulhd(w, ta); \ + low = (w) * ta; \ + q = __builtin_e2k_addcd_c(ret, tc, 0); \ + ret += tc; \ + c = __builtin_e2k_addcd_c(ret, low, 0); \ + r = ret + low; \ + c += high + q; \ + } + +#define mul(r, a, w, c) \ + { \ + BN_ULONG high, low, q, ta = (a); \ + low = (w) * ta; \ + high = __builtin_e2k_umulhd(w, ta); \ + q = __builtin_e2k_addcd_c(low, c, 0); \ + r = low + (c); \ + c = high + q; \ + } +#endif + +#define sqr(r0, r1, a) \ + { \ + BN_ULONG tmp = (a); \ + (r0) = tmp * tmp; \ + (r1) = __builtin_e2k_umulhd(tmp, tmp); \ + } + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, + BN_ULONG w) +{ + BN_ULONG c1 = 0; + + assert(num >= 0); + if (num <= 0) + return c1; + +#ifndef OPENSSL_SMALL_FOOTPRINT + while (num & ~3) { + mul_add(rp[0], ap[0], w, c1); + mul_add(rp[1], ap[1], w, c1); + mul_add(rp[2], ap[2], w, c1); + mul_add(rp[3], ap[3], w, c1); + ap += 4; + rp += 4; + num -= 4; + } +#endif + while (num) { + mul_add(rp[0], ap[0], w, c1); + ap++; + rp++; + num--; + } + + return c1; +} + +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) +{ + BN_ULONG c1 = 0; + + assert(num >= 0); + if (num <= 0) + return c1; + +#ifndef OPENSSL_SMALL_FOOTPRINT + while (num & ~3) { + mul(rp[0], ap[0], w, c1); + mul(rp[1], ap[1], w, c1); + mul(rp[2], ap[2], w, c1); + mul(rp[3], ap[3], w, c1); + ap += 4; + rp += 4; + num -= 4; + } +#endif + while (num) { + mul(rp[0], ap[0], w, c1); + ap++; + rp++; + num--; + } + return c1; +} + +void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) +{ + assert(n >= 0); + if (n <= 0) + return; + +#ifndef OPENSSL_SMALL_FOOTPRINT + while (n & ~3) { + sqr(r[0], r[1], a[0]); + sqr(r[2], r[3], a[1]); + sqr(r[4], r[5], a[2]); + sqr(r[6], r[7], a[3]); + a += 4; + r += 8; + n -= 4; + } +#endif + while (n) { + sqr(r[0], r[1], a[0]); + a++; + r += 2; + n--; + } +} + +/* Divide h,l by d and return the result. */ +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) +{ + BN_ULONG dh, dl, q, ret = 0, th, tl, t; + int i, count = 2; + + if (d == 0) + return BN_MASK2; + + i = BN_num_bits_word(d); + assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i)); + + i = BN_BITS2 - i; + if (h >= d) + h -= d; + + if (i) { + d <<= i; + h = (h << i) | (l >> (BN_BITS2 - i)); + l <<= i; + } + dh = (d & BN_MASK2h) >> BN_BITS4; + dl = (d & BN_MASK2l); + for (;;) { + if ((h >> BN_BITS4) == dh) + q = BN_MASK2l; + else + q = h / dh; + + th = q * dh; + tl = dl * q; + for (;;) { + t = h - th; + if ((t & BN_MASK2h) || ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4)))) + break; + q--; + th -= dh; + tl -= dl; + } + t = (tl >> BN_BITS4); + tl = (tl << BN_BITS4) & BN_MASK2h; + th += t; + + if (l < tl) + th++; + l -= tl; + if (h < th) { + h += d; + q--; + } + h -= th; + + if (--count == 0) + break; + + ret = q << BN_BITS4; + h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2; + l = (l & BN_MASK2l) << BN_BITS4; + } + ret |= q; + return ret; +} + +BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int n) +{ + BN_ULONG c, l, t; + + assert(n >= 0); + if (n <= 0) + return (BN_ULONG)0; + + c = 0; +#ifndef OPENSSL_SMALL_FOOTPRINT + while (n & ~3) { +#if __iset__ < 5 + t = a[0]; + t = (t + c) & BN_MASK2; + c = (t < c); + l = (t + b[0]) & BN_MASK2; + c += (l < t); + r[0] = l; + t = a[1]; + t = (t + c) & BN_MASK2; + c = (t < c); + l = (t + b[1]) & BN_MASK2; + c += (l < t); + r[1] = l; + t = a[2]; + t = (t + c) & BN_MASK2; + c = (t < c); + l = (t + b[2]) & BN_MASK2; + c += (l < t); + r[2] = l; + t = a[3]; + t = (t + c) & BN_MASK2; + c = (t < c); + l = (t + b[3]) & BN_MASK2; + c += (l < t); + r[3] = l; +#else + BN_ULONG t = __builtin_e2k_addcd_c(a[0], b[0], c); + r[0] = __builtin_e2k_addcd(a[0], b[0], c); + c = t; + t = __builtin_e2k_addcd_c(a[1], b[1], c); + r[1] = __builtin_e2k_addcd(a[1], b[1], c); + c = t; + t = __builtin_e2k_addcd_c(a[2], b[2], c); + r[2] = __builtin_e2k_addcd(a[2], b[2], c); + c = t; + t = __builtin_e2k_addcd_c(a[3], b[3], c); + r[3] = __builtin_e2k_addcd(a[3], b[3], c); + c = t; +#endif + a += 4; + b += 4; + r += 4; + n -= 4; + } +#endif + while (n) { +#if __iset__ < 5 + t = a[0]; + t = (t + c) & BN_MASK2; + c = (t < c); + l = (t + b[0]) & BN_MASK2; + c += (l < t); + r[0] = l; +#else + BN_ULONG t = __builtin_e2k_addcd_c(a[0], b[0], c); + r[0] = __builtin_e2k_addcd(a[0], b[0], c); + c = t; +#endif + a++; + b++; + r++; + n--; + } + return (BN_ULONG)c; +} + +BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int n) +{ +#if __iset__ < 5 + BN_ULONG t1, t2; +#endif + int c = 0; + + assert(n >= 0); + if (n <= 0) + return (BN_ULONG)0; + +#ifndef OPENSSL_SMALL_FOOTPRINT + while (n & ~3) { +#if __iset__ < 5 + t1 = a[0]; + t2 = (t1 - c) & BN_MASK2; + c = (t2 > t1); + t1 = b[0]; + t1 = (t2 - t1) & BN_MASK2; + r[0] = t1; + c += (t1 > t2); + t1 = a[1]; + t2 = (t1 - c) & BN_MASK2; + c = (t2 > t1); + t1 = b[1]; + t1 = (t2 - t1) & BN_MASK2; + r[1] = t1; + c += (t1 > t2); + t1 = a[2]; + t2 = (t1 - c) & BN_MASK2; + c = (t2 > t1); + t1 = b[2]; + t1 = (t2 - t1) & BN_MASK2; + r[2] = t1; + c += (t1 > t2); + t1 = a[3]; + t2 = (t1 - c) & BN_MASK2; + c = (t2 > t1); + t1 = b[3]; + t1 = (t2 - t1) & BN_MASK2; + r[3] = t1; + c += (t1 > t2); +#else + BN_ULONG t = __builtin_e2k_subcd_c(a[0], b[0], c); + r[0] = __builtin_e2k_subcd(a[0], b[0], c); + c = t; + t = __builtin_e2k_subcd_c(a[1], b[1], c); + r[1] = __builtin_e2k_subcd(a[1], b[1], c); + c = t; + t = __builtin_e2k_subcd_c(a[2], b[2], c); + r[2] = __builtin_e2k_subcd(a[2], b[2], c); + c = t; + t = __builtin_e2k_subcd_c(a[3], b[3], c); + r[3] = __builtin_e2k_subcd(a[3], b[3], c); + c = t; +#endif + a += 4; + b += 4; + r += 4; + n -= 4; + } +#endif + while (n) { +#if __iset__ < 5 + t1 = a[0]; + t2 = (t1 - c) & BN_MASK2; + c = (t2 > t1); + t1 = b[0]; + t1 = (t2 - t1) & BN_MASK2; + r[0] = t1; + c += (t1 > t2); +#else + BN_ULONG t = __builtin_e2k_subcd_c(a[0], b[0], c); + r[0] = __builtin_e2k_subcd(a[0], b[0], c); + c = t; +#endif + a++; + b++; + r++; + n--; + } + return c; +} + +#ifndef OPENSSL_SMALL_FOOTPRINT + +/* mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) */ +/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */ +/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */ +/* + * sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number + * c=(c2,c1,c0) + */ + +#if __iset__ < 5 +/* + * Keep in mind that carrying into high part of multiplication result + * can not overflow, because it cannot be all-ones. + */ +#define mul_add_c(a, b, c0, c1, c2) \ + do { \ + BN_ULONG ta = (a), tb = (b); \ + BN_ULONG lo, hi; \ + BN_UMULT_LOHI(lo, hi, ta, tb); \ + c0 += lo; \ + hi += (c0 < lo); \ + c1 += hi; \ + c2 += (c1 < hi); \ + } while (0) + +#define mul_add_c2(a, b, c0, c1, c2) \ + do { \ + BN_ULONG ta = (a), tb = (b); \ + BN_ULONG lo, hi, tt; \ + BN_UMULT_LOHI(lo, hi, ta, tb); \ + c0 += lo; \ + tt = hi + (c0 < lo); \ + c1 += tt; \ + c2 += (c1 < tt); \ + c0 += lo; \ + hi += (c0 < lo); \ + c1 += hi; \ + c2 += (c1 < hi); \ + } while (0) + +#define sqr_add_c(a, i, c0, c1, c2) \ + do { \ + BN_ULONG ta = (a)[i]; \ + BN_ULONG lo, hi; \ + BN_UMULT_LOHI(lo, hi, ta, ta); \ + c0 += lo; \ + hi += (c0 < lo); \ + c1 += hi; \ + c2 += (c1 < hi); \ + } while (0) +#else /* __iset__ >= 5 */ +#define mul_add_c(a, b, c0, c1, c2) \ + do { \ + BN_ULONG ta = (a), tb = (b); \ + BN_ULONG lo, hi; \ + int q; \ + lo = ta * tb; \ + hi = __builtin_e2k_umulhd(ta, tb); \ + q = __builtin_e2k_addcd_c(c0, lo, 0); \ + c0 += lo; \ + c2 += __builtin_e2k_addcd_c(c1, hi, q); \ + c1 = __builtin_e2k_addcd(c1, hi, q); \ + } while (0) + +#define mul_add_c2(a, b, c0, c1, c2) \ + do { \ + BN_ULONG ta = (a), tb = (b); \ + BN_ULONG lo, hi, lo_msb; \ + int q; \ + lo = ta * tb; \ + hi = __builtin_e2k_umulhd(ta, tb); \ + \ + lo_msb = lo >> 63; \ + lo <<= 1; \ + c2 += hi >> 63; \ + hi = __builtin_e2k_insfd(hi, 0x7f, lo_msb); \ + \ + q = __builtin_e2k_addcd_c(c0, lo, 0); \ + c0 += lo; \ + c2 += __builtin_e2k_addcd_c(c1, hi, q); \ + c1 = __builtin_e2k_addcd(c1, hi, q); \ + } while (0) + +#define sqr_add_c(a, i, c0, c1, c2) \ + do { \ + BN_ULONG ta = (a)[i]; \ + BN_ULONG lo, hi; \ + int q; \ + lo = ta * ta; \ + hi = __builtin_e2k_umulhd(ta, ta); \ + q = __builtin_e2k_addcd_c(c0, lo, 0); \ + c0 += lo; \ + c2 += __builtin_e2k_addcd_c(c1, hi, q); \ + c1 = __builtin_e2k_addcd(c1, hi, q); \ + } while (0) +#endif /* __iset__ */ + +#define sqr_add_c2(a, i, j, c0, c1, c2) \ + mul_add_c2((a)[i], (a)[j], c0, c1, c2) + +void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) +{ + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + mul_add_c(a[0], b[0], c1, c2, c3); + r[0] = c1; + c1 = 0; + mul_add_c(a[0], b[1], c2, c3, c1); + mul_add_c(a[1], b[0], c2, c3, c1); + r[1] = c2; + c2 = 0; + mul_add_c(a[2], b[0], c3, c1, c2); + mul_add_c(a[1], b[1], c3, c1, c2); + mul_add_c(a[0], b[2], c3, c1, c2); + r[2] = c3; + c3 = 0; + mul_add_c(a[0], b[3], c1, c2, c3); + mul_add_c(a[1], b[2], c1, c2, c3); + mul_add_c(a[2], b[1], c1, c2, c3); + mul_add_c(a[3], b[0], c1, c2, c3); + r[3] = c1; + c1 = 0; + mul_add_c(a[4], b[0], c2, c3, c1); + mul_add_c(a[3], b[1], c2, c3, c1); + mul_add_c(a[2], b[2], c2, c3, c1); + mul_add_c(a[1], b[3], c2, c3, c1); + mul_add_c(a[0], b[4], c2, c3, c1); + r[4] = c2; + c2 = 0; + mul_add_c(a[0], b[5], c3, c1, c2); + mul_add_c(a[1], b[4], c3, c1, c2); + mul_add_c(a[2], b[3], c3, c1, c2); + mul_add_c(a[3], b[2], c3, c1, c2); + mul_add_c(a[4], b[1], c3, c1, c2); + mul_add_c(a[5], b[0], c3, c1, c2); + r[5] = c3; + c3 = 0; + mul_add_c(a[6], b[0], c1, c2, c3); + mul_add_c(a[5], b[1], c1, c2, c3); + mul_add_c(a[4], b[2], c1, c2, c3); + mul_add_c(a[3], b[3], c1, c2, c3); + mul_add_c(a[2], b[4], c1, c2, c3); + mul_add_c(a[1], b[5], c1, c2, c3); + mul_add_c(a[0], b[6], c1, c2, c3); + r[6] = c1; + c1 = 0; + mul_add_c(a[0], b[7], c2, c3, c1); + mul_add_c(a[1], b[6], c2, c3, c1); + mul_add_c(a[2], b[5], c2, c3, c1); + mul_add_c(a[3], b[4], c2, c3, c1); + mul_add_c(a[4], b[3], c2, c3, c1); + mul_add_c(a[5], b[2], c2, c3, c1); + mul_add_c(a[6], b[1], c2, c3, c1); + mul_add_c(a[7], b[0], c2, c3, c1); + r[7] = c2; + c2 = 0; + mul_add_c(a[7], b[1], c3, c1, c2); + mul_add_c(a[6], b[2], c3, c1, c2); + mul_add_c(a[5], b[3], c3, c1, c2); + mul_add_c(a[4], b[4], c3, c1, c2); + mul_add_c(a[3], b[5], c3, c1, c2); + mul_add_c(a[2], b[6], c3, c1, c2); + mul_add_c(a[1], b[7], c3, c1, c2); + r[8] = c3; + c3 = 0; + mul_add_c(a[2], b[7], c1, c2, c3); + mul_add_c(a[3], b[6], c1, c2, c3); + mul_add_c(a[4], b[5], c1, c2, c3); + mul_add_c(a[5], b[4], c1, c2, c3); + mul_add_c(a[6], b[3], c1, c2, c3); + mul_add_c(a[7], b[2], c1, c2, c3); + r[9] = c1; + c1 = 0; + mul_add_c(a[7], b[3], c2, c3, c1); + mul_add_c(a[6], b[4], c2, c3, c1); + mul_add_c(a[5], b[5], c2, c3, c1); + mul_add_c(a[4], b[6], c2, c3, c1); + mul_add_c(a[3], b[7], c2, c3, c1); + r[10] = c2; + c2 = 0; + mul_add_c(a[4], b[7], c3, c1, c2); + mul_add_c(a[5], b[6], c3, c1, c2); + mul_add_c(a[6], b[5], c3, c1, c2); + mul_add_c(a[7], b[4], c3, c1, c2); + r[11] = c3; + c3 = 0; + mul_add_c(a[7], b[5], c1, c2, c3); + mul_add_c(a[6], b[6], c1, c2, c3); + mul_add_c(a[5], b[7], c1, c2, c3); + r[12] = c1; + c1 = 0; + mul_add_c(a[6], b[7], c2, c3, c1); + mul_add_c(a[7], b[6], c2, c3, c1); + r[13] = c2; + c2 = 0; + mul_add_c(a[7], b[7], c3, c1, c2); + r[14] = c3; + r[15] = c1; +} + +void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) +{ + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + mul_add_c(a[0], b[0], c1, c2, c3); + r[0] = c1; + c1 = 0; + mul_add_c(a[0], b[1], c2, c3, c1); + mul_add_c(a[1], b[0], c2, c3, c1); + r[1] = c2; + c2 = 0; + mul_add_c(a[2], b[0], c3, c1, c2); + mul_add_c(a[1], b[1], c3, c1, c2); + mul_add_c(a[0], b[2], c3, c1, c2); + r[2] = c3; + c3 = 0; + mul_add_c(a[0], b[3], c1, c2, c3); + mul_add_c(a[1], b[2], c1, c2, c3); + mul_add_c(a[2], b[1], c1, c2, c3); + mul_add_c(a[3], b[0], c1, c2, c3); + r[3] = c1; + c1 = 0; + mul_add_c(a[3], b[1], c2, c3, c1); + mul_add_c(a[2], b[2], c2, c3, c1); + mul_add_c(a[1], b[3], c2, c3, c1); + r[4] = c2; + c2 = 0; + mul_add_c(a[2], b[3], c3, c1, c2); + mul_add_c(a[3], b[2], c3, c1, c2); + r[5] = c3; + c3 = 0; + mul_add_c(a[3], b[3], c1, c2, c3); + r[6] = c1; + r[7] = c2; +} + +void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) +{ + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + sqr_add_c(a, 0, c1, c2, c3); + r[0] = c1; + c1 = 0; + sqr_add_c2(a, 1, 0, c2, c3, c1); + r[1] = c2; + c2 = 0; + sqr_add_c(a, 1, c3, c1, c2); + sqr_add_c2(a, 2, 0, c3, c1, c2); + r[2] = c3; + c3 = 0; + sqr_add_c2(a, 3, 0, c1, c2, c3); + sqr_add_c2(a, 2, 1, c1, c2, c3); + r[3] = c1; + c1 = 0; + sqr_add_c(a, 2, c2, c3, c1); + sqr_add_c2(a, 3, 1, c2, c3, c1); + sqr_add_c2(a, 4, 0, c2, c3, c1); + r[4] = c2; + c2 = 0; + sqr_add_c2(a, 5, 0, c3, c1, c2); + sqr_add_c2(a, 4, 1, c3, c1, c2); + sqr_add_c2(a, 3, 2, c3, c1, c2); + r[5] = c3; + c3 = 0; + sqr_add_c(a, 3, c1, c2, c3); + sqr_add_c2(a, 4, 2, c1, c2, c3); + sqr_add_c2(a, 5, 1, c1, c2, c3); + sqr_add_c2(a, 6, 0, c1, c2, c3); + r[6] = c1; + c1 = 0; + sqr_add_c2(a, 7, 0, c2, c3, c1); + sqr_add_c2(a, 6, 1, c2, c3, c1); + sqr_add_c2(a, 5, 2, c2, c3, c1); + sqr_add_c2(a, 4, 3, c2, c3, c1); + r[7] = c2; + c2 = 0; + sqr_add_c(a, 4, c3, c1, c2); + sqr_add_c2(a, 5, 3, c3, c1, c2); + sqr_add_c2(a, 6, 2, c3, c1, c2); + sqr_add_c2(a, 7, 1, c3, c1, c2); + r[8] = c3; + c3 = 0; + sqr_add_c2(a, 7, 2, c1, c2, c3); + sqr_add_c2(a, 6, 3, c1, c2, c3); + sqr_add_c2(a, 5, 4, c1, c2, c3); + r[9] = c1; + c1 = 0; + sqr_add_c(a, 5, c2, c3, c1); + sqr_add_c2(a, 6, 4, c2, c3, c1); + sqr_add_c2(a, 7, 3, c2, c3, c1); + r[10] = c2; + c2 = 0; + sqr_add_c2(a, 7, 4, c3, c1, c2); + sqr_add_c2(a, 6, 5, c3, c1, c2); + r[11] = c3; + c3 = 0; + sqr_add_c(a, 6, c1, c2, c3); + sqr_add_c2(a, 7, 5, c1, c2, c3); + r[12] = c1; + c1 = 0; + sqr_add_c2(a, 7, 6, c2, c3, c1); + r[13] = c2; + c2 = 0; + sqr_add_c(a, 7, c3, c1, c2); + r[14] = c3; + r[15] = c1; +} + +void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) +{ + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + sqr_add_c(a, 0, c1, c2, c3); + r[0] = c1; + c1 = 0; + sqr_add_c2(a, 1, 0, c2, c3, c1); + r[1] = c2; + c2 = 0; + sqr_add_c(a, 1, c3, c1, c2); + sqr_add_c2(a, 2, 0, c3, c1, c2); + r[2] = c3; + c3 = 0; + sqr_add_c2(a, 3, 0, c1, c2, c3); + sqr_add_c2(a, 2, 1, c1, c2, c3); + r[3] = c1; + c1 = 0; + sqr_add_c(a, 2, c2, c3, c1); + sqr_add_c2(a, 3, 1, c2, c3, c1); + r[4] = c2; + c2 = 0; + sqr_add_c2(a, 3, 2, c3, c1, c2); + r[5] = c3; + c3 = 0; + sqr_add_c(a, 3, c1, c2, c3); + r[6] = c1; + r[7] = c2; +} + +#include +/* + * This is essentially reference implementation, which may or may not + * result in performance improvement. E.g. on IA-32 this routine was + * observed to give 40% faster rsa1024 private key operations and 10% + * faster rsa4096 ones, while on AMD64 it improves rsa1024 sign only + * by 10% and *worsens* rsa4096 sign by 15%. Once again, it's a + * reference implementation, one to be used as starting point for + * platform-specific assembler. Mentioned numbers apply to compiler + * generated code compiled with and without -DOPENSSL_BN_ASM_MONT and + * can vary not only from platform to platform, but even for compiler + * versions. Assembler vs. assembler improvement coefficients can + * [and are known to] differ and are to be documented elsewhere. + */ +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0p, int num) +{ + BN_ULONG c0, c1, ml, *tp, n0; + volatile BN_ULONG *vp; + int i = 0, j; + +#if 0 /* template for platform-specific \ + * implementation */ + if (ap == bp) + return bn_sqr_mont(rp, ap, np, n0p, num); +#endif + vp = tp = alloca((num + 2) * sizeof(BN_ULONG)); + + n0 = *n0p; + + c0 = 0; + ml = bp[0]; + + for (j = 0; j < num; ++j) + mul(tp[j], ap[j], ml, c0); + + tp[num] = c0; + tp[num + 1] = 0; + goto enter; + + for (i = 0; i < num; i++) { + c0 = 0; + ml = bp[i]; + + for (j = 0; j < num; ++j) + mul_add(tp[j], ap[j], ml, c0); + + c1 = (tp[num] + c0) & BN_MASK2; + tp[num] = c1; + tp[num + 1] = (c1 < c0 ? 1 : 0); + enter: + c1 = tp[0]; + ml = (c1 * n0) & BN_MASK2; + c0 = 0; + + mul_add(c1, ml, np[0], c0); + + for (j = 1; j < num; j++) { + c1 = tp[j]; + mul_add(c1, ml, np[j], c0); + tp[j - 1] = c1 & BN_MASK2; + } + c1 = (tp[num] + c0) & BN_MASK2; + tp[num - 1] = c1; + tp[num] = tp[num + 1] + (c1 < c0 ? 1 : 0); + } + + if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) { + c0 = bn_sub_words(rp, tp, np, num); + if (tp[num] != 0 || c0 == 0) { + for (i = 0; i < num + 2; i++) + vp[i] = 0; + return 1; + } + } + for (i = 0; i < num; i++) + rp[i] = tp[i], vp[i] = 0; + vp[num] = 0; + vp[num + 1] = 0; + return 1; +} +#endif /* !OPENSSL_SMALL_FOOTPRINT */ diff --git a/crypto/bn/asm/e2kv6-gf2m.c b/crypto/bn/asm/e2kv6-gf2m.c new file mode 100644 index 0000000000000..83c2729a0ba29 --- /dev/null +++ b/crypto/bn/asm/e2kv6-gf2m.c @@ -0,0 +1,30 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#include "../bn_local.h" + +void bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0, + const BN_ULONG b1, const BN_ULONG b0) +{ + BN_ULONG m1, m0; + + r[3] = __builtin_e2k_clmulh(a1, b1); + r[2] = __builtin_e2k_clmull(a1, b1); + + r[1] = __builtin_e2k_clmulh(a0, b0); + r[0] = __builtin_e2k_clmull(a0, b0); + + m1 = __builtin_e2k_clmulh(a0 ^ a1, b0 ^ b1); + m0 = __builtin_e2k_clmull(a0 ^ a1, b0 ^ b1); + + r[2] ^= __builtin_e2k_plog(0x96, m1, r[1], r[3]); + r[1] = __builtin_e2k_plog(0x96, r[3], r[2], __builtin_e2k_plog(0x96, r[0], m1, m0)); +} diff --git a/crypto/bn/asm/mips-mont.pl b/crypto/bn/asm/mips-mont.pl index b26989271f622..2aeb927ee99bb 100644 --- a/crypto/bn/asm/mips-mont.pl +++ b/crypto/bn/asm/mips-mont.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2010-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2010-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/asm/mips.pl b/crypto/bn/asm/mips.pl index 0e7046ac48a00..bec55b954e8b0 100644 --- a/crypto/bn/asm/mips.pl +++ b/crypto/bn/asm/mips.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2010-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2010-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/asm/riscv64-mont.pl b/crypto/bn/asm/riscv64-mont.pl index f9db3c11eba04..098ae6b960bb6 100644 --- a/crypto/bn/asm/riscv64-mont.pl +++ b/crypto/bn/asm/riscv64-mont.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/asm/rsaz-2k-avx512.pl b/crypto/bn/asm/rsaz-2k-avx512.pl index 7e1db31e223ac..6c0cb566f9d7a 100644 --- a/crypto/bn/asm/rsaz-2k-avx512.pl +++ b/crypto/bn/asm/rsaz-2k-avx512.pl @@ -1,4 +1,4 @@ -# Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2020, Intel Corporation. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/bn/asm/rsaz-2k-avxifma.pl b/crypto/bn/asm/rsaz-2k-avxifma.pl index 652d659442892..52d9781834d68 100644 --- a/crypto/bn/asm/rsaz-2k-avxifma.pl +++ b/crypto/bn/asm/rsaz-2k-avxifma.pl @@ -1,4 +1,4 @@ -# Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2024, Intel Corporation. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/bn/asm/rsaz-3k-avx512.pl b/crypto/bn/asm/rsaz-3k-avx512.pl index 403e09099f732..fe5b1ebefab6e 100644 --- a/crypto/bn/asm/rsaz-3k-avx512.pl +++ b/crypto/bn/asm/rsaz-3k-avx512.pl @@ -1,4 +1,4 @@ -# Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2021, Intel Corporation. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/bn/asm/rsaz-3k-avxifma.pl b/crypto/bn/asm/rsaz-3k-avxifma.pl index 9141e552bd334..aa11c546af6db 100644 --- a/crypto/bn/asm/rsaz-3k-avxifma.pl +++ b/crypto/bn/asm/rsaz-3k-avxifma.pl @@ -1,4 +1,4 @@ -# Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2024, Intel Corporation. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/bn/asm/rsaz-4k-avx512.pl b/crypto/bn/asm/rsaz-4k-avx512.pl index f41c1c60df838..b07180f6feca7 100644 --- a/crypto/bn/asm/rsaz-4k-avx512.pl +++ b/crypto/bn/asm/rsaz-4k-avx512.pl @@ -1,4 +1,4 @@ -# Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2021, Intel Corporation. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/bn/asm/rsaz-4k-avxifma.pl b/crypto/bn/asm/rsaz-4k-avxifma.pl index 2f7b036e5d5ba..28a447800d0d7 100644 --- a/crypto/bn/asm/rsaz-4k-avxifma.pl +++ b/crypto/bn/asm/rsaz-4k-avxifma.pl @@ -1,4 +1,4 @@ -# Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2024, Intel Corporation. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/bn/asm/rsaz-avx2.pl b/crypto/bn/asm/rsaz-avx2.pl index 239ffb7e2b72c..72e4afe2dfc4b 100755 --- a/crypto/bn/asm/rsaz-avx2.pl +++ b/crypto/bn/asm/rsaz-avx2.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2013-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2013-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2012, Intel Corporation. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/bn/asm/rsaz-x86_64.pl b/crypto/bn/asm/rsaz-x86_64.pl index ea6f3f2ac6c52..faa360af2b867 100755 --- a/crypto/bn/asm/rsaz-x86_64.pl +++ b/crypto/bn/asm/rsaz-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2013-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2013-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2012, Intel Corporation. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/bn/asm/sparct4-mont.pl b/crypto/bn/asm/sparct4-mont.pl index 1d2747c4ca94b..341959035b79d 100755 --- a/crypto/bn/asm/sparct4-mont.pl +++ b/crypto/bn/asm/sparct4-mont.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2012-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2012-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/asm/sparcv9-gf2m.pl b/crypto/bn/asm/sparcv9-gf2m.pl index 2cd0498aa1c8e..5ef817457f548 100644 --- a/crypto/bn/asm/sparcv9-gf2m.pl +++ b/crypto/bn/asm/sparcv9-gf2m.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2012-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2012-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/asm/sparcv9a-mont.pl b/crypto/bn/asm/sparcv9a-mont.pl index 81fc807625634..6b6393be07acb 100755 --- a/crypto/bn/asm/sparcv9a-mont.pl +++ b/crypto/bn/asm/sparcv9a-mont.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/asm/vis3-mont.pl b/crypto/bn/asm/vis3-mont.pl index 65a6c23e3c960..5181ba4a4d2cc 100644 --- a/crypto/bn/asm/vis3-mont.pl +++ b/crypto/bn/asm/vis3-mont.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2012-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2012-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/asm/x86_64-gcc.c b/crypto/bn/asm/x86_64-gcc.c index 03299a7b72ea9..c9081d35d8474 100644 --- a/crypto/bn/asm/x86_64-gcc.c +++ b/crypto/bn/asm/x86_64-gcc.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/asm/x86_64-mont.pl b/crypto/bn/asm/x86_64-mont.pl index 3b3bd747e5a8a..c40fa0c69c9b6 100755 --- a/crypto/bn/asm/x86_64-mont.pl +++ b/crypto/bn/asm/x86_64-mont.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/asm/x86_64-mont5.pl b/crypto/bn/asm/x86_64-mont5.pl index 95d34e0b50867..6bc91b550cd1f 100755 --- a/crypto/bn/asm/x86_64-mont5.pl +++ b/crypto/bn/asm/x86_64-mont5.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_add.c b/crypto/bn/bn_add.c index 24151d0e13d8f..501e88c0735fb 100644 --- a/crypto/bn/bn_add.c +++ b/crypto/bn/bn_add.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_const.c b/crypto/bn/bn_const.c index 1dfdbf6ac01d6..07a3a4a7c380f 100644 --- a/crypto/bn/bn_const.c +++ b/crypto/bn/bn_const.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_conv.c b/crypto/bn/bn_conv.c index f295e5db9a963..47e7dcd8b14bd 100644 --- a/crypto/bn/bn_conv.c +++ b/crypto/bn/bn_conv.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,6 +7,8 @@ * https://www.openssl.org/source/license.html */ +#include + #include #include "crypto/ctype.h" #include "bn_local.h" @@ -93,14 +95,14 @@ char *BN_bn2dec(const BIGNUM *a) * the last one needs truncation. The blocks need to be reversed in * order. */ - n = BIO_snprintf(p, tbytes - (size_t)(p - buf), BN_DEC_FMT1, *lp); - if (n < 0) + n = snprintf(p, tbytes - (size_t)(p - buf), BN_DEC_FMT1, *lp); + if (n < 0 || (size_t)n >= tbytes - (size_t)(p - buf)) goto err; p += n; while (lp != bn_data) { lp--; - n = BIO_snprintf(p, tbytes - (size_t)(p - buf), BN_DEC_FMT2, *lp); - if (n < 0) + n = snprintf(p, tbytes - (size_t)(p - buf), BN_DEC_FMT2, *lp); + if (n < 0 || (size_t)n >= tbytes - (size_t)(p - buf)) goto err; p += n; } diff --git a/crypto/bn/bn_div.c b/crypto/bn/bn_div.c index a731b2d37ddbf..bcc483ac61eea 100644 --- a/crypto/bn/bn_div.c +++ b/crypto/bn/bn_div.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_err.c b/crypto/bn/bn_err.c deleted file mode 100644 index 84aaf75b529e1..0000000000000 --- a/crypto/bn/bn_err.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/bnerr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA BN_str_reasons[] = { - { ERR_PACK(ERR_LIB_BN, 0, BN_R_ARG2_LT_ARG3), "arg2 lt arg3" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_BAD_RECIPROCAL), "bad reciprocal" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_BIGNUM_TOO_LONG), "bignum too long" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_BITS_TOO_SMALL), "bits too small" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_CALLED_WITH_EVEN_MODULUS), - "called with even modulus" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_DIV_BY_ZERO), "div by zero" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_ENCODING_ERROR), "encoding error" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA), - "expand on static bignum data" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_INPUT_NOT_REDUCED), "input not reduced" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_INVALID_LENGTH), "invalid length" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_INVALID_RANGE), "invalid range" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_INVALID_SHIFT), "invalid shift" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_NOT_A_SQUARE), "not a square" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_NOT_INITIALIZED), "not initialized" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_NO_INVERSE), "no inverse" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_NO_PRIME_CANDIDATE), "no prime candidate" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_NO_SOLUTION), "no solution" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_NO_SUITABLE_DIGEST), "no suitable digest" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_PRIVATE_KEY_TOO_LARGE), - "private key too large" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_P_IS_NOT_PRIME), "p is not prime" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_TOO_MANY_ITERATIONS), "too many iterations" }, - { ERR_PACK(ERR_LIB_BN, 0, BN_R_TOO_MANY_TEMPORARY_VARIABLES), - "too many temporary variables" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_BN_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(BN_str_reasons[0].error) == NULL) - ERR_load_strings_const(BN_str_reasons); -#endif - return 1; -} diff --git a/crypto/bn/bn_exp.c b/crypto/bn/bn_exp.c index c3bd5e7b5dcdb..535d2d1f52320 100644 --- a/crypto/bn/bn_exp.c +++ b/crypto/bn/bn_exp.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -552,7 +552,7 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, BN_ULONG acc = 0; for (j = 0; j < width; j++) { - acc |= table[j] & ((BN_ULONG)0 - (constant_time_eq_int(j, idx) & 1)); + acc |= table[j] & value_barrier_bn((BN_ULONG)0 - (constant_time_eq_int(j, idx) & 1)); } b->d[i] = acc; @@ -573,8 +573,9 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, BN_ULONG acc = 0; for (j = 0; j < xstride; j++) { - acc |= ((table[j + 0 * xstride] & y0) | (table[j + 1 * xstride] & y1) | (table[j + 2 * xstride] & y2) | (table[j + 3 * xstride] & y3)) - & ((BN_ULONG)0 - (constant_time_eq_int(j, idx) & 1)); + acc |= ((table[j + 0 * xstride] & value_barrier_bn(y0)) | (table[j + 1 * xstride] & value_barrier_bn(y1)) + | (table[j + 2 * xstride] & value_barrier_bn(y2)) | (table[j + 3 * xstride] & value_barrier_bn(y3))) + & value_barrier_bn((BN_ULONG)0 - (constant_time_eq_int(j, idx) & 1)); } b->d[i] = acc; diff --git a/crypto/bn/bn_gcd.c b/crypto/bn/bn_gcd.c index 42d02ef12340e..5d7c076d9b56f 100644 --- a/crypto/bn/bn_gcd.c +++ b/crypto/bn/bn_gcd.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_gf2m.c b/crypto/bn/bn_gf2m.c index 81a7fda5b31b2..0ecfac021b743 100644 --- a/crypto/bn/bn_gf2m.c +++ b/crypto/bn/bn_gf2m.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/bn/bn_kron.c b/crypto/bn/bn_kron.c index b2dda11cc236f..177d674f98889 100644 --- a/crypto/bn/bn_kron.c +++ b/crypto/bn/bn_kron.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_lib.c b/crypto/bn/bn_lib.c index a63e2b9154e1d..494561b0fab81 100644 --- a/crypto/bn/bn_lib.c +++ b/crypto/bn/bn_lib.c @@ -28,13 +28,9 @@ * 8 - 256 == 8192 */ static int bn_limit_bits = 0; -static int bn_limit_num = 8; /* (1< (int)(sizeof(int) * 8) - 1) mult = sizeof(int) * 8 - 1; bn_limit_bits = mult; - bn_limit_num = 1 << mult; } if (high >= 0) { if (high > (int)(sizeof(int) * 8) - 1) high = sizeof(int) * 8 - 1; bn_limit_bits_high = high; - bn_limit_num_high = 1 << high; } if (low >= 0) { if (low > (int)(sizeof(int) * 8) - 1) low = sizeof(int) * 8 - 1; bn_limit_bits_low = low; - bn_limit_num_low = 1 << low; } if (mont >= 0) { if (mont > (int)(sizeof(int) * 8) - 1) mont = sizeof(int) * 8 - 1; bn_limit_bits_mont = mont; - bn_limit_num_mont = 1 << mont; } } @@ -89,6 +81,7 @@ const BIGNUM *BN_value_one(void) return &const_one; } +#ifndef __e2k__ int BN_num_bits_word(BN_ULONG l) { BN_ULONG x, mask; @@ -133,6 +126,20 @@ int BN_num_bits_word(BN_ULONG l) return bits; } +#else /* __e2k__ */ +#include +int BN_num_bits_word(BN_ULONG l) +{ + /* clz(0) is well-defined on e2k, hence no if (l == 0) return 0; + * is required here. + */ +#if BN_BITS2 > 32 + return 64 - __builtin_clzll(l); +#else + return 32 - __builtin_clz(l); +#endif +} +#endif /* __e2k__ */ /* * This function still leaks `a->dmax`: it's caller's responsibility to @@ -955,21 +962,24 @@ void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) condition = ((~condition & ((condition - 1))) >> (BN_BITS2 - 1)) - 1; - t = (a->top ^ b->top) & condition; + t = (a->top ^ b->top) & value_barrier_bn(condition); a->top ^= t; b->top ^= t; - t = (a->neg ^ b->neg) & condition; + t = (a->neg ^ b->neg) & value_barrier_bn(condition); a->neg ^= t; b->neg ^= t; /*- - * BN_FLG_STATIC_DATA: indicates that data may not be written to. Intention - * is actually to treat it as it's read-only data, and some (if not most) - * of it does reside in read-only segment. In other words observation of - * BN_FLG_STATIC_DATA in BN_consttime_swap should be treated as fatal - * condition. It would either cause SEGV or effectively cause data - * corruption. + * BN_FLG_STATIC_DATA: indicates that d points to a buffer that this + * BIGNUM does not own, so it must never be reallocated or freed through + * the BIGNUM. The flag by itself does not forbid writing to the words, + * but much of the data marked this way is compiled-in and does reside in + * a read-only segment. Since BN_consttime_swap writes to d, observing + * BN_FLG_STATIC_DATA here should be treated as a fatal condition: it + * would either cause SEGV or effectively cause data corruption. The flag + * is therefore never swapped, as it describes the storage of each d + * buffer, which is not exchanged. * * BN_FLG_MALLOCED: refers to BN structure itself, and hence must be * preserved. @@ -987,13 +997,13 @@ void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) #define BN_CONSTTIME_SWAP_FLAGS (BN_FLG_CONSTTIME | BN_FLG_FIXED_TOP) - t = ((a->flags ^ b->flags) & BN_CONSTTIME_SWAP_FLAGS) & condition; + t = ((a->flags ^ b->flags) & BN_CONSTTIME_SWAP_FLAGS) & value_barrier_bn(condition); a->flags ^= t; b->flags ^= t; /* conditionally swap the data */ for (i = 0; i < nwords; i++) { - t = (a->d[i] ^ b->d[i]) & condition; + t = (a->d[i] ^ b->d[i]) & value_barrier_bn(condition); a->d[i] ^= t; b->d[i] ^= t; } diff --git a/crypto/bn/bn_local.h b/crypto/bn/bn_local.h index 4602cdcaba0fc..506fcaa2b8501 100644 --- a/crypto/bn/bn_local.h +++ b/crypto/bn/bn_local.h @@ -443,6 +443,8 @@ unsigned __int64 _umul128(unsigned __int64 a, unsigned __int64 b, : "r"(a), "r"(b)); \ ret; }) #endif +#elif defined(__e2k__) && __iset__ >= 5 +#define BN_UMULT_HIGH(a, b) __builtin_e2k_umulhd(a, b) #endif /* cpu */ #endif /* OPENSSL_NO_ASM */ diff --git a/crypto/bn/bn_mod.c b/crypto/bn/bn_mod.c index 703072bbf22d2..236543ce8d9f3 100644 --- a/crypto/bn/bn_mod.c +++ b/crypto/bn/bn_mod.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_mont.c b/crypto/bn/bn_mont.c index 0bdfce3c485ee..e2f30931fc73c 100644 --- a/crypto/bn/bn_mont.c +++ b/crypto/bn/bn_mont.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_nist.c b/crypto/bn/bn_nist.c index b820ef74869ba..8573df2bc1daa 100644 --- a/crypto/bn/bn_nist.c +++ b/crypto/bn/bn_nist.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_ppc.c b/crypto/bn/bn_ppc.c index f7e2568ab7571..82b8c1ee61dd0 100644 --- a/crypto/bn/bn_ppc.c +++ b/crypto/bn/bn_ppc.c @@ -1,5 +1,5 @@ /* - * Copyright 2009-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2009-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_prime.c b/crypto/bn/bn_prime.c index 33a9fc8d672a9..7074fadcbc47a 100644 --- a/crypto/bn/bn_prime.c +++ b/crypto/bn/bn_prime.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_prime.h b/crypto/bn/bn_prime.h deleted file mode 100644 index 4038d99b6abe5..0000000000000 --- a/crypto/bn/bn_prime.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - * WARNING: do not edit! - * Generated by crypto/bn/bn_prime.pl - * - * Copyright 1998-2026 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#if !defined(OSSL_LIBCRYPTO_BN_BN_PRIME_H) -#define OSSL_LIBCRYPTO_BN_BN_PRIME_H - -/* clang-format off */ -typedef unsigned short prime_t; -# define NUMPRIMES 2048 - -static const prime_t primes[2048] = { - 2, 3, 5, 7, 11, 13, 17, 19, - 23, 29, 31, 37, 41, 43, 47, 53, - 59, 61, 67, 71, 73, 79, 83, 89, - 97, 101, 103, 107, 109, 113, 127, 131, - 137, 139, 149, 151, 157, 163, 167, 173, - 179, 181, 191, 193, 197, 199, 211, 223, - 227, 229, 233, 239, 241, 251, 257, 263, - 269, 271, 277, 281, 283, 293, 307, 311, - 313, 317, 331, 337, 347, 349, 353, 359, - 367, 373, 379, 383, 389, 397, 401, 409, - 419, 421, 431, 433, 439, 443, 449, 457, - 461, 463, 467, 479, 487, 491, 499, 503, - 509, 521, 523, 541, 547, 557, 563, 569, - 571, 577, 587, 593, 599, 601, 607, 613, - 617, 619, 631, 641, 643, 647, 653, 659, - 661, 673, 677, 683, 691, 701, 709, 719, - 727, 733, 739, 743, 751, 757, 761, 769, - 773, 787, 797, 809, 811, 821, 823, 827, - 829, 839, 853, 857, 859, 863, 877, 881, - 883, 887, 907, 911, 919, 929, 937, 941, - 947, 953, 967, 971, 977, 983, 991, 997, - 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, - 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, - 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, - 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, - 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, - 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, - 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, - 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, - 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, - 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, - 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, - 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, - 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, - 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, - 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, - 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, - 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, - 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, - 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, - 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, - 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, - 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, - 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, - 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, - 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, - 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, - 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, - 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, - 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, - 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, - 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, - 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, - 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, - 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, - 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, - 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, - 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, - 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, - 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, - 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, - 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, - 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, - 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, - 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, - 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, - 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, - 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, - 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, - 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, - 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, - 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, - 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, - 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, - 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, - 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, - 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, - 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, - 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, - 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, - 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, - 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, - 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, - 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, - 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, - 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, - 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, - 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, - 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, - 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, - 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, - 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, - 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, - 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, - 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, - 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, - 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, - 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, - 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, - 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, - 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, - 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, - 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, - 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, - 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, - 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, - 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, - 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, - 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, - 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, - 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, - 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, - 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, - 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, - 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, - 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, - 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, - 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, - 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, - 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, - 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, - 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, - 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, - 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, - 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, - 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, - 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, - 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, - 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, - 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, - 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, - 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, - 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, - 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, - 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, - 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, - 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, - 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, - 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, - 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, - 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, - 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, - 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, - 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, - 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, - 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, - 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, - 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, - 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, - 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, - 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, - 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, - 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, - 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037, - 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, - 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, - 10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247, - 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, - 10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369, - 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, - 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, - 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, - 10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691, - 10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771, - 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, - 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, - 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, - 11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087, - 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, - 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, - 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317, - 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, - 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, - 11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551, - 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, - 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, - 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, - 11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887, - 11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941, - 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, - 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, - 12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161, - 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251, - 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, - 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, - 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473, - 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, - 12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, - 12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653, - 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, - 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, - 12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907, - 12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967, - 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, - 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, - 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177, - 13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259, - 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, - 13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, - 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, - 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597, - 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, - 13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723, - 13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799, - 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, - 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, - 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033, - 14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143, - 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221, - 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, - 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407, - 14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461, - 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, - 14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627, - 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, - 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, - 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, - 14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887, - 14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957, - 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, - 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, - 15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217, - 15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277, - 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, - 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, - 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, - 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, - 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, - 15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727, - 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, - 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, - 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, - 15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007, - 16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087, - 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, - 16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249, - 16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349, - 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, - 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, - 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, - 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661, - 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, - 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, - 16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927, - 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, - 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, - 17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159, - 17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231, - 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, - 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, - 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467, - 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519, - 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, - 17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, - 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, - 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863, -}; -/* clang-format on */ - -#endif /* !defined(OSSL_LIBCRYPTO_BN_BN_PRIME_H) */ diff --git a/crypto/bn/bn_prime.pl b/crypto/bn/bn_prime.pl index 3d9722d0088a6..7535251be87f6 100644 --- a/crypto/bn/bn_prime.pl +++ b/crypto/bn/bn_prime.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1998-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_print.c b/crypto/bn/bn_print.c index a04e6cf0c2d8a..328e7421af745 100644 --- a/crypto/bn/bn_print.c +++ b/crypto/bn/bn_print.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -61,10 +61,10 @@ char *BN_options(void) if (!init) { init++; #ifdef BN_LLONG - BIO_snprintf(data, sizeof(data), "bn(%zu,%zu)", + snprintf(data, sizeof(data), "bn(%zu,%zu)", sizeof(BN_ULLONG) * 8, sizeof(BN_ULONG) * 8); #else - BIO_snprintf(data, sizeof(data), "bn(%zu,%zu)", + snprintf(data, sizeof(data), "bn(%zu,%zu)", sizeof(BN_ULONG) * 8, sizeof(BN_ULONG) * 8); #endif } diff --git a/crypto/bn/bn_recp.c b/crypto/bn/bn_recp.c index ab546ce9eb2fc..46534ae965ffe 100644 --- a/crypto/bn/bn_recp.c +++ b/crypto/bn/bn_recp.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_s390x.c b/crypto/bn/bn_s390x.c index 4e7aba35f6097..64842cf458bb2 100644 --- a/crypto/bn/bn_s390x.c +++ b/crypto/bn/bn_s390x.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_sparc.c b/crypto/bn/bn_sparc.c index 1dedbdf26f91d..48bafb5883cb7 100644 --- a/crypto/bn/bn_sparc.c +++ b/crypto/bn/bn_sparc.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_sqrt.c b/crypto/bn/bn_sqrt.c index 2f2d9e446f924..5f8f8e4e894dc 100644 --- a/crypto/bn/bn_sqrt.c +++ b/crypto/bn/bn_sqrt.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/bn_x931p.c b/crypto/bn/bn_x931p.c index 67d0431cc5586..7eb62957740e2 100644 --- a/crypto/bn/bn_x931p.c +++ b/crypto/bn/bn_x931p.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/bn/build.info b/crypto/bn/build.info index 01e98e45443cb..691fd514d8b5d 100644 --- a/crypto/bn/build.info +++ b/crypto/bn/build.info @@ -90,6 +90,13 @@ IF[{- !$disabled{asm} -}] $BNASM_c64xplus_ec2m=c64xplus-gf2m.s $BNDEF_c64xplus_ec2m=OPENSSL_BN_ASM_GF2m + $BNASM_e2k=asm/e2k-bn-asm.c + $BNDEF_e2k=OPENSSL_BN_ASM_MONT + $BNASM_e2kv6=asm/e2kv6-gf2m.c $BNASM_e2k + $BNDEF_e2kv6=OPENSSL_BN_ASM_GF2m $BNDEF_e2k + $BNASM_e2kv7=asm/e2kv6-gf2m.c $BNASM_e2k + $BNDEF_e2kv7=OPENSSL_BN_ASM_GF2m $BNDEF_e2k + # Now that we have defined all the arch specific variables, use the # appropriate ones, and define the appropriate macros IF[$BNASM_{- $target{asm_arch} -}] @@ -187,3 +194,7 @@ GENERATE[armv8-mont.S]=asm/armv8-mont.pl INCLUDE[armv8-mont.o]=.. GENERATE[riscv64-mont.S]=asm/riscv64-mont.pl INCLUDE[riscv64-mont.o]=.. + +DEPEND[bn_prime.o]=bn_prime.h +GENERATE[bn_prime.h]=bn_prime.pl +INCLUDE[bn_prime.o]=. diff --git a/crypto/buffer/buf_err.c b/crypto/buffer/buf_err.c deleted file mode 100644 index 32209c0829800..0000000000000 --- a/crypto/buffer/buf_err.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/buffererr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA BUF_str_reasons[] = { - { 0, NULL } -}; - -#endif - -int ossl_err_load_BUF_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(BUF_str_reasons[0].error) == NULL) - ERR_load_strings_const(BUF_str_reasons); -#endif - return 1; -} diff --git a/crypto/build.info b/crypto/build.info index 4e9068407cfff..191bc1f3f3e88 100644 --- a/crypto/build.info +++ b/crypto/build.info @@ -3,10 +3,10 @@ SUBDIRS=objects buffer bio stack lhash hashtable rand evp asn1 pem x509 conf \ txt_db pkcs7 pkcs12 ui kdf store property \ md2 md4 md5 sha mdc2 ml_kem hmac ripemd whrlpool poly1305 \ - siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \ + siphash sm3 des aes rc2 rc4 rc5 idea aria ascon bf cast camellia \ seed sm4 chacha modes bn ec rsa dsa dh sm2 dso \ err comp http ocsp cms ts srp cmac ct async ess crmf cmp encode_decode \ - ffc hpke thread lms ml_dsa slh_dsa + ffc hpke thread lms ml_dsa slh_dsa rbtree LIBS=../libcrypto @@ -140,3 +140,9 @@ GENERATE[loongarch64cpuid.s]=loongarch64cpuid.pl IF[{- $config{target} =~ /^(?:Cygwin|mingw|VC-|BC-)/ -}] SHARED_SOURCE[../libcrypto]=dllmain.c ENDIF + +INCLUDE[init.o]=. + +IF[{- $target{needs_c99_snprintf_compat} -}] + SOURCE[../libcrypto]=msvc2013_snprintf.c +ENDIF diff --git a/crypto/camellia/asm/cmllt4-sparcv9.pl b/crypto/camellia/asm/cmllt4-sparcv9.pl index c1299397e3c2e..8a892c573ee90 100644 --- a/crypto/camellia/asm/cmllt4-sparcv9.pl +++ b/crypto/camellia/asm/cmllt4-sparcv9.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2012-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2012-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/camellia/camellia.c b/crypto/camellia/camellia.c index 8841baa7a51e5..efe5d78899ffa 100644 --- a/crypto/camellia/camellia.c +++ b/crypto/camellia/camellia.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/camellia/cmll_local.h b/crypto/camellia/cmll_local.h index 45b8dc0e2d54d..010bdf3d60b40 100644 --- a/crypto/camellia/cmll_local.h +++ b/crypto/camellia/cmll_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2006-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/cast/c_cfb64.c b/crypto/cast/c_cfb64.c index 477762005f70c..3de52f56af466 100644 --- a/crypto/cast/c_cfb64.c +++ b/crypto/cast/c_cfb64.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/cast/c_ofb64.c b/crypto/cast/c_ofb64.c index c130f9183fc9e..dbd6e02729d29 100644 --- a/crypto/cast/c_ofb64.c +++ b/crypto/cast/c_ofb64.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/cast/cast_local.h b/crypto/cast/cast_local.h index e18a8eee7cc0e..192d718c3d95d 100644 --- a/crypto/cast/cast_local.h +++ b/crypto/cast/cast_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/cast/cast_s.h b/crypto/cast/cast_s.h index eb4159d61549a..e5abfeb6f2e10 100644 --- a/crypto/cast/cast_s.h +++ b/crypto/cast/cast_s.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/chacha/asm/chacha-armv4.pl b/crypto/chacha/asm/chacha-armv4.pl index 24acb742b0731..ee8fff32632a8 100755 --- a/crypto/chacha/asm/chacha-armv4.pl +++ b/crypto/chacha/asm/chacha-armv4.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/chacha/asm/chacha-armv8-sve.pl b/crypto/chacha/asm/chacha-armv8-sve.pl index df5232d62139c..44c3b8d462d89 100755 --- a/crypto/chacha/asm/chacha-armv8-sve.pl +++ b/crypto/chacha/asm/chacha-armv8-sve.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/chacha/asm/chacha-armv8.pl b/crypto/chacha/asm/chacha-armv8.pl index ccbc816136eec..05917805f3372 100755 --- a/crypto/chacha/asm/chacha-armv8.pl +++ b/crypto/chacha/asm/chacha-armv8.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/chacha/asm/chacha-loongarch64.pl b/crypto/chacha/asm/chacha-loongarch64.pl index e78f668927c70..658c421b33af8 100644 --- a/crypto/chacha/asm/chacha-loongarch64.pl +++ b/crypto/chacha/asm/chacha-loongarch64.pl @@ -1,6 +1,6 @@ #! /usr/bin/env perl # Author: Min Zhou -# Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/chacha/asm/chacha-s390x.pl b/crypto/chacha/asm/chacha-s390x.pl index a5a7102b7a0d2..099f2c154984d 100755 --- a/crypto/chacha/asm/chacha-s390x.pl +++ b/crypto/chacha/asm/chacha-s390x.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/chacha/asm/chacha-x86.pl b/crypto/chacha/asm/chacha-x86.pl index 6a64a57651dfa..7e28d6b1fe4ca 100755 --- a/crypto/chacha/asm/chacha-x86.pl +++ b/crypto/chacha/asm/chacha-x86.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/chacha/asm/chacha-x86_64.pl b/crypto/chacha/asm/chacha-x86_64.pl index ed54836dbf215..d991d40739904 100755 --- a/crypto/chacha/asm/chacha-x86_64.pl +++ b/crypto/chacha/asm/chacha-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/chacha/asm/chachap10-ppc.pl b/crypto/chacha/asm/chachap10-ppc.pl index 10f8a57749901..823fd9300c31a 100755 --- a/crypto/chacha/asm/chachap10-ppc.pl +++ b/crypto/chacha/asm/chachap10-ppc.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/chacha/build.info b/crypto/chacha/build.info index c151e190429d1..41c22f7a981b9 100644 --- a/crypto/chacha/build.info +++ b/crypto/chacha/build.info @@ -25,6 +25,10 @@ IF[{- !$disabled{asm} -}] $CHACHAASM_riscv64=chacha_riscv.c chacha_enc.c chacha-riscv64-v-zbb.s chacha-riscv64-v-zbb-zvkb.s $CHACHADEF_riscv64=INCLUDE_C_CHACHA20 + $CHACHAASM_e2k=chacha_e2k.c + $CHACHAASM_e2kv6=chacha_e2k.c + $CHACHAASM_e2kv7=chacha_e2k.c + # Now that we have defined all the arch specific variables, use the # appropriate one IF[$CHACHAASM_{- $target{asm_arch} -}] diff --git a/crypto/chacha/chacha_e2k.c b/crypto/chacha/chacha_e2k.c new file mode 100644 index 0000000000000..88ac0ab715fd6 --- /dev/null +++ b/crypto/chacha/chacha_e2k.c @@ -0,0 +1,256 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#include "internal/endian.h" +#include "crypto/chacha.h" +#include "crypto/ctype.h" + +typedef uint32_t u32; +typedef uint8_t u8; + +#include +#include + +#if __iset__ >= 5 /* 128-bit SIMD */ + +/* QUARTERROUND updates a, b, c, d with a ChaCha "quarter" round. */ +#define QUARTERROUND(a, b, c, d) ( \ + x[a] = __builtin_e2k_qpaddw(x[a], x[b]), x[d] = __builtin_e2k_qpsrcw(__builtin_e2k_qpxor(x[d], x[a]), 32 - 16), \ + x[c] = __builtin_e2k_qpaddw(x[c], x[d]), x[b] = __builtin_e2k_qpsrcw(__builtin_e2k_qpxor(x[b], x[c]), 32 - 12), \ + x[a] = __builtin_e2k_qpaddw(x[a], x[b]), x[d] = __builtin_e2k_qpsrcw(__builtin_e2k_qpxor(x[d], x[a]), 32 - 8), \ + x[c] = __builtin_e2k_qpaddw(x[c], x[d]), x[b] = __builtin_e2k_qpsrcw(__builtin_e2k_qpxor(x[b], x[c]), 32 - 7)) + +/* chacha_core performs 20 rounds of ChaCha on the input words in + * |input| and writes the 64 output bytes to |output|. + */ +static inline __attribute__((__always_inline__)) void chacha20_core_x4(__v2di *output, const __v2di input[16]) +{ + __v2di x[16]; + int i; + memcpy(x, input, sizeof(x)); + + for (i = 20; i > 0; i -= 2) { + QUARTERROUND(0, 4, 8, 12); + QUARTERROUND(1, 5, 9, 13); + QUARTERROUND(2, 6, 10, 14); + QUARTERROUND(3, 7, 11, 15); + QUARTERROUND(0, 5, 10, 15); + QUARTERROUND(1, 6, 11, 12); + QUARTERROUND(2, 7, 8, 13); + QUARTERROUND(3, 4, 9, 14); + } + + for (i = 0; i < 16; ++i) + output[i] = __builtin_e2k_qpaddw(x[i], input[i]); +} + +void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, size_t len, + const unsigned int key[8], const unsigned int counter[4]) +{ + u32 input[16]; + __v2di input_x4[16]; + __v2di buf[16]; + size_t todo, i; + + /* sigma constant "expand 32-byte k" in little-endian encoding */ + input[0] = ((u32)('e')) | ((u32)('x') << 8) | ((u32)('p') << 16) | ((u32)('a') << 24); + input[1] = ((u32)('n')) | ((u32)('d') << 8) | ((u32)(' ') << 16) | ((u32)('3') << 24); + input[2] = ((u32)('2')) | ((u32)('-') << 8) | ((u32)('b') << 16) | ((u32)('y') << 24); + input[3] = ((u32)('t')) | ((u32)('e') << 8) | ((u32)(' ') << 16) | ((u32)('k') << 24); + + input[4] = key[0]; + input[5] = key[1]; + input[6] = key[2]; + input[7] = key[3]; + input[8] = key[4]; + input[9] = key[5]; + input[10] = key[6]; + input[11] = key[7]; + + input[12] = counter[0]; + input[13] = counter[1]; + input[14] = counter[2]; + input[15] = counter[3]; + + for (i = 0; i < 16; i++) { + unsigned long long w = input[i] * 0x100000001LL; + input_x4[i] = __builtin_e2k_qppackdl(w, w); + } + + input_x4[12] = __builtin_e2k_qpaddw(input_x4[12], (__v2di) { 0x100000000LL, 0x300000002LL }); + + while (len > 0) { + __v2di buf_tran[16]; + + chacha20_core_x4(buf, input_x4); + + for (i = 0; i < 16; i += 4) { + const __v2di f1 = __builtin_e2k_qppackdl(0x1f1e1d1c0f0e0d0cLL, 0x1716151407060504LL); + const __v2di f0 = __builtin_e2k_qppackdl(0x1b1a19180b0a0908LL, 0x1312111003020100LL); + + const __v2di f3 = __builtin_e2k_qppackdl(0x1f1e1d1c1b1a1918LL, 0x0f0e0d0c0b0a0908LL); + const __v2di f2 = __builtin_e2k_qppackdl(0x1716151413121110LL, 0x0706050403020100LL); + + __v2di t0 = __builtin_e2k_qppermb(buf[i + 1], buf[i + 0], f0); + __v2di t1 = __builtin_e2k_qppermb(buf[i + 1], buf[i + 0], f1); + __v2di t2 = __builtin_e2k_qppermb(buf[i + 3], buf[i + 2], f0); + __v2di t3 = __builtin_e2k_qppermb(buf[i + 3], buf[i + 2], f1); + + buf_tran[i / 4 + 0] = __builtin_e2k_qppermb(t2, t0, f2); + buf_tran[i / 4 + 4] = __builtin_e2k_qppermb(t3, t1, f2); + buf_tran[i / 4 + 8] = __builtin_e2k_qppermb(t2, t0, f3); + buf_tran[i / 4 + 12] = __builtin_e2k_qppermb(t3, t1, f3); + } + + todo = sizeof(buf); + if (__builtin_expect(len < todo, 0)) { + todo = len & ~(size_t)15; + + for (i = 0; i < todo; i += 16) { + *(__v2di *)&out[i] = __builtin_e2k_qpxor(*(__v2di *)&inp[i], buf_tran[i / 16]); + } + for (; i < len; i++) { + out[i] = inp[i] ^ ((u8 *)buf_tran)[i]; + } + return; + } + + for (i = 0; i < todo; i += 16) { + *(__v2di *)&out[i] = __builtin_e2k_qpxor(*(__v2di *)&inp[i], buf_tran[i / 16]); + } + + /* + * Advance 32-bit counters. Note that as subroutine is so to + * say nonce-agnostic, this limited counter width doesn't + * prevent caller from implementing wider counter. It would + * simply take two calls split on counter overflow... + */ + input_x4[12] = __builtin_e2k_qpaddw(input_x4[12], (__v2di) { 0x400000004LL, 0x400000004LL }); + + out += todo; + inp += todo; + len -= todo; + } +} + +#else /* 64-bit SIMD */ + +/* QUARTERROUND updates a, b, c, d with a ChaCha "quarter" round. */ +#define QUARTERROUND(a, b, c, d) ( \ + x[a] = __builtin_e2k_paddw(x[a], x[b]), tt = __builtin_e2k_pxord(x[d], x[a]), x[d] = __builtin_e2k_pshufb(tt, tt, 0x0504070601000302ull), \ + x[c] = __builtin_e2k_paddw(x[c], x[d]), tt = __builtin_e2k_pxord(x[b], x[c]), x[b] = __builtin_e2k_pord(__builtin_e2k_psllw(tt, 12), __builtin_e2k_psrlw(tt, 32 - 12)), \ + x[a] = __builtin_e2k_paddw(x[a], x[b]), tt = __builtin_e2k_pxord(x[d], x[a]), x[d] = __builtin_e2k_pshufb(tt, tt, 0x0605040702010003ull), \ + x[c] = __builtin_e2k_paddw(x[c], x[d]), tt = __builtin_e2k_pxord(x[b], x[c]), x[b] = __builtin_e2k_pord(__builtin_e2k_psllw(tt, 7), __builtin_e2k_psrlw(tt, 32 - 7))) + +/* chacha_core performs 20 rounds of ChaCha on the input words in *inp + * and writes the 64 output bytes to *out . + */ +void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp, + size_t len, const unsigned int key[8], + const unsigned int counter[4]) +{ + u32 input[16]; + uint64_t input_x2[16]; + uint64_t buf[16]; + size_t todo, i; + + /* sigma constant "expand 32-byte k" in little-endian encoding */ + input[0] = ((u32)('e')) | ((u32)('x') << 8) | ((u32)('p') << 16) | ((u32)('a') << 24); + input[1] = ((u32)('n')) | ((u32)('d') << 8) | ((u32)(' ') << 16) | ((u32)('3') << 24); + input[2] = ((u32)('2')) | ((u32)('-') << 8) | ((u32)('b') << 16) | ((u32)('y') << 24); + input[3] = ((u32)('t')) | ((u32)('e') << 8) | ((u32)(' ') << 16) | ((u32)('k') << 24); + + input[4] = key[0]; + input[5] = key[1]; + input[6] = key[2]; + input[7] = key[3]; + input[8] = key[4]; + input[9] = key[5]; + input[10] = key[6]; + input[11] = key[7]; + + input[12] = counter[0]; + input[13] = counter[1]; + input[14] = counter[2]; + input[15] = counter[3]; + +#pragma unroll(16) + for (i = 0; i < 16; i++) { + input_x2[i] = input[i] * 0x100000001ull; + } + + input_x2[12] = __builtin_e2k_paddw(input_x2[12], 0x100000000ull); + + while (len > 0) { + uint64_t buf_tran[16]; + uint64_t x[16], tt; + uint64_t *__restrict__ outw = (uint64_t *)out; + + for (i = 0; i < 16; ++i) + x[i] = input_x2[i]; + + for (i = 20; i > 0; i -= 2) { + QUARTERROUND(0, 4, 8, 12); + QUARTERROUND(1, 5, 9, 13); + QUARTERROUND(2, 6, 10, 14); + QUARTERROUND(3, 7, 11, 15); + QUARTERROUND(0, 5, 10, 15); + QUARTERROUND(1, 6, 11, 12); + QUARTERROUND(2, 7, 8, 13); + QUARTERROUND(3, 4, 9, 14); + } + + for (i = 0; i < 16; ++i) + buf[i] = __builtin_e2k_paddw(x[i], input_x2[i]); + +#pragma unroll(8) + for (i = 0; i < 16; i += 2) { + const uint64_t fmtl = 0x0b0a090803020100ull; + const uint64_t fmtr = 0x0f0e0d0c07060504ull; + + buf_tran[i / 2 + 0] = __builtin_e2k_pshufb(buf[i + 1], buf[i + 0], fmtl); + buf_tran[i / 2 + 8] = __builtin_e2k_pshufb(buf[i + 1], buf[i + 0], fmtr); + } + + todo = sizeof(buf); + if (__builtin_expect(len < todo, 0)) { + todo = len & ~(size_t)7; + +#pragma loop count(16) + for (i = 0; i < todo; i += 8) { + *(uint64_t *)&out[i] = __builtin_e2k_pxord(*(uint64_t *)&inp[i], buf_tran[i / 8]); + } +#pragma loop count(7) + for (; i < len; i++) { + out[i] = inp[i] ^ ((u8 *)buf_tran)[i]; + } + return; + } + +#pragma unroll(16) + for (i = 0; i < todo; i += 8) { + *outw++ = __builtin_e2k_pxord(*(uint64_t *)&inp[i], buf_tran[i / 8]); + } + + /* + * Advance 32-bit counters. Note that as subroutine is so to + * say nonce-agnostic, this limited counter width doesn't + * prevent caller from implementing wider counter. It would + * simply take two calls split on counter overflow... + */ + input_x2[12] = __builtin_e2k_paddw(input_x2[12], 0x200000002ull); + + out += todo; + inp += todo; + len -= todo; + } +} +#endif diff --git a/crypto/chacha/chacha_enc.c b/crypto/chacha/chacha_enc.c index c7c36b9c5485f..8318f4fdf8350 100644 --- a/crypto/chacha/chacha_enc.c +++ b/crypto/chacha/chacha_enc.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/chacha/chacha_ppc.c b/crypto/chacha/chacha_ppc.c index d2e0a68baa4c0..b2149dab32c68 100644 --- a/crypto/chacha/chacha_ppc.c +++ b/crypto/chacha/chacha_ppc.c @@ -1,5 +1,5 @@ /* - * Copyright 2009-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2009-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/chacha/chacha_riscv.c b/crypto/chacha/chacha_riscv.c index e3e24c99fab71..8c4d34fa65bc1 100644 --- a/crypto/chacha/chacha_riscv.c +++ b/crypto/chacha/chacha_riscv.c @@ -2,7 +2,7 @@ * This file is dual-licensed, meaning that you can use it under your * choice of either of the following two licenses: * - * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/cmp/cmp_client.c b/crypto/cmp/cmp_client.c index 60c769af932ed..ba855858c7638 100644 --- a/crypto/cmp/cmp_client.c +++ b/crypto/cmp/cmp_client.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -9,6 +9,8 @@ * https://www.openssl.org/source/license.html */ +#include + #include "cmp_local.h" #include @@ -231,7 +233,7 @@ static int send_receive_check(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req, != NULL) ERR_add_error_data(1, buf); if (emc->errorCode != NULL - && BIO_snprintf(buf, sizeof(buf), "; errorCode: %08lX", + && snprintf(buf, sizeof(buf), "; errorCode: %08lX", ASN1_INTEGER_get(emc->errorCode)) > 0) ERR_add_error_data(1, buf); @@ -310,7 +312,7 @@ static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid, } if (check_after < 0 || (uint64_t)check_after > (sleep ? ULONG_MAX / 1000 : INT_MAX)) { ERR_raise(ERR_LIB_CMP, CMP_R_CHECKAFTER_OUT_OF_RANGE); - if (BIO_snprintf(str, OSSL_CMP_PKISI_BUFLEN, "value = %" PRId64, + if (snprintf(str, OSSL_CMP_PKISI_BUFLEN, "value = %" PRId64, check_after) >= 0) ERR_add_error_data(1, str); @@ -318,18 +320,21 @@ static int poll_for_response(OSSL_CMP_CTX *ctx, int sleep, int rid, } if (pollRep->reason == NULL - || (len = BIO_snprintf(str, OSSL_CMP_PKISI_BUFLEN, + || (len = snprintf(str, OSSL_CMP_PKISI_BUFLEN, " with reason = '")) - < 0) { + < 0 + || (size_t)len >= OSSL_CMP_PKISI_BUFLEN) { *str = '\0'; } else { char *text = ossl_sk_ASN1_UTF8STRING2text(pollRep->reason, ", ", sizeof(str) - len - 2); + int n; if (text == NULL - || BIO_snprintf(str + len, sizeof(str) - len, - "%s'", text) - < 0) + || (n = snprintf(str + len, sizeof(str) - len, + "%s'", text)) + < 0 + || (size_t)n >= sizeof(str) - len) *str = '\0'; OPENSSL_free(text); } diff --git a/crypto/cmp/cmp_ctx.c b/crypto/cmp/cmp_ctx.c index da8277f5feaa6..7e1c43a89c2b8 100644 --- a/crypto/cmp/cmp_ctx.c +++ b/crypto/cmp/cmp_ctx.c @@ -9,6 +9,8 @@ * https://www.openssl.org/source/license.html */ +#include + #include "cmp_local.h" #include /* for OCSP_REVOKED_STATUS_* */ @@ -377,11 +379,11 @@ int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx, if (OSSL_TRACE_ENABLED(CMP)) { OSSL_TRACE_BEGIN(CMP) { - int printed = BIO_snprintf(hugebuf, sizeof(hugebuf), + int printed = snprintf(hugebuf, sizeof(hugebuf), "%s:%s:%d:" OSSL_CMP_LOG_PREFIX "%s: ", func, file, line, level_str); if (printed > 0 && (size_t)printed < sizeof(hugebuf)) { - if (BIO_vsnprintf(hugebuf + printed, + if (vsnprintf(hugebuf + printed, sizeof(hugebuf) - printed, format, args) > 0) res = BIO_puts(trc_out, hugebuf) > 0; @@ -391,7 +393,7 @@ int ossl_cmp_print_log(OSSL_CMP_severity level, const OSSL_CMP_CTX *ctx, } #else /* compensate for disabled trace API */ { - if (BIO_vsnprintf(hugebuf, sizeof(hugebuf), format, args) > 0) + if (vsnprintf(hugebuf, sizeof(hugebuf), format, args) > 0) res = ctx->log_cb(func, file, line, level, hugebuf); } #endif diff --git a/crypto/cmp/cmp_err.c b/crypto/cmp/cmp_err.c deleted file mode 100644 index fe1d8b3d1d29c..0000000000000 --- a/crypto/cmp/cmp_err.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/cmperr.h" - -#ifndef OPENSSL_NO_CMP - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA CMP_str_reasons[] = { - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ALGORITHM_NOT_SUPPORTED), - "algorithm not supported" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_BAD_CHECKAFTER_IN_POLLREP), - "bad checkafter in pollrep" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_BAD_REQUEST_ID), "bad request id" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTHASH_UNMATCHED), "certhash unmatched" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTID_NOT_FOUND), "certid not found" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTIFICATE_NOT_ACCEPTED), - "certificate not accepted" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTIFICATE_NOT_FOUND), - "certificate not found" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTREQMSG_NOT_FOUND), - "certreqmsg not found" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERTRESPONSE_NOT_FOUND), - "certresponse not found" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CERT_AND_KEY_DO_NOT_MATCH), - "cert and key do not match" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_CHECKAFTER_OUT_OF_RANGE), - "checkafter out of range" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ENCOUNTERED_KEYUPDATEWARNING), - "encountered keyupdatewarning" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ENCOUNTERED_WAITING), - "encountered waiting" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CALCULATING_PROTECTION), - "error calculating protection" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CERTCONF), - "error creating certconf" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CERTREP), - "error creating certrep" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_CERTREQ), - "error creating certreq" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_ERROR), - "error creating error" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_GENM), - "error creating genm" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_GENP), - "error creating genp" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_PKICONF), - "error creating pkiconf" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_POLLREP), - "error creating pollrep" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_POLLREQ), - "error creating pollreq" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_RP), "error creating rp" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_CREATING_RR), "error creating rr" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PARSING_PKISTATUS), - "error parsing pkistatus" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PROCESSING_MESSAGE), - "error processing message" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_PROTECTING_MESSAGE), - "error protecting message" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_SETTING_CERTHASH), - "error setting certhash" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_UNEXPECTED_CERTCONF), - "error unexpected certconf" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_PROTECTION), - "error validating protection" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_ERROR_VALIDATING_SIGNATURE), - "error validating signature" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_EXPECTED_POLLREQ), "expected pollreq" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_BUILDING_OWN_CHAIN), - "failed building own chain" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_CENTRAL_GEN_KEY), - "failed extracting central gen key" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILED_EXTRACTING_PUBKEY), - "failed extracting pubkey" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAILURE_OBTAINING_RANDOM), - "failure obtaining random" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_FAIL_INFO_OUT_OF_RANGE), - "fail info out of range" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GENERATE_CERTREQTEMPLATE), - "generate certreqtemplate" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GENERATE_CRLSTATUS), - "error creating crlstatus" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GETTING_GENP), "getting genp" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_GET_ITAV), "get itav" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ARGS), "invalid args" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_GENP), "invalid genp" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_KEYSPEC), "invalid keyspec" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_OPTION), "invalid option" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_INVALID_ROOTCAKEYUPDATE), - "invalid rootcakeyupdate" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_CENTRAL_GEN_KEY), - "missing central gen key" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_CERTID), "missing certid" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION), - "missing key input for creating protection" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE), - "missing key usage digitalsignature" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_P10CSR), "missing p10csr" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PBM_SECRET), "missing pbm secret" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PRIVATE_KEY), - "missing private key" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PRIVATE_KEY_FOR_POPO), - "missing private key for popo" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PROTECTION), "missing protection" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_PUBLIC_KEY), "missing public key" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_REFERENCE_CERT), - "missing reference cert" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_SECRET), "missing secret" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_SENDER_IDENTIFICATION), - "missing sender identification" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_TRUST_ANCHOR), - "missing trust anchor" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MISSING_TRUST_STORE), - "missing trust store" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED), - "multiple requests not supported" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED), - "multiple responses not supported" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_MULTIPLE_SAN_SOURCES), - "multiple san sources" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NO_STDIO), "no stdio" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NO_SUITABLE_SENDER_CERT), - "no suitable sender cert" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_NULL_ARGUMENT), "null argument" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_PKIBODY_ERROR), "pkibody error" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_PKISTATUSINFO_NOT_FOUND), - "pkistatusinfo not found" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_POLLING_FAILED), "polling failed" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_POTENTIALLY_INVALID_CERTIFICATE), - "potentially invalid certificate" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_RECEIVED_ERROR), "received error" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_RECIPNONCE_UNMATCHED), - "recipnonce unmatched" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_REQUEST_NOT_ACCEPTED), - "request not accepted" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_REQUEST_REJECTED_BY_SERVER), - "request rejected by server" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED), - "sender generalname type not supported" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG), - "srvcert does not validate msg" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TOTAL_TIMEOUT), "total timeout" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSACTIONID_UNMATCHED), - "transactionid unmatched" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_TRANSFER_ERROR), "transfer error" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNCLEAN_CTX), "unclean ctx" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_CENTRAL_GEN_KEY), - "unexpected central gen key" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_CERTPROFILE), - "unexpected certprofile" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_CRLSTATUSLIST), - "unexpected crlstatuslist" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKIBODY), "unexpected pkibody" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PKISTATUS), - "unexpected pkistatus" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_POLLREQ), "unexpected pollreq" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_PVNO), "unexpected pvno" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNEXPECTED_SENDER), "unexpected sender" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_ALGORITHM_ID), - "unknown algorithm id" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_CERT_TYPE), "unknown cert type" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_CRL_ISSUER), "unknown crl issuer" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNKNOWN_PKISTATUS), "unknown pkistatus" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_ALGORITHM), - "unsupported algorithm" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_KEY_TYPE), - "unsupported key type" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_PKIBODY), - "unsupported pkibody" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC), - "unsupported protection alg dhbasedmac" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_VALUE_TOO_LARGE), "value too large" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_VALUE_TOO_SMALL), "value too small" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_ALGORITHM_OID), - "wrong algorithm oid" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_CERTID), "wrong certid" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_CERTID_IN_RP), "wrong certid in rp" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_PBM_VALUE), "wrong pbm value" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_RP_COMPONENT_COUNT), - "wrong rp component count" }, - { ERR_PACK(ERR_LIB_CMP, 0, CMP_R_WRONG_SERIAL_IN_RP), "wrong serial in rp" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_CMP_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(CMP_str_reasons[0].error) == NULL) - ERR_load_strings_const(CMP_str_reasons); -#endif - return 1; -} -#else -NON_EMPTY_TRANSLATION_UNIT -#endif diff --git a/crypto/cmp/cmp_genm.c b/crypto/cmp/cmp_genm.c index 8e974297fde2f..241ea3d5c3db5 100644 --- a/crypto/cmp/cmp_genm.c +++ b/crypto/cmp/cmp_genm.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright Siemens AG 2022 * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/cmp/cmp_http.c b/crypto/cmp/cmp_http.c index 5f42a85623081..cb2d5d8340121 100644 --- a/crypto/cmp/cmp_http.c +++ b/crypto/cmp/cmp_http.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -9,6 +9,8 @@ * https://www.openssl.org/source/license.html */ +#include + #include "cmp_local.h" static int keep_alive(int want_keep_alive, int body_type, BIO **bios) @@ -54,7 +56,7 @@ OSSL_CMP_MSG *OSSL_CMP_MSG_http_perform(OSSL_CMP_CTX *ctx, bios = OSSL_CMP_CTX_get_transfer_cb_arg(ctx); if (ctx->serverPort != 0) - BIO_snprintf(server_port, sizeof(server_port), "%d", ctx->serverPort); + snprintf(server_port, sizeof(server_port), "%d", ctx->serverPort); tls_used = ctx->tls_used >= 0 ? ctx->tls_used != 0 : OSSL_CMP_CTX_get_http_cb_arg(ctx) != NULL; /* backward compat */ if (ctx->http_ctx == NULL) { /* using existing connection or yet not set up own connection */ diff --git a/crypto/cmp/cmp_local.h b/crypto/cmp/cmp_local.h index e664a6ae221be..ac892f62bd783 100644 --- a/crypto/cmp/cmp_local.h +++ b/crypto/cmp/cmp_local.h @@ -819,7 +819,7 @@ int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs, int only_self_issued); STACK_OF(X509) *ossl_cmp_X509_STORE_get1_certs(X509_STORE *store); int ossl_cmp_sk_ASN1_UTF8STRING_push_str(STACK_OF(ASN1_UTF8STRING) *sk, - const char *text, int len); + const char *text, size_t len); int ossl_cmp_asn1_octet_string_set1(ASN1_OCTET_STRING **tgt, const ASN1_OCTET_STRING *src); int ossl_cmp_asn1_octet_string_set1_bytes(ASN1_OCTET_STRING **tgt, diff --git a/crypto/cmp/cmp_msg.c b/crypto/cmp/cmp_msg.c index fec747458dcbb..abea670ce9ce0 100644 --- a/crypto/cmp/cmp_msg.c +++ b/crypto/cmp/cmp_msg.c @@ -824,13 +824,13 @@ OSSL_CMP_MSG *ossl_cmp_error_new(OSSL_CMP_CTX *ctx, const OSSL_CMP_PKISI *si, goto err; msg->body->value.error->errorDetails = ft; if (lib != NULL && *lib != '\0' - && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, lib, -1)) + && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, lib, strlen(lib))) goto err; if (reason != NULL && *reason != '\0' - && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, reason, -1)) + && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, reason, strlen(reason))) goto err; if (details != NULL - && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, details, -1)) + && !ossl_cmp_sk_ASN1_UTF8STRING_push_str(ft, details, strlen(details))) goto err; } diff --git a/crypto/cmp/cmp_protect.c b/crypto/cmp/cmp_protect.c index b0f52e9f360f0..428d163f816f1 100644 --- a/crypto/cmp/cmp_protect.c +++ b/crypto/cmp/cmp_protect.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -59,7 +59,7 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx, ERR_raise(ERR_LIB_CMP, CMP_R_MISSING_PBM_SECRET); return NULL; } - if (ppval == NULL) { + if (pptype != V_ASN1_SEQUENCE || ppval == NULL) { ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_CALCULATING_PROTECTION); return NULL; } @@ -73,7 +73,11 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx, pbm_str = (ASN1_STRING *)ppval; pbm_str_uc = ASN1_STRING_get0_data(pbm_str); - pbm = d2i_OSSL_CRMF_PBMPARAMETER(NULL, &pbm_str_uc, ASN1_STRING_length(pbm_str)); + if (ASN1_STRING_get_length(pbm_str) > INT_MAX) { + ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_ALGORITHM_OID); + goto end; + } + pbm = d2i_OSSL_CRMF_PBMPARAMETER(NULL, &pbm_str_uc, (long)ASN1_STRING_get_length(pbm_str)); if (pbm == NULL) { ERR_raise(ERR_LIB_CMP, CMP_R_WRONG_ALGORITHM_OID); goto end; @@ -81,7 +85,7 @@ ASN1_BIT_STRING *ossl_cmp_calc_protection(const OSSL_CMP_CTX *ctx, if (!OSSL_CRMF_pbm_new(ctx->libctx, ctx->propq, pbm, prot_part_der, prot_part_der_len, - ASN1_STRING_get0_data(ctx->secretValue), ASN1_STRING_length(ctx->secretValue), + ASN1_STRING_get0_data(ctx->secretValue), ASN1_STRING_get_length(ctx->secretValue), &protection, &sig_len)) goto end; @@ -202,7 +206,7 @@ static X509_ALGOR *pbmac_algor(const OSSL_CMP_CTX *ctx) goto err; if ((pbm_der_len = i2d_OSSL_CRMF_PBMPARAMETER(pbm, &pbm_der)) < 0) goto err; - if (!ASN1_STRING_set(pbm_str, pbm_der, pbm_der_len)) + if (!ossl_asn1_string_set1_data(pbm_str, pbm_der, pbm_der_len)) goto err; alg = ossl_X509_ALGOR_from_nid(NID_id_PasswordBasedMAC, V_ASN1_SEQUENCE, pbm_str); diff --git a/crypto/cmp/cmp_server.c b/crypto/cmp/cmp_server.c index 8a321ecbd920e..56ca4d0c873a6 100644 --- a/crypto/cmp/cmp_server.c +++ b/crypto/cmp/cmp_server.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -55,7 +55,6 @@ OSSL_CMP_SRV_CTX *OSSL_CMP_SRV_CTX_new(OSSL_LIB_CTX *libctx, const char *propq) if ((ctx->ctx = OSSL_CMP_CTX_new(libctx, propq)) == NULL) goto err; ctx->certReqId = OSSL_CMP_CERTREQID_INVALID; - ctx->polling = 0; /* all other elements are initialized to 0 or NULL, respectively */ return ctx; @@ -571,6 +570,60 @@ static int unprotected_exception(const OSSL_CMP_CTX *ctx, return 0; } +static int assuming_new_transaction(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *req) +{ + int body_type = OSSL_CMP_MSG_get_bodytype(req); + ASN1_OCTET_STRING *tid; + + if (ctx->transactionID == NULL) /* no currently active transaction */ + return 1; + + tid = OSSL_CMP_HDR_get0_transactionID(OSSL_CMP_MSG_get0_header(req)); + if (tid != NULL && ASN1_OCTET_STRING_cmp(tid, ctx->transactionID) != 0) { + char *ctx_str = i2s_ASN1_OCTET_STRING(NULL, ctx->transactionID); + char *tid_str = i2s_ASN1_OCTET_STRING(NULL, tid); + + ossl_cmp_log2(WARN, ctx, "Assuming that last transaction with ID=%s got aborted, new ID=%s", + ctx_str != NULL ? ctx_str : "(null)", + tid_str != NULL ? tid_str : "(null)"); + OPENSSL_free(tid_str); + OPENSSL_free(ctx_str); + return 1; + } + + switch (body_type) { + case OSSL_CMP_PKIBODY_IR: + case OSSL_CMP_PKIBODY_CR: + case OSSL_CMP_PKIBODY_P10CR: + case OSSL_CMP_PKIBODY_KUR: + case OSSL_CMP_PKIBODY_RR: + case OSSL_CMP_PKIBODY_GENM: + ossl_cmp_log1(WARN, ctx, "Assuming new transaction due to received body type %s", + ossl_cmp_bodytype_to_string(body_type)); + return 1; + default: + return 0; + } +} + +/* Prepare for next transaction */ +static int transaction_reinit(OSSL_CMP_SRV_CTX *srv_ctx) +{ + int ret = 1; + + srv_ctx->ctx->status = OSSL_CMP_PKISTATUS_unspecified; /* transaction closed */ + srv_ctx->certReqId = OSSL_CMP_CERTREQID_INVALID; + srv_ctx->polling = 0; + + if (srv_ctx->clean_transaction != NULL) + ret = srv_ctx->clean_transaction(srv_ctx, srv_ctx->ctx->transactionID); + if (!OSSL_CMP_CTX_set1_transactionID(srv_ctx->ctx, NULL)) + ret = 0; + if (!OSSL_CMP_CTX_set1_senderNonce(srv_ctx->ctx, NULL)) + ret = 0; + return ret; +} + /* * returns created message and NULL on internal error */ @@ -607,42 +660,18 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, if (!OSSL_CMP_CTX_set1_recipient(ctx, hdr->sender->d.directoryName)) goto err; - if (srv_ctx->polling && req_type != OSSL_CMP_PKIBODY_POLLREQ - && req_type != OSSL_CMP_PKIBODY_ERROR) { - ERR_raise(ERR_LIB_CMP, CMP_R_EXPECTED_POLLREQ); - goto err; - } - - switch (req_type) { - case OSSL_CMP_PKIBODY_IR: - case OSSL_CMP_PKIBODY_CR: - case OSSL_CMP_PKIBODY_P10CR: - case OSSL_CMP_PKIBODY_KUR: - case OSSL_CMP_PKIBODY_RR: - case OSSL_CMP_PKIBODY_GENM: - case OSSL_CMP_PKIBODY_ERROR: - if (ctx->transactionID != NULL) { - char *tid = i2s_ASN1_OCTET_STRING(NULL, ctx->transactionID); - - if (tid != NULL) - ossl_cmp_log1(WARN, ctx, - "Assuming that last transaction with ID=%s got aborted", - tid); - OPENSSL_free(tid); - } - /* start of a new transaction, reset transactionID and senderNonce */ - if (!OSSL_CMP_CTX_set1_transactionID(ctx, NULL) - || !OSSL_CMP_CTX_set1_senderNonce(ctx, NULL)) - goto err; - - if (srv_ctx->clean_transaction != NULL - && !srv_ctx->clean_transaction(srv_ctx, NULL)) { + if (assuming_new_transaction(ctx, req)) { + /* + * Start of a new transaction, resetting transactionID and senderNonce. + * Must in this case reset transactionID beforehand such that the clean() + * callback function gets a NULL transactionID argument, as documented. + */ + (void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL); + if (!transaction_reinit(srv_ctx)) { ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_PROCESSING_MESSAGE); goto err; } - - break; - default: + } else { /* transactionID should be already initialized */ if (ctx->transactionID == NULL) { #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION @@ -650,6 +679,11 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, goto err; #endif } + if (srv_ctx->polling && req_type != OSSL_CMP_PKIBODY_POLLREQ + && req_type != OSSL_CMP_PKIBODY_ERROR) { + ERR_raise(ERR_LIB_CMP, CMP_R_EXPECTED_POLLREQ); + goto err; + } } req_verified = ossl_cmp_msg_check_update(ctx, req, unprotected_exception, @@ -735,13 +769,9 @@ OSSL_CMP_MSG *OSSL_CMP_SRV_process_request(OSSL_CMP_SRV_CTX *srv_ctx, case OSSL_CMP_PKIBODY_PKICONF: case OSSL_CMP_PKIBODY_GENP: /* Other terminating response message types are not supported */ - srv_ctx->certReqId = OSSL_CMP_CERTREQID_INVALID; - /* Prepare for next transaction, ignoring any errors here: */ - if (srv_ctx->clean_transaction != NULL) - (void)srv_ctx->clean_transaction(srv_ctx, ctx->transactionID); - (void)OSSL_CMP_CTX_set1_transactionID(ctx, NULL); - (void)OSSL_CMP_CTX_set1_senderNonce(ctx, NULL); - ctx->status = OSSL_CMP_PKISTATUS_unspecified; /* transaction closed */ + + /* Prepare for next transaction, ignoring any errors here */ + (void)transaction_reinit(srv_ctx); default: /* not closing transaction in other cases */ break; diff --git a/crypto/cmp/cmp_status.c b/crypto/cmp/cmp_status.c index 40e1ee671e077..b052c91246854 100644 --- a/crypto/cmp/cmp_status.c +++ b/crypto/cmp/cmp_status.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -11,6 +11,8 @@ /* CMP functions for PKIStatusInfo handling and PKIMessage decomposition */ +#include + #include "cmp_local.h" /* CMP functions related to PKIStatus */ @@ -176,7 +178,7 @@ static char *snprint_PKIStatusInfo_parts(int status, int fail_info, write_ptr += printed_chars; \ bufsize -= printed_chars; - printed_chars = BIO_snprintf(write_ptr, bufsize, "%s", status_string); + printed_chars = snprintf(write_ptr, bufsize, "%s", status_string); ADVANCE_BUFFER; /* @@ -184,13 +186,13 @@ static char *snprint_PKIStatusInfo_parts(int status, int fail_info, * if present, print failInfo before statusString because it is more concise */ if (fail_info != -1 && fail_info != 0) { - printed_chars = BIO_snprintf(write_ptr, bufsize, "; PKIFailureInfo: "); + printed_chars = snprintf(write_ptr, bufsize, "; PKIFailureInfo: "); ADVANCE_BUFFER; for (failure = 0; failure <= OSSL_CMP_PKIFAILUREINFO_MAX; failure++) { if ((fail_info & (1 << failure)) != 0) { failure_string = CMP_PKIFAILUREINFO_to_string(failure); if (failure_string != NULL) { - printed_chars = BIO_snprintf(write_ptr, bufsize, "%s%s", + printed_chars = snprintf(write_ptr, bufsize, "%s%s", failinfo_found ? ", " : "", failure_string); ADVANCE_BUFFER; @@ -201,21 +203,22 @@ static char *snprint_PKIStatusInfo_parts(int status, int fail_info, } if (!failinfo_found && status != OSSL_CMP_PKISTATUS_accepted && status != OSSL_CMP_PKISTATUS_grantedWithMods) { - printed_chars = BIO_snprintf(write_ptr, bufsize, "; "); + printed_chars = snprintf(write_ptr, bufsize, "; "); ADVANCE_BUFFER; } /* statusString sequence is optional and may be empty */ n_status_strings = sk_ASN1_UTF8STRING_num(status_strings); if (n_status_strings > 0) { - printed_chars = BIO_snprintf(write_ptr, bufsize, "; StatusString%s: ", + printed_chars = snprintf(write_ptr, bufsize, "; StatusString%s: ", n_status_strings > 1 ? "s" : ""); ADVANCE_BUFFER; for (i = 0; i < n_status_strings; i++) { text = sk_ASN1_UTF8STRING_value(status_strings, i); - printed_chars = BIO_snprintf(write_ptr, bufsize, "\"%.*s\"%s", - ASN1_STRING_length(text), - ASN1_STRING_get0_data(text), + printed_chars = snprintf(write_ptr, bufsize, "\"%.*s\"%s", + (int)ASN1_STRING_get_length(text), + ASN1_STRING_get_length(text) ? ASN1_STRING_get0_data(text) + : (const unsigned char *)"", i < n_status_strings - 1 ? ", " : ""); ADVANCE_BUFFER; } @@ -275,7 +278,7 @@ OSSL_CMP_PKISI *OSSL_CMP_STATUSINFO_new(int status, int fail_info, if (text != NULL) { if ((utf8_text = ASN1_UTF8STRING_new()) == NULL - || !ASN1_STRING_set(utf8_text, text, -1)) + || !ossl_asn1_string_set1_string(utf8_text, text)) goto err; if ((si->statusString = sk_ASN1_UTF8STRING_new_null()) == NULL) goto err; diff --git a/crypto/cmp/cmp_util.c b/crypto/cmp/cmp_util.c index 5c710addf2031..d32106266e584 100644 --- a/crypto/cmp/cmp_util.c +++ b/crypto/cmp/cmp_util.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -9,6 +9,7 @@ * https://www.openssl.org/source/license.html */ +#include #include #include #include "cmp_local.h" /* just for decls of internal functions defined here */ @@ -170,13 +171,13 @@ void OSSL_CMP_print_errors_cb(OSSL_CMP_log_cb_t log_fn) } #endif if (rs == NULL) { - BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", reason); + snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", reason); rs = rsbuf; } if (data != NULL && (flags & ERR_TXT_STRING) != 0) - BIO_snprintf(msg, sizeof(msg), "%s:%s", rs, data); + snprintf(msg, sizeof(msg), "%s:%s", rs, data); else - BIO_snprintf(msg, sizeof(msg), "%s", rs); + snprintf(msg, sizeof(msg), "%s", rs); if (log_fn == NULL) { #ifndef OPENSSL_NO_STDIO @@ -219,15 +220,16 @@ int ossl_cmp_X509_STORE_add1_certs(X509_STORE *store, STACK_OF(X509) *certs, } int ossl_cmp_sk_ASN1_UTF8STRING_push_str(STACK_OF(ASN1_UTF8STRING) *sk, - const char *text, int len) + const char *text, size_t len) { ASN1_UTF8STRING *utf8string; - if (!ossl_assert(sk != NULL && text != NULL)) + /* text == NULL with len == 0 is the canonical empty string and is valid */ + if (!ossl_assert(sk != NULL && (text != NULL || len == 0))) return 0; if ((utf8string = ASN1_UTF8STRING_new()) == NULL) return 0; - if (!ASN1_STRING_set(utf8string, text, len)) + if (!ossl_asn1_string_set1_data(utf8string, (const uint8_t *)text, len)) goto err; if (!sk_ASN1_UTF8STRING_push(sk, utf8string)) goto err; diff --git a/crypto/cmp/cmp_vfy.c b/crypto/cmp/cmp_vfy.c index 48014295e33c6..647dd044f21aa 100644 --- a/crypto/cmp/cmp_vfy.c +++ b/crypto/cmp/cmp_vfy.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2020 * Copyright Siemens AG 2015-2020 * @@ -770,7 +770,7 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, "expected sender", expected_sender)) { str = X509_NAME_oneline(actual_sender, NULL, 0); ERR_raise_data(ERR_LIB_CMP, CMP_R_UNEXPECTED_SENDER, - str != NULL ? str : ""); + "%s", str != NULL ? str : ""); OPENSSL_free(str); return 0; } @@ -816,8 +816,13 @@ int ossl_cmp_msg_check_update(OSSL_CMP_CTX *ctx, const OSSL_CMP_MSG *msg, res = 1; /* support more aggressive fuzzing by letting invalid msg pass */ #endif - /* remove extraCerts again if not caching */ - if (ctx->noCacheExtraCerts) + /* + * remove extraCerts again if not caching + * or if we failed validation above, lest a remote user + * starts sending us lots of certificates in invalid messages + * leading to a DOS from unbounded certificate stack growth + */ + if (ctx->noCacheExtraCerts || res != 1) while (num_added-- > 0) X509_free(sk_X509_shift(ctx->untrusted)); diff --git a/crypto/cms/cms_asn1.c b/crypto/cms/cms_asn1.c index 96b125e930309..4381651897fc1 100644 --- a/crypto/cms/cms_asn1.c +++ b/crypto/cms/cms_asn1.c @@ -318,9 +318,9 @@ ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = { ASN1_SIMPLE(CMS_AuthenticatedData, macAlgorithm, X509_ALGOR), ASN1_IMP(CMS_AuthenticatedData, digestAlgorithm, X509_ALGOR, 1), ASN1_SIMPLE(CMS_AuthenticatedData, encapContentInfo, CMS_EncapsulatedContentInfo), - ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ALGOR, 2), + ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ATTRIBUTE, 2), ASN1_SIMPLE(CMS_AuthenticatedData, mac, ASN1_OCTET_STRING), - ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ALGOR, 3) + ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ATTRIBUTE, 3) } static_ASN1_NDEF_SEQUENCE_END(CMS_AuthenticatedData) ASN1_NDEF_SEQUENCE(CMS_CompressedData) @@ -358,7 +358,7 @@ static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, switch (operation) { case ASN1_OP_STREAM_PRE: - if (CMS_stream(&sarg->boundary, cms) <= 0) + if (ossl_cms_stream(cms) <= 0) return 0; /* fall through */ case ASN1_OP_DETACHED_PRE: @@ -373,6 +373,13 @@ static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, return 0; break; + case ASN1_OP_GET0_STREAM_CONTENT: { + ASN1_STRING **content = exarg; + ASN1_OCTET_STRING **pos = CMS_get0_content(cms); + + *content = pos == NULL ? NULL : *pos; + } break; + case ASN1_OP_FREE_POST: OPENSSL_free(cms->ctx.propq); break; diff --git a/crypto/cms/cms_dd.c b/crypto/cms/cms_dd.c index 2e1dd78f5e4d2..6449bf83ea1d6 100644 --- a/crypto/cms/cms_dd.c +++ b/crypto/cms/cms_dd.c @@ -92,7 +92,7 @@ int ossl_cms_DigestedData_do_final(const CMS_ContentInfo *cms, BIO *chain, else r = 1; } else { - if (!ASN1_STRING_set(dd->digest, md, mdlen)) + if (!ossl_asn1_string_set1_data(dd->digest, md, mdlen)) goto err; r = 1; } diff --git a/crypto/cms/cms_dh.c b/crypto/cms/cms_dh.c index a3ae620deab1a..0548666524c99 100644 --- a/crypto/cms/cms_dh.c +++ b/crypto/cms/cms_dh.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -29,7 +29,7 @@ static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx, BIGNUM *bnpub = NULL; const unsigned char *p; unsigned char *buf = NULL; - int plen; + size_t plen; X509_ALGOR_get0(&aoid, &atype, &aval, alg); if (OBJ_obj2nid(aoid) != NID_dhpublicnumber) @@ -43,29 +43,33 @@ static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx, goto err; /* Get public key */ - plen = ASN1_STRING_length(pubkey); + plen = ASN1_STRING_get_length(pubkey); + if (plen > INT_MAX) + goto err; p = ASN1_STRING_get0_data(pubkey); if (p == NULL || plen == 0) goto err; - if ((public_key = d2i_ASN1_INTEGER(NULL, &p, plen)) == NULL) + if ((public_key = d2i_ASN1_INTEGER(NULL, &p, (int)plen)) == NULL) goto err; /* * Pad to full p parameter size as that is checked by * EVP_PKEY_set1_encoded_public_key() */ plen = EVP_PKEY_get_size(pk); + if (plen > INT_MAX) + goto err; if ((bnpub = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) goto err; if ((buf = OPENSSL_malloc(plen)) == NULL) goto err; - if (BN_bn2binpad(bnpub, buf, plen) < 0) + if (BN_bn2binpad(bnpub, buf, (int)plen) < 0) goto err; pkpeer = EVP_PKEY_new(); if (pkpeer == NULL || !EVP_PKEY_copy_parameters(pkpeer, pk) - || EVP_PKEY_set1_encoded_public_key(pkpeer, buf, plen) <= 0) + || EVP_PKEY_set1_encoded_public_key(pkpeer, buf, (int)plen) <= 0) goto err; if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) @@ -85,8 +89,9 @@ static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) ASN1_OCTET_STRING *ukm; const unsigned char *p; unsigned char *dukm = NULL; - int dukmlen = 0; - int keylen, plen; + size_t dukmlen = 0; + int keylen; + size_t plen; EVP_CIPHER *kekcipher = NULL; EVP_CIPHER_CTX *kekctx; const ASN1_OBJECT *aoid; @@ -116,8 +121,10 @@ static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) goto err; p = ASN1_STRING_get0_data(parameter); - plen = ASN1_STRING_length(parameter); - kekalg = d2i_X509_ALGOR(NULL, &p, plen); + plen = ASN1_STRING_get_length(parameter); + if (plen > INT_MAX) + goto err; + kekalg = d2i_X509_ALGOR(NULL, &p, (int)plen); if (kekalg == NULL) goto err; kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); @@ -146,13 +153,15 @@ static int dh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) goto err; if (ukm != NULL) { - dukmlen = ASN1_STRING_length(ukm); - dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen); + dukmlen = ASN1_STRING_get_length(ukm); + if (dukmlen > INT_MAX) + goto err; + dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), (int)dukmlen); if (dukm == NULL) goto err; } - if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) + if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, (int)dukmlen) <= 0) goto err; dukm = NULL; @@ -206,7 +215,7 @@ static int dh_cms_encrypt(CMS_RecipientInfo *ri) ASN1_OCTET_STRING *ukm; unsigned char *penc = NULL, *dukm = NULL; int penclen; - int dukmlen = 0; + size_t dukmlen = 0; int rv = 0; int kdf_type, wrap_nid; const EVP_MD *kdf_md; @@ -298,13 +307,15 @@ static int dh_cms_encrypt(CMS_RecipientInfo *ri) goto err; if (ukm != NULL) { - dukmlen = ASN1_STRING_length(ukm); + dukmlen = ASN1_STRING_get_length(ukm); + if (dukmlen > INT_MAX) + goto err; dukm = OPENSSL_memdup(ASN1_STRING_get0_data(ukm), dukmlen); if (dukm == NULL) goto err; } - if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, dukmlen) <= 0) + if (EVP_PKEY_CTX_set0_dh_kdf_ukm(pctx, dukm, (int)dukmlen) <= 0) goto err; dukm = NULL; diff --git a/crypto/cms/cms_ec.c b/crypto/cms/cms_ec.c index 8a8fe3f912cf8..2976022906830 100644 --- a/crypto/cms/cms_ec.c +++ b/crypto/cms/cms_ec.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -79,7 +79,7 @@ static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, int rv = 0; EVP_PKEY *pkpeer = NULL; const unsigned char *p; - int plen; + size_t plen; X509_ALGOR_get0(&aoid, &atype, &aval, alg); if (OBJ_obj2nid(aoid) != NID_X9_62_id_ecPublicKey) @@ -106,12 +106,14 @@ static int ecdh_cms_set_peerkey(EVP_PKEY_CTX *pctx, goto err; } /* We have parameters now set public key */ - plen = ASN1_STRING_length(pubkey); + plen = ASN1_STRING_get_length(pubkey); + if (plen > INT_MAX) + goto err; p = ASN1_STRING_get0_data(pubkey); if (p == NULL || plen == 0) goto err; - if (EVP_PKEY_set1_encoded_public_key(pkpeer, p, plen) <= 0) + if (EVP_PKEY_set1_encoded_public_key(pkpeer, p, (int)plen) <= 0) goto err; if (EVP_PKEY_derive_set_peer(pctx, pkpeer) > 0) @@ -163,7 +165,8 @@ static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) ASN1_OCTET_STRING *ukm; const unsigned char *p; unsigned char *der = NULL; - int plen, keylen; + int keylen, plen_i; + size_t plen; EVP_CIPHER *kekcipher = NULL; EVP_CIPHER_CTX *kekctx; const ASN1_OBJECT *aoid = NULL; @@ -186,8 +189,10 @@ static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) return 0; p = ASN1_STRING_get0_data(parameter); - plen = ASN1_STRING_length(parameter); - kekalg = d2i_X509_ALGOR(NULL, &p, plen); + plen = ASN1_STRING_get_length(parameter); + if (plen > INT_MAX) + goto err; + kekalg = d2i_X509_ALGOR(NULL, &p, (int)plen); if (kekalg == NULL) goto err; kekctx = CMS_RecipientInfo_kari_get0_ctx(ri); @@ -206,12 +211,12 @@ static int ecdh_cms_set_shared_info(EVP_PKEY_CTX *pctx, CMS_RecipientInfo *ri) if (EVP_PKEY_CTX_set_ecdh_kdf_outlen(pctx, keylen) <= 0) goto err; - plen = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen); + plen_i = CMS_SharedInfo_encode(&der, kekalg, ukm, keylen); - if (plen <= 0) + if (plen_i <= 0) goto err; - if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen) <= 0) + if (EVP_PKEY_CTX_set0_ecdh_kdf_ukm(pctx, der, plen_i) <= 0) goto err; der = NULL; diff --git a/crypto/cms/cms_enc.c b/crypto/cms/cms_enc.c index 32133c6847db4..1dfb19c3ebe25 100644 --- a/crypto/cms/cms_enc.c +++ b/crypto/cms/cms_enc.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,6 +17,7 @@ #include "crypto/evp.h" #include "crypto/asn1.h" #include "cms_local.h" +#include "internal/sizes.h" /* CMS EncryptedData Utilities */ @@ -65,9 +66,13 @@ BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec, if (cipher != NULL) { fetched_ciph = EVP_CIPHER_fetch(libctx, EVP_CIPHER_get0_name(cipher), propq); - if (fetched_ciph != NULL) - cipher = fetched_ciph; + } else { + char txtoid[OSSL_MAX_NAME_SIZE]; + if (OBJ_obj2txt(txtoid, sizeof(txtoid), calg->algorithm, 1) > 0) + fetched_ciph = EVP_CIPHER_fetch(libctx, txtoid, propq); } + if (fetched_ciph != NULL) + cipher = fetched_ciph; if (cipher == NULL) { (void)ERR_clear_last_mark(); ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_CIPHER); @@ -81,8 +86,14 @@ BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec, } if (enc) { + (void)ERR_set_mark(); calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_get_type(ctx)); - if (calg->algorithm == NULL || calg->algorithm->nid == NID_undef) { + (void)ERR_pop_to_mark(); + + if (calg->algorithm == NULL || calg->algorithm->nid == NID_undef) + calg->algorithm = OBJ_txt2obj(EVP_CIPHER_get0_name(cipher), 0); + + if (calg->algorithm == NULL || OBJ_length(calg->algorithm) == 0) { ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM); goto err; } @@ -140,25 +151,19 @@ BIO *ossl_cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec, ERR_clear_error(); } - if (ec->keylen != tkeylen) { - /* If necessary set key length */ - if (EVP_CIPHER_CTX_set_key_length(ctx, (int)ec->keylen) <= 0) { - /* - * Only reveal failure if debugging so we don't leak information - * which may be useful in MMA. - */ - if (enc || ec->debug) { - ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); - goto err; - } else { - /* Use random key */ - OPENSSL_clear_free(ec->key, ec->keylen); - ec->key = tkey; - ec->keylen = tkeylen; - tkey = NULL; - ERR_clear_error(); - } + if (ec->keylen != tkeylen + && EVP_CIPHER_CTX_set_key_length(ctx, (int)ec->keylen) <= 0) { + /* Fail only when this cannot act as an MMA oracle or debug enabled */ + if (enc || ec->debug || ec->harderr) { + ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); + goto err; } + /* Use random key */ + OPENSSL_clear_free(ec->key, ec->keylen); + ec->key = tkey; + ec->keylen = tkeylen; + tkey = NULL; + ERR_clear_error(); } if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) { diff --git a/crypto/cms/cms_env.c b/crypto/cms/cms_env.c index 8413f497db06c..bd66900861ab3 100644 --- a/crypto/cms/cms_env.c +++ b/crypto/cms/cms_env.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include "internal/sizes.h" #include "crypto/asn1.h" @@ -278,12 +280,17 @@ BIO *CMS_EnvelopedData_decrypt(CMS_EnvelopedData *env, BIO *detached_data, CMS_ContentInfo *ci; BIO *bio = NULL; int res = 0; + size_t secret_len = 0; if (env == NULL) { ERR_raise(ERR_LIB_CMS, ERR_R_PASSED_NULL_PARAMETER); return NULL; } + if (secret != NULL + && (secret_len = ASN1_STRING_get_length(secret)) > INT_MAX) + return NULL; + if ((ci = CMS_ContentInfo_new_ex(libctx, propq)) == NULL || (bio = BIO_new(BIO_s_mem())) == NULL) goto end; @@ -291,7 +298,7 @@ BIO *CMS_EnvelopedData_decrypt(CMS_EnvelopedData *env, BIO *detached_data, ci->d.envelopedData = env; if (secret != NULL && CMS_decrypt_set1_password(ci, (unsigned char *)ASN1_STRING_get0_data(secret), - ASN1_STRING_length(secret)) + (int)secret_len) != 1) goto end; res = CMS_decrypt(ci, secret == NULL ? pkey : NULL, @@ -586,6 +593,35 @@ static int cms_RecipientInfo_ktri_encrypt(const CMS_ContentInfo *cms, /* Decrypt content key from KTRI */ +/* Check whether reporting a key length mismatch cannot act as an MMA oracle */ +static int cms_ktri_harderr_ok(EVP_PKEY_CTX *pctx, EVP_PKEY *pkey) +{ + int pad_mode; + unsigned int implicit_rejection = 0; + OSSL_PARAM params[2]; + + if (!EVP_PKEY_is_a(pkey, "RSA") + || EVP_PKEY_CTX_get_rsa_padding(pctx, &pad_mode) <= 0) + return 0; + + /* An RSA-OAEP decryption failure is safe to reveal */ + if (pad_mode == RSA_PKCS1_OAEP_PADDING) + return 1; + if (pad_mode != RSA_PKCS1_PADDING) + return 0; + + /* For PKCS#1 v1.5 it is only safe with implicit rejection in effect */ + params[0] = OSSL_PARAM_construct_uint( + OSSL_ASYM_CIPHER_PARAM_IMPLICIT_REJECTION, + &implicit_rejection); + params[1] = OSSL_PARAM_construct_end(); + if (EVP_PKEY_CTX_get_params(pctx, params) <= 0 + || !OSSL_PARAM_modified(¶ms[0])) + return 0; + + return implicit_rejection != 0; +} + static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) { @@ -644,6 +680,17 @@ static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, if (!ossl_cms_env_asn1_ctrl(ri, 1)) goto err; + /* + * Check whether a decryption failure or a key length mismatch can be + * reported without MMA risk. This must be determined before the + * decryption is attempted so a failure of the decryption itself (only + * possible for a publicly invalid ciphertext when implicit rejection + * is in effect, or a padding check failure with RSA-OAEP) is reported + * as well. + */ + if (!ec->havenocert && !ec->debug) + ec->harderr = cms_ktri_harderr_ok(ktri->pctx, pkey); + if (evp_pkey_decrypt_alloc(ktri->pctx, &ek, &eklen, fixlen, ktri->encryptedKey->data, ktri->encryptedKey->length) @@ -953,6 +1000,7 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, CMS_EncryptedContentInfo *ec; CMS_KEKRecipientInfo *kekri; unsigned char *ukey = NULL; + size_t ukey_alloc_len = 0; int ukeylen; int r = 0, wrap_nid; EVP_CIPHER *cipher = NULL; @@ -990,7 +1038,8 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, goto err; } - ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8); + ukey_alloc_len = (size_t)kekri->encryptedKey->length - 8; + ukey = OPENSSL_malloc(ukey_alloc_len); if (ukey == NULL) goto err; @@ -1019,7 +1068,7 @@ static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, err: EVP_CIPHER_free(cipher); if (!r) - OPENSSL_free(ukey); + OPENSSL_clear_free(ukey, ukey_alloc_len); EVP_CIPHER_CTX_free(ctx); return r; diff --git a/crypto/cms/cms_err.c b/crypto/cms/cms_err.c deleted file mode 100644 index 14ef7f11908fd..0000000000000 --- a/crypto/cms/cms_err.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/cmserr.h" - -#ifndef OPENSSL_NO_CMS - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA CMS_str_reasons[] = { - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ADD_SIGNER_ERROR), "add signer error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ATTRIBUTE_ERROR), "attribute error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_ALREADY_PRESENT), - "certificate already present" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_HAS_NO_KEYID), - "certificate has no keyid" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CERTIFICATE_VERIFY_ERROR), - "certificate verify error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_AEAD_IN_ENVELOPED_DATA), - "cipher aead in enveloped data" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_AEAD_SET_TAG_ERROR), - "cipher aead set tag error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_GET_TAG), "cipher get tag" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_INITIALISATION_ERROR), - "cipher initialisation error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR), - "cipher parameter initialisation error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CMS_DATAFINAL_ERROR), - "cms datafinal error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CMS_LIB), "cms lib" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENTIDENTIFIER_MISMATCH), - "contentidentifier mismatch" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_NOT_FOUND), "content not found" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_MISMATCH), - "content type mismatch" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA), - "content type not compressed data" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA), - "content type not enveloped data" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA), - "content type not signed data" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CONTENT_VERIFY_ERROR), - "content verify error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CTRL_ERROR), "ctrl error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_CTRL_FAILURE), "ctrl failure" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_DECODE_ERROR), "decode error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_DECRYPT_ERROR), "decrypt error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_GETTING_PUBLIC_KEY), - "error getting public key" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE), - "error reading messagedigest attribute" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_KEY), "error setting key" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_SETTING_RECIPIENTINFO), - "error setting recipientinfo" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ERROR_UNSUPPORTED_STATIC_KEY_AGREEMENT), - "error unsupported static key agreement" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR), - "ess signing certid mismatch error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_ENCRYPTED_KEY_LENGTH), - "invalid encrypted key length" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER), - "invalid key encryption parameter" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_KEY_LENGTH), "invalid key length" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_LABEL), "invalid label" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_INVALID_OAEP_PARAMETERS), - "invalid oaep parameters" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_KDF_PARAMETER_ERROR), - "kdf parameter error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MD_BIO_INIT_ERROR), "md bio init error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH), - "messagedigest attribute wrong length" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MESSAGEDIGEST_WRONG_LENGTH), - "messagedigest wrong length" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MSGSIGDIGEST_ERROR), "msgsigdigest error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE), - "msgsigdigest verification failure" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_MSGSIGDIGEST_WRONG_LENGTH), - "msgsigdigest wrong length" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NEED_ONE_SIGNER), "need one signer" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_A_SIGNED_RECEIPT), - "not a signed receipt" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_ENCRYPTED_DATA), "not encrypted data" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_KEK), "not kek" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_KEM), "not kem" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_KEY_AGREEMENT), "not key agreement" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_KEY_TRANSPORT), "not key transport" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_PWRI), "not pwri" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), - "not supported for this key type" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_CIPHER), "no cipher" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_CONTENT), "no content" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_CONTENT_TYPE), "no content type" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_DEFAULT_DIGEST), "no default digest" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_DIGEST_SET), "no digest set" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_KEY), "no key" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_KEY_OR_CERT), "no key or cert" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MATCHING_DIGEST), "no matching digest" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MATCHING_RECIPIENT), - "no matching recipient" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MATCHING_SIGNATURE), - "no matching signature" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_MSGSIGDIGEST), "no msgsigdigest" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PASSWORD), "no password" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PRIVATE_KEY), "no private key" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_PUBLIC_KEY), "no public key" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_RECEIPT_REQUEST), "no receipt request" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_NO_SIGNERS), "no signers" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_OPERATION_UNSUPPORTED), - "operation unsupported" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PEER_KEY_ERROR), "peer key error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), - "private key does not match certificate" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_RECEIPT_DECODE_ERROR), - "receipt decode error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_RECIPIENT_ERROR), "recipient error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SHARED_INFO_ERROR), "shared info error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND), - "signer certificate not found" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SIGNFINAL_ERROR), "signfinal error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_SMIME_TEXT_ERROR), "smime text error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_STORE_INIT_ERROR), "store init error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_COMPRESSED_DATA), - "type not compressed data" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_DATA), "type not data" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_DIGESTED_DATA), - "type not digested data" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_ENCRYPTED_DATA), - "type not encrypted data" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_TYPE_NOT_ENVELOPED_DATA), - "type not enveloped data" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNABLE_TO_FINALIZE_CONTEXT), - "unable to finalize context" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNKNOWN_CIPHER), "unknown cipher" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNKNOWN_DIGEST_ALGORITHM), - "unknown digest algorithm" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNKNOWN_ID), "unknown id" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNKNOWN_KDF_ALGORITHM), - "unknown kdf algorithm" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM), - "unsupported compression algorithm" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM), - "unsupported content encryption algorithm" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_CONTENT_TYPE), - "unsupported content type" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_ENCRYPTION_TYPE), - "unsupported encryption type" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KDF_ALGORITHM), - "unsupported kdf algorithm" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KEK_ALGORITHM), - "unsupported kek algorithm" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM), - "unsupported key encryption algorithm" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_LABEL_SOURCE), - "unsupported label source" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE), - "unsupported recipientinfo type" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_RECIPIENT_TYPE), - "unsupported recipient type" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_SIGNATURE_ALGORITHM), - "unsupported signature algorithm" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNSUPPORTED_TYPE), "unsupported type" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNWRAP_ERROR), "unwrap error" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_UNWRAP_FAILURE), "unwrap failure" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_VERIFICATION_FAILURE), - "verification failure" }, - { ERR_PACK(ERR_LIB_CMS, 0, CMS_R_WRAP_ERROR), "wrap error" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_CMS_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(CMS_str_reasons[0].error) == NULL) - ERR_load_strings_const(CMS_str_reasons); -#endif - return 1; -} -#else -NON_EMPTY_TRANSLATION_UNIT -#endif diff --git a/crypto/cms/cms_ess.c b/crypto/cms/cms_ess.c index cafb8273944cc..cd4ab27eaad17 100644 --- a/crypto/cms/cms_ess.c +++ b/crypto/cms/cms_ess.c @@ -131,7 +131,7 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0_ex( if (id) ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen); else { - if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32)) { + if (!ossl_asn1_string_set1_data(rr->signedContentIdentifier, NULL, 32)) { ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); goto err; } diff --git a/crypto/cms/cms_io.c b/crypto/cms/cms_io.c index 9d2345d0db398..fb948093cbb25 100644 --- a/crypto/cms/cms_io.c +++ b/crypto/cms/cms_io.c @@ -14,10 +14,7 @@ #include #include "cms_local.h" -#include - -/* unfortunately cannot constify BIO_new_NDEF() due to this and PKCS7_stream() */ -int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms) +int ossl_cms_stream(CMS_ContentInfo *cms) { ASN1_OCTET_STRING **pos; @@ -27,15 +24,22 @@ int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms) if (*pos == NULL) *pos = ASN1_OCTET_STRING_new(); if (*pos != NULL) { - (*pos)->flags |= ASN1_STRING_FLAG_NDEF; - (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; - *boundary = &(*pos)->data; + cms->contentIncomplete = 0; return 1; } ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); return 0; } +#if !defined(OPENSSL_NO_DEPRECATED_4_1) +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms) +{ + if (boundary != NULL) + *boundary = NULL; + return ossl_cms_stream(cms); +} +#endif /* !defined(OPENSSL_NO_DEPRECATED_4_1) */ + CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms) { CMS_ContentInfo *ci; diff --git a/crypto/cms/cms_kari.c b/crypto/cms/cms_kari.c index e6f6e1679085d..3e40691e10007 100644 --- a/crypto/cms/cms_kari.c +++ b/crypto/cms/cms_kari.c @@ -1,5 +1,5 @@ /* - * Copyright 2013-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2013-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -210,7 +210,9 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen, size_t keklen; int rv = 0; unsigned char *out = NULL; + size_t out_alloc_len = 0; int outlen; + size_t outsize; keklen = EVP_CIPHER_CTX_get_key_length(kari->ctx); if (keklen > EVP_MAX_KEY_LENGTH || inlen > INT_MAX) @@ -224,9 +226,16 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen, /* obtain output length of ciphered key */ if (!EVP_CipherUpdate(kari->ctx, NULL, &outlen, in, (int)inlen)) goto err; - out = OPENSSL_malloc(outlen); + /* + * On its integrity-failure paths that primitive writes and cleanses up to + * inlen bytes of the output buffer. Size the buffer for that worst case so + * a failed unwrap cannot write past the allocation. + */ + outsize = (size_t)outlen < inlen ? inlen : (size_t)outlen; + out = OPENSSL_malloc(outsize); if (out == NULL) goto err; + out_alloc_len = (size_t)outlen; if (!EVP_CipherUpdate(kari->ctx, out, &outlen, in, (int)inlen)) goto err; *pout = out; @@ -236,7 +245,7 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen, err: OPENSSL_cleanse(kek, keklen); if (!rv) - OPENSSL_free(out); + OPENSSL_clear_free(out, out_alloc_len); EVP_CIPHER_CTX_reset(kari->ctx); /* FIXME: WHY IS kari->pctx freed here? /RL */ EVP_PKEY_CTX_free(kari->pctx); diff --git a/crypto/cms/cms_kemri.c b/crypto/cms/cms_kemri.c index 1d867c0db16be..1a3ec8ddf46dc 100644 --- a/crypto/cms/cms_kemri.c +++ b/crypto/cms/cms_kemri.c @@ -264,12 +264,16 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen, unsigned char *out = NULL; int outlen = 0; int rv = 0; + size_t outsize; if (keklen > sizeof(kek)) { ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH); return 0; } + if (inlen > INT_MAX) + return 0; + if (!kdf_derive(kek, keklen, ss, sslen, kemri)) goto err; @@ -279,7 +283,13 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen, /* obtain output length of ciphered key */ if (!EVP_CipherUpdate(kemri->ctx, NULL, &outlen, in, (int)inlen)) goto err; - out = OPENSSL_malloc(outlen); + /* + * On its integrity-failure paths that primitive writes and cleanses up to + * inlen bytes of the output buffer. Size the buffer for that worst case so + * a failed unwrap cannot write past the allocation. + */ + outsize = (size_t)outlen < inlen ? inlen : (size_t)outlen; + out = OPENSSL_malloc(outsize); if (out == NULL) goto err; if (!EVP_CipherUpdate(kemri->ctx, out, &outlen, in, (int)inlen)) @@ -388,7 +398,7 @@ int ossl_cms_RecipientInfo_kemri_decrypt(const CMS_ContentInfo *cms, goto err; kem_ct = ASN1_STRING_get0_data(kemri->kemct); - kem_ct_len = ASN1_STRING_length(kemri->kemct); + kem_ct_len = ASN1_STRING_get_length(kemri->kemct); if (EVP_PKEY_decapsulate(kemri->pctx, NULL, &kem_secret_len, kem_ct, kem_ct_len) <= 0) return 0; diff --git a/crypto/cms/cms_lib.c b/crypto/cms/cms_lib.c index 82bf01df26567..11aac8656e75f 100644 --- a/crypto/cms/cms_lib.c +++ b/crypto/cms/cms_lib.c @@ -35,7 +35,7 @@ CMS_ContentInfo *d2i_CMS_ContentInfo(CMS_ContentInfo **a, const CMS_CTX *ctx = ossl_cms_get0_cmsctx(a == NULL ? NULL : *a); ci = (CMS_ContentInfo *)ASN1_item_d2i_ex((ASN1_VALUE **)a, in, len, - (CMS_ContentInfo_it()), + ASN1_ITEM_rptr(CMS_ContentInfo), ossl_cms_ctx_get0_libctx(ctx), ossl_cms_ctx_get0_propq(ctx)); if (ci != NULL) { @@ -48,7 +48,7 @@ CMS_ContentInfo *d2i_CMS_ContentInfo(CMS_ContentInfo **a, int i2d_CMS_ContentInfo(const CMS_ContentInfo *a, unsigned char **out) { - return ASN1_item_i2d((const ASN1_VALUE *)a, out, (CMS_ContentInfo_it())); + return ASN1_item_i2d((const ASN1_VALUE *)a, out, ASN1_ITEM_rptr(CMS_ContentInfo)); } CMS_ContentInfo *CMS_ContentInfo_new_ex(OSSL_LIB_CTX *libctx, const char *propq) @@ -137,7 +137,7 @@ BIO *ossl_cms_content_bio(CMS_ContentInfo *cms) /* * If content not detached and created return memory BIO */ - if (*pos == NULL || ((*pos)->flags == ASN1_STRING_FLAG_CONT)) + if (*pos == NULL || cms->contentIncomplete) return BIO_new(BIO_s_mem()); /* Else content was read in: return read only BIO for it */ return BIO_new_mem_buf((*pos)->data, (*pos)->length); @@ -217,7 +217,7 @@ int ossl_cms_DataFinal(CMS_ContentInfo *cms, BIO *cmsbio, BIO *data, if (pos == NULL) return 0; /* If embedded content find memory BIO and set content */ - if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) { + if (*pos && cms->contentIncomplete) { BIO *mbio; unsigned char *cont; long contlen; @@ -231,7 +231,7 @@ int ossl_cms_DataFinal(CMS_ContentInfo *cms, BIO *cmsbio, BIO *data, BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY); BIO_set_mem_eof_return(mbio, 0); ASN1_STRING_set0(*pos, cont, contlen); - (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; + cms->contentIncomplete = 0; } switch (OBJ_obj2nid(cms->contentType)) { @@ -387,15 +387,13 @@ int CMS_set_detached(CMS_ContentInfo *cms, int detached) if (detached) { ASN1_OCTET_STRING_free(*pos); *pos = NULL; + cms->contentIncomplete = 0; return 1; } if (*pos == NULL) *pos = ASN1_OCTET_STRING_new(); if (*pos != NULL) { - /* - * NB: special flag to show content is created and not read in. - */ - (*pos)->flags |= ASN1_STRING_FLAG_CONT; + cms->contentIncomplete = 1; return 1; } ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB); diff --git a/crypto/cms/cms_local.h b/crypto/cms/cms_local.h index bfb0ca729b6e5..c2dfa55be95dd 100644 --- a/crypto/cms/cms_local.h +++ b/crypto/cms/cms_local.h @@ -66,6 +66,16 @@ struct CMS_ContentInfo_st { void *otherData; } d; CMS_CTX ctx; + /*- + * Set when the content octet string is empty and is to be filled at + * dataFinal time from the memory BIO ossl_cms_content_bio() returns. + * Cleared: + * - once the string has been filled; + * - when the content is detached; + * - when streaming is set up, where the encoder writes the content out + * and records its position in the string rather than filling it. + */ + int contentIncomplete; }; DEFINE_STACK_OF(CMS_CertificateChoices) @@ -74,6 +84,7 @@ struct CMS_SignedData_st { int32_t version; STACK_OF(X509_ALGOR) *digestAlgorithms; CMS_EncapsulatedContentInfo *encapContentInfo; + /* untrusted certificates for chain building, may include signer certs: */ STACK_OF(CMS_CertificateChoices) *certificates; STACK_OF(CMS_RevocationInfoChoice) *crls; STACK_OF(CMS_SignerInfo) *signerInfos; @@ -103,6 +114,11 @@ struct CMS_SignerInfo_st { const CMS_CTX *cms_ctx; /* Set to 1 if signing time attribute is to be omitted */ int omit_signing_time; + /* Remember which aspects have been verified */ + int verify_result; /* for this SignerInfo, all attempted verification aspects succeeded */ + int cert_verified; /* the certificate was verified successfully */ + int attr_verified; /* any given signed attributes were verified successfully */ + int content_verified; /* the signature over the content was verified successfully */ }; struct CMS_SignerIdentifier_st { @@ -140,6 +156,8 @@ struct CMS_EncryptedContentInfo_st { int debug; /* Set to 1 if we have no cert and need extra safety measures for MMA */ int havenocert; + /* Set to 1 if key length mismatch can be reported without an MMA risk */ + int harderr; }; struct CMS_RecipientInfo_st { @@ -431,6 +449,14 @@ CMS_ContentInfo *ossl_cms_Data_create(OSSL_LIB_CTX *ctx, const char *propq); int ossl_cms_DataFinal(CMS_ContentInfo *cms, BIO *cmsbio, BIO *data, const unsigned char *precomp_md, unsigned int precomp_mdlen); +/** + * @brief Prepare the content of cms for indefinite-length streaming. + * The content octet string is created if it is not already present, and the + * content is recorded as created here rather than read in via d2i. + * @param cms the CMS_ContentInfo to prepare for streaming + * @returns 1 on success, 0 on failure + */ +int ossl_cms_stream(CMS_ContentInfo *cms); CMS_ContentInfo *ossl_cms_DigestedData_create(const EVP_MD *md, OSSL_LIB_CTX *libctx, diff --git a/crypto/cms/cms_pwri.c b/crypto/cms/cms_pwri.c index 2cdac56fcf9fa..0950cc060bbf3 100644 --- a/crypto/cms/cms_pwri.c +++ b/crypto/cms/cms_pwri.c @@ -1,5 +1,5 @@ /* - * Copyright 2009-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2009-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -316,6 +316,7 @@ int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, EVP_CIPHER *kekcipher; unsigned char *key = NULL; size_t keylen; + size_t key_alloc_len = 0; const CMS_CTX *cms_ctx = ossl_cms_get0_cmsctx(cms); ec = ossl_cms_get0_env_enc_content(cms); @@ -392,6 +393,7 @@ int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, if (key == NULL) goto err; + key_alloc_len = keylen; if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, kekctx, cms_ctx)) goto err; @@ -401,6 +403,7 @@ int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, key = OPENSSL_malloc(pwri->encryptedKey->length); if (key == NULL) goto err; + key_alloc_len = (size_t)pwri->encryptedKey->length; if (!kek_unwrap_key(key, &keylen, pwri->encryptedKey->data, pwri->encryptedKey->length, kekctx)) { @@ -420,7 +423,7 @@ int ossl_cms_RecipientInfo_pwri_crypt(const CMS_ContentInfo *cms, EVP_CIPHER_CTX_free(kekctx); if (!r) - OPENSSL_free(key); + OPENSSL_clear_free(key, key_alloc_len); X509_ALGOR_free(kekalg); return r; diff --git a/crypto/cms/cms_rsa.c b/crypto/cms/cms_rsa.c index fc7fc6c284b79..c81e02aa40bf7 100644 --- a/crypto/cms/cms_rsa.c +++ b/crypto/cms/cms_rsa.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -43,7 +43,7 @@ static int rsa_cms_decrypt(CMS_RecipientInfo *ri) int nid; int rv = -1; const unsigned char *label = NULL; - int labellen = 0; + size_t labellen = 0; const EVP_MD *mgf1md = NULL, *md = NULL; RSA_OAEP_PARAMS *oaep; const ASN1_OBJECT *aoid; @@ -90,7 +90,9 @@ static int rsa_cms_decrypt(CMS_RecipientInfo *ri) } label = ASN1_STRING_get0_data(parameter); - labellen = ASN1_STRING_length(parameter); + labellen = ASN1_STRING_get_length(parameter); + if (labellen > INT_MAX) + goto err; } if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_OAEP_PADDING) <= 0) @@ -105,7 +107,7 @@ static int rsa_cms_decrypt(CMS_RecipientInfo *ri) if (dup_label == NULL) goto err; - if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, dup_label, labellen) <= 0) { + if (EVP_PKEY_CTX_set0_rsa_oaep_label(pkctx, dup_label, (int)labellen) <= 0) { OPENSSL_free(dup_label); goto err; } diff --git a/crypto/cms/cms_sd.c b/crypto/cms/cms_sd.c index 6466aacec1d99..f0d581e8edab3 100644 --- a/crypto/cms/cms_sd.c +++ b/crypto/cms/cms_sd.c @@ -304,7 +304,7 @@ static int ossl_cms_add1_signing_cert(CMS_SignerInfo *si, p = pp; i2d_ESS_SIGNING_CERT(sc, &p); - if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) { + if (!(seq = ASN1_STRING_new()) || !ossl_asn1_string_set1_data(seq, pp, len)) { ASN1_STRING_free(seq); OPENSSL_free(pp); return 0; @@ -329,7 +329,7 @@ static int ossl_cms_add1_signing_cert_v2(CMS_SignerInfo *si, p = pp; i2d_ESS_SIGNING_CERT_V2(sc, &p); - if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) { + if (!(seq = ASN1_STRING_new()) || !ossl_asn1_string_set1_data(seq, pp, len)) { ASN1_STRING_free(seq); OPENSSL_free(pp); return 0; @@ -631,7 +631,7 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, if (!ossl_cms_set1_SignerIdentifier(si->sid, signer, type, ctx)) goto err; - if (ossl_cms_adjust_md(ctx, pk, &md, &local_md, flags) != 1 && local_md != md) + if (ossl_cms_adjust_md(ctx, pk, &md, &local_md, flags) != 1) goto err; if (!X509_ALGOR_set_md(si->digestAlgorithm, md)) @@ -677,7 +677,8 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, if (!(flags & CMS_NOSMIMECAP)) { STACK_OF(X509_ALGOR) *smcap = NULL; - i = CMS_add_standard_smimecap(&smcap); + i = CMS_add_standard_smimecap_ex(&smcap, ossl_cms_ctx_get0_libctx(ctx), + ossl_cms_ctx_get0_propq(ctx)); if (i) i = CMS_add_smimecap(si, smcap); sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); @@ -728,7 +729,6 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, } if (!(flags & CMS_NOCERTS)) { - /* NB ignore -1 return for duplicate cert */ if (!CMS_add1_cert(cms, signer)) { ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB); goto err; @@ -870,6 +870,11 @@ void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer) si->signer = signer; } +X509 *CMS_SignerInfo_get0_signer_cert(const CMS_SignerInfo *si) +{ + return si->signer; +} + int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno) @@ -902,6 +907,7 @@ int CMS_set1_signers_certs(CMS_ContentInfo *cms, const STACK_OF(X509) *scerts, if (si->signer != NULL) continue; + /* If any certificates passed they take priority */ for (j = 0; j < sk_X509_num(scerts); j++) { x = sk_X509_value(scerts, j); if (CMS_SignerInfo_cert_cmp(si, x) == 0) { @@ -1052,6 +1058,27 @@ static int cms_EVP_PKEY_verify(EVP_PKEY_CTX *pctx, BIO *in, unsigned char *sig, return ret; } +int CMS_SignerInfo_get_verification_result(const CMS_SignerInfo *si, int type) +{ + switch (type) { + case CMS_VERIFY_RESULT: + return si->verify_result; + + case CMS_VERIFY_CERT: + return si->cert_verified; + + case CMS_VERIFY_ATTR: + return si->attr_verified; + + case CMS_VERIFY_CONTENT: + return si->content_verified; + + default: + ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_ID); + return 0; + } +} + static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, CMS_SignerInfo *si, BIO *chain, BIO *data, @@ -1308,10 +1335,15 @@ int CMS_SignerInfo_verify(CMS_SignerInfo *si) (void)ERR_set_mark(); fetched_md = EVP_MD_fetch(libctx, name, propq); - if (fetched_md != NULL) + if (fetched_md != NULL) { md = fetched_md; - else + } else { md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); + /* Reject aliases such as signature algorithm OIDs */ + if (md != NULL + && EVP_MD_get_type(md) != OBJ_obj2nid(si->digestAlgorithm->algorithm)) + md = NULL; + } if (md == NULL) { (void)ERR_clear_last_mark(); ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_DIGEST_ALGORITHM); @@ -1584,34 +1616,53 @@ int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, } /* Check to see if a cipher exists and if so add S/MIME capabilities */ -static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) +static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg, + OSSL_LIB_CTX *libctx, const char *propq) { - if (EVP_get_cipherbynid(nid)) + EVP_CIPHER *cipher; + + ERR_set_mark(); + cipher = EVP_CIPHER_fetch(libctx, OBJ_nid2sn(nid), propq); + ERR_pop_to_mark(); + if (cipher != NULL) { + EVP_CIPHER_free(cipher); return CMS_add_simple_smimecap(sk, nid, arg); + } return 1; } -static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) +static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg, + OSSL_LIB_CTX *libctx, const char *propq) { - if (EVP_get_digestbynid(nid)) + EVP_MD *md; + + ERR_set_mark(); + md = EVP_MD_fetch(libctx, OBJ_nid2sn(nid), propq); + ERR_pop_to_mark(); + if (md != NULL) { + EVP_MD_free(md); return CMS_add_simple_smimecap(sk, nid, arg); + } return 1; } -int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) +int CMS_add_standard_smimecap_ex(STACK_OF(X509_ALGOR) **smcap, + OSSL_LIB_CTX *libctx, const char *propq) { - if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) - || !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_256, -1) - || !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_512, -1) - || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1) - || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) - || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) - || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) - || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) - || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128) - || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64) - || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1) - || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40)) + if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1, libctx, propq) + || !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_256, -1, libctx, propq) + || !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_512, -1, libctx, propq) + || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1, libctx, propq) + || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1, libctx, propq) + || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1, libctx, propq) + || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1, libctx, propq) + || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1, libctx, propq) + || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128, libctx, propq)) return 0; return 1; } + +int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) +{ + return CMS_add_standard_smimecap_ex(smcap, NULL, NULL); +} diff --git a/crypto/cms/cms_smime.c b/crypto/cms/cms_smime.c index 044cb2326f554..ae99d1b27f2e2 100644 --- a/crypto/cms/cms_smime.c +++ b/crypto/cms/cms_smime.c @@ -350,7 +350,7 @@ int CMS_verify(CMS_ContentInfo *cms, const STACK_OF(X509) *certs, STACK_OF(X509_CRL) *crls = NULL; STACK_OF(X509) **si_chains = NULL; X509 *signer; - int i, scount = 0, ret = 0; + int i, n = 0, scount = 0, ret = 0; BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL; int cadesVerify = (flags & CMS_CADES) != 0; const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); @@ -378,6 +378,11 @@ int CMS_verify(CMS_ContentInfo *cms, const STACK_OF(X509) *certs, CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); if (signer != NULL) scount++; + /* Reset verification results */ + si->verify_result = 1; /* so far, fine */ + si->cert_verified = 0; + si->attr_verified = 0; + si->content_verified = 0; } if (scount != sk_CMS_SignerInfo_num(sinfos)) @@ -413,8 +418,11 @@ int CMS_verify(CMS_ContentInfo *cms, const STACK_OF(X509) *certs, if (!cms_signerinfo_verify_cert(si, store, untrusted, crls, si_chains ? &si_chains[i] : NULL, - ctx)) - goto err; + ctx)) { + si->verify_result = 0; + continue; + } + si->cert_verified = 1; } } @@ -423,16 +431,25 @@ int CMS_verify(CMS_ContentInfo *cms, const STACK_OF(X509) *certs, if ((flags & CMS_NO_ATTR_VERIFY) == 0 || cadesVerify) { for (i = 0; i < scount; i++) { si = sk_CMS_SignerInfo_value(sinfos, i); - if (CMS_signed_get_attr_count(si) < 0) + if (!si->verify_result) continue; - if (CMS_SignerInfo_verify(si) <= 0) - goto err; + if (CMS_signed_get_attr_count(si) < 0) { + si->attr_verified = 1; + continue; + } + if (CMS_SignerInfo_verify(si) <= 0) { + si->verify_result = 0; + continue; + } if (cadesVerify) { STACK_OF(X509) *si_chain = si_chains ? si_chains[i] : NULL; - if (ossl_cms_check_signing_certs(si, si_chain) <= 0) - goto err; + if (ossl_cms_check_signing_certs(si, si_chain) <= 0) { + si->verify_result = 0; + continue; + } } + si->attr_verified = 1; } } @@ -497,15 +514,30 @@ int CMS_verify(CMS_ContentInfo *cms, const STACK_OF(X509) *certs, if (!(flags & CMS_NO_CONTENT_VERIFY)) { for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { si = sk_CMS_SignerInfo_value(sinfos, i); + if (!si->verify_result) + continue; if (CMS_SignerInfo_verify_ex(si, cmsbio, tmpin) <= 0) { ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_VERIFY_ERROR); - goto err; + si->verify_result = 0; + continue; } + si->content_verified = 1; } } - ret = 1; + /* Determine overall result */ + for (i = 0; i < scount; i++) { + if (sk_CMS_SignerInfo_value(sinfos, i)->verify_result) + n++; + } + if ((flags & CMS_VERIFY_PARTIAL) != 0) + ret = n > 0; /* One success is enough */ + else + ret = n == scount; /* All must be successful */ err: + if (!ret) + for (i = 0; i < scount; i++) + sk_CMS_SignerInfo_value(sinfos, i)->verify_result = 0; if (!(flags & SMIME_BINARY) && dcont) { do_free_upto(cmsbio, tmpout); if (tmpin != dcont) @@ -760,6 +792,7 @@ int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, OPENSSL_clear_free(ec->key, ec->keylen); ec->key = NULL; ec->keylen = 0; + ec->harderr = 0; } if (ris != NULL && ec != NULL) @@ -803,10 +836,11 @@ int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, CMS_RecipientInfo_set0_pkey(ri, NULL); if (cert != NULL) { /* - * If not debugging clear any error and return success to - * avoid leaking of information useful to MMA + * If not debugging and a failure cannot be reported safely, + * clear any error and return success to avoid leaking of + * information useful to MMA */ - if (!debug) { + if (!debug && (ec == NULL || !ec->harderr)) { ERR_clear_error(); return 1; } @@ -887,6 +921,7 @@ int CMS_decrypt_set1_password(CMS_ContentInfo *cms, OPENSSL_clear_free(ec->key, ec->keylen); ec->key = NULL; ec->keylen = 0; + ec->harderr = 0; } for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { diff --git a/crypto/comp/c_brotli.c b/crypto/comp/c_brotli.c index 9c99e066b78d6..9ede56fa97a74 100644 --- a/crypto/comp/c_brotli.c +++ b/crypto/comp/c_brotli.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -289,6 +289,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_brotli_init) #define LIBBROTLIDEC "brotlidec" #endif + ERR_set_mark(); brotli_encode_dso = DSO_load(NULL, LIBBROTLIENC, NULL, 0); if (brotli_encode_dso != NULL) { p_encode_init = (encode_init_ft)DSO_bind_func(brotli_encode_dso, "BrotliEncoderCreateInstance"); @@ -315,9 +316,12 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_brotli_init) || p_decode_stream == NULL || p_decode_has_more == NULL || p_decode_end == NULL || p_decode_error == NULL || p_decode_error_string == NULL || p_decode_is_finished == NULL || p_decode_oneshot == NULL) { + ERR_clear_last_mark(); ossl_comp_brotli_cleanup(); return 0; } + /* Do not leave errors behind on success. */ + ERR_pop_to_mark(); #endif return 1; } diff --git a/crypto/comp/c_zlib.c b/crypto/comp/c_zlib.c index 4af4e30b64b13..da073385372d7 100644 --- a/crypto/comp/c_zlib.c +++ b/crypto/comp/c_zlib.c @@ -278,6 +278,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init) #endif #endif + ERR_set_mark(); zlib_dso = DSO_load(NULL, LIBZ, NULL, 0); if (zlib_dso != NULL) { p_compress = (compress_ft)DSO_bind_func(zlib_dso, "compress"); @@ -295,9 +296,12 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_zlib_init) || p_inflate == NULL || p_inflateInit_ == NULL || p_deflateEnd == NULL || p_deflate == NULL || p_deflateInit_ == NULL || p_zError == NULL) { + ERR_clear_last_mark(); ossl_comp_zlib_cleanup(); return 0; } + /* Do not leave errors behind on success. */ + ERR_pop_to_mark(); #endif return 1; } diff --git a/crypto/comp/c_zstd.c b/crypto/comp/c_zstd.c index c5c6cd6eef9dd..6eaf2c362a5ce 100644 --- a/crypto/comp/c_zstd.c +++ b/crypto/comp/c_zstd.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -357,6 +357,7 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_zstd_init) #define LIBZSTD "zstd" #endif + ERR_set_mark(); zstd_dso = DSO_load(NULL, LIBZSTD, NULL, 0); if (zstd_dso != NULL) { p_createCStream = (createCStream_ft)DSO_bind_func(zstd_dso, "ZSTD_createCStream"); @@ -383,9 +384,12 @@ DEFINE_RUN_ONCE_STATIC(ossl_comp_zstd_init) || p_freeDStream == NULL || p_decompressStream == NULL || p_decompress == NULL || p_isError == NULL || p_getErrorName == NULL || p_DStreamInSize == NULL || p_CStreamInSize == NULL) { + ERR_clear_last_mark(); ossl_comp_zstd_cleanup(); return 0; } + /* Do not leave errors behind on success. */ + ERR_pop_to_mark(); #endif return 1; } diff --git a/crypto/comp/comp_err.c b/crypto/comp/comp_err.c deleted file mode 100644 index 0aa0dc6302483..0000000000000 --- a/crypto/comp/comp_err.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/comperr.h" - -#ifndef OPENSSL_NO_COMP - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA COMP_str_reasons[] = { - { ERR_PACK(ERR_LIB_COMP, 0, COMP_R_BROTLI_DECODE_ERROR), - "brotli decode error" }, - { ERR_PACK(ERR_LIB_COMP, 0, COMP_R_BROTLI_ENCODE_ERROR), - "brotli encode error" }, - { ERR_PACK(ERR_LIB_COMP, 0, COMP_R_BROTLI_NOT_SUPPORTED), - "brotli not supported" }, - { ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZLIB_DEFLATE_ERROR), - "zlib deflate error" }, - { ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZLIB_INFLATE_ERROR), - "zlib inflate error" }, - { ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZLIB_NOT_SUPPORTED), - "zlib not supported" }, - { ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZSTD_COMPRESS_ERROR), - "zstd compress error" }, - { ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZSTD_DECODE_ERROR), "zstd decode error" }, - { ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZSTD_DECOMPRESS_ERROR), - "zstd decompress error" }, - { ERR_PACK(ERR_LIB_COMP, 0, COMP_R_ZSTD_NOT_SUPPORTED), - "zstd not supported" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_COMP_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(COMP_str_reasons[0].error) == NULL) - ERR_load_strings_const(COMP_str_reasons); -#endif - return 1; -} -#else -NON_EMPTY_TRANSLATION_UNIT -#endif diff --git a/crypto/comp/comp_local.h b/crypto/comp/comp_local.h index bb9d4a0f79705..41f47a66fee09 100644 --- a/crypto/comp/comp_local.h +++ b/crypto/comp/comp_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/conf/build.info b/crypto/conf/build.info index ff367994ea091..3f563dc98804a 100644 --- a/crypto/conf/build.info +++ b/crypto/conf/build.info @@ -2,3 +2,7 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]= \ conf_err.c conf_lib.c conf_api.c conf_def.c conf_mod.c \ conf_mall.c conf_sap.c conf_ssl.c + +DEPEND[conf_def.o]=conf_def.h +GENERATE[conf_def.h]=keysets.pl +INCLUDE[conf_def.o]=. diff --git a/crypto/conf/conf_def.c b/crypto/conf/conf_def.c index e41fdbe6c71f3..f414add6a820f 100644 --- a/crypto/conf/conf_def.c +++ b/crypto/conf/conf_def.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -587,7 +587,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *line) #endif if (line != NULL) *line = eline; - BIO_snprintf(btmp, sizeof(btmp), "%ld", eline); + snprintf(btmp, sizeof(btmp), "%ld", eline); ERR_add_error_data(2, "line ", btmp); if (h != conf->data) { CONF_free(conf->data); @@ -643,6 +643,7 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) int q, r, rr = 0, to = 0; char *s, *e, *rp, *p, *rrp, *np, *cp, v; BUF_MEM *buf; + int ret = 0; if ((buf = BUF_MEM_new()) == NULL) return 0; @@ -783,11 +784,12 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) buf->data[to] = '\0'; OPENSSL_free(*pto); *pto = buf->data; - OPENSSL_free(buf); - return 1; + /* Take ownership of the buf mem data */ + buf->data = NULL; + ret = 1; err: BUF_MEM_free(buf); - return 0; + return ret; } #ifndef OPENSSL_NO_POSIX_IO diff --git a/crypto/conf/conf_def.h b/crypto/conf/conf_def.h deleted file mode 100644 index 2fdc9d7d996ed..0000000000000 --- a/crypto/conf/conf_def.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * WARNING: do not edit! - * Generated by crypto/conf/keysets.pl - * - * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ -#if !defined(OSSL_LIBCRYPTO_CONF_CONF_DEF_H) -#define OSSL_LIBCRYPTO_CONF_CONF_DEF_H - -/* clang-format off */ -#define CONF_NUMBER 1 -#define CONF_UPPER 2 -#define CONF_LOWER 4 -#define CONF_UNDER 256 -#define CONF_PUNCT 512 -#define CONF_WS 16 -#define CONF_ESC 32 -#define CONF_QUOTE 64 -#define CONF_DQUOTE 1024 -#define CONF_COMMENT 128 -#define CONF_FCOMMENT 2048 -#define CONF_DOLLAR 4096 -#define CONF_EOF 8 -#define CONF_ALPHA (CONF_UPPER|CONF_LOWER) -#define CONF_ALNUM (CONF_ALPHA|CONF_NUMBER|CONF_UNDER) -#define CONF_ALNUM_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER|CONF_PUNCT) - - -#define IS_COMMENT(conf,c) is_keytype(conf, c, CONF_COMMENT) -#define IS_FCOMMENT(conf,c) is_keytype(conf, c, CONF_FCOMMENT) -#define IS_EOF(conf,c) is_keytype(conf, c, CONF_EOF) -#define IS_ESC(conf,c) is_keytype(conf, c, CONF_ESC) -#define IS_NUMBER(conf,c) is_keytype(conf, c, CONF_NUMBER) -#define IS_WS(conf,c) is_keytype(conf, c, CONF_WS) -#define IS_ALNUM(conf,c) is_keytype(conf, c, CONF_ALNUM) -#define IS_ALNUM_PUNCT(conf,c) is_keytype(conf, c, CONF_ALNUM_PUNCT) -#define IS_QUOTE(conf,c) is_keytype(conf, c, CONF_QUOTE) -#define IS_DQUOTE(conf,c) is_keytype(conf, c, CONF_DQUOTE) -#define IS_DOLLAR(conf,c) is_keytype(conf, c, CONF_DOLLAR) - -static const unsigned short CONF_type_default[128] = { - 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0010, 0x0200, 0x0040, 0x0080, 0x1000, 0x0200, 0x0200, 0x0040, - 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, - 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, - 0x0001, 0x0001, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200, - 0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, - 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, - 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, - 0x0002, 0x0002, 0x0002, 0x0000, 0x0020, 0x0000, 0x0200, 0x0100, - 0x0040, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, - 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, - 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, - 0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000, -}; - -#ifndef OPENSSL_NO_DEPRECATED_3_0 -static const unsigned short CONF_type_win32[128] = { - 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0010, 0x0200, 0x0400, 0x0000, 0x1000, 0x0200, 0x0200, 0x0000, - 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, - 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, - 0x0001, 0x0001, 0x0000, 0x0A00, 0x0000, 0x0000, 0x0000, 0x0200, - 0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, - 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, - 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, - 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0200, 0x0100, - 0x0000, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, - 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, - 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, - 0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000, -}; -#endif -/* clang-format on */ - -#endif /* !defined(OSSL_LIBCRYPTO_CONF_CONF_DEF_H) */ diff --git a/crypto/conf/conf_err.c b/crypto/conf/conf_err.c deleted file mode 100644 index 0dd42e0f43c75..0000000000000 --- a/crypto/conf/conf_err.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/conferr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA CONF_str_reasons[] = { - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_ERROR_LOADING_DSO), "error loading dso" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_INVALID_PRAGMA), "invalid pragma" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_LIST_CANNOT_BE_NULL), - "list cannot be null" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_MANDATORY_BRACES_IN_VARIABLE_EXPANSION), - "mandatory braces in variable expansion" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_MISSING_CLOSE_SQUARE_BRACKET), - "missing close square bracket" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_MISSING_EQUAL_SIGN), - "missing equal sign" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_MISSING_INIT_FUNCTION), - "missing init function" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_MODULE_INITIALIZATION_ERROR), - "module initialization error" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NO_CLOSE_BRACE), "no close brace" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NO_CONF), "no conf" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE), - "no conf or environment variable" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NO_SECTION), "no section" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NO_SUCH_FILE), "no such file" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NO_VALUE), "no value" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_NUMBER_TOO_LARGE), "number too large" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_OPENSSL_CONF_REFERENCES_MISSING_SECTION), - "openssl conf references missing section" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_RECURSIVE_DIRECTORY_INCLUDE), - "recursive directory include" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_RECURSIVE_SECTION_REFERENCE), - "recursive section reference" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_RELATIVE_PATH), "relative path" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_SSL_COMMAND_SECTION_EMPTY), - "ssl command section empty" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_SSL_COMMAND_SECTION_NOT_FOUND), - "ssl command section not found" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_SSL_SECTION_EMPTY), "ssl section empty" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_SSL_SECTION_NOT_FOUND), - "ssl section not found" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_UNABLE_TO_CREATE_NEW_SECTION), - "unable to create new section" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_UNKNOWN_MODULE_NAME), - "unknown module name" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_VARIABLE_EXPANSION_TOO_LONG), - "variable expansion too long" }, - { ERR_PACK(ERR_LIB_CONF, 0, CONF_R_VARIABLE_HAS_NO_VALUE), - "variable has no value" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_CONF_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(CONF_str_reasons[0].error) == NULL) - ERR_load_strings_const(CONF_str_reasons); -#endif - return 1; -} diff --git a/crypto/conf/conf_lib.c b/crypto/conf/conf_lib.c index c148a43490a56..3bd750144cec2 100644 --- a/crypto/conf/conf_lib.c +++ b/crypto/conf/conf_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/conf/conf_local.h b/crypto/conf/conf_local.h index 1ecef7549a358..53e34c8aa80e4 100644 --- a/crypto/conf/conf_local.h +++ b/crypto/conf/conf_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/conf/conf_mod.c b/crypto/conf/conf_mod.c index 9f55954bf9034..f20bc6ab46ab5 100644 --- a/crypto/conf/conf_mod.c +++ b/crypto/conf/conf_mod.c @@ -672,7 +672,7 @@ char *CONF_get1_default_config_file(void) if (file == NULL) return NULL; - BIO_snprintf(file, size, "%s%s%s", t, sep, OPENSSL_CONF); + snprintf(file, size, "%s%s%s", t, sep, OPENSSL_CONF); return file; } @@ -723,3 +723,35 @@ int CONF_parse_list(const char *list_, int sep, int nospc, lstart = p + 1; } } + +/* + * Parse a boolean configuration value: 1, yes, true or on (in lower or + * uppercase) enables, 0, no, false or off disables. Returns 0 when the + * value is missing or not recognised, without raising an error. + */ +int ossl_conf_parse_bool(const char *value, int *result) +{ + if (value == NULL) + return 0; + if (strcmp(value, "1") == 0 + || strcmp(value, "yes") == 0 + || strcmp(value, "YES") == 0 + || strcmp(value, "true") == 0 + || strcmp(value, "TRUE") == 0 + || strcmp(value, "on") == 0 + || strcmp(value, "ON") == 0) { + *result = 1; + return 1; + } + if (strcmp(value, "0") == 0 + || strcmp(value, "no") == 0 + || strcmp(value, "NO") == 0 + || strcmp(value, "false") == 0 + || strcmp(value, "FALSE") == 0 + || strcmp(value, "off") == 0 + || strcmp(value, "OFF") == 0) { + *result = 0; + return 1; + } + return 0; +} diff --git a/crypto/conf/keysets.pl b/crypto/conf/keysets.pl index cb0ddc300a9c9..9af08ead2e138 100644 --- a/crypto/conf/keysets.pl +++ b/crypto/conf/keysets.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/core_fetch.c b/crypto/core_fetch.c index 3d09b384aa18f..2abd32255c981 100644 --- a/crypto/core_fetch.c +++ b/crypto/core_fetch.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/cpt_err.c b/crypto/cpt_err.c deleted file mode 100644 index e102782978bb3..0000000000000 --- a/crypto/cpt_err.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/cryptoerr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA CRYPTO_str_reasons[] = { - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_BAD_ALGORITHM_NAME), - "bad algorithm name" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_CONFLICTING_NAMES), - "conflicting names" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_HEX_STRING_TOO_SHORT), - "hex string too short" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ILLEGAL_HEX_DIGIT), - "illegal hex digit" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INSUFFICIENT_DATA_SPACE), - "insufficient data space" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INSUFFICIENT_PARAM_SIZE), - "insufficient param size" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE), - "insufficient secure data space" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INTEGER_OVERFLOW), - "integer overflow" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INVALID_NEGATIVE_VALUE), - "invalid negative value" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INVALID_NULL_ARGUMENT), - "invalid null argument" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_INVALID_OSSL_PARAM_TYPE), - "invalid ossl param type" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_NO_PARAMS_TO_MERGE), - "no params to merge" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_NO_SPACE_FOR_TERMINATING_NULL), - "no space for terminating null" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ODD_NUMBER_OF_DIGITS), - "odd number of digits" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PARAM_CANNOT_BE_REPRESENTED_EXACTLY), - "param cannot be represented exactly" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PARAM_NOT_INTEGER_TYPE), - "param not integer type" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PARAM_OF_INCOMPATIBLE_TYPE), - "param of incompatible type" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PARAM_UNSIGNED_INTEGER_NEGATIVE_VALUE_UNSUPPORTED), - "param unsigned integer negative value unsupported" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PARAM_UNSUPPORTED_FLOATING_POINT_FORMAT), - "param unsupported floating point format" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PARAM_VALUE_TOO_LARGE_FOR_DESTINATION), - "param value too large for destination" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PROVIDER_ALREADY_EXISTS), - "provider already exists" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_PROVIDER_SECTION_ERROR), - "provider section error" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_RANDOM_SECTION_ERROR), - "random section error" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_SECURE_MALLOC_FAILURE), - "secure malloc failure" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_STRING_TOO_LONG), "string too long" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_MANY_BYTES), "too many bytes" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_MANY_NAMES), "too many names" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_MANY_RECORDS), - "too many records" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_TOO_SMALL_BUFFER), - "too small buffer" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION), - "unknown name in random section" }, - { ERR_PACK(ERR_LIB_CRYPTO, 0, CRYPTO_R_ZERO_LENGTH_NUMBER), - "zero length number" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_CRYPTO_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(CRYPTO_str_reasons[0].error) == NULL) - ERR_load_strings_const(CRYPTO_str_reasons); -#endif - return 1; -} diff --git a/crypto/cpuid.c b/crypto/cpuid.c index 89d841bfd0df7..83a5e0b57bd05 100644 --- a/crypto/cpuid.c +++ b/crypto/cpuid.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/crmf/crmf_err.c b/crypto/crmf/crmf_err.c deleted file mode 100644 index 5441d6ccd2980..0000000000000 --- a/crypto/crmf/crmf_err.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/crmferr.h" - -#ifndef OPENSSL_NO_CRMF - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA CRMF_str_reasons[] = { - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_BAD_PBM_ITERATIONCOUNT), - "bad pbm iterationcount" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_CMS_NOT_SUPPORTED), "cms not supported" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_CRMFERROR), "crmferror" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR), "error" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECODING_CERTIFICATE), - "error decoding certificate" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECODING_ENCRYPTEDKEY), - "error decoding encryptedkey" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_CERTIFICATE), - "error decrypting certificate" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_ENCRYPTEDKEY), - "error decrypting encryptedkey" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_ENCRYPTEDVALUE), - "error decrypting encryptedvalue" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY), - "error decrypting symmetric key" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_SETTING_PURPOSE), - "error setting purpose" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_SIGNING_POPO), - "error signing popo" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ERROR_VERIFYING_ENCRYPTEDKEY), - "error verifying encryptedkey" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_FAILURE_OBTAINING_RANDOM), - "failure obtaining random" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_ITERATIONCOUNT_BELOW_100), - "iterationcount below 100" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_MALFORMED_IV), "malformed iv" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_NULL_ARGUMENT), "null argument" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPOSKINPUT_NOT_SUPPORTED), - "poposkinput not supported" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_INCONSISTENT_CENTRAL_KEYGEN), - "popo inconsistent central keygen" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY), - "popo inconsistent public key" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING), "popo missing" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING_PUBLIC_KEY), - "popo missing public key" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_MISSING_SUBJECT), - "popo missing subject" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED), - "popo raverified not accepted" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_MAC_ALGOR_FAILURE), - "setting mac algor failure" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_SETTING_OWF_ALGOR_FAILURE), - "setting owf algor failure" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_ALGORITHM), - "unsupported algorithm" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_CIPHER), - "unsupported cipher" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO), - "unsupported method for creating popo" }, - { ERR_PACK(ERR_LIB_CRMF, 0, CRMF_R_UNSUPPORTED_POPO_METHOD), - "unsupported popo method" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_CRMF_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(CRMF_str_reasons[0].error) == NULL) - ERR_load_strings_const(CRMF_str_reasons); -#endif - return 1; -} -#else -NON_EMPTY_TRANSLATION_UNIT -#endif diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c index 07b244cb35676..229552f85c913 100644 --- a/crypto/cryptlib.c +++ b/crypto/cryptlib.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/ct/ct_b64.c b/crypto/ct/ct_b64.c index ed8407350321b..b2a91b9426abc 100644 --- a/crypto/ct/ct_b64.c +++ b/crypto/ct/ct_b64.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ct/ct_err.c b/crypto/ct/ct_err.c deleted file mode 100644 index 21d9061b9b088..0000000000000 --- a/crypto/ct/ct_err.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/cterr.h" - -#ifndef OPENSSL_NO_CT - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA CT_str_reasons[] = { - { ERR_PACK(ERR_LIB_CT, 0, CT_R_BASE64_DECODE_ERROR), "base64 decode error" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_INVALID_LOG_ID_LENGTH), - "invalid log id length" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_INVALID), "log conf invalid" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_INVALID_KEY), - "log conf invalid key" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_MISSING_DESCRIPTION), - "log conf missing description" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_CONF_MISSING_KEY), - "log conf missing key" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_LOG_KEY_INVALID), "log key invalid" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_FUTURE_TIMESTAMP), - "sct future timestamp" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_INVALID), "sct invalid" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_INVALID_SIGNATURE), - "sct invalid signature" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_LIST_INVALID), "sct list invalid" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_LOG_ID_MISMATCH), "sct log id mismatch" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_NOT_SET), "sct not set" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_SCT_UNSUPPORTED_VERSION), - "sct unsupported version" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_UNRECOGNIZED_SIGNATURE_NID), - "unrecognized signature nid" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_UNSUPPORTED_ENTRY_TYPE), - "unsupported entry type" }, - { ERR_PACK(ERR_LIB_CT, 0, CT_R_UNSUPPORTED_VERSION), "unsupported version" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_CT_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(CT_str_reasons[0].error) == NULL) - ERR_load_strings_const(CT_str_reasons); -#endif - return 1; -} -#else -NON_EMPTY_TRANSLATION_UNIT -#endif diff --git a/crypto/ct/ct_local.h b/crypto/ct/ct_local.h index 337dc272c305c..771d63dcdaece 100644 --- a/crypto/ct/ct_local.h +++ b/crypto/ct/ct_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ct/ct_log.c b/crypto/ct/ct_log.c index 6fad6a6bd4db8..8c1184984f375 100644 --- a/crypto/ct/ct_log.c +++ b/crypto/ct/ct_log.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ct/ct_oct.c b/crypto/ct/ct_oct.c index b8bef582a9fd9..3f1666baa1e29 100644 --- a/crypto/ct/ct_oct.c +++ b/crypto/ct/ct_oct.c @@ -381,7 +381,7 @@ STACK_OF(SCT) *d2i_SCT_LIST(STACK_OF(SCT) **a, const unsigned char **pp, return NULL; p = ASN1_STRING_get0_data(oct); - if ((sk = o2i_SCT_LIST(a, &p, ASN1_STRING_length(oct))) != NULL) + if ((sk = o2i_SCT_LIST(a, &p, ASN1_STRING_get_length(oct))) != NULL) *pp += len; ASN1_OCTET_STRING_free(oct); diff --git a/crypto/ct/ct_prn.c b/crypto/ct/ct_prn.c index 64323a8e507ee..cdca666cfe035 100644 --- a/crypto/ct/ct_prn.c +++ b/crypto/ct/ct_prn.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,6 +11,8 @@ #error "CT is disabled" #endif +#include + #include #include @@ -40,7 +42,7 @@ static void timestamp_print(uint64_t timestamp, BIO *out) * Note GeneralizedTime from ASN1_GENERALIZETIME_adj is always 15 * characters long with a final Z. Update it with fractional seconds. */ - BIO_snprintf(genstr, sizeof(genstr), "%.14s.%03dZ", + snprintf(genstr, sizeof(genstr), "%.14s.%03dZ", ASN1_STRING_get0_data(gen), (unsigned int)(timestamp % 1000)); if (ASN1_GENERALIZEDTIME_set_string(gen, genstr)) ASN1_GENERALIZEDTIME_print(out, gen); diff --git a/crypto/ctype.c b/crypto/ctype.c index 75192b11f4af7..4f19d6002c5e7 100644 --- a/crypto/ctype.c +++ b/crypto/ctype.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/cversion.c b/crypto/cversion.c index 98f7e2798b845..380a35a8efd86 100644 --- a/crypto/cversion.c +++ b/crypto/cversion.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -59,9 +59,9 @@ static CRYPTO_ONCE version_strings_once = CRYPTO_ONCE_STATIC_INIT; DEFINE_RUN_ONCE_STATIC(version_strings_setup) { - BIO_snprintf(openssldir, sizeof(openssldir), "OPENSSLDIR: \"%s\"", + snprintf(openssldir, sizeof(openssldir), "OPENSSLDIR: \"%s\"", ossl_get_openssldir()); - BIO_snprintf(modulesdir, sizeof(modulesdir), "MODULESDIR: \"%s\"", + snprintf(modulesdir, sizeof(modulesdir), "MODULESDIR: \"%s\"", ossl_get_modulesdir()); return 1; } diff --git a/crypto/defaults.c b/crypto/defaults.c index b98d5eaabcb51..f55f79a82eea6 100644 --- a/crypto/defaults.c +++ b/crypto/defaults.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -61,8 +61,12 @@ static char *get_windows_regdirs(char *dst, DWORD dstsizebytes, LPCWSTR valuenam DWORD index = 0; LPCWSTR tempstr = NULL; - ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, - TEXT(REGISTRY_KEY), KEY_WOW64_32KEY, + /* + * Narrow call: TEXT(REGISTRY_KEY) would widen only the first literal of the + * concatenation, which MSVC 12.0 rejects. The subkey path is ASCII. + */ + ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, + REGISTRY_KEY, KEY_WOW64_32KEY, KEY_QUERY_VALUE, &hkey); if (ret != ERROR_SUCCESS) goto out; diff --git a/crypto/des/asm/dest4-sparcv9.pl b/crypto/des/asm/dest4-sparcv9.pl index 87a5a82742ccc..3928d58665436 100644 --- a/crypto/des/asm/dest4-sparcv9.pl +++ b/crypto/des/asm/dest4-sparcv9.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2013-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2013-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/des/cfb64ede.c b/crypto/des/cfb64ede.c index 56aab27f0dbbf..b73c805f18108 100644 --- a/crypto/des/cfb64ede.c +++ b/crypto/des/cfb64ede.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/des/cfb64enc.c b/crypto/des/cfb64enc.c index b3abc12a2539a..c27400a979878 100644 --- a/crypto/des/cfb64enc.c +++ b/crypto/des/cfb64enc.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/des/des_local.h b/crypto/des/des_local.h index fa368c359c2c8..c175227e3f5cb 100644 --- a/crypto/des/des_local.h +++ b/crypto/des/des_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/des/fcrypt.c b/crypto/des/fcrypt.c index c01e1f960d3b0..09740de630600 100644 --- a/crypto/des/fcrypt.c +++ b/crypto/des/fcrypt.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/des/ofb64ede.c b/crypto/des/ofb64ede.c index 17236d219585a..c3bb7d7e1b36a 100644 --- a/crypto/des/ofb64ede.c +++ b/crypto/des/ofb64ede.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/des/ofb64enc.c b/crypto/des/ofb64enc.c index 1426407423f9a..84b99d9d8ff70 100644 --- a/crypto/des/ofb64enc.c +++ b/crypto/des/ofb64enc.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/des/spr.h b/crypto/des/spr.h index fe3e9d31e38ea..2274f95f35c19 100644 --- a/crypto/des/spr.h +++ b/crypto/des/spr.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c index 96256f9283487..8787945f8a1cd 100644 --- a/crypto/dh/dh_check.c +++ b/crypto/dh/dh_check.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c deleted file mode 100644 index 63c6d98a3b332..0000000000000 --- a/crypto/dh/dh_err.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/dherr.h" - -#ifndef OPENSSL_NO_DH - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA DH_str_reasons[] = { - { ERR_PACK(ERR_LIB_DH, 0, DH_R_BAD_FFC_PARAMETERS), "bad ffc parameters" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_BAD_GENERATOR), "bad generator" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_BN_DECODE_ERROR), "bn decode error" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_BN_ERROR), "bn error" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_INVALID_J_VALUE), - "check invalid j value" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_INVALID_Q_VALUE), - "check invalid q value" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_PUBKEY_INVALID), - "check pubkey invalid" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_PUBKEY_TOO_LARGE), - "check pubkey too large" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_PUBKEY_TOO_SMALL), - "check pubkey too small" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_P_NOT_PRIME), "check p not prime" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_P_NOT_SAFE_PRIME), - "check p not safe prime" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_CHECK_Q_NOT_PRIME), "check q not prime" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_DECODE_ERROR), "decode error" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_INVALID_PARAMETER_NAME), - "invalid parameter name" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_INVALID_PARAMETER_NID), - "invalid parameter nid" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_INVALID_PUBKEY), "invalid public key" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_INVALID_SECRET), "invalid secret" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_INVALID_SIZE), "invalid size" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_KDF_PARAMETER_ERROR), "kdf parameter error" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_KEYS_NOT_SET), "keys not set" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_MISSING_PUBKEY), "missing pubkey" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_MODULUS_TOO_LARGE), "modulus too large" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_MODULUS_TOO_SMALL), "modulus too small" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_NOT_SUITABLE_GENERATOR), - "not suitable generator" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_NO_PARAMETERS_SET), "no parameters set" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_NO_PRIVATE_VALUE), "no private value" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_PARAMETER_ENCODING_ERROR), - "parameter encoding error" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_PEER_KEY_ERROR), "peer key error" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_Q_TOO_LARGE), "q too large" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_SHARED_INFO_ERROR), "shared info error" }, - { ERR_PACK(ERR_LIB_DH, 0, DH_R_UNABLE_TO_CHECK_GENERATOR), - "unable to check generator" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_DH_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(DH_str_reasons[0].error) == NULL) - ERR_load_strings_const(DH_str_reasons); -#endif - return 1; -} -#else -NON_EMPTY_TRANSLATION_UNIT -#endif diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c index 3f45a8d8f018b..d996f3f81e17f 100644 --- a/crypto/dh/dh_key.c +++ b/crypto/dh/dh_key.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -207,6 +207,7 @@ static int dh_init(DH *dh) static int dh_finish(DH *dh) { BN_MONT_CTX_free(dh->method_mont_p); + dh->method_mont_p = NULL; return 1; } diff --git a/crypto/dh/dh_lib.c b/crypto/dh/dh_lib.c index 27ca94d1a6514..1934c71080759 100644 --- a/crypto/dh/dh_lib.c +++ b/crypto/dh/dh_lib.c @@ -142,7 +142,7 @@ int DH_up_ref(DH *r) { int i; - if (CRYPTO_UP_REF(&r->references, &i) <= 0) + if (!CRYPTO_UP_REF(&r->references, &i)) return 0; REF_PRINT_COUNT("DH", i, r); diff --git a/crypto/dh/dh_local.h b/crypto/dh/dh_local.h index ea6c378a9d95e..da5e549ca09b4 100644 --- a/crypto/dh/dh_local.h +++ b/crypto/dh/dh_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/dsa/dsa_err.c b/crypto/dsa/dsa_err.c deleted file mode 100644 index 12bc68ab56e19..0000000000000 --- a/crypto/dsa/dsa_err.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/dsaerr.h" - -#ifndef OPENSSL_NO_DSA - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA DSA_str_reasons[] = { - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BAD_FFC_PARAMETERS), "bad ffc parameters" }, - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BAD_Q_VALUE), "bad q value" }, - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BN_DECODE_ERROR), "bn decode error" }, - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_BN_ERROR), "bn error" }, - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_DECODE_ERROR), "decode error" }, - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_INVALID_DIGEST_TYPE), - "invalid digest type" }, - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_INVALID_PARAMETERS), "invalid parameters" }, - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MISSING_PARAMETERS), "missing parameters" }, - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MISSING_PRIVATE_KEY), - "missing private key" }, - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_MODULUS_TOO_LARGE), "modulus too large" }, - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_NO_PARAMETERS_SET), "no parameters set" }, - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_PARAMETER_ENCODING_ERROR), - "parameter encoding error" }, - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_P_NOT_PRIME), "p not prime" }, - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_Q_NOT_PRIME), "q not prime" }, - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_SEED_LEN_SMALL), - "seed_len is less than the length of q" }, - { ERR_PACK(ERR_LIB_DSA, 0, DSA_R_TOO_MANY_RETRIES), "too many retries" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_DSA_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(DSA_str_reasons[0].error) == NULL) - ERR_load_strings_const(DSA_str_reasons); -#endif - return 1; -} -#else -NON_EMPTY_TRANSLATION_UNIT -#endif diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c index a07f866a218a7..738915cc4f3d5 100644 --- a/crypto/dsa/dsa_key.c +++ b/crypto/dsa/dsa_key.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/dsa/dsa_lib.c b/crypto/dsa/dsa_lib.c index 834d271346e4c..5936b84098016 100644 --- a/crypto/dsa/dsa_lib.c +++ b/crypto/dsa/dsa_lib.c @@ -215,7 +215,7 @@ int DSA_up_ref(DSA *r) { int i; - if (CRYPTO_UP_REF(&r->references, &i) <= 0) + if (!CRYPTO_UP_REF(&r->references, &i)) return 0; REF_PRINT_COUNT("DSA", i, r); diff --git a/crypto/dsa/dsa_local.h b/crypto/dsa/dsa_local.h index 566bcb0def09a..56cc4360f5ff6 100644 --- a/crypto/dsa/dsa_local.h +++ b/crypto/dsa/dsa_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/dsa/dsa_ossl.c b/crypto/dsa/dsa_ossl.c index b6706cd52ab97..10655137df453 100644 --- a/crypto/dsa/dsa_ossl.c +++ b/crypto/dsa/dsa_ossl.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -468,6 +468,7 @@ static int dsa_init(DSA *dsa) static int dsa_finish(DSA *dsa) { BN_MONT_CTX_free(dsa->method_mont_p); + dsa->method_mont_p = NULL; return 1; } diff --git a/crypto/dso/dso_dl.c b/crypto/dso/dso_dl.c index ff51764deafe9..26f6ee8d22e95 100644 --- a/crypto/dso/dso_dl.c +++ b/crypto/dso/dso_dl.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,6 +7,8 @@ * https://www.openssl.org/source/license.html */ +#include + #include "dso_local.h" #ifdef DSO_DL @@ -228,13 +230,13 @@ static char *dl_name_converter(DSO *dso, const char *filename) return NULL; } if (transform) - BIO_snprintf(translated, rsize, + snprintf(translated, rsize, (DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0 ? "lib%s%s" : "%s%s", filename, DSO_EXTENSION); else - BIO_snprintf(translated, rsize, "%s", filename); + snprintf(translated, rsize, "%s", filename); return translated; } diff --git a/crypto/dso/dso_dlfcn.c b/crypto/dso/dso_dlfcn.c index 26493009743ed..3b8242ff2e94b 100644 --- a/crypto/dso/dso_dlfcn.c +++ b/crypto/dso/dso_dlfcn.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -16,6 +16,8 @@ #define _GNU_SOURCE /* make sure dladdr is declared */ #endif +#include + #include "dso_local.h" #include "internal/e_os.h" @@ -262,11 +264,11 @@ static char *dlfcn_name_converter(DSO *dso, const char *filename) } if (transform) { if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) - BIO_snprintf(translated, rsize, "lib%s" DSO_EXTENSION, filename); + snprintf(translated, rsize, "lib%s" DSO_EXTENSION, filename); else - BIO_snprintf(translated, rsize, "%s" DSO_EXTENSION, filename); + snprintf(translated, rsize, "%s" DSO_EXTENSION, filename); } else { - BIO_snprintf(translated, rsize, "%s", filename); + snprintf(translated, rsize, "%s", filename); } return translated; } diff --git a/crypto/dso/dso_err.c b/crypto/dso/dso_err.c deleted file mode 100644 index ec55b9a30a92c..0000000000000 --- a/crypto/dso/dso_err.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "internal/dsoerr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA DSO_str_reasons[] = { - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_CTRL_FAILED), "control command failed" }, - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_DSO_ALREADY_LOADED), "dso already loaded" }, - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_EMPTY_FILE_STRUCTURE), - "empty file structure" }, - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_FAILURE), "failure" }, - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_FILENAME_TOO_BIG), "filename too big" }, - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_FINISH_FAILED), - "cleanup method function failed" }, - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_INCORRECT_FILE_SYNTAX), - "incorrect file syntax" }, - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_LOAD_FAILED), - "could not load the shared library" }, - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_NAME_TRANSLATION_FAILED), - "name translation failed" }, - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_NO_FILENAME), "no filename" }, - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_NULL_HANDLE), - "a null shared library handle was used" }, - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_SET_FILENAME_FAILED), - "set filename failed" }, - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_STACK_ERROR), - "the meth_data stack is corrupt" }, - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_SYM_FAILURE), - "could not bind to the requested symbol name" }, - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_UNLOAD_FAILED), - "could not unload the shared library" }, - { ERR_PACK(ERR_LIB_DSO, 0, DSO_R_UNSUPPORTED), - "functionality not supported" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_DSO_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(DSO_str_reasons[0].error) == NULL) - ERR_load_strings_const(DSO_str_reasons); -#endif - return 1; -} diff --git a/crypto/dso/dso_lib.c b/crypto/dso/dso_lib.c index 6f51e4d35a0d1..a0fddd3c6b463 100644 --- a/crypto/dso/dso_lib.c +++ b/crypto/dso/dso_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -93,7 +93,7 @@ int DSO_up_ref(DSO *dso) return 0; } - if (CRYPTO_UP_REF(&dso->references, &i) <= 0) + if (!CRYPTO_UP_REF(&dso->references, &i)) return 0; REF_PRINT_COUNT("DSO", i, dso); diff --git a/crypto/dso/dso_local.h b/crypto/dso/dso_local.h index 8318e3ab0c242..1a80dccbae6a4 100644 --- a/crypto/dso/dso_local.h +++ b/crypto/dso/dso_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/dso/dso_win32.c b/crypto/dso/dso_win32.c index 6ac6727fda545..e785bb8abb977 100644 --- a/crypto/dso/dso_win32.c +++ b/crypto/dso/dso_win32.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,6 +7,8 @@ * https://www.openssl.org/source/license.html */ +#include + #include "internal/e_os.h" #include "dso_local.h" @@ -413,7 +415,7 @@ static char *win32_name_converter(DSO *dso, const char *filename) ERR_raise(ERR_LIB_DSO, DSO_R_NAME_TRANSLATION_FAILED); return NULL; } - BIO_snprintf(translated, len, "%s%s", filename, transform ? ".dll" : ""); + snprintf(translated, len, "%s%s", filename, transform ? ".dll" : ""); return translated; } diff --git a/crypto/ec/asm/ecp_nistz256-armv4.pl b/crypto/ec/asm/ecp_nistz256-armv4.pl index f00767e28badb..8b3e54fa0f1cb 100755 --- a/crypto/ec/asm/ecp_nistz256-armv4.pl +++ b/crypto/ec/asm/ecp_nistz256-armv4.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ec/asm/ecp_nistz256-armv8.pl b/crypto/ec/asm/ecp_nistz256-armv8.pl index 9ecabca7a7d30..04e035f772740 100644 --- a/crypto/ec/asm/ecp_nistz256-armv8.pl +++ b/crypto/ec/asm/ecp_nistz256-armv8.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ec/asm/ecp_nistz256-sparcv9.pl b/crypto/ec/asm/ecp_nistz256-sparcv9.pl index 0171420aaa069..bee6d539e95e7 100755 --- a/crypto/ec/asm/ecp_nistz256-sparcv9.pl +++ b/crypto/ec/asm/ecp_nistz256-sparcv9.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ec/asm/ecp_nistz256-x86_64.pl b/crypto/ec/asm/ecp_nistz256-x86_64.pl index f30811bc86602..f8a021ee03095 100755 --- a/crypto/ec/asm/ecp_nistz256-x86_64.pl +++ b/crypto/ec/asm/ecp_nistz256-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2014-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2014-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2014, Intel Corporation. All Rights Reserved. # Copyright (c) 2015 CloudFlare, Inc. # diff --git a/crypto/ec/asm/ecp_sm2p256-armv8.pl b/crypto/ec/asm/ecp_sm2p256-armv8.pl index 34def77c6e0ae..509e93a81588b 100644 --- a/crypto/ec/asm/ecp_sm2p256-armv8.pl +++ b/crypto/ec/asm/ecp_sm2p256-armv8.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ec/asm/ecp_sm2p256-riscv64.pl b/crypto/ec/asm/ecp_sm2p256-riscv64.pl index 2a17e124dc45b..011f7a5a251d7 100644 --- a/crypto/ec/asm/ecp_sm2p256-riscv64.pl +++ b/crypto/ec/asm/ecp_sm2p256-riscv64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -366,7 +366,7 @@ () .type .Lord_div_2,\@object .Lord_div_2: .dword 0xa9ddfa049ceaa092,0xb901efb590e30295,0xffffffffffffffff,0x7fffffff7fffffff - +.previous // void bn_rshift1(BN_ULONG *a); .globl bn_rshift1 diff --git a/crypto/ec/asm/x25519-x86_64.pl b/crypto/ec/asm/x25519-x86_64.pl index d2fdd76948c39..2842e34823a4d 100755 --- a/crypto/ec/asm/x25519-x86_64.pl +++ b/crypto/ec/asm/x25519-x86_64.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ec/curve25519.c b/crypto/ec/curve25519.c index 53c8bff5ed50b..d6ab92b8c1c9a 100644 --- a/crypto/ec/curve25519.c +++ b/crypto/ec/curve25519.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ec/curve448/arch_32/arch_intrinsics.inc b/crypto/ec/curve448/arch_32/arch_intrinsics.inc index 78f5afc69f2cb..dab7a017659bd 100644 --- a/crypto/ec/curve448/arch_32/arch_intrinsics.inc +++ b/crypto/ec/curve448/arch_32/arch_intrinsics.inc @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2016 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/ec/curve448/arch_64/arch_intrinsics.inc b/crypto/ec/curve448/arch_64/arch_intrinsics.inc index 5dc906a2416d3..6739ff36cb358 100644 --- a/crypto/ec/curve448/arch_64/arch_intrinsics.inc +++ b/crypto/ec/curve448/arch_64/arch_intrinsics.inc @@ -1,5 +1,5 @@ /* - * Copyright 2017-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2016 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/ec/curve448/curve448.c b/crypto/ec/curve448/curve448.c index 29edb317f13e4..e7255ef22bb48 100644 --- a/crypto/ec/curve448/curve448.c +++ b/crypto/ec/curve448/curve448.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015-2016 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/ec/curve448/ed448.h b/crypto/ec/curve448/ed448.h index bb045fce87190..b6f68e608d99b 100644 --- a/crypto/ec/curve448/ed448.h +++ b/crypto/ec/curve448/ed448.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015-2016 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/ec/curve448/field.h b/crypto/ec/curve448/field.h index 850244ee55def..9c3b8a3f166d2 100644 --- a/crypto/ec/curve448/field.h +++ b/crypto/ec/curve448/field.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2014 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/ec/curve448/scalar.c b/crypto/ec/curve448/scalar.c index 2308de6f635c0..cad2a4c465b15 100644 --- a/crypto/ec/curve448/scalar.c +++ b/crypto/ec/curve448/scalar.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2015-2016 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/ec/curve448/word.h b/crypto/ec/curve448/word.h index 65ff1be12b641..e795b57ac2142 100644 --- a/crypto/ec/curve448/word.h +++ b/crypto/ec/curve448/word.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2014 Cryptography Research, Inc. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/ec/ec2_smpl.c b/crypto/ec/ec2_smpl.c index d8301ac6b7494..34a2d5a7411cf 100644 --- a/crypto/ec/ec2_smpl.c +++ b/crypto/ec/ec2_smpl.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c index a274f720f3e54..e32055a06cab1 100644 --- a/crypto/ec/ec_ameth.c +++ b/crypto/ec/ec_ameth.c @@ -21,6 +21,7 @@ #include #include "crypto/asn1.h" #include "crypto/evp.h" +#include "crypto/ec_params.h" #include "crypto/x509.h" #include #include @@ -598,15 +599,20 @@ static int ec_pkey_import_from(const OSSL_PARAM params[], void *vpctx) EVP_PKEY_CTX *pctx = vpctx; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); EC_KEY *ec = EC_KEY_new_ex(pctx->libctx, pctx->propquery); + EC_PARAMS p; if (ec == NULL) { ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); return 0; } + if (!ec_pkey_import_from_decoder(params, &p)) { + EC_KEY_free(ec); + return 0; + } - if (!ossl_ec_group_fromdata(ec, params) - || !ossl_ec_key_otherparams_fromdata(ec, params) - || !ossl_ec_key_fromdata(ec, params, 1) + if (!ossl_ec_group_fromdata_parsed(ec, &p) + || !ossl_ec_key_otherparams_fromdata_parsed(ec, &p) + || !ossl_ec_key_fromdata_parsed(ec, &p, 1) || !EVP_PKEY_assign_EC_KEY(pkey, ec)) { EC_KEY_free(ec); return 0; diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c index fdc3ce94c790e..ab9ab45ed8fa3 100644 --- a/crypto/ec/ec_asn1.c +++ b/crypto/ec/ec_asn1.c @@ -966,9 +966,10 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) if (priv_key->privateKey) { ASN1_OCTET_STRING *pkey = priv_key->privateKey; - if (EC_KEY_oct2priv(ret, ASN1_STRING_get0_data(pkey), - ASN1_STRING_length(pkey)) - == 0) + size_t pkey_len = ASN1_STRING_get_length(pkey); + if (pkey_len > INT_MAX) + goto err; + if (EC_KEY_oct2priv(ret, ASN1_STRING_get0_data(pkey), (int)pkey_len) == 0) goto err; } else { ERR_raise(ERR_LIB_EC, EC_R_MISSING_PRIVATE_KEY); @@ -987,11 +988,13 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) if (priv_key->publicKey) { const unsigned char *pub_oct; - int pub_oct_len; + size_t pub_oct_len; pub_oct = ASN1_STRING_get0_data(priv_key->publicKey); - pub_oct_len = ASN1_STRING_length(priv_key->publicKey); - if (!EC_KEY_oct2key(ret, pub_oct, pub_oct_len, NULL)) { + pub_oct_len = ASN1_STRING_get_length(priv_key->publicKey); + if (pub_oct_len > INT_MAX) + goto err; + if (!EC_KEY_oct2key(ret, pub_oct, (int)pub_oct_len, NULL)) { ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB); goto err; } diff --git a/crypto/ec/ec_backend.c b/crypto/ec/ec_backend.c index 764ab7558bfc4..4c6302c5b516a 100644 --- a/crypto/ec/ec_backend.c +++ b/crypto/ec/ec_backend.c @@ -22,6 +22,7 @@ #endif #include "crypto/bn.h" #include "crypto/ec.h" +#include "crypto/ec_params.h" #include "ec_local.h" #include "internal/e_os.h" #include "internal/nelem.h" @@ -156,15 +157,15 @@ char *ossl_ec_pt_format_id2name(int id) } static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, - OSSL_PARAM params[], BN_CTX *bnctx, + const EC_PARAMS *params, BN_CTX *bnctx, unsigned char **genbuf) { int ret = 0, fid; const char *field_type; - const OSSL_PARAM *param = NULL; - const OSSL_PARAM *param_p = NULL; - const OSSL_PARAM *param_a = NULL; - const OSSL_PARAM *param_b = NULL; + OSSL_PARAM *param = NULL; + OSSL_PARAM *param_p = NULL; + OSSL_PARAM *param_a = NULL; + OSSL_PARAM *param_b = NULL; fid = EC_GROUP_get_field_type(group); @@ -182,9 +183,11 @@ static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, return 0; } - param_p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_P); - param_a = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_A); - param_b = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_B); + if (params != NULL) { + param_p = params->p; + param_a = params->a; + param_b = params->b; + } if (tmpl != NULL || param_p != NULL || param_a != NULL || param_b != NULL) { BIGNUM *p = BN_CTX_get(bnctx); BIGNUM *a = BN_CTX_get(bnctx); @@ -199,15 +202,17 @@ static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE); goto err; } - if (!ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_P, p) - || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_A, a) - || !ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_B, b)) { + if (!ossl_param_build_set_bn(tmpl, param_p, OSSL_PKEY_PARAM_EC_P, p) + || !ossl_param_build_set_bn(tmpl, param_a, + OSSL_PKEY_PARAM_EC_A, a) + || !ossl_param_build_set_bn(tmpl, param_b, + OSSL_PKEY_PARAM_EC_B, b)) { ERR_raise(ERR_LIB_EC, ERR_R_CRYPTO_LIB); goto err; } } - param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ORDER); + param = params == NULL ? NULL : params->order; if (tmpl != NULL || param != NULL) { const BIGNUM *order = EC_GROUP_get0_order(group); @@ -215,16 +220,16 @@ static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, ERR_raise(ERR_LIB_EC, EC_R_INVALID_GROUP_ORDER); goto err; } - if (!ossl_param_build_set_bn(tmpl, params, OSSL_PKEY_PARAM_EC_ORDER, + if (!ossl_param_build_set_bn(tmpl, param, OSSL_PKEY_PARAM_EC_ORDER, order)) { ERR_raise(ERR_LIB_EC, ERR_R_CRYPTO_LIB); goto err; } } - param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE); + param = params == NULL ? NULL : params->field_type; if (tmpl != NULL || param != NULL) { - if (!ossl_param_build_set_utf8_string(tmpl, params, + if (!ossl_param_build_set_utf8_string(tmpl, param, OSSL_PKEY_PARAM_EC_FIELD_TYPE, field_type)) { ERR_raise(ERR_LIB_EC, ERR_R_CRYPTO_LIB); @@ -232,7 +237,7 @@ static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, } } - param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_GENERATOR); + param = params == NULL ? NULL : params->generator; if (tmpl != NULL || param != NULL) { size_t genbuf_len; const EC_POINT *genpt = EC_GROUP_get0_generator(group); @@ -247,7 +252,7 @@ static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, ERR_raise(ERR_LIB_EC, EC_R_INVALID_GENERATOR); goto err; } - if (!ossl_param_build_set_octet_string(tmpl, params, + if (!ossl_param_build_set_octet_string(tmpl, param, OSSL_PKEY_PARAM_EC_GENERATOR, *genbuf, genbuf_len)) { ERR_raise(ERR_LIB_EC, ERR_R_CRYPTO_LIB); @@ -255,26 +260,26 @@ static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, } } - param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_COFACTOR); + param = params == NULL ? NULL : params->cofactor; if (tmpl != NULL || param != NULL) { const BIGNUM *cofactor = EC_GROUP_get0_cofactor(group); if (cofactor != NULL - && !ossl_param_build_set_bn(tmpl, params, + && !ossl_param_build_set_bn(tmpl, param, OSSL_PKEY_PARAM_EC_COFACTOR, cofactor)) { ERR_raise(ERR_LIB_EC, ERR_R_CRYPTO_LIB); goto err; } } - param = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_SEED); + param = params == NULL ? NULL : params->seed; if (tmpl != NULL || param != NULL) { unsigned char *seed = EC_GROUP_get0_seed(group); size_t seed_len = EC_GROUP_get_seed_len(group); if (seed != NULL && seed_len > 0 - && !ossl_param_build_set_octet_string(tmpl, params, + && !ossl_param_build_set_octet_string(tmpl, param, OSSL_PKEY_PARAM_EC_SEED, seed, seed_len)) { ERR_raise(ERR_LIB_EC, ERR_R_CRYPTO_LIB); @@ -286,8 +291,8 @@ static int ec_group_explicit_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, return ret; } -int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, - OSSL_PARAM params[], OSSL_LIB_CTX *libctx, +int ossl_ec_group_todata_parsed(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, + const EC_PARAMS *params, OSSL_LIB_CTX *libctx, const char *propq, BN_CTX *bnctx, unsigned char **genbuf) { @@ -304,7 +309,7 @@ int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, pt_form_name = ossl_ec_pt_format_id2name(genform); if (pt_form_name == NULL || !ossl_param_build_set_utf8_string( - tmpl, params, + tmpl, params == NULL ? NULL : params->pt_format, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, pt_form_name)) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_FORM); return 0; @@ -312,14 +317,16 @@ int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, encoding_flag = EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE; encoding_name = ec_param_encoding_id2name(encoding_flag); if (encoding_name == NULL - || !ossl_param_build_set_utf8_string(tmpl, params, + || !ossl_param_build_set_utf8_string(tmpl, + params == NULL ? NULL : params->encoding, OSSL_PKEY_PARAM_EC_ENCODING, encoding_name)) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); return 0; } - if (!ossl_param_build_set_int(tmpl, params, + if (!ossl_param_build_set_int(tmpl, + params == NULL ? NULL : params->decoded, OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, group->decoded_from_explicit_params)) return 0; @@ -340,7 +347,8 @@ int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, const char *curve_name = OSSL_EC_curve_nid2name(curve_nid); if (curve_name == NULL - || !ossl_param_build_set_utf8_string(tmpl, params, + || !ossl_param_build_set_utf8_string(tmpl, + params == NULL ? NULL : params->group_name, OSSL_PKEY_PARAM_GROUP_NAME, curve_name)) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_CURVE); @@ -352,6 +360,23 @@ int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, return ret; } +int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, + OSSL_PARAM params[], OSSL_LIB_CTX *libctx, + const char *propq, + BN_CTX *bnctx, unsigned char **genbuf) +{ + EC_PARAMS p; + + if (params != NULL) { + if (!ec_group_todata_decoder(params, &p)) + return 0; + return ossl_ec_group_todata_parsed(group, tmpl, &p, libctx, propq, + bnctx, genbuf); + } + return ossl_ec_group_todata_parsed(group, tmpl, NULL, libctx, propq, + bnctx, genbuf); +} + /* * The intention with the "backend" source file is to offer backend functions * for legacy backends (EVP_PKEY_ASN1_METHOD) and provider implementations @@ -394,7 +419,8 @@ int ossl_ec_set_ecdh_cofactor_mode(EC_KEY *ec, int mode) * parameters are treated separately, and domain parameters are required to * define a keypair. */ -int ossl_ec_key_fromdata(EC_KEY *ec, const OSSL_PARAM params[], int include_private) +int ossl_ec_key_fromdata_parsed(EC_KEY *ec, const EC_PARAMS *params, + int include_private) { const OSSL_PARAM *param_priv_key = NULL, *param_pub_key = NULL; BN_CTX *ctx = NULL; @@ -409,9 +435,12 @@ int ossl_ec_key_fromdata(EC_KEY *ec, const OSSL_PARAM params[], int include_priv if (ecg == NULL) return 0; - param_pub_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY); + if (params == NULL) + return 0; + + param_pub_key = params->pub; if (include_private) - param_priv_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY); + param_priv_key = params->priv; ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(ec)); if (ctx == NULL) @@ -504,7 +533,17 @@ int ossl_ec_key_fromdata(EC_KEY *ec, const OSSL_PARAM params[], int include_priv return ok; } -int ossl_ec_group_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) +int ossl_ec_key_fromdata(EC_KEY *ec, const OSSL_PARAM params[], + int include_private) +{ + EC_PARAMS p; + + if (!ec_key_fromdata_decoder(params, &p)) + return 0; + return ossl_ec_key_fromdata_parsed(ec, &p, include_private); +} + +int ossl_ec_group_fromdata_parsed(EC_KEY *ec, const EC_PARAMS *params) { int ok = 0; EC_GROUP *group = NULL; @@ -512,7 +551,8 @@ int ossl_ec_group_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) if (ec == NULL) return 0; - group = EC_GROUP_new_from_params(params, ossl_ec_key_get_libctx(ec), + group = ossl_ec_group_new_from_params_parsed(params, + ossl_ec_key_get_libctx(ec), ossl_ec_key_get0_propq(ec)); if (!EC_KEY_set_group(ec, group)) @@ -523,14 +563,21 @@ int ossl_ec_group_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) return ok; } -static int ec_key_point_format_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) +int ossl_ec_group_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) +{ + EC_PARAMS p; + + if (!ec_group_fromdata_decoder(params, &p)) + return 0; + return ossl_ec_group_fromdata_parsed(ec, &p); +} + +static int ec_key_point_format_fromdata(EC_KEY *ec, const EC_PARAMS *params) { - const OSSL_PARAM *p; int format = -1; - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT); - if (p != NULL) { - if (!ossl_ec_pt_format_param2id(p, &format)) { + if (params->pt_format != NULL) { + if (!ossl_ec_pt_format_param2id(params->pt_format, &format)) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_FORM); return 0; } @@ -539,13 +586,10 @@ static int ec_key_point_format_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) return 1; } -static int ec_key_group_check_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) +static int ec_key_group_check_fromdata(EC_KEY *ec, const EC_PARAMS *params) { - const OSSL_PARAM *p; - - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE); - if (p != NULL) - return ec_set_check_group_type_from_param(ec, p); + if (params->group_check != NULL) + return ec_set_check_group_type_from_param(ec, params->group_check); return 1; } @@ -561,27 +605,24 @@ static int ec_set_include_public(EC_KEY *ec, int include) return 1; } -int ossl_ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) +int ossl_ec_key_otherparams_fromdata_parsed(EC_KEY *ec, + const EC_PARAMS *params) { - const OSSL_PARAM *p; - - if (ec == NULL) + if (ec == NULL || params == NULL) return 0; - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH); - if (p != NULL) { + if (params->use_cofactor != NULL) { int mode; - if (!OSSL_PARAM_get_int(p, &mode) + if (!OSSL_PARAM_get_int(params->use_cofactor, &mode) || !ossl_ec_set_ecdh_cofactor_mode(ec, mode)) return 0; } - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC); - if (p != NULL) { + if (params->include_public != NULL) { int include = 1; - if (!OSSL_PARAM_get_int(p, &include) + if (!OSSL_PARAM_get_int(params->include_public, &include) || !ec_set_include_public(ec, include)) return 0; } @@ -592,6 +633,15 @@ int ossl_ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) return 1; } +int ossl_ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]) +{ + EC_PARAMS p; + + if (!ec_key_otherparams_fromdata_decoder(params, &p)) + return 0; + return ossl_ec_key_otherparams_fromdata_parsed(ec, &p); +} + int ossl_ec_key_is_foreign(const EC_KEY *ec) { #ifndef FIPS_MODULE diff --git a/crypto/ec/ec_curve.c b/crypto/ec/ec_curve.c index 0fa1e7a6a65b8..e63d89bae7375 100644 --- a/crypto/ec/ec_curve.c +++ b/crypto/ec/ec_curve.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c deleted file mode 100644 index 4e3152d0df6b0..0000000000000 --- a/crypto/ec/ec_err.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/ecerr.h" - -#ifndef OPENSSL_NO_EC - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA EC_str_reasons[] = { - { ERR_PACK(ERR_LIB_EC, 0, EC_R_ASN1_ERROR), "asn1 error" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_BAD_SIGNATURE), "bad signature" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_BUFFER_TOO_SMALL), "buffer too small" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_CANNOT_INVERT), "cannot invert" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_COORDINATES_OUT_OF_RANGE), - "coordinates out of range" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_ECDH), - "curve does not support ecdh" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA), - "curve does not support ecdsa" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING), - "curve does not support signing" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_DECODE_ERROR), "decode error" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_DISCRIMINANT_IS_ZERO), - "discriminant is zero" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE), - "ec group new by name failure" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED), - "explicit params not supported" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_FAILED_MAKING_PUBLIC_KEY), - "failed making public key" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_FIELD_TOO_LARGE), "field too large" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_GROUP2PKPARAMETERS_FAILURE), - "group2pkparameters failure" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_I2D_ECPKPARAMETERS_FAILURE), - "i2d ecpkparameters failure" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INCOMPATIBLE_OBJECTS), - "incompatible objects" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_A), "invalid a" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_ARGUMENT), "invalid argument" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_B), "invalid b" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COFACTOR), "invalid cofactor" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COMPRESSED_POINT), - "invalid compressed point" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_COMPRESSION_BIT), - "invalid compression bit" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_CURVE), "invalid curve" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_DIGEST), "invalid digest" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_DIGEST_TYPE), "invalid digest type" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_ENCODING), "invalid encoding" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_FIELD), "invalid field" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_FORM), "invalid form" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_GENERATOR), "invalid generator" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_GROUP_ORDER), "invalid group order" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_KEY), "invalid key" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_LENGTH), "invalid length" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_NAMED_GROUP_CONVERSION), - "invalid named group conversion" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_OUTPUT_LENGTH), - "invalid output length" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_P), "invalid p" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PEER_KEY), "invalid peer key" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PENTANOMIAL_BASIS), - "invalid pentanomial basis" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_PRIVATE_KEY), "invalid private key" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_SEED), "invalid seed" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_INVALID_TRINOMIAL_BASIS), - "invalid trinomial basis" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_KDF_PARAMETER_ERROR), "kdf parameter error" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_KEYS_NOT_SET), "keys not set" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_LADDER_POST_FAILURE), "ladder post failure" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_LADDER_PRE_FAILURE), "ladder pre failure" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_LADDER_STEP_FAILURE), "ladder step failure" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_MISSING_OID), "missing OID" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_MISSING_PARAMETERS), "missing parameters" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_MISSING_PRIVATE_KEY), "missing private key" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_NEED_NEW_SETUP_VALUES), - "need new setup values" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_NOT_A_NIST_PRIME), "not a NIST prime" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_NOT_IMPLEMENTED), "not implemented" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_NOT_INITIALIZED), "not initialized" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_NO_PARAMETERS_SET), "no parameters set" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_NO_PRIVATE_VALUE), "no private value" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_OPERATION_NOT_SUPPORTED), - "operation not supported" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_PASSED_NULL_PARAMETER), - "passed null parameter" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_PEER_KEY_ERROR), "peer key error" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_ARITHMETIC_FAILURE), - "point arithmetic failure" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_AT_INFINITY), "point at infinity" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_COORDINATES_BLIND_FAILURE), - "point coordinates blind failure" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_POINT_IS_NOT_ON_CURVE), - "point is not on curve" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_RANDOM_NUMBER_GENERATION_FAILED), - "random number generation failed" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_SHARED_INFO_ERROR), "shared info error" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_SLOT_FULL), "slot full" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_TOO_MANY_RETRIES), "too many retries" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_UNDEFINED_GENERATOR), "undefined generator" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_UNDEFINED_ORDER), "undefined order" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_UNKNOWN_COFACTOR), "unknown cofactor" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_UNKNOWN_GROUP), "unknown group" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_UNKNOWN_ORDER), "unknown order" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_UNSUPPORTED_FIELD), "unsupported field" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_WRONG_CURVE_PARAMETERS), - "wrong curve parameters" }, - { ERR_PACK(ERR_LIB_EC, 0, EC_R_WRONG_ORDER), "wrong order" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_EC_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(EC_str_reasons[0].error) == NULL) - ERR_load_strings_const(EC_str_reasons); -#endif - return 1; -} -#else -NON_EMPTY_TRANSLATION_UNIT -#endif diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index 44791a2c3eddb..d8640a4bca1db 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -175,7 +175,7 @@ int EC_KEY_up_ref(EC_KEY *r) { int i; - if (CRYPTO_UP_REF(&r->references, &i) <= 0) + if (!CRYPTO_UP_REF(&r->references, &i)) return 0; REF_PRINT_COUNT("EC_KEY", i, r); diff --git a/crypto/ec/ec_kmeth.c b/crypto/ec/ec_kmeth.c index b27a40519d131..cf3e0be2e6642 100644 --- a/crypto/ec/ec_kmeth.c +++ b/crypto/ec/ec_kmeth.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c index 51f0457f65a4f..6df9774ed907d 100644 --- a/crypto/ec/ec_lib.c +++ b/crypto/ec/ec_lib.c @@ -21,6 +21,7 @@ #include #include #include "crypto/ec.h" +#include "crypto/ec_params.h" #include "crypto/bn.h" #include "internal/nelem.h" #include "ec_local.h" @@ -1548,34 +1549,34 @@ static EC_GROUP *group_new_from_name(const OSSL_PARAM *p, } /* These parameters can be set directly into an EC_GROUP */ -int ossl_ec_group_set_params(EC_GROUP *group, const OSSL_PARAM params[]) +int ossl_ec_group_set_params_parsed(EC_GROUP *group, const EC_PARAMS *params) { int encoding_flag = -1, format = -1; - const OSSL_PARAM *p; - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT); - if (p != NULL) { - if (!ossl_ec_pt_format_param2id(p, &format)) { + if (params == NULL) + return 0; + + if (params->pt_format != NULL) { + if (!ossl_ec_pt_format_param2id(params->pt_format, &format)) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_FORM); return 0; } EC_GROUP_set_point_conversion_form(group, format); } - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING); - if (p != NULL) { - if (!ossl_ec_encoding_param2id(p, &encoding_flag)) { + if (params->encoding != NULL) { + if (!ossl_ec_encoding_param2id(params->encoding, &encoding_flag)) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_FORM); return 0; } EC_GROUP_set_asn1_flag(group, encoding_flag); } /* Optional seed */ - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_SEED); - if (p != NULL) { + if (params->seed != NULL) { /* The seed is allowed to be NULL */ - if (p->data_type != OSSL_PARAM_OCTET_STRING - || !EC_GROUP_set_seed(group, p->data, p->data_size)) { + if (params->seed->data_type != OSSL_PARAM_OCTET_STRING + || !EC_GROUP_set_seed(group, params->seed->data, + params->seed->data_size)) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_SEED); return 0; } @@ -1583,7 +1584,16 @@ int ossl_ec_group_set_params(EC_GROUP *group, const OSSL_PARAM params[]) return 1; } -EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], +int ossl_ec_group_set_params(EC_GROUP *group, const OSSL_PARAM params[]) +{ + EC_PARAMS p; + + if (!ec_group_fromdata_decoder(params, &p)) + return 0; + return ossl_ec_group_set_params_parsed(group, &p); +} + +EC_GROUP *ossl_ec_group_new_from_params_parsed(const EC_PARAMS *params, OSSL_LIB_CTX *libctx, const char *propq) { const OSSL_PARAM *ptmp; @@ -1605,19 +1615,21 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], #endif /* This is the simple named group case */ - ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME); + if (params == NULL) + return NULL; + + ptmp = params->group_name; if (ptmp != NULL) { int decoded = 0; if ((group = group_new_from_name(ptmp, libctx, propq)) == NULL) return NULL; - if (!ossl_ec_group_set_params(group, params)) { + if (!ossl_ec_group_set_params_parsed(group, params)) { EC_GROUP_free(group); return NULL; } - ptmp = OSSL_PARAM_locate_const(params, - OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS); + ptmp = params->decoded; if (ptmp != NULL && !OSSL_PARAM_get_int(ptmp, &decoded)) { ERR_raise(ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS); EC_GROUP_free(group); @@ -1647,7 +1659,7 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], goto err; } - ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE); + ptmp = params->field_type; if (ptmp == NULL || ptmp->data_type != OSSL_PARAM_UTF8_STRING) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD); goto err; @@ -1664,19 +1676,19 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], goto err; } - pa = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_A); + pa = params->a; if (!OSSL_PARAM_get_BN(pa, &a)) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_A); goto err; } - pb = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_B); + pb = params->b; if (!OSSL_PARAM_get_BN(pb, &b)) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_B); goto err; } /* extract the prime number or irreducible polynomial */ - ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_P); + ptmp = params->p; if (!OSSL_PARAM_get_BN(ptmp, &p)) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_P); goto err; @@ -1718,7 +1730,7 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], } /* Optional seed */ - ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_SEED); + ptmp = params->seed; if (ptmp != NULL) { if (ptmp->data_type != OSSL_PARAM_OCTET_STRING) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_SEED); @@ -1729,7 +1741,7 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], } /* generator base point */ - ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_GENERATOR); + ptmp = params->generator; if (ptmp == NULL || ptmp->data_type != OSSL_PARAM_OCTET_STRING || ptmp->data_size == 0) { @@ -1747,7 +1759,7 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], } /* order */ - ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ORDER); + ptmp = params->order; if (!OSSL_PARAM_get_BN(ptmp, &order) || (BN_is_negative(order) || BN_is_zero(order)) || (BN_num_bits(order) > (int)field_bits + 1)) { /* Hasse bound */ @@ -1756,7 +1768,7 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], } /* Optional cofactor */ - ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_COFACTOR); + ptmp = params->cofactor; if (ptmp != NULL) { cofactor = BN_CTX_get(bnctx); if (cofactor == NULL || !OSSL_PARAM_get_BN(ptmp, &cofactor)) { @@ -1787,7 +1799,7 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], * If we did not find a named group then the encoding should be explicit * if it was specified */ - ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_EC_ENCODING); + ptmp = params->encoding; if (ptmp != NULL && !ossl_ec_encoding_param2id(ptmp, &encoding_flag)) { ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); @@ -1803,6 +1815,8 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], EC_GROUP_free(group); group = named_group; } + if (!ossl_ec_group_set_params_parsed(group, params)) + goto err; /* We've imported the group from explicit parameters, set it so. */ group->decoded_from_explicit_params = 1; ok = 1; @@ -1819,6 +1833,16 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], #endif /* FIPS_MODULE */ } +EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[], + OSSL_LIB_CTX *libctx, const char *propq) +{ + EC_PARAMS p; + + if (!ec_group_fromdata_decoder(params, &p)) + return NULL; + return ossl_ec_group_new_from_params_parsed(&p, libctx, propq); +} + OSSL_PARAM *EC_GROUP_to_params(const EC_GROUP *group, OSSL_LIB_CTX *libctx, const char *propq, BN_CTX *bnctx) { diff --git a/crypto/ec/ec_local.h b/crypto/ec/ec_local.h index 0be3c5529eabf..8ddda4516b39e 100644 --- a/crypto/ec/ec_local.h +++ b/crypto/ec/ec_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/ec/ec_mult.c b/crypto/ec/ec_mult.c index 4771789151bf5..f728a2f958c87 100644 --- a/crypto/ec/ec_mult.c +++ b/crypto/ec/ec_mult.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -72,8 +72,8 @@ static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group) EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_COMP *pre) { int i; - if (pre != NULL) - CRYPTO_UP_REF(&pre->references, &i); + if (pre == NULL || !CRYPTO_UP_REF(&pre->references, &i)) + return NULL; return pre; } diff --git a/crypto/ec/ecp_mont.c b/crypto/ec/ecp_mont.c index 5c289c10bee88..175aa81ae54d5 100644 --- a/crypto/ec/ecp_mont.c +++ b/crypto/ec/ecp_mont.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/ec/ecp_nistp224.c b/crypto/ec/ecp_nistp224.c index 7183131622f4f..e39dabe16bb6d 100644 --- a/crypto/ec/ecp_nistp224.c +++ b/crypto/ec/ecp_nistp224.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2010-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -1234,8 +1234,8 @@ static NISTP224_PRE_COMP *nistp224_pre_comp_new(void) NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *p) { int i; - if (p != NULL) - CRYPTO_UP_REF(&p->references, &i); + if (p == NULL || !CRYPTO_UP_REF(&p->references, &i)) + return NULL; return p; } diff --git a/crypto/ec/ecp_nistp256.c b/crypto/ec/ecp_nistp256.c index e247e51c9c78e..ae5c8389c6cfc 100644 --- a/crypto/ec/ecp_nistp256.c +++ b/crypto/ec/ecp_nistp256.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -1852,8 +1852,8 @@ static NISTP256_PRE_COMP *nistp256_pre_comp_new(void) NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *p) { int i; - if (p != NULL) - CRYPTO_UP_REF(&p->references, &i); + if (p == NULL || !CRYPTO_UP_REF(&p->references, &i)) + return NULL; return p; } diff --git a/crypto/ec/ecp_nistp384.c b/crypto/ec/ecp_nistp384.c index e03bda21787ef..711399326098b 100644 --- a/crypto/ec/ecp_nistp384.c +++ b/crypto/ec/ecp_nistp384.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -1576,8 +1576,8 @@ NISTP384_PRE_COMP *ossl_ec_nistp384_pre_comp_dup(NISTP384_PRE_COMP *p) { int i; - if (p != NULL) - CRYPTO_UP_REF(&p->references, &i); + if (p == NULL || !CRYPTO_UP_REF(&p->references, &i)) + return NULL; return p; } diff --git a/crypto/ec/ecp_nistp521.c b/crypto/ec/ecp_nistp521.c index 7ea8d00c14414..c624295e90aa3 100644 --- a/crypto/ec/ecp_nistp521.c +++ b/crypto/ec/ecp_nistp521.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -1667,8 +1667,8 @@ static NISTP521_PRE_COMP *nistp521_pre_comp_new(void) NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *p) { int i; - if (p != NULL) - CRYPTO_UP_REF(&p->references, &i); + if (p == NULL || !CRYPTO_UP_REF(&p->references, &i)) + return NULL; return p; } diff --git a/crypto/ec/ecp_nistz256.c b/crypto/ec/ecp_nistz256.c index 301f90188a5aa..86ef80183fea6 100644 --- a/crypto/ec/ecp_nistz256.c +++ b/crypto/ec/ecp_nistz256.c @@ -1,5 +1,5 @@ /* - * Copyright 2014-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2014, Intel Corporation. All Rights Reserved. * Copyright (c) 2015, CloudFlare, Inc. * @@ -1208,8 +1208,8 @@ static NISTZ256_PRE_COMP *ecp_nistz256_pre_comp_new(const EC_GROUP *group) NISTZ256_PRE_COMP *EC_nistz256_pre_comp_dup(NISTZ256_PRE_COMP *p) { int i; - if (p != NULL) - CRYPTO_UP_REF(&p->references, &i); + if (p == NULL || !CRYPTO_UP_REF(&p->references, &i)) + return NULL; return p; } diff --git a/crypto/ec/ecp_ppc.c b/crypto/ec/ecp_ppc.c index 5fd27654fde68..e4b6f2e6bd083 100644 --- a/crypto/ec/ecp_ppc.c +++ b/crypto/ec/ecp_ppc.c @@ -1,5 +1,5 @@ /* - * Copyright 2009-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2009-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ec/ecp_sm2p256.c b/crypto/ec/ecp_sm2p256.c index 6a9e8c66d5737..86fe8183f3e50 100644 --- a/crypto/ec/ecp_sm2p256.c +++ b/crypto/ec/ecp_sm2p256.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ec/ecp_smpl.c b/crypto/ec/ecp_smpl.c index 7570693015828..33c6fcb0ee913 100644 --- a/crypto/ec/ecp_smpl.c +++ b/crypto/ec/ecp_smpl.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/ec/ecx_backend.c b/crypto/ec/ecx_backend.c index 710ad31a66788..371361a92dd92 100644 --- a/crypto/ec/ecx_backend.c +++ b/crypto/ec/ecx_backend.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -230,15 +230,19 @@ ECX_KEY *ossl_ecx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, const X509_ALGOR *palg; if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8inf)) - return 0; + goto err; oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen); if (oct == NULL) { p = NULL; plen = 0; } else { + size_t tmp; p = ASN1_STRING_get0_data(oct); - plen = ASN1_STRING_length(oct); + tmp = ASN1_STRING_get_length(oct); + if (tmp > INT_MAX) + goto err; + plen = (int)tmp; } /* @@ -247,6 +251,7 @@ ECX_KEY *ossl_ecx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, */ ecx = ossl_ecx_key_op(palg, p, plen, EVP_PKEY_NONE, KEY_OP_PRIVATE, libctx, propq); +err: ASN1_OCTET_STRING_free(oct); return ecx; } diff --git a/crypto/ec/ecx_backend.h b/crypto/ec/ecx_backend.h index c549178d9c606..9b25ff05931f9 100644 --- a/crypto/ec/ecx_backend.h +++ b/crypto/ec/ecx_backend.h @@ -1,5 +1,5 @@ /* - * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ec/ecx_key.c b/crypto/ec/ecx_key.c index 4d8c9457554ce..7f84375344b1c 100644 --- a/crypto/ec/ecx_key.c +++ b/crypto/ec/ecx_key.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -92,7 +92,7 @@ int ossl_ecx_key_up_ref(ECX_KEY *key) { int i; - if (CRYPTO_UP_REF(&key->references, &i) <= 0) + if (!CRYPTO_UP_REF(&key->references, &i)) return 0; REF_PRINT_COUNT("ECX_KEY", i, key); diff --git a/crypto/ec/ecx_s390x.c b/crypto/ec/ecx_s390x.c index 5f0cad0fe3ca0..7a6a25b6d5a1b 100644 --- a/crypto/ec/ecx_s390x.c +++ b/crypto/ec/ecx_s390x.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/encode_decode/decoder_err.c b/crypto/encode_decode/decoder_err.c deleted file mode 100644 index 9e6556a1467d3..0000000000000 --- a/crypto/encode_decode/decoder_err.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/decodererr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA OSSL_DECODER_str_reasons[] = { - { ERR_PACK(ERR_LIB_OSSL_DECODER, 0, OSSL_DECODER_R_COULD_NOT_DECODE_OBJECT), - "could not decode object" }, - { ERR_PACK(ERR_LIB_OSSL_DECODER, 0, OSSL_DECODER_R_DECODER_NOT_FOUND), - "decoder not found" }, - { ERR_PACK(ERR_LIB_OSSL_DECODER, 0, OSSL_DECODER_R_MISSING_GET_PARAMS), - "missing get params" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_OSSL_DECODER_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(OSSL_DECODER_str_reasons[0].error) == NULL) - ERR_load_strings_const(OSSL_DECODER_str_reasons); -#endif - return 1; -} diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c index 7be00d21a14ec..3711f2653b746 100644 --- a/crypto/encode_decode/decoder_lib.c +++ b/crypto/encode_decode/decoder_lib.c @@ -231,6 +231,7 @@ OSSL_DECODER_INSTANCE * ossl_decoder_instance_new_forprov(OSSL_DECODER *decoder, void *provctx, const char *input_structure) { + OSSL_DECODER_INSTANCE *decoder_inst = NULL; void *decoderctx; if (!ossl_assert(decoder != NULL)) { @@ -251,7 +252,10 @@ ossl_decoder_instance_new_forprov(OSSL_DECODER *decoder, void *provctx, return 0; } } - return ossl_decoder_instance_new(decoder, decoderctx); + decoder_inst = ossl_decoder_instance_new(decoder, decoderctx); + if (decoder_inst == NULL) + decoder->freectx(decoderctx); + return decoder_inst; } OSSL_DECODER_INSTANCE *ossl_decoder_instance_new(OSSL_DECODER *decoder, diff --git a/crypto/encode_decode/decoder_meth.c b/crypto/encode_decode/decoder_meth.c index 772c29c031952..5e2a7ce3be32e 100644 --- a/crypto/encode_decode/decoder_meth.c +++ b/crypto/encode_decode/decoder_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -47,8 +47,7 @@ static int ossl_decoder_up_ref(void *data) OSSL_DECODER *decoder = (OSSL_DECODER *)data; int ref = 0; - CRYPTO_UP_REF(&decoder->base.refcnt, &ref); - return 1; + return CRYPTO_UP_REF(&decoder->base.refcnt, &ref); } /* Simple method structure constructor and destructor */ @@ -416,7 +415,10 @@ inner_ossl_decoder_fetch(struct decoder_data_st *methdata, * lives beyond the freeing of that tmp_store */ #ifndef OPENSSL_NO_CACHED_FETCH - OSSL_DECODER_up_ref((OSSL_DECODER *)method); + if (!OSSL_DECODER_up_ref((OSSL_DECODER *)method)) { + ossl_decoder_free(method); + method = NULL; + } #endif } } diff --git a/crypto/encode_decode/encoder_err.c b/crypto/encode_decode/encoder_err.c deleted file mode 100644 index 1def566f00fa1..0000000000000 --- a/crypto/encode_decode/encoder_err.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/encodererr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA OSSL_ENCODER_str_reasons[] = { - { ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, OSSL_ENCODER_R_BAD_PARAMETER_VALUE), - "bad parameter value" }, - { ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, OSSL_ENCODER_R_ENCODER_NOT_FOUND), - "encoder not found" }, - { ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY), - "incorrect property query" }, - { ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, OSSL_ENCODER_R_MISSING_GET_PARAMS), - "missing get params" }, - { ERR_PACK(ERR_LIB_OSSL_ENCODER, 0, OSSL_ENCODER_R_UNKNOWN_PARAMETER_NAME), - "unknown parameter name" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_OSSL_ENCODER_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(OSSL_ENCODER_str_reasons[0].error) == NULL) - ERR_load_strings_const(OSSL_ENCODER_str_reasons); -#endif - return 1; -} diff --git a/crypto/encode_decode/encoder_lib.c b/crypto/encode_decode/encoder_lib.c index 375c98188cd57..be1463d29bf63 100644 --- a/crypto/encode_decode/encoder_lib.c +++ b/crypto/encode_decode/encoder_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -583,6 +583,7 @@ static int encoder_process(struct encoder_process_data_st *data) data->prev_encoder_inst = new_data.prev_encoder_inst; data->running_output = new_data.running_output; data->running_output_length = new_data.running_output_length; + data->data_type = new_data.data_type; /* * ok == -1 means that the recursion call above gave no further diff --git a/crypto/encode_decode/encoder_local.h b/crypto/encode_decode/encoder_local.h index 6ebbe1c5136ce..0544e09ccdc8b 100644 --- a/crypto/encode_decode/encoder_local.h +++ b/crypto/encode_decode/encoder_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/encode_decode/encoder_meth.c b/crypto/encode_decode/encoder_meth.c index 23dcccebb958a..f02b6ddc22a58 100644 --- a/crypto/encode_decode/encoder_meth.c +++ b/crypto/encode_decode/encoder_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -48,8 +48,7 @@ static int ossl_encoder_up_ref(void *data) OSSL_ENCODER *encoder = (OSSL_ENCODER *)data; int ref = 0; - CRYPTO_UP_REF(&encoder->base.refcnt, &ref); - return 1; + return CRYPTO_UP_REF(&encoder->base.refcnt, &ref); } /* Simple method structure constructor and destructor */ diff --git a/crypto/err/README.md b/crypto/err/README.md index 477dffa2ad325..2f48714f3b6fe 100644 --- a/crypto/err/README.md +++ b/crypto/err/README.md @@ -1,55 +1,49 @@ Adding new libraries ==================== -When adding a new sub-library to OpenSSL, assign it a library number -`ERR_LIB_XXX`, define a macro `XXXerr()` (both in `err.h`), add its -name to `ERR_str_libraries[]` (in `crypto/err/err.c`), and add -`ERR_load_XXX_strings()` to the `ERR_load_crypto_strings()` function -(in `crypto/err/err_all.c`). Finally, add an entry: +When adding a new sub-library to OpenSSL: - L XXX xxx.h xxx_err.c +- assign it a library number `ERR_LIB_XXX` in `include/openssl/err.h`; +- add its name to `ERR_str_libraries[]` in `crypto/err/err.c`; +- add a call to `ossl_err_load_XXX_strings()` in + `ossl_err_load_crypto_strings()` in `crypto/err/err_all.c`. That + function is defined in the generated source named below; +- add an entry to `crypto/err/openssl.ec`: -to `crypto/err/openssl.ec`, and add `xxx_err.c` to the `Makefile`. -Running make errors will then generate a file `xxx_err.c`, and -add all error codes used in the library to `xxx.h`. + L XXX include/openssl/xxxerr.h crypto/xxx/xxx_err.c -Additionally the library include file must have a certain form. -Typically it will initially look like this: + The fields after the library name are the public header, the source + file, and an optional private header. `NONE` stands for a file that + is not wanted. The public header must be under `include/openssl/`, + and a private header may only be given for an internal library; - #ifndef HEADER_XXX_H - #define HEADER_XXX_H +- add the files named on that entry to the block of generated error + files in `.gitignore`. - #ifdef __cplusplus - extern "C" { - #endif +Those files are produced during the build from `crypto/err/openssl.ec` +and `crypto/err/openssl.txt`, and are not in git. They are left +read-only: an edit to one is lost the next time it is generated. - /* Include files */ - - #include - #include +Adding new error codes +====================== - /* Macros, structures and function prototypes */ +Raise an error with `ERR_raise()`, using a reason name of the form +`XXX_R_...`: + ERR_raise(ERR_LIB_XXX, XXX_R_SOMETHING_FAILED); - /* BEGIN ERROR CODES */ +The reason does not have to be declared first. Running -The `BEGIN ERROR CODES` sequence is used by the error code -generation script as the point to place new error codes, any text -after this point will be overwritten when make errors is run. -The closing `#endif` etc will be automatically added by the script. + make update -The generated C error code file `xxx_err.c` will load the header -files `stdio.h`, `openssl/err.h` and `openssl/xxx.h` so the -header file must load any additional header files containing any -definitions it uses. +scans the sources, assigns a number to each reason that does not have +one, and records it in `crypto/err/openssl.txt`: -Adding new error codes -====================== + XXX_R_SOMETHING_FAILED:100:something failed -Instead of manually adding error codes into `crypto/err/openssl.txt`, -it is recommended to leverage `make update` for error code generation. -The target will process relevant sources and generate error codes for -any *used* error codes. +Numbers already recorded there are kept, so they remain stable for +applications that have compiled against them. -If an error code is added manually into `crypto/err/openssl.txt`, -subsequent `make update` has no effect. +The third field is the string returned by `ERR_reason_error_string()`. +It is derived from the reason name, with underscores replaced by +spaces; edit `crypto/err/openssl.txt` if it should read differently. diff --git a/crypto/err/err.c b/crypto/err/err.c index bf637e1d45e7a..2923f0b13fdc8 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -302,6 +302,10 @@ int ERR_unload_strings(int lib, ERR_STRING_DATA *str) if (!RUN_ONCE(&err_string_init, do_err_strings_init)) return 0; + /* The error string table may already have been cleaned up. */ + if (err_string_lock == NULL) + return 1; + if (!CRYPTO_THREAD_write_lock(err_string_lock)) return 0; /* @@ -516,6 +520,7 @@ void ossl_err_string_int(unsigned long e, const char *func, char lsbuf[64], rsbuf[256]; const char *ls, *rs = NULL; unsigned long l, r; + int n; if (len == 0) return; @@ -523,7 +528,7 @@ void ossl_err_string_int(unsigned long e, const char *func, l = ERR_GET_LIB(e); ls = ERR_lib_error_string(e); if (ls == NULL) { - BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l); + snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l); ls = lsbuf; } @@ -543,16 +548,15 @@ void ossl_err_string_int(unsigned long e, const char *func, } #endif if (rs == NULL) { - BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", + snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r & ~(ERR_RFLAGS_MASK << ERR_RFLAGS_OFFSET)); rs = rsbuf; } - BIO_snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls, func, rs); - if (strlen(buf) == len - 1) { + n = snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls, func, rs); + if (n < 0 || (size_t)n >= len) /* Didn't fit; use a minimal format. */ - BIO_snprintf(buf, len, "err:%lx:%lx:%lx:%lx", e, l, 0L, r); - } + snprintf(buf, len, "err:%lx:%lx:%lx:%lx", e, l, 0L, r); } void ERR_error_string_n(unsigned long e, char *buf, size_t len) diff --git a/crypto/err/err_all.c b/crypto/err/err_all.c index 7761410f2d6bf..9b118383c314c 100644 --- a/crypto/err/err_all.c +++ b/crypto/err/err_all.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/err/err_blocks.c b/crypto/err/err_blocks.c index 90451ea880a0c..05de163280836 100644 --- a/crypto/err/err_blocks.c +++ b/crypto/err/err_blocks.c @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ +#include #include #include #include "err_local.h" @@ -85,9 +86,9 @@ void ERR_vset_error(int lib, int reason, const char *fmt, va_list args) } if (buf != NULL) { - printed_len = BIO_vsnprintf(buf, buf_size, fmt, args); + printed_len = vsnprintf(buf, buf_size, fmt, args); } - if (printed_len < 0) + if (printed_len < 0 || (size_t)printed_len >= buf_size) printed_len = 0; if (buf != NULL) buf[printed_len] = '\0'; diff --git a/crypto/err/err_prn.c b/crypto/err/err_prn.c index b4970da437107..d3f704056e8cf 100644 --- a/crypto/err/err_prn.c +++ b/crypto/err/err_prn.c @@ -32,11 +32,11 @@ void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u), data = ""; hex = ossl_buf2hexstr_sep((const unsigned char *)&tid, sizeof(tid), '\0'); - BIO_snprintf(buf, sizeof(buf), "%s:", hex == NULL ? "" : hex); + snprintf(buf, sizeof(buf), "%s:", hex == NULL ? "" : hex); offset = (int)strlen(buf); ossl_err_string_int(l, func, buf + offset, sizeof(buf) - offset); offset += (int)strlen(buf + offset); - BIO_snprintf(buf + offset, sizeof(buf) - offset, ":%s:%d:%s\n", + snprintf(buf + offset, sizeof(buf) - offset, ":%s:%d:%s\n", file, line, data); OPENSSL_free(hex); if (cb(buf, strlen(buf), u) <= 0) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 14658d76341c4..adf38e601a8bf 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -154,7 +154,8 @@ BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED:143:\ BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED:144:no hostname or service specified BIO_R_NO_PORT_DEFINED:113:no port defined BIO_R_NO_SUCH_FILE:128:no such file -BIO_R_PEER_ADDR_NOT_AVAILABLE:114:peer addr not available +BIO_R_NULL_PARAMETER:115:null parameter +BIO_R_PEER_ADDR_NOT_AVAILABLE:151:peer addr not available BIO_R_PORT_MISMATCH:150:port mismatch BIO_R_TFO_DISABLED:106:tfo disabled BIO_R_TFO_NO_KERNEL_SUPPORT:108:tfo no kernel support @@ -1056,6 +1057,7 @@ PROV_R_FIPS_MODULE_CONDITIONAL_ERROR:227:fips module conditional error PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE:224:fips module entering error state PROV_R_FIPS_MODULE_IMPORT_PCT_ERROR:253:fips module import pct error PROV_R_FIPS_MODULE_IN_ERROR_STATE:225:fips module in error state +PROV_R_FIPS_MODULE_MISSING_CHECKSUM:267:fips module missing checksum PROV_R_GENERATE_ERROR:191:generate error PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE:165:\ illegal or unsupported padding mode @@ -1645,25 +1647,24 @@ SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE:1113:\ SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE:1111:tlsv1 certificate unobtainable SSL_R_TLSV1_UNRECOGNIZED_NAME:1112:tlsv1 unrecognized name SSL_R_TLSV1_UNSUPPORTED_EXTENSION:1110:tlsv1 unsupported extension -SSL_R_TLS_ALERT_BAD_CERTIFICATE:1042:ssl/tls alert bad certificate -SSL_R_TLS_ALERT_BAD_RECORD_MAC:1020:ssl/tls alert bad record mac -SSL_R_TLS_ALERT_CERTIFICATE_EXPIRED:1045:ssl/tls alert certificate expired -SSL_R_TLS_ALERT_CERTIFICATE_REVOKED:1044:ssl/tls alert certificate revoked -SSL_R_TLS_ALERT_CERTIFICATE_UNKNOWN:1046:ssl/tls alert certificate unknown -SSL_R_TLS_ALERT_DECOMPRESSION_FAILURE:1030:ssl/tls alert decompression failure -SSL_R_TLS_ALERT_HANDSHAKE_FAILURE:1040:ssl/tls alert handshake failure -SSL_R_TLS_ALERT_ILLEGAL_PARAMETER:1047:ssl/tls alert illegal parameter -SSL_R_TLS_ALERT_NO_CERTIFICATE:1041:ssl/tls alert no certificate -SSL_R_TLS_ALERT_UNEXPECTED_MESSAGE:1010:ssl/tls alert unexpected message -SSL_R_TLS_ALERT_UNSUPPORTED_CERTIFICATE:1043:\ - ssl/tls alert unsupported certificate +SSL_R_TLS_ALERT_BAD_CERTIFICATE:1042:tls alert bad certificate +SSL_R_TLS_ALERT_BAD_RECORD_MAC:1020:tls alert bad record mac +SSL_R_TLS_ALERT_CERTIFICATE_EXPIRED:1045:tls alert certificate expired +SSL_R_TLS_ALERT_CERTIFICATE_REVOKED:1044:tls alert certificate revoked +SSL_R_TLS_ALERT_CERTIFICATE_UNKNOWN:1046:tls alert certificate unknown +SSL_R_TLS_ALERT_DECOMPRESSION_FAILURE:1030:tls alert decompression failure +SSL_R_TLS_ALERT_HANDSHAKE_FAILURE:1040:tls alert handshake failure +SSL_R_TLS_ALERT_ILLEGAL_PARAMETER:1047:tls alert illegal parameter +SSL_R_TLS_ALERT_NO_CERTIFICATE:1041:tls alert no certificate +SSL_R_TLS_ALERT_UNEXPECTED_MESSAGE:1010:tls alert unexpected message +SSL_R_TLS_ALERT_UNSUPPORTED_CERTIFICATE:1043:tls alert unsupported certificate SSL_R_TLS_EXT_INVALID_MAX_FRAGMENT_LENGTH:232:\ - ssl3 ext invalid max fragment length -SSL_R_TLS_EXT_INVALID_SERVERNAME:319:ssl3 ext invalid servername -SSL_R_TLS_EXT_INVALID_SERVERNAME_TYPE:320:ssl3 ext invalid servername type + tls ext invalid max fragment length +SSL_R_TLS_EXT_INVALID_SERVERNAME:319:tls ext invalid servername +SSL_R_TLS_EXT_INVALID_SERVERNAME_TYPE:320:tls ext invalid servername type SSL_R_TLS_ILLEGAL_EXPORTER_LABEL:367:tls illegal exporter label SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST:157:tls invalid ecpointformat list -SSL_R_TLS_SESSION_ID_TOO_LONG:300:ssl3 session id too long +SSL_R_TLS_SESSION_ID_TOO_LONG:300:tls session id too long SSL_R_TOO_MANY_KEY_UPDATES:132:too many key updates SSL_R_TOO_MANY_WARN_ALERTS:409:too many warn alerts SSL_R_TOO_MUCH_EARLY_DATA:164:too much early data @@ -1776,6 +1777,7 @@ X509V3_R_BN_DEC2BN_ERROR:100:bn dec2bn error X509V3_R_BN_TO_ASN1_INTEGER_ERROR:101:bn to asn1 integer error X509V3_R_DIRNAME_ERROR:149:dirname error X509V3_R_DISTPOINT_ALREADY_SET:160:distpoint already set +X509V3_R_DUPLICATE_FIELD:174:duplicate field X509V3_R_DUPLICATE_ZONE_ID:133:duplicate zone id X509V3_R_EMPTY_KEY_USAGE:169:empty key usage X509V3_R_ERROR_CONVERTING_ZONE:131:error converting zone diff --git a/crypto/ess/ess_err.c b/crypto/ess/ess_err.c deleted file mode 100644 index cd232d8934f71..0000000000000 --- a/crypto/ess/ess_err.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/esserr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA ESS_str_reasons[] = { - { ERR_PACK(ERR_LIB_ESS, 0, ESS_R_EMPTY_ESS_CERT_ID_LIST), - "empty ess cert id list" }, - { ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_CERT_DIGEST_ERROR), - "ess cert digest error" }, - { ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_CERT_ID_NOT_FOUND), - "ess cert id not found" }, - { ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_CERT_ID_WRONG_ORDER), - "ess cert id wrong order" }, - { ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_DIGEST_ALG_UNKNOWN), - "ess digest alg unknown" }, - { ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_SIGNING_CERTIFICATE_ERROR), - "ess signing certificate error" }, - { ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_SIGNING_CERT_ADD_ERROR), - "ess signing cert add error" }, - { ERR_PACK(ERR_LIB_ESS, 0, ESS_R_ESS_SIGNING_CERT_V2_ADD_ERROR), - "ess signing cert v2 add error" }, - { ERR_PACK(ERR_LIB_ESS, 0, ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE), - "missing signing certificate attribute" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_ESS_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(ESS_str_reasons[0].error) == NULL) - ERR_load_strings_const(ESS_str_reasons); -#endif - return 1; -} diff --git a/crypto/evp/asymcipher.c b/crypto/evp/asymcipher.c index 1665efd3e285c..ed3dcaaf45b00 100644 --- a/crypto/evp/asymcipher.c +++ b/crypto/evp/asymcipher.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -38,8 +38,7 @@ static int evp_asym_cipher_up_ref(void *data) EVP_ASYM_CIPHER *cipher = (EVP_ASYM_CIPHER *)data; int ref = 0; - CRYPTO_UP_REF(&cipher->refcnt, &ref); - return 1; + return CRYPTO_UP_REF(&cipher->refcnt, &ref); } static int evp_pkey_asym_cipher_init(EVP_PKEY_CTX *ctx, int operation, diff --git a/crypto/evp/bio_b64.c b/crypto/evp/bio_b64.c index 7f32d7a5d0c50..2a6f06c110063 100644 --- a/crypto/evp/bio_b64.c +++ b/crypto/evp/bio_b64.c @@ -44,6 +44,8 @@ typedef struct b64_struct { unsigned char tmp[B64_BLOCK_SIZE]; unsigned char *encoded_buf; size_t encoded_buf_len; + size_t encoded_len; + size_t encoded_off; } BIO_B64_CTX; static const BIO_METHOD methods_b64 = { @@ -111,6 +113,72 @@ static int b64_free(BIO *a) return 1; } +static int b64_write_buffer(BIO *b, BIO *next, unsigned char *buf, + size_t *buf_len, size_t *buf_off) +{ + size_t n; + int i, dlen; + + if (!ossl_assert(*buf_len >= *buf_off)) { + ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR); + return -1; + } + + n = *buf_len - *buf_off; + if (n > 0 && !ossl_assert(buf != NULL)) { + ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR); + return -1; + } + while (n > 0) { + if (n > INT_MAX) + dlen = INT_MAX; + else + dlen = (int)n; + i = BIO_write(next, &(buf[*buf_off]), dlen); + if (i <= 0) { + BIO_copy_next_retry(b); + return i; + } + if (!ossl_assert((size_t)i <= n)) { + ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR); + return -1; + } + *buf_off += (size_t)i; + n -= (size_t)i; + } + *buf_off = 0; + *buf_len = 0; + + return 1; +} + +static int b64_write_buffer_int(BIO *b, BIO *next, unsigned char *buf, + int *buf_len, int *buf_off) +{ + int ret; + size_t len; + size_t off; + + if (!ossl_assert(*buf_off >= 0)) { + ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR); + return -1; + } + + len = (size_t)*buf_len; + off = (size_t)*buf_off; + ret = b64_write_buffer(b, next, buf, &len, &off); + + *buf_len = (int)len; + *buf_off = (int)off; + return ret; +} + +static int b64_write_pending(BIO_B64_CTX *ctx) +{ + return ctx->encoded_len != ctx->encoded_off + || ctx->buf_len != ctx->buf_off; +} + /* * Unless `BIO_FLAGS_BASE64_NO_NL` is set, this BIO ignores leading lines that * aren't exclusively composed of valid Base64 characters (followed by @@ -141,6 +209,8 @@ static int b64_read(BIO *b, char *out, int outl) ctx->buf_len = 0; ctx->buf_off = 0; ctx->tmp_len = 0; + ctx->encoded_len = 0; + ctx->encoded_off = 0; EVP_DecodeInit(ctx->base64); } @@ -330,7 +400,6 @@ static int b64_read(BIO *b, char *out, int outl) static int b64_write(BIO *b, const char *in, int inl) { int ret = 0; - int n; int i; BIO_B64_CTX *ctx; BIO *next; @@ -350,6 +419,8 @@ static int b64_write(BIO *b, const char *in, int inl) ctx->buf_len = 0; ctx->buf_off = 0; ctx->tmp_len = 0; + ctx->encoded_len = 0; + ctx->encoded_off = 0; EVP_EncodeInit(ctx->base64); if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) evp_encode_ctx_set_flags(ctx->base64, EVP_ENCODE_CTX_NO_NEWLINES); @@ -366,27 +437,26 @@ static int b64_write(BIO *b, const char *in, int inl) ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR); return -1; } - n = ctx->buf_len - ctx->buf_off; - while (n > 0) { - i = BIO_write(next, &(ctx->buf[ctx->buf_off]), n); - if (i <= 0) { - BIO_copy_next_retry(b); - return i; - } - ctx->buf_off += i; - if (!ossl_assert(ctx->buf_off <= (int)sizeof(ctx->buf))) { - ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR); - return -1; - } - if (!ossl_assert(ctx->buf_len >= ctx->buf_off)) { - ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR); - return -1; - } - n -= i; + if (!ossl_assert(ctx->encoded_len >= ctx->encoded_off)) { + ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR); + return -1; + } + if (!ossl_assert(ctx->encoded_len <= ctx->encoded_buf_len)) { + ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR); + return -1; + } + + i = b64_write_buffer(b, next, ctx->encoded_buf, &ctx->encoded_len, + &ctx->encoded_off); + if (i <= 0) + return i; + i = b64_write_buffer_int(b, next, ctx->buf, &ctx->buf_len, &ctx->buf_off); + if (i <= 0) + return i; + if (!ossl_assert(ctx->buf_off <= (int)sizeof(ctx->buf))) { + ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR); + return -1; } - /* at this point all pending data has been written */ - ctx->buf_off = 0; - ctx->buf_len = 0; if (in == NULL || inl <= 0) return 0; @@ -400,6 +470,8 @@ static int b64_write(BIO *b, const char *in, int inl) if (ctx->encoded_buf == NULL || encoded_length > ctx->encoded_buf_len) { OPENSSL_free(ctx->encoded_buf); + ctx->encoded_buf = NULL; + ctx->encoded_buf_len = 0; ctx->encoded_buf = OPENSSL_malloc(encoded_length); if (ctx->encoded_buf == NULL) { ERR_raise(ERR_LIB_BIO, ERR_R_MALLOC_FAILURE); @@ -419,10 +491,19 @@ static int b64_write(BIO *b, const char *in, int inl) (unsigned char *)in, inl)) { return -1; } + /* + * The encoder state has consumed the input. Keep any unwritten encoded + * output pending so a later retry or flush can complete it. + */ ret += inl; - i = BIO_write(next, encoded, n_bytes_enc); - if (i <= 0) - BIO_copy_next_retry(b); + ctx->encoded_len = (size_t)n_bytes_enc; + ctx->encoded_off = 0; + /* + * Try to write it now, but the input is consumed into encoder state, so + * report it as written even if downstream cannot accept all encoded output. + */ + (void)b64_write_buffer(b, next, ctx->encoded_buf, &ctx->encoded_len, + &ctx->encoded_off); return ret; } @@ -447,6 +528,8 @@ static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) ctx->cont = 1; ctx->start = 1; ctx->encode = B64_NONE; + ctx->encoded_len = 0; + ctx->encoded_off = 0; ret = BIO_ctrl(next, cmd, num, ptr); break; case BIO_CTRL_EOF: /* More to read */ @@ -456,11 +539,16 @@ static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) ret = BIO_ctrl(next, cmd, num, ptr); break; case BIO_CTRL_WPENDING: /* More to write in buffer */ + if (!ossl_assert(ctx->encoded_len >= ctx->encoded_off)) { + ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR); + return -1; + } if (!ossl_assert(ctx->buf_len >= ctx->buf_off)) { ERR_raise(ERR_LIB_BIO, ERR_R_INTERNAL_ERROR); return -1; } - ret = ctx->buf_len - ctx->buf_off; + ret = (long)(ctx->encoded_len - ctx->encoded_off) + + (ctx->buf_len - ctx->buf_off); if (ret == 0 && ctx->encode != B64_NONE && EVP_ENCODE_CTX_num(ctx->base64) != 0) ret = 1; @@ -480,9 +568,9 @@ static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) if (ctx->encode == B64_ENCODE) { /* do a final write */ again: - while (ctx->buf_len != ctx->buf_off) { + while (b64_write_pending(ctx)) { i = b64_write(b, NULL, 0); - if (i < 0) + if (i < 0 || (i == 0 && b64_write_pending(ctx))) return i; } if (EVP_ENCODE_CTX_num(ctx->base64) != 0) { diff --git a/crypto/evp/bio_enc.c b/crypto/evp/bio_enc.c index a56bc3b9e6f3a..4b12e49359f72 100644 --- a/crypto/evp/bio_enc.c +++ b/crypto/evp/bio_enc.c @@ -396,9 +396,6 @@ static long enc_ctrl(BIO *b, int cmd, long num, void *ptr) case BIO_CTRL_DUP: dbio = (BIO *)ptr; dctx = BIO_get_data(dbio); - dctx->cipher = EVP_CIPHER_CTX_new(); - if (dctx->cipher == NULL) - return 0; ret = EVP_CIPHER_CTX_copy(dctx->cipher, ctx->cipher); if (ret) BIO_set_init(dbio, 1); diff --git a/crypto/evp/build.info b/crypto/evp/build.info index 5897acd943da4..4849f3dfa186c 100644 --- a/crypto/evp/build.info +++ b/crypto/evp/build.info @@ -2,7 +2,7 @@ LIBS=../../libcrypto $COMMON=digest.c evp_enc.c evp_lib.c evp_fetch.c evp_utils.c \ mac_lib.c mac_meth.c keymgmt_meth.c keymgmt_lib.c kdf_lib.c kdf_meth.c \ skeymgmt_meth.c \ - pmeth_lib.c signature.c p_lib.c s_lib.c pmeth_gn.c exchange.c \ + pmeth_lib.c signature.c p_lib.c pmeth_gn.c exchange.c \ evp_rand.c asymcipher.c kem.c dh_support.c ec_support.c pmeth_check.c \ evp_pkey_type.c @@ -20,7 +20,7 @@ SOURCE[../../libcrypto]=$COMMON\ e_aes_cbc_hmac_sha1.c e_aes_cbc_hmac_sha256.c e_rc4_hmac_md5.c \ e_chacha20_poly1305.c \ legacy_sha.c ctrl_params_translate.c \ - m_sigver.c + m_sigver.c s_lib.c # Diverse type specific ctrl functions. They are kinda sorta legacy, kinda # sorta not. diff --git a/crypto/evp/ctrl_params_translate.c b/crypto/evp/ctrl_params_translate.c index c515c6cbbf9d6..f605900cb57f3 100644 --- a/crypto/evp/ctrl_params_translate.c +++ b/crypto/evp/ctrl_params_translate.c @@ -15,6 +15,7 @@ */ #include "internal/deprecated.h" +#include #include /* The following includes get us all the EVP_PKEY_CTRL macros */ @@ -1046,9 +1047,19 @@ static int fix_dh_nid5114(enum state state, case PRE_CTRL_STR_TO_PARAMS: if (ctx->p2 == NULL) return 0; - if ((ctx->p2 = (char *)ossl_ffc_named_group_get_name(ossl_ffc_uid_to_dh_named_group(atoi(ctx->p2)))) == NULL) { - ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_VALUE); - return 0; + { + int uid; + + if (!ossl_strtoint(ctx->p2, NULL, 10, &uid)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_VALUE); + return 0; + } + ctx->p2 = (char *)ossl_ffc_named_group_get_name( + ossl_ffc_uid_to_dh_named_group(uid)); + if (ctx->p2 == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_VALUE); + return 0; + } } ctx->p1 = 0; @@ -1076,8 +1087,14 @@ static int fix_dh_paramgen_type(enum state state, return 0; if (state == PRE_CTRL_STR_TO_PARAMS) { - if ((ctx->p2 = (char *)ossl_dh_gen_type_id2name(atoi(ctx->p2))) - == NULL) { + int id; + + if (!ossl_strtoint(ctx->p2, NULL, 10, &id)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_VALUE); + return 0; + } + ctx->p2 = (char *)ossl_dh_gen_type_id2name(id); + if (ctx->p2 == NULL) { ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_VALUE); return 0; } @@ -1410,7 +1427,7 @@ static int fix_rsa_pss_saltlen(enum state state, break; } if (i == OSSL_NELEM(str_value_map)) { - BIO_snprintf(ctx->name_buf, sizeof(ctx->name_buf), "%d", ctx->p1); + snprintf(ctx->name_buf, sizeof(ctx->name_buf), "%d", ctx->p1); } else { /* This won't truncate but it will quiet static analysers */ strncpy(ctx->name_buf, str_value_map[i].ptr, sizeof(ctx->name_buf) - 1); @@ -1433,8 +1450,14 @@ static int fix_rsa_pss_saltlen(enum state state, break; } - val = i == OSSL_NELEM(str_value_map) ? atoi(ctx->p2) - : (int)str_value_map[i].id; + if (i == OSSL_NELEM(str_value_map)) { + if (!ossl_strtoint(ctx->p2, NULL, 10, &val)) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_VALUE); + return 0; + } + } else { + val = (int)str_value_map[i].id; + } if (state == POST_CTRL_TO_PARAMS) { /* * EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN weirdness explained further diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c index 61e7dbc4ecc7a..db7121f0a4618 100644 --- a/crypto/evp/digest.c +++ b/crypto/evp/digest.c @@ -981,7 +981,7 @@ static int evp_md_up_ref(void *m) int ref = 0; if (md->origin == EVP_ORIG_DYNAMIC) - CRYPTO_UP_REF(&md->refcnt, &ref); + return CRYPTO_UP_REF(&md->refcnt, &ref); return 1; } diff --git a/crypto/evp/ec_support.c b/crypto/evp/ec_support.c index 4763507ec1c59..1e01a56436561 100644 --- a/crypto/evp/ec_support.c +++ b/crypto/evp/ec_support.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/evp/enc_b64_avx2.c b/crypto/evp/enc_b64_avx2.c index dafa834a4813e..df6406de5713b 100644 --- a/crypto/evp/enc_b64_avx2.c +++ b/crypto/evp/enc_b64_avx2.c @@ -5,7 +5,7 @@ #include "crypto/evp.h" #include "evp_local.h" -#if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) +#if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) || defined(__e2k__) #if !defined(_M_ARM64EC) #if defined(HAVE_AVX2_INTRINSICS) #define STRINGIFY_IMPLEMENTATION_(a) #a diff --git a/crypto/evp/enc_b64_avx2.h b/crypto/evp/enc_b64_avx2.h index 71b0a004e7d77..a450d40a8c766 100644 --- a/crypto/evp/enc_b64_avx2.h +++ b/crypto/evp/enc_b64_avx2.h @@ -6,13 +6,13 @@ #if defined(__clang__) #define HAVE_AVX2_INTRINSICS 1 -#elif defined(__GNUC__) && (__GNUC__ >= 8) +#elif defined(__GNUC__) && (__GNUC__ >= 8) && !defined(__MINGW32__) #define HAVE_AVX2_INTRINSICS 1 #elif defined(_MSC_VER) && (_MSC_VER >= 1920) /* MSVC 2019 */ #define HAVE_AVX2_INTRINSICS 1 #endif -#if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) +#if defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) || defined(__e2k__) #if !defined(_M_ARM64EC) #if defined(HAVE_AVX2_INTRINSICS) size_t encode_base64_avx2(EVP_ENCODE_CTX *ctx, diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index 830cfdb8d8f90..4b3fdc63759f1 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -254,6 +254,7 @@ static int evp_cipher_init_internal(EVP_CIPHER_CTX *ctx, params); } +#ifndef FIPS_MODULE /* * This function is basically evp_cipher_init_internal without ENGINE support. * They should be combined when engines are not supported any longer. @@ -389,6 +390,7 @@ int EVP_CipherInit_SKEY(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, { return evp_cipher_init_skey_internal(ctx, cipher, skey, iv, iv_len, enc, params); } +#endif /* !FIPS_MODULE */ int EVP_CipherInit_ex2(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, @@ -986,6 +988,12 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) ctx->iv_len = -1; break; case EVP_CTRL_AEAD_SET_IV_FIXED: + /* + * arg == -1 is a valid sentinel meaning "use full ivlen"; anything + * below that would wrap to a huge size_t and overflow on memcpy. + */ + if (arg < -1) + return 0; params[0] = OSSL_PARAM_construct_octet_string( OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED, ptr, sz); break; @@ -1346,7 +1354,7 @@ static int evp_cipher_up_ref(void *c) int ref = 0; if (cipher->origin == EVP_ORIG_DYNAMIC) - CRYPTO_UP_REF(&cipher->refcnt, &ref); + return CRYPTO_UP_REF(&cipher->refcnt, &ref); return 1; } diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c deleted file mode 100644 index 55b26c7cd7ae4..0000000000000 --- a/crypto/evp/evp_err.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/evperr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA EVP_str_reasons[] = { - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_AES_KEY_SETUP_FAILED), - "aes key setup failed" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ARIA_KEY_SETUP_FAILED), - "aria key setup failed" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_ALGORITHM_NAME), "bad algorithm name" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_DECRYPT), "bad decrypt" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BAD_KEY_LENGTH), "bad key length" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_BUFFER_TOO_SMALL), "buffer too small" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CACHE_CONSTANTS_FAILED), - "cache constants failed" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CAMELLIA_KEY_SETUP_FAILED), - "camellia key setup failed" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CANNOT_GET_PARAMETERS), - "cannot get parameters" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CANNOT_SET_PARAMETERS), - "cannot set parameters" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CIPHER_NOT_GCM_MODE), - "cipher not gcm mode" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CIPHER_PARAMETER_ERROR), - "cipher parameter error" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_COMMAND_NOT_SUPPORTED), - "command not supported" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CONFLICTING_ALGORITHM_NAME), - "conflicting algorithm name" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CONTEXT_FINALIZED), "context finalized" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_COPY_ERROR), "copy error" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CTRL_NOT_IMPLEMENTED), - "ctrl not implemented" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED), - "ctrl operation not implemented" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH), - "data not multiple of block length" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DECODE_ERROR), "decode error" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DEFAULT_QUERY_PARSE_ERROR), - "default query parse error" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_KEY_TYPES), - "different key types" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_DIFFERENT_PARAMETERS), - "different parameters" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ERROR_LOADING_SECTION), - "error loading section" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_HMAC_KEY), - "expecting an hmac key" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_AN_RSA_KEY), - "expecting an rsa key" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_DH_KEY), "expecting a dh key" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_DSA_KEY), - "expecting a dsa key" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_ECX_KEY), - "expecting an ecx key" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_EC_KEY), "expecting an ec key" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_POLY1305_KEY), - "expecting a poly1305 key" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_EXPECTING_A_SIPHASH_KEY), - "expecting a siphash key" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_FINAL_ERROR), "final error" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_GENERATE_ERROR), "generate error" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_GETTING_ALGORITHMIDENTIFIER_NOT_SUPPORTED), - "getting AlgorithmIdentifier not supported" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_GET_RAW_KEY_FAILED), "get raw key failed" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ILLEGAL_SCRYPT_PARAMETERS), - "illegal scrypt parameters" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS), - "inaccessible domain parameters" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INACCESSIBLE_KEY), "inaccessible key" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INITIALIZATION_ERROR), - "initialization error" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INPUT_NOT_INITIALIZED), - "input not initialized" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_CUSTOM_LENGTH), - "invalid custom length" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_DIGEST), "invalid digest" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_IV_LENGTH), "invalid iv length" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY), "invalid key" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_KEY_LENGTH), "invalid key length" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_LENGTH), "invalid length" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_NULL_ALGORITHM), - "invalid null algorithm" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_OPERATION), "invalid operation" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_PROVIDER_FUNCTIONS), - "invalid provider functions" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SALT_LENGTH), - "invalid salt length" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SECRET_LENGTH), - "invalid secret length" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_SEED_LENGTH), - "invalid seed length" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_INVALID_VALUE), "invalid value" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEYMGMT_EXPORT_FAILURE), - "keymgmt export failure" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_KEY_SETUP_FAILED), "key setup failed" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_LOCKING_NOT_SUPPORTED), - "locking not supported" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MEMORY_LIMIT_EXCEEDED), - "memory limit exceeded" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MESSAGE_DIGEST_IS_NULL), - "message digest is null" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_METHOD_NOT_SUPPORTED), - "method not supported" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_MISSING_PARAMETERS), "missing parameters" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NOT_ABLE_TO_COPY_CTX), - "not able to copy ctx" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NOT_XOF_OR_INVALID_LENGTH), - "not XOF or invalid length" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_CIPHER_SET), "no cipher set" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DEFAULT_DIGEST), "no default digest" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_DIGEST_SET), "no digest set" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_IMPORT_FUNCTION), "no import function" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEYMGMT_AVAILABLE), - "no keymgmt available" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEYMGMT_PRESENT), "no keymgmt present" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_KEY_SET), "no key set" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NO_OPERATION_SET), "no operation set" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_NULL_MAC_PKEY_CTX), "null mac pkey ctx" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_ONLY_ONESHOT_SUPPORTED), - "only oneshot supported" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATION_NOT_INITIALIZED), - "operation not initialized" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), - "operation not supported for this keytype" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_SIGNATURE_TYPE), - "operation not supported for this signature type" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_OUTPUT_WOULD_OVERFLOW), - "output would overflow" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARAMETER_TOO_LARGE), - "parameter too large" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PARTIALLY_OVERLAPPING), - "partially overlapping buffers" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PBKDF2_ERROR), "pbkdf2 error" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PIPELINE_NOT_SUPPORTED), - "pipeline not supported" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED), - "pkey application asn1 method already registered" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PRIVATE_KEY_DECODE_ERROR), - "private key decode error" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PRIVATE_KEY_ENCODE_ERROR), - "private key encode error" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_ASYM_CIPHER_FAILURE), - "provider asym cipher failure" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED), - "provider asym cipher not supported" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_GET_CTX_PARAMS_NOT_SUPPORTED), - "provider get ctx params not supported" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_KEYMGMT_FAILURE), - "provider keymgmt failure" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_KEYMGMT_NOT_SUPPORTED), - "provider keymgmt not supported" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_SIGNATURE_FAILURE), - "provider signature failure" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED), - "provider signature not supported" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_SETTING_XOF_FAILED), "setting xof failed" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_SET_DEFAULT_PROPERTY_FAILURE), - "set default property failure" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_SIGNATURE_TYPE_AND_KEY_TYPE_INCOMPATIBLE), - "signature type and key type incompatible" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_TOO_MANY_PIPES), "too many pipes" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_TOO_MANY_RECORDS), "too many records" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_ENABLE_LOCKING), - "unable to enable locking" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE), - "unable to get maximum request size" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_GET_RANDOM_STRENGTH), - "unable to get random strength" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_LOCK_CONTEXT), - "unable to lock context" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNABLE_TO_SET_CALLBACKS), - "unable to set callbacks" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_BITS), "unknown bits" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_CIPHER), "unknown cipher" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_DIGEST), "unknown digest" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_KEY_TYPE), "unknown key type" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_MAX_SIZE), "unknown max size" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_OPTION), "unknown option" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_PBE_ALGORITHM), - "unknown pbe algorithm" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNKNOWN_SECURITY_BITS), - "unknown security bits" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_ALGORITHM), - "unsupported algorithm" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_CIPHER), "unsupported cipher" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_KEYLENGTH), - "unsupported keylength" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION), - "unsupported key derivation function" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_KEY_SIZE), - "unsupported key size" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_KEY_TYPE), - "unsupported key type" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS), - "unsupported number of rounds" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_PRF), "unsupported prf" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM), - "unsupported private key algorithm" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UNSUPPORTED_SALT_TYPE), - "unsupported salt type" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_UPDATE_ERROR), "update error" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRAP_MODE_NOT_ALLOWED), - "wrap mode not allowed" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_WRONG_FINAL_BLOCK_LENGTH), - "wrong final block length" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE), - "xts data unit is too large" }, - { ERR_PACK(ERR_LIB_EVP, 0, EVP_R_XTS_DUPLICATED_KEYS), - "xts duplicated keys" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_EVP_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(EVP_str_reasons[0].error) == NULL) - ERR_load_strings_const(EVP_str_reasons); -#endif - return 1; -} diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c index 15204628db947..d798f8a900227 100644 --- a/crypto/evp/evp_fetch.c +++ b/crypto/evp/evp_fetch.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -274,6 +274,9 @@ inner_evp_generic_fetch(struct evp_method_data_st *methdata, uint32_t meth_id = 0; void *method = NULL; int unsupported, name_id; + int set_in_cache = 1; + void *tmp_method; + const OSSL_PROVIDER *tmp_prov = prov; if (store == NULL || namemap == NULL) { ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_INVALID_ARGUMENT); @@ -364,7 +367,34 @@ inner_evp_generic_fetch(struct evp_method_data_st *methdata, * cached end up in ->tmp_store when provider asks not * to cache the result (see ossl_method_construct_reserve_store()) */ - if (meth_id != 0 && methdata->tmp_store == NULL) { + if (meth_id != 0) { + /* + * If the method doesn't exist in the tmp_store, either the tmp_store doesn't exist + * or the algorithm doesn't exist there, in either case, this is a cacheable entry + */ + if (!ossl_method_store_fetch(methdata->tmp_store, meth_id, propq, &tmp_prov, &tmp_method)) { + set_in_cache = 1; + } else { + /* + * We found a matching method in the temp store, don't cache this entry + */ + if (tmp_method == method) { + set_in_cache = 0; + } else { + set_in_cache = 1; + } + +#ifdef OPENSSL_NO_CACHED_FETCH + /* + * ossl_method_store_fetch takes a reference on the fetched method + * when using NO_CACHED_FETCH, so we need to free it here + */ + free_method(tmp_method); +#endif + } + } + + if (set_in_cache == 1) { ossl_method_store_cache_set(store, prov, meth_id, propq, method, up_ref_method, free_method); } else { diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c index 644772bf377cf..35a44e878c7f9 100644 --- a/crypto/evp/evp_lib.c +++ b/crypto/evp/evp_lib.c @@ -180,7 +180,9 @@ int evp_cipher_asn1_to_param_ex(EVP_CIPHER_CTX *c, ASN1_TYPE *type, break; default: - ret = EVP_CIPHER_get_asn1_iv(c, type) >= 0 ? 1 : -1; + ret = EVP_CIPHER_get_asn1_iv(c, type); + if (ret == 0 && EVP_CIPHER_CTX_get_iv_length(c) == 0) + ret = 1; } } else if (cipher->prov != NULL) { /* We cheat, there's no need for an object ID for this use */ diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h index 1f41cfe644f12..749bc09f55478 100644 --- a/crypto/evp/evp_local.h +++ b/crypto/evp/evp_local.h @@ -232,6 +232,10 @@ struct evp_skeymgmt_st { /* Key identifier */ OSSL_FUNC_skeymgmt_get_key_id_fn *get_key_id; + /* Key metadata accessors */ + OSSL_FUNC_skeymgmt_get_local_keyid_fn *get_local_keyid; + OSSL_FUNC_skeymgmt_get_algorithm_id_fn *get_algorithm_id; + /* destructor */ OSSL_FUNC_skeymgmt_free_fn *free; } /* EVP_SKEYMGMT */; diff --git a/crypto/evp/evp_rand.c b/crypto/evp/evp_rand.c index a0041719b5f9b..168f308f6067c 100644 --- a/crypto/evp/evp_rand.c +++ b/crypto/evp/evp_rand.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/evp/exchange.c b/crypto/evp/exchange.c index 83fcbeb104178..23c838d43ab1d 100644 --- a/crypto/evp/exchange.c +++ b/crypto/evp/exchange.c @@ -40,8 +40,7 @@ static int evp_keyexch_up_ref(void *data) EVP_KEYEXCH *exchange = (EVP_KEYEXCH *)data; int ref = 0; - CRYPTO_UP_REF(&exchange->refcnt, &ref); - return 1; + return CRYPTO_UP_REF(&exchange->refcnt, &ref); } static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov) @@ -486,6 +485,7 @@ int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen) return ret; } +#ifndef FIPS_MODULE EVP_SKEY *EVP_PKEY_derive_SKEY(EVP_PKEY_CTX *ctx, EVP_SKEYMGMT *mgmt, const char *key_type, const char *propquery, size_t keylen, const OSSL_PARAM params[]) @@ -581,6 +581,7 @@ EVP_SKEY *EVP_PKEY_derive_SKEY(EVP_PKEY_CTX *ctx, EVP_SKEYMGMT *mgmt, EVP_SKEYMGMT_free(skeymgmt); return ret; } +#endif /* !FIPS_MODULE */ int evp_keyexch_get_number(const EVP_KEYEXCH *keyexch) { diff --git a/crypto/evp/kdf_lib.c b/crypto/evp/kdf_lib.c index 67351044fba01..c89d93b3bafa4 100644 --- a/crypto/evp/kdf_lib.c +++ b/crypto/evp/kdf_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2018-2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -159,6 +159,7 @@ int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen, return ctx->meth->derive(ctx->algctx, key, keylen, params); } +#ifndef FIPS_MODULE struct convert_key { const char *name; OSSL_PARAM *param; @@ -295,6 +296,7 @@ EVP_SKEY *EVP_KDF_derive_SKEY(EVP_KDF_CTX *ctx, EVP_SKEYMGMT *mgmt, EVP_SKEYMGMT_free(skeymgmt); return ret; } +#endif /* !FIPS_MODULE */ /* * The {get,set}_params functions return 1 if there is no corresponding diff --git a/crypto/evp/kdf_meth.c b/crypto/evp/kdf_meth.c index e0741450e9ee2..2ad6f49235a81 100644 --- a/crypto/evp/kdf_meth.c +++ b/crypto/evp/kdf_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -22,8 +22,7 @@ static int evp_kdf_up_ref(void *vkdf) EVP_KDF *kdf = (EVP_KDF *)vkdf; int ref = 0; - CRYPTO_UP_REF(&kdf->refcnt, &ref); - return 1; + return CRYPTO_UP_REF(&kdf->refcnt, &ref); } static void evp_kdf_free(void *vkdf) diff --git a/crypto/evp/kem.c b/crypto/evp/kem.c index 4041390106213..8ae968d5a5120 100644 --- a/crypto/evp/kem.c +++ b/crypto/evp/kem.c @@ -39,8 +39,7 @@ static int evp_kem_up_ref(void *data) EVP_KEM *kem = (EVP_KEM *)data; int ref = 0; - CRYPTO_UP_REF(&kem->refcnt, &ref); - return 1; + return CRYPTO_UP_REF(&kem->refcnt, &ref); } static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation, diff --git a/crypto/evp/keymgmt_lib.c b/crypto/evp/keymgmt_lib.c index 1d80c747b74b4..108601e939e75 100644 --- a/crypto/evp/keymgmt_lib.c +++ b/crypto/evp/keymgmt_lib.c @@ -33,7 +33,7 @@ int evp_keymgmt_util_try_import(const OSSL_PARAM params[], void *arg) /* Just in time creation of keydata */ if (data->keydata == NULL) { - if ((data->keydata = evp_keymgmt_newdata(data->keymgmt, NULL)) == NULL) { + if ((data->keydata = evp_keymgmt_newdata(data->keymgmt, params)) == NULL) { ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB); return 0; } @@ -320,7 +320,7 @@ void *evp_keymgmt_util_fromdata(EVP_PKEY *target, EVP_KEYMGMT *keymgmt, { void *keydata = NULL; - if ((keydata = evp_keymgmt_newdata(keymgmt, NULL)) == NULL + if ((keydata = evp_keymgmt_newdata(keymgmt, params)) == NULL || !evp_keymgmt_import(keymgmt, keydata, selection, params) || !evp_keymgmt_util_assign_pkey(target, keymgmt, keydata)) { evp_keymgmt_freedata(keymgmt, keydata); diff --git a/crypto/evp/keymgmt_meth.c b/crypto/evp/keymgmt_meth.c index 07ea8f8b9ef31..9cf4ef5e4fa8a 100644 --- a/crypto/evp/keymgmt_meth.c +++ b/crypto/evp/keymgmt_meth.c @@ -39,8 +39,7 @@ static int evp_keymgmt_up_ref(void *data) EVP_KEYMGMT *keymgmt = (EVP_KEYMGMT *)data; int ref = 0; - CRYPTO_UP_REF(&keymgmt->refcnt, &ref); - return 1; + return CRYPTO_UP_REF(&keymgmt->refcnt, &ref); } static void *keymgmt_new(void) diff --git a/crypto/evp/mac_meth.c b/crypto/evp/mac_meth.c index 62d94de45c07b..fb6f3f0b8f61f 100644 --- a/crypto/evp/mac_meth.c +++ b/crypto/evp/mac_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -21,8 +21,7 @@ static int evp_mac_up_ref(void *vmac) EVP_MAC *mac = vmac; int ref = 0; - CRYPTO_UP_REF(&mac->refcnt, &ref); - return 1; + return CRYPTO_UP_REF(&mac->refcnt, &ref); } static void evp_mac_free(void *vmac) diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 2895db09a78c2..d4097994e7ad0 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -700,40 +700,6 @@ int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len) } #ifndef OPENSSL_NO_DEPRECATED_3_0 -static void detect_foreign_key(EVP_PKEY *pkey) -{ - switch (pkey->type) { - case EVP_PKEY_RSA: - case EVP_PKEY_RSA_PSS: - pkey->foreign = pkey->pkey.rsa != NULL - && ossl_rsa_is_foreign(pkey->pkey.rsa); - break; -#ifndef OPENSSL_NO_EC - case EVP_PKEY_SM2: - break; - case EVP_PKEY_EC: - pkey->foreign = pkey->pkey.ec != NULL - && ossl_ec_key_is_foreign(pkey->pkey.ec); - break; -#endif -#ifndef OPENSSL_NO_DSA - case EVP_PKEY_DSA: - pkey->foreign = pkey->pkey.dsa != NULL - && ossl_dsa_is_foreign(pkey->pkey.dsa); - break; -#endif -#ifndef OPENSSL_NO_DH - case EVP_PKEY_DH: - pkey->foreign = pkey->pkey.dh != NULL - && ossl_dh_is_foreign(pkey->pkey.dh); - break; -#endif - default: - pkey->foreign = 0; - break; - } -} - int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) { #ifndef OPENSSL_NO_EC @@ -762,7 +728,6 @@ int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) return 0; pkey->pkey.ptr = key; - detect_foreign_key(pkey); return (key != NULL); } @@ -1630,7 +1595,7 @@ int EVP_PKEY_up_ref(EVP_PKEY *pkey) { int i; - if (CRYPTO_UP_REF(&pkey->references, &i) <= 0) + if (!CRYPTO_UP_REF(&pkey->references, &i)) return 0; REF_PRINT_COUNT("EVP_PKEY", i, pkey); @@ -1912,6 +1877,10 @@ void *evp_pkey_export_to_provider(EVP_PKEY *pk, OSSL_LIB_CTX *libctx, params[0] = OSSL_PARAM_construct_octet_ptr("legacy-object", &pk->pkey.ptr, sizeof(pk->pkey.ptr)); p = params; + } else if (propquery != NULL) { + params[0] = OSSL_PARAM_construct_utf8_string( + OSSL_PKEY_PARAM_PROPERTIES, (char *)propquery, 0); + p = params; } keydata = evp_keymgmt_newdata(tmp_keymgmt, p); if (keydata == NULL) diff --git a/crypto/evp/s_lib.c b/crypto/evp/s_lib.c index 5594dc81c5a33..8342897731498 100644 --- a/crypto/evp/s_lib.c +++ b/crypto/evp/s_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -196,7 +196,7 @@ int EVP_SKEY_up_ref(EVP_SKEY *skey) { int i; - if (CRYPTO_UP_REF(&skey->references, &i) <= 0) + if (!CRYPTO_UP_REF(&skey->references, &i)) return 0; REF_PRINT_COUNT("EVP_SKEY", i, skey); @@ -340,3 +340,49 @@ EVP_SKEY *EVP_SKEY_to_provider(EVP_SKEY *skey, OSSL_LIB_CTX *libctx, EVP_SKEY_free(ret); return NULL; } + +int EVP_SKEY_get0_local_keyid(const EVP_SKEY *skey, + const unsigned char **id, size_t *len) +{ + if (skey == NULL || id == NULL || len == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (skey->skeymgmt->get_local_keyid == NULL) + return 0; + + return skey->skeymgmt->get_local_keyid(skey->keydata, id, len); +} + +int EVP_SKEY_get0_algorithm_id(const EVP_SKEY *skey, + const unsigned char **oid, size_t *oid_len, + const unsigned char **params, size_t *params_len) +{ + int ret_oid = 0, ret_params = 0; + + if (skey == NULL) { + ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (skey->skeymgmt->get_algorithm_id == NULL) + return 0; + + if (oid != NULL && oid_len != NULL) + ret_oid = 1; + if (params != NULL && params_len != NULL) + ret_params = 1; + + if (ret_oid == 0 && ret_params == 0) + return 0; + + if (ret_oid == 0 && (oid != NULL || oid_len != NULL)) + return 0; + + if (ret_params == 0 && (params != NULL || params_len != NULL)) + return 0; + + return skey->skeymgmt->get_algorithm_id(skey->keydata, + oid, oid_len, params, params_len); +} diff --git a/crypto/evp/signature.c b/crypto/evp/signature.c index f2e405aaa3226..6c6aad7e92d9e 100644 --- a/crypto/evp/signature.c +++ b/crypto/evp/signature.c @@ -41,8 +41,7 @@ static int evp_signature_up_ref(void *data) EVP_SIGNATURE *signature = (EVP_SIGNATURE *)data; int ref = 0; - CRYPTO_UP_REF(&signature->refcnt, &ref); - return 1; + return CRYPTO_UP_REF(&signature->refcnt, &ref); } static EVP_SIGNATURE *evp_signature_new(OSSL_PROVIDER *prov) diff --git a/crypto/evp/skeymgmt_meth.c b/crypto/evp/skeymgmt_meth.c index d1e5c9d4466c5..6d27ec54e39bd 100644 --- a/crypto/evp/skeymgmt_meth.c +++ b/crypto/evp/skeymgmt_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -100,6 +100,14 @@ static void *skeymgmt_from_algorithm(int name_id, if (skeymgmt->get_key_id == NULL) skeymgmt->get_key_id = OSSL_FUNC_skeymgmt_get_key_id(fns); break; + case OSSL_FUNC_SKEYMGMT_GET_LOCAL_KEYID: + if (skeymgmt->get_local_keyid == NULL) + skeymgmt->get_local_keyid = OSSL_FUNC_skeymgmt_get_local_keyid(fns); + break; + case OSSL_FUNC_SKEYMGMT_GET_ALGORITHM_ID: + if (skeymgmt->get_algorithm_id == NULL) + skeymgmt->get_algorithm_id = OSSL_FUNC_skeymgmt_get_algorithm_id(fns); + break; case OSSL_FUNC_SKEYMGMT_IMP_SETTABLE_PARAMS: if (skeymgmt->imp_params == NULL) skeymgmt->imp_params = OSSL_FUNC_skeymgmt_imp_settable_params(fns); @@ -135,8 +143,7 @@ static int evp_skeymgmt_up_ref(void *s) EVP_SKEYMGMT *skeymgmt = (EVP_SKEYMGMT *)s; int ref = 0; - CRYPTO_UP_REF(&skeymgmt->refcnt, &ref); - return 1; + return CRYPTO_UP_REF(&skeymgmt->refcnt, &ref); } static void evp_skeymgmt_free(void *s) diff --git a/crypto/ffc/ffc_params.c b/crypto/ffc/ffc_params.c index 23d3fab56b259..4f8da4c4ed0dc 100644 --- a/crypto/ffc/ffc_params.c +++ b/crypto/ffc/ffc_params.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ffc/ffc_params_generate.c b/crypto/ffc/ffc_params_generate.c index 73672740b367b..3e84a9ba7c101 100644 --- a/crypto/ffc/ffc_params_generate.c +++ b/crypto/ffc/ffc_params_generate.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -84,6 +84,13 @@ static int ffc_validate_LN(size_t L, size_t N, int type, int verify) L, N); #endif } else if (type == FFC_PARAM_TYPE_DSA) { + if (N > 512) { +#ifndef OPENSSL_NO_DSA + ERR_raise_data(ERR_LIB_DSA, DSA_R_BAD_FFC_PARAMETERS, + "N is %zu, but the maximum supported N is 512", N); +#endif + return 0; + } if (L >= 3072 && N >= 256) return 128; if (L >= 2048 && N >= 224) diff --git a/crypto/getenv.c b/crypto/getenv.c index 8ea7128864b7c..5edcecb4ee561 100644 --- a/crypto/getenv.c +++ b/crypto/getenv.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/hmac/hmac.c b/crypto/hmac/hmac.c index f12b5bf0b3649..8eaf116926fcb 100644 --- a/crypto/hmac/hmac.c +++ b/crypto/hmac/hmac.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/hmac/hmac_s390x.c b/crypto/hmac/hmac_s390x.c index 873e9752842e2..6a0287a92d49b 100644 --- a/crypto/hmac/hmac_s390x.c +++ b/crypto/hmac/hmac_s390x.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/hpke/hpke_util.c b/crypto/hpke/hpke_util.c index 3a662bc3f07c3..3ffe30ef6fd26 100644 --- a/crypto/hpke/hpke_util.c +++ b/crypto/hpke/hpke_util.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/http/http_client.c b/crypto/http/http_client.c index 34d3a2cccc9c9..db0aaf6d8bdfc 100644 --- a/crypto/http/http_client.c +++ b/crypto/http/http_client.c @@ -1242,7 +1242,7 @@ BIO *OSSL_HTTP_exchange(OSSL_HTTP_REQ_CTX *rctx, char **redirection_url) #endif ) { if (rctx->server != NULL && *rctx->server != '\0') { - BIO_snprintf(buf, sizeof(buf), "server=http%s://%s%s%s", + snprintf(buf, sizeof(buf), "server=http%s://%s%s%s", rctx->use_ssl ? "s" : "", rctx->server, rctx->port != NULL ? ":" : "", rctx->port != NULL ? rctx->port : ""); @@ -1251,7 +1251,7 @@ BIO *OSSL_HTTP_exchange(OSSL_HTTP_REQ_CTX *rctx, char **redirection_url) if (rctx->proxy != NULL) ERR_add_error_data(2, " proxy=", rctx->proxy); if (err == 0) { - BIO_snprintf(buf, sizeof(buf), " peer has disconnected%s", + snprintf(buf, sizeof(buf), " peer has disconnected%s", rctx->use_ssl ? " violating the protocol" : ", likely because it requires the use of TLS"); ERR_add_error_data(1, buf); } @@ -1264,7 +1264,7 @@ BIO *OSSL_HTTP_exchange(OSSL_HTTP_REQ_CTX *rctx, char **redirection_url) return resp; } -static int redirection_ok(int n_redir, const char *old_url, const char *new_url) +static int redirection_ok(int n_redir, int use_ssl, const char *new_url) { if (n_redir >= HTTP_VERSION_MAX_REDIRECTIONS) { ERR_raise(ERR_LIB_HTTP, HTTP_R_TOO_MANY_REDIRECTIONS); @@ -1272,7 +1272,7 @@ static int redirection_ok(int n_redir, const char *old_url, const char *new_url) } if (*new_url == '/') /* redirection to same server => same protocol */ return 1; - if (HAS_PREFIX(old_url, OSSL_HTTPS_NAME ":") && !HAS_PREFIX(new_url, OSSL_HTTPS_NAME ":")) { + if (use_ssl && !HAS_PREFIX(new_url, OSSL_HTTPS_NAME ":")) { ERR_raise(ERR_LIB_HTTP, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP); return 0; } @@ -1331,7 +1331,7 @@ BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy, } OPENSSL_free(path); if (resp == NULL && redirection_url != NULL) { - if (redirection_ok(++n_redirs, current_url, redirection_url) + if (redirection_ok(++n_redirs, use_ssl, redirection_url) && may_still_retry(max_time, &timeout)) { (void)BIO_reset(bio); OPENSSL_free(current_url); @@ -1508,7 +1508,7 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port, proxyauth = OPENSSL_malloc(len + 1); if (proxyauth == NULL) goto end; - if (BIO_snprintf(proxyauth, len + 1, "%s:%s", proxyuser, + if (snprintf(proxyauth, len + 1, "%s:%s", proxyuser, proxypass != NULL ? proxypass : "") != (int)len) goto proxy_end; diff --git a/crypto/http/http_err.c b/crypto/http/http_err.c deleted file mode 100644 index 8598dd1ff48a1..0000000000000 --- a/crypto/http/http_err.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/httperr.h" - -#ifndef OPENSSL_NO_HTTP - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA HTTP_str_reasons[] = { - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN), - "asn1 len exceeds max resp len" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_CONNECT_FAILURE), "connect failure" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_CONTENT_TYPE_MISMATCH), - "content type mismatch" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_PARSING_ASN1_LENGTH), - "error parsing asn1 length" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_PARSING_CONTENT_LENGTH), - "error parsing content length" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_PARSING_URL), "error parsing url" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_RECEIVING), "error receiving" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_ERROR_SENDING), "error sending" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_FAILED_READING_DATA), - "failed reading data" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_HEADER_PARSE_ERROR), - "header parse error" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INCONSISTENT_CONTENT_LENGTH), - "inconsistent content length" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_PORT_NUMBER), - "invalid port number" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_URL_PATH), "invalid url path" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_URL_SCHEME), - "invalid url scheme" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MAX_RESP_LEN_EXCEEDED), - "max resp len exceeded" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_ASN1_ENCODING), - "missing asn1 encoding" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_CONTENT_TYPE), - "missing content type" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_REDIRECT_LOCATION), - "missing redirect location" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RECEIVED_ERROR), "received error" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RECEIVED_WRONG_HTTP_VERSION), - "received wrong http version" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP), - "redirection from https to http" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_REDIRECTION_NOT_ENABLED), - "redirection not enabled" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_LINE_TOO_LONG), - "response line too long" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_PARSE_ERROR), - "response parse error" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RESPONSE_TOO_MANY_HDRLINES), - "response too many hdrlines" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_RETRY_TIMEOUT), "retry timeout" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_SERVER_CANCELED_CONNECTION), - "server canceled connection" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_SOCK_NOT_SUPPORTED), - "sock not supported" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_STATUS_CODE_UNSUPPORTED), - "status code unsupported" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_TLS_NOT_ENABLED), "tls not enabled" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_TOO_MANY_REDIRECTIONS), - "too many redirections" }, - { ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_UNEXPECTED_CONTENT_TYPE), - "unexpected content type" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_HTTP_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(HTTP_str_reasons[0].error) == NULL) - ERR_load_strings_const(HTTP_str_reasons); -#endif - return 1; -} -#else -NON_EMPTY_TRANSLATION_UNIT -#endif diff --git a/crypto/http/http_lib.c b/crypto/http/http_lib.c index 0c394a2d9ae2f..443f050b51087 100644 --- a/crypto/http/http_lib.c +++ b/crypto/http/http_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,7 +11,6 @@ #include #include #include -#include /* for BIO_snprintf() */ #include #include "internal/cryptlib.h" /* for ossl_assert() */ #ifndef OPENSSL_NO_SOCK @@ -83,11 +82,7 @@ int OSSL_parse_url(const char *url, char **pscheme, char **puser, char **phost, /* check for optional prefix "://" as per RFC 3986 */ scheme = scheme_end = p = url; if (ossl_isalpha(*p)) { - while (*p != '\0' - && (ossl_isalpha(*p) - || ossl_isdigit(*p) - || strchr("+-.", *p) != NULL)) - p++; + OSSL_SKIP_SCHEME(p); if (HAS_PREFIX(p, OSSL_URL_SCHEME_SUFFIX)) { scheme_end = p; p += sizeof(OSSL_URL_SCHEME_SUFFIX) - 1; @@ -181,7 +176,7 @@ int OSSL_parse_url(const char *url, char **pscheme, char **puser, char **phost, if ((*ppath = OPENSSL_malloc(buflen)) == NULL) goto err; - BIO_snprintf(*ppath, buflen, "/%s", path); + snprintf(*ppath, buflen, "/%s", path); } return 1; diff --git a/crypto/idea/i_cfb64.c b/crypto/idea/i_cfb64.c index 1d530e06063ef..9e95ed7323fe6 100644 --- a/crypto/idea/i_cfb64.c +++ b/crypto/idea/i_cfb64.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/idea/i_ofb64.c b/crypto/idea/i_ofb64.c index 6c1ced96a3aff..64f8469abc607 100644 --- a/crypto/idea/i_ofb64.c +++ b/crypto/idea/i_ofb64.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/idea/idea_local.h b/crypto/idea/idea_local.h index 6a3d6829ae1f0..ffe8f7dedd833 100644 --- a/crypto/idea/idea_local.h +++ b/crypto/idea/idea_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/info.c b/crypto/info.c index 4baece2246bb8..588374f7804db 100644 --- a/crypto/info.c +++ b/crypto/info.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -241,7 +241,7 @@ DEFINE_RUN_ONCE_STATIC(init_info_strings) { char buf[32]; - BIO_snprintf(buf, sizeof(buf), "JITTER (%d)", jent_version()); + snprintf(buf, sizeof(buf), "JITTER (%d)", jent_version()); add_seeds_string(buf); } #endif diff --git a/crypto/init.c b/crypto/init.c index 302e37f7fae33..1863894b39343 100644 --- a/crypto/init.c +++ b/crypto/init.c @@ -348,6 +348,7 @@ void ossl_cleanup_destructor(void) int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { uint64_t tmp; + uint64_t optsdone_bits = opts; int aloaddone = 0; /* Applications depend on 0 being returned when cleanup was already done */ @@ -453,8 +454,15 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) if (opts & OPENSSL_INIT_LOAD_CONFIG) { int loading = CRYPTO_THREAD_get_local(&in_init_config_local) != NULL; - /* If called recursively from OBJ_ calls, just skip it. */ - if (!loading) { + /* If called recursively from OBJ_ calls during config loading, + * we have to mask OPENSSL_INIT_LOAD_CONFIG in optsdone to not + * advertise that config loading is complete, otherwise other + * threads may proceed, e.g., to fetching from a provider that + * is not yet loaded. + */ + if (loading) { + optsdone_bits &= ~(uint64_t)OPENSSL_INIT_LOAD_CONFIG; + } else { int ret; if (!CRYPTO_THREAD_set_local(&in_init_config_local, (void *)-1)) @@ -480,7 +488,7 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) && !RUN_ONCE(&async, ossl_init_async)) return 0; - if (!CRYPTO_atomic_or(&optsdone, opts, &tmp, optsdone_lock)) + if (!CRYPTO_atomic_or(&optsdone, optsdone_bits, &tmp, optsdone_lock)) return 0; return 1; diff --git a/crypto/lhash/lhash_local.h b/crypto/lhash/lhash_local.h index 8d1b671d18de8..9a8a325b45742 100644 --- a/crypto/lhash/lhash_local.h +++ b/crypto/lhash/lhash_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/lms/lms_pubkey_decode.c b/crypto/lms/lms_pubkey_decode.c index 29ca1d44af826..0e89f089fec01 100644 --- a/crypto/lms/lms_pubkey_decode.c +++ b/crypto/lms/lms_pubkey_decode.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/loongarchcap.c b/crypto/loongarchcap.c index d259276e47625..2e92b54ecde57 100644 --- a/crypto/loongarchcap.c +++ b/crypto/loongarchcap.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/md2/md2_dgst.c b/crypto/md2/md2_dgst.c index 4b99f88bea76f..6fb24e32dd5e5 100644 --- a/crypto/md2/md2_dgst.c +++ b/crypto/md2/md2_dgst.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/md4/md4_local.h b/crypto/md4/md4_local.h index c6ccfb1c789d3..2d0360bc430e4 100644 --- a/crypto/md4/md4_local.h +++ b/crypto/md4/md4_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/md5/asm/md5-aarch64.pl b/crypto/md5/asm/md5-aarch64.pl index 6ef69715d0219..78537b4d50cc1 100755 --- a/crypto/md5/asm/md5-aarch64.pl +++ b/crypto/md5/asm/md5-aarch64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/md5/asm/md5-loongarch64.pl b/crypto/md5/asm/md5-loongarch64.pl index 40bb241290022..5f13d4639d45e 100755 --- a/crypto/md5/asm/md5-loongarch64.pl +++ b/crypto/md5/asm/md5-loongarch64.pl @@ -1,6 +1,6 @@ #! /usr/bin/env perl # Author: Min Zhou -# Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the OpenSSL license (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/md5/asm/md5-sparcv9.pl b/crypto/md5/asm/md5-sparcv9.pl index 24439e490bbd4..05f13f09f0949 100644 --- a/crypto/md5/asm/md5-sparcv9.pl +++ b/crypto/md5/asm/md5-sparcv9.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2012-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2012-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/md5/md5_local.h b/crypto/md5/md5_local.h index 581222a7912f3..a0523df6d36b2 100644 --- a/crypto/md5/md5_local.h +++ b/crypto/md5/md5_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/md5/md5_riscv.c b/crypto/md5/md5_riscv.c index 64dd1a5a26ea5..efc8d0d2ea5ee 100644 --- a/crypto/md5/md5_riscv.c +++ b/crypto/md5/md5_riscv.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,10 +11,10 @@ #include #include "arch/riscv_arch.h" -void ossl_md5_block_asm_data_order(MD5_CTX *c, const void *p, size_t num); -void ossl_md5_block_asm_data_order_zbb(MD5_CTX *c, const void *p, size_t num); -void ossl_md5_block_asm_data_order_riscv64(MD5_CTX *c, const void *p, size_t num); -void ossl_md5_block_asm_data_order(MD5_CTX *c, const void *p, size_t num) +void ossl_md5_block_asm_data_order(void *c, const void *p, size_t num); +void ossl_md5_block_asm_data_order_zbb(void *c, const void *p, size_t num); +void ossl_md5_block_asm_data_order_riscv64(void *c, const void *p, size_t num); +void ossl_md5_block_asm_data_order(void *c, const void *p, size_t num) { if (RISCV_HAS_ZBB()) { ossl_md5_block_asm_data_order_zbb(c, p, num); diff --git a/crypto/mdc2/mdc2dgst.c b/crypto/mdc2/mdc2dgst.c index 0a62569c2ba58..ea39990eb68e6 100644 --- a/crypto/mdc2/mdc2dgst.c +++ b/crypto/mdc2/mdc2dgst.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/mem.c b/crypto/mem.c index 476d6b25293e9..f5286e4aa5e28 100644 --- a/crypto/mem.c +++ b/crypto/mem.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -112,12 +112,19 @@ static void parseit(void) { char *semi = strchr(md_failstring, ';'); char *atsign; + char *end; if (semi != NULL) *semi++ = '\0'; - /* Get the count (atol will stop at the @ if there), and percentage */ - md_count = atol(md_failstring); + /* + * Get the count (parsing stops at the '@' if present), and percentage. + * Ignore an unparsable/overflowing count rather than acting on garbage. + * Validate that the count is followed by '@' or end-of-string. + */ + if (!ossl_strtol(md_failstring, &end, 10, &md_count) + || (*end != '\0' && *end != '@')) + md_count = 0; atsign = strchr(md_failstring, '@'); md_fail_percent = atsign == NULL ? 0 : (int)(atof(atsign + 1) * 100 + 0.5); @@ -147,7 +154,7 @@ static int shouldfail(void) char buff[80]; if (md_tracefd > 0) { - BIO_snprintf(buff, sizeof(buff), + snprintf(buff, sizeof(buff), "%c C%ld %%%d R%d\n", shoulditfail ? '-' : '+', md_count, md_fail_percent, roll); len = strlen(buff); @@ -179,10 +186,19 @@ void ossl_malloc_setup_failures(void) parseit(); } } - if ((cp = getenv("OPENSSL_MALLOC_FD")) != NULL) - md_tracefd = atoi(cp); - if ((cp = getenv("OPENSSL_MALLOC_SEED")) != NULL) - srandom(atoi(cp)); + if ((cp = getenv("OPENSSL_MALLOC_FD")) != NULL) { + int fd; + + if (ossl_strtoint(cp, NULL, 10, &fd) && fd >= 0) + md_tracefd = fd; + } + if ((cp = getenv("OPENSSL_MALLOC_SEED")) != NULL) { + unsigned long seed; + + /* Any value is a usable seed; just truncate it to the srandom() type. */ + if (OPENSSL_strtoul(cp, NULL, 10, &seed)) + srandom((unsigned int)seed); + } } #endif diff --git a/crypto/mem_sec.c b/crypto/mem_sec.c index a727d2008dd89..50078ab7c066e 100644 --- a/crypto/mem_sec.c +++ b/crypto/mem_sec.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2004-2014, Akamai Technologies. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/ml_dsa/asm/mldsa_intt_ppc64le.S b/crypto/ml_dsa/asm/mldsa_intt_ppc64le.S new file mode 100644 index 0000000000000..d4072915ef04a --- /dev/null +++ b/crypto/ml_dsa/asm/mldsa_intt_ppc64le.S @@ -0,0 +1,648 @@ +/* + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +/* + * Copyright IBM Corp. 2025, 2026 + * + * =================================================================================== + * Written by Danny Tsen + * + * Optimized inverse NTT implementation for ppc64le. + */ + +#define Q_NEG_INV_OFFSET 16 +#define FCONST_OFFSET 32 +#define ZETA_INTT_OFFSET 48 + +#define V_F 2 +#define V_ZETA 2 +#define V_Z0 2 +#define V_Z1 3 +#define V_Z2 4 +#define V_Z3 5 + +#include "mldsa_ppc_macros_asm.inc" + +.machine "any" +.text + +.macro SAVE_REGS + stdu 1, -352(1) + mflr 0 + std 14, 56(1) + std 15, 64(1) + std 16, 72(1) + std 17, 80(1) + std 18, 88(1) + std 19, 96(1) + std 20, 104(1) + std 21, 112(1) + li 10, 128 + li 11, 144 + li 12, 160 + li 14, 176 + li 15, 192 + li 16, 208 + stxvx 32+20, 10, 1 + stxvx 32+21, 11, 1 + stxvx 32+22, 12, 1 + stxvx 32+23, 14, 1 + stxvx 32+24, 15, 1 + stxvx 32+25, 16, 1 + li 10, 224 + li 11, 240 + li 12, 256 + li 14, 272 + stxvx 32+26, 10, 1 + stxvx 32+27, 11, 1 + stxvx 32+28, 12, 1 + stxvx 32+29, 14, 1 +.endm + +.macro RESTORE_REGS + li 10, 128 + li 11, 144 + li 12, 160 + li 14, 176 + li 15, 192 + li 16, 208 + lxvx 32+20, 10, 1 + lxvx 32+21, 11, 1 + lxvx 32+22, 12, 1 + lxvx 32+23, 14, 1 + lxvx 32+24, 15, 1 + lxvx 32+25, 16, 1 + li 10, 224 + li 11, 240 + li 12, 256 + li 14, 272 + lxvx 32+26, 10, 1 + lxvx 32+27, 11, 1 + lxvx 32+28, 12, 1 + lxvx 32+29, 14, 1 + ld 14, 56(1) + ld 15, 64(1) + ld 16, 72(1) + ld 17, 80(1) + ld 18, 88(1) + ld 19, 96(1) + ld 20, 104(1) + ld 21, 112(1) + + mtlr 0 + addi 1, 1, 352 +.endm + +/* + * Compute updated curr and peer coefficients. + * + * Input curr : V14, V15, V16, V17 + * Input peer : V18, V19, V20, V21 + * + * updated curr: V26, V27, V28, V29 + * updated peer: V6, V7, V8, V9 + */ +.macro _Compute_4Coeff + vadduwm 26, 14, 18 + vsubuwm 10, 14, 18 + vadduwm 6, 10, V_Q + + vadduwm 27, 15, 19 + vsubuwm 11, 15, 19 + vadduwm 7, 11, V_Q + + vadduwm 28, 16, 20 + vsubuwm 12, 16, 20 + vadduwm 8, 12, V_Q + + vadduwm 29, 17, 21 + vsubuwm 13, 17, 21 + vadduwm 9, 13, V_Q + + reduce_once_1x 26 + reduce_once_1x 27 + reduce_once_1x 28 + reduce_once_1x 29 +.endm + +/* + * For Len=2, + * Transpose the final coefficients of 2-2 layout to the original + * coefficient array order. + * + * updated peer : V15, V17, V19, V21 + * updated curr : V14, V16, V18, V20 + */ +.macro _delayed_writes_xxperm + xxpermdi 32+14, 32+26, 32+10, 0 + xxpermdi 32+15, 32+26, 32+10, 3 + xxpermdi 32+16, 32+27, 32+11, 0 + xxpermdi 32+17, 32+27, 32+11, 3 + xxpermdi 32+18, 32+28, 32+12, 0 + xxpermdi 32+19, 32+28, 32+12, 3 + xxpermdi 32+20, 32+29, 32+13, 0 + xxpermdi 32+21, 32+29, 32+13, 3 + delayed_writes_curr_peer 14, 15, 16, 17, 18, 19, 20, 21 +.endm + +/* + * For Len=1, + * Transpose the final coefficients of 1-1-1-1 layout to the original + * coefficient array order. + * + * updated peer : V15, V17, V19, V21 + * updated curr : V14, V16, V18, V20 + */ +.macro _delayed_writes_vmrg + vmrgew 14, 10, 26 + vmrgow 15, 10, 26 + vmrgew 16, 11, 27 + vmrgow 17, 11, 27 + vmrgew 18, 12, 28 + vmrgow 19, 12, 28 + vmrgew 20, 13, 29 + vmrgow 21, 13, 29 + delayed_writes_curr_peer 14, 15, 16, 17, 18, 19, 20, 21 +.endm + +/* + * For Layer 1, Len= 1, layer with 1-1-1-1 layout. + */ +.macro INTT_Layer1_4x + lxvd2x 32+V_Z0, 0, 14 + lxvd2x 32+V_Z1, 10, 14 + lxvd2x 32+V_Z2, 11, 14 + lxvd2x 32+V_Z3, 12, 14 + addi 14, 14, 64 + Load_vmrg_coeffs 14, 15, 16, 17, 18, 19, 20, 21 + _Compute_4Coeff + mont_mul_reduce_4x V_Z0, V_Z1, V_Z2, V_Z3 + _delayed_writes_vmrg + addi 5, 5, 128 +.endm + +/* + * For Layer 2, Len= 2, layer with 2-2 layout. + */ +.macro INTT_Layer2_4x + lxvd2x 32+V_Z0, 0, 14 + lxvd2x 32+V_Z1, 10, 14 + lxvd2x 32+V_Z2, 11, 14 + lxvd2x 32+V_Z3, 12, 14 + addi 14, 14, 64 + Load_xxperm_coeffs 14, 15, 16, 17, 18, 19, 20, 21 + _Compute_4Coeff + mont_mul_reduce_4x V_Z0, V_Z1, V_Z2, V_Z3 + _delayed_writes_xxperm + addi 5, 5, 128 +.endm + +.macro _load_curr_peer_coeffs + lxvd2x 32+18, GPR_OFFSET_P0, 5 + lxvd2x 32+19, GPR_OFFSET_P1, 5 + lxvd2x 32+20, GPR_OFFSET_P2, 5 + lxvd2x 32+21, GPR_OFFSET_P3, 5 + + lxvd2x 32+14, GPR_OFFSET_C0, 5 + lxvd2x 32+15, GPR_OFFSET_C1, 5 + lxvd2x 32+16, GPR_OFFSET_C2, 5 + lxvd2x 32+17, GPR_OFFSET_C3, 5 +.endm + +/* + * For Layer 3, 4, 5, Len=4, 8, 16 + */ +.macro INTT_Layer345_4x _vz0 _vz1 _vz2 _vz3 + _load_curr_peer_coeffs + _Compute_4Coeff + mont_mul_reduce_4x \_vz0, \_vz1, \_vz2, \_vz3 + delayed_writes_curr_peer 26, 10, 27, 11, 28, 12, 29, 13 + addi 5, 5, 128 +.endm + +/* + * For Layer 6, 7, 8, Len=32, 64, 128 + */ +.macro INTT_Layer678 _vz0 _vz1 _vz2 _vz3 + _load_curr_peer_coeffs + _Compute_4Coeff + mont_mul_reduce_4x \_vz0, \_vz1, \_vz2, \_vz3 + delayed_writes_curr_peer 26, 10, 27, 11, 28, 12, 29, 13 + addi 5, 5, 64 +.endm + +/* ===================================================================== */ +/* + * Supporting macros for Montgomery reduce loops with + * constant f=41978 (mont^2/256). + */ +.macro _Reload_4coeffs + lxvd2x 32+6, 0, 6 + lxvd2x 32+7, 10, 6 + lxvd2x 32+8, 11, 6 + lxvd2x 32+9, 12, 6 +.endm + +.macro _update_curr_coeffs_4x + stxvd2x 32+10, 0, 6 + stxvd2x 32+11, 10, 6 + stxvd2x 32+12, 11, 6 + stxvd2x 32+13, 12, 6 + addi 6, 6, 64 +.endm + +.macro POLY_Mont_Reduce_4x + _Reload_4coeffs + mont_mul_reduce_4x V_F, V_F, V_F, V_F + _update_curr_coeffs_4x + + _Reload_4coeffs + mont_mul_reduce_4x V_F, V_F, V_F, V_F + _update_curr_coeffs_4x + + _Reload_4coeffs + mont_mul_reduce_4x V_F, V_F, V_F, V_F + _update_curr_coeffs_4x + + _Reload_4coeffs + mont_mul_reduce_4x V_F, V_F, V_F, V_F + _update_curr_coeffs_4x +.endm +/* ===================================================================== */ + +/* + * mldsa_poly_ntt_inverse_ppc(int32_t *r) + * + * Compute Inverse NTT based on the following 8 layers - + * len = 1, 2, 4, 8, 16, 32, 64, 128. + * + * Each layer compute the coefficients on 2 legs, start and start + len*2 offsets. + * + * leg 1 leg 2 + * ----- ----- + * start start+len*2 + * start+next start+len*2+next + * start+next+next start+len*2+next+next + * start+next+next+next start+len*2+next+next+next + * + * Each computation loads 8 vectors, 4 for each leg. + * The final coefficient (t) from each vector of leg1 and leg2 then do the + * add/sub operations to obtain the final results. + * + * -> leg1 = leg1 + t, leg2 = leg1 - t + * + * The resulting coefficients then store back to each leg's offset. + * + * Each vector has the same corresponding zeta except len=2. + * + * len=2 has 2-2 layout which means every 2 32-bit coefficients has the same zeta. + * e.g. + * coeff vector a1 a2 a3 a4 + * zeta vector z1 z1 z2 z2 + * + * For len=2, each vector will get permuted to leg1 and leg2. Zeta is + * pre-arranged for the leg1 and leg2. After the computation, each vector needs + * to transpose back to its original 2-2 layout. + * + * For len=1, each vector will get permuted to leg1 and leg2. Zeta is + * pre-arranged for the leg1 and leg2. After the computation, each vector needs + * to transpose back to its original 1-1-1-1 layout. + * + * Registers used for offsets to coefficients, curr and peer. Each layer may + * reset these registers. + * + * R9: offset to curr + * R11: offset to R9 + next curr offset + * R15: offset to R11 + next curr offset + * R17: offset to R15 + next curr offset + * + * R10: offset to peer + * R12: offset to R10 + next peer offset + * R16: offset to R12 + next peer offset + * R18: offset to R16 + next peer offset + */ +.global mldsa_poly_ntt_inverse_ppc +.align 4 +mldsa_poly_ntt_inverse_ppc: + + SAVE_REGS + + /* load Q and Q_NEG_INV */ + addis 8,2,.mldsa_consts@toc@ha + addi 8,8,.mldsa_consts@toc@l + lvx V_Q, 0, 8 + li 10, Q_NEG_INV_OFFSET + lvx Q_NEG_INV, 10, 8 + + /* set zetas array */ + addi 14, 8, ZETA_INTT_OFFSET + +.align 4 + /* + * Layer 1. len = 1 + */ + mr 5, 3 + + li GPR_OFFSET_C0, 0 + li GPR_OFFSET_C1, 0x20 + li GPR_OFFSET_C2, 0x40 + li GPR_OFFSET_C3, 0x60 + + li GPR_OFFSET_P0, 0x10 + li GPR_OFFSET_P1, 0x30 + li GPR_OFFSET_P2, 0x50 + li GPR_OFFSET_P3, 0x70 + + INTT_Layer1_4x + INTT_Layer1_4x + INTT_Layer1_4x + INTT_Layer1_4x + INTT_Layer1_4x + INTT_Layer1_4x + INTT_Layer1_4x + INTT_Layer1_4x + +.align 4 + /* + * Layer 2. len = 2 + */ + mr 5, 3 + + INTT_Layer2_4x + INTT_Layer2_4x + INTT_Layer2_4x + INTT_Layer2_4x + INTT_Layer2_4x + INTT_Layer2_4x + INTT_Layer2_4x + INTT_Layer2_4x + +.align 4 + /* + * Layer 3. len = 4 + */ + mr 5, 3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + INTT_Layer345_4x V_Z0, V_Z1, V_Z2, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + INTT_Layer345_4x V_Z0, V_Z1, V_Z2, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + INTT_Layer345_4x V_Z0, V_Z1, V_Z2, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + INTT_Layer345_4x V_Z0, V_Z1, V_Z2, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + INTT_Layer345_4x V_Z0, V_Z1, V_Z2, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + INTT_Layer345_4x V_Z0, V_Z1, V_Z2, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + INTT_Layer345_4x V_Z0, V_Z1, V_Z2, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + INTT_Layer345_4x V_Z0, V_Z1, V_Z2, V_Z3 + +.align 4 + /* + * Layer 4. len = 8 + */ + mr 5, 3 + + li GPR_OFFSET_C1, 0x10 + li GPR_OFFSET_C2, 0x40 + li GPR_OFFSET_C3, 0x50 + + li GPR_OFFSET_P0, 0x20 + li GPR_OFFSET_P1, 0x30 + li GPR_OFFSET_P2, 0x60 + li GPR_OFFSET_P3, 0x70 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + INTT_Layer345_4x V_Z0, V_Z0, V_Z1, V_Z1 + INTT_Layer345_4x V_Z2, V_Z2, V_Z3, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + INTT_Layer345_4x V_Z0, V_Z0, V_Z1, V_Z1 + INTT_Layer345_4x V_Z2, V_Z2, V_Z3, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + INTT_Layer345_4x V_Z0, V_Z0, V_Z1, V_Z1 + INTT_Layer345_4x V_Z2, V_Z2, V_Z3, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + INTT_Layer345_4x V_Z0, V_Z0, V_Z1, V_Z1 + INTT_Layer345_4x V_Z2, V_Z2, V_Z3, V_Z3 + +.align 4 + /* + * Layer 5. len = 16 + */ + mr 5, 3 + + li GPR_OFFSET_C1, 0x10 + li GPR_OFFSET_C2, 0x20 + li GPR_OFFSET_C3, 0x30 + + li GPR_OFFSET_P0, 0x40 + li GPR_OFFSET_P1, 0x50 + li GPR_OFFSET_P2, 0x60 + li GPR_OFFSET_P3, 0x70 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + INTT_Layer345_4x V_Z0, V_Z0, V_Z0, V_Z0 + INTT_Layer345_4x V_Z1, V_Z1, V_Z1, V_Z1 + INTT_Layer345_4x V_Z2, V_Z2, V_Z2, V_Z2 + INTT_Layer345_4x V_Z3, V_Z3, V_Z3, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + INTT_Layer345_4x V_Z0, V_Z0, V_Z0, V_Z0 + INTT_Layer345_4x V_Z1, V_Z1, V_Z1, V_Z1 + INTT_Layer345_4x V_Z2, V_Z2, V_Z2, V_Z2 + INTT_Layer345_4x V_Z3, V_Z3, V_Z3, V_Z3 + +.align 4 + /* + * Layer 6. len = 32 + */ + mr 5, 3 + + li GPR_OFFSET_P0, 0x80 + li GPR_OFFSET_P1, 0x90 + li GPR_OFFSET_P2, 0xa0 + li GPR_OFFSET_P3, 0xb0 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + INTT_Layer678 V_Z0, V_Z0, V_Z0, V_Z0 + INTT_Layer678 V_Z0, V_Z0, V_Z0, V_Z0 + addi 5, 5, 0x80 + + INTT_Layer678 V_Z1, V_Z1, V_Z1, V_Z1 + INTT_Layer678 V_Z1, V_Z1, V_Z1, V_Z1 + addi 5, 5, 0x80 + + INTT_Layer678 V_Z2, V_Z2, V_Z2, V_Z2 + INTT_Layer678 V_Z2, V_Z2, V_Z2, V_Z2 + addi 5, 5, 0x80 + + INTT_Layer678 V_Z3, V_Z3, V_Z3, V_Z3 + INTT_Layer678 V_Z3, V_Z3, V_Z3, V_Z3 + +.align 4 + /* + * Layer 7. len = 64 + */ + mr 5, 3 + + li GPR_OFFSET_P0, 0x100 + li GPR_OFFSET_P1, 0x110 + li GPR_OFFSET_P2, 0x120 + li GPR_OFFSET_P3, 0x130 + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + addi 5, 5, 0x100 + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + + /* + * Layer 8. len = 128 + */ + mr 5, 3 + + li GPR_OFFSET_P0, 0x200 + li GPR_OFFSET_P1, 0x210 + li GPR_OFFSET_P2, 0x220 + li GPR_OFFSET_P3, 0x230 + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + INTT_Layer678 V_ZETA, V_ZETA, V_ZETA, V_ZETA + + /* + * Montgomery reduce loops with + * constant inverse_degree_montgomery f=41978 (mont^2/256) + * + * updated coeff = montgomery_reduce((int64_t)f * coeff) + */ + addi 10, 8, FCONST_OFFSET + lvx V_F, 0, 10 + + li 10, 16 + li 11, 32 + li 12, 48 + + mr 6, 3 + + POLY_Mont_Reduce_4x + POLY_Mont_Reduce_4x + POLY_Mont_Reduce_4x + POLY_Mont_Reduce_4x + + RESTORE_REGS + blr +.size mldsa_poly_ntt_inverse_ppc,.-mldsa_poly_ntt_inverse_ppc + +.rodata +.align 4 +.mldsa_consts: +.long ML_DSA_Q, ML_DSA_Q, ML_DSA_Q, ML_DSA_Q +.long ML_DSA_Q_NEG_INV, ML_DSA_Q_NEG_INV, ML_DSA_Q_NEG_INV, ML_DSA_Q_NEG_INV +/* Constant for INTT, f=mont^2/256 */ +.long 41978, 41978, 41978, 41978 + +.mldsa_izetas: +/* Zetas for Lane=1: setup as (3, 2, 1, 4) order */ +.long 6979993, 6403635, 4442679, 846154, 4460757, 1362209, 554416, 48306 +.long 976891, 3545687, 8196974, 6767575, 2235985, 2286327, 2939036, 420899 +.long 1104333, 3833893, 1667432, 260646, 6656817, 6470041, 426683, 1803090 +.long 975884, 7908339, 6167306, 6662682, 4856520, 8110657, 3038916, 4513516 +.long 6727783, 1799107, 7570268, 3694233, 8217573, 5366416, 3183426, 6764025 +.long 5011305, 1207385, 6423145, 8194886, 5948022, 164721, 2013608, 5925962 +.long 3724270, 3776993, 2584293, 7786281, 2831860, 1846953, 542412, 1671176 +.long 7603226, 4974386, 6880252, 6144537, 6463336, 1374803, 1279661, 2546312 +.long 7067962, 1962642, 451100, 5074302, 7143142, 1430225, 1333058, 3318210 +.long 6511298, 1050970, 2994039, 6476982, 7129923, 3548272, 3767016, 5744496 +.long 7132797, 6784443, 4325093, 5894064, 5688936, 7115408, 5538076, 2590150 +.long 3342277, 8177373, 4943130, 6644538, 8093429, 4272102, 8038120, 2437823 +.long 525098, 3595838, 3556995, 768622, 3122442, 5173371, 655327, 6348669 +.long 1613174, 522500, 7884926, 43260, 6521319, 7561383, 7479715, 7470875 +.long 3759364, 3193378, 3520352, 1197226, 5945978, 4867236, 8113420, 1235728 +.long 6136326, 3562462, 3342478, 2446433, 4972711, 4562441, 6288750, 6063917 +/* For Len=2 */ +.long 4540456, 4540456, 3628969, 3628969, 3881060, 3881060, 3019102, 3019102 +.long 1439742, 1439742, 812732, 812732, 1584928, 1584928, 7094748, 7094748 +.long 7039087, 7039087, 7064828, 7064828, 177440, 177440, 2409325, 2409325 +.long 1851402, 1851402, 5220671, 5220671, 3553272, 3553272, 8190869, 8190869 +.long 1316856, 1316856, 7620448, 7620448, 210977, 210977, 5991061, 5991061 +.long 3249728, 3249728, 6727353, 6727353, 8578, 8578, 3724342, 3724342 +.long 4421799, 4421799, 7475901, 7475901, 1100098, 1100098, 8336129, 8336129 +.long 5282425, 5282425, 7871466, 7871466, 8115473, 8115473, 3343383, 3343383 +.long 1430430, 1430430, 6527646, 6527646, 7031341, 7031341, 381987, 381987 +.long 1308169, 1308169, 22981, 22981, 1228525, 1228525, 671102, 671102 +.long 2477047, 2477047, 411027, 411027, 3693493, 3693493, 2967645, 2967645 +.long 5665122, 5665122, 6232521, 6232521, 983419, 983419, 4968207, 4968207 +.long 8253495, 8253495, 3632928, 3632928, 3157330, 3157330, 3190144, 3190144 +.long 1000202, 1000202, 4083598, 4083598, 6441103, 6441103, 1257611, 1257611 +.long 1585221, 1585221, 6203962, 6203962, 4904467, 4904467, 1452451, 1452451 +.long 3041255, 3041255, 3677745, 3677745, 1528703, 1528703, 3930395, 3930395 +/* For Lane=4 */ +.long 2797779, 2797779, 2797779, 2797779, 6308525, 6308525, 6308525, 6308525 +.long 2556880, 2556880, 2556880, 2556880, 4479693, 4479693, 4479693, 4479693 +.long 4499374, 4499374, 4499374, 4499374, 7426187, 7426187, 7426187, 7426187 +.long 7849063, 7849063, 7849063, 7849063, 7568473, 7568473, 7568473, 7568473 +.long 4680821, 4680821, 4680821, 4680821, 1600420, 1600420, 1600420, 1600420 +.long 2140649, 2140649, 2140649, 2140649, 4873154, 4873154, 4873154, 4873154 +.long 3821735, 3821735, 3821735, 3821735, 4874723, 4874723, 4874723, 4874723 +.long 1643818, 1643818, 1643818, 1643818, 1699267, 1699267, 1699267, 1699267 +.long 539299, 539299, 539299, 539299, 6031717, 6031717, 6031717, 6031717 +.long 300467, 300467, 300467, 300467, 4840449, 4840449, 4840449, 4840449 +.long 2867647, 2867647, 2867647, 2867647, 4805995, 4805995, 4805995, 4805995 +.long 3043716, 3043716, 3043716, 3043716, 3861115, 3861115, 3861115, 3861115 +.long 4464978, 4464978, 4464978, 4464978, 2537516, 2537516, 2537516, 2537516 +.long 3592148, 3592148, 3592148, 3592148, 1661693, 1661693, 1661693, 1661693 +.long 4849980, 4849980, 4849980, 4849980, 5303092, 5303092, 5303092, 5303092 +.long 8284641, 8284641, 8284641, 8284641, 5674394, 5674394, 5674394, 5674394 +/* zetas for other len */ +.long 8100412, 8100412, 8100412, 8100412, 4369920, 4369920, 4369920, 4369920 +.long 19422, 19422, 19422, 19422, 6623180, 6623180, 6623180, 6623180 +.long 3277672, 3277672, 3277672, 3277672, 1399561, 1399561, 1399561, 1399561 +.long 3859737, 3859737, 3859737, 3859737, 2118186, 2118186, 2118186, 2118186 +.long 2108549, 2108549, 2108549, 2108549, 5760665, 5760665, 5760665, 5760665 +.long 1119584, 1119584, 1119584, 1119584, 549488, 549488, 549488, 549488 +.long 4794489, 4794489, 4794489, 4794489, 1079900, 1079900, 1079900, 1079900 +.long 7356305, 7356305, 7356305, 7356305, 5654953, 5654953, 5654953, 5654953 +.long 5700314, 5700314, 5700314, 5700314, 5268920, 5268920, 5268920, 5268920 +.long 2884855, 2884855, 2884855, 2884855, 5260684, 5260684, 5260684, 5260684 +.long 2091905, 2091905, 2091905, 2091905, 359251, 359251, 359251, 359251 +.long 6026966, 6026966, 6026966, 6026966, 6554070, 6554070, 6554070, 6554070 +.long 7913949, 7913949, 7913949, 7913949, 876248, 876248, 876248, 876248 +.long 777960, 777960, 777960, 777960, 8143293, 8143293, 8143293, 8143293 +.long 518909, 518909, 518909, 518909, 2608894, 2608894, 2608894, 2608894 +.long 8354570, 8354570, 8354570, 8354570 diff --git a/crypto/ml_dsa/asm/mldsa_ntt_ppc64le.S b/crypto/ml_dsa/asm/mldsa_ntt_ppc64le.S new file mode 100644 index 0000000000000..40f12bcd68572 --- /dev/null +++ b/crypto/ml_dsa/asm/mldsa_ntt_ppc64le.S @@ -0,0 +1,700 @@ +/* + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +/* + * Copyright IBM Corp. 2025, 2026 + * + * =================================================================================== + * Written by Danny Tsen + * + * Optimized NTT implementation for ppc64le. + */ + +#define Q_NEG_INV_OFFSET 16 +#define ZETA_NTT_OFFSET 32 + +#define V_ZETA 2 +#define V_Z0 2 +#define V_Z1 3 +#define V_Z2 4 +#define V_Z3 5 + +#include "mldsa_ppc_macros_asm.inc" + +.machine "any" +.text + +.macro SAVE_REGS + stdu 1, -352(1) + mflr 0 + std 14, 56(1) + std 15, 64(1) + std 16, 72(1) + std 17, 80(1) + std 18, 88(1) + std 19, 96(1) + std 20, 104(1) + std 21, 112(1) + li 10, 128 + li 11, 144 + li 12, 160 + li 14, 176 + li 15, 192 + li 16, 208 + stxvx 32+20, 10, 1 + stxvx 32+21, 11, 1 + stxvx 32+22, 12, 1 + stxvx 32+23, 14, 1 + stxvx 32+24, 15, 1 + stxvx 32+25, 16, 1 + li 10, 224 + li 11, 240 + li 12, 256 + li 14, 272 + stxvx 32+26, 10, 1 + stxvx 32+27, 11, 1 + stxvx 32+28, 12, 1 + stxvx 32+29, 14, 1 +.endm + +.macro RESTORE_REGS + li 10, 128 + li 11, 144 + li 12, 160 + li 14, 176 + li 15, 192 + li 16, 208 + lxvx 32+20, 10, 1 + lxvx 32+21, 11, 1 + lxvx 32+22, 12, 1 + lxvx 32+23, 14, 1 + lxvx 32+24, 15, 1 + lxvx 32+25, 16, 1 + li 10, 224 + li 11, 240 + li 12, 256 + li 14, 272 + lxvx 32+26, 10, 1 + lxvx 32+27, 11, 1 + lxvx 32+28, 12, 1 + lxvx 32+29, 14, 1 + ld 14, 56(1) + ld 15, 64(1) + ld 16, 72(1) + ld 17, 80(1) + ld 18, 88(1) + ld 19, 96(1) + ld 20, 104(1) + ld 21, 112(1) + + mtlr 0 + addi 1, 1, 352 +.endm + +/* ===================================================================== */ +/* + * Compute updated curr and peer coefficients. + * updated curr = reduce_once(curr + peer); + * updated peer = mod_sub(curr, peer); + * + * Input curr : V26, V27, V28, V29 + * Input peer : V10, V11, V12, V13 + * + * updated peer : V18, V19, V20, V21 + * updated curr : V22, V23, V24, V25 + */ +.macro _update_curr_peer_coeffs + vadduwm 22, 26, 10 + mod_sub 18, 26, 10 + + vadduwm 23, 27, 11 + mod_sub 19, 27, 11 + + vadduwm 24, 28, 12 + mod_sub 20, 28, 12 + + vadduwm 25, 29, 13 + mod_sub 21, 29, 13 + + reduce_once_1x 22 + reduce_once_1x 23 + reduce_once_1x 24 + reduce_once_1x 25 +.endm + +/* + * Transpose the final coefficients of 2-2 layout to the original + * coefficient array order. + * + * updated peer : V14, V15, V16, V17 + * updated curr : V10, V11, V12, V13 + */ +.macro _delayed_writes_xxperm + xxpermdi 32+10, 32+22, 32+18, 0 + xxpermdi 32+14, 32+22, 32+18, 3 + xxpermdi 32+11, 32+23, 32+19, 0 + xxpermdi 32+15, 32+23, 32+19, 3 + xxpermdi 32+12, 32+24, 32+20, 0 + xxpermdi 32+16, 32+24, 32+20, 3 + xxpermdi 32+13, 32+25, 32+21, 0 + xxpermdi 32+17, 32+25, 32+21, 3 + delayed_writes_curr_peer 10, 14, 11, 15, 12, 16, 13, 17 +.endm + +/* + * Transpose the final coefficients of 1-1-1-1 layout to the original + * coefficient array order. + * + * updated peer : V14, V15, V16, V17 + * updated curr : V10, V11, V12, V13 + */ +.macro _delayed_writes_vmrg + vmrgew 10, 18, 22 + vmrgow 11, 18, 22 + vmrgew 12, 19, 23 + vmrgow 13, 19, 23 + vmrgew 14, 20, 24 + vmrgow 15, 20, 24 + vmrgew 16, 21, 25 + vmrgow 17, 21, 25 + delayed_writes_curr_peer 10, 11, 12, 13, 14, 15, 16, 17 +.endm + +/* + * NTT computation for layers, 1, 2, 3, 4, 5, 6. + */ +.macro _ntt_body _vz0, _vz1, _vz2, _vz3 + lxvd2x 32+6, 5, GPR_OFFSET_P0 + lxvd2x 32+7, 5, GPR_OFFSET_P1 + lxvd2x 32+8, 5, GPR_OFFSET_P2 + lxvd2x 32+9, 5, GPR_OFFSET_P3 + mont_mul_reduce_4x \_vz0, \_vz1, \_vz2, \_vz3 + lxvd2x 32+26, 5, GPR_OFFSET_C0 + lxvd2x 32+27, 5, GPR_OFFSET_C1 + lxvd2x 32+28, 5, GPR_OFFSET_C2 + lxvd2x 32+29, 5, GPR_OFFSET_C3 + + /* update curr and peer coefficients */ + _update_curr_peer_coeffs +.endm + +/* + * For Layer 1, 2, 3, Len=32, 64, 128 + */ +.macro NTT_Layer123_4x _vz0, _vz1, _vz2, _vz3 + _ntt_body \_vz0, \_vz1, \_vz2, \_vz3 + delayed_writes_curr_peer 22, 18, 23, 19, 24, 20, 25, 21 + addi 5, 5, 64 +.endm + +/* + * For Layer 4, 5, 6, Len=4, 8, 16 + */ +.macro NTT_Layer456_4x _vz0, _vz1, _vz2, _vz3 + _ntt_body \_vz0, \_vz1, \_vz2, \_vz3 + delayed_writes_curr_peer 22, 18, 23, 19, 24, 20, 25, 21 + addi 5, 5, 128 +.endm + +/* + * For Layer 7, Len= 2, layer with 2-2 layout. + */ +.macro NTT_Layer7_4x + lxvd2x 32+V_Z0, 0, 14 + lxvd2x 32+V_Z1, 10, 14 + lxvd2x 32+V_Z2, 11, 14 + lxvd2x 32+V_Z3, 12, 14 + addi 14, 14, 64 + Load_xxperm_coeffs 26, 27, 28, 29, 6, 7, 8, 9 + mont_mul_reduce_4x V_Z0, V_Z1, V_Z2, V_Z3 + _update_curr_peer_coeffs + _delayed_writes_xxperm + addi 5, 5, 128 +.endm + +/* + * For Layer 8, Len= 1, layer with 1-1-1-1 layout. + */ +.macro NTT_Layer8_4x + lxvd2x 32+V_Z0, 0, 14 + lxvd2x 32+V_Z1, 10, 14 + lxvd2x 32+V_Z2, 11, 14 + lxvd2x 32+V_Z3, 12, 14 + addi 14, 14, 64 + Load_vmrg_coeffs 26, 27, 28, 29, 6, 7, 8, 9 + mont_mul_reduce_4x V_Z0, V_Z1, V_Z2, V_Z3 + _update_curr_peer_coeffs + _delayed_writes_vmrg + addi 5, 5, 128 +.endm + +/* ===================================================================== */ +/* + * mldsa_poly_ntt_ppc(int32_t *r) + * Compute forward NTT based on the following 8 layers - + * len = 128, 64, 32, 16, 8, 4, 2, 1. + * + * Each layer compute the coefficients on 2 legs, start and start + len*2 offsets. + * + * leg 1 leg 2 + * ----- ----- + * start start+len*2 + * start+next start+len*2+next + * start+next+next start+len*2+next+next + * start+next+next+next start+len*2+next+next+next + * + * Each computation loads 8 vectors, 4 for each leg. + * The final coefficient (t) from each vector of leg1 and leg2 then do the + * add/sub operations to obtain the final results. + * + * -> leg1 = leg1 + t, leg2 = leg1 - t + * + * The resulting coefficients then store back to each leg's offset. + * + * Each vector has the same corresponding zeta except len=2. + * + * len=2 has 2-2 layout which means every 2 32-bit coefficients has the same zeta. + * e.g. + * coeff vector a1 a2 a3 a4 + * zeta vector z1 z1 z2 z2 + * + * For len=2, each vector will get permuted to leg1 and leg2. Zeta is + * pre-arranged for the leg1 and leg2. After the computation, each vector needs + * to transpose back to its original 2-2 layout. + * + * For len=1, each vector will get permuted to leg1 and leg2. Zeta is + * pre-arranged for the leg1 and leg2. After the computation, each vector needs + * to transpose back to its original 1-1-1-1 layout. + * + * Registers used for offsets to coefficients, curr and peer. Each layer may + * reset these registers. + * + * R9: offset to curr + * R11: offset to R9 + next curr offset + * R15: offset to R11 + next curr offset + * R17: offset to R15 + next curr offset + * + * R10: offset to peer + * R12: offset to R10 + next peer offset + * R16: offset to R12 + next peer offset + * R18: offset to R16 + next peer offset + */ +.global mldsa_poly_ntt_ppc +.align 4 +mldsa_poly_ntt_ppc: + + SAVE_REGS + + /* load Q and Q_NEG_INV */ + addis 8,2,.mldsa_consts@toc@ha + addi 8,8,.mldsa_consts@toc@l + lvx V_Q, 0, 8 + li 10, Q_NEG_INV_OFFSET + lvx Q_NEG_INV, 10, 8 + + /* set zetas array */ + addi 14, 8, ZETA_NTT_OFFSET + + /* + * 1. Layer 1, len = 128 + */ + mr 5, 3 + + li GPR_OFFSET_C0, 0 + li GPR_OFFSET_C1, 0x10 + li GPR_OFFSET_C2, 0x20 + li GPR_OFFSET_C3, 0x30 + + li GPR_OFFSET_P0, 0x200 + li GPR_OFFSET_P1, 0x210 + li GPR_OFFSET_P2, 0x220 + li GPR_OFFSET_P3, 0x230 + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + +.align 4 + /* + * Layer 2. len = 64 + */ + mr 5, 3 + + li GPR_OFFSET_P0, 0x100 + li GPR_OFFSET_P1, 0x110 + li GPR_OFFSET_P2, 0x120 + li GPR_OFFSET_P3, 0x130 + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + addi 5, 5, 0x100 + + lvx V_ZETA, 0, 14 + addi 14, 14, 16 + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + NTT_Layer123_4x V_ZETA, V_ZETA, V_ZETA, V_ZETA + +.align 4 + /* + * Layer 3. len = 32 + */ + mr 5, 3 + + li GPR_OFFSET_P0, 0x80 + li GPR_OFFSET_P1, 0x90 + li GPR_OFFSET_P2, 0xa0 + li GPR_OFFSET_P3, 0xb0 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + NTT_Layer123_4x V_Z0, V_Z0, V_Z0, V_Z0 + NTT_Layer123_4x V_Z0, V_Z0, V_Z0, V_Z0 + addi 5, 5, 0x80 + + NTT_Layer123_4x V_Z1, V_Z1, V_Z1, V_Z1 + NTT_Layer123_4x V_Z1, V_Z1, V_Z1, V_Z1 + addi 5, 5, 0x80 + + NTT_Layer123_4x V_Z2, V_Z2, V_Z2, V_Z2 + NTT_Layer123_4x V_Z2, V_Z2, V_Z2, V_Z2 + addi 5, 5, 0x80 + + NTT_Layer123_4x V_Z3, V_Z3, V_Z3, V_Z3 + NTT_Layer123_4x V_Z3, V_Z3, V_Z3, V_Z3 + +.align 4 + /* + * Layer 4. len = 16 + */ + mr 5, 3 + + li GPR_OFFSET_P0, 0x40 + li GPR_OFFSET_P1, 0x50 + li GPR_OFFSET_P2, 0x60 + li GPR_OFFSET_P3, 0x70 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + NTT_Layer456_4x V_Z0, V_Z0, V_Z0, V_Z0 + NTT_Layer456_4x V_Z1, V_Z1, V_Z1, V_Z1 + NTT_Layer456_4x V_Z2, V_Z2, V_Z2, V_Z2 + NTT_Layer456_4x V_Z3, V_Z3, V_Z3, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + NTT_Layer456_4x V_Z0, V_Z0, V_Z0, V_Z0 + NTT_Layer456_4x V_Z1, V_Z1, V_Z1, V_Z1 + NTT_Layer456_4x V_Z2, V_Z2, V_Z2, V_Z2 + NTT_Layer456_4x V_Z3, V_Z3, V_Z3, V_Z3 + +.align 4 + /* + * Layer 5. len = 8 + */ + mr 5, 3 + + li GPR_OFFSET_C1, 0x10 + li GPR_OFFSET_C2, 0x40 + li GPR_OFFSET_C3, 0x50 + + li GPR_OFFSET_P0, 0x20 + li GPR_OFFSET_P1, 0x30 + li GPR_OFFSET_P2, 0x60 + li GPR_OFFSET_P3, 0x70 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + NTT_Layer456_4x V_Z0, V_Z0, V_Z1, V_Z1 + NTT_Layer456_4x V_Z2, V_Z2, V_Z3, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + NTT_Layer456_4x V_Z0, V_Z0, V_Z1, V_Z1 + NTT_Layer456_4x V_Z2, V_Z2, V_Z3, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + NTT_Layer456_4x V_Z0, V_Z0, V_Z1, V_Z1 + NTT_Layer456_4x V_Z2, V_Z2, V_Z3, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + NTT_Layer456_4x V_Z0, V_Z0, V_Z1, V_Z1 + NTT_Layer456_4x V_Z2, V_Z2, V_Z3, V_Z3 + +.align 4 + /* + * Layer 6. len = 4 + */ + mr 5, 3 + + li GPR_OFFSET_C1, 0x20 + li GPR_OFFSET_C2, 0x40 + li GPR_OFFSET_C3, 0x60 + + li GPR_OFFSET_P0, 0x10 + li GPR_OFFSET_P1, 0x30 + li GPR_OFFSET_P2, 0x50 + li GPR_OFFSET_P3, 0x70 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + NTT_Layer456_4x V_Z0, V_Z1, V_Z2, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + NTT_Layer456_4x V_Z0, V_Z1, V_Z2, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + NTT_Layer456_4x V_Z0, V_Z1, V_Z2, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + NTT_Layer456_4x V_Z0, V_Z1, V_Z2, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + NTT_Layer456_4x V_Z0, V_Z1, V_Z2, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + NTT_Layer456_4x V_Z0, V_Z1, V_Z2, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + NTT_Layer456_4x V_Z0, V_Z1, V_Z2, V_Z3 + + Load_4zetas V_Z0, V_Z1, V_Z2, V_Z3 + NTT_Layer456_4x V_Z0, V_Z1, V_Z2, V_Z3 + +.align 4 + /* + * Layer 7. len = 2 + * Layer 7 uses the same offset as Layer 6. + */ + mr 5, 3 + + NTT_Layer7_4x + NTT_Layer7_4x + NTT_Layer7_4x + NTT_Layer7_4x + NTT_Layer7_4x + NTT_Layer7_4x + NTT_Layer7_4x + NTT_Layer7_4x + +.align 4 + /* + * Layer 8. len = 1 + * Layer 8 uses the same offset as Layer 6. + */ + mr 5, 3 + + NTT_Layer8_4x + NTT_Layer8_4x + NTT_Layer8_4x + NTT_Layer8_4x + NTT_Layer8_4x + NTT_Layer8_4x + NTT_Layer8_4x + NTT_Layer8_4x + + RESTORE_REGS + blr +.size mldsa_poly_ntt_ppc,.-mldsa_poly_ntt_ppc + +/* ===================================================================== */ +.macro POLY_SAVE_REGS + stdu 1, -256(1) + mflr 0 + li 9, 128 + li 10, 144 + li 11, 160 + li 12, 176 + stxvx 32+20, 9, 1 + stxvx 32+21, 10, 1 + stxvx 32+22, 11, 1 + stxvx 32+23, 12, 1 + li 9, 192 + li 10, 208 + stxvx 32+24, 9, 1 + stxvx 32+25, 10, 1 +.endm + +.macro POLY_RESTORE_REGS + li 9, 128 + li 10, 144 + li 11, 160 + li 12, 176 + lxvx 32+20, 9, 1 + lxvx 32+21, 10, 1 + lxvx 32+22, 11, 1 + lxvx 32+23, 12, 1 + li 9, 192 + li 10, 208 + lxvx 32+24, 9, 1 + lxvx 32+25, 10, 1 + + mtlr 0 + addi 1, 1, 256 +.endm + +.macro _Load_poly_points_vectors + lxvd2x 32+2, 0, 4 + lxvd2x 32+3, 10, 4 + lxvd2x 32+4, 11, 4 + lxvd2x 32+5, 12, 4 + + lxvd2x 32+6, 0, 5 + lxvd2x 32+7, 10, 5 + lxvd2x 32+8, 11, 5 + lxvd2x 32+9, 12, 5 + addi 4, 4, 64 + addi 5, 5, 64 +.endm + +.macro _update_poly_coeffs + stxvd2x 32+10, 0, 3 + stxvd2x 32+11, 10, 3 + stxvd2x 32+12, 11, 3 + stxvd2x 32+13, 12, 3 + addi 3, 3, 64 +.endm + +.macro _poly_ntt_mul_4x + _Load_poly_points_vectors + //_Mont_point_mul + Mont_scalar_mul_4x 2, 3, 4, 5 + Mont_reduce_4x + _update_poly_coeffs +.endm + +/* + * mldsa_poly_ntt_mult(poly *c, const poly *a, const poly *b) + */ +.global mldsa_poly_ntt_mult_ppc +.align 4 +mldsa_poly_ntt_mult_ppc: + + POLY_SAVE_REGS + + /* load Q and Q_NEG_INV */ + addis 8,2,.mldsa_consts@toc@ha + addi 8,8,.mldsa_consts@toc@l + lvx V_Q, 0, 8 + li 10, 16 + lvx Q_NEG_INV, 10, 8 + + /* + * Montgomery reduce loops for a * b + * + * c[j] = montgomery_reduce(a[j] * b[j]) + */ + li 10, 16 + li 11, 32 + li 12, 48 + + _poly_ntt_mul_4x + _poly_ntt_mul_4x + _poly_ntt_mul_4x + _poly_ntt_mul_4x + _poly_ntt_mul_4x + _poly_ntt_mul_4x + _poly_ntt_mul_4x + _poly_ntt_mul_4x + _poly_ntt_mul_4x + _poly_ntt_mul_4x + _poly_ntt_mul_4x + _poly_ntt_mul_4x + _poly_ntt_mul_4x + _poly_ntt_mul_4x + _poly_ntt_mul_4x + _poly_ntt_mul_4x + + POLY_RESTORE_REGS + blr +.size mldsa_poly_ntt_mult_ppc,.-mldsa_poly_ntt_mult_ppc +/* ===================================================================== */ + +.rodata +.align 4 +.mldsa_consts: +.long ML_DSA_Q, ML_DSA_Q, ML_DSA_Q, ML_DSA_Q +.long ML_DSA_Q_NEG_INV, ML_DSA_Q_NEG_INV, ML_DSA_Q_NEG_INV, ML_DSA_Q_NEG_INV + +/* zetas */ +.mldsa_zetas: +/* For Len=128, 64, 32, 16, 8 */ +.long 25847, 25847, 25847, 25847, 5771523, 5771523, 5771523, 5771523 +.long 7861508, 7861508, 7861508, 7861508, 237124, 237124, 237124, 237124 +.long 7602457, 7602457, 7602457, 7602457, 7504169, 7504169, 7504169, 7504169 +.long 466468, 466468, 466468, 466468, 1826347, 1826347, 1826347, 1826347 +.long 2353451, 2353451, 2353451, 2353451, 8021166, 8021166, 8021166, 8021166 +.long 6288512, 6288512, 6288512, 6288512, 3119733, 3119733, 3119733, 3119733 +.long 5495562, 5495562, 5495562, 5495562, 3111497, 3111497, 3111497, 3111497 +.long 2680103, 2680103, 2680103, 2680103, 2725464, 2725464, 2725464, 2725464 +.long 1024112, 1024112, 1024112, 1024112, 7300517, 7300517, 7300517, 7300517 +.long 3585928, 3585928, 3585928, 3585928, 7830929, 7830929, 7830929, 7830929 +.long 7260833, 7260833, 7260833, 7260833, 2619752, 2619752, 2619752, 2619752 +.long 6271868, 6271868, 6271868, 6271868, 6262231, 6262231, 6262231, 6262231 +.long 4520680, 4520680, 4520680, 4520680, 6980856, 6980856, 6980856, 6980856 +.long 5102745, 5102745, 5102745, 5102745, 1757237, 1757237, 1757237, 1757237 +.long 8360995, 8360995, 8360995, 8360995, 4010497, 4010497, 4010497, 4010497 +.long 280005, 280005, 280005, 280005 +/*For Len=4 */ +.long 2706023, 2706023, 2706023, 2706023, 95776, 95776, 95776, 95776 +.long 3077325, 3077325, 3077325, 3077325, 3530437, 3530437, 3530437, 3530437 +.long 6718724, 6718724, 6718724, 6718724, 4788269, 4788269, 4788269, 4788269 +.long 5842901, 5842901, 5842901, 5842901, 3915439, 3915439, 3915439, 3915439 +.long 4519302, 4519302, 4519302, 4519302, 5336701, 5336701, 5336701, 5336701 +.long 3574422, 3574422, 3574422, 3574422, 5512770, 5512770, 5512770, 5512770 +.long 3539968, 3539968, 3539968, 3539968, 8079950, 8079950, 8079950, 8079950 +.long 2348700, 2348700, 2348700, 2348700, 7841118, 7841118, 7841118, 7841118 +.long 6681150, 6681150, 6681150, 6681150, 6736599, 6736599, 6736599, 6736599 +.long 3505694, 3505694, 3505694, 3505694, 4558682, 4558682, 4558682, 4558682 +.long 3507263, 3507263, 3507263, 3507263, 6239768, 6239768, 6239768, 6239768 +.long 6779997, 6779997, 6779997, 6779997, 3699596, 3699596, 3699596, 3699596 +.long 811944, 811944, 811944, 811944, 531354, 531354, 531354, 531354 +.long 954230, 954230, 954230, 954230, 3881043, 3881043, 3881043, 3881043 +.long 3900724, 3900724, 3900724, 3900724, 5823537, 5823537, 5823537, 5823537 +.long 2071892, 2071892, 2071892, 2071892, 5582638, 5582638, 5582638, 5582638 +/* For Len=2 */ +.long 4450022, 4450022, 6851714, 6851714, 4702672, 4702672, 5339162, 5339162 +.long 6927966, 6927966, 3475950, 3475950, 2176455, 2176455, 6795196, 6795196 +.long 7122806, 7122806, 1939314, 1939314, 4296819, 4296819, 7380215, 7380215 +.long 5190273, 5190273, 5223087, 5223087, 4747489, 4747489, 126922, 126922 +.long 3412210, 3412210, 7396998, 7396998, 2147896, 2147896, 2715295, 2715295 +.long 5412772, 5412772, 4686924, 4686924, 7969390, 7969390, 5903370, 5903370 +.long 7709315, 7709315, 7151892, 7151892, 8357436, 8357436, 7072248, 7072248 +.long 7998430, 7998430, 1349076, 1349076, 1852771, 1852771, 6949987, 6949987 +.long 5037034, 5037034, 264944, 264944, 508951, 508951, 3097992, 3097992 +.long 44288, 44288, 7280319, 7280319, 904516, 904516, 3958618, 3958618 +.long 4656075, 4656075, 8371839, 8371839, 1653064, 1653064, 5130689, 5130689 +.long 2389356, 2389356, 8169440, 8169440, 759969, 759969, 7063561, 7063561 +.long 189548, 189548, 4827145, 4827145, 3159746, 3159746, 6529015, 6529015 +.long 5971092, 5971092, 8202977, 8202977, 1315589, 1315589, 1341330, 1341330 +.long 1285669, 1285669, 6795489, 6795489, 7567685, 7567685, 6940675, 6940675 +.long 5361315, 5361315, 4499357, 4499357, 4751448, 4751448, 3839961, 3839961 +/* Setup zetas for Len=1 as (3, 2, 1, 4) order */ +.long 2316500, 2091667, 3817976, 3407706, 5933984, 5037939, 4817955, 2244091 +.long 7144689, 266997, 3513181, 2434439, 7183191, 4860065, 5187039, 4621053 +.long 909542, 900702, 819034, 1859098, 8337157, 495491, 7857917, 6767243 +.long 2031748, 7725090, 3207046, 5257975, 7611795, 4823422, 4784579, 7855319 +.long 5942594, 342297, 4108315, 286988, 1735879, 3437287, 203044, 5038140 +.long 5790267, 2842341, 1265009, 2691481, 2486353, 4055324, 1595974, 1247620 +.long 2635921, 4613401, 4832145, 1250494, 1903435, 5386378, 7329447, 1869119 +.long 5062207, 7047359, 6950192, 1237275, 3306115, 7929317, 6417775, 1312455 +.long 5834105, 7100756, 7005614, 1917081, 2235880, 1500165, 3406031, 777191 +.long 6709241, 7838005, 6533464, 5548557, 594136, 5796124, 4603424, 4656147 +.long 2454455, 6366809, 8215696, 2432395, 185531, 1957272, 7173032, 3369112 +.long 1616392, 5196991, 3014001, 162844, 4686184, 810149, 6581310, 1652634 +.long 3866901, 5341501, 269760, 3523897, 1717735, 2213111, 472078, 7404533 +.long 6577327, 7953734, 1910376, 1723600, 8119771, 6712985, 4546524, 7276084 +.long 7959518, 5441381, 6094090, 6144432, 1612842, 183443, 4834730, 7403526 +.long 8332111, 7826001, 7018208, 3919660, 7534263, 3937738, 1976782, 1400424 diff --git a/crypto/ml_dsa/asm/mldsa_ppc_macros_asm.inc b/crypto/ml_dsa/asm/mldsa_ppc_macros_asm.inc new file mode 100644 index 0000000000000..3f386db5634d5 --- /dev/null +++ b/crypto/ml_dsa/asm/mldsa_ppc_macros_asm.inc @@ -0,0 +1,228 @@ +/* + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +/* + * Copyright IBM Corp. 2025, 2026 + * + * =================================================================================== + * Written by Danny Tsen + */ + +#define ML_DSA_Q 8380417 /* The modulus is 23 bits (2^23 - 2^13 + 1) */ +#define ML_DSA_Q_NEG_INV 4236238847 /* Inverse of -q modulo 2^32 */ + +#define Q_NEG_INV 0 +#define V_Q 1 + +#define GPR_OFFSET_C0 9 +#define GPR_OFFSET_C1 11 +#define GPR_OFFSET_C2 15 +#define GPR_OFFSET_C3 17 + +#define GPR_OFFSET_P0 10 +#define GPR_OFFSET_P1 12 +#define GPR_OFFSET_P2 16 +#define GPR_OFFSET_P3 18 + +/* ===================================================================== */ +/* + * For NTT implementation, initial peer and curr vectors setup as + * peer = V6, V7, V8, V9 + * curr = V26, V27, V28, V29 + * + * For Inverse NTT implementation, initial peer and curr vectors setup as + * peer = V18, V19, V20, V21 + * curr = V14, V15, V16, V17 + */ +/* + * Load coefficients with 1-1-1-1 layout, + * each load contains 2 curr and 2 peer elements. + * -> curr1 peer1 curr2 peer2 + * curr3 peer3 curr4 peer4 + * vmrgew and vmrgow -> + * curr vector contains 4 curr elements and + * peer vector contains 4 peer elements + * + * In order to do the coefficients computation, zeta vector will arrange + * in the proper order to match the multiplication. + */ +.macro Load_vmrg_coeffs _c1, _c2, _c3, _c4, _p1, _p2, _p3, _p4 + lxvd2x 32+10, GPR_OFFSET_C0, 5 + lxvd2x 32+11, GPR_OFFSET_P0, 5 + vmrgew \_p1, 10, 11 + vmrgow \_c1, 10, 11 + lxvd2x 32+12, GPR_OFFSET_C1, 5 + lxvd2x 32+13, GPR_OFFSET_P1, 5 + vmrgew \_p2, 12, 13 + vmrgow \_c2, 12, 13 + lxvd2x 32+10, GPR_OFFSET_C2, 5 + lxvd2x 32+11, GPR_OFFSET_P2, 5 + vmrgew \_p3, 10, 11 + vmrgow \_c3, 10, 11 + lxvd2x 32+12, GPR_OFFSET_C3, 5 + lxvd2x 32+13, GPR_OFFSET_P3, 5 + vmrgew \_p4, 12, 13 + vmrgow \_c4, 12, 13 +.endm + +/* + * Load coefficients with 2-2 layout, + * each load contains 4 curr and 4 peer elements + * -> curr1 curr2 peer1 peer2 + * curr3 curr3 pee43 peer4 + * xxpermidi -> 4 curr elements and 4 peer elements + * curr vector contains 4 curr elements and + * peer vector contains 4 peer elements + * + * In order to do the coefficients computation, zeta vector will arrange + * in the proper order to match the multiplication. + */ +.macro Load_xxperm_coeffs _c1, _c2, _c3, _c4, _p1, _p2, _p3, _p4 + lxvd2x 1, GPR_OFFSET_C0, 5 + lxvd2x 2, GPR_OFFSET_P0, 5 + xxpermdi 32+\_p1, 1, 2, 3 + xxpermdi 32+\_c1, 1, 2, 0 + lxvd2x 3, GPR_OFFSET_C1, 5 + lxvd2x 4, GPR_OFFSET_P1, 5 + xxpermdi 32+\_p2, 3, 4, 3 + xxpermdi 32+\_c2, 3, 4, 0 + lxvd2x 1, GPR_OFFSET_C2, 5 + lxvd2x 2, GPR_OFFSET_P2, 5 + xxpermdi 32+\_p3, 1, 2, 3 + xxpermdi 32+\_c3, 1, 2, 0 + lxvd2x 3, GPR_OFFSET_C3, 5 + lxvd2x 4, GPR_OFFSET_P3, 5 + xxpermdi 32+\_p4, 3, 4, 3 + xxpermdi 32+\_c4, 3, 4, 0 +.endm + +/* + * Reduces x mod q in constant time + * i.e. return x < q ? x : x - q; + * @param x Where x is assumed to be in the range 0 <= x < 2*q + * @returns the difference in the range 0..q-1 + */ +.macro reduce_once_1x _vt + vsubuwm 16, \_vt, V_Q + vcmpgtsw 17, V_Q, \_vt + xxsel 32+\_vt, 32+16, 32+\_vt, 32+17 +.endm + +/* + * Calculate The positive value of (a-b) mod q in constant time. + * + * a - b mod q gives a value in the range -(q-1)..(q-1) + * By adding q we get a range of 1..(2q-1). + * Reducing this once then gives the range 0..q-1 + * + * returns The value (q + a - b) mod q + */ +.macro mod_sub _x _a _b + vadduwm 14, \_a, V_Q + vsubuwm \_x, 14, \_b + reduce_once_1x \_x +.endm + +/* Delayed writes resulting curr and peer coefficients */ +.macro delayed_writes_curr_peer _c1, _p1, _c2, _p2, _c3, _p3, _c4, _p4 + stxvd2x 32+\_c1, GPR_OFFSET_C0, 5 + stxvd2x 32+\_p1, GPR_OFFSET_P0, 5 + stxvd2x 32+\_c2, GPR_OFFSET_C1, 5 + stxvd2x 32+\_p2, GPR_OFFSET_P1, 5 + stxvd2x 32+\_c3, GPR_OFFSET_C2, 5 + stxvd2x 32+\_p3, GPR_OFFSET_P2, 5 + stxvd2x 32+\_c4, GPR_OFFSET_C3, 5 + stxvd2x 32+\_p4, GPR_OFFSET_P3, 5 +.endm + +.macro Load_4zetas _vz0, _vz1, _vz2, _vz3 + lvx \_vz0, 0, 14 + addi 14, 14, 16 + lvx \_vz1, 0, 14 + addi 14, 14, 16 + lvx \_vz2, 0, 14 + addi 14, 14, 16 + lvx \_vz3, 0, 14 + addi 14, 14, 16 +.endm + +/* + * Montgomery multiply: + * a = zeta * peer or a = b * c + * Multiply of 2 numbers in montgomery form, in the range 0...(2^32)*q + */ +.macro Mont_scalar_mul_4x _vz0 _vz1 _vz2 _vz3 + vmuleuw 10, 6, \_vz0 + vmulouw 11, 6, \_vz0 + vmuleuw 12, 7, \_vz1 + vmulouw 13, 7, \_vz1 + vmuleuw 14, 8, \_vz2 + vmulouw 15, 8, \_vz2 + vmuleuw 16, 9, \_vz3 + vmulouw 17, 9, \_vz3 +.endm + +/* + * @brief When multiplying 2 numbers mod q that are in montgomery form, the + * product mod q needs to be multiplied by 2^-32 to be in montgomery form. + * See FIPS 204, Algorithm 49, MontgomeryReduce() + * Note it is slightly different due to the input range being positive + * + * @param a is the result of a multiply of 2 numbers in montgomery form, + * in the range 0...(2^32)*q + * @returns The Montgomery form of 'a' with multiplier 2^32 in the range 0..q-1 + * The result is congruent to x * 2^-32 mod q + */ +.macro Mont_reduce_4x + vmulouw 18, 10, Q_NEG_INV + vmulouw 19, 11, Q_NEG_INV + vmulouw 20, 12, Q_NEG_INV + vmulouw 21, 13, Q_NEG_INV + vmulouw 22, 14, Q_NEG_INV + vmulouw 23, 15, Q_NEG_INV + vmulouw 24, 16, Q_NEG_INV + vmulouw 25, 17, Q_NEG_INV + + vmulouw 18, 18, V_Q + vmulouw 19, 19, V_Q + vmulouw 20, 20, V_Q + vmulouw 21, 21, V_Q + vmulouw 22, 22, V_Q + vmulouw 23, 23, V_Q + vmulouw 24, 24, V_Q + vmulouw 25, 25, V_Q + + vaddudm 18, 18, 10 + vaddudm 19, 19, 11 + vaddudm 20, 20, 12 + vaddudm 21, 21, 13 + vaddudm 22, 22, 14 + vaddudm 23, 23, 15 + vaddudm 24, 24, 16 + vaddudm 25, 25, 17 + + vmrgew 10, 18, 19 + vmrgew 11, 20, 21 + vmrgew 12, 22, 23 + vmrgew 13, 24, 25 + + reduce_once_1x 10 + reduce_once_1x 11 + reduce_once_1x 12 + reduce_once_1x 13 +.endm + +/* + * ----------------------------------- + * mont_mul_reduce_4x(_vz0, _vz1, _vz2, _vz3) + */ +.macro mont_mul_reduce_4x _vz0 _vz1 _vz2 _vz3 + Mont_scalar_mul_4x \_vz0, \_vz1, \_vz2, \_vz3 + Mont_reduce_4x +.endm +/* ===================================================================== */ diff --git a/crypto/ml_dsa/build.info b/crypto/ml_dsa/build.info index e41867f573974..3c74aef2f7a05 100644 --- a/crypto/ml_dsa/build.info +++ b/crypto/ml_dsa/build.info @@ -8,6 +8,12 @@ $ML_DSA_ASM= IF[{- !$disabled{asm} -}] $ML_DSA_ASM_x86_64=ml_dsa_ntt-x86_64.s + IF[{- $target{sys_id} ne "AIX" && $target{sys_id} ne "MACOSX" -}] + $ML_DSA_ASM_ppc64=asm/mldsa_ntt_ppc64le.S asm/mldsa_intt_ppc64le.S + ENDIF + + # Now that we have defined all the arch specific variables, use the + # appropriate one, and define the appropriate macros IF[$ML_DSA_ASM_{- $target{asm_arch} -}] $ML_DSA_ASM=$ML_DSA_ASM_{- $target{asm_arch} -} ENDIF @@ -27,9 +33,6 @@ IF[{- !$disabled{'ml-dsa'} -}] ENDIF ENDIF -DEFINE[../../libcrypto]=$ML_DSA_DEF -DEFINE[../../providers/libfips.a]=$ML_DSA_DEF - IF[{- !$disabled{'ml-dsa'} -}] SOURCE[../../libcrypto]=$COMMON $ML_DSA_ASM $ML_DSA_VX SOURCE[../../providers/libfips.a]=$COMMON $ML_DSA_ASM $ML_DSA_VX diff --git a/crypto/ml_dsa/ml_dsa_encoders.c b/crypto/ml_dsa/ml_dsa_encoders.c index de93f404fa95a..7d04d867c2166 100644 --- a/crypto/ml_dsa/ml_dsa_encoders.c +++ b/crypto/ml_dsa/ml_dsa_encoders.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -935,6 +935,9 @@ int ossl_ml_dsa_sig_encode(const ML_DSA_SIG *sig, const ML_DSA_PARAMS *params, ret = 1; err: WPACKET_finish(&pkt); + /* Erase any partial signature output on failure */ + if (ret == 0) + OPENSSL_cleanse(out, params->sig_len); return ret; } diff --git a/crypto/ml_dsa/ml_dsa_hash.h b/crypto/ml_dsa/ml_dsa_hash.h index 1b7ce63516070..db450c7fd5c0d 100644 --- a/crypto/ml_dsa/ml_dsa_hash.h +++ b/crypto/ml_dsa/ml_dsa_hash.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ml_dsa/ml_dsa_key.c b/crypto/ml_dsa/ml_dsa_key.c index ea5f4ee4dab61..e1b4f3bb738b4 100644 --- a/crypto/ml_dsa/ml_dsa_key.c +++ b/crypto/ml_dsa/ml_dsa_key.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -365,10 +365,15 @@ static int public_from_private(const ML_DSA_KEY *key, EVP_MD_CTX *md_ctx, /* Compress t */ vector_power2_round(&t, t1, t0); - /* Zeroize secret */ - vector_zero(&s1_ntt); ret = 1; err: + /* + * The low bits of |t| are private and |s1_ntt| is secret, wipe both. + * The trailing |a_ntt| matrix is not wiped: per FIPS 204 section 3.6.3 + * the matrix A is easily computed from the public key and does not + * require any special protections. + */ + OPENSSL_cleanse(polys, (k + l) * sizeof(*polys)); OPENSSL_free(polys); return ret; } @@ -390,6 +395,7 @@ int ossl_ml_dsa_key_public_from_private(ML_DSA_KEY *key) && shake_xof(md_ctx, key->shake256_md, key->pub_encoding, key->params->pk_len, key->tr, sizeof(key->tr)); + vector_zero(&t0); vector_free(&t0); EVP_MD_CTX_free(md_ctx); return ret; @@ -422,7 +428,7 @@ int ossl_ml_dsa_key_pairwise_check(const ML_DSA_KEY *key) ret = vector_equal(&t1, &key->t1) && vector_equal(&t0, &key->t0); err: EVP_MD_CTX_free(md_ctx); - OPENSSL_free(polys); + OPENSSL_clear_free(polys, 2 * k * sizeof(*polys)); return ret; } @@ -500,6 +506,11 @@ int ossl_ml_dsa_generate_key(ML_DSA_KEY *out) if (sk == NULL) { ret = keygen_internal(out); } else { + /* + * A constant-time comparison is unnecessary here since this check + * is only performed during key generation and is not exposed to + * timing attacks. + */ if ((ret = keygen_internal(out)) != 0 && memcmp(out->priv_encoding, sk, out->params->sk_len) != 0) { ret = 0; diff --git a/crypto/ml_dsa/ml_dsa_key.h b/crypto/ml_dsa/ml_dsa_key.h index 6defd090feded..4752475a66b74 100644 --- a/crypto/ml_dsa/ml_dsa_key.h +++ b/crypto/ml_dsa/ml_dsa_key.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ml_dsa/ml_dsa_local.h b/crypto/ml_dsa/ml_dsa_local.h index 23e2db247c1c1..a47355e7b4cbb 100644 --- a/crypto/ml_dsa/ml_dsa_local.h +++ b/crypto/ml_dsa/ml_dsa_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ml_dsa/ml_dsa_matrix.c b/crypto/ml_dsa/ml_dsa_matrix.c index c7ff59845217f..94fd16936c8b5 100644 --- a/crypto/ml_dsa/ml_dsa_matrix.c +++ b/crypto/ml_dsa/ml_dsa_matrix.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ +#include #include "ml_dsa_local.h" #include "ml_dsa_vector.h" #include "ml_dsa_matrix.h" @@ -25,15 +26,16 @@ void ossl_ml_dsa_matrix_mult_vector(const MATRIX *a, const VECTOR *s, { size_t i, j; POLY *poly = a->m_poly; + POLY product; vector_zero(t); for (i = 0; i < a->k; i++) { for (j = 0; j < a->l; j++) { - POLY product; - ossl_ml_dsa_poly_ntt_mult(poly++, &s->poly[j], &product); poly_add(&product, &t->poly[i], &t->poly[i]); } } + + OPENSSL_cleanse(&product, sizeof(product)); } diff --git a/crypto/ml_dsa/ml_dsa_matrix.h b/crypto/ml_dsa/ml_dsa_matrix.h index e5f4ebf6d932f..2318ce4de479b 100644 --- a/crypto/ml_dsa/ml_dsa_matrix.h +++ b/crypto/ml_dsa/ml_dsa_matrix.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ml_dsa/ml_dsa_ntt.c b/crypto/ml_dsa/ml_dsa_ntt.c index 3f5ebd520670c..17a63802f3979 100644 --- a/crypto/ml_dsa/ml_dsa_ntt.c +++ b/crypto/ml_dsa/ml_dsa_ntt.c @@ -227,6 +227,34 @@ static void poly_ntt_inverse_avx2_wrapper(POLY *p) } #endif +/* + * PPC64le wrapper functions. + */ +#if !defined(OPENSSL_NO_ASM) && defined(_ARCH_PPC64) && (defined(__LITTLE_ENDIAN__) || (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) +#define MLDSA_NTT_PPC_ASM +#include "arch/ppc_arch.h" +#endif + +#if defined(MLDSA_NTT_PPC_ASM) +extern void mldsa_poly_ntt_mult_ppc(POLY *out, const POLY *lhs, const POLY *rhs); +static void poly_ntt_mult_ppc64le_wrapper(const POLY *lhs, const POLY *rhs, POLY *out) +{ + mldsa_poly_ntt_mult_ppc(out, lhs, rhs); +} + +extern void mldsa_poly_ntt_ppc(uint32_t *p); +static void poly_ntt_ppc64le_wrapper(POLY *p) +{ + mldsa_poly_ntt_ppc(p->coeff); +} + +extern void mldsa_poly_ntt_inverse_ppc(uint32_t *p); +static void poly_ntt_inverse_ppc64le_wrapper(POLY *p) +{ + mldsa_poly_ntt_inverse_ppc(p->coeff); +} +#endif + /* * Initialize NTT function pointers to AVX2 implementations if available. * Scalar implementations are used by default. @@ -240,6 +268,15 @@ static void ml_dsa_ntt_init(void) poly_ntt_mult_impl = poly_ntt_mult_avx2_wrapper; } #endif + +#if defined(MLDSA_NTT_PPC_ASM) + if (OPENSSL_ppccap_P & PPC_CRYPTO207) { + poly_ntt_impl = poly_ntt_ppc64le_wrapper; + poly_ntt_inverse_impl = poly_ntt_inverse_ppc64le_wrapper; + poly_ntt_mult_impl = poly_ntt_mult_ppc64le_wrapper; + } +#endif + #ifdef VX_COMPILER_SUPPORT_VEC128 if (S390X_VX_CAPABLE) { poly_ntt_impl = ossl_ml_dsa_poly_ntt_vec128; diff --git a/crypto/ml_dsa/ml_dsa_poly.h b/crypto/ml_dsa/ml_dsa_poly.h index 7998fdd9c1d89..c45bd549cd6a0 100644 --- a/crypto/ml_dsa/ml_dsa_poly.h +++ b/crypto/ml_dsa/ml_dsa_poly.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -20,6 +20,8 @@ struct poly_st { #if defined(VX_COMPILER_SUPPORT_VEC128) ALIGN16 uint32_t coeff[ML_DSA_NUM_POLY_COEFFICIENTS]; +#elif defined(_ARCH_PPC64) + ALIGN16 uint32_t coeff[ML_DSA_NUM_POLY_COEFFICIENTS]; #else uint32_t coeff[ML_DSA_NUM_POLY_COEFFICIENTS]; #endif diff --git a/crypto/ml_dsa/ml_dsa_sample.c b/crypto/ml_dsa/ml_dsa_sample.c index afa09b7971c7f..be86b9844f794 100644 --- a/crypto/ml_dsa/ml_dsa_sample.c +++ b/crypto/ml_dsa/ml_dsa_sample.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -219,6 +219,13 @@ static int matrix_expand_A_scalar(EVP_MD_CTX *g_ctx, const EVP_MD *md, uint8_t derived_seed[ML_DSA_RHO_BYTES + 2]; POLY *poly = out->m_poly; + /* + * The seeds derived below and the sampling buffers in rej_ntt_poly() are + * not cleansed: per FIPS 204 section 3.6.3 the matrix A is easily + * computed from the public key and does not require any special + * protections. + */ + /* The seed used for each matrix element is rho + column_index + row_index */ memcpy(derived_seed, rho, ML_DSA_RHO_BYTES); for (i = 0; i < out->k; i++) { @@ -327,13 +334,14 @@ int ossl_ml_dsa_poly_sample_in_ball(POLY *out_c, const uint8_t *seed, int seed_l uint64_t signs; int offset = 8; size_t end; + int ret = 0; /* * Rather than squeeze 8 bytes followed by lots of 1 byte squeezes * the SHAKE blocksize is squeezed each time and buffered into 'block'. */ if (!shake_xof(h_ctx, md, seed, seed_len, block, sizeof(block))) - return 0; + goto err; /* * grab the first 64 bits - since tau < 64 @@ -369,7 +377,7 @@ int ossl_ml_dsa_poly_sample_in_ball(POLY *out_c, const uint8_t *seed, int seed_l if (offset == sizeof(block)) { /* squeeze another block if the bytes from block have been used */ if (!EVP_DigestSqueeze(h_ctx, block, sizeof(block))) - return 0; + goto err; /* See comment above for why the block is declassified. */ CONSTTIME_DECLASSIFY(block, sizeof(block)); offset = 0; @@ -389,7 +397,10 @@ int ossl_ml_dsa_poly_sample_in_ball(POLY *out_c, const uint8_t *seed, int seed_l out_c->coeff[index] = mod_sub(1, 2 * (signs & 1)); signs >>= 1; /* grab the next random bit */ } - return 1; + ret = 1; +err: + OPENSSL_cleanse(block, sizeof(block)); + return ret; } static void vector_expand_mask_scalar(VECTOR *out, diff --git a/crypto/ml_dsa/ml_dsa_sample_hw_x86_64.inc b/crypto/ml_dsa/ml_dsa_sample_hw_x86_64.inc index fcf5f0332373d..1fb8b2b64e76a 100644 --- a/crypto/ml_dsa/ml_dsa_sample_hw_x86_64.inc +++ b/crypto/ml_dsa/ml_dsa_sample_hw_x86_64.inc @@ -199,13 +199,20 @@ static int matrix_expand_A_mb(EVP_MD_CTX *g_ctx, const EVP_MD *md, POLY *polys[ML_DSA_SHAKE_X4_BATCH_SIZE]; POLY *poly = out->m_poly; + /* + * The seeds derived below and the sampling buffers in rej_ntt_poly_mb() + * are not cleansed: per FIPS 204 section 3.6.3 the matrix A is easily + * computed from the public key and does not require any special + * protections. + */ + for (b = 0; b < ML_DSA_SHAKE_X4_BATCH_SIZE; b++) { memcpy(derived_seeds[b], rho, ML_DSA_RHO_BYTES); seeds[b] = derived_seeds[b]; } for (idx = 0; (idx + ML_DSA_SHAKE_X4_BATCH_SIZE - 1) < (out->k * out->l); - idx += ML_DSA_SHAKE_X4_BATCH_SIZE) { + idx += ML_DSA_SHAKE_X4_BATCH_SIZE) { for (b = 0; b < ML_DSA_SHAKE_X4_BATCH_SIZE; b++) { const size_t row = (idx + b) / out->l; const size_t col = (idx + b) % out->l; diff --git a/crypto/ml_dsa/ml_dsa_sign.c b/crypto/ml_dsa/ml_dsa_sign.c index 62dfd08d53c6a..bcff47dbc2226 100644 --- a/crypto/ml_dsa/ml_dsa_sign.c +++ b/crypto/ml_dsa/ml_dsa_sign.c @@ -360,6 +360,7 @@ static int ml_dsa_sign_internal(const ML_DSA_KEY *priv, if (w1_encoded != NULL) OPENSSL_clear_free(w1_encoded, w1_encoded_len); OPENSSL_cleanse(rho_prime, sizeof(rho_prime)); + OPENSSL_cleanse(c_tilde, sizeof(c_tilde)); /* * Declassify the private key material before returning. The key struct * is not owned here, so we do not free it, but we must remove the @@ -540,6 +541,7 @@ int ossl_ml_dsa_sign(const ML_DSA_KEY *priv, err: EVP_MD_CTX_free(md_ctx); + OPENSSL_cleanse(mu, sizeof(mu)); return ret; } @@ -579,5 +581,6 @@ int ossl_ml_dsa_verify(const ML_DSA_KEY *pub, ret = ml_dsa_verify_internal(pub, mu_ptr, mu_len, sig, sig_len); err: EVP_MD_CTX_free(md_ctx); + OPENSSL_cleanse(mu, sizeof(mu)); return ret; } diff --git a/crypto/ml_dsa/ml_dsa_sign.h b/crypto/ml_dsa/ml_dsa_sign.h index 1a13410050422..5a6cbe81d517c 100644 --- a/crypto/ml_dsa/ml_dsa_sign.h +++ b/crypto/ml_dsa/ml_dsa_sign.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ml_dsa/ml_dsa_vector.h b/crypto/ml_dsa/ml_dsa_vector.h index 9b83c0420e96a..feedb56eff92c 100644 --- a/crypto/ml_dsa/ml_dsa_vector.h +++ b/crypto/ml_dsa/ml_dsa_vector.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ml_kem/asm/mlkem_intt_ppc64le.S b/crypto/ml_kem/asm/mlkem_intt_ppc64le.S index ff14c45626716..8f22851605a04 100644 --- a/crypto/ml_kem/asm/mlkem_intt_ppc64le.S +++ b/crypto/ml_kem/asm/mlkem_intt_ppc64le.S @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ml_kem/asm/mlkem_ntt_ppc64le.S b/crypto/ml_kem/asm/mlkem_ntt_ppc64le.S index 1aefed531e75b..7569e201270a5 100644 --- a/crypto/ml_kem/asm/mlkem_ntt_ppc64le.S +++ b/crypto/ml_kem/asm/mlkem_ntt_ppc64le.S @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ml_kem/asm/mlkem_ppc_macros_asm.inc b/crypto/ml_kem/asm/mlkem_ppc_macros_asm.inc index 58598ccf58848..2a52e14527fac 100644 --- a/crypto/ml_kem/asm/mlkem_ppc_macros_asm.inc +++ b/crypto/ml_kem/asm/mlkem_ppc_macros_asm.inc @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ml_kem/ml_kem.c b/crypto/ml_kem/ml_kem.c index 27fa15e246561..60d3fd2af63d3 100644 --- a/crypto/ml_kem/ml_kem.c +++ b/crypto/ml_kem/ml_kem.c @@ -985,6 +985,12 @@ static __owur int matrix_expand(EVP_MD_CTX *mdctx, ML_KEM_KEY *key) int rank = key->vinfo->rank; int i, j; + /* + * The seeds derived below and the sampling buffers in sample_scalar() + * are not cleansed: per FIPS 203 section 3.3 the matrix A is easily + * computed from the public encapsulation key and does not require any + * special protections. + */ memcpy(input, key->rho, ML_KEM_RANDOM_BYTES); for (i = 0; i < rank; i++) { for (j = 0; j < rank; j++) { @@ -1015,8 +1021,10 @@ static __owur int cbd_2(scalar *out, uint8_t in[ML_KEM_RANDOM_BYTES + 1], uint16_t value, mask; uint8_t b; - if (!prf(randbuf, sizeof(randbuf), in, mdctx, key)) + if (!prf(randbuf, sizeof(randbuf), in, mdctx, key)) { + OPENSSL_cleanse((void *)randbuf, sizeof(randbuf)); return 0; + } do { b = *r++; @@ -1038,6 +1046,8 @@ static __owur int cbd_2(scalar *out, uint8_t in[ML_KEM_RANDOM_BYTES + 1], mask = constish_time_true(value >> 15); *curr++ = value + (kPrime & mask); } while (curr < end); + + OPENSSL_cleanse((void *)randbuf, sizeof(randbuf)); return 1; } @@ -1055,8 +1065,10 @@ static __owur int cbd_3(scalar *out, uint8_t in[ML_KEM_RANDOM_BYTES + 1], uint8_t b1, b2, b3; uint16_t value, mask; - if (!prf(randbuf, sizeof(randbuf), in, mdctx, key)) + if (!prf(randbuf, sizeof(randbuf), in, mdctx, key)) { + OPENSSL_cleanse((void *)randbuf, sizeof(randbuf)); return 0; + } do { b1 = *r++; @@ -1090,6 +1102,8 @@ static __owur int cbd_3(scalar *out, uint8_t in[ML_KEM_RANDOM_BYTES + 1], mask = constish_time_true(value >> 15); *curr++ = value + (kPrime & mask); } while (curr < end); + + OPENSSL_cleanse((void *)randbuf, sizeof(randbuf)); return 1; } @@ -1102,14 +1116,19 @@ static __owur int gencbd_vector(scalar *out, CBD_FUNC cbd, uint8_t *counter, EVP_MD_CTX *mdctx, const ML_KEM_KEY *key) { uint8_t input[ML_KEM_RANDOM_BYTES + 1]; + int ret = 0; memcpy(input, seed, ML_KEM_RANDOM_BYTES); do { input[ML_KEM_RANDOM_BYTES] = (*counter)++; if (!cbd(out++, input, mdctx, key)) - return 0; + goto end; } while (--rank > 0); - return 1; + ret = 1; + +end: + OPENSSL_cleanse((void *)input, sizeof(input)); + return ret; } /* @@ -1120,15 +1139,20 @@ static __owur int gencbd_vector_ntt(scalar *out, CBD_FUNC cbd, uint8_t *counter, EVP_MD_CTX *mdctx, const ML_KEM_KEY *key) { uint8_t input[ML_KEM_RANDOM_BYTES + 1]; + int ret = 0; memcpy(input, seed, ML_KEM_RANDOM_BYTES); do { input[ML_KEM_RANDOM_BYTES] = (*counter)++; if (!cbd(out, input, mdctx, key)) - return 0; + goto end; scalar_ntt(out++); } while (--rank > 0); - return 1; + ret = 1; + +end: + OPENSSL_cleanse((void *)input, sizeof(input)); + return ret; } /* The |ETA1| value for ML-KEM-512 is 3, the rest and all ETA2 values are 2. */ @@ -1167,10 +1191,11 @@ static __owur int encrypt_cpa(uint8_t out[ML_KEM_SHARED_SECRET_BYTES], uint8_t counter = 0; int du = vinfo->du; int dv = vinfo->dv; + int ret = 0; /* FIPS 203 "y" vector */ if (!gencbd_vector_ntt(y, cbd_1, &counter, r, rank, mdctx, key)) - return 0; + goto end; /* FIPS 203 "v" scalar */ inner_product(&v, key->t, y, rank); scalar_inverse_ntt(&v); @@ -1179,7 +1204,7 @@ static __owur int encrypt_cpa(uint8_t out[ML_KEM_SHARED_SECRET_BYTES], /* All done with |y|, now free to reuse tmp[0] for FIPS 203 |e1| */ if (!gencbd_vector(e1, cbd_2, &counter, r, rank, mdctx, key)) - return 0; + goto end; vector_add(u, e1, rank); vector_compress(u, du, rank); vector_encode(out, u, du, rank); @@ -1188,14 +1213,19 @@ static __owur int encrypt_cpa(uint8_t out[ML_KEM_SHARED_SECRET_BYTES], memcpy(input, r, ML_KEM_RANDOM_BYTES); input[ML_KEM_RANDOM_BYTES] = counter; if (!cbd_2(e2, input, mdctx, key)) - return 0; + goto end; scalar_add(&v, e2); /* Combine message with |v| */ scalar_decode_decompress_add(&v, message); scalar_compress(&v, dv); scalar_encode(out + vinfo->u_vector_bytes, &v, dv); - return 1; + ret = 1; + +end: + OPENSSL_cleanse((void *)input, sizeof(input)); + OPENSSL_cleanse((void *)&v, sizeof(v)); + return ret; } /* @@ -1219,6 +1249,9 @@ decrypt_cpa(uint8_t out[ML_KEM_SHARED_SECRET_BYTES], scalar_sub(&v, &mask); scalar_compress(&v, 1); scalar_encode_1(out, &v); + + OPENSSL_cleanse((void *)&v, sizeof(v)); + OPENSSL_cleanse((void *)&mask, sizeof(mask)); } /*- @@ -1407,8 +1440,8 @@ static __owur int genkey(const uint8_t seed[ML_KEM_SEED_BYTES], ret = 1; end: - OPENSSL_cleanse((void *)augmented_seed, ML_KEM_RANDOM_BYTES); - OPENSSL_cleanse((void *)sigma, ML_KEM_RANDOM_BYTES); + OPENSSL_cleanse((void *)augmented_seed, sizeof(augmented_seed)); + OPENSSL_cleanse((void *)hashed, sizeof(hashed)); if (ret == 0) { ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR, "internal error while generating %s private key", @@ -1446,6 +1479,7 @@ static int encap(uint8_t *ctext, uint8_t secret[ML_KEM_SHARED_SECRET_BYTES], ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR, "internal error while performing %s encapsulation", key->vinfo->algorithm_name); + OPENSSL_cleanse((void *)Kr, sizeof(Kr)); return ret; } @@ -1510,7 +1544,7 @@ static int decap(uint8_t secret[ML_KEM_SHARED_SECRET_BYTES], ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR, "internal error while performing %s decapsulation", vinfo->algorithm_name); - return 0; + goto end; } decrypt_cpa(m, ctext, tmp, key); if (!hash_kr(Kr, m, mdctx, key) @@ -1930,6 +1964,9 @@ int ossl_ml_kem_genkey(uint8_t *pubenc, size_t publen, ML_KEM_KEY *key) EVP_MD_CTX_free(mdctx); if (!ret) { + /* Erase any partial public key output */ + if (pubenc != NULL) + OPENSSL_cleanse(pubenc, vinfo->pubkey_bytes); ossl_ml_kem_key_reset(key); return 0; } @@ -1993,6 +2030,10 @@ int ossl_ml_kem_encap_seed(uint8_t *ctext, size_t clen, } #undef case_encap_seed + /* Erase any partial ciphertext output on failure */ + if (!ret) + OPENSSL_cleanse(ctext, clen); + /* Declassify secret inputs and derived outputs before returning control */ CONSTTIME_DECLASSIFY(entropy, elen); CONSTTIME_DECLASSIFY(ctext, clen); @@ -2007,6 +2048,7 @@ int ossl_ml_kem_encap_rand(uint8_t *ctext, size_t clen, const ML_KEM_KEY *key) { uint8_t r[ML_KEM_RANDOM_BYTES]; + int ret; if (key == NULL) return 0; @@ -2016,8 +2058,11 @@ int ossl_ml_kem_encap_rand(uint8_t *ctext, size_t clen, < 1) return 0; - return ossl_ml_kem_encap_seed(ctext, clen, shared_secret, slen, + ret = ossl_ml_kem_encap_seed(ctext, clen, shared_secret, slen, r, sizeof(r), key); + + OPENSSL_cleanse((void *)r, sizeof(r)); + return ret; } int ossl_ml_kem_decap(uint8_t *shared_secret, size_t slen, @@ -2032,11 +2077,13 @@ int ossl_ml_kem_decap(uint8_t *shared_secret, size_t slen, #endif /* Need a private key here */ - if (!ossl_ml_kem_have_prvkey(key)) + if (!ossl_ml_kem_have_prvkey(key) + || shared_secret == NULL + || slen < ML_KEM_SHARED_SECRET_BYTES) return 0; vinfo = key->vinfo; - if (shared_secret == NULL || slen != ML_KEM_SHARED_SECRET_BYTES + if (slen != ML_KEM_SHARED_SECRET_BYTES || ctext == NULL || clen != vinfo->ctext_bytes || (mdctx = EVP_MD_CTX_new()) == NULL) { (void)RAND_bytes_ex(key->libctx, shared_secret, @@ -2065,6 +2112,7 @@ int ossl_ml_kem_decap(uint8_t *shared_secret, size_t slen, \ ret = decap(shared_secret, ctext, cbuf, tmp, mdctx, key); \ OPENSSL_cleanse((void *)tmp, sizeof(tmp)); \ + OPENSSL_cleanse((void *)cbuf, sizeof(cbuf)); \ } switch (vinfo->evp_type) { case EVP_PKEY_ML_KEM_512: diff --git a/crypto/modes/asm/aes-gcm-armv8-unroll8_64.pl b/crypto/modes/asm/aes-gcm-armv8-unroll8_64.pl index 81d1c195a9353..f96bc3c12326c 100644 --- a/crypto/modes/asm/aes-gcm-armv8-unroll8_64.pl +++ b/crypto/modes/asm/aes-gcm-armv8-unroll8_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/modes/asm/aes-gcm-armv8_64.pl b/crypto/modes/asm/aes-gcm-armv8_64.pl index d4c076961bd75..ce513412d763a 100755 --- a/crypto/modes/asm/aes-gcm-armv8_64.pl +++ b/crypto/modes/asm/aes-gcm-armv8_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/modes/asm/aes-gcm-avx512.pl b/crypto/modes/asm/aes-gcm-avx512.pl index ad6461f9e52fb..3da7c69cb985c 100644 --- a/crypto/modes/asm/aes-gcm-avx512.pl +++ b/crypto/modes/asm/aes-gcm-avx512.pl @@ -1,4 +1,4 @@ -# Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2021, Intel Corporation. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/modes/asm/aesni-gcm-x86_64.pl b/crypto/modes/asm/aesni-gcm-x86_64.pl index f3b920bb3a7e1..68f71eaff1027 100644 --- a/crypto/modes/asm/aesni-gcm-x86_64.pl +++ b/crypto/modes/asm/aesni-gcm-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2013-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2013-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/modes/asm/ghash-armv4.pl b/crypto/modes/asm/ghash-armv4.pl index b3b82bcf2c53f..7d9ea5d5be7cf 100644 --- a/crypto/modes/asm/ghash-armv4.pl +++ b/crypto/modes/asm/ghash-armv4.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2010-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2010-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/modes/asm/ghash-e2kv6.c b/crypto/modes/asm/ghash-e2kv6.c new file mode 100644 index 0000000000000..25615693e22ff --- /dev/null +++ b/crypto/modes/asm/ghash-e2kv6.c @@ -0,0 +1,180 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include + +#include "crypto/modes.h" + +static __attribute__((__always_inline__)) inline __v2di reverse_vector(const __v2di in) +{ + __v2di fmt = __builtin_e2k_qppackdl(0x0001020304050607LL, 0x08090a0b0c0d0e0fLL); + return __builtin_e2k_qppermb(in, in, fmt); +} + +static __attribute__((__always_inline__)) inline __v2di gcm_reduce(__v2di B0, __v2di B1) +{ + __v2di X0 = __builtin_e2k_qpsrlw(B1, 31); + __v2di X1 = __builtin_e2k_qpsllw(B1, 1); + __v2di X2 = __builtin_e2k_qpsrlw(B0, 31); + __v2di X3 = __builtin_e2k_qpsllw(B0, 1); + + X3 = X3 | __builtin_e2k_qpshufb(X0, X0, __builtin_e2k_qppackdl(0x8080808080808080LL, 0x808080800f0e0d0cLL)) + | __builtin_e2k_qpshufb(X2, X2, __builtin_e2k_qppackdl(0x0b0a090807060504LL, 0x0302010080808080LL)); + + X1 = X1 | __builtin_e2k_qpshufb(X0, X0, __builtin_e2k_qppackdl(0x0b0a090807060504LL, 0x0302010080808080LL)); + + X0 = __builtin_e2k_qpsllw(X1, 31) ^ __builtin_e2k_qpsllw(X1, 30) ^ __builtin_e2k_qpsllw(X1, 25); + + X1 ^= __builtin_e2k_qpshufb(X0, X0, __builtin_e2k_qppackdl(0x0302010080808080LL, 0x8080808080808080LL)); + + X0 = X1 ^ X3 ^ __builtin_e2k_qpshufb(X0, X0, __builtin_e2k_qppackdl(0x808080800f0e0d0cLL, 0x0b0a090807060504LL)); + + X0 ^= __builtin_e2k_qpsrlw(X1, 7) ^ __builtin_e2k_qpsrlw(X1, 2) ^ __builtin_e2k_qpsrlw(X1, 1); + + return X0; +} + +static __attribute__((__always_inline__)) inline __v2di gcm_multiply(__v2di H, __v2di x) +{ + uint64_t Hh = H[1], Hl = H[0]; + uint64_t xh = x[1], xl = x[0]; + + uint64_t T0h = __builtin_e2k_clmulh(Hh, xh), T0l = __builtin_e2k_clmull(Hh, xh); + uint64_t T1h = __builtin_e2k_clmulh(Hh, xl), T1l = __builtin_e2k_clmull(Hh, xl); + uint64_t T2h = __builtin_e2k_clmulh(Hl, xh), T2l = __builtin_e2k_clmull(Hl, xh); + uint64_t T3h = __builtin_e2k_clmulh(Hl, xl), T3l = __builtin_e2k_clmull(Hl, xl); + + T1h = __builtin_e2k_pxord(T1h, T2h); + T1l = __builtin_e2k_pxord(T1l, T2l); + + T0l = __builtin_e2k_pxord(T0l, T1h); + T3h = __builtin_e2k_pxord(T3h, T1l); + + return gcm_reduce(__builtin_e2k_qppackdl(T0h, T0l), __builtin_e2k_qppackdl(T3h, T3l)); +} + +static __attribute__((__always_inline__)) inline __v2di gcm_multiply_x4(__v2di H1, __v2di H2, __v2di H3, __v2di H4, + __v2di X1, __v2di X2, __v2di X3, __v2di X4) +{ + /* + * Multiply with delayed reduction, algorithm by Krzysztof Jankowski + * and Pierre Laurent of Intel + */ + + const uint64_t loh = (__builtin_e2k_clmulh(H1[0], X1[0]) ^ __builtin_e2k_clmulh(H2[0], X2[0])) ^ (__builtin_e2k_clmulh(H3[0], X3[0]) ^ __builtin_e2k_clmulh(H4[0], X4[0])); + const uint64_t lol = (__builtin_e2k_clmull(H1[0], X1[0]) ^ __builtin_e2k_clmull(H2[0], X2[0])) ^ (__builtin_e2k_clmull(H3[0], X3[0]) ^ __builtin_e2k_clmull(H4[0], X4[0])); + + const uint64_t hih = (__builtin_e2k_clmulh(H1[1], X1[1]) ^ __builtin_e2k_clmulh(H2[1], X2[1])) ^ (__builtin_e2k_clmulh(H3[1], X3[1]) ^ __builtin_e2k_clmulh(H4[1], X4[1])); + const uint64_t hil = (__builtin_e2k_clmull(H1[1], X1[1]) ^ __builtin_e2k_clmull(H2[1], X2[1])) ^ (__builtin_e2k_clmull(H3[1], X3[1]) ^ __builtin_e2k_clmull(H4[1], X4[1])); + uint64_t Th, Tl; + + Th = __builtin_e2k_clmulh(H1[0] ^ H1[1], X1[0] ^ X1[1]); + Tl = __builtin_e2k_clmull(H1[0] ^ H1[1], X1[0] ^ X1[1]); + + Th ^= __builtin_e2k_clmulh(H2[0] ^ H2[1], X2[0] ^ X2[1]); + Tl ^= __builtin_e2k_clmull(H2[0] ^ H2[1], X2[0] ^ X2[1]); + + Th ^= __builtin_e2k_clmulh(H3[0] ^ H3[1], X3[0] ^ X3[1]); + Tl ^= __builtin_e2k_clmull(H3[0] ^ H3[1], X3[0] ^ X3[1]); + + Th ^= __builtin_e2k_clmulh(H4[0] ^ H4[1], X4[0] ^ X4[1]); + Tl ^= __builtin_e2k_clmull(H4[0] ^ H4[1], X4[0] ^ X4[1]); + + Th ^= loh; + Tl ^= lol; + Th ^= hih; + Tl ^= hil; + + return gcm_reduce(__builtin_e2k_qppackdl(hih, hil ^ Th), + __builtin_e2k_qppackdl(loh ^ Tl, lol)); +} + +/*############################################################################## +# void gcm_init_e2kv6_clmul(u128 Htable[16],const uint64_t H[2]); +# +# input: 128-bit H - secret parameter E(K,0^128) +# output: precomputed table filled with degrees of twisted H; +# H is twisted to handle reverse bitness of GHASH; +# only few of 16 slots of Htable[16] are used; +# data is opaque to outside world (which allows to +# optimize the code independently); +# +*/ +void gcm_init_e2kv6_clmul(u128 Htable[16], const uint64_t H[2]) +{ + __v2di *Hp = (__v2di *)Htable; + __v2di H1 = (__v2di) { H[1], H[0] }; /* H in LE, but need swap hi/lo */ + __v2di H2 = gcm_multiply(H1, H1); + __v2di H3 = gcm_multiply(H1, H2); + __v2di H4 = gcm_multiply(H2, H2); + + Hp[0] = H1; + Hp[1] = H2; + Hp[2] = H3; + Hp[3] = H4; +} + +/*############################################################################## +# void gcm_gmult_e2kv6_clmul(uint64_t Xi[2],const u128 Htable[16]); +# +# input: Xi - current hash value; +# Htable - table precomputed in gcm_init_e2kv6_clmul; +# output: Xi - next hash value Xi; +*/ +void gcm_gmult_e2kv6_clmul(uint64_t Xi[2], const u128 Htable[16]) +{ + __v2di *Xp = (__v2di *)Xi; + __v2di *Hp = (__v2di *)Htable; + *Xp = reverse_vector(gcm_multiply(Hp[0], reverse_vector(*Xp))); +} + +/*############################################################################## +# void gcm_ghash_e2kv6_clmul(uint64_t Xi[2], const u128 Htable[16], +# const uint8_t *inp,size_t len); +# +# input: table precomputed in gcm_init_e2kv6_clmul; +# current hash value Xi; +# pointer to input data; +# length of input data in bytes, but divisible by block size; +# output: next hash value Xi; +*/ +void gcm_ghash_e2kv6_clmul(uint64_t Xi[2], const u128 Htable[16], + const uint8_t *inp, size_t len) +{ + __v2di *Hp = (__v2di *)Htable; + __v2di *input = (__v2di *)inp; + __v2di x; + size_t i, blocks = (len >> 4); + + x = reverse_vector(*(__v2di *)Xi); + + while (blocks >= 4) { + __v2di m0 = reverse_vector(input[0]); + __v2di m1 = reverse_vector(input[1]); + __v2di m2 = reverse_vector(input[2]); + __v2di m3 = reverse_vector(input[3]); + + x ^= m0; + x = gcm_multiply_x4(Hp[0], Hp[1], Hp[2], Hp[3], m3, m2, m1, x); + + input += 4; + blocks -= 4; + } + +#pragma loop count(3) + for (i = 0; i < blocks; i++) { + __v2di m = reverse_vector(input[i]); + + x ^= m; + x = gcm_multiply(Hp[0], x); + } + + *(__v2di *)Xi = reverse_vector(x); +} diff --git a/crypto/modes/asm/ghash-riscv64-zvkb-zvbc.pl b/crypto/modes/asm/ghash-riscv64-zvkb-zvbc.pl index 5eb748bdc2c34..c62a7e32965b0 100644 --- a/crypto/modes/asm/ghash-riscv64-zvkb-zvbc.pl +++ b/crypto/modes/asm/ghash-riscv64-zvkb-zvbc.pl @@ -2,7 +2,7 @@ # This file is dual-licensed, meaning that you can use it under your # choice of either of the following two licenses: # -# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You can obtain # a copy in the file LICENSE in the source distribution or at @@ -11,6 +11,7 @@ # or # # Copyright (c) 2023, Christoph Müllner +# Copyright (c) 2026, Julian Zhu # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -58,6 +59,12 @@ .text ___ +my ($V0, $V1, $V2, $V3, $V4, $V5, $V6, $V7, + $V8, $V9, $V10, $V11, $V12, $V13, $V14, $V15, + $V16, $V17, $V18, $V19, $V20, $V21, $V22, $V23, + $V24, $V25, $V26, $V27, $V28, $V29, $V30, $V31, +) = map("v$_",(0..31)); + ################################################################################ # void gcm_init_rv64i_zvkb_zvbc(u128 Htable[16], const u64 H[2]); # @@ -65,8 +72,7 @@ # output: Htable: Preprocessed key data for gcm_gmult_rv64i_zvkb_zvbc and # gcm_ghash_rv64i_zvkb_zvbc { -my ($Htable,$H,$TMP0,$TMP1,$TMP2) = ("a0","a1","t0","t1","t2"); -my ($V0,$V1,$V2,$V3,$V4,$V5,$V6) = ("v0","v1","v2","v3","v4","v5","v6"); +my ($Htable,$H,$TMP0,$TMP1,$TMP2,$TMP3) = ("a0","a1","t0","t1","t2","t3"); $code .= <<___; .p2align 3 @@ -108,7 +114,139 @@ @{[vxor_vv_v0t $V1, $V1, $V2]} # vxor.vv v1, v1, v2, v0.t - @{[vse64_v $V1, $Htable]} # vse64.v v1, (a0) + @{[vse64_v $V1, $Htable]} # vse64.v v1, (a0) -- store H + + # --- Compute H^2 = H * H for multi-block aggregation --- + ld $TMP0, 0($Htable) + ld $TMP1, 8($Htable) + la $TMP3, Lpolymod + ld $TMP3, 8($TMP3) + + @{[vmv_v_v $V5, $V1]} # copy H to v5 + + # Schoolbook multiply: H * H + @{[vclmul_vx $V1, $V5, $TMP0]} + @{[vclmulh_vx $V3, $V5, $TMP0]} + @{[vclmul_vx $V4, $V5, $TMP1]} + @{[vclmulh_vx $V2, $V5, $TMP1]} + + @{[vslideup_vi $V5, $V3, 1]} + @{[vslideup_vi $V6, $V4, 1]} + @{[vslidedown_vi $V3, $V3, 1]} + @{[vslidedown_vi $V4, $V4, 1]} + + @{[vmv_v_i $V0, 1]} + @{[vxor_vv_v0t $V2, $V2, $V3]} + @{[vxor_vv_v0t $V2, $V2, $V4]} + + @{[vmv_v_i $V0, 2]} + @{[vxor_vv_v0t $V1, $V1, $V5]} + @{[vxor_vv_v0t $V1, $V1, $V6]} + + # Gueron reduction + @{[vslideup_vi_v0t $V3, $V1, 1]} + @{[vclmul_vx_v0t $V3, $V3, $TMP3]} + @{[vxor_vv_v0t $V1, $V1, $V3]} + + @{[vclmul_vx_v0t $V3, $V1, $TMP3]} + @{[vclmulh_vx $V4, $V1, $TMP3]} + + @{[vmv_v_i $V0, 1]} + @{[vslidedown_vi $V3, $V3, 1]} + + @{[vxor_vv $V1, $V1, $V4]} + @{[vxor_vv_v0t $V1, $V1, $V3]} + + @{[vxor_vv $V2, $V2, $V1]} + + # Store H^2 at Htable+16 + addi $Htable, $Htable, 16 + @{[vse64_v $V2, $Htable]} + + # --- Compute H^3 = H^2 * H --- + @{[vmv_v_v $V5, $V2]} # v5 = H^2 + + @{[vclmul_vx $V1, $V5, $TMP0]} + @{[vclmulh_vx $V3, $V5, $TMP0]} + @{[vclmul_vx $V4, $V5, $TMP1]} + @{[vclmulh_vx $V2, $V5, $TMP1]} + + @{[vslideup_vi $V5, $V3, 1]} + @{[vslideup_vi $V6, $V4, 1]} + @{[vslidedown_vi $V3, $V3, 1]} + @{[vslidedown_vi $V4, $V4, 1]} + + @{[vmv_v_i $V0, 1]} + @{[vxor_vv_v0t $V2, $V2, $V3]} + @{[vxor_vv_v0t $V2, $V2, $V4]} + + @{[vmv_v_i $V0, 2]} + @{[vxor_vv_v0t $V1, $V1, $V5]} + @{[vxor_vv_v0t $V1, $V1, $V6]} + + @{[vslideup_vi_v0t $V3, $V1, 1]} + @{[vclmul_vx_v0t $V3, $V3, $TMP3]} + @{[vxor_vv_v0t $V1, $V1, $V3]} + + @{[vclmul_vx_v0t $V3, $V1, $TMP3]} + @{[vclmulh_vx $V4, $V1, $TMP3]} + + @{[vmv_v_i $V0, 1]} + @{[vslidedown_vi $V3, $V3, 1]} + + @{[vxor_vv $V1, $V1, $V4]} + @{[vxor_vv_v0t $V1, $V1, $V3]} + + @{[vxor_vv $V2, $V2, $V1]} + + # Store H^3 at Htable+32 + addi $Htable, $Htable, 16 + @{[vse64_v $V2, $Htable]} + + # --- Compute H^4 = H^2 * H^2 --- + # Load H^2 vector and scalar halves from Htable-16 + addi $TMP2, $Htable, -16 + ld $TMP0, 0($TMP2) + ld $TMP1, 8($TMP2) + @{[vle64_v $V5, $TMP2]} + + @{[vclmul_vx $V1, $V5, $TMP0]} + @{[vclmulh_vx $V3, $V5, $TMP0]} + @{[vclmul_vx $V4, $V5, $TMP1]} + @{[vclmulh_vx $V2, $V5, $TMP1]} + + @{[vslideup_vi $V5, $V3, 1]} + @{[vslideup_vi $V6, $V4, 1]} + @{[vslidedown_vi $V3, $V3, 1]} + @{[vslidedown_vi $V4, $V4, 1]} + + @{[vmv_v_i $V0, 1]} + @{[vxor_vv_v0t $V2, $V2, $V3]} + @{[vxor_vv_v0t $V2, $V2, $V4]} + + @{[vmv_v_i $V0, 2]} + @{[vxor_vv_v0t $V1, $V1, $V5]} + @{[vxor_vv_v0t $V1, $V1, $V6]} + + @{[vslideup_vi_v0t $V3, $V1, 1]} + @{[vclmul_vx_v0t $V3, $V3, $TMP3]} + @{[vxor_vv_v0t $V1, $V1, $V3]} + + @{[vclmul_vx_v0t $V3, $V1, $TMP3]} + @{[vclmulh_vx $V4, $V1, $TMP3]} + + @{[vmv_v_i $V0, 1]} + @{[vslidedown_vi $V3, $V3, 1]} + + @{[vxor_vv $V1, $V1, $V4]} + @{[vxor_vv_v0t $V1, $V1, $V3]} + + @{[vxor_vv $V2, $V2, $V1]} + + # Store H^4 at Htable+48 + addi $Htable, $Htable, 16 + @{[vse64_v $V2, $Htable]} + ret .size gcm_init_rv64i_zvkb_zvbc,.-gcm_init_rv64i_zvkb_zvbc ___ @@ -122,7 +260,6 @@ # output: Xi: next hash value Xi = (Xi * H mod f) { my ($Xi,$Htable,$TMP0,$TMP1,$TMP2,$TMP3,$TMP4) = ("a0","a1","t0","t1","t2","t3","t4"); -my ($V0,$V1,$V2,$V3,$V4,$V5,$V6) = ("v0","v1","v2","v3","v4","v5","v6"); $code .= <<___; .text @@ -243,123 +380,324 @@ # output: Xi: Xi+1 (next hash value Xi) { my ($Xi,$Htable,$inp,$len,$TMP0,$TMP1,$TMP2,$TMP3,$M8,$TMP5,$TMP6) = ("a0","a1","a2","a3","t0","t1","t2","t3","t4","t5","t6"); -my ($V0,$V1,$V2,$V3,$V4,$V5,$V6,$Vinp) = ("v0","v1","v2","v3","v4","v5","v6","v7"); +my ($s0,$s1,$s2,$s3) = ("s0","s1","s2","s3"); $code .= <<___; .p2align 3 .globl gcm_ghash_rv64i_zvkb_zvbc .type gcm_ghash_rv64i_zvkb_zvbc,\@function gcm_ghash_rv64i_zvkb_zvbc: + # Load H (for single-block and second multiply in 2-block) ld $TMP0, ($Htable) ld $TMP1, 8($Htable) - li $TMP2, 63 + # Load H^2 (for first multiply in 2-block) + ld $TMP2, 16($Htable) + ld $TMP5, 24($Htable) la $TMP3, Lpolymod ld $TMP3, 8($TMP3) - # Load/store data in reverse order. - # This is needed as a part of endianness swap. + # Load/store data in reverse order for endianness swap. add $Xi, $Xi, 8 add $inp, $inp, 8 li $M8, -8 @{[vsetivli__x0_2_e64_m1_tu_mu]} # vsetivli x0, 2, e64, m1, tu, mu - @{[vlse64_v $V5, $Xi, $M8]} # vlse64.v v5, (a0), t4 + @{[vlse64_v $V5, $Xi, $M8]} # load Xi (word-swapped) + + # Check for 4-block path (len >= 64) + li $TMP6, 64 + blt $len, $TMP6, Lcheck_2x + + # --- 4-block aggregation path --- + # Save callee-saved registers + addi sp, sp, -32 + sd s0, 0(sp) + sd s1, 8(sp) + sd s2, 16(sp) + sd s3, 24(sp) + + # Load H^3, H^4 + ld s0, 32($Htable) # H^3_lo + ld s1, 40($Htable) # H^3_hi + ld s2, 48($Htable) # H^4_lo + ld s3, 56($Htable) # H^4_hi + +Lstep_4x: + # === Block 1: (Xi ^ C1) * H^4 === + @{[vlse64_v $V7, $inp, $M8]} + add $inp, $inp, 16 + @{[vxor_vv $V5, $V5, $V7]} + @{[vrev8_v $V5, $V5]} + + @{[vclmul_vx $V1, $V5, $s2]} + @{[vclmulh_vx $V3, $V5, $s2]} + @{[vclmul_vx $V4, $V5, $s3]} + @{[vclmulh_vx $V2, $V5, $s3]} + + @{[vslideup_vi $V5, $V3, 1]} + @{[vslideup_vi $V6, $V4, 1]} + @{[vslidedown_vi $V3, $V3, 1]} + @{[vslidedown_vi $V4, $V4, 1]} + + @{[vmv_v_i $V0, 1]} + @{[vxor_vv_v0t $V2, $V2, $V3]} + @{[vxor_vv_v0t $V2, $V2, $V4]} + @{[vmv_v_i $V0, 2]} + @{[vxor_vv_v0t $V1, $V1, $V5]} + @{[vxor_vv_v0t $V1, $V1, $V6]} + + # Save product 1 + @{[vmv_v_v $V8, $V2]} + @{[vmv_v_v $V9, $V1]} + + # === Block 2: C2 * H^3 === + @{[vlse64_v $V7, $inp, $M8]} + add $inp, $inp, 16 + @{[vrev8_v $V5, $V7]} + + @{[vclmul_vx $V1, $V5, $s0]} + @{[vclmulh_vx $V3, $V5, $s0]} + @{[vclmul_vx $V4, $V5, $s1]} + @{[vclmulh_vx $V2, $V5, $s1]} + + @{[vslideup_vi $V5, $V3, 1]} + @{[vslideup_vi $V6, $V4, 1]} + @{[vslidedown_vi $V3, $V3, 1]} + @{[vslidedown_vi $V4, $V4, 1]} + + @{[vmv_v_i $V0, 1]} + @{[vxor_vv_v0t $V2, $V2, $V3]} + @{[vxor_vv_v0t $V2, $V2, $V4]} + @{[vmv_v_i $V0, 2]} + @{[vxor_vv_v0t $V1, $V1, $V5]} + @{[vxor_vv_v0t $V1, $V1, $V6]} + + # Accumulate product 2 + @{[vxor_vv $V8, $V8, $V2]} + @{[vxor_vv $V9, $V9, $V1]} + + # === Block 3: C3 * H^2 === + @{[vlse64_v $V7, $inp, $M8]} + add $inp, $inp, 16 + @{[vrev8_v $V5, $V7]} + + @{[vclmul_vx $V1, $V5, $TMP2]} + @{[vclmulh_vx $V3, $V5, $TMP2]} + @{[vclmul_vx $V4, $V5, $TMP5]} + @{[vclmulh_vx $V2, $V5, $TMP5]} + + @{[vslideup_vi $V5, $V3, 1]} + @{[vslideup_vi $V6, $V4, 1]} + @{[vslidedown_vi $V3, $V3, 1]} + @{[vslidedown_vi $V4, $V4, 1]} + + @{[vmv_v_i $V0, 1]} + @{[vxor_vv_v0t $V2, $V2, $V3]} + @{[vxor_vv_v0t $V2, $V2, $V4]} + @{[vmv_v_i $V0, 2]} + @{[vxor_vv_v0t $V1, $V1, $V5]} + @{[vxor_vv_v0t $V1, $V1, $V6]} + + # Accumulate product 3 + @{[vxor_vv $V8, $V8, $V2]} + @{[vxor_vv $V9, $V9, $V1]} + + # === Block 4: C4 * H === + @{[vlse64_v $V7, $inp, $M8]} + add $inp, $inp, 16 + add $len, $len, -64 + @{[vrev8_v $V5, $V7]} -Lstep: - # Read input data - @{[vlse64_v $Vinp, $inp, $M8]} # vle64.v v0, (a2) + @{[vclmul_vx $V1, $V5, $TMP0]} + @{[vclmulh_vx $V3, $V5, $TMP0]} + @{[vclmul_vx $V4, $V5, $TMP1]} + @{[vclmulh_vx $V2, $V5, $TMP1]} + + @{[vslideup_vi $V5, $V3, 1]} + @{[vslideup_vi $V6, $V4, 1]} + @{[vslidedown_vi $V3, $V3, 1]} + @{[vslidedown_vi $V4, $V4, 1]} + + @{[vmv_v_i $V0, 1]} + @{[vxor_vv_v0t $V2, $V2, $V3]} + @{[vxor_vv_v0t $V2, $V2, $V4]} + @{[vmv_v_i $V0, 2]} + @{[vxor_vv_v0t $V1, $V1, $V5]} + @{[vxor_vv_v0t $V1, $V1, $V6]} + + # Combine all 4 products + @{[vxor_vv $V2, $V2, $V8]} + @{[vxor_vv $V1, $V1, $V9]} + + # Single Gueron reduction for all 4 blocks + # v0 = 2 from above + @{[vslideup_vi_v0t $V3, $V1, 1]} + @{[vclmul_vx_v0t $V3, $V3, $TMP3]} + @{[vxor_vv_v0t $V1, $V1, $V3]} + + @{[vclmul_vx_v0t $V3, $V1, $TMP3]} + @{[vclmulh_vx $V4, $V1, $TMP3]} + + @{[vmv_v_i $V0, 1]} + @{[vslidedown_vi $V3, $V3, 1]} + + @{[vxor_vv $V1, $V1, $V4]} + @{[vxor_vv_v0t $V1, $V1, $V3]} + + @{[vxor_vv $V2, $V2, $V1]} + + @{[vrev8_v $V5, $V2]} + + li $TMP6, 64 + bge $len, $TMP6, Lstep_4x + + # Restore callee-saved registers + ld s0, 0(sp) + ld s1, 8(sp) + ld s2, 16(sp) + ld s3, 24(sp) + addi sp, sp, 32 + +Lcheck_2x: + # Check for 2-block path (len >= 32) + li $TMP6, 32 + blt $len, $TMP6, Lcheck_1x + +Lstep_2x: + # === 2-block iteration: (Xi ^ C1) * H^2 + C2 * H === + + # Block 1: load C1, XOR with Xi + @{[vlse64_v $V7, $inp, $M8]} add $inp, $inp, 16 add $len, $len, -16 - # XOR them into Xi - @{[vxor_vv $V5, $V5, $Vinp]} # vxor.vv v0, v0, v1 + @{[vxor_vv $V5, $V5, $V7]} + @{[vrev8_v $V5, $V5]} + + # Schoolbook multiply (Xi ^ C1) * H^2 -> product in (v2, v1) + @{[vclmul_vx $V1, $V5, $TMP2]} + @{[vclmulh_vx $V3, $V5, $TMP2]} + @{[vclmul_vx $V4, $V5, $TMP5]} + @{[vclmulh_vx $V2, $V5, $TMP5]} + + @{[vslideup_vi $V5, $V3, 1]} + @{[vslideup_vi $V6, $V4, 1]} + @{[vslidedown_vi $V3, $V3, 1]} + @{[vslidedown_vi $V4, $V4, 1]} + + @{[vmv_v_i $V0, 1]} + @{[vxor_vv_v0t $V2, $V2, $V3]} + @{[vxor_vv_v0t $V2, $V2, $V4]} + @{[vmv_v_i $V0, 2]} + @{[vxor_vv_v0t $V1, $V1, $V5]} + @{[vxor_vv_v0t $V1, $V1, $V6]} + + # Save first product + @{[vmv_v_v $V8, $V2]} + @{[vmv_v_v $V9, $V1]} + + # Block 2: load C2 (no XOR with Xi) + @{[vlse64_v $V7, $inp, $M8]} + add $inp, $inp, 16 + add $len, $len, -16 + @{[vrev8_v $V5, $V7]} - @{[vrev8_v $V5, $V5]} # vrev8.v v5, v5 + # Schoolbook multiply C2 * H -> product in (v2, v1) + @{[vclmul_vx $V1, $V5, $TMP0]} + @{[vclmulh_vx $V3, $V5, $TMP0]} + @{[vclmul_vx $V4, $V5, $TMP1]} + @{[vclmulh_vx $V2, $V5, $TMP1]} - # Multiplication + @{[vslideup_vi $V5, $V3, 1]} + @{[vslideup_vi $V6, $V4, 1]} + @{[vslidedown_vi $V3, $V3, 1]} + @{[vslidedown_vi $V4, $V4, 1]} - # Do two 64x64 multiplications in one go to save some time - # and simplify things. + @{[vmv_v_i $V0, 1]} + @{[vxor_vv_v0t $V2, $V2, $V3]} + @{[vxor_vv_v0t $V2, $V2, $V4]} + @{[vmv_v_i $V0, 2]} + @{[vxor_vv_v0t $V1, $V1, $V5]} + @{[vxor_vv_v0t $V1, $V1, $V6]} - # A = a1a0 (t1, t0) - # B = b1b0 (v5) - # C = c1c0 (256 bit) - # c1 = a1b1 + (a0b1)h + (a1b0)h - # c0 = a0b0 + (a0b1)l + (a1b0)h + # Combine products: (v2,v1) += (v8,v9) + @{[vxor_vv $V2, $V2, $V8]} + @{[vxor_vv $V1, $V1, $V9]} - # v1 = (a0b1)l,(a0b0)l - @{[vclmul_vx $V1, $V5, $TMP0]} # vclmul.vx v1, v5, t0 - # v3 = (a0b1)h,(a0b0)h - @{[vclmulh_vx $V3, $V5, $TMP0]} # vclmulh.vx v3, v5, t0 + # Single Gueron reduction for both blocks + # v0 = 2 from above + @{[vslideup_vi_v0t $V3, $V1, 1]} + @{[vclmul_vx_v0t $V3, $V3, $TMP3]} + @{[vxor_vv_v0t $V1, $V1, $V3]} - # v4 = (a1b1)l,(a1b0)l - @{[vclmul_vx $V4, $V5, $TMP1]} # vclmul.vx v4, v5, t1 - # v2 = (a1b1)h,(a1b0)h - @{[vclmulh_vx $V2, $V5, $TMP1]} # vclmulh.vx v2, v5, t1 + @{[vclmul_vx_v0t $V3, $V1, $TMP3]} + @{[vclmulh_vx $V4, $V1, $TMP3]} - # Is there a better way to do this? - # Would need to swap the order of elements within a vector register. - @{[vslideup_vi $V5, $V3, 1]} # vslideup.vi v5, v3, 1 - @{[vslideup_vi $V6, $V4, 1]} # vslideup.vi v6, v4, 1 - @{[vslidedown_vi $V3, $V3, 1]} # vslidedown.vi v3, v3, 1 - @{[vslidedown_vi $V4, $V4, 1]} # vslidedown.vi v4, v4, 1 + @{[vmv_v_i $V0, 1]} + @{[vslidedown_vi $V3, $V3, 1]} - @{[vmv_v_i $V0, 1]} # vmv.v.i v0, 1 - # v2 += (a0b1)h - @{[vxor_vv_v0t $V2, $V2, $V3]} # vxor.vv v2, v2, v3, v0.t - # v2 += (a1b1)l - @{[vxor_vv_v0t $V2, $V2, $V4]} # vxor.vv v2, v2, v4, v0.t + @{[vxor_vv $V1, $V1, $V4]} + @{[vxor_vv_v0t $V1, $V1, $V3]} - @{[vmv_v_i $V0, 2]} # vmv.v.i v0, 2 - # v1 += (a0b0)h,0 - @{[vxor_vv_v0t $V1, $V1, $V5]} # vxor.vv v1, v1, v5, v0.t - # v1 += (a1b0)l,0 - @{[vxor_vv_v0t $V1, $V1, $V6]} # vxor.vv v1, v1, v6, v0.t + @{[vxor_vv $V2, $V2, $V1]} - # Now the 256bit product should be stored in (v2,v1) - # v1 = (a0b1)l + (a0b0)h + (a1b0)l, (a0b0)l - # v2 = (a1b1)h, (a1b0)h + (a0b1)h + (a1b1)l + @{[vrev8_v $V5, $V2]} - # Reduction - # Let C := A*B = c3,c2,c1,c0 = v2[1],v2[0],v1[1],v1[0] - # This is a slight variation of the Gueron's Montgomery reduction. - # The difference being the order of some operations has been changed, - # to make a better use of vclmul(h) instructions. + li $TMP6, 32 + bge $len, $TMP6, Lstep_2x - # First step: - # c1 += (c0 * P)l - # vmv.v.i v0, 2 - @{[vslideup_vi_v0t $V3, $V1, 1]} # vslideup.vi v3, v1, 1, v0.t - @{[vclmul_vx_v0t $V3, $V3, $TMP3]} # vclmul.vx v3, v3, t3, v0.t - @{[vxor_vv_v0t $V1, $V1, $V3]} # vxor.vv v1, v1, v3, v0.t +Lcheck_1x: + # Check for remaining single block + beqz $len, Ldone - # Second step: - # D = d1,d0 is final result - # We want: - # m1 = c1 + (c1 * P)h - # m0 = (c1 * P)l + (c0 * P)h + c0 - # d1 = c3 + m1 - # d0 = c2 + m0 +Lstep: + # === Single-block: (Xi ^ block) * H === + @{[vlse64_v $V7, $inp, $M8]} + add $inp, $inp, 16 + add $len, $len, -16 + @{[vxor_vv $V5, $V5, $V7]} + @{[vrev8_v $V5, $V5]} - #v3 = (c1 * P)l, 0 - @{[vclmul_vx_v0t $V3, $V1, $TMP3]} # vclmul.vx v3, v1, t3, v0.t - #v4 = (c1 * P)h, (c0 * P)h - @{[vclmulh_vx $V4, $V1, $TMP3]} # vclmulh.vx v4, v1, t3 + # Schoolbook multiply * H + @{[vclmul_vx $V1, $V5, $TMP0]} + @{[vclmulh_vx $V3, $V5, $TMP0]} + @{[vclmul_vx $V4, $V5, $TMP1]} + @{[vclmulh_vx $V2, $V5, $TMP1]} - @{[vmv_v_i $V0, 1]} # vmv.v.i v0, 1 - @{[vslidedown_vi $V3, $V3, 1]} # vslidedown.vi v3, v3, 1 + @{[vslideup_vi $V5, $V3, 1]} + @{[vslideup_vi $V6, $V4, 1]} + @{[vslidedown_vi $V3, $V3, 1]} + @{[vslidedown_vi $V4, $V4, 1]} - @{[vxor_vv $V1, $V1, $V4]} # vxor.vv v1, v1, v4 - @{[vxor_vv_v0t $V1, $V1, $V3]} # vxor.vv v1, v1, v3, v0.t + @{[vmv_v_i $V0, 1]} + @{[vxor_vv_v0t $V2, $V2, $V3]} + @{[vxor_vv_v0t $V2, $V2, $V4]} + @{[vmv_v_i $V0, 2]} + @{[vxor_vv_v0t $V1, $V1, $V5]} + @{[vxor_vv_v0t $V1, $V1, $V6]} - # XOR in the upper upper part of the product - @{[vxor_vv $V2, $V2, $V1]} # vxor.vv v2, v2, v1 + # Gueron reduction + @{[vslideup_vi_v0t $V3, $V1, 1]} + @{[vclmul_vx_v0t $V3, $V3, $TMP3]} + @{[vxor_vv_v0t $V1, $V1, $V3]} + + @{[vclmul_vx_v0t $V3, $V1, $TMP3]} + @{[vclmulh_vx $V4, $V1, $TMP3]} + + @{[vmv_v_i $V0, 1]} + @{[vslidedown_vi $V3, $V3, 1]} + + @{[vxor_vv $V1, $V1, $V4]} + @{[vxor_vv_v0t $V1, $V1, $V3]} + + @{[vxor_vv $V2, $V2, $V1]} - @{[vrev8_v $V5, $V2]} # vrev8.v v2, v2 + @{[vrev8_v $V5, $V2]} bnez $len, Lstep - @{[vsse64_v $V5, $Xi, $M8]} # vsse64.v v2, (a0), t4 +Ldone: + @{[vsse64_v $V5, $Xi, $M8]} ret .size gcm_ghash_rv64i_zvkb_zvbc,.-gcm_ghash_rv64i_zvkb_zvbc ___ diff --git a/crypto/modes/asm/ghash-riscv64-zvkg.pl b/crypto/modes/asm/ghash-riscv64-zvkg.pl index e16fcf5cdd39f..8676ab38c4efb 100644 --- a/crypto/modes/asm/ghash-riscv64-zvkg.pl +++ b/crypto/modes/asm/ghash-riscv64-zvkg.pl @@ -2,7 +2,7 @@ # This file is dual-licensed, meaning that you can use it under your # choice of either of the following two licenses: # -# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You can obtain # a copy in the file LICENSE in the source distribution or at @@ -11,6 +11,7 @@ # or # # Copyright (c) 2023, Christoph Müllner +# Copyright (c) 2026, Julian Zhu # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -60,6 +61,12 @@ .text ___ +my ($V0, $V1, $V2, $V3, $V4, $V5, $V6, $V7, + $V8, $V9, $V10, $V11, $V12, $V13, $V14, $V15, + $V16, $V17, $V18, $V19, $V20, $V21, $V22, $V23, + $V24, $V25, $V26, $V27, $V28, $V29, $V30, $V31, +) = map("v$_",(0..31)); + ################################################################################ # void gcm_init_rv64i_zvkg(u128 Htable[16], const u64 H[2]); # void gcm_init_rv64i_zvkg_zvkb(u128 Htable[16], const u64 H[2]); @@ -77,27 +84,61 @@ .globl gcm_init_rv64i_zvkg .type gcm_init_rv64i_zvkg,\@function gcm_init_rv64i_zvkg: - ld $VAL0, 0($H) - ld $VAL1, 8($H) + # Store byte-reversed H at Htable[0] + ld $VAL0, 0($H) + ld $VAL1, 8($H) @{[sd_rev8_rv64i $VAL0, $Htable, 0, $TMP0]} @{[sd_rev8_rv64i $VAL1, $Htable, 8, $TMP0]} + + # Precompute H^2, H^3, H^4 for multi-block aggregation + @{[vsetivli__x0_4_e32_m1_tu_mu]} + @{[vle32_v $V1, $Htable]} # v1 = H + @{[vmv_v_v $V2, $V1]} + @{[vgmul_vv $V2, $V1]} # v2 = H * H = H^2 + addi $TMP0, $Htable, 16 + @{[vse32_v $V2, $TMP0]} # Htable[16] = H^2 + @{[vmv_v_v $V3, $V2]} + @{[vgmul_vv $V3, $V1]} # v3 = H^2 * H = H^3 + addi $TMP0, $TMP0, 16 + @{[vse32_v $V3, $TMP0]} # Htable[32] = H^3 + @{[vmv_v_v $V4, $V2]} + @{[vgmul_vv $V4, $V2]} # v4 = H^2 * H^2 = H^4 + addi $TMP0, $TMP0, 16 + @{[vse32_v $V4, $TMP0]} # Htable[48] = H^4 ret .size gcm_init_rv64i_zvkg,.-gcm_init_rv64i_zvkg ___ } { -my ($Htable,$H,$V0) = ("a0","a1","v0"); +my ($Htable,$H) = ("a0","a1"); $code .= <<___; .p2align 3 .globl gcm_init_rv64i_zvkg_zvkb .type gcm_init_rv64i_zvkg_zvkb,\@function gcm_init_rv64i_zvkg_zvkb: - @{[vsetivli__x0_2_e64_m1_tu_mu]} # vsetivli x0, 2, e64, m1, tu, mu - @{[vle64_v $V0, $H]} # vle64.v v0, (a1) - @{[vrev8_v $V0, $V0]} # vrev8.v v0, v0 - @{[vse64_v $V0, $Htable]} # vse64.v v0, (a0) + # Store byte-reversed H at Htable[0] + @{[vsetivli__x0_2_e64_m1_tu_mu]} + @{[vle64_v $V0, $H]} + @{[vrev8_v $V0, $V0]} + @{[vse64_v $V0, $Htable]} + + # Precompute H^2, H^3, H^4 for multi-block aggregation + @{[vsetivli__x0_4_e32_m1_tu_mu]} + # v0 already holds H (same bits, reinterpreted as 4×e32) + @{[vmv_v_v $V1, $V0]} + @{[vgmul_vv $V1, $V0]} # v1 = H^2 + addi t0, $Htable, 16 + @{[vse32_v $V1, "t0"]} # Htable[16] = H^2 + @{[vmv_v_v $V2, $V1]} + @{[vgmul_vv $V2, $V0]} # v2 = H^2 * H = H^3 + addi t0, t0, 16 + @{[vse32_v $V2, "t0"]} # Htable[32] = H^3 + @{[vmv_v_v $V3, $V1]} + @{[vgmul_vv $V3, $V1]} # v3 = H^2 * H^2 = H^4 + addi t0, t0, 16 + @{[vse32_v $V3, "t0"]} # Htable[48] = H^4 ret .size gcm_init_rv64i_zvkg_zvkb,.-gcm_init_rv64i_zvkg_zvkb ___ @@ -107,7 +148,7 @@ # void gcm_gmult_rv64i_zvkg(u64 Xi[2], const u128 Htable[16]); # # input: Xi: current hash value -# Htable: copy of H +# Htable: copy of H # output: Xi: next hash value Xi { my ($Xi,$Htable) = ("a0","a1"); @@ -130,16 +171,24 @@ ################################################################################ # void gcm_ghash_rv64i_zvkg(u64 Xi[2], const u128 Htable[16], -# const u8 *inp, size_t len); +# const u8 *inp, size_t len); # # input: Xi: current hash value -# Htable: copy of H -# inp: pointer to input data -# len: length of input data in bytes (multiple of block size) +# Htable: copy of H, H^2, H^3, H^4 +# inp: pointer to input data +# len: length of input data in bytes (multiple of block size) # output: Xi: Xi+1 (next hash value Xi) +# +# Uses 4-block aggregation when len >= 64: +# 4 independent accumulators (v20-v23), each using vghsh.vv with m1. +# Main loop: all 4 lanes multiply by H^4. +# Last 4-block set: lanes multiply by [H^4, H^3, H^2, H]. +# Result = XOR of all 4 lanes. +# Tail: single-block loop for remaining 1-3 blocks. +# This approach is VLEN-independent (always uses m1 with vl=4). { my ($Xi,$Htable,$inp,$len) = ("a0","a1","a2","a3"); -my ($vXi,$vH,$vinp,$Vzero) = ("v1","v2","v3","v4"); +my ($vXi,$vH,$vinp) = ("v1","v2","v3"); $code .= <<___; .p2align 3 @@ -147,16 +196,84 @@ .type gcm_ghash_rv64i_zvkg,\@function gcm_ghash_rv64i_zvkg: @{[vsetivli__x0_4_e32_m1_tu_mu]} - @{[vle32_v $vH, $Htable]} - @{[vle32_v $vXi, $Xi]} + @{[vle32_v $vH, $Htable]} # v2 = H + @{[vle32_v $vXi, $Xi]} # v1 = Xi + + # Check for 4-block path (need at least 64 bytes) + li t0, 64 + blt $len, t0, .Lstep_zvkg + + # --- 4-block aggregation path --- + # Load H powers: H^4, H^3, H^2 (H already in v2) + addi t0, $Htable, 48 + @{[vle32_v $V5, "t0"]} # v5 = H^4 + addi t0, $Htable, 32 + @{[vle32_v $V6, "t0"]} # v6 = H^3 + addi t0, $Htable, 16 + @{[vle32_v $V7, "t0"]} # v7 = H^2 + + # Initialize 4 accumulator lanes: v20=Xi, v21=v22=v23=0 + @{[vmv_v_v $V20, $vXi]} + @{[vmv_v_i $V21, 0]} + @{[vmv_v_i $V22, 0]} + @{[vmv_v_i $V23, 0]} + + # Need >= 128 bytes for main loop (at least 2 sets of 4 blocks) + li t0, 128 + blt $len, t0, .Llast_4x_zvkg + +.Lghash_4x_zvkg: + # Load 4 blocks + @{[vle32_v $V8, $inp]} + addi $inp, $inp, 16 + @{[vle32_v $V9, $inp]} + addi $inp, $inp, 16 + @{[vle32_v $V10, $inp]} + addi $inp, $inp, 16 + @{[vle32_v $V11, $inp]} + addi $inp, $inp, 16 + add $len, $len, -64 + # 4 independent GHASH operations with H^4 + @{[vghsh_vv $V20, $V5, $V8]} + @{[vghsh_vv $V21, $V5, $V9]} + @{[vghsh_vv $V22, $V5, $V10]} + @{[vghsh_vv $V23, $V5, $V11]} + li t0, 128 + bge $len, t0, .Lghash_4x_zvkg + +.Llast_4x_zvkg: + # Process last 4-block set with [H^4, H^3, H^2, H] + @{[vle32_v $V8, $inp]} + addi $inp, $inp, 16 + @{[vle32_v $V9, $inp]} + addi $inp, $inp, 16 + @{[vle32_v $V10, $inp]} + addi $inp, $inp, 16 + @{[vle32_v $V11, $inp]} + addi $inp, $inp, 16 + add $len, $len, -64 + @{[vghsh_vv $V20, $V5, $V8]} # lane 0 x H^4 + @{[vghsh_vv $V21, $V6, $V9]} # lane 1 x H^3 + @{[vghsh_vv $V22, $V7, $V10]} # lane 2 x H^2 + @{[vghsh_vv $V23, $vH, $V11]} # lane 3 x H + + # Combine 4 lanes: result = S0 ^ S1 ^ S2 ^ S3 + @{[vxor_vv $V20, $V20, $V21]} + @{[vxor_vv $V20, $V20, $V22]} + @{[vxor_vv $V20, $V20, $V23]} + + @{[vmv_v_v $vXi, $V20]} # v1 = combined result + beqz $len, .Ldone_zvkg -Lstep: +.Lstep_zvkg: + # Single-block loop for remaining 1-3 blocks @{[vle32_v $vinp, $inp]} - add $inp, $inp, 16 - add $len, $len, -16 + add $inp, $inp, 16 + add $len, $len, -16 @{[vghsh_vv $vXi, $vH, $vinp]} - bnez $len, Lstep + bnez $len, .Lstep_zvkg +.Ldone_zvkg: @{[vse32_v $vXi, $Xi]} ret diff --git a/crypto/modes/asm/ghash-riscv64.pl b/crypto/modes/asm/ghash-riscv64.pl index ee97ff0dd3f38..db0641dabfbec 100644 --- a/crypto/modes/asm/ghash-riscv64.pl +++ b/crypto/modes/asm/ghash-riscv64.pl @@ -2,7 +2,7 @@ # This file is dual-licensed, meaning that you can use it under your # choice of either of the following two licenses: # -# Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You can obtain # a copy in the file LICENSE in the source distribution or at @@ -11,6 +11,7 @@ # or # # Copyright (c) 2023, Christoph Müllner +# Copyright (c) 2026, Julian Zhu # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -68,6 +69,7 @@ { my ($Htable,$H,$VAL0,$VAL1,$TMP0,$TMP1,$TMP2) = ("a0","a1","a2","a3","t0","t1","t2"); +my ($z0,$z1,$z2,$z3,$r0,$r1,$polymod) = ("a4","a5","a6","a7","t3","t4","t5"); $code .= <<___; .p2align 3 @@ -80,6 +82,73 @@ @{[brev8_rv64i $VAL1, $TMP0, $TMP1, $TMP2]} @{[sd_rev8_rv64i $VAL0, $Htable, 0, $TMP0]} @{[sd_rev8_rv64i $VAL1, $Htable, 8, $TMP0]} + + # Compute H^2 = H*H for 2-block ghash aggregation. + # Re-load H in multiply-ready format. + ld $VAL0, 0($Htable) + ld $VAL1, 8($Htable) + la $polymod, Lpolymod + lbu $polymod, 0($polymod) + # Squaring in GF(2): cross terms cancel, only 4 clmul needed. + @{[clmulh $z3, $VAL1, $VAL1]} + @{[clmul $z2, $VAL1, $VAL1]} + @{[clmulh $z1, $VAL0, $VAL0]} + @{[clmul $z0, $VAL0, $VAL0]} + @{[clmulh $r1, $z3, $polymod]} + @{[clmul $r0, $z3, $polymod]} + xor $z2, $z2, $r1 + xor $z1, $z1, $r0 + @{[clmulh $r1, $z2, $polymod]} + @{[clmul $r0, $z2, $polymod]} + xor $VAL1, $z1, $r1 + xor $VAL0, $z0, $r0 + sd $VAL0, 16($Htable) + sd $VAL1, 24($Htable) + + # Compute H^3 = H^2 * H for 4-block ghash aggregation. + ld $TMP0, 0($Htable) + ld $TMP1, 8($Htable) + @{[clmulh $z3, $VAL1, $TMP1]} + @{[clmul $z2, $VAL1, $TMP1]} + @{[clmulh $r1, $VAL0, $TMP1]} + @{[clmul $z1, $VAL0, $TMP1]} + xor $z2, $z2, $r1 + @{[clmulh $r1, $VAL1, $TMP0]} + @{[clmul $r0, $VAL1, $TMP0]} + xor $z2, $z2, $r1 + xor $z1, $z1, $r0 + @{[clmulh $r1, $VAL0, $TMP0]} + @{[clmul $z0, $VAL0, $TMP0]} + xor $z1, $z1, $r1 + @{[clmulh $r1, $z3, $polymod]} + @{[clmul $r0, $z3, $polymod]} + xor $z2, $z2, $r1 + xor $z1, $z1, $r0 + @{[clmulh $r1, $z2, $polymod]} + @{[clmul $r0, $z2, $polymod]} + xor $VAL1, $z1, $r1 + xor $VAL0, $z0, $r0 + sd $VAL0, 32($Htable) + sd $VAL1, 40($Htable) + + # Compute H^4 = (H^2)^2. + ld $TMP0, 16($Htable) + ld $TMP1, 24($Htable) + @{[clmulh $z3, $TMP1, $TMP1]} + @{[clmul $z2, $TMP1, $TMP1]} + @{[clmulh $z1, $TMP0, $TMP0]} + @{[clmul $z0, $TMP0, $TMP0]} + @{[clmulh $r1, $z3, $polymod]} + @{[clmul $r0, $z3, $polymod]} + xor $z2, $z2, $r1 + xor $z1, $z1, $r0 + @{[clmulh $r1, $z2, $polymod]} + @{[clmul $r0, $z2, $polymod]} + xor $VAL1, $z1, $r1 + xor $VAL0, $z0, $r0 + sd $VAL0, 48($Htable) + sd $VAL1, 56($Htable) + ret .size gcm_init_rv64i_zbc,.-gcm_init_rv64i_zbc ___ @@ -87,6 +156,7 @@ { my ($Htable,$H,$VAL0,$VAL1,$TMP0,$TMP1,$TMP2) = ("a0","a1","a2","a3","t0","t1","t2"); +my ($z0,$z1,$z2,$z3,$r0,$r1,$polymod) = ("a4","a5","a6","a7","t3","t4","t5"); $code .= <<___; .p2align 3 @@ -101,6 +171,69 @@ @{[rev8 $VAL1, $VAL1]} sd $VAL0,0($Htable) sd $VAL1,8($Htable) + + # Compute H^2. VAL0/VAL1 are already in loaded format. + la $polymod, Lpolymod + lbu $polymod, 0($polymod) + @{[clmulh $z3, $VAL1, $VAL1]} + @{[clmul $z2, $VAL1, $VAL1]} + @{[clmulh $z1, $VAL0, $VAL0]} + @{[clmul $z0, $VAL0, $VAL0]} + @{[clmulh $r1, $z3, $polymod]} + @{[clmul $r0, $z3, $polymod]} + xor $z2, $z2, $r1 + xor $z1, $z1, $r0 + @{[clmulh $r1, $z2, $polymod]} + @{[clmul $r0, $z2, $polymod]} + xor $VAL1, $z1, $r1 + xor $VAL0, $z0, $r0 + sd $VAL0, 16($Htable) + sd $VAL1, 24($Htable) + + # Compute H^3 = H^2 * H for 4-block ghash aggregation. + ld $TMP0, 0($Htable) + ld $TMP1, 8($Htable) + @{[clmulh $z3, $VAL1, $TMP1]} + @{[clmul $z2, $VAL1, $TMP1]} + @{[clmulh $r1, $VAL0, $TMP1]} + @{[clmul $z1, $VAL0, $TMP1]} + xor $z2, $z2, $r1 + @{[clmulh $r1, $VAL1, $TMP0]} + @{[clmul $r0, $VAL1, $TMP0]} + xor $z2, $z2, $r1 + xor $z1, $z1, $r0 + @{[clmulh $r1, $VAL0, $TMP0]} + @{[clmul $z0, $VAL0, $TMP0]} + xor $z1, $z1, $r1 + @{[clmulh $r1, $z3, $polymod]} + @{[clmul $r0, $z3, $polymod]} + xor $z2, $z2, $r1 + xor $z1, $z1, $r0 + @{[clmulh $r1, $z2, $polymod]} + @{[clmul $r0, $z2, $polymod]} + xor $VAL1, $z1, $r1 + xor $VAL0, $z0, $r0 + sd $VAL0, 32($Htable) + sd $VAL1, 40($Htable) + + # Compute H^4 = (H^2)^2. + ld $TMP0, 16($Htable) + ld $TMP1, 24($Htable) + @{[clmulh $z3, $TMP1, $TMP1]} + @{[clmul $z2, $TMP1, $TMP1]} + @{[clmulh $z1, $TMP0, $TMP0]} + @{[clmul $z0, $TMP0, $TMP0]} + @{[clmulh $r1, $z3, $polymod]} + @{[clmul $r0, $z3, $polymod]} + xor $z2, $z2, $r1 + xor $z1, $z1, $r0 + @{[clmulh $r1, $z2, $polymod]} + @{[clmul $r0, $z2, $polymod]} + xor $VAL1, $z1, $r1 + xor $VAL0, $z0, $r0 + sd $VAL0, 48($Htable) + sd $VAL1, 56($Htable) + ret .size gcm_init_rv64i_zbc__zbb,.-gcm_init_rv64i_zbc__zbb ___ @@ -108,6 +241,7 @@ { my ($Htable,$H,$TMP0,$TMP1) = ("a0","a1","t0","t1"); +my ($z0,$z1,$z2,$z3,$r0,$r1,$polymod) = ("a2","a3","a4","a5","t2","t3","t4"); $code .= <<___; .p2align 3 @@ -122,6 +256,72 @@ @{[rev8 $TMP1, $TMP1]} sd $TMP0,0($Htable) sd $TMP1,8($Htable) + + # Compute H^2. TMP0/TMP1 are already in loaded format. + la $polymod, Lpolymod + lbu $polymod, 0($polymod) + @{[clmulh $z3, $TMP1, $TMP1]} + @{[clmul $z2, $TMP1, $TMP1]} + @{[clmulh $z1, $TMP0, $TMP0]} + @{[clmul $z0, $TMP0, $TMP0]} + @{[clmulh $r1, $z3, $polymod]} + @{[clmul $r0, $z3, $polymod]} + xor $z2, $z2, $r1 + xor $z1, $z1, $r0 + @{[clmulh $r1, $z2, $polymod]} + @{[clmul $r0, $z2, $polymod]} + xor $TMP1, $z1, $r1 + xor $TMP0, $z0, $r0 + sd $TMP0, 16($Htable) + sd $TMP1, 24($Htable) + + # Compute H^3 = H^2 * H for 4-block ghash aggregation. + # H^2 is in TMP0:TMP1. Load H into z0:H (a2:a1). + ld $z0, 0($Htable) + ld $H, 8($Htable) + # Schoolbook multiply (TMP0:TMP1) * (z0:H). + # Order: read z0 as input before overwriting as product. + @{[clmulh $z3, $TMP1, $H]} + @{[clmul $z2, $TMP1, $H]} + @{[clmulh $r1, $TMP0, $H]} + @{[clmul $z1, $TMP0, $H]} + xor $z2, $z2, $r1 + @{[clmulh $r1, $TMP1, $z0]} + @{[clmul $r0, $TMP1, $z0]} + xor $z2, $z2, $r1 + xor $z1, $z1, $r0 + @{[clmulh $r1, $TMP0, $z0]} + @{[clmul $z0, $TMP0, $z0]} + xor $z1, $z1, $r1 + @{[clmulh $r1, $z3, $polymod]} + @{[clmul $r0, $z3, $polymod]} + xor $z2, $z2, $r1 + xor $z1, $z1, $r0 + @{[clmulh $r1, $z2, $polymod]} + @{[clmul $r0, $z2, $polymod]} + xor $TMP1, $z1, $r1 + xor $TMP0, $z0, $r0 + sd $TMP0, 32($Htable) + sd $TMP1, 40($Htable) + + # Compute H^4 = (H^2)^2. + ld $TMP0, 16($Htable) + ld $TMP1, 24($Htable) + @{[clmulh $z3, $TMP1, $TMP1]} + @{[clmul $z2, $TMP1, $TMP1]} + @{[clmulh $z1, $TMP0, $TMP0]} + @{[clmul $z0, $TMP0, $TMP0]} + @{[clmulh $r1, $z3, $polymod]} + @{[clmul $r0, $z3, $polymod]} + xor $z2, $z2, $r1 + xor $z1, $z1, $r0 + @{[clmulh $r1, $z2, $polymod]} + @{[clmul $r0, $z2, $polymod]} + xor $TMP1, $z1, $r1 + xor $TMP0, $z0, $r0 + sd $TMP0, 48($Htable) + sd $TMP1, 56($Htable) + ret .size gcm_init_rv64i_zbc__zbkb,.-gcm_init_rv64i_zbc__zbkb ___ @@ -269,30 +469,34 @@ # len: length of input data in bytes (multiple of block size) # output: Xi: Xi+1 (next hash value Xi) { -my ($Xi,$Htable,$inp,$len,$x0,$x1,$y0,$y1) = ("a0","a1","a2","a3","a4","a5","a6","a7"); +my ($Xi,$Htable,$inp,$len) = ("a0","a1","a2","a3"); +my ($x0,$x1,$y0,$y1) = ("a4","a5","a6","a7"); my ($z0,$z1,$z2,$z3,$t0,$t1,$polymod) = ("t0","t1","t2","t3","t4","t5","t6"); +# Additional regs for 2-block aggregation path +my ($sXi,$sH0,$sH1,$sH2_0,$sH2_1,$sP) = ("s0","s1","s2","s3","s4","s5"); +# Additional regs for 4-block aggregation path +my ($sH3_0,$sH3_1,$sH4_0,$sH4_1) = ("s6","s7","s8","s9"); $code .= <<___; .p2align 3 .globl gcm_ghash_rv64i_zbc .type gcm_ghash_rv64i_zbc,\@function gcm_ghash_rv64i_zbc: - # Load Xi and bit-reverse it + # Fast path: skip s-reg setup for small inputs (< 128 bytes) + li $z0, 128 + bge $len, $z0, Lghash_2x_enter + + # --- Original single-block path (no s-reg overhead) --- ld $x0, 0($Xi) ld $x1, 8($Xi) @{[brev8_rv64i $x0, $z0, $z1, $z2]} @{[brev8_rv64i $x1, $z0, $z1, $z2]} - - # Load the key (already bit-reversed) ld $y0, 0($Htable) ld $y1, 8($Htable) - - # Load the reduction constant la $polymod, Lpolymod lbu $polymod, 0($polymod) -Lstep: - # Load the input data, bit-reverse them, and XOR them with Xi +Lghash_orig_loop: ld $t0, 0($inp) ld $t1, 8($inp) add $inp, $inp, 16 @@ -302,7 +506,6 @@ xor $x0, $x0, $t0 xor $x1, $x1, $t1 - # Multiplication (without Karatsuba) @{[clmulh $z3, $x1, $y1]} @{[clmul $z2, $x1, $y1]} @{[clmulh $t1, $x0, $y1]} @@ -316,7 +519,6 @@ @{[clmul $z0, $x0, $y0]} xor $z1, $z1, $t1 - # Reduction with clmul @{[clmulh $t1, $z3, $polymod]} @{[clmul $t0, $z3, $polymod]} xor $z2, $z2, $t1 @@ -326,44 +528,335 @@ xor $x1, $z1, $t1 xor $x0, $z0, $t0 - # Iterate over all blocks - bnez $len, Lstep + bnez $len, Lghash_orig_loop - # Bit-reverse final Xi back and store it @{[brev8_rv64i $x0, $z0, $z1, $z2]} @{[brev8_rv64i $x1, $z0, $z1, $z2]} sd $x0, 0($Xi) sd $x1, 8($Xi) ret + +Lghash_2x_enter: + # --- Multi-block aggregation path --- + addi sp, sp, -48 + sd $sXi, 0(sp) + sd $sH0, 8(sp) + sd $sH1, 16(sp) + sd $sH2_0, 24(sp) + sd $sH2_1, 32(sp) + sd $sP, 40(sp) + + mv $sXi, $Xi + ld $sH0, 0($Htable) + ld $sH1, 8($Htable) + ld $sH2_0, 16($Htable) + ld $sH2_1, 24($Htable) + la $sP, Lpolymod + lbu $sP, 0($sP) + + ld $x0, 0($sXi) + ld $x1, 8($sXi) + @{[brev8_rv64i $x0, $z0, $z1, $z2]} + @{[brev8_rv64i $x1, $z0, $z1, $z2]} + + # Check if 4-block aggregation is possible (>= 64 bytes = 4 blocks) + li $z0, 64 + blt $len, $z0, Lghash_2x + + # Save additional s6-s9, load H^3 and H^4 + addi sp, sp, -32 + sd $sH3_0, 0(sp) + sd $sH3_1, 8(sp) + sd $sH4_0, 16(sp) + sd $sH4_1, 24(sp) + ld $sH3_0, 32($Htable) + ld $sH3_1, 40($Htable) + ld $sH4_0, 48($Htable) + ld $sH4_1, 56($Htable) + +Lghash_4x: + # --- 4-block iteration: processes 64 bytes --- + # Phase 1: A = (Xi^C1)*H^4, B = C2*H^3 + + ld $z3, 0($inp) + ld $t0, 8($inp) + @{[brev8_rv64i $z3, $z0, $z1, $z2]} + @{[brev8_rv64i $t0, $z0, $z1, $z2]} + xor $x0, $x0, $z3 + xor $x1, $x1, $t0 + + ld $y0, 16($inp) + ld $y1, 24($inp) + @{[brev8_rv64i $y0, $z0, $z1, $z2]} + @{[brev8_rv64i $y1, $z0, $z1, $z2]} + + # Interleaved multiply A = (x1:x0)*H^4, B = (y1:y0)*H^3 + @{[clmulh $z3, $x1, $sH4_1]} + @{[clmulh $t1, $y1, $sH3_1]} + @{[clmul $z2, $x1, $sH4_1]} + @{[clmul $t0, $y1, $sH3_1]} + xor $z3, $z3, $t1 + xor $z2, $z2, $t0 + + @{[clmulh $t1, $x0, $sH4_1]} + @{[clmulh $t0, $y0, $sH3_1]} + xor $z2, $z2, $t1 + xor $z2, $z2, $t0 + @{[clmul $z1, $x0, $sH4_1]} + @{[clmul $t1, $y0, $sH3_1]} + xor $z1, $z1, $t1 + + @{[clmulh $t1, $x1, $sH4_0]} + @{[clmulh $t0, $y1, $sH3_0]} + xor $z2, $z2, $t1 + xor $z2, $z2, $t0 + @{[clmul $t1, $x1, $sH4_0]} + @{[clmul $t0, $y1, $sH3_0]} + xor $z1, $z1, $t1 + xor $z1, $z1, $t0 + + @{[clmulh $t1, $x0, $sH4_0]} + @{[clmulh $t0, $y0, $sH3_0]} + xor $z1, $z1, $t1 + xor $z1, $z1, $t0 + @{[clmul $z0, $x0, $sH4_0]} + @{[clmul $t1, $y0, $sH3_0]} + xor $z0, $z0, $t1 + + # Phase 1 product in z3:z2:z1:z0 = t3:t2:t1:t0. + # Load C3, C4 — use $t0/$t1/$polymod (t4/t5/t6) as brev8 temps + # to avoid clobbering Phase 1 product in t0-t3. + ld $x0, 32($inp) + ld $x1, 40($inp) + @{[brev8_rv64i $x0, $t0, $t1, $polymod]} + @{[brev8_rv64i $x1, $t0, $t1, $polymod]} + + ld $y0, 48($inp) + ld $y1, 56($inp) + @{[brev8_rv64i $y0, $t0, $t1, $polymod]} + @{[brev8_rv64i $y1, $t0, $t1, $polymod]} + + addi $inp, $inp, 64 + addi $len, $len, -64 + + # Phase 2: C = C3*H^2, D = C4*H (single-temp interleave) + # Product in w3:w2:w1:w0 = $t1:$t0:$Htable:$Xi + # Scratch: $polymod (t6) + + @{[clmulh $t1, $x1, $sH2_1]} + @{[clmulh $polymod, $y1, $sH1]} + xor $t1, $t1, $polymod + @{[clmul $t0, $x1, $sH2_1]} + @{[clmul $polymod, $y1, $sH1]} + xor $t0, $t0, $polymod + + @{[clmulh $polymod, $x0, $sH2_1]} + xor $t0, $t0, $polymod + @{[clmulh $polymod, $y0, $sH1]} + xor $t0, $t0, $polymod + @{[clmul $Htable, $x0, $sH2_1]} + @{[clmul $polymod, $y0, $sH1]} + xor $Htable, $Htable, $polymod + + @{[clmulh $polymod, $x1, $sH2_0]} + xor $t0, $t0, $polymod + @{[clmulh $polymod, $y1, $sH0]} + xor $t0, $t0, $polymod + @{[clmul $polymod, $x1, $sH2_0]} + xor $Htable, $Htable, $polymod + @{[clmul $polymod, $y1, $sH0]} + xor $Htable, $Htable, $polymod + + @{[clmulh $polymod, $x0, $sH2_0]} + xor $Htable, $Htable, $polymod + @{[clmulh $polymod, $y0, $sH0]} + xor $Htable, $Htable, $polymod + @{[clmul $Xi, $x0, $sH2_0]} + @{[clmul $polymod, $y0, $sH0]} + xor $Xi, $Xi, $polymod + + # Combine Phase 1 + Phase 2 products + xor $z0, $z0, $Xi + xor $z1, $z1, $Htable + xor $z2, $z2, $t0 + xor $z3, $z3, $t1 + + # Single reduction for all 4 blocks + @{[clmulh $t1, $z3, $sP]} + @{[clmul $t0, $z3, $sP]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $z2, $sP]} + @{[clmul $t0, $z2, $sP]} + xor $x1, $z1, $t1 + xor $x0, $z0, $t0 + + li $z0, 64 + bge $len, $z0, Lghash_4x + + # Restore s6-s9 + ld $sH3_0, 0(sp) + ld $sH3_1, 8(sp) + ld $sH4_0, 16(sp) + ld $sH4_1, 24(sp) + addi sp, sp, 32 + +Lghash_2x: + # Guard: skip 2-block loop if len < 32 (e.g. after 4-block consumed all data) + li $z0, 32 + blt $len, $z0, Lghash_2x_tail_check + + # Load first input block, bit-reverse, XOR with Xi + ld $z3, 0($inp) + ld $t0, 8($inp) + @{[brev8_rv64i $z3, $z0, $z1, $z2]} + @{[brev8_rv64i $t0, $z0, $z1, $z2]} + xor $x0, $x0, $z3 + xor $x1, $x1, $t0 + + # Load second input block, bit-reverse + ld $y0, 16($inp) + ld $y1, 24($inp) + @{[brev8_rv64i $y0, $z0, $z1, $z2]} + @{[brev8_rv64i $y1, $z0, $z1, $z2]} + + addi $inp, $inp, 32 + addi $len, $len, -32 + + # Interleaved multiplication (A + B accumulated into z3:z2:z1:z0): + # A = (x1:x0) * (sH2_1:sH2_0) = (Xi^C1) * H^2 + # B = (y1:y0) * (sH1:sH0) = C2 * H + + # high * high + @{[clmulh $z3, $x1, $sH2_1]} + @{[clmulh $t1, $y1, $sH1]} + @{[clmul $z2, $x1, $sH2_1]} + @{[clmul $t0, $y1, $sH1]} + xor $z3, $z3, $t1 + xor $z2, $z2, $t0 + + # low * high + @{[clmulh $t1, $x0, $sH2_1]} + @{[clmulh $t0, $y0, $sH1]} + xor $z2, $z2, $t1 + xor $z2, $z2, $t0 + @{[clmul $z1, $x0, $sH2_1]} + @{[clmul $t1, $y0, $sH1]} + xor $z1, $z1, $t1 + + # high * low + @{[clmulh $t1, $x1, $sH2_0]} + @{[clmulh $t0, $y1, $sH0]} + xor $z2, $z2, $t1 + xor $z2, $z2, $t0 + @{[clmul $t1, $x1, $sH2_0]} + @{[clmul $t0, $y1, $sH0]} + xor $z1, $z1, $t1 + xor $z1, $z1, $t0 + + # low * low + @{[clmulh $t1, $x0, $sH2_0]} + @{[clmulh $t0, $y0, $sH0]} + xor $z1, $z1, $t1 + xor $z1, $z1, $t0 + @{[clmul $z0, $x0, $sH2_0]} + @{[clmul $t1, $y0, $sH0]} + xor $z0, $z0, $t1 + + # Reduction with clmul + @{[clmulh $t1, $z3, $sP]} + @{[clmul $t0, $z3, $sP]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $z2, $sP]} + @{[clmul $t0, $z2, $sP]} + xor $x1, $z1, $t1 + xor $x0, $z0, $t0 + + li $z0, 32 + bge $len, $z0, Lghash_2x + + # Handle remaining single block (if any) +Lghash_2x_tail_check: + beqz $len, Lghash_2x_done + +Lghash_1x_tail: + ld $z3, 0($inp) + ld $t0, 8($inp) + addi $inp, $inp, 16 + addi $len, $len, -16 + @{[brev8_rv64i $z3, $z0, $z1, $z2]} + @{[brev8_rv64i $t0, $z0, $z1, $z2]} + xor $x0, $x0, $z3 + xor $x1, $x1, $t0 + + @{[clmulh $z3, $x1, $sH1]} + @{[clmul $z2, $x1, $sH1]} + @{[clmulh $t1, $x0, $sH1]} + @{[clmul $z1, $x0, $sH1]} + xor $z2, $z2, $t1 + @{[clmulh $t1, $x1, $sH0]} + @{[clmul $t0, $x1, $sH0]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $x0, $sH0]} + @{[clmul $z0, $x0, $sH0]} + xor $z1, $z1, $t1 + + @{[clmulh $t1, $z3, $sP]} + @{[clmul $t0, $z3, $sP]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $z2, $sP]} + @{[clmul $t0, $z2, $sP]} + xor $x1, $z1, $t1 + xor $x0, $z0, $t0 + +Lghash_2x_done: + @{[brev8_rv64i $x0, $z0, $z1, $z2]} + @{[brev8_rv64i $x1, $z0, $z1, $z2]} + sd $x0, 0($sXi) + sd $x1, 8($sXi) + + ld $sXi, 0(sp) + ld $sH0, 8(sp) + ld $sH1, 16(sp) + ld $sH2_0, 24(sp) + ld $sH2_1, 32(sp) + ld $sP, 40(sp) + addi sp, sp, 48 + ret .size gcm_ghash_rv64i_zbc,.-gcm_ghash_rv64i_zbc ___ } { -my ($Xi,$Htable,$inp,$len,$x0,$x1,$y0,$y1) = ("a0","a1","a2","a3","a4","a5","a6","a7"); +my ($Xi,$Htable,$inp,$len) = ("a0","a1","a2","a3"); +my ($x0,$x1,$y0,$y1) = ("a4","a5","a6","a7"); my ($z0,$z1,$z2,$z3,$t0,$t1,$polymod) = ("t0","t1","t2","t3","t4","t5","t6"); +my ($sXi,$sH0,$sH1,$sH2_0,$sH2_1,$sP) = ("s0","s1","s2","s3","s4","s5"); +my ($sH3_0,$sH3_1,$sH4_0,$sH4_1) = ("s6","s7","s8","s9"); $code .= <<___; .p2align 3 .globl gcm_ghash_rv64i_zbc__zbkb .type gcm_ghash_rv64i_zbc__zbkb,\@function gcm_ghash_rv64i_zbc__zbkb: - # Load Xi and bit-reverse it + # Fast path: skip s-reg setup for small inputs (< 128 bytes) + li $z0, 128 + bge $len, $z0, Lghash_2x_enter_zbkb + + # --- Original single-block path (no s-reg overhead) --- ld $x0, 0($Xi) ld $x1, 8($Xi) @{[brev8 $x0, $x0]} @{[brev8 $x1, $x1]} - - # Load the key (already bit-reversed) ld $y0, 0($Htable) ld $y1, 8($Htable) - - # Load the reduction constant la $polymod, Lpolymod lbu $polymod, 0($polymod) -Lstep_zkbk: - # Load the input data, bit-reverse them, and XOR them with Xi +Lghash_orig_loop_zbkb: ld $t0, 0($inp) ld $t1, 8($inp) add $inp, $inp, 16 @@ -373,7 +866,6 @@ xor $x0, $x0, $t0 xor $x1, $x1, $t1 - # Multiplication (without Karatsuba) @{[clmulh $z3, $x1, $y1]} @{[clmul $z2, $x1, $y1]} @{[clmulh $t1, $x0, $y1]} @@ -387,7 +879,6 @@ @{[clmul $z0, $x0, $y0]} xor $z1, $z1, $t1 - # Reduction with clmul @{[clmulh $t1, $z3, $polymod]} @{[clmul $t0, $z3, $polymod]} xor $z2, $z2, $t1 @@ -397,14 +888,289 @@ xor $x1, $z1, $t1 xor $x0, $z0, $t0 - # Iterate over all blocks - bnez $len, Lstep_zkbk + bnez $len, Lghash_orig_loop_zbkb - # Bit-reverse final Xi back and store it @{[brev8 $x0, $x0]} @{[brev8 $x1, $x1]} - sd $x0, 0($Xi) - sd $x1, 8($Xi) + sd $x0, 0($Xi) + sd $x1, 8($Xi) + ret + +Lghash_2x_enter_zbkb: + # --- Multi-block aggregation path --- + addi sp, sp, -48 + sd $sXi, 0(sp) + sd $sH0, 8(sp) + sd $sH1, 16(sp) + sd $sH2_0, 24(sp) + sd $sH2_1, 32(sp) + sd $sP, 40(sp) + + mv $sXi, $Xi + ld $sH0, 0($Htable) + ld $sH1, 8($Htable) + ld $sH2_0, 16($Htable) + ld $sH2_1, 24($Htable) + la $sP, Lpolymod + lbu $sP, 0($sP) + + ld $x0, 0($sXi) + ld $x1, 8($sXi) + @{[brev8 $x0, $x0]} + @{[brev8 $x1, $x1]} + + # Check if 4-block aggregation is possible (>= 64 bytes) + li $z0, 64 + blt $len, $z0, Lghash_2x_zbkb + + # Save additional s6-s9, load H^3 and H^4 + addi sp, sp, -32 + sd $sH3_0, 0(sp) + sd $sH3_1, 8(sp) + sd $sH4_0, 16(sp) + sd $sH4_1, 24(sp) + ld $sH3_0, 32($Htable) + ld $sH3_1, 40($Htable) + ld $sH4_0, 48($Htable) + ld $sH4_1, 56($Htable) + +Lghash_4x_zbkb: + # --- 4-block iteration: processes 64 bytes --- + # Phase 1: A = (Xi^C1)*H^4, B = C2*H^3 + + ld $z3, 0($inp) + ld $t0, 8($inp) + @{[brev8 $z3, $z3]} + @{[brev8 $t0, $t0]} + xor $x0, $x0, $z3 + xor $x1, $x1, $t0 + + ld $y0, 16($inp) + ld $y1, 24($inp) + @{[brev8 $y0, $y0]} + @{[brev8 $y1, $y1]} + + # Interleaved multiply A = (x1:x0)*H^4, B = (y1:y0)*H^3 + @{[clmulh $z3, $x1, $sH4_1]} + @{[clmulh $t1, $y1, $sH3_1]} + @{[clmul $z2, $x1, $sH4_1]} + @{[clmul $t0, $y1, $sH3_1]} + xor $z3, $z3, $t1 + xor $z2, $z2, $t0 + + @{[clmulh $t1, $x0, $sH4_1]} + @{[clmulh $t0, $y0, $sH3_1]} + xor $z2, $z2, $t1 + xor $z2, $z2, $t0 + @{[clmul $z1, $x0, $sH4_1]} + @{[clmul $t1, $y0, $sH3_1]} + xor $z1, $z1, $t1 + + @{[clmulh $t1, $x1, $sH4_0]} + @{[clmulh $t0, $y1, $sH3_0]} + xor $z2, $z2, $t1 + xor $z2, $z2, $t0 + @{[clmul $t1, $x1, $sH4_0]} + @{[clmul $t0, $y1, $sH3_0]} + xor $z1, $z1, $t1 + xor $z1, $z1, $t0 + + @{[clmulh $t1, $x0, $sH4_0]} + @{[clmulh $t0, $y0, $sH3_0]} + xor $z1, $z1, $t1 + xor $z1, $z1, $t0 + @{[clmul $z0, $x0, $sH4_0]} + @{[clmul $t1, $y0, $sH3_0]} + xor $z0, $z0, $t1 + + # Phase 1 product in z3:z2:z1:z0. + # Load C3, C4 — zbkb brev8 is in-place, no temp conflict. + ld $x0, 32($inp) + ld $x1, 40($inp) + @{[brev8 $x0, $x0]} + @{[brev8 $x1, $x1]} + + ld $y0, 48($inp) + ld $y1, 56($inp) + @{[brev8 $y0, $y0]} + @{[brev8 $y1, $y1]} + + addi $inp, $inp, 64 + addi $len, $len, -64 + + # Phase 2: C = C3*H^2, D = C4*H (single-temp interleave) + # Product in w3:w2:w1:w0 = $t1:$t0:$Htable:$Xi + # Scratch: $polymod (t6) + + @{[clmulh $t1, $x1, $sH2_1]} + @{[clmulh $polymod, $y1, $sH1]} + xor $t1, $t1, $polymod + @{[clmul $t0, $x1, $sH2_1]} + @{[clmul $polymod, $y1, $sH1]} + xor $t0, $t0, $polymod + + @{[clmulh $polymod, $x0, $sH2_1]} + xor $t0, $t0, $polymod + @{[clmulh $polymod, $y0, $sH1]} + xor $t0, $t0, $polymod + @{[clmul $Htable, $x0, $sH2_1]} + @{[clmul $polymod, $y0, $sH1]} + xor $Htable, $Htable, $polymod + + @{[clmulh $polymod, $x1, $sH2_0]} + xor $t0, $t0, $polymod + @{[clmulh $polymod, $y1, $sH0]} + xor $t0, $t0, $polymod + @{[clmul $polymod, $x1, $sH2_0]} + xor $Htable, $Htable, $polymod + @{[clmul $polymod, $y1, $sH0]} + xor $Htable, $Htable, $polymod + + @{[clmulh $polymod, $x0, $sH2_0]} + xor $Htable, $Htable, $polymod + @{[clmulh $polymod, $y0, $sH0]} + xor $Htable, $Htable, $polymod + @{[clmul $Xi, $x0, $sH2_0]} + @{[clmul $polymod, $y0, $sH0]} + xor $Xi, $Xi, $polymod + + # Combine Phase 1 + Phase 2 products + xor $z0, $z0, $Xi + xor $z1, $z1, $Htable + xor $z2, $z2, $t0 + xor $z3, $z3, $t1 + + # Single reduction for all 4 blocks + @{[clmulh $t1, $z3, $sP]} + @{[clmul $t0, $z3, $sP]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $z2, $sP]} + @{[clmul $t0, $z2, $sP]} + xor $x1, $z1, $t1 + xor $x0, $z0, $t0 + + li $z0, 64 + bge $len, $z0, Lghash_4x_zbkb + + # Restore s6-s9 + ld $sH3_0, 0(sp) + ld $sH3_1, 8(sp) + ld $sH4_0, 16(sp) + ld $sH4_1, 24(sp) + addi sp, sp, 32 + +Lghash_2x_zbkb: + # Guard: skip 2-block loop if len < 32 + li $z0, 32 + blt $len, $z0, Lghash_2x_tail_check_zbkb + + ld $z3, 0($inp) + ld $t0, 8($inp) + @{[brev8 $z3, $z3]} + @{[brev8 $t0, $t0]} + xor $x0, $x0, $z3 + xor $x1, $x1, $t0 + + ld $y0, 16($inp) + ld $y1, 24($inp) + @{[brev8 $y0, $y0]} + @{[brev8 $y1, $y1]} + + addi $inp, $inp, 32 + addi $len, $len, -32 + + @{[clmulh $z3, $x1, $sH2_1]} + @{[clmulh $t1, $y1, $sH1]} + @{[clmul $z2, $x1, $sH2_1]} + @{[clmul $t0, $y1, $sH1]} + xor $z3, $z3, $t1 + xor $z2, $z2, $t0 + + @{[clmulh $t1, $x0, $sH2_1]} + @{[clmulh $t0, $y0, $sH1]} + xor $z2, $z2, $t1 + xor $z2, $z2, $t0 + @{[clmul $z1, $x0, $sH2_1]} + @{[clmul $t1, $y0, $sH1]} + xor $z1, $z1, $t1 + + @{[clmulh $t1, $x1, $sH2_0]} + @{[clmulh $t0, $y1, $sH0]} + xor $z2, $z2, $t1 + xor $z2, $z2, $t0 + @{[clmul $t1, $x1, $sH2_0]} + @{[clmul $t0, $y1, $sH0]} + xor $z1, $z1, $t1 + xor $z1, $z1, $t0 + + @{[clmulh $t1, $x0, $sH2_0]} + @{[clmulh $t0, $y0, $sH0]} + xor $z1, $z1, $t1 + xor $z1, $z1, $t0 + @{[clmul $z0, $x0, $sH2_0]} + @{[clmul $t1, $y0, $sH0]} + xor $z0, $z0, $t1 + + @{[clmulh $t1, $z3, $sP]} + @{[clmul $t0, $z3, $sP]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $z2, $sP]} + @{[clmul $t0, $z2, $sP]} + xor $x1, $z1, $t1 + xor $x0, $z0, $t0 + + li $z0, 32 + bge $len, $z0, Lghash_2x_zbkb + +Lghash_2x_tail_check_zbkb: + beqz $len, Lghash_2x_done_zbkb + + ld $z3, 0($inp) + ld $t0, 8($inp) + addi $inp, $inp, 16 + addi $len, $len, -16 + @{[brev8 $z3, $z3]} + @{[brev8 $t0, $t0]} + xor $x0, $x0, $z3 + xor $x1, $x1, $t0 + + @{[clmulh $z3, $x1, $sH1]} + @{[clmul $z2, $x1, $sH1]} + @{[clmulh $t1, $x0, $sH1]} + @{[clmul $z1, $x0, $sH1]} + xor $z2, $z2, $t1 + @{[clmulh $t1, $x1, $sH0]} + @{[clmul $t0, $x1, $sH0]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $x0, $sH0]} + @{[clmul $z0, $x0, $sH0]} + xor $z1, $z1, $t1 + + @{[clmulh $t1, $z3, $sP]} + @{[clmul $t0, $z3, $sP]} + xor $z2, $z2, $t1 + xor $z1, $z1, $t0 + @{[clmulh $t1, $z2, $sP]} + @{[clmul $t0, $z2, $sP]} + xor $x1, $z1, $t1 + xor $x0, $z0, $t0 + +Lghash_2x_done_zbkb: + @{[brev8 $x0, $x0]} + @{[brev8 $x1, $x1]} + sd $x0, 0($sXi) + sd $x1, 8($sXi) + + ld $sXi, 0(sp) + ld $sH0, 8(sp) + ld $sH1, 16(sp) + ld $sH2_0, 24(sp) + ld $sH2_1, 32(sp) + ld $sP, 40(sp) + addi sp, sp, 48 ret .size gcm_ghash_rv64i_zbc__zbkb,.-gcm_ghash_rv64i_zbc__zbkb ___ diff --git a/crypto/modes/asm/ghash-s390x.pl b/crypto/modes/asm/ghash-s390x.pl index fbb4ac6ffa082..84fc5550953bf 100644 --- a/crypto/modes/asm/ghash-s390x.pl +++ b/crypto/modes/asm/ghash-s390x.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2010-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2010-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/modes/asm/ghash-sparcv9.pl b/crypto/modes/asm/ghash-sparcv9.pl index 63021645c06a6..b28b752ef0936 100644 --- a/crypto/modes/asm/ghash-sparcv9.pl +++ b/crypto/modes/asm/ghash-sparcv9.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2010-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2010-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/modes/asm/ghash-x86_64.pl b/crypto/modes/asm/ghash-x86_64.pl index 5a761cfb1f62b..5371fd16684db 100644 --- a/crypto/modes/asm/ghash-x86_64.pl +++ b/crypto/modes/asm/ghash-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2010-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2010-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/modes/asm/ghashv8-armx.pl b/crypto/modes/asm/ghashv8-armx.pl index 065154a8b3d64..d39b84460173c 100644 --- a/crypto/modes/asm/ghashv8-armx.pl +++ b/crypto/modes/asm/ghashv8-armx.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2014-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2014-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/modes/build.info b/crypto/modes/build.info index 9fb2d503d8d6c..cd4e0330dac0a 100644 --- a/crypto/modes/build.info +++ b/crypto/modes/build.info @@ -46,6 +46,11 @@ IF[{- !$disabled{asm} -}] $MODESASM_riscv64=ghash-riscv64.s ghash-riscv64-zvkb-zvbc.s ghash-riscv64-zvkg.s aes-gcm-riscv64-zvkb-zvkg-zvkned.s $MODESDEF_riscv64=GHASH_ASM + $MODESASM_e2kv6=asm/ghash-e2kv6.c + $MODESDEF_e2kv6=GHASH_ASM + $MODESASM_e2kv7=asm/ghash-e2kv6.c + $MODESDEF_e2kv7=GHASH_ASM + # Now that we have defined all the arch specific variables, use the # appropriate one, and define the appropriate macros IF[$MODESASM_{- $target{asm_arch} -}] diff --git a/crypto/modes/ccm128.c b/crypto/modes/ccm128.c index ba73600f39a23..3b9d5d542704b 100644 --- a/crypto/modes/ccm128.c +++ b/crypto/modes/ccm128.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/modes/ctr128.c b/crypto/modes/ctr128.c index 5954615e7d067..29a48fe0df73d 100644 --- a/crypto/modes/ctr128.c +++ b/crypto/modes/ctr128.c @@ -1,5 +1,5 @@ /* - * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2008-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/modes/gcm128.c b/crypto/modes/gcm128.c index 1b77c2e27e577..f1a6ebff173fc 100644 --- a/crypto/modes/gcm128.c +++ b/crypto/modes/gcm128.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2010-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -422,6 +422,12 @@ void gcm_init_rv64i_zvkg_zvkb(u128 Htable[16], const uint64_t Xi[2]); void gcm_gmult_rv64i_zvkg(uint64_t Xi[2], const u128 Htable[16]); void gcm_ghash_rv64i_zvkg(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, size_t len); +#elif defined(__e2k__) && (__iset__ >= 6) +#define GHASH_ASM_E2KV6 +void gcm_init_e2kv6_clmul(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_e2kv6_clmul(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_e2kv6_clmul(uint64_t Xi[2], const u128 Htable[16], + const uint8_t *inp, size_t len); #endif #endif @@ -552,6 +558,11 @@ static void gcm_get_funcs(struct gcm_funcs_st *ctx) } } return; +#elif defined(GHASH_ASM_E2KV6) + ctx->ginit = gcm_init_e2kv6_clmul; + ctx->gmult = gcm_gmult_e2kv6_clmul; + ctx->ghash = gcm_ghash_e2kv6_clmul; + return; #elif defined(GHASH_ASM) /* all other architectures use the generic names */ ctx->gmult = gcm_gmult_4bit; @@ -1540,6 +1551,13 @@ int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, #endif } +/* + * Calculate the tag and verify it against the supplied tag. + * Returns: + * -1: invalid tag length + * 0: tag verified + * >0: tag mismatch + */ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, size_t len) { diff --git a/crypto/modes/ocb128.c b/crypto/modes/ocb128.c index c6b906a56bb68..7d44ff1a0880d 100644 --- a/crypto/modes/ocb128.c +++ b/crypto/modes/ocb128.c @@ -534,6 +534,10 @@ static int ocb_finish(OCB128_CONTEXT *ctx, unsigned char *tag, size_t len, /* * Calculate the tag and verify it against the supplied tag + * Returns: + * -1: invalid tag length + * 0: tag verified + * >0: tag mismatch */ int CRYPTO_ocb128_finish(OCB128_CONTEXT *ctx, const unsigned char *tag, size_t len) diff --git a/crypto/modes/siv128.c b/crypto/modes/siv128.c index 0ab183b37b58d..456c1ae6639e4 100644 --- a/crypto/modes/siv128.c +++ b/crypto/modes/siv128.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -276,23 +276,29 @@ int ossl_siv128_encrypt(SIV128_CONTEXT *ctx, size_t len) { SIV_BLOCK q; + int ret = 0; + int final_ret_value = -1; /* can only do one crypto operation */ if (ctx->crypto_ok == 0) - return 0; + goto end; ctx->crypto_ok--; if (!siv128_do_s2v_p(ctx, &q, in, len)) - return 0; + goto end; memcpy(ctx->tag.byte, &q, SIV_LEN); q.byte[8] &= 0x7f; q.byte[12] &= 0x7f; if (!siv128_do_encrypt(ctx->cipher_ctx, out, in, len, &q)) - return 0; - ctx->final_ret = 0; - return 1; + goto end; + + ret = 1; + final_ret_value = 0; +end: + ctx->final_ret = final_ret_value; + return ret; } /* @@ -305,10 +311,12 @@ int ossl_siv128_decrypt(SIV128_CONTEXT *ctx, unsigned char *p; SIV_BLOCK t, q; int i; + int ret = 0; + int final_ret_value = -1; /* can only do one crypto operation */ if (ctx->crypto_ok == 0) - return 0; + goto end; ctx->crypto_ok--; memcpy(&q, ctx->tag.byte, SIV_LEN); @@ -317,7 +325,7 @@ int ossl_siv128_decrypt(SIV128_CONTEXT *ctx, if (!siv128_do_encrypt(ctx->cipher_ctx, out, in, len, &q) || !siv128_do_s2v_p(ctx, &t, out, len)) - return 0; + goto end; p = ctx->tag.byte; for (i = 0; i < SIV_LEN; i++) @@ -325,10 +333,13 @@ int ossl_siv128_decrypt(SIV128_CONTEXT *ctx, if ((t.word[0] | t.word[1]) != 0) { OPENSSL_cleanse(out, len); - return 0; + goto end; } - ctx->final_ret = 0; - return 1; + ret = 1; + final_ret_value = 0; +end: + ctx->final_ret = final_ret_value; + return ret; } /* diff --git a/crypto/modes/wrap128.c b/crypto/modes/wrap128.c index 6aa564a8b3b03..165d8e09aa951 100644 --- a/crypto/modes/wrap128.c +++ b/crypto/modes/wrap128.c @@ -1,5 +1,5 @@ /* - * Copyright 2013-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2013-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -288,7 +288,7 @@ size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv, padded_len = inlen - 8; ret = crypto_128_unwrap_raw(key, aiv, out, in, inlen, block); if (padded_len != ret) { - OPENSSL_cleanse(out, inlen); + OPENSSL_cleanse(out, padded_len); return 0; } } @@ -300,7 +300,7 @@ size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv, */ if ((!icv && CRYPTO_memcmp(aiv, default_aiv, 4)) || (icv && CRYPTO_memcmp(aiv, icv, 4))) { - OPENSSL_cleanse(out, inlen); + OPENSSL_cleanse(out, padded_len); return 0; } @@ -314,7 +314,7 @@ size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv, | ((unsigned int)aiv[6] << 8) | (unsigned int)aiv[7]; if (8 * (n - 1) >= ptext_len || ptext_len > 8 * n) { - OPENSSL_cleanse(out, inlen); + OPENSSL_cleanse(out, padded_len); return 0; } @@ -324,7 +324,7 @@ size_t CRYPTO_128_unwrap_pad(void *key, const unsigned char *icv, */ padding_len = padded_len - ptext_len; if (CRYPTO_memcmp(out + ptext_len, zeros, padding_len) != 0) { - OPENSSL_cleanse(out, inlen); + OPENSSL_cleanse(out, padded_len); return 0; } diff --git a/crypto/modes/xts128.c b/crypto/modes/xts128.c index f4bc0eccbc18c..2afcfbaacdce5 100644 --- a/crypto/modes/xts128.c +++ b/crypto/modes/xts128.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/modes/xts128gb.c b/crypto/modes/xts128gb.c index 586d69e48c017..3ad94e107ae98 100644 --- a/crypto/modes/xts128gb.c +++ b/crypto/modes/xts128gb.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/msvc2013_snprintf.c b/crypto/msvc2013_snprintf.c new file mode 100644 index 0000000000000..973e86b11bd20 --- /dev/null +++ b/crypto/msvc2013_snprintf.c @@ -0,0 +1,171 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * C99 snprintf and vsnprintf emulation for MSVC versions earlier than + * Visual Studio 2015 (_MSC_VER < 1900). Those compilers ship _snprintf + * and _vsnprintf with non-C99 semantics (return -1 on truncation, no + * guaranteed NUL termination) and do not provide the standard names at + * all. This file supplies the missing C99 names. + * + * This file is only compiled when the configured target is one of the + * Windows MSVC 2013 compatibility variants; on every other platform + * the standard library already provides these symbols. + * + * IMPORTANT: This translation unit MUST define snprintf and vsnprintf + * and nothing else. This single file is compiled directly into libcrypto, + * libssl, and the apps; each references it from its own build.info rather + * than keeping a copy. Because each definition lives in its own .obj, the + * linker's archive-search rule ensures only one copy is pulled into any + * final binary. Defining any additional symbol here would risk pulling + * multiple copies and producing a duplicate-symbol link error. + */ + +#include +#include +#include +#include +#include +#include + +/* + * _MSC_VER described here: + * https://learn.microsoft.com/en-us/cpp/overview/compiler-versions?view=msvc-170 + * + * Beginning with the UCRT in Visual Studio 2015 and Windows 10, snprintf is no + * longer identical to _snprintf. The snprintf behavior is now C99 standard + * conformant. The difference is that if you run out of buffer, snprintf + * null-terminates the end of the buffer and returns the number of characters + * that would have been required whereas _snprintf doesn't null-terminate the + * buffer and returns -1. Also, snprintf() includes one more character in the + * output because it doesn't null-terminate the buffer. + * [ https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/snprintf-snprintf-snprintf-l-snwprintf-snwprintf-l?view=msvc-170#remarks + * + * for older MSVC (older than 2015) we can use _vscprintf() and _vsnprintf() + * as suggested here: + * https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 + * + */ +int msvc_translate_printf_format(const char *format, const char **out, + char **tmp) +{ + /* Valid printf conversion specifiers, grouped by category: signed + * integers (d i), unsigned (o u x X), floating-point (f F e E g G a A), + * misc (c s p n) and MSVC-specific (S Z C). */ + static const char conv[] = "diouxXfFeEgGaAcspnSZC"; + const char *p = format; + char *dst = NULL, *q = NULL; + + /* + * The VS 2013 CRT does not understand the C99 z, t and j length + * modifiers. Translate z and t to I (both are pointer-sized on Windows) + * and j to I64 (intmax_t is 64 bits). Every input character expands to + * at most three output characters (j -> I64), so 3 * length is a safe + * bound for the buffer. + * + * This is done in a single pass: nothing is allocated until the first + * modifier is seen, so formats that need no translation return the + * original string untouched. EMIT_CHAR() appends a character to the + * output once the buffer exists; before that it is a no-op. + */ +#define EMIT_CHAR(c) \ + do { \ + if (dst != NULL) \ + *q++ = (c); \ + } while (0) + + *out = format; + *tmp = NULL; + + while (*p != '\0') { + if (*p != '%') { /* literal character */ + EMIT_CHAR(*p); + p++; + continue; + } + p++; /* consume '%' */ + if (*p == '%') { /* literal "%%" */ + EMIT_CHAR('%'); + EMIT_CHAR('%'); + p++; + continue; + } + EMIT_CHAR('%'); + while (*p != '\0' && strchr(conv, *p) == NULL) { + char c = *p++; + if (c != 'z' && c != 't' && c != 'j') { /* verbatim */ + EMIT_CHAR(c); + continue; + } + if (dst == NULL) { /* first modifier: allocate + flush prefix */ + size_t len = strlen(format); + if (len > (SIZE_MAX - 1) / 3) /* make static analysis happy */ + return 0; + dst = (char *)OPENSSL_malloc(3 * len + 1); + if (dst == NULL) + return 0; + q = dst; + memcpy(q, format, (size_t)(p - 1 - format)); + q += p - 1 - format; + } + EMIT_CHAR('I'); + if (c == 'j') { + EMIT_CHAR('6'); + EMIT_CHAR('4'); + } + } + if (*p != '\0') { /* copy the conversion specifier */ + EMIT_CHAR(*p); + p++; + } + } +#undef EMIT_CHAR + + if (dst != NULL) { + *q = '\0'; + *out = dst; + *tmp = dst; + } + return 1; +} + +int vsnprintf(char *buf, size_t n, const char *format, va_list args) +{ + int count = -1; + va_list args_copy; + char *fmt_alloc = NULL; + const char *fmt; + + if (!msvc_translate_printf_format(format, &fmt, &fmt_alloc)) + goto done; + va_copy(args_copy, args); + count = _vscprintf(fmt, args_copy); + va_end(args_copy); + + if (count < 0) + goto done; + + if (n > 0) + (void)_vsnprintf_s(buf, n, _TRUNCATE, fmt, args); + +done: + OPENSSL_free(fmt_alloc); + return count; +} + +int snprintf(char *buf, size_t n, const char *fmt, ...) +{ + va_list args; + int ret; + + va_start(args, fmt); + ret = vsnprintf(buf, n, fmt, args); + va_end(args); + return ret; +} diff --git a/crypto/o_dir.c b/crypto/o_dir.c index ed92b9f130498..7da07c78ef614 100644 --- a/crypto/o_dir.c +++ b/crypto/o_dir.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/o_str.c b/crypto/o_str.c index 2192d48775dd8..3532276af74f9 100644 --- a/crypto/o_str.c +++ b/crypto/o_str.c @@ -1,5 +1,5 @@ /* - * Copyright 2003-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2003-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -161,6 +161,52 @@ int OPENSSL_strtoul(const char *str, char **endptr, int base, return 1; } +/* + * Internal signed counterpart to OPENSSL_strtoul(). Parses a signed long with + * the same validation rules: it fails on a conversion error (including + * overflow/underflow), if no digits were consumed, or, when |endptr| is NULL, + * if the whole string was not consumed. Returns 1 on success (storing the + * result in |*result|), 0 otherwise. + */ +int ossl_strtol(const char *str, char **endptr, int base, long *result) +{ + char *tmp_endptr; + char **internal_endptr = endptr == NULL ? &tmp_endptr : endptr; + + errno = 0; + + *internal_endptr = (char *)str; + + if (result == NULL || str == NULL) + return 0; + + *result = strtol(str, internal_endptr, base); + if (errno != 0 + || (endptr == NULL && **internal_endptr != '\0') + || str == *internal_endptr) + return 0; + + return 1; +} + +/* + * As ossl_strtol() but stores the result in an int, additionally failing if + * the parsed value does not fit in an int. Returns 1 on success (storing the + * result in |*result|), 0 otherwise. + */ +int ossl_strtoint(const char *str, char **endptr, int base, int *result) +{ + long l; + + if (result == NULL || !ossl_strtol(str, endptr, base, &l)) + return 0; + if (l < INT_MIN || l > INT_MAX) + return 0; + + *result = (int)l; + return 1; +} + int OPENSSL_hexchar2int(unsigned char c) { #ifdef CHARSET_EBCDIC diff --git a/crypto/objects/build.info b/crypto/objects/build.info index 38e290756b94f..cc4e731ddf222 100644 --- a/crypto/objects/build.info +++ b/crypto/objects/build.info @@ -1,3 +1,14 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=\ o_names.c obj_dat.c obj_lib.c obj_err.c obj_xref.c + +DEPEND[obj_dat.o]=obj_dat.h +GENERATE[obj_dat.h]=obj_dat.pl $(BLDDIR)/include/openssl/obj_mac.h +DEPEND[obj_dat.h]=../../include/openssl/obj_mac.h + +DEPEND[obj_xref.o]=obj_xref.h +GENERATE[obj_xref.h]=objxref.pl $(SRCDIR)/crypto/objects/obj_mac.num \ + $(SRCDIR)/crypto/objects/obj_xref.txt +DEPEND[obj_xref.h]=obj_mac.num obj_xref.txt +INCLUDE[obj_dat.o]=. +INCLUDE[obj_xref.o]=. diff --git a/crypto/objects/o_names.c b/crypto/objects/o_names.c index 9ab9a2acd1b43..2ac33aa5633a8 100644 --- a/crypto/objects/o_names.c +++ b/crypto/objects/o_names.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1998-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c index 570fde8d15641..cbb98f4030eea 100644 --- a/crypto/objects/obj_dat.c +++ b/crypto/objects/obj_dat.c @@ -508,7 +508,7 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) n += i; OPENSSL_free(bndec); } else { - BIO_snprintf(tbuf, sizeof(tbuf), ".%lu", l); + snprintf(tbuf, sizeof(tbuf), ".%lu", l); i = (int)strlen(tbuf); if (buf && buf_len > 0) { OPENSSL_strlcpy(buf, tbuf, buf_len); diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h deleted file mode 100644 index c7925932d51bb..0000000000000 --- a/crypto/objects/obj_dat.h +++ /dev/null @@ -1,7224 +0,0 @@ -/* - * WARNING: do not edit! - * Generated by crypto/objects/obj_dat.pl - * - * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#if !defined(OSSL_LIBCRYPTO_OBJECTS_OBJ_DAT_H) -#define OSSL_LIBCRYPTO_OBJECTS_OBJ_DAT_H - -/* clang-format off */ - -#include -#include - -#include - -/* Serialized OID's */ -static const unsigned char so[9582] = { - 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05, /* [ 21] OBJ_md5 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x04, /* [ 29] OBJ_rc4 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01, /* [ 37] OBJ_rsaEncryption */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x02, /* [ 46] OBJ_md2WithRSAEncryption */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04, /* [ 55] OBJ_md5WithRSAEncryption */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x01, /* [ 64] OBJ_pbeWithMD2AndDES_CBC */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x03, /* [ 73] OBJ_pbeWithMD5AndDES_CBC */ - 0x55, /* [ 82] OBJ_X500 */ - 0x55,0x04, /* [ 83] OBJ_X509 */ - 0x55,0x04,0x03, /* [ 85] OBJ_commonName */ - 0x55,0x04,0x06, /* [ 88] OBJ_countryName */ - 0x55,0x04,0x07, /* [ 91] OBJ_localityName */ - 0x55,0x04,0x08, /* [ 94] OBJ_stateOrProvinceName */ - 0x55,0x04,0x0A, /* [ 97] OBJ_organizationName */ - 0x55,0x04,0x0B, /* [ 100] OBJ_organizationalUnitName */ - 0x55,0x08,0x01,0x01, /* [ 103] OBJ_rsa */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07, /* [ 107] OBJ_pkcs7 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x01, /* [ 115] OBJ_pkcs7_data */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x02, /* [ 124] OBJ_pkcs7_signed */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x03, /* [ 133] OBJ_pkcs7_enveloped */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x04, /* [ 142] OBJ_pkcs7_signedAndEnveloped */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x05, /* [ 151] OBJ_pkcs7_digest */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x06, /* [ 160] OBJ_pkcs7_encrypted */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03, /* [ 169] OBJ_pkcs3 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,0x01, /* [ 177] OBJ_dhKeyAgreement */ - 0x2B,0x0E,0x03,0x02,0x06, /* [ 186] OBJ_des_ecb */ - 0x2B,0x0E,0x03,0x02,0x09, /* [ 191] OBJ_des_cfb64 */ - 0x2B,0x0E,0x03,0x02,0x07, /* [ 196] OBJ_des_cbc */ - 0x2B,0x0E,0x03,0x02,0x11, /* [ 201] OBJ_des_ede_ecb */ - 0x2B,0x06,0x01,0x04,0x01,0x81,0x3C,0x07,0x01,0x01,0x02, /* [ 206] OBJ_idea_cbc */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x02, /* [ 217] OBJ_rc2_cbc */ - 0x2B,0x0E,0x03,0x02,0x12, /* [ 225] OBJ_sha */ - 0x2B,0x0E,0x03,0x02,0x0F, /* [ 230] OBJ_shaWithRSAEncryption */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x07, /* [ 235] OBJ_des_ede3_cbc */ - 0x2B,0x0E,0x03,0x02,0x08, /* [ 243] OBJ_des_ofb64 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09, /* [ 248] OBJ_pkcs9 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01, /* [ 256] OBJ_pkcs9_emailAddress */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x02, /* [ 265] OBJ_pkcs9_unstructuredName */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x03, /* [ 274] OBJ_pkcs9_contentType */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x04, /* [ 283] OBJ_pkcs9_messageDigest */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x05, /* [ 292] OBJ_pkcs9_signingTime */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x06, /* [ 301] OBJ_pkcs9_countersignature */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x07, /* [ 310] OBJ_pkcs9_challengePassword */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x08, /* [ 319] OBJ_pkcs9_unstructuredAddress */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x09, /* [ 328] OBJ_pkcs9_extCertAttributes */ - 0x60,0x86,0x48,0x01,0x86,0xF8,0x42, /* [ 337] OBJ_netscape */ - 0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01, /* [ 344] OBJ_netscape_cert_extension */ - 0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02, /* [ 352] OBJ_netscape_data_type */ - 0x2B,0x0E,0x03,0x02,0x1A, /* [ 360] OBJ_sha1 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05, /* [ 365] OBJ_sha1WithRSAEncryption */ - 0x2B,0x0E,0x03,0x02,0x0D, /* [ 374] OBJ_dsaWithSHA */ - 0x2B,0x0E,0x03,0x02,0x0C, /* [ 379] OBJ_dsa_2 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0B, /* [ 384] OBJ_pbeWithSHA1AndRC2_CBC */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0C, /* [ 393] OBJ_id_pbkdf2 */ - 0x2B,0x0E,0x03,0x02,0x1B, /* [ 402] OBJ_dsaWithSHA1_2 */ - 0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01, /* [ 407] OBJ_netscape_cert_type */ - 0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x02, /* [ 416] OBJ_netscape_base_url */ - 0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x03, /* [ 425] OBJ_netscape_revocation_url */ - 0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x04, /* [ 434] OBJ_netscape_ca_revocation_url */ - 0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x07, /* [ 443] OBJ_netscape_renewal_url */ - 0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x08, /* [ 452] OBJ_netscape_ca_policy_url */ - 0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0C, /* [ 461] OBJ_netscape_ssl_server_name */ - 0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0D, /* [ 470] OBJ_netscape_comment */ - 0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,0x05, /* [ 479] OBJ_netscape_cert_sequence */ - 0x55,0x1D, /* [ 488] OBJ_id_ce */ - 0x55,0x1D,0x0E, /* [ 490] OBJ_subject_key_identifier */ - 0x55,0x1D,0x0F, /* [ 493] OBJ_key_usage */ - 0x55,0x1D,0x10, /* [ 496] OBJ_private_key_usage_period */ - 0x55,0x1D,0x11, /* [ 499] OBJ_subject_alt_name */ - 0x55,0x1D,0x12, /* [ 502] OBJ_issuer_alt_name */ - 0x55,0x1D,0x13, /* [ 505] OBJ_basic_constraints */ - 0x55,0x1D,0x14, /* [ 508] OBJ_crl_number */ - 0x55,0x1D,0x20, /* [ 511] OBJ_certificate_policies */ - 0x55,0x1D,0x23, /* [ 514] OBJ_authority_key_identifier */ - 0x2B,0x06,0x01,0x04,0x01,0x97,0x55,0x01,0x02, /* [ 517] OBJ_bf_cbc */ - 0x55,0x08,0x03,0x65, /* [ 526] OBJ_mdc2 */ - 0x55,0x08,0x03,0x64, /* [ 530] OBJ_mdc2WithRSA */ - 0x55,0x04,0x2A, /* [ 534] OBJ_givenName */ - 0x55,0x04,0x04, /* [ 537] OBJ_surname */ - 0x55,0x04,0x2B, /* [ 540] OBJ_initials */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2C, /* [ 543] OBJ_uniqueIdentifier */ - 0x55,0x1D,0x1F, /* [ 553] OBJ_crl_distribution_points */ - 0x2B,0x0E,0x03,0x02,0x03, /* [ 556] OBJ_md5WithRSA */ - 0x55,0x04,0x05, /* [ 561] OBJ_serialNumber */ - 0x55,0x04,0x0C, /* [ 564] OBJ_title */ - 0x55,0x04,0x0D, /* [ 567] OBJ_description */ - 0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0A, /* [ 570] OBJ_cast5_cbc */ - 0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0C, /* [ 579] OBJ_pbeWithMD5AndCast5_CBC */ - 0x2A,0x86,0x48,0xCE,0x38,0x04,0x03, /* [ 588] OBJ_dsaWithSHA1 */ - 0x2B,0x0E,0x03,0x02,0x1D, /* [ 595] OBJ_sha1WithRSA */ - 0x2A,0x86,0x48,0xCE,0x38,0x04,0x01, /* [ 600] OBJ_dsa */ - 0x2B,0x24,0x03,0x02,0x01, /* [ 607] OBJ_ripemd160 */ - 0x2B,0x24,0x03,0x03,0x01,0x02, /* [ 612] OBJ_ripemd160WithRSA */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x08, /* [ 618] OBJ_rc5_cbc */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x08, /* [ 626] OBJ_zlib_compression */ - 0x55,0x1D,0x25, /* [ 637] OBJ_ext_key_usage */ - 0x2B,0x06,0x01,0x05,0x05,0x07, /* [ 640] OBJ_id_pkix */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03, /* [ 646] OBJ_id_kp */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01, /* [ 653] OBJ_server_auth */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02, /* [ 661] OBJ_client_auth */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03, /* [ 669] OBJ_code_sign */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x04, /* [ 677] OBJ_email_protect */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x08, /* [ 685] OBJ_time_stamp */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x15, /* [ 693] OBJ_ms_code_ind */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x16, /* [ 703] OBJ_ms_code_com */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x01, /* [ 713] OBJ_ms_ctl_sign */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03, /* [ 723] OBJ_ms_sgc */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x04, /* [ 733] OBJ_ms_efs */ - 0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01, /* [ 743] OBJ_ns_sgc */ - 0x55,0x1D,0x1B, /* [ 752] OBJ_delta_crl */ - 0x55,0x1D,0x15, /* [ 755] OBJ_crl_reason */ - 0x55,0x1D,0x18, /* [ 758] OBJ_invalidity_date */ - 0x2B,0x65,0x01,0x04,0x01, /* [ 761] OBJ_sxnet */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x01, /* [ 766] OBJ_pbe_WithSHA1And128BitRC4 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x02, /* [ 776] OBJ_pbe_WithSHA1And40BitRC4 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x03, /* [ 786] OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x04, /* [ 796] OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x05, /* [ 806] OBJ_pbe_WithSHA1And128BitRC2_CBC */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x06, /* [ 816] OBJ_pbe_WithSHA1And40BitRC2_CBC */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x01, /* [ 826] OBJ_keyBag */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x02, /* [ 837] OBJ_pkcs8ShroudedKeyBag */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x03, /* [ 848] OBJ_certBag */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x04, /* [ 859] OBJ_crlBag */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x05, /* [ 870] OBJ_secretBag */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x06, /* [ 881] OBJ_safeContentsBag */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x14, /* [ 892] OBJ_friendlyName */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x15, /* [ 901] OBJ_localKeyID */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x01, /* [ 910] OBJ_x509Certificate */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x02, /* [ 920] OBJ_sdsiCertificate */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x17,0x01, /* [ 930] OBJ_x509Crl */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0D, /* [ 940] OBJ_pbes2 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0E, /* [ 949] OBJ_pbmac1 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x07, /* [ 958] OBJ_hmacWithSHA1 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01, /* [ 966] OBJ_id_qt_cps */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02, /* [ 974] OBJ_id_qt_unotice */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0F, /* [ 982] OBJ_SMIMECapabilities */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x04, /* [ 991] OBJ_pbeWithMD2AndRC2_CBC */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x06, /* [ 1000] OBJ_pbeWithMD5AndRC2_CBC */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0A, /* [ 1009] OBJ_pbeWithSHA1AndDES_CBC */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x0E, /* [ 1018] OBJ_ms_ext_req */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0E, /* [ 1028] OBJ_ext_req */ - 0x55,0x04,0x29, /* [ 1037] OBJ_name */ - 0x55,0x04,0x2E, /* [ 1040] OBJ_dnQualifier */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01, /* [ 1043] OBJ_id_pe */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30, /* [ 1050] OBJ_id_ad */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01, /* [ 1057] OBJ_info_access */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01, /* [ 1065] OBJ_ad_OCSP */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02, /* [ 1073] OBJ_ad_ca_issuers */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09, /* [ 1081] OBJ_OCSP_sign */ - 0x2A, /* [ 1089] OBJ_member_body */ - 0x2A,0x86,0x48, /* [ 1090] OBJ_ISO_US */ - 0x2A,0x86,0x48,0xCE,0x38, /* [ 1093] OBJ_X9_57 */ - 0x2A,0x86,0x48,0xCE,0x38,0x04, /* [ 1098] OBJ_X9cm */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, /* [ 1104] OBJ_pkcs1 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05, /* [ 1112] OBJ_pkcs5 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10, /* [ 1120] OBJ_SMIME */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00, /* [ 1129] OBJ_id_smime_mod */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01, /* [ 1139] OBJ_id_smime_ct */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02, /* [ 1149] OBJ_id_smime_aa */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03, /* [ 1159] OBJ_id_smime_alg */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04, /* [ 1169] OBJ_id_smime_cd */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05, /* [ 1179] OBJ_id_smime_spq */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06, /* [ 1189] OBJ_id_smime_cti */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x01, /* [ 1199] OBJ_id_smime_mod_cms */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x02, /* [ 1210] OBJ_id_smime_mod_ess */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x03, /* [ 1221] OBJ_id_smime_mod_oid */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x04, /* [ 1232] OBJ_id_smime_mod_msg_v3 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x05, /* [ 1243] OBJ_id_smime_mod_ets_eSignature_88 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x06, /* [ 1254] OBJ_id_smime_mod_ets_eSignature_97 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x07, /* [ 1265] OBJ_id_smime_mod_ets_eSigPolicy_88 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x08, /* [ 1276] OBJ_id_smime_mod_ets_eSigPolicy_97 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x01, /* [ 1287] OBJ_id_smime_ct_receipt */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x02, /* [ 1298] OBJ_id_smime_ct_authData */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x03, /* [ 1309] OBJ_id_smime_ct_publishCert */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x04, /* [ 1320] OBJ_id_smime_ct_TSTInfo */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x05, /* [ 1331] OBJ_id_smime_ct_TDTInfo */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x06, /* [ 1342] OBJ_id_smime_ct_contentInfo */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x07, /* [ 1353] OBJ_id_smime_ct_DVCSRequestData */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x08, /* [ 1364] OBJ_id_smime_ct_DVCSResponseData */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x01, /* [ 1375] OBJ_id_smime_aa_receiptRequest */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x02, /* [ 1386] OBJ_id_smime_aa_securityLabel */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x03, /* [ 1397] OBJ_id_smime_aa_mlExpandHistory */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x04, /* [ 1408] OBJ_id_smime_aa_contentHint */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x05, /* [ 1419] OBJ_id_smime_aa_msgSigDigest */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x06, /* [ 1430] OBJ_id_smime_aa_encapContentType */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x07, /* [ 1441] OBJ_id_smime_aa_contentIdentifier */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x08, /* [ 1452] OBJ_id_smime_aa_macValue */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x09, /* [ 1463] OBJ_id_smime_aa_equivalentLabels */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0A, /* [ 1474] OBJ_id_smime_aa_contentReference */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0B, /* [ 1485] OBJ_id_smime_aa_encrypKeyPref */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0C, /* [ 1496] OBJ_id_smime_aa_signingCertificate */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0D, /* [ 1507] OBJ_id_smime_aa_smimeEncryptCerts */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0E, /* [ 1518] OBJ_id_smime_aa_timeStampToken */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0F, /* [ 1529] OBJ_id_smime_aa_ets_sigPolicyId */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x10, /* [ 1540] OBJ_id_smime_aa_ets_commitmentType */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x11, /* [ 1551] OBJ_id_smime_aa_ets_signerLocation */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x12, /* [ 1562] OBJ_id_smime_aa_ets_signerAttr */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x13, /* [ 1573] OBJ_id_smime_aa_ets_otherSigCert */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x14, /* [ 1584] OBJ_id_smime_aa_ets_contentTimestamp */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x15, /* [ 1595] OBJ_id_smime_aa_ets_CertificateRefs */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x16, /* [ 1606] OBJ_id_smime_aa_ets_RevocationRefs */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x17, /* [ 1617] OBJ_id_smime_aa_ets_certValues */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x18, /* [ 1628] OBJ_id_smime_aa_ets_revocationValues */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x19, /* [ 1639] OBJ_id_smime_aa_ets_escTimeStamp */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1A, /* [ 1650] OBJ_id_smime_aa_ets_certCRLTimestamp */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1B, /* [ 1661] OBJ_id_smime_aa_ets_archiveTimeStamp */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1C, /* [ 1672] OBJ_id_smime_aa_signatureType */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1D, /* [ 1683] OBJ_id_smime_aa_dvcs_dvc */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x01, /* [ 1694] OBJ_id_smime_alg_ESDHwith3DES */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x02, /* [ 1705] OBJ_id_smime_alg_ESDHwithRC2 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x03, /* [ 1716] OBJ_id_smime_alg_3DESwrap */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x04, /* [ 1727] OBJ_id_smime_alg_RC2wrap */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x05, /* [ 1738] OBJ_id_smime_alg_ESDH */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x06, /* [ 1749] OBJ_id_smime_alg_CMS3DESwrap */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x07, /* [ 1760] OBJ_id_smime_alg_CMSRC2wrap */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,0x01, /* [ 1771] OBJ_id_smime_cd_ldap */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x01, /* [ 1782] OBJ_id_smime_spq_ets_sqt_uri */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x02, /* [ 1793] OBJ_id_smime_spq_ets_sqt_unotice */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x01, /* [ 1804] OBJ_id_smime_cti_ets_proofOfOrigin */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x02, /* [ 1815] OBJ_id_smime_cti_ets_proofOfReceipt */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x03, /* [ 1826] OBJ_id_smime_cti_ets_proofOfDelivery */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x04, /* [ 1837] OBJ_id_smime_cti_ets_proofOfSender */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x05, /* [ 1848] OBJ_id_smime_cti_ets_proofOfApproval */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x06, /* [ 1859] OBJ_id_smime_cti_ets_proofOfCreation */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x04, /* [ 1870] OBJ_md4 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00, /* [ 1878] OBJ_id_pkix_mod */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x02, /* [ 1885] OBJ_id_qt */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04, /* [ 1892] OBJ_id_it */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x05, /* [ 1899] OBJ_id_pkip */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x06, /* [ 1906] OBJ_id_alg */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07, /* [ 1913] OBJ_id_cmc */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x08, /* [ 1920] OBJ_id_on */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x09, /* [ 1927] OBJ_id_pda */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0A, /* [ 1934] OBJ_id_aca */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0B, /* [ 1941] OBJ_id_qcs */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0C, /* [ 1948] OBJ_id_cct */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x01, /* [ 1955] OBJ_id_pkix1_explicit_88 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x02, /* [ 1963] OBJ_id_pkix1_implicit_88 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x03, /* [ 1971] OBJ_id_pkix1_explicit_93 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x04, /* [ 1979] OBJ_id_pkix1_implicit_93 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x05, /* [ 1987] OBJ_id_mod_crmf */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x06, /* [ 1995] OBJ_id_mod_cmc */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x07, /* [ 2003] OBJ_id_mod_kea_profile_88 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x08, /* [ 2011] OBJ_id_mod_kea_profile_93 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x09, /* [ 2019] OBJ_id_mod_cmp */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0A, /* [ 2027] OBJ_id_mod_qualified_cert_88 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0B, /* [ 2035] OBJ_id_mod_qualified_cert_93 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0C, /* [ 2043] OBJ_id_mod_attribute_cert */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0D, /* [ 2051] OBJ_id_mod_timestamp_protocol */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0E, /* [ 2059] OBJ_id_mod_ocsp */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0F, /* [ 2067] OBJ_id_mod_dvcs */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x10, /* [ 2075] OBJ_id_mod_cmp2000 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x02, /* [ 2083] OBJ_biometricInfo */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x03, /* [ 2091] OBJ_qcStatements */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x04, /* [ 2099] OBJ_ac_auditIdentity */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x05, /* [ 2107] OBJ_ac_targeting */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x06, /* [ 2115] OBJ_aaControls */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x07, /* [ 2123] OBJ_sbgp_ipAddrBlock */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x08, /* [ 2131] OBJ_sbgp_autonomousSysNum */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x09, /* [ 2139] OBJ_sbgp_routerIdentifier */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x03, /* [ 2147] OBJ_textNotice */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x05, /* [ 2155] OBJ_ipsecEndSystem */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x06, /* [ 2163] OBJ_ipsecTunnel */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07, /* [ 2171] OBJ_ipsecUser */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x0A, /* [ 2179] OBJ_dvcs */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x01, /* [ 2187] OBJ_id_it_caProtEncCert */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x02, /* [ 2195] OBJ_id_it_signKeyPairTypes */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x03, /* [ 2203] OBJ_id_it_encKeyPairTypes */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x04, /* [ 2211] OBJ_id_it_preferredSymmAlg */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x05, /* [ 2219] OBJ_id_it_caKeyUpdateInfo */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x06, /* [ 2227] OBJ_id_it_currentCRL */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x07, /* [ 2235] OBJ_id_it_unsupportedOIDs */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x08, /* [ 2243] OBJ_id_it_subscriptionRequest */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x09, /* [ 2251] OBJ_id_it_subscriptionResponse */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0A, /* [ 2259] OBJ_id_it_keyPairParamReq */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0B, /* [ 2267] OBJ_id_it_keyPairParamRep */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0C, /* [ 2275] OBJ_id_it_revPassphrase */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0D, /* [ 2283] OBJ_id_it_implicitConfirm */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0E, /* [ 2291] OBJ_id_it_confirmWaitTime */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0F, /* [ 2299] OBJ_id_it_origPKIMessage */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01, /* [ 2307] OBJ_id_regCtrl */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02, /* [ 2315] OBJ_id_regInfo */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x01, /* [ 2323] OBJ_id_regCtrl_regToken */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x02, /* [ 2332] OBJ_id_regCtrl_authenticator */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x03, /* [ 2341] OBJ_id_regCtrl_pkiPublicationInfo */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x04, /* [ 2350] OBJ_id_regCtrl_pkiArchiveOptions */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x05, /* [ 2359] OBJ_id_regCtrl_oldCertID */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x06, /* [ 2368] OBJ_id_regCtrl_protocolEncrKey */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x01, /* [ 2377] OBJ_id_regInfo_utf8Pairs */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x02, /* [ 2386] OBJ_id_regInfo_certReq */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x01, /* [ 2395] OBJ_id_alg_des40 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x02, /* [ 2403] OBJ_id_alg_noSignature */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x03, /* [ 2411] OBJ_id_alg_dh_sig_hmac_sha1 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x04, /* [ 2419] OBJ_id_alg_dh_pop */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x01, /* [ 2427] OBJ_id_cmc_statusInfo */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x02, /* [ 2435] OBJ_id_cmc_identification */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x03, /* [ 2443] OBJ_id_cmc_identityProof */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x04, /* [ 2451] OBJ_id_cmc_dataReturn */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x05, /* [ 2459] OBJ_id_cmc_transactionId */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x06, /* [ 2467] OBJ_id_cmc_senderNonce */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x07, /* [ 2475] OBJ_id_cmc_recipientNonce */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x08, /* [ 2483] OBJ_id_cmc_addExtensions */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x09, /* [ 2491] OBJ_id_cmc_encryptedPOP */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0A, /* [ 2499] OBJ_id_cmc_decryptedPOP */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0B, /* [ 2507] OBJ_id_cmc_lraPOPWitness */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0F, /* [ 2515] OBJ_id_cmc_getCert */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x10, /* [ 2523] OBJ_id_cmc_getCRL */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x11, /* [ 2531] OBJ_id_cmc_revokeRequest */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x12, /* [ 2539] OBJ_id_cmc_regInfo */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x13, /* [ 2547] OBJ_id_cmc_responseInfo */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x15, /* [ 2555] OBJ_id_cmc_queryPending */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x16, /* [ 2563] OBJ_id_cmc_popLinkRandom */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x17, /* [ 2571] OBJ_id_cmc_popLinkWitness */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x18, /* [ 2579] OBJ_id_cmc_confirmCertAcceptance */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x01, /* [ 2587] OBJ_id_on_personalData */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x01, /* [ 2595] OBJ_id_pda_dateOfBirth */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x02, /* [ 2603] OBJ_id_pda_placeOfBirth */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x03, /* [ 2611] OBJ_id_pda_gender */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x04, /* [ 2619] OBJ_id_pda_countryOfCitizenship */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x05, /* [ 2627] OBJ_id_pda_countryOfResidence */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x01, /* [ 2635] OBJ_id_aca_authenticationInfo */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x02, /* [ 2643] OBJ_id_aca_accessIdentity */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x03, /* [ 2651] OBJ_id_aca_chargingIdentity */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x04, /* [ 2659] OBJ_id_aca_group */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x05, /* [ 2667] OBJ_id_aca_role */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,0x01, /* [ 2675] OBJ_id_qcs_pkixQCSyntax_v1 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x01, /* [ 2683] OBJ_id_cct_crs */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x02, /* [ 2691] OBJ_id_cct_PKIData */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x03, /* [ 2699] OBJ_id_cct_PKIResponse */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x03, /* [ 2707] OBJ_ad_timeStamping */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x04, /* [ 2715] OBJ_ad_dvcs */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x01, /* [ 2723] OBJ_id_pkix_OCSP_basic */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x02, /* [ 2732] OBJ_id_pkix_OCSP_Nonce */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x03, /* [ 2741] OBJ_id_pkix_OCSP_CrlID */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x04, /* [ 2750] OBJ_id_pkix_OCSP_acceptableResponses */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05, /* [ 2759] OBJ_id_pkix_OCSP_noCheck */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x06, /* [ 2768] OBJ_id_pkix_OCSP_archiveCutoff */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x07, /* [ 2777] OBJ_id_pkix_OCSP_serviceLocator */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x08, /* [ 2786] OBJ_id_pkix_OCSP_extendedStatus */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x09, /* [ 2795] OBJ_id_pkix_OCSP_valid */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0A, /* [ 2804] OBJ_id_pkix_OCSP_path */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0B, /* [ 2813] OBJ_id_pkix_OCSP_trustRoot */ - 0x2B,0x0E,0x03,0x02, /* [ 2822] OBJ_algorithm */ - 0x2B,0x0E,0x03,0x02,0x0B, /* [ 2826] OBJ_rsaSignature */ - 0x55,0x08, /* [ 2831] OBJ_X500algorithms */ - 0x2B, /* [ 2833] OBJ_org */ - 0x2B,0x06, /* [ 2834] OBJ_dod */ - 0x2B,0x06,0x01, /* [ 2836] OBJ_iana */ - 0x2B,0x06,0x01,0x01, /* [ 2839] OBJ_Directory */ - 0x2B,0x06,0x01,0x02, /* [ 2843] OBJ_Management */ - 0x2B,0x06,0x01,0x03, /* [ 2847] OBJ_Experimental */ - 0x2B,0x06,0x01,0x04, /* [ 2851] OBJ_Private */ - 0x2B,0x06,0x01,0x05, /* [ 2855] OBJ_Security */ - 0x2B,0x06,0x01,0x06, /* [ 2859] OBJ_SNMPv2 */ - 0x2B,0x06,0x01,0x07, /* [ 2863] OBJ_Mail */ - 0x2B,0x06,0x01,0x04,0x01, /* [ 2867] OBJ_Enterprises */ - 0x2B,0x06,0x01,0x04,0x01,0x8B,0x3A,0x82,0x58, /* [ 2872] OBJ_dcObject */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19, /* [ 2881] OBJ_domainComponent */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0D, /* [ 2891] OBJ_Domain */ - 0x55,0x01,0x05, /* [ 2901] OBJ_selected_attribute_types */ - 0x55,0x01,0x05,0x37, /* [ 2904] OBJ_clearance */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x03, /* [ 2908] OBJ_md4WithRSAEncryption */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0A, /* [ 2917] OBJ_ac_proxying */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0B, /* [ 2925] OBJ_sinfo_access */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x06, /* [ 2933] OBJ_id_aca_encAttrs */ - 0x55,0x04,0x48, /* [ 2941] OBJ_role */ - 0x55,0x1D,0x24, /* [ 2944] OBJ_policy_constraints */ - 0x55,0x1D,0x37, /* [ 2947] OBJ_target_information */ - 0x55,0x1D,0x38, /* [ 2950] OBJ_no_rev_avail */ - 0x2A,0x86,0x48,0xCE,0x3D, /* [ 2953] OBJ_ansi_X9_62 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x01,0x01, /* [ 2958] OBJ_X9_62_prime_field */ - 0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02, /* [ 2965] OBJ_X9_62_characteristic_two_field */ - 0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01, /* [ 2972] OBJ_X9_62_id_ecPublicKey */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01, /* [ 2979] OBJ_X9_62_prime192v1 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02, /* [ 2987] OBJ_X9_62_prime192v2 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03, /* [ 2995] OBJ_X9_62_prime192v3 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04, /* [ 3003] OBJ_X9_62_prime239v1 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05, /* [ 3011] OBJ_X9_62_prime239v2 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06, /* [ 3019] OBJ_X9_62_prime239v3 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07, /* [ 3027] OBJ_X9_62_prime256v1 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01, /* [ 3035] OBJ_ecdsa_with_SHA1 */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x01, /* [ 3042] OBJ_ms_csp_name */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x01, /* [ 3051] OBJ_aes_128_ecb */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x02, /* [ 3060] OBJ_aes_128_cbc */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x03, /* [ 3069] OBJ_aes_128_ofb128 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x04, /* [ 3078] OBJ_aes_128_cfb128 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x15, /* [ 3087] OBJ_aes_192_ecb */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x16, /* [ 3096] OBJ_aes_192_cbc */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x17, /* [ 3105] OBJ_aes_192_ofb128 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x18, /* [ 3114] OBJ_aes_192_cfb128 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x29, /* [ 3123] OBJ_aes_256_ecb */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2A, /* [ 3132] OBJ_aes_256_cbc */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2B, /* [ 3141] OBJ_aes_256_ofb128 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2C, /* [ 3150] OBJ_aes_256_cfb128 */ - 0x55,0x1D,0x17, /* [ 3159] OBJ_hold_instruction_code */ - 0x2A,0x86,0x48,0xCE,0x38,0x02,0x01, /* [ 3162] OBJ_hold_instruction_none */ - 0x2A,0x86,0x48,0xCE,0x38,0x02,0x02, /* [ 3169] OBJ_hold_instruction_call_issuer */ - 0x2A,0x86,0x48,0xCE,0x38,0x02,0x03, /* [ 3176] OBJ_hold_instruction_reject */ - 0x09, /* [ 3183] OBJ_data */ - 0x09,0x92,0x26, /* [ 3184] OBJ_pss */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C, /* [ 3187] OBJ_ucl */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64, /* [ 3194] OBJ_pilot */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01, /* [ 3202] OBJ_pilotAttributeType */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03, /* [ 3211] OBJ_pilotAttributeSyntax */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04, /* [ 3220] OBJ_pilotObjectClass */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x0A, /* [ 3229] OBJ_pilotGroups */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x04, /* [ 3238] OBJ_iA5StringSyntax */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x05, /* [ 3248] OBJ_caseIgnoreIA5StringSyntax */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x03, /* [ 3258] OBJ_pilotObject */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x04, /* [ 3268] OBJ_pilotPerson */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x05, /* [ 3278] OBJ_account */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x06, /* [ 3288] OBJ_document */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x07, /* [ 3298] OBJ_room */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x09, /* [ 3308] OBJ_documentSeries */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0E, /* [ 3318] OBJ_rFC822localPart */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0F, /* [ 3328] OBJ_dNSDomain */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x11, /* [ 3338] OBJ_domainRelatedObject */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x12, /* [ 3348] OBJ_friendlyCountry */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x13, /* [ 3358] OBJ_simpleSecurityObject */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x14, /* [ 3368] OBJ_pilotOrganization */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x15, /* [ 3378] OBJ_pilotDSA */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x16, /* [ 3388] OBJ_qualityLabelledData */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01, /* [ 3398] OBJ_userId */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x02, /* [ 3408] OBJ_textEncodedORAddress */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x03, /* [ 3418] OBJ_rfc822Mailbox */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x04, /* [ 3428] OBJ_info */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x05, /* [ 3438] OBJ_favouriteDrink */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x06, /* [ 3448] OBJ_roomNumber */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x07, /* [ 3458] OBJ_photo */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x08, /* [ 3468] OBJ_userClass */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x09, /* [ 3478] OBJ_host */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0A, /* [ 3488] OBJ_manager */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0B, /* [ 3498] OBJ_documentIdentifier */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0C, /* [ 3508] OBJ_documentTitle */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0D, /* [ 3518] OBJ_documentVersion */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0E, /* [ 3528] OBJ_documentAuthor */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0F, /* [ 3538] OBJ_documentLocation */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x14, /* [ 3548] OBJ_homeTelephoneNumber */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x15, /* [ 3558] OBJ_secretary */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x16, /* [ 3568] OBJ_otherMailbox */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x17, /* [ 3578] OBJ_lastModifiedTime */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x18, /* [ 3588] OBJ_lastModifiedBy */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1A, /* [ 3598] OBJ_aRecord */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1B, /* [ 3608] OBJ_pilotAttributeType27 */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1C, /* [ 3618] OBJ_mXRecord */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1D, /* [ 3628] OBJ_nSRecord */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1E, /* [ 3638] OBJ_sOARecord */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1F, /* [ 3648] OBJ_cNAMERecord */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x25, /* [ 3658] OBJ_associatedDomain */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x26, /* [ 3668] OBJ_associatedName */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x27, /* [ 3678] OBJ_homePostalAddress */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x28, /* [ 3688] OBJ_personalTitle */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x29, /* [ 3698] OBJ_mobileTelephoneNumber */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2A, /* [ 3708] OBJ_pagerTelephoneNumber */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2B, /* [ 3718] OBJ_friendlyCountryName */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2D, /* [ 3728] OBJ_organizationalStatus */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2E, /* [ 3738] OBJ_janetMailbox */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2F, /* [ 3748] OBJ_mailPreferenceOption */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x30, /* [ 3758] OBJ_buildingName */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x31, /* [ 3768] OBJ_dSAQuality */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x32, /* [ 3778] OBJ_singleLevelQuality */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x33, /* [ 3788] OBJ_subtreeMinimumQuality */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x34, /* [ 3798] OBJ_subtreeMaximumQuality */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x35, /* [ 3808] OBJ_personalSignature */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x36, /* [ 3818] OBJ_dITRedirect */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x37, /* [ 3828] OBJ_audio */ - 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x38, /* [ 3838] OBJ_documentPublisher */ - 0x55,0x04,0x2D, /* [ 3848] OBJ_x500UniqueIdentifier */ - 0x2B,0x06,0x01,0x07,0x01, /* [ 3851] OBJ_mime_mhs */ - 0x2B,0x06,0x01,0x07,0x01,0x01, /* [ 3856] OBJ_mime_mhs_headings */ - 0x2B,0x06,0x01,0x07,0x01,0x02, /* [ 3862] OBJ_mime_mhs_bodies */ - 0x2B,0x06,0x01,0x07,0x01,0x01,0x01, /* [ 3868] OBJ_id_hex_partial_message */ - 0x2B,0x06,0x01,0x07,0x01,0x01,0x02, /* [ 3875] OBJ_id_hex_multipart_message */ - 0x55,0x04,0x2C, /* [ 3882] OBJ_generationQualifier */ - 0x55,0x04,0x41, /* [ 3885] OBJ_pseudonym */ - 0x67,0x2A, /* [ 3888] OBJ_id_set */ - 0x67,0x2A,0x00, /* [ 3890] OBJ_set_ctype */ - 0x67,0x2A,0x01, /* [ 3893] OBJ_set_msgExt */ - 0x67,0x2A,0x03, /* [ 3896] OBJ_set_attr */ - 0x67,0x2A,0x05, /* [ 3899] OBJ_set_policy */ - 0x67,0x2A,0x07, /* [ 3902] OBJ_set_certExt */ - 0x67,0x2A,0x08, /* [ 3905] OBJ_set_brand */ - 0x67,0x2A,0x00,0x00, /* [ 3908] OBJ_setct_PANData */ - 0x67,0x2A,0x00,0x01, /* [ 3912] OBJ_setct_PANToken */ - 0x67,0x2A,0x00,0x02, /* [ 3916] OBJ_setct_PANOnly */ - 0x67,0x2A,0x00,0x03, /* [ 3920] OBJ_setct_OIData */ - 0x67,0x2A,0x00,0x04, /* [ 3924] OBJ_setct_PI */ - 0x67,0x2A,0x00,0x05, /* [ 3928] OBJ_setct_PIData */ - 0x67,0x2A,0x00,0x06, /* [ 3932] OBJ_setct_PIDataUnsigned */ - 0x67,0x2A,0x00,0x07, /* [ 3936] OBJ_setct_HODInput */ - 0x67,0x2A,0x00,0x08, /* [ 3940] OBJ_setct_AuthResBaggage */ - 0x67,0x2A,0x00,0x09, /* [ 3944] OBJ_setct_AuthRevReqBaggage */ - 0x67,0x2A,0x00,0x0A, /* [ 3948] OBJ_setct_AuthRevResBaggage */ - 0x67,0x2A,0x00,0x0B, /* [ 3952] OBJ_setct_CapTokenSeq */ - 0x67,0x2A,0x00,0x0C, /* [ 3956] OBJ_setct_PInitResData */ - 0x67,0x2A,0x00,0x0D, /* [ 3960] OBJ_setct_PI_TBS */ - 0x67,0x2A,0x00,0x0E, /* [ 3964] OBJ_setct_PResData */ - 0x67,0x2A,0x00,0x10, /* [ 3968] OBJ_setct_AuthReqTBS */ - 0x67,0x2A,0x00,0x11, /* [ 3972] OBJ_setct_AuthResTBS */ - 0x67,0x2A,0x00,0x12, /* [ 3976] OBJ_setct_AuthResTBSX */ - 0x67,0x2A,0x00,0x13, /* [ 3980] OBJ_setct_AuthTokenTBS */ - 0x67,0x2A,0x00,0x14, /* [ 3984] OBJ_setct_CapTokenData */ - 0x67,0x2A,0x00,0x15, /* [ 3988] OBJ_setct_CapTokenTBS */ - 0x67,0x2A,0x00,0x16, /* [ 3992] OBJ_setct_AcqCardCodeMsg */ - 0x67,0x2A,0x00,0x17, /* [ 3996] OBJ_setct_AuthRevReqTBS */ - 0x67,0x2A,0x00,0x18, /* [ 4000] OBJ_setct_AuthRevResData */ - 0x67,0x2A,0x00,0x19, /* [ 4004] OBJ_setct_AuthRevResTBS */ - 0x67,0x2A,0x00,0x1A, /* [ 4008] OBJ_setct_CapReqTBS */ - 0x67,0x2A,0x00,0x1B, /* [ 4012] OBJ_setct_CapReqTBSX */ - 0x67,0x2A,0x00,0x1C, /* [ 4016] OBJ_setct_CapResData */ - 0x67,0x2A,0x00,0x1D, /* [ 4020] OBJ_setct_CapRevReqTBS */ - 0x67,0x2A,0x00,0x1E, /* [ 4024] OBJ_setct_CapRevReqTBSX */ - 0x67,0x2A,0x00,0x1F, /* [ 4028] OBJ_setct_CapRevResData */ - 0x67,0x2A,0x00,0x20, /* [ 4032] OBJ_setct_CredReqTBS */ - 0x67,0x2A,0x00,0x21, /* [ 4036] OBJ_setct_CredReqTBSX */ - 0x67,0x2A,0x00,0x22, /* [ 4040] OBJ_setct_CredResData */ - 0x67,0x2A,0x00,0x23, /* [ 4044] OBJ_setct_CredRevReqTBS */ - 0x67,0x2A,0x00,0x24, /* [ 4048] OBJ_setct_CredRevReqTBSX */ - 0x67,0x2A,0x00,0x25, /* [ 4052] OBJ_setct_CredRevResData */ - 0x67,0x2A,0x00,0x26, /* [ 4056] OBJ_setct_PCertReqData */ - 0x67,0x2A,0x00,0x27, /* [ 4060] OBJ_setct_PCertResTBS */ - 0x67,0x2A,0x00,0x28, /* [ 4064] OBJ_setct_BatchAdminReqData */ - 0x67,0x2A,0x00,0x29, /* [ 4068] OBJ_setct_BatchAdminResData */ - 0x67,0x2A,0x00,0x2A, /* [ 4072] OBJ_setct_CardCInitResTBS */ - 0x67,0x2A,0x00,0x2B, /* [ 4076] OBJ_setct_MeAqCInitResTBS */ - 0x67,0x2A,0x00,0x2C, /* [ 4080] OBJ_setct_RegFormResTBS */ - 0x67,0x2A,0x00,0x2D, /* [ 4084] OBJ_setct_CertReqData */ - 0x67,0x2A,0x00,0x2E, /* [ 4088] OBJ_setct_CertReqTBS */ - 0x67,0x2A,0x00,0x2F, /* [ 4092] OBJ_setct_CertResData */ - 0x67,0x2A,0x00,0x30, /* [ 4096] OBJ_setct_CertInqReqTBS */ - 0x67,0x2A,0x00,0x31, /* [ 4100] OBJ_setct_ErrorTBS */ - 0x67,0x2A,0x00,0x32, /* [ 4104] OBJ_setct_PIDualSignedTBE */ - 0x67,0x2A,0x00,0x33, /* [ 4108] OBJ_setct_PIUnsignedTBE */ - 0x67,0x2A,0x00,0x34, /* [ 4112] OBJ_setct_AuthReqTBE */ - 0x67,0x2A,0x00,0x35, /* [ 4116] OBJ_setct_AuthResTBE */ - 0x67,0x2A,0x00,0x36, /* [ 4120] OBJ_setct_AuthResTBEX */ - 0x67,0x2A,0x00,0x37, /* [ 4124] OBJ_setct_AuthTokenTBE */ - 0x67,0x2A,0x00,0x38, /* [ 4128] OBJ_setct_CapTokenTBE */ - 0x67,0x2A,0x00,0x39, /* [ 4132] OBJ_setct_CapTokenTBEX */ - 0x67,0x2A,0x00,0x3A, /* [ 4136] OBJ_setct_AcqCardCodeMsgTBE */ - 0x67,0x2A,0x00,0x3B, /* [ 4140] OBJ_setct_AuthRevReqTBE */ - 0x67,0x2A,0x00,0x3C, /* [ 4144] OBJ_setct_AuthRevResTBE */ - 0x67,0x2A,0x00,0x3D, /* [ 4148] OBJ_setct_AuthRevResTBEB */ - 0x67,0x2A,0x00,0x3E, /* [ 4152] OBJ_setct_CapReqTBE */ - 0x67,0x2A,0x00,0x3F, /* [ 4156] OBJ_setct_CapReqTBEX */ - 0x67,0x2A,0x00,0x40, /* [ 4160] OBJ_setct_CapResTBE */ - 0x67,0x2A,0x00,0x41, /* [ 4164] OBJ_setct_CapRevReqTBE */ - 0x67,0x2A,0x00,0x42, /* [ 4168] OBJ_setct_CapRevReqTBEX */ - 0x67,0x2A,0x00,0x43, /* [ 4172] OBJ_setct_CapRevResTBE */ - 0x67,0x2A,0x00,0x44, /* [ 4176] OBJ_setct_CredReqTBE */ - 0x67,0x2A,0x00,0x45, /* [ 4180] OBJ_setct_CredReqTBEX */ - 0x67,0x2A,0x00,0x46, /* [ 4184] OBJ_setct_CredResTBE */ - 0x67,0x2A,0x00,0x47, /* [ 4188] OBJ_setct_CredRevReqTBE */ - 0x67,0x2A,0x00,0x48, /* [ 4192] OBJ_setct_CredRevReqTBEX */ - 0x67,0x2A,0x00,0x49, /* [ 4196] OBJ_setct_CredRevResTBE */ - 0x67,0x2A,0x00,0x4A, /* [ 4200] OBJ_setct_BatchAdminReqTBE */ - 0x67,0x2A,0x00,0x4B, /* [ 4204] OBJ_setct_BatchAdminResTBE */ - 0x67,0x2A,0x00,0x4C, /* [ 4208] OBJ_setct_RegFormReqTBE */ - 0x67,0x2A,0x00,0x4D, /* [ 4212] OBJ_setct_CertReqTBE */ - 0x67,0x2A,0x00,0x4E, /* [ 4216] OBJ_setct_CertReqTBEX */ - 0x67,0x2A,0x00,0x4F, /* [ 4220] OBJ_setct_CertResTBE */ - 0x67,0x2A,0x00,0x50, /* [ 4224] OBJ_setct_CRLNotificationTBS */ - 0x67,0x2A,0x00,0x51, /* [ 4228] OBJ_setct_CRLNotificationResTBS */ - 0x67,0x2A,0x00,0x52, /* [ 4232] OBJ_setct_BCIDistributionTBS */ - 0x67,0x2A,0x01,0x01, /* [ 4236] OBJ_setext_genCrypt */ - 0x67,0x2A,0x01,0x03, /* [ 4240] OBJ_setext_miAuth */ - 0x67,0x2A,0x01,0x04, /* [ 4244] OBJ_setext_pinSecure */ - 0x67,0x2A,0x01,0x05, /* [ 4248] OBJ_setext_pinAny */ - 0x67,0x2A,0x01,0x07, /* [ 4252] OBJ_setext_track2 */ - 0x67,0x2A,0x01,0x08, /* [ 4256] OBJ_setext_cv */ - 0x67,0x2A,0x05,0x00, /* [ 4260] OBJ_set_policy_root */ - 0x67,0x2A,0x07,0x00, /* [ 4264] OBJ_setCext_hashedRoot */ - 0x67,0x2A,0x07,0x01, /* [ 4268] OBJ_setCext_certType */ - 0x67,0x2A,0x07,0x02, /* [ 4272] OBJ_setCext_merchData */ - 0x67,0x2A,0x07,0x03, /* [ 4276] OBJ_setCext_cCertRequired */ - 0x67,0x2A,0x07,0x04, /* [ 4280] OBJ_setCext_tunneling */ - 0x67,0x2A,0x07,0x05, /* [ 4284] OBJ_setCext_setExt */ - 0x67,0x2A,0x07,0x06, /* [ 4288] OBJ_setCext_setQualf */ - 0x67,0x2A,0x07,0x07, /* [ 4292] OBJ_setCext_PGWYcapabilities */ - 0x67,0x2A,0x07,0x08, /* [ 4296] OBJ_setCext_TokenIdentifier */ - 0x67,0x2A,0x07,0x09, /* [ 4300] OBJ_setCext_Track2Data */ - 0x67,0x2A,0x07,0x0A, /* [ 4304] OBJ_setCext_TokenType */ - 0x67,0x2A,0x07,0x0B, /* [ 4308] OBJ_setCext_IssuerCapabilities */ - 0x67,0x2A,0x03,0x00, /* [ 4312] OBJ_setAttr_Cert */ - 0x67,0x2A,0x03,0x01, /* [ 4316] OBJ_setAttr_PGWYcap */ - 0x67,0x2A,0x03,0x02, /* [ 4320] OBJ_setAttr_TokenType */ - 0x67,0x2A,0x03,0x03, /* [ 4324] OBJ_setAttr_IssCap */ - 0x67,0x2A,0x03,0x00,0x00, /* [ 4328] OBJ_set_rootKeyThumb */ - 0x67,0x2A,0x03,0x00,0x01, /* [ 4333] OBJ_set_addPolicy */ - 0x67,0x2A,0x03,0x02,0x01, /* [ 4338] OBJ_setAttr_Token_EMV */ - 0x67,0x2A,0x03,0x02,0x02, /* [ 4343] OBJ_setAttr_Token_B0Prime */ - 0x67,0x2A,0x03,0x03,0x03, /* [ 4348] OBJ_setAttr_IssCap_CVM */ - 0x67,0x2A,0x03,0x03,0x04, /* [ 4353] OBJ_setAttr_IssCap_T2 */ - 0x67,0x2A,0x03,0x03,0x05, /* [ 4358] OBJ_setAttr_IssCap_Sig */ - 0x67,0x2A,0x03,0x03,0x03,0x01, /* [ 4363] OBJ_setAttr_GenCryptgrm */ - 0x67,0x2A,0x03,0x03,0x04,0x01, /* [ 4369] OBJ_setAttr_T2Enc */ - 0x67,0x2A,0x03,0x03,0x04,0x02, /* [ 4375] OBJ_setAttr_T2cleartxt */ - 0x67,0x2A,0x03,0x03,0x05,0x01, /* [ 4381] OBJ_setAttr_TokICCsig */ - 0x67,0x2A,0x03,0x03,0x05,0x02, /* [ 4387] OBJ_setAttr_SecDevSig */ - 0x67,0x2A,0x08,0x01, /* [ 4393] OBJ_set_brand_IATA_ATA */ - 0x67,0x2A,0x08,0x1E, /* [ 4397] OBJ_set_brand_Diners */ - 0x67,0x2A,0x08,0x22, /* [ 4401] OBJ_set_brand_AmericanExpress */ - 0x67,0x2A,0x08,0x23, /* [ 4405] OBJ_set_brand_JCB */ - 0x67,0x2A,0x08,0x04, /* [ 4409] OBJ_set_brand_Visa */ - 0x67,0x2A,0x08,0x05, /* [ 4413] OBJ_set_brand_MasterCard */ - 0x67,0x2A,0x08,0xAE,0x7B, /* [ 4417] OBJ_set_brand_Novus */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x0A, /* [ 4422] OBJ_des_cdmf */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x06, /* [ 4430] OBJ_rsaOAEPEncryptionSET */ - 0x67, /* [ 4439] OBJ_international_organizations */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02, /* [ 4440] OBJ_ms_smartcard_login */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03, /* [ 4450] OBJ_ms_upn */ - 0x55,0x04,0x09, /* [ 4460] OBJ_streetAddress */ - 0x55,0x04,0x11, /* [ 4463] OBJ_postalCode */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x15, /* [ 4466] OBJ_id_ppl */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0E, /* [ 4473] OBJ_proxyCertInfo */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x00, /* [ 4481] OBJ_id_ppl_anyLanguage */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x01, /* [ 4489] OBJ_id_ppl_inheritAll */ - 0x55,0x1D,0x1E, /* [ 4497] OBJ_name_constraints */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x02, /* [ 4500] OBJ_Independent */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B, /* [ 4508] OBJ_sha256WithRSAEncryption */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C, /* [ 4517] OBJ_sha384WithRSAEncryption */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0D, /* [ 4526] OBJ_sha512WithRSAEncryption */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0E, /* [ 4535] OBJ_sha224WithRSAEncryption */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01, /* [ 4544] OBJ_sha256 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02, /* [ 4553] OBJ_sha384 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03, /* [ 4562] OBJ_sha512 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04, /* [ 4571] OBJ_sha224 */ - 0x2B, /* [ 4580] OBJ_identified_organization */ - 0x2B,0x81,0x04, /* [ 4581] OBJ_certicom_arc */ - 0x67,0x2B, /* [ 4584] OBJ_wap */ - 0x67,0x2B,0x01, /* [ 4586] OBJ_wap_wsg */ - 0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03, /* [ 4589] OBJ_X9_62_id_characteristic_two_basis */ - 0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x01, /* [ 4597] OBJ_X9_62_onBasis */ - 0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x02, /* [ 4606] OBJ_X9_62_tpBasis */ - 0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x03, /* [ 4615] OBJ_X9_62_ppBasis */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x01, /* [ 4624] OBJ_X9_62_c2pnb163v1 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x02, /* [ 4632] OBJ_X9_62_c2pnb163v2 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x03, /* [ 4640] OBJ_X9_62_c2pnb163v3 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x04, /* [ 4648] OBJ_X9_62_c2pnb176v1 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x05, /* [ 4656] OBJ_X9_62_c2tnb191v1 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x06, /* [ 4664] OBJ_X9_62_c2tnb191v2 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x07, /* [ 4672] OBJ_X9_62_c2tnb191v3 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x08, /* [ 4680] OBJ_X9_62_c2onb191v4 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x09, /* [ 4688] OBJ_X9_62_c2onb191v5 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0A, /* [ 4696] OBJ_X9_62_c2pnb208w1 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0B, /* [ 4704] OBJ_X9_62_c2tnb239v1 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0C, /* [ 4712] OBJ_X9_62_c2tnb239v2 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0D, /* [ 4720] OBJ_X9_62_c2tnb239v3 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0E, /* [ 4728] OBJ_X9_62_c2onb239v4 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0F, /* [ 4736] OBJ_X9_62_c2onb239v5 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x10, /* [ 4744] OBJ_X9_62_c2pnb272w1 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x11, /* [ 4752] OBJ_X9_62_c2pnb304w1 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x12, /* [ 4760] OBJ_X9_62_c2tnb359v1 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x13, /* [ 4768] OBJ_X9_62_c2pnb368w1 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x14, /* [ 4776] OBJ_X9_62_c2tnb431r1 */ - 0x2B,0x81,0x04,0x00,0x06, /* [ 4784] OBJ_secp112r1 */ - 0x2B,0x81,0x04,0x00,0x07, /* [ 4789] OBJ_secp112r2 */ - 0x2B,0x81,0x04,0x00,0x1C, /* [ 4794] OBJ_secp128r1 */ - 0x2B,0x81,0x04,0x00,0x1D, /* [ 4799] OBJ_secp128r2 */ - 0x2B,0x81,0x04,0x00,0x09, /* [ 4804] OBJ_secp160k1 */ - 0x2B,0x81,0x04,0x00,0x08, /* [ 4809] OBJ_secp160r1 */ - 0x2B,0x81,0x04,0x00,0x1E, /* [ 4814] OBJ_secp160r2 */ - 0x2B,0x81,0x04,0x00,0x1F, /* [ 4819] OBJ_secp192k1 */ - 0x2B,0x81,0x04,0x00,0x20, /* [ 4824] OBJ_secp224k1 */ - 0x2B,0x81,0x04,0x00,0x21, /* [ 4829] OBJ_secp224r1 */ - 0x2B,0x81,0x04,0x00,0x0A, /* [ 4834] OBJ_secp256k1 */ - 0x2B,0x81,0x04,0x00,0x22, /* [ 4839] OBJ_secp384r1 */ - 0x2B,0x81,0x04,0x00,0x23, /* [ 4844] OBJ_secp521r1 */ - 0x2B,0x81,0x04,0x00,0x04, /* [ 4849] OBJ_sect113r1 */ - 0x2B,0x81,0x04,0x00,0x05, /* [ 4854] OBJ_sect113r2 */ - 0x2B,0x81,0x04,0x00,0x16, /* [ 4859] OBJ_sect131r1 */ - 0x2B,0x81,0x04,0x00,0x17, /* [ 4864] OBJ_sect131r2 */ - 0x2B,0x81,0x04,0x00,0x01, /* [ 4869] OBJ_sect163k1 */ - 0x2B,0x81,0x04,0x00,0x02, /* [ 4874] OBJ_sect163r1 */ - 0x2B,0x81,0x04,0x00,0x0F, /* [ 4879] OBJ_sect163r2 */ - 0x2B,0x81,0x04,0x00,0x18, /* [ 4884] OBJ_sect193r1 */ - 0x2B,0x81,0x04,0x00,0x19, /* [ 4889] OBJ_sect193r2 */ - 0x2B,0x81,0x04,0x00,0x1A, /* [ 4894] OBJ_sect233k1 */ - 0x2B,0x81,0x04,0x00,0x1B, /* [ 4899] OBJ_sect233r1 */ - 0x2B,0x81,0x04,0x00,0x03, /* [ 4904] OBJ_sect239k1 */ - 0x2B,0x81,0x04,0x00,0x10, /* [ 4909] OBJ_sect283k1 */ - 0x2B,0x81,0x04,0x00,0x11, /* [ 4914] OBJ_sect283r1 */ - 0x2B,0x81,0x04,0x00,0x24, /* [ 4919] OBJ_sect409k1 */ - 0x2B,0x81,0x04,0x00,0x25, /* [ 4924] OBJ_sect409r1 */ - 0x2B,0x81,0x04,0x00,0x26, /* [ 4929] OBJ_sect571k1 */ - 0x2B,0x81,0x04,0x00,0x27, /* [ 4934] OBJ_sect571r1 */ - 0x67,0x2B,0x01,0x04,0x01, /* [ 4939] OBJ_wap_wsg_idm_ecid_wtls1 */ - 0x67,0x2B,0x01,0x04,0x03, /* [ 4944] OBJ_wap_wsg_idm_ecid_wtls3 */ - 0x67,0x2B,0x01,0x04,0x04, /* [ 4949] OBJ_wap_wsg_idm_ecid_wtls4 */ - 0x67,0x2B,0x01,0x04,0x05, /* [ 4954] OBJ_wap_wsg_idm_ecid_wtls5 */ - 0x67,0x2B,0x01,0x04,0x06, /* [ 4959] OBJ_wap_wsg_idm_ecid_wtls6 */ - 0x67,0x2B,0x01,0x04,0x07, /* [ 4964] OBJ_wap_wsg_idm_ecid_wtls7 */ - 0x67,0x2B,0x01,0x04,0x08, /* [ 4969] OBJ_wap_wsg_idm_ecid_wtls8 */ - 0x67,0x2B,0x01,0x04,0x09, /* [ 4974] OBJ_wap_wsg_idm_ecid_wtls9 */ - 0x67,0x2B,0x01,0x04,0x0A, /* [ 4979] OBJ_wap_wsg_idm_ecid_wtls10 */ - 0x67,0x2B,0x01,0x04,0x0B, /* [ 4984] OBJ_wap_wsg_idm_ecid_wtls11 */ - 0x67,0x2B,0x01,0x04,0x0C, /* [ 4989] OBJ_wap_wsg_idm_ecid_wtls12 */ - 0x55,0x1D,0x20,0x00, /* [ 4994] OBJ_any_policy */ - 0x55,0x1D,0x21, /* [ 4998] OBJ_policy_mappings */ - 0x55,0x1D,0x36, /* [ 5001] OBJ_inhibit_any_policy */ - 0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x02, /* [ 5004] OBJ_camellia_128_cbc */ - 0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x03, /* [ 5015] OBJ_camellia_192_cbc */ - 0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x04, /* [ 5026] OBJ_camellia_256_cbc */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x01, /* [ 5037] OBJ_camellia_128_ecb */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x15, /* [ 5045] OBJ_camellia_192_ecb */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x29, /* [ 5053] OBJ_camellia_256_ecb */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x04, /* [ 5061] OBJ_camellia_128_cfb128 */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x18, /* [ 5069] OBJ_camellia_192_cfb128 */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2C, /* [ 5077] OBJ_camellia_256_cfb128 */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x03, /* [ 5085] OBJ_camellia_128_ofb128 */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x17, /* [ 5093] OBJ_camellia_192_ofb128 */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2B, /* [ 5101] OBJ_camellia_256_ofb128 */ - 0x55,0x1D,0x09, /* [ 5109] OBJ_subject_directory_attributes */ - 0x55,0x1D,0x1C, /* [ 5112] OBJ_issuing_distribution_point */ - 0x55,0x1D,0x1D, /* [ 5115] OBJ_certificate_issuer */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x44, /* [ 5118] OBJ_kisa */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x03, /* [ 5124] OBJ_seed_ecb */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x04, /* [ 5132] OBJ_seed_cbc */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x06, /* [ 5140] OBJ_seed_ofb128 */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x05, /* [ 5148] OBJ_seed_cfb128 */ - 0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x01, /* [ 5156] OBJ_hmac_md5 */ - 0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x02, /* [ 5164] OBJ_hmac_sha1 */ - 0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0D, /* [ 5172] OBJ_id_PasswordBasedMAC */ - 0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x1E, /* [ 5181] OBJ_id_DHBasedMac */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x10, /* [ 5190] OBJ_id_it_suppLangTags */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x05, /* [ 5198] OBJ_caRepository */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x09, /* [ 5206] OBJ_id_smime_ct_compressedData */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1B, /* [ 5217] OBJ_id_ct_asciiTextWithCRLF */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x05, /* [ 5228] OBJ_id_aes128_wrap */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x19, /* [ 5237] OBJ_id_aes192_wrap */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2D, /* [ 5246] OBJ_id_aes256_wrap */ - 0x2A,0x86,0x48,0xCE,0x3D,0x04,0x02, /* [ 5255] OBJ_ecdsa_with_Recommended */ - 0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03, /* [ 5262] OBJ_ecdsa_with_Specified */ - 0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x01, /* [ 5269] OBJ_ecdsa_with_SHA224 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02, /* [ 5277] OBJ_ecdsa_with_SHA256 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03, /* [ 5285] OBJ_ecdsa_with_SHA384 */ - 0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04, /* [ 5293] OBJ_ecdsa_with_SHA512 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x06, /* [ 5301] OBJ_hmacWithMD5 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x08, /* [ 5309] OBJ_hmacWithSHA224 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x09, /* [ 5317] OBJ_hmacWithSHA256 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0A, /* [ 5325] OBJ_hmacWithSHA384 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0B, /* [ 5333] OBJ_hmacWithSHA512 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x01, /* [ 5341] OBJ_dsa_with_SHA224 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x02, /* [ 5350] OBJ_dsa_with_SHA256 */ - 0x28,0xCF,0x06,0x03,0x00,0x37, /* [ 5359] OBJ_whirlpool */ - 0x2A,0x85,0x03,0x02,0x02, /* [ 5365] OBJ_cryptopro */ - 0x2A,0x85,0x03,0x02,0x09, /* [ 5370] OBJ_cryptocom */ - 0x2A,0x85,0x03,0x02,0x02,0x03, /* [ 5375] OBJ_id_GostR3411_94_with_GostR3410_2001 */ - 0x2A,0x85,0x03,0x02,0x02,0x04, /* [ 5381] OBJ_id_GostR3411_94_with_GostR3410_94 */ - 0x2A,0x85,0x03,0x02,0x02,0x09, /* [ 5387] OBJ_id_GostR3411_94 */ - 0x2A,0x85,0x03,0x02,0x02,0x0A, /* [ 5393] OBJ_id_HMACGostR3411_94 */ - 0x2A,0x85,0x03,0x02,0x02,0x13, /* [ 5399] OBJ_id_GostR3410_2001 */ - 0x2A,0x85,0x03,0x02,0x02,0x14, /* [ 5405] OBJ_id_GostR3410_94 */ - 0x2A,0x85,0x03,0x02,0x02,0x15, /* [ 5411] OBJ_id_Gost28147_89 */ - 0x2A,0x85,0x03,0x02,0x02,0x16, /* [ 5417] OBJ_id_Gost28147_89_MAC */ - 0x2A,0x85,0x03,0x02,0x02,0x17, /* [ 5423] OBJ_id_GostR3411_94_prf */ - 0x2A,0x85,0x03,0x02,0x02,0x62, /* [ 5429] OBJ_id_GostR3410_2001DH */ - 0x2A,0x85,0x03,0x02,0x02,0x63, /* [ 5435] OBJ_id_GostR3410_94DH */ - 0x2A,0x85,0x03,0x02,0x02,0x0E,0x01, /* [ 5441] OBJ_id_Gost28147_89_CryptoPro_KeyMeshing */ - 0x2A,0x85,0x03,0x02,0x02,0x0E,0x00, /* [ 5448] OBJ_id_Gost28147_89_None_KeyMeshing */ - 0x2A,0x85,0x03,0x02,0x02,0x1E,0x00, /* [ 5455] OBJ_id_GostR3411_94_TestParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x1E,0x01, /* [ 5462] OBJ_id_GostR3411_94_CryptoProParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x1F,0x00, /* [ 5469] OBJ_id_Gost28147_89_TestParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x1F,0x01, /* [ 5476] OBJ_id_Gost28147_89_CryptoPro_A_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x1F,0x02, /* [ 5483] OBJ_id_Gost28147_89_CryptoPro_B_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x1F,0x03, /* [ 5490] OBJ_id_Gost28147_89_CryptoPro_C_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x1F,0x04, /* [ 5497] OBJ_id_Gost28147_89_CryptoPro_D_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x1F,0x05, /* [ 5504] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x1F,0x06, /* [ 5511] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x1F,0x07, /* [ 5518] OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x20,0x00, /* [ 5525] OBJ_id_GostR3410_94_TestParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x20,0x02, /* [ 5532] OBJ_id_GostR3410_94_CryptoPro_A_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x20,0x03, /* [ 5539] OBJ_id_GostR3410_94_CryptoPro_B_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x20,0x04, /* [ 5546] OBJ_id_GostR3410_94_CryptoPro_C_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x20,0x05, /* [ 5553] OBJ_id_GostR3410_94_CryptoPro_D_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x21,0x01, /* [ 5560] OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x21,0x02, /* [ 5567] OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x21,0x03, /* [ 5574] OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x23,0x00, /* [ 5581] OBJ_id_GostR3410_2001_TestParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x23,0x01, /* [ 5588] OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x23,0x02, /* [ 5595] OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x23,0x03, /* [ 5602] OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x24,0x00, /* [ 5609] OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x24,0x01, /* [ 5616] OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet */ - 0x2A,0x85,0x03,0x02,0x02,0x14,0x01, /* [ 5623] OBJ_id_GostR3410_94_a */ - 0x2A,0x85,0x03,0x02,0x02,0x14,0x02, /* [ 5630] OBJ_id_GostR3410_94_aBis */ - 0x2A,0x85,0x03,0x02,0x02,0x14,0x03, /* [ 5637] OBJ_id_GostR3410_94_b */ - 0x2A,0x85,0x03,0x02,0x02,0x14,0x04, /* [ 5644] OBJ_id_GostR3410_94_bBis */ - 0x2A,0x85,0x03,0x02,0x09,0x01,0x06,0x01, /* [ 5651] OBJ_id_Gost28147_89_cc */ - 0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x03, /* [ 5659] OBJ_id_GostR3410_94_cc */ - 0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x04, /* [ 5667] OBJ_id_GostR3410_2001_cc */ - 0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03, /* [ 5675] OBJ_id_GostR3411_94_with_GostR3410_94_cc */ - 0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04, /* [ 5683] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */ - 0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01, /* [ 5691] OBJ_id_GostR3410_2001_ParamSet_cc */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02, /* [ 5699] OBJ_LocalKeySet */ - 0x55,0x1D,0x2E, /* [ 5708] OBJ_freshest_crl */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x03, /* [ 5711] OBJ_id_on_permanentIdentifier */ - 0x55,0x04,0x0E, /* [ 5719] OBJ_searchGuide */ - 0x55,0x04,0x0F, /* [ 5722] OBJ_businessCategory */ - 0x55,0x04,0x10, /* [ 5725] OBJ_postalAddress */ - 0x55,0x04,0x12, /* [ 5728] OBJ_postOfficeBox */ - 0x55,0x04,0x13, /* [ 5731] OBJ_physicalDeliveryOfficeName */ - 0x55,0x04,0x14, /* [ 5734] OBJ_telephoneNumber */ - 0x55,0x04,0x15, /* [ 5737] OBJ_telexNumber */ - 0x55,0x04,0x16, /* [ 5740] OBJ_teletexTerminalIdentifier */ - 0x55,0x04,0x17, /* [ 5743] OBJ_facsimileTelephoneNumber */ - 0x55,0x04,0x18, /* [ 5746] OBJ_x121Address */ - 0x55,0x04,0x19, /* [ 5749] OBJ_internationaliSDNNumber */ - 0x55,0x04,0x1A, /* [ 5752] OBJ_registeredAddress */ - 0x55,0x04,0x1B, /* [ 5755] OBJ_destinationIndicator */ - 0x55,0x04,0x1C, /* [ 5758] OBJ_preferredDeliveryMethod */ - 0x55,0x04,0x1D, /* [ 5761] OBJ_presentationAddress */ - 0x55,0x04,0x1E, /* [ 5764] OBJ_supportedApplicationContext */ - 0x55,0x04,0x1F, /* [ 5767] OBJ_member */ - 0x55,0x04,0x20, /* [ 5770] OBJ_owner */ - 0x55,0x04,0x21, /* [ 5773] OBJ_roleOccupant */ - 0x55,0x04,0x22, /* [ 5776] OBJ_seeAlso */ - 0x55,0x04,0x23, /* [ 5779] OBJ_userPassword */ - 0x55,0x04,0x24, /* [ 5782] OBJ_userCertificate */ - 0x55,0x04,0x25, /* [ 5785] OBJ_cACertificate */ - 0x55,0x04,0x26, /* [ 5788] OBJ_authorityRevocationList */ - 0x55,0x04,0x27, /* [ 5791] OBJ_certificateRevocationList */ - 0x55,0x04,0x28, /* [ 5794] OBJ_crossCertificatePair */ - 0x55,0x04,0x2F, /* [ 5797] OBJ_enhancedSearchGuide */ - 0x55,0x04,0x30, /* [ 5800] OBJ_protocolInformation */ - 0x55,0x04,0x31, /* [ 5803] OBJ_distinguishedName */ - 0x55,0x04,0x32, /* [ 5806] OBJ_uniqueMember */ - 0x55,0x04,0x33, /* [ 5809] OBJ_houseIdentifier */ - 0x55,0x04,0x34, /* [ 5812] OBJ_supportedAlgorithms */ - 0x55,0x04,0x35, /* [ 5815] OBJ_deltaRevocationList */ - 0x55,0x04,0x36, /* [ 5818] OBJ_dmdName */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x09, /* [ 5821] OBJ_id_alg_PWRI_KEK */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x06, /* [ 5832] OBJ_aes_128_gcm */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x07, /* [ 5841] OBJ_aes_128_ccm */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x08, /* [ 5850] OBJ_id_aes128_wrap_pad */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1A, /* [ 5859] OBJ_aes_192_gcm */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1B, /* [ 5868] OBJ_aes_192_ccm */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1C, /* [ 5877] OBJ_id_aes192_wrap_pad */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2E, /* [ 5886] OBJ_aes_256_gcm */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2F, /* [ 5895] OBJ_aes_256_ccm */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x30, /* [ 5904] OBJ_id_aes256_wrap_pad */ - 0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x02, /* [ 5913] OBJ_id_camellia128_wrap */ - 0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x03, /* [ 5924] OBJ_id_camellia192_wrap */ - 0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x04, /* [ 5935] OBJ_id_camellia256_wrap */ - 0x55,0x1D,0x25,0x00, /* [ 5946] OBJ_anyExtendedKeyUsage */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x08, /* [ 5950] OBJ_mgf1 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0A, /* [ 5959] OBJ_rsassaPss */ - 0x2B,0x6F,0x02,0x8C,0x53,0x00,0x01,0x01, /* [ 5968] OBJ_aes_128_xts */ - 0x2B,0x6F,0x02,0x8C,0x53,0x00,0x01,0x02, /* [ 5976] OBJ_aes_256_xts */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x07, /* [ 5984] OBJ_rsaesOaep */ - 0x2A,0x86,0x48,0xCE,0x3E,0x02,0x01, /* [ 5993] OBJ_dhpublicnumber */ - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x01, /* [ 6000] OBJ_brainpoolP160r1 */ - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x02, /* [ 6009] OBJ_brainpoolP160t1 */ - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x03, /* [ 6018] OBJ_brainpoolP192r1 */ - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x04, /* [ 6027] OBJ_brainpoolP192t1 */ - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x05, /* [ 6036] OBJ_brainpoolP224r1 */ - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x06, /* [ 6045] OBJ_brainpoolP224t1 */ - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x07, /* [ 6054] OBJ_brainpoolP256r1 */ - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x08, /* [ 6063] OBJ_brainpoolP256t1 */ - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x09, /* [ 6072] OBJ_brainpoolP320r1 */ - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0A, /* [ 6081] OBJ_brainpoolP320t1 */ - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0B, /* [ 6090] OBJ_brainpoolP384r1 */ - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0C, /* [ 6099] OBJ_brainpoolP384t1 */ - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0D, /* [ 6108] OBJ_brainpoolP512r1 */ - 0x2B,0x24,0x03,0x03,0x02,0x08,0x01,0x01,0x0E, /* [ 6117] OBJ_brainpoolP512t1 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x09, /* [ 6126] OBJ_pSpecified */ - 0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x02, /* [ 6135] OBJ_dhSinglePass_stdDH_sha1kdf_scheme */ - 0x2B,0x81,0x04,0x01,0x0B,0x00, /* [ 6144] OBJ_dhSinglePass_stdDH_sha224kdf_scheme */ - 0x2B,0x81,0x04,0x01,0x0B,0x01, /* [ 6150] OBJ_dhSinglePass_stdDH_sha256kdf_scheme */ - 0x2B,0x81,0x04,0x01,0x0B,0x02, /* [ 6156] OBJ_dhSinglePass_stdDH_sha384kdf_scheme */ - 0x2B,0x81,0x04,0x01,0x0B,0x03, /* [ 6162] OBJ_dhSinglePass_stdDH_sha512kdf_scheme */ - 0x2B,0x81,0x05,0x10,0x86,0x48,0x3F,0x00,0x03, /* [ 6168] OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme */ - 0x2B,0x81,0x04,0x01,0x0E,0x00, /* [ 6177] OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme */ - 0x2B,0x81,0x04,0x01,0x0E,0x01, /* [ 6183] OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme */ - 0x2B,0x81,0x04,0x01,0x0E,0x02, /* [ 6189] OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme */ - 0x2B,0x81,0x04,0x01,0x0E,0x03, /* [ 6195] OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme */ - 0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x02, /* [ 6201] OBJ_ct_precert_scts */ - 0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x03, /* [ 6211] OBJ_ct_precert_poison */ - 0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x04, /* [ 6221] OBJ_ct_precert_signer */ - 0x2B,0x06,0x01,0x04,0x01,0xD6,0x79,0x02,0x04,0x05, /* [ 6231] OBJ_ct_cert_scts */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x01, /* [ 6241] OBJ_jurisdictionLocalityName */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x02, /* [ 6252] OBJ_jurisdictionStateOrProvinceName */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x3C,0x02,0x01,0x03, /* [ 6263] OBJ_jurisdictionCountryName */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x06, /* [ 6274] OBJ_camellia_128_gcm */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x07, /* [ 6282] OBJ_camellia_128_ccm */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x09, /* [ 6290] OBJ_camellia_128_ctr */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x0A, /* [ 6298] OBJ_camellia_128_cmac */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x1A, /* [ 6306] OBJ_camellia_192_gcm */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x1B, /* [ 6314] OBJ_camellia_192_ccm */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x1D, /* [ 6322] OBJ_camellia_192_ctr */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x1E, /* [ 6330] OBJ_camellia_192_cmac */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2E, /* [ 6338] OBJ_camellia_256_gcm */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2F, /* [ 6346] OBJ_camellia_256_ccm */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x31, /* [ 6354] OBJ_camellia_256_ctr */ - 0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x32, /* [ 6362] OBJ_camellia_256_cmac */ - 0x2B,0x06,0x01,0x04,0x01,0xDA,0x47,0x04,0x0B, /* [ 6370] OBJ_id_scrypt */ - 0x2A,0x85,0x03,0x07,0x01, /* [ 6379] OBJ_id_tc26 */ - 0x2A,0x85,0x03,0x07,0x01,0x01, /* [ 6384] OBJ_id_tc26_algorithms */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x01, /* [ 6390] OBJ_id_tc26_sign */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x01,0x01, /* [ 6397] OBJ_id_GostR3410_2012_256 */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x01,0x02, /* [ 6405] OBJ_id_GostR3410_2012_512 */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x02, /* [ 6413] OBJ_id_tc26_digest */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x02,0x02, /* [ 6420] OBJ_id_GostR3411_2012_256 */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x02,0x03, /* [ 6428] OBJ_id_GostR3411_2012_512 */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x03, /* [ 6436] OBJ_id_tc26_signwithdigest */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x03,0x02, /* [ 6443] OBJ_id_tc26_signwithdigest_gost3410_2012_256 */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x03,0x03, /* [ 6451] OBJ_id_tc26_signwithdigest_gost3410_2012_512 */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x04, /* [ 6459] OBJ_id_tc26_mac */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x04,0x01, /* [ 6466] OBJ_id_tc26_hmac_gost_3411_2012_256 */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x04,0x02, /* [ 6474] OBJ_id_tc26_hmac_gost_3411_2012_512 */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x05, /* [ 6482] OBJ_id_tc26_cipher */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x06, /* [ 6489] OBJ_id_tc26_agreement */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x06,0x01, /* [ 6496] OBJ_id_tc26_agreement_gost_3410_2012_256 */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x06,0x02, /* [ 6504] OBJ_id_tc26_agreement_gost_3410_2012_512 */ - 0x2A,0x85,0x03,0x07,0x01,0x02, /* [ 6512] OBJ_id_tc26_constants */ - 0x2A,0x85,0x03,0x07,0x01,0x02,0x01, /* [ 6518] OBJ_id_tc26_sign_constants */ - 0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02, /* [ 6525] OBJ_id_tc26_gost_3410_2012_512_constants */ - 0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x00, /* [ 6533] OBJ_id_tc26_gost_3410_2012_512_paramSetTest */ - 0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x01, /* [ 6542] OBJ_id_tc26_gost_3410_2012_512_paramSetA */ - 0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x02, /* [ 6551] OBJ_id_tc26_gost_3410_2012_512_paramSetB */ - 0x2A,0x85,0x03,0x07,0x01,0x02,0x02, /* [ 6560] OBJ_id_tc26_digest_constants */ - 0x2A,0x85,0x03,0x07,0x01,0x02,0x05, /* [ 6567] OBJ_id_tc26_cipher_constants */ - 0x2A,0x85,0x03,0x07,0x01,0x02,0x05,0x01, /* [ 6574] OBJ_id_tc26_gost_28147_constants */ - 0x2A,0x85,0x03,0x07,0x01,0x02,0x05,0x01,0x01, /* [ 6582] OBJ_id_tc26_gost_28147_param_Z */ - 0x2A,0x85,0x03,0x03,0x81,0x03,0x01,0x01, /* [ 6591] OBJ_INN */ - 0x2A,0x85,0x03,0x64,0x01, /* [ 6599] OBJ_OGRN */ - 0x2A,0x85,0x03,0x64,0x03, /* [ 6604] OBJ_SNILS */ - 0x2A,0x85,0x03,0x64,0x6F, /* [ 6609] OBJ_subjectSignTool */ - 0x2A,0x85,0x03,0x64,0x70, /* [ 6614] OBJ_issuerSignTool */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x18, /* [ 6619] OBJ_tlsfeature */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x11, /* [ 6627] OBJ_ipsec_IKE */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x12, /* [ 6635] OBJ_capwapAC */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x13, /* [ 6643] OBJ_capwapWTP */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x15, /* [ 6651] OBJ_sshClient */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x16, /* [ 6659] OBJ_sshServer */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x17, /* [ 6667] OBJ_sendRouter */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x18, /* [ 6675] OBJ_sendProxiedRouter */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x19, /* [ 6683] OBJ_sendOwner */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1A, /* [ 6691] OBJ_sendProxiedOwner */ - 0x2B,0x06,0x01,0x05,0x02,0x03, /* [ 6699] OBJ_id_pkinit */ - 0x2B,0x06,0x01,0x05,0x02,0x03,0x04, /* [ 6705] OBJ_pkInitClientAuth */ - 0x2B,0x06,0x01,0x05,0x02,0x03,0x05, /* [ 6712] OBJ_pkInitKDC */ - 0x2B,0x65,0x6E, /* [ 6719] OBJ_X25519 */ - 0x2B,0x65,0x6F, /* [ 6722] OBJ_X448 */ - 0x2B,0x06,0x01,0x04,0x01,0x8D,0x3A,0x0C,0x02,0x01,0x10, /* [ 6725] OBJ_blake2b512 */ - 0x2B,0x06,0x01,0x04,0x01,0x8D,0x3A,0x0C,0x02,0x02,0x08, /* [ 6736] OBJ_blake2s256 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x13, /* [ 6747] OBJ_id_smime_ct_contentCollection */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x17, /* [ 6758] OBJ_id_smime_ct_authEnvelopedData */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1C, /* [ 6769] OBJ_id_ct_xml */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x01, /* [ 6780] OBJ_aria_128_ecb */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x02, /* [ 6789] OBJ_aria_128_cbc */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x03, /* [ 6798] OBJ_aria_128_cfb128 */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x04, /* [ 6807] OBJ_aria_128_ofb128 */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x05, /* [ 6816] OBJ_aria_128_ctr */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x06, /* [ 6825] OBJ_aria_192_ecb */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x07, /* [ 6834] OBJ_aria_192_cbc */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x08, /* [ 6843] OBJ_aria_192_cfb128 */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x09, /* [ 6852] OBJ_aria_192_ofb128 */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x0A, /* [ 6861] OBJ_aria_192_ctr */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x0B, /* [ 6870] OBJ_aria_256_ecb */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x0C, /* [ 6879] OBJ_aria_256_cbc */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x0D, /* [ 6888] OBJ_aria_256_cfb128 */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x0E, /* [ 6897] OBJ_aria_256_ofb128 */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x0F, /* [ 6906] OBJ_aria_256_ctr */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x2F, /* [ 6915] OBJ_id_smime_aa_signingCertificateV2 */ - 0x2B,0x65,0x70, /* [ 6926] OBJ_ED25519 */ - 0x2B,0x65,0x71, /* [ 6929] OBJ_ED448 */ - 0x55,0x04,0x61, /* [ 6932] OBJ_organizationIdentifier */ - 0x55,0x04,0x62, /* [ 6935] OBJ_countryCode3c */ - 0x55,0x04,0x63, /* [ 6938] OBJ_countryCode3n */ - 0x55,0x04,0x64, /* [ 6941] OBJ_dnsName */ - 0x2B,0x24,0x08,0x03,0x03, /* [ 6944] OBJ_x509ExtAdmission */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x05, /* [ 6949] OBJ_sha512_224 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x06, /* [ 6958] OBJ_sha512_256 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x07, /* [ 6967] OBJ_sha3_224 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x08, /* [ 6976] OBJ_sha3_256 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x09, /* [ 6985] OBJ_sha3_384 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x0A, /* [ 6994] OBJ_sha3_512 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x0B, /* [ 7003] OBJ_shake128 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x0C, /* [ 7012] OBJ_shake256 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x0D, /* [ 7021] OBJ_hmac_sha3_224 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x0E, /* [ 7030] OBJ_hmac_sha3_256 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x0F, /* [ 7039] OBJ_hmac_sha3_384 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x10, /* [ 7048] OBJ_hmac_sha3_512 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x03, /* [ 7057] OBJ_dsa_with_SHA384 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x04, /* [ 7066] OBJ_dsa_with_SHA512 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x05, /* [ 7075] OBJ_dsa_with_SHA3_224 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x06, /* [ 7084] OBJ_dsa_with_SHA3_256 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x07, /* [ 7093] OBJ_dsa_with_SHA3_384 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x08, /* [ 7102] OBJ_dsa_with_SHA3_512 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x09, /* [ 7111] OBJ_ecdsa_with_SHA3_224 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x0A, /* [ 7120] OBJ_ecdsa_with_SHA3_256 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x0B, /* [ 7129] OBJ_ecdsa_with_SHA3_384 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x0C, /* [ 7138] OBJ_ecdsa_with_SHA3_512 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x0D, /* [ 7147] OBJ_RSA_SHA3_224 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x0E, /* [ 7156] OBJ_RSA_SHA3_256 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x0F, /* [ 7165] OBJ_RSA_SHA3_384 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x10, /* [ 7174] OBJ_RSA_SHA3_512 */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x25, /* [ 7183] OBJ_aria_128_ccm */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x26, /* [ 7192] OBJ_aria_192_ccm */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x27, /* [ 7201] OBJ_aria_256_ccm */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x22, /* [ 7210] OBJ_aria_128_gcm */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x23, /* [ 7219] OBJ_aria_192_gcm */ - 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x24, /* [ 7228] OBJ_aria_256_gcm */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1B, /* [ 7237] OBJ_cmcCA */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1C, /* [ 7245] OBJ_cmcRA */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x01, /* [ 7253] OBJ_sm4_ecb */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x02, /* [ 7261] OBJ_sm4_cbc */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x03, /* [ 7269] OBJ_sm4_ofb128 */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x05, /* [ 7277] OBJ_sm4_cfb1 */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x04, /* [ 7285] OBJ_sm4_cfb128 */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x06, /* [ 7293] OBJ_sm4_cfb8 */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x07, /* [ 7301] OBJ_sm4_ctr */ - 0x2A,0x81,0x1C, /* [ 7309] OBJ_ISO_CN */ - 0x2A,0x81,0x1C,0xCF,0x55, /* [ 7312] OBJ_oscca */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01, /* [ 7317] OBJ_sm_scheme */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x11, /* [ 7323] OBJ_sm3 */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x78, /* [ 7331] OBJ_sm3WithRSAEncryption */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0F, /* [ 7339] OBJ_sha512_224WithRSAEncryption */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x10, /* [ 7348] OBJ_sha512_256WithRSAEncryption */ - 0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01, /* [ 7357] OBJ_id_tc26_gost_3410_2012_256_constants */ - 0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x01, /* [ 7365] OBJ_id_tc26_gost_3410_2012_256_paramSetA */ - 0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x02,0x03, /* [ 7374] OBJ_id_tc26_gost_3410_2012_512_paramSetC */ - 0x2A,0x86,0x24, /* [ 7383] OBJ_ISO_UA */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01, /* [ 7386] OBJ_ua_pki */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x01,0x01, /* [ 7393] OBJ_dstu28147 */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x02, /* [ 7403] OBJ_dstu28147_ofb */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x03, /* [ 7414] OBJ_dstu28147_cfb */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x05, /* [ 7425] OBJ_dstu28147_wrap */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x01,0x02, /* [ 7436] OBJ_hmacWithDstu34311 */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x02,0x01, /* [ 7446] OBJ_dstu34311 */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x03,0x01,0x01, /* [ 7456] OBJ_dstu4145le */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x03,0x01,0x01,0x01,0x01, /* [ 7467] OBJ_dstu4145be */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x03,0x01,0x01,0x02,0x00, /* [ 7480] OBJ_uacurve0 */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x03,0x01,0x01,0x02,0x01, /* [ 7493] OBJ_uacurve1 */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x03,0x01,0x01,0x02,0x02, /* [ 7506] OBJ_uacurve2 */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x03,0x01,0x01,0x02,0x03, /* [ 7519] OBJ_uacurve3 */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x03,0x01,0x01,0x02,0x04, /* [ 7532] OBJ_uacurve4 */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x03,0x01,0x01,0x02,0x05, /* [ 7545] OBJ_uacurve5 */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x03,0x01,0x01,0x02,0x06, /* [ 7558] OBJ_uacurve6 */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x03,0x01,0x01,0x02,0x07, /* [ 7571] OBJ_uacurve7 */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x03,0x01,0x01,0x02,0x08, /* [ 7584] OBJ_uacurve8 */ - 0x2A,0x86,0x24,0x02,0x01,0x01,0x01,0x01,0x03,0x01,0x01,0x02,0x09, /* [ 7597] OBJ_uacurve9 */ - 0x2B,0x6F, /* [ 7610] OBJ_ieee */ - 0x2B,0x6F,0x02,0x8C,0x53, /* [ 7612] OBJ_ieee_siswg */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x82,0x2D, /* [ 7617] OBJ_sm2 */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x01, /* [ 7625] OBJ_id_tc26_cipher_gostr3412_2015_magma */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x01,0x01, /* [ 7633] OBJ_magma_ctr_acpkm */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x01,0x02, /* [ 7642] OBJ_magma_ctr_acpkm_omac */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x02, /* [ 7651] OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x02,0x01, /* [ 7659] OBJ_kuznyechik_ctr_acpkm */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x05,0x02,0x02, /* [ 7668] OBJ_kuznyechik_ctr_acpkm_omac */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x07, /* [ 7677] OBJ_id_tc26_wrap */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x01, /* [ 7684] OBJ_id_tc26_wrap_gostr3412_2015_magma */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x01,0x01, /* [ 7692] OBJ_magma_kexp15 */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x02, /* [ 7701] OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik */ - 0x2A,0x85,0x03,0x07,0x01,0x01,0x07,0x02,0x01, /* [ 7709] OBJ_kuznyechik_kexp15 */ - 0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x02, /* [ 7718] OBJ_id_tc26_gost_3410_2012_256_paramSetB */ - 0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x03, /* [ 7727] OBJ_id_tc26_gost_3410_2012_256_paramSetC */ - 0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x04, /* [ 7736] OBJ_id_tc26_gost_3410_2012_256_paramSetD */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0C, /* [ 7745] OBJ_hmacWithSHA512_224 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0D, /* [ 7753] OBJ_hmacWithSHA512_256 */ - 0x28,0xCC,0x45,0x03,0x04, /* [ 7761] OBJ_gmac */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x13, /* [ 7766] OBJ_kmac128 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x14, /* [ 7775] OBJ_kmac256 */ - 0x2B,0x06,0x01,0x04,0x01,0x8D,0x3A,0x0C,0x02,0x01, /* [ 7784] OBJ_blake2bmac */ - 0x2B,0x06,0x01,0x04,0x01,0x8D,0x3A,0x0C,0x02,0x02, /* [ 7794] OBJ_blake2smac */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75, /* [ 7804] OBJ_SM2_with_SM3 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x09, /* [ 7812] OBJ_id_on_SmtpUTF8Mailbox */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x05, /* [ 7820] OBJ_XmppAddr */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x07, /* [ 7828] OBJ_SRVName */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x08, /* [ 7836] OBJ_NAIRealm */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1D, /* [ 7844] OBJ_cmcArchive */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1E, /* [ 7852] OBJ_id_kp_bgpsec_router */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x1F, /* [ 7860] OBJ_id_kp_BrandIndicatorforMessageIdentification */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x20, /* [ 7868] OBJ_cmKGA */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x11, /* [ 7876] OBJ_id_it_caCerts */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x12, /* [ 7884] OBJ_id_it_rootCaKeyUpdate */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x13, /* [ 7892] OBJ_id_it_certReqTemplate */ - 0x2A,0x85,0x03,0x64,0x05, /* [ 7900] OBJ_OGRNIP */ - 0x2A,0x85,0x03,0x64,0x71, /* [ 7905] OBJ_classSignTool */ - 0x2A,0x85,0x03,0x64,0x71,0x01, /* [ 7910] OBJ_classSignToolKC1 */ - 0x2A,0x85,0x03,0x64,0x71,0x02, /* [ 7916] OBJ_classSignToolKC2 */ - 0x2A,0x85,0x03,0x64,0x71,0x03, /* [ 7922] OBJ_classSignToolKC3 */ - 0x2A,0x85,0x03,0x64,0x71,0x04, /* [ 7928] OBJ_classSignToolKB1 */ - 0x2A,0x85,0x03,0x64,0x71,0x05, /* [ 7934] OBJ_classSignToolKB2 */ - 0x2A,0x85,0x03,0x64,0x71,0x06, /* [ 7940] OBJ_classSignToolKA1 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x18, /* [ 7946] OBJ_id_ct_routeOriginAuthz */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1A, /* [ 7957] OBJ_id_ct_rpkiManifest */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x23, /* [ 7968] OBJ_id_ct_rpkiGhostbusters */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x24, /* [ 7979] OBJ_id_ct_resourceTaggedAttest */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0E, /* [ 7990] OBJ_id_cp */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x1C, /* [ 7997] OBJ_sbgp_ipAddrBlockv2 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x1D, /* [ 8005] OBJ_sbgp_autonomousSysNumv2 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0E,0x02, /* [ 8013] OBJ_ipAddr_asNumber */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x0E,0x03, /* [ 8021] OBJ_ipAddr_asNumberv2 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x0A, /* [ 8029] OBJ_rpkiManifest */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x0B, /* [ 8037] OBJ_signedObject */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x0D, /* [ 8045] OBJ_rpkiNotify */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x2F, /* [ 8053] OBJ_id_ct_geofeedCSVwithCRLF */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x30, /* [ 8064] OBJ_id_ct_signedChecklist */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x08, /* [ 8075] OBJ_sm4_gcm */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x09, /* [ 8083] OBJ_sm4_ccm */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x31, /* [ 8091] OBJ_id_ct_ASPA */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x32, /* [ 8102] OBJ_id_mod_cmp2000_02 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x63, /* [ 8110] OBJ_id_mod_cmp2021_88 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x64, /* [ 8118] OBJ_id_mod_cmp2021_02 */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x14, /* [ 8126] OBJ_id_it_rootCaCert */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x15, /* [ 8134] OBJ_id_it_certProfile */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x16, /* [ 8142] OBJ_id_it_crlStatusList */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x17, /* [ 8150] OBJ_id_it_crls */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x07, /* [ 8158] OBJ_id_regCtrl_altCertTemplate */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x0B, /* [ 8167] OBJ_id_regCtrl_algId */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x0C, /* [ 8176] OBJ_id_regCtrl_rsaKeyLen */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x2C, /* [ 8185] OBJ_id_aa_ets_attrCertificateRefs */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x2D, /* [ 8196] OBJ_id_aa_ets_attrRevocationRefs */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x34, /* [ 8207] OBJ_id_aa_CMSAlgorithmProtection */ - 0x04, /* [ 8216] OBJ_itu_t_identified_organization */ - 0x04,0x00, /* [ 8217] OBJ_etsi */ - 0x04,0x00,0x8D,0x45, /* [ 8219] OBJ_electronic_signature_standard */ - 0x04,0x00,0x8D,0x45,0x02, /* [ 8223] OBJ_ess_attributes */ - 0x04,0x00,0x8D,0x45,0x02,0x01, /* [ 8228] OBJ_id_aa_ets_mimeType */ - 0x04,0x00,0x8D,0x45,0x02,0x02, /* [ 8234] OBJ_id_aa_ets_longTermValidation */ - 0x04,0x00,0x8D,0x45,0x02,0x03, /* [ 8240] OBJ_id_aa_ets_SignaturePolicyDocument */ - 0x04,0x00,0x8D,0x45,0x02,0x04, /* [ 8246] OBJ_id_aa_ets_archiveTimestampV3 */ - 0x04,0x00,0x8D,0x45,0x02,0x05, /* [ 8252] OBJ_id_aa_ATSHashIndex */ - 0x04,0x00,0x81,0x95,0x32, /* [ 8258] OBJ_cades */ - 0x04,0x00,0x81,0x95,0x32,0x01, /* [ 8263] OBJ_cades_attributes */ - 0x04,0x00,0x81,0x95,0x32,0x01,0x01, /* [ 8269] OBJ_id_aa_ets_signerAttrV2 */ - 0x04,0x00,0x81,0x95,0x32,0x01,0x03, /* [ 8276] OBJ_id_aa_ets_sigPolicyStore */ - 0x04,0x00,0x81,0x95,0x32,0x01,0x04, /* [ 8283] OBJ_id_aa_ATSHashIndex_v2 */ - 0x04,0x00,0x81,0x95,0x32,0x01,0x05, /* [ 8290] OBJ_id_aa_ATSHashIndex_v3 */ - 0x04,0x00,0x81,0x95,0x32,0x01,0x06, /* [ 8297] OBJ_signedAssertion */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x30, /* [ 8304] OBJ_id_aa_ets_archiveTimestampV2 */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x11,0x03,0x01, /* [ 8315] OBJ_hmacWithSM3 */ - 0x60,0x86,0x48,0x01,0x86,0xF9,0x66, /* [ 8325] OBJ_oracle */ - 0x60,0x86,0x48,0x01,0x86,0xF9,0x66,0xAD,0xCA,0x7B,0x01,0x01, /* [ 8332] OBJ_oracle_jdk_trustedkeyusage */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x32, /* [ 8344] OBJ_id_ct_signedTAL */ - 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x68,0x0A, /* [ 8355] OBJ_sm4_xts */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x19,0x02,0x01, /* [ 8363] OBJ_ms_ntds_obj_sid */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x19,0x02, /* [ 8373] OBJ_ms_ntds_sec_ext */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x15,0x07, /* [ 8382] OBJ_ms_cert_templ */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x15,0x0A, /* [ 8391] OBJ_ms_app_policies */ - 0x55,0x1D,0x26, /* [ 8400] OBJ_authority_attribute_identifier */ - 0x55,0x1D,0x27, /* [ 8403] OBJ_role_spec_cert_identifier */ - 0x55,0x1D,0x29, /* [ 8406] OBJ_basic_att_constraints */ - 0x55,0x1D,0x2A, /* [ 8409] OBJ_delegated_name_constraints */ - 0x55,0x1D,0x2B, /* [ 8412] OBJ_time_specification */ - 0x55,0x1D,0x30, /* [ 8415] OBJ_attribute_descriptor */ - 0x55,0x1D,0x31, /* [ 8418] OBJ_user_notice */ - 0x55,0x1D,0x32, /* [ 8421] OBJ_soa_identifier */ - 0x55,0x1D,0x34, /* [ 8424] OBJ_acceptable_cert_policies */ - 0x55,0x1D,0x39, /* [ 8427] OBJ_acceptable_privilege_policies */ - 0x55,0x1D,0x3D, /* [ 8430] OBJ_indirect_issuer */ - 0x55,0x1D,0x3E, /* [ 8433] OBJ_no_assertion */ - 0x55,0x1D,0x3F, /* [ 8436] OBJ_id_aa_issuing_distribution_point */ - 0x55,0x1D,0x40, /* [ 8439] OBJ_issued_on_behalf_of */ - 0x55,0x1D,0x41, /* [ 8442] OBJ_single_use */ - 0x55,0x1D,0x42, /* [ 8445] OBJ_group_ac */ - 0x55,0x1D,0x43, /* [ 8448] OBJ_allowed_attribute_assignments */ - 0x55,0x1D,0x44, /* [ 8451] OBJ_attribute_mappings */ - 0x55,0x1D,0x45, /* [ 8454] OBJ_holder_name_constraints */ - 0x55,0x1D,0x46, /* [ 8457] OBJ_authorization_validation */ - 0x55,0x1D,0x47, /* [ 8460] OBJ_prot_restrict */ - 0x55,0x1D,0x48, /* [ 8463] OBJ_subject_alt_public_key_info */ - 0x55,0x1D,0x49, /* [ 8466] OBJ_alt_signature_algorithm */ - 0x55,0x1D,0x4A, /* [ 8469] OBJ_alt_signature_value */ - 0x55,0x1D,0x4B, /* [ 8472] OBJ_associated_information */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x33, /* [ 8475] OBJ_id_ct_rpkiSignedPrefixList */ - 0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x04, /* [ 8486] OBJ_id_on_hardwareModuleName */ - 0x2B,0x06,0x01,0x04,0x01,0x82,0xE4,0x25,0x01, /* [ 8494] OBJ_id_kp_wisun_fan_device */ - 0x67,0x81,0x05, /* [ 8503] OBJ_tcg */ - 0x67,0x81,0x05,0x01, /* [ 8506] OBJ_tcg_tcpaSpecVersion */ - 0x67,0x81,0x05,0x02, /* [ 8510] OBJ_tcg_attribute */ - 0x67,0x81,0x05,0x03, /* [ 8514] OBJ_tcg_protocol */ - 0x67,0x81,0x05,0x04, /* [ 8518] OBJ_tcg_algorithm */ - 0x67,0x81,0x05,0x05, /* [ 8522] OBJ_tcg_platformClass */ - 0x67,0x81,0x05,0x06, /* [ 8526] OBJ_tcg_ce */ - 0x67,0x81,0x05,0x08, /* [ 8530] OBJ_tcg_kp */ - 0x67,0x81,0x05,0x0B, /* [ 8534] OBJ_tcg_ca */ - 0x67,0x81,0x05,0x11, /* [ 8538] OBJ_tcg_address */ - 0x67,0x81,0x05,0x12, /* [ 8542] OBJ_tcg_registry */ - 0x67,0x81,0x05,0x13, /* [ 8546] OBJ_tcg_traits */ - 0x67,0x81,0x05,0x05,0x01, /* [ 8550] OBJ_tcg_common */ - 0x67,0x81,0x05,0x05,0x01,0x01, /* [ 8555] OBJ_tcg_at_platformManufacturerStr */ - 0x67,0x81,0x05,0x05,0x01,0x02, /* [ 8561] OBJ_tcg_at_platformManufacturerId */ - 0x67,0x81,0x05,0x05,0x01,0x03, /* [ 8567] OBJ_tcg_at_platformConfigUri */ - 0x67,0x81,0x05,0x05,0x01,0x04, /* [ 8573] OBJ_tcg_at_platformModel */ - 0x67,0x81,0x05,0x05,0x01,0x05, /* [ 8579] OBJ_tcg_at_platformVersion */ - 0x67,0x81,0x05,0x05,0x01,0x06, /* [ 8585] OBJ_tcg_at_platformSerial */ - 0x67,0x81,0x05,0x05,0x01,0x07, /* [ 8591] OBJ_tcg_at_platformConfiguration */ - 0x67,0x81,0x05,0x05,0x01,0x08, /* [ 8597] OBJ_tcg_at_platformIdentifier */ - 0x67,0x81,0x05,0x02,0x01, /* [ 8603] OBJ_tcg_at_tpmManufacturer */ - 0x67,0x81,0x05,0x02,0x02, /* [ 8608] OBJ_tcg_at_tpmModel */ - 0x67,0x81,0x05,0x02,0x03, /* [ 8613] OBJ_tcg_at_tpmVersion */ - 0x67,0x81,0x05,0x02,0x0A, /* [ 8618] OBJ_tcg_at_securityQualities */ - 0x67,0x81,0x05,0x02,0x0B, /* [ 8623] OBJ_tcg_at_tpmProtectionProfile */ - 0x67,0x81,0x05,0x02,0x0C, /* [ 8628] OBJ_tcg_at_tpmSecurityTarget */ - 0x67,0x81,0x05,0x02,0x0D, /* [ 8633] OBJ_tcg_at_tbbProtectionProfile */ - 0x67,0x81,0x05,0x02,0x0E, /* [ 8638] OBJ_tcg_at_tbbSecurityTarget */ - 0x67,0x81,0x05,0x02,0x0F, /* [ 8643] OBJ_tcg_at_tpmIdLabel */ - 0x67,0x81,0x05,0x02,0x10, /* [ 8648] OBJ_tcg_at_tpmSpecification */ - 0x67,0x81,0x05,0x02,0x11, /* [ 8653] OBJ_tcg_at_tcgPlatformSpecification */ - 0x67,0x81,0x05,0x02,0x12, /* [ 8658] OBJ_tcg_at_tpmSecurityAssertions */ - 0x67,0x81,0x05,0x02,0x13, /* [ 8663] OBJ_tcg_at_tbbSecurityAssertions */ - 0x67,0x81,0x05,0x02,0x17, /* [ 8668] OBJ_tcg_at_tcgCredentialSpecification */ - 0x67,0x81,0x05,0x02,0x19, /* [ 8673] OBJ_tcg_at_tcgCredentialType */ - 0x67,0x81,0x05,0x02,0x1A, /* [ 8678] OBJ_tcg_at_previousPlatformCertificates */ - 0x67,0x81,0x05,0x02,0x1B, /* [ 8683] OBJ_tcg_at_tbbSecurityAssertions_v3 */ - 0x67,0x81,0x05,0x02,0x1C, /* [ 8688] OBJ_tcg_at_cryptographicAnchors */ - 0x67,0x81,0x05,0x05,0x01,0x07,0x01, /* [ 8693] OBJ_tcg_at_platformConfiguration_v1 */ - 0x67,0x81,0x05,0x05,0x01,0x07,0x02, /* [ 8700] OBJ_tcg_at_platformConfiguration_v2 */ - 0x67,0x81,0x05,0x05,0x01,0x07,0x03, /* [ 8707] OBJ_tcg_at_platformConfiguration_v3 */ - 0x67,0x81,0x05,0x05,0x01,0x07,0x04, /* [ 8714] OBJ_tcg_at_platformConfigUri_v3 */ - 0x67,0x81,0x05,0x04,0x01, /* [ 8721] OBJ_tcg_algorithm_null */ - 0x67,0x81,0x05,0x08,0x01, /* [ 8726] OBJ_tcg_kp_EKCertificate */ - 0x67,0x81,0x05,0x08,0x02, /* [ 8731] OBJ_tcg_kp_PlatformAttributeCertificate */ - 0x67,0x81,0x05,0x08,0x03, /* [ 8736] OBJ_tcg_kp_AIKCertificate */ - 0x67,0x81,0x05,0x08,0x04, /* [ 8741] OBJ_tcg_kp_PlatformKeyCertificate */ - 0x67,0x81,0x05,0x08,0x05, /* [ 8746] OBJ_tcg_kp_DeltaPlatformAttributeCertificate */ - 0x67,0x81,0x05,0x08,0x06, /* [ 8751] OBJ_tcg_kp_DeltaPlatformKeyCertificate */ - 0x67,0x81,0x05,0x08,0x07, /* [ 8756] OBJ_tcg_kp_AdditionalPlatformAttributeCertificate */ - 0x67,0x81,0x05,0x08,0x08, /* [ 8761] OBJ_tcg_kp_AdditionalPlatformKeyCertificate */ - 0x67,0x81,0x05,0x06,0x02, /* [ 8766] OBJ_tcg_ce_relevantCredentials */ - 0x67,0x81,0x05,0x06,0x03, /* [ 8771] OBJ_tcg_ce_relevantManifests */ - 0x67,0x81,0x05,0x06,0x04, /* [ 8776] OBJ_tcg_ce_virtualPlatformAttestationService */ - 0x67,0x81,0x05,0x06,0x05, /* [ 8781] OBJ_tcg_ce_migrationControllerAttestationService */ - 0x67,0x81,0x05,0x06,0x06, /* [ 8786] OBJ_tcg_ce_migrationControllerRegistrationService */ - 0x67,0x81,0x05,0x06,0x07, /* [ 8791] OBJ_tcg_ce_virtualPlatformBackupService */ - 0x67,0x81,0x05,0x03,0x01, /* [ 8796] OBJ_tcg_prt_tpmIdProtocol */ - 0x67,0x81,0x05,0x11,0x01, /* [ 8801] OBJ_tcg_address_ethernetmac */ - 0x67,0x81,0x05,0x11,0x02, /* [ 8806] OBJ_tcg_address_wlanmac */ - 0x67,0x81,0x05,0x11,0x03, /* [ 8811] OBJ_tcg_address_bluetoothmac */ - 0x67,0x81,0x05,0x12,0x03, /* [ 8816] OBJ_tcg_registry_componentClass */ - 0x67,0x81,0x05,0x12,0x03,0x01, /* [ 8821] OBJ_tcg_registry_componentClass_tcg */ - 0x67,0x81,0x05,0x12,0x03,0x02, /* [ 8827] OBJ_tcg_registry_componentClass_ietf */ - 0x67,0x81,0x05,0x12,0x03,0x03, /* [ 8833] OBJ_tcg_registry_componentClass_dmtf */ - 0x67,0x81,0x05,0x12,0x03,0x04, /* [ 8839] OBJ_tcg_registry_componentClass_pcie */ - 0x67,0x81,0x05,0x12,0x03,0x05, /* [ 8845] OBJ_tcg_registry_componentClass_disk */ - 0x67,0x81,0x05,0x0B,0x04, /* [ 8851] OBJ_tcg_cap_verifiedPlatformCertificate */ - 0x67,0x81,0x05,0x13,0x01, /* [ 8856] OBJ_tcg_tr_ID */ - 0x67,0x81,0x05,0x13,0x02, /* [ 8861] OBJ_tcg_tr_category */ - 0x67,0x81,0x05,0x13,0x03, /* [ 8866] OBJ_tcg_tr_registry */ - 0x67,0x81,0x05,0x13,0x01,0x01, /* [ 8871] OBJ_tcg_tr_ID_Boolean */ - 0x67,0x81,0x05,0x13,0x01,0x02, /* [ 8877] OBJ_tcg_tr_ID_CertificateIdentifier */ - 0x67,0x81,0x05,0x13,0x01,0x03, /* [ 8883] OBJ_tcg_tr_ID_CommonCriteria */ - 0x67,0x81,0x05,0x13,0x01,0x04, /* [ 8889] OBJ_tcg_tr_ID_componentClass */ - 0x67,0x81,0x05,0x13,0x01,0x05, /* [ 8895] OBJ_tcg_tr_ID_componentIdentifierV11 */ - 0x67,0x81,0x05,0x13,0x01,0x06, /* [ 8901] OBJ_tcg_tr_ID_FIPSLevel */ - 0x67,0x81,0x05,0x13,0x01,0x07, /* [ 8907] OBJ_tcg_tr_ID_ISO9000Level */ - 0x67,0x81,0x05,0x13,0x01,0x08, /* [ 8913] OBJ_tcg_tr_ID_networkMAC */ - 0x67,0x81,0x05,0x13,0x01,0x09, /* [ 8919] OBJ_tcg_tr_ID_OID */ - 0x67,0x81,0x05,0x13,0x01,0x0A, /* [ 8925] OBJ_tcg_tr_ID_PEN */ - 0x67,0x81,0x05,0x13,0x01,0x0B, /* [ 8931] OBJ_tcg_tr_ID_platformFirmwareCapabilities */ - 0x67,0x81,0x05,0x13,0x01,0x0C, /* [ 8937] OBJ_tcg_tr_ID_platformFirmwareSignatureVerification */ - 0x67,0x81,0x05,0x13,0x01,0x0D, /* [ 8943] OBJ_tcg_tr_ID_platformFirmwareUpdateCompliance */ - 0x67,0x81,0x05,0x13,0x01,0x0E, /* [ 8949] OBJ_tcg_tr_ID_platformHardwareCapabilities */ - 0x67,0x81,0x05,0x13,0x01,0x0F, /* [ 8955] OBJ_tcg_tr_ID_RTM */ - 0x67,0x81,0x05,0x13,0x01,0x10, /* [ 8961] OBJ_tcg_tr_ID_status */ - 0x67,0x81,0x05,0x13,0x01,0x11, /* [ 8967] OBJ_tcg_tr_ID_URI */ - 0x67,0x81,0x05,0x13,0x01,0x12, /* [ 8973] OBJ_tcg_tr_ID_UTF8String */ - 0x67,0x81,0x05,0x13,0x01,0x13, /* [ 8979] OBJ_tcg_tr_ID_IA5String */ - 0x67,0x81,0x05,0x13,0x01,0x14, /* [ 8985] OBJ_tcg_tr_ID_PEMCertString */ - 0x67,0x81,0x05,0x13,0x01,0x15, /* [ 8991] OBJ_tcg_tr_ID_PublicKey */ - 0x67,0x81,0x05,0x13,0x02,0x01, /* [ 8997] OBJ_tcg_tr_cat_platformManufacturer */ - 0x67,0x81,0x05,0x13,0x02,0x02, /* [ 9003] OBJ_tcg_tr_cat_platformModel */ - 0x67,0x81,0x05,0x13,0x02,0x03, /* [ 9009] OBJ_tcg_tr_cat_platformVersion */ - 0x67,0x81,0x05,0x13,0x02,0x04, /* [ 9015] OBJ_tcg_tr_cat_platformSerial */ - 0x67,0x81,0x05,0x13,0x02,0x05, /* [ 9021] OBJ_tcg_tr_cat_platformManufacturerIdentifier */ - 0x67,0x81,0x05,0x13,0x02,0x06, /* [ 9027] OBJ_tcg_tr_cat_platformOwnership */ - 0x67,0x81,0x05,0x13,0x02,0x07, /* [ 9033] OBJ_tcg_tr_cat_componentClass */ - 0x67,0x81,0x05,0x13,0x02,0x08, /* [ 9039] OBJ_tcg_tr_cat_componentManufacturer */ - 0x67,0x81,0x05,0x13,0x02,0x09, /* [ 9045] OBJ_tcg_tr_cat_componentModel */ - 0x67,0x81,0x05,0x13,0x02,0x0A, /* [ 9051] OBJ_tcg_tr_cat_componentSerial */ - 0x67,0x81,0x05,0x13,0x02,0x0B, /* [ 9057] OBJ_tcg_tr_cat_componentStatus */ - 0x67,0x81,0x05,0x13,0x02,0x0C, /* [ 9063] OBJ_tcg_tr_cat_componentLocation */ - 0x67,0x81,0x05,0x13,0x02,0x0D, /* [ 9069] OBJ_tcg_tr_cat_componentRevision */ - 0x67,0x81,0x05,0x13,0x02,0x0E, /* [ 9075] OBJ_tcg_tr_cat_componentFieldReplaceable */ - 0x67,0x81,0x05,0x13,0x02,0x0F, /* [ 9081] OBJ_tcg_tr_cat_EKCertificate */ - 0x67,0x81,0x05,0x13,0x02,0x10, /* [ 9087] OBJ_tcg_tr_cat_IAKCertificate */ - 0x67,0x81,0x05,0x13,0x02,0x11, /* [ 9093] OBJ_tcg_tr_cat_IDevIDCertificate */ - 0x67,0x81,0x05,0x13,0x02,0x12, /* [ 9099] OBJ_tcg_tr_cat_DICECertificate */ - 0x67,0x81,0x05,0x13,0x02,0x13, /* [ 9105] OBJ_tcg_tr_cat_SPDMCertificate */ - 0x67,0x81,0x05,0x13,0x02,0x14, /* [ 9111] OBJ_tcg_tr_cat_PEMCertificate */ - 0x67,0x81,0x05,0x13,0x02,0x15, /* [ 9117] OBJ_tcg_tr_cat_PlatformCertificate */ - 0x67,0x81,0x05,0x13,0x02,0x16, /* [ 9123] OBJ_tcg_tr_cat_DeltaPlatformCertificate */ - 0x67,0x81,0x05,0x13,0x02,0x17, /* [ 9129] OBJ_tcg_tr_cat_RebasePlatformCertificate */ - 0x67,0x81,0x05,0x13,0x02,0x18, /* [ 9135] OBJ_tcg_tr_cat_genericCertificate */ - 0x67,0x81,0x05,0x13,0x02,0x19, /* [ 9141] OBJ_tcg_tr_cat_CommonCriteria */ - 0x67,0x81,0x05,0x13,0x02,0x1A, /* [ 9147] OBJ_tcg_tr_cat_componentIdentifierV11 */ - 0x67,0x81,0x05,0x13,0x02,0x1B, /* [ 9153] OBJ_tcg_tr_cat_FIPSLevel */ - 0x67,0x81,0x05,0x13,0x02,0x1C, /* [ 9159] OBJ_tcg_tr_cat_ISO9000 */ - 0x67,0x81,0x05,0x13,0x02,0x1D, /* [ 9165] OBJ_tcg_tr_cat_networkMAC */ - 0x67,0x81,0x05,0x13,0x02,0x1E, /* [ 9171] OBJ_tcg_tr_cat_attestationProtocol */ - 0x67,0x81,0x05,0x13,0x02,0x1F, /* [ 9177] OBJ_tcg_tr_cat_PEN */ - 0x67,0x81,0x05,0x13,0x02,0x20, /* [ 9183] OBJ_tcg_tr_cat_platformFirmwareCapabilities */ - 0x67,0x81,0x05,0x13,0x02,0x21, /* [ 9189] OBJ_tcg_tr_cat_platformHardwareCapabilities */ - 0x67,0x81,0x05,0x13,0x02,0x22, /* [ 9195] OBJ_tcg_tr_cat_platformFirmwareSignatureVerification */ - 0x67,0x81,0x05,0x13,0x02,0x23, /* [ 9201] OBJ_tcg_tr_cat_platformFirmwareUpdateCompliance */ - 0x67,0x81,0x05,0x13,0x02,0x24, /* [ 9207] OBJ_tcg_tr_cat_RTM */ - 0x67,0x81,0x05,0x13,0x02,0x25, /* [ 9213] OBJ_tcg_tr_cat_PublicKey */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x04,0x01, /* [ 9219] OBJ_ML_KEM_512 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x04,0x02, /* [ 9228] OBJ_ML_KEM_768 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x04,0x03, /* [ 9237] OBJ_ML_KEM_1024 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x11, /* [ 9246] OBJ_ML_DSA_44 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x12, /* [ 9255] OBJ_ML_DSA_65 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x13, /* [ 9264] OBJ_ML_DSA_87 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x14, /* [ 9273] OBJ_SLH_DSA_SHA2_128s */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x15, /* [ 9282] OBJ_SLH_DSA_SHA2_128f */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x16, /* [ 9291] OBJ_SLH_DSA_SHA2_192s */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x17, /* [ 9300] OBJ_SLH_DSA_SHA2_192f */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x18, /* [ 9309] OBJ_SLH_DSA_SHA2_256s */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x19, /* [ 9318] OBJ_SLH_DSA_SHA2_256f */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1A, /* [ 9327] OBJ_SLH_DSA_SHAKE_128s */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1B, /* [ 9336] OBJ_SLH_DSA_SHAKE_128f */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1C, /* [ 9345] OBJ_SLH_DSA_SHAKE_192s */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1D, /* [ 9354] OBJ_SLH_DSA_SHAKE_192f */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1E, /* [ 9363] OBJ_SLH_DSA_SHAKE_256s */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x1F, /* [ 9372] OBJ_SLH_DSA_SHAKE_256f */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x20, /* [ 9381] OBJ_HASH_ML_DSA_44_WITH_SHA512 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x21, /* [ 9390] OBJ_HASH_ML_DSA_65_WITH_SHA512 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x22, /* [ 9399] OBJ_HASH_ML_DSA_87_WITH_SHA512 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x23, /* [ 9408] OBJ_SLH_DSA_SHA2_128s_WITH_SHA256 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x24, /* [ 9417] OBJ_SLH_DSA_SHA2_128f_WITH_SHA256 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x25, /* [ 9426] OBJ_SLH_DSA_SHA2_192s_WITH_SHA512 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x26, /* [ 9435] OBJ_SLH_DSA_SHA2_192f_WITH_SHA512 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x27, /* [ 9444] OBJ_SLH_DSA_SHA2_256s_WITH_SHA512 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x28, /* [ 9453] OBJ_SLH_DSA_SHA2_256f_WITH_SHA512 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x29, /* [ 9462] OBJ_SLH_DSA_SHAKE_128s_WITH_SHAKE128 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x2A, /* [ 9471] OBJ_SLH_DSA_SHAKE_128f_WITH_SHAKE128 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x2B, /* [ 9480] OBJ_SLH_DSA_SHAKE_192s_WITH_SHAKE256 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x2C, /* [ 9489] OBJ_SLH_DSA_SHAKE_192f_WITH_SHAKE256 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x2D, /* [ 9498] OBJ_SLH_DSA_SHAKE_256s_WITH_SHAKE256 */ - 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x2E, /* [ 9507] OBJ_SLH_DSA_SHAKE_256f_WITH_SHAKE256 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x1C, /* [ 9516] OBJ_HKDF_SHA256 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x1D, /* [ 9527] OBJ_HKDF_SHA384 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x1E, /* [ 9538] OBJ_HKDF_SHA512 */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x0D, /* [ 9549] OBJ_id_smime_ori */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x0D,0x03, /* [ 9559] OBJ_id_smime_ori_kem */ - 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x11, /* [ 9570] OBJ_id_alg_hss_lms_hashsig */ -}; - -#define NUM_NID 1502 -static const ASN1_OBJECT nid_objs[NUM_NID] = { - {"UNDEF", "undefined", NID_undef}, - {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, - {"pkcs", "RSA Data Security, Inc. PKCS", NID_pkcs, 7, &so[6]}, - {"MD2", "md2", NID_md2, 8, &so[13]}, - {"MD5", "md5", NID_md5, 8, &so[21]}, - {"RC4", "rc4", NID_rc4, 8, &so[29]}, - {"rsaEncryption", "rsaEncryption", NID_rsaEncryption, 9, &so[37]}, - {"RSA-MD2", "md2WithRSAEncryption", NID_md2WithRSAEncryption, 9, &so[46]}, - {"RSA-MD5", "md5WithRSAEncryption", NID_md5WithRSAEncryption, 9, &so[55]}, - {"PBE-MD2-DES", "pbeWithMD2AndDES-CBC", NID_pbeWithMD2AndDES_CBC, 9, &so[64]}, - {"PBE-MD5-DES", "pbeWithMD5AndDES-CBC", NID_pbeWithMD5AndDES_CBC, 9, &so[73]}, - {"X500", "directory services (X.500)", NID_X500, 1, &so[82]}, - {"X509", "X509", NID_X509, 2, &so[83]}, - {"CN", "commonName", NID_commonName, 3, &so[85]}, - {"C", "countryName", NID_countryName, 3, &so[88]}, - {"L", "localityName", NID_localityName, 3, &so[91]}, - {"ST", "stateOrProvinceName", NID_stateOrProvinceName, 3, &so[94]}, - {"O", "organizationName", NID_organizationName, 3, &so[97]}, - {"OU", "organizationalUnitName", NID_organizationalUnitName, 3, &so[100]}, - {"RSA", "rsa", NID_rsa, 4, &so[103]}, - {"pkcs7", "pkcs7", NID_pkcs7, 8, &so[107]}, - {"pkcs7-data", "pkcs7-data", NID_pkcs7_data, 9, &so[115]}, - {"pkcs7-signedData", "pkcs7-signedData", NID_pkcs7_signed, 9, &so[124]}, - {"pkcs7-envelopedData", "pkcs7-envelopedData", NID_pkcs7_enveloped, 9, &so[133]}, - {"pkcs7-signedAndEnvelopedData", "pkcs7-signedAndEnvelopedData", NID_pkcs7_signedAndEnveloped, 9, &so[142]}, - {"pkcs7-digestData", "pkcs7-digestData", NID_pkcs7_digest, 9, &so[151]}, - {"pkcs7-encryptedData", "pkcs7-encryptedData", NID_pkcs7_encrypted, 9, &so[160]}, - {"pkcs3", "pkcs3", NID_pkcs3, 8, &so[169]}, - {"dhKeyAgreement", "dhKeyAgreement", NID_dhKeyAgreement, 9, &so[177]}, - {"DES-ECB", "des-ecb", NID_des_ecb, 5, &so[186]}, - {"DES-CFB", "des-cfb", NID_des_cfb64, 5, &so[191]}, - {"DES-CBC", "des-cbc", NID_des_cbc, 5, &so[196]}, - {"DES-EDE", "des-ede", NID_des_ede_ecb, 5, &so[201]}, - {"DES-EDE3", "des-ede3", NID_des_ede3_ecb}, - {"IDEA-CBC", "idea-cbc", NID_idea_cbc, 11, &so[206]}, - {"IDEA-CFB", "idea-cfb", NID_idea_cfb64}, - {"IDEA-ECB", "idea-ecb", NID_idea_ecb}, - {"RC2-CBC", "rc2-cbc", NID_rc2_cbc, 8, &so[217]}, - {"RC2-ECB", "rc2-ecb", NID_rc2_ecb}, - {"RC2-CFB", "rc2-cfb", NID_rc2_cfb64}, - {"RC2-OFB", "rc2-ofb", NID_rc2_ofb64}, - {"SHA", "sha", NID_sha, 5, &so[225]}, - {"RSA-SHA", "shaWithRSAEncryption", NID_shaWithRSAEncryption, 5, &so[230]}, - {"DES-EDE-CBC", "des-ede-cbc", NID_des_ede_cbc}, - {"DES-EDE3-CBC", "des-ede3-cbc", NID_des_ede3_cbc, 8, &so[235]}, - {"DES-OFB", "des-ofb", NID_des_ofb64, 5, &so[243]}, - {"IDEA-OFB", "idea-ofb", NID_idea_ofb64}, - {"pkcs9", "pkcs9", NID_pkcs9, 8, &so[248]}, - {"emailAddress", "emailAddress", NID_pkcs9_emailAddress, 9, &so[256]}, - {"unstructuredName", "unstructuredName", NID_pkcs9_unstructuredName, 9, &so[265]}, - {"contentType", "contentType", NID_pkcs9_contentType, 9, &so[274]}, - {"messageDigest", "messageDigest", NID_pkcs9_messageDigest, 9, &so[283]}, - {"signingTime", "signingTime", NID_pkcs9_signingTime, 9, &so[292]}, - {"countersignature", "countersignature", NID_pkcs9_countersignature, 9, &so[301]}, - {"challengePassword", "challengePassword", NID_pkcs9_challengePassword, 9, &so[310]}, - {"unstructuredAddress", "unstructuredAddress", NID_pkcs9_unstructuredAddress, 9, &so[319]}, - {"extendedCertificateAttributes", "extendedCertificateAttributes", NID_pkcs9_extCertAttributes, 9, &so[328]}, - {"Netscape", "Netscape Communications Corp.", NID_netscape, 7, &so[337]}, - {"nsCertExt", "Netscape Certificate Extension", NID_netscape_cert_extension, 8, &so[344]}, - {"nsDataType", "Netscape Data Type", NID_netscape_data_type, 8, &so[352]}, - {"DES-EDE-CFB", "des-ede-cfb", NID_des_ede_cfb64}, - {"DES-EDE3-CFB", "des-ede3-cfb", NID_des_ede3_cfb64}, - {"DES-EDE-OFB", "des-ede-ofb", NID_des_ede_ofb64}, - {"DES-EDE3-OFB", "des-ede3-ofb", NID_des_ede3_ofb64}, - {"SHA1", "sha1", NID_sha1, 5, &so[360]}, - {"RSA-SHA1", "sha1WithRSAEncryption", NID_sha1WithRSAEncryption, 9, &so[365]}, - {"DSA-SHA", "dsaWithSHA", NID_dsaWithSHA, 5, &so[374]}, - {"DSA-old", "dsaEncryption-old", NID_dsa_2, 5, &so[379]}, - {"PBE-SHA1-RC2-64", "pbeWithSHA1AndRC2-CBC", NID_pbeWithSHA1AndRC2_CBC, 9, &so[384]}, - {"PBKDF2", "PBKDF2", NID_id_pbkdf2, 9, &so[393]}, - {"DSA-SHA1-old", "dsaWithSHA1-old", NID_dsaWithSHA1_2, 5, &so[402]}, - {"nsCertType", "Netscape Cert Type", NID_netscape_cert_type, 9, &so[407]}, - {"nsBaseUrl", "Netscape Base Url", NID_netscape_base_url, 9, &so[416]}, - {"nsRevocationUrl", "Netscape Revocation Url", NID_netscape_revocation_url, 9, &so[425]}, - {"nsCaRevocationUrl", "Netscape CA Revocation Url", NID_netscape_ca_revocation_url, 9, &so[434]}, - {"nsRenewalUrl", "Netscape Renewal Url", NID_netscape_renewal_url, 9, &so[443]}, - {"nsCaPolicyUrl", "Netscape CA Policy Url", NID_netscape_ca_policy_url, 9, &so[452]}, - {"nsSslServerName", "Netscape SSL Server Name", NID_netscape_ssl_server_name, 9, &so[461]}, - {"nsComment", "Netscape Comment", NID_netscape_comment, 9, &so[470]}, - {"nsCertSequence", "Netscape Certificate Sequence", NID_netscape_cert_sequence, 9, &so[479]}, - {"DESX-CBC", "desx-cbc", NID_desx_cbc}, - {"id-ce", "id-ce", NID_id_ce, 2, &so[488]}, - {"subjectKeyIdentifier", "X509v3 Subject Key Identifier", NID_subject_key_identifier, 3, &so[490]}, - {"keyUsage", "X509v3 Key Usage", NID_key_usage, 3, &so[493]}, - {"privateKeyUsagePeriod", "X509v3 Private Key Usage Period", NID_private_key_usage_period, 3, &so[496]}, - {"subjectAltName", "X509v3 Subject Alternative Name", NID_subject_alt_name, 3, &so[499]}, - {"issuerAltName", "X509v3 Issuer Alternative Name", NID_issuer_alt_name, 3, &so[502]}, - {"basicConstraints", "X509v3 Basic Constraints", NID_basic_constraints, 3, &so[505]}, - {"crlNumber", "X509v3 CRL Number", NID_crl_number, 3, &so[508]}, - {"certificatePolicies", "X509v3 Certificate Policies", NID_certificate_policies, 3, &so[511]}, - {"authorityKeyIdentifier", "X509v3 Authority Key Identifier", NID_authority_key_identifier, 3, &so[514]}, - {"BF-CBC", "bf-cbc", NID_bf_cbc, 9, &so[517]}, - {"BF-ECB", "bf-ecb", NID_bf_ecb}, - {"BF-CFB", "bf-cfb", NID_bf_cfb64}, - {"BF-OFB", "bf-ofb", NID_bf_ofb64}, - {"MDC2", "mdc2", NID_mdc2, 4, &so[526]}, - {"RSA-MDC2", "mdc2WithRSA", NID_mdc2WithRSA, 4, &so[530]}, - {"RC4-40", "rc4-40", NID_rc4_40}, - {"RC2-40-CBC", "rc2-40-cbc", NID_rc2_40_cbc}, - {"GN", "givenName", NID_givenName, 3, &so[534]}, - {"SN", "surname", NID_surname, 3, &so[537]}, - {"initials", "initials", NID_initials, 3, &so[540]}, - {"uid", "uniqueIdentifier", NID_uniqueIdentifier, 10, &so[543]}, - {"crlDistributionPoints", "X509v3 CRL Distribution Points", NID_crl_distribution_points, 3, &so[553]}, - {"RSA-NP-MD5", "md5WithRSA", NID_md5WithRSA, 5, &so[556]}, - {"serialNumber", "serialNumber", NID_serialNumber, 3, &so[561]}, - {"title", "title", NID_title, 3, &so[564]}, - {"description", "description", NID_description, 3, &so[567]}, - {"CAST5-CBC", "cast5-cbc", NID_cast5_cbc, 9, &so[570]}, - {"CAST5-ECB", "cast5-ecb", NID_cast5_ecb}, - {"CAST5-CFB", "cast5-cfb", NID_cast5_cfb64}, - {"CAST5-OFB", "cast5-ofb", NID_cast5_ofb64}, - {"pbeWithMD5AndCast5CBC", "pbeWithMD5AndCast5CBC", NID_pbeWithMD5AndCast5_CBC, 9, &so[579]}, - {"DSA-SHA1", "dsaWithSHA1", NID_dsaWithSHA1, 7, &so[588]}, - {"MD5-SHA1", "md5-sha1", NID_md5_sha1}, - {"RSA-SHA1-2", "sha1WithRSA", NID_sha1WithRSA, 5, &so[595]}, - {"DSA", "dsaEncryption", NID_dsa, 7, &so[600]}, - {"RIPEMD160", "ripemd160", NID_ripemd160, 5, &so[607]}, - { NULL, NULL, NID_undef }, - {"RSA-RIPEMD160", "ripemd160WithRSA", NID_ripemd160WithRSA, 6, &so[612]}, - {"RC5-CBC", "rc5-cbc", NID_rc5_cbc, 8, &so[618]}, - {"RC5-ECB", "rc5-ecb", NID_rc5_ecb}, - {"RC5-CFB", "rc5-cfb", NID_rc5_cfb64}, - {"RC5-OFB", "rc5-ofb", NID_rc5_ofb64}, - { NULL, NULL, NID_undef }, - {"ZLIB", "zlib compression", NID_zlib_compression, 11, &so[626]}, - {"extendedKeyUsage", "X509v3 Extended Key Usage", NID_ext_key_usage, 3, &so[637]}, - {"PKIX", "PKIX", NID_id_pkix, 6, &so[640]}, - {"id-kp", "id-kp", NID_id_kp, 7, &so[646]}, - {"serverAuth", "TLS Web Server Authentication", NID_server_auth, 8, &so[653]}, - {"clientAuth", "TLS Web Client Authentication", NID_client_auth, 8, &so[661]}, - {"codeSigning", "Code Signing", NID_code_sign, 8, &so[669]}, - {"emailProtection", "E-mail Protection", NID_email_protect, 8, &so[677]}, - {"timeStamping", "Time Stamping", NID_time_stamp, 8, &so[685]}, - {"msCodeInd", "Microsoft Individual Code Signing", NID_ms_code_ind, 10, &so[693]}, - {"msCodeCom", "Microsoft Commercial Code Signing", NID_ms_code_com, 10, &so[703]}, - {"msCTLSign", "Microsoft Trust List Signing", NID_ms_ctl_sign, 10, &so[713]}, - {"msSGC", "Microsoft Server Gated Crypto", NID_ms_sgc, 10, &so[723]}, - {"msEFS", "Microsoft Encrypted File System", NID_ms_efs, 10, &so[733]}, - {"nsSGC", "Netscape Server Gated Crypto", NID_ns_sgc, 9, &so[743]}, - {"deltaCRL", "X509v3 Delta CRL Indicator", NID_delta_crl, 3, &so[752]}, - {"CRLReason", "X509v3 CRL Reason Code", NID_crl_reason, 3, &so[755]}, - {"invalidityDate", "Invalidity Date", NID_invalidity_date, 3, &so[758]}, - {"SXNetID", "Strong Extranet ID", NID_sxnet, 5, &so[761]}, - {"PBE-SHA1-RC4-128", "pbeWithSHA1And128BitRC4", NID_pbe_WithSHA1And128BitRC4, 10, &so[766]}, - {"PBE-SHA1-RC4-40", "pbeWithSHA1And40BitRC4", NID_pbe_WithSHA1And40BitRC4, 10, &so[776]}, - {"PBE-SHA1-3DES", "pbeWithSHA1And3-KeyTripleDES-CBC", NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 10, &so[786]}, - {"PBE-SHA1-2DES", "pbeWithSHA1And2-KeyTripleDES-CBC", NID_pbe_WithSHA1And2_Key_TripleDES_CBC, 10, &so[796]}, - {"PBE-SHA1-RC2-128", "pbeWithSHA1And128BitRC2-CBC", NID_pbe_WithSHA1And128BitRC2_CBC, 10, &so[806]}, - {"PBE-SHA1-RC2-40", "pbeWithSHA1And40BitRC2-CBC", NID_pbe_WithSHA1And40BitRC2_CBC, 10, &so[816]}, - {"keyBag", "keyBag", NID_keyBag, 11, &so[826]}, - {"pkcs8ShroudedKeyBag", "pkcs8ShroudedKeyBag", NID_pkcs8ShroudedKeyBag, 11, &so[837]}, - {"certBag", "certBag", NID_certBag, 11, &so[848]}, - {"crlBag", "crlBag", NID_crlBag, 11, &so[859]}, - {"secretBag", "secretBag", NID_secretBag, 11, &so[870]}, - {"safeContentsBag", "safeContentsBag", NID_safeContentsBag, 11, &so[881]}, - {"friendlyName", "friendlyName", NID_friendlyName, 9, &so[892]}, - {"localKeyID", "localKeyID", NID_localKeyID, 9, &so[901]}, - {"x509Certificate", "x509Certificate", NID_x509Certificate, 10, &so[910]}, - {"sdsiCertificate", "sdsiCertificate", NID_sdsiCertificate, 10, &so[920]}, - {"x509Crl", "x509Crl", NID_x509Crl, 10, &so[930]}, - {"PBES2", "PBES2", NID_pbes2, 9, &so[940]}, - {"PBMAC1", "PBMAC1", NID_pbmac1, 9, &so[949]}, - {"hmacWithSHA1", "hmacWithSHA1", NID_hmacWithSHA1, 8, &so[958]}, - {"id-qt-cps", "Policy Qualifier CPS", NID_id_qt_cps, 8, &so[966]}, - {"id-qt-unotice", "Policy Qualifier User Notice", NID_id_qt_unotice, 8, &so[974]}, - {"RC2-64-CBC", "rc2-64-cbc", NID_rc2_64_cbc}, - {"SMIME-CAPS", "S/MIME Capabilities", NID_SMIMECapabilities, 9, &so[982]}, - {"PBE-MD2-RC2-64", "pbeWithMD2AndRC2-CBC", NID_pbeWithMD2AndRC2_CBC, 9, &so[991]}, - {"PBE-MD5-RC2-64", "pbeWithMD5AndRC2-CBC", NID_pbeWithMD5AndRC2_CBC, 9, &so[1000]}, - {"PBE-SHA1-DES", "pbeWithSHA1AndDES-CBC", NID_pbeWithSHA1AndDES_CBC, 9, &so[1009]}, - {"msExtReq", "Microsoft Extension Request", NID_ms_ext_req, 10, &so[1018]}, - {"extReq", "Extension Request", NID_ext_req, 9, &so[1028]}, - {"name", "name", NID_name, 3, &so[1037]}, - {"dnQualifier", "dnQualifier", NID_dnQualifier, 3, &so[1040]}, - {"id-pe", "id-pe", NID_id_pe, 7, &so[1043]}, - {"id-ad", "id-ad", NID_id_ad, 7, &so[1050]}, - {"authorityInfoAccess", "Authority Information Access", NID_info_access, 8, &so[1057]}, - {"OCSP", "OCSP", NID_ad_OCSP, 8, &so[1065]}, - {"caIssuers", "CA Issuers", NID_ad_ca_issuers, 8, &so[1073]}, - {"OCSPSigning", "OCSP Signing", NID_OCSP_sign, 8, &so[1081]}, - {"ISO", "iso", NID_iso}, - {"member-body", "ISO Member Body", NID_member_body, 1, &so[1089]}, - {"ISO-US", "ISO US Member Body", NID_ISO_US, 3, &so[1090]}, - {"X9-57", "X9.57", NID_X9_57, 5, &so[1093]}, - {"X9cm", "X9.57 CM ?", NID_X9cm, 6, &so[1098]}, - {"pkcs1", "pkcs1", NID_pkcs1, 8, &so[1104]}, - {"pkcs5", "pkcs5", NID_pkcs5, 8, &so[1112]}, - {"SMIME", "S/MIME", NID_SMIME, 9, &so[1120]}, - {"id-smime-mod", "id-smime-mod", NID_id_smime_mod, 10, &so[1129]}, - {"id-smime-ct", "id-smime-ct", NID_id_smime_ct, 10, &so[1139]}, - {"id-smime-aa", "id-smime-aa", NID_id_smime_aa, 10, &so[1149]}, - {"id-smime-alg", "id-smime-alg", NID_id_smime_alg, 10, &so[1159]}, - {"id-smime-cd", "id-smime-cd", NID_id_smime_cd, 10, &so[1169]}, - {"id-smime-spq", "id-smime-spq", NID_id_smime_spq, 10, &so[1179]}, - {"id-smime-cti", "id-smime-cti", NID_id_smime_cti, 10, &so[1189]}, - {"id-smime-mod-cms", "id-smime-mod-cms", NID_id_smime_mod_cms, 11, &so[1199]}, - {"id-smime-mod-ess", "id-smime-mod-ess", NID_id_smime_mod_ess, 11, &so[1210]}, - {"id-smime-mod-oid", "id-smime-mod-oid", NID_id_smime_mod_oid, 11, &so[1221]}, - {"id-smime-mod-msg-v3", "id-smime-mod-msg-v3", NID_id_smime_mod_msg_v3, 11, &so[1232]}, - {"id-smime-mod-ets-eSignature-88", "id-smime-mod-ets-eSignature-88", NID_id_smime_mod_ets_eSignature_88, 11, &so[1243]}, - {"id-smime-mod-ets-eSignature-97", "id-smime-mod-ets-eSignature-97", NID_id_smime_mod_ets_eSignature_97, 11, &so[1254]}, - {"id-smime-mod-ets-eSigPolicy-88", "id-smime-mod-ets-eSigPolicy-88", NID_id_smime_mod_ets_eSigPolicy_88, 11, &so[1265]}, - {"id-smime-mod-ets-eSigPolicy-97", "id-smime-mod-ets-eSigPolicy-97", NID_id_smime_mod_ets_eSigPolicy_97, 11, &so[1276]}, - {"id-smime-ct-receipt", "id-smime-ct-receipt", NID_id_smime_ct_receipt, 11, &so[1287]}, - {"id-smime-ct-authData", "id-smime-ct-authData", NID_id_smime_ct_authData, 11, &so[1298]}, - {"id-smime-ct-publishCert", "id-smime-ct-publishCert", NID_id_smime_ct_publishCert, 11, &so[1309]}, - {"id-smime-ct-TSTInfo", "id-smime-ct-TSTInfo", NID_id_smime_ct_TSTInfo, 11, &so[1320]}, - {"id-smime-ct-TDTInfo", "id-smime-ct-TDTInfo", NID_id_smime_ct_TDTInfo, 11, &so[1331]}, - {"id-smime-ct-contentInfo", "id-smime-ct-contentInfo", NID_id_smime_ct_contentInfo, 11, &so[1342]}, - {"id-smime-ct-DVCSRequestData", "id-smime-ct-DVCSRequestData", NID_id_smime_ct_DVCSRequestData, 11, &so[1353]}, - {"id-smime-ct-DVCSResponseData", "id-smime-ct-DVCSResponseData", NID_id_smime_ct_DVCSResponseData, 11, &so[1364]}, - {"id-smime-aa-receiptRequest", "id-smime-aa-receiptRequest", NID_id_smime_aa_receiptRequest, 11, &so[1375]}, - {"id-smime-aa-securityLabel", "id-smime-aa-securityLabel", NID_id_smime_aa_securityLabel, 11, &so[1386]}, - {"id-smime-aa-mlExpandHistory", "id-smime-aa-mlExpandHistory", NID_id_smime_aa_mlExpandHistory, 11, &so[1397]}, - {"id-smime-aa-contentHint", "id-smime-aa-contentHint", NID_id_smime_aa_contentHint, 11, &so[1408]}, - {"id-smime-aa-msgSigDigest", "id-smime-aa-msgSigDigest", NID_id_smime_aa_msgSigDigest, 11, &so[1419]}, - {"id-smime-aa-encapContentType", "id-smime-aa-encapContentType", NID_id_smime_aa_encapContentType, 11, &so[1430]}, - {"id-smime-aa-contentIdentifier", "id-smime-aa-contentIdentifier", NID_id_smime_aa_contentIdentifier, 11, &so[1441]}, - {"id-smime-aa-macValue", "id-smime-aa-macValue", NID_id_smime_aa_macValue, 11, &so[1452]}, - {"id-smime-aa-equivalentLabels", "id-smime-aa-equivalentLabels", NID_id_smime_aa_equivalentLabels, 11, &so[1463]}, - {"id-smime-aa-contentReference", "id-smime-aa-contentReference", NID_id_smime_aa_contentReference, 11, &so[1474]}, - {"id-smime-aa-encrypKeyPref", "id-smime-aa-encrypKeyPref", NID_id_smime_aa_encrypKeyPref, 11, &so[1485]}, - {"id-smime-aa-signingCertificate", "id-smime-aa-signingCertificate", NID_id_smime_aa_signingCertificate, 11, &so[1496]}, - {"id-smime-aa-smimeEncryptCerts", "id-smime-aa-smimeEncryptCerts", NID_id_smime_aa_smimeEncryptCerts, 11, &so[1507]}, - {"id-smime-aa-timeStampToken", "id-smime-aa-timeStampToken", NID_id_smime_aa_timeStampToken, 11, &so[1518]}, - {"id-smime-aa-ets-sigPolicyId", "id-smime-aa-ets-sigPolicyId", NID_id_smime_aa_ets_sigPolicyId, 11, &so[1529]}, - {"id-smime-aa-ets-commitmentType", "id-smime-aa-ets-commitmentType", NID_id_smime_aa_ets_commitmentType, 11, &so[1540]}, - {"id-smime-aa-ets-signerLocation", "id-smime-aa-ets-signerLocation", NID_id_smime_aa_ets_signerLocation, 11, &so[1551]}, - {"id-smime-aa-ets-signerAttr", "id-smime-aa-ets-signerAttr", NID_id_smime_aa_ets_signerAttr, 11, &so[1562]}, - {"id-smime-aa-ets-otherSigCert", "id-smime-aa-ets-otherSigCert", NID_id_smime_aa_ets_otherSigCert, 11, &so[1573]}, - {"id-smime-aa-ets-contentTimestamp", "id-smime-aa-ets-contentTimestamp", NID_id_smime_aa_ets_contentTimestamp, 11, &so[1584]}, - {"id-smime-aa-ets-CertificateRefs", "id-smime-aa-ets-CertificateRefs", NID_id_smime_aa_ets_CertificateRefs, 11, &so[1595]}, - {"id-smime-aa-ets-RevocationRefs", "id-smime-aa-ets-RevocationRefs", NID_id_smime_aa_ets_RevocationRefs, 11, &so[1606]}, - {"id-smime-aa-ets-certValues", "id-smime-aa-ets-certValues", NID_id_smime_aa_ets_certValues, 11, &so[1617]}, - {"id-smime-aa-ets-revocationValues", "id-smime-aa-ets-revocationValues", NID_id_smime_aa_ets_revocationValues, 11, &so[1628]}, - {"id-smime-aa-ets-escTimeStamp", "id-smime-aa-ets-escTimeStamp", NID_id_smime_aa_ets_escTimeStamp, 11, &so[1639]}, - {"id-smime-aa-ets-certCRLTimestamp", "id-smime-aa-ets-certCRLTimestamp", NID_id_smime_aa_ets_certCRLTimestamp, 11, &so[1650]}, - {"id-smime-aa-ets-archiveTimeStamp", "id-smime-aa-ets-archiveTimeStamp", NID_id_smime_aa_ets_archiveTimeStamp, 11, &so[1661]}, - {"id-smime-aa-signatureType", "id-smime-aa-signatureType", NID_id_smime_aa_signatureType, 11, &so[1672]}, - {"id-smime-aa-dvcs-dvc", "id-smime-aa-dvcs-dvc", NID_id_smime_aa_dvcs_dvc, 11, &so[1683]}, - {"id-smime-alg-ESDHwith3DES", "id-smime-alg-ESDHwith3DES", NID_id_smime_alg_ESDHwith3DES, 11, &so[1694]}, - {"id-smime-alg-ESDHwithRC2", "id-smime-alg-ESDHwithRC2", NID_id_smime_alg_ESDHwithRC2, 11, &so[1705]}, - {"id-smime-alg-3DESwrap", "id-smime-alg-3DESwrap", NID_id_smime_alg_3DESwrap, 11, &so[1716]}, - {"id-smime-alg-RC2wrap", "id-smime-alg-RC2wrap", NID_id_smime_alg_RC2wrap, 11, &so[1727]}, - {"id-smime-alg-ESDH", "id-smime-alg-ESDH", NID_id_smime_alg_ESDH, 11, &so[1738]}, - {"id-smime-alg-CMS3DESwrap", "id-smime-alg-CMS3DESwrap", NID_id_smime_alg_CMS3DESwrap, 11, &so[1749]}, - {"id-smime-alg-CMSRC2wrap", "id-smime-alg-CMSRC2wrap", NID_id_smime_alg_CMSRC2wrap, 11, &so[1760]}, - {"id-smime-cd-ldap", "id-smime-cd-ldap", NID_id_smime_cd_ldap, 11, &so[1771]}, - {"id-smime-spq-ets-sqt-uri", "id-smime-spq-ets-sqt-uri", NID_id_smime_spq_ets_sqt_uri, 11, &so[1782]}, - {"id-smime-spq-ets-sqt-unotice", "id-smime-spq-ets-sqt-unotice", NID_id_smime_spq_ets_sqt_unotice, 11, &so[1793]}, - {"id-smime-cti-ets-proofOfOrigin", "id-smime-cti-ets-proofOfOrigin", NID_id_smime_cti_ets_proofOfOrigin, 11, &so[1804]}, - {"id-smime-cti-ets-proofOfReceipt", "id-smime-cti-ets-proofOfReceipt", NID_id_smime_cti_ets_proofOfReceipt, 11, &so[1815]}, - {"id-smime-cti-ets-proofOfDelivery", "id-smime-cti-ets-proofOfDelivery", NID_id_smime_cti_ets_proofOfDelivery, 11, &so[1826]}, - {"id-smime-cti-ets-proofOfSender", "id-smime-cti-ets-proofOfSender", NID_id_smime_cti_ets_proofOfSender, 11, &so[1837]}, - {"id-smime-cti-ets-proofOfApproval", "id-smime-cti-ets-proofOfApproval", NID_id_smime_cti_ets_proofOfApproval, 11, &so[1848]}, - {"id-smime-cti-ets-proofOfCreation", "id-smime-cti-ets-proofOfCreation", NID_id_smime_cti_ets_proofOfCreation, 11, &so[1859]}, - {"MD4", "md4", NID_md4, 8, &so[1870]}, - {"id-pkix-mod", "id-pkix-mod", NID_id_pkix_mod, 7, &so[1878]}, - {"id-qt", "id-qt", NID_id_qt, 7, &so[1885]}, - {"id-it", "id-it", NID_id_it, 7, &so[1892]}, - {"id-pkip", "id-pkip", NID_id_pkip, 7, &so[1899]}, - {"id-alg", "id-alg", NID_id_alg, 7, &so[1906]}, - {"id-cmc", "id-cmc", NID_id_cmc, 7, &so[1913]}, - {"id-on", "id-on", NID_id_on, 7, &so[1920]}, - {"id-pda", "id-pda", NID_id_pda, 7, &so[1927]}, - {"id-aca", "id-aca", NID_id_aca, 7, &so[1934]}, - {"id-qcs", "id-qcs", NID_id_qcs, 7, &so[1941]}, - {"id-cct", "id-cct", NID_id_cct, 7, &so[1948]}, - {"id-pkix1-explicit-88", "id-pkix1-explicit-88", NID_id_pkix1_explicit_88, 8, &so[1955]}, - {"id-pkix1-implicit-88", "id-pkix1-implicit-88", NID_id_pkix1_implicit_88, 8, &so[1963]}, - {"id-pkix1-explicit-93", "id-pkix1-explicit-93", NID_id_pkix1_explicit_93, 8, &so[1971]}, - {"id-pkix1-implicit-93", "id-pkix1-implicit-93", NID_id_pkix1_implicit_93, 8, &so[1979]}, - {"id-mod-crmf", "id-mod-crmf", NID_id_mod_crmf, 8, &so[1987]}, - {"id-mod-cmc", "id-mod-cmc", NID_id_mod_cmc, 8, &so[1995]}, - {"id-mod-kea-profile-88", "id-mod-kea-profile-88", NID_id_mod_kea_profile_88, 8, &so[2003]}, - {"id-mod-kea-profile-93", "id-mod-kea-profile-93", NID_id_mod_kea_profile_93, 8, &so[2011]}, - {"id-mod-cmp", "id-mod-cmp", NID_id_mod_cmp, 8, &so[2019]}, - {"id-mod-qualified-cert-88", "id-mod-qualified-cert-88", NID_id_mod_qualified_cert_88, 8, &so[2027]}, - {"id-mod-qualified-cert-93", "id-mod-qualified-cert-93", NID_id_mod_qualified_cert_93, 8, &so[2035]}, - {"id-mod-attribute-cert", "id-mod-attribute-cert", NID_id_mod_attribute_cert, 8, &so[2043]}, - {"id-mod-timestamp-protocol", "id-mod-timestamp-protocol", NID_id_mod_timestamp_protocol, 8, &so[2051]}, - {"id-mod-ocsp", "id-mod-ocsp", NID_id_mod_ocsp, 8, &so[2059]}, - {"id-mod-dvcs", "id-mod-dvcs", NID_id_mod_dvcs, 8, &so[2067]}, - {"id-mod-cmp2000", "id-mod-cmp2000", NID_id_mod_cmp2000, 8, &so[2075]}, - {"biometricInfo", "Biometric Info", NID_biometricInfo, 8, &so[2083]}, - {"qcStatements", "qcStatements", NID_qcStatements, 8, &so[2091]}, - {"ac-auditIdentity", "X509v3 Audit Identity", NID_ac_auditIdentity, 8, &so[2099]}, - {"ac-targeting", "ac-targeting", NID_ac_targeting, 8, &so[2107]}, - {"aaControls", "aaControls", NID_aaControls, 8, &so[2115]}, - {"sbgp-ipAddrBlock", "sbgp-ipAddrBlock", NID_sbgp_ipAddrBlock, 8, &so[2123]}, - {"sbgp-autonomousSysNum", "sbgp-autonomousSysNum", NID_sbgp_autonomousSysNum, 8, &so[2131]}, - {"sbgp-routerIdentifier", "sbgp-routerIdentifier", NID_sbgp_routerIdentifier, 8, &so[2139]}, - {"textNotice", "textNotice", NID_textNotice, 8, &so[2147]}, - {"ipsecEndSystem", "IPSec End System", NID_ipsecEndSystem, 8, &so[2155]}, - {"ipsecTunnel", "IPSec Tunnel", NID_ipsecTunnel, 8, &so[2163]}, - {"ipsecUser", "IPSec User", NID_ipsecUser, 8, &so[2171]}, - {"DVCS", "dvcs", NID_dvcs, 8, &so[2179]}, - {"id-it-caProtEncCert", "id-it-caProtEncCert", NID_id_it_caProtEncCert, 8, &so[2187]}, - {"id-it-signKeyPairTypes", "id-it-signKeyPairTypes", NID_id_it_signKeyPairTypes, 8, &so[2195]}, - {"id-it-encKeyPairTypes", "id-it-encKeyPairTypes", NID_id_it_encKeyPairTypes, 8, &so[2203]}, - {"id-it-preferredSymmAlg", "id-it-preferredSymmAlg", NID_id_it_preferredSymmAlg, 8, &so[2211]}, - {"id-it-caKeyUpdateInfo", "id-it-caKeyUpdateInfo", NID_id_it_caKeyUpdateInfo, 8, &so[2219]}, - {"id-it-currentCRL", "id-it-currentCRL", NID_id_it_currentCRL, 8, &so[2227]}, - {"id-it-unsupportedOIDs", "id-it-unsupportedOIDs", NID_id_it_unsupportedOIDs, 8, &so[2235]}, - {"id-it-subscriptionRequest", "id-it-subscriptionRequest", NID_id_it_subscriptionRequest, 8, &so[2243]}, - {"id-it-subscriptionResponse", "id-it-subscriptionResponse", NID_id_it_subscriptionResponse, 8, &so[2251]}, - {"id-it-keyPairParamReq", "id-it-keyPairParamReq", NID_id_it_keyPairParamReq, 8, &so[2259]}, - {"id-it-keyPairParamRep", "id-it-keyPairParamRep", NID_id_it_keyPairParamRep, 8, &so[2267]}, - {"id-it-revPassphrase", "id-it-revPassphrase", NID_id_it_revPassphrase, 8, &so[2275]}, - {"id-it-implicitConfirm", "id-it-implicitConfirm", NID_id_it_implicitConfirm, 8, &so[2283]}, - {"id-it-confirmWaitTime", "id-it-confirmWaitTime", NID_id_it_confirmWaitTime, 8, &so[2291]}, - {"id-it-origPKIMessage", "id-it-origPKIMessage", NID_id_it_origPKIMessage, 8, &so[2299]}, - {"id-regCtrl", "id-regCtrl", NID_id_regCtrl, 8, &so[2307]}, - {"id-regInfo", "id-regInfo", NID_id_regInfo, 8, &so[2315]}, - {"id-regCtrl-regToken", "id-regCtrl-regToken", NID_id_regCtrl_regToken, 9, &so[2323]}, - {"id-regCtrl-authenticator", "id-regCtrl-authenticator", NID_id_regCtrl_authenticator, 9, &so[2332]}, - {"id-regCtrl-pkiPublicationInfo", "id-regCtrl-pkiPublicationInfo", NID_id_regCtrl_pkiPublicationInfo, 9, &so[2341]}, - {"id-regCtrl-pkiArchiveOptions", "id-regCtrl-pkiArchiveOptions", NID_id_regCtrl_pkiArchiveOptions, 9, &so[2350]}, - {"id-regCtrl-oldCertID", "id-regCtrl-oldCertID", NID_id_regCtrl_oldCertID, 9, &so[2359]}, - {"id-regCtrl-protocolEncrKey", "id-regCtrl-protocolEncrKey", NID_id_regCtrl_protocolEncrKey, 9, &so[2368]}, - {"id-regInfo-utf8Pairs", "id-regInfo-utf8Pairs", NID_id_regInfo_utf8Pairs, 9, &so[2377]}, - {"id-regInfo-certReq", "id-regInfo-certReq", NID_id_regInfo_certReq, 9, &so[2386]}, - {"id-alg-des40", "id-alg-des40", NID_id_alg_des40, 8, &so[2395]}, - {"id-alg-noSignature", "id-alg-noSignature", NID_id_alg_noSignature, 8, &so[2403]}, - {"id-alg-dh-sig-hmac-sha1", "id-alg-dh-sig-hmac-sha1", NID_id_alg_dh_sig_hmac_sha1, 8, &so[2411]}, - {"id-alg-dh-pop", "id-alg-dh-pop", NID_id_alg_dh_pop, 8, &so[2419]}, - {"id-cmc-statusInfo", "id-cmc-statusInfo", NID_id_cmc_statusInfo, 8, &so[2427]}, - {"id-cmc-identification", "id-cmc-identification", NID_id_cmc_identification, 8, &so[2435]}, - {"id-cmc-identityProof", "id-cmc-identityProof", NID_id_cmc_identityProof, 8, &so[2443]}, - {"id-cmc-dataReturn", "id-cmc-dataReturn", NID_id_cmc_dataReturn, 8, &so[2451]}, - {"id-cmc-transactionId", "id-cmc-transactionId", NID_id_cmc_transactionId, 8, &so[2459]}, - {"id-cmc-senderNonce", "id-cmc-senderNonce", NID_id_cmc_senderNonce, 8, &so[2467]}, - {"id-cmc-recipientNonce", "id-cmc-recipientNonce", NID_id_cmc_recipientNonce, 8, &so[2475]}, - {"id-cmc-addExtensions", "id-cmc-addExtensions", NID_id_cmc_addExtensions, 8, &so[2483]}, - {"id-cmc-encryptedPOP", "id-cmc-encryptedPOP", NID_id_cmc_encryptedPOP, 8, &so[2491]}, - {"id-cmc-decryptedPOP", "id-cmc-decryptedPOP", NID_id_cmc_decryptedPOP, 8, &so[2499]}, - {"id-cmc-lraPOPWitness", "id-cmc-lraPOPWitness", NID_id_cmc_lraPOPWitness, 8, &so[2507]}, - {"id-cmc-getCert", "id-cmc-getCert", NID_id_cmc_getCert, 8, &so[2515]}, - {"id-cmc-getCRL", "id-cmc-getCRL", NID_id_cmc_getCRL, 8, &so[2523]}, - {"id-cmc-revokeRequest", "id-cmc-revokeRequest", NID_id_cmc_revokeRequest, 8, &so[2531]}, - {"id-cmc-regInfo", "id-cmc-regInfo", NID_id_cmc_regInfo, 8, &so[2539]}, - {"id-cmc-responseInfo", "id-cmc-responseInfo", NID_id_cmc_responseInfo, 8, &so[2547]}, - {"id-cmc-queryPending", "id-cmc-queryPending", NID_id_cmc_queryPending, 8, &so[2555]}, - {"id-cmc-popLinkRandom", "id-cmc-popLinkRandom", NID_id_cmc_popLinkRandom, 8, &so[2563]}, - {"id-cmc-popLinkWitness", "id-cmc-popLinkWitness", NID_id_cmc_popLinkWitness, 8, &so[2571]}, - {"id-cmc-confirmCertAcceptance", "id-cmc-confirmCertAcceptance", NID_id_cmc_confirmCertAcceptance, 8, &so[2579]}, - {"id-on-personalData", "id-on-personalData", NID_id_on_personalData, 8, &so[2587]}, - {"id-pda-dateOfBirth", "id-pda-dateOfBirth", NID_id_pda_dateOfBirth, 8, &so[2595]}, - {"id-pda-placeOfBirth", "id-pda-placeOfBirth", NID_id_pda_placeOfBirth, 8, &so[2603]}, - { NULL, NULL, NID_undef }, - {"id-pda-gender", "id-pda-gender", NID_id_pda_gender, 8, &so[2611]}, - {"id-pda-countryOfCitizenship", "id-pda-countryOfCitizenship", NID_id_pda_countryOfCitizenship, 8, &so[2619]}, - {"id-pda-countryOfResidence", "id-pda-countryOfResidence", NID_id_pda_countryOfResidence, 8, &so[2627]}, - {"id-aca-authenticationInfo", "id-aca-authenticationInfo", NID_id_aca_authenticationInfo, 8, &so[2635]}, - {"id-aca-accessIdentity", "id-aca-accessIdentity", NID_id_aca_accessIdentity, 8, &so[2643]}, - {"id-aca-chargingIdentity", "id-aca-chargingIdentity", NID_id_aca_chargingIdentity, 8, &so[2651]}, - {"id-aca-group", "id-aca-group", NID_id_aca_group, 8, &so[2659]}, - {"id-aca-role", "id-aca-role", NID_id_aca_role, 8, &so[2667]}, - {"id-qcs-pkixQCSyntax-v1", "id-qcs-pkixQCSyntax-v1", NID_id_qcs_pkixQCSyntax_v1, 8, &so[2675]}, - {"id-cct-crs", "id-cct-crs", NID_id_cct_crs, 8, &so[2683]}, - {"id-cct-PKIData", "id-cct-PKIData", NID_id_cct_PKIData, 8, &so[2691]}, - {"id-cct-PKIResponse", "id-cct-PKIResponse", NID_id_cct_PKIResponse, 8, &so[2699]}, - {"ad_timestamping", "AD Time Stamping", NID_ad_timeStamping, 8, &so[2707]}, - {"AD_DVCS", "ad dvcs", NID_ad_dvcs, 8, &so[2715]}, - {"basicOCSPResponse", "Basic OCSP Response", NID_id_pkix_OCSP_basic, 9, &so[2723]}, - {"Nonce", "OCSP Nonce", NID_id_pkix_OCSP_Nonce, 9, &so[2732]}, - {"CrlID", "OCSP CRL ID", NID_id_pkix_OCSP_CrlID, 9, &so[2741]}, - {"acceptableResponses", "Acceptable OCSP Responses", NID_id_pkix_OCSP_acceptableResponses, 9, &so[2750]}, - {"noCheck", "OCSP No Check", NID_id_pkix_OCSP_noCheck, 9, &so[2759]}, - {"archiveCutoff", "OCSP Archive Cutoff", NID_id_pkix_OCSP_archiveCutoff, 9, &so[2768]}, - {"serviceLocator", "OCSP Service Locator", NID_id_pkix_OCSP_serviceLocator, 9, &so[2777]}, - {"extendedStatus", "Extended OCSP Status", NID_id_pkix_OCSP_extendedStatus, 9, &so[2786]}, - {"valid", "valid", NID_id_pkix_OCSP_valid, 9, &so[2795]}, - {"path", "path", NID_id_pkix_OCSP_path, 9, &so[2804]}, - {"trustRoot", "Trust Root", NID_id_pkix_OCSP_trustRoot, 9, &so[2813]}, - {"algorithm", "algorithm", NID_algorithm, 4, &so[2822]}, - {"rsaSignature", "rsaSignature", NID_rsaSignature, 5, &so[2826]}, - {"X500algorithms", "directory services - algorithms", NID_X500algorithms, 2, &so[2831]}, - {"ORG", "org", NID_org, 1, &so[2833]}, - {"DOD", "dod", NID_dod, 2, &so[2834]}, - {"IANA", "iana", NID_iana, 3, &so[2836]}, - {"directory", "Directory", NID_Directory, 4, &so[2839]}, - {"mgmt", "Management", NID_Management, 4, &so[2843]}, - {"experimental", "Experimental", NID_Experimental, 4, &so[2847]}, - {"private", "Private", NID_Private, 4, &so[2851]}, - {"security", "Security", NID_Security, 4, &so[2855]}, - {"snmpv2", "SNMPv2", NID_SNMPv2, 4, &so[2859]}, - {"Mail", "Mail", NID_Mail, 4, &so[2863]}, - {"enterprises", "Enterprises", NID_Enterprises, 5, &so[2867]}, - {"dcobject", "dcObject", NID_dcObject, 9, &so[2872]}, - {"DC", "domainComponent", NID_domainComponent, 10, &so[2881]}, - {"domain", "Domain", NID_Domain, 10, &so[2891]}, - {"NULL", "NULL", NID_joint_iso_ccitt}, - {"selected-attribute-types", "Selected Attribute Types", NID_selected_attribute_types, 3, &so[2901]}, - {"clearance", "clearance", NID_clearance, 4, &so[2904]}, - {"RSA-MD4", "md4WithRSAEncryption", NID_md4WithRSAEncryption, 9, &so[2908]}, - {"ac-proxying", "ac-proxying", NID_ac_proxying, 8, &so[2917]}, - {"subjectInfoAccess", "Subject Information Access", NID_sinfo_access, 8, &so[2925]}, - {"id-aca-encAttrs", "id-aca-encAttrs", NID_id_aca_encAttrs, 8, &so[2933]}, - {"role", "role", NID_role, 3, &so[2941]}, - {"policyConstraints", "X509v3 Policy Constraints", NID_policy_constraints, 3, &so[2944]}, - {"targetInformation", "X509v3 AC Targeting", NID_target_information, 3, &so[2947]}, - {"noRevAvail", "X509v3 No Revocation Available", NID_no_rev_avail, 3, &so[2950]}, - {"NULL", "NULL", NID_ccitt}, - {"ansi-X9-62", "ANSI X9.62", NID_ansi_X9_62, 5, &so[2953]}, - {"prime-field", "prime-field", NID_X9_62_prime_field, 7, &so[2958]}, - {"characteristic-two-field", "characteristic-two-field", NID_X9_62_characteristic_two_field, 7, &so[2965]}, - {"id-ecPublicKey", "id-ecPublicKey", NID_X9_62_id_ecPublicKey, 7, &so[2972]}, - {"prime192v1", "prime192v1", NID_X9_62_prime192v1, 8, &so[2979]}, - {"prime192v2", "prime192v2", NID_X9_62_prime192v2, 8, &so[2987]}, - {"prime192v3", "prime192v3", NID_X9_62_prime192v3, 8, &so[2995]}, - {"prime239v1", "prime239v1", NID_X9_62_prime239v1, 8, &so[3003]}, - {"prime239v2", "prime239v2", NID_X9_62_prime239v2, 8, &so[3011]}, - {"prime239v3", "prime239v3", NID_X9_62_prime239v3, 8, &so[3019]}, - {"prime256v1", "prime256v1", NID_X9_62_prime256v1, 8, &so[3027]}, - {"ecdsa-with-SHA1", "ecdsa-with-SHA1", NID_ecdsa_with_SHA1, 7, &so[3035]}, - {"CSPName", "Microsoft CSP Name", NID_ms_csp_name, 9, &so[3042]}, - {"AES-128-ECB", "aes-128-ecb", NID_aes_128_ecb, 9, &so[3051]}, - {"AES-128-CBC", "aes-128-cbc", NID_aes_128_cbc, 9, &so[3060]}, - {"AES-128-OFB", "aes-128-ofb", NID_aes_128_ofb128, 9, &so[3069]}, - {"AES-128-CFB", "aes-128-cfb", NID_aes_128_cfb128, 9, &so[3078]}, - {"AES-192-ECB", "aes-192-ecb", NID_aes_192_ecb, 9, &so[3087]}, - {"AES-192-CBC", "aes-192-cbc", NID_aes_192_cbc, 9, &so[3096]}, - {"AES-192-OFB", "aes-192-ofb", NID_aes_192_ofb128, 9, &so[3105]}, - {"AES-192-CFB", "aes-192-cfb", NID_aes_192_cfb128, 9, &so[3114]}, - {"AES-256-ECB", "aes-256-ecb", NID_aes_256_ecb, 9, &so[3123]}, - {"AES-256-CBC", "aes-256-cbc", NID_aes_256_cbc, 9, &so[3132]}, - {"AES-256-OFB", "aes-256-ofb", NID_aes_256_ofb128, 9, &so[3141]}, - {"AES-256-CFB", "aes-256-cfb", NID_aes_256_cfb128, 9, &so[3150]}, - {"holdInstructionCode", "Hold Instruction Code", NID_hold_instruction_code, 3, &so[3159]}, - {"holdInstructionNone", "Hold Instruction None", NID_hold_instruction_none, 7, &so[3162]}, - {"holdInstructionCallIssuer", "Hold Instruction Call Issuer", NID_hold_instruction_call_issuer, 7, &so[3169]}, - {"holdInstructionReject", "Hold Instruction Reject", NID_hold_instruction_reject, 7, &so[3176]}, - {"data", "data", NID_data, 1, &so[3183]}, - {"pss", "pss", NID_pss, 3, &so[3184]}, - {"ucl", "ucl", NID_ucl, 7, &so[3187]}, - {"pilot", "pilot", NID_pilot, 8, &so[3194]}, - {"pilotAttributeType", "pilotAttributeType", NID_pilotAttributeType, 9, &so[3202]}, - {"pilotAttributeSyntax", "pilotAttributeSyntax", NID_pilotAttributeSyntax, 9, &so[3211]}, - {"pilotObjectClass", "pilotObjectClass", NID_pilotObjectClass, 9, &so[3220]}, - {"pilotGroups", "pilotGroups", NID_pilotGroups, 9, &so[3229]}, - {"iA5StringSyntax", "iA5StringSyntax", NID_iA5StringSyntax, 10, &so[3238]}, - {"caseIgnoreIA5StringSyntax", "caseIgnoreIA5StringSyntax", NID_caseIgnoreIA5StringSyntax, 10, &so[3248]}, - {"pilotObject", "pilotObject", NID_pilotObject, 10, &so[3258]}, - {"pilotPerson", "pilotPerson", NID_pilotPerson, 10, &so[3268]}, - {"account", "account", NID_account, 10, &so[3278]}, - {"document", "document", NID_document, 10, &so[3288]}, - {"room", "room", NID_room, 10, &so[3298]}, - {"documentSeries", "documentSeries", NID_documentSeries, 10, &so[3308]}, - {"rFC822localPart", "rFC822localPart", NID_rFC822localPart, 10, &so[3318]}, - {"dNSDomain", "dNSDomain", NID_dNSDomain, 10, &so[3328]}, - {"domainRelatedObject", "domainRelatedObject", NID_domainRelatedObject, 10, &so[3338]}, - {"friendlyCountry", "friendlyCountry", NID_friendlyCountry, 10, &so[3348]}, - {"simpleSecurityObject", "simpleSecurityObject", NID_simpleSecurityObject, 10, &so[3358]}, - {"pilotOrganization", "pilotOrganization", NID_pilotOrganization, 10, &so[3368]}, - {"pilotDSA", "pilotDSA", NID_pilotDSA, 10, &so[3378]}, - {"qualityLabelledData", "qualityLabelledData", NID_qualityLabelledData, 10, &so[3388]}, - {"UID", "userId", NID_userId, 10, &so[3398]}, - {"textEncodedORAddress", "textEncodedORAddress", NID_textEncodedORAddress, 10, &so[3408]}, - {"mail", "rfc822Mailbox", NID_rfc822Mailbox, 10, &so[3418]}, - {"info", "info", NID_info, 10, &so[3428]}, - {"favouriteDrink", "favouriteDrink", NID_favouriteDrink, 10, &so[3438]}, - {"roomNumber", "roomNumber", NID_roomNumber, 10, &so[3448]}, - {"photo", "photo", NID_photo, 10, &so[3458]}, - {"userClass", "userClass", NID_userClass, 10, &so[3468]}, - {"host", "host", NID_host, 10, &so[3478]}, - {"manager", "manager", NID_manager, 10, &so[3488]}, - {"documentIdentifier", "documentIdentifier", NID_documentIdentifier, 10, &so[3498]}, - {"documentTitle", "documentTitle", NID_documentTitle, 10, &so[3508]}, - {"documentVersion", "documentVersion", NID_documentVersion, 10, &so[3518]}, - {"documentAuthor", "documentAuthor", NID_documentAuthor, 10, &so[3528]}, - {"documentLocation", "documentLocation", NID_documentLocation, 10, &so[3538]}, - {"homeTelephoneNumber", "homeTelephoneNumber", NID_homeTelephoneNumber, 10, &so[3548]}, - {"secretary", "secretary", NID_secretary, 10, &so[3558]}, - {"otherMailbox", "otherMailbox", NID_otherMailbox, 10, &so[3568]}, - {"lastModifiedTime", "lastModifiedTime", NID_lastModifiedTime, 10, &so[3578]}, - {"lastModifiedBy", "lastModifiedBy", NID_lastModifiedBy, 10, &so[3588]}, - {"aRecord", "aRecord", NID_aRecord, 10, &so[3598]}, - {"pilotAttributeType27", "pilotAttributeType27", NID_pilotAttributeType27, 10, &so[3608]}, - {"mXRecord", "mXRecord", NID_mXRecord, 10, &so[3618]}, - {"nSRecord", "nSRecord", NID_nSRecord, 10, &so[3628]}, - {"sOARecord", "sOARecord", NID_sOARecord, 10, &so[3638]}, - {"cNAMERecord", "cNAMERecord", NID_cNAMERecord, 10, &so[3648]}, - {"associatedDomain", "associatedDomain", NID_associatedDomain, 10, &so[3658]}, - {"associatedName", "associatedName", NID_associatedName, 10, &so[3668]}, - {"homePostalAddress", "homePostalAddress", NID_homePostalAddress, 10, &so[3678]}, - {"personalTitle", "personalTitle", NID_personalTitle, 10, &so[3688]}, - {"mobileTelephoneNumber", "mobileTelephoneNumber", NID_mobileTelephoneNumber, 10, &so[3698]}, - {"pagerTelephoneNumber", "pagerTelephoneNumber", NID_pagerTelephoneNumber, 10, &so[3708]}, - {"friendlyCountryName", "friendlyCountryName", NID_friendlyCountryName, 10, &so[3718]}, - {"organizationalStatus", "organizationalStatus", NID_organizationalStatus, 10, &so[3728]}, - {"janetMailbox", "janetMailbox", NID_janetMailbox, 10, &so[3738]}, - {"mailPreferenceOption", "mailPreferenceOption", NID_mailPreferenceOption, 10, &so[3748]}, - {"buildingName", "buildingName", NID_buildingName, 10, &so[3758]}, - {"dSAQuality", "dSAQuality", NID_dSAQuality, 10, &so[3768]}, - {"singleLevelQuality", "singleLevelQuality", NID_singleLevelQuality, 10, &so[3778]}, - {"subtreeMinimumQuality", "subtreeMinimumQuality", NID_subtreeMinimumQuality, 10, &so[3788]}, - {"subtreeMaximumQuality", "subtreeMaximumQuality", NID_subtreeMaximumQuality, 10, &so[3798]}, - {"personalSignature", "personalSignature", NID_personalSignature, 10, &so[3808]}, - {"dITRedirect", "dITRedirect", NID_dITRedirect, 10, &so[3818]}, - {"audio", "audio", NID_audio, 10, &so[3828]}, - {"documentPublisher", "documentPublisher", NID_documentPublisher, 10, &so[3838]}, - {"x500UniqueIdentifier", "x500UniqueIdentifier", NID_x500UniqueIdentifier, 3, &so[3848]}, - {"mime-mhs", "MIME MHS", NID_mime_mhs, 5, &so[3851]}, - {"mime-mhs-headings", "mime-mhs-headings", NID_mime_mhs_headings, 6, &so[3856]}, - {"mime-mhs-bodies", "mime-mhs-bodies", NID_mime_mhs_bodies, 6, &so[3862]}, - {"id-hex-partial-message", "id-hex-partial-message", NID_id_hex_partial_message, 7, &so[3868]}, - {"id-hex-multipart-message", "id-hex-multipart-message", NID_id_hex_multipart_message, 7, &so[3875]}, - {"generationQualifier", "generationQualifier", NID_generationQualifier, 3, &so[3882]}, - {"pseudonym", "pseudonym", NID_pseudonym, 3, &so[3885]}, - { NULL, NULL, NID_undef }, - {"id-set", "Secure Electronic Transactions", NID_id_set, 2, &so[3888]}, - {"set-ctype", "content types", NID_set_ctype, 3, &so[3890]}, - {"set-msgExt", "message extensions", NID_set_msgExt, 3, &so[3893]}, - {"set-attr", "set-attr", NID_set_attr, 3, &so[3896]}, - {"set-policy", "set-policy", NID_set_policy, 3, &so[3899]}, - {"set-certExt", "certificate extensions", NID_set_certExt, 3, &so[3902]}, - {"set-brand", "set-brand", NID_set_brand, 3, &so[3905]}, - {"setct-PANData", "setct-PANData", NID_setct_PANData, 4, &so[3908]}, - {"setct-PANToken", "setct-PANToken", NID_setct_PANToken, 4, &so[3912]}, - {"setct-PANOnly", "setct-PANOnly", NID_setct_PANOnly, 4, &so[3916]}, - {"setct-OIData", "setct-OIData", NID_setct_OIData, 4, &so[3920]}, - {"setct-PI", "setct-PI", NID_setct_PI, 4, &so[3924]}, - {"setct-PIData", "setct-PIData", NID_setct_PIData, 4, &so[3928]}, - {"setct-PIDataUnsigned", "setct-PIDataUnsigned", NID_setct_PIDataUnsigned, 4, &so[3932]}, - {"setct-HODInput", "setct-HODInput", NID_setct_HODInput, 4, &so[3936]}, - {"setct-AuthResBaggage", "setct-AuthResBaggage", NID_setct_AuthResBaggage, 4, &so[3940]}, - {"setct-AuthRevReqBaggage", "setct-AuthRevReqBaggage", NID_setct_AuthRevReqBaggage, 4, &so[3944]}, - {"setct-AuthRevResBaggage", "setct-AuthRevResBaggage", NID_setct_AuthRevResBaggage, 4, &so[3948]}, - {"setct-CapTokenSeq", "setct-CapTokenSeq", NID_setct_CapTokenSeq, 4, &so[3952]}, - {"setct-PInitResData", "setct-PInitResData", NID_setct_PInitResData, 4, &so[3956]}, - {"setct-PI-TBS", "setct-PI-TBS", NID_setct_PI_TBS, 4, &so[3960]}, - {"setct-PResData", "setct-PResData", NID_setct_PResData, 4, &so[3964]}, - {"setct-AuthReqTBS", "setct-AuthReqTBS", NID_setct_AuthReqTBS, 4, &so[3968]}, - {"setct-AuthResTBS", "setct-AuthResTBS", NID_setct_AuthResTBS, 4, &so[3972]}, - {"setct-AuthResTBSX", "setct-AuthResTBSX", NID_setct_AuthResTBSX, 4, &so[3976]}, - {"setct-AuthTokenTBS", "setct-AuthTokenTBS", NID_setct_AuthTokenTBS, 4, &so[3980]}, - {"setct-CapTokenData", "setct-CapTokenData", NID_setct_CapTokenData, 4, &so[3984]}, - {"setct-CapTokenTBS", "setct-CapTokenTBS", NID_setct_CapTokenTBS, 4, &so[3988]}, - {"setct-AcqCardCodeMsg", "setct-AcqCardCodeMsg", NID_setct_AcqCardCodeMsg, 4, &so[3992]}, - {"setct-AuthRevReqTBS", "setct-AuthRevReqTBS", NID_setct_AuthRevReqTBS, 4, &so[3996]}, - {"setct-AuthRevResData", "setct-AuthRevResData", NID_setct_AuthRevResData, 4, &so[4000]}, - {"setct-AuthRevResTBS", "setct-AuthRevResTBS", NID_setct_AuthRevResTBS, 4, &so[4004]}, - {"setct-CapReqTBS", "setct-CapReqTBS", NID_setct_CapReqTBS, 4, &so[4008]}, - {"setct-CapReqTBSX", "setct-CapReqTBSX", NID_setct_CapReqTBSX, 4, &so[4012]}, - {"setct-CapResData", "setct-CapResData", NID_setct_CapResData, 4, &so[4016]}, - {"setct-CapRevReqTBS", "setct-CapRevReqTBS", NID_setct_CapRevReqTBS, 4, &so[4020]}, - {"setct-CapRevReqTBSX", "setct-CapRevReqTBSX", NID_setct_CapRevReqTBSX, 4, &so[4024]}, - {"setct-CapRevResData", "setct-CapRevResData", NID_setct_CapRevResData, 4, &so[4028]}, - {"setct-CredReqTBS", "setct-CredReqTBS", NID_setct_CredReqTBS, 4, &so[4032]}, - {"setct-CredReqTBSX", "setct-CredReqTBSX", NID_setct_CredReqTBSX, 4, &so[4036]}, - {"setct-CredResData", "setct-CredResData", NID_setct_CredResData, 4, &so[4040]}, - {"setct-CredRevReqTBS", "setct-CredRevReqTBS", NID_setct_CredRevReqTBS, 4, &so[4044]}, - {"setct-CredRevReqTBSX", "setct-CredRevReqTBSX", NID_setct_CredRevReqTBSX, 4, &so[4048]}, - {"setct-CredRevResData", "setct-CredRevResData", NID_setct_CredRevResData, 4, &so[4052]}, - {"setct-PCertReqData", "setct-PCertReqData", NID_setct_PCertReqData, 4, &so[4056]}, - {"setct-PCertResTBS", "setct-PCertResTBS", NID_setct_PCertResTBS, 4, &so[4060]}, - {"setct-BatchAdminReqData", "setct-BatchAdminReqData", NID_setct_BatchAdminReqData, 4, &so[4064]}, - {"setct-BatchAdminResData", "setct-BatchAdminResData", NID_setct_BatchAdminResData, 4, &so[4068]}, - {"setct-CardCInitResTBS", "setct-CardCInitResTBS", NID_setct_CardCInitResTBS, 4, &so[4072]}, - {"setct-MeAqCInitResTBS", "setct-MeAqCInitResTBS", NID_setct_MeAqCInitResTBS, 4, &so[4076]}, - {"setct-RegFormResTBS", "setct-RegFormResTBS", NID_setct_RegFormResTBS, 4, &so[4080]}, - {"setct-CertReqData", "setct-CertReqData", NID_setct_CertReqData, 4, &so[4084]}, - {"setct-CertReqTBS", "setct-CertReqTBS", NID_setct_CertReqTBS, 4, &so[4088]}, - {"setct-CertResData", "setct-CertResData", NID_setct_CertResData, 4, &so[4092]}, - {"setct-CertInqReqTBS", "setct-CertInqReqTBS", NID_setct_CertInqReqTBS, 4, &so[4096]}, - {"setct-ErrorTBS", "setct-ErrorTBS", NID_setct_ErrorTBS, 4, &so[4100]}, - {"setct-PIDualSignedTBE", "setct-PIDualSignedTBE", NID_setct_PIDualSignedTBE, 4, &so[4104]}, - {"setct-PIUnsignedTBE", "setct-PIUnsignedTBE", NID_setct_PIUnsignedTBE, 4, &so[4108]}, - {"setct-AuthReqTBE", "setct-AuthReqTBE", NID_setct_AuthReqTBE, 4, &so[4112]}, - {"setct-AuthResTBE", "setct-AuthResTBE", NID_setct_AuthResTBE, 4, &so[4116]}, - {"setct-AuthResTBEX", "setct-AuthResTBEX", NID_setct_AuthResTBEX, 4, &so[4120]}, - {"setct-AuthTokenTBE", "setct-AuthTokenTBE", NID_setct_AuthTokenTBE, 4, &so[4124]}, - {"setct-CapTokenTBE", "setct-CapTokenTBE", NID_setct_CapTokenTBE, 4, &so[4128]}, - {"setct-CapTokenTBEX", "setct-CapTokenTBEX", NID_setct_CapTokenTBEX, 4, &so[4132]}, - {"setct-AcqCardCodeMsgTBE", "setct-AcqCardCodeMsgTBE", NID_setct_AcqCardCodeMsgTBE, 4, &so[4136]}, - {"setct-AuthRevReqTBE", "setct-AuthRevReqTBE", NID_setct_AuthRevReqTBE, 4, &so[4140]}, - {"setct-AuthRevResTBE", "setct-AuthRevResTBE", NID_setct_AuthRevResTBE, 4, &so[4144]}, - {"setct-AuthRevResTBEB", "setct-AuthRevResTBEB", NID_setct_AuthRevResTBEB, 4, &so[4148]}, - {"setct-CapReqTBE", "setct-CapReqTBE", NID_setct_CapReqTBE, 4, &so[4152]}, - {"setct-CapReqTBEX", "setct-CapReqTBEX", NID_setct_CapReqTBEX, 4, &so[4156]}, - {"setct-CapResTBE", "setct-CapResTBE", NID_setct_CapResTBE, 4, &so[4160]}, - {"setct-CapRevReqTBE", "setct-CapRevReqTBE", NID_setct_CapRevReqTBE, 4, &so[4164]}, - {"setct-CapRevReqTBEX", "setct-CapRevReqTBEX", NID_setct_CapRevReqTBEX, 4, &so[4168]}, - {"setct-CapRevResTBE", "setct-CapRevResTBE", NID_setct_CapRevResTBE, 4, &so[4172]}, - {"setct-CredReqTBE", "setct-CredReqTBE", NID_setct_CredReqTBE, 4, &so[4176]}, - {"setct-CredReqTBEX", "setct-CredReqTBEX", NID_setct_CredReqTBEX, 4, &so[4180]}, - {"setct-CredResTBE", "setct-CredResTBE", NID_setct_CredResTBE, 4, &so[4184]}, - {"setct-CredRevReqTBE", "setct-CredRevReqTBE", NID_setct_CredRevReqTBE, 4, &so[4188]}, - {"setct-CredRevReqTBEX", "setct-CredRevReqTBEX", NID_setct_CredRevReqTBEX, 4, &so[4192]}, - {"setct-CredRevResTBE", "setct-CredRevResTBE", NID_setct_CredRevResTBE, 4, &so[4196]}, - {"setct-BatchAdminReqTBE", "setct-BatchAdminReqTBE", NID_setct_BatchAdminReqTBE, 4, &so[4200]}, - {"setct-BatchAdminResTBE", "setct-BatchAdminResTBE", NID_setct_BatchAdminResTBE, 4, &so[4204]}, - {"setct-RegFormReqTBE", "setct-RegFormReqTBE", NID_setct_RegFormReqTBE, 4, &so[4208]}, - {"setct-CertReqTBE", "setct-CertReqTBE", NID_setct_CertReqTBE, 4, &so[4212]}, - {"setct-CertReqTBEX", "setct-CertReqTBEX", NID_setct_CertReqTBEX, 4, &so[4216]}, - {"setct-CertResTBE", "setct-CertResTBE", NID_setct_CertResTBE, 4, &so[4220]}, - {"setct-CRLNotificationTBS", "setct-CRLNotificationTBS", NID_setct_CRLNotificationTBS, 4, &so[4224]}, - {"setct-CRLNotificationResTBS", "setct-CRLNotificationResTBS", NID_setct_CRLNotificationResTBS, 4, &so[4228]}, - {"setct-BCIDistributionTBS", "setct-BCIDistributionTBS", NID_setct_BCIDistributionTBS, 4, &so[4232]}, - {"setext-genCrypt", "generic cryptogram", NID_setext_genCrypt, 4, &so[4236]}, - {"setext-miAuth", "merchant initiated auth", NID_setext_miAuth, 4, &so[4240]}, - {"setext-pinSecure", "setext-pinSecure", NID_setext_pinSecure, 4, &so[4244]}, - {"setext-pinAny", "setext-pinAny", NID_setext_pinAny, 4, &so[4248]}, - {"setext-track2", "setext-track2", NID_setext_track2, 4, &so[4252]}, - {"setext-cv", "additional verification", NID_setext_cv, 4, &so[4256]}, - {"set-policy-root", "set-policy-root", NID_set_policy_root, 4, &so[4260]}, - {"setCext-hashedRoot", "setCext-hashedRoot", NID_setCext_hashedRoot, 4, &so[4264]}, - {"setCext-certType", "setCext-certType", NID_setCext_certType, 4, &so[4268]}, - {"setCext-merchData", "setCext-merchData", NID_setCext_merchData, 4, &so[4272]}, - {"setCext-cCertRequired", "setCext-cCertRequired", NID_setCext_cCertRequired, 4, &so[4276]}, - {"setCext-tunneling", "setCext-tunneling", NID_setCext_tunneling, 4, &so[4280]}, - {"setCext-setExt", "setCext-setExt", NID_setCext_setExt, 4, &so[4284]}, - {"setCext-setQualf", "setCext-setQualf", NID_setCext_setQualf, 4, &so[4288]}, - {"setCext-PGWYcapabilities", "setCext-PGWYcapabilities", NID_setCext_PGWYcapabilities, 4, &so[4292]}, - {"setCext-TokenIdentifier", "setCext-TokenIdentifier", NID_setCext_TokenIdentifier, 4, &so[4296]}, - {"setCext-Track2Data", "setCext-Track2Data", NID_setCext_Track2Data, 4, &so[4300]}, - {"setCext-TokenType", "setCext-TokenType", NID_setCext_TokenType, 4, &so[4304]}, - {"setCext-IssuerCapabilities", "setCext-IssuerCapabilities", NID_setCext_IssuerCapabilities, 4, &so[4308]}, - {"setAttr-Cert", "setAttr-Cert", NID_setAttr_Cert, 4, &so[4312]}, - {"setAttr-PGWYcap", "payment gateway capabilities", NID_setAttr_PGWYcap, 4, &so[4316]}, - {"setAttr-TokenType", "setAttr-TokenType", NID_setAttr_TokenType, 4, &so[4320]}, - {"setAttr-IssCap", "issuer capabilities", NID_setAttr_IssCap, 4, &so[4324]}, - {"set-rootKeyThumb", "set-rootKeyThumb", NID_set_rootKeyThumb, 5, &so[4328]}, - {"set-addPolicy", "set-addPolicy", NID_set_addPolicy, 5, &so[4333]}, - {"setAttr-Token-EMV", "setAttr-Token-EMV", NID_setAttr_Token_EMV, 5, &so[4338]}, - {"setAttr-Token-B0Prime", "setAttr-Token-B0Prime", NID_setAttr_Token_B0Prime, 5, &so[4343]}, - {"setAttr-IssCap-CVM", "setAttr-IssCap-CVM", NID_setAttr_IssCap_CVM, 5, &so[4348]}, - {"setAttr-IssCap-T2", "setAttr-IssCap-T2", NID_setAttr_IssCap_T2, 5, &so[4353]}, - {"setAttr-IssCap-Sig", "setAttr-IssCap-Sig", NID_setAttr_IssCap_Sig, 5, &so[4358]}, - {"setAttr-GenCryptgrm", "generate cryptogram", NID_setAttr_GenCryptgrm, 6, &so[4363]}, - {"setAttr-T2Enc", "encrypted track 2", NID_setAttr_T2Enc, 6, &so[4369]}, - {"setAttr-T2cleartxt", "cleartext track 2", NID_setAttr_T2cleartxt, 6, &so[4375]}, - {"setAttr-TokICCsig", "ICC or token signature", NID_setAttr_TokICCsig, 6, &so[4381]}, - {"setAttr-SecDevSig", "secure device signature", NID_setAttr_SecDevSig, 6, &so[4387]}, - {"set-brand-IATA-ATA", "set-brand-IATA-ATA", NID_set_brand_IATA_ATA, 4, &so[4393]}, - {"set-brand-Diners", "set-brand-Diners", NID_set_brand_Diners, 4, &so[4397]}, - {"set-brand-AmericanExpress", "set-brand-AmericanExpress", NID_set_brand_AmericanExpress, 4, &so[4401]}, - {"set-brand-JCB", "set-brand-JCB", NID_set_brand_JCB, 4, &so[4405]}, - {"set-brand-Visa", "set-brand-Visa", NID_set_brand_Visa, 4, &so[4409]}, - {"set-brand-MasterCard", "set-brand-MasterCard", NID_set_brand_MasterCard, 4, &so[4413]}, - {"set-brand-Novus", "set-brand-Novus", NID_set_brand_Novus, 5, &so[4417]}, - {"DES-CDMF", "des-cdmf", NID_des_cdmf, 8, &so[4422]}, - {"rsaOAEPEncryptionSET", "rsaOAEPEncryptionSET", NID_rsaOAEPEncryptionSET, 9, &so[4430]}, - {"ITU-T", "itu-t", NID_itu_t}, - {"JOINT-ISO-ITU-T", "joint-iso-itu-t", NID_joint_iso_itu_t}, - {"international-organizations", "International Organizations", NID_international_organizations, 1, &so[4439]}, - {"msSmartcardLogin", "Microsoft Smartcard Login", NID_ms_smartcard_login, 10, &so[4440]}, - {"msUPN", "Microsoft User Principal Name", NID_ms_upn, 10, &so[4450]}, - {"AES-128-CFB1", "aes-128-cfb1", NID_aes_128_cfb1}, - {"AES-192-CFB1", "aes-192-cfb1", NID_aes_192_cfb1}, - {"AES-256-CFB1", "aes-256-cfb1", NID_aes_256_cfb1}, - {"AES-128-CFB8", "aes-128-cfb8", NID_aes_128_cfb8}, - {"AES-192-CFB8", "aes-192-cfb8", NID_aes_192_cfb8}, - {"AES-256-CFB8", "aes-256-cfb8", NID_aes_256_cfb8}, - {"DES-CFB1", "des-cfb1", NID_des_cfb1}, - {"DES-CFB8", "des-cfb8", NID_des_cfb8}, - {"DES-EDE3-CFB1", "des-ede3-cfb1", NID_des_ede3_cfb1}, - {"DES-EDE3-CFB8", "des-ede3-cfb8", NID_des_ede3_cfb8}, - {"street", "streetAddress", NID_streetAddress, 3, &so[4460]}, - {"postalCode", "postalCode", NID_postalCode, 3, &so[4463]}, - {"id-ppl", "id-ppl", NID_id_ppl, 7, &so[4466]}, - {"proxyCertInfo", "Proxy Certificate Information", NID_proxyCertInfo, 8, &so[4473]}, - {"id-ppl-anyLanguage", "Any language", NID_id_ppl_anyLanguage, 8, &so[4481]}, - {"id-ppl-inheritAll", "Inherit all", NID_id_ppl_inheritAll, 8, &so[4489]}, - {"nameConstraints", "X509v3 Name Constraints", NID_name_constraints, 3, &so[4497]}, - {"id-ppl-independent", "Independent", NID_Independent, 8, &so[4500]}, - {"RSA-SHA256", "sha256WithRSAEncryption", NID_sha256WithRSAEncryption, 9, &so[4508]}, - {"RSA-SHA384", "sha384WithRSAEncryption", NID_sha384WithRSAEncryption, 9, &so[4517]}, - {"RSA-SHA512", "sha512WithRSAEncryption", NID_sha512WithRSAEncryption, 9, &so[4526]}, - {"RSA-SHA224", "sha224WithRSAEncryption", NID_sha224WithRSAEncryption, 9, &so[4535]}, - {"SHA256", "sha256", NID_sha256, 9, &so[4544]}, - {"SHA384", "sha384", NID_sha384, 9, &so[4553]}, - {"SHA512", "sha512", NID_sha512, 9, &so[4562]}, - {"SHA224", "sha224", NID_sha224, 9, &so[4571]}, - {"identified-organization", "identified-organization", NID_identified_organization, 1, &so[4580]}, - {"certicom-arc", "certicom-arc", NID_certicom_arc, 3, &so[4581]}, - {"wap", "wap", NID_wap, 2, &so[4584]}, - {"wap-wsg", "wap-wsg", NID_wap_wsg, 3, &so[4586]}, - {"id-characteristic-two-basis", "id-characteristic-two-basis", NID_X9_62_id_characteristic_two_basis, 8, &so[4589]}, - {"onBasis", "onBasis", NID_X9_62_onBasis, 9, &so[4597]}, - {"tpBasis", "tpBasis", NID_X9_62_tpBasis, 9, &so[4606]}, - {"ppBasis", "ppBasis", NID_X9_62_ppBasis, 9, &so[4615]}, - {"c2pnb163v1", "c2pnb163v1", NID_X9_62_c2pnb163v1, 8, &so[4624]}, - {"c2pnb163v2", "c2pnb163v2", NID_X9_62_c2pnb163v2, 8, &so[4632]}, - {"c2pnb163v3", "c2pnb163v3", NID_X9_62_c2pnb163v3, 8, &so[4640]}, - {"c2pnb176v1", "c2pnb176v1", NID_X9_62_c2pnb176v1, 8, &so[4648]}, - {"c2tnb191v1", "c2tnb191v1", NID_X9_62_c2tnb191v1, 8, &so[4656]}, - {"c2tnb191v2", "c2tnb191v2", NID_X9_62_c2tnb191v2, 8, &so[4664]}, - {"c2tnb191v3", "c2tnb191v3", NID_X9_62_c2tnb191v3, 8, &so[4672]}, - {"c2onb191v4", "c2onb191v4", NID_X9_62_c2onb191v4, 8, &so[4680]}, - {"c2onb191v5", "c2onb191v5", NID_X9_62_c2onb191v5, 8, &so[4688]}, - {"c2pnb208w1", "c2pnb208w1", NID_X9_62_c2pnb208w1, 8, &so[4696]}, - {"c2tnb239v1", "c2tnb239v1", NID_X9_62_c2tnb239v1, 8, &so[4704]}, - {"c2tnb239v2", "c2tnb239v2", NID_X9_62_c2tnb239v2, 8, &so[4712]}, - {"c2tnb239v3", "c2tnb239v3", NID_X9_62_c2tnb239v3, 8, &so[4720]}, - {"c2onb239v4", "c2onb239v4", NID_X9_62_c2onb239v4, 8, &so[4728]}, - {"c2onb239v5", "c2onb239v5", NID_X9_62_c2onb239v5, 8, &so[4736]}, - {"c2pnb272w1", "c2pnb272w1", NID_X9_62_c2pnb272w1, 8, &so[4744]}, - {"c2pnb304w1", "c2pnb304w1", NID_X9_62_c2pnb304w1, 8, &so[4752]}, - {"c2tnb359v1", "c2tnb359v1", NID_X9_62_c2tnb359v1, 8, &so[4760]}, - {"c2pnb368w1", "c2pnb368w1", NID_X9_62_c2pnb368w1, 8, &so[4768]}, - {"c2tnb431r1", "c2tnb431r1", NID_X9_62_c2tnb431r1, 8, &so[4776]}, - {"secp112r1", "secp112r1", NID_secp112r1, 5, &so[4784]}, - {"secp112r2", "secp112r2", NID_secp112r2, 5, &so[4789]}, - {"secp128r1", "secp128r1", NID_secp128r1, 5, &so[4794]}, - {"secp128r2", "secp128r2", NID_secp128r2, 5, &so[4799]}, - {"secp160k1", "secp160k1", NID_secp160k1, 5, &so[4804]}, - {"secp160r1", "secp160r1", NID_secp160r1, 5, &so[4809]}, - {"secp160r2", "secp160r2", NID_secp160r2, 5, &so[4814]}, - {"secp192k1", "secp192k1", NID_secp192k1, 5, &so[4819]}, - {"secp224k1", "secp224k1", NID_secp224k1, 5, &so[4824]}, - {"secp224r1", "secp224r1", NID_secp224r1, 5, &so[4829]}, - {"secp256k1", "secp256k1", NID_secp256k1, 5, &so[4834]}, - {"secp384r1", "secp384r1", NID_secp384r1, 5, &so[4839]}, - {"secp521r1", "secp521r1", NID_secp521r1, 5, &so[4844]}, - {"sect113r1", "sect113r1", NID_sect113r1, 5, &so[4849]}, - {"sect113r2", "sect113r2", NID_sect113r2, 5, &so[4854]}, - {"sect131r1", "sect131r1", NID_sect131r1, 5, &so[4859]}, - {"sect131r2", "sect131r2", NID_sect131r2, 5, &so[4864]}, - {"sect163k1", "sect163k1", NID_sect163k1, 5, &so[4869]}, - {"sect163r1", "sect163r1", NID_sect163r1, 5, &so[4874]}, - {"sect163r2", "sect163r2", NID_sect163r2, 5, &so[4879]}, - {"sect193r1", "sect193r1", NID_sect193r1, 5, &so[4884]}, - {"sect193r2", "sect193r2", NID_sect193r2, 5, &so[4889]}, - {"sect233k1", "sect233k1", NID_sect233k1, 5, &so[4894]}, - {"sect233r1", "sect233r1", NID_sect233r1, 5, &so[4899]}, - {"sect239k1", "sect239k1", NID_sect239k1, 5, &so[4904]}, - {"sect283k1", "sect283k1", NID_sect283k1, 5, &so[4909]}, - {"sect283r1", "sect283r1", NID_sect283r1, 5, &so[4914]}, - {"sect409k1", "sect409k1", NID_sect409k1, 5, &so[4919]}, - {"sect409r1", "sect409r1", NID_sect409r1, 5, &so[4924]}, - {"sect571k1", "sect571k1", NID_sect571k1, 5, &so[4929]}, - {"sect571r1", "sect571r1", NID_sect571r1, 5, &so[4934]}, - {"wap-wsg-idm-ecid-wtls1", "wap-wsg-idm-ecid-wtls1", NID_wap_wsg_idm_ecid_wtls1, 5, &so[4939]}, - {"wap-wsg-idm-ecid-wtls3", "wap-wsg-idm-ecid-wtls3", NID_wap_wsg_idm_ecid_wtls3, 5, &so[4944]}, - {"wap-wsg-idm-ecid-wtls4", "wap-wsg-idm-ecid-wtls4", NID_wap_wsg_idm_ecid_wtls4, 5, &so[4949]}, - {"wap-wsg-idm-ecid-wtls5", "wap-wsg-idm-ecid-wtls5", NID_wap_wsg_idm_ecid_wtls5, 5, &so[4954]}, - {"wap-wsg-idm-ecid-wtls6", "wap-wsg-idm-ecid-wtls6", NID_wap_wsg_idm_ecid_wtls6, 5, &so[4959]}, - {"wap-wsg-idm-ecid-wtls7", "wap-wsg-idm-ecid-wtls7", NID_wap_wsg_idm_ecid_wtls7, 5, &so[4964]}, - {"wap-wsg-idm-ecid-wtls8", "wap-wsg-idm-ecid-wtls8", NID_wap_wsg_idm_ecid_wtls8, 5, &so[4969]}, - {"wap-wsg-idm-ecid-wtls9", "wap-wsg-idm-ecid-wtls9", NID_wap_wsg_idm_ecid_wtls9, 5, &so[4974]}, - {"wap-wsg-idm-ecid-wtls10", "wap-wsg-idm-ecid-wtls10", NID_wap_wsg_idm_ecid_wtls10, 5, &so[4979]}, - {"wap-wsg-idm-ecid-wtls11", "wap-wsg-idm-ecid-wtls11", NID_wap_wsg_idm_ecid_wtls11, 5, &so[4984]}, - {"wap-wsg-idm-ecid-wtls12", "wap-wsg-idm-ecid-wtls12", NID_wap_wsg_idm_ecid_wtls12, 5, &so[4989]}, - {"anyPolicy", "X509v3 Any Policy", NID_any_policy, 4, &so[4994]}, - {"policyMappings", "X509v3 Policy Mappings", NID_policy_mappings, 3, &so[4998]}, - {"inhibitAnyPolicy", "X509v3 Inhibit Any Policy", NID_inhibit_any_policy, 3, &so[5001]}, - {"Oakley-EC2N-3", "ipsec3", NID_ipsec3}, - {"Oakley-EC2N-4", "ipsec4", NID_ipsec4}, - {"CAMELLIA-128-CBC", "camellia-128-cbc", NID_camellia_128_cbc, 11, &so[5004]}, - {"CAMELLIA-192-CBC", "camellia-192-cbc", NID_camellia_192_cbc, 11, &so[5015]}, - {"CAMELLIA-256-CBC", "camellia-256-cbc", NID_camellia_256_cbc, 11, &so[5026]}, - {"CAMELLIA-128-ECB", "camellia-128-ecb", NID_camellia_128_ecb, 8, &so[5037]}, - {"CAMELLIA-192-ECB", "camellia-192-ecb", NID_camellia_192_ecb, 8, &so[5045]}, - {"CAMELLIA-256-ECB", "camellia-256-ecb", NID_camellia_256_ecb, 8, &so[5053]}, - {"CAMELLIA-128-CFB", "camellia-128-cfb", NID_camellia_128_cfb128, 8, &so[5061]}, - {"CAMELLIA-192-CFB", "camellia-192-cfb", NID_camellia_192_cfb128, 8, &so[5069]}, - {"CAMELLIA-256-CFB", "camellia-256-cfb", NID_camellia_256_cfb128, 8, &so[5077]}, - {"CAMELLIA-128-CFB1", "camellia-128-cfb1", NID_camellia_128_cfb1}, - {"CAMELLIA-192-CFB1", "camellia-192-cfb1", NID_camellia_192_cfb1}, - {"CAMELLIA-256-CFB1", "camellia-256-cfb1", NID_camellia_256_cfb1}, - {"CAMELLIA-128-CFB8", "camellia-128-cfb8", NID_camellia_128_cfb8}, - {"CAMELLIA-192-CFB8", "camellia-192-cfb8", NID_camellia_192_cfb8}, - {"CAMELLIA-256-CFB8", "camellia-256-cfb8", NID_camellia_256_cfb8}, - {"CAMELLIA-128-OFB", "camellia-128-ofb", NID_camellia_128_ofb128, 8, &so[5085]}, - {"CAMELLIA-192-OFB", "camellia-192-ofb", NID_camellia_192_ofb128, 8, &so[5093]}, - {"CAMELLIA-256-OFB", "camellia-256-ofb", NID_camellia_256_ofb128, 8, &so[5101]}, - {"subjectDirectoryAttributes", "X509v3 Subject Directory Attributes", NID_subject_directory_attributes, 3, &so[5109]}, - {"issuingDistributionPoint", "X509v3 Issuing Distribution Point", NID_issuing_distribution_point, 3, &so[5112]}, - {"certificateIssuer", "X509v3 Certificate Issuer", NID_certificate_issuer, 3, &so[5115]}, - { NULL, NULL, NID_undef }, - {"KISA", "kisa", NID_kisa, 6, &so[5118]}, - { NULL, NULL, NID_undef }, - { NULL, NULL, NID_undef }, - {"SEED-ECB", "seed-ecb", NID_seed_ecb, 8, &so[5124]}, - {"SEED-CBC", "seed-cbc", NID_seed_cbc, 8, &so[5132]}, - {"SEED-OFB", "seed-ofb", NID_seed_ofb128, 8, &so[5140]}, - {"SEED-CFB", "seed-cfb", NID_seed_cfb128, 8, &so[5148]}, - {"HMAC-MD5", "hmac-md5", NID_hmac_md5, 8, &so[5156]}, - {"HMAC-SHA1", "hmac-sha1", NID_hmac_sha1, 8, &so[5164]}, - {"id-PasswordBasedMAC", "password based MAC", NID_id_PasswordBasedMAC, 9, &so[5172]}, - {"id-DHBasedMac", "Diffie-Hellman based MAC", NID_id_DHBasedMac, 9, &so[5181]}, - {"id-it-suppLangTags", "id-it-suppLangTags", NID_id_it_suppLangTags, 8, &so[5190]}, - {"caRepository", "CA Repository", NID_caRepository, 8, &so[5198]}, - {"id-smime-ct-compressedData", "id-smime-ct-compressedData", NID_id_smime_ct_compressedData, 11, &so[5206]}, - {"id-ct-asciiTextWithCRLF", "id-ct-asciiTextWithCRLF", NID_id_ct_asciiTextWithCRLF, 11, &so[5217]}, - {"id-aes128-wrap", "id-aes128-wrap", NID_id_aes128_wrap, 9, &so[5228]}, - {"id-aes192-wrap", "id-aes192-wrap", NID_id_aes192_wrap, 9, &so[5237]}, - {"id-aes256-wrap", "id-aes256-wrap", NID_id_aes256_wrap, 9, &so[5246]}, - {"ecdsa-with-Recommended", "ecdsa-with-Recommended", NID_ecdsa_with_Recommended, 7, &so[5255]}, - {"ecdsa-with-Specified", "ecdsa-with-Specified", NID_ecdsa_with_Specified, 7, &so[5262]}, - {"ecdsa-with-SHA224", "ecdsa-with-SHA224", NID_ecdsa_with_SHA224, 8, &so[5269]}, - {"ecdsa-with-SHA256", "ecdsa-with-SHA256", NID_ecdsa_with_SHA256, 8, &so[5277]}, - {"ecdsa-with-SHA384", "ecdsa-with-SHA384", NID_ecdsa_with_SHA384, 8, &so[5285]}, - {"ecdsa-with-SHA512", "ecdsa-with-SHA512", NID_ecdsa_with_SHA512, 8, &so[5293]}, - {"hmacWithMD5", "hmacWithMD5", NID_hmacWithMD5, 8, &so[5301]}, - {"hmacWithSHA224", "hmacWithSHA224", NID_hmacWithSHA224, 8, &so[5309]}, - {"hmacWithSHA256", "hmacWithSHA256", NID_hmacWithSHA256, 8, &so[5317]}, - {"hmacWithSHA384", "hmacWithSHA384", NID_hmacWithSHA384, 8, &so[5325]}, - {"hmacWithSHA512", "hmacWithSHA512", NID_hmacWithSHA512, 8, &so[5333]}, - {"dsa_with_SHA224", "dsa_with_SHA224", NID_dsa_with_SHA224, 9, &so[5341]}, - {"dsa_with_SHA256", "dsa_with_SHA256", NID_dsa_with_SHA256, 9, &so[5350]}, - {"whirlpool", "whirlpool", NID_whirlpool, 6, &so[5359]}, - {"cryptopro", "cryptopro", NID_cryptopro, 5, &so[5365]}, - {"cryptocom", "cryptocom", NID_cryptocom, 5, &so[5370]}, - {"id-GostR3411-94-with-GostR3410-2001", "GOST R 34.11-94 with GOST R 34.10-2001", NID_id_GostR3411_94_with_GostR3410_2001, 6, &so[5375]}, - {"id-GostR3411-94-with-GostR3410-94", "GOST R 34.11-94 with GOST R 34.10-94", NID_id_GostR3411_94_with_GostR3410_94, 6, &so[5381]}, - {"md_gost94", "GOST R 34.11-94", NID_id_GostR3411_94, 6, &so[5387]}, - {"id-HMACGostR3411-94", "HMAC GOST 34.11-94", NID_id_HMACGostR3411_94, 6, &so[5393]}, - {"gost2001", "GOST R 34.10-2001", NID_id_GostR3410_2001, 6, &so[5399]}, - {"gost94", "GOST R 34.10-94", NID_id_GostR3410_94, 6, &so[5405]}, - {"gost89", "GOST 28147-89", NID_id_Gost28147_89, 6, &so[5411]}, - {"gost89-cnt", "gost89-cnt", NID_gost89_cnt}, - {"gost-mac", "GOST 28147-89 MAC", NID_id_Gost28147_89_MAC, 6, &so[5417]}, - {"prf-gostr3411-94", "GOST R 34.11-94 PRF", NID_id_GostR3411_94_prf, 6, &so[5423]}, - {"id-GostR3410-2001DH", "GOST R 34.10-2001 DH", NID_id_GostR3410_2001DH, 6, &so[5429]}, - {"id-GostR3410-94DH", "GOST R 34.10-94 DH", NID_id_GostR3410_94DH, 6, &so[5435]}, - {"id-Gost28147-89-CryptoPro-KeyMeshing", "id-Gost28147-89-CryptoPro-KeyMeshing", NID_id_Gost28147_89_CryptoPro_KeyMeshing, 7, &so[5441]}, - {"id-Gost28147-89-None-KeyMeshing", "id-Gost28147-89-None-KeyMeshing", NID_id_Gost28147_89_None_KeyMeshing, 7, &so[5448]}, - {"id-GostR3411-94-TestParamSet", "id-GostR3411-94-TestParamSet", NID_id_GostR3411_94_TestParamSet, 7, &so[5455]}, - {"id-GostR3411-94-CryptoProParamSet", "id-GostR3411-94-CryptoProParamSet", NID_id_GostR3411_94_CryptoProParamSet, 7, &so[5462]}, - {"id-Gost28147-89-TestParamSet", "id-Gost28147-89-TestParamSet", NID_id_Gost28147_89_TestParamSet, 7, &so[5469]}, - {"id-Gost28147-89-CryptoPro-A-ParamSet", "id-Gost28147-89-CryptoPro-A-ParamSet", NID_id_Gost28147_89_CryptoPro_A_ParamSet, 7, &so[5476]}, - {"id-Gost28147-89-CryptoPro-B-ParamSet", "id-Gost28147-89-CryptoPro-B-ParamSet", NID_id_Gost28147_89_CryptoPro_B_ParamSet, 7, &so[5483]}, - {"id-Gost28147-89-CryptoPro-C-ParamSet", "id-Gost28147-89-CryptoPro-C-ParamSet", NID_id_Gost28147_89_CryptoPro_C_ParamSet, 7, &so[5490]}, - {"id-Gost28147-89-CryptoPro-D-ParamSet", "id-Gost28147-89-CryptoPro-D-ParamSet", NID_id_Gost28147_89_CryptoPro_D_ParamSet, 7, &so[5497]}, - {"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet, 7, &so[5504]}, - {"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet, 7, &so[5511]}, - {"id-Gost28147-89-CryptoPro-RIC-1-ParamSet", "id-Gost28147-89-CryptoPro-RIC-1-ParamSet", NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet, 7, &so[5518]}, - {"id-GostR3410-94-TestParamSet", "id-GostR3410-94-TestParamSet", NID_id_GostR3410_94_TestParamSet, 7, &so[5525]}, - {"id-GostR3410-94-CryptoPro-A-ParamSet", "id-GostR3410-94-CryptoPro-A-ParamSet", NID_id_GostR3410_94_CryptoPro_A_ParamSet, 7, &so[5532]}, - {"id-GostR3410-94-CryptoPro-B-ParamSet", "id-GostR3410-94-CryptoPro-B-ParamSet", NID_id_GostR3410_94_CryptoPro_B_ParamSet, 7, &so[5539]}, - {"id-GostR3410-94-CryptoPro-C-ParamSet", "id-GostR3410-94-CryptoPro-C-ParamSet", NID_id_GostR3410_94_CryptoPro_C_ParamSet, 7, &so[5546]}, - {"id-GostR3410-94-CryptoPro-D-ParamSet", "id-GostR3410-94-CryptoPro-D-ParamSet", NID_id_GostR3410_94_CryptoPro_D_ParamSet, 7, &so[5553]}, - {"id-GostR3410-94-CryptoPro-XchA-ParamSet", "id-GostR3410-94-CryptoPro-XchA-ParamSet", NID_id_GostR3410_94_CryptoPro_XchA_ParamSet, 7, &so[5560]}, - {"id-GostR3410-94-CryptoPro-XchB-ParamSet", "id-GostR3410-94-CryptoPro-XchB-ParamSet", NID_id_GostR3410_94_CryptoPro_XchB_ParamSet, 7, &so[5567]}, - {"id-GostR3410-94-CryptoPro-XchC-ParamSet", "id-GostR3410-94-CryptoPro-XchC-ParamSet", NID_id_GostR3410_94_CryptoPro_XchC_ParamSet, 7, &so[5574]}, - {"id-GostR3410-2001-TestParamSet", "id-GostR3410-2001-TestParamSet", NID_id_GostR3410_2001_TestParamSet, 7, &so[5581]}, - {"id-GostR3410-2001-CryptoPro-A-ParamSet", "id-GostR3410-2001-CryptoPro-A-ParamSet", NID_id_GostR3410_2001_CryptoPro_A_ParamSet, 7, &so[5588]}, - {"id-GostR3410-2001-CryptoPro-B-ParamSet", "id-GostR3410-2001-CryptoPro-B-ParamSet", NID_id_GostR3410_2001_CryptoPro_B_ParamSet, 7, &so[5595]}, - {"id-GostR3410-2001-CryptoPro-C-ParamSet", "id-GostR3410-2001-CryptoPro-C-ParamSet", NID_id_GostR3410_2001_CryptoPro_C_ParamSet, 7, &so[5602]}, - {"id-GostR3410-2001-CryptoPro-XchA-ParamSet", "id-GostR3410-2001-CryptoPro-XchA-ParamSet", NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet, 7, &so[5609]}, - {"id-GostR3410-2001-CryptoPro-XchB-ParamSet", "id-GostR3410-2001-CryptoPro-XchB-ParamSet", NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet, 7, &so[5616]}, - {"id-GostR3410-94-a", "id-GostR3410-94-a", NID_id_GostR3410_94_a, 7, &so[5623]}, - {"id-GostR3410-94-aBis", "id-GostR3410-94-aBis", NID_id_GostR3410_94_aBis, 7, &so[5630]}, - {"id-GostR3410-94-b", "id-GostR3410-94-b", NID_id_GostR3410_94_b, 7, &so[5637]}, - {"id-GostR3410-94-bBis", "id-GostR3410-94-bBis", NID_id_GostR3410_94_bBis, 7, &so[5644]}, - {"id-Gost28147-89-cc", "GOST 28147-89 Cryptocom ParamSet", NID_id_Gost28147_89_cc, 8, &so[5651]}, - {"gost94cc", "GOST 34.10-94 Cryptocom", NID_id_GostR3410_94_cc, 8, &so[5659]}, - {"gost2001cc", "GOST 34.10-2001 Cryptocom", NID_id_GostR3410_2001_cc, 8, &so[5667]}, - {"id-GostR3411-94-with-GostR3410-94-cc", "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom", NID_id_GostR3411_94_with_GostR3410_94_cc, 8, &so[5675]}, - {"id-GostR3411-94-with-GostR3410-2001-cc", "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom", NID_id_GostR3411_94_with_GostR3410_2001_cc, 8, &so[5683]}, - {"id-GostR3410-2001-ParamSet-cc", "GOST R 3410-2001 Parameter Set Cryptocom", NID_id_GostR3410_2001_ParamSet_cc, 8, &so[5691]}, - {"HMAC", "hmac", NID_hmac}, - {"LocalKeySet", "Microsoft Local Key set", NID_LocalKeySet, 9, &so[5699]}, - {"freshestCRL", "X509v3 Freshest CRL", NID_freshest_crl, 3, &so[5708]}, - {"id-on-permanentIdentifier", "Permanent Identifier", NID_id_on_permanentIdentifier, 8, &so[5711]}, - {"searchGuide", "searchGuide", NID_searchGuide, 3, &so[5719]}, - {"businessCategory", "businessCategory", NID_businessCategory, 3, &so[5722]}, - {"postalAddress", "postalAddress", NID_postalAddress, 3, &so[5725]}, - {"postOfficeBox", "postOfficeBox", NID_postOfficeBox, 3, &so[5728]}, - {"physicalDeliveryOfficeName", "physicalDeliveryOfficeName", NID_physicalDeliveryOfficeName, 3, &so[5731]}, - {"telephoneNumber", "telephoneNumber", NID_telephoneNumber, 3, &so[5734]}, - {"telexNumber", "telexNumber", NID_telexNumber, 3, &so[5737]}, - {"teletexTerminalIdentifier", "teletexTerminalIdentifier", NID_teletexTerminalIdentifier, 3, &so[5740]}, - {"facsimileTelephoneNumber", "facsimileTelephoneNumber", NID_facsimileTelephoneNumber, 3, &so[5743]}, - {"x121Address", "x121Address", NID_x121Address, 3, &so[5746]}, - {"internationaliSDNNumber", "internationaliSDNNumber", NID_internationaliSDNNumber, 3, &so[5749]}, - {"registeredAddress", "registeredAddress", NID_registeredAddress, 3, &so[5752]}, - {"destinationIndicator", "destinationIndicator", NID_destinationIndicator, 3, &so[5755]}, - {"preferredDeliveryMethod", "preferredDeliveryMethod", NID_preferredDeliveryMethod, 3, &so[5758]}, - {"presentationAddress", "presentationAddress", NID_presentationAddress, 3, &so[5761]}, - {"supportedApplicationContext", "supportedApplicationContext", NID_supportedApplicationContext, 3, &so[5764]}, - {"member", "member", NID_member, 3, &so[5767]}, - {"owner", "owner", NID_owner, 3, &so[5770]}, - {"roleOccupant", "roleOccupant", NID_roleOccupant, 3, &so[5773]}, - {"seeAlso", "seeAlso", NID_seeAlso, 3, &so[5776]}, - {"userPassword", "userPassword", NID_userPassword, 3, &so[5779]}, - {"userCertificate", "userCertificate", NID_userCertificate, 3, &so[5782]}, - {"cACertificate", "cACertificate", NID_cACertificate, 3, &so[5785]}, - {"authorityRevocationList", "authorityRevocationList", NID_authorityRevocationList, 3, &so[5788]}, - {"certificateRevocationList", "certificateRevocationList", NID_certificateRevocationList, 3, &so[5791]}, - {"crossCertificatePair", "crossCertificatePair", NID_crossCertificatePair, 3, &so[5794]}, - {"enhancedSearchGuide", "enhancedSearchGuide", NID_enhancedSearchGuide, 3, &so[5797]}, - {"protocolInformation", "protocolInformation", NID_protocolInformation, 3, &so[5800]}, - {"distinguishedName", "distinguishedName", NID_distinguishedName, 3, &so[5803]}, - {"uniqueMember", "uniqueMember", NID_uniqueMember, 3, &so[5806]}, - {"houseIdentifier", "houseIdentifier", NID_houseIdentifier, 3, &so[5809]}, - {"supportedAlgorithms", "supportedAlgorithms", NID_supportedAlgorithms, 3, &so[5812]}, - {"deltaRevocationList", "deltaRevocationList", NID_deltaRevocationList, 3, &so[5815]}, - {"dmdName", "dmdName", NID_dmdName, 3, &so[5818]}, - {"id-alg-PWRI-KEK", "id-alg-PWRI-KEK", NID_id_alg_PWRI_KEK, 11, &so[5821]}, - {"CMAC", "cmac", NID_cmac}, - {"id-aes128-GCM", "aes-128-gcm", NID_aes_128_gcm, 9, &so[5832]}, - {"id-aes128-CCM", "aes-128-ccm", NID_aes_128_ccm, 9, &so[5841]}, - {"id-aes128-wrap-pad", "id-aes128-wrap-pad", NID_id_aes128_wrap_pad, 9, &so[5850]}, - {"id-aes192-GCM", "aes-192-gcm", NID_aes_192_gcm, 9, &so[5859]}, - {"id-aes192-CCM", "aes-192-ccm", NID_aes_192_ccm, 9, &so[5868]}, - {"id-aes192-wrap-pad", "id-aes192-wrap-pad", NID_id_aes192_wrap_pad, 9, &so[5877]}, - {"id-aes256-GCM", "aes-256-gcm", NID_aes_256_gcm, 9, &so[5886]}, - {"id-aes256-CCM", "aes-256-ccm", NID_aes_256_ccm, 9, &so[5895]}, - {"id-aes256-wrap-pad", "id-aes256-wrap-pad", NID_id_aes256_wrap_pad, 9, &so[5904]}, - {"AES-128-CTR", "aes-128-ctr", NID_aes_128_ctr}, - {"AES-192-CTR", "aes-192-ctr", NID_aes_192_ctr}, - {"AES-256-CTR", "aes-256-ctr", NID_aes_256_ctr}, - {"id-camellia128-wrap", "id-camellia128-wrap", NID_id_camellia128_wrap, 11, &so[5913]}, - {"id-camellia192-wrap", "id-camellia192-wrap", NID_id_camellia192_wrap, 11, &so[5924]}, - {"id-camellia256-wrap", "id-camellia256-wrap", NID_id_camellia256_wrap, 11, &so[5935]}, - {"anyExtendedKeyUsage", "Any Extended Key Usage", NID_anyExtendedKeyUsage, 4, &so[5946]}, - {"MGF1", "mgf1", NID_mgf1, 9, &so[5950]}, - {"RSASSA-PSS", "rsassaPss", NID_rsassaPss, 9, &so[5959]}, - {"AES-128-XTS", "aes-128-xts", NID_aes_128_xts, 8, &so[5968]}, - {"AES-256-XTS", "aes-256-xts", NID_aes_256_xts, 8, &so[5976]}, - {"RC4-HMAC-MD5", "rc4-hmac-md5", NID_rc4_hmac_md5}, - {"AES-128-CBC-HMAC-SHA1", "aes-128-cbc-hmac-sha1", NID_aes_128_cbc_hmac_sha1}, - {"AES-192-CBC-HMAC-SHA1", "aes-192-cbc-hmac-sha1", NID_aes_192_cbc_hmac_sha1}, - {"AES-256-CBC-HMAC-SHA1", "aes-256-cbc-hmac-sha1", NID_aes_256_cbc_hmac_sha1}, - {"RSAES-OAEP", "rsaesOaep", NID_rsaesOaep, 9, &so[5984]}, - {"dhpublicnumber", "X9.42 DH", NID_dhpublicnumber, 7, &so[5993]}, - {"brainpoolP160r1", "brainpoolP160r1", NID_brainpoolP160r1, 9, &so[6000]}, - {"brainpoolP160t1", "brainpoolP160t1", NID_brainpoolP160t1, 9, &so[6009]}, - {"brainpoolP192r1", "brainpoolP192r1", NID_brainpoolP192r1, 9, &so[6018]}, - {"brainpoolP192t1", "brainpoolP192t1", NID_brainpoolP192t1, 9, &so[6027]}, - {"brainpoolP224r1", "brainpoolP224r1", NID_brainpoolP224r1, 9, &so[6036]}, - {"brainpoolP224t1", "brainpoolP224t1", NID_brainpoolP224t1, 9, &so[6045]}, - {"brainpoolP256r1", "brainpoolP256r1", NID_brainpoolP256r1, 9, &so[6054]}, - {"brainpoolP256t1", "brainpoolP256t1", NID_brainpoolP256t1, 9, &so[6063]}, - {"brainpoolP320r1", "brainpoolP320r1", NID_brainpoolP320r1, 9, &so[6072]}, - {"brainpoolP320t1", "brainpoolP320t1", NID_brainpoolP320t1, 9, &so[6081]}, - {"brainpoolP384r1", "brainpoolP384r1", NID_brainpoolP384r1, 9, &so[6090]}, - {"brainpoolP384t1", "brainpoolP384t1", NID_brainpoolP384t1, 9, &so[6099]}, - {"brainpoolP512r1", "brainpoolP512r1", NID_brainpoolP512r1, 9, &so[6108]}, - {"brainpoolP512t1", "brainpoolP512t1", NID_brainpoolP512t1, 9, &so[6117]}, - {"PSPECIFIED", "pSpecified", NID_pSpecified, 9, &so[6126]}, - {"dhSinglePass-stdDH-sha1kdf-scheme", "dhSinglePass-stdDH-sha1kdf-scheme", NID_dhSinglePass_stdDH_sha1kdf_scheme, 9, &so[6135]}, - {"dhSinglePass-stdDH-sha224kdf-scheme", "dhSinglePass-stdDH-sha224kdf-scheme", NID_dhSinglePass_stdDH_sha224kdf_scheme, 6, &so[6144]}, - {"dhSinglePass-stdDH-sha256kdf-scheme", "dhSinglePass-stdDH-sha256kdf-scheme", NID_dhSinglePass_stdDH_sha256kdf_scheme, 6, &so[6150]}, - {"dhSinglePass-stdDH-sha384kdf-scheme", "dhSinglePass-stdDH-sha384kdf-scheme", NID_dhSinglePass_stdDH_sha384kdf_scheme, 6, &so[6156]}, - {"dhSinglePass-stdDH-sha512kdf-scheme", "dhSinglePass-stdDH-sha512kdf-scheme", NID_dhSinglePass_stdDH_sha512kdf_scheme, 6, &so[6162]}, - {"dhSinglePass-cofactorDH-sha1kdf-scheme", "dhSinglePass-cofactorDH-sha1kdf-scheme", NID_dhSinglePass_cofactorDH_sha1kdf_scheme, 9, &so[6168]}, - {"dhSinglePass-cofactorDH-sha224kdf-scheme", "dhSinglePass-cofactorDH-sha224kdf-scheme", NID_dhSinglePass_cofactorDH_sha224kdf_scheme, 6, &so[6177]}, - {"dhSinglePass-cofactorDH-sha256kdf-scheme", "dhSinglePass-cofactorDH-sha256kdf-scheme", NID_dhSinglePass_cofactorDH_sha256kdf_scheme, 6, &so[6183]}, - {"dhSinglePass-cofactorDH-sha384kdf-scheme", "dhSinglePass-cofactorDH-sha384kdf-scheme", NID_dhSinglePass_cofactorDH_sha384kdf_scheme, 6, &so[6189]}, - {"dhSinglePass-cofactorDH-sha512kdf-scheme", "dhSinglePass-cofactorDH-sha512kdf-scheme", NID_dhSinglePass_cofactorDH_sha512kdf_scheme, 6, &so[6195]}, - {"dh-std-kdf", "dh-std-kdf", NID_dh_std_kdf}, - {"dh-cofactor-kdf", "dh-cofactor-kdf", NID_dh_cofactor_kdf}, - {"AES-128-CBC-HMAC-SHA256", "aes-128-cbc-hmac-sha256", NID_aes_128_cbc_hmac_sha256}, - {"AES-192-CBC-HMAC-SHA256", "aes-192-cbc-hmac-sha256", NID_aes_192_cbc_hmac_sha256}, - {"AES-256-CBC-HMAC-SHA256", "aes-256-cbc-hmac-sha256", NID_aes_256_cbc_hmac_sha256}, - {"ct_precert_scts", "CT Precertificate SCTs", NID_ct_precert_scts, 10, &so[6201]}, - {"ct_precert_poison", "CT Precertificate Poison", NID_ct_precert_poison, 10, &so[6211]}, - {"ct_precert_signer", "CT Precertificate Signer", NID_ct_precert_signer, 10, &so[6221]}, - {"ct_cert_scts", "CT Certificate SCTs", NID_ct_cert_scts, 10, &so[6231]}, - {"jurisdictionL", "jurisdictionLocalityName", NID_jurisdictionLocalityName, 11, &so[6241]}, - {"jurisdictionST", "jurisdictionStateOrProvinceName", NID_jurisdictionStateOrProvinceName, 11, &so[6252]}, - {"jurisdictionC", "jurisdictionCountryName", NID_jurisdictionCountryName, 11, &so[6263]}, - {"AES-128-OCB", "aes-128-ocb", NID_aes_128_ocb}, - {"AES-192-OCB", "aes-192-ocb", NID_aes_192_ocb}, - {"AES-256-OCB", "aes-256-ocb", NID_aes_256_ocb}, - {"CAMELLIA-128-GCM", "camellia-128-gcm", NID_camellia_128_gcm, 8, &so[6274]}, - {"CAMELLIA-128-CCM", "camellia-128-ccm", NID_camellia_128_ccm, 8, &so[6282]}, - {"CAMELLIA-128-CTR", "camellia-128-ctr", NID_camellia_128_ctr, 8, &so[6290]}, - {"CAMELLIA-128-CMAC", "camellia-128-cmac", NID_camellia_128_cmac, 8, &so[6298]}, - {"CAMELLIA-192-GCM", "camellia-192-gcm", NID_camellia_192_gcm, 8, &so[6306]}, - {"CAMELLIA-192-CCM", "camellia-192-ccm", NID_camellia_192_ccm, 8, &so[6314]}, - {"CAMELLIA-192-CTR", "camellia-192-ctr", NID_camellia_192_ctr, 8, &so[6322]}, - {"CAMELLIA-192-CMAC", "camellia-192-cmac", NID_camellia_192_cmac, 8, &so[6330]}, - {"CAMELLIA-256-GCM", "camellia-256-gcm", NID_camellia_256_gcm, 8, &so[6338]}, - {"CAMELLIA-256-CCM", "camellia-256-ccm", NID_camellia_256_ccm, 8, &so[6346]}, - {"CAMELLIA-256-CTR", "camellia-256-ctr", NID_camellia_256_ctr, 8, &so[6354]}, - {"CAMELLIA-256-CMAC", "camellia-256-cmac", NID_camellia_256_cmac, 8, &so[6362]}, - {"id-scrypt", "scrypt", NID_id_scrypt, 9, &so[6370]}, - {"id-tc26", "id-tc26", NID_id_tc26, 5, &so[6379]}, - {"gost89-cnt-12", "gost89-cnt-12", NID_gost89_cnt_12}, - {"gost-mac-12", "gost-mac-12", NID_gost_mac_12}, - {"id-tc26-algorithms", "id-tc26-algorithms", NID_id_tc26_algorithms, 6, &so[6384]}, - {"id-tc26-sign", "id-tc26-sign", NID_id_tc26_sign, 7, &so[6390]}, - {"gost2012_256", "GOST R 34.10-2012 with 256 bit modulus", NID_id_GostR3410_2012_256, 8, &so[6397]}, - {"gost2012_512", "GOST R 34.10-2012 with 512 bit modulus", NID_id_GostR3410_2012_512, 8, &so[6405]}, - {"id-tc26-digest", "id-tc26-digest", NID_id_tc26_digest, 7, &so[6413]}, - {"md_gost12_256", "GOST R 34.11-2012 with 256 bit hash", NID_id_GostR3411_2012_256, 8, &so[6420]}, - {"md_gost12_512", "GOST R 34.11-2012 with 512 bit hash", NID_id_GostR3411_2012_512, 8, &so[6428]}, - {"id-tc26-signwithdigest", "id-tc26-signwithdigest", NID_id_tc26_signwithdigest, 7, &so[6436]}, - {"id-tc26-signwithdigest-gost3410-2012-256", "GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)", NID_id_tc26_signwithdigest_gost3410_2012_256, 8, &so[6443]}, - {"id-tc26-signwithdigest-gost3410-2012-512", "GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)", NID_id_tc26_signwithdigest_gost3410_2012_512, 8, &so[6451]}, - {"id-tc26-mac", "id-tc26-mac", NID_id_tc26_mac, 7, &so[6459]}, - {"id-tc26-hmac-gost-3411-2012-256", "HMAC GOST 34.11-2012 256 bit", NID_id_tc26_hmac_gost_3411_2012_256, 8, &so[6466]}, - {"id-tc26-hmac-gost-3411-2012-512", "HMAC GOST 34.11-2012 512 bit", NID_id_tc26_hmac_gost_3411_2012_512, 8, &so[6474]}, - {"id-tc26-cipher", "id-tc26-cipher", NID_id_tc26_cipher, 7, &so[6482]}, - {"id-tc26-agreement", "id-tc26-agreement", NID_id_tc26_agreement, 7, &so[6489]}, - {"id-tc26-agreement-gost-3410-2012-256", "id-tc26-agreement-gost-3410-2012-256", NID_id_tc26_agreement_gost_3410_2012_256, 8, &so[6496]}, - {"id-tc26-agreement-gost-3410-2012-512", "id-tc26-agreement-gost-3410-2012-512", NID_id_tc26_agreement_gost_3410_2012_512, 8, &so[6504]}, - {"id-tc26-constants", "id-tc26-constants", NID_id_tc26_constants, 6, &so[6512]}, - {"id-tc26-sign-constants", "id-tc26-sign-constants", NID_id_tc26_sign_constants, 7, &so[6518]}, - {"id-tc26-gost-3410-2012-512-constants", "id-tc26-gost-3410-2012-512-constants", NID_id_tc26_gost_3410_2012_512_constants, 8, &so[6525]}, - {"id-tc26-gost-3410-2012-512-paramSetTest", "GOST R 34.10-2012 (512 bit) testing parameter set", NID_id_tc26_gost_3410_2012_512_paramSetTest, 9, &so[6533]}, - {"id-tc26-gost-3410-2012-512-paramSetA", "GOST R 34.10-2012 (512 bit) ParamSet A", NID_id_tc26_gost_3410_2012_512_paramSetA, 9, &so[6542]}, - {"id-tc26-gost-3410-2012-512-paramSetB", "GOST R 34.10-2012 (512 bit) ParamSet B", NID_id_tc26_gost_3410_2012_512_paramSetB, 9, &so[6551]}, - {"id-tc26-digest-constants", "id-tc26-digest-constants", NID_id_tc26_digest_constants, 7, &so[6560]}, - {"id-tc26-cipher-constants", "id-tc26-cipher-constants", NID_id_tc26_cipher_constants, 7, &so[6567]}, - {"id-tc26-gost-28147-constants", "id-tc26-gost-28147-constants", NID_id_tc26_gost_28147_constants, 8, &so[6574]}, - {"id-tc26-gost-28147-param-Z", "GOST 28147-89 TC26 parameter set", NID_id_tc26_gost_28147_param_Z, 9, &so[6582]}, - {"INN", "INN", NID_INN, 8, &so[6591]}, - {"OGRN", "OGRN", NID_OGRN, 5, &so[6599]}, - {"SNILS", "SNILS", NID_SNILS, 5, &so[6604]}, - {"subjectSignTool", "Signing Tool of Subject", NID_subjectSignTool, 5, &so[6609]}, - {"issuerSignTool", "Signing Tool of Issuer", NID_issuerSignTool, 5, &so[6614]}, - {"gost89-cbc", "gost89-cbc", NID_gost89_cbc}, - {"gost89-ecb", "gost89-ecb", NID_gost89_ecb}, - {"gost89-ctr", "gost89-ctr", NID_gost89_ctr}, - {"kuznyechik-ecb", "kuznyechik-ecb", NID_kuznyechik_ecb}, - {"kuznyechik-ctr", "kuznyechik-ctr", NID_kuznyechik_ctr}, - {"kuznyechik-ofb", "kuznyechik-ofb", NID_kuznyechik_ofb}, - {"kuznyechik-cbc", "kuznyechik-cbc", NID_kuznyechik_cbc}, - {"kuznyechik-cfb", "kuznyechik-cfb", NID_kuznyechik_cfb}, - {"kuznyechik-mac", "kuznyechik-mac", NID_kuznyechik_mac}, - {"ChaCha20-Poly1305", "chacha20-poly1305", NID_chacha20_poly1305}, - {"ChaCha20", "chacha20", NID_chacha20}, - {"tlsfeature", "TLS Feature", NID_tlsfeature, 8, &so[6619]}, - {"TLS1-PRF", "tls1-prf", NID_tls1_prf}, - {"ipsecIKE", "ipsec Internet Key Exchange", NID_ipsec_IKE, 8, &so[6627]}, - {"capwapAC", "Ctrl/provision WAP Access", NID_capwapAC, 8, &so[6635]}, - {"capwapWTP", "Ctrl/Provision WAP Termination", NID_capwapWTP, 8, &so[6643]}, - {"secureShellClient", "SSH Client", NID_sshClient, 8, &so[6651]}, - {"secureShellServer", "SSH Server", NID_sshServer, 8, &so[6659]}, - {"sendRouter", "Send Router", NID_sendRouter, 8, &so[6667]}, - {"sendProxiedRouter", "Send Proxied Router", NID_sendProxiedRouter, 8, &so[6675]}, - {"sendOwner", "Send Owner", NID_sendOwner, 8, &so[6683]}, - {"sendProxiedOwner", "Send Proxied Owner", NID_sendProxiedOwner, 8, &so[6691]}, - {"id-pkinit", "id-pkinit", NID_id_pkinit, 6, &so[6699]}, - {"pkInitClientAuth", "PKINIT Client Auth", NID_pkInitClientAuth, 7, &so[6705]}, - {"pkInitKDC", "Signing KDC Response", NID_pkInitKDC, 7, &so[6712]}, - {"X25519", "X25519", NID_X25519, 3, &so[6719]}, - {"X448", "X448", NID_X448, 3, &so[6722]}, - {"HKDF", "hkdf", NID_hkdf}, - {"KxRSA", "kx-rsa", NID_kx_rsa}, - {"KxECDHE", "kx-ecdhe", NID_kx_ecdhe}, - {"KxDHE", "kx-dhe", NID_kx_dhe}, - {"KxECDHE-PSK", "kx-ecdhe-psk", NID_kx_ecdhe_psk}, - {"KxDHE-PSK", "kx-dhe-psk", NID_kx_dhe_psk}, - {"KxRSA_PSK", "kx-rsa-psk", NID_kx_rsa_psk}, - {"KxPSK", "kx-psk", NID_kx_psk}, - {"KxSRP", "kx-srp", NID_kx_srp}, - {"KxGOST", "kx-gost", NID_kx_gost}, - {"AuthRSA", "auth-rsa", NID_auth_rsa}, - {"AuthECDSA", "auth-ecdsa", NID_auth_ecdsa}, - {"AuthPSK", "auth-psk", NID_auth_psk}, - {"AuthDSS", "auth-dss", NID_auth_dss}, - {"AuthGOST01", "auth-gost01", NID_auth_gost01}, - {"AuthGOST12", "auth-gost12", NID_auth_gost12}, - {"AuthSRP", "auth-srp", NID_auth_srp}, - {"AuthNULL", "auth-null", NID_auth_null}, - { NULL, NULL, NID_undef }, - { NULL, NULL, NID_undef }, - {"BLAKE2b512", "blake2b512", NID_blake2b512, 11, &so[6725]}, - {"BLAKE2s256", "blake2s256", NID_blake2s256, 11, &so[6736]}, - {"id-smime-ct-contentCollection", "id-smime-ct-contentCollection", NID_id_smime_ct_contentCollection, 11, &so[6747]}, - {"id-smime-ct-authEnvelopedData", "id-smime-ct-authEnvelopedData", NID_id_smime_ct_authEnvelopedData, 11, &so[6758]}, - {"id-ct-xml", "id-ct-xml", NID_id_ct_xml, 11, &so[6769]}, - {"Poly1305", "poly1305", NID_poly1305}, - {"SipHash", "siphash", NID_siphash}, - {"KxANY", "kx-any", NID_kx_any}, - {"AuthANY", "auth-any", NID_auth_any}, - {"ARIA-128-ECB", "aria-128-ecb", NID_aria_128_ecb, 9, &so[6780]}, - {"ARIA-128-CBC", "aria-128-cbc", NID_aria_128_cbc, 9, &so[6789]}, - {"ARIA-128-CFB", "aria-128-cfb", NID_aria_128_cfb128, 9, &so[6798]}, - {"ARIA-128-OFB", "aria-128-ofb", NID_aria_128_ofb128, 9, &so[6807]}, - {"ARIA-128-CTR", "aria-128-ctr", NID_aria_128_ctr, 9, &so[6816]}, - {"ARIA-192-ECB", "aria-192-ecb", NID_aria_192_ecb, 9, &so[6825]}, - {"ARIA-192-CBC", "aria-192-cbc", NID_aria_192_cbc, 9, &so[6834]}, - {"ARIA-192-CFB", "aria-192-cfb", NID_aria_192_cfb128, 9, &so[6843]}, - {"ARIA-192-OFB", "aria-192-ofb", NID_aria_192_ofb128, 9, &so[6852]}, - {"ARIA-192-CTR", "aria-192-ctr", NID_aria_192_ctr, 9, &so[6861]}, - {"ARIA-256-ECB", "aria-256-ecb", NID_aria_256_ecb, 9, &so[6870]}, - {"ARIA-256-CBC", "aria-256-cbc", NID_aria_256_cbc, 9, &so[6879]}, - {"ARIA-256-CFB", "aria-256-cfb", NID_aria_256_cfb128, 9, &so[6888]}, - {"ARIA-256-OFB", "aria-256-ofb", NID_aria_256_ofb128, 9, &so[6897]}, - {"ARIA-256-CTR", "aria-256-ctr", NID_aria_256_ctr, 9, &so[6906]}, - {"ARIA-128-CFB1", "aria-128-cfb1", NID_aria_128_cfb1}, - {"ARIA-192-CFB1", "aria-192-cfb1", NID_aria_192_cfb1}, - {"ARIA-256-CFB1", "aria-256-cfb1", NID_aria_256_cfb1}, - {"ARIA-128-CFB8", "aria-128-cfb8", NID_aria_128_cfb8}, - {"ARIA-192-CFB8", "aria-192-cfb8", NID_aria_192_cfb8}, - {"ARIA-256-CFB8", "aria-256-cfb8", NID_aria_256_cfb8}, - {"id-smime-aa-signingCertificateV2", "id-smime-aa-signingCertificateV2", NID_id_smime_aa_signingCertificateV2, 11, &so[6915]}, - {"ED25519", "ED25519", NID_ED25519, 3, &so[6926]}, - {"ED448", "ED448", NID_ED448, 3, &so[6929]}, - {"organizationIdentifier", "organizationIdentifier", NID_organizationIdentifier, 3, &so[6932]}, - {"c3", "countryCode3c", NID_countryCode3c, 3, &so[6935]}, - {"n3", "countryCode3n", NID_countryCode3n, 3, &so[6938]}, - {"dnsName", "dnsName", NID_dnsName, 3, &so[6941]}, - {"x509ExtAdmission", "Professional Information or basis for Admission", NID_x509ExtAdmission, 5, &so[6944]}, - {"SHA512-224", "sha512-224", NID_sha512_224, 9, &so[6949]}, - {"SHA512-256", "sha512-256", NID_sha512_256, 9, &so[6958]}, - {"SHA3-224", "sha3-224", NID_sha3_224, 9, &so[6967]}, - {"SHA3-256", "sha3-256", NID_sha3_256, 9, &so[6976]}, - {"SHA3-384", "sha3-384", NID_sha3_384, 9, &so[6985]}, - {"SHA3-512", "sha3-512", NID_sha3_512, 9, &so[6994]}, - {"SHAKE128", "shake128", NID_shake128, 9, &so[7003]}, - {"SHAKE256", "shake256", NID_shake256, 9, &so[7012]}, - {"id-hmacWithSHA3-224", "hmac-sha3-224", NID_hmac_sha3_224, 9, &so[7021]}, - {"id-hmacWithSHA3-256", "hmac-sha3-256", NID_hmac_sha3_256, 9, &so[7030]}, - {"id-hmacWithSHA3-384", "hmac-sha3-384", NID_hmac_sha3_384, 9, &so[7039]}, - {"id-hmacWithSHA3-512", "hmac-sha3-512", NID_hmac_sha3_512, 9, &so[7048]}, - {"id-dsa-with-sha384", "dsa_with_SHA384", NID_dsa_with_SHA384, 9, &so[7057]}, - {"id-dsa-with-sha512", "dsa_with_SHA512", NID_dsa_with_SHA512, 9, &so[7066]}, - {"id-dsa-with-sha3-224", "dsa_with_SHA3-224", NID_dsa_with_SHA3_224, 9, &so[7075]}, - {"id-dsa-with-sha3-256", "dsa_with_SHA3-256", NID_dsa_with_SHA3_256, 9, &so[7084]}, - {"id-dsa-with-sha3-384", "dsa_with_SHA3-384", NID_dsa_with_SHA3_384, 9, &so[7093]}, - {"id-dsa-with-sha3-512", "dsa_with_SHA3-512", NID_dsa_with_SHA3_512, 9, &so[7102]}, - {"id-ecdsa-with-sha3-224", "ecdsa_with_SHA3-224", NID_ecdsa_with_SHA3_224, 9, &so[7111]}, - {"id-ecdsa-with-sha3-256", "ecdsa_with_SHA3-256", NID_ecdsa_with_SHA3_256, 9, &so[7120]}, - {"id-ecdsa-with-sha3-384", "ecdsa_with_SHA3-384", NID_ecdsa_with_SHA3_384, 9, &so[7129]}, - {"id-ecdsa-with-sha3-512", "ecdsa_with_SHA3-512", NID_ecdsa_with_SHA3_512, 9, &so[7138]}, - {"id-rsassa-pkcs1-v1_5-with-sha3-224", "RSA-SHA3-224", NID_RSA_SHA3_224, 9, &so[7147]}, - {"id-rsassa-pkcs1-v1_5-with-sha3-256", "RSA-SHA3-256", NID_RSA_SHA3_256, 9, &so[7156]}, - {"id-rsassa-pkcs1-v1_5-with-sha3-384", "RSA-SHA3-384", NID_RSA_SHA3_384, 9, &so[7165]}, - {"id-rsassa-pkcs1-v1_5-with-sha3-512", "RSA-SHA3-512", NID_RSA_SHA3_512, 9, &so[7174]}, - {"ARIA-128-CCM", "aria-128-ccm", NID_aria_128_ccm, 9, &so[7183]}, - {"ARIA-192-CCM", "aria-192-ccm", NID_aria_192_ccm, 9, &so[7192]}, - {"ARIA-256-CCM", "aria-256-ccm", NID_aria_256_ccm, 9, &so[7201]}, - {"ARIA-128-GCM", "aria-128-gcm", NID_aria_128_gcm, 9, &so[7210]}, - {"ARIA-192-GCM", "aria-192-gcm", NID_aria_192_gcm, 9, &so[7219]}, - {"ARIA-256-GCM", "aria-256-gcm", NID_aria_256_gcm, 9, &so[7228]}, - {"ffdhe2048", "ffdhe2048", NID_ffdhe2048}, - {"ffdhe3072", "ffdhe3072", NID_ffdhe3072}, - {"ffdhe4096", "ffdhe4096", NID_ffdhe4096}, - {"ffdhe6144", "ffdhe6144", NID_ffdhe6144}, - {"ffdhe8192", "ffdhe8192", NID_ffdhe8192}, - {"cmcCA", "CMC Certificate Authority", NID_cmcCA, 8, &so[7237]}, - {"cmcRA", "CMC Registration Authority", NID_cmcRA, 8, &so[7245]}, - {"SM4-ECB", "sm4-ecb", NID_sm4_ecb, 8, &so[7253]}, - {"SM4-CBC", "sm4-cbc", NID_sm4_cbc, 8, &so[7261]}, - {"SM4-OFB", "sm4-ofb", NID_sm4_ofb128, 8, &so[7269]}, - {"SM4-CFB1", "sm4-cfb1", NID_sm4_cfb1, 8, &so[7277]}, - {"SM4-CFB", "sm4-cfb", NID_sm4_cfb128, 8, &so[7285]}, - {"SM4-CFB8", "sm4-cfb8", NID_sm4_cfb8, 8, &so[7293]}, - {"SM4-CTR", "sm4-ctr", NID_sm4_ctr, 8, &so[7301]}, - {"ISO-CN", "ISO CN Member Body", NID_ISO_CN, 3, &so[7309]}, - {"oscca", "oscca", NID_oscca, 5, &so[7312]}, - {"sm-scheme", "sm-scheme", NID_sm_scheme, 6, &so[7317]}, - {"SM3", "sm3", NID_sm3, 8, &so[7323]}, - {"RSA-SM3", "sm3WithRSAEncryption", NID_sm3WithRSAEncryption, 8, &so[7331]}, - {"RSA-SHA512/224", "sha512-224WithRSAEncryption", NID_sha512_224WithRSAEncryption, 9, &so[7339]}, - {"RSA-SHA512/256", "sha512-256WithRSAEncryption", NID_sha512_256WithRSAEncryption, 9, &so[7348]}, - {"id-tc26-gost-3410-2012-256-constants", "id-tc26-gost-3410-2012-256-constants", NID_id_tc26_gost_3410_2012_256_constants, 8, &so[7357]}, - {"id-tc26-gost-3410-2012-256-paramSetA", "GOST R 34.10-2012 (256 bit) ParamSet A", NID_id_tc26_gost_3410_2012_256_paramSetA, 9, &so[7365]}, - {"id-tc26-gost-3410-2012-512-paramSetC", "GOST R 34.10-2012 (512 bit) ParamSet C", NID_id_tc26_gost_3410_2012_512_paramSetC, 9, &so[7374]}, - {"ISO-UA", "ISO-UA", NID_ISO_UA, 3, &so[7383]}, - {"ua-pki", "ua-pki", NID_ua_pki, 7, &so[7386]}, - {"dstu28147", "DSTU Gost 28147-2009", NID_dstu28147, 10, &so[7393]}, - {"dstu28147-ofb", "DSTU Gost 28147-2009 OFB mode", NID_dstu28147_ofb, 11, &so[7403]}, - {"dstu28147-cfb", "DSTU Gost 28147-2009 CFB mode", NID_dstu28147_cfb, 11, &so[7414]}, - {"dstu28147-wrap", "DSTU Gost 28147-2009 key wrap", NID_dstu28147_wrap, 11, &so[7425]}, - {"hmacWithDstu34311", "HMAC DSTU Gost 34311-95", NID_hmacWithDstu34311, 10, &so[7436]}, - {"dstu34311", "DSTU Gost 34311-95", NID_dstu34311, 10, &so[7446]}, - {"dstu4145le", "DSTU 4145-2002 little endian", NID_dstu4145le, 11, &so[7456]}, - {"dstu4145be", "DSTU 4145-2002 big endian", NID_dstu4145be, 13, &so[7467]}, - {"uacurve0", "DSTU curve 0", NID_uacurve0, 13, &so[7480]}, - {"uacurve1", "DSTU curve 1", NID_uacurve1, 13, &so[7493]}, - {"uacurve2", "DSTU curve 2", NID_uacurve2, 13, &so[7506]}, - {"uacurve3", "DSTU curve 3", NID_uacurve3, 13, &so[7519]}, - {"uacurve4", "DSTU curve 4", NID_uacurve4, 13, &so[7532]}, - {"uacurve5", "DSTU curve 5", NID_uacurve5, 13, &so[7545]}, - {"uacurve6", "DSTU curve 6", NID_uacurve6, 13, &so[7558]}, - {"uacurve7", "DSTU curve 7", NID_uacurve7, 13, &so[7571]}, - {"uacurve8", "DSTU curve 8", NID_uacurve8, 13, &so[7584]}, - {"uacurve9", "DSTU curve 9", NID_uacurve9, 13, &so[7597]}, - {"ieee", "ieee", NID_ieee, 2, &so[7610]}, - {"ieee-siswg", "IEEE Security in Storage Working Group", NID_ieee_siswg, 5, &so[7612]}, - {"SM2", "sm2", NID_sm2, 8, &so[7617]}, - {"id-tc26-cipher-gostr3412-2015-magma", "id-tc26-cipher-gostr3412-2015-magma", NID_id_tc26_cipher_gostr3412_2015_magma, 8, &so[7625]}, - {"magma-ctr-acpkm", "magma-ctr-acpkm", NID_magma_ctr_acpkm, 9, &so[7633]}, - {"magma-ctr-acpkm-omac", "magma-ctr-acpkm-omac", NID_magma_ctr_acpkm_omac, 9, &so[7642]}, - {"id-tc26-cipher-gostr3412-2015-kuznyechik", "id-tc26-cipher-gostr3412-2015-kuznyechik", NID_id_tc26_cipher_gostr3412_2015_kuznyechik, 8, &so[7651]}, - {"kuznyechik-ctr-acpkm", "kuznyechik-ctr-acpkm", NID_kuznyechik_ctr_acpkm, 9, &so[7659]}, - {"kuznyechik-ctr-acpkm-omac", "kuznyechik-ctr-acpkm-omac", NID_kuznyechik_ctr_acpkm_omac, 9, &so[7668]}, - {"id-tc26-wrap", "id-tc26-wrap", NID_id_tc26_wrap, 7, &so[7677]}, - {"id-tc26-wrap-gostr3412-2015-magma", "id-tc26-wrap-gostr3412-2015-magma", NID_id_tc26_wrap_gostr3412_2015_magma, 8, &so[7684]}, - {"magma-kexp15", "magma-kexp15", NID_magma_kexp15, 9, &so[7692]}, - {"id-tc26-wrap-gostr3412-2015-kuznyechik", "id-tc26-wrap-gostr3412-2015-kuznyechik", NID_id_tc26_wrap_gostr3412_2015_kuznyechik, 8, &so[7701]}, - {"kuznyechik-kexp15", "kuznyechik-kexp15", NID_kuznyechik_kexp15, 9, &so[7709]}, - {"id-tc26-gost-3410-2012-256-paramSetB", "GOST R 34.10-2012 (256 bit) ParamSet B", NID_id_tc26_gost_3410_2012_256_paramSetB, 9, &so[7718]}, - {"id-tc26-gost-3410-2012-256-paramSetC", "GOST R 34.10-2012 (256 bit) ParamSet C", NID_id_tc26_gost_3410_2012_256_paramSetC, 9, &so[7727]}, - {"id-tc26-gost-3410-2012-256-paramSetD", "GOST R 34.10-2012 (256 bit) ParamSet D", NID_id_tc26_gost_3410_2012_256_paramSetD, 9, &so[7736]}, - {"magma-ecb", "magma-ecb", NID_magma_ecb}, - {"magma-ctr", "magma-ctr", NID_magma_ctr}, - {"magma-ofb", "magma-ofb", NID_magma_ofb}, - {"magma-cbc", "magma-cbc", NID_magma_cbc}, - {"magma-cfb", "magma-cfb", NID_magma_cfb}, - {"magma-mac", "magma-mac", NID_magma_mac}, - {"hmacWithSHA512-224", "hmacWithSHA512-224", NID_hmacWithSHA512_224, 8, &so[7745]}, - {"hmacWithSHA512-256", "hmacWithSHA512-256", NID_hmacWithSHA512_256, 8, &so[7753]}, - {"GMAC", "gmac", NID_gmac, 5, &so[7761]}, - {"KMAC128", "kmac128", NID_kmac128, 9, &so[7766]}, - {"KMAC256", "kmac256", NID_kmac256, 9, &so[7775]}, - {"AES-128-SIV", "aes-128-siv", NID_aes_128_siv}, - {"AES-192-SIV", "aes-192-siv", NID_aes_192_siv}, - {"AES-256-SIV", "aes-256-siv", NID_aes_256_siv}, - {"BLAKE2BMAC", "blake2bmac", NID_blake2bmac, 10, &so[7784]}, - {"BLAKE2SMAC", "blake2smac", NID_blake2smac, 10, &so[7794]}, - {"SSHKDF", "sshkdf", NID_sshkdf}, - {"SM2-SM3", "SM2-with-SM3", NID_SM2_with_SM3, 8, &so[7804]}, - {"SSKDF", "sskdf", NID_sskdf}, - {"X963KDF", "x963kdf", NID_x963kdf}, - {"X942KDF", "x942kdf", NID_x942kdf}, - {"id-on-SmtpUTF8Mailbox", "Smtp UTF8 Mailbox", NID_id_on_SmtpUTF8Mailbox, 8, &so[7812]}, - {"id-on-xmppAddr", "XmppAddr", NID_XmppAddr, 8, &so[7820]}, - {"id-on-dnsSRV", "SRVName", NID_SRVName, 8, &so[7828]}, - {"id-on-NAIRealm", "NAIRealm", NID_NAIRealm, 8, &so[7836]}, - {"modp_1536", "modp_1536", NID_modp_1536}, - {"modp_2048", "modp_2048", NID_modp_2048}, - {"modp_3072", "modp_3072", NID_modp_3072}, - {"modp_4096", "modp_4096", NID_modp_4096}, - {"modp_6144", "modp_6144", NID_modp_6144}, - {"modp_8192", "modp_8192", NID_modp_8192}, - {"KxGOST18", "kx-gost18", NID_kx_gost18}, - {"cmcArchive", "CMC Archive Server", NID_cmcArchive, 8, &so[7844]}, - {"id-kp-bgpsec-router", "BGPsec Router", NID_id_kp_bgpsec_router, 8, &so[7852]}, - {"id-kp-BrandIndicatorforMessageIdentification", "Brand Indicator for Message Identification", NID_id_kp_BrandIndicatorforMessageIdentification, 8, &so[7860]}, - {"cmKGA", "Certificate Management Key Generation Authority", NID_cmKGA, 8, &so[7868]}, - {"id-it-caCerts", "id-it-caCerts", NID_id_it_caCerts, 8, &so[7876]}, - {"id-it-rootCaKeyUpdate", "id-it-rootCaKeyUpdate", NID_id_it_rootCaKeyUpdate, 8, &so[7884]}, - {"id-it-certReqTemplate", "id-it-certReqTemplate", NID_id_it_certReqTemplate, 8, &so[7892]}, - {"OGRNIP", "OGRNIP", NID_OGRNIP, 5, &so[7900]}, - {"classSignTool", "Class of Signing Tool", NID_classSignTool, 5, &so[7905]}, - {"classSignToolKC1", "Class of Signing Tool KC1", NID_classSignToolKC1, 6, &so[7910]}, - {"classSignToolKC2", "Class of Signing Tool KC2", NID_classSignToolKC2, 6, &so[7916]}, - {"classSignToolKC3", "Class of Signing Tool KC3", NID_classSignToolKC3, 6, &so[7922]}, - {"classSignToolKB1", "Class of Signing Tool KB1", NID_classSignToolKB1, 6, &so[7928]}, - {"classSignToolKB2", "Class of Signing Tool KB2", NID_classSignToolKB2, 6, &so[7934]}, - {"classSignToolKA1", "Class of Signing Tool KA1", NID_classSignToolKA1, 6, &so[7940]}, - {"id-ct-routeOriginAuthz", "id-ct-routeOriginAuthz", NID_id_ct_routeOriginAuthz, 11, &so[7946]}, - {"id-ct-rpkiManifest", "id-ct-rpkiManifest", NID_id_ct_rpkiManifest, 11, &so[7957]}, - {"id-ct-rpkiGhostbusters", "id-ct-rpkiGhostbusters", NID_id_ct_rpkiGhostbusters, 11, &so[7968]}, - {"id-ct-resourceTaggedAttest", "id-ct-resourceTaggedAttest", NID_id_ct_resourceTaggedAttest, 11, &so[7979]}, - {"id-cp", "id-cp", NID_id_cp, 7, &so[7990]}, - {"sbgp-ipAddrBlockv2", "sbgp-ipAddrBlockv2", NID_sbgp_ipAddrBlockv2, 8, &so[7997]}, - {"sbgp-autonomousSysNumv2", "sbgp-autonomousSysNumv2", NID_sbgp_autonomousSysNumv2, 8, &so[8005]}, - {"ipAddr-asNumber", "ipAddr-asNumber", NID_ipAddr_asNumber, 8, &so[8013]}, - {"ipAddr-asNumberv2", "ipAddr-asNumberv2", NID_ipAddr_asNumberv2, 8, &so[8021]}, - {"rpkiManifest", "RPKI Manifest", NID_rpkiManifest, 8, &so[8029]}, - {"signedObject", "Signed Object", NID_signedObject, 8, &so[8037]}, - {"rpkiNotify", "RPKI Notify", NID_rpkiNotify, 8, &so[8045]}, - {"id-ct-geofeedCSVwithCRLF", "id-ct-geofeedCSVwithCRLF", NID_id_ct_geofeedCSVwithCRLF, 11, &so[8053]}, - {"id-ct-signedChecklist", "id-ct-signedChecklist", NID_id_ct_signedChecklist, 11, &so[8064]}, - {"SM4-GCM", "sm4-gcm", NID_sm4_gcm, 8, &so[8075]}, - {"SM4-CCM", "sm4-ccm", NID_sm4_ccm, 8, &so[8083]}, - {"id-ct-ASPA", "id-ct-ASPA", NID_id_ct_ASPA, 11, &so[8091]}, - {"id-mod-cmp2000-02", "id-mod-cmp2000-02", NID_id_mod_cmp2000_02, 8, &so[8102]}, - {"id-mod-cmp2021-88", "id-mod-cmp2021-88", NID_id_mod_cmp2021_88, 8, &so[8110]}, - {"id-mod-cmp2021-02", "id-mod-cmp2021-02", NID_id_mod_cmp2021_02, 8, &so[8118]}, - {"id-it-rootCaCert", "id-it-rootCaCert", NID_id_it_rootCaCert, 8, &so[8126]}, - {"id-it-certProfile", "id-it-certProfile", NID_id_it_certProfile, 8, &so[8134]}, - {"id-it-crlStatusList", "id-it-crlStatusList", NID_id_it_crlStatusList, 8, &so[8142]}, - {"id-it-crls", "id-it-crls", NID_id_it_crls, 8, &so[8150]}, - {"id-regCtrl-altCertTemplate", "id-regCtrl-altCertTemplate", NID_id_regCtrl_altCertTemplate, 9, &so[8158]}, - {"id-regCtrl-algId", "id-regCtrl-algId", NID_id_regCtrl_algId, 9, &so[8167]}, - {"id-regCtrl-rsaKeyLen", "id-regCtrl-rsaKeyLen", NID_id_regCtrl_rsaKeyLen, 9, &so[8176]}, - {"id-aa-ets-attrCertificateRefs", "id-aa-ets-attrCertificateRefs", NID_id_aa_ets_attrCertificateRefs, 11, &so[8185]}, - {"id-aa-ets-attrRevocationRefs", "id-aa-ets-attrRevocationRefs", NID_id_aa_ets_attrRevocationRefs, 11, &so[8196]}, - {"id-aa-CMSAlgorithmProtection", "id-aa-CMSAlgorithmProtection", NID_id_aa_CMSAlgorithmProtection, 9, &so[8207]}, - {"itu-t-identified-organization", "itu-t-identified-organization", NID_itu_t_identified_organization, 1, &so[8216]}, - {"etsi", "etsi", NID_etsi, 2, &so[8217]}, - {"electronic-signature-standard", "electronic-signature-standard", NID_electronic_signature_standard, 4, &so[8219]}, - {"ess-attributes", "ess-attributes", NID_ess_attributes, 5, &so[8223]}, - {"id-aa-ets-mimeType", "id-aa-ets-mimeType", NID_id_aa_ets_mimeType, 6, &so[8228]}, - {"id-aa-ets-longTermValidation", "id-aa-ets-longTermValidation", NID_id_aa_ets_longTermValidation, 6, &so[8234]}, - {"id-aa-ets-SignaturePolicyDocument", "id-aa-ets-SignaturePolicyDocument", NID_id_aa_ets_SignaturePolicyDocument, 6, &so[8240]}, - {"id-aa-ets-archiveTimestampV3", "id-aa-ets-archiveTimestampV3", NID_id_aa_ets_archiveTimestampV3, 6, &so[8246]}, - {"id-aa-ATSHashIndex", "id-aa-ATSHashIndex", NID_id_aa_ATSHashIndex, 6, &so[8252]}, - {"cades", "cades", NID_cades, 5, &so[8258]}, - {"cades-attributes", "cades-attributes", NID_cades_attributes, 6, &so[8263]}, - {"id-aa-ets-signerAttrV2", "id-aa-ets-signerAttrV2", NID_id_aa_ets_signerAttrV2, 7, &so[8269]}, - {"id-aa-ets-sigPolicyStore", "id-aa-ets-sigPolicyStore", NID_id_aa_ets_sigPolicyStore, 7, &so[8276]}, - {"id-aa-ATSHashIndex-v2", "id-aa-ATSHashIndex-v2", NID_id_aa_ATSHashIndex_v2, 7, &so[8283]}, - {"id-aa-ATSHashIndex-v3", "id-aa-ATSHashIndex-v3", NID_id_aa_ATSHashIndex_v3, 7, &so[8290]}, - {"signedAssertion", "signedAssertion", NID_signedAssertion, 7, &so[8297]}, - {"id-aa-ets-archiveTimestampV2", "id-aa-ets-archiveTimestampV2", NID_id_aa_ets_archiveTimestampV2, 11, &so[8304]}, - {"hmacWithSM3", "hmacWithSM3", NID_hmacWithSM3, 10, &so[8315]}, - {"oracle-organization", "Oracle organization", NID_oracle, 7, &so[8325]}, - {"oracle-jdk-trustedkeyusage", "Trusted key usage (Oracle)", NID_oracle_jdk_trustedkeyusage, 12, &so[8332]}, - {"id-ct-signedTAL", "id-ct-signedTAL", NID_id_ct_signedTAL, 11, &so[8344]}, - {"brainpoolP256r1tls13", "brainpoolP256r1tls13", NID_brainpoolP256r1tls13}, - {"brainpoolP384r1tls13", "brainpoolP384r1tls13", NID_brainpoolP384r1tls13}, - {"brainpoolP512r1tls13", "brainpoolP512r1tls13", NID_brainpoolP512r1tls13}, - {"brotli", "Brotli compression", NID_brotli}, - {"zstd", "Zstandard compression", NID_zstd}, - {"SM4-XTS", "sm4-xts", NID_sm4_xts, 8, &so[8355]}, - {"ms-ntds-obj-sid", "Microsoft NTDS AD objectSid", NID_ms_ntds_obj_sid, 10, &so[8363]}, - {"ms-ntds-sec-ext", "Microsoft NTDS CA Extension", NID_ms_ntds_sec_ext, 9, &so[8373]}, - {"ms-cert-templ", "Microsoft certificate template", NID_ms_cert_templ, 9, &so[8382]}, - {"ms-app-policies", "Microsoft Application Policies Extension", NID_ms_app_policies, 9, &so[8391]}, - {"authorityAttributeIdentifier", "X509v3 Authority Attribute Identifier", NID_authority_attribute_identifier, 3, &so[8400]}, - {"roleSpecCertIdentifier", "X509v3 Role Specification Certificate Identifier", NID_role_spec_cert_identifier, 3, &so[8403]}, - {"basicAttConstraints", "X509v3 Basic Attribute Certificate Constraints", NID_basic_att_constraints, 3, &so[8406]}, - {"delegatedNameConstraints", "X509v3 Delegated Name Constraints", NID_delegated_name_constraints, 3, &so[8409]}, - {"timeSpecification", "X509v3 Time Specification", NID_time_specification, 3, &so[8412]}, - {"attributeDescriptor", "X509v3 Attribute Descriptor", NID_attribute_descriptor, 3, &so[8415]}, - {"userNotice", "X509v3 User Notice", NID_user_notice, 3, &so[8418]}, - {"sOAIdentifier", "X509v3 Source of Authority Identifier", NID_soa_identifier, 3, &so[8421]}, - {"acceptableCertPolicies", "X509v3 Acceptable Certification Policies", NID_acceptable_cert_policies, 3, &so[8424]}, - {"acceptablePrivPolicies", "X509v3 Acceptable Privilege Policies", NID_acceptable_privilege_policies, 3, &so[8427]}, - {"indirectIssuer", "X509v3 Indirect Issuer", NID_indirect_issuer, 3, &so[8430]}, - {"noAssertion", "X509v3 No Assertion", NID_no_assertion, 3, &so[8433]}, - {"aAissuingDistributionPoint", "X509v3 Attribute Authority Issuing Distribution Point", NID_id_aa_issuing_distribution_point, 3, &so[8436]}, - {"issuedOnBehalfOf", "X509v3 Issued On Behalf Of", NID_issued_on_behalf_of, 3, &so[8439]}, - {"singleUse", "X509v3 Single Use", NID_single_use, 3, &so[8442]}, - {"groupAC", "X509v3 Group Attribute Certificate", NID_group_ac, 3, &so[8445]}, - {"allowedAttributeAssignments", "X509v3 Allowed Attribute Assignments", NID_allowed_attribute_assignments, 3, &so[8448]}, - {"attributeMappings", "X509v3 Attribute Mappings", NID_attribute_mappings, 3, &so[8451]}, - {"holderNameConstraints", "X509v3 Holder Name Constraints", NID_holder_name_constraints, 3, &so[8454]}, - {"authorizationValidation", "X509v3 Authorization Validation", NID_authorization_validation, 3, &so[8457]}, - {"protRestrict", "X509v3 Protocol Restriction", NID_prot_restrict, 3, &so[8460]}, - {"subjectAltPublicKeyInfo", "X509v3 Subject Alternative Public Key Info", NID_subject_alt_public_key_info, 3, &so[8463]}, - {"altSignatureAlgorithm", "X509v3 Alternative Signature Algorithm", NID_alt_signature_algorithm, 3, &so[8466]}, - {"altSignatureValue", "X509v3 Alternative Signature Value", NID_alt_signature_value, 3, &so[8469]}, - {"associatedInformation", "X509v3 Associated Information", NID_associated_information, 3, &so[8472]}, - {"id-ct-rpkiSignedPrefixList", "id-ct-rpkiSignedPrefixList", NID_id_ct_rpkiSignedPrefixList, 11, &so[8475]}, - {"id-on-hardwareModuleName", "Hardware Module Name", NID_id_on_hardwareModuleName, 8, &so[8486]}, - {"id-kp-wisun-fan-device", "Wi-SUN Alliance Field Area Network (FAN)", NID_id_kp_wisun_fan_device, 9, &so[8494]}, - {"NULL", "NULL", NID_ac_auditEntity}, - {"tcg", "Trusted Computing Group", NID_tcg, 3, &so[8503]}, - {"tcg-tcpaSpecVersion", "tcg-tcpaSpecVersion", NID_tcg_tcpaSpecVersion, 4, &so[8506]}, - {"tcg-attribute", "Trusted Computing Group Attributes", NID_tcg_attribute, 4, &so[8510]}, - {"tcg-protocol", "Trusted Computing Group Protocols", NID_tcg_protocol, 4, &so[8514]}, - {"tcg-algorithm", "Trusted Computing Group Algorithms", NID_tcg_algorithm, 4, &so[8518]}, - {"tcg-platformClass", "Trusted Computing Group Platform Classes", NID_tcg_platformClass, 4, &so[8522]}, - {"tcg-ce", "Trusted Computing Group Certificate Extensions", NID_tcg_ce, 4, &so[8526]}, - {"tcg-kp", "Trusted Computing Group Key Purposes", NID_tcg_kp, 4, &so[8530]}, - {"tcg-ca", "Trusted Computing Group Certificate Policies", NID_tcg_ca, 4, &so[8534]}, - {"tcg-address", "Trusted Computing Group Address Formats", NID_tcg_address, 4, &so[8538]}, - {"tcg-registry", "Trusted Computing Group Registry", NID_tcg_registry, 4, &so[8542]}, - {"tcg-traits", "Trusted Computing Group Traits", NID_tcg_traits, 4, &so[8546]}, - {"tcg-common", "Trusted Computing Group Common", NID_tcg_common, 5, &so[8550]}, - {"tcg-at-platformManufacturerStr", "TCG Platform Manufacturer String", NID_tcg_at_platformManufacturerStr, 6, &so[8555]}, - {"tcg-at-platformManufacturerId", "TCG Platform Manufacturer ID", NID_tcg_at_platformManufacturerId, 6, &so[8561]}, - {"tcg-at-platformConfigUri", "TCG Platform Configuration URI", NID_tcg_at_platformConfigUri, 6, &so[8567]}, - {"tcg-at-platformModel", "TCG Platform Model", NID_tcg_at_platformModel, 6, &so[8573]}, - {"tcg-at-platformVersion", "TCG Platform Version", NID_tcg_at_platformVersion, 6, &so[8579]}, - {"tcg-at-platformSerial", "TCG Platform Serial Number", NID_tcg_at_platformSerial, 6, &so[8585]}, - {"tcg-at-platformConfiguration", "TCG Platform Configuration", NID_tcg_at_platformConfiguration, 6, &so[8591]}, - {"tcg-at-platformIdentifier", "TCG Platform Identifier", NID_tcg_at_platformIdentifier, 6, &so[8597]}, - {"tcg-at-tpmManufacturer", "TPM Manufacturer", NID_tcg_at_tpmManufacturer, 5, &so[8603]}, - {"tcg-at-tpmModel", "TPM Model", NID_tcg_at_tpmModel, 5, &so[8608]}, - {"tcg-at-tpmVersion", "TPM Version", NID_tcg_at_tpmVersion, 5, &so[8613]}, - {"tcg-at-securityQualities", "Security Qualities", NID_tcg_at_securityQualities, 5, &so[8618]}, - {"tcg-at-tpmProtectionProfile", "TPM Protection Profile", NID_tcg_at_tpmProtectionProfile, 5, &so[8623]}, - {"tcg-at-tpmSecurityTarget", "TPM Security Target", NID_tcg_at_tpmSecurityTarget, 5, &so[8628]}, - {"tcg-at-tbbProtectionProfile", "TBB Protection Profile", NID_tcg_at_tbbProtectionProfile, 5, &so[8633]}, - {"tcg-at-tbbSecurityTarget", "TBB Security Target", NID_tcg_at_tbbSecurityTarget, 5, &so[8638]}, - {"tcg-at-tpmIdLabel", "TPM ID Label", NID_tcg_at_tpmIdLabel, 5, &so[8643]}, - {"tcg-at-tpmSpecification", "TPM Specification", NID_tcg_at_tpmSpecification, 5, &so[8648]}, - {"tcg-at-tcgPlatformSpecification", "TPM Platform Specification", NID_tcg_at_tcgPlatformSpecification, 5, &so[8653]}, - {"tcg-at-tpmSecurityAssertions", "TPM Security Assertions", NID_tcg_at_tpmSecurityAssertions, 5, &so[8658]}, - {"tcg-at-tbbSecurityAssertions", "TBB Security Assertions", NID_tcg_at_tbbSecurityAssertions, 5, &so[8663]}, - {"tcg-at-tcgCredentialSpecification", "TCG Credential Specification", NID_tcg_at_tcgCredentialSpecification, 5, &so[8668]}, - {"tcg-at-tcgCredentialType", "TCG Credential Type", NID_tcg_at_tcgCredentialType, 5, &so[8673]}, - {"tcg-at-previousPlatformCertificates", "TCG Previous Platform Certificates", NID_tcg_at_previousPlatformCertificates, 5, &so[8678]}, - {"tcg-at-tbbSecurityAssertions-v3", "TCG TBB Security Assertions V3", NID_tcg_at_tbbSecurityAssertions_v3, 5, &so[8683]}, - {"tcg-at-cryptographicAnchors", "TCG Cryptographic Anchors", NID_tcg_at_cryptographicAnchors, 5, &so[8688]}, - {"tcg-at-platformConfiguration-v1", "Platform Configuration Version 1", NID_tcg_at_platformConfiguration_v1, 7, &so[8693]}, - {"tcg-at-platformConfiguration-v2", "Platform Configuration Version 2", NID_tcg_at_platformConfiguration_v2, 7, &so[8700]}, - {"tcg-at-platformConfiguration-v3", "Platform Configuration Version 3", NID_tcg_at_platformConfiguration_v3, 7, &so[8707]}, - {"tcg-at-platformConfigUri-v3", "Platform Configuration URI Version 3", NID_tcg_at_platformConfigUri_v3, 7, &so[8714]}, - {"tcg-algorithm-null", "TCG NULL Algorithm", NID_tcg_algorithm_null, 5, &so[8721]}, - {"tcg-kp-EKCertificate", "Endorsement Key Certificate", NID_tcg_kp_EKCertificate, 5, &so[8726]}, - {"tcg-kp-PlatformAttributeCertificate", "Platform Attribute Certificate", NID_tcg_kp_PlatformAttributeCertificate, 5, &so[8731]}, - {"tcg-kp-AIKCertificate", "Attestation Identity Key Certificate", NID_tcg_kp_AIKCertificate, 5, &so[8736]}, - {"tcg-kp-PlatformKeyCertificate", "Platform Key Certificate", NID_tcg_kp_PlatformKeyCertificate, 5, &so[8741]}, - {"tcg-kp-DeltaPlatformAttributeCertificate", "Delta Platform Attribute Certificate", NID_tcg_kp_DeltaPlatformAttributeCertificate, 5, &so[8746]}, - {"tcg-kp-DeltaPlatformKeyCertificate", "Delta Platform Key Certificate", NID_tcg_kp_DeltaPlatformKeyCertificate, 5, &so[8751]}, - {"tcg-kp-AdditionalPlatformAttributeCertificate", "Additional Platform Attribute Certificate", NID_tcg_kp_AdditionalPlatformAttributeCertificate, 5, &so[8756]}, - {"tcg-kp-AdditionalPlatformKeyCertificate", "Additional Platform Key Certificate", NID_tcg_kp_AdditionalPlatformKeyCertificate, 5, &so[8761]}, - {"tcg-ce-relevantCredentials", "Relevant Credentials", NID_tcg_ce_relevantCredentials, 5, &so[8766]}, - {"tcg-ce-relevantManifests", "Relevant Manifests", NID_tcg_ce_relevantManifests, 5, &so[8771]}, - {"tcg-ce-virtualPlatformAttestationService", "Virtual Platform Attestation Service", NID_tcg_ce_virtualPlatformAttestationService, 5, &so[8776]}, - {"tcg-ce-migrationControllerAttestationService", "Migration Controller Attestation Service", NID_tcg_ce_migrationControllerAttestationService, 5, &so[8781]}, - {"tcg-ce-migrationControllerRegistrationService", "Migration Controller Registration Service", NID_tcg_ce_migrationControllerRegistrationService, 5, &so[8786]}, - {"tcg-ce-virtualPlatformBackupService", "Virtual Platform Backup Service", NID_tcg_ce_virtualPlatformBackupService, 5, &so[8791]}, - {"tcg-prt-tpmIdProtocol", "TCG TPM Protocol", NID_tcg_prt_tpmIdProtocol, 5, &so[8796]}, - {"tcg-address-ethernetmac", "Ethernet MAC Address", NID_tcg_address_ethernetmac, 5, &so[8801]}, - {"tcg-address-wlanmac", "WLAN MAC Address", NID_tcg_address_wlanmac, 5, &so[8806]}, - {"tcg-address-bluetoothmac", "Bluetooth MAC Address", NID_tcg_address_bluetoothmac, 5, &so[8811]}, - {"tcg-registry-componentClass", "TCG Component Class", NID_tcg_registry_componentClass, 5, &so[8816]}, - {"tcg-registry-componentClass-tcg", "Trusted Computed Group Registry", NID_tcg_registry_componentClass_tcg, 6, &so[8821]}, - {"tcg-registry-componentClass-ietf", "Internet Engineering Task Force Registry", NID_tcg_registry_componentClass_ietf, 6, &so[8827]}, - {"tcg-registry-componentClass-dmtf", "Distributed Management Task Force Registry", NID_tcg_registry_componentClass_dmtf, 6, &so[8833]}, - {"tcg-registry-componentClass-pcie", "PCIE Component Class", NID_tcg_registry_componentClass_pcie, 6, &so[8839]}, - {"tcg-registry-componentClass-disk", "Disk Component Class", NID_tcg_registry_componentClass_disk, 6, &so[8845]}, - {"tcg-cap-verifiedPlatformCertificate", "TCG Verified Platform Certificate CA Policy", NID_tcg_cap_verifiedPlatformCertificate, 5, &so[8851]}, - {"tcg-tr-ID", "TCG Trait Identifiers", NID_tcg_tr_ID, 5, &so[8856]}, - {"tcg-tr-category", "TCG Trait Categories", NID_tcg_tr_category, 5, &so[8861]}, - {"tcg-tr-registry", "TCG Trait Registries", NID_tcg_tr_registry, 5, &so[8866]}, - {"tcg-tr-ID-Boolean", "Boolean Trait", NID_tcg_tr_ID_Boolean, 6, &so[8871]}, - {"tcg-tr-ID-CertificateIdentifier", "Certificate Identifier Trait", NID_tcg_tr_ID_CertificateIdentifier, 6, &so[8877]}, - {"tcg-tr-ID-CommonCriteria", "Common Criteria Trait", NID_tcg_tr_ID_CommonCriteria, 6, &so[8883]}, - {"tcg-tr-ID-componentClass", "Component Class Trait", NID_tcg_tr_ID_componentClass, 6, &so[8889]}, - {"tcg-tr-ID-componentIdentifierV11", "Component Identifier V1.1 Trait", NID_tcg_tr_ID_componentIdentifierV11, 6, &so[8895]}, - {"tcg-tr-ID-FIPSLevel", "FIPS Level Trait", NID_tcg_tr_ID_FIPSLevel, 6, &so[8901]}, - {"tcg-tr-ID-ISO9000Level", "ISO 9000 Level Trait", NID_tcg_tr_ID_ISO9000Level, 6, &so[8907]}, - {"tcg-tr-ID-networkMAC", "Network MAC Trait", NID_tcg_tr_ID_networkMAC, 6, &so[8913]}, - {"tcg-tr-ID-OID", "Object Identifier Trait", NID_tcg_tr_ID_OID, 6, &so[8919]}, - {"tcg-tr-ID-PEN", "Private Enterprise Number Trait", NID_tcg_tr_ID_PEN, 6, &so[8925]}, - {"tcg-tr-ID-platformFirmwareCapabilities", "Platform Firmware Capabilities Trait", NID_tcg_tr_ID_platformFirmwareCapabilities, 6, &so[8931]}, - {"tcg-tr-ID-platformFirmwareSignatureVerification", "Platform Firmware Signature Verification Trait", NID_tcg_tr_ID_platformFirmwareSignatureVerification, 6, &so[8937]}, - {"tcg-tr-ID-platformFirmwareUpdateCompliance", "Platform Firmware Update Compliance Trait", NID_tcg_tr_ID_platformFirmwareUpdateCompliance, 6, &so[8943]}, - {"tcg-tr-ID-platformHardwareCapabilities", "Platform Hardware Capabilities Trait", NID_tcg_tr_ID_platformHardwareCapabilities, 6, &so[8949]}, - {"tcg-tr-ID-RTM", "Root of Trust for Measurement Trait", NID_tcg_tr_ID_RTM, 6, &so[8955]}, - {"tcg-tr-ID-status", "Attribute Status Trait", NID_tcg_tr_ID_status, 6, &so[8961]}, - {"tcg-tr-ID-URI", "Uniform Resource Identifier Trait", NID_tcg_tr_ID_URI, 6, &so[8967]}, - {"tcg-tr-ID-UTF8String", "UTF8String Trait", NID_tcg_tr_ID_UTF8String, 6, &so[8973]}, - {"tcg-tr-ID-IA5String", "IA5String Trait", NID_tcg_tr_ID_IA5String, 6, &so[8979]}, - {"tcg-tr-ID-PEMCertString", "PEM-Encoded Certificate String Trait", NID_tcg_tr_ID_PEMCertString, 6, &so[8985]}, - {"tcg-tr-ID-PublicKey", "Public Key Trait", NID_tcg_tr_ID_PublicKey, 6, &so[8991]}, - {"tcg-tr-cat-platformManufacturer", "Platform Manufacturer Trait Category", NID_tcg_tr_cat_platformManufacturer, 6, &so[8997]}, - {"tcg-tr-cat-platformModel", "Platform Model Trait Category", NID_tcg_tr_cat_platformModel, 6, &so[9003]}, - {"tcg-tr-cat-platformVersion", "Platform Version Trait Category", NID_tcg_tr_cat_platformVersion, 6, &so[9009]}, - {"tcg-tr-cat-platformSerial", "Platform Serial Trait Category", NID_tcg_tr_cat_platformSerial, 6, &so[9015]}, - {"tcg-tr-cat-platformManufacturerIdentifier", "Platform Manufacturer Identifier Trait Category", NID_tcg_tr_cat_platformManufacturerIdentifier, 6, &so[9021]}, - {"tcg-tr-cat-platformOwnership", "Platform Ownership Trait Category", NID_tcg_tr_cat_platformOwnership, 6, &so[9027]}, - {"tcg-tr-cat-componentClass", "Component Class Trait Category", NID_tcg_tr_cat_componentClass, 6, &so[9033]}, - {"tcg-tr-cat-componentManufacturer", "Component Manufacturer Trait Category", NID_tcg_tr_cat_componentManufacturer, 6, &so[9039]}, - {"tcg-tr-cat-componentModel", "Component Model Trait Category", NID_tcg_tr_cat_componentModel, 6, &so[9045]}, - {"tcg-tr-cat-componentSerial", "Component Serial Trait Category", NID_tcg_tr_cat_componentSerial, 6, &so[9051]}, - {"tcg-tr-cat-componentStatus", "Component Status Trait Category", NID_tcg_tr_cat_componentStatus, 6, &so[9057]}, - {"tcg-tr-cat-componentLocation", "Component Location Trait Category", NID_tcg_tr_cat_componentLocation, 6, &so[9063]}, - {"tcg-tr-cat-componentRevision", "Component Revision Trait Category", NID_tcg_tr_cat_componentRevision, 6, &so[9069]}, - {"tcg-tr-cat-componentFieldReplaceable", "Component Field Replaceable Trait Category", NID_tcg_tr_cat_componentFieldReplaceable, 6, &so[9075]}, - {"tcg-tr-cat-EKCertificate", "EK Certificate Trait Category", NID_tcg_tr_cat_EKCertificate, 6, &so[9081]}, - {"tcg-tr-cat-IAKCertificate", "IAK Certificate Trait Category", NID_tcg_tr_cat_IAKCertificate, 6, &so[9087]}, - {"tcg-tr-cat-IDevIDCertificate", "IDevID Certificate Trait Category", NID_tcg_tr_cat_IDevIDCertificate, 6, &so[9093]}, - {"tcg-tr-cat-DICECertificate", "DICE Certificate Trait Category", NID_tcg_tr_cat_DICECertificate, 6, &so[9099]}, - {"tcg-tr-cat-SPDMCertificate", "SPDM Certificate Trait Category", NID_tcg_tr_cat_SPDMCertificate, 6, &so[9105]}, - {"tcg-tr-cat-PEMCertificate", "PEM Certificate Trait Category", NID_tcg_tr_cat_PEMCertificate, 6, &so[9111]}, - {"tcg-tr-cat-PlatformCertificate", "Platform Certificate Trait Category", NID_tcg_tr_cat_PlatformCertificate, 6, &so[9117]}, - {"tcg-tr-cat-DeltaPlatformCertificate", "Delta Platform Certificate Trait Category", NID_tcg_tr_cat_DeltaPlatformCertificate, 6, &so[9123]}, - {"tcg-tr-cat-RebasePlatformCertificate", "Rebase Platform Certificate Trait Category", NID_tcg_tr_cat_RebasePlatformCertificate, 6, &so[9129]}, - {"tcg-tr-cat-genericCertificate", "Generic Certificate Trait Category", NID_tcg_tr_cat_genericCertificate, 6, &so[9135]}, - {"tcg-tr-cat-CommonCriteria", "Common Criteria Trait Category", NID_tcg_tr_cat_CommonCriteria, 6, &so[9141]}, - {"tcg-tr-cat-componentIdentifierV11", "Component Identifier V1.1 Trait Category", NID_tcg_tr_cat_componentIdentifierV11, 6, &so[9147]}, - {"tcg-tr-cat-FIPSLevel", "FIPS Level Trait Category", NID_tcg_tr_cat_FIPSLevel, 6, &so[9153]}, - {"tcg-tr-cat-ISO9000", "ISO 9000 Trait Category", NID_tcg_tr_cat_ISO9000, 6, &so[9159]}, - {"tcg-tr-cat-networkMAC", "Network MAC Trait Category", NID_tcg_tr_cat_networkMAC, 6, &so[9165]}, - {"tcg-tr-cat-attestationProtocol", "Attestation Protocol Trait Category", NID_tcg_tr_cat_attestationProtocol, 6, &so[9171]}, - {"tcg-tr-cat-PEN", "Private Enterprise Number Trait Category", NID_tcg_tr_cat_PEN, 6, &so[9177]}, - {"tcg-tr-cat-platformFirmwareCapabilities", "Platform Firmware Capabilities Trait Category", NID_tcg_tr_cat_platformFirmwareCapabilities, 6, &so[9183]}, - {"tcg-tr-cat-platformHardwareCapabilities", "Platform Hardware Capabilities Trait Category", NID_tcg_tr_cat_platformHardwareCapabilities, 6, &so[9189]}, - {"tcg-tr-cat-platformFirmwareSignatureVerification", "Platform Firmware Signature Verification Trait Category", NID_tcg_tr_cat_platformFirmwareSignatureVerification, 6, &so[9195]}, - {"tcg-tr-cat-platformFirmwareUpdateCompliance", "Platform Firmware Update Compliance Trait Category", NID_tcg_tr_cat_platformFirmwareUpdateCompliance, 6, &so[9201]}, - {"tcg-tr-cat-RTM", "Root of Trust of Measurement Trait Category", NID_tcg_tr_cat_RTM, 6, &so[9207]}, - {"tcg-tr-cat-PublicKey", "Public Key Trait Category", NID_tcg_tr_cat_PublicKey, 6, &so[9213]}, - {"id-alg-ml-kem-512", "ML-KEM-512", NID_ML_KEM_512, 9, &so[9219]}, - {"id-alg-ml-kem-768", "ML-KEM-768", NID_ML_KEM_768, 9, &so[9228]}, - {"id-alg-ml-kem-1024", "ML-KEM-1024", NID_ML_KEM_1024, 9, &so[9237]}, - {"id-ml-dsa-44", "ML-DSA-44", NID_ML_DSA_44, 9, &so[9246]}, - {"id-ml-dsa-65", "ML-DSA-65", NID_ML_DSA_65, 9, &so[9255]}, - {"id-ml-dsa-87", "ML-DSA-87", NID_ML_DSA_87, 9, &so[9264]}, - {"id-slh-dsa-sha2-128s", "SLH-DSA-SHA2-128s", NID_SLH_DSA_SHA2_128s, 9, &so[9273]}, - {"id-slh-dsa-sha2-128f", "SLH-DSA-SHA2-128f", NID_SLH_DSA_SHA2_128f, 9, &so[9282]}, - {"id-slh-dsa-sha2-192s", "SLH-DSA-SHA2-192s", NID_SLH_DSA_SHA2_192s, 9, &so[9291]}, - {"id-slh-dsa-sha2-192f", "SLH-DSA-SHA2-192f", NID_SLH_DSA_SHA2_192f, 9, &so[9300]}, - {"id-slh-dsa-sha2-256s", "SLH-DSA-SHA2-256s", NID_SLH_DSA_SHA2_256s, 9, &so[9309]}, - {"id-slh-dsa-sha2-256f", "SLH-DSA-SHA2-256f", NID_SLH_DSA_SHA2_256f, 9, &so[9318]}, - {"id-slh-dsa-shake-128s", "SLH-DSA-SHAKE-128s", NID_SLH_DSA_SHAKE_128s, 9, &so[9327]}, - {"id-slh-dsa-shake-128f", "SLH-DSA-SHAKE-128f", NID_SLH_DSA_SHAKE_128f, 9, &so[9336]}, - {"id-slh-dsa-shake-192s", "SLH-DSA-SHAKE-192s", NID_SLH_DSA_SHAKE_192s, 9, &so[9345]}, - {"id-slh-dsa-shake-192f", "SLH-DSA-SHAKE-192f", NID_SLH_DSA_SHAKE_192f, 9, &so[9354]}, - {"id-slh-dsa-shake-256s", "SLH-DSA-SHAKE-256s", NID_SLH_DSA_SHAKE_256s, 9, &so[9363]}, - {"id-slh-dsa-shake-256f", "SLH-DSA-SHAKE-256f", NID_SLH_DSA_SHAKE_256f, 9, &so[9372]}, - {"id-hash-ml-dsa-44-with-sha512", "HASH-ML-DSA-44-WITH-SHA512", NID_HASH_ML_DSA_44_WITH_SHA512, 9, &so[9381]}, - {"id-hash-ml-dsa-65-with-sha512", "HASH-ML-DSA-65-WITH-SHA512", NID_HASH_ML_DSA_65_WITH_SHA512, 9, &so[9390]}, - {"id-hash-ml-dsa-87-with-sha512", "HASH-ML-DSA-87-WITH-SHA512", NID_HASH_ML_DSA_87_WITH_SHA512, 9, &so[9399]}, - {"id-hash-slh-dsa-sha2-128s-with-sha256", "SLH-DSA-SHA2-128s-WITH-SHA256", NID_SLH_DSA_SHA2_128s_WITH_SHA256, 9, &so[9408]}, - {"id-hash-slh-dsa-sha2-128f-with-sha256", "SLH-DSA-SHA2-128f-WITH-SHA256", NID_SLH_DSA_SHA2_128f_WITH_SHA256, 9, &so[9417]}, - {"id-hash-slh-dsa-sha2-192s-with-sha512", "SLH-DSA-SHA2-192s-WITH-SHA512", NID_SLH_DSA_SHA2_192s_WITH_SHA512, 9, &so[9426]}, - {"id-hash-slh-dsa-sha2-192f-with-sha512", "SLH-DSA-SHA2-192f-WITH-SHA512", NID_SLH_DSA_SHA2_192f_WITH_SHA512, 9, &so[9435]}, - {"id-hash-slh-dsa-sha2-256s-with-sha512", "SLH-DSA-SHA2-256s-WITH-SHA512", NID_SLH_DSA_SHA2_256s_WITH_SHA512, 9, &so[9444]}, - {"id-hash-slh-dsa-sha2-256f-with-sha512", "SLH-DSA-SHA2-256f-WITH-SHA512", NID_SLH_DSA_SHA2_256f_WITH_SHA512, 9, &so[9453]}, - {"id-hash-slh-dsa-shake-128s-with-shake128", "SLH-DSA-SHAKE-128s-WITH-SHAKE128", NID_SLH_DSA_SHAKE_128s_WITH_SHAKE128, 9, &so[9462]}, - {"id-hash-slh-dsa-shake-128f-with-shake128", "SLH-DSA-SHAKE-128f-WITH-SHAKE128", NID_SLH_DSA_SHAKE_128f_WITH_SHAKE128, 9, &so[9471]}, - {"id-hash-slh-dsa-shake-192s-with-shake256", "SLH-DSA-SHAKE-192s-WITH-SHAKE256", NID_SLH_DSA_SHAKE_192s_WITH_SHAKE256, 9, &so[9480]}, - {"id-hash-slh-dsa-shake-192f-with-shake256", "SLH-DSA-SHAKE-192f-WITH-SHAKE256", NID_SLH_DSA_SHAKE_192f_WITH_SHAKE256, 9, &so[9489]}, - {"id-hash-slh-dsa-shake-256s-with-shake256", "SLH-DSA-SHAKE-256s-WITH-SHAKE256", NID_SLH_DSA_SHAKE_256s_WITH_SHAKE256, 9, &so[9498]}, - {"id-hash-slh-dsa-shake-256f-with-shake256", "SLH-DSA-SHAKE-256f-WITH-SHAKE256", NID_SLH_DSA_SHAKE_256f_WITH_SHAKE256, 9, &so[9507]}, - {"AES-128-CBC-HMAC-SHA1-ETM", "aes-128-cbc-hmac-sha1-etm", NID_aes_128_cbc_hmac_sha1_etm}, - {"AES-192-CBC-HMAC-SHA1-ETM", "aes-192-cbc-hmac-sha1-etm", NID_aes_192_cbc_hmac_sha1_etm}, - {"AES-256-CBC-HMAC-SHA1-ETM", "aes-256-cbc-hmac-sha1-etm", NID_aes_256_cbc_hmac_sha1_etm}, - {"AES-128-CBC-HMAC-SHA256-ETM", "aes-128-cbc-hmac-sha256-etm", NID_aes_128_cbc_hmac_sha256_etm}, - {"AES-192-CBC-HMAC-SHA256-ETM", "aes-192-cbc-hmac-sha256-etm", NID_aes_192_cbc_hmac_sha256_etm}, - {"AES-256-CBC-HMAC-SHA256-ETM", "aes-256-cbc-hmac-sha256-etm", NID_aes_256_cbc_hmac_sha256_etm}, - {"AES-128-CBC-HMAC-SHA512-ETM", "aes-128-cbc-hmac-sha512-etm", NID_aes_128_cbc_hmac_sha512_etm}, - {"AES-192-CBC-HMAC-SHA512-ETM", "aes-192-cbc-hmac-sha512-etm", NID_aes_192_cbc_hmac_sha512_etm}, - {"AES-256-CBC-HMAC-SHA512-ETM", "aes-256-cbc-hmac-sha512-etm", NID_aes_256_cbc_hmac_sha512_etm}, - {"id-alg-hkdf-with-sha256", "HKDF-SHA256", NID_HKDF_SHA256, 11, &so[9516]}, - {"id-alg-hkdf-with-sha384", "HKDF-SHA384", NID_HKDF_SHA384, 11, &so[9527]}, - {"id-alg-hkdf-with-sha512", "HKDF-SHA512", NID_HKDF_SHA512, 11, &so[9538]}, - {"id-smime-ori", "id-smime-ori", NID_id_smime_ori, 10, &so[9549]}, - {"id-smime-ori-kem", "id-smime-ori-kem", NID_id_smime_ori_kem, 11, &so[9559]}, - {"id-alg-hss-lms-hashsig", "id-alg-hss-lms-hashsig", NID_id_alg_hss_lms_hashsig, 11, &so[9570]}, -}; - -#define NUM_SN 1493 -static const unsigned int sn_objs[NUM_SN] = { - 364, /* "AD_DVCS" */ - 419, /* "AES-128-CBC" */ - 916, /* "AES-128-CBC-HMAC-SHA1" */ - 1487, /* "AES-128-CBC-HMAC-SHA1-ETM" */ - 948, /* "AES-128-CBC-HMAC-SHA256" */ - 1490, /* "AES-128-CBC-HMAC-SHA256-ETM" */ - 1493, /* "AES-128-CBC-HMAC-SHA512-ETM" */ - 421, /* "AES-128-CFB" */ - 650, /* "AES-128-CFB1" */ - 653, /* "AES-128-CFB8" */ - 904, /* "AES-128-CTR" */ - 418, /* "AES-128-ECB" */ - 958, /* "AES-128-OCB" */ - 420, /* "AES-128-OFB" */ - 1198, /* "AES-128-SIV" */ - 913, /* "AES-128-XTS" */ - 423, /* "AES-192-CBC" */ - 917, /* "AES-192-CBC-HMAC-SHA1" */ - 1488, /* "AES-192-CBC-HMAC-SHA1-ETM" */ - 949, /* "AES-192-CBC-HMAC-SHA256" */ - 1491, /* "AES-192-CBC-HMAC-SHA256-ETM" */ - 1494, /* "AES-192-CBC-HMAC-SHA512-ETM" */ - 425, /* "AES-192-CFB" */ - 651, /* "AES-192-CFB1" */ - 654, /* "AES-192-CFB8" */ - 905, /* "AES-192-CTR" */ - 422, /* "AES-192-ECB" */ - 959, /* "AES-192-OCB" */ - 424, /* "AES-192-OFB" */ - 1199, /* "AES-192-SIV" */ - 427, /* "AES-256-CBC" */ - 918, /* "AES-256-CBC-HMAC-SHA1" */ - 1489, /* "AES-256-CBC-HMAC-SHA1-ETM" */ - 950, /* "AES-256-CBC-HMAC-SHA256" */ - 1492, /* "AES-256-CBC-HMAC-SHA256-ETM" */ - 1495, /* "AES-256-CBC-HMAC-SHA512-ETM" */ - 429, /* "AES-256-CFB" */ - 652, /* "AES-256-CFB1" */ - 655, /* "AES-256-CFB8" */ - 906, /* "AES-256-CTR" */ - 426, /* "AES-256-ECB" */ - 960, /* "AES-256-OCB" */ - 428, /* "AES-256-OFB" */ - 1200, /* "AES-256-SIV" */ - 914, /* "AES-256-XTS" */ - 1066, /* "ARIA-128-CBC" */ - 1120, /* "ARIA-128-CCM" */ - 1067, /* "ARIA-128-CFB" */ - 1080, /* "ARIA-128-CFB1" */ - 1083, /* "ARIA-128-CFB8" */ - 1069, /* "ARIA-128-CTR" */ - 1065, /* "ARIA-128-ECB" */ - 1123, /* "ARIA-128-GCM" */ - 1068, /* "ARIA-128-OFB" */ - 1071, /* "ARIA-192-CBC" */ - 1121, /* "ARIA-192-CCM" */ - 1072, /* "ARIA-192-CFB" */ - 1081, /* "ARIA-192-CFB1" */ - 1084, /* "ARIA-192-CFB8" */ - 1074, /* "ARIA-192-CTR" */ - 1070, /* "ARIA-192-ECB" */ - 1124, /* "ARIA-192-GCM" */ - 1073, /* "ARIA-192-OFB" */ - 1076, /* "ARIA-256-CBC" */ - 1122, /* "ARIA-256-CCM" */ - 1077, /* "ARIA-256-CFB" */ - 1082, /* "ARIA-256-CFB1" */ - 1085, /* "ARIA-256-CFB8" */ - 1079, /* "ARIA-256-CTR" */ - 1075, /* "ARIA-256-ECB" */ - 1125, /* "ARIA-256-GCM" */ - 1078, /* "ARIA-256-OFB" */ - 1064, /* "AuthANY" */ - 1049, /* "AuthDSS" */ - 1047, /* "AuthECDSA" */ - 1050, /* "AuthGOST01" */ - 1051, /* "AuthGOST12" */ - 1053, /* "AuthNULL" */ - 1048, /* "AuthPSK" */ - 1046, /* "AuthRSA" */ - 1052, /* "AuthSRP" */ - 91, /* "BF-CBC" */ - 93, /* "BF-CFB" */ - 92, /* "BF-ECB" */ - 94, /* "BF-OFB" */ - 1201, /* "BLAKE2BMAC" */ - 1202, /* "BLAKE2SMAC" */ - 1056, /* "BLAKE2b512" */ - 1057, /* "BLAKE2s256" */ - 14, /* "C" */ - 751, /* "CAMELLIA-128-CBC" */ - 962, /* "CAMELLIA-128-CCM" */ - 757, /* "CAMELLIA-128-CFB" */ - 760, /* "CAMELLIA-128-CFB1" */ - 763, /* "CAMELLIA-128-CFB8" */ - 964, /* "CAMELLIA-128-CMAC" */ - 963, /* "CAMELLIA-128-CTR" */ - 754, /* "CAMELLIA-128-ECB" */ - 961, /* "CAMELLIA-128-GCM" */ - 766, /* "CAMELLIA-128-OFB" */ - 752, /* "CAMELLIA-192-CBC" */ - 966, /* "CAMELLIA-192-CCM" */ - 758, /* "CAMELLIA-192-CFB" */ - 761, /* "CAMELLIA-192-CFB1" */ - 764, /* "CAMELLIA-192-CFB8" */ - 968, /* "CAMELLIA-192-CMAC" */ - 967, /* "CAMELLIA-192-CTR" */ - 755, /* "CAMELLIA-192-ECB" */ - 965, /* "CAMELLIA-192-GCM" */ - 767, /* "CAMELLIA-192-OFB" */ - 753, /* "CAMELLIA-256-CBC" */ - 970, /* "CAMELLIA-256-CCM" */ - 759, /* "CAMELLIA-256-CFB" */ - 762, /* "CAMELLIA-256-CFB1" */ - 765, /* "CAMELLIA-256-CFB8" */ - 972, /* "CAMELLIA-256-CMAC" */ - 971, /* "CAMELLIA-256-CTR" */ - 756, /* "CAMELLIA-256-ECB" */ - 969, /* "CAMELLIA-256-GCM" */ - 768, /* "CAMELLIA-256-OFB" */ - 108, /* "CAST5-CBC" */ - 110, /* "CAST5-CFB" */ - 109, /* "CAST5-ECB" */ - 111, /* "CAST5-OFB" */ - 894, /* "CMAC" */ - 13, /* "CN" */ - 141, /* "CRLReason" */ - 417, /* "CSPName" */ - 1019, /* "ChaCha20" */ - 1018, /* "ChaCha20-Poly1305" */ - 367, /* "CrlID" */ - 391, /* "DC" */ - 31, /* "DES-CBC" */ - 643, /* "DES-CDMF" */ - 30, /* "DES-CFB" */ - 656, /* "DES-CFB1" */ - 657, /* "DES-CFB8" */ - 29, /* "DES-ECB" */ - 32, /* "DES-EDE" */ - 43, /* "DES-EDE-CBC" */ - 60, /* "DES-EDE-CFB" */ - 62, /* "DES-EDE-OFB" */ - 33, /* "DES-EDE3" */ - 44, /* "DES-EDE3-CBC" */ - 61, /* "DES-EDE3-CFB" */ - 658, /* "DES-EDE3-CFB1" */ - 659, /* "DES-EDE3-CFB8" */ - 63, /* "DES-EDE3-OFB" */ - 45, /* "DES-OFB" */ - 80, /* "DESX-CBC" */ - 380, /* "DOD" */ - 116, /* "DSA" */ - 66, /* "DSA-SHA" */ - 113, /* "DSA-SHA1" */ - 70, /* "DSA-SHA1-old" */ - 67, /* "DSA-old" */ - 297, /* "DVCS" */ - 1087, /* "ED25519" */ - 1088, /* "ED448" */ - 1195, /* "GMAC" */ - 99, /* "GN" */ - 1036, /* "HKDF" */ - 855, /* "HMAC" */ - 780, /* "HMAC-MD5" */ - 781, /* "HMAC-SHA1" */ - 381, /* "IANA" */ - 34, /* "IDEA-CBC" */ - 35, /* "IDEA-CFB" */ - 36, /* "IDEA-ECB" */ - 46, /* "IDEA-OFB" */ - 1004, /* "INN" */ - 181, /* "ISO" */ - 1140, /* "ISO-CN" */ - 1150, /* "ISO-UA" */ - 183, /* "ISO-US" */ - 645, /* "ITU-T" */ - 646, /* "JOINT-ISO-ITU-T" */ - 773, /* "KISA" */ - 1196, /* "KMAC128" */ - 1197, /* "KMAC256" */ - 1063, /* "KxANY" */ - 1039, /* "KxDHE" */ - 1041, /* "KxDHE-PSK" */ - 1038, /* "KxECDHE" */ - 1040, /* "KxECDHE-PSK" */ - 1045, /* "KxGOST" */ - 1218, /* "KxGOST18" */ - 1043, /* "KxPSK" */ - 1037, /* "KxRSA" */ - 1042, /* "KxRSA_PSK" */ - 1044, /* "KxSRP" */ - 15, /* "L" */ - 856, /* "LocalKeySet" */ - 3, /* "MD2" */ - 257, /* "MD4" */ - 4, /* "MD5" */ - 114, /* "MD5-SHA1" */ - 95, /* "MDC2" */ - 911, /* "MGF1" */ - 388, /* "Mail" */ - 393, /* "NULL" */ - 404, /* "NULL" */ - 1323, /* "NULL" */ - 57, /* "Netscape" */ - 366, /* "Nonce" */ - 17, /* "O" */ - 178, /* "OCSP" */ - 180, /* "OCSPSigning" */ - 1005, /* "OGRN" */ - 1226, /* "OGRNIP" */ - 379, /* "ORG" */ - 18, /* "OU" */ - 749, /* "Oakley-EC2N-3" */ - 750, /* "Oakley-EC2N-4" */ - 9, /* "PBE-MD2-DES" */ - 168, /* "PBE-MD2-RC2-64" */ - 10, /* "PBE-MD5-DES" */ - 169, /* "PBE-MD5-RC2-64" */ - 147, /* "PBE-SHA1-2DES" */ - 146, /* "PBE-SHA1-3DES" */ - 170, /* "PBE-SHA1-DES" */ - 148, /* "PBE-SHA1-RC2-128" */ - 149, /* "PBE-SHA1-RC2-40" */ - 68, /* "PBE-SHA1-RC2-64" */ - 144, /* "PBE-SHA1-RC4-128" */ - 145, /* "PBE-SHA1-RC4-40" */ - 161, /* "PBES2" */ - 69, /* "PBKDF2" */ - 162, /* "PBMAC1" */ - 127, /* "PKIX" */ - 935, /* "PSPECIFIED" */ - 1061, /* "Poly1305" */ - 98, /* "RC2-40-CBC" */ - 166, /* "RC2-64-CBC" */ - 37, /* "RC2-CBC" */ - 39, /* "RC2-CFB" */ - 38, /* "RC2-ECB" */ - 40, /* "RC2-OFB" */ - 5, /* "RC4" */ - 97, /* "RC4-40" */ - 915, /* "RC4-HMAC-MD5" */ - 120, /* "RC5-CBC" */ - 122, /* "RC5-CFB" */ - 121, /* "RC5-ECB" */ - 123, /* "RC5-OFB" */ - 117, /* "RIPEMD160" */ - 19, /* "RSA" */ - 7, /* "RSA-MD2" */ - 396, /* "RSA-MD4" */ - 8, /* "RSA-MD5" */ - 96, /* "RSA-MDC2" */ - 104, /* "RSA-NP-MD5" */ - 119, /* "RSA-RIPEMD160" */ - 42, /* "RSA-SHA" */ - 65, /* "RSA-SHA1" */ - 115, /* "RSA-SHA1-2" */ - 671, /* "RSA-SHA224" */ - 668, /* "RSA-SHA256" */ - 669, /* "RSA-SHA384" */ - 670, /* "RSA-SHA512" */ - 1145, /* "RSA-SHA512/224" */ - 1146, /* "RSA-SHA512/256" */ - 1144, /* "RSA-SM3" */ - 919, /* "RSAES-OAEP" */ - 912, /* "RSASSA-PSS" */ - 777, /* "SEED-CBC" */ - 779, /* "SEED-CFB" */ - 776, /* "SEED-ECB" */ - 778, /* "SEED-OFB" */ - 41, /* "SHA" */ - 64, /* "SHA1" */ - 675, /* "SHA224" */ - 672, /* "SHA256" */ - 1096, /* "SHA3-224" */ - 1097, /* "SHA3-256" */ - 1098, /* "SHA3-384" */ - 1099, /* "SHA3-512" */ - 673, /* "SHA384" */ - 674, /* "SHA512" */ - 1094, /* "SHA512-224" */ - 1095, /* "SHA512-256" */ - 1100, /* "SHAKE128" */ - 1101, /* "SHAKE256" */ - 1172, /* "SM2" */ - 1204, /* "SM2-SM3" */ - 1143, /* "SM3" */ - 1134, /* "SM4-CBC" */ - 1249, /* "SM4-CCM" */ - 1137, /* "SM4-CFB" */ - 1136, /* "SM4-CFB1" */ - 1138, /* "SM4-CFB8" */ - 1139, /* "SM4-CTR" */ - 1133, /* "SM4-ECB" */ - 1248, /* "SM4-GCM" */ - 1135, /* "SM4-OFB" */ - 1290, /* "SM4-XTS" */ - 188, /* "SMIME" */ - 167, /* "SMIME-CAPS" */ - 100, /* "SN" */ - 1006, /* "SNILS" */ - 1203, /* "SSHKDF" */ - 1205, /* "SSKDF" */ - 16, /* "ST" */ - 143, /* "SXNetID" */ - 1062, /* "SipHash" */ - 1021, /* "TLS1-PRF" */ - 458, /* "UID" */ - 0, /* "UNDEF" */ - 1034, /* "X25519" */ - 1035, /* "X448" */ - 11, /* "X500" */ - 378, /* "X500algorithms" */ - 12, /* "X509" */ - 184, /* "X9-57" */ - 1207, /* "X942KDF" */ - 1206, /* "X963KDF" */ - 185, /* "X9cm" */ - 125, /* "ZLIB" */ - 1307, /* "aAissuingDistributionPoint" */ - 478, /* "aRecord" */ - 289, /* "aaControls" */ - 287, /* "ac-auditIdentity" */ - 397, /* "ac-proxying" */ - 288, /* "ac-targeting" */ - 1303, /* "acceptableCertPolicies" */ - 1304, /* "acceptablePrivPolicies" */ - 368, /* "acceptableResponses" */ - 446, /* "account" */ - 363, /* "ad_timestamping" */ - 376, /* "algorithm" */ - 1311, /* "allowedAttributeAssignments" */ - 1317, /* "altSignatureAlgorithm" */ - 1318, /* "altSignatureValue" */ - 405, /* "ansi-X9-62" */ - 910, /* "anyExtendedKeyUsage" */ - 746, /* "anyPolicy" */ - 370, /* "archiveCutoff" */ - 484, /* "associatedDomain" */ - 1319, /* "associatedInformation" */ - 485, /* "associatedName" */ - 1300, /* "attributeDescriptor" */ - 1312, /* "attributeMappings" */ - 501, /* "audio" */ - 1295, /* "authorityAttributeIdentifier" */ - 177, /* "authorityInfoAccess" */ - 90, /* "authorityKeyIdentifier" */ - 882, /* "authorityRevocationList" */ - 1314, /* "authorizationValidation" */ - 1297, /* "basicAttConstraints" */ - 87, /* "basicConstraints" */ - 365, /* "basicOCSPResponse" */ - 285, /* "biometricInfo" */ - 921, /* "brainpoolP160r1" */ - 922, /* "brainpoolP160t1" */ - 923, /* "brainpoolP192r1" */ - 924, /* "brainpoolP192t1" */ - 925, /* "brainpoolP224r1" */ - 926, /* "brainpoolP224t1" */ - 927, /* "brainpoolP256r1" */ - 1285, /* "brainpoolP256r1tls13" */ - 928, /* "brainpoolP256t1" */ - 929, /* "brainpoolP320r1" */ - 930, /* "brainpoolP320t1" */ - 931, /* "brainpoolP384r1" */ - 1286, /* "brainpoolP384r1tls13" */ - 932, /* "brainpoolP384t1" */ - 933, /* "brainpoolP512r1" */ - 1287, /* "brainpoolP512r1tls13" */ - 934, /* "brainpoolP512t1" */ - 1288, /* "brotli" */ - 494, /* "buildingName" */ - 860, /* "businessCategory" */ - 691, /* "c2onb191v4" */ - 692, /* "c2onb191v5" */ - 697, /* "c2onb239v4" */ - 698, /* "c2onb239v5" */ - 684, /* "c2pnb163v1" */ - 685, /* "c2pnb163v2" */ - 686, /* "c2pnb163v3" */ - 687, /* "c2pnb176v1" */ - 693, /* "c2pnb208w1" */ - 699, /* "c2pnb272w1" */ - 700, /* "c2pnb304w1" */ - 702, /* "c2pnb368w1" */ - 688, /* "c2tnb191v1" */ - 689, /* "c2tnb191v2" */ - 690, /* "c2tnb191v3" */ - 694, /* "c2tnb239v1" */ - 695, /* "c2tnb239v2" */ - 696, /* "c2tnb239v3" */ - 701, /* "c2tnb359v1" */ - 703, /* "c2tnb431r1" */ - 1090, /* "c3" */ - 881, /* "cACertificate" */ - 483, /* "cNAMERecord" */ - 179, /* "caIssuers" */ - 785, /* "caRepository" */ - 1273, /* "cades" */ - 1274, /* "cades-attributes" */ - 1023, /* "capwapAC" */ - 1024, /* "capwapWTP" */ - 443, /* "caseIgnoreIA5StringSyntax" */ - 152, /* "certBag" */ - 677, /* "certicom-arc" */ - 771, /* "certificateIssuer" */ - 89, /* "certificatePolicies" */ - 883, /* "certificateRevocationList" */ - 54, /* "challengePassword" */ - 407, /* "characteristic-two-field" */ - 1227, /* "classSignTool" */ - 1233, /* "classSignToolKA1" */ - 1231, /* "classSignToolKB1" */ - 1232, /* "classSignToolKB2" */ - 1228, /* "classSignToolKC1" */ - 1229, /* "classSignToolKC2" */ - 1230, /* "classSignToolKC3" */ - 395, /* "clearance" */ - 130, /* "clientAuth" */ - 1222, /* "cmKGA" */ - 1219, /* "cmcArchive" */ - 1131, /* "cmcCA" */ - 1132, /* "cmcRA" */ - 131, /* "codeSigning" */ - 50, /* "contentType" */ - 53, /* "countersignature" */ - 153, /* "crlBag" */ - 103, /* "crlDistributionPoints" */ - 88, /* "crlNumber" */ - 884, /* "crossCertificatePair" */ - 806, /* "cryptocom" */ - 805, /* "cryptopro" */ - 954, /* "ct_cert_scts" */ - 952, /* "ct_precert_poison" */ - 951, /* "ct_precert_scts" */ - 953, /* "ct_precert_signer" */ - 500, /* "dITRedirect" */ - 451, /* "dNSDomain" */ - 495, /* "dSAQuality" */ - 434, /* "data" */ - 390, /* "dcobject" */ - 1298, /* "delegatedNameConstraints" */ - 140, /* "deltaCRL" */ - 891, /* "deltaRevocationList" */ - 107, /* "description" */ - 871, /* "destinationIndicator" */ - 947, /* "dh-cofactor-kdf" */ - 946, /* "dh-std-kdf" */ - 28, /* "dhKeyAgreement" */ - 941, /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */ - 942, /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */ - 943, /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */ - 944, /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */ - 945, /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */ - 936, /* "dhSinglePass-stdDH-sha1kdf-scheme" */ - 937, /* "dhSinglePass-stdDH-sha224kdf-scheme" */ - 938, /* "dhSinglePass-stdDH-sha256kdf-scheme" */ - 939, /* "dhSinglePass-stdDH-sha384kdf-scheme" */ - 940, /* "dhSinglePass-stdDH-sha512kdf-scheme" */ - 920, /* "dhpublicnumber" */ - 382, /* "directory" */ - 887, /* "distinguishedName" */ - 892, /* "dmdName" */ - 174, /* "dnQualifier" */ - 1092, /* "dnsName" */ - 447, /* "document" */ - 471, /* "documentAuthor" */ - 468, /* "documentIdentifier" */ - 472, /* "documentLocation" */ - 502, /* "documentPublisher" */ - 449, /* "documentSeries" */ - 469, /* "documentTitle" */ - 470, /* "documentVersion" */ - 392, /* "domain" */ - 452, /* "domainRelatedObject" */ - 802, /* "dsa_with_SHA224" */ - 803, /* "dsa_with_SHA256" */ - 1152, /* "dstu28147" */ - 1154, /* "dstu28147-cfb" */ - 1153, /* "dstu28147-ofb" */ - 1155, /* "dstu28147-wrap" */ - 1157, /* "dstu34311" */ - 1159, /* "dstu4145be" */ - 1158, /* "dstu4145le" */ - 791, /* "ecdsa-with-Recommended" */ - 416, /* "ecdsa-with-SHA1" */ - 793, /* "ecdsa-with-SHA224" */ - 794, /* "ecdsa-with-SHA256" */ - 795, /* "ecdsa-with-SHA384" */ - 796, /* "ecdsa-with-SHA512" */ - 792, /* "ecdsa-with-Specified" */ - 1266, /* "electronic-signature-standard" */ - 48, /* "emailAddress" */ - 132, /* "emailProtection" */ - 885, /* "enhancedSearchGuide" */ - 389, /* "enterprises" */ - 1267, /* "ess-attributes" */ - 1265, /* "etsi" */ - 384, /* "experimental" */ - 172, /* "extReq" */ - 56, /* "extendedCertificateAttributes" */ - 126, /* "extendedKeyUsage" */ - 372, /* "extendedStatus" */ - 867, /* "facsimileTelephoneNumber" */ - 462, /* "favouriteDrink" */ - 1126, /* "ffdhe2048" */ - 1127, /* "ffdhe3072" */ - 1128, /* "ffdhe4096" */ - 1129, /* "ffdhe6144" */ - 1130, /* "ffdhe8192" */ - 857, /* "freshestCRL" */ - 453, /* "friendlyCountry" */ - 490, /* "friendlyCountryName" */ - 156, /* "friendlyName" */ - 509, /* "generationQualifier" */ - 815, /* "gost-mac" */ - 976, /* "gost-mac-12" */ - 811, /* "gost2001" */ - 851, /* "gost2001cc" */ - 979, /* "gost2012_256" */ - 980, /* "gost2012_512" */ - 813, /* "gost89" */ - 1009, /* "gost89-cbc" */ - 814, /* "gost89-cnt" */ - 975, /* "gost89-cnt-12" */ - 1011, /* "gost89-ctr" */ - 1010, /* "gost89-ecb" */ - 812, /* "gost94" */ - 850, /* "gost94cc" */ - 1310, /* "groupAC" */ - 1156, /* "hmacWithDstu34311" */ - 797, /* "hmacWithMD5" */ - 163, /* "hmacWithSHA1" */ - 798, /* "hmacWithSHA224" */ - 799, /* "hmacWithSHA256" */ - 800, /* "hmacWithSHA384" */ - 801, /* "hmacWithSHA512" */ - 1193, /* "hmacWithSHA512-224" */ - 1194, /* "hmacWithSHA512-256" */ - 1281, /* "hmacWithSM3" */ - 432, /* "holdInstructionCallIssuer" */ - 430, /* "holdInstructionCode" */ - 431, /* "holdInstructionNone" */ - 433, /* "holdInstructionReject" */ - 1313, /* "holderNameConstraints" */ - 486, /* "homePostalAddress" */ - 473, /* "homeTelephoneNumber" */ - 466, /* "host" */ - 889, /* "houseIdentifier" */ - 442, /* "iA5StringSyntax" */ - 783, /* "id-DHBasedMac" */ - 824, /* "id-Gost28147-89-CryptoPro-A-ParamSet" */ - 825, /* "id-Gost28147-89-CryptoPro-B-ParamSet" */ - 826, /* "id-Gost28147-89-CryptoPro-C-ParamSet" */ - 827, /* "id-Gost28147-89-CryptoPro-D-ParamSet" */ - 819, /* "id-Gost28147-89-CryptoPro-KeyMeshing" */ - 829, /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */ - 828, /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */ - 830, /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */ - 820, /* "id-Gost28147-89-None-KeyMeshing" */ - 823, /* "id-Gost28147-89-TestParamSet" */ - 849, /* "id-Gost28147-89-cc" */ - 840, /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */ - 841, /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */ - 842, /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */ - 843, /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */ - 844, /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */ - 854, /* "id-GostR3410-2001-ParamSet-cc" */ - 839, /* "id-GostR3410-2001-TestParamSet" */ - 817, /* "id-GostR3410-2001DH" */ - 832, /* "id-GostR3410-94-CryptoPro-A-ParamSet" */ - 833, /* "id-GostR3410-94-CryptoPro-B-ParamSet" */ - 834, /* "id-GostR3410-94-CryptoPro-C-ParamSet" */ - 835, /* "id-GostR3410-94-CryptoPro-D-ParamSet" */ - 836, /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */ - 837, /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */ - 838, /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */ - 831, /* "id-GostR3410-94-TestParamSet" */ - 845, /* "id-GostR3410-94-a" */ - 846, /* "id-GostR3410-94-aBis" */ - 847, /* "id-GostR3410-94-b" */ - 848, /* "id-GostR3410-94-bBis" */ - 818, /* "id-GostR3410-94DH" */ - 822, /* "id-GostR3411-94-CryptoProParamSet" */ - 821, /* "id-GostR3411-94-TestParamSet" */ - 807, /* "id-GostR3411-94-with-GostR3410-2001" */ - 853, /* "id-GostR3411-94-with-GostR3410-2001-cc" */ - 808, /* "id-GostR3411-94-with-GostR3410-94" */ - 852, /* "id-GostR3411-94-with-GostR3410-94-cc" */ - 810, /* "id-HMACGostR3411-94" */ - 782, /* "id-PasswordBasedMAC" */ - 1272, /* "id-aa-ATSHashIndex" */ - 1277, /* "id-aa-ATSHashIndex-v2" */ - 1278, /* "id-aa-ATSHashIndex-v3" */ - 1263, /* "id-aa-CMSAlgorithmProtection" */ - 1270, /* "id-aa-ets-SignaturePolicyDocument" */ - 1280, /* "id-aa-ets-archiveTimestampV2" */ - 1271, /* "id-aa-ets-archiveTimestampV3" */ - 1261, /* "id-aa-ets-attrCertificateRefs" */ - 1262, /* "id-aa-ets-attrRevocationRefs" */ - 1269, /* "id-aa-ets-longTermValidation" */ - 1268, /* "id-aa-ets-mimeType" */ - 1276, /* "id-aa-ets-sigPolicyStore" */ - 1275, /* "id-aa-ets-signerAttrV2" */ - 266, /* "id-aca" */ - 355, /* "id-aca-accessIdentity" */ - 354, /* "id-aca-authenticationInfo" */ - 356, /* "id-aca-chargingIdentity" */ - 399, /* "id-aca-encAttrs" */ - 357, /* "id-aca-group" */ - 358, /* "id-aca-role" */ - 176, /* "id-ad" */ - 896, /* "id-aes128-CCM" */ - 895, /* "id-aes128-GCM" */ - 788, /* "id-aes128-wrap" */ - 897, /* "id-aes128-wrap-pad" */ - 899, /* "id-aes192-CCM" */ - 898, /* "id-aes192-GCM" */ - 789, /* "id-aes192-wrap" */ - 900, /* "id-aes192-wrap-pad" */ - 902, /* "id-aes256-CCM" */ - 901, /* "id-aes256-GCM" */ - 790, /* "id-aes256-wrap" */ - 903, /* "id-aes256-wrap-pad" */ - 262, /* "id-alg" */ - 893, /* "id-alg-PWRI-KEK" */ - 323, /* "id-alg-des40" */ - 326, /* "id-alg-dh-pop" */ - 325, /* "id-alg-dh-sig-hmac-sha1" */ - 1496, /* "id-alg-hkdf-with-sha256" */ - 1497, /* "id-alg-hkdf-with-sha384" */ - 1498, /* "id-alg-hkdf-with-sha512" */ - 1501, /* "id-alg-hss-lms-hashsig" */ - 1456, /* "id-alg-ml-kem-1024" */ - 1454, /* "id-alg-ml-kem-512" */ - 1455, /* "id-alg-ml-kem-768" */ - 324, /* "id-alg-noSignature" */ - 907, /* "id-camellia128-wrap" */ - 908, /* "id-camellia192-wrap" */ - 909, /* "id-camellia256-wrap" */ - 268, /* "id-cct" */ - 361, /* "id-cct-PKIData" */ - 362, /* "id-cct-PKIResponse" */ - 360, /* "id-cct-crs" */ - 81, /* "id-ce" */ - 680, /* "id-characteristic-two-basis" */ - 263, /* "id-cmc" */ - 334, /* "id-cmc-addExtensions" */ - 346, /* "id-cmc-confirmCertAcceptance" */ - 330, /* "id-cmc-dataReturn" */ - 336, /* "id-cmc-decryptedPOP" */ - 335, /* "id-cmc-encryptedPOP" */ - 339, /* "id-cmc-getCRL" */ - 338, /* "id-cmc-getCert" */ - 328, /* "id-cmc-identification" */ - 329, /* "id-cmc-identityProof" */ - 337, /* "id-cmc-lraPOPWitness" */ - 344, /* "id-cmc-popLinkRandom" */ - 345, /* "id-cmc-popLinkWitness" */ - 343, /* "id-cmc-queryPending" */ - 333, /* "id-cmc-recipientNonce" */ - 341, /* "id-cmc-regInfo" */ - 342, /* "id-cmc-responseInfo" */ - 340, /* "id-cmc-revokeRequest" */ - 332, /* "id-cmc-senderNonce" */ - 327, /* "id-cmc-statusInfo" */ - 331, /* "id-cmc-transactionId" */ - 1238, /* "id-cp" */ - 1250, /* "id-ct-ASPA" */ - 787, /* "id-ct-asciiTextWithCRLF" */ - 1246, /* "id-ct-geofeedCSVwithCRLF" */ - 1237, /* "id-ct-resourceTaggedAttest" */ - 1234, /* "id-ct-routeOriginAuthz" */ - 1236, /* "id-ct-rpkiGhostbusters" */ - 1235, /* "id-ct-rpkiManifest" */ - 1320, /* "id-ct-rpkiSignedPrefixList" */ - 1247, /* "id-ct-signedChecklist" */ - 1284, /* "id-ct-signedTAL" */ - 1060, /* "id-ct-xml" */ - 1108, /* "id-dsa-with-sha3-224" */ - 1109, /* "id-dsa-with-sha3-256" */ - 1110, /* "id-dsa-with-sha3-384" */ - 1111, /* "id-dsa-with-sha3-512" */ - 1106, /* "id-dsa-with-sha384" */ - 1107, /* "id-dsa-with-sha512" */ - 408, /* "id-ecPublicKey" */ - 1112, /* "id-ecdsa-with-sha3-224" */ - 1113, /* "id-ecdsa-with-sha3-256" */ - 1114, /* "id-ecdsa-with-sha3-384" */ - 1115, /* "id-ecdsa-with-sha3-512" */ - 1472, /* "id-hash-ml-dsa-44-with-sha512" */ - 1473, /* "id-hash-ml-dsa-65-with-sha512" */ - 1474, /* "id-hash-ml-dsa-87-with-sha512" */ - 1476, /* "id-hash-slh-dsa-sha2-128f-with-sha256" */ - 1475, /* "id-hash-slh-dsa-sha2-128s-with-sha256" */ - 1478, /* "id-hash-slh-dsa-sha2-192f-with-sha512" */ - 1477, /* "id-hash-slh-dsa-sha2-192s-with-sha512" */ - 1480, /* "id-hash-slh-dsa-sha2-256f-with-sha512" */ - 1479, /* "id-hash-slh-dsa-sha2-256s-with-sha512" */ - 1482, /* "id-hash-slh-dsa-shake-128f-with-shake128" */ - 1481, /* "id-hash-slh-dsa-shake-128s-with-shake128" */ - 1484, /* "id-hash-slh-dsa-shake-192f-with-shake256" */ - 1483, /* "id-hash-slh-dsa-shake-192s-with-shake256" */ - 1486, /* "id-hash-slh-dsa-shake-256f-with-shake256" */ - 1485, /* "id-hash-slh-dsa-shake-256s-with-shake256" */ - 508, /* "id-hex-multipart-message" */ - 507, /* "id-hex-partial-message" */ - 1102, /* "id-hmacWithSHA3-224" */ - 1103, /* "id-hmacWithSHA3-256" */ - 1104, /* "id-hmacWithSHA3-384" */ - 1105, /* "id-hmacWithSHA3-512" */ - 260, /* "id-it" */ - 1223, /* "id-it-caCerts" */ - 302, /* "id-it-caKeyUpdateInfo" */ - 298, /* "id-it-caProtEncCert" */ - 1255, /* "id-it-certProfile" */ - 1225, /* "id-it-certReqTemplate" */ - 311, /* "id-it-confirmWaitTime" */ - 1256, /* "id-it-crlStatusList" */ - 1257, /* "id-it-crls" */ - 303, /* "id-it-currentCRL" */ - 300, /* "id-it-encKeyPairTypes" */ - 310, /* "id-it-implicitConfirm" */ - 308, /* "id-it-keyPairParamRep" */ - 307, /* "id-it-keyPairParamReq" */ - 312, /* "id-it-origPKIMessage" */ - 301, /* "id-it-preferredSymmAlg" */ - 309, /* "id-it-revPassphrase" */ - 1254, /* "id-it-rootCaCert" */ - 1224, /* "id-it-rootCaKeyUpdate" */ - 299, /* "id-it-signKeyPairTypes" */ - 305, /* "id-it-subscriptionRequest" */ - 306, /* "id-it-subscriptionResponse" */ - 784, /* "id-it-suppLangTags" */ - 304, /* "id-it-unsupportedOIDs" */ - 128, /* "id-kp" */ - 1221, /* "id-kp-BrandIndicatorforMessageIdentification" */ - 1220, /* "id-kp-bgpsec-router" */ - 1322, /* "id-kp-wisun-fan-device" */ - 1457, /* "id-ml-dsa-44" */ - 1458, /* "id-ml-dsa-65" */ - 1459, /* "id-ml-dsa-87" */ - 280, /* "id-mod-attribute-cert" */ - 274, /* "id-mod-cmc" */ - 277, /* "id-mod-cmp" */ - 284, /* "id-mod-cmp2000" */ - 1251, /* "id-mod-cmp2000-02" */ - 1253, /* "id-mod-cmp2021-02" */ - 1252, /* "id-mod-cmp2021-88" */ - 273, /* "id-mod-crmf" */ - 283, /* "id-mod-dvcs" */ - 275, /* "id-mod-kea-profile-88" */ - 276, /* "id-mod-kea-profile-93" */ - 282, /* "id-mod-ocsp" */ - 278, /* "id-mod-qualified-cert-88" */ - 279, /* "id-mod-qualified-cert-93" */ - 281, /* "id-mod-timestamp-protocol" */ - 264, /* "id-on" */ - 1211, /* "id-on-NAIRealm" */ - 1208, /* "id-on-SmtpUTF8Mailbox" */ - 1210, /* "id-on-dnsSRV" */ - 1321, /* "id-on-hardwareModuleName" */ - 858, /* "id-on-permanentIdentifier" */ - 347, /* "id-on-personalData" */ - 1209, /* "id-on-xmppAddr" */ - 265, /* "id-pda" */ - 352, /* "id-pda-countryOfCitizenship" */ - 353, /* "id-pda-countryOfResidence" */ - 348, /* "id-pda-dateOfBirth" */ - 351, /* "id-pda-gender" */ - 349, /* "id-pda-placeOfBirth" */ - 175, /* "id-pe" */ - 1031, /* "id-pkinit" */ - 261, /* "id-pkip" */ - 258, /* "id-pkix-mod" */ - 269, /* "id-pkix1-explicit-88" */ - 271, /* "id-pkix1-explicit-93" */ - 270, /* "id-pkix1-implicit-88" */ - 272, /* "id-pkix1-implicit-93" */ - 662, /* "id-ppl" */ - 664, /* "id-ppl-anyLanguage" */ - 667, /* "id-ppl-independent" */ - 665, /* "id-ppl-inheritAll" */ - 267, /* "id-qcs" */ - 359, /* "id-qcs-pkixQCSyntax-v1" */ - 259, /* "id-qt" */ - 164, /* "id-qt-cps" */ - 165, /* "id-qt-unotice" */ - 313, /* "id-regCtrl" */ - 1259, /* "id-regCtrl-algId" */ - 1258, /* "id-regCtrl-altCertTemplate" */ - 316, /* "id-regCtrl-authenticator" */ - 319, /* "id-regCtrl-oldCertID" */ - 318, /* "id-regCtrl-pkiArchiveOptions" */ - 317, /* "id-regCtrl-pkiPublicationInfo" */ - 320, /* "id-regCtrl-protocolEncrKey" */ - 315, /* "id-regCtrl-regToken" */ - 1260, /* "id-regCtrl-rsaKeyLen" */ - 314, /* "id-regInfo" */ - 322, /* "id-regInfo-certReq" */ - 321, /* "id-regInfo-utf8Pairs" */ - 1116, /* "id-rsassa-pkcs1-v1_5-with-sha3-224" */ - 1117, /* "id-rsassa-pkcs1-v1_5-with-sha3-256" */ - 1118, /* "id-rsassa-pkcs1-v1_5-with-sha3-384" */ - 1119, /* "id-rsassa-pkcs1-v1_5-with-sha3-512" */ - 973, /* "id-scrypt" */ - 512, /* "id-set" */ - 1461, /* "id-slh-dsa-sha2-128f" */ - 1460, /* "id-slh-dsa-sha2-128s" */ - 1463, /* "id-slh-dsa-sha2-192f" */ - 1462, /* "id-slh-dsa-sha2-192s" */ - 1465, /* "id-slh-dsa-sha2-256f" */ - 1464, /* "id-slh-dsa-sha2-256s" */ - 1467, /* "id-slh-dsa-shake-128f" */ - 1466, /* "id-slh-dsa-shake-128s" */ - 1469, /* "id-slh-dsa-shake-192f" */ - 1468, /* "id-slh-dsa-shake-192s" */ - 1471, /* "id-slh-dsa-shake-256f" */ - 1470, /* "id-slh-dsa-shake-256s" */ - 191, /* "id-smime-aa" */ - 215, /* "id-smime-aa-contentHint" */ - 218, /* "id-smime-aa-contentIdentifier" */ - 221, /* "id-smime-aa-contentReference" */ - 240, /* "id-smime-aa-dvcs-dvc" */ - 217, /* "id-smime-aa-encapContentType" */ - 222, /* "id-smime-aa-encrypKeyPref" */ - 220, /* "id-smime-aa-equivalentLabels" */ - 232, /* "id-smime-aa-ets-CertificateRefs" */ - 233, /* "id-smime-aa-ets-RevocationRefs" */ - 238, /* "id-smime-aa-ets-archiveTimeStamp" */ - 237, /* "id-smime-aa-ets-certCRLTimestamp" */ - 234, /* "id-smime-aa-ets-certValues" */ - 227, /* "id-smime-aa-ets-commitmentType" */ - 231, /* "id-smime-aa-ets-contentTimestamp" */ - 236, /* "id-smime-aa-ets-escTimeStamp" */ - 230, /* "id-smime-aa-ets-otherSigCert" */ - 235, /* "id-smime-aa-ets-revocationValues" */ - 226, /* "id-smime-aa-ets-sigPolicyId" */ - 229, /* "id-smime-aa-ets-signerAttr" */ - 228, /* "id-smime-aa-ets-signerLocation" */ - 219, /* "id-smime-aa-macValue" */ - 214, /* "id-smime-aa-mlExpandHistory" */ - 216, /* "id-smime-aa-msgSigDigest" */ - 212, /* "id-smime-aa-receiptRequest" */ - 213, /* "id-smime-aa-securityLabel" */ - 239, /* "id-smime-aa-signatureType" */ - 223, /* "id-smime-aa-signingCertificate" */ - 1086, /* "id-smime-aa-signingCertificateV2" */ - 224, /* "id-smime-aa-smimeEncryptCerts" */ - 225, /* "id-smime-aa-timeStampToken" */ - 192, /* "id-smime-alg" */ - 243, /* "id-smime-alg-3DESwrap" */ - 246, /* "id-smime-alg-CMS3DESwrap" */ - 247, /* "id-smime-alg-CMSRC2wrap" */ - 245, /* "id-smime-alg-ESDH" */ - 241, /* "id-smime-alg-ESDHwith3DES" */ - 242, /* "id-smime-alg-ESDHwithRC2" */ - 244, /* "id-smime-alg-RC2wrap" */ - 193, /* "id-smime-cd" */ - 248, /* "id-smime-cd-ldap" */ - 190, /* "id-smime-ct" */ - 210, /* "id-smime-ct-DVCSRequestData" */ - 211, /* "id-smime-ct-DVCSResponseData" */ - 208, /* "id-smime-ct-TDTInfo" */ - 207, /* "id-smime-ct-TSTInfo" */ - 205, /* "id-smime-ct-authData" */ - 1059, /* "id-smime-ct-authEnvelopedData" */ - 786, /* "id-smime-ct-compressedData" */ - 1058, /* "id-smime-ct-contentCollection" */ - 209, /* "id-smime-ct-contentInfo" */ - 206, /* "id-smime-ct-publishCert" */ - 204, /* "id-smime-ct-receipt" */ - 195, /* "id-smime-cti" */ - 255, /* "id-smime-cti-ets-proofOfApproval" */ - 256, /* "id-smime-cti-ets-proofOfCreation" */ - 253, /* "id-smime-cti-ets-proofOfDelivery" */ - 251, /* "id-smime-cti-ets-proofOfOrigin" */ - 252, /* "id-smime-cti-ets-proofOfReceipt" */ - 254, /* "id-smime-cti-ets-proofOfSender" */ - 189, /* "id-smime-mod" */ - 196, /* "id-smime-mod-cms" */ - 197, /* "id-smime-mod-ess" */ - 202, /* "id-smime-mod-ets-eSigPolicy-88" */ - 203, /* "id-smime-mod-ets-eSigPolicy-97" */ - 200, /* "id-smime-mod-ets-eSignature-88" */ - 201, /* "id-smime-mod-ets-eSignature-97" */ - 199, /* "id-smime-mod-msg-v3" */ - 198, /* "id-smime-mod-oid" */ - 1499, /* "id-smime-ori" */ - 1500, /* "id-smime-ori-kem" */ - 194, /* "id-smime-spq" */ - 250, /* "id-smime-spq-ets-sqt-unotice" */ - 249, /* "id-smime-spq-ets-sqt-uri" */ - 974, /* "id-tc26" */ - 991, /* "id-tc26-agreement" */ - 992, /* "id-tc26-agreement-gost-3410-2012-256" */ - 993, /* "id-tc26-agreement-gost-3410-2012-512" */ - 977, /* "id-tc26-algorithms" */ - 990, /* "id-tc26-cipher" */ - 1001, /* "id-tc26-cipher-constants" */ - 1176, /* "id-tc26-cipher-gostr3412-2015-kuznyechik" */ - 1173, /* "id-tc26-cipher-gostr3412-2015-magma" */ - 994, /* "id-tc26-constants" */ - 981, /* "id-tc26-digest" */ - 1000, /* "id-tc26-digest-constants" */ - 1002, /* "id-tc26-gost-28147-constants" */ - 1003, /* "id-tc26-gost-28147-param-Z" */ - 1147, /* "id-tc26-gost-3410-2012-256-constants" */ - 1148, /* "id-tc26-gost-3410-2012-256-paramSetA" */ - 1184, /* "id-tc26-gost-3410-2012-256-paramSetB" */ - 1185, /* "id-tc26-gost-3410-2012-256-paramSetC" */ - 1186, /* "id-tc26-gost-3410-2012-256-paramSetD" */ - 996, /* "id-tc26-gost-3410-2012-512-constants" */ - 998, /* "id-tc26-gost-3410-2012-512-paramSetA" */ - 999, /* "id-tc26-gost-3410-2012-512-paramSetB" */ - 1149, /* "id-tc26-gost-3410-2012-512-paramSetC" */ - 997, /* "id-tc26-gost-3410-2012-512-paramSetTest" */ - 988, /* "id-tc26-hmac-gost-3411-2012-256" */ - 989, /* "id-tc26-hmac-gost-3411-2012-512" */ - 987, /* "id-tc26-mac" */ - 978, /* "id-tc26-sign" */ - 995, /* "id-tc26-sign-constants" */ - 984, /* "id-tc26-signwithdigest" */ - 985, /* "id-tc26-signwithdigest-gost3410-2012-256" */ - 986, /* "id-tc26-signwithdigest-gost3410-2012-512" */ - 1179, /* "id-tc26-wrap" */ - 1182, /* "id-tc26-wrap-gostr3412-2015-kuznyechik" */ - 1180, /* "id-tc26-wrap-gostr3412-2015-magma" */ - 676, /* "identified-organization" */ - 1170, /* "ieee" */ - 1171, /* "ieee-siswg" */ - 1305, /* "indirectIssuer" */ - 461, /* "info" */ - 748, /* "inhibitAnyPolicy" */ - 101, /* "initials" */ - 647, /* "international-organizations" */ - 869, /* "internationaliSDNNumber" */ - 142, /* "invalidityDate" */ - 1241, /* "ipAddr-asNumber" */ - 1242, /* "ipAddr-asNumberv2" */ - 294, /* "ipsecEndSystem" */ - 1022, /* "ipsecIKE" */ - 295, /* "ipsecTunnel" */ - 296, /* "ipsecUser" */ - 1308, /* "issuedOnBehalfOf" */ - 86, /* "issuerAltName" */ - 1008, /* "issuerSignTool" */ - 770, /* "issuingDistributionPoint" */ - 1264, /* "itu-t-identified-organization" */ - 492, /* "janetMailbox" */ - 957, /* "jurisdictionC" */ - 955, /* "jurisdictionL" */ - 956, /* "jurisdictionST" */ - 150, /* "keyBag" */ - 83, /* "keyUsage" */ - 1015, /* "kuznyechik-cbc" */ - 1016, /* "kuznyechik-cfb" */ - 1013, /* "kuznyechik-ctr" */ - 1177, /* "kuznyechik-ctr-acpkm" */ - 1178, /* "kuznyechik-ctr-acpkm-omac" */ - 1012, /* "kuznyechik-ecb" */ - 1183, /* "kuznyechik-kexp15" */ - 1017, /* "kuznyechik-mac" */ - 1014, /* "kuznyechik-ofb" */ - 477, /* "lastModifiedBy" */ - 476, /* "lastModifiedTime" */ - 157, /* "localKeyID" */ - 480, /* "mXRecord" */ - 1190, /* "magma-cbc" */ - 1191, /* "magma-cfb" */ - 1188, /* "magma-ctr" */ - 1174, /* "magma-ctr-acpkm" */ - 1175, /* "magma-ctr-acpkm-omac" */ - 1187, /* "magma-ecb" */ - 1181, /* "magma-kexp15" */ - 1192, /* "magma-mac" */ - 1189, /* "magma-ofb" */ - 460, /* "mail" */ - 493, /* "mailPreferenceOption" */ - 467, /* "manager" */ - 982, /* "md_gost12_256" */ - 983, /* "md_gost12_512" */ - 809, /* "md_gost94" */ - 875, /* "member" */ - 182, /* "member-body" */ - 51, /* "messageDigest" */ - 383, /* "mgmt" */ - 504, /* "mime-mhs" */ - 506, /* "mime-mhs-bodies" */ - 505, /* "mime-mhs-headings" */ - 488, /* "mobileTelephoneNumber" */ - 1212, /* "modp_1536" */ - 1213, /* "modp_2048" */ - 1214, /* "modp_3072" */ - 1215, /* "modp_4096" */ - 1216, /* "modp_6144" */ - 1217, /* "modp_8192" */ - 1294, /* "ms-app-policies" */ - 1293, /* "ms-cert-templ" */ - 1291, /* "ms-ntds-obj-sid" */ - 1292, /* "ms-ntds-sec-ext" */ - 136, /* "msCTLSign" */ - 135, /* "msCodeCom" */ - 134, /* "msCodeInd" */ - 138, /* "msEFS" */ - 171, /* "msExtReq" */ - 137, /* "msSGC" */ - 648, /* "msSmartcardLogin" */ - 649, /* "msUPN" */ - 1091, /* "n3" */ - 481, /* "nSRecord" */ - 173, /* "name" */ - 666, /* "nameConstraints" */ - 1306, /* "noAssertion" */ - 369, /* "noCheck" */ - 403, /* "noRevAvail" */ - 72, /* "nsBaseUrl" */ - 76, /* "nsCaPolicyUrl" */ - 74, /* "nsCaRevocationUrl" */ - 58, /* "nsCertExt" */ - 79, /* "nsCertSequence" */ - 71, /* "nsCertType" */ - 78, /* "nsComment" */ - 59, /* "nsDataType" */ - 75, /* "nsRenewalUrl" */ - 73, /* "nsRevocationUrl" */ - 139, /* "nsSGC" */ - 77, /* "nsSslServerName" */ - 681, /* "onBasis" */ - 1283, /* "oracle-jdk-trustedkeyusage" */ - 1282, /* "oracle-organization" */ - 1089, /* "organizationIdentifier" */ - 491, /* "organizationalStatus" */ - 1141, /* "oscca" */ - 475, /* "otherMailbox" */ - 876, /* "owner" */ - 489, /* "pagerTelephoneNumber" */ - 374, /* "path" */ - 112, /* "pbeWithMD5AndCast5CBC" */ - 499, /* "personalSignature" */ - 487, /* "personalTitle" */ - 464, /* "photo" */ - 863, /* "physicalDeliveryOfficeName" */ - 437, /* "pilot" */ - 439, /* "pilotAttributeSyntax" */ - 438, /* "pilotAttributeType" */ - 479, /* "pilotAttributeType27" */ - 456, /* "pilotDSA" */ - 441, /* "pilotGroups" */ - 444, /* "pilotObject" */ - 440, /* "pilotObjectClass" */ - 455, /* "pilotOrganization" */ - 445, /* "pilotPerson" */ - 1032, /* "pkInitClientAuth" */ - 1033, /* "pkInitKDC" */ - 2, /* "pkcs" */ - 186, /* "pkcs1" */ - 27, /* "pkcs3" */ - 187, /* "pkcs5" */ - 20, /* "pkcs7" */ - 21, /* "pkcs7-data" */ - 25, /* "pkcs7-digestData" */ - 26, /* "pkcs7-encryptedData" */ - 23, /* "pkcs7-envelopedData" */ - 24, /* "pkcs7-signedAndEnvelopedData" */ - 22, /* "pkcs7-signedData" */ - 151, /* "pkcs8ShroudedKeyBag" */ - 47, /* "pkcs9" */ - 401, /* "policyConstraints" */ - 747, /* "policyMappings" */ - 862, /* "postOfficeBox" */ - 861, /* "postalAddress" */ - 661, /* "postalCode" */ - 683, /* "ppBasis" */ - 872, /* "preferredDeliveryMethod" */ - 873, /* "presentationAddress" */ - 816, /* "prf-gostr3411-94" */ - 406, /* "prime-field" */ - 409, /* "prime192v1" */ - 410, /* "prime192v2" */ - 411, /* "prime192v3" */ - 412, /* "prime239v1" */ - 413, /* "prime239v2" */ - 414, /* "prime239v3" */ - 415, /* "prime256v1" */ - 385, /* "private" */ - 84, /* "privateKeyUsagePeriod" */ - 1315, /* "protRestrict" */ - 886, /* "protocolInformation" */ - 663, /* "proxyCertInfo" */ - 510, /* "pseudonym" */ - 435, /* "pss" */ - 286, /* "qcStatements" */ - 457, /* "qualityLabelledData" */ - 450, /* "rFC822localPart" */ - 870, /* "registeredAddress" */ - 400, /* "role" */ - 877, /* "roleOccupant" */ - 1296, /* "roleSpecCertIdentifier" */ - 448, /* "room" */ - 463, /* "roomNumber" */ - 1243, /* "rpkiManifest" */ - 1245, /* "rpkiNotify" */ - 6, /* "rsaEncryption" */ - 644, /* "rsaOAEPEncryptionSET" */ - 377, /* "rsaSignature" */ - 1, /* "rsadsi" */ - 1302, /* "sOAIdentifier" */ - 482, /* "sOARecord" */ - 155, /* "safeContentsBag" */ - 291, /* "sbgp-autonomousSysNum" */ - 1240, /* "sbgp-autonomousSysNumv2" */ - 290, /* "sbgp-ipAddrBlock" */ - 1239, /* "sbgp-ipAddrBlockv2" */ - 292, /* "sbgp-routerIdentifier" */ - 159, /* "sdsiCertificate" */ - 859, /* "searchGuide" */ - 704, /* "secp112r1" */ - 705, /* "secp112r2" */ - 706, /* "secp128r1" */ - 707, /* "secp128r2" */ - 708, /* "secp160k1" */ - 709, /* "secp160r1" */ - 710, /* "secp160r2" */ - 711, /* "secp192k1" */ - 712, /* "secp224k1" */ - 713, /* "secp224r1" */ - 714, /* "secp256k1" */ - 715, /* "secp384r1" */ - 716, /* "secp521r1" */ - 154, /* "secretBag" */ - 474, /* "secretary" */ - 717, /* "sect113r1" */ - 718, /* "sect113r2" */ - 719, /* "sect131r1" */ - 720, /* "sect131r2" */ - 721, /* "sect163k1" */ - 722, /* "sect163r1" */ - 723, /* "sect163r2" */ - 724, /* "sect193r1" */ - 725, /* "sect193r2" */ - 726, /* "sect233k1" */ - 727, /* "sect233r1" */ - 728, /* "sect239k1" */ - 729, /* "sect283k1" */ - 730, /* "sect283r1" */ - 731, /* "sect409k1" */ - 732, /* "sect409r1" */ - 733, /* "sect571k1" */ - 734, /* "sect571r1" */ - 1025, /* "secureShellClient" */ - 1026, /* "secureShellServer" */ - 386, /* "security" */ - 878, /* "seeAlso" */ - 394, /* "selected-attribute-types" */ - 1029, /* "sendOwner" */ - 1030, /* "sendProxiedOwner" */ - 1028, /* "sendProxiedRouter" */ - 1027, /* "sendRouter" */ - 105, /* "serialNumber" */ - 129, /* "serverAuth" */ - 371, /* "serviceLocator" */ - 625, /* "set-addPolicy" */ - 515, /* "set-attr" */ - 518, /* "set-brand" */ - 638, /* "set-brand-AmericanExpress" */ - 637, /* "set-brand-Diners" */ - 636, /* "set-brand-IATA-ATA" */ - 639, /* "set-brand-JCB" */ - 641, /* "set-brand-MasterCard" */ - 642, /* "set-brand-Novus" */ - 640, /* "set-brand-Visa" */ - 517, /* "set-certExt" */ - 513, /* "set-ctype" */ - 514, /* "set-msgExt" */ - 516, /* "set-policy" */ - 607, /* "set-policy-root" */ - 624, /* "set-rootKeyThumb" */ - 620, /* "setAttr-Cert" */ - 631, /* "setAttr-GenCryptgrm" */ - 623, /* "setAttr-IssCap" */ - 628, /* "setAttr-IssCap-CVM" */ - 630, /* "setAttr-IssCap-Sig" */ - 629, /* "setAttr-IssCap-T2" */ - 621, /* "setAttr-PGWYcap" */ - 635, /* "setAttr-SecDevSig" */ - 632, /* "setAttr-T2Enc" */ - 633, /* "setAttr-T2cleartxt" */ - 634, /* "setAttr-TokICCsig" */ - 627, /* "setAttr-Token-B0Prime" */ - 626, /* "setAttr-Token-EMV" */ - 622, /* "setAttr-TokenType" */ - 619, /* "setCext-IssuerCapabilities" */ - 615, /* "setCext-PGWYcapabilities" */ - 616, /* "setCext-TokenIdentifier" */ - 618, /* "setCext-TokenType" */ - 617, /* "setCext-Track2Data" */ - 611, /* "setCext-cCertRequired" */ - 609, /* "setCext-certType" */ - 608, /* "setCext-hashedRoot" */ - 610, /* "setCext-merchData" */ - 613, /* "setCext-setExt" */ - 614, /* "setCext-setQualf" */ - 612, /* "setCext-tunneling" */ - 540, /* "setct-AcqCardCodeMsg" */ - 576, /* "setct-AcqCardCodeMsgTBE" */ - 570, /* "setct-AuthReqTBE" */ - 534, /* "setct-AuthReqTBS" */ - 527, /* "setct-AuthResBaggage" */ - 571, /* "setct-AuthResTBE" */ - 572, /* "setct-AuthResTBEX" */ - 535, /* "setct-AuthResTBS" */ - 536, /* "setct-AuthResTBSX" */ - 528, /* "setct-AuthRevReqBaggage" */ - 577, /* "setct-AuthRevReqTBE" */ - 541, /* "setct-AuthRevReqTBS" */ - 529, /* "setct-AuthRevResBaggage" */ - 542, /* "setct-AuthRevResData" */ - 578, /* "setct-AuthRevResTBE" */ - 579, /* "setct-AuthRevResTBEB" */ - 543, /* "setct-AuthRevResTBS" */ - 573, /* "setct-AuthTokenTBE" */ - 537, /* "setct-AuthTokenTBS" */ - 600, /* "setct-BCIDistributionTBS" */ - 558, /* "setct-BatchAdminReqData" */ - 592, /* "setct-BatchAdminReqTBE" */ - 559, /* "setct-BatchAdminResData" */ - 593, /* "setct-BatchAdminResTBE" */ - 599, /* "setct-CRLNotificationResTBS" */ - 598, /* "setct-CRLNotificationTBS" */ - 580, /* "setct-CapReqTBE" */ - 581, /* "setct-CapReqTBEX" */ - 544, /* "setct-CapReqTBS" */ - 545, /* "setct-CapReqTBSX" */ - 546, /* "setct-CapResData" */ - 582, /* "setct-CapResTBE" */ - 583, /* "setct-CapRevReqTBE" */ - 584, /* "setct-CapRevReqTBEX" */ - 547, /* "setct-CapRevReqTBS" */ - 548, /* "setct-CapRevReqTBSX" */ - 549, /* "setct-CapRevResData" */ - 585, /* "setct-CapRevResTBE" */ - 538, /* "setct-CapTokenData" */ - 530, /* "setct-CapTokenSeq" */ - 574, /* "setct-CapTokenTBE" */ - 575, /* "setct-CapTokenTBEX" */ - 539, /* "setct-CapTokenTBS" */ - 560, /* "setct-CardCInitResTBS" */ - 566, /* "setct-CertInqReqTBS" */ - 563, /* "setct-CertReqData" */ - 595, /* "setct-CertReqTBE" */ - 596, /* "setct-CertReqTBEX" */ - 564, /* "setct-CertReqTBS" */ - 565, /* "setct-CertResData" */ - 597, /* "setct-CertResTBE" */ - 586, /* "setct-CredReqTBE" */ - 587, /* "setct-CredReqTBEX" */ - 550, /* "setct-CredReqTBS" */ - 551, /* "setct-CredReqTBSX" */ - 552, /* "setct-CredResData" */ - 588, /* "setct-CredResTBE" */ - 589, /* "setct-CredRevReqTBE" */ - 590, /* "setct-CredRevReqTBEX" */ - 553, /* "setct-CredRevReqTBS" */ - 554, /* "setct-CredRevReqTBSX" */ - 555, /* "setct-CredRevResData" */ - 591, /* "setct-CredRevResTBE" */ - 567, /* "setct-ErrorTBS" */ - 526, /* "setct-HODInput" */ - 561, /* "setct-MeAqCInitResTBS" */ - 522, /* "setct-OIData" */ - 519, /* "setct-PANData" */ - 521, /* "setct-PANOnly" */ - 520, /* "setct-PANToken" */ - 556, /* "setct-PCertReqData" */ - 557, /* "setct-PCertResTBS" */ - 523, /* "setct-PI" */ - 532, /* "setct-PI-TBS" */ - 524, /* "setct-PIData" */ - 525, /* "setct-PIDataUnsigned" */ - 568, /* "setct-PIDualSignedTBE" */ - 569, /* "setct-PIUnsignedTBE" */ - 531, /* "setct-PInitResData" */ - 533, /* "setct-PResData" */ - 594, /* "setct-RegFormReqTBE" */ - 562, /* "setct-RegFormResTBS" */ - 606, /* "setext-cv" */ - 601, /* "setext-genCrypt" */ - 602, /* "setext-miAuth" */ - 604, /* "setext-pinAny" */ - 603, /* "setext-pinSecure" */ - 605, /* "setext-track2" */ - 1279, /* "signedAssertion" */ - 1244, /* "signedObject" */ - 52, /* "signingTime" */ - 454, /* "simpleSecurityObject" */ - 496, /* "singleLevelQuality" */ - 1309, /* "singleUse" */ - 1142, /* "sm-scheme" */ - 387, /* "snmpv2" */ - 660, /* "street" */ - 85, /* "subjectAltName" */ - 1316, /* "subjectAltPublicKeyInfo" */ - 769, /* "subjectDirectoryAttributes" */ - 398, /* "subjectInfoAccess" */ - 82, /* "subjectKeyIdentifier" */ - 1007, /* "subjectSignTool" */ - 498, /* "subtreeMaximumQuality" */ - 497, /* "subtreeMinimumQuality" */ - 890, /* "supportedAlgorithms" */ - 874, /* "supportedApplicationContext" */ - 402, /* "targetInformation" */ - 1324, /* "tcg" */ - 1333, /* "tcg-address" */ - 1385, /* "tcg-address-bluetoothmac" */ - 1383, /* "tcg-address-ethernetmac" */ - 1384, /* "tcg-address-wlanmac" */ - 1328, /* "tcg-algorithm" */ - 1367, /* "tcg-algorithm-null" */ - 1362, /* "tcg-at-cryptographicAnchors" */ - 1339, /* "tcg-at-platformConfigUri" */ - 1366, /* "tcg-at-platformConfigUri-v3" */ - 1343, /* "tcg-at-platformConfiguration" */ - 1363, /* "tcg-at-platformConfiguration-v1" */ - 1364, /* "tcg-at-platformConfiguration-v2" */ - 1365, /* "tcg-at-platformConfiguration-v3" */ - 1344, /* "tcg-at-platformIdentifier" */ - 1338, /* "tcg-at-platformManufacturerId" */ - 1337, /* "tcg-at-platformManufacturerStr" */ - 1340, /* "tcg-at-platformModel" */ - 1342, /* "tcg-at-platformSerial" */ - 1341, /* "tcg-at-platformVersion" */ - 1360, /* "tcg-at-previousPlatformCertificates" */ - 1348, /* "tcg-at-securityQualities" */ - 1351, /* "tcg-at-tbbProtectionProfile" */ - 1357, /* "tcg-at-tbbSecurityAssertions" */ - 1361, /* "tcg-at-tbbSecurityAssertions-v3" */ - 1352, /* "tcg-at-tbbSecurityTarget" */ - 1358, /* "tcg-at-tcgCredentialSpecification" */ - 1359, /* "tcg-at-tcgCredentialType" */ - 1355, /* "tcg-at-tcgPlatformSpecification" */ - 1353, /* "tcg-at-tpmIdLabel" */ - 1345, /* "tcg-at-tpmManufacturer" */ - 1346, /* "tcg-at-tpmModel" */ - 1349, /* "tcg-at-tpmProtectionProfile" */ - 1356, /* "tcg-at-tpmSecurityAssertions" */ - 1350, /* "tcg-at-tpmSecurityTarget" */ - 1354, /* "tcg-at-tpmSpecification" */ - 1347, /* "tcg-at-tpmVersion" */ - 1326, /* "tcg-attribute" */ - 1332, /* "tcg-ca" */ - 1392, /* "tcg-cap-verifiedPlatformCertificate" */ - 1330, /* "tcg-ce" */ - 1379, /* "tcg-ce-migrationControllerAttestationService" */ - 1380, /* "tcg-ce-migrationControllerRegistrationService" */ - 1376, /* "tcg-ce-relevantCredentials" */ - 1377, /* "tcg-ce-relevantManifests" */ - 1378, /* "tcg-ce-virtualPlatformAttestationService" */ - 1381, /* "tcg-ce-virtualPlatformBackupService" */ - 1336, /* "tcg-common" */ - 1331, /* "tcg-kp" */ - 1370, /* "tcg-kp-AIKCertificate" */ - 1374, /* "tcg-kp-AdditionalPlatformAttributeCertificate" */ - 1375, /* "tcg-kp-AdditionalPlatformKeyCertificate" */ - 1372, /* "tcg-kp-DeltaPlatformAttributeCertificate" */ - 1373, /* "tcg-kp-DeltaPlatformKeyCertificate" */ - 1368, /* "tcg-kp-EKCertificate" */ - 1369, /* "tcg-kp-PlatformAttributeCertificate" */ - 1371, /* "tcg-kp-PlatformKeyCertificate" */ - 1329, /* "tcg-platformClass" */ - 1327, /* "tcg-protocol" */ - 1382, /* "tcg-prt-tpmIdProtocol" */ - 1334, /* "tcg-registry" */ - 1386, /* "tcg-registry-componentClass" */ - 1391, /* "tcg-registry-componentClass-disk" */ - 1389, /* "tcg-registry-componentClass-dmtf" */ - 1388, /* "tcg-registry-componentClass-ietf" */ - 1390, /* "tcg-registry-componentClass-pcie" */ - 1387, /* "tcg-registry-componentClass-tcg" */ - 1325, /* "tcg-tcpaSpecVersion" */ - 1393, /* "tcg-tr-ID" */ - 1396, /* "tcg-tr-ID-Boolean" */ - 1397, /* "tcg-tr-ID-CertificateIdentifier" */ - 1398, /* "tcg-tr-ID-CommonCriteria" */ - 1401, /* "tcg-tr-ID-FIPSLevel" */ - 1414, /* "tcg-tr-ID-IA5String" */ - 1402, /* "tcg-tr-ID-ISO9000Level" */ - 1404, /* "tcg-tr-ID-OID" */ - 1415, /* "tcg-tr-ID-PEMCertString" */ - 1405, /* "tcg-tr-ID-PEN" */ - 1416, /* "tcg-tr-ID-PublicKey" */ - 1410, /* "tcg-tr-ID-RTM" */ - 1412, /* "tcg-tr-ID-URI" */ - 1413, /* "tcg-tr-ID-UTF8String" */ - 1399, /* "tcg-tr-ID-componentClass" */ - 1400, /* "tcg-tr-ID-componentIdentifierV11" */ - 1403, /* "tcg-tr-ID-networkMAC" */ - 1406, /* "tcg-tr-ID-platformFirmwareCapabilities" */ - 1407, /* "tcg-tr-ID-platformFirmwareSignatureVerification" */ - 1408, /* "tcg-tr-ID-platformFirmwareUpdateCompliance" */ - 1409, /* "tcg-tr-ID-platformHardwareCapabilities" */ - 1411, /* "tcg-tr-ID-status" */ - 1441, /* "tcg-tr-cat-CommonCriteria" */ - 1434, /* "tcg-tr-cat-DICECertificate" */ - 1438, /* "tcg-tr-cat-DeltaPlatformCertificate" */ - 1431, /* "tcg-tr-cat-EKCertificate" */ - 1443, /* "tcg-tr-cat-FIPSLevel" */ - 1432, /* "tcg-tr-cat-IAKCertificate" */ - 1433, /* "tcg-tr-cat-IDevIDCertificate" */ - 1444, /* "tcg-tr-cat-ISO9000" */ - 1436, /* "tcg-tr-cat-PEMCertificate" */ - 1447, /* "tcg-tr-cat-PEN" */ - 1437, /* "tcg-tr-cat-PlatformCertificate" */ - 1453, /* "tcg-tr-cat-PublicKey" */ - 1452, /* "tcg-tr-cat-RTM" */ - 1439, /* "tcg-tr-cat-RebasePlatformCertificate" */ - 1435, /* "tcg-tr-cat-SPDMCertificate" */ - 1446, /* "tcg-tr-cat-attestationProtocol" */ - 1423, /* "tcg-tr-cat-componentClass" */ - 1430, /* "tcg-tr-cat-componentFieldReplaceable" */ - 1442, /* "tcg-tr-cat-componentIdentifierV11" */ - 1428, /* "tcg-tr-cat-componentLocation" */ - 1424, /* "tcg-tr-cat-componentManufacturer" */ - 1425, /* "tcg-tr-cat-componentModel" */ - 1429, /* "tcg-tr-cat-componentRevision" */ - 1426, /* "tcg-tr-cat-componentSerial" */ - 1427, /* "tcg-tr-cat-componentStatus" */ - 1440, /* "tcg-tr-cat-genericCertificate" */ - 1445, /* "tcg-tr-cat-networkMAC" */ - 1448, /* "tcg-tr-cat-platformFirmwareCapabilities" */ - 1450, /* "tcg-tr-cat-platformFirmwareSignatureVerification" */ - 1451, /* "tcg-tr-cat-platformFirmwareUpdateCompliance" */ - 1449, /* "tcg-tr-cat-platformHardwareCapabilities" */ - 1417, /* "tcg-tr-cat-platformManufacturer" */ - 1421, /* "tcg-tr-cat-platformManufacturerIdentifier" */ - 1418, /* "tcg-tr-cat-platformModel" */ - 1422, /* "tcg-tr-cat-platformOwnership" */ - 1420, /* "tcg-tr-cat-platformSerial" */ - 1419, /* "tcg-tr-cat-platformVersion" */ - 1394, /* "tcg-tr-category" */ - 1395, /* "tcg-tr-registry" */ - 1335, /* "tcg-traits" */ - 864, /* "telephoneNumber" */ - 866, /* "teletexTerminalIdentifier" */ - 865, /* "telexNumber" */ - 459, /* "textEncodedORAddress" */ - 293, /* "textNotice" */ - 1299, /* "timeSpecification" */ - 133, /* "timeStamping" */ - 106, /* "title" */ - 1020, /* "tlsfeature" */ - 682, /* "tpBasis" */ - 375, /* "trustRoot" */ - 1151, /* "ua-pki" */ - 1160, /* "uacurve0" */ - 1161, /* "uacurve1" */ - 1162, /* "uacurve2" */ - 1163, /* "uacurve3" */ - 1164, /* "uacurve4" */ - 1165, /* "uacurve5" */ - 1166, /* "uacurve6" */ - 1167, /* "uacurve7" */ - 1168, /* "uacurve8" */ - 1169, /* "uacurve9" */ - 436, /* "ucl" */ - 102, /* "uid" */ - 888, /* "uniqueMember" */ - 55, /* "unstructuredAddress" */ - 49, /* "unstructuredName" */ - 880, /* "userCertificate" */ - 465, /* "userClass" */ - 1301, /* "userNotice" */ - 879, /* "userPassword" */ - 373, /* "valid" */ - 678, /* "wap" */ - 679, /* "wap-wsg" */ - 735, /* "wap-wsg-idm-ecid-wtls1" */ - 743, /* "wap-wsg-idm-ecid-wtls10" */ - 744, /* "wap-wsg-idm-ecid-wtls11" */ - 745, /* "wap-wsg-idm-ecid-wtls12" */ - 736, /* "wap-wsg-idm-ecid-wtls3" */ - 737, /* "wap-wsg-idm-ecid-wtls4" */ - 738, /* "wap-wsg-idm-ecid-wtls5" */ - 739, /* "wap-wsg-idm-ecid-wtls6" */ - 740, /* "wap-wsg-idm-ecid-wtls7" */ - 741, /* "wap-wsg-idm-ecid-wtls8" */ - 742, /* "wap-wsg-idm-ecid-wtls9" */ - 804, /* "whirlpool" */ - 868, /* "x121Address" */ - 503, /* "x500UniqueIdentifier" */ - 158, /* "x509Certificate" */ - 160, /* "x509Crl" */ - 1093, /* "x509ExtAdmission" */ - 1289, /* "zstd" */ -}; - -#define NUM_LN 1493 -static const unsigned int ln_objs[NUM_LN] = { - 363, /* "AD Time Stamping" */ - 405, /* "ANSI X9.62" */ - 368, /* "Acceptable OCSP Responses" */ - 1374, /* "Additional Platform Attribute Certificate" */ - 1375, /* "Additional Platform Key Certificate" */ - 910, /* "Any Extended Key Usage" */ - 664, /* "Any language" */ - 1370, /* "Attestation Identity Key Certificate" */ - 1446, /* "Attestation Protocol Trait Category" */ - 1411, /* "Attribute Status Trait" */ - 177, /* "Authority Information Access" */ - 1220, /* "BGPsec Router" */ - 365, /* "Basic OCSP Response" */ - 285, /* "Biometric Info" */ - 1385, /* "Bluetooth MAC Address" */ - 1396, /* "Boolean Trait" */ - 1221, /* "Brand Indicator for Message Identification" */ - 1288, /* "Brotli compression" */ - 179, /* "CA Issuers" */ - 785, /* "CA Repository" */ - 1219, /* "CMC Archive Server" */ - 1131, /* "CMC Certificate Authority" */ - 1132, /* "CMC Registration Authority" */ - 954, /* "CT Certificate SCTs" */ - 952, /* "CT Precertificate Poison" */ - 951, /* "CT Precertificate SCTs" */ - 953, /* "CT Precertificate Signer" */ - 1397, /* "Certificate Identifier Trait" */ - 1222, /* "Certificate Management Key Generation Authority" */ - 1227, /* "Class of Signing Tool" */ - 1233, /* "Class of Signing Tool KA1" */ - 1231, /* "Class of Signing Tool KB1" */ - 1232, /* "Class of Signing Tool KB2" */ - 1228, /* "Class of Signing Tool KC1" */ - 1229, /* "Class of Signing Tool KC2" */ - 1230, /* "Class of Signing Tool KC3" */ - 131, /* "Code Signing" */ - 1398, /* "Common Criteria Trait" */ - 1441, /* "Common Criteria Trait Category" */ - 1399, /* "Component Class Trait" */ - 1423, /* "Component Class Trait Category" */ - 1430, /* "Component Field Replaceable Trait Category" */ - 1400, /* "Component Identifier V1.1 Trait" */ - 1442, /* "Component Identifier V1.1 Trait Category" */ - 1428, /* "Component Location Trait Category" */ - 1424, /* "Component Manufacturer Trait Category" */ - 1425, /* "Component Model Trait Category" */ - 1429, /* "Component Revision Trait Category" */ - 1426, /* "Component Serial Trait Category" */ - 1427, /* "Component Status Trait Category" */ - 1024, /* "Ctrl/Provision WAP Termination" */ - 1023, /* "Ctrl/provision WAP Access" */ - 1434, /* "DICE Certificate Trait Category" */ - 1159, /* "DSTU 4145-2002 big endian" */ - 1158, /* "DSTU 4145-2002 little endian" */ - 1152, /* "DSTU Gost 28147-2009" */ - 1154, /* "DSTU Gost 28147-2009 CFB mode" */ - 1153, /* "DSTU Gost 28147-2009 OFB mode" */ - 1155, /* "DSTU Gost 28147-2009 key wrap" */ - 1157, /* "DSTU Gost 34311-95" */ - 1160, /* "DSTU curve 0" */ - 1161, /* "DSTU curve 1" */ - 1162, /* "DSTU curve 2" */ - 1163, /* "DSTU curve 3" */ - 1164, /* "DSTU curve 4" */ - 1165, /* "DSTU curve 5" */ - 1166, /* "DSTU curve 6" */ - 1167, /* "DSTU curve 7" */ - 1168, /* "DSTU curve 8" */ - 1169, /* "DSTU curve 9" */ - 1372, /* "Delta Platform Attribute Certificate" */ - 1438, /* "Delta Platform Certificate Trait Category" */ - 1373, /* "Delta Platform Key Certificate" */ - 783, /* "Diffie-Hellman based MAC" */ - 382, /* "Directory" */ - 1391, /* "Disk Component Class" */ - 1389, /* "Distributed Management Task Force Registry" */ - 392, /* "Domain" */ - 132, /* "E-mail Protection" */ - 1087, /* "ED25519" */ - 1088, /* "ED448" */ - 1431, /* "EK Certificate Trait Category" */ - 1368, /* "Endorsement Key Certificate" */ - 389, /* "Enterprises" */ - 1383, /* "Ethernet MAC Address" */ - 384, /* "Experimental" */ - 372, /* "Extended OCSP Status" */ - 172, /* "Extension Request" */ - 1401, /* "FIPS Level Trait" */ - 1443, /* "FIPS Level Trait Category" */ - 813, /* "GOST 28147-89" */ - 849, /* "GOST 28147-89 Cryptocom ParamSet" */ - 815, /* "GOST 28147-89 MAC" */ - 1003, /* "GOST 28147-89 TC26 parameter set" */ - 851, /* "GOST 34.10-2001 Cryptocom" */ - 850, /* "GOST 34.10-94 Cryptocom" */ - 811, /* "GOST R 34.10-2001" */ - 817, /* "GOST R 34.10-2001 DH" */ - 1148, /* "GOST R 34.10-2012 (256 bit) ParamSet A" */ - 1184, /* "GOST R 34.10-2012 (256 bit) ParamSet B" */ - 1185, /* "GOST R 34.10-2012 (256 bit) ParamSet C" */ - 1186, /* "GOST R 34.10-2012 (256 bit) ParamSet D" */ - 998, /* "GOST R 34.10-2012 (512 bit) ParamSet A" */ - 999, /* "GOST R 34.10-2012 (512 bit) ParamSet B" */ - 1149, /* "GOST R 34.10-2012 (512 bit) ParamSet C" */ - 997, /* "GOST R 34.10-2012 (512 bit) testing parameter set" */ - 979, /* "GOST R 34.10-2012 with 256 bit modulus" */ - 980, /* "GOST R 34.10-2012 with 512 bit modulus" */ - 985, /* "GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)" */ - 986, /* "GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)" */ - 812, /* "GOST R 34.10-94" */ - 818, /* "GOST R 34.10-94 DH" */ - 982, /* "GOST R 34.11-2012 with 256 bit hash" */ - 983, /* "GOST R 34.11-2012 with 512 bit hash" */ - 809, /* "GOST R 34.11-94" */ - 816, /* "GOST R 34.11-94 PRF" */ - 807, /* "GOST R 34.11-94 with GOST R 34.10-2001" */ - 853, /* "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" */ - 808, /* "GOST R 34.11-94 with GOST R 34.10-94" */ - 852, /* "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" */ - 854, /* "GOST R 3410-2001 Parameter Set Cryptocom" */ - 1440, /* "Generic Certificate Trait Category" */ - 1472, /* "HASH-ML-DSA-44-WITH-SHA512" */ - 1473, /* "HASH-ML-DSA-65-WITH-SHA512" */ - 1474, /* "HASH-ML-DSA-87-WITH-SHA512" */ - 1496, /* "HKDF-SHA256" */ - 1497, /* "HKDF-SHA384" */ - 1498, /* "HKDF-SHA512" */ - 1156, /* "HMAC DSTU Gost 34311-95" */ - 988, /* "HMAC GOST 34.11-2012 256 bit" */ - 989, /* "HMAC GOST 34.11-2012 512 bit" */ - 810, /* "HMAC GOST 34.11-94" */ - 1321, /* "Hardware Module Name" */ - 432, /* "Hold Instruction Call Issuer" */ - 430, /* "Hold Instruction Code" */ - 431, /* "Hold Instruction None" */ - 433, /* "Hold Instruction Reject" */ - 1414, /* "IA5String Trait" */ - 1432, /* "IAK Certificate Trait Category" */ - 634, /* "ICC or token signature" */ - 1433, /* "IDevID Certificate Trait Category" */ - 1171, /* "IEEE Security in Storage Working Group" */ - 1004, /* "INN" */ - 294, /* "IPSec End System" */ - 295, /* "IPSec Tunnel" */ - 296, /* "IPSec User" */ - 1402, /* "ISO 9000 Level Trait" */ - 1444, /* "ISO 9000 Trait Category" */ - 1140, /* "ISO CN Member Body" */ - 182, /* "ISO Member Body" */ - 183, /* "ISO US Member Body" */ - 1150, /* "ISO-UA" */ - 667, /* "Independent" */ - 665, /* "Inherit all" */ - 647, /* "International Organizations" */ - 1388, /* "Internet Engineering Task Force Registry" */ - 142, /* "Invalidity Date" */ - 504, /* "MIME MHS" */ - 1457, /* "ML-DSA-44" */ - 1458, /* "ML-DSA-65" */ - 1459, /* "ML-DSA-87" */ - 1456, /* "ML-KEM-1024" */ - 1454, /* "ML-KEM-512" */ - 1455, /* "ML-KEM-768" */ - 388, /* "Mail" */ - 383, /* "Management" */ - 1294, /* "Microsoft Application Policies Extension" */ - 417, /* "Microsoft CSP Name" */ - 135, /* "Microsoft Commercial Code Signing" */ - 138, /* "Microsoft Encrypted File System" */ - 171, /* "Microsoft Extension Request" */ - 134, /* "Microsoft Individual Code Signing" */ - 856, /* "Microsoft Local Key set" */ - 1291, /* "Microsoft NTDS AD objectSid" */ - 1292, /* "Microsoft NTDS CA Extension" */ - 137, /* "Microsoft Server Gated Crypto" */ - 648, /* "Microsoft Smartcard Login" */ - 136, /* "Microsoft Trust List Signing" */ - 649, /* "Microsoft User Principal Name" */ - 1293, /* "Microsoft certificate template" */ - 1379, /* "Migration Controller Attestation Service" */ - 1380, /* "Migration Controller Registration Service" */ - 1211, /* "NAIRealm" */ - 393, /* "NULL" */ - 404, /* "NULL" */ - 1323, /* "NULL" */ - 72, /* "Netscape Base Url" */ - 76, /* "Netscape CA Policy Url" */ - 74, /* "Netscape CA Revocation Url" */ - 71, /* "Netscape Cert Type" */ - 58, /* "Netscape Certificate Extension" */ - 79, /* "Netscape Certificate Sequence" */ - 78, /* "Netscape Comment" */ - 57, /* "Netscape Communications Corp." */ - 59, /* "Netscape Data Type" */ - 75, /* "Netscape Renewal Url" */ - 73, /* "Netscape Revocation Url" */ - 77, /* "Netscape SSL Server Name" */ - 139, /* "Netscape Server Gated Crypto" */ - 1403, /* "Network MAC Trait" */ - 1445, /* "Network MAC Trait Category" */ - 178, /* "OCSP" */ - 370, /* "OCSP Archive Cutoff" */ - 367, /* "OCSP CRL ID" */ - 369, /* "OCSP No Check" */ - 366, /* "OCSP Nonce" */ - 371, /* "OCSP Service Locator" */ - 180, /* "OCSP Signing" */ - 1005, /* "OGRN" */ - 1226, /* "OGRNIP" */ - 1404, /* "Object Identifier Trait" */ - 1282, /* "Oracle organization" */ - 161, /* "PBES2" */ - 69, /* "PBKDF2" */ - 162, /* "PBMAC1" */ - 1390, /* "PCIE Component Class" */ - 1436, /* "PEM Certificate Trait Category" */ - 1415, /* "PEM-Encoded Certificate String Trait" */ - 1032, /* "PKINIT Client Auth" */ - 127, /* "PKIX" */ - 858, /* "Permanent Identifier" */ - 1369, /* "Platform Attribute Certificate" */ - 1437, /* "Platform Certificate Trait Category" */ - 1366, /* "Platform Configuration URI Version 3" */ - 1363, /* "Platform Configuration Version 1" */ - 1364, /* "Platform Configuration Version 2" */ - 1365, /* "Platform Configuration Version 3" */ - 1406, /* "Platform Firmware Capabilities Trait" */ - 1448, /* "Platform Firmware Capabilities Trait Category" */ - 1407, /* "Platform Firmware Signature Verification Trait" */ - 1450, /* "Platform Firmware Signature Verification Trait Category" */ - 1408, /* "Platform Firmware Update Compliance Trait" */ - 1451, /* "Platform Firmware Update Compliance Trait Category" */ - 1409, /* "Platform Hardware Capabilities Trait" */ - 1449, /* "Platform Hardware Capabilities Trait Category" */ - 1371, /* "Platform Key Certificate" */ - 1421, /* "Platform Manufacturer Identifier Trait Category" */ - 1417, /* "Platform Manufacturer Trait Category" */ - 1418, /* "Platform Model Trait Category" */ - 1422, /* "Platform Ownership Trait Category" */ - 1420, /* "Platform Serial Trait Category" */ - 1419, /* "Platform Version Trait Category" */ - 164, /* "Policy Qualifier CPS" */ - 165, /* "Policy Qualifier User Notice" */ - 385, /* "Private" */ - 1405, /* "Private Enterprise Number Trait" */ - 1447, /* "Private Enterprise Number Trait Category" */ - 1093, /* "Professional Information or basis for Admission" */ - 663, /* "Proxy Certificate Information" */ - 1416, /* "Public Key Trait" */ - 1453, /* "Public Key Trait Category" */ - 1243, /* "RPKI Manifest" */ - 1245, /* "RPKI Notify" */ - 1, /* "RSA Data Security, Inc." */ - 2, /* "RSA Data Security, Inc. PKCS" */ - 1116, /* "RSA-SHA3-224" */ - 1117, /* "RSA-SHA3-256" */ - 1118, /* "RSA-SHA3-384" */ - 1119, /* "RSA-SHA3-512" */ - 1439, /* "Rebase Platform Certificate Trait Category" */ - 1376, /* "Relevant Credentials" */ - 1377, /* "Relevant Manifests" */ - 1410, /* "Root of Trust for Measurement Trait" */ - 1452, /* "Root of Trust of Measurement Trait Category" */ - 188, /* "S/MIME" */ - 167, /* "S/MIME Capabilities" */ - 1461, /* "SLH-DSA-SHA2-128f" */ - 1476, /* "SLH-DSA-SHA2-128f-WITH-SHA256" */ - 1460, /* "SLH-DSA-SHA2-128s" */ - 1475, /* "SLH-DSA-SHA2-128s-WITH-SHA256" */ - 1463, /* "SLH-DSA-SHA2-192f" */ - 1478, /* "SLH-DSA-SHA2-192f-WITH-SHA512" */ - 1462, /* "SLH-DSA-SHA2-192s" */ - 1477, /* "SLH-DSA-SHA2-192s-WITH-SHA512" */ - 1465, /* "SLH-DSA-SHA2-256f" */ - 1480, /* "SLH-DSA-SHA2-256f-WITH-SHA512" */ - 1464, /* "SLH-DSA-SHA2-256s" */ - 1479, /* "SLH-DSA-SHA2-256s-WITH-SHA512" */ - 1467, /* "SLH-DSA-SHAKE-128f" */ - 1482, /* "SLH-DSA-SHAKE-128f-WITH-SHAKE128" */ - 1466, /* "SLH-DSA-SHAKE-128s" */ - 1481, /* "SLH-DSA-SHAKE-128s-WITH-SHAKE128" */ - 1469, /* "SLH-DSA-SHAKE-192f" */ - 1484, /* "SLH-DSA-SHAKE-192f-WITH-SHAKE256" */ - 1468, /* "SLH-DSA-SHAKE-192s" */ - 1483, /* "SLH-DSA-SHAKE-192s-WITH-SHAKE256" */ - 1471, /* "SLH-DSA-SHAKE-256f" */ - 1486, /* "SLH-DSA-SHAKE-256f-WITH-SHAKE256" */ - 1470, /* "SLH-DSA-SHAKE-256s" */ - 1485, /* "SLH-DSA-SHAKE-256s-WITH-SHAKE256" */ - 1204, /* "SM2-with-SM3" */ - 1006, /* "SNILS" */ - 387, /* "SNMPv2" */ - 1435, /* "SPDM Certificate Trait Category" */ - 1210, /* "SRVName" */ - 1025, /* "SSH Client" */ - 1026, /* "SSH Server" */ - 512, /* "Secure Electronic Transactions" */ - 386, /* "Security" */ - 1348, /* "Security Qualities" */ - 394, /* "Selected Attribute Types" */ - 1029, /* "Send Owner" */ - 1030, /* "Send Proxied Owner" */ - 1028, /* "Send Proxied Router" */ - 1027, /* "Send Router" */ - 1244, /* "Signed Object" */ - 1033, /* "Signing KDC Response" */ - 1008, /* "Signing Tool of Issuer" */ - 1007, /* "Signing Tool of Subject" */ - 1208, /* "Smtp UTF8 Mailbox" */ - 143, /* "Strong Extranet ID" */ - 398, /* "Subject Information Access" */ - 1351, /* "TBB Protection Profile" */ - 1357, /* "TBB Security Assertions" */ - 1352, /* "TBB Security Target" */ - 1386, /* "TCG Component Class" */ - 1358, /* "TCG Credential Specification" */ - 1359, /* "TCG Credential Type" */ - 1362, /* "TCG Cryptographic Anchors" */ - 1367, /* "TCG NULL Algorithm" */ - 1343, /* "TCG Platform Configuration" */ - 1339, /* "TCG Platform Configuration URI" */ - 1344, /* "TCG Platform Identifier" */ - 1338, /* "TCG Platform Manufacturer ID" */ - 1337, /* "TCG Platform Manufacturer String" */ - 1340, /* "TCG Platform Model" */ - 1342, /* "TCG Platform Serial Number" */ - 1341, /* "TCG Platform Version" */ - 1360, /* "TCG Previous Platform Certificates" */ - 1361, /* "TCG TBB Security Assertions V3" */ - 1382, /* "TCG TPM Protocol" */ - 1394, /* "TCG Trait Categories" */ - 1393, /* "TCG Trait Identifiers" */ - 1395, /* "TCG Trait Registries" */ - 1392, /* "TCG Verified Platform Certificate CA Policy" */ - 1020, /* "TLS Feature" */ - 130, /* "TLS Web Client Authentication" */ - 129, /* "TLS Web Server Authentication" */ - 1353, /* "TPM ID Label" */ - 1345, /* "TPM Manufacturer" */ - 1346, /* "TPM Model" */ - 1355, /* "TPM Platform Specification" */ - 1349, /* "TPM Protection Profile" */ - 1356, /* "TPM Security Assertions" */ - 1350, /* "TPM Security Target" */ - 1354, /* "TPM Specification" */ - 1347, /* "TPM Version" */ - 133, /* "Time Stamping" */ - 375, /* "Trust Root" */ - 1387, /* "Trusted Computed Group Registry" */ - 1324, /* "Trusted Computing Group" */ - 1333, /* "Trusted Computing Group Address Formats" */ - 1328, /* "Trusted Computing Group Algorithms" */ - 1326, /* "Trusted Computing Group Attributes" */ - 1330, /* "Trusted Computing Group Certificate Extensions" */ - 1332, /* "Trusted Computing Group Certificate Policies" */ - 1336, /* "Trusted Computing Group Common" */ - 1331, /* "Trusted Computing Group Key Purposes" */ - 1329, /* "Trusted Computing Group Platform Classes" */ - 1327, /* "Trusted Computing Group Protocols" */ - 1334, /* "Trusted Computing Group Registry" */ - 1335, /* "Trusted Computing Group Traits" */ - 1283, /* "Trusted key usage (Oracle)" */ - 1413, /* "UTF8String Trait" */ - 1412, /* "Uniform Resource Identifier Trait" */ - 1378, /* "Virtual Platform Attestation Service" */ - 1381, /* "Virtual Platform Backup Service" */ - 1384, /* "WLAN MAC Address" */ - 1322, /* "Wi-SUN Alliance Field Area Network (FAN)" */ - 1034, /* "X25519" */ - 1035, /* "X448" */ - 12, /* "X509" */ - 402, /* "X509v3 AC Targeting" */ - 1303, /* "X509v3 Acceptable Certification Policies" */ - 1304, /* "X509v3 Acceptable Privilege Policies" */ - 1311, /* "X509v3 Allowed Attribute Assignments" */ - 1317, /* "X509v3 Alternative Signature Algorithm" */ - 1318, /* "X509v3 Alternative Signature Value" */ - 746, /* "X509v3 Any Policy" */ - 1319, /* "X509v3 Associated Information" */ - 1307, /* "X509v3 Attribute Authority Issuing Distribution Point" */ - 1300, /* "X509v3 Attribute Descriptor" */ - 1312, /* "X509v3 Attribute Mappings" */ - 287, /* "X509v3 Audit Identity" */ - 1295, /* "X509v3 Authority Attribute Identifier" */ - 90, /* "X509v3 Authority Key Identifier" */ - 1314, /* "X509v3 Authorization Validation" */ - 1297, /* "X509v3 Basic Attribute Certificate Constraints" */ - 87, /* "X509v3 Basic Constraints" */ - 103, /* "X509v3 CRL Distribution Points" */ - 88, /* "X509v3 CRL Number" */ - 141, /* "X509v3 CRL Reason Code" */ - 771, /* "X509v3 Certificate Issuer" */ - 89, /* "X509v3 Certificate Policies" */ - 1298, /* "X509v3 Delegated Name Constraints" */ - 140, /* "X509v3 Delta CRL Indicator" */ - 126, /* "X509v3 Extended Key Usage" */ - 857, /* "X509v3 Freshest CRL" */ - 1310, /* "X509v3 Group Attribute Certificate" */ - 1313, /* "X509v3 Holder Name Constraints" */ - 1305, /* "X509v3 Indirect Issuer" */ - 748, /* "X509v3 Inhibit Any Policy" */ - 1308, /* "X509v3 Issued On Behalf Of" */ - 86, /* "X509v3 Issuer Alternative Name" */ - 770, /* "X509v3 Issuing Distribution Point" */ - 83, /* "X509v3 Key Usage" */ - 666, /* "X509v3 Name Constraints" */ - 1306, /* "X509v3 No Assertion" */ - 403, /* "X509v3 No Revocation Available" */ - 401, /* "X509v3 Policy Constraints" */ - 747, /* "X509v3 Policy Mappings" */ - 84, /* "X509v3 Private Key Usage Period" */ - 1315, /* "X509v3 Protocol Restriction" */ - 1296, /* "X509v3 Role Specification Certificate Identifier" */ - 1309, /* "X509v3 Single Use" */ - 1302, /* "X509v3 Source of Authority Identifier" */ - 85, /* "X509v3 Subject Alternative Name" */ - 1316, /* "X509v3 Subject Alternative Public Key Info" */ - 769, /* "X509v3 Subject Directory Attributes" */ - 82, /* "X509v3 Subject Key Identifier" */ - 1299, /* "X509v3 Time Specification" */ - 1301, /* "X509v3 User Notice" */ - 920, /* "X9.42 DH" */ - 184, /* "X9.57" */ - 185, /* "X9.57 CM ?" */ - 1209, /* "XmppAddr" */ - 1289, /* "Zstandard compression" */ - 478, /* "aRecord" */ - 289, /* "aaControls" */ - 397, /* "ac-proxying" */ - 288, /* "ac-targeting" */ - 446, /* "account" */ - 364, /* "ad dvcs" */ - 606, /* "additional verification" */ - 419, /* "aes-128-cbc" */ - 916, /* "aes-128-cbc-hmac-sha1" */ - 1487, /* "aes-128-cbc-hmac-sha1-etm" */ - 948, /* "aes-128-cbc-hmac-sha256" */ - 1490, /* "aes-128-cbc-hmac-sha256-etm" */ - 1493, /* "aes-128-cbc-hmac-sha512-etm" */ - 896, /* "aes-128-ccm" */ - 421, /* "aes-128-cfb" */ - 650, /* "aes-128-cfb1" */ - 653, /* "aes-128-cfb8" */ - 904, /* "aes-128-ctr" */ - 418, /* "aes-128-ecb" */ - 895, /* "aes-128-gcm" */ - 958, /* "aes-128-ocb" */ - 420, /* "aes-128-ofb" */ - 1198, /* "aes-128-siv" */ - 913, /* "aes-128-xts" */ - 423, /* "aes-192-cbc" */ - 917, /* "aes-192-cbc-hmac-sha1" */ - 1488, /* "aes-192-cbc-hmac-sha1-etm" */ - 949, /* "aes-192-cbc-hmac-sha256" */ - 1491, /* "aes-192-cbc-hmac-sha256-etm" */ - 1494, /* "aes-192-cbc-hmac-sha512-etm" */ - 899, /* "aes-192-ccm" */ - 425, /* "aes-192-cfb" */ - 651, /* "aes-192-cfb1" */ - 654, /* "aes-192-cfb8" */ - 905, /* "aes-192-ctr" */ - 422, /* "aes-192-ecb" */ - 898, /* "aes-192-gcm" */ - 959, /* "aes-192-ocb" */ - 424, /* "aes-192-ofb" */ - 1199, /* "aes-192-siv" */ - 427, /* "aes-256-cbc" */ - 918, /* "aes-256-cbc-hmac-sha1" */ - 1489, /* "aes-256-cbc-hmac-sha1-etm" */ - 950, /* "aes-256-cbc-hmac-sha256" */ - 1492, /* "aes-256-cbc-hmac-sha256-etm" */ - 1495, /* "aes-256-cbc-hmac-sha512-etm" */ - 902, /* "aes-256-ccm" */ - 429, /* "aes-256-cfb" */ - 652, /* "aes-256-cfb1" */ - 655, /* "aes-256-cfb8" */ - 906, /* "aes-256-ctr" */ - 426, /* "aes-256-ecb" */ - 901, /* "aes-256-gcm" */ - 960, /* "aes-256-ocb" */ - 428, /* "aes-256-ofb" */ - 1200, /* "aes-256-siv" */ - 914, /* "aes-256-xts" */ - 376, /* "algorithm" */ - 1066, /* "aria-128-cbc" */ - 1120, /* "aria-128-ccm" */ - 1067, /* "aria-128-cfb" */ - 1080, /* "aria-128-cfb1" */ - 1083, /* "aria-128-cfb8" */ - 1069, /* "aria-128-ctr" */ - 1065, /* "aria-128-ecb" */ - 1123, /* "aria-128-gcm" */ - 1068, /* "aria-128-ofb" */ - 1071, /* "aria-192-cbc" */ - 1121, /* "aria-192-ccm" */ - 1072, /* "aria-192-cfb" */ - 1081, /* "aria-192-cfb1" */ - 1084, /* "aria-192-cfb8" */ - 1074, /* "aria-192-ctr" */ - 1070, /* "aria-192-ecb" */ - 1124, /* "aria-192-gcm" */ - 1073, /* "aria-192-ofb" */ - 1076, /* "aria-256-cbc" */ - 1122, /* "aria-256-ccm" */ - 1077, /* "aria-256-cfb" */ - 1082, /* "aria-256-cfb1" */ - 1085, /* "aria-256-cfb8" */ - 1079, /* "aria-256-ctr" */ - 1075, /* "aria-256-ecb" */ - 1125, /* "aria-256-gcm" */ - 1078, /* "aria-256-ofb" */ - 484, /* "associatedDomain" */ - 485, /* "associatedName" */ - 501, /* "audio" */ - 1064, /* "auth-any" */ - 1049, /* "auth-dss" */ - 1047, /* "auth-ecdsa" */ - 1050, /* "auth-gost01" */ - 1051, /* "auth-gost12" */ - 1053, /* "auth-null" */ - 1048, /* "auth-psk" */ - 1046, /* "auth-rsa" */ - 1052, /* "auth-srp" */ - 882, /* "authorityRevocationList" */ - 91, /* "bf-cbc" */ - 93, /* "bf-cfb" */ - 92, /* "bf-ecb" */ - 94, /* "bf-ofb" */ - 1056, /* "blake2b512" */ - 1201, /* "blake2bmac" */ - 1057, /* "blake2s256" */ - 1202, /* "blake2smac" */ - 921, /* "brainpoolP160r1" */ - 922, /* "brainpoolP160t1" */ - 923, /* "brainpoolP192r1" */ - 924, /* "brainpoolP192t1" */ - 925, /* "brainpoolP224r1" */ - 926, /* "brainpoolP224t1" */ - 927, /* "brainpoolP256r1" */ - 1285, /* "brainpoolP256r1tls13" */ - 928, /* "brainpoolP256t1" */ - 929, /* "brainpoolP320r1" */ - 930, /* "brainpoolP320t1" */ - 931, /* "brainpoolP384r1" */ - 1286, /* "brainpoolP384r1tls13" */ - 932, /* "brainpoolP384t1" */ - 933, /* "brainpoolP512r1" */ - 1287, /* "brainpoolP512r1tls13" */ - 934, /* "brainpoolP512t1" */ - 494, /* "buildingName" */ - 860, /* "businessCategory" */ - 691, /* "c2onb191v4" */ - 692, /* "c2onb191v5" */ - 697, /* "c2onb239v4" */ - 698, /* "c2onb239v5" */ - 684, /* "c2pnb163v1" */ - 685, /* "c2pnb163v2" */ - 686, /* "c2pnb163v3" */ - 687, /* "c2pnb176v1" */ - 693, /* "c2pnb208w1" */ - 699, /* "c2pnb272w1" */ - 700, /* "c2pnb304w1" */ - 702, /* "c2pnb368w1" */ - 688, /* "c2tnb191v1" */ - 689, /* "c2tnb191v2" */ - 690, /* "c2tnb191v3" */ - 694, /* "c2tnb239v1" */ - 695, /* "c2tnb239v2" */ - 696, /* "c2tnb239v3" */ - 701, /* "c2tnb359v1" */ - 703, /* "c2tnb431r1" */ - 881, /* "cACertificate" */ - 483, /* "cNAMERecord" */ - 1273, /* "cades" */ - 1274, /* "cades-attributes" */ - 751, /* "camellia-128-cbc" */ - 962, /* "camellia-128-ccm" */ - 757, /* "camellia-128-cfb" */ - 760, /* "camellia-128-cfb1" */ - 763, /* "camellia-128-cfb8" */ - 964, /* "camellia-128-cmac" */ - 963, /* "camellia-128-ctr" */ - 754, /* "camellia-128-ecb" */ - 961, /* "camellia-128-gcm" */ - 766, /* "camellia-128-ofb" */ - 752, /* "camellia-192-cbc" */ - 966, /* "camellia-192-ccm" */ - 758, /* "camellia-192-cfb" */ - 761, /* "camellia-192-cfb1" */ - 764, /* "camellia-192-cfb8" */ - 968, /* "camellia-192-cmac" */ - 967, /* "camellia-192-ctr" */ - 755, /* "camellia-192-ecb" */ - 965, /* "camellia-192-gcm" */ - 767, /* "camellia-192-ofb" */ - 753, /* "camellia-256-cbc" */ - 970, /* "camellia-256-ccm" */ - 759, /* "camellia-256-cfb" */ - 762, /* "camellia-256-cfb1" */ - 765, /* "camellia-256-cfb8" */ - 972, /* "camellia-256-cmac" */ - 971, /* "camellia-256-ctr" */ - 756, /* "camellia-256-ecb" */ - 969, /* "camellia-256-gcm" */ - 768, /* "camellia-256-ofb" */ - 443, /* "caseIgnoreIA5StringSyntax" */ - 108, /* "cast5-cbc" */ - 110, /* "cast5-cfb" */ - 109, /* "cast5-ecb" */ - 111, /* "cast5-ofb" */ - 152, /* "certBag" */ - 677, /* "certicom-arc" */ - 517, /* "certificate extensions" */ - 883, /* "certificateRevocationList" */ - 1019, /* "chacha20" */ - 1018, /* "chacha20-poly1305" */ - 54, /* "challengePassword" */ - 407, /* "characteristic-two-field" */ - 395, /* "clearance" */ - 633, /* "cleartext track 2" */ - 894, /* "cmac" */ - 13, /* "commonName" */ - 513, /* "content types" */ - 50, /* "contentType" */ - 53, /* "countersignature" */ - 1090, /* "countryCode3c" */ - 1091, /* "countryCode3n" */ - 14, /* "countryName" */ - 153, /* "crlBag" */ - 884, /* "crossCertificatePair" */ - 806, /* "cryptocom" */ - 805, /* "cryptopro" */ - 500, /* "dITRedirect" */ - 451, /* "dNSDomain" */ - 495, /* "dSAQuality" */ - 434, /* "data" */ - 390, /* "dcObject" */ - 891, /* "deltaRevocationList" */ - 31, /* "des-cbc" */ - 643, /* "des-cdmf" */ - 30, /* "des-cfb" */ - 656, /* "des-cfb1" */ - 657, /* "des-cfb8" */ - 29, /* "des-ecb" */ - 32, /* "des-ede" */ - 43, /* "des-ede-cbc" */ - 60, /* "des-ede-cfb" */ - 62, /* "des-ede-ofb" */ - 33, /* "des-ede3" */ - 44, /* "des-ede3-cbc" */ - 61, /* "des-ede3-cfb" */ - 658, /* "des-ede3-cfb1" */ - 659, /* "des-ede3-cfb8" */ - 63, /* "des-ede3-ofb" */ - 45, /* "des-ofb" */ - 107, /* "description" */ - 871, /* "destinationIndicator" */ - 80, /* "desx-cbc" */ - 947, /* "dh-cofactor-kdf" */ - 946, /* "dh-std-kdf" */ - 28, /* "dhKeyAgreement" */ - 941, /* "dhSinglePass-cofactorDH-sha1kdf-scheme" */ - 942, /* "dhSinglePass-cofactorDH-sha224kdf-scheme" */ - 943, /* "dhSinglePass-cofactorDH-sha256kdf-scheme" */ - 944, /* "dhSinglePass-cofactorDH-sha384kdf-scheme" */ - 945, /* "dhSinglePass-cofactorDH-sha512kdf-scheme" */ - 936, /* "dhSinglePass-stdDH-sha1kdf-scheme" */ - 937, /* "dhSinglePass-stdDH-sha224kdf-scheme" */ - 938, /* "dhSinglePass-stdDH-sha256kdf-scheme" */ - 939, /* "dhSinglePass-stdDH-sha384kdf-scheme" */ - 940, /* "dhSinglePass-stdDH-sha512kdf-scheme" */ - 11, /* "directory services (X.500)" */ - 378, /* "directory services - algorithms" */ - 887, /* "distinguishedName" */ - 892, /* "dmdName" */ - 174, /* "dnQualifier" */ - 1092, /* "dnsName" */ - 447, /* "document" */ - 471, /* "documentAuthor" */ - 468, /* "documentIdentifier" */ - 472, /* "documentLocation" */ - 502, /* "documentPublisher" */ - 449, /* "documentSeries" */ - 469, /* "documentTitle" */ - 470, /* "documentVersion" */ - 380, /* "dod" */ - 391, /* "domainComponent" */ - 452, /* "domainRelatedObject" */ - 116, /* "dsaEncryption" */ - 67, /* "dsaEncryption-old" */ - 66, /* "dsaWithSHA" */ - 113, /* "dsaWithSHA1" */ - 70, /* "dsaWithSHA1-old" */ - 802, /* "dsa_with_SHA224" */ - 803, /* "dsa_with_SHA256" */ - 1108, /* "dsa_with_SHA3-224" */ - 1109, /* "dsa_with_SHA3-256" */ - 1110, /* "dsa_with_SHA3-384" */ - 1111, /* "dsa_with_SHA3-512" */ - 1106, /* "dsa_with_SHA384" */ - 1107, /* "dsa_with_SHA512" */ - 297, /* "dvcs" */ - 791, /* "ecdsa-with-Recommended" */ - 416, /* "ecdsa-with-SHA1" */ - 793, /* "ecdsa-with-SHA224" */ - 794, /* "ecdsa-with-SHA256" */ - 795, /* "ecdsa-with-SHA384" */ - 796, /* "ecdsa-with-SHA512" */ - 792, /* "ecdsa-with-Specified" */ - 1112, /* "ecdsa_with_SHA3-224" */ - 1113, /* "ecdsa_with_SHA3-256" */ - 1114, /* "ecdsa_with_SHA3-384" */ - 1115, /* "ecdsa_with_SHA3-512" */ - 1266, /* "electronic-signature-standard" */ - 48, /* "emailAddress" */ - 632, /* "encrypted track 2" */ - 885, /* "enhancedSearchGuide" */ - 1267, /* "ess-attributes" */ - 1265, /* "etsi" */ - 56, /* "extendedCertificateAttributes" */ - 867, /* "facsimileTelephoneNumber" */ - 462, /* "favouriteDrink" */ - 1126, /* "ffdhe2048" */ - 1127, /* "ffdhe3072" */ - 1128, /* "ffdhe4096" */ - 1129, /* "ffdhe6144" */ - 1130, /* "ffdhe8192" */ - 453, /* "friendlyCountry" */ - 490, /* "friendlyCountryName" */ - 156, /* "friendlyName" */ - 631, /* "generate cryptogram" */ - 509, /* "generationQualifier" */ - 601, /* "generic cryptogram" */ - 99, /* "givenName" */ - 1195, /* "gmac" */ - 976, /* "gost-mac-12" */ - 1009, /* "gost89-cbc" */ - 814, /* "gost89-cnt" */ - 975, /* "gost89-cnt-12" */ - 1011, /* "gost89-ctr" */ - 1010, /* "gost89-ecb" */ - 1036, /* "hkdf" */ - 855, /* "hmac" */ - 780, /* "hmac-md5" */ - 781, /* "hmac-sha1" */ - 1102, /* "hmac-sha3-224" */ - 1103, /* "hmac-sha3-256" */ - 1104, /* "hmac-sha3-384" */ - 1105, /* "hmac-sha3-512" */ - 797, /* "hmacWithMD5" */ - 163, /* "hmacWithSHA1" */ - 798, /* "hmacWithSHA224" */ - 799, /* "hmacWithSHA256" */ - 800, /* "hmacWithSHA384" */ - 801, /* "hmacWithSHA512" */ - 1193, /* "hmacWithSHA512-224" */ - 1194, /* "hmacWithSHA512-256" */ - 1281, /* "hmacWithSM3" */ - 486, /* "homePostalAddress" */ - 473, /* "homeTelephoneNumber" */ - 466, /* "host" */ - 889, /* "houseIdentifier" */ - 442, /* "iA5StringSyntax" */ - 381, /* "iana" */ - 824, /* "id-Gost28147-89-CryptoPro-A-ParamSet" */ - 825, /* "id-Gost28147-89-CryptoPro-B-ParamSet" */ - 826, /* "id-Gost28147-89-CryptoPro-C-ParamSet" */ - 827, /* "id-Gost28147-89-CryptoPro-D-ParamSet" */ - 819, /* "id-Gost28147-89-CryptoPro-KeyMeshing" */ - 829, /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */ - 828, /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */ - 830, /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */ - 820, /* "id-Gost28147-89-None-KeyMeshing" */ - 823, /* "id-Gost28147-89-TestParamSet" */ - 840, /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */ - 841, /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */ - 842, /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */ - 843, /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */ - 844, /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */ - 839, /* "id-GostR3410-2001-TestParamSet" */ - 832, /* "id-GostR3410-94-CryptoPro-A-ParamSet" */ - 833, /* "id-GostR3410-94-CryptoPro-B-ParamSet" */ - 834, /* "id-GostR3410-94-CryptoPro-C-ParamSet" */ - 835, /* "id-GostR3410-94-CryptoPro-D-ParamSet" */ - 836, /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */ - 837, /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */ - 838, /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */ - 831, /* "id-GostR3410-94-TestParamSet" */ - 845, /* "id-GostR3410-94-a" */ - 846, /* "id-GostR3410-94-aBis" */ - 847, /* "id-GostR3410-94-b" */ - 848, /* "id-GostR3410-94-bBis" */ - 822, /* "id-GostR3411-94-CryptoProParamSet" */ - 821, /* "id-GostR3411-94-TestParamSet" */ - 1272, /* "id-aa-ATSHashIndex" */ - 1277, /* "id-aa-ATSHashIndex-v2" */ - 1278, /* "id-aa-ATSHashIndex-v3" */ - 1263, /* "id-aa-CMSAlgorithmProtection" */ - 1270, /* "id-aa-ets-SignaturePolicyDocument" */ - 1280, /* "id-aa-ets-archiveTimestampV2" */ - 1271, /* "id-aa-ets-archiveTimestampV3" */ - 1261, /* "id-aa-ets-attrCertificateRefs" */ - 1262, /* "id-aa-ets-attrRevocationRefs" */ - 1269, /* "id-aa-ets-longTermValidation" */ - 1268, /* "id-aa-ets-mimeType" */ - 1276, /* "id-aa-ets-sigPolicyStore" */ - 1275, /* "id-aa-ets-signerAttrV2" */ - 266, /* "id-aca" */ - 355, /* "id-aca-accessIdentity" */ - 354, /* "id-aca-authenticationInfo" */ - 356, /* "id-aca-chargingIdentity" */ - 399, /* "id-aca-encAttrs" */ - 357, /* "id-aca-group" */ - 358, /* "id-aca-role" */ - 176, /* "id-ad" */ - 788, /* "id-aes128-wrap" */ - 897, /* "id-aes128-wrap-pad" */ - 789, /* "id-aes192-wrap" */ - 900, /* "id-aes192-wrap-pad" */ - 790, /* "id-aes256-wrap" */ - 903, /* "id-aes256-wrap-pad" */ - 262, /* "id-alg" */ - 893, /* "id-alg-PWRI-KEK" */ - 323, /* "id-alg-des40" */ - 326, /* "id-alg-dh-pop" */ - 325, /* "id-alg-dh-sig-hmac-sha1" */ - 1501, /* "id-alg-hss-lms-hashsig" */ - 324, /* "id-alg-noSignature" */ - 907, /* "id-camellia128-wrap" */ - 908, /* "id-camellia192-wrap" */ - 909, /* "id-camellia256-wrap" */ - 268, /* "id-cct" */ - 361, /* "id-cct-PKIData" */ - 362, /* "id-cct-PKIResponse" */ - 360, /* "id-cct-crs" */ - 81, /* "id-ce" */ - 680, /* "id-characteristic-two-basis" */ - 263, /* "id-cmc" */ - 334, /* "id-cmc-addExtensions" */ - 346, /* "id-cmc-confirmCertAcceptance" */ - 330, /* "id-cmc-dataReturn" */ - 336, /* "id-cmc-decryptedPOP" */ - 335, /* "id-cmc-encryptedPOP" */ - 339, /* "id-cmc-getCRL" */ - 338, /* "id-cmc-getCert" */ - 328, /* "id-cmc-identification" */ - 329, /* "id-cmc-identityProof" */ - 337, /* "id-cmc-lraPOPWitness" */ - 344, /* "id-cmc-popLinkRandom" */ - 345, /* "id-cmc-popLinkWitness" */ - 343, /* "id-cmc-queryPending" */ - 333, /* "id-cmc-recipientNonce" */ - 341, /* "id-cmc-regInfo" */ - 342, /* "id-cmc-responseInfo" */ - 340, /* "id-cmc-revokeRequest" */ - 332, /* "id-cmc-senderNonce" */ - 327, /* "id-cmc-statusInfo" */ - 331, /* "id-cmc-transactionId" */ - 1238, /* "id-cp" */ - 1250, /* "id-ct-ASPA" */ - 787, /* "id-ct-asciiTextWithCRLF" */ - 1246, /* "id-ct-geofeedCSVwithCRLF" */ - 1237, /* "id-ct-resourceTaggedAttest" */ - 1234, /* "id-ct-routeOriginAuthz" */ - 1236, /* "id-ct-rpkiGhostbusters" */ - 1235, /* "id-ct-rpkiManifest" */ - 1320, /* "id-ct-rpkiSignedPrefixList" */ - 1247, /* "id-ct-signedChecklist" */ - 1284, /* "id-ct-signedTAL" */ - 1060, /* "id-ct-xml" */ - 408, /* "id-ecPublicKey" */ - 508, /* "id-hex-multipart-message" */ - 507, /* "id-hex-partial-message" */ - 260, /* "id-it" */ - 1223, /* "id-it-caCerts" */ - 302, /* "id-it-caKeyUpdateInfo" */ - 298, /* "id-it-caProtEncCert" */ - 1255, /* "id-it-certProfile" */ - 1225, /* "id-it-certReqTemplate" */ - 311, /* "id-it-confirmWaitTime" */ - 1256, /* "id-it-crlStatusList" */ - 1257, /* "id-it-crls" */ - 303, /* "id-it-currentCRL" */ - 300, /* "id-it-encKeyPairTypes" */ - 310, /* "id-it-implicitConfirm" */ - 308, /* "id-it-keyPairParamRep" */ - 307, /* "id-it-keyPairParamReq" */ - 312, /* "id-it-origPKIMessage" */ - 301, /* "id-it-preferredSymmAlg" */ - 309, /* "id-it-revPassphrase" */ - 1254, /* "id-it-rootCaCert" */ - 1224, /* "id-it-rootCaKeyUpdate" */ - 299, /* "id-it-signKeyPairTypes" */ - 305, /* "id-it-subscriptionRequest" */ - 306, /* "id-it-subscriptionResponse" */ - 784, /* "id-it-suppLangTags" */ - 304, /* "id-it-unsupportedOIDs" */ - 128, /* "id-kp" */ - 280, /* "id-mod-attribute-cert" */ - 274, /* "id-mod-cmc" */ - 277, /* "id-mod-cmp" */ - 284, /* "id-mod-cmp2000" */ - 1251, /* "id-mod-cmp2000-02" */ - 1253, /* "id-mod-cmp2021-02" */ - 1252, /* "id-mod-cmp2021-88" */ - 273, /* "id-mod-crmf" */ - 283, /* "id-mod-dvcs" */ - 275, /* "id-mod-kea-profile-88" */ - 276, /* "id-mod-kea-profile-93" */ - 282, /* "id-mod-ocsp" */ - 278, /* "id-mod-qualified-cert-88" */ - 279, /* "id-mod-qualified-cert-93" */ - 281, /* "id-mod-timestamp-protocol" */ - 264, /* "id-on" */ - 347, /* "id-on-personalData" */ - 265, /* "id-pda" */ - 352, /* "id-pda-countryOfCitizenship" */ - 353, /* "id-pda-countryOfResidence" */ - 348, /* "id-pda-dateOfBirth" */ - 351, /* "id-pda-gender" */ - 349, /* "id-pda-placeOfBirth" */ - 175, /* "id-pe" */ - 1031, /* "id-pkinit" */ - 261, /* "id-pkip" */ - 258, /* "id-pkix-mod" */ - 269, /* "id-pkix1-explicit-88" */ - 271, /* "id-pkix1-explicit-93" */ - 270, /* "id-pkix1-implicit-88" */ - 272, /* "id-pkix1-implicit-93" */ - 662, /* "id-ppl" */ - 267, /* "id-qcs" */ - 359, /* "id-qcs-pkixQCSyntax-v1" */ - 259, /* "id-qt" */ - 313, /* "id-regCtrl" */ - 1259, /* "id-regCtrl-algId" */ - 1258, /* "id-regCtrl-altCertTemplate" */ - 316, /* "id-regCtrl-authenticator" */ - 319, /* "id-regCtrl-oldCertID" */ - 318, /* "id-regCtrl-pkiArchiveOptions" */ - 317, /* "id-regCtrl-pkiPublicationInfo" */ - 320, /* "id-regCtrl-protocolEncrKey" */ - 315, /* "id-regCtrl-regToken" */ - 1260, /* "id-regCtrl-rsaKeyLen" */ - 314, /* "id-regInfo" */ - 322, /* "id-regInfo-certReq" */ - 321, /* "id-regInfo-utf8Pairs" */ - 191, /* "id-smime-aa" */ - 215, /* "id-smime-aa-contentHint" */ - 218, /* "id-smime-aa-contentIdentifier" */ - 221, /* "id-smime-aa-contentReference" */ - 240, /* "id-smime-aa-dvcs-dvc" */ - 217, /* "id-smime-aa-encapContentType" */ - 222, /* "id-smime-aa-encrypKeyPref" */ - 220, /* "id-smime-aa-equivalentLabels" */ - 232, /* "id-smime-aa-ets-CertificateRefs" */ - 233, /* "id-smime-aa-ets-RevocationRefs" */ - 238, /* "id-smime-aa-ets-archiveTimeStamp" */ - 237, /* "id-smime-aa-ets-certCRLTimestamp" */ - 234, /* "id-smime-aa-ets-certValues" */ - 227, /* "id-smime-aa-ets-commitmentType" */ - 231, /* "id-smime-aa-ets-contentTimestamp" */ - 236, /* "id-smime-aa-ets-escTimeStamp" */ - 230, /* "id-smime-aa-ets-otherSigCert" */ - 235, /* "id-smime-aa-ets-revocationValues" */ - 226, /* "id-smime-aa-ets-sigPolicyId" */ - 229, /* "id-smime-aa-ets-signerAttr" */ - 228, /* "id-smime-aa-ets-signerLocation" */ - 219, /* "id-smime-aa-macValue" */ - 214, /* "id-smime-aa-mlExpandHistory" */ - 216, /* "id-smime-aa-msgSigDigest" */ - 212, /* "id-smime-aa-receiptRequest" */ - 213, /* "id-smime-aa-securityLabel" */ - 239, /* "id-smime-aa-signatureType" */ - 223, /* "id-smime-aa-signingCertificate" */ - 1086, /* "id-smime-aa-signingCertificateV2" */ - 224, /* "id-smime-aa-smimeEncryptCerts" */ - 225, /* "id-smime-aa-timeStampToken" */ - 192, /* "id-smime-alg" */ - 243, /* "id-smime-alg-3DESwrap" */ - 246, /* "id-smime-alg-CMS3DESwrap" */ - 247, /* "id-smime-alg-CMSRC2wrap" */ - 245, /* "id-smime-alg-ESDH" */ - 241, /* "id-smime-alg-ESDHwith3DES" */ - 242, /* "id-smime-alg-ESDHwithRC2" */ - 244, /* "id-smime-alg-RC2wrap" */ - 193, /* "id-smime-cd" */ - 248, /* "id-smime-cd-ldap" */ - 190, /* "id-smime-ct" */ - 210, /* "id-smime-ct-DVCSRequestData" */ - 211, /* "id-smime-ct-DVCSResponseData" */ - 208, /* "id-smime-ct-TDTInfo" */ - 207, /* "id-smime-ct-TSTInfo" */ - 205, /* "id-smime-ct-authData" */ - 1059, /* "id-smime-ct-authEnvelopedData" */ - 786, /* "id-smime-ct-compressedData" */ - 1058, /* "id-smime-ct-contentCollection" */ - 209, /* "id-smime-ct-contentInfo" */ - 206, /* "id-smime-ct-publishCert" */ - 204, /* "id-smime-ct-receipt" */ - 195, /* "id-smime-cti" */ - 255, /* "id-smime-cti-ets-proofOfApproval" */ - 256, /* "id-smime-cti-ets-proofOfCreation" */ - 253, /* "id-smime-cti-ets-proofOfDelivery" */ - 251, /* "id-smime-cti-ets-proofOfOrigin" */ - 252, /* "id-smime-cti-ets-proofOfReceipt" */ - 254, /* "id-smime-cti-ets-proofOfSender" */ - 189, /* "id-smime-mod" */ - 196, /* "id-smime-mod-cms" */ - 197, /* "id-smime-mod-ess" */ - 202, /* "id-smime-mod-ets-eSigPolicy-88" */ - 203, /* "id-smime-mod-ets-eSigPolicy-97" */ - 200, /* "id-smime-mod-ets-eSignature-88" */ - 201, /* "id-smime-mod-ets-eSignature-97" */ - 199, /* "id-smime-mod-msg-v3" */ - 198, /* "id-smime-mod-oid" */ - 1499, /* "id-smime-ori" */ - 1500, /* "id-smime-ori-kem" */ - 194, /* "id-smime-spq" */ - 250, /* "id-smime-spq-ets-sqt-unotice" */ - 249, /* "id-smime-spq-ets-sqt-uri" */ - 974, /* "id-tc26" */ - 991, /* "id-tc26-agreement" */ - 992, /* "id-tc26-agreement-gost-3410-2012-256" */ - 993, /* "id-tc26-agreement-gost-3410-2012-512" */ - 977, /* "id-tc26-algorithms" */ - 990, /* "id-tc26-cipher" */ - 1001, /* "id-tc26-cipher-constants" */ - 1176, /* "id-tc26-cipher-gostr3412-2015-kuznyechik" */ - 1173, /* "id-tc26-cipher-gostr3412-2015-magma" */ - 994, /* "id-tc26-constants" */ - 981, /* "id-tc26-digest" */ - 1000, /* "id-tc26-digest-constants" */ - 1002, /* "id-tc26-gost-28147-constants" */ - 1147, /* "id-tc26-gost-3410-2012-256-constants" */ - 996, /* "id-tc26-gost-3410-2012-512-constants" */ - 987, /* "id-tc26-mac" */ - 978, /* "id-tc26-sign" */ - 995, /* "id-tc26-sign-constants" */ - 984, /* "id-tc26-signwithdigest" */ - 1179, /* "id-tc26-wrap" */ - 1182, /* "id-tc26-wrap-gostr3412-2015-kuznyechik" */ - 1180, /* "id-tc26-wrap-gostr3412-2015-magma" */ - 34, /* "idea-cbc" */ - 35, /* "idea-cfb" */ - 36, /* "idea-ecb" */ - 46, /* "idea-ofb" */ - 676, /* "identified-organization" */ - 1170, /* "ieee" */ - 461, /* "info" */ - 101, /* "initials" */ - 869, /* "internationaliSDNNumber" */ - 1241, /* "ipAddr-asNumber" */ - 1242, /* "ipAddr-asNumberv2" */ - 1022, /* "ipsec Internet Key Exchange" */ - 749, /* "ipsec3" */ - 750, /* "ipsec4" */ - 181, /* "iso" */ - 623, /* "issuer capabilities" */ - 645, /* "itu-t" */ - 1264, /* "itu-t-identified-organization" */ - 492, /* "janetMailbox" */ - 646, /* "joint-iso-itu-t" */ - 957, /* "jurisdictionCountryName" */ - 955, /* "jurisdictionLocalityName" */ - 956, /* "jurisdictionStateOrProvinceName" */ - 150, /* "keyBag" */ - 773, /* "kisa" */ - 1196, /* "kmac128" */ - 1197, /* "kmac256" */ - 1015, /* "kuznyechik-cbc" */ - 1016, /* "kuznyechik-cfb" */ - 1013, /* "kuznyechik-ctr" */ - 1177, /* "kuznyechik-ctr-acpkm" */ - 1178, /* "kuznyechik-ctr-acpkm-omac" */ - 1012, /* "kuznyechik-ecb" */ - 1183, /* "kuznyechik-kexp15" */ - 1017, /* "kuznyechik-mac" */ - 1014, /* "kuznyechik-ofb" */ - 1063, /* "kx-any" */ - 1039, /* "kx-dhe" */ - 1041, /* "kx-dhe-psk" */ - 1038, /* "kx-ecdhe" */ - 1040, /* "kx-ecdhe-psk" */ - 1045, /* "kx-gost" */ - 1218, /* "kx-gost18" */ - 1043, /* "kx-psk" */ - 1037, /* "kx-rsa" */ - 1042, /* "kx-rsa-psk" */ - 1044, /* "kx-srp" */ - 477, /* "lastModifiedBy" */ - 476, /* "lastModifiedTime" */ - 157, /* "localKeyID" */ - 15, /* "localityName" */ - 480, /* "mXRecord" */ - 1190, /* "magma-cbc" */ - 1191, /* "magma-cfb" */ - 1188, /* "magma-ctr" */ - 1174, /* "magma-ctr-acpkm" */ - 1175, /* "magma-ctr-acpkm-omac" */ - 1187, /* "magma-ecb" */ - 1181, /* "magma-kexp15" */ - 1192, /* "magma-mac" */ - 1189, /* "magma-ofb" */ - 493, /* "mailPreferenceOption" */ - 467, /* "manager" */ - 3, /* "md2" */ - 7, /* "md2WithRSAEncryption" */ - 257, /* "md4" */ - 396, /* "md4WithRSAEncryption" */ - 4, /* "md5" */ - 114, /* "md5-sha1" */ - 104, /* "md5WithRSA" */ - 8, /* "md5WithRSAEncryption" */ - 95, /* "mdc2" */ - 96, /* "mdc2WithRSA" */ - 875, /* "member" */ - 602, /* "merchant initiated auth" */ - 514, /* "message extensions" */ - 51, /* "messageDigest" */ - 911, /* "mgf1" */ - 506, /* "mime-mhs-bodies" */ - 505, /* "mime-mhs-headings" */ - 488, /* "mobileTelephoneNumber" */ - 1212, /* "modp_1536" */ - 1213, /* "modp_2048" */ - 1214, /* "modp_3072" */ - 1215, /* "modp_4096" */ - 1216, /* "modp_6144" */ - 1217, /* "modp_8192" */ - 481, /* "nSRecord" */ - 173, /* "name" */ - 681, /* "onBasis" */ - 379, /* "org" */ - 1089, /* "organizationIdentifier" */ - 17, /* "organizationName" */ - 491, /* "organizationalStatus" */ - 18, /* "organizationalUnitName" */ - 1141, /* "oscca" */ - 475, /* "otherMailbox" */ - 876, /* "owner" */ - 935, /* "pSpecified" */ - 489, /* "pagerTelephoneNumber" */ - 782, /* "password based MAC" */ - 374, /* "path" */ - 621, /* "payment gateway capabilities" */ - 9, /* "pbeWithMD2AndDES-CBC" */ - 168, /* "pbeWithMD2AndRC2-CBC" */ - 112, /* "pbeWithMD5AndCast5CBC" */ - 10, /* "pbeWithMD5AndDES-CBC" */ - 169, /* "pbeWithMD5AndRC2-CBC" */ - 148, /* "pbeWithSHA1And128BitRC2-CBC" */ - 144, /* "pbeWithSHA1And128BitRC4" */ - 147, /* "pbeWithSHA1And2-KeyTripleDES-CBC" */ - 146, /* "pbeWithSHA1And3-KeyTripleDES-CBC" */ - 149, /* "pbeWithSHA1And40BitRC2-CBC" */ - 145, /* "pbeWithSHA1And40BitRC4" */ - 170, /* "pbeWithSHA1AndDES-CBC" */ - 68, /* "pbeWithSHA1AndRC2-CBC" */ - 499, /* "personalSignature" */ - 487, /* "personalTitle" */ - 464, /* "photo" */ - 863, /* "physicalDeliveryOfficeName" */ - 437, /* "pilot" */ - 439, /* "pilotAttributeSyntax" */ - 438, /* "pilotAttributeType" */ - 479, /* "pilotAttributeType27" */ - 456, /* "pilotDSA" */ - 441, /* "pilotGroups" */ - 444, /* "pilotObject" */ - 440, /* "pilotObjectClass" */ - 455, /* "pilotOrganization" */ - 445, /* "pilotPerson" */ - 186, /* "pkcs1" */ - 27, /* "pkcs3" */ - 187, /* "pkcs5" */ - 20, /* "pkcs7" */ - 21, /* "pkcs7-data" */ - 25, /* "pkcs7-digestData" */ - 26, /* "pkcs7-encryptedData" */ - 23, /* "pkcs7-envelopedData" */ - 24, /* "pkcs7-signedAndEnvelopedData" */ - 22, /* "pkcs7-signedData" */ - 151, /* "pkcs8ShroudedKeyBag" */ - 47, /* "pkcs9" */ - 1061, /* "poly1305" */ - 862, /* "postOfficeBox" */ - 861, /* "postalAddress" */ - 661, /* "postalCode" */ - 683, /* "ppBasis" */ - 872, /* "preferredDeliveryMethod" */ - 873, /* "presentationAddress" */ - 406, /* "prime-field" */ - 409, /* "prime192v1" */ - 410, /* "prime192v2" */ - 411, /* "prime192v3" */ - 412, /* "prime239v1" */ - 413, /* "prime239v2" */ - 414, /* "prime239v3" */ - 415, /* "prime256v1" */ - 886, /* "protocolInformation" */ - 510, /* "pseudonym" */ - 435, /* "pss" */ - 286, /* "qcStatements" */ - 457, /* "qualityLabelledData" */ - 450, /* "rFC822localPart" */ - 98, /* "rc2-40-cbc" */ - 166, /* "rc2-64-cbc" */ - 37, /* "rc2-cbc" */ - 39, /* "rc2-cfb" */ - 38, /* "rc2-ecb" */ - 40, /* "rc2-ofb" */ - 5, /* "rc4" */ - 97, /* "rc4-40" */ - 915, /* "rc4-hmac-md5" */ - 120, /* "rc5-cbc" */ - 122, /* "rc5-cfb" */ - 121, /* "rc5-ecb" */ - 123, /* "rc5-ofb" */ - 870, /* "registeredAddress" */ - 460, /* "rfc822Mailbox" */ - 117, /* "ripemd160" */ - 119, /* "ripemd160WithRSA" */ - 400, /* "role" */ - 877, /* "roleOccupant" */ - 448, /* "room" */ - 463, /* "roomNumber" */ - 19, /* "rsa" */ - 6, /* "rsaEncryption" */ - 644, /* "rsaOAEPEncryptionSET" */ - 377, /* "rsaSignature" */ - 919, /* "rsaesOaep" */ - 912, /* "rsassaPss" */ - 482, /* "sOARecord" */ - 155, /* "safeContentsBag" */ - 291, /* "sbgp-autonomousSysNum" */ - 1240, /* "sbgp-autonomousSysNumv2" */ - 290, /* "sbgp-ipAddrBlock" */ - 1239, /* "sbgp-ipAddrBlockv2" */ - 292, /* "sbgp-routerIdentifier" */ - 973, /* "scrypt" */ - 159, /* "sdsiCertificate" */ - 859, /* "searchGuide" */ - 704, /* "secp112r1" */ - 705, /* "secp112r2" */ - 706, /* "secp128r1" */ - 707, /* "secp128r2" */ - 708, /* "secp160k1" */ - 709, /* "secp160r1" */ - 710, /* "secp160r2" */ - 711, /* "secp192k1" */ - 712, /* "secp224k1" */ - 713, /* "secp224r1" */ - 714, /* "secp256k1" */ - 715, /* "secp384r1" */ - 716, /* "secp521r1" */ - 154, /* "secretBag" */ - 474, /* "secretary" */ - 717, /* "sect113r1" */ - 718, /* "sect113r2" */ - 719, /* "sect131r1" */ - 720, /* "sect131r2" */ - 721, /* "sect163k1" */ - 722, /* "sect163r1" */ - 723, /* "sect163r2" */ - 724, /* "sect193r1" */ - 725, /* "sect193r2" */ - 726, /* "sect233k1" */ - 727, /* "sect233r1" */ - 728, /* "sect239k1" */ - 729, /* "sect283k1" */ - 730, /* "sect283r1" */ - 731, /* "sect409k1" */ - 732, /* "sect409r1" */ - 733, /* "sect571k1" */ - 734, /* "sect571r1" */ - 635, /* "secure device signature" */ - 878, /* "seeAlso" */ - 777, /* "seed-cbc" */ - 779, /* "seed-cfb" */ - 776, /* "seed-ecb" */ - 778, /* "seed-ofb" */ - 105, /* "serialNumber" */ - 625, /* "set-addPolicy" */ - 515, /* "set-attr" */ - 518, /* "set-brand" */ - 638, /* "set-brand-AmericanExpress" */ - 637, /* "set-brand-Diners" */ - 636, /* "set-brand-IATA-ATA" */ - 639, /* "set-brand-JCB" */ - 641, /* "set-brand-MasterCard" */ - 642, /* "set-brand-Novus" */ - 640, /* "set-brand-Visa" */ - 516, /* "set-policy" */ - 607, /* "set-policy-root" */ - 624, /* "set-rootKeyThumb" */ - 620, /* "setAttr-Cert" */ - 628, /* "setAttr-IssCap-CVM" */ - 630, /* "setAttr-IssCap-Sig" */ - 629, /* "setAttr-IssCap-T2" */ - 627, /* "setAttr-Token-B0Prime" */ - 626, /* "setAttr-Token-EMV" */ - 622, /* "setAttr-TokenType" */ - 619, /* "setCext-IssuerCapabilities" */ - 615, /* "setCext-PGWYcapabilities" */ - 616, /* "setCext-TokenIdentifier" */ - 618, /* "setCext-TokenType" */ - 617, /* "setCext-Track2Data" */ - 611, /* "setCext-cCertRequired" */ - 609, /* "setCext-certType" */ - 608, /* "setCext-hashedRoot" */ - 610, /* "setCext-merchData" */ - 613, /* "setCext-setExt" */ - 614, /* "setCext-setQualf" */ - 612, /* "setCext-tunneling" */ - 540, /* "setct-AcqCardCodeMsg" */ - 576, /* "setct-AcqCardCodeMsgTBE" */ - 570, /* "setct-AuthReqTBE" */ - 534, /* "setct-AuthReqTBS" */ - 527, /* "setct-AuthResBaggage" */ - 571, /* "setct-AuthResTBE" */ - 572, /* "setct-AuthResTBEX" */ - 535, /* "setct-AuthResTBS" */ - 536, /* "setct-AuthResTBSX" */ - 528, /* "setct-AuthRevReqBaggage" */ - 577, /* "setct-AuthRevReqTBE" */ - 541, /* "setct-AuthRevReqTBS" */ - 529, /* "setct-AuthRevResBaggage" */ - 542, /* "setct-AuthRevResData" */ - 578, /* "setct-AuthRevResTBE" */ - 579, /* "setct-AuthRevResTBEB" */ - 543, /* "setct-AuthRevResTBS" */ - 573, /* "setct-AuthTokenTBE" */ - 537, /* "setct-AuthTokenTBS" */ - 600, /* "setct-BCIDistributionTBS" */ - 558, /* "setct-BatchAdminReqData" */ - 592, /* "setct-BatchAdminReqTBE" */ - 559, /* "setct-BatchAdminResData" */ - 593, /* "setct-BatchAdminResTBE" */ - 599, /* "setct-CRLNotificationResTBS" */ - 598, /* "setct-CRLNotificationTBS" */ - 580, /* "setct-CapReqTBE" */ - 581, /* "setct-CapReqTBEX" */ - 544, /* "setct-CapReqTBS" */ - 545, /* "setct-CapReqTBSX" */ - 546, /* "setct-CapResData" */ - 582, /* "setct-CapResTBE" */ - 583, /* "setct-CapRevReqTBE" */ - 584, /* "setct-CapRevReqTBEX" */ - 547, /* "setct-CapRevReqTBS" */ - 548, /* "setct-CapRevReqTBSX" */ - 549, /* "setct-CapRevResData" */ - 585, /* "setct-CapRevResTBE" */ - 538, /* "setct-CapTokenData" */ - 530, /* "setct-CapTokenSeq" */ - 574, /* "setct-CapTokenTBE" */ - 575, /* "setct-CapTokenTBEX" */ - 539, /* "setct-CapTokenTBS" */ - 560, /* "setct-CardCInitResTBS" */ - 566, /* "setct-CertInqReqTBS" */ - 563, /* "setct-CertReqData" */ - 595, /* "setct-CertReqTBE" */ - 596, /* "setct-CertReqTBEX" */ - 564, /* "setct-CertReqTBS" */ - 565, /* "setct-CertResData" */ - 597, /* "setct-CertResTBE" */ - 586, /* "setct-CredReqTBE" */ - 587, /* "setct-CredReqTBEX" */ - 550, /* "setct-CredReqTBS" */ - 551, /* "setct-CredReqTBSX" */ - 552, /* "setct-CredResData" */ - 588, /* "setct-CredResTBE" */ - 589, /* "setct-CredRevReqTBE" */ - 590, /* "setct-CredRevReqTBEX" */ - 553, /* "setct-CredRevReqTBS" */ - 554, /* "setct-CredRevReqTBSX" */ - 555, /* "setct-CredRevResData" */ - 591, /* "setct-CredRevResTBE" */ - 567, /* "setct-ErrorTBS" */ - 526, /* "setct-HODInput" */ - 561, /* "setct-MeAqCInitResTBS" */ - 522, /* "setct-OIData" */ - 519, /* "setct-PANData" */ - 521, /* "setct-PANOnly" */ - 520, /* "setct-PANToken" */ - 556, /* "setct-PCertReqData" */ - 557, /* "setct-PCertResTBS" */ - 523, /* "setct-PI" */ - 532, /* "setct-PI-TBS" */ - 524, /* "setct-PIData" */ - 525, /* "setct-PIDataUnsigned" */ - 568, /* "setct-PIDualSignedTBE" */ - 569, /* "setct-PIUnsignedTBE" */ - 531, /* "setct-PInitResData" */ - 533, /* "setct-PResData" */ - 594, /* "setct-RegFormReqTBE" */ - 562, /* "setct-RegFormResTBS" */ - 604, /* "setext-pinAny" */ - 603, /* "setext-pinSecure" */ - 605, /* "setext-track2" */ - 41, /* "sha" */ - 64, /* "sha1" */ - 115, /* "sha1WithRSA" */ - 65, /* "sha1WithRSAEncryption" */ - 675, /* "sha224" */ - 671, /* "sha224WithRSAEncryption" */ - 672, /* "sha256" */ - 668, /* "sha256WithRSAEncryption" */ - 1096, /* "sha3-224" */ - 1097, /* "sha3-256" */ - 1098, /* "sha3-384" */ - 1099, /* "sha3-512" */ - 673, /* "sha384" */ - 669, /* "sha384WithRSAEncryption" */ - 674, /* "sha512" */ - 1094, /* "sha512-224" */ - 1145, /* "sha512-224WithRSAEncryption" */ - 1095, /* "sha512-256" */ - 1146, /* "sha512-256WithRSAEncryption" */ - 670, /* "sha512WithRSAEncryption" */ - 42, /* "shaWithRSAEncryption" */ - 1100, /* "shake128" */ - 1101, /* "shake256" */ - 1279, /* "signedAssertion" */ - 52, /* "signingTime" */ - 454, /* "simpleSecurityObject" */ - 496, /* "singleLevelQuality" */ - 1062, /* "siphash" */ - 1142, /* "sm-scheme" */ - 1172, /* "sm2" */ - 1143, /* "sm3" */ - 1144, /* "sm3WithRSAEncryption" */ - 1134, /* "sm4-cbc" */ - 1249, /* "sm4-ccm" */ - 1137, /* "sm4-cfb" */ - 1136, /* "sm4-cfb1" */ - 1138, /* "sm4-cfb8" */ - 1139, /* "sm4-ctr" */ - 1133, /* "sm4-ecb" */ - 1248, /* "sm4-gcm" */ - 1135, /* "sm4-ofb" */ - 1290, /* "sm4-xts" */ - 1203, /* "sshkdf" */ - 1205, /* "sskdf" */ - 16, /* "stateOrProvinceName" */ - 660, /* "streetAddress" */ - 498, /* "subtreeMaximumQuality" */ - 497, /* "subtreeMinimumQuality" */ - 890, /* "supportedAlgorithms" */ - 874, /* "supportedApplicationContext" */ - 100, /* "surname" */ - 1325, /* "tcg-tcpaSpecVersion" */ - 864, /* "telephoneNumber" */ - 866, /* "teletexTerminalIdentifier" */ - 865, /* "telexNumber" */ - 459, /* "textEncodedORAddress" */ - 293, /* "textNotice" */ - 106, /* "title" */ - 1021, /* "tls1-prf" */ - 682, /* "tpBasis" */ - 1151, /* "ua-pki" */ - 436, /* "ucl" */ - 0, /* "undefined" */ - 102, /* "uniqueIdentifier" */ - 888, /* "uniqueMember" */ - 55, /* "unstructuredAddress" */ - 49, /* "unstructuredName" */ - 880, /* "userCertificate" */ - 465, /* "userClass" */ - 458, /* "userId" */ - 879, /* "userPassword" */ - 373, /* "valid" */ - 678, /* "wap" */ - 679, /* "wap-wsg" */ - 735, /* "wap-wsg-idm-ecid-wtls1" */ - 743, /* "wap-wsg-idm-ecid-wtls10" */ - 744, /* "wap-wsg-idm-ecid-wtls11" */ - 745, /* "wap-wsg-idm-ecid-wtls12" */ - 736, /* "wap-wsg-idm-ecid-wtls3" */ - 737, /* "wap-wsg-idm-ecid-wtls4" */ - 738, /* "wap-wsg-idm-ecid-wtls5" */ - 739, /* "wap-wsg-idm-ecid-wtls6" */ - 740, /* "wap-wsg-idm-ecid-wtls7" */ - 741, /* "wap-wsg-idm-ecid-wtls8" */ - 742, /* "wap-wsg-idm-ecid-wtls9" */ - 804, /* "whirlpool" */ - 868, /* "x121Address" */ - 503, /* "x500UniqueIdentifier" */ - 158, /* "x509Certificate" */ - 160, /* "x509Crl" */ - 1207, /* "x942kdf" */ - 1206, /* "x963kdf" */ - 125, /* "zlib compression" */ -}; - -#define NUM_OBJ 1350 -static const unsigned int obj_objs[NUM_OBJ] = { - 0, /* OBJ_undef 0 */ - 181, /* OBJ_iso 1 */ - 393, /* OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t */ - 404, /* OBJ_ccitt OBJ_itu_t */ - 645, /* OBJ_itu_t 0 */ - 646, /* OBJ_joint_iso_itu_t 2 */ - 1323, /* OBJ_ac_auditEntity OBJ_ac_auditIdentity */ - 1264, /* OBJ_itu_t_identified_organization 0 4 */ - 434, /* OBJ_data 0 9 */ - 182, /* OBJ_member_body 1 2 */ - 379, /* OBJ_org 1 3 */ - 676, /* OBJ_identified_organization 1 3 */ - 11, /* OBJ_X500 2 5 */ - 647, /* OBJ_international_organizations 2 23 */ - 1265, /* OBJ_etsi 0 4 0 */ - 380, /* OBJ_dod 1 3 6 */ - 1170, /* OBJ_ieee 1 3 111 */ - 12, /* OBJ_X509 2 5 4 */ - 378, /* OBJ_X500algorithms 2 5 8 */ - 81, /* OBJ_id_ce 2 5 29 */ - 512, /* OBJ_id_set 2 23 42 */ - 678, /* OBJ_wap 2 23 43 */ - 435, /* OBJ_pss 0 9 2342 */ - 1140, /* OBJ_ISO_CN 1 2 156 */ - 1150, /* OBJ_ISO_UA 1 2 804 */ - 183, /* OBJ_ISO_US 1 2 840 */ - 381, /* OBJ_iana 1 3 6 1 */ - 1034, /* OBJ_X25519 1 3 101 110 */ - 1035, /* OBJ_X448 1 3 101 111 */ - 1087, /* OBJ_ED25519 1 3 101 112 */ - 1088, /* OBJ_ED448 1 3 101 113 */ - 677, /* OBJ_certicom_arc 1 3 132 */ - 394, /* OBJ_selected_attribute_types 2 5 1 5 */ - 13, /* OBJ_commonName 2 5 4 3 */ - 100, /* OBJ_surname 2 5 4 4 */ - 105, /* OBJ_serialNumber 2 5 4 5 */ - 14, /* OBJ_countryName 2 5 4 6 */ - 15, /* OBJ_localityName 2 5 4 7 */ - 16, /* OBJ_stateOrProvinceName 2 5 4 8 */ - 660, /* OBJ_streetAddress 2 5 4 9 */ - 17, /* OBJ_organizationName 2 5 4 10 */ - 18, /* OBJ_organizationalUnitName 2 5 4 11 */ - 106, /* OBJ_title 2 5 4 12 */ - 107, /* OBJ_description 2 5 4 13 */ - 859, /* OBJ_searchGuide 2 5 4 14 */ - 860, /* OBJ_businessCategory 2 5 4 15 */ - 861, /* OBJ_postalAddress 2 5 4 16 */ - 661, /* OBJ_postalCode 2 5 4 17 */ - 862, /* OBJ_postOfficeBox 2 5 4 18 */ - 863, /* OBJ_physicalDeliveryOfficeName 2 5 4 19 */ - 864, /* OBJ_telephoneNumber 2 5 4 20 */ - 865, /* OBJ_telexNumber 2 5 4 21 */ - 866, /* OBJ_teletexTerminalIdentifier 2 5 4 22 */ - 867, /* OBJ_facsimileTelephoneNumber 2 5 4 23 */ - 868, /* OBJ_x121Address 2 5 4 24 */ - 869, /* OBJ_internationaliSDNNumber 2 5 4 25 */ - 870, /* OBJ_registeredAddress 2 5 4 26 */ - 871, /* OBJ_destinationIndicator 2 5 4 27 */ - 872, /* OBJ_preferredDeliveryMethod 2 5 4 28 */ - 873, /* OBJ_presentationAddress 2 5 4 29 */ - 874, /* OBJ_supportedApplicationContext 2 5 4 30 */ - 875, /* OBJ_member 2 5 4 31 */ - 876, /* OBJ_owner 2 5 4 32 */ - 877, /* OBJ_roleOccupant 2 5 4 33 */ - 878, /* OBJ_seeAlso 2 5 4 34 */ - 879, /* OBJ_userPassword 2 5 4 35 */ - 880, /* OBJ_userCertificate 2 5 4 36 */ - 881, /* OBJ_cACertificate 2 5 4 37 */ - 882, /* OBJ_authorityRevocationList 2 5 4 38 */ - 883, /* OBJ_certificateRevocationList 2 5 4 39 */ - 884, /* OBJ_crossCertificatePair 2 5 4 40 */ - 173, /* OBJ_name 2 5 4 41 */ - 99, /* OBJ_givenName 2 5 4 42 */ - 101, /* OBJ_initials 2 5 4 43 */ - 509, /* OBJ_generationQualifier 2 5 4 44 */ - 503, /* OBJ_x500UniqueIdentifier 2 5 4 45 */ - 174, /* OBJ_dnQualifier 2 5 4 46 */ - 885, /* OBJ_enhancedSearchGuide 2 5 4 47 */ - 886, /* OBJ_protocolInformation 2 5 4 48 */ - 887, /* OBJ_distinguishedName 2 5 4 49 */ - 888, /* OBJ_uniqueMember 2 5 4 50 */ - 889, /* OBJ_houseIdentifier 2 5 4 51 */ - 890, /* OBJ_supportedAlgorithms 2 5 4 52 */ - 891, /* OBJ_deltaRevocationList 2 5 4 53 */ - 892, /* OBJ_dmdName 2 5 4 54 */ - 510, /* OBJ_pseudonym 2 5 4 65 */ - 400, /* OBJ_role 2 5 4 72 */ - 1089, /* OBJ_organizationIdentifier 2 5 4 97 */ - 1090, /* OBJ_countryCode3c 2 5 4 98 */ - 1091, /* OBJ_countryCode3n 2 5 4 99 */ - 1092, /* OBJ_dnsName 2 5 4 100 */ - 769, /* OBJ_subject_directory_attributes 2 5 29 9 */ - 82, /* OBJ_subject_key_identifier 2 5 29 14 */ - 83, /* OBJ_key_usage 2 5 29 15 */ - 84, /* OBJ_private_key_usage_period 2 5 29 16 */ - 85, /* OBJ_subject_alt_name 2 5 29 17 */ - 86, /* OBJ_issuer_alt_name 2 5 29 18 */ - 87, /* OBJ_basic_constraints 2 5 29 19 */ - 88, /* OBJ_crl_number 2 5 29 20 */ - 141, /* OBJ_crl_reason 2 5 29 21 */ - 430, /* OBJ_hold_instruction_code 2 5 29 23 */ - 142, /* OBJ_invalidity_date 2 5 29 24 */ - 140, /* OBJ_delta_crl 2 5 29 27 */ - 770, /* OBJ_issuing_distribution_point 2 5 29 28 */ - 771, /* OBJ_certificate_issuer 2 5 29 29 */ - 666, /* OBJ_name_constraints 2 5 29 30 */ - 103, /* OBJ_crl_distribution_points 2 5 29 31 */ - 89, /* OBJ_certificate_policies 2 5 29 32 */ - 747, /* OBJ_policy_mappings 2 5 29 33 */ - 90, /* OBJ_authority_key_identifier 2 5 29 35 */ - 401, /* OBJ_policy_constraints 2 5 29 36 */ - 126, /* OBJ_ext_key_usage 2 5 29 37 */ - 1295, /* OBJ_authority_attribute_identifier 2 5 29 38 */ - 1296, /* OBJ_role_spec_cert_identifier 2 5 29 39 */ - 1297, /* OBJ_basic_att_constraints 2 5 29 41 */ - 1298, /* OBJ_delegated_name_constraints 2 5 29 42 */ - 1299, /* OBJ_time_specification 2 5 29 43 */ - 857, /* OBJ_freshest_crl 2 5 29 46 */ - 1300, /* OBJ_attribute_descriptor 2 5 29 48 */ - 1301, /* OBJ_user_notice 2 5 29 49 */ - 1302, /* OBJ_soa_identifier 2 5 29 50 */ - 1303, /* OBJ_acceptable_cert_policies 2 5 29 52 */ - 748, /* OBJ_inhibit_any_policy 2 5 29 54 */ - 402, /* OBJ_target_information 2 5 29 55 */ - 403, /* OBJ_no_rev_avail 2 5 29 56 */ - 1304, /* OBJ_acceptable_privilege_policies 2 5 29 57 */ - 1305, /* OBJ_indirect_issuer 2 5 29 61 */ - 1306, /* OBJ_no_assertion 2 5 29 62 */ - 1307, /* OBJ_id_aa_issuing_distribution_point 2 5 29 63 */ - 1308, /* OBJ_issued_on_behalf_of 2 5 29 64 */ - 1309, /* OBJ_single_use 2 5 29 65 */ - 1310, /* OBJ_group_ac 2 5 29 66 */ - 1311, /* OBJ_allowed_attribute_assignments 2 5 29 67 */ - 1312, /* OBJ_attribute_mappings 2 5 29 68 */ - 1313, /* OBJ_holder_name_constraints 2 5 29 69 */ - 1314, /* OBJ_authorization_validation 2 5 29 70 */ - 1315, /* OBJ_prot_restrict 2 5 29 71 */ - 1316, /* OBJ_subject_alt_public_key_info 2 5 29 72 */ - 1317, /* OBJ_alt_signature_algorithm 2 5 29 73 */ - 1318, /* OBJ_alt_signature_value 2 5 29 74 */ - 1319, /* OBJ_associated_information 2 5 29 75 */ - 513, /* OBJ_set_ctype 2 23 42 0 */ - 514, /* OBJ_set_msgExt 2 23 42 1 */ - 515, /* OBJ_set_attr 2 23 42 3 */ - 516, /* OBJ_set_policy 2 23 42 5 */ - 517, /* OBJ_set_certExt 2 23 42 7 */ - 518, /* OBJ_set_brand 2 23 42 8 */ - 679, /* OBJ_wap_wsg 2 23 43 1 */ - 1324, /* OBJ_tcg 2 23 133 */ - 1266, /* OBJ_electronic_signature_standard 0 4 0 1733 */ - 382, /* OBJ_Directory 1 3 6 1 1 */ - 383, /* OBJ_Management 1 3 6 1 2 */ - 384, /* OBJ_Experimental 1 3 6 1 3 */ - 385, /* OBJ_Private 1 3 6 1 4 */ - 386, /* OBJ_Security 1 3 6 1 5 */ - 387, /* OBJ_SNMPv2 1 3 6 1 6 */ - 388, /* OBJ_Mail 1 3 6 1 7 */ - 376, /* OBJ_algorithm 1 3 14 3 2 */ - 395, /* OBJ_clearance 2 5 1 5 55 */ - 19, /* OBJ_rsa 2 5 8 1 1 */ - 96, /* OBJ_mdc2WithRSA 2 5 8 3 100 */ - 95, /* OBJ_mdc2 2 5 8 3 101 */ - 746, /* OBJ_any_policy 2 5 29 32 0 */ - 910, /* OBJ_anyExtendedKeyUsage 2 5 29 37 0 */ - 519, /* OBJ_setct_PANData 2 23 42 0 0 */ - 520, /* OBJ_setct_PANToken 2 23 42 0 1 */ - 521, /* OBJ_setct_PANOnly 2 23 42 0 2 */ - 522, /* OBJ_setct_OIData 2 23 42 0 3 */ - 523, /* OBJ_setct_PI 2 23 42 0 4 */ - 524, /* OBJ_setct_PIData 2 23 42 0 5 */ - 525, /* OBJ_setct_PIDataUnsigned 2 23 42 0 6 */ - 526, /* OBJ_setct_HODInput 2 23 42 0 7 */ - 527, /* OBJ_setct_AuthResBaggage 2 23 42 0 8 */ - 528, /* OBJ_setct_AuthRevReqBaggage 2 23 42 0 9 */ - 529, /* OBJ_setct_AuthRevResBaggage 2 23 42 0 10 */ - 530, /* OBJ_setct_CapTokenSeq 2 23 42 0 11 */ - 531, /* OBJ_setct_PInitResData 2 23 42 0 12 */ - 532, /* OBJ_setct_PI_TBS 2 23 42 0 13 */ - 533, /* OBJ_setct_PResData 2 23 42 0 14 */ - 534, /* OBJ_setct_AuthReqTBS 2 23 42 0 16 */ - 535, /* OBJ_setct_AuthResTBS 2 23 42 0 17 */ - 536, /* OBJ_setct_AuthResTBSX 2 23 42 0 18 */ - 537, /* OBJ_setct_AuthTokenTBS 2 23 42 0 19 */ - 538, /* OBJ_setct_CapTokenData 2 23 42 0 20 */ - 539, /* OBJ_setct_CapTokenTBS 2 23 42 0 21 */ - 540, /* OBJ_setct_AcqCardCodeMsg 2 23 42 0 22 */ - 541, /* OBJ_setct_AuthRevReqTBS 2 23 42 0 23 */ - 542, /* OBJ_setct_AuthRevResData 2 23 42 0 24 */ - 543, /* OBJ_setct_AuthRevResTBS 2 23 42 0 25 */ - 544, /* OBJ_setct_CapReqTBS 2 23 42 0 26 */ - 545, /* OBJ_setct_CapReqTBSX 2 23 42 0 27 */ - 546, /* OBJ_setct_CapResData 2 23 42 0 28 */ - 547, /* OBJ_setct_CapRevReqTBS 2 23 42 0 29 */ - 548, /* OBJ_setct_CapRevReqTBSX 2 23 42 0 30 */ - 549, /* OBJ_setct_CapRevResData 2 23 42 0 31 */ - 550, /* OBJ_setct_CredReqTBS 2 23 42 0 32 */ - 551, /* OBJ_setct_CredReqTBSX 2 23 42 0 33 */ - 552, /* OBJ_setct_CredResData 2 23 42 0 34 */ - 553, /* OBJ_setct_CredRevReqTBS 2 23 42 0 35 */ - 554, /* OBJ_setct_CredRevReqTBSX 2 23 42 0 36 */ - 555, /* OBJ_setct_CredRevResData 2 23 42 0 37 */ - 556, /* OBJ_setct_PCertReqData 2 23 42 0 38 */ - 557, /* OBJ_setct_PCertResTBS 2 23 42 0 39 */ - 558, /* OBJ_setct_BatchAdminReqData 2 23 42 0 40 */ - 559, /* OBJ_setct_BatchAdminResData 2 23 42 0 41 */ - 560, /* OBJ_setct_CardCInitResTBS 2 23 42 0 42 */ - 561, /* OBJ_setct_MeAqCInitResTBS 2 23 42 0 43 */ - 562, /* OBJ_setct_RegFormResTBS 2 23 42 0 44 */ - 563, /* OBJ_setct_CertReqData 2 23 42 0 45 */ - 564, /* OBJ_setct_CertReqTBS 2 23 42 0 46 */ - 565, /* OBJ_setct_CertResData 2 23 42 0 47 */ - 566, /* OBJ_setct_CertInqReqTBS 2 23 42 0 48 */ - 567, /* OBJ_setct_ErrorTBS 2 23 42 0 49 */ - 568, /* OBJ_setct_PIDualSignedTBE 2 23 42 0 50 */ - 569, /* OBJ_setct_PIUnsignedTBE 2 23 42 0 51 */ - 570, /* OBJ_setct_AuthReqTBE 2 23 42 0 52 */ - 571, /* OBJ_setct_AuthResTBE 2 23 42 0 53 */ - 572, /* OBJ_setct_AuthResTBEX 2 23 42 0 54 */ - 573, /* OBJ_setct_AuthTokenTBE 2 23 42 0 55 */ - 574, /* OBJ_setct_CapTokenTBE 2 23 42 0 56 */ - 575, /* OBJ_setct_CapTokenTBEX 2 23 42 0 57 */ - 576, /* OBJ_setct_AcqCardCodeMsgTBE 2 23 42 0 58 */ - 577, /* OBJ_setct_AuthRevReqTBE 2 23 42 0 59 */ - 578, /* OBJ_setct_AuthRevResTBE 2 23 42 0 60 */ - 579, /* OBJ_setct_AuthRevResTBEB 2 23 42 0 61 */ - 580, /* OBJ_setct_CapReqTBE 2 23 42 0 62 */ - 581, /* OBJ_setct_CapReqTBEX 2 23 42 0 63 */ - 582, /* OBJ_setct_CapResTBE 2 23 42 0 64 */ - 583, /* OBJ_setct_CapRevReqTBE 2 23 42 0 65 */ - 584, /* OBJ_setct_CapRevReqTBEX 2 23 42 0 66 */ - 585, /* OBJ_setct_CapRevResTBE 2 23 42 0 67 */ - 586, /* OBJ_setct_CredReqTBE 2 23 42 0 68 */ - 587, /* OBJ_setct_CredReqTBEX 2 23 42 0 69 */ - 588, /* OBJ_setct_CredResTBE 2 23 42 0 70 */ - 589, /* OBJ_setct_CredRevReqTBE 2 23 42 0 71 */ - 590, /* OBJ_setct_CredRevReqTBEX 2 23 42 0 72 */ - 591, /* OBJ_setct_CredRevResTBE 2 23 42 0 73 */ - 592, /* OBJ_setct_BatchAdminReqTBE 2 23 42 0 74 */ - 593, /* OBJ_setct_BatchAdminResTBE 2 23 42 0 75 */ - 594, /* OBJ_setct_RegFormReqTBE 2 23 42 0 76 */ - 595, /* OBJ_setct_CertReqTBE 2 23 42 0 77 */ - 596, /* OBJ_setct_CertReqTBEX 2 23 42 0 78 */ - 597, /* OBJ_setct_CertResTBE 2 23 42 0 79 */ - 598, /* OBJ_setct_CRLNotificationTBS 2 23 42 0 80 */ - 599, /* OBJ_setct_CRLNotificationResTBS 2 23 42 0 81 */ - 600, /* OBJ_setct_BCIDistributionTBS 2 23 42 0 82 */ - 601, /* OBJ_setext_genCrypt 2 23 42 1 1 */ - 602, /* OBJ_setext_miAuth 2 23 42 1 3 */ - 603, /* OBJ_setext_pinSecure 2 23 42 1 4 */ - 604, /* OBJ_setext_pinAny 2 23 42 1 5 */ - 605, /* OBJ_setext_track2 2 23 42 1 7 */ - 606, /* OBJ_setext_cv 2 23 42 1 8 */ - 620, /* OBJ_setAttr_Cert 2 23 42 3 0 */ - 621, /* OBJ_setAttr_PGWYcap 2 23 42 3 1 */ - 622, /* OBJ_setAttr_TokenType 2 23 42 3 2 */ - 623, /* OBJ_setAttr_IssCap 2 23 42 3 3 */ - 607, /* OBJ_set_policy_root 2 23 42 5 0 */ - 608, /* OBJ_setCext_hashedRoot 2 23 42 7 0 */ - 609, /* OBJ_setCext_certType 2 23 42 7 1 */ - 610, /* OBJ_setCext_merchData 2 23 42 7 2 */ - 611, /* OBJ_setCext_cCertRequired 2 23 42 7 3 */ - 612, /* OBJ_setCext_tunneling 2 23 42 7 4 */ - 613, /* OBJ_setCext_setExt 2 23 42 7 5 */ - 614, /* OBJ_setCext_setQualf 2 23 42 7 6 */ - 615, /* OBJ_setCext_PGWYcapabilities 2 23 42 7 7 */ - 616, /* OBJ_setCext_TokenIdentifier 2 23 42 7 8 */ - 617, /* OBJ_setCext_Track2Data 2 23 42 7 9 */ - 618, /* OBJ_setCext_TokenType 2 23 42 7 10 */ - 619, /* OBJ_setCext_IssuerCapabilities 2 23 42 7 11 */ - 636, /* OBJ_set_brand_IATA_ATA 2 23 42 8 1 */ - 640, /* OBJ_set_brand_Visa 2 23 42 8 4 */ - 641, /* OBJ_set_brand_MasterCard 2 23 42 8 5 */ - 637, /* OBJ_set_brand_Diners 2 23 42 8 30 */ - 638, /* OBJ_set_brand_AmericanExpress 2 23 42 8 34 */ - 639, /* OBJ_set_brand_JCB 2 23 42 8 35 */ - 1325, /* OBJ_tcg_tcpaSpecVersion 2 23 133 1 */ - 1326, /* OBJ_tcg_attribute 2 23 133 2 */ - 1327, /* OBJ_tcg_protocol 2 23 133 3 */ - 1328, /* OBJ_tcg_algorithm 2 23 133 4 */ - 1329, /* OBJ_tcg_platformClass 2 23 133 5 */ - 1330, /* OBJ_tcg_ce 2 23 133 6 */ - 1331, /* OBJ_tcg_kp 2 23 133 8 */ - 1332, /* OBJ_tcg_ca 2 23 133 11 */ - 1333, /* OBJ_tcg_address 2 23 133 17 */ - 1334, /* OBJ_tcg_registry 2 23 133 18 */ - 1335, /* OBJ_tcg_traits 2 23 133 19 */ - 1273, /* OBJ_cades 0 4 0 19122 */ - 1267, /* OBJ_ess_attributes 0 4 0 1733 2 */ - 1195, /* OBJ_gmac 1 0 9797 3 4 */ - 1141, /* OBJ_oscca 1 2 156 10197 */ - 805, /* OBJ_cryptopro 1 2 643 2 2 */ - 806, /* OBJ_cryptocom 1 2 643 2 9 */ - 974, /* OBJ_id_tc26 1 2 643 7 1 */ - 1005, /* OBJ_OGRN 1 2 643 100 1 */ - 1006, /* OBJ_SNILS 1 2 643 100 3 */ - 1226, /* OBJ_OGRNIP 1 2 643 100 5 */ - 1007, /* OBJ_subjectSignTool 1 2 643 100 111 */ - 1008, /* OBJ_issuerSignTool 1 2 643 100 112 */ - 1227, /* OBJ_classSignTool 1 2 643 100 113 */ - 184, /* OBJ_X9_57 1 2 840 10040 */ - 405, /* OBJ_ansi_X9_62 1 2 840 10045 */ - 389, /* OBJ_Enterprises 1 3 6 1 4 1 */ - 504, /* OBJ_mime_mhs 1 3 6 1 7 1 */ - 104, /* OBJ_md5WithRSA 1 3 14 3 2 3 */ - 29, /* OBJ_des_ecb 1 3 14 3 2 6 */ - 31, /* OBJ_des_cbc 1 3 14 3 2 7 */ - 45, /* OBJ_des_ofb64 1 3 14 3 2 8 */ - 30, /* OBJ_des_cfb64 1 3 14 3 2 9 */ - 377, /* OBJ_rsaSignature 1 3 14 3 2 11 */ - 67, /* OBJ_dsa_2 1 3 14 3 2 12 */ - 66, /* OBJ_dsaWithSHA 1 3 14 3 2 13 */ - 42, /* OBJ_shaWithRSAEncryption 1 3 14 3 2 15 */ - 32, /* OBJ_des_ede_ecb 1 3 14 3 2 17 */ - 41, /* OBJ_sha 1 3 14 3 2 18 */ - 64, /* OBJ_sha1 1 3 14 3 2 26 */ - 70, /* OBJ_dsaWithSHA1_2 1 3 14 3 2 27 */ - 115, /* OBJ_sha1WithRSA 1 3 14 3 2 29 */ - 117, /* OBJ_ripemd160 1 3 36 3 2 1 */ - 1093, /* OBJ_x509ExtAdmission 1 3 36 8 3 3 */ - 143, /* OBJ_sxnet 1 3 101 1 4 1 */ - 1171, /* OBJ_ieee_siswg 1 3 111 2 1619 */ - 721, /* OBJ_sect163k1 1 3 132 0 1 */ - 722, /* OBJ_sect163r1 1 3 132 0 2 */ - 728, /* OBJ_sect239k1 1 3 132 0 3 */ - 717, /* OBJ_sect113r1 1 3 132 0 4 */ - 718, /* OBJ_sect113r2 1 3 132 0 5 */ - 704, /* OBJ_secp112r1 1 3 132 0 6 */ - 705, /* OBJ_secp112r2 1 3 132 0 7 */ - 709, /* OBJ_secp160r1 1 3 132 0 8 */ - 708, /* OBJ_secp160k1 1 3 132 0 9 */ - 714, /* OBJ_secp256k1 1 3 132 0 10 */ - 723, /* OBJ_sect163r2 1 3 132 0 15 */ - 729, /* OBJ_sect283k1 1 3 132 0 16 */ - 730, /* OBJ_sect283r1 1 3 132 0 17 */ - 719, /* OBJ_sect131r1 1 3 132 0 22 */ - 720, /* OBJ_sect131r2 1 3 132 0 23 */ - 724, /* OBJ_sect193r1 1 3 132 0 24 */ - 725, /* OBJ_sect193r2 1 3 132 0 25 */ - 726, /* OBJ_sect233k1 1 3 132 0 26 */ - 727, /* OBJ_sect233r1 1 3 132 0 27 */ - 706, /* OBJ_secp128r1 1 3 132 0 28 */ - 707, /* OBJ_secp128r2 1 3 132 0 29 */ - 710, /* OBJ_secp160r2 1 3 132 0 30 */ - 711, /* OBJ_secp192k1 1 3 132 0 31 */ - 712, /* OBJ_secp224k1 1 3 132 0 32 */ - 713, /* OBJ_secp224r1 1 3 132 0 33 */ - 715, /* OBJ_secp384r1 1 3 132 0 34 */ - 716, /* OBJ_secp521r1 1 3 132 0 35 */ - 731, /* OBJ_sect409k1 1 3 132 0 36 */ - 732, /* OBJ_sect409r1 1 3 132 0 37 */ - 733, /* OBJ_sect571k1 1 3 132 0 38 */ - 734, /* OBJ_sect571r1 1 3 132 0 39 */ - 624, /* OBJ_set_rootKeyThumb 2 23 42 3 0 0 */ - 625, /* OBJ_set_addPolicy 2 23 42 3 0 1 */ - 626, /* OBJ_setAttr_Token_EMV 2 23 42 3 2 1 */ - 627, /* OBJ_setAttr_Token_B0Prime 2 23 42 3 2 2 */ - 628, /* OBJ_setAttr_IssCap_CVM 2 23 42 3 3 3 */ - 629, /* OBJ_setAttr_IssCap_T2 2 23 42 3 3 4 */ - 630, /* OBJ_setAttr_IssCap_Sig 2 23 42 3 3 5 */ - 642, /* OBJ_set_brand_Novus 2 23 42 8 6011 */ - 735, /* OBJ_wap_wsg_idm_ecid_wtls1 2 23 43 1 4 1 */ - 736, /* OBJ_wap_wsg_idm_ecid_wtls3 2 23 43 1 4 3 */ - 737, /* OBJ_wap_wsg_idm_ecid_wtls4 2 23 43 1 4 4 */ - 738, /* OBJ_wap_wsg_idm_ecid_wtls5 2 23 43 1 4 5 */ - 739, /* OBJ_wap_wsg_idm_ecid_wtls6 2 23 43 1 4 6 */ - 740, /* OBJ_wap_wsg_idm_ecid_wtls7 2 23 43 1 4 7 */ - 741, /* OBJ_wap_wsg_idm_ecid_wtls8 2 23 43 1 4 8 */ - 742, /* OBJ_wap_wsg_idm_ecid_wtls9 2 23 43 1 4 9 */ - 743, /* OBJ_wap_wsg_idm_ecid_wtls10 2 23 43 1 4 10 */ - 744, /* OBJ_wap_wsg_idm_ecid_wtls11 2 23 43 1 4 11 */ - 745, /* OBJ_wap_wsg_idm_ecid_wtls12 2 23 43 1 4 12 */ - 1345, /* OBJ_tcg_at_tpmManufacturer 2 23 133 2 1 */ - 1346, /* OBJ_tcg_at_tpmModel 2 23 133 2 2 */ - 1347, /* OBJ_tcg_at_tpmVersion 2 23 133 2 3 */ - 1348, /* OBJ_tcg_at_securityQualities 2 23 133 2 10 */ - 1349, /* OBJ_tcg_at_tpmProtectionProfile 2 23 133 2 11 */ - 1350, /* OBJ_tcg_at_tpmSecurityTarget 2 23 133 2 12 */ - 1351, /* OBJ_tcg_at_tbbProtectionProfile 2 23 133 2 13 */ - 1352, /* OBJ_tcg_at_tbbSecurityTarget 2 23 133 2 14 */ - 1353, /* OBJ_tcg_at_tpmIdLabel 2 23 133 2 15 */ - 1354, /* OBJ_tcg_at_tpmSpecification 2 23 133 2 16 */ - 1355, /* OBJ_tcg_at_tcgPlatformSpecification 2 23 133 2 17 */ - 1356, /* OBJ_tcg_at_tpmSecurityAssertions 2 23 133 2 18 */ - 1357, /* OBJ_tcg_at_tbbSecurityAssertions 2 23 133 2 19 */ - 1358, /* OBJ_tcg_at_tcgCredentialSpecification 2 23 133 2 23 */ - 1359, /* OBJ_tcg_at_tcgCredentialType 2 23 133 2 25 */ - 1360, /* OBJ_tcg_at_previousPlatformCertificates 2 23 133 2 26 */ - 1361, /* OBJ_tcg_at_tbbSecurityAssertions_v3 2 23 133 2 27 */ - 1362, /* OBJ_tcg_at_cryptographicAnchors 2 23 133 2 28 */ - 1382, /* OBJ_tcg_prt_tpmIdProtocol 2 23 133 3 1 */ - 1367, /* OBJ_tcg_algorithm_null 2 23 133 4 1 */ - 1336, /* OBJ_tcg_common 2 23 133 5 1 */ - 1376, /* OBJ_tcg_ce_relevantCredentials 2 23 133 6 2 */ - 1377, /* OBJ_tcg_ce_relevantManifests 2 23 133 6 3 */ - 1378, /* OBJ_tcg_ce_virtualPlatformAttestationService 2 23 133 6 4 */ - 1379, /* OBJ_tcg_ce_migrationControllerAttestationService 2 23 133 6 5 */ - 1380, /* OBJ_tcg_ce_migrationControllerRegistrationService 2 23 133 6 6 */ - 1381, /* OBJ_tcg_ce_virtualPlatformBackupService 2 23 133 6 7 */ - 1368, /* OBJ_tcg_kp_EKCertificate 2 23 133 8 1 */ - 1369, /* OBJ_tcg_kp_PlatformAttributeCertificate 2 23 133 8 2 */ - 1370, /* OBJ_tcg_kp_AIKCertificate 2 23 133 8 3 */ - 1371, /* OBJ_tcg_kp_PlatformKeyCertificate 2 23 133 8 4 */ - 1372, /* OBJ_tcg_kp_DeltaPlatformAttributeCertificate 2 23 133 8 5 */ - 1373, /* OBJ_tcg_kp_DeltaPlatformKeyCertificate 2 23 133 8 6 */ - 1374, /* OBJ_tcg_kp_AdditionalPlatformAttributeCertificate 2 23 133 8 7 */ - 1375, /* OBJ_tcg_kp_AdditionalPlatformKeyCertificate 2 23 133 8 8 */ - 1392, /* OBJ_tcg_cap_verifiedPlatformCertificate 2 23 133 11 4 */ - 1383, /* OBJ_tcg_address_ethernetmac 2 23 133 17 1 */ - 1384, /* OBJ_tcg_address_wlanmac 2 23 133 17 2 */ - 1385, /* OBJ_tcg_address_bluetoothmac 2 23 133 17 3 */ - 1386, /* OBJ_tcg_registry_componentClass 2 23 133 18 3 */ - 1393, /* OBJ_tcg_tr_ID 2 23 133 19 1 */ - 1394, /* OBJ_tcg_tr_category 2 23 133 19 2 */ - 1395, /* OBJ_tcg_tr_registry 2 23 133 19 3 */ - 1274, /* OBJ_cades_attributes 0 4 0 19122 1 */ - 1268, /* OBJ_id_aa_ets_mimeType 0 4 0 1733 2 1 */ - 1269, /* OBJ_id_aa_ets_longTermValidation 0 4 0 1733 2 2 */ - 1270, /* OBJ_id_aa_ets_SignaturePolicyDocument 0 4 0 1733 2 3 */ - 1271, /* OBJ_id_aa_ets_archiveTimestampV3 0 4 0 1733 2 4 */ - 1272, /* OBJ_id_aa_ATSHashIndex 0 4 0 1733 2 5 */ - 804, /* OBJ_whirlpool 1 0 10118 3 0 55 */ - 1142, /* OBJ_sm_scheme 1 2 156 10197 1 */ - 773, /* OBJ_kisa 1 2 410 200004 */ - 807, /* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */ - 808, /* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */ - 809, /* OBJ_id_GostR3411_94 1 2 643 2 2 9 */ - 810, /* OBJ_id_HMACGostR3411_94 1 2 643 2 2 10 */ - 811, /* OBJ_id_GostR3410_2001 1 2 643 2 2 19 */ - 812, /* OBJ_id_GostR3410_94 1 2 643 2 2 20 */ - 813, /* OBJ_id_Gost28147_89 1 2 643 2 2 21 */ - 815, /* OBJ_id_Gost28147_89_MAC 1 2 643 2 2 22 */ - 816, /* OBJ_id_GostR3411_94_prf 1 2 643 2 2 23 */ - 817, /* OBJ_id_GostR3410_2001DH 1 2 643 2 2 98 */ - 818, /* OBJ_id_GostR3410_94DH 1 2 643 2 2 99 */ - 977, /* OBJ_id_tc26_algorithms 1 2 643 7 1 1 */ - 994, /* OBJ_id_tc26_constants 1 2 643 7 1 2 */ - 1228, /* OBJ_classSignToolKC1 1 2 643 100 113 1 */ - 1229, /* OBJ_classSignToolKC2 1 2 643 100 113 2 */ - 1230, /* OBJ_classSignToolKC3 1 2 643 100 113 3 */ - 1231, /* OBJ_classSignToolKB1 1 2 643 100 113 4 */ - 1232, /* OBJ_classSignToolKB2 1 2 643 100 113 5 */ - 1233, /* OBJ_classSignToolKA1 1 2 643 100 113 6 */ - 1, /* OBJ_rsadsi 1 2 840 113549 */ - 185, /* OBJ_X9cm 1 2 840 10040 4 */ - 1031, /* OBJ_id_pkinit 1 3 6 1 5 2 3 */ - 127, /* OBJ_id_pkix 1 3 6 1 5 5 7 */ - 505, /* OBJ_mime_mhs_headings 1 3 6 1 7 1 1 */ - 506, /* OBJ_mime_mhs_bodies 1 3 6 1 7 1 2 */ - 119, /* OBJ_ripemd160WithRSA 1 3 36 3 3 1 2 */ - 937, /* OBJ_dhSinglePass_stdDH_sha224kdf_scheme 1 3 132 1 11 0 */ - 938, /* OBJ_dhSinglePass_stdDH_sha256kdf_scheme 1 3 132 1 11 1 */ - 939, /* OBJ_dhSinglePass_stdDH_sha384kdf_scheme 1 3 132 1 11 2 */ - 940, /* OBJ_dhSinglePass_stdDH_sha512kdf_scheme 1 3 132 1 11 3 */ - 942, /* OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme 1 3 132 1 14 0 */ - 943, /* OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme 1 3 132 1 14 1 */ - 944, /* OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme 1 3 132 1 14 2 */ - 945, /* OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme 1 3 132 1 14 3 */ - 631, /* OBJ_setAttr_GenCryptgrm 2 23 42 3 3 3 1 */ - 632, /* OBJ_setAttr_T2Enc 2 23 42 3 3 4 1 */ - 633, /* OBJ_setAttr_T2cleartxt 2 23 42 3 3 4 2 */ - 634, /* OBJ_setAttr_TokICCsig 2 23 42 3 3 5 1 */ - 635, /* OBJ_setAttr_SecDevSig 2 23 42 3 3 5 2 */ - 1337, /* OBJ_tcg_at_platformManufacturerStr 2 23 133 5 1 1 */ - 1338, /* OBJ_tcg_at_platformManufacturerId 2 23 133 5 1 2 */ - 1339, /* OBJ_tcg_at_platformConfigUri 2 23 133 5 1 3 */ - 1340, /* OBJ_tcg_at_platformModel 2 23 133 5 1 4 */ - 1341, /* OBJ_tcg_at_platformVersion 2 23 133 5 1 5 */ - 1342, /* OBJ_tcg_at_platformSerial 2 23 133 5 1 6 */ - 1343, /* OBJ_tcg_at_platformConfiguration 2 23 133 5 1 7 */ - 1344, /* OBJ_tcg_at_platformIdentifier 2 23 133 5 1 8 */ - 1387, /* OBJ_tcg_registry_componentClass_tcg 2 23 133 18 3 1 */ - 1388, /* OBJ_tcg_registry_componentClass_ietf 2 23 133 18 3 2 */ - 1389, /* OBJ_tcg_registry_componentClass_dmtf 2 23 133 18 3 3 */ - 1390, /* OBJ_tcg_registry_componentClass_pcie 2 23 133 18 3 4 */ - 1391, /* OBJ_tcg_registry_componentClass_disk 2 23 133 18 3 5 */ - 1396, /* OBJ_tcg_tr_ID_Boolean 2 23 133 19 1 1 */ - 1397, /* OBJ_tcg_tr_ID_CertificateIdentifier 2 23 133 19 1 2 */ - 1398, /* OBJ_tcg_tr_ID_CommonCriteria 2 23 133 19 1 3 */ - 1399, /* OBJ_tcg_tr_ID_componentClass 2 23 133 19 1 4 */ - 1400, /* OBJ_tcg_tr_ID_componentIdentifierV11 2 23 133 19 1 5 */ - 1401, /* OBJ_tcg_tr_ID_FIPSLevel 2 23 133 19 1 6 */ - 1402, /* OBJ_tcg_tr_ID_ISO9000Level 2 23 133 19 1 7 */ - 1403, /* OBJ_tcg_tr_ID_networkMAC 2 23 133 19 1 8 */ - 1404, /* OBJ_tcg_tr_ID_OID 2 23 133 19 1 9 */ - 1405, /* OBJ_tcg_tr_ID_PEN 2 23 133 19 1 10 */ - 1406, /* OBJ_tcg_tr_ID_platformFirmwareCapabilities 2 23 133 19 1 11 */ - 1407, /* OBJ_tcg_tr_ID_platformFirmwareSignatureVerification 2 23 133 19 1 12 */ - 1408, /* OBJ_tcg_tr_ID_platformFirmwareUpdateCompliance 2 23 133 19 1 13 */ - 1409, /* OBJ_tcg_tr_ID_platformHardwareCapabilities 2 23 133 19 1 14 */ - 1410, /* OBJ_tcg_tr_ID_RTM 2 23 133 19 1 15 */ - 1411, /* OBJ_tcg_tr_ID_status 2 23 133 19 1 16 */ - 1412, /* OBJ_tcg_tr_ID_URI 2 23 133 19 1 17 */ - 1413, /* OBJ_tcg_tr_ID_UTF8String 2 23 133 19 1 18 */ - 1414, /* OBJ_tcg_tr_ID_IA5String 2 23 133 19 1 19 */ - 1415, /* OBJ_tcg_tr_ID_PEMCertString 2 23 133 19 1 20 */ - 1416, /* OBJ_tcg_tr_ID_PublicKey 2 23 133 19 1 21 */ - 1417, /* OBJ_tcg_tr_cat_platformManufacturer 2 23 133 19 2 1 */ - 1418, /* OBJ_tcg_tr_cat_platformModel 2 23 133 19 2 2 */ - 1419, /* OBJ_tcg_tr_cat_platformVersion 2 23 133 19 2 3 */ - 1420, /* OBJ_tcg_tr_cat_platformSerial 2 23 133 19 2 4 */ - 1421, /* OBJ_tcg_tr_cat_platformManufacturerIdentifier 2 23 133 19 2 5 */ - 1422, /* OBJ_tcg_tr_cat_platformOwnership 2 23 133 19 2 6 */ - 1423, /* OBJ_tcg_tr_cat_componentClass 2 23 133 19 2 7 */ - 1424, /* OBJ_tcg_tr_cat_componentManufacturer 2 23 133 19 2 8 */ - 1425, /* OBJ_tcg_tr_cat_componentModel 2 23 133 19 2 9 */ - 1426, /* OBJ_tcg_tr_cat_componentSerial 2 23 133 19 2 10 */ - 1427, /* OBJ_tcg_tr_cat_componentStatus 2 23 133 19 2 11 */ - 1428, /* OBJ_tcg_tr_cat_componentLocation 2 23 133 19 2 12 */ - 1429, /* OBJ_tcg_tr_cat_componentRevision 2 23 133 19 2 13 */ - 1430, /* OBJ_tcg_tr_cat_componentFieldReplaceable 2 23 133 19 2 14 */ - 1431, /* OBJ_tcg_tr_cat_EKCertificate 2 23 133 19 2 15 */ - 1432, /* OBJ_tcg_tr_cat_IAKCertificate 2 23 133 19 2 16 */ - 1433, /* OBJ_tcg_tr_cat_IDevIDCertificate 2 23 133 19 2 17 */ - 1434, /* OBJ_tcg_tr_cat_DICECertificate 2 23 133 19 2 18 */ - 1435, /* OBJ_tcg_tr_cat_SPDMCertificate 2 23 133 19 2 19 */ - 1436, /* OBJ_tcg_tr_cat_PEMCertificate 2 23 133 19 2 20 */ - 1437, /* OBJ_tcg_tr_cat_PlatformCertificate 2 23 133 19 2 21 */ - 1438, /* OBJ_tcg_tr_cat_DeltaPlatformCertificate 2 23 133 19 2 22 */ - 1439, /* OBJ_tcg_tr_cat_RebasePlatformCertificate 2 23 133 19 2 23 */ - 1440, /* OBJ_tcg_tr_cat_genericCertificate 2 23 133 19 2 24 */ - 1441, /* OBJ_tcg_tr_cat_CommonCriteria 2 23 133 19 2 25 */ - 1442, /* OBJ_tcg_tr_cat_componentIdentifierV11 2 23 133 19 2 26 */ - 1443, /* OBJ_tcg_tr_cat_FIPSLevel 2 23 133 19 2 27 */ - 1444, /* OBJ_tcg_tr_cat_ISO9000 2 23 133 19 2 28 */ - 1445, /* OBJ_tcg_tr_cat_networkMAC 2 23 133 19 2 29 */ - 1446, /* OBJ_tcg_tr_cat_attestationProtocol 2 23 133 19 2 30 */ - 1447, /* OBJ_tcg_tr_cat_PEN 2 23 133 19 2 31 */ - 1448, /* OBJ_tcg_tr_cat_platformFirmwareCapabilities 2 23 133 19 2 32 */ - 1449, /* OBJ_tcg_tr_cat_platformHardwareCapabilities 2 23 133 19 2 33 */ - 1450, /* OBJ_tcg_tr_cat_platformFirmwareSignatureVerification 2 23 133 19 2 34 */ - 1451, /* OBJ_tcg_tr_cat_platformFirmwareUpdateCompliance 2 23 133 19 2 35 */ - 1452, /* OBJ_tcg_tr_cat_RTM 2 23 133 19 2 36 */ - 1453, /* OBJ_tcg_tr_cat_PublicKey 2 23 133 19 2 37 */ - 1275, /* OBJ_id_aa_ets_signerAttrV2 0 4 0 19122 1 1 */ - 1276, /* OBJ_id_aa_ets_sigPolicyStore 0 4 0 19122 1 3 */ - 1277, /* OBJ_id_aa_ATSHashIndex_v2 0 4 0 19122 1 4 */ - 1278, /* OBJ_id_aa_ATSHashIndex_v3 0 4 0 19122 1 5 */ - 1279, /* OBJ_signedAssertion 0 4 0 19122 1 6 */ - 436, /* OBJ_ucl 0 9 2342 19200300 */ - 820, /* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */ - 819, /* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */ - 845, /* OBJ_id_GostR3410_94_a 1 2 643 2 2 20 1 */ - 846, /* OBJ_id_GostR3410_94_aBis 1 2 643 2 2 20 2 */ - 847, /* OBJ_id_GostR3410_94_b 1 2 643 2 2 20 3 */ - 848, /* OBJ_id_GostR3410_94_bBis 1 2 643 2 2 20 4 */ - 821, /* OBJ_id_GostR3411_94_TestParamSet 1 2 643 2 2 30 0 */ - 822, /* OBJ_id_GostR3411_94_CryptoProParamSet 1 2 643 2 2 30 1 */ - 823, /* OBJ_id_Gost28147_89_TestParamSet 1 2 643 2 2 31 0 */ - 824, /* OBJ_id_Gost28147_89_CryptoPro_A_ParamSet 1 2 643 2 2 31 1 */ - 825, /* OBJ_id_Gost28147_89_CryptoPro_B_ParamSet 1 2 643 2 2 31 2 */ - 826, /* OBJ_id_Gost28147_89_CryptoPro_C_ParamSet 1 2 643 2 2 31 3 */ - 827, /* OBJ_id_Gost28147_89_CryptoPro_D_ParamSet 1 2 643 2 2 31 4 */ - 828, /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 1 2 643 2 2 31 5 */ - 829, /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 1 2 643 2 2 31 6 */ - 830, /* OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 1 2 643 2 2 31 7 */ - 831, /* OBJ_id_GostR3410_94_TestParamSet 1 2 643 2 2 32 0 */ - 832, /* OBJ_id_GostR3410_94_CryptoPro_A_ParamSet 1 2 643 2 2 32 2 */ - 833, /* OBJ_id_GostR3410_94_CryptoPro_B_ParamSet 1 2 643 2 2 32 3 */ - 834, /* OBJ_id_GostR3410_94_CryptoPro_C_ParamSet 1 2 643 2 2 32 4 */ - 835, /* OBJ_id_GostR3410_94_CryptoPro_D_ParamSet 1 2 643 2 2 32 5 */ - 836, /* OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet 1 2 643 2 2 33 1 */ - 837, /* OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet 1 2 643 2 2 33 2 */ - 838, /* OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet 1 2 643 2 2 33 3 */ - 839, /* OBJ_id_GostR3410_2001_TestParamSet 1 2 643 2 2 35 0 */ - 840, /* OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet 1 2 643 2 2 35 1 */ - 841, /* OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet 1 2 643 2 2 35 2 */ - 842, /* OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet 1 2 643 2 2 35 3 */ - 843, /* OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet 1 2 643 2 2 36 0 */ - 844, /* OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet 1 2 643 2 2 36 1 */ - 978, /* OBJ_id_tc26_sign 1 2 643 7 1 1 1 */ - 981, /* OBJ_id_tc26_digest 1 2 643 7 1 1 2 */ - 984, /* OBJ_id_tc26_signwithdigest 1 2 643 7 1 1 3 */ - 987, /* OBJ_id_tc26_mac 1 2 643 7 1 1 4 */ - 990, /* OBJ_id_tc26_cipher 1 2 643 7 1 1 5 */ - 991, /* OBJ_id_tc26_agreement 1 2 643 7 1 1 6 */ - 1179, /* OBJ_id_tc26_wrap 1 2 643 7 1 1 7 */ - 995, /* OBJ_id_tc26_sign_constants 1 2 643 7 1 2 1 */ - 1000, /* OBJ_id_tc26_digest_constants 1 2 643 7 1 2 2 */ - 1001, /* OBJ_id_tc26_cipher_constants 1 2 643 7 1 2 5 */ - 1151, /* OBJ_ua_pki 1 2 804 2 1 1 1 */ - 2, /* OBJ_pkcs 1 2 840 113549 1 */ - 431, /* OBJ_hold_instruction_none 1 2 840 10040 2 1 */ - 432, /* OBJ_hold_instruction_call_issuer 1 2 840 10040 2 2 */ - 433, /* OBJ_hold_instruction_reject 1 2 840 10040 2 3 */ - 116, /* OBJ_dsa 1 2 840 10040 4 1 */ - 113, /* OBJ_dsaWithSHA1 1 2 840 10040 4 3 */ - 406, /* OBJ_X9_62_prime_field 1 2 840 10045 1 1 */ - 407, /* OBJ_X9_62_characteristic_two_field 1 2 840 10045 1 2 */ - 408, /* OBJ_X9_62_id_ecPublicKey 1 2 840 10045 2 1 */ - 416, /* OBJ_ecdsa_with_SHA1 1 2 840 10045 4 1 */ - 791, /* OBJ_ecdsa_with_Recommended 1 2 840 10045 4 2 */ - 792, /* OBJ_ecdsa_with_Specified 1 2 840 10045 4 3 */ - 920, /* OBJ_dhpublicnumber 1 2 840 10046 2 1 */ - 1032, /* OBJ_pkInitClientAuth 1 3 6 1 5 2 3 4 */ - 1033, /* OBJ_pkInitKDC 1 3 6 1 5 2 3 5 */ - 258, /* OBJ_id_pkix_mod 1 3 6 1 5 5 7 0 */ - 175, /* OBJ_id_pe 1 3 6 1 5 5 7 1 */ - 259, /* OBJ_id_qt 1 3 6 1 5 5 7 2 */ - 128, /* OBJ_id_kp 1 3 6 1 5 5 7 3 */ - 260, /* OBJ_id_it 1 3 6 1 5 5 7 4 */ - 261, /* OBJ_id_pkip 1 3 6 1 5 5 7 5 */ - 262, /* OBJ_id_alg 1 3 6 1 5 5 7 6 */ - 263, /* OBJ_id_cmc 1 3 6 1 5 5 7 7 */ - 264, /* OBJ_id_on 1 3 6 1 5 5 7 8 */ - 265, /* OBJ_id_pda 1 3 6 1 5 5 7 9 */ - 266, /* OBJ_id_aca 1 3 6 1 5 5 7 10 */ - 267, /* OBJ_id_qcs 1 3 6 1 5 5 7 11 */ - 268, /* OBJ_id_cct 1 3 6 1 5 5 7 12 */ - 1238, /* OBJ_id_cp 1 3 6 1 5 5 7 14 */ - 662, /* OBJ_id_ppl 1 3 6 1 5 5 7 21 */ - 176, /* OBJ_id_ad 1 3 6 1 5 5 7 48 */ - 507, /* OBJ_id_hex_partial_message 1 3 6 1 7 1 1 1 */ - 508, /* OBJ_id_hex_multipart_message 1 3 6 1 7 1 1 2 */ - 57, /* OBJ_netscape 2 16 840 1 113730 */ - 1282, /* OBJ_oracle 2 16 840 1 113894 */ - 1363, /* OBJ_tcg_at_platformConfiguration_v1 2 23 133 5 1 7 1 */ - 1364, /* OBJ_tcg_at_platformConfiguration_v2 2 23 133 5 1 7 2 */ - 1365, /* OBJ_tcg_at_platformConfiguration_v3 2 23 133 5 1 7 3 */ - 1366, /* OBJ_tcg_at_platformConfigUri_v3 2 23 133 5 1 7 4 */ - 754, /* OBJ_camellia_128_ecb 0 3 4401 5 3 1 9 1 */ - 766, /* OBJ_camellia_128_ofb128 0 3 4401 5 3 1 9 3 */ - 757, /* OBJ_camellia_128_cfb128 0 3 4401 5 3 1 9 4 */ - 961, /* OBJ_camellia_128_gcm 0 3 4401 5 3 1 9 6 */ - 962, /* OBJ_camellia_128_ccm 0 3 4401 5 3 1 9 7 */ - 963, /* OBJ_camellia_128_ctr 0 3 4401 5 3 1 9 9 */ - 964, /* OBJ_camellia_128_cmac 0 3 4401 5 3 1 9 10 */ - 755, /* OBJ_camellia_192_ecb 0 3 4401 5 3 1 9 21 */ - 767, /* OBJ_camellia_192_ofb128 0 3 4401 5 3 1 9 23 */ - 758, /* OBJ_camellia_192_cfb128 0 3 4401 5 3 1 9 24 */ - 965, /* OBJ_camellia_192_gcm 0 3 4401 5 3 1 9 26 */ - 966, /* OBJ_camellia_192_ccm 0 3 4401 5 3 1 9 27 */ - 967, /* OBJ_camellia_192_ctr 0 3 4401 5 3 1 9 29 */ - 968, /* OBJ_camellia_192_cmac 0 3 4401 5 3 1 9 30 */ - 756, /* OBJ_camellia_256_ecb 0 3 4401 5 3 1 9 41 */ - 768, /* OBJ_camellia_256_ofb128 0 3 4401 5 3 1 9 43 */ - 759, /* OBJ_camellia_256_cfb128 0 3 4401 5 3 1 9 44 */ - 969, /* OBJ_camellia_256_gcm 0 3 4401 5 3 1 9 46 */ - 970, /* OBJ_camellia_256_ccm 0 3 4401 5 3 1 9 47 */ - 971, /* OBJ_camellia_256_ctr 0 3 4401 5 3 1 9 49 */ - 972, /* OBJ_camellia_256_cmac 0 3 4401 5 3 1 9 50 */ - 437, /* OBJ_pilot 0 9 2342 19200300 100 */ - 1133, /* OBJ_sm4_ecb 1 2 156 10197 1 104 1 */ - 1134, /* OBJ_sm4_cbc 1 2 156 10197 1 104 2 */ - 1135, /* OBJ_sm4_ofb128 1 2 156 10197 1 104 3 */ - 1137, /* OBJ_sm4_cfb128 1 2 156 10197 1 104 4 */ - 1136, /* OBJ_sm4_cfb1 1 2 156 10197 1 104 5 */ - 1138, /* OBJ_sm4_cfb8 1 2 156 10197 1 104 6 */ - 1139, /* OBJ_sm4_ctr 1 2 156 10197 1 104 7 */ - 1248, /* OBJ_sm4_gcm 1 2 156 10197 1 104 8 */ - 1249, /* OBJ_sm4_ccm 1 2 156 10197 1 104 9 */ - 1290, /* OBJ_sm4_xts 1 2 156 10197 1 104 10 */ - 1172, /* OBJ_sm2 1 2 156 10197 1 301 */ - 1143, /* OBJ_sm3 1 2 156 10197 1 401 */ - 1204, /* OBJ_SM2_with_SM3 1 2 156 10197 1 501 */ - 1144, /* OBJ_sm3WithRSAEncryption 1 2 156 10197 1 504 */ - 776, /* OBJ_seed_ecb 1 2 410 200004 1 3 */ - 777, /* OBJ_seed_cbc 1 2 410 200004 1 4 */ - 779, /* OBJ_seed_cfb128 1 2 410 200004 1 5 */ - 778, /* OBJ_seed_ofb128 1 2 410 200004 1 6 */ - 852, /* OBJ_id_GostR3411_94_with_GostR3410_94_cc 1 2 643 2 9 1 3 3 */ - 853, /* OBJ_id_GostR3411_94_with_GostR3410_2001_cc 1 2 643 2 9 1 3 4 */ - 850, /* OBJ_id_GostR3410_94_cc 1 2 643 2 9 1 5 3 */ - 851, /* OBJ_id_GostR3410_2001_cc 1 2 643 2 9 1 5 4 */ - 849, /* OBJ_id_Gost28147_89_cc 1 2 643 2 9 1 6 1 */ - 854, /* OBJ_id_GostR3410_2001_ParamSet_cc 1 2 643 2 9 1 8 1 */ - 1004, /* OBJ_INN 1 2 643 3 131 1 1 */ - 979, /* OBJ_id_GostR3410_2012_256 1 2 643 7 1 1 1 1 */ - 980, /* OBJ_id_GostR3410_2012_512 1 2 643 7 1 1 1 2 */ - 982, /* OBJ_id_GostR3411_2012_256 1 2 643 7 1 1 2 2 */ - 983, /* OBJ_id_GostR3411_2012_512 1 2 643 7 1 1 2 3 */ - 985, /* OBJ_id_tc26_signwithdigest_gost3410_2012_256 1 2 643 7 1 1 3 2 */ - 986, /* OBJ_id_tc26_signwithdigest_gost3410_2012_512 1 2 643 7 1 1 3 3 */ - 988, /* OBJ_id_tc26_hmac_gost_3411_2012_256 1 2 643 7 1 1 4 1 */ - 989, /* OBJ_id_tc26_hmac_gost_3411_2012_512 1 2 643 7 1 1 4 2 */ - 1173, /* OBJ_id_tc26_cipher_gostr3412_2015_magma 1 2 643 7 1 1 5 1 */ - 1176, /* OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik 1 2 643 7 1 1 5 2 */ - 992, /* OBJ_id_tc26_agreement_gost_3410_2012_256 1 2 643 7 1 1 6 1 */ - 993, /* OBJ_id_tc26_agreement_gost_3410_2012_512 1 2 643 7 1 1 6 2 */ - 1180, /* OBJ_id_tc26_wrap_gostr3412_2015_magma 1 2 643 7 1 1 7 1 */ - 1182, /* OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik 1 2 643 7 1 1 7 2 */ - 1147, /* OBJ_id_tc26_gost_3410_2012_256_constants 1 2 643 7 1 2 1 1 */ - 996, /* OBJ_id_tc26_gost_3410_2012_512_constants 1 2 643 7 1 2 1 2 */ - 1002, /* OBJ_id_tc26_gost_28147_constants 1 2 643 7 1 2 5 1 */ - 186, /* OBJ_pkcs1 1 2 840 113549 1 1 */ - 27, /* OBJ_pkcs3 1 2 840 113549 1 3 */ - 187, /* OBJ_pkcs5 1 2 840 113549 1 5 */ - 20, /* OBJ_pkcs7 1 2 840 113549 1 7 */ - 47, /* OBJ_pkcs9 1 2 840 113549 1 9 */ - 3, /* OBJ_md2 1 2 840 113549 2 2 */ - 257, /* OBJ_md4 1 2 840 113549 2 4 */ - 4, /* OBJ_md5 1 2 840 113549 2 5 */ - 797, /* OBJ_hmacWithMD5 1 2 840 113549 2 6 */ - 163, /* OBJ_hmacWithSHA1 1 2 840 113549 2 7 */ - 798, /* OBJ_hmacWithSHA224 1 2 840 113549 2 8 */ - 799, /* OBJ_hmacWithSHA256 1 2 840 113549 2 9 */ - 800, /* OBJ_hmacWithSHA384 1 2 840 113549 2 10 */ - 801, /* OBJ_hmacWithSHA512 1 2 840 113549 2 11 */ - 1193, /* OBJ_hmacWithSHA512_224 1 2 840 113549 2 12 */ - 1194, /* OBJ_hmacWithSHA512_256 1 2 840 113549 2 13 */ - 37, /* OBJ_rc2_cbc 1 2 840 113549 3 2 */ - 5, /* OBJ_rc4 1 2 840 113549 3 4 */ - 44, /* OBJ_des_ede3_cbc 1 2 840 113549 3 7 */ - 120, /* OBJ_rc5_cbc 1 2 840 113549 3 8 */ - 643, /* OBJ_des_cdmf 1 2 840 113549 3 10 */ - 680, /* OBJ_X9_62_id_characteristic_two_basis 1 2 840 10045 1 2 3 */ - 684, /* OBJ_X9_62_c2pnb163v1 1 2 840 10045 3 0 1 */ - 685, /* OBJ_X9_62_c2pnb163v2 1 2 840 10045 3 0 2 */ - 686, /* OBJ_X9_62_c2pnb163v3 1 2 840 10045 3 0 3 */ - 687, /* OBJ_X9_62_c2pnb176v1 1 2 840 10045 3 0 4 */ - 688, /* OBJ_X9_62_c2tnb191v1 1 2 840 10045 3 0 5 */ - 689, /* OBJ_X9_62_c2tnb191v2 1 2 840 10045 3 0 6 */ - 690, /* OBJ_X9_62_c2tnb191v3 1 2 840 10045 3 0 7 */ - 691, /* OBJ_X9_62_c2onb191v4 1 2 840 10045 3 0 8 */ - 692, /* OBJ_X9_62_c2onb191v5 1 2 840 10045 3 0 9 */ - 693, /* OBJ_X9_62_c2pnb208w1 1 2 840 10045 3 0 10 */ - 694, /* OBJ_X9_62_c2tnb239v1 1 2 840 10045 3 0 11 */ - 695, /* OBJ_X9_62_c2tnb239v2 1 2 840 10045 3 0 12 */ - 696, /* OBJ_X9_62_c2tnb239v3 1 2 840 10045 3 0 13 */ - 697, /* OBJ_X9_62_c2onb239v4 1 2 840 10045 3 0 14 */ - 698, /* OBJ_X9_62_c2onb239v5 1 2 840 10045 3 0 15 */ - 699, /* OBJ_X9_62_c2pnb272w1 1 2 840 10045 3 0 16 */ - 700, /* OBJ_X9_62_c2pnb304w1 1 2 840 10045 3 0 17 */ - 701, /* OBJ_X9_62_c2tnb359v1 1 2 840 10045 3 0 18 */ - 702, /* OBJ_X9_62_c2pnb368w1 1 2 840 10045 3 0 19 */ - 703, /* OBJ_X9_62_c2tnb431r1 1 2 840 10045 3 0 20 */ - 409, /* OBJ_X9_62_prime192v1 1 2 840 10045 3 1 1 */ - 410, /* OBJ_X9_62_prime192v2 1 2 840 10045 3 1 2 */ - 411, /* OBJ_X9_62_prime192v3 1 2 840 10045 3 1 3 */ - 412, /* OBJ_X9_62_prime239v1 1 2 840 10045 3 1 4 */ - 413, /* OBJ_X9_62_prime239v2 1 2 840 10045 3 1 5 */ - 414, /* OBJ_X9_62_prime239v3 1 2 840 10045 3 1 6 */ - 415, /* OBJ_X9_62_prime256v1 1 2 840 10045 3 1 7 */ - 793, /* OBJ_ecdsa_with_SHA224 1 2 840 10045 4 3 1 */ - 794, /* OBJ_ecdsa_with_SHA256 1 2 840 10045 4 3 2 */ - 795, /* OBJ_ecdsa_with_SHA384 1 2 840 10045 4 3 3 */ - 796, /* OBJ_ecdsa_with_SHA512 1 2 840 10045 4 3 4 */ - 269, /* OBJ_id_pkix1_explicit_88 1 3 6 1 5 5 7 0 1 */ - 270, /* OBJ_id_pkix1_implicit_88 1 3 6 1 5 5 7 0 2 */ - 271, /* OBJ_id_pkix1_explicit_93 1 3 6 1 5 5 7 0 3 */ - 272, /* OBJ_id_pkix1_implicit_93 1 3 6 1 5 5 7 0 4 */ - 273, /* OBJ_id_mod_crmf 1 3 6 1 5 5 7 0 5 */ - 274, /* OBJ_id_mod_cmc 1 3 6 1 5 5 7 0 6 */ - 275, /* OBJ_id_mod_kea_profile_88 1 3 6 1 5 5 7 0 7 */ - 276, /* OBJ_id_mod_kea_profile_93 1 3 6 1 5 5 7 0 8 */ - 277, /* OBJ_id_mod_cmp 1 3 6 1 5 5 7 0 9 */ - 278, /* OBJ_id_mod_qualified_cert_88 1 3 6 1 5 5 7 0 10 */ - 279, /* OBJ_id_mod_qualified_cert_93 1 3 6 1 5 5 7 0 11 */ - 280, /* OBJ_id_mod_attribute_cert 1 3 6 1 5 5 7 0 12 */ - 281, /* OBJ_id_mod_timestamp_protocol 1 3 6 1 5 5 7 0 13 */ - 282, /* OBJ_id_mod_ocsp 1 3 6 1 5 5 7 0 14 */ - 283, /* OBJ_id_mod_dvcs 1 3 6 1 5 5 7 0 15 */ - 284, /* OBJ_id_mod_cmp2000 1 3 6 1 5 5 7 0 16 */ - 1251, /* OBJ_id_mod_cmp2000_02 1 3 6 1 5 5 7 0 50 */ - 1252, /* OBJ_id_mod_cmp2021_88 1 3 6 1 5 5 7 0 99 */ - 1253, /* OBJ_id_mod_cmp2021_02 1 3 6 1 5 5 7 0 100 */ - 177, /* OBJ_info_access 1 3 6 1 5 5 7 1 1 */ - 285, /* OBJ_biometricInfo 1 3 6 1 5 5 7 1 2 */ - 286, /* OBJ_qcStatements 1 3 6 1 5 5 7 1 3 */ - 287, /* OBJ_ac_auditIdentity 1 3 6 1 5 5 7 1 4 */ - 288, /* OBJ_ac_targeting 1 3 6 1 5 5 7 1 5 */ - 289, /* OBJ_aaControls 1 3 6 1 5 5 7 1 6 */ - 290, /* OBJ_sbgp_ipAddrBlock 1 3 6 1 5 5 7 1 7 */ - 291, /* OBJ_sbgp_autonomousSysNum 1 3 6 1 5 5 7 1 8 */ - 292, /* OBJ_sbgp_routerIdentifier 1 3 6 1 5 5 7 1 9 */ - 397, /* OBJ_ac_proxying 1 3 6 1 5 5 7 1 10 */ - 398, /* OBJ_sinfo_access 1 3 6 1 5 5 7 1 11 */ - 663, /* OBJ_proxyCertInfo 1 3 6 1 5 5 7 1 14 */ - 1020, /* OBJ_tlsfeature 1 3 6 1 5 5 7 1 24 */ - 1239, /* OBJ_sbgp_ipAddrBlockv2 1 3 6 1 5 5 7 1 28 */ - 1240, /* OBJ_sbgp_autonomousSysNumv2 1 3 6 1 5 5 7 1 29 */ - 164, /* OBJ_id_qt_cps 1 3 6 1 5 5 7 2 1 */ - 165, /* OBJ_id_qt_unotice 1 3 6 1 5 5 7 2 2 */ - 293, /* OBJ_textNotice 1 3 6 1 5 5 7 2 3 */ - 129, /* OBJ_server_auth 1 3 6 1 5 5 7 3 1 */ - 130, /* OBJ_client_auth 1 3 6 1 5 5 7 3 2 */ - 131, /* OBJ_code_sign 1 3 6 1 5 5 7 3 3 */ - 132, /* OBJ_email_protect 1 3 6 1 5 5 7 3 4 */ - 294, /* OBJ_ipsecEndSystem 1 3 6 1 5 5 7 3 5 */ - 295, /* OBJ_ipsecTunnel 1 3 6 1 5 5 7 3 6 */ - 296, /* OBJ_ipsecUser 1 3 6 1 5 5 7 3 7 */ - 133, /* OBJ_time_stamp 1 3 6 1 5 5 7 3 8 */ - 180, /* OBJ_OCSP_sign 1 3 6 1 5 5 7 3 9 */ - 297, /* OBJ_dvcs 1 3 6 1 5 5 7 3 10 */ - 1022, /* OBJ_ipsec_IKE 1 3 6 1 5 5 7 3 17 */ - 1023, /* OBJ_capwapAC 1 3 6 1 5 5 7 3 18 */ - 1024, /* OBJ_capwapWTP 1 3 6 1 5 5 7 3 19 */ - 1025, /* OBJ_sshClient 1 3 6 1 5 5 7 3 21 */ - 1026, /* OBJ_sshServer 1 3 6 1 5 5 7 3 22 */ - 1027, /* OBJ_sendRouter 1 3 6 1 5 5 7 3 23 */ - 1028, /* OBJ_sendProxiedRouter 1 3 6 1 5 5 7 3 24 */ - 1029, /* OBJ_sendOwner 1 3 6 1 5 5 7 3 25 */ - 1030, /* OBJ_sendProxiedOwner 1 3 6 1 5 5 7 3 26 */ - 1131, /* OBJ_cmcCA 1 3 6 1 5 5 7 3 27 */ - 1132, /* OBJ_cmcRA 1 3 6 1 5 5 7 3 28 */ - 1219, /* OBJ_cmcArchive 1 3 6 1 5 5 7 3 29 */ - 1220, /* OBJ_id_kp_bgpsec_router 1 3 6 1 5 5 7 3 30 */ - 1221, /* OBJ_id_kp_BrandIndicatorforMessageIdentification 1 3 6 1 5 5 7 3 31 */ - 1222, /* OBJ_cmKGA 1 3 6 1 5 5 7 3 32 */ - 298, /* OBJ_id_it_caProtEncCert 1 3 6 1 5 5 7 4 1 */ - 299, /* OBJ_id_it_signKeyPairTypes 1 3 6 1 5 5 7 4 2 */ - 300, /* OBJ_id_it_encKeyPairTypes 1 3 6 1 5 5 7 4 3 */ - 301, /* OBJ_id_it_preferredSymmAlg 1 3 6 1 5 5 7 4 4 */ - 302, /* OBJ_id_it_caKeyUpdateInfo 1 3 6 1 5 5 7 4 5 */ - 303, /* OBJ_id_it_currentCRL 1 3 6 1 5 5 7 4 6 */ - 304, /* OBJ_id_it_unsupportedOIDs 1 3 6 1 5 5 7 4 7 */ - 305, /* OBJ_id_it_subscriptionRequest 1 3 6 1 5 5 7 4 8 */ - 306, /* OBJ_id_it_subscriptionResponse 1 3 6 1 5 5 7 4 9 */ - 307, /* OBJ_id_it_keyPairParamReq 1 3 6 1 5 5 7 4 10 */ - 308, /* OBJ_id_it_keyPairParamRep 1 3 6 1 5 5 7 4 11 */ - 309, /* OBJ_id_it_revPassphrase 1 3 6 1 5 5 7 4 12 */ - 310, /* OBJ_id_it_implicitConfirm 1 3 6 1 5 5 7 4 13 */ - 311, /* OBJ_id_it_confirmWaitTime 1 3 6 1 5 5 7 4 14 */ - 312, /* OBJ_id_it_origPKIMessage 1 3 6 1 5 5 7 4 15 */ - 784, /* OBJ_id_it_suppLangTags 1 3 6 1 5 5 7 4 16 */ - 1223, /* OBJ_id_it_caCerts 1 3 6 1 5 5 7 4 17 */ - 1224, /* OBJ_id_it_rootCaKeyUpdate 1 3 6 1 5 5 7 4 18 */ - 1225, /* OBJ_id_it_certReqTemplate 1 3 6 1 5 5 7 4 19 */ - 1254, /* OBJ_id_it_rootCaCert 1 3 6 1 5 5 7 4 20 */ - 1255, /* OBJ_id_it_certProfile 1 3 6 1 5 5 7 4 21 */ - 1256, /* OBJ_id_it_crlStatusList 1 3 6 1 5 5 7 4 22 */ - 1257, /* OBJ_id_it_crls 1 3 6 1 5 5 7 4 23 */ - 313, /* OBJ_id_regCtrl 1 3 6 1 5 5 7 5 1 */ - 314, /* OBJ_id_regInfo 1 3 6 1 5 5 7 5 2 */ - 323, /* OBJ_id_alg_des40 1 3 6 1 5 5 7 6 1 */ - 324, /* OBJ_id_alg_noSignature 1 3 6 1 5 5 7 6 2 */ - 325, /* OBJ_id_alg_dh_sig_hmac_sha1 1 3 6 1 5 5 7 6 3 */ - 326, /* OBJ_id_alg_dh_pop 1 3 6 1 5 5 7 6 4 */ - 327, /* OBJ_id_cmc_statusInfo 1 3 6 1 5 5 7 7 1 */ - 328, /* OBJ_id_cmc_identification 1 3 6 1 5 5 7 7 2 */ - 329, /* OBJ_id_cmc_identityProof 1 3 6 1 5 5 7 7 3 */ - 330, /* OBJ_id_cmc_dataReturn 1 3 6 1 5 5 7 7 4 */ - 331, /* OBJ_id_cmc_transactionId 1 3 6 1 5 5 7 7 5 */ - 332, /* OBJ_id_cmc_senderNonce 1 3 6 1 5 5 7 7 6 */ - 333, /* OBJ_id_cmc_recipientNonce 1 3 6 1 5 5 7 7 7 */ - 334, /* OBJ_id_cmc_addExtensions 1 3 6 1 5 5 7 7 8 */ - 335, /* OBJ_id_cmc_encryptedPOP 1 3 6 1 5 5 7 7 9 */ - 336, /* OBJ_id_cmc_decryptedPOP 1 3 6 1 5 5 7 7 10 */ - 337, /* OBJ_id_cmc_lraPOPWitness 1 3 6 1 5 5 7 7 11 */ - 338, /* OBJ_id_cmc_getCert 1 3 6 1 5 5 7 7 15 */ - 339, /* OBJ_id_cmc_getCRL 1 3 6 1 5 5 7 7 16 */ - 340, /* OBJ_id_cmc_revokeRequest 1 3 6 1 5 5 7 7 17 */ - 341, /* OBJ_id_cmc_regInfo 1 3 6 1 5 5 7 7 18 */ - 342, /* OBJ_id_cmc_responseInfo 1 3 6 1 5 5 7 7 19 */ - 343, /* OBJ_id_cmc_queryPending 1 3 6 1 5 5 7 7 21 */ - 344, /* OBJ_id_cmc_popLinkRandom 1 3 6 1 5 5 7 7 22 */ - 345, /* OBJ_id_cmc_popLinkWitness 1 3 6 1 5 5 7 7 23 */ - 346, /* OBJ_id_cmc_confirmCertAcceptance 1 3 6 1 5 5 7 7 24 */ - 347, /* OBJ_id_on_personalData 1 3 6 1 5 5 7 8 1 */ - 858, /* OBJ_id_on_permanentIdentifier 1 3 6 1 5 5 7 8 3 */ - 1321, /* OBJ_id_on_hardwareModuleName 1 3 6 1 5 5 7 8 4 */ - 1209, /* OBJ_XmppAddr 1 3 6 1 5 5 7 8 5 */ - 1210, /* OBJ_SRVName 1 3 6 1 5 5 7 8 7 */ - 1211, /* OBJ_NAIRealm 1 3 6 1 5 5 7 8 8 */ - 1208, /* OBJ_id_on_SmtpUTF8Mailbox 1 3 6 1 5 5 7 8 9 */ - 348, /* OBJ_id_pda_dateOfBirth 1 3 6 1 5 5 7 9 1 */ - 349, /* OBJ_id_pda_placeOfBirth 1 3 6 1 5 5 7 9 2 */ - 351, /* OBJ_id_pda_gender 1 3 6 1 5 5 7 9 3 */ - 352, /* OBJ_id_pda_countryOfCitizenship 1 3 6 1 5 5 7 9 4 */ - 353, /* OBJ_id_pda_countryOfResidence 1 3 6 1 5 5 7 9 5 */ - 354, /* OBJ_id_aca_authenticationInfo 1 3 6 1 5 5 7 10 1 */ - 355, /* OBJ_id_aca_accessIdentity 1 3 6 1 5 5 7 10 2 */ - 356, /* OBJ_id_aca_chargingIdentity 1 3 6 1 5 5 7 10 3 */ - 357, /* OBJ_id_aca_group 1 3 6 1 5 5 7 10 4 */ - 358, /* OBJ_id_aca_role 1 3 6 1 5 5 7 10 5 */ - 399, /* OBJ_id_aca_encAttrs 1 3 6 1 5 5 7 10 6 */ - 359, /* OBJ_id_qcs_pkixQCSyntax_v1 1 3 6 1 5 5 7 11 1 */ - 360, /* OBJ_id_cct_crs 1 3 6 1 5 5 7 12 1 */ - 361, /* OBJ_id_cct_PKIData 1 3 6 1 5 5 7 12 2 */ - 362, /* OBJ_id_cct_PKIResponse 1 3 6 1 5 5 7 12 3 */ - 1241, /* OBJ_ipAddr_asNumber 1 3 6 1 5 5 7 14 2 */ - 1242, /* OBJ_ipAddr_asNumberv2 1 3 6 1 5 5 7 14 3 */ - 664, /* OBJ_id_ppl_anyLanguage 1 3 6 1 5 5 7 21 0 */ - 665, /* OBJ_id_ppl_inheritAll 1 3 6 1 5 5 7 21 1 */ - 667, /* OBJ_Independent 1 3 6 1 5 5 7 21 2 */ - 178, /* OBJ_ad_OCSP 1 3 6 1 5 5 7 48 1 */ - 179, /* OBJ_ad_ca_issuers 1 3 6 1 5 5 7 48 2 */ - 363, /* OBJ_ad_timeStamping 1 3 6 1 5 5 7 48 3 */ - 364, /* OBJ_ad_dvcs 1 3 6 1 5 5 7 48 4 */ - 785, /* OBJ_caRepository 1 3 6 1 5 5 7 48 5 */ - 1243, /* OBJ_rpkiManifest 1 3 6 1 5 5 7 48 10 */ - 1244, /* OBJ_signedObject 1 3 6 1 5 5 7 48 11 */ - 1245, /* OBJ_rpkiNotify 1 3 6 1 5 5 7 48 13 */ - 780, /* OBJ_hmac_md5 1 3 6 1 5 5 8 1 1 */ - 781, /* OBJ_hmac_sha1 1 3 6 1 5 5 8 1 2 */ - 913, /* OBJ_aes_128_xts 1 3 111 2 1619 0 1 1 */ - 914, /* OBJ_aes_256_xts 1 3 111 2 1619 0 1 2 */ - 58, /* OBJ_netscape_cert_extension 2 16 840 1 113730 1 */ - 59, /* OBJ_netscape_data_type 2 16 840 1 113730 2 */ - 438, /* OBJ_pilotAttributeType 0 9 2342 19200300 100 1 */ - 439, /* OBJ_pilotAttributeSyntax 0 9 2342 19200300 100 3 */ - 440, /* OBJ_pilotObjectClass 0 9 2342 19200300 100 4 */ - 441, /* OBJ_pilotGroups 0 9 2342 19200300 100 10 */ - 1065, /* OBJ_aria_128_ecb 1 2 410 200046 1 1 1 */ - 1066, /* OBJ_aria_128_cbc 1 2 410 200046 1 1 2 */ - 1067, /* OBJ_aria_128_cfb128 1 2 410 200046 1 1 3 */ - 1068, /* OBJ_aria_128_ofb128 1 2 410 200046 1 1 4 */ - 1069, /* OBJ_aria_128_ctr 1 2 410 200046 1 1 5 */ - 1070, /* OBJ_aria_192_ecb 1 2 410 200046 1 1 6 */ - 1071, /* OBJ_aria_192_cbc 1 2 410 200046 1 1 7 */ - 1072, /* OBJ_aria_192_cfb128 1 2 410 200046 1 1 8 */ - 1073, /* OBJ_aria_192_ofb128 1 2 410 200046 1 1 9 */ - 1074, /* OBJ_aria_192_ctr 1 2 410 200046 1 1 10 */ - 1075, /* OBJ_aria_256_ecb 1 2 410 200046 1 1 11 */ - 1076, /* OBJ_aria_256_cbc 1 2 410 200046 1 1 12 */ - 1077, /* OBJ_aria_256_cfb128 1 2 410 200046 1 1 13 */ - 1078, /* OBJ_aria_256_ofb128 1 2 410 200046 1 1 14 */ - 1079, /* OBJ_aria_256_ctr 1 2 410 200046 1 1 15 */ - 1123, /* OBJ_aria_128_gcm 1 2 410 200046 1 1 34 */ - 1124, /* OBJ_aria_192_gcm 1 2 410 200046 1 1 35 */ - 1125, /* OBJ_aria_256_gcm 1 2 410 200046 1 1 36 */ - 1120, /* OBJ_aria_128_ccm 1 2 410 200046 1 1 37 */ - 1121, /* OBJ_aria_192_ccm 1 2 410 200046 1 1 38 */ - 1122, /* OBJ_aria_256_ccm 1 2 410 200046 1 1 39 */ - 1174, /* OBJ_magma_ctr_acpkm 1 2 643 7 1 1 5 1 1 */ - 1175, /* OBJ_magma_ctr_acpkm_omac 1 2 643 7 1 1 5 1 2 */ - 1177, /* OBJ_kuznyechik_ctr_acpkm 1 2 643 7 1 1 5 2 1 */ - 1178, /* OBJ_kuznyechik_ctr_acpkm_omac 1 2 643 7 1 1 5 2 2 */ - 1181, /* OBJ_magma_kexp15 1 2 643 7 1 1 7 1 1 */ - 1183, /* OBJ_kuznyechik_kexp15 1 2 643 7 1 1 7 2 1 */ - 1148, /* OBJ_id_tc26_gost_3410_2012_256_paramSetA 1 2 643 7 1 2 1 1 1 */ - 1184, /* OBJ_id_tc26_gost_3410_2012_256_paramSetB 1 2 643 7 1 2 1 1 2 */ - 1185, /* OBJ_id_tc26_gost_3410_2012_256_paramSetC 1 2 643 7 1 2 1 1 3 */ - 1186, /* OBJ_id_tc26_gost_3410_2012_256_paramSetD 1 2 643 7 1 2 1 1 4 */ - 997, /* OBJ_id_tc26_gost_3410_2012_512_paramSetTest 1 2 643 7 1 2 1 2 0 */ - 998, /* OBJ_id_tc26_gost_3410_2012_512_paramSetA 1 2 643 7 1 2 1 2 1 */ - 999, /* OBJ_id_tc26_gost_3410_2012_512_paramSetB 1 2 643 7 1 2 1 2 2 */ - 1149, /* OBJ_id_tc26_gost_3410_2012_512_paramSetC 1 2 643 7 1 2 1 2 3 */ - 1003, /* OBJ_id_tc26_gost_28147_param_Z 1 2 643 7 1 2 5 1 1 */ - 108, /* OBJ_cast5_cbc 1 2 840 113533 7 66 10 */ - 112, /* OBJ_pbeWithMD5AndCast5_CBC 1 2 840 113533 7 66 12 */ - 782, /* OBJ_id_PasswordBasedMAC 1 2 840 113533 7 66 13 */ - 783, /* OBJ_id_DHBasedMac 1 2 840 113533 7 66 30 */ - 6, /* OBJ_rsaEncryption 1 2 840 113549 1 1 1 */ - 7, /* OBJ_md2WithRSAEncryption 1 2 840 113549 1 1 2 */ - 396, /* OBJ_md4WithRSAEncryption 1 2 840 113549 1 1 3 */ - 8, /* OBJ_md5WithRSAEncryption 1 2 840 113549 1 1 4 */ - 65, /* OBJ_sha1WithRSAEncryption 1 2 840 113549 1 1 5 */ - 644, /* OBJ_rsaOAEPEncryptionSET 1 2 840 113549 1 1 6 */ - 919, /* OBJ_rsaesOaep 1 2 840 113549 1 1 7 */ - 911, /* OBJ_mgf1 1 2 840 113549 1 1 8 */ - 935, /* OBJ_pSpecified 1 2 840 113549 1 1 9 */ - 912, /* OBJ_rsassaPss 1 2 840 113549 1 1 10 */ - 668, /* OBJ_sha256WithRSAEncryption 1 2 840 113549 1 1 11 */ - 669, /* OBJ_sha384WithRSAEncryption 1 2 840 113549 1 1 12 */ - 670, /* OBJ_sha512WithRSAEncryption 1 2 840 113549 1 1 13 */ - 671, /* OBJ_sha224WithRSAEncryption 1 2 840 113549 1 1 14 */ - 1145, /* OBJ_sha512_224WithRSAEncryption 1 2 840 113549 1 1 15 */ - 1146, /* OBJ_sha512_256WithRSAEncryption 1 2 840 113549 1 1 16 */ - 28, /* OBJ_dhKeyAgreement 1 2 840 113549 1 3 1 */ - 9, /* OBJ_pbeWithMD2AndDES_CBC 1 2 840 113549 1 5 1 */ - 10, /* OBJ_pbeWithMD5AndDES_CBC 1 2 840 113549 1 5 3 */ - 168, /* OBJ_pbeWithMD2AndRC2_CBC 1 2 840 113549 1 5 4 */ - 169, /* OBJ_pbeWithMD5AndRC2_CBC 1 2 840 113549 1 5 6 */ - 170, /* OBJ_pbeWithSHA1AndDES_CBC 1 2 840 113549 1 5 10 */ - 68, /* OBJ_pbeWithSHA1AndRC2_CBC 1 2 840 113549 1 5 11 */ - 69, /* OBJ_id_pbkdf2 1 2 840 113549 1 5 12 */ - 161, /* OBJ_pbes2 1 2 840 113549 1 5 13 */ - 162, /* OBJ_pbmac1 1 2 840 113549 1 5 14 */ - 21, /* OBJ_pkcs7_data 1 2 840 113549 1 7 1 */ - 22, /* OBJ_pkcs7_signed 1 2 840 113549 1 7 2 */ - 23, /* OBJ_pkcs7_enveloped 1 2 840 113549 1 7 3 */ - 24, /* OBJ_pkcs7_signedAndEnveloped 1 2 840 113549 1 7 4 */ - 25, /* OBJ_pkcs7_digest 1 2 840 113549 1 7 5 */ - 26, /* OBJ_pkcs7_encrypted 1 2 840 113549 1 7 6 */ - 48, /* OBJ_pkcs9_emailAddress 1 2 840 113549 1 9 1 */ - 49, /* OBJ_pkcs9_unstructuredName 1 2 840 113549 1 9 2 */ - 50, /* OBJ_pkcs9_contentType 1 2 840 113549 1 9 3 */ - 51, /* OBJ_pkcs9_messageDigest 1 2 840 113549 1 9 4 */ - 52, /* OBJ_pkcs9_signingTime 1 2 840 113549 1 9 5 */ - 53, /* OBJ_pkcs9_countersignature 1 2 840 113549 1 9 6 */ - 54, /* OBJ_pkcs9_challengePassword 1 2 840 113549 1 9 7 */ - 55, /* OBJ_pkcs9_unstructuredAddress 1 2 840 113549 1 9 8 */ - 56, /* OBJ_pkcs9_extCertAttributes 1 2 840 113549 1 9 9 */ - 172, /* OBJ_ext_req 1 2 840 113549 1 9 14 */ - 167, /* OBJ_SMIMECapabilities 1 2 840 113549 1 9 15 */ - 188, /* OBJ_SMIME 1 2 840 113549 1 9 16 */ - 156, /* OBJ_friendlyName 1 2 840 113549 1 9 20 */ - 157, /* OBJ_localKeyID 1 2 840 113549 1 9 21 */ - 1263, /* OBJ_id_aa_CMSAlgorithmProtection 1 2 840 113549 1 9 52 */ - 681, /* OBJ_X9_62_onBasis 1 2 840 10045 1 2 3 1 */ - 682, /* OBJ_X9_62_tpBasis 1 2 840 10045 1 2 3 2 */ - 683, /* OBJ_X9_62_ppBasis 1 2 840 10045 1 2 3 3 */ - 417, /* OBJ_ms_csp_name 1 3 6 1 4 1 311 17 1 */ - 856, /* OBJ_LocalKeySet 1 3 6 1 4 1 311 17 2 */ - 1293, /* OBJ_ms_cert_templ 1 3 6 1 4 1 311 21 7 */ - 1294, /* OBJ_ms_app_policies 1 3 6 1 4 1 311 21 10 */ - 1292, /* OBJ_ms_ntds_sec_ext 1 3 6 1 4 1 311 25 2 */ - 1322, /* OBJ_id_kp_wisun_fan_device 1 3 6 1 4 1 45605 1 */ - 390, /* OBJ_dcObject 1 3 6 1 4 1 1466 344 */ - 91, /* OBJ_bf_cbc 1 3 6 1 4 1 3029 1 2 */ - 973, /* OBJ_id_scrypt 1 3 6 1 4 1 11591 4 11 */ - 315, /* OBJ_id_regCtrl_regToken 1 3 6 1 5 5 7 5 1 1 */ - 316, /* OBJ_id_regCtrl_authenticator 1 3 6 1 5 5 7 5 1 2 */ - 317, /* OBJ_id_regCtrl_pkiPublicationInfo 1 3 6 1 5 5 7 5 1 3 */ - 318, /* OBJ_id_regCtrl_pkiArchiveOptions 1 3 6 1 5 5 7 5 1 4 */ - 319, /* OBJ_id_regCtrl_oldCertID 1 3 6 1 5 5 7 5 1 5 */ - 320, /* OBJ_id_regCtrl_protocolEncrKey 1 3 6 1 5 5 7 5 1 6 */ - 1258, /* OBJ_id_regCtrl_altCertTemplate 1 3 6 1 5 5 7 5 1 7 */ - 1259, /* OBJ_id_regCtrl_algId 1 3 6 1 5 5 7 5 1 11 */ - 1260, /* OBJ_id_regCtrl_rsaKeyLen 1 3 6 1 5 5 7 5 1 12 */ - 321, /* OBJ_id_regInfo_utf8Pairs 1 3 6 1 5 5 7 5 2 1 */ - 322, /* OBJ_id_regInfo_certReq 1 3 6 1 5 5 7 5 2 2 */ - 365, /* OBJ_id_pkix_OCSP_basic 1 3 6 1 5 5 7 48 1 1 */ - 366, /* OBJ_id_pkix_OCSP_Nonce 1 3 6 1 5 5 7 48 1 2 */ - 367, /* OBJ_id_pkix_OCSP_CrlID 1 3 6 1 5 5 7 48 1 3 */ - 368, /* OBJ_id_pkix_OCSP_acceptableResponses 1 3 6 1 5 5 7 48 1 4 */ - 369, /* OBJ_id_pkix_OCSP_noCheck 1 3 6 1 5 5 7 48 1 5 */ - 370, /* OBJ_id_pkix_OCSP_archiveCutoff 1 3 6 1 5 5 7 48 1 6 */ - 371, /* OBJ_id_pkix_OCSP_serviceLocator 1 3 6 1 5 5 7 48 1 7 */ - 372, /* OBJ_id_pkix_OCSP_extendedStatus 1 3 6 1 5 5 7 48 1 8 */ - 373, /* OBJ_id_pkix_OCSP_valid 1 3 6 1 5 5 7 48 1 9 */ - 374, /* OBJ_id_pkix_OCSP_path 1 3 6 1 5 5 7 48 1 10 */ - 375, /* OBJ_id_pkix_OCSP_trustRoot 1 3 6 1 5 5 7 48 1 11 */ - 921, /* OBJ_brainpoolP160r1 1 3 36 3 3 2 8 1 1 1 */ - 922, /* OBJ_brainpoolP160t1 1 3 36 3 3 2 8 1 1 2 */ - 923, /* OBJ_brainpoolP192r1 1 3 36 3 3 2 8 1 1 3 */ - 924, /* OBJ_brainpoolP192t1 1 3 36 3 3 2 8 1 1 4 */ - 925, /* OBJ_brainpoolP224r1 1 3 36 3 3 2 8 1 1 5 */ - 926, /* OBJ_brainpoolP224t1 1 3 36 3 3 2 8 1 1 6 */ - 927, /* OBJ_brainpoolP256r1 1 3 36 3 3 2 8 1 1 7 */ - 928, /* OBJ_brainpoolP256t1 1 3 36 3 3 2 8 1 1 8 */ - 929, /* OBJ_brainpoolP320r1 1 3 36 3 3 2 8 1 1 9 */ - 930, /* OBJ_brainpoolP320t1 1 3 36 3 3 2 8 1 1 10 */ - 931, /* OBJ_brainpoolP384r1 1 3 36 3 3 2 8 1 1 11 */ - 932, /* OBJ_brainpoolP384t1 1 3 36 3 3 2 8 1 1 12 */ - 933, /* OBJ_brainpoolP512r1 1 3 36 3 3 2 8 1 1 13 */ - 934, /* OBJ_brainpoolP512t1 1 3 36 3 3 2 8 1 1 14 */ - 936, /* OBJ_dhSinglePass_stdDH_sha1kdf_scheme 1 3 133 16 840 63 0 2 */ - 941, /* OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme 1 3 133 16 840 63 0 3 */ - 418, /* OBJ_aes_128_ecb 2 16 840 1 101 3 4 1 1 */ - 419, /* OBJ_aes_128_cbc 2 16 840 1 101 3 4 1 2 */ - 420, /* OBJ_aes_128_ofb128 2 16 840 1 101 3 4 1 3 */ - 421, /* OBJ_aes_128_cfb128 2 16 840 1 101 3 4 1 4 */ - 788, /* OBJ_id_aes128_wrap 2 16 840 1 101 3 4 1 5 */ - 895, /* OBJ_aes_128_gcm 2 16 840 1 101 3 4 1 6 */ - 896, /* OBJ_aes_128_ccm 2 16 840 1 101 3 4 1 7 */ - 897, /* OBJ_id_aes128_wrap_pad 2 16 840 1 101 3 4 1 8 */ - 422, /* OBJ_aes_192_ecb 2 16 840 1 101 3 4 1 21 */ - 423, /* OBJ_aes_192_cbc 2 16 840 1 101 3 4 1 22 */ - 424, /* OBJ_aes_192_ofb128 2 16 840 1 101 3 4 1 23 */ - 425, /* OBJ_aes_192_cfb128 2 16 840 1 101 3 4 1 24 */ - 789, /* OBJ_id_aes192_wrap 2 16 840 1 101 3 4 1 25 */ - 898, /* OBJ_aes_192_gcm 2 16 840 1 101 3 4 1 26 */ - 899, /* OBJ_aes_192_ccm 2 16 840 1 101 3 4 1 27 */ - 900, /* OBJ_id_aes192_wrap_pad 2 16 840 1 101 3 4 1 28 */ - 426, /* OBJ_aes_256_ecb 2 16 840 1 101 3 4 1 41 */ - 427, /* OBJ_aes_256_cbc 2 16 840 1 101 3 4 1 42 */ - 428, /* OBJ_aes_256_ofb128 2 16 840 1 101 3 4 1 43 */ - 429, /* OBJ_aes_256_cfb128 2 16 840 1 101 3 4 1 44 */ - 790, /* OBJ_id_aes256_wrap 2 16 840 1 101 3 4 1 45 */ - 901, /* OBJ_aes_256_gcm 2 16 840 1 101 3 4 1 46 */ - 902, /* OBJ_aes_256_ccm 2 16 840 1 101 3 4 1 47 */ - 903, /* OBJ_id_aes256_wrap_pad 2 16 840 1 101 3 4 1 48 */ - 672, /* OBJ_sha256 2 16 840 1 101 3 4 2 1 */ - 673, /* OBJ_sha384 2 16 840 1 101 3 4 2 2 */ - 674, /* OBJ_sha512 2 16 840 1 101 3 4 2 3 */ - 675, /* OBJ_sha224 2 16 840 1 101 3 4 2 4 */ - 1094, /* OBJ_sha512_224 2 16 840 1 101 3 4 2 5 */ - 1095, /* OBJ_sha512_256 2 16 840 1 101 3 4 2 6 */ - 1096, /* OBJ_sha3_224 2 16 840 1 101 3 4 2 7 */ - 1097, /* OBJ_sha3_256 2 16 840 1 101 3 4 2 8 */ - 1098, /* OBJ_sha3_384 2 16 840 1 101 3 4 2 9 */ - 1099, /* OBJ_sha3_512 2 16 840 1 101 3 4 2 10 */ - 1100, /* OBJ_shake128 2 16 840 1 101 3 4 2 11 */ - 1101, /* OBJ_shake256 2 16 840 1 101 3 4 2 12 */ - 1102, /* OBJ_hmac_sha3_224 2 16 840 1 101 3 4 2 13 */ - 1103, /* OBJ_hmac_sha3_256 2 16 840 1 101 3 4 2 14 */ - 1104, /* OBJ_hmac_sha3_384 2 16 840 1 101 3 4 2 15 */ - 1105, /* OBJ_hmac_sha3_512 2 16 840 1 101 3 4 2 16 */ - 1196, /* OBJ_kmac128 2 16 840 1 101 3 4 2 19 */ - 1197, /* OBJ_kmac256 2 16 840 1 101 3 4 2 20 */ - 802, /* OBJ_dsa_with_SHA224 2 16 840 1 101 3 4 3 1 */ - 803, /* OBJ_dsa_with_SHA256 2 16 840 1 101 3 4 3 2 */ - 1106, /* OBJ_dsa_with_SHA384 2 16 840 1 101 3 4 3 3 */ - 1107, /* OBJ_dsa_with_SHA512 2 16 840 1 101 3 4 3 4 */ - 1108, /* OBJ_dsa_with_SHA3_224 2 16 840 1 101 3 4 3 5 */ - 1109, /* OBJ_dsa_with_SHA3_256 2 16 840 1 101 3 4 3 6 */ - 1110, /* OBJ_dsa_with_SHA3_384 2 16 840 1 101 3 4 3 7 */ - 1111, /* OBJ_dsa_with_SHA3_512 2 16 840 1 101 3 4 3 8 */ - 1112, /* OBJ_ecdsa_with_SHA3_224 2 16 840 1 101 3 4 3 9 */ - 1113, /* OBJ_ecdsa_with_SHA3_256 2 16 840 1 101 3 4 3 10 */ - 1114, /* OBJ_ecdsa_with_SHA3_384 2 16 840 1 101 3 4 3 11 */ - 1115, /* OBJ_ecdsa_with_SHA3_512 2 16 840 1 101 3 4 3 12 */ - 1116, /* OBJ_RSA_SHA3_224 2 16 840 1 101 3 4 3 13 */ - 1117, /* OBJ_RSA_SHA3_256 2 16 840 1 101 3 4 3 14 */ - 1118, /* OBJ_RSA_SHA3_384 2 16 840 1 101 3 4 3 15 */ - 1119, /* OBJ_RSA_SHA3_512 2 16 840 1 101 3 4 3 16 */ - 1457, /* OBJ_ML_DSA_44 2 16 840 1 101 3 4 3 17 */ - 1458, /* OBJ_ML_DSA_65 2 16 840 1 101 3 4 3 18 */ - 1459, /* OBJ_ML_DSA_87 2 16 840 1 101 3 4 3 19 */ - 1460, /* OBJ_SLH_DSA_SHA2_128s 2 16 840 1 101 3 4 3 20 */ - 1461, /* OBJ_SLH_DSA_SHA2_128f 2 16 840 1 101 3 4 3 21 */ - 1462, /* OBJ_SLH_DSA_SHA2_192s 2 16 840 1 101 3 4 3 22 */ - 1463, /* OBJ_SLH_DSA_SHA2_192f 2 16 840 1 101 3 4 3 23 */ - 1464, /* OBJ_SLH_DSA_SHA2_256s 2 16 840 1 101 3 4 3 24 */ - 1465, /* OBJ_SLH_DSA_SHA2_256f 2 16 840 1 101 3 4 3 25 */ - 1466, /* OBJ_SLH_DSA_SHAKE_128s 2 16 840 1 101 3 4 3 26 */ - 1467, /* OBJ_SLH_DSA_SHAKE_128f 2 16 840 1 101 3 4 3 27 */ - 1468, /* OBJ_SLH_DSA_SHAKE_192s 2 16 840 1 101 3 4 3 28 */ - 1469, /* OBJ_SLH_DSA_SHAKE_192f 2 16 840 1 101 3 4 3 29 */ - 1470, /* OBJ_SLH_DSA_SHAKE_256s 2 16 840 1 101 3 4 3 30 */ - 1471, /* OBJ_SLH_DSA_SHAKE_256f 2 16 840 1 101 3 4 3 31 */ - 1472, /* OBJ_HASH_ML_DSA_44_WITH_SHA512 2 16 840 1 101 3 4 3 32 */ - 1473, /* OBJ_HASH_ML_DSA_65_WITH_SHA512 2 16 840 1 101 3 4 3 33 */ - 1474, /* OBJ_HASH_ML_DSA_87_WITH_SHA512 2 16 840 1 101 3 4 3 34 */ - 1475, /* OBJ_SLH_DSA_SHA2_128s_WITH_SHA256 2 16 840 1 101 3 4 3 35 */ - 1476, /* OBJ_SLH_DSA_SHA2_128f_WITH_SHA256 2 16 840 1 101 3 4 3 36 */ - 1477, /* OBJ_SLH_DSA_SHA2_192s_WITH_SHA512 2 16 840 1 101 3 4 3 37 */ - 1478, /* OBJ_SLH_DSA_SHA2_192f_WITH_SHA512 2 16 840 1 101 3 4 3 38 */ - 1479, /* OBJ_SLH_DSA_SHA2_256s_WITH_SHA512 2 16 840 1 101 3 4 3 39 */ - 1480, /* OBJ_SLH_DSA_SHA2_256f_WITH_SHA512 2 16 840 1 101 3 4 3 40 */ - 1481, /* OBJ_SLH_DSA_SHAKE_128s_WITH_SHAKE128 2 16 840 1 101 3 4 3 41 */ - 1482, /* OBJ_SLH_DSA_SHAKE_128f_WITH_SHAKE128 2 16 840 1 101 3 4 3 42 */ - 1483, /* OBJ_SLH_DSA_SHAKE_192s_WITH_SHAKE256 2 16 840 1 101 3 4 3 43 */ - 1484, /* OBJ_SLH_DSA_SHAKE_192f_WITH_SHAKE256 2 16 840 1 101 3 4 3 44 */ - 1485, /* OBJ_SLH_DSA_SHAKE_256s_WITH_SHAKE256 2 16 840 1 101 3 4 3 45 */ - 1486, /* OBJ_SLH_DSA_SHAKE_256f_WITH_SHAKE256 2 16 840 1 101 3 4 3 46 */ - 1454, /* OBJ_ML_KEM_512 2 16 840 1 101 3 4 4 1 */ - 1455, /* OBJ_ML_KEM_768 2 16 840 1 101 3 4 4 2 */ - 1456, /* OBJ_ML_KEM_1024 2 16 840 1 101 3 4 4 3 */ - 71, /* OBJ_netscape_cert_type 2 16 840 1 113730 1 1 */ - 72, /* OBJ_netscape_base_url 2 16 840 1 113730 1 2 */ - 73, /* OBJ_netscape_revocation_url 2 16 840 1 113730 1 3 */ - 74, /* OBJ_netscape_ca_revocation_url 2 16 840 1 113730 1 4 */ - 75, /* OBJ_netscape_renewal_url 2 16 840 1 113730 1 7 */ - 76, /* OBJ_netscape_ca_policy_url 2 16 840 1 113730 1 8 */ - 77, /* OBJ_netscape_ssl_server_name 2 16 840 1 113730 1 12 */ - 78, /* OBJ_netscape_comment 2 16 840 1 113730 1 13 */ - 79, /* OBJ_netscape_cert_sequence 2 16 840 1 113730 2 5 */ - 139, /* OBJ_ns_sgc 2 16 840 1 113730 4 1 */ - 458, /* OBJ_userId 0 9 2342 19200300 100 1 1 */ - 459, /* OBJ_textEncodedORAddress 0 9 2342 19200300 100 1 2 */ - 460, /* OBJ_rfc822Mailbox 0 9 2342 19200300 100 1 3 */ - 461, /* OBJ_info 0 9 2342 19200300 100 1 4 */ - 462, /* OBJ_favouriteDrink 0 9 2342 19200300 100 1 5 */ - 463, /* OBJ_roomNumber 0 9 2342 19200300 100 1 6 */ - 464, /* OBJ_photo 0 9 2342 19200300 100 1 7 */ - 465, /* OBJ_userClass 0 9 2342 19200300 100 1 8 */ - 466, /* OBJ_host 0 9 2342 19200300 100 1 9 */ - 467, /* OBJ_manager 0 9 2342 19200300 100 1 10 */ - 468, /* OBJ_documentIdentifier 0 9 2342 19200300 100 1 11 */ - 469, /* OBJ_documentTitle 0 9 2342 19200300 100 1 12 */ - 470, /* OBJ_documentVersion 0 9 2342 19200300 100 1 13 */ - 471, /* OBJ_documentAuthor 0 9 2342 19200300 100 1 14 */ - 472, /* OBJ_documentLocation 0 9 2342 19200300 100 1 15 */ - 473, /* OBJ_homeTelephoneNumber 0 9 2342 19200300 100 1 20 */ - 474, /* OBJ_secretary 0 9 2342 19200300 100 1 21 */ - 475, /* OBJ_otherMailbox 0 9 2342 19200300 100 1 22 */ - 476, /* OBJ_lastModifiedTime 0 9 2342 19200300 100 1 23 */ - 477, /* OBJ_lastModifiedBy 0 9 2342 19200300 100 1 24 */ - 391, /* OBJ_domainComponent 0 9 2342 19200300 100 1 25 */ - 478, /* OBJ_aRecord 0 9 2342 19200300 100 1 26 */ - 479, /* OBJ_pilotAttributeType27 0 9 2342 19200300 100 1 27 */ - 480, /* OBJ_mXRecord 0 9 2342 19200300 100 1 28 */ - 481, /* OBJ_nSRecord 0 9 2342 19200300 100 1 29 */ - 482, /* OBJ_sOARecord 0 9 2342 19200300 100 1 30 */ - 483, /* OBJ_cNAMERecord 0 9 2342 19200300 100 1 31 */ - 484, /* OBJ_associatedDomain 0 9 2342 19200300 100 1 37 */ - 485, /* OBJ_associatedName 0 9 2342 19200300 100 1 38 */ - 486, /* OBJ_homePostalAddress 0 9 2342 19200300 100 1 39 */ - 487, /* OBJ_personalTitle 0 9 2342 19200300 100 1 40 */ - 488, /* OBJ_mobileTelephoneNumber 0 9 2342 19200300 100 1 41 */ - 489, /* OBJ_pagerTelephoneNumber 0 9 2342 19200300 100 1 42 */ - 490, /* OBJ_friendlyCountryName 0 9 2342 19200300 100 1 43 */ - 102, /* OBJ_uniqueIdentifier 0 9 2342 19200300 100 1 44 */ - 491, /* OBJ_organizationalStatus 0 9 2342 19200300 100 1 45 */ - 492, /* OBJ_janetMailbox 0 9 2342 19200300 100 1 46 */ - 493, /* OBJ_mailPreferenceOption 0 9 2342 19200300 100 1 47 */ - 494, /* OBJ_buildingName 0 9 2342 19200300 100 1 48 */ - 495, /* OBJ_dSAQuality 0 9 2342 19200300 100 1 49 */ - 496, /* OBJ_singleLevelQuality 0 9 2342 19200300 100 1 50 */ - 497, /* OBJ_subtreeMinimumQuality 0 9 2342 19200300 100 1 51 */ - 498, /* OBJ_subtreeMaximumQuality 0 9 2342 19200300 100 1 52 */ - 499, /* OBJ_personalSignature 0 9 2342 19200300 100 1 53 */ - 500, /* OBJ_dITRedirect 0 9 2342 19200300 100 1 54 */ - 501, /* OBJ_audio 0 9 2342 19200300 100 1 55 */ - 502, /* OBJ_documentPublisher 0 9 2342 19200300 100 1 56 */ - 442, /* OBJ_iA5StringSyntax 0 9 2342 19200300 100 3 4 */ - 443, /* OBJ_caseIgnoreIA5StringSyntax 0 9 2342 19200300 100 3 5 */ - 444, /* OBJ_pilotObject 0 9 2342 19200300 100 4 3 */ - 445, /* OBJ_pilotPerson 0 9 2342 19200300 100 4 4 */ - 446, /* OBJ_account 0 9 2342 19200300 100 4 5 */ - 447, /* OBJ_document 0 9 2342 19200300 100 4 6 */ - 448, /* OBJ_room 0 9 2342 19200300 100 4 7 */ - 449, /* OBJ_documentSeries 0 9 2342 19200300 100 4 9 */ - 392, /* OBJ_Domain 0 9 2342 19200300 100 4 13 */ - 450, /* OBJ_rFC822localPart 0 9 2342 19200300 100 4 14 */ - 451, /* OBJ_dNSDomain 0 9 2342 19200300 100 4 15 */ - 452, /* OBJ_domainRelatedObject 0 9 2342 19200300 100 4 17 */ - 453, /* OBJ_friendlyCountry 0 9 2342 19200300 100 4 18 */ - 454, /* OBJ_simpleSecurityObject 0 9 2342 19200300 100 4 19 */ - 455, /* OBJ_pilotOrganization 0 9 2342 19200300 100 4 20 */ - 456, /* OBJ_pilotDSA 0 9 2342 19200300 100 4 21 */ - 457, /* OBJ_qualityLabelledData 0 9 2342 19200300 100 4 22 */ - 1281, /* OBJ_hmacWithSM3 1 2 156 10197 1 401 3 1 */ - 1152, /* OBJ_dstu28147 1 2 804 2 1 1 1 1 1 1 */ - 1156, /* OBJ_hmacWithDstu34311 1 2 804 2 1 1 1 1 1 2 */ - 1157, /* OBJ_dstu34311 1 2 804 2 1 1 1 1 2 1 */ - 189, /* OBJ_id_smime_mod 1 2 840 113549 1 9 16 0 */ - 190, /* OBJ_id_smime_ct 1 2 840 113549 1 9 16 1 */ - 191, /* OBJ_id_smime_aa 1 2 840 113549 1 9 16 2 */ - 192, /* OBJ_id_smime_alg 1 2 840 113549 1 9 16 3 */ - 193, /* OBJ_id_smime_cd 1 2 840 113549 1 9 16 4 */ - 194, /* OBJ_id_smime_spq 1 2 840 113549 1 9 16 5 */ - 195, /* OBJ_id_smime_cti 1 2 840 113549 1 9 16 6 */ - 1499, /* OBJ_id_smime_ori 1 2 840 113549 1 9 16 13 */ - 158, /* OBJ_x509Certificate 1 2 840 113549 1 9 22 1 */ - 159, /* OBJ_sdsiCertificate 1 2 840 113549 1 9 22 2 */ - 160, /* OBJ_x509Crl 1 2 840 113549 1 9 23 1 */ - 144, /* OBJ_pbe_WithSHA1And128BitRC4 1 2 840 113549 1 12 1 1 */ - 145, /* OBJ_pbe_WithSHA1And40BitRC4 1 2 840 113549 1 12 1 2 */ - 146, /* OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC 1 2 840 113549 1 12 1 3 */ - 147, /* OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC 1 2 840 113549 1 12 1 4 */ - 148, /* OBJ_pbe_WithSHA1And128BitRC2_CBC 1 2 840 113549 1 12 1 5 */ - 149, /* OBJ_pbe_WithSHA1And40BitRC2_CBC 1 2 840 113549 1 12 1 6 */ - 171, /* OBJ_ms_ext_req 1 3 6 1 4 1 311 2 1 14 */ - 134, /* OBJ_ms_code_ind 1 3 6 1 4 1 311 2 1 21 */ - 135, /* OBJ_ms_code_com 1 3 6 1 4 1 311 2 1 22 */ - 136, /* OBJ_ms_ctl_sign 1 3 6 1 4 1 311 10 3 1 */ - 137, /* OBJ_ms_sgc 1 3 6 1 4 1 311 10 3 3 */ - 138, /* OBJ_ms_efs 1 3 6 1 4 1 311 10 3 4 */ - 648, /* OBJ_ms_smartcard_login 1 3 6 1 4 1 311 20 2 2 */ - 649, /* OBJ_ms_upn 1 3 6 1 4 1 311 20 2 3 */ - 1291, /* OBJ_ms_ntds_obj_sid 1 3 6 1 4 1 311 25 2 1 */ - 1201, /* OBJ_blake2bmac 1 3 6 1 4 1 1722 12 2 1 */ - 1202, /* OBJ_blake2smac 1 3 6 1 4 1 1722 12 2 2 */ - 951, /* OBJ_ct_precert_scts 1 3 6 1 4 1 11129 2 4 2 */ - 952, /* OBJ_ct_precert_poison 1 3 6 1 4 1 11129 2 4 3 */ - 953, /* OBJ_ct_precert_signer 1 3 6 1 4 1 11129 2 4 4 */ - 954, /* OBJ_ct_cert_scts 1 3 6 1 4 1 11129 2 4 5 */ - 751, /* OBJ_camellia_128_cbc 1 2 392 200011 61 1 1 1 2 */ - 752, /* OBJ_camellia_192_cbc 1 2 392 200011 61 1 1 1 3 */ - 753, /* OBJ_camellia_256_cbc 1 2 392 200011 61 1 1 1 4 */ - 907, /* OBJ_id_camellia128_wrap 1 2 392 200011 61 1 1 3 2 */ - 908, /* OBJ_id_camellia192_wrap 1 2 392 200011 61 1 1 3 3 */ - 909, /* OBJ_id_camellia256_wrap 1 2 392 200011 61 1 1 3 4 */ - 1153, /* OBJ_dstu28147_ofb 1 2 804 2 1 1 1 1 1 1 2 */ - 1154, /* OBJ_dstu28147_cfb 1 2 804 2 1 1 1 1 1 1 3 */ - 1155, /* OBJ_dstu28147_wrap 1 2 804 2 1 1 1 1 1 1 5 */ - 1158, /* OBJ_dstu4145le 1 2 804 2 1 1 1 1 3 1 1 */ - 196, /* OBJ_id_smime_mod_cms 1 2 840 113549 1 9 16 0 1 */ - 197, /* OBJ_id_smime_mod_ess 1 2 840 113549 1 9 16 0 2 */ - 198, /* OBJ_id_smime_mod_oid 1 2 840 113549 1 9 16 0 3 */ - 199, /* OBJ_id_smime_mod_msg_v3 1 2 840 113549 1 9 16 0 4 */ - 200, /* OBJ_id_smime_mod_ets_eSignature_88 1 2 840 113549 1 9 16 0 5 */ - 201, /* OBJ_id_smime_mod_ets_eSignature_97 1 2 840 113549 1 9 16 0 6 */ - 202, /* OBJ_id_smime_mod_ets_eSigPolicy_88 1 2 840 113549 1 9 16 0 7 */ - 203, /* OBJ_id_smime_mod_ets_eSigPolicy_97 1 2 840 113549 1 9 16 0 8 */ - 204, /* OBJ_id_smime_ct_receipt 1 2 840 113549 1 9 16 1 1 */ - 205, /* OBJ_id_smime_ct_authData 1 2 840 113549 1 9 16 1 2 */ - 206, /* OBJ_id_smime_ct_publishCert 1 2 840 113549 1 9 16 1 3 */ - 207, /* OBJ_id_smime_ct_TSTInfo 1 2 840 113549 1 9 16 1 4 */ - 208, /* OBJ_id_smime_ct_TDTInfo 1 2 840 113549 1 9 16 1 5 */ - 209, /* OBJ_id_smime_ct_contentInfo 1 2 840 113549 1 9 16 1 6 */ - 210, /* OBJ_id_smime_ct_DVCSRequestData 1 2 840 113549 1 9 16 1 7 */ - 211, /* OBJ_id_smime_ct_DVCSResponseData 1 2 840 113549 1 9 16 1 8 */ - 786, /* OBJ_id_smime_ct_compressedData 1 2 840 113549 1 9 16 1 9 */ - 1058, /* OBJ_id_smime_ct_contentCollection 1 2 840 113549 1 9 16 1 19 */ - 1059, /* OBJ_id_smime_ct_authEnvelopedData 1 2 840 113549 1 9 16 1 23 */ - 1234, /* OBJ_id_ct_routeOriginAuthz 1 2 840 113549 1 9 16 1 24 */ - 1235, /* OBJ_id_ct_rpkiManifest 1 2 840 113549 1 9 16 1 26 */ - 787, /* OBJ_id_ct_asciiTextWithCRLF 1 2 840 113549 1 9 16 1 27 */ - 1060, /* OBJ_id_ct_xml 1 2 840 113549 1 9 16 1 28 */ - 1236, /* OBJ_id_ct_rpkiGhostbusters 1 2 840 113549 1 9 16 1 35 */ - 1237, /* OBJ_id_ct_resourceTaggedAttest 1 2 840 113549 1 9 16 1 36 */ - 1246, /* OBJ_id_ct_geofeedCSVwithCRLF 1 2 840 113549 1 9 16 1 47 */ - 1247, /* OBJ_id_ct_signedChecklist 1 2 840 113549 1 9 16 1 48 */ - 1250, /* OBJ_id_ct_ASPA 1 2 840 113549 1 9 16 1 49 */ - 1284, /* OBJ_id_ct_signedTAL 1 2 840 113549 1 9 16 1 50 */ - 1320, /* OBJ_id_ct_rpkiSignedPrefixList 1 2 840 113549 1 9 16 1 51 */ - 212, /* OBJ_id_smime_aa_receiptRequest 1 2 840 113549 1 9 16 2 1 */ - 213, /* OBJ_id_smime_aa_securityLabel 1 2 840 113549 1 9 16 2 2 */ - 214, /* OBJ_id_smime_aa_mlExpandHistory 1 2 840 113549 1 9 16 2 3 */ - 215, /* OBJ_id_smime_aa_contentHint 1 2 840 113549 1 9 16 2 4 */ - 216, /* OBJ_id_smime_aa_msgSigDigest 1 2 840 113549 1 9 16 2 5 */ - 217, /* OBJ_id_smime_aa_encapContentType 1 2 840 113549 1 9 16 2 6 */ - 218, /* OBJ_id_smime_aa_contentIdentifier 1 2 840 113549 1 9 16 2 7 */ - 219, /* OBJ_id_smime_aa_macValue 1 2 840 113549 1 9 16 2 8 */ - 220, /* OBJ_id_smime_aa_equivalentLabels 1 2 840 113549 1 9 16 2 9 */ - 221, /* OBJ_id_smime_aa_contentReference 1 2 840 113549 1 9 16 2 10 */ - 222, /* OBJ_id_smime_aa_encrypKeyPref 1 2 840 113549 1 9 16 2 11 */ - 223, /* OBJ_id_smime_aa_signingCertificate 1 2 840 113549 1 9 16 2 12 */ - 224, /* OBJ_id_smime_aa_smimeEncryptCerts 1 2 840 113549 1 9 16 2 13 */ - 225, /* OBJ_id_smime_aa_timeStampToken 1 2 840 113549 1 9 16 2 14 */ - 226, /* OBJ_id_smime_aa_ets_sigPolicyId 1 2 840 113549 1 9 16 2 15 */ - 227, /* OBJ_id_smime_aa_ets_commitmentType 1 2 840 113549 1 9 16 2 16 */ - 228, /* OBJ_id_smime_aa_ets_signerLocation 1 2 840 113549 1 9 16 2 17 */ - 229, /* OBJ_id_smime_aa_ets_signerAttr 1 2 840 113549 1 9 16 2 18 */ - 230, /* OBJ_id_smime_aa_ets_otherSigCert 1 2 840 113549 1 9 16 2 19 */ - 231, /* OBJ_id_smime_aa_ets_contentTimestamp 1 2 840 113549 1 9 16 2 20 */ - 232, /* OBJ_id_smime_aa_ets_CertificateRefs 1 2 840 113549 1 9 16 2 21 */ - 233, /* OBJ_id_smime_aa_ets_RevocationRefs 1 2 840 113549 1 9 16 2 22 */ - 234, /* OBJ_id_smime_aa_ets_certValues 1 2 840 113549 1 9 16 2 23 */ - 235, /* OBJ_id_smime_aa_ets_revocationValues 1 2 840 113549 1 9 16 2 24 */ - 236, /* OBJ_id_smime_aa_ets_escTimeStamp 1 2 840 113549 1 9 16 2 25 */ - 237, /* OBJ_id_smime_aa_ets_certCRLTimestamp 1 2 840 113549 1 9 16 2 26 */ - 238, /* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */ - 239, /* OBJ_id_smime_aa_signatureType 1 2 840 113549 1 9 16 2 28 */ - 240, /* OBJ_id_smime_aa_dvcs_dvc 1 2 840 113549 1 9 16 2 29 */ - 1261, /* OBJ_id_aa_ets_attrCertificateRefs 1 2 840 113549 1 9 16 2 44 */ - 1262, /* OBJ_id_aa_ets_attrRevocationRefs 1 2 840 113549 1 9 16 2 45 */ - 1086, /* OBJ_id_smime_aa_signingCertificateV2 1 2 840 113549 1 9 16 2 47 */ - 1280, /* OBJ_id_aa_ets_archiveTimestampV2 1 2 840 113549 1 9 16 2 48 */ - 241, /* OBJ_id_smime_alg_ESDHwith3DES 1 2 840 113549 1 9 16 3 1 */ - 242, /* OBJ_id_smime_alg_ESDHwithRC2 1 2 840 113549 1 9 16 3 2 */ - 243, /* OBJ_id_smime_alg_3DESwrap 1 2 840 113549 1 9 16 3 3 */ - 244, /* OBJ_id_smime_alg_RC2wrap 1 2 840 113549 1 9 16 3 4 */ - 245, /* OBJ_id_smime_alg_ESDH 1 2 840 113549 1 9 16 3 5 */ - 246, /* OBJ_id_smime_alg_CMS3DESwrap 1 2 840 113549 1 9 16 3 6 */ - 247, /* OBJ_id_smime_alg_CMSRC2wrap 1 2 840 113549 1 9 16 3 7 */ - 125, /* OBJ_zlib_compression 1 2 840 113549 1 9 16 3 8 */ - 893, /* OBJ_id_alg_PWRI_KEK 1 2 840 113549 1 9 16 3 9 */ - 1501, /* OBJ_id_alg_hss_lms_hashsig 1 2 840 113549 1 9 16 3 17 */ - 1496, /* OBJ_HKDF_SHA256 1 2 840 113549 1 9 16 3 28 */ - 1497, /* OBJ_HKDF_SHA384 1 2 840 113549 1 9 16 3 29 */ - 1498, /* OBJ_HKDF_SHA512 1 2 840 113549 1 9 16 3 30 */ - 248, /* OBJ_id_smime_cd_ldap 1 2 840 113549 1 9 16 4 1 */ - 249, /* OBJ_id_smime_spq_ets_sqt_uri 1 2 840 113549 1 9 16 5 1 */ - 250, /* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */ - 251, /* OBJ_id_smime_cti_ets_proofOfOrigin 1 2 840 113549 1 9 16 6 1 */ - 252, /* OBJ_id_smime_cti_ets_proofOfReceipt 1 2 840 113549 1 9 16 6 2 */ - 253, /* OBJ_id_smime_cti_ets_proofOfDelivery 1 2 840 113549 1 9 16 6 3 */ - 254, /* OBJ_id_smime_cti_ets_proofOfSender 1 2 840 113549 1 9 16 6 4 */ - 255, /* OBJ_id_smime_cti_ets_proofOfApproval 1 2 840 113549 1 9 16 6 5 */ - 256, /* OBJ_id_smime_cti_ets_proofOfCreation 1 2 840 113549 1 9 16 6 6 */ - 1500, /* OBJ_id_smime_ori_kem 1 2 840 113549 1 9 16 13 3 */ - 150, /* OBJ_keyBag 1 2 840 113549 1 12 10 1 1 */ - 151, /* OBJ_pkcs8ShroudedKeyBag 1 2 840 113549 1 12 10 1 2 */ - 152, /* OBJ_certBag 1 2 840 113549 1 12 10 1 3 */ - 153, /* OBJ_crlBag 1 2 840 113549 1 12 10 1 4 */ - 154, /* OBJ_secretBag 1 2 840 113549 1 12 10 1 5 */ - 155, /* OBJ_safeContentsBag 1 2 840 113549 1 12 10 1 6 */ - 34, /* OBJ_idea_cbc 1 3 6 1 4 1 188 7 1 1 2 */ - 955, /* OBJ_jurisdictionLocalityName 1 3 6 1 4 1 311 60 2 1 1 */ - 956, /* OBJ_jurisdictionStateOrProvinceName 1 3 6 1 4 1 311 60 2 1 2 */ - 957, /* OBJ_jurisdictionCountryName 1 3 6 1 4 1 311 60 2 1 3 */ - 1056, /* OBJ_blake2b512 1 3 6 1 4 1 1722 12 2 1 16 */ - 1057, /* OBJ_blake2s256 1 3 6 1 4 1 1722 12 2 2 8 */ - 1283, /* OBJ_oracle_jdk_trustedkeyusage 2 16 840 1 113894 746875 1 1 */ - 1159, /* OBJ_dstu4145be 1 2 804 2 1 1 1 1 3 1 1 1 1 */ - 1160, /* OBJ_uacurve0 1 2 804 2 1 1 1 1 3 1 1 2 0 */ - 1161, /* OBJ_uacurve1 1 2 804 2 1 1 1 1 3 1 1 2 1 */ - 1162, /* OBJ_uacurve2 1 2 804 2 1 1 1 1 3 1 1 2 2 */ - 1163, /* OBJ_uacurve3 1 2 804 2 1 1 1 1 3 1 1 2 3 */ - 1164, /* OBJ_uacurve4 1 2 804 2 1 1 1 1 3 1 1 2 4 */ - 1165, /* OBJ_uacurve5 1 2 804 2 1 1 1 1 3 1 1 2 5 */ - 1166, /* OBJ_uacurve6 1 2 804 2 1 1 1 1 3 1 1 2 6 */ - 1167, /* OBJ_uacurve7 1 2 804 2 1 1 1 1 3 1 1 2 7 */ - 1168, /* OBJ_uacurve8 1 2 804 2 1 1 1 1 3 1 1 2 8 */ - 1169, /* OBJ_uacurve9 1 2 804 2 1 1 1 1 3 1 1 2 9 */ -}; -/* clang-format on */ - -#endif /* !defined(OSSL_LIBCRYPTO_OBJECTS_OBJ_DAT_H) */ diff --git a/crypto/objects/obj_dat.pl b/crypto/objects/obj_dat.pl index 54c42cdbebfe0..0f23a26a73deb 100644 --- a/crypto/objects/obj_dat.pl +++ b/crypto/objects/obj_dat.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -55,6 +55,9 @@ sub der_it my %objd; open(IN, "$ARGV[0]") || die "Can't open input file $ARGV[0], $!"; while () { + # The compatibility aliases appended after the include guard's + # closing #endif carry no object data; read only the guarded body. + last if m@^#endif\s+/\* OPENSSL_OBJ_MAC_H \*/@; next unless /^\#define\s+(\S+)\s+(.*)$/; my $v = $1; my $d = $2; diff --git a/crypto/objects/obj_err.c b/crypto/objects/obj_err.c deleted file mode 100644 index c3c5478034257..0000000000000 --- a/crypto/objects/obj_err.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/objectserr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA OBJ_str_reasons[] = { - { ERR_PACK(ERR_LIB_OBJ, 0, OBJ_R_OID_EXISTS), "oid exists" }, - { ERR_PACK(ERR_LIB_OBJ, 0, OBJ_R_UNKNOWN_NID), "unknown nid" }, - { ERR_PACK(ERR_LIB_OBJ, 0, OBJ_R_UNKNOWN_OBJECT_NAME), - "unknown object name" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_OBJ_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(OBJ_str_reasons[0].error) == NULL) - ERR_load_strings_const(OBJ_str_reasons); -#endif - return 1; -} diff --git a/crypto/objects/obj_local.h b/crypto/objects/obj_local.h index 29e5cc034b91c..e8c83ae5ba6bd 100644 --- a/crypto/objects/obj_local.h +++ b/crypto/objects/obj_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index e72170b47f7d0..0a64723d06044 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -1499,3 +1499,24 @@ HKDF_SHA512 1498 id_smime_ori 1499 id_smime_ori_kem 1500 id_alg_hss_lms_hashsig 1501 +id_rdna_unsigned 1502 +id_alg_unsigned 1503 +id_aes 1504 +ML_DSA_44_RSA2048_PSS_SHA256 1505 +ML_DSA_44_RSA2048_PKCS15_SHA256 1506 +ML_DSA_44_Ed25519_SHA512 1507 +ML_DSA_44_ECDSA_P256_SHA256 1508 +ML_DSA_65_RSA3072_PSS_SHA512 1509 +ML_DSA_65_RSA3072_PKCS15_SHA512 1510 +ML_DSA_65_RSA4096_PSS_SHA512 1511 +ML_DSA_65_RSA4096_PKCS15_SHA512 1512 +ML_DSA_65_ECDSA_P256_SHA512 1513 +ML_DSA_65_ECDSA_P384_SHA512 1514 +ML_DSA_65_ECDSA_brainpoolP256r1_SHA512 1515 +ML_DSA_65_Ed25519_SHA512 1516 +ML_DSA_87_ECDSA_P384_SHA512 1517 +ML_DSA_87_ECDSA_brainpoolP384r1_SHA512 1518 +ML_DSA_87_Ed448_SHAKE256 1519 +ML_DSA_87_RSA3072_PSS_SHA512 1520 +ML_DSA_87_RSA4096_PSS_SHA512 1521 +ML_DSA_87_ECDSA_P521_SHA512 1522 diff --git a/crypto/objects/obj_xref.h b/crypto/objects/obj_xref.h deleted file mode 100644 index 955571e134f53..0000000000000 --- a/crypto/objects/obj_xref.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * WARNING: do not edit! - * Generated by objxref.pl - * - * Copyright 1998-2026 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#if !defined(OSSL_LIBCRYPTO_OBJECTS_OBJ_XREF_H) -#define OSSL_LIBCRYPTO_OBJECTS_OBJ_XREF_H - -/* clang-format off */ - -#include - -typedef struct { - int sign_id; - int hash_id; - int pkey_id; -} nid_triple; - -DEFINE_STACK_OF(nid_triple) - -static const nid_triple sigoid_srt[] = { - {NID_md2WithRSAEncryption, NID_md2, NID_rsaEncryption}, - {NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption}, - {NID_shaWithRSAEncryption, NID_sha, NID_rsaEncryption}, - {NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption}, - {NID_dsaWithSHA, NID_sha, NID_dsa}, - {NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2}, - {NID_mdc2WithRSA, NID_mdc2, NID_rsaEncryption}, - {NID_md5WithRSA, NID_md5, NID_rsa}, - {NID_dsaWithSHA1, NID_sha1, NID_dsa}, - {NID_sha1WithRSA, NID_sha1, NID_rsa}, - {NID_ripemd160WithRSA, NID_ripemd160, NID_rsaEncryption}, - {NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption}, - {NID_ecdsa_with_SHA1, NID_sha1, NID_X9_62_id_ecPublicKey}, - {NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption}, - {NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption}, - {NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption}, - {NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption}, - {NID_ecdsa_with_Recommended, NID_undef, NID_X9_62_id_ecPublicKey}, - {NID_ecdsa_with_Specified, NID_undef, NID_X9_62_id_ecPublicKey}, - {NID_ecdsa_with_SHA224, NID_sha224, NID_X9_62_id_ecPublicKey}, - {NID_ecdsa_with_SHA256, NID_sha256, NID_X9_62_id_ecPublicKey}, - {NID_ecdsa_with_SHA384, NID_sha384, NID_X9_62_id_ecPublicKey}, - {NID_ecdsa_with_SHA512, NID_sha512, NID_X9_62_id_ecPublicKey}, - {NID_dsa_with_SHA224, NID_sha224, NID_dsa}, - {NID_dsa_with_SHA256, NID_sha256, NID_dsa}, - {NID_id_GostR3411_94_with_GostR3410_2001, NID_id_GostR3411_94, - NID_id_GostR3410_2001}, - {NID_id_GostR3411_94_with_GostR3410_94, NID_id_GostR3411_94, - NID_id_GostR3410_94}, - {NID_id_GostR3411_94_with_GostR3410_94_cc, NID_id_GostR3411_94, - NID_id_GostR3410_94_cc}, - {NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94, - NID_id_GostR3410_2001_cc}, - {NID_rsassaPss, NID_undef, NID_rsassaPss}, - {NID_dhSinglePass_stdDH_sha1kdf_scheme, NID_sha1, NID_dh_std_kdf}, - {NID_dhSinglePass_stdDH_sha224kdf_scheme, NID_sha224, NID_dh_std_kdf}, - {NID_dhSinglePass_stdDH_sha256kdf_scheme, NID_sha256, NID_dh_std_kdf}, - {NID_dhSinglePass_stdDH_sha384kdf_scheme, NID_sha384, NID_dh_std_kdf}, - {NID_dhSinglePass_stdDH_sha512kdf_scheme, NID_sha512, NID_dh_std_kdf}, - {NID_dhSinglePass_cofactorDH_sha1kdf_scheme, NID_sha1, - NID_dh_cofactor_kdf}, - {NID_dhSinglePass_cofactorDH_sha224kdf_scheme, NID_sha224, - NID_dh_cofactor_kdf}, - {NID_dhSinglePass_cofactorDH_sha256kdf_scheme, NID_sha256, - NID_dh_cofactor_kdf}, - {NID_dhSinglePass_cofactorDH_sha384kdf_scheme, NID_sha384, - NID_dh_cofactor_kdf}, - {NID_dhSinglePass_cofactorDH_sha512kdf_scheme, NID_sha512, - NID_dh_cofactor_kdf}, - {NID_id_tc26_signwithdigest_gost3410_2012_256, NID_id_GostR3411_2012_256, - NID_id_GostR3410_2012_256}, - {NID_id_tc26_signwithdigest_gost3410_2012_512, NID_id_GostR3411_2012_512, - NID_id_GostR3410_2012_512}, - {NID_ED25519, NID_undef, NID_ED25519}, - {NID_ED448, NID_undef, NID_ED448}, - {NID_ecdsa_with_SHA3_224, NID_sha3_224, NID_X9_62_id_ecPublicKey}, - {NID_ecdsa_with_SHA3_256, NID_sha3_256, NID_X9_62_id_ecPublicKey}, - {NID_ecdsa_with_SHA3_384, NID_sha3_384, NID_X9_62_id_ecPublicKey}, - {NID_ecdsa_with_SHA3_512, NID_sha3_512, NID_X9_62_id_ecPublicKey}, - {NID_RSA_SHA3_224, NID_sha3_224, NID_rsaEncryption}, - {NID_RSA_SHA3_256, NID_sha3_256, NID_rsaEncryption}, - {NID_RSA_SHA3_384, NID_sha3_384, NID_rsaEncryption}, - {NID_RSA_SHA3_512, NID_sha3_512, NID_rsaEncryption}, - {NID_SM2_with_SM3, NID_sm3, NID_sm2}, - {NID_ML_DSA_44, NID_undef, NID_ML_DSA_44}, - {NID_ML_DSA_65, NID_undef, NID_ML_DSA_65}, - {NID_ML_DSA_87, NID_undef, NID_ML_DSA_87}, - {NID_SLH_DSA_SHA2_128s, NID_undef, NID_SLH_DSA_SHA2_128s}, - {NID_SLH_DSA_SHA2_128f, NID_undef, NID_SLH_DSA_SHA2_128f}, - {NID_SLH_DSA_SHA2_192s, NID_undef, NID_SLH_DSA_SHA2_192s}, - {NID_SLH_DSA_SHA2_192f, NID_undef, NID_SLH_DSA_SHA2_192f}, - {NID_SLH_DSA_SHA2_256s, NID_undef, NID_SLH_DSA_SHA2_256s}, - {NID_SLH_DSA_SHA2_256f, NID_undef, NID_SLH_DSA_SHA2_256f}, - {NID_SLH_DSA_SHAKE_128s, NID_undef, NID_SLH_DSA_SHAKE_128s}, - {NID_SLH_DSA_SHAKE_128f, NID_undef, NID_SLH_DSA_SHAKE_128f}, - {NID_SLH_DSA_SHAKE_192s, NID_undef, NID_SLH_DSA_SHAKE_192s}, - {NID_SLH_DSA_SHAKE_192f, NID_undef, NID_SLH_DSA_SHAKE_192f}, - {NID_SLH_DSA_SHAKE_256s, NID_undef, NID_SLH_DSA_SHAKE_256s}, - {NID_SLH_DSA_SHAKE_256f, NID_undef, NID_SLH_DSA_SHAKE_256f}, -}; - -static const nid_triple *const sigoid_srt_xref[] = { - &sigoid_srt[0], - &sigoid_srt[1], - &sigoid_srt[7], - &sigoid_srt[2], - &sigoid_srt[4], - &sigoid_srt[3], - &sigoid_srt[9], - &sigoid_srt[5], - &sigoid_srt[8], - &sigoid_srt[12], - &sigoid_srt[30], - &sigoid_srt[35], - &sigoid_srt[6], - &sigoid_srt[10], - &sigoid_srt[11], - &sigoid_srt[13], - &sigoid_srt[24], - &sigoid_srt[20], - &sigoid_srt[32], - &sigoid_srt[37], - &sigoid_srt[14], - &sigoid_srt[21], - &sigoid_srt[33], - &sigoid_srt[38], - &sigoid_srt[15], - &sigoid_srt[22], - &sigoid_srt[34], - &sigoid_srt[39], - &sigoid_srt[16], - &sigoid_srt[23], - &sigoid_srt[19], - &sigoid_srt[31], - &sigoid_srt[36], - &sigoid_srt[25], - &sigoid_srt[26], - &sigoid_srt[27], - &sigoid_srt[28], - &sigoid_srt[40], - &sigoid_srt[41], - &sigoid_srt[48], - &sigoid_srt[44], - &sigoid_srt[49], - &sigoid_srt[45], - &sigoid_srt[50], - &sigoid_srt[46], - &sigoid_srt[51], - &sigoid_srt[47], - &sigoid_srt[52], -}; -/* clang-format on */ - -#endif /* !defined(OSSL_LIBCRYPTO_OBJECTS_OBJ_XREF_H) */ diff --git a/crypto/objects/obj_xref.txt b/crypto/objects/obj_xref.txt index 71bc12af74541..08efd8813ab83 100644 --- a/crypto/objects/obj_xref.txt +++ b/crypto/objects/obj_xref.txt @@ -11,6 +11,8 @@ sha256WithRSAEncryption sha256 rsaEncryption sha384WithRSAEncryption sha384 rsaEncryption sha512WithRSAEncryption sha512 rsaEncryption sha224WithRSAEncryption sha224 rsaEncryption +sha512_224WithRSAEncryption sha512_224 rsaEncryption +sha512_256WithRSAEncryption sha512_256 rsaEncryption mdc2WithRSA mdc2 rsaEncryption ripemd160WithRSA ripemd160 rsaEncryption RSA_SHA3_224 sha3_224 rsaEncryption @@ -38,6 +40,24 @@ SLH_DSA_SHAKE_192s undef SLH_DSA_SHAKE_192s SLH_DSA_SHAKE_192f undef SLH_DSA_SHAKE_192f SLH_DSA_SHAKE_256s undef SLH_DSA_SHAKE_256s SLH_DSA_SHAKE_256f undef SLH_DSA_SHAKE_256f +ML_DSA_44_RSA2048_PSS_SHA256 undef ML_DSA_44_RSA2048_PSS_SHA256 +ML_DSA_44_RSA2048_PKCS15_SHA256 undef ML_DSA_44_RSA2048_PKCS15_SHA256 +ML_DSA_44_Ed25519_SHA512 undef ML_DSA_44_Ed25519_SHA512 +ML_DSA_44_ECDSA_P256_SHA256 undef ML_DSA_44_ECDSA_P256_SHA256 +ML_DSA_65_RSA3072_PSS_SHA512 undef ML_DSA_65_RSA3072_PSS_SHA512 +ML_DSA_65_RSA3072_PKCS15_SHA512 undef ML_DSA_65_RSA3072_PKCS15_SHA512 +ML_DSA_65_RSA4096_PSS_SHA512 undef ML_DSA_65_RSA4096_PSS_SHA512 +ML_DSA_65_RSA4096_PKCS15_SHA512 undef ML_DSA_65_RSA4096_PKCS15_SHA512 +ML_DSA_65_ECDSA_P256_SHA512 undef ML_DSA_65_ECDSA_P256_SHA512 +ML_DSA_65_ECDSA_P384_SHA512 undef ML_DSA_65_ECDSA_P384_SHA512 +ML_DSA_65_ECDSA_brainpoolP256r1_SHA512 undef ML_DSA_65_ECDSA_brainpoolP256r1_SHA512 +ML_DSA_65_Ed25519_SHA512 undef ML_DSA_65_Ed25519_SHA512 +ML_DSA_87_ECDSA_P384_SHA512 undef ML_DSA_87_ECDSA_P384_SHA512 +ML_DSA_87_ECDSA_brainpoolP384r1_SHA512 undef ML_DSA_87_ECDSA_brainpoolP384r1_SHA512 +ML_DSA_87_Ed448_SHAKE256 undef ML_DSA_87_Ed448_SHAKE256 +ML_DSA_87_RSA3072_PSS_SHA512 undef ML_DSA_87_RSA3072_PSS_SHA512 +ML_DSA_87_RSA4096_PSS_SHA512 undef ML_DSA_87_RSA4096_PSS_SHA512 +ML_DSA_87_ECDSA_P521_SHA512 undef ML_DSA_87_ECDSA_P521_SHA512 # Alternative deprecated OIDs. By using the older "rsa" OID this # type will be recognized by not normally used. @@ -64,6 +84,8 @@ ecdsa_with_SHA3_512 sha3_512 X9_62_id_ecPublicKey dsa_with_SHA224 sha224 dsa dsa_with_SHA256 sha256 dsa +dsa_with_SHA384 sha384 dsa +dsa_with_SHA512 sha512 dsa id_GostR3411_94_with_GostR3410_2001 id_GostR3411_94 id_GostR3410_2001 id_GostR3411_94_with_GostR3410_94 id_GostR3411_94 id_GostR3410_94 diff --git a/crypto/objects/objects.pl b/crypto/objects/objects.pl index bc6941ff16f1f..b38dbd998214e 100644 --- a/crypto/objects/objects.pl +++ b/crypto/objects/objects.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -11,8 +11,8 @@ use lib "$FindBin::Bin/../../util/perl"; use OpenSSL::copyright; -our($opt_n); -getopts('n'); +our($opt_n, $opt_a); +getopts('na:'); # The year the output file is generated. my $YEAR = OpenSSL::copyright::latest(($0, $ARGV[1], $ARGV[0])); @@ -183,6 +183,19 @@ sub expand #endif /* OPENSSL_OBJ_MAC_H */ EOF +# Append the compatibility aliases, skipping their license header the +# same way the old build recipe did with sed -e '1,8d'. +if ( $opt_a ) + { + open (CMP,"$opt_a") || die "Can't open compat file $opt_a"; + my $line = 0; + while () + { + print if ++$line > 8; + } + close CMP; + } + sub process_oid { local($oid)=@_; diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index 946cdf5ec68cd..dc77456d1956a 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -499,6 +499,7 @@ id-pkix 11 : id-qcs id-pkix 14 : id-cp id-pkix 12 : id-cct id-pkix 21 : id-ppl +id-pkix 25 1 : id-rdna-unsigned id-pkix 48 : id-ad # PKIX Modules @@ -640,6 +641,27 @@ id-alg 1 : id-alg-des40 id-alg 2 : id-alg-noSignature id-alg 3 : id-alg-dh-sig-hmac-sha1 id-alg 4 : id-alg-dh-pop +id-alg 36 : id-alg-unsigned + +# Composite signature algorithms (draft-ietf-lamps-pq-composite-sigs) +id-alg 37 : id-mldsa44-rsa2048-pss-sha256 : ML-DSA-44-RSA2048-PSS-SHA256 +id-alg 38 : id-mldsa44-rsa2048-pkcs15-sha256 : ML-DSA-44-RSA2048-PKCS15-SHA256 +id-alg 39 : id-mldsa44-ed25519-sha512 : ML-DSA-44-Ed25519-SHA512 +id-alg 40 : id-mldsa44-ecdsa-p256-sha256 : ML-DSA-44-ECDSA-P256-SHA256 +id-alg 41 : id-mldsa65-rsa3072-pss-sha512 : ML-DSA-65-RSA3072-PSS-SHA512 +id-alg 42 : id-mldsa65-rsa3072-pkcs15-sha512 : ML-DSA-65-RSA3072-PKCS15-SHA512 +id-alg 43 : id-mldsa65-rsa4096-pss-sha512 : ML-DSA-65-RSA4096-PSS-SHA512 +id-alg 44 : id-mldsa65-rsa4096-pkcs15-sha512 : ML-DSA-65-RSA4096-PKCS15-SHA512 +id-alg 45 : id-mldsa65-ecdsa-p256-sha512 : ML-DSA-65-ECDSA-P256-SHA512 +id-alg 46 : id-mldsa65-ecdsa-p384-sha512 : ML-DSA-65-ECDSA-P384-SHA512 +id-alg 47 : id-mldsa65-ecdsa-brainpoolP256r1-sha512 : ML-DSA-65-ECDSA-brainpoolP256r1-SHA512 +id-alg 48 : id-mldsa65-ed25519-sha512 : ML-DSA-65-Ed25519-SHA512 +id-alg 49 : id-mldsa87-ecdsa-p384-sha512 : ML-DSA-87-ECDSA-P384-SHA512 +id-alg 50 : id-mldsa87-ecdsa-brainpoolp384r1-sha512 : ML-DSA-87-ECDSA-brainpoolP384r1-SHA512 +id-alg 51 : id-mldsa87-ed448-shake256 : ML-DSA-87-Ed448-SHAKE256 +id-alg 52 : id-mldsa87-rsa3072-pss-sha512 : ML-DSA-87-RSA3072-PSS-SHA512 +id-alg 53 : id-mldsa87-rsa4096-pss-sha512 : ML-DSA-87-RSA4096-PSS-SHA512 +id-alg 54 : id-mldsa87-ecdsa-p521-sha512 : ML-DSA-87-ECDSA-P521-SHA512 # CMC controls id-cmc 1 : id-cmc-statusInfo @@ -1024,6 +1046,9 @@ id-smime-alg 8 : ZLIB : zlib compression !Alias nistAlgorithms csor 4 !Alias aes nistAlgorithms 1 +# Base AES OID (used by Java keytool for generic AES keys) +nistAlgorithms 1 : id-aes + aes 1 : AES-128-ECB : aes-128-ecb aes 2 : AES-128-CBC : aes-128-cbc !Cname aes-128-ofb128 diff --git a/crypto/objects/objxref.pl b/crypto/objects/objxref.pl index 5eeeac5c1ff9f..9f4ccdfb4a0a0 100644 --- a/crypto/objects/objxref.pl +++ b/crypto/objects/objxref.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1998-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ocsp/ocsp_cl.c b/crypto/ocsp/ocsp_cl.c index 432edba3143e6..3e057caa6127d 100644 --- a/crypto/ocsp/ocsp_cl.c +++ b/crypto/ocsp/ocsp_cl.c @@ -347,7 +347,7 @@ int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, } /* Check nextUpdate is not more than nsec in the past */ if (next_time < t_now - nsec) { - ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_NOT_YET_VALID); + ERR_raise(ERR_LIB_OCSP, OCSP_R_STATUS_EXPIRED); goto err; } /* Also don't allow nextUpdate to precede thisUpdate */ diff --git a/crypto/ocsp/ocsp_err.c b/crypto/ocsp/ocsp_err.c deleted file mode 100644 index aa0ee11af4f0a..0000000000000 --- a/crypto/ocsp/ocsp_err.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/ocsperr.h" - -#ifndef OPENSSL_NO_OCSP - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA OCSP_str_reasons[] = { - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_CERTIFICATE_VERIFY_ERROR), - "certificate verify error" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_DIGEST_ERR), "digest err" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_DIGEST_NAME_ERR), "digest name err" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_DIGEST_SIZE_ERR), "digest size err" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD), - "error in nextupdate field" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_ERROR_IN_THISUPDATE_FIELD), - "error in thisupdate field" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_MISSING_OCSPSIGNING_USAGE), - "missing ocspsigning usage" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE), - "nextupdate before thisupdate" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_NOT_BASIC_RESPONSE), - "not basic response" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_NO_CERTIFICATES_IN_CHAIN), - "no certificates in chain" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_NO_RESPONSE_DATA), "no response data" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_NO_REVOKED_TIME), "no revoked time" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_NO_SIGNER_KEY), "no signer key" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), - "private key does not match certificate" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_REQUEST_NOT_SIGNED), - "request not signed" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA), - "response contains no revocation data" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_ROOT_CA_NOT_TRUSTED), - "root ca not trusted" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_SIGNATURE_FAILURE), "signature failure" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND), - "signer certificate not found" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_STATUS_EXPIRED), "status expired" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_STATUS_NOT_YET_VALID), - "status not yet valid" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_STATUS_TOO_OLD), "status too old" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_UNKNOWN_MESSAGE_DIGEST), - "unknown message digest" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_UNKNOWN_NID), "unknown nid" }, - { ERR_PACK(ERR_LIB_OCSP, 0, OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE), - "unsupported requestorname type" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_OCSP_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(OCSP_str_reasons[0].error) == NULL) - ERR_load_strings_const(OCSP_str_reasons); -#endif - return 1; -} -#else -NON_EMPTY_TRANSLATION_UNIT -#endif diff --git a/crypto/ocsp/ocsp_ext.c b/crypto/ocsp/ocsp_ext.c index e6467aa0ae81e..2d21a94dcaf87 100644 --- a/crypto/ocsp/ocsp_ext.c +++ b/crypto/ocsp/ocsp_ext.c @@ -360,7 +360,7 @@ X509_EXTENSION *OCSP_crlID_new(const char *url, long *n, char *tim) if (url) { if ((cid->crlUrl = ASN1_IA5STRING_new()) == NULL) goto err; - if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) + if (!(ossl_asn1_string_set1_string(cid->crlUrl, url))) goto err; } if (n) { @@ -446,7 +446,7 @@ X509_EXTENSION *OCSP_url_svcloc_new(const X509_NAME *issuer, const char **urls) goto err; if ((ia5 = ASN1_IA5STRING_new()) == NULL) goto err; - if (!ASN1_STRING_set((ASN1_STRING *)ia5, *urls, -1)) + if (!ossl_asn1_string_set1_string((ASN1_STRING *)ia5, *urls)) goto err; /* ad->location is allocated inside ACCESS_DESCRIPTION_new */ ad->location->type = GEN_URI; diff --git a/crypto/ocsp/ocsp_local.h b/crypto/ocsp/ocsp_local.h index 82676ce2d4d25..dc1bb39e66234 100644 --- a/crypto/ocsp/ocsp_local.h +++ b/crypto/ocsp/ocsp_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ocsp/ocsp_prn.c b/crypto/ocsp/ocsp_prn.c index c304777bda21f..2e3d43f0e6302 100644 --- a/crypto/ocsp/ocsp_prn.c +++ b/crypto/ocsp/ocsp_prn.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ocsp/ocsp_srv.c b/crypto/ocsp/ocsp_srv.c index beecad63a244d..9e77dcff74856 100644 --- a/crypto/ocsp/ocsp_srv.c +++ b/crypto/ocsp/ocsp_srv.c @@ -301,7 +301,7 @@ int OCSP_RESPID_match_ex(OCSP_RESPID *respid, X509 *cert, OSSL_LIB_CTX *libctx, if (!X509_pubkey_digest(cert, sha1, md, NULL)) goto err; - ret = (ASN1_STRING_length(respid->value.byKey) == SHA_DIGEST_LENGTH) + ret = (ASN1_STRING_get_length(respid->value.byKey) == SHA_DIGEST_LENGTH) && (memcmp(ASN1_STRING_get0_data(respid->value.byKey), md, SHA_DIGEST_LENGTH) == 0); diff --git a/crypto/ocsp/v3_ocsp.c b/crypto/ocsp/v3_ocsp.c index d31c74ef453f7..95b815776465d 100644 --- a/crypto/ocsp/v3_ocsp.c +++ b/crypto/ocsp/v3_ocsp.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -143,7 +143,7 @@ static void *ocsp_nonce_new(void) static int i2d_ocsp_nonce(const void *a, unsigned char **pp) { const ASN1_OCTET_STRING *os = a; - if (pp) { + if (pp != NULL && os->length > 0) { memcpy(*pp, os->data, os->length); *pp += os->length; } @@ -164,7 +164,8 @@ static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length) if (!ASN1_OCTET_STRING_set(os, *pp, length)) goto err; - *pp += length; + if (length > 0) + *pp += length; if (pos) *pos = os; diff --git a/crypto/packet.c b/crypto/packet.c index b728ad5a07a22..56cde3866e82a 100644 --- a/crypto/packet.c +++ b/crypto/packet.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -365,6 +365,12 @@ int WPACKET_finish(WPACKET *pkt) } int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes) +{ + return WPACKET_start_sub_packet_at_offset_len__(pkt, lenbytes, 0); +} + +int WPACKET_start_sub_packet_at_offset_len__(WPACKET *pkt, size_t lenbytes, + size_t offset) { WPACKET_SUB *sub; unsigned char *lenchars; @@ -382,7 +388,7 @@ int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes) sub->parent = pkt->subs; pkt->subs = sub; - sub->pwritten = pkt->written + lenbytes; + sub->pwritten = pkt->written + lenbytes + offset; sub->lenbytes = lenbytes; if (lenbytes == 0) { @@ -392,7 +398,8 @@ int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes) sub->packet_len = pkt->written; - if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars)) + if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars) + || (offset > 0 && !WPACKET_allocate_bytes(pkt, offset, &lenchars))) return 0; return 1; diff --git a/crypto/param_build.c b/crypto/param_build.c index c268730db271c..30254a5087ea4 100644 --- a/crypto/param_build.c +++ b/crypto/param_build.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/param_build_set.c b/crypto/param_build_set.c index 51a2678350f44..dc9bcc9c8ae4a 100644 --- a/crypto/param_build_set.c +++ b/crypto/param_build_set.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -99,31 +99,3 @@ int ossl_param_build_set_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, return OSSL_PARAM_set_BN(p, bn) > 0; return 1; } - -int ossl_param_build_set_multi_key_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *params, - const char *names[], - STACK_OF(BIGNUM_const) *stk) -{ - int i, sz = sk_BIGNUM_const_num(stk); - OSSL_PARAM *p; - const BIGNUM *bn; - - if (bld != NULL) { - for (i = 0; i < sz && names[i] != NULL; ++i) { - bn = sk_BIGNUM_const_value(stk, i); - if (bn != NULL && !OSSL_PARAM_BLD_push_BN(bld, names[i], bn)) - return 0; - } - return 1; - } - - for (i = 0; i < sz && names[i] != NULL; ++i) { - bn = sk_BIGNUM_const_value(stk, i); - p = OSSL_PARAM_locate(params, names[i]); - if (p != NULL && bn != NULL) { - if (!OSSL_PARAM_set_BN(p, bn)) - return 0; - } - } - return 1; -} diff --git a/crypto/pem/pem_err.c b/crypto/pem/pem_err.c deleted file mode 100644 index d51e584c009c1..0000000000000 --- a/crypto/pem/pem_err.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/pemerr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA PEM_str_reasons[] = { - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_BASE64_DECODE), "bad base64 decode" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_DECRYPT), "bad decrypt" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_END_LINE), "bad end line" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_IV_CHARS), "bad iv chars" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_MAGIC_NUMBER), "bad magic number" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_PASSWORD_READ), "bad password read" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BAD_VERSION_NUMBER), "bad version number" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_BIO_WRITE_FAILURE), "bio write failure" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_CIPHER_IS_NULL), "cipher is null" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_ERROR_CONVERTING_PRIVATE_KEY), - "error converting private key" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_EXPECTING_DSS_KEY_BLOB), - "expecting dss key blob" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_EXPECTING_PRIVATE_KEY_BLOB), - "expecting private key blob" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_EXPECTING_PUBLIC_KEY_BLOB), - "expecting public key blob" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_EXPECTING_RSA_KEY_BLOB), - "expecting rsa key blob" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_HEADER_TOO_LONG), "header too long" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_INCONSISTENT_HEADER), - "inconsistent header" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_KEYBLOB_HEADER_PARSE_ERROR), - "keyblob header parse error" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_KEYBLOB_TOO_SHORT), "keyblob too short" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_MISSING_DEK_IV), "missing dek iv" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_NOT_DEK_INFO), "not dek info" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_NOT_ENCRYPTED), "not encrypted" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_NOT_PROC_TYPE), "not proc type" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_NO_START_LINE), "no start line" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_PROBLEMS_GETTING_PASSWORD), - "problems getting password" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_PVK_DATA_TOO_SHORT), "pvk data too short" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_PVK_TOO_SHORT), "pvk too short" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_READ_KEY), "read key" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_SHORT_HEADER), "short header" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_UNEXPECTED_DEK_IV), "unexpected dek iv" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_UNSUPPORTED_CIPHER), "unsupported cipher" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_UNSUPPORTED_ENCRYPTION), - "unsupported encryption" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_UNSUPPORTED_KEY_COMPONENTS), - "unsupported key components" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE), - "unsupported public key type" }, - { ERR_PACK(ERR_LIB_PEM, 0, PEM_R_UNSUPPORTED_PVK_KEY_TYPE), - "unsupported pvk key type" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_PEM_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(PEM_str_reasons[0].error) == NULL) - ERR_load_strings_const(PEM_str_reasons); -#endif - return 1; -} diff --git a/crypto/pem/pem_info.c b/crypto/pem/pem_info.c index fa189f0c5dadf..281dfd69ed269 100644 --- a/crypto/pem/pem_info.c +++ b/crypto/pem/pem_info.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/pem/pem_lib.c b/crypto/pem/pem_lib.c index 8eff7e950ab21..6c6df85198cd5 100644 --- a/crypto/pem/pem_lib.c +++ b/crypto/pem/pem_lib.c @@ -82,7 +82,7 @@ void PEM_proc_type(char *buf, int type) else str = "BAD-TYPE"; - BIO_snprintf(p, PEM_BUFSIZE - (size_t)(p - buf), "Proc-Type: 4,%s\n", str); + snprintf(p, PEM_BUFSIZE - (size_t)(p - buf), "Proc-Type: 4,%s\n", str); } void PEM_dek_info(char *buf, const char *type, int len, const char *str) @@ -91,13 +91,13 @@ void PEM_dek_info(char *buf, const char *type, int len, const char *str) char *p = buf + strlen(buf); int j = PEM_BUFSIZE - (int)(p - buf), n; - n = BIO_snprintf(p, j, "DEK-Info: %s,", type); - if (n > 0) { + n = snprintf(p, j, "DEK-Info: %s,", type); + if (n > 0 && n < j) { j -= n; p += n; for (i = 0; i < len; i++) { - n = BIO_snprintf(p, j, "%02X", 0xff & str[i]); - if (n <= 0) + n = snprintf(p, j, "%02X", 0xff & str[i]); + if (n <= 0 || n >= j) return; j -= n; p += n; diff --git a/crypto/pem/pem_local.h b/crypto/pem/pem_local.h index 840b6acb7f94c..e74efe590ac08 100644 --- a/crypto/pem/pem_local.h +++ b/crypto/pem/pem_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c index d6eb42c602e72..55744f3d658f2 100644 --- a/crypto/pem/pem_pkey.c +++ b/crypto/pem/pem_pkey.c @@ -360,7 +360,7 @@ int PEM_write_bio_PrivateKey_traditional(BIO *bp, const EVP_PKEY *x, EVP_PKEY_free(copy); return 0; } - BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str); + snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str); ret = PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, pem_str, bp, x, enc, kstr, klen, cb, u); @@ -400,7 +400,7 @@ PEM_write_fnsig(Parameters, EVP_PKEY, BIO, write_bio) if (!x->ameth || !x->ameth->param_encode) return 0; - BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str); + snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str); return PEM_ASN1_write_bio((i2d_of_void *)x->ameth->param_encode, pem_str, out, x, NULL, NULL, 0, 0, NULL); } diff --git a/crypto/pem/pvkfmt.c b/crypto/pem/pvkfmt.c index 31b46183a4043..8b81f66e0e3b7 100644 --- a/crypto/pem/pvkfmt.c +++ b/crypto/pem/pvkfmt.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/perlasm/x86_64-xlate.pl b/crypto/perlasm/x86_64-xlate.pl index cd8d35ea6795a..12dd1b5470dc9 100755 --- a/crypto/perlasm/x86_64-xlate.pl +++ b/crypto/perlasm/x86_64-xlate.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/perlasm/x86gas.pl b/crypto/perlasm/x86gas.pl index 04e0d043b4010..af477080e8376 100644 --- a/crypto/perlasm/x86gas.pl +++ b/crypto/perlasm/x86gas.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/perlasm/x86masm.pl b/crypto/perlasm/x86masm.pl index 98dedec8ded41..d56bc48428afb 100644 --- a/crypto/perlasm/x86masm.pl +++ b/crypto/perlasm/x86masm.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/perlasm/x86nasm.pl b/crypto/perlasm/x86nasm.pl index 0d223a617be6c..c9df05bd1eea0 100644 --- a/crypto/perlasm/x86nasm.pl +++ b/crypto/perlasm/x86nasm.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1999-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/pkcs12/p12_add.c b/crypto/pkcs12/p12_add.c index 1217317783777..1d330e4701ddb 100644 --- a/crypto/pkcs12/p12_add.c +++ b/crypto/pkcs12/p12_add.c @@ -149,8 +149,9 @@ PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, iter, bags, NULL, NULL); } -STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, - int passlen) +STACK_OF(PKCS12_SAFEBAG) *ossl_pkcs12_unpack_p7encdata_ex(PKCS7 *p7, + const char *pass, int passlen, + OSSL_LIB_CTX *libctx, const char *propq) { if (!PKCS7_type_is_encrypted(p7)) return NULL; @@ -164,6 +165,13 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass, passlen, p7->d.encrypted->enc_data->enc_data, 1, + libctx, propq); +} + +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, + int passlen) +{ + return ossl_pkcs12_unpack_p7encdata_ex(p7, pass, passlen, p7->ctx.libctx, p7->ctx.propq); } @@ -180,6 +188,35 @@ PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(const PKCS12_SAFEBAG *bag, return PKCS12_decrypt_skey_ex(bag, pass, passlen, NULL, NULL); } +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_secretbag(const PKCS12_SAFEBAG *bag, + const char *pass, int passlen, + OSSL_LIB_CTX *ctx, const char *propq) +{ + const ASN1_TYPE *bag_obj; + const unsigned char *p; + X509_SIG *p8enc = NULL; + PKCS8_PRIV_KEY_INFO *p8inf = NULL; + + if (PKCS12_SAFEBAG_get_nid(bag) != NID_secretBag) + return NULL; + if (PKCS12_SAFEBAG_get_bag_nid(bag) != NID_pkcs8ShroudedKeyBag) + return NULL; + + bag_obj = PKCS12_SAFEBAG_get0_bag_obj(bag); + if (bag_obj == NULL || bag_obj->type != V_ASN1_OCTET_STRING) + return NULL; + + p = ASN1_STRING_get0_data(bag_obj->value.octet_string); + p8enc = d2i_X509_SIG(NULL, &p, + (unsigned int)ASN1_STRING_get_length(bag_obj->value.octet_string)); + if (p8enc == NULL) + return NULL; + + p8inf = PKCS8_decrypt_ex(p8enc, pass, passlen, ctx, propq); + X509_SIG_free(p8enc); + return p8inf; +} + int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes) { if (ASN1_item_pack(safes, ASN1_ITEM_rptr(PKCS12_AUTHSAFES), @@ -188,10 +225,10 @@ int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes) return 0; } -STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12) +STACK_OF(PKCS7) *ossl_pkcs12_unpack_authsafes_ex(const PKCS12 *p12, + OSSL_LIB_CTX *libctx, const char *propq) { STACK_OF(PKCS7) *p7s; - PKCS7_CTX *p7ctx; PKCS7 *p7; int i; @@ -205,16 +242,15 @@ STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12) return NULL; } - p7ctx = &p12->authsafes->ctx; p7s = ASN1_item_unpack_ex(p12->authsafes->d.data, - ASN1_ITEM_rptr(PKCS12_AUTHSAFES), - ossl_pkcs7_ctx_get0_libctx(p7ctx), - ossl_pkcs7_ctx_get0_propq(p7ctx)); + ASN1_ITEM_rptr(PKCS12_AUTHSAFES), libctx, propq); if (p7s != NULL) { for (i = 0; i < sk_PKCS7_num(p7s); i++) { p7 = sk_PKCS7_value(p7s, i); - if (!ossl_pkcs7_ctx_propagate(p12->authsafes, p7)) + ossl_pkcs7_set0_libctx(p7, libctx); + if (!ossl_pkcs7_set1_propq(p7, propq)) goto err; + ossl_pkcs7_resolve_libctx(p7); } } return p7s; @@ -222,3 +258,11 @@ STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12) sk_PKCS7_pop_free(p7s, PKCS7_free); return NULL; } + +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12) +{ + PKCS7_CTX *p7ctx; + p7ctx = &p12->authsafes->ctx; + + return ossl_pkcs12_unpack_authsafes_ex(p12, ossl_pkcs7_ctx_get0_libctx(p7ctx), ossl_pkcs7_ctx_get0_propq(p7ctx)); +} diff --git a/crypto/pkcs12/p12_crt.c b/crypto/pkcs12/p12_crt.c index 948d46b851626..c0bcc155af012 100644 --- a/crypto/pkcs12/p12_crt.c +++ b/crypto/pkcs12/p12_crt.c @@ -126,7 +126,7 @@ PKCS12 *PKCS12_create_ex2(const char *pass, const char *name, EVP_PKEY *pkey, if (!copy_bag_attr(bag, pkey, NID_LocalKeySet)) goto err; - if (name && !PKCS12_add_friendlyname(bag, name, -1)) + if (name && !PKCS12_add_friendlyname(bag, name, namelen)) goto err; if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) goto err; diff --git a/crypto/pkcs12/p12_decr.c b/crypto/pkcs12/p12_decr.c index 535481cdfe7dd..5b51f69027ca9 100644 --- a/crypto/pkcs12/p12_decr.c +++ b/crypto/pkcs12/p12_decr.c @@ -57,7 +57,8 @@ unsigned char *PKCS12_pbe_crypt_ex(const X509_ALGOR *algor, if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ctx)) & EVP_CIPH_FLAG_CIPHER_WITH_MAC) != 0) { - if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, 0, &mac_len) < 0) { + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_TLS1_AAD, 0, &mac_len) + <= 0) { ERR_raise(ERR_LIB_PKCS12, ERR_R_INTERNAL_ERROR); goto err; } @@ -72,7 +73,7 @@ unsigned char *PKCS12_pbe_crypt_ex(const X509_ALGOR *algor, inlen -= mac_len; if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, (int)mac_len, (unsigned char *)in + inlen) - < 0) { + <= 0) { ERR_raise(ERR_LIB_PKCS12, ERR_R_INTERNAL_ERROR); goto err; } diff --git a/crypto/pkcs12/p12_kiss.c b/crypto/pkcs12/p12_kiss.c index 1c2e49a57fa25..5b7ee063c2ff3 100644 --- a/crypto/pkcs12/p12_kiss.c +++ b/crypto/pkcs12/p12_kiss.c @@ -10,46 +10,93 @@ #include #include "internal/cryptlib.h" #include +#include +#include "crypto/pkcs7/pk7_local.h" +#include "p12_local.h" #include "crypto/x509.h" /* for ossl_x509_add_cert_new() */ /* Simplified PKCS#12 routines */ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, - EVP_PKEY **pkey, STACK_OF(X509) *ocerts); + PKCS12_PARSE_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq); static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, - int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts, + int passlen, PKCS12_PARSE_CTX *ctx, OSSL_LIB_CTX *libctx, const char *propq); static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, - EVP_PKEY **pkey, STACK_OF(X509) *ocerts, + PKCS12_PARSE_CTX *ctx, OSSL_LIB_CTX *libctx, const char *propq); +PKCS12_PARSE_CTX *PKCS12_PARSE_CTX_new(void) +{ + return OPENSSL_zalloc(sizeof(PKCS12_PARSE_CTX)); +} + +void PKCS12_PARSE_CTX_free(PKCS12_PARSE_CTX *ctx) +{ + OPENSSL_free(ctx); +} + +void PKCS12_PARSE_CTX_set_pkey(PKCS12_PARSE_CTX *ctx, EVP_PKEY **pkey) +{ + ctx->pkey = pkey; +} + +void PKCS12_PARSE_CTX_set_cert(PKCS12_PARSE_CTX *ctx, X509 **cert) +{ + ctx->cert = cert; +} + +void PKCS12_PARSE_CTX_set_ca(PKCS12_PARSE_CTX *ctx, STACK_OF(X509) **ca) +{ + ctx->ca = ca; +} + +void PKCS12_PARSE_CTX_set_skeys(PKCS12_PARSE_CTX *ctx, STACK_OF(EVP_SKEY) **skeys) +{ + ctx->skeys = skeys; +} + /* - * Parse and decrypt a PKCS#12 structure returning user key, user cert and - * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it - * should point to a valid STACK structure. pkey and/or cert may be NULL; - * if non-NULL the variables they point to can be passed uninitialised. + * Parse and decrypt a PKCS#12 structure returning user key, user cert, + * other (CA) certs, and/or symmetric secret keys according to ctx settings. */ -int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, - STACK_OF(X509) **ca) +int PKCS12_parse_ex(PKCS12 *p12, const char *pass, + PKCS12_PARSE_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq) { - STACK_OF(X509) *ocerts = NULL; X509 *x = NULL; - - if (pkey != NULL) - *pkey = NULL; - if (cert != NULL) - *cert = NULL; - - /* Check for NULL PKCS12 structure */ + STACK_OF(X509) *initial_ca = NULL; + STACK_OF(EVP_SKEY) *initial_skeys = NULL; + int initial_ca_count = 0; + int initial_skeys_count = 0; + int ca_added_count = 0; + int skeys_added_count = 0; if (p12 == NULL) { ERR_raise(ERR_LIB_PKCS12, PKCS12_R_INVALID_NULL_PKCS12_POINTER); return 0; } + if (ctx == NULL) { + ERR_raise(ERR_LIB_PKCS12, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + initial_ca = ctx->ca != NULL ? *ctx->ca : NULL; + initial_ca_count = initial_ca == NULL ? 0 : sk_X509_num(initial_ca); + initial_skeys = ctx->skeys != NULL ? *ctx->skeys : NULL; + initial_skeys_count = initial_skeys == NULL ? 0 : sk_EVP_SKEY_num(initial_skeys); + + if (ctx->pkey != NULL) + *ctx->pkey = NULL; + if (ctx->cert != NULL) + *ctx->cert = NULL; + ctx->ocerts = NULL; + /* Check the mac */ if (PKCS12_mac_present(p12)) { /* @@ -59,15 +106,15 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, * password are two different things... */ if (pass == NULL || *pass == '\0') { - if (PKCS12_verify_mac(p12, NULL, 0)) + if (ossl_pkcs12_verify_mac(p12, NULL, 0, libctx, propq)) pass = NULL; - else if (PKCS12_verify_mac(p12, "", 0)) + else if (ossl_pkcs12_verify_mac(p12, "", 0, libctx, propq)) pass = ""; else { ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE); goto err; } - } else if (!PKCS12_verify_mac(p12, pass, -1)) { + } else if (!ossl_pkcs12_verify_mac(p12, pass, -1, libctx, propq)) { ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_VERIFY_FAILURE); goto err; } @@ -76,13 +123,13 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, } /* If needed, allocate stack for other certificates */ - if ((cert != NULL || ca != NULL) - && (ocerts = sk_X509_new_null()) == NULL) { + if ((ctx->cert != NULL || ctx->ca != NULL) + && (ctx->ocerts = sk_X509_new_null()) == NULL) { ERR_raise(ERR_LIB_PKCS12, ERR_R_CRYPTO_LIB); goto err; } - if (!parse_pk12(p12, pass, -1, pkey, ocerts)) { + if (!parse_pk12(p12, pass, -1, ctx, libctx, propq)) { int err = ERR_peek_last_error(); if (ERR_GET_LIB(err) != ERR_LIB_EVP @@ -92,58 +139,112 @@ int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, } /* Split the certs in ocerts over *cert and *ca as far as requested */ - while ((x = sk_X509_shift(ocerts)) != NULL) { - if (pkey != NULL && *pkey != NULL - && cert != NULL && *cert == NULL) { + while ((x = sk_X509_shift(ctx->ocerts)) != NULL) { + if (ctx->pkey != NULL && *ctx->pkey != NULL + && ctx->cert != NULL && *ctx->cert == NULL) { int match; ERR_set_mark(); - match = X509_check_private_key(x, *pkey); + match = X509_check_private_key(x, *ctx->pkey); ERR_pop_to_mark(); if (match) { - *cert = x; + *ctx->cert = x; continue; } } - if (ca != NULL) { - if (!ossl_x509_add_cert_new(ca, x, X509_ADD_FLAG_DEFAULT)) + if (ctx->ca != NULL) { + if (!ossl_x509_add_cert_new(ctx->ca, x, X509_ADD_FLAG_DEFAULT)) goto err; continue; } X509_free(x); } - sk_X509_free(ocerts); + sk_X509_free(ctx->ocerts); + ctx->ocerts = NULL; return 1; err: + if (ctx->pkey != NULL) { + EVP_PKEY_free(*ctx->pkey); + *ctx->pkey = NULL; + } + if (ctx->cert != NULL) { + X509_free(*ctx->cert); + *ctx->cert = NULL; + } + skeys_added_count = ctx->skeys == NULL || *ctx->skeys == NULL ? 0 : sk_EVP_SKEY_num(*ctx->skeys) - initial_skeys_count; + while (skeys_added_count > 0) { + EVP_SKEY *t_skey = sk_EVP_SKEY_pop(*ctx->skeys); + EVP_SKEY_free(t_skey); + skeys_added_count--; + } - if (pkey != NULL) { - EVP_PKEY_free(*pkey); - *pkey = NULL; + if (initial_skeys == NULL && ctx->skeys != NULL) { + sk_EVP_SKEY_free(*ctx->skeys); + *ctx->skeys = NULL; } - if (cert != NULL) { - X509_free(*cert); - *cert = NULL; + + ca_added_count = ctx->ca == NULL || *ctx->ca == NULL ? 0 : sk_X509_num(*ctx->ca) - initial_ca_count; + while (ca_added_count > 0) { + X509 *t_cert = sk_X509_pop(*ctx->ca); + X509_free(t_cert); + ca_added_count--; + } + + if (initial_ca == NULL && ctx->ca != NULL) { + sk_X509_free(*ctx->ca); + *ctx->ca = NULL; } + X509_free(x); - OSSL_STACK_OF_X509_free(ocerts); + OSSL_STACK_OF_X509_free(ctx->ocerts); + ctx->ocerts = NULL; return 0; } +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, + STACK_OF(X509) **ca) +{ + PKCS12_PARSE_CTX *ctx; + int ret; + + if (pkey != NULL) + *pkey = NULL; + if (cert != NULL) + *cert = NULL; + + if (p12 == NULL) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_INVALID_NULL_PKCS12_POINTER); + return 0; + } + + ctx = PKCS12_PARSE_CTX_new(); + if (ctx == NULL) + return 0; + + PKCS12_PARSE_CTX_set_pkey(ctx, pkey); + PKCS12_PARSE_CTX_set_cert(ctx, cert); + PKCS12_PARSE_CTX_set_ca(ctx, ca); + + ret = PKCS12_parse_ex(p12, pass, ctx, p12->authsafes->ctx.libctx, p12->authsafes->ctx.propq); + PKCS12_PARSE_CTX_free(ctx); + return ret; +} + /* Parse the outer PKCS#12 structure */ -/* pkey and/or ocerts may be NULL */ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, - EVP_PKEY **pkey, STACK_OF(X509) *ocerts) + PKCS12_PARSE_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq) { STACK_OF(PKCS7) *asafes; STACK_OF(PKCS12_SAFEBAG) *bags; int i, bagnid; PKCS7 *p7; - if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL) + if ((asafes = ossl_pkcs12_unpack_authsafes_ex(p12, libctx, propq)) == NULL) return 0; for (i = 0; i < sk_PKCS7_num(asafes); i++) { p7 = sk_PKCS7_value(asafes, i); @@ -151,15 +252,15 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, if (bagnid == NID_pkcs7_data) { bags = PKCS12_unpack_p7data(p7); } else if (bagnid == NID_pkcs7_encrypted) { - bags = PKCS12_unpack_p7encdata(p7, pass, passlen); + bags = ossl_pkcs12_unpack_p7encdata_ex(p7, pass, passlen, + libctx, propq); } else continue; if (!bags) { sk_PKCS7_pop_free(asafes, PKCS7_free); return 0; } - if (!parse_bags(bags, pass, passlen, pkey, ocerts, - p7->ctx.libctx, p7->ctx.propq)) { + if (!parse_bags(bags, pass, passlen, ctx, libctx, propq)) { sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); sk_PKCS7_pop_free(asafes, PKCS7_free); return 0; @@ -170,24 +271,22 @@ static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, return 1; } -/* pkey and/or ocerts may be NULL */ static int parse_bags(const STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, - int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts, + int passlen, PKCS12_PARSE_CTX *ctx, OSSL_LIB_CTX *libctx, const char *propq) { int i; for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i), - pass, passlen, pkey, ocerts, + pass, passlen, ctx, libctx, propq)) return 0; } return 1; } -/* pkey and/or ocerts may be NULL */ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, - EVP_PKEY **pkey, STACK_OF(X509) *ocerts, + PKCS12_PARSE_CTX *ctx, OSSL_LIB_CTX *libctx, const char *propq) { PKCS8_PRIV_KEY_INFO *p8; @@ -210,29 +309,29 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, switch (PKCS12_SAFEBAG_get_nid(bag)) { case NID_keyBag: - if (pkey == NULL || *pkey != NULL) + if (ctx->pkey == NULL || *ctx->pkey != NULL) return 1; - *pkey = EVP_PKCS82PKEY_ex(PKCS12_SAFEBAG_get0_p8inf(bag), + *ctx->pkey = EVP_PKCS82PKEY_ex(PKCS12_SAFEBAG_get0_p8inf(bag), libctx, propq); - if (*pkey == NULL) + if (*ctx->pkey == NULL) return 0; break; case NID_pkcs8ShroudedKeyBag: - if (pkey == NULL || *pkey != NULL) + if (ctx->pkey == NULL || *ctx->pkey != NULL) return 1; if ((p8 = PKCS12_decrypt_skey_ex(bag, pass, passlen, libctx, propq)) == NULL) return 0; - *pkey = EVP_PKCS82PKEY_ex(p8, libctx, propq); + *ctx->pkey = EVP_PKCS82PKEY_ex(p8, libctx, propq); PKCS8_PRIV_KEY_INFO_free(p8); - if (!(*pkey)) + if (!(*ctx->pkey)) return 0; break; case NID_certBag: - if (ocerts == NULL + if (ctx->ocerts == NULL || PKCS12_SAFEBAG_get_bag_nid(bag) != NID_x509Certificate) return 1; if ((x509 = PKCS12_SAFEBAG_get1_cert_ex(bag, libctx, propq)) == NULL) @@ -256,16 +355,66 @@ static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, } } - if (!sk_X509_push(ocerts, x509)) { + if (!sk_X509_push(ctx->ocerts, x509)) { X509_free(x509); return 0; } break; + case NID_secretBag: + if (ctx->skeys == NULL) + return 1; + if (PKCS12_SAFEBAG_get_bag_nid(bag) != NID_pkcs8ShroudedKeyBag) + return 1; + { + EVP_SKEY *skey; + OSSL_PARAM extra[3]; + int nparams = 0; + unsigned char *fname_utf8 = NULL; + int fname_utf8_len = 0; + PKCS8_PRIV_KEY_INFO *p8sb = PKCS12_decrypt_secretbag(bag, pass, + passlen, libctx, propq); + + if (p8sb == NULL) + return 0; + + if (fname) { + fname_utf8_len = ASN1_STRING_to_UTF8(&fname_utf8, fname); + if (fname_utf8_len >= 0) + extra[nparams++] = OSSL_PARAM_construct_utf8_string( + OSSL_SKEY_PARAM_ALIAS, + (char *)fname_utf8, (size_t)fname_utf8_len); + } + if (lkid) + extra[nparams++] = OSSL_PARAM_construct_octet_string( + OSSL_SKEY_PARAM_LOCAL_KEYID, + lkid->data, (size_t)lkid->length); + extra[nparams] = OSSL_PARAM_construct_end(); + + skey = PKCS8_PRIV_KEY_INFO_get1_skey(p8sb, libctx, propq, + extra, 1); + PKCS8_PRIV_KEY_INFO_free(p8sb); + OPENSSL_free(fname_utf8); + if (skey == NULL) { + ERR_raise(ERR_LIB_PKCS12, PKCS12_R_PARSE_ERROR); + return 0; + } + if (*ctx->skeys == NULL + && (*ctx->skeys = sk_EVP_SKEY_new_null()) == NULL) { + EVP_SKEY_free(skey); + return 0; + } + if (!sk_EVP_SKEY_push(*ctx->skeys, skey)) { + EVP_SKEY_free(skey); + return 0; + } + } + return 1; + case NID_safeContentsBag: - return parse_bags(PKCS12_SAFEBAG_get0_safes(bag), pass, passlen, pkey, - ocerts, libctx, propq); + return parse_bags(PKCS12_SAFEBAG_get0_safes(bag), pass, passlen, ctx, + libctx, propq); default: return 1; diff --git a/crypto/pkcs12/p12_local.h b/crypto/pkcs12/p12_local.h index ef5866ad9bdd3..147454bc7ad28 100644 --- a/crypto/pkcs12/p12_local.h +++ b/crypto/pkcs12/p12_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -49,6 +49,22 @@ struct pkcs12_bag_st { } value; }; +struct pkcs12_parse_ctx_st { + EVP_PKEY **pkey; + X509 **cert; + STACK_OF(X509) **ca; + STACK_OF(EVP_SKEY) **skeys; + /* internal: temporary cert collection used during parsing */ + STACK_OF(X509) *ocerts; +}; + const PKCS7_CTX *ossl_pkcs12_get0_pkcs7ctx(const PKCS12 *p12); +int ossl_pkcs12_verify_mac(PKCS12 *p12, const char *pass, int passlen, + OSSL_LIB_CTX *libctx, const char *propq); +STACK_OF(PKCS7) *ossl_pkcs12_unpack_authsafes_ex(const PKCS12 *p12, + OSSL_LIB_CTX *libctx, const char *propq); +STACK_OF(PKCS12_SAFEBAG) *ossl_pkcs12_unpack_p7encdata_ex(PKCS7 *p7, + const char *pass, int passlen, + OSSL_LIB_CTX *libctx, const char *propq); #endif /* !defined(OSSL_LIBCRYPTO_PKCS12_P12_LOCAL_H) */ diff --git a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c index 2888efd6893e7..f434b15f63da4 100644 --- a/crypto/pkcs12/p12_mutl.c +++ b/crypto/pkcs12/p12_mutl.c @@ -182,7 +182,8 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, unsigned char *out, const EVP_MD *md_type, OSSL_LIB_CTX *libctx, - const char *propq)) + const char *propq), + OSSL_LIB_CTX *libctx, const char *propq) { int ret = 0; EVP_MD *md; @@ -193,8 +194,6 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, int md_nid = NID_undef; const X509_ALGOR *macalg; const ASN1_OBJECT *macoid; - OSSL_LIB_CTX *libctx; - const char *propq; size_t md_sz, outlen; if (!PKCS7_type_is_data(p12->authsafes)) { @@ -207,8 +206,6 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, return 0; } - libctx = p12->authsafes->ctx.libctx; - propq = p12->authsafes->ctx.propq; salt = p12->mac->salt->data; saltlen = p12->mac->salt->length; if (p12->mac->iter == NULL) @@ -305,11 +302,11 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen, int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, unsigned char *mac, unsigned int *maclen) { - return pkcs12_gen_mac(p12, pass, passlen, mac, maclen, NID_undef, NID_undef, NULL); + return pkcs12_gen_mac(p12, pass, passlen, mac, maclen, NID_undef, NID_undef, NULL, p12->authsafes->ctx.libctx, p12->authsafes->ctx.propq); } -/* Verify the mac */ -int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen) +int ossl_pkcs12_verify_mac(PKCS12 *p12, const char *pass, int passlen, + OSSL_LIB_CTX *libctx, const char *propq) { unsigned char mac[EVP_MAX_MD_SIZE]; unsigned int maclen; @@ -337,26 +334,32 @@ int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen) X509_ALGOR_get0(&hmac_oid, NULL, NULL, param->messageAuthScheme); md_nid = ossl_hmac2mdnid(OBJ_obj2nid(hmac_oid)); - if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, md_nid, NID_undef, NULL)) { + if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, md_nid, NID_undef, NULL, libctx, propq)) { ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR); PBMAC1PARAM_free(param); return 0; } PBMAC1PARAM_free(param); } else { - if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NID_undef, NID_undef, NULL)) { + if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NID_undef, NID_undef, NULL, libctx, propq)) { ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR); return 0; } } X509_SIG_get0(p12->mac->dinfo, NULL, &macoct); - if ((maclen != (unsigned int)ASN1_STRING_length(macoct)) + if ((maclen != ASN1_STRING_get_length(macoct)) || CRYPTO_memcmp(mac, ASN1_STRING_get0_data(macoct), maclen) != 0) return 0; return 1; } +/* Verify the mac */ +int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen) +{ + return ossl_pkcs12_verify_mac(p12, pass, passlen, p12->authsafes->ctx.libctx, p12->authsafes->ctx.propq); +} + /* Set a mac */ int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, unsigned char *salt, int saltlen, int iter, @@ -378,7 +381,7 @@ int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, /* * Note that output mac is forced to UTF-8... */ - if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NID_undef, NID_undef, NULL)) { + if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, NID_undef, NID_undef, NULL, p12->authsafes->ctx.libctx, p12->authsafes->ctx.propq)) { ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR); return 0; } @@ -542,7 +545,7 @@ int PKCS12_set_pbmac1_pbkdf2(PKCS12 *p12, const char *pass, int passlen, */ if (!pkcs12_gen_mac(p12, pass, passlen, mac, &maclen, EVP_MD_get_type(md_type), prf_md_nid, - pkcs12_pbmac1_pbkdf2_key_gen)) { + pkcs12_pbmac1_pbkdf2_key_gen, p12->authsafes->ctx.libctx, p12->authsafes->ctx.propq)) { ERR_raise(ERR_LIB_PKCS12, PKCS12_R_MAC_GENERATION_ERROR); goto err; } diff --git a/crypto/pkcs12/p12_npas.c b/crypto/pkcs12/p12_npas.c index 44763e8668009..6b25bf95bd751 100644 --- a/crypto/pkcs12/p12_npas.c +++ b/crypto/pkcs12/p12_npas.c @@ -99,7 +99,9 @@ static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass) if (bagnid == NID_pkcs7_data) p7new = PKCS12_pack_p7data(bags); else - p7new = PKCS12_pack_p7encdata_ex(pbe_nid, newpass, -1, NULL, + p7new = PKCS12_pack_p7encdata_ex( + cipherid != NID_undef ? cipherid : pbe_nid, + newpass, -1, NULL, pbe_saltlen, pbe_iter, bags, p7->ctx.libctx, p7->ctx.propq); if (p7new == NULL || !sk_PKCS7_push(newsafes, p7new)) { diff --git a/crypto/pkcs12/p12_sbag.c b/crypto/pkcs12/p12_sbag.c index 2bb7c6fa8bac7..860553162f391 100644 --- a/crypto/pkcs12/p12_sbag.c +++ b/crypto/pkcs12/p12_sbag.c @@ -10,6 +10,9 @@ #include #include "internal/cryptlib.h" #include +#include +#include +#include #include "p12_local.h" #include "crypto/x509.h" @@ -147,6 +150,133 @@ X509_CRL *PKCS12_SAFEBAG_get1_crl_ex(const PKCS12_SAFEBAG *bag, return ret; } +EVP_SKEY *PKCS8_PRIV_KEY_INFO_get1_skey(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq, + const OSSL_PARAM *extra_params, int strict) +{ + const ASN1_OBJECT *algoid = NULL; + const X509_ALGOR *algor = NULL; + const unsigned char *raw_key = NULL; + int raw_key_len = 0; + const char *skey_type = OSSL_SKEY_TYPE_GENERIC; + unsigned char *oid_der = NULL; + int oid_der_len = 0; + unsigned char *params_der = NULL; + int params_der_len = 0; + OSSL_PARAM_BLD *bld = NULL; + OSSL_PARAM *params = NULL; + EVP_SKEY *skey = NULL; + + if (p8inf == NULL) + return NULL; + + if (!PKCS8_pkey_get0(&algoid, &raw_key, &raw_key_len, &algor, p8inf) + || raw_key == NULL || raw_key_len <= 0) + return NULL; + + if (algoid != NULL) { + int nid = OBJ_obj2nid(algoid); + + switch (nid) { + case NID_id_aes: + if (raw_key_len != 16 && raw_key_len != 24 && raw_key_len != 32) + return NULL; + skey_type = OSSL_SKEY_TYPE_AES; + break; + case NID_aes_128_cbc: + case NID_aes_128_ccm: + case NID_aes_128_ecb: + case NID_aes_128_gcm: + if (raw_key_len != 16) + return NULL; + skey_type = OSSL_SKEY_TYPE_AES; + break; + case NID_aes_192_cbc: + case NID_aes_192_ccm: + case NID_aes_192_ecb: + case NID_aes_192_gcm: + if (raw_key_len != 24) + return NULL; + skey_type = OSSL_SKEY_TYPE_AES; + break; + case NID_aes_256_cbc: + case NID_aes_256_ccm: + case NID_aes_256_ecb: + case NID_aes_256_gcm: + if (raw_key_len != 32) + return NULL; + skey_type = OSSL_SKEY_TYPE_AES; + break; + default: + if (strict != 0) + return NULL; + break; + } + } + + bld = OSSL_PARAM_BLD_new(); + if (bld == NULL) + return NULL; + + if (!OSSL_PARAM_BLD_push_octet_string(bld, OSSL_SKEY_PARAM_RAW_BYTES, + raw_key, (size_t)raw_key_len)) + goto err; + + if (algoid != NULL) { + oid_der_len = i2d_ASN1_OBJECT(algoid, &oid_der); + if (oid_der_len > 0 + && !OSSL_PARAM_BLD_push_octet_string(bld, + OSSL_SKEY_PARAM_ALGORITHM_OID, + oid_der, (size_t)oid_der_len)) + goto err; + } + + if (algor != NULL && algor->parameter != NULL + && algor->parameter->type != V_ASN1_UNDEF) { + params_der_len = i2d_ASN1_TYPE(algor->parameter, ¶ms_der); + if (params_der_len > 0 + && !OSSL_PARAM_BLD_push_octet_string(bld, + OSSL_SKEY_PARAM_ALGORITHM_PARAMS, + params_der, (size_t)params_der_len)) + goto err; + } + + if (extra_params != NULL) { + const OSSL_PARAM *p; + + for (p = extra_params; p->key != NULL; p++) { + switch (p->data_type) { + case OSSL_PARAM_UTF8_STRING: + if (!OSSL_PARAM_BLD_push_utf8_string(bld, + p->key, p->data, p->data_size)) + goto err; + break; + case OSSL_PARAM_OCTET_STRING: + if (!OSSL_PARAM_BLD_push_octet_string(bld, + p->key, p->data, p->data_size)) + goto err; + break; + default: + break; + } + } + } + + params = OSSL_PARAM_BLD_to_param(bld); + if (params == NULL) + goto err; + + skey = EVP_SKEY_import(libctx, skey_type, propq, + OSSL_SKEYMGMT_SELECT_ALL, params); + +err: + OSSL_PARAM_BLD_free(bld); + OSSL_PARAM_clear_free(params); + OPENSSL_free(oid_der); + OPENSSL_free(params_der); + return skey; +} + PKCS12_SAFEBAG *PKCS12_SAFEBAG_create_cert(X509 *x509) { return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509), diff --git a/crypto/pkcs12/p12_utl.c b/crypto/pkcs12/p12_utl.c index 3c19f727a1b9c..dd8e969767738 100644 --- a/crypto/pkcs12/p12_utl.c +++ b/crypto/pkcs12/p12_utl.c @@ -57,11 +57,15 @@ char *OPENSSL_uni2asc(const unsigned char *uni, int unilen) /* If no terminating zero allow for one */ if (!unilen || uni[unilen - 1]) asclen++; - uni++; if ((asctmp = OPENSSL_malloc(asclen)) == NULL) return NULL; + /* + * Take the low byte of each big-endian UTF-16 unit. Index from the + * caller's pointer rather than incrementing it first, so that a zero + * length input does not do pointer arithmetic on a NULL pointer. + */ for (i = 0; i < unilen; i += 2) - asctmp[i >> 1] = uni[i]; + asctmp[i >> 1] = uni[i + 1]; asctmp[asclen - 1] = 0; return asctmp; } diff --git a/crypto/pkcs12/pk12err.c b/crypto/pkcs12/pk12err.c deleted file mode 100644 index 5556f2eceeefa..0000000000000 --- a/crypto/pkcs12/pk12err.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/pkcs12err.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA PKCS12_str_reasons[] = { - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_CALLBACK_FAILED), "callback failed" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_CANT_PACK_STRUCTURE), - "can't pack structure" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_CONTENT_TYPE_NOT_DATA), - "content type not data" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_DECODE_ERROR), "decode error" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_ENCODE_ERROR), "encode error" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_ENCRYPT_ERROR), "encrypt error" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE), - "error setting encrypted data type" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_INVALID_NULL_ARGUMENT), - "invalid null argument" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_INVALID_NULL_PKCS12_POINTER), - "invalid null pkcs12 pointer" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_INVALID_SALT_LENGTH), - "invalid salt length" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_INVALID_TYPE), "invalid type" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_IV_GEN_ERROR), "iv gen error" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_KEY_GEN_ERROR), "key gen error" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_MAC_ABSENT), "mac absent" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_MAC_GENERATION_ERROR), - "mac generation error" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_MAC_SETUP_ERROR), "mac setup error" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_MAC_STRING_SET_ERROR), - "mac string set error" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_MAC_VERIFY_FAILURE), - "mac verify failure" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_PARSE_ERROR), "parse error" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_PKCS12_CIPHERFINAL_ERROR), - "pkcs12 cipherfinal error" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM), - "unknown digest algorithm" }, - { ERR_PACK(ERR_LIB_PKCS12, 0, PKCS12_R_UNSUPPORTED_PKCS12_MODE), - "unsupported pkcs12 mode" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_PKCS12_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(PKCS12_str_reasons[0].error) == NULL) - ERR_load_strings_const(PKCS12_str_reasons); -#endif - return 1; -} diff --git a/crypto/pkcs7/pk7_asn1.c b/crypto/pkcs7/pk7_asn1.c index 733f3bb69dcad..00eabd981589e 100644 --- a/crypto/pkcs7/pk7_asn1.c +++ b/crypto/pkcs7/pk7_asn1.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -39,7 +39,7 @@ static int pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, switch (operation) { case ASN1_OP_STREAM_PRE: - if (PKCS7_stream(&sarg->boundary, *pp7) <= 0) + if (ossl_pkcs7_stream(*pp7) <= 0) return 0; /* fall through */ case ASN1_OP_DETACHED_PRE: @@ -53,6 +53,12 @@ static int pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0) return 0; break; + + case ASN1_OP_GET0_STREAM_CONTENT: { + ASN1_STRING **content = exarg; + + *content = ossl_pkcs7_get0_stream_content(*pp7); + } break; } return 1; } @@ -73,7 +79,7 @@ PKCS7 *d2i_PKCS7(PKCS7 **a, const unsigned char **in, long len) propq = (*a)->ctx.propq; } - ret = (PKCS7 *)ASN1_item_d2i_ex((ASN1_VALUE **)a, in, len, (PKCS7_it()), + ret = (PKCS7 *)ASN1_item_d2i_ex((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(PKCS7), libctx, propq); if (ret != NULL) ossl_pkcs7_resolve_libctx(ret); @@ -82,7 +88,7 @@ PKCS7 *d2i_PKCS7(PKCS7 **a, const unsigned char **in, long len) int i2d_PKCS7(const PKCS7 *a, unsigned char **out) { - return ASN1_item_i2d((const ASN1_VALUE *)a, out, (PKCS7_it())); + return ASN1_item_i2d((const ASN1_VALUE *)a, out, ASN1_ITEM_rptr(PKCS7)); } PKCS7 *PKCS7_new(void) diff --git a/crypto/pkcs7/pk7_attr.c b/crypto/pkcs7/pk7_attr.c index b865d9735656d..ac7a4cb4af758 100644 --- a/crypto/pkcs7/pk7_attr.c +++ b/crypto/pkcs7/pk7_attr.c @@ -30,7 +30,7 @@ int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, } seq->length = ASN1_item_i2d((ASN1_VALUE *)cap, &seq->data, ASN1_ITEM_rptr(X509_ALGORS)); - if (ASN1_STRING_length(seq) <= 0 || ASN1_STRING_get0_data(seq) == NULL) { + if (ASN1_STRING_get_length(seq) == 0 || ASN1_STRING_get0_data(seq) == NULL) { ASN1_STRING_free(seq); return 1; } @@ -46,14 +46,17 @@ STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si) { const ASN1_TYPE *cap; const unsigned char *p; + size_t len; cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities); if (cap == NULL || (cap->type != V_ASN1_SEQUENCE)) return NULL; p = ASN1_STRING_get0_data(cap->value.sequence); + len = ASN1_STRING_get_length(cap->value.sequence); + if (len > INT_MAX) + return NULL; return (STACK_OF(X509_ALGOR) *) - ASN1_item_d2i(NULL, &p, ASN1_STRING_length(cap->value.sequence), - ASN1_ITEM_rptr(X509_ALGORS)); + ASN1_item_d2i(NULL, &p, (int)len, ASN1_ITEM_rptr(X509_ALGORS)); } /* Basic smime-capabilities OID and optional integer arg */ @@ -129,7 +132,7 @@ int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, os = ASN1_OCTET_STRING_new(); if (os == NULL) return 0; - if (!ASN1_STRING_set(os, md, mdlen) + if (!ossl_asn1_string_set1_data(os, md, mdlen) || !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest, V_ASN1_OCTET_STRING, os)) { ASN1_OCTET_STRING_free(os); diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c index 1878b4aac2475..3799dec1dab9c 100644 --- a/crypto/pkcs7/pk7_doit.c +++ b/crypto/pkcs7/pk7_doit.c @@ -56,7 +56,7 @@ ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) return NULL; } -static ASN1_OCTET_STRING *pkcs7_get1_data(PKCS7 *p7) +static ASN1_OCTET_STRING *pkcs7_get1_data(PKCS7 *p7, int streaming) { ASN1_OCTET_STRING *os = PKCS7_get_octet_string(p7); @@ -64,8 +64,7 @@ static ASN1_OCTET_STRING *pkcs7_get1_data(PKCS7 *p7) /* Edge case for MIME content, see RFC 5652 section-5.2.1 */ ASN1_OCTET_STRING *osdup = ASN1_OCTET_STRING_dup(os); - if (osdup != NULL && (os->flags & ASN1_STRING_FLAG_NDEF)) - /* ASN1_STRING_FLAG_NDEF flag is currently used by openssl-smime */ + if (osdup != NULL && streaming) ASN1_STRING_set0(osdup, NULL, 0); return osdup; } @@ -74,16 +73,19 @@ static ASN1_OCTET_STRING *pkcs7_get1_data(PKCS7 *p7) if (PKCS7_type_is_other(p7) && (p7->d.other != NULL) && (p7->d.other->type == V_ASN1_SEQUENCE) && (p7->d.other->value.sequence != NULL) - && (ASN1_STRING_length(p7->d.other->value.sequence) > 0)) { + && (ASN1_STRING_get_length(p7->d.other->value.sequence) > 0)) { const unsigned char *data = ASN1_STRING_get0_data(p7->d.other->value.sequence); long len; int inf, tag, class; + size_t tmp; + tmp = ASN1_STRING_get_length(p7->d.other->value.sequence); + if (tmp > INT_MAX) + return NULL; os = ASN1_OCTET_STRING_new(); if (os == NULL) return NULL; - inf = ASN1_get_object(&data, &len, &tag, &class, - ASN1_STRING_length(p7->d.other->value.sequence)); + inf = ASN1_get_object(&data, &len, &tag, &class, (int)tmp); if (inf != V_ASN1_CONSTRUCTED || tag != V_ASN1_SEQUENCE || !ASN1_OCTET_STRING_set(os, data, len)) { ASN1_OCTET_STRING_free(os); @@ -198,7 +200,7 @@ static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, goto err; ret = evp_pkey_decrypt_alloc(pctx, &ek, &eklen, fixlen, - ASN1_STRING_get0_data(ri->enc_key), ASN1_STRING_length(ri->enc_key)); + ASN1_STRING_get0_data(ri->enc_key), ASN1_STRING_get_length(ri->enc_key)); if (ret <= 0) goto err; @@ -257,12 +259,12 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) } i = OBJ_obj2nid(p7->type); - p7->state = PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: md_sk = p7->d.sign->md_algs; - os = pkcs7_get1_data(p7->d.sign->contents); + os = pkcs7_get1_data(p7->d.sign->contents, + (p7->state & PKCS7_STATE_STREAMING) != 0); break; case NID_pkcs7_signedAndEnveloped: rsk = p7->d.signed_and_enveloped->recipientinfo; @@ -285,7 +287,8 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) break; case NID_pkcs7_digest: xa = p7->d.digest->md; - os = pkcs7_get1_data(p7->d.digest->contents); + os = pkcs7_get1_data(p7->d.digest->contents, + (p7->state & PKCS7_STATE_STREAMING) != 0); break; case NID_pkcs7_data: break; @@ -371,7 +374,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) if (bio == NULL) { if (PKCS7_is_detached(p7)) { bio = BIO_new(BIO_s_null()); - } else if (os != NULL && ASN1_STRING_length(os) > 0) { + } else if (os != NULL && ASN1_STRING_get_length(os) > 0) { /* * bio needs a copy of os->data instead of a pointer because * the data will be used after os has been freed @@ -380,8 +383,8 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) if (bio != NULL) { BIO_set_mem_eof_return(bio, 0); const unsigned char *os_data = ASN1_STRING_get0_data(os); - int os_len = ASN1_STRING_length(os); - if (BIO_write(bio, os_data, os_len) != os_len) { + size_t os_len = ASN1_STRING_get_length(os); + if (os_len > INT_MAX || BIO_write(bio, os_data, (int)os_len) != (int)os_len) { BIO_free_all(bio); bio = NULL; } @@ -458,7 +461,6 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) } i = OBJ_obj2nid(p7->type); - p7->state = PKCS7_S_HEADER; switch (i) { case NID_pkcs7_signed: @@ -656,10 +658,12 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) if (in_bio != NULL) { bio = in_bio; } else { - int data_body_len = ASN1_STRING_length(data_body); + size_t data_body_len = ASN1_STRING_get_length(data_body); + if (data_body_len > INT_MAX) + goto err; if (data_body_len > 0) bio = BIO_new_mem_buf(ASN1_STRING_get0_data(data_body), - data_body_len); + (int)data_body_len); else { bio = BIO_new(BIO_s_mem()); if (bio == NULL) @@ -766,7 +770,6 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) } i = OBJ_obj2nid(p7->type); - p7->state = PKCS7_S_HEADER; switch (i) { case NID_pkcs7_data: @@ -897,7 +900,7 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) */ if (os == NULL) goto err; - if (!(os->flags & ASN1_STRING_FLAG_NDEF)) { + if (!(p7->state & PKCS7_STATE_STREAMING)) { char *cont; long contlen; btmp = BIO_find_type(bio, BIO_TYPE_MEM); @@ -1110,7 +1113,7 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); goto err; } - if ((ASN1_STRING_length(message_digest) != (int)md_len) + if ((ASN1_STRING_get_length(message_digest) != md_len) || (memcmp(ASN1_STRING_get0_data(message_digest), md_dat, md_len))) { ERR_raise(ERR_LIB_PKCS7, PKCS7_R_DIGEST_FAILURE); ret = -1; @@ -1142,8 +1145,12 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, } const unsigned char *sig_data = ASN1_STRING_get0_data(os); - int sig_len = ASN1_STRING_length(os); - i = EVP_VerifyFinal_ex(mdc_tmp, sig_data, sig_len, pkey, libctx, propq); + size_t sig_len = ASN1_STRING_get_length(os); + if (sig_len > INT_MAX) { + ret = -1; + goto err; + } + i = EVP_VerifyFinal_ex(mdc_tmp, sig_data, (int)sig_len, pkey, libctx, propq); if (i <= 0) { ERR_raise(ERR_LIB_PKCS7, PKCS7_R_SIGNATURE_FAILURE); ret = -1; diff --git a/crypto/pkcs7/pk7_lib.c b/crypto/pkcs7/pk7_lib.c index a9640769cf008..539bb1633b85f 100644 --- a/crypto/pkcs7/pk7_lib.c +++ b/crypto/pkcs7/pk7_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -716,8 +716,8 @@ int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) return 1; } -/* unfortunately cannot constify BIO_new_NDEF() due to this and CMS_stream() */ -int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) +/* Return the content octet string that indefinite-length streaming encodes */ +ASN1_OCTET_STRING *ossl_pkcs7_get0_stream_content(PKCS7 *p7) { ASN1_OCTET_STRING *os = NULL; @@ -727,6 +727,10 @@ int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) break; case NID_pkcs7_signedAndEnveloped: + if (p7->d.signed_and_enveloped == NULL || p7->d.signed_and_enveloped->enc_data == NULL) { + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT); + break; + } os = p7->d.signed_and_enveloped->enc_data->enc_data; if (os == NULL) { os = ASN1_OCTET_STRING_new(); @@ -735,6 +739,10 @@ int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) break; case NID_pkcs7_enveloped: + if (p7->d.enveloped == NULL || p7->d.enveloped->enc_data == NULL) { + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT); + break; + } os = p7->d.enveloped->enc_data->enc_data; if (os == NULL) { os = ASN1_OCTET_STRING_new(); @@ -747,7 +755,13 @@ int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_CONTENT); break; } - os = p7->d.sign->contents->d.data; + + if (!PKCS7_type_is_data(p7->d.sign->contents)) { + ERR_raise(ERR_LIB_PKCS7, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + break; + } + + os = PKCS7_get_octet_string(p7->d.sign->contents); break; default: @@ -755,11 +769,26 @@ int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) break; } + return os; +} + +int ossl_pkcs7_stream(PKCS7 *p7) +{ + ASN1_OCTET_STRING *os = ossl_pkcs7_get0_stream_content(p7); + if (os == NULL) return 0; - os->flags |= ASN1_STRING_FLAG_NDEF; - *boundary = &os->data; + p7->state |= PKCS7_STATE_STREAMING; return 1; } + +#if !defined(OPENSSL_NO_DEPRECATED_4_1) +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) +{ + if (boundary != NULL) + *boundary = NULL; + return ossl_pkcs7_stream(p7); +} +#endif /* !defined(OPENSSL_NO_DEPRECATED_4_1) */ diff --git a/crypto/pkcs7/pk7_local.h b/crypto/pkcs7/pk7_local.h index 2155b7b56f2ba..ab15ad923e48e 100644 --- a/crypto/pkcs7/pk7_local.h +++ b/crypto/pkcs7/pk7_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,6 +12,29 @@ #include "crypto/pkcs7.h" +/* + * The public PKCS7 state field once held PKCS7_S_HEADER/BODY/TAIL; those + * values are no longer used but remain public. Use a separate bit of the + * field, clear of the public values, as an internal flag. + * + * Set when streaming is set up, where the encoder writes the content out. + * When it is not set and the content is not detached, the content octet + * string is filled at dataFinal time from the memory BIO PKCS7_dataInit() + * creates. + */ +#define PKCS7_STATE_STREAMING 0x100 + +ASN1_OCTET_STRING *ossl_pkcs7_get0_stream_content(PKCS7 *p7); + +/** + * @brief Prepare the content of p7 for indefinite-length streaming. + * The content octet string is created if it is not already present, and the + * content is recorded as a streaming placeholder in the state field. + * @param p7 the PKCS7 to prepare for streaming + * @returns 1 on success, 0 on failure + */ +int ossl_pkcs7_stream(PKCS7 *p7); + STACK_OF(X509) *pkcs7_get0_certificates(const PKCS7 *p7); const PKCS7_CTX *ossl_pkcs7_get0_ctx(const PKCS7 *p7); OSSL_LIB_CTX *ossl_pkcs7_ctx_get0_libctx(const PKCS7_CTX *ctx); diff --git a/crypto/pkcs7/pk7_smime.c b/crypto/pkcs7/pk7_smime.c index 49129690deb96..7ff5682e57d1a 100644 --- a/crypto/pkcs7/pk7_smime.c +++ b/crypto/pkcs7/pk7_smime.c @@ -97,17 +97,33 @@ int PKCS7_final(PKCS7 *p7, BIO *data, int flags) /* Check to see if a cipher exists and if so add S/MIME capabilities */ -static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) +static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg, + OSSL_LIB_CTX *libctx, const char *propq) { - if (EVP_get_cipherbynid(nid)) + EVP_CIPHER *cipher; + + ERR_set_mark(); + cipher = EVP_CIPHER_fetch(libctx, OBJ_nid2sn(nid), propq); + ERR_pop_to_mark(); + if (cipher != NULL) { + EVP_CIPHER_free(cipher); return PKCS7_simple_smimecap(sk, nid, arg); + } return 1; } -static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) +static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg, + OSSL_LIB_CTX *libctx, const char *propq) { - if (EVP_get_digestbynid(nid)) + EVP_MD *md; + + ERR_set_mark(); + md = EVP_MD_fetch(libctx, OBJ_nid2sn(nid), propq); + ERR_pop_to_mark(); + if (md != NULL) { + EVP_MD_free(md); return PKCS7_simple_smimecap(sk, nid, arg); + } return 1; } @@ -117,6 +133,8 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, { PKCS7_SIGNER_INFO *si = NULL; STACK_OF(X509_ALGOR) *smcap = NULL; + OSSL_LIB_CTX *libctx; + const char *propq; if (!X509_check_private_key(signcert, pkey)) { ERR_raise(ERR_LIB_PKCS7, @@ -144,18 +162,17 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, ERR_raise(ERR_LIB_PKCS7, ERR_R_CRYPTO_LIB); goto err; } - if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1) - || !add_digest_smcap(smcap, NID_id_GostR3411_2012_256, -1) - || !add_digest_smcap(smcap, NID_id_GostR3411_2012_512, -1) - || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1) - || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) - || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1) - || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1) - || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) - || !add_cipher_smcap(smcap, NID_rc2_cbc, 128) - || !add_cipher_smcap(smcap, NID_rc2_cbc, 64) - || !add_cipher_smcap(smcap, NID_des_cbc, -1) - || !add_cipher_smcap(smcap, NID_rc2_cbc, 40) + libctx = ossl_pkcs7_ctx_get0_libctx(si->ctx); + propq = ossl_pkcs7_ctx_get0_propq(si->ctx); + if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1, libctx, propq) + || !add_digest_smcap(smcap, NID_id_GostR3411_2012_256, -1, libctx, propq) + || !add_digest_smcap(smcap, NID_id_GostR3411_2012_512, -1, libctx, propq) + || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1, libctx, propq) + || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1, libctx, propq) + || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1, libctx, propq) + || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1, libctx, propq) + || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1, libctx, propq) + || !add_cipher_smcap(smcap, NID_rc2_cbc, 128, libctx, propq) || !PKCS7_add_attrib_smimecap(si, smcap)) goto err; sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); @@ -199,9 +216,15 @@ static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si) } } - if (osdig != NULL) - return PKCS7_add1_attrib_digest(si, ASN1_STRING_get0_data(osdig), ASN1_STRING_length(osdig)); + if (osdig != NULL) { + size_t len; + len = ASN1_STRING_get_length(osdig); + if (len > INT_MAX) + goto err; + return PKCS7_add1_attrib_digest(si, ASN1_STRING_get0_data(osdig), (int)len); + } +err: ERR_raise(ERR_LIB_PKCS7, PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND); return 0; } diff --git a/crypto/pkcs7/pkcs7err.c b/crypto/pkcs7/pkcs7err.c deleted file mode 100644 index 45494a976864e..0000000000000 --- a/crypto/pkcs7/pkcs7err.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/pkcs7err.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA PKCS7_str_reasons[] = { - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_CERTIFICATE_VERIFY_ERROR), - "certificate verify error" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER), - "cipher has no object identifier" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_CIPHER_NOT_INITIALIZED), - "cipher not initialized" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_CONTENT_AND_DATA_PRESENT), - "content and data present" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_CTRL_ERROR), "ctrl error" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_DECRYPT_ERROR), "decrypt error" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_DIGEST_FAILURE), "digest failure" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_ENCRYPTION_CTRL_FAILURE), - "encryption ctrl failure" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), - "encryption not supported for this key type" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_ERROR_ADDING_RECIPIENT), - "error adding recipient" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_ERROR_SETTING_CIPHER), - "error setting cipher" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_INVALID_NULL_POINTER), - "invalid null pointer" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_INVALID_SIGNED_DATA_TYPE), - "invalid signed data type" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_NO_CONTENT), "no content" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_NO_DEFAULT_DIGEST), - "no default digest" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND), - "no matching digest type found" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE), - "no recipient matches certificate" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_NO_SIGNATURES_ON_DATA), - "no signatures on data" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_NO_SIGNERS), "no signers" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE), - "operation not supported on this type" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR), - "pkcs7 add signature error" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_PKCS7_ADD_SIGNER_ERROR), - "pkcs7 add signer error" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_PKCS7_DATASIGN), "pkcs7 datasign" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), - "private key does not match certificate" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_SIGNATURE_FAILURE), - "signature failure" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND), - "signer certificate not found" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_SIGNING_CTRL_FAILURE), - "signing ctrl failure" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), - "signing not supported for this key type" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_SMIME_TEXT_ERROR), "smime text error" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_UNABLE_TO_FIND_CERTIFICATE), - "unable to find certificate" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_UNABLE_TO_FIND_MEM_BIO), - "unable to find mem bio" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST), - "unable to find message digest" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_UNKNOWN_DIGEST_TYPE), - "unknown digest type" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_UNKNOWN_OPERATION), - "unknown operation" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_UNSUPPORTED_CIPHER_TYPE), - "unsupported cipher type" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_UNSUPPORTED_CONTENT_TYPE), - "unsupported content type" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_WRONG_CONTENT_TYPE), - "wrong content type" }, - { ERR_PACK(ERR_LIB_PKCS7, 0, PKCS7_R_WRONG_PKCS7_TYPE), "wrong pkcs7 type" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_PKCS7_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(PKCS7_str_reasons[0].error) == NULL) - ERR_load_strings_const(PKCS7_str_reasons); -#endif - return 1; -} diff --git a/crypto/poly1305/asm/poly1305-armv4.pl b/crypto/poly1305/asm/poly1305-armv4.pl index 31500feed284b..f7c30c9e5b43a 100755 --- a/crypto/poly1305/asm/poly1305-armv4.pl +++ b/crypto/poly1305/asm/poly1305-armv4.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/poly1305/asm/poly1305-armv8.pl b/crypto/poly1305/asm/poly1305-armv8.pl index 17bf15d781a12..fe72c6ff01868 100755 --- a/crypto/poly1305/asm/poly1305-armv8.pl +++ b/crypto/poly1305/asm/poly1305-armv8.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/poly1305/asm/poly1305-armv9-sve2.pl b/crypto/poly1305/asm/poly1305-armv9-sve2.pl index 7f957f0188f60..1ba59c796d578 100755 --- a/crypto/poly1305/asm/poly1305-armv9-sve2.pl +++ b/crypto/poly1305/asm/poly1305-armv9-sve2.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -304,6 +304,7 @@ // a VLA risc-v implementation in https://github.com/dot-asm/cryptogams. // .globl poly1305_blocks_sve2 +.hidden poly1305_blocks_sve2 .type poly1305_blocks_sve2,%function .align 5 poly1305_blocks_sve2: diff --git a/crypto/poly1305/asm/poly1305-mips.pl b/crypto/poly1305/asm/poly1305-mips.pl index 7ecf2855206af..7b3fd212d2073 100755 --- a/crypto/poly1305/asm/poly1305-mips.pl +++ b/crypto/poly1305/asm/poly1305-mips.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/poly1305/asm/poly1305-s390x.pl b/crypto/poly1305/asm/poly1305-s390x.pl index 34e4f5cf2db57..a2f1f669fff9a 100755 --- a/crypto/poly1305/asm/poly1305-s390x.pl +++ b/crypto/poly1305/asm/poly1305-s390x.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/poly1305/asm/poly1305-sparcv9.pl b/crypto/poly1305/asm/poly1305-sparcv9.pl index 62ab114acb1e3..a8717bb21f702 100755 --- a/crypto/poly1305/asm/poly1305-sparcv9.pl +++ b/crypto/poly1305/asm/poly1305-sparcv9.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/poly1305/asm/poly1305-x86.pl b/crypto/poly1305/asm/poly1305-x86.pl index 42e575516e18f..22819d21b09d7 100755 --- a/crypto/poly1305/asm/poly1305-x86.pl +++ b/crypto/poly1305/asm/poly1305-x86.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/poly1305/asm/poly1305-x86_64.pl b/crypto/poly1305/asm/poly1305-x86_64.pl index a70ec0f952cbb..1ef2fad211ee6 100755 --- a/crypto/poly1305/asm/poly1305-x86_64.pl +++ b/crypto/poly1305/asm/poly1305-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/poly1305/poly1305.c b/crypto/poly1305/poly1305.c index 09167cb9d4c43..5e09a304ab34f 100644 --- a/crypto/poly1305/poly1305.c +++ b/crypto/poly1305/poly1305.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/poly1305/poly1305_ppc.c b/crypto/poly1305/poly1305_ppc.c index 4a2a943a8bef3..32aa67041a8c9 100644 --- a/crypto/poly1305/poly1305_ppc.c +++ b/crypto/poly1305/poly1305_ppc.c @@ -1,5 +1,5 @@ /* - * Copyright 2009-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2009-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ppccap.c b/crypto/ppccap.c index e029eb3051af6..a258cf316d552 100644 --- a/crypto/ppccap.c +++ b/crypto/ppccap.c @@ -1,5 +1,5 @@ /* - * Copyright 2009-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2009-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -160,11 +160,16 @@ void OPENSSL_cpuid_setup(void) if (sizeof(size_t) == 4) { struct utsname uts; + long major; + char *end; #if defined(_SC_AIX_KERNEL_BITMODE) if (sysconf(_SC_AIX_KERNEL_BITMODE) != 64) return; #endif - if (uname(&uts) != 0 || atoi(uts.version) < 6) + if (uname(&uts) != 0 + || !ossl_strtol(uts.version, &end, 10, &major) + || (*end != '\0' && *end != '.') + || major < 6) return; } diff --git a/crypto/property/property.c b/crypto/property/property.c index aa0bb283f1a8f..80f657f2be179 100644 --- a/crypto/property/property.c +++ b/crypto/property/property.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -72,7 +72,7 @@ typedef struct { } ALGORITHM; typedef struct { - SPARSE_ARRAY_OF(ALGORITHM) * algs; + SPARSE_ARRAY_OF(ALGORITHM) *algs; QUERY *cache_lists[MAX_CACHE_LINES]; QUERY *archive; diff --git a/crypto/property/property_err.c b/crypto/property/property_err.c deleted file mode 100644 index 2361806fc7b53..0000000000000 --- a/crypto/property/property_err.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "internal/propertyerr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA PROP_str_reasons[] = { - { ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NAME_TOO_LONG), "name too long" }, - { ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_ASCII_CHARACTER), - "not an ascii character" }, - { ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_HEXADECIMAL_DIGIT), - "not an hexadecimal digit" }, - { ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_IDENTIFIER), "not an identifier" }, - { ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_AN_OCTAL_DIGIT), - "not an octal digit" }, - { ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NOT_A_DECIMAL_DIGIT), - "not a decimal digit" }, - { ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NO_MATCHING_STRING_DELIMITER), - "no matching string delimiter" }, - { ERR_PACK(ERR_LIB_PROP, 0, PROP_R_NO_VALUE), "no value" }, - { ERR_PACK(ERR_LIB_PROP, 0, PROP_R_PARSE_FAILED), "parse failed" }, - { ERR_PACK(ERR_LIB_PROP, 0, PROP_R_STRING_TOO_LONG), "string too long" }, - { ERR_PACK(ERR_LIB_PROP, 0, PROP_R_TRAILING_CHARACTERS), - "trailing characters" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_PROP_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(PROP_str_reasons[0].error) == NULL) - ERR_load_strings_const(PROP_str_reasons); -#endif - return 1; -} diff --git a/crypto/property/property_local.h b/crypto/property/property_local.h index 0e63b2b67f4cc..015b16109ad96 100644 --- a/crypto/property/property_local.h +++ b/crypto/property/property_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c index 869d19da85af0..b698d09b9516d 100644 --- a/crypto/property/property_parse.c +++ b/crypto/property/property_parse.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -685,7 +685,7 @@ static void put_num(int64_t val, char **buf, size_t *remain, size_t *needed) if (*remain == 0) return; - BIO_snprintf(*buf, *remain, "%lld", (long long int)val); + snprintf(*buf, *remain, "%lld", (long long int)val); if (*remain < len) { *buf += *remain; *remain = 0; diff --git a/crypto/provider_conf.c b/crypto/provider_conf.c index f2e76ac402e6c..021b654079051 100644 --- a/crypto/provider_conf.c +++ b/crypto/provider_conf.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -15,6 +15,7 @@ #include #include "internal/provider.h" #include "internal/cryptlib.h" +#include "internal/conf.h" #include "provider_local.h" #include "crypto/context.h" @@ -275,30 +276,7 @@ static int provider_conf_activate(OSSL_LIB_CTX *libctx, const char *name, static int provider_conf_parse_bool_setting(const char *confname, const char *confvalue, int *val) { - - if (confvalue == NULL) { - ERR_raise_data(ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_SECTION_ERROR, - "directive %s set to unrecognized value", - confname); - return 0; - } - if ((strcmp(confvalue, "1") == 0) - || (strcmp(confvalue, "yes") == 0) - || (strcmp(confvalue, "YES") == 0) - || (strcmp(confvalue, "true") == 0) - || (strcmp(confvalue, "TRUE") == 0) - || (strcmp(confvalue, "on") == 0) - || (strcmp(confvalue, "ON") == 0)) { - *val = 1; - } else if ((strcmp(confvalue, "0") == 0) - || (strcmp(confvalue, "no") == 0) - || (strcmp(confvalue, "NO") == 0) - || (strcmp(confvalue, "false") == 0) - || (strcmp(confvalue, "FALSE") == 0) - || (strcmp(confvalue, "off") == 0) - || (strcmp(confvalue, "OFF") == 0)) { - *val = 0; - } else { + if (!ossl_conf_parse_bool(confvalue, val)) { ERR_raise_data(ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_SECTION_ERROR, "directive %s set to unrecognized value", confname); diff --git a/crypto/provider_core.c b/crypto/provider_core.c index b408e95e10e2c..127cb4a23c2b9 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -486,7 +487,7 @@ int ossl_provider_up_ref(OSSL_PROVIDER *prov) { int ref = 0; - if (CRYPTO_UP_REF(&prov->refcnt, &ref) <= 0) + if (!CRYPTO_UP_REF(&prov->refcnt, &ref)) return 0; #ifndef FIPS_MODULE @@ -1576,7 +1577,7 @@ int ossl_provider_doall_activated(OSSL_LIB_CTX *ctx, * to avoid upping the ref count on the parent provider, which we * must not do while holding locks. */ - if (CRYPTO_UP_REF(&prov->refcnt, &ref) <= 0) { + if (!CRYPTO_UP_REF(&prov->refcnt, &ref)) { CRYPTO_THREAD_unlock(prov->flag_lock); goto err_unlock; } @@ -1674,10 +1675,10 @@ int OSSL_PROVIDER_available(OSSL_LIB_CTX *libctx, const char *name) prov = ossl_provider_find(libctx, name, 0); if (prov != NULL) { - if (!CRYPTO_THREAD_read_lock(prov->flag_lock)) - return 0; - available = prov->flag_activated; - CRYPTO_THREAD_unlock(prov->flag_lock); + if (CRYPTO_THREAD_read_lock(prov->flag_lock)) { + available = prov->flag_activated; + CRYPTO_THREAD_unlock(prov->flag_lock); + } ossl_provider_free(prov); } return available; @@ -2283,7 +2284,9 @@ OSSL_FUNC_BIO_puts_fn ossl_core_bio_puts; OSSL_FUNC_BIO_up_ref_fn ossl_core_bio_up_ref; OSSL_FUNC_BIO_free_fn ossl_core_bio_free; OSSL_FUNC_BIO_vprintf_fn ossl_core_bio_vprintf; -OSSL_FUNC_BIO_vsnprintf_fn BIO_vsnprintf; +#ifndef FIPS_MODULE +static OSSL_FUNC_BIO_vsnprintf_fn core_bio_vsnprintf; +#endif static OSSL_FUNC_indicator_cb_fn core_indicator_get_callback; static OSSL_FUNC_self_test_cb_fn core_self_test_get_callback; static OSSL_FUNC_get_entropy_fn rand_get_entropy; @@ -2586,6 +2589,18 @@ static int core_obj_create(const OSSL_CORE_HANDLE *prov, const char *oid, /* * Functions provided by the core. */ +#ifndef FIPS_MODULE +static int core_bio_vsnprintf(char *buf, size_t n, const char *format, + va_list args) +{ + int ret = vsnprintf(buf, n, format, args); + + if ((size_t)ret >= n) + ret = -1; + return ret; +} +#endif + static const OSSL_DISPATCH core_dispatch_[] = { { OSSL_FUNC_CORE_GETTABLE_PARAMS, (void (*)(void))core_gettable_params }, { OSSL_FUNC_CORE_GET_PARAMS, (void (*)(void))core_get_params }, @@ -2610,7 +2625,7 @@ static const OSSL_DISPATCH core_dispatch_[] = { { OSSL_FUNC_BIO_UP_REF, (void (*)(void))ossl_core_bio_up_ref }, { OSSL_FUNC_BIO_FREE, (void (*)(void))ossl_core_bio_free }, { OSSL_FUNC_BIO_VPRINTF, (void (*)(void))ossl_core_bio_vprintf }, - { OSSL_FUNC_BIO_VSNPRINTF, (void (*)(void))BIO_vsnprintf }, + { OSSL_FUNC_BIO_VSNPRINTF, (void (*)(void))core_bio_vsnprintf }, { OSSL_FUNC_SELF_TEST_CB, (void (*)(void))core_self_test_get_callback }, { OSSL_FUNC_INDICATOR_CB, (void (*)(void))core_indicator_get_callback }, { OSSL_FUNC_GET_ENTROPY, (void (*)(void))rand_get_entropy }, diff --git a/crypto/provider_local.h b/crypto/provider_local.h index a7c830ab511e7..7017e905c37f8 100644 --- a/crypto/provider_local.h +++ b/crypto/provider_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rand/prov_seed.c b/crypto/rand/prov_seed.c index 8466ded8ab089..d0c7c635511e6 100644 --- a/crypto/rand/prov_seed.c +++ b/crypto/rand/prov_seed.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -45,13 +45,27 @@ size_t ossl_rand_get_user_entropy(OSSL_LIB_CTX *ctx, unsigned char **pout, int entropy, size_t min_len, size_t max_len) { - EVP_RAND_CTX *rng = ossl_rand_get0_seed_noncreating(ctx); - - if (rng != NULL && evp_rand_can_seed(rng)) - return evp_rand_get_seed(rng, pout, entropy, min_len, max_len, - 0, NULL, 0); - else - return ossl_rand_get_entropy(ctx, pout, entropy, min_len, max_len); + EVP_RAND_CTX *rng; + + if (ossl_rand_seed_source_strict(ctx)) { + /* + * With strict seeding the seed source must be used, even when the + * request arrives before anything instantiated it: create it now + * and fail instead of silently substituting the operating system + * entropy sources. + */ + rng = ossl_rand_get0_seed(ctx); + if (rng == NULL || !evp_rand_can_seed(rng)) { + ERR_raise(ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_ENTROPY); + return 0; + } + } else { + rng = ossl_rand_get0_seed_noncreating(ctx); + if (rng == NULL || !evp_rand_can_seed(rng)) + return ossl_rand_get_entropy(ctx, pout, entropy, min_len, max_len); + } + return evp_rand_get_seed(rng, pout, entropy, min_len, max_len, + 0, NULL, 0); } void ossl_rand_cleanup_entropy(ossl_unused OSSL_LIB_CTX *ctx, @@ -103,10 +117,21 @@ size_t ossl_rand_get_user_nonce(OSSL_LIB_CTX *ctx, const void *salt, size_t salt_len) { unsigned char *buf; - EVP_RAND_CTX *rng = ossl_rand_get0_seed_noncreating(ctx); - - if (rng == NULL) - return ossl_rand_get_nonce(ctx, pout, min_len, max_len, salt, salt_len); + EVP_RAND_CTX *rng; + + if (ossl_rand_seed_source_strict(ctx)) { + /* See ossl_rand_get_user_entropy() */ + rng = ossl_rand_get0_seed(ctx); + if (rng == NULL) { + ERR_raise(ERR_LIB_RAND, RAND_R_ERROR_RETRIEVING_NONCE); + return 0; + } + } else { + rng = ossl_rand_get0_seed_noncreating(ctx); + if (rng == NULL) + return ossl_rand_get_nonce(ctx, pout, min_len, max_len, + salt, salt_len); + } if ((buf = OPENSSL_malloc(min_len)) == NULL) return 0; diff --git a/crypto/rand/rand_deprecated.c b/crypto/rand/rand_deprecated.c index 07b6ff04e8da7..4745d7ac80c97 100644 --- a/crypto/rand/rand_deprecated.c +++ b/crypto/rand/rand_deprecated.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rand/rand_egd.c b/crypto/rand/rand_egd.c index c3f0a12ef1fe4..aeb9bd0d2384d 100644 --- a/crypto/rand/rand_egd.c +++ b/crypto/rand/rand_egd.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rand/rand_err.c b/crypto/rand/rand_err.c deleted file mode 100644 index 5bd44f2190bee..0000000000000 --- a/crypto/rand/rand_err.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/randerr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA RAND_str_reasons[] = { - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ADDITIONAL_INPUT_TOO_LONG), - "additional input too long" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ALREADY_INSTANTIATED), - "already instantiated" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ARGUMENT_OUT_OF_RANGE), - "argument out of range" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_CANNOT_OPEN_FILE), "Cannot open file" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_DRBG_ALREADY_INITIALIZED), - "drbg already initialized" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_DRBG_NOT_INITIALISED), - "drbg not initialised" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ENTROPY_INPUT_TOO_LONG), - "entropy input too long" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ENTROPY_OUT_OF_RANGE), - "entropy out of range" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED), - "error entropy pool was ignored" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ERROR_INITIALISING_DRBG), - "error initialising drbg" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ERROR_INSTANTIATING_DRBG), - "error instantiating drbg" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ERROR_RETRIEVING_ADDITIONAL_INPUT), - "error retrieving additional input" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ERROR_RETRIEVING_ENTROPY), - "error retrieving entropy" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_ERROR_RETRIEVING_NONCE), - "error retrieving nonce" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_FAILED_TO_CREATE_LOCK), - "failed to create lock" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_FUNC_NOT_IMPLEMENTED), - "Function not implemented" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_FWRITE_ERROR), "Error writing file" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_GENERATE_ERROR), "generate error" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_INSUFFICIENT_DRBG_STRENGTH), - "insufficient drbg strength" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_INTERNAL_ERROR), "internal error" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_INVALID_PROPERTY_QUERY), - "invalid property query" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_IN_ERROR_STATE), "in error state" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NOT_A_REGULAR_FILE), - "Not a regular file" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NOT_INSTANTIATED), "not instantiated" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED), - "no drbg implementation selected" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PARENT_LOCKING_NOT_ENABLED), - "parent locking not enabled" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PARENT_STRENGTH_TOO_WEAK), - "parent strength too weak" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PERSONALISATION_STRING_TOO_LONG), - "personalisation string too long" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED), - "prediction resistance not supported" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_PRNG_NOT_SEEDED), "PRNG not seeded" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_RANDOM_POOL_IS_EMPTY), - "random pool is empty" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_RANDOM_POOL_OVERFLOW), - "random pool overflow" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_RANDOM_POOL_UNDERFLOW), - "random pool underflow" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_REQUEST_TOO_LARGE_FOR_DRBG), - "request too large for drbg" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_RESEED_ERROR), "reseed error" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_SELFTEST_FAILURE), "selftest failure" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_TOO_LITTLE_NONCE_REQUESTED), - "too little nonce requested" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_TOO_MUCH_NONCE_REQUESTED), - "too much nonce requested" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_CREATE_DRBG), - "unable to create drbg" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_FETCH_DRBG), - "unable to fetch drbg" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER), - "unable to get parent reseed prop counter" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_GET_PARENT_STRENGTH), - "unable to get parent strength" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNABLE_TO_LOCK_PARENT), - "unable to lock parent" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNSUPPORTED_DRBG_FLAGS), - "unsupported drbg flags" }, - { ERR_PACK(ERR_LIB_RAND, 0, RAND_R_UNSUPPORTED_DRBG_TYPE), - "unsupported drbg type" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_RAND_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(RAND_str_reasons[0].error) == NULL) - ERR_load_strings_const(RAND_str_reasons); -#endif - return 1; -} diff --git a/crypto/rand/rand_lib.c b/crypto/rand/rand_lib.c index 63a3d1bca8244..13067172028eb 100644 --- a/crypto/rand/rand_lib.c +++ b/crypto/rand/rand_lib.c @@ -10,6 +10,9 @@ /* We need to use some RAND deprecated APIs */ #define OPENSSL_SUPPRESS_DEPRECATED +#ifndef FIPS_MODULE +#include +#endif #include #include #include @@ -68,6 +71,12 @@ typedef struct rand_global_st { /* Allow the randomness source to be changed */ char *seed_name; char *seed_propq; + + /* + * Whether the seed source may never fall back to the OS entropy: + * 1 strict, 0 not strict, -1 unset (strict only for JITTER) + */ + int seed_strict; } RAND_GLOBAL; static EVP_RAND_CTX *rand_get0_primary(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl); @@ -85,6 +94,7 @@ static RAND_GLOBAL *rand_get_global(OSSL_LIB_CTX *libctx) #include #include #include +#include "internal/conf.h" #include "crypto/rand_pool.h" #include "prov/seeding.h" #include "internal/e_os.h" @@ -451,6 +461,8 @@ void *ossl_rand_ctx_new(OSSL_LIB_CTX *libctx) if (dgbl == NULL) return NULL; + dgbl->seed_strict = -1; + #ifndef FIPS_MODULE /* * We need to ensure that base libcrypto thread handling has been @@ -522,6 +534,27 @@ static void rand_delete_thread_state(void *arg) } #if !defined(FIPS_MODULE) || !defined(OPENSSL_NO_FIPS_JITTER) +/* + * Return 1 if the seed source must always be used and never be silently + * substituted by the operating system entropy sources: requested via the + * seed_strict option of the [random] configuration section, defaulting + * to strict for the JITTER seed source or implied by an + * enable-fips-jitter build which hard-wires the JITTER seed source. + */ +static int rand_seed_source_strict(ossl_unused RAND_GLOBAL *dgbl) +{ +#ifdef OPENSSL_NO_FIPS_JITTER + const char *name; + + if (dgbl->seed_strict >= 0) + return dgbl->seed_strict; + name = dgbl->seed_name != NULL ? dgbl->seed_name : OPENSSL_SEED_SRC_NAME; + return OPENSSL_strcasecmp(name, "JITTER") == 0; +#else /* !OPENSSL_NO_FIPS_JITTER */ + return 1; +#endif /* OPENSSL_NO_FIPS_JITTER */ +} + static EVP_RAND_CTX *rand_new_seed(OSSL_LIB_CTX *libctx) { EVP_RAND *rand; @@ -535,10 +568,14 @@ static EVP_RAND_CTX *rand_new_seed(OSSL_LIB_CTX *libctx) if (dgbl == NULL) return NULL; propq = dgbl->seed_propq; +#ifdef OPENSSL_DEFAULT_SEED_PROPQ + if (propq == NULL) + propq = OPENSSL_MSTR(OPENSSL_DEFAULT_SEED_PROPQ); +#endif /* OPENSSL_DEFAULT_SEED_PROPQ */ if (dgbl->seed_name != NULL) { name = dgbl->seed_name; } else { - fallback = 1; + fallback = !rand_seed_source_strict(dgbl); name = OPENSSL_SEED_SRC_NAME; } #else /* !OPENSSL_NO_FIPS_JITTER */ @@ -569,6 +606,116 @@ static EVP_RAND_CTX *rand_new_seed(OSSL_LIB_CTX *libctx) EVP_RAND_CTX_free(ctx); return NULL; } + +typedef struct rand_seed_construction_st { +#ifndef FIPS_MODULE + ASYNC_JOB *job; +#endif + struct rand_seed_construction_st *next; +} RAND_SEED_CONSTRUCTION; + +static int rand_seed_construction_begin(OSSL_LIB_CTX *ctx, + RAND_SEED_CONSTRUCTION *marker) +{ + RAND_SEED_CONSTRUCTION *current, *head; +#ifndef FIPS_MODULE + ASYNC_JOB *job = ASYNC_get_current_job(); +#endif + + head = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_RAND_SEED_KEY, ctx); + for (current = head; current != NULL; current = current->next) { +#ifndef FIPS_MODULE + if (current->job != job) + continue; +#endif + ERR_raise(ERR_LIB_RAND, RAND_R_ERROR_INSTANTIATING_DRBG); + return 0; + } + +#ifndef FIPS_MODULE + marker->job = job; +#endif + marker->next = head; + if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_RAND_SEED_KEY, ctx, + marker)) { + ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR); + return 0; + } + return 1; +} + +static int rand_seed_construction_end(OSSL_LIB_CTX *ctx, + RAND_SEED_CONSTRUCTION *marker) +{ + RAND_SEED_CONSTRUCTION *current, *head; + + head = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_RAND_SEED_KEY, ctx); + if (head == marker) { + if (!CRYPTO_THREAD_set_local_ex(CRYPTO_THREAD_LOCAL_RAND_SEED_KEY, + ctx, marker->next)) { + ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR); + return 0; + } + return 1; + } + + for (current = head; current != NULL; current = current->next) { + if (current->next == marker) { + current->next = marker->next; + return 1; + } + } + + ERR_raise(ERR_LIB_RAND, ERR_R_INTERNAL_ERROR); + return 0; +} + +/* + * Get the global seed source, creating and storing it if it does not + * exist yet. If several threads race here, exactly one instance is + * kept and returned to all of them. + */ +static EVP_RAND_CTX *rand_get0_seed(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl) +{ + EVP_RAND_CTX *ret, *seed; + RAND_SEED_CONSTRUCTION marker; + + if (!CRYPTO_THREAD_read_lock(dgbl->lock)) + return NULL; + ret = dgbl->seed; + CRYPTO_THREAD_unlock(dgbl->lock); + if (ret != NULL) + return ret; + + /* + * Mark before fetching so recursion through provider lookup is covered + * as well as recursion during context creation or instantiation. + */ + if (!rand_seed_construction_begin(ctx, &marker)) + return NULL; + + seed = rand_new_seed(ctx); + if (!rand_seed_construction_end(ctx, &marker)) { + EVP_RAND_CTX_free(seed); + return NULL; + } + if (seed == NULL) + return NULL; + + if (!CRYPTO_THREAD_write_lock(dgbl->lock)) { + EVP_RAND_CTX_free(seed); + return NULL; + } + if (dgbl->seed == NULL) { + dgbl->seed = seed; + seed = NULL; + } + ret = dgbl->seed; + CRYPTO_THREAD_unlock(dgbl->lock); + /* Free the instance that lost a creation race */ + EVP_RAND_CTX_free(seed); + return ret; +} #endif /* !FIPS_MODULE || !OPENSSL_NO_FIPS_JITTER */ #ifndef FIPS_MODULE @@ -586,6 +733,22 @@ EVP_RAND_CTX *ossl_rand_get0_seed_noncreating(OSSL_LIB_CTX *ctx) CRYPTO_THREAD_unlock(dgbl->lock); return ret; } + +EVP_RAND_CTX *ossl_rand_get0_seed(OSSL_LIB_CTX *ctx) +{ + RAND_GLOBAL *dgbl = rand_get_global(ctx); + + if (dgbl == NULL) + return NULL; + return rand_get0_seed(ctx, dgbl); +} + +int ossl_rand_seed_source_strict(OSSL_LIB_CTX *ctx) +{ + RAND_GLOBAL *dgbl = rand_get_global(ctx); + + return dgbl != NULL && rand_seed_source_strict(dgbl); +} #endif /* !FIPS_MODULE */ static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent, @@ -597,7 +760,6 @@ static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent, EVP_RAND_CTX *ctx; OSSL_PARAM params[9], *p = params; const OSSL_PARAM *settables; - const char *prov_name; char *name, *cipher; int use_df = 1; @@ -609,7 +771,6 @@ static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent, ERR_raise(ERR_LIB_RAND, RAND_R_UNABLE_TO_FETCH_DRBG); return NULL; } - prov_name = ossl_provider_name(EVP_RAND_get0_provider(rand)); ctx = EVP_RAND_CTX_new(rand, parent); EVP_RAND_free(rand); if (ctx == NULL) { @@ -627,9 +788,6 @@ static EVP_RAND_CTX *rand_new_drbg(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent, && OSSL_PARAM_locate_const(settables, OSSL_DRBG_PARAM_DIGEST)) *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_DIGEST, dgbl->rng_digest, 0); - if (prov_name != NULL) - *p++ = OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_CORE_PROV_NAME, - (char *)prov_name, 0); if (dgbl->rng_propq != NULL) *p++ = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_PROPERTIES, dgbl->rng_propq, 0); @@ -684,7 +842,7 @@ static EVP_RAND_CTX *rand_new_crngt(OSSL_LIB_CTX *libctx, EVP_RAND_CTX *parent) */ static EVP_RAND_CTX *rand_get0_primary(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl) { - EVP_RAND_CTX *ret, *seed, *newseed = NULL, *primary; + EVP_RAND_CTX *ret, *seed = NULL, *primary; if (dgbl == NULL) return NULL; @@ -693,7 +851,6 @@ static EVP_RAND_CTX *rand_get0_primary(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl) return NULL; ret = dgbl->primary; - seed = dgbl->seed; CRYPTO_THREAD_unlock(dgbl->lock); if (ret != NULL) @@ -701,16 +858,13 @@ static EVP_RAND_CTX *rand_get0_primary(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl) #if !defined(FIPS_MODULE) || !defined(OPENSSL_NO_FIPS_JITTER) /* Create a seed source for libcrypto or jitter enabled FIPS provider */ - if (seed == NULL) { - ERR_set_mark(); - seed = newseed = rand_new_seed(ctx); - if (ERR_count_to_mark() > 0) { - EVP_RAND_CTX_free(newseed); - ERR_clear_last_mark(); - return NULL; - } - ERR_pop_to_mark(); + ERR_set_mark(); + seed = rand_get0_seed(ctx, dgbl); + if (seed == NULL && ERR_count_to_mark() > 0) { + ERR_clear_last_mark(); + return NULL; } + ERR_pop_to_mark(); #endif /* !FIPS_MODULE || !OPENSSL_NO_FIPS_JITTER */ #if defined(FIPS_MODULE) @@ -721,33 +875,30 @@ static EVP_RAND_CTX *rand_get0_primary(OSSL_LIB_CTX *ctx, RAND_GLOBAL *dgbl) PRIMARY_RESEED_TIME_INTERVAL); #endif /* FIPS_MODULE */ + if (ret == NULL) + return NULL; + /* * The primary DRBG may be shared between multiple threads so we must * enable locking. */ - if (ret == NULL || !EVP_RAND_enable_locking(ret)) { - if (ret != NULL) { - ERR_raise(ERR_LIB_EVP, EVP_R_UNABLE_TO_ENABLE_LOCKING); - EVP_RAND_CTX_free(ret); - } - if (newseed == NULL) - return NULL; - /* else carry on and store seed */ - ret = NULL; + if (!EVP_RAND_enable_locking(ret)) { + ERR_raise(ERR_LIB_EVP, EVP_R_UNABLE_TO_ENABLE_LOCKING); + EVP_RAND_CTX_free(ret); + return NULL; } - if (!CRYPTO_THREAD_write_lock(dgbl->lock)) + if (!CRYPTO_THREAD_write_lock(dgbl->lock)) { + EVP_RAND_CTX_free(ret); return NULL; + } primary = dgbl->primary; if (primary != NULL) { CRYPTO_THREAD_unlock(dgbl->lock); EVP_RAND_CTX_free(ret); - EVP_RAND_CTX_free(newseed); return primary; } - if (newseed != NULL) - dgbl->seed = newseed; dgbl->primary = ret; CRYPTO_THREAD_unlock(dgbl->lock); @@ -911,6 +1062,16 @@ static int random_set_string(char **p, const char *s) return 1; } +static int random_set_bool(int *p, const CONF_VALUE *cval) +{ + if (!ossl_conf_parse_bool(cval->value, p)) { + ERR_raise_data(ERR_LIB_CRYPTO, CRYPTO_R_RANDOM_SECTION_ERROR, + "name=%s, value=%s", cval->name, cval->value); + return 0; + } + return 1; +} + /* * Load the DRBG definitions from a configuration file. */ @@ -955,6 +1116,9 @@ static int random_conf_init(CONF_IMODULE *md, const CONF *cnf) } else if (OPENSSL_strcasecmp(cval->name, "seed_properties") == 0) { if (!random_set_string(&dgbl->seed_propq, cval->value)) return 0; + } else if (OPENSSL_strcasecmp(cval->name, "seed_strict") == 0) { + if (!random_set_bool(&dgbl->seed_strict, cval)) + return 0; } else if (OPENSSL_strcasecmp(cval->name, "random_provider") == 0) { #ifndef FIPS_MODULE OSSL_PROVIDER *prov = ossl_provider_find(libctx, cval->value, 0); diff --git a/crypto/rand/rand_uniform.c b/crypto/rand/rand_uniform.c index 0b7f7a3c0a069..b34f2e603a5af 100644 --- a/crypto/rand/rand_uniform.c +++ b/crypto/rand/rand_uniform.c @@ -1,5 +1,5 @@ /* - * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rand/randfile.c b/crypto/rand/randfile.c index c2be28a1226f1..eeb81faa95d1b 100644 --- a/crypto/rand/randfile.c +++ b/crypto/rand/randfile.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rbtree/build.info b/crypto/rbtree/build.info new file mode 100644 index 0000000000000..79f9ff01e6796 --- /dev/null +++ b/crypto/rbtree/build.info @@ -0,0 +1,3 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]=\ + rbtree.c diff --git a/crypto/rbtree/rbtree.c b/crypto/rbtree/rbtree.c new file mode 100644 index 0000000000000..f1d89166e5603 --- /dev/null +++ b/crypto/rbtree/rbtree.c @@ -0,0 +1,561 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2016 David Gwynne + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * The code here comes from David Gwynne . The original + * version can be found: + * https://github.com/dgwynne/data-structures/ + * file bst.h. The same code is also part of OpenBSD OS where it is shipped + * under BSD license. + * + * David Gwynne agrees to include modified version to OpenSSL and ship it + * under OpenSSL Apache 2.0 license. + */ + +#include "internal/ossl_rbtree.h" + +#ifndef NDEBUG +#include +#endif + +#define OSSL_RBT_BLACK 0 +#define OSSL_RBT_RED 1 + +static struct ossl_rbt_entry * +rbt_n2e(const struct ossl_rbt_type *t, void *node) +{ + uintptr_t addr = (uintptr_t)node; + + return (struct ossl_rbt_entry *)(addr + t->t_offset); +} + +static void * +rbt_e2n(const struct ossl_rbt_type *t, struct ossl_rbt_entry *rbe) +{ + uintptr_t addr = (uintptr_t)rbe; + + return (void *)(addr - t->t_offset); +} + +#define OSSL_RBE_LEFT(_rbe) (_rbe)->rb_left +#define OSSL_RBE_RIGHT(_rbe) (_rbe)->rb_right +#define OSSL_RBE_PARENT(_rbe) (_rbe)->rb_parent +#define OSSL_RBE_COLOR(_rbe) (_rbe)->rb_color + +#define OSSL_RBH_ROOT(_rbt) (_rbt)->rb_root + +static void +rbe_set(struct ossl_rbt_entry *rbe, struct ossl_rbt_entry *parent) +{ + OSSL_RBE_PARENT(rbe) = parent; + OSSL_RBE_LEFT(rbe) = OSSL_RBE_RIGHT(rbe) = NULL; + OSSL_RBE_COLOR(rbe) = OSSL_RBT_RED; +} + +static void +rbe_set_blackred(struct ossl_rbt_entry *black, struct ossl_rbt_entry *red) +{ + OSSL_RBE_COLOR(black) = OSSL_RBT_BLACK; + OSSL_RBE_COLOR(red) = OSSL_RBT_RED; +} + +static void +rbe_rotate_left(struct ossl_rbt_tree *rbt, struct ossl_rbt_entry *rbe) +{ + struct ossl_rbt_entry *parent; + struct ossl_rbt_entry *tmp; + + tmp = OSSL_RBE_RIGHT(rbe); + OSSL_RBE_RIGHT(rbe) = OSSL_RBE_LEFT(tmp); + if (OSSL_RBE_RIGHT(rbe) != NULL) + OSSL_RBE_PARENT(OSSL_RBE_LEFT(tmp)) = rbe; + + parent = OSSL_RBE_PARENT(rbe); + OSSL_RBE_PARENT(tmp) = parent; + if (parent != NULL) { + if (rbe == OSSL_RBE_LEFT(parent)) + OSSL_RBE_LEFT(parent) = tmp; + else + OSSL_RBE_RIGHT(parent) = tmp; + } else + OSSL_RBH_ROOT(rbt) = tmp; + + OSSL_RBE_LEFT(tmp) = rbe; + OSSL_RBE_PARENT(rbe) = tmp; +} + +static void +rbe_rotate_right(struct ossl_rbt_tree *rbt, struct ossl_rbt_entry *rbe) +{ + struct ossl_rbt_entry *parent; + struct ossl_rbt_entry *tmp; + + tmp = OSSL_RBE_LEFT(rbe); + OSSL_RBE_LEFT(rbe) = OSSL_RBE_RIGHT(tmp); + if (OSSL_RBE_LEFT(rbe) != NULL) + OSSL_RBE_PARENT(OSSL_RBE_RIGHT(tmp)) = rbe; + + parent = OSSL_RBE_PARENT(rbe); + OSSL_RBE_PARENT(tmp) = parent; + if (parent != NULL) { + if (rbe == OSSL_RBE_LEFT(parent)) + OSSL_RBE_LEFT(parent) = tmp; + else + OSSL_RBE_RIGHT(parent) = tmp; + } else + OSSL_RBH_ROOT(rbt) = tmp; + + OSSL_RBE_RIGHT(tmp) = rbe; + OSSL_RBE_PARENT(rbe) = tmp; +} + +static void +rbe_insert_color(struct ossl_rbt_tree *rbt, struct ossl_rbt_entry *rbe) +{ + struct ossl_rbt_entry *parent, *gparent, *tmp; + + while ((parent = OSSL_RBE_PARENT(rbe)) != NULL && OSSL_RBE_COLOR(parent) == OSSL_RBT_RED) { + gparent = OSSL_RBE_PARENT(parent); + + if (parent == OSSL_RBE_LEFT(gparent)) { + tmp = OSSL_RBE_RIGHT(gparent); + if (tmp != NULL && OSSL_RBE_COLOR(tmp) == OSSL_RBT_RED) { + OSSL_RBE_COLOR(tmp) = OSSL_RBT_BLACK; + rbe_set_blackred(parent, gparent); + rbe = gparent; + continue; + } + + if (OSSL_RBE_RIGHT(parent) == rbe) { + rbe_rotate_left(rbt, parent); + tmp = parent; + parent = rbe; + rbe = tmp; + } + + rbe_set_blackred(parent, gparent); + rbe_rotate_right(rbt, gparent); + } else { + tmp = OSSL_RBE_LEFT(gparent); + if (tmp != NULL && OSSL_RBE_COLOR(tmp) == OSSL_RBT_RED) { + OSSL_RBE_COLOR(tmp) = OSSL_RBT_BLACK; + rbe_set_blackred(parent, gparent); + rbe = gparent; + continue; + } + + if (OSSL_RBE_LEFT(parent) == rbe) { + rbe_rotate_right(rbt, parent); + tmp = parent; + parent = rbe; + rbe = tmp; + } + + rbe_set_blackred(parent, gparent); + rbe_rotate_left(rbt, gparent); + } + } + + OSSL_RBE_COLOR(OSSL_RBH_ROOT(rbt)) = OSSL_RBT_BLACK; +} + +static void +rbe_remove_color(struct ossl_rbt_tree *rbt, + struct ossl_rbt_entry *parent, struct ossl_rbt_entry *rbe) +{ + struct ossl_rbt_entry *tmp; + + while ((rbe == NULL || OSSL_RBE_COLOR(rbe) == OSSL_RBT_BLACK) && rbe != OSSL_RBH_ROOT(rbt)) { + if (OSSL_RBE_LEFT(parent) == rbe) { + tmp = OSSL_RBE_RIGHT(parent); + if (OSSL_RBE_COLOR(tmp) == OSSL_RBT_RED) { + rbe_set_blackred(tmp, parent); + rbe_rotate_left(rbt, parent); + tmp = OSSL_RBE_RIGHT(parent); + } + if ((OSSL_RBE_LEFT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_LEFT(tmp)) == OSSL_RBT_BLACK) && (OSSL_RBE_RIGHT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_RIGHT(tmp)) == OSSL_RBT_BLACK)) { + OSSL_RBE_COLOR(tmp) = OSSL_RBT_RED; + rbe = parent; + parent = OSSL_RBE_PARENT(rbe); + } else { + if (OSSL_RBE_RIGHT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_RIGHT(tmp)) == OSSL_RBT_BLACK) { + struct ossl_rbt_entry *oleft; + + oleft = OSSL_RBE_LEFT(tmp); + if (oleft != NULL) + OSSL_RBE_COLOR(oleft) = OSSL_RBT_BLACK; + + OSSL_RBE_COLOR(tmp) = OSSL_RBT_RED; + rbe_rotate_right(rbt, tmp); + tmp = OSSL_RBE_RIGHT(parent); + } + + OSSL_RBE_COLOR(tmp) = OSSL_RBE_COLOR(parent); + OSSL_RBE_COLOR(parent) = OSSL_RBT_BLACK; + if (OSSL_RBE_RIGHT(tmp)) + OSSL_RBE_COLOR(OSSL_RBE_RIGHT(tmp)) = OSSL_RBT_BLACK; + + rbe_rotate_left(rbt, parent); + rbe = OSSL_RBH_ROOT(rbt); + break; + } + } else { + tmp = OSSL_RBE_LEFT(parent); + if (OSSL_RBE_COLOR(tmp) == OSSL_RBT_RED) { + rbe_set_blackred(tmp, parent); + rbe_rotate_right(rbt, parent); + tmp = OSSL_RBE_LEFT(parent); + } + + if ((OSSL_RBE_LEFT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_LEFT(tmp)) == OSSL_RBT_BLACK) && (OSSL_RBE_RIGHT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_RIGHT(tmp)) == OSSL_RBT_BLACK)) { + OSSL_RBE_COLOR(tmp) = OSSL_RBT_RED; + rbe = parent; + parent = OSSL_RBE_PARENT(rbe); + } else { + if (OSSL_RBE_LEFT(tmp) == NULL || OSSL_RBE_COLOR(OSSL_RBE_LEFT(tmp)) == OSSL_RBT_BLACK) { + struct ossl_rbt_entry *oright; + + oright = OSSL_RBE_RIGHT(tmp); + if (oright != NULL) + OSSL_RBE_COLOR(oright) = OSSL_RBT_BLACK; + + OSSL_RBE_COLOR(tmp) = OSSL_RBT_RED; + rbe_rotate_left(rbt, tmp); + tmp = OSSL_RBE_LEFT(parent); + } + + OSSL_RBE_COLOR(tmp) = OSSL_RBE_COLOR(parent); + OSSL_RBE_COLOR(parent) = OSSL_RBT_BLACK; + if (OSSL_RBE_LEFT(tmp) != NULL) + OSSL_RBE_COLOR(OSSL_RBE_LEFT(tmp)) = OSSL_RBT_BLACK; + + rbe_rotate_right(rbt, parent); + rbe = OSSL_RBH_ROOT(rbt); + break; + } + } + } + + if (rbe != NULL) + OSSL_RBE_COLOR(rbe) = OSSL_RBT_BLACK; +} + +static struct ossl_rbt_entry * +rbe_remove(struct ossl_rbt_tree *rbt, struct ossl_rbt_entry *rbe) +{ + struct ossl_rbt_entry *child, *parent, *old = rbe; + unsigned int color; + + if (OSSL_RBE_LEFT(rbe) == NULL) + child = OSSL_RBE_RIGHT(rbe); + else if (OSSL_RBE_RIGHT(rbe) == NULL) + child = OSSL_RBE_LEFT(rbe); + else { + struct ossl_rbt_entry *tmp; + + rbe = OSSL_RBE_RIGHT(rbe); + while ((tmp = OSSL_RBE_LEFT(rbe)) != NULL) + rbe = tmp; + + child = OSSL_RBE_RIGHT(rbe); + parent = OSSL_RBE_PARENT(rbe); + color = OSSL_RBE_COLOR(rbe); + if (child != NULL) + OSSL_RBE_PARENT(child) = parent; + if (parent != NULL) { + if (OSSL_RBE_LEFT(parent) == rbe) + OSSL_RBE_LEFT(parent) = child; + else + OSSL_RBE_RIGHT(parent) = child; + } else + OSSL_RBH_ROOT(rbt) = child; + if (OSSL_RBE_PARENT(rbe) == old) + parent = rbe; + *rbe = *old; + + tmp = OSSL_RBE_PARENT(old); + if (tmp != NULL) { + if (OSSL_RBE_LEFT(tmp) == old) + OSSL_RBE_LEFT(tmp) = rbe; + else + OSSL_RBE_RIGHT(tmp) = rbe; + } else + OSSL_RBH_ROOT(rbt) = rbe; + + OSSL_RBE_PARENT(OSSL_RBE_LEFT(old)) = rbe; + if (OSSL_RBE_RIGHT(old)) + OSSL_RBE_PARENT(OSSL_RBE_RIGHT(old)) = rbe; + goto color; + } + + parent = OSSL_RBE_PARENT(rbe); + color = OSSL_RBE_COLOR(rbe); + + if (child != NULL) + OSSL_RBE_PARENT(child) = parent; + if (parent != NULL) { + if (OSSL_RBE_LEFT(parent) == rbe) + OSSL_RBE_LEFT(parent) = child; + else + OSSL_RBE_RIGHT(parent) = child; + } else + OSSL_RBH_ROOT(rbt) = child; +color: + if (color == OSSL_RBT_BLACK) + rbe_remove_color(rbt, parent, child); + +#ifndef NDEBUG + if (old != NULL) { + OSSL_RBE_PARENT(old) = NULL; + OSSL_RBE_LEFT(old) = NULL; + OSSL_RBE_RIGHT(old) = NULL; + } +#endif + + return old; +} + +void * +ossl_rbt_remove(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt, void *elm) +{ + struct ossl_rbt_entry *rbe = rbt_n2e(t, elm); + struct ossl_rbt_entry *old; + + old = rbe_remove(rbt, rbe); + + return old == NULL ? NULL : rbt_e2n(t, old); +} + +void * +ossl_rbt_insert(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt, void *elm) +{ + struct ossl_rbt_entry *rbe = rbt_n2e(t, elm); + struct ossl_rbt_entry *tmp; + struct ossl_rbt_entry *parent = NULL; + void *node; + int comp = 0; + +#ifndef NDEBUG + assert(rbe->rb_parent == NULL); + assert(rbe->rb_left == NULL); + assert(rbe->rb_right == NULL); +#endif + + tmp = OSSL_RBH_ROOT(rbt); + while (tmp != NULL) { + parent = tmp; + + node = rbt_e2n(t, tmp); + comp = (*t->t_compare)(elm, node); + if (comp < 0) + tmp = OSSL_RBE_LEFT(tmp); + else if (comp > 0) + tmp = OSSL_RBE_RIGHT(tmp); + else + return node; + } + + rbe_set(rbe, parent); + + if (parent != NULL) { + if (comp < 0) + OSSL_RBE_LEFT(parent) = rbe; + else + OSSL_RBE_RIGHT(parent) = rbe; + } else + OSSL_RBH_ROOT(rbt) = rbe; + + rbe_insert_color(rbt, rbe); + + return NULL; +} + +/* Finds the node with the same key as elm */ +void * +ossl_rbt_find(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt, const void *key) +{ + struct ossl_rbt_entry *tmp = OSSL_RBH_ROOT(rbt); + void *node; + int comp; + + while (tmp != NULL) { + node = rbt_e2n(t, tmp); + comp = (*t->t_compare)(key, node); + if (comp < 0) + tmp = OSSL_RBE_LEFT(tmp); + else if (comp > 0) + tmp = OSSL_RBE_RIGHT(tmp); + else + return node; + } + + return NULL; +} + +/* Finds the first node greater than or equal to the search key */ +void * +ossl_rbt_nfind(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt, const void *key) +{ + struct ossl_rbt_entry *tmp = OSSL_RBH_ROOT(rbt); + void *node; + void *res = NULL; + int comp; + + while (tmp != NULL) { + node = rbt_e2n(t, tmp); + comp = (*t->t_compare)(key, node); + if (comp < 0) { + res = node; + tmp = OSSL_RBE_LEFT(tmp); + } else if (comp > 0) + tmp = OSSL_RBE_RIGHT(tmp); + else + return node; + } + + return res; +} + +void * +ossl_rbt_next(const struct ossl_rbt_type *t, void *elm) +{ + struct ossl_rbt_entry *rbe = rbt_n2e(t, elm); + + if (OSSL_RBE_RIGHT(rbe) != NULL) { + rbe = OSSL_RBE_RIGHT(rbe); + while (OSSL_RBE_LEFT(rbe) != NULL) + rbe = OSSL_RBE_LEFT(rbe); + } else { + if (OSSL_RBE_PARENT(rbe) && (rbe == OSSL_RBE_LEFT(OSSL_RBE_PARENT(rbe)))) + rbe = OSSL_RBE_PARENT(rbe); + else { + while (OSSL_RBE_PARENT(rbe) && (rbe == OSSL_RBE_RIGHT(OSSL_RBE_PARENT(rbe)))) + rbe = OSSL_RBE_PARENT(rbe); + rbe = OSSL_RBE_PARENT(rbe); + } + } + + return rbe == NULL ? NULL : rbt_e2n(t, rbe); +} + +void * +ossl_rbt_prev(const struct ossl_rbt_type *t, void *elm) +{ + struct ossl_rbt_entry *rbe = rbt_n2e(t, elm); + + if (OSSL_RBE_LEFT(rbe)) { + rbe = OSSL_RBE_LEFT(rbe); + while (OSSL_RBE_RIGHT(rbe)) + rbe = OSSL_RBE_RIGHT(rbe); + } else { + if (OSSL_RBE_PARENT(rbe) && (rbe == OSSL_RBE_RIGHT(OSSL_RBE_PARENT(rbe)))) + rbe = OSSL_RBE_PARENT(rbe); + else { + while (OSSL_RBE_PARENT(rbe) && (rbe == OSSL_RBE_LEFT(OSSL_RBE_PARENT(rbe)))) + rbe = OSSL_RBE_PARENT(rbe); + rbe = OSSL_RBE_PARENT(rbe); + } + } + + return rbe == NULL ? NULL : rbt_e2n(t, rbe); +} + +void * +ossl_rbt_root(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt) +{ + struct ossl_rbt_entry *rbe = OSSL_RBH_ROOT(rbt); + + return rbe == NULL ? rbe : rbt_e2n(t, rbe); +} + +void * +ossl_rbt_min(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt) +{ + struct ossl_rbt_entry *rbe = OSSL_RBH_ROOT(rbt); + struct ossl_rbt_entry *parent = NULL; + + while (rbe != NULL) { + parent = rbe; + rbe = OSSL_RBE_LEFT(rbe); + } + + return parent == NULL ? NULL : rbt_e2n(t, parent); +} + +void * +ossl_rbt_max(const struct ossl_rbt_type *t, struct ossl_rbt_tree *rbt) +{ + struct ossl_rbt_entry *rbe = OSSL_RBH_ROOT(rbt); + struct ossl_rbt_entry *parent = NULL; + + while (rbe != NULL) { + parent = rbe; + rbe = OSSL_RBE_RIGHT(rbe); + } + + return parent == NULL ? NULL : rbt_e2n(t, parent); +} + +void * +ossl_rbt_left(const struct ossl_rbt_type *t, void *node) +{ + struct ossl_rbt_entry *rbe = rbt_n2e(t, node); + rbe = OSSL_RBE_LEFT(rbe); + return rbe == NULL ? NULL : rbt_e2n(t, rbe); +} + +void * +ossl_rbt_right(const struct ossl_rbt_type *t, void *node) +{ + struct ossl_rbt_entry *rbe = rbt_n2e(t, node); + rbe = OSSL_RBE_RIGHT(rbe); + return rbe == NULL ? NULL : rbt_e2n(t, rbe); +} + +void * +ossl_rbt_parent(const struct ossl_rbt_type *t, void *node) +{ + struct ossl_rbt_entry *rbe = rbt_n2e(t, node); + rbe = OSSL_RBE_PARENT(rbe); + return rbe == NULL ? NULL : rbt_e2n(t, rbe); +} + +void ossl_rbt_set_left(const struct ossl_rbt_type *t, void *node, void *left) +{ + struct ossl_rbt_entry *rbe = rbt_n2e(t, node); + struct ossl_rbt_entry *rbl = (left == NULL) ? NULL : rbt_n2e(t, left); + + OSSL_RBE_LEFT(rbe) = rbl; +} + +void ossl_rbt_set_right(const struct ossl_rbt_type *t, void *node, void *right) +{ + struct ossl_rbt_entry *rbe = rbt_n2e(t, node); + struct ossl_rbt_entry *rbr = (right == NULL) ? NULL : rbt_n2e(t, right); + + OSSL_RBE_RIGHT(rbe) = rbr; +} + +void ossl_rbt_set_parent(const struct ossl_rbt_type *t, void *node, void *parent) +{ + struct ossl_rbt_entry *rbe = rbt_n2e(t, node); + struct ossl_rbt_entry *rbp = (parent == NULL) ? NULL : rbt_n2e(t, parent); + + OSSL_RBE_PARENT(rbe) = rbp; +} + +void ossl_rbt_init_rbe(const struct ossl_rbt_type *t, void *node) +{ + struct ossl_rbt_entry *rbe = rbt_n2e(t, node); + + OSSL_RBE_PARENT(rbe) = NULL; + OSSL_RBE_LEFT(rbe) = NULL; + OSSL_RBE_RIGHT(rbe) = NULL; +} diff --git a/crypto/rc2/rc2_cbc.c b/crypto/rc2/rc2_cbc.c index 2a487ed507287..539e5f3672380 100644 --- a/crypto/rc2/rc2_cbc.c +++ b/crypto/rc2/rc2_cbc.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rc2/rc2_local.h b/crypto/rc2/rc2_local.h index b2be41d41938f..96eb449e2b855 100644 --- a/crypto/rc2/rc2_local.h +++ b/crypto/rc2/rc2_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rc2/rc2_skey.c b/crypto/rc2/rc2_skey.c index 02bfe45f2df6b..aa4aca99d5c1d 100644 --- a/crypto/rc2/rc2_skey.c +++ b/crypto/rc2/rc2_skey.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rc2/rc2cfb64.c b/crypto/rc2/rc2cfb64.c index 88c460b004a05..26d4c71a2581a 100644 --- a/crypto/rc2/rc2cfb64.c +++ b/crypto/rc2/rc2cfb64.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rc2/rc2ofb64.c b/crypto/rc2/rc2ofb64.c index 45fe7aecd29b8..f615ccfcc362a 100644 --- a/crypto/rc2/rc2ofb64.c +++ b/crypto/rc2/rc2ofb64.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rc4/asm/rc4-md5-x86_64.pl b/crypto/rc4/asm/rc4-md5-x86_64.pl index c4440ab32c965..e11be98c431b4 100644 --- a/crypto/rc4/asm/rc4-md5-x86_64.pl +++ b/crypto/rc4/asm/rc4-md5-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rc5/rc5_local.h b/crypto/rc5/rc5_local.h index 7b5f8c847bc3c..75022bed943dc 100644 --- a/crypto/rc5/rc5_local.h +++ b/crypto/rc5/rc5_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rc5/rc5cfb64.c b/crypto/rc5/rc5cfb64.c index 7e3357f039cde..a7c447f681d3b 100644 --- a/crypto/rc5/rc5cfb64.c +++ b/crypto/rc5/rc5cfb64.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rc5/rc5ofb64.c b/crypto/rc5/rc5ofb64.c index e55b519956dbf..5217303a28d23 100644 --- a/crypto/rc5/rc5ofb64.c +++ b/crypto/rc5/rc5ofb64.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rcu_internal.h b/crypto/rcu_internal.h index e4b9aab6fac0c..508ca19b6c9d9 100644 --- a/crypto/rcu_internal.h +++ b/crypto/rcu_internal.h @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ripemd/rmd_local.h b/crypto/ripemd/rmd_local.h index a1dd4802826e2..d66c66bca4e73 100644 --- a/crypto/ripemd/rmd_local.h +++ b/crypto/ripemd/rmd_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ripemd/rmdconst.h b/crypto/ripemd/rmdconst.h index bb48abe49ad2d..dd75463eb0e2a 100644 --- a/crypto/ripemd/rmdconst.h +++ b/crypto/ripemd/rmdconst.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/riscvcap.c b/crypto/riscvcap.c index 760fc5b0dd51c..17e4dbc7d717f 100644 --- a/crypto/riscvcap.c +++ b/crypto/riscvcap.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/rsa/rsa_acvp_test_params.c b/crypto/rsa/rsa_acvp_test_params.c index 77e1c39c3e079..c7a6b626de1e3 100644 --- a/crypto/rsa/rsa_acvp_test_params.c +++ b/crypto/rsa/rsa_acvp_test_params.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,12 +11,14 @@ #include #include #include "crypto/rsa.h" +#include "crypto/rsa_params.h" #include "rsa_local.h" -int ossl_rsa_acvp_test_gen_params_new(OSSL_PARAM **dst, const OSSL_PARAM src[]) +int ossl_rsa_acvp_test_gen_params_new_parsed(OSSL_PARAM **dst, + const RSA_PARAMS *params) { - const OSSL_PARAM *p, *s; OSSL_PARAM *d, *alloc = NULL; + size_t i; int ret = 1; static const OSSL_PARAM settable[] = { @@ -29,9 +31,16 @@ int ossl_rsa_acvp_test_gen_params_new(OSSL_PARAM **dst, const OSSL_PARAM src[]) OSSL_PARAM_END }; - /* Assume the first element is a required field if this feature is used */ - p = OSSL_PARAM_locate_const(src, settable[0].key); - if (p == NULL) + if (dst == NULL || params == NULL) + return 0; + + const OSSL_PARAM *src[] = { + params->fips.xp, params->fips.xp1, params->fips.xp2, + params->fips.xq, params->fips.xq1, params->fips.xq2 + }; + + /* Xp is required whenever the ACVP test interface is used. */ + if (src[0] == NULL) return 1; /* Zeroing here means the terminator is always set at the end */ @@ -40,16 +49,16 @@ int ossl_rsa_acvp_test_gen_params_new(OSSL_PARAM **dst, const OSSL_PARAM src[]) return 0; d = alloc; - for (s = settable; s->key != NULL; ++s) { - /* If src contains a key from settable then copy the src to the dest */ - p = OSSL_PARAM_locate_const(src, s->key); - if (p != NULL) { - *d = *s; /* shallow copy from the static settable[] */ - d->data_size = p->data_size; - d->data = OPENSSL_memdup(p->data, p->data_size); - if (d->data == NULL) + for (i = 0; i < OSSL_NELEM(src); i++) { + if (src[i] != NULL) { + *d = settable[i]; + d->data_size = src[i]->data_size; + d->data = OPENSSL_memdup(src[i]->data, src[i]->data_size); + if (d->data == NULL) { ret = 0; - ++d; + break; + } + d++; } } if (ret == 0) { @@ -62,6 +71,16 @@ int ossl_rsa_acvp_test_gen_params_new(OSSL_PARAM **dst, const OSSL_PARAM src[]) return ret; } +int ossl_rsa_acvp_test_gen_params_new(OSSL_PARAM **dst, + const OSSL_PARAM src[]) +{ + RSA_PARAMS params; + + if (!rsa_acvp_input_decoder(src, ¶ms)) + return 0; + return ossl_rsa_acvp_test_gen_params_new_parsed(dst, ¶ms); +} + void ossl_rsa_acvp_test_gen_params_free(OSSL_PARAM *dst) { OSSL_PARAM *p; @@ -76,10 +95,12 @@ void ossl_rsa_acvp_test_gen_params_free(OSSL_PARAM *dst) OPENSSL_free(dst); } -int ossl_rsa_acvp_test_set_params(RSA *r, const OSSL_PARAM params[]) +static int rsa_acvp_test_set_params_parsed(RSA *r, const RSA_PARAMS *p) { RSA_ACVP_TEST *t; - const OSSL_PARAM *p; + + if (r == NULL || p == NULL) + return 0; if (r->acvp_test != NULL) { ossl_rsa_acvp_test_free(r->acvp_test); @@ -90,31 +111,25 @@ int ossl_rsa_acvp_test_set_params(RSA *r, const OSSL_PARAM params[]) if (t == NULL) return 0; - /* Set the input parameters */ - if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XP1)) != NULL - && !OSSL_PARAM_get_BN(p, &t->Xp1)) + if (p->fips.xp1 != NULL && !OSSL_PARAM_get_BN(p->fips.xp1, &t->Xp1)) goto err; - if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XP2)) != NULL - && !OSSL_PARAM_get_BN(p, &t->Xp2)) + if (p->fips.xp2 != NULL && !OSSL_PARAM_get_BN(p->fips.xp2, &t->Xp2)) goto err; - if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XP)) != NULL - && !OSSL_PARAM_get_BN(p, &t->Xp)) + if (p->fips.xp != NULL && !OSSL_PARAM_get_BN(p->fips.xp, &t->Xp)) goto err; - if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XQ1)) != NULL - && !OSSL_PARAM_get_BN(p, &t->Xq1)) + if (p->fips.xq1 != NULL && !OSSL_PARAM_get_BN(p->fips.xq1, &t->Xq1)) goto err; - if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XQ2)) != NULL - && !OSSL_PARAM_get_BN(p, &t->Xq2)) + if (p->fips.xq2 != NULL && !OSSL_PARAM_get_BN(p->fips.xq2, &t->Xq2)) goto err; - if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XQ)) != NULL - && !OSSL_PARAM_get_BN(p, &t->Xq)) + if (p->fips.xq != NULL && !OSSL_PARAM_get_BN(p->fips.xq, &t->Xq)) goto err; - /* Setup the output parameters */ t->p1 = BN_new(); t->p2 = BN_new(); t->q1 = BN_new(); t->q2 = BN_new(); + if (t->p1 == NULL || t->p2 == NULL || t->q1 == NULL || t->q2 == NULL) + goto err; r->acvp_test = t; return 1; err: @@ -122,32 +137,45 @@ int ossl_rsa_acvp_test_set_params(RSA *r, const OSSL_PARAM params[]) return 0; } -int ossl_rsa_acvp_test_get_params(RSA *r, OSSL_PARAM params[]) +int ossl_rsa_acvp_test_set_params(RSA *r, const OSSL_PARAM params[]) +{ + RSA_PARAMS p; + + if (!rsa_acvp_input_decoder(params, &p)) + return 0; + return rsa_acvp_test_set_params_parsed(r, &p); +} + +int ossl_rsa_acvp_test_get_params_parsed(RSA *r, const RSA_PARAMS *p) { RSA_ACVP_TEST *t; - OSSL_PARAM *p; - if (r == NULL) + if (r == NULL || p == NULL) return 0; t = r->acvp_test; if (t != NULL) { - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_P1)) != NULL - && !OSSL_PARAM_set_BN(p, t->p1)) + if (p->fips.p1 != NULL && !OSSL_PARAM_set_BN(p->fips.p1, t->p1)) return 0; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_P2)) != NULL - && !OSSL_PARAM_set_BN(p, t->p2)) + if (p->fips.p2 != NULL && !OSSL_PARAM_set_BN(p->fips.p2, t->p2)) return 0; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_Q1)) != NULL - && !OSSL_PARAM_set_BN(p, t->q1)) + if (p->fips.q1 != NULL && !OSSL_PARAM_set_BN(p->fips.q1, t->q1)) return 0; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_Q2)) != NULL - && !OSSL_PARAM_set_BN(p, t->q2)) + if (p->fips.q2 != NULL && !OSSL_PARAM_set_BN(p->fips.q2, t->q2)) return 0; } return 1; } +int ossl_rsa_acvp_test_get_params(RSA *r, OSSL_PARAM params[]) +{ + RSA_PARAMS p; + + if (!rsa_acvp_output_decoder(params, &p)) + return 0; + return ossl_rsa_acvp_test_get_params_parsed(r, &p); +} + void ossl_rsa_acvp_test_free(RSA_ACVP_TEST *t) { if (t != NULL) { diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index 1eb4649481438..a1ee53e47da5f 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -23,6 +23,7 @@ #include "crypto/asn1.h" #include "crypto/evp.h" #include "crypto/rsa.h" +#include "crypto/rsa_params.h" #include "rsa_local.h" /* Set any parameters associated with pkey */ @@ -850,10 +851,8 @@ static int rsa_int_export_to(const EVP_PKEY *from, int rsa_type, return rv; } -static int rsa_int_import_from(const OSSL_PARAM params[], void *vpctx, - int rsa_type) +static int rsa_int_import_from(const RSA_PARAMS *p, EVP_PKEY_CTX *pctx, int rsa_type) { - EVP_PKEY_CTX *pctx = vpctx; EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); RSA *rsa = ossl_rsa_new_with_ctx(pctx->libctx); RSA_PSS_PARAMS_30 rsa_pss_params = { @@ -870,8 +869,9 @@ static int rsa_int_import_from(const OSSL_PARAM params[], void *vpctx, RSA_clear_flags(rsa, RSA_FLAG_TYPE_MASK); RSA_set_flags(rsa, rsa_type); - if (!ossl_rsa_pss_params_30_fromdata(&rsa_pss_params, &pss_defaults_set, - params, pctx->libctx)) + if (!ossl_rsa_pss_params_30_fromdata_parsed(&rsa_pss_params, + &pss_defaults_set, + p, pctx->libctx)) goto err; switch (rsa_type) { @@ -907,7 +907,7 @@ static int rsa_int_import_from(const OSSL_PARAM params[], void *vpctx, goto err; } - if (!ossl_rsa_fromdata(rsa, params, 1)) + if (!ossl_rsa_fromdata_parsed(rsa, p, 1)) goto err; switch (rsa_type) { @@ -943,12 +943,22 @@ static int rsa_pss_pkey_export_to(const EVP_PKEY *from, void *to_keydata, static int rsa_pkey_import_from(const OSSL_PARAM params[], void *vpctx) { - return rsa_int_import_from(params, vpctx, RSA_FLAG_TYPE_RSA); + EVP_PKEY_CTX *pctx = vpctx; + RSA_PARAMS p; + + if (pctx == NULL || !rsa_pkey_import_from_decoder(params, &p)) + return 0; + return rsa_int_import_from(&p, pctx, RSA_FLAG_TYPE_RSA); } static int rsa_pss_pkey_import_from(const OSSL_PARAM params[], void *vpctx) { - return rsa_int_import_from(params, vpctx, RSA_FLAG_TYPE_RSASSAPSS); + EVP_PKEY_CTX *pctx = vpctx; + RSA_PARAMS p; + + if (pctx == NULL || !rsa_pss_pkey_import_from_decoder(params, &p)) + return 0; + return rsa_int_import_from(&p, pctx, RSA_FLAG_TYPE_RSASSAPSS); } static int rsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) diff --git a/crypto/rsa/rsa_backend.c b/crypto/rsa/rsa_backend.c index 161d9a9c5612b..969adf4d3e045 100644 --- a/crypto/rsa/rsa_backend.c +++ b/crypto/rsa/rsa_backend.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -25,6 +25,7 @@ #include "internal/sizes.h" #include "internal/param_build_set.h" #include "crypto/rsa.h" +#include "crypto/rsa_params.h" #include "rsa_local.h" /* @@ -36,20 +37,18 @@ DEFINE_STACK_OF(BIGNUM) static int collect_numbers(STACK_OF(BIGNUM) *numbers, - const OSSL_PARAM params[], const char *names[]) + OSSL_PARAM *const params[], size_t num_params) { - const OSSL_PARAM *p = NULL; - int i; + size_t i; if (numbers == NULL) return 0; - for (i = 0; names[i] != NULL; i++) { - p = OSSL_PARAM_locate_const(params, names[i]); - if (p != NULL) { + for (i = 0; i < num_params; i++) { + if (params[i] != NULL) { BIGNUM *tmp = NULL; - if (!OSSL_PARAM_get_BN(p, &tmp)) + if (!OSSL_PARAM_get_BN(params[i], &tmp)) return 0; if (sk_BIGNUM_push(numbers, tmp) == 0) { BN_clear_free(tmp); @@ -61,38 +60,30 @@ static int collect_numbers(STACK_OF(BIGNUM) *numbers, return 1; } -int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[], int include_private) +int ossl_rsa_fromdata_parsed(RSA *rsa, const RSA_PARAMS *p, + int include_private) { - const OSSL_PARAM *param_n, *param_e, *param_d = NULL; - const OSSL_PARAM *param_derive = NULL; BIGNUM *n = NULL, *e = NULL, *d = NULL; STACK_OF(BIGNUM) *factors = NULL, *exps = NULL, *coeffs = NULL; int is_private = 0; int derive_from_pq = 0; BN_CTX *ctx = NULL; - if (rsa == NULL) + if (rsa == NULL || p == NULL) return 0; - param_n = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_N); - param_e = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_E); - - if ((param_n == NULL || !OSSL_PARAM_get_BN(param_n, &n)) - || (param_e == NULL || !OSSL_PARAM_get_BN(param_e, &e))) { + if ((p->n == NULL || !OSSL_PARAM_get_BN(p->n, &n)) + || (p->e == NULL || !OSSL_PARAM_get_BN(p->e, &e))) { ERR_raise(ERR_LIB_RSA, ERR_R_PASSED_NULL_PARAMETER); goto err; } if (include_private) { - - param_derive = OSSL_PARAM_locate_const(params, - OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ); - if ((param_derive != NULL) - && !OSSL_PARAM_get_int(param_derive, &derive_from_pq)) + if ((p->derive != NULL) + && !OSSL_PARAM_get_int(p->derive, &derive_from_pq)) goto err; - param_d = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_D); - if (param_d != NULL && !OSSL_PARAM_get_BN(param_d, &d)) { + if (p->d != NULL && !OSSL_PARAM_get_BN(p->d, &d)) { ERR_raise(ERR_LIB_RSA, ERR_R_PASSED_NULL_PARAMETER); goto err; } @@ -103,8 +94,7 @@ int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[], int include_private) goto err; /* we need at minimum p, q */ - if (OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR1) == NULL - || OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_FACTOR2) == NULL) { + if (p->mp.factors[0] == NULL || p->mp.factors[1] == NULL) { ERR_raise(ERR_LIB_RSA, ERR_R_PASSED_NULL_PARAMETER); goto err; } @@ -118,12 +108,12 @@ int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[], int include_private) n = e = d = NULL; if (is_private) { - if (!collect_numbers(factors = sk_BIGNUM_new_null(), params, - ossl_rsa_mp_factor_names) - || !collect_numbers(exps = sk_BIGNUM_new_null(), params, - ossl_rsa_mp_exp_names) - || !collect_numbers(coeffs = sk_BIGNUM_new_null(), params, - ossl_rsa_mp_coeff_names)) + if (!collect_numbers(factors = sk_BIGNUM_new_null(), p->mp.factors, + OSSL_NELEM(p->mp.factors)) + || !collect_numbers(exps = sk_BIGNUM_new_null(), p->mp.exps, + OSSL_NELEM(p->mp.exps)) + || !collect_numbers(coeffs = sk_BIGNUM_new_null(), p->mp.coeffs, + OSSL_NELEM(p->mp.coeffs))) goto err; if (derive_from_pq && sk_BIGNUM_num(exps) == 0 @@ -142,7 +132,7 @@ int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[], int include_private) * been provided */ if (sk_BIGNUM_num(factors) > 2 - && (param_n == NULL || param_d == NULL)) { + && (p->n == NULL || p->d == NULL)) { ERR_raise(ERR_LIB_RSA, ERR_R_PASSED_NULL_PARAMETER); goto err; } @@ -180,10 +170,7 @@ int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[], int include_private) * in the multiprime case we have to generate exps/coeffs here * for each additional prime */ - if (!ossl_rsa_multiprime_derive(rsa, RSA_bits(rsa), - sk_BIGNUM_num(factors), - rsa->e, factors, exps, - coeffs)) { + if (!ossl_rsa_multiprime_derive(rsa, factors, exps, coeffs)) { ERR_raise(ERR_LIB_RSA, ERR_R_INTERNAL_ERROR); goto err; } @@ -248,10 +235,38 @@ int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[], int include_private) return 0; } +int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[], + int include_private) +{ + RSA_PARAMS p; + + if (!rsa_key_fromdata_decoder(params, &p)) + return 0; + return ossl_rsa_fromdata_parsed(rsa, &p, include_private); +} + DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) -int ossl_rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[], - int include_private) +static int rsa_set_multi_key_bn(OSSL_PARAM_BLD *bld, + OSSL_PARAM *const params[], size_t num_params, const char *names[], + STACK_OF(BIGNUM_const) *numbers) +{ + int i, num_numbers = sk_BIGNUM_const_num(numbers); + + for (i = 0; i < num_numbers && (size_t)i < num_params + && names[i] != NULL; + i++) { + const BIGNUM *bn = sk_BIGNUM_const_value(numbers, i); + OSSL_PARAM *p = bld == NULL ? params[i] : NULL; + + if (bn != NULL && !ossl_param_build_set_bn(bld, p, names[i], bn)) + return 0; + } + return 1; +} + +int ossl_rsa_todata_parsed(RSA *rsa, OSSL_PARAM_BLD *bld, + const RSA_PARAMS *p, int include_private) { int ret = 0; const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL; @@ -259,36 +274,42 @@ int ossl_rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[], STACK_OF(BIGNUM_const) *exps = sk_BIGNUM_const_new_null(); STACK_OF(BIGNUM_const) *coeffs = sk_BIGNUM_const_new_null(); - if (rsa == NULL || factors == NULL || exps == NULL || coeffs == NULL) + if (rsa == NULL || (bld == NULL && p == NULL) + || factors == NULL || exps == NULL || coeffs == NULL) goto err; RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); ossl_rsa_get0_all_params(rsa, factors, exps, coeffs); - if (!ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_N, rsa_n) - || !ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_E, rsa_e)) + if (!ossl_param_build_set_bn(bld, p == NULL ? NULL : p->n, + OSSL_PKEY_PARAM_RSA_N, rsa_n) + || !ossl_param_build_set_bn(bld, p == NULL ? NULL : p->e, + OSSL_PKEY_PARAM_RSA_E, rsa_e)) goto err; /* Check private key data integrity */ if (include_private && rsa_d != NULL) { - if (!ossl_param_build_set_bn(bld, params, OSSL_PKEY_PARAM_RSA_D, + if (!ossl_param_build_set_bn(bld, p == NULL ? NULL : p->d, + OSSL_PKEY_PARAM_RSA_D, rsa_d) - || !ossl_param_build_set_multi_key_bn(bld, params, - ossl_rsa_mp_factor_names, - factors) - || !ossl_param_build_set_multi_key_bn(bld, params, - ossl_rsa_mp_exp_names, exps) - || !ossl_param_build_set_multi_key_bn(bld, params, - ossl_rsa_mp_coeff_names, - coeffs)) + || !rsa_set_multi_key_bn(bld, + p == NULL ? NULL : p->mp.factors, + OSSL_RSA_PARAM_MAX_PRIMES, ossl_rsa_mp_factor_names, factors) + || !rsa_set_multi_key_bn(bld, + p == NULL ? NULL : p->mp.exps, + OSSL_RSA_PARAM_MAX_PRIMES, ossl_rsa_mp_exp_names, exps) + || !rsa_set_multi_key_bn(bld, + p == NULL ? NULL : p->mp.coeffs, + OSSL_RSA_PARAM_MAX_PRIMES - 1, + ossl_rsa_mp_coeff_names, coeffs)) goto err; } #if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) /* The acvp test results are not meant for export so check for bld == NULL */ if (bld == NULL) - ossl_rsa_acvp_test_get_params(rsa, params); + ossl_rsa_acvp_test_get_params_parsed(rsa, p); #endif ret = 1; err: @@ -298,9 +319,25 @@ int ossl_rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[], return ret; } -int ossl_rsa_pss_params_30_todata(const RSA_PSS_PARAMS_30 *pss, - OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) +int ossl_rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[], + int include_private) +{ + RSA_PARAMS p; + + if (params != NULL) { + if (!rsa_key_todata_decoder(params, &p)) + return 0; + return ossl_rsa_todata_parsed(rsa, bld, &p, include_private); + } + return ossl_rsa_todata_parsed(rsa, bld, NULL, include_private); +} + +int ossl_rsa_pss_params_30_todata_parsed(const RSA_PSS_PARAMS_30 *pss, + OSSL_PARAM_BLD *bld, const RSA_PARAMS *p) { + if (bld == NULL && p == NULL) + return 0; + if (!ossl_rsa_pss_params_30_is_unrestricted(pss)) { int hashalg_nid = ossl_rsa_pss_params_30_hashalg(pss); int maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(pss); @@ -329,42 +366,52 @@ int ossl_rsa_pss_params_30_todata(const RSA_PSS_PARAMS_30 *pss, * if it has a default value; saltlen. */ if ((mdname != NULL - && !ossl_param_build_set_utf8_string(bld, params, key_md, mdname)) + && !ossl_param_build_set_utf8_string(bld, + p == NULL ? NULL : p->digest, key_md, mdname)) || (mgfname != NULL - && !ossl_param_build_set_utf8_string(bld, params, - key_mgf, mgfname)) + && !ossl_param_build_set_utf8_string(bld, + p == NULL ? NULL : p->maskgenfunc, key_mgf, mgfname)) || (mgf1mdname != NULL - && !ossl_param_build_set_utf8_string(bld, params, + && !ossl_param_build_set_utf8_string(bld, + p == NULL ? NULL : p->mgf1_digest, key_mgf1_md, mgf1mdname)) - || (!ossl_param_build_set_int(bld, params, key_saltlen, saltlen))) + || (!ossl_param_build_set_int(bld, + p == NULL ? NULL : p->pss_saltlen, + key_saltlen, saltlen))) return 0; } return 1; } -int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, - int *defaults_set, - const OSSL_PARAM params[], - OSSL_LIB_CTX *libctx) +int ossl_rsa_pss_params_30_todata(const RSA_PSS_PARAMS_30 *pss, + OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) +{ + RSA_PARAMS p; + + if (params != NULL) { + if (!rsa_pss_todata_decoder(params, &p)) + return 0; + return ossl_rsa_pss_params_30_todata_parsed(pss, bld, &p); + } + return ossl_rsa_pss_params_30_todata_parsed(pss, bld, NULL); +} + +int ossl_rsa_pss_params_30_fromdata_parsed(RSA_PSS_PARAMS_30 *pss_params, + int *defaults_set, const RSA_PARAMS *p, OSSL_LIB_CTX *libctx) { - const OSSL_PARAM *param_md, *param_mgf, *param_mgf1md, *param_saltlen; - const OSSL_PARAM *param_propq; const char *propq = NULL; EVP_MD *md = NULL, *mgf1md = NULL; int saltlen; int ret = 0; - if (pss_params == NULL) + if (pss_params == NULL || defaults_set == NULL || p == NULL) return 0; - param_propq = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_DIGEST_PROPS); - param_md = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_DIGEST); - param_mgf = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_MASKGENFUNC); - param_mgf1md = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_MGF1_DIGEST); - param_saltlen = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_PSS_SALTLEN); - - if (param_propq != NULL) { - if (param_propq->data_type == OSSL_PARAM_UTF8_STRING) - propq = param_propq->data; + + if (p->digest_props != NULL) { + if (p->digest_props->data_type == OSSL_PARAM_UTF8_STRING) + propq = p->digest_props->data; + else if (!OSSL_PARAM_get_utf8_ptr(p->digest_props, &propq)) + return 0; } /* * If we get any of the parameters, we know we have at least some @@ -372,25 +419,26 @@ int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, * parameter override their specific restriction data. */ if (!*defaults_set - && (param_md != NULL || param_mgf != NULL || param_mgf1md != NULL - || param_saltlen != NULL)) { + && (p->digest != NULL || p->maskgenfunc != NULL || p->mgf1_digest != NULL + || p->pss_saltlen != NULL)) { if (!ossl_rsa_pss_params_30_set_defaults(pss_params)) return 0; *defaults_set = 1; } - if (param_mgf != NULL) { + if (p->maskgenfunc != NULL) { int default_maskgenalg_nid = ossl_rsa_pss_params_30_maskgenalg(NULL); const char *mgfname = NULL; - if (param_mgf->data_type == OSSL_PARAM_UTF8_STRING) - mgfname = param_mgf->data; - else if (!OSSL_PARAM_get_utf8_ptr(param_mgf, &mgfname)) + if (p->maskgenfunc->data_type == OSSL_PARAM_UTF8_STRING) + mgfname = p->maskgenfunc->data; + else if (!OSSL_PARAM_get_utf8_ptr(p->maskgenfunc, &mgfname)) return 0; - if (OPENSSL_strcasecmp(param_mgf->data, - ossl_rsa_mgf_nid2name(default_maskgenalg_nid)) - != 0) + if (mgfname == NULL + || OPENSSL_strcasecmp(mgfname, + ossl_rsa_mgf_nid2name(default_maskgenalg_nid)) + != 0) return 0; } @@ -399,12 +447,12 @@ int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, * exact propquery is unimportant in the EVP_MD_fetch() calls below. */ - if (param_md != NULL) { + if (p->digest != NULL) { const char *mdname = NULL; - if (param_md->data_type == OSSL_PARAM_UTF8_STRING) - mdname = param_md->data; - else if (!OSSL_PARAM_get_utf8_ptr(param_mgf, &mdname)) + if (p->digest->data_type == OSSL_PARAM_UTF8_STRING) + mdname = p->digest->data; + else if (!OSSL_PARAM_get_utf8_ptr(p->digest, &mdname)) goto err; if ((md = EVP_MD_fetch(libctx, mdname, propq)) == NULL @@ -413,12 +461,12 @@ int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, goto err; } - if (param_mgf1md != NULL) { + if (p->mgf1_digest != NULL) { const char *mgf1mdname = NULL; - if (param_mgf1md->data_type == OSSL_PARAM_UTF8_STRING) - mgf1mdname = param_mgf1md->data; - else if (!OSSL_PARAM_get_utf8_ptr(param_mgf, &mgf1mdname)) + if (p->mgf1_digest->data_type == OSSL_PARAM_UTF8_STRING) + mgf1mdname = p->mgf1_digest->data; + else if (!OSSL_PARAM_get_utf8_ptr(p->mgf1_digest, &mgf1mdname)) goto err; if ((mgf1md = EVP_MD_fetch(libctx, mgf1mdname, propq)) == NULL @@ -427,8 +475,8 @@ int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, goto err; } - if (param_saltlen != NULL) { - if (!OSSL_PARAM_get_int(param_saltlen, &saltlen) + if (p->pss_saltlen != NULL) { + if (!OSSL_PARAM_get_int(p->pss_saltlen, &saltlen) || !ossl_rsa_pss_params_30_set_saltlen(pss_params, saltlen)) goto err; } @@ -441,6 +489,17 @@ int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, return ret; } +int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, + int *defaults_set, const OSSL_PARAM params[], OSSL_LIB_CTX *libctx) +{ + RSA_PARAMS p; + + if (!rsa_pss_fromdata_decoder(params, &p)) + return 0; + return ossl_rsa_pss_params_30_fromdata_parsed(pss_params, defaults_set, + &p, libctx); +} + int ossl_rsa_is_foreign(const RSA *rsa) { #ifndef FIPS_MODULE diff --git a/crypto/rsa/rsa_err.c b/crypto/rsa/rsa_err.c deleted file mode 100644 index aced712b1de16..0000000000000 --- a/crypto/rsa/rsa_err.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/rsaerr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA RSA_str_reasons[] = { - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_ALGORITHM_MISMATCH), "algorithm mismatch" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_E_VALUE), "bad e value" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_FIXED_HEADER_DECRYPT), - "bad fixed header decrypt" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_PAD_BYTE_COUNT), "bad pad byte count" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BAD_SIGNATURE), "bad signature" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BLOCK_TYPE_IS_NOT_01), - "block type is not 01" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_BLOCK_TYPE_IS_NOT_02), - "block type is not 02" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_GREATER_THAN_MOD_LEN), - "data greater than mod len" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_LARGE), "data too large" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), - "data too large for key size" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_LARGE_FOR_MODULUS), - "data too large for modulus" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_SMALL), "data too small" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE), - "data too small for key size" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DIGEST_DOES_NOT_MATCH), - "digest does not match" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DIGEST_NOT_ALLOWED), "digest not allowed" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY), - "digest too big for rsa key" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DMP1_NOT_CONGRUENT_TO_D), - "dmp1 not congruent to d" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_DMQ1_NOT_CONGRUENT_TO_D), - "dmq1 not congruent to d" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_D_E_NOT_CONGRUENT_TO_1), - "d e not congruent to 1" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_FIRST_OCTET_INVALID), - "first octet invalid" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE), - "illegal or unsupported padding mode" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_DIGEST), "invalid digest" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_DIGEST_LENGTH), - "invalid digest length" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_HEADER), "invalid header" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_KEYPAIR), "invalid keypair" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_KEY_LENGTH), "invalid key length" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_LABEL), "invalid label" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_LENGTH), "invalid length" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_MESSAGE_LENGTH), - "invalid message length" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_MGF1_MD), "invalid mgf1 md" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_MODULUS), "invalid modulus" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_MULTI_PRIME_KEY), - "invalid multi prime key" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_OAEP_PARAMETERS), - "invalid oaep parameters" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_PADDING), "invalid padding" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_PADDING_MODE), - "invalid padding mode" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_PSS_PARAMETERS), - "invalid pss parameters" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_PSS_SALTLEN), - "invalid pss saltlen" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_REQUEST), "invalid request" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_SALT_LENGTH), - "invalid salt length" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_STRENGTH), "invalid strength" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_TRAILER), "invalid trailer" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_INVALID_X931_DIGEST), - "invalid x931 digest" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_IQMP_NOT_INVERSE_OF_Q), - "iqmp not inverse of q" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_KEY_PRIME_NUM_INVALID), - "key prime num invalid" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_KEY_SIZE_TOO_SMALL), "key size too small" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_LAST_OCTET_INVALID), "last octet invalid" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MGF1_DIGEST_NOT_ALLOWED), - "mgf1 digest not allowed" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MISSING_PRIVATE_KEY), - "missing private key" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MODULUS_TOO_LARGE), "modulus too large" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R), - "mp coefficient not inverse of r" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D), - "mp exponent not congruent to d" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_MP_R_NOT_PRIME), "mp r not prime" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NO_PUBLIC_EXPONENT), "no public exponent" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_NULL_BEFORE_BLOCK_MISSING), - "null before block missing" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES), - "n does not equal product of primes" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_N_DOES_NOT_EQUAL_P_Q), - "n does not equal p q" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OAEP_DECODING_ERROR), - "oaep decoding error" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), - "operation not supported for this keytype" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PADDING_CHECK_FAILED), - "padding check failed" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PAIRWISE_TEST_FAILURE), - "pairwise test failure" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PKCS_DECODING_ERROR), - "pkcs decoding error" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PSS_SALTLEN_TOO_SMALL), - "pss saltlen too small" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_PUB_EXPONENT_OUT_OF_RANGE), - "pub exponent out of range" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_P_NOT_PRIME), "p not prime" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_Q_NOT_PRIME), "q not prime" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT), - "randomness source strength insufficient" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED), - "rsa operations not supported" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_SLEN_CHECK_FAILED), - "salt length check failed" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_SLEN_RECOVERY_FAILED), - "salt length recovery failed" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD), - "the asn1 object identifier is not known for this md" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNKNOWN_ALGORITHM_TYPE), - "unknown algorithm type" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNKNOWN_DIGEST), "unknown digest" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNKNOWN_MASK_DIGEST), - "unknown mask digest" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNKNOWN_PADDING_TYPE), - "unknown padding type" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_ENCRYPTION_TYPE), - "unsupported encryption type" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_LABEL_SOURCE), - "unsupported label source" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_MASK_ALGORITHM), - "unsupported mask algorithm" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_MASK_PARAMETER), - "unsupported mask parameter" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_UNSUPPORTED_SIGNATURE_TYPE), - "unsupported signature type" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_VALUE_MISSING), "value missing" }, - { ERR_PACK(ERR_LIB_RSA, 0, RSA_R_WRONG_SIGNATURE_LENGTH), - "wrong signature length" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_RSA_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(RSA_str_reasons[0].error) == NULL) - ERR_load_strings_const(RSA_str_reasons); -#endif - return 1; -} diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c index df44f50a768d6..bd481f7b08dcd 100644 --- a/crypto/rsa/rsa_gen.c +++ b/crypto/rsa/rsa_gen.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -87,8 +87,7 @@ DEFINE_STACK_OF(BIGNUM) * on their respective exps and coeffs stacks */ #ifndef FIPS_MODULE -int ossl_rsa_multiprime_derive(RSA *rsa, int bits, int primes, - BIGNUM *e_value, +int ossl_rsa_multiprime_derive(RSA *rsa, STACK_OF(BIGNUM) *factors, STACK_OF(BIGNUM) *exps, STACK_OF(BIGNUM) *coeffs) @@ -568,8 +567,7 @@ static int rsa_multiprime_keygen(RSA *rsa, int bits, int primes, } /* derive any missing exponents and coefficients */ - if (!ossl_rsa_multiprime_derive(rsa, bits, primes, e_value, - factors, exps, coeffs)) + if (!ossl_rsa_multiprime_derive(rsa, factors, exps, coeffs)) goto err; /* diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index a7d5798c885a1..879974c96e43c 100644 --- a/crypto/rsa/rsa_lib.c +++ b/crypto/rsa/rsa_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -163,7 +163,7 @@ int RSA_up_ref(RSA *r) { int i; - if (CRYPTO_UP_REF(&r->references, &i) <= 0) + if (!CRYPTO_UP_REF(&r->references, &i)) return 0; REF_PRINT_COUNT("RSA", i, r); diff --git a/crypto/rsa/rsa_local.h b/crypto/rsa/rsa_local.h index 7ea7ee6541445..564240f570f4a 100644 --- a/crypto/rsa/rsa_local.h +++ b/crypto/rsa/rsa_local.h @@ -146,8 +146,7 @@ struct rsa_meth_st { /* Macro to test if a pkey is for a PSS key */ #define pkey_is_pss(pkey) (pkey->ameth->pkey_id == EVP_PKEY_RSA_PSS) -int ossl_rsa_multiprime_derive(RSA *rsa, int bits, int primes, - BIGNUM *e_value, +int ossl_rsa_multiprime_derive(RSA *rsa, STACK_OF(BIGNUM) *factors, STACK_OF(BIGNUM) *exps, STACK_OF(BIGNUM) *coeffs); diff --git a/crypto/rsa/rsa_ossl.c b/crypto/rsa/rsa_ossl.c index 674ee4b10d755..f444e98e61aba 100644 --- a/crypto/rsa/rsa_ossl.c +++ b/crypto/rsa/rsa_ossl.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -167,6 +167,14 @@ static int rsa_ossl_public_encrypt(int flen, const unsigned char *from, * See SP800-56Br2, section 7.1.1.1 * RSAEP: 1 < f < (n – 1). * (where f is the plaintext). + * + * This bound is somewhat overkill here. RSASVE.GENERATE (7.2.1.2) + * regenerates z until 1 < z < n-1, so on that path the plaintext is in + * range unconditionally. On the OAEP path the leading 0x00 octet of the + * encoding forces m < n-1 unconditionally, while m = 0 or 1 is only + * cryptographically negligible, not impossible. The check is kept to + * mirror the RSADP bound in rsa_ossl_private_decrypt() and to keep RSAEP + * faithful to 7.1.1 of the SP; nothing in the SP relies on it here. */ if (padding == RSA_NO_PADDING) { BIGNUM *nminus1 = BN_CTX_get(ctx); @@ -569,6 +577,12 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from, * See SP800-56Br2, section 7.1.2.1 * RSADP: 1 < f < (n – 1) * (where f is the ciphertext). + * + * Kept under FIPS_MODULE because SP 800-56B KTS-OAEP (section 9.2) also + * decrypts through RSADP and needs this bound in a FIPS build, and there + * is no KTS-OAEP-specific path to attach it to. The non-FIPS RSASVE path + * applies the same 1 < c < n-1 in rsasve_recover() + * (providers/implementations/kem/rsa_kem.c); keep the two in step. */ if (padding == RSA_NO_PADDING) { BIGNUM *nminus1 = BN_CTX_get(ctx); diff --git a/crypto/rsa/rsa_sp800_56b_check.c b/crypto/rsa/rsa_sp800_56b_check.c index b9f39dd091b9c..bdaf20530ac17 100644 --- a/crypto/rsa/rsa_sp800_56b_check.c +++ b/crypto/rsa/rsa_sp800_56b_check.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2018-2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/s390xcap.c b/crypto/s390xcap.c index 2d2d4b9f3bf9f..54db50c39b223 100644 --- a/crypto/s390xcap.c +++ b/crypto/s390xcap.c @@ -1,5 +1,5 @@ /* - * Copyright 2010-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2010-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/s390xcpuid.pl b/crypto/s390xcpuid.pl index dce17a3bfac88..098f958f84733 100755 --- a/crypto/s390xcpuid.pl +++ b/crypto/s390xcpuid.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2009-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2009-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/keccak1600-armv4.pl b/crypto/sha/asm/keccak1600-armv4.pl index 896ce6ec5bd7d..6414ef5cfe0c7 100755 --- a/crypto/sha/asm/keccak1600-armv4.pl +++ b/crypto/sha/asm/keccak1600-armv4.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/keccak1600-armv8.pl b/crypto/sha/asm/keccak1600-armv8.pl index 48247dcd27bf4..3bda2fd727c11 100755 --- a/crypto/sha/asm/keccak1600-armv8.pl +++ b/crypto/sha/asm/keccak1600-armv8.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/keccak1600-avx512.pl b/crypto/sha/asm/keccak1600-avx512.pl index 1b40130a6eebe..465479ab66482 100755 --- a/crypto/sha/asm/keccak1600-avx512.pl +++ b/crypto/sha/asm/keccak1600-avx512.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/keccak1600-s390x.pl b/crypto/sha/asm/keccak1600-s390x.pl index 696dcbb863845..fda541fbfa2a3 100755 --- a/crypto/sha/asm/keccak1600-s390x.pl +++ b/crypto/sha/asm/keccak1600-s390x.pl @@ -1,5 +1,5 @@ #!/usr/bin/env perl -# Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha1-586.pl b/crypto/sha/asm/sha1-586.pl index 277c33ea7fb31..91e5f5612b858 100644 --- a/crypto/sha/asm/sha1-586.pl +++ b/crypto/sha/asm/sha1-586.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 1998-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1998-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha1-armv4-large.pl b/crypto/sha/asm/sha1-armv4-large.pl index 38f5ae988d744..e9abf95d704e2 100644 --- a/crypto/sha/asm/sha1-armv4-large.pl +++ b/crypto/sha/asm/sha1-armv4-large.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha1-armv8.pl b/crypto/sha/asm/sha1-armv8.pl index 4eeec6b0b272a..b71321783f86d 100644 --- a/crypto/sha/asm/sha1-armv8.pl +++ b/crypto/sha/asm/sha1-armv8.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2014-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2014-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha1-mb-x86_64.pl b/crypto/sha/asm/sha1-mb-x86_64.pl index 5a8c0755e1714..9f57342152b0d 100644 --- a/crypto/sha/asm/sha1-mb-x86_64.pl +++ b/crypto/sha/asm/sha1-mb-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2013-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2013-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha1-mips.pl b/crypto/sha/asm/sha1-mips.pl index c60791b17540b..63f1200c0ad5e 100644 --- a/crypto/sha/asm/sha1-mips.pl +++ b/crypto/sha/asm/sha1-mips.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2009-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2009-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha1-s390x.pl b/crypto/sha/asm/sha1-s390x.pl index 448b4a8848522..731143ca90e06 100644 --- a/crypto/sha/asm/sha1-s390x.pl +++ b/crypto/sha/asm/sha1-s390x.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha1-sparcv9.pl b/crypto/sha/asm/sha1-sparcv9.pl index 24ee48222af78..72ef0fb989f4e 100644 --- a/crypto/sha/asm/sha1-sparcv9.pl +++ b/crypto/sha/asm/sha1-sparcv9.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha1-x86_64.pl b/crypto/sha/asm/sha1-x86_64.pl index af9d172153b5b..62823574d3555 100755 --- a/crypto/sha/asm/sha1-x86_64.pl +++ b/crypto/sha/asm/sha1-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha256-586.pl b/crypto/sha/asm/sha256-586.pl index 68a9fa9e6481e..3cf8e1217a159 100644 --- a/crypto/sha/asm/sha256-586.pl +++ b/crypto/sha/asm/sha256-586.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha256-armv4.pl b/crypto/sha/asm/sha256-armv4.pl index 1bcf7cea4fda3..a874eac9a4c6c 100644 --- a/crypto/sha/asm/sha256-armv4.pl +++ b/crypto/sha/asm/sha256-armv4.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha256-loongarch64.pl b/crypto/sha/asm/sha256-loongarch64.pl index 3cba5ba258f0a..cb8dd97be8b61 100644 --- a/crypto/sha/asm/sha256-loongarch64.pl +++ b/crypto/sha/asm/sha256-loongarch64.pl @@ -2,7 +2,7 @@ # This file is dual-licensed, meaning that you can use it under your # choice of either of the following two licenses: # -# Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You can obtain # a copy in the file LICENSE in the source distribution or at diff --git a/crypto/sha/asm/sha256-mb-x86_64.pl b/crypto/sha/asm/sha256-mb-x86_64.pl index 0175f5b36f4d0..d43d31b4510b6 100644 --- a/crypto/sha/asm/sha256-mb-x86_64.pl +++ b/crypto/sha/asm/sha256-mb-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2013-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2013-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha512-armv4.pl b/crypto/sha/asm/sha512-armv4.pl index 619cb36516cfa..8c65869c09610 100644 --- a/crypto/sha/asm/sha512-armv4.pl +++ b/crypto/sha/asm/sha512-armv4.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha512-armv8.pl b/crypto/sha/asm/sha512-armv8.pl index 66c29a5eef9e9..497091982631f 100644 --- a/crypto/sha/asm/sha512-armv8.pl +++ b/crypto/sha/asm/sha512-armv8.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2014-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2014-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha512-loongarch64.pl b/crypto/sha/asm/sha512-loongarch64.pl index 44d1736586a56..82e6244963581 100644 --- a/crypto/sha/asm/sha512-loongarch64.pl +++ b/crypto/sha/asm/sha512-loongarch64.pl @@ -2,7 +2,7 @@ # This file is dual-licensed, meaning that you can use it under your # choice of either of the following two licenses: # -# Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You can obtain # a copy in the file LICENSE in the source distribution or at diff --git a/crypto/sha/asm/sha512-mips.pl b/crypto/sha/asm/sha512-mips.pl index cbca8163a0ba4..1d01da6617e29 100644 --- a/crypto/sha/asm/sha512-mips.pl +++ b/crypto/sha/asm/sha512-mips.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2010-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2010-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha512-s390x.pl b/crypto/sha/asm/sha512-s390x.pl index 7d57eaaa47e71..aa659dc996e54 100644 --- a/crypto/sha/asm/sha512-s390x.pl +++ b/crypto/sha/asm/sha512-s390x.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha512-sparcv9.pl b/crypto/sha/asm/sha512-sparcv9.pl index b2c64c7a3f75c..cc05c7bbc3499 100644 --- a/crypto/sha/asm/sha512-sparcv9.pl +++ b/crypto/sha/asm/sha512-sparcv9.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/asm/sha512-x86_64.pl b/crypto/sha/asm/sha512-x86_64.pl index 4db4b1beb08f5..1842718d8e0e0 100755 --- a/crypto/sha/asm/sha512-x86_64.pl +++ b/crypto/sha/asm/sha512-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/keccak1600.c b/crypto/sha/keccak1600.c index 26d75f1b8e0d0..b4cbd6b56375e 100644 --- a/crypto/sha/keccak1600.c +++ b/crypto/sha/keccak1600.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/sha1dgst.c b/crypto/sha/sha1dgst.c index 3fe0aebfffa16..88437ba0bc7de 100644 --- a/crypto/sha/sha1dgst.c +++ b/crypto/sha/sha1dgst.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/sha512.c b/crypto/sha/sha512.c index 9ba32f2926424..637eac146fe20 100644 --- a/crypto/sha/sha512.c +++ b/crypto/sha/sha512.c @@ -60,7 +60,7 @@ #include "internal/cryptlib.h" #include "crypto/sha.h" -#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || defined(__s390__) || defined(__s390x__) || defined(__aarch64__) || defined(SHA512_ASM) +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || defined(__s390__) || defined(__s390x__) || defined(__aarch64__) || defined(__e2k__) || defined(SHA512_ASM) #define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA #endif @@ -405,6 +405,11 @@ static const SHA_LONG64 K512[80] = { asm ("rev8 %0, %1" \ : "=r"(ret) \ : "r"(x)); ret; }) +#elif defined(__e2k__) +#include +#define PULL64(x) __builtin_bswap64(x) +#define ROTR(x, s) ((s) > 48 ? __rolq((x), 64 - (s)) \ + : __rorq((x), (s))) #endif #if defined(__riscv_zknh) && __riscv_xlen == 32 #define Sigma0(x) ({ SHA_LONG64 ret; unsigned int *r = (unsigned int *)(&(ret)); \ @@ -487,6 +492,9 @@ static const SHA_LONG64 K512[80] = { asm (".insn r4 0x33, 1, 0x3, %0, %2, %1, %3"\ : "=r"(ret) \ : "r"(x^z), "r"(y), "r"(x)); ret; }) +#elif defined(__e2k__) && __iset__ >= 5 +#define sigma0(x) (__builtin_e2k_plog(0x96, ROTR((x), 1), ROTR((x), 8), ((x) >> 7))) +#define sigma1(x) (__builtin_e2k_plog(0x96, ROTR((x), 19), ROTR((x), 61), ((x) >> 6))) #endif #elif defined(_MSC_VER) #if defined(_WIN64) /* applies to both IA-64 and AMD64 */ diff --git a/crypto/sha/sha_loongarch.c b/crypto/sha/sha_loongarch.c index 55ececfe04108..f04eb5aa5155e 100644 --- a/crypto/sha/sha_loongarch.c +++ b/crypto/sha/sha_loongarch.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -16,9 +16,9 @@ void sha256_block_data_order_la64v100(void *ctx, const void *in, size_t num); void sha256_block_data_order_lsx(void *ctx, const void *in, size_t num); -void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num); +void sha256_block_data_order(void *ctx, const void *in, size_t num); -void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num) +void sha256_block_data_order(void *ctx, const void *in, size_t num) { if (OPENSSL_loongarch_hwcap_P & LOONGARCH_HWCAP_LSX) { sha256_block_data_order_lsx(ctx, in, num); @@ -29,9 +29,9 @@ void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num) void sha512_block_data_order_la64v100(void *ctx, const void *in, size_t num); void sha512_block_data_order_lsx(void *ctx, const void *in, size_t num); -void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num); +void sha512_block_data_order(void *ctx, const void *in, size_t num); -void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num) +void sha512_block_data_order(void *ctx, const void *in, size_t num) { if (OPENSSL_loongarch_hwcap_P & LOONGARCH_HWCAP_LSX) { sha512_block_data_order_lsx(ctx, in, num); diff --git a/crypto/sha/sha_ppc.c b/crypto/sha/sha_ppc.c index 0e5c5c57092cd..46372de183f67 100644 --- a/crypto/sha/sha_ppc.c +++ b/crypto/sha/sha_ppc.c @@ -1,5 +1,5 @@ /* - * Copyright 2009-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2009-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sha/sha_riscv.c b/crypto/sha/sha_riscv.c index 28248fd5ac07e..f2e17a3e5e9ae 100644 --- a/crypto/sha/sha_riscv.c +++ b/crypto/sha/sha_riscv.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -18,9 +18,9 @@ void sha256_block_data_order_zvkb_zvknha_or_zvknhb(void *ctx, const void *in, size_t num); void sha256_block_data_order_zbb(void *ctx, const void *in, size_t num); void sha256_block_data_order_riscv64(void *ctx, const void *in, size_t num); -void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num); +void sha256_block_data_order(void *ctx, const void *in, size_t num); -void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num) +void sha256_block_data_order(void *ctx, const void *in, size_t num) { if (RISCV_HAS_ZVKB() && (RISCV_HAS_ZVKNHA() || RISCV_HAS_ZVKNHB()) && riscv_vlen() >= 128) { sha256_block_data_order_zvkb_zvknha_or_zvknhb(ctx, in, num); @@ -34,9 +34,9 @@ void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num) void sha512_block_data_order_zvkb_zvknhb(void *ctx, const void *in, size_t num); void sha512_block_data_order_zbb(void *ctx, const void *in, size_t num); void sha512_block_data_order_c(void *ctx, const void *in, size_t num); -void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num); +void sha512_block_data_order(void *ctx, const void *in, size_t num); -void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num) +void sha512_block_data_order(void *ctx, const void *in, size_t num) { if (RISCV_HAS_ZVKB_AND_ZVKNHB() && riscv_vlen() >= 128) { sha512_block_data_order_zvkb_zvknhb(ctx, in, num); diff --git a/crypto/sleep.c b/crypto/sleep.c index 3d8be852c9106..fbe9450bb6000 100644 --- a/crypto/sleep.c +++ b/crypto/sleep.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/slh_dsa/slh_adrs.h b/crypto/slh_dsa/slh_adrs.h index f07d7e8b559e5..d41f396208645 100644 --- a/crypto/slh_dsa/slh_adrs.h +++ b/crypto/slh_dsa/slh_adrs.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/slh_dsa/slh_dsa.c b/crypto/slh_dsa/slh_dsa.c index 6519e8640fb18..4cf75089920a0 100644 --- a/crypto/slh_dsa/slh_dsa.c +++ b/crypto/slh_dsa/slh_dsa.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,6 +8,7 @@ */ #include #include +#include #include #include #include "slh_dsa_local.h" @@ -122,8 +123,13 @@ static int slh_sign_internal(SLH_DSA_HASH_CTX *hctx, err: if (!WPACKET_finish(wpkt)) ret = 0; + OPENSSL_cleanse(m_digest, sizeof(m_digest)); + OPENSSL_cleanse(pk_fors, sizeof(pk_fors)); if (ret) *sig_len = sig_len_expected; + else + /* Erase any partial signature output */ + OPENSSL_cleanse(sig, sig_len_expected); return ret; } @@ -148,6 +154,7 @@ static int slh_verify_internal(SLH_DSA_HASH_CTX *hctx, const uint8_t *msg, size_t msg_len, const uint8_t *sig, size_t sig_len) { + int ret = 0; const SLH_DSA_KEY *pub = hctx->key; SLH_HASH_FUNC_DECLARE(pub, hashf); SLH_ADRS_FUNC_DECLARE(pub, adrsf); @@ -185,7 +192,7 @@ static int slh_verify_internal(SLH_DSA_HASH_CTX *hctx, if (!hashf->H_MSG(hctx, r, pk_seed, pk_root, msg, msg_len, m_digest, sizeof(m_digest))) - return 0; + goto err; /* * Get md (the first md_len bytes of m_digest to use in @@ -195,16 +202,20 @@ static int slh_verify_internal(SLH_DSA_HASH_CTX *hctx, if (!PACKET_buf_init(m_digest_rpkt, m_digest, sizeof(m_digest)) || !PACKET_get_bytes(m_digest_rpkt, &md, md_len) || !get_tree_ids(m_digest_rpkt, params, &tree_id, &leaf_id)) - return 0; + goto err; adrsf->set_tree_address(adrs, tree_id); adrsf->set_type_and_clear(adrs, SLH_ADRS_TYPE_FORS_TREE); adrsf->set_keypair_address(adrs, leaf_id); - return ossl_slh_fors_pk_from_sig(hctx, sig_rpkt, md, pk_seed, adrs, - pk_fors, sizeof(pk_fors)) + ret = ossl_slh_fors_pk_from_sig(hctx, sig_rpkt, md, pk_seed, adrs, + pk_fors, sizeof(pk_fors)) && ossl_slh_ht_verify(hctx, pk_fors, sig_rpkt, pk_seed, tree_id, leaf_id, pk_root) && PACKET_remaining(sig_rpkt) == 0; +err: + OPENSSL_cleanse(m_digest, sizeof(m_digest)); + OPENSSL_cleanse(pk_fors, sizeof(pk_fors)); + return ret; } /** @@ -292,8 +303,13 @@ int ossl_slh_dsa_sign(SLH_DSA_HASH_CTX *slh_ctx, return 0; } ret = slh_sign_internal(slh_ctx, m, m_len, sig, siglen, sigsize, add_rand); - if (m != msg && m != m_tmp) - OPENSSL_free(m); + /* The encoded message may contain confidential message content */ + if (m != msg) { + if (m != m_tmp) + OPENSSL_clear_free(m, m_len); + else + OPENSSL_cleanse(m_tmp, sizeof(m_tmp)); + } return ret; } @@ -317,8 +333,13 @@ int ossl_slh_dsa_verify(SLH_DSA_HASH_CTX *slh_ctx, return 0; ret = slh_verify_internal(slh_ctx, m, m_len, sig, sig_len); - if (m != msg && m != m_tmp) - OPENSSL_free(m); + /* The encoded message may contain confidential message content */ + if (m != msg) { + if (m != m_tmp) + OPENSSL_clear_free(m, m_len); + else + OPENSSL_cleanse(m_tmp, sizeof(m_tmp)); + } return ret; } diff --git a/crypto/slh_dsa/slh_dsa_hash_ctx.c b/crypto/slh_dsa/slh_dsa_hash_ctx.c index 0c7282af870ec..f13c40e81ce4e 100644 --- a/crypto/slh_dsa/slh_dsa_hash_ctx.c +++ b/crypto/slh_dsa/slh_dsa_hash_ctx.c @@ -98,8 +98,9 @@ void ossl_slh_dsa_hash_ctx_free(SLH_DSA_HASH_CTX *ctx) { if (ctx == NULL) return; - OPENSSL_free(ctx->shactx); - OPENSSL_free(ctx->shactx_pkseed); + OPENSSL_clear_free(ctx->shactx, ctx->shactx_len); + OPENSSL_clear_free(ctx->shactx_pkseed, ctx->shactx_len); + OPENSSL_clear_free(ctx->scratch, ctx->scratch_len); EVP_MAC_CTX_free(ctx->hmac_ctx); OPENSSL_free(ctx); } diff --git a/crypto/slh_dsa/slh_dsa_key.c b/crypto/slh_dsa/slh_dsa_key.c index f99a00efb975f..7fec917aa9ca5 100644 --- a/crypto/slh_dsa/slh_dsa_key.c +++ b/crypto/slh_dsa/slh_dsa_key.c @@ -307,6 +307,12 @@ int ossl_slh_dsa_key_fromdata(SLH_DSA_KEY *key, const OSSL_PARAM *param_pub, key->pub = p; return 1; err: + /* + * A private key of unexpected length may have been copied into |priv| + * before |has_priv| was set, in which case the reset below would not + * erase it, so cleanse unconditionally. + */ + OPENSSL_cleanse(key->priv, sizeof(key->priv)); ossl_slh_dsa_key_reset(key); return 0; } diff --git a/crypto/slh_dsa/slh_dsa_local.h b/crypto/slh_dsa/slh_dsa_local.h index f11bf097cdbc6..df024dfbc5f32 100644 --- a/crypto/slh_dsa/slh_dsa_local.h +++ b/crypto/slh_dsa/slh_dsa_local.h @@ -52,6 +52,16 @@ struct slh_dsa_hash_ctx_st { const SLH_DSA_KEY *key; /* This key is not owned by this object */ void *shactx; /* A low level SHAKE object */ void *shactx_pkseed; /* A low level SHAKE or SHA256 object with PK.seed hashed in it */ + size_t shactx_len; /* The size of the two hash contexts above */ + /* + * A working hash context used by the hash functions in place of local + * stack copies, so that intermediate hash states derived from secrets + * live in one place and are erased when this object is freed. It is + * also used for the one-shot SHA-512 contexts of the security category + * 3 and 5 SHA2 parameter sets. Not used concurrently. + */ + void *scratch; + size_t scratch_len; EVP_MAC_CTX *hmac_ctx; /* required by SHA algorithms for PRFmsg() */ int hmac_digest_used; /* Used for lazy init of hmac_ctx digest */ }; diff --git a/crypto/slh_dsa/slh_fors.c b/crypto/slh_dsa/slh_fors.c index 10335cc5df2e9..305a172dc338a 100644 --- a/crypto/slh_dsa/slh_fors.c +++ b/crypto/slh_dsa/slh_fors.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,8 +17,8 @@ /* a = 6, 8, 9, 12 or 14 - There are (2^a) merkle trees */ #define SLH_MAX_A 9 -#define SLH_MAX_K_TIMES_A (SLH_MAX_A * SLH_MAX_K) -#define SLH_MAX_ROOTS (SLH_MAX_K_TIMES_A * SLH_MAX_N) +/* The FORS public key is computed from the roots of k Merkle trees */ +#define SLH_MAX_ROOTS (SLH_MAX_K * SLH_MAX_N) static void slh_base_2b(const uint8_t *in, uint32_t b, uint32_t *out, size_t out_len); @@ -87,25 +87,25 @@ static int slh_fors_node(SLH_DSA_HASH_CTX *ctx, const uint8_t *sk_seed, if (height == 0) { /* Gets here for leaf nodes */ - if (!slh_fors_sk_gen(ctx, sk_seed, pk_seed, adrs, node_id, sk, sizeof(sk))) - return 0; - adrsf->set_tree_height(adrs, 0); - adrsf->set_tree_index(adrs, node_id); - ret = key->hash_func->F(ctx, pk_seed, adrs, sk, n, node, node_len); + if (slh_fors_sk_gen(ctx, sk_seed, pk_seed, adrs, node_id, sk, sizeof(sk))) { + adrsf->set_tree_height(adrs, 0); + adrsf->set_tree_index(adrs, node_id); + ret = key->hash_func->F(ctx, pk_seed, adrs, sk, n, node, node_len); + } OPENSSL_cleanse(sk, n); - return ret; } else { - if (!slh_fors_node(ctx, sk_seed, pk_seed, adrs, 2 * node_id, height - 1, - lnode, sizeof(rnode)) - || !slh_fors_node(ctx, sk_seed, pk_seed, adrs, 2 * node_id + 1, - height - 1, rnode, sizeof(rnode))) - return 0; - adrsf->set_tree_height(adrs, height); - adrsf->set_tree_index(adrs, node_id); - if (!key->hash_func->H(ctx, pk_seed, adrs, lnode, rnode, node, node_len)) - return 0; + if (slh_fors_node(ctx, sk_seed, pk_seed, adrs, 2 * node_id, height - 1, + lnode, sizeof(lnode)) + && slh_fors_node(ctx, sk_seed, pk_seed, adrs, 2 * node_id + 1, + height - 1, rnode, sizeof(rnode))) { + adrsf->set_tree_height(adrs, height); + adrsf->set_tree_index(adrs, node_id); + ret = key->hash_func->H(ctx, pk_seed, adrs, lnode, rnode, node, node_len); + } + OPENSSL_cleanse(lnode, sizeof(lnode)); + OPENSSL_cleanse(rnode, sizeof(rnode)); } - return 1; + return ret; } /** @@ -132,6 +132,7 @@ int ossl_slh_fors_sign(SLH_DSA_HASH_CTX *ctx, const uint8_t *md, const uint8_t *sk_seed, const uint8_t *pk_seed, uint8_t *adrs, WPACKET *sig_wpkt) { + int ret = 0; const SLH_DSA_KEY *key = ctx->key; uint32_t tree_id, layer, s, tree_offset; uint32_t ids[SLH_MAX_K]; @@ -165,7 +166,7 @@ int ossl_slh_fors_sign(SLH_DSA_HASH_CTX *ctx, const uint8_t *md, if (!slh_fors_sk_gen(ctx, sk_seed, pk_seed, adrs, node_id + tree_id_times_two_power_a, out, sizeof(out)) || !WPACKET_memcpy(sig_wpkt, out, n)) - return 0; + goto err; /* * Traverse from the bottom of the tree (layer = 0) @@ -178,15 +179,18 @@ int ossl_slh_fors_sign(SLH_DSA_HASH_CTX *ctx, const uint8_t *md, s = node_id ^ 1; /* XOR gets the index of the other child in a binary tree */ if (!slh_fors_node(ctx, sk_seed, pk_seed, adrs, s + tree_offset, layer, out, sizeof(out))) - return 0; + goto err; node_id >>= 1; /* Get the parent node id */ tree_offset >>= 1; /* Each layer up has half as many nodes */ if (!WPACKET_memcpy(sig_wpkt, out, n)) - return 0; + goto err; } tree_id_times_two_power_a += two_power_a; } - return 1; + ret = 1; +err: + OPENSSL_cleanse(out, sizeof(out)); + return ret; } /** @@ -288,6 +292,8 @@ int ossl_slh_fors_pk_from_sig(SLH_DSA_HASH_CTX *ctx, PACKET *fors_sig_rpkt, err: if (!WPACKET_finish(wroot_pkt)) ret = 0; + /* At most one |n| byte root per tree was written */ + OPENSSL_cleanse(roots, k * n); return ret; } diff --git a/crypto/slh_dsa/slh_hash.c b/crypto/slh_dsa/slh_hash.c index 6e25371f29878..d8d4a9e9690df 100644 --- a/crypto/slh_dsa/slh_hash.c +++ b/crypto/slh_dsa/slh_hash.c @@ -82,6 +82,7 @@ slh_prf_msg_shake(SLH_DSA_HASH_CTX *hctx, const uint8_t *sk_prf, const uint8_t *opt_rand, const uint8_t *msg, size_t msg_len, WPACKET *pkt) { + int ret; unsigned char out[SLH_MAX_N]; const SLH_DSA_PARAMS *params = hctx->key->params; size_t n = params->n; @@ -92,7 +93,9 @@ slh_prf_msg_shake(SLH_DSA_HASH_CTX *hctx, const uint8_t *sk_prf, ossl_sha3_absorb(sctx, opt_rand, n); ossl_sha3_absorb(sctx, msg, msg_len); ossl_sha3_squeeze(sctx, out, n); - return WPACKET_memcpy(pkt, out, n); + ret = WPACKET_memcpy(pkt, out, n); + OPENSSL_cleanse(out, sizeof(out)); + return ret; } static int @@ -101,11 +104,12 @@ slh_f_shake(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs, { const SLH_DSA_PARAMS *params = hctx->key->params; size_t n = params->n; - KECCAK1600_CTX sctx = *((KECCAK1600_CTX *)(hctx->shactx_pkseed)); + KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->scratch); - ossl_sha3_absorb(&sctx, adrs, SLH_ADRS_SIZE); - ossl_sha3_absorb(&sctx, m1, m1_len); - ossl_sha3_squeeze(&sctx, out, n); + *sctx = *((KECCAK1600_CTX *)(hctx->shactx_pkseed)); + ossl_sha3_absorb(sctx, adrs, SLH_ADRS_SIZE); + ossl_sha3_absorb(sctx, m1, m1_len); + ossl_sha3_squeeze(sctx, out, n); return 1; } @@ -116,11 +120,12 @@ slh_prf_shake(SLH_DSA_HASH_CTX *hctx, { const SLH_DSA_PARAMS *params = hctx->key->params; size_t n = params->n; - KECCAK1600_CTX sctx = *((KECCAK1600_CTX *)(hctx->shactx_pkseed)); + KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->scratch); - ossl_sha3_absorb(&sctx, adrs, SLH_ADRS_SIZE); - ossl_sha3_absorb(&sctx, sk_seed, n); - ossl_sha3_squeeze(&sctx, out, n); + *sctx = *((KECCAK1600_CTX *)(hctx->shactx_pkseed)); + ossl_sha3_absorb(sctx, adrs, SLH_ADRS_SIZE); + ossl_sha3_absorb(sctx, sk_seed, n); + ossl_sha3_squeeze(sctx, out, n); return 1; } @@ -128,10 +133,11 @@ static int slh_h_shake(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs, const uint8_t *m1, const uint8_t *m2, uint8_t *out, size_t out_len) { - KECCAK1600_CTX ctx = *((KECCAK1600_CTX *)(hctx->shactx_pkseed)), *sctx = &ctx; + KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->scratch); const SLH_DSA_PARAMS *params = hctx->key->params; size_t n = params->n; + *sctx = *((KECCAK1600_CTX *)(hctx->shactx_pkseed)); ossl_sha3_absorb(sctx, adrs, SLH_ADRS_SIZE); ossl_sha3_absorb(sctx, m1, n); ossl_sha3_absorb(sctx, m2, n); @@ -146,7 +152,8 @@ slh_hmsg_sha256(SLH_DSA_HASH_CTX *hctx, const uint8_t *r, const uint8_t *pk_seed const uint8_t *pk_root, const uint8_t *msg, size_t msg_len, uint8_t *out, size_t out_len) { - SHA256_CTX ctx, *sctx = &ctx; + int ret; + SHA256_CTX *sctx = (SHA256_CTX *)(hctx->scratch); const SLH_DSA_PARAMS *params = hctx->key->params; size_t m = params->m; size_t n = params->n; @@ -161,8 +168,10 @@ slh_hmsg_sha256(SLH_DSA_HASH_CTX *hctx, const uint8_t *r, const uint8_t *pk_seed SHA256_Update(sctx, pk_seed, n); SHA256_Update(sctx, pk_root, n); SHA256_Update(sctx, msg, msg_len); - return SHA256_Final(seed + 2 * n, sctx) + ret = SHA256_Final(seed + 2 * n, sctx) && (PKCS1_MGF1(out, (long)m, seed, seed_len, hctx->key->md) == 0); + OPENSSL_cleanse(seed, sizeof(seed)); + return ret; } static int @@ -170,7 +179,8 @@ slh_hmsg_sha512(SLH_DSA_HASH_CTX *hctx, const uint8_t *r, const uint8_t *pk_seed const uint8_t *pk_root, const uint8_t *msg, size_t msg_len, uint8_t *out, size_t out_len) { - SHA512_CTX ctx, *sctx = &ctx; + int ret; + SHA512_CTX *sctx = (SHA512_CTX *)(hctx->scratch); const SLH_DSA_PARAMS *params = hctx->key->params; size_t m = params->m; size_t n = params->n; @@ -185,8 +195,10 @@ slh_hmsg_sha512(SLH_DSA_HASH_CTX *hctx, const uint8_t *r, const uint8_t *pk_seed SHA512_Update(sctx, pk_seed, n); SHA512_Update(sctx, pk_root, n); SHA512_Update(sctx, msg, msg_len); - return SHA512_Final(seed + 2 * n, sctx) + ret = SHA512_Final(seed + 2 * n, sctx) && (PKCS1_MGF1(out, (long)m, seed, seed_len, hctx->key->md_sha512) == 0); + OPENSSL_cleanse(seed, sizeof(seed)); + return ret; } static int @@ -227,6 +239,7 @@ slh_prf_msg_sha2(SLH_DSA_HASH_CTX *hctx, && EVP_MAC_update(mctx, msg, msg_len) == 1 && EVP_MAC_final(mctx, mac, NULL, sizeof(mac)) == 1 && WPACKET_memcpy(pkt, mac, n); /* Truncate output to n bytes */ + OPENSSL_cleanse(mac, sizeof(mac)); return ret; } @@ -235,9 +248,10 @@ slh_prf_sha256(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *sk_seed, const uint8_t *adrs, uint8_t *out, size_t out_len) { - SHA256_CTX ctx = *((SHA256_CTX *)hctx->shactx_pkseed), *sctx = &ctx; + SHA256_CTX *sctx = (SHA256_CTX *)(hctx->scratch); size_t n = hctx->key->params->n; + *sctx = *((SHA256_CTX *)hctx->shactx_pkseed); SHA256_Update(sctx, adrs, SLH_ADRSC_SIZE); SHA256_Update(sctx, sk_seed, n); sha256_final(sctx, out, n); @@ -254,7 +268,7 @@ slh_wots_pk_gen_sha2(SLH_DSA_HASH_CTX *hctx, size_t i, j = 0, len = SLH_WOTS_LEN(n); uint8_t sk[SLH_MAX_N]; SHA256_CTX *sctx = (SHA256_CTX *)(hctx->shactx_pkseed); - SHA256_CTX ctx; + SHA256_CTX *ctx = (SHA256_CTX *)(hctx->scratch); const SLH_ADRS_FUNC *adrsf = hctx->key->adrs_func; SLH_ADRS_DECLARE(sk_adrs); SLH_ADRS_FN_DECLARE(adrsf, set_chain_address); @@ -268,24 +282,25 @@ slh_wots_pk_gen_sha2(SLH_DSA_HASH_CTX *hctx, set_chain_address(sk_adrs, (uint32_t)i); /* PRF */ - ctx = *sctx; - SHA256_Update(&ctx, sk_adrs, SLH_ADRSC_SIZE); - SHA256_Update(&ctx, sk_seed, n); - sha256_final(&ctx, sk, n); + *ctx = *sctx; + SHA256_Update(ctx, sk_adrs, SLH_ADRSC_SIZE); + SHA256_Update(ctx, sk_seed, n); + sha256_final(ctx, sk, n); set_chain_address(adrs, (uint32_t)i); for (j = 0; j < NIBBLE_MASK; ++j) { set_hash_address(adrs, (uint32_t)j); /* F */ - ctx = *sctx; - SHA256_Update(&ctx, adrs, SLH_ADRSC_SIZE); - SHA256_Update(&ctx, sk, n); - sha256_final(&ctx, sk, n); + *ctx = *sctx; + SHA256_Update(ctx, adrs, SLH_ADRSC_SIZE); + SHA256_Update(ctx, sk, n); + sha256_final(ctx, sk, n); } memcpy(pk_out, sk, n); pk_out += n; } ret = 1; + OPENSSL_cleanse(sk, sizeof(sk)); return ret; } @@ -302,7 +317,7 @@ int slh_wots_pk_gen_shake(SLH_DSA_HASH_CTX *hctx, SLH_ADRS_FN_DECLARE(adrsf, set_chain_address); SLH_ADRS_FN_DECLARE(adrsf, set_hash_address); KECCAK1600_CTX *sctx = (KECCAK1600_CTX *)(hctx->shactx_pkseed); - KECCAK1600_CTX ctx; + KECCAK1600_CTX *ctx = (KECCAK1600_CTX *)(hctx->scratch); adrsf->copy(sk_adrs, adrs); adrsf->set_type_and_clear(sk_adrs, SLH_ADRS_TYPE_WOTS_PRF); @@ -312,24 +327,25 @@ int slh_wots_pk_gen_shake(SLH_DSA_HASH_CTX *hctx, set_chain_address(sk_adrs, (uint32_t)i); /* PRF */ - ctx = *sctx; - ossl_sha3_absorb(&ctx, sk_adrs, SLH_ADRS_SIZE); - ossl_sha3_absorb(&ctx, sk_seed, n); - ossl_sha3_squeeze(&ctx, sk, n); + *ctx = *sctx; + ossl_sha3_absorb(ctx, sk_adrs, SLH_ADRS_SIZE); + ossl_sha3_absorb(ctx, sk_seed, n); + ossl_sha3_squeeze(ctx, sk, n); set_chain_address(adrs, (uint32_t)i); for (j = 0; j < NIBBLE_MASK; ++j) { set_hash_address(adrs, (uint32_t)j); /* F */ - ctx = *sctx; - ossl_sha3_absorb(&ctx, adrs, SLH_ADRS_SIZE); - ossl_sha3_absorb(&ctx, sk, n); - ossl_sha3_squeeze(&ctx, sk, n); + *ctx = *sctx; + ossl_sha3_absorb(ctx, adrs, SLH_ADRS_SIZE); + ossl_sha3_absorb(ctx, sk, n); + ossl_sha3_squeeze(ctx, sk, n); } memcpy(pk_out, sk, n); pk_out += n; } ret = 1; + OPENSSL_cleanse(sk, sizeof(sk)); return ret; } @@ -337,8 +353,9 @@ static int slh_f_sha256(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs, const uint8_t *m1, size_t m1_len, uint8_t *out, size_t out_len) { - SHA256_CTX ctx = *((SHA256_CTX *)hctx->shactx_pkseed), *sctx = &ctx; + SHA256_CTX *sctx = (SHA256_CTX *)(hctx->scratch); + *sctx = *((SHA256_CTX *)hctx->shactx_pkseed); SHA256_Update(sctx, adrs, SLH_ADRSC_SIZE); SHA256_Update(sctx, m1, m1_len); sha256_final(sctx, out, hctx->key->params->n); @@ -349,10 +366,11 @@ static int slh_h_sha256(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs, const uint8_t *m1, const uint8_t *m2, uint8_t *out, size_t out_len) { - SHA256_CTX ctx = *((SHA256_CTX *)hctx->shactx_pkseed), *sctx = &ctx; + SHA256_CTX *sctx = (SHA256_CTX *)(hctx->scratch); const SLH_DSA_PARAMS *prms = hctx->key->params; size_t n = prms->n; + *sctx = *((SHA256_CTX *)hctx->shactx_pkseed); SHA256_Update(sctx, adrs, SLH_ADRSC_SIZE); SHA256_Update(sctx, m1, n); SHA256_Update(sctx, m2, n); @@ -364,7 +382,7 @@ static int slh_h_sha512(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs, const uint8_t *m1, const uint8_t *m2, uint8_t *out, size_t out_len) { - SHA512_CTX ctx, *sctx = &ctx; + SHA512_CTX *sctx = (SHA512_CTX *)(hctx->scratch); const SLH_DSA_PARAMS *prms = hctx->key->params; size_t n = prms->n; @@ -382,8 +400,9 @@ static int slh_t_sha256(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs, const uint8_t *ml, size_t ml_len, uint8_t *out, size_t out_len) { - SHA256_CTX ctx = *((SHA256_CTX *)hctx->shactx_pkseed), *sctx = &ctx; + SHA256_CTX *sctx = (SHA256_CTX *)(hctx->scratch); + *sctx = *((SHA256_CTX *)hctx->shactx_pkseed); SHA256_Update(sctx, adrs, SLH_ADRSC_SIZE); SHA256_Update(sctx, ml, ml_len); sha256_final(sctx, out, hctx->key->params->n); @@ -394,7 +413,7 @@ static int slh_t_sha512(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs, const uint8_t *ml, size_t ml_len, uint8_t *out, size_t out_len) { - SHA512_CTX ctx, *sctx = &ctx; + SHA512_CTX *sctx = (SHA512_CTX *)(hctx->scratch); const SLH_DSA_PARAMS *prms = hctx->key->params; size_t n = prms->n; @@ -409,19 +428,25 @@ slh_t_sha512(SLH_DSA_HASH_CTX *hctx, const uint8_t *pk_seed, const uint8_t *adrs static int slh_hash_shake_precache(SLH_DSA_HASH_CTX *hctx, const uint8_t *pkseed, size_t n) { - KECCAK1600_CTX *ctx = NULL, *seedctx = NULL; + KECCAK1600_CTX *ctx = NULL, *seedctx = NULL, *scratch = NULL; ctx = ossl_shake256_new(); if (ctx == NULL) return 0; seedctx = OPENSSL_memdup(ctx, sizeof(*ctx)); - if (seedctx == NULL) { + scratch = OPENSSL_malloc(sizeof(*scratch)); + if (seedctx == NULL || scratch == NULL) { OPENSSL_free(ctx); + OPENSSL_free(seedctx); + OPENSSL_free(scratch); return 0; } ossl_sha3_absorb(seedctx, pkseed, n); hctx->shactx = (void *)ctx; hctx->shactx_pkseed = (void *)seedctx; + hctx->shactx_len = sizeof(*ctx); + hctx->scratch = (void *)scratch; + hctx->scratch_len = sizeof(*scratch); return 1; } @@ -440,19 +465,38 @@ static int slh_hash_shake_dup(SLH_DSA_HASH_CTX *dst, const SLH_DSA_HASH_CTX *src return 0; } } + dst->shactx_len = src->shactx_len; + /* A prehashed context needs a scratch context, its content is transient */ + if (dst->shactx_pkseed != NULL) { + dst->scratch = OPENSSL_malloc(sizeof(KECCAK1600_CTX)); + if (dst->scratch == NULL) + return 0; + dst->scratch_len = sizeof(KECCAK1600_CTX); + } else { + dst->scratch = NULL; + dst->scratch_len = 0; + } return 1; } static int slh_hash_sha256_precache(SLH_DSA_HASH_CTX *hctx, const uint8_t *pkseed, size_t n) { SHA256_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); + /* The scratch context is also used as a SHA512_CTX by category 3 and 5 */ + size_t scratch_len = sizeof(SHA512_CTX); if (ctx == NULL) return 0; + if ((hctx->scratch = OPENSSL_malloc(scratch_len)) == NULL) { + OPENSSL_free(ctx); + return 0; + } + hctx->scratch_len = scratch_len; SHA256_Init(ctx); SHA256_Update(ctx, pkseed, n); SHA256_Update(ctx, zeros, 64 - n); hctx->shactx_pkseed = (void *)ctx; + hctx->shactx_len = sizeof(*ctx); return 1; } @@ -463,6 +507,21 @@ static int slh_hash_sha256_dup(SLH_DSA_HASH_CTX *dst, const SLH_DSA_HASH_CTX *sr if (dst->shactx_pkseed == NULL) return 0; } + /* + * A prehashed context needs a scratch context, its content is transient. + * As in slh_hash_sha256_precache() the scratch context is sized to also + * serve as a SHA512_CTX for security categories 3 and 5. + */ + dst->shactx_len = src->shactx_len; + if (dst->shactx_pkseed != NULL) { + dst->scratch = OPENSSL_malloc(sizeof(SHA512_CTX)); + if (dst->scratch == NULL) + return 0; + dst->scratch_len = sizeof(SHA512_CTX); + } else { + dst->scratch = NULL; + dst->scratch_len = 0; + } return 1; } diff --git a/crypto/slh_dsa/slh_hypertree.c b/crypto/slh_dsa/slh_hypertree.c index bc352bf5bc3a2..e1e2901ce5f32 100644 --- a/crypto/slh_dsa/slh_hypertree.c +++ b/crypto/slh_dsa/slh_hypertree.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,6 +8,7 @@ */ #include +#include #include "slh_dsa_local.h" #include "slh_dsa_key.h" @@ -33,6 +34,7 @@ int ossl_slh_ht_sign(SLH_DSA_HASH_CTX *ctx, const uint8_t *pk_seed, uint64_t tree_id, uint32_t leaf_id, WPACKET *sig_wpkt) { + int ret = 0; const SLH_DSA_KEY *key = ctx->key; SLH_ADRS_FUNC_DECLARE(key, adrsf); SLH_ADRS_DECLARE(adrs); @@ -70,7 +72,7 @@ int ossl_slh_ht_sign(SLH_DSA_HASH_CTX *ctx, psig = WPACKET_get_curr(sig_wpkt); if (!ossl_slh_xmss_sign(ctx, root, sk_seed, leaf_id, pk_seed, adrs, sig_wpkt)) - return 0; + goto err; /* * On the last loop it skips getting the public key since it is not needed * to calculate another signature. If this was called it should equal @@ -79,15 +81,18 @@ int ossl_slh_ht_sign(SLH_DSA_HASH_CTX *ctx, if (layer < d - 1) { if (!PACKET_buf_init(xmss_sig_rpkt, psig, WPACKET_get_curr(sig_wpkt) - psig)) - return 0; + goto err; if (!ossl_slh_xmss_pk_from_sig(ctx, leaf_id, xmss_sig_rpkt, root, pk_seed, adrs, root, sizeof(root))) - return 0; + goto err; leaf_id = tree_id & mask; tree_id >>= hm; } } - return 1; + ret = 1; +err: + OPENSSL_cleanse(root, sizeof(root)); + return ret; } /** @@ -108,6 +113,7 @@ int ossl_slh_ht_verify(SLH_DSA_HASH_CTX *ctx, const uint8_t *msg, PACKET *sig_pk const uint8_t *pk_seed, uint64_t tree_id, uint32_t leaf_id, const uint8_t *pk_root) { + int ret = 0; const SLH_DSA_KEY *key = ctx->key; SLH_ADRS_FUNC_DECLARE(key, adrsf); SLH_ADRS_DECLARE(adrs); @@ -127,9 +133,12 @@ int ossl_slh_ht_verify(SLH_DSA_HASH_CTX *ctx, const uint8_t *msg, PACKET *sig_pk adrsf->set_tree_address(adrs, tree_id); if (!ossl_slh_xmss_pk_from_sig(ctx, leaf_id, sig_pkt, node, pk_seed, adrs, node, sizeof(node))) - return 0; + goto err; leaf_id = tree_id & mask; tree_id >>= tree_height; } - return (memcmp(node, pk_root, n) == 0); + ret = (memcmp(node, pk_root, n) == 0); +err: + OPENSSL_cleanse(node, sizeof(node)); + return ret; } diff --git a/crypto/slh_dsa/slh_params.h b/crypto/slh_dsa/slh_params.h index edc3644b61f25..5a97b9fb58aa9 100644 --- a/crypto/slh_dsa/slh_params.h +++ b/crypto/slh_dsa/slh_params.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/slh_dsa/slh_wots.c b/crypto/slh_dsa/slh_wots.c index 3b84474c412b8..e4e82f4407a58 100644 --- a/crypto/slh_dsa/slh_wots.c +++ b/crypto/slh_dsa/slh_wots.c @@ -158,6 +158,7 @@ int ossl_slh_wots_pk_gen(SLH_DSA_HASH_CTX *ctx, adrsf->copy_keypair_address(wots_pk_adrs, adrs); ret = hashf->T(ctx, pk_seed, wots_pk_adrs, tmp, tmp_len, pk_out, pk_out_len); end: + OPENSSL_cleanse(tmp, tmp_len); return ret; } @@ -221,6 +222,8 @@ int ossl_slh_wots_sign(SLH_DSA_HASH_CTX *ctx, const uint8_t *msg, } ret = 1; err: + OPENSSL_cleanse(sk, sizeof(sk)); + OPENSSL_cleanse(msg_and_csum_nibbles, sizeof(msg_and_csum_nibbles)); return ret; } @@ -288,5 +291,7 @@ int ossl_slh_wots_pk_from_sig(SLH_DSA_HASH_CTX *ctx, err: if (!WPACKET_finish(tmp_pkt)) ret = 0; + OPENSSL_cleanse(tmp, sizeof(tmp)); + OPENSSL_cleanse(msg_and_csum_nibbles, sizeof(msg_and_csum_nibbles)); return ret; } diff --git a/crypto/slh_dsa/slh_xmss.c b/crypto/slh_dsa/slh_xmss.c index dae036c6a2189..a53a6c1e99117 100644 --- a/crypto/slh_dsa/slh_xmss.c +++ b/crypto/slh_dsa/slh_xmss.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,6 +8,7 @@ */ #include +#include #include "slh_dsa_local.h" #include "slh_dsa_key.h" @@ -39,29 +40,31 @@ int ossl_slh_xmss_node(SLH_DSA_HASH_CTX *ctx, const uint8_t *sk_seed, { const SLH_DSA_KEY *key = ctx->key; SLH_ADRS_FUNC_DECLARE(key, adrsf); + int ret = 0; if (h == 0) { /* For leaf nodes generate the public key */ adrsf->set_type_and_clear(adrs, SLH_ADRS_TYPE_WOTS_HASH); adrsf->set_keypair_address(adrs, node_id); - if (!ossl_slh_wots_pk_gen(ctx, sk_seed, pk_seed, adrs, + if (ossl_slh_wots_pk_gen(ctx, sk_seed, pk_seed, adrs, pk_out, pk_out_len)) - return 0; + ret = 1; } else { uint8_t lnode[SLH_MAX_N], rnode[SLH_MAX_N]; - if (!ossl_slh_xmss_node(ctx, sk_seed, 2 * node_id, h - 1, pk_seed, adrs, + if (ossl_slh_xmss_node(ctx, sk_seed, 2 * node_id, h - 1, pk_seed, adrs, lnode, sizeof(lnode)) - || !ossl_slh_xmss_node(ctx, sk_seed, 2 * node_id + 1, h - 1, - pk_seed, adrs, rnode, sizeof(rnode))) - return 0; - adrsf->set_type_and_clear(adrs, SLH_ADRS_TYPE_TREE); - adrsf->set_tree_height(adrs, h); - adrsf->set_tree_index(adrs, node_id); - if (!key->hash_func->H(ctx, pk_seed, adrs, lnode, rnode, pk_out, pk_out_len)) - return 0; + && ossl_slh_xmss_node(ctx, sk_seed, 2 * node_id + 1, h - 1, + pk_seed, adrs, rnode, sizeof(rnode))) { + adrsf->set_type_and_clear(adrs, SLH_ADRS_TYPE_TREE); + adrsf->set_tree_height(adrs, h); + adrsf->set_tree_index(adrs, node_id); + ret = key->hash_func->H(ctx, pk_seed, adrs, lnode, rnode, pk_out, pk_out_len); + } + OPENSSL_cleanse(lnode, sizeof(lnode)); + OPENSSL_cleanse(rnode, sizeof(rnode)); } - return 1; + return ret; } /** diff --git a/crypto/sm2/sm2_crypt.c b/crypto/sm2/sm2_crypt.c index a1cbd88c2df81..7aa8ecb68227c 100644 --- a/crypto/sm2/sm2_crypt.c +++ b/crypto/sm2/sm2_crypt.c @@ -78,7 +78,7 @@ int ossl_sm2_plaintext_size(const unsigned char *ct, size_t ct_size, return 0; } - *pt_size = ASN1_STRING_length(sm2_ctext->C2); + *pt_size = ASN1_STRING_get_length(sm2_ctext->C2); SM2_Ciphertext_free(sm2_ctext); return 1; @@ -309,7 +309,7 @@ int ossl_sm2_decrypt(const EC_KEY *key, uint8_t *msg_mask = NULL; const uint8_t *C2 = NULL; const uint8_t *C3 = NULL; - int msg_len = 0; + size_t c3_len, msg_len = 0; EVP_MD_CTX *hash = NULL; OSSL_LIB_CTX *libctx = ossl_ec_key_get_libctx(key); const char *propq = ossl_ec_key_get0_propq(key); @@ -326,14 +326,18 @@ int ossl_sm2_decrypt(const EC_KEY *key, goto done; } - if (ASN1_STRING_length(sm2_ctext->C3) != hash_size) { + msg_len = ASN1_STRING_get_length(sm2_ctext->C2); + if (msg_len > INT_MAX) + goto done; + + c3_len = ASN1_STRING_get_length(sm2_ctext->C3); + if (c3_len > INT_MAX || c3_len != (size_t)hash_size) { ERR_raise(ERR_LIB_SM2, SM2_R_INVALID_ENCODING); goto done; } C2 = ASN1_STRING_get0_data(sm2_ctext->C2); C3 = ASN1_STRING_get0_data(sm2_ctext->C3); - msg_len = ASN1_STRING_length(sm2_ctext->C2); if (*ptext_len < (size_t)msg_len) { ERR_raise(ERR_LIB_SM2, SM2_R_BUFFER_TOO_SMALL); goto done; @@ -378,7 +382,7 @@ int ossl_sm2_decrypt(const EC_KEY *key, if (BN_bn2binpad(x2, x2y2, field_size) < 0 || BN_bn2binpad(y2, x2y2 + field_size, field_size) < 0 - || !ossl_ecdh_kdf_X9_63(msg_mask, msg_len, x2y2, 2 * field_size, + || !ossl_ecdh_kdf_X9_63(msg_mask, (int)msg_len, x2y2, 2 * field_size, NULL, 0, digest, libctx, propq)) { ERR_raise(ERR_LIB_SM2, ERR_R_INTERNAL_ERROR); goto done; @@ -389,7 +393,7 @@ int ossl_sm2_decrypt(const EC_KEY *key, goto done; } - for (i = 0; i != msg_len; ++i) + for (i = 0; i != (int)msg_len; ++i) ptext_buf[i] = C2[i] ^ msg_mask[i]; hash = EVP_MD_CTX_new(); @@ -400,7 +404,7 @@ int ossl_sm2_decrypt(const EC_KEY *key, if (!EVP_DigestInit(hash, digest) || !EVP_DigestUpdate(hash, x2y2, field_size) - || !EVP_DigestUpdate(hash, ptext_buf, msg_len) + || !EVP_DigestUpdate(hash, ptext_buf, (int)msg_len) || !EVP_DigestUpdate(hash, x2y2 + field_size, field_size) || !EVP_DigestFinal(hash, computed_C3, NULL)) { ERR_raise(ERR_LIB_SM2, ERR_R_EVP_LIB); @@ -413,7 +417,7 @@ int ossl_sm2_decrypt(const EC_KEY *key, } rc = 1; - *ptext_len = msg_len; + *ptext_len = (int)msg_len; done: if (rc == 0) diff --git a/crypto/sm2/sm2_err.c b/crypto/sm2/sm2_err.c deleted file mode 100644 index 2cb3de1c9ef16..0000000000000 --- a/crypto/sm2/sm2_err.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include "crypto/sm2err.h" - -#ifndef OPENSSL_NO_SM2 - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA SM2_str_reasons[] = { - { ERR_PACK(ERR_LIB_SM2, 0, SM2_R_ASN1_ERROR), "asn1 error" }, - { ERR_PACK(ERR_LIB_SM2, 0, SM2_R_BAD_SIGNATURE), "bad signature" }, - { ERR_PACK(ERR_LIB_SM2, 0, SM2_R_BUFFER_TOO_SMALL), "buffer too small" }, - { ERR_PACK(ERR_LIB_SM2, 0, SM2_R_DIST_ID_TOO_LARGE), "dist id too large" }, - { ERR_PACK(ERR_LIB_SM2, 0, SM2_R_ID_NOT_SET), "id not set" }, - { ERR_PACK(ERR_LIB_SM2, 0, SM2_R_ID_TOO_LARGE), "id too large" }, - { ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_CURVE), "invalid curve" }, - { ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_DIGEST), "invalid digest" }, - { ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_DIGEST_TYPE), - "invalid digest type" }, - { ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_ENCODING), "invalid encoding" }, - { ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_FIELD), "invalid field" }, - { ERR_PACK(ERR_LIB_SM2, 0, SM2_R_INVALID_PRIVATE_KEY), - "invalid private key" }, - { ERR_PACK(ERR_LIB_SM2, 0, SM2_R_NO_PARAMETERS_SET), "no parameters set" }, - { ERR_PACK(ERR_LIB_SM2, 0, SM2_R_USER_ID_TOO_LARGE), "user id too large" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_SM2_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(SM2_str_reasons[0].error) == NULL) - ERR_load_strings_const(SM2_str_reasons); -#endif - return 1; -} -#else -NON_EMPTY_TRANSLATION_UNIT -#endif diff --git a/crypto/sm3/asm/sm3-armv8.pl b/crypto/sm3/asm/sm3-armv8.pl index 6c51df28f81f2..da7f839d719c0 100644 --- a/crypto/sm3/asm/sm3-armv8.pl +++ b/crypto/sm3/asm/sm3-armv8.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sm3/asm/sm3-x86_64.pl b/crypto/sm3/asm/sm3-x86_64.pl index 2f6ddf5616819..05fead782d9b1 100755 --- a/crypto/sm3/asm/sm3-x86_64.pl +++ b/crypto/sm3/asm/sm3-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2024, Intel Corporation. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/sm3/sm3_local.h b/crypto/sm3/sm3_local.h index 41639b3c95be7..ee20db8a1d278 100644 --- a/crypto/sm3/sm3_local.h +++ b/crypto/sm3/sm3_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2017 Ribose Inc. All Rights Reserved. * Ported from Ribose contributions from Botan. * diff --git a/crypto/sm3/sm3_riscv.c b/crypto/sm3/sm3_riscv.c index 3dcb3d2938ebc..961b7f107c9e8 100644 --- a/crypto/sm3/sm3_riscv.c +++ b/crypto/sm3/sm3_riscv.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sm4/asm/sm4-armv8.pl b/crypto/sm4/asm/sm4-armv8.pl index 8024922ece24b..602059d7b3917 100755 --- a/crypto/sm4/asm/sm4-armv8.pl +++ b/crypto/sm4/asm/sm4-armv8.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sm4/asm/sm4-x86_64.pl b/crypto/sm4/asm/sm4-x86_64.pl index f5b485968ef08..ec7d3f2b373c2 100644 --- a/crypto/sm4/asm/sm4-x86_64.pl +++ b/crypto/sm4/asm/sm4-x86_64.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2025, Intel Corporation. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/crypto/sm4/asm/vpsm4-armv8.pl b/crypto/sm4/asm/vpsm4-armv8.pl index e242af75ee780..21a6f2bb06d50 100755 --- a/crypto/sm4/asm/vpsm4-armv8.pl +++ b/crypto/sm4/asm/vpsm4-armv8.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sparccpuid.S b/crypto/sparccpuid.S index aa92241197fc1..8ad9723a7f8c3 100644 --- a/crypto/sparccpuid.S +++ b/crypto/sparccpuid.S @@ -1,4 +1,4 @@ -! Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved. +! Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. ! ! Licensed under the Apache License 2.0 (the "License"). You may not use ! this file except in compliance with the License. You can obtain a copy diff --git a/crypto/sparcv9cap.c b/crypto/sparcv9cap.c index cea44ada9b841..a0550006e82d6 100644 --- a/crypto/sparcv9cap.c +++ b/crypto/sparcv9cap.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ssl_err.c b/crypto/ssl_err.c deleted file mode 100644 index 0dca54bb1db63..0000000000000 --- a/crypto/ssl_err.c +++ /dev/null @@ -1,635 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "sslerr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA SSL_str_reasons[] = { - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY), - "application data after close notify" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_APP_DATA_IN_HANDSHAKE), - "app data in handshake" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT), - "attempt to reuse session in different context" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE), - "at least (D)TLS 1.2 needed in Suite B mode" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CERTIFICATE), "bad certificate" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CHANGE_CIPHER_SPEC), - "bad change cipher spec" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_CIPHER), "bad cipher" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_COMPRESSION_ALGORITHM), - "bad compression algorithm" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_DATA), "bad data" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_DATA_RETURNED_BY_CALLBACK), - "bad data returned by callback" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_DECOMPRESSION), "bad decompression" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_DH_VALUE), "bad dh value" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_DIGEST_LENGTH), "bad digest length" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_EARLY_DATA), "bad early data" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_ECC_CERT), "bad ecc cert" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_ECHCONFIG_EXTENSION), - "bad echconfig extension" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_ECPOINT), "bad ecpoint" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_EXTENSION), "bad extension" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_HANDSHAKE_LENGTH), - "bad handshake length" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_HANDSHAKE_STATE), - "bad handshake state" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_HELLO_REQUEST), "bad hello request" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_HRR_VERSION), "bad hrr version" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_KEY_SHARE), "bad key share" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_KEY_UPDATE), "bad key update" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_LEGACY_VERSION), "bad legacy version" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_LENGTH), "bad length" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_PACKET), "bad packet" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_PACKET_LENGTH), "bad packet length" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_PROTOCOL_VERSION_NUMBER), - "bad protocol version number" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_PSK), "bad psk" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_PSK_IDENTITY), "bad psk identity" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_RECORD_TYPE), "bad record type" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_RSA_ENCRYPT), "bad rsa encrypt" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_SIGNATURE), "bad signature" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_SRP_A_LENGTH), "bad srp a length" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_SRP_PARAMETERS), "bad srp parameters" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_SRTP_MKI_VALUE), "bad srtp mki value" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST), - "bad srtp protection profile list" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_SSL_FILETYPE), "bad ssl filetype" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_VALUE), "bad value" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BAD_WRITE_RETRY), "bad write retry" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BINDER_DOES_NOT_VERIFY), - "binder does not verify" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BIO_NOT_SET), "bio not set" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG), - "block cipher pad is wrong" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_BN_LIB), "bn lib" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CALLBACK_FAILED), "callback failed" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CANNOT_CHANGE_CIPHER), - "cannot change cipher" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CANNOT_GET_GROUP_NAME), - "cannot get group name" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CA_DN_LENGTH_MISMATCH), - "ca dn length mismatch" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CA_KEY_TOO_SMALL), "ca key too small" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CA_MD_TOO_WEAK), "ca md too weak" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CCS_RECEIVED_EARLY), "ccs received early" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CERTIFICATE_VERIFY_FAILED), - "certificate verify failed" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CERT_CB_ERROR), "cert cb error" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CERT_LENGTH_MISMATCH), - "cert length mismatch" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED), - "ciphersuite digest has changed" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CIPHER_CODE_WRONG_LENGTH), - "cipher code wrong length" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CLIENTHELLO_TLSEXT), "clienthello tlsext" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_COMPRESSED_LENGTH_TOO_LONG), - "compressed length too long" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_COMPRESSION_DISABLED), - "compression disabled" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_COMPRESSION_FAILURE), - "compression failure" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE), - "compression id not within private range" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_COMPRESSION_LIBRARY_ERROR), - "compression library error" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CONNECTION_TYPE_NOT_SET), - "connection type not set" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CONN_USE_ONLY), "conn use only" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CONTEXT_NOT_DANE_ENABLED), - "context not dane enabled" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_COOKIE_GEN_CALLBACK_FAILURE), - "cookie gen callback failure" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_COOKIE_MISMATCH), "cookie mismatch" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_COPY_PARAMETERS_FAILED), - "copy parameters failed" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED), - "custom ext handler already installed" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DANE_ALREADY_ENABLED), - "dane already enabled" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL), - "dane cannot override mtype full" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DANE_NOT_ENABLED), "dane not enabled" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DANE_TLSA_BAD_CERTIFICATE), - "dane tlsa bad certificate" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE), - "dane tlsa bad certificate usage" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DANE_TLSA_BAD_DATA_LENGTH), - "dane tlsa bad data length" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH), - "dane tlsa bad digest length" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DANE_TLSA_BAD_MATCHING_TYPE), - "dane tlsa bad matching type" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DANE_TLSA_BAD_PUBLIC_KEY), - "dane tlsa bad public key" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DANE_TLSA_BAD_SELECTOR), - "dane tlsa bad selector" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DANE_TLSA_NULL_DATA), - "dane tlsa null data" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED), - "data between ccs and finished" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DATA_LENGTH_TOO_LONG), - "data length too long" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DECRYPTION_FAILED), "decryption failed" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC), - "decryption failed or bad record mac" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DH_KEY_TOO_SMALL), "dh key too small" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG), - "dh public value length is wrong" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DIGEST_CHECK_FAILED), - "digest check failed" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DOMAIN_USE_ONLY), "domain use only" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DTLS_MESSAGE_TOO_BIG), - "dtls message too big" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_DUPLICATE_COMPRESSION_ID), - "duplicate compression id" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ECC_CERT_NOT_FOR_SIGNING), - "ecc cert not for signing" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE), - "ecdh required for suiteb mode" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ECH_DECODE_ERROR), "ech decode error" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ECH_REQUIRED), "ech required" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EE_KEY_TOO_SMALL), "ee key too small" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EMPTY_RAW_PUBLIC_KEY), - "empty raw public key" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST), - "empty srtp protection profile list" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ENCRYPTED_LENGTH_TOO_LONG), - "encrypted length too long" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST), - "error in received cipher list" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ERROR_IN_SYSTEM_DEFAULT_CONFIG), - "error in system default config" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN), - "error setting tlsa base domain" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE), - "exceeds max fragment size" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EXCESSIVE_MESSAGE_SIZE), - "excessive message size" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EXTENSION_NOT_RECEIVED), - "extension not received" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EXTRA_DATA_IN_MESSAGE), - "extra data in message" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_EXT_LENGTH_MISMATCH), - "ext length mismatch" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FAILED_TO_GET_PARAMETER), - "failed to get parameter" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FAILED_TO_INIT_ASYNC), - "failed to init async" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FEATURE_NEGOTIATION_NOT_COMPLETE), - "feature negotiation not complete" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FEATURE_NOT_RENEGOTIABLE), - "feature not renegotiable" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_FRAGMENTED_CLIENT_HELLO), - "fragmented client hello" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_GOT_A_FIN_BEFORE_A_CCS), - "got a fin before a ccs" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_HTTPS_PROXY_REQUEST), - "https proxy request" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_HTTP_REQUEST), "http request" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ILLEGAL_POINT_COMPRESSION), - "illegal point compression" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_ILLEGAL_SUITEB_DIGEST), - "illegal Suite B digest" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INAPPROPRIATE_FALLBACK), - "inappropriate fallback" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_COMPRESSION), - "inconsistent compression" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_EARLY_DATA_ALPN), - "inconsistent early data alpn" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_EARLY_DATA_SNI), - "inconsistent early data sni" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INCONSISTENT_EXTMS), "inconsistent extms" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INSUFFICIENT_SECURITY), - "insufficient security" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_ALERT), "invalid alert" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_CCS_MESSAGE), - "invalid ccs message" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_CERTIFICATE_OR_ALG), - "invalid certificate or alg" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_COMMAND), "invalid command" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_COMPRESSION_ALGORITHM), - "invalid compression algorithm" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_CONFIG), "invalid config" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_CONFIGURATION_NAME), - "invalid configuration name" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_CONTEXT), "invalid context" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_CT_VALIDATION_TYPE), - "invalid ct validation type" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_KEY_UPDATE_TYPE), - "invalid key update type" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_MAX_EARLY_DATA), - "invalid max early data" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_NULL_CMD_NAME), - "invalid null cmd name" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_RAW_PUBLIC_KEY), - "invalid raw public key" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_RECORD), "invalid record" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_SEQUENCE_NUMBER), - "invalid sequence number" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_SERVERINFO_DATA), - "invalid serverinfo data" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_SESSION_ID), "invalid session id" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_SRP_USERNAME), - "invalid srp username" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_STATUS_RESPONSE), - "invalid status response" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_INVALID_TICKET_KEYS_LENGTH), - "invalid ticket keys length" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED), - "legacy sigalg disallowed or unsupported" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LENGTH_MISMATCH), "length mismatch" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LENGTH_TOO_LONG), "length too long" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LENGTH_TOO_SHORT), "length too short" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LIBRARY_BUG), "library bug" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LIBRARY_HAS_NO_CIPHERS), - "library has no ciphers" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_LISTENER_USE_ONLY), "listener use only" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MAXIMUM_ENCRYPTED_PKTS_REACHED), - "maximum encrypted pkts reached" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_DSA_SIGNING_CERT), - "missing dsa signing cert" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_ECDSA_SIGNING_CERT), - "missing ecdsa signing cert" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_FATAL), "missing fatal" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_PARAMETERS), "missing parameters" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_PSK_KEX_MODES_EXTENSION), - "missing psk kex modes extension" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_QUIC_TLS_FUNCTIONS), - "missing quic tls functions" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_RSA_CERTIFICATE), - "missing rsa certificate" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_RSA_ENCRYPTING_CERT), - "missing rsa encrypting cert" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_RSA_SIGNING_CERT), - "missing rsa signing cert" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_SIGALGS_EXTENSION), - "missing sigalgs extension" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_SIGNING_CERT), - "missing signing cert" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_SRP_PARAM), - "can't find SRP server param" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION), - "missing supported groups extension" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_SUPPORTED_VERSIONS_EXTENSION), - "missing supported versions extension" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_TMP_DH_KEY), "missing tmp dh key" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MISSING_TMP_ECDH_KEY), - "missing tmp ecdh key" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA), - "mixed handshake and non handshake data" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_ON_RECORD_BOUNDARY), - "not on record boundary" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_REPLACING_CERTIFICATE), - "not replacing certificate" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NOT_SERVER), "not server" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_APPLICATION_PROTOCOL), - "no application protocol" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CERTIFICATES_RETURNED), - "no certificates returned" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CERTIFICATE_ASSIGNED), - "no certificate assigned" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CERTIFICATE_SET), "no certificate set" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CHANGE_FOLLOWING_HRR), - "no change following hrr" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CIPHERS_AVAILABLE), - "no ciphers available" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CIPHERS_SPECIFIED), - "no ciphers specified" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CIPHER_MATCH), "no cipher match" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_CLIENT_CERT_METHOD), - "no client cert method" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_COMPRESSION_SPECIFIED), - "no compression specified" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_COOKIE_CALLBACK_SET), - "no cookie callback set" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER), - "Peer haven't sent GOST certificate, required for selected ciphersuite" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_METHOD_SPECIFIED), - "no method specified" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_PEM_EXTENSIONS), "no pem extensions" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_PRIVATE_KEY_ASSIGNED), - "no private key assigned" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_PROTOCOLS_AVAILABLE), - "no protocols available" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_RENEGOTIATION), "no renegotiation" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_REQUIRED_DIGEST), "no required digest" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SHARED_CIPHER), "no shared cipher" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SHARED_GROUPS), "no shared groups" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS), - "no shared signature algorithms" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SRTP_PROFILES), "no srtp profiles" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_STREAM), "no stream" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_DIGEST_ALGORITHM), - "no suitable digest algorithm" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_GROUPS), "no suitable groups" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_KEY_SHARE), - "no suitable key share" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_RECORD_LAYER), - "no suitable record layer" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM), - "no suitable signature algorithm" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_VALID_SCTS), "no valid scts" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NO_VERIFY_COOKIE_CALLBACK), - "no verify cookie callback" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NULL_SSL_CTX), "null ssl ctx" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_NULL_SSL_METHOD_PASSED), - "null ssl method passed" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_OCSP_CALLBACK_FAILURE), - "ocsp callback failure" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED), - "old session cipher not returned" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED), - "old session compression algorithm not returned" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_OVERFLOW_ERROR), "overflow error" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PACKET_LENGTH_TOO_LONG), - "packet length too long" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PARSE_TLSEXT), "parse tlsext" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PATH_TOO_LONG), "path too long" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE), - "peer did not return a certificate" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PEM_NAME_BAD_PREFIX), - "pem name bad prefix" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PEM_NAME_TOO_SHORT), "pem name too short" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PIPELINE_FAILURE), "pipeline failure" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_POLL_REQUEST_NOT_SUPPORTED), - "poll request not supported" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR), - "post handshake auth encoding err" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PRIVATE_KEY_MISMATCH), - "private key mismatch" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PROTOCOL_IS_SHUTDOWN), - "protocol is shutdown" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PSK_IDENTITY_NOT_FOUND), - "psk identity not found" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PSK_NO_CLIENT_CB), "psk no client cb" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_PSK_NO_SERVER_CB), "psk no server cb" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_QUIC_HANDSHAKE_LAYER_ERROR), - "quic handshake layer error" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_QUIC_NETWORK_ERROR), "quic network error" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_QUIC_PROTOCOL_ERROR), - "quic protocol error" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_READ_BIO_NOT_SET), "read bio not set" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_READ_TIMEOUT_EXPIRED), - "read timeout expired" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RECORDS_NOT_RELEASED), - "records not released" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RECORD_LAYER_FAILURE), - "record layer failure" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RECORD_LENGTH_MISMATCH), - "record length mismatch" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RECORD_TOO_SMALL), "record too small" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_REMOTE_PEER_ADDRESS_NOT_SET), - "remote peer address not set" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RENEGOTIATE_EXT_TOO_LONG), - "renegotiate ext too long" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RENEGOTIATION_ENCODING_ERR), - "renegotiation encoding err" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_RENEGOTIATION_MISMATCH), - "renegotiation mismatch" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_REQUEST_PENDING), "request pending" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_REQUEST_SENT), "request sent" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_REQUIRED_CIPHER_MISSING), - "required cipher missing" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING), - "required compression algorithm missing" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING), - "scsv received when renegotiating" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SCT_VERIFICATION_FAILED), - "sct verification failed" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SEQUENCE_CTR_WRAPPED), - "sequence ctr wrapped" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SERVERHELLO_TLSEXT), "serverhello tlsext" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED), - "session id context uninitialized" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SHUTDOWN_WHILE_IN_INIT), - "shutdown while in init" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SIGNATURE_ALGORITHMS_ERROR), - "signature algorithms error" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE), - "signature for non signing certificate" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SRP_A_CALC), "error with the srp params" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES), - "srtp could not allocate profiles" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG), - "srtp protection profile list too long" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE), - "srtp unknown protection profile" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_EXT_INVALID_MAX_FRAGMENT_LENGTH), - "tls ext invalid max fragment length" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_EXT_INVALID_SERVERNAME), - "tls ext invalid servername" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_EXT_INVALID_SERVERNAME_TYPE), - "tls ext invalid servername type" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_SESSION_ID_TOO_LONG), - "tls session id too long" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_ALERT_BAD_CERTIFICATE), - "tls alert bad certificate" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_ALERT_BAD_RECORD_MAC), - "tls alert bad record mac" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_ALERT_CERTIFICATE_EXPIRED), - "tls alert certificate expired" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_ALERT_CERTIFICATE_REVOKED), - "tls alert certificate revoked" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_ALERT_CERTIFICATE_UNKNOWN), - "tls alert certificate unknown" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_ALERT_DECOMPRESSION_FAILURE), - "tls alert decompression failure" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_ALERT_HANDSHAKE_FAILURE), - "tls alert handshake failure" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_ALERT_ILLEGAL_PARAMETER), - "tls alert illegal parameter" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_ALERT_NO_CERTIFICATE), - "tls alert no certificate" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_ALERT_UNEXPECTED_MESSAGE), - "tls alert unexpected message" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_ALERT_UNSUPPORTED_CERTIFICATE), - "tls alert unsupported certificate" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_COMMAND_SECTION_EMPTY), - "ssl command section empty" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_COMMAND_SECTION_NOT_FOUND), - "ssl command section not found" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION), - "ssl ctx has no default ssl version" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_HANDSHAKE_FAILURE), - "ssl handshake failure" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS), - "ssl library has no ciphers" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_NEGATIVE_LENGTH), - "ssl negative length" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_SECTION_EMPTY), "ssl section empty" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_SECTION_NOT_FOUND), - "ssl section not found" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_SESSION_ID_CALLBACK_FAILED), - "ssl session id callback failed" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_SESSION_ID_CONFLICT), - "ssl session id conflict" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG), - "ssl session id context too long" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH), - "ssl session id has bad length" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_SESSION_ID_TOO_LONG), - "ssl session id too long" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_SSL_SESSION_VERSION_MISMATCH), - "ssl session version mismatch" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_STILL_IN_INIT), "still in init" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_STREAM_COUNT_LIMITED), - "stream count limited" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_STREAM_FINISHED), "stream finished" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_STREAM_RECV_ONLY), "stream recv only" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_STREAM_RESET), "stream reset" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_STREAM_SEND_ONLY), "stream send only" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED), - "tlsv13 alert certificate required" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV13_ALERT_MISSING_EXTENSION), - "tlsv13 alert missing extension" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_ACCESS_DENIED), - "tlsv1 alert access denied" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_DECODE_ERROR), - "tlsv1 alert decode error" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_DECRYPTION_FAILED), - "tlsv1 alert decryption failed" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_DECRYPT_ERROR), - "tlsv1 alert decrypt error" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION), - "tlsv1 alert export restriction" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK), - "tlsv1 alert inappropriate fallback" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY), - "tlsv1 alert insufficient security" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_INTERNAL_ERROR), - "tlsv1 alert internal error" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_NO_APPLICATION_PROTOCOL), - "tlsv1 alert no application protocol" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_NO_RENEGOTIATION), - "tlsv1 alert no renegotiation" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_PROTOCOL_VERSION), - "tlsv1 alert protocol version" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_RECORD_OVERFLOW), - "tlsv1 alert record overflow" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_UNKNOWN_CA), - "tlsv1 alert unknown ca" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_UNKNOWN_PSK_IDENTITY), - "tlsv1 alert unknown psk identity" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_ALERT_USER_CANCELLED), - "tlsv1 alert user cancelled" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE), - "tlsv1 bad certificate hash value" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE), - "tlsv1 bad certificate status response" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE), - "tlsv1 certificate unobtainable" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_UNRECOGNIZED_NAME), - "tlsv1 unrecognized name" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLSV1_UNSUPPORTED_EXTENSION), - "tlsv1 unsupported extension" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_ILLEGAL_EXPORTER_LABEL), - "tls illegal exporter label" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST), - "tls invalid ecpointformat list" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TOO_MANY_KEY_UPDATES), - "too many key updates" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TOO_MANY_WARN_ALERTS), - "too many warn alerts" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_TOO_MUCH_EARLY_DATA), - "too much early data" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS), - "unable to find ecdh parameters" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS), - "unable to find public key parameters" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_CCS_MESSAGE), - "unexpected ccs message" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_END_OF_EARLY_DATA), - "unexpected end of early data" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_EOF_WHILE_READING), - "unexpected eof while reading" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_MESSAGE), "unexpected message" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNEXPECTED_RECORD), "unexpected record" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNINITIALIZED), "uninitialized" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_ALERT_TYPE), "unknown alert type" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_CERTIFICATE_TYPE), - "unknown certificate type" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_CIPHER_RETURNED), - "unknown cipher returned" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_CIPHER_TYPE), - "unknown cipher type" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_CMD_NAME), "unknown cmd name" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_COMMAND), "unknown command" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_DIGEST), "unknown digest" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE), - "unknown key exchange type" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_MANDATORY_PARAMETER), - "unknown mandatory parameter" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_PKEY_TYPE), "unknown pkey type" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_PROTOCOL), "unknown protocol" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_SSL_VERSION), - "unknown ssl version" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNKNOWN_STATE), "unknown state" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED), - "unsafe legacy renegotiation disabled" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSOLICITED_EXTENSION), - "unsolicited extension" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM), - "unsupported compression algorithm" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_CONFIG_VALUE), - "unsupported config value" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS), - "unsupported config value class" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_CONFIG_VALUE_OP), - "unsupported config value op" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE), - "unsupported elliptic curve" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_PROTOCOL), - "unsupported protocol" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_SSL_VERSION), - "unsupported ssl version" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_STATUS_TYPE), - "unsupported status type" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_UNSUPPORTED_WRITE_FLAG), - "unsupported write flag" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_USE_SRTP_NOT_NEGOTIATED), - "use srtp not negotiated" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_VERSION_TOO_HIGH), "version too high" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_VERSION_TOO_LOW), "version too low" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_CERTIFICATE_TYPE), - "wrong certificate type" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_CIPHER_RETURNED), - "wrong cipher returned" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_CURVE), "wrong curve" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_RPK_TYPE), "wrong rpk type" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_SIGNATURE_LENGTH), - "wrong signature length" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_SIGNATURE_SIZE), - "wrong signature size" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_SIGNATURE_TYPE), - "wrong signature type" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_SSL_VERSION), "wrong ssl version" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_WRONG_VERSION_NUMBER), - "wrong version number" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_X509_LIB), "x509 lib" }, - { ERR_PACK(ERR_LIB_SSL, 0, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS), - "x509 verification setup problems" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_SSL_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(SSL_str_reasons[0].error) == NULL) - ERR_load_strings_const(SSL_str_reasons); -#endif - return 1; -} diff --git a/crypto/sslerr.h b/crypto/sslerr.h deleted file mode 100644 index 968f27b00a6be..0000000000000 --- a/crypto/sslerr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_SSLERR_H -#define OSSL_SSLERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_SSL_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/crypto/store/store_err.c b/crypto/store/store_err.c deleted file mode 100644 index 8ee9d5eebedad..0000000000000 --- a/crypto/store/store_err.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/storeerr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA OSSL_STORE_str_reasons[] = { - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE), - "ambiguous content type" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_BAD_PASSWORD_READ), - "bad password read" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC), - "error verifying pkcs12 mac" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST), - "fingerprint size does not match digest" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_INVALID_SCHEME), - "invalid scheme" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_IS_NOT_A), "is not a" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_LOADER_INCOMPLETE), - "loader incomplete" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_LOADING_STARTED), - "loading started" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_CERTIFICATE), - "not a certificate" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_CRL), "not a crl" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_NAME), "not a name" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_PRIVATE_KEY), - "not a private key" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_PUBLIC_KEY), - "not a public key" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_A_SYMMETRIC_KEY), - "not a symmetric key" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NOT_PARAMETERS), - "not parameters" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_NO_LOADERS_FOUND), - "no loaders found" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR), - "passphrase callback error" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE), - "path must be absolute" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES), - "search only supported for directories" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED), - "ui process interrupted or cancelled" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_UNREGISTERED_SCHEME), - "unregistered scheme" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE), - "unsupported content type" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_UNSUPPORTED_OPERATION), - "unsupported operation" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE), - "unsupported search type" }, - { ERR_PACK(ERR_LIB_OSSL_STORE, 0, OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED), - "uri authority unsupported" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_OSSL_STORE_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(OSSL_STORE_str_reasons[0].error) == NULL) - ERR_load_strings_const(OSSL_STORE_str_reasons); -#endif - return 1; -} diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c index 1086cbcd5b234..902dd3cf6d185 100644 --- a/crypto/store/store_lib.c +++ b/crypto/store/store_lib.c @@ -74,7 +74,7 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, OSSL_STORE_CTX *ctx = NULL; char *propq_copy = NULL; int no_loader_found = 1; - char scheme_copy[256], *p, *schemes[2], *scheme = NULL; + char scheme_copy[256], *p = scheme_copy, *schemes[2], *scheme = NULL; size_t schemes_n = 0; size_t i; @@ -91,14 +91,15 @@ OSSL_STORE_open_ex(const char *uri, OSSL_LIB_CTX *libctx, const char *propq, schemes[schemes_n++] = "file"; /* - * Now, check if we have something that looks like a scheme, and add it + * Now, check if we have a syntactically valid scheme, and add it * as a second scheme. However, also check if there's an authority start * (://), because that will invalidate the previous file scheme. Also, * check that this isn't actually the file scheme, as there's no point * going through that one twice! */ OPENSSL_strlcpy(scheme_copy, uri, sizeof(scheme_copy)); - if ((p = strchr(scheme_copy, ':')) != NULL) { + OSSL_SKIP_SCHEME(p); + if (p != scheme_copy && *p == ':') { *p++ = '\0'; if (OPENSSL_strcasecmp(scheme_copy, "file") != 0) { if (HAS_PREFIX(p, "//")) @@ -1091,6 +1092,7 @@ OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme, } else if (!loader_set_params(fetched_loader, loader_ctx, params, propq)) { (void)fetched_loader->p_close(loader_ctx); + loader_ctx = NULL; OSSL_STORE_LOADER_free(fetched_loader); fetched_loader = NULL; } @@ -1099,20 +1101,16 @@ OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme, } if (loader_ctx == NULL) { - ERR_clear_last_mark(); - return NULL; + goto err; } if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - ERR_clear_last_mark(); - return NULL; + goto err; } if (ui_method != NULL && !ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data)) { - ERR_clear_last_mark(); - OPENSSL_free(ctx); - return NULL; + goto err; } ctx->fetched_loader = fetched_loader; @@ -1129,4 +1127,28 @@ OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme, ERR_pop_to_mark(); return ctx; + +err: + ERR_clear_last_mark(); + if (loader_ctx != NULL) { + /* + * Temporary structure so OSSL_STORE_close() can work even when + * |ctx| couldn't be allocated or initialized properly. + */ + OSSL_STORE_CTX tmpctx = { + NULL, + }; + + tmpctx.fetched_loader = fetched_loader; + tmpctx.loader = loader; + tmpctx.loader_ctx = loader_ctx; + + /* We return NULL regardless of an error while closing. */ + (void)ossl_store_close_it(&tmpctx); + fetched_loader = NULL; + } + + OSSL_STORE_LOADER_free(fetched_loader); + OPENSSL_free(ctx); + return NULL; } diff --git a/crypto/store/store_meth.c b/crypto/store/store_meth.c index 976e4aa734778..5b2b6ac57fe1a 100644 --- a/crypto/store/store_meth.c +++ b/crypto/store/store_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -22,7 +22,7 @@ static int up_ref_loader(void *method) int ref = 0; if (loader->prov != NULL) - CRYPTO_UP_REF(&loader->refcnt, &ref); + return CRYPTO_UP_REF(&loader->refcnt, &ref); return 1; } diff --git a/crypto/store/store_register.c b/crypto/store/store_register.c index c9d789e27b4d6..97a49e8739b91 100644 --- a/crypto/store/store_register.c +++ b/crypto/store/store_register.c @@ -8,7 +8,6 @@ */ #include -#include "crypto/ctype.h" #include #include @@ -165,13 +164,8 @@ int ossl_store_register_loader_int(OSSL_STORE_LOADER *loader) * * scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */ - if (ossl_isalpha(*scheme)) - while (*scheme != '\0' - && (ossl_isalpha(*scheme) - || ossl_isdigit(*scheme) - || strchr("+-.", *scheme) != NULL)) - scheme++; - if (*scheme != '\0') { + OSSL_SKIP_SCHEME(scheme); + if (*loader->scheme == '\0' || *scheme != '\0') { ERR_raise_data(ERR_LIB_OSSL_STORE, OSSL_STORE_R_INVALID_SCHEME, "scheme=%s", loader->scheme); return 0; diff --git a/crypto/store/store_result.c b/crypto/store/store_result.c index a47eb2a601fcd..0a0198ee326e2 100644 --- a/crypto/store/store_result.c +++ b/crypto/store/store_result.c @@ -308,6 +308,12 @@ static EVP_PKEY *try_key_value(struct extracted_param_data_st *data, decoderctx = OSSL_DECODER_CTX_new_for_pkey(&pk, data->input_type, data->data_structure, data->data_type, selection, libctx, propq); + + if (decoderctx == NULL) { + *harderr = 1; + return NULL; + } + (void)OSSL_DECODER_CTX_set_passphrase_cb(decoderctx, cb, cbarg); /* No error if this couldn't be decoded */ @@ -560,9 +566,11 @@ static int try_pkcs12(struct extracted_param_data_st *data, OSSL_STORE_INFO **v, /* There is no specific object type for PKCS12 */ if (data->object_type == OSSL_OBJECT_UNKNOWN) { /* Initial parsing */ - PKCS12 *p12; + PKCS12 *p12 = PKCS12_init_ex(NID_pkcs7_data, libctx, propq); + if (p12 == NULL) + return 0; - p12 = d2i_PKCS12(NULL, (const unsigned char **)&data->octet_data, + p12 = d2i_PKCS12(&p12, (const unsigned char **)&data->octet_data, (long)data->octet_data_size); if (p12 != NULL) { @@ -572,6 +580,8 @@ static int try_pkcs12(struct extracted_param_data_st *data, OSSL_STORE_INFO **v, EVP_PKEY *pkey = NULL; X509 *cert = NULL; STACK_OF(X509) *chain = NULL; + STACK_OF(EVP_SKEY) *skeys = NULL; + PKCS12_PARSE_CTX *pctx = NULL; data->object_type = OSSL_OBJECT_PKCS12; @@ -601,7 +611,7 @@ static int try_pkcs12(struct extracted_param_data_st *data, OSSL_STORE_INFO **v, pass = tpass; /* * ossl_pw_get_passphrase() does not NUL terminate but - * we must do it for PKCS12_parse() + * we must do it for PKCS12_parse_ex() */ pass[tpass_len] = '\0'; if (!PKCS12_verify_mac(p12, pass, (int)tpass_len)) { @@ -612,11 +622,19 @@ static int try_pkcs12(struct extracted_param_data_st *data, OSSL_STORE_INFO **v, } } - if (PKCS12_parse(p12, pass, &pkey, &cert, &chain)) { + if ((pctx = PKCS12_PARSE_CTX_new()) == NULL) + goto p12_end; + PKCS12_PARSE_CTX_set_pkey(pctx, &pkey); + PKCS12_PARSE_CTX_set_cert(pctx, &cert); + PKCS12_PARSE_CTX_set_ca(pctx, &chain); + PKCS12_PARSE_CTX_set_skeys(pctx, &skeys); + + if (PKCS12_parse_ex(p12, pass, pctx, libctx, propq)) { STACK_OF(OSSL_STORE_INFO) *infos = NULL; OSSL_STORE_INFO *osi_pkey = NULL; OSSL_STORE_INFO *osi_cert = NULL; OSSL_STORE_INFO *osi_ca = NULL; + OSSL_STORE_INFO *osi_skey = NULL; ok = 1; /* Parsing went through correctly! */ @@ -639,6 +657,16 @@ static int try_pkcs12(struct extracted_param_data_st *data, OSSL_STORE_INFO **v, else ok = 0; } + while (ok && sk_EVP_SKEY_num(skeys) > 0) { + EVP_SKEY *sk = sk_EVP_SKEY_value(skeys, 0); + + if ((osi_skey = OSSL_STORE_INFO_new_SKEY(sk)) != NULL + && sk_EVP_SKEY_shift(skeys) != NULL + && sk_OSSL_STORE_INFO_push(infos, osi_skey) != 0) + osi_skey = NULL; + else + ok = 0; + } while (ok && sk_X509_num(chain) > 0) { X509 *ca = sk_X509_value(chain, 0); @@ -653,15 +681,18 @@ static int try_pkcs12(struct extracted_param_data_st *data, OSSL_STORE_INFO **v, EVP_PKEY_free(pkey); X509_free(cert); OSSL_STACK_OF_X509_free(chain); + sk_EVP_SKEY_pop_free(skeys, EVP_SKEY_free); OSSL_STORE_INFO_free(osi_pkey); OSSL_STORE_INFO_free(osi_cert); OSSL_STORE_INFO_free(osi_ca); + OSSL_STORE_INFO_free(osi_skey); if (!ok) { sk_OSSL_STORE_INFO_pop_free(infos, OSSL_STORE_INFO_free); infos = NULL; } ctx->cached_info = infos; } + PKCS12_PARSE_CTX_free(pctx); p12_end: OPENSSL_cleanse(tpass, sizeof(tpass)); PKCS12_free(p12); diff --git a/crypto/thread/arch/thread_win.c b/crypto/thread/arch/thread_win.c index 1026ed3de369a..2bd649c3233ba 100644 --- a/crypto/thread/arch/thread_win.c +++ b/crypto/thread/arch/thread_win.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/thread/build.info b/crypto/thread/build.info index b3bada0ed3af4..f24cfedf43495 100644 --- a/crypto/thread/build.info +++ b/crypto/thread/build.info @@ -5,13 +5,13 @@ $THREADS_ARCH=\ arch/thread_win.c arch/thread_posix.c arch/thread_none.c IF[{- !$disabled{'thread-pool'} -}] - IF[{- !$disabled{quic} -}] + IF[{- !$disabled{quic} || !$disabled{dtls} -}] SHARED_SOURCE[../../libssl]=$THREADS_ARCH ENDIF $THREADS=\ api.c internal.c $THREADS_ARCH ELSE - IF[{- !$disabled{quic} -}] + IF[{- !$disabled{quic} || !$disabled{dtls} -}] SOURCE[../../libssl]=$THREADS_ARCH ENDIF $THREADS=api.c arch/thread_win.c diff --git a/crypto/threads_common.c b/crypto/threads_common.c index 52b4d76c5a20f..04f9cd34e4ad4 100644 --- a/crypto/threads_common.c +++ b/crypto/threads_common.c @@ -123,7 +123,7 @@ DEFINE_SPARSE_ARRAY_OF(CTX_TABLE_ENTRY); * */ typedef struct master_key_entry { - SPARSE_ARRAY_OF(CTX_TABLE_ENTRY) * ctx_table; + SPARSE_ARRAY_OF(CTX_TABLE_ENTRY) *ctx_table; } MASTER_KEY_ENTRY; /** diff --git a/crypto/threads_pthread.c b/crypto/threads_pthread.c index 7cf820b54675f..132479bab665d 100644 --- a/crypto/threads_pthread.c +++ b/crypto/threads_pthread.c @@ -1279,10 +1279,10 @@ int CRYPTO_atomic_store_ptr(void **dst, void **val, CRYPTO_RWLOCK *lock) int CRYPTO_atomic_cmp_exch_ptr(void **ptr, void **expect, void *desire, CRYPTO_RWLOCK *lock, int *lock_failed) { -#if defined(__GNUC__) && defined(__ATOMIC_RELAXED) && !defined(BROKEN_CLANG_ATOMICS) +#if defined(__GNUC__) && defined(__ATOMIC_ACQ_REL) && !defined(BROKEN_CLANG_ATOMICS) if (lock_failed != NULL) *lock_failed = 0; - return __atomic_compare_exchange_n(ptr, expect, desire, 0, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED) ? 1 : 0; + return __atomic_compare_exchange_n(ptr, expect, desire, 0, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE) ? 1 : 0; #else int lock_sink; int ret = 0; diff --git a/crypto/threads_win.c b/crypto/threads_win.c index d777010cd8a3c..22b59f64d0b45 100644 --- a/crypto/threads_win.c +++ b/crypto/threads_win.c @@ -183,8 +183,8 @@ void ossl_rcu_lock_free(CRYPTO_RCU_LOCK *lock) /* Read side acquisition of the current qp */ static ossl_inline struct rcu_qp *get_hold_current_qp(CRYPTO_RCU_LOCK *lock) { - uint32_t qp_idx; - uint32_t tmp; + uint32_t qp_idx = 0; + uint32_t tmp = 0; uint64_t tmp64; /* get the current qp index */ @@ -273,7 +273,7 @@ void ossl_rcu_read_unlock(CRYPTO_RCU_LOCK *lock) { struct rcu_thr_data *data = CRYPTO_THREAD_get_local_ex(CRYPTO_THREAD_LOCAL_RCU_KEY, lock->ctx); int i; - LONG64 ret; + LONG64 ret = 0; assert(data != NULL); @@ -611,8 +611,7 @@ int CRYPTO_THREAD_compare_id(CRYPTO_THREAD_ID a, CRYPTO_THREAD_ID b) int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock) { #if (!defined(OSSL_USE_INTERLOCKEDOR64)) - OPENSSL_assert(lock != NULL); - if (!CRYPTO_THREAD_write_lock(lock)) + if (lock == NULL || !CRYPTO_THREAD_write_lock(lock)) return 0; *val += amount; *ret = *val; @@ -632,8 +631,7 @@ int CRYPTO_atomic_add64(uint64_t *val, uint64_t op, uint64_t *ret, CRYPTO_RWLOCK *lock) { #if (!defined(OSSL_USE_INTERLOCKEDOR64)) - OPENSSL_assert(lock != NULL); - if (!CRYPTO_THREAD_write_lock(lock)) + if (lock == NULL || !CRYPTO_THREAD_write_lock(lock)) return 0; *val += op; *ret = *val; @@ -652,8 +650,7 @@ int CRYPTO_atomic_and(uint64_t *val, uint64_t op, uint64_t *ret, CRYPTO_RWLOCK *lock) { #if (!defined(OSSL_USE_INTERLOCKEDOR64)) - OPENSSL_assert(lock != NULL); - if (!CRYPTO_THREAD_write_lock(lock)) + if (lock == NULL || !CRYPTO_THREAD_write_lock(lock)) return 0; *val &= op; *ret = *val; @@ -672,8 +669,7 @@ int CRYPTO_atomic_or(uint64_t *val, uint64_t op, uint64_t *ret, CRYPTO_RWLOCK *lock) { #if (!defined(OSSL_USE_INTERLOCKEDOR64)) - OPENSSL_assert(lock != NULL); - if (!CRYPTO_THREAD_write_lock(lock)) + if (lock == NULL || !CRYPTO_THREAD_write_lock(lock)) return 0; *val |= op; *ret = *val; @@ -691,8 +687,7 @@ int CRYPTO_atomic_or(uint64_t *val, uint64_t op, uint64_t *ret, int CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock) { #if (!defined(OSSL_USE_INTERLOCKEDOR64)) - OPENSSL_assert(lock != NULL); - if (!CRYPTO_THREAD_read_lock(lock)) + if (lock == NULL || !CRYPTO_THREAD_read_lock(lock)) return 0; *ret = *val; if (!CRYPTO_THREAD_unlock(lock)) @@ -708,8 +703,7 @@ int CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock) int CRYPTO_atomic_store(uint64_t *dst, uint64_t val, CRYPTO_RWLOCK *lock) { #if (!defined(OSSL_USE_INTERLOCKEDOR64)) - OPENSSL_assert(lock != NULL); - if (!CRYPTO_THREAD_read_lock(lock)) + if (lock == NULL || !CRYPTO_THREAD_read_lock(lock)) return 0; *dst = val; if (!CRYPTO_THREAD_unlock(lock)) @@ -725,8 +719,7 @@ int CRYPTO_atomic_store(uint64_t *dst, uint64_t val, CRYPTO_RWLOCK *lock) int CRYPTO_atomic_load_int(int *val, int *ret, CRYPTO_RWLOCK *lock) { #if (!defined(OSSL_USE_INTERLOCKEDOR64)) - OPENSSL_assert(lock != NULL); - if (!CRYPTO_THREAD_read_lock(lock)) + if (lock == NULL || !CRYPTO_THREAD_read_lock(lock)) return 0; *ret = *val; if (!CRYPTO_THREAD_unlock(lock)) @@ -743,8 +736,7 @@ int CRYPTO_atomic_load_int(int *val, int *ret, CRYPTO_RWLOCK *lock) int CRYPTO_atomic_store_int(int *dst, int val, CRYPTO_RWLOCK *lock) { #if (!defined(OSSL_USE_INTERLOCKEDOR64)) - OPENSSL_assert(lock != NULL); - if (!CRYPTO_THREAD_read_lock(lock)) + if (lock == NULL || !CRYPTO_THREAD_read_lock(lock)) return 0; *dst = val; if (!CRYPTO_THREAD_unlock(lock)) @@ -781,7 +773,7 @@ int CRYPTO_atomic_cmp_exch_ptr(void **ptr, void **expect, void *desire, CRYPTO_R void *initial; if (lock_failed != NULL) - lock_failed = 0; + *lock_failed = 0; /* Load the current pointer value */ initial = InterlockedCompareExchangePointer(ptr, desire, *expect); diff --git a/crypto/ts/ts_asn1.c b/crypto/ts/ts_asn1.c index b44002ef2f6cd..1aa21c9776e7c 100644 --- a/crypto/ts/ts_asn1.c +++ b/crypto/ts/ts_asn1.c @@ -208,6 +208,7 @@ TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token) ASN1_TYPE *tst_info_wrapper; ASN1_OCTET_STRING *tst_info_der; const unsigned char *p; + size_t len; if (!PKCS7_type_is_signed(token)) { ERR_raise(ERR_LIB_TS, TS_R_BAD_PKCS7_TYPE); @@ -230,5 +231,10 @@ TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token) } tst_info_der = tst_info_wrapper->value.octet_string; p = ASN1_STRING_get0_data(tst_info_der); - return d2i_TS_TST_INFO(NULL, &p, ASN1_STRING_length(tst_info_der)); + len = ASN1_STRING_get_length(tst_info_der); + if (len > INT_MAX) { + ERR_raise(ERR_LIB_TS, TS_R_BAD_TYPE); + return NULL; + } + return d2i_TS_TST_INFO(NULL, &p, (int)len); } diff --git a/crypto/ts/ts_conf.c b/crypto/ts/ts_conf.c index f8d01813df532..6359a4db9887b 100644 --- a/crypto/ts/ts_conf.c +++ b/crypto/ts/ts_conf.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -358,14 +358,26 @@ int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx) for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { CONF_VALUE *val = sk_CONF_VALUE_value(list, i); if (strcmp(val->name, ENV_VALUE_SECS) == 0) { - if (val->value) - secs = atoi(val->value); + if (val->value != NULL + && (!ossl_strtoint(val->value, NULL, 10, &secs) + || secs < 0)) { + ts_CONF_invalid(section, ENV_ACCURACY); + goto err; + } } else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0) { - if (val->value) - millis = atoi(val->value); + if (val->value != NULL + && (!ossl_strtoint(val->value, NULL, 10, &millis) + || millis < 0)) { + ts_CONF_invalid(section, ENV_ACCURACY); + goto err; + } } else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0) { - if (val->value) - micros = atoi(val->value); + if (val->value != NULL + && (!ossl_strtoint(val->value, NULL, 10, µs) + || micros < 0)) { + ts_CONF_invalid(section, ENV_ACCURACY); + goto err; + } } else { ts_CONF_invalid(section, ENV_ACCURACY); goto err; diff --git a/crypto/ts/ts_err.c b/crypto/ts/ts_err.c deleted file mode 100644 index fa3f6bc1696b7..0000000000000 --- a/crypto/ts/ts_err.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/tserr.h" - -#ifndef OPENSSL_NO_TS - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA TS_str_reasons[] = { - { ERR_PACK(ERR_LIB_TS, 0, TS_R_BAD_PKCS7_TYPE), "bad pkcs7 type" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_BAD_TYPE), "bad type" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_CANNOT_LOAD_CERT), "cannot load certificate" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_CANNOT_LOAD_KEY), "cannot load private key" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_CERTIFICATE_VERIFY_ERROR), - "certificate verify error" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_COULD_NOT_SET_ENGINE), - "could not set engine" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_COULD_NOT_SET_TIME), "could not set time" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_DETACHED_CONTENT), "detached content" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_ESS_ADD_SIGNING_CERT_ERROR), - "ess add signing cert error" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR), - "ess add signing cert v2 error" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_ESS_SIGNING_CERTIFICATE_ERROR), - "ess signing certificate error" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_INVALID_NULL_POINTER), - "invalid null pointer" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE), - "invalid signer certificate purpose" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_MESSAGE_IMPRINT_MISMATCH), - "message imprint mismatch" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_NONCE_MISMATCH), "nonce mismatch" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_NONCE_NOT_RETURNED), "nonce not returned" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_NO_CONTENT), "no content" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_NO_TIME_STAMP_TOKEN), "no time stamp token" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_PKCS7_ADD_SIGNATURE_ERROR), - "pkcs7 add signature error" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR), - "pkcs7 add signed attr error" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_PKCS7_TO_TS_TST_INFO_FAILED), - "pkcs7 to ts tst info failed" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_POLICY_MISMATCH), "policy mismatch" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), - "private key does not match certificate" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_RESPONSE_SETUP_ERROR), - "response setup error" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_SIGNATURE_FAILURE), "signature failure" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_THERE_MUST_BE_ONE_SIGNER), - "there must be one signer" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_TIME_SYSCALL_ERROR), "time syscall error" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_TOKEN_NOT_PRESENT), "token not present" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_TOKEN_PRESENT), "token present" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_TSA_NAME_MISMATCH), "tsa name mismatch" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_TSA_UNTRUSTED), "tsa untrusted" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_TST_INFO_SETUP_ERROR), - "tst info setup error" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_TS_DATASIGN), "ts datasign" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_UNACCEPTABLE_POLICY), "unacceptable policy" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_UNSUPPORTED_MD_ALGORITHM), - "unsupported md algorithm" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_UNSUPPORTED_VERSION), "unsupported version" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_VAR_BAD_VALUE), "var bad value" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_VAR_LOOKUP_FAILURE), - "cannot find config variable" }, - { ERR_PACK(ERR_LIB_TS, 0, TS_R_WRONG_CONTENT_TYPE), "wrong content type" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_TS_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(TS_str_reasons[0].error) == NULL) - ERR_load_strings_const(TS_str_reasons); -#endif - return 1; -} -#else -NON_EMPTY_TRANSLATION_UNIT -#endif diff --git a/crypto/ts/ts_lib.c b/crypto/ts/ts_lib.c index 8b46fb4744510..00b40355512e7 100644 --- a/crypto/ts/ts_lib.c +++ b/crypto/ts/ts_lib.c @@ -86,7 +86,7 @@ int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a) BIO_printf(bio, "Message data:\n"); msg = a->hashed_msg; BIO_dump_indent(bio, (const char *)ASN1_STRING_get0_data(msg), - ASN1_STRING_length(msg), 4); + (int)ASN1_STRING_get_length(msg), 4); return 1; } diff --git a/crypto/ts/ts_local.h b/crypto/ts/ts_local.h index be1be4ad5f5b2..99ce6255751b8 100644 --- a/crypto/ts/ts_local.h +++ b/crypto/ts/ts_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/ts/ts_rsp_sign.c b/crypto/ts/ts_rsp_sign.c index 1421275fd9fbd..0495e59408af2 100644 --- a/crypto/ts/ts_rsp_sign.c +++ b/crypto/ts/ts_rsp_sign.c @@ -7,6 +7,8 @@ * https://www.openssl.org/source/license.html */ +#include + #include "internal/e_os.h" #include @@ -16,6 +18,7 @@ #include "internal/cryptlib.h" #include "internal/sizes.h" #include "internal/time.h" +#include "crypto/asn1.h" #include "crypto/ess.h" #include "ts_local.h" @@ -298,7 +301,7 @@ int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, } if (text) { if ((utf8_text = ASN1_UTF8STRING_new()) == NULL - || !ASN1_STRING_set(utf8_text, text, (int)strlen(text))) { + || !ossl_asn1_string_set1_string(utf8_text, text)) { ERR_raise(ERR_LIB_TS, ERR_R_ASN1_LIB); goto err; } @@ -487,7 +490,7 @@ static int ts_RESP_check_request(TS_RESP_CTX *ctx) return 0; } digest = msg_imprint->hashed_msg; - if (ASN1_STRING_length(digest) != md_size) { + if (ASN1_STRING_get_length(digest) != (size_t)md_size) { TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, "Bad message digest."); TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); @@ -645,7 +648,7 @@ static int ossl_ess_add1_signing_cert(PKCS7_SIGNER_INFO *si, p = pp; i2d_ESS_SIGNING_CERT(sc, &p); - if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) { + if ((seq = ASN1_STRING_new()) == NULL || !ossl_asn1_string_set1_data(seq, pp, len)) { ASN1_STRING_free(seq); OPENSSL_free(pp); return 0; @@ -676,7 +679,7 @@ static int ossl_ess_add1_signing_cert_v2(PKCS7_SIGNER_INFO *si, p = pp; i2d_ESS_SIGNING_CERT_V2(sc, &p); - if ((seq = ASN1_STRING_new()) == NULL || !ASN1_STRING_set(seq, pp, len)) { + if ((seq = ASN1_STRING_new()) == NULL || !ossl_asn1_string_set1_data(seq, pp, len)) { ASN1_STRING_free(seq); OPENSSL_free(pp); return 0; @@ -844,6 +847,7 @@ static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision( char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS]; char *p = genTime_str; char *p_end = genTime_str + sizeof(genTime_str); + int n; if (precision > TS_MAX_CLOCK_PRECISION_DIGITS) goto err; @@ -858,12 +862,15 @@ static ASN1_GENERALIZEDTIME *TS_RESP_set_genTime_with_precision( * meet the rfc3161 requirement: "GeneralizedTime syntax can include * fraction-of-second details". */ - p += BIO_snprintf(p, p_end - p, + n = snprintf(p, p_end - p, "%04d%02d%02d%02d%02d%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); + if (n < 0 || n >= p_end - p) + goto err; + p += n; if (precision > 0) { - BIO_snprintf(p, 2 + precision, ".%06ld", usec); + snprintf(p, 2 + precision, ".%06ld", usec); p += strlen(p); /* diff --git a/crypto/ts/ts_rsp_verify.c b/crypto/ts/ts_rsp_verify.c index 1dc70c125bda1..5210df04c5468 100644 --- a/crypto/ts/ts_rsp_verify.c +++ b/crypto/ts/ts_rsp_verify.c @@ -207,24 +207,32 @@ static ESS_SIGNING_CERT *ossl_ess_get_signing_cert(const PKCS7_SIGNER_INFO *si) { const ASN1_TYPE *attr; const unsigned char *p; + size_t len; attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate); if (attr == NULL || attr->type != V_ASN1_SEQUENCE) return NULL; p = ASN1_STRING_get0_data(attr->value.sequence); - return d2i_ESS_SIGNING_CERT(NULL, &p, ASN1_STRING_length(attr->value.sequence)); + len = ASN1_STRING_get_length(attr->value.sequence); + if (len > INT_MAX) + return NULL; + return d2i_ESS_SIGNING_CERT(NULL, &p, (int)len); } static ESS_SIGNING_CERT_V2 *ossl_ess_get_signing_cert_v2(const PKCS7_SIGNER_INFO *si) { const ASN1_TYPE *attr; const unsigned char *p; + size_t len; attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificateV2); if (attr == NULL || attr->type != V_ASN1_SEQUENCE) return NULL; p = ASN1_STRING_get0_data(attr->value.sequence); - return d2i_ESS_SIGNING_CERT_V2(NULL, &p, ASN1_STRING_length(attr->value.sequence)); + len = ASN1_STRING_get_length(attr->value.sequence); + if (len > INT_MAX) + return NULL; + return d2i_ESS_SIGNING_CERT_V2(NULL, &p, (int)len); } static int ts_check_signing_certs(const PKCS7_SIGNER_INFO *si, @@ -482,6 +490,7 @@ static int ts_check_imprints(X509_ALGOR *algor_a, TS_MSG_IMPRINT *b = tst_info->msg_imprint; X509_ALGOR *algor_b = b->hash_algo; int ret = 0; + size_t len; if (algor_a) { if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm)) @@ -495,7 +504,11 @@ static int ts_check_imprints(X509_ALGOR *algor_a, goto err; } - ret = len_a == (unsigned)ASN1_STRING_length(b->hashed_msg) && memcmp(imprint_a, ASN1_STRING_get0_data(b->hashed_msg), len_a) == 0; + len = ASN1_STRING_get_length(b->hashed_msg); + if (len > INT_MAX) + goto err; + + ret = len_a == (unsigned)len && memcmp(imprint_a, ASN1_STRING_get0_data(b->hashed_msg), len) == 0; err: if (!ret) ERR_raise(ERR_LIB_TS, TS_R_MESSAGE_IMPRINT_MISMATCH); diff --git a/crypto/ts/ts_verify_ctx.c b/crypto/ts/ts_verify_ctx.c index ec9993ed9f051..738615dfe8a40 100644 --- a/crypto/ts/ts_verify_ctx.c +++ b/crypto/ts/ts_verify_ctx.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -142,6 +142,7 @@ TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx) X509_ALGOR *md_alg; ASN1_OCTET_STRING *msg; const ASN1_INTEGER *nonce; + size_t tmp; OPENSSL_assert(req != NULL); if (ret) @@ -162,8 +163,11 @@ TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx) if ((ret->md_alg = X509_ALGOR_dup(md_alg)) == NULL) goto err; msg = imprint->hashed_msg; - ret->imprint_len = ASN1_STRING_length(msg); - if (ret->imprint_len <= 0) + tmp = ASN1_STRING_get_length(msg); + if (tmp > INT_MAX) + goto err; + ret->imprint_len = (unsigned int)tmp; + if (ret->imprint_len == 0) goto err; if ((ret->imprint = OPENSSL_malloc(ret->imprint_len)) == NULL) goto err; diff --git a/crypto/ui/ui_err.c b/crypto/ui/ui_err.c deleted file mode 100644 index 1c21b3a4f7454..0000000000000 --- a/crypto/ui/ui_err.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/uierr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA UI_str_reasons[] = { - { ERR_PACK(ERR_LIB_UI, 0, UI_R_COMMON_OK_AND_CANCEL_CHARACTERS), - "common ok and cancel characters" }, - { ERR_PACK(ERR_LIB_UI, 0, UI_R_INDEX_TOO_LARGE), "index too large" }, - { ERR_PACK(ERR_LIB_UI, 0, UI_R_INDEX_TOO_SMALL), "index too small" }, - { ERR_PACK(ERR_LIB_UI, 0, UI_R_NO_RESULT_BUFFER), "no result buffer" }, - { ERR_PACK(ERR_LIB_UI, 0, UI_R_PROCESSING_ERROR), "processing error" }, - { ERR_PACK(ERR_LIB_UI, 0, UI_R_RESULT_TOO_LARGE), "result too large" }, - { ERR_PACK(ERR_LIB_UI, 0, UI_R_RESULT_TOO_SMALL), "result too small" }, - { ERR_PACK(ERR_LIB_UI, 0, UI_R_SYSASSIGN_ERROR), "sys$assign error" }, - { ERR_PACK(ERR_LIB_UI, 0, UI_R_SYSDASSGN_ERROR), "sys$dassgn error" }, - { ERR_PACK(ERR_LIB_UI, 0, UI_R_SYSQIOW_ERROR), "sys$qiow error" }, - { ERR_PACK(ERR_LIB_UI, 0, UI_R_UNKNOWN_CONTROL_COMMAND), - "unknown control command" }, - { ERR_PACK(ERR_LIB_UI, 0, UI_R_UNKNOWN_TTYGET_ERRNO_VALUE), - "unknown ttyget errno value" }, - { ERR_PACK(ERR_LIB_UI, 0, UI_R_USER_DATA_DUPLICATION_UNSUPPORTED), - "user data duplication unsupported" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_UI_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(UI_str_reasons[0].error) == NULL) - ERR_load_strings_const(UI_str_reasons); -#endif - return 1; -} diff --git a/crypto/ui/ui_openssl.c b/crypto/ui/ui_openssl.c index 5b97cc6448216..0778b2811f4de 100644 --- a/crypto/ui/ui_openssl.c +++ b/crypto/ui/ui_openssl.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/vms_rms.h b/crypto/vms_rms.h index 3c3c98ea13d65..8315d2865c508 100644 --- a/crypto/vms_rms.h +++ b/crypto/vms_rms.h @@ -1,5 +1,5 @@ /* - * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/whrlpool/wp_block.c b/crypto/whrlpool/wp_block.c index 62fa849dad84a..95ae0a3bc3e2c 100644 --- a/crypto/whrlpool/wp_block.c +++ b/crypto/whrlpool/wp_block.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/whrlpool/wp_local.h b/crypto/whrlpool/wp_local.h index 8e7c8b52ec133..7bccc35f98546 100644 --- a/crypto/whrlpool/wp_local.h +++ b/crypto/whrlpool/wp_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/x509/build.info b/crypto/x509/build.info index c9ed634b86a61..5ad2b92fb7989 100644 --- a/crypto/x509/build.info +++ b/crypto/x509/build.info @@ -23,3 +23,5 @@ SOURCE[../../libcrypto]=\ IF[{- !$disabled{'deprecated-3.0'} -}] SOURCE[../../libcrypto]=x509type.c ENDIF + +DEPEND[v3_purp.o]=../objects/obj_dat.h diff --git a/crypto/x509/by_dir.c b/crypto/x509/by_dir.c index d9a3e986e994e..2314d21e77c0c 100644 --- a/crypto/x509/by_dir.c +++ b/crypto/x509/by_dir.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -228,7 +228,7 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, X509 st_x509; X509_CRL crl; } data; - int ok = 0; + int res, ok = 0; int i, j, k; unsigned long h; BUF_MEM *b = NULL; @@ -310,35 +310,45 @@ static int get_cert_by_subject_ex(X509_LOOKUP *xl, X509_LOOKUP_TYPE type, * This is special. When c == '\0', no directory separator * should be added. */ - BIO_snprintf(b->data, b->max, + snprintf(b->data, b->max, "%s%08lx.%s%d", ent->dir, h, postfix, k); } else #endif { - BIO_snprintf(b->data, b->max, + snprintf(b->data, b->max, "%s%c%08lx.%s%d", ent->dir, c, h, postfix, k); } #ifndef OPENSSL_NO_POSIX_IO #ifdef _WIN32 +#define lstat _stat #define stat _stat #endif { struct stat st; - if (stat(b->data, &st) < 0) - break; - } + if (lstat(b->data, &st) < 0) + break; /* file does not exist, not even a symlink */ +#ifndef _WIN32 + if (stat(b->data, &st) < 0) { + k++; + continue; /* symlink is broken: following it went wrong */ + } #endif - /* found one. */ - if (type == X509_LU_X509) { - if ((X509_load_cert_file_ex(xl, b->data, ent->dir_type, libctx, - propq)) - == 0) - break; - } else if (type == X509_LU_CRL) { - if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0) - break; } +#endif + res = 0; + ERR_set_mark(); + if (type == X509_LU_X509) + res = X509_load_cert_file_ex(xl, b->data, ent->dir_type, libctx, propq); + else if (type == X509_LU_CRL) + res = X509_load_crl_file(xl, b->data, ent->dir_type); /* else case will caught higher up */ + ERR_pop_to_mark(); + /* unless OPENSSL_NO_POSIX_IO, gracefully skip found file if cert/CRL fails to load. */ +#ifndef OPENSSL_NO_POSIX_IO + res = 1; +#endif + if (res == 0) + break; k++; } diff --git a/crypto/x509/ext_dat.h b/crypto/x509/ext_dat.h index 668f05c6e9505..02f4a5e158eb4 100644 --- a/crypto/x509/ext_dat.h +++ b/crypto/x509/ext_dat.h @@ -1,5 +1,5 @@ /* - * Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/x509/pcy_cache.c b/crypto/x509/pcy_cache.c index bffa96fd6c51d..b3b6a3da1a9a2 100644 --- a/crypto/x509/pcy_cache.c +++ b/crypto/x509/pcy_cache.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/x509/pcy_local.h b/crypto/x509/pcy_local.h index 0892c8dd0b820..491b0236d456f 100644 --- a/crypto/x509/pcy_local.h +++ b/crypto/x509/pcy_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/x509/pcy_tree.c b/crypto/x509/pcy_tree.c index ea3f8ae20b01d..ebc093f6aa46e 100644 --- a/crypto/x509/pcy_tree.c +++ b/crypto/x509/pcy_tree.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/x509/standard_exts.h b/crypto/x509/standard_exts.h index e72cc98da7511..077b7dee35a8f 100644 --- a/crypto/x509/standard_exts.h +++ b/crypto/x509/standard_exts.h @@ -1,5 +1,5 @@ /* - * Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/x509/t_x509.c b/crypto/x509/t_x509.c index cf8062a90205d..8e57d9b32843e 100644 --- a/crypto/x509/t_x509.c +++ b/crypto/x509/t_x509.c @@ -244,7 +244,7 @@ int X509_ocspid_print(BIO *bp, const X509 *x) goto err; if (!EVP_Digest(ASN1_STRING_get0_data(keybstr), - ASN1_STRING_length(keybstr), SHA1md, NULL, md, NULL)) + ASN1_STRING_get_length(keybstr), SHA1md, NULL, md, NULL)) goto err; for (i = 0; i < SHA_DIGEST_LENGTH; i++) { if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) diff --git a/crypto/x509/v3_addr.c b/crypto/x509/v3_addr.c index bdaa74a0d1c00..8bf6fed69e4bc 100644 --- a/crypto/x509/v3_addr.c +++ b/crypto/x509/v3_addr.c @@ -55,9 +55,11 @@ ASN1_SEQUENCE(IPAddressFamily) = { ASN1_ITEM_TEMPLATE(IPAddrBlocks) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, IPAddrBlocks, IPAddressFamily) -static_ASN1_ITEM_TEMPLATE_END(IPAddrBlocks) +ASN1_ITEM_TEMPLATE_END(IPAddrBlocks) - IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange) +IMPLEMENT_ASN1_FUNCTIONS_fname(IPAddrBlocks, IPAddrBlocks, IPAddrBlocks) + +IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange) IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange) IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice) IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily) @@ -409,6 +411,11 @@ static int make_addressPrefix(IPAddressOrRange **result, unsigned char *addr, { int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8; IPAddressOrRange *aor; + unsigned char *prefix = NULL; + uint8_t unused_bits = 0; + + if (bitlen > 0) + unused_bits = 8 - bitlen; if (prefixlen < 0 || prefixlen > (afilen * 8)) return 0; @@ -417,19 +424,23 @@ static int make_addressPrefix(IPAddressOrRange **result, unsigned char *addr, aor->type = IPAddressOrRange_addressPrefix; if (aor->u.addressPrefix == NULL && (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL) goto err; - /* BIT_STRING is a typedef of STRING - * this function allows to set value without checking invalid bits - * as they are nullified after setting */ - if (!ASN1_STRING_set(aor->u.addressPrefix, addr, bytelen)) + if (bytelen > 0) { + prefix = OPENSSL_malloc(bytelen); + if (prefix == NULL) + goto err; + memcpy(prefix, addr, bytelen); + if (unused_bits) + prefix[bytelen - 1] &= ~(0xFF >> bitlen); + } + if (!ASN1_BIT_STRING_set1(aor->u.addressPrefix, prefix, bytelen, unused_bits)) goto err; - if (bitlen > 0) - aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen); - ossl_asn1_bit_string_set_unused_bits(aor->u.addressPrefix, 8 - bitlen); - *result = aor; + + OPENSSL_free(prefix); return 1; err: + OPENSSL_free(prefix); IPAddressOrRange_free(aor); return 0; } @@ -819,39 +830,42 @@ int X509v3_addr_is_canonical(IPAddrBlocks *addr) * After the initial sort, the merge runs as a single linear sweep * over the list using a write index. Adjacent entries are folded * into the previous output by replacing it with a freshly built - * merged range; both old entries are then freed and the source slot - * is left NULL so the asn1 free machinery does not double-free on a - * subsequent abort. Total cost is O(N log N) sort + O(N) merge, - * with no stack deletes inside the loop. + * merged range; both old entries are then freed and the consumed + * source slot is recorded as NULL. Total cost is O(N log N) sort + + * O(N) merge, with no stack deletes inside the loop. + * + * The NULL slots are closed up by a single compaction pass at the end, + * which runs whether the sweep succeeded or failed. This guarantees + * the live stack is always left hole-free, with every occupied slot + * non-NULL, so on error the caller may safely inspect, print, encode, + * free, or retry canonize on the object. The sort comparator + * dereferences every slot with no NULL guard, so a retry (which + * re-sorts) would crash on a hole. is_canonical tolerates NULL by + * returning non-canonical, but the object is still structurally + * invalid. */ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, const unsigned afi) { int length = length_from_afi(afi); int read, write = 0, n; + int ret = 0; sk_IPAddressOrRange_sort(aors); n = sk_IPAddressOrRange_num(aors); - /* - * Error paths below all `return 0` directly. Slots at - * [write..read-1] are NULL (from earlier iterations) and slots at - * [read..n-1] still hold their original entries; the caller's - * normal teardown walks the whole stack and frees each non-NULL - * slot safely, so leaving the stack in this mixed state is sound. - */ for (read = 0; read < n; read++) { IPAddressOrRange *cur = sk_IPAddressOrRange_value(aors, read); unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN]; if (!extract_min_max(cur, c_min, c_max, length)) - return 0; + goto done; /* * Punt inverted range. */ if (memcmp(c_min, c_max, length) > 0) - return 0; + goto done; if (write > 0) { IPAddressOrRange *prev = sk_IPAddressOrRange_value(aors, @@ -861,13 +875,13 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, int j; if (!extract_min_max(prev, p_min, p_max, length)) - return 0; + goto done; /* * Reject overlap with the previous accepted entry. */ if (memcmp(p_max, c_min, length) >= 0) - return 0; + goto done; /* * Adjacency test: does c_min - 1 equal p_max? Work on a @@ -883,11 +897,12 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, IPAddressOrRange *merged; if (!make_addressRange(&merged, p_min, c_max, length)) - return 0; + goto done; /* * Replace prev with merged, free the originals, and - * NULL the source slot so the stack does not retain a - * second reference to cur. + * record the consumed source slot as NULL; the epilogue + * compacts NULLs out of the live stack so it is left + * hole-free whether we succeed or fail. */ (void)sk_IPAddressOrRange_set(aors, write - 1, merged); IPAddressOrRange_free(prev); @@ -909,13 +924,38 @@ static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, write++; } + ret = 1; + +done: /* - * Compaction succeeded: every slot at [write..n-1] is NULL, so - * popping the tail leaves the canonicalised list at [0..write-1]. + * The sweep above NULLs source slots as it folds entries. Whether + * we succeeded or bailed out on an error, the stack must be left + * hole-free, with every occupied slot non-NULL, so that the caller + * may inspect, print, encode, free, or even retry canonize on the + * object without dereferencing NULL. Slide every non-NULL slot + * forward to close the holes, then pop the vacated tail. On success + * this collapses [write..n-1] (all NULL) to length `write`; on error + * it removes the possibly empty contiguous run of NULL slots in + * [write, read), preserving the processed output in [0, write) and + * the untouched original entries in [read, n). */ - while (sk_IPAddressOrRange_num(aors) > write) - (void)sk_IPAddressOrRange_pop(aors); - return 1; + { + int w = 0, r; + + for (r = 0; r < sk_IPAddressOrRange_num(aors); r++) { + IPAddressOrRange *v = sk_IPAddressOrRange_value(aors, r); + + if (v != NULL) { + if (w != r) + (void)sk_IPAddressOrRange_set(aors, w, v); + w++; + } + } + while (sk_IPAddressOrRange_num(aors) > w) + (void)sk_IPAddressOrRange_pop(aors); + } + + return ret; } /* diff --git a/crypto/x509/v3_admis.h b/crypto/x509/v3_admis.h index fa4a409f243bd..fc9b0809410ab 100644 --- a/crypto/x509/v3_admis.h +++ b/crypto/x509/v3_admis.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/x509/v3_akid.c b/crypto/x509/v3_akid.c index f500165d0da84..dc660a42b098d 100644 --- a/crypto/x509/v3_akid.c +++ b/crypto/x509/v3_akid.c @@ -184,9 +184,12 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, i = X509_get_ext_by_NID(issuer_cert, NID_subject_key_identifier, -1); if (i >= 0 && (ext = X509_get_ext(issuer_cert, i)) != NULL && !(same_issuer && !ss)) { - ikeyid = X509V3_EXT_d2i(ext); + + if ((ikeyid = X509V3_EXT_d2i(ext)) == NULL) + goto err; + /* Ignore empty keyids in the issuer cert */ - if (ASN1_STRING_length(ikeyid) == 0) { + if (ASN1_STRING_get_length(ikeyid) == 0) { ASN1_OCTET_STRING_free(ikeyid); ikeyid = NULL; } diff --git a/crypto/x509/v3_asid.c b/crypto/x509/v3_asid.c index c00ded15f9ed5..05aabcc9f6659 100644 --- a/crypto/x509/v3_asid.c +++ b/crypto/x509/v3_asid.c @@ -351,10 +351,17 @@ int X509v3_asid_is_canonical(ASIdentifiers *asid) * After the initial sort, the merge runs as a single linear sweep * over the list using a write index. Each entry is examined once; * adjacent / mergeable entries extend the previous output's upper - * bound in O(1) and the source slot is left NULL so the asn1 free - * machinery does not double-free on a subsequent abort. Total cost - * is O(N log N) sort + O(N) merge, with no stack deletes inside the - * loop. + * bound in O(1) and the consumed source slot is recorded as NULL. + * Total cost is O(N log N) sort + O(N) merge, with no stack deletes + * inside the loop. + * + * The NULL slots are closed up by a single compaction pass at the end, + * which runs whether the sweep succeeded or failed. This guarantees + * the live stack is always left hole-free, with every occupied slot + * non-NULL, so on error the caller may safely inspect, print, encode, + * free, or retry canonize on the object. The sort comparator + * dereferences every slot with no NULL guard, and is_canonical's call + * to extract_min_max would hit its ossl_assert(aor != NULL) on a hole. */ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) { @@ -470,8 +477,10 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) } ASIdOrRange_free(cur); /* - * NULL the source slot so any later teardown does not - * walk a freed pointer. We do not advance `write`. + * Record the consumed source slot as NULL; the epilogue + * compacts NULLs out of the live stack so it is left + * hole-free whether we succeed or fail. We do not + * advance `write`. */ (void)sk_ASIdOrRange_set(choice->u.asIdsOrRanges, read, NULL); continue; @@ -494,15 +503,35 @@ static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) done: /* - * On success every slot at [write..n-1] is NULL, so popping the - * tail leaves the canonicalised list at [0..write-1]. On error we - * leave the tail untouched; the slots are either NULL (from earlier - * iterations) or original entries the loop never reached, both of - * which the caller's ASIdentifierChoice_free path handles safely. + * The sweep above NULLs source slots as it folds entries. Whether + * we succeeded or bailed out on an error, the stack must be left + * hole-free, with every occupied slot non-NULL, so that the caller + * may inspect, print, encode, free, or even retry canonize on the + * object without dereferencing NULL (the sort comparator in + * particular has no NULL guard). Slide every non-NULL slot forward + * to close the holes, then pop the vacated tail. On success this + * collapses [write..n-1] (all NULL) to length `write`; on error it + * removes the possibly empty contiguous run of NULL slots in + * [write, read), preserving the processed output in [0, write) and + * the untouched original entries in [read, n). */ - if (ret) { - while (sk_ASIdOrRange_num(choice->u.asIdsOrRanges) > write) + { + int w = 0, r; + + for (r = 0; r < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); r++) { + ASIdOrRange *v = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, r); + + if (v != NULL) { + if (w != r) + (void)sk_ASIdOrRange_set(choice->u.asIdsOrRanges, w, v); + w++; + } + } + while (sk_ASIdOrRange_num(choice->u.asIdsOrRanges) > w) (void)sk_ASIdOrRange_pop(choice->u.asIdsOrRanges); + } + + if (ret) { /* Paranoia */ if (!ossl_assert(ASIdentifierChoice_is_canonical(choice))) ret = 0; diff --git a/crypto/x509/v3_attrdesc.c b/crypto/x509/v3_attrdesc.c index 997241fac0d6c..3817b076a1641 100644 --- a/crypto/x509/v3_attrdesc.c +++ b/crypto/x509/v3_attrdesc.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -100,7 +100,11 @@ static int i2r_OSSL_INFO_SYNTAX(X509V3_EXT_METHOD *method, case OSSL_INFO_SYNTAX_TYPE_CONTENT: if (BIO_printf(out, "%*sContent: ", indent, "") <= 0) return 0; - if (BIO_printf(out, "%.*s", info->choice.content->length, info->choice.content->data) <= 0) + if (BIO_printf(out, "%.*s", info->choice.content->length, + info->choice.content->length + ? info->choice.content->data + : (const unsigned char *)"") + <= 0) return 0; if (BIO_puts(out, "\n") <= 0) return 0; @@ -145,18 +149,28 @@ static int i2r_OSSL_ATTRIBUTE_DESCRIPTOR(X509V3_EXT_METHOD *method, if (BIO_printf(out, "%*sSyntax:\n", indent, "") <= 0) return 0; if (BIO_printf(out, "%*s%.*s", indent + 4, "", - ad->attributeSyntax->length, ad->attributeSyntax->data) + ad->attributeSyntax->length, + ad->attributeSyntax->length + ? ad->attributeSyntax->data + : (const unsigned char *)"") <= 0) return 0; if (BIO_puts(out, "\n\n") <= 0) return 0; if (ad->name != NULL) { - if (BIO_printf(out, "%*sName: %.*s\n", indent, "", ad->name->length, ad->name->data) <= 0) + if (BIO_printf(out, "%*sName: %.*s\n", indent, "", ad->name->length, + ad->name->length + ? ad->name->data + : (const unsigned char *)"") + <= 0) return 0; } if (ad->description != NULL) { if (BIO_printf(out, "%*sDescription: %.*s\n", indent, "", - ad->description->length, ad->description->data) + ad->description->length, + ad->description->length + ? ad->description->data + : (const unsigned char *)"") <= 0) return 0; } diff --git a/crypto/x509/v3_battcons.c b/crypto/x509/v3_battcons.c index 2905fb4398b90..3a9731ee8d503 100644 --- a/crypto/x509/v3_battcons.c +++ b/crypto/x509/v3_battcons.c @@ -61,7 +61,7 @@ static OSSL_BASIC_ATTR_CONSTRAINTS *v2i_OSSL_BASIC_ATTR_CONSTRAINTS( { OSSL_BASIC_ATTR_CONSTRAINTS *battcons = NULL; CONF_VALUE *val; - int i; + int i, authority_seen = 0; if ((battcons = OSSL_BASIC_ATTR_CONSTRAINTS_new()) == NULL) { ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); @@ -70,9 +70,20 @@ static OSSL_BASIC_ATTR_CONSTRAINTS *v2i_OSSL_BASIC_ATTR_CONSTRAINTS( for (i = 0; i < sk_CONF_VALUE_num(values); i++) { val = sk_CONF_VALUE_value(values, i); if (strcmp(val->name, "authority") == 0) { + if (authority_seen) { + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_DUPLICATE_FIELD, + "field=%s", val->name); + goto err; + } if (!X509V3_get_value_bool(val, &battcons->authority)) goto err; + authority_seen = 1; } else if (strcmp(val->name, "pathlen") == 0) { + if (battcons->pathlen != NULL) { + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_DUPLICATE_FIELD, + "field=%s", val->name); + goto err; + } if (!X509V3_get_value_int(val, &battcons->pathlen)) goto err; } else { diff --git a/crypto/x509/v3_bcons.c b/crypto/x509/v3_bcons.c index 21e819542dff0..debfc9a3fed00 100644 --- a/crypto/x509/v3_bcons.c +++ b/crypto/x509/v3_bcons.c @@ -60,7 +60,7 @@ static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, { BASIC_CONSTRAINTS *bcons = NULL; CONF_VALUE *val; - int i; + int i, ca_seen = 0; if ((bcons = BASIC_CONSTRAINTS_new()) == NULL) { ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); @@ -69,9 +69,20 @@ static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, for (i = 0; i < sk_CONF_VALUE_num(values); i++) { val = sk_CONF_VALUE_value(values, i); if (strcmp(val->name, "CA") == 0) { + if (ca_seen) { + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_DUPLICATE_FIELD, + "field=%s", val->name); + goto err; + } if (!X509V3_get_value_bool(val, &bcons->ca)) goto err; + ca_seen = 1; } else if (strcmp(val->name, "pathlen") == 0) { + if (bcons->pathlen != NULL) { + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_DUPLICATE_FIELD, + "field=%s", val->name); + goto err; + } if (!X509V3_get_value_int(val, &bcons->pathlen)) goto err; } else { diff --git a/crypto/x509/v3_bitst.c b/crypto/x509/v3_bitst.c index 1b0204bf75d70..2befd2994b133 100644 --- a/crypto/x509/v3_bitst.c +++ b/crypto/x509/v3_bitst.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/x509/v3_conf.c b/crypto/x509/v3_conf.c index 6b6f8457356e6..520453a9131d6 100644 --- a/crypto/x509/v3_conf.c +++ b/crypto/x509/v3_conf.c @@ -58,7 +58,14 @@ static X509_EXTENSION *X509V3_EXT_nconf_int(CONF *conf, X509V3_CTX *ctx, X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, const char *value) { - return X509V3_EXT_nconf_int(conf, ctx, NULL, name, value); + X509V3_CTX tmpctx; + + if (ctx == NULL) { + X509V3_set_ctx(&tmpctx, NULL, NULL, NULL, NULL, 0); + X509V3_set_nconf(&tmpctx, conf); + } + + return X509V3_EXT_nconf_int(conf, ctx ? ctx : &tmpctx, NULL, name, value); } X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, @@ -66,12 +73,18 @@ X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, { int crit; int ext_type; + X509V3_CTX tmpctx; + + if (ctx == NULL) { + X509V3_set_ctx(&tmpctx, NULL, NULL, NULL, NULL, 0); + X509V3_set_nconf(&tmpctx, conf); + } crit = v3_check_critical(&value); if ((ext_type = v3_check_generic(&value))) return v3_generic_extension(OBJ_nid2sn(ext_nid), - value, crit, ext_type, ctx); - return do_ext_nconf(conf, ctx, ext_nid, crit, value); + value, crit, ext_type, ctx ? ctx : &tmpctx); + return do_ext_nconf(conf, ctx ? ctx : &tmpctx, ext_nid, crit, value); } /* CONF *conf: Config file */ @@ -313,6 +326,13 @@ int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, const char *section, STACK_OF(CONF_VALUE) *nval; const CONF_VALUE *val; int i, akid = -1, skid = -1; + X509V3_CTX tmpctx; + + if (ctx == NULL) { + X509V3_set_ctx(&tmpctx, NULL, NULL, NULL, NULL, 0); + X509V3_set_nconf(&tmpctx, conf); + ctx = &tmpctx; + } if ((nval = NCONF_get_section(conf, section)) == NULL) return 0; diff --git a/crypto/x509/v3_cpols.c b/crypto/x509/v3_cpols.c index 0dc8f76ad49cb..0414f3d387385 100644 --- a/crypto/x509/v3_cpols.c +++ b/crypto/x509/v3_cpols.c @@ -208,8 +208,7 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx, ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } - if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value, - (int)strlen(cnf->value))) { + if (!ossl_asn1_string_set1_string(qual->d.cpsuri, cnf->value)) { ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } @@ -325,7 +324,7 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, if (tag_len != 0) value += tag_len + 1; len = (int)strlen(value); - if (!ASN1_STRING_set(not->exptext, value, len)) { + if (!ossl_asn1_string_set1_data(not->exptext, (uint8_t *)value, len)) { ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } @@ -344,8 +343,7 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, nref->organization->type = V_ASN1_IA5STRING; else nref->organization->type = V_ASN1_VISIBLESTRING; - if (!ASN1_STRING_set(nref->organization, cnf->value, - (int)strlen(cnf->value))) { + if (!ossl_asn1_string_set1_string(nref->organization, cnf->value)) { ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } @@ -446,7 +444,9 @@ static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, case NID_id_qt_cps: BIO_printf(out, "%*sCPS: %.*s", indent, "", qualinfo->d.cpsuri->length, - qualinfo->d.cpsuri->data); + qualinfo->d.cpsuri->length + ? qualinfo->d.cpsuri->data + : (const unsigned char *)""); break; case NID_id_qt_unotice: @@ -471,7 +471,9 @@ static void print_notice(BIO *out, USERNOTICE *notice, int indent) ref = notice->noticeref; BIO_printf(out, "%*sOrganization: %.*s\n", indent, "", ref->organization->length, - ref->organization->data); + ref->organization->length + ? ref->organization->data + : (const unsigned char *)""); BIO_printf(out, "%*sNumber%s: ", indent, "", sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : ""); for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) { @@ -496,7 +498,9 @@ static void print_notice(BIO *out, USERNOTICE *notice, int indent) if (notice->exptext) BIO_printf(out, "%*sExplicit Text: %.*s", indent, "", notice->exptext->length, - notice->exptext->data); + notice->exptext->length + ? notice->exptext->data + : (const unsigned char *)""); } void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent) diff --git a/crypto/x509/v3_genn.c b/crypto/x509/v3_genn.c index 23a2435842f71..db42d5a415861 100644 --- a/crypto/x509/v3_genn.c +++ b/crypto/x509/v3_genn.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/x509/v3_ia5.c b/crypto/x509/v3_ia5.c index 539c43a141a0c..35cc81a2ea239 100644 --- a/crypto/x509/v3_ia5.c +++ b/crypto/x509/v3_ia5.c @@ -52,7 +52,7 @@ ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); return NULL; } - if (!ASN1_STRING_set((ASN1_STRING *)ia5, str, (int)strlen(str))) { + if (!ossl_asn1_string_set1_string((ASN1_STRING *)ia5, str)) { ASN1_IA5STRING_free(ia5); return NULL; } diff --git a/crypto/x509/v3_info.c b/crypto/x509/v3_info.c index e49e251667ac5..b987f84fa2d33 100644 --- a/crypto/x509/v3_info.c +++ b/crypto/x509/v3_info.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -84,7 +84,7 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS( ntmp = OPENSSL_malloc(nlen); if (ntmp == NULL) goto err; - BIO_snprintf(ntmp, nlen, "%s - %s", objtmp, vtmp->name); + snprintf(ntmp, nlen, "%s - %s", objtmp, vtmp->name); OPENSSL_free(vtmp->name); vtmp->name = ntmp; } diff --git a/crypto/x509/v3_ist.c b/crypto/x509/v3_ist.c index 0409b52d60371..aaaa91aacb88d 100644 --- a/crypto/x509/v3_ist.c +++ b/crypto/x509/v3_ist.c @@ -52,28 +52,28 @@ static ISSUER_SIGN_TOOL *v2i_issuer_sign_tool(X509V3_EXT_METHOD *method, X509V3_ if (strcmp(cnf->name, "signTool") == 0) { if (ist->signTool == NULL || cnf->value == NULL - || !ASN1_STRING_set(ist->signTool, cnf->value, (int)strlen(cnf->value))) { + || !ossl_asn1_string_set1_string(ist->signTool, cnf->value)) { ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } } else if (strcmp(cnf->name, "cATool") == 0) { if (ist->cATool == NULL || cnf->value == NULL - || !ASN1_STRING_set(ist->cATool, cnf->value, (int)strlen(cnf->value))) { + || !ossl_asn1_string_set1_string(ist->cATool, cnf->value)) { ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } } else if (strcmp(cnf->name, "signToolCert") == 0) { if (ist->signToolCert == NULL || cnf->value == NULL - || !ASN1_STRING_set(ist->signToolCert, cnf->value, (int)strlen(cnf->value))) { + || !ossl_asn1_string_set1_string(ist->signToolCert, cnf->value)) { ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } } else if (strcmp(cnf->name, "cAToolCert") == 0) { if (ist->cAToolCert == NULL || cnf->value == NULL - || !ASN1_STRING_set(ist->cAToolCert, cnf->value, (int)strlen(cnf->value))) { + || !ossl_asn1_string_set1_string(ist->cAToolCert, cnf->value)) { ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); goto err; } diff --git a/crypto/x509/v3_lib.c b/crypto/x509/v3_lib.c index aee7ad119f34d..a4b46d0924806 100644 --- a/crypto/x509/v3_lib.c +++ b/crypto/x509/v3_lib.c @@ -169,16 +169,18 @@ void *X509V3_EXT_d2i(const X509_EXTENSION *ext) const X509V3_EXT_METHOD *method; const unsigned char *p; const ASN1_STRING *extvalue; - int extlen; + size_t extlen; if ((method = X509V3_EXT_get(ext)) == NULL) return NULL; extvalue = X509_EXTENSION_get_data(ext); p = ASN1_STRING_get0_data(extvalue); - extlen = ASN1_STRING_length(extvalue); + extlen = ASN1_STRING_get_length(extvalue); + if (extlen > INT_MAX) + return NULL; if (method->it) - return ASN1_item_d2i(NULL, &p, extlen, ASN1_ITEM_ptr(method->it)); - return method->d2i(NULL, &p, extlen); + return ASN1_item_d2i(NULL, &p, (int)extlen, ASN1_ITEM_ptr(method->it)); + return method->d2i(NULL, &p, (int)extlen); } /*- diff --git a/crypto/x509/v3_pci.c b/crypto/x509/v3_pci.c index 78e76e130c61a..ce56e4c6a12da 100644 --- a/crypto/x509/v3_pci.c +++ b/crypto/x509/v3_pci.c @@ -166,6 +166,13 @@ static int process_pci_value(CONF_VALUE *val, } else if (CHECK_AND_SKIP_PREFIX(valp, "file:")) { unsigned char buf[2048]; int n; + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + /* + * Prevent fuzzer from mutating input to reading random files. + */ + valp = NULL; +#endif BIO *b = BIO_new_file(valp, "r"); if (!b) { ERR_raise(ERR_LIB_X509V3, ERR_R_BIO_LIB); diff --git a/crypto/x509/v3_pcons.c b/crypto/x509/v3_pcons.c index e8c3d242d9ac9..c67ade1eb19c0 100644 --- a/crypto/x509/v3_pcons.c +++ b/crypto/x509/v3_pcons.c @@ -1,5 +1,5 @@ /* - * Copyright 2003-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2003-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -67,9 +67,19 @@ static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, for (i = 0; i < sk_CONF_VALUE_num(values); i++) { val = sk_CONF_VALUE_value(values, i); if (strcmp(val->name, "requireExplicitPolicy") == 0) { + if (pcons->requireExplicitPolicy != NULL) { + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_DUPLICATE_FIELD, + "field=%s", val->name); + goto err; + } if (!X509V3_get_value_int(val, &pcons->requireExplicitPolicy)) goto err; } else if (strcmp(val->name, "inhibitPolicyMapping") == 0) { + if (pcons->inhibitPolicyMapping != NULL) { + ERR_raise_data(ERR_LIB_X509V3, X509V3_R_DUPLICATE_FIELD, + "field=%s", val->name); + goto err; + } if (!X509V3_get_value_int(val, &pcons->inhibitPolicyMapping)) goto err; } else { diff --git a/crypto/x509/v3_prn.c b/crypto/x509/v3_prn.c index 4a0df33ea3182..e890183134550 100644 --- a/crypto/x509/v3_prn.c +++ b/crypto/x509/v3_prn.c @@ -73,24 +73,26 @@ int X509V3_EXT_print(BIO *out, const X509_EXTENSION *ext, unsigned long flag, char *value = NULL; const ASN1_OCTET_STRING *extoct; const unsigned char *p; - int extlen; + size_t extlen; const X509V3_EXT_METHOD *method; STACK_OF(CONF_VALUE) *nval = NULL; int ok = 1; extoct = X509_EXTENSION_get_data(ext); p = ASN1_STRING_get0_data(extoct); - extlen = ASN1_STRING_length(extoct); + extlen = ASN1_STRING_get_length(extoct); + if (extlen > INT_MAX) + return 0; if ((method = X509V3_EXT_get(ext)) == NULL) - return unknown_ext_print(out, p, extlen, flag, indent, 0); + return unknown_ext_print(out, p, (int)extlen, flag, indent, 0); if (method->it) - ext_str = ASN1_item_d2i(NULL, &p, extlen, ASN1_ITEM_ptr(method->it)); + ext_str = ASN1_item_d2i(NULL, &p, (int)extlen, ASN1_ITEM_ptr(method->it)); else - ext_str = method->d2i(NULL, &p, extlen); + ext_str = method->d2i(NULL, &p, (int)extlen); if (!ext_str) - return unknown_ext_print(out, p, extlen, flag, indent, 1); + return unknown_ext_print(out, p, (int)extlen, flag, indent, 1); if (method->i2s) { if ((value = method->i2s(method, ext_str)) == NULL) { diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c index 462e2f12c824f..f13d785a38468 100644 --- a/crypto/x509/v3_purp.c +++ b/crypto/x509/v3_purp.c @@ -518,8 +518,8 @@ static void scan_ext_flags(const X509 *x509, uint32_t *flags) /* * Cache info on various X.509v3 extensions and further derived information, * e.g., if cert 'x' is self-issued, in x->ex_flags and other internal fields. - * x->sha1_hash is filled in, or else EXFLAG_NO_FINGERPRINT is set in x->flags. - * X509_SIG_INFO_VALID is set in x->flags if x->siginf was filled successfully. + * x->fingerprint is filled in, or else EXFLAG_NO_FINGERPRINT is set in + * x->ex_flags. * Set EXFLAG_INVALID and return 0 in case the certificate is invalid. * * This is usually called by side-effect on objects, and forces us to keep @@ -537,7 +537,7 @@ int ossl_x509v3_cache_extensions(const X509 *const_x) int i; int res; uint32_t tmp_ex_flags; - unsigned char tmp_sha1_hash[SHA_DIGEST_LENGTH]; + unsigned char tmp_fingerprint[OSSL_X509_FINGERPRINT_SIZE]; long tmp_ex_pathlen; long tmp_ex_pcpathlen; uint32_t tmp_ex_kusage; @@ -548,7 +548,6 @@ int ossl_x509v3_cache_extensions(const X509 *const_x) STACK_OF(GENERAL_NAME) *tmp_altname; NAME_CONSTRAINTS *tmp_nc; STACK_OF(DIST_POINT) *tmp_crldp = NULL; - X509_SIG_INFO tmp_siginf; #ifdef tsan_ld_acq /* Fast lock-free check, see end of the function for details. */ @@ -570,8 +569,8 @@ int ossl_x509v3_cache_extensions(const X509 *const_x) ERR_set_mark(); - /* Cache the SHA1 digest of the cert */ - if (!X509_digest(const_x, EVP_sha1(), tmp_sha1_hash, NULL)) + if (!ossl_x509_internal_fingerprint(ASN1_ITEM_rptr(X509), const_x, + tmp_fingerprint)) tmp_ex_flags |= EXFLAG_NO_FINGERPRINT; /* V1 should mean no extensions ... */ @@ -710,8 +709,15 @@ int ossl_x509v3_cache_extensions(const X509 *const_x) * we could afford doing the (accurate) actual self-signature check, but * decided against it for efficiency reasons and according to RFC 5280, * CA certs MUST have an SKID and non-root certs MUST have an AKID. + * + * The cached const_x->skid is not populated until the write-lock + * publication below, so the keyid comparison is done directly + * against tmp_skid. X509_check_akid() is retained for its serial + * number and issuer name checks. */ - if (X509_check_akid(const_x, tmp_akid) == X509_V_OK + if ((tmp_akid == NULL || tmp_akid->keyid == NULL || tmp_skid == NULL + || ASN1_OCTET_STRING_cmp(tmp_akid->keyid, tmp_skid) == 0) + && X509_check_akid(const_x, tmp_akid) == X509_V_OK && check_sig_alg_match(X509_get0_pubkey(const_x), const_x) == X509_V_OK) { /* * Assume self-signed if the signature alg matches the pkey alg and @@ -751,9 +757,6 @@ int ossl_x509v3_cache_extensions(const X509 *const_x) scan_ext_flags(const_x, &tmp_ex_flags); - /* Set x->siginf, ignoring errors due to unsupported algos */ - (void)ossl_x509_init_sig_info(const_x, &tmp_siginf); - tmp_ex_flags |= EXFLAG_SET; /* Indicate that cert has been processed */ ERR_pop_to_mark(); @@ -768,7 +771,8 @@ int ossl_x509v3_cache_extensions(const X509 *const_x) ((X509 *)const_x)->ex_pathlen = tmp_ex_pathlen; ((X509 *)const_x)->ex_pcpathlen = tmp_ex_pcpathlen; if (!(tmp_ex_flags & EXFLAG_NO_FINGERPRINT)) - memcpy(((X509 *)const_x)->sha1_hash, tmp_sha1_hash, SHA_DIGEST_LENGTH); + memcpy(((X509 *)const_x)->fingerprint, tmp_fingerprint, + sizeof(tmp_fingerprint)); if (tmp_ex_flags & EXFLAG_KUSAGE) ((X509 *)const_x)->ex_kusage = tmp_ex_kusage; ((X509 *)const_x)->ex_xkusage = tmp_ex_xkusage; @@ -790,7 +794,6 @@ int ossl_x509v3_cache_extensions(const X509 *const_x) ASIdentifiers_free(((X509 *)const_x)->rfc3779_asid); ((X509 *)const_x)->rfc3779_asid = tmp_rfc3779_asid; #endif - ((X509 *)const_x)->siginf = tmp_siginf; #ifdef tsan_st_rel tsan_st_rel((TSAN_QUALIFIER int *)&const_x->ex_cached, 1); diff --git a/crypto/x509/v3_san.c b/crypto/x509/v3_san.c index 0f12939d6d254..0defca074d8de 100644 --- a/crypto/x509/v3_san.c +++ b/crypto/x509/v3_san.c @@ -128,7 +128,7 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, break; default: if (OBJ_obj2txt(oline, sizeof(oline), gen->d.otherName->type_id, 0) > 0) - BIO_snprintf(othername, sizeof(othername), "othername: %s", + snprintf(othername, sizeof(othername), "othername: %s", oline); else OPENSSL_strlcpy(othername, "othername", sizeof(othername)); @@ -225,27 +225,37 @@ int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) case NID_id_on_SmtpUTF8Mailbox: BIO_printf(out, "othername:SmtpUTF8Mailbox:%.*s", gen->d.otherName->value->value.utf8string->length, - gen->d.otherName->value->value.utf8string->data); + gen->d.otherName->value->value.utf8string->length + ? gen->d.otherName->value->value.utf8string->data + : (const unsigned char *)""); break; case NID_XmppAddr: BIO_printf(out, "othername:XmppAddr:%.*s", gen->d.otherName->value->value.utf8string->length, - gen->d.otherName->value->value.utf8string->data); + gen->d.otherName->value->value.utf8string->length + ? gen->d.otherName->value->value.utf8string->data + : (const unsigned char *)""); break; case NID_SRVName: BIO_printf(out, "othername:SRVName:%.*s", gen->d.otherName->value->value.ia5string->length, - gen->d.otherName->value->value.ia5string->data); + gen->d.otherName->value->value.ia5string->length + ? gen->d.otherName->value->value.ia5string->data + : (const unsigned char *)""); break; case NID_ms_upn: BIO_printf(out, "othername:UPN:%.*s", gen->d.otherName->value->value.utf8string->length, - gen->d.otherName->value->value.utf8string->data); + gen->d.otherName->value->value.utf8string->length + ? gen->d.otherName->value->value.utf8string->data + : (const unsigned char *)""); break; case NID_NAIRealm: BIO_printf(out, "othername:NAIRealm:%.*s", gen->d.otherName->value->value.utf8string->length, - gen->d.otherName->value->value.utf8string->data); + gen->d.otherName->value->value.utf8string->length + ? gen->d.otherName->value->value.utf8string->data + : (const unsigned char *)""); break; default: BIO_printf(out, "othername:"); @@ -575,7 +585,8 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, } if (is_string) { - if ((gen->d.ia5 = ASN1_IA5STRING_new()) == NULL || !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, (int)strlen(value))) { + if ((gen->d.ia5 = ASN1_IA5STRING_new()) == NULL + || !ossl_asn1_string_set1_string(gen->d.ia5, value)) { ASN1_IA5STRING_free(gen->d.ia5); gen->d.ia5 = NULL; ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); diff --git a/crypto/x509/v3_timespec.c b/crypto/x509/v3_timespec.c index f29265f4be2f7..4dcf0fce289e6 100644 --- a/crypto/x509/v3_timespec.c +++ b/crypto/x509/v3_timespec.c @@ -1,5 +1,5 @@ /* - * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -142,7 +142,11 @@ static int i2r_OSSL_TIME_SPEC_ABSOLUTE(X509V3_EXT_METHOD *method, return 0; if (!ossl_asn1_time_print_ex(out, time->startTime, 0)) return 0; - if (BIO_printf(out, "%.*s", time->startTime->length, time->startTime->data) <= 0) + if (BIO_printf(out, "%.*s", time->startTime->length, + time->startTime->length + ? time->startTime->data + : (const unsigned char *)"") + <= 0) return 0; } else if (time->endTime != NULL) { if (!BIO_puts(out, "Any time until ")) diff --git a/crypto/x509/v3_usernotice.c b/crypto/x509/v3_usernotice.c index 8a53eff96e5a5..ce6627bf23187 100644 --- a/crypto/x509/v3_usernotice.c +++ b/crypto/x509/v3_usernotice.c @@ -29,7 +29,9 @@ static int print_notice(BIO *out, USERNOTICE *notice, int indent) ref = notice->noticeref; if (BIO_printf(out, "%*sOrganization: %.*s\n", indent, "", ref->organization->length, - ref->organization->data) + ref->organization->length + ? ref->organization->data + : (const unsigned char *)"") <= 0) return 0; if (BIO_printf(out, "%*sNumber%s: ", indent, "", @@ -61,7 +63,9 @@ static int print_notice(BIO *out, USERNOTICE *notice, int indent) return BIO_printf(out, "%*sExplicit Text: %.*s", indent, "", notice->exptext->length, - notice->exptext->data) + notice->exptext->length + ? notice->exptext->data + : (const unsigned char *)"") >= 0; } diff --git a/crypto/x509/v3_utf8.c b/crypto/x509/v3_utf8.c index 49095ffdd982c..fcc932f766fde 100644 --- a/crypto/x509/v3_utf8.c +++ b/crypto/x509/v3_utf8.c @@ -55,7 +55,7 @@ ASN1_UTF8STRING *s2i_ASN1_UTF8STRING(X509V3_EXT_METHOD *method, ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); return NULL; } - if (!ASN1_STRING_set((ASN1_STRING *)utf8, str, (int)strlen(str))) { + if (!ossl_asn1_string_set1_string(utf8, str)) { ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); ASN1_UTF8STRING_free(utf8); return NULL; diff --git a/crypto/x509/v3_utl.c b/crypto/x509/v3_utl.c index 4ccfcacadb493..88c19ab7d29c6 100644 --- a/crypto/x509/v3_utl.c +++ b/crypto/x509/v3_utl.c @@ -874,7 +874,6 @@ static int do_x509_check(const X509 *x, const char *chk, size_t chklen, int i; int cnid = NID_undef; int alt_type; - int san_present = 0; int rv = 0; equal_fn equal; @@ -934,15 +933,8 @@ static int do_x509_check(const X509 *x, const char *chk, size_t chklen, * SmtpUTF8Mailbox is encoded as UTF8String. * * If it is not a UTF8String then that is unexpected, and - * we ignore the invalid SAN (neither set san_present nor - * consider it a candidate for equality). This does mean - * that the subject CN may be considered, as would be the - * case when the malformed SmtpUtf8Mailbox SAN is instead - * simply absent. - * - * When CN-ID matching is not desirable, applications can - * choose to turn it off, doing so is at this time a best - * practice. + * we ignore the invalid SAN, so it is not considered a + * candidate for equality. */ if (othername_nid != NID_id_on_SmtpUTF8Mailbox || gen->d.otherName->value->type != V_ASN1_UTF8STRING) @@ -968,7 +960,6 @@ static int do_x509_check(const X509 *x, const char *chk, size_t chklen, cstr = gen->d.iPAddress; break; } - san_present = 1; /* Positive on success, negative on error! */ if ((rv = do_check_string(cstr, alt_type, equal, flags, chk, chklen, peername)) @@ -978,12 +969,17 @@ static int do_x509_check(const X509 *x, const char *chk, size_t chklen, GENERAL_NAMES_free(gens); if (rv != 0) return rv; - if (san_present && !(flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT)) - return 0; } - /* We're done if CN-ID is not pertinent */ - if (cnid == NID_undef || (flags & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT)) + /* + * The subject DN is not consulted by default: the subject commonName or + * emailAddress is matched only when the caller explicitly opts in with + * X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT, and never when + * X509_CHECK_FLAG_NEVER_CHECK_SUBJECT is set. + */ + if (cnid == NID_undef + || (flags & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT) != 0 + || (flags & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT) == 0) return 0; i = -1; @@ -1108,20 +1104,20 @@ char *ossl_ipaddr_to_asc(const unsigned char *p, int len) switch (len) { case 4: /* IPv4 */ - BIO_snprintf(buf, sizeof(buf), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + snprintf(buf, sizeof(buf), "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); break; case 16: /* IPv6 */ for (out = buf, i = 8, remain = sizeof(buf); - i-- > 0 && bytes >= 0; + i-- > 0 && bytes >= 0 && remain > 0; remain -= bytes, out += bytes) { const char *template = (i > 0 ? "%X:" : "%X"); - bytes = BIO_snprintf(out, remain, template, p[0] << 8 | p[1]); + bytes = snprintf(out, remain, template, p[0] << 8 | p[1]); p += 2; } break; default: - BIO_snprintf(buf, sizeof(buf), "", len); + snprintf(buf, sizeof(buf), "", len); break; } return OPENSSL_strdup(buf); diff --git a/crypto/x509/v3err.c b/crypto/x509/v3err.c deleted file mode 100644 index 96a27aaf488f2..0000000000000 --- a/crypto/x509/v3err.c +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/x509v3err.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA X509V3_str_reasons[] = { - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BAD_IP_ADDRESS), "bad ip address" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BAD_OBJECT), "bad object" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BAD_OPTION), "bad option" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BAD_VALUE), "bad value" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BN_DEC2BN_ERROR), "bn dec2bn error" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_BN_TO_ASN1_INTEGER_ERROR), - "bn to asn1 integer error" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_DIRNAME_ERROR), "dirname error" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_DISTPOINT_ALREADY_SET), - "distpoint already set" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_DUPLICATE_ZONE_ID), - "duplicate zone id" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_EMPTY_KEY_USAGE), "empty key usage" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_ERROR_CONVERTING_ZONE), - "error converting zone" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_ERROR_CREATING_EXTENSION), - "error creating extension" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_ERROR_IN_EXTENSION), - "error in extension" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_EXPECTED_A_SECTION_NAME), - "expected a section name" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_EXTENSION_EXISTS), - "extension exists" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_EXTENSION_NAME_ERROR), - "extension name error" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_EXTENSION_NOT_FOUND), - "extension not found" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED), - "extension setting not supported" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_EXTENSION_VALUE_ERROR), - "extension value error" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_ILLEGAL_EMPTY_EXTENSION), - "illegal empty extension" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG), - "incorrect policy syntax tag" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_ASNUMBER), - "invalid asnumber" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_ASRANGE), "invalid asrange" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_BOOLEAN_STRING), - "invalid boolean string" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_CERTIFICATE), - "invalid certificate" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_EMPTY_NAME), - "invalid empty name" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_EXTENSION_STRING), - "invalid extension string" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_INHERITANCE), - "invalid inheritance" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_IPADDRESS), - "invalid ipaddress" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_MULTIPLE_RDNS), - "invalid multiple rdns" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_NAME), "invalid name" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_NULL_ARGUMENT), - "invalid null argument" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_NULL_VALUE), - "invalid null value" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_NUMBER), "invalid number" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_NUMBERS), "invalid numbers" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_OBJECT_IDENTIFIER), - "invalid object identifier" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_OPTION), "invalid option" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_POLICY_IDENTIFIER), - "invalid policy identifier" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_PROXY_POLICY_SETTING), - "invalid proxy policy setting" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_PURPOSE), "invalid purpose" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_SAFI), "invalid safi" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_SECTION), "invalid section" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_INVALID_SYNTAX), "invalid syntax" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_ISSUER_DECODE_ERROR), - "issuer decode error" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_MISSING_VALUE), "missing value" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS), - "need organization and numbers" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NEGATIVE_PATHLEN), - "negative pathlen" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NO_CONFIG_DATABASE), - "no config database" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NO_ISSUER_CERTIFICATE), - "no issuer certificate" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NO_ISSUER_DETAILS), - "no issuer details" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NO_POLICY_IDENTIFIER), - "no policy identifier" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED), - "no proxy cert policy language defined" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NO_PUBLIC_KEY), "no public key" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_NO_SUBJECT_DETAILS), - "no subject details" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_OPERATION_NOT_DEFINED), - "operation not defined" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_OTHERNAME_ERROR), "othername error" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED), - "policy language already defined" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_POLICY_PATH_LENGTH), - "policy path length" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED), - "policy path length already defined" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY), - "policy when proxy language requires no policy" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_PURPOSE_NOT_UNIQUE), - "purpose not unique" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_SECTION_NOT_FOUND), - "section not found" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS), - "unable to get issuer details" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID), - "unable to get issuer keyid" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT), - "unknown bit string argument" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_UNKNOWN_EXTENSION), - "unknown extension" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_UNKNOWN_EXTENSION_NAME), - "unknown extension name" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_UNKNOWN_OPTION), "unknown option" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_UNKNOWN_VALUE), "unknown value" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_UNSUPPORTED_OPTION), - "unsupported option" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_UNSUPPORTED_TYPE), - "unsupported type" }, - { ERR_PACK(ERR_LIB_X509V3, 0, X509V3_R_USER_TOO_LONG), "user too long" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_X509V3_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(X509V3_str_reasons[0].error) == NULL) - ERR_load_strings_const(X509V3_str_reasons); -#endif - return 1; -} diff --git a/crypto/x509/x509_att.c b/crypto/x509/x509_att.c index ee631db75ac7e..ae4b71c05b22c 100644 --- a/crypto/x509/x509_att.c +++ b/crypto/x509/x509_att.c @@ -364,8 +364,24 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, } atype = stmp->type; } else if (len != -1) { - if ((stmp = ASN1_STRING_type_new(attrtype)) == NULL - || !ASN1_STRING_set(stmp, data, len)) { + if ((stmp = ASN1_STRING_type_new(attrtype)) == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); + goto err; + } + if (attrtype == V_ASN1_BIT_STRING) { + /* + * ossl_asn1_string_set1_data() rejects bit strings, so use the + * dedicated bit string setter, with zero unused bits. + */ + if (data == NULL && len > 0) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + if (!ASN1_BIT_STRING_set1(stmp, data, len, 0)) { + ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); + goto err; + } + } else if (!ossl_asn1_string_set1_data(stmp, data, len)) { ERR_raise(ERR_LIB_X509, ERR_R_ASN1_LIB); goto err; } diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c index 6cf674ea85583..996ab10707a5b 100644 --- a/crypto/x509/x509_cmp.c +++ b/crypto/x509/x509_cmp.c @@ -86,14 +86,34 @@ int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) { - int rv; + int rv = 0; + + if (a == b) + return 0; + + /* A CRL modified since it was signed or decoded is equal only to itself */ + if (a->crl.enc.modified || b->crl.enc.modified) + return a->crl.enc.modified ? 1 : -1; if ((a->flags & EXFLAG_NO_FINGERPRINT) == 0 && (b->flags & EXFLAG_NO_FINGERPRINT) == 0) - rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH); - else - return -2; + rv = memcmp(a->fingerprint, b->fingerprint, sizeof(a->fingerprint)); + if (rv != 0) + return rv < 0 ? -1 : 1; + /* Check for match against stored encoding too */ + if (a->crl.enc.len < b->crl.enc.len) + return -1; + if (a->crl.enc.len > b->crl.enc.len) + return 1; + rv = memcmp(a->crl.enc.enc, b->crl.enc.enc, a->crl.enc.len); + if (rv != 0) + return rv < 0 ? -1 : 1; + /* Same TBS: the signature algorithm and signature must match too */ + rv = X509_ALGOR_cmp(&a->sig_alg, &b->sig_alg); + if (rv != 0) + return rv < 0 ? -1 : 1; + rv = ASN1_STRING_cmp(&a->signature, &b->signature); return rv < 0 ? -1 : rv > 0; } @@ -156,25 +176,37 @@ int X509_cmp(const X509 *a, const X509 *b) if (a == b) /* for efficiency */ return 0; + /* + * A certificate modified since it was signed or decoded is equal only + * to itself + */ + if (a->cert_info.enc.modified || b->cert_info.enc.modified) + return a->cert_info.enc.modified ? 1 : -1; + /* attempt to compute cert hash */ (void)X509_check_purpose((X509 *)a, -1, 0); (void)X509_check_purpose((X509 *)b, -1, 0); if ((a->ex_flags & EXFLAG_NO_FINGERPRINT) == 0 && (b->ex_flags & EXFLAG_NO_FINGERPRINT) == 0) - rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH); + rv = memcmp(a->fingerprint, b->fingerprint, sizeof(a->fingerprint)); if (rv != 0) return rv < 0 ? -1 : 1; /* Check for match against stored encoding too */ - if (!a->cert_info.enc.modified && !b->cert_info.enc.modified) { - if (a->cert_info.enc.len < b->cert_info.enc.len) - return -1; - if (a->cert_info.enc.len > b->cert_info.enc.len) - return 1; - rv = memcmp(a->cert_info.enc.enc, - b->cert_info.enc.enc, a->cert_info.enc.len); - } + if (a->cert_info.enc.len < b->cert_info.enc.len) + return -1; + if (a->cert_info.enc.len > b->cert_info.enc.len) + return 1; + rv = memcmp(a->cert_info.enc.enc, + b->cert_info.enc.enc, a->cert_info.enc.len); + if (rv != 0) + return rv < 0 ? -1 : 1; + /* Same TBS: the signature algorithm and signature must match too */ + rv = X509_ALGOR_cmp(&a->sig_alg, &b->sig_alg); + if (rv != 0) + return rv < 0 ? -1 : 1; + rv = ASN1_STRING_cmp(&a->signature, &b->signature); return rv < 0 ? -1 : rv > 0; } diff --git a/crypto/x509/x509_def.c b/crypto/x509/x509_def.c index 797f687d13a77..f0e530e1315cb 100644 --- a/crypto/x509/x509_def.c +++ b/crypto/x509/x509_def.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c deleted file mode 100644 index b78f210fd4a09..0000000000000 --- a/crypto/x509/x509_err.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "crypto/x509err.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA X509_str_reasons[] = { - { ERR_PACK(ERR_LIB_X509, 0, X509_R_AKID_MISMATCH), "akid mismatch" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_BAD_SELECTOR), "bad selector" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_BAD_X509_FILETYPE), "bad x509 filetype" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_BASE64_DECODE_ERROR), - "base64 decode error" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_CANT_CHECK_DH_KEY), "can't check dh key" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_CERTIFICATE_VERIFICATION_FAILED), - "certificate verification failed" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_CERT_ALREADY_IN_HASH_TABLE), - "cert already in hash table" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_ALREADY_DELTA), "crl already delta" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_SIGNATURE_ALGORITHM_MISMATCH), - "crl signature algorithm mismatch" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_CRL_VERIFY_FAILURE), - "crl verify failure" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_DUPLICATE_ATTRIBUTE), - "duplicate attribute" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_ERROR_GETTING_MD_BY_NID), - "error getting md by nid" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_ERROR_USING_SIGINF_SET), - "error using siginf set" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_IDP_MISMATCH), "idp mismatch" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_ATTRIBUTES), - "invalid attributes" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_DIRECTORY), "invalid directory" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_DISTPOINT), "invalid distpoint" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_EXTENSION), "invalid extension" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_FIELD_NAME), - "invalid field name" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_INVALID_TRUST), "invalid trust" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_ISSUER_MISMATCH), "issuer mismatch" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_KEY_TYPE_MISMATCH), "key type mismatch" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_KEY_VALUES_MISMATCH), - "key values mismatch" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_LOADING_CERT_DIR), "loading cert dir" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_LOADING_DEFAULTS), "loading defaults" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_METHOD_NOT_SUPPORTED), - "method not supported" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_NAME_TOO_LONG), "name too long" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_NEWER_CRL_NOT_NEWER), - "newer crl not newer" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_NO_CERTIFICATE_FOUND), - "no certificate found" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_NO_CERTIFICATE_OR_CRL_FOUND), - "no certificate or crl found" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY), - "no cert set for us to verify" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_NO_CRL_FOUND), "no crl found" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_NO_CRL_NUMBER), "no crl number" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_PUBLIC_KEY_DECODE_ERROR), - "public key decode error" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_PUBLIC_KEY_ENCODE_ERROR), - "public key encode error" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_SHOULD_RETRY), "should retry" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN), - "unable to find parameters in chain" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY), - "unable to get certs public key" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_KEY_TYPE), "unknown key type" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_NID), "unknown nid" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_PURPOSE_ID), - "unknown purpose id" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_SIGID_ALGS), - "unknown sigid algs" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_UNKNOWN_TRUST_ID), "unknown trust id" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_UNSUPPORTED_ALGORITHM), - "unsupported algorithm" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_UNSUPPORTED_VERSION), - "unsupported version" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_WRONG_LOOKUP_TYPE), "wrong lookup type" }, - { ERR_PACK(ERR_LIB_X509, 0, X509_R_WRONG_TYPE), "wrong type" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_X509_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(X509_str_reasons[0].error) == NULL) - ERR_load_strings_const(X509_str_reasons); -#endif - return 1; -} diff --git a/crypto/x509/x509_ext.c b/crypto/x509/x509_ext.c index 8c9c5d96bcc01..261eccc51dee0 100644 --- a/crypto/x509/x509_ext.c +++ b/crypto/x509/x509_ext.c @@ -59,12 +59,20 @@ void *X509_CRL_get_ext_d2i(const X509_CRL *x, int nid, int *crit, int *idx) int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, unsigned long flags) { + /* + * Assume modified, sadly the underlying function does not tell us whether + * changes were made, or not. + */ + x->crl.enc.modified = 1; return X509V3_add1_i2d(&x->crl.extensions, nid, value, crit, flags); } int X509_CRL_add_ext(X509_CRL *x, const X509_EXTENSION *ex, int loc) { - return (X509v3_add_ext(&(x->crl.extensions), ex, loc) != NULL); + if (X509v3_add_ext(&x->crl.extensions, ex, loc) == NULL) + return 0; + x->crl.enc.modified = 1; + return 1; } int X509_get_ext_count(const X509 *x) diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c index d1f4c1eb406ab..5be50c219553a 100644 --- a/crypto/x509/x509_lu.c +++ b/crypto/x509/x509_lu.c @@ -287,7 +287,7 @@ int X509_STORE_up_ref(X509_STORE *xs) { int i; - if (CRYPTO_UP_REF(&xs->references, &i) <= 0) + if (!CRYPTO_UP_REF(&xs->references, &i)) return 0; REF_PRINT_COUNT("X509_STORE", i, xs); diff --git a/crypto/x509/x509_set.c b/crypto/x509/x509_set.c index 8a2a12e4b6920..9096c0915d6d8 100644 --- a/crypto/x509/x509_set.c +++ b/crypto/x509/x509_set.c @@ -49,8 +49,8 @@ int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) if (x == NULL) return 0; in = &x->cert_info.serialNumber; - if (in != serial) - return ASN1_STRING_copy(in, serial); + if (in != serial && !ASN1_STRING_copy(in, serial)) + return 0; x->cert_info.enc.modified = 1; return 1; } @@ -117,7 +117,7 @@ int X509_up_ref(X509 *x) { int i; - if (CRYPTO_UP_REF(&x->references, &i) <= 0) + if (!CRYPTO_UP_REF(&x->references, &i)) return 0; REF_PRINT_COUNT("X509", i, x); @@ -202,13 +202,6 @@ void X509_SIG_INFO_set(X509_SIG_INFO *siginf, int mdnid, int pknid, siginf->flags = flags; } -int X509_get_signature_info(const X509 *x, int *mdnid, int *pknid, int *secbits, - uint32_t *flags) -{ - X509_check_purpose(x, -1, -1); - return X509_SIG_INFO_get(&x->siginf, mdnid, pknid, secbits, flags); -} - /* Modify *siginf according to alg and sig. Return 1 on success, else 0. */ static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg, const ASN1_STRING *sig, const EVP_PKEY *pubkey, @@ -312,9 +305,18 @@ static int x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg, return 1; } -/* Returns 1 on success, 0 on failure */ -int ossl_x509_init_sig_info(const X509 *x, X509_SIG_INFO *info) +int X509_get_signature_info(const X509 *x, int *mdnid, int *pknid, int *secbits, + uint32_t *flags) { - return x509_sig_info_init(info, &x->sig_alg, &x->signature, + X509_SIG_INFO siginf; + + if (x == NULL) { + ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ERR_set_mark(); + (void)x509_sig_info_init(&siginf, &x->sig_alg, &x->signature, X509_PUBKEY_get0(x->cert_info.key), x->libctx, x->propq); + ERR_pop_to_mark(); + return X509_SIG_INFO_get(&siginf, mdnid, pknid, secbits, flags); } diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 977672d8fcaa9..973b586dac25f 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -58,6 +58,7 @@ static int check_name_constraints(X509_STORE_CTX *ctx); static int check_id(X509_STORE_CTX *ctx); static int check_trust(X509_STORE_CTX *ctx, int num_untrusted); static int check_revocation(X509_STORE_CTX *ctx); +static int revocation_check_end(X509_STORE_CTX *ctx, int check_all); #ifndef OPENSSL_NO_OCSP static int check_cert_ocsp_resp(X509_STORE_CTX *ctx); #endif @@ -78,6 +79,8 @@ static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, STACK_OF(X509_CRL) *crls); static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, int *pcrl_score); +static int matching_crl_issuer_and_akid(const X509_CRL *crl, + const X509 *issuer, const X509_NAME *crl_issuer_name); static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, unsigned int *preasons); static int check_crl_path(X509_STORE_CTX *ctx, X509 *x); @@ -775,27 +778,6 @@ static int check_extensions(X509_STORE_CTX *ctx) return 1; } -static int has_san_id(const X509 *x, int gtype) -{ - int i; - int ret = 0; - GENERAL_NAMES *gs = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); - - if (gs == NULL) - return 0; - - for (i = 0; i < sk_GENERAL_NAME_num(gs); i++) { - GENERAL_NAME *g = sk_GENERAL_NAME_value(gs, i); - - if (g->type == gtype) { - ret = 1; - break; - } - } - GENERAL_NAMES_free(gs); - return ret; -} - /*- * Returns -1 on internal error. * Sadly, returns 0 also on internal error in ctx->verify_cb(). @@ -892,20 +874,22 @@ static int check_name_constraints(X509_STORE_CTX *ctx) if (nc) { int rv = NAME_CONSTRAINTS_check(x, nc); - int ret = 1; - /* If EE certificate check commonName too */ + /* + * Apply DNS name constraints to the EE subject commonName + * only when the commonName may be used for host name checks, + * mirroring do_x509_check(): only when the caller opted in + * with X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT, and never when + * X509_CHECK_FLAG_NEVER_CHECK_SUBJECT is set. + */ if (rv == X509_V_OK && i == 0 && (ctx->param->hostflags & X509_CHECK_FLAG_NEVER_CHECK_SUBJECT) == 0 - && ((ctx->param->hostflags - & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT) - != 0 - || (ret = has_san_id(x, GEN_DNS)) == 0)) + && (ctx->param->hostflags + & X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT) + != 0) rv = NAME_CONSTRAINTS_check_CN(x, nc); - if (ret < 0) - return ret; switch (rv) { case X509_V_OK: @@ -1173,6 +1157,20 @@ static int check_trust(X509_STORE_CTX *ctx, int num_untrusted) return X509_TRUST_UNTRUSTED; } +/* + * Return the last chain depth whose revocation status should be checked. + * With X509_V_FLAG_*_CHECK_ALL and X509_V_FLAG_PARTIAL_CHAIN, revocation + * checking stops before the first trusted certificate in the chain. + */ +static int revocation_check_end(X509_STORE_CTX *ctx, int check_all) +{ + if (!check_all) + return 0; + return (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) == 0 + ? sk_X509_num(ctx->chain) - 1 + : ctx->num_untrusted - 1; +} + /* Sadly, returns 0 also on internal error. */ static int check_revocation(X509_STORE_CTX *ctx) { @@ -1190,10 +1188,10 @@ static int check_revocation(X509_STORE_CTX *ctx) /* * certificate status checking with OCSP */ - if (ocsp_check_all_enabled) - last = sk_X509_num(ctx->chain) - 1; - else if (!crl_check_all_enabled && ctx->parent != NULL) + if (!ocsp_check_all_enabled && !crl_check_all_enabled + && ctx->parent != NULL) return 1; /* If checking CRL paths this isn't the EE certificate */ + last = revocation_check_end(ctx, ocsp_check_all_enabled); for (i = 0; i <= last; i++) { ctx->error_depth = i; @@ -1256,14 +1254,9 @@ static int check_revocation(X509_STORE_CTX *ctx) if (crl_check_enabled && !ocsp_check_all_enabled) { /* certificate status check with CRLs */ - if (crl_check_all_enabled) { - last = sk_X509_num(ctx->chain) - 1; - } else { - /* If checking CRL paths this isn't the EE certificate */ - if (ctx->parent != NULL) - return 1; - last = 0; - } + if (!crl_check_all_enabled && ctx->parent != NULL) + return 1; /* If checking CRL paths this isn't the EE certificate */ + last = revocation_check_end(ctx, crl_check_all_enabled); /* * in the case that OCSP is only enabled for the server certificate @@ -1307,10 +1300,20 @@ static int check_cert_ocsp_resp(X509_STORE_CTX *ctx) return X509_V_ERR_OCSP_NO_RESPONSE; if ((resp = sk_OCSP_RESPONSE_value(ctx->ocsp_resp, ctx->error_depth)) == NULL - || (bs = OCSP_response_get1_basic(resp)) == NULL - || (num = OCSP_resp_count(bs)) < 1) + || (bs = OCSP_response_get1_basic(resp)) == NULL) return X509_V_ERR_OCSP_NO_RESPONSE; + /* + * OCSP_response_get1_basic() returns an owning reference, so once bs is + * non-NULL it must be released via the end: cleanup label. Route an empty + * BasicResponse (no single responses) through end: rather than returning + * directly, otherwise bs leaks. + */ + if ((num = OCSP_resp_count(bs)) < 1) { + ret = X509_V_ERR_OCSP_NO_RESPONSE; + goto end; + } + if (OCSP_response_status(resp) != OCSP_RESPONSE_STATUS_SUCCESSFUL) { OCSP_BASICRESP_free(bs); bs = NULL; @@ -1756,7 +1759,7 @@ static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, crl_issuer = sk_X509_value(ctx->chain, cidx); - if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + if (matching_crl_issuer_and_akid(crl, crl_issuer, cnm)) { if (*pcrl_score & CRL_SCORE_ISSUER_NAME) { *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT; *pissuer = crl_issuer; @@ -1766,9 +1769,7 @@ static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) { crl_issuer = sk_X509_value(ctx->chain, cidx); - if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) - continue; - if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + if (matching_crl_issuer_and_akid(crl, crl_issuer, cnm)) { *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH; *pissuer = crl_issuer; return; @@ -1785,9 +1786,7 @@ static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, */ for (i = 0; i < sk_X509_num(ctx->untrusted); i++) { crl_issuer = sk_X509_value(ctx->untrusted, i); - if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm) != 0) - continue; - if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + if (matching_crl_issuer_and_akid(crl, crl_issuer, cnm)) { *pissuer = crl_issuer; *pcrl_score |= CRL_SCORE_AKID; return; @@ -1795,6 +1794,16 @@ static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, } } +static int matching_crl_issuer_and_akid(const X509_CRL *crl, + const X509 *issuer, const X509_NAME *crl_issuer_name) +{ + if (issuer == NULL) + return 0; + if (X509_NAME_cmp(X509_get_subject_name(issuer), crl_issuer_name) != 0) + return 0; + return X509_check_akid(issuer, crl->akid) == X509_V_OK; +} + /* * Check the path of a CRL issuer certificate. This creates a new * X509_STORE_CTX and populates it with most of the parameters from the @@ -1930,6 +1939,52 @@ static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) return 0; } +/* + * Check whether the distribution point name |idpname| of a CRL's IDP extension + * matches the default distribution point that RFC 5280, section 6.3.3, assumes + * for CRLs not specified in any of the certificate's distribution points: one + * whose fullName consists of the certificate issuer name and the names in the + * certificate's issuerAltName extension. The assumed distribution point is + * constructed and matched with idp_check_dp(). + */ +static int idp_check_issuer(DIST_POINT_NAME *idpname, X509 *x) +{ + DIST_POINT_NAME dpname; + GENERAL_NAMES *gens; + GENERAL_NAME *gen = NULL; + X509_NAME *iname = NULL; + int ret = 0; + + /* + * An undecodable issuerAltName extension is treated as an absent one; + * any decoding errors are not left in the error queue. + */ + ERR_set_mark(); + gens = X509_get_ext_d2i(x, NID_issuer_alt_name, NULL, NULL); + ERR_pop_to_mark(); + if (gens == NULL && (gens = sk_GENERAL_NAME_new_null()) == NULL) + return 0; + if ((gen = GENERAL_NAME_new()) == NULL + || (iname = X509_NAME_dup(X509_get_issuer_name(x))) == NULL) + goto end; + GENERAL_NAME_set0_value(gen, GEN_DIRNAME, iname); + iname = NULL; /* now owned by |gen| */ + if (!sk_GENERAL_NAME_push(gens, gen)) + goto end; + gen = NULL; /* now owned by |gens| */ + + dpname.type = 0; /* fullName */ + dpname.name.fullname = gens; + dpname.dpname = NULL; + ret = idp_check_dp(&dpname, idpname); + +end: + GENERAL_NAME_free(gen); + X509_NAME_free(iname); + GENERAL_NAMES_free(gens); + return ret; +} + /* Check CRLDP and IDP */ static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, unsigned int *preasons) @@ -1957,8 +2012,16 @@ static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, } } } - return (crl->idp == NULL || crl->idp->distpoint == NULL) - && (crl_score & CRL_SCORE_ISSUER_NAME) != 0; + /* + * The CRL is not specified in any distribution point of the certificate. + * RFC 5280, section 6.3.3, allows such a CRL if it is issued by the + * certificate issuer, assuming a distribution point with the reasons and + * cRLIssuer fields omitted and a distribution point name consisting of + * the certificate issuer name and any issuerAltName entries. + */ + return (crl_score & CRL_SCORE_ISSUER_NAME) != 0 + && (crl->idp == NULL || crl->idp->distpoint == NULL + || idp_check_issuer(crl->idp->distpoint, x)); } /* diff --git a/crypto/x509/x509cset.c b/crypto/x509/x509cset.c index 20de6a340e7bc..ec3e1f53603c2 100644 --- a/crypto/x509/x509cset.c +++ b/crypto/x509/x509cset.c @@ -75,7 +75,7 @@ int X509_CRL_up_ref(X509_CRL *crl) { int i; - if (CRYPTO_UP_REF(&crl->references, &i) <= 0) + if (!CRYPTO_UP_REF(&crl->references, &i)) return 0; REF_PRINT_COUNT("X509_CRL", i, crl); diff --git a/crypto/x509/x509name.c b/crypto/x509/x509name.c index ebd58a20125e2..1cb9ad00f4d17 100644 --- a/crypto/x509/x509name.c +++ b/crypto/x509/x509name.c @@ -45,7 +45,8 @@ int X509_NAME_get_text_by_OBJ(const X509_NAME *name, const ASN1_OBJECT *obj, if (len <= 0) return 0; i = (data->length > (len - 1)) ? (len - 1) : data->length; - memcpy(buf, data->data, i); + if (i > 0) + memcpy(buf, data->data, i); buf[i] = '\0'; return i; } @@ -332,9 +333,12 @@ int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, OBJ_obj2nid(ne->object)) ? 1 : 0; - if (len < 0) - len = (int)strlen((const char *)bytes); - i = ASN1_STRING_set(ne->value, bytes, len); + if (len < -1) + return 0; + if (len == -1) + i = ossl_asn1_string_set1_string(ne->value, (const char *)bytes); + else + i = ossl_asn1_string_set1_data(ne->value, bytes, (size_t)len); if (!i) return 0; if (type != V_ASN1_UNDEF) { diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c index ef16a7fc884b0..6612dd06f90bd 100644 --- a/crypto/x509/x_all.c +++ b/crypto/x509/x_all.c @@ -30,6 +30,7 @@ #include "crypto/x509.h" #include "crypto/x509_acert.h" #include "crypto/rsa.h" +#include "crypto/siphash.h" #include "x509_local.h" static void *RSA_new_thunk(void) @@ -643,17 +644,28 @@ int X509_pubkey_digest(const X509 *data, const EVP_MD *type, return EVP_Digest(key->data, key->length, md, len, type, NULL); } +int ossl_x509_internal_fingerprint(const ASN1_ITEM *it, const void *val, + unsigned char *hash) +{ + static const unsigned char key[SIPHASH_KEY_SIZE] = { 0 }; + SIPHASH ctx = { 0 }; + unsigned char *der = NULL; + int der_len; + + der_len = ASN1_item_i2d((const ASN1_VALUE *)val, &der, it); + if (der_len < 0) + return 0; + (void)SipHash_set_hash_size(&ctx, OSSL_X509_FINGERPRINT_SIZE); + (void)SipHash_Init(&ctx, key, 0, 0); + SipHash_Update(&ctx, der, (size_t)der_len); + (void)SipHash_Final(&ctx, hash, OSSL_X509_FINGERPRINT_SIZE); + OPENSSL_free(der); + return 1; +} + int X509_digest(const X509 *cert, const EVP_MD *md, unsigned char *data, unsigned int *len) { - if (EVP_MD_is_a(md, SN_sha1) && (cert->ex_flags & EXFLAG_SET) != 0 - && (cert->ex_flags & EXFLAG_NO_FINGERPRINT) == 0) { - /* Asking for SHA1 and we already computed it. */ - if (len != NULL) - *len = sizeof(cert->sha1_hash); - memcpy(data, cert->sha1_hash, sizeof(cert->sha1_hash)); - return 1; - } return ossl_asn1_item_digest_ex(ASN1_ITEM_rptr(X509), md, (char *)cert, data, len, cert->libctx, cert->propq); } @@ -759,15 +771,6 @@ int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, ERR_raise(ERR_LIB_X509, ERR_R_PASSED_NULL_PARAMETER); return 0; } - if (EVP_MD_is_a(type, SN_sha1) - && (data->flags & EXFLAG_SET) != 0 - && (data->flags & EXFLAG_NO_FINGERPRINT) == 0) { - /* Asking for SHA1; always computed in CRL d2i. */ - if (len != NULL) - *len = sizeof(data->sha1_hash); - memcpy(md, data->sha1_hash, sizeof(data->sha1_hash)); - return 1; - } return ossl_asn1_item_digest_ex(ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len, data->libctx, data->propq); } diff --git a/crypto/x509/x_attrib.c b/crypto/x509/x_attrib.c index 648d64bcf376b..98a99cc43b7cc 100644 --- a/crypto/x509/x_attrib.c +++ b/crypto/x509/x_attrib.c @@ -135,7 +135,9 @@ int ossl_print_attribute_value(BIO *out, case V_ASN1_OBJECT_DESCRIPTOR: return BIO_printf(out, "%*s%.*s", indent, "", av->value.generalstring->length, - av->value.generalstring->data) + av->value.generalstring->length + ? av->value.generalstring->data + : (const unsigned char *)"") >= 0; /* EXTERNAL would go here. */ @@ -144,7 +146,9 @@ int ossl_print_attribute_value(BIO *out, case V_ASN1_UTF8STRING: return BIO_printf(out, "%*s%.*s", indent, "", av->value.utf8string->length, - av->value.utf8string->data) + av->value.utf8string->length + ? av->value.utf8string->data + : (const unsigned char *)"") >= 0; case V_ASN1_REAL: @@ -208,25 +212,33 @@ int ossl_print_attribute_value(BIO *out, case V_ASN1_NUMERICSTRING: return BIO_printf(out, "%*s%.*s", indent, "", av->value.visiblestring->length, - av->value.visiblestring->data) + av->value.visiblestring->length + ? av->value.visiblestring->data + : (const unsigned char *)"") >= 0; case V_ASN1_PRINTABLESTRING: return BIO_printf(out, "%*s%.*s", indent, "", av->value.printablestring->length, - av->value.printablestring->data) + av->value.printablestring->length + ? av->value.printablestring->data + : (const unsigned char *)"") >= 0; case V_ASN1_T61STRING: return BIO_printf(out, "%*s%.*s", indent, "", av->value.t61string->length, - av->value.t61string->data) + av->value.t61string->length + ? av->value.t61string->data + : (const unsigned char *)"") >= 0; case V_ASN1_IA5STRING: return BIO_printf(out, "%*s%.*s", indent, "", av->value.ia5string->length, - av->value.ia5string->data) + av->value.ia5string->length + ? av->value.ia5string->data + : (const unsigned char *)"") >= 0; /* UniversalString would go here. */ diff --git a/crypto/x509/x_crl.c b/crypto/x509/x_crl.c index e19f0e181d3a3..9693ad16a33c4 100644 --- a/crypto/x509/x_crl.c +++ b/crypto/x509/x_crl.c @@ -208,7 +208,8 @@ static int crl_set_issuers(X509_CRL *crl) /* * The X509_CRL structure needs a bit of customisation. Cache some extensions - * and hash of the whole CRL or set EXFLAG_NO_FINGERPRINT if this fails. + * and the internal-use fingerprint of the whole CRL, or set + * EXFLAG_NO_FINGERPRINT if this fails. */ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, void *exarg) @@ -245,7 +246,8 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, break; case ASN1_OP_D2I_POST: - if (!X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL)) + if (!ossl_x509_internal_fingerprint(ASN1_ITEM_rptr(X509_CRL), crl, + crl->fingerprint)) crl->flags |= EXFLAG_NO_FINGERPRINT; crl->idp = X509_CRL_get_ext_d2i(crl, NID_issuing_distribution_point, &i, NULL); if (crl->idp == NULL && i != -1) { @@ -417,7 +419,7 @@ X509_CRL *X509_CRL_new_ex(OSSL_LIB_CTX *libctx, const char *propq) { X509_CRL *crl = NULL; - crl = (X509_CRL *)ASN1_item_new((X509_CRL_it())); + crl = (X509_CRL *)ASN1_item_new(ASN1_ITEM_rptr(X509_CRL)); if (!ossl_x509_crl_set0_libctx(crl, libctx, propq)) { X509_CRL_free(crl); crl = NULL; diff --git a/crypto/x509/x_ietfatt.c b/crypto/x509/x_ietfatt.c index df68878dad437..6750a088f63bd 100644 --- a/crypto/x509/x_ietfatt.c +++ b/crypto/x509/x_ietfatt.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -64,7 +64,7 @@ OSSL_IETF_ATTR_SYNTAX *d2i_OSSL_IETF_ATTR_SYNTAX(OSSL_IETF_ATTR_SYNTAX **a, int i; ias = (OSSL_IETF_ATTR_SYNTAX *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, - OSSL_IETF_ATTR_SYNTAX_it()); + ASN1_ITEM_rptr(OSSL_IETF_ATTR_SYNTAX)); if (ias == NULL) return ias; @@ -91,7 +91,7 @@ OSSL_IETF_ATTR_SYNTAX *d2i_OSSL_IETF_ATTR_SYNTAX(OSSL_IETF_ATTR_SYNTAX **a, int i2d_OSSL_IETF_ATTR_SYNTAX(const OSSL_IETF_ATTR_SYNTAX *a, unsigned char **out) { - return ASN1_item_i2d((const ASN1_VALUE *)a, out, OSSL_IETF_ATTR_SYNTAX_it()); + return ASN1_item_i2d((const ASN1_VALUE *)a, out, ASN1_ITEM_rptr(OSSL_IETF_ATTR_SYNTAX)); } int OSSL_IETF_ATTR_SYNTAX_get_value_num(const OSSL_IETF_ATTR_SYNTAX *a) diff --git a/crypto/x509/x_name.c b/crypto/x509/x_name.c index 90588c8c67ea6..e965dee4c891e 100644 --- a/crypto/x509/x_name.c +++ b/crypto/x509/x_name.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -224,6 +224,7 @@ static int x509_name_ex_i2d(const ASN1_VALUE **val, unsigned char **out, ret = x509_name_canon(a); if (!ret) return -1; + a->modified = 0; } ret = (int)a->bytes->length; if (out != NULL) { @@ -241,8 +242,8 @@ static int x509_name_encode(X509_NAME *a) } intname = { NULL }; - int len; - unsigned char *p; + int len, outlen; + unsigned char *p, *start; STACK_OF(X509_NAME_ENTRY) *entries = NULL; X509_NAME_ENTRY *entry; int i, set = -1; @@ -267,16 +268,20 @@ static int x509_name_encode(X509_NAME *a) } len = ASN1_item_ex_i2d(&intname.a, NULL, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); + if (len < 0) + goto err; if (!BUF_MEM_grow(a->bytes, len)) { ERR_raise(ERR_LIB_ASN1, ERR_R_BUF_LIB); goto err; } p = (unsigned char *)a->bytes->data; - ASN1_item_ex_i2d(&intname.a, + start = p; + outlen = ASN1_item_ex_i2d(&intname.a, &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); + if (outlen != len || p != start + len) + goto err; sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, local_sk_X509_NAME_ENTRY_free); - a->modified = 0; return len; cerr: ERR_raise(ERR_LIB_ASN1, ERR_R_CRYPTO_LIB); @@ -310,14 +315,15 @@ static int x509_name_ex_print(BIO *out, const ASN1_VALUE **pval, static int x509_name_canon(X509_NAME *a) { - unsigned char *p; + unsigned char *buf = NULL, *p; STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname; STACK_OF(X509_NAME_ENTRY) *entries = NULL; X509_NAME_ENTRY *entry, *tmpentry = NULL; - int i, set = -1, ret = 0, len; + int i, set = -1, ret = 0, len, outlen; OPENSSL_free(a->canon_enc); a->canon_enc = NULL; + a->canon_enclen = 0; /* Special case: empty X509_NAME => null encoding */ if (sk_X509_NAME_ENTRY_num(a->entries) == 0) { a->canon_enclen = 0; @@ -364,19 +370,23 @@ static int x509_name_canon(X509_NAME *a) len = i2d_name_canon(intname, NULL); if (len < 0) goto err; - a->canon_enclen = len; - p = OPENSSL_malloc(a->canon_enclen); - if (p == NULL) + buf = OPENSSL_malloc(len); + if (buf == NULL) goto err; + p = buf; - a->canon_enc = p; - - i2d_name_canon(intname, &p); + outlen = i2d_name_canon(intname, &p); + if (outlen != len || p != buf + len) + goto err; + a->canon_enc = buf; + a->canon_enclen = len; + buf = NULL; ret = 1; err: + OPENSSL_free(buf); X509_NAME_ENTRY_free(tmpentry); sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, local_sk_X509_NAME_ENTRY_pop_free); @@ -404,8 +414,10 @@ static int asn1_string_canon(ASN1_STRING *out, const ASN1_STRING *in) out->type = V_ASN1_UTF8STRING; out->length = ASN1_STRING_to_UTF8(&out->data, in); - if (out->length == -1) + if (out->length < 0) return 0; + if (out->length == 0) + return 1; to = out->data; from = to; diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c index 888bcfd7b1b20..df4bccbeef31b 100644 --- a/crypto/x509/x_pubkey.c +++ b/crypto/x509/x_pubkey.c @@ -280,7 +280,7 @@ X509_PUBKEY *X509_PUBKEY_new_ex(OSSL_LIB_CTX *libctx, const char *propq) { X509_PUBKEY *pubkey = NULL; - pubkey = (X509_PUBKEY *)ASN1_item_new_ex(X509_PUBKEY_it(), libctx, propq); + pubkey = (X509_PUBKEY *)ASN1_item_new_ex(ASN1_ITEM_rptr(X509_PUBKEY), libctx, propq); if (!x509_pubkey_set0_libctx(pubkey, libctx, propq)) { X509_PUBKEY_free(pubkey); pubkey = NULL; diff --git a/crypto/x509/x_req.c b/crypto/x509/x_req.c index 6f60df5b041d5..5137885a5b16a 100644 --- a/crypto/x509/x_req.c +++ b/crypto/x509/x_req.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -158,7 +158,7 @@ X509_REQ *X509_REQ_new_ex(OSSL_LIB_CTX *libctx, const char *propq) { X509_REQ *req = NULL; - req = (X509_REQ *)ASN1_item_new((X509_REQ_it())); + req = (X509_REQ *)ASN1_item_new(ASN1_ITEM_rptr(X509_REQ)); if (!ossl_x509_req_set0_libctx(req, libctx, propq)) { X509_REQ_free(req); req = NULL; diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c index 570434eaea9e5..43a19a4d8f75a 100644 --- a/crypto/x509/x_x509.c +++ b/crypto/x509/x_x509.c @@ -156,7 +156,7 @@ X509 *X509_new_ex(OSSL_LIB_CTX *libctx, const char *propq) { X509 *cert = NULL; - cert = (X509 *)ASN1_item_new_ex(X509_it(), libctx, propq); + cert = (X509 *)ASN1_item_new_ex(ASN1_ITEM_rptr(X509), libctx, propq); if (!ossl_x509_set0_libctx(cert, libctx, propq)) { X509_free(cert); cert = NULL; diff --git a/crypto/x509/x_x509a.c b/crypto/x509/x_x509a.c index 6dfd68f74d75f..07f15009bf330 100644 --- a/crypto/x509/x_x509a.c +++ b/crypto/x509/x_x509a.c @@ -50,6 +50,8 @@ static X509_CERT_AUX *aux_get(X509 *x) int X509_alias_set1(X509 *x, const unsigned char *name, int len) { X509_CERT_AUX *aux; + size_t len_s; + if (!name) { if (!x || !x->aux || !x->aux->alias) return 1; @@ -59,14 +61,25 @@ int X509_alias_set1(X509 *x, const unsigned char *name, int len) } if ((aux = aux_get(x)) == NULL) return 0; + + if (len < -1) + return 0; + + if (len == -1) + len_s = strlen((const char *)name); + else + len_s = len; + if (aux->alias == NULL && (aux->alias = ASN1_UTF8STRING_new()) == NULL) return 0; - return ASN1_STRING_set(aux->alias, name, len); + return ossl_asn1_string_set1_data(aux->alias, name, len_s); } int X509_keyid_set1(X509 *x, const unsigned char *id, int len) { X509_CERT_AUX *aux; + size_t len_s; + if (!id) { if (!x || !x->aux || !x->aux->keyid) return 1; @@ -76,10 +89,19 @@ int X509_keyid_set1(X509 *x, const unsigned char *id, int len) } if ((aux = aux_get(x)) == NULL) return 0; + + if (len < -1) + return 0; + + if (len == -1) + len_s = strlen((const char *)id); + else + len_s = len; + if (aux->keyid == NULL && (aux->keyid = ASN1_OCTET_STRING_new()) == NULL) return 0; - return ASN1_STRING_set(aux->keyid, id, len); + return ossl_asn1_string_set1_data(aux->keyid, id, len_s); } const unsigned char *X509_alias_get0(const X509 *x, int *len) diff --git a/crypto/x86_64cpuid.pl b/crypto/x86_64cpuid.pl index cf8a7605a636a..22cf520f0dd0c 100644 --- a/crypto/x86_64cpuid.pl +++ b/crypto/x86_64cpuid.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/crypto/x86cpuid.pl b/crypto/x86cpuid.pl index 32f6e4352395e..941afa042019a 100644 --- a/crypto/x86cpuid.pl +++ b/crypto/x86cpuid.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2004-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2004-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/demos/README.txt b/demos/README.txt index 9ccb5f1c2fb43..9caafcad7727c 100644 --- a/demos/README.txt +++ b/demos/README.txt @@ -36,8 +36,11 @@ guide: Sample code from the OpenSSL Guide tutorials. See quic-client-block.c: A simple blocking QUIC client quic-client-non-block.c: A simple non-blocking QUIC client quic-multi-stream.c: A simple QUIC client using multiple streams +quic-server-block.c: A simple blocking QUIC server +quic-server-non-block.c: A simple non-blocking QUIC server tls-client-block.c: A simple blocking SSL/TLS client tls-client-non-block.c: A simple non-blocking SSL/TLS client +tls-server-block.c: A simple blocking SSL/TLS server http3: Demonstration of how to use OpenSSL's QUIC capabilities for HTTP/3. @@ -81,4 +84,5 @@ rsa_pss_hash.c Compute and verify an RSA-PSS signature over a buffer smime: Demonstrations related to S/MIME sslecho: +echecho.c Simple SSL/TLS echo client/server that uses ECH. main.c Simple SSL/TLS echo client/server. diff --git a/demos/build.info b/demos/build.info index 49068f74ecec2..15948e7f12e02 100644 --- a/demos/build.info +++ b/demos/build.info @@ -1,4 +1,4 @@ -SUBDIRS=bio cipher digest info keyexch mac kdf pkey signature \ +SUBDIRS=bio cipher digest info keyexch mac kdf pkcs12 pkey signature \ encrypt encode sslecho IF[{- !$disabled{"h3demo"} -}] @@ -19,6 +19,10 @@ ENDIF IF[{- !$disabled{"dgram"} -}] SUBDIRS=guide + SUBDIRS=dtlsecho + IF[{- !$disabled{"threads"} -}] + SUBDIRS=dtlslistenerecho + ENDIF ENDIF IF[{- !$disabled{"des"} -}] diff --git a/demos/cipher/aeskeywrap.c b/demos/cipher/aeskeywrap.c index 189eb5c688c39..560c32c5c481f 100644 --- a/demos/cipher/aeskeywrap.c +++ b/demos/cipher/aeskeywrap.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/demos/cipher/ariacbc.c b/demos/cipher/ariacbc.c index f5bb44490dbf6..48c2bdc0bf783 100644 --- a/demos/cipher/ariacbc.c +++ b/demos/cipher/ariacbc.c @@ -1,5 +1,5 @@ /* - * Copyright 2012-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2012-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/demos/digest/EVP_MD_demo.c b/demos/digest/EVP_MD_demo.c index a01ab695bfaec..f24bec75fd1d9 100644 --- a/demos/digest/EVP_MD_demo.c +++ b/demos/digest/EVP_MD_demo.c @@ -1,5 +1,5 @@ /*- - * Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/demos/digest/EVP_MD_xof.c b/demos/digest/EVP_MD_xof.c index f0c9de3e5fd62..fb3020f177c3f 100644 --- a/demos/digest/EVP_MD_xof.c +++ b/demos/digest/EVP_MD_xof.c @@ -1,5 +1,5 @@ /*- - * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -9,8 +9,10 @@ #include #include +#include #include #include +#include #include /* @@ -53,7 +55,13 @@ int main(int argc, char **argv) /* Allow digest length to be changed for demonstration purposes. */ if (argc > 1) { - digest_len_i = atoi(argv[1]); + unsigned long ul; + + if (!OPENSSL_strtoul(argv[1], NULL, 10, &ul) || ul > INT_MAX) { + fprintf(stderr, "Specify a non-negative digest length\n"); + goto end; + } + digest_len_i = (int)ul; if (digest_len_i <= 0) { fprintf(stderr, "Specify a non-negative digest length\n"); goto end; diff --git a/demos/dtlsecho/A-SSL-Docs.txt b/demos/dtlsecho/A-SSL-Docs.txt new file mode 100644 index 0000000000000..d9c18bf1065d3 --- /dev/null +++ b/demos/dtlsecho/A-SSL-Docs.txt @@ -0,0 +1,20 @@ +Useful Links: + +OpenSSL API Documentation: https://docs.openssl.org/master + +Github: https://github.com/openssl/openssl + +OpenSSL Wiki: https://github.com/openssl/openssl/wiki + +Original Simple Server: https://github.com/openssl/openssl/wiki/Simple_TLS_Server + +--------------------------------------------------------------- + +Generate self signed cert and key 'pem' files (good for 10 years): + +openssl req -newkey rsa:4096 -x509 -sha256 -days 3650 -nodes -out cert.pem -keyout key.pem + +You can just hit carriage returns to accept the default values, except for "Common Name"; you +should enter 'localhost', or an actual hostname. + +The same keys can be used for both communicating instances; same or different machines. diff --git a/demos/dtlsecho/README.md b/demos/dtlsecho/README.md new file mode 100644 index 0000000000000..d26909482c9f7 --- /dev/null +++ b/demos/dtlsecho/README.md @@ -0,0 +1,21 @@ +OpenSSL Simple DTLSv1.3 Echo Client/Server +========================================== + +This project implements a simple DTLSv1.3 echo client/server. + +It is a console application, with command line parameters determining the mode +of operation (client or server). Start it with no parameters to see usage. + +The code adapted the sslecho demo to support DTLSv1.3. + +The client code illustrates that: + +- Connection to the DTLS server is established. +- When the DTLSv1.3 connection completes, data is sent and received using + SSL_write() and SSL_read(). +- Pretty simple. + +The cert.pem and key.pem files included are self signed certificates with the +"Common Name" of 'localhost'. + +Best to create the 'pem' files using an actual hostname. diff --git a/demos/dtlsecho/build.info b/demos/dtlsecho/build.info new file mode 100644 index 0000000000000..d9b1aea254db6 --- /dev/null +++ b/demos/dtlsecho/build.info @@ -0,0 +1,11 @@ +# +# To run the demos when linked with a shared library (default) ensure that +# libcrypto and libssl are on the library path. For example: +# +# LD_LIBRARY_PATH=../.. ./dtlsecho + +PROGRAMS{noinst} = dtlsecho + +INCLUDE[dtlsecho]=../../include +SOURCE[dtlsecho]=main.c +DEPEND[dtlsecho]=../../libcrypto ../../libssl diff --git a/demos/dtlsecho/cert.pem b/demos/dtlsecho/cert.pem new file mode 100644 index 0000000000000..834d46285f50c --- /dev/null +++ b/demos/dtlsecho/cert.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFkzCCA3ugAwIBAgIUQJ8FQFwuVg1UlnIBam0+liL0RSQwDQYJKoZIhvcNAQEL +BQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X +DTIyMDIwMjE0MzgzNloXDTMyMDEzMTE0MzgzNlowWTELMAkGA1UEBhMCQVUxEzAR +BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 +IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAyPZfTbR9lVvpHxIGRzpYb1gYFjPZ7yTXYZVKEqQLVxw/O2L32ufa +lODiYJr/pKu9++9T+JrmRnonYlyl0uFta3w4rMY9PzHsT7jIZJByoFdraNz1SnxF +1UaHjzF9fjIA0/n/ZGVJDZCCYulpcVkpW14oNG4tTW5IefYUH3GxmPZ5godhWEla +6OXl3+9xkGd5yXq1O4VZbsekcVcZlznuq7blmvs3UrjrEZ5xgmCd8kNzy/E9APKY +SSGx87/U9yyiz5GAphgSNTqAfEWqpzouMv+hUm/J5NuZCXbOPYbE7zfDDauspYiY +/wdGty9ZvDy5g+fFz8sZig1OWuHqvU8QGoIfVRCxjhX3+p0/KshGDBWjLHek+8Wh +IZHmuf1LgT+gOzN3dxxVEcphSiJX0eZ/OhBelowrdabEycm2WAk3qs/tUDMbWh6V +VSH22ODLX/cBrSAY2sk2EU8Mz5Mbm6gFTcJhqOBgVn5g8/3QCAhFG3xq/2LKZ+za +itAKbaeQqyAw5G/+oc7mKCjUqSKE92n6FKZRsJrB+vfy3AQYyqJevHcIf2nbBimX +vb4/rDed/gvSOVGIXIUiUlFHgg8DoVZqMrfJ+y/xwr+Ya+AX8n6J8EB2It3W4EEf +nmosupBcZPb6U2VrtpEe/199nPj2ZXQHGLLQfw8lYjvZDghCFiP0o8cCAwEAAaNT +MFEwHQYDVR0OBBYEFDClIPCiAkevl1qh188Ycjz5IZ/DMB8GA1UdIwQYMBaAFDCl +IPCiAkevl1qh188Ycjz5IZ/DMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggIBAGQm27D74xUm1X99GbDQpgJenUIu+Bszk8qXCsPfyyQZy4H6+70uXlkC +ASf/keQjrPzrco3rBelbtlCGqqWhsCznVplrjNIntBAkLD0fU3z92SjsMvHEcBDa +Nu6aXExN9gv85EBJHNnj16hqjo8Mk+ydNQ8BtcnZa4zi7GdVh29KbPuEzeoyRnXP +xh5yHUj5Bs6hEUbirhm1WLEK8bvfWykfEJiGOQO8MHAeYK1uPFXDmswgTwJFzZyA +6LSXYbmGOnCM8yAmVXHMnXXCKd+DQFyQ0KrXDiixyTinYFtrONBkNNt/7SnCjJt5 +H3LRTNuoZvvGmaS7GxbIMemBjLdrigKicVZunEPGFRTEL7K+spmSMnpAiITStxjR +70wHEe3M9IUbJximKaxvMhXhP0VSPJGOzgG304A2MqMS7UPBDzD/pz5c7gn7ILfM +LcxzStnQcbTqqmdpNVlMv31YpOk5nel5RY3UmwKbQkix6UAo/CJmC1Q3yLU8uG5O +6j7vS8t0wOYcVTAA845JU8C7V5yy6UeCB9F2oGDgVwCe6U8bzTIoCDnkzIKO7LlS +734KP+fNK9LatNzpPQWW+1SK4XEZBNLOMePwu560GLVzPgr9ji0z83E+0yAcWrAO +4gKT+/h3Ep1Ut73daskFAvNJFFt/5Rm+xZECHrxRkXqW1AN/2eXX +-----END CERTIFICATE----- diff --git a/demos/dtlsecho/key.pem b/demos/dtlsecho/key.pem new file mode 100644 index 0000000000000..75b86c3a38d8e --- /dev/null +++ b/demos/dtlsecho/key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDI9l9NtH2VW+kf +EgZHOlhvWBgWM9nvJNdhlUoSpAtXHD87Yvfa59qU4OJgmv+kq73771P4muZGeidi +XKXS4W1rfDisxj0/MexPuMhkkHKgV2to3PVKfEXVRoePMX1+MgDT+f9kZUkNkIJi +6WlxWSlbXig0bi1Nbkh59hQfcbGY9nmCh2FYSVro5eXf73GQZ3nJerU7hVlux6Rx +VxmXOe6rtuWa+zdSuOsRnnGCYJ3yQ3PL8T0A8phJIbHzv9T3LKLPkYCmGBI1OoB8 +RaqnOi4y/6FSb8nk25kJds49hsTvN8MNq6yliJj/B0a3L1m8PLmD58XPyxmKDU5a +4eq9TxAagh9VELGOFff6nT8qyEYMFaMsd6T7xaEhkea5/UuBP6A7M3d3HFURymFK +IlfR5n86EF6WjCt1psTJybZYCTeqz+1QMxtaHpVVIfbY4Mtf9wGtIBjayTYRTwzP +kxubqAVNwmGo4GBWfmDz/dAICEUbfGr/Yspn7NqK0Aptp5CrIDDkb/6hzuYoKNSp +IoT3afoUplGwmsH69/LcBBjKol68dwh/adsGKZe9vj+sN53+C9I5UYhchSJSUUeC +DwOhVmoyt8n7L/HCv5hr4BfyfonwQHYi3dbgQR+eaiy6kFxk9vpTZWu2kR7/X32c ++PZldAcYstB/DyViO9kOCEIWI/SjxwIDAQABAoICAH51SpODOGN8ar36gajgtjWa +oc2W41TxQfdOEkaYo+o1BDVCmeVOcOWufcV8w9HDoNGgUJ7oGm/O/mmPE2oYINq6 +WI+gT3os2B9yj+d4Xik32YcrQ8+TU/5ZW4RoCCgZHxxE/MkYU1gNz36ekpOZH8U3 +AuW7Txaih0j36MHAsZknwF67Ai6kOmjEAltgOX49Hw4CAXlq+FQVnQ0VWi0nb2Du +vp0/6BhN9N4pbhQ06C9C8uMq8tBd2CZs5aYU2NaRaAJl9SaPjyWfoqqQzEpe+iNt +aP6PCeTRqwOhlzZwUAyYck1v8jxYMK6KzZ0IVtd0/uhaOMgBbhjJNr1J3IUz81Ud +gwmU7UrifjtcGiMHNmHnIAJNcbm9sY27EvsyEHz3zf90VQL8wLpYflX9kX5v8soi +WPv6On+u7ARKofHfQKmP1BfJoGY651uyI1vqdpwUds9iQk3dZWUuBf1WRzywH4t/ +Vwz/h9cEW1Pd42cjukRCoPE1kLc9vHBUEADaaQG7Y5avuLIfDFzXEmwf9YokGRcy +ULUikhhFgiL4bOiQ4cj0/c3CLFAM98iq+z1pTlGFy5msjgUTg3ouUUbbPTaxaMS5 +yVeXelleQADdpj25MTGatBkGW4WC3DYopvvSy+DZ6XarJ6gYm+/cV+eoXddQYLUd +RAQqnQFqVPUIy2rlVuQBAoIBAQDlKILSqQNPZqou6lFgo4tbFLpzUFVAnmrEUhuJ +3v9ppseKncolZ3pcr10VwIzuQZliLLvUiZ8aB+TzMeuIRBm1PkXMpSRhPsVb2bGb +QrTzzPafB8uwVwvr3YzYeRXbpdabU9UpuQMk+lD+GEx5DfowdYJMtdIBOeQdjROi +7JZnHPfNwNheEakJpCgPbulQRfrXx4Fd+npWQprcvCYhg8vnqCHrGazy5g/2dnYF +NW7L2CNHdM74SJKl8gY/YcfEQSFcir6SFWUGPOiHsVdpKX9K0his6DoiV8QPH/S0 +RIKZuNIuOmiO8ATblYksrh8UuOQWi2kywE3bF3neMmNgwoRBAoIBAQDggGL0C9Ij +n+DHlkHujbziEwe1pLVSb4x2q5KmZwA4VWDGLARbK2ypx6/LJDsUCwK6ZFHh89DU +eW9Ze6fXMi8Fiv1N1DfawIu9+bU3BG5boiQMdAgYzSCUhwojo3KiIpvbzXCmSQd9 +1lJkbwxQFo2GuYZIX+QLyONhGBA1JdF0kBzIrrQWmza+wNj1emftFptZlwAW1+wm +KvZyzAZl3/5fj5/9oAMxlH489edbgRMF/cOmzpB4fIAkbzmvU97xXOzKWX+nPA6D +BTVkkruqESpq2pf06gGnlbCC5Tcf1QS+On+/LGr1frr/aeouRy8xHv5xgVCRcyh+ +nLwOP6W/KYYHAoIBAQCXgjtMkJYxrw0hy6ZWIIsIgyHrD9fty0+H0UmH1DpGXhBb +44s9Q7cxBHik4xPKivCgajcdhIf+q+2BpSW2iF/+5tc7QIxXBytxWPMGVgpRjtgX +uQ3A3yxwm6B9l0EOYg0L0VeEKGCd2CoodWRKPSWHWIn3sdbRHLdnmli7RXUDY7Gr +Ba+IMmDykOgzm/8CJeJ9O9iai/rKgWrmOjdzvTHZTd5vFCC2z8kKCLRrKTLB73sT +yXT1zvW2Zdgfm8R6Sx2Fk+3/o8mRYD/VRzklvFv+2f2ahEe7YQ+teFFPxmQawomk +KtXqe2Ka07lIIy9FgiC7jxzUgzR2gIUAlYwC81iBAoIBAC30Oc0oykf+hv1z1WUm +YD6KlK5q267XJJJ6BlfHh7UATQHjqrSay/Bo7qQPc4RjyJgsxtIQnXOQs+lGNZII +NLXWwIj44sIFXdVyUtTDNG/PXb+q1Kl2+69LgRjQcTudB/hTMjbnhgANKepjDMss +AqZMPZ98+WosIdcTHOY0Ko7InQu7LyPde7RKN17wQmu2j/Ajx6HlavJZIv9Wogyi +cChRdvdslJrGgZyq3UPOxP0Z972iVNJE8doDZnRsH5uaYOH+tfGein3pSAehPYbP +YrZirm40pEgQjQQONV1vtjvWL6YLSo2b9l0n6ga1DYTpij3jsYFEaEqafKgSATSD +JGsCggEAVnGMMovIgEADUAiwQzlYb5/gUjRJOetFpPW8R/3CZqFt3FTprNH0Q7Jb +be3PJCLONqYE8K84n66Ro5I/58oVcJ5QwCwZCmZ+Kk4u7j0RYR9kkpR6gWShSpfw +CkrSVNz0zn3l8GxIs11YO+ztBQG82StU+7PTZH9KGEQhytO3km+txC3EXih7Fn7R +Vb2rJ+2v6aSGjH+1n/GFP8YxKAxYk7jPwI5s4YMrn6TQPt4tgr4I0f7DDjjlVLEg +LMixBvYHG/8fXWtldf6Wwhl6UJ5G0LA4KxXRAJ68RX8cQNLG7mv66xogbLEMnrJr +DDFU5HazFnn1G0/rg2SnKHTRLV2E9g== +-----END PRIVATE KEY----- diff --git a/demos/dtlsecho/main.c b/demos/dtlsecho/main.c new file mode 100644 index 0000000000000..e9856171f9dd6 --- /dev/null +++ b/demos/dtlsecho/main.c @@ -0,0 +1,426 @@ +/* + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#if !defined(OPENSSL_SYS_WINDOWS) +#include +#include +#include +#include + +#define SOCKET int +#define INVALID_SOCKET -1 +#define closesocket(s) close(s) + +#else +#include +#include +#endif + +static const int server_port = 4433; + +typedef unsigned char flag; +#define true 1 +#define false 0 + +/* + * This flag won't be useful until both accept/read (UDP & DTLS) methods + * can be called with a timeout. TBD. + */ +static volatile flag server_running = true; + +static SOCKET create_socket(void) +{ + SOCKET s = INVALID_SOCKET; + BIO_ADDRINFO *res = NULL; + const BIO_ADDR *addr; + char port_str[6]; + + /* + * Resolve the wildcard address for our port. Requesting AF_INET6 gives a + * single socket that, BIO_listen will clear IPV6_V6ONLY below, and the + * socket accepts both IPv6 and IPv4 clients. + */ + snprintf(port_str, sizeof(port_str), "%d", server_port); + if (!BIO_lookup_ex(NULL, port_str, BIO_LOOKUP_SERVER, AF_INET6, + SOCK_DGRAM, 0, &res)) { + fprintf(stderr, "Unable to resolve local address\n"); + ERR_print_errors_fp(stderr); + exit(EXIT_FAILURE); + } + addr = BIO_ADDRINFO_address(res); + + s = BIO_socket(BIO_ADDRINFO_family(res), SOCK_DGRAM, 0, 0); + if (s == INVALID_SOCKET) { + fprintf(stderr, "Unable to create socket\n"); + ERR_print_errors_fp(stderr); + BIO_ADDRINFO_free(res); + exit(EXIT_FAILURE); + } + + /* + * BIO_listen binds with SO_REUSEADDR and, since we do not pass + * BIO_SOCK_V6_ONLY, clears IPV6_V6ONLY to give us a dual-stack socket + * that serves both IPv6 and IPv4 clients. + */ + if (!BIO_listen((int)s, addr, BIO_SOCK_REUSEADDR)) { + fprintf(stderr, "Unable to bind\n"); + ERR_print_errors_fp(stderr); + BIO_closesocket((int)s); + BIO_ADDRINFO_free(res); + exit(EXIT_FAILURE); + } + + BIO_ADDRINFO_free(res); + return s; +} + +static SSL_CTX *create_context(flag isServer) +{ + const SSL_METHOD *method; + SSL_CTX *ctx; + + if (isServer) + method = DTLS_server_method(); + else + method = DTLS_client_method(); + + ctx = SSL_CTX_new(method); + if (ctx == NULL) { + perror("Unable to create SSL context"); + ERR_print_errors_fp(stderr); + exit(EXIT_FAILURE); + } + + /* Restrict to DTLSv1.3 only */ + if (!SSL_CTX_set_min_proto_version(ctx, DTLS1_3_VERSION)) { + ERR_print_errors_fp(stderr); + SSL_CTX_free(ctx); + exit(EXIT_FAILURE); + } + if (!SSL_CTX_set_max_proto_version(ctx, DTLS1_3_VERSION)) { + ERR_print_errors_fp(stderr); + SSL_CTX_free(ctx); + exit(EXIT_FAILURE); + } + + return ctx; +} + +static void configure_server_context(SSL_CTX *ctx) +{ + /* Set the key and cert */ + if (SSL_CTX_use_certificate_chain_file(ctx, "cert.pem") <= 0) { + ERR_print_errors_fp(stderr); + exit(EXIT_FAILURE); + } + + if (SSL_CTX_use_PrivateKey_file(ctx, "key.pem", SSL_FILETYPE_PEM) <= 0) { + ERR_print_errors_fp(stderr); + exit(EXIT_FAILURE); + } +} + +static void configure_client_context(SSL_CTX *ctx) +{ + /* + * Configure the client to abort the handshake if certificate verification + * fails + */ + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); + /* + * In a real application you would probably just use the default system + * certificate trust store and call: + * SSL_CTX_set_default_verify_paths(ctx); + * In this demo though we are using a self-signed certificate, so the + * client must trust it directly. + */ + if (!SSL_CTX_load_verify_locations(ctx, "cert.pem", NULL)) { + ERR_print_errors_fp(stderr); + exit(EXIT_FAILURE); + } +} + +static void usage(void) +{ + printf("Usage: dtlsecho s\n"); + printf(" --or--\n"); + printf(" dtlsecho c hostname\n"); + printf(" c=client, s=server, hostname=hostname of server\n"); + exit(EXIT_FAILURE); +} + +#define BUFFERSIZE 1024 +int main(int argc, char **argv) +{ + flag isServer; + int result; + + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + + SOCKET server_skt = INVALID_SOCKET; + SOCKET client_skt = INVALID_SOCKET; + + /* used by fgets */ + char buffer[BUFFERSIZE]; + char *txbuf; + + char rxbuf[128]; + size_t rxcap = sizeof(rxbuf); + int rxlen; + + char *rem_server_name = NULL; + + int received_new_session_ack = 0; + +#if !defined(OPENSSL_SYS_WINDOWS) + /* Ignore SIGPIPE so that server can continue running when client pipe closes abruptly */ + signal(SIGPIPE, SIG_IGN); +#endif + + /* Splash */ + printf("\ndtlsecho : Simple Echo Client/Server : %s : %s\n\n", __DATE__, + __TIME__); + + /* Need to know if client or server */ + if (argc < 2) { + usage(); + /* NOTREACHED */ + } + isServer = (argv[1][0] == 's') ? true : false; + /* If client get remote server hostname */ + if (!isServer) { + if (argc != 3) { + usage(); + /* NOTREACHED */ + } + rem_server_name = argv[2]; + } + + /* Create context used by both client and server */ + ssl_ctx = create_context(isServer); + + /* If server */ + if (isServer) { + BIO *bio = NULL; + + printf("We are the server on port: %d\n\n", server_port); + + /* Configure server context with appropriate key files */ + configure_server_context(ssl_ctx); + + /* Create server socket; will bind to server port */ + server_skt = create_socket(); + if (server_skt == INVALID_SOCKET) { + perror("Unable to create server socket"); + exit(EXIT_FAILURE); + } + + printf("Waiting for DTLS connection...\n"); + + ssl = SSL_new(ssl_ctx); + if (ssl == NULL) { + ERR_print_errors_fp(stderr); + goto exit; + } + + /* Wrap the bound server socket in a datagram BIO for OpenSSL */ + bio = BIO_new_dgram((int)server_skt, BIO_NOCLOSE); + if (bio == NULL) { + ERR_print_errors_fp(stderr); + goto exit; + } + SSL_set_bio(ssl, bio, bio); + DTLS_set_link_mtu(ssl, 1500); + + /* Complete the DTLS handshake */ + if (SSL_accept(ssl) <= 0) { + ERR_print_errors_fp(stderr); + goto exit; + } + + printf("Client DTLS connection accepted\n\n"); + + /* Echo loop */ + while (server_running) { + /* Get message from client; will fail if client closes connection */ + if ((rxlen = SSL_read(ssl, rxbuf, (int)rxcap)) <= 0) { + if (rxlen == 0) { + printf("Client closed connection\n"); + } else { + /* + * When the application starts the server is waiting for + * ACKs to the new session tickets it sent out. Therefore + * it will return -1 on the SSL_read until it receives + * those acks. For that scenario, let's keep us in the loop. + */ + if (received_new_session_ack) + printf("SSL_read returned %d\n", rxlen); + continue; + } + ERR_print_errors_fp(stderr); + break; + } + received_new_session_ack = 1; + /* Insure null terminated input */ + rxbuf[rxlen] = 0; + /* Look for kill switch */ + if (strcmp(rxbuf, "kill\n") == 0) { + /* Terminate...with extreme prejudice */ + printf("Server received 'kill' command\n"); + server_running = false; + break; + } + /* Show received message */ + printf("Received: %s", rxbuf); + /* Echo it back */ + if (SSL_write(ssl, rxbuf, rxlen) <= 0) { + ERR_print_errors_fp(stderr); + } + } + + printf("Server exiting...\n"); + } + /* Else client */ + else { + BIO *bio; + BIO_ADDRINFO *res = NULL; + const BIO_ADDRINFO *ai = NULL; + char port_str[6]; + + printf("We are the client\n\n"); + + /* Configure client context so we verify the server correctly */ + configure_client_context(ssl_ctx); + + /* Resolve server hostname or IP address (IPv4 or IPv6) */ + snprintf(port_str, sizeof(port_str), "%d", server_port); + if (!BIO_lookup(rem_server_name, port_str, BIO_LOOKUP_CLIENT, + AF_UNSPEC, SOCK_DGRAM, &res)) { + fprintf(stderr, "Unable to resolve server: %s\n", rem_server_name); + ERR_print_errors_fp(stderr); + goto exit; + } + + /* + * Iterate over the resolved addresses and connect to the first one + * that works, creating a UDP socket of the matching address family for + * each attempt. For UDP, BIO_connect just sets the default peer address. + */ + for (ai = res; ai != NULL; ai = BIO_ADDRINFO_next(ai)) { + client_skt = BIO_socket(BIO_ADDRINFO_family(ai), SOCK_DGRAM, 0, 0); + if (client_skt == INVALID_SOCKET) + continue; + if (BIO_connect((int)client_skt, BIO_ADDRINFO_address(ai), 0)) + break; + BIO_closesocket((int)client_skt); + client_skt = INVALID_SOCKET; + } + BIO_ADDRINFO_free(res); + + if (client_skt == INVALID_SOCKET) { + fprintf(stderr, "Unable to UDP connect to server: %s\n", + rem_server_name); + ERR_print_errors_fp(stderr); + goto exit; + } + printf("UDP connection to server successful\n"); + + /* Create a datagram BIO for the connected socket */ + bio = BIO_new_dgram((int)client_skt, BIO_NOCLOSE); + if (bio == NULL) { + ERR_print_errors_fp(stderr); + goto exit; + } + + /* Create client SSL structure and attach the BIO */ + ssl = SSL_new(ssl_ctx); + if (ssl == NULL) { + ERR_print_errors_fp(stderr); + BIO_free(bio); + goto exit; + } + SSL_set_bio(ssl, bio, bio); + + /* Configure server hostname check */ + if (!SSL_set1_dnsname(ssl, rem_server_name)) { + ERR_print_errors_fp(stderr); + goto exit; + } + + /* Now do DTLS connect with server */ + if (SSL_connect(ssl) == 1) { + + printf("DTLS connection to server successful\n\n"); + + /* Loop to send input from keyboard */ + while (true) { + /* Get a line of input */ + memset(buffer, 0, BUFFERSIZE); + txbuf = fgets(buffer, BUFFERSIZE, stdin); + + /* Exit loop on error */ + if (txbuf == NULL) { + break; + } + /* Exit loop if just a carriage return */ + if (txbuf[0] == '\n') { + break; + } + /* Send it to the server */ + if ((result = SSL_write(ssl, txbuf, (int)strlen(txbuf))) <= 0) { + printf("Server closed connection\n"); + ERR_print_errors_fp(stderr); + break; + } + + /* Wait for the echo */ + rxlen = SSL_read(ssl, rxbuf, (int)rxcap); + if (rxlen <= 0) { + printf("Server closed connection\n"); + ERR_print_errors_fp(stderr); + break; + } else { + /* Show it */ + rxbuf[rxlen] = 0; + printf("Received: %s", rxbuf); + } + } + printf("Client exiting...\n"); + } else { + + printf("DTLS connection to server failed\n\n"); + + ERR_print_errors_fp(stderr); + } + } +exit: + /* Close up */ + if (ssl != NULL) { + SSL_shutdown(ssl); + SSL_free(ssl); + } + SSL_CTX_free(ssl_ctx); + + if (client_skt != INVALID_SOCKET) + closesocket(client_skt); + if (server_skt != INVALID_SOCKET) + closesocket(server_skt); + + printf("dtlsecho exiting\n"); + + return EXIT_SUCCESS; +} diff --git a/demos/dtlslistenerecho/README.md b/demos/dtlslistenerecho/README.md new file mode 100644 index 0000000000000..7811e9341f8e3 --- /dev/null +++ b/demos/dtlslistenerecho/README.md @@ -0,0 +1,120 @@ +OpenSSL DTLS Listener Server/Client +=================================== + +This project implements a simple echo application utilizing DTLS SSL Listener. + +It is a console application, with command line parameters determining the mode +of operation (client or server). Start it with no parameters to see usage. + +The server code utilizes the SSL Listener to setup a DTLS Server object that +can handle multiple client connections using a thread-per-connection model. +Each accepted connection is handled in its own dedicated thread using the +platform's native threads. + +The client will send application data to the server and the server will simply +respond to the client with an echo of that data. + +Features +-------- + +- Up to 10 concurrent DTLS client connections (MAX_CONNECTIONS) +- Thread-per-connection architecture using native OS threads +- Non-blocking I/O using SSL_poll() within each connection thread +- Supports both DTLS 1.2 (HelloVerifyRequest) and DTLS 1.3 (HelloRetryRequest) +- Client option to specify DTLS protocol version (dtls12 or dtls13) +- Active shutdown signaling for clean thread termination +- Server-wide shutdown via "killall" command + +Limitations +----------- + +- Maximum 10 concurrent client connections (defined by MAX_CONNECTIONS) +- Additional connection attempts while at capacity will be rejected with an + error message printed to the server console +- Connections do not stay open indefinitely: if a client sends no data for + CLIENT_IDLE_TIMEOUT_SEC (90 seconds), the server abandons the connection and + frees its thread slot. A stalled handshake is likewise time-bounded rather + than retried for minutes (see dtls_timer_cb() in main.c) + +The code demonstrates +--------------------- + +- DTLS Server using SSL Listener APIs to establish Connections +- Placing the listener (and the connections it accepts, which inherit its mode) + into non-blocking mode via SSL_set_blocking_mode(), since a DTLS listener is + blocking by default +- DTLS Server validating Clients via HRR/HVR +- Thread-per-connection model for handling multiple clients +- Clients sending data to an established Server +- Server utilizing SSL_poll() within each thread for read readiness +- Server sending data to an established Client +- Client-side DTLS version selection via command-line argument +- Using SSL_CTX_set_min_proto_version() and SSL_CTX_set_max_proto_version() +- Bounding the handshake retransmit backoff via DTLS_set_timer_cb() +- Active thread shutdown via signaling mechanism +- Graceful server shutdown with client disconnection + +Running +------- + +First, change to the demo directory: + +```console +cd demos/dtlslistenerecho +``` + +### Start the Server + +```console +./dtlslistenerecho s +``` + +### Connect Multiple Clients (in separate terminals) + +You can connect up to 10 clients simultaneously: + +```console +./dtlslistenerecho c localhost +./dtlslistenerecho c localhost +./dtlslistenerecho c localhost +``` + +Each client can send messages independently and receive echoes. + +### Specify DTLS Protocol Version + +You can optionally specify the DTLS protocol version for the client: + +```console +# Connect using DTLS 1.2 +./dtlslistenerecho c localhost dtls12 + +# Connect using DTLS 1.3 +./dtlslistenerecho c localhost dtls13 + +# Connect using default (negotiates highest available) +./dtlslistenerecho c localhost +``` + +Special Commands +---------------- + +- Type "kill" in a client to disconnect that client only (server continues running) +- Type "killall" in a client to disconnect all clients and shutdown the server gracefully + +When "killall" is received: +1. The server sets a shutdown flag +2. All connection threads are signaled to terminate +3. Each thread completes its current operation and exits cleanly +4. The server closes the listener and exits + +The cert.pem and key.pem files included are self signed certificates with the +"Common Name" of 'localhost'. + +The client verifies the server's certificate against the hostname you pass on +the command line (via SSL_set1_dnsname()), so that name must match the +certificate. With the bundled certificate you must use 'localhost'. Note that +the hostname is matched strictly as a DNS name: an IP address literal such as +'127.0.0.1' will not verify, even though it resolves to the same host. + +Best to create the 'pem' files using an actual hostname. diff --git a/demos/dtlslistenerecho/build.info b/demos/dtlslistenerecho/build.info new file mode 100644 index 0000000000000..a7c44df0431e8 --- /dev/null +++ b/demos/dtlslistenerecho/build.info @@ -0,0 +1,11 @@ +# +# To run the demos when linked with a shared library (default) ensure that +# libcrypto and libssl are on the library path. For example: +# +# LD_LIBRARY_PATH=../.. ./dtlslistenerecho + +PROGRAMS{noinst} = dtlslistenerecho + +INCLUDE[dtlslistenerecho]=../../include +SOURCE[dtlslistenerecho]=main.c +DEPEND[dtlslistenerecho]=../../libcrypto ../../libssl diff --git a/demos/dtlslistenerecho/cert.pem b/demos/dtlslistenerecho/cert.pem new file mode 100644 index 0000000000000..834d46285f50c --- /dev/null +++ b/demos/dtlslistenerecho/cert.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFkzCCA3ugAwIBAgIUQJ8FQFwuVg1UlnIBam0+liL0RSQwDQYJKoZIhvcNAQEL +BQAwWTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM +GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MB4X +DTIyMDIwMjE0MzgzNloXDTMyMDEzMTE0MzgzNlowWTELMAkGA1UEBhMCQVUxEzAR +BgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5 +IEx0ZDESMBAGA1UEAwwJbG9jYWxob3N0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEAyPZfTbR9lVvpHxIGRzpYb1gYFjPZ7yTXYZVKEqQLVxw/O2L32ufa +lODiYJr/pKu9++9T+JrmRnonYlyl0uFta3w4rMY9PzHsT7jIZJByoFdraNz1SnxF +1UaHjzF9fjIA0/n/ZGVJDZCCYulpcVkpW14oNG4tTW5IefYUH3GxmPZ5godhWEla +6OXl3+9xkGd5yXq1O4VZbsekcVcZlznuq7blmvs3UrjrEZ5xgmCd8kNzy/E9APKY +SSGx87/U9yyiz5GAphgSNTqAfEWqpzouMv+hUm/J5NuZCXbOPYbE7zfDDauspYiY +/wdGty9ZvDy5g+fFz8sZig1OWuHqvU8QGoIfVRCxjhX3+p0/KshGDBWjLHek+8Wh +IZHmuf1LgT+gOzN3dxxVEcphSiJX0eZ/OhBelowrdabEycm2WAk3qs/tUDMbWh6V +VSH22ODLX/cBrSAY2sk2EU8Mz5Mbm6gFTcJhqOBgVn5g8/3QCAhFG3xq/2LKZ+za +itAKbaeQqyAw5G/+oc7mKCjUqSKE92n6FKZRsJrB+vfy3AQYyqJevHcIf2nbBimX +vb4/rDed/gvSOVGIXIUiUlFHgg8DoVZqMrfJ+y/xwr+Ya+AX8n6J8EB2It3W4EEf +nmosupBcZPb6U2VrtpEe/199nPj2ZXQHGLLQfw8lYjvZDghCFiP0o8cCAwEAAaNT +MFEwHQYDVR0OBBYEFDClIPCiAkevl1qh188Ycjz5IZ/DMB8GA1UdIwQYMBaAFDCl +IPCiAkevl1qh188Ycjz5IZ/DMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggIBAGQm27D74xUm1X99GbDQpgJenUIu+Bszk8qXCsPfyyQZy4H6+70uXlkC +ASf/keQjrPzrco3rBelbtlCGqqWhsCznVplrjNIntBAkLD0fU3z92SjsMvHEcBDa +Nu6aXExN9gv85EBJHNnj16hqjo8Mk+ydNQ8BtcnZa4zi7GdVh29KbPuEzeoyRnXP +xh5yHUj5Bs6hEUbirhm1WLEK8bvfWykfEJiGOQO8MHAeYK1uPFXDmswgTwJFzZyA +6LSXYbmGOnCM8yAmVXHMnXXCKd+DQFyQ0KrXDiixyTinYFtrONBkNNt/7SnCjJt5 +H3LRTNuoZvvGmaS7GxbIMemBjLdrigKicVZunEPGFRTEL7K+spmSMnpAiITStxjR +70wHEe3M9IUbJximKaxvMhXhP0VSPJGOzgG304A2MqMS7UPBDzD/pz5c7gn7ILfM +LcxzStnQcbTqqmdpNVlMv31YpOk5nel5RY3UmwKbQkix6UAo/CJmC1Q3yLU8uG5O +6j7vS8t0wOYcVTAA845JU8C7V5yy6UeCB9F2oGDgVwCe6U8bzTIoCDnkzIKO7LlS +734KP+fNK9LatNzpPQWW+1SK4XEZBNLOMePwu560GLVzPgr9ji0z83E+0yAcWrAO +4gKT+/h3Ep1Ut73daskFAvNJFFt/5Rm+xZECHrxRkXqW1AN/2eXX +-----END CERTIFICATE----- diff --git a/demos/dtlslistenerecho/key.pem b/demos/dtlslistenerecho/key.pem new file mode 100644 index 0000000000000..75b86c3a38d8e --- /dev/null +++ b/demos/dtlslistenerecho/key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDI9l9NtH2VW+kf +EgZHOlhvWBgWM9nvJNdhlUoSpAtXHD87Yvfa59qU4OJgmv+kq73771P4muZGeidi +XKXS4W1rfDisxj0/MexPuMhkkHKgV2to3PVKfEXVRoePMX1+MgDT+f9kZUkNkIJi +6WlxWSlbXig0bi1Nbkh59hQfcbGY9nmCh2FYSVro5eXf73GQZ3nJerU7hVlux6Rx +VxmXOe6rtuWa+zdSuOsRnnGCYJ3yQ3PL8T0A8phJIbHzv9T3LKLPkYCmGBI1OoB8 +RaqnOi4y/6FSb8nk25kJds49hsTvN8MNq6yliJj/B0a3L1m8PLmD58XPyxmKDU5a +4eq9TxAagh9VELGOFff6nT8qyEYMFaMsd6T7xaEhkea5/UuBP6A7M3d3HFURymFK +IlfR5n86EF6WjCt1psTJybZYCTeqz+1QMxtaHpVVIfbY4Mtf9wGtIBjayTYRTwzP +kxubqAVNwmGo4GBWfmDz/dAICEUbfGr/Yspn7NqK0Aptp5CrIDDkb/6hzuYoKNSp +IoT3afoUplGwmsH69/LcBBjKol68dwh/adsGKZe9vj+sN53+C9I5UYhchSJSUUeC +DwOhVmoyt8n7L/HCv5hr4BfyfonwQHYi3dbgQR+eaiy6kFxk9vpTZWu2kR7/X32c ++PZldAcYstB/DyViO9kOCEIWI/SjxwIDAQABAoICAH51SpODOGN8ar36gajgtjWa +oc2W41TxQfdOEkaYo+o1BDVCmeVOcOWufcV8w9HDoNGgUJ7oGm/O/mmPE2oYINq6 +WI+gT3os2B9yj+d4Xik32YcrQ8+TU/5ZW4RoCCgZHxxE/MkYU1gNz36ekpOZH8U3 +AuW7Txaih0j36MHAsZknwF67Ai6kOmjEAltgOX49Hw4CAXlq+FQVnQ0VWi0nb2Du +vp0/6BhN9N4pbhQ06C9C8uMq8tBd2CZs5aYU2NaRaAJl9SaPjyWfoqqQzEpe+iNt +aP6PCeTRqwOhlzZwUAyYck1v8jxYMK6KzZ0IVtd0/uhaOMgBbhjJNr1J3IUz81Ud +gwmU7UrifjtcGiMHNmHnIAJNcbm9sY27EvsyEHz3zf90VQL8wLpYflX9kX5v8soi +WPv6On+u7ARKofHfQKmP1BfJoGY651uyI1vqdpwUds9iQk3dZWUuBf1WRzywH4t/ +Vwz/h9cEW1Pd42cjukRCoPE1kLc9vHBUEADaaQG7Y5avuLIfDFzXEmwf9YokGRcy +ULUikhhFgiL4bOiQ4cj0/c3CLFAM98iq+z1pTlGFy5msjgUTg3ouUUbbPTaxaMS5 +yVeXelleQADdpj25MTGatBkGW4WC3DYopvvSy+DZ6XarJ6gYm+/cV+eoXddQYLUd +RAQqnQFqVPUIy2rlVuQBAoIBAQDlKILSqQNPZqou6lFgo4tbFLpzUFVAnmrEUhuJ +3v9ppseKncolZ3pcr10VwIzuQZliLLvUiZ8aB+TzMeuIRBm1PkXMpSRhPsVb2bGb +QrTzzPafB8uwVwvr3YzYeRXbpdabU9UpuQMk+lD+GEx5DfowdYJMtdIBOeQdjROi +7JZnHPfNwNheEakJpCgPbulQRfrXx4Fd+npWQprcvCYhg8vnqCHrGazy5g/2dnYF +NW7L2CNHdM74SJKl8gY/YcfEQSFcir6SFWUGPOiHsVdpKX9K0his6DoiV8QPH/S0 +RIKZuNIuOmiO8ATblYksrh8UuOQWi2kywE3bF3neMmNgwoRBAoIBAQDggGL0C9Ij +n+DHlkHujbziEwe1pLVSb4x2q5KmZwA4VWDGLARbK2ypx6/LJDsUCwK6ZFHh89DU +eW9Ze6fXMi8Fiv1N1DfawIu9+bU3BG5boiQMdAgYzSCUhwojo3KiIpvbzXCmSQd9 +1lJkbwxQFo2GuYZIX+QLyONhGBA1JdF0kBzIrrQWmza+wNj1emftFptZlwAW1+wm +KvZyzAZl3/5fj5/9oAMxlH489edbgRMF/cOmzpB4fIAkbzmvU97xXOzKWX+nPA6D +BTVkkruqESpq2pf06gGnlbCC5Tcf1QS+On+/LGr1frr/aeouRy8xHv5xgVCRcyh+ +nLwOP6W/KYYHAoIBAQCXgjtMkJYxrw0hy6ZWIIsIgyHrD9fty0+H0UmH1DpGXhBb +44s9Q7cxBHik4xPKivCgajcdhIf+q+2BpSW2iF/+5tc7QIxXBytxWPMGVgpRjtgX +uQ3A3yxwm6B9l0EOYg0L0VeEKGCd2CoodWRKPSWHWIn3sdbRHLdnmli7RXUDY7Gr +Ba+IMmDykOgzm/8CJeJ9O9iai/rKgWrmOjdzvTHZTd5vFCC2z8kKCLRrKTLB73sT +yXT1zvW2Zdgfm8R6Sx2Fk+3/o8mRYD/VRzklvFv+2f2ahEe7YQ+teFFPxmQawomk +KtXqe2Ka07lIIy9FgiC7jxzUgzR2gIUAlYwC81iBAoIBAC30Oc0oykf+hv1z1WUm +YD6KlK5q267XJJJ6BlfHh7UATQHjqrSay/Bo7qQPc4RjyJgsxtIQnXOQs+lGNZII +NLXWwIj44sIFXdVyUtTDNG/PXb+q1Kl2+69LgRjQcTudB/hTMjbnhgANKepjDMss +AqZMPZ98+WosIdcTHOY0Ko7InQu7LyPde7RKN17wQmu2j/Ajx6HlavJZIv9Wogyi +cChRdvdslJrGgZyq3UPOxP0Z972iVNJE8doDZnRsH5uaYOH+tfGein3pSAehPYbP +YrZirm40pEgQjQQONV1vtjvWL6YLSo2b9l0n6ga1DYTpij3jsYFEaEqafKgSATSD +JGsCggEAVnGMMovIgEADUAiwQzlYb5/gUjRJOetFpPW8R/3CZqFt3FTprNH0Q7Jb +be3PJCLONqYE8K84n66Ro5I/58oVcJ5QwCwZCmZ+Kk4u7j0RYR9kkpR6gWShSpfw +CkrSVNz0zn3l8GxIs11YO+ztBQG82StU+7PTZH9KGEQhytO3km+txC3EXih7Fn7R +Vb2rJ+2v6aSGjH+1n/GFP8YxKAxYk7jPwI5s4YMrn6TQPt4tgr4I0f7DDjjlVLEg +LMixBvYHG/8fXWtldf6Wwhl6UJ5G0LA4KxXRAJ68RX8cQNLG7mv66xogbLEMnrJr +DDFU5HazFnn1G0/rg2SnKHTRLV2E9g== +-----END PRIVATE KEY----- diff --git a/demos/dtlslistenerecho/main.c b/demos/dtlslistenerecho/main.c new file mode 100644 index 0000000000000..bdaf445d2f667 --- /dev/null +++ b/demos/dtlslistenerecho/main.c @@ -0,0 +1,1067 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(OPENSSL_SYS_WINDOWS) +#include +#include +#include +#include +#include +#include + +#define SOCKET int +#define INVALID_SOCKET (-1) +#define closesocket(s) close(s) + +#else +#include +#include +#include +#endif + +#if defined(OPENSSL_SYS_WINDOWS) +typedef HANDLE thread_t; +#else +typedef pthread_t thread_t; +#endif + +static const int server_port = 4433; + +#define MAX_CONNECTIONS 10 +#define POLL_TIMEOUT_SEC 5 +/* Abandon a connection whose client sends nothing for 90 seconds. */ +#define CLIENT_IDLE_TIMEOUT_SEC 90 + +/* + * Cap the DTLS handshake retransmit backoff. The library default doubles the + * timeout up to 60s; across the retransmits DTLS allows before giving up that + * lets a dead peer stall a handshake for nearly 8 minutes. Capping each backoff + * at 8s bounds the handshake to about 87s (1 + 2 + 4 + 8 x 10), keeping it in + * line with CLIENT_IDLE_TIMEOUT_SEC. See dtls_timer_cb(). + */ +#define DTLS_MAX_RETRANSMIT_TIMEOUT_US (8 * 1000000u) + +/* + * Per-thread state for connection handlers + */ +struct connection_thread_args { + SSL *conn; + int thread_idx; + thread_t thread; + int active; + int shutdown_requested; + int finished; + int *server_shutdown; +}; + +static CRYPTO_RWLOCK *atomic_lock = NULL; + +static SSL_CTX *create_context(bool isServer) +{ + SSL_CTX *ctx; + + if (isServer) { + ctx = SSL_CTX_new(DTLS_server_method()); + } else { + ctx = SSL_CTX_new(DTLS_client_method()); + } + + if (ctx == NULL) { + fprintf(stderr, "Unable to create SSL context\n"); + ERR_print_errors_fp(stderr); + exit(EXIT_FAILURE); + } + + return ctx; +} + +/* + * DTLS retransmit timer callback. Installed with DTLS_set_timer_cb(), it is + * invoked for each handshake flight to choose the next retransmit interval. + * timer_us holds the previous interval (0 on the first call). We start at 1s + * and double, but cap the backoff so a stalled handshake is abandoned in a + * reasonable time rather than the library default of nearly 8 minutes. + */ +static unsigned int dtls_timer_cb(SSL *s, unsigned int timer_us) +{ + unsigned int next = (timer_us == 0) ? 1000000u : timer_us * 2; + + if (next > DTLS_MAX_RETRANSMIT_TIMEOUT_US) + next = DTLS_MAX_RETRANSMIT_TIMEOUT_US; + return next; +} + +static int create_dtls_listener(SSL_CTX *ssl_ctx, int port, + SSL **listener, SOCKET *server_fd) +{ + BIO *listener_bio = NULL; + BIO_ADDRINFO *res = NULL; + const BIO_ADDR *addr; + char port_str[6]; + int ret = 0; + + *listener = NULL; + *server_fd = INVALID_SOCKET; + + /* + * Resolve the wildcard address for our port. Requesting AF_INET6 gives a + * single socket that, since we do not pass BIO_SOCK_V6_ONLY to BIO_listen, + * serves both IPv6 and IPv4 clients. + */ + snprintf(port_str, sizeof(port_str), "%d", port); + if (!BIO_lookup_ex(NULL, port_str, BIO_LOOKUP_SERVER, AF_INET6, + SOCK_DGRAM, 0, &res)) { + fprintf(stderr, "Unable to resolve local address\n"); + ERR_print_errors_fp(stderr); + goto err; + } + addr = BIO_ADDRINFO_address(res); + + *server_fd = BIO_socket(BIO_ADDRINFO_family(res), SOCK_DGRAM, 0, 0); + if (*server_fd == INVALID_SOCKET) { + fprintf(stderr, "Unable to create UDP socket\n"); + ERR_print_errors_fp(stderr); + goto err; + } + + /* + * BIO_listen binds the socket. Pass BIO_SOCK_NONBLOCK so the listener is + * non-blocking. Omitting BIO_SOCK_V6_ONLY clears IPV6_V6ONLY, giving a + * dual-stack socket that serves both IPv6 and IPv4 clients. + */ + if (!BIO_listen((int)*server_fd, addr, + BIO_SOCK_REUSEADDR | BIO_SOCK_NONBLOCK)) { + fprintf(stderr, "Unable to bind socket\n"); + ERR_print_errors_fp(stderr); + goto err; + } + + printf("Server bound to port %d\n", port); + + /* Create a datagram BIO and attach the socket */ + listener_bio = BIO_new_dgram((int)*server_fd, BIO_NOCLOSE); + if (listener_bio == NULL) { + fprintf(stderr, "Unable to create datagram BIO\n"); + ERR_print_errors_fp(stderr); + goto err; + } + + /* + * Create the DTLS listener. By default it will perform HelloVerifyRequest + * (HVR) and HelloRetryRequest (HRR). + */ + *listener = SSL_new_listener(ssl_ctx, 0); + if (*listener == NULL) { + fprintf(stderr, "Unable to create DTLS listener\n"); + ERR_print_errors_fp(stderr); + goto err; + } + + /* + * Attach the BIO to the listener for both read and write. Because rbio and + * wbio are the same BIO, each set0 call takes one reference, so bump the + * reference count once beforehand. + */ + if (!BIO_up_ref(listener_bio)) { + fprintf(stderr, "Unable to increment BIO reference count\n"); + ERR_print_errors_fp(stderr); + goto err; + } + SSL_set0_rbio(*listener, listener_bio); + SSL_set0_wbio(*listener, listener_bio); + listener_bio = NULL; /* Both references transferred to listener */ + + /* + * A DTLS listener is blocking by default, and the connections it returns + * inherit that mode. This demo drives the listener and its connections with + * SSL_poll() and passes SSL_ACCEPT_CONNECTION_NO_BLOCK to + * SSL_accept_connection(), so put the listener into non-blocking mode. The + * accepted connections then inherit non-blocking mode as well. + */ + if (SSL_set_blocking_mode(*listener, 0) != 1) { + fprintf(stderr, "Unable to set listener to non-blocking mode\n"); + ERR_print_errors_fp(stderr); + goto err; + } + + /* Start listening for incoming connections */ + if (SSL_listen(*listener) != 1) { + fprintf(stderr, "SSL_listen failed\n"); + ERR_print_errors_fp(stderr); + goto err; + } + + ret = 1; + +err: + BIO_free(listener_bio); + BIO_ADDRINFO_free(res); + if (ret == 0) { + SSL_free(*listener); + *listener = NULL; + if (*server_fd != INVALID_SOCKET) + BIO_closesocket((int)*server_fd); + *server_fd = INVALID_SOCKET; + } + return ret; +} + +/* + * Thread worker: handles a single DTLS connection. Completes the handshake, + * then reads data and echoes it back until the peer disconnects, a shutdown is + * requested, or the client goes idle. + */ +static void handle_connection(struct connection_thread_args *conn_args) +{ + SSL_POLL_ITEM item; + struct timeval timeout; + size_t result_count, readbytes, written; + char buf[1500]; + int ret, err; + int shutdown_requested = 0; + time_t idle_deadline; + + printf("Thread %d: Starting connection handler\n", conn_args->thread_idx); + + /* Complete the handshake */ + while ((ret = SSL_accept(conn_args->conn)) != 1) { + CRYPTO_atomic_load_int(&conn_args->shutdown_requested, + &shutdown_requested, atomic_lock); + if (shutdown_requested) { + printf("Thread %d: Shutdown requested during handshake\n", conn_args->thread_idx); + goto done; + } + err = SSL_get_error(conn_args->conn, ret); + if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { + printf("Thread %d: Handshake failed\n", conn_args->thread_idx); + ERR_print_errors_fp(stderr); + goto done; + } + + /* + * Wait for the socket to become ready rather than busy-looping. Size + * the wait to the DTLS retransmit timer so we wake when a flight is + * due for retransmission; fall back to a fixed interval if no timer is + * armed. + */ + item.desc = SSL_as_poll_descriptor(conn_args->conn); + item.events = (err == SSL_ERROR_WANT_READ) ? SSL_POLL_EVENT_R + : SSL_POLL_EVENT_W; + item.revents = 0; + if (!DTLSv1_get_timeout(conn_args->conn, &timeout)) { + timeout.tv_sec = POLL_TIMEOUT_SEC; + timeout.tv_usec = 0; + } + if (!SSL_poll(&item, 1, sizeof(item), &timeout, 0, &result_count)) { + printf("Thread %d: SSL_poll failed during handshake\n", conn_args->thread_idx); + ERR_print_errors_fp(stderr); + goto done; + } + /* + * No inbound datagram before the timer expired: loop back into + * SSL_accept() so the library retransmits the last flight. A dead peer + * eventually exhausts the DTLS retransmit budget, which surfaces as a + * fatal error from SSL_accept() above and ends the loop. + */ + if (result_count == 0) + continue; + } + + printf("Thread %d: Handshake completed\n", conn_args->thread_idx); + + /* Setup poll item for reading */ + item.desc = SSL_as_poll_descriptor(conn_args->conn); + item.events = SSL_POLL_EVENT_R; + + idle_deadline = time(NULL) + CLIENT_IDLE_TIMEOUT_SEC; + + /* Main read/echo loop */ + while (!shutdown_requested) { + item.revents = 0; + timeout.tv_sec = POLL_TIMEOUT_SEC; + timeout.tv_usec = 0; + + if (!SSL_poll(&item, 1, sizeof(item), &timeout, 0, &result_count)) { + printf("Thread %d: SSL_poll failed\n", conn_args->thread_idx); + ERR_print_errors_fp(stderr); + break; + } + + /* Check shutdown after poll returns */ + CRYPTO_atomic_load_int(&conn_args->shutdown_requested, + &shutdown_requested, atomic_lock); + if (shutdown_requested) { + printf("Thread %d: Shutdown requested\n", conn_args->thread_idx); + break; + } + + /* No data this round; abandon if the client has been idle too long. */ + if (result_count == 0 || (item.revents & SSL_POLL_EVENT_R) == 0) { + if (time(NULL) >= idle_deadline) { + printf("Thread %d: Client idle timeout, abandoning\n", conn_args->thread_idx); + break; + } + continue; + } + + ret = SSL_read_ex(conn_args->conn, buf, sizeof(buf) - 1, &readbytes); + if (ret != 1) { + err = SSL_get_error(conn_args->conn, ret); + if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) + continue; + if (err == SSL_ERROR_ZERO_RETURN) + printf("Thread %d: Client closed connection\n", conn_args->thread_idx); + else + printf("Thread %d: Read error\n", conn_args->thread_idx); + break; + } + + buf[readbytes] = '\0'; + + /* Received data: the client is alive, so push out the idle deadline. */ + idle_deadline = time(NULL) + CLIENT_IDLE_TIMEOUT_SEC; + + /* Check for kill command - exits this thread only */ + if (strcmp(buf, "kill\n") == 0 || strcmp(buf, "kill\r\n") == 0) { + printf("Thread %d: Kill command received, disconnecting\n", conn_args->thread_idx); + break; + } + + /* Check for killall command - signals server-wide shutdown */ + if (strcmp(buf, "killall\n") == 0 || strcmp(buf, "killall\r\n") == 0) { + printf("Thread %d: Killall command received, initiating server shutdown\n", conn_args->thread_idx); + if (conn_args->server_shutdown != NULL) + CRYPTO_atomic_store_int(conn_args->server_shutdown, 1, + atomic_lock); + break; + } + + printf("Thread %d: Received: %s", conn_args->thread_idx, buf); + + /* Echo back */ + while (!SSL_write_ex(conn_args->conn, buf, readbytes, &written)) { + err = SSL_get_error(conn_args->conn, 0); + if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { + printf("Thread %d: Write failed\n", conn_args->thread_idx); + ERR_print_errors_fp(stderr); + goto done; + } + } + } + +done: + /* Send graceful shutdown to client */ + printf("Thread %d: Sending shutdown to client\n", conn_args->thread_idx); + SSL_shutdown(conn_args->conn); + + printf("Thread %d: Exiting\n", conn_args->thread_idx); + CRYPTO_atomic_store_int(&conn_args->finished, 1, atomic_lock); +} + +/* + * Platform thread glue. handle_connection() does the real work; these wrappers + * adapt it to the native thread entry-point signature and start/join threads. + */ +#if defined(OPENSSL_SYS_WINDOWS) + +static DWORD WINAPI thread_run(LPVOID arg) +{ + handle_connection(arg); + OPENSSL_thread_stop(); + return 0; +} + +static int run_thread(thread_t *t, void *arg) +{ + *t = CreateThread(NULL, 0, thread_run, arg, 0, NULL); + return *t != NULL; +} + +static int wait_for_thread(thread_t thread) +{ + int ok = WaitForSingleObject(thread, INFINITE) == 0; + + /* Release the handle so a long-running server does not leak them. */ + CloseHandle(thread); + return ok; +} + +#else + +static void *thread_run(void *arg) +{ + handle_connection(arg); + OPENSSL_thread_stop(); + return NULL; +} + +static int run_thread(thread_t *t, void *arg) +{ + return pthread_create(t, NULL, thread_run, arg) == 0; +} + +static int wait_for_thread(thread_t thread) +{ + return pthread_join(thread, NULL) == 0; +} + +#endif + +/* + * Find a free slot in the thread array. + * Returns the index of a free slot, or -1 if all slots are in use. + */ +static int find_free_thread_slot(struct connection_thread_args *threads) +{ + int i; + + for (i = 0; i < MAX_CONNECTIONS; i++) { + if (!threads[i].active) + return i; + } + return -1; +} + +/* + * Clean up finished threads. + * Called from main thread after each poll to reclaim resources from + * threads that have set their finished flag. + */ +static void cleanup_finished_threads(struct connection_thread_args *threads) +{ + int i; + + for (i = 0; i < MAX_CONNECTIONS; i++) { + int finished = 0; + + if (threads[i].active) + CRYPTO_atomic_load_int(&threads[i].finished, &finished, atomic_lock); + if (threads[i].active && finished) { + wait_for_thread(threads[i].thread); + SSL_free(threads[i].conn); + threads[i].active = 0; + threads[i].conn = NULL; + threads[i].finished = 0; + printf("Main: Cleaned up thread %d\n", i); + } + } +} + +/* + * Signal all threads to shut down and wait for them to finish. + * Called when the server is exiting. + */ +static void shutdown_all_threads(struct connection_thread_args *threads) +{ + int i; + + /* Signal all threads to terminate */ + for (i = 0; i < MAX_CONNECTIONS; i++) { + if (threads[i].active) + CRYPTO_atomic_store_int(&threads[i].shutdown_requested, 1, + atomic_lock); + } + + /* Join and clean up all threads */ + for (i = 0; i < MAX_CONNECTIONS; i++) { + if (threads[i].active) { + wait_for_thread(threads[i].thread); + SSL_free(threads[i].conn); + threads[i].active = 0; + threads[i].conn = NULL; + printf("Main: Shut down thread %d\n", i); + } + } +} + +static void run_server(void) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *listener = NULL; + SSL *new_conn = NULL; + SOCKET server_fd = INVALID_SOCKET; + int server_shutdown = 0; + int shutdown_seen = 0; + struct connection_thread_args conn_threads[MAX_CONNECTIONS]; + SSL_POLL_ITEM listener_item; + struct timeval timeout; + size_t result_count; + int slot; + + /* Initialize thread array */ + memset(conn_threads, 0, sizeof(conn_threads)); + + atomic_lock = CRYPTO_THREAD_lock_new(); + if (atomic_lock == NULL) { + fprintf(stderr, "Unable to create lock\n"); + goto err; + } + + ssl_ctx = create_context(true); + + /* Set the key and cert */ + if (SSL_CTX_use_certificate_chain_file(ssl_ctx, "cert.pem") <= 0) { + ERR_print_errors_fp(stderr); + goto err; + } + + if (SSL_CTX_use_PrivateKey_file(ssl_ctx, "key.pem", SSL_FILETYPE_PEM) <= 0) { + ERR_print_errors_fp(stderr); + goto err; + } + + /* Create the DTLS listener with socket and BIO */ + if (!create_dtls_listener(ssl_ctx, server_port, &listener, &server_fd)) { + goto err; + } + + printf("DTLS listener started on port %d (max %d connections)\n", + server_port, MAX_CONNECTIONS); + + /* Setup poll item for listener */ + listener_item.desc = SSL_as_poll_descriptor(listener); + listener_item.events = SSL_POLL_EVENT_IC; + + while (!shutdown_seen) { + /* Clean up any finished threads first */ + cleanup_finished_threads(conn_threads); + + /* Poll listener for incoming connections */ + listener_item.revents = 0; + timeout.tv_sec = POLL_TIMEOUT_SEC; + timeout.tv_usec = 0; + + if (!SSL_poll(&listener_item, 1, sizeof(listener_item), + &timeout, 0, &result_count)) { + ERR_print_errors_fp(stderr); + break; + } + + /* Check if shutdown was requested by a connection thread */ + CRYPTO_atomic_load_int(&server_shutdown, &shutdown_seen, atomic_lock); + if (shutdown_seen) { + printf("Main: Server shutdown requested\n"); + break; + } + + /* Timeout - no incoming connection, loop again */ + if (result_count == 0 || (listener_item.revents & SSL_POLL_EVENT_IC) == 0) + continue; + + /* Accept new connection */ + new_conn = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + if (new_conn == NULL) { + fprintf(stderr, "SSL_accept_connection failed\n"); + ERR_print_errors_fp(stderr); + continue; + } + + /* Bound the handshake retransmit backoff (see dtls_timer_cb). */ + DTLS_set_timer_cb(new_conn, dtls_timer_cb); + + /* Find free slot */ + slot = find_free_thread_slot(conn_threads); + if (slot < 0) { + fprintf(stderr, "Connection limit reached (%d), dropping new connection\n", + MAX_CONNECTIONS); + SSL_free(new_conn); + continue; + } + + /* Initialize thread args and spawn thread */ + conn_threads[slot].conn = new_conn; + conn_threads[slot].thread_idx = slot; + conn_threads[slot].shutdown_requested = 0; + conn_threads[slot].finished = 0; + conn_threads[slot].server_shutdown = &server_shutdown; + + conn_threads[slot].active = 1; + if (!run_thread(&conn_threads[slot].thread, &conn_threads[slot])) { + fprintf(stderr, "Failed to start thread for slot %d\n", slot); + SSL_free(new_conn); + conn_threads[slot].conn = NULL; + conn_threads[slot].active = 0; + continue; + } + + printf("Main: Spawned thread %d for new connection\n", slot); + } + + printf("Server exiting...\n"); + +err: + /* Signal all threads to shut down and clean up */ + shutdown_all_threads(conn_threads); + + CRYPTO_THREAD_lock_free(atomic_lock); + SSL_free(listener); + SSL_CTX_free(ssl_ctx); + if (server_fd != INVALID_SOCKET) + BIO_closesocket((int)server_fd); +} + +/* + * Create a DTLS client connection to the server. + */ +static int create_dtls_client(SSL_CTX *ssl_ctx, const char *server_name, int port, + SSL **client, SOCKET *client_fd) +{ + BIO *client_bio = NULL; + BIO_ADDRINFO *res = NULL; + const BIO_ADDRINFO *ai; + char port_str[6]; + int ret = 0; + + *client = NULL; + *client_fd = INVALID_SOCKET; + + /* + * Resolve the server address (IPv4 or IPv6) and connect a UDP socket of the + * matching family to the first address that works. For UDP, BIO_connect + * just records the default peer. + */ + snprintf(port_str, sizeof(port_str), "%d", port); + if (!BIO_lookup(server_name, port_str, BIO_LOOKUP_CLIENT, AF_UNSPEC, + SOCK_DGRAM, &res)) { + fprintf(stderr, "Unable to resolve server: %s\n", server_name); + ERR_print_errors_fp(stderr); + goto err; + } + + for (ai = res; ai != NULL; ai = BIO_ADDRINFO_next(ai)) { + *client_fd = BIO_socket(BIO_ADDRINFO_family(ai), SOCK_DGRAM, 0, 0); + if (*client_fd == INVALID_SOCKET) + continue; + if (BIO_connect((int)*client_fd, BIO_ADDRINFO_address(ai), 0)) + break; + BIO_closesocket((int)*client_fd); + *client_fd = INVALID_SOCKET; + } + BIO_ADDRINFO_free(res); + res = NULL; + if (*client_fd == INVALID_SOCKET) { + fprintf(stderr, "Unable to UDP connect to server: %s\n", server_name); + ERR_print_errors_fp(stderr); + goto err; + } + + /* Set socket to non-blocking mode */ + if (!BIO_socket_nbio((int)*client_fd, 1)) { + fprintf(stderr, "Unable to set socket to non-blocking\n"); + ERR_print_errors_fp(stderr); + goto err; + } + + /* + * Create the datagram BIO. Because the socket is already connected, the BIO + * auto-detects the peer (via getpeername), so no BIO_dgram_set_peer call is + * needed. + */ + client_bio = BIO_new_dgram((int)*client_fd, BIO_NOCLOSE); + if (client_bio == NULL) { + fprintf(stderr, "Unable to create datagram BIO\n"); + ERR_print_errors_fp(stderr); + goto err; + } + + /* Create the SSL client */ + *client = SSL_new(ssl_ctx); + if (*client == NULL) { + fprintf(stderr, "Unable to create SSL client\n"); + ERR_print_errors_fp(stderr); + goto err; + } + + /* Bound the handshake retransmit backoff (see dtls_timer_cb). */ + DTLS_set_timer_cb(*client, dtls_timer_cb); + + /* + * Attach the BIO to the SSL for both read and write. Because rbio and wbio + * are the same BIO, each set0 call takes one reference, so bump the + * reference count once beforehand. + */ + if (!BIO_up_ref(client_bio)) { + fprintf(stderr, "Unable to increment BIO reference count\n"); + ERR_print_errors_fp(stderr); + goto err; + } + SSL_set0_rbio(*client, client_bio); + SSL_set0_wbio(*client, client_bio); + client_bio = NULL; /* Both references transferred to the SSL */ + + if (!SSL_set1_dnsname(*client, server_name)) { + ERR_print_errors_fp(stderr); + goto err; + } + + ret = 1; + +err: + BIO_free(client_bio); + BIO_ADDRINFO_free(res); + if (ret == 0) { + SSL_free(*client); + *client = NULL; + if (*client_fd != INVALID_SOCKET) + BIO_closesocket((int)*client_fd); + *client_fd = INVALID_SOCKET; + } + return ret; +} + +/* + * Perform the DTLS handshake with the server. + * Uses SSL_poll to wait for the connection to be ready. + */ +static int do_client_handshake(SSL *client) +{ + SSL_POLL_ITEM item; + struct timeval timeout; + size_t result_count; + int ret, err; + + while ((ret = SSL_connect(client)) != 1) { + err = SSL_get_error(client, ret); + if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { + fprintf(stderr, "Handshake failed with err=%d\n", err); + ERR_print_errors_fp(stderr); + return 0; + } + + /* + * Poll for the socket to be ready. Size the wait to the DTLS + * retransmit timer so we wake when a flight is due for retransmission; + * fall back to a fixed interval if no timer is armed. + */ + item.desc = SSL_as_poll_descriptor(client); + item.events = (err == SSL_ERROR_WANT_READ) ? SSL_POLL_EVENT_R : SSL_POLL_EVENT_W; + item.revents = 0; + + if (!DTLSv1_get_timeout(client, &timeout)) { + timeout.tv_sec = POLL_TIMEOUT_SEC; + timeout.tv_usec = 0; + } + + if (!SSL_poll(&item, 1, sizeof(item), &timeout, 0, &result_count)) { + fprintf(stderr, "SSL_poll failed during handshake\n"); + ERR_print_errors_fp(stderr); + return 0; + } + + /* + * No inbound datagram before the timer expired: loop back into + * SSL_connect() so the library retransmits the last flight. A dead + * peer eventually exhausts the DTLS retransmit budget, which surfaces + * as a fatal error from SSL_connect() above and ends the loop. + */ + if (result_count == 0) + continue; + } + + return 1; +} + +/* + * Send one line of user input to the server. Returns 1 to keep the client loop + * running, or 0 when the client should stop. + */ +static int process_line(SSL *client, const char *line, size_t len) +{ + size_t written; + + if (!SSL_write_ex(client, line, len, &written)) { + fprintf(stderr, "Failed to send data\n"); + ERR_print_errors_fp(stderr); + return 0; + } + + if ((len == sizeof("kill\n") - 1 && memcmp(line, "kill\n", len) == 0) + || (len == sizeof("kill\r\n") - 1 && memcmp(line, "kill\r\n", len) == 0)) { + printf("Sent kill command, disconnecting\n"); + return 0; + } + + if ((len == sizeof("killall\n") - 1 && memcmp(line, "killall\n", len) == 0) + || (len == sizeof("killall\r\n") - 1 + && memcmp(line, "killall\r\n", len) == 0)) { + printf("Sent killall command, server will shutdown\n"); + return 0; + } + + return 1; +} + +static void run_client(char *rem_server_name, int dtls_version) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *client = NULL; + SOCKET client_fd = INVALID_SOCKET; + char input_buf[1500]; + char recv_buf[1500]; + size_t readbytes; + int ret, err; + int has_server_data = 0; + int has_user_input = 0; +#if !defined(OPENSSL_SYS_WINDOWS) + struct pollfd pfds[2]; + BIO *rbio; + BIO_POLL_DESCRIPTOR rdesc; + int ssl_fd; + size_t input_used = 0; + ssize_t n; + char *nl; +#else + fd_set read_fds; + struct timeval timeout; +#endif + + ssl_ctx = create_context(false); + + /* Apply DTLS version constraint if specified */ + if (dtls_version != 0) { + if (!SSL_CTX_set_min_proto_version(ssl_ctx, dtls_version) + || !SSL_CTX_set_max_proto_version(ssl_ctx, dtls_version)) { + ERR_print_errors_fp(stderr); + goto err; + } + printf("Forcing %s\n", + dtls_version == DTLS1_2_VERSION ? "DTLS 1.2" : "DTLS 1.3"); + } + + /* Abort the handshake if the server certificate cannot be verified. */ + SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); + + /* + * This is an atypical use case for real applications, which normally load a + * directory of trusted roots. Here we trust the server's certificate directly. + */ + if (!SSL_CTX_load_verify_locations(ssl_ctx, "cert.pem", NULL)) { + ERR_print_errors_fp(stderr); + goto err; + } + + /* Create DTLS client connection */ + if (!create_dtls_client(ssl_ctx, rem_server_name, server_port, &client, &client_fd)) { + goto err; + } + + printf("Connecting to %s:%d...\n", rem_server_name, server_port); + + /* Perform handshake */ + if (!do_client_handshake(client)) { + goto err; + } + + printf("Connected! Type messages to send (or 'kill' to disconnect, 'killall' to shutdown server):\n"); + +#if !defined(OPENSSL_SYS_WINDOWS) + /* Get the SSL socket fd for polling */ + rbio = SSL_get_rbio(client); + if (rbio == NULL || !BIO_get_rpoll_descriptor(rbio, &rdesc) + || rdesc.type != BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) { + fprintf(stderr, "Failed to get SSL socket fd\n"); + goto err; + } + ssl_fd = rdesc.value.fd; + + /* Setup poll fds: [0] = stdin, [1] = SSL socket */ + pfds[0].fd = STDIN_FILENO; + pfds[0].events = POLLIN; + pfds[1].fd = ssl_fd; + pfds[1].events = POLLIN; +#else + /* + * Make stdin unbuffered so fgets() reads only up to the newline and does + * not pull following lines out of the console into the stdio buffer, where + * _kbhit() cannot see them. Any remaining lines then stay in the console + * buffer and are processed on subsequent loop iterations. + */ + setvbuf(stdin, NULL, _IONBF, 0); +#endif + + /* Main loop: poll on both stdin and SSL connection */ + while (1) { + has_server_data = 0; + has_user_input = 0; + +#if !defined(OPENSSL_SYS_WINDOWS) + pfds[0].revents = 0; + pfds[1].revents = 0; + + ret = poll(pfds, 2, POLL_TIMEOUT_SEC * 1000); + if (ret < 0) { + perror("poll failed"); + break; + } + + has_server_data = (pfds[1].revents & POLLIN) != 0; + has_user_input = (pfds[0].revents & POLLIN) != 0; +#else + /* + * Windows: use select() for socket and _kbhit() for console input. + * We can't easily poll stdin and a socket together on Windows, so we + * use a short timeout on select() and check for keyboard input. + */ + FD_ZERO(&read_fds); + FD_SET(client_fd, &read_fds); + timeout.tv_sec = 0; + timeout.tv_usec = 100000; /* 100ms */ + + ret = select(0, &read_fds, NULL, NULL, &timeout); + if (ret < 0) { + fprintf(stderr, "select failed\n"); + break; + } + + has_server_data = (ret > 0 && FD_ISSET(client_fd, &read_fds)); + has_user_input = _kbhit(); +#endif + + /* Check for server data/shutdown first */ + if (has_server_data) { + ret = SSL_read_ex(client, recv_buf, sizeof(recv_buf) - 1, &readbytes); + if (ret != 1) { + err = SSL_get_error(client, ret); + if (err == SSL_ERROR_ZERO_RETURN) { + printf("Server closed connection\n"); + break; + } else if (err == SSL_ERROR_WANT_READ + || err == SSL_ERROR_WANT_WRITE) { + /* + * No progress possible yet. SSL_read_ex() can ask to write + * (e.g. a DTLS retransmission or post-handshake message) + * when the socket is momentarily unwritable. Either way, + * go back to polling and retry. + */ + continue; + } else { + fprintf(stderr, "Read error from server\n"); + ERR_print_errors_fp(stderr); + break; + } + } + recv_buf[readbytes] = '\0'; + printf("Server: %s", recv_buf); + } + + /* Check for user input */ + if (has_user_input) { +#if !defined(OPENSSL_SYS_WINDOWS) + n = read(STDIN_FILENO, input_buf + input_used, + sizeof(input_buf) - input_used); + if (n <= 0) { + if (n == 0) + printf("EOF received, exiting\n"); + else + perror("Failed to read from stdin"); + break; + } + input_used += (size_t)n; + + while ((nl = memchr(input_buf, '\n', input_used)) != NULL) { + size_t linelen = (size_t)(nl - input_buf) + 1; + int keep_going = process_line(client, input_buf, linelen); + + memmove(input_buf, input_buf + linelen, input_used - linelen); + input_used -= linelen; + if (!keep_going) + goto err; + } + + /* A single line that fills the buffer without a newline */ + if (input_used == sizeof(input_buf)) { + if (!process_line(client, input_buf, input_used)) + goto err; + input_used = 0; + } +#else + if (fgets(input_buf, sizeof(input_buf), stdin) == NULL) { + printf("EOF received, exiting\n"); + break; + } + if (!process_line(client, input_buf, strlen(input_buf))) + break; +#endif + } + } + +err: + /* Send a graceful shutdown (close_notify) to the server before freeing. */ + if (client != NULL) + SSL_shutdown(client); + SSL_free(client); + SSL_CTX_free(ssl_ctx); + if (client_fd != INVALID_SOCKET) + BIO_closesocket((int)client_fd); +} + +static void usage(void) +{ + printf("Usage: dtlslistenerecho s\n"); + printf(" --or--\n"); + printf(" dtlslistenerecho c hostname [dtls12|dtls13]\n"); + printf(" c=client, s=server, hostname=hostname of server\n"); + printf(" dtls12=force DTLS 1.2, dtls13=force DTLS 1.3 (optional)\n"); + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) +{ + bool isServer; + char *rem_server_name = NULL; + int dtls_version = 0; + + /* Need to know if client or server */ + if (argc < 2) { + usage(); + /* NOTREACHED */ + } + + isServer = (argv[1][0] == 's') ? true : false; + + /* If client get remote server address */ + if (!isServer) { + if (argc < 3) { + usage(); + /* NOTREACHED */ + } + rem_server_name = argv[2]; + + /* Check for optional DTLS version argument */ + if (argc >= 4) { + if (strcmp(argv[3], "dtls12") == 0) { + dtls_version = DTLS1_2_VERSION; + } else if (strcmp(argv[3], "dtls13") == 0) { + dtls_version = DTLS1_3_VERSION; + } else { + fprintf(stderr, "Unknown protocol version: %s\n", argv[3]); + usage(); + /* NOTREACHED */ + } + } + } + + if (isServer) { + run_server(); + } else { + run_client(rem_server_name, dtls_version); + } + + return EXIT_SUCCESS; +} diff --git a/demos/encrypt/rsa_encrypt.h b/demos/encrypt/rsa_encrypt.h index 9cd98e3866751..72854950d0458 100644 --- a/demos/encrypt/rsa_encrypt.h +++ b/demos/encrypt/rsa_encrypt.h @@ -1,5 +1,5 @@ /*- - * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/demos/guide/build.info b/demos/guide/build.info index de184ff0d1aa1..7b5b54f073117 100644 --- a/demos/guide/build.info +++ b/demos/guide/build.info @@ -5,6 +5,7 @@ # LD_LIBRARY_PATH=../.. ./tls-client-block www.example.com 443 PROGRAMS{noinst} = tls-client-block \ + tls-server-block \ quic-client-block \ quic-multi-stream \ tls-client-non-block \ @@ -17,6 +18,10 @@ INCLUDE[tls-client-block]=../../include SOURCE[tls-client-block]=tls-client-block.c DEPEND[tls-client-block]=../../libcrypto ../../libssl +INCLUDE[tls-server-block]=../../include +SOURCE[tls-server-block]=tls-server-block.c +DEPEND[tls-server-block]=../../libcrypto ../../libssl + INCLUDE[quic-client-block]=../../include SOURCE[quic-client-block]=quic-client-block.c DEPEND[quic-client-block]=../../libcrypto ../../libssl diff --git a/demos/guide/quic-server-block.c b/demos/guide/quic-server-block.c index 434516679b38e..e05b855484d21 100644 --- a/demos/guide/quic-server-block.c +++ b/demos/guide/quic-server-block.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/demos/guide/quic-server-non-block.c b/demos/guide/quic-server-non-block.c index eb954f9f79f12..b122244ce7560 100644 --- a/demos/guide/quic-server-non-block.c +++ b/demos/guide/quic-server-non-block.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/demos/guide/tls-server-block.c b/demos/guide/tls-server-block.c index 2bee2219ed8c6..3e72d66c398ef 100644 --- a/demos/guide/tls-server-block.c +++ b/demos/guide/tls-server-block.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -64,6 +64,7 @@ int main(int argc, char *argv[]) { int res = EXIT_FAILURE; long opts; + long old_timeout; const char *hostport; SSL_CTX *ctx = NULL; BIO *acceptor_bio; @@ -174,7 +175,11 @@ int main(int argc, char *argv[]) * byte array, that identifies the server application, and reduces the * chance of inappropriate cache sharing. */ - SSL_CTX_set_session_id_context(ctx, (void *)cache_id, sizeof(cache_id)); + if (SSL_CTX_set_session_id_context(ctx, (void *)cache_id, sizeof(cache_id)) <= 0) { + SSL_CTX_free(ctx); + ERR_print_errors_fp(stderr); + errx(res, "Failed to set server session ID context"); + } SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER); /* @@ -191,7 +196,9 @@ int main(int argc, char *argv[]) * loaded servers with sporadic connections from any given client, a longer * time may be appropriate. */ - SSL_CTX_set_timeout(ctx, 3600); + old_timeout = SSL_CTX_set_timeout(ctx, 3600); + if (old_timeout != 3600) + warnx("Changing session timeout from %ld to 3600", old_timeout); /* * Clients rarely employ certificate-based authentication, and so we don't diff --git a/demos/http3/ossl-nghttp3-demo-server.c b/demos/http3/ossl-nghttp3-demo-server.c index 227ac6e26487c..7fcbed854daa1 100644 --- a/demos/http3/ossl-nghttp3-demo-server.c +++ b/demos/http3/ossl-nghttp3-demo-server.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/demos/mac/cmac-aes256.c b/demos/mac/cmac-aes256.c index 778ac108626cb..c843b732552bb 100644 --- a/demos/mac/cmac-aes256.c +++ b/demos/mac/cmac-aes256.c @@ -1,5 +1,5 @@ /*- - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/demos/mac/hmac-sha512.c b/demos/mac/hmac-sha512.c index e9a4fbaf23516..27847def3e913 100644 --- a/demos/mac/hmac-sha512.c +++ b/demos/mac/hmac-sha512.c @@ -1,5 +1,5 @@ /*- - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/demos/pkcs12/build.info b/demos/pkcs12/build.info new file mode 100644 index 0000000000000..6fd35d1822e6e --- /dev/null +++ b/demos/pkcs12/build.info @@ -0,0 +1,16 @@ +# +# To run the demos when linked with a shared library (default) ensure that +# libcrypto is on the library path. For example: +# +# LD_LIBRARY_PATH=../.. ./pkread + +PROGRAMS{noinst} = pkread \ + pkwrite + +INCLUDE[pkread]=../../include +SOURCE[pkread]=pkread.c +DEPEND[pkread]=../../libcrypto + +INCLUDE[pkwrite]=../../include +SOURCE[pkwrite]=pkwrite.c +DEPEND[pkwrite]=../../libcrypto diff --git a/demos/pkcs12/pkwrite.c b/demos/pkcs12/pkwrite.c index 7bb73f35a41ea..5995cfd274484 100644 --- a/demos/pkcs12/pkwrite.c +++ b/demos/pkcs12/pkwrite.c @@ -1,5 +1,5 @@ /* - * Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -25,8 +25,6 @@ int main(int argc, char **argv) fprintf(stderr, "Usage: pkwrite infile password name p12file\n"); exit(EXIT_FAILURE); } - OpenSSL_add_all_algorithms(); - ERR_load_crypto_strings(); if ((fp = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "Error opening file %s\n", argv[1]); exit(EXIT_FAILURE); diff --git a/demos/pkey/EVP_PKEY_RSA_keygen.c b/demos/pkey/EVP_PKEY_RSA_keygen.c index a889ab6f77d4b..b998b2c5d7ff1 100644 --- a/demos/pkey/EVP_PKEY_RSA_keygen.c +++ b/demos/pkey/EVP_PKEY_RSA_keygen.c @@ -1,5 +1,5 @@ /*- - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,8 +17,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -253,7 +255,13 @@ int main(int argc, char **argv) } if (argc > 1) { - bits_i = atoi(argv[1]); + unsigned long ul; + + if (!OPENSSL_strtoul(argv[1], NULL, 10, &ul) || ul > INT_MAX) { + fprintf(stderr, "Invalid RSA key size\n"); + return EXIT_FAILURE; + } + bits_i = (int)ul; if (bits_i < 512) { fprintf(stderr, "Invalid RSA key size\n"); return EXIT_FAILURE; diff --git a/demos/quic/poll-server/quic-server-ssl-poll-http.c b/demos/quic/poll-server/quic-server-ssl-poll-http.c index c76dc609a2348..043d9da012be8 100644 --- a/demos/quic/poll-server/quic-server-ssl-poll-http.c +++ b/demos/quic/poll-server/quic-server-ssl-poll-http.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -1018,8 +1018,7 @@ rebuild_poll_set(struct poll_manager *pm) i = 0; DPRINTF(stderr, "%s there %zu events to poll\n", __func__, ossl_list_pe_num(&pm->pm_head)); - OSSL_LIST_FOREACH(pe, pe, &pm->pm_head) - { + OSSL_LIST_FOREACH (pe, pe, &pm->pm_head) { pe->pe_poll_item.events = pe->pe_want_events; pm->pm_poll_set[i++] = *pe; DPRINTF(stderr, "\t%p (%s) " POLL_FMT " (disabled: " POLL_FMT ")\n", @@ -1041,8 +1040,8 @@ destroy_poll_manager(struct poll_manager *pm) if (pm == NULL) return; - OSSL_LIST_FOREACH_DELSAFE(pe, pe_safe, pe, &pm->pm_head) - destroy_pe(pe); + OSSL_LIST_FOREACH_DELSAFE (pe, pe_safe, pe, &pm->pm_head) + destroy_pe(pe); OPENSSL_free(pm->pm_poll_set); OPENSSL_free(pm); @@ -1625,14 +1624,12 @@ app_destroy_qconn(struct poll_event *pe) if (pec == NULL) return; - OSSL_LIST_FOREACH_DELSAFE(peccx, peccx_save, peccx, &pec->pec_unistream_cx) - { + OSSL_LIST_FOREACH_DELSAFE (peccx, peccx_save, peccx, &pec->pec_unistream_cx) { peccx->peccx_cb_ondestroy(peccx->peccx); OPENSSL_free(peccx); } - OSSL_LIST_FOREACH_DELSAFE(peccx, peccx_save, peccx, &pec->pec_stream_cx) - { + OSSL_LIST_FOREACH_DELSAFE (peccx, peccx_save, peccx, &pec->pec_stream_cx) { peccx->peccx_cb_ondestroy(peccx->peccx); OPENSSL_free(peccx); } diff --git a/demos/signature/EVP_DSA_Signature_demo.c b/demos/signature/EVP_DSA_Signature_demo.c index 088c568724b65..ad4466060910a 100644 --- a/demos/signature/EVP_DSA_Signature_demo.c +++ b/demos/signature/EVP_DSA_Signature_demo.c @@ -1,5 +1,5 @@ /*- - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/demos/signature/EVP_EC_Signature_demo.h b/demos/signature/EVP_EC_Signature_demo.h index c7527beebc40e..33e08b9507d56 100644 --- a/demos/signature/EVP_EC_Signature_demo.h +++ b/demos/signature/EVP_EC_Signature_demo.h @@ -1,5 +1,5 @@ /*- - * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/demos/sslecho/build.info b/demos/sslecho/build.info index d42716cd5103c..7784357ed6bb3 100644 --- a/demos/sslecho/build.info +++ b/demos/sslecho/build.info @@ -6,6 +6,15 @@ PROGRAMS{noinst} = sslecho + INCLUDE[sslecho]=../../include SOURCE[sslecho]=main.c DEPEND[sslecho]=../../libcrypto ../../libssl + +IF[{- !$disabled{"ech"} -}] + PROGRAMS{noinst} = echecho + + INCLUDE[echecho]=../../include + SOURCE[echecho]=echecho.c + DEPEND[echecho]=../../libcrypto ../../libssl +ENDIF diff --git a/demos/sslecho/echecho.c b/demos/sslecho/echecho.c index bcd097d3835c2..d9c757cba2510 100644 --- a/demos/sslecho/echecho.c +++ b/demos/sslecho/echecho.c @@ -7,27 +7,38 @@ * https://www.openssl.org/source/license.html */ +#include #include -#include #include -#include -#include #include #include -static const int server_port = 4433; +#if !defined(OPENSSL_SYS_WINDOWS) +#include +#include +#include -static const char echconfig[] = "AD7+DQA65wAgACA8wVN2BtscOl3vQheUzHeIkVmKIiydUhDCliA4iyQRCwAEAAEAAQALZXhhbXBsZS5jb20AAA=="; -static const char echprivbuf[] = "-----BEGIN PRIVATE KEY-----\n" - "MC4CAQAwBQYDK2VuBCIEICjd4yGRdsoP9gU7YT7My8DHx1Tjme8GYDXrOMCi8v1V\n" - "-----END PRIVATE KEY-----\n" - "-----BEGIN ECHCONFIG-----\n" - "AD7+DQA65wAgACA8wVN2BtscOl3vQheUzHeIkVmKIiydUhDCliA4iyQRCwAEAAEAAQALZXhhbXBsZS5jb20AAA==\n" - "-----END ECHCONFIG-----\n"; +#define SOCKET int +#define INVALID_SOCKET -1 +#define closesocket(s) close(s) +#else /* defined(OPENSSL_SYS_WINDOWS) */ +#include +#include +#endif /* !defined(OPENSSL_SYS_WINDOWS) */ -typedef unsigned char bool; -#define true 1 -#define false 0 +static const int server_port = 4433; + +static const char echconfig[] + = "AD7+DQA65wAgACA8wVN2BtscOl3vQheUzHeIkVmKIiydUhDCliA4iyQRCwAEAAEA" + "AQALZXhhbXBsZS5jb20AAA=="; +static const char echprivbuf[] + = "-----BEGIN PRIVATE KEY-----\n" + "MC4CAQAwBQYDK2VuBCIEICjd4yGRdsoP9gU7YT7My8DHx1Tjme8GYDXrOMCi8v1V\n" + "-----END PRIVATE KEY-----\n" + "-----BEGIN ECHCONFIG-----\n" + "AD7+DQA65wAgACA8wVN2BtscOl3vQheUzHeIkVmKIiydUhDCliA4iyQRCwAEAAEA" + "AQALZXhhbXBsZS5jb20AAA==\n" + "-----END ECHCONFIG-----\n"; /* * This flag won't be useful until both accept/read (TCP & SSL) methods @@ -35,14 +46,14 @@ typedef unsigned char bool; */ static volatile bool server_running = true; -int create_socket(bool isServer) +static SOCKET create_socket(bool isServer) { - int s; + SOCKET s; int optval = 1; struct sockaddr_in addr = { 0 }; s = socket(AF_INET, SOCK_STREAM, 0); - if (s < 0) { + if (s == INVALID_SOCKET) { perror("Unable to create socket"); exit(EXIT_FAILURE); } @@ -53,7 +64,7 @@ int create_socket(bool isServer) addr.sin_addr.s_addr = INADDR_ANY; /* Reuse the address; good for quick restarts */ - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *)&optval, sizeof(optval)) < 0) { perror("setsockopt(SO_REUSEADDR) failed"); exit(EXIT_FAILURE); @@ -73,7 +84,7 @@ int create_socket(bool isServer) return s; } -SSL_CTX *create_context(bool isServer) +static SSL_CTX *create_context(bool isServer) { const SSL_METHOD *method; SSL_CTX *ctx; @@ -97,7 +108,7 @@ static int configure_ech(SSL_CTX *ctx, int server, unsigned char *buf, size_t len) { OSSL_ECHSTORE *es = NULL; - BIO *es_in = BIO_new_mem_buf(buf, len); + BIO *es_in = BIO_new_mem_buf(buf, (int)len); if (es_in == NULL || (es = OSSL_ECHSTORE_new(NULL, NULL)) == NULL) goto err; @@ -115,7 +126,7 @@ static int configure_ech(SSL_CTX *ctx, int server, return 0; } -void configure_server_context(SSL_CTX *ctx) +static void configure_server_context(SSL_CTX *ctx) { /* Set the key and cert */ if (SSL_CTX_use_certificate_chain_file(ctx, "cert.pem") <= 0) { @@ -136,7 +147,7 @@ void configure_server_context(SSL_CTX *ctx) } } -void configure_client_context(SSL_CTX *ctx) +static void configure_client_context(SSL_CTX *ctx) { /* * Configure the client to abort the handshake if certificate verification @@ -144,9 +155,11 @@ void configure_client_context(SSL_CTX *ctx) */ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); /* - * In a real application you would probably just use the default system certificate trust store and call: + * In a real application you would probably just use the default system + * certificate trust store and call: * SSL_CTX_set_default_verify_paths(ctx); - * In this demo though we are using a self-signed certificate, so the client must trust it directly. + * In this demo though we are using a self-signed certificate, + * so the client must trust it directly. */ if (!SSL_CTX_load_verify_locations(ctx, "cert.pem", NULL)) { ERR_print_errors_fp(stderr); @@ -160,7 +173,7 @@ void configure_client_context(SSL_CTX *ctx) } } -void usage() +static void usage(void) { printf("Usage: echecho s\n"); printf(" --or--\n"); @@ -169,6 +182,7 @@ void usage() exit(1); } +#define BUFFERSIZE 1024 int main(int argc, char **argv) { bool isServer; @@ -177,13 +191,13 @@ int main(int argc, char **argv) SSL_CTX *ssl_ctx = NULL; SSL *ssl = NULL; - int server_skt = -1; - int client_skt = -1; + SOCKET server_skt = INVALID_SOCKET; + SOCKET client_skt = INVALID_SOCKET; - /* used by getline relying on realloc, can't be statically allocated */ + /* used by fgets */ + char buffer[BUFFERSIZE]; char *txbuf = NULL; size_t txcap = 0; - int txlen; char rxbuf[128]; size_t rxcap = sizeof(rxbuf); @@ -192,7 +206,7 @@ int main(int argc, char **argv) char *rem_server_ip = NULL; struct sockaddr_in addr = { 0 }; - unsigned int addr_len = sizeof(addr); + socklen_t addr_len = (socklen_t)sizeof(addr); char *outer_sni = NULL, *inner_sni = NULL; int ech_status; @@ -239,7 +253,7 @@ int main(int argc, char **argv) /* Wait for TCP connection from client */ client_skt = accept(server_skt, (struct sockaddr *)&addr, &addr_len); - if (client_skt < 0) { + if (client_skt == INVALID_SOCKET) { perror("Unable to accept"); exit(EXIT_FAILURE); } @@ -248,7 +262,11 @@ int main(int argc, char **argv) /* Create server SSL structure using newly accepted client socket */ ssl = SSL_new(ssl_ctx); - SSL_set_fd(ssl, client_skt); + if (SSL_set_fd(ssl, (int)client_skt) <= 0) { + puts("Unable to set fd for the SSL object"); + ERR_print_errors_fp(stderr); + exit(EXIT_FAILURE); + } /* Wait for SSL connection from the client */ if (SSL_accept(ssl) <= 0) { @@ -268,8 +286,11 @@ int main(int argc, char **argv) /* Echo loop */ while (true) { - /* Get message from client; will fail if client closes connection */ - if ((rxlen = SSL_read(ssl, rxbuf, rxcap)) <= 0) { + /* + * Get message from client; will fail if client closes + * connection + */ + if ((rxlen = SSL_read(ssl, rxbuf, (int)rxcap)) <= 0) { if (rxlen == 0) { printf("Client closed connection\n"); } @@ -297,7 +318,12 @@ int main(int argc, char **argv) /* Cleanup for next client */ SSL_shutdown(ssl); SSL_free(ssl); - close(client_skt); + closesocket(client_skt); + /* + * Set client_skt to INVALID_SOCKET to avoid double close when + * server_running become false before next accept + */ + client_skt = INVALID_SOCKET; } } printf("Server exiting...\n"); @@ -326,11 +352,19 @@ int main(int argc, char **argv) /* Create client SSL structure using dedicated client socket */ ssl = SSL_new(ssl_ctx); - SSL_set_fd(ssl, client_skt); + if (SSL_set_fd(ssl, (int)client_skt) <= 0) { + puts("Unable to set fd for the SSL object"); + ERR_print_errors_fp(stderr); + exit(EXIT_FAILURE); + } /* Set hostname for SNI */ SSL_set_tlsext_host_name(ssl, rem_server_ip); /* Configure server hostname check */ - SSL_set1_host(ssl, rem_server_ip); + if (SSL_set1_ipaddr(ssl, rem_server_ip) <= 0) { + puts("Unable to set IP address for the SSL object"); + ERR_print_errors_fp(stderr); + exit(EXIT_FAILURE); + } /* Now do SSL connect with server */ if (SSL_connect(ssl) == 1) { @@ -348,9 +382,11 @@ int main(int argc, char **argv) /* Loop to send input from keyboard */ while (true) { /* Get a line of input */ - txlen = getline(&txbuf, &txcap, stdin); + memset(buffer, 0, BUFFERSIZE); + txbuf = fgets(buffer, BUFFERSIZE, stdin); + /* Exit loop on error */ - if (txlen < 0 || txbuf == NULL) { + if (txbuf == NULL) { break; } /* Exit loop if just a carriage return */ @@ -358,14 +394,14 @@ int main(int argc, char **argv) break; } /* Send it to the server */ - if ((result = SSL_write(ssl, txbuf, txlen)) <= 0) { + if ((result = SSL_write(ssl, txbuf, (int)strlen(txbuf))) <= 0) { printf("Server closed connection\n"); ERR_print_errors_fp(stderr); break; } /* Wait for the echo */ - rxlen = SSL_read(ssl, rxbuf, rxcap); + rxlen = SSL_read(ssl, rxbuf, (int)rxcap); if (rxlen <= 0) { printf("Server closed connection\n"); ERR_print_errors_fp(stderr); @@ -392,10 +428,10 @@ int main(int argc, char **argv) } SSL_CTX_free(ssl_ctx); - if (client_skt != -1) - close(client_skt); - if (server_skt != -1) - close(server_skt); + if (client_skt != INVALID_SOCKET) + closesocket(client_skt); + if (server_skt != INVALID_SOCKET) + closesocket(server_skt); if (txbuf != NULL && txcap > 0) free(txbuf); diff --git a/demos/sslecho/main.c b/demos/sslecho/main.c index dfa5d263bd3e0..7b2738332db30 100644 --- a/demos/sslecho/main.c +++ b/demos/sslecho/main.c @@ -133,8 +133,8 @@ static void usage(void) { printf("Usage: sslecho s\n"); printf(" --or--\n"); - printf(" sslecho c ip\n"); - printf(" c=client, s=server, ip=dotted ip of server\n"); + printf(" sslecho c hostname\n"); + printf(" c=client, s=server, hostname=hostname of server\n"); exit(EXIT_FAILURE); } @@ -158,7 +158,7 @@ int main(int argc, char **argv) size_t rxcap = sizeof(rxbuf); int rxlen; - char *rem_server_ip = NULL; + char *rem_server_name = NULL; struct sockaddr_in addr; #if defined(OPENSSL_SYS_CYGWIN) || defined(OPENSSL_SYS_WINDOWS) @@ -182,13 +182,13 @@ int main(int argc, char **argv) /* NOTREACHED */ } isServer = (argv[1][0] == 's') ? true : false; - /* If client get remote server address (could be 127.0.0.1) */ + /* If client get remote server hostname */ if (!isServer) { if (argc != 3) { usage(); /* NOTREACHED */ } - rem_server_ip = argv[2]; + rem_server_name = argv[2]; } /* Create context used by both client and server */ @@ -291,7 +291,7 @@ int main(int argc, char **argv) client_skt = create_socket(false); /* Set up connect address */ addr.sin_family = AF_INET; - inet_pton(AF_INET, rem_server_ip, &addr.sin_addr.s_addr); + inet_pton(AF_INET, rem_server_name, &addr.sin_addr.s_addr); addr.sin_port = htons(server_port); /* Do TCP connect with server */ if (connect(client_skt, (struct sockaddr *)&addr, sizeof(addr)) != 0) { @@ -308,9 +308,9 @@ int main(int argc, char **argv) goto exit; } /* Set hostname for SNI */ - SSL_set_tlsext_host_name(ssl, rem_server_ip); + SSL_set_tlsext_host_name(ssl, rem_server_name); /* Configure server hostname check */ - if (!SSL_set1_dnsname(ssl, rem_server_ip)) { + if (!SSL_set1_dnsname(ssl, rem_server_name)) { ERR_print_errors_fp(stderr); goto exit; } diff --git a/doc/README.md b/doc/README.md index d999b0262b763..505f48856b144 100644 --- a/doc/README.md +++ b/doc/README.md @@ -22,5 +22,9 @@ README.md This file Overviews; start with crypto.pod and ssl.pod, for example Algorithm specific EVP_PKEY documentation. +Directories above should contain public information and API documentation. +For internal documentation (like an API included with headers in +include/internal), use [internal/](internal/) directory. + Formatted versions of the manpages (apps,ssl,crypto) can be found at diff --git a/doc/build.info b/doc/build.info index 44b06941e4d96..e89862b72be5a 100644 --- a/doc/build.info +++ b/doc/build.info @@ -827,6 +827,10 @@ DEPEND[html/man3/CMS_add1_signer.html]=man3/CMS_add1_signer.pod GENERATE[html/man3/CMS_add1_signer.html]=man3/CMS_add1_signer.pod DEPEND[man/man3/CMS_add1_signer.3]=man3/CMS_add1_signer.pod GENERATE[man/man3/CMS_add1_signer.3]=man3/CMS_add1_signer.pod +DEPEND[html/man3/CMS_add_standard_smimecap_ex.html]=man3/CMS_add_standard_smimecap_ex.pod +GENERATE[html/man3/CMS_add_standard_smimecap_ex.html]=man3/CMS_add_standard_smimecap_ex.pod +DEPEND[man/man3/CMS_add_standard_smimecap_ex.3]=man3/CMS_add_standard_smimecap_ex.pod +GENERATE[man/man3/CMS_add_standard_smimecap_ex.3]=man3/CMS_add_standard_smimecap_ex.pod DEPEND[html/man3/CMS_compress.html]=man3/CMS_compress.pod GENERATE[html/man3/CMS_compress.html]=man3/CMS_compress.pod DEPEND[man/man3/CMS_compress.3]=man3/CMS_compress.pod @@ -1551,6 +1555,10 @@ DEPEND[html/man3/OPENSSL_LH_stats.html]=man3/OPENSSL_LH_stats.pod GENERATE[html/man3/OPENSSL_LH_stats.html]=man3/OPENSSL_LH_stats.pod DEPEND[man/man3/OPENSSL_LH_stats.3]=man3/OPENSSL_LH_stats.pod GENERATE[man/man3/OPENSSL_LH_stats.3]=man3/OPENSSL_LH_stats.pod +DEPEND[html/man3/OPENSSL_armcap.html]=man3/OPENSSL_armcap.pod +GENERATE[html/man3/OPENSSL_armcap.html]=man3/OPENSSL_armcap.pod +DEPEND[man/man3/OPENSSL_armcap.3]=man3/OPENSSL_armcap.pod +GENERATE[man/man3/OPENSSL_armcap.3]=man3/OPENSSL_armcap.pod DEPEND[html/man3/OPENSSL_config.html]=man3/OPENSSL_config.pod GENERATE[html/man3/OPENSSL_config.html]=man3/OPENSSL_config.pod DEPEND[man/man3/OPENSSL_config.3]=man3/OPENSSL_config.pod @@ -1955,6 +1963,10 @@ DEPEND[html/man3/PKCS12_create.html]=man3/PKCS12_create.pod GENERATE[html/man3/PKCS12_create.html]=man3/PKCS12_create.pod DEPEND[man/man3/PKCS12_create.3]=man3/PKCS12_create.pod GENERATE[man/man3/PKCS12_create.3]=man3/PKCS12_create.pod +DEPEND[html/man3/PKCS12_decrypt_secretbag.html]=man3/PKCS12_decrypt_secretbag.pod +GENERATE[html/man3/PKCS12_decrypt_secretbag.html]=man3/PKCS12_decrypt_secretbag.pod +DEPEND[man/man3/PKCS12_decrypt_secretbag.3]=man3/PKCS12_decrypt_secretbag.pod +GENERATE[man/man3/PKCS12_decrypt_secretbag.3]=man3/PKCS12_decrypt_secretbag.pod DEPEND[html/man3/PKCS12_decrypt_skey.html]=man3/PKCS12_decrypt_skey.pod GENERATE[html/man3/PKCS12_decrypt_skey.html]=man3/PKCS12_decrypt_skey.pod DEPEND[man/man3/PKCS12_decrypt_skey.3]=man3/PKCS12_decrypt_skey.pod @@ -2891,6 +2903,10 @@ DEPEND[html/man3/UI_new.html]=man3/UI_new.pod GENERATE[html/man3/UI_new.html]=man3/UI_new.pod DEPEND[man/man3/UI_new.3]=man3/UI_new.pod GENERATE[man/man3/UI_new.3]=man3/UI_new.pod +DEPEND[html/man3/X509V3_EXT_nconf_nid.html]=man3/X509V3_EXT_nconf_nid.pod +GENERATE[html/man3/X509V3_EXT_nconf_nid.html]=man3/X509V3_EXT_nconf_nid.pod +DEPEND[man/man3/X509V3_EXT_nconf_nid.3]=man3/X509V3_EXT_nconf_nid.pod +GENERATE[man/man3/X509V3_EXT_nconf_nid.3]=man3/X509V3_EXT_nconf_nid.pod DEPEND[html/man3/X509V3_EXT_print.html]=man3/X509V3_EXT_print.pod GENERATE[html/man3/X509V3_EXT_print.html]=man3/X509V3_EXT_print.pod DEPEND[man/man3/X509V3_EXT_print.3]=man3/X509V3_EXT_print.pod @@ -3019,10 +3035,18 @@ DEPEND[html/man3/X509_STORE_set_verify_cb_func.html]=man3/X509_STORE_set_verify_ GENERATE[html/man3/X509_STORE_set_verify_cb_func.html]=man3/X509_STORE_set_verify_cb_func.pod DEPEND[man/man3/X509_STORE_set_verify_cb_func.3]=man3/X509_STORE_set_verify_cb_func.pod GENERATE[man/man3/X509_STORE_set_verify_cb_func.3]=man3/X509_STORE_set_verify_cb_func.pod +DEPEND[html/man3/X509_VERIFY_PARAM_set1_host.html]=man3/X509_VERIFY_PARAM_set1_host.pod +GENERATE[html/man3/X509_VERIFY_PARAM_set1_host.html]=man3/X509_VERIFY_PARAM_set1_host.pod +DEPEND[man/man3/X509_VERIFY_PARAM_set1_host.3]=man3/X509_VERIFY_PARAM_set1_host.pod +GENERATE[man/man3/X509_VERIFY_PARAM_set1_host.3]=man3/X509_VERIFY_PARAM_set1_host.pod DEPEND[html/man3/X509_VERIFY_PARAM_set_flags.html]=man3/X509_VERIFY_PARAM_set_flags.pod GENERATE[html/man3/X509_VERIFY_PARAM_set_flags.html]=man3/X509_VERIFY_PARAM_set_flags.pod DEPEND[man/man3/X509_VERIFY_PARAM_set_flags.3]=man3/X509_VERIFY_PARAM_set_flags.pod GENERATE[man/man3/X509_VERIFY_PARAM_set_flags.3]=man3/X509_VERIFY_PARAM_set_flags.pod +DEPEND[html/man3/X509_VERIFY_PARAM_set_hostflags.html]=man3/X509_VERIFY_PARAM_set_hostflags.pod +GENERATE[html/man3/X509_VERIFY_PARAM_set_hostflags.html]=man3/X509_VERIFY_PARAM_set_hostflags.pod +DEPEND[man/man3/X509_VERIFY_PARAM_set_hostflags.3]=man3/X509_VERIFY_PARAM_set_hostflags.pod +GENERATE[man/man3/X509_VERIFY_PARAM_set_hostflags.3]=man3/X509_VERIFY_PARAM_set_hostflags.pod DEPEND[html/man3/X509_add_cert.html]=man3/X509_add_cert.pod GENERATE[html/man3/X509_add_cert.html]=man3/X509_add_cert.pod DEPEND[man/man3/X509_add_cert.3]=man3/X509_add_cert.pod @@ -3151,14 +3175,10 @@ DEPEND[html/man3/d2i_X509.html]=man3/d2i_X509.pod GENERATE[html/man3/d2i_X509.html]=man3/d2i_X509.pod DEPEND[man/man3/d2i_X509.3]=man3/d2i_X509.pod GENERATE[man/man3/d2i_X509.3]=man3/d2i_X509.pod -DEPEND[html/man3/i2d_CMS_bio_stream.html]=man3/i2d_CMS_bio_stream.pod -GENERATE[html/man3/i2d_CMS_bio_stream.html]=man3/i2d_CMS_bio_stream.pod -DEPEND[man/man3/i2d_CMS_bio_stream.3]=man3/i2d_CMS_bio_stream.pod -GENERATE[man/man3/i2d_CMS_bio_stream.3]=man3/i2d_CMS_bio_stream.pod -DEPEND[html/man3/i2d_PKCS7_bio_stream.html]=man3/i2d_PKCS7_bio_stream.pod -GENERATE[html/man3/i2d_PKCS7_bio_stream.html]=man3/i2d_PKCS7_bio_stream.pod -DEPEND[man/man3/i2d_PKCS7_bio_stream.3]=man3/i2d_PKCS7_bio_stream.pod -GENERATE[man/man3/i2d_PKCS7_bio_stream.3]=man3/i2d_PKCS7_bio_stream.pod +DEPEND[html/man3/i2d_ASN1_bio_stream.html]=man3/i2d_ASN1_bio_stream.pod +GENERATE[html/man3/i2d_ASN1_bio_stream.html]=man3/i2d_ASN1_bio_stream.pod +DEPEND[man/man3/i2d_ASN1_bio_stream.3]=man3/i2d_ASN1_bio_stream.pod +GENERATE[man/man3/i2d_ASN1_bio_stream.3]=man3/i2d_ASN1_bio_stream.pod DEPEND[html/man3/i2d_re_X509_tbs.html]=man3/i2d_re_X509_tbs.pod GENERATE[html/man3/i2d_re_X509_tbs.html]=man3/i2d_re_X509_tbs.pod DEPEND[man/man3/i2d_re_X509_tbs.3]=man3/i2d_re_X509_tbs.pod @@ -3262,6 +3282,7 @@ html/man3/CMS_EnvelopedData_create.html \ html/man3/CMS_add0_cert.html \ html/man3/CMS_add1_recipient_cert.html \ html/man3/CMS_add1_signer.html \ +html/man3/CMS_add_standard_smimecap_ex.html \ html/man3/CMS_compress.html \ html/man3/CMS_data_create.html \ html/man3/CMS_decrypt.html \ @@ -3443,6 +3464,7 @@ html/man3/OPENSSL_Applink.html \ html/man3/OPENSSL_FILE.html \ html/man3/OPENSSL_LH_COMPFUNC.html \ html/man3/OPENSSL_LH_stats.html \ +html/man3/OPENSSL_armcap.html \ html/man3/OPENSSL_config.html \ html/man3/OPENSSL_fork_prepare.html \ html/man3/OPENSSL_gmtime.html \ @@ -3544,6 +3566,7 @@ html/man3/PKCS12_add_friendlyname_asc.html \ html/man3/PKCS12_add_localkeyid.html \ html/man3/PKCS12_add_safe.html \ html/man3/PKCS12_create.html \ +html/man3/PKCS12_decrypt_secretbag.html \ html/man3/PKCS12_decrypt_skey.html \ html/man3/PKCS12_gen_mac.html \ html/man3/PKCS12_get_friendlyname.html \ @@ -3778,6 +3801,7 @@ html/man3/UI_STRING.html \ html/man3/UI_UTIL_read_pw.html \ html/man3/UI_create_method.html \ html/man3/UI_new.html \ +html/man3/X509V3_EXT_nconf_nid.html \ html/man3/X509V3_EXT_print.html \ html/man3/X509V3_get_d2i.html \ html/man3/X509V3_set_ctx.html \ @@ -3810,7 +3834,9 @@ html/man3/X509_STORE_add_cert.html \ html/man3/X509_STORE_get0_param.html \ html/man3/X509_STORE_new.html \ html/man3/X509_STORE_set_verify_cb_func.html \ +html/man3/X509_VERIFY_PARAM_set1_host.html \ html/man3/X509_VERIFY_PARAM_set_flags.html \ +html/man3/X509_VERIFY_PARAM_set_hostflags.html \ html/man3/X509_add_cert.html \ html/man3/X509_check_ca.html \ html/man3/X509_check_certificate_times.html \ @@ -3843,8 +3869,7 @@ html/man3/d2i_PrivateKey.html \ html/man3/d2i_RSAPrivateKey.html \ html/man3/d2i_SSL_SESSION.html \ html/man3/d2i_X509.html \ -html/man3/i2d_CMS_bio_stream.html \ -html/man3/i2d_PKCS7_bio_stream.html \ +html/man3/i2d_ASN1_bio_stream.html \ html/man3/i2d_re_X509_tbs.html \ html/man3/o2i_SCT_LIST.html \ html/man3/s2i_ASN1_IA5STRING.html @@ -3938,6 +3963,7 @@ man/man3/CMS_EnvelopedData_create.3 \ man/man3/CMS_add0_cert.3 \ man/man3/CMS_add1_recipient_cert.3 \ man/man3/CMS_add1_signer.3 \ +man/man3/CMS_add_standard_smimecap_ex.3 \ man/man3/CMS_compress.3 \ man/man3/CMS_data_create.3 \ man/man3/CMS_decrypt.3 \ @@ -4119,6 +4145,7 @@ man/man3/OPENSSL_Applink.3 \ man/man3/OPENSSL_FILE.3 \ man/man3/OPENSSL_LH_COMPFUNC.3 \ man/man3/OPENSSL_LH_stats.3 \ +man/man3/OPENSSL_armcap.3 \ man/man3/OPENSSL_config.3 \ man/man3/OPENSSL_fork_prepare.3 \ man/man3/OPENSSL_gmtime.3 \ @@ -4220,6 +4247,7 @@ man/man3/PKCS12_add_friendlyname_asc.3 \ man/man3/PKCS12_add_localkeyid.3 \ man/man3/PKCS12_add_safe.3 \ man/man3/PKCS12_create.3 \ +man/man3/PKCS12_decrypt_secretbag.3 \ man/man3/PKCS12_decrypt_skey.3 \ man/man3/PKCS12_gen_mac.3 \ man/man3/PKCS12_get_friendlyname.3 \ @@ -4454,6 +4482,7 @@ man/man3/UI_STRING.3 \ man/man3/UI_UTIL_read_pw.3 \ man/man3/UI_create_method.3 \ man/man3/UI_new.3 \ +man/man3/X509V3_EXT_nconf_nid.3 \ man/man3/X509V3_EXT_print.3 \ man/man3/X509V3_get_d2i.3 \ man/man3/X509V3_set_ctx.3 \ @@ -4486,7 +4515,9 @@ man/man3/X509_STORE_add_cert.3 \ man/man3/X509_STORE_get0_param.3 \ man/man3/X509_STORE_new.3 \ man/man3/X509_STORE_set_verify_cb_func.3 \ +man/man3/X509_VERIFY_PARAM_set1_host.3 \ man/man3/X509_VERIFY_PARAM_set_flags.3 \ +man/man3/X509_VERIFY_PARAM_set_hostflags.3 \ man/man3/X509_add_cert.3 \ man/man3/X509_check_ca.3 \ man/man3/X509_check_certificate_times.3 \ @@ -4519,8 +4550,7 @@ man/man3/d2i_PrivateKey.3 \ man/man3/d2i_RSAPrivateKey.3 \ man/man3/d2i_SSL_SESSION.3 \ man/man3/d2i_X509.3 \ -man/man3/i2d_CMS_bio_stream.3 \ -man/man3/i2d_PKCS7_bio_stream.3 \ +man/man3/i2d_ASN1_bio_stream.3 \ man/man3/i2d_re_X509_tbs.3 \ man/man3/o2i_SCT_LIST.3 \ man/man3/s2i_ASN1_IA5STRING.3 @@ -4559,6 +4589,10 @@ DEPEND[html/man7/EVP_CIPHER-ARIA.html]=man7/EVP_CIPHER-ARIA.pod GENERATE[html/man7/EVP_CIPHER-ARIA.html]=man7/EVP_CIPHER-ARIA.pod DEPEND[man/man7/EVP_CIPHER-ARIA.7]=man7/EVP_CIPHER-ARIA.pod GENERATE[man/man7/EVP_CIPHER-ARIA.7]=man7/EVP_CIPHER-ARIA.pod +DEPEND[html/man7/EVP_CIPHER-ASCON-AEAD128.html]=man7/EVP_CIPHER-ASCON-AEAD128.pod +GENERATE[html/man7/EVP_CIPHER-ASCON-AEAD128.html]=man7/EVP_CIPHER-ASCON-AEAD128.pod +DEPEND[man/man7/EVP_CIPHER-ASCON-AEAD128.7]=man7/EVP_CIPHER-ASCON-AEAD128.pod +GENERATE[man/man7/EVP_CIPHER-ASCON-AEAD128.7]=man7/EVP_CIPHER-ASCON-AEAD128.pod DEPEND[html/man7/EVP_CIPHER-BLOWFISH.html]=man7/EVP_CIPHER-BLOWFISH.pod GENERATE[html/man7/EVP_CIPHER-BLOWFISH.html]=man7/EVP_CIPHER-BLOWFISH.pod DEPEND[man/man7/EVP_CIPHER-BLOWFISH.7]=man7/EVP_CIPHER-BLOWFISH.pod @@ -5053,6 +5087,10 @@ DEPEND[man/man7/openssl_user_macros.7]=man7/openssl_user_macros.pod GENERATE[man/man7/openssl_user_macros.7]=man7/openssl_user_macros.pod DEPEND[man7/openssl_user_macros.pod]{pod}=man7/openssl_user_macros.pod.in GENERATE[man7/openssl_user_macros.pod]=man7/openssl_user_macros.pod.in +DEPEND[html/man7/ossl-guide-dtlsv13.html]=man7/ossl-guide-dtlsv13.pod +GENERATE[html/man7/ossl-guide-dtlsv13.html]=man7/ossl-guide-dtlsv13.pod +DEPEND[man/man7/ossl-guide-dtlsv13.7]=man7/ossl-guide-dtlsv13.pod +GENERATE[man/man7/ossl-guide-dtlsv13.7]=man7/ossl-guide-dtlsv13.pod DEPEND[html/man7/ossl-guide-introduction.html]=man7/ossl-guide-introduction.pod GENERATE[html/man7/ossl-guide-introduction.html]=man7/ossl-guide-introduction.pod DEPEND[man/man7/ossl-guide-introduction.7]=man7/ossl-guide-introduction.pod @@ -5219,6 +5257,7 @@ HTMLDOCS[man7]=html/man7/EVP_ASYM_CIPHER-RSA.html \ html/man7/EVP_ASYM_CIPHER-SM2.html \ html/man7/EVP_CIPHER-AES.html \ html/man7/EVP_CIPHER-ARIA.html \ +html/man7/EVP_CIPHER-ASCON-AEAD128.html \ html/man7/EVP_CIPHER-BLOWFISH.html \ html/man7/EVP_CIPHER-CAMELLIA.html \ html/man7/EVP_CIPHER-CAST.html \ @@ -5342,6 +5381,7 @@ html/man7/openssl-quic-concurrency.html \ html/man7/openssl-quic.html \ html/man7/openssl-threads.html \ html/man7/openssl_user_macros.html \ +html/man7/ossl-guide-dtlsv13.html \ html/man7/ossl-guide-introduction.html \ html/man7/ossl-guide-libcrypto-introduction.html \ html/man7/ossl-guide-libraries-introduction.html \ @@ -5385,6 +5425,7 @@ MANDOCS[man7]=man/man7/EVP_ASYM_CIPHER-RSA.7 \ man/man7/EVP_ASYM_CIPHER-SM2.7 \ man/man7/EVP_CIPHER-AES.7 \ man/man7/EVP_CIPHER-ARIA.7 \ +man/man7/EVP_CIPHER-ASCON-AEAD128.7 \ man/man7/EVP_CIPHER-BLOWFISH.7 \ man/man7/EVP_CIPHER-CAMELLIA.7 \ man/man7/EVP_CIPHER-CAST.7 \ @@ -5508,6 +5549,7 @@ man/man7/openssl-quic-concurrency.7 \ man/man7/openssl-quic.7 \ man/man7/openssl-threads.7 \ man/man7/openssl_user_macros.7 \ +man/man7/ossl-guide-dtlsv13.7 \ man/man7/ossl-guide-introduction.7 \ man/man7/ossl-guide-libcrypto-introduction.7 \ man/man7/ossl-guide-libraries-introduction.7 \ diff --git a/doc/designs/ML-KEM.md b/doc/designs/ML-KEM.md index b1ca4098e0895..5c73e437f2391 100644 --- a/doc/designs/ML-KEM.md +++ b/doc/designs/ML-KEM.md @@ -36,7 +36,7 @@ there are unambiguous choices for its encoding and decoding functions. It may be noted that the *wire-form* public key is "compressed". Instead of the bulky "A" ("m" in the code) matrix, which represents the majority of the storage required for ML-KEM public and private keys, the *wire-form* public -key, holds a 32-byte seed from which the the matrix is regenerated by the recipient +key, holds a 32-byte seed from which the matrix is regenerated by the recipient of the public key. In the OpenSSL implementation, the matrix is *eagerly* evaluated as part of decoding the public key, and stored in memory in the internal form needed for diff --git a/doc/designs/dtlsv1_3/dtlsv1_3-main.md b/doc/designs/dtlsv1_3/dtlsv1_3-main.md new file mode 100644 index 0000000000000..131ca020ab5ca --- /dev/null +++ b/doc/designs/dtlsv1_3/dtlsv1_3-main.md @@ -0,0 +1,297 @@ +DTLSv1.3 Design +=============== + +This page presents an overview of the design rationale for the DTLSv1.3 +(RFC 9147) implementation in OpenSSL. + +Objectives +---------- + +* A user should be able to establish a DTLSv1.3 connection through the same + apis as previous versions of DTLS. +* MUSTs, SHALLs and REQUIREDs of RFC 9147 are implemented. +* Implementation details of OPTIONALs, SHOULDs and MAYs are documented in + this document. + +Implementation details +---------------------- + +This section describes the implementation requirements of DTLSv1.3 +(RFC 9147). + +### DTLSv1.0 support + +RFC 9147 recommends to drop DTLSv1.0 support but OpenSSL will continue to +support it for now. + +### DTLSv1.3 unified header + +A new feature for DTLSv1.3 is the unified header (unified_hdr) (RFC 9147 +section 4) of the DTLSCiphertext. OpenSSL supports receiving a DTLSCiphertext +of any format but always formats the header of outgoing DTLSCiphertext's the +same way: + +* The C-bit is set to 0. Refer to [DTLSv1.3 connection id](#dtlsv1.3-connection-id) +* The S-bit is set to 1 (sequence numbers are 16-bit) +* The L-bit is set to 1 (length field is present) + +Configurability of the unified header fields requires a new api and is marked +as a feature request in issue ###########. + +### DTLSv1.3 connection id + +OpenSSL does not support Connection IDs (RFC 9146). Notably Openssl DTLSv1.3 clients +will not offer the "connection_id" extension even though RFC 9147 states: + +> DTLS clients which do not want to receive a Connection ID SHOULD still offer +> the "connection_id" extension [RFC9146] unless there is an application +> profile to the contrary. This permits a server which wants to receive a CID +> to negotiate one. + +### Clearing retransmission queue + +When the session keys are updated the DTLSv1.3 implementation will clear the +messages waiting for retransmission that belongs to the key that is being updated. + +#### TLS 1.3 "compatibility mode" is not enabled + +Opposed to the TLS 1.3 implementation, the DTLSv1.3 implementation does not offer +the compatibility which is in consistency with RFC9147 section 5. + +This is enforced by the macro `SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(sc)`. + +#### Cryptographic label prefix + +The DTLSv1.3 implementation uses the label "dtls1.3" as described by RFC9147 +section 5.9. + +#### DTLS 1.3 Epoch + +The DTLSv1.3 implementation modifies the epoch according to RFC9147 section 6.1 +for DTLSv1.3 connections. + +### DTLS 1.3 Sequence Numbers + +Sequence numbers from the Unified Header are Encrypted. Please see RFC9147 +section 4.2.3. This procedure requires at least 16 bytes and thus padding +is required for smaller payloads. + +#### DTLS 1.3 Transcript Hash + +The DTLSv1.3 implementation does not include the message sequence number, +fragment offset and fragment length as is the case with previous versions of DTLS. + +#### DTLS ACK records (RFC9147 Section 7) + +ACKs are sent for KeyUpdates, NewSessionTicket, Certificate (client), +CompressedCertificate (Client), CertificateVerify (client) and Finish (client). + +Notes on RFC9147 Section 7.1: + +* The implementation does not offer any logic to determine that there is disruption + when receiving messages which means it will not send ACKs for the example given + in RFC9147 Figure 12. +* ACKs are always sent immediately after receiving a full message to be ACKed. +* If the implementation does not receive an ACK for all fragments of a flight, + then the full flight will be retransmitted. +* Empty ACKs are never sent. +* The implementation does not explicitly prohibit receiving unencrypted ACKs. The + implementation will only ACK records of epoch > 0 so all ACKs sent by the + implementation will be encrypted. +* The implementation only accepts ACKs after DTLSv1.3 has been negotiated. ACKs + that are received when DTLSv1.3 has not been negotiated is handled with a fatal + alert as any other unexpected message. ACKs that are received before version + negotiation are dropped. +* The implementation ignores ACKs received for messages other than KeyUpdates, + NewSessionTicket, Certificate (client), CertificateVerify (client) and Finish (client). + +Missing functionality: + +There's need for a lot more corner case testing: + +* Correct handling of ACKs during KeyUpdate and SessionTicket updates. +* Currently only retransmission after a missing ACK of client Finish message is + tested. +* TLSProxy does not support testing post handshake message ACK testing. Such + testing probably needs to be performed by another framework. +* This comment also forms a great test case: + + +### Known issues + +SCTP for DTLS 1.3 is not supported. SCTP is only supported up to DTLS 1.2. +Currently there is a draft for updating SCTP to support DLTS 1.3. + + +Race condition when the Server sends data right away once the connection is +established. Since the Server must send an ACK to acknowledge the Client's +Finish message the data may arrive before the ACK message. In the case of +when application data arrives before an expected ACK message the application +data will be buffered and processed once the ACK message has been read and +processed. + +Implementation progress +----------------------- + +This section contains a summary of the work required to implement DTLSv1.3 for Openssl. +It is basically a condensed version of the RFC. + +### Backlog of work items + +A summary of larger work items that needs to be addressed. + +Notice that some of the requirements mentioned in [List of DTLSv1.3 requirements](#list-of-dtls-13-requirements) +is not covered by these workitems and must be implemented separately. + +| Summary | #PR | +|------------------------|--------| +| DTLSv1.3 Fuzzer | - | + +### Changes from DTLS 1.2 and/or TLS 1.3 + +In general the implementation of DTLSv1.3 reuses much of the same functionality of +TLSv1.3 and DTLSv1.2. This part of the implementation can be considered a +separate work item. + +Here follows a collection of changes that need to be implemented. + +#### DTLSCipherText + +DTLSCipherText differs from DTLS 1.2 and TLS 1.3: + +> The DTLSCiphertext structure omits the superfluous version number and type fields +> ... +> The DTLSCiphertext structure has a variable-length header +> ... +> The entire header value shown in Figure 4 (but prior to record number encryption; +> see Section 4.2.3) is used as the additional data value for the AEAD function +> ... +> In DTLSv1.3 the 64-bit sequence_number is used as the sequence number for the +> AEAD computation; unlike DTLS 1.2, the epoch is not included. + +Because of the encrypted sequence number and record number the implementation must +handle them as described in: + +> 4.2.2. Reconstructing the Sequence Number and Epoch + +And + +> 4.2.3. Record Number Encryption + +#### ClientHello + +DTLS adds legacy_cookie which has a forced value. And there are changes to the +random value: + +> random: Same as for TLS 1.3, except that the downgrade sentinels ... apply to +> DTLS 1.2 and DTLS 1.0, respectively. + +#### EndOfEarlyData message + +> the EndOfEarlyData message is omitted both from the wire and the handshake +> transcript + +### List of DTLSv1.3 requirements + +Here's a list of requirements from RFC 9147 together with their implementation status +and associated PR with the relevant implementation. + +"TBD" indicates that the implementation is missing. Note there may exist a fix in a PR. + +"Yes" indicates that the requirement is already implemented. + +"No" indicates that the requirement will not be implemented. For example some requirements only +applies if the implementation supports Connection Id's. + +"DTLS 1.2" indicates that the requirement is the same for DTLS 1.2 and is expected to already +have been implemented. "DTLS 1.2?" indicates that this is an optional requirement for DTLS 1.2. + +"TLS 1.3" indicates that the requirement is the same for TLS 1.3 and is expected to already +have been implemented. + +| Requirement description | Implemented? | +|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------| +| Plaintext records MUST NOT be sent with sequence numbers that would exceed 2^48-1 | TBD | +| [legacy_record_version] MUST be set to {254, 253} for all records other than the initial ClientHello | TBD | +| [legacy_record_version] MUST be ignored for all purposes | TBD | +| Omitting the length field MUST only be used for the last record in a datagram. | No | +| If a Connection ID is negotiated, then it MUST be contained in all datagrams | No | +| Sending implementations MUST NOT mix records from multiple DTLS associations in the same datagram | TBD | +| If the second or later record has a connection ID which does not correspond to the same association used for previous records, the rest of the datagram MUST be discarded | No | +| If the first byte is alert(21), handshake(22), or ack(proposed, 26), the record MUST be interpreted as a DTLSPlaintext record | TBD | +| If the first byte is any other value, then receivers MUST check to see if the leading bits of the first byte are 001 | TBD | +| If so, the implementation MUST process the record as DTLSCiphertext; the true content type will be inside the protected portion | TBD | +| Otherwise, the record MUST be rejected as if it had failed deprotection | TBD | +| Implementations MUST send retransmissions of lost messages using the same epoch and keying material as the original transmission | TBD | +| Implementations MUST either abandon an association or rekey prior to allowing the sequence number to wrap. | DTLS 1.2? | +| Implementations MUST NOT allow the epoch to wrap, but instead MUST establish a new association, terminating the old association. | DTLS 1.2 | +| Receivers MUST reject shorter records [Ciphertexts lengths less than 16 bytes] as if they had failed deprotection | TBD | +| Senders MUST pad short plaintexts out | TBD | +| cipher suites, which are not based on AES or ChaCha20, MUST define their own record sequence number encryption in order to be used with DTLS | N/A | +| Each DTLS record MUST fit within a single datagram | DTLS 1.2 | +| The first byte of the datagram payload MUST be the beginning of a record | DTLS 1.2 | +| Records MUST NOT span datagrams | DTLS 1.2 | +| [For DTLS over TCP or SCTP] the upper layer protocol MUST NOT write any record that exceeds the maximum record size of 2^14 bytes | DTLS 1.2 | +| [If there is a transport protocol indication that the PMTU was exceeded] then the DTLS record layer MUST inform the upper layer protocol of the error | DTLS 1.2 | +| The received record counter for an epoch MUST be initialized to zero when that epoch is first used. | TBD | +| For each received record, the receiver MUST verify that the record contains a sequence number that does not duplicate the sequence number of any other record | DTLS 1.2 | +| The window MUST NOT be updated due to a received record until that record has been deprotected successfully | DTLS 1.2 | +| Implementations which choose to generate an alert [for invalid records] instead MUST generate fatal alerts | TBD | +| Implementations MUST count the number of received packets that fail authentication with each key. | TBD | +| Therefore, TLS_AES_128_CCM_8_SHA256 MUST NOT be used in DTLS without additional safeguards against forgery. | No | +| Implementations MUST set usage limits for AEAD_AES_128_CCM_8 based on an understanding of any additional forgery protections that are used. | TBD | +| Any TLS cipher suite that is specified for use with DTLS MUST define limits on the use of the associated AEAD function | N/A | +| DTLS servers MUST NOT echo the "legacy_session_id" value from the client | TBD | +| endpoints MUST NOT send ChangeCipherSpec messages | TBD | +| The client MUST send a new ClientHello with the cookie added as an extension | TBD | +| the legacy_cookie field in the ClientHello message MUST be set to a zero-length vector | TBD | +| When responding to a HelloRetryRequest, the client MUST create a new ClientHello message following the description in Section 4.1.2 of [TLS13] | TBD | +| Clients MUST be prepared to do a cookie exchange with every handshake. | DTLS 1.2 | +| If a server receives a ClientHello with an invalid cookie, it MUST terminate the handshake with an "illegal_parameter" alert | TBD | +| clients MUST abort the handshake with an "unexpected_message" alert in response to any second HelloRetryRequest which was sent in the same connection | TLS 1.3 | +| If the sequence number is less than next_receive_seq, the message MUST be discarded | DTLS 1.2 | +| DTLSv1.3-compliant implementations MUST NOT use the HelloVerifyRequest to execute a return-routability check. | TBD | +| A dual-stack DTLS 1.2 / DTLSv1.3 client MUST, however, be prepared to interact with a DTLS 1.2 server | TBD | +| the legacy_version field MUST be set to {254, 253} | TBD | +| A client which has a cached session ID set by a pre-DTLSv1.3 server SHOULD set this field to that value. Otherwise, it MUST be set as a zero-length vector | TBD | +| A DTLSv1.3-only client MUST set the legacy_cookie field to zero length | TBD | +| If a DTLSv1.3 ClientHello is received with any other value in this field [ie. legacy_cookie], the server MUST abort the handshake with an "illegal_parameter" alert | TBD | +| When transmitting the handshake message, the sender divides the message into a series of N contiguous data ranges. The ranges MUST NOT overlap | DTLS 1.2? | +| Each handshake message fragment that is placed into a record MUST be delivered in a single UDP datagram | DTLS 1.2? | +| When a DTLS implementation receives a handshake message fragment corresponding to the next expected handshake message sequence number, it MUST process it | DTLS 1.2? | +| DTLS implementations MUST be able to handle overlapping fragment ranges | DTLS 1.2 | +| Senders MUST NOT change handshake message bytes upon retransmission | TBD | +| when in the FINISHED state, the server MUST respond to retransmission of the client's final flight with a retransmit of its ACK | TBD | +| Implementations MUST either discard or buffer all application data records for epoch 3 and above until they have received the Finished message from the peer | TBD | +| implementations MUST NOT send KeyUpdate, NewConnectionId, or RequestConnectionId messages if an earlier message of the same type has not yet been acknowledged | TBD | +| Any data received with an epoch/sequence number pair after that of a valid received closure alert MUST be ignored | TBD | +| [The server] MUST NOT destroy the existing association until the client has demonstrated reachability | DTLS 1.2 | +| After a correct Finished message is received, the server MUST abandon the previous association | DTLS 1.2 | +| If a DTLS implementation would need to wrap the epoch value, it MUST terminate the connection. | DTLS 1.2 | +| Implementations MUST NOT acknowledge records containing handshake messages or fragments which have not been processed or buffered | TBD | +| For post-handshake messages, ACKs SHOULD be sent once for each received and processed handshake record | TBD | +| During the handshake, ACK records MUST be sent with an epoch which is equal to or higher than the record which is being acknowledged | TBD | +| After the handshake, implementations MUST use the highest available sending epoch | TBD | +| flights MUST be ACKed unless they are implicitly acknowledged | TBD | +| ACKs MUST NOT be sent for records of any content type other than handshake or for records which cannot be deprotected | TBD | +| Once all the messages in a flight have been acknowledged, the implementation MUST cancel all retransmissions of that flight | TBD | +| Implementations MUST treat a record as having been acknowledged if it appears in any ACK | TBD | +| the receipt of any record responding to a given flight MUST be taken as an implicit acknowledgement for the entire flight to which it is responding. | TBD | +| KeyUpdates MUST be acknowledged | TBD | +| implementations MUST NOT send records with the new keys or send a new KeyUpdate until the previous KeyUpdate has been acknowledged | TBD | +| receivers MUST retain the pre-update keying material until receipt and successful decryption of a message using the new keys | TBD | +| sending implementations MUST NOT allow the epoch to exceed 2^48-1 | DTLS 1.2 | +| receiving implementations MUST NOT enforce this rule [i.e. epoch exceeding 2^48-1] | TBD | +| sending implementations MUST NOT send its own KeyUpdate if that would cause it to exceed these limits [i.e. epoch exceeding 2^48-1] | TBD | +| If usage is set to "cid_immediate", then one of the new CIDs MUST be used immediately for all future records. | No | +| Endpoints MUST NOT have more than one NewConnectionId message outstanding | No | +| Implementations which either did not negotiate the "connection_id" extension or which have negotiated receiving an empty CID MUST NOT send NewConnectionId | No | +| Implementations MUST NOT send RequestConnectionId when sending an empty Connection ID | No | +| Implementations which detect a violation of these rules MUST terminate the connection with an "unexpected_message" alert | TBD | +| Endpoints MUST NOT send a RequestConnectionId message when an existing request is still unfulfilled | No | +| Endpoints MUST NOT send either of these messages [i.e. NewConnectionId and RequestConnectionId] if they did not negotiate a CID. | No | +| If an implementation receives these messages [i.e. NewConnectionId, RequestConnectionId] when CIDs were not negotiated, it MUST abort the connection with an "unexpected_message" alert | TBD | +| If no CID is negotiated, then the receiver MUST reject any records it receives that contain a CID. | TBD | +| The cookie MUST depend on the client's address. | Yes | +| It MUST NOT be possible for anyone other than the issuing entity to generate cookies that are accepted as valid by that entity. | TBD | +| DTLS implementations MUST NOT update the address they send to in response to packets from a different address | TBD | diff --git a/doc/designs/evp_skey_metadata.md b/doc/designs/evp_skey_metadata.md new file mode 100644 index 0000000000000..59479a15c1ce2 --- /dev/null +++ b/doc/designs/evp_skey_metadata.md @@ -0,0 +1,209 @@ +EVP_SKEY metadata support for PKCS#12 symmetric keys +==================================================== + +Problem +------- + +When parsing PKCS#12 files, the resulting object should be created with both +raw key bytes and other attributes (the friendly name, local key ID, original +AlgorithmIdentifier with parameters etc). + +We can store metadata in the provider-side `PROV_SKEY` structure and manage it +through the `EVP_SKEYMGMT` import/export mechanism. This keeps `evp_skey_st` +opaque to metadata details and lets providers handle metadata naturally through +`OSSL_PARAM`. + +The alias (friendly name) is returned through the existing `EVP_SKEY_get0_key_id` +API, which dispatches to `skeymgmt->get_key_id`. + +Binary metadata (local key ID, algorithm parameters) uses byte-pointer + length +pairs. + +OSSL_PARAM names for metadata +------------------------------ + +New parameter name constants in `include/openssl/core_names.h`: + +```c +#define OSSL_SKEY_PARAM_ALIAS "skey-alias" +#define OSSL_SKEY_PARAM_LOCAL_KEYID "skey-local-keyid" +#define OSSL_SKEY_PARAM_ALGORITHM_OID "skey-algorithm-oid" +#define OSSL_SKEY_PARAM_ALGORITHM_PARAMS "skey-algorithm-params" +``` + +- `OSSL_SKEY_PARAM_ALIAS` — UTF-8 string, the friendly name / key identifier. + Used as the return value from `skeymgmt->get_key_id`. +- `OSSL_SKEY_PARAM_LOCAL_KEYID` — octet string, the PKCS#12 local key ID. +- `OSSL_SKEY_PARAM_ALGORITHM_OID` — octet string, the DER-encoded algorithm + OID from the AlgorithmIdentifier. +- `OSSL_SKEY_PARAM_ALGORITHM_PARAMS` — octet string, the DER-encoded algorithm + parameters from the AlgorithmIdentifier. + +PROV_SKEY changes +----------------- + +Extend `struct prov_skey_st` in `include/internal/skey.h`: + +```c +struct prov_skey_st { + OSSL_LIB_CTX *libctx; + int type; + unsigned char *data; + size_t length; + + /* Metadata — set during import, returned during export / get_key_id */ + char *alias; /* friendly name, may be NULL */ + unsigned char *local_keyid; /* local key ID, may be NULL */ + size_t local_keyid_len; + unsigned char *algorithm_oid; /* DER-encoded algorithm OID, may be NULL */ + size_t algorithm_oid_len; + unsigned char *algorithm_params; /* DER-encoded alg params, may be NULL */ + size_t algorithm_params_len; +}; +``` + +All metadata fields are optional (NULL when not provided). `generic_free()` +must free them with `OPENSSL_free()`. + +EVP_SKEYMGMT implementation changes +------------------------------------ + +### generic skeymgmt + +- **Import**: decode new `OSSL_SKEY_PARAM_*` parameters from the import params + and store them in the `PROV_SKEY` fields. +- **Export**: include metadata params alongside `OSSL_SKEY_PARAM_RAW_BYTES` + when the corresponding fields are non-NULL. +- **get_key_id**: implement `OSSL_FUNC_SKEYMGMT_GET_KEY_ID` — return + `prov_skey->alias`. This makes `EVP_SKEY_get0_key_id()` return the + friendly name. +- **get_local_keyid**: implement `OSSL_FUNC_SKEYMGMT_GET_LOCAL_KEYID` — + return `prov_skey->local_keyid` and its length. This makes + `EVP_SKEY_get0_local_keyid()` work via dispatch. +- **get_algorithm_id**: implement `OSSL_FUNC_SKEYMGMT_GET_ALGORITHM_ID` — + return DER-encoded OID and parameters from `prov_skey`. This makes + `EVP_SKEY_get0_algorithm_id()` work via dispatch. +- **Import settable params**: update `generic_skey_import_list` to include + the new params. +- **free**: free all metadata fields. + +### AES skeymgmt + +Inherits generic import/export/free for metadata handling. No AES-specific +metadata logic needed — the base `generic_import` already stores the fields. + +EVP_SKEY metadata accessors +---------------------------- + +We implement the following accessors: + +- **Alias**: `EVP_SKEY_get0_key_id()` (existing API, no changes). + Returns `const char *` — the friendly name from the provider. + +- **Local key ID**: new accessor via export: + + ```c + int EVP_SKEY_get0_local_keyid(const EVP_SKEY *skey, + const unsigned char **id, size_t *len); + ``` + + Returns 1 on success (with `*id` and `*len` set), 0 on error. + +- **Algorithm identifier**: new accessor that returns both the DER-encoded OID + and the DER-encoded parameters: + + ```c + int EVP_SKEY_get0_algorithm_id(const EVP_SKEY *skey, + const unsigned char **oid, + size_t *oid_len, + const unsigned char **params, + size_t *params_len); + ``` + + Returns 1 on success. Either output pointer may be NULL if the caller + doesn't need that part. + +These accessors use dedicated `OSSL_FUNC_SKEYMGMT_GET_LOCAL_KEYID` and +`OSSL_FUNC_SKEYMGMT_GET_ALGORITHM_ID` dispatch functions, following the +pattern of `EVP_SKEY_get0_key_id()`. + +The implementation is in general provider-dependent. If the corresponding +callback is not implemented for the EVP_SKEYMGMT, 0 is returned. However, as +metadata is completely optional, the success doesn't indicate that the data is +available. + +PKCS8_PRIV_KEY_INFO_get1_skey changes +-------------------------------------- + +The function gains two new parameters: + +```c +EVP_SKEY *PKCS8_PRIV_KEY_INFO_get1_skey(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, + const char *propq, + const OSSL_PARAM *extra_params, + int strict); +``` + +- **`extra_params`**: caller-built `OSSL_PARAM` array containing metadata + from bag attributes (local key ID and friendly name). May be NULL. + The function merges these with the params it builds from the PKCS8 + structure (raw key bytes, algorithm identifier, algorithm parameters). + +- **`strict`**: controls how unrecognized algorithm OIDs are handled. + The function always attempts to match an algorithm-specific SKEYMGMT + based on the AlgorithmIdentifier OID (e.g. `OSSL_SKEY_TYPE_AES` for + AES NIDs). + - `0` (permissive, default): unrecognized OIDs fall back to + `OSSL_SKEY_TYPE_GENERIC`. + - non-zero (strict): unrecognized OIDs cause the function to return + NULL. + +The function now also: +1. Extracts the full `X509_ALGOR` from the PKCS8 structure (via `PKCS8_pkey_get0`). +2. DER-encodes the algorithm OID and adds it as + `OSSL_SKEY_PARAM_ALGORITHM_OID`. +3. DER-encodes the algorithm parameters (if present) and adds them as + `OSSL_SKEY_PARAM_ALGORITHM_PARAMS`. +4. Merges with `extra_params` (lkid, fname from caller). +5. Calls `EVP_SKEY_import()` with the combined parameter set. + +Caller changes in p12_kiss.c +----------------------------- + +In the `NID_secretBag` case in `parse_bag()`, the caller builds an +`OSSL_PARAM` array with the friendly name and local key ID extracted +from bag attributes, and passes it to `PKCS8_PRIV_KEY_INFO_get1_skey` +via `extra_params`: + +```c +case NID_secretBag: +{ + OSSL_PARAM extra[3]; + int nparams = 0; + unsigned char *fname_utf8 = NULL; + int fname_utf8_len = 0; + + if (fname) { + fname_utf8_len = ASN1_STRING_to_UTF8(&fname_utf8, fname); + if (fname_utf8_len >= 0) { + extra[nparams++] = OSSL_PARAM_construct_utf8_string( + OSSL_SKEY_PARAM_ALIAS, + (char *)fname_utf8, fname_utf8_len); + } + } + if (lkid) { + extra[nparams++] = OSSL_PARAM_construct_octet_string( + OSSL_SKEY_PARAM_LOCAL_KEYID, + lkid->data, lkid->length); + } + extra[nparams] = OSSL_PARAM_construct_end(); + + skey = PKCS8_PRIV_KEY_INFO_get1_skey(p8, ctx, propq, extra, 0); + OPENSSL_free(fname_utf8); + if (skey == NULL) + goto err; + + /* push skey to stack ... */ +} +``` diff --git a/doc/designs/evp_skey_multi.md b/doc/designs/evp_skey_multi.md index dfff81ed17c84..1e5413abba591 100644 --- a/doc/designs/evp_skey_multi.md +++ b/doc/designs/evp_skey_multi.md @@ -27,7 +27,7 @@ As all the objects are derived in one transaction, we can store a single opaque pointer keeping all the keys inside in the EVP_KDF_CTX object, and provide the API for access to a particular object. -To derive the opaque keys and and bytes buffers, we use the function +To derive the opaque keys and bytes buffers, we use the function ```C int EVP_KDF_derive_SKEYs(EVP_KDF_CTX *ctx, EVP_SKEYMGMT *mgmt, diff --git a/doc/designs/pkcs12_symmetric.md b/doc/designs/pkcs12_symmetric.md new file mode 100644 index 0000000000000..3917fbe6c3d7c --- /dev/null +++ b/doc/designs/pkcs12_symmetric.md @@ -0,0 +1,148 @@ +PKCS#12 Java Keytool Support Extension — Alternative Approach +============================================================= + +Problem Statement +----------------- + +OpenSSL cannot parse PKCS#12 files created by Java's keytool utility that +contain symmetric secret keys. Java keytool stores symmetric keys in +`secretBag` structures containing `pkcs8ShroudedKeyBag` with encrypted key +material. OpenSSL's PKCS#12 parser ignores `NID_secretBag` entirely. + +Approach: Bag-Level API + Parse Context +--------------------------------------- + +The key insight: follow the existing OpenSSL pattern where each bag type has +its own `PKCS12_SAFEBAG_get1_*()` extractor, and use an opaque context for the +high-level parse API. + +Design Principles +----------------- + +- **Opaque parse context**: `PKCS12_PARSE_CTX` tells `PKCS12_parse_ex()` which + object types to extract. Adding a new type means adding a struct field and a +setter — no function signature changes. +- **Bag-level extraction**: Add `PKCS8_PRIV_KEY_INFO_get1_skey()` in `p12_sbag.c`, + following the `get1_cert` / `get1_crl` pattern. This is the single source of +truth for secret bag decryption — both the parser and the CLI tool call it. +- **Minimal internal churn**: `parse_bag()` handles `NID_secretBag` by calling + the public bag-level API, just like it calls `PKCS12_SAFEBAG_get1_cert_ex()` +for `NID_certBag`. Internal functions pass `PKCS12_PARSE_CTX *` instead of +individual pointer parameters. + +Implementation Plan +------------------- + +1. OID Registration + +Registering OID for generic AES algorithm as most important for our purposes. + +2. Bag-Level Secret Key API (following private key pattern) + +Two functions, mirroring `PKCS12_decrypt_skey_ex()` + `EVP_PKCS82PKEY_ex()`: + +Decrypt: `PKCS12_decrypt_secretbag` + +**File**: `crypto/pkcs12/p12_add.c` (alongside `PKCS12_decrypt_skey_ex`) + +```c +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_secretbag(const PKCS12_SAFEBAG *bag, + const char *pass, int passlen, + OSSL_LIB_CTX *ctx, const char *propq); +``` + +Implementation: +1. Check `PKCS12_SAFEBAG_get_nid(bag) == NID_secretBag` +2. Check `PKCS12_SAFEBAG_get_bag_nid(bag) == NID_pkcs8ShroudedKeyBag` +3. Get bag object via `PKCS12_SAFEBAG_get0_bag_obj()`, verify `V_ASN1_OCTET_STRING` +4. Parse as `X509_SIG` via `d2i_X509_SIG()` +5. Decrypt via `PKCS8_decrypt_ex()` and return `PKCS8_PRIV_KEY_INFO` + +Convert: `PKCS8_PRIV_KEY_INFO_get1_skey` + +**File**: `crypto/pkcs12/p12_sbag.c` + +```c +EVP_SKEY *PKCS8_PRIV_KEY_INFO_get1_skey(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq); +``` + +Implementation: +1. Extract key bytes via `PKCS8_pkey_get0()`, determine key type from algorithm OID +2. Create and return `EVP_SKEY` via `EVP_SKEY_import_raw_key()` + +This follows the private key pattern: `PKCS12_decrypt_skey_ex()` + +`EVP_PKCS82PKEY_ex()` → `PKCS12_decrypt_secretbag()` + +`PKCS8_PRIV_KEY_INFO_get1_skey()`. + +3. Parse Context API and PKCS12_parse_ex() + +**Files**: `crypto/pkcs12/p12_kiss.c`, `include/openssl/pkcs12.h.in`, `crypto/pkcs12/p12_local.h` + +PKCS12_PARSE_CTX + +Introduce an opaque context structure that tells `PKCS12_parse_ex()` what to extract: + +```c +/* In p12_local.h (internal definition) */ +struct pkcs12_parse_ctx_st { + EVP_PKEY **pkey; + X509 **cert; + STACK_OF(X509) **ca; + EVP_SKEY **skey; + /* internal: temporary cert collection used during parsing */ + STACK_OF(X509) *ocerts; +}; +``` + +Public API: + +```c +PKCS12_PARSE_CTX *PKCS12_PARSE_CTX_new(void); +void PKCS12_PARSE_CTX_free(PKCS12_PARSE_CTX *ctx); + +/* Setters — each tells the parser to extract that object type */ +void PKCS12_PARSE_CTX_set_pkey(PKCS12_PARSE_CTX *ctx, EVP_PKEY **pkey); +void PKCS12_PARSE_CTX_set_cert(PKCS12_PARSE_CTX *ctx, X509 **cert); +void PKCS12_PARSE_CTX_set_ca(PKCS12_PARSE_CTX *ctx, STACK_OF(X509) **ca); +void PKCS12_PARSE_CTX_set_skeys(PKCS12_PARSE_CTX *ctx, STACK_OF(EVP_SKEY) **skeys); +``` + +Internal functions `parse_pk12()`, `parse_bags()`, `parse_bag()` accept +`PKCS12_PARSE_CTX *ctx` instead of individual pointer parameters. This replaces +the current `EVP_PKEY **pkey, STACK_OF(X509) *ocerts` signatures and is +extensible — adding a new object type means adding a field to the struct and a +setter, not changing every internal function signature. + +PKCS12_parse_ex() + +```c +int PKCS12_parse_ex(PKCS12 *p12, const char *pass, + PKCS12_PARSE_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq); +``` + +The context tells the parser which output slots to fill. Slots not set via +setters are ignored. On error, all set slots are cleaned up (freed and set to +NULL). + +4. Command-Line Tool + +**File**: `apps/pkcs12.c` + +Add `-raw` option (`OPT_RAW`) for raw binary output. + +For `-info` mode, add `dump_secret_bag_info()` — displays bag type, encryption +algorithm, encrypted data length on stderr. + +`dump_skey_output()` handles three output modes: +- `-raw`: raw binary via `EVP_SKEY_get0_raw_key()` → `BIO_write()` +- `-noenc`/`-nodes`: bag attributes + algorithm + key length + hex key data +- default: bag attributes + algorithm + key length + "use -noenc to output" message + +5. OSSL_STORE Integration + +**File**: `crypto/store/store_result.c` + +Update `try_pkcs12()` to use a `PKCS12_PARSE_CTX` object requesting pkey, cert, +ca, and skey diff --git a/doc/designs/quic-design/glossary.md b/doc/designs/quic-design/glossary.md index 50a9d5ae2f7fa..1f3a48e4df274 100644 --- a/doc/designs/quic-design/glossary.md +++ b/doc/designs/quic-design/glossary.md @@ -56,7 +56,7 @@ dispatches calls to libssl public APIs to the APL. **Engine:** See `QUIC_ENGINE`. -**Event Leader:** The QSO which is is the top-level QSO in a hierarchy of QSOs, +**Event Leader:** The QSO which is the top-level QSO in a hierarchy of QSOs, and which is responsible for event processing for all QSOs in that hierarchy. This may be a QLSO or QCSO. See [the server API design](server/quic-server-api.md). diff --git a/doc/designs/quic-design/quic-ackm.md b/doc/designs/quic-design/quic-ackm.md index 38d72aac3cdbb..c67dea3465ae6 100644 --- a/doc/designs/quic-design/quic-ackm.md +++ b/doc/designs/quic-design/quic-ackm.md @@ -421,7 +421,7 @@ one that is not either process it safely). This should be called for a packet before attempting to process its contents. -Failure to do so may may result in processing a duplicated packet in violation +Failure to do so may result in processing a duplicated packet in violation of the RFC. The return value of this function transitions from 1 to 0 for a given PN once diff --git a/doc/designs/quic-design/quic-api-ssl-funcs.md b/doc/designs/quic-design/quic-api-ssl-funcs.md index 37229c26e68f2..1a702b81731ad 100644 --- a/doc/designs/quic-design/quic-api-ssl-funcs.md +++ b/doc/designs/quic-design/quic-api-ssl-funcs.md @@ -876,7 +876,6 @@ The following options must be explicitly forbidden: - `SSL_OP_ENABLE_MIDDLEBOX_COMPAT` — forbidden by QUIC RFCs - `SSL_OP_ENABLE_KTLS` — not currently supported for QUIC - `SSL_OP_SAFARI_ECDHE_ECDSA_BUG` -- `SSL_OP_TLSEXT_PADDING` - `SSL_OP_TLS_ROLLBACK_BUG` - `SSL_OP_IGNORE_UNEXPECTED_EOF` - `SSL_OP_ALLOW_NO_DHE_KEX` diff --git a/doc/designs/quic-design/quic-api.md b/doc/designs/quic-design/quic-api.md index dbb18264f8e4e..e1702c57f9e4b 100644 --- a/doc/designs/quic-design/quic-api.md +++ b/doc/designs/quic-design/quic-api.md @@ -453,7 +453,7 @@ use cases. The design is similar to that of `DTLSv1_get_timeout` and uses a `struct timeval`. However, this function can also output an infinite timeout using the -`is_infinite` argument, whereas whereas `DTLSv1_get_timeout` represents an +`is_infinite` argument, whereas `DTLSv1_get_timeout` represents an infinite timeout using a 0 return value, which does not allow a failure condition to be distinguished. diff --git a/doc/designs/quic-design/record-layer.md b/doc/designs/quic-design/record-layer.md index 4bea5fd5033d0..60b0d483c3091 100644 --- a/doc/designs/quic-design/record-layer.md +++ b/doc/designs/quic-design/record-layer.md @@ -401,7 +401,7 @@ struct ossl_record_method_st { const char *propq, int vers, int role, int direction, int level, - uint16_t epoch, + uint64_t epoch, unsigned char *key, size_t keylen, unsigned char *iv, diff --git a/doc/internal/man3/DEFINE_LIST_OF.pod b/doc/internal/man3/DEFINE_LIST_OF.pod index d886defc43fb9..95693cf0b2a90 100644 --- a/doc/internal/man3/DEFINE_LIST_OF.pod +++ b/doc/internal/man3/DEFINE_LIST_OF.pod @@ -8,7 +8,7 @@ ossl_list_TYPE_is_empty, ossl_list_TYPE_num, ossl_list_TYPE_head, ossl_list_TYPE_tail, ossl_list_TYPE_next, ossl_list_TYPE_prev, ossl_list_TYPE_remove, ossl_list_TYPE_insert_head, ossl_list_TYPE_insert_tail, -ossl_list_TYPE_insert_before, ossl_list_TYPE_after +ossl_list_TYPE_insert_before, ossl_list_TYPE_after, ossl_list_TYPE_join - doubly linked list =head1 SYNOPSIS @@ -38,6 +38,7 @@ ossl_list_TYPE_insert_before, ossl_list_TYPE_after void ossl_list_TYPE_insert_before(OSSL_LIST(name) *list, type *existing, type *elem); void ossl_list_TYPE_insert_after(OSSL_LIST(name) *list, type *existing, type *elem); + void ossl_list_TYPE_join(OSSL_LIST(name) *lh, OSSL_LIST(name) *lt); =head1 DESCRIPTION @@ -90,6 +91,10 @@ B_insert_after>() inserts the element I, which must not be in the list, into the I immediately after the I element. +B_join<()> joins list B with list B. +List B is appended to list B. The list B becomes empty, +as all its members are part of B after the function returns. + =head1 RETURN VALUES B_is_empty>() returns nonzero if the list is empty and zero @@ -124,11 +129,13 @@ the specified element in the list. =head1 HISTORY -The functions described here were all added in OpenSSL 3.2. +ossl_list_TYPE_join() was added in OpenSSL 4.1, 4.0.2, 3.6.4, 3.5.8, and 3.4.7. + +The rest of the functions described here was added in OpenSSL 3.2. =head1 COPYRIGHT -Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/internal/man3/OPTIONS.pod b/doc/internal/man3/OPTIONS.pod index 669823ee8f598..3691f9c705fa2 100644 --- a/doc/internal/man3/OPTIONS.pod +++ b/doc/internal/man3/OPTIONS.pod @@ -186,7 +186,7 @@ B macro: OPT_PARAMETERS() {OPT_PARAM_STR, 1, '-', "Parameters:\n"} -Every "option" after after this should contain the parameter and +Every "option" after this should contain the parameter and the help string: {"text", 0, 0, "Words to display (optional)"}, @@ -244,7 +244,7 @@ The opt_arg() function returns the option's argument value, if there is one. The opt_unknown() function returns the unknown option. In an option list, there can be at most one option with the empty string. This is a "wildcard" or "unknown" option. For example, it allows an -option to be be taken as digest algorithm, like C<-sha1>. The function +option to be taken as digest algorithm, like C<-sha1>. The function opt_md() takes the specified I and fills in the digest into I. The functions opt_cipher(), opt_cipher_any() and opt_cipher_silent() each takes the specified I and fills in the cipher into I. @@ -324,7 +324,7 @@ things very differently. =head1 COPYRIGHT -Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file diff --git a/doc/internal/man3/OSSL_SAFE_MATH_SIGNED.pod b/doc/internal/man3/OSSL_SAFE_MATH_SIGNED.pod index 740555e6adb8a..6c78c3a447af3 100644 --- a/doc/internal/man3/OSSL_SAFE_MATH_SIGNED.pod +++ b/doc/internal/man3/OSSL_SAFE_MATH_SIGNED.pod @@ -99,7 +99,7 @@ The functions described here were all added in OpenSSL 3.2. =head1 COPYRIGHT -Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/internal/man3/evp_generic_fetch.pod b/doc/internal/man3/evp_generic_fetch.pod index 016494239e04e..5c43d751cd6e1 100644 --- a/doc/internal/man3/evp_generic_fetch.pod +++ b/doc/internal/man3/evp_generic_fetch.pod @@ -187,8 +187,7 @@ And here's the implementation of the FOO method fetcher: EVP_FOO *foo = vfoo; int ref = 0; - CRYPTO_UP_REF(&foo->refcnt, &ref); - return 1; + return CRYPTO_UP_REF(&foo->refcnt, &ref); } static void foo_free(void *vfoo) @@ -275,7 +274,7 @@ The functions described here were all added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/internal/man3/ossl_cmp_msg_check_update.pod b/doc/internal/man3/ossl_cmp_msg_check_update.pod index eab024749212c..4643be69b77b3 100644 --- a/doc/internal/man3/ossl_cmp_msg_check_update.pod +++ b/doc/internal/man3/ossl_cmp_msg_check_update.pod @@ -86,7 +86,7 @@ The OpenSSL CMP support was added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/internal/man3/ossl_rand_get_entropy.pod b/doc/internal/man3/ossl_rand_get_entropy.pod index be39369f2b700..746f634f80b0c 100644 --- a/doc/internal/man3/ossl_rand_get_entropy.pod +++ b/doc/internal/man3/ossl_rand_get_entropy.pod @@ -44,7 +44,15 @@ returned to the caller. ossl_rand_get_user_entropy() is the same as ossl_rand_get_entropy() except that it retrieves the seeding material from the library context's DRBG seed source. By default this is the operating system but it can -be changed by calling L. +be changed by calling L, via the B +configuration section or at build time by overriding +B. With strict seeding, enabled via the +B option of the B configuration section, used by +default for the B seed source or implied by an +B build, the seed source is instantiated on first +use and an error is returned when it cannot be used. Otherwise the +operating system entropy sources are used as a fallback while the seed +source has not been instantiated yet. ossl_rand_cleanup_entropy() cleanses and frees any storage allocated by ossl_rand_get_entropy(). The entropy buffer is pointed to by I @@ -64,8 +72,9 @@ buffer length returned to the caller. ossl_rand_get_user_nonce() is the same as ossl_rand_get_nonce() except that it retrieves the seeding material from the library context's DRBG -seed source. By default this is the operating system but it can be -changed by calling L. +seed source. The seed source is selected and instantiated in the same +way as for ossl_rand_get_user_entropy(), including the strict seeding +behaviour. ossl_rand_cleanup_nonce() cleanses and frees any storage allocated by ossl_rand_get_nonce() or ossl_rand_get_user_nonce(). The nonce buffer @@ -94,7 +103,7 @@ The remaining functions described here were all added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/internal/man3/x509v3_cache_extensions.pod b/doc/internal/man3/x509v3_cache_extensions.pod index cc0aeb6079a89..f01d1993a1069 100644 --- a/doc/internal/man3/x509v3_cache_extensions.pod +++ b/doc/internal/man3/x509v3_cache_extensions.pod @@ -16,11 +16,13 @@ x509v3_cache_extensions This function processes any X509v3 extensions present in an X509 object I and caches the result of that processing as well as further derived info, for instance whether the certificate is self-issued or has version X.509v1. -It computes the SHA1 digest of the certificate using the default library context -and property query string and stores the result in x->sha1_hash, -or on failure sets B in x->flags. -It sets B in x->flags if x->siginf was filled successfully, -which may not be possible if a referenced algorithm is unknown or not available. +It computes an internal-use fingerprint of the certificate, used only by +L and never exposed to callers, +independent of any library context or property query string, +and stores the result in x->fingerprint; +on failure (the certificate cannot be DER encoded, for instance because it is +still under construction, or memory allocation failed) it sets +B in x->flags instead. Many OpenSSL functions that use an X509 object call this function implicitly. =head1 RETURN VALUES diff --git a/doc/internal/man7/VERSION.pod b/doc/internal/man7/VERSION.pod index 8ffd836c13110..4b8e340d575cb 100644 --- a/doc/internal/man7/VERSION.pod +++ b/doc/internal/man7/VERSION.pod @@ -89,7 +89,7 @@ the string will be C<3.0.0>. =item $config{full_version} The fully loaded version number, a string composed from $config{version}, -$config{prerelease} and $config{build_metadata}. See See L for +$config{prerelease} and $config{build_metadata}. See L for a few examples. =back @@ -139,7 +139,7 @@ L =head1 COPYRIGHT -Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/internal/man7/build.info.pod b/doc/internal/man7/build.info.pod index de5bcb33c6955..353d4746ea99e 100644 --- a/doc/internal/man7/build.info.pod +++ b/doc/internal/man7/build.info.pod @@ -36,6 +36,10 @@ BIB<]=> I[B<=>I] ... BIB<]=> I ... +BIB<]=> I ... + +BIB<]=> I ... + B<$>IB<=>I =head1 DESCRIPTION @@ -563,6 +567,44 @@ Collects inclusion directories that will be used when building the I components (object files and whatever else). This is used at the discretion of the build file generators. +=item BIB<]> B<=> I ... + +Collects function names that should be wrapped when linking I, which +must be a program. Each I adds a C<-Wl,--wrap=>I flag +to the link command, so that references to I resolve to a +C<__wrap_>I symbol provided by I while the original is +still reachable as C<__real_>I. This depends on the C<--wrap> +feature of the GNU and BSD linkers, so B is only available on those +platforms (Linux and the BSDs). The Windows unit tests cannot use it and +intercept their functions in C code with Microsoft Detours instead, +selecting that support library with B (see below). + +B is used by the cmocka-based unit tests and implies the B +unit-test link set (see B below), so it also adds the cmocka +inclusion directory and link library to I; a separate B +statement is therefore not needed alongside it. + +=item BIB<]> B<=> I ... + +Declares that I, which must be a program, is a unit test, and +selects the unit-test support libraries it is linked against. Each +I is one of the recognised keywords B or B; any +other value is an error. + +For each selected library, the corresponding inclusion directory and link +library are added to I. These are configured with the +B<--with->IB<-include> and B<--with->IB<-lib> options; +without them, the library is expected on the compiler's and linker's +default search paths. + +The B link set is implied by B, so a test that uses B +does not need a B statement. An explicit B statement +is used when a test links a support library without B, most notably +the Windows tests, which combine B with B to intercept +calls at run time in place of the linker's C<--wrap> option: + + UNIT_TEST[crypto/bio/test_bss_dgram_win]=cmocka detours + =back =head2 Known attributes @@ -661,7 +703,7 @@ L =head1 COPYRIGHT -Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file diff --git a/doc/internal/man7/deprecation.pod b/doc/internal/man7/deprecation.pod index f27e664b49981..69f4cb9bee179 100644 --- a/doc/internal/man7/deprecation.pod +++ b/doc/internal/man7/deprecation.pod @@ -2,19 +2,19 @@ =head1 NAME -OPENSSL_NO_DEPRECATED_4_1, OSSL_DEPRECATEDIN_4_1, -OPENSSL_NO_DEPRECATED_4_0, OSSL_DEPRECATEDIN_4_0, -OPENSSL_NO_DEPRECATED_3_6, OSSL_DEPRECATEDIN_3_6, -OPENSSL_NO_DEPRECATED_3_5, OSSL_DEPRECATEDIN_3_5, -OPENSSL_NO_DEPRECATED_3_4, OSSL_DEPRECATEDIN_3_4, -OPENSSL_NO_DEPRECATED_3_1, OSSL_DEPRECATEDIN_3_1, -OPENSSL_NO_DEPRECATED_3_0, OSSL_DEPRECATEDIN_3_0, -OPENSSL_NO_DEPRECATED_1_1_1, OSSL_DEPRECATEDIN_1_1_1, -OPENSSL_NO_DEPRECATED_1_1_0, OSSL_DEPRECATEDIN_1_1_0, -OPENSSL_NO_DEPRECATED_1_0_2, OSSL_DEPRECATEDIN_1_0_2, -OPENSSL_NO_DEPRECATED_1_0_1, OSSL_DEPRECATEDIN_1_0_1, -OPENSSL_NO_DEPRECATED_1_0_0, OSSL_DEPRECATEDIN_1_0_0, -OPENSSL_NO_DEPRECATED_0_9_8, OSSL_DEPRECATEDIN_0_9_8, +OPENSSL_NO_DEPRECATED_4_1, OSSL_DEPRECATEDIN_4_1, OSSL_DEPRECATEDIN_4_1_FOR, +OPENSSL_NO_DEPRECATED_4_0, OSSL_DEPRECATEDIN_4_0, OSSL_DEPRECATEDIN_4_0_FOR, +OPENSSL_NO_DEPRECATED_3_6, OSSL_DEPRECATEDIN_3_6, OSSL_DEPRECATEDIN_3_6_FOR, +OPENSSL_NO_DEPRECATED_3_5, OSSL_DEPRECATEDIN_3_5, OSSL_DEPRECATEDIN_3_5_FOR, +OPENSSL_NO_DEPRECATED_3_4, OSSL_DEPRECATEDIN_3_4, OSSL_DEPRECATEDIN_3_4_FOR, +OPENSSL_NO_DEPRECATED_3_1, OSSL_DEPRECATEDIN_3_1, OSSL_DEPRECATEDIN_3_1_FOR, +OPENSSL_NO_DEPRECATED_3_0, OSSL_DEPRECATEDIN_3_0, OSSL_DEPRECATEDIN_3_0_FOR, +OPENSSL_NO_DEPRECATED_1_1_1, OSSL_DEPRECATEDIN_1_1_1, OSSL_DEPRECATEDIN_1_1_1_FOR, +OPENSSL_NO_DEPRECATED_1_1_0, OSSL_DEPRECATEDIN_1_1_0, OSSL_DEPRECATEDIN_1_1_0_FOR, +OPENSSL_NO_DEPRECATED_1_0_2, OSSL_DEPRECATEDIN_1_0_2, OSSL_DEPRECATEDIN_1_0_2_FOR, +OPENSSL_NO_DEPRECATED_1_0_1, OSSL_DEPRECATEDIN_1_0_1, OSSL_DEPRECATEDIN_1_0_1_FOR, +OPENSSL_NO_DEPRECATED_1_0_0, OSSL_DEPRECATEDIN_1_0_0, OSSL_DEPRECATEDIN_1_0_0_FOR, +OPENSSL_NO_DEPRECATED_0_9_8, OSSL_DEPRECATEDIN_0_9_8, OSSL_DEPRECATEDIN_0_9_8_FOR, deprecation - How to do deprecation =head1 DESCRIPTION @@ -34,7 +34,14 @@ configuration option C<--api>, or if the user chooses to do so, with L). Deprecation is done using attribute macros named -B>, used with any declaration it applies to. +B> and B_FOR>, +used with any declaration it applies to. +B_FOR>(I) is the preferable macro variant +to use, as it provides ability to communicate to the user (via the I +argument) the reason a particular symbol has been deprecated, and point out +the migration path; +I should be provided without leading spaces, without capitalisation +of the first word, and without a terminating period. Simulating removal is done with C<#ifndef> preprocessor guards using macros named B>. diff --git a/doc/internal/man7/ossl_rbtree.pod b/doc/internal/man7/ossl_rbtree.pod new file mode 100644 index 0000000000000..ce05729798ed2 --- /dev/null +++ b/doc/internal/man7/ossl_rbtree.pod @@ -0,0 +1,303 @@ +=pod + +=head1 NAME + +OSSL_RBT_PROTOTYPE, OSSL_RBT_GENERATE, OSSL_RBT_ENTRY, OSSL_RBT_HEAD, +OSSL_RBT_INITIALIZER, OSSL_RBT_ROOT, OSSL_RBT_EMPTY, OSSL_RBT_NEXT, +OSSL_RBT_PREV, OSSL_RBT_MIN, OSSL_RBT_MAX, OSSL_RBT_FIND, OSSL_RBT_NFIND, +OSSL_RBT_LEFT, OSSL_RBT_RIGHT, OSSL_RBT_PARENT, OSSL_RBT_SET_LEFT, +OSSL_RBT_SET_RIGHT, OSSL_RBT_SET_PARENT, OSSL_RBT_FOREACH, +OSSL_RBT_FOREACH_SAFE, OSSL_RBT_FOREACH_REVERSE, OSSL_RBT_FOREACH_REVERSE_SAFE, +OSSL_RBT_INIT, OSSL_RBT_INSERT, OSSL_RBT_REMOVE, +ossl_rbtree - implementation of red-black tree + +=head1 SYNOPSIS + + #include "internal/ossl_rbtree.h" + + /* int (*CMP)(const NODE_TYPE *, const NODE_TYPE *); */ + + OSSL_RBT_PROTOTYPE(NAME, NODE_TYPE, FIELD, CMP) + + OSSL_RBT_GENERATE(NAME, NODE_TYPE, FIELD, CMP); + + OSSL_RBT_ENTRY(NODE_TYPE) + + OSSL_RBT_HEAD(HEADNAME, NODE_TYPE) + + OSSL_RBT_INITIALIZER(OSSL_RBT_HEAD *head); + + struct NODE_TYPE * OSSL_RBT_ROOT(NAME, OSSL_RBT_HEAD *head); + + int OSSL_RBT_EMPTY(NAME, OSSL_RBT_HEAD *head); + + struct NODE_TYPE * OSSL_RBT_NEXT(NAME, struct NODE_TYPE *elm); + + struct NODE_TYPE * OSSL_RBT_PREV(NAME, struct NODE_TYPE *elm); + + struct NODE_TYPE * OSSL_RBT_MIN(NAME, OSSL_RBT_HEAD *head); + + struct NODE_TYPE * OSSL_RBT_MAX(NAME, OSSL_RBT_HEAD *head); + + struct NODE_TYPE * OSSL_RBT_FIND(NAME, OSSL_RBT_HEAD *head, struct NODE_TYPE *elm); + + struct NODE_TYPE * OSSL_RBT_NFIND(NAME, OSSL_RBT_HEAD *head, struct NODE_TYPE *elm); + + struct NODE_TYPE * OSSL_RBT_LEFT(NAME, struct NODE_TYPE *elm); + + struct NODE_TYPE * OSSL_RBT_RIGHT(NAME, struct NODE_TYPE *elm); + + struct NODE_TYPE * OSSL_RBT_PARENT(NAME, struct NODE_TYPE *elm); + + void OSSL_RBT_SET_LEFT(NAME, struct NODE_TYPE *elm, struct NODE_TYPE *left); + + void OSSL_RBT_SET_RIGHT(NAME, struct NODE_TYPE *elm, struct NODE_TYPE *right); + + void OSSL_RBT_SET_PARENT(NAME, struct NODE_TYPE *elm, struct NODE_TYPE *parent); + + OSSL_RBT_FOREACH(VARNAME, NAME, OSSL_RBT_HEAD *head); + + OSSL_RBT_FOREACH_SAFE(VARNAME, NAME, OSSL_RBT_HEAD *head, TEMP_VARNAME); + + OSSL_RBT_FOREACH_REVERSE(VARNAME, NAME, OSSL_RBT_HEAD *head); + + OSSL_RBT_FOREACH_REVERSE_SAFE(VARNAME, NAME, OSSL_RBT_HEAD *head, TEMP_VARNAME); + + void OSSL_RBT_INIT(NAME, OSSL_RBT_HEAD *head); + + struct NODE_TYPE * OSSL_RBT_INSERT(NAME, OSSL_RBT_HEAD *head, struct NODE_TYPE *elm); + + struct NODE_TYPE * OSSL_RBT_REMOVE(NAME, OSSL_RBT_HEAD *head, struct NODE_TYPE *elm); + +=head1 DESCRIPTION + +These macros define data structures for a red-black tree. +Every operation on a red-black tree is bounded as O(lg n). The maximum +height of a red-black tree is 2lg (n+1). + +In the macro definitions, B is the name tag of a user defined +structure that must contain a field named B, of type B. +The argument B is the name tag of a user defined +structure that must be declared using the macro OSSL_RBT_HEAD(). +The argument B has to be a unique name prefix for every +tree that is defined. + +The function prototypes are declared with B, +B. See the examples below for further +explanation of how these macros are used. + +A red-black tree is a binary search tree with the node color as an extra +attribute. It fulfills a set of conditions: + +=over 4 + +=item 1. +every search path from the root to a leaf consists of the same +number of black nodes, + +=item 2. +each red node (except for the root) has a black parent, + +=item 3. +each leaf node is black. + +=back + +A red-black tree is headed by a structure defined by the OSSL_RBT_HEAD macro. +An OSSL_RBT_HEAD structure is declared as follows: + + OSSL_RBT_HEAD(HEADNAME, NODE_TYPE) head; + +where B is the name of the structure to be defined, and B is the type of the elements to be inserted into the tree. + +The OSSL_RBT_ENTRY macro declares a structure that allows elements to be +connected in the tree. + +In order to use the functions that manipulate the tree structure, their +prototypes need to be declared with the OSSL_RBT_PROTOTYPE() macro, +where B is a unique identifier for this +particular tree. The B argument is the type of the structure that is +being managed by the tree. The B argument is the name of the element +defined by OSSL_RBT_ENTRY(). + +The function bodies are generated with the OSSL_RBT_GENERATE() macro. +These macros take the same arguments as the +OSSL_RBT_PROTOTYPE() macro, but should be used only once. + +Finally, the B argument is the name of a function used to compare +trees' nodes with each other. The function takes two arguments of type +B. If the first argument is smaller than the second, +the function returns a value smaller than zero. If they are equal, the +function returns zero. Otherwise, it should return a value greater than +zero. The compare function defines the order of the tree elements. + +The OSSL_RBT_INIT() macro initializes the tree referenced by B. + +The red-black tree can also be initialized statically by using the +OSSL_RBT_INITIALIZER() macro like this: + + OSSL_RBT_HEAD(HEADNAME, NODE_TYPE) head = OSSL_RBT_INITIALIZER(&head); + +The OSSL_RBT_INSERT() macro inserts the new element B into the tree pointed by B. +Upon success, NULL is returned. If a matching element already exists in the +tree, the insertion is aborted, and a pointer to the existing element is +returned. + +The OSSL_RBT_REMOVE() macro removes the element B from the tree pointed by +B. OSSL_RBT_REMOVE() returns B. + +The OSSL_RBT_LEFT() macro returns a pointer to the left child element of B +in a red-black tree of type B. + +The OSSL_RBT_RIGHT() macro returns a pointer to the right child element +of B in a red-black tree of type B. + +The OSSL_RBT_PARENT() macro returns a pointer to the parent element of B +in a red-black tree of type B. + +The OSSL_RBT_SET_LEFT() macro sets the left child pointer of element B +to B in a red-black tree of type B. + +The OSSL_RBT_SET_RIGHT() macro sets the right child pointer of element B +to B in a red-black tree of type B. + +The OSSL_RBT_SET_PARENT() macro sets the parent pointer of element B +to B in a red-black tree of type B. + +The OSSL_RBT_FIND() and OSSL_RBT_NFIND() macros can be used to find a particular +element in the tree. OSSL_RBT_FIND() finds the node with the same key as B. +OSSL_RBT_NFIND() finds the first node greater than or equal to the search key. + + struct NODE_TYPE find, *res; + find.key = 30; + res = OSSL_RBT_FIND(NAME, &head, &find); + +The OSSL_RBT_ROOT(), OSSL_RBT_MIN(), OSSL_RBT_MAX(), OSSL_RBT_NEXT(), and +OSSL_RBT_PREV() macros can be used to traverse the tree: + + for (np = OSSL_RBT_MIN(NAME, &head); np != NULL; np = OSSL_RBT_NEXT(NAME, &head, np)) + +Or, for simplicity, one can use the OSSL_RBT_FOREACH() or OSSL_RBT_FOREACH_REVERSE() +macros: + + OSSL_RBT_FOREACH(np, NAME, &head) + +The macros OSSL_RBT_FOREACH_SAFE() and OSSL_RBT_FOREACH_REVERSE_SAFE() traverse the +tree referenced by head in a forward or reverse direction respectively, +assigning each element in turn to B. However, unlike their unsafe +counterparts, they permit both the removal of B as well as freeing it +from within the loop safely without interfering with the traversal. + +The OSSL_RBT_EMPTY() macro should be used to check whether a red-black tree is +empty. + +=head1 EXAMPLES + +The following example demonstrates how to declare a red-black tree +holding integers. Values are inserted into it and the contents of the +tree are printed in order. Lastly, the internal structure of the tree +is printed. + + #include + #include + #include + + #include "internal/nelem.h" + #include "internal/ossl_rbtree.h" + + struct node { + OSSL_RBT_ENTRY(node) entry; + int i; + }; + + static int intcmp(const struct node *, const struct node *); + + OSSL_RBT_HEAD(inttree, node) head = OSSL_RBT_INITIALIZER(&head); + OSSL_RBT_PROTOTYPE(inttree, node, entry, intcmp) + OSSL_RBT_GENERATE(inttree, node, entry, intcmp); + + static const int testdata[] = { + 20, 16, 17, 13, 3, 6, 1, 8, 2, 4, + 10, 19, 5, 9, 12, 15, 18, 7, 11, 14 + }; + + static int intcmp(const struct node *e1, const struct node *e2) + { + return e1->i < e2->i ? -1 : e1->i > e2->i; + } + + static void print_tree(struct node *n) + { + struct node *left, *right; + + if (n == NULL) { + printf("nil"); + return; + } + + left = OSSL_RBT_LEFT(inttree, n); + right = OSSL_RBT_RIGHT(inttree, n); + + if (left == NULL && right == NULL) { + printf("%d", n->i); + } else { + printf("%d(", n->i); + print_tree(left); + printf(","); + print_tree(right); + printf(")"); + } + } + + int main(void) + { + size_t i; + struct node *n; + + for (i = 0; i < OSSL_NELEM(testdata); i++) { + if ((n = OPENSSL_malloc(sizeof(struct node))) == NULL) + err(1, NULL); + n->i = testdata[i]; + OSSL_RBT_INSERT(inttree, &head, n); + } + + OSSL_RBT_FOREACH (n, inttree, &head) { + printf("%d\n", n->i); + } + + print_tree(OSSL_RBT_ROOT(inttree, &head)); + printf("\n"); + + return 0; + } + +=head1 HISTORY + +The red-black tree implementation comes from David Gwynne. It can be found +here: L. OpenSSL project +obtained a permission from David Gwynne to license his work under +Apache License 2.0 + +Apart from B prefix, the API is compatible with implementation +done by Neils Provos for OpenBSD. + +The text in this manual page comes from C in OpenBSD, the text was +authored by Neils Provos (according to the commit history) + +The red-black tree implementation was added in OpenSSL 4.1. + +=head1 COPYRIGHT + +Copyright 2002 Niels Provos +All rights reserved. + +Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man1/CA.pl.pod b/doc/man1/CA.pl.pod index 3d7c644249934..3bcbcace9a3ea 100644 --- a/doc/man1/CA.pl.pod +++ b/doc/man1/CA.pl.pod @@ -191,7 +191,7 @@ L =head1 COPYRIGHT -Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man1/openssl-cms.pod.in b/doc/man1/openssl-cms.pod.in index 8da6ee02293f1..3226f49f4f532 100644 --- a/doc/man1/openssl-cms.pod.in +++ b/doc/man1/openssl-cms.pod.in @@ -64,8 +64,8 @@ Keys and password options: Encryption options: -[B<-originator> I] -[B<-recip> I] +[B<-originator> I|I] +[B<-recip> I|I] [I ...] [B<-I>] [B<-kekcipher> I] @@ -81,8 +81,8 @@ Encryption options: Signing options: [B<-md> I] -[B<-signer> I] -[B<-certfile> I] +[B<-signer> I|I] +[B<-certfile> I|I] [B<-cades>] [B<-nodetach>] [B<-nocerts>] @@ -104,6 +104,7 @@ Verification options: [B<-noverify>] [B<-nointern>] [B<-cades>] +[B<-verify_partial>] [B<-verify_retcode>] {- $OpenSSL::safe::opt_trust_synopsis -} @@ -359,8 +360,8 @@ B structures. The private key to use when signing or decrypting. This must match the corresponding certificate. If this option is not specified then the -private key must be included in the certificate file specified with -the B<-recip> or B<-signer> file. When signing this option can be used +private key must be included in the certificate specified with +the B<-recip> or B<-signer> option. When signing this option can be used multiple times to specify successive keys. =item B<-passin> I @@ -390,13 +391,13 @@ See L for details. =over 4 -=item B<-originator> I +=item B<-originator> I|I A certificate of the originator of the encrypted message. Necessary for decryption when Key Agreement is in use for a shared key. Currently, not allowed for encryption. -=item B<-recip> I +=item B<-recip> I|I When decrypting a message this specifies the certificate of the recipient. The certificate must match one of the recipients of the message. @@ -411,7 +412,7 @@ option. =item I ... This is an alternative to using the B<-recip> option when encrypting a message. -One or more certificate filenames may be given. +One or more certificates may be given. =item B<-I> @@ -480,16 +481,26 @@ and a digest algorithm required by the signing scheme will be used. This is the case for EdDSA (RFC 8419). For SLH-DSA (RFC 9814) and ML-DSA (RFC 9882), the scheme-suggested digest algorithm will only be used if none is given. -=item B<-signer> I +=item B<-signer> I|I -A signing certificate. When signing or resigning a message, this option can be +A signer certificate. When signing or resigning a message, this option can be used multiple times if more than one signer is required. -=item B<-certfile> I +=item B<-certfile> I|I + +Provide extra certificates. +When signing, these will be included with the message and can serve +both as candidate untrusted CA certificates for chain building in verification +and as fallback signer certificates. +When verifying, the provided certificates will be used for chain building +and take precedence over the signer certificates in the message +as a source of candidate signers. +With B<-nointern> these will be the only signer certificates considered. -Allows additional certificates to be specified. When signing these will -be included with the message. When verifying, these will be searched for -signer certificates and will be used for chain building. +Note that a message can have multiple signers. +In such cases, all signer certificates must be available. +When verifying a multi-signed message, all the signatures must be valid +unless B<-verify_partial> has been specified. The input can be in PEM, DER, or PKCS#12 format. @@ -509,9 +520,10 @@ the MIME type multipart/signed is used. =item B<-nocerts> -When signing a message the signer's certificate is normally included -with this option it is excluded. This will reduce the size of the -signed message but the verifier must have a copy of the signers certificate +When signing a message, the signer certificates are normally included, +but this option disables their inclusion. +This will reduce the size of the signed message, +but the verifier must then have a copy of those certificates available locally (passed using the B<-certfile> option for example). =item B<-noattr> @@ -554,8 +566,8 @@ option B but supplied if a signed receipt is requested. =item B<-signer> I -If a message has been verified successfully then the signers certificate(s) -will be written to this file if the verification was successful. +If a message has been verified successfully, then the signer certificate(s) +will be written to this file. =item B<-content> I @@ -583,16 +595,23 @@ Do not verify the signers certificate of a signed message. =item B<-nointern> -When verifying a message normally certificates (if any) included in -the message are searched for the signing certificate. With this option -only the certificates specified in the B<-certfile> option are used. -The supplied certificates can still be used as untrusted CAs however. +Normally, when verifying a message, the certificates (if any) included in +the message are searched for the signer certificates. With this option, +only the certificates given with the B<-certfile> option are used. +However, the certificates included in the message are still used +as candidate intermediate CA certificates during chain construction. =item B<-cades> When used with B<-verify>, require and check signer certificate digest. See the NOTES section for more details. +=item B<-verify_partial> + +Succeed if at least one signature can be verified. +Print info which signature verifications succeeded or failed in which +aspect(s). + =item B<-verify_retcode> Exit nonzero on verification failure. @@ -962,6 +981,8 @@ The B<-recip_kdf> and B<-recip_ukm> options were added in OpenSSL 3.6. The B<-engine> option was removed in OpenSSL 4.0. +The B<-verify_partial> option was added in OpenSSL 4.1. + =head1 COPYRIGHT Copyright 2008-2026 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man1/openssl-crl.pod.in b/doc/man1/openssl-crl.pod.in index 3d12d1700dbf2..c89cb2e15fa5e 100644 --- a/doc/man1/openssl-crl.pod.in +++ b/doc/man1/openssl-crl.pod.in @@ -179,7 +179,7 @@ Since OpenSSL 3.3, the B<-verify> option will exit with 1 on failure. =head1 COPYRIGHT -Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man1/openssl-dgst.pod.in b/doc/man1/openssl-dgst.pod.in index 73e439ad14445..2652675b42446 100644 --- a/doc/man1/openssl-dgst.pod.in +++ b/doc/man1/openssl-dgst.pod.in @@ -343,7 +343,7 @@ input. =head1 COPYRIGHT -Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man1/openssl-ec.pod.in b/doc/man1/openssl-ec.pod.in index 2fd397da00b3a..10fe19053c7b1 100644 --- a/doc/man1/openssl-ec.pod.in +++ b/doc/man1/openssl-ec.pod.in @@ -194,7 +194,7 @@ The B<-engine> option was removed in OpenSSL 4.0. =head1 COPYRIGHT -Copyright 2003-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2003-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man1/openssl-ecparam.pod.in b/doc/man1/openssl-ecparam.pod.in index d48f19d789cef..89bf7861736ac 100644 --- a/doc/man1/openssl-ecparam.pod.in +++ b/doc/man1/openssl-ecparam.pod.in @@ -173,7 +173,7 @@ The B<-engine> option was removed in OpenSSL 4.0. =head1 COPYRIGHT -Copyright 2003-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2003-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man1/openssl-format-options.pod b/doc/man1/openssl-format-options.pod index 2da9bef5efcc3..1bdb82efad511 100644 --- a/doc/man1/openssl-format-options.pod +++ b/doc/man1/openssl-format-options.pod @@ -60,6 +60,11 @@ is described in each command documentation. A binary format, encoded or parsed according to Distinguished Encoding Rules (DER) of the ASN.1 data language. +When a command reads a single DER object, it may stop after successfully +decoding that object. Any trailing data in the input is not necessarily +examined or rejected. Therefore, a successful command does not by itself +confirm that the entire input consists of one valid DER object. + =item B A DER-encoded file containing a PKCS#12 object. @@ -124,7 +129,7 @@ Note that the parsing is simple and might fail to parse some legal data. =head1 COPYRIGHT -Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man1/openssl-list.pod.in b/doc/man1/openssl-list.pod.in index 4b2582bf9db7d..3e3b3f0377402 100644 --- a/doc/man1/openssl-list.pod.in +++ b/doc/man1/openssl-list.pod.in @@ -309,7 +309,7 @@ The B<-engines> option was removed in OpenSSL 4.0. =head1 COPYRIGHT -Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man1/openssl-pkcs12.pod.in b/doc/man1/openssl-pkcs12.pod.in index ab49c95291d20..8cd57c381234d 100644 --- a/doc/man1/openssl-pkcs12.pod.in +++ b/doc/man1/openssl-pkcs12.pod.in @@ -104,14 +104,19 @@ Print out a usage message. =item B<-passin> I -The password source for the input, and for encrypting any private keys that -are output. +The password source for input files. With B<-export>, it is used to decrypt +the input private key. Otherwise, it is the password for the input PKCS#12 +file. For more information about the format of B see L. =item B<-passout> I -The password source for output files. +The password source for output files. With B<-export>, it is the password for +the output PKCS#12 file. Otherwise, it is used to encrypt any private keys that +are output. +For more information about the format of B +see L. =item B<-password> I @@ -490,7 +495,7 @@ The B<-engine> option was removed in OpenSSL 4.0. =head1 COPYRIGHT -Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man1/openssl-pkcs8.pod.in b/doc/man1/openssl-pkcs8.pod.in index 884a5d5a38fbf..de1438d97216c 100644 --- a/doc/man1/openssl-pkcs8.pod.in +++ b/doc/man1/openssl-pkcs8.pod.in @@ -287,7 +287,7 @@ The B<-engine> option was removed in OpenSSL 4.0. =head1 COPYRIGHT -Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man1/openssl-pkeyutl.pod.in b/doc/man1/openssl-pkeyutl.pod.in index 053385ca0b895..76394fb99606e 100644 --- a/doc/man1/openssl-pkeyutl.pod.in +++ b/doc/man1/openssl-pkeyutl.pod.in @@ -373,7 +373,7 @@ explicitly set in PSS mode then the signing digest is used. =item BI Sets the digest used for the OAEP hash function. If not explicitly set then -SHA256 is used. +SHA1 is used. =item BI @@ -677,8 +677,10 @@ L, =head1 HISTORY Since OpenSSL 3.5, -the B<-digest> option implies B<-rawin>, and these two options are -no longer required when signing or verifying with an Ed25519 or Ed448 key. +the B<-digest> option implies B<-rawin>. The B<-rawin> option is no longer +required when signing or verifying with a key type that does not support a +prehash digest, such as Ed25519, Ed448, ML-DSA, or SLH-DSA. For these key +types, B<-digest> is not supported. Also since OpenSSL 3.5, the B<-kemop> option is no longer required for any of the supported algorithms, the only supported B is now the default. @@ -692,7 +694,7 @@ without loading the entire file into memory. =head1 COPYRIGHT -Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man1/openssl-prime.pod.in b/doc/man1/openssl-prime.pod.in index f5b65fd7b245d..4bcb9f17ec3c9 100644 --- a/doc/man1/openssl-prime.pod.in +++ b/doc/man1/openssl-prime.pod.in @@ -69,7 +69,7 @@ This parameter is ignored. =head1 COPYRIGHT -Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man1/openssl-rand.pod.in b/doc/man1/openssl-rand.pod.in index 4d4cda2b4dd94..310d65946c404 100644 --- a/doc/man1/openssl-rand.pod.in +++ b/doc/man1/openssl-rand.pod.in @@ -79,7 +79,7 @@ The B<-engine> option was removed in OpenSSL 4.0. =head1 COPYRIGHT -Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man1/openssl-req.pod.in b/doc/man1/openssl-req.pod.in index d3d490a687a7e..0fcce9fff29bd 100644 --- a/doc/man1/openssl-req.pod.in +++ b/doc/man1/openssl-req.pod.in @@ -393,9 +393,9 @@ certificate requests. This allows several different sections to be used in the same configuration file to specify requests for a variety of purposes. -When signing a new CSR or X.509 certificate, if neither the the B<-extensions> +When signing a new CSR or X.509 certificate, if neither the B<-extensions> option nor its alias B<-reqexts> are specified, the name of the extension -section is taken from from C section of the configuration file. +section is taken from C section of the configuration file. Specifically, from the value of that section's C variable (for a CSR) or its C variable (for a certificate). If there is no setting for the variable (name/value assignment, see diff --git a/doc/man1/openssl-s_client.pod.in b/doc/man1/openssl-s_client.pod.in index 3257e9f68018f..d4c45b71ee640 100644 --- a/doc/man1/openssl-s_client.pod.in +++ b/doc/man1/openssl-s_client.pod.in @@ -29,10 +29,10 @@ B B {- $OpenSSL::safe::opt_trust_synopsis -} [B<-verifyCAfile> I] [B<-verifyCApath> I] -[B<-verifyCAstore> I] +[B<-verifyCAstore> I|I] [B<-chainCAfile> I] [B<-chainCApath> I] -[B<-chainCAstore> I] +[B<-chainCAstore> I|I] [B<-cert> I] [B<-certform> B|B|B] [B<-cert_chain> I] @@ -349,11 +349,11 @@ to trust for verifying the server's certificate. This directory must be in "hash format", see L for more information. -=item B<-verifyCAstore> I +=item B<-verifyCAstore> I|I -URI of a store containing CA certificates +The filename or URI of a store containing CA certificates to trust for verifying the server's certificate. -The URI may indicate a single certificate, as well as a collection of them. +May indicate a single certificate, as well as a collection of them. With URIs in the C scheme, this is generally treated like B<-verifyCApath> or B<-verifyCAfile>, depending on if the URI indicates a directory or a single file. See L for more information on stores and supported schemes. @@ -379,11 +379,11 @@ when attempting to build the client certificate chain provided to the server. This directory must be in "hash format", see L for more information. -=item B<-chainCAstore> I +=item B<-chainCAstore> I|I -The URI of a store containing trusted certificates to use +The filename or URI of a store containing trusted certificates to use when attempting to build the client certificate chain provided to the server. -The URI may indicate a single certificate, as well as a collection of them. +May indicate a single certificate, as well as a collection of them. With URIs in the C scheme, this is generally treated like B<-chainCApath> or B<-chainCAfile>, depending on whether the URI points to a directory or a single file. See L for more information on stores and supported schemes. @@ -392,7 +392,7 @@ See L for more information on stores and supported schemes. A file containing a list of certificates whose subject names will be sent to the server in the B extension. Only supported -for TLS 1.3 +for TLS 1.3 and DTLS 1.3 =item B<-dane_tlsa_domain> I @@ -555,8 +555,8 @@ input. This implicitly turns on B<-nocommands> as well. =item B<-quiet> -Inhibit printing of session and certificate information. This implicitly -turns on B<-ign_eof> and B<-nocommands> as well. +Inhibit printing any non-error-related information. This implicitly +turns on B<-ign_eof>, B<-nocommands> and B<-verify_quiet> as well. =item B<-no_ign_eof> @@ -578,13 +578,13 @@ This option must be provided in order to use a PSK cipher. =item B<-psk_session> I Use the pem encoded SSL_SESSION data stored in I as the basis of a PSK. -Note that this will only work if TLSv1.3 is negotiated. +Note that this will only work if (D)TLSv1.3 is negotiated. =item B<-sctp> Use SCTP for the transport protocol instead of UDP in DTLS. Must be used in -conjunction with B<-dtls>, B<-dtls1> or B<-dtls1_2>. This option is only -available where OpenSSL has support for SCTP enabled. +conjunction with B<-dtls>, B<-dtls1>, B<-dtls1_2> or B<-dtls1_3>. This option +is only available where OpenSSL has support for SCTP enabled. =item B<-sctp_label_bug> @@ -651,11 +651,11 @@ For more information on shutting down a connection, see L. =item B<-no_tx_cert_comp> -Disables support for sending TLSv1.3 compressed certificates. +Disables support for sending (D)TLSv1.3 compressed certificates. =item B<-no_rx_cert_comp> -Disables support for receiving TLSv1.3 compressed certificate. +Disables support for receiving (D)TLSv1.3 compressed certificate. =item B<-brief> @@ -744,7 +744,8 @@ The I list is a comma-separated list of protocol names that the client should advertise support for. The list should contain the most desirable protocols first. Protocol names are printable ASCII strings, for example "http/1.1" or "spdy/3". -The flag B<-nextprotoneg> cannot be specified if B<-tls1_3> is used. +The flag B<-nextprotoneg> cannot be specified if B<-tls1_3> or B<-dtls1_3> is +used. =item B<-ct>, B<-noct> @@ -774,8 +775,8 @@ data and when the server accepts the early data. =item B<-enable_pha> -For TLSv1.3 only, send the Post-Handshake Authentication extension. This will -happen whether or not a certificate has been provided via B<-cert>. +For (D)TLSv1.3 only, send the Post-Handshake Authentication extension. This +will happen whether or not a certificate has been provided via B<-cert>. =item B<-use_srtp> I @@ -955,7 +956,7 @@ End the current SSL connection and exit. =item B -Renegotiate the SSL session (TLSv1.2 and below only). +Renegotiate the SSL session ((D)TLSv1.2 and below only). =item B @@ -963,11 +964,11 @@ Attempt to reconnect to the server using a resumption handshake. =item B -Send a key update message to the server (TLSv1.3 only) +Send a key update message to the server ((D)TLSv1.3 only) =item B -Send a key update message to the server and request one back (TLSv1.3 only) +Send a key update message to the server and request one back ((D)TLSv1.3 only) =back @@ -1008,7 +1009,7 @@ Reconnect to the peer and attempt a resumption handshake =item B -Send a Key Update message. TLSv1.3 only. This command takes an optional +Send a Key Update message. (D)TLSv1.3 only. This command takes an optional argument. If the argument "req" is supplied then the peer is also requested to update its keys. Otherwise if "noreq" is supplied the peer is not requested to update its keys. The default is "req". diff --git a/doc/man1/openssl-s_server.pod.in b/doc/man1/openssl-s_server.pod.in index 2a295cac22264..8f5bcbfd0d238 100644 --- a/doc/man1/openssl-s_server.pod.in +++ b/doc/man1/openssl-s_server.pod.in @@ -62,10 +62,10 @@ B B [B<-crl_download>] [B<-chainCAfile> I] [B<-chainCApath> I] -[B<-chainCAstore> I] +[B<-chainCAstore> I|I] [B<-verifyCAfile> I] [B<-verifyCApath> I] -[B<-verifyCAstore> I] +[B<-verifyCAstore> I|I] [B<-no_cache>] [B<-ext_cache>] [B<-verify_return_error>] @@ -354,11 +354,11 @@ for verifying client certificates. This directory must be in "hash format", see L for more information. -=item B<-verifyCAstore> I +=item B<-verifyCAstore> I|I -URI of a store containing trusted certificates to use +The filename or URI of a store containing trusted certificates to use for verifying client certificates. -The URI may indicate a single certificate, as well as a collection of them. +May indicate a single certificate, as well as a collection of them. With URIs in the C scheme, this is generally treated like B<-verifyCApath> or B<-verifyCAfile>, depending on whether the URI points to a directory or a single file. See L for more information on stores and supported schemes. @@ -383,11 +383,11 @@ for building the server certificate chain provided to the client. This directory must be in "hash format", see L for more information. -=item B<-chainCAstore> I +=item B<-chainCAstore> I|I -The URI of a store containing trusted certificates to use +The filename or URI of a store containing trusted certificates to use for building the server certificate chain provided to the client. -The URI may indicate a single certificate, as well as a collection of them. +May indicate a single certificate, as well as a collection of them. With URIs in the C scheme, this is generally treated like B<-chainCApath> or B<-chainCAfile>, depending on whether the URI points to a directory or a single file. See L for more information on stores and supported schemes. @@ -617,11 +617,11 @@ further information). =item B<-no_tx_cert_comp> -Disables support for sending TLSv1.3 compressed certificates. +Disables support for sending (D)TLSv1.3 compressed certificates. =item B<-no_rx_cert_comp> -Disables support for receiving TLSv1.3 compressed certificates. +Disables support for receiving (D)TLSv1.3 compressed certificates. =item B<-no_comp> @@ -632,8 +632,8 @@ OpenSSL 1.1.0. =item B<-num_tickets> Control the number of tickets that will be sent to the client after a full -handshake in TLSv1.3. The default number of tickets is 2. This option does not -affect the number of tickets sent after a resumption handshake. +handshake in (D)TLSv1.3. The default number of tickets is 2. This option does +not affect the number of tickets sent after a resumption handshake. =item B<-dhparam> I @@ -701,8 +701,8 @@ connect to that peer and complete the handshake. =item B<-sctp> Use SCTP for the transport protocol instead of UDP in DTLS. Must be used in -conjunction with B<-dtls>, B<-dtls1> or B<-dtls1_2>. This option is only -available where OpenSSL has support for SCTP enabled. +conjunction with B<-dtls>, B<-dtls1>, B<-dtls1_2> or B<-dtls1_3>. This option +is only available where OpenSSL has support for SCTP enabled. =item B<-sctp_label_bug> @@ -730,7 +730,8 @@ The I list is a comma-separated list of supported protocol names. The list should contain the most desirable protocols first. Protocol names are printable ASCII strings, for example "http/1.1" or "spdy/3". -The flag B<-nextprotoneg> cannot be specified if B<-tls1_3> is used. +The flag B<-nextprotoneg> cannot be specified if B<-tls1_3> or B<-dtls1_3> +is used. =item B<-ktls> @@ -778,16 +779,16 @@ B<-WWW>, B<-HTTP> or B<-rev>. =item B<-stateless> -Require TLSv1.3 cookies. +Require (D)TLSv1.3 cookies. =item B<-anti_replay>, B<-no_anti_replay> Switches replay protection on or off, respectively. Replay protection is on by default unless overridden by a configuration file. When it is on, OpenSSL will -automatically detect if a session ticket has been used more than once, TLSv1.3 -has been negotiated, and early data is enabled on the server. A full handshake -is forced if a session ticket is used a second or subsequent time. Any early -data that was sent will be rejected. +automatically detect if a session ticket has been used more than once, +(D)TLSv1.3 has been negotiated, and early data is enabled on the server. A full +handshake is forced if a session ticket is used a second or subsequent time. +Any early data that was sent will be rejected. Note that the server manages an internal cache of session tickets. If a client closes the connection without sending the close_notify alert, the @@ -919,12 +920,12 @@ End the current SSL connection and exit. =item B -Renegotiate the SSL session (TLSv1.2 and below only). +Renegotiate the SSL session ((D)TLSv1.2 and below only). =item B -Renegotiate the SSL session and request a client certificate (TLSv1.2 and below -only). +Renegotiate the SSL session and request a client certificate ((D)TLSv1.2 and +below only). =item B

@@ -937,15 +938,15 @@ Print out some session cache status information. =item B -Send a key update message to the client (TLSv1.3 only) +Send a key update message to the client ((D)TLSv1.3 only). =item B -Send a key update message to the client and request one back (TLSv1.3 only) +Send a key update message to the client and request one back ((D)TLSv1.3 only). =item B -Send a certificate request to the client (TLSv1.3 only) +Send a certificate request to the client ((D)TLSv1.3 only). =back diff --git a/doc/man1/openssl-smime.pod.in b/doc/man1/openssl-smime.pod.in index 498d0c57251fa..c25528f8eaabb 100644 --- a/doc/man1/openssl-smime.pod.in +++ b/doc/man1/openssl-smime.pod.in @@ -19,8 +19,8 @@ B B [B<-crlfeol>] [B<-I>] [B<-in> I] -[B<-certfile> I] -[B<-signer> I] +[B<-certfile> I|I] +[B<-signer> I|I] [B<-nointern>] [B<-noverify>] [B<-nochain>] @@ -29,7 +29,7 @@ B B [B<-noattr>] [B<-nodetach>] [B<-nosmimecap>] -[B<-recip> I< file>] +[B<-recip> I|I] [B<-inform> B|B|B] [B<-outform> B|B|B] [B<-keyform> B|B|B] @@ -100,6 +100,10 @@ Resign a message: take an existing message and one or more new signers. Verify signed mail. Expects a signed mail message on input and outputs the signed data. Both clear text and opaque signing is supported. +Unless B<-nochain> is specified, validation of signer certificates and their +chain is done by default w.r.t. the S/MIME signing (C) purpose. +For details see L. + =item B<-pk7out> Takes an input message and writes out a PEM encoded PKCS#7 structure. @@ -178,10 +182,12 @@ If not specified, AES-256-CBC is used as the default. Only used with B<-encrypt> =item B<-nointern> -When verifying a message normally certificates (if any) included in -the message are searched for the signing certificate. With this option -only the certificates specified in the B<-certfile> option are used. -The supplied certificates can still be used as untrusted CAs however. +Normally, when verifying a message, the certificates (if any) included in +the message are searched for the signer certificates. With this option, +only the certificates given with the B<-certfile> option are used. +However, the certificates included in the message are still used +as candidate intermediate CA certificates during chain construction +unless B<-nochain> is also specified. =item B<-noverify> @@ -189,8 +195,10 @@ Do not verify the signers certificate of a signed message. =item B<-nochain> -Do not do chain verification of signers certificates; that is, do not -use the certificates in the signed message as untrusted CAs. +When verifying the signer certificates of a signed message, do not use the +certificates in the message as candidate CA certificates for chain building. +This also disables the default use of the S/MIME signing (C) purpose. +To re-enable it, B<-purpose smimesign> can be specified. =item B<-nosigs> @@ -198,11 +206,19 @@ Don't try to verify the signatures on the message. =item B<-nocerts> -When signing a message, the signer's certificate is normally included. -With this option it is excluded. This will reduce the size of the -signed message, but the verifier must have a copy of the signers certificate +When signing a message, the signer certificates are normally included, +but this option disables their inclusion. +This will reduce the size of the signed message, +but the verifier must have a copy of those certificates available locally (passed using the B<-certfile> option for example). +With the -sign operation, +setting this option has special effect on any extra certificates supplied via the +B<-certfile> option: while signer certificates supplied via the B<-signer> option are +not included, the extra certificates from B<-certfile> are included in the given order. +This can be used to specify the order certificates appear in the PKCS#7 structure +as a workaround for broken applications that require a certain ordering. + =item B<-noattr> Normally, when a message is signed, a set of attributes are included which @@ -232,22 +248,32 @@ is useful when handling binary data which may not be in MIME format. Normally the output file uses a single B as end of line. When this option is present B is used instead. -=item B<-certfile> I +=item B<-certfile> I|I + +Provide extra certificates. +When signing, these will be included with the message and can serve +both as candidate untrusted CA certificates for chain building in verification +and as fallback signer certificates. +When verifying, the provided certificates will be used for chain building +and take precedence over the signer certificates in the message +as a source of candidate signers. +With B<-nointern> these will be the only signer certificates considered. -Allows additional certificates to be specified. When signing these will -be included with the message. When verifying, these will be searched for -signer certificates and will be used for chain building. +Note that a message can have multiple signers. +When verifying a multi-signed message, all the signatures must be valid, +and so all the signer certificates need to be available. The input can be in PEM, DER, or PKCS#12 format. -=item B<-signer> I +=item B<-signer> I|I -A signing certificate when signing or resigning a message, this option can be -used multiple times if more than one signer is required. If a message is being -verified then the signers certificates will be written to this file if the -verification was successful. +A signer certificate. When signing or resigning a message, this option can be +used multiple times if more than one signer is required. +If a message has been verified successfully, then the signer certificate(s) +will be written to this file. +In the verification case, the option argument format I cannot be used. -=item B<-recip> I +=item B<-recip> I|I The recipients certificate when decrypting a message. This certificate must match one of the recipients of the message or an error occurs. @@ -257,7 +283,7 @@ must match one of the recipients of the message or an error occurs. The private key to use when signing or decrypting. This must match the corresponding certificate. If this option is not specified then the private key must be included in the certificate file specified with -the B<-recip> or B<-signer> file. When signing this option can be used +the B<-recip> or B<-signer> option. When signing this option can be used multiple times to specify successive keys. =item B<-passin> I @@ -456,7 +482,7 @@ algorithms as supplied in the SMIMECapabilities signed attribute. This means the user has to manually include the correct encryption algorithm. It should store the list of permitted ciphers in a database and only use those. -No revocation checking is done on the signer's certificate. +No revocation checking is done on signer certificates. The current code can only handle S/MIME v2 messages, the more complex S/MIME v3 structures may cause parsing errors. @@ -478,7 +504,7 @@ The B<-engine> option was removed in OpenSSL 4.0. =head1 COPYRIGHT -Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man1/openssl-ts.pod.in b/doc/man1/openssl-ts.pod.in index d7493f6bb249b..86f1c5d5236c7 100644 --- a/doc/man1/openssl-ts.pod.in +++ b/doc/man1/openssl-ts.pod.in @@ -55,7 +55,7 @@ B<-verify> [B<-untrusted> I|I] [B<-CAfile> I] [B<-CApath> I

] -[B<-CAstore> I] +[B<-CAstore> I|I] {- $OpenSSL::safe::opt_v_synopsis -} {- $OpenSSL::safe::opt_provider_synopsis -} @@ -347,7 +347,7 @@ certificates as far as the response already includes them. Multiple sources may be given, separated by commas and/or whitespace. Each file may contain multiple certificates. -=item B<-CAfile> I, B<-CApath> I, B<-CAstore> I +=item B<-CAfile> I, B<-CApath> I, B<-CAstore> I|I See L for details. At least one of B<-CAfile>, B<-CApath> or B<-CAstore> must be specified. diff --git a/doc/man1/openssl-verification-options.pod b/doc/man1/openssl-verification-options.pod index e330f8f015074..09d6de75b74a4 100644 --- a/doc/man1/openssl-verification-options.pod +++ b/doc/man1/openssl-verification-options.pod @@ -302,10 +302,10 @@ See L for information on creating this type of directory. Do not use the default directory of trusted certificates. -=item B<-CAstore> I +=item B<-CAstore> I|I -Use I as a store of trusted certificates. -The URI may indicate a single certificate or a collection of them. +Use I or I as a store of trusted certificates. +May indicate a single certificate or a collection of them. When the URI references a file, only the PEM format is supported. With URIs in the C scheme, this is generally treated like B<-CApath> or B<-CAfile>, depending on whether the URI indicates a directory or a single file. diff --git a/doc/man1/openssl.pod b/doc/man1/openssl.pod index 27f1d3c88e735..a227847a4649a 100644 --- a/doc/man1/openssl.pod +++ b/doc/man1/openssl.pod @@ -611,12 +611,12 @@ the B options. The B options do not work with B and B commands but work with B and B commands. -=item B<-dtls>, B<-dtls1>, B<-dtls1_2> +=item B<-dtls>, B<-dtls1>, B<-dtls1_2>, B<-dtls1_3> These options specify to use DTLS instead of TLS. With B<-dtls>, clients will negotiate any supported DTLS protocol version. -Use the B<-dtls1> or B<-dtls1_2> options to support only DTLS1.0 or DTLS1.2, -respectively. +Use the B<-dtls1>, B<-dtls1_2> or B<-dtls1_3> options to support only DTLS1.0, +DTLS1.2 or DTLS1.3 respectively. =back @@ -678,8 +678,8 @@ For information about specific commands, see L and L. For information about querying or specifying CPU architecture flags, see -L, L, L, -and L. +L, L, L, +L and L. =head1 SEE ALSO diff --git a/doc/man1/tsget.pod b/doc/man1/tsget.pod index 66c0ba6299f36..84919a528ee82 100644 --- a/doc/man1/tsget.pod +++ b/doc/man1/tsget.pod @@ -76,7 +76,7 @@ error. (Optional) =for comment perlpodstyle(1) says to refer to modules without section -Switches on verbose mode for the underlying perl module L. +Switches on verbose mode for the underlying perl module L. You can see detailed debug messages for the connection. (Optional) =item B<-k> I @@ -95,7 +95,7 @@ it will be prompted for. (Optional) =item B<-c> I (HTTPS) In case of certificate-based client authentication over HTTPS -I must contain the X.509 certificate of the user. The B<-k> +I must contain the X.509 certificate of the user. The B<-k> option must also be specified. If this option is not specified no certificate-based client authentication will take place. (Optional) @@ -123,8 +123,7 @@ The name of an EGD socket to get random data from. (Optional) List of files containing RFC 3161 DER-encoded timestamp requests. If no requests are specified only one request will be sent to the server and it will -be read from the standard input. -(Optional) +be read from the standard input. (Optional) =back @@ -183,16 +182,16 @@ example: =head1 SEE ALSO -=for openssl foreign manual WWW::Curl::Easy +=for openssl foreign manual Net::Curl::Easy L, L, -L, +L, L =head1 COPYRIGHT -Copyright 2006-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/ADMISSIONS.pod b/doc/man3/ADMISSIONS.pod index d4db385d9b9b7..b6335cb735505 100644 --- a/doc/man3/ADMISSIONS.pod +++ b/doc/man3/ADMISSIONS.pod @@ -169,7 +169,7 @@ L, =head1 COPYRIGHT -Copyright 2017-2018 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/ASN1_INTEGER_get_int64.pod b/doc/man3/ASN1_INTEGER_get_int64.pod index d25c87a5e25c2..69fff46460f25 100644 --- a/doc/man3/ASN1_INTEGER_get_int64.pod +++ b/doc/man3/ASN1_INTEGER_get_int64.pod @@ -123,7 +123,7 @@ were added in OpenSSL 1.1.0. =head1 COPYRIGHT -Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/ASN1_STRING_length.pod b/doc/man3/ASN1_STRING_length.pod index 47cacb253a0c8..74b37b03334b4 100644 --- a/doc/man3/ASN1_STRING_length.pod +++ b/doc/man3/ASN1_STRING_length.pod @@ -2,6 +2,7 @@ =head1 NAME +ASN1_STRING_set1_data, ASN1_STRING_set1_string, ASN1_STRING_get_length, ASN1_STRING_dup, ASN1_STRING_cmp, ASN1_STRING_set, ASN1_STRING_length, ASN1_STRING_type, ASN1_STRING_get0_data, ASN1_STRING_to_UTF8 - ASN1_STRING utility functions @@ -10,19 +11,30 @@ ASN1_STRING_to_UTF8 - ASN1_STRING utility functions #include - int ASN1_STRING_length(ASN1_STRING *x); const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x); ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a); int ASN1_STRING_cmp(ASN1_STRING *a, ASN1_STRING *b); - int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); - int ASN1_STRING_type(const ASN1_STRING *x); int ASN1_STRING_to_UTF8(unsigned char **out, const ASN1_STRING *in); + int ASN1_STRING_set1_data(ASN1_STRING *str, const uint8_t *data, size_t len); + + int ASN1_STRING_set1_string(ASN1_STRING *str, const char *data); + + size_t ASN1_STRING_get_length(const ASN1_STRING *x); + +The following functions have been deprecated since OpenSSL 4.1, and can be +hidden entirely by defining B with a suitable version value, +see L: + + int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); + + int ASN1_STRING_length(ASN1_STRING *x); + =head1 DESCRIPTION These functions allow an B structure to be manipulated. @@ -38,17 +50,35 @@ ASN1_STRING_dup() returns a copy of the structure I. ASN1_STRING_cmp() compares I and I returning 0 if the two are identical. The string types and content are compared. -ASN1_STRING_set() sets the data of string I to the buffer -I or length I. The supplied data is copied. If I -is -1 then the length is determined by strlen(data). +ASN1_STRING_set() allocates memory for string I to hold I +bytes of data. Any previously allocated memory owned by I will be +freed or re-used. If I is not NULL, I bytes are copied +from the memory pointed to by I to I. If I is -1 then +the length is determined by strlen(data). + +ASN1_STRING_set1_data() allocates memory for string I to hold +I bytes of data. Any previously allocated memory owned by I +will be freed or re-used. If I is not NULL, I bytes are +copied from the memory pointed to by I to I. It is an error +to use this function on a string of type B. + +ASN1_STRING_set1_string() allocates memory for the string I and makes +a copy of the characters from I. Any previously +allocated memory owned by I will be freed or re-used. I +must point to a valid NUL-terminated C string, and must not be +NULL. The terminating NUL byte is not included in the data copied into +I. It is an error to use this function on a string of type +B. ASN1_STRING_type() returns the type of I, using standard constants such as B. ASN1_STRING_to_UTF8() converts the string I to UTF8 format, the -converted data is allocated in a buffer in I<*out>. The length of +converted data is allocated in a buffer in I<*out>. The buffer is NUL +terminated, so it is a valid C string, but the returned length does not +include the terminating NUL. The length of I is returned or a negative error code. The buffer I<*out> -should be freed using OPENSSL_free(). +should be freed using OPENSSL_free(). See L below. =head1 NOTES @@ -70,8 +100,19 @@ actual string type itself: for example for an IA5String the data will be ASCII, for a BMPString two bytes per character in big endian format, and for a UTF8String it will be in UTF8 format. -Similar care should be take to ensure the data is in the correct format -when calling ASN1_STRING_set(). +Similar care should be taken to ensure the data is in the correct +format when calling ASN1_STRING_set(), ASN1_STRING_set1_data(), or +ASN1_STRING_set1_string(). + +=head1 WARNINGS + +Although the buffer returned by ASN1_STRING_to_UTF8() is NUL terminated and +is therefore a valid C string, the converted data may itself contain embedded +NUL bytes. Using C string functions such as strlen() or strcmp() on +the output is therefore inherently dangerous: they will stop at the first +embedded NUL and silently process only part of the string, which can lead to +incorrect comparisons or truncated data. Callers should use the returned +length and not rely on NUL termination. =head1 RETURN VALUES @@ -86,7 +127,8 @@ error occurred. ASN1_STRING_cmp() returns an integer greater than, equal to, or less than 0, according to whether I is greater than, equal to, or less than I. -ASN1_STRING_set() returns 1 on success or 0 on error. +ASN1_STRING_set(), ASN1_STRING_set1_data(), and +ASN1_STRING_set1_string() return 1 on success or 0 on error or failure. ASN1_STRING_type() returns the type of I. @@ -97,9 +139,14 @@ negative value if an error occurred. L +=head1 HISTORY + +ASN1_STRING_set1_data(), ASN1_STRING_set1_string(), and ASN1_STRING_get_length() +were added in OpenSSL 4.1. + =head1 COPYRIGHT -Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/ASN1_STRING_new.pod b/doc/man3/ASN1_STRING_new.pod index 7698f7411e380..0747d6c7cea0e 100644 --- a/doc/man3/ASN1_STRING_new.pod +++ b/doc/man3/ASN1_STRING_new.pod @@ -63,7 +63,7 @@ ASN1_STRING_new_not_owned() was added in OpenSSL 4.1. =head1 COPYRIGHT -Copyright 2002-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/ASN1_aux_cb.pod b/doc/man3/ASN1_aux_cb.pod index 9a38ab168ff31..865d188bc2db1 100644 --- a/doc/man3/ASN1_aux_cb.pod +++ b/doc/man3/ASN1_aux_cb.pod @@ -223,6 +223,16 @@ Invoked in order to obtain the property query string associated with an B if any. A pointer to the property query string should be stored in I<*exarg> if such a value exists. +=item B + +Invoked while setting up indefinite length streaming, after +B, in order to obtain the content octet string of the +B being streamed. A pointer to the B should be stored +in I<*exarg> if such a value exists. The caller marks that string for +indefinite length encoding and records the position of the content in it on +every encoding pass, so it must remain valid for as long as the streaming +B is in use. + =back An B object is used during processing of B @@ -261,7 +271,9 @@ The B with filters appended =item I -The streaming I/O boundary. +The streaming I/O boundary. This field is no longer used: the position of the +content is taken from the content octet string obtained with +B. =back @@ -312,9 +324,11 @@ L The ASN1_aux_const_cb() callback and the B and B operation types were added in OpenSSL 3.0. +The B operation type was added in OpenSSL 4.1. + =head1 COPYRIGHT -Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/BIO_f_buffer.pod b/doc/man3/BIO_f_buffer.pod index 2eb6e8eab1a52..cd23ddfb3209f 100644 --- a/doc/man3/BIO_f_buffer.pod +++ b/doc/man3/BIO_f_buffer.pod @@ -70,6 +70,34 @@ whenever any pending data should be written such as when removing a buffering BIO using BIO_pop(). BIO_flush() may need to be retried if the ultimate source/sink BIO is non blocking. +=head2 BIO_sendmmsg() behaviour + +The buffering BIO provides an implementation of BIO_sendmmsg() with behaviour +that differs significantly from the general BIO_sendmmsg() contract described in +L. + +B Unlike a caller that might expect N individually +buffered messages to be replayed as N separate messages on flush, the buffering +BIO I the payload bytes of all messages into its single write +buffer. When the buffer is flushed (either because it is full or because +BIO_flush() is called), all accumulated bytes are delivered to the next BIO as a +single datagram via BIO_sendmmsg(). The same applies within a single call: if +B is greater than 1, the payload data of every message in the array is +appended to the write buffer in order, and they will all be emitted together in +the next flush. Callers should take care that the total coalesced size does not +exceed the maximum datagram size of the underlying transport. + +B The destination address is taken from the peer field of the +first message of the first call after a flush. It remains fixed for the entire +flush cycle and is cleared automatically after each successful flush so that +subsequent calls may supply a new peer address. + +B The general BIO_sendmmsg() documentation states that +concurrent readers and writers on the same BIO are permitted. That guarantee +does B apply to the buffering BIO implementation. BIO_sendmmsg() on a +buffering BIO is B thread-safe; callers must not invoke it concurrently on +the same BIO object. + =head1 RETURN VALUES BIO_f_buffer() returns the buffering BIO method. @@ -93,7 +121,7 @@ L. =head1 COPYRIGHT -Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/BIO_f_ssl.pod b/doc/man3/BIO_f_ssl.pod index 000f34e9e9401..051a36efb96b9 100644 --- a/doc/man3/BIO_f_ssl.pod +++ b/doc/man3/BIO_f_ssl.pod @@ -303,7 +303,7 @@ be modified to handle this fix or they may free up an already freed BIO. =head1 COPYRIGHT -Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/BIO_printf.pod b/doc/man3/BIO_printf.pod index 221881d123cab..6d85ec8a05dc6 100644 --- a/doc/man3/BIO_printf.pod +++ b/doc/man3/BIO_printf.pod @@ -12,6 +12,10 @@ BIO_printf, BIO_vprintf, BIO_snprintf, BIO_vsnprintf int BIO_printf(BIO *bio, const char *format, ...); int BIO_vprintf(BIO *bio, const char *format, va_list args); +Deprecated since OpenSSL 4.1, can be hidden entirely by defining +B with a suitable version value, see +L: + int BIO_snprintf(char *buf, size_t n, const char *format, ...); int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args); @@ -26,28 +30,46 @@ the output is sent to the specified BIO, I, rather than standard output. All common format specifiers are supported. The argument list I is a stdarg argument list. -BIO_snprintf() is for platforms that do not have the common snprintf() -function. It is like sprintf() except that the size parameter, I, -specifies the size of the output buffer. - -BIO_vsnprintf() is to BIO_snprintf() as BIO_vprintf() is to BIO_printf(). +BIO_snprintf() and BIO_vsnprintf() were provided when not every supported +platform shipped a C99 snprintf() implementation. That is no longer the +case: every supported build target provides C99 snprintf(), and new code +should use the standard library functions directly. BIO_snprintf() and +BIO_vsnprintf() are retained for source compatibility but are deprecated +as of OpenSSL 4.1. + +BIO_snprintf() and BIO_vsnprintf() have the same signatures as snprintf() +and vsnprintf() but they do not have the same return value on truncation. +When the formatted output would exceed I bytes, snprintf() returns the +number of bytes that would have been written had the buffer been large +enough, while BIO_snprintf() and BIO_vsnprintf() return -1. Because the +functions look identical at the call site, callers reach for the standard +C99 idiom by reflex, and the divergence becomes a source of bugs. New +code should call snprintf() and vsnprintf() directly. =head1 RETURN VALUES -All functions return the number of bytes written, or -1 on error. -For BIO_snprintf() and BIO_vsnprintf() this includes when the output -buffer is too small. +BIO_printf() and BIO_vprintf() return the number of bytes written, or +-1 on error. + +BIO_snprintf() and BIO_vsnprintf() return the number of bytes written to +I (excluding the terminating C<'\0'>) on success, or -1 if the +formatted output would not fit in I bytes or on other error. =head1 NOTES -Except when I is 0, both BIO_snprintf() and BIO_vsnprintf() always -terminate their output with C<'\0'>. This includes cases where -1 is -returned, such as when there is insufficient space to output the whole -string. +When I is greater than 0, BIO_snprintf() and BIO_vsnprintf() always +terminate I with C<'\0'>, including in the truncation case where -1 +is returned. + +=head1 HISTORY + +BIO_snprintf() and BIO_vsnprintf() were deprecated in OpenSSL 4.1. Callers +should use the standard C library functions snprintf() and vsnprintf() +instead. =head1 COPYRIGHT -Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/BIO_push.pod b/doc/man3/BIO_push.pod index 8170a48c0cea2..739c2f1b855d5 100644 --- a/doc/man3/BIO_push.pod +++ b/doc/man3/BIO_push.pod @@ -88,7 +88,7 @@ The BIO_set_next() function was added in OpenSSL 1.1.0. =head1 COPYRIGHT -Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/BIO_s_bio.pod b/doc/man3/BIO_s_bio.pod index 482edfcfc89b9..494b3632ee930 100644 --- a/doc/man3/BIO_s_bio.pod +++ b/doc/man3/BIO_s_bio.pod @@ -270,7 +270,7 @@ L, L =head1 COPYRIGHT -Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/BIO_s_datagram.pod b/doc/man3/BIO_s_datagram.pod index b28dcf088c0b8..dc25a6750286f 100644 --- a/doc/man3/BIO_s_datagram.pod +++ b/doc/man3/BIO_s_datagram.pod @@ -264,7 +264,7 @@ BIO_dgram_detect_peer_addr() was added in OpenSSL 3.2. =head1 COPYRIGHT -Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/BIO_s_dgram_pair.pod b/doc/man3/BIO_s_dgram_pair.pod index 4d7dc8d5ac07a..0df30f00991f6 100644 --- a/doc/man3/BIO_s_dgram_pair.pod +++ b/doc/man3/BIO_s_dgram_pair.pod @@ -55,7 +55,10 @@ The two BIOs must both use the method returned by BIO_s_dgram_pair() and neither of the BIOs may currently be associated in a pair. L destroys the association between two connected BIOs. -Freeing either half of the pair will automatically destroy the association. +Freeing either half of the pair will automatically destroy the association. This +destruction is implied if L is used to free one half of a BIO pair. +Note that the other half of the BIO pair in such a situation may be joined to a +new BIO, but only after calling L on itself. L clears any data in the write buffer of the given BIO. This means that the opposite BIO in the pair will no longer have any data waiting to be diff --git a/doc/man3/BIO_s_file.pod b/doc/man3/BIO_s_file.pod index 6cd1da02a3eae..3b867aa6efa86 100644 --- a/doc/man3/BIO_s_file.pod +++ b/doc/man3/BIO_s_file.pod @@ -157,7 +157,7 @@ L, L =head1 COPYRIGHT -Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/BIO_sendmmsg.pod b/doc/man3/BIO_sendmmsg.pod index 5c13e566650fa..b81f37a98a013 100644 --- a/doc/man3/BIO_sendmmsg.pod +++ b/doc/man3/BIO_sendmmsg.pod @@ -132,6 +132,13 @@ always process at most one message at a time, for example when OS-level functionality to transmit or receive multiple messages at a time is not available. +The thread-safety guarantee stated above is the default for all BIO types +that support BIO_sendmmsg() unless stated otherwise in the documentation +for the BIO. The buffering BIO returned by L is one example +where this guarantee does not apply: its BIO_sendmmsg() implementation is +not thread-safe and its semantics differ significantly from those described here; +see L for details. + =head1 RETURN VALUES On success, the functions BIO_sendmmsg() and BIO_recvmmsg() return 1 and write @@ -219,7 +226,7 @@ These functions were added in OpenSSL 3.2. =head1 COPYRIGHT -Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/BIO_socket_wait.pod b/doc/man3/BIO_socket_wait.pod index f1050f80fb7e6..32d8869d01313 100644 --- a/doc/man3/BIO_socket_wait.pod +++ b/doc/man3/BIO_socket_wait.pod @@ -3,6 +3,7 @@ =head1 NAME BIO_socket_wait, +BIO_socket_ready, BIO_wait, BIO_do_connect_retry - BIO connection utility functions @@ -13,6 +14,7 @@ BIO_do_connect_retry #ifndef OPENSSL_NO_SOCK int BIO_socket_wait(int fd, int for_read, time_t max_time); + int BIO_socket_ready(int fd, int for_read); #endif int BIO_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds); int BIO_do_connect_retry(BIO *bio, int timeout, int nap_milliseconds); @@ -23,6 +25,11 @@ BIO_socket_wait() waits on the socket B for reading if B is not 0, else for writing, at most until B. It succeeds immediately if B == 0 (which means no timeout given). +BIO_socket_ready() checks if the socket B is ready for reading if +B is not 0, else for writing, without blocking. +This is useful for polling a socket to determine if an I/O operation +can be performed immediately without waiting. + BIO_wait() waits at most until B on the given (typically socket-based) B, for reading if B is supposed to read, else for writing. It is used by BIO_do_connect_retry() and can be used together L. @@ -45,8 +52,9 @@ The function may, directly or indirectly, invoke ERR_clear_error(). =head1 RETURN VALUES -BIO_socket_wait(), BIO_wait(), and BIO_do_connect_retry() -return -1 on error, 0 on timeout, and 1 on success. +BIO_socket_wait(), BIO_socket_ready(), BIO_wait(), and BIO_do_connect_retry() +return -1 on error, 0 on timeout (or not ready in the case of BIO_socket_ready()), +and 1 on success (or ready in the case of BIO_socket_ready()). =head1 SEE ALSO @@ -57,9 +65,11 @@ L, L BIO_socket_wait(), BIO_wait(), and BIO_do_connect_retry() were added in OpenSSL 3.0. +BIO_socket_ready() was added in OpenSSL 4.1. + =head1 COPYRIGHT -Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/BN_add.pod b/doc/man3/BN_add.pod index edbc48c50f92b..a7ff19565f49a 100644 --- a/doc/man3/BN_add.pod +++ b/doc/man3/BN_add.pod @@ -137,7 +137,7 @@ L, L =head1 COPYRIGHT -Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/BN_generate_prime.pod b/doc/man3/BN_generate_prime.pod index 005c25fd7cc0a..876c26816ccb6 100644 --- a/doc/man3/BN_generate_prime.pod +++ b/doc/man3/BN_generate_prime.pod @@ -201,6 +201,8 @@ BN_is_prime_fasttest() and BN_check_prime return 0 if the number is composite, -1 on error. BN_generate_prime() returns the prime number on success, B otherwise. +Please note that the B BIGNUM is freed on failure and must not be +used or freed by the caller in such case. BN_GENCB_new returns a pointer to a BN_GENCB structure on success, or B otherwise. @@ -246,7 +248,7 @@ BN_check_prime() was added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/CMS_EncryptedData_decrypt.pod b/doc/man3/CMS_EncryptedData_decrypt.pod index f7375f2c58b1b..c2b00b0584f0c 100644 --- a/doc/man3/CMS_EncryptedData_decrypt.pod +++ b/doc/man3/CMS_EncryptedData_decrypt.pod @@ -58,7 +58,7 @@ CMS_EnvelopedData_decrypt() was added in OpenSSL 3.2. =head1 COPYRIGHT -Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/CMS_add0_cert.pod b/doc/man3/CMS_add0_cert.pod index 8f7e0e9e42f58..75be55a87366a 100644 --- a/doc/man3/CMS_add0_cert.pod +++ b/doc/man3/CMS_add0_cert.pod @@ -22,22 +22,23 @@ CMS_add0_crl, CMS_add1_crl, CMS_get1_crls CMS_add0_cert() and CMS_add1_cert() add certificate I to I unless it is already present. -This is used by L and L and may be used before -calling L to help chain building in certificate validation. +Signer certificates and intermediate CA certificates are usually added +to a CMS structure by L and L, yet further +such certificates may be added in advance by directly calling these functions. +The verifier of the message can use the included certificates +as candidate signer certificates and for chain building. +These functions may also be used before calling L to add +fallback signer certificates or intermediate CA certificates for chain building. As the 0 implies, CMS_add0_cert() adds I internally to I and on success it must not be freed up by the caller. In contrast, the caller of CMS_add1_cert() must free I. I must be of type signed data or (authenticated) enveloped data. -For signed data, such a certificate can be used when signing or verifying -to fill in the signer certificate or to provide an extra CA certificate -that may be needed for chain building in certificate validation. CMS_get1_certs() returns all certificates in I. CMS_add0_crl() and CMS_add1_crl() add CRL I to I. I must be of type signed data or (authenticated) enveloped data. -For signed data, such a CRL may be used in certificate validation -with L. +Such a CRL may be used in certificate validation, e.g., with L. It may be given both for inclusion when signing a CMS message and when verifying a signed CMS message. @@ -75,7 +76,7 @@ not to throw an error if a certificate to be added is already present. =head1 COPYRIGHT -Copyright 2008-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2008-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/CMS_add1_signer.pod b/doc/man3/CMS_add1_signer.pod index 58b8bcc51d7ff..a24abce583a7b 100644 --- a/doc/man3/CMS_add1_signer.pod +++ b/doc/man3/CMS_add1_signer.pod @@ -76,10 +76,10 @@ and serial number. If B is set it will use the subject key identifier value instead. An error occurs if the signing certificate does not have a subject key identifier extension. -If present the SMIMECapabilities attribute indicates support for the following -algorithms in preference order: 256 bit AES, Gost R3411-94, Gost 28147-89, 192 -bit AES, 128 bit AES, triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. -If any of these algorithms is not available then it will not be included. +If present, the SMIMECapabilities attribute indicates support for only the +algorithms that are available in the providers associated with the +B structure. See L for the +full candidate list and further details. Note that, in the case signedAttributes are not used, for some hash-less signing schemes the given hash B will be ignored and a hash required by the signing @@ -109,7 +109,7 @@ L, =head1 COPYRIGHT -Copyright 2014-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2014-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/CMS_add_standard_smimecap_ex.pod b/doc/man3/CMS_add_standard_smimecap_ex.pod new file mode 100644 index 0000000000000..226d81635d204 --- /dev/null +++ b/doc/man3/CMS_add_standard_smimecap_ex.pod @@ -0,0 +1,85 @@ +=pod + +=head1 NAME + +CMS_add_standard_smimecap_ex, CMS_add_standard_smimecap, +CMS_add_smimecap, CMS_add_simple_smimecap +- CMS SMIMECapabilities attribute utilities + +=head1 SYNOPSIS + + #include + + int CMS_add_standard_smimecap_ex(STACK_OF(X509_ALGOR) **smcap, + OSSL_LIB_CTX *libctx, const char *propq); + int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap); + + int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs); + int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, + int algnid, int keysize); + +=head1 DESCRIPTION + +CMS_add_standard_smimecap_ex() populates B<*smcap> with the set of +algorithms that should be advertised in an SMIMECapabilities signed +attribute. Only algorithms that are available in the providers +associated with B and the property query string B are +included, so the list accurately reflects what the caller can actually +use. If B is NULL the default library context is used. If +B<*smcap> is NULL a new B is allocated; otherwise +entries are appended to the existing stack. + +The candidate algorithms, listed in preference order, are: AES-256-CBC, +GOST R 34.11-2012 (256-bit), GOST R 34.11-2012 (512-bit), GOST R +34.11-94, GOST 28147-89, AES-192-CBC, AES-128-CBC, DES-EDE3-CBC, +RC2-CBC (128-bit key), RC2-CBC (64-bit key), DES-CBC, and RC2-CBC +(40-bit key). Algorithms not available in the active providers +(for example, RC2 and DES when only the default provider is loaded) +are silently omitted. + +CMS_add_standard_smimecap() is a wrapper that calls +CMS_add_standard_smimecap_ex() with a NULL library context and NULL +property query string. + +CMS_add_smimecap() adds a pre-built stack of algorithm identifiers +B as the SMIMECapabilities signed attribute on the +B B. + +CMS_add_simple_smimecap() appends a single algorithm entry to B<*algs>. +B is the NID of the algorithm and B is the key size in +bits, or -1 if the algorithm does not use a variable key size. + +=head1 NOTES + +Applications that need accurate capability advertisements should use +CMS_add_standard_smimecap_ex(), passing the same B and B +used for the rest of the CMS operation. This ensures that only +algorithms genuinely available to the application are listed. + +CMS_add1_signer() calls CMS_add_standard_smimecap_ex() internally using +the library context associated with the CMS_ContentInfo structure, so +applications that use CMS_add1_signer() without B do not +need to call these functions directly. + +=head1 RETURN VALUES + +All functions return 1 for success or 0 for failure. + +=head1 SEE ALSO + +L, L, L + +=head1 HISTORY + +CMS_add_standard_smimecap_ex() was added in OpenSSL 4.1. + +=head1 COPYRIGHT + +Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/CMS_decrypt.pod b/doc/man3/CMS_decrypt.pod index 66a94287b6f54..4e40b37f214ae 100644 --- a/doc/man3/CMS_decrypt.pod +++ b/doc/man3/CMS_decrypt.pod @@ -112,7 +112,7 @@ were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2008-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2008-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/CMS_get0_SignerInfos.pod b/doc/man3/CMS_get0_SignerInfos.pod index 46dba9cde0828..a9dc9ed9dd54d 100644 --- a/doc/man3/CMS_get0_SignerInfos.pod +++ b/doc/man3/CMS_get0_SignerInfos.pod @@ -3,8 +3,10 @@ =head1 NAME CMS_SignerInfo_set1_signer_cert, +CMS_SignerInfo_get0_signer_cert, CMS_get0_SignerInfos, CMS_SignerInfo_get0_signer_id, -CMS_SignerInfo_get0_signature, CMS_SignerInfo_cert_cmp +CMS_SignerInfo_get0_signature, CMS_SignerInfo_cert_cmp, +CMS_SignerInfo_get_verification_result - CMS signedData signer functions =head1 SYNOPSIS @@ -18,6 +20,8 @@ CMS_SignerInfo_get0_signature, CMS_SignerInfo_cert_cmp ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si); int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert); void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer); + X509 *CMS_SignerInfo_get0_signer_cert(CMS_SignerInfo *si); + int CMS_SignerInfo_get_verification_result(CMS_SignerInfo *si, int type); =head1 DESCRIPTION @@ -41,6 +45,16 @@ if not. CMS_SignerInfo_set1_signer_cert() sets the signer's certificate of B to B. +CMS_SignerInfo_get0_signer_cert() returns the signer's certificate associated +with I. This pointer should not be freed by the caller. + +CMS_SignerInfo_get_verification_result() returns whether a specific aspect of +the signature verification was successful after calling L with +the flag B. Pass B as I to get +the overall result, B for certificate verification, +B for attribute verification and B for +content verification. + =head1 NOTES The main purpose of these functions is to enable an application to lookup @@ -78,9 +92,14 @@ Any error can be obtained from L L, L +=head1 HISTORY + +B and +B were added in OpenSSL 4.1. + =head1 COPYRIGHT -Copyright 2008-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2008-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/CMS_verify.pod b/doc/man3/CMS_verify.pod index 9ec172468d282..92e1012210b9f 100644 --- a/doc/man3/CMS_verify.pod +++ b/doc/man3/CMS_verify.pod @@ -32,8 +32,9 @@ CMS_SignerInfo_verify_content, CMS_SignerInfo_verify_ex CMS_verify() is very similar to L. It verifies a B structure contained in a structure of type B. I points to the B structure to verify. -The optional I parameter refers to a set of certificates -in which to search for signing certificates. +The optional I parameter can provide a list of certificates +that are used for searching for signer certificates first, +as far as they are not already associated with the B. It is also used as a source of untrusted intermediate CA certificates for chain building. I may contain extra untrusted CA certificates that may be used for @@ -57,7 +58,7 @@ Also the list of CRLs must not contain duplicates. The optional parameters library context I and property query I are used when retrieving algorithms from providers. -CMS_get0_signers() retrieves the signing certificate(s) from I; it may only +CMS_get0_signers() retrieves the signer certificate(s) from I; it may only be called after a successful CMS_verify() or CMS_SignedData_verify() operation. CMS_SignerInfo_verify() verifies the signed attributes attached to the given @@ -83,34 +84,41 @@ Initially some sanity checks are performed on I. The type of I must be SignedData. There must be at least one signature on the data and if the content is detached I cannot be NULL. -An attempt is made to locate all the signing certificate(s), first looking in -the I parameter (if it is not NULL) and then looking in any -certificates contained in the I structure unless B is set. -If any signing certificate cannot be located the operation fails. - -Each signing certificate is chain verified -using the trusted certificate store I if supplied. -The purpose required in this verification is I -unless a different one (or B) -has been set in I using L. +An attempt is made to locate all the signer certificate(s) +as far as they are not already associated with the B. +First, they are searched among the certificates provided +in the I parameter (if it is not NULL). +Then they are looked up among the certificates contained +in the I structure unless B is set. +If any signer certificate cannot be located, the operation fails. +Signer associations are retained between verification calls. + +Each found signer certificate is chain verified using I as the trusted +certificate store if supplied, and by default requiring the I purpose. +The default purpose may be overridden using L. Any internal certificates in the message, which may have been added using L, are used as untrusted CAs. If CRL checking is enabled in I and B is not set, any internal CRLs, which may have been added using L, are used in addition to attempting to look them up in I. -If I is not NULL and any chain verify fails an error code is returned. +If I is not NULL and any chain verify fails an error code is returned +unless B is set, where one successful verify can be sufficient. Finally the signed content is read (and written to I unless it is NULL) -and the signature is checked. +and each signature (for which the certificate was successfully verified) is checked. -If all signatures verify correctly then the function is successful. +The overall result of the function depends on whether B is +set. When set, a single successfully verified signature is enough and +L can be used to inspect each signature. +Otherwise, the function is only successful if all signatures verify successfully. Any of the following flags (ored together) can be passed in the I parameter to change the default verify behaviour. If B is set the certificates in the message itself are not -searched when locating the signing certificate(s). -This means that all the signing certificates must be in the I parameter. +searched when locating the signer certificate(s). +This means that the signer certificates that are not already associated +with the B must be in the I parameter. If B is set and CRL checking is enabled in I then any CRLs in the message itself and provided via the I parameter are ignored. @@ -119,7 +127,7 @@ If the B flag is set MIME headers for type C are deleted from the content. If the content is not of type C then an error is returned. -If B is set the signing certificates are not +If B is set the signer certificates are not chain verified, unless B flag is also set. If B is set the signed attributes signature is not @@ -133,7 +141,8 @@ If B is set then the content digest is not checked. =head1 NOTES -One application of B is to only accept messages signed by +As far as signer certificates are not already associated with B, +one application of B can be to only accept messages signed by a small number of certificates. The acceptable certificates would be passed in the I parameter. In this case if the signer certificate is not one of the certificates supplied in I then the verify will fail because the @@ -169,7 +178,7 @@ The error can be obtained from L. =head1 BUGS -The trusted certificate store is not searched for the signing certificate. +The trusted certificate store is not searched for the signer certificate. This is primarily due to the inadequacies of the current B functionality. @@ -187,6 +196,8 @@ L, L CMS_SignedData_verify() was added in OpenSSL 3.2. +The B flag was added in OpenSSL 4.1. + =head1 COPYRIGHT Copyright 2008-2026 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/CTLOG_STORE_new.pod b/doc/man3/CTLOG_STORE_new.pod index f342637012c8f..e99deb41cebc7 100644 --- a/doc/man3/CTLOG_STORE_new.pod +++ b/doc/man3/CTLOG_STORE_new.pod @@ -91,7 +91,7 @@ OpenSSL 3.0. All other functions were added in OpenSSL 1.1.0. =head1 COPYRIGHT -Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/DTLSv1_get_timeout.pod b/doc/man3/DTLSv1_get_timeout.pod index 0b9c33fdc0dcf..532a27fda1230 100644 --- a/doc/man3/DTLSv1_get_timeout.pod +++ b/doc/man3/DTLSv1_get_timeout.pod @@ -33,7 +33,7 @@ Once the timeout expires, DTLSv1_handle_timeout() should be called to handle any internal processing which is due; for more information, see L. -L supersedes all use cases for this this function and +L supersedes all use cases for this function and may be used instead of it. =head1 RETURN VALUES @@ -48,7 +48,7 @@ L, L, L =head1 COPYRIGHT -Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/DTLSv1_listen.pod b/doc/man3/DTLSv1_listen.pod index eda8aaf22a27e..4dc2d2062274a 100644 --- a/doc/man3/DTLSv1_listen.pod +++ b/doc/man3/DTLSv1_listen.pod @@ -16,11 +16,13 @@ DTLSv1_listen =head1 DESCRIPTION SSL_stateless() statelessly listens for new incoming TLSv1.3 connections. -DTLSv1_listen() statelessly listens for new incoming DTLS connections. If a -ClientHello is received that does not contain a cookie, then they respond with a -request for a new ClientHello that does contain a cookie. If a ClientHello is -received with a cookie that is verified then the function returns in order to -enable the handshake to be completed (for example by using SSL_accept()). +DTLSv1_listen() statelessly listens for new incoming DTLS 1.0 and DTLS 1.2 +connections. B; for DTLS 1.3 server +applications, use L instead. If a ClientHello is received +that does not contain a cookie, then they respond with a request for a new +ClientHello that does contain a cookie. If a ClientHello is received with a +cookie that is verified then the function returns in order to enable the +handshake to be completed (for example by using SSL_accept()). =head1 NOTES @@ -106,6 +108,15 @@ start. SSL_stateless() cannot be used with QUIC SSL objects and returns an error if called on such an object. +DTLSv1_listen() with an SSL object configured for a max of DTLSv1.3 will +silently downgrade it to a max of DTLSv1.2. + +DTLSv1_listen() cannot be used with DTLS 1.3. If the SSL object is configured +for DTLS 1.3 only (i.e., both minimum and maximum protocol versions are set to +DTLS 1.3), DTLSv1_listen() will fail. For DTLS 1.3 server applications, use +L instead, which performs address validation via +HelloRetryRequest (HRR) by default. + =head1 RETURN VALUES For SSL_stateless() a return value of 1 indicates success and the B object @@ -132,7 +143,8 @@ errors as non-fatal), whilst return codes >0 indicate success. =head1 SEE ALSO -L, L, +L, L, +L, L, L, L, L, L, L @@ -144,9 +156,12 @@ The SSL_stateless() function was added in OpenSSL 1.1.1. The DTLSv1_listen() return codes were clarified in OpenSSL 1.1.0. The type of "peer" also changed in OpenSSL 1.1.0. +DTLSv1_listen() supports only DTLS 1.0 and DTLS 1.2 in OpenSSL 4.1. +DTLS 1.3 applications should use L instead. + =head1 COPYRIGHT -Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EVP_KDF.pod b/doc/man3/EVP_KDF.pod index 6df44e8643415..f2d890b70cb57 100644 --- a/doc/man3/EVP_KDF.pod +++ b/doc/man3/EVP_KDF.pod @@ -341,7 +341,7 @@ in OpenSSL 4.1. =head1 COPYRIGHT -Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EVP_PKEY_CTX_new.pod b/doc/man3/EVP_PKEY_CTX_new.pod index fff102a769ab8..9ded13de5df5c 100644 --- a/doc/man3/EVP_PKEY_CTX_new.pod +++ b/doc/man3/EVP_PKEY_CTX_new.pod @@ -48,6 +48,9 @@ EVP_PKEY_CTX_new_id() and EVP_PKEY_CTX_new_from_name() are normally used when no B structure is associated with the operations, for example during parameter generation or key generation for some algorithms. +The key returned by L is not associated with the +generation context. To perform operations using that key, create a new context +with L. EVP_PKEY_CTX_dup() duplicates the context I. It is not supported for a keygen operation. @@ -125,7 +128,7 @@ added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EVP_PKEY_decrypt.pod b/doc/man3/EVP_PKEY_decrypt.pod index 5e624e8c6117c..6b46329793730 100644 --- a/doc/man3/EVP_PKEY_decrypt.pod +++ b/doc/man3/EVP_PKEY_decrypt.pod @@ -17,12 +17,13 @@ EVP_PKEY_decrypt - decrypt using a public key algorithm =head1 DESCRIPTION -The EVP_PKEY_decrypt_init() function initializes a public key algorithm -context using key I for a decryption operation. +The EVP_PKEY_decrypt_init() function initializes the public key algorithm +context I for a decryption operation. A key must already be associated +with I; this is normally done by creating it with +L or L. -The EVP_PKEY_decrypt_init_ex() function initializes a public key algorithm -context using key I for a decryption operation and sets the -algorithm specific I. +The EVP_PKEY_decrypt_init_ex() function is the same as +EVP_PKEY_decrypt_init() but additionally sets the algorithm-specific I. The EVP_PKEY_decrypt() function performs a public key decryption operation using I. The data to be decrypted is specified using the I and @@ -88,7 +89,7 @@ Decrypt data using OAEP (for RSA keys): * NB: assumes key, in, inlen are already set up * and that key is an RSA private key */ - ctx = EVP_PKEY_CTX_new(key, NULL); + ctx = EVP_PKEY_CTX_new_from_pkey(NULL, key, NULL); if (!ctx) /* Error occurred */ if (EVP_PKEY_decrypt_init(ctx) <= 0) @@ -125,7 +126,7 @@ These functions were added in OpenSSL 1.0.0. =head1 COPYRIGHT -Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EVP_PKEY_encrypt.pod b/doc/man3/EVP_PKEY_encrypt.pod index 1fb41f99f428c..fda95c218e5d9 100644 --- a/doc/man3/EVP_PKEY_encrypt.pod +++ b/doc/man3/EVP_PKEY_encrypt.pod @@ -17,12 +17,13 @@ EVP_PKEY_encrypt_init, EVP_PKEY_encrypt - encrypt using a public key algorithm =head1 DESCRIPTION -The EVP_PKEY_encrypt_init() function initializes a public key algorithm -context using key B for an encryption operation. +The EVP_PKEY_encrypt_init() function initializes the public key algorithm +context I for an encryption operation. A key must already be associated +with I; this is normally done by creating it with +L or L. -The EVP_PKEY_encrypt_init_ex() function initializes a public key algorithm -context using key B for an encryption operation and sets the -algorithm specific B. +The EVP_PKEY_encrypt_init_ex() function is the same as +EVP_PKEY_encrypt_init() but additionally sets the algorithm-specific I. The EVP_PKEY_encrypt() function performs a public key encryption operation using B. The data to be encrypted is specified using the B and @@ -66,7 +67,7 @@ L for means to load a public key. * NB: assumes key, in, inlen are already set up, * and that key is an RSA public key */ - ctx = EVP_PKEY_CTX_new(key, NULL); + ctx = EVP_PKEY_CTX_new_from_pkey(NULL, key, NULL); if (!ctx) /* Error occurred */ if (EVP_PKEY_encrypt_init(ctx) <= 0) @@ -104,7 +105,7 @@ These functions were added in OpenSSL 1.0.0. =head1 COPYRIGHT -Copyright 2006-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EVP_PKEY_fromdata.pod b/doc/man3/EVP_PKEY_fromdata.pod index 44d8788db010d..eb2771a46af6a 100644 --- a/doc/man3/EVP_PKEY_fromdata.pod +++ b/doc/man3/EVP_PKEY_fromdata.pod @@ -292,7 +292,7 @@ Support for B was added in OpenSSL 3.6. =head1 COPYRIGHT -Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EVP_PKEY_get_size.pod b/doc/man3/EVP_PKEY_get_size.pod index f7ec7c5f84935..922c2a0e6eb5e 100644 --- a/doc/man3/EVP_PKEY_get_size.pod +++ b/doc/man3/EVP_PKEY_get_size.pod @@ -143,7 +143,7 @@ _ =begin html -> + @@ -202,7 +202,7 @@ EVP_PKEY_get_security_category() was added in OpenSSL 3.6. =head1 COPYRIGHT -Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EVP_PKEY_keygen.pod b/doc/man3/EVP_PKEY_keygen.pod index 1d5180ef6f4bc..0a3b31e678d7c 100644 --- a/doc/man3/EVP_PKEY_keygen.pod +++ b/doc/man3/EVP_PKEY_keygen.pod @@ -66,6 +66,12 @@ parameters or key are written to I<*ppkey>. If I<*ppkey> is NULL when this function is called, it will be allocated, and should be freed by the caller when no longer useful, using L. +When a key is generated, EVP_PKEY_generate() does not associate it with I +or change I into a context for operations using that key. To use the +generated key, create a new context with L, +passing I<*ppkey>. The generation context can be reused for further generation +operations or freed. + EVP_PKEY_paramgen() and EVP_PKEY_keygen() do exactly the same thing as EVP_PKEY_generate(), after checking that the corresponding EVP_PKEY_paramgen_init() or EVP_PKEY_keygen_init() was used to initialize I. @@ -102,6 +108,9 @@ If I is C, a B parameter must be given to specify the size of the RSA key. If I is C, a string parameter must be given to specify the name of the EC curve. +The list of built-in curves can be obtained programmatically using +L, and their names can be retrieved using +L. If I is: C, C, @@ -153,7 +162,7 @@ in functions which require the use of a public key or parameters. =head1 EXAMPLES -Generate a 2048 bit RSA key: +Generate a 2048 bit RSA key, then initialize a context for encryption: #include #include @@ -161,7 +170,7 @@ Generate a 2048 bit RSA key: EVP_PKEY_CTX *ctx; EVP_PKEY *pkey = NULL; - ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); if (!ctx) /* Error occurred */ if (EVP_PKEY_keygen_init(ctx) <= 0) @@ -170,7 +179,15 @@ Generate a 2048 bit RSA key: /* Error */ /* Generate key */ - if (EVP_PKEY_keygen(ctx, &pkey) <= 0) + if (EVP_PKEY_generate(ctx, &pkey) <= 0) + /* Error */ + + /* ctx is still a generation context; pkey contains the generated key */ + EVP_PKEY_CTX_free(ctx); + ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); + if (!ctx) + /* Error occurred */ + if (EVP_PKEY_encrypt_init(ctx) <= 0) /* Error */ Generate a key from a set of parameters: diff --git a/doc/man3/EVP_PKEY_todata.pod b/doc/man3/EVP_PKEY_todata.pod index d3455ce1bd1dc..5751d8a060cbb 100644 --- a/doc/man3/EVP_PKEY_todata.pod +++ b/doc/man3/EVP_PKEY_todata.pod @@ -70,7 +70,7 @@ Support for B was added in OpenSSL 3.6. =head1 COPYRIGHT -Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EVP_PKEY_verify_recover.pod b/doc/man3/EVP_PKEY_verify_recover.pod index 10084d61c1add..52682f2aa5e3a 100644 --- a/doc/man3/EVP_PKEY_verify_recover.pod +++ b/doc/man3/EVP_PKEY_verify_recover.pod @@ -22,10 +22,10 @@ EVP_PKEY_verify_recover_init_ex2, EVP_PKEY_verify_recover =head1 DESCRIPTION EVP_PKEY_verify_recover_init() initializes a public key algorithm context -I for signing using the algorithm given when the context was created -using L or variants thereof. The algorithm is used to -fetch a B method implicitly, see L -for more information about implicit fetches. +I for a verify-recover operation using the algorithm given when the +context was created using L or variants thereof. The +algorithm is used to fetch a B method implicitly, see +L for more information about implicit fetches. EVP_PKEY_verify_recover_init_ex() is the same as EVP_PKEY_verify_recover_init() but additionally sets the passed parameters @@ -35,8 +35,8 @@ EVP_PKEY_verify_recover_init_ex2() is the same as EVP_PKEY_verify_recover_init_e but works with an explicitly fetched B I. A context I without a pre-loaded key cannot be used with this function. Depending on what algorithm was fetched, certain details revolving around the -treatment of the input to EVP_PKEY_verify() may be pre-determined, and in that -case, those details may normally not be changed. +treatment of the input to EVP_PKEY_verify_recover() may be pre-determined, and +in that case, those details may normally not be changed. See L below for a deeper explanation. The EVP_PKEY_verify_recover() function recovers signed data @@ -132,7 +132,7 @@ The EVP_PKEY_verify_recover_init_ex() function was added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2013-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2013-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/EVP_SKEY.pod b/doc/man3/EVP_SKEY.pod index f45aac10c57fd..b9ee17d1da39d 100644 --- a/doc/man3/EVP_SKEY.pod +++ b/doc/man3/EVP_SKEY.pod @@ -5,7 +5,8 @@ EVP_SKEY, EVP_SKEY_generate, EVP_SKEY_import, EVP_SKEY_import_raw_key, EVP_SKEY_import_SKEYMGMT, EVP_SKEY_up_ref, EVP_SKEY_export, EVP_SKEY_get0_raw_key, EVP_SKEY_get0_key_id, EVP_SKEY_get0_skeymgmt_name, -EVP_SKEY_get0_provider_name, EVP_SKEY_free, EVP_SKEY_is_a, EVP_SKEY_to_provider +EVP_SKEY_get0_provider_name, EVP_SKEY_free, EVP_SKEY_is_a, EVP_SKEY_to_provider, +EVP_SKEY_get0_local_keyid, EVP_SKEY_get0_algorithm_id - opaque symmetric key allocation and handling functions =head1 SYNOPSIS @@ -39,6 +40,12 @@ EVP_SKEY_get0_provider_name, EVP_SKEY_free, EVP_SKEY_is_a, EVP_SKEY_to_provider EVP_SKEY *EVP_SKEY_to_provider(EVP_SKEY *skey, OSSL_LIB_CTX *libctx, OSSL_PROVIDER *prov, const char *propquery); + int EVP_SKEY_get0_local_keyid(const EVP_SKEY *skey, + const unsigned char **id, size_t *len); + int EVP_SKEY_get0_algorithm_id(const EVP_SKEY *skey, + const unsigned char **oid, size_t *oid_len, + const unsigned char **params, + size_t *params_len); =head1 DESCRIPTION @@ -95,6 +102,41 @@ EVP_SKEY_to_provider() simplifies the task of importing a I into a different provider identified by I. If I is NULL, the default provider for the key type identified via I is used. +=head2 Metadata + +An B object can carry optional metadata alongside the cryptographic +key material. This metadata is managed by the provider through the +B import/export mechanism and stored in the provider-side key +data. + +The friendly name (alias) is accessible via EVP_SKEY_get0_key_id(), which +dispatches to the provider's B function. +The built-in providers return the value of B if it +was set during import. + +EVP_SKEY_get0_local_keyid() retrieves the local key identifier from I. +On success, I<*id> is set to a pointer to the identifier bytes and I<*len> +is set to the length. The returned pointer is valid for the lifetime of +I. Returns 1 on success, 0 on error. + +EVP_SKEY_get0_algorithm_id() retrieves the algorithm identifier from I. +It can return both the DER-encoded algorithm OID (via I and I) +and the DER-encoded algorithm parameters (via I and I). +Either output pair may be NULL if the caller does not need that part. +The returned pointers are valid for the lifetime of I. +Returns 1 on success, 0 on error. + +These metadata fields are populated on obtaining the key object (e.g. when +parsing PKCS#12 files). For PKCS#12 files the friendly name and local key ID +correspond to PKCS#12 bag attributes (B and +B), while the algorithm OID and parameters are extracted from +the PKCS8 B. + +The implementation is in general provider-dependent. If the corresponding +callback is not implemented for the EVP_SKEYMGMT, 0 is returned. However, as +metadata is completely optional, the success doesn't indicate that the data is +available. + =head2 Selections The following constants can be used for I: @@ -145,6 +187,9 @@ otherwise 0. EVP_SKEY_to_provider() returns a new B suitable for operations with the I provider or NULL in case of failure. +EVP_SKEY_get0_local_keyid() and EVP_SKEY_get0_algorithm_id() return 1 on +success or 0 on error. + =head1 SEE ALSO L, L, L @@ -160,6 +205,9 @@ were introduced in OpenSSL 3.5. The EVP_SKEY_import_SKEYMGMT() function was introduced in OpenSSL 4.0. +The EVP_SKEY_get0_local_keyid() and EVP_SKEY_get0_algorithm_id() +functions were added in OpenSSL 4.1. + =head1 COPYRIGHT Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/EVP_set_default_properties.pod b/doc/man3/EVP_set_default_properties.pod index 356b590778337..7f02ed7fc5235 100644 --- a/doc/man3/EVP_set_default_properties.pod +++ b/doc/man3/EVP_set_default_properties.pod @@ -91,7 +91,7 @@ EVP_default_properties_is_fips_enabled(NULL) in OpenSSL 4.1. =head1 COPYRIGHT -Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/HMAC.pod b/doc/man3/HMAC.pod index 53a3853eb2bd1..1690a73274a3a 100644 --- a/doc/man3/HMAC.pod +++ b/doc/man3/HMAC.pod @@ -112,6 +112,9 @@ be authenticated (I bytes at I). HMAC_Final() places the message authentication code in I, which must have space for the hash function output. +After calling HMAC_Final() no calls to HMAC_Update() or HMAC_Final() can be +made, but HMAC_Init_ex() can be called to initialize a new HMAC +operation. HMAC_CTX_copy() copies all of the internal state from I into I. @@ -163,7 +166,7 @@ OpenSSL before version 1.0.0. =head1 COPYRIGHT -Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/OPENSSL_armcap.pod b/doc/man3/OPENSSL_armcap.pod new file mode 100644 index 0000000000000..78c8d3fbedc9d --- /dev/null +++ b/doc/man3/OPENSSL_armcap.pod @@ -0,0 +1,246 @@ +=pod + +=head1 NAME + +OPENSSL_armcap - the Arm processor capabilities vector + +=head1 SYNOPSIS + + env OPENSSL_armcap=... + +=head1 DESCRIPTION + +libcrypto supports a range of Arm instruction set extensions. These +extensions are represented by bits in the Arm processor capabilities vector. +When libcrypto initializes, it stores the results returned by Arm CPU +capabilities detection logic in the Arm processor capabilities vector. The +CPU capabilities detection methods are OS-dependent, using a combination of +information gathered by the kernel during boot, and probe functions that attempt +to execute instructions and trap illegal instruction signals with a signal +handler. + +To override the set of extensions available to an application, set the +B environment variable before starting the application. The +environment variable is assigned a numerical value that denotes the bits in +the Arm processor capabilities vector. The arm_arch.h header file defines +the possible values, which are explained in detail below. + +Multiple extensions are enabled by logically OR-ing the values that represent +the desired extensions. + +B: Attempting to executing an instruction from an extension that the +target CPU does not support will result in an illegal instruction exception +(SIGILL). + +Please note that not all possible values in the Arm processor capabilities +vector are actual processor capabilities. Some values represent OpenSSL +performance preferences for some implementations which only make sense on +specific CPUs. + +The following extensions are defined: + +=over 4 + +=item 0x0001 + +Name: B + +Meaning: Indicates support for the Armv7 Neon SIMD extensions on the processor. + +Effect: Enables various Armv7 Neon SIMD implementations. + +=item 0x00002 + +Name: B + +Meaning: Indicates support for the Armv7 system timer on the processor. + +Effect: This is used as a seed for some random number generators. + +=item 0x00004 + +Name: B + +Meaning: Indicates support for the Armv8.0 AES hardware-acceleration extensions +on the processor. + +Effect: Enables various Armv8.0 AES hardware-accelerated implementations. + +=item 0x00008 + +Name: B + +Meaning: Indicates support for the Armv8.0 SHA1 hardware-acceleration extensions +on the processor. + +Effect: Enables various Armv8.0 SHA1 hardware-accelerated implementations. + +=item 0x00010 + +Name: B + +Meaning: Indicates support for the Armv8.0 SHA256 hardware-acceleration +extensions on the processor. + +Effect: Enables various Armv8.0 SHA256 hardware-accelerated implementations. + +=item 0x00020 + +Name: B + +Meaning: Indicates support for the Armv8.0 polynomial multiplication +hardware-acceleration extensions on the processor. + +Effect: Used to hardware-accelerate polynomial multiplication, for example in +AES-GCM. + +=item 0x00040 + +Name: B + +Meaning: Indicates support for the Armv8.2 SHA512 hardware-acceleration +extensions on the processor. + +Effect: Enables Armv8.2 SHA512 hardware-accelerated implementations. + +=item 0x00080 + +Name: B + +Meaning: Indicates support for the Armv8.0 hardware identification extensions on +the processor. + +Effect: Allows implementations to change their behaviour, dependant on the +processor platform in order to achieve better performance. + +=item 0x00100 + +Name: B + +Meaning: Indicates support for the Armv8.5 hardware random number generation +extensions on the processor. + +Effect: Enables hardware random number generation on supported AArch64 +processors. + +=item 0x00200 + +Name: B + +Meaning: Indicates support for the Armv8.2 SM3 hardware-acceleration extensions +on the processor. + +Effect: Enables Armv8.2 SM3 hardware-accelerated implementations. + +=item 0x00400 + +Name: B + +Meaning: Indicates support for the Armv8.2 SM4 hardware-acceleration extensions +on the processor. + +Effect: Enables Armv8.2 SM4 hardware-accelerated implementations. + +=item 0x00800 + +Name: B + +Meaning: Indicates support for the Armv8.2 SHA3 hardware-acceleration extensions +on the processor. + +Effect: Enables SHA3 hardware-accelerated implementations (see also +ARMV8_HAVE_SHA3_AND_WORTH_USING). + +=item 0x01000 + +Name: B + +Meaning: Indicates support for the Arm EOR3 instruction, which is a part of the +Armv8.2 SHA3 extensions, and enables 8x Loop unrolling in the AES-CTR +implementation. + +Effect: Enables the 8x loop unrolling utilising EOR3 implementation of AES-CTR +on platforms that support the SHA3 extension and have enough vector bandwidth. + +=item 0x02000 + +Name: B + +Meaning: Indicates support for the Armv8.2 SVE hardware extension on the +processor. + +Effect: Enables various Armv8.2 SVE implementations. + +=item 0x04000 + +Name: B + +Meaning: Indicates support for the Armv9.0 SVE2 hardware extension on the +processor. + +Effect: Enables various Armv9.0 SVE2 implementations. + +=item 0x08000 + +Name: B + +Meaning: Indicates support for the Armv8.2 SHA3 hardware-acceleration extensions +on the processor, and that the hardware bandwidth is sufficient for it to be +worth using. + +Effect: On certain Apple platforms, although the SHA3 extension is supported, it +is actually slower than other implementations. This flag disables the +hardware-accelerated SHA3 implementations on these platforms. + +=item 0x10000 + +Name: B + +Meaning: Indicates support for the Arm EOR3 instruction, which is a part of the +Armv8.2 SHA3 extensions, and enables 12x loop unrolling in the AES-CTR +implementation. + +Effect: Enables the 12x loop unrolling utilising EOR3 implementation of AES-CTR +on platforms that support the extension and have enough vector bandwidth. + +=item 0x20000 + +Name: B + +Meaning: Indicates support for the Armv9.0 SVE2 hardware extension, and enables +its use in the Poly1305 implementation. + +Effect: Enables the Armv9.0 SVE2 Poly1305 implementation if SVE2 is enabled, the +vector length is greater than 128 bits, and the vector length is a power of 2. + +=back + +=head1 RETURN VALUES + +Not available. + +=head1 EXAMPLES + +Check currently detected capabilities: + + $ openssl info -cpusettings + OPENSSL_armcap=0x987d + +The detected capabilities in the above example indicate that ARMV7_NEON, +ARMV8_AES, ARMV8_SHA1, ARMV8_SHA256, ARMV8_PMULL, ARMV8_SHA512, ARMV8_SHA3, +ARMV8_UNROLL8_EOR3, and ARMV8_HAVE_SHA3_AND_WORTH_USING are enabled. + +Disable all instruction set extensions: + + export OPENSSL_armcap=0x00 + +=head1 COPYRIGHT + +Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/OPENSSL_init_crypto.pod b/doc/man3/OPENSSL_init_crypto.pod index ae7e89ec251a8..93acb5cd1eb19 100644 --- a/doc/man3/OPENSSL_init_crypto.pod +++ b/doc/man3/OPENSSL_init_crypto.pod @@ -224,6 +224,9 @@ with those threads. The application should either call OPENSSL_thread_stop() on each thread prior to the dlclose() call, or alternatively the original dlopen() call should use the RTLD_NODELETE flag (where available on the platform). +Thread cleanup does not unwind an OpenSSL function interrupted by cancellation +or thread exit; see L. + =head1 RETURN VALUES The functions OPENSSL_init_crypto, and @@ -231,7 +234,7 @@ OPENSSL_INIT_set_config_appname() return 1 on success or 0 on error. =head1 SEE ALSO -L +L, L =head1 HISTORY diff --git a/doc/man3/OPENSSL_malloc.pod b/doc/man3/OPENSSL_malloc.pod index 1907469fcd111..e4d2a12c4c0e6 100644 --- a/doc/man3/OPENSSL_malloc.pod +++ b/doc/man3/OPENSSL_malloc.pod @@ -47,7 +47,7 @@ OPENSSL_MALLOC_SEED char *OPENSSL_strndup(const char *str, size_t s); size_t OPENSSL_strlcat(char *dst, const char *src, size_t size); size_t OPENSSL_strlcpy(char *dst, const char *src, size_t size); - int OPENSSL_strtoul(char *src, char **endptr, int base, unsigned long *num); + int OPENSSL_strtoul(const char *str, char **endptr, int base, unsigned long *num); void *OPENSSL_memdup(void *data, size_t s); void *OPENSSL_clear_realloc(void *p, size_t old_len, size_t num); void *OPENSSL_clear_realloc_array(void *p, size_t old_len, size_t num, @@ -226,8 +226,8 @@ work on all platforms): ...app invocation... 3>/tmp/log$$ If the environment variable B is set, its value -is interpreted as an integer using atoi(3) and supplied to the srandom(3) -call for the random number generator initialisation. +is parsed using OPENSSL_strtoul() and supplied to the srandom(3) call for +the random number generator initialisation. =head1 RETURN VALUES @@ -327,7 +327,7 @@ used against B specification. =head1 COPYRIGHT -Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/OPENSSL_ppccap.pod b/doc/man3/OPENSSL_ppccap.pod index 8434395f3c859..b353226f01f08 100644 --- a/doc/man3/OPENSSL_ppccap.pod +++ b/doc/man3/OPENSSL_ppccap.pod @@ -63,7 +63,7 @@ enabled. Name: B Meaning: Use instructions added in ISA level 2.07. The associated probe -instruction instruction is vcipher (vector AES cipher round). +instruction is vcipher (vector AES cipher round). Effect: Enables AES, SHA-2 sigma, and other ISA 2.07 instructions for AES, SHA-2, GHASH, and Poly1305. @@ -145,7 +145,7 @@ Enable base AltiVec extensions: =head1 COPYRIGHT -Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/OPENSSL_secure_malloc.pod b/doc/man3/OPENSSL_secure_malloc.pod index 510e3bac8fb8d..06c507005c5d5 100644 --- a/doc/man3/OPENSSL_secure_malloc.pod +++ b/doc/man3/OPENSSL_secure_malloc.pod @@ -172,7 +172,7 @@ in OpenSSL 3.6. =head1 COPYRIGHT -Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/OSSL_CMP_CTX_new.pod b/doc/man3/OSSL_CMP_CTX_new.pod index 9e4cd0c22a1a8..2c4cabca696c9 100644 --- a/doc/man3/OSSL_CMP_CTX_new.pod +++ b/doc/man3/OSSL_CMP_CTX_new.pod @@ -907,7 +907,7 @@ The B option was added in OpenSSL 4.1. =head1 COPYRIGHT -Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/OSSL_CMP_SRV_CTX_new.pod b/doc/man3/OSSL_CMP_SRV_CTX_new.pod index aac88bafcc9aa..2052e2963a175 100644 --- a/doc/man3/OSSL_CMP_SRV_CTX_new.pod +++ b/doc/man3/OSSL_CMP_SRV_CTX_new.pod @@ -94,15 +94,27 @@ OSSL_CMP_SRV_CTX_set_grant_implicit_confirm =head1 DESCRIPTION -OSSL_CMP_SRV_process_request() implements the generic aspects of a CMP server. -Its arguments are the B I and the CMP request message +OSSL_CMP_SRV_process_request() implements the generic core aspects +of Certificate Management Protocol (CMP) servers. +Its arguments are the B I and a CMP request message I. It does the typical generic checks on I, calls the respective callback function (if present) for more specific processing, -and then assembles a result message, which may be a CMP error message. +and then assembles a response message, which may be a CMP error message. + +Since OSSL_CMP_SRV_process_request() handles only a single CMP request message, +it may need to be called multiple times until a CMP transaction has ended. If after return of the function the expression I yields -1 then the function has closed the current transaction, which may be due to normal successful end of the transaction or due to an error. +Otherwise, it should be called again with the next request message of the same +transaction (which can be a certificate confirmation or a poll request message). +The function should not be called by multiple threads sharing +the same I without explicitly serialising the calls; +calling it in parallel leads to undefined behavior. +When an earlier call did not yet finish the respective transaction, +calling it in an interleaved way with a new request belonging to a different +transaction will abort the earlier transaction and begin the new one. OSSL_CMP_CTX_server_perform() is an interface to OSSL_CMP_SRV_process_request() that can be used by a CMP client @@ -160,11 +172,21 @@ confirmation of newly enrolled certificates if requested. CMP is defined in RFC 9810 (and CRMF in RFC 4211). -So far the CMP server implementation is limited to one request per CMP message -(and consequently to at most one response component per CMP message). +Like the OpenSSL CMP client, the CMP server implementation documented here +focuses on the Lightweight CMP Profile (RFC 9483). +Among other things, this implies that only commonly used CMP message types are supported +and that each CMP message may not contain multiple certificate requests or responses. + +So far, this server implementation is single-threaded and +should not be called in parallel for any given B I. +It can handle only one CMP transaction at a time (which, of course, is not a problem +for transactions consisting of just a single request/response message pair). =head1 RETURN VALUES +OSSL_CMP_SRV_process_request() returns a CMP response message, which may be an +error message, or NULL on internal errors that preclude producing a response. + OSSL_CMP_SRV_CTX_new() returns a B structure on success, NULL on error. diff --git a/doc/man3/OSSL_CMP_exec_certreq.pod b/doc/man3/OSSL_CMP_exec_certreq.pod index e210c6e6b5dec..bc5afcf0c3271 100644 --- a/doc/man3/OSSL_CMP_exec_certreq.pod +++ b/doc/man3/OSSL_CMP_exec_certreq.pod @@ -51,8 +51,9 @@ OSSL_CMP_get1_certReqTemplate OSSL_CMP_ATAVS **keySpec); =head1 DESCRIPTION -This is the OpenSSL API for doing CMP (Certificate Management Protocol) -client-server transactions, i.e., sequences of CMP requests and responses. +This is the OpenSSL main API for Certificate Management Protocol (CMP) clients. +Each of the OSSL_CMP_exec_*() functions performs a whole CMP transaction, +which is a sequence of related CMP request messages and response messages. All functions take a populated OSSL_CMP_CTX structure as their first argument. Usually the server name, port, and path ("CMP alias") need to be set, as well as @@ -185,8 +186,9 @@ Both must be freed by the caller. CMP is defined in RFC 9810 (and CRMF in RFC 4211). -The CMP client implementation is limited to one request per CMP message -(and consequently to at most one response component per CMP message). +This CMP implementation focuses on the Lightweight CMP Profile (RFC 9483). +Among other things, this implies that only commonly used CMP message types are supported +and that each CMP message may not contain multiple certificate requests or responses. When a client obtains from a CMP server CA certificates that it is going to trust, for instance via the caPubs field of a certificate response or using @@ -253,7 +255,7 @@ were added in OpenSSL 3.4. =head1 COPYRIGHT -Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/OSSL_HTTP_REQ_CTX.pod b/doc/man3/OSSL_HTTP_REQ_CTX.pod index 88e90c2330bd7..498f3270656be 100644 --- a/doc/man3/OSSL_HTTP_REQ_CTX.pod +++ b/doc/man3/OSSL_HTTP_REQ_CTX.pod @@ -303,7 +303,7 @@ All other functions described here were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/OSSL_HTTP_parse_url.pod b/doc/man3/OSSL_HTTP_parse_url.pod index 1e8c3efa77738..1247501cbaeee 100644 --- a/doc/man3/OSSL_HTTP_parse_url.pod +++ b/doc/man3/OSSL_HTTP_parse_url.pod @@ -62,15 +62,19 @@ The port component is optional and defaults to C<0>. If given, it must be in decimal form. If the I argument is not NULL the integer value of the port number is assigned to I<*pport_num> on success. The path component is also optional and defaults to C. + Each non-NULL result pointer argument I, I, I, I, I, I, and I, is assigned the respective url component. +On success, these are string pointers in case the respective element is present; +an empty string (with only the terminating NUL char) +is provided for absent scheme, userinfo, and port; +NULL is provided for absent query and fragment components. Any IPv6 address in I<*phost> is enclosed in C<[> and C<]>. -On success, they are guaranteed to contain non-NULL string pointers, else NULL. -It is the responsibility of the caller to free them using L. -If I is NULL, any given query component is handled as part of the path. A string returned via I<*ppath> is guaranteed to begin with a C character. -For absent scheme, userinfo, port, query, and fragment components -an empty string is provided. +If I is NULL, any given query component is handled as part of the path. +On success is the responsibility of the caller +to free the obtained string pointers using L, +while on failure, all of them are guaranteed to be to NULL. OSSL_HTTP_parse_url() is a special form of OSSL_parse_url() where the scheme, if given, must be C or C. @@ -106,7 +110,7 @@ OCSP_parse_url() was deprecated in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/OSSL_HTTP_transfer.pod b/doc/man3/OSSL_HTTP_transfer.pod index 6c03e347fbc95..573df2b4a9476 100644 --- a/doc/man3/OSSL_HTTP_transfer.pod +++ b/doc/man3/OSSL_HTTP_transfer.pod @@ -207,7 +207,8 @@ The caller is responsible for freeing the BIO pointer obtained. OSSL_HTTP_get() uses HTTP GET to obtain data from I if non-NULL, else from the server contained in the I, and returns it as a BIO. -It supports redirection via HTTP status code 301 or 302. It is meant for +It supports redirection via HTTP status code 301 or 302. +Redirection from HTTPS to HTTP is not allowed. It is meant for transfers with a single round trip, so does not support persistent connections. If I is non-NULL, any host and port components in the I are not used for connecting but the hostname is used, as usual, for the C header. @@ -278,7 +279,7 @@ All the functions described here were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/OSSL_PARAM_BLD.pod b/doc/man3/OSSL_PARAM_BLD.pod index b5a2839385386..2f107ec75081f 100644 --- a/doc/man3/OSSL_PARAM_BLD.pod +++ b/doc/man3/OSSL_PARAM_BLD.pod @@ -208,7 +208,7 @@ The functions described here were all added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/PEM_read_bio_PrivateKey.pod b/doc/man3/PEM_read_bio_PrivateKey.pod index f442168a409fb..46ae14046477e 100644 --- a/doc/man3/PEM_read_bio_PrivateKey.pod +++ b/doc/man3/PEM_read_bio_PrivateKey.pod @@ -59,21 +59,21 @@ PEM_write_bio_PKCS7, PEM_write_PKCS7 - PEM routines int PEM_write_bio_PrivateKey(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); - int PEM_write_bio_PrivateKey_traditional(BIO *bp, EVP_PKEY *x, + int PEM_write_bio_PrivateKey_traditional(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); - int PEM_write_PrivateKey_ex(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + int PEM_write_PrivateKey_ex(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u, OSSL_LIB_CTX *libctx, const char *propq); - int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + int PEM_write_PrivateKey(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); - int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + int PEM_write_bio_PKCS8PrivateKey(BIO *bp, const EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); - int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + int PEM_write_PKCS8PrivateKey(FILE *fp, const EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, const EVP_PKEY *x, int nid, @@ -93,12 +93,12 @@ PEM_write_bio_PKCS7, PEM_write_PKCS7 - PEM routines OSSL_LIB_CTX *libctx, const char *propq); EVP_PKEY *PEM_read_PUBKEY(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u); - int PEM_write_bio_PUBKEY_ex(BIO *bp, EVP_PKEY *x, + int PEM_write_bio_PUBKEY_ex(BIO *bp, const EVP_PKEY *x, OSSL_LIB_CTX *libctx, const char *propq); - int PEM_write_bio_PUBKEY(BIO *bp, EVP_PKEY *x); - int PEM_write_PUBKEY_ex(FILE *fp, EVP_PKEY *x, + int PEM_write_bio_PUBKEY(BIO *bp, const EVP_PKEY *x); + int PEM_write_PUBKEY_ex(FILE *fp, const EVP_PKEY *x, OSSL_LIB_CTX *libctx, const char *propq); - int PEM_write_PUBKEY(FILE *fp, EVP_PKEY *x); + int PEM_write_PUBKEY(FILE *fp, const EVP_PKEY *x); EVP_PKEY *PEM_read_bio_Parameters_ex(BIO *bp, EVP_PKEY **x, OSSL_LIB_CTX *libctx, const char *propq); @@ -107,41 +107,41 @@ PEM_write_bio_PKCS7, PEM_write_PKCS7 - PEM routines X509 *PEM_read_bio_X509(BIO *bp, X509 **x, pem_password_cb *cb, void *u); X509 *PEM_read_X509(FILE *fp, X509 **x, pem_password_cb *cb, void *u); - int PEM_write_bio_X509(BIO *bp, X509 *x); - int PEM_write_X509(FILE *fp, X509 *x); + int PEM_write_bio_X509(BIO *bp, const X509 *x); + int PEM_write_X509(FILE *fp, const X509 *x); X509_ACERT *PEM_read_bio_X509_ACERT(BIO *bp, X509_ACERT **x, pem_password_cb *cb, void *u); X509_ACERT *PEM_read_X509_ACERT(FILE *fp, X509_ACERT **x, pem_password_cb *cb, void *u); - int PEM_write_bio_X509_ACERT(BIO *bp, X509_ACERT *x); - int PEM_write_X509_ACERT(FILE *fp, X509_ACERT *x); + int PEM_write_bio_X509_ACERT(BIO *bp, const X509_ACERT *x); + int PEM_write_X509_ACERT(FILE *fp, const X509_ACERT *x); X509 *PEM_read_bio_X509_AUX(BIO *bp, X509 **x, pem_password_cb *cb, void *u); X509 *PEM_read_X509_AUX(FILE *fp, X509 **x, pem_password_cb *cb, void *u); - int PEM_write_bio_X509_AUX(BIO *bp, X509 *x); - int PEM_write_X509_AUX(FILE *fp, X509 *x); + int PEM_write_bio_X509_AUX(BIO *bp, const X509 *x); + int PEM_write_X509_AUX(FILE *fp, const X509 *x); X509_REQ *PEM_read_bio_X509_REQ(BIO *bp, X509_REQ **x, pem_password_cb *cb, void *u); X509_REQ *PEM_read_X509_REQ(FILE *fp, X509_REQ **x, pem_password_cb *cb, void *u); - int PEM_write_bio_X509_REQ(BIO *bp, X509_REQ *x); - int PEM_write_X509_REQ(FILE *fp, X509_REQ *x); - int PEM_write_bio_X509_REQ_NEW(BIO *bp, X509_REQ *x); - int PEM_write_X509_REQ_NEW(FILE *fp, X509_REQ *x); + int PEM_write_bio_X509_REQ(BIO *bp, const X509_REQ *x); + int PEM_write_X509_REQ(FILE *fp, const X509_REQ *x); + int PEM_write_bio_X509_REQ_NEW(BIO *bp, const X509_REQ *x); + int PEM_write_X509_REQ_NEW(FILE *fp, const X509_REQ *x); X509_CRL *PEM_read_bio_X509_CRL(BIO *bp, X509_CRL **x, pem_password_cb *cb, void *u); X509_CRL *PEM_read_X509_CRL(FILE *fp, X509_CRL **x, pem_password_cb *cb, void *u); - int PEM_write_bio_X509_CRL(BIO *bp, X509_CRL *x); - int PEM_write_X509_CRL(FILE *fp, X509_CRL *x); + int PEM_write_bio_X509_CRL(BIO *bp, const X509_CRL *x); + int PEM_write_X509_CRL(FILE *fp, const X509_CRL *x); PKCS7 *PEM_read_bio_PKCS7(BIO *bp, PKCS7 **x, pem_password_cb *cb, void *u); PKCS7 *PEM_read_PKCS7(FILE *fp, PKCS7 **x, pem_password_cb *cb, void *u); - int PEM_write_bio_PKCS7(BIO *bp, PKCS7 *x); - int PEM_write_PKCS7(FILE *fp, PKCS7 *x); + int PEM_write_bio_PKCS7(BIO *bp, const PKCS7 *x); + int PEM_write_PKCS7(FILE *fp, const PKCS7 *x); The following functions have been deprecated since OpenSSL 3.0, and can be hidden entirely by defining B with a suitable version value, @@ -151,10 +151,10 @@ see L: pem_password_cb *cb, void *u); RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **x, pem_password_cb *cb, void *u); - int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc, + int PEM_write_bio_RSAPrivateKey(BIO *bp, const RSA *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); - int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc, + int PEM_write_RSAPrivateKey(FILE *fp, const RSA *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); @@ -162,24 +162,24 @@ see L: pem_password_cb *cb, void *u); RSA *PEM_read_RSAPublicKey(FILE *fp, RSA **x, pem_password_cb *cb, void *u); - int PEM_write_bio_RSAPublicKey(BIO *bp, RSA *x); - int PEM_write_RSAPublicKey(FILE *fp, RSA *x); + int PEM_write_bio_RSAPublicKey(BIO *bp, const RSA *x); + int PEM_write_RSAPublicKey(FILE *fp, const RSA *x); RSA *PEM_read_bio_RSA_PUBKEY(BIO *bp, RSA **x, pem_password_cb *cb, void *u); RSA *PEM_read_RSA_PUBKEY(FILE *fp, RSA **x, pem_password_cb *cb, void *u); - int PEM_write_bio_RSA_PUBKEY(BIO *bp, RSA *x); - int PEM_write_RSA_PUBKEY(FILE *fp, RSA *x); + int PEM_write_bio_RSA_PUBKEY(BIO *bp, const RSA *x); + int PEM_write_RSA_PUBKEY(FILE *fp, const RSA *x); DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **x, pem_password_cb *cb, void *u); DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **x, pem_password_cb *cb, void *u); - int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc, + int PEM_write_bio_DSAPrivateKey(BIO *bp, const DSA *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); - int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc, + int PEM_write_DSAPrivateKey(FILE *fp, const DSA *x, const EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); @@ -187,17 +187,17 @@ see L: pem_password_cb *cb, void *u); DSA *PEM_read_DSA_PUBKEY(FILE *fp, DSA **x, pem_password_cb *cb, void *u); - int PEM_write_bio_DSA_PUBKEY(BIO *bp, DSA *x); - int PEM_write_DSA_PUBKEY(FILE *fp, DSA *x); + int PEM_write_bio_DSA_PUBKEY(BIO *bp, const DSA *x); + int PEM_write_DSA_PUBKEY(FILE *fp, const DSA *x); DSA *PEM_read_bio_DSAparams(BIO *bp, DSA **x, pem_password_cb *cb, void *u); DSA *PEM_read_DSAparams(FILE *fp, DSA **x, pem_password_cb *cb, void *u); - int PEM_write_bio_DSAparams(BIO *bp, DSA *x); - int PEM_write_DSAparams(FILE *fp, DSA *x); + int PEM_write_bio_DSAparams(BIO *bp, const DSA *x); + int PEM_write_DSAparams(FILE *fp, const DSA *x); DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u); DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u); - int PEM_write_bio_DHparams(BIO *bp, DH *x); - int PEM_write_DHparams(FILE *fp, DH *x); + int PEM_write_bio_DHparams(BIO *bp, const DH *x); + int PEM_write_DHparams(FILE *fp, const DH *x); =head1 DESCRIPTION @@ -591,7 +591,7 @@ were added in OpenSSL 3.4. =head1 COPYRIGHT -Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2001-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/PKCS12_SAFEBAG_get1_cert.pod b/doc/man3/PKCS12_SAFEBAG_get1_cert.pod index 28bed08e3d405..d9a8b185575dd 100644 --- a/doc/man3/PKCS12_SAFEBAG_get1_cert.pod +++ b/doc/man3/PKCS12_SAFEBAG_get1_cert.pod @@ -8,7 +8,8 @@ PKCS12_SAFEBAG_get0_bag_obj, PKCS12_SAFEBAG_get0_bag_type, PKCS12_SAFEBAG_get1_cert_ex, PKCS12_SAFEBAG_get1_cert, PKCS12_SAFEBAG_get1_crl_ex, PKCS12_SAFEBAG_get1_crl, PKCS12_SAFEBAG_get0_safes, PKCS12_SAFEBAG_get0_p8inf, -PKCS12_SAFEBAG_get0_pkcs8 - Get objects from a PKCS#12 safeBag +PKCS12_SAFEBAG_get0_pkcs8, +PKCS8_PRIV_KEY_INFO_get1_skey - Get objects from a PKCS#12 safeBag =head1 SYNOPSIS @@ -31,6 +32,10 @@ PKCS12_SAFEBAG_get0_pkcs8 - Get objects from a PKCS#12 safeBag const PKCS8_PRIV_KEY_INFO *PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag); const X509_SIG *PKCS12_SAFEBAG_get0_pkcs8(const PKCS12_SAFEBAG *bag); + EVP_SKEY *PKCS8_PRIV_KEY_INFO_get1_skey(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq, + const OSSL_PARAM *extra_params, int strict); + =head1 DESCRIPTION PKCS12_SAFEBAG_get0_attr() gets the attribute value corresponding to the B. @@ -60,6 +65,24 @@ from a PKCS8shroudedKeyBag or a keyBag. PKCS12_SAFEBAG_get0_safes() retrieves the set of B contained within a safeContentsBag. +PKCS8_PRIV_KEY_INFO_get1_skey() converts a decrypted B (as +returned by L) into an B symmetric key +object if it holds a symmetric key inside. The algorithm OID and parameters +from the PKCS8 AlgorithmIdentifier are stored as metadata on the key and can be +retrieved via L. + +The I parameter controls how unrecognized algorithm OIDs are handled. +In permissive mode (I is 0), recognized OIDs select an algorithm-specific +SKEYMGMT (e.g., B for AES NIDs) and unrecognized OIDs +fall back to a generic key type. +In strict mode (I is nonzero), only recognized OIDs are accepted and +unrecognized OIDs cause the function to return NULL. + +I is an optional caller-built L array containing +additional metadata to attach to the key (e.g., B for the +friendly name and B for the local key ID from +PKCS#12 bag attributes). May be NULL. + =head1 RETURN VALUES PKCS12_SAFEBAG_get_nid() and PKCS12_SAFEBAG_get_bag_nid() return the NID of the safeBag @@ -70,16 +93,20 @@ Other functions return a valid object of the specified type or NULL if an error L, L, -L +L, +L, +L =head1 HISTORY The functions PKCS12_SAFEBAG_get1_cert_ex() and PKCS12_SAFEBAG_get1_crl_ex() were added in OpenSSL 3.2. +PKCS8_PRIV_KEY_INFO_get1_skey() was added in OpenSSL 4.2. + =head1 COPYRIGHT -Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/PKCS12_decrypt_secretbag.pod b/doc/man3/PKCS12_decrypt_secretbag.pod new file mode 100644 index 0000000000000..c4ade7637a8a7 --- /dev/null +++ b/doc/man3/PKCS12_decrypt_secretbag.pod @@ -0,0 +1,55 @@ +=pod + +=head1 NAME + +PKCS12_decrypt_secretbag - PKCS12 secret bag decrypt function + +=head1 SYNOPSIS + + #include + + PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_secretbag(const PKCS12_SAFEBAG *bag, + const char *pass, int passlen, + OSSL_LIB_CTX *ctx, + const char *propq); + +=head1 DESCRIPTION + +PKCS12_decrypt_secretbag() decrypts a PKCS#12 B that contains an +encrypted PKCS#8 structure (B as the bag type within +B). This is the format used by Java's keytool to store symmetric +secret keys in PKCS#12 files. + +I is the B to decrypt. I is the passphrase of +length I. I and I specify the library context and property +query string for algorithm lookups. + +The returned B can be passed to +L to obtain an B symmetric key object. + +=head1 RETURN VALUES + +PKCS12_decrypt_secretbag() returns a B on success or +NULL on error. The caller must free the returned object with +PKCS8_PRIV_KEY_INFO_free(). + +=head1 SEE ALSO + +L, +L, +L + +=head1 HISTORY + +PKCS12_decrypt_secretbag() was added in OpenSSL 4.2. + +=head1 COPYRIGHT + +Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/PKCS12_gen_mac.pod b/doc/man3/PKCS12_gen_mac.pod index edcbeb5612c34..478c85fa122b3 100644 --- a/doc/man3/PKCS12_gen_mac.pod +++ b/doc/man3/PKCS12_gen_mac.pod @@ -109,7 +109,7 @@ The I function was added in OpenSSL 3.4. =head1 COPYRIGHT -Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/PKCS12_parse.pod b/doc/man3/PKCS12_parse.pod index f16600147b3fc..8b338fc5aff38 100644 --- a/doc/man3/PKCS12_parse.pod +++ b/doc/man3/PKCS12_parse.pod @@ -2,38 +2,91 @@ =head1 NAME -PKCS12_parse - parse a PKCS#12 structure +PKCS12_parse_ex, PKCS12_PARSE_CTX_new, PKCS12_PARSE_CTX_free, +PKCS12_PARSE_CTX_set_pkey, PKCS12_PARSE_CTX_set_cert, +PKCS12_PARSE_CTX_set_ca, PKCS12_PARSE_CTX_set_skeys, +PKCS12_parse +- parse a PKCS#12 structure =head1 SYNOPSIS #include + PKCS12_PARSE_CTX *PKCS12_PARSE_CTX_new(void); + void PKCS12_PARSE_CTX_free(PKCS12_PARSE_CTX *ctx); + void PKCS12_PARSE_CTX_set_pkey(PKCS12_PARSE_CTX *ctx, EVP_PKEY **pkey); + void PKCS12_PARSE_CTX_set_cert(PKCS12_PARSE_CTX *ctx, X509 **cert); + void PKCS12_PARSE_CTX_set_ca(PKCS12_PARSE_CTX *ctx, STACK_OF(X509) **ca); + void PKCS12_PARSE_CTX_set_skeys(PKCS12_PARSE_CTX *ctx, STACK_OF(EVP_SKEY) **skeys); + + int PKCS12_parse_ex(PKCS12 *p12, const char *pass, PKCS12_PARSE_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq); int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca); =head1 DESCRIPTION -PKCS12_parse() parses a PKCS12 structure. +PKCS12_parse_ex() parses a PKCS12 structure, extracting the components +specified by the parse context B. B is the B structure to parse. B is the passphrase to use. -If successful the private key will be written to B<*pkey>, the corresponding -certificate to B<*cert> and any additional certificates to B<*ca>. +B is a B that specifies which components to extract. +B and B specify the library context and property query string +for algorithm lookups. + +PKCS12_PARSE_CTX_new() allocates a new parse context. All output pointers +are initially NULL, meaning no components will be extracted until configured +via the setter functions. + +PKCS12_PARSE_CTX_free() frees the parse context. It does not free any +extracted objects. + +PKCS12_PARSE_CTX_set_pkey() configures the context to extract the private key +into B<*pkey>. + +PKCS12_PARSE_CTX_set_cert() configures the context to extract the matching +certificate into B<*cert>. + +PKCS12_PARSE_CTX_set_ca() configures the context to extract additional +certificates into B<*ca>. + +PKCS12_PARSE_CTX_set_skeys() configures the context to extract symmetric +secret keys into B<*skeys> as a B. All SecretBag structures +found in the PKCS#12 file will be decrypted and added to the stack. +This is used for PKCS#12 files containing SecretBag structures, such as +those created by Java's keytool utility. + +PKCS12_parse() is a wrapper around PKCS12_parse_ex() that +extracts the private key, certificate, and CA certificates. It does not +support symmetric key extraction or custom library contexts. =head1 NOTES Each of the parameters B, B, and B can be NULL in which case the private key, the corresponding certificate, or the additional certificates, -respectively, will be discarded. +respectively, will not be returned to the caller. If any of B and B is non-NULL the variable it points to is initialized. If B is non-NULL and B<*ca> is NULL a new STACK will be allocated. If B is non-NULL and B<*ca> is a valid STACK then additional certificates are appended in the given order to B<*ca>. +The corresponding certificate is identified by matching it against the private +key. This means that B<*cert> is only set when both B and B are +non-NULL and a private key was found. +When B is NULL or B is NULL, no matching is performed and the +certificate that would have been the corresponding one is treated as an +additional certificate: it is added to B<*ca> if B is non-NULL, +or freed otherwise. + The B and B attributes (if present) on each certificate will be stored in the B and B attributes of the B structure. +If parsing fails B<*pkey>, B<*cert> are set to NULL. If B is non-NULL +then B<*ca> is left unchanged. If B is configured in the parse context +then B<*skeys> is also left unchanged on failure. + The parameter B is interpreted as a string in the UTF-8 encoding. If it is not valid UTF-8, then it is assumed to be ISO8859-1 instead. @@ -45,15 +98,41 @@ L, for example. =head1 RETURN VALUES -PKCS12_parse() returns 1 for success and zero if an error occurred. +PKCS12_parse_ex() and PKCS12_parse() return 1 for success and zero if an +error occurred. The error can be obtained from L +=head1 EXAMPLES + +Extract all components including symmetric keys from a PKCS#12 file: + + PKCS12_PARSE_CTX *ctx = PKCS12_PARSE_CTX_new(); + EVP_PKEY *pkey = NULL; + X509 *cert = NULL; + STACK_OF(X509) *ca = NULL; + STACK_OF(EVP_SKEY) *skeys = NULL; + + PKCS12_PARSE_CTX_set_pkey(ctx, &pkey); + PKCS12_PARSE_CTX_set_cert(ctx, &cert); + PKCS12_PARSE_CTX_set_ca(ctx, &ca); + PKCS12_PARSE_CTX_set_skeys(ctx, &skeys); + + if (PKCS12_parse_ex(p12, password, ctx, NULL, NULL)) { + /* use pkey, cert, ca, skeys */ + } + + EVP_PKEY_free(pkey); + X509_free(cert); + OSSL_STACK_OF_X509_free(ca); + sk_EVP_SKEY_pop_free(skeys, EVP_SKEY_free); + PKCS12_PARSE_CTX_free(ctx); + =head1 BUGS -Only a single private key and corresponding certificate is returned by this -function. More complex PKCS#12 files with multiple private keys will only -return the first match. +Only a single private key and corresponding certificate is returned by +PKCS12_parse() and PKCS12_parse_ex(). More complex PKCS#12 files with +multiple private keys will only return the first match. Only B and B attributes are currently stored in certificates. Other attributes are discarded. @@ -65,9 +144,16 @@ Attributes currently cannot be stored in the private key B structure. L, L +=head1 HISTORY + +PKCS12_parse_ex(), PKCS12_PARSE_CTX_new(), PKCS12_PARSE_CTX_free(), +PKCS12_PARSE_CTX_set_pkey(), PKCS12_PARSE_CTX_set_cert(), +PKCS12_PARSE_CTX_set_ca(), and PKCS12_PARSE_CTX_set_skeys() +were added in OpenSSL 4.2. + =head1 COPYRIGHT -Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/PKCS5_PBE_keyivgen.pod b/doc/man3/PKCS5_PBE_keyivgen.pod index eff685c1023d4..2b925a09e17ae 100644 --- a/doc/man3/PKCS5_PBE_keyivgen.pod +++ b/doc/man3/PKCS5_PBE_keyivgen.pod @@ -186,7 +186,7 @@ This is required for PBKDF2 FIPS compliance. =head1 COPYRIGHT -Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/PKCS7_decrypt.pod b/doc/man3/PKCS7_decrypt.pod index 3534559d5950c..751556501b91c 100644 --- a/doc/man3/PKCS7_decrypt.pod +++ b/doc/man3/PKCS7_decrypt.pod @@ -52,7 +52,7 @@ L, L, L =head1 COPYRIGHT -Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/PKCS7_sign.pod b/doc/man3/PKCS7_sign.pod index 620b3b699dfee..7670cb300ecc6 100644 --- a/doc/man3/PKCS7_sign.pod +++ b/doc/man3/PKCS7_sign.pod @@ -20,8 +20,9 @@ PKCS7_sign_ex, PKCS7_sign PKCS7_sign_ex() creates and returns a PKCS#7 signedData structure. I is the certificate to sign with, I is the corresponding -private key. I is an optional set of extra certificates to include -in the PKCS#7 structure (for example any intermediate CAs in the chain). +private key. I is an optional additional set of certificates to include, +unless B is set, in the B structure. They may be used as +untrusted CA certificates for chain building or as extra signer certificates. The library context I and property query I are used when retrieving algorithms from providers. @@ -36,14 +37,14 @@ Many S/MIME clients expect the signed content to include valid MIME headers. If the B flag is set MIME headers for type C are prepended to the data. -If B is set the signer's certificate and the extra I -will not be included in the PKCS7 structure. -The signer's certificate must still be supplied in the I parameter -though. This can reduce the size of the signatures if the signer's certificates +If B is set, the signer's certificate and extra certificates +given in the I parameter will not be included in the B structure. +The signer's certificate must still be supplied in the B parameter +though. This can reduce the size of the signatures if the signer certificates can be obtained by other means: for example a previously signed message. -The data being signed is included in the PKCS7 structure, unless -B is set in which case it is omitted. This is used for PKCS7 +The data being signed is included in the B structure, unless +B is set in which case it is omitted. This is used for PKCS#7 detached signatures which are used in S/MIME plaintext signed messages for example. @@ -90,7 +91,7 @@ called to finalize the structure if streaming is not enabled. Alternative signing digests can also be specified using this method. If I and I are NULL then a certificates only -PKCS#7 structure is output. +B structure is output. In versions of OpenSSL before 1.0.0 the I and I parameters must not be NULL. @@ -105,7 +106,7 @@ Some advanced attributes such as counter signatures are not supported. =head1 RETURN VALUES -PKCS7_sign_ex() and PKCS7_sign() return either a valid PKCS7 structure +PKCS7_sign_ex() and PKCS7_sign() return either a valid B structure or NULL if an error occurred. The error can be obtained from ERR_get_error(3). =head1 SEE ALSO diff --git a/doc/man3/PKCS7_sign_add_signer.pod b/doc/man3/PKCS7_sign_add_signer.pod index 24353484abc7e..f0c2847916dc0 100644 --- a/doc/man3/PKCS7_sign_add_signer.pod +++ b/doc/man3/PKCS7_sign_add_signer.pod @@ -30,16 +30,31 @@ Unless the B flag is set the returned B structure is not complete and must be finalized either by streaming (if applicable) or a call to PKCS7_final(). +PKCS7_add_certificate() adds to the B structure I the certificate +I, which may be an end-entity (signer) certificate +or a CA certificate useful for chain building. +This is done internally by L and similar signing functions +but can also be called directly to add another such certificate. +It may be used also before calling L +to provide any missing certificate(s) needed for chain building +or to provide a fallback signer certificate. + +PKCS7_add_crl() adds the CRL I to the B structure I. +This may be called to provide certificate status information +to be included when signing or to use when verifying the B structure. =head1 NOTES -The main purpose of this function is to provide finer control over a PKCS#7 +The main purpose of these functions is to provide finer control over a PKCS#7 signed data structure where the simpler PKCS7_sign() function defaults are not appropriate. For example if multiple signers or non default digest algorithms are needed. +The PKCS7 structure I argument must be of type signed data or +signed-and-enveloped data or an error will be returned. + Any of the following flags (ored together) can be passed in the I -parameter. +parameter of PKCS7_sign_add_signer(). If B is set then an attempt is made to copy the content digest value from the B structure: to add a signer to an existing structure. @@ -47,15 +62,15 @@ An error occurs if a matching digest value cannot be found to copy. The returned B structure will be valid and finalized when this flag is set. If B is set in addition to B then the -B structure will not be finalized so additional attributes +B structure will not be finalized so additional attributes can be added. In this case an explicit call to PKCS7_SIGNER_INFO_sign() is needed to finalize it. -If B is set the signer's certificate will not be included in the -B structure, the signer's certificate must still be supplied in the -I parameter though. This can reduce the size of the signature if the -signers certificate can be obtained by other means: for example a previously -signed message. +If B is set, this call does not add I to the +B structure. Certificates already present in the structure are left +unchanged. I must still be supplied. This can reduce the size of +the signature if the signer certificate can be obtained by other means, +for example a previously signed message. The signedData structure includes several PKCS#7 authenticatedAttributes including the signing time, the PKCS#7 content type and the supported list of @@ -67,25 +82,14 @@ If present the SMIMECapabilities attribute indicates support for the following algorithms: triple DES, 128 bit RC2, 64 bit RC2, DES and 40 bit RC2. If any of these algorithms is disabled then it will not be included. -PKCS7_sign_add_signers() returns an internal pointer to the B -structure just added, which can be used to set additional attributes -before it is finalized. - -PKCS7_add_certificate() adds to the B structure I the certificate -I, which may be an end-entity (signer) certificate -or a CA certificate useful for chain building. -This is done internally by L and similar signing functions. -It may have to be used before calling L -in order to provide any missing certificate(s) needed for verification. - -PKCS7_add_crl() adds the CRL I to the B structure I. -This may be called to provide certificate status information -to be included when signing or to use when verifying the B structure. +Certificates and CRLs are added to the I or +I fields of B or B structures. =head1 RETURN VALUES -PKCS7_sign_add_signers() returns an internal pointer to the B -structure just added or NULL if an error occurs. +PKCS7_sign_add_signer() returns an internal pointer to the B +structure just added (which can be used to set additional attributes +before it is finalized), or NULL if an error occurs. PKCS7_add_certificate() and PKCS7_add_crl() return 1 on success, 0 on error. @@ -100,7 +104,7 @@ The PPKCS7_sign_add_signer() function was added in OpenSSL 1.0.0. =head1 COPYRIGHT -Copyright 2007-2016 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/PKCS7_verify.pod b/doc/man3/PKCS7_verify.pod index 3dd30b63bfdc4..ead63cd04f4e6 100644 --- a/doc/man3/PKCS7_verify.pod +++ b/doc/man3/PKCS7_verify.pod @@ -21,8 +21,8 @@ PKCS7_verify, PKCS7_dataVerify, PKCS7_get0_signers - verify a PKCS#7 signedData PKCS7_verify() is very similar to L. It verifies a PKCS#7 signedData structure given in I. -The optional I parameter refers to a set of certificates -in which to search for signer's certificates. +The optional I parameter can provide a list of certificates, +which is searched first for signer's certificates. It is also used as a source of untrusted intermediate CA certificates for chain building. I may contain extra untrusted CA certificates that may be used for @@ -34,9 +34,13 @@ Otherwise I should be NULL, and then the signed data must be in I. The content is written to the BIO I unless it is NULL. I is an optional set of flags, which can be used to modify the operation. -PKCS7_get0_signers() retrieves the signer certificates from I, it does +PKCS7_get0_signers() retrieves the signer certificates from I +by matching the pairs of certificate issuer and serial number contained in +the SignerInfos with available candidate signer certificates. It does B check their validity or whether any signatures are valid. The I and I parameters have the same meanings as in PKCS7_verify(). +If the result is not NULL, the caller must free the structure returned using +sk_X509_free(), but must not free the certificates included there. PKCS7_dataVerify() operates in a similar fashion to PKCS7_verify, with a few notable exceptions: @@ -68,16 +72,16 @@ B. The default behavior allows this, for compatibility with older versions of OpenSSL. -An attempt is made to locate all the signer's certificates, first looking in +An attempt is made to locate all the signer certificates, first looking in the I parameter (if it is not NULL). Then they are looked up in any certificates contained in the I structure unless B is set. -If any signer's certificates cannot be located the operation fails. +If any signer certificates cannot be located the operation fails. -Each signer's certificate is chain verified -using the trusted certificate store I if supplied. -The purpose required in this verification is I -unless a different one (or B) has been set in -I using L and unless B is set. +Each signer certificate is chain verified +using I as the trusted certificate store if supplied. +Unless B is set, +the default purpose required in this verification is I. +The default purpose may be overridden using L. Any internal certificates in the message, which may have been added using L, are used as untrusted CAs unless B is set. @@ -96,8 +100,8 @@ parameter to change the default verify behaviour. Only the flag B is meaningful to PKCS7_get0_signers(). If B is set the certificates in the message itself are not -searched when locating the signer's certificates. -This means that all the signer's certificates must be in the I parameter. +searched when locating the signer certificates. +This means that all the signer certificates must be in the I parameter. If B is set and CRL checking is enabled in I then any CRLs in the message itself are ignored. @@ -106,11 +110,10 @@ If the B flag is set MIME headers for type C are deleted from the content. If the content is not of type C then an error is returned. -If B is set the signer's certificates are not chain verified. +If B is set the signer certificates are not chain verified. If B is set then the certificates contained in the message are -not used as untrusted CAs. This means that the whole verify chain (apart from -the signer's certificates) must be contained in the trusted store. +not used as untrusted CA certificates for chain building. If B is set then the signatures on the data are not checked. @@ -118,7 +121,7 @@ If B is set then the signatures on the data are not checked. One application of B is to only accept messages signed by a small number of certificates. The acceptable certificates would be passed -in the I parameter. In this case if the signer's certificate is not one +in the I parameter. In this case, if the signer's certificate is not one of the certificates supplied in I then the verify will fail because the signer cannot be found. @@ -144,7 +147,7 @@ The error can be obtained from L. =head1 BUGS -The trusted certificate store is not searched for the signer's certificates. +The trusted certificate store is not searched for the signer certificates. This is primarily due to the inadequacies of the current B functionality. diff --git a/doc/man3/RAND_bytes.pod b/doc/man3/RAND_bytes.pod index 9d3bd349cb1a7..611799a324804 100644 --- a/doc/man3/RAND_bytes.pod +++ b/doc/man3/RAND_bytes.pod @@ -50,7 +50,7 @@ ignored. RAND_set1_random_provider() specifies a provider, I, which will be used by the library context I for all of the generate calls above instead -of the built-in in DRBGs and entropy source. Pass NULL for the provider +of the built-in DRBGs and entropy source. Pass NULL for the provider to disable the random provider functionality. In this case, the built-in DRBGs and entropy source will be used. This call should not be considered thread safe. @@ -115,7 +115,7 @@ The RAND_set1_random_provider() function was added in OpenSSL 3.5 =head1 COPYRIGHT -Copyright 2000-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/RAND_set_DRBG_type.pod b/doc/man3/RAND_set_DRBG_type.pod index 4d26029c2fe29..5184df735423a 100644 --- a/doc/man3/RAND_set_DRBG_type.pod +++ b/doc/man3/RAND_set_DRBG_type.pod @@ -39,11 +39,19 @@ These functions must be called before the random bit generators are first created in the library context. They will return an error if the call is made too late. +Note that with strict seeding, enabled via the B option of +the B configuration section, used by default for the B +seed source or implied by an B build, a provider +(for example the FIPS provider) requesting entropy or a nonce +instantiates the seed source before the application's first use of it. +RAND_set_seed_source_type() fails once this happens. + The default DRBG is "CTR-DRBG" using the "AES-256-CTR" cipher. The default seed source can be configured when OpenSSL is compiled by setting B<-DOPENSSL_DEFAULT_SEED_SRC=SEED-SRC>. If not set then -"SEED-SRC" is used. +"SEED-SRC" is used. The property query used when fetching the default +seed source can similarly be set with B<-DOPENSSL_DEFAULT_SEED_PROPQ>. =head1 EXAMPLES @@ -62,7 +70,7 @@ These functions were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/SSL_CIPHER_get_name.pod b/doc/man3/SSL_CIPHER_get_name.pod index d0cee8adf1a38..fed1b48ed8812 100644 --- a/doc/man3/SSL_CIPHER_get_name.pod +++ b/doc/man3/SSL_CIPHER_get_name.pod @@ -72,7 +72,7 @@ different to the digest used to calculate the MAC for encrypted records. SSL_CIPHER_get_kx_nid() returns the key exchange NID corresponding to the method used by B. If there is no key exchange, then B is returned. -If any appropriate key exchange algorithm can be used (as in the case of TLS 1.3 +If any appropriate key exchange algorithm can be used (as in the case of (D)TLS 1.3 cipher suites) B is returned. Examples (not comprehensive): NID_kx_rsa @@ -83,7 +83,7 @@ cipher suites) B is returned. Examples (not comprehensive): SSL_CIPHER_get_auth_nid() returns the authentication NID corresponding to the method used by B. If there is no authentication, then B is returned. If any appropriate authentication algorithm can be used (as in the case of -TLS 1.3 cipher suites) B is returned. Examples (not comprehensive): +(D)TLS 1.3 cipher suites) B is returned. Examples (not comprehensive): NID_auth_rsa NID_auth_ecdsa @@ -201,7 +201,7 @@ The OPENSSL_cipher_name() function was added in OpenSSL 1.1.1. =head1 COPYRIGHT -Copyright 2000-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/SSL_COMP_add_compression_method.pod b/doc/man3/SSL_COMP_add_compression_method.pod index 56f708ca88ce6..8d41a19f9e659 100644 --- a/doc/man3/SSL_COMP_add_compression_method.pod +++ b/doc/man3/SSL_COMP_add_compression_method.pod @@ -110,7 +110,7 @@ The SSL_COMP_get0_name() and SSL_comp_get_id() functions were added in OpenSSL 1 =head1 COPYRIGHT -Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2001-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/SSL_CONF_cmd.pod b/doc/man3/SSL_CONF_cmd.pod index 15f969eb61808..5eb1fffc67720 100644 --- a/doc/man3/SSL_CONF_cmd.pod +++ b/doc/man3/SSL_CONF_cmd.pod @@ -96,8 +96,8 @@ Only used by servers. Requires B<-serverpref>. =item B<-allow_no_dhe_kex> -In TLSv1.3 allow a non-(ec)dhe based key exchange mode on resumption. This means -that there will be no forward secrecy for the resumed session. +In (D)TLSv1.3 allow a non-(ec)dhe based key exchange mode on resumption. This +means that there will be no forward secrecy for the resumed session. =item B<-prefer_no_dhe_kex> @@ -107,12 +107,45 @@ Equivalent to B. Only used by servers. =item B<-strict> -Enables strict mode protocol handling. Equivalent to setting +Enables strict certificate chain checking. Equivalent to setting B. +When enabled, this enforces additional TLS certificate chain requirements that +many implementations ignore: + +=over 4 + +=item * + +All certificates in the chain must use signature algorithms that are in the +configured or negotiated list. Without strict mode, SHA1-based signatures are +permitted as a fallback even if not explicitly configured. + +=item * + +The parameters (such as EC curves) of CA certificates in the chain are +validated against the supported list, not just the end-entity certificate. + +=item * + +For client authentication in TLS 1.2 and earlier, the certificate type must +match one of the types requested by the server in the CertificateRequest +message. + +=item * + +For client authentication, the certificate chain must contain a certificate +issued by one of the CAs in the server's CertificateRequest CA list (if +provided). + +=back + +Suite B modes (enabled via B or +B) always imply strict mode. + =item B<-sigalgs> I -This sets the supported signature algorithms for TLSv1.2 and TLSv1.3. +This sets the supported signature algorithms for (D)TLSv1.2 and (D)TLSv1.3. For clients this value is used directly for the supported signature algorithms extension. For servers it is used to determine which signature algorithms to support. @@ -124,7 +157,7 @@ B is one of B, B or B and B is a supported algorithm OID short name such as B, B, B, B or B. B is one of the signature schemes defined -in TLSv1.3, specified using the IETF name, e.g., B, +in (D)TLSv1.3, specified using the IETF name, e.g., B, B, or B. Additional providers may make available further algorithms via the TLS-SIGALG capability. Signature scheme names and public key algorithm names (but not the hash names) @@ -136,12 +169,12 @@ activated providers are permissible. Note: algorithms which specify a PKCS#1 v1.5 signature scheme (either by using B as the B or by using one of the B -identifiers) are ignored in TLSv1.3 and will not be negotiated. +identifiers) are ignored in (D)TLSv1.3 and will not be negotiated. =item B<-client_sigalgs> I This sets the supported signature algorithms associated with client -authentication for TLSv1.2 and TLSv1.3. For servers the B is used +authentication for (D)TLSv1.2 and (D)TLSv1.3. For servers the B is used in the B field of a B message. For clients it is used to determine which signature algorithm to use with the client certificate. If a server does not request a certificate this @@ -154,7 +187,7 @@ value set for B<-sigalgs> will be used instead. This sets the supported groups. For clients, the groups are sent using the supported groups extension. For servers, it is used to determine which -group to use. This setting affects groups used for signatures (in TLSv1.2 +group to use. This setting affects groups used for signatures (in (D)TLSv1.2 and earlier) and key exchange. In its simplest form the I argument is a colon separated list of @@ -169,15 +202,15 @@ Group names are case-insensitive in OpenSSL 3.5 and later. The list should be in order of preference with the most preferred group first. The first group listed will also be used for the B sent by a client -in a TLSv1.3 B. +in a (D)TLSv1.3 B. -The commands below list the IANA names for TLS 1.2 and TLS 1.3, +The commands below list the IANA names for (D)TLS 1.2 and (D)TLS 1.3, respectively: $ openssl list -tls1_2 -tls-groups $ openssl list -tls1_3 -tls-groups -The recommended groups for TLS 1.3 are presently documented in the default +The recommended groups for (D)TLS 1.3 are presently documented in the default TLS group list in the OpenSSL code base. Starting with OpenSSL 3.5, the hybrid algorithm B is first in this default list. It mitigates against threats from future quantum computers while @@ -189,7 +222,7 @@ in the HISTORY section below. An enriched alternative syntax, that enables clients to send multiple keyshares and allows servers to prioritise some groups over others, is described in L. -Since TLS 1.2 has neither keyshares nor a hello retry mechanism, with TLS 1.2 +Since (D)TLS 1.2 has neither keyshares nor a hello retry mechanism, with (D)TLS 1.2 the enriched syntax is ultimately equivalent to just a simple ordered list of groups, as with the simple form above. @@ -213,42 +246,42 @@ Curve names are case-insensitive in OpenSSL 3.5 and later. =item B<-tx_cert_comp> -Enables support for sending TLSv1.3 compressed certificates. +Enables support for sending (D)TLSv1.3 compressed certificates. =item B<-no_tx_cert_comp> -Disables support for sending TLSv1.3 compressed certificates. +Disables support for sending (D)TLSv1.3 compressed certificates. =item B<-rx_cert_comp> -Enables support for receiving TLSv1.3 compressed certificates. +Enables support for receiving (D)TLSv1.3 compressed certificates. =item B<-no_rx_cert_comp> -Disables support for receiving TLSv1.3 compressed certificates. +Disables support for receiving (D)TLSv1.3 compressed certificates. =item B<-comp> =item B<-cipher> I -Sets the TLSv1.2 and below ciphersuite list to B. This list will be -combined with any configured TLSv1.3 ciphersuites. Note: syntax checking +Sets the (D)TLSv1.2 and below ciphersuite list to B. This list will be +combined with any configured (D)TLSv1.3 ciphersuites. Note: syntax checking of B is currently not performed unless a B or B structure is associated with B. =item B<-ciphersuites> I<1.3ciphers> -Sets the available ciphersuites for TLSv1.3 to value. This is a -colon-separated list of TLSv1.3 ciphersuite names in order of preference. This -list will be combined any configured TLSv1.2 and below ciphersuites. +Sets the available ciphersuites for (D)TLSv1.3 to value. This is a +colon-separated list of (D)TLSv1.3 ciphersuite names in order of preference. +This list will be combined any configured (D)TLSv1.2 and below ciphersuites. See L for more information. =item B<-min_protocol> I, B<-max_protocol> I Sets the minimum and maximum supported protocol. Currently supported protocol values are B, B, -B, B for TLS; B, B for DTLS, and B -for no limit. +B, B for TLS; B, B, B for DTLS, +and B for no limit. If either the lower or upper bound is not specified then only the other bound applies, if specified. If your application supports both TLS and DTLS you can specify any of these @@ -259,13 +292,13 @@ deprecated alternative commands below. =item B<-record_padding> I -Controls use of TLSv1.3 record layer padding. B is a string of the +Controls use of (D)TLSv1.3 record layer padding. B is a string of the form "number[,number]" where the (required) first number is the padding block size (in octets) for application data, and the optional second number is the padding block size for handshake and alert messages. If the optional second number is omitted, the same padding will be applied to all messages. -Padding attempts to pad TLSv1.3 records so that they are a multiple of the set +Padding attempts to pad (D)TLSv1.3 records so that they are a multiple of the set length on send. A value of 0 or 1 turns off padding as relevant. Otherwise, the values must be >1 or <=16384. @@ -322,11 +355,11 @@ Note that B<-no_ssl3> is a no-op since support for SSLv3 was removed in OpenSSL Switches replay protection, on or off respectively. With replay protection on, OpenSSL will automatically detect if a session ticket has been used more than -once, TLSv1.3 has been negotiated, and early data is enabled on the server. A -full handshake is forced if a session ticket is used a second or subsequent +once, (D)TLSv1.3 has been negotiated, and early data is enabled on the server. +A full handshake is forced if a session ticket is used a second or subsequent time. Anti-Replay is on by default unless overridden by a configuration file and is only used by servers. Anti-replay measures are required for compliance with -the TLSv1.3 specification. Some applications may be able to mitigate the replay +the (D)TLSv1.3 specification. Some applications may be able to mitigate the replay risks in other ways and in such cases the built-in OpenSSL functionality is not required. Switching off anti-replay is equivalent to B. @@ -346,16 +379,16 @@ Note: the command prefix (if set) alters the recognised B) from +early data that the server rejected. +Both cases are reported as SSL_EARLY_DATA_REJECTED. A server uses the SSL_read_early_data() function to receive early data on a connection for which early data has been enabled using @@ -370,7 +378,7 @@ All of the functions described above were added in OpenSSL 1.1.1. =head1 COPYRIGHT -Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/SSL_set_bio.pod b/doc/man3/SSL_set_bio.pod index 07f46ab4d783d..000b6dcaa24c5 100644 --- a/doc/man3/SSL_set_bio.pod +++ b/doc/man3/SSL_set_bio.pod @@ -101,6 +101,20 @@ BIO is subsequently set on the SSL object which can support blocking mode, blocking mode will not be automatically re-enabled. For more information, see L. +When B is a DTLS listener object, the BIO is configured for nonblocking +operation, since a listener demultiplexes one socket to many connections and so +cannot allow a read for one of them to block. Blocking behaviour is provided by +waiting for readiness of the socket instead; see L. + +When B is a DTLS listener object, these functions must not be called +concurrently with any other operations on the listener or its connections. +This includes L, L, +L, and any I/O operations on connections created from +the listener. The BIO should typically be configured once before calling +L and not modified afterward while the listener is in use. +If the listener was created with the B flag, +all operations including BIO changes must be performed from a single thread. + =head1 RETURN VALUES SSL_set_bio(), SSL_set0_rbio() and SSL_set0_wbio() cannot fail. @@ -117,7 +131,7 @@ SSL_set0_rbio() and SSL_set0_wbio() were added in OpenSSL 1.1.0. =head1 COPYRIGHT -Copyright 2000-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/SSL_set_blocking_mode.pod b/doc/man3/SSL_set_blocking_mode.pod index 4cf45fea29c99..12cba0aab1adf 100644 --- a/doc/man3/SSL_set_blocking_mode.pod +++ b/doc/man3/SSL_set_blocking_mode.pod @@ -3,7 +3,7 @@ =head1 NAME SSL_set_blocking_mode, SSL_get_blocking_mode - configure blocking mode for a -QUIC SSL object +QUIC or DTLS listener SSL object =head1 SYNOPSIS @@ -14,11 +14,14 @@ QUIC SSL object =head1 DESCRIPTION -SSL_set_blocking_mode() can be used to enable or disable blocking mode on a QUIC -connection SSL object. By default, blocking is enabled, unless the SSL object is -configured to use an underlying read or write BIO which cannot provide a poll -descriptor (see L), as blocking mode cannot be -supported in this case. +SSL_set_blocking_mode() can be used to enable or disable blocking mode on an SSL +object which has a blocking mode of its own. For QUIC that means a connection, +stream or listener SSL object. For DTLS it means a listener SSL object created +with L, or a connection SSL object returned from one by +L. By default, blocking is enabled, unless the SSL +object is configured to use an underlying read or write BIO which cannot provide +a poll descriptor (see L), as blocking mode cannot +be supported in this case. To enable blocking mode, call SSL_set_blocking_mode() with I set to 1; to disable it, call SSL_set_blocking_mode() with I set to 0. @@ -30,10 +33,13 @@ until the requested operation can be performed. In nonblocking mode, these calls will fail if the requested operation cannot be performed immediately; see L. -These functions are only applicable to QUIC connection SSL objects. Other kinds -of SSL object, such as those for TLS, automatically function in blocking or -nonblocking mode based on whether the underlying network read and write BIOs -provided to the SSL object are themselves configured in nonblocking mode. +Other kinds of SSL object, such as those for TLS or a DTLS object which did not +come from a listener, automatically function in blocking or nonblocking mode +based on whether the underlying network read and write BIOs provided to the SSL +object are themselves configured in nonblocking mode, and so have no separate +blocking mode to configure. + +=head2 QUIC connections Where a QUIC connection SSL object is used in nonblocking mode, an application is responsible for ensuring that the SSL object is ticked regularly; see @@ -44,28 +50,51 @@ connection SSL object with a network BIO which cannot support blocking mode. To re-enable blocking mode in this case, an application must set a network BIO which can support blocking mode and explicitly call SSL_set_blocking_mode(). +=head2 DTLS listeners + +A DTLS listener demultiplexes a single network socket to many connections, so it +cannot allow a read for one connection to block and thereby stall the others. +Its network BIO is therefore configured for nonblocking operation when it is set, +and blocking mode is provided by waiting for readiness of that socket instead, +as it is for QUIC. This applies to L on the listener as +well as to reads and writes on the connections it returns. A write which the +socket cannot accept is retried once it can be sent, where a nonblocking +connection discards the datagram and reports that the write should be retried. + +A connection SSL object returned by L inherits the +blocking mode of the listener it came from. Calling SSL_set_blocking_mode() on +such a connection overrides that inheritance for that connection only, and there +is no way to return it to inheriting afterwards. The blocking mode of a listener +is normally configured once, before it is used. + +A DTLS listener whose network BIO cannot provide a poll descriptor, such as one +using a memory BIO, has nothing to wait on and is therefore nonblocking +whatever has been requested. + =head1 RETURN VALUES SSL_set_blocking_mode() returns 1 on success and 0 on failure. The function -fails if called on an SSL object which does not represent a QUIC connection, -or if blocking mode cannot be used for the given connection. +fails if called on an SSL object which has no blocking mode of its own, or if +blocking mode was requested and cannot be used for the given object. -SSL_get_blocking_mode() returns 1 if blocking is currently enabled. It returns --1 if called on an unsupported SSL object. +SSL_get_blocking_mode() returns 1 if blocking is currently enabled and 0 if it +is not. It returns -1 if called on an SSL object which has no blocking mode of +its own. =head1 SEE ALSO -L, L, L, -L, L +L, L, L, +L, L, L =head1 HISTORY The SSL_set_blocking_mode() and SSL_get_blocking_mode() functions were added in -OpenSSL 3.2. +OpenSSL 3.2. Support for DTLS listeners and the connections created from them +was added in OpenSSL 4.1. =head1 COPYRIGHT -Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/SSL_set_connect_state.pod b/doc/man3/SSL_set_connect_state.pod index 7c1969e7fc037..efa2ce08d67e7 100644 --- a/doc/man3/SSL_set_connect_state.pod +++ b/doc/man3/SSL_set_connect_state.pod @@ -69,7 +69,7 @@ L =head1 COPYRIGHT -Copyright 2001-2017 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2001-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/SSL_set_retry_verify.pod b/doc/man3/SSL_set_retry_verify.pod index 0f20a49306160..d64816784af98 100644 --- a/doc/man3/SSL_set_retry_verify.pod +++ b/doc/man3/SSL_set_retry_verify.pod @@ -13,7 +13,8 @@ SSL_set_retry_verify - indicate that certificate verification should be retried =head1 DESCRIPTION SSL_set_retry_verify() should be called from the certificate verification -callback on a client when the application wants to indicate that the handshake +callback on a client or server when the application wants to indicate that +the handshake should be suspended and the control should be returned to the application. L will return 1 as a consequence until the handshake is resumed again by the application, retrying the verification step. @@ -23,7 +24,7 @@ Please refer to L for further details. =head1 NOTES The effect of calling SSL_set_retry_verify() outside of the certificate -verification callback on the client side is undefined. +verification callback is undefined. =head1 RETURN VALUES @@ -60,7 +61,7 @@ callback. =head1 COPYRIGHT -Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/X509V3_EXT_nconf_nid.pod b/doc/man3/X509V3_EXT_nconf_nid.pod new file mode 100644 index 0000000000000..41f2c315180a2 --- /dev/null +++ b/doc/man3/X509V3_EXT_nconf_nid.pod @@ -0,0 +1,51 @@ +=pod + +=head1 NAME + +X509V3_EXT_nconf, X509V3_EXT_nconf_nid - functions to +create X.509 certificate extensions based on OpenSSL configuration + + +=head1 SYNOPSIS + + #include + + X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, + const char *value); + X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, const char *name, + const char *value); + +=head1 DESCRIPTION + +X509V3_EXT_nconf_nid() and X509V3_EXT_nconf() create a requested X.509 +extension identified either by I or I correspondingly using +I contains the string to encode. + +I the configuration information where additional data +will be read from. I will typically come from a config +file. + +In case when I value is null, the default one is used. + +=head1 NOTES + +Normally these functions should not be called directly. For many extensions +they will not produce the expected results without a suitably configured +context (I and I arguments) that specifies the target object, issuer +data etc. + +=head1 RETURN VALUES + +X509V3_EXT_nconf() and X509V3_EXT_nconf_nid() return an B +object on success and NULL on failure. + +=head1 COPYRIGHT + +Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/X509_ATTRIBUTE.pod b/doc/man3/X509_ATTRIBUTE.pod index a7054395b7c25..868e8b690c8af 100644 --- a/doc/man3/X509_ATTRIBUTE.pod +++ b/doc/man3/X509_ATTRIBUTE.pod @@ -152,6 +152,9 @@ ASN1_STRING_set_by_NID(), and the passed in I must be in the format required for that object type or an error will occur. If I is not -1 then internally ASN1_STRING_type_new() is used with the passed in I. +If I is B and I is not -1, I is +taken as complete octets of the bit string, so the resulting +B is created with zero unused bits. If I is 0 the call does nothing except return 1. X509_ATTRIBUTE_create() creates a new B using the I diff --git a/doc/man3/X509_LOOKUP.pod b/doc/man3/X509_LOOKUP.pod index b17a47e9bb828..7f5178af9ce6e 100644 --- a/doc/man3/X509_LOOKUP.pod +++ b/doc/man3/X509_LOOKUP.pod @@ -116,16 +116,18 @@ L. X509_LOOKUP_load_file() is similar to X509_LOOKUP_load_file_ex() but uses NULL for the library context I and property query I. -X509_LOOKUP_add_dir() passes a directory specification from which -certificates and CRLs are loaded on demand into the associated -B. +X509_LOOKUP_add_dir() adds to the given store lookup list I +a directory specification, from which trusted certificates and CRLs +may be looked up later on demand, +typically when building a certificate chain or verifying a certificate. I indicates what type of object is expected. This can only be used with a lookup using the implementation L. -X509_LOOKUP_add_store_ex() passes a URI for a directory-like or file-like -structure from which containers with certificates and CRLs are loaded on demand -into the associated B. The library context I and property +X509_LOOKUP_add_store_ex() adds to the given store lookup list I +a URI or filename for a directory-like or file-like structure. As with +X509_LOOKUP_add_dir(), certificates and CRLs will be loaded only on demand. +The library context I and property query I are used when fetching algorithms from providers. If I is not NULL, it must be a URI to a store, which may represent a single container or a whole catalogue of containers. @@ -242,7 +244,7 @@ added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/X509_LOOKUP_hash_dir.pod b/doc/man3/X509_LOOKUP_hash_dir.pod index b512f2a3cf186..6898b68ea1294 100644 --- a/doc/man3/X509_LOOKUP_hash_dir.pod +++ b/doc/man3/X509_LOOKUP_hash_dir.pod @@ -158,7 +158,7 @@ OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/X509_NAME_ENTRY_get_object.pod b/doc/man3/X509_NAME_ENTRY_get_object.pod index c35c6c202ac16..f7c146d49865c 100644 --- a/doc/man3/X509_NAME_ENTRY_get_object.pod +++ b/doc/man3/X509_NAME_ENTRY_get_object.pod @@ -31,10 +31,10 @@ X509_NAME_ENTRY_create_by_OBJ - X509_NAME_ENTRY utility functions =head1 DESCRIPTION X509_NAME_ENTRY_get_object() retrieves the field name of B in -and B structure. +an B structure. X509_NAME_ENTRY_get_data() retrieves the field value of B in -and B structure. +an B structure. X509_NAME_ENTRY_set_object() sets the field name of B to B. @@ -66,11 +66,11 @@ set first so the relevant field information can be looked up internally. =head1 RETURN VALUES -X509_NAME_ENTRY_get_object() returns a valid B structure if it is -set or NULL if an error occurred. +X509_NAME_ENTRY_get_object() returns an internal pointer to a valid +B structure if it is set, or NULL if an error occurred. -X509_NAME_ENTRY_get_data() returns a valid B structure if it is set -or NULL if an error occurred. +X509_NAME_ENTRY_get_data() returns an internal pointer to a valid +B structure if it is set, or NULL if an error occurred. X509_NAME_ENTRY_set_object() and X509_NAME_ENTRY_set_data() return 1 on success or 0 on error. diff --git a/doc/man3/X509_NAME_print_ex.pod b/doc/man3/X509_NAME_print_ex.pod index f09bd1f79f417..f86849d26e2ee 100644 --- a/doc/man3/X509_NAME_print_ex.pod +++ b/doc/man3/X509_NAME_print_ex.pod @@ -121,7 +121,7 @@ L =head1 COPYRIGHT -Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/X509_STORE_CTX_get_by_subject.pod b/doc/man3/X509_STORE_CTX_get_by_subject.pod index b13d109a301e9..46df68a8702eb 100644 --- a/doc/man3/X509_STORE_CTX_get_by_subject.pod +++ b/doc/man3/X509_STORE_CTX_get_by_subject.pod @@ -53,7 +53,7 @@ L =head1 COPYRIGHT -Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/X509_STORE_add_cert.pod b/doc/man3/X509_STORE_add_cert.pod index cb083dc1d068a..ca447213e6a06 100644 --- a/doc/man3/X509_STORE_add_cert.pod +++ b/doc/man3/X509_STORE_add_cert.pod @@ -102,16 +102,18 @@ query I are used when fetching algorithms from providers. X509_STORE_load_file() is similar to X509_STORE_load_file_ex() but uses NULL for the library context I and property query I. -X509_STORE_load_path() sets in B the given directory with -certificate files in PEM format as source of trusted certificate(s). -The certificate files in I are only looked up when required, e.g., when -building the certificate chain or when verifying a peer certificate. +X509_STORE_load_path() adds to B the given directory, which should +contain certificate files in PEM format, as a source of trusted certificates. +The certificate files in I are only looked up when required, +typically on building a certificate chain when verifying a certificate. The certificates in the directory must be in hashed form, as documented in L. Use the L utility to create the necessary links. -X509_STORE_load_store_ex() loads trusted certificate(s) into an B -from a given URI. The library context I and +X509_STORE_load_store_ex() adds to the given B a URI or filename +for a directory-like or file-like structure. As with X509_STORE_load_path(), +the trusted certificates that may be found there will be loaded only on demand. +The library context I and property query I are used when fetching algorithms from providers. I must not be NULL. It must be a URI to a store, which may represent a single container or a whole catalogue of containers. diff --git a/doc/man3/X509_STORE_new.pod b/doc/man3/X509_STORE_new.pod index 330cbe53c76b7..5404175122d2e 100644 --- a/doc/man3/X509_STORE_new.pod +++ b/doc/man3/X509_STORE_new.pod @@ -78,7 +78,7 @@ functions were added in OpenSSL 1.1.0. =head1 COPYRIGHT -Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/X509_VERIFY_PARAM_set1_host.pod b/doc/man3/X509_VERIFY_PARAM_set1_host.pod new file mode 100644 index 0000000000000..d21096ad444cf --- /dev/null +++ b/doc/man3/X509_VERIFY_PARAM_set1_host.pod @@ -0,0 +1,329 @@ +=pod + +=head1 NAME + +X509_VERIFY_PARAM_set1_host, X509_VERIFY_PARAM_add1_host, +X509_VERIFY_PARAM_get0_host, +X509_VERIFY_PARAM_set1_email, +X509_VERIFY_PARAM_get0_email, +X509_VERIFY_PARAM_set1_rfc822, X509_VERIFY_PARAM_add1_rfc822, +X509_VERIFY_PARAM_set1_smtputf8, X509_VERIFY_PARAM_add1_smtputf8, +X509_VERIFY_PARAM_set1_ip, X509_VERIFY_PARAM_add1_ip, +X509_VERIFY_PARAM_set1_ip_asc, X509_VERIFY_PARAM_add1_ip_asc, +X509_VERIFY_PARAM_get1_ip_asc, +X509_VERIFY_PARAM_set1_host_input_validation, +X509_VERIFY_PARAM_set1_rfc822_input_validation, +X509_VERIFY_PARAM_set1_smtputf8_input_validation, +X509_VERIFY_PARAM_set1_ip_input_validation +- X509 verification reference identifier configuration + +=head1 SYNOPSIS + + #include + + int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); + int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); + char *X509_VERIFY_PARAM_get0_host(X509_VERIFY_PARAM *param, int idx); + + int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, + const char *email, size_t emaillen); + char *X509_VERIFY_PARAM_get0_email(X509_VERIFY_PARAM *param); + int X509_VERIFY_PARAM_set1_rfc822(X509_VERIFY_PARAM *param, + const char *email, size_t emaillen); + int X509_VERIFY_PARAM_add1_rfc822(X509_VERIFY_PARAM *param, + const char *email, size_t emaillen); + int X509_VERIFY_PARAM_set1_smtputf8(X509_VERIFY_PARAM *param, + const char *email, size_t emaillen); + int X509_VERIFY_PARAM_add1_smtputf8(X509_VERIFY_PARAM *param, + const char *email, size_t emaillen); + + int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, + const unsigned char *ip, size_t iplen); + int X509_VERIFY_PARAM_add1_ip(X509_VERIFY_PARAM *param, + const unsigned char *ip, size_t iplen); + int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, + const char *ip_asc); + int X509_VERIFY_PARAM_add1_ip_asc(X509_VERIFY_PARAM *param, + const char *ip_asc); + char *X509_VERIFY_PARAM_get1_ip_asc(X509_VERIFY_PARAM *param); + + void X509_VERIFY_PARAM_set1_host_input_validation(X509_VERIFY_PARAM *param, + int (*validate_host)(const char *name, size_t len)); + void X509_VERIFY_PARAM_set1_rfc822_input_validation(X509_VERIFY_PARAM *param, + int (*validate_rfc822)(const char *name, size_t len)); + void X509_VERIFY_PARAM_set1_smtputf8_input_validation(X509_VERIFY_PARAM *param, + int (*validate_smtputf8)(const char *name, size_t len)); + void X509_VERIFY_PARAM_set1_ip_input_validation(X509_VERIFY_PARAM *param, + int (*validate_ip)(const uint8_t *name, size_t len)); + +=head1 DESCRIPTION + +These functions configure the set of B that an +B will match against the names asserted by a peer's +certificate during certificate verification. Four families of reference +identifier are supported, each matched against a distinct location in the +certificate: + +=over 4 + +=item * + +B, matched against B entries in the certificate's +subject alternative name (SAN) extension. + +=item * + +B, matched against B entries in the +certificate's SAN. + +=item * + +B, matched against B entries of type +B (RFC 8398) in the certificate's SAN. + +=item * + +B, matched against B entries in the certificate's +SAN. + +=back + +For each family the C form clears any previously configured values +and installs the supplied value as the sole reference identifier, and the +C form appends the supplied value to the existing list. When a list contains more than +one entry, the certificate is considered to match if any of the configured +values matches a corresponding name in the certificate. + +For the functions whose value is a string with an explicit length (the +hostname and email families), if the length argument is zero +the value must be NUL-terminated; otherwise the length argument must be the +length of the value in bytes. + +=head2 Hostname matching + +X509_VERIFY_PARAM_set1_host() sets in I the expected DNS hostname to +I, for matching against B SAN entries in the peer's +certificate, clearing any previously specified hostname. If I is NULL +or the empty string, the host list is cleared, hostname matching is +disabled, and the call succeeds. + +X509_VERIFY_PARAM_add1_host() adds I as an additional reference +identifier that can match a B SAN entry in the peer's certificate. +Any previous names set via X509_VERIFY_PARAM_set1_host() or +X509_VERIFY_PARAM_add1_host() are retained. If I is NULL or the empty +string, the list is left unchanged and the call succeeds. + +X509_VERIFY_PARAM_get0_host() returns the Ith DNS hostname previously +configured on I via X509_VERIFY_PARAM_set1_host() or +X509_VERIFY_PARAM_add1_host(), or NULL if I is out of range. To iterate +over the configured hostnames, start with I = 0 and increment I +until the function returns NULL. The returned string is owned by the library +and remains valid until I is modified or freed; the caller must +not free it. + +Hostname matching is governed by the B host flags; +see L for the available flags and +their effect on wildcards and subject-DN consultation. The names by which +the peer matched can be retrieved via L. + +=head2 Email matching + +The C<_rfc822()> family of functions is used for email names that have +ASCII localpart addresses, in which case the domain part of the address +must be represented in A-label form. They are used to specify the list of +values to match against the SAN B entries in certificates. + +X509_VERIFY_PARAM_set1_rfc822() clears all expected RFC 822 email +addresses, and sets the expected RFC 822 email address to I for +matching against B SAN entries in the peer's certificate. A NULL +I clears the RFC 822 list and returns success; the empty string +clears the list but returns failure. + +X509_VERIFY_PARAM_add1_rfc822() adds I as an additional reference +identifier that can match a B SAN entry in the peer's +certificate. Any previous names set via X509_VERIFY_PARAM_set1_rfc822(), +X509_VERIFY_PARAM_add1_rfc822(), or X509_VERIFY_PARAM_set1_email() are +retained on success; no change is made on failure. I must not be +NULL, and the empty string is rejected as a failure. + +The C<_smtputf8()> family of functions is used for email names that have a +non-ASCII localpart, in which case the domain part of the address must be +represented in U-label form. They are used to specify the list of values +to match against the B entries of type +B (RFC 8398) in certificates. + +X509_VERIFY_PARAM_set1_smtputf8() sets the expected SMTPUTF8 email address +to I for matching against B SAN entries of type +B, clearing any previously specified SMTPUTF8 email +address. A NULL I clears the SMTPUTF8 list and returns success; the +empty string clears the list but returns failure. + +X509_VERIFY_PARAM_add1_smtputf8() adds I as an additional reference +identifier that can match an B SAN entry of type +B in the peer's certificate. Any previous names set +via X509_VERIFY_PARAM_set1_smtputf8(), X509_VERIFY_PARAM_add1_smtputf8(), +or X509_VERIFY_PARAM_set1_email() are retained on success; no change is +made on failure. I must not be NULL, and the empty string is +rejected as a failure. + +X509_VERIFY_PARAM_set1_email() is a convenience function that calls +X509_VERIFY_PARAM_set1_rfc822() and X509_VERIFY_PARAM_set1_smtputf8() with +the same I argument and succeeds if either call succeeds. This +allows a caller that does not know whether a given email value is +ASCII-localpart or SMTPUTF8 to install it for matching against both +B and B id-on-SmtpUTF8Mailbox SAN entries. A NULL +I clears both lists and returns success. + +When any email address is configured, certificate verification +automatically invokes L. The peer is considered +verified when any one of the specified RFC 822 names matches an +B SAN entry, or any one of the specified SMTPUTF8 names +matches an B id-on-SmtpUTF8Mailbox SAN entry, in the +certificate. + +X509_VERIFY_PARAM_get0_email() returns a previously configured expected +email address from I, or NULL if neither an RFC 822 nor an +SMTPUTF8 address has been set. When both have been configured, the first +RFC 822 address is returned in preference to any SMTPUTF8 address. The +returned string is owned by the library and remains valid until I +is modified or freed; the caller must not free it. + +=head2 IP address matching + +X509_VERIFY_PARAM_set1_ip() sets the expected IP address to I for +matching against B SAN entries in the peer's certificate, +clearing any previously specified IP address. The I argument must be +in binary format, in network byte order, and I must be 4 for IPv4 +or 16 for IPv6. A NULL I clears the IP list, disables IP matching, and +returns success. + +X509_VERIFY_PARAM_add1_ip() adds I as an additional reference +identifier that can match an B SAN entry in the peer's +certificate. Any previous addresses set via X509_VERIFY_PARAM_set1_ip(), +X509_VERIFY_PARAM_add1_ip(), X509_VERIFY_PARAM_set1_ip_asc(), or +X509_VERIFY_PARAM_add1_ip_asc() are retained on success; no change is +made on failure. It is a failure if I is NULL or I is neither +4 nor 16. + +X509_VERIFY_PARAM_set1_ip_asc() sets the expected IP address to I +for matching against B SAN entries in the peer's certificate, +clearing any previously specified IP address. The I argument +must be a NUL-terminated ASCII string: dotted decimal quad for IPv4 and +colon-separated hexadecimal for IPv6. The condensed "::" notation is +supported for IPv6 addresses. A NULL I clears the IP list and +returns success; a string that cannot be parsed as an IP address, including +the empty string, returns failure and leaves the list unchanged. + +X509_VERIFY_PARAM_add1_ip_asc() adds I as an additional reference +identifier that can match an B SAN entry in the peer's +certificate. The format requirements on I are the same as for +X509_VERIFY_PARAM_set1_ip_asc(). Any previous addresses set via +X509_VERIFY_PARAM_set1_ip(), X509_VERIFY_PARAM_add1_ip(), +X509_VERIFY_PARAM_set1_ip_asc(), or X509_VERIFY_PARAM_add1_ip_asc() are +retained on success; no change is made on failure. I must not be +NULL; a string that cannot be parsed as an IP address, including the empty +string, is a failure. + +When any IP address is configured, certificate verification automatically +invokes L to match against B SAN entries. + +X509_VERIFY_PARAM_get1_ip_asc() returns a previously configured expected +IP address from I as a freshly allocated ASCII string (dotted +decimal quad for IPv4, colon-separated hexadecimal for IPv6), or NULL if +no IP address has been set. The caller is responsible for freeing the +returned string with L. + +=head2 Input validation + +X509_VERIFY_PARAM_set1_host_input_validation(), +X509_VERIFY_PARAM_set1_rfc822_input_validation(), +X509_VERIFY_PARAM_set1_smtputf8_input_validation() and +X509_VERIFY_PARAM_set1_ip_input_validation() install a caller-supplied +callback that validates a reference-identifier value at the point it is +configured via the corresponding C or C function. The +callback receives the value and its length, and returns a nonzero value to +accept the input or zero to reject it; on rejection the C/C +call fails and no value is stored. + +These callbacks override OpenSSL's built-in input validation for the +corresponding name type. They affect only the validation performed when +reference identifiers are installed on the verification parameters; they +do not affect the actual matching performed during certificate +verification. + +=head1 RETURN VALUES + +The C and C functions return 1 for success and 0 for +failure. + +X509_VERIFY_PARAM_get0_host() and X509_VERIFY_PARAM_get0_email() return +a pointer to a library-owned string, or NULL if no such configured value +exists (X509_VERIFY_PARAM_get0_host() also returns NULL when its index +argument is out of range). Callers must not free the returned pointer. + +X509_VERIFY_PARAM_get1_ip_asc() returns a freshly allocated string that +the caller must free with L, or NULL if no IP address +has been configured. + +The C functions do not return a value. + +=head1 NOTES + +The reference identifier lists configured by these functions are +consulted by L when the corresponding B +checks are performed. Configuring a list for a given name type implicitly +enables the corresponding check; clearing it (by passing NULL or the +empty string to the C form) disables it. + +By default only the subject alternative name extension is consulted. When +B is set, the configured hostnames +are also matched against the B attribute of the certificate's +subject distinguished name, and the configured RFC 822 email addresses +against the subject B attribute. SMTPUTF8 email and IP +addresses have no subject distinguished name counterpart and are always +matched only against the subject alternative name extension. See +L and L. + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L, +L, +L, +L + +=head1 HISTORY + +X509_VERIFY_PARAM_set1_host(), X509_VERIFY_PARAM_add1_host(), +X509_VERIFY_PARAM_set1_email(), X509_VERIFY_PARAM_set1_ip(), and +X509_VERIFY_PARAM_set1_ip_asc() were added in OpenSSL 1.0.2. + +X509_VERIFY_PARAM_get0_host(), X509_VERIFY_PARAM_get0_email(), and +X509_VERIFY_PARAM_get1_ip_asc() were added in OpenSSL 3.0. + +X509_VERIFY_PARAM_add1_ip_asc() was added in OpenSSL 1.1.0. + +X509_VERIFY_PARAM_set1_rfc822(), X509_VERIFY_PARAM_add1_rfc822(), +X509_VERIFY_PARAM_set1_smtputf8(), X509_VERIFY_PARAM_add1_smtputf8(), +X509_VERIFY_PARAM_add1_ip(), +X509_VERIFY_PARAM_set1_host_input_validation(), +X509_VERIFY_PARAM_set1_rfc822_input_validation(), +X509_VERIFY_PARAM_set1_smtputf8_input_validation(), and +X509_VERIFY_PARAM_set1_ip_input_validation() were added in OpenSSL 4.0. + +=head1 COPYRIGHT + +Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/X509_VERIFY_PARAM_set_flags.pod b/doc/man3/X509_VERIFY_PARAM_set_flags.pod index a2078ae247e33..7f953f9a9fe9f 100644 --- a/doc/man3/X509_VERIFY_PARAM_set_flags.pod +++ b/doc/man3/X509_VERIFY_PARAM_set_flags.pod @@ -11,22 +11,7 @@ X509_VERIFY_PARAM_get_depth, X509_VERIFY_PARAM_set_auth_level, X509_VERIFY_PARAM_get_auth_level, X509_VERIFY_PARAM_set_time, X509_VERIFY_PARAM_get_time, X509_VERIFY_PARAM_add0_policy, X509_VERIFY_PARAM_set1_policies, -X509_VERIFY_PARAM_get0_host, -X509_VERIFY_PARAM_set1_host, X509_VERIFY_PARAM_add1_host, -X509_VERIFY_PARAM_set_hostflags, -X509_VERIFY_PARAM_get_hostflags, -X509_VERIFY_PARAM_get0_peername, -X509_VERIFY_PARAM_get0_email, -X509_VERIFY_PARAM_set1_email, -X509_VERIFY_PARAM_set1_rfc822, X509_VERIFY_PARAM_add1_rfc822, -X509_VERIFY_PARAM_set1_smtputf8, X509_VERIFY_PARAM_add1_smtputf8, -X509_VERIFY_PARAM_set1_ip, X509_VERIFY_PARAM_add1_ip, -X509_VERIFY_PARAM_set1_ip_asc, X509_VERIFY_PARAM_add1_ip_asc, -X509_VERIFY_PARAM_get1_ip_asc, -X509_VERIFY_PARAM_set1_host_input_validation, -X509_VERIFY_PARAM_set1_rfc822_input_validation, -X509_VERIFY_PARAM_set1_smtputf8_input_validation, -X509_VERIFY_PARAM_set1_ip_input_validation +X509_VERIFY_PARAM_get0_peername - X509 verification parameters =head1 SYNOPSIS @@ -62,51 +47,31 @@ X509_VERIFY_PARAM_set1_ip_input_validation int auth_level); int X509_VERIFY_PARAM_get_auth_level(const X509_VERIFY_PARAM *param); - char *X509_VERIFY_PARAM_get0_host(X509_VERIFY_PARAM *param, int n); - int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, - const char *name, size_t namelen); - int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, - const char *name, size_t namelen); - void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, - unsigned int flags); - unsigned int X509_VERIFY_PARAM_get_hostflags(const X509_VERIFY_PARAM *param); char *X509_VERIFY_PARAM_get0_peername(const X509_VERIFY_PARAM *param); - char *X509_VERIFY_PARAM_get0_email(X509_VERIFY_PARAM *param); - int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, - const char *email, size_t emaillen); - int X509_VERIFY_PARAM_set1_rfc822(X509_VERIFY_PARAM *param, - const char *email, size_t emaillen); - int X509_VERIFY_PARAM_add1_rfc822(X509_VERIFY_PARAM *param, - const char *email, size_t emaillen); - int X509_VERIFY_PARAM_set1_smtputf8(X509_VERIFY_PARAM *param, - const char *email, size_t emaillen); - int X509_VERIFY_PARAM_add1_smtputf8(X509_VERIFY_PARAM *param, - const char *email, size_t emaillen); - char *X509_VERIFY_PARAM_get1_ip_asc(X509_VERIFY_PARAM *param); - int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, - const unsigned char *ip, size_t iplen); - int X509_VERIFY_PARAM_add1_ip(X509_VERIFY_PARAM *param, - const unsigned char *ip, size_t iplen); - int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ip_asc); - int X509_VERIFY_PARAM_add1_ip_asc(X509_VERIFY_PARAM *param, const char *ip_asc); - void X509_VERIFY_PARAM_set1_ip_input_validation(X509_VERIFY_PARAM *param, - int (*validate_ip)(const uint8_t *name, size_t len)); - void X509_VERIFY_PARAM_set1_host_input_validation(X509_VERIFY_PARAM *param, - int (*validate_host)(const char *name, size_t len)); - void X509_VERIFY_PARAM_set1_rfc822_input_validation(X509_VERIFY_PARAM *param, - int (*validate_rfc822)(const char *name, size_t len)); - void X509_VERIFY_PARAM_set1_smtputf8_input_validation(X509_VERIFY_PARAM *param, - int (*validate_smtputf8)(const char *name, size_t len)); =head1 DESCRIPTION -These functions manipulate the B structure associated with -a certificate verification operation. - -The X509_VERIFY_PARAM_set_flags() function sets the flags in I by oring -it with I. See L for a complete +An B object collects the configuration consumed by a +certificate verification operation: the verification flags, the purpose +and trust selectors, the verification time, the maximum chain depth, the +required security level, the acceptable certificate policies, and the +reference identifiers against which the peer certificate's names are +matched. B objects are typically attached to an +B or an B/B and reach L +through the B being verified; values propagate from one +parameter set to another according to the rules in L. + +These functions manipulate an B. The functions for +configuring its reference identifiers (hostnames, email addresses, and +IP addresses) are documented in +L. + +The X509_VERIFY_PARAM_set_flags() function sets the flags in I by +ORing it with I. See L for a complete description of values the I parameter can take. +X509_VERIFY_PARAM_clear_flags() clears the flags I in I. + X509_VERIFY_PARAM_get_flags() returns the flags in I. X509_VERIFY_PARAM_get_inh_flags() returns the inheritance flags in I @@ -114,8 +79,6 @@ which specifies how verification flags are copied from one structure to another. X509_VERIFY_PARAM_set_inh_flags() sets the inheritance flags. See the L section for a description of these bits. -X509_VERIFY_PARAM_clear_flags() clears the flags I in I. - X509_VERIFY_PARAM_set_purpose() sets the verification purpose in I to I. This determines the acceptable purpose of the certificate chain, for example B. @@ -123,24 +86,36 @@ The purpose requirement is cleared if I is B. X509_VERIFY_PARAM_get_purpose() returns the purpose in I. -X509_VERIFY_PARAM_set_trust() sets the trust setting in I to -I. +X509_VERIFY_PARAM_set_trust() sets the trust selector in I to +I, which must be one of the B identifiers defined +in F. This is a legacy mechanism that most +applications should not use; see L. There is no public getter +for the trust selector. X509_VERIFY_PARAM_set_time() sets the verification time in I to -I. Normally the current time is used. +I, which is then used as the reference time for certificate and CRL +validity-period checks in place of the current time. Calling this +function automatically sets the B flag (see +L). If X509_VERIFY_PARAM_set_time() has not +been called, validity checks are performed against the current time. + +X509_VERIFY_PARAM_get_time() returns the verification time configured on +I. -X509_VERIFY_PARAM_add0_policy() adds I to the acceptable policy set. -Contrary to preexisting documentation of this function it does not enable -policy checking. +X509_VERIFY_PARAM_add0_policy() adds I to the acceptable policy +set. Policy checking itself must be enabled separately, either by setting +B via X509_VERIFY_PARAM_set_flags() or by +calling X509_VERIFY_PARAM_set1_policies(). X509_VERIFY_PARAM_set1_policies() enables policy checking (it is disabled by default) and sets the acceptable policy set to I. Any existing policy set is cleared. The I parameter can be NULL to clear an existing policy set. -X509_VERIFY_PARAM_set_depth() sets the maximum verification depth to I. -That is the maximum number of intermediate CA certificates that can appear in a -chain. +X509_VERIFY_PARAM_set_depth() sets the maximum verification depth to +I. That is the maximum number of intermediate CA certificates that +can appear in a chain. If X509_VERIFY_PARAM_set_depth() is not called, +the verification depth defaults to 100. A maximal depth chain contains 2 more certificates than the limit, since neither the end-entity certificate nor the trust-anchor count against this limit. @@ -166,189 +141,38 @@ Security level 1 requires at least 80-bit-equivalent security and is broadly interoperable, though it will, for example, reject MD5 signatures or RSA keys shorter than 1024 bits. -X509_VERIFY_PARAM_get0_host() returns the Ith expected DNS hostname that has -been set using X509_VERIFY_PARAM_set1_host() or X509_VERIFY_PARAM_add1_host(). -To obtain all names start with I = 0 and increment I as long as no NULL -pointer is returned. - -X509_VERIFY_PARAM_set1_host() sets in I the expected -DNS hostname to I, clearing any previously specified hostname. -If I is NULL or the empty string, the list of hostnames is cleared -and hostname checks are not performed on the peer certificate. -If I is zero, I must be NUL-terminated, -otherwise I must be set to the length of I. - -When a hostname is specified, -certificate verification automatically invokes L -with flags equal to the I argument given to -X509_VERIFY_PARAM_set_hostflags() (default zero). Applications -are strongly advised to use this interface in preference to explicitly -calling L, hostname checks may be out of scope -with the DANE-EE(3) certificate usage, and the internal check will -be suppressed as appropriate when DANE verification is enabled. - -When the subject CommonName will not be ignored, whether as a result of the -B host flag, or because no DNS subject -alternative names are present in the certificate, any DNS name constraints in -issuer certificates apply to the subject CommonName as well as the subject -alternative name extension. - -When the subject CommonName will be ignored, whether as a result of the -B host flag, or because some DNS subject -alternative names are present in the certificate, DNS name constraints in -issuer certificates will not be applied to the subject DN. -As described in X509_check_host(3) the B -flag takes precedence over the B flag. - -X509_VERIFY_PARAM_get_hostflags() returns any host flags previously set via a -call to X509_VERIFY_PARAM_set_hostflags(). - -X509_VERIFY_PARAM_add1_host() adds I as an additional reference -identifier that can match the peer's certificate. Any previous names -set via X509_VERIFY_PARAM_set1_host() or X509_VERIFY_PARAM_add1_host() -are retained, no change is made if I is NULL or the empty string. When -multiple names are configured, the peer is considered verified when -any name matches. - +The remaining accessor on this page reports a result populated during +certificate verification rather than a configured parameter: X509_VERIFY_PARAM_get0_peername() returns the DNS hostname or subject CommonName from the peer certificate that matched one of the reference -identifiers. When wildcard matching is not disabled, or when a -reference identifier specifies a parent domain (starts with ".") -rather than a hostname, the peer name may be a wildcard name or a -sub-domain of the reference identifier respectively. The return -string is allocated by the library and is no longer valid once the -associated I argument is freed. Applications must not free -the return value. - -X509_VERIFY_PARAM_get0_email() returns the expected RFC822 email address. - -The _rfc822() family of functions is used for email names that have -ASCII localpart addresses, in which case the domain part of the -address must be represented in A-label form. They are used to -specify the list of values to match against the SAN Email names in -certificates. - -X509_VERIFY_PARAM_set1_rfc822() clears all expected RFC822 email -addresses, and sets the expected RFC822 email address to I. If -I is NULL no expected address is set. Otherwise, if -I is zero, I must be NUL-terminated; if I -is nonzero, I must be set to the length of I. When -any email address is specified, certificate verification automatically -invokes L. - -X509_VERIFY_PARAM_add1_rfc822() adds I as an additional -reference identifier that can match RFC822 email addresses in the -peer's certificate. Any previous names set via -X509_VERIFY_PARAM_set1_rfc822(), X509_VERIFY_PARAM_add1_rfc822(), or -X509_VERIFY_PARAM_set1_email() are -retained on success, no change is made on failure. It is a failure if -email is NULL or the empty string. -The peer is considered verified -when any one of the specified RFC822 or SMTPUTF8 names matches a corresponding email -address SAN in the certificate. - -The _smtputf8() family of functions is used for email names that have -a non-ASCII localpart addresses, in which case the domain part of the -address must be represented in U-label form. They are used to -specify the list of values to match against the OTHERNAME SMTPUTF8 names in -certificates. - -X509_VERIFY_PARAM_set1_smtputf8() sets the expected SMTPUTF8 email address to -I. -If I is NULL, SMTPUTF8 email checking is disabled. Otherwise, -if I is zero, I must be NUL-terminated; if I is nonzero, -I must be set to the length of I. When any email address -is specified, certificate verification automatically invokes -L. - -X509_VERIFY_PARAM_add1_smtputf8() adds I as an additional -reference identifier that can match SMTPUTF8 email addresses in the -peer's certificate. Any previous names set via -X509_VERIFY_PARAM_set1_smtputf8(), X509_VERIFY_PARAM_add1_smtputf8(), or -X509_VERIFY_PARAM_set1_email() are -retained on success, no change is made on failure. It is a failure if -email is NULL or the empty string. The peer is considered verified -when any one of the specified RFC822 or SMTPUTF8 names matches a corresponding email -address SAN in the certificate. - -X509_VERIFY_PARAM_set1_email() calls X509_VERIFY_PARAM_set_rfc822(), and -X509_VERIFY_PARAM_set_smtputf8() and succeeds if either call succeeds. - -X509_VERIFY_PARAM_get1_ip_asc() returns the expected IP address as a string. -The caller is responsible for freeing it. - -X509_VERIFY_PARAM_set1_ip() sets the expected IP address to I. -If I is NULL, IP address checking is disabled. Otherwise, -the I argument must be in binary format, in network byte-order and -I must be set to 4 for IPv4 and 16 for IPv6. When an IP -address is specified, certificate verification automatically invokes -L. - -X509_VERIFY_PARAM_add1_ip() adds I as an additional reference -identifier that can match the peer's certificate on success. Any -previous addresses set via X509_VERIFY_PARAM_set1_ip(), -X509_VERIFY_PARAM_add1_ip(), X509_VERIFY_PARAM_set1_ip_asc(), or -X509_VERIFY_PARAM_add1_ip_asc() are retained. No change is made on -failure. -It is a failure if I is NULL or the value I is neither 4 nor 16 bytes. -When -multiple names are configured, the peer is considered verified when -any name matches. - -X509_VERIFY_PARAM_set1_ip_asc() sets the expected IP address to -I. The I argument must be a NUL-terminated ASCII string: -dotted decimal quad for IPv4 and colon-separated hexadecimal for -IPv6. The condensed "::" notation is supported for IPv6 addresses. - -X509_VERIFY_PARAM_add1_ip_asc() adds I as an additional -reference identifier that can match the peer's certificate on success. -The I argument must be a NUL-terminated ASCII string: dotted -decimal quad for IPv4 and colon-separated hexadecimal for IPv6. The -condensed "::" notation is supported for IPv6 addresses. Any previous -names set via X509_VERIFY_PARAM_set1_ip(), -X509_VERIFY_PARAM_add1_ip(), X509_VERIFY_PARAM_set1_ip_asc(), or -X509_VERIFY_PARAM_add1_ip_asc() are retained. No change is made on -failure. -It is a failure if I is NULL or the empty string. -When multiple addresses are configured, the peer is considered verified -when any one of the specified addresses matches a corresponding IP address SAN in the certificate. - -X509_VERIFY_PARAM_set1_host_input_validation(), -X509_VERIFY_PARAM_set1_rfc822_input_validation(), -X509_VERIFY_PARAM_set1_smtputf8_input_validation(), and -X509_VERIFY_PARAM_set1_ip_input_validation() set a verification -function to validate the input on setting the corresponding validation -parameter expected values. -These functions make it possible to override OpenSSL's built-in input validation of -the corresponding verification parameters. -If the provided function succeeds, the corresponding -input will be accepted for use in certificate verification. +identifiers. When wildcard matching is not disabled, or when a reference +identifier specifies a parent domain (starts with "."), rather than a +hostname, the peer name may be a wildcard name or a sub-domain of the +reference identifier respectively. The returned string is allocated by +the library and is no longer valid once the associated I argument +is freed. Applications must not free the return value. =head1 RETURN VALUES X509_VERIFY_PARAM_set_flags(), X509_VERIFY_PARAM_clear_flags(), X509_VERIFY_PARAM_set_inh_flags(), X509_VERIFY_PARAM_set_purpose(), X509_VERIFY_PARAM_set_trust(), -X509_VERIFY_PARAM_add0_policy() X509_VERIFY_PARAM_set1_policies(), -X509_VERIFY_PARAM_set1_host(), X509_VERIFY_PARAM_add1_host(), -X509_VERIFY_PARAM_set1_email(), -X509_VERIFY_PARAM_set1_ip(), X509_VERIFY_PARAM_add1_ip(), -X509_VERIFY_PARAM_set1_ip_asc(), -X509_VERIFY_PARAM_add1_ip_asc() return 1 for success and 0 for -failure. - -X509_VERIFY_PARAM_get0_host(), X509_VERIFY_PARAM_get0_email(), and -X509_VERIFY_PARAM_get1_ip_asc(), return the string pointers specified above -or NULL if the respective value has not been set or on error. +X509_VERIFY_PARAM_add0_policy(), and X509_VERIFY_PARAM_set1_policies() +return 1 for success and 0 for failure. -X509_VERIFY_PARAM_get_flags() returns the current verification flags. +X509_VERIFY_PARAM_get0_peername() returns a pointer to the name from the +peer certificate that matched a configured reference identifier, or NULL +if no match has been recorded. -X509_VERIFY_PARAM_get_hostflags() returns any current host flags. +X509_VERIFY_PARAM_get_flags() returns the current verification flags. X509_VERIFY_PARAM_get_inh_flags() returns the current inheritance flags. -X509_VERIFY_PARAM_set_time() and X509_VERIFY_PARAM_set_depth() do not return -values. +X509_VERIFY_PARAM_set_time(), X509_VERIFY_PARAM_set_depth(), and +X509_VERIFY_PARAM_set_auth_level() do not return values. + +X509_VERIFY_PARAM_get_time() returns the verification time previously +configured on I via X509_VERIFY_PARAM_set_time(). X509_VERIFY_PARAM_get_depth() returns the current verification depth. @@ -360,99 +184,151 @@ which may be B if unset. =head1 VERIFICATION FLAGS -The verification flags consists of zero or more of the following flags -ored together. +The verification flags consist of zero or more of the following values +ORed together. Unless noted otherwise, each flag is off by default. -B enables CRL checking for the certificate chain leaf -certificate. An error occurs if a suitable CRL cannot be found. +=head2 Revocation checking -B expands CRL checking to the entire certificate -chain if B has also been enabled, and is otherwise ignored. +B enables CRL checking for the certificate chain +leaf certificate. An error occurs if a suitable CRL cannot be found. -B enables Online Certificate Status Protocol (OCSP) -checking for the certificate chain leaf certificate. An error occurs if a suitable -OCSP response cannot be found. +B expands CRL checking to the entire +certificate chain if B has also been enabled, and +is otherwise ignored. -B expands OCSP checking to the entire certificate -chain if B has also been enabled, and is otherwise -ignored. +B enables Online Certificate Status Protocol +(OCSP) checking for the certificate chain leaf certificate. An error +occurs if a suitable OCSP response cannot be found. -B disables critical extension checking. By default -any unhandled critical extensions in certificates or (if checked) CRLs result -in a fatal error. If this flag is set unhandled critical extensions are -ignored. B setting this option for anything other than debugging -purposes can be a security risk. Finer control over which extensions are -supported can be performed in the verification callback. +B expands OCSP checking to the entire +certificate chain if B has also been +enabled, and is otherwise ignored. -The B flag disables workarounds for some broken -certificates and makes the verification strictly apply B rules. +If B is set, some additional features +such as indirect CRLs and CRLs signed by different keys are enabled. By +default these features are disabled. -B enables proxy certificate verification. +If B is set, delta CRLs (if present) are used to +determine certificate status. If not set, deltas are ignored. -B enables certificate policy checking, by default -no policy checking is performed. Additional information is sent to the -verification callback relating to policy checking. +=head2 Certificate policy checking -B, B and -B set the C, C and C flags respectively as defined in -RFC 5280. Policy checking is automatically enabled if any of these flags -are set. +B enables certificate policy checking. By +default no policy checking is performed. Additional information is sent +to the verification callback relating to policy checking. -If B is set and the policy checking is successful -a special status code is set to the verification callback. This permits it -to examine the valid policy tree and perform additional checks or simply -log it for debugging purposes. +B, B, and +B set the C, C, and C flags respectively as defined +in RFC 5280. Policy checking is automatically enabled if any of these +flags is set. -By default some additional features such as indirect CRLs and CRLs signed by -different keys are disabled. If B is set -they are enabled. +If B is set and policy checking is +successful, a special status code is delivered to the verification +callback. This permits the callback to examine the valid policy tree +and perform additional checks, or simply to log it for debugging +purposes. -If B is set delta CRLs (if present) are used to -determine certificate status. If not set deltas are ignored. +=head2 Chain construction + +When B is set, which is the default since +OpenSSL 1.1.0, construction of the certificate chain in +L searches the trust store for issuer certificates +before searching the provided untrusted certificates. Local issuer +certificates are often more likely to satisfy local security +requirements and lead to a locally trusted root. This is especially +important when some certificates in the trust store have explicit trust +settings (see "TRUST SETTINGS" in L). + +The B flag suppresses checking for +alternative chains. By default, when the initial untrusted-first chain +fails to reach a trust anchor, the build is retried with progressively +shorter untrusted prefixes in an attempt to find an alternative. + +The B flag causes non-self-signed +certificates in the trust store to be treated as trust anchors, in the +same way as self-signed root CA certificates. This makes it possible to +trust self-issued certificates as well as certificates issued by an +intermediate CA without having to trust their ancestor root CA. With +B set, chain construction stops as soon as +the first certificate contained in the trust store is added to the +chain, whether that certificate is a self-signed "root" certificate or +a not self-signed "intermediate" or self-issued certificate. Thus, when +an intermediate certificate is found in the trust store, the verified +chain passed to callbacks may be shorter than it otherwise would be +without the B flag. B requests checking the signature of -the last certificate in a chain if the certificate is supposedly self-signed. -This is prohibited and will result in an error if it is a non-conforming CA -certificate with key usage restrictions not including the I bit. -By default this check is disabled because it doesn't -add any additional security but in some cases applications might want to -check the signature anyway. A side effect of not checking the self-signature -of such a certificate is that disabled or unsupported message digests used for -the signature are not treated as fatal errors. +the last certificate in a chain if the certificate is supposedly +self-signed. This is prohibited and will result in an error if it is a +non-conforming CA certificate with key usage restrictions not including +the I bit. By default this check is disabled because it +does not add any additional security, but in some cases applications +might want to check the signature anyway. A side effect of not checking +the self-signature of such a certificate is that disabled or +unsupported message digests used for the signature are not treated as +fatal errors. + +=head2 Validity period (time) + +B indicates that the time stored on the +parameters should be used for validity period checks in place of the +current time. This flag is set automatically by +X509_VERIFY_PARAM_set_time(); applications do not normally manipulate +it directly. + +The B flag suppresses checking the validity +period of certificates and CRLs against the current time. If +X509_VERIFY_PARAM_set_time() has been used to specify a verification +time, the check is performed against the specified time and this flag +has no effect. + +=head2 Extension processing and strictness + +B disables critical extension checking. By +default, any unhandled critical extensions in certificates or (if +checked) CRLs result in a fatal error. If this flag is set, unhandled +critical extensions are ignored. B setting this option for +anything other than debugging purposes can be a security risk. Finer +control over which extensions are supported can be performed in the +verification callback. + +The B flag disables workarounds for some +broken certificates and makes verification strictly apply B +rules. -When B is set, which is the default since -OpenSSL 1.1.0, construction of the certificate chain -in L searches the trust store for issuer certificates -before searching the provided untrusted certificates. -Local issuer certificates are often more likely to satisfy local security -requirements and lead to a locally trusted root. -This is especially important when some certificates in the trust store have -explicit trust settings (see "TRUST SETTINGS" in L). - -The B flag suppresses checking for alternative chains. - -The B flag causes non-self-signed certificates in the -trust store to be treated as trust anchors, in the same way as self-signed -root CA certificates. -This makes it possible to trust self-issued certificates as well as certificates -issued by an intermediate CA without having to trust their ancestor root CA. -With B set, chain -construction stops as soon as the first certificate contained in the trust store -is added to the chain, whether that certificate is a self-signed "root" -certificate or a not self-signed "intermediate" or self-issued certificate. -Thus, when an intermediate certificate is found in the trust store, the -verified chain passed to callbacks may be shorter than it otherwise would -be without the B flag. - -The B flag suppresses checking the validity period -of certificates and CRLs against the current time. If X509_VERIFY_PARAM_set_time() -is used to specify a verification time, the check is not suppressed. +B enables proxy certificate verification. +By default, proxy certificates are not accepted. + +=head2 Suite B compliance + +These flags enable enforcement of the NSA Suite B cryptographic +profile, a now-legacy profile that restricts chain validation to a +specific subset of elliptic-curve algorithms. Suite B has been +superseded by NSA's Commercial National Security Algorithm (CNSA) Suite +for new deployments. + +B restricts the chain to the Suite B +128-bit level of security: certificates must use the NIST P-256 curve +with ECDSA and SHA-256. + +B restricts the chain to the Suite B 192-bit +level of security: certificates must use the NIST P-384 curve with +ECDSA and SHA-384. + +B is the bitwise OR of the two flags above +and permits either level of security in the chain, with the constraint +that once a P-384 certificate has appeared in the chain, P-256 +certificates may not subsequently be used. =head1 INHERITANCE FLAGS -These flags specify how parameters are "inherited" from one structure to -another. +These flags control how the values stored in one B are +copied into another when verification parameters are "inherited", for +example when an B object inherits its verification parameters from +the B that created it. In the descriptions below, "from" refers +to the source B from which values are copied, and "to" +refers to the destination B into which they are copied. If B is set then the current setting is zeroed after the next call. @@ -465,8 +341,8 @@ to the destination. Effectively the values in "to" become default values which will be used only if nothing new is set in "from". This is the default. -If B is set then all value are copied across whether -they are set or not. Flags is still Ored though. +If B is set then all values are copied across +whether they are set or not. Flags are still ORed though. If B is set then the flags value is copied instead of ORed. @@ -478,11 +354,12 @@ instead of functions which work in specific structures such as X509_STORE_CTX_set_flags() which are likely to be deprecated in a future release. -TLS clients are recommended to set up validation of server hostname(s) and/or -IP address (directly using the above functions -or more conveniently using L or L) -and to use L for Server Name Indication (SNI), -which may be crucial also for correct routing of the connection request. +TLS clients are recommended to set up validation of server hostname(s) +and/or IP address (directly using the functions described in +L, or more conveniently using +L or L) and to use +L for Server Name Indication (SNI), which +may be crucial also for correct routing of the connection request. =head1 BUGS @@ -490,10 +367,19 @@ Delta CRL checking is currently primitive. Only a single delta can be used and (partly due to limitations of B) constructed CRLs are not maintained. -If CRLs checking is enable CRLs are expected to be available in the +If CRL checking is enabled, CRLs are expected to be available in the corresponding B structure. No attempt is made to download CRLs from the CRL distribution points extension. +The B selectors used by X509_VERIFY_PARAM_set_trust() are +deceptively named: although each mirrors a PKIX extended key usage, the +selector does not check that B. It matches only auxiliary +trust information that is never carried in the certificate itself but +must be attached to the in-memory B object by the application; +absent that, the selector has no effect. Use +X509_VERIFY_PARAM_set_purpose() to constrain a certificate by its +extended key usage instead. + =head1 EXAMPLES Enable CRL checking when performing certificate verification during SSL @@ -510,6 +396,8 @@ connections associated with an B structure I: L, L, +L, +L, L, L, L, @@ -529,11 +417,6 @@ The B flag was added in OpenSSL 1.1.0. The flag B was deprecated in OpenSSL 1.1.0 and has no effect. -The X509_VERIFY_PARAM_get_hostflags() function was added in OpenSSL 1.1.0i. - -The X509_VERIFY_PARAM_get0_host(), X509_VERIFY_PARAM_get0_email(), -and X509_VERIFY_PARAM_get1_ip_asc() functions were added in OpenSSL 3.0. - The function X509_VERIFY_PARAM_add0_policy() was historically documented as enabling policy checking however the implementation has never done this. The documentation was changed to align with the implementation. diff --git a/doc/man3/X509_VERIFY_PARAM_set_hostflags.pod b/doc/man3/X509_VERIFY_PARAM_set_hostflags.pod new file mode 100644 index 0000000000000..6963adcb934f9 --- /dev/null +++ b/doc/man3/X509_VERIFY_PARAM_set_hostflags.pod @@ -0,0 +1,110 @@ +=pod + +=head1 NAME + +X509_VERIFY_PARAM_set_hostflags, X509_VERIFY_PARAM_get_hostflags - X509 hostname verification flags + +=head1 SYNOPSIS + + #include + + void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, + unsigned int flags); + unsigned int X509_VERIFY_PARAM_get_hostflags(const X509_VERIFY_PARAM *param); + +=head1 DESCRIPTION + +Host flags control how hostname matching is performed during certificate +verification: which wildcard forms are permitted in the certificate's subject +alternative name (SAN) entries, and whether the certificate's subject +distinguished name is consulted in addition to the SAN. + +X509_VERIFY_PARAM_set_hostflags() sets the host flags on I to +I, for use during subsequent calls to L. + +X509_VERIFY_PARAM_get_hostflags() returns any host flags previously set via a +call to X509_VERIFY_PARAM_set_hostflags(). + +The I default to 0. They may be set to a bitwise OR of the following: + +=over 4 + +=item B + +=item B + +=item B + +=item B + +=item B + +=item B + +=back + +By default the subject distinguished name is not consulted; matching is +performed only against the subject alternative name extension. + +The B flag causes the function to +also match against the subject DN (the B attribute for DNS +names, the B attribute for email addresses), whether or not +the certificate contains a subject alternative name of the corresponding +type. During certificate chain verification this flag additionally +causes DNS name constraints to be applied to the subject B +of the leaf certificate, since the B may then be used as a +DNS identity; see L. + +The B flag suppresses matching against +the subject DN. As that is already the default, this flag has an effect +only in combination with B, over +which it takes precedence. + +If set, B disables wildcard +expansion. + +If set, B suppresses support +for "*" as wildcard pattern in labels that have a prefix or suffix, +such as: "www*" or "*www". + +If set, B allows a "*" that +constitutes the complete label of a DNS name (e.g. "*.example.com") +to match more than one label in the configured reference identifier. + +If set, B restricts reference +identifiers which start with ".", that would otherwise match any +sub-domain in the peer certificate, to only match direct child +sub-domains. Thus, for instance, with this flag set a reference +identifier of ".example.com" would match a peer certificate with a DNS +name of "www.example.com", but would not match a peer certificate with +a DNS name of "www.sub.example.com". + +=head1 RETURN VALUES + +X509_VERIFY_PARAM_get_hostflags() returns the flag values. + +=head1 SEE ALSO + +L, +L, +L, +L, +L, +L + +=head1 HISTORY + +X509_VERIFY_PARAM_set_hostflags() was added in OpenSSL 1.0.2. + +X509_VERIFY_PARAM_get_hostflags() was added in OpenSSL 1.1.0i. + +=head1 COPYRIGHT + +Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/X509_check_host.pod b/doc/man3/X509_check_host.pod index 6b095f9582707..e43dddbbe58fe 100644 --- a/doc/man3/X509_check_host.pod +++ b/doc/man3/X509_check_host.pod @@ -24,13 +24,14 @@ The validity of the certificate and its trust level has to be checked by other means. X509_check_host() checks if the certificate Subject Alternative -Name (SAN) or Subject CommonName (CN) matches the specified hostname, -which must be encoded in the preferred name syntax described -in section 3.5 of RFC 1034. By default, wildcards are supported +Name (SAN) matches the specified hostname, and, when +B is set, the Subject CommonName +(CN) as well. The hostname must be encoded in the preferred name syntax +described in section 3.5 of RFC 1034. By default, wildcards are supported and they match only in the left-most label; but they may match part of that label with an explicit prefix or suffix. For example, by default, the host B "www.example.com" would match a -certificate with a SAN or CN value of "*.example.com", "w*.example.com" +certificate with a SAN value of "*.example.com", "w*.example.com" or "*w.example.com". Per section 6.4.2 of RFC 6125, B values representing international @@ -87,20 +88,19 @@ flags: =back -The B flag causes the function -to consider the subject DN even if the certificate contains at least -one subject alternative name of the right type (DNS name or email -address as appropriate); the default is to ignore the subject DN -when at least one corresponding subject alternative names is present. - -The B flag causes the function to never -consider the subject DN even if the certificate contains no subject alternative -names of the right type (DNS name or email address as appropriate); the default -is to use the subject DN when no corresponding subject alternative names are -present. -If both B and -B are specified, the latter takes -precedence and the subject DN is not checked for matching names. +By default the subject distinguished name is not consulted; matching is +performed only against the subject alternative name extension. + +The B flag causes the function to +also match against the subject DN (the B attribute for DNS +names, the B attribute for email addresses), whether or not +the certificate contains a subject alternative name of the corresponding +type. + +The B flag suppresses matching against +the subject DN. As that is already the default, this flag has an effect +only in combination with B, over +which it takes precedence. If set, B disables wildcard expansion; this only applies to B. diff --git a/doc/man3/X509_cmp.pod b/doc/man3/X509_cmp.pod index f22333d19e231..b4a8872fcee25 100644 --- a/doc/man3/X509_cmp.pod +++ b/doc/man3/X509_cmp.pod @@ -27,6 +27,8 @@ certificates, X509 CRL objects and various values in an X509 certificate. The X509_cmp() function compares two B objects indicated by parameters I and I. The comparison is based on the B result of the hash values of two B objects and the canonical (DER) encoding values. +A certificate that has been modified since it was signed or decoded, and +not signed again, compares equal only to itself. The X509_NAME_cmp() function compares two B objects indicated by parameters I and I, any of which may be NULL. @@ -48,7 +50,8 @@ objects, respectively. The X509_CRL_match() function compares two B objects. Unlike the X509_CRL_cmp() function, this function compares the whole CRL content instead -of just the issuer name. +of just the issuer name. A CRL that has been modified since it was signed or +decoded, and not signed again, compares equal only to itself. =head1 RETURN VALUES @@ -56,15 +59,20 @@ The B comparison functions return B<-1>, B<0>, or B<1> if object I is found to be less than, to match, or be greater than object I, respectively. X509_NAME_cmp(), X509_issuer_and_serial_cmp(), X509_issuer_name_cmp(), -X509_subject_name_cmp(), X509_CRL_cmp(), and X509_CRL_match() +X509_subject_name_cmp(), and X509_CRL_cmp() may return B<-2> to indicate an error. +X509_CRL_match() no longer returns B<-2>, but did so in earlier versions +to indicate an error, and callers should still be prepared to receive it. =head1 NOTES These functions in fact utilize the underlying B of the C library to do the comparison job. Data to be compared varies from DER encoding data, hash -value or B. The sign of the comparison can be used to order the -objects but it does not have a special meaning in some cases. +value or B. The sign of the result of X509_cmp() and +X509_CRL_match() orders objects consistently only while none of them has been +modified since it was signed or decoded, and the internal hash of each could +be computed. A modified object compares unequal to every other object, but +two modified objects are not ordered with respect to each other. X509_NAME_cmp() and wrappers utilize the value B<-2> to indicate errors in some circumstances, which could cause confusion for the applications. diff --git a/doc/man3/X509_dup.pod b/doc/man3/X509_dup.pod index d0b649738bc0e..59fe73a082788 100644 --- a/doc/man3/X509_dup.pod +++ b/doc/man3/X509_dup.pod @@ -92,6 +92,9 @@ IPAddressOrRange_free, IPAddressOrRange_new, IPAddressRange_free, IPAddressRange_new, +IPAddrBlocks_free, +IPAddrBlocks_it, +IPAddrBlocks_new, ISSUER_SIGN_TOOL_free, ISSUER_SIGN_TOOL_it, ISSUER_SIGN_TOOL_new, @@ -604,6 +607,9 @@ CMS_EnvelopedData_dup(), OSSL_CRMF_ENCRYPTEDKEY_free(), OSSL_CRMF_ENCRYPTEDKEY_it() and OSSL_CRMF_ENCRYPTEDKEY_new() were added in OpenSSL 3.5. +IPAddrBlocks_free(), IPAddrBlocks_it() and IPAddrBlocks_new() +were added in OpenSSL 4.1. + =head1 COPYRIGHT Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man3/X509_get_default_cert_file.pod b/doc/man3/X509_get_default_cert_file.pod index a604cf5571774..982c8954d89a2 100644 --- a/doc/man3/X509_get_default_cert_file.pod +++ b/doc/man3/X509_get_default_cert_file.pod @@ -76,7 +76,7 @@ L =head1 COPYRIGHT -Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/X509_get_extension_flags.pod b/doc/man3/X509_get_extension_flags.pod index bc2ec51eccb6f..21bf952e75cc2 100644 --- a/doc/man3/X509_get_extension_flags.pod +++ b/doc/man3/X509_get_extension_flags.pod @@ -86,8 +86,9 @@ ASN1 object itself. =item B -Failed to compute the internal SHA1 hash value of the certificate or CRL. -This may be due to malloc failure or because no SHA1 implementation was found. +Failed to compute the internal fingerprint of the certificate or CRL, +because it could not be DER encoded (for instance a certificate still under +construction) or on memory allocation failure. =item B diff --git a/doc/man3/d2i_X509.pod b/doc/man3/d2i_X509.pod index 53f5aaacb7cf1..b37855da1657d 100644 --- a/doc/man3/d2i_X509.pod +++ b/doc/man3/d2i_X509.pod @@ -67,6 +67,7 @@ d2i_IPAddressChoice, d2i_IPAddressFamily, d2i_IPAddressOrRange, d2i_IPAddressRange, +d2i_IPAddrBlocks, d2i_ISSUER_SIGN_TOOL, d2i_ISSUING_DIST_POINT, d2i_NAMING_AUTHORITY, @@ -251,7 +252,6 @@ i2d_ASN1_UNIVERSALSTRING, i2d_ASN1_UTCTIME, i2d_ASN1_UTF8STRING, i2d_ASN1_VISIBLESTRING, -i2d_ASN1_bio_stream, i2d_ASRange, i2d_AUTHORITY_INFO_ACCESS, i2d_AUTHORITY_KEYID, @@ -282,6 +282,7 @@ i2d_IPAddressChoice, i2d_IPAddressFamily, i2d_IPAddressOrRange, i2d_IPAddressRange, +i2d_IPAddrBlocks, i2d_ISSUER_SIGN_TOOL, i2d_ISSUING_DIST_POINT, i2d_NAMING_AUTHORITY, @@ -596,8 +597,7 @@ freed in the event of error and I<*a> is set to NULL. B>() returns the number of bytes successfully encoded or a negative value if an error occurs. -B_bio>() and B_fp>(), -as well as i2d_ASN1_bio_stream(), +B_bio>() and B_fp>() return 1 for success and 0 if an error occurs. On error, these functions may record the error in the OpenSSL error queue. @@ -767,9 +767,11 @@ i2d_OSSL_TIME_SPEC_TIME(), i2d_OSSL_TIME_SPEC_WEEKS(), i2d_OSSL_TIME_SPEC_X_DAY_OF() were added in OpenSSL 3.5. +d2i_IPAddrBlocks() and i2d_IPAddrBlocks() were added in OpenSSL 4.1. + =head1 COPYRIGHT -Copyright 1998-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 1998-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man3/i2d_ASN1_bio_stream.pod b/doc/man3/i2d_ASN1_bio_stream.pod new file mode 100644 index 0000000000000..f652166b98f98 --- /dev/null +++ b/doc/man3/i2d_ASN1_bio_stream.pod @@ -0,0 +1,76 @@ +=pod + +=head1 NAME + +i2d_ASN1_bio_stream, i2d_CMS_bio_stream, i2d_PKCS7_bio_stream +- output ASN.1 structures in BER format + +=head1 SYNOPSIS + + #include + + int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it); + + #include + + int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags); + + #include + + int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *data, int flags); + +=head1 DESCRIPTION + +i2d_ASN1_bio_stream() outputs an ASN1_VALUE structure in BER format. +The I parameter specifies the B that describes the structure +type. If the B flag is set in I, streaming mode is used +where content from BIO I is processed through an encoding BIO chain for +structures that support indefinite length encoding. If B is not +set, I is ignored and the structure is written directly to I. + +i2d_CMS_bio_stream() outputs a CMS_ContentInfo structure in BER format. +It is otherwise identical to the function SMIME_write_CMS(). + +i2d_PKCS7_bio_stream() outputs a PKCS7 structure in BER format. +It is otherwise identical to the function SMIME_write_PKCS7(). + +Both i2d_CMS_bio_stream() and i2d_PKCS7_bio_stream() are implemented using +i2d_ASN1_bio_stream() internally. + +=head1 NOTES + +These functions are effectively versions of the corresponding i2d functions +that support streaming. + +=head1 BUGS + +The prefix "i2d" is arguably wrong because these functions output BER format. + +=head1 RETURN VALUES + +These functions return 1 for success or 0 for failure. + +=head1 SEE ALSO + +L, +L, L, L, L, +L, L, L, L, +L, L, +L, L + +=head1 HISTORY + +i2d_ASN1_bio_stream(), i2d_CMS_bio_stream() and i2d_PKCS7_bio_stream() +were added in OpenSSL 1.0.0. + +=head1 COPYRIGHT + +Copyright 2008-2026 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/i2d_CMS_bio_stream.pod b/doc/man3/i2d_CMS_bio_stream.pod deleted file mode 100644 index 88289b115fc48..0000000000000 --- a/doc/man3/i2d_CMS_bio_stream.pod +++ /dev/null @@ -1,53 +0,0 @@ -=pod - -=head1 NAME - -i2d_CMS_bio_stream - output CMS_ContentInfo structure in BER format - -=head1 SYNOPSIS - - #include - - int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *data, int flags); - -=head1 DESCRIPTION - -i2d_CMS_bio_stream() outputs a CMS_ContentInfo structure in BER format. - -It is otherwise identical to the function SMIME_write_CMS(). - -=head1 NOTES - -This function is effectively a version of the i2d_CMS_bio() supporting -streaming. - -=head1 BUGS - -The prefix "i2d" is arguably wrong because the function outputs BER format. - -=head1 RETURN VALUES - -i2d_CMS_bio_stream() returns 1 for success or 0 for failure. - -=head1 SEE ALSO - -L, L, -L, L -L, -L, -L - -=head1 HISTORY - -The i2d_CMS_bio_stream() function was added in OpenSSL 1.0.0. - -=head1 COPYRIGHT - -Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. - -Licensed under the Apache License 2.0 (the "License"). You may not use -this file except in compliance with the License. You can obtain a copy -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/doc/man3/i2d_PKCS7_bio_stream.pod b/doc/man3/i2d_PKCS7_bio_stream.pod deleted file mode 100644 index ced178bd55801..0000000000000 --- a/doc/man3/i2d_PKCS7_bio_stream.pod +++ /dev/null @@ -1,53 +0,0 @@ -=pod - -=head1 NAME - -i2d_PKCS7_bio_stream - output PKCS7 structure in BER format - -=head1 SYNOPSIS - - #include - - int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *data, int flags); - -=head1 DESCRIPTION - -i2d_PKCS7_bio_stream() outputs a PKCS7 structure in BER format. - -It is otherwise identical to the function SMIME_write_PKCS7(). - -=head1 NOTES - -This function is effectively a version of the d2i_PKCS7_bio() supporting -streaming. - -=head1 BUGS - -The prefix "i2d" is arguably wrong because the function outputs BER format. - -=head1 RETURN VALUES - -i2d_PKCS7_bio_stream() returns 1 for success or 0 for failure. - -=head1 SEE ALSO - -L, L, -L, L -L, -L, -L - -=head1 HISTORY - -The i2d_PKCS7_bio_stream() function was added in OpenSSL 1.0.0. - -=head1 COPYRIGHT - -Copyright 2008-2016 The OpenSSL Project Authors. All Rights Reserved. - -Licensed under the Apache License 2.0 (the "License"). You may not use -this file except in compliance with the License. You can obtain a copy -in the file LICENSE in the source distribution or at -L. - -=cut diff --git a/doc/man5/config.pod b/doc/man5/config.pod index 2e455ea78cfce..3da360b7e78ae 100644 --- a/doc/man5/config.pod +++ b/doc/man5/config.pod @@ -416,6 +416,18 @@ to access the same randomness sources from outside the validated boundary. This sets the property query used when fetching the randomness source. +=item B + +This enables strict seeding. The randomness source is then instantiated +on first use, even for a provider entropy or nonce request arriving before +the DRBG setup, and an unusable randomness source is an error instead of +a silent fallback to the operating system entropy sources. Recognised +values are B, B, B, B<1> to enable and B, B, +B, B<0> to disable, in lower or uppercase. The default is B, +except for the B randomness source, which seeds strictly unless +this option disables it. Builds configured with B +always seed strictly. + =item B This sets the provider to use for the L calls instead of the built-in diff --git a/doc/man7/EVP_CIPHER-AES.pod b/doc/man7/EVP_CIPHER-AES.pod index 6da3f96a2da50..51ff912187749 100644 --- a/doc/man7/EVP_CIPHER-AES.pod +++ b/doc/man7/EVP_CIPHER-AES.pod @@ -65,9 +65,10 @@ L. =head1 NOTES -The AES-SIV and AES-WRAP mode implementations do not support streaming. That -means to obtain correct results there can be only one L -or L call after the initialization of the context. +The AES-SIV, AES-WRAP, and GCM-SIV mode implementations do not support +streaming. That means to obtain correct results there can be only one +L or L call on the payload after +the initialization of the context. When wrapping with AES-WRAP-PAD ciphers, the output buffer must be at least I rounded up to the cipher block size (8 bytes) plus the block size. @@ -90,7 +91,7 @@ The GCM-SIV mode ciphers were added in OpenSSL version 3.2. =head1 COPYRIGHT -Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/EVP_CIPHER-ASCON-AEAD128.pod b/doc/man7/EVP_CIPHER-ASCON-AEAD128.pod new file mode 100644 index 0000000000000..da7c16d05442c --- /dev/null +++ b/doc/man7/EVP_CIPHER-ASCON-AEAD128.pod @@ -0,0 +1,82 @@ +=pod + +=head1 NAME + +EVP_CIPHER-ASCON-AEAD128 - The Ascon-AEAD128 EVP_CIPHER implementations + +=head1 DESCRIPTION + +Support for Ascon-AEAD128 (NIST SP 800-232) symmetric authenticated encryption +using the B API + +=head2 Algorithm Names + +The following algorithms are available in the default provider: + +=over 4 + +=item "ASCON-AEAD128" + +=item "ascon-aead128" + +=back + +=head2 Parameters + +This implementation supports the parameters described in L. + +=head1 NOTES + +Ascon-AEAD128 is the NIST-standardized authenticated encryption algorithm +specified in NIST SP 800-232. It is based on the Ascon128a variant of the Ascon +family of algorithms, suitable for lightweight and constrained environments. + +The algorithm supports associated data (AAD) that is authenticated but not +encrypted. AAD can be provided before encryption/decryption operations begin. + +Ascon-AEAD128 uses a 128-bit key, 128-bit nonce, and produces a 128-bit +authentication tag. The implementation processes data in 128-bit (16-byte) blocks +using the Ascon-p[8] permutation for data processing and Ascon-p[12] for +initialization and finalization. + +The nonce (IV) must be unique for each encryption under a given key. Reusing a +nonce with the same key can compromise confidentiality and/or integrity. +Ascon-AEAD128 is not misuse-resistant. + +When decrypting, applications must verify that the final step succeeds (for +example L returns success). If finalisation fails, +authentication must be treated as failed and any produced plaintext must not be +trusted or used. Streaming decryption output is not authenticated until the +tag is verified. + +=head1 CONFORMING TO + +=over 4 + +=item NIST SP 800-232 + +=back + +=head1 SEE ALSO + +L, L + +=head1 HISTORY + +Ascon-AEAD128 was added in OpenSSL 4.1 + +This implementation conforms to the NIST SP 800-232 specification for +Ascon-AEAD128, which defines the authenticated encryption scheme using the +Ascon128a algorithm variant. The NIST draft specification used the Ascon128 algorithm variant. + +=head1 COPYRIGHT + +Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut + diff --git a/doc/man7/EVP_CIPHER-SM4.pod b/doc/man7/EVP_CIPHER-SM4.pod index a446fafb6d4b1..b68ffc9b6aae9 100644 --- a/doc/man7/EVP_CIPHER-SM4.pod +++ b/doc/man7/EVP_CIPHER-SM4.pod @@ -39,6 +39,13 @@ L. =head1 NOTES +SM4 implementations in OpenSSL may use secret-dependent table lookups and +are not guaranteed to be constant-time. In particular, the portable C +implementation uses S-box and T-table lookups and may be vulnerable to +cache-timing side-channel attacks. Which code path is used depends on CPU +capabilities; see L, L and +L. + The SM4-XTS implementation allows streaming to be performed, but each L or L call requires each input to be a multiple of the blocksize. Only the final EVP_EncryptUpdate() or @@ -48,11 +55,12 @@ stealing (CTS) is used to fill the block. =head1 SEE ALSO -L, L +L, L, L, +L, L =head1 COPYRIGHT -Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/EVP_KDF-SS.pod b/doc/man7/EVP_KDF-SS.pod index acd2df00b2100..d2aeb24f7d1cb 100644 --- a/doc/man7/EVP_KDF-SS.pod +++ b/doc/man7/EVP_KDF-SS.pod @@ -55,9 +55,13 @@ This parameter is ignored for KMAC. These parameters work as described in L. -=item "key" (B) +=item "key" (B) -This parameter set the shared secret that is used for key derivation. +This parameter sets the shared secret that is used for key derivation. + +=item "secret" (B) + +This parameter sets the shared secret that is used for key derivation. =item "info" (B) @@ -140,7 +144,7 @@ fixedinfo value "label" and salt "salt": SN_hmac, strlen(SN_hmac)); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, SN_sha256, strlen(SN_sha256)); - *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, "secret", (size_t)6); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, "label", (size_t)5); @@ -167,7 +171,7 @@ fixedinfo value "label", salt of "salt" and KMAC outlen of 20: *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_MAC, SN_kmac128, strlen(SN_kmac128)); - *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SECRET, + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, "secret", (size_t)6); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, "label", (size_t)5); @@ -201,7 +205,7 @@ This functionality was added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. Copyright +Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/doc/man7/EVP_MAC-Poly1305.pod b/doc/man7/EVP_MAC-Poly1305.pod index a942226cd8aaf..6fc1cb663ced6 100644 --- a/doc/man7/EVP_MAC-Poly1305.pod +++ b/doc/man7/EVP_MAC-Poly1305.pod @@ -46,7 +46,7 @@ Gets the MAC size. =back -The "size" parameter can also be retrieved with with EVP_MAC_CTX_get_mac_size(). +The "size" parameter can also be retrieved with EVP_MAC_CTX_get_mac_size(). The length of the "size" parameter should not exceed that of an B. =head1 NOTES @@ -63,7 +63,7 @@ L, L =head1 COPYRIGHT -Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/EVP_PKEY-ML-DSA.pod b/doc/man7/EVP_PKEY-ML-DSA.pod index 173c3ddf2fe6c..6f6fd5cb1f6a2 100644 --- a/doc/man7/EVP_PKEY-ML-DSA.pod +++ b/doc/man7/EVP_PKEY-ML-DSA.pod @@ -322,7 +322,7 @@ The C B parameter was added in OpenSSL 4.0. =head1 COPYRIGHT -Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/EVP_PKEY-ML-KEM.pod b/doc/man7/EVP_PKEY-ML-KEM.pod index 31f2f2f0a3473..e67b52f1c8c87 100644 --- a/doc/man7/EVP_PKEY-ML-KEM.pod +++ b/doc/man7/EVP_PKEY-ML-KEM.pod @@ -342,7 +342,7 @@ The C B parameter was added in OpenSSL 4.0. =head1 COPYRIGHT -Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/EVP_PKEY-MLX-KEM.pod b/doc/man7/EVP_PKEY-MLX-KEM.pod index 12134056b04a6..0106b0b26df27 100644 --- a/doc/man7/EVP_PKEY-MLX-KEM.pod +++ b/doc/man7/EVP_PKEY-MLX-KEM.pod @@ -21,12 +21,19 @@ default and FIPS providers. =over 4 +=item B + +The shared secret is a concatenation of a 32-byte L shared +secret and a 32 byte L shared secret. +X25519 is not an approved FIPS algorithm, but this combination is still allowed +by FIPS 140-3, since ML-KEM is FIPS approved. + =item B -The shared secret is the concatenation of a 32 byte L shared -secret followed by a 32 byte L shared secret. X25519 is not an -approved FIPS algorithm, but this combination is still allowed by FIPS 140-3 -since ML-KEM is FIPS approved. +The shared secret is a concatenation of a 32-byte L shared +secret and a 32 byte L shared secret. +X25519 is not an approved FIPS algorithm, but this combination is still allowed +by FIPS 140-3, since ML-KEM is FIPS approved. =item B @@ -34,6 +41,12 @@ Similar to B with a higher security strength, the shared secret is the concatenation of a 32 byte L shared secret followed by a 56 byte L shared secret. +=item B + +The shared secret is the concatenation of a 32 byte L shared +secret followed by a 32 byte L shared secret. +Both algorithms used are FIPS approved. + =item B The shared secret is the concatenation of a 32 byte L shared @@ -110,25 +123,33 @@ The format of the public keys for the different algorithms is: =over 4 +=item B + +A 65-byte EC public key followed by an 800-byte ML-KEM-512 public key. + =item B -A 65 byte EC public key followed by a 1184 byte ML-KEM-768 public key. +A 65-byte EC public key followed by an 1184-byte ML-KEM-768 public key. =item B -A 97 byte EC public key followed by a 1568 byte ML-KEM-1024 public key. +A 97 byte EC public key followed by a 1568-byte ML-KEM-1024 public key. + +=item B + +An 800-byte ML-KEM-512 public key followed by a 32-byte X25519 public key. =item B -A 1184 byte ML-KEM-768 public key followed by a 32 byte X25519 public key. +A 1184-byte ML-KEM-768 public key followed by a 32-byte X25519 public key. =item B -A 1568 byte ML-KEM-1024 public key followed by a 56 byte X448 public key. +A 1568-byte ML-KEM-1024 public key followed by a 56-byte X448 public key. =item B -A 65 byte SM2 public key followed by a 1184 byte ML-KEM-768 public key. +A 65-byte SM2 public key followed by an 1184-byte ML-KEM-768 public key. =back @@ -138,7 +159,7 @@ The public key value. This parameter is only used when importing or exporting the public key value with the EVP_PKEY_fromdata() and EVP_PKEY_todata() functions. -The public key format format is the same as "encoded-pub-key". +The public key format is the same as "encoded-pub-key". =item "priv" (B) @@ -152,6 +173,10 @@ The format of the private keys for the different algorithms is: =over 4 +=item B + +32 byte EC private key followed by a 1632 byte ML-KEM-512 private key. + =item B 32 byte EC private key followed by a 2400 byte ML-KEM-768 private key. @@ -160,6 +185,10 @@ The format of the private keys for the different algorithms is: 48 byte EC private key followed by a 3168 byte ML-KEM-1024 private key. +=item B + +1632 byte ML-KEM-512 private key followed by a 32 byte X25519 private key. + =item B 2400 byte ML-KEM-768 private key followed by a 32 byte X25519 private key. @@ -209,6 +238,9 @@ This functionality was added in OpenSSL 3.5. Support for B was added in OpenSSL 4.0. +Support for B and B was added in OpenSSL +4.2. + =head1 COPYRIGHT Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man7/EVP_SIGNATURE-ECDSA.pod b/doc/man7/EVP_SIGNATURE-ECDSA.pod index aa1d1a8f0de93..cd9536ef2900f 100644 --- a/doc/man7/EVP_SIGNATURE-ECDSA.pod +++ b/doc/man7/EVP_SIGNATURE-ECDSA.pod @@ -89,7 +89,7 @@ EVP_PKEY_CTX_get_params(). =item "fips-indicator" (B) -=item "verify-message" (B +=item "verify-message" (B) The parameters are described in L. diff --git a/doc/man7/EVP_SIGNATURE-RSA.pod b/doc/man7/EVP_SIGNATURE-RSA.pod index 7ec9eda5c1a5c..6de51825b5d34 100644 --- a/doc/man7/EVP_SIGNATURE-RSA.pod +++ b/doc/man7/EVP_SIGNATURE-RSA.pod @@ -167,7 +167,7 @@ EVP_PKEY_CTX_get_params(). =item "fips-indicator" (B) -=item "verify-message" (B +=item "verify-message" (B) These common parameter are described in L. diff --git a/doc/man7/OSSL_PROVIDER-FIPS.pod b/doc/man7/OSSL_PROVIDER-FIPS.pod index c45788ddf9acf..c5422e2fccd5f 100644 --- a/doc/man7/OSSL_PROVIDER-FIPS.pod +++ b/doc/man7/OSSL_PROVIDER-FIPS.pod @@ -159,10 +159,14 @@ It is used internally as a sub algorithm of CSHAKE. =item ML-KEM-1024, see L +=item MLKEM512X25519, see L + =item X25519MLKEM768, see L =item X448MLKEM1024, see L +=item SecP256r1MLKEM512, see L + =item SecP256r1MLKEM768, see L =item SecP384r1MLKEM1024, see L @@ -275,10 +279,14 @@ included in SP 800-56Arev3 are not approved for key agreement". =item MK-KEM-1024, see L +=item MLKEM512X25519, see L + =item X25519MLKEM768, see L =item X448MLKEM1024, see L +=item SecP256r1MLKEM512, see L + =item SecP256r1MLKEM768, see L =item SecP384r1MLKEM1024, see L @@ -643,8 +651,16 @@ L =head1 HISTORY +The ML-DSA-44, ML-DSA-65, ML-DSA-87 signature algorithms, the ML-KEM-512, +ML-KEM-768, ML-KEM-768 key exchange algorithms, and the hybrid X25519MLKEM768, +SecP256r1MLKEM768, SecP384r1MLKEM1024 key exchange algorithms were added in +OpenSSL 3.5. + The HKDF-SHA256, HKDF-SHA384 and HKDF-SHA512 algorithms were added in OpenSSL 3.6. +The hybrid key exchange MLKEM512X25519 and SecP256r1MLKEM512 algorithms were +added in OpenSSL 4.2. + The CSHAKE-128 and CSHAKE-256 algorithms were added in OpenSSL 4.0. All other functionality was added in OpenSSL 3.0. diff --git a/doc/man7/OSSL_PROVIDER-default.pod b/doc/man7/OSSL_PROVIDER-default.pod index e61d3d8137057..96b76a8cd025c 100644 --- a/doc/man7/OSSL_PROVIDER-default.pod +++ b/doc/man7/OSSL_PROVIDER-default.pod @@ -189,10 +189,14 @@ The OpenSSL default provider supports these operations and algorithms: =item ML-KEM-1024, see L +=item MLKEM512X25519, see L + =item X25519MLKEM768, see L =item X448MLKEM1024, see L +=item SecP256r1MLKEM512, see L + =item SecP256r1MLKEM768, see L =item SecP384r1MLKEM1024, see L @@ -327,16 +331,20 @@ The OpenSSL default provider supports these operations and algorithms: =item ML-DSA-87, see L -=item MK-KEM-512, see L +=item ML-KEM-512, see L + +=item ML-KEM-768, see L -=item MK-KEM-768, see L +=item ML-KEM-1024, see L -=item MK-KEM-1024, see L +=item MLKEM512X25519, see L =item X25519MLKEM768, see L =item X448MLKEM1024, see L +=item SecP256r1MLKEM512, see L + =item SecP256r1MLKEM768, see L =item SecP384r1MLKEM1024, see L @@ -584,6 +592,9 @@ Support for B was added in OpenSSL 4.0. Support for CSHAKE-128 and CSHAKE-256 was added in OpenSSL 4.0. +Support for B and B was added in OpenSSL +4.2. + =head1 COPYRIGHT Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. diff --git a/doc/man7/fips_module.pod b/doc/man7/fips_module.pod index 824bbedcde0ed..cecd7a449b2b6 100644 --- a/doc/man7/fips_module.pod +++ b/doc/man7/fips_module.pod @@ -596,13 +596,16 @@ L /for further information. Some released versions of OpenSSL do not include a validated FIPS provider. To determine which versions have undergone the validation process, please refer to the -L. If you +L. If you require FIPS-approved functionality, it is essential to build your FIPS provider using one of the validated versions listed there. Normally, it is possible to utilize a FIPS provider constructed from one of the validated versions alongside F and F compiled from any -release within the same major release series. This flexibility enables -you to address bug fixes and CVEs that fall outside the FIPS boundary. +supported release from OpenSSL 3.0 onwards; provider compatibility is +maintained backward and forward across these releases, including future +major release series, for as long as the module remains supported. This +flexibility enables you to address bug fixes and CVEs that fall outside +the FIPS boundary. As the FIPS provider still supports non-FIPS validated algorithms, The property query C is mandatory for applications that @@ -621,7 +624,7 @@ FIPS indicators were added in OpenSSL 3.4. =head1 COPYRIGHT -Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/openssl-core_dispatch.h.pod b/doc/man7/openssl-core_dispatch.h.pod index 7f99fe2a811bd..84668b8047610 100644 --- a/doc/man7/openssl-core_dispatch.h.pod +++ b/doc/man7/openssl-core_dispatch.h.pod @@ -46,7 +46,7 @@ The types and macros described here were added in OpenSSL 3.0. =head1 COPYRIGHT -Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/openssl-env.pod b/doc/man7/openssl-env.pod index 27debe8ae2477..82e43e2a7ec17 100644 --- a/doc/man7/openssl-env.pod +++ b/doc/man7/openssl-env.pod @@ -91,6 +91,19 @@ Equivalently, the generic B<-provider-path> command-line option may be used. This variable is considered a security-sensitive environment variable. +=item B + +This environment variable is used to flag the fact that unit tests are being run +(i.e. C). +It is used to detect when OpenSSL should behave in a special manner +during unit tests (i.e. when unit tests are being run on fuzzing builds). +It should generally not be set by users. + +This variable is available only when OpenSSL is built +with C<-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION>. + +This variable is not considered security-sensitive. + =item B Initializes the secure memory at the beginning of the application which makes @@ -130,13 +143,6 @@ This output usually makes sense only if you know OpenSSL internals well. The value of this environment variable is a comma-separated list of names, with the following available: -=item B - -This environment variable is used to flag the fact that unit tests are being run -(i.e. `make test`). It is used to detect when the OpenSSL should behave in a special -manner during unit tests (i.e. when unit tests are being run on fuzzing builds). It should -generally not be set by users. - =over 4 =item B @@ -241,8 +247,8 @@ OpenSSL supports a number of different algorithm implementations for various machines and, by default, it determines which to use based on the processor capabilities and run time feature enquiry. These environment variables can be used to exert more control over this selection process. -See L, L, L, -and L. +See L, L, L, +L and L. These variables are not considered security-sensitive. diff --git a/doc/man7/openssl-quic-concurrency.pod b/doc/man7/openssl-quic-concurrency.pod index e79dd2a3a2c67..7f2e54bcb35c9 100644 --- a/doc/man7/openssl-quic-concurrency.pod +++ b/doc/man7/openssl-quic-concurrency.pod @@ -150,6 +150,29 @@ default concurrency model if the application does not explicitly specify a concurrency model or disable it. This is known as Legacy Blocking Compatibility Mode, and its usage is not recommended for multi-threaded applications. +=head1 THREAD CANCELLATION + +The restrictions in L also apply to +OpenSSL QUIC APIs, including calls used in nonblocking mode. + +CCM and TACM use domain-wide synchronisation during API processing. Event +processing may perform network I/O while it is held, which can be a POSIX +cancellation point. Interruption can leave later use or teardown of the domain +unsafe. + +TACM and CCM with B also maintain internal wait state +for blocking calls. If interruption prevents cleanup of this state, later calls +on the affected domain can block indefinitely. L can maintain such +state in multiple domains in one call. + +Because most blocking QUIC functions do not provide a per-call timeout, +applications requiring prompt cooperative cancellation should use nonblocking +mode and an application-driven event loop as described in +L, waiting for the application +cancellation event alongside QUIC events. Alternatively, an application can +call L with a finite timeout and check a cancellation condition +between calls. + =head1 RECOMMENDED USAGE New applications are advised to choose a concurrency model as follows: @@ -323,13 +346,15 @@ blocking mode can be changed explicitly using L. =head1 SEE ALSO -L, L, L, +L, L, L, +L, L, +L, L, L, L, L =head1 COPYRIGHT -Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/openssl-quic.pod b/doc/man7/openssl-quic.pod index 041bb5804dc56..7c0fcc8622e8a 100644 --- a/doc/man7/openssl-quic.pod +++ b/doc/man7/openssl-quic.pod @@ -439,7 +439,7 @@ are handled in a timely manner. See B for details. Ensure that your usage of L, L and L reflects the API changes described in B. In particular, you should use these APIs to determine the ability of a -QUIC stream to receive or provide application data, not to to determine if +QUIC stream to receive or provide application data, not to determine if network I/O is required. =item diff --git a/doc/man7/openssl-threads.pod b/doc/man7/openssl-threads.pod index bf2b2fb553e65..9f7e6e9da68c9 100644 --- a/doc/man7/openssl-threads.pod +++ b/doc/man7/openssl-threads.pod @@ -92,9 +92,35 @@ are using the same B object concurrently. Each thread handling TLS connections in parallel should create its own B object from the shared B. +=head1 THREAD CANCELLATION + +Thread safety does not imply cancellation safety. +Unless a specific function documents otherwise, OpenSSL does not guarantee +that an in-progress call can be abandoned safely by thread cancellation or +forced termination. An interruption can leave locks held, resources unreleased, +or shared state inconsistent, making later use or cleanup unsafe. + +Deferred cancellation can take effect at a cancellation point reached directly +or through a callback, BIO, provider, or other pluggable implementation. +Automatic thread-local cleanup and L, when they run, do +not unwind the interrupted call. + +Applications should act on cancellation only between OpenSSL calls. On POSIX +systems, applications using pthread cancellation should disable cancellation +with B() before entering OpenSSL and restore it only +after OpenSSL returns at a point safe for cancellation. Callbacks invoked by +OpenSSL must not re-enable it. Disabling cancellation does not make a blocking +call return on a cancellation request; applications requiring prompt +cancellation should use nonblocking operation where available. + +The same restriction applies to other non-local exits which abandon an OpenSSL +call in progress, including direct thread exit, long jumps, and language +exceptions. + =head1 SEE ALSO -CRYPTO_THREAD_run_once(3), +L, L, +L, local system threads documentation. =head1 BUGS @@ -103,7 +129,7 @@ This page is admittedly very incomplete. =head1 COPYRIGHT -Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/ossl-guide-dtlsv13.pod b/doc/man7/ossl-guide-dtlsv13.pod new file mode 100644 index 0000000000000..fc054ff7569ca --- /dev/null +++ b/doc/man7/ossl-guide-dtlsv13.pod @@ -0,0 +1,303 @@ +=pod + +=head1 NAME + +ossl-guide-dtlsv13 - OpenSSL DTLSv1.3 + +=head1 INTRODUCTION + +This page provides an introduction to the DTLSv1.3 protocol. +It explains the concepts behind the protocol and how it differs +from previous versions of DTLS. + +=head1 DESCRIPTION + +DTLSv1.3 is a version of the Datagram Transport Layer Security (DTLS) +protocol. DTLSv1.3 is defined in RFC 9147. It is based on TLSv1.3 and provides +similar security guarantees to TLSv1.3 but is designed to work over datagram +transport protocols such as UDP. + +The Supported Versions extension in the ClientHello and ServerHello is updated to +include support for DTLSv1.3 by adding the value 0xFEFD to the list of supported +versions. + +The TLSv1.3 state machine has been updated to support the DTLSv1.3 protocol. +The main difference in the state machine between TLSv1.3 and DTLSv1.3 is the +addition of Acknowledgement messages that are used to acknowledge the receipt of +messages in the DTLSv1.3 protocol. This allows either the client or the server +to signal to the peer that they have received and processed a handshake message. +This prevents unnecessary retransmissions of messages. + +A major difference between DTLSv1.3 and DTLSv1.2 is the addition of the Unified +Header. This Unified Header is in plaintext, and it contains an encrypted sequence +number. The handshake header follows the Unified Header, and both the handshake +header and all of its contents are encrypted. + + struct { + ContentType type; + ProtocolVersion legacy_record_version; + uint16 epoch_val = 0; + uint48 sequence_number; + uint16 length; + opaque fragment[DTLSPlaintext.length]; + } DTLSPlaintext; + + struct { + opaque content[DTLSPlaintext.length]; + ContentType type; + uint8 zeros[length_of_padding]; + } DTLSInnerPlaintext; + + struct { + opaque unified_hdr[variable]; + opaque encrypted_record[length]; + } DTLSCiphertext; + +=head1 UNIFIED HEADER + +The first byte of a Unified Header indicates which fields are present in the Unified Header. + + 0 1 2 3 4 5 6 7 + +-+-+-+-+-+-+-+-+ + |0|0|1|C|S|L|E E| + +-+-+-+-+-+-+-+-+ + | Connection ID | Legend: + | (if any, | + / length as / C - Connection ID (CID) present + | negotiated) | S - Sequence number length + +-+-+-+-+-+-+-+-+ L - Length present + | 8 or 16 bit | E - Epoch + |Sequence Number| + +-+-+-+-+-+-+-+-+ + | 16 bit Length | + | (if present) | + +-+-+-+-+-+-+-+-+ + +When OpenSSL is generating a Unified Header it will always have Connection ID (C) set to +zero. The Sequence Number will always be set to 1, indicating a 2 byte Sequence Number. +Lastly the length bit will always be set indicating a length is present in the Unified +Header. + +=head2 Epoch + +The Epoch value is incremented every time the cryptographic parameters change. +ClientHello and ServerHello use an Epoch of 0. Only the client uses an Epoch of 1 +when it is sending Early Data. The rest of the handshake messages use an Epoch of 2. + +=head2 Encrypted Sequence Numbers + +The Sequence Number in the Unified Header is encrypted. For each Epoch, it always +starts at 0, but since it is encrypted, it will not appear as zero when viewing it +on the wire. The Sequence Number increments with every new DTLSv1.3 record. + +=head1 ACKNOWLEDGEMENT MESSAGE + +DTLSv1.3 adds explicit Acknowledgement messages to the protocol. There are also +implicit acknowledgements in DTLSv1.3. For instance, when the client receives +ServerHello, that ServerHello implicitly acknowledges the receipt of the ClientHello +message. Also, ClientFinished implicitly acknowledges the receipt of ServerFinished. +The new explicit Acknowledgement messages are used for the server to acknowledge the +receipt of the ClientFinished message. The client uses an explicit Acknowledgement +message to acknowledge the receipt of NewSessionTicket messages. Both the server and +the client use the explicit Acknowledgement to acknowledge the receipt of KeyUpdate +messages. + +When the server sends data immediately after the connection is established, there is +a potential race condition where the Application Data may be received by the client +before the Acknowledgement message for the ClientFinished message is received. OpenSSL +buffers the Application Data until the Acknowledgement message is received and processed. + +=head1 END OF EARLY DATA MESSAGE + +In DTLSv1.3, the End of Early Data message is not sent. Instead, when the client +starts sending messages in Epoch 2, this signals to the server that the client has +finished sending Early Data. + +=head1 HELLO RETRY REQUEST + +For DTLSv1.3 server applications, use L: HelloRetryRequest +cookie validation is enabled by default. This provides connection demultiplexing +for multiple clients on a single UDP socket. + +Note that L only supports DTLS 1.0/1.2 with HelloVerifyRequest and +cannot be used with DTLSv1.3. + +=head1 DTLS LISTENER API + +For DTLSv1.3 server applications that need to handle multiple clients on a single +UDP socket, the SSL Listener API provides connection demultiplexing and address +validation. Unlike L which only supports DTLS 1.0/1.2 with +HelloVerifyRequest, the listener API fully supports DTLSv1.3 with HelloRetryRequest +cookie validation. + +Create a DTLS listener using L with an SSL_CTX configured +for DTLS. Address validation is enabled by default. The following flags adjust +listener behavior: + +=over 4 + +=item B + +Requests address validation by HelloRetryRequest and HelloVerifyRequest. This +is the default. + +=item B + +Disables all address validation. The listener will not send HelloVerifyRequest +(for DTLS 1.0/1.2) or HelloRetryRequest with cookie (for DTLSv1.3). This is +faster but provides no protection against amplification attacks. Not recommended +for use in untrusted network environments. If both this flag and +B are specified, the listener fails safe +and performs address validation. + +=item B + +Specifies that the DTLS listener will operate in single-threaded mode. When this +flag is set, the listener and all connections accepted from it should only be +used from a single thread. This avoids the overhead of internal synchronization +mechanisms. + +=back + +By default (when B is not set), the listener +initializes internal synchronization mechanisms that allow connections accepted +from the listener to be safely used from multiple threads concurrently. This +includes a notifier mechanism that enables efficient polling across threads. + +After attaching a UDP socket BIO with L and L +and calling L, use L to accept incoming +connections. Each accepted connection has completed cookie validation (if required) +but still requires L or L to complete the TLS +handshake before application data can be exchanged. + +By default a DTLS listener created with L operates in +blocking mode. Because a listener demultiplexes a single UDP socket across many +connections, it cannot allow a read for one connection to block and thereby +stall the others. Its network BIO is therefore configured for nonblocking +operation, and blocking is instead provided by waiting for readiness of the +underlying socket. This applies to L on the listener +as well as to L and L on the connections it returns. + +Use L to enable or disable blocking mode, and +L to query it. The blocking mode of a listener is +normally configured once, before it is used. + +A connection SSL object returned by L inherits the +blocking mode of the listener it came from. Calling L +on such a connection overrides that inheritance for that connection only. To +perform a single nonblocking accept on an otherwise blocking listener, pass the +B flag to L. + +See L for full details. + +The following tunables are available via L / +L: B +(pending-connection cap, default 256), B +(pending connection timeout in milliseconds, default 30000; pending connections +that do not complete their handshake within this period are automatically cleaned +up), and B (maximum received datagram size +in bytes, default 2000). + +See L for complete API documentation. + +The complete source code for an example DTLS listener server (and a matching +client) is available in the B directory of the OpenSSL +source distribution in the file B. It is also available online at +L. + +=head1 APPLICATION DATA + +When either the DTLSv1.3 client or server is awaiting an Acknowledgement message, +Application Data will be buffered until the Acknowledgement message is received and processed. +Once either the DTLSv1.3 client or server processes the Acknowledgement message it will then +process the buffered Application Data. + +Another scenario when Application Data is buffered is when multiple handshake messages like +the NewSessionTicket are received with Application Data. The Application Data will be buffered +until all the handshake messages have been processed. + +=head1 SCTP + +Even though DTLSv1.3 is enabled, the client will only perform a DTLSv1.2 or DTLSv1.0 handshake. +If a DTLSv1.3 over SCTP compatible client connects to an OpenSSL server, the server will +downgrade to DTLSv1.2 or earlier. + +=head1 CONNECTION ID + +OpenSSL does not support Connection IDs in DTLSv1.3. If a client that supports Connection +IDs connects to an OpenSSL server, the server will ignore the Connection ID and will not +include a Connection ID in its responses. + +=head1 CIPHER SUITES + +RFC 9147 requires that TLS_AES_128_CCM_8_SHA256 must not be used with DTLS +without additional safeguards against forgery, due to its short +authentication tag. OpenSSL does not implement such safeguards, so this +ciphersuite is not available when negotiating DTLS, even though it remains +available for TLS. + +=head1 HOW TO UTILIZE DTLSV1.3 IN OPENSSL + +=head2 SSL_set_min_proto_version and SSL_set_max_proto_version + +Use L and L with the +DTLS1_3_VERSION macro to set the minimum and maximum protocol version to DTLSv1.3. + +=head2 SSL_CTX_set_min_proto_version and SSL_CTX_set_max_proto_version + +Use L and L with +the DTLS1_3_VERSION macro to set the minimum and maximum protocol version to DTLSv1.3. + +=head2 s_client + +Use the min_protocol and max_protocol parameters and set them to DTLSv1.3. +Use the -dtls option to specify that you want to use DTLS instead of TLS. + +=head2 s_server + +Use the min_protocol and max_protocol parameters and set them to DTLSv1.3. + +=head1 DEMOS + +OpenSSL is distributed with two DTLS demo applications that illustrate the +concepts described on this page. They can be found in the B directory +of the OpenSSL source distribution: + +=over 4 + +=item B + +A simple DTLSv1.3 echo client and server built on a single B object per +connection. The complete source code is available in the B +directory of the OpenSSL source distribution in the file B. It is also +available online at +L. + +=item B + +A DTLS echo server that uses the DTLS listener API (L, +L and L) to demultiplex and handle +multiple client connections on a single UDP socket, together with a matching +client. The complete source code is available in the B +directory of the OpenSSL source distribution in the file B. It is also +available online at +L. + +=back + +=head1 SEE ALSO + +L, L, +L, L, +L, L, L + +=head1 COPYRIGHT + +Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man7/ossl-guide-migration.pod b/doc/man7/ossl-guide-migration.pod index bf5c57d617ae9..6bd27323ee6d6 100644 --- a/doc/man7/ossl-guide-migration.pod +++ b/doc/man7/ossl-guide-migration.pod @@ -44,6 +44,50 @@ This function is deprecated in favour of EVP_KDF_CTX_get0_ctx(), to align with the naming of functions that provide similar functionality for other kinds of EVP context oobjects. +=head3 B is now a no-op + +Prior to OpenSSL 4.1, when B was set, TLS clients sent +a padding extension (RFC 7685) whenever the ClientHello would otherwise be +between 256 and 511 bytes long. The option was part of B, so any +application setting B sent this padding. It worked around a bug +in F5 middleboxes; the fix shipped long ago and the affected hardware is +long out of support, so nothing should still be running the problematic +version. The option now has no effect and has been removed from +B. + +Applications that require the padding extension can construct it themselves +by registering a handler for B with +L. Registering a handler for this extension type +was previously refused. + +=head3 B values have never been NUL byte terminated + +The bytes returned by L have never been guaranteed to +be NUL byte terminated, and the documentation has said so since 2002. Values +constructed as pointers into parsed DER never have been. Applications treating +them as C strings have always relied on behaviour that was never promised. + +Such code usually escaped consequences because ASN1_STRING_set() allocated one +byte more than the requested length and wrote a NUL byte into it. That byte was +never counted in the length reported by ASN1_STRING_length(). + +ASN1_STRING_set() is now deprecated. Its replacements, +L and L, allocate exactly +the requested number of bytes and append nothing. This includes +ASN1_STRING_set1_string(): it takes a NUL byte terminated C string, but does not +store the terminator. + +Applications must use the data only together with its length, obtained from +L, and never derive the length from the data. +Applications should be cautious of passing a NULL data pointer when an +B has a length of 0 to functions where this behaviour may be +undefined. + +Applications which wish to use the content of an B as a C string +should make a copy of the data, NUL byte terminate it, and when appropriate, +sanitize it for embedded NUL bytes. They should never have been using the +B data directly. + =head1 OPENSSL 4.0 =head2 Main Changes from OpenSSL 3.6 @@ -2428,8 +2472,11 @@ See L RSA_private_encrypt(), RSA_public_decrypt() -This is equivalent to doing sign and verify recover operations (with a padding -mode of none). See L. +These are equivalent to L and +L operations, respectively. For compatibility +with the legacy low-level operations, do not configure a signature digest and +use the same padding mode as the legacy call (B or +B). See L. =item * diff --git a/doc/man7/ossl-guide-quic-client-block.pod b/doc/man7/ossl-guide-quic-client-block.pod index 9d5bc62da53ac..5c349a8fe3ddc 100644 --- a/doc/man7/ossl-guide-quic-client-block.pod +++ b/doc/man7/ossl-guide-quic-client-block.pod @@ -394,7 +394,7 @@ L, L =head1 COPYRIGHT -Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/ossl-guide-quic-client-non-block.pod b/doc/man7/ossl-guide-quic-client-non-block.pod index c7f66079d7f2e..509d5fe0c228d 100644 --- a/doc/man7/ossl-guide-quic-client-non-block.pod +++ b/doc/man7/ossl-guide-quic-client-non-block.pod @@ -463,7 +463,7 @@ L, L =head1 COPYRIGHT -Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/ossl-guide-quic-multi-stream.pod b/doc/man7/ossl-guide-quic-multi-stream.pod index f2b8084bd5a1d..933c47051f9c6 100644 --- a/doc/man7/ossl-guide-quic-multi-stream.pod +++ b/doc/man7/ossl-guide-quic-multi-stream.pod @@ -392,7 +392,7 @@ L =head1 COPYRIGHT -Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/ossl-guide-quic-server-block.pod b/doc/man7/ossl-guide-quic-server-block.pod index ec78a0ada8573..a6c4c04d148be 100644 --- a/doc/man7/ossl-guide-quic-server-block.pod +++ b/doc/man7/ossl-guide-quic-server-block.pod @@ -271,7 +271,7 @@ L, L =head1 COPYRIGHT -Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/ossl-guide-quic-server-non-block.pod b/doc/man7/ossl-guide-quic-server-non-block.pod index 2a5cfaa603a89..c5087ce8242c4 100644 --- a/doc/man7/ossl-guide-quic-server-non-block.pod +++ b/doc/man7/ossl-guide-quic-server-non-block.pod @@ -362,7 +362,7 @@ L, L =head1 COPYRIGHT -Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/ossl-guide-tls-client-block.pod b/doc/man7/ossl-guide-tls-client-block.pod index e508eb23ecd68..2dd29e6dda2e2 100644 --- a/doc/man7/ossl-guide-tls-client-block.pod +++ b/doc/man7/ossl-guide-tls-client-block.pod @@ -247,7 +247,7 @@ Finally we associate the B object we created earlier with the B using the L function. Note that this passes ownership of the B object to the B object. Once ownership is passed the SSL object is responsible for its management and will free it automatically when the B is -freed. So, once L has been been called, you should not call +freed. So, once L has been called, you should not call L on the B. SSL_set_bio(ssl, bio, bio); @@ -578,7 +578,7 @@ L, L =head1 COPYRIGHT -Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/ossl-guide-tls-client-non-block.pod b/doc/man7/ossl-guide-tls-client-non-block.pod index a45086caf6e4a..9b927293ed162 100644 --- a/doc/man7/ossl-guide-tls-client-non-block.pod +++ b/doc/man7/ossl-guide-tls-client-non-block.pod @@ -373,7 +373,7 @@ L, L =head1 COPYRIGHT -Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/ossl-guide-tls-introduction.pod b/doc/man7/ossl-guide-tls-introduction.pod index 4b69a9e642b00..adda375923785 100644 --- a/doc/man7/ossl-guide-tls-introduction.pod +++ b/doc/man7/ossl-guide-tls-introduction.pod @@ -311,7 +311,7 @@ L, L =head1 COPYRIGHT -Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/ossl-guide-tls-server-block.pod b/doc/man7/ossl-guide-tls-server-block.pod index f445492282c4d..8176f52516032 100644 --- a/doc/man7/ossl-guide-tls-server-block.pod +++ b/doc/man7/ossl-guide-tls-server-block.pod @@ -319,7 +319,7 @@ L, L =head1 COPYRIGHT -Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/ossl_store.pod b/doc/man7/ossl_store.pod index 0441fe34e9ce0..a78aefb5dcc14 100644 --- a/doc/man7/ossl_store.pod +++ b/doc/man7/ossl_store.pod @@ -84,7 +84,7 @@ L, L =head1 COPYRIGHT -Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/property.pod b/doc/man7/property.pod index 7adf282ebfbed..4da7f2a25e5cc 100644 --- a/doc/man7/property.pod +++ b/doc/man7/property.pod @@ -105,6 +105,12 @@ The quotes are not included in the body of the string. =back +String values in property definitions and queries are matched case-sensitively. +An unquoted string value is converted to lowercase when it is parsed, while a +quoted string value retains its case. For example, C matches +C, and C is treated as C, but neither matches +C. + =head2 Lookups When an algorithm is looked up, a property query is used to determine diff --git a/doc/man7/provider-asym_cipher.pod b/doc/man7/provider-asym_cipher.pod index e28f57f742a20..3ff9e647ca631 100644 --- a/doc/man7/provider-asym_cipher.pod +++ b/doc/man7/provider-asym_cipher.pod @@ -291,7 +291,7 @@ were added in OpenSSL 3.4. =head1 COPYRIGHT -Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/provider-digest.pod b/doc/man7/provider-digest.pod index 6d90534f9e86b..09492c7a52d56 100644 --- a/doc/man7/provider-digest.pod +++ b/doc/man7/provider-digest.pod @@ -192,7 +192,7 @@ provider side digest context I to I. Any parameter settings are additional to any that were previously set. Passing NULL for I should return true. -OSSL_FUNC_digest_get_ctx_params() gets digest operation details details from +OSSL_FUNC_digest_get_ctx_params() gets digest operation details from the given provider side digest context I and stores them in I. Passing NULL for I should return true. diff --git a/doc/man7/provider-kdf.pod b/doc/man7/provider-kdf.pod index 432b67472f1ff..e371e24ea9454 100644 --- a/doc/man7/provider-kdf.pod +++ b/doc/man7/provider-kdf.pod @@ -341,7 +341,10 @@ It is defined as per RFC 7292 section B.3. OSSL_FUNC_kdf_newctx() and OSSL_FUNC_kdf_dupctx() should return the newly created provider side KDF context, or NULL on failure. -OSSL_FUNC_kdf_derive(), OSSL_FUNC_kdf_derive_skey(), OSSL_FUNC_kdf_get_params(), +OSSL_FUNC_kdf_derive_skey() should return the newly created opaque +provider-side key object, or NULL on failure. + +OSSL_FUNC_kdf_derive(), OSSL_FUNC_kdf_get_params(), OSSL_FUNC_kdf_get_ctx_params(), OSSL_FUNC_kdf_set_ctx_params() and OSSL_FUNC_kdf_set_skey() should return 1 for success or 0 on error. @@ -367,7 +370,7 @@ OSSL_FUNC_kdf_derive_skey() and OSSL_FUNC_kdf_set_skey() were added in OpenSSL 3 =head1 COPYRIGHT -Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/provider-kem.pod b/doc/man7/provider-kem.pod index 85b8f1a6b80aa..739264ec329f0 100644 --- a/doc/man7/provider-kem.pod +++ b/doc/man7/provider-kem.pod @@ -32,7 +32,8 @@ provider-kem - The kem library E-E provider functions unsigned char *secret, size_t *secretlen); /* Decapsulation */ - int OSSL_FUNC_kem_decapsulate_init(void *ctx, void *provkey); + int OSSL_FUNC_kem_decapsulate_init(void *ctx, void *provkey, + const OSSL_PARAM params[]); int OSSL_FUNC_kem_auth_decapsulate_init(void *ctx, void *provkey, void *provauthkey, const OSSL_PARAM params[]); @@ -129,13 +130,13 @@ context in the I parameter and return the duplicate copy. OSSL_FUNC_kem_encapsulate_init() initialises a context for an asymmetric encapsulation given a provider side asymmetric kem context in the I -parameter, a pointer to a provider key object in the I parameter and -the I of the algorithm. +parameter, a pointer to a provider key object in the I parameter. + The I, if not NULL, should be set on the context in a manner similar to using OSSL_FUNC_kem_set_ctx_params(). The key object should have been previously generated, loaded or imported into the provider using the key management (OSSL_OP_KEYMGMT) operation (see -provider-keymgmt(7)>. +L. OSSL_FUNC_kem_auth_encapsulate_init() is similar to OSSL_FUNC_kem_encapsulate_init(), but also passes an additional authentication @@ -159,11 +160,13 @@ written to I<*secretlen>. OSSL_FUNC_kem_decapsulate_init() initialises a context for an asymmetric decapsulation given a provider side asymmetric kem context in the I -parameter, a pointer to a provider key object in the I parameter, and -a I of the algorithm. +parameter, a pointer to a provider key object in the I parameter. + +The I, if not NULL, should be set on the context in a manner similar to +using OSSL_FUNC_kem_set_ctx_params(). The key object should have been previously generated, loaded or imported into the provider using the key management (OSSL_OP_KEYMGMT) operation (see -provider-keymgmt(7)>. +L. OSSL_FUNC_kem_auth_decapsulate_init() is similar to OSSL_FUNC_kem_decapsulate_init(), but also passes an additional authentication @@ -250,7 +253,7 @@ were added in OpenSSL 3.4. =head1 COPYRIGHT -Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/provider-keyexch.pod b/doc/man7/provider-keyexch.pod index d5d2d4769c36c..a0d8f508eb3bf 100644 --- a/doc/man7/provider-keyexch.pod +++ b/doc/man7/provider-keyexch.pod @@ -28,9 +28,10 @@ provider-keyexch - The keyexch library E-E provider functions int OSSL_FUNC_keyexch_set_peer(void *ctx, void *provkey); int OSSL_FUNC_keyexch_derive(void *ctx, unsigned char *secret, size_t *secretlen, size_t outlen); - int OSSL_FUNC_keyexch_derive_skey(void *ctx, const char *key_type, void *provctx, - OSSL_FUNC_skeymgmt_import_fn *import, - size_t keylen, const OSSL_PARAM params[]); + void *OSSL_FUNC_keyexch_derive_skey(void *ctx, const char *key_type, + void *provctx, + OSSL_FUNC_skeymgmt_import_fn *import, + size_t keylen, const OSSL_PARAM params[]); /* Key Exchange parameters */ int OSSL_FUNC_keyexch_set_ctx_params(void *ctx, const OSSL_PARAM params[]); @@ -115,10 +116,10 @@ OSSL_FUNC_keyexch_init() initialises a key exchange operation given a provider s exchange context in the I parameter, and a pointer to a provider key object in the I parameter. The I, if not NULL, should be set on the context in a manner similar to -using OSSL_FUNC_keyexch_set_params(). +using OSSL_FUNC_keyexch_set_ctx_params(). The key object should have been previously generated, loaded or imported into the provider using the key management -(OSSL_OP_KEYMGMT) operation (see provider-keymgmt(7)>. +(OSSL_OP_KEYMGMT) operation (see L. OSSL_FUNC_keyexch_set_peer() is called to supply the peer's public key (in the I parameter) to be used when deriving the shared secret. @@ -126,7 +127,7 @@ It is also passed a previously initialised key exchange context in the I parameter. The key object should have been previously generated, loaded or imported into the provider using the key management (OSSL_OP_KEYMGMT) operation (see -provider-keymgmt(7)>. +L. OSSL_FUNC_keyexch_derive() performs the actual key exchange itself by deriving a shared secret. @@ -143,7 +144,7 @@ uses an opaque object for storing the derived key. It accepts I parameter to give a hint to the provider what type of the key (e.g. generic or AES) would be generated and I function from the B object to be associated with the key. The B object comes from the same -provider as the KDF itself. +provider as the key exchange implementation. =head2 Key Exchange Parameters Functions @@ -253,10 +254,12 @@ to return 0. OSSL_FUNC_keyexch_newctx() and OSSL_FUNC_keyexch_dupctx() should return the newly created provider side key exchange context, or NULL on failure. -OSSL_FUNC_keyexch_init(), OSSL_FUNC_keyexch_set_peer(), OSSL_FUNC_keyexch_derive(), -OSSL_FUNC_keyexch_derive_skey(), -OSSL_FUNC_keyexch_set_params(), and OSSL_FUNC_keyexch_get_params() should return 1 for success -or 0 on error. +OSSL_FUNC_keyexch_derive_skey() should return the newly created opaque +provider-side key object, or NULL on failure. + +OSSL_FUNC_keyexch_init(), OSSL_FUNC_keyexch_set_peer(), +OSSL_FUNC_keyexch_derive(), OSSL_FUNC_keyexch_set_ctx_params(), and +OSSL_FUNC_keyexch_get_ctx_params() should return 1 for success or 0 on error. OSSL_FUNC_keyexch_settable_ctx_params() and OSSL_FUNC_keyexch_gettable_ctx_params() should always return a constant L array. @@ -276,7 +279,7 @@ The OSSL_FUNC_keyexch_derive_skey() function was added in OpenSSL 3.6. =head1 COPYRIGHT -Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/provider-signature.pod b/doc/man7/provider-signature.pod index 1e4e99c0b131f..e0c892a99eefd 100644 --- a/doc/man7/provider-signature.pod +++ b/doc/man7/provider-signature.pod @@ -592,7 +592,7 @@ A getter that returns 1 if the operation is FIPS approved, or 0 otherwise. This may be used after calling either the sign or verify final functions. It may return 0 if either the "digest-check", "key-check", or "sign-check" are set to 0. -=item "verify-message" (B +=item "verify-message" (B) A getter that returns 1 if a signature verification operation acted on a raw message, or 0 if it verified a predigested message. A value of 0 @@ -711,7 +711,7 @@ Deterministic digital signature generation for ECDSA was added to the FIPS provi =head1 COPYRIGHT -Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/provider-skeymgmt.pod b/doc/man7/provider-skeymgmt.pod index c788178cb1514..f6d894a78e6b4 100644 --- a/doc/man7/provider-skeymgmt.pod +++ b/doc/man7/provider-skeymgmt.pod @@ -27,6 +27,14 @@ provider-skeymgmt - The SKEYMGMT library E-E provider functions const OSSL_PARAM *OSSL_FUNC_skeymgmt_gen_settable_params(void *provctx); const OSSL_PARAM *OSSL_FUNC_skeymgmt_imp_settable_params(void *provctx); const char *OSSL_FUNC_skeymgmt_get_key_id(void *keydata); + int OSSL_FUNC_skeymgmt_get_local_keyid(void *keydata, + const unsigned char **id, + size_t *len); + int OSSL_FUNC_skeymgmt_get_algorithm_id(void *keydata, + const unsigned char **oid, + size_t *oid_len, + const unsigned char **params, + size_t *params_len); =head1 DESCRIPTION @@ -63,6 +71,8 @@ macros in L, as follows: OSSL_FUNC_skeymgmt_generate OSSL_FUNC_SKEYMGMT_GENERATE OSSL_FUNC_skeymgmt_get_key_id OSSL_FUNC_SKEYMGMT_GET_KEY_ID + OSSL_FUNC_skeymgmt_get_local_keyid OSSL_FUNC_SKEYMGMT_GET_LOCAL_KEYID + OSSL_FUNC_skeymgmt_get_algorithm_id OSSL_FUNC_SKEYMGMT_GET_ALGORITHM_ID OSSL_FUNC_skeymgmt_imp_settable_params OSSL_FUNC_SKEYMGMT_IMP_SETTABLE_PARAMS OSSL_FUNC_skeymgmt_gen_settable_params OSSL_FUNC_SKEYMGMT_GEN_SETTABLE_PARAMS @@ -146,7 +156,21 @@ particular key. The returned string will be freed by a call to EVP_SKEY_free() so callers need to copy it themselves if they want to preserve the value past the key lifetime. The purpose of this function is providing a printable string that can help users to access the specific key. The content of this string is -provider-specific. +provider-specific. The built-in implementations return the value of +B if it was set during import. + +OSSL_FUNC_skeymgmt_get_local_keyid() retrieves the local key ID from I. +On success, it sets I<*id> to point to the key ID bytes and I<*len> to their +length, and returns 1 on success and 0 on error. As metadata is optional, the +resulting value still can be NULL and 0 correspondingly. + +OSSL_FUNC_skeymgmt_get_algorithm_id() retrieves the algorithm identifier from +I. On success, it sets I<*oid> and I<*oid_len> to point to the +DER-encoded algorithm OID, and I<*params> and I<*params_len> to point to the +DER-encoded algorithm parameters. Either output pointer pair may be NULL if +the caller does not need that part. Returns 1 if the requested data is set +successfully and 0 otherwise. As metadata is optional, the resulting value +still can be NULL and 0 correspondingly. =head2 Common Import and Export Parameters @@ -157,14 +181,33 @@ skeymgmt algorithms are as follows: =over 4 -=item "raw-bytes" (B) +=item "raw-bytes" (B) The value represents symmetric key as a byte array. -=item "key-length" (B) +=item "key-length" (B) The value is the byte length of the given key. +=item "skey-alias" (B) + +The friendly name (alias) for the key. This is used as the return value +from OSSL_FUNC_skeymgmt_get_key_id(). May be NULL. + +=item "skey-local-keyid" (B) + +The local key ID, typically originating from PKCS#12 bag attributes. +Represented as a byte array with an associated length. May be NULL. + +=item "skey-algorithm-oid" (B) + +The DER-encoded algorithm OID from the AlgorithmIdentifier. May be NULL. + +=item "skey-algorithm-params" (B) + +The DER-encoded algorithm parameters from the AlgorithmIdentifier. +May be NULL. + =back =head1 RETURN VALUES @@ -176,6 +219,9 @@ OSSL_FUNC_skeymgmt_export() returns 1 for success or 0 on error. OSSL_FUNC_skeymgmt_get_key_id() returns a pointer to a 0-terminated string or NULL. +OSSL_FUNC_skeymgmt_get_local_keyid() and OSSL_FUNC_skeymgmt_get_algorithm_id() +return 1 on success or 0 on error. + OSSL_FUNC_skeymgmt_gen_settable_params() and OSSL_FUNC_skeymgmt_imp_settable_params() return references to an array of B which can be NULL if there are no settable parameters. @@ -190,7 +236,7 @@ The SKEYMGMT interface was introduced in OpenSSL 3.5. =head1 COPYRIGHT -Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/man7/provider-storemgmt.pod b/doc/man7/provider-storemgmt.pod index 6c9f46075418b..c5703424fdd15 100644 --- a/doc/man7/provider-storemgmt.pod +++ b/doc/man7/provider-storemgmt.pod @@ -214,7 +214,7 @@ OSSL_FUNC_store_delete() callback was added in OpenSSL 3.2 =head1 COPYRIGHT -Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. +Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy diff --git a/doc/perlvars.pm b/doc/perlvars.pm index 5bc8ac61c5c42..5b68777f397c1 100644 --- a/doc/perlvars.pm +++ b/doc/perlvars.pm @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -151,11 +151,12 @@ $OpenSSL::safe::opt_version_synopsis = "" . "$OpenSSL::safe::opt_versiontls_synopsis\n" . "[B<-dtls>]\n" . "[B<-dtls1>]\n" -. "[B<-dtls1_2>]"; +. "[B<-dtls1_2>]\n" +. "[B<-dtls1_3>]"; $OpenSSL::safe::opt_version_item = "\n" . "$OpenSSL::safe::opt_versiontls_item\n" . "\n" -. "=item B<-dtls>, B<-dtls1>, B<-dtls1_2>\n" +. "=item B<-dtls>, B<-dtls1>, B<-dtls1_2>, B<-dtls1_3>\n" . "\n" . "These specify the use of DTLS instead of TLS.\n" . "See L."; diff --git a/exporters/cmake/OpenSSLConfig.cmake.in b/exporters/cmake/OpenSSLConfig.cmake.in index 4970528573ce8..e43560532116e 100644 --- a/exporters/cmake/OpenSSLConfig.cmake.in +++ b/exporters/cmake/OpenSSLConfig.cmake.in @@ -223,7 +223,7 @@ else() set(OPENSSL_CRYPTO_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY}) set(OPENSSL_SSL_LIBRARY ${OPENSSL_LIBSSL_SHARED}) set(OPENSSL_SSL_LIBRARIES ${OPENSSL_SSL_LIBRARY}) - set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES}) + set(OPENSSL_LIBRARIES ${OPENSSL_SSL_LIBRARIES} ${OPENSSL_CRYPTO_LIBRARIES}) {- output_on() if $lib_info{libcrypto}->{shared_import}; "" -} {- output_on() if $no_shared; "" -} endif() diff --git a/fuzz/acert.c b/fuzz/acert.c index 3af3c3e87a434..adff75c3ac6a1 100644 --- a/fuzz/acert.c +++ b/fuzz/acert.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/fuzz/asn1.c b/fuzz/asn1.c index 12ba8a13d47ce..2ceed4b5489d3 100644 --- a/fuzz/asn1.c +++ b/fuzz/asn1.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/fuzz/bignum.c b/fuzz/bignum.c index eec776e7b3ef1..990efff9303f5 100644 --- a/fuzz/bignum.c +++ b/fuzz/bignum.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/fuzz/bndiv.c b/fuzz/bndiv.c index c3a2d2f305f55..4a6732a775221 100644 --- a/fuzz/bndiv.c +++ b/fuzz/bndiv.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/fuzz/build.info b/fuzz/build.info index 5c410260e4c4d..90954aad0ecba 100644 --- a/fuzz/build.info +++ b/fuzz/build.info @@ -10,8 +10,9 @@ IF[{- !$disabled{"fuzz-afl"} || !$disabled{"fuzz-libfuzzer"} -}] PROGRAMS{noinst}=asn1 asn1parse bignum bndiv client conf crl server smime + PROGRAMS{noinst}=pkcs7_verify PROGRAMS{noinst}=pkcs12 punycode pem decoder hashtable acert - PROGRAMS{noinst}=v3name + PROGRAMS{noinst}=v3name x509v3 PROGRAMS{noinst}=provider IF[{- !$disabled{"ml-kem"} -}] @@ -31,7 +32,7 @@ IF[{- !$disabled{"fuzz-afl"} || !$disabled{"fuzz-libfuzzer"} -}] ENDIF IF[{- !$disabled{"cms"} -}] - PROGRAMS{noinst}=cms + PROGRAMS{noinst}=cms cms_verify ENDIF IF[{- !$disabled{"ct"} -}] @@ -50,6 +51,10 @@ IF[{- !$disabled{"fuzz-afl"} || !$disabled{"fuzz-libfuzzer"} -}] PROGRAMS{noinst}=dtlsclient dtlsserver ENDIF + IF[{- !$disabled{"ech"} -}] + PROGRAMS{noinst}=echconfiglist_parser + ENDIF + SOURCE[asn1]=asn1.c driver.c fuzz_rand.c INCLUDE[asn1]=../include {- $ex_inc -} DEPEND[asn1]=../libcrypto ../libssl {- $ex_lib -} @@ -82,6 +87,10 @@ IF[{- !$disabled{"fuzz-afl"} || !$disabled{"fuzz-libfuzzer"} -}] INCLUDE[cms]=../include {- $ex_inc -} DEPEND[cms]=../libcrypto {- $ex_lib -} + SOURCE[cms_verify]=cms_verify.c driver.c + INCLUDE[cms_verify]=../include {- $ex_inc -} + DEPEND[cms_verify]=../libcrypto {- $ex_lib -} + SOURCE[pkcs12]=pkcs12.c driver.c INCLUDE[pkcs12]=../include {- $ex_inc -} DEPEND[pkcs12]=../libcrypto {- $ex_lib -} @@ -106,6 +115,10 @@ IF[{- !$disabled{"fuzz-afl"} || !$disabled{"fuzz-libfuzzer"} -}] INCLUDE[dtlsserver]=../include {- $ex_inc -} DEPEND[dtlsserver]=../libcrypto ../libssl {- $ex_lib -} + SOURCE[echconfiglist_parser]=echconfiglist_parser.c driver.c + INCLUDE[echconfiglist_parser]=../include {- $ex_inc -} + DEPEND[echconfiglist_parser]=../libcrypto ../libssl {- $ex_lib -} + SOURCE[pem]=pem.c driver.c INCLUDE[pem]=../include {- $ex_inc -} DEPEND[pem]=../libcrypto.a {- $ex_lib -} @@ -130,10 +143,18 @@ IF[{- !$disabled{"fuzz-afl"} || !$disabled{"fuzz-libfuzzer"} -}] INCLUDE[smime]=../include {- $ex_inc -} DEPEND[smime]=../libcrypto ../libssl {- $ex_lib -} + SOURCE[pkcs7_verify]=pkcs7_verify.c driver.c + INCLUDE[pkcs7_verify]=../include {- $ex_inc -} + DEPEND[pkcs7_verify]=../libcrypto {- $ex_lib -} + SOURCE[v3name]=v3name.c driver.c INCLUDE[v3name]=../include {- $ex_inc -} DEPEND[v3name]=../libcrypto.a {- $ex_lib -} + SOURCE[x509v3]=x509v3.c driver.c + INCLUDE[x509v3]=../include {- $ex_inc -} + DEPEND[x509v3]=../libcrypto.a {- $ex_lib -} + SOURCE[quic-client]=quic-client.c driver.c fuzz_rand.c INCLUDE[quic-client]=../include {- $ex_inc -} DEPEND[quic-client]=../libcrypto.a ../libssl.a {- $ex_lib -} @@ -179,8 +200,9 @@ IF[{- !$disabled{tests} -}] $FUZZTESTSRC=test-corpus.c ../test/mfail/mfail.c PROGRAMS{noinst}=asn1-test asn1parse-test bignum-test bndiv-test client-test conf-test crl-test server-test smime-test + PROGRAMS{noinst}=pkcs7_verify-test PROGRAMS{noinst}=pkcs12-test punycode-test pem-test decoder-test hashtable-test acert-test - PROGRAMS{noinst}=v3name-test + PROGRAMS{noinst}=v3name-test x509v3-test PROGRAMS{noinst}=provider-test IF[{- !$disabled{"ml-kem"} -}] @@ -200,7 +222,7 @@ IF[{- !$disabled{tests} -}] ENDIF IF[{- !$disabled{"cms"} -}] - PROGRAMS{noinst}=cms-test + PROGRAMS{noinst}=cms-test cms_verify-test ENDIF IF[{- !$disabled{"ct"} -}] @@ -220,6 +242,10 @@ IF[{- !$disabled{tests} -}] PROGRAMS{noinst}=dtlsclient-test dtlsserver-test ENDIF + IF[{- !$disabled{"ech"} -}] + PROGRAMS{noinst}=echconfiglist_parser-test + ENDIF + SOURCE[asn1-test]=asn1.c $FUZZTESTSRC fuzz_rand.c INCLUDE[asn1-test]=../include ../test/mfail DEPEND[asn1-test]=../libcrypto.a ../libssl.a @@ -264,6 +290,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[cms-test]=../include ../test/mfail DEPEND[cms-test]=../libcrypto.a + SOURCE[cms_verify-test]=cms_verify.c $FUZZTESTSRC + INCLUDE[cms_verify-test]=../include ../test/mfail + DEPEND[cms_verify-test]=../libcrypto.a + SOURCE[pkcs12-test]=pkcs12.c $FUZZTESTSRC INCLUDE[pkcs12-test]=../include ../test/mfail DEPEND[pkcs12-test]=../libcrypto.a @@ -288,6 +318,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[dtlsserver-test]=../include ../test/mfail DEPEND[dtlsserver-test]=../libcrypto.a ../libssl.a + SOURCE[echconfiglist_parser-test]=echconfiglist_parser.c $FUZZTESTSRC + INCLUDE[echconfiglist_parser-test]=../include ../test/mfail + DEPEND[echconfiglist_parser-test]=../libcrypto.a ../libssl.a + SOURCE[pem-test]=pem.c $FUZZTESTSRC INCLUDE[pem-test]=../include ../test/mfail DEPEND[pem-test]=../libcrypto.a @@ -312,10 +346,18 @@ IF[{- !$disabled{tests} -}] INCLUDE[smime-test]=../include ../test/mfail DEPEND[smime-test]=../libcrypto.a ../libssl.a + SOURCE[pkcs7_verify-test]=pkcs7_verify.c $FUZZTESTSRC + INCLUDE[pkcs7_verify-test]=../include ../test/mfail + DEPEND[pkcs7_verify-test]=../libcrypto.a + SOURCE[v3name-test]=v3name.c $FUZZTESTSRC INCLUDE[v3name-test]=../include ../test/mfail DEPEND[v3name-test]=../libcrypto.a + SOURCE[x509v3-test]=x509v3.c $FUZZTESTSRC + INCLUDE[x509v3-test]=../include ../test/mfail + DEPEND[x509v3-test]=../libcrypto.a + SOURCE[quic-client-test]=quic-client.c $FUZZTESTSRC fuzz_rand.c INCLUDE[quic-client-test]=../include ../test/mfail DEPEND[quic-client-test]=../libcrypto.a ../libssl.a diff --git a/fuzz/client.c b/fuzz/client.c index 64d30dd09ebf9..8ed77ea8cd546 100644 --- a/fuzz/client.c +++ b/fuzz/client.c @@ -18,9 +18,6 @@ #include #include "fuzzer.h" -/* unused, to avoid warning. */ -static int idx; - #define FUZZTIME 1485898104 #define TIME_IMPL(t) \ @@ -50,7 +47,9 @@ time_t time(time_t *t) TIME_IMPL(t) OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); ERR_clear_error(); CRYPTO_free_ex_index(0, -1); - idx = SSL_get_ex_data_X509_STORE_CTX_idx(); + if (SSL_get_ex_data_X509_STORE_CTX_idx() != 0) { + /* Just suppress warning */ + } comp_methods = SSL_COMP_get_compression_methods(); if (comp_methods != NULL) sk_SSL_COMP_sort(comp_methods); diff --git a/fuzz/cms.c b/fuzz/cms.c index d45bf1b63c0f1..bd67e4f3a8924 100644 --- a/fuzz/cms.c +++ b/fuzz/cms.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/fuzz/cms_verify.c b/fuzz/cms_verify.c new file mode 100644 index 0000000000000..7e9ce3eafcbd6 --- /dev/null +++ b/fuzz/cms_verify.c @@ -0,0 +1,66 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * https://www.openssl.org/source/license.html + * or in the file LICENSE in the source distribution. + */ +#include +#include +#include +#include +#include "fuzzer.h" + +int FuzzerInitialize(int *argc, char ***argv) +{ + return 1; +} + +int FuzzerTestOneInput(const uint8_t *buf, size_t len) +{ + BIO *indata = NULL; + BIO *out = NULL; + CMS_ContentInfo *cms = NULL; + const unsigned char *in; + size_t consumed; + size_t remaining; + + if (len > LONG_MAX) + return 0; + + in = buf; + cms = d2i_CMS_ContentInfo(NULL, &in, (long)len); + if (cms == NULL) + goto err; + + consumed = (size_t)(in - buf); + remaining = len - consumed; + if (remaining > INT_MAX) + goto err; + + if (consumed < len) { + indata = BIO_new_mem_buf(in, (int)remaining); + if (indata == NULL) + goto err; + } + + out = BIO_new(BIO_s_null()); + if (out == NULL) + goto err; + + CMS_verify(cms, NULL, NULL, indata, out, + CMS_NO_SIGNER_CERT_VERIFY); + +err: + BIO_free(out); + CMS_ContentInfo_free(cms); + BIO_free(indata); + ERR_clear_error(); + return 0; +} + +void FuzzerCleanup(void) +{ +} diff --git a/fuzz/conf.c b/fuzz/conf.c index 116759a0a1f40..5e6b5ea7ad806 100644 --- a/fuzz/conf.c +++ b/fuzz/conf.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/fuzz/corpora b/fuzz/corpora index e79bbce6dc62e..5aad44f59020f 160000 --- a/fuzz/corpora +++ b/fuzz/corpora @@ -1 +1 @@ -Subproject commit e79bbce6dc62e794eab651d4be29b3d499d6df5c +Subproject commit 5aad44f59020f6b08e8af0c03eacb1e766970ed0 diff --git a/fuzz/crl.c b/fuzz/crl.c index f704321ac5f19..9268c5aae74ee 100644 --- a/fuzz/crl.c +++ b/fuzz/crl.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/fuzz/ct.c b/fuzz/ct.c index 74fbf66c0429d..430419d53dad3 100644 --- a/fuzz/ct.c +++ b/fuzz/ct.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/fuzz/decoder.c b/fuzz/decoder.c index 227c24fd71fa8..ab5dd3112bad0 100644 --- a/fuzz/decoder.c +++ b/fuzz/decoder.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/fuzz/dtlsclient.c b/fuzz/dtlsclient.c index 2dc5ed709c069..0fe3c9eacf919 100644 --- a/fuzz/dtlsclient.c +++ b/fuzz/dtlsclient.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,9 +18,6 @@ #include #include "fuzzer.h" -/* unused, to avoid warning. */ -static int idx; - #define FUZZTIME 1485898104 #define TIME_IMPL(t) \ @@ -50,7 +47,9 @@ time_t time(time_t *t) TIME_IMPL(t) OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); ERR_clear_error(); CRYPTO_free_ex_index(0, -1); - idx = SSL_get_ex_data_X509_STORE_CTX_idx(); + if (SSL_get_ex_data_X509_STORE_CTX_idx() != 0) { + /* Just suppress warning */ + } comp_methods = SSL_COMP_get_compression_methods(); if (comp_methods != NULL) sk_SSL_COMP_sort(comp_methods); @@ -78,6 +77,8 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) goto end; if (SSL_set_min_proto_version(client, 0) != 1) goto end; + if (SSL_set_max_proto_version(client, 0) != 1) + goto end; if (SSL_set_cipher_list(client, "ALL:eNULL:@SECLEVEL=0") != 1) goto end; SSL_set_tlsext_host_name(client, "localhost"); diff --git a/fuzz/dtlsserver.c b/fuzz/dtlsserver.c index 84ded9a4dfca0..e9c825ea81422 100644 --- a/fuzz/dtlsserver.c +++ b/fuzz/dtlsserver.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -735,9 +735,6 @@ static const char DSACertPEM[] = { }; #endif -/* unused, to avoid warning. */ -static int idx; - #define FUZZTIME 1485898104 #define TIME_IMPL(t) \ @@ -767,7 +764,9 @@ time_t time(time_t *t) TIME_IMPL(t) OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); ERR_clear_error(); CRYPTO_free_ex_index(0, -1); - idx = SSL_get_ex_data_X509_STORE_CTX_idx(); + if (SSL_get_ex_data_X509_STORE_CTX_idx() == 0) { + /* Just suppress warning */ + } comp_methods = SSL_COMP_get_compression_methods(); if (comp_methods != NULL) sk_SSL_COMP_sort(comp_methods); diff --git a/fuzz/echconfiglist_parser.c b/fuzz/echconfiglist_parser.c new file mode 100644 index 0000000000000..fce416ec4d8bd --- /dev/null +++ b/fuzz/echconfiglist_parser.c @@ -0,0 +1,88 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * https://www.openssl.org/source/license.html + * or in the file LICENSE in the source distribution. + */ +#include +#include +#include +#include +#include +#include +#include +#include "fuzzer.h" + +static void parse_one(const uint8_t *buf, int len) +{ + OSSL_ECHSTORE *es; + BIO *in; + + es = OSSL_ECHSTORE_new(NULL, NULL); + if (es == NULL) + return; + + in = BIO_new_mem_buf(buf, len); + if (in == NULL) { + OSSL_ECHSTORE_free(es); + return; + } + + OSSL_ECHSTORE_read_echconfiglist(es, in); + + OSSL_ECHSTORE_free(es); + BIO_free(in); +} + +int FuzzerInitialize(int *argc, char ***argv) +{ + return 1; +} + +int FuzzerTestOneInput(const uint8_t *buf, size_t len) +{ + uint8_t *fixed_buf = NULL; + int bio_len; + uint16_t outer_len, inner_len; + + if (len > INT_MAX) + return 0; + bio_len = (int)len; + + /* Target raw without any fixup */ + parse_one(buf, bio_len); + + /* + * ech_decode_and_flatten has a strict size check: + * OSSL_ECH_MIN_ECHCONFIG_LEN = 32 + * OSSL_ECH_MAX_ECHCONFIG_LEN = 1500 + */ + if (len < OSSL_ECH_MIN_ECHCONFIG_LEN || len >= OSSL_ECH_MAX_ECHCONFIG_LEN) + goto end; + outer_len = (uint16_t)(len - 2); + inner_len = (uint16_t)(len - 6); + + fixed_buf = OPENSSL_memdup(buf, len); + if (fixed_buf == NULL) + goto end; + + /* Fix up to pass initial checks*/ + OPENSSL_store_u16_be(fixed_buf, outer_len); + OPENSSL_store_u16_be(fixed_buf + 2, OSSL_ECH_RFC9849_VERSION); + OPENSSL_store_u16_be(fixed_buf + 4, inner_len); + + parse_one(fixed_buf, bio_len); + +end: + OPENSSL_free(fixed_buf); + ERR_clear_error(); + + return 0; +} + +void FuzzerCleanup(void) +{ +} diff --git a/fuzz/hashtable.c b/fuzz/hashtable.c index 9eb81c0a9eff2..2e503cc1a45a7 100644 --- a/fuzz/hashtable.c +++ b/fuzz/hashtable.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -12,6 +12,7 @@ * Test hashtable operation. */ #include +#include #include #include #include @@ -344,5 +345,11 @@ void FuzzerCleanup(void) { ossl_ht_free(fuzzer_table); OPENSSL_free(prediction_table); + + fprintf(stderr, "skipped_values: %zu inserts: %zu replacements: %zu deletes %zu\n" + "flushes: %zu lookups: %zu foreaches %zu filters %zu\n", + skipped_values, inserts, replacements, deletes, + flushes, lookups, foreaches, filters); + OPENSSL_cleanup(); } diff --git a/fuzz/ml-dsa.c b/fuzz/ml-dsa.c index e56a023e4673d..efd65185bdae2 100644 --- a/fuzz/ml-dsa.c +++ b/fuzz/ml-dsa.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/fuzz/ml-kem.c b/fuzz/ml-kem.c index dfd4faf6dcc0f..b74bfbfa98a0a 100644 --- a/fuzz/ml-kem.c +++ b/fuzz/ml-kem.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/fuzz/oids.txt b/fuzz/oids.txt index 5fac3e1c88b43..15202c7ff6e2d 100644 --- a/fuzz/oids.txt +++ b/fuzz/oids.txt @@ -1350,3 +1350,24 @@ OBJ_HKDF_SHA512="\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x03\x1E" OBJ_id_smime_ori="\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x0D" OBJ_id_smime_ori_kem="\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x0D\x03" OBJ_id_alg_hss_lms_hashsig="\x2A\x86\x48\x86\xF7\x0D\x01\x09\x10\x03\x11" +OBJ_id_rdna_unsigned="\x2B\x06\x01\x05\x05\x07\x19\x01" +OBJ_id_alg_unsigned="\x2B\x06\x01\x05\x05\x07\x06\x24" +OBJ_id_aes="\x60\x86\x48\x01\x65\x03\x04\x01" +OBJ_ML_DSA_44_RSA2048_PSS_SHA256="\x2B\x06\x01\x05\x05\x07\x06\x25" +OBJ_ML_DSA_44_RSA2048_PKCS15_SHA256="\x2B\x06\x01\x05\x05\x07\x06\x26" +OBJ_ML_DSA_44_Ed25519_SHA512="\x2B\x06\x01\x05\x05\x07\x06\x27" +OBJ_ML_DSA_44_ECDSA_P256_SHA256="\x2B\x06\x01\x05\x05\x07\x06\x28" +OBJ_ML_DSA_65_RSA3072_PSS_SHA512="\x2B\x06\x01\x05\x05\x07\x06\x29" +OBJ_ML_DSA_65_RSA3072_PKCS15_SHA512="\x2B\x06\x01\x05\x05\x07\x06\x2A" +OBJ_ML_DSA_65_RSA4096_PSS_SHA512="\x2B\x06\x01\x05\x05\x07\x06\x2B" +OBJ_ML_DSA_65_RSA4096_PKCS15_SHA512="\x2B\x06\x01\x05\x05\x07\x06\x2C" +OBJ_ML_DSA_65_ECDSA_P256_SHA512="\x2B\x06\x01\x05\x05\x07\x06\x2D" +OBJ_ML_DSA_65_ECDSA_P384_SHA512="\x2B\x06\x01\x05\x05\x07\x06\x2E" +OBJ_ML_DSA_65_ECDSA_brainpoolP256r1_SHA512="\x2B\x06\x01\x05\x05\x07\x06\x2F" +OBJ_ML_DSA_65_Ed25519_SHA512="\x2B\x06\x01\x05\x05\x07\x06\x30" +OBJ_ML_DSA_87_ECDSA_P384_SHA512="\x2B\x06\x01\x05\x05\x07\x06\x31" +OBJ_ML_DSA_87_ECDSA_brainpoolP384r1_SHA512="\x2B\x06\x01\x05\x05\x07\x06\x32" +OBJ_ML_DSA_87_Ed448_SHAKE256="\x2B\x06\x01\x05\x05\x07\x06\x33" +OBJ_ML_DSA_87_RSA3072_PSS_SHA512="\x2B\x06\x01\x05\x05\x07\x06\x34" +OBJ_ML_DSA_87_RSA4096_PSS_SHA512="\x2B\x06\x01\x05\x05\x07\x06\x35" +OBJ_ML_DSA_87_ECDSA_P521_SHA512="\x2B\x06\x01\x05\x05\x07\x06\x36" diff --git a/fuzz/pem.c b/fuzz/pem.c index a2da9820a7205..cedd688b52137 100644 --- a/fuzz/pem.c +++ b/fuzz/pem.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/fuzz/pkcs12.c b/fuzz/pkcs12.c index 74e2b6dd8aac3..b8c8927253dec 100644 --- a/fuzz/pkcs12.c +++ b/fuzz/pkcs12.c @@ -27,14 +27,31 @@ int FuzzerInitialize(int *argc, char ***argv) return 1; } -int FuzzerTestOneInput(const uint8_t *buf, size_t len) +static void fuzz_pkcs12_parse(PKCS12 *p12, const char *pass) { - PKCS12 *p12; - BIO *in; + PKCS12_PARSE_CTX *ctx; EVP_PKEY *pkey = NULL; X509 *cert = NULL; STACK_OF(X509) *ca = NULL; + ctx = PKCS12_PARSE_CTX_new(); + if (ctx == NULL) + return; + PKCS12_PARSE_CTX_set_pkey(ctx, &pkey); + PKCS12_PARSE_CTX_set_cert(ctx, &cert); + PKCS12_PARSE_CTX_set_ca(ctx, &ca); + PKCS12_parse_ex(p12, pass, ctx, NULL, NULL); + PKCS12_PARSE_CTX_free(ctx); + EVP_PKEY_free(pkey); + X509_free(cert); + OSSL_STACK_OF_X509_free(ca); +} + +int FuzzerTestOneInput(const uint8_t *buf, size_t len) +{ + PKCS12 *p12; + BIO *in; + if (len == 0 || len > INT_MAX) return 0; @@ -53,18 +70,8 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) PKCS12_verify_mac(p12, NULL, 0); PKCS12_verify_mac(p12, "", 0); - PKCS12_parse(p12, NULL, &pkey, &cert, &ca); - EVP_PKEY_free(pkey); - X509_free(cert); - OSSL_STACK_OF_X509_free(ca); - - pkey = NULL; - cert = NULL; - ca = NULL; - PKCS12_parse(p12, "", &pkey, &cert, &ca); - EVP_PKEY_free(pkey); - X509_free(cert); - OSSL_STACK_OF_X509_free(ca); + fuzz_pkcs12_parse(p12, NULL); + fuzz_pkcs12_parse(p12, ""); PKCS12_free(p12); } diff --git a/fuzz/pkcs7_verify.c b/fuzz/pkcs7_verify.c new file mode 100644 index 0000000000000..a167afb13dd77 --- /dev/null +++ b/fuzz/pkcs7_verify.c @@ -0,0 +1,65 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * https://www.openssl.org/source/license.html + * or in the file LICENSE in the source distribution. + */ +#include +#include +#include +#include +#include "fuzzer.h" + +int FuzzerInitialize(int *argc, char ***argv) +{ + return 1; +} + +int FuzzerTestOneInput(const uint8_t *buf, size_t len) +{ + BIO *indata = NULL; + BIO *out = NULL; + PKCS7 *p7 = NULL; + const unsigned char *in; + size_t consumed; + size_t remaining; + + if (len > LONG_MAX) + return 0; + + in = buf; + p7 = d2i_PKCS7(NULL, &in, (long)len); + if (p7 == NULL) + goto err; + + consumed = (size_t)(in - buf); + remaining = len - consumed; + if (remaining > INT_MAX) + goto err; + + if (consumed < len) { + indata = BIO_new_mem_buf(in, (int)remaining); + if (indata == NULL) + goto err; + } + + out = BIO_new(BIO_s_null()); + if (out == NULL) + goto err; + + PKCS7_verify(p7, NULL, NULL, indata, out, PKCS7_NOVERIFY); + +err: + BIO_free(out); + PKCS7_free(p7); + BIO_free(indata); + ERR_clear_error(); + return 0; +} + +void FuzzerCleanup(void) +{ +} diff --git a/fuzz/quic-client.c b/fuzz/quic-client.c index e75390ad602d6..00238998c7aff 100644 --- a/fuzz/quic-client.c +++ b/fuzz/quic-client.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,6 @@ #include "internal/time.h" #include "internal/quic_ssl.h" -/* unused, to avoid warning. */ -static int idx; - static OSSL_TIME fake_now; static OSSL_TIME fake_now_cb(void *arg) @@ -35,7 +32,9 @@ int FuzzerInitialize(int *argc, char ***argv) OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); ERR_clear_error(); CRYPTO_free_ex_index(0, -1); - idx = SSL_get_ex_data_X509_STORE_CTX_idx(); + if (SSL_get_ex_data_X509_STORE_CTX_idx() == 0) { + /* Just suppress warning */ + } comp_methods = SSL_COMP_get_compression_methods(); if (comp_methods != NULL) sk_SSL_COMP_sort(comp_methods); diff --git a/fuzz/quic-server.c b/fuzz/quic-server.c index 6be099d31dc70..65446f47dc124 100644 --- a/fuzz/quic-server.c +++ b/fuzz/quic-server.c @@ -16,9 +16,6 @@ #include "internal/time.h" #include "internal/quic_ssl.h" -/* unused, to avoid warning. */ -static int idx; - static OSSL_TIME fake_now; static OSSL_TIME fake_now_cb(void *arg) @@ -35,7 +32,9 @@ int FuzzerInitialize(int *argc, char ***argv) OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); ERR_clear_error(); CRYPTO_free_ex_index(0, -1); - idx = SSL_get_ex_data_X509_STORE_CTX_idx(); + if (SSL_get_ex_data_X509_STORE_CTX_idx() == 0) { + /* Just suppress warning */ + } comp_methods = SSL_COMP_get_compression_methods(); if (comp_methods != NULL) sk_SSL_COMP_sort(comp_methods); diff --git a/fuzz/quic-srtm.c b/fuzz/quic-srtm.c index 6e152299e1b62..9ab365d22d273 100644 --- a/fuzz/quic-srtm.c +++ b/fuzz/quic-srtm.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -88,7 +88,7 @@ int FuzzerTestOneInput(const uint8_t *buf, size_t len) continue; /* just stop */ if (ossl_quic_srtm_remove(srtm, (void *)(uintptr_t)arg_opaque, - arg_seq_num)) + arg_seq_num, NULL)) ossl_quic_srtm_check(srtm); break; diff --git a/fuzz/server.c b/fuzz/server.c index 740ade8513dc2..a06d872d1d0f2 100644 --- a/fuzz/server.c +++ b/fuzz/server.c @@ -551,9 +551,6 @@ static const char DSACertPEM[] = { }; #endif -/* unused, to avoid warning. */ -static int idx; - #define FUZZTIME 1485898104 #define TIME_IMPL(t) \ @@ -583,7 +580,9 @@ time_t time(time_t *t) TIME_IMPL(t) OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); ERR_clear_error(); CRYPTO_free_ex_index(0, -1); - idx = SSL_get_ex_data_X509_STORE_CTX_idx(); + if (SSL_get_ex_data_X509_STORE_CTX_idx() == 0) { + /* Just suppress warning */ + } comp_methods = SSL_COMP_get_compression_methods(); if (comp_methods != NULL) sk_SSL_COMP_sort(comp_methods); diff --git a/fuzz/slh-dsa.c b/fuzz/slh-dsa.c index 0f78a01da890d..22153dea42570 100644 --- a/fuzz/slh-dsa.c +++ b/fuzz/slh-dsa.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/fuzz/smime.c b/fuzz/smime.c index ab68cb0165df3..2556e49718654 100644 --- a/fuzz/smime.c +++ b/fuzz/smime.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/fuzz/v3name.c b/fuzz/v3name.c index 87fd8c147174b..5cf20bc33862e 100644 --- a/fuzz/v3name.c +++ b/fuzz/v3name.c @@ -1,5 +1,5 @@ /* - * Copyright 2012-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2012-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/fuzz/x509.c b/fuzz/x509.c index a10e8c006774d..011e2b0fa7b11 100644 --- a/fuzz/x509.c +++ b/fuzz/x509.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/fuzz/x509v3.c b/fuzz/x509v3.c new file mode 100644 index 0000000000000..d44b958082dfe --- /dev/null +++ b/fuzz/x509v3.c @@ -0,0 +1,84 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * https://www.openssl.org/source/license.html + * or in the file LICENSE in the source distribution. + */ +#include +#include +#include +#include +#include +#include "fuzzer.h" + +/* + * Repeated section references in the string-based extension APIs can cause + * quadratic output growth. Limit input size + * to keep individual fuzzing iterations small. See: + * https://github.com/google/boringssl/blob/f1f2556a5dfa59e147d9d47279cc3f7f8a18b433/fuzz/conf.cc#L22-L25 + * https://issues.chromium.org/issues/42290485 + */ +#define MAX_INPUT_SIZE (8 * 1024) + +int FuzzerInitialize(int *argc, char ***argv) +{ + return 1; +} + +int FuzzerTestOneInput(const uint8_t *buf, size_t len) +{ + BIO *in = NULL; + CONF *conf = NULL; + X509 *cert = NULL; + X509V3_CTX ctx; + + if (len == 0) + return 0; + + if (len > MAX_INPUT_SIZE) + len = MAX_INPUT_SIZE; + + in = BIO_new(BIO_s_mem()); + if (in == NULL) + goto end; + + if ((size_t)BIO_write(in, buf, (int)len) != len) + goto end; + + conf = NCONF_new(NULL); + if (conf == NULL) + goto end; + + if (NCONF_load_bio(conf, in, NULL) <= 0) + goto end; + + cert = X509_new(); + if (cert != NULL) { + X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0); + X509V3_set_nconf(&ctx, conf); + X509V3_EXT_add_nconf(conf, &ctx, "default", cert); + X509_free(cert); + } + + cert = X509_new(); + if (cert != NULL) { + X509V3_set_ctx(&ctx, NULL, NULL, NULL, NULL, 0); + X509V3_set_nconf(&ctx, conf); + X509V3_EXT_add_nconf(conf, &ctx, "default", cert); + } + +end: + X509_free(cert); + NCONF_free(conf); + BIO_free(in); + ERR_clear_error(); + + return 0; +} + +void FuzzerCleanup(void) +{ +} diff --git a/include/arch/arm_arch.h b/include/arch/arm_arch.h index 5bc61c22e1931..0721b067f757d 100644 --- a/include/arch/arm_arch.h +++ b/include/arch/arm_arch.h @@ -159,8 +159,9 @@ extern unsigned int OPENSSL_armv8_rsa_neonized; /* * Support macros for - * - Armv8.3-A Pointer Authentication and + * - Armv8.3-A Pointer Authentication * - Armv8.5-A Branch Target Identification + * - Armv9.4-A Guarded Control Stack * features which require emitting a .note.gnu.property section with the * appropriate architecture-dependent feature bits set. * Read more: "ELF for the Arm® 64-bit Architecture" @@ -194,7 +195,13 @@ extern unsigned int OPENSSL_armv8_rsa_neonized; #define AARCH64_VALIDATE_LINK_REGISTER #endif -#if GNU_PROPERTY_AARCH64_POINTER_AUTH != 0 || GNU_PROPERTY_AARCH64_BTI != 0 +#if defined(__ARM_FEATURE_GCS_DEFAULT) && __ARM_FEATURE_GCS_DEFAULT == 1 +#define GNU_PROPERTY_AARCH64_GCS (1 << 2) +#else +#define GNU_PROPERTY_AARCH64_GCS 0 /* No GCS */ +#endif + +#if GNU_PROPERTY_AARCH64_POINTER_AUTH != 0 || GNU_PROPERTY_AARCH64_BTI != 0 || GNU_PROPERTY_AARCH64_GCS != 0 /* clang-format off */ .pushsection .note.gnu.property, "a"; /* clang-format on */ @@ -205,7 +212,7 @@ extern unsigned int OPENSSL_armv8_rsa_neonized; .asciz "GNU"; .long 0xc0000000; /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */ .long 4; -.long(GNU_PROPERTY_AARCH64_POINTER_AUTH | GNU_PROPERTY_AARCH64_BTI); +.long(GNU_PROPERTY_AARCH64_POINTER_AUTH | GNU_PROPERTY_AARCH64_BTI | GNU_PROPERTY_AARCH64_GCS); .long 0; .popsection; #endif diff --git a/include/arch/loongarch_arch.h b/include/arch/loongarch_arch.h index e1a7f82293f8a..bfd0584f2bfef 100644 --- a/include/arch/loongarch_arch.h +++ b/include/arch/loongarch_arch.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/arch/mips_arch.h b/include/arch/mips_arch.h index ddc1293b2e6eb..8a23a949e0c5b 100644 --- a/include/arch/mips_arch.h +++ b/include/arch/mips_arch.h @@ -1,5 +1,5 @@ /* - * Copyright 2011-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/arch/ppc_arch.h b/include/arch/ppc_arch.h index 5945853ab1722..2550507171d53 100644 --- a/include/arch/ppc_arch.h +++ b/include/arch/ppc_arch.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/arch/riscv_arch.def b/include/arch/riscv_arch.def index 32147d0939c6d..8608b4309ee83 100644 --- a/include/arch/riscv_arch.def +++ b/include/arch/riscv_arch.def @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/arch/riscv_arch.h b/include/arch/riscv_arch.h index ddc36e58f1be1..b83d3b62c6fac 100644 --- a/include/arch/riscv_arch.h +++ b/include/arch/riscv_arch.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/arch/s390x_arch.h b/include/arch/s390x_arch.h index 95c01dd2dc980..a52ee7f993fe3 100644 --- a/include/arch/s390x_arch.h +++ b/include/arch/s390x_arch.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/aes_platform.h b/include/crypto/aes_platform.h index 36ba2665ee85a..8ae047def1553 100644 --- a/include/crypto/aes_platform.h +++ b/include/crypto/aes_platform.h @@ -184,6 +184,51 @@ void gcm_ghash_v8(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, siz #endif #endif +#if (defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)) \ + && !defined(OPENSSL_NO_ASM) \ + && ((defined(__GNUC__) && !defined(__clang__) && (__GNUC__ >= 8)) \ + || (defined(__clang__) && (__clang_major__ >= 7)) \ + || (defined(_MSC_VER) && (_MSC_VER >= 1927))) +#define VAES512_ELIGIBLE 1 +#else +#define VAES512_ELIGIBLE 0 +#endif + +/* + * An MSVC build of the VAES-512 CTR kernel returns a wrong keystream for + * AES-192 and AES-256 on a CPU that really has AVX-512 + VAES, for every + * payload whose block count leaves a 4-block (single-zmm) step. That also + * corrupts the AES-256-CTR based CTR-DRBG, so the damage is not confined to + * CTR callers. + * + * The same C is correct on VAES hardware under gcc, so this looks like code + * generation rather than a logic error. MSVC 14.51 is the toolset that fails; + * 14.41 does not reproduce it. Keep the CTR hook off for MSVC until that is + * understood. AES-CBC decryption stays enabled: it passed on the same host + * and compiler that exposed the CTR failure. + * See https://github.com/openssl/openssl/issues/32873. + */ +#if defined(_MSC_VER) && !defined(__clang__) +#define VAES_CTR_ELIGIBLE 0 +#else +#define VAES_CTR_ELIGIBLE VAES512_ELIGIBLE +#endif +#define VAES_CBC_ELIGIBLE VAES512_ELIGIBLE + +#if VAES_CTR_ELIGIBLE +void ossl_aes_ctr_vaes(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *counter, + unsigned char *ecount_buf, unsigned int *num); +int ossl_aes_ctr_vaes_eligible(void); +#endif + +#if VAES_CBC_ELIGIBLE +void ossl_aes_cbc_vaes_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, unsigned char ivec[16], int enc); +int ossl_aes_cbc_vaes_eligible(void); +#endif + #if defined(AES_ASM) && !defined(I386_ONLY) && (((defined(__i386) || defined(__i386__) || defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2)) || defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)) /* AES-NI section */ @@ -210,6 +255,7 @@ void ossl_aes_cfb128_vaes_enc(const unsigned char *in, unsigned char *out, void ossl_aes_cfb128_vaes_dec(const unsigned char *in, unsigned char *out, size_t len, const AES_KEY *ks, const unsigned char ivec[16], ossl_ssize_t *num); + int ossl_aes_cfb128_vaes_eligible(void); void aesni_encrypt(const unsigned char *in, unsigned char *out, diff --git a/include/crypto/ascon.h b/include/crypto/ascon.h new file mode 100644 index 0000000000000..01c4c86c9b458 --- /dev/null +++ b/include/crypto/ascon.h @@ -0,0 +1,57 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_CRYPTO_ASCON_H +#define OSSL_CRYPTO_ASCON_H +#include + +#ifndef OPENSSL_NO_ASCON128 + +#include +#include + +typedef struct { + uint64_t state[5]; + uint64_t key[2]; + size_t offset; + uint64_t flags; +} ascon_aead128_ctx; + +/* Provider compatibility typedef */ +typedef ascon_aead128_ctx ASCON_AEAD_CTX; + +/* Constants */ +#define ASCON_AEAD_NONCE_LEN 16 +#define ASCON_AEAD128_KEY_LEN 16 +#define ASCON_AEAD_TAG_LEN 16 + +/* Provider compatibility functions */ +void ossl_ascon_aead128_init(ASCON_AEAD_CTX *ctx, const unsigned char *k, + const unsigned char *n); +void ossl_ascon_aead128_assoc_data_update(ASCON_AEAD_CTX *ctx, + const unsigned char *in, size_t inl); +size_t ossl_ascon_aead128_encrypt_update(ASCON_AEAD_CTX *ctx, + unsigned char *out, + const unsigned char *in, size_t inl); +size_t ossl_ascon_aead128_decrypt_update(ASCON_AEAD_CTX *ctx, + unsigned char *out, + const unsigned char *in, size_t inl); +size_t ossl_ascon_aead128_encrypt_final(ASCON_AEAD_CTX *ctx, + unsigned char *out, + unsigned char *tag, size_t tag_len); +size_t ossl_ascon_aead128_decrypt_final(ASCON_AEAD_CTX *ctx, + unsigned char *out, + int *is_tag_valid, + const unsigned char *tag, + size_t tag_len); +void ossl_ascon_aead_cleanup(ASCON_AEAD_CTX *ctx); + +#endif /* OPENSSL_NO_ASCON128 */ + +#endif /* OSSL_CRYPTO_ASCON_H */ diff --git a/include/crypto/asn1.h b/include/crypto/asn1.h index bc556588d0c9f..ef5b836313f5c 100644 --- a/include/crypto/asn1.h +++ b/include/crypto/asn1.h @@ -27,14 +27,6 @@ * inserted in the memory buffer */ #define ASN1_STRING_FLAG_NDEF 0x010 - -/* - * This flag is used by the CMS code to indicate that a string is not - * complete and is a place holder for content when it had all been accessed. - * The flag will be reset when content has been written to it. - */ - -#define ASN1_STRING_FLAG_CONT 0x020 /* * This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING * type. @@ -50,7 +42,7 @@ struct asn1_string_st { int length; int type; - unsigned char *data; + unsigned char *data OPENSSL_NONSTRING; /* * The value of the following field depends on the type being held. It * is mostly being used for BIT_STRING so if the input data has a @@ -189,6 +181,28 @@ X509_ALGOR *ossl_X509_ALGOR_from_nid(int nid, int ptype, void *pval); void ossl_asn1_bit_string_clear_unused_bits(ASN1_STRING *str); void ossl_asn1_bit_string_set_unused_bits(ASN1_STRING *str, unsigned int num); +/** + * @brief Set str's data as ASN1_STRING_set1_data() does, and NUL-terminate it. + * The terminator is not counted in str->length. + * @param str the string to set + * @param data the bytes to copy, or NULL to allocate len bytes unset + * @param len the number of bytes at data + * @returns 1 on success, 0 on failure + * @see ASN1_STRING_set1_data(3) + */ +int ossl_asn1_string_set1_data(ASN1_STRING *str, const uint8_t *data, + size_t len); + +/** + * @brief Set str's data as ASN1_STRING_set1_string() does, and NUL-terminate it. + * The terminator is not counted in str->length. + * @param str the string to set + * @param c_string the NUL-terminated string to copy + * @returns 1 on success, 0 on failure + * @see ASN1_STRING_set1_string(3) + */ +int ossl_asn1_string_set1_string(ASN1_STRING *str, const char *c_string); + int asn1_item_embed_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt, ASN1_TLC *ctx, int depth, diff --git a/include/crypto/asn1err.h b/include/crypto/asn1err.h deleted file mode 100644 index 62fdfd5e9bf2a..0000000000000 --- a/include/crypto/asn1err.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_ASN1ERR_H -#define OSSL_CRYPTO_ASN1ERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_ASN1_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/asyncerr.h b/include/crypto/asyncerr.h deleted file mode 100644 index 6a653247abf5d..0000000000000 --- a/include/crypto/asyncerr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_ASYNCERR_H -#define OSSL_CRYPTO_ASYNCERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_ASYNC_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/bioerr.h b/include/crypto/bioerr.h deleted file mode 100644 index f30975213efc1..0000000000000 --- a/include/crypto/bioerr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_BIOERR_H -#define OSSL_CRYPTO_BIOERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_BIO_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/bn_dh.h b/include/crypto/bn_dh.h index 89175dfac2979..c0142bc77e924 100644 --- a/include/crypto/bn_dh.h +++ b/include/crypto/bn_dh.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/bn_srp.h b/include/crypto/bn_srp.h index 7e3dade0bd710..831f8d27cf3f4 100644 --- a/include/crypto/bn_srp.h +++ b/include/crypto/bn_srp.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/bnerr.h b/include/crypto/bnerr.h deleted file mode 100644 index 96b3a8dfba141..0000000000000 --- a/include/crypto/bnerr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_BNERR_H -#define OSSL_CRYPTO_BNERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_BN_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/buffererr.h b/include/crypto/buffererr.h deleted file mode 100644 index 21caac21f548c..0000000000000 --- a/include/crypto/buffererr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_BUFFERERR_H -#define OSSL_CRYPTO_BUFFERERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_BUF_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/cmll_platform.h b/include/crypto/cmll_platform.h index 207084b123e59..f1e28eb8b4f92 100644 --- a/include/crypto/cmll_platform.h +++ b/include/crypto/cmll_platform.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/cmperr.h b/include/crypto/cmperr.h deleted file mode 100644 index ea3ac24d270cf..0000000000000 --- a/include/crypto/cmperr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_CMPERR_H -#define OSSL_CRYPTO_CMPERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef OPENSSL_NO_CMP - -int ossl_err_load_CMP_strings(void); -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/cmserr.h b/include/crypto/cmserr.h deleted file mode 100644 index f9fd933682e54..0000000000000 --- a/include/crypto/cmserr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_CMSERR_H -#define OSSL_CRYPTO_CMSERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef OPENSSL_NO_CMS - -int ossl_err_load_CMS_strings(void); -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/comperr.h b/include/crypto/comperr.h deleted file mode 100644 index b12b70cc8b07d..0000000000000 --- a/include/crypto/comperr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_COMPERR_H -#define OSSL_CRYPTO_COMPERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef OPENSSL_NO_COMP - -int ossl_err_load_COMP_strings(void); -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/conferr.h b/include/crypto/conferr.h deleted file mode 100644 index 4e0474290bb55..0000000000000 --- a/include/crypto/conferr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_CONFERR_H -#define OSSL_CRYPTO_CONFERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_CONF_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/context.h b/include/crypto/context.h index d84b4879a69c5..6715f9219d2de 100644 --- a/include/crypto/context.h +++ b/include/crypto/context.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/crmferr.h b/include/crypto/crmferr.h deleted file mode 100644 index 8216e7fcf74bc..0000000000000 --- a/include/crypto/crmferr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_CRMFERR_H -#define OSSL_CRYPTO_CRMFERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef OPENSSL_NO_CRMF - -int ossl_err_load_CRMF_strings(void); -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/cryptoerr.h b/include/crypto/cryptoerr.h deleted file mode 100644 index f4a2389907a93..0000000000000 --- a/include/crypto/cryptoerr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_CRYPTOERR_H -#define OSSL_CRYPTO_CRYPTOERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_CRYPTO_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/cterr.h b/include/crypto/cterr.h deleted file mode 100644 index 0af2d31516f81..0000000000000 --- a/include/crypto/cterr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_CTERR_H -#define OSSL_CRYPTO_CTERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef OPENSSL_NO_CT - -int ossl_err_load_CT_strings(void); -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/decoder.h b/include/crypto/decoder.h index dafb1435938f4..ef143f9200561 100644 --- a/include/crypto/decoder.h +++ b/include/crypto/decoder.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/decodererr.h b/include/crypto/decodererr.h deleted file mode 100644 index c1aadca3652da..0000000000000 --- a/include/crypto/decodererr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_DECODERERR_H -#define OSSL_CRYPTO_DECODERERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_OSSL_DECODER_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/des_platform.h b/include/crypto/des_platform.h index 660d1b6a1877f..4805ba784f4c2 100644 --- a/include/crypto/des_platform.h +++ b/include/crypto/des_platform.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/dherr.h b/include/crypto/dherr.h deleted file mode 100644 index 00ea8fe667ba5..0000000000000 --- a/include/crypto/dherr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_DHERR_H -#define OSSL_CRYPTO_DHERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef OPENSSL_NO_DH - -int ossl_err_load_DH_strings(void); -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/dsaerr.h b/include/crypto/dsaerr.h deleted file mode 100644 index f4a886b1ac534..0000000000000 --- a/include/crypto/dsaerr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_DSAERR_H -#define OSSL_CRYPTO_DSAERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef OPENSSL_NO_DSA - -int ossl_err_load_DSA_strings(void); -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/ec.h b/include/crypto/ec.h index 22f614cccd3e5..cb648bcf95271 100644 --- a/include/crypto/ec.h +++ b/include/crypto/ec.h @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -26,6 +26,55 @@ int evp_pkey_ctx_set_ec_param_enc_prov(EVP_PKEY_CTX *ctx, int param_enc); #include #include "crypto/types.h" +typedef struct ec_params_st { + /* Domain parameters */ + OSSL_PARAM *group_name; + OSSL_PARAM *encoding; + OSSL_PARAM *pt_format; + OSSL_PARAM *field_type; + OSSL_PARAM *p; + OSSL_PARAM *a; + OSSL_PARAM *b; + OSSL_PARAM *generator; + OSSL_PARAM *order; + OSSL_PARAM *cofactor; + OSSL_PARAM *seed; + OSSL_PARAM *decoded; + + /* Key and other parameters */ + OSSL_PARAM *pub; + OSSL_PARAM *priv; + OSSL_PARAM *pub_x; + OSSL_PARAM *pub_y; + OSSL_PARAM *encoded_pub; + OSSL_PARAM *use_cofactor; + OSSL_PARAM *include_public; + OSSL_PARAM *group_check; + + /* Key information */ + OSSL_PARAM *bits; + OSSL_PARAM *field_degree; + OSSL_PARAM *secbits; + OSSL_PARAM *maxsize; + OSSL_PARAM *seccat; + OSSL_PARAM *default_digest; + + /* Characteristic two field information */ + OSSL_PARAM *char2_m; + OSSL_PARAM *char2_type; + OSSL_PARAM *char2_tp; + OSSL_PARAM *char2_k1; + OSSL_PARAM *char2_k2; + OSSL_PARAM *char2_k3; + + /* Generation parameters */ + OSSL_PARAM *dhkem_ikm; +#ifdef FIPS_MODULE + OSSL_PARAM *fips_key_check; + OSSL_PARAM *fips_indicator; +#endif +} EC_PARAMS; + /*- * Computes the multiplicative inverse of x in the range * [1,EC_GROUP::order), where EC_GROUP::order is the cardinality of the @@ -72,11 +121,23 @@ int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, OSSL_PARAM params[], OSSL_LIB_CTX *libctx, const char *propq, BN_CTX *bnctx, unsigned char **genbuf); +int ossl_ec_group_todata_parsed(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl, + const EC_PARAMS *params, OSSL_LIB_CTX *libctx, + const char *propq, + BN_CTX *bnctx, unsigned char **genbuf); int ossl_ec_group_fromdata(EC_KEY *ec, const OSSL_PARAM params[]); +int ossl_ec_group_fromdata_parsed(EC_KEY *ec, const EC_PARAMS *params); int ossl_ec_group_set_params(EC_GROUP *group, const OSSL_PARAM params[]); +int ossl_ec_group_set_params_parsed(EC_GROUP *group, const EC_PARAMS *params); +EC_GROUP *ossl_ec_group_new_from_params_parsed(const EC_PARAMS *params, + OSSL_LIB_CTX *libctx, const char *propq); int ossl_ec_key_fromdata(EC_KEY *ecx, const OSSL_PARAM params[], int include_private); +int ossl_ec_key_fromdata_parsed(EC_KEY *ecx, const EC_PARAMS *params, + int include_private); int ossl_ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]); +int ossl_ec_key_otherparams_fromdata_parsed(EC_KEY *ec, + const EC_PARAMS *params); int ossl_ec_key_is_foreign(const EC_KEY *ec); EC_KEY *ossl_ec_key_dup(const EC_KEY *key, int selection); int ossl_x509_algor_is_sm2(const X509_ALGOR *palg); diff --git a/include/crypto/ec_params.h.in b/include/crypto/ec_params.h.in new file mode 100644 index 0000000000000..700fa8bae8f34 --- /dev/null +++ b/include/crypto/ec_params.h.in @@ -0,0 +1,263 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_CRYPTO_EC_PARAMS_H +#define OSSL_CRYPTO_EC_PARAMS_H + +/* clang-format off */ + +{- +use OpenSSL::paramnames qw(produce_param_decoder); +-} + +#include "crypto/ec.h" +#include +#include +#include + +{- +our @EC_GROUP_NAME_TYPES = ( + ['OSSL_PKEY_PARAM_GROUP_NAME', 'group_name', 'utf8_string'], +); + +our @EC_ENCODING_TYPES = ( + ['OSSL_PKEY_PARAM_EC_ENCODING', 'encoding', 'utf8_string'], +); + +our @EC_POINT_FORMAT_TYPES = ( + ['OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT', 'pt_format', 'utf8_string', 'duplicate: first'], +); + +our @EC_FIELD_TYPE_TYPES = ( + ['OSSL_PKEY_PARAM_EC_FIELD_TYPE', 'field_type', 'utf8_string'], +); + +our @EC_EXPLICIT_CURVE_TYPES = ( + ['OSSL_PKEY_PARAM_EC_P', 'p', 'BN'], + ['OSSL_PKEY_PARAM_EC_A', 'a', 'BN'], + ['OSSL_PKEY_PARAM_EC_B', 'b', 'BN'], + ['OSSL_PKEY_PARAM_EC_GENERATOR', 'generator', 'octet_string'], + ['OSSL_PKEY_PARAM_EC_ORDER', 'order', 'BN'], + ['OSSL_PKEY_PARAM_EC_COFACTOR', 'cofactor', 'BN'], +); + +our @EC_SEED_TYPES = ( + ['OSSL_PKEY_PARAM_EC_SEED', 'seed', 'octet_string'], +); + +our @EC_DECODED_TYPES = ( + ['OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS', 'decoded', 'int'], +); + +our @EC_DOMAIN_TYPES = ( + @EC_GROUP_NAME_TYPES, + @EC_ENCODING_TYPES, + @EC_POINT_FORMAT_TYPES, + @EC_FIELD_TYPE_TYPES, + @EC_EXPLICIT_CURVE_TYPES, + @EC_SEED_TYPES, + @EC_DECODED_TYPES, +); + +our @EC_PRIVATE_KEY_TYPES = ( + ['OSSL_PKEY_PARAM_PRIV_KEY', 'priv', 'BN'], +); + +our @EC_PUBLIC_KEY_TYPES = ( + ['OSSL_PKEY_PARAM_PUB_KEY', 'pub', 'octet_string'], +); + +our @EC_KEY_TYPES = ( + @EC_PUBLIC_KEY_TYPES, + @EC_PRIVATE_KEY_TYPES, +); + +our @EC_COFACTOR_MODE_TYPES = ( + ['OSSL_PKEY_PARAM_USE_COFACTOR_ECDH', 'use_cofactor', 'int'], +); + +our @EC_INCLUDE_PUBLIC_TYPES = ( + ['OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC', 'include_public', 'int'], +); + +our @EC_GROUP_CHECK_TYPES = ( + ['OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE', 'group_check', 'utf8_string'], +); + +our @EC_OTHER_TYPES = ( + @EC_COFACTOR_MODE_TYPES, + @EC_INCLUDE_PUBLIC_TYPES, + @EC_GROUP_CHECK_TYPES, +); + +our @EC_COMMON_INFO_TYPES = ( + ['OSSL_PKEY_PARAM_BITS', 'bits', 'int'], + ['OSSL_PKEY_PARAM_EC_FIELD_DEGREE', 'field_degree', 'int'], + ['OSSL_PKEY_PARAM_SECURITY_BITS', 'secbits', 'int'], + ['OSSL_PKEY_PARAM_MAX_SIZE', 'maxsize', 'int'], +); + +our @EC_SECURITY_CATEGORY_INFO_TYPES = ( + ['OSSL_PKEY_PARAM_SECURITY_CATEGORY', 'seccat', 'int'], +); + +our @EC_DIGEST_INFO_TYPES = ( + ['OSSL_PKEY_PARAM_DEFAULT_DIGEST', 'default_digest', 'utf8_string'], +); + +our @EC_ENCODED_PUBLIC_KEY_TYPES = ( + ['OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY', 'encoded_pub', 'octet_string'], +); + +our @EC_AFFINE_PUBLIC_KEY_TYPES = ( + ['OSSL_PKEY_PARAM_EC_PUB_X', 'pub_x', 'BN'], + ['OSSL_PKEY_PARAM_EC_PUB_Y', 'pub_y', 'BN'], +); + +our @EC_INFO_TYPES = ( + @EC_COMMON_INFO_TYPES, + @EC_SECURITY_CATEGORY_INFO_TYPES, + @EC_DIGEST_INFO_TYPES, + @EC_ENCODED_PUBLIC_KEY_TYPES, + @EC_AFFINE_PUBLIC_KEY_TYPES, +); + +our @EC2M_INFO_TYPES = ( + ['OSSL_PKEY_PARAM_EC_CHAR2_M', 'char2_m', 'int', + '#if !defined(OPENSSL_NO_EC2M)'], + ['OSSL_PKEY_PARAM_EC_CHAR2_TYPE', 'char2_type', 'utf8_string', + '#if !defined(OPENSSL_NO_EC2M)'], + ['OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS', 'char2_tp', 'int', + '#if !defined(OPENSSL_NO_EC2M)'], + ['OSSL_PKEY_PARAM_EC_CHAR2_PP_K1', 'char2_k1', 'int', + '#if !defined(OPENSSL_NO_EC2M)'], + ['OSSL_PKEY_PARAM_EC_CHAR2_PP_K2', 'char2_k2', 'int', + '#if !defined(OPENSSL_NO_EC2M)'], + ['OSSL_PKEY_PARAM_EC_CHAR2_PP_K3', 'char2_k3', 'int', + '#if !defined(OPENSSL_NO_EC2M)'], +); + +our @EC_SETTABLE_TYPES = ( + @EC_COFACTOR_MODE_TYPES, + @EC_ENCODED_PUBLIC_KEY_TYPES, + @EC_ENCODING_TYPES, + @EC_POINT_FORMAT_TYPES, + @EC_SEED_TYPES, + @EC_INCLUDE_PUBLIC_TYPES, + @EC_GROUP_CHECK_TYPES, +); + +our @EC_DHKEM_GEN_TYPES = ( + ['OSSL_PKEY_PARAM_DHKEM_IKM', 'dhkem_ikm', 'octet_string', '!fips'], +); + +our @EC_FIPS_GEN_TYPES = ( + ['OSSL_PKEY_PARAM_FIPS_KEY_CHECK', 'fips_key_check', 'int', 'fips'], +); + +our @EC_GEN_TYPES = ( + @EC_GROUP_NAME_TYPES, + @EC_COFACTOR_MODE_TYPES, + @EC_ENCODING_TYPES, + @EC_POINT_FORMAT_TYPES, + @EC_FIELD_TYPE_TYPES, + @EC_GROUP_CHECK_TYPES, + @EC_EXPLICIT_CURVE_TYPES, + @EC_SEED_TYPES, + @EC_DHKEM_GEN_TYPES, + @EC_FIPS_GEN_TYPES, +); + +return ""; +-} + +/* Selection-specific provider import and export declarations. */ +{- +my $imexport = ""; + +# Compact bit flags used to index ec_types in ec_kmgmt.c. +my $private_key_type = 1; +my $public_key_type = 2; +my $domain_type = 4; +my $other_parameters_type = 8; +my $all_types = $private_key_type | $public_key_type + | $domain_type | $other_parameters_type; + +for my $selection ($private_key_type..$all_types) { + my @types = (); + + push @types, @EC_PRIVATE_KEY_TYPES + if ($selection & $private_key_type); + push @types, @EC_PUBLIC_KEY_TYPES + if ($selection & $public_key_type); + push @types, @EC_DOMAIN_TYPES if ($selection & $domain_type); + push @types, @EC_OTHER_TYPES if ($selection & $other_parameters_type); + $imexport .= "#define ec_imexport_types_" + . "${selection}_st ec_params_st\n"; + $imexport .= produce_param_decoder( + "ec_imexport_types_${selection}", @types); + $imexport .= "\n"; +} +$imexport; +-} + +/* Public EC compatibility functions retain their existing signatures. */ +#define ec_group_fromdata_st ec_params_st +{- produce_param_decoder('ec_group_fromdata', @EC_DOMAIN_TYPES); -} + +#define ec_group_todata_st ec_params_st +{- produce_param_decoder('ec_group_todata', @EC_DOMAIN_TYPES); -} + +#define ec_key_fromdata_st ec_params_st +{- produce_param_decoder('ec_key_fromdata', @EC_KEY_TYPES); -} + +#define ec_key_otherparams_fromdata_st ec_params_st +{- produce_param_decoder('ec_key_otherparams_fromdata', @EC_OTHER_TYPES, + @EC_POINT_FORMAT_TYPES); -} + +#define ec_pkey_import_from_st ec_params_st +{- produce_param_decoder('ec_pkey_import_from', + (@EC_DOMAIN_TYPES, @EC_KEY_TYPES, @EC_OTHER_TYPES)); -} + +/* Keymgmt get and set parameter surfaces. */ +#define ec_get_params_st ec_params_st +{- produce_param_decoder('ec_get_params', + (@EC_INFO_TYPES, @EC_DOMAIN_TYPES, @EC2M_INFO_TYPES, + @EC_KEY_TYPES, @EC_OTHER_TYPES)); -} + +#define sm2_get_params_st ec_params_st +{- produce_param_decoder('sm2_get_params', + (@EC_COMMON_INFO_TYPES, @EC_DIGEST_INFO_TYPES, + @EC_ENCODED_PUBLIC_KEY_TYPES, @EC_DOMAIN_TYPES, + @EC_KEY_TYPES, @EC_AFFINE_PUBLIC_KEY_TYPES)); -} + +#define ec_set_params_st ec_params_st +{- produce_param_decoder('ec_set_params', @EC_SETTABLE_TYPES); -} + +#define sm2_set_params_st ec_params_st +{- produce_param_decoder('sm2_set_params', @EC_SETTABLE_TYPES); -} + +/* Key generation context parameters. */ +#define ec_gen_set_params_st ec_params_st +{- produce_param_decoder('ec_gen_set_params', @EC_GEN_TYPES); -} + +#define sm2_gen_set_params_st ec_params_st +{- produce_param_decoder('sm2_gen_set_params', + (@EC_GROUP_NAME_TYPES, @EC_ENCODING_TYPES, + @EC_POINT_FORMAT_TYPES, @EC_FIELD_TYPE_TYPES, + @EC_EXPLICIT_CURVE_TYPES, @EC_SEED_TYPES)); -} + +#define ec_gen_get_params_st ec_params_st +{- produce_param_decoder('ec_gen_get_params', + ['OSSL_PKEY_PARAM_FIPS_APPROVED_INDICATOR', + 'fips_indicator', 'int', 'fips']); -} + +/* clang-format on */ + +#endif diff --git a/include/crypto/ecerr.h b/include/crypto/ecerr.h deleted file mode 100644 index 22003a3025ca6..0000000000000 --- a/include/crypto/ecerr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_ECERR_H -#define OSSL_CRYPTO_ECERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef OPENSSL_NO_EC - -int ossl_err_load_EC_strings(void); -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/encodererr.h b/include/crypto/encodererr.h deleted file mode 100644 index 71fddeb50c633..0000000000000 --- a/include/crypto/encodererr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_ENCODERERR_H -#define OSSL_CRYPTO_ENCODERERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_OSSL_ENCODER_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/ess.h b/include/crypto/ess.h index cc5bb7febcc7b..779903e11ce6f 100644 --- a/include/crypto/ess.h +++ b/include/crypto/ess.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/esserr.h b/include/crypto/esserr.h deleted file mode 100644 index 7766d05cd92fb..0000000000000 --- a/include/crypto/esserr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_ESSERR_H -#define OSSL_CRYPTO_ESSERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_ESS_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/evp.h b/include/crypto/evp.h index eca29a7438230..332ff7ae5916d 100644 --- a/include/crypto/evp.h +++ b/include/crypto/evp.h @@ -426,7 +426,6 @@ struct evp_pkey_st { #ifndef FIPS_MODULE STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ int save_parameters; - unsigned int foreign : 1; /* the low-level key is using an engine or an app-method */ CRYPTO_EX_DATA ex_data; #endif diff --git a/include/crypto/evperr.h b/include/crypto/evperr.h deleted file mode 100644 index afe136c816ae6..0000000000000 --- a/include/crypto/evperr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_EVPERR_H -#define OSSL_CRYPTO_EVPERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_EVP_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/httperr.h b/include/crypto/httperr.h deleted file mode 100644 index 94d812295cd92..0000000000000 --- a/include/crypto/httperr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_HTTPERR_H -#define OSSL_CRYPTO_HTTPERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef OPENSSL_NO_HTTP - -int ossl_err_load_HTTP_strings(void); -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/lms_util.h b/include/crypto/lms_util.h index 54aa51e17a7ba..083c87400ce9f 100644 --- a/include/crypto/lms_util.h +++ b/include/crypto/lms_util.h @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/md32_common.inc b/include/crypto/md32_common.inc index 3dea481c5677d..53c3bf7936b73 100644 --- a/include/crypto/md32_common.inc +++ b/include/crypto/md32_common.inc @@ -120,6 +120,11 @@ : "=r"(ret) \ : "r"(x), "i"(32 - (n))); ret; }) #endif +# elif defined(__e2k__) +# undef ROTATE +# define ROTATE(a,n) ( (__builtin_constant_p(n) && (n) > 16) \ + ? __builtin_e2k_scrs((a), 32 - (n)) \ + : __builtin_e2k_scls((a), (n)) ) #endif #endif #endif diff --git a/include/crypto/ml_kem.h b/include/crypto/ml_kem.h index 7d1f3cd602862..a4455dc71b36b 100644 --- a/include/crypto/ml_kem.h +++ b/include/crypto/ml_kem.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/modes.h b/include/crypto/modes.h index baa0f3a6c14ee..c7c31fd7ff9a0 100644 --- a/include/crypto/modes.h +++ b/include/crypto/modes.h @@ -1,5 +1,5 @@ /* - * Copyright 2010-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2010-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -25,7 +25,7 @@ #define STRICT_ALIGNMENT 1 #ifndef PEDANTIC -#if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || defined(__aarch64__) || defined(__s390__) || defined(__s390x__) +#if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || defined(__aarch64__) || defined(__s390__) || defined(__s390x__) || defined(__e2k__) #undef STRICT_ALIGNMENT #endif #endif @@ -72,6 +72,9 @@ #define BSWAP4(x) ({ uint32_t ret_=(x); \ asm ("rev8 %0,%0; srli %0,%0,32"\ : "+&r"(ret_)); ret_; }) +#elif defined(__e2k__) +#define BSWAP8(x) __builtin_bswap64(x) +#define BSWAP4(x) __builtin_bswap32(x) #endif #elif defined(_MSC_VER) #if _MSC_VER >= 1300 diff --git a/include/crypto/objects.h b/include/crypto/objects.h index 499c769dd06a6..7bc9c4d725d3f 100644 --- a/include/crypto/objects.h +++ b/include/crypto/objects.h @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/objectserr.h b/include/crypto/objectserr.h deleted file mode 100644 index 47fc698aa135c..0000000000000 --- a/include/crypto/objectserr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_OBJECTSERR_H -#define OSSL_CRYPTO_OBJECTSERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_OBJ_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/ocsperr.h b/include/crypto/ocsperr.h deleted file mode 100644 index d05a0324c0b4c..0000000000000 --- a/include/crypto/ocsperr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_OCSPERR_H -#define OSSL_CRYPTO_OCSPERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef OPENSSL_NO_OCSP - -int ossl_err_load_OCSP_strings(void); -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/pemerr.h b/include/crypto/pemerr.h deleted file mode 100644 index 3a2aa02261049..0000000000000 --- a/include/crypto/pemerr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_PEMERR_H -#define OSSL_CRYPTO_PEMERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_PEM_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/pkcs12err.h b/include/crypto/pkcs12err.h deleted file mode 100644 index eebf3f99a967f..0000000000000 --- a/include/crypto/pkcs12err.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_PKCS12ERR_H -#define OSSL_CRYPTO_PKCS12ERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_PKCS12_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/pkcs7.h b/include/crypto/pkcs7.h index 8d999fd44f8b8..df9d123fce7af 100644 --- a/include/crypto/pkcs7.h +++ b/include/crypto/pkcs7.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/pkcs7err.h b/include/crypto/pkcs7err.h deleted file mode 100644 index 68d071b936fa4..0000000000000 --- a/include/crypto/pkcs7err.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_PKCS7ERR_H -#define OSSL_CRYPTO_PKCS7ERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_PKCS7_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/rand.h b/include/crypto/rand.h index 357ce885b716b..183fd5ec571da 100644 --- a/include/crypto/rand.h +++ b/include/crypto/rand.h @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -153,6 +153,8 @@ int ossl_pool_add_nonce_data(RAND_POOL *pool); EVP_RAND_CTX *ossl_rand_get0_private_noncreating(OSSL_LIB_CTX *ctx); #else EVP_RAND_CTX *ossl_rand_get0_seed_noncreating(OSSL_LIB_CTX *ctx); +EVP_RAND_CTX *ossl_rand_get0_seed(OSSL_LIB_CTX *ctx); +int ossl_rand_seed_source_strict(OSSL_LIB_CTX *ctx); #endif /* Generate a uniformly distributed random integer in the interval [0, upper) */ diff --git a/include/crypto/randerr.h b/include/crypto/randerr.h deleted file mode 100644 index b6c91c7f98069..0000000000000 --- a/include/crypto/randerr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_RANDERR_H -#define OSSL_CRYPTO_RANDERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_RAND_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/rsa.h b/include/crypto/rsa.h index 0b853f9a80f92..a57702aa1d1bd 100644 --- a/include/crypto/rsa.h +++ b/include/crypto/rsa.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,6 +17,58 @@ #define RSA_MIN_MODULUS_BITS 512 +#ifdef FIPS_MODULE +#define OSSL_RSA_PARAM_MAX_PRIMES 2 +#else +#define OSSL_RSA_PARAM_MAX_PRIMES 10 +#endif + +typedef struct rsa_params_st { + OSSL_PARAM *n; + OSSL_PARAM *e; + OSSL_PARAM *d; + OSSL_PARAM *a; + OSSL_PARAM *b; + OSSL_PARAM *bits; + OSSL_PARAM *secbits; + OSSL_PARAM *maxsize; + OSSL_PARAM *seccat; + OSSL_PARAM *default_digest; + OSSL_PARAM *mandatory_digest; + + /* PSS specific params */ + OSSL_PARAM *digest; + OSSL_PARAM *digest_props; + OSSL_PARAM *maskgenfunc; + OSSL_PARAM *mgf1_digest; + OSSL_PARAM *pss_saltlen; + + /* import specific params */ + OSSL_PARAM *derive; + +#ifdef FIPS_MODULE + struct { + OSSL_PARAM *xp; + OSSL_PARAM *xp1; + OSSL_PARAM *xp2; + OSSL_PARAM *xq; + OSSL_PARAM *xq1; + OSSL_PARAM *xq2; + OSSL_PARAM *p1; + OSSL_PARAM *p2; + OSSL_PARAM *q1; + OSSL_PARAM *q2; + } fips; +#endif + + OSSL_PARAM *primes; + struct { + OSSL_PARAM *factors[OSSL_RSA_PARAM_MAX_PRIMES]; + OSSL_PARAM *exps[OSSL_RSA_PARAM_MAX_PRIMES]; + OSSL_PARAM *coeffs[OSSL_RSA_PARAM_MAX_PRIMES - 1]; + } mp; +} RSA_PARAMS; + typedef struct rsa_pss_params_30_st { int hash_algorithm_nid; struct { @@ -73,13 +125,19 @@ RSA *ossl_rsa_dup(const RSA *rsa, int selection); int ossl_rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[], int include_private); +int ossl_rsa_todata_parsed(RSA *rsa, OSSL_PARAM_BLD *bld, + const RSA_PARAMS *params, int include_private); int ossl_rsa_fromdata(RSA *rsa, const OSSL_PARAM params[], int include_private); +int ossl_rsa_fromdata_parsed(RSA *rsa, const RSA_PARAMS *params, + int include_private); int ossl_rsa_pss_params_30_todata(const RSA_PSS_PARAMS_30 *pss, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]); +int ossl_rsa_pss_params_30_todata_parsed(const RSA_PSS_PARAMS_30 *pss, + OSSL_PARAM_BLD *bld, const RSA_PARAMS *params); int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, - int *defaults_set, - const OSSL_PARAM params[], - OSSL_LIB_CTX *libctx); + int *defaults_set, const OSSL_PARAM params[], OSSL_LIB_CTX *libctx); +int ossl_rsa_pss_params_30_fromdata_parsed(RSA_PSS_PARAMS_30 *pss_params, + int *defaults_set, const RSA_PARAMS *params, OSSL_LIB_CTX *libctx); int ossl_rsa_set0_pss_params(RSA *r, RSA_PSS_PARAMS *pss); int ossl_rsa_pss_get_param_unverified(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, const EVP_MD **pmgf1md, @@ -130,10 +188,13 @@ int ossl_rsa_generate_multi_prime_key(RSA *rsa, int bits, int primes, #if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) int ossl_rsa_acvp_test_gen_params_new(OSSL_PARAM **dst, const OSSL_PARAM src[]); +int ossl_rsa_acvp_test_gen_params_new_parsed(OSSL_PARAM **dst, + const RSA_PARAMS *params); void ossl_rsa_acvp_test_gen_params_free(OSSL_PARAM *dst); int ossl_rsa_acvp_test_set_params(RSA *r, const OSSL_PARAM params[]); int ossl_rsa_acvp_test_get_params(RSA *r, OSSL_PARAM params[]); +int ossl_rsa_acvp_test_get_params_parsed(RSA *r, const RSA_PARAMS *params); typedef struct rsa_acvp_test_st RSA_ACVP_TEST; void ossl_rsa_acvp_test_free(RSA_ACVP_TEST *t); #else diff --git a/include/crypto/rsa_params.h.in b/include/crypto/rsa_params.h.in new file mode 100644 index 0000000000000..e7fcf95cc1c22 --- /dev/null +++ b/include/crypto/rsa_params.h.in @@ -0,0 +1,246 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_CRYPTO_RSA_PARAMS_H +#define OSSL_CRYPTO_RSA_PARAMS_H + +/* clang-format off */ + +{- +use OpenSSL::paramnames qw(produce_param_decoder); +-} + +#include "crypto/rsa.h" +#include +#include +#include + +{- +our @RSA_KEY_MP_TYPES = ( + ['OSSL_PKEY_PARAM_RSA_FACTOR1', 'mp.factors[0]', 'BN'], + ['OSSL_PKEY_PARAM_RSA_FACTOR2', 'mp.factors[1]', 'BN'], + ['OSSL_PKEY_PARAM_RSA_FACTOR3', 'mp.factors[2]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_FACTOR4', 'mp.factors[3]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_FACTOR5', 'mp.factors[4]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_FACTOR6', 'mp.factors[5]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_FACTOR7', 'mp.factors[6]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_FACTOR8', 'mp.factors[7]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_FACTOR9', 'mp.factors[8]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_FACTOR10', 'mp.factors[9]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_EXPONENT1', 'mp.exps[0]', 'BN'], + ['OSSL_PKEY_PARAM_RSA_EXPONENT2', 'mp.exps[1]', 'BN'], + ['OSSL_PKEY_PARAM_RSA_EXPONENT3', 'mp.exps[2]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_EXPONENT4', 'mp.exps[3]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_EXPONENT5', 'mp.exps[4]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_EXPONENT6', 'mp.exps[5]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_EXPONENT7', 'mp.exps[6]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_EXPONENT8', 'mp.exps[7]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_EXPONENT9', 'mp.exps[8]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_EXPONENT10', 'mp.exps[9]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_COEFFICIENT1', 'mp.coeffs[0]', 'BN'], + ['OSSL_PKEY_PARAM_RSA_COEFFICIENT2', 'mp.coeffs[1]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_COEFFICIENT3', 'mp.coeffs[2]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_COEFFICIENT4', 'mp.coeffs[3]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_COEFFICIENT5', 'mp.coeffs[4]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_COEFFICIENT6', 'mp.coeffs[5]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_COEFFICIENT7', 'mp.coeffs[6]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_COEFFICIENT8', 'mp.coeffs[7]', 'BN', '!fips'], + ['OSSL_PKEY_PARAM_RSA_COEFFICIENT9', 'mp.coeffs[8]', 'BN', '!fips'], +); + +our @RSA_KEY_TYPES = ( + ['OSSL_PKEY_PARAM_RSA_N', 'n', 'BN'], + ['OSSL_PKEY_PARAM_RSA_E', 'e', 'BN'], + ['OSSL_PKEY_PARAM_RSA_D', 'd', 'BN'], + @RSA_KEY_MP_TYPES +); + +our @RSA_PSS_IMPORT_TYPES = ( + ['OSSL_PKEY_PARAM_RSA_DIGEST', 'digest', 'utf8_string'], + ['OSSL_PKEY_PARAM_RSA_DIGEST_PROPS', 'digest_props', 'utf8_string'], + ['OSSL_PKEY_PARAM_RSA_MASKGENFUNC', 'maskgenfunc', 'utf8_string'], + ['OSSL_PKEY_PARAM_RSA_MGF1_DIGEST', 'mgf1_digest', 'utf8_string'], + ['OSSL_PKEY_PARAM_RSA_PSS_SALTLEN', 'pss_saltlen', 'int'], +); + +our @RSA_PSS_EXPORT_TYPES = ( + ['OSSL_PKEY_PARAM_RSA_DIGEST', 'digest', 'utf8_string'], + ['OSSL_PKEY_PARAM_RSA_MASKGENFUNC', 'maskgenfunc', 'utf8_string'], + ['OSSL_PKEY_PARAM_RSA_MGF1_DIGEST', 'mgf1_digest', 'utf8_string'], + ['OSSL_PKEY_PARAM_RSA_PSS_SALTLEN', 'pss_saltlen', 'int'], +); + +our @RSA_GEN_BASIC_TYPES = ( + ['OSSL_PKEY_PARAM_RSA_BITS', 'bits', 'size_t'], + ['OSSL_PKEY_PARAM_RSA_PRIMES', 'primes', 'size_t'], + ['OSSL_PKEY_PARAM_RSA_E', 'e', 'BN'], + ['OSSL_PKEY_PARAM_RSA_A', 'a', 'uint32'], + ['OSSL_PKEY_PARAM_RSA_B', 'b', 'uint32'], +); + +our @RSA_ACVP_INPUT_TYPES = ( + ['OSSL_PKEY_PARAM_RSA_TEST_XP', 'fips.xp', 'BN', 'fips'], + ['OSSL_PKEY_PARAM_RSA_TEST_XP1', 'fips.xp1', 'BN', 'fips'], + ['OSSL_PKEY_PARAM_RSA_TEST_XP2', 'fips.xp2', 'BN', 'fips'], + ['OSSL_PKEY_PARAM_RSA_TEST_XQ', 'fips.xq', 'BN', 'fips'], + ['OSSL_PKEY_PARAM_RSA_TEST_XQ1', 'fips.xq1', 'BN', 'fips'], + ['OSSL_PKEY_PARAM_RSA_TEST_XQ2', 'fips.xq2', 'BN', 'fips'], +); + +our @RSA_ACVP_OUTPUT_TYPES = ( + ['OSSL_PKEY_PARAM_RSA_TEST_P1', 'fips.p1', 'BN', 'fips'], + ['OSSL_PKEY_PARAM_RSA_TEST_P2', 'fips.p2', 'BN', 'fips'], + ['OSSL_PKEY_PARAM_RSA_TEST_Q1', 'fips.q1', 'BN', 'fips'], + ['OSSL_PKEY_PARAM_RSA_TEST_Q2', 'fips.q2', 'BN', 'fips'], +); + +return ""; +-} + +/* Key component parsing used by the public compatibility wrappers. */ +#define rsa_key_fromdata_st rsa_params_st +{- produce_param_decoder('rsa_key_fromdata', + (@RSA_KEY_TYPES, + ['OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ', 'derive', 'int'] + )); -} + +#define rsa_key_todata_st rsa_params_st +{- produce_param_decoder('rsa_key_todata', + (@RSA_KEY_TYPES, @RSA_ACVP_OUTPUT_TYPES)); -} + +#define rsa_pss_fromdata_st rsa_params_st +{- produce_param_decoder('rsa_pss_fromdata', @RSA_PSS_IMPORT_TYPES); -} + +#define rsa_pss_todata_st rsa_params_st +{- produce_param_decoder('rsa_pss_todata', @RSA_PSS_EXPORT_TYPES); -} + +/* + * Parameters processed by plain RSA get_params(), including conditional ACVP + * data. + */ +#define rsa_get_params_st rsa_params_st +{- produce_param_decoder('rsa_get_params', + (['OSSL_PKEY_PARAM_BITS', 'bits', 'int'], + ['OSSL_PKEY_PARAM_SECURITY_BITS', 'secbits', 'int'], + ['OSSL_PKEY_PARAM_MAX_SIZE', 'maxsize', 'int'], + ['OSSL_PKEY_PARAM_SECURITY_CATEGORY', 'seccat', 'int'], + ['OSSL_PKEY_PARAM_DEFAULT_DIGEST', 'default_digest', 'utf8_string'], + @RSA_KEY_TYPES, + @RSA_ACVP_OUTPUT_TYPES + )); -} + +/* Parameters processed by RSA-PSS get_params(). */ +#define rsapss_get_params_st rsa_params_st +{- produce_param_decoder('rsapss_get_params', + (['OSSL_PKEY_PARAM_BITS', 'bits', 'int'], + ['OSSL_PKEY_PARAM_SECURITY_BITS', 'secbits', 'int'], + ['OSSL_PKEY_PARAM_MAX_SIZE', 'maxsize', 'int'], + ['OSSL_PKEY_PARAM_SECURITY_CATEGORY', 'seccat', 'int'], + ['OSSL_PKEY_PARAM_DEFAULT_DIGEST', 'default_digest', 'utf8_string'], + ['OSSL_PKEY_PARAM_MANDATORY_DIGEST', 'mandatory_digest', 'utf8_string'], + @RSA_KEY_TYPES, + @RSA_PSS_EXPORT_TYPES, + @RSA_ACVP_OUTPUT_TYPES + )); -} + +/* Plain RSA generation parameters. */ +#define rsa_gen_set_params_st rsa_params_st +{- produce_param_decoder('rsa_gen_set_params', + (@RSA_GEN_BASIC_TYPES, + @RSA_ACVP_INPUT_TYPES + )); -} + +#define rsapss_gen_set_params_st rsa_params_st +{- produce_param_decoder('rsapss_gen_set_params', + (@RSA_GEN_BASIC_TYPES, + @RSA_PSS_IMPORT_TYPES, + @RSA_ACVP_INPUT_TYPES + )); -} + +/* Legacy EVP_PKEY import-from callbacks retain their existing signatures. */ +#define rsa_pkey_import_from_st rsa_params_st +{- produce_param_decoder('rsa_pkey_import_from', + (@RSA_KEY_TYPES, + ['OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ', 'derive', 'int'] + )); -} + +#define rsa_pss_pkey_import_from_st rsa_params_st +{- produce_param_decoder('rsa_pss_pkey_import_from', + (@RSA_KEY_TYPES, + ['OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ', 'derive', 'int'], + @RSA_PSS_IMPORT_TYPES + )); -} + +/* FIPS ACVP helpers also use the generated trie. */ +#define rsa_acvp_input_st rsa_params_st +{- produce_param_decoder('rsa_acvp_input', @RSA_ACVP_INPUT_TYPES); -} + +#define rsa_acvp_output_st rsa_params_st +{- produce_param_decoder('rsa_acvp_output', @RSA_ACVP_OUTPUT_TYPES); -} + +/* Selection-specific import and export declarations. */ +#define rsa_key_import_types_st rsa_params_st +{- produce_param_decoder('rsa_key_import_types', + (@RSA_KEY_TYPES, + ['OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ', 'derive', 'int'] + )); -} + +#define rsa_key_export_types_st +#define rsa_key_export_types_decoder +{- produce_param_decoder('rsa_key_export_types', @RSA_KEY_TYPES); -} + +#define rsa_other_import_types_st rsa_params_st +{- produce_param_decoder('rsa_other_import_types'); -} + +#define rsa_other_export_types_st +#define rsa_other_export_types_decoder +{- produce_param_decoder('rsa_other_export_types'); -} + +#define rsa_all_import_types_st rsa_params_st +{- produce_param_decoder('rsa_all_import_types', + (@RSA_KEY_TYPES, + ['OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ', 'derive', 'int'] + )); -} + +#define rsa_all_export_types_st +#define rsa_all_export_types_decoder +{- produce_param_decoder('rsa_all_export_types', @RSA_KEY_TYPES); -} + +#define rsapss_key_import_types_st rsa_params_st +{- produce_param_decoder('rsapss_key_import_types', + (@RSA_KEY_TYPES, + ['OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ', 'derive', 'int'] + )); -} + +#define rsapss_key_export_types_st +#define rsapss_key_export_types_decoder +{- produce_param_decoder('rsapss_key_export_types', @RSA_KEY_TYPES); -} + +#define rsapss_other_import_types_st rsa_params_st +{- produce_param_decoder('rsapss_other_import_types', @RSA_PSS_IMPORT_TYPES); -} + +#define rsapss_other_export_types_st +#define rsapss_other_export_types_decoder +{- produce_param_decoder('rsapss_other_export_types', @RSA_PSS_EXPORT_TYPES); -} + +#define rsapss_all_import_types_st rsa_params_st +{- produce_param_decoder('rsapss_all_import_types', + (@RSA_KEY_TYPES, + ['OSSL_PKEY_PARAM_RSA_DERIVE_FROM_PQ', 'derive', 'int'], + @RSA_PSS_IMPORT_TYPES + )); -} + +#define rsapss_all_export_types_st +#define rsapss_all_export_types_decoder +{- produce_param_decoder('rsapss_all_export_types', + (@RSA_KEY_TYPES, @RSA_PSS_EXPORT_TYPES)); -} + +/* clang-format on */ + +#endif diff --git a/include/crypto/rsaerr.h b/include/crypto/rsaerr.h deleted file mode 100644 index d295eef80d233..0000000000000 --- a/include/crypto/rsaerr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_RSAERR_H -#define OSSL_CRYPTO_RSAERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_RSA_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/security_bits.h b/include/crypto/security_bits.h index 8b42338a4dceb..1db3c904a28b5 100644 --- a/include/crypto/security_bits.h +++ b/include/crypto/security_bits.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/siphash.h b/include/crypto/siphash.h index cb2f6de68faba..fc6b7661f6d0e 100644 --- a/include/crypto/siphash.h +++ b/include/crypto/siphash.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/siv.h b/include/crypto/siv.h index d842baae49411..52d3fb8c9bc71 100644 --- a/include/crypto/siv.h +++ b/include/crypto/siv.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/sm2err.h b/include/crypto/sm2err.h deleted file mode 100644 index 3dc4f7d93a100..0000000000000 --- a/include/crypto/sm2err.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_SM2ERR_H -#define OSSL_CRYPTO_SM2ERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef OPENSSL_NO_SM2 - -int ossl_err_load_SM2_strings(void); - -/* - * SM2 reason codes. - */ -#define SM2_R_ASN1_ERROR 100 -#define SM2_R_BAD_SIGNATURE 101 -#define SM2_R_BUFFER_TOO_SMALL 107 -#define SM2_R_DIST_ID_TOO_LARGE 110 -#define SM2_R_ID_NOT_SET 112 -#define SM2_R_ID_TOO_LARGE 111 -#define SM2_R_INVALID_CURVE 108 -#define SM2_R_INVALID_DIGEST 102 -#define SM2_R_INVALID_DIGEST_TYPE 103 -#define SM2_R_INVALID_ENCODING 104 -#define SM2_R_INVALID_FIELD 105 -#define SM2_R_INVALID_PRIVATE_KEY 113 -#define SM2_R_NO_PARAMETERS_SET 109 -#define SM2_R_USER_ID_TOO_LARGE 106 - -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/sm4_platform.h b/include/crypto/sm4_platform.h index 48c9ff93cf691..74b3a701f9252 100644 --- a/include/crypto/sm4_platform.h +++ b/include/crypto/sm4_platform.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/crypto/sparse_array.h b/include/crypto/sparse_array.h index d77a46ebfa89f..e8de36a1f097e 100644 --- a/include/crypto/sparse_array.h +++ b/include/crypto/sparse_array.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -20,74 +20,74 @@ extern "C" { #define SPARSE_ARRAY_OF(type) struct sparse_array_st_##type -#define DEFINE_SPARSE_ARRAY_OF_INTERNAL(type, ctype) \ - SPARSE_ARRAY_OF(type); \ - typedef void (*sa_##type##_leaffunc)(ossl_uintmax_t idx, type *t); \ - typedef void (*sa_##type##_leaffunc_arg)(ossl_uintmax_t idx, type *t, void *arg); \ - static ossl_unused ossl_inline SPARSE_ARRAY_OF(type) * ossl_sa_##type##_new(void) \ - { \ - return (SPARSE_ARRAY_OF(type) *)ossl_sa_new(); \ - } \ - static ossl_unused ossl_inline void \ - ossl_sa_##type##_free(SPARSE_ARRAY_OF(type) * sa) \ - { \ - ossl_sa_free((OPENSSL_SA *)sa); \ - } \ - static ossl_unused ossl_inline void \ - ossl_sa_##type##_free_leaves(SPARSE_ARRAY_OF(type) * sa) \ - { \ - ossl_sa_free_leaves((OPENSSL_SA *)sa); \ - } \ - static ossl_unused ossl_inline size_t \ - ossl_sa_##type##_num(const SPARSE_ARRAY_OF(type) * sa) \ - { \ - return ossl_sa_num((OPENSSL_SA *)sa); \ - } \ - static ossl_unused void \ - ossl_sa_##type##_doall_thunk(ossl_uintmax_t idx, void *leaf, void *arg) \ - { \ - sa_##type##_leaffunc fn = *(sa_##type##_leaffunc *)arg; \ - (*fn)(idx, (type *)leaf); \ - } \ - static ossl_unused ossl_inline void \ - ossl_sa_##type##_doall(const SPARSE_ARRAY_OF(type) * sa, \ - void (*leaf)(ossl_uintmax_t, type *)) \ - { \ - ossl_sa_doall_arg((OPENSSL_SA *)sa, ossl_sa_##type##_doall_thunk, &leaf); \ - } \ - struct ossl_sa_##type##_doall_thunk { \ - sa_##type##_leaffunc_arg fn; \ - void *arg; \ - }; \ - static ossl_unused void \ - ossl_sa_##type##_doall_arg_thunk(ossl_uintmax_t idx, void *leaf, void *arg) \ - { \ - struct ossl_sa_##type##_doall_thunk *t = arg; \ - \ - (*t->fn)(idx, (type *)leaf, t->arg); \ - } \ - static ossl_unused ossl_inline void \ - ossl_sa_##type##_doall_arg(const SPARSE_ARRAY_OF(type) * sa, \ - void (*leaf)(ossl_uintmax_t, type *, void *), \ - void *arg) \ - { \ - struct ossl_sa_##type##_doall_thunk t; \ - \ - t.fn = leaf; \ - t.arg = arg; \ - ossl_sa_doall_arg((OPENSSL_SA *)sa, \ - ossl_sa_##type##_doall_arg_thunk, &t); \ - } \ - static ossl_unused ossl_inline ctype *ossl_sa_##type##_get(const SPARSE_ARRAY_OF(type) * sa, ossl_uintmax_t n) \ - { \ - return (type *)ossl_sa_get((OPENSSL_SA *)sa, n); \ - } \ - static ossl_unused ossl_inline int \ - ossl_sa_##type##_set(SPARSE_ARRAY_OF(type) * sa, \ - ossl_uintmax_t n, ctype *val) \ - { \ - return ossl_sa_set((OPENSSL_SA *)sa, n, (void *)val); \ - } \ +#define DEFINE_SPARSE_ARRAY_OF_INTERNAL(type, ctype) \ + SPARSE_ARRAY_OF(type); \ + typedef void (*sa_##type##_leaffunc)(ossl_uintmax_t idx, type *t); \ + typedef void (*sa_##type##_leaffunc_arg)(ossl_uintmax_t idx, type *t, void *arg); \ + static ossl_unused ossl_inline SPARSE_ARRAY_OF(type) *ossl_sa_##type##_new(void) \ + { \ + return (SPARSE_ARRAY_OF(type) *)ossl_sa_new(); \ + } \ + static ossl_unused ossl_inline void \ + ossl_sa_##type##_free(SPARSE_ARRAY_OF(type) *sa) \ + { \ + ossl_sa_free((OPENSSL_SA *)sa); \ + } \ + static ossl_unused ossl_inline void \ + ossl_sa_##type##_free_leaves(SPARSE_ARRAY_OF(type) *sa) \ + { \ + ossl_sa_free_leaves((OPENSSL_SA *)sa); \ + } \ + static ossl_unused ossl_inline size_t \ + ossl_sa_##type##_num(const SPARSE_ARRAY_OF(type) *sa) \ + { \ + return ossl_sa_num((OPENSSL_SA *)sa); \ + } \ + static ossl_unused void \ + ossl_sa_##type##_doall_thunk(ossl_uintmax_t idx, void *leaf, void *arg) \ + { \ + sa_##type##_leaffunc fn = *(sa_##type##_leaffunc *)arg; \ + (*fn)(idx, (type *)leaf); \ + } \ + static ossl_unused ossl_inline void \ + ossl_sa_##type##_doall(const SPARSE_ARRAY_OF(type) *sa, \ + void (*leaf)(ossl_uintmax_t, type *)) \ + { \ + ossl_sa_doall_arg((OPENSSL_SA *)sa, ossl_sa_##type##_doall_thunk, &leaf); \ + } \ + struct ossl_sa_##type##_doall_thunk { \ + sa_##type##_leaffunc_arg fn; \ + void *arg; \ + }; \ + static ossl_unused void \ + ossl_sa_##type##_doall_arg_thunk(ossl_uintmax_t idx, void *leaf, void *arg) \ + { \ + struct ossl_sa_##type##_doall_thunk *t = arg; \ + \ + (*t->fn)(idx, (type *)leaf, t->arg); \ + } \ + static ossl_unused ossl_inline void \ + ossl_sa_##type##_doall_arg(const SPARSE_ARRAY_OF(type) *sa, \ + void (*leaf)(ossl_uintmax_t, type *, void *), \ + void *arg) \ + { \ + struct ossl_sa_##type##_doall_thunk t; \ + \ + t.fn = leaf; \ + t.arg = arg; \ + ossl_sa_doall_arg((OPENSSL_SA *)sa, \ + ossl_sa_##type##_doall_arg_thunk, &t); \ + } \ + static ossl_unused ossl_inline ctype *ossl_sa_##type##_get(const SPARSE_ARRAY_OF(type) *sa, ossl_uintmax_t n) \ + { \ + return (type *)ossl_sa_get((OPENSSL_SA *)sa, n); \ + } \ + static ossl_unused ossl_inline int \ + ossl_sa_##type##_set(SPARSE_ARRAY_OF(type) *sa, \ + ossl_uintmax_t n, ctype *val) \ + { \ + return ossl_sa_set((OPENSSL_SA *)sa, n, (void *)val); \ + } \ SPARSE_ARRAY_OF(type) #define DEFINE_SPARSE_ARRAY_OF(type) \ diff --git a/include/crypto/storeerr.h b/include/crypto/storeerr.h deleted file mode 100644 index 33bed4cc24b86..0000000000000 --- a/include/crypto/storeerr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_STOREERR_H -#define OSSL_CRYPTO_STOREERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_OSSL_STORE_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/tserr.h b/include/crypto/tserr.h deleted file mode 100644 index 31c9da41f3d68..0000000000000 --- a/include/crypto/tserr.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_TSERR_H -#define OSSL_CRYPTO_TSERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef OPENSSL_NO_TS - -int ossl_err_load_TS_strings(void); -#endif - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/uierr.h b/include/crypto/uierr.h deleted file mode 100644 index dbd149679135e..0000000000000 --- a/include/crypto/uierr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_UIERR_H -#define OSSL_CRYPTO_UIERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_UI_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/x509.h b/include/crypto/x509.h index 49251311800f8..e89f2fed508bd 100644 --- a/include/crypto/x509.h +++ b/include/crypto/x509.h @@ -19,6 +19,19 @@ #include "crypto/types.h" #include +#include + +/* + * Size in bytes of the internal X509 / X509_CRL fingerprint, see + * ossl_x509_internal_fingerprint(). The fingerprint only short-circuits + * X509_cmp() and X509_CRL_match(), which compare the encodings on a match, + * so a collision costs one extra memcmp. With 64 bits a collision among + * n objects has probability about n^2 / 2^65: one in 10^12 for 10,000 + * certificates, and even odds only at around 2^32 of them. The SipHash key + * is fixed, so an attacker can craft certificates that collide, but gains + * only that memcmp per colliding pair on certificates they had to supply. + */ +#define OSSL_X509_FINGERPRINT_SIZE SIPHASH_MIN_DIGEST_SIZE /* Internal X509 structures and functions: not for application use */ @@ -119,8 +132,12 @@ struct X509_crl_st { ASN1_INTEGER *crl_number; ASN1_INTEGER *base_crl_number; STACK_OF(GENERAL_NAMES) *issuers; - /* hash of CRL */ - unsigned char sha1_hash[SHA_DIGEST_LENGTH]; + /* + * Internal-use fingerprint for X509_CRL_match(), see + * ossl_x509_internal_fingerprint(). Not cryptographically secure and + * not collision free: a match is confirmed by comparing the CRLs. + */ + unsigned char fingerprint[OSSL_X509_FINGERPRINT_SIZE]; /* alternative method to handle this CRL */ const X509_CRL_METHOD *meth; void *meth_data; @@ -178,7 +195,6 @@ struct x509_st { X509_CINF cert_info; X509_ALGOR sig_alg; ASN1_BIT_STRING signature; - X509_SIG_INFO siginf; CRYPTO_REF_COUNT references; CRYPTO_EX_DATA ex_data; /* These contain copies of various extension values */ @@ -198,7 +214,12 @@ struct x509_st { STACK_OF(IPAddressFamily) *rfc3779_addr; struct ASIdentifiers_st *rfc3779_asid; #endif - unsigned char sha1_hash[SHA_DIGEST_LENGTH]; + /* + * Internal-use fingerprint for X509_cmp(), see + * ossl_x509_internal_fingerprint(). Not cryptographically secure and + * not collision free: a match is confirmed by comparing the certificates. + */ + unsigned char fingerprint[OSSL_X509_FINGERPRINT_SIZE]; X509_CERT_AUX *aux; CRYPTO_RWLOCK *lock; volatile int ex_cached; @@ -317,7 +338,30 @@ int ossl_a2i_ipadd(unsigned char *ipout, const char *ipasc); int ossl_x509_set1_time(int *modified, ASN1_TIME **ptm, const ASN1_TIME *tm); int ossl_x509_print_ex_brief(BIO *bio, const X509 *cert, unsigned long neg_cflags); int ossl_x509v3_cache_extensions(const X509 *x); -int ossl_x509_init_sig_info(const X509 *x, X509_SIG_INFO *info); + +/** + * @brief Compute the internal-use fingerprint of a DER-encodable object. + * + * The fingerprint is cached in X509 / X509_CRL fingerprint and used only for + * internal identity comparison (X509_cmp(), X509_CRL_match()); it is never + * returned to callers, so the algorithm is an implementation detail + * (currently SipHash-2-4 with a fixed key and 64-bit output; a collision + * only costs the callers a fall through to their encoding comparison). + * Callers hash the whole signed object (X509, X509_CRL). No algorithm + * is fetched, so the result depends on neither the library context nor the + * property query string of the object and stays valid if the object is + * moved to another library context. It fails only if the object cannot be + * DER encoded, for instance a certificate still under construction, or on + * an allocation failure in the encoder. + * + * @param it the ASN1_ITEM describing @p val + * @param val the object to encode and hash + * @param hash output buffer for the fingerprint, OSSL_X509_FINGERPRINT_SIZE + * bytes + * @returns 1 on success, 0 on failure + */ +int ossl_x509_internal_fingerprint(const ASN1_ITEM *it, const void *val, + unsigned char *hash); int ossl_x509_set0_libctx(X509 *x, OSSL_LIB_CTX *libctx, const char *propq); int ossl_x509_crl_set0_libctx(X509_CRL *x, OSSL_LIB_CTX *libctx, diff --git a/include/crypto/x509err.h b/include/crypto/x509err.h deleted file mode 100644 index 45e62fa7da883..0000000000000 --- a/include/crypto/x509err.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_X509ERR_H -#define OSSL_CRYPTO_X509ERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_X509_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/crypto/x509v3err.h b/include/crypto/x509v3err.h deleted file mode 100644 index b3874fc472153..0000000000000 --- a/include/crypto/x509v3err.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_CRYPTO_X509V3ERR_H -#define OSSL_CRYPTO_X509V3ERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_X509V3_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/internal/bio.h b/include/internal/bio.h index 91a27b22185aa..bec4242b2618d 100644 --- a/include/internal/bio.h +++ b/include/internal/bio.h @@ -107,8 +107,4 @@ int ossl_core_bio_vprintf(OSSL_CORE_BIO *cb, const char *format, va_list args); int ossl_bio_init_core(OSSL_LIB_CTX *libctx, const OSSL_DISPATCH *fns); -#ifdef _MSC_VER -int ossl_BIO_snprintf_msvc(char *buf, size_t n, const char *fmt, ...); -#endif - #endif diff --git a/include/internal/bio_tfo.h b/include/internal/bio_tfo.h index 68b85b0ecc634..b9c8e8c677cbc 100644 --- a/include/internal/bio_tfo.h +++ b/include/internal/bio_tfo.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/common.h b/include/internal/common.h index 6e72a7ececa2c..6834b595a58eb 100644 --- a/include/internal/common.h +++ b/include/internal/common.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -13,6 +13,7 @@ #include #include +#include "crypto/ctype.h" #include "openssl/configuration.h" #include "internal/e_os.h" /* ossl_inline in many files */ @@ -69,6 +70,13 @@ __owur static ossl_inline int ossl_assert_int(int expr, const char *exprstr, (HAS_CASE_PREFIX(str, pre) ? ((str) += sizeof(pre) - 1, 1) : 0) /* Check if the string literal |suffix| is a case-insensitive suffix of |str| */ #define HAS_CASE_SUFFIX(str, suffix) (strlen(str) < sizeof(suffix) - 1 ? 0 : OPENSSL_strcasecmp(str + strlen(str) - sizeof(suffix) + 1, suffix "") == 0) +/* Advance string pointer past scheme acc to RFC 3986: ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) */ +#define OSSL_SKIP_SCHEME(s) \ + do { \ + if (ossl_isalpha(*(s))) \ + while (*(s) != '\0' && (ossl_isalnum(*(s)) || strchr("+-.", *(s)) != NULL)) \ + (s)++; \ + } while (0) /* * Use this inside a union with the field that needs to be aligned to a @@ -277,6 +285,10 @@ __owur static ossl_inline int ossl_assert_int(int expr, const char *exprstr, (c)[2] = (unsigned char)(((l)) & 0xff)), \ (c) += 3) +#define l3n2(c, l) (l = ((uint64_t)(*((c)++))) << 16, \ + l |= ((uint64_t)(*((c)++))) << 8, \ + l |= ((uint64_t)(*((c)++)))) + static ossl_inline int ossl_ends_with_dirsep(const char *path) { if (*path != '\0') diff --git a/include/internal/conf.h b/include/internal/conf.h index bf0ca15f744eb..c917ed9c6bb20 100644 --- a/include/internal/conf.h +++ b/include/internal/conf.h @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -62,5 +62,6 @@ struct conf_imodule_st { int ossl_config_int(const OPENSSL_INIT_SETTINGS *); void ossl_no_config_int(void); void ossl_config_modules_free(void); +int ossl_conf_parse_bool(const char *value, int *result); #endif diff --git a/include/internal/constant_time.h b/include/internal/constant_time.h index ddb15d7b6f689..168b3e8880f51 100644 --- a/include/internal/constant_time.h +++ b/include/internal/constant_time.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/core.h b/include/internal/core.h index 33a16395e268f..ad49160c546f2 100644 --- a/include/internal/core.h +++ b/include/internal/core.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h index 0dcc6b6acd3fe..1a367b3238bdd 100644 --- a/include/internal/cryptlib.h +++ b/include/internal/cryptlib.h @@ -154,6 +154,21 @@ const void *ossl_bsearch(const void *key, const void *base, int num, int (*cmp_thunk)(int (*real_cmp_fn)(const void *, const void *), const void *, const void *), int flags); +/** + * @brief Join a stack of ASN1_UTF8STRINGs into one allocated string. + * + * Concatenates the elements of text, separated by sep, into a newly allocated + * NUL terminated string. The element data is copied in full and may itself + * contain embedded NUL bytes, so a caller that treats the result as a C string + * will see it truncated at the first such byte. + * + * @param text the stack of ASN1_UTF8STRINGs to join + * @param sep separator placed between elements, or NULL for none + * @param max_len maximum length of the result, excluding the NUL terminator, + * or 0 for no restriction + * @returns a newly allocated string to be freed with OPENSSL_free(), or NULL on + * error or if the result would exceed max_len + */ char *ossl_sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text, const char *sep, size_t max_len); char *ossl_ipaddr_to_asc(const unsigned char *p, int len); @@ -162,6 +177,19 @@ char *ossl_buf2hexstr_sep(const unsigned char *buf, long buflen, char sep); unsigned char *ossl_hexstr2buf_sep(const char *str, long *buflen, const char sep); +/* + * Parse a signed long with validation; see OPENSSL_strtoul() for the rules. + * Returns 1 on success (and stores the result in |*result|), 0 on failure. + */ +int ossl_strtol(const char *str, char **endptr, int base, long *result); + +/* + * As ossl_strtol() but stores the result in an int, additionally failing if + * the parsed value does not fit in an int. + * Returns 1 on success (and stores the result in |*result|), 0 on failure. + */ +int ossl_strtoint(const char *str, char **endptr, int base, int *result); + /** * Writes |n| value in hex format into |buf|, * and returns the number of bytes written diff --git a/include/internal/dane.h b/include/internal/dane.h index 8df761facfbce..cd3b17a6652db 100644 --- a/include/internal/dane.h +++ b/include/internal/dane.h @@ -1,5 +1,5 @@ /* - * Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/dgram_conn_lookup.h b/include/internal/dgram_conn_lookup.h new file mode 100644 index 0000000000000..5bd69c08886c3 --- /dev/null +++ b/include/internal/dgram_conn_lookup.h @@ -0,0 +1,77 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_DGRAM_CONN_LOOKUP_H +#define OSSL_INTERNAL_DGRAM_CONN_LOOKUP_H +#pragma once + +#include +#include "internal/dgram_demux.h" + +#ifndef OPENSSL_NO_DTLS + +/* + * DGRAM_CONN_LOOKUP - Address-based connection lookup for DTLS + * ============================================================= + * + * This provides connection lookup by peer address (IP:port) for DTLS. + * QUIC uses its own QUIC_LCIDM for CID-based lookup and does not use + * this interface. + * + * The lookup uses the peer address from the DGRAM_URXE to find the + * associated connection. + */ + +/* Forward declarations */ +typedef struct dgram_conn_lookup_st DGRAM_CONN_LOOKUP; +typedef struct dgram_conn_lookup_methods_st DGRAM_CONN_LOOKUP_METHODS; + +/* Callback type for iterating over connections */ +typedef void (*ossl_dgram_conn_lookup_iter_fn)(SSL *ssl, const BIO_ADDR *peer, + void *arg); + +struct dgram_conn_lookup_methods_st { + SSL *(*lookup)(DGRAM_CONN_LOOKUP *lookup, const DGRAM_URXE *e); + int (*register_conn)(DGRAM_CONN_LOOKUP *lookup, const DGRAM_URXE *e, SSL *ssl); + int (*register_conn_addr)(DGRAM_CONN_LOOKUP *lookup, const BIO_ADDR *peer, SSL *ssl); + int (*unregister_conn)(DGRAM_CONN_LOOKUP *lookup, const BIO_ADDR *peer); + void (*foreach)(DGRAM_CONN_LOOKUP *lookup, ossl_dgram_conn_lookup_iter_fn cb, + void *arg); + void (*free)(DGRAM_CONN_LOOKUP *lookup); + size_t (*num_items)(const DGRAM_CONN_LOOKUP *lookup); +}; + +struct dgram_conn_lookup_st { + const DGRAM_CONN_LOOKUP_METHODS *methods; + void *impl_data; +}; + +/* Factory function for address-based lookup (DTLS) */ +DGRAM_CONN_LOOKUP *ossl_dgram_conn_lookup_new_addr(void); + +/* + * Public API - calls through methods table. + */ +SSL *ossl_dgram_conn_lookup_find(DGRAM_CONN_LOOKUP *lookup, + const DGRAM_URXE *e); +int ossl_dgram_conn_lookup_register(DGRAM_CONN_LOOKUP *lookup, + const DGRAM_URXE *e, SSL *ssl); +int ossl_dgram_conn_lookup_register_addr(DGRAM_CONN_LOOKUP *lookup, + const BIO_ADDR *peer, + SSL *ssl); +int ossl_dgram_conn_lookup_unregister(DGRAM_CONN_LOOKUP *lookup, + const BIO_ADDR *peer); +void ossl_dgram_conn_lookup_foreach(DGRAM_CONN_LOOKUP *lookup, + ossl_dgram_conn_lookup_iter_fn cb, + void *arg); +void ossl_dgram_conn_lookup_free(DGRAM_CONN_LOOKUP *lookup); +size_t ossl_dgram_conn_lookup_num_items(const DGRAM_CONN_LOOKUP *lookup); + +#endif /* OPENSSL_NO_DTLS */ +#endif /* OSSL_INTERNAL_DGRAM_CONN_LOOKUP_H */ diff --git a/include/internal/dgram_demux.h b/include/internal/dgram_demux.h new file mode 100644 index 0000000000000..9b91b8be5c5f3 --- /dev/null +++ b/include/internal/dgram_demux.h @@ -0,0 +1,262 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_DGRAM_DEMUX_H +#define OSSL_DGRAM_DEMUX_H +#pragma once + +#include +#include "internal/bio_addr.h" +#include "internal/time.h" +#include "internal/list.h" + +#if !defined(OPENSSL_NO_QUIC) || !defined(OPENSSL_NO_DTLS) + +/* + * Generic Datagram Demuxer + * ======================== + * + * The datagram demuxer is responsible for receiving datagrams from the network + * via a datagram BIO. It maintains a pool of Unprocessed RX Entries (URXEs) + * for efficient batch receiving via BIO_recvmmsg(). + * + * The demuxer is protocol-agnostic. It receives datagrams and invokes a + * callback for each one. The callback is responsible for routing the datagram + * to the appropriate connection (e.g., by DCID for QUIC, or by peer address + * for DTLS). + */ + +/* Forward declarations */ +typedef struct dgram_demux_st DGRAM_DEMUX; +typedef struct dgram_urxe_st DGRAM_URXE; + +/* + * URXE (Unprocessed RX Entry) structure. + * + * This structure is exposed so that callers can manage URXEs in their own + * queues when needed. The data buffer follows immediately after this structure. + * + * This structure includes fields used by QUIC (processed, hpr_removed, deferred) + * which are unused by DTLS. This allows QUIC_URXE to be a simple typedef to + * DGRAM_URXE, enabling QUIC_DEMUX to wrap DGRAM_DEMUX without list type issues. + */ +struct dgram_urxe_st { + OSSL_LIST_MEMBER(urxe, DGRAM_URXE); + + /* + * The URXE data starts after this structure so we don't need a pointer. + * data_len stores the current length (i.e., the length of the received + * datagram) and alloc_len stores the allocation length. The URXE will be + * reallocated if we need a larger allocation than is available, though this + * should not be common as we will have a good idea of worst-case MTUs up + * front. + */ + size_t data_len, alloc_len; + + /* + * Bitfields per packet. processed indicates the packet has been processed + * and must not be processed again, hpr_removed indicates header protection + * has already been removed. Used by QUIC QRX only; not used by the demuxer + * or DTLS. + */ + uint64_t processed, hpr_removed; + + /* + * This monotonically increases with each datagram received. It is used for + * diagnostic purposes only. + */ + uint64_t datagram_id; + + /* + * Address of peer we received the datagram from, and the local interface + * address we received it on. If local address support is not enabled, local + * is zeroed. + */ + BIO_ADDR peer, local; + + /* + * Time at which datagram was received (or ossl_time_zero()) if a now + * function was not provided). + */ + OSSL_TIME time; + + /* + * Used by the QUIC QRX to mark whether a datagram has been deferred. + * Not used by the demuxer or DTLS. + */ + char deferred; + + /* + * Used by the DEMUX to track if a URXE has been handed out. Used primarily + * for debugging purposes. + */ + char demux_state; +}; + +/* Values for demux_state field */ +#define URXE_DEMUX_STATE_FREE 0 /* on urx_free list */ +#define URXE_DEMUX_STATE_PENDING 1 /* on urx_pending list */ +#define URXE_DEMUX_STATE_ISSUED 2 /* on neither list */ + +/* List structure tracking a queue of URXEs. */ +DEFINE_LIST_OF(urxe, DGRAM_URXE); +typedef OSSL_LIST(urxe) DGRAM_URXE_LIST; + +/* + * List management helpers. These are used by the demuxer but can also be used + * by users of the demuxer to manage URXEs. + */ +void ossl_dgram_urxe_remove(DGRAM_URXE_LIST *l, DGRAM_URXE *e); +void ossl_dgram_urxe_insert_head(DGRAM_URXE_LIST *l, DGRAM_URXE *e); +void ossl_dgram_urxe_insert_tail(DGRAM_URXE_LIST *l, DGRAM_URXE *e); + +/* + * Callback function type for datagram routing. + * + * Called when a datagram is received. e is a URXE containing the datagram + * payload. It is permissible for the callee to mutate this buffer; once the + * demuxer calls this callback, it will never read the buffer again. + * + * The callee must arrange for ossl_dgram_demux_release_urxe or + * ossl_dgram_demux_reinject_urxe to be called on the URXE at some point in the + * future (this need not be before the callback returns). + * + * At the time the callback is made, the URXE will not be in any queue, + * therefore the callee can use the prev and next fields as it wishes. + */ +typedef void(ossl_dgram_demux_cb_fn)(DGRAM_URXE *e, void *arg); + +/* + * Creates a new demuxer. The given BIO is used to receive datagrams from the + * network using BIO_recvmmsg. + * + * threadsafe: If non-zero, enables internal locking for thread safety. Use this + * when the demux may be accessed from multiple threads (DTLS + * where connections share a demux). Pass 0 if thread safety is + * handled at a higher level (QUIC). + * + * now is an optional function used to determine the time a datagram was + * received. now_arg is an opaque argument passed to the function. If now is + * NULL, ossl_time_zero() is used as the datagram reception time. + */ +DGRAM_DEMUX *ossl_dgram_demux_new(BIO *net_bio, + int threadsafe, + OSSL_TIME (*now)(void *arg), + void *now_arg); + +/* + * Destroy a demuxer. All URXEs must have been released back to the demuxer + * before calling this. No-op if demux is NULL. + */ +void ossl_dgram_demux_free(DGRAM_DEMUX *demux); + +/* + * Changes the BIO which the demuxer reads from. This also sets the MTU if the + * BIO supports querying the MTU. + */ +void ossl_dgram_demux_set_bio(DGRAM_DEMUX *demux, BIO *net_bio); + +/* + * Changes the MTU in bytes we use to receive datagrams. + * Returns 1 on success, 0 if mtu is below minimum. + */ +int ossl_dgram_demux_set_mtu(DGRAM_DEMUX *demux, unsigned int mtu); + +/* + * Set the default packet handler. This is called for every incoming datagram. + * If a default packet handler is not set, received datagrams are silently + * dropped. A default packet handler may be unset by passing NULL. + * + * The handler is responsible for ensuring that ossl_dgram_demux_reinject_urxe + * or ossl_dgram_demux_release_urxe is called on the passed packet at some + * point in the future, which may or may not be before the handler returns. + */ +void ossl_dgram_demux_set_default_handler(DGRAM_DEMUX *demux, + ossl_dgram_demux_cb_fn *cb, + void *cb_arg); + +/* + * Releases a URXE back to the demuxer. No reference must be made to the URXE or + * its buffer after calling this function. The URXE must not be in any queue; + * that is, its prev and next pointers must be NULL. + */ +void ossl_dgram_demux_release_urxe(DGRAM_DEMUX *demux, DGRAM_URXE *e); + +/* + * Reinjects a URXE back into the pending queue. This is useful when a packet + * needs to be reprocessed. Once this has been called, the caller must not + * touch the URXE anymore and must not also call ossl_dgram_demux_release_urxe(). + * + * The URXE is reinjected at the head of the queue, so it will be reprocessed + * immediately. + */ +void ossl_dgram_demux_reinject_urxe(DGRAM_DEMUX *demux, DGRAM_URXE *e); + +/* + * Process any unprocessed RX'd datagrams, by calling registered callbacks, + * reading more datagrams from the BIO if necessary. + * + * Returns one of the following values: + * + * DGRAM_DEMUX_PUMP_RES_OK + * At least one incoming datagram was processed. + * + * DGRAM_DEMUX_PUMP_RES_TRANSIENT_FAIL + * No more incoming datagrams are currently available. + * Call again later. + * + * DGRAM_DEMUX_PUMP_RES_PERMANENT_FAIL + * Either the network read BIO has failed in a non-transient fashion, or + * an internal state, assertion or allocation error occurred. The caller + * should tear down the connection. + */ +#define DGRAM_DEMUX_PUMP_RES_OK 1 +#define DGRAM_DEMUX_PUMP_RES_TRANSIENT_FAIL (-1) +#define DGRAM_DEMUX_PUMP_RES_PERMANENT_FAIL (-2) + +int ossl_dgram_demux_pump(DGRAM_DEMUX *demux); + +/* + * Artificially inject a packet into the demuxer for testing purposes. The + * buffer must not exceed the URXE size being used by the demuxer. + * + * If peer or local are NULL, their respective fields are zeroed in the injected + * URXE. + * + * Returns 1 on success or 0 on failure. + */ +int ossl_dgram_demux_inject(DGRAM_DEMUX *demux, + const unsigned char *buf, + size_t buf_len, + const BIO_ADDR *peer, + const BIO_ADDR *local); + +/* + * Returns 1 if there are any pending URXEs. + */ +int ossl_dgram_demux_has_pending(const DGRAM_DEMUX *demux); + +/* + * Accessor for URXE data buffer. This returns a pointer to the data buffer + * that follows the URXE structure. + */ +static ossl_unused ossl_inline unsigned char * +ossl_dgram_urxe_data(const DGRAM_URXE *e) +{ + return (unsigned char *)&e[1]; +} + +static ossl_unused ossl_inline unsigned char * +ossl_dgram_urxe_data_end(const DGRAM_URXE *e) +{ + return ossl_dgram_urxe_data(e) + e->data_len; +} + +#endif /* !OPENSSL_NO_QUIC || !OPENSSL_NO_DTLS */ +#endif /* OSSL_DGRAM_DEMUX_H */ diff --git a/include/internal/dsoerr.h b/include/internal/dsoerr.h deleted file mode 100644 index 3b1de62fccc4a..0000000000000 --- a/include/internal/dsoerr.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_INTERNAL_DSOERR_H -#define OSSL_INTERNAL_DSOERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_DSO_strings(void); - -/* - * DSO reason codes. - */ -#define DSO_R_CTRL_FAILED 100 -#define DSO_R_DSO_ALREADY_LOADED 110 -#define DSO_R_EMPTY_FILE_STRUCTURE 113 -#define DSO_R_FAILURE 114 -#define DSO_R_FILENAME_TOO_BIG 101 -#define DSO_R_FINISH_FAILED 102 -#define DSO_R_INCORRECT_FILE_SYNTAX 115 -#define DSO_R_LOAD_FAILED 103 -#define DSO_R_NAME_TRANSLATION_FAILED 109 -#define DSO_R_NO_FILENAME 111 -#define DSO_R_NULL_HANDLE 104 -#define DSO_R_SET_FILENAME_FAILED 112 -#define DSO_R_STACK_ERROR 105 -#define DSO_R_SYM_FAILURE 106 -#define DSO_R_UNLOAD_FAILED 107 -#define DSO_R_UNSUPPORTED 108 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/internal/dtls_record_rx.h b/include/internal/dtls_record_rx.h new file mode 100644 index 0000000000000..44099b2477f09 --- /dev/null +++ b/include/internal/dtls_record_rx.h @@ -0,0 +1,53 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_DTLS_RECORD_RX_H +#define OSSL_DTLS_RECORD_RX_H +#pragma once + +#include "internal/dgram_demux.h" +#include "internal/thread_arch.h" + +#ifndef OPENSSL_NO_DTLS + +typedef struct dtls_rx_st { + DGRAM_DEMUX *demux; + DGRAM_URXE_LIST urxe_pending; + CRYPTO_MUTEX *mutex; +} DTLS_RX; + +/* + * Creates a new DTLS_RX structe. The demuxer is + * provided and owned by the DTLS listener. + */ +DTLS_RX *ossl_dtls_rx_new(DGRAM_DEMUX *demux); + +/* + * Frees a DTLS_RX struct. The demuxer is not freed, as it is + * owned by the DTLS listener. The list is walked and freed. + */ +void ossl_dtls_rx_free(DTLS_RX *rx); + +/* + * Injects a received URXE into the DTLS_RX struct. + */ +void ossl_dtls_rx_inject_urxe(DTLS_RX *rx, DGRAM_URXE *e); + +/* + * Release the URXE from the DTLS_RX struct. + */ +void ossl_dtls_rx_release_urxe(DTLS_RX *rx, DGRAM_URXE *e); + +/* + * Reads a datagram from the DTLS_RX struct. + */ +DGRAM_URXE *ossl_dtls_read_datagram(DTLS_RX *rx); + +#endif /* OPENSSL_NO_DTLS */ +#endif /* OSSL_DTLS_RECORD_RX_H */ diff --git a/include/internal/e_os.h b/include/internal/e_os.h index 444f888674bfb..4fb1840f618db 100644 --- a/include/internal/e_os.h +++ b/include/internal/e_os.h @@ -152,6 +152,20 @@ FILE *__iob_func(void); #define check_win_minplat(x) (LOBYTE(LOWORD(GetVersion())) >= (x)) #endif +/* + * MSVC versions earlier than Visual Studio 2015 (_MSC_VER < 1900) do not + * declare or define C99 snprintf or vsnprintf. Definitions are supplied + * by crypto/msvc2013_snprintf.c, which is built only on the matching + * Configure target variants. + */ +#if defined(_MSC_VER) && _MSC_VER < 1900 +#include +int msvc_translate_printf_format(const char *format, const char **out, + char **tmp); +int snprintf(char *buf, size_t n, const char *fmt, ...); +int vsnprintf(char *buf, size_t n, const char *fmt, va_list args); +#endif + #else /* The non-microsoft world */ #if defined(OPENSSL_SYS_VXWORKS) diff --git a/include/internal/hpke_util.h b/include/internal/hpke_util.h index 152c3213edf61..ae0b518020acd 100644 --- a/include/internal/hpke_util.h +++ b/include/internal/hpke_util.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/ktls.h b/include/internal/ktls.h index d358481999e4c..cf14728fa51e8 100644 --- a/include/internal/ktls.h +++ b/include/internal/ktls.h @@ -98,7 +98,7 @@ static ossl_inline int ktls_enable_tx_zerocopy_sendfile(int fd) * record using this control message. */ static ossl_inline int ktls_send_ctrl_message(int fd, - unsigned char record_type, const void *data, size_t lengthi, int flags) + unsigned char record_type, const void *data, size_t length, int flags) { struct msghdr msg = { 0 }; int cmsg_len = sizeof(record_type); diff --git a/include/internal/list.h b/include/internal/list.h index 8bb0b741bed12..82d851538a1b1 100644 --- a/include/internal/list.h +++ b/include/internal/list.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -25,28 +25,28 @@ (p) != NULL; \ (p) = ossl_list_##name##_next(p)) #define OSSL_LIST_FOREACH(p, name, l) \ - OSSL_LIST_FOREACH_FROM(p, name, ossl_list_##name##_head(l)) + OSSL_LIST_FOREACH_FROM (p, name, ossl_list_##name##_head(l)) #define OSSL_LIST_FOREACH_REV_FROM(p, name, init) \ for ((p) = (init); \ (p) != NULL; \ (p) = ossl_list_##name##_prev(p)) #define OSSL_LIST_FOREACH_REV(p, name, l) \ - OSSL_LIST_FOREACH_FROM(p, name, ossl_list_##name##_tail(l)) + OSSL_LIST_FOREACH_FROM (p, name, ossl_list_##name##_tail(l)) #define OSSL_LIST_FOREACH_DELSAFE_FROM(p, pn, name, init) \ for ((p) = (init); \ (p) != NULL && (((pn) = ossl_list_##name##_next(p)), 1); \ (p) = (pn)) #define OSSL_LIST_FOREACH_DELSAFE(p, pn, name, l) \ - OSSL_LIST_FOREACH_DELSAFE_FROM(p, pn, name, ossl_list_##name##_head(l)) + OSSL_LIST_FOREACH_DELSAFE_FROM (p, pn, name, ossl_list_##name##_head(l)) #define OSSL_LIST_FOREACH_REV_DELSAFE_FROM(p, pn, name, init) \ for ((p) = (init); \ (p) != NULL && (((pn) = ossl_list_##name##_prev(p)), 1); \ (p) = (pn)) #define OSSL_LIST_FOREACH_REV_DELSAFE(p, pn, name, l) \ - OSSL_LIST_FOREACH_REV_DELSAFE_FROM(p, pn, name, ossl_list_##name##_tail(l)) + OSSL_LIST_FOREACH_REV_DELSAFE_FROM (p, pn, name, ossl_list_##name##_tail(l)) /* Define a list structure */ #define OSSL_LIST(name) OSSL_LIST_##name @@ -67,7 +67,7 @@ #define DEFINE_LIST_OF_IMPL(name, type) \ static ossl_unused ossl_inline void \ - ossl_list_##name##_init(OSSL_LIST(name) * list) \ + ossl_list_##name##_init(OSSL_LIST(name) *list) \ { \ memset(list, 0, sizeof(*list)); \ } \ @@ -78,24 +78,24 @@ sizeof(elem->ossl_list_##name)); \ } \ static ossl_unused ossl_inline int \ - ossl_list_##name##_is_empty(const OSSL_LIST(name) * list) \ + ossl_list_##name##_is_empty(const OSSL_LIST(name) *list) \ { \ return list->num_elems == 0; \ } \ static ossl_unused ossl_inline size_t \ - ossl_list_##name##_num(const OSSL_LIST(name) * list) \ + ossl_list_##name##_num(const OSSL_LIST(name) *list) \ { \ return list->num_elems; \ } \ static ossl_unused ossl_inline type * \ - ossl_list_##name##_head(const OSSL_LIST(name) * list) \ + ossl_list_##name##_head(const OSSL_LIST(name) *list) \ { \ assert(list->alpha == NULL \ || list->alpha->ossl_list_##name.list == list); \ return list->alpha; \ } \ static ossl_unused ossl_inline type * \ - ossl_list_##name##_tail(const OSSL_LIST(name) * list) \ + ossl_list_##name##_tail(const OSSL_LIST(name) *list) \ { \ assert(list->omega == NULL \ || list->omega->ossl_list_##name.list == list); \ @@ -120,7 +120,7 @@ return elem->ossl_list_##name.prev; \ } \ static ossl_unused ossl_inline void \ - ossl_list_##name##_remove(OSSL_LIST(name) * list, type * elem) \ + ossl_list_##name##_remove(OSSL_LIST(name) *list, type *elem) \ { \ assert(elem->ossl_list_##name.list == list); \ OSSL_LIST_DBG(elem->ossl_list_##name.list = NULL) \ @@ -137,7 +137,7 @@ sizeof(elem->ossl_list_##name)); \ } \ static ossl_unused ossl_inline void \ - ossl_list_##name##_insert_head(OSSL_LIST(name) * list, type * elem) \ + ossl_list_##name##_insert_head(OSSL_LIST(name) *list, type *elem) \ { \ assert(elem->ossl_list_##name.list == NULL); \ OSSL_LIST_DBG(elem->ossl_list_##name.list = list) \ @@ -151,7 +151,7 @@ list->num_elems++; \ } \ static ossl_unused ossl_inline void \ - ossl_list_##name##_insert_tail(OSSL_LIST(name) * list, type * elem) \ + ossl_list_##name##_insert_tail(OSSL_LIST(name) *list, type *elem) \ { \ assert(elem->ossl_list_##name.list == NULL); \ OSSL_LIST_DBG(elem->ossl_list_##name.list = list) \ @@ -165,8 +165,8 @@ list->num_elems++; \ } \ static ossl_unused ossl_inline void \ - ossl_list_##name##_insert_before(OSSL_LIST(name) * list, type * e, \ - type * elem) \ + ossl_list_##name##_insert_before(OSSL_LIST(name) *list, type *e, \ + type *elem) \ { \ assert(elem->ossl_list_##name.list == NULL); \ OSSL_LIST_DBG(elem->ossl_list_##name.list = list) \ @@ -180,8 +180,8 @@ list->num_elems++; \ } \ static ossl_unused ossl_inline void \ - ossl_list_##name##_insert_after(OSSL_LIST(name) * list, type * e, \ - type * elem) \ + ossl_list_##name##_insert_after(OSSL_LIST(name) *list, type *e, \ + type *elem) \ { \ assert(elem->ossl_list_##name.list == NULL); \ OSSL_LIST_DBG(elem->ossl_list_##name.list = list) \ @@ -194,6 +194,35 @@ list->omega = elem; \ list->num_elems++; \ } \ + static ossl_unused ossl_inline void \ + ossl_list_##name##_join(OSSL_LIST(name) *lh, OSSL_LIST(name) *lt) \ + { \ + OSSL_LIST_DBG(type * _p); /* local variable '_p' when debug */ \ + if (lt == NULL || lh == NULL || lt->num_elems == 0 || lh == lt) \ + return; \ + /* \ + * let's be optimistic about size_t overflow here: it can not happen. \ + */ \ + lh->num_elems += lt->num_elems; \ + if (lh->omega == NULL) { \ + assert(lh->alpha == NULL); \ + lh->omega = lt->omega; \ + lh->alpha = lt->alpha; \ + } else { \ + if (lt->alpha != NULL) \ + ((type *)lt->alpha)->ossl_list_##name.prev = lh->omega; \ + ((type *)lh->omega)->ossl_list_##name.next = lt->alpha; \ + } \ + OSSL_LIST_DBG(for (_p = (type *)lt->alpha; \ + assert(_p == NULL || _p->ossl_list_##name.list == lt), _p != NULL; \ + _p = _p->ossl_list_##name.next) \ + _p->ossl_list_##name.list \ + = lh); \ + lh->omega = lt->omega; \ + lt->alpha = NULL; \ + lt->omega = NULL; \ + lt->num_elems = 0; \ + } \ struct ossl_list_st_##name #define DEFINE_LIST_OF(name, type) \ diff --git a/include/internal/namemap.h b/include/internal/namemap.h index bea96857dca58..1a9e39adf3080 100644 --- a/include/internal/namemap.h +++ b/include/internal/namemap.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/ossl_rbtree.h b/include/internal/ossl_rbtree.h new file mode 100644 index 0000000000000..053ed99478bb9 --- /dev/null +++ b/include/internal/ossl_rbtree.h @@ -0,0 +1,265 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2016 David Gwynne + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * The code here comes from David Gwynne . The original + * version can be found: + * https://github.com/dgwynne/data-structures/ + * file bst.h. The same code is also part of OpenBSD OS where it is shipped + * under BSD license. + * + * David Gwynne agrees to include modified version to OpenSSL and ship it + * under OpenSSL Apache 2.0 license. + */ +#ifndef _OSSL_INTERNAL_RBTREE_H_ +#define _OSSL_INTERNAL_RBTREE_H_ + +#include "internal/e_os.h" + +/* + * List of changes against upstream version: + * augmentation mechanism is removed in OpenSSL as there is no demand for it + * + * prefix changed from rb/rbt to ossl_rbt + * + * debug version of OSSL_RBT_REMOVE() sets parent, left, right members + * to NULL + * + * cstyle is changed to match OpenSSL. + */ +struct ossl_rbt_type { + int (*t_compare)(const void *, const void *); + uintptr_t t_offset; /* offset of ossl_rbt_entry in type */ +}; + +struct ossl_rbt_tree { + struct ossl_rbt_entry *rb_root; +}; + +struct ossl_rbt_entry { + struct ossl_rbt_entry *rb_parent; + struct ossl_rbt_entry *rb_left; + struct ossl_rbt_entry *rb_right; + unsigned int rb_color; +}; + +#define OSSL_RBT_HEAD(_name, _type) \ + struct _name { \ + struct ossl_rbt_tree rbh_root; \ + } + +#define OSSL_RBT_ENTRY(_type) struct ossl_rbt_entry + +static ossl_inline void +ossl_rbt_init(struct ossl_rbt_tree *rb) +{ + rb->rb_root = NULL; +} + +static ossl_inline int +ossl_rbt_empty(struct ossl_rbt_tree *rb) +{ + return rb->rb_root == NULL; +} + +void *ossl_rbt_insert(const struct ossl_rbt_type *, struct ossl_rbt_tree *, void *); +void *ossl_rbt_remove(const struct ossl_rbt_type *, struct ossl_rbt_tree *, void *); +void *ossl_rbt_find(const struct ossl_rbt_type *, struct ossl_rbt_tree *, const void *); +void *ossl_rbt_nfind(const struct ossl_rbt_type *, struct ossl_rbt_tree *, const void *); +void *ossl_rbt_root(const struct ossl_rbt_type *, struct ossl_rbt_tree *); +void *ossl_rbt_min(const struct ossl_rbt_type *, struct ossl_rbt_tree *); +void *ossl_rbt_max(const struct ossl_rbt_type *, struct ossl_rbt_tree *); +void *ossl_rbt_next(const struct ossl_rbt_type *, void *); +void *ossl_rbt_prev(const struct ossl_rbt_type *, void *); +void *ossl_rbt_left(const struct ossl_rbt_type *, void *); +void *ossl_rbt_right(const struct ossl_rbt_type *, void *); +void *ossl_rbt_parent(const struct ossl_rbt_type *, void *); +void ossl_rbt_set_left(const struct ossl_rbt_type *, void *, void *); +void ossl_rbt_set_right(const struct ossl_rbt_type *, void *, void *); +void ossl_rbt_set_parent(const struct ossl_rbt_type *, void *, void *); +void ossl_rbt_init_rbe(const struct ossl_rbt_type *, void *); + +#define OSSL_RBT_INITIALIZER(_head) \ + { \ + { \ + NULL \ + } \ + } + +#define OSSL_RBT_PROTOTYPE(_name, _type, _field, _cmp) \ + extern const struct ossl_rbt_type *const _name##_OSSL_RBT_TYPE; \ + \ + ossl_unused static ossl_inline void \ + _name##_OSSL_RBT_INIT(struct _name *head) \ + { \ + ossl_rbt_init(&head->rbh_root); \ + } \ + \ + ossl_unused static ossl_inline struct _type * \ + _name##_OSSL_RBT_INSERT(struct _name *head, struct _type *elm) \ + { \ + return ossl_rbt_insert(_name##_OSSL_RBT_TYPE, &head->rbh_root, elm); \ + } \ + \ + ossl_unused static ossl_inline struct _type * \ + _name##_OSSL_RBT_REMOVE(struct _name *head, struct _type *elm) \ + { \ + return ossl_rbt_remove(_name##_OSSL_RBT_TYPE, &head->rbh_root, elm); \ + } \ + \ + ossl_unused static ossl_inline struct _type * \ + _name##_OSSL_RBT_FIND(struct _name *head, const struct _type *key) \ + { \ + return ossl_rbt_find(_name##_OSSL_RBT_TYPE, &head->rbh_root, key); \ + } \ + \ + ossl_unused static ossl_inline struct _type * \ + _name##_OSSL_RBT_NFIND(struct _name *head, const struct _type *key) \ + { \ + return ossl_rbt_nfind(_name##_OSSL_RBT_TYPE, &head->rbh_root, key); \ + } \ + \ + ossl_unused static ossl_inline struct _type * \ + _name##_OSSL_RBT_ROOT(struct _name *head) \ + { \ + return ossl_rbt_root(_name##_OSSL_RBT_TYPE, &head->rbh_root); \ + } \ + \ + ossl_unused static ossl_inline int \ + _name##_OSSL_RBT_EMPTY(struct _name *head) \ + { \ + return ossl_rbt_empty(&head->rbh_root); \ + } \ + \ + ossl_unused static ossl_inline struct _type * \ + _name##_OSSL_RBT_MIN(struct _name *head) \ + { \ + return ossl_rbt_min(_name##_OSSL_RBT_TYPE, &head->rbh_root); \ + } \ + \ + ossl_unused static ossl_inline struct _type * \ + _name##_OSSL_RBT_MAX(struct _name *head) \ + { \ + return ossl_rbt_max(_name##_OSSL_RBT_TYPE, &head->rbh_root); \ + } \ + \ + ossl_unused static ossl_inline struct _type * \ + _name##_OSSL_RBT_NEXT(struct _type *elm) \ + { \ + return ossl_rbt_next(_name##_OSSL_RBT_TYPE, elm); \ + } \ + \ + ossl_unused static ossl_inline struct _type * \ + _name##_OSSL_RBT_PREV(struct _type *elm) \ + { \ + return ossl_rbt_prev(_name##_OSSL_RBT_TYPE, elm); \ + } \ + \ + ossl_unused static ossl_inline struct _type * \ + _name##_OSSL_RBT_LEFT(struct _type *elm) \ + { \ + return ossl_rbt_left(_name##_OSSL_RBT_TYPE, elm); \ + } \ + \ + ossl_unused static ossl_inline struct _type * \ + _name##_OSSL_RBT_RIGHT(struct _type *elm) \ + { \ + return ossl_rbt_right(_name##_OSSL_RBT_TYPE, elm); \ + } \ + \ + ossl_unused static ossl_inline struct _type * \ + _name##_OSSL_RBT_PARENT(struct _type *elm) \ + { \ + return ossl_rbt_parent(_name##_OSSL_RBT_TYPE, elm); \ + } \ + \ + ossl_unused static ossl_inline void \ + _name##_OSSL_RBT_SET_LEFT(struct _type *elm, struct _type *left) \ + { \ + ossl_rbt_set_left(_name##_OSSL_RBT_TYPE, elm, left); \ + } \ + \ + ossl_unused static ossl_inline void \ + _name##_OSSL_RBT_SET_RIGHT(struct _type *elm, struct _type *right) \ + { \ + ossl_rbt_set_right(_name##_OSSL_RBT_TYPE, elm, right); \ + } \ + \ + ossl_unused static ossl_inline void \ + _name##_OSSL_RBT_SET_PARENT(struct _type *elm, struct _type *parent) \ + { \ + ossl_rbt_set_parent(_name##_OSSL_RBT_TYPE, elm, parent); \ + } \ + ossl_unused static ossl_inline void \ + _name##_OSSL_RBT_INIT_RBE(struct _type *elm) \ + { \ + ossl_rbt_init_rbe(_name##_OSSL_RBT_TYPE, elm); \ + } + +#define OSSL_RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp) \ + static int \ + _name##_OSSL_RBT_COMPARE(const void *lptr, const void *rptr) \ + { \ + const struct _type *l = lptr, *r = rptr; \ + return _cmp(l, r); \ + } \ + static const struct ossl_rbt_type _name##_OSSL_RBT_INFO = { \ + _name##_OSSL_RBT_COMPARE, \ + offsetof(struct _type, _field), \ + }; \ + const struct ossl_rbt_type *const _name##_OSSL_RBT_TYPE = &_name##_OSSL_RBT_INFO + +#define OSSL_RBT_GENERATE(_name, _type, _field, _cmp) \ + OSSL_RBT_GENERATE_INTERNAL(_name, _type, _field, _cmp) + +#define OSSL_RBT_INIT(_name, _head) _name##_OSSL_RBT_INIT(_head) +#define OSSL_RBT_INSERT(_name, _head, _elm) _name##_OSSL_RBT_INSERT(_head, _elm) +#define OSSL_RBT_REMOVE(_name, _head, _elm) _name##_OSSL_RBT_REMOVE(_head, _elm) +#define OSSL_RBT_FIND(_name, _head, _key) _name##_OSSL_RBT_FIND(_head, _key) +#define OSSL_RBT_NFIND(_name, _head, _key) _name##_OSSL_RBT_NFIND(_head, _key) +#define OSSL_RBT_ROOT(_name, _head) _name##_OSSL_RBT_ROOT(_head) +#define OSSL_RBT_EMPTY(_name, _head) _name##_OSSL_RBT_EMPTY(_head) +#define OSSL_RBT_MIN(_name, _head) _name##_OSSL_RBT_MIN(_head) +#define OSSL_RBT_MAX(_name, _head) _name##_OSSL_RBT_MAX(_head) +#define OSSL_RBT_NEXT(_name, _elm) _name##_OSSL_RBT_NEXT(_elm) +#define OSSL_RBT_PREV(_name, _elm) _name##_OSSL_RBT_PREV(_elm) +#define OSSL_RBT_LEFT(_name, _elm) _name##_OSSL_RBT_LEFT(_elm) +#define OSSL_RBT_RIGHT(_name, _elm) _name##_OSSL_RBT_RIGHT(_elm) +#define OSSL_RBT_PARENT(_name, _elm) _name##_OSSL_RBT_PARENT(_elm) +#define OSSL_RBT_SET_LEFT(_name, _elm, _l) _name##_OSSL_RBT_SET_LEFT(_elm, _l) +#define OSSL_RBT_SET_RIGHT(_name, _elm, _r) _name##_OSSL_RBT_SET_RIGHT(_elm, _r) +#define OSSL_RBT_SET_PARENT(_name, _elm, _p) _name##_OSSL_RBT_SET_PARENT(_elm, _p) +#ifndef NDEBUG +#define OSSL_RBT_INIT_RBE(_name, _elm) _name##_OSSL_RBT_INIT_RBE(_elm) +#else +#define OSSL_RBT_INIT_RBE(_name, _elm) (void)(0) +#endif + +#define OSSL_RBT_FOREACH(_e, _name, _head) \ + for ((_e) = OSSL_RBT_MIN(_name, (_head)); \ + (_e) != NULL; \ + (_e) = OSSL_RBT_NEXT(_name, (_e))) + +#define OSSL_RBT_FOREACH_SAFE(_e, _name, _head, _n) \ + for ((_e) = OSSL_RBT_MIN(_name, (_head)); \ + (_e) != NULL && ((_n) = OSSL_RBT_NEXT(_name, (_e)), 1); \ + (_e) = (_n)) + +#define OSSL_RBT_FOREACH_REVERSE(_e, _name, _head) \ + for ((_e) = OSSL_RBT_MAX(_name, (_head)); \ + (_e) != NULL; \ + (_e) = OSSL_RBT_PREV(_name, (_e))) + +#define OSSL_RBT_FOREACH_REVERSE_SAFE(_e, _name, _head, _n) \ + for ((_e) = OSSL_RBT_MAX(_name, (_head)); \ + (_e) != NULL && ((_n) = OSSL_RBT_PREV(_name, (_e)), 1); \ + (_e) = (_n)) + +#endif /* _OSSL_INTERNAL_RBTREE_H_ */ diff --git a/include/internal/packet.h b/include/internal/packet.h index 44b63c5aa14e7..e15e0db83c0a4 100644 --- a/include/internal/packet.h +++ b/include/internal/packet.h @@ -243,6 +243,37 @@ __owur static ossl_inline int PACKET_peek_net_4(const PACKET *pkt, return 1; } +/* + * Peek ahead at 6 bytes in network order from |pkt| and store the value in + * |*data| + */ +__owur static ossl_inline int PACKET_peek_net_6(const PACKET *pkt, + uint64_t *data) +{ + if (PACKET_remaining(pkt) < 6) + return 0; + + *data = ((uint64_t)(*(pkt->curr))) << 40; + *data |= ((uint64_t)(*(pkt->curr + 1))) << 32; + *data |= ((uint64_t)(*(pkt->curr + 2))) << 24; + *data |= ((uint64_t)(*(pkt->curr + 3))) << 16; + *data |= ((uint64_t)(*(pkt->curr + 4))) << 8; + *data |= *(pkt->curr + 5); + + return 1; +} + +/* Get 6 bytes in network order from |pkt| and store the value in |*data| */ +__owur static ossl_inline int PACKET_get_net_6(PACKET *pkt, uint64_t *data) +{ + if (!PACKET_peek_net_6(pkt, data)) + return 0; + + packet_forward(pkt, 6); + + return 1; +} + /* * Peek ahead at 8 bytes in network order from |pkt| and store the value in * |*data| @@ -795,6 +826,18 @@ int WPACKET_finish(WPACKET *pkt); */ int WPACKET_fill_lengths(WPACKET *pkt); +/* + * Initialise a new sub-packet. Additionally |lenbytes| of data is preallocated + * at the current position in |pkt| to store the sub-packets length once we know + * it. The sub-packet start is set at |offset| from current position in |pkt| + * Don't call this directly. Use the convenience macros below instead. + */ +int WPACKET_start_sub_packet_at_offset_len__(WPACKET *pkt, size_t lenbytes, + size_t offset); + +#define WPACKET_start_sub_packet_u24_at_offset(pkt, offset) \ + WPACKET_start_sub_packet_at_offset_len__((pkt), 3, (offset)) + /* * Initialise a new sub-packet. Additionally |lenbytes| of data is preallocated * at the start of the sub-packet to store its length once we know it. Don't @@ -913,6 +956,8 @@ int WPACKET_put_bytes__(WPACKET *pkt, uint64_t val, size_t bytes); WPACKET_put_bytes__((pkt), (val), 3) #define WPACKET_put_bytes_u32(pkt, val) \ WPACKET_put_bytes__((pkt), (val), 4) +#define WPACKET_put_bytes_u48(pkt, val) \ + WPACKET_put_bytes__((pkt), (val), 6) #define WPACKET_put_bytes_u64(pkt, val) \ WPACKET_put_bytes__((pkt), (val), 8) diff --git a/include/internal/param_build_set.h b/include/internal/param_build_set.h index c7785a12e6161..a01cf2d1c92d5 100644 --- a/include/internal/param_build_set.h +++ b/include/internal/param_build_set.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -44,8 +44,4 @@ int ossl_param_build_set_signed_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, int ossl_param_build_set_signed_bn_pad(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, const char *key, const BIGNUM *bn, size_t sz); -int ossl_param_build_set_multi_key_bn(OSSL_PARAM_BLD *bld, OSSL_PARAM *p, - const char *names[], - STACK_OF(BIGNUM_const) *stk); - #endif /* OSSL_INTERNAL_PARAM_BUILD_SET_H */ diff --git a/include/internal/params.h b/include/internal/params.h index b5b423351f5f3..d9234c8dd1f62 100644 --- a/include/internal/params.h +++ b/include/internal/params.h @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/passphrase.h b/include/internal/passphrase.h index b7cbaa1057ade..078feae5cc227 100644 --- a/include/internal/passphrase.h +++ b/include/internal/passphrase.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/priority_queue.h b/include/internal/priority_queue.h index 9f4a6361656e7..e702c573c39c5 100644 --- a/include/internal/priority_queue.h +++ b/include/internal/priority_queue.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -16,56 +16,56 @@ #define PRIORITY_QUEUE_OF(type) OSSL_PRIORITY_QUEUE_##type -#define DEFINE_PRIORITY_QUEUE_OF_INTERNAL(type, ctype) \ - typedef struct ossl_priority_queue_st_##type PRIORITY_QUEUE_OF(type); \ - static ossl_unused ossl_inline PRIORITY_QUEUE_OF(type) * ossl_pqueue_##type##_new(int (*compare)(const void *, const void *)) \ - { \ - return (PRIORITY_QUEUE_OF(type) *)ossl_pqueue_new( \ - compare); \ - } \ - static ossl_unused ossl_inline void \ - ossl_pqueue_##type##_free(PRIORITY_QUEUE_OF(type) * pq) \ - { \ - ossl_pqueue_free((OSSL_PQUEUE *)pq); \ - } \ - static ossl_unused ossl_inline void \ - ossl_pqueue_##type##_pop_free(PRIORITY_QUEUE_OF(type) * pq, \ - void (*freefunc)(void *)) \ - { \ - ossl_pqueue_pop_free((OSSL_PQUEUE *)pq, freefunc); \ - } \ - static ossl_unused ossl_inline int \ - ossl_pqueue_##type##_reserve(PRIORITY_QUEUE_OF(type) * pq, size_t n) \ - { \ - return ossl_pqueue_reserve((OSSL_PQUEUE *)pq, n); \ - } \ - static ossl_unused ossl_inline size_t \ - ossl_pqueue_##type##_num(const PRIORITY_QUEUE_OF(type) * pq) \ - { \ - return ossl_pqueue_num((OSSL_PQUEUE *)pq); \ - } \ - static ossl_unused ossl_inline int \ - ossl_pqueue_##type##_push(PRIORITY_QUEUE_OF(type) * pq, \ - ctype * data, size_t *elem) \ - { \ - return ossl_pqueue_push((OSSL_PQUEUE *)pq, (void *)data, elem); \ - } \ - static ossl_unused ossl_inline ctype * \ - ossl_pqueue_##type##_peek(const PRIORITY_QUEUE_OF(type) * pq) \ - { \ - return (type *)ossl_pqueue_peek((OSSL_PQUEUE *)pq); \ - } \ - static ossl_unused ossl_inline ctype * \ - ossl_pqueue_##type##_pop(PRIORITY_QUEUE_OF(type) * pq) \ - { \ - return (type *)ossl_pqueue_pop((OSSL_PQUEUE *)pq); \ - } \ - static ossl_unused ossl_inline ctype * \ - ossl_pqueue_##type##_remove(PRIORITY_QUEUE_OF(type) * pq, \ - size_t elem) \ - { \ - return (type *)ossl_pqueue_remove((OSSL_PQUEUE *)pq, elem); \ - } \ +#define DEFINE_PRIORITY_QUEUE_OF_INTERNAL(type, ctype) \ + typedef struct ossl_priority_queue_st_##type PRIORITY_QUEUE_OF(type); \ + static ossl_unused ossl_inline PRIORITY_QUEUE_OF(type) *ossl_pqueue_##type##_new(int (*compare)(const void *, const void *)) \ + { \ + return (PRIORITY_QUEUE_OF(type) *)ossl_pqueue_new( \ + compare); \ + } \ + static ossl_unused ossl_inline void \ + ossl_pqueue_##type##_free(PRIORITY_QUEUE_OF(type) *pq) \ + { \ + ossl_pqueue_free((OSSL_PQUEUE *)pq); \ + } \ + static ossl_unused ossl_inline void \ + ossl_pqueue_##type##_pop_free(PRIORITY_QUEUE_OF(type) *pq, \ + void (*freefunc)(void *)) \ + { \ + ossl_pqueue_pop_free((OSSL_PQUEUE *)pq, freefunc); \ + } \ + static ossl_unused ossl_inline int \ + ossl_pqueue_##type##_reserve(PRIORITY_QUEUE_OF(type) *pq, size_t n) \ + { \ + return ossl_pqueue_reserve((OSSL_PQUEUE *)pq, n); \ + } \ + static ossl_unused ossl_inline size_t \ + ossl_pqueue_##type##_num(const PRIORITY_QUEUE_OF(type) *pq) \ + { \ + return ossl_pqueue_num((OSSL_PQUEUE *)pq); \ + } \ + static ossl_unused ossl_inline int \ + ossl_pqueue_##type##_push(PRIORITY_QUEUE_OF(type) *pq, \ + ctype *data, size_t *elem) \ + { \ + return ossl_pqueue_push((OSSL_PQUEUE *)pq, (void *)data, elem); \ + } \ + static ossl_unused ossl_inline ctype * \ + ossl_pqueue_##type##_peek(const PRIORITY_QUEUE_OF(type) *pq) \ + { \ + return (type *)ossl_pqueue_peek((OSSL_PQUEUE *)pq); \ + } \ + static ossl_unused ossl_inline ctype * \ + ossl_pqueue_##type##_pop(PRIORITY_QUEUE_OF(type) *pq) \ + { \ + return (type *)ossl_pqueue_pop((OSSL_PQUEUE *)pq); \ + } \ + static ossl_unused ossl_inline ctype * \ + ossl_pqueue_##type##_remove(PRIORITY_QUEUE_OF(type) *pq, \ + size_t elem) \ + { \ + return (type *)ossl_pqueue_remove((OSSL_PQUEUE *)pq, elem); \ + } \ struct ossl_priority_queue_st_##type #define DEFINE_PRIORITY_QUEUE_OF(type) \ diff --git a/include/internal/propertyerr.h b/include/internal/propertyerr.h deleted file mode 100644 index 94e2c90955d7e..0000000000000 --- a/include/internal/propertyerr.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_INTERNAL_PROPERTYERR_H -#define OSSL_INTERNAL_PROPERTYERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_PROP_strings(void); - -/* - * PROP reason codes. - */ -#define PROP_R_NAME_TOO_LONG 100 -#define PROP_R_NOT_AN_ASCII_CHARACTER 101 -#define PROP_R_NOT_AN_HEXADECIMAL_DIGIT 102 -#define PROP_R_NOT_AN_IDENTIFIER 103 -#define PROP_R_NOT_AN_OCTAL_DIGIT 104 -#define PROP_R_NOT_A_DECIMAL_DIGIT 105 -#define PROP_R_NO_MATCHING_STRING_DELIMITER 106 -#define PROP_R_NO_VALUE 107 -#define PROP_R_PARSE_FAILED 108 -#define PROP_R_STRING_TOO_LONG 109 -#define PROP_R_TRAILING_CHARACTERS 110 - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/internal/qlog.h b/include/internal/qlog.h index ecabe942f2ea3..8c8174fbfdb0a 100644 --- a/include/internal/qlog.h +++ b/include/internal/qlog.h @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/qlog_events.inc b/include/internal/qlog_events.inc index 8d2ef1b349d60..6fcc060a63087 100644 --- a/include/internal/qlog_events.inc +++ b/include/internal/qlog_events.inc @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/quic_ackm.h b/include/internal/quic_ackm.h index c0617da4855f6..5b325e166bd54 100644 --- a/include/internal/quic_ackm.h +++ b/include/internal/quic_ackm.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -129,6 +129,11 @@ struct ossl_ackm_tx_pkt_st { }; int ossl_ackm_on_tx_packet(OSSL_ACKM *ackm, OSSL_ACKM_TX_PKT *pkt); + +/* + * Records transmission of a packet containing only ACK frames. + */ +int ossl_ackm_on_tx_ack_only_packet(OSSL_ACKM *ackm, OSSL_ACKM_TX_PKT *pkt); int ossl_ackm_on_rx_datagram(OSSL_ACKM *ackm, size_t num_bytes); #define OSSL_ACKM_ECN_NONE 0 diff --git a/include/internal/quic_cfq.h b/include/internal/quic_cfq.h index 96c8d89eb6006..6e4332af81195 100644 --- a/include/internal/quic_cfq.h +++ b/include/internal/quic_cfq.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/quic_channel.h b/include/internal/quic_channel.h index cfe7a6005c82a..47a6202164c4f 100644 --- a/include/internal/quic_channel.h +++ b/include/internal/quic_channel.h @@ -15,6 +15,7 @@ #include "internal/quic_record_tx.h" #include "internal/quic_wire.h" #include "internal/quic_predef.h" +#include "internal/quic_demux.h" #include "internal/qlog.h" #include "internal/time.h" #include "internal/thread.h" @@ -330,8 +331,8 @@ OSSL_STATM *ossl_quic_channel_get_statm(QUIC_CHANNEL *ch); /* Gets the TLS handshake layer used with the channel. */ SSL *ossl_quic_channel_get0_tls(QUIC_CHANNEL *ch); -/* Sets the TLS handshake layer used for the channel */ -void ossl_quic_channel_set0_tls(QUIC_CHANNEL *ch, SSL *ssl); +/* Attaches the TLS layer to a deferred channel. */ +int ossl_quic_channel_set0_tls(QUIC_CHANNEL *ch, SSL *ssl); /* Gets the channels short header connection id length */ size_t ossl_quic_channel_get_short_header_conn_id_len(QUIC_CHANNEL *ch); diff --git a/include/internal/quic_demux.h b/include/internal/quic_demux.h index a1bb344dc4688..4e2180c2ba125 100644 --- a/include/internal/quic_demux.h +++ b/include/internal/quic_demux.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -16,6 +16,7 @@ #include "internal/bio_addr.h" #include "internal/time.h" #include "internal/list.h" +#include "internal/dgram_demux.h" #ifndef OPENSSL_NO_QUIC @@ -86,57 +87,14 @@ /* Maximum number of packets we allow to exist in one datagram. */ #define QUIC_MAX_PKT_PER_URXE (sizeof(uint64_t) * 8) -struct quic_urxe_st { - OSSL_LIST_MEMBER(urxe, QUIC_URXE); - - /* - * The URXE data starts after this structure so we don't need a pointer. - * data_len stores the current length (i.e., the length of the received - * datagram) and alloc_len stores the allocation length. The URXE will be - * reallocated if we need a larger allocation than is available, though this - * should not be common as we will have a good idea of worst-case MTUs up - * front. - */ - size_t data_len, alloc_len; - - /* - * Bitfields per packet. processed indicates the packet has been processed - * and must not be processed again, hpr_removed indicates header protection - * has already been removed. Used by QRX only; not used by the demuxer. - */ - uint64_t processed, hpr_removed; - - /* - * This monotonically increases with each datagram received. It is used for - * diagnostic purposes only. - */ - uint64_t datagram_id; - - /* - * Address of peer we received the datagram from, and the local interface - * address we received it on. If local address support is not enabled, local - * is zeroed. - */ - BIO_ADDR peer, local; - - /* - * Time at which datagram was received (or ossl_time_zero()) if a now - * function was not provided). - */ - OSSL_TIME time; - - /* - * Used by the QRX to mark whether a datagram has been deferred. Used by the - * QRX only; not used by the demuxer. - */ - char deferred; - - /* - * Used by the DEMUX to track if a URXE has been handed out. Used primarily - * for debugging purposes. - */ - char demux_state; -}; +/* + * QUIC_URXE is a typedef to DGRAM_URXE. The DGRAM_URXE structure includes + * QUIC-specific fields (processed, hpr_removed, deferred) that are used by + * the QRX but ignored by DTLS. This allows list and demuxer operations to + * be shared. + */ +typedef DGRAM_URXE QUIC_URXE; +typedef DGRAM_URXE_LIST QUIC_URXE_LIST; /* Accessors for URXE buffer. */ static ossl_unused ossl_inline unsigned char * @@ -151,17 +109,26 @@ ossl_quic_urxe_data_end(const QUIC_URXE *e) return ossl_quic_urxe_data(e) + e->data_len; } -/* List structure tracking a queue of URXEs. */ -DEFINE_LIST_OF(urxe, QUIC_URXE); -typedef OSSL_LIST(urxe) QUIC_URXE_LIST; - /* - * List management helpers. These are used by the demuxer but can also be used - * by users of the demuxer to manage URXEs. + * List management helpers. These delegate to the DGRAM_URXE list functions. */ -void ossl_quic_urxe_remove(QUIC_URXE_LIST *l, QUIC_URXE *e); -void ossl_quic_urxe_insert_head(QUIC_URXE_LIST *l, QUIC_URXE *e); -void ossl_quic_urxe_insert_tail(QUIC_URXE_LIST *l, QUIC_URXE *e); +static ossl_unused ossl_inline void +ossl_quic_urxe_remove(QUIC_URXE_LIST *l, QUIC_URXE *e) +{ + ossl_dgram_urxe_remove(l, e); +} + +static ossl_unused ossl_inline void +ossl_quic_urxe_insert_head(QUIC_URXE_LIST *l, QUIC_URXE *e) +{ + ossl_dgram_urxe_insert_head(l, e); +} + +static ossl_unused ossl_inline void +ossl_quic_urxe_insert_tail(QUIC_URXE_LIST *l, QUIC_URXE *e) +{ + ossl_dgram_urxe_insert_tail(l, e); +} /* * Called when a datagram is received for a given connection ID. diff --git a/include/internal/quic_fifd.h b/include/internal/quic_fifd.h index afa330cbc4a2e..a7577b2120582 100644 --- a/include/internal/quic_fifd.h +++ b/include/internal/quic_fifd.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/quic_lcidm.h b/include/internal/quic_lcidm.h index 079dacd597dc2..3ebb45c7b6cf4 100644 --- a/include/internal/quic_lcidm.h +++ b/include/internal/quic_lcidm.h @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/quic_port.h b/include/internal/quic_port.h index 0ce54dea97c43..bd590939fa8a7 100644 --- a/include/internal/quic_port.h +++ b/include/internal/quic_port.h @@ -95,6 +95,9 @@ QUIC_CHANNEL *ossl_quic_port_create_incoming(QUIC_PORT *port, SSL *tls); */ QUIC_CHANNEL *ossl_quic_port_pop_incoming(QUIC_PORT *port); +/* Returns the first incoming channel without removing it, or NULL. */ +QUIC_CHANNEL *ossl_quic_port_peek_incoming(QUIC_PORT *port); + /* Returns 1 if there is at least one connection incoming. */ int ossl_quic_port_have_incoming(QUIC_PORT *port); @@ -241,6 +244,10 @@ uint64_t ossl_quic_port_get_net_bio_epoch(const QUIC_PORT *port); void ossl_quic_port_raise_net_error(QUIC_PORT *port, QUIC_CHANNEL *triggering_ch); +uint64_t ossl_quic_port_get_max_pending_channels(const QUIC_PORT *port); + +void ossl_quic_port_set_max_pending_channels(QUIC_PORT *port, uint64_t max_pending_channels); + #endif #endif diff --git a/include/internal/quic_predef.h b/include/internal/quic_predef.h index c8d4ad470f588..7d666c431ab3a 100644 --- a/include/internal/quic_predef.h +++ b/include/internal/quic_predef.h @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -37,7 +37,6 @@ typedef struct ossl_qtx_pkt_st OSSL_QTX_PKT; typedef struct quic_tick_result_st QUIC_TICK_RESULT; typedef struct quic_srtm_st QUIC_SRTM; typedef struct quic_lcidm_st QUIC_LCIDM; -typedef struct quic_urxe_st QUIC_URXE; typedef struct quic_engine_st QUIC_ENGINE; typedef struct quic_obj_st QUIC_OBJ; typedef struct quic_conn_st QUIC_CONNECTION; diff --git a/include/internal/quic_record_rx.h b/include/internal/quic_record_rx.h index 287837b2a5610..a4e9e7cacd259 100644 --- a/include/internal/quic_record_rx.h +++ b/include/internal/quic_record_rx.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -51,8 +51,9 @@ typedef struct ossl_qrx_args_st { OSSL_QRX *ossl_qrx_new(const OSSL_QRX_ARGS *args); /* - * Frees the QRX. All packets obtained using ossl_qrx_read_pkt must already - * have been released by calling ossl_qrx_release_pkt. + * Frees the QRX/reference to QRX. Frees the QRX object, if all references are + * gone. All packets obtained using ossl_qrx_read_pkt must already have been + * released by calling ossl_qrx_release_pkt. * * You do not need to call ossl_qrx_remove_dst_conn_id first; this function will * unregister the QRX from the demuxer for all registered destination connection @@ -60,6 +61,12 @@ OSSL_QRX *ossl_qrx_new(const OSSL_QRX_ARGS *args); */ void ossl_qrx_free(OSSL_QRX *qrx); +/* + * Obtains a new reference to QRX object. Returns NULL if reference can not + * be obtained. + */ +OSSL_QRX *ossl_qrx_newref(OSSL_QRX *qrx); + /* Setters for the msg_callback and msg_callback_arg */ void ossl_qrx_set_msg_callback(OSSL_QRX *qrx, ossl_msg_cb msg_callback, SSL *msg_callback_ssl); diff --git a/include/internal/quic_srtm.h b/include/internal/quic_srtm.h index 1a8f55da5df28..251b71d457ce3 100644 --- a/include/internal/quic_srtm.h +++ b/include/internal/quic_srtm.h @@ -1,5 +1,5 @@ /* - * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,6 +11,7 @@ #define OSSL_INTERNAL_QUIC_SRTM_H #pragma once +#include #include "internal/e_os.h" #include "internal/time.h" #include "internal/quic_types.h" @@ -69,11 +70,22 @@ void ossl_quic_srtm_free(QUIC_SRTM *srtm); int ossl_quic_srtm_add(QUIC_SRTM *srtm, void *opaque, uint64_t seq_num, const QUIC_STATELESS_RESET_TOKEN *token); -/* - * Removes an entry by identifying it via its (opaque, seq_num) tuple. - * Returns 1 if the entry was found and removed, and 0 if it was not found. +/** + * @brief Removes an entry identified by its (opaque, seq_num) tuple. + * + * The absence of a matching entry is not an error. + * + * @param srtm SRTM instance to remove the entry from. + * @param opaque Opaque pointer identifying the entry. + * @param seq_num Sequence number identifying the entry. + * @param match If non-NULL, @c *match is set to 1 if a matching entry was + * found or to 0 if not. May be NULL if this information is not + * required. + * + * @returns 1 on success and 0 on internal error. */ -int ossl_quic_srtm_remove(QUIC_SRTM *srtm, void *opaque, uint64_t seq_num); +int ossl_quic_srtm_remove(QUIC_SRTM *srtm, void *opaque, uint64_t seq_num, + uint8_t *match); /* * Removes all entries (opaque, *) with the given opaque pointer. diff --git a/include/internal/quic_ssl.h b/include/internal/quic_ssl.h index 45b8e090ed3da..75a0fc5103635 100644 --- a/include/internal/quic_ssl.h +++ b/include/internal/quic_ssl.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -179,6 +179,7 @@ int ossl_quic_conn_poll_events(SSL *ssl, uint64_t events, int do_tick, int ossl_quic_get_notifier_fd(SSL *ssl); void ossl_quic_enter_blocking_section(SSL *ssl, QUIC_REACTOR_WAIT_CTX *wctx); void ossl_quic_leave_blocking_section(SSL *ssl, QUIC_REACTOR_WAIT_CTX *wctx); +QUIC_PORT *ossl_quic_listener_get_port(SSL *s); #endif diff --git a/include/internal/quic_stream_map.h b/include/internal/quic_stream_map.h index 36753d71965f0..3556bef38b970 100644 --- a/include/internal/quic_stream_map.h +++ b/include/internal/quic_stream_map.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -840,6 +840,15 @@ QUIC_STREAM *ossl_quic_stream_map_peek_accept_queue(QUIC_STREAM_MAP *qsm); QUIC_STREAM *ossl_quic_stream_map_find_in_accept_queue(QUIC_STREAM_MAP *qsm, int is_uni); +/* + * Retires an incoming stream for the purposes of MAX_STREAMS RXFC, so that the + * peer is granted credit for another stream. rtt is the estimated connection + * RTT. Must be called at most once for a given stream. + */ +void ossl_quic_stream_map_retire_stream_credit(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *s, + OSSL_TIME rtt); + /* * Removes a stream from the accept queue. rtt is the estimated connection RTT. * The stream is retired for the purposes of MAX_STREAMS RXFC. diff --git a/include/internal/quic_thread_assist.h b/include/internal/quic_thread_assist.h index 152c84663da2d..a4a55a39790d4 100644 --- a/include/internal/quic_thread_assist.h +++ b/include/internal/quic_thread_assist.h @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/quic_tls.h b/include/internal/quic_tls.h index 707f7df9e37c0..03b755e960aa3 100644 --- a/include/internal/quic_tls.h +++ b/include/internal/quic_tls.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -89,6 +89,9 @@ typedef struct quic_tls_args_st { QUIC_TLS *ossl_quic_tls_new(const QUIC_TLS_ARGS *args); +/* Attach an SSL to an unconfigured, deferred handshake layer. */ +int ossl_quic_tls_set0_ssl(QUIC_TLS *qtls, SSL *ssl); + void ossl_quic_tls_free(QUIC_TLS *qtls); int ossl_quic_tls_configure(QUIC_TLS *qtls); diff --git a/include/internal/quic_trace.h b/include/internal/quic_trace.h index bddb9823c23b5..d772a062ebe0c 100644 --- a/include/internal/quic_trace.h +++ b/include/internal/quic_trace.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/quic_vlint.h b/include/internal/quic_vlint.h index c8b056909d7e6..b5750b23b90e9 100644 --- a/include/internal/quic_vlint.h +++ b/include/internal/quic_vlint.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/quic_wire.h b/include/internal/quic_wire.h index 06ae9ca677808..8efd73979afcf 100644 --- a/include/internal/quic_wire.h +++ b/include/internal/quic_wire.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/rcu.h b/include/internal/rcu.h index 7090e5b2562c2..780846d9399cb 100644 --- a/include/internal/rcu.h +++ b/include/internal/rcu.h @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/recordmethod.h b/include/internal/recordmethod.h index 15e16c0026f93..a3b30f22e75a3 100644 --- a/include/internal/recordmethod.h +++ b/include/internal/recordmethod.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -56,6 +56,8 @@ typedef struct ossl_record_layer_st OSSL_RECORD_LAYER; struct ossl_record_template_st { unsigned char type; unsigned int version; + uint64_t sequence_number; + uint64_t epoch; const unsigned char *buf; size_t buflen; }; @@ -114,15 +116,17 @@ struct ossl_record_method_st { const char *propq, int vers, int role, int direction, int level, - uint16_t epoch, + uint64_t epoch, unsigned char *secret, size_t secretlen, + unsigned char *snkey, unsigned char *key, size_t keylen, unsigned char *iv, size_t ivlen, unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *snciph, const EVP_CIPHER *ciph, size_t taglen, int mactype, @@ -132,6 +136,7 @@ struct ossl_record_method_st { BIO *prev, BIO *transport, BIO *next, + int use_urxe, const OSSL_PARAM *settings, const OSSL_PARAM *options, const OSSL_DISPATCH *fns, @@ -222,7 +227,7 @@ struct ossl_record_method_st { */ int (*read_record)(OSSL_RECORD_LAYER *rl, void **rechandle, int *rversion, uint8_t *type, const unsigned char **data, size_t *datalen, - uint16_t *epoch, unsigned char *seq_num); + uint64_t *epoch, uint64_t *seq_num); /* * Release length bytes from a buffer associated with a record previously * read with read_record. Once all the bytes from a record are released, the @@ -244,6 +249,21 @@ struct ossl_record_method_st { */ int (*set1_bio)(OSSL_RECORD_LAYER *rl, BIO *bio); + /* + * Update the peer address for DTLS write record layers. When set + * (family != AF_UNSPEC), the record layer will use BIO_sendmmsg() + * with this address instead of BIO_write(). This is used by + * listener-created connections that share the listener's network BIO. + */ + int (*set1_peer)(OSSL_RECORD_LAYER *rl, const BIO_ADDR *peer); + + /* + * Set whether to use the URXE queue for reading. This is used by + * listener-created DTLS connections that receive data via the + * listener's demux rather than directly from a BIO. + */ + void (*set_use_urxe)(OSSL_RECORD_LAYER *rl, int use_urxe); + /* Called when protocol negotiation selects a protocol version to use */ int (*set_protocol_version)(OSSL_RECORD_LAYER *rl, int version); @@ -304,6 +324,31 @@ struct ossl_record_method_st { */ int (*increment_sequence_ctr)(OSSL_RECORD_LAYER *rl); + /* + * Get the Sequence number + */ + int (*get_sequence)(OSSL_RECORD_LAYER *rl, uint64_t *sequence); + + /* + * Set the Sequence number to a specific value + */ + int (*set_sequence)(OSSL_RECORD_LAYER *rl, uint64_t sequence); + + /* + * Get the Epoch value + */ + int (*get_epoch)(OSSL_RECORD_LAYER *rl, uint64_t *epoch); + + /* + * Set the current MTU length to be used for the record layer. + */ + int (*set_curr_mtu)(OSSL_RECORD_LAYER *rl, size_t curr_mtu); + + /* + * Return number of records in the queue of unprocessed records + */ + size_t (*unprocessed_records)(OSSL_RECORD_LAYER *rl); + /* * Allocate read or write buffers. Does nothing if already allocated. * Assumes default buffer length and 1 pipeline. diff --git a/include/internal/refcount.h b/include/internal/refcount.h index 2e7dedf2c3a16..7cc4ce660e1aa 100644 --- a/include/internal/refcount.h +++ b/include/internal/refcount.h @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,6 +14,8 @@ #include #include +#include + #if defined(OPENSSL_THREADS) && !defined(OPENSSL_DEV_NO_ATOMICS) #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L \ && !defined(__STDC_NO_ATOMICS__) @@ -36,10 +38,10 @@ typedef struct { _Atomic int val; } CRYPTO_REF_COUNT; -static inline int CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) +static inline bool CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { *ret = atomic_fetch_add_explicit(&refcnt->val, 1, memory_order_relaxed) + 1; - return 1; + return true; } /* @@ -76,10 +78,10 @@ typedef struct { int val; } CRYPTO_REF_COUNT; -static __inline__ int CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) +static __inline__ bool CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { *ret = __atomic_fetch_add(&refcnt->val, 1, __ATOMIC_RELAXED) + 1; - return 1; + return true; } static __inline__ int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, int *ret) @@ -91,21 +93,22 @@ static __inline__ int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, int *ret) } #elif defined(__ICL) && defined(_WIN32) +#include #define HAVE_ATOMICS 1 typedef struct { - volatile int val; + volatile long val; } CRYPTO_REF_COUNT; -static __inline int CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) +static __inline bool CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { - *ret = _InterlockedExchangeAdd((void *)&refcnt->val, 1) + 1; - return 1; + *ret = _InterlockedExchangeAdd(&refcnt->val, 1) + 1; + return true; } static __inline int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { - *ret = _InterlockedExchangeAdd((void *)&refcnt->val, -1) - 1; + *ret = _InterlockedExchangeAdd(&refcnt->val, -1) - 1; return 1; } @@ -114,7 +117,7 @@ static __inline int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, int *ret) #define HAVE_ATOMICS 1 typedef struct { - volatile int val; + volatile long val; } CRYPTO_REF_COUNT; #if (defined(_M_ARM) && _M_ARM >= 7) || defined(_M_ARM64) @@ -123,10 +126,10 @@ typedef struct { #define _ARM_BARRIER_ISH _ARM64_BARRIER_ISH #endif -static __inline int CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) +static __inline bool CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { *ret = _InterlockedExchangeAdd_nf(&refcnt->val, 1) + 1; - return 1; + return true; } static __inline int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, int *ret) @@ -138,10 +141,10 @@ static __inline int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, int *ret) #else #pragma intrinsic(_InterlockedExchangeAdd) -static __inline int CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) +static __inline bool CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { *ret = _InterlockedExchangeAdd(&refcnt->val, 1) + 1; - return 1; + return true; } static __inline int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, int *ret) @@ -171,10 +174,10 @@ typedef struct { #ifdef OPENSSL_THREADS -static ossl_unused ossl_inline int CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, +static ossl_unused ossl_inline bool CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { - return CRYPTO_atomic_add(&refcnt->val, 1, ret, refcnt->lock); + return CRYPTO_atomic_add(&refcnt->val, 1, ret, refcnt->lock) ? true : false; } static ossl_unused ossl_inline int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, @@ -203,12 +206,12 @@ static ossl_unused ossl_inline void CRYPTO_FREE_REF(CRYPTO_REF_COUNT *refcnt) #else /* OPENSSL_THREADS */ -static ossl_unused ossl_inline int CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, +static ossl_unused ossl_inline bool CRYPTO_UP_REF(CRYPTO_REF_COUNT *refcnt, int *ret) { refcnt->val++; *ret = refcnt->val; - return 1; + return true; } static ossl_unused ossl_inline int CRYPTO_DOWN_REF(CRYPTO_REF_COUNT *refcnt, diff --git a/include/internal/ring_buf.h b/include/internal/ring_buf.h index 19c13817fd486..c8110e40ab4fa 100644 --- a/include/internal/ring_buf.h +++ b/include/internal/ring_buf.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/skey.h b/include/internal/skey.h index b511af8c32c29..b731ce5dc3307 100644 --- a/include/internal/skey.h +++ b/include/internal/skey.h @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -31,6 +31,15 @@ struct prov_skey_st { unsigned char *data; size_t length; + + /* Metadata — set during import, returned during export / get_key_id */ + char *alias; + unsigned char *local_keyid; + size_t local_keyid_len; + unsigned char *algorithm_oid; + size_t algorithm_oid_len; + unsigned char *algorithm_params; + size_t algorithm_params_len; }; #endif /* OSSL_CRYPTO_SKEY_H */ diff --git a/include/internal/sm3.h b/include/internal/sm3.h index 0faf5449426b5..0c4c53d2fcef4 100644 --- a/include/internal/sm3.h +++ b/include/internal/sm3.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2017 Ribose Inc. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/include/internal/ssl3_cbc.h b/include/internal/ssl3_cbc.h index 84c2ccb81370c..32e4e0b1965dc 100644 --- a/include/internal/ssl3_cbc.h +++ b/include/internal/ssl3_cbc.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/ssl_unwrap.h b/include/internal/ssl_unwrap.h index 63791b1552a91..3c0f5ecfe1cbf 100644 --- a/include/internal/ssl_unwrap.h +++ b/include/internal/ssl_unwrap.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -46,6 +46,14 @@ struct ssl_connection_st *ossl_quic_obj_get0_handshake_layer(QUIC_OBJ *obj); SSL_CONNECTION_FROM_SSL_ONLY_int(ssl, const) #endif +#ifndef OPENSSL_NO_DTLS + +#define IS_DTLS(ssl) \ + ((ssl) != NULL && ((ssl)->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) != 0) +#else +#define IS_DTLS(ssl) 0 +#endif + #ifndef OPENSSL_NO_QUIC #define IS_QUIC_METHOD(m) \ diff --git a/include/internal/sslconf.h b/include/internal/sslconf.h index a016613a57b3a..45a417815407a 100644 --- a/include/internal/sslconf.h +++ b/include/internal/sslconf.h @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/statem.h b/include/internal/statem.h index 990100c4dc055..027853eccd658 100644 --- a/include/internal/statem.h +++ b/include/internal/statem.h @@ -117,6 +117,10 @@ struct ossl_statem_st { OSSL_HANDSHAKE_STATE hand_state; /* The handshake state requested by an API call (e.g. HelloRequest) */ OSSL_HANDSHAKE_STATE request_state; + /* The handshake state to resume after sending an ACK */ + OSSL_HANDSHAKE_STATE deferred_ack_state; + /* The handshake state before receiving an ACK */ + OSSL_HANDSHAKE_STATE pre_ack_hand_state; ERROR_STATE error_state; int in_init; int read_state_first_init; @@ -136,6 +140,8 @@ struct ossl_statem_st { ossl_statem_finish_mutate_handshake_cb finish_mutate_handshake_cb; void *mutatearg; unsigned int write_in_progress : 1; + /* Send an ACK for an already processed post-handshake message */ + unsigned int ack_for_retransmit : 1; }; typedef struct ossl_statem_st OSSL_STATEM; diff --git a/include/internal/thread_arch.h b/include/internal/thread_arch.h index 73e6e0d1e7fd0..fed6923394b96 100644 --- a/include/internal/thread_arch.h +++ b/include/internal/thread_arch.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/threads_common.h b/include/internal/threads_common.h index e32257d63018b..a9cfa4c6acd10 100644 --- a/include/internal/threads_common.h +++ b/include/internal/threads_common.h @@ -14,9 +14,11 @@ #if defined(__clang__) && defined(__has_feature) #if __has_feature(thread_sanitizer) +#if !defined(__SANITIZE_THREAD__) #define __SANITIZE_THREAD__ #endif #endif +#endif #if defined(__SANITIZE_THREAD__) #include @@ -38,6 +40,7 @@ typedef enum { CRYPTO_THREAD_LOCAL_TEVENT_KEY, CRYPTO_THREAD_LOCAL_TANDEM_ID_KEY, CRYPTO_THREAD_LOCAL_FIPS_DEFERRED_KEY, + CRYPTO_THREAD_LOCAL_RAND_SEED_KEY, CRYPTO_THREAD_LOCAL_KEY_MAX } CRYPTO_THREAD_LOCAL_KEY_ID; diff --git a/include/internal/tlsgroups.h b/include/internal/tlsgroups.h index f12e142b9a4bf..8f9e9e83e5410 100644 --- a/include/internal/tlsgroups.h +++ b/include/internal/tlsgroups.h @@ -64,6 +64,8 @@ #define OSSL_TLS_GROUP_ID_mlkem512 0x0200 #define OSSL_TLS_GROUP_ID_mlkem768 0x0201 #define OSSL_TLS_GROUP_ID_mlkem1024 0x0202 +#define OSSL_TLS_GROUP_ID_SecP256r1MLKEM512 0x11E9 +#define OSSL_TLS_GROUP_ID_MLKEM512X25519 0x11EA #define OSSL_TLS_GROUP_ID_SecP256r1MLKEM768 0x11EB #define OSSL_TLS_GROUP_ID_X25519MLKEM768 0x11EC #define OSSL_TLS_GROUP_ID_SecP384r1MLKEM1024 0x11ED diff --git a/include/internal/to_hex.h b/include/internal/to_hex.h index 4b3940800f82a..f43f64a3c102a 100644 --- a/include/internal/to_hex.h +++ b/include/internal/to_hex.h @@ -1,5 +1,5 @@ /* - * Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/internal/unicode.h b/include/internal/unicode.h index f09bfc732092c..0add94d1116d9 100644 --- a/include/internal/unicode.h +++ b/include/internal/unicode.h @@ -1,5 +1,5 @@ /* - * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/asn1.h.in b/include/openssl/asn1.h.in index a7291738ff1e4..4962a203c9079 100644 --- a/include/openssl/asn1.h.in +++ b/include/openssl/asn1.h.in @@ -540,9 +540,16 @@ int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); * Since this is used to store all sorts of things, via macros, for now, * make its data void * */ +#if !defined(OPENSSL_NO_DEPRECATED_4_1) +OSSL_DEPRECATEDIN_4_1_FOR("use ASN1_STRING_set1_data() or ASN1_STRING_set1_string()") int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); -void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); +OSSL_DEPRECATEDIN_4_1_FOR("use ASN1_STRING_get_length()") int ASN1_STRING_length(const ASN1_STRING *x); +#endif /* !defined(OPENSSL_NO_DEPRECATED_4_1) */ +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); +int ASN1_STRING_set1_data(ASN1_STRING *str, const uint8_t *data, size_t len); +int ASN1_STRING_set1_string(ASN1_STRING *str, const char *cstring); +size_t ASN1_STRING_get_length(const ASN1_STRING *x); #ifndef OPENSSL_NO_DEPRECATED_3_0 OSSL_DEPRECATEDIN_3_0 void ASN1_STRING_length_set(ASN1_STRING *x, int n); #endif diff --git a/include/openssl/asn1err.h b/include/openssl/asn1err.h deleted file mode 100644 index 91756141b0f83..0000000000000 --- a/include/openssl/asn1err.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_ASN1ERR_H -#define OPENSSL_ASN1ERR_H -#pragma once - -#include -#include -#include - -/* - * ASN1 reason codes. - */ -#define ASN1_R_ADDING_OBJECT 171 -#define ASN1_R_ASN1_PARSE_ERROR 203 -#define ASN1_R_ASN1_SIG_PARSE_ERROR 204 -#define ASN1_R_AUX_ERROR 100 -#define ASN1_R_BAD_OBJECT_HEADER 102 -#define ASN1_R_BAD_TEMPLATE 230 -#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214 -#define ASN1_R_BN_LIB 105 -#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 -#define ASN1_R_BUFFER_TOO_SMALL 107 -#define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108 -#define ASN1_R_CONTEXT_NOT_INITIALISED 217 -#define ASN1_R_DATA_IS_WRONG 109 -#define ASN1_R_DECODE_ERROR 110 -#define ASN1_R_DEPTH_EXCEEDED 174 -#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198 -#define ASN1_R_ENCODE_ERROR 112 -#define ASN1_R_ERROR_GETTING_TIME 173 -#define ASN1_R_ERROR_LOADING_SECTION 172 -#define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 114 -#define ASN1_R_EXPECTING_AN_INTEGER 115 -#define ASN1_R_EXPECTING_AN_OBJECT 116 -#define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119 -#define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120 -#define ASN1_R_FIELD_MISSING 121 -#define ASN1_R_FIRST_NUM_TOO_LARGE 122 -#define ASN1_R_GENERALIZEDTIME_IS_TOO_SHORT 232 -#define ASN1_R_HEADER_TOO_LONG 123 -#define ASN1_R_ILLEGAL_BITSTRING_FORMAT 175 -#define ASN1_R_ILLEGAL_BOOLEAN 176 -#define ASN1_R_ILLEGAL_CHARACTERS 124 -#define ASN1_R_ILLEGAL_FORMAT 177 -#define ASN1_R_ILLEGAL_HEX 178 -#define ASN1_R_ILLEGAL_IMPLICIT_TAG 179 -#define ASN1_R_ILLEGAL_INTEGER 180 -#define ASN1_R_ILLEGAL_NEGATIVE_VALUE 226 -#define ASN1_R_ILLEGAL_NESTED_TAGGING 181 -#define ASN1_R_ILLEGAL_NULL 125 -#define ASN1_R_ILLEGAL_NULL_VALUE 182 -#define ASN1_R_ILLEGAL_OBJECT 183 -#define ASN1_R_ILLEGAL_OPTIONAL_ANY 126 -#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 170 -#define ASN1_R_ILLEGAL_PADDING 221 -#define ASN1_R_ILLEGAL_TAGGED_ANY 127 -#define ASN1_R_ILLEGAL_TIME_VALUE 184 -#define ASN1_R_ILLEGAL_ZERO_CONTENT 222 -#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185 -#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 -#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220 -#define ASN1_R_INVALID_BMPSTRING_LENGTH 129 -#define ASN1_R_INVALID_DIGIT 130 -#define ASN1_R_INVALID_MIME_TYPE 205 -#define ASN1_R_INVALID_MODIFIER 186 -#define ASN1_R_INVALID_NUMBER 187 -#define ASN1_R_INVALID_OBJECT_ENCODING 216 -#define ASN1_R_INVALID_SCRYPT_PARAMETERS 227 -#define ASN1_R_INVALID_SEPARATOR 131 -#define ASN1_R_INVALID_STRING_TABLE_VALUE 218 -#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133 -#define ASN1_R_INVALID_UTF8STRING 134 -#define ASN1_R_INVALID_VALUE 219 -#define ASN1_R_LENGTH_TOO_LONG 231 -#define ASN1_R_LIST_ERROR 188 -#define ASN1_R_MIME_NO_CONTENT_TYPE 206 -#define ASN1_R_MIME_PARSE_ERROR 207 -#define ASN1_R_MIME_SIG_PARSE_ERROR 208 -#define ASN1_R_MISSING_EOC 137 -#define ASN1_R_MISSING_SECOND_NUMBER 138 -#define ASN1_R_MISSING_VALUE 189 -#define ASN1_R_MSTRING_NOT_UNIVERSAL 139 -#define ASN1_R_MSTRING_WRONG_TAG 140 -#define ASN1_R_NESTED_ASN1_STRING 197 -#define ASN1_R_NESTED_TOO_DEEP 201 -#define ASN1_R_NON_HEX_CHARACTERS 141 -#define ASN1_R_NOT_ASCII_FORMAT 190 -#define ASN1_R_NOT_ENOUGH_DATA 142 -#define ASN1_R_NO_CONTENT_TYPE 209 -#define ASN1_R_NO_MATCHING_CHOICE_TYPE 143 -#define ASN1_R_NO_MULTIPART_BODY_FAILURE 210 -#define ASN1_R_NO_MULTIPART_BOUNDARY 211 -#define ASN1_R_NO_SIG_CONTENT_TYPE 212 -#define ASN1_R_NULL_IS_WRONG_LENGTH 144 -#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191 -#define ASN1_R_ODD_NUMBER_OF_CHARS 145 -#define ASN1_R_SECOND_NUMBER_TOO_LARGE 147 -#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 148 -#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149 -#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192 -#define ASN1_R_SHORT_LINE 150 -#define ASN1_R_SIG_INVALID_MIME_TYPE 213 -#define ASN1_R_STREAMING_NOT_SUPPORTED 202 -#define ASN1_R_STRING_TOO_LONG 151 -#define ASN1_R_STRING_TOO_SHORT 152 -#define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154 -#define ASN1_R_TIME_NOT_ASCII_FORMAT 193 -#define ASN1_R_TOO_LARGE 223 -#define ASN1_R_TOO_LONG 155 -#define ASN1_R_TOO_SMALL 224 -#define ASN1_R_TYPE_NOT_CONSTRUCTED 156 -#define ASN1_R_TYPE_NOT_PRIMITIVE 195 -#define ASN1_R_UNEXPECTED_EOC 159 -#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215 -#define ASN1_R_UNKNOWN_DIGEST 229 -#define ASN1_R_UNKNOWN_FORMAT 160 -#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 -#define ASN1_R_UNKNOWN_OBJECT_TYPE 162 -#define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163 -#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 199 -#define ASN1_R_UNKNOWN_TAG 194 -#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164 -#define ASN1_R_UNSUPPORTED_CIPHER 228 -#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167 -#define ASN1_R_UNSUPPORTED_TYPE 196 -#define ASN1_R_UTCTIME_IS_TOO_SHORT 233 -#define ASN1_R_WRONG_INTEGER_TYPE 225 -#define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200 -#define ASN1_R_WRONG_TAG 168 - -#endif diff --git a/include/openssl/asn1t.h.in b/include/openssl/asn1t.h.in index ca8bbc2517daf..1564aae371e37 100644 --- a/include/openssl/asn1t.h.in +++ b/include/openssl/asn1t.h.in @@ -1,7 +1,7 @@ /* * {- join("\n * ", @autowarntext) -} * - * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -747,6 +747,7 @@ typedef struct ASN1_STREAM_ARG_st { #define ASN1_OP_DUP_POST 15 #define ASN1_OP_GET0_LIBCTX 16 #define ASN1_OP_GET0_PROPQ 17 +#define ASN1_OP_GET0_STREAM_CONTENT 18 /* Macro to implement a primitive type */ #define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) diff --git a/include/openssl/asyncerr.h b/include/openssl/asyncerr.h deleted file mode 100644 index 41bd4a0391ad2..0000000000000 --- a/include/openssl/asyncerr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_ASYNCERR_H -#define OPENSSL_ASYNCERR_H -#pragma once - -#include -#include -#include - -/* - * ASYNC reason codes. - */ -#define ASYNC_R_FAILED_TO_SET_POOL 101 -#define ASYNC_R_FAILED_TO_SWAP_CONTEXT 102 -#define ASYNC_R_INIT_FAILED 105 -#define ASYNC_R_INVALID_POOL_SIZE 103 - -#endif diff --git a/include/openssl/bio.h.in b/include/openssl/bio.h.in index c2990efde4b2d..a2a5972980dfe 100644 --- a/include/openssl/bio.h.in +++ b/include/openssl/bio.h.in @@ -806,6 +806,7 @@ int BIO_sock_should_retry(int i); int BIO_sock_non_fatal_error(int error); int BIO_err_is_non_fatal(unsigned int errcode); int BIO_socket_wait(int fd, int for_read, time_t max_time); +int BIO_socket_ready(int fd, int for_read); #endif long BIO_set_send_flags(BIO *b, int flags); int BIO_wait(BIO *bio, time_t max_time, unsigned int nap_milliseconds); @@ -941,10 +942,14 @@ int BIO_printf(BIO *bio, const char *format, ...) ossl_bio__attr__((__format__(__printf__, 2, 3))); int BIO_vprintf(BIO *bio, const char *format, va_list args) ossl_bio__attr__((__format__(__printf__, 2, 0))); +#ifndef OPENSSL_NO_DEPRECATED_4_1 +OSSL_DEPRECATEDIN_4_1_FOR("use snprintf()") int BIO_snprintf(char *buf, size_t n, const char *format, ...) ossl_bio__attr__((__format__(__printf__, 3, 4))); +OSSL_DEPRECATEDIN_4_1_FOR("use vsnprintf()") int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) ossl_bio__attr__((__format__(__printf__, 3, 0))); +#endif #undef ossl_bio__attr__ BIO_METHOD *BIO_meth_new(int type, const char *name); diff --git a/include/openssl/bioerr.h b/include/openssl/bioerr.h deleted file mode 100644 index b4ee5c68beec1..0000000000000 --- a/include/openssl/bioerr.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_BIOERR_H -#define OPENSSL_BIOERR_H -#pragma once - -#include -#include -#include - -/* - * BIO reason codes. - */ -#define BIO_R_ACCEPT_ERROR 100 -#define BIO_R_ADDRINFO_ADDR_IS_NOT_AF_INET 141 -#define BIO_R_AMBIGUOUS_HOST_OR_SERVICE 129 -#define BIO_R_BAD_FOPEN_MODE 101 -#define BIO_R_BROKEN_PIPE 124 -#define BIO_R_CONNECT_ERROR 103 -#define BIO_R_CONNECT_TIMEOUT 147 -#define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 -#define BIO_R_GETSOCKNAME_ERROR 132 -#define BIO_R_GETSOCKNAME_TRUNCATED_ADDRESS 133 -#define BIO_R_GETTING_SOCKTYPE 134 -#define BIO_R_INVALID_ARGUMENT 125 -#define BIO_R_INVALID_SOCKET 135 -#define BIO_R_IN_USE 123 -#define BIO_R_LENGTH_TOO_LONG 102 -#define BIO_R_LISTEN_V6_ONLY 136 -#define BIO_R_LOCAL_ADDR_NOT_AVAILABLE 111 -#define BIO_R_LOOKUP_RETURNED_NOTHING 142 -#define BIO_R_MALFORMED_HOST_OR_SERVICE 130 -#define BIO_R_NBIO_CONNECT_ERROR 110 -#define BIO_R_NON_FATAL 112 -#define BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED 143 -#define BIO_R_NO_HOSTNAME_OR_SERVICE_SPECIFIED 144 -#define BIO_R_NO_PORT_DEFINED 113 -#define BIO_R_NO_SUCH_FILE 128 -#define BIO_R_NULL_PARAMETER 115 /* unused */ -#define BIO_R_TFO_DISABLED 106 -#define BIO_R_TFO_NO_KERNEL_SUPPORT 108 -#define BIO_R_TRANSFER_ERROR 104 -#define BIO_R_TRANSFER_TIMEOUT 105 -#define BIO_R_UNABLE_TO_BIND_SOCKET 117 -#define BIO_R_UNABLE_TO_CREATE_SOCKET 118 -#define BIO_R_UNABLE_TO_KEEPALIVE 137 -#define BIO_R_UNABLE_TO_LISTEN_SOCKET 119 -#define BIO_R_UNABLE_TO_NODELAY 138 -#define BIO_R_UNABLE_TO_REUSEADDR 139 -#define BIO_R_UNABLE_TO_TFO 109 -#define BIO_R_UNAVAILABLE_IP_FAMILY 145 -#define BIO_R_UNINITIALIZED 120 -#define BIO_R_UNKNOWN_INFO_TYPE 140 -#define BIO_R_UNSUPPORTED_IP_FAMILY 146 -#define BIO_R_UNSUPPORTED_METHOD 121 -#define BIO_R_UNSUPPORTED_PROTOCOL_FAMILY 131 -#define BIO_R_WRITE_TO_READ_ONLY_BIO 126 -#define BIO_R_WSASTARTUP 122 -#define BIO_R_PORT_MISMATCH 150 -#define BIO_R_PEER_ADDR_NOT_AVAILABLE 151 - -#endif diff --git a/include/openssl/bn.h b/include/openssl/bn.h index 5d7e5ce83fe62..fa708eb805162 100644 --- a/include/openssl/bn.h +++ b/include/openssl/bn.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/include/openssl/bnerr.h b/include/openssl/bnerr.h deleted file mode 100644 index dbbcd699bba48..0000000000000 --- a/include/openssl/bnerr.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_BNERR_H -#define OPENSSL_BNERR_H -#pragma once - -#include -#include -#include - -/* - * BN reason codes. - */ -#define BN_R_ARG2_LT_ARG3 100 -#define BN_R_BAD_RECIPROCAL 101 -#define BN_R_BIGNUM_TOO_LONG 114 -#define BN_R_BITS_TOO_SMALL 118 -#define BN_R_CALLED_WITH_EVEN_MODULUS 102 -#define BN_R_DIV_BY_ZERO 103 -#define BN_R_ENCODING_ERROR 104 -#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105 -#define BN_R_INPUT_NOT_REDUCED 110 -#define BN_R_INVALID_LENGTH 106 -#define BN_R_INVALID_RANGE 115 -#define BN_R_INVALID_SHIFT 119 -#define BN_R_NOT_A_SQUARE 111 -#define BN_R_NOT_INITIALIZED 107 -#define BN_R_NO_INVERSE 108 -#define BN_R_NO_PRIME_CANDIDATE 121 -#define BN_R_NO_SOLUTION 116 -#define BN_R_NO_SUITABLE_DIGEST 120 -#define BN_R_PRIVATE_KEY_TOO_LARGE 117 -#define BN_R_P_IS_NOT_PRIME 112 -#define BN_R_TOO_MANY_ITERATIONS 113 -#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109 - -#endif diff --git a/include/openssl/buffererr.h b/include/openssl/buffererr.h deleted file mode 100644 index 4fa0da44be232..0000000000000 --- a/include/openssl/buffererr.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_BUFFERERR_H -#define OPENSSL_BUFFERERR_H -#pragma once - -#include -#include -#include - -/* - * BUF reason codes. - */ - -#endif diff --git a/include/openssl/cmperr.h b/include/openssl/cmperr.h deleted file mode 100644 index b07ac6d6c6db1..0000000000000 --- a/include/openssl/cmperr.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_CMPERR_H -#define OPENSSL_CMPERR_H -#pragma once - -#include -#include -#include - -#ifndef OPENSSL_NO_CMP - -/* - * CMP reason codes. - */ -#define CMP_R_ALGORITHM_NOT_SUPPORTED 139 -#define CMP_R_BAD_CHECKAFTER_IN_POLLREP 167 -#define CMP_R_BAD_REQUEST_ID 108 -#define CMP_R_CERTHASH_UNMATCHED 156 -#define CMP_R_CERTID_NOT_FOUND 109 -#define CMP_R_CERTIFICATE_NOT_ACCEPTED 169 -#define CMP_R_CERTIFICATE_NOT_FOUND 112 -#define CMP_R_CERTREQMSG_NOT_FOUND 157 -#define CMP_R_CERTRESPONSE_NOT_FOUND 113 -#define CMP_R_CERT_AND_KEY_DO_NOT_MATCH 114 -#define CMP_R_CHECKAFTER_OUT_OF_RANGE 181 -#define CMP_R_ENCOUNTERED_KEYUPDATEWARNING 176 -#define CMP_R_ENCOUNTERED_WAITING 162 -#define CMP_R_ERROR_CALCULATING_PROTECTION 115 -#define CMP_R_ERROR_CREATING_CERTCONF 116 -#define CMP_R_ERROR_CREATING_CERTREP 117 -#define CMP_R_ERROR_CREATING_CERTREQ 163 -#define CMP_R_ERROR_CREATING_ERROR 118 -#define CMP_R_ERROR_CREATING_GENM 119 -#define CMP_R_ERROR_CREATING_GENP 120 -#define CMP_R_ERROR_CREATING_PKICONF 122 -#define CMP_R_ERROR_CREATING_POLLREP 123 -#define CMP_R_ERROR_CREATING_POLLREQ 124 -#define CMP_R_ERROR_CREATING_RP 125 -#define CMP_R_ERROR_CREATING_RR 126 -#define CMP_R_ERROR_PARSING_PKISTATUS 107 -#define CMP_R_ERROR_PROCESSING_MESSAGE 158 -#define CMP_R_ERROR_PROTECTING_MESSAGE 127 -#define CMP_R_ERROR_SETTING_CERTHASH 128 -#define CMP_R_ERROR_UNEXPECTED_CERTCONF 160 -#define CMP_R_ERROR_VALIDATING_PROTECTION 140 -#define CMP_R_ERROR_VALIDATING_SIGNATURE 171 -#define CMP_R_EXPECTED_POLLREQ 104 -#define CMP_R_FAILED_BUILDING_OWN_CHAIN 164 -#define CMP_R_FAILED_EXTRACTING_CENTRAL_GEN_KEY 203 -#define CMP_R_FAILED_EXTRACTING_PUBKEY 141 -#define CMP_R_FAILURE_OBTAINING_RANDOM 110 -#define CMP_R_FAIL_INFO_OUT_OF_RANGE 129 -#define CMP_R_GENERATE_CERTREQTEMPLATE 197 -#define CMP_R_GENERATE_CRLSTATUS 198 -#define CMP_R_GETTING_GENP 192 -#define CMP_R_GET_ITAV 199 -#define CMP_R_INVALID_ARGS 100 -#define CMP_R_INVALID_GENP 193 -#define CMP_R_INVALID_KEYSPEC 202 -#define CMP_R_INVALID_OPTION 174 -#define CMP_R_INVALID_ROOTCAKEYUPDATE 195 -#define CMP_R_MISSING_CENTRAL_GEN_KEY 204 -#define CMP_R_MISSING_CERTID 165 -#define CMP_R_MISSING_KEY_INPUT_FOR_CREATING_PROTECTION 130 -#define CMP_R_MISSING_KEY_USAGE_DIGITALSIGNATURE 142 -#define CMP_R_MISSING_P10CSR 121 -#define CMP_R_MISSING_PBM_SECRET 166 -#define CMP_R_MISSING_PRIVATE_KEY 131 -#define CMP_R_MISSING_PRIVATE_KEY_FOR_POPO 190 -#define CMP_R_MISSING_PROTECTION 143 -#define CMP_R_MISSING_PUBLIC_KEY 183 -#define CMP_R_MISSING_REFERENCE_CERT 168 -#define CMP_R_MISSING_SECRET 178 -#define CMP_R_MISSING_SENDER_IDENTIFICATION 111 -#define CMP_R_MISSING_TRUST_ANCHOR 179 -#define CMP_R_MISSING_TRUST_STORE 144 -#define CMP_R_MULTIPLE_REQUESTS_NOT_SUPPORTED 161 -#define CMP_R_MULTIPLE_RESPONSES_NOT_SUPPORTED 170 -#define CMP_R_MULTIPLE_SAN_SOURCES 102 -#define CMP_R_NO_STDIO 194 -#define CMP_R_NO_SUITABLE_SENDER_CERT 145 -#define CMP_R_NULL_ARGUMENT 103 -#define CMP_R_PKIBODY_ERROR 146 -#define CMP_R_PKISTATUSINFO_NOT_FOUND 132 -#define CMP_R_POLLING_FAILED 172 -#define CMP_R_POTENTIALLY_INVALID_CERTIFICATE 147 -#define CMP_R_RECEIVED_ERROR 180 -#define CMP_R_RECIPNONCE_UNMATCHED 148 -#define CMP_R_REQUEST_NOT_ACCEPTED 149 -#define CMP_R_REQUEST_REJECTED_BY_SERVER 182 -#define CMP_R_SENDER_GENERALNAME_TYPE_NOT_SUPPORTED 150 -#define CMP_R_SRVCERT_DOES_NOT_VALIDATE_MSG 151 -#define CMP_R_TOTAL_TIMEOUT 184 -#define CMP_R_TRANSACTIONID_UNMATCHED 152 -#define CMP_R_TRANSFER_ERROR 159 -#define CMP_R_UNCLEAN_CTX 191 -#define CMP_R_UNEXPECTED_CENTRAL_GEN_KEY 205 -#define CMP_R_UNEXPECTED_CERTPROFILE 196 -#define CMP_R_UNEXPECTED_CRLSTATUSLIST 201 -#define CMP_R_UNEXPECTED_PKIBODY 133 -#define CMP_R_UNEXPECTED_PKISTATUS 185 -#define CMP_R_UNEXPECTED_POLLREQ 105 -#define CMP_R_UNEXPECTED_PVNO 153 -#define CMP_R_UNEXPECTED_SENDER 106 -#define CMP_R_UNKNOWN_ALGORITHM_ID 134 -#define CMP_R_UNKNOWN_CERT_TYPE 135 -#define CMP_R_UNKNOWN_CRL_ISSUER 200 -#define CMP_R_UNKNOWN_PKISTATUS 186 -#define CMP_R_UNSUPPORTED_ALGORITHM 136 -#define CMP_R_UNSUPPORTED_KEY_TYPE 137 -#define CMP_R_UNSUPPORTED_PKIBODY 101 -#define CMP_R_UNSUPPORTED_PROTECTION_ALG_DHBASEDMAC 154 -#define CMP_R_VALUE_TOO_LARGE 175 -#define CMP_R_VALUE_TOO_SMALL 177 -#define CMP_R_WRONG_ALGORITHM_OID 138 -#define CMP_R_WRONG_CERTID 189 -#define CMP_R_WRONG_CERTID_IN_RP 187 -#define CMP_R_WRONG_PBM_VALUE 155 -#define CMP_R_WRONG_RP_COMPONENT_COUNT 188 -#define CMP_R_WRONG_SERIAL_IN_RP 173 - -#endif -#endif diff --git a/include/openssl/cms.h.in b/include/openssl/cms.h.in index 20af42015c2b8..b7e8d72303510 100644 --- a/include/openssl/cms.h.in +++ b/include/openssl/cms.h.in @@ -76,6 +76,11 @@ CMS_ContentInfo *CMS_ContentInfo_new_ex(OSSL_LIB_CTX *libctx, const char *propq) #define CMS_RECIPINFO_OTHER 4 #define CMS_RECIPINFO_KEM 5 +#define CMS_VERIFY_RESULT 0 +#define CMS_VERIFY_CERT 1 +#define CMS_VERIFY_ATTR 2 +#define CMS_VERIFY_CONTENT 3 + /* S/MIME related flags */ #define CMS_TEXT 0x1 @@ -104,6 +109,7 @@ CMS_ContentInfo *CMS_ContentInfo_new_ex(OSSL_LIB_CTX *libctx, const char *propq) #define CMS_CADES 0x100000 #define CMS_USE_ORIGINATOR_KEYID 0x200000 #define CMS_NO_SIGNING_TIME 0x400000 +#define CMS_VERIFY_PARTIAL 0x800000 const ASN1_OBJECT *CMS_get0_type(const CMS_ContentInfo *cms); @@ -118,7 +124,9 @@ int CMS_set_detached(CMS_ContentInfo *cms, int detached); #ifdef OPENSSL_PEM_H DECLARE_PEM_rw(CMS, CMS_ContentInfo) #endif -int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms); +#if !defined(OPENSSL_NO_DEPRECATED_4_1) +OSSL_DEPRECATEDIN_4_1 int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms); +#endif /* !defined(OPENSSL_NO_DEPRECATED_4_1) */ CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); @@ -289,6 +297,7 @@ EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si); STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms); void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer); +X509 *CMS_SignerInfo_get0_signer_cert(const CMS_SignerInfo *si); int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno); @@ -299,6 +308,7 @@ void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer, X509_ALGOR **pdig, X509_ALGOR **psig); ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si); +int CMS_SignerInfo_get_verification_result(const CMS_SignerInfo *si, int type); int CMS_SignerInfo_sign(CMS_SignerInfo *si); int CMS_SignerInfo_verify(CMS_SignerInfo *si); int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain); @@ -312,6 +322,8 @@ BIO *CMS_SignedData_verify(CMS_SignedData *sd, BIO *detached_data, int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs); int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, int algnid, int keysize); +int CMS_add_standard_smimecap_ex(STACK_OF(X509_ALGOR) **smcap, + OSSL_LIB_CTX *libctx, const char *propq); int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap); int CMS_signed_get_attr_count(const CMS_SignerInfo *si); diff --git a/include/openssl/cmserr.h b/include/openssl/cmserr.h deleted file mode 100644 index 49c22c2bddb49..0000000000000 --- a/include/openssl/cmserr.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_CMSERR_H -#define OPENSSL_CMSERR_H -#pragma once - -#include -#include -#include - -#ifndef OPENSSL_NO_CMS - -/* - * CMS reason codes. - */ -#define CMS_R_ADD_SIGNER_ERROR 99 -#define CMS_R_ATTRIBUTE_ERROR 161 -#define CMS_R_CERTIFICATE_ALREADY_PRESENT 175 -#define CMS_R_CERTIFICATE_HAS_NO_KEYID 160 -#define CMS_R_CERTIFICATE_VERIFY_ERROR 100 -#define CMS_R_CIPHER_AEAD_IN_ENVELOPED_DATA 200 -#define CMS_R_CIPHER_AEAD_SET_TAG_ERROR 184 -#define CMS_R_CIPHER_GET_TAG 185 -#define CMS_R_CIPHER_INITIALISATION_ERROR 101 -#define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 102 -#define CMS_R_CMS_DATAFINAL_ERROR 103 -#define CMS_R_CMS_LIB 104 -#define CMS_R_CONTENTIDENTIFIER_MISMATCH 170 -#define CMS_R_CONTENT_NOT_FOUND 105 -#define CMS_R_CONTENT_TYPE_MISMATCH 171 -#define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA 106 -#define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 107 -#define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA 108 -#define CMS_R_CONTENT_VERIFY_ERROR 109 -#define CMS_R_CTRL_ERROR 110 -#define CMS_R_CTRL_FAILURE 111 -#define CMS_R_DECODE_ERROR 187 -#define CMS_R_DECRYPT_ERROR 112 -#define CMS_R_ERROR_GETTING_PUBLIC_KEY 113 -#define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114 -#define CMS_R_ERROR_SETTING_KEY 115 -#define CMS_R_ERROR_SETTING_RECIPIENTINFO 116 -#define CMS_R_ERROR_UNSUPPORTED_STATIC_KEY_AGREEMENT 196 -#define CMS_R_ESS_SIGNING_CERTID_MISMATCH_ERROR 183 -#define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117 -#define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER 176 -#define CMS_R_INVALID_KEY_LENGTH 118 -#define CMS_R_INVALID_LABEL 190 -#define CMS_R_INVALID_OAEP_PARAMETERS 191 -#define CMS_R_KDF_PARAMETER_ERROR 186 -#define CMS_R_MD_BIO_INIT_ERROR 119 -#define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120 -#define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121 -#define CMS_R_MSGSIGDIGEST_ERROR 172 -#define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE 162 -#define CMS_R_MSGSIGDIGEST_WRONG_LENGTH 163 -#define CMS_R_NEED_ONE_SIGNER 164 -#define CMS_R_NOT_A_SIGNED_RECEIPT 165 -#define CMS_R_NOT_ENCRYPTED_DATA 122 -#define CMS_R_NOT_KEK 123 -#define CMS_R_NOT_KEM 197 -#define CMS_R_NOT_KEY_AGREEMENT 181 -#define CMS_R_NOT_KEY_TRANSPORT 124 -#define CMS_R_NOT_PWRI 177 -#define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125 -#define CMS_R_NO_CIPHER 126 -#define CMS_R_NO_CONTENT 127 -#define CMS_R_NO_CONTENT_TYPE 173 -#define CMS_R_NO_DEFAULT_DIGEST 128 -#define CMS_R_NO_DIGEST_SET 129 -#define CMS_R_NO_KEY 130 -#define CMS_R_NO_KEY_OR_CERT 174 -#define CMS_R_NO_MATCHING_DIGEST 131 -#define CMS_R_NO_MATCHING_RECIPIENT 132 -#define CMS_R_NO_MATCHING_SIGNATURE 166 -#define CMS_R_NO_MSGSIGDIGEST 167 -#define CMS_R_NO_PASSWORD 178 -#define CMS_R_NO_PRIVATE_KEY 133 -#define CMS_R_NO_PUBLIC_KEY 134 -#define CMS_R_NO_RECEIPT_REQUEST 168 -#define CMS_R_NO_SIGNERS 135 -#define CMS_R_OPERATION_UNSUPPORTED 182 -#define CMS_R_PEER_KEY_ERROR 188 -#define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136 -#define CMS_R_RECEIPT_DECODE_ERROR 169 -#define CMS_R_RECIPIENT_ERROR 137 -#define CMS_R_SHARED_INFO_ERROR 189 -#define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138 -#define CMS_R_SIGNFINAL_ERROR 139 -#define CMS_R_SMIME_TEXT_ERROR 140 -#define CMS_R_STORE_INIT_ERROR 141 -#define CMS_R_TYPE_NOT_COMPRESSED_DATA 142 -#define CMS_R_TYPE_NOT_DATA 143 -#define CMS_R_TYPE_NOT_DIGESTED_DATA 144 -#define CMS_R_TYPE_NOT_ENCRYPTED_DATA 145 -#define CMS_R_TYPE_NOT_ENVELOPED_DATA 146 -#define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 147 -#define CMS_R_UNKNOWN_CIPHER 148 -#define CMS_R_UNKNOWN_DIGEST_ALGORITHM 149 -#define CMS_R_UNKNOWN_ID 150 -#define CMS_R_UNKNOWN_KDF_ALGORITHM 198 -#define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151 -#define CMS_R_UNSUPPORTED_CONTENT_ENCRYPTION_ALGORITHM 194 -#define CMS_R_UNSUPPORTED_CONTENT_TYPE 152 -#define CMS_R_UNSUPPORTED_ENCRYPTION_TYPE 192 -#define CMS_R_UNSUPPORTED_KDF_ALGORITHM 199 -#define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153 -#define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM 179 -#define CMS_R_UNSUPPORTED_LABEL_SOURCE 193 -#define CMS_R_UNSUPPORTED_RECIPIENTINFO_TYPE 155 -#define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 154 -#define CMS_R_UNSUPPORTED_SIGNATURE_ALGORITHM 195 -#define CMS_R_UNSUPPORTED_TYPE 156 -#define CMS_R_UNWRAP_ERROR 157 -#define CMS_R_UNWRAP_FAILURE 180 -#define CMS_R_VERIFICATION_FAILURE 158 -#define CMS_R_WRAP_ERROR 159 - -#endif -#endif diff --git a/include/openssl/comperr.h b/include/openssl/comperr.h deleted file mode 100644 index 90ec7c1144be7..0000000000000 --- a/include/openssl/comperr.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_COMPERR_H -#define OPENSSL_COMPERR_H -#pragma once - -#include -#include -#include - -#ifndef OPENSSL_NO_COMP - -/* - * COMP reason codes. - */ -#define COMP_R_BROTLI_DECODE_ERROR 102 -#define COMP_R_BROTLI_ENCODE_ERROR 103 -#define COMP_R_BROTLI_NOT_SUPPORTED 104 -#define COMP_R_ZLIB_DEFLATE_ERROR 99 -#define COMP_R_ZLIB_INFLATE_ERROR 100 -#define COMP_R_ZLIB_NOT_SUPPORTED 101 -#define COMP_R_ZSTD_COMPRESS_ERROR 105 -#define COMP_R_ZSTD_DECODE_ERROR 106 -#define COMP_R_ZSTD_DECOMPRESS_ERROR 107 -#define COMP_R_ZSTD_NOT_SUPPORTED 108 - -#endif -#endif diff --git a/include/openssl/conferr.h b/include/openssl/conferr.h deleted file mode 100644 index 0b984dd65d4d0..0000000000000 --- a/include/openssl/conferr.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_CONFERR_H -#define OPENSSL_CONFERR_H -#pragma once - -#include -#include -#include - -/* - * CONF reason codes. - */ -#define CONF_R_ERROR_LOADING_DSO 110 -#define CONF_R_INVALID_PRAGMA 122 -#define CONF_R_LIST_CANNOT_BE_NULL 115 -#define CONF_R_MANDATORY_BRACES_IN_VARIABLE_EXPANSION 123 -#define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 100 -#define CONF_R_MISSING_EQUAL_SIGN 101 -#define CONF_R_MISSING_INIT_FUNCTION 112 -#define CONF_R_MODULE_INITIALIZATION_ERROR 109 -#define CONF_R_NO_CLOSE_BRACE 102 -#define CONF_R_NO_CONF 105 -#define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE 106 -#define CONF_R_NO_SECTION 107 -#define CONF_R_NO_SUCH_FILE 114 -#define CONF_R_NO_VALUE 108 -#define CONF_R_NUMBER_TOO_LARGE 121 -#define CONF_R_OPENSSL_CONF_REFERENCES_MISSING_SECTION 124 -#define CONF_R_RECURSIVE_DIRECTORY_INCLUDE 111 -#define CONF_R_RECURSIVE_SECTION_REFERENCE 126 -#define CONF_R_RELATIVE_PATH 125 -#define CONF_R_SSL_COMMAND_SECTION_EMPTY 117 -#define CONF_R_SSL_COMMAND_SECTION_NOT_FOUND 118 -#define CONF_R_SSL_SECTION_EMPTY 119 -#define CONF_R_SSL_SECTION_NOT_FOUND 120 -#define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 103 -#define CONF_R_UNKNOWN_MODULE_NAME 113 -#define CONF_R_VARIABLE_EXPANSION_TOO_LONG 116 -#define CONF_R_VARIABLE_HAS_NO_VALUE 104 - -#endif diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h index 1bab83d792215..176f8c426c66e 100644 --- a/include/openssl/core_dispatch.h +++ b/include/openssl/core_dispatch.h @@ -488,6 +488,8 @@ OSSL_CORE_MAKE_FUNC(int, mac_init_skey, (void *mctx, void *key, const OSSL_PARAM #define OSSL_FUNC_SKEYMGMT_GET_KEY_ID 5 #define OSSL_FUNC_SKEYMGMT_IMP_SETTABLE_PARAMS 6 #define OSSL_FUNC_SKEYMGMT_GEN_SETTABLE_PARAMS 7 +#define OSSL_FUNC_SKEYMGMT_GET_LOCAL_KEYID 8 +#define OSSL_FUNC_SKEYMGMT_GET_ALGORITHM_ID 9 OSSL_CORE_MAKE_FUNC(void, skeymgmt_free, (void *keydata)) OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, @@ -500,6 +502,12 @@ OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, skeymgmt_gen_settable_params, (void *provctx)) OSSL_CORE_MAKE_FUNC(void *, skeymgmt_generate, (void *provctx, const OSSL_PARAM params[])) OSSL_CORE_MAKE_FUNC(const char *, skeymgmt_get_key_id, (void *keydata)) +OSSL_CORE_MAKE_FUNC(int, skeymgmt_get_local_keyid, + (void *keydata, const unsigned char **id, size_t *len)) +OSSL_CORE_MAKE_FUNC(int, skeymgmt_get_algorithm_id, + (void *keydata, + const unsigned char **oid, size_t *oid_len, + const unsigned char **params, size_t *params_len)) /* KDFs and PRFs */ diff --git a/include/openssl/crmferr.h b/include/openssl/crmferr.h deleted file mode 100644 index dd957e9d04ae6..0000000000000 --- a/include/openssl/crmferr.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_CRMFERR_H -#define OPENSSL_CRMFERR_H -#pragma once - -#include -#include -#include - -#ifndef OPENSSL_NO_CRMF - -/* - * CRMF reason codes. - */ -#define CRMF_R_BAD_PBM_ITERATIONCOUNT 100 -#define CRMF_R_CMS_NOT_SUPPORTED 122 -#define CRMF_R_CRMFERROR 102 -#define CRMF_R_ERROR 103 -#define CRMF_R_ERROR_DECODING_CERTIFICATE 104 -#define CRMF_R_ERROR_DECODING_ENCRYPTEDKEY 123 -#define CRMF_R_ERROR_DECRYPTING_CERTIFICATE 105 -#define CRMF_R_ERROR_DECRYPTING_ENCRYPTEDKEY 124 -#define CRMF_R_ERROR_DECRYPTING_ENCRYPTEDVALUE 125 -#define CRMF_R_ERROR_DECRYPTING_SYMMETRIC_KEY 106 -#define CRMF_R_ERROR_SETTING_PURPOSE 126 -#define CRMF_R_ERROR_SIGNING_POPO 129 -#define CRMF_R_ERROR_VERIFYING_ENCRYPTEDKEY 127 -#define CRMF_R_FAILURE_OBTAINING_RANDOM 107 -#define CRMF_R_ITERATIONCOUNT_BELOW_100 108 -#define CRMF_R_MALFORMED_IV 101 -#define CRMF_R_NULL_ARGUMENT 109 -#define CRMF_R_POPOSKINPUT_NOT_SUPPORTED 113 -#define CRMF_R_POPO_INCONSISTENT_CENTRAL_KEYGEN 128 -#define CRMF_R_POPO_INCONSISTENT_PUBLIC_KEY 117 -#define CRMF_R_POPO_MISSING 121 -#define CRMF_R_POPO_MISSING_PUBLIC_KEY 118 -#define CRMF_R_POPO_MISSING_SUBJECT 119 -#define CRMF_R_POPO_RAVERIFIED_NOT_ACCEPTED 120 -#define CRMF_R_SETTING_MAC_ALGOR_FAILURE 110 -#define CRMF_R_SETTING_OWF_ALGOR_FAILURE 111 -#define CRMF_R_UNSUPPORTED_ALGORITHM 112 -#define CRMF_R_UNSUPPORTED_CIPHER 114 -#define CRMF_R_UNSUPPORTED_METHOD_FOR_CREATING_POPO 115 -#define CRMF_R_UNSUPPORTED_POPO_METHOD 116 - -#endif -#endif diff --git a/include/openssl/cryptoerr.h b/include/openssl/cryptoerr.h deleted file mode 100644 index 626e3e9be57bd..0000000000000 --- a/include/openssl/cryptoerr.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_CRYPTOERR_H -#define OPENSSL_CRYPTOERR_H -#pragma once - -#include -#include -#include - -/* - * CRYPTO reason codes. - */ -#define CRYPTO_R_BAD_ALGORITHM_NAME 117 -#define CRYPTO_R_CONFLICTING_NAMES 118 -#define CRYPTO_R_HEX_STRING_TOO_SHORT 121 -#define CRYPTO_R_ILLEGAL_HEX_DIGIT 102 -#define CRYPTO_R_INSUFFICIENT_DATA_SPACE 106 -#define CRYPTO_R_INSUFFICIENT_PARAM_SIZE 107 -#define CRYPTO_R_INSUFFICIENT_SECURE_DATA_SPACE 108 -#define CRYPTO_R_INTEGER_OVERFLOW 127 -#define CRYPTO_R_INVALID_NEGATIVE_VALUE 122 -#define CRYPTO_R_INVALID_NULL_ARGUMENT 109 -#define CRYPTO_R_INVALID_OSSL_PARAM_TYPE 110 -#define CRYPTO_R_NO_PARAMS_TO_MERGE 131 -#define CRYPTO_R_NO_SPACE_FOR_TERMINATING_NULL 128 -#define CRYPTO_R_ODD_NUMBER_OF_DIGITS 103 -#define CRYPTO_R_PARAM_CANNOT_BE_REPRESENTED_EXACTLY 123 -#define CRYPTO_R_PARAM_NOT_INTEGER_TYPE 124 -#define CRYPTO_R_PARAM_OF_INCOMPATIBLE_TYPE 129 -#define CRYPTO_R_PARAM_UNSIGNED_INTEGER_NEGATIVE_VALUE_UNSUPPORTED 125 -#define CRYPTO_R_PARAM_UNSUPPORTED_FLOATING_POINT_FORMAT 130 -#define CRYPTO_R_PARAM_VALUE_TOO_LARGE_FOR_DESTINATION 126 -#define CRYPTO_R_PROVIDER_ALREADY_EXISTS 104 -#define CRYPTO_R_PROVIDER_SECTION_ERROR 105 -#define CRYPTO_R_RANDOM_SECTION_ERROR 119 -#define CRYPTO_R_SECURE_MALLOC_FAILURE 111 -#define CRYPTO_R_STRING_TOO_LONG 112 -#define CRYPTO_R_TOO_MANY_BYTES 113 -#define CRYPTO_R_TOO_MANY_NAMES 132 -#define CRYPTO_R_TOO_MANY_RECORDS 114 -#define CRYPTO_R_TOO_SMALL_BUFFER 116 -#define CRYPTO_R_UNKNOWN_NAME_IN_RANDOM_SECTION 120 -#define CRYPTO_R_ZERO_LENGTH_NUMBER 115 - -#endif diff --git a/include/openssl/ct.h.in b/include/openssl/ct.h.in index 8c83f53a26222..4b0d866d2492c 100644 --- a/include/openssl/ct.h.in +++ b/include/openssl/ct.h.in @@ -1,7 +1,7 @@ /* * {- join("\n * ", @autowarntext) -} * - * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/cterr.h b/include/openssl/cterr.h deleted file mode 100644 index 950b7b388cc78..0000000000000 --- a/include/openssl/cterr.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_CTERR_H -#define OPENSSL_CTERR_H -#pragma once - -#include -#include -#include - -#ifndef OPENSSL_NO_CT - -/* - * CT reason codes. - */ -#define CT_R_BASE64_DECODE_ERROR 108 -#define CT_R_INVALID_LOG_ID_LENGTH 100 -#define CT_R_LOG_CONF_INVALID 109 -#define CT_R_LOG_CONF_INVALID_KEY 110 -#define CT_R_LOG_CONF_MISSING_DESCRIPTION 111 -#define CT_R_LOG_CONF_MISSING_KEY 112 -#define CT_R_LOG_KEY_INVALID 113 -#define CT_R_SCT_FUTURE_TIMESTAMP 116 -#define CT_R_SCT_INVALID 104 -#define CT_R_SCT_INVALID_SIGNATURE 107 -#define CT_R_SCT_LIST_INVALID 105 -#define CT_R_SCT_LOG_ID_MISMATCH 114 -#define CT_R_SCT_NOT_SET 106 -#define CT_R_SCT_UNSUPPORTED_VERSION 115 -#define CT_R_UNRECOGNIZED_SIGNATURE_NID 101 -#define CT_R_UNSUPPORTED_ENTRY_TYPE 102 -#define CT_R_UNSUPPORTED_VERSION 103 - -#endif -#endif diff --git a/include/openssl/decodererr.h b/include/openssl/decodererr.h deleted file mode 100644 index 5fdeace4f971a..0000000000000 --- a/include/openssl/decodererr.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_DECODERERR_H -#define OPENSSL_DECODERERR_H -#pragma once - -#include -#include -#include - -/* - * OSSL_DECODER reason codes. - */ -#define OSSL_DECODER_R_COULD_NOT_DECODE_OBJECT 101 -#define OSSL_DECODER_R_DECODER_NOT_FOUND 102 -#define OSSL_DECODER_R_MISSING_GET_PARAMS 100 - -#endif diff --git a/include/openssl/dherr.h b/include/openssl/dherr.h deleted file mode 100644 index 753659be16f82..0000000000000 --- a/include/openssl/dherr.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_DHERR_H -#define OPENSSL_DHERR_H -#pragma once - -#include -#include -#include - -#ifndef OPENSSL_NO_DH - -/* - * DH reason codes. - */ -#define DH_R_BAD_FFC_PARAMETERS 127 -#define DH_R_BAD_GENERATOR 101 -#define DH_R_BN_DECODE_ERROR 109 -#define DH_R_BN_ERROR 106 -#define DH_R_CHECK_INVALID_J_VALUE 115 -#define DH_R_CHECK_INVALID_Q_VALUE 116 -#define DH_R_CHECK_PUBKEY_INVALID 122 -#define DH_R_CHECK_PUBKEY_TOO_LARGE 123 -#define DH_R_CHECK_PUBKEY_TOO_SMALL 124 -#define DH_R_CHECK_P_NOT_PRIME 117 -#define DH_R_CHECK_P_NOT_SAFE_PRIME 118 -#define DH_R_CHECK_Q_NOT_PRIME 119 -#define DH_R_DECODE_ERROR 104 -#define DH_R_INVALID_PARAMETER_NAME 110 -#define DH_R_INVALID_PARAMETER_NID 114 -#define DH_R_INVALID_PUBKEY 102 -#define DH_R_INVALID_SECRET 128 -#define DH_R_INVALID_SIZE 129 -#define DH_R_KDF_PARAMETER_ERROR 112 -#define DH_R_KEYS_NOT_SET 108 -#define DH_R_MISSING_PUBKEY 125 -#define DH_R_MODULUS_TOO_LARGE 103 -#define DH_R_MODULUS_TOO_SMALL 126 -#define DH_R_NOT_SUITABLE_GENERATOR 120 -#define DH_R_NO_PARAMETERS_SET 107 -#define DH_R_NO_PRIVATE_VALUE 100 -#define DH_R_PARAMETER_ENCODING_ERROR 105 -#define DH_R_PEER_KEY_ERROR 111 -#define DH_R_Q_TOO_LARGE 130 -#define DH_R_SHARED_INFO_ERROR 113 -#define DH_R_UNABLE_TO_CHECK_GENERATOR 121 - -#endif -#endif diff --git a/include/openssl/dsaerr.h b/include/openssl/dsaerr.h deleted file mode 100644 index cc5f4bfbb7c3a..0000000000000 --- a/include/openssl/dsaerr.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_DSAERR_H -#define OPENSSL_DSAERR_H -#pragma once - -#include -#include -#include - -#ifndef OPENSSL_NO_DSA - -/* - * DSA reason codes. - */ -#define DSA_R_BAD_FFC_PARAMETERS 114 -#define DSA_R_BAD_Q_VALUE 102 -#define DSA_R_BN_DECODE_ERROR 108 -#define DSA_R_BN_ERROR 109 -#define DSA_R_DECODE_ERROR 104 -#define DSA_R_INVALID_DIGEST_TYPE 106 -#define DSA_R_INVALID_PARAMETERS 112 -#define DSA_R_MISSING_PARAMETERS 101 -#define DSA_R_MISSING_PRIVATE_KEY 111 -#define DSA_R_MODULUS_TOO_LARGE 103 -#define DSA_R_NO_PARAMETERS_SET 107 -#define DSA_R_PARAMETER_ENCODING_ERROR 105 -#define DSA_R_P_NOT_PRIME 115 -#define DSA_R_Q_NOT_PRIME 113 -#define DSA_R_SEED_LEN_SMALL 110 -#define DSA_R_TOO_MANY_RETRIES 116 - -#endif -#endif diff --git a/include/openssl/dtls1.h b/include/openssl/dtls1.h index 0b42948d02d8c..a0863556efc94 100644 --- a/include/openssl/dtls1.h +++ b/include/openssl/dtls1.h @@ -1,5 +1,5 @@ /* - * Copyright 2005-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -27,17 +27,19 @@ extern "C" { /* DTLS*_VERSION constants are defined in prov_ssl.h */ #ifndef OPENSSL_NO_DEPRECATED_3_0 #define DTLS_MIN_VERSION DTLS1_VERSION -#define DTLS_MAX_VERSION DTLS1_2_VERSION +#define DTLS_MAX_VERSION DTLS1_3_VERSION #endif #define DTLS1_VERSION_MAJOR 0xFE /* Special value for method supporting multiple versions */ #define DTLS_ANY_VERSION 0x1FFFF -/* lengths of messages */ +/* DTLS records and messages lengths and offsets */ #define DTLS1_COOKIE_LENGTH 255 +#define DTLS1_RT_HEADER_SEQ_OFFS 5 +#define DTLS1_RT_HEADER_SEQ_LEN 6 #define DTLS1_RT_HEADER_LENGTH 13 #define DTLS1_HM_HEADER_LENGTH 12 @@ -51,6 +53,18 @@ extern "C" { #define DTLS1_TMO_ALERT_COUNT 12 +/* DTLS 1.3 Unified header */ +#define DTLS13_UNI_HDR_FIXED_LENGTH 5 +#define DTLS13_UNI_HDR_FIX_BITS 0x20 +#define DTLS13_UNI_HDR_CID_BIT 0x10 +#define DTLS13_UNI_HDR_SEQ_BIT 0x08 +#define DTLS13_UNI_HDR_SEQ_OFF 1 +#define DTLS13_UNI_HDR_LEN_BIT 0x04 +#define DTLS13_UNI_HDR_FIX_BITS_MASK 0xe0 +#define DTLS13_UNI_HDR_EPOCH_BITS_MASK 0x03 + +#define DTLS13_CIPHERTEXT_MINSIZE 16 + #ifdef __cplusplus } #endif diff --git a/include/openssl/e_os2.h b/include/openssl/e_os2.h index f3cda73da168a..8cec931f55d59 100644 --- a/include/openssl/e_os2.h +++ b/include/openssl/e_os2.h @@ -284,6 +284,22 @@ typedef uint64_t ossl_uintmax_t; #define ossl_unused #endif +/* + * OPENSSL_NONSTRING: mark a char/unsigned char buffer object or struct field + * whose contents are not necessarily NUL terminated, so that misuse with C + * string functions (strlen(), strcpy(), "%s", ...) is diagnosed by compilers + * that support the attribute. It has no effect elsewhere. + */ +#if defined(__has_attribute) +#if __has_attribute(nonstring) +#define OPENSSL_NONSTRING __attribute__((nonstring)) +#else +#define OPENSSL_NONSTRING +#endif +#else +#define OPENSSL_NONSTRING +#endif + #ifdef __cplusplus } #endif diff --git a/include/openssl/e_ostime.h b/include/openssl/e_ostime.h index 21022eb2062be..2927aee409f0b 100644 --- a/include/openssl/e_ostime.h +++ b/include/openssl/e_ostime.h @@ -1,5 +1,5 @@ /* - * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/ecdh.h b/include/openssl/ecdh.h index 3781b82cfad97..8d8d0e6911792 100644 --- a/include/openssl/ecdh.h +++ b/include/openssl/ecdh.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/ecdsa.h b/include/openssl/ecdsa.h index e84dc60ed74c2..1fd6713f9736e 100644 --- a/include/openssl/ecdsa.h +++ b/include/openssl/ecdsa.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/ecerr.h b/include/openssl/ecerr.h deleted file mode 100644 index e4d26aa111512..0000000000000 --- a/include/openssl/ecerr.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_ECERR_H -#define OPENSSL_ECERR_H -#pragma once - -#include -#include -#include - -#ifndef OPENSSL_NO_EC - -/* - * EC reason codes. - */ -#define EC_R_ASN1_ERROR 115 -#define EC_R_BAD_SIGNATURE 156 -#define EC_R_BIGNUM_OUT_OF_RANGE 144 -#define EC_R_BUFFER_TOO_SMALL 100 -#define EC_R_CANNOT_INVERT 165 -#define EC_R_COORDINATES_OUT_OF_RANGE 146 -#define EC_R_CURVE_DOES_NOT_SUPPORT_ECDH 160 -#define EC_R_CURVE_DOES_NOT_SUPPORT_ECDSA 170 -#define EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING 159 -#define EC_R_DECODE_ERROR 142 -#define EC_R_DISCRIMINANT_IS_ZERO 118 -#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 -#define EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED 127 -#define EC_R_FAILED_MAKING_PUBLIC_KEY 166 -#define EC_R_FIELD_TOO_LARGE 143 -#define EC_R_GF2M_NOT_SUPPORTED 147 -#define EC_R_GROUP2PKPARAMETERS_FAILURE 120 -#define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 -#define EC_R_INCOMPATIBLE_OBJECTS 101 -#define EC_R_INVALID_A 168 -#define EC_R_INVALID_ARGUMENT 112 -#define EC_R_INVALID_B 169 -#define EC_R_INVALID_COFACTOR 171 -#define EC_R_INVALID_COMPRESSED_POINT 110 -#define EC_R_INVALID_COMPRESSION_BIT 109 -#define EC_R_INVALID_CURVE 141 -#define EC_R_INVALID_DIGEST 151 -#define EC_R_INVALID_DIGEST_TYPE 138 -#define EC_R_INVALID_ENCODING 102 -#define EC_R_INVALID_FIELD 103 -#define EC_R_INVALID_FORM 104 -#define EC_R_INVALID_GENERATOR 173 -#define EC_R_INVALID_GROUP_ORDER 122 -#define EC_R_INVALID_KEY 116 -#define EC_R_INVALID_LENGTH 117 -#define EC_R_INVALID_NAMED_GROUP_CONVERSION 174 -#define EC_R_INVALID_OUTPUT_LENGTH 161 -#define EC_R_INVALID_P 172 -#define EC_R_INVALID_PEER_KEY 133 -#define EC_R_INVALID_PENTANOMIAL_BASIS 132 -#define EC_R_INVALID_PRIVATE_KEY 123 -#define EC_R_INVALID_SEED 175 -#define EC_R_INVALID_TRINOMIAL_BASIS 137 -#define EC_R_KDF_PARAMETER_ERROR 148 -#define EC_R_KEYS_NOT_SET 140 -#define EC_R_LADDER_POST_FAILURE 136 -#define EC_R_LADDER_PRE_FAILURE 153 -#define EC_R_LADDER_STEP_FAILURE 162 -#define EC_R_MISSING_OID 167 -#define EC_R_MISSING_PARAMETERS 124 -#define EC_R_MISSING_PRIVATE_KEY 125 -#define EC_R_NEED_NEW_SETUP_VALUES 157 -#define EC_R_NOT_A_NIST_PRIME 135 -#define EC_R_NOT_IMPLEMENTED 126 -#define EC_R_NOT_INITIALIZED 111 -#define EC_R_NO_PARAMETERS_SET 139 -#define EC_R_NO_PRIVATE_VALUE 154 -#define EC_R_OPERATION_NOT_SUPPORTED 152 -#define EC_R_PASSED_NULL_PARAMETER 134 -#define EC_R_PEER_KEY_ERROR 149 -#define EC_R_POINT_ARITHMETIC_FAILURE 155 -#define EC_R_POINT_AT_INFINITY 106 -#define EC_R_POINT_COORDINATES_BLIND_FAILURE 163 -#define EC_R_POINT_IS_NOT_ON_CURVE 107 -#define EC_R_RANDOM_NUMBER_GENERATION_FAILED 158 -#define EC_R_SHARED_INFO_ERROR 150 -#define EC_R_SLOT_FULL 108 -#define EC_R_TOO_MANY_RETRIES 176 -#define EC_R_UNDEFINED_GENERATOR 113 -#define EC_R_UNDEFINED_ORDER 128 -#define EC_R_UNKNOWN_COFACTOR 164 -#define EC_R_UNKNOWN_GROUP 129 -#define EC_R_UNKNOWN_ORDER 114 -#define EC_R_UNSUPPORTED_FIELD 131 -#define EC_R_WRONG_CURVE_PARAMETERS 145 -#define EC_R_WRONG_ORDER 130 - -#endif -#endif diff --git a/include/openssl/encodererr.h b/include/openssl/encodererr.h deleted file mode 100644 index b895b6be322d8..0000000000000 --- a/include/openssl/encodererr.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_ENCODERERR_H -#define OPENSSL_ENCODERERR_H -#pragma once - -#include -#include -#include - -/* - * OSSL_ENCODER reason codes. - */ -#define OSSL_ENCODER_R_BAD_PARAMETER_VALUE 103 -#define OSSL_ENCODER_R_ENCODER_NOT_FOUND 101 -#define OSSL_ENCODER_R_INCORRECT_PROPERTY_QUERY 100 -#define OSSL_ENCODER_R_MISSING_GET_PARAMS 102 -#define OSSL_ENCODER_R_UNKNOWN_PARAMETER_NAME 104 - -#endif diff --git a/include/openssl/engine.h b/include/openssl/engine.h index b9d97e2083b18..27501b11a1ac8 100644 --- a/include/openssl/engine.h +++ b/include/openssl/engine.h @@ -1,5 +1,5 @@ /* - * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/include/openssl/esserr.h b/include/openssl/esserr.h deleted file mode 100644 index 46881293cb071..0000000000000 --- a/include/openssl/esserr.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_ESSERR_H -#define OPENSSL_ESSERR_H -#pragma once - -#include -#include -#include - -/* - * ESS reason codes. - */ -#define ESS_R_EMPTY_ESS_CERT_ID_LIST 107 -#define ESS_R_ESS_CERT_DIGEST_ERROR 103 -#define ESS_R_ESS_CERT_ID_NOT_FOUND 104 -#define ESS_R_ESS_CERT_ID_WRONG_ORDER 105 -#define ESS_R_ESS_DIGEST_ALG_UNKNOWN 106 -#define ESS_R_ESS_SIGNING_CERTIFICATE_ERROR 102 -#define ESS_R_ESS_SIGNING_CERT_ADD_ERROR 100 -#define ESS_R_ESS_SIGNING_CERT_V2_ADD_ERROR 101 -#define ESS_R_MISSING_SIGNING_CERTIFICATE_ATTRIBUTE 108 - -#endif diff --git a/include/openssl/evp.h b/include/openssl/evp.h.in similarity index 99% rename from include/openssl/evp.h rename to include/openssl/evp.h.in index dcbc5b26d36ae..7bad41ba7945c 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h.in @@ -7,6 +7,12 @@ * https://www.openssl.org/source/license.html */ +/* clang-format off */ +{- +use OpenSSL::stackhash qw(generate_stack_macros); +-} +/* clang-format on */ + #ifndef OPENSSL_EVP_H #define OPENSSL_EVP_H #pragma once @@ -118,6 +124,12 @@ extern "C" { #endif +/* clang-format off */ +{- + generate_stack_macros("EVP_SKEY"); +-} +/* clang-format on */ + int EVP_set_default_properties(OSSL_LIB_CTX *libctx, const char *propq); char *EVP_get1_default_properties(OSSL_LIB_CTX *libctx); int EVP_default_properties_is_fips_enabled(OSSL_LIB_CTX *libctx); @@ -1950,6 +1962,11 @@ const char *EVP_SKEY_get0_skeymgmt_name(const EVP_SKEY *skey); const char *EVP_SKEY_get0_provider_name(const EVP_SKEY *skey); EVP_SKEY *EVP_SKEY_to_provider(EVP_SKEY *skey, OSSL_LIB_CTX *libctx, OSSL_PROVIDER *prov, const char *propquery); +int EVP_SKEY_get0_local_keyid(const EVP_SKEY *skey, + const unsigned char **id, size_t *len); +int EVP_SKEY_get0_algorithm_id(const EVP_SKEY *skey, + const unsigned char **oid, size_t *oid_len, + const unsigned char **params, size_t *params_len); /* * The seemingly redundant expression (char *)(strstr(curve, "")) serves to diff --git a/include/openssl/evperr.h b/include/openssl/evperr.h deleted file mode 100644 index b3d2cb04efabe..0000000000000 --- a/include/openssl/evperr.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_EVPERR_H -#define OPENSSL_EVPERR_H -#pragma once - -#include -#include -#include - -/* - * EVP reason codes. - */ -#define EVP_R_AES_KEY_SETUP_FAILED 143 -#define EVP_R_ARIA_KEY_SETUP_FAILED 176 -#define EVP_R_BAD_ALGORITHM_NAME 200 -#define EVP_R_BAD_DECRYPT 100 -#define EVP_R_BAD_KEY_LENGTH 195 -#define EVP_R_BUFFER_TOO_SMALL 155 -#define EVP_R_CACHE_CONSTANTS_FAILED 225 -#define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157 -#define EVP_R_CANNOT_GET_PARAMETERS 197 -#define EVP_R_CANNOT_SET_PARAMETERS 198 -#define EVP_R_CIPHER_NOT_GCM_MODE 184 -#define EVP_R_CIPHER_PARAMETER_ERROR 122 -#define EVP_R_COMMAND_NOT_SUPPORTED 147 -#define EVP_R_CONFLICTING_ALGORITHM_NAME 201 -#define EVP_R_CONTEXT_FINALIZED 239 -#define EVP_R_COPY_ERROR 173 -#define EVP_R_CTRL_NOT_IMPLEMENTED 132 -#define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 -#define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 -#define EVP_R_DECODE_ERROR 114 -#define EVP_R_DEFAULT_QUERY_PARSE_ERROR 210 -#define EVP_R_DIFFERENT_KEY_TYPES 101 -#define EVP_R_DIFFERENT_PARAMETERS 153 -#define EVP_R_ERROR_LOADING_SECTION 165 -#define EVP_R_EXPECTING_AN_HMAC_KEY 174 -#define EVP_R_EXPECTING_AN_RSA_KEY 127 -#define EVP_R_EXPECTING_A_DH_KEY 128 -#define EVP_R_EXPECTING_A_DSA_KEY 129 -#define EVP_R_EXPECTING_A_ECX_KEY 219 -#define EVP_R_EXPECTING_A_EC_KEY 142 -#define EVP_R_EXPECTING_A_POLY1305_KEY 164 -#define EVP_R_EXPECTING_A_SIPHASH_KEY 175 -#define EVP_R_FINAL_ERROR 188 -#define EVP_R_GENERATE_ERROR 214 -#define EVP_R_GETTING_ALGORITHMIDENTIFIER_NOT_SUPPORTED 229 -#define EVP_R_GET_RAW_KEY_FAILED 182 -#define EVP_R_ILLEGAL_SCRYPT_PARAMETERS 171 -#define EVP_R_INACCESSIBLE_DOMAIN_PARAMETERS 204 -#define EVP_R_INACCESSIBLE_KEY 203 -#define EVP_R_INITIALIZATION_ERROR 134 -#define EVP_R_INPUT_NOT_INITIALIZED 111 -#define EVP_R_INVALID_CUSTOM_LENGTH 185 -#define EVP_R_INVALID_DIGEST 152 -#define EVP_R_INVALID_IV_LENGTH 194 -#define EVP_R_INVALID_KEY 163 -#define EVP_R_INVALID_KEY_LENGTH 130 -#define EVP_R_INVALID_LENGTH 221 -#define EVP_R_INVALID_NULL_ALGORITHM 218 -#define EVP_R_INVALID_OPERATION 148 -#define EVP_R_INVALID_PROVIDER_FUNCTIONS 193 -#define EVP_R_INVALID_SALT_LENGTH 186 -#define EVP_R_INVALID_SECRET_LENGTH 223 -#define EVP_R_INVALID_SEED_LENGTH 220 -#define EVP_R_INVALID_VALUE 222 -#define EVP_R_KEYMGMT_EXPORT_FAILURE 205 -#define EVP_R_KEY_SETUP_FAILED 180 -#define EVP_R_LOCKING_NOT_SUPPORTED 213 -#define EVP_R_MEMORY_LIMIT_EXCEEDED 172 -#define EVP_R_MESSAGE_DIGEST_IS_NULL 159 -#define EVP_R_METHOD_NOT_SUPPORTED 144 -#define EVP_R_MISSING_PARAMETERS 103 -#define EVP_R_NOT_ABLE_TO_COPY_CTX 190 -#define EVP_R_NOT_XOF_OR_INVALID_LENGTH 178 -#define EVP_R_NO_CIPHER_SET 131 -#define EVP_R_NO_DEFAULT_DIGEST 158 -#define EVP_R_NO_DIGEST_SET 139 -#define EVP_R_NO_IMPORT_FUNCTION 206 -#define EVP_R_NO_KEYMGMT_AVAILABLE 199 -#define EVP_R_NO_KEYMGMT_PRESENT 196 -#define EVP_R_NO_KEY_SET 154 -#define EVP_R_NO_OPERATION_SET 149 -#define EVP_R_NULL_MAC_PKEY_CTX 208 -#define EVP_R_ONLY_ONESHOT_SUPPORTED 177 -#define EVP_R_OPERATION_NOT_INITIALIZED 151 -#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 -#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_SIGNATURE_TYPE 226 -#define EVP_R_OUTPUT_WOULD_OVERFLOW 202 -#define EVP_R_PARAMETER_TOO_LARGE 187 -#define EVP_R_PARTIALLY_OVERLAPPING 162 -#define EVP_R_PBKDF2_ERROR 181 -#define EVP_R_PIPELINE_NOT_SUPPORTED 230 -#define EVP_R_PKEY_APPLICATION_ASN1_METHOD_ALREADY_REGISTERED 179 -#define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 -#define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 -#define EVP_R_PROVIDER_ASYM_CIPHER_FAILURE 232 -#define EVP_R_PROVIDER_ASYM_CIPHER_NOT_SUPPORTED 235 -#define EVP_R_PROVIDER_GET_CTX_PARAMS_NOT_SUPPORTED 238 -#define EVP_R_PROVIDER_KEYMGMT_FAILURE 233 -#define EVP_R_PROVIDER_KEYMGMT_NOT_SUPPORTED 236 -#define EVP_R_PROVIDER_SIGNATURE_FAILURE 234 -#define EVP_R_PROVIDER_SIGNATURE_NOT_SUPPORTED 237 -#define EVP_R_PUBLIC_KEY_NOT_RSA 106 -#define EVP_R_SETTING_XOF_FAILED 227 -#define EVP_R_SET_DEFAULT_PROPERTY_FAILURE 209 -#define EVP_R_SIGNATURE_TYPE_AND_KEY_TYPE_INCOMPATIBLE 228 -#define EVP_R_TOO_MANY_PIPES 231 -#define EVP_R_TOO_MANY_RECORDS 183 -#define EVP_R_UNABLE_TO_ENABLE_LOCKING 212 -#define EVP_R_UNABLE_TO_GET_MAXIMUM_REQUEST_SIZE 215 -#define EVP_R_UNABLE_TO_GET_RANDOM_STRENGTH 216 -#define EVP_R_UNABLE_TO_LOCK_CONTEXT 211 -#define EVP_R_UNABLE_TO_SET_CALLBACKS 217 -#define EVP_R_UNKNOWN_BITS 166 -#define EVP_R_UNKNOWN_CIPHER 160 -#define EVP_R_UNKNOWN_DIGEST 161 -#define EVP_R_UNKNOWN_KEY_TYPE 207 -#define EVP_R_UNKNOWN_MAX_SIZE 167 -#define EVP_R_UNKNOWN_OPTION 169 -#define EVP_R_UNKNOWN_PBE_ALGORITHM 121 -#define EVP_R_UNKNOWN_SECURITY_BITS 168 -#define EVP_R_UNSUPPORTED_ALGORITHM 156 -#define EVP_R_UNSUPPORTED_CIPHER 107 -#define EVP_R_UNSUPPORTED_KEYLENGTH 123 -#define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124 -#define EVP_R_UNSUPPORTED_KEY_SIZE 108 -#define EVP_R_UNSUPPORTED_KEY_TYPE 224 -#define EVP_R_UNSUPPORTED_NUMBER_OF_ROUNDS 135 -#define EVP_R_UNSUPPORTED_PRF 125 -#define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 118 -#define EVP_R_UNSUPPORTED_SALT_TYPE 126 -#define EVP_R_UPDATE_ERROR 189 -#define EVP_R_WRAP_MODE_NOT_ALLOWED 170 -#define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 -#define EVP_R_XTS_DATA_UNIT_IS_TOO_LARGE 191 -#define EVP_R_XTS_DUPLICATED_KEYS 192 - -#endif diff --git a/include/openssl/httperr.h b/include/openssl/httperr.h deleted file mode 100644 index 4c1cc6ad6bf77..0000000000000 --- a/include/openssl/httperr.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_HTTPERR_H -#define OPENSSL_HTTPERR_H -#pragma once - -#include -#include -#include - -/* - * HTTP reason codes. - */ -#define HTTP_R_ASN1_LEN_EXCEEDS_MAX_RESP_LEN 108 -#define HTTP_R_CONNECT_FAILURE 100 -#define HTTP_R_CONTENT_TYPE_MISMATCH 131 -#define HTTP_R_ERROR_PARSING_ASN1_LENGTH 109 -#define HTTP_R_ERROR_PARSING_CONTENT_LENGTH 119 -#define HTTP_R_ERROR_PARSING_URL 101 -#define HTTP_R_ERROR_RECEIVING 103 -#define HTTP_R_ERROR_SENDING 102 -#define HTTP_R_FAILED_READING_DATA 128 -#define HTTP_R_HEADER_PARSE_ERROR 126 -#define HTTP_R_INCONSISTENT_CONTENT_LENGTH 120 -#define HTTP_R_INVALID_PORT_NUMBER 123 -#define HTTP_R_INVALID_URL_PATH 125 -#define HTTP_R_INVALID_URL_SCHEME 124 -#define HTTP_R_MAX_RESP_LEN_EXCEEDED 117 -#define HTTP_R_MISSING_ASN1_ENCODING 110 -#define HTTP_R_MISSING_CONTENT_TYPE 121 -#define HTTP_R_MISSING_REDIRECT_LOCATION 111 -#define HTTP_R_RECEIVED_ERROR 105 -#define HTTP_R_RECEIVED_WRONG_HTTP_VERSION 106 -#define HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP 112 -#define HTTP_R_REDIRECTION_NOT_ENABLED 116 -#define HTTP_R_RESPONSE_LINE_TOO_LONG 113 -#define HTTP_R_RESPONSE_PARSE_ERROR 104 -#define HTTP_R_RESPONSE_TOO_MANY_HDRLINES 130 -#define HTTP_R_RETRY_TIMEOUT 129 -#define HTTP_R_SERVER_CANCELED_CONNECTION 127 -#define HTTP_R_SOCK_NOT_SUPPORTED 122 -#define HTTP_R_STATUS_CODE_UNSUPPORTED 114 -#define HTTP_R_TLS_NOT_ENABLED 107 -#define HTTP_R_TOO_MANY_REDIRECTIONS 115 -#define HTTP_R_UNEXPECTED_CONTENT_TYPE 118 - -#endif diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h index d49b22373e803..aee4aa1bc6014 100644 --- a/include/openssl/kdf.h +++ b/include/openssl/kdf.h @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -41,7 +41,7 @@ const EVP_KDF *EVP_KDF_CTX_get0_kdf(const EVP_KDF_CTX *ctx); EVP_KDF *EVP_KDF_CTX_get1_kdf(const EVP_KDF_CTX *ctx); #if !defined(OPENSSL_NO_DEPRECATED_4_1) -OSSL_DEPRECATEDIN_4_1_FOR("Use EVP_KDF_CTX_get0_kdf") +OSSL_DEPRECATEDIN_4_1_FOR("use EVP_KDF_CTX_get0_kdf()") const EVP_KDF *EVP_KDF_CTX_kdf(const EVP_KDF_CTX *ctx); #endif /* !OPENSSL_NO_DEPRECATED_4_1 */ diff --git a/include/openssl/macros.h b/include/openssl/macros.h index 7e820875e228a..96b832565428c 100644 --- a/include/openssl/macros.h +++ b/include/openssl/macros.h @@ -42,7 +42,7 @@ #define OSSL_DEPRECATED(since) \ __declspec(deprecated("Since OpenSSL " #since)) #define OSSL_DEPRECATED_FOR(since, message) \ - __declspec(deprecated("Since OpenSSL " #since ";" message)) + __declspec(deprecated("Since OpenSSL " #since "; " message)) #define OSSL_DEPRECATED_MESSAGE(message) __declspec(deprecated(message)) #elif _MSC_VER >= 1310 #define OSSL_DEPRECATED(since) __declspec(deprecated) @@ -56,7 +56,7 @@ #define OSSL_DEPRECATED(since) \ __attribute__((deprecated("Since OpenSSL " #since))) #define OSSL_DEPRECATED_FOR(since, message) \ - __attribute__((deprecated("Since OpenSSL " #since ";" message))) + __attribute__((deprecated("Since OpenSSL " #since "; " message))) #define OSSL_DEPRECATED_MESSAGE(message) __attribute__((deprecated(message))) #define OSSL_BEGIN_ALLOW_DEPRECATED \ _Pragma("GCC diagnostic push") \ diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h deleted file mode 100644 index fd43b9077ad0c..0000000000000 --- a/include/openssl/obj_mac.h +++ /dev/null @@ -1,6701 +0,0 @@ -/* - * WARNING: do not edit! - * Generated by crypto/objects/objects.pl - * - * Copyright 2000-2026 The OpenSSL Project Authors. All Rights Reserved. - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_OBJ_MAC_H -#define OPENSSL_OBJ_MAC_H -#pragma once - -/* clang-format off */ -#define SN_undef "UNDEF" -#define LN_undef "undefined" -#define NID_undef 0 -#define OBJ_undef 0L - -#define SN_itu_t "ITU-T" -#define LN_itu_t "itu-t" -#define NID_itu_t 645 -#define OBJ_itu_t 0L - -#define NID_ccitt 404 -#define OBJ_ccitt OBJ_itu_t - -#define SN_iso "ISO" -#define LN_iso "iso" -#define NID_iso 181 -#define OBJ_iso 1L - -#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T" -#define LN_joint_iso_itu_t "joint-iso-itu-t" -#define NID_joint_iso_itu_t 646 -#define OBJ_joint_iso_itu_t 2L - -#define NID_joint_iso_ccitt 393 -#define OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t - -#define SN_member_body "member-body" -#define LN_member_body "ISO Member Body" -#define NID_member_body 182 -#define OBJ_member_body OBJ_iso,2L - -#define SN_identified_organization "identified-organization" -#define NID_identified_organization 676 -#define OBJ_identified_organization OBJ_iso,3L - -#define SN_gmac "GMAC" -#define LN_gmac "gmac" -#define NID_gmac 1195 -#define OBJ_gmac OBJ_iso,0L,9797L,3L,4L - -#define SN_hmac_md5 "HMAC-MD5" -#define LN_hmac_md5 "hmac-md5" -#define NID_hmac_md5 780 -#define OBJ_hmac_md5 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L - -#define SN_hmac_sha1 "HMAC-SHA1" -#define LN_hmac_sha1 "hmac-sha1" -#define NID_hmac_sha1 781 -#define OBJ_hmac_sha1 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L - -#define SN_x509ExtAdmission "x509ExtAdmission" -#define LN_x509ExtAdmission "Professional Information or basis for Admission" -#define NID_x509ExtAdmission 1093 -#define OBJ_x509ExtAdmission OBJ_identified_organization,36L,8L,3L,3L - -#define SN_certicom_arc "certicom-arc" -#define NID_certicom_arc 677 -#define OBJ_certicom_arc OBJ_identified_organization,132L - -#define SN_ieee "ieee" -#define NID_ieee 1170 -#define OBJ_ieee OBJ_identified_organization,111L - -#define SN_ieee_siswg "ieee-siswg" -#define LN_ieee_siswg "IEEE Security in Storage Working Group" -#define NID_ieee_siswg 1171 -#define OBJ_ieee_siswg OBJ_ieee,2L,1619L - -#define SN_international_organizations "international-organizations" -#define LN_international_organizations "International Organizations" -#define NID_international_organizations 647 -#define OBJ_international_organizations OBJ_joint_iso_itu_t,23L - -#define SN_wap "wap" -#define NID_wap 678 -#define OBJ_wap OBJ_international_organizations,43L - -#define SN_wap_wsg "wap-wsg" -#define NID_wap_wsg 679 -#define OBJ_wap_wsg OBJ_wap,1L - -#define SN_selected_attribute_types "selected-attribute-types" -#define LN_selected_attribute_types "Selected Attribute Types" -#define NID_selected_attribute_types 394 -#define OBJ_selected_attribute_types OBJ_joint_iso_itu_t,5L,1L,5L - -#define SN_clearance "clearance" -#define NID_clearance 395 -#define OBJ_clearance OBJ_selected_attribute_types,55L - -#define SN_ISO_US "ISO-US" -#define LN_ISO_US "ISO US Member Body" -#define NID_ISO_US 183 -#define OBJ_ISO_US OBJ_member_body,840L - -#define SN_X9_57 "X9-57" -#define LN_X9_57 "X9.57" -#define NID_X9_57 184 -#define OBJ_X9_57 OBJ_ISO_US,10040L - -#define SN_X9cm "X9cm" -#define LN_X9cm "X9.57 CM ?" -#define NID_X9cm 185 -#define OBJ_X9cm OBJ_X9_57,4L - -#define SN_ISO_CN "ISO-CN" -#define LN_ISO_CN "ISO CN Member Body" -#define NID_ISO_CN 1140 -#define OBJ_ISO_CN OBJ_member_body,156L - -#define SN_oscca "oscca" -#define NID_oscca 1141 -#define OBJ_oscca OBJ_ISO_CN,10197L - -#define SN_sm_scheme "sm-scheme" -#define NID_sm_scheme 1142 -#define OBJ_sm_scheme OBJ_oscca,1L - -#define SN_dsa "DSA" -#define LN_dsa "dsaEncryption" -#define NID_dsa 116 -#define OBJ_dsa OBJ_X9cm,1L - -#define SN_dsaWithSHA1 "DSA-SHA1" -#define LN_dsaWithSHA1 "dsaWithSHA1" -#define NID_dsaWithSHA1 113 -#define OBJ_dsaWithSHA1 OBJ_X9cm,3L - -#define SN_ansi_X9_62 "ansi-X9-62" -#define LN_ansi_X9_62 "ANSI X9.62" -#define NID_ansi_X9_62 405 -#define OBJ_ansi_X9_62 OBJ_ISO_US,10045L - -#define OBJ_X9_62_id_fieldType OBJ_ansi_X9_62,1L - -#define SN_X9_62_prime_field "prime-field" -#define NID_X9_62_prime_field 406 -#define OBJ_X9_62_prime_field OBJ_X9_62_id_fieldType,1L - -#define SN_X9_62_characteristic_two_field "characteristic-two-field" -#define NID_X9_62_characteristic_two_field 407 -#define OBJ_X9_62_characteristic_two_field OBJ_X9_62_id_fieldType,2L - -#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis" -#define NID_X9_62_id_characteristic_two_basis 680 -#define OBJ_X9_62_id_characteristic_two_basis OBJ_X9_62_characteristic_two_field,3L - -#define SN_X9_62_onBasis "onBasis" -#define NID_X9_62_onBasis 681 -#define OBJ_X9_62_onBasis OBJ_X9_62_id_characteristic_two_basis,1L - -#define SN_X9_62_tpBasis "tpBasis" -#define NID_X9_62_tpBasis 682 -#define OBJ_X9_62_tpBasis OBJ_X9_62_id_characteristic_two_basis,2L - -#define SN_X9_62_ppBasis "ppBasis" -#define NID_X9_62_ppBasis 683 -#define OBJ_X9_62_ppBasis OBJ_X9_62_id_characteristic_two_basis,3L - -#define OBJ_X9_62_id_publicKeyType OBJ_ansi_X9_62,2L - -#define SN_X9_62_id_ecPublicKey "id-ecPublicKey" -#define NID_X9_62_id_ecPublicKey 408 -#define OBJ_X9_62_id_ecPublicKey OBJ_X9_62_id_publicKeyType,1L - -#define OBJ_X9_62_ellipticCurve OBJ_ansi_X9_62,3L - -#define OBJ_X9_62_c_TwoCurve OBJ_X9_62_ellipticCurve,0L - -#define SN_X9_62_c2pnb163v1 "c2pnb163v1" -#define NID_X9_62_c2pnb163v1 684 -#define OBJ_X9_62_c2pnb163v1 OBJ_X9_62_c_TwoCurve,1L - -#define SN_X9_62_c2pnb163v2 "c2pnb163v2" -#define NID_X9_62_c2pnb163v2 685 -#define OBJ_X9_62_c2pnb163v2 OBJ_X9_62_c_TwoCurve,2L - -#define SN_X9_62_c2pnb163v3 "c2pnb163v3" -#define NID_X9_62_c2pnb163v3 686 -#define OBJ_X9_62_c2pnb163v3 OBJ_X9_62_c_TwoCurve,3L - -#define SN_X9_62_c2pnb176v1 "c2pnb176v1" -#define NID_X9_62_c2pnb176v1 687 -#define OBJ_X9_62_c2pnb176v1 OBJ_X9_62_c_TwoCurve,4L - -#define SN_X9_62_c2tnb191v1 "c2tnb191v1" -#define NID_X9_62_c2tnb191v1 688 -#define OBJ_X9_62_c2tnb191v1 OBJ_X9_62_c_TwoCurve,5L - -#define SN_X9_62_c2tnb191v2 "c2tnb191v2" -#define NID_X9_62_c2tnb191v2 689 -#define OBJ_X9_62_c2tnb191v2 OBJ_X9_62_c_TwoCurve,6L - -#define SN_X9_62_c2tnb191v3 "c2tnb191v3" -#define NID_X9_62_c2tnb191v3 690 -#define OBJ_X9_62_c2tnb191v3 OBJ_X9_62_c_TwoCurve,7L - -#define SN_X9_62_c2onb191v4 "c2onb191v4" -#define NID_X9_62_c2onb191v4 691 -#define OBJ_X9_62_c2onb191v4 OBJ_X9_62_c_TwoCurve,8L - -#define SN_X9_62_c2onb191v5 "c2onb191v5" -#define NID_X9_62_c2onb191v5 692 -#define OBJ_X9_62_c2onb191v5 OBJ_X9_62_c_TwoCurve,9L - -#define SN_X9_62_c2pnb208w1 "c2pnb208w1" -#define NID_X9_62_c2pnb208w1 693 -#define OBJ_X9_62_c2pnb208w1 OBJ_X9_62_c_TwoCurve,10L - -#define SN_X9_62_c2tnb239v1 "c2tnb239v1" -#define NID_X9_62_c2tnb239v1 694 -#define OBJ_X9_62_c2tnb239v1 OBJ_X9_62_c_TwoCurve,11L - -#define SN_X9_62_c2tnb239v2 "c2tnb239v2" -#define NID_X9_62_c2tnb239v2 695 -#define OBJ_X9_62_c2tnb239v2 OBJ_X9_62_c_TwoCurve,12L - -#define SN_X9_62_c2tnb239v3 "c2tnb239v3" -#define NID_X9_62_c2tnb239v3 696 -#define OBJ_X9_62_c2tnb239v3 OBJ_X9_62_c_TwoCurve,13L - -#define SN_X9_62_c2onb239v4 "c2onb239v4" -#define NID_X9_62_c2onb239v4 697 -#define OBJ_X9_62_c2onb239v4 OBJ_X9_62_c_TwoCurve,14L - -#define SN_X9_62_c2onb239v5 "c2onb239v5" -#define NID_X9_62_c2onb239v5 698 -#define OBJ_X9_62_c2onb239v5 OBJ_X9_62_c_TwoCurve,15L - -#define SN_X9_62_c2pnb272w1 "c2pnb272w1" -#define NID_X9_62_c2pnb272w1 699 -#define OBJ_X9_62_c2pnb272w1 OBJ_X9_62_c_TwoCurve,16L - -#define SN_X9_62_c2pnb304w1 "c2pnb304w1" -#define NID_X9_62_c2pnb304w1 700 -#define OBJ_X9_62_c2pnb304w1 OBJ_X9_62_c_TwoCurve,17L - -#define SN_X9_62_c2tnb359v1 "c2tnb359v1" -#define NID_X9_62_c2tnb359v1 701 -#define OBJ_X9_62_c2tnb359v1 OBJ_X9_62_c_TwoCurve,18L - -#define SN_X9_62_c2pnb368w1 "c2pnb368w1" -#define NID_X9_62_c2pnb368w1 702 -#define OBJ_X9_62_c2pnb368w1 OBJ_X9_62_c_TwoCurve,19L - -#define SN_X9_62_c2tnb431r1 "c2tnb431r1" -#define NID_X9_62_c2tnb431r1 703 -#define OBJ_X9_62_c2tnb431r1 OBJ_X9_62_c_TwoCurve,20L - -#define OBJ_X9_62_primeCurve OBJ_X9_62_ellipticCurve,1L - -#define SN_X9_62_prime192v1 "prime192v1" -#define NID_X9_62_prime192v1 409 -#define OBJ_X9_62_prime192v1 OBJ_X9_62_primeCurve,1L - -#define SN_X9_62_prime192v2 "prime192v2" -#define NID_X9_62_prime192v2 410 -#define OBJ_X9_62_prime192v2 OBJ_X9_62_primeCurve,2L - -#define SN_X9_62_prime192v3 "prime192v3" -#define NID_X9_62_prime192v3 411 -#define OBJ_X9_62_prime192v3 OBJ_X9_62_primeCurve,3L - -#define SN_X9_62_prime239v1 "prime239v1" -#define NID_X9_62_prime239v1 412 -#define OBJ_X9_62_prime239v1 OBJ_X9_62_primeCurve,4L - -#define SN_X9_62_prime239v2 "prime239v2" -#define NID_X9_62_prime239v2 413 -#define OBJ_X9_62_prime239v2 OBJ_X9_62_primeCurve,5L - -#define SN_X9_62_prime239v3 "prime239v3" -#define NID_X9_62_prime239v3 414 -#define OBJ_X9_62_prime239v3 OBJ_X9_62_primeCurve,6L - -#define SN_X9_62_prime256v1 "prime256v1" -#define NID_X9_62_prime256v1 415 -#define OBJ_X9_62_prime256v1 OBJ_X9_62_primeCurve,7L - -#define OBJ_X9_62_id_ecSigType OBJ_ansi_X9_62,4L - -#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1" -#define NID_ecdsa_with_SHA1 416 -#define OBJ_ecdsa_with_SHA1 OBJ_X9_62_id_ecSigType,1L - -#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended" -#define NID_ecdsa_with_Recommended 791 -#define OBJ_ecdsa_with_Recommended OBJ_X9_62_id_ecSigType,2L - -#define SN_ecdsa_with_Specified "ecdsa-with-Specified" -#define NID_ecdsa_with_Specified 792 -#define OBJ_ecdsa_with_Specified OBJ_X9_62_id_ecSigType,3L - -#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224" -#define NID_ecdsa_with_SHA224 793 -#define OBJ_ecdsa_with_SHA224 OBJ_ecdsa_with_Specified,1L - -#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256" -#define NID_ecdsa_with_SHA256 794 -#define OBJ_ecdsa_with_SHA256 OBJ_ecdsa_with_Specified,2L - -#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384" -#define NID_ecdsa_with_SHA384 795 -#define OBJ_ecdsa_with_SHA384 OBJ_ecdsa_with_Specified,3L - -#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512" -#define NID_ecdsa_with_SHA512 796 -#define OBJ_ecdsa_with_SHA512 OBJ_ecdsa_with_Specified,4L - -#define OBJ_secg_ellipticCurve OBJ_certicom_arc,0L - -#define SN_secp112r1 "secp112r1" -#define NID_secp112r1 704 -#define OBJ_secp112r1 OBJ_secg_ellipticCurve,6L - -#define SN_secp112r2 "secp112r2" -#define NID_secp112r2 705 -#define OBJ_secp112r2 OBJ_secg_ellipticCurve,7L - -#define SN_secp128r1 "secp128r1" -#define NID_secp128r1 706 -#define OBJ_secp128r1 OBJ_secg_ellipticCurve,28L - -#define SN_secp128r2 "secp128r2" -#define NID_secp128r2 707 -#define OBJ_secp128r2 OBJ_secg_ellipticCurve,29L - -#define SN_secp160k1 "secp160k1" -#define NID_secp160k1 708 -#define OBJ_secp160k1 OBJ_secg_ellipticCurve,9L - -#define SN_secp160r1 "secp160r1" -#define NID_secp160r1 709 -#define OBJ_secp160r1 OBJ_secg_ellipticCurve,8L - -#define SN_secp160r2 "secp160r2" -#define NID_secp160r2 710 -#define OBJ_secp160r2 OBJ_secg_ellipticCurve,30L - -#define SN_secp192k1 "secp192k1" -#define NID_secp192k1 711 -#define OBJ_secp192k1 OBJ_secg_ellipticCurve,31L - -#define SN_secp224k1 "secp224k1" -#define NID_secp224k1 712 -#define OBJ_secp224k1 OBJ_secg_ellipticCurve,32L - -#define SN_secp224r1 "secp224r1" -#define NID_secp224r1 713 -#define OBJ_secp224r1 OBJ_secg_ellipticCurve,33L - -#define SN_secp256k1 "secp256k1" -#define NID_secp256k1 714 -#define OBJ_secp256k1 OBJ_secg_ellipticCurve,10L - -#define SN_secp384r1 "secp384r1" -#define NID_secp384r1 715 -#define OBJ_secp384r1 OBJ_secg_ellipticCurve,34L - -#define SN_secp521r1 "secp521r1" -#define NID_secp521r1 716 -#define OBJ_secp521r1 OBJ_secg_ellipticCurve,35L - -#define SN_sect113r1 "sect113r1" -#define NID_sect113r1 717 -#define OBJ_sect113r1 OBJ_secg_ellipticCurve,4L - -#define SN_sect113r2 "sect113r2" -#define NID_sect113r2 718 -#define OBJ_sect113r2 OBJ_secg_ellipticCurve,5L - -#define SN_sect131r1 "sect131r1" -#define NID_sect131r1 719 -#define OBJ_sect131r1 OBJ_secg_ellipticCurve,22L - -#define SN_sect131r2 "sect131r2" -#define NID_sect131r2 720 -#define OBJ_sect131r2 OBJ_secg_ellipticCurve,23L - -#define SN_sect163k1 "sect163k1" -#define NID_sect163k1 721 -#define OBJ_sect163k1 OBJ_secg_ellipticCurve,1L - -#define SN_sect163r1 "sect163r1" -#define NID_sect163r1 722 -#define OBJ_sect163r1 OBJ_secg_ellipticCurve,2L - -#define SN_sect163r2 "sect163r2" -#define NID_sect163r2 723 -#define OBJ_sect163r2 OBJ_secg_ellipticCurve,15L - -#define SN_sect193r1 "sect193r1" -#define NID_sect193r1 724 -#define OBJ_sect193r1 OBJ_secg_ellipticCurve,24L - -#define SN_sect193r2 "sect193r2" -#define NID_sect193r2 725 -#define OBJ_sect193r2 OBJ_secg_ellipticCurve,25L - -#define SN_sect233k1 "sect233k1" -#define NID_sect233k1 726 -#define OBJ_sect233k1 OBJ_secg_ellipticCurve,26L - -#define SN_sect233r1 "sect233r1" -#define NID_sect233r1 727 -#define OBJ_sect233r1 OBJ_secg_ellipticCurve,27L - -#define SN_sect239k1 "sect239k1" -#define NID_sect239k1 728 -#define OBJ_sect239k1 OBJ_secg_ellipticCurve,3L - -#define SN_sect283k1 "sect283k1" -#define NID_sect283k1 729 -#define OBJ_sect283k1 OBJ_secg_ellipticCurve,16L - -#define SN_sect283r1 "sect283r1" -#define NID_sect283r1 730 -#define OBJ_sect283r1 OBJ_secg_ellipticCurve,17L - -#define SN_sect409k1 "sect409k1" -#define NID_sect409k1 731 -#define OBJ_sect409k1 OBJ_secg_ellipticCurve,36L - -#define SN_sect409r1 "sect409r1" -#define NID_sect409r1 732 -#define OBJ_sect409r1 OBJ_secg_ellipticCurve,37L - -#define SN_sect571k1 "sect571k1" -#define NID_sect571k1 733 -#define OBJ_sect571k1 OBJ_secg_ellipticCurve,38L - -#define SN_sect571r1 "sect571r1" -#define NID_sect571r1 734 -#define OBJ_sect571r1 OBJ_secg_ellipticCurve,39L - -#define OBJ_wap_wsg_idm_ecid OBJ_wap_wsg,4L - -#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1" -#define NID_wap_wsg_idm_ecid_wtls1 735 -#define OBJ_wap_wsg_idm_ecid_wtls1 OBJ_wap_wsg_idm_ecid,1L - -#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3" -#define NID_wap_wsg_idm_ecid_wtls3 736 -#define OBJ_wap_wsg_idm_ecid_wtls3 OBJ_wap_wsg_idm_ecid,3L - -#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4" -#define NID_wap_wsg_idm_ecid_wtls4 737 -#define OBJ_wap_wsg_idm_ecid_wtls4 OBJ_wap_wsg_idm_ecid,4L - -#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5" -#define NID_wap_wsg_idm_ecid_wtls5 738 -#define OBJ_wap_wsg_idm_ecid_wtls5 OBJ_wap_wsg_idm_ecid,5L - -#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6" -#define NID_wap_wsg_idm_ecid_wtls6 739 -#define OBJ_wap_wsg_idm_ecid_wtls6 OBJ_wap_wsg_idm_ecid,6L - -#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7" -#define NID_wap_wsg_idm_ecid_wtls7 740 -#define OBJ_wap_wsg_idm_ecid_wtls7 OBJ_wap_wsg_idm_ecid,7L - -#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8" -#define NID_wap_wsg_idm_ecid_wtls8 741 -#define OBJ_wap_wsg_idm_ecid_wtls8 OBJ_wap_wsg_idm_ecid,8L - -#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9" -#define NID_wap_wsg_idm_ecid_wtls9 742 -#define OBJ_wap_wsg_idm_ecid_wtls9 OBJ_wap_wsg_idm_ecid,9L - -#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10" -#define NID_wap_wsg_idm_ecid_wtls10 743 -#define OBJ_wap_wsg_idm_ecid_wtls10 OBJ_wap_wsg_idm_ecid,10L - -#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11" -#define NID_wap_wsg_idm_ecid_wtls11 744 -#define OBJ_wap_wsg_idm_ecid_wtls11 OBJ_wap_wsg_idm_ecid,11L - -#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12" -#define NID_wap_wsg_idm_ecid_wtls12 745 -#define OBJ_wap_wsg_idm_ecid_wtls12 OBJ_wap_wsg_idm_ecid,12L - -#define SN_cast5_cbc "CAST5-CBC" -#define LN_cast5_cbc "cast5-cbc" -#define NID_cast5_cbc 108 -#define OBJ_cast5_cbc OBJ_ISO_US,113533L,7L,66L,10L - -#define SN_cast5_ecb "CAST5-ECB" -#define LN_cast5_ecb "cast5-ecb" -#define NID_cast5_ecb 109 - -#define SN_cast5_cfb64 "CAST5-CFB" -#define LN_cast5_cfb64 "cast5-cfb" -#define NID_cast5_cfb64 110 - -#define SN_cast5_ofb64 "CAST5-OFB" -#define LN_cast5_ofb64 "cast5-ofb" -#define NID_cast5_ofb64 111 - -#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" -#define NID_pbeWithMD5AndCast5_CBC 112 -#define OBJ_pbeWithMD5AndCast5_CBC OBJ_ISO_US,113533L,7L,66L,12L - -#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC" -#define LN_id_PasswordBasedMAC "password based MAC" -#define NID_id_PasswordBasedMAC 782 -#define OBJ_id_PasswordBasedMAC OBJ_ISO_US,113533L,7L,66L,13L - -#define SN_id_DHBasedMac "id-DHBasedMac" -#define LN_id_DHBasedMac "Diffie-Hellman based MAC" -#define NID_id_DHBasedMac 783 -#define OBJ_id_DHBasedMac OBJ_ISO_US,113533L,7L,66L,30L - -#define SN_rsadsi "rsadsi" -#define LN_rsadsi "RSA Data Security, Inc." -#define NID_rsadsi 1 -#define OBJ_rsadsi OBJ_ISO_US,113549L - -#define SN_pkcs "pkcs" -#define LN_pkcs "RSA Data Security, Inc. PKCS" -#define NID_pkcs 2 -#define OBJ_pkcs OBJ_rsadsi,1L - -#define SN_pkcs1 "pkcs1" -#define NID_pkcs1 186 -#define OBJ_pkcs1 OBJ_pkcs,1L - -#define LN_rsaEncryption "rsaEncryption" -#define NID_rsaEncryption 6 -#define OBJ_rsaEncryption OBJ_pkcs1,1L - -#define SN_md2WithRSAEncryption "RSA-MD2" -#define LN_md2WithRSAEncryption "md2WithRSAEncryption" -#define NID_md2WithRSAEncryption 7 -#define OBJ_md2WithRSAEncryption OBJ_pkcs1,2L - -#define SN_md4WithRSAEncryption "RSA-MD4" -#define LN_md4WithRSAEncryption "md4WithRSAEncryption" -#define NID_md4WithRSAEncryption 396 -#define OBJ_md4WithRSAEncryption OBJ_pkcs1,3L - -#define SN_md5WithRSAEncryption "RSA-MD5" -#define LN_md5WithRSAEncryption "md5WithRSAEncryption" -#define NID_md5WithRSAEncryption 8 -#define OBJ_md5WithRSAEncryption OBJ_pkcs1,4L - -#define SN_sha1WithRSAEncryption "RSA-SHA1" -#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" -#define NID_sha1WithRSAEncryption 65 -#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L - -#define SN_rsaesOaep "RSAES-OAEP" -#define LN_rsaesOaep "rsaesOaep" -#define NID_rsaesOaep 919 -#define OBJ_rsaesOaep OBJ_pkcs1,7L - -#define SN_mgf1 "MGF1" -#define LN_mgf1 "mgf1" -#define NID_mgf1 911 -#define OBJ_mgf1 OBJ_pkcs1,8L - -#define SN_pSpecified "PSPECIFIED" -#define LN_pSpecified "pSpecified" -#define NID_pSpecified 935 -#define OBJ_pSpecified OBJ_pkcs1,9L - -#define SN_rsassaPss "RSASSA-PSS" -#define LN_rsassaPss "rsassaPss" -#define NID_rsassaPss 912 -#define OBJ_rsassaPss OBJ_pkcs1,10L - -#define SN_sha256WithRSAEncryption "RSA-SHA256" -#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption" -#define NID_sha256WithRSAEncryption 668 -#define OBJ_sha256WithRSAEncryption OBJ_pkcs1,11L - -#define SN_sha384WithRSAEncryption "RSA-SHA384" -#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption" -#define NID_sha384WithRSAEncryption 669 -#define OBJ_sha384WithRSAEncryption OBJ_pkcs1,12L - -#define SN_sha512WithRSAEncryption "RSA-SHA512" -#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption" -#define NID_sha512WithRSAEncryption 670 -#define OBJ_sha512WithRSAEncryption OBJ_pkcs1,13L - -#define SN_sha224WithRSAEncryption "RSA-SHA224" -#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption" -#define NID_sha224WithRSAEncryption 671 -#define OBJ_sha224WithRSAEncryption OBJ_pkcs1,14L - -#define SN_sha512_224WithRSAEncryption "RSA-SHA512/224" -#define LN_sha512_224WithRSAEncryption "sha512-224WithRSAEncryption" -#define NID_sha512_224WithRSAEncryption 1145 -#define OBJ_sha512_224WithRSAEncryption OBJ_pkcs1,15L - -#define SN_sha512_256WithRSAEncryption "RSA-SHA512/256" -#define LN_sha512_256WithRSAEncryption "sha512-256WithRSAEncryption" -#define NID_sha512_256WithRSAEncryption 1146 -#define OBJ_sha512_256WithRSAEncryption OBJ_pkcs1,16L - -#define SN_pkcs3 "pkcs3" -#define NID_pkcs3 27 -#define OBJ_pkcs3 OBJ_pkcs,3L - -#define LN_dhKeyAgreement "dhKeyAgreement" -#define NID_dhKeyAgreement 28 -#define OBJ_dhKeyAgreement OBJ_pkcs3,1L - -#define SN_pkcs5 "pkcs5" -#define NID_pkcs5 187 -#define OBJ_pkcs5 OBJ_pkcs,5L - -#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" -#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" -#define NID_pbeWithMD2AndDES_CBC 9 -#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs5,1L - -#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" -#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" -#define NID_pbeWithMD5AndDES_CBC 10 -#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs5,3L - -#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" -#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" -#define NID_pbeWithMD2AndRC2_CBC 168 -#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs5,4L - -#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" -#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" -#define NID_pbeWithMD5AndRC2_CBC 169 -#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs5,6L - -#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" -#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" -#define NID_pbeWithSHA1AndDES_CBC 170 -#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs5,10L - -#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" -#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" -#define NID_pbeWithSHA1AndRC2_CBC 68 -#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs5,11L - -#define LN_id_pbkdf2 "PBKDF2" -#define NID_id_pbkdf2 69 -#define OBJ_id_pbkdf2 OBJ_pkcs5,12L - -#define LN_pbes2 "PBES2" -#define NID_pbes2 161 -#define OBJ_pbes2 OBJ_pkcs5,13L - -#define LN_pbmac1 "PBMAC1" -#define NID_pbmac1 162 -#define OBJ_pbmac1 OBJ_pkcs5,14L - -#define SN_pkcs7 "pkcs7" -#define NID_pkcs7 20 -#define OBJ_pkcs7 OBJ_pkcs,7L - -#define LN_pkcs7_data "pkcs7-data" -#define NID_pkcs7_data 21 -#define OBJ_pkcs7_data OBJ_pkcs7,1L - -#define LN_pkcs7_signed "pkcs7-signedData" -#define NID_pkcs7_signed 22 -#define OBJ_pkcs7_signed OBJ_pkcs7,2L - -#define LN_pkcs7_enveloped "pkcs7-envelopedData" -#define NID_pkcs7_enveloped 23 -#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L - -#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" -#define NID_pkcs7_signedAndEnveloped 24 -#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L - -#define LN_pkcs7_digest "pkcs7-digestData" -#define NID_pkcs7_digest 25 -#define OBJ_pkcs7_digest OBJ_pkcs7,5L - -#define LN_pkcs7_encrypted "pkcs7-encryptedData" -#define NID_pkcs7_encrypted 26 -#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L - -#define SN_pkcs9 "pkcs9" -#define NID_pkcs9 47 -#define OBJ_pkcs9 OBJ_pkcs,9L - -#define LN_pkcs9_emailAddress "emailAddress" -#define NID_pkcs9_emailAddress 48 -#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L - -#define LN_pkcs9_unstructuredName "unstructuredName" -#define NID_pkcs9_unstructuredName 49 -#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L - -#define LN_pkcs9_contentType "contentType" -#define NID_pkcs9_contentType 50 -#define OBJ_pkcs9_contentType OBJ_pkcs9,3L - -#define LN_pkcs9_messageDigest "messageDigest" -#define NID_pkcs9_messageDigest 51 -#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L - -#define LN_pkcs9_signingTime "signingTime" -#define NID_pkcs9_signingTime 52 -#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L - -#define LN_pkcs9_countersignature "countersignature" -#define NID_pkcs9_countersignature 53 -#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L - -#define LN_pkcs9_challengePassword "challengePassword" -#define NID_pkcs9_challengePassword 54 -#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L - -#define LN_pkcs9_unstructuredAddress "unstructuredAddress" -#define NID_pkcs9_unstructuredAddress 55 -#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L - -#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" -#define NID_pkcs9_extCertAttributes 56 -#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L - -#define SN_ext_req "extReq" -#define LN_ext_req "Extension Request" -#define NID_ext_req 172 -#define OBJ_ext_req OBJ_pkcs9,14L - -#define SN_SMIMECapabilities "SMIME-CAPS" -#define LN_SMIMECapabilities "S/MIME Capabilities" -#define NID_SMIMECapabilities 167 -#define OBJ_SMIMECapabilities OBJ_pkcs9,15L - -#define SN_SMIME "SMIME" -#define LN_SMIME "S/MIME" -#define NID_SMIME 188 -#define OBJ_SMIME OBJ_pkcs9,16L - -#define SN_id_smime_mod "id-smime-mod" -#define NID_id_smime_mod 189 -#define OBJ_id_smime_mod OBJ_SMIME,0L - -#define SN_id_smime_ct "id-smime-ct" -#define NID_id_smime_ct 190 -#define OBJ_id_smime_ct OBJ_SMIME,1L - -#define SN_id_smime_aa "id-smime-aa" -#define NID_id_smime_aa 191 -#define OBJ_id_smime_aa OBJ_SMIME,2L - -#define SN_id_smime_alg "id-smime-alg" -#define NID_id_smime_alg 192 -#define OBJ_id_smime_alg OBJ_SMIME,3L - -#define SN_id_smime_cd "id-smime-cd" -#define NID_id_smime_cd 193 -#define OBJ_id_smime_cd OBJ_SMIME,4L - -#define SN_id_smime_spq "id-smime-spq" -#define NID_id_smime_spq 194 -#define OBJ_id_smime_spq OBJ_SMIME,5L - -#define SN_id_smime_cti "id-smime-cti" -#define NID_id_smime_cti 195 -#define OBJ_id_smime_cti OBJ_SMIME,6L - -#define SN_id_smime_ori "id-smime-ori" -#define NID_id_smime_ori 1499 -#define OBJ_id_smime_ori OBJ_SMIME,13L - -#define SN_id_smime_mod_cms "id-smime-mod-cms" -#define NID_id_smime_mod_cms 196 -#define OBJ_id_smime_mod_cms OBJ_id_smime_mod,1L - -#define SN_id_smime_mod_ess "id-smime-mod-ess" -#define NID_id_smime_mod_ess 197 -#define OBJ_id_smime_mod_ess OBJ_id_smime_mod,2L - -#define SN_id_smime_mod_oid "id-smime-mod-oid" -#define NID_id_smime_mod_oid 198 -#define OBJ_id_smime_mod_oid OBJ_id_smime_mod,3L - -#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3" -#define NID_id_smime_mod_msg_v3 199 -#define OBJ_id_smime_mod_msg_v3 OBJ_id_smime_mod,4L - -#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88" -#define NID_id_smime_mod_ets_eSignature_88 200 -#define OBJ_id_smime_mod_ets_eSignature_88 OBJ_id_smime_mod,5L - -#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97" -#define NID_id_smime_mod_ets_eSignature_97 201 -#define OBJ_id_smime_mod_ets_eSignature_97 OBJ_id_smime_mod,6L - -#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88" -#define NID_id_smime_mod_ets_eSigPolicy_88 202 -#define OBJ_id_smime_mod_ets_eSigPolicy_88 OBJ_id_smime_mod,7L - -#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97" -#define NID_id_smime_mod_ets_eSigPolicy_97 203 -#define OBJ_id_smime_mod_ets_eSigPolicy_97 OBJ_id_smime_mod,8L - -#define SN_id_smime_ct_receipt "id-smime-ct-receipt" -#define NID_id_smime_ct_receipt 204 -#define OBJ_id_smime_ct_receipt OBJ_id_smime_ct,1L - -#define SN_id_smime_ct_authData "id-smime-ct-authData" -#define NID_id_smime_ct_authData 205 -#define OBJ_id_smime_ct_authData OBJ_id_smime_ct,2L - -#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert" -#define NID_id_smime_ct_publishCert 206 -#define OBJ_id_smime_ct_publishCert OBJ_id_smime_ct,3L - -#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo" -#define NID_id_smime_ct_TSTInfo 207 -#define OBJ_id_smime_ct_TSTInfo OBJ_id_smime_ct,4L - -#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo" -#define NID_id_smime_ct_TDTInfo 208 -#define OBJ_id_smime_ct_TDTInfo OBJ_id_smime_ct,5L - -#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo" -#define NID_id_smime_ct_contentInfo 209 -#define OBJ_id_smime_ct_contentInfo OBJ_id_smime_ct,6L - -#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData" -#define NID_id_smime_ct_DVCSRequestData 210 -#define OBJ_id_smime_ct_DVCSRequestData OBJ_id_smime_ct,7L - -#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData" -#define NID_id_smime_ct_DVCSResponseData 211 -#define OBJ_id_smime_ct_DVCSResponseData OBJ_id_smime_ct,8L - -#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData" -#define NID_id_smime_ct_compressedData 786 -#define OBJ_id_smime_ct_compressedData OBJ_id_smime_ct,9L - -#define SN_id_smime_ct_contentCollection "id-smime-ct-contentCollection" -#define NID_id_smime_ct_contentCollection 1058 -#define OBJ_id_smime_ct_contentCollection OBJ_id_smime_ct,19L - -#define SN_id_smime_ct_authEnvelopedData "id-smime-ct-authEnvelopedData" -#define NID_id_smime_ct_authEnvelopedData 1059 -#define OBJ_id_smime_ct_authEnvelopedData OBJ_id_smime_ct,23L - -#define SN_id_ct_routeOriginAuthz "id-ct-routeOriginAuthz" -#define NID_id_ct_routeOriginAuthz 1234 -#define OBJ_id_ct_routeOriginAuthz OBJ_id_smime_ct,24L - -#define SN_id_ct_rpkiManifest "id-ct-rpkiManifest" -#define NID_id_ct_rpkiManifest 1235 -#define OBJ_id_ct_rpkiManifest OBJ_id_smime_ct,26L - -#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF" -#define NID_id_ct_asciiTextWithCRLF 787 -#define OBJ_id_ct_asciiTextWithCRLF OBJ_id_smime_ct,27L - -#define SN_id_ct_xml "id-ct-xml" -#define NID_id_ct_xml 1060 -#define OBJ_id_ct_xml OBJ_id_smime_ct,28L - -#define SN_id_ct_rpkiGhostbusters "id-ct-rpkiGhostbusters" -#define NID_id_ct_rpkiGhostbusters 1236 -#define OBJ_id_ct_rpkiGhostbusters OBJ_id_smime_ct,35L - -#define SN_id_ct_resourceTaggedAttest "id-ct-resourceTaggedAttest" -#define NID_id_ct_resourceTaggedAttest 1237 -#define OBJ_id_ct_resourceTaggedAttest OBJ_id_smime_ct,36L - -#define SN_id_ct_geofeedCSVwithCRLF "id-ct-geofeedCSVwithCRLF" -#define NID_id_ct_geofeedCSVwithCRLF 1246 -#define OBJ_id_ct_geofeedCSVwithCRLF OBJ_id_smime_ct,47L - -#define SN_id_ct_signedChecklist "id-ct-signedChecklist" -#define NID_id_ct_signedChecklist 1247 -#define OBJ_id_ct_signedChecklist OBJ_id_smime_ct,48L - -#define SN_id_ct_ASPA "id-ct-ASPA" -#define NID_id_ct_ASPA 1250 -#define OBJ_id_ct_ASPA OBJ_id_smime_ct,49L - -#define SN_id_ct_signedTAL "id-ct-signedTAL" -#define NID_id_ct_signedTAL 1284 -#define OBJ_id_ct_signedTAL OBJ_id_smime_ct,50L - -#define SN_id_ct_rpkiSignedPrefixList "id-ct-rpkiSignedPrefixList" -#define NID_id_ct_rpkiSignedPrefixList 1320 -#define OBJ_id_ct_rpkiSignedPrefixList OBJ_id_smime_ct,51L - -#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" -#define NID_id_smime_aa_receiptRequest 212 -#define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L - -#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel" -#define NID_id_smime_aa_securityLabel 213 -#define OBJ_id_smime_aa_securityLabel OBJ_id_smime_aa,2L - -#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory" -#define NID_id_smime_aa_mlExpandHistory 214 -#define OBJ_id_smime_aa_mlExpandHistory OBJ_id_smime_aa,3L - -#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint" -#define NID_id_smime_aa_contentHint 215 -#define OBJ_id_smime_aa_contentHint OBJ_id_smime_aa,4L - -#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest" -#define NID_id_smime_aa_msgSigDigest 216 -#define OBJ_id_smime_aa_msgSigDigest OBJ_id_smime_aa,5L - -#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType" -#define NID_id_smime_aa_encapContentType 217 -#define OBJ_id_smime_aa_encapContentType OBJ_id_smime_aa,6L - -#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier" -#define NID_id_smime_aa_contentIdentifier 218 -#define OBJ_id_smime_aa_contentIdentifier OBJ_id_smime_aa,7L - -#define SN_id_smime_aa_macValue "id-smime-aa-macValue" -#define NID_id_smime_aa_macValue 219 -#define OBJ_id_smime_aa_macValue OBJ_id_smime_aa,8L - -#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels" -#define NID_id_smime_aa_equivalentLabels 220 -#define OBJ_id_smime_aa_equivalentLabels OBJ_id_smime_aa,9L - -#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference" -#define NID_id_smime_aa_contentReference 221 -#define OBJ_id_smime_aa_contentReference OBJ_id_smime_aa,10L - -#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref" -#define NID_id_smime_aa_encrypKeyPref 222 -#define OBJ_id_smime_aa_encrypKeyPref OBJ_id_smime_aa,11L - -#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate" -#define NID_id_smime_aa_signingCertificate 223 -#define OBJ_id_smime_aa_signingCertificate OBJ_id_smime_aa,12L - -#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts" -#define NID_id_smime_aa_smimeEncryptCerts 224 -#define OBJ_id_smime_aa_smimeEncryptCerts OBJ_id_smime_aa,13L - -#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken" -#define NID_id_smime_aa_timeStampToken 225 -#define OBJ_id_smime_aa_timeStampToken OBJ_id_smime_aa,14L - -#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId" -#define NID_id_smime_aa_ets_sigPolicyId 226 -#define OBJ_id_smime_aa_ets_sigPolicyId OBJ_id_smime_aa,15L - -#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType" -#define NID_id_smime_aa_ets_commitmentType 227 -#define OBJ_id_smime_aa_ets_commitmentType OBJ_id_smime_aa,16L - -#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation" -#define NID_id_smime_aa_ets_signerLocation 228 -#define OBJ_id_smime_aa_ets_signerLocation OBJ_id_smime_aa,17L - -#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr" -#define NID_id_smime_aa_ets_signerAttr 229 -#define OBJ_id_smime_aa_ets_signerAttr OBJ_id_smime_aa,18L - -#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert" -#define NID_id_smime_aa_ets_otherSigCert 230 -#define OBJ_id_smime_aa_ets_otherSigCert OBJ_id_smime_aa,19L - -#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp" -#define NID_id_smime_aa_ets_contentTimestamp 231 -#define OBJ_id_smime_aa_ets_contentTimestamp OBJ_id_smime_aa,20L - -#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs" -#define NID_id_smime_aa_ets_CertificateRefs 232 -#define OBJ_id_smime_aa_ets_CertificateRefs OBJ_id_smime_aa,21L - -#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs" -#define NID_id_smime_aa_ets_RevocationRefs 233 -#define OBJ_id_smime_aa_ets_RevocationRefs OBJ_id_smime_aa,22L - -#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues" -#define NID_id_smime_aa_ets_certValues 234 -#define OBJ_id_smime_aa_ets_certValues OBJ_id_smime_aa,23L - -#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues" -#define NID_id_smime_aa_ets_revocationValues 235 -#define OBJ_id_smime_aa_ets_revocationValues OBJ_id_smime_aa,24L - -#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp" -#define NID_id_smime_aa_ets_escTimeStamp 236 -#define OBJ_id_smime_aa_ets_escTimeStamp OBJ_id_smime_aa,25L - -#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp" -#define NID_id_smime_aa_ets_certCRLTimestamp 237 -#define OBJ_id_smime_aa_ets_certCRLTimestamp OBJ_id_smime_aa,26L - -#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp" -#define NID_id_smime_aa_ets_archiveTimeStamp 238 -#define OBJ_id_smime_aa_ets_archiveTimeStamp OBJ_id_smime_aa,27L - -#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType" -#define NID_id_smime_aa_signatureType 239 -#define OBJ_id_smime_aa_signatureType OBJ_id_smime_aa,28L - -#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc" -#define NID_id_smime_aa_dvcs_dvc 240 -#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L - -#define SN_id_aa_ets_attrCertificateRefs "id-aa-ets-attrCertificateRefs" -#define NID_id_aa_ets_attrCertificateRefs 1261 -#define OBJ_id_aa_ets_attrCertificateRefs OBJ_id_smime_aa,44L - -#define SN_id_aa_ets_attrRevocationRefs "id-aa-ets-attrRevocationRefs" -#define NID_id_aa_ets_attrRevocationRefs 1262 -#define OBJ_id_aa_ets_attrRevocationRefs OBJ_id_smime_aa,45L - -#define SN_id_smime_aa_signingCertificateV2 "id-smime-aa-signingCertificateV2" -#define NID_id_smime_aa_signingCertificateV2 1086 -#define OBJ_id_smime_aa_signingCertificateV2 OBJ_id_smime_aa,47L - -#define SN_id_aa_ets_archiveTimestampV2 "id-aa-ets-archiveTimestampV2" -#define NID_id_aa_ets_archiveTimestampV2 1280 -#define OBJ_id_aa_ets_archiveTimestampV2 OBJ_id_smime_aa,48L - -#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES" -#define NID_id_smime_alg_ESDHwith3DES 241 -#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L - -#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2" -#define NID_id_smime_alg_ESDHwithRC2 242 -#define OBJ_id_smime_alg_ESDHwithRC2 OBJ_id_smime_alg,2L - -#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap" -#define NID_id_smime_alg_3DESwrap 243 -#define OBJ_id_smime_alg_3DESwrap OBJ_id_smime_alg,3L - -#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap" -#define NID_id_smime_alg_RC2wrap 244 -#define OBJ_id_smime_alg_RC2wrap OBJ_id_smime_alg,4L - -#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH" -#define NID_id_smime_alg_ESDH 245 -#define OBJ_id_smime_alg_ESDH OBJ_id_smime_alg,5L - -#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap" -#define NID_id_smime_alg_CMS3DESwrap 246 -#define OBJ_id_smime_alg_CMS3DESwrap OBJ_id_smime_alg,6L - -#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap" -#define NID_id_smime_alg_CMSRC2wrap 247 -#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L - -#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK" -#define NID_id_alg_PWRI_KEK 893 -#define OBJ_id_alg_PWRI_KEK OBJ_id_smime_alg,9L - -#define SN_id_alg_hss_lms_hashsig "id-alg-hss-lms-hashsig" -#define NID_id_alg_hss_lms_hashsig 1501 -#define OBJ_id_alg_hss_lms_hashsig OBJ_id_smime_alg,17L - -#define SN_HKDF_SHA256 "id-alg-hkdf-with-sha256" -#define LN_HKDF_SHA256 "HKDF-SHA256" -#define NID_HKDF_SHA256 1496 -#define OBJ_HKDF_SHA256 OBJ_id_smime_alg,28L - -#define SN_HKDF_SHA384 "id-alg-hkdf-with-sha384" -#define LN_HKDF_SHA384 "HKDF-SHA384" -#define NID_HKDF_SHA384 1497 -#define OBJ_HKDF_SHA384 OBJ_id_smime_alg,29L - -#define SN_HKDF_SHA512 "id-alg-hkdf-with-sha512" -#define LN_HKDF_SHA512 "HKDF-SHA512" -#define NID_HKDF_SHA512 1498 -#define OBJ_HKDF_SHA512 OBJ_id_smime_alg,30L - -#define SN_id_smime_cd_ldap "id-smime-cd-ldap" -#define NID_id_smime_cd_ldap 248 -#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L - -#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri" -#define NID_id_smime_spq_ets_sqt_uri 249 -#define OBJ_id_smime_spq_ets_sqt_uri OBJ_id_smime_spq,1L - -#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice" -#define NID_id_smime_spq_ets_sqt_unotice 250 -#define OBJ_id_smime_spq_ets_sqt_unotice OBJ_id_smime_spq,2L - -#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin" -#define NID_id_smime_cti_ets_proofOfOrigin 251 -#define OBJ_id_smime_cti_ets_proofOfOrigin OBJ_id_smime_cti,1L - -#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt" -#define NID_id_smime_cti_ets_proofOfReceipt 252 -#define OBJ_id_smime_cti_ets_proofOfReceipt OBJ_id_smime_cti,2L - -#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery" -#define NID_id_smime_cti_ets_proofOfDelivery 253 -#define OBJ_id_smime_cti_ets_proofOfDelivery OBJ_id_smime_cti,3L - -#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender" -#define NID_id_smime_cti_ets_proofOfSender 254 -#define OBJ_id_smime_cti_ets_proofOfSender OBJ_id_smime_cti,4L - -#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval" -#define NID_id_smime_cti_ets_proofOfApproval 255 -#define OBJ_id_smime_cti_ets_proofOfApproval OBJ_id_smime_cti,5L - -#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation" -#define NID_id_smime_cti_ets_proofOfCreation 256 -#define OBJ_id_smime_cti_ets_proofOfCreation OBJ_id_smime_cti,6L - -#define SN_id_smime_ori_kem "id-smime-ori-kem" -#define NID_id_smime_ori_kem 1500 -#define OBJ_id_smime_ori_kem OBJ_id_smime_ori,3L - -#define LN_friendlyName "friendlyName" -#define NID_friendlyName 156 -#define OBJ_friendlyName OBJ_pkcs9,20L - -#define LN_localKeyID "localKeyID" -#define NID_localKeyID 157 -#define OBJ_localKeyID OBJ_pkcs9,21L - -#define OBJ_ms_corp 1L,3L,6L,1L,4L,1L,311L - -#define SN_ms_csp_name "CSPName" -#define LN_ms_csp_name "Microsoft CSP Name" -#define NID_ms_csp_name 417 -#define OBJ_ms_csp_name OBJ_ms_corp,17L,1L - -#define SN_LocalKeySet "LocalKeySet" -#define LN_LocalKeySet "Microsoft Local Key set" -#define NID_LocalKeySet 856 -#define OBJ_LocalKeySet OBJ_ms_corp,17L,2L - -#define OBJ_certTypes OBJ_pkcs9,22L - -#define LN_x509Certificate "x509Certificate" -#define NID_x509Certificate 158 -#define OBJ_x509Certificate OBJ_certTypes,1L - -#define LN_sdsiCertificate "sdsiCertificate" -#define NID_sdsiCertificate 159 -#define OBJ_sdsiCertificate OBJ_certTypes,2L - -#define OBJ_crlTypes OBJ_pkcs9,23L - -#define LN_x509Crl "x509Crl" -#define NID_x509Crl 160 -#define OBJ_x509Crl OBJ_crlTypes,1L - -#define SN_id_aa_CMSAlgorithmProtection "id-aa-CMSAlgorithmProtection" -#define NID_id_aa_CMSAlgorithmProtection 1263 -#define OBJ_id_aa_CMSAlgorithmProtection OBJ_pkcs9,52L - -#define OBJ_pkcs12 OBJ_pkcs,12L - -#define OBJ_pkcs12_pbeids OBJ_pkcs12,1L - -#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" -#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" -#define NID_pbe_WithSHA1And128BitRC4 144 -#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids,1L - -#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" -#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" -#define NID_pbe_WithSHA1And40BitRC4 145 -#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids,2L - -#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" -#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" -#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 -#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids,3L - -#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" -#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" -#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 -#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids,4L - -#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" -#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" -#define NID_pbe_WithSHA1And128BitRC2_CBC 148 -#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids,5L - -#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" -#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" -#define NID_pbe_WithSHA1And40BitRC2_CBC 149 -#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids,6L - -#define OBJ_pkcs12_Version1 OBJ_pkcs12,10L - -#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1,1L - -#define LN_keyBag "keyBag" -#define NID_keyBag 150 -#define OBJ_keyBag OBJ_pkcs12_BagIds,1L - -#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" -#define NID_pkcs8ShroudedKeyBag 151 -#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds,2L - -#define LN_certBag "certBag" -#define NID_certBag 152 -#define OBJ_certBag OBJ_pkcs12_BagIds,3L - -#define LN_crlBag "crlBag" -#define NID_crlBag 153 -#define OBJ_crlBag OBJ_pkcs12_BagIds,4L - -#define LN_secretBag "secretBag" -#define NID_secretBag 154 -#define OBJ_secretBag OBJ_pkcs12_BagIds,5L - -#define LN_safeContentsBag "safeContentsBag" -#define NID_safeContentsBag 155 -#define OBJ_safeContentsBag OBJ_pkcs12_BagIds,6L - -#define SN_md2 "MD2" -#define LN_md2 "md2" -#define NID_md2 3 -#define OBJ_md2 OBJ_rsadsi,2L,2L - -#define SN_md4 "MD4" -#define LN_md4 "md4" -#define NID_md4 257 -#define OBJ_md4 OBJ_rsadsi,2L,4L - -#define SN_md5 "MD5" -#define LN_md5 "md5" -#define NID_md5 4 -#define OBJ_md5 OBJ_rsadsi,2L,5L - -#define SN_md5_sha1 "MD5-SHA1" -#define LN_md5_sha1 "md5-sha1" -#define NID_md5_sha1 114 - -#define LN_hmacWithMD5 "hmacWithMD5" -#define NID_hmacWithMD5 797 -#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L - -#define LN_hmacWithSHA1 "hmacWithSHA1" -#define NID_hmacWithSHA1 163 -#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L - -#define SN_sm2 "SM2" -#define LN_sm2 "sm2" -#define NID_sm2 1172 -#define OBJ_sm2 OBJ_sm_scheme,301L - -#define SN_sm3 "SM3" -#define LN_sm3 "sm3" -#define NID_sm3 1143 -#define OBJ_sm3 OBJ_sm_scheme,401L - -#define SN_sm3WithRSAEncryption "RSA-SM3" -#define LN_sm3WithRSAEncryption "sm3WithRSAEncryption" -#define NID_sm3WithRSAEncryption 1144 -#define OBJ_sm3WithRSAEncryption OBJ_sm_scheme,504L - -#define SN_SM2_with_SM3 "SM2-SM3" -#define LN_SM2_with_SM3 "SM2-with-SM3" -#define NID_SM2_with_SM3 1204 -#define OBJ_SM2_with_SM3 OBJ_sm_scheme,501L - -#define LN_hmacWithSM3 "hmacWithSM3" -#define NID_hmacWithSM3 1281 -#define OBJ_hmacWithSM3 OBJ_sm3,3L,1L - -#define LN_hmacWithSHA224 "hmacWithSHA224" -#define NID_hmacWithSHA224 798 -#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L - -#define LN_hmacWithSHA256 "hmacWithSHA256" -#define NID_hmacWithSHA256 799 -#define OBJ_hmacWithSHA256 OBJ_rsadsi,2L,9L - -#define LN_hmacWithSHA384 "hmacWithSHA384" -#define NID_hmacWithSHA384 800 -#define OBJ_hmacWithSHA384 OBJ_rsadsi,2L,10L - -#define LN_hmacWithSHA512 "hmacWithSHA512" -#define NID_hmacWithSHA512 801 -#define OBJ_hmacWithSHA512 OBJ_rsadsi,2L,11L - -#define LN_hmacWithSHA512_224 "hmacWithSHA512-224" -#define NID_hmacWithSHA512_224 1193 -#define OBJ_hmacWithSHA512_224 OBJ_rsadsi,2L,12L - -#define LN_hmacWithSHA512_256 "hmacWithSHA512-256" -#define NID_hmacWithSHA512_256 1194 -#define OBJ_hmacWithSHA512_256 OBJ_rsadsi,2L,13L - -#define SN_rc2_cbc "RC2-CBC" -#define LN_rc2_cbc "rc2-cbc" -#define NID_rc2_cbc 37 -#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L - -#define SN_rc2_ecb "RC2-ECB" -#define LN_rc2_ecb "rc2-ecb" -#define NID_rc2_ecb 38 - -#define SN_rc2_cfb64 "RC2-CFB" -#define LN_rc2_cfb64 "rc2-cfb" -#define NID_rc2_cfb64 39 - -#define SN_rc2_ofb64 "RC2-OFB" -#define LN_rc2_ofb64 "rc2-ofb" -#define NID_rc2_ofb64 40 - -#define SN_rc2_40_cbc "RC2-40-CBC" -#define LN_rc2_40_cbc "rc2-40-cbc" -#define NID_rc2_40_cbc 98 - -#define SN_rc2_64_cbc "RC2-64-CBC" -#define LN_rc2_64_cbc "rc2-64-cbc" -#define NID_rc2_64_cbc 166 - -#define SN_rc4 "RC4" -#define LN_rc4 "rc4" -#define NID_rc4 5 -#define OBJ_rc4 OBJ_rsadsi,3L,4L - -#define SN_rc4_40 "RC4-40" -#define LN_rc4_40 "rc4-40" -#define NID_rc4_40 97 - -#define SN_des_ede3_cbc "DES-EDE3-CBC" -#define LN_des_ede3_cbc "des-ede3-cbc" -#define NID_des_ede3_cbc 44 -#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L - -#define SN_rc5_cbc "RC5-CBC" -#define LN_rc5_cbc "rc5-cbc" -#define NID_rc5_cbc 120 -#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L - -#define SN_rc5_ecb "RC5-ECB" -#define LN_rc5_ecb "rc5-ecb" -#define NID_rc5_ecb 121 - -#define SN_rc5_cfb64 "RC5-CFB" -#define LN_rc5_cfb64 "rc5-cfb" -#define NID_rc5_cfb64 122 - -#define SN_rc5_ofb64 "RC5-OFB" -#define LN_rc5_ofb64 "rc5-ofb" -#define NID_rc5_ofb64 123 - -#define SN_ms_ext_req "msExtReq" -#define LN_ms_ext_req "Microsoft Extension Request" -#define NID_ms_ext_req 171 -#define OBJ_ms_ext_req OBJ_ms_corp,2L,1L,14L - -#define SN_ms_code_ind "msCodeInd" -#define LN_ms_code_ind "Microsoft Individual Code Signing" -#define NID_ms_code_ind 134 -#define OBJ_ms_code_ind OBJ_ms_corp,2L,1L,21L - -#define SN_ms_code_com "msCodeCom" -#define LN_ms_code_com "Microsoft Commercial Code Signing" -#define NID_ms_code_com 135 -#define OBJ_ms_code_com OBJ_ms_corp,2L,1L,22L - -#define SN_ms_ctl_sign "msCTLSign" -#define LN_ms_ctl_sign "Microsoft Trust List Signing" -#define NID_ms_ctl_sign 136 -#define OBJ_ms_ctl_sign OBJ_ms_corp,10L,3L,1L - -#define SN_ms_sgc "msSGC" -#define LN_ms_sgc "Microsoft Server Gated Crypto" -#define NID_ms_sgc 137 -#define OBJ_ms_sgc OBJ_ms_corp,10L,3L,3L - -#define SN_ms_efs "msEFS" -#define LN_ms_efs "Microsoft Encrypted File System" -#define NID_ms_efs 138 -#define OBJ_ms_efs OBJ_ms_corp,10L,3L,4L - -#define SN_ms_smartcard_login "msSmartcardLogin" -#define LN_ms_smartcard_login "Microsoft Smartcard Login" -#define NID_ms_smartcard_login 648 -#define OBJ_ms_smartcard_login OBJ_ms_corp,20L,2L,2L - -#define SN_ms_upn "msUPN" -#define LN_ms_upn "Microsoft User Principal Name" -#define NID_ms_upn 649 -#define OBJ_ms_upn OBJ_ms_corp,20L,2L,3L - -#define SN_ms_ntds_sec_ext "ms-ntds-sec-ext" -#define LN_ms_ntds_sec_ext "Microsoft NTDS CA Extension" -#define NID_ms_ntds_sec_ext 1292 -#define OBJ_ms_ntds_sec_ext OBJ_ms_corp,25L,2L - -#define SN_ms_ntds_obj_sid "ms-ntds-obj-sid" -#define LN_ms_ntds_obj_sid "Microsoft NTDS AD objectSid" -#define NID_ms_ntds_obj_sid 1291 -#define OBJ_ms_ntds_obj_sid OBJ_ms_corp,25L,2L,1L - -#define SN_ms_cert_templ "ms-cert-templ" -#define LN_ms_cert_templ "Microsoft certificate template" -#define NID_ms_cert_templ 1293 -#define OBJ_ms_cert_templ OBJ_ms_corp,21L,7L - -#define SN_ms_app_policies "ms-app-policies" -#define LN_ms_app_policies "Microsoft Application Policies Extension" -#define NID_ms_app_policies 1294 -#define OBJ_ms_app_policies OBJ_ms_corp,21L,10L - -#define SN_idea_cbc "IDEA-CBC" -#define LN_idea_cbc "idea-cbc" -#define NID_idea_cbc 34 -#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L - -#define SN_idea_ecb "IDEA-ECB" -#define LN_idea_ecb "idea-ecb" -#define NID_idea_ecb 36 - -#define SN_idea_cfb64 "IDEA-CFB" -#define LN_idea_cfb64 "idea-cfb" -#define NID_idea_cfb64 35 - -#define SN_idea_ofb64 "IDEA-OFB" -#define LN_idea_ofb64 "idea-ofb" -#define NID_idea_ofb64 46 - -#define SN_bf_cbc "BF-CBC" -#define LN_bf_cbc "bf-cbc" -#define NID_bf_cbc 91 -#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L - -#define SN_bf_ecb "BF-ECB" -#define LN_bf_ecb "bf-ecb" -#define NID_bf_ecb 92 - -#define SN_bf_cfb64 "BF-CFB" -#define LN_bf_cfb64 "bf-cfb" -#define NID_bf_cfb64 93 - -#define SN_bf_ofb64 "BF-OFB" -#define LN_bf_ofb64 "bf-ofb" -#define NID_bf_ofb64 94 - -#define SN_id_pkix "PKIX" -#define NID_id_pkix 127 -#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L - -#define SN_id_pkix_mod "id-pkix-mod" -#define NID_id_pkix_mod 258 -#define OBJ_id_pkix_mod OBJ_id_pkix,0L - -#define SN_id_pe "id-pe" -#define NID_id_pe 175 -#define OBJ_id_pe OBJ_id_pkix,1L - -#define SN_id_qt "id-qt" -#define NID_id_qt 259 -#define OBJ_id_qt OBJ_id_pkix,2L - -#define SN_id_kp "id-kp" -#define NID_id_kp 128 -#define OBJ_id_kp OBJ_id_pkix,3L - -#define SN_id_it "id-it" -#define NID_id_it 260 -#define OBJ_id_it OBJ_id_pkix,4L - -#define SN_id_pkip "id-pkip" -#define NID_id_pkip 261 -#define OBJ_id_pkip OBJ_id_pkix,5L - -#define SN_id_alg "id-alg" -#define NID_id_alg 262 -#define OBJ_id_alg OBJ_id_pkix,6L - -#define SN_id_cmc "id-cmc" -#define NID_id_cmc 263 -#define OBJ_id_cmc OBJ_id_pkix,7L - -#define SN_id_on "id-on" -#define NID_id_on 264 -#define OBJ_id_on OBJ_id_pkix,8L - -#define SN_id_pda "id-pda" -#define NID_id_pda 265 -#define OBJ_id_pda OBJ_id_pkix,9L - -#define SN_id_aca "id-aca" -#define NID_id_aca 266 -#define OBJ_id_aca OBJ_id_pkix,10L - -#define SN_id_qcs "id-qcs" -#define NID_id_qcs 267 -#define OBJ_id_qcs OBJ_id_pkix,11L - -#define SN_id_cp "id-cp" -#define NID_id_cp 1238 -#define OBJ_id_cp OBJ_id_pkix,14L - -#define SN_id_cct "id-cct" -#define NID_id_cct 268 -#define OBJ_id_cct OBJ_id_pkix,12L - -#define SN_id_ppl "id-ppl" -#define NID_id_ppl 662 -#define OBJ_id_ppl OBJ_id_pkix,21L - -#define SN_id_ad "id-ad" -#define NID_id_ad 176 -#define OBJ_id_ad OBJ_id_pkix,48L - -#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88" -#define NID_id_pkix1_explicit_88 269 -#define OBJ_id_pkix1_explicit_88 OBJ_id_pkix_mod,1L - -#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88" -#define NID_id_pkix1_implicit_88 270 -#define OBJ_id_pkix1_implicit_88 OBJ_id_pkix_mod,2L - -#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93" -#define NID_id_pkix1_explicit_93 271 -#define OBJ_id_pkix1_explicit_93 OBJ_id_pkix_mod,3L - -#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93" -#define NID_id_pkix1_implicit_93 272 -#define OBJ_id_pkix1_implicit_93 OBJ_id_pkix_mod,4L - -#define SN_id_mod_crmf "id-mod-crmf" -#define NID_id_mod_crmf 273 -#define OBJ_id_mod_crmf OBJ_id_pkix_mod,5L - -#define SN_id_mod_cmc "id-mod-cmc" -#define NID_id_mod_cmc 274 -#define OBJ_id_mod_cmc OBJ_id_pkix_mod,6L - -#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88" -#define NID_id_mod_kea_profile_88 275 -#define OBJ_id_mod_kea_profile_88 OBJ_id_pkix_mod,7L - -#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93" -#define NID_id_mod_kea_profile_93 276 -#define OBJ_id_mod_kea_profile_93 OBJ_id_pkix_mod,8L - -#define SN_id_mod_cmp "id-mod-cmp" -#define NID_id_mod_cmp 277 -#define OBJ_id_mod_cmp OBJ_id_pkix_mod,9L - -#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88" -#define NID_id_mod_qualified_cert_88 278 -#define OBJ_id_mod_qualified_cert_88 OBJ_id_pkix_mod,10L - -#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93" -#define NID_id_mod_qualified_cert_93 279 -#define OBJ_id_mod_qualified_cert_93 OBJ_id_pkix_mod,11L - -#define SN_id_mod_attribute_cert "id-mod-attribute-cert" -#define NID_id_mod_attribute_cert 280 -#define OBJ_id_mod_attribute_cert OBJ_id_pkix_mod,12L - -#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol" -#define NID_id_mod_timestamp_protocol 281 -#define OBJ_id_mod_timestamp_protocol OBJ_id_pkix_mod,13L - -#define SN_id_mod_ocsp "id-mod-ocsp" -#define NID_id_mod_ocsp 282 -#define OBJ_id_mod_ocsp OBJ_id_pkix_mod,14L - -#define SN_id_mod_dvcs "id-mod-dvcs" -#define NID_id_mod_dvcs 283 -#define OBJ_id_mod_dvcs OBJ_id_pkix_mod,15L - -#define SN_id_mod_cmp2000 "id-mod-cmp2000" -#define NID_id_mod_cmp2000 284 -#define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L - -#define SN_id_mod_cmp2000_02 "id-mod-cmp2000-02" -#define NID_id_mod_cmp2000_02 1251 -#define OBJ_id_mod_cmp2000_02 OBJ_id_pkix_mod,50L - -#define SN_id_mod_cmp2021_88 "id-mod-cmp2021-88" -#define NID_id_mod_cmp2021_88 1252 -#define OBJ_id_mod_cmp2021_88 OBJ_id_pkix_mod,99L - -#define SN_id_mod_cmp2021_02 "id-mod-cmp2021-02" -#define NID_id_mod_cmp2021_02 1253 -#define OBJ_id_mod_cmp2021_02 OBJ_id_pkix_mod,100L - -#define SN_info_access "authorityInfoAccess" -#define LN_info_access "Authority Information Access" -#define NID_info_access 177 -#define OBJ_info_access OBJ_id_pe,1L - -#define SN_biometricInfo "biometricInfo" -#define LN_biometricInfo "Biometric Info" -#define NID_biometricInfo 285 -#define OBJ_biometricInfo OBJ_id_pe,2L - -#define SN_qcStatements "qcStatements" -#define NID_qcStatements 286 -#define OBJ_qcStatements OBJ_id_pe,3L - -#define SN_ac_auditIdentity "ac-auditIdentity" -#define LN_ac_auditIdentity "X509v3 Audit Identity" -#define NID_ac_auditIdentity 287 -#define OBJ_ac_auditIdentity OBJ_id_pe,4L - -#define NID_ac_auditEntity 1323 -#define OBJ_ac_auditEntity OBJ_ac_auditIdentity - -#define SN_ac_targeting "ac-targeting" -#define NID_ac_targeting 288 -#define OBJ_ac_targeting OBJ_id_pe,5L - -#define SN_aaControls "aaControls" -#define NID_aaControls 289 -#define OBJ_aaControls OBJ_id_pe,6L - -#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock" -#define NID_sbgp_ipAddrBlock 290 -#define OBJ_sbgp_ipAddrBlock OBJ_id_pe,7L - -#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum" -#define NID_sbgp_autonomousSysNum 291 -#define OBJ_sbgp_autonomousSysNum OBJ_id_pe,8L - -#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier" -#define NID_sbgp_routerIdentifier 292 -#define OBJ_sbgp_routerIdentifier OBJ_id_pe,9L - -#define SN_ac_proxying "ac-proxying" -#define NID_ac_proxying 397 -#define OBJ_ac_proxying OBJ_id_pe,10L - -#define SN_sinfo_access "subjectInfoAccess" -#define LN_sinfo_access "Subject Information Access" -#define NID_sinfo_access 398 -#define OBJ_sinfo_access OBJ_id_pe,11L - -#define SN_proxyCertInfo "proxyCertInfo" -#define LN_proxyCertInfo "Proxy Certificate Information" -#define NID_proxyCertInfo 663 -#define OBJ_proxyCertInfo OBJ_id_pe,14L - -#define SN_tlsfeature "tlsfeature" -#define LN_tlsfeature "TLS Feature" -#define NID_tlsfeature 1020 -#define OBJ_tlsfeature OBJ_id_pe,24L - -#define SN_sbgp_ipAddrBlockv2 "sbgp-ipAddrBlockv2" -#define NID_sbgp_ipAddrBlockv2 1239 -#define OBJ_sbgp_ipAddrBlockv2 OBJ_id_pe,28L - -#define SN_sbgp_autonomousSysNumv2 "sbgp-autonomousSysNumv2" -#define NID_sbgp_autonomousSysNumv2 1240 -#define OBJ_sbgp_autonomousSysNumv2 OBJ_id_pe,29L - -#define SN_id_qt_cps "id-qt-cps" -#define LN_id_qt_cps "Policy Qualifier CPS" -#define NID_id_qt_cps 164 -#define OBJ_id_qt_cps OBJ_id_qt,1L - -#define SN_id_qt_unotice "id-qt-unotice" -#define LN_id_qt_unotice "Policy Qualifier User Notice" -#define NID_id_qt_unotice 165 -#define OBJ_id_qt_unotice OBJ_id_qt,2L - -#define SN_textNotice "textNotice" -#define NID_textNotice 293 -#define OBJ_textNotice OBJ_id_qt,3L - -#define SN_server_auth "serverAuth" -#define LN_server_auth "TLS Web Server Authentication" -#define NID_server_auth 129 -#define OBJ_server_auth OBJ_id_kp,1L - -#define SN_client_auth "clientAuth" -#define LN_client_auth "TLS Web Client Authentication" -#define NID_client_auth 130 -#define OBJ_client_auth OBJ_id_kp,2L - -#define SN_code_sign "codeSigning" -#define LN_code_sign "Code Signing" -#define NID_code_sign 131 -#define OBJ_code_sign OBJ_id_kp,3L - -#define SN_email_protect "emailProtection" -#define LN_email_protect "E-mail Protection" -#define NID_email_protect 132 -#define OBJ_email_protect OBJ_id_kp,4L - -#define SN_ipsecEndSystem "ipsecEndSystem" -#define LN_ipsecEndSystem "IPSec End System" -#define NID_ipsecEndSystem 294 -#define OBJ_ipsecEndSystem OBJ_id_kp,5L - -#define SN_ipsecTunnel "ipsecTunnel" -#define LN_ipsecTunnel "IPSec Tunnel" -#define NID_ipsecTunnel 295 -#define OBJ_ipsecTunnel OBJ_id_kp,6L - -#define SN_ipsecUser "ipsecUser" -#define LN_ipsecUser "IPSec User" -#define NID_ipsecUser 296 -#define OBJ_ipsecUser OBJ_id_kp,7L - -#define SN_time_stamp "timeStamping" -#define LN_time_stamp "Time Stamping" -#define NID_time_stamp 133 -#define OBJ_time_stamp OBJ_id_kp,8L - -#define SN_OCSP_sign "OCSPSigning" -#define LN_OCSP_sign "OCSP Signing" -#define NID_OCSP_sign 180 -#define OBJ_OCSP_sign OBJ_id_kp,9L - -#define SN_dvcs "DVCS" -#define LN_dvcs "dvcs" -#define NID_dvcs 297 -#define OBJ_dvcs OBJ_id_kp,10L - -#define SN_ipsec_IKE "ipsecIKE" -#define LN_ipsec_IKE "ipsec Internet Key Exchange" -#define NID_ipsec_IKE 1022 -#define OBJ_ipsec_IKE OBJ_id_kp,17L - -#define SN_capwapAC "capwapAC" -#define LN_capwapAC "Ctrl/provision WAP Access" -#define NID_capwapAC 1023 -#define OBJ_capwapAC OBJ_id_kp,18L - -#define SN_capwapWTP "capwapWTP" -#define LN_capwapWTP "Ctrl/Provision WAP Termination" -#define NID_capwapWTP 1024 -#define OBJ_capwapWTP OBJ_id_kp,19L - -#define SN_sshClient "secureShellClient" -#define LN_sshClient "SSH Client" -#define NID_sshClient 1025 -#define OBJ_sshClient OBJ_id_kp,21L - -#define SN_sshServer "secureShellServer" -#define LN_sshServer "SSH Server" -#define NID_sshServer 1026 -#define OBJ_sshServer OBJ_id_kp,22L - -#define SN_sendRouter "sendRouter" -#define LN_sendRouter "Send Router" -#define NID_sendRouter 1027 -#define OBJ_sendRouter OBJ_id_kp,23L - -#define SN_sendProxiedRouter "sendProxiedRouter" -#define LN_sendProxiedRouter "Send Proxied Router" -#define NID_sendProxiedRouter 1028 -#define OBJ_sendProxiedRouter OBJ_id_kp,24L - -#define SN_sendOwner "sendOwner" -#define LN_sendOwner "Send Owner" -#define NID_sendOwner 1029 -#define OBJ_sendOwner OBJ_id_kp,25L - -#define SN_sendProxiedOwner "sendProxiedOwner" -#define LN_sendProxiedOwner "Send Proxied Owner" -#define NID_sendProxiedOwner 1030 -#define OBJ_sendProxiedOwner OBJ_id_kp,26L - -#define SN_cmcCA "cmcCA" -#define LN_cmcCA "CMC Certificate Authority" -#define NID_cmcCA 1131 -#define OBJ_cmcCA OBJ_id_kp,27L - -#define SN_cmcRA "cmcRA" -#define LN_cmcRA "CMC Registration Authority" -#define NID_cmcRA 1132 -#define OBJ_cmcRA OBJ_id_kp,28L - -#define SN_cmcArchive "cmcArchive" -#define LN_cmcArchive "CMC Archive Server" -#define NID_cmcArchive 1219 -#define OBJ_cmcArchive OBJ_id_kp,29L - -#define SN_id_kp_bgpsec_router "id-kp-bgpsec-router" -#define LN_id_kp_bgpsec_router "BGPsec Router" -#define NID_id_kp_bgpsec_router 1220 -#define OBJ_id_kp_bgpsec_router OBJ_id_kp,30L - -#define SN_id_kp_BrandIndicatorforMessageIdentification "id-kp-BrandIndicatorforMessageIdentification" -#define LN_id_kp_BrandIndicatorforMessageIdentification "Brand Indicator for Message Identification" -#define NID_id_kp_BrandIndicatorforMessageIdentification 1221 -#define OBJ_id_kp_BrandIndicatorforMessageIdentification OBJ_id_kp,31L - -#define SN_cmKGA "cmKGA" -#define LN_cmKGA "Certificate Management Key Generation Authority" -#define NID_cmKGA 1222 -#define OBJ_cmKGA OBJ_id_kp,32L - -#define SN_id_it_caProtEncCert "id-it-caProtEncCert" -#define NID_id_it_caProtEncCert 298 -#define OBJ_id_it_caProtEncCert OBJ_id_it,1L - -#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes" -#define NID_id_it_signKeyPairTypes 299 -#define OBJ_id_it_signKeyPairTypes OBJ_id_it,2L - -#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes" -#define NID_id_it_encKeyPairTypes 300 -#define OBJ_id_it_encKeyPairTypes OBJ_id_it,3L - -#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg" -#define NID_id_it_preferredSymmAlg 301 -#define OBJ_id_it_preferredSymmAlg OBJ_id_it,4L - -#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo" -#define NID_id_it_caKeyUpdateInfo 302 -#define OBJ_id_it_caKeyUpdateInfo OBJ_id_it,5L - -#define SN_id_it_currentCRL "id-it-currentCRL" -#define NID_id_it_currentCRL 303 -#define OBJ_id_it_currentCRL OBJ_id_it,6L - -#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs" -#define NID_id_it_unsupportedOIDs 304 -#define OBJ_id_it_unsupportedOIDs OBJ_id_it,7L - -#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest" -#define NID_id_it_subscriptionRequest 305 -#define OBJ_id_it_subscriptionRequest OBJ_id_it,8L - -#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse" -#define NID_id_it_subscriptionResponse 306 -#define OBJ_id_it_subscriptionResponse OBJ_id_it,9L - -#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq" -#define NID_id_it_keyPairParamReq 307 -#define OBJ_id_it_keyPairParamReq OBJ_id_it,10L - -#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep" -#define NID_id_it_keyPairParamRep 308 -#define OBJ_id_it_keyPairParamRep OBJ_id_it,11L - -#define SN_id_it_revPassphrase "id-it-revPassphrase" -#define NID_id_it_revPassphrase 309 -#define OBJ_id_it_revPassphrase OBJ_id_it,12L - -#define SN_id_it_implicitConfirm "id-it-implicitConfirm" -#define NID_id_it_implicitConfirm 310 -#define OBJ_id_it_implicitConfirm OBJ_id_it,13L - -#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime" -#define NID_id_it_confirmWaitTime 311 -#define OBJ_id_it_confirmWaitTime OBJ_id_it,14L - -#define SN_id_it_origPKIMessage "id-it-origPKIMessage" -#define NID_id_it_origPKIMessage 312 -#define OBJ_id_it_origPKIMessage OBJ_id_it,15L - -#define SN_id_it_suppLangTags "id-it-suppLangTags" -#define NID_id_it_suppLangTags 784 -#define OBJ_id_it_suppLangTags OBJ_id_it,16L - -#define SN_id_it_caCerts "id-it-caCerts" -#define NID_id_it_caCerts 1223 -#define OBJ_id_it_caCerts OBJ_id_it,17L - -#define SN_id_it_rootCaKeyUpdate "id-it-rootCaKeyUpdate" -#define NID_id_it_rootCaKeyUpdate 1224 -#define OBJ_id_it_rootCaKeyUpdate OBJ_id_it,18L - -#define SN_id_it_certReqTemplate "id-it-certReqTemplate" -#define NID_id_it_certReqTemplate 1225 -#define OBJ_id_it_certReqTemplate OBJ_id_it,19L - -#define SN_id_it_rootCaCert "id-it-rootCaCert" -#define NID_id_it_rootCaCert 1254 -#define OBJ_id_it_rootCaCert OBJ_id_it,20L - -#define SN_id_it_certProfile "id-it-certProfile" -#define NID_id_it_certProfile 1255 -#define OBJ_id_it_certProfile OBJ_id_it,21L - -#define SN_id_it_crlStatusList "id-it-crlStatusList" -#define NID_id_it_crlStatusList 1256 -#define OBJ_id_it_crlStatusList OBJ_id_it,22L - -#define SN_id_it_crls "id-it-crls" -#define NID_id_it_crls 1257 -#define OBJ_id_it_crls OBJ_id_it,23L - -#define SN_id_regCtrl "id-regCtrl" -#define NID_id_regCtrl 313 -#define OBJ_id_regCtrl OBJ_id_pkip,1L - -#define SN_id_regInfo "id-regInfo" -#define NID_id_regInfo 314 -#define OBJ_id_regInfo OBJ_id_pkip,2L - -#define SN_id_regCtrl_regToken "id-regCtrl-regToken" -#define NID_id_regCtrl_regToken 315 -#define OBJ_id_regCtrl_regToken OBJ_id_regCtrl,1L - -#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator" -#define NID_id_regCtrl_authenticator 316 -#define OBJ_id_regCtrl_authenticator OBJ_id_regCtrl,2L - -#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo" -#define NID_id_regCtrl_pkiPublicationInfo 317 -#define OBJ_id_regCtrl_pkiPublicationInfo OBJ_id_regCtrl,3L - -#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions" -#define NID_id_regCtrl_pkiArchiveOptions 318 -#define OBJ_id_regCtrl_pkiArchiveOptions OBJ_id_regCtrl,4L - -#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID" -#define NID_id_regCtrl_oldCertID 319 -#define OBJ_id_regCtrl_oldCertID OBJ_id_regCtrl,5L - -#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey" -#define NID_id_regCtrl_protocolEncrKey 320 -#define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L - -#define SN_id_regCtrl_altCertTemplate "id-regCtrl-altCertTemplate" -#define NID_id_regCtrl_altCertTemplate 1258 -#define OBJ_id_regCtrl_altCertTemplate OBJ_id_regCtrl,7L - -#define SN_id_regCtrl_algId "id-regCtrl-algId" -#define NID_id_regCtrl_algId 1259 -#define OBJ_id_regCtrl_algId OBJ_id_regCtrl,11L - -#define SN_id_regCtrl_rsaKeyLen "id-regCtrl-rsaKeyLen" -#define NID_id_regCtrl_rsaKeyLen 1260 -#define OBJ_id_regCtrl_rsaKeyLen OBJ_id_regCtrl,12L - -#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs" -#define NID_id_regInfo_utf8Pairs 321 -#define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L - -#define SN_id_regInfo_certReq "id-regInfo-certReq" -#define NID_id_regInfo_certReq 322 -#define OBJ_id_regInfo_certReq OBJ_id_regInfo,2L - -#define SN_id_alg_des40 "id-alg-des40" -#define NID_id_alg_des40 323 -#define OBJ_id_alg_des40 OBJ_id_alg,1L - -#define SN_id_alg_noSignature "id-alg-noSignature" -#define NID_id_alg_noSignature 324 -#define OBJ_id_alg_noSignature OBJ_id_alg,2L - -#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1" -#define NID_id_alg_dh_sig_hmac_sha1 325 -#define OBJ_id_alg_dh_sig_hmac_sha1 OBJ_id_alg,3L - -#define SN_id_alg_dh_pop "id-alg-dh-pop" -#define NID_id_alg_dh_pop 326 -#define OBJ_id_alg_dh_pop OBJ_id_alg,4L - -#define SN_id_cmc_statusInfo "id-cmc-statusInfo" -#define NID_id_cmc_statusInfo 327 -#define OBJ_id_cmc_statusInfo OBJ_id_cmc,1L - -#define SN_id_cmc_identification "id-cmc-identification" -#define NID_id_cmc_identification 328 -#define OBJ_id_cmc_identification OBJ_id_cmc,2L - -#define SN_id_cmc_identityProof "id-cmc-identityProof" -#define NID_id_cmc_identityProof 329 -#define OBJ_id_cmc_identityProof OBJ_id_cmc,3L - -#define SN_id_cmc_dataReturn "id-cmc-dataReturn" -#define NID_id_cmc_dataReturn 330 -#define OBJ_id_cmc_dataReturn OBJ_id_cmc,4L - -#define SN_id_cmc_transactionId "id-cmc-transactionId" -#define NID_id_cmc_transactionId 331 -#define OBJ_id_cmc_transactionId OBJ_id_cmc,5L - -#define SN_id_cmc_senderNonce "id-cmc-senderNonce" -#define NID_id_cmc_senderNonce 332 -#define OBJ_id_cmc_senderNonce OBJ_id_cmc,6L - -#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce" -#define NID_id_cmc_recipientNonce 333 -#define OBJ_id_cmc_recipientNonce OBJ_id_cmc,7L - -#define SN_id_cmc_addExtensions "id-cmc-addExtensions" -#define NID_id_cmc_addExtensions 334 -#define OBJ_id_cmc_addExtensions OBJ_id_cmc,8L - -#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP" -#define NID_id_cmc_encryptedPOP 335 -#define OBJ_id_cmc_encryptedPOP OBJ_id_cmc,9L - -#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP" -#define NID_id_cmc_decryptedPOP 336 -#define OBJ_id_cmc_decryptedPOP OBJ_id_cmc,10L - -#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness" -#define NID_id_cmc_lraPOPWitness 337 -#define OBJ_id_cmc_lraPOPWitness OBJ_id_cmc,11L - -#define SN_id_cmc_getCert "id-cmc-getCert" -#define NID_id_cmc_getCert 338 -#define OBJ_id_cmc_getCert OBJ_id_cmc,15L - -#define SN_id_cmc_getCRL "id-cmc-getCRL" -#define NID_id_cmc_getCRL 339 -#define OBJ_id_cmc_getCRL OBJ_id_cmc,16L - -#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest" -#define NID_id_cmc_revokeRequest 340 -#define OBJ_id_cmc_revokeRequest OBJ_id_cmc,17L - -#define SN_id_cmc_regInfo "id-cmc-regInfo" -#define NID_id_cmc_regInfo 341 -#define OBJ_id_cmc_regInfo OBJ_id_cmc,18L - -#define SN_id_cmc_responseInfo "id-cmc-responseInfo" -#define NID_id_cmc_responseInfo 342 -#define OBJ_id_cmc_responseInfo OBJ_id_cmc,19L - -#define SN_id_cmc_queryPending "id-cmc-queryPending" -#define NID_id_cmc_queryPending 343 -#define OBJ_id_cmc_queryPending OBJ_id_cmc,21L - -#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom" -#define NID_id_cmc_popLinkRandom 344 -#define OBJ_id_cmc_popLinkRandom OBJ_id_cmc,22L - -#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness" -#define NID_id_cmc_popLinkWitness 345 -#define OBJ_id_cmc_popLinkWitness OBJ_id_cmc,23L - -#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance" -#define NID_id_cmc_confirmCertAcceptance 346 -#define OBJ_id_cmc_confirmCertAcceptance OBJ_id_cmc,24L - -#define SN_id_on_personalData "id-on-personalData" -#define NID_id_on_personalData 347 -#define OBJ_id_on_personalData OBJ_id_on,1L - -#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier" -#define LN_id_on_permanentIdentifier "Permanent Identifier" -#define NID_id_on_permanentIdentifier 858 -#define OBJ_id_on_permanentIdentifier OBJ_id_on,3L - -#define SN_id_on_hardwareModuleName "id-on-hardwareModuleName" -#define LN_id_on_hardwareModuleName "Hardware Module Name" -#define NID_id_on_hardwareModuleName 1321 -#define OBJ_id_on_hardwareModuleName OBJ_id_on,4L - -#define SN_XmppAddr "id-on-xmppAddr" -#define LN_XmppAddr "XmppAddr" -#define NID_XmppAddr 1209 -#define OBJ_XmppAddr OBJ_id_on,5L - -#define SN_SRVName "id-on-dnsSRV" -#define LN_SRVName "SRVName" -#define NID_SRVName 1210 -#define OBJ_SRVName OBJ_id_on,7L - -#define SN_NAIRealm "id-on-NAIRealm" -#define LN_NAIRealm "NAIRealm" -#define NID_NAIRealm 1211 -#define OBJ_NAIRealm OBJ_id_on,8L - -#define SN_id_on_SmtpUTF8Mailbox "id-on-SmtpUTF8Mailbox" -#define LN_id_on_SmtpUTF8Mailbox "Smtp UTF8 Mailbox" -#define NID_id_on_SmtpUTF8Mailbox 1208 -#define OBJ_id_on_SmtpUTF8Mailbox OBJ_id_on,9L - -#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth" -#define NID_id_pda_dateOfBirth 348 -#define OBJ_id_pda_dateOfBirth OBJ_id_pda,1L - -#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth" -#define NID_id_pda_placeOfBirth 349 -#define OBJ_id_pda_placeOfBirth OBJ_id_pda,2L - -#define SN_id_pda_gender "id-pda-gender" -#define NID_id_pda_gender 351 -#define OBJ_id_pda_gender OBJ_id_pda,3L - -#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship" -#define NID_id_pda_countryOfCitizenship 352 -#define OBJ_id_pda_countryOfCitizenship OBJ_id_pda,4L - -#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence" -#define NID_id_pda_countryOfResidence 353 -#define OBJ_id_pda_countryOfResidence OBJ_id_pda,5L - -#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo" -#define NID_id_aca_authenticationInfo 354 -#define OBJ_id_aca_authenticationInfo OBJ_id_aca,1L - -#define SN_id_aca_accessIdentity "id-aca-accessIdentity" -#define NID_id_aca_accessIdentity 355 -#define OBJ_id_aca_accessIdentity OBJ_id_aca,2L - -#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity" -#define NID_id_aca_chargingIdentity 356 -#define OBJ_id_aca_chargingIdentity OBJ_id_aca,3L - -#define SN_id_aca_group "id-aca-group" -#define NID_id_aca_group 357 -#define OBJ_id_aca_group OBJ_id_aca,4L - -#define SN_id_aca_role "id-aca-role" -#define NID_id_aca_role 358 -#define OBJ_id_aca_role OBJ_id_aca,5L - -#define SN_id_aca_encAttrs "id-aca-encAttrs" -#define NID_id_aca_encAttrs 399 -#define OBJ_id_aca_encAttrs OBJ_id_aca,6L - -#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1" -#define NID_id_qcs_pkixQCSyntax_v1 359 -#define OBJ_id_qcs_pkixQCSyntax_v1 OBJ_id_qcs,1L - -#define SN_ipAddr_asNumber "ipAddr-asNumber" -#define NID_ipAddr_asNumber 1241 -#define OBJ_ipAddr_asNumber OBJ_id_cp,2L - -#define SN_ipAddr_asNumberv2 "ipAddr-asNumberv2" -#define NID_ipAddr_asNumberv2 1242 -#define OBJ_ipAddr_asNumberv2 OBJ_id_cp,3L - -#define SN_id_cct_crs "id-cct-crs" -#define NID_id_cct_crs 360 -#define OBJ_id_cct_crs OBJ_id_cct,1L - -#define SN_id_cct_PKIData "id-cct-PKIData" -#define NID_id_cct_PKIData 361 -#define OBJ_id_cct_PKIData OBJ_id_cct,2L - -#define SN_id_cct_PKIResponse "id-cct-PKIResponse" -#define NID_id_cct_PKIResponse 362 -#define OBJ_id_cct_PKIResponse OBJ_id_cct,3L - -#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage" -#define LN_id_ppl_anyLanguage "Any language" -#define NID_id_ppl_anyLanguage 664 -#define OBJ_id_ppl_anyLanguage OBJ_id_ppl,0L - -#define SN_id_ppl_inheritAll "id-ppl-inheritAll" -#define LN_id_ppl_inheritAll "Inherit all" -#define NID_id_ppl_inheritAll 665 -#define OBJ_id_ppl_inheritAll OBJ_id_ppl,1L - -#define SN_Independent "id-ppl-independent" -#define LN_Independent "Independent" -#define NID_Independent 667 -#define OBJ_Independent OBJ_id_ppl,2L - -#define SN_ad_OCSP "OCSP" -#define LN_ad_OCSP "OCSP" -#define NID_ad_OCSP 178 -#define OBJ_ad_OCSP OBJ_id_ad,1L - -#define SN_ad_ca_issuers "caIssuers" -#define LN_ad_ca_issuers "CA Issuers" -#define NID_ad_ca_issuers 179 -#define OBJ_ad_ca_issuers OBJ_id_ad,2L - -#define SN_ad_timeStamping "ad_timestamping" -#define LN_ad_timeStamping "AD Time Stamping" -#define NID_ad_timeStamping 363 -#define OBJ_ad_timeStamping OBJ_id_ad,3L - -#define SN_ad_dvcs "AD_DVCS" -#define LN_ad_dvcs "ad dvcs" -#define NID_ad_dvcs 364 -#define OBJ_ad_dvcs OBJ_id_ad,4L - -#define SN_caRepository "caRepository" -#define LN_caRepository "CA Repository" -#define NID_caRepository 785 -#define OBJ_caRepository OBJ_id_ad,5L - -#define SN_rpkiManifest "rpkiManifest" -#define LN_rpkiManifest "RPKI Manifest" -#define NID_rpkiManifest 1243 -#define OBJ_rpkiManifest OBJ_id_ad,10L - -#define SN_signedObject "signedObject" -#define LN_signedObject "Signed Object" -#define NID_signedObject 1244 -#define OBJ_signedObject OBJ_id_ad,11L - -#define SN_rpkiNotify "rpkiNotify" -#define LN_rpkiNotify "RPKI Notify" -#define NID_rpkiNotify 1245 -#define OBJ_rpkiNotify OBJ_id_ad,13L - -#define OBJ_id_pkix_OCSP OBJ_ad_OCSP - -#define SN_id_pkix_OCSP_basic "basicOCSPResponse" -#define LN_id_pkix_OCSP_basic "Basic OCSP Response" -#define NID_id_pkix_OCSP_basic 365 -#define OBJ_id_pkix_OCSP_basic OBJ_id_pkix_OCSP,1L - -#define SN_id_pkix_OCSP_Nonce "Nonce" -#define LN_id_pkix_OCSP_Nonce "OCSP Nonce" -#define NID_id_pkix_OCSP_Nonce 366 -#define OBJ_id_pkix_OCSP_Nonce OBJ_id_pkix_OCSP,2L - -#define SN_id_pkix_OCSP_CrlID "CrlID" -#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID" -#define NID_id_pkix_OCSP_CrlID 367 -#define OBJ_id_pkix_OCSP_CrlID OBJ_id_pkix_OCSP,3L - -#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses" -#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses" -#define NID_id_pkix_OCSP_acceptableResponses 368 -#define OBJ_id_pkix_OCSP_acceptableResponses OBJ_id_pkix_OCSP,4L - -#define SN_id_pkix_OCSP_noCheck "noCheck" -#define LN_id_pkix_OCSP_noCheck "OCSP No Check" -#define NID_id_pkix_OCSP_noCheck 369 -#define OBJ_id_pkix_OCSP_noCheck OBJ_id_pkix_OCSP,5L - -#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff" -#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff" -#define NID_id_pkix_OCSP_archiveCutoff 370 -#define OBJ_id_pkix_OCSP_archiveCutoff OBJ_id_pkix_OCSP,6L - -#define SN_id_pkix_OCSP_serviceLocator "serviceLocator" -#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator" -#define NID_id_pkix_OCSP_serviceLocator 371 -#define OBJ_id_pkix_OCSP_serviceLocator OBJ_id_pkix_OCSP,7L - -#define SN_id_pkix_OCSP_extendedStatus "extendedStatus" -#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status" -#define NID_id_pkix_OCSP_extendedStatus 372 -#define OBJ_id_pkix_OCSP_extendedStatus OBJ_id_pkix_OCSP,8L - -#define SN_id_pkix_OCSP_valid "valid" -#define NID_id_pkix_OCSP_valid 373 -#define OBJ_id_pkix_OCSP_valid OBJ_id_pkix_OCSP,9L - -#define SN_id_pkix_OCSP_path "path" -#define NID_id_pkix_OCSP_path 374 -#define OBJ_id_pkix_OCSP_path OBJ_id_pkix_OCSP,10L - -#define SN_id_pkix_OCSP_trustRoot "trustRoot" -#define LN_id_pkix_OCSP_trustRoot "Trust Root" -#define NID_id_pkix_OCSP_trustRoot 375 -#define OBJ_id_pkix_OCSP_trustRoot OBJ_id_pkix_OCSP,11L - -#define SN_algorithm "algorithm" -#define LN_algorithm "algorithm" -#define NID_algorithm 376 -#define OBJ_algorithm 1L,3L,14L,3L,2L - -#define SN_md5WithRSA "RSA-NP-MD5" -#define LN_md5WithRSA "md5WithRSA" -#define NID_md5WithRSA 104 -#define OBJ_md5WithRSA OBJ_algorithm,3L - -#define SN_des_ecb "DES-ECB" -#define LN_des_ecb "des-ecb" -#define NID_des_ecb 29 -#define OBJ_des_ecb OBJ_algorithm,6L - -#define SN_des_cbc "DES-CBC" -#define LN_des_cbc "des-cbc" -#define NID_des_cbc 31 -#define OBJ_des_cbc OBJ_algorithm,7L - -#define SN_des_ofb64 "DES-OFB" -#define LN_des_ofb64 "des-ofb" -#define NID_des_ofb64 45 -#define OBJ_des_ofb64 OBJ_algorithm,8L - -#define SN_des_cfb64 "DES-CFB" -#define LN_des_cfb64 "des-cfb" -#define NID_des_cfb64 30 -#define OBJ_des_cfb64 OBJ_algorithm,9L - -#define SN_rsaSignature "rsaSignature" -#define NID_rsaSignature 377 -#define OBJ_rsaSignature OBJ_algorithm,11L - -#define SN_dsa_2 "DSA-old" -#define LN_dsa_2 "dsaEncryption-old" -#define NID_dsa_2 67 -#define OBJ_dsa_2 OBJ_algorithm,12L - -#define SN_dsaWithSHA "DSA-SHA" -#define LN_dsaWithSHA "dsaWithSHA" -#define NID_dsaWithSHA 66 -#define OBJ_dsaWithSHA OBJ_algorithm,13L - -#define SN_shaWithRSAEncryption "RSA-SHA" -#define LN_shaWithRSAEncryption "shaWithRSAEncryption" -#define NID_shaWithRSAEncryption 42 -#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L - -#define SN_des_ede_ecb "DES-EDE" -#define LN_des_ede_ecb "des-ede" -#define NID_des_ede_ecb 32 -#define OBJ_des_ede_ecb OBJ_algorithm,17L - -#define SN_des_ede3_ecb "DES-EDE3" -#define LN_des_ede3_ecb "des-ede3" -#define NID_des_ede3_ecb 33 - -#define SN_des_ede_cbc "DES-EDE-CBC" -#define LN_des_ede_cbc "des-ede-cbc" -#define NID_des_ede_cbc 43 - -#define SN_des_ede_cfb64 "DES-EDE-CFB" -#define LN_des_ede_cfb64 "des-ede-cfb" -#define NID_des_ede_cfb64 60 - -#define SN_des_ede3_cfb64 "DES-EDE3-CFB" -#define LN_des_ede3_cfb64 "des-ede3-cfb" -#define NID_des_ede3_cfb64 61 - -#define SN_des_ede_ofb64 "DES-EDE-OFB" -#define LN_des_ede_ofb64 "des-ede-ofb" -#define NID_des_ede_ofb64 62 - -#define SN_des_ede3_ofb64 "DES-EDE3-OFB" -#define LN_des_ede3_ofb64 "des-ede3-ofb" -#define NID_des_ede3_ofb64 63 - -#define SN_desx_cbc "DESX-CBC" -#define LN_desx_cbc "desx-cbc" -#define NID_desx_cbc 80 - -#define SN_sha "SHA" -#define LN_sha "sha" -#define NID_sha 41 -#define OBJ_sha OBJ_algorithm,18L - -#define SN_sha1 "SHA1" -#define LN_sha1 "sha1" -#define NID_sha1 64 -#define OBJ_sha1 OBJ_algorithm,26L - -#define SN_dsaWithSHA1_2 "DSA-SHA1-old" -#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" -#define NID_dsaWithSHA1_2 70 -#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L - -#define SN_sha1WithRSA "RSA-SHA1-2" -#define LN_sha1WithRSA "sha1WithRSA" -#define NID_sha1WithRSA 115 -#define OBJ_sha1WithRSA OBJ_algorithm,29L - -#define SN_ripemd160 "RIPEMD160" -#define LN_ripemd160 "ripemd160" -#define NID_ripemd160 117 -#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L - -#define SN_ripemd160WithRSA "RSA-RIPEMD160" -#define LN_ripemd160WithRSA "ripemd160WithRSA" -#define NID_ripemd160WithRSA 119 -#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L - -#define SN_blake2bmac "BLAKE2BMAC" -#define LN_blake2bmac "blake2bmac" -#define NID_blake2bmac 1201 -#define OBJ_blake2bmac 1L,3L,6L,1L,4L,1L,1722L,12L,2L,1L - -#define SN_blake2smac "BLAKE2SMAC" -#define LN_blake2smac "blake2smac" -#define NID_blake2smac 1202 -#define OBJ_blake2smac 1L,3L,6L,1L,4L,1L,1722L,12L,2L,2L - -#define SN_blake2b512 "BLAKE2b512" -#define LN_blake2b512 "blake2b512" -#define NID_blake2b512 1056 -#define OBJ_blake2b512 OBJ_blake2bmac,16L - -#define SN_blake2s256 "BLAKE2s256" -#define LN_blake2s256 "blake2s256" -#define NID_blake2s256 1057 -#define OBJ_blake2s256 OBJ_blake2smac,8L - -#define SN_sxnet "SXNetID" -#define LN_sxnet "Strong Extranet ID" -#define NID_sxnet 143 -#define OBJ_sxnet 1L,3L,101L,1L,4L,1L - -#define SN_X500 "X500" -#define LN_X500 "directory services (X.500)" -#define NID_X500 11 -#define OBJ_X500 2L,5L - -#define SN_X509 "X509" -#define NID_X509 12 -#define OBJ_X509 OBJ_X500,4L - -#define SN_commonName "CN" -#define LN_commonName "commonName" -#define NID_commonName 13 -#define OBJ_commonName OBJ_X509,3L - -#define SN_surname "SN" -#define LN_surname "surname" -#define NID_surname 100 -#define OBJ_surname OBJ_X509,4L - -#define LN_serialNumber "serialNumber" -#define NID_serialNumber 105 -#define OBJ_serialNumber OBJ_X509,5L - -#define SN_countryName "C" -#define LN_countryName "countryName" -#define NID_countryName 14 -#define OBJ_countryName OBJ_X509,6L - -#define SN_localityName "L" -#define LN_localityName "localityName" -#define NID_localityName 15 -#define OBJ_localityName OBJ_X509,7L - -#define SN_stateOrProvinceName "ST" -#define LN_stateOrProvinceName "stateOrProvinceName" -#define NID_stateOrProvinceName 16 -#define OBJ_stateOrProvinceName OBJ_X509,8L - -#define SN_streetAddress "street" -#define LN_streetAddress "streetAddress" -#define NID_streetAddress 660 -#define OBJ_streetAddress OBJ_X509,9L - -#define SN_organizationName "O" -#define LN_organizationName "organizationName" -#define NID_organizationName 17 -#define OBJ_organizationName OBJ_X509,10L - -#define SN_organizationalUnitName "OU" -#define LN_organizationalUnitName "organizationalUnitName" -#define NID_organizationalUnitName 18 -#define OBJ_organizationalUnitName OBJ_X509,11L - -#define SN_title "title" -#define LN_title "title" -#define NID_title 106 -#define OBJ_title OBJ_X509,12L - -#define LN_description "description" -#define NID_description 107 -#define OBJ_description OBJ_X509,13L - -#define LN_searchGuide "searchGuide" -#define NID_searchGuide 859 -#define OBJ_searchGuide OBJ_X509,14L - -#define LN_businessCategory "businessCategory" -#define NID_businessCategory 860 -#define OBJ_businessCategory OBJ_X509,15L - -#define LN_postalAddress "postalAddress" -#define NID_postalAddress 861 -#define OBJ_postalAddress OBJ_X509,16L - -#define LN_postalCode "postalCode" -#define NID_postalCode 661 -#define OBJ_postalCode OBJ_X509,17L - -#define LN_postOfficeBox "postOfficeBox" -#define NID_postOfficeBox 862 -#define OBJ_postOfficeBox OBJ_X509,18L - -#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName" -#define NID_physicalDeliveryOfficeName 863 -#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L - -#define LN_telephoneNumber "telephoneNumber" -#define NID_telephoneNumber 864 -#define OBJ_telephoneNumber OBJ_X509,20L - -#define LN_telexNumber "telexNumber" -#define NID_telexNumber 865 -#define OBJ_telexNumber OBJ_X509,21L - -#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier" -#define NID_teletexTerminalIdentifier 866 -#define OBJ_teletexTerminalIdentifier OBJ_X509,22L - -#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber" -#define NID_facsimileTelephoneNumber 867 -#define OBJ_facsimileTelephoneNumber OBJ_X509,23L - -#define LN_x121Address "x121Address" -#define NID_x121Address 868 -#define OBJ_x121Address OBJ_X509,24L - -#define LN_internationaliSDNNumber "internationaliSDNNumber" -#define NID_internationaliSDNNumber 869 -#define OBJ_internationaliSDNNumber OBJ_X509,25L - -#define LN_registeredAddress "registeredAddress" -#define NID_registeredAddress 870 -#define OBJ_registeredAddress OBJ_X509,26L - -#define LN_destinationIndicator "destinationIndicator" -#define NID_destinationIndicator 871 -#define OBJ_destinationIndicator OBJ_X509,27L - -#define LN_preferredDeliveryMethod "preferredDeliveryMethod" -#define NID_preferredDeliveryMethod 872 -#define OBJ_preferredDeliveryMethod OBJ_X509,28L - -#define LN_presentationAddress "presentationAddress" -#define NID_presentationAddress 873 -#define OBJ_presentationAddress OBJ_X509,29L - -#define LN_supportedApplicationContext "supportedApplicationContext" -#define NID_supportedApplicationContext 874 -#define OBJ_supportedApplicationContext OBJ_X509,30L - -#define SN_member "member" -#define NID_member 875 -#define OBJ_member OBJ_X509,31L - -#define SN_owner "owner" -#define NID_owner 876 -#define OBJ_owner OBJ_X509,32L - -#define LN_roleOccupant "roleOccupant" -#define NID_roleOccupant 877 -#define OBJ_roleOccupant OBJ_X509,33L - -#define SN_seeAlso "seeAlso" -#define NID_seeAlso 878 -#define OBJ_seeAlso OBJ_X509,34L - -#define LN_userPassword "userPassword" -#define NID_userPassword 879 -#define OBJ_userPassword OBJ_X509,35L - -#define LN_userCertificate "userCertificate" -#define NID_userCertificate 880 -#define OBJ_userCertificate OBJ_X509,36L - -#define LN_cACertificate "cACertificate" -#define NID_cACertificate 881 -#define OBJ_cACertificate OBJ_X509,37L - -#define LN_authorityRevocationList "authorityRevocationList" -#define NID_authorityRevocationList 882 -#define OBJ_authorityRevocationList OBJ_X509,38L - -#define LN_certificateRevocationList "certificateRevocationList" -#define NID_certificateRevocationList 883 -#define OBJ_certificateRevocationList OBJ_X509,39L - -#define LN_crossCertificatePair "crossCertificatePair" -#define NID_crossCertificatePair 884 -#define OBJ_crossCertificatePair OBJ_X509,40L - -#define SN_name "name" -#define LN_name "name" -#define NID_name 173 -#define OBJ_name OBJ_X509,41L - -#define SN_givenName "GN" -#define LN_givenName "givenName" -#define NID_givenName 99 -#define OBJ_givenName OBJ_X509,42L - -#define SN_initials "initials" -#define LN_initials "initials" -#define NID_initials 101 -#define OBJ_initials OBJ_X509,43L - -#define LN_generationQualifier "generationQualifier" -#define NID_generationQualifier 509 -#define OBJ_generationQualifier OBJ_X509,44L - -#define LN_x500UniqueIdentifier "x500UniqueIdentifier" -#define NID_x500UniqueIdentifier 503 -#define OBJ_x500UniqueIdentifier OBJ_X509,45L - -#define SN_dnQualifier "dnQualifier" -#define LN_dnQualifier "dnQualifier" -#define NID_dnQualifier 174 -#define OBJ_dnQualifier OBJ_X509,46L - -#define LN_enhancedSearchGuide "enhancedSearchGuide" -#define NID_enhancedSearchGuide 885 -#define OBJ_enhancedSearchGuide OBJ_X509,47L - -#define LN_protocolInformation "protocolInformation" -#define NID_protocolInformation 886 -#define OBJ_protocolInformation OBJ_X509,48L - -#define LN_distinguishedName "distinguishedName" -#define NID_distinguishedName 887 -#define OBJ_distinguishedName OBJ_X509,49L - -#define LN_uniqueMember "uniqueMember" -#define NID_uniqueMember 888 -#define OBJ_uniqueMember OBJ_X509,50L - -#define LN_houseIdentifier "houseIdentifier" -#define NID_houseIdentifier 889 -#define OBJ_houseIdentifier OBJ_X509,51L - -#define LN_supportedAlgorithms "supportedAlgorithms" -#define NID_supportedAlgorithms 890 -#define OBJ_supportedAlgorithms OBJ_X509,52L - -#define LN_deltaRevocationList "deltaRevocationList" -#define NID_deltaRevocationList 891 -#define OBJ_deltaRevocationList OBJ_X509,53L - -#define SN_dmdName "dmdName" -#define NID_dmdName 892 -#define OBJ_dmdName OBJ_X509,54L - -#define LN_pseudonym "pseudonym" -#define NID_pseudonym 510 -#define OBJ_pseudonym OBJ_X509,65L - -#define SN_role "role" -#define LN_role "role" -#define NID_role 400 -#define OBJ_role OBJ_X509,72L - -#define LN_organizationIdentifier "organizationIdentifier" -#define NID_organizationIdentifier 1089 -#define OBJ_organizationIdentifier OBJ_X509,97L - -#define SN_countryCode3c "c3" -#define LN_countryCode3c "countryCode3c" -#define NID_countryCode3c 1090 -#define OBJ_countryCode3c OBJ_X509,98L - -#define SN_countryCode3n "n3" -#define LN_countryCode3n "countryCode3n" -#define NID_countryCode3n 1091 -#define OBJ_countryCode3n OBJ_X509,99L - -#define LN_dnsName "dnsName" -#define NID_dnsName 1092 -#define OBJ_dnsName OBJ_X509,100L - -#define SN_X500algorithms "X500algorithms" -#define LN_X500algorithms "directory services - algorithms" -#define NID_X500algorithms 378 -#define OBJ_X500algorithms OBJ_X500,8L - -#define SN_rsa "RSA" -#define LN_rsa "rsa" -#define NID_rsa 19 -#define OBJ_rsa OBJ_X500algorithms,1L,1L - -#define SN_mdc2WithRSA "RSA-MDC2" -#define LN_mdc2WithRSA "mdc2WithRSA" -#define NID_mdc2WithRSA 96 -#define OBJ_mdc2WithRSA OBJ_X500algorithms,3L,100L - -#define SN_mdc2 "MDC2" -#define LN_mdc2 "mdc2" -#define NID_mdc2 95 -#define OBJ_mdc2 OBJ_X500algorithms,3L,101L - -#define SN_id_ce "id-ce" -#define NID_id_ce 81 -#define OBJ_id_ce OBJ_X500,29L - -#define SN_subject_directory_attributes "subjectDirectoryAttributes" -#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes" -#define NID_subject_directory_attributes 769 -#define OBJ_subject_directory_attributes OBJ_id_ce,9L - -#define SN_subject_key_identifier "subjectKeyIdentifier" -#define LN_subject_key_identifier "X509v3 Subject Key Identifier" -#define NID_subject_key_identifier 82 -#define OBJ_subject_key_identifier OBJ_id_ce,14L - -#define SN_key_usage "keyUsage" -#define LN_key_usage "X509v3 Key Usage" -#define NID_key_usage 83 -#define OBJ_key_usage OBJ_id_ce,15L - -#define SN_private_key_usage_period "privateKeyUsagePeriod" -#define LN_private_key_usage_period "X509v3 Private Key Usage Period" -#define NID_private_key_usage_period 84 -#define OBJ_private_key_usage_period OBJ_id_ce,16L - -#define SN_subject_alt_name "subjectAltName" -#define LN_subject_alt_name "X509v3 Subject Alternative Name" -#define NID_subject_alt_name 85 -#define OBJ_subject_alt_name OBJ_id_ce,17L - -#define SN_issuer_alt_name "issuerAltName" -#define LN_issuer_alt_name "X509v3 Issuer Alternative Name" -#define NID_issuer_alt_name 86 -#define OBJ_issuer_alt_name OBJ_id_ce,18L - -#define SN_basic_constraints "basicConstraints" -#define LN_basic_constraints "X509v3 Basic Constraints" -#define NID_basic_constraints 87 -#define OBJ_basic_constraints OBJ_id_ce,19L - -#define SN_crl_number "crlNumber" -#define LN_crl_number "X509v3 CRL Number" -#define NID_crl_number 88 -#define OBJ_crl_number OBJ_id_ce,20L - -#define SN_crl_reason "CRLReason" -#define LN_crl_reason "X509v3 CRL Reason Code" -#define NID_crl_reason 141 -#define OBJ_crl_reason OBJ_id_ce,21L - -#define SN_invalidity_date "invalidityDate" -#define LN_invalidity_date "Invalidity Date" -#define NID_invalidity_date 142 -#define OBJ_invalidity_date OBJ_id_ce,24L - -#define SN_delta_crl "deltaCRL" -#define LN_delta_crl "X509v3 Delta CRL Indicator" -#define NID_delta_crl 140 -#define OBJ_delta_crl OBJ_id_ce,27L - -#define SN_issuing_distribution_point "issuingDistributionPoint" -#define LN_issuing_distribution_point "X509v3 Issuing Distribution Point" -#define NID_issuing_distribution_point 770 -#define OBJ_issuing_distribution_point OBJ_id_ce,28L - -#define SN_certificate_issuer "certificateIssuer" -#define LN_certificate_issuer "X509v3 Certificate Issuer" -#define NID_certificate_issuer 771 -#define OBJ_certificate_issuer OBJ_id_ce,29L - -#define SN_name_constraints "nameConstraints" -#define LN_name_constraints "X509v3 Name Constraints" -#define NID_name_constraints 666 -#define OBJ_name_constraints OBJ_id_ce,30L - -#define SN_crl_distribution_points "crlDistributionPoints" -#define LN_crl_distribution_points "X509v3 CRL Distribution Points" -#define NID_crl_distribution_points 103 -#define OBJ_crl_distribution_points OBJ_id_ce,31L - -#define SN_certificate_policies "certificatePolicies" -#define LN_certificate_policies "X509v3 Certificate Policies" -#define NID_certificate_policies 89 -#define OBJ_certificate_policies OBJ_id_ce,32L - -#define SN_any_policy "anyPolicy" -#define LN_any_policy "X509v3 Any Policy" -#define NID_any_policy 746 -#define OBJ_any_policy OBJ_certificate_policies,0L - -#define SN_policy_mappings "policyMappings" -#define LN_policy_mappings "X509v3 Policy Mappings" -#define NID_policy_mappings 747 -#define OBJ_policy_mappings OBJ_id_ce,33L - -#define SN_authority_key_identifier "authorityKeyIdentifier" -#define LN_authority_key_identifier "X509v3 Authority Key Identifier" -#define NID_authority_key_identifier 90 -#define OBJ_authority_key_identifier OBJ_id_ce,35L - -#define SN_policy_constraints "policyConstraints" -#define LN_policy_constraints "X509v3 Policy Constraints" -#define NID_policy_constraints 401 -#define OBJ_policy_constraints OBJ_id_ce,36L - -#define SN_ext_key_usage "extendedKeyUsage" -#define LN_ext_key_usage "X509v3 Extended Key Usage" -#define NID_ext_key_usage 126 -#define OBJ_ext_key_usage OBJ_id_ce,37L - -#define SN_authority_attribute_identifier "authorityAttributeIdentifier" -#define LN_authority_attribute_identifier "X509v3 Authority Attribute Identifier" -#define NID_authority_attribute_identifier 1295 -#define OBJ_authority_attribute_identifier OBJ_id_ce,38L - -#define SN_role_spec_cert_identifier "roleSpecCertIdentifier" -#define LN_role_spec_cert_identifier "X509v3 Role Specification Certificate Identifier" -#define NID_role_spec_cert_identifier 1296 -#define OBJ_role_spec_cert_identifier OBJ_id_ce,39L - -#define SN_basic_att_constraints "basicAttConstraints" -#define LN_basic_att_constraints "X509v3 Basic Attribute Certificate Constraints" -#define NID_basic_att_constraints 1297 -#define OBJ_basic_att_constraints OBJ_id_ce,41L - -#define SN_delegated_name_constraints "delegatedNameConstraints" -#define LN_delegated_name_constraints "X509v3 Delegated Name Constraints" -#define NID_delegated_name_constraints 1298 -#define OBJ_delegated_name_constraints OBJ_id_ce,42L - -#define SN_time_specification "timeSpecification" -#define LN_time_specification "X509v3 Time Specification" -#define NID_time_specification 1299 -#define OBJ_time_specification OBJ_id_ce,43L - -#define SN_freshest_crl "freshestCRL" -#define LN_freshest_crl "X509v3 Freshest CRL" -#define NID_freshest_crl 857 -#define OBJ_freshest_crl OBJ_id_ce,46L - -#define SN_attribute_descriptor "attributeDescriptor" -#define LN_attribute_descriptor "X509v3 Attribute Descriptor" -#define NID_attribute_descriptor 1300 -#define OBJ_attribute_descriptor OBJ_id_ce,48L - -#define SN_user_notice "userNotice" -#define LN_user_notice "X509v3 User Notice" -#define NID_user_notice 1301 -#define OBJ_user_notice OBJ_id_ce,49L - -#define SN_soa_identifier "sOAIdentifier" -#define LN_soa_identifier "X509v3 Source of Authority Identifier" -#define NID_soa_identifier 1302 -#define OBJ_soa_identifier OBJ_id_ce,50L - -#define SN_acceptable_cert_policies "acceptableCertPolicies" -#define LN_acceptable_cert_policies "X509v3 Acceptable Certification Policies" -#define NID_acceptable_cert_policies 1303 -#define OBJ_acceptable_cert_policies OBJ_id_ce,52L - -#define SN_inhibit_any_policy "inhibitAnyPolicy" -#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy" -#define NID_inhibit_any_policy 748 -#define OBJ_inhibit_any_policy OBJ_id_ce,54L - -#define SN_target_information "targetInformation" -#define LN_target_information "X509v3 AC Targeting" -#define NID_target_information 402 -#define OBJ_target_information OBJ_id_ce,55L - -#define SN_no_rev_avail "noRevAvail" -#define LN_no_rev_avail "X509v3 No Revocation Available" -#define NID_no_rev_avail 403 -#define OBJ_no_rev_avail OBJ_id_ce,56L - -#define SN_acceptable_privilege_policies "acceptablePrivPolicies" -#define LN_acceptable_privilege_policies "X509v3 Acceptable Privilege Policies" -#define NID_acceptable_privilege_policies 1304 -#define OBJ_acceptable_privilege_policies OBJ_id_ce,57L - -#define SN_indirect_issuer "indirectIssuer" -#define LN_indirect_issuer "X509v3 Indirect Issuer" -#define NID_indirect_issuer 1305 -#define OBJ_indirect_issuer OBJ_id_ce,61L - -#define SN_no_assertion "noAssertion" -#define LN_no_assertion "X509v3 No Assertion" -#define NID_no_assertion 1306 -#define OBJ_no_assertion OBJ_id_ce,62L - -#define SN_id_aa_issuing_distribution_point "aAissuingDistributionPoint" -#define LN_id_aa_issuing_distribution_point "X509v3 Attribute Authority Issuing Distribution Point" -#define NID_id_aa_issuing_distribution_point 1307 -#define OBJ_id_aa_issuing_distribution_point OBJ_id_ce,63L - -#define SN_issued_on_behalf_of "issuedOnBehalfOf" -#define LN_issued_on_behalf_of "X509v3 Issued On Behalf Of" -#define NID_issued_on_behalf_of 1308 -#define OBJ_issued_on_behalf_of OBJ_id_ce,64L - -#define SN_single_use "singleUse" -#define LN_single_use "X509v3 Single Use" -#define NID_single_use 1309 -#define OBJ_single_use OBJ_id_ce,65L - -#define SN_group_ac "groupAC" -#define LN_group_ac "X509v3 Group Attribute Certificate" -#define NID_group_ac 1310 -#define OBJ_group_ac OBJ_id_ce,66L - -#define SN_allowed_attribute_assignments "allowedAttributeAssignments" -#define LN_allowed_attribute_assignments "X509v3 Allowed Attribute Assignments" -#define NID_allowed_attribute_assignments 1311 -#define OBJ_allowed_attribute_assignments OBJ_id_ce,67L - -#define SN_attribute_mappings "attributeMappings" -#define LN_attribute_mappings "X509v3 Attribute Mappings" -#define NID_attribute_mappings 1312 -#define OBJ_attribute_mappings OBJ_id_ce,68L - -#define SN_holder_name_constraints "holderNameConstraints" -#define LN_holder_name_constraints "X509v3 Holder Name Constraints" -#define NID_holder_name_constraints 1313 -#define OBJ_holder_name_constraints OBJ_id_ce,69L - -#define SN_authorization_validation "authorizationValidation" -#define LN_authorization_validation "X509v3 Authorization Validation" -#define NID_authorization_validation 1314 -#define OBJ_authorization_validation OBJ_id_ce,70L - -#define SN_prot_restrict "protRestrict" -#define LN_prot_restrict "X509v3 Protocol Restriction" -#define NID_prot_restrict 1315 -#define OBJ_prot_restrict OBJ_id_ce,71L - -#define SN_subject_alt_public_key_info "subjectAltPublicKeyInfo" -#define LN_subject_alt_public_key_info "X509v3 Subject Alternative Public Key Info" -#define NID_subject_alt_public_key_info 1316 -#define OBJ_subject_alt_public_key_info OBJ_id_ce,72L - -#define SN_alt_signature_algorithm "altSignatureAlgorithm" -#define LN_alt_signature_algorithm "X509v3 Alternative Signature Algorithm" -#define NID_alt_signature_algorithm 1317 -#define OBJ_alt_signature_algorithm OBJ_id_ce,73L - -#define SN_alt_signature_value "altSignatureValue" -#define LN_alt_signature_value "X509v3 Alternative Signature Value" -#define NID_alt_signature_value 1318 -#define OBJ_alt_signature_value OBJ_id_ce,74L - -#define SN_associated_information "associatedInformation" -#define LN_associated_information "X509v3 Associated Information" -#define NID_associated_information 1319 -#define OBJ_associated_information OBJ_id_ce,75L - -#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage" -#define LN_anyExtendedKeyUsage "Any Extended Key Usage" -#define NID_anyExtendedKeyUsage 910 -#define OBJ_anyExtendedKeyUsage OBJ_ext_key_usage,0L - -#define SN_netscape "Netscape" -#define LN_netscape "Netscape Communications Corp." -#define NID_netscape 57 -#define OBJ_netscape 2L,16L,840L,1L,113730L - -#define SN_netscape_cert_extension "nsCertExt" -#define LN_netscape_cert_extension "Netscape Certificate Extension" -#define NID_netscape_cert_extension 58 -#define OBJ_netscape_cert_extension OBJ_netscape,1L - -#define SN_netscape_data_type "nsDataType" -#define LN_netscape_data_type "Netscape Data Type" -#define NID_netscape_data_type 59 -#define OBJ_netscape_data_type OBJ_netscape,2L - -#define SN_netscape_cert_type "nsCertType" -#define LN_netscape_cert_type "Netscape Cert Type" -#define NID_netscape_cert_type 71 -#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L - -#define SN_netscape_base_url "nsBaseUrl" -#define LN_netscape_base_url "Netscape Base Url" -#define NID_netscape_base_url 72 -#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L - -#define SN_netscape_revocation_url "nsRevocationUrl" -#define LN_netscape_revocation_url "Netscape Revocation Url" -#define NID_netscape_revocation_url 73 -#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L - -#define SN_netscape_ca_revocation_url "nsCaRevocationUrl" -#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" -#define NID_netscape_ca_revocation_url 74 -#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L - -#define SN_netscape_renewal_url "nsRenewalUrl" -#define LN_netscape_renewal_url "Netscape Renewal Url" -#define NID_netscape_renewal_url 75 -#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L - -#define SN_netscape_ca_policy_url "nsCaPolicyUrl" -#define LN_netscape_ca_policy_url "Netscape CA Policy Url" -#define NID_netscape_ca_policy_url 76 -#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L - -#define SN_netscape_ssl_server_name "nsSslServerName" -#define LN_netscape_ssl_server_name "Netscape SSL Server Name" -#define NID_netscape_ssl_server_name 77 -#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L - -#define SN_netscape_comment "nsComment" -#define LN_netscape_comment "Netscape Comment" -#define NID_netscape_comment 78 -#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L - -#define SN_netscape_cert_sequence "nsCertSequence" -#define LN_netscape_cert_sequence "Netscape Certificate Sequence" -#define NID_netscape_cert_sequence 79 -#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L - -#define SN_ns_sgc "nsSGC" -#define LN_ns_sgc "Netscape Server Gated Crypto" -#define NID_ns_sgc 139 -#define OBJ_ns_sgc OBJ_netscape,4L,1L - -#define SN_org "ORG" -#define LN_org "org" -#define NID_org 379 -#define OBJ_org OBJ_iso,3L - -#define SN_dod "DOD" -#define LN_dod "dod" -#define NID_dod 380 -#define OBJ_dod OBJ_org,6L - -#define SN_iana "IANA" -#define LN_iana "iana" -#define NID_iana 381 -#define OBJ_iana OBJ_dod,1L - -#define OBJ_internet OBJ_iana - -#define SN_Directory "directory" -#define LN_Directory "Directory" -#define NID_Directory 382 -#define OBJ_Directory OBJ_internet,1L - -#define SN_Management "mgmt" -#define LN_Management "Management" -#define NID_Management 383 -#define OBJ_Management OBJ_internet,2L - -#define SN_Experimental "experimental" -#define LN_Experimental "Experimental" -#define NID_Experimental 384 -#define OBJ_Experimental OBJ_internet,3L - -#define SN_Private "private" -#define LN_Private "Private" -#define NID_Private 385 -#define OBJ_Private OBJ_internet,4L - -#define SN_Security "security" -#define LN_Security "Security" -#define NID_Security 386 -#define OBJ_Security OBJ_internet,5L - -#define SN_SNMPv2 "snmpv2" -#define LN_SNMPv2 "SNMPv2" -#define NID_SNMPv2 387 -#define OBJ_SNMPv2 OBJ_internet,6L - -#define LN_Mail "Mail" -#define NID_Mail 388 -#define OBJ_Mail OBJ_internet,7L - -#define SN_Enterprises "enterprises" -#define LN_Enterprises "Enterprises" -#define NID_Enterprises 389 -#define OBJ_Enterprises OBJ_Private,1L - -#define SN_dcObject "dcobject" -#define LN_dcObject "dcObject" -#define NID_dcObject 390 -#define OBJ_dcObject OBJ_Enterprises,1466L,344L - -#define SN_id_kp_wisun_fan_device "id-kp-wisun-fan-device" -#define LN_id_kp_wisun_fan_device "Wi-SUN Alliance Field Area Network (FAN)" -#define NID_id_kp_wisun_fan_device 1322 -#define OBJ_id_kp_wisun_fan_device OBJ_Enterprises,45605L,1L - -#define SN_mime_mhs "mime-mhs" -#define LN_mime_mhs "MIME MHS" -#define NID_mime_mhs 504 -#define OBJ_mime_mhs OBJ_Mail,1L - -#define SN_mime_mhs_headings "mime-mhs-headings" -#define LN_mime_mhs_headings "mime-mhs-headings" -#define NID_mime_mhs_headings 505 -#define OBJ_mime_mhs_headings OBJ_mime_mhs,1L - -#define SN_mime_mhs_bodies "mime-mhs-bodies" -#define LN_mime_mhs_bodies "mime-mhs-bodies" -#define NID_mime_mhs_bodies 506 -#define OBJ_mime_mhs_bodies OBJ_mime_mhs,2L - -#define SN_id_hex_partial_message "id-hex-partial-message" -#define LN_id_hex_partial_message "id-hex-partial-message" -#define NID_id_hex_partial_message 507 -#define OBJ_id_hex_partial_message OBJ_mime_mhs_headings,1L - -#define SN_id_hex_multipart_message "id-hex-multipart-message" -#define LN_id_hex_multipart_message "id-hex-multipart-message" -#define NID_id_hex_multipart_message 508 -#define OBJ_id_hex_multipart_message OBJ_mime_mhs_headings,2L - -#define SN_zlib_compression "ZLIB" -#define LN_zlib_compression "zlib compression" -#define NID_zlib_compression 125 -#define OBJ_zlib_compression OBJ_id_smime_alg,8L - -#define OBJ_csor 2L,16L,840L,1L,101L,3L - -#define OBJ_nistAlgorithms OBJ_csor,4L - -#define OBJ_aes OBJ_nistAlgorithms,1L - -#define SN_aes_128_ecb "AES-128-ECB" -#define LN_aes_128_ecb "aes-128-ecb" -#define NID_aes_128_ecb 418 -#define OBJ_aes_128_ecb OBJ_aes,1L - -#define SN_aes_128_cbc "AES-128-CBC" -#define LN_aes_128_cbc "aes-128-cbc" -#define NID_aes_128_cbc 419 -#define OBJ_aes_128_cbc OBJ_aes,2L - -#define SN_aes_128_ofb128 "AES-128-OFB" -#define LN_aes_128_ofb128 "aes-128-ofb" -#define NID_aes_128_ofb128 420 -#define OBJ_aes_128_ofb128 OBJ_aes,3L - -#define SN_aes_128_cfb128 "AES-128-CFB" -#define LN_aes_128_cfb128 "aes-128-cfb" -#define NID_aes_128_cfb128 421 -#define OBJ_aes_128_cfb128 OBJ_aes,4L - -#define SN_id_aes128_wrap "id-aes128-wrap" -#define NID_id_aes128_wrap 788 -#define OBJ_id_aes128_wrap OBJ_aes,5L - -#define SN_aes_128_gcm "id-aes128-GCM" -#define LN_aes_128_gcm "aes-128-gcm" -#define NID_aes_128_gcm 895 -#define OBJ_aes_128_gcm OBJ_aes,6L - -#define SN_aes_128_ccm "id-aes128-CCM" -#define LN_aes_128_ccm "aes-128-ccm" -#define NID_aes_128_ccm 896 -#define OBJ_aes_128_ccm OBJ_aes,7L - -#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad" -#define NID_id_aes128_wrap_pad 897 -#define OBJ_id_aes128_wrap_pad OBJ_aes,8L - -#define SN_aes_192_ecb "AES-192-ECB" -#define LN_aes_192_ecb "aes-192-ecb" -#define NID_aes_192_ecb 422 -#define OBJ_aes_192_ecb OBJ_aes,21L - -#define SN_aes_192_cbc "AES-192-CBC" -#define LN_aes_192_cbc "aes-192-cbc" -#define NID_aes_192_cbc 423 -#define OBJ_aes_192_cbc OBJ_aes,22L - -#define SN_aes_192_ofb128 "AES-192-OFB" -#define LN_aes_192_ofb128 "aes-192-ofb" -#define NID_aes_192_ofb128 424 -#define OBJ_aes_192_ofb128 OBJ_aes,23L - -#define SN_aes_192_cfb128 "AES-192-CFB" -#define LN_aes_192_cfb128 "aes-192-cfb" -#define NID_aes_192_cfb128 425 -#define OBJ_aes_192_cfb128 OBJ_aes,24L - -#define SN_id_aes192_wrap "id-aes192-wrap" -#define NID_id_aes192_wrap 789 -#define OBJ_id_aes192_wrap OBJ_aes,25L - -#define SN_aes_192_gcm "id-aes192-GCM" -#define LN_aes_192_gcm "aes-192-gcm" -#define NID_aes_192_gcm 898 -#define OBJ_aes_192_gcm OBJ_aes,26L - -#define SN_aes_192_ccm "id-aes192-CCM" -#define LN_aes_192_ccm "aes-192-ccm" -#define NID_aes_192_ccm 899 -#define OBJ_aes_192_ccm OBJ_aes,27L - -#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad" -#define NID_id_aes192_wrap_pad 900 -#define OBJ_id_aes192_wrap_pad OBJ_aes,28L - -#define SN_aes_256_ecb "AES-256-ECB" -#define LN_aes_256_ecb "aes-256-ecb" -#define NID_aes_256_ecb 426 -#define OBJ_aes_256_ecb OBJ_aes,41L - -#define SN_aes_256_cbc "AES-256-CBC" -#define LN_aes_256_cbc "aes-256-cbc" -#define NID_aes_256_cbc 427 -#define OBJ_aes_256_cbc OBJ_aes,42L - -#define SN_aes_256_ofb128 "AES-256-OFB" -#define LN_aes_256_ofb128 "aes-256-ofb" -#define NID_aes_256_ofb128 428 -#define OBJ_aes_256_ofb128 OBJ_aes,43L - -#define SN_aes_256_cfb128 "AES-256-CFB" -#define LN_aes_256_cfb128 "aes-256-cfb" -#define NID_aes_256_cfb128 429 -#define OBJ_aes_256_cfb128 OBJ_aes,44L - -#define SN_id_aes256_wrap "id-aes256-wrap" -#define NID_id_aes256_wrap 790 -#define OBJ_id_aes256_wrap OBJ_aes,45L - -#define SN_aes_256_gcm "id-aes256-GCM" -#define LN_aes_256_gcm "aes-256-gcm" -#define NID_aes_256_gcm 901 -#define OBJ_aes_256_gcm OBJ_aes,46L - -#define SN_aes_256_ccm "id-aes256-CCM" -#define LN_aes_256_ccm "aes-256-ccm" -#define NID_aes_256_ccm 902 -#define OBJ_aes_256_ccm OBJ_aes,47L - -#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad" -#define NID_id_aes256_wrap_pad 903 -#define OBJ_id_aes256_wrap_pad OBJ_aes,48L - -#define SN_aes_128_xts "AES-128-XTS" -#define LN_aes_128_xts "aes-128-xts" -#define NID_aes_128_xts 913 -#define OBJ_aes_128_xts OBJ_ieee_siswg,0L,1L,1L - -#define SN_aes_256_xts "AES-256-XTS" -#define LN_aes_256_xts "aes-256-xts" -#define NID_aes_256_xts 914 -#define OBJ_aes_256_xts OBJ_ieee_siswg,0L,1L,2L - -#define SN_aes_128_cfb1 "AES-128-CFB1" -#define LN_aes_128_cfb1 "aes-128-cfb1" -#define NID_aes_128_cfb1 650 - -#define SN_aes_192_cfb1 "AES-192-CFB1" -#define LN_aes_192_cfb1 "aes-192-cfb1" -#define NID_aes_192_cfb1 651 - -#define SN_aes_256_cfb1 "AES-256-CFB1" -#define LN_aes_256_cfb1 "aes-256-cfb1" -#define NID_aes_256_cfb1 652 - -#define SN_aes_128_cfb8 "AES-128-CFB8" -#define LN_aes_128_cfb8 "aes-128-cfb8" -#define NID_aes_128_cfb8 653 - -#define SN_aes_192_cfb8 "AES-192-CFB8" -#define LN_aes_192_cfb8 "aes-192-cfb8" -#define NID_aes_192_cfb8 654 - -#define SN_aes_256_cfb8 "AES-256-CFB8" -#define LN_aes_256_cfb8 "aes-256-cfb8" -#define NID_aes_256_cfb8 655 - -#define SN_aes_128_ctr "AES-128-CTR" -#define LN_aes_128_ctr "aes-128-ctr" -#define NID_aes_128_ctr 904 - -#define SN_aes_192_ctr "AES-192-CTR" -#define LN_aes_192_ctr "aes-192-ctr" -#define NID_aes_192_ctr 905 - -#define SN_aes_256_ctr "AES-256-CTR" -#define LN_aes_256_ctr "aes-256-ctr" -#define NID_aes_256_ctr 906 - -#define SN_aes_128_ocb "AES-128-OCB" -#define LN_aes_128_ocb "aes-128-ocb" -#define NID_aes_128_ocb 958 - -#define SN_aes_192_ocb "AES-192-OCB" -#define LN_aes_192_ocb "aes-192-ocb" -#define NID_aes_192_ocb 959 - -#define SN_aes_256_ocb "AES-256-OCB" -#define LN_aes_256_ocb "aes-256-ocb" -#define NID_aes_256_ocb 960 - -#define SN_des_cfb1 "DES-CFB1" -#define LN_des_cfb1 "des-cfb1" -#define NID_des_cfb1 656 - -#define SN_des_cfb8 "DES-CFB8" -#define LN_des_cfb8 "des-cfb8" -#define NID_des_cfb8 657 - -#define SN_des_ede3_cfb1 "DES-EDE3-CFB1" -#define LN_des_ede3_cfb1 "des-ede3-cfb1" -#define NID_des_ede3_cfb1 658 - -#define SN_des_ede3_cfb8 "DES-EDE3-CFB8" -#define LN_des_ede3_cfb8 "des-ede3-cfb8" -#define NID_des_ede3_cfb8 659 - -#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L - -#define SN_sha256 "SHA256" -#define LN_sha256 "sha256" -#define NID_sha256 672 -#define OBJ_sha256 OBJ_nist_hashalgs,1L - -#define SN_sha384 "SHA384" -#define LN_sha384 "sha384" -#define NID_sha384 673 -#define OBJ_sha384 OBJ_nist_hashalgs,2L - -#define SN_sha512 "SHA512" -#define LN_sha512 "sha512" -#define NID_sha512 674 -#define OBJ_sha512 OBJ_nist_hashalgs,3L - -#define SN_sha224 "SHA224" -#define LN_sha224 "sha224" -#define NID_sha224 675 -#define OBJ_sha224 OBJ_nist_hashalgs,4L - -#define SN_sha512_224 "SHA512-224" -#define LN_sha512_224 "sha512-224" -#define NID_sha512_224 1094 -#define OBJ_sha512_224 OBJ_nist_hashalgs,5L - -#define SN_sha512_256 "SHA512-256" -#define LN_sha512_256 "sha512-256" -#define NID_sha512_256 1095 -#define OBJ_sha512_256 OBJ_nist_hashalgs,6L - -#define SN_sha3_224 "SHA3-224" -#define LN_sha3_224 "sha3-224" -#define NID_sha3_224 1096 -#define OBJ_sha3_224 OBJ_nist_hashalgs,7L - -#define SN_sha3_256 "SHA3-256" -#define LN_sha3_256 "sha3-256" -#define NID_sha3_256 1097 -#define OBJ_sha3_256 OBJ_nist_hashalgs,8L - -#define SN_sha3_384 "SHA3-384" -#define LN_sha3_384 "sha3-384" -#define NID_sha3_384 1098 -#define OBJ_sha3_384 OBJ_nist_hashalgs,9L - -#define SN_sha3_512 "SHA3-512" -#define LN_sha3_512 "sha3-512" -#define NID_sha3_512 1099 -#define OBJ_sha3_512 OBJ_nist_hashalgs,10L - -#define SN_shake128 "SHAKE128" -#define LN_shake128 "shake128" -#define NID_shake128 1100 -#define OBJ_shake128 OBJ_nist_hashalgs,11L - -#define SN_shake256 "SHAKE256" -#define LN_shake256 "shake256" -#define NID_shake256 1101 -#define OBJ_shake256 OBJ_nist_hashalgs,12L - -#define SN_hmac_sha3_224 "id-hmacWithSHA3-224" -#define LN_hmac_sha3_224 "hmac-sha3-224" -#define NID_hmac_sha3_224 1102 -#define OBJ_hmac_sha3_224 OBJ_nist_hashalgs,13L - -#define SN_hmac_sha3_256 "id-hmacWithSHA3-256" -#define LN_hmac_sha3_256 "hmac-sha3-256" -#define NID_hmac_sha3_256 1103 -#define OBJ_hmac_sha3_256 OBJ_nist_hashalgs,14L - -#define SN_hmac_sha3_384 "id-hmacWithSHA3-384" -#define LN_hmac_sha3_384 "hmac-sha3-384" -#define NID_hmac_sha3_384 1104 -#define OBJ_hmac_sha3_384 OBJ_nist_hashalgs,15L - -#define SN_hmac_sha3_512 "id-hmacWithSHA3-512" -#define LN_hmac_sha3_512 "hmac-sha3-512" -#define NID_hmac_sha3_512 1105 -#define OBJ_hmac_sha3_512 OBJ_nist_hashalgs,16L - -#define SN_kmac128 "KMAC128" -#define LN_kmac128 "kmac128" -#define NID_kmac128 1196 -#define OBJ_kmac128 OBJ_nist_hashalgs,19L - -#define SN_kmac256 "KMAC256" -#define LN_kmac256 "kmac256" -#define NID_kmac256 1197 -#define OBJ_kmac256 OBJ_nist_hashalgs,20L - -#define OBJ_dsa_with_sha2 OBJ_nistAlgorithms,3L - -#define SN_dsa_with_SHA224 "dsa_with_SHA224" -#define NID_dsa_with_SHA224 802 -#define OBJ_dsa_with_SHA224 OBJ_dsa_with_sha2,1L - -#define SN_dsa_with_SHA256 "dsa_with_SHA256" -#define NID_dsa_with_SHA256 803 -#define OBJ_dsa_with_SHA256 OBJ_dsa_with_sha2,2L - -#define OBJ_sigAlgs OBJ_nistAlgorithms,3L - -#define SN_dsa_with_SHA384 "id-dsa-with-sha384" -#define LN_dsa_with_SHA384 "dsa_with_SHA384" -#define NID_dsa_with_SHA384 1106 -#define OBJ_dsa_with_SHA384 OBJ_sigAlgs,3L - -#define SN_dsa_with_SHA512 "id-dsa-with-sha512" -#define LN_dsa_with_SHA512 "dsa_with_SHA512" -#define NID_dsa_with_SHA512 1107 -#define OBJ_dsa_with_SHA512 OBJ_sigAlgs,4L - -#define SN_dsa_with_SHA3_224 "id-dsa-with-sha3-224" -#define LN_dsa_with_SHA3_224 "dsa_with_SHA3-224" -#define NID_dsa_with_SHA3_224 1108 -#define OBJ_dsa_with_SHA3_224 OBJ_sigAlgs,5L - -#define SN_dsa_with_SHA3_256 "id-dsa-with-sha3-256" -#define LN_dsa_with_SHA3_256 "dsa_with_SHA3-256" -#define NID_dsa_with_SHA3_256 1109 -#define OBJ_dsa_with_SHA3_256 OBJ_sigAlgs,6L - -#define SN_dsa_with_SHA3_384 "id-dsa-with-sha3-384" -#define LN_dsa_with_SHA3_384 "dsa_with_SHA3-384" -#define NID_dsa_with_SHA3_384 1110 -#define OBJ_dsa_with_SHA3_384 OBJ_sigAlgs,7L - -#define SN_dsa_with_SHA3_512 "id-dsa-with-sha3-512" -#define LN_dsa_with_SHA3_512 "dsa_with_SHA3-512" -#define NID_dsa_with_SHA3_512 1111 -#define OBJ_dsa_with_SHA3_512 OBJ_sigAlgs,8L - -#define SN_ecdsa_with_SHA3_224 "id-ecdsa-with-sha3-224" -#define LN_ecdsa_with_SHA3_224 "ecdsa_with_SHA3-224" -#define NID_ecdsa_with_SHA3_224 1112 -#define OBJ_ecdsa_with_SHA3_224 OBJ_sigAlgs,9L - -#define SN_ecdsa_with_SHA3_256 "id-ecdsa-with-sha3-256" -#define LN_ecdsa_with_SHA3_256 "ecdsa_with_SHA3-256" -#define NID_ecdsa_with_SHA3_256 1113 -#define OBJ_ecdsa_with_SHA3_256 OBJ_sigAlgs,10L - -#define SN_ecdsa_with_SHA3_384 "id-ecdsa-with-sha3-384" -#define LN_ecdsa_with_SHA3_384 "ecdsa_with_SHA3-384" -#define NID_ecdsa_with_SHA3_384 1114 -#define OBJ_ecdsa_with_SHA3_384 OBJ_sigAlgs,11L - -#define SN_ecdsa_with_SHA3_512 "id-ecdsa-with-sha3-512" -#define LN_ecdsa_with_SHA3_512 "ecdsa_with_SHA3-512" -#define NID_ecdsa_with_SHA3_512 1115 -#define OBJ_ecdsa_with_SHA3_512 OBJ_sigAlgs,12L - -#define SN_RSA_SHA3_224 "id-rsassa-pkcs1-v1_5-with-sha3-224" -#define LN_RSA_SHA3_224 "RSA-SHA3-224" -#define NID_RSA_SHA3_224 1116 -#define OBJ_RSA_SHA3_224 OBJ_sigAlgs,13L - -#define SN_RSA_SHA3_256 "id-rsassa-pkcs1-v1_5-with-sha3-256" -#define LN_RSA_SHA3_256 "RSA-SHA3-256" -#define NID_RSA_SHA3_256 1117 -#define OBJ_RSA_SHA3_256 OBJ_sigAlgs,14L - -#define SN_RSA_SHA3_384 "id-rsassa-pkcs1-v1_5-with-sha3-384" -#define LN_RSA_SHA3_384 "RSA-SHA3-384" -#define NID_RSA_SHA3_384 1118 -#define OBJ_RSA_SHA3_384 OBJ_sigAlgs,15L - -#define SN_RSA_SHA3_512 "id-rsassa-pkcs1-v1_5-with-sha3-512" -#define LN_RSA_SHA3_512 "RSA-SHA3-512" -#define NID_RSA_SHA3_512 1119 -#define OBJ_RSA_SHA3_512 OBJ_sigAlgs,16L - -#define SN_ML_DSA_44 "id-ml-dsa-44" -#define LN_ML_DSA_44 "ML-DSA-44" -#define NID_ML_DSA_44 1457 -#define OBJ_ML_DSA_44 OBJ_sigAlgs,17L - -#define SN_ML_DSA_65 "id-ml-dsa-65" -#define LN_ML_DSA_65 "ML-DSA-65" -#define NID_ML_DSA_65 1458 -#define OBJ_ML_DSA_65 OBJ_sigAlgs,18L - -#define SN_ML_DSA_87 "id-ml-dsa-87" -#define LN_ML_DSA_87 "ML-DSA-87" -#define NID_ML_DSA_87 1459 -#define OBJ_ML_DSA_87 OBJ_sigAlgs,19L - -#define SN_SLH_DSA_SHA2_128s "id-slh-dsa-sha2-128s" -#define LN_SLH_DSA_SHA2_128s "SLH-DSA-SHA2-128s" -#define NID_SLH_DSA_SHA2_128s 1460 -#define OBJ_SLH_DSA_SHA2_128s OBJ_sigAlgs,20L - -#define SN_SLH_DSA_SHA2_128f "id-slh-dsa-sha2-128f" -#define LN_SLH_DSA_SHA2_128f "SLH-DSA-SHA2-128f" -#define NID_SLH_DSA_SHA2_128f 1461 -#define OBJ_SLH_DSA_SHA2_128f OBJ_sigAlgs,21L - -#define SN_SLH_DSA_SHA2_192s "id-slh-dsa-sha2-192s" -#define LN_SLH_DSA_SHA2_192s "SLH-DSA-SHA2-192s" -#define NID_SLH_DSA_SHA2_192s 1462 -#define OBJ_SLH_DSA_SHA2_192s OBJ_sigAlgs,22L - -#define SN_SLH_DSA_SHA2_192f "id-slh-dsa-sha2-192f" -#define LN_SLH_DSA_SHA2_192f "SLH-DSA-SHA2-192f" -#define NID_SLH_DSA_SHA2_192f 1463 -#define OBJ_SLH_DSA_SHA2_192f OBJ_sigAlgs,23L - -#define SN_SLH_DSA_SHA2_256s "id-slh-dsa-sha2-256s" -#define LN_SLH_DSA_SHA2_256s "SLH-DSA-SHA2-256s" -#define NID_SLH_DSA_SHA2_256s 1464 -#define OBJ_SLH_DSA_SHA2_256s OBJ_sigAlgs,24L - -#define SN_SLH_DSA_SHA2_256f "id-slh-dsa-sha2-256f" -#define LN_SLH_DSA_SHA2_256f "SLH-DSA-SHA2-256f" -#define NID_SLH_DSA_SHA2_256f 1465 -#define OBJ_SLH_DSA_SHA2_256f OBJ_sigAlgs,25L - -#define SN_SLH_DSA_SHAKE_128s "id-slh-dsa-shake-128s" -#define LN_SLH_DSA_SHAKE_128s "SLH-DSA-SHAKE-128s" -#define NID_SLH_DSA_SHAKE_128s 1466 -#define OBJ_SLH_DSA_SHAKE_128s OBJ_sigAlgs,26L - -#define SN_SLH_DSA_SHAKE_128f "id-slh-dsa-shake-128f" -#define LN_SLH_DSA_SHAKE_128f "SLH-DSA-SHAKE-128f" -#define NID_SLH_DSA_SHAKE_128f 1467 -#define OBJ_SLH_DSA_SHAKE_128f OBJ_sigAlgs,27L - -#define SN_SLH_DSA_SHAKE_192s "id-slh-dsa-shake-192s" -#define LN_SLH_DSA_SHAKE_192s "SLH-DSA-SHAKE-192s" -#define NID_SLH_DSA_SHAKE_192s 1468 -#define OBJ_SLH_DSA_SHAKE_192s OBJ_sigAlgs,28L - -#define SN_SLH_DSA_SHAKE_192f "id-slh-dsa-shake-192f" -#define LN_SLH_DSA_SHAKE_192f "SLH-DSA-SHAKE-192f" -#define NID_SLH_DSA_SHAKE_192f 1469 -#define OBJ_SLH_DSA_SHAKE_192f OBJ_sigAlgs,29L - -#define SN_SLH_DSA_SHAKE_256s "id-slh-dsa-shake-256s" -#define LN_SLH_DSA_SHAKE_256s "SLH-DSA-SHAKE-256s" -#define NID_SLH_DSA_SHAKE_256s 1470 -#define OBJ_SLH_DSA_SHAKE_256s OBJ_sigAlgs,30L - -#define SN_SLH_DSA_SHAKE_256f "id-slh-dsa-shake-256f" -#define LN_SLH_DSA_SHAKE_256f "SLH-DSA-SHAKE-256f" -#define NID_SLH_DSA_SHAKE_256f 1471 -#define OBJ_SLH_DSA_SHAKE_256f OBJ_sigAlgs,31L - -#define SN_HASH_ML_DSA_44_WITH_SHA512 "id-hash-ml-dsa-44-with-sha512" -#define LN_HASH_ML_DSA_44_WITH_SHA512 "HASH-ML-DSA-44-WITH-SHA512" -#define NID_HASH_ML_DSA_44_WITH_SHA512 1472 -#define OBJ_HASH_ML_DSA_44_WITH_SHA512 OBJ_sigAlgs,32L - -#define SN_HASH_ML_DSA_65_WITH_SHA512 "id-hash-ml-dsa-65-with-sha512" -#define LN_HASH_ML_DSA_65_WITH_SHA512 "HASH-ML-DSA-65-WITH-SHA512" -#define NID_HASH_ML_DSA_65_WITH_SHA512 1473 -#define OBJ_HASH_ML_DSA_65_WITH_SHA512 OBJ_sigAlgs,33L - -#define SN_HASH_ML_DSA_87_WITH_SHA512 "id-hash-ml-dsa-87-with-sha512" -#define LN_HASH_ML_DSA_87_WITH_SHA512 "HASH-ML-DSA-87-WITH-SHA512" -#define NID_HASH_ML_DSA_87_WITH_SHA512 1474 -#define OBJ_HASH_ML_DSA_87_WITH_SHA512 OBJ_sigAlgs,34L - -#define SN_SLH_DSA_SHA2_128s_WITH_SHA256 "id-hash-slh-dsa-sha2-128s-with-sha256" -#define LN_SLH_DSA_SHA2_128s_WITH_SHA256 "SLH-DSA-SHA2-128s-WITH-SHA256" -#define NID_SLH_DSA_SHA2_128s_WITH_SHA256 1475 -#define OBJ_SLH_DSA_SHA2_128s_WITH_SHA256 OBJ_sigAlgs,35L - -#define SN_SLH_DSA_SHA2_128f_WITH_SHA256 "id-hash-slh-dsa-sha2-128f-with-sha256" -#define LN_SLH_DSA_SHA2_128f_WITH_SHA256 "SLH-DSA-SHA2-128f-WITH-SHA256" -#define NID_SLH_DSA_SHA2_128f_WITH_SHA256 1476 -#define OBJ_SLH_DSA_SHA2_128f_WITH_SHA256 OBJ_sigAlgs,36L - -#define SN_SLH_DSA_SHA2_192s_WITH_SHA512 "id-hash-slh-dsa-sha2-192s-with-sha512" -#define LN_SLH_DSA_SHA2_192s_WITH_SHA512 "SLH-DSA-SHA2-192s-WITH-SHA512" -#define NID_SLH_DSA_SHA2_192s_WITH_SHA512 1477 -#define OBJ_SLH_DSA_SHA2_192s_WITH_SHA512 OBJ_sigAlgs,37L - -#define SN_SLH_DSA_SHA2_192f_WITH_SHA512 "id-hash-slh-dsa-sha2-192f-with-sha512" -#define LN_SLH_DSA_SHA2_192f_WITH_SHA512 "SLH-DSA-SHA2-192f-WITH-SHA512" -#define NID_SLH_DSA_SHA2_192f_WITH_SHA512 1478 -#define OBJ_SLH_DSA_SHA2_192f_WITH_SHA512 OBJ_sigAlgs,38L - -#define SN_SLH_DSA_SHA2_256s_WITH_SHA512 "id-hash-slh-dsa-sha2-256s-with-sha512" -#define LN_SLH_DSA_SHA2_256s_WITH_SHA512 "SLH-DSA-SHA2-256s-WITH-SHA512" -#define NID_SLH_DSA_SHA2_256s_WITH_SHA512 1479 -#define OBJ_SLH_DSA_SHA2_256s_WITH_SHA512 OBJ_sigAlgs,39L - -#define SN_SLH_DSA_SHA2_256f_WITH_SHA512 "id-hash-slh-dsa-sha2-256f-with-sha512" -#define LN_SLH_DSA_SHA2_256f_WITH_SHA512 "SLH-DSA-SHA2-256f-WITH-SHA512" -#define NID_SLH_DSA_SHA2_256f_WITH_SHA512 1480 -#define OBJ_SLH_DSA_SHA2_256f_WITH_SHA512 OBJ_sigAlgs,40L - -#define SN_SLH_DSA_SHAKE_128s_WITH_SHAKE128 "id-hash-slh-dsa-shake-128s-with-shake128" -#define LN_SLH_DSA_SHAKE_128s_WITH_SHAKE128 "SLH-DSA-SHAKE-128s-WITH-SHAKE128" -#define NID_SLH_DSA_SHAKE_128s_WITH_SHAKE128 1481 -#define OBJ_SLH_DSA_SHAKE_128s_WITH_SHAKE128 OBJ_sigAlgs,41L - -#define SN_SLH_DSA_SHAKE_128f_WITH_SHAKE128 "id-hash-slh-dsa-shake-128f-with-shake128" -#define LN_SLH_DSA_SHAKE_128f_WITH_SHAKE128 "SLH-DSA-SHAKE-128f-WITH-SHAKE128" -#define NID_SLH_DSA_SHAKE_128f_WITH_SHAKE128 1482 -#define OBJ_SLH_DSA_SHAKE_128f_WITH_SHAKE128 OBJ_sigAlgs,42L - -#define SN_SLH_DSA_SHAKE_192s_WITH_SHAKE256 "id-hash-slh-dsa-shake-192s-with-shake256" -#define LN_SLH_DSA_SHAKE_192s_WITH_SHAKE256 "SLH-DSA-SHAKE-192s-WITH-SHAKE256" -#define NID_SLH_DSA_SHAKE_192s_WITH_SHAKE256 1483 -#define OBJ_SLH_DSA_SHAKE_192s_WITH_SHAKE256 OBJ_sigAlgs,43L - -#define SN_SLH_DSA_SHAKE_192f_WITH_SHAKE256 "id-hash-slh-dsa-shake-192f-with-shake256" -#define LN_SLH_DSA_SHAKE_192f_WITH_SHAKE256 "SLH-DSA-SHAKE-192f-WITH-SHAKE256" -#define NID_SLH_DSA_SHAKE_192f_WITH_SHAKE256 1484 -#define OBJ_SLH_DSA_SHAKE_192f_WITH_SHAKE256 OBJ_sigAlgs,44L - -#define SN_SLH_DSA_SHAKE_256s_WITH_SHAKE256 "id-hash-slh-dsa-shake-256s-with-shake256" -#define LN_SLH_DSA_SHAKE_256s_WITH_SHAKE256 "SLH-DSA-SHAKE-256s-WITH-SHAKE256" -#define NID_SLH_DSA_SHAKE_256s_WITH_SHAKE256 1485 -#define OBJ_SLH_DSA_SHAKE_256s_WITH_SHAKE256 OBJ_sigAlgs,45L - -#define SN_SLH_DSA_SHAKE_256f_WITH_SHAKE256 "id-hash-slh-dsa-shake-256f-with-shake256" -#define LN_SLH_DSA_SHAKE_256f_WITH_SHAKE256 "SLH-DSA-SHAKE-256f-WITH-SHAKE256" -#define NID_SLH_DSA_SHAKE_256f_WITH_SHAKE256 1486 -#define OBJ_SLH_DSA_SHAKE_256f_WITH_SHAKE256 OBJ_sigAlgs,46L - -#define SN_hold_instruction_code "holdInstructionCode" -#define LN_hold_instruction_code "Hold Instruction Code" -#define NID_hold_instruction_code 430 -#define OBJ_hold_instruction_code OBJ_id_ce,23L - -#define OBJ_holdInstruction OBJ_X9_57,2L - -#define SN_hold_instruction_none "holdInstructionNone" -#define LN_hold_instruction_none "Hold Instruction None" -#define NID_hold_instruction_none 431 -#define OBJ_hold_instruction_none OBJ_holdInstruction,1L - -#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer" -#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer" -#define NID_hold_instruction_call_issuer 432 -#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L - -#define SN_hold_instruction_reject "holdInstructionReject" -#define LN_hold_instruction_reject "Hold Instruction Reject" -#define NID_hold_instruction_reject 433 -#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L - -#define SN_itu_t_identified_organization "itu-t-identified-organization" -#define NID_itu_t_identified_organization 1264 -#define OBJ_itu_t_identified_organization OBJ_itu_t,4L - -#define SN_etsi "etsi" -#define NID_etsi 1265 -#define OBJ_etsi OBJ_itu_t_identified_organization,0L - -#define SN_electronic_signature_standard "electronic-signature-standard" -#define NID_electronic_signature_standard 1266 -#define OBJ_electronic_signature_standard OBJ_etsi,1733L - -#define SN_ess_attributes "ess-attributes" -#define NID_ess_attributes 1267 -#define OBJ_ess_attributes OBJ_electronic_signature_standard,2L - -#define SN_id_aa_ets_mimeType "id-aa-ets-mimeType" -#define NID_id_aa_ets_mimeType 1268 -#define OBJ_id_aa_ets_mimeType OBJ_ess_attributes,1L - -#define SN_id_aa_ets_longTermValidation "id-aa-ets-longTermValidation" -#define NID_id_aa_ets_longTermValidation 1269 -#define OBJ_id_aa_ets_longTermValidation OBJ_ess_attributes,2L - -#define SN_id_aa_ets_SignaturePolicyDocument "id-aa-ets-SignaturePolicyDocument" -#define NID_id_aa_ets_SignaturePolicyDocument 1270 -#define OBJ_id_aa_ets_SignaturePolicyDocument OBJ_ess_attributes,3L - -#define SN_id_aa_ets_archiveTimestampV3 "id-aa-ets-archiveTimestampV3" -#define NID_id_aa_ets_archiveTimestampV3 1271 -#define OBJ_id_aa_ets_archiveTimestampV3 OBJ_ess_attributes,4L - -#define SN_id_aa_ATSHashIndex "id-aa-ATSHashIndex" -#define NID_id_aa_ATSHashIndex 1272 -#define OBJ_id_aa_ATSHashIndex OBJ_ess_attributes,5L - -#define SN_cades "cades" -#define NID_cades 1273 -#define OBJ_cades OBJ_etsi,19122L - -#define SN_cades_attributes "cades-attributes" -#define NID_cades_attributes 1274 -#define OBJ_cades_attributes OBJ_cades,1L - -#define SN_id_aa_ets_signerAttrV2 "id-aa-ets-signerAttrV2" -#define NID_id_aa_ets_signerAttrV2 1275 -#define OBJ_id_aa_ets_signerAttrV2 OBJ_cades_attributes,1L - -#define SN_id_aa_ets_sigPolicyStore "id-aa-ets-sigPolicyStore" -#define NID_id_aa_ets_sigPolicyStore 1276 -#define OBJ_id_aa_ets_sigPolicyStore OBJ_cades_attributes,3L - -#define SN_id_aa_ATSHashIndex_v2 "id-aa-ATSHashIndex-v2" -#define NID_id_aa_ATSHashIndex_v2 1277 -#define OBJ_id_aa_ATSHashIndex_v2 OBJ_cades_attributes,4L - -#define SN_id_aa_ATSHashIndex_v3 "id-aa-ATSHashIndex-v3" -#define NID_id_aa_ATSHashIndex_v3 1278 -#define OBJ_id_aa_ATSHashIndex_v3 OBJ_cades_attributes,5L - -#define SN_signedAssertion "signedAssertion" -#define NID_signedAssertion 1279 -#define OBJ_signedAssertion OBJ_cades_attributes,6L - -#define SN_data "data" -#define NID_data 434 -#define OBJ_data OBJ_itu_t,9L - -#define SN_pss "pss" -#define NID_pss 435 -#define OBJ_pss OBJ_data,2342L - -#define SN_ucl "ucl" -#define NID_ucl 436 -#define OBJ_ucl OBJ_pss,19200300L - -#define SN_pilot "pilot" -#define NID_pilot 437 -#define OBJ_pilot OBJ_ucl,100L - -#define LN_pilotAttributeType "pilotAttributeType" -#define NID_pilotAttributeType 438 -#define OBJ_pilotAttributeType OBJ_pilot,1L - -#define LN_pilotAttributeSyntax "pilotAttributeSyntax" -#define NID_pilotAttributeSyntax 439 -#define OBJ_pilotAttributeSyntax OBJ_pilot,3L - -#define LN_pilotObjectClass "pilotObjectClass" -#define NID_pilotObjectClass 440 -#define OBJ_pilotObjectClass OBJ_pilot,4L - -#define LN_pilotGroups "pilotGroups" -#define NID_pilotGroups 441 -#define OBJ_pilotGroups OBJ_pilot,10L - -#define LN_iA5StringSyntax "iA5StringSyntax" -#define NID_iA5StringSyntax 442 -#define OBJ_iA5StringSyntax OBJ_pilotAttributeSyntax,4L - -#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax" -#define NID_caseIgnoreIA5StringSyntax 443 -#define OBJ_caseIgnoreIA5StringSyntax OBJ_pilotAttributeSyntax,5L - -#define LN_pilotObject "pilotObject" -#define NID_pilotObject 444 -#define OBJ_pilotObject OBJ_pilotObjectClass,3L - -#define LN_pilotPerson "pilotPerson" -#define NID_pilotPerson 445 -#define OBJ_pilotPerson OBJ_pilotObjectClass,4L - -#define SN_account "account" -#define NID_account 446 -#define OBJ_account OBJ_pilotObjectClass,5L - -#define SN_document "document" -#define NID_document 447 -#define OBJ_document OBJ_pilotObjectClass,6L - -#define SN_room "room" -#define NID_room 448 -#define OBJ_room OBJ_pilotObjectClass,7L - -#define LN_documentSeries "documentSeries" -#define NID_documentSeries 449 -#define OBJ_documentSeries OBJ_pilotObjectClass,9L - -#define SN_Domain "domain" -#define LN_Domain "Domain" -#define NID_Domain 392 -#define OBJ_Domain OBJ_pilotObjectClass,13L - -#define LN_rFC822localPart "rFC822localPart" -#define NID_rFC822localPart 450 -#define OBJ_rFC822localPart OBJ_pilotObjectClass,14L - -#define LN_dNSDomain "dNSDomain" -#define NID_dNSDomain 451 -#define OBJ_dNSDomain OBJ_pilotObjectClass,15L - -#define LN_domainRelatedObject "domainRelatedObject" -#define NID_domainRelatedObject 452 -#define OBJ_domainRelatedObject OBJ_pilotObjectClass,17L - -#define LN_friendlyCountry "friendlyCountry" -#define NID_friendlyCountry 453 -#define OBJ_friendlyCountry OBJ_pilotObjectClass,18L - -#define LN_simpleSecurityObject "simpleSecurityObject" -#define NID_simpleSecurityObject 454 -#define OBJ_simpleSecurityObject OBJ_pilotObjectClass,19L - -#define LN_pilotOrganization "pilotOrganization" -#define NID_pilotOrganization 455 -#define OBJ_pilotOrganization OBJ_pilotObjectClass,20L - -#define LN_pilotDSA "pilotDSA" -#define NID_pilotDSA 456 -#define OBJ_pilotDSA OBJ_pilotObjectClass,21L - -#define LN_qualityLabelledData "qualityLabelledData" -#define NID_qualityLabelledData 457 -#define OBJ_qualityLabelledData OBJ_pilotObjectClass,22L - -#define SN_userId "UID" -#define LN_userId "userId" -#define NID_userId 458 -#define OBJ_userId OBJ_pilotAttributeType,1L - -#define LN_textEncodedORAddress "textEncodedORAddress" -#define NID_textEncodedORAddress 459 -#define OBJ_textEncodedORAddress OBJ_pilotAttributeType,2L - -#define SN_rfc822Mailbox "mail" -#define LN_rfc822Mailbox "rfc822Mailbox" -#define NID_rfc822Mailbox 460 -#define OBJ_rfc822Mailbox OBJ_pilotAttributeType,3L - -#define SN_info "info" -#define NID_info 461 -#define OBJ_info OBJ_pilotAttributeType,4L - -#define LN_favouriteDrink "favouriteDrink" -#define NID_favouriteDrink 462 -#define OBJ_favouriteDrink OBJ_pilotAttributeType,5L - -#define LN_roomNumber "roomNumber" -#define NID_roomNumber 463 -#define OBJ_roomNumber OBJ_pilotAttributeType,6L - -#define SN_photo "photo" -#define NID_photo 464 -#define OBJ_photo OBJ_pilotAttributeType,7L - -#define LN_userClass "userClass" -#define NID_userClass 465 -#define OBJ_userClass OBJ_pilotAttributeType,8L - -#define SN_host "host" -#define NID_host 466 -#define OBJ_host OBJ_pilotAttributeType,9L - -#define SN_manager "manager" -#define NID_manager 467 -#define OBJ_manager OBJ_pilotAttributeType,10L - -#define LN_documentIdentifier "documentIdentifier" -#define NID_documentIdentifier 468 -#define OBJ_documentIdentifier OBJ_pilotAttributeType,11L - -#define LN_documentTitle "documentTitle" -#define NID_documentTitle 469 -#define OBJ_documentTitle OBJ_pilotAttributeType,12L - -#define LN_documentVersion "documentVersion" -#define NID_documentVersion 470 -#define OBJ_documentVersion OBJ_pilotAttributeType,13L - -#define LN_documentAuthor "documentAuthor" -#define NID_documentAuthor 471 -#define OBJ_documentAuthor OBJ_pilotAttributeType,14L - -#define LN_documentLocation "documentLocation" -#define NID_documentLocation 472 -#define OBJ_documentLocation OBJ_pilotAttributeType,15L - -#define LN_homeTelephoneNumber "homeTelephoneNumber" -#define NID_homeTelephoneNumber 473 -#define OBJ_homeTelephoneNumber OBJ_pilotAttributeType,20L - -#define SN_secretary "secretary" -#define NID_secretary 474 -#define OBJ_secretary OBJ_pilotAttributeType,21L - -#define LN_otherMailbox "otherMailbox" -#define NID_otherMailbox 475 -#define OBJ_otherMailbox OBJ_pilotAttributeType,22L - -#define LN_lastModifiedTime "lastModifiedTime" -#define NID_lastModifiedTime 476 -#define OBJ_lastModifiedTime OBJ_pilotAttributeType,23L - -#define LN_lastModifiedBy "lastModifiedBy" -#define NID_lastModifiedBy 477 -#define OBJ_lastModifiedBy OBJ_pilotAttributeType,24L - -#define SN_domainComponent "DC" -#define LN_domainComponent "domainComponent" -#define NID_domainComponent 391 -#define OBJ_domainComponent OBJ_pilotAttributeType,25L - -#define LN_aRecord "aRecord" -#define NID_aRecord 478 -#define OBJ_aRecord OBJ_pilotAttributeType,26L - -#define LN_pilotAttributeType27 "pilotAttributeType27" -#define NID_pilotAttributeType27 479 -#define OBJ_pilotAttributeType27 OBJ_pilotAttributeType,27L - -#define LN_mXRecord "mXRecord" -#define NID_mXRecord 480 -#define OBJ_mXRecord OBJ_pilotAttributeType,28L - -#define LN_nSRecord "nSRecord" -#define NID_nSRecord 481 -#define OBJ_nSRecord OBJ_pilotAttributeType,29L - -#define LN_sOARecord "sOARecord" -#define NID_sOARecord 482 -#define OBJ_sOARecord OBJ_pilotAttributeType,30L - -#define LN_cNAMERecord "cNAMERecord" -#define NID_cNAMERecord 483 -#define OBJ_cNAMERecord OBJ_pilotAttributeType,31L - -#define LN_associatedDomain "associatedDomain" -#define NID_associatedDomain 484 -#define OBJ_associatedDomain OBJ_pilotAttributeType,37L - -#define LN_associatedName "associatedName" -#define NID_associatedName 485 -#define OBJ_associatedName OBJ_pilotAttributeType,38L - -#define LN_homePostalAddress "homePostalAddress" -#define NID_homePostalAddress 486 -#define OBJ_homePostalAddress OBJ_pilotAttributeType,39L - -#define LN_personalTitle "personalTitle" -#define NID_personalTitle 487 -#define OBJ_personalTitle OBJ_pilotAttributeType,40L - -#define LN_mobileTelephoneNumber "mobileTelephoneNumber" -#define NID_mobileTelephoneNumber 488 -#define OBJ_mobileTelephoneNumber OBJ_pilotAttributeType,41L - -#define LN_pagerTelephoneNumber "pagerTelephoneNumber" -#define NID_pagerTelephoneNumber 489 -#define OBJ_pagerTelephoneNumber OBJ_pilotAttributeType,42L - -#define LN_friendlyCountryName "friendlyCountryName" -#define NID_friendlyCountryName 490 -#define OBJ_friendlyCountryName OBJ_pilotAttributeType,43L - -#define SN_uniqueIdentifier "uid" -#define LN_uniqueIdentifier "uniqueIdentifier" -#define NID_uniqueIdentifier 102 -#define OBJ_uniqueIdentifier OBJ_pilotAttributeType,44L - -#define LN_organizationalStatus "organizationalStatus" -#define NID_organizationalStatus 491 -#define OBJ_organizationalStatus OBJ_pilotAttributeType,45L - -#define LN_janetMailbox "janetMailbox" -#define NID_janetMailbox 492 -#define OBJ_janetMailbox OBJ_pilotAttributeType,46L - -#define LN_mailPreferenceOption "mailPreferenceOption" -#define NID_mailPreferenceOption 493 -#define OBJ_mailPreferenceOption OBJ_pilotAttributeType,47L - -#define LN_buildingName "buildingName" -#define NID_buildingName 494 -#define OBJ_buildingName OBJ_pilotAttributeType,48L - -#define LN_dSAQuality "dSAQuality" -#define NID_dSAQuality 495 -#define OBJ_dSAQuality OBJ_pilotAttributeType,49L - -#define LN_singleLevelQuality "singleLevelQuality" -#define NID_singleLevelQuality 496 -#define OBJ_singleLevelQuality OBJ_pilotAttributeType,50L - -#define LN_subtreeMinimumQuality "subtreeMinimumQuality" -#define NID_subtreeMinimumQuality 497 -#define OBJ_subtreeMinimumQuality OBJ_pilotAttributeType,51L - -#define LN_subtreeMaximumQuality "subtreeMaximumQuality" -#define NID_subtreeMaximumQuality 498 -#define OBJ_subtreeMaximumQuality OBJ_pilotAttributeType,52L - -#define LN_personalSignature "personalSignature" -#define NID_personalSignature 499 -#define OBJ_personalSignature OBJ_pilotAttributeType,53L - -#define LN_dITRedirect "dITRedirect" -#define NID_dITRedirect 500 -#define OBJ_dITRedirect OBJ_pilotAttributeType,54L - -#define SN_audio "audio" -#define NID_audio 501 -#define OBJ_audio OBJ_pilotAttributeType,55L - -#define LN_documentPublisher "documentPublisher" -#define NID_documentPublisher 502 -#define OBJ_documentPublisher OBJ_pilotAttributeType,56L - -#define SN_id_set "id-set" -#define LN_id_set "Secure Electronic Transactions" -#define NID_id_set 512 -#define OBJ_id_set OBJ_international_organizations,42L - -#define SN_set_ctype "set-ctype" -#define LN_set_ctype "content types" -#define NID_set_ctype 513 -#define OBJ_set_ctype OBJ_id_set,0L - -#define SN_set_msgExt "set-msgExt" -#define LN_set_msgExt "message extensions" -#define NID_set_msgExt 514 -#define OBJ_set_msgExt OBJ_id_set,1L - -#define SN_set_attr "set-attr" -#define NID_set_attr 515 -#define OBJ_set_attr OBJ_id_set,3L - -#define SN_set_policy "set-policy" -#define NID_set_policy 516 -#define OBJ_set_policy OBJ_id_set,5L - -#define SN_set_certExt "set-certExt" -#define LN_set_certExt "certificate extensions" -#define NID_set_certExt 517 -#define OBJ_set_certExt OBJ_id_set,7L - -#define SN_set_brand "set-brand" -#define NID_set_brand 518 -#define OBJ_set_brand OBJ_id_set,8L - -#define SN_setct_PANData "setct-PANData" -#define NID_setct_PANData 519 -#define OBJ_setct_PANData OBJ_set_ctype,0L - -#define SN_setct_PANToken "setct-PANToken" -#define NID_setct_PANToken 520 -#define OBJ_setct_PANToken OBJ_set_ctype,1L - -#define SN_setct_PANOnly "setct-PANOnly" -#define NID_setct_PANOnly 521 -#define OBJ_setct_PANOnly OBJ_set_ctype,2L - -#define SN_setct_OIData "setct-OIData" -#define NID_setct_OIData 522 -#define OBJ_setct_OIData OBJ_set_ctype,3L - -#define SN_setct_PI "setct-PI" -#define NID_setct_PI 523 -#define OBJ_setct_PI OBJ_set_ctype,4L - -#define SN_setct_PIData "setct-PIData" -#define NID_setct_PIData 524 -#define OBJ_setct_PIData OBJ_set_ctype,5L - -#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned" -#define NID_setct_PIDataUnsigned 525 -#define OBJ_setct_PIDataUnsigned OBJ_set_ctype,6L - -#define SN_setct_HODInput "setct-HODInput" -#define NID_setct_HODInput 526 -#define OBJ_setct_HODInput OBJ_set_ctype,7L - -#define SN_setct_AuthResBaggage "setct-AuthResBaggage" -#define NID_setct_AuthResBaggage 527 -#define OBJ_setct_AuthResBaggage OBJ_set_ctype,8L - -#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage" -#define NID_setct_AuthRevReqBaggage 528 -#define OBJ_setct_AuthRevReqBaggage OBJ_set_ctype,9L - -#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage" -#define NID_setct_AuthRevResBaggage 529 -#define OBJ_setct_AuthRevResBaggage OBJ_set_ctype,10L - -#define SN_setct_CapTokenSeq "setct-CapTokenSeq" -#define NID_setct_CapTokenSeq 530 -#define OBJ_setct_CapTokenSeq OBJ_set_ctype,11L - -#define SN_setct_PInitResData "setct-PInitResData" -#define NID_setct_PInitResData 531 -#define OBJ_setct_PInitResData OBJ_set_ctype,12L - -#define SN_setct_PI_TBS "setct-PI-TBS" -#define NID_setct_PI_TBS 532 -#define OBJ_setct_PI_TBS OBJ_set_ctype,13L - -#define SN_setct_PResData "setct-PResData" -#define NID_setct_PResData 533 -#define OBJ_setct_PResData OBJ_set_ctype,14L - -#define SN_setct_AuthReqTBS "setct-AuthReqTBS" -#define NID_setct_AuthReqTBS 534 -#define OBJ_setct_AuthReqTBS OBJ_set_ctype,16L - -#define SN_setct_AuthResTBS "setct-AuthResTBS" -#define NID_setct_AuthResTBS 535 -#define OBJ_setct_AuthResTBS OBJ_set_ctype,17L - -#define SN_setct_AuthResTBSX "setct-AuthResTBSX" -#define NID_setct_AuthResTBSX 536 -#define OBJ_setct_AuthResTBSX OBJ_set_ctype,18L - -#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS" -#define NID_setct_AuthTokenTBS 537 -#define OBJ_setct_AuthTokenTBS OBJ_set_ctype,19L - -#define SN_setct_CapTokenData "setct-CapTokenData" -#define NID_setct_CapTokenData 538 -#define OBJ_setct_CapTokenData OBJ_set_ctype,20L - -#define SN_setct_CapTokenTBS "setct-CapTokenTBS" -#define NID_setct_CapTokenTBS 539 -#define OBJ_setct_CapTokenTBS OBJ_set_ctype,21L - -#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg" -#define NID_setct_AcqCardCodeMsg 540 -#define OBJ_setct_AcqCardCodeMsg OBJ_set_ctype,22L - -#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS" -#define NID_setct_AuthRevReqTBS 541 -#define OBJ_setct_AuthRevReqTBS OBJ_set_ctype,23L - -#define SN_setct_AuthRevResData "setct-AuthRevResData" -#define NID_setct_AuthRevResData 542 -#define OBJ_setct_AuthRevResData OBJ_set_ctype,24L - -#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS" -#define NID_setct_AuthRevResTBS 543 -#define OBJ_setct_AuthRevResTBS OBJ_set_ctype,25L - -#define SN_setct_CapReqTBS "setct-CapReqTBS" -#define NID_setct_CapReqTBS 544 -#define OBJ_setct_CapReqTBS OBJ_set_ctype,26L - -#define SN_setct_CapReqTBSX "setct-CapReqTBSX" -#define NID_setct_CapReqTBSX 545 -#define OBJ_setct_CapReqTBSX OBJ_set_ctype,27L - -#define SN_setct_CapResData "setct-CapResData" -#define NID_setct_CapResData 546 -#define OBJ_setct_CapResData OBJ_set_ctype,28L - -#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS" -#define NID_setct_CapRevReqTBS 547 -#define OBJ_setct_CapRevReqTBS OBJ_set_ctype,29L - -#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX" -#define NID_setct_CapRevReqTBSX 548 -#define OBJ_setct_CapRevReqTBSX OBJ_set_ctype,30L - -#define SN_setct_CapRevResData "setct-CapRevResData" -#define NID_setct_CapRevResData 549 -#define OBJ_setct_CapRevResData OBJ_set_ctype,31L - -#define SN_setct_CredReqTBS "setct-CredReqTBS" -#define NID_setct_CredReqTBS 550 -#define OBJ_setct_CredReqTBS OBJ_set_ctype,32L - -#define SN_setct_CredReqTBSX "setct-CredReqTBSX" -#define NID_setct_CredReqTBSX 551 -#define OBJ_setct_CredReqTBSX OBJ_set_ctype,33L - -#define SN_setct_CredResData "setct-CredResData" -#define NID_setct_CredResData 552 -#define OBJ_setct_CredResData OBJ_set_ctype,34L - -#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS" -#define NID_setct_CredRevReqTBS 553 -#define OBJ_setct_CredRevReqTBS OBJ_set_ctype,35L - -#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX" -#define NID_setct_CredRevReqTBSX 554 -#define OBJ_setct_CredRevReqTBSX OBJ_set_ctype,36L - -#define SN_setct_CredRevResData "setct-CredRevResData" -#define NID_setct_CredRevResData 555 -#define OBJ_setct_CredRevResData OBJ_set_ctype,37L - -#define SN_setct_PCertReqData "setct-PCertReqData" -#define NID_setct_PCertReqData 556 -#define OBJ_setct_PCertReqData OBJ_set_ctype,38L - -#define SN_setct_PCertResTBS "setct-PCertResTBS" -#define NID_setct_PCertResTBS 557 -#define OBJ_setct_PCertResTBS OBJ_set_ctype,39L - -#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData" -#define NID_setct_BatchAdminReqData 558 -#define OBJ_setct_BatchAdminReqData OBJ_set_ctype,40L - -#define SN_setct_BatchAdminResData "setct-BatchAdminResData" -#define NID_setct_BatchAdminResData 559 -#define OBJ_setct_BatchAdminResData OBJ_set_ctype,41L - -#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS" -#define NID_setct_CardCInitResTBS 560 -#define OBJ_setct_CardCInitResTBS OBJ_set_ctype,42L - -#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS" -#define NID_setct_MeAqCInitResTBS 561 -#define OBJ_setct_MeAqCInitResTBS OBJ_set_ctype,43L - -#define SN_setct_RegFormResTBS "setct-RegFormResTBS" -#define NID_setct_RegFormResTBS 562 -#define OBJ_setct_RegFormResTBS OBJ_set_ctype,44L - -#define SN_setct_CertReqData "setct-CertReqData" -#define NID_setct_CertReqData 563 -#define OBJ_setct_CertReqData OBJ_set_ctype,45L - -#define SN_setct_CertReqTBS "setct-CertReqTBS" -#define NID_setct_CertReqTBS 564 -#define OBJ_setct_CertReqTBS OBJ_set_ctype,46L - -#define SN_setct_CertResData "setct-CertResData" -#define NID_setct_CertResData 565 -#define OBJ_setct_CertResData OBJ_set_ctype,47L - -#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS" -#define NID_setct_CertInqReqTBS 566 -#define OBJ_setct_CertInqReqTBS OBJ_set_ctype,48L - -#define SN_setct_ErrorTBS "setct-ErrorTBS" -#define NID_setct_ErrorTBS 567 -#define OBJ_setct_ErrorTBS OBJ_set_ctype,49L - -#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE" -#define NID_setct_PIDualSignedTBE 568 -#define OBJ_setct_PIDualSignedTBE OBJ_set_ctype,50L - -#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE" -#define NID_setct_PIUnsignedTBE 569 -#define OBJ_setct_PIUnsignedTBE OBJ_set_ctype,51L - -#define SN_setct_AuthReqTBE "setct-AuthReqTBE" -#define NID_setct_AuthReqTBE 570 -#define OBJ_setct_AuthReqTBE OBJ_set_ctype,52L - -#define SN_setct_AuthResTBE "setct-AuthResTBE" -#define NID_setct_AuthResTBE 571 -#define OBJ_setct_AuthResTBE OBJ_set_ctype,53L - -#define SN_setct_AuthResTBEX "setct-AuthResTBEX" -#define NID_setct_AuthResTBEX 572 -#define OBJ_setct_AuthResTBEX OBJ_set_ctype,54L - -#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE" -#define NID_setct_AuthTokenTBE 573 -#define OBJ_setct_AuthTokenTBE OBJ_set_ctype,55L - -#define SN_setct_CapTokenTBE "setct-CapTokenTBE" -#define NID_setct_CapTokenTBE 574 -#define OBJ_setct_CapTokenTBE OBJ_set_ctype,56L - -#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX" -#define NID_setct_CapTokenTBEX 575 -#define OBJ_setct_CapTokenTBEX OBJ_set_ctype,57L - -#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE" -#define NID_setct_AcqCardCodeMsgTBE 576 -#define OBJ_setct_AcqCardCodeMsgTBE OBJ_set_ctype,58L - -#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE" -#define NID_setct_AuthRevReqTBE 577 -#define OBJ_setct_AuthRevReqTBE OBJ_set_ctype,59L - -#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE" -#define NID_setct_AuthRevResTBE 578 -#define OBJ_setct_AuthRevResTBE OBJ_set_ctype,60L - -#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB" -#define NID_setct_AuthRevResTBEB 579 -#define OBJ_setct_AuthRevResTBEB OBJ_set_ctype,61L - -#define SN_setct_CapReqTBE "setct-CapReqTBE" -#define NID_setct_CapReqTBE 580 -#define OBJ_setct_CapReqTBE OBJ_set_ctype,62L - -#define SN_setct_CapReqTBEX "setct-CapReqTBEX" -#define NID_setct_CapReqTBEX 581 -#define OBJ_setct_CapReqTBEX OBJ_set_ctype,63L - -#define SN_setct_CapResTBE "setct-CapResTBE" -#define NID_setct_CapResTBE 582 -#define OBJ_setct_CapResTBE OBJ_set_ctype,64L - -#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE" -#define NID_setct_CapRevReqTBE 583 -#define OBJ_setct_CapRevReqTBE OBJ_set_ctype,65L - -#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX" -#define NID_setct_CapRevReqTBEX 584 -#define OBJ_setct_CapRevReqTBEX OBJ_set_ctype,66L - -#define SN_setct_CapRevResTBE "setct-CapRevResTBE" -#define NID_setct_CapRevResTBE 585 -#define OBJ_setct_CapRevResTBE OBJ_set_ctype,67L - -#define SN_setct_CredReqTBE "setct-CredReqTBE" -#define NID_setct_CredReqTBE 586 -#define OBJ_setct_CredReqTBE OBJ_set_ctype,68L - -#define SN_setct_CredReqTBEX "setct-CredReqTBEX" -#define NID_setct_CredReqTBEX 587 -#define OBJ_setct_CredReqTBEX OBJ_set_ctype,69L - -#define SN_setct_CredResTBE "setct-CredResTBE" -#define NID_setct_CredResTBE 588 -#define OBJ_setct_CredResTBE OBJ_set_ctype,70L - -#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE" -#define NID_setct_CredRevReqTBE 589 -#define OBJ_setct_CredRevReqTBE OBJ_set_ctype,71L - -#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX" -#define NID_setct_CredRevReqTBEX 590 -#define OBJ_setct_CredRevReqTBEX OBJ_set_ctype,72L - -#define SN_setct_CredRevResTBE "setct-CredRevResTBE" -#define NID_setct_CredRevResTBE 591 -#define OBJ_setct_CredRevResTBE OBJ_set_ctype,73L - -#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE" -#define NID_setct_BatchAdminReqTBE 592 -#define OBJ_setct_BatchAdminReqTBE OBJ_set_ctype,74L - -#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE" -#define NID_setct_BatchAdminResTBE 593 -#define OBJ_setct_BatchAdminResTBE OBJ_set_ctype,75L - -#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE" -#define NID_setct_RegFormReqTBE 594 -#define OBJ_setct_RegFormReqTBE OBJ_set_ctype,76L - -#define SN_setct_CertReqTBE "setct-CertReqTBE" -#define NID_setct_CertReqTBE 595 -#define OBJ_setct_CertReqTBE OBJ_set_ctype,77L - -#define SN_setct_CertReqTBEX "setct-CertReqTBEX" -#define NID_setct_CertReqTBEX 596 -#define OBJ_setct_CertReqTBEX OBJ_set_ctype,78L - -#define SN_setct_CertResTBE "setct-CertResTBE" -#define NID_setct_CertResTBE 597 -#define OBJ_setct_CertResTBE OBJ_set_ctype,79L - -#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS" -#define NID_setct_CRLNotificationTBS 598 -#define OBJ_setct_CRLNotificationTBS OBJ_set_ctype,80L - -#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS" -#define NID_setct_CRLNotificationResTBS 599 -#define OBJ_setct_CRLNotificationResTBS OBJ_set_ctype,81L - -#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS" -#define NID_setct_BCIDistributionTBS 600 -#define OBJ_setct_BCIDistributionTBS OBJ_set_ctype,82L - -#define SN_setext_genCrypt "setext-genCrypt" -#define LN_setext_genCrypt "generic cryptogram" -#define NID_setext_genCrypt 601 -#define OBJ_setext_genCrypt OBJ_set_msgExt,1L - -#define SN_setext_miAuth "setext-miAuth" -#define LN_setext_miAuth "merchant initiated auth" -#define NID_setext_miAuth 602 -#define OBJ_setext_miAuth OBJ_set_msgExt,3L - -#define SN_setext_pinSecure "setext-pinSecure" -#define NID_setext_pinSecure 603 -#define OBJ_setext_pinSecure OBJ_set_msgExt,4L - -#define SN_setext_pinAny "setext-pinAny" -#define NID_setext_pinAny 604 -#define OBJ_setext_pinAny OBJ_set_msgExt,5L - -#define SN_setext_track2 "setext-track2" -#define NID_setext_track2 605 -#define OBJ_setext_track2 OBJ_set_msgExt,7L - -#define SN_setext_cv "setext-cv" -#define LN_setext_cv "additional verification" -#define NID_setext_cv 606 -#define OBJ_setext_cv OBJ_set_msgExt,8L - -#define SN_set_policy_root "set-policy-root" -#define NID_set_policy_root 607 -#define OBJ_set_policy_root OBJ_set_policy,0L - -#define SN_setCext_hashedRoot "setCext-hashedRoot" -#define NID_setCext_hashedRoot 608 -#define OBJ_setCext_hashedRoot OBJ_set_certExt,0L - -#define SN_setCext_certType "setCext-certType" -#define NID_setCext_certType 609 -#define OBJ_setCext_certType OBJ_set_certExt,1L - -#define SN_setCext_merchData "setCext-merchData" -#define NID_setCext_merchData 610 -#define OBJ_setCext_merchData OBJ_set_certExt,2L - -#define SN_setCext_cCertRequired "setCext-cCertRequired" -#define NID_setCext_cCertRequired 611 -#define OBJ_setCext_cCertRequired OBJ_set_certExt,3L - -#define SN_setCext_tunneling "setCext-tunneling" -#define NID_setCext_tunneling 612 -#define OBJ_setCext_tunneling OBJ_set_certExt,4L - -#define SN_setCext_setExt "setCext-setExt" -#define NID_setCext_setExt 613 -#define OBJ_setCext_setExt OBJ_set_certExt,5L - -#define SN_setCext_setQualf "setCext-setQualf" -#define NID_setCext_setQualf 614 -#define OBJ_setCext_setQualf OBJ_set_certExt,6L - -#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities" -#define NID_setCext_PGWYcapabilities 615 -#define OBJ_setCext_PGWYcapabilities OBJ_set_certExt,7L - -#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier" -#define NID_setCext_TokenIdentifier 616 -#define OBJ_setCext_TokenIdentifier OBJ_set_certExt,8L - -#define SN_setCext_Track2Data "setCext-Track2Data" -#define NID_setCext_Track2Data 617 -#define OBJ_setCext_Track2Data OBJ_set_certExt,9L - -#define SN_setCext_TokenType "setCext-TokenType" -#define NID_setCext_TokenType 618 -#define OBJ_setCext_TokenType OBJ_set_certExt,10L - -#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities" -#define NID_setCext_IssuerCapabilities 619 -#define OBJ_setCext_IssuerCapabilities OBJ_set_certExt,11L - -#define SN_setAttr_Cert "setAttr-Cert" -#define NID_setAttr_Cert 620 -#define OBJ_setAttr_Cert OBJ_set_attr,0L - -#define SN_setAttr_PGWYcap "setAttr-PGWYcap" -#define LN_setAttr_PGWYcap "payment gateway capabilities" -#define NID_setAttr_PGWYcap 621 -#define OBJ_setAttr_PGWYcap OBJ_set_attr,1L - -#define SN_setAttr_TokenType "setAttr-TokenType" -#define NID_setAttr_TokenType 622 -#define OBJ_setAttr_TokenType OBJ_set_attr,2L - -#define SN_setAttr_IssCap "setAttr-IssCap" -#define LN_setAttr_IssCap "issuer capabilities" -#define NID_setAttr_IssCap 623 -#define OBJ_setAttr_IssCap OBJ_set_attr,3L - -#define SN_set_rootKeyThumb "set-rootKeyThumb" -#define NID_set_rootKeyThumb 624 -#define OBJ_set_rootKeyThumb OBJ_setAttr_Cert,0L - -#define SN_set_addPolicy "set-addPolicy" -#define NID_set_addPolicy 625 -#define OBJ_set_addPolicy OBJ_setAttr_Cert,1L - -#define SN_setAttr_Token_EMV "setAttr-Token-EMV" -#define NID_setAttr_Token_EMV 626 -#define OBJ_setAttr_Token_EMV OBJ_setAttr_TokenType,1L - -#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime" -#define NID_setAttr_Token_B0Prime 627 -#define OBJ_setAttr_Token_B0Prime OBJ_setAttr_TokenType,2L - -#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM" -#define NID_setAttr_IssCap_CVM 628 -#define OBJ_setAttr_IssCap_CVM OBJ_setAttr_IssCap,3L - -#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2" -#define NID_setAttr_IssCap_T2 629 -#define OBJ_setAttr_IssCap_T2 OBJ_setAttr_IssCap,4L - -#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig" -#define NID_setAttr_IssCap_Sig 630 -#define OBJ_setAttr_IssCap_Sig OBJ_setAttr_IssCap,5L - -#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm" -#define LN_setAttr_GenCryptgrm "generate cryptogram" -#define NID_setAttr_GenCryptgrm 631 -#define OBJ_setAttr_GenCryptgrm OBJ_setAttr_IssCap_CVM,1L - -#define SN_setAttr_T2Enc "setAttr-T2Enc" -#define LN_setAttr_T2Enc "encrypted track 2" -#define NID_setAttr_T2Enc 632 -#define OBJ_setAttr_T2Enc OBJ_setAttr_IssCap_T2,1L - -#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt" -#define LN_setAttr_T2cleartxt "cleartext track 2" -#define NID_setAttr_T2cleartxt 633 -#define OBJ_setAttr_T2cleartxt OBJ_setAttr_IssCap_T2,2L - -#define SN_setAttr_TokICCsig "setAttr-TokICCsig" -#define LN_setAttr_TokICCsig "ICC or token signature" -#define NID_setAttr_TokICCsig 634 -#define OBJ_setAttr_TokICCsig OBJ_setAttr_IssCap_Sig,1L - -#define SN_setAttr_SecDevSig "setAttr-SecDevSig" -#define LN_setAttr_SecDevSig "secure device signature" -#define NID_setAttr_SecDevSig 635 -#define OBJ_setAttr_SecDevSig OBJ_setAttr_IssCap_Sig,2L - -#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA" -#define NID_set_brand_IATA_ATA 636 -#define OBJ_set_brand_IATA_ATA OBJ_set_brand,1L - -#define SN_set_brand_Diners "set-brand-Diners" -#define NID_set_brand_Diners 637 -#define OBJ_set_brand_Diners OBJ_set_brand,30L - -#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress" -#define NID_set_brand_AmericanExpress 638 -#define OBJ_set_brand_AmericanExpress OBJ_set_brand,34L - -#define SN_set_brand_JCB "set-brand-JCB" -#define NID_set_brand_JCB 639 -#define OBJ_set_brand_JCB OBJ_set_brand,35L - -#define SN_set_brand_Visa "set-brand-Visa" -#define NID_set_brand_Visa 640 -#define OBJ_set_brand_Visa OBJ_set_brand,4L - -#define SN_set_brand_MasterCard "set-brand-MasterCard" -#define NID_set_brand_MasterCard 641 -#define OBJ_set_brand_MasterCard OBJ_set_brand,5L - -#define SN_set_brand_Novus "set-brand-Novus" -#define NID_set_brand_Novus 642 -#define OBJ_set_brand_Novus OBJ_set_brand,6011L - -#define SN_des_cdmf "DES-CDMF" -#define LN_des_cdmf "des-cdmf" -#define NID_des_cdmf 643 -#define OBJ_des_cdmf OBJ_rsadsi,3L,10L - -#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET" -#define NID_rsaOAEPEncryptionSET 644 -#define OBJ_rsaOAEPEncryptionSET OBJ_rsadsi,1L,1L,6L - -#define SN_ipsec3 "Oakley-EC2N-3" -#define LN_ipsec3 "ipsec3" -#define NID_ipsec3 749 - -#define SN_ipsec4 "Oakley-EC2N-4" -#define LN_ipsec4 "ipsec4" -#define NID_ipsec4 750 - -#define SN_whirlpool "whirlpool" -#define NID_whirlpool 804 -#define OBJ_whirlpool OBJ_iso,0L,10118L,3L,0L,55L - -#define SN_cryptopro "cryptopro" -#define NID_cryptopro 805 -#define OBJ_cryptopro OBJ_member_body,643L,2L,2L - -#define SN_cryptocom "cryptocom" -#define NID_cryptocom 806 -#define OBJ_cryptocom OBJ_member_body,643L,2L,9L - -#define SN_id_tc26 "id-tc26" -#define NID_id_tc26 974 -#define OBJ_id_tc26 OBJ_member_body,643L,7L,1L - -#define SN_id_GostR3411_94_with_GostR3410_2001 "id-GostR3411-94-with-GostR3410-2001" -#define LN_id_GostR3411_94_with_GostR3410_2001 "GOST R 34.11-94 with GOST R 34.10-2001" -#define NID_id_GostR3411_94_with_GostR3410_2001 807 -#define OBJ_id_GostR3411_94_with_GostR3410_2001 OBJ_cryptopro,3L - -#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94" -#define LN_id_GostR3411_94_with_GostR3410_94 "GOST R 34.11-94 with GOST R 34.10-94" -#define NID_id_GostR3411_94_with_GostR3410_94 808 -#define OBJ_id_GostR3411_94_with_GostR3410_94 OBJ_cryptopro,4L - -#define SN_id_GostR3411_94 "md_gost94" -#define LN_id_GostR3411_94 "GOST R 34.11-94" -#define NID_id_GostR3411_94 809 -#define OBJ_id_GostR3411_94 OBJ_cryptopro,9L - -#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94" -#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94" -#define NID_id_HMACGostR3411_94 810 -#define OBJ_id_HMACGostR3411_94 OBJ_cryptopro,10L - -#define SN_id_GostR3410_2001 "gost2001" -#define LN_id_GostR3410_2001 "GOST R 34.10-2001" -#define NID_id_GostR3410_2001 811 -#define OBJ_id_GostR3410_2001 OBJ_cryptopro,19L - -#define SN_id_GostR3410_94 "gost94" -#define LN_id_GostR3410_94 "GOST R 34.10-94" -#define NID_id_GostR3410_94 812 -#define OBJ_id_GostR3410_94 OBJ_cryptopro,20L - -#define SN_id_Gost28147_89 "gost89" -#define LN_id_Gost28147_89 "GOST 28147-89" -#define NID_id_Gost28147_89 813 -#define OBJ_id_Gost28147_89 OBJ_cryptopro,21L - -#define SN_gost89_cnt "gost89-cnt" -#define NID_gost89_cnt 814 - -#define SN_gost89_cnt_12 "gost89-cnt-12" -#define NID_gost89_cnt_12 975 - -#define SN_gost89_cbc "gost89-cbc" -#define NID_gost89_cbc 1009 - -#define SN_gost89_ecb "gost89-ecb" -#define NID_gost89_ecb 1010 - -#define SN_gost89_ctr "gost89-ctr" -#define NID_gost89_ctr 1011 - -#define SN_id_Gost28147_89_MAC "gost-mac" -#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC" -#define NID_id_Gost28147_89_MAC 815 -#define OBJ_id_Gost28147_89_MAC OBJ_cryptopro,22L - -#define SN_gost_mac_12 "gost-mac-12" -#define NID_gost_mac_12 976 - -#define SN_id_GostR3411_94_prf "prf-gostr3411-94" -#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF" -#define NID_id_GostR3411_94_prf 816 -#define OBJ_id_GostR3411_94_prf OBJ_cryptopro,23L - -#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH" -#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH" -#define NID_id_GostR3410_2001DH 817 -#define OBJ_id_GostR3410_2001DH OBJ_cryptopro,98L - -#define SN_id_GostR3410_94DH "id-GostR3410-94DH" -#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH" -#define NID_id_GostR3410_94DH 818 -#define OBJ_id_GostR3410_94DH OBJ_cryptopro,99L - -#define SN_id_Gost28147_89_CryptoPro_KeyMeshing "id-Gost28147-89-CryptoPro-KeyMeshing" -#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819 -#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing OBJ_cryptopro,14L,1L - -#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing" -#define NID_id_Gost28147_89_None_KeyMeshing 820 -#define OBJ_id_Gost28147_89_None_KeyMeshing OBJ_cryptopro,14L,0L - -#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet" -#define NID_id_GostR3411_94_TestParamSet 821 -#define OBJ_id_GostR3411_94_TestParamSet OBJ_cryptopro,30L,0L - -#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet" -#define NID_id_GostR3411_94_CryptoProParamSet 822 -#define OBJ_id_GostR3411_94_CryptoProParamSet OBJ_cryptopro,30L,1L - -#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet" -#define NID_id_Gost28147_89_TestParamSet 823 -#define OBJ_id_Gost28147_89_TestParamSet OBJ_cryptopro,31L,0L - -#define SN_id_Gost28147_89_CryptoPro_A_ParamSet "id-Gost28147-89-CryptoPro-A-ParamSet" -#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824 -#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet OBJ_cryptopro,31L,1L - -#define SN_id_Gost28147_89_CryptoPro_B_ParamSet "id-Gost28147-89-CryptoPro-B-ParamSet" -#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825 -#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet OBJ_cryptopro,31L,2L - -#define SN_id_Gost28147_89_CryptoPro_C_ParamSet "id-Gost28147-89-CryptoPro-C-ParamSet" -#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826 -#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet OBJ_cryptopro,31L,3L - -#define SN_id_Gost28147_89_CryptoPro_D_ParamSet "id-Gost28147-89-CryptoPro-D-ParamSet" -#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827 -#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet OBJ_cryptopro,31L,4L - -#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" -#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828 -#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet OBJ_cryptopro,31L,5L - -#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" -#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829 -#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet OBJ_cryptopro,31L,6L - -#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" -#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830 -#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet OBJ_cryptopro,31L,7L - -#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet" -#define NID_id_GostR3410_94_TestParamSet 831 -#define OBJ_id_GostR3410_94_TestParamSet OBJ_cryptopro,32L,0L - -#define SN_id_GostR3410_94_CryptoPro_A_ParamSet "id-GostR3410-94-CryptoPro-A-ParamSet" -#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832 -#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet OBJ_cryptopro,32L,2L - -#define SN_id_GostR3410_94_CryptoPro_B_ParamSet "id-GostR3410-94-CryptoPro-B-ParamSet" -#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833 -#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet OBJ_cryptopro,32L,3L - -#define SN_id_GostR3410_94_CryptoPro_C_ParamSet "id-GostR3410-94-CryptoPro-C-ParamSet" -#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834 -#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet OBJ_cryptopro,32L,4L - -#define SN_id_GostR3410_94_CryptoPro_D_ParamSet "id-GostR3410-94-CryptoPro-D-ParamSet" -#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835 -#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet OBJ_cryptopro,32L,5L - -#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet "id-GostR3410-94-CryptoPro-XchA-ParamSet" -#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836 -#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet OBJ_cryptopro,33L,1L - -#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet "id-GostR3410-94-CryptoPro-XchB-ParamSet" -#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837 -#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet OBJ_cryptopro,33L,2L - -#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet "id-GostR3410-94-CryptoPro-XchC-ParamSet" -#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838 -#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet OBJ_cryptopro,33L,3L - -#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet" -#define NID_id_GostR3410_2001_TestParamSet 839 -#define OBJ_id_GostR3410_2001_TestParamSet OBJ_cryptopro,35L,0L - -#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet "id-GostR3410-2001-CryptoPro-A-ParamSet" -#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840 -#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet OBJ_cryptopro,35L,1L - -#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet "id-GostR3410-2001-CryptoPro-B-ParamSet" -#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841 -#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet OBJ_cryptopro,35L,2L - -#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet "id-GostR3410-2001-CryptoPro-C-ParamSet" -#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842 -#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet OBJ_cryptopro,35L,3L - -#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet "id-GostR3410-2001-CryptoPro-XchA-ParamSet" -#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843 -#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet OBJ_cryptopro,36L,0L - -#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet "id-GostR3410-2001-CryptoPro-XchB-ParamSet" -#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844 -#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet OBJ_cryptopro,36L,1L - -#define SN_id_GostR3410_94_a "id-GostR3410-94-a" -#define NID_id_GostR3410_94_a 845 -#define OBJ_id_GostR3410_94_a OBJ_id_GostR3410_94,1L - -#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis" -#define NID_id_GostR3410_94_aBis 846 -#define OBJ_id_GostR3410_94_aBis OBJ_id_GostR3410_94,2L - -#define SN_id_GostR3410_94_b "id-GostR3410-94-b" -#define NID_id_GostR3410_94_b 847 -#define OBJ_id_GostR3410_94_b OBJ_id_GostR3410_94,3L - -#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis" -#define NID_id_GostR3410_94_bBis 848 -#define OBJ_id_GostR3410_94_bBis OBJ_id_GostR3410_94,4L - -#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc" -#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet" -#define NID_id_Gost28147_89_cc 849 -#define OBJ_id_Gost28147_89_cc OBJ_cryptocom,1L,6L,1L - -#define SN_id_GostR3410_94_cc "gost94cc" -#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom" -#define NID_id_GostR3410_94_cc 850 -#define OBJ_id_GostR3410_94_cc OBJ_cryptocom,1L,5L,3L - -#define SN_id_GostR3410_2001_cc "gost2001cc" -#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom" -#define NID_id_GostR3410_2001_cc 851 -#define OBJ_id_GostR3410_2001_cc OBJ_cryptocom,1L,5L,4L - -#define SN_id_GostR3411_94_with_GostR3410_94_cc "id-GostR3411-94-with-GostR3410-94-cc" -#define LN_id_GostR3411_94_with_GostR3410_94_cc "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" -#define NID_id_GostR3411_94_with_GostR3410_94_cc 852 -#define OBJ_id_GostR3411_94_with_GostR3410_94_cc OBJ_cryptocom,1L,3L,3L - -#define SN_id_GostR3411_94_with_GostR3410_2001_cc "id-GostR3411-94-with-GostR3410-2001-cc" -#define LN_id_GostR3411_94_with_GostR3410_2001_cc "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" -#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853 -#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc OBJ_cryptocom,1L,3L,4L - -#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc" -#define LN_id_GostR3410_2001_ParamSet_cc "GOST R 3410-2001 Parameter Set Cryptocom" -#define NID_id_GostR3410_2001_ParamSet_cc 854 -#define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L - -#define SN_id_tc26_algorithms "id-tc26-algorithms" -#define NID_id_tc26_algorithms 977 -#define OBJ_id_tc26_algorithms OBJ_id_tc26,1L - -#define SN_id_tc26_sign "id-tc26-sign" -#define NID_id_tc26_sign 978 -#define OBJ_id_tc26_sign OBJ_id_tc26_algorithms,1L - -#define SN_id_GostR3410_2012_256 "gost2012_256" -#define LN_id_GostR3410_2012_256 "GOST R 34.10-2012 with 256 bit modulus" -#define NID_id_GostR3410_2012_256 979 -#define OBJ_id_GostR3410_2012_256 OBJ_id_tc26_sign,1L - -#define SN_id_GostR3410_2012_512 "gost2012_512" -#define LN_id_GostR3410_2012_512 "GOST R 34.10-2012 with 512 bit modulus" -#define NID_id_GostR3410_2012_512 980 -#define OBJ_id_GostR3410_2012_512 OBJ_id_tc26_sign,2L - -#define SN_id_tc26_digest "id-tc26-digest" -#define NID_id_tc26_digest 981 -#define OBJ_id_tc26_digest OBJ_id_tc26_algorithms,2L - -#define SN_id_GostR3411_2012_256 "md_gost12_256" -#define LN_id_GostR3411_2012_256 "GOST R 34.11-2012 with 256 bit hash" -#define NID_id_GostR3411_2012_256 982 -#define OBJ_id_GostR3411_2012_256 OBJ_id_tc26_digest,2L - -#define SN_id_GostR3411_2012_512 "md_gost12_512" -#define LN_id_GostR3411_2012_512 "GOST R 34.11-2012 with 512 bit hash" -#define NID_id_GostR3411_2012_512 983 -#define OBJ_id_GostR3411_2012_512 OBJ_id_tc26_digest,3L - -#define SN_id_tc26_signwithdigest "id-tc26-signwithdigest" -#define NID_id_tc26_signwithdigest 984 -#define OBJ_id_tc26_signwithdigest OBJ_id_tc26_algorithms,3L - -#define SN_id_tc26_signwithdigest_gost3410_2012_256 "id-tc26-signwithdigest-gost3410-2012-256" -#define LN_id_tc26_signwithdigest_gost3410_2012_256 "GOST R 34.10-2012 with GOST R 34.11-2012 (256 bit)" -#define NID_id_tc26_signwithdigest_gost3410_2012_256 985 -#define OBJ_id_tc26_signwithdigest_gost3410_2012_256 OBJ_id_tc26_signwithdigest,2L - -#define SN_id_tc26_signwithdigest_gost3410_2012_512 "id-tc26-signwithdigest-gost3410-2012-512" -#define LN_id_tc26_signwithdigest_gost3410_2012_512 "GOST R 34.10-2012 with GOST R 34.11-2012 (512 bit)" -#define NID_id_tc26_signwithdigest_gost3410_2012_512 986 -#define OBJ_id_tc26_signwithdigest_gost3410_2012_512 OBJ_id_tc26_signwithdigest,3L - -#define SN_id_tc26_mac "id-tc26-mac" -#define NID_id_tc26_mac 987 -#define OBJ_id_tc26_mac OBJ_id_tc26_algorithms,4L - -#define SN_id_tc26_hmac_gost_3411_2012_256 "id-tc26-hmac-gost-3411-2012-256" -#define LN_id_tc26_hmac_gost_3411_2012_256 "HMAC GOST 34.11-2012 256 bit" -#define NID_id_tc26_hmac_gost_3411_2012_256 988 -#define OBJ_id_tc26_hmac_gost_3411_2012_256 OBJ_id_tc26_mac,1L - -#define SN_id_tc26_hmac_gost_3411_2012_512 "id-tc26-hmac-gost-3411-2012-512" -#define LN_id_tc26_hmac_gost_3411_2012_512 "HMAC GOST 34.11-2012 512 bit" -#define NID_id_tc26_hmac_gost_3411_2012_512 989 -#define OBJ_id_tc26_hmac_gost_3411_2012_512 OBJ_id_tc26_mac,2L - -#define SN_id_tc26_cipher "id-tc26-cipher" -#define NID_id_tc26_cipher 990 -#define OBJ_id_tc26_cipher OBJ_id_tc26_algorithms,5L - -#define SN_id_tc26_cipher_gostr3412_2015_magma "id-tc26-cipher-gostr3412-2015-magma" -#define NID_id_tc26_cipher_gostr3412_2015_magma 1173 -#define OBJ_id_tc26_cipher_gostr3412_2015_magma OBJ_id_tc26_cipher,1L - -#define SN_magma_ctr_acpkm "magma-ctr-acpkm" -#define NID_magma_ctr_acpkm 1174 -#define OBJ_magma_ctr_acpkm OBJ_id_tc26_cipher_gostr3412_2015_magma,1L - -#define SN_magma_ctr_acpkm_omac "magma-ctr-acpkm-omac" -#define NID_magma_ctr_acpkm_omac 1175 -#define OBJ_magma_ctr_acpkm_omac OBJ_id_tc26_cipher_gostr3412_2015_magma,2L - -#define SN_id_tc26_cipher_gostr3412_2015_kuznyechik "id-tc26-cipher-gostr3412-2015-kuznyechik" -#define NID_id_tc26_cipher_gostr3412_2015_kuznyechik 1176 -#define OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik OBJ_id_tc26_cipher,2L - -#define SN_kuznyechik_ctr_acpkm "kuznyechik-ctr-acpkm" -#define NID_kuznyechik_ctr_acpkm 1177 -#define OBJ_kuznyechik_ctr_acpkm OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik,1L - -#define SN_kuznyechik_ctr_acpkm_omac "kuznyechik-ctr-acpkm-omac" -#define NID_kuznyechik_ctr_acpkm_omac 1178 -#define OBJ_kuznyechik_ctr_acpkm_omac OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik,2L - -#define SN_id_tc26_agreement "id-tc26-agreement" -#define NID_id_tc26_agreement 991 -#define OBJ_id_tc26_agreement OBJ_id_tc26_algorithms,6L - -#define SN_id_tc26_agreement_gost_3410_2012_256 "id-tc26-agreement-gost-3410-2012-256" -#define NID_id_tc26_agreement_gost_3410_2012_256 992 -#define OBJ_id_tc26_agreement_gost_3410_2012_256 OBJ_id_tc26_agreement,1L - -#define SN_id_tc26_agreement_gost_3410_2012_512 "id-tc26-agreement-gost-3410-2012-512" -#define NID_id_tc26_agreement_gost_3410_2012_512 993 -#define OBJ_id_tc26_agreement_gost_3410_2012_512 OBJ_id_tc26_agreement,2L - -#define SN_id_tc26_wrap "id-tc26-wrap" -#define NID_id_tc26_wrap 1179 -#define OBJ_id_tc26_wrap OBJ_id_tc26_algorithms,7L - -#define SN_id_tc26_wrap_gostr3412_2015_magma "id-tc26-wrap-gostr3412-2015-magma" -#define NID_id_tc26_wrap_gostr3412_2015_magma 1180 -#define OBJ_id_tc26_wrap_gostr3412_2015_magma OBJ_id_tc26_wrap,1L - -#define SN_magma_kexp15 "magma-kexp15" -#define NID_magma_kexp15 1181 -#define OBJ_magma_kexp15 OBJ_id_tc26_wrap_gostr3412_2015_magma,1L - -#define SN_id_tc26_wrap_gostr3412_2015_kuznyechik "id-tc26-wrap-gostr3412-2015-kuznyechik" -#define NID_id_tc26_wrap_gostr3412_2015_kuznyechik 1182 -#define OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik OBJ_id_tc26_wrap,2L - -#define SN_kuznyechik_kexp15 "kuznyechik-kexp15" -#define NID_kuznyechik_kexp15 1183 -#define OBJ_kuznyechik_kexp15 OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik,1L - -#define SN_id_tc26_constants "id-tc26-constants" -#define NID_id_tc26_constants 994 -#define OBJ_id_tc26_constants OBJ_id_tc26,2L - -#define SN_id_tc26_sign_constants "id-tc26-sign-constants" -#define NID_id_tc26_sign_constants 995 -#define OBJ_id_tc26_sign_constants OBJ_id_tc26_constants,1L - -#define SN_id_tc26_gost_3410_2012_256_constants "id-tc26-gost-3410-2012-256-constants" -#define NID_id_tc26_gost_3410_2012_256_constants 1147 -#define OBJ_id_tc26_gost_3410_2012_256_constants OBJ_id_tc26_sign_constants,1L - -#define SN_id_tc26_gost_3410_2012_256_paramSetA "id-tc26-gost-3410-2012-256-paramSetA" -#define LN_id_tc26_gost_3410_2012_256_paramSetA "GOST R 34.10-2012 (256 bit) ParamSet A" -#define NID_id_tc26_gost_3410_2012_256_paramSetA 1148 -#define OBJ_id_tc26_gost_3410_2012_256_paramSetA OBJ_id_tc26_gost_3410_2012_256_constants,1L - -#define SN_id_tc26_gost_3410_2012_256_paramSetB "id-tc26-gost-3410-2012-256-paramSetB" -#define LN_id_tc26_gost_3410_2012_256_paramSetB "GOST R 34.10-2012 (256 bit) ParamSet B" -#define NID_id_tc26_gost_3410_2012_256_paramSetB 1184 -#define OBJ_id_tc26_gost_3410_2012_256_paramSetB OBJ_id_tc26_gost_3410_2012_256_constants,2L - -#define SN_id_tc26_gost_3410_2012_256_paramSetC "id-tc26-gost-3410-2012-256-paramSetC" -#define LN_id_tc26_gost_3410_2012_256_paramSetC "GOST R 34.10-2012 (256 bit) ParamSet C" -#define NID_id_tc26_gost_3410_2012_256_paramSetC 1185 -#define OBJ_id_tc26_gost_3410_2012_256_paramSetC OBJ_id_tc26_gost_3410_2012_256_constants,3L - -#define SN_id_tc26_gost_3410_2012_256_paramSetD "id-tc26-gost-3410-2012-256-paramSetD" -#define LN_id_tc26_gost_3410_2012_256_paramSetD "GOST R 34.10-2012 (256 bit) ParamSet D" -#define NID_id_tc26_gost_3410_2012_256_paramSetD 1186 -#define OBJ_id_tc26_gost_3410_2012_256_paramSetD OBJ_id_tc26_gost_3410_2012_256_constants,4L - -#define SN_id_tc26_gost_3410_2012_512_constants "id-tc26-gost-3410-2012-512-constants" -#define NID_id_tc26_gost_3410_2012_512_constants 996 -#define OBJ_id_tc26_gost_3410_2012_512_constants OBJ_id_tc26_sign_constants,2L - -#define SN_id_tc26_gost_3410_2012_512_paramSetTest "id-tc26-gost-3410-2012-512-paramSetTest" -#define LN_id_tc26_gost_3410_2012_512_paramSetTest "GOST R 34.10-2012 (512 bit) testing parameter set" -#define NID_id_tc26_gost_3410_2012_512_paramSetTest 997 -#define OBJ_id_tc26_gost_3410_2012_512_paramSetTest OBJ_id_tc26_gost_3410_2012_512_constants,0L - -#define SN_id_tc26_gost_3410_2012_512_paramSetA "id-tc26-gost-3410-2012-512-paramSetA" -#define LN_id_tc26_gost_3410_2012_512_paramSetA "GOST R 34.10-2012 (512 bit) ParamSet A" -#define NID_id_tc26_gost_3410_2012_512_paramSetA 998 -#define OBJ_id_tc26_gost_3410_2012_512_paramSetA OBJ_id_tc26_gost_3410_2012_512_constants,1L - -#define SN_id_tc26_gost_3410_2012_512_paramSetB "id-tc26-gost-3410-2012-512-paramSetB" -#define LN_id_tc26_gost_3410_2012_512_paramSetB "GOST R 34.10-2012 (512 bit) ParamSet B" -#define NID_id_tc26_gost_3410_2012_512_paramSetB 999 -#define OBJ_id_tc26_gost_3410_2012_512_paramSetB OBJ_id_tc26_gost_3410_2012_512_constants,2L - -#define SN_id_tc26_gost_3410_2012_512_paramSetC "id-tc26-gost-3410-2012-512-paramSetC" -#define LN_id_tc26_gost_3410_2012_512_paramSetC "GOST R 34.10-2012 (512 bit) ParamSet C" -#define NID_id_tc26_gost_3410_2012_512_paramSetC 1149 -#define OBJ_id_tc26_gost_3410_2012_512_paramSetC OBJ_id_tc26_gost_3410_2012_512_constants,3L - -#define SN_id_tc26_digest_constants "id-tc26-digest-constants" -#define NID_id_tc26_digest_constants 1000 -#define OBJ_id_tc26_digest_constants OBJ_id_tc26_constants,2L - -#define SN_id_tc26_cipher_constants "id-tc26-cipher-constants" -#define NID_id_tc26_cipher_constants 1001 -#define OBJ_id_tc26_cipher_constants OBJ_id_tc26_constants,5L - -#define SN_id_tc26_gost_28147_constants "id-tc26-gost-28147-constants" -#define NID_id_tc26_gost_28147_constants 1002 -#define OBJ_id_tc26_gost_28147_constants OBJ_id_tc26_cipher_constants,1L - -#define SN_id_tc26_gost_28147_param_Z "id-tc26-gost-28147-param-Z" -#define LN_id_tc26_gost_28147_param_Z "GOST 28147-89 TC26 parameter set" -#define NID_id_tc26_gost_28147_param_Z 1003 -#define OBJ_id_tc26_gost_28147_param_Z OBJ_id_tc26_gost_28147_constants,1L - -#define SN_INN "INN" -#define LN_INN "INN" -#define NID_INN 1004 -#define OBJ_INN OBJ_member_body,643L,3L,131L,1L,1L - -#define SN_OGRN "OGRN" -#define LN_OGRN "OGRN" -#define NID_OGRN 1005 -#define OBJ_OGRN OBJ_member_body,643L,100L,1L - -#define SN_SNILS "SNILS" -#define LN_SNILS "SNILS" -#define NID_SNILS 1006 -#define OBJ_SNILS OBJ_member_body,643L,100L,3L - -#define SN_OGRNIP "OGRNIP" -#define LN_OGRNIP "OGRNIP" -#define NID_OGRNIP 1226 -#define OBJ_OGRNIP OBJ_member_body,643L,100L,5L - -#define SN_subjectSignTool "subjectSignTool" -#define LN_subjectSignTool "Signing Tool of Subject" -#define NID_subjectSignTool 1007 -#define OBJ_subjectSignTool OBJ_member_body,643L,100L,111L - -#define SN_issuerSignTool "issuerSignTool" -#define LN_issuerSignTool "Signing Tool of Issuer" -#define NID_issuerSignTool 1008 -#define OBJ_issuerSignTool OBJ_member_body,643L,100L,112L - -#define SN_classSignTool "classSignTool" -#define LN_classSignTool "Class of Signing Tool" -#define NID_classSignTool 1227 -#define OBJ_classSignTool OBJ_member_body,643L,100L,113L - -#define SN_classSignToolKC1 "classSignToolKC1" -#define LN_classSignToolKC1 "Class of Signing Tool KC1" -#define NID_classSignToolKC1 1228 -#define OBJ_classSignToolKC1 OBJ_member_body,643L,100L,113L,1L - -#define SN_classSignToolKC2 "classSignToolKC2" -#define LN_classSignToolKC2 "Class of Signing Tool KC2" -#define NID_classSignToolKC2 1229 -#define OBJ_classSignToolKC2 OBJ_member_body,643L,100L,113L,2L - -#define SN_classSignToolKC3 "classSignToolKC3" -#define LN_classSignToolKC3 "Class of Signing Tool KC3" -#define NID_classSignToolKC3 1230 -#define OBJ_classSignToolKC3 OBJ_member_body,643L,100L,113L,3L - -#define SN_classSignToolKB1 "classSignToolKB1" -#define LN_classSignToolKB1 "Class of Signing Tool KB1" -#define NID_classSignToolKB1 1231 -#define OBJ_classSignToolKB1 OBJ_member_body,643L,100L,113L,4L - -#define SN_classSignToolKB2 "classSignToolKB2" -#define LN_classSignToolKB2 "Class of Signing Tool KB2" -#define NID_classSignToolKB2 1232 -#define OBJ_classSignToolKB2 OBJ_member_body,643L,100L,113L,5L - -#define SN_classSignToolKA1 "classSignToolKA1" -#define LN_classSignToolKA1 "Class of Signing Tool KA1" -#define NID_classSignToolKA1 1233 -#define OBJ_classSignToolKA1 OBJ_member_body,643L,100L,113L,6L - -#define SN_kuznyechik_ecb "kuznyechik-ecb" -#define NID_kuznyechik_ecb 1012 - -#define SN_kuznyechik_ctr "kuznyechik-ctr" -#define NID_kuznyechik_ctr 1013 - -#define SN_kuznyechik_ofb "kuznyechik-ofb" -#define NID_kuznyechik_ofb 1014 - -#define SN_kuznyechik_cbc "kuznyechik-cbc" -#define NID_kuznyechik_cbc 1015 - -#define SN_kuznyechik_cfb "kuznyechik-cfb" -#define NID_kuznyechik_cfb 1016 - -#define SN_kuznyechik_mac "kuznyechik-mac" -#define NID_kuznyechik_mac 1017 - -#define SN_magma_ecb "magma-ecb" -#define NID_magma_ecb 1187 - -#define SN_magma_ctr "magma-ctr" -#define NID_magma_ctr 1188 - -#define SN_magma_ofb "magma-ofb" -#define NID_magma_ofb 1189 - -#define SN_magma_cbc "magma-cbc" -#define NID_magma_cbc 1190 - -#define SN_magma_cfb "magma-cfb" -#define NID_magma_cfb 1191 - -#define SN_magma_mac "magma-mac" -#define NID_magma_mac 1192 - -#define SN_camellia_128_cbc "CAMELLIA-128-CBC" -#define LN_camellia_128_cbc "camellia-128-cbc" -#define NID_camellia_128_cbc 751 -#define OBJ_camellia_128_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,2L - -#define SN_camellia_192_cbc "CAMELLIA-192-CBC" -#define LN_camellia_192_cbc "camellia-192-cbc" -#define NID_camellia_192_cbc 752 -#define OBJ_camellia_192_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,3L - -#define SN_camellia_256_cbc "CAMELLIA-256-CBC" -#define LN_camellia_256_cbc "camellia-256-cbc" -#define NID_camellia_256_cbc 753 -#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L - -#define SN_id_camellia128_wrap "id-camellia128-wrap" -#define NID_id_camellia128_wrap 907 -#define OBJ_id_camellia128_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,2L - -#define SN_id_camellia192_wrap "id-camellia192-wrap" -#define NID_id_camellia192_wrap 908 -#define OBJ_id_camellia192_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,3L - -#define SN_id_camellia256_wrap "id-camellia256-wrap" -#define NID_id_camellia256_wrap 909 -#define OBJ_id_camellia256_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,4L - -#define OBJ_ntt_ds 0L,3L,4401L,5L - -#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L - -#define SN_camellia_128_ecb "CAMELLIA-128-ECB" -#define LN_camellia_128_ecb "camellia-128-ecb" -#define NID_camellia_128_ecb 754 -#define OBJ_camellia_128_ecb OBJ_camellia,1L - -#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB" -#define LN_camellia_128_ofb128 "camellia-128-ofb" -#define NID_camellia_128_ofb128 766 -#define OBJ_camellia_128_ofb128 OBJ_camellia,3L - -#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB" -#define LN_camellia_128_cfb128 "camellia-128-cfb" -#define NID_camellia_128_cfb128 757 -#define OBJ_camellia_128_cfb128 OBJ_camellia,4L - -#define SN_camellia_128_gcm "CAMELLIA-128-GCM" -#define LN_camellia_128_gcm "camellia-128-gcm" -#define NID_camellia_128_gcm 961 -#define OBJ_camellia_128_gcm OBJ_camellia,6L - -#define SN_camellia_128_ccm "CAMELLIA-128-CCM" -#define LN_camellia_128_ccm "camellia-128-ccm" -#define NID_camellia_128_ccm 962 -#define OBJ_camellia_128_ccm OBJ_camellia,7L - -#define SN_camellia_128_ctr "CAMELLIA-128-CTR" -#define LN_camellia_128_ctr "camellia-128-ctr" -#define NID_camellia_128_ctr 963 -#define OBJ_camellia_128_ctr OBJ_camellia,9L - -#define SN_camellia_128_cmac "CAMELLIA-128-CMAC" -#define LN_camellia_128_cmac "camellia-128-cmac" -#define NID_camellia_128_cmac 964 -#define OBJ_camellia_128_cmac OBJ_camellia,10L - -#define SN_camellia_192_ecb "CAMELLIA-192-ECB" -#define LN_camellia_192_ecb "camellia-192-ecb" -#define NID_camellia_192_ecb 755 -#define OBJ_camellia_192_ecb OBJ_camellia,21L - -#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB" -#define LN_camellia_192_ofb128 "camellia-192-ofb" -#define NID_camellia_192_ofb128 767 -#define OBJ_camellia_192_ofb128 OBJ_camellia,23L - -#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB" -#define LN_camellia_192_cfb128 "camellia-192-cfb" -#define NID_camellia_192_cfb128 758 -#define OBJ_camellia_192_cfb128 OBJ_camellia,24L - -#define SN_camellia_192_gcm "CAMELLIA-192-GCM" -#define LN_camellia_192_gcm "camellia-192-gcm" -#define NID_camellia_192_gcm 965 -#define OBJ_camellia_192_gcm OBJ_camellia,26L - -#define SN_camellia_192_ccm "CAMELLIA-192-CCM" -#define LN_camellia_192_ccm "camellia-192-ccm" -#define NID_camellia_192_ccm 966 -#define OBJ_camellia_192_ccm OBJ_camellia,27L - -#define SN_camellia_192_ctr "CAMELLIA-192-CTR" -#define LN_camellia_192_ctr "camellia-192-ctr" -#define NID_camellia_192_ctr 967 -#define OBJ_camellia_192_ctr OBJ_camellia,29L - -#define SN_camellia_192_cmac "CAMELLIA-192-CMAC" -#define LN_camellia_192_cmac "camellia-192-cmac" -#define NID_camellia_192_cmac 968 -#define OBJ_camellia_192_cmac OBJ_camellia,30L - -#define SN_camellia_256_ecb "CAMELLIA-256-ECB" -#define LN_camellia_256_ecb "camellia-256-ecb" -#define NID_camellia_256_ecb 756 -#define OBJ_camellia_256_ecb OBJ_camellia,41L - -#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB" -#define LN_camellia_256_ofb128 "camellia-256-ofb" -#define NID_camellia_256_ofb128 768 -#define OBJ_camellia_256_ofb128 OBJ_camellia,43L - -#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB" -#define LN_camellia_256_cfb128 "camellia-256-cfb" -#define NID_camellia_256_cfb128 759 -#define OBJ_camellia_256_cfb128 OBJ_camellia,44L - -#define SN_camellia_256_gcm "CAMELLIA-256-GCM" -#define LN_camellia_256_gcm "camellia-256-gcm" -#define NID_camellia_256_gcm 969 -#define OBJ_camellia_256_gcm OBJ_camellia,46L - -#define SN_camellia_256_ccm "CAMELLIA-256-CCM" -#define LN_camellia_256_ccm "camellia-256-ccm" -#define NID_camellia_256_ccm 970 -#define OBJ_camellia_256_ccm OBJ_camellia,47L - -#define SN_camellia_256_ctr "CAMELLIA-256-CTR" -#define LN_camellia_256_ctr "camellia-256-ctr" -#define NID_camellia_256_ctr 971 -#define OBJ_camellia_256_ctr OBJ_camellia,49L - -#define SN_camellia_256_cmac "CAMELLIA-256-CMAC" -#define LN_camellia_256_cmac "camellia-256-cmac" -#define NID_camellia_256_cmac 972 -#define OBJ_camellia_256_cmac OBJ_camellia,50L - -#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1" -#define LN_camellia_128_cfb1 "camellia-128-cfb1" -#define NID_camellia_128_cfb1 760 - -#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1" -#define LN_camellia_192_cfb1 "camellia-192-cfb1" -#define NID_camellia_192_cfb1 761 - -#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1" -#define LN_camellia_256_cfb1 "camellia-256-cfb1" -#define NID_camellia_256_cfb1 762 - -#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8" -#define LN_camellia_128_cfb8 "camellia-128-cfb8" -#define NID_camellia_128_cfb8 763 - -#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8" -#define LN_camellia_192_cfb8 "camellia-192-cfb8" -#define NID_camellia_192_cfb8 764 - -#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8" -#define LN_camellia_256_cfb8 "camellia-256-cfb8" -#define NID_camellia_256_cfb8 765 - -#define OBJ_aria 1L,2L,410L,200046L,1L,1L - -#define SN_aria_128_ecb "ARIA-128-ECB" -#define LN_aria_128_ecb "aria-128-ecb" -#define NID_aria_128_ecb 1065 -#define OBJ_aria_128_ecb OBJ_aria,1L - -#define SN_aria_128_cbc "ARIA-128-CBC" -#define LN_aria_128_cbc "aria-128-cbc" -#define NID_aria_128_cbc 1066 -#define OBJ_aria_128_cbc OBJ_aria,2L - -#define SN_aria_128_cfb128 "ARIA-128-CFB" -#define LN_aria_128_cfb128 "aria-128-cfb" -#define NID_aria_128_cfb128 1067 -#define OBJ_aria_128_cfb128 OBJ_aria,3L - -#define SN_aria_128_ofb128 "ARIA-128-OFB" -#define LN_aria_128_ofb128 "aria-128-ofb" -#define NID_aria_128_ofb128 1068 -#define OBJ_aria_128_ofb128 OBJ_aria,4L - -#define SN_aria_128_ctr "ARIA-128-CTR" -#define LN_aria_128_ctr "aria-128-ctr" -#define NID_aria_128_ctr 1069 -#define OBJ_aria_128_ctr OBJ_aria,5L - -#define SN_aria_192_ecb "ARIA-192-ECB" -#define LN_aria_192_ecb "aria-192-ecb" -#define NID_aria_192_ecb 1070 -#define OBJ_aria_192_ecb OBJ_aria,6L - -#define SN_aria_192_cbc "ARIA-192-CBC" -#define LN_aria_192_cbc "aria-192-cbc" -#define NID_aria_192_cbc 1071 -#define OBJ_aria_192_cbc OBJ_aria,7L - -#define SN_aria_192_cfb128 "ARIA-192-CFB" -#define LN_aria_192_cfb128 "aria-192-cfb" -#define NID_aria_192_cfb128 1072 -#define OBJ_aria_192_cfb128 OBJ_aria,8L - -#define SN_aria_192_ofb128 "ARIA-192-OFB" -#define LN_aria_192_ofb128 "aria-192-ofb" -#define NID_aria_192_ofb128 1073 -#define OBJ_aria_192_ofb128 OBJ_aria,9L - -#define SN_aria_192_ctr "ARIA-192-CTR" -#define LN_aria_192_ctr "aria-192-ctr" -#define NID_aria_192_ctr 1074 -#define OBJ_aria_192_ctr OBJ_aria,10L - -#define SN_aria_256_ecb "ARIA-256-ECB" -#define LN_aria_256_ecb "aria-256-ecb" -#define NID_aria_256_ecb 1075 -#define OBJ_aria_256_ecb OBJ_aria,11L - -#define SN_aria_256_cbc "ARIA-256-CBC" -#define LN_aria_256_cbc "aria-256-cbc" -#define NID_aria_256_cbc 1076 -#define OBJ_aria_256_cbc OBJ_aria,12L - -#define SN_aria_256_cfb128 "ARIA-256-CFB" -#define LN_aria_256_cfb128 "aria-256-cfb" -#define NID_aria_256_cfb128 1077 -#define OBJ_aria_256_cfb128 OBJ_aria,13L - -#define SN_aria_256_ofb128 "ARIA-256-OFB" -#define LN_aria_256_ofb128 "aria-256-ofb" -#define NID_aria_256_ofb128 1078 -#define OBJ_aria_256_ofb128 OBJ_aria,14L - -#define SN_aria_256_ctr "ARIA-256-CTR" -#define LN_aria_256_ctr "aria-256-ctr" -#define NID_aria_256_ctr 1079 -#define OBJ_aria_256_ctr OBJ_aria,15L - -#define SN_aria_128_cfb1 "ARIA-128-CFB1" -#define LN_aria_128_cfb1 "aria-128-cfb1" -#define NID_aria_128_cfb1 1080 - -#define SN_aria_192_cfb1 "ARIA-192-CFB1" -#define LN_aria_192_cfb1 "aria-192-cfb1" -#define NID_aria_192_cfb1 1081 - -#define SN_aria_256_cfb1 "ARIA-256-CFB1" -#define LN_aria_256_cfb1 "aria-256-cfb1" -#define NID_aria_256_cfb1 1082 - -#define SN_aria_128_cfb8 "ARIA-128-CFB8" -#define LN_aria_128_cfb8 "aria-128-cfb8" -#define NID_aria_128_cfb8 1083 - -#define SN_aria_192_cfb8 "ARIA-192-CFB8" -#define LN_aria_192_cfb8 "aria-192-cfb8" -#define NID_aria_192_cfb8 1084 - -#define SN_aria_256_cfb8 "ARIA-256-CFB8" -#define LN_aria_256_cfb8 "aria-256-cfb8" -#define NID_aria_256_cfb8 1085 - -#define SN_aria_128_ccm "ARIA-128-CCM" -#define LN_aria_128_ccm "aria-128-ccm" -#define NID_aria_128_ccm 1120 -#define OBJ_aria_128_ccm OBJ_aria,37L - -#define SN_aria_192_ccm "ARIA-192-CCM" -#define LN_aria_192_ccm "aria-192-ccm" -#define NID_aria_192_ccm 1121 -#define OBJ_aria_192_ccm OBJ_aria,38L - -#define SN_aria_256_ccm "ARIA-256-CCM" -#define LN_aria_256_ccm "aria-256-ccm" -#define NID_aria_256_ccm 1122 -#define OBJ_aria_256_ccm OBJ_aria,39L - -#define SN_aria_128_gcm "ARIA-128-GCM" -#define LN_aria_128_gcm "aria-128-gcm" -#define NID_aria_128_gcm 1123 -#define OBJ_aria_128_gcm OBJ_aria,34L - -#define SN_aria_192_gcm "ARIA-192-GCM" -#define LN_aria_192_gcm "aria-192-gcm" -#define NID_aria_192_gcm 1124 -#define OBJ_aria_192_gcm OBJ_aria,35L - -#define SN_aria_256_gcm "ARIA-256-GCM" -#define LN_aria_256_gcm "aria-256-gcm" -#define NID_aria_256_gcm 1125 -#define OBJ_aria_256_gcm OBJ_aria,36L - -#define SN_kisa "KISA" -#define LN_kisa "kisa" -#define NID_kisa 773 -#define OBJ_kisa OBJ_member_body,410L,200004L - -#define SN_seed_ecb "SEED-ECB" -#define LN_seed_ecb "seed-ecb" -#define NID_seed_ecb 776 -#define OBJ_seed_ecb OBJ_kisa,1L,3L - -#define SN_seed_cbc "SEED-CBC" -#define LN_seed_cbc "seed-cbc" -#define NID_seed_cbc 777 -#define OBJ_seed_cbc OBJ_kisa,1L,4L - -#define SN_seed_cfb128 "SEED-CFB" -#define LN_seed_cfb128 "seed-cfb" -#define NID_seed_cfb128 779 -#define OBJ_seed_cfb128 OBJ_kisa,1L,5L - -#define SN_seed_ofb128 "SEED-OFB" -#define LN_seed_ofb128 "seed-ofb" -#define NID_seed_ofb128 778 -#define OBJ_seed_ofb128 OBJ_kisa,1L,6L - -#define SN_sm4_ecb "SM4-ECB" -#define LN_sm4_ecb "sm4-ecb" -#define NID_sm4_ecb 1133 -#define OBJ_sm4_ecb OBJ_sm_scheme,104L,1L - -#define SN_sm4_cbc "SM4-CBC" -#define LN_sm4_cbc "sm4-cbc" -#define NID_sm4_cbc 1134 -#define OBJ_sm4_cbc OBJ_sm_scheme,104L,2L - -#define SN_sm4_ofb128 "SM4-OFB" -#define LN_sm4_ofb128 "sm4-ofb" -#define NID_sm4_ofb128 1135 -#define OBJ_sm4_ofb128 OBJ_sm_scheme,104L,3L - -#define SN_sm4_cfb128 "SM4-CFB" -#define LN_sm4_cfb128 "sm4-cfb" -#define NID_sm4_cfb128 1137 -#define OBJ_sm4_cfb128 OBJ_sm_scheme,104L,4L - -#define SN_sm4_cfb1 "SM4-CFB1" -#define LN_sm4_cfb1 "sm4-cfb1" -#define NID_sm4_cfb1 1136 -#define OBJ_sm4_cfb1 OBJ_sm_scheme,104L,5L - -#define SN_sm4_cfb8 "SM4-CFB8" -#define LN_sm4_cfb8 "sm4-cfb8" -#define NID_sm4_cfb8 1138 -#define OBJ_sm4_cfb8 OBJ_sm_scheme,104L,6L - -#define SN_sm4_ctr "SM4-CTR" -#define LN_sm4_ctr "sm4-ctr" -#define NID_sm4_ctr 1139 -#define OBJ_sm4_ctr OBJ_sm_scheme,104L,7L - -#define SN_sm4_gcm "SM4-GCM" -#define LN_sm4_gcm "sm4-gcm" -#define NID_sm4_gcm 1248 -#define OBJ_sm4_gcm OBJ_sm_scheme,104L,8L - -#define SN_sm4_ccm "SM4-CCM" -#define LN_sm4_ccm "sm4-ccm" -#define NID_sm4_ccm 1249 -#define OBJ_sm4_ccm OBJ_sm_scheme,104L,9L - -#define SN_sm4_xts "SM4-XTS" -#define LN_sm4_xts "sm4-xts" -#define NID_sm4_xts 1290 -#define OBJ_sm4_xts OBJ_sm_scheme,104L,10L - -#define SN_hmac "HMAC" -#define LN_hmac "hmac" -#define NID_hmac 855 - -#define SN_cmac "CMAC" -#define LN_cmac "cmac" -#define NID_cmac 894 - -#define SN_rc4_hmac_md5 "RC4-HMAC-MD5" -#define LN_rc4_hmac_md5 "rc4-hmac-md5" -#define NID_rc4_hmac_md5 915 - -#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1" -#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1" -#define NID_aes_128_cbc_hmac_sha1 916 - -#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1" -#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1" -#define NID_aes_192_cbc_hmac_sha1 917 - -#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1" -#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1" -#define NID_aes_256_cbc_hmac_sha1 918 - -#define SN_aes_128_cbc_hmac_sha256 "AES-128-CBC-HMAC-SHA256" -#define LN_aes_128_cbc_hmac_sha256 "aes-128-cbc-hmac-sha256" -#define NID_aes_128_cbc_hmac_sha256 948 - -#define SN_aes_192_cbc_hmac_sha256 "AES-192-CBC-HMAC-SHA256" -#define LN_aes_192_cbc_hmac_sha256 "aes-192-cbc-hmac-sha256" -#define NID_aes_192_cbc_hmac_sha256 949 - -#define SN_aes_256_cbc_hmac_sha256 "AES-256-CBC-HMAC-SHA256" -#define LN_aes_256_cbc_hmac_sha256 "aes-256-cbc-hmac-sha256" -#define NID_aes_256_cbc_hmac_sha256 950 - -#define SN_chacha20_poly1305 "ChaCha20-Poly1305" -#define LN_chacha20_poly1305 "chacha20-poly1305" -#define NID_chacha20_poly1305 1018 - -#define SN_chacha20 "ChaCha20" -#define LN_chacha20 "chacha20" -#define NID_chacha20 1019 - -#define SN_aes_128_cbc_hmac_sha1_etm "AES-128-CBC-HMAC-SHA1-ETM" -#define LN_aes_128_cbc_hmac_sha1_etm "aes-128-cbc-hmac-sha1-etm" -#define NID_aes_128_cbc_hmac_sha1_etm 1487 - -#define SN_aes_192_cbc_hmac_sha1_etm "AES-192-CBC-HMAC-SHA1-ETM" -#define LN_aes_192_cbc_hmac_sha1_etm "aes-192-cbc-hmac-sha1-etm" -#define NID_aes_192_cbc_hmac_sha1_etm 1488 - -#define SN_aes_256_cbc_hmac_sha1_etm "AES-256-CBC-HMAC-SHA1-ETM" -#define LN_aes_256_cbc_hmac_sha1_etm "aes-256-cbc-hmac-sha1-etm" -#define NID_aes_256_cbc_hmac_sha1_etm 1489 - -#define SN_aes_128_cbc_hmac_sha256_etm "AES-128-CBC-HMAC-SHA256-ETM" -#define LN_aes_128_cbc_hmac_sha256_etm "aes-128-cbc-hmac-sha256-etm" -#define NID_aes_128_cbc_hmac_sha256_etm 1490 - -#define SN_aes_192_cbc_hmac_sha256_etm "AES-192-CBC-HMAC-SHA256-ETM" -#define LN_aes_192_cbc_hmac_sha256_etm "aes-192-cbc-hmac-sha256-etm" -#define NID_aes_192_cbc_hmac_sha256_etm 1491 - -#define SN_aes_256_cbc_hmac_sha256_etm "AES-256-CBC-HMAC-SHA256-ETM" -#define LN_aes_256_cbc_hmac_sha256_etm "aes-256-cbc-hmac-sha256-etm" -#define NID_aes_256_cbc_hmac_sha256_etm 1492 - -#define SN_aes_128_cbc_hmac_sha512_etm "AES-128-CBC-HMAC-SHA512-ETM" -#define LN_aes_128_cbc_hmac_sha512_etm "aes-128-cbc-hmac-sha512-etm" -#define NID_aes_128_cbc_hmac_sha512_etm 1493 - -#define SN_aes_192_cbc_hmac_sha512_etm "AES-192-CBC-HMAC-SHA512-ETM" -#define LN_aes_192_cbc_hmac_sha512_etm "aes-192-cbc-hmac-sha512-etm" -#define NID_aes_192_cbc_hmac_sha512_etm 1494 - -#define SN_aes_256_cbc_hmac_sha512_etm "AES-256-CBC-HMAC-SHA512-ETM" -#define LN_aes_256_cbc_hmac_sha512_etm "aes-256-cbc-hmac-sha512-etm" -#define NID_aes_256_cbc_hmac_sha512_etm 1495 - -#define SN_dhpublicnumber "dhpublicnumber" -#define LN_dhpublicnumber "X9.42 DH" -#define NID_dhpublicnumber 920 -#define OBJ_dhpublicnumber OBJ_ISO_US,10046L,2L,1L - -#define SN_brainpoolP160r1 "brainpoolP160r1" -#define NID_brainpoolP160r1 921 -#define OBJ_brainpoolP160r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,1L - -#define SN_brainpoolP160t1 "brainpoolP160t1" -#define NID_brainpoolP160t1 922 -#define OBJ_brainpoolP160t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,2L - -#define SN_brainpoolP192r1 "brainpoolP192r1" -#define NID_brainpoolP192r1 923 -#define OBJ_brainpoolP192r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,3L - -#define SN_brainpoolP192t1 "brainpoolP192t1" -#define NID_brainpoolP192t1 924 -#define OBJ_brainpoolP192t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,4L - -#define SN_brainpoolP224r1 "brainpoolP224r1" -#define NID_brainpoolP224r1 925 -#define OBJ_brainpoolP224r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,5L - -#define SN_brainpoolP224t1 "brainpoolP224t1" -#define NID_brainpoolP224t1 926 -#define OBJ_brainpoolP224t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,6L - -#define SN_brainpoolP256r1 "brainpoolP256r1" -#define NID_brainpoolP256r1 927 -#define OBJ_brainpoolP256r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,7L - -#define SN_brainpoolP256r1tls13 "brainpoolP256r1tls13" -#define NID_brainpoolP256r1tls13 1285 - -#define SN_brainpoolP256t1 "brainpoolP256t1" -#define NID_brainpoolP256t1 928 -#define OBJ_brainpoolP256t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,8L - -#define SN_brainpoolP320r1 "brainpoolP320r1" -#define NID_brainpoolP320r1 929 -#define OBJ_brainpoolP320r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,9L - -#define SN_brainpoolP320t1 "brainpoolP320t1" -#define NID_brainpoolP320t1 930 -#define OBJ_brainpoolP320t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,10L - -#define SN_brainpoolP384r1 "brainpoolP384r1" -#define NID_brainpoolP384r1 931 -#define OBJ_brainpoolP384r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,11L - -#define SN_brainpoolP384r1tls13 "brainpoolP384r1tls13" -#define NID_brainpoolP384r1tls13 1286 - -#define SN_brainpoolP384t1 "brainpoolP384t1" -#define NID_brainpoolP384t1 932 -#define OBJ_brainpoolP384t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,12L - -#define SN_brainpoolP512r1 "brainpoolP512r1" -#define NID_brainpoolP512r1 933 -#define OBJ_brainpoolP512r1 1L,3L,36L,3L,3L,2L,8L,1L,1L,13L - -#define SN_brainpoolP512r1tls13 "brainpoolP512r1tls13" -#define NID_brainpoolP512r1tls13 1287 - -#define SN_brainpoolP512t1 "brainpoolP512t1" -#define NID_brainpoolP512t1 934 -#define OBJ_brainpoolP512t1 1L,3L,36L,3L,3L,2L,8L,1L,1L,14L - -#define OBJ_x9_63_scheme 1L,3L,133L,16L,840L,63L,0L - -#define OBJ_secg_scheme OBJ_certicom_arc,1L - -#define SN_dhSinglePass_stdDH_sha1kdf_scheme "dhSinglePass-stdDH-sha1kdf-scheme" -#define NID_dhSinglePass_stdDH_sha1kdf_scheme 936 -#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme OBJ_x9_63_scheme,2L - -#define SN_dhSinglePass_stdDH_sha224kdf_scheme "dhSinglePass-stdDH-sha224kdf-scheme" -#define NID_dhSinglePass_stdDH_sha224kdf_scheme 937 -#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme OBJ_secg_scheme,11L,0L - -#define SN_dhSinglePass_stdDH_sha256kdf_scheme "dhSinglePass-stdDH-sha256kdf-scheme" -#define NID_dhSinglePass_stdDH_sha256kdf_scheme 938 -#define OBJ_dhSinglePass_stdDH_sha256kdf_scheme OBJ_secg_scheme,11L,1L - -#define SN_dhSinglePass_stdDH_sha384kdf_scheme "dhSinglePass-stdDH-sha384kdf-scheme" -#define NID_dhSinglePass_stdDH_sha384kdf_scheme 939 -#define OBJ_dhSinglePass_stdDH_sha384kdf_scheme OBJ_secg_scheme,11L,2L - -#define SN_dhSinglePass_stdDH_sha512kdf_scheme "dhSinglePass-stdDH-sha512kdf-scheme" -#define NID_dhSinglePass_stdDH_sha512kdf_scheme 940 -#define OBJ_dhSinglePass_stdDH_sha512kdf_scheme OBJ_secg_scheme,11L,3L - -#define SN_dhSinglePass_cofactorDH_sha1kdf_scheme "dhSinglePass-cofactorDH-sha1kdf-scheme" -#define NID_dhSinglePass_cofactorDH_sha1kdf_scheme 941 -#define OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme OBJ_x9_63_scheme,3L - -#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme "dhSinglePass-cofactorDH-sha224kdf-scheme" -#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme 942 -#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme OBJ_secg_scheme,14L,0L - -#define SN_dhSinglePass_cofactorDH_sha256kdf_scheme "dhSinglePass-cofactorDH-sha256kdf-scheme" -#define NID_dhSinglePass_cofactorDH_sha256kdf_scheme 943 -#define OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme OBJ_secg_scheme,14L,1L - -#define SN_dhSinglePass_cofactorDH_sha384kdf_scheme "dhSinglePass-cofactorDH-sha384kdf-scheme" -#define NID_dhSinglePass_cofactorDH_sha384kdf_scheme 944 -#define OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme OBJ_secg_scheme,14L,2L - -#define SN_dhSinglePass_cofactorDH_sha512kdf_scheme "dhSinglePass-cofactorDH-sha512kdf-scheme" -#define NID_dhSinglePass_cofactorDH_sha512kdf_scheme 945 -#define OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme OBJ_secg_scheme,14L,3L - -#define SN_dh_std_kdf "dh-std-kdf" -#define NID_dh_std_kdf 946 - -#define SN_dh_cofactor_kdf "dh-cofactor-kdf" -#define NID_dh_cofactor_kdf 947 - -#define SN_ct_precert_scts "ct_precert_scts" -#define LN_ct_precert_scts "CT Precertificate SCTs" -#define NID_ct_precert_scts 951 -#define OBJ_ct_precert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,2L - -#define SN_ct_precert_poison "ct_precert_poison" -#define LN_ct_precert_poison "CT Precertificate Poison" -#define NID_ct_precert_poison 952 -#define OBJ_ct_precert_poison 1L,3L,6L,1L,4L,1L,11129L,2L,4L,3L - -#define SN_ct_precert_signer "ct_precert_signer" -#define LN_ct_precert_signer "CT Precertificate Signer" -#define NID_ct_precert_signer 953 -#define OBJ_ct_precert_signer 1L,3L,6L,1L,4L,1L,11129L,2L,4L,4L - -#define SN_ct_cert_scts "ct_cert_scts" -#define LN_ct_cert_scts "CT Certificate SCTs" -#define NID_ct_cert_scts 954 -#define OBJ_ct_cert_scts 1L,3L,6L,1L,4L,1L,11129L,2L,4L,5L - -#define SN_jurisdictionLocalityName "jurisdictionL" -#define LN_jurisdictionLocalityName "jurisdictionLocalityName" -#define NID_jurisdictionLocalityName 955 -#define OBJ_jurisdictionLocalityName OBJ_ms_corp,60L,2L,1L,1L - -#define SN_jurisdictionStateOrProvinceName "jurisdictionST" -#define LN_jurisdictionStateOrProvinceName "jurisdictionStateOrProvinceName" -#define NID_jurisdictionStateOrProvinceName 956 -#define OBJ_jurisdictionStateOrProvinceName OBJ_ms_corp,60L,2L,1L,2L - -#define SN_jurisdictionCountryName "jurisdictionC" -#define LN_jurisdictionCountryName "jurisdictionCountryName" -#define NID_jurisdictionCountryName 957 -#define OBJ_jurisdictionCountryName OBJ_ms_corp,60L,2L,1L,3L - -#define SN_id_scrypt "id-scrypt" -#define LN_id_scrypt "scrypt" -#define NID_id_scrypt 973 -#define OBJ_id_scrypt 1L,3L,6L,1L,4L,1L,11591L,4L,11L - -#define SN_tls1_prf "TLS1-PRF" -#define LN_tls1_prf "tls1-prf" -#define NID_tls1_prf 1021 - -#define SN_hkdf "HKDF" -#define LN_hkdf "hkdf" -#define NID_hkdf 1036 - -#define SN_sshkdf "SSHKDF" -#define LN_sshkdf "sshkdf" -#define NID_sshkdf 1203 - -#define SN_sskdf "SSKDF" -#define LN_sskdf "sskdf" -#define NID_sskdf 1205 - -#define SN_x942kdf "X942KDF" -#define LN_x942kdf "x942kdf" -#define NID_x942kdf 1207 - -#define SN_x963kdf "X963KDF" -#define LN_x963kdf "x963kdf" -#define NID_x963kdf 1206 - -#define SN_id_pkinit "id-pkinit" -#define NID_id_pkinit 1031 -#define OBJ_id_pkinit 1L,3L,6L,1L,5L,2L,3L - -#define SN_pkInitClientAuth "pkInitClientAuth" -#define LN_pkInitClientAuth "PKINIT Client Auth" -#define NID_pkInitClientAuth 1032 -#define OBJ_pkInitClientAuth OBJ_id_pkinit,4L - -#define SN_pkInitKDC "pkInitKDC" -#define LN_pkInitKDC "Signing KDC Response" -#define NID_pkInitKDC 1033 -#define OBJ_pkInitKDC OBJ_id_pkinit,5L - -#define SN_X25519 "X25519" -#define NID_X25519 1034 -#define OBJ_X25519 1L,3L,101L,110L - -#define SN_X448 "X448" -#define NID_X448 1035 -#define OBJ_X448 1L,3L,101L,111L - -#define SN_ED25519 "ED25519" -#define NID_ED25519 1087 -#define OBJ_ED25519 1L,3L,101L,112L - -#define SN_ED448 "ED448" -#define NID_ED448 1088 -#define OBJ_ED448 1L,3L,101L,113L - -#define SN_kx_rsa "KxRSA" -#define LN_kx_rsa "kx-rsa" -#define NID_kx_rsa 1037 - -#define SN_kx_ecdhe "KxECDHE" -#define LN_kx_ecdhe "kx-ecdhe" -#define NID_kx_ecdhe 1038 - -#define SN_kx_dhe "KxDHE" -#define LN_kx_dhe "kx-dhe" -#define NID_kx_dhe 1039 - -#define SN_kx_ecdhe_psk "KxECDHE-PSK" -#define LN_kx_ecdhe_psk "kx-ecdhe-psk" -#define NID_kx_ecdhe_psk 1040 - -#define SN_kx_dhe_psk "KxDHE-PSK" -#define LN_kx_dhe_psk "kx-dhe-psk" -#define NID_kx_dhe_psk 1041 - -#define SN_kx_rsa_psk "KxRSA_PSK" -#define LN_kx_rsa_psk "kx-rsa-psk" -#define NID_kx_rsa_psk 1042 - -#define SN_kx_psk "KxPSK" -#define LN_kx_psk "kx-psk" -#define NID_kx_psk 1043 - -#define SN_kx_srp "KxSRP" -#define LN_kx_srp "kx-srp" -#define NID_kx_srp 1044 - -#define SN_kx_gost "KxGOST" -#define LN_kx_gost "kx-gost" -#define NID_kx_gost 1045 - -#define SN_kx_gost18 "KxGOST18" -#define LN_kx_gost18 "kx-gost18" -#define NID_kx_gost18 1218 - -#define SN_kx_any "KxANY" -#define LN_kx_any "kx-any" -#define NID_kx_any 1063 - -#define SN_auth_rsa "AuthRSA" -#define LN_auth_rsa "auth-rsa" -#define NID_auth_rsa 1046 - -#define SN_auth_ecdsa "AuthECDSA" -#define LN_auth_ecdsa "auth-ecdsa" -#define NID_auth_ecdsa 1047 - -#define SN_auth_psk "AuthPSK" -#define LN_auth_psk "auth-psk" -#define NID_auth_psk 1048 - -#define SN_auth_dss "AuthDSS" -#define LN_auth_dss "auth-dss" -#define NID_auth_dss 1049 - -#define SN_auth_gost01 "AuthGOST01" -#define LN_auth_gost01 "auth-gost01" -#define NID_auth_gost01 1050 - -#define SN_auth_gost12 "AuthGOST12" -#define LN_auth_gost12 "auth-gost12" -#define NID_auth_gost12 1051 - -#define SN_auth_srp "AuthSRP" -#define LN_auth_srp "auth-srp" -#define NID_auth_srp 1052 - -#define SN_auth_null "AuthNULL" -#define LN_auth_null "auth-null" -#define NID_auth_null 1053 - -#define SN_auth_any "AuthANY" -#define LN_auth_any "auth-any" -#define NID_auth_any 1064 - -#define SN_poly1305 "Poly1305" -#define LN_poly1305 "poly1305" -#define NID_poly1305 1061 - -#define SN_siphash "SipHash" -#define LN_siphash "siphash" -#define NID_siphash 1062 - -#define SN_ffdhe2048 "ffdhe2048" -#define NID_ffdhe2048 1126 - -#define SN_ffdhe3072 "ffdhe3072" -#define NID_ffdhe3072 1127 - -#define SN_ffdhe4096 "ffdhe4096" -#define NID_ffdhe4096 1128 - -#define SN_ffdhe6144 "ffdhe6144" -#define NID_ffdhe6144 1129 - -#define SN_ffdhe8192 "ffdhe8192" -#define NID_ffdhe8192 1130 - -#define SN_modp_1536 "modp_1536" -#define NID_modp_1536 1212 - -#define SN_modp_2048 "modp_2048" -#define NID_modp_2048 1213 - -#define SN_modp_3072 "modp_3072" -#define NID_modp_3072 1214 - -#define SN_modp_4096 "modp_4096" -#define NID_modp_4096 1215 - -#define SN_modp_6144 "modp_6144" -#define NID_modp_6144 1216 - -#define SN_modp_8192 "modp_8192" -#define NID_modp_8192 1217 - -#define SN_ISO_UA "ISO-UA" -#define NID_ISO_UA 1150 -#define OBJ_ISO_UA OBJ_member_body,804L - -#define SN_ua_pki "ua-pki" -#define NID_ua_pki 1151 -#define OBJ_ua_pki OBJ_ISO_UA,2L,1L,1L,1L - -#define SN_dstu28147 "dstu28147" -#define LN_dstu28147 "DSTU Gost 28147-2009" -#define NID_dstu28147 1152 -#define OBJ_dstu28147 OBJ_ua_pki,1L,1L,1L - -#define SN_dstu28147_ofb "dstu28147-ofb" -#define LN_dstu28147_ofb "DSTU Gost 28147-2009 OFB mode" -#define NID_dstu28147_ofb 1153 -#define OBJ_dstu28147_ofb OBJ_dstu28147,2L - -#define SN_dstu28147_cfb "dstu28147-cfb" -#define LN_dstu28147_cfb "DSTU Gost 28147-2009 CFB mode" -#define NID_dstu28147_cfb 1154 -#define OBJ_dstu28147_cfb OBJ_dstu28147,3L - -#define SN_dstu28147_wrap "dstu28147-wrap" -#define LN_dstu28147_wrap "DSTU Gost 28147-2009 key wrap" -#define NID_dstu28147_wrap 1155 -#define OBJ_dstu28147_wrap OBJ_dstu28147,5L - -#define SN_hmacWithDstu34311 "hmacWithDstu34311" -#define LN_hmacWithDstu34311 "HMAC DSTU Gost 34311-95" -#define NID_hmacWithDstu34311 1156 -#define OBJ_hmacWithDstu34311 OBJ_ua_pki,1L,1L,2L - -#define SN_dstu34311 "dstu34311" -#define LN_dstu34311 "DSTU Gost 34311-95" -#define NID_dstu34311 1157 -#define OBJ_dstu34311 OBJ_ua_pki,1L,2L,1L - -#define SN_dstu4145le "dstu4145le" -#define LN_dstu4145le "DSTU 4145-2002 little endian" -#define NID_dstu4145le 1158 -#define OBJ_dstu4145le OBJ_ua_pki,1L,3L,1L,1L - -#define SN_dstu4145be "dstu4145be" -#define LN_dstu4145be "DSTU 4145-2002 big endian" -#define NID_dstu4145be 1159 -#define OBJ_dstu4145be OBJ_dstu4145le,1L,1L - -#define SN_uacurve0 "uacurve0" -#define LN_uacurve0 "DSTU curve 0" -#define NID_uacurve0 1160 -#define OBJ_uacurve0 OBJ_dstu4145le,2L,0L - -#define SN_uacurve1 "uacurve1" -#define LN_uacurve1 "DSTU curve 1" -#define NID_uacurve1 1161 -#define OBJ_uacurve1 OBJ_dstu4145le,2L,1L - -#define SN_uacurve2 "uacurve2" -#define LN_uacurve2 "DSTU curve 2" -#define NID_uacurve2 1162 -#define OBJ_uacurve2 OBJ_dstu4145le,2L,2L - -#define SN_uacurve3 "uacurve3" -#define LN_uacurve3 "DSTU curve 3" -#define NID_uacurve3 1163 -#define OBJ_uacurve3 OBJ_dstu4145le,2L,3L - -#define SN_uacurve4 "uacurve4" -#define LN_uacurve4 "DSTU curve 4" -#define NID_uacurve4 1164 -#define OBJ_uacurve4 OBJ_dstu4145le,2L,4L - -#define SN_uacurve5 "uacurve5" -#define LN_uacurve5 "DSTU curve 5" -#define NID_uacurve5 1165 -#define OBJ_uacurve5 OBJ_dstu4145le,2L,5L - -#define SN_uacurve6 "uacurve6" -#define LN_uacurve6 "DSTU curve 6" -#define NID_uacurve6 1166 -#define OBJ_uacurve6 OBJ_dstu4145le,2L,6L - -#define SN_uacurve7 "uacurve7" -#define LN_uacurve7 "DSTU curve 7" -#define NID_uacurve7 1167 -#define OBJ_uacurve7 OBJ_dstu4145le,2L,7L - -#define SN_uacurve8 "uacurve8" -#define LN_uacurve8 "DSTU curve 8" -#define NID_uacurve8 1168 -#define OBJ_uacurve8 OBJ_dstu4145le,2L,8L - -#define SN_uacurve9 "uacurve9" -#define LN_uacurve9 "DSTU curve 9" -#define NID_uacurve9 1169 -#define OBJ_uacurve9 OBJ_dstu4145le,2L,9L - -#define SN_aes_128_siv "AES-128-SIV" -#define LN_aes_128_siv "aes-128-siv" -#define NID_aes_128_siv 1198 - -#define SN_aes_192_siv "AES-192-SIV" -#define LN_aes_192_siv "aes-192-siv" -#define NID_aes_192_siv 1199 - -#define SN_aes_256_siv "AES-256-SIV" -#define LN_aes_256_siv "aes-256-siv" -#define NID_aes_256_siv 1200 - -#define SN_oracle "oracle-organization" -#define LN_oracle "Oracle organization" -#define NID_oracle 1282 -#define OBJ_oracle OBJ_joint_iso_itu_t,16L,840L,1L,113894L - -#define SN_oracle_jdk_trustedkeyusage "oracle-jdk-trustedkeyusage" -#define LN_oracle_jdk_trustedkeyusage "Trusted key usage (Oracle)" -#define NID_oracle_jdk_trustedkeyusage 1283 -#define OBJ_oracle_jdk_trustedkeyusage OBJ_oracle,746875L,1L,1L - -#define SN_brotli "brotli" -#define LN_brotli "Brotli compression" -#define NID_brotli 1288 - -#define SN_zstd "zstd" -#define LN_zstd "Zstandard compression" -#define NID_zstd 1289 - -#define SN_tcg "tcg" -#define LN_tcg "Trusted Computing Group" -#define NID_tcg 1324 -#define OBJ_tcg 2L,23L,133L - -#define SN_tcg_tcpaSpecVersion "tcg-tcpaSpecVersion" -#define NID_tcg_tcpaSpecVersion 1325 -#define OBJ_tcg_tcpaSpecVersion OBJ_tcg,1L - -#define SN_tcg_attribute "tcg-attribute" -#define LN_tcg_attribute "Trusted Computing Group Attributes" -#define NID_tcg_attribute 1326 -#define OBJ_tcg_attribute OBJ_tcg,2L - -#define SN_tcg_protocol "tcg-protocol" -#define LN_tcg_protocol "Trusted Computing Group Protocols" -#define NID_tcg_protocol 1327 -#define OBJ_tcg_protocol OBJ_tcg,3L - -#define SN_tcg_algorithm "tcg-algorithm" -#define LN_tcg_algorithm "Trusted Computing Group Algorithms" -#define NID_tcg_algorithm 1328 -#define OBJ_tcg_algorithm OBJ_tcg,4L - -#define SN_tcg_platformClass "tcg-platformClass" -#define LN_tcg_platformClass "Trusted Computing Group Platform Classes" -#define NID_tcg_platformClass 1329 -#define OBJ_tcg_platformClass OBJ_tcg,5L - -#define SN_tcg_ce "tcg-ce" -#define LN_tcg_ce "Trusted Computing Group Certificate Extensions" -#define NID_tcg_ce 1330 -#define OBJ_tcg_ce OBJ_tcg,6L - -#define SN_tcg_kp "tcg-kp" -#define LN_tcg_kp "Trusted Computing Group Key Purposes" -#define NID_tcg_kp 1331 -#define OBJ_tcg_kp OBJ_tcg,8L - -#define SN_tcg_ca "tcg-ca" -#define LN_tcg_ca "Trusted Computing Group Certificate Policies" -#define NID_tcg_ca 1332 -#define OBJ_tcg_ca OBJ_tcg,11L - -#define SN_tcg_address "tcg-address" -#define LN_tcg_address "Trusted Computing Group Address Formats" -#define NID_tcg_address 1333 -#define OBJ_tcg_address OBJ_tcg,17L - -#define SN_tcg_registry "tcg-registry" -#define LN_tcg_registry "Trusted Computing Group Registry" -#define NID_tcg_registry 1334 -#define OBJ_tcg_registry OBJ_tcg,18L - -#define SN_tcg_traits "tcg-traits" -#define LN_tcg_traits "Trusted Computing Group Traits" -#define NID_tcg_traits 1335 -#define OBJ_tcg_traits OBJ_tcg,19L - -#define SN_tcg_common "tcg-common" -#define LN_tcg_common "Trusted Computing Group Common" -#define NID_tcg_common 1336 -#define OBJ_tcg_common OBJ_tcg_platformClass,1L - -#define SN_tcg_at_platformManufacturerStr "tcg-at-platformManufacturerStr" -#define LN_tcg_at_platformManufacturerStr "TCG Platform Manufacturer String" -#define NID_tcg_at_platformManufacturerStr 1337 -#define OBJ_tcg_at_platformManufacturerStr OBJ_tcg_common,1L - -#define SN_tcg_at_platformManufacturerId "tcg-at-platformManufacturerId" -#define LN_tcg_at_platformManufacturerId "TCG Platform Manufacturer ID" -#define NID_tcg_at_platformManufacturerId 1338 -#define OBJ_tcg_at_platformManufacturerId OBJ_tcg_common,2L - -#define SN_tcg_at_platformConfigUri "tcg-at-platformConfigUri" -#define LN_tcg_at_platformConfigUri "TCG Platform Configuration URI" -#define NID_tcg_at_platformConfigUri 1339 -#define OBJ_tcg_at_platformConfigUri OBJ_tcg_common,3L - -#define SN_tcg_at_platformModel "tcg-at-platformModel" -#define LN_tcg_at_platformModel "TCG Platform Model" -#define NID_tcg_at_platformModel 1340 -#define OBJ_tcg_at_platformModel OBJ_tcg_common,4L - -#define SN_tcg_at_platformVersion "tcg-at-platformVersion" -#define LN_tcg_at_platformVersion "TCG Platform Version" -#define NID_tcg_at_platformVersion 1341 -#define OBJ_tcg_at_platformVersion OBJ_tcg_common,5L - -#define SN_tcg_at_platformSerial "tcg-at-platformSerial" -#define LN_tcg_at_platformSerial "TCG Platform Serial Number" -#define NID_tcg_at_platformSerial 1342 -#define OBJ_tcg_at_platformSerial OBJ_tcg_common,6L - -#define SN_tcg_at_platformConfiguration "tcg-at-platformConfiguration" -#define LN_tcg_at_platformConfiguration "TCG Platform Configuration" -#define NID_tcg_at_platformConfiguration 1343 -#define OBJ_tcg_at_platformConfiguration OBJ_tcg_common,7L - -#define SN_tcg_at_platformIdentifier "tcg-at-platformIdentifier" -#define LN_tcg_at_platformIdentifier "TCG Platform Identifier" -#define NID_tcg_at_platformIdentifier 1344 -#define OBJ_tcg_at_platformIdentifier OBJ_tcg_common,8L - -#define SN_tcg_at_tpmManufacturer "tcg-at-tpmManufacturer" -#define LN_tcg_at_tpmManufacturer "TPM Manufacturer" -#define NID_tcg_at_tpmManufacturer 1345 -#define OBJ_tcg_at_tpmManufacturer OBJ_tcg_attribute,1L - -#define SN_tcg_at_tpmModel "tcg-at-tpmModel" -#define LN_tcg_at_tpmModel "TPM Model" -#define NID_tcg_at_tpmModel 1346 -#define OBJ_tcg_at_tpmModel OBJ_tcg_attribute,2L - -#define SN_tcg_at_tpmVersion "tcg-at-tpmVersion" -#define LN_tcg_at_tpmVersion "TPM Version" -#define NID_tcg_at_tpmVersion 1347 -#define OBJ_tcg_at_tpmVersion OBJ_tcg_attribute,3L - -#define SN_tcg_at_securityQualities "tcg-at-securityQualities" -#define LN_tcg_at_securityQualities "Security Qualities" -#define NID_tcg_at_securityQualities 1348 -#define OBJ_tcg_at_securityQualities OBJ_tcg_attribute,10L - -#define SN_tcg_at_tpmProtectionProfile "tcg-at-tpmProtectionProfile" -#define LN_tcg_at_tpmProtectionProfile "TPM Protection Profile" -#define NID_tcg_at_tpmProtectionProfile 1349 -#define OBJ_tcg_at_tpmProtectionProfile OBJ_tcg_attribute,11L - -#define SN_tcg_at_tpmSecurityTarget "tcg-at-tpmSecurityTarget" -#define LN_tcg_at_tpmSecurityTarget "TPM Security Target" -#define NID_tcg_at_tpmSecurityTarget 1350 -#define OBJ_tcg_at_tpmSecurityTarget OBJ_tcg_attribute,12L - -#define SN_tcg_at_tbbProtectionProfile "tcg-at-tbbProtectionProfile" -#define LN_tcg_at_tbbProtectionProfile "TBB Protection Profile" -#define NID_tcg_at_tbbProtectionProfile 1351 -#define OBJ_tcg_at_tbbProtectionProfile OBJ_tcg_attribute,13L - -#define SN_tcg_at_tbbSecurityTarget "tcg-at-tbbSecurityTarget" -#define LN_tcg_at_tbbSecurityTarget "TBB Security Target" -#define NID_tcg_at_tbbSecurityTarget 1352 -#define OBJ_tcg_at_tbbSecurityTarget OBJ_tcg_attribute,14L - -#define SN_tcg_at_tpmIdLabel "tcg-at-tpmIdLabel" -#define LN_tcg_at_tpmIdLabel "TPM ID Label" -#define NID_tcg_at_tpmIdLabel 1353 -#define OBJ_tcg_at_tpmIdLabel OBJ_tcg_attribute,15L - -#define SN_tcg_at_tpmSpecification "tcg-at-tpmSpecification" -#define LN_tcg_at_tpmSpecification "TPM Specification" -#define NID_tcg_at_tpmSpecification 1354 -#define OBJ_tcg_at_tpmSpecification OBJ_tcg_attribute,16L - -#define SN_tcg_at_tcgPlatformSpecification "tcg-at-tcgPlatformSpecification" -#define LN_tcg_at_tcgPlatformSpecification "TPM Platform Specification" -#define NID_tcg_at_tcgPlatformSpecification 1355 -#define OBJ_tcg_at_tcgPlatformSpecification OBJ_tcg_attribute,17L - -#define SN_tcg_at_tpmSecurityAssertions "tcg-at-tpmSecurityAssertions" -#define LN_tcg_at_tpmSecurityAssertions "TPM Security Assertions" -#define NID_tcg_at_tpmSecurityAssertions 1356 -#define OBJ_tcg_at_tpmSecurityAssertions OBJ_tcg_attribute,18L - -#define SN_tcg_at_tbbSecurityAssertions "tcg-at-tbbSecurityAssertions" -#define LN_tcg_at_tbbSecurityAssertions "TBB Security Assertions" -#define NID_tcg_at_tbbSecurityAssertions 1357 -#define OBJ_tcg_at_tbbSecurityAssertions OBJ_tcg_attribute,19L - -#define SN_tcg_at_tcgCredentialSpecification "tcg-at-tcgCredentialSpecification" -#define LN_tcg_at_tcgCredentialSpecification "TCG Credential Specification" -#define NID_tcg_at_tcgCredentialSpecification 1358 -#define OBJ_tcg_at_tcgCredentialSpecification OBJ_tcg_attribute,23L - -#define SN_tcg_at_tcgCredentialType "tcg-at-tcgCredentialType" -#define LN_tcg_at_tcgCredentialType "TCG Credential Type" -#define NID_tcg_at_tcgCredentialType 1359 -#define OBJ_tcg_at_tcgCredentialType OBJ_tcg_attribute,25L - -#define SN_tcg_at_previousPlatformCertificates "tcg-at-previousPlatformCertificates" -#define LN_tcg_at_previousPlatformCertificates "TCG Previous Platform Certificates" -#define NID_tcg_at_previousPlatformCertificates 1360 -#define OBJ_tcg_at_previousPlatformCertificates OBJ_tcg_attribute,26L - -#define SN_tcg_at_tbbSecurityAssertions_v3 "tcg-at-tbbSecurityAssertions-v3" -#define LN_tcg_at_tbbSecurityAssertions_v3 "TCG TBB Security Assertions V3" -#define NID_tcg_at_tbbSecurityAssertions_v3 1361 -#define OBJ_tcg_at_tbbSecurityAssertions_v3 OBJ_tcg_attribute,27L - -#define SN_tcg_at_cryptographicAnchors "tcg-at-cryptographicAnchors" -#define LN_tcg_at_cryptographicAnchors "TCG Cryptographic Anchors" -#define NID_tcg_at_cryptographicAnchors 1362 -#define OBJ_tcg_at_cryptographicAnchors OBJ_tcg_attribute,28L - -#define SN_tcg_at_platformConfiguration_v1 "tcg-at-platformConfiguration-v1" -#define LN_tcg_at_platformConfiguration_v1 "Platform Configuration Version 1" -#define NID_tcg_at_platformConfiguration_v1 1363 -#define OBJ_tcg_at_platformConfiguration_v1 OBJ_tcg_at_platformConfiguration,1L - -#define SN_tcg_at_platformConfiguration_v2 "tcg-at-platformConfiguration-v2" -#define LN_tcg_at_platformConfiguration_v2 "Platform Configuration Version 2" -#define NID_tcg_at_platformConfiguration_v2 1364 -#define OBJ_tcg_at_platformConfiguration_v2 OBJ_tcg_at_platformConfiguration,2L - -#define SN_tcg_at_platformConfiguration_v3 "tcg-at-platformConfiguration-v3" -#define LN_tcg_at_platformConfiguration_v3 "Platform Configuration Version 3" -#define NID_tcg_at_platformConfiguration_v3 1365 -#define OBJ_tcg_at_platformConfiguration_v3 OBJ_tcg_at_platformConfiguration,3L - -#define SN_tcg_at_platformConfigUri_v3 "tcg-at-platformConfigUri-v3" -#define LN_tcg_at_platformConfigUri_v3 "Platform Configuration URI Version 3" -#define NID_tcg_at_platformConfigUri_v3 1366 -#define OBJ_tcg_at_platformConfigUri_v3 OBJ_tcg_at_platformConfiguration,4L - -#define SN_tcg_algorithm_null "tcg-algorithm-null" -#define LN_tcg_algorithm_null "TCG NULL Algorithm" -#define NID_tcg_algorithm_null 1367 -#define OBJ_tcg_algorithm_null OBJ_tcg_algorithm,1L - -#define SN_tcg_kp_EKCertificate "tcg-kp-EKCertificate" -#define LN_tcg_kp_EKCertificate "Endorsement Key Certificate" -#define NID_tcg_kp_EKCertificate 1368 -#define OBJ_tcg_kp_EKCertificate OBJ_tcg_kp,1L - -#define SN_tcg_kp_PlatformAttributeCertificate "tcg-kp-PlatformAttributeCertificate" -#define LN_tcg_kp_PlatformAttributeCertificate "Platform Attribute Certificate" -#define NID_tcg_kp_PlatformAttributeCertificate 1369 -#define OBJ_tcg_kp_PlatformAttributeCertificate OBJ_tcg_kp,2L - -#define SN_tcg_kp_AIKCertificate "tcg-kp-AIKCertificate" -#define LN_tcg_kp_AIKCertificate "Attestation Identity Key Certificate" -#define NID_tcg_kp_AIKCertificate 1370 -#define OBJ_tcg_kp_AIKCertificate OBJ_tcg_kp,3L - -#define SN_tcg_kp_PlatformKeyCertificate "tcg-kp-PlatformKeyCertificate" -#define LN_tcg_kp_PlatformKeyCertificate "Platform Key Certificate" -#define NID_tcg_kp_PlatformKeyCertificate 1371 -#define OBJ_tcg_kp_PlatformKeyCertificate OBJ_tcg_kp,4L - -#define SN_tcg_kp_DeltaPlatformAttributeCertificate "tcg-kp-DeltaPlatformAttributeCertificate" -#define LN_tcg_kp_DeltaPlatformAttributeCertificate "Delta Platform Attribute Certificate" -#define NID_tcg_kp_DeltaPlatformAttributeCertificate 1372 -#define OBJ_tcg_kp_DeltaPlatformAttributeCertificate OBJ_tcg_kp,5L - -#define SN_tcg_kp_DeltaPlatformKeyCertificate "tcg-kp-DeltaPlatformKeyCertificate" -#define LN_tcg_kp_DeltaPlatformKeyCertificate "Delta Platform Key Certificate" -#define NID_tcg_kp_DeltaPlatformKeyCertificate 1373 -#define OBJ_tcg_kp_DeltaPlatformKeyCertificate OBJ_tcg_kp,6L - -#define SN_tcg_kp_AdditionalPlatformAttributeCertificate "tcg-kp-AdditionalPlatformAttributeCertificate" -#define LN_tcg_kp_AdditionalPlatformAttributeCertificate "Additional Platform Attribute Certificate" -#define NID_tcg_kp_AdditionalPlatformAttributeCertificate 1374 -#define OBJ_tcg_kp_AdditionalPlatformAttributeCertificate OBJ_tcg_kp,7L - -#define SN_tcg_kp_AdditionalPlatformKeyCertificate "tcg-kp-AdditionalPlatformKeyCertificate" -#define LN_tcg_kp_AdditionalPlatformKeyCertificate "Additional Platform Key Certificate" -#define NID_tcg_kp_AdditionalPlatformKeyCertificate 1375 -#define OBJ_tcg_kp_AdditionalPlatformKeyCertificate OBJ_tcg_kp,8L - -#define SN_tcg_ce_relevantCredentials "tcg-ce-relevantCredentials" -#define LN_tcg_ce_relevantCredentials "Relevant Credentials" -#define NID_tcg_ce_relevantCredentials 1376 -#define OBJ_tcg_ce_relevantCredentials OBJ_tcg_ce,2L - -#define SN_tcg_ce_relevantManifests "tcg-ce-relevantManifests" -#define LN_tcg_ce_relevantManifests "Relevant Manifests" -#define NID_tcg_ce_relevantManifests 1377 -#define OBJ_tcg_ce_relevantManifests OBJ_tcg_ce,3L - -#define SN_tcg_ce_virtualPlatformAttestationService "tcg-ce-virtualPlatformAttestationService" -#define LN_tcg_ce_virtualPlatformAttestationService "Virtual Platform Attestation Service" -#define NID_tcg_ce_virtualPlatformAttestationService 1378 -#define OBJ_tcg_ce_virtualPlatformAttestationService OBJ_tcg_ce,4L - -#define SN_tcg_ce_migrationControllerAttestationService "tcg-ce-migrationControllerAttestationService" -#define LN_tcg_ce_migrationControllerAttestationService "Migration Controller Attestation Service" -#define NID_tcg_ce_migrationControllerAttestationService 1379 -#define OBJ_tcg_ce_migrationControllerAttestationService OBJ_tcg_ce,5L - -#define SN_tcg_ce_migrationControllerRegistrationService "tcg-ce-migrationControllerRegistrationService" -#define LN_tcg_ce_migrationControllerRegistrationService "Migration Controller Registration Service" -#define NID_tcg_ce_migrationControllerRegistrationService 1380 -#define OBJ_tcg_ce_migrationControllerRegistrationService OBJ_tcg_ce,6L - -#define SN_tcg_ce_virtualPlatformBackupService "tcg-ce-virtualPlatformBackupService" -#define LN_tcg_ce_virtualPlatformBackupService "Virtual Platform Backup Service" -#define NID_tcg_ce_virtualPlatformBackupService 1381 -#define OBJ_tcg_ce_virtualPlatformBackupService OBJ_tcg_ce,7L - -#define SN_tcg_prt_tpmIdProtocol "tcg-prt-tpmIdProtocol" -#define LN_tcg_prt_tpmIdProtocol "TCG TPM Protocol" -#define NID_tcg_prt_tpmIdProtocol 1382 -#define OBJ_tcg_prt_tpmIdProtocol OBJ_tcg_protocol,1L - -#define SN_tcg_address_ethernetmac "tcg-address-ethernetmac" -#define LN_tcg_address_ethernetmac "Ethernet MAC Address" -#define NID_tcg_address_ethernetmac 1383 -#define OBJ_tcg_address_ethernetmac OBJ_tcg_address,1L - -#define SN_tcg_address_wlanmac "tcg-address-wlanmac" -#define LN_tcg_address_wlanmac "WLAN MAC Address" -#define NID_tcg_address_wlanmac 1384 -#define OBJ_tcg_address_wlanmac OBJ_tcg_address,2L - -#define SN_tcg_address_bluetoothmac "tcg-address-bluetoothmac" -#define LN_tcg_address_bluetoothmac "Bluetooth MAC Address" -#define NID_tcg_address_bluetoothmac 1385 -#define OBJ_tcg_address_bluetoothmac OBJ_tcg_address,3L - -#define SN_tcg_registry_componentClass "tcg-registry-componentClass" -#define LN_tcg_registry_componentClass "TCG Component Class" -#define NID_tcg_registry_componentClass 1386 -#define OBJ_tcg_registry_componentClass OBJ_tcg_registry,3L - -#define SN_tcg_registry_componentClass_tcg "tcg-registry-componentClass-tcg" -#define LN_tcg_registry_componentClass_tcg "Trusted Computed Group Registry" -#define NID_tcg_registry_componentClass_tcg 1387 -#define OBJ_tcg_registry_componentClass_tcg OBJ_tcg_registry_componentClass,1L - -#define SN_tcg_registry_componentClass_ietf "tcg-registry-componentClass-ietf" -#define LN_tcg_registry_componentClass_ietf "Internet Engineering Task Force Registry" -#define NID_tcg_registry_componentClass_ietf 1388 -#define OBJ_tcg_registry_componentClass_ietf OBJ_tcg_registry_componentClass,2L - -#define SN_tcg_registry_componentClass_dmtf "tcg-registry-componentClass-dmtf" -#define LN_tcg_registry_componentClass_dmtf "Distributed Management Task Force Registry" -#define NID_tcg_registry_componentClass_dmtf 1389 -#define OBJ_tcg_registry_componentClass_dmtf OBJ_tcg_registry_componentClass,3L - -#define SN_tcg_registry_componentClass_pcie "tcg-registry-componentClass-pcie" -#define LN_tcg_registry_componentClass_pcie "PCIE Component Class" -#define NID_tcg_registry_componentClass_pcie 1390 -#define OBJ_tcg_registry_componentClass_pcie OBJ_tcg_registry_componentClass,4L - -#define SN_tcg_registry_componentClass_disk "tcg-registry-componentClass-disk" -#define LN_tcg_registry_componentClass_disk "Disk Component Class" -#define NID_tcg_registry_componentClass_disk 1391 -#define OBJ_tcg_registry_componentClass_disk OBJ_tcg_registry_componentClass,5L - -#define SN_tcg_cap_verifiedPlatformCertificate "tcg-cap-verifiedPlatformCertificate" -#define LN_tcg_cap_verifiedPlatformCertificate "TCG Verified Platform Certificate CA Policy" -#define NID_tcg_cap_verifiedPlatformCertificate 1392 -#define OBJ_tcg_cap_verifiedPlatformCertificate OBJ_tcg_ca,4L - -#define SN_tcg_tr_ID "tcg-tr-ID" -#define LN_tcg_tr_ID "TCG Trait Identifiers" -#define NID_tcg_tr_ID 1393 -#define OBJ_tcg_tr_ID OBJ_tcg_traits,1L - -#define SN_tcg_tr_category "tcg-tr-category" -#define LN_tcg_tr_category "TCG Trait Categories" -#define NID_tcg_tr_category 1394 -#define OBJ_tcg_tr_category OBJ_tcg_traits,2L - -#define SN_tcg_tr_registry "tcg-tr-registry" -#define LN_tcg_tr_registry "TCG Trait Registries" -#define NID_tcg_tr_registry 1395 -#define OBJ_tcg_tr_registry OBJ_tcg_traits,3L - -#define SN_tcg_tr_ID_Boolean "tcg-tr-ID-Boolean" -#define LN_tcg_tr_ID_Boolean "Boolean Trait" -#define NID_tcg_tr_ID_Boolean 1396 -#define OBJ_tcg_tr_ID_Boolean OBJ_tcg_tr_ID,1L - -#define SN_tcg_tr_ID_CertificateIdentifier "tcg-tr-ID-CertificateIdentifier" -#define LN_tcg_tr_ID_CertificateIdentifier "Certificate Identifier Trait" -#define NID_tcg_tr_ID_CertificateIdentifier 1397 -#define OBJ_tcg_tr_ID_CertificateIdentifier OBJ_tcg_tr_ID,2L - -#define SN_tcg_tr_ID_CommonCriteria "tcg-tr-ID-CommonCriteria" -#define LN_tcg_tr_ID_CommonCriteria "Common Criteria Trait" -#define NID_tcg_tr_ID_CommonCriteria 1398 -#define OBJ_tcg_tr_ID_CommonCriteria OBJ_tcg_tr_ID,3L - -#define SN_tcg_tr_ID_componentClass "tcg-tr-ID-componentClass" -#define LN_tcg_tr_ID_componentClass "Component Class Trait" -#define NID_tcg_tr_ID_componentClass 1399 -#define OBJ_tcg_tr_ID_componentClass OBJ_tcg_tr_ID,4L - -#define SN_tcg_tr_ID_componentIdentifierV11 "tcg-tr-ID-componentIdentifierV11" -#define LN_tcg_tr_ID_componentIdentifierV11 "Component Identifier V1.1 Trait" -#define NID_tcg_tr_ID_componentIdentifierV11 1400 -#define OBJ_tcg_tr_ID_componentIdentifierV11 OBJ_tcg_tr_ID,5L - -#define SN_tcg_tr_ID_FIPSLevel "tcg-tr-ID-FIPSLevel" -#define LN_tcg_tr_ID_FIPSLevel "FIPS Level Trait" -#define NID_tcg_tr_ID_FIPSLevel 1401 -#define OBJ_tcg_tr_ID_FIPSLevel OBJ_tcg_tr_ID,6L - -#define SN_tcg_tr_ID_ISO9000Level "tcg-tr-ID-ISO9000Level" -#define LN_tcg_tr_ID_ISO9000Level "ISO 9000 Level Trait" -#define NID_tcg_tr_ID_ISO9000Level 1402 -#define OBJ_tcg_tr_ID_ISO9000Level OBJ_tcg_tr_ID,7L - -#define SN_tcg_tr_ID_networkMAC "tcg-tr-ID-networkMAC" -#define LN_tcg_tr_ID_networkMAC "Network MAC Trait" -#define NID_tcg_tr_ID_networkMAC 1403 -#define OBJ_tcg_tr_ID_networkMAC OBJ_tcg_tr_ID,8L - -#define SN_tcg_tr_ID_OID "tcg-tr-ID-OID" -#define LN_tcg_tr_ID_OID "Object Identifier Trait" -#define NID_tcg_tr_ID_OID 1404 -#define OBJ_tcg_tr_ID_OID OBJ_tcg_tr_ID,9L - -#define SN_tcg_tr_ID_PEN "tcg-tr-ID-PEN" -#define LN_tcg_tr_ID_PEN "Private Enterprise Number Trait" -#define NID_tcg_tr_ID_PEN 1405 -#define OBJ_tcg_tr_ID_PEN OBJ_tcg_tr_ID,10L - -#define SN_tcg_tr_ID_platformFirmwareCapabilities "tcg-tr-ID-platformFirmwareCapabilities" -#define LN_tcg_tr_ID_platformFirmwareCapabilities "Platform Firmware Capabilities Trait" -#define NID_tcg_tr_ID_platformFirmwareCapabilities 1406 -#define OBJ_tcg_tr_ID_platformFirmwareCapabilities OBJ_tcg_tr_ID,11L - -#define SN_tcg_tr_ID_platformFirmwareSignatureVerification "tcg-tr-ID-platformFirmwareSignatureVerification" -#define LN_tcg_tr_ID_platformFirmwareSignatureVerification "Platform Firmware Signature Verification Trait" -#define NID_tcg_tr_ID_platformFirmwareSignatureVerification 1407 -#define OBJ_tcg_tr_ID_platformFirmwareSignatureVerification OBJ_tcg_tr_ID,12L - -#define SN_tcg_tr_ID_platformFirmwareUpdateCompliance "tcg-tr-ID-platformFirmwareUpdateCompliance" -#define LN_tcg_tr_ID_platformFirmwareUpdateCompliance "Platform Firmware Update Compliance Trait" -#define NID_tcg_tr_ID_platformFirmwareUpdateCompliance 1408 -#define OBJ_tcg_tr_ID_platformFirmwareUpdateCompliance OBJ_tcg_tr_ID,13L - -#define SN_tcg_tr_ID_platformHardwareCapabilities "tcg-tr-ID-platformHardwareCapabilities" -#define LN_tcg_tr_ID_platformHardwareCapabilities "Platform Hardware Capabilities Trait" -#define NID_tcg_tr_ID_platformHardwareCapabilities 1409 -#define OBJ_tcg_tr_ID_platformHardwareCapabilities OBJ_tcg_tr_ID,14L - -#define SN_tcg_tr_ID_RTM "tcg-tr-ID-RTM" -#define LN_tcg_tr_ID_RTM "Root of Trust for Measurement Trait" -#define NID_tcg_tr_ID_RTM 1410 -#define OBJ_tcg_tr_ID_RTM OBJ_tcg_tr_ID,15L - -#define SN_tcg_tr_ID_status "tcg-tr-ID-status" -#define LN_tcg_tr_ID_status "Attribute Status Trait" -#define NID_tcg_tr_ID_status 1411 -#define OBJ_tcg_tr_ID_status OBJ_tcg_tr_ID,16L - -#define SN_tcg_tr_ID_URI "tcg-tr-ID-URI" -#define LN_tcg_tr_ID_URI "Uniform Resource Identifier Trait" -#define NID_tcg_tr_ID_URI 1412 -#define OBJ_tcg_tr_ID_URI OBJ_tcg_tr_ID,17L - -#define SN_tcg_tr_ID_UTF8String "tcg-tr-ID-UTF8String" -#define LN_tcg_tr_ID_UTF8String "UTF8String Trait" -#define NID_tcg_tr_ID_UTF8String 1413 -#define OBJ_tcg_tr_ID_UTF8String OBJ_tcg_tr_ID,18L - -#define SN_tcg_tr_ID_IA5String "tcg-tr-ID-IA5String" -#define LN_tcg_tr_ID_IA5String "IA5String Trait" -#define NID_tcg_tr_ID_IA5String 1414 -#define OBJ_tcg_tr_ID_IA5String OBJ_tcg_tr_ID,19L - -#define SN_tcg_tr_ID_PEMCertString "tcg-tr-ID-PEMCertString" -#define LN_tcg_tr_ID_PEMCertString "PEM-Encoded Certificate String Trait" -#define NID_tcg_tr_ID_PEMCertString 1415 -#define OBJ_tcg_tr_ID_PEMCertString OBJ_tcg_tr_ID,20L - -#define SN_tcg_tr_ID_PublicKey "tcg-tr-ID-PublicKey" -#define LN_tcg_tr_ID_PublicKey "Public Key Trait" -#define NID_tcg_tr_ID_PublicKey 1416 -#define OBJ_tcg_tr_ID_PublicKey OBJ_tcg_tr_ID,21L - -#define SN_tcg_tr_cat_platformManufacturer "tcg-tr-cat-platformManufacturer" -#define LN_tcg_tr_cat_platformManufacturer "Platform Manufacturer Trait Category" -#define NID_tcg_tr_cat_platformManufacturer 1417 -#define OBJ_tcg_tr_cat_platformManufacturer OBJ_tcg_tr_category,1L - -#define SN_tcg_tr_cat_platformModel "tcg-tr-cat-platformModel" -#define LN_tcg_tr_cat_platformModel "Platform Model Trait Category" -#define NID_tcg_tr_cat_platformModel 1418 -#define OBJ_tcg_tr_cat_platformModel OBJ_tcg_tr_category,2L - -#define SN_tcg_tr_cat_platformVersion "tcg-tr-cat-platformVersion" -#define LN_tcg_tr_cat_platformVersion "Platform Version Trait Category" -#define NID_tcg_tr_cat_platformVersion 1419 -#define OBJ_tcg_tr_cat_platformVersion OBJ_tcg_tr_category,3L - -#define SN_tcg_tr_cat_platformSerial "tcg-tr-cat-platformSerial" -#define LN_tcg_tr_cat_platformSerial "Platform Serial Trait Category" -#define NID_tcg_tr_cat_platformSerial 1420 -#define OBJ_tcg_tr_cat_platformSerial OBJ_tcg_tr_category,4L - -#define SN_tcg_tr_cat_platformManufacturerIdentifier "tcg-tr-cat-platformManufacturerIdentifier" -#define LN_tcg_tr_cat_platformManufacturerIdentifier "Platform Manufacturer Identifier Trait Category" -#define NID_tcg_tr_cat_platformManufacturerIdentifier 1421 -#define OBJ_tcg_tr_cat_platformManufacturerIdentifier OBJ_tcg_tr_category,5L - -#define SN_tcg_tr_cat_platformOwnership "tcg-tr-cat-platformOwnership" -#define LN_tcg_tr_cat_platformOwnership "Platform Ownership Trait Category" -#define NID_tcg_tr_cat_platformOwnership 1422 -#define OBJ_tcg_tr_cat_platformOwnership OBJ_tcg_tr_category,6L - -#define SN_tcg_tr_cat_componentClass "tcg-tr-cat-componentClass" -#define LN_tcg_tr_cat_componentClass "Component Class Trait Category" -#define NID_tcg_tr_cat_componentClass 1423 -#define OBJ_tcg_tr_cat_componentClass OBJ_tcg_tr_category,7L - -#define SN_tcg_tr_cat_componentManufacturer "tcg-tr-cat-componentManufacturer" -#define LN_tcg_tr_cat_componentManufacturer "Component Manufacturer Trait Category" -#define NID_tcg_tr_cat_componentManufacturer 1424 -#define OBJ_tcg_tr_cat_componentManufacturer OBJ_tcg_tr_category,8L - -#define SN_tcg_tr_cat_componentModel "tcg-tr-cat-componentModel" -#define LN_tcg_tr_cat_componentModel "Component Model Trait Category" -#define NID_tcg_tr_cat_componentModel 1425 -#define OBJ_tcg_tr_cat_componentModel OBJ_tcg_tr_category,9L - -#define SN_tcg_tr_cat_componentSerial "tcg-tr-cat-componentSerial" -#define LN_tcg_tr_cat_componentSerial "Component Serial Trait Category" -#define NID_tcg_tr_cat_componentSerial 1426 -#define OBJ_tcg_tr_cat_componentSerial OBJ_tcg_tr_category,10L - -#define SN_tcg_tr_cat_componentStatus "tcg-tr-cat-componentStatus" -#define LN_tcg_tr_cat_componentStatus "Component Status Trait Category" -#define NID_tcg_tr_cat_componentStatus 1427 -#define OBJ_tcg_tr_cat_componentStatus OBJ_tcg_tr_category,11L - -#define SN_tcg_tr_cat_componentLocation "tcg-tr-cat-componentLocation" -#define LN_tcg_tr_cat_componentLocation "Component Location Trait Category" -#define NID_tcg_tr_cat_componentLocation 1428 -#define OBJ_tcg_tr_cat_componentLocation OBJ_tcg_tr_category,12L - -#define SN_tcg_tr_cat_componentRevision "tcg-tr-cat-componentRevision" -#define LN_tcg_tr_cat_componentRevision "Component Revision Trait Category" -#define NID_tcg_tr_cat_componentRevision 1429 -#define OBJ_tcg_tr_cat_componentRevision OBJ_tcg_tr_category,13L - -#define SN_tcg_tr_cat_componentFieldReplaceable "tcg-tr-cat-componentFieldReplaceable" -#define LN_tcg_tr_cat_componentFieldReplaceable "Component Field Replaceable Trait Category" -#define NID_tcg_tr_cat_componentFieldReplaceable 1430 -#define OBJ_tcg_tr_cat_componentFieldReplaceable OBJ_tcg_tr_category,14L - -#define SN_tcg_tr_cat_EKCertificate "tcg-tr-cat-EKCertificate" -#define LN_tcg_tr_cat_EKCertificate "EK Certificate Trait Category" -#define NID_tcg_tr_cat_EKCertificate 1431 -#define OBJ_tcg_tr_cat_EKCertificate OBJ_tcg_tr_category,15L - -#define SN_tcg_tr_cat_IAKCertificate "tcg-tr-cat-IAKCertificate" -#define LN_tcg_tr_cat_IAKCertificate "IAK Certificate Trait Category" -#define NID_tcg_tr_cat_IAKCertificate 1432 -#define OBJ_tcg_tr_cat_IAKCertificate OBJ_tcg_tr_category,16L - -#define SN_tcg_tr_cat_IDevIDCertificate "tcg-tr-cat-IDevIDCertificate" -#define LN_tcg_tr_cat_IDevIDCertificate "IDevID Certificate Trait Category" -#define NID_tcg_tr_cat_IDevIDCertificate 1433 -#define OBJ_tcg_tr_cat_IDevIDCertificate OBJ_tcg_tr_category,17L - -#define SN_tcg_tr_cat_DICECertificate "tcg-tr-cat-DICECertificate" -#define LN_tcg_tr_cat_DICECertificate "DICE Certificate Trait Category" -#define NID_tcg_tr_cat_DICECertificate 1434 -#define OBJ_tcg_tr_cat_DICECertificate OBJ_tcg_tr_category,18L - -#define SN_tcg_tr_cat_SPDMCertificate "tcg-tr-cat-SPDMCertificate" -#define LN_tcg_tr_cat_SPDMCertificate "SPDM Certificate Trait Category" -#define NID_tcg_tr_cat_SPDMCertificate 1435 -#define OBJ_tcg_tr_cat_SPDMCertificate OBJ_tcg_tr_category,19L - -#define SN_tcg_tr_cat_PEMCertificate "tcg-tr-cat-PEMCertificate" -#define LN_tcg_tr_cat_PEMCertificate "PEM Certificate Trait Category" -#define NID_tcg_tr_cat_PEMCertificate 1436 -#define OBJ_tcg_tr_cat_PEMCertificate OBJ_tcg_tr_category,20L - -#define SN_tcg_tr_cat_PlatformCertificate "tcg-tr-cat-PlatformCertificate" -#define LN_tcg_tr_cat_PlatformCertificate "Platform Certificate Trait Category" -#define NID_tcg_tr_cat_PlatformCertificate 1437 -#define OBJ_tcg_tr_cat_PlatformCertificate OBJ_tcg_tr_category,21L - -#define SN_tcg_tr_cat_DeltaPlatformCertificate "tcg-tr-cat-DeltaPlatformCertificate" -#define LN_tcg_tr_cat_DeltaPlatformCertificate "Delta Platform Certificate Trait Category" -#define NID_tcg_tr_cat_DeltaPlatformCertificate 1438 -#define OBJ_tcg_tr_cat_DeltaPlatformCertificate OBJ_tcg_tr_category,22L - -#define SN_tcg_tr_cat_RebasePlatformCertificate "tcg-tr-cat-RebasePlatformCertificate" -#define LN_tcg_tr_cat_RebasePlatformCertificate "Rebase Platform Certificate Trait Category" -#define NID_tcg_tr_cat_RebasePlatformCertificate 1439 -#define OBJ_tcg_tr_cat_RebasePlatformCertificate OBJ_tcg_tr_category,23L - -#define SN_tcg_tr_cat_genericCertificate "tcg-tr-cat-genericCertificate" -#define LN_tcg_tr_cat_genericCertificate "Generic Certificate Trait Category" -#define NID_tcg_tr_cat_genericCertificate 1440 -#define OBJ_tcg_tr_cat_genericCertificate OBJ_tcg_tr_category,24L - -#define SN_tcg_tr_cat_CommonCriteria "tcg-tr-cat-CommonCriteria" -#define LN_tcg_tr_cat_CommonCriteria "Common Criteria Trait Category" -#define NID_tcg_tr_cat_CommonCriteria 1441 -#define OBJ_tcg_tr_cat_CommonCriteria OBJ_tcg_tr_category,25L - -#define SN_tcg_tr_cat_componentIdentifierV11 "tcg-tr-cat-componentIdentifierV11" -#define LN_tcg_tr_cat_componentIdentifierV11 "Component Identifier V1.1 Trait Category" -#define NID_tcg_tr_cat_componentIdentifierV11 1442 -#define OBJ_tcg_tr_cat_componentIdentifierV11 OBJ_tcg_tr_category,26L - -#define SN_tcg_tr_cat_FIPSLevel "tcg-tr-cat-FIPSLevel" -#define LN_tcg_tr_cat_FIPSLevel "FIPS Level Trait Category" -#define NID_tcg_tr_cat_FIPSLevel 1443 -#define OBJ_tcg_tr_cat_FIPSLevel OBJ_tcg_tr_category,27L - -#define SN_tcg_tr_cat_ISO9000 "tcg-tr-cat-ISO9000" -#define LN_tcg_tr_cat_ISO9000 "ISO 9000 Trait Category" -#define NID_tcg_tr_cat_ISO9000 1444 -#define OBJ_tcg_tr_cat_ISO9000 OBJ_tcg_tr_category,28L - -#define SN_tcg_tr_cat_networkMAC "tcg-tr-cat-networkMAC" -#define LN_tcg_tr_cat_networkMAC "Network MAC Trait Category" -#define NID_tcg_tr_cat_networkMAC 1445 -#define OBJ_tcg_tr_cat_networkMAC OBJ_tcg_tr_category,29L - -#define SN_tcg_tr_cat_attestationProtocol "tcg-tr-cat-attestationProtocol" -#define LN_tcg_tr_cat_attestationProtocol "Attestation Protocol Trait Category" -#define NID_tcg_tr_cat_attestationProtocol 1446 -#define OBJ_tcg_tr_cat_attestationProtocol OBJ_tcg_tr_category,30L - -#define SN_tcg_tr_cat_PEN "tcg-tr-cat-PEN" -#define LN_tcg_tr_cat_PEN "Private Enterprise Number Trait Category" -#define NID_tcg_tr_cat_PEN 1447 -#define OBJ_tcg_tr_cat_PEN OBJ_tcg_tr_category,31L - -#define SN_tcg_tr_cat_platformFirmwareCapabilities "tcg-tr-cat-platformFirmwareCapabilities" -#define LN_tcg_tr_cat_platformFirmwareCapabilities "Platform Firmware Capabilities Trait Category" -#define NID_tcg_tr_cat_platformFirmwareCapabilities 1448 -#define OBJ_tcg_tr_cat_platformFirmwareCapabilities OBJ_tcg_tr_category,32L - -#define SN_tcg_tr_cat_platformHardwareCapabilities "tcg-tr-cat-platformHardwareCapabilities" -#define LN_tcg_tr_cat_platformHardwareCapabilities "Platform Hardware Capabilities Trait Category" -#define NID_tcg_tr_cat_platformHardwareCapabilities 1449 -#define OBJ_tcg_tr_cat_platformHardwareCapabilities OBJ_tcg_tr_category,33L - -#define SN_tcg_tr_cat_platformFirmwareSignatureVerification "tcg-tr-cat-platformFirmwareSignatureVerification" -#define LN_tcg_tr_cat_platformFirmwareSignatureVerification "Platform Firmware Signature Verification Trait Category" -#define NID_tcg_tr_cat_platformFirmwareSignatureVerification 1450 -#define OBJ_tcg_tr_cat_platformFirmwareSignatureVerification OBJ_tcg_tr_category,34L - -#define SN_tcg_tr_cat_platformFirmwareUpdateCompliance "tcg-tr-cat-platformFirmwareUpdateCompliance" -#define LN_tcg_tr_cat_platformFirmwareUpdateCompliance "Platform Firmware Update Compliance Trait Category" -#define NID_tcg_tr_cat_platformFirmwareUpdateCompliance 1451 -#define OBJ_tcg_tr_cat_platformFirmwareUpdateCompliance OBJ_tcg_tr_category,35L - -#define SN_tcg_tr_cat_RTM "tcg-tr-cat-RTM" -#define LN_tcg_tr_cat_RTM "Root of Trust of Measurement Trait Category" -#define NID_tcg_tr_cat_RTM 1452 -#define OBJ_tcg_tr_cat_RTM OBJ_tcg_tr_category,36L - -#define SN_tcg_tr_cat_PublicKey "tcg-tr-cat-PublicKey" -#define LN_tcg_tr_cat_PublicKey "Public Key Trait Category" -#define NID_tcg_tr_cat_PublicKey 1453 -#define OBJ_tcg_tr_cat_PublicKey OBJ_tcg_tr_category,37L - -#define OBJ_nistKems OBJ_nistAlgorithms,4L - -#define SN_ML_KEM_512 "id-alg-ml-kem-512" -#define LN_ML_KEM_512 "ML-KEM-512" -#define NID_ML_KEM_512 1454 -#define OBJ_ML_KEM_512 OBJ_nistKems,1L - -#define SN_ML_KEM_768 "id-alg-ml-kem-768" -#define LN_ML_KEM_768 "ML-KEM-768" -#define NID_ML_KEM_768 1455 -#define OBJ_ML_KEM_768 OBJ_nistKems,2L - -#define SN_ML_KEM_1024 "id-alg-ml-kem-1024" -#define LN_ML_KEM_1024 "ML-KEM-1024" -#define NID_ML_KEM_1024 1456 -#define OBJ_ML_KEM_1024 OBJ_nistKems,3L -/* clang-format on */ - -#endif /* OPENSSL_OBJ_MAC_H */ - -#ifndef OPENSSL_NO_DEPRECATED_3_0 - -#define SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm SN_magma_ctr_acpkm -#define NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm NID_magma_ctr_acpkm -#define OBJ_id_tc26_cipher_gostr3412_2015_magma_ctracpkm OBJ_magma_ctr_acpkm - -#define SN_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac SN_magma_ctr_acpkm_omac -#define NID_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac NID_magma_ctr_acpkm_omac -#define OBJ_id_tc26_cipher_gostr3412_2015_magma_ctracpkm_omac OBJ_magma_ctr_acpkm_omac - -#define SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm SN_kuznyechik_ctr_acpkm -#define NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm NID_kuznyechik_ctr_acpkm -#define OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm OBJ_kuznyechik_ctr_acpkm - -#define SN_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac SN_kuznyechik_ctr_acpkm_omac -#define NID_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac NID_kuznyechik_ctr_acpkm_omac -#define OBJ_id_tc26_cipher_gostr3412_2015_kuznyechik_ctracpkm_omac OBJ_kuznyechik_ctr_acpkm_omac - -#define SN_id_tc26_wrap_gostr3412_2015_magma_kexp15 SN_magma_kexp15 -#define NID_id_tc26_wrap_gostr3412_2015_magma_kexp15 NID_magma_kexp15 -#define OBJ_id_tc26_wrap_gostr3412_2015_magma_kexp15 OBJ_magma_kexp15 - -#define SN_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 SN_kuznyechik_kexp15 -#define NID_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 NID_kuznyechik_kexp15 -#define OBJ_id_tc26_wrap_gostr3412_2015_kuznyechik_kexp15 OBJ_kuznyechik_kexp15 - -#define SN_grasshopper_ecb SN_kuznyechik_ecb -#define NID_grasshopper_ecb NID_kuznyechik_ecb - -#define SN_grasshopper_ctr SN_kuznyechik_ctr -#define NID_grasshopper_ctr NID_kuznyechik_ctr - -#define SN_grasshopper_ofb SN_kuznyechik_ofb -#define NID_grasshopper_ofb NID_kuznyechik_ofb - -#define SN_grasshopper_cbc SN_kuznyechik_cbc -#define NID_grasshopper_cbc NID_kuznyechik_cbc - -#define SN_grasshopper_cfb SN_kuznyechik_cfb -#define NID_grasshopper_cfb NID_kuznyechik_cfb - -#define SN_grasshopper_mac SN_kuznyechik_mac -#define NID_grasshopper_mac NID_kuznyechik_mac - -#endif /* OPENSSL_NO_DEPRECATED_3_0 */ diff --git a/include/openssl/objectserr.h b/include/openssl/objectserr.h deleted file mode 100644 index 2927561135f20..0000000000000 --- a/include/openssl/objectserr.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_OBJECTSERR_H -#define OPENSSL_OBJECTSERR_H -#pragma once - -#include -#include -#include - -/* - * OBJ reason codes. - */ -#define OBJ_R_OID_EXISTS 102 -#define OBJ_R_UNKNOWN_NID 101 -#define OBJ_R_UNKNOWN_OBJECT_NAME 103 - -#endif diff --git a/include/openssl/ocsperr.h b/include/openssl/ocsperr.h deleted file mode 100644 index 18e035e8a4e10..0000000000000 --- a/include/openssl/ocsperr.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_OCSPERR_H -#define OPENSSL_OCSPERR_H -#pragma once - -#include -#include -#include - -#ifndef OPENSSL_NO_OCSP - -/* - * OCSP reason codes. - */ -#define OCSP_R_CERTIFICATE_VERIFY_ERROR 101 -#define OCSP_R_DIGEST_ERR 102 -#define OCSP_R_DIGEST_NAME_ERR 106 -#define OCSP_R_DIGEST_SIZE_ERR 107 -#define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD 122 -#define OCSP_R_ERROR_IN_THISUPDATE_FIELD 123 -#define OCSP_R_MISSING_OCSPSIGNING_USAGE 103 -#define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE 124 -#define OCSP_R_NOT_BASIC_RESPONSE 104 -#define OCSP_R_NO_CERTIFICATES_IN_CHAIN 105 -#define OCSP_R_NO_RESPONSE_DATA 108 -#define OCSP_R_NO_REVOKED_TIME 109 -#define OCSP_R_NO_SIGNER_KEY 130 -#define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 110 -#define OCSP_R_REQUEST_NOT_SIGNED 128 -#define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA 111 -#define OCSP_R_ROOT_CA_NOT_TRUSTED 112 -#define OCSP_R_SIGNATURE_FAILURE 117 -#define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND 118 -#define OCSP_R_STATUS_EXPIRED 125 -#define OCSP_R_STATUS_NOT_YET_VALID 126 -#define OCSP_R_STATUS_TOO_OLD 127 -#define OCSP_R_UNKNOWN_MESSAGE_DIGEST 119 -#define OCSP_R_UNKNOWN_NID 120 -#define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE 129 - -#endif -#endif diff --git a/include/openssl/ossl_typ.h b/include/openssl/ossl_typ.h index c3899c97dc6a9..fa396e92170c6 100644 --- a/include/openssl/ossl_typ.h +++ b/include/openssl/ossl_typ.h @@ -1,5 +1,5 @@ /* - * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/pemerr.h b/include/openssl/pemerr.h deleted file mode 100644 index eb3c9a1d94fa1..0000000000000 --- a/include/openssl/pemerr.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_PEMERR_H -#define OPENSSL_PEMERR_H -#pragma once - -#include -#include -#include - -/* - * PEM reason codes. - */ -#define PEM_R_BAD_BASE64_DECODE 100 -#define PEM_R_BAD_DECRYPT 101 -#define PEM_R_BAD_END_LINE 102 -#define PEM_R_BAD_IV_CHARS 103 -#define PEM_R_BAD_MAGIC_NUMBER 116 -#define PEM_R_BAD_PASSWORD_READ 104 -#define PEM_R_BAD_VERSION_NUMBER 117 -#define PEM_R_BIO_WRITE_FAILURE 118 -#define PEM_R_CIPHER_IS_NULL 127 -#define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115 -#define PEM_R_EXPECTING_DSS_KEY_BLOB 131 -#define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119 -#define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120 -#define PEM_R_EXPECTING_RSA_KEY_BLOB 132 -#define PEM_R_HEADER_TOO_LONG 128 -#define PEM_R_INCONSISTENT_HEADER 121 -#define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122 -#define PEM_R_KEYBLOB_TOO_SHORT 123 -#define PEM_R_MISSING_DEK_IV 129 -#define PEM_R_NOT_DEK_INFO 105 -#define PEM_R_NOT_ENCRYPTED 106 -#define PEM_R_NOT_PROC_TYPE 107 -#define PEM_R_NO_START_LINE 108 -#define PEM_R_PROBLEMS_GETTING_PASSWORD 109 -#define PEM_R_PVK_DATA_TOO_SHORT 124 -#define PEM_R_PVK_TOO_SHORT 125 -#define PEM_R_READ_KEY 111 -#define PEM_R_SHORT_HEADER 112 -#define PEM_R_UNEXPECTED_DEK_IV 130 -#define PEM_R_UNSUPPORTED_CIPHER 113 -#define PEM_R_UNSUPPORTED_ENCRYPTION 114 -#define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126 -#define PEM_R_UNSUPPORTED_PUBLIC_KEY_TYPE 110 -#define PEM_R_UNSUPPORTED_PVK_KEY_TYPE 133 - -#endif diff --git a/include/openssl/pkcs12.h.in b/include/openssl/pkcs12.h.in index 6555322be314f..1c470f15e0cbf 100644 --- a/include/openssl/pkcs12.h.in +++ b/include/openssl/pkcs12.h.in @@ -27,6 +27,7 @@ use OpenSSL::stackhash qw(generate_stack_macros); #include #include #include +#include #include #ifndef OPENSSL_NO_STDIO #include @@ -125,6 +126,9 @@ X509 *PKCS12_SAFEBAG_get1_cert_ex(const PKCS12_SAFEBAG *bag, OSSL_LIB_CTX *libct X509 *PKCS12_SAFEBAG_get1_cert(const PKCS12_SAFEBAG *bag); X509_CRL *PKCS12_SAFEBAG_get1_crl_ex(const PKCS12_SAFEBAG *bag, OSSL_LIB_CTX *libctx, const char *propq); X509_CRL *PKCS12_SAFEBAG_get1_crl(const PKCS12_SAFEBAG *bag); +EVP_SKEY *PKCS8_PRIV_KEY_INFO_get1_skey(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq, + const OSSL_PARAM *extra_params, int strict); const STACK_OF(PKCS12_SAFEBAG) * PKCS12_SAFEBAG_get0_safes(const PKCS12_SAFEBAG *bag); const PKCS8_PRIV_KEY_INFO *PKCS12_SAFEBAG_get0_p8inf(const PKCS12_SAFEBAG *bag); @@ -163,6 +167,9 @@ PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey_ex(const PKCS12_SAFEBAG *bag, const char *pass, int passlen, OSSL_LIB_CTX *ctx, const char *propq); +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_secretbag(const PKCS12_SAFEBAG *bag, + const char *pass, int passlen, + OSSL_LIB_CTX *ctx, const char *propq); X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass, int passlen, unsigned char *salt, int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8); @@ -300,6 +307,19 @@ DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS) DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES) void PKCS12_PBE_add(void); + +typedef struct pkcs12_parse_ctx_st PKCS12_PARSE_CTX; +PKCS12_PARSE_CTX *PKCS12_PARSE_CTX_new(void); +void PKCS12_PARSE_CTX_free(PKCS12_PARSE_CTX *ctx); +void PKCS12_PARSE_CTX_set_pkey(PKCS12_PARSE_CTX *ctx, EVP_PKEY **pkey); +void PKCS12_PARSE_CTX_set_cert(PKCS12_PARSE_CTX *ctx, X509 **cert); +void PKCS12_PARSE_CTX_set_ca(PKCS12_PARSE_CTX *ctx, STACK_OF(X509) **ca); +void PKCS12_PARSE_CTX_set_skeys(PKCS12_PARSE_CTX *ctx, STACK_OF(EVP_SKEY) **skeys); + +int PKCS12_parse_ex(PKCS12 *p12, const char *pass, + PKCS12_PARSE_CTX *ctx, + OSSL_LIB_CTX *libctx, const char *propq); + int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, STACK_OF(X509) **ca); typedef int PKCS12_create_cb(PKCS12_SAFEBAG *bag, void *cbarg); diff --git a/include/openssl/pkcs12err.h b/include/openssl/pkcs12err.h deleted file mode 100644 index 6e35f335c4d29..0000000000000 --- a/include/openssl/pkcs12err.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_PKCS12ERR_H -#define OPENSSL_PKCS12ERR_H -#pragma once - -#include -#include -#include - -/* - * PKCS12 reason codes. - */ -#define PKCS12_R_CALLBACK_FAILED 115 -#define PKCS12_R_CANT_PACK_STRUCTURE 100 -#define PKCS12_R_CONTENT_TYPE_NOT_DATA 121 -#define PKCS12_R_DECODE_ERROR 101 -#define PKCS12_R_ENCODE_ERROR 102 -#define PKCS12_R_ENCRYPT_ERROR 103 -#define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE 120 -#define PKCS12_R_INVALID_NULL_ARGUMENT 104 -#define PKCS12_R_INVALID_NULL_PKCS12_POINTER 105 -#define PKCS12_R_INVALID_SALT_LENGTH 117 -#define PKCS12_R_INVALID_TYPE 112 -#define PKCS12_R_IV_GEN_ERROR 106 -#define PKCS12_R_KEY_GEN_ERROR 107 -#define PKCS12_R_MAC_ABSENT 108 -#define PKCS12_R_MAC_GENERATION_ERROR 109 -#define PKCS12_R_MAC_SETUP_ERROR 110 -#define PKCS12_R_MAC_STRING_SET_ERROR 111 -#define PKCS12_R_MAC_VERIFY_FAILURE 113 -#define PKCS12_R_PARSE_ERROR 114 -#define PKCS12_R_PKCS12_CIPHERFINAL_ERROR 116 -#define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM 118 -#define PKCS12_R_UNSUPPORTED_PKCS12_MODE 119 - -#endif diff --git a/include/openssl/pkcs7.h.in b/include/openssl/pkcs7.h.in index e922bf6d4a004..c9edcdd7acb04 100644 --- a/include/openssl/pkcs7.h.in +++ b/include/openssl/pkcs7.h.in @@ -91,6 +91,7 @@ typedef struct pkcs7_recip_info_st { typedef struct pkcs7_signed_st { ASN1_INTEGER *version; /* version 1 */ STACK_OF(X509_ALGOR) *md_algs; /* md used */ + /* untrusted certificates for chain building, may include signer certs: */ STACK_OF(X509) *cert; /* [ 0 ] */ /* name should be 'certificates' */ STACK_OF(X509_CRL) *crl; /* [ 1 ] */ /* name should be 'crls' */ STACK_OF(PKCS7_SIGNER_INFO) *signer_info; @@ -118,6 +119,7 @@ typedef struct pkcs7_enveloped_st { typedef struct pkcs7_signedandenveloped_st { ASN1_INTEGER *version; /* version 1 */ STACK_OF(X509_ALGOR) *md_algs; /* md used */ + /* untrusted certificates for chain building, may include signer certs: */ STACK_OF(X509) *cert; /* [ 0 ] */ /* name should be 'certificates' */ STACK_OF(X509_CRL) *crl; /* [ 1 ] */ /* name should be 'crls' */ STACK_OF(PKCS7_SIGNER_INFO) *signer_info; @@ -303,7 +305,9 @@ void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc); int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri); int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509); int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); -int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7); +#if !defined(OPENSSL_NO_DEPRECATED_4_1) +OSSL_DEPRECATEDIN_4_1 int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7); +#endif /* !defined(OPENSSL_NO_DEPRECATED_4_1) */ PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7); diff --git a/include/openssl/pkcs7err.h b/include/openssl/pkcs7err.h deleted file mode 100644 index 358fe1018fb2d..0000000000000 --- a/include/openssl/pkcs7err.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_PKCS7ERR_H -#define OPENSSL_PKCS7ERR_H -#pragma once - -#include -#include -#include - -/* - * PKCS7 reason codes. - */ -#define PKCS7_R_CERTIFICATE_VERIFY_ERROR 117 -#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144 -#define PKCS7_R_CIPHER_NOT_INITIALIZED 116 -#define PKCS7_R_CONTENT_AND_DATA_PRESENT 118 -#define PKCS7_R_CTRL_ERROR 152 -#define PKCS7_R_DECRYPT_ERROR 119 -#define PKCS7_R_DIGEST_FAILURE 101 -#define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149 -#define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150 -#define PKCS7_R_ERROR_ADDING_RECIPIENT 120 -#define PKCS7_R_ERROR_SETTING_CIPHER 121 -#define PKCS7_R_INVALID_NULL_POINTER 143 -#define PKCS7_R_INVALID_SIGNED_DATA_TYPE 155 -#define PKCS7_R_NO_CONTENT 122 -#define PKCS7_R_NO_DEFAULT_DIGEST 151 -#define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154 -#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 -#define PKCS7_R_NO_SIGNATURES_ON_DATA 123 -#define PKCS7_R_NO_SIGNERS 142 -#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 -#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124 -#define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153 -#define PKCS7_R_PKCS7_DATASIGN 145 -#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127 -#define PKCS7_R_SIGNATURE_FAILURE 105 -#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128 -#define PKCS7_R_SIGNING_CTRL_FAILURE 147 -#define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148 -#define PKCS7_R_SMIME_TEXT_ERROR 129 -#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106 -#define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107 -#define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108 -#define PKCS7_R_UNKNOWN_DIGEST_TYPE 109 -#define PKCS7_R_UNKNOWN_OPERATION 110 -#define PKCS7_R_UNSUPPORTED_CIPHER_TYPE 111 -#define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 112 -#define PKCS7_R_WRONG_CONTENT_TYPE 113 -#define PKCS7_R_WRONG_PKCS7_TYPE 114 - -#endif diff --git a/include/openssl/prov_ssl.h b/include/openssl/prov_ssl.h index 269c3b8057378..2d2682b466c35 100644 --- a/include/openssl/prov_ssl.h +++ b/include/openssl/prov_ssl.h @@ -1,5 +1,5 @@ /* - * Copyright 2021-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -27,11 +27,17 @@ extern "C" { #define TLS1_3_VERSION 0x0304 #define DTLS1_VERSION 0xFEFF #define DTLS1_2_VERSION 0xFEFD +#define DTLS1_3_VERSION 0xFEFC #define DTLS1_BAD_VER 0x0100 +#define PROTO_VERSION_UNSET 0 + /* QUIC uses a 4 byte unsigned version number */ #define OSSL_QUIC1_VERSION 0x0000001 +/* Maximum plaintext length: defined by SSL/TLS standards */ +#define SSL3_RT_MAX_PLAIN_LENGTH 16384 + #ifdef __cplusplus } #endif diff --git a/include/openssl/proverr.h b/include/openssl/proverr.h deleted file mode 100644 index 0db3a82b47085..0000000000000 --- a/include/openssl/proverr.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_PROVERR_H -#define OPENSSL_PROVERR_H -#pragma once - -#include -#include -#include - -/* - * PROV reason codes. - */ -#define PROV_R_ADDITIONAL_INPUT_TOO_LONG 184 -#define PROV_R_ALGORITHM_MISMATCH 173 -#define PROV_R_ALREADY_INSTANTIATED 185 -#define PROV_R_BAD_DECRYPT 100 -#define PROV_R_BAD_ENCODING 141 -#define PROV_R_BAD_LENGTH 142 -#define PROV_R_BAD_TLS_CLIENT_VERSION 161 -#define PROV_R_BN_ERROR 160 -#define PROV_R_CIPHER_OPERATION_FAILED 102 -#define PROV_R_COFACTOR_REQUIRED 236 -#define PROV_R_DERIVATION_FUNCTION_INIT_FAILED 205 -#define PROV_R_DIGEST_NOT_ALLOWED 174 -#define PROV_R_EMS_NOT_ENABLED 233 -#define PROV_R_ENTROPY_SOURCE_FAILED_CONTINUOUS_TESTS 244 -#define PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK 186 -#define PROV_R_ERROR_INSTANTIATING_DRBG 188 -#define PROV_R_ERROR_RETRIEVING_ENTROPY 189 -#define PROV_R_ERROR_RETRIEVING_NONCE 190 -#define PROV_R_FAILED_DURING_DERIVATION 164 -#define PROV_R_FAILED_TO_CREATE_LOCK 180 -#define PROV_R_FAILED_TO_DECRYPT 162 -#define PROV_R_FAILED_TO_GENERATE_KEY 121 -#define PROV_R_FAILED_TO_GET_PARAMETER 103 -#define PROV_R_FAILED_TO_SET_PARAMETER 104 -#define PROV_R_FAILED_TO_SIGN 175 -#define PROV_R_FINAL_CALL_OUT_OF_ORDER 237 -#define PROV_R_FIPS_MODULE_CONDITIONAL_ERROR 227 -#define PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE 224 -#define PROV_R_FIPS_MODULE_IMPORT_PCT_ERROR 253 -#define PROV_R_FIPS_MODULE_IN_ERROR_STATE 225 -#define PROV_R_GENERATE_ERROR 191 -#define PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 165 -#define PROV_R_INDICATOR_INTEGRITY_FAILURE 210 -#define PROV_R_INIT_CALL_OUT_OF_ORDER 238 -#define PROV_R_INSUFFICIENT_DRBG_STRENGTH 181 -#define PROV_R_INVALID_AAD 108 -#define PROV_R_INVALID_AEAD 231 -#define PROV_R_INVALID_CIPHER 260 -#define PROV_R_INVALID_CONFIG_DATA 211 -#define PROV_R_INVALID_CONSTANT_LENGTH 157 -#define PROV_R_INVALID_CURVE 176 -#define PROV_R_INVALID_CUSTOM_LENGTH 111 -#define PROV_R_INVALID_DATA 115 -#define PROV_R_INVALID_DIGEST 122 -#define PROV_R_INVALID_DIGEST_LENGTH 166 -#define PROV_R_INVALID_DIGEST_SIZE 218 -#define PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION 243 -#define PROV_R_INVALID_FUNCTION_NAME 258 -#define PROV_R_INVALID_INDEX_LENGTH 259 -#define PROV_R_INVALID_INPUT_LENGTH 230 -#define PROV_R_INVALID_ITERATION_COUNT 123 -#define PROV_R_INVALID_IV_LENGTH 109 -#define PROV_R_INVALID_KDF 232 -#define PROV_R_INVALID_KDR 256 -#define PROV_R_INVALID_KEY 158 -#define PROV_R_INVALID_KEY_LENGTH 105 -#define PROV_R_INVALID_LABEL 257 -#define PROV_R_INVALID_MAC 151 -#define PROV_R_INVALID_MEMORY_SIZE 235 -#define PROV_R_INVALID_MGF1_MD 167 -#define PROV_R_INVALID_MODE 125 -#define PROV_R_INVALID_NONCE_LENGTH 264 -#define PROV_R_INVALID_OUTPUT_LENGTH 217 -#define PROV_R_INVALID_PADDING_MODE 168 -#define PROV_R_INVALID_PARAMETERS_FOR_DKM 261 -#define PROV_R_INVALID_PREHASHED_DIGEST_LENGTH 241 -#define PROV_R_INVALID_PUBINFO 198 -#define PROV_R_INVALID_SALT_LENGTH 112 -#define PROV_R_INVALID_SECRET_LENGTH 265 -#define PROV_R_INVALID_SEED_LENGTH 154 -#define PROV_R_INVALID_SIGNATURE_SIZE 179 -#define PROV_R_INVALID_STATE 212 -#define PROV_R_INVALID_TAG 110 -#define PROV_R_INVALID_TAG_LENGTH 118 -#define PROV_R_INVALID_THREAD_POOL_SIZE 234 -#define PROV_R_INVALID_UKM_LENGTH 200 -#define PROV_R_INVALID_X931_DIGEST 170 -#define PROV_R_IN_ERROR_STATE 192 -#define PROV_R_KEY_IMMUTABLE_ONCE_SET 266 -#define PROV_R_KEY_SETUP_FAILED 101 -#define PROV_R_KEY_SIZE_TOO_SMALL 171 -#define PROV_R_LENGTH_TOO_LARGE 202 -#define PROV_R_MISMATCHING_DOMAIN_PARAMETERS 203 -#define PROV_R_MISSING_CEK_ALG 144 -#define PROV_R_MISSING_CIPHER 155 -#define PROV_R_MISSING_CONFIG_DATA 213 -#define PROV_R_MISSING_CONSTANT 156 -#define PROV_R_MISSING_DKM 262 -#define PROV_R_MISSING_EID 255 -#define PROV_R_MISSING_KEY 128 -#define PROV_R_MISSING_MAC 150 -#define PROV_R_MISSING_MESSAGE_DIGEST 129 -#define PROV_R_MISSING_NONCE 263 -#define PROV_R_MISSING_OID 209 -#define PROV_R_MISSING_PASS 130 -#define PROV_R_MISSING_SALT 131 -#define PROV_R_MISSING_SECRET 132 -#define PROV_R_MISSING_SEED 140 -#define PROV_R_MISSING_SESSION_ID 133 -#define PROV_R_MISSING_TYPE 134 -#define PROV_R_MISSING_XCGHASH 135 -#define PROV_R_ML_DSA_NO_FORMAT 245 -#define PROV_R_ML_KEM_NO_FORMAT 246 -#define PROV_R_MODULE_INTEGRITY_FAILURE 214 -#define PROV_R_NOT_A_PRIVATE_KEY 221 -#define PROV_R_NOT_A_PUBLIC_KEY 220 -#define PROV_R_NOT_INSTANTIATED 193 -#define PROV_R_NOT_PARAMETERS 226 -#define PROV_R_NOT_SUPPORTED 136 -#define PROV_R_NOT_XOF_OR_INVALID_LENGTH 113 -#define PROV_R_NO_INSTANCE_ALLOWED 242 -#define PROV_R_NO_KEY_SET 114 -#define PROV_R_NO_PARAMETERS_SET 177 -#define PROV_R_NULL_LENGTH_POINTER 247 -#define PROV_R_NULL_OUTPUT_BUFFER 248 -#define PROV_R_ONESHOT_CALL_OUT_OF_ORDER 239 -#define PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 178 -#define PROV_R_OUTPUT_BUFFER_TOO_SMALL 106 -#define PROV_R_PARENT_CANNOT_GENERATE_RANDOM_NUMBERS 228 -#define PROV_R_PARENT_CANNOT_SUPPLY_ENTROPY_SEED 187 -#define PROV_R_PARENT_LOCKING_NOT_ENABLED 182 -#define PROV_R_PARENT_STRENGTH_TOO_WEAK 194 -#define PROV_R_PASSWORD_STRENGTH_TOO_WEAK 254 -#define PROV_R_PATH_MUST_BE_ABSOLUTE 219 -#define PROV_R_PERSONALISATION_STRING_TOO_LONG 195 -#define PROV_R_PSS_SALTLEN_TOO_SMALL 172 -#define PROV_R_REPEATED_PARAMETER 252 -#define PROV_R_REQUEST_TOO_LARGE_FOR_DRBG 196 -#define PROV_R_REQUIRE_CTR_MODE_CIPHER 206 -#define PROV_R_RESEED_ERROR 197 -#define PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES 222 -#define PROV_R_SEED_SOURCES_MUST_NOT_HAVE_A_PARENT 229 -#define PROV_R_SELF_TEST_KAT_FAILURE 215 -#define PROV_R_SELF_TEST_POST_FAILURE 216 -#define PROV_R_TAG_NOT_NEEDED 120 -#define PROV_R_TAG_NOT_SET 119 -#define PROV_R_TOO_MANY_RECORDS 126 -#define PROV_R_UNABLE_TO_FIND_CIPHERS 207 -#define PROV_R_UNABLE_TO_GET_PARENT_STRENGTH 199 -#define PROV_R_UNABLE_TO_GET_PASSPHRASE 159 -#define PROV_R_UNABLE_TO_INITIALISE_CIPHERS 208 -#define PROV_R_UNABLE_TO_LOAD_SHA256 147 -#define PROV_R_UNABLE_TO_LOCK_PARENT 201 -#define PROV_R_UNABLE_TO_RESEED 204 -#define PROV_R_UNEXPECTED_KEY_PARAMETERS 249 -#define PROV_R_UNSUPPORTED_CEK_ALG 145 -#define PROV_R_UNSUPPORTED_KEY_SIZE 153 -#define PROV_R_UNSUPPORTED_MAC_TYPE 137 -#define PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS 152 -#define PROV_R_UNSUPPORTED_SELECTION 250 -#define PROV_R_UPDATE_CALL_OUT_OF_ORDER 240 -#define PROV_R_URI_AUTHORITY_UNSUPPORTED 223 -#define PROV_R_VALUE_ERROR 138 -#define PROV_R_WRONG_CIPHERTEXT_SIZE 251 -#define PROV_R_WRONG_FINAL_BLOCK_LENGTH 107 -#define PROV_R_WRONG_OUTPUT_BUFFER_SIZE 139 -#define PROV_R_XOF_DIGESTS_NOT_ALLOWED 183 -#define PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE 148 -#define PROV_R_XTS_DUPLICATED_KEYS 149 - -#endif diff --git a/include/openssl/randerr.h b/include/openssl/randerr.h deleted file mode 100644 index 6107cdd48167d..0000000000000 --- a/include/openssl/randerr.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_RANDERR_H -#define OPENSSL_RANDERR_H -#pragma once - -#include -#include -#include - -/* - * RAND reason codes. - */ -#define RAND_R_ADDITIONAL_INPUT_TOO_LONG 102 -#define RAND_R_ALREADY_INSTANTIATED 103 -#define RAND_R_ARGUMENT_OUT_OF_RANGE 105 -#define RAND_R_CANNOT_OPEN_FILE 121 -#define RAND_R_DRBG_ALREADY_INITIALIZED 129 -#define RAND_R_DRBG_NOT_INITIALISED 104 -#define RAND_R_ENTROPY_INPUT_TOO_LONG 106 -#define RAND_R_ENTROPY_OUT_OF_RANGE 124 -#define RAND_R_ERROR_ENTROPY_POOL_WAS_IGNORED 127 -#define RAND_R_ERROR_INITIALISING_DRBG 107 -#define RAND_R_ERROR_INSTANTIATING_DRBG 108 -#define RAND_R_ERROR_RETRIEVING_ADDITIONAL_INPUT 109 -#define RAND_R_ERROR_RETRIEVING_ENTROPY 110 -#define RAND_R_ERROR_RETRIEVING_NONCE 111 -#define RAND_R_FAILED_TO_CREATE_LOCK 126 -#define RAND_R_FUNC_NOT_IMPLEMENTED 101 -#define RAND_R_FWRITE_ERROR 123 -#define RAND_R_GENERATE_ERROR 112 -#define RAND_R_INSUFFICIENT_DRBG_STRENGTH 139 -#define RAND_R_INTERNAL_ERROR 113 -#define RAND_R_INVALID_PROPERTY_QUERY 137 -#define RAND_R_IN_ERROR_STATE 114 -#define RAND_R_NOT_A_REGULAR_FILE 122 -#define RAND_R_NOT_INSTANTIATED 115 -#define RAND_R_NO_DRBG_IMPLEMENTATION_SELECTED 128 -#define RAND_R_PARENT_LOCKING_NOT_ENABLED 130 -#define RAND_R_PARENT_STRENGTH_TOO_WEAK 131 -#define RAND_R_PERSONALISATION_STRING_TOO_LONG 116 -#define RAND_R_PREDICTION_RESISTANCE_NOT_SUPPORTED 133 -#define RAND_R_PRNG_NOT_SEEDED 100 -#define RAND_R_RANDOM_POOL_IS_EMPTY 142 -#define RAND_R_RANDOM_POOL_OVERFLOW 125 -#define RAND_R_RANDOM_POOL_UNDERFLOW 134 -#define RAND_R_REQUEST_TOO_LARGE_FOR_DRBG 117 -#define RAND_R_RESEED_ERROR 118 -#define RAND_R_SELFTEST_FAILURE 119 -#define RAND_R_TOO_LITTLE_NONCE_REQUESTED 135 -#define RAND_R_TOO_MUCH_NONCE_REQUESTED 136 -#define RAND_R_UNABLE_TO_CREATE_DRBG 143 -#define RAND_R_UNABLE_TO_FETCH_DRBG 144 -#define RAND_R_UNABLE_TO_GET_PARENT_RESEED_PROP_COUNTER 141 -#define RAND_R_UNABLE_TO_GET_PARENT_STRENGTH 138 -#define RAND_R_UNABLE_TO_LOCK_PARENT 140 -#define RAND_R_UNSUPPORTED_DRBG_FLAGS 132 -#define RAND_R_UNSUPPORTED_DRBG_TYPE 120 - -#endif diff --git a/include/openssl/rsaerr.h b/include/openssl/rsaerr.h deleted file mode 100644 index 781e333132693..0000000000000 --- a/include/openssl/rsaerr.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_RSAERR_H -#define OPENSSL_RSAERR_H -#pragma once - -#include -#include -#include - -/* - * RSA reason codes. - */ -#define RSA_R_ALGORITHM_MISMATCH 100 -#define RSA_R_BAD_E_VALUE 101 -#define RSA_R_BAD_FIXED_HEADER_DECRYPT 102 -#define RSA_R_BAD_PAD_BYTE_COUNT 103 -#define RSA_R_BAD_SIGNATURE 104 -#define RSA_R_BLOCK_TYPE_IS_NOT_01 106 -#define RSA_R_BLOCK_TYPE_IS_NOT_02 107 -#define RSA_R_DATA_GREATER_THAN_MOD_LEN 108 -#define RSA_R_DATA_TOO_LARGE 109 -#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 110 -#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 132 -#define RSA_R_DATA_TOO_SMALL 111 -#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 122 -#define RSA_R_DIGEST_DOES_NOT_MATCH 158 -#define RSA_R_DIGEST_NOT_ALLOWED 145 -#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 112 -#define RSA_R_DMP1_NOT_CONGRUENT_TO_D 124 -#define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125 -#define RSA_R_D_E_NOT_CONGRUENT_TO_1 123 -#define RSA_R_FIRST_OCTET_INVALID 133 -#define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 144 -#define RSA_R_INVALID_DIGEST 157 -#define RSA_R_INVALID_DIGEST_LENGTH 143 -#define RSA_R_INVALID_HEADER 137 -#define RSA_R_INVALID_KEYPAIR 171 -#define RSA_R_INVALID_KEY_LENGTH 173 -#define RSA_R_INVALID_LABEL 160 -#define RSA_R_INVALID_LENGTH 181 -#define RSA_R_INVALID_MESSAGE_LENGTH 131 -#define RSA_R_INVALID_MGF1_MD 156 -#define RSA_R_INVALID_MODULUS 174 -#define RSA_R_INVALID_MULTI_PRIME_KEY 167 -#define RSA_R_INVALID_OAEP_PARAMETERS 161 -#define RSA_R_INVALID_PADDING 138 -#define RSA_R_INVALID_PADDING_MODE 141 -#define RSA_R_INVALID_PSS_PARAMETERS 149 -#define RSA_R_INVALID_PSS_SALTLEN 146 -#define RSA_R_INVALID_REQUEST 175 -#define RSA_R_INVALID_SALT_LENGTH 150 -#define RSA_R_INVALID_STRENGTH 176 -#define RSA_R_INVALID_TRAILER 139 -#define RSA_R_INVALID_X931_DIGEST 142 -#define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 -#define RSA_R_KEY_PRIME_NUM_INVALID 165 -#define RSA_R_KEY_SIZE_TOO_SMALL 120 -#define RSA_R_LAST_OCTET_INVALID 134 -#define RSA_R_MGF1_DIGEST_NOT_ALLOWED 152 -#define RSA_R_MISSING_PRIVATE_KEY 179 -#define RSA_R_MODULUS_TOO_LARGE 105 -#define RSA_R_MP_COEFFICIENT_NOT_INVERSE_OF_R 168 -#define RSA_R_MP_EXPONENT_NOT_CONGRUENT_TO_D 169 -#define RSA_R_MP_R_NOT_PRIME 170 -#define RSA_R_NO_PUBLIC_EXPONENT 140 -#define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 -#define RSA_R_N_DOES_NOT_EQUAL_PRODUCT_OF_PRIMES 172 -#define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 -#define RSA_R_OAEP_DECODING_ERROR 121 -#define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 -#define RSA_R_PADDING_CHECK_FAILED 114 -#define RSA_R_PAIRWISE_TEST_FAILURE 177 -#define RSA_R_PKCS_DECODING_ERROR 159 -#define RSA_R_PSS_SALTLEN_TOO_SMALL 164 -#define RSA_R_PUB_EXPONENT_OUT_OF_RANGE 178 -#define RSA_R_P_NOT_PRIME 128 -#define RSA_R_Q_NOT_PRIME 129 -#define RSA_R_RANDOMNESS_SOURCE_STRENGTH_INSUFFICIENT 180 -#define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED 130 -#define RSA_R_SLEN_CHECK_FAILED 136 -#define RSA_R_SLEN_RECOVERY_FAILED 135 -#define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116 -#define RSA_R_UNKNOWN_ALGORITHM_TYPE 117 -#define RSA_R_UNKNOWN_DIGEST 166 -#define RSA_R_UNKNOWN_MASK_DIGEST 151 -#define RSA_R_UNKNOWN_PADDING_TYPE 118 -#define RSA_R_UNSUPPORTED_ENCRYPTION_TYPE 162 -#define RSA_R_UNSUPPORTED_LABEL_SOURCE 163 -#define RSA_R_UNSUPPORTED_MASK_ALGORITHM 153 -#define RSA_R_UNSUPPORTED_MASK_PARAMETER 154 -#define RSA_R_UNSUPPORTED_SIGNATURE_TYPE 155 -#define RSA_R_VALUE_MISSING 147 -#define RSA_R_WRONG_SIGNATURE_LENGTH 119 - -#endif diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in index b010a6e67747d..bdf5d201c95d7 100644 --- a/include/openssl/ssl.h.in +++ b/include/openssl/ssl.h.in @@ -338,7 +338,7 @@ typedef int (*SSL_async_callback_fn)(SSL *s, void *arg); #define SSL_OP_LEGACY_SERVER_CONNECT SSL_OP_BIT(2) /* Enable support for Kernel TLS */ #define SSL_OP_ENABLE_KTLS SSL_OP_BIT(3) -#define SSL_OP_TLSEXT_PADDING SSL_OP_BIT(4) +/* SSL_OP_BIT(4) was SSL_OP_TLSEXT_PADDING, now a no-op */ #define SSL_OP_SAFARI_ECDHE_ECDSA_BUG SSL_OP_BIT(6) #define SSL_OP_IGNORE_UNEXPECTED_EOF SSL_OP_BIT(7) #define SSL_OP_ALLOW_CLIENT_RENEGOTIATION SSL_OP_BIT(8) @@ -410,6 +410,7 @@ typedef int (*SSL_async_callback_fn)(SSL *s, void *arg); #define SSL_OP_NO_TLSv1_3 SSL_OP_BIT(29) #define SSL_OP_NO_DTLSv1 SSL_OP_BIT(26) #define SSL_OP_NO_DTLSv1_2 SSL_OP_BIT(27) +#define SSL_OP_NO_DTLSv1_3 SSL_OP_BIT(29) /* Disallow all renegotiation */ #define SSL_OP_NO_RENEGOTIATION SSL_OP_BIT(30) /* @@ -468,7 +469,7 @@ typedef int (*SSL_async_callback_fn)(SSL *s, void *arg); /* Various bug workarounds that should be rather harmless. */ #define SSL_OP_ALL \ (SSL_OP_CRYPTOPRO_TLSEXT_BUG | SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS \ - | SSL_OP_TLSEXT_PADDING | SSL_OP_SAFARI_ECDHE_ECDSA_BUG) + | SSL_OP_SAFARI_ECDHE_ECDSA_BUG) /* * OBSOLETE OPTIONS retained for compatibility @@ -491,6 +492,7 @@ typedef int (*SSL_async_callback_fn)(SSL *s, void *arg); #define SSL_OP_PKCS1_CHECK_2 0x0 #define SSL_OP_NETSCAPE_CA_DN_BUG 0x0 #define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x0 +#define SSL_OP_TLSEXT_PADDING 0x0 /* * Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success @@ -1095,7 +1097,11 @@ typedef enum { TLS_ST_EARLY_DATA, TLS_ST_PENDING_EARLY_DATA_END, TLS_ST_CW_END_OF_EARLY_DATA, - TLS_ST_SR_END_OF_EARLY_DATA + TLS_ST_SR_END_OF_EARLY_DATA, + TLS_ST_CR_ACK, + TLS_ST_CW_ACK, + TLS_ST_SR_ACK, + TLS_ST_SW_ACK } OSSL_HANDSHAKE_STATE; /* @@ -2315,6 +2321,8 @@ __owur int SSL_is_connection(SSL *s); __owur int SSL_is_listener(SSL *ssl); __owur SSL *SSL_get0_listener(SSL *s); #define SSL_LISTENER_FLAG_NO_VALIDATE (1UL << 1) +#define SSL_LISTENER_FLAG_ADDRESS_VALIDATION (1UL << 2) +#define SSL_LISTENER_FLAG_SINGLE_THREAD (1UL << 3) __owur SSL *SSL_new_listener(SSL_CTX *ctx, uint64_t flags); __owur SSL *SSL_new_listener_from(SSL *ssl, uint64_t flags); __owur SSL *SSL_new_from_listener(SSL *ssl, uint64_t flags); @@ -2446,6 +2454,11 @@ __owur int SSL_get_conn_close_info(SSL *ssl, #define SSL_VALUE_QUIC_WINDOWUSTR 13 #define SSL_VALUE_QUIC_ACK_DELAY_EXPONENT 14 #define SSL_VALUE_QUIC_ACK_DELAY_MAX 15 +#define SSL_VALUE_QUIC_MAX_PENDING_CONNS 16 + +#define SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS 17 +#define SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT 18 +#define SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE 19 #define SSL_VALUE_EVENT_HANDLING_MODE_INHERIT 0 #define SSL_VALUE_EVENT_HANDLING_MODE_IMPLICIT 1 diff --git a/include/openssl/ssl3.h b/include/openssl/ssl3.h index f35b6eadb0f7b..b588fe1259c1a 100644 --- a/include/openssl/ssl3.h +++ b/include/openssl/ssl3.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -173,8 +173,6 @@ extern "C" { #define SSL3_RT_MAX_EXTRA (16384) -/* Maximum plaintext length: defined by SSL/TLS standards */ -#define SSL3_RT_MAX_PLAIN_LENGTH 16384 /* Maximum compression overhead: defined by SSL/TLS standards */ #define SSL3_RT_MAX_COMPRESSED_OVERHEAD 1024 @@ -220,6 +218,7 @@ extern "C" { #define SSL3_RT_ALERT 21 #define SSL3_RT_HANDSHAKE 22 #define SSL3_RT_APPLICATION_DATA 23 +#define SSL3_RT_ACK 26 /* RFC 9147 */ /* Pseudo content types to indicate additional parameters */ #define TLS1_RT_CRYPTO 0x1000 @@ -333,6 +332,9 @@ extern "C" { #define SSL3_MT_MESSAGE_HASH 254 #define DTLS1_MT_HELLO_VERIFY_REQUEST 3 +/* Dummy message type for handling ACK like a normal handshake message */ +#define DTLS13_MT_ACK 0x0126 + /* Dummy message type for handling CCS like a normal handshake message */ #define SSL3_MT_CHANGE_CIPHER_SPEC 0x0101 @@ -346,6 +348,7 @@ extern "C" { #define SSL3_CC_EARLY 0x040 #define SSL3_CC_HANDSHAKE 0x080 #define SSL3_CC_APPLICATION 0x100 +#define SSL3_CC_COMP_CERT 0x200 #define SSL3_CHANGE_CIPHER_CLIENT_WRITE (SSL3_CC_CLIENT | SSL3_CC_WRITE) #define SSL3_CHANGE_CIPHER_SERVER_READ (SSL3_CC_SERVER | SSL3_CC_READ) #define SSL3_CHANGE_CIPHER_CLIENT_READ (SSL3_CC_CLIENT | SSL3_CC_READ) diff --git a/include/openssl/sslerr.h b/include/openssl/sslerr.h deleted file mode 100644 index 28e38861696f3..0000000000000 --- a/include/openssl/sslerr.h +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_SSLERR_H -#define OPENSSL_SSLERR_H -#pragma once - -#include -#include -#include - -/* - * SSL reason codes. - */ -#define SSL_R_APPLICATION_DATA_AFTER_CLOSE_NOTIFY 291 -#define SSL_R_APP_DATA_IN_HANDSHAKE 100 -#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 -#define SSL_R_AT_LEAST_TLS_1_2_NEEDED_IN_SUITEB_MODE 158 -#define SSL_R_BAD_CERTIFICATE 348 -#define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 -#define SSL_R_BAD_CIPHER 186 -#define SSL_R_BAD_COMPRESSION_ALGORITHM 326 -#define SSL_R_BAD_DATA 390 -#define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 106 -#define SSL_R_BAD_DECOMPRESSION 107 -#define SSL_R_BAD_DH_VALUE 102 -#define SSL_R_BAD_DIGEST_LENGTH 111 -#define SSL_R_BAD_EARLY_DATA 233 -#define SSL_R_BAD_ECC_CERT 304 -#define SSL_R_BAD_ECHCONFIG_EXTENSION 425 -#define SSL_R_BAD_ECPOINT 306 -#define SSL_R_BAD_EXTENSION 110 -#define SSL_R_BAD_HANDSHAKE_LENGTH 332 -#define SSL_R_BAD_HANDSHAKE_STATE 236 -#define SSL_R_BAD_HELLO_REQUEST 105 -#define SSL_R_BAD_HRR_VERSION 263 -#define SSL_R_BAD_KEY_SHARE 108 -#define SSL_R_BAD_KEY_UPDATE 122 -#define SSL_R_BAD_LEGACY_VERSION 292 -#define SSL_R_BAD_LENGTH 271 -#define SSL_R_BAD_PACKET 240 -#define SSL_R_BAD_PACKET_LENGTH 115 -#define SSL_R_BAD_PROTOCOL_VERSION_NUMBER 116 -#define SSL_R_BAD_PSK 219 -#define SSL_R_BAD_PSK_IDENTITY 114 -#define SSL_R_BAD_RECORD_TYPE 443 -#define SSL_R_BAD_RSA_ENCRYPT 119 -#define SSL_R_BAD_SIGNATURE 123 -#define SSL_R_BAD_SRP_A_LENGTH 347 -#define SSL_R_BAD_SRP_PARAMETERS 371 -#define SSL_R_BAD_SRTP_MKI_VALUE 352 -#define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 353 -#define SSL_R_BAD_SSL_FILETYPE 124 -#define SSL_R_BAD_VALUE 384 -#define SSL_R_BAD_WRITE_RETRY 127 -#define SSL_R_BINDER_DOES_NOT_VERIFY 253 -#define SSL_R_BIO_NOT_SET 128 -#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129 -#define SSL_R_BN_LIB 130 -#define SSL_R_CALLBACK_FAILED 234 -#define SSL_R_CANNOT_CHANGE_CIPHER 109 -#define SSL_R_CANNOT_GET_GROUP_NAME 299 -#define SSL_R_CA_DN_LENGTH_MISMATCH 131 -#define SSL_R_CA_KEY_TOO_SMALL 397 -#define SSL_R_CA_MD_TOO_WEAK 398 -#define SSL_R_CCS_RECEIVED_EARLY 133 -#define SSL_R_CERTIFICATE_VERIFY_FAILED 134 -#define SSL_R_CERT_CB_ERROR 377 -#define SSL_R_CERT_LENGTH_MISMATCH 135 -#define SSL_R_CIPHERSUITE_DIGEST_HAS_CHANGED 218 -#define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 -#define SSL_R_CLIENTHELLO_TLSEXT 226 -#define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 -#define SSL_R_COMPRESSION_DISABLED 343 -#define SSL_R_COMPRESSION_FAILURE 141 -#define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE 307 -#define SSL_R_COMPRESSION_LIBRARY_ERROR 142 -#define SSL_R_CONNECTION_TYPE_NOT_SET 144 -#define SSL_R_CONN_USE_ONLY 356 -#define SSL_R_CONTEXT_NOT_DANE_ENABLED 167 -#define SSL_R_COOKIE_GEN_CALLBACK_FAILURE 400 -#define SSL_R_COOKIE_MISMATCH 308 -#define SSL_R_COPY_PARAMETERS_FAILED 296 -#define SSL_R_CUSTOM_EXT_HANDLER_ALREADY_INSTALLED 206 -#define SSL_R_DANE_ALREADY_ENABLED 172 -#define SSL_R_DANE_CANNOT_OVERRIDE_MTYPE_FULL 173 -#define SSL_R_DANE_NOT_ENABLED 175 -#define SSL_R_DANE_TLSA_BAD_CERTIFICATE 180 -#define SSL_R_DANE_TLSA_BAD_CERTIFICATE_USAGE 184 -#define SSL_R_DANE_TLSA_BAD_DATA_LENGTH 189 -#define SSL_R_DANE_TLSA_BAD_DIGEST_LENGTH 192 -#define SSL_R_DANE_TLSA_BAD_MATCHING_TYPE 200 -#define SSL_R_DANE_TLSA_BAD_PUBLIC_KEY 201 -#define SSL_R_DANE_TLSA_BAD_SELECTOR 202 -#define SSL_R_DANE_TLSA_NULL_DATA 203 -#define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145 -#define SSL_R_DATA_LENGTH_TOO_LONG 146 -#define SSL_R_DECRYPTION_FAILED 147 -#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281 -#define SSL_R_DH_KEY_TOO_SMALL 394 -#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 -#define SSL_R_DIGEST_CHECK_FAILED 149 -#define SSL_R_DOMAIN_USE_ONLY 422 -#define SSL_R_DTLS_MESSAGE_TOO_BIG 334 -#define SSL_R_DUPLICATE_COMPRESSION_ID 309 -#define SSL_R_ECC_CERT_NOT_FOR_SIGNING 318 -#define SSL_R_ECDH_REQUIRED_FOR_SUITEB_MODE 374 -#define SSL_R_ECH_DECODE_ERROR 426 -#define SSL_R_ECH_REQUIRED 424 -#define SSL_R_EE_KEY_TOO_SMALL 399 -#define SSL_R_EMPTY_RAW_PUBLIC_KEY 349 -#define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 354 -#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150 -#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151 -#define SSL_R_ERROR_IN_SYSTEM_DEFAULT_CONFIG 419 -#define SSL_R_ERROR_SETTING_TLSA_BASE_DOMAIN 204 -#define SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE 194 -#define SSL_R_EXCESSIVE_MESSAGE_SIZE 152 -#define SSL_R_EXTENSION_NOT_RECEIVED 279 -#define SSL_R_EXTRA_DATA_IN_MESSAGE 153 -#define SSL_R_EXT_LENGTH_MISMATCH 163 -#define SSL_R_FAILED_TO_GET_PARAMETER 316 -#define SSL_R_FAILED_TO_INIT_ASYNC 405 -#define SSL_R_FEATURE_NEGOTIATION_NOT_COMPLETE 417 -#define SSL_R_FEATURE_NOT_RENEGOTIABLE 413 -#define SSL_R_FRAGMENTED_CLIENT_HELLO 401 -#define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 -#define SSL_R_HTTPS_PROXY_REQUEST 155 -#define SSL_R_HTTP_REQUEST 156 -#define SSL_R_ILLEGAL_POINT_COMPRESSION 162 -#define SSL_R_ILLEGAL_SUITEB_DIGEST 380 -#define SSL_R_INAPPROPRIATE_FALLBACK 373 -#define SSL_R_INCONSISTENT_COMPRESSION 340 -#define SSL_R_INCONSISTENT_EARLY_DATA_ALPN 222 -#define SSL_R_INCONSISTENT_EARLY_DATA_SNI 231 -#define SSL_R_INCONSISTENT_EXTMS 104 -#define SSL_R_INSUFFICIENT_SECURITY 241 -#define SSL_R_INVALID_ALERT 205 -#define SSL_R_INVALID_CCS_MESSAGE 260 -#define SSL_R_INVALID_CERTIFICATE_OR_ALG 238 -#define SSL_R_INVALID_COMMAND 280 -#define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 -#define SSL_R_INVALID_CONFIG 283 -#define SSL_R_INVALID_CONFIGURATION_NAME 113 -#define SSL_R_INVALID_CONTEXT 282 -#define SSL_R_INVALID_CT_VALIDATION_TYPE 212 -#define SSL_R_INVALID_KEY_UPDATE_TYPE 120 -#define SSL_R_INVALID_MAX_EARLY_DATA 174 -#define SSL_R_INVALID_NULL_CMD_NAME 385 -#define SSL_R_INVALID_RAW_PUBLIC_KEY 350 -#define SSL_R_INVALID_RECORD 317 -#define SSL_R_INVALID_SEQUENCE_NUMBER 402 -#define SSL_R_INVALID_SERVERINFO_DATA 388 -#define SSL_R_INVALID_SESSION_ID 999 -#define SSL_R_INVALID_SRP_USERNAME 357 -#define SSL_R_INVALID_STATUS_RESPONSE 328 -#define SSL_R_INVALID_TICKET_KEYS_LENGTH 325 -#define SSL_R_LEGACY_SIGALG_DISALLOWED_OR_UNSUPPORTED 333 -#define SSL_R_LENGTH_MISMATCH 159 -#define SSL_R_LENGTH_TOO_LONG 404 -#define SSL_R_LENGTH_TOO_SHORT 160 -#define SSL_R_LIBRARY_BUG 274 -#define SSL_R_LIBRARY_HAS_NO_CIPHERS 161 -#define SSL_R_LISTENER_USE_ONLY 421 -#define SSL_R_MAXIMUM_ENCRYPTED_PKTS_REACHED 395 -#define SSL_R_MISSING_DSA_SIGNING_CERT 165 -#define SSL_R_MISSING_ECDSA_SIGNING_CERT 381 -#define SSL_R_MISSING_FATAL 256 -#define SSL_R_MISSING_PARAMETERS 290 -#define SSL_R_MISSING_PSK_KEX_MODES_EXTENSION 310 -#define SSL_R_MISSING_QUIC_TLS_FUNCTIONS 423 -#define SSL_R_MISSING_RSA_CERTIFICATE 168 -#define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169 -#define SSL_R_MISSING_RSA_SIGNING_CERT 170 -#define SSL_R_MISSING_SIGALGS_EXTENSION 112 -#define SSL_R_MISSING_SIGNING_CERT 221 -#define SSL_R_MISSING_SRP_PARAM 358 -#define SSL_R_MISSING_SUPPORTED_GROUPS_EXTENSION 209 -#define SSL_R_MISSING_SUPPORTED_VERSIONS_EXTENSION 420 -#define SSL_R_MISSING_TMP_DH_KEY 171 -#define SSL_R_MISSING_TMP_ECDH_KEY 311 -#define SSL_R_MIXED_HANDSHAKE_AND_NON_HANDSHAKE_DATA 293 -#define SSL_R_NOT_ON_RECORD_BOUNDARY 182 -#define SSL_R_NOT_REPLACING_CERTIFICATE 289 -#define SSL_R_NOT_SERVER 284 -#define SSL_R_NO_APPLICATION_PROTOCOL 235 -#define SSL_R_NO_CERTIFICATES_RETURNED 176 -#define SSL_R_NO_CERTIFICATE_ASSIGNED 177 -#define SSL_R_NO_CERTIFICATE_SET 179 -#define SSL_R_NO_CHANGE_FOLLOWING_HRR 214 -#define SSL_R_NO_CIPHERS_AVAILABLE 181 -#define SSL_R_NO_CIPHERS_SPECIFIED 183 -#define SSL_R_NO_CIPHER_MATCH 185 -#define SSL_R_NO_CLIENT_CERT_METHOD 331 -#define SSL_R_NO_COMPRESSION_SPECIFIED 187 -#define SSL_R_NO_COOKIE_CALLBACK_SET 287 -#define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER 330 -#define SSL_R_NO_METHOD_SPECIFIED 188 -#define SSL_R_NO_PEM_EXTENSIONS 389 -#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190 -#define SSL_R_NO_PROTOCOLS_AVAILABLE 191 -#define SSL_R_NO_RENEGOTIATION 339 -#define SSL_R_NO_REQUIRED_DIGEST 324 -#define SSL_R_NO_SHARED_CIPHER 193 -#define SSL_R_NO_SHARED_GROUPS 410 -#define SSL_R_NO_SHARED_SIGNATURE_ALGORITHMS 376 -#define SSL_R_NO_SRTP_PROFILES 359 -#define SSL_R_NO_STREAM 355 -#define SSL_R_NO_SUITABLE_DIGEST_ALGORITHM 297 -#define SSL_R_NO_SUITABLE_GROUPS 295 -#define SSL_R_NO_SUITABLE_KEY_SHARE 101 -#define SSL_R_NO_SUITABLE_RECORD_LAYER 322 -#define SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM 118 -#define SSL_R_NO_VALID_SCTS 216 -#define SSL_R_NO_VERIFY_COOKIE_CALLBACK 403 -#define SSL_R_NULL_SSL_CTX 195 -#define SSL_R_NULL_SSL_METHOD_PASSED 196 -#define SSL_R_OCSP_CALLBACK_FAILURE 305 -#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197 -#define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344 -#define SSL_R_OVERFLOW_ERROR 237 -#define SSL_R_PACKET_LENGTH_TOO_LONG 198 -#define SSL_R_PARSE_TLSEXT 227 -#define SSL_R_PATH_TOO_LONG 270 -#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199 -#define SSL_R_PEM_NAME_BAD_PREFIX 391 -#define SSL_R_PEM_NAME_TOO_SHORT 392 -#define SSL_R_PIPELINE_FAILURE 406 -#define SSL_R_POLL_REQUEST_NOT_SUPPORTED 418 -#define SSL_R_POST_HANDSHAKE_AUTH_ENCODING_ERR 278 -#define SSL_R_PRIVATE_KEY_MISMATCH 288 -#define SSL_R_PROTOCOL_IS_SHUTDOWN 207 -#define SSL_R_PSK_IDENTITY_NOT_FOUND 223 -#define SSL_R_PSK_NO_CLIENT_CB 224 -#define SSL_R_PSK_NO_SERVER_CB 225 -#define SSL_R_QUIC_HANDSHAKE_LAYER_ERROR 393 -#define SSL_R_QUIC_NETWORK_ERROR 387 -#define SSL_R_QUIC_PROTOCOL_ERROR 382 -#define SSL_R_READ_BIO_NOT_SET 211 -#define SSL_R_READ_TIMEOUT_EXPIRED 312 -#define SSL_R_RECORDS_NOT_RELEASED 321 -#define SSL_R_RECORD_LAYER_FAILURE 313 -#define SSL_R_RECORD_LENGTH_MISMATCH 213 -#define SSL_R_RECORD_TOO_SMALL 298 -#define SSL_R_REMOTE_PEER_ADDRESS_NOT_SET 346 -#define SSL_R_RENEGOTIATE_EXT_TOO_LONG 335 -#define SSL_R_RENEGOTIATION_ENCODING_ERR 336 -#define SSL_R_RENEGOTIATION_MISMATCH 337 -#define SSL_R_REQUEST_PENDING 285 -#define SSL_R_REQUEST_SENT 286 -#define SSL_R_REQUIRED_CIPHER_MISSING 215 -#define SSL_R_REQUIRED_COMPRESSION_ALGORITHM_MISSING 342 -#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 -#define SSL_R_SCT_VERIFICATION_FAILED 208 -#define SSL_R_SEQUENCE_CTR_WRAPPED 327 -#define SSL_R_SERVERHELLO_TLSEXT 275 -#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 -#define SSL_R_SHUTDOWN_WHILE_IN_INIT 407 -#define SSL_R_SIGNATURE_ALGORITHMS_ERROR 360 -#define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 -#define SSL_R_SRP_A_CALC 361 -#define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 362 -#define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG 363 -#define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 364 -#define SSL_R_TLS_EXT_INVALID_MAX_FRAGMENT_LENGTH 232 -#define SSL_R_TLS_EXT_INVALID_SERVERNAME 319 -#define SSL_R_TLS_EXT_INVALID_SERVERNAME_TYPE 320 -#define SSL_R_TLS_SESSION_ID_TOO_LONG 300 -#define SSL_R_TLS_ALERT_BAD_CERTIFICATE 1042 -#define SSL_R_TLS_ALERT_BAD_RECORD_MAC 1020 -#define SSL_R_TLS_ALERT_CERTIFICATE_EXPIRED 1045 -#define SSL_R_TLS_ALERT_CERTIFICATE_REVOKED 1044 -#define SSL_R_TLS_ALERT_CERTIFICATE_UNKNOWN 1046 -#define SSL_R_TLS_ALERT_DECOMPRESSION_FAILURE 1030 -#define SSL_R_TLS_ALERT_HANDSHAKE_FAILURE 1040 -#define SSL_R_TLS_ALERT_ILLEGAL_PARAMETER 1047 -#define SSL_R_TLS_ALERT_NO_CERTIFICATE 1041 -#define SSL_R_TLS_ALERT_UNEXPECTED_MESSAGE 1010 -#define SSL_R_TLS_ALERT_UNSUPPORTED_CERTIFICATE 1043 -#define SSL_R_SSL_COMMAND_SECTION_EMPTY 117 -#define SSL_R_SSL_COMMAND_SECTION_NOT_FOUND 125 -#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 228 -#define SSL_R_SSL_HANDSHAKE_FAILURE 229 -#define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS 230 -#define SSL_R_SSL_NEGATIVE_LENGTH 372 -#define SSL_R_SSL_SECTION_EMPTY 126 -#define SSL_R_SSL_SECTION_NOT_FOUND 136 -#define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED 301 -#define SSL_R_SSL_SESSION_ID_CONFLICT 302 -#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 273 -#define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH 303 -#define SSL_R_SSL_SESSION_ID_TOO_LONG 408 -#define SSL_R_SSL_SESSION_VERSION_MISMATCH 210 -#define SSL_R_STILL_IN_INIT 121 -#define SSL_R_STREAM_COUNT_LIMITED 411 -#define SSL_R_STREAM_FINISHED 365 -#define SSL_R_STREAM_RECV_ONLY 366 -#define SSL_R_STREAM_RESET 375 -#define SSL_R_STREAM_SEND_ONLY 379 -#define SSL_R_TLSV13_ALERT_CERTIFICATE_REQUIRED 1116 -#define SSL_R_TLSV13_ALERT_MISSING_EXTENSION 1109 -#define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 -#define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 -#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 -#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 -#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 -#define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 -#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 -#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 -#define SSL_R_TLSV1_ALERT_NO_APPLICATION_PROTOCOL 1120 -#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 -#define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 -#define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 -#define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 -#define SSL_R_TLSV1_ALERT_UNKNOWN_PSK_IDENTITY 1115 -#define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 -#define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 -#define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 -#define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 -#define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 -#define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 -#define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 367 -#define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157 -#define SSL_R_TOO_MANY_KEY_UPDATES 132 -#define SSL_R_TOO_MANY_WARN_ALERTS 409 -#define SSL_R_TOO_MUCH_EARLY_DATA 164 -#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 314 -#define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239 -#define SSL_R_UNEXPECTED_CCS_MESSAGE 262 -#define SSL_R_UNEXPECTED_END_OF_EARLY_DATA 178 -#define SSL_R_UNEXPECTED_EOF_WHILE_READING 294 -#define SSL_R_UNEXPECTED_MESSAGE 244 -#define SSL_R_UNEXPECTED_RECORD 245 -#define SSL_R_UNINITIALIZED 276 -#define SSL_R_UNKNOWN_ALERT_TYPE 246 -#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247 -#define SSL_R_UNKNOWN_CIPHER_RETURNED 248 -#define SSL_R_UNKNOWN_CIPHER_TYPE 249 -#define SSL_R_UNKNOWN_CMD_NAME 386 -#define SSL_R_UNKNOWN_COMMAND 139 -#define SSL_R_UNKNOWN_DIGEST 368 -#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250 -#define SSL_R_UNKNOWN_MANDATORY_PARAMETER 323 -#define SSL_R_UNKNOWN_PKEY_TYPE 251 -#define SSL_R_UNKNOWN_PROTOCOL 252 -#define SSL_R_UNKNOWN_SSL_VERSION 254 -#define SSL_R_UNKNOWN_STATE 255 -#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 338 -#define SSL_R_UNSOLICITED_EXTENSION 217 -#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 -#define SSL_R_UNSUPPORTED_CONFIG_VALUE 414 -#define SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS 415 -#define SSL_R_UNSUPPORTED_CONFIG_VALUE_OP 416 -#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315 -#define SSL_R_UNSUPPORTED_PROTOCOL 258 -#define SSL_R_UNSUPPORTED_SSL_VERSION 259 -#define SSL_R_UNSUPPORTED_STATUS_TYPE 329 -#define SSL_R_UNSUPPORTED_WRITE_FLAG 412 -#define SSL_R_USE_SRTP_NOT_NEGOTIATED 369 -#define SSL_R_VERSION_TOO_HIGH 166 -#define SSL_R_VERSION_TOO_LOW 396 -#define SSL_R_WRONG_CERTIFICATE_TYPE 383 -#define SSL_R_WRONG_CIPHER_RETURNED 261 -#define SSL_R_WRONG_CURVE 378 -#define SSL_R_WRONG_RPK_TYPE 351 -#define SSL_R_WRONG_SIGNATURE_LENGTH 264 -#define SSL_R_WRONG_SIGNATURE_SIZE 265 -#define SSL_R_WRONG_SIGNATURE_TYPE 370 -#define SSL_R_WRONG_SSL_VERSION 266 -#define SSL_R_WRONG_VERSION_NUMBER 267 -#define SSL_R_X509_LIB 268 -#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 269 - -#endif diff --git a/include/openssl/storeerr.h b/include/openssl/storeerr.h deleted file mode 100644 index fb58f0630e7c9..0000000000000 --- a/include/openssl/storeerr.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_STOREERR_H -#define OPENSSL_STOREERR_H -#pragma once - -#include -#include -#include - -/* - * OSSL_STORE reason codes. - */ -#define OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE 107 -#define OSSL_STORE_R_BAD_PASSWORD_READ 115 -#define OSSL_STORE_R_ERROR_VERIFYING_PKCS12_MAC 113 -#define OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST 121 -#define OSSL_STORE_R_INVALID_SCHEME 106 -#define OSSL_STORE_R_IS_NOT_A 112 -#define OSSL_STORE_R_LOADER_INCOMPLETE 116 -#define OSSL_STORE_R_LOADING_STARTED 117 -#define OSSL_STORE_R_NOT_A_CERTIFICATE 100 -#define OSSL_STORE_R_NOT_A_CRL 101 -#define OSSL_STORE_R_NOT_A_NAME 103 -#define OSSL_STORE_R_NOT_A_PRIVATE_KEY 102 -#define OSSL_STORE_R_NOT_A_PUBLIC_KEY 122 -#define OSSL_STORE_R_NOT_A_SYMMETRIC_KEY 124 -#define OSSL_STORE_R_NOT_PARAMETERS 104 -#define OSSL_STORE_R_NO_LOADERS_FOUND 123 -#define OSSL_STORE_R_PASSPHRASE_CALLBACK_ERROR 114 -#define OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE 108 -#define OSSL_STORE_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES 119 -#define OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED 109 -#define OSSL_STORE_R_UNREGISTERED_SCHEME 105 -#define OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE 110 -#define OSSL_STORE_R_UNSUPPORTED_OPERATION 118 -#define OSSL_STORE_R_UNSUPPORTED_SEARCH_TYPE 120 -#define OSSL_STORE_R_URI_AUTHORITY_UNSUPPORTED 111 - -#endif diff --git a/include/openssl/ts.h b/include/openssl/ts.h index 93c7dce4b6ebf..ac6b988041e8f 100644 --- a/include/openssl/ts.h +++ b/include/openssl/ts.h @@ -418,19 +418,19 @@ void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx); int TS_VERIFY_CTX_set_flags(TS_VERIFY_CTX *ctx, int f); int TS_VERIFY_CTX_add_flags(TS_VERIFY_CTX *ctx, int f); #ifndef OPENSSL_NO_DEPRECATED_3_4 -OSSL_DEPRECATEDIN_3_4_FOR("Unclear semantics, replace with TS_VERIFY_CTX_set0_data().") +OSSL_DEPRECATEDIN_3_4_FOR("unclear semantics, replace with TS_VERIFY_CTX_set0_data()") BIO *TS_VERIFY_CTX_set_data(TS_VERIFY_CTX *ctx, BIO *b); #endif int TS_VERIFY_CTX_set0_data(TS_VERIFY_CTX *ctx, BIO *b); #ifndef OPENSSL_NO_DEPRECATED_3_4 -OSSL_DEPRECATEDIN_3_4_FOR("Unclear semantics, replace with TS_VERIFY_CTX_set0_imprint().") +OSSL_DEPRECATEDIN_3_4_FOR("unclear semantics, replace with TS_VERIFY_CTX_set0_imprint()") unsigned char *TS_VERIFY_CTX_set_imprint(TS_VERIFY_CTX *ctx, unsigned char *hexstr, long len); #endif int TS_VERIFY_CTX_set0_imprint(TS_VERIFY_CTX *ctx, unsigned char *hexstr, long len); #ifndef OPENSSL_NO_DEPRECATED_3_4 -OSSL_DEPRECATEDIN_3_4_FOR("Unclear semantics, replace with TS_VERIFY_CTX_set0_store().") +OSSL_DEPRECATEDIN_3_4_FOR("unclear semantics, replace with TS_VERIFY_CTX_set0_store()") X509_STORE *TS_VERIFY_CTX_set_store(TS_VERIFY_CTX *ctx, X509_STORE *s); #endif int TS_VERIFY_CTX_set0_store(TS_VERIFY_CTX *ctx, X509_STORE *s); @@ -438,7 +438,7 @@ int TS_VERIFY_CTX_set0_store(TS_VERIFY_CTX *ctx, X509_STORE *s); #define TS_VERIFY_CTS_set_certs(ctx, cert) TS_VERIFY_CTX_set_certs(ctx, cert) #endif #ifndef OPENSSL_NO_DEPRECATED_3_4 -OSSL_DEPRECATEDIN_3_4_FOR("Unclear semantics, replace with TS_VERIFY_CTX_set0_certs().") +OSSL_DEPRECATEDIN_3_4_FOR("unclear semantics, replace with TS_VERIFY_CTX_set0_certs()") STACK_OF(X509) *TS_VERIFY_CTX_set_certs(TS_VERIFY_CTX *ctx, STACK_OF(X509) *certs); #endif int TS_VERIFY_CTX_set0_certs(TS_VERIFY_CTX *ctx, STACK_OF(X509) *certs); diff --git a/include/openssl/tserr.h b/include/openssl/tserr.h deleted file mode 100644 index 0bec94a37cd36..0000000000000 --- a/include/openssl/tserr.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_TSERR_H -#define OPENSSL_TSERR_H -#pragma once - -#include -#include -#include - -#ifndef OPENSSL_NO_TS - -/* - * TS reason codes. - */ -#define TS_R_BAD_PKCS7_TYPE 132 -#define TS_R_BAD_TYPE 133 -#define TS_R_CANNOT_LOAD_CERT 137 -#define TS_R_CANNOT_LOAD_KEY 138 -#define TS_R_CERTIFICATE_VERIFY_ERROR 100 -#define TS_R_COULD_NOT_SET_ENGINE 127 -#define TS_R_COULD_NOT_SET_TIME 115 -#define TS_R_DETACHED_CONTENT 134 -#define TS_R_ESS_ADD_SIGNING_CERT_ERROR 116 -#define TS_R_ESS_ADD_SIGNING_CERT_V2_ERROR 139 -#define TS_R_ESS_SIGNING_CERTIFICATE_ERROR 101 -#define TS_R_INVALID_NULL_POINTER 102 -#define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE 117 -#define TS_R_MESSAGE_IMPRINT_MISMATCH 103 -#define TS_R_NONCE_MISMATCH 104 -#define TS_R_NONCE_NOT_RETURNED 105 -#define TS_R_NO_CONTENT 106 -#define TS_R_NO_TIME_STAMP_TOKEN 107 -#define TS_R_PKCS7_ADD_SIGNATURE_ERROR 118 -#define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR 119 -#define TS_R_PKCS7_TO_TS_TST_INFO_FAILED 129 -#define TS_R_POLICY_MISMATCH 108 -#define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 120 -#define TS_R_RESPONSE_SETUP_ERROR 121 -#define TS_R_SIGNATURE_FAILURE 109 -#define TS_R_THERE_MUST_BE_ONE_SIGNER 110 -#define TS_R_TIME_SYSCALL_ERROR 122 -#define TS_R_TOKEN_NOT_PRESENT 130 -#define TS_R_TOKEN_PRESENT 131 -#define TS_R_TSA_NAME_MISMATCH 111 -#define TS_R_TSA_UNTRUSTED 112 -#define TS_R_TST_INFO_SETUP_ERROR 123 -#define TS_R_TS_DATASIGN 124 -#define TS_R_UNACCEPTABLE_POLICY 125 -#define TS_R_UNSUPPORTED_MD_ALGORITHM 126 -#define TS_R_UNSUPPORTED_VERSION 113 -#define TS_R_VAR_BAD_VALUE 135 -#define TS_R_VAR_LOOKUP_FAILURE 136 -#define TS_R_WRONG_CONTENT_TYPE 114 - -#endif -#endif diff --git a/include/openssl/uierr.h b/include/openssl/uierr.h deleted file mode 100644 index 5201b0311df6f..0000000000000 --- a/include/openssl/uierr.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_UIERR_H -#define OPENSSL_UIERR_H -#pragma once - -#include -#include -#include - -/* - * UI reason codes. - */ -#define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS 104 -#define UI_R_INDEX_TOO_LARGE 102 -#define UI_R_INDEX_TOO_SMALL 103 -#define UI_R_NO_RESULT_BUFFER 105 -#define UI_R_PROCESSING_ERROR 107 -#define UI_R_RESULT_TOO_LARGE 100 -#define UI_R_RESULT_TOO_SMALL 101 -#define UI_R_SYSASSIGN_ERROR 109 -#define UI_R_SYSDASSGN_ERROR 110 -#define UI_R_SYSQIOW_ERROR 111 -#define UI_R_UNKNOWN_CONTROL_COMMAND 106 -#define UI_R_UNKNOWN_TTYGET_ERRNO_VALUE 108 -#define UI_R_USER_DATA_DUPLICATION_UNSUPPORTED 112 - -#endif diff --git a/include/openssl/x509_acert.h.in b/include/openssl/x509_acert.h.in index d00b95c781877..0c5adf53b42d4 100644 --- a/include/openssl/x509_acert.h.in +++ b/include/openssl/x509_acert.h.in @@ -1,7 +1,7 @@ /* * {- join("\n * ", @autowarntext) -} * - * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/include/openssl/x509_vfy.h.in b/include/openssl/x509_vfy.h.in index e6d19ff14c091..1d20703a76fe1 100644 --- a/include/openssl/x509_vfy.h.in +++ b/include/openssl/x509_vfy.h.in @@ -428,7 +428,7 @@ int X509_STORE_lock(X509_STORE *xs); int X509_STORE_unlock(X509_STORE *xs); int X509_STORE_up_ref(X509_STORE *xs); #ifndef OPENSSL_NO_DEPRECATED_4_0 -OSSL_DEPRECATEDIN_4_0_FOR("Use X509_STORE_get1_objects") +OSSL_DEPRECATEDIN_4_0_FOR("use X509_STORE_get1_objects()") STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(const X509_STORE *xs); #endif STACK_OF(X509_OBJECT) *X509_STORE_get1_objects(X509_STORE *xs); diff --git a/include/openssl/x509err.h b/include/openssl/x509err.h deleted file mode 100644 index fa00e4143fe30..0000000000000 --- a/include/openssl/x509err.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_X509ERR_H -#define OPENSSL_X509ERR_H -#pragma once - -#include -#include -#include - -/* - * X509 reason codes. - */ -#define X509_R_AKID_MISMATCH 110 -#define X509_R_BAD_SELECTOR 133 -#define X509_R_BAD_X509_FILETYPE 100 -#define X509_R_BASE64_DECODE_ERROR 118 -#define X509_R_CANT_CHECK_DH_KEY 114 -#define X509_R_CERTIFICATE_VERIFICATION_FAILED 139 -#define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 -#define X509_R_CRL_ALREADY_DELTA 127 -#define X509_R_CRL_SIGNATURE_ALGORITHM_MISMATCH 147 -#define X509_R_CRL_VERIFY_FAILURE 131 -#define X509_R_DUPLICATE_ATTRIBUTE 140 -#define X509_R_ERROR_GETTING_MD_BY_NID 141 -#define X509_R_ERROR_USING_SIGINF_SET 142 -#define X509_R_IDP_MISMATCH 128 -#define X509_R_INVALID_ATTRIBUTES 138 -#define X509_R_INVALID_DIRECTORY 113 -#define X509_R_INVALID_DISTPOINT 143 -#define X509_R_INVALID_EXTENSION 146 -#define X509_R_INVALID_FIELD_NAME 119 -#define X509_R_INVALID_TRUST 123 -#define X509_R_ISSUER_MISMATCH 129 -#define X509_R_KEY_TYPE_MISMATCH 115 -#define X509_R_KEY_VALUES_MISMATCH 116 -#define X509_R_LOADING_CERT_DIR 103 -#define X509_R_LOADING_DEFAULTS 104 -#define X509_R_METHOD_NOT_SUPPORTED 124 -#define X509_R_NAME_TOO_LONG 134 -#define X509_R_NEWER_CRL_NOT_NEWER 132 -#define X509_R_NO_CERTIFICATE_FOUND 135 -#define X509_R_NO_CERTIFICATE_OR_CRL_FOUND 136 -#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105 -#define X509_R_NO_CRL_FOUND 137 -#define X509_R_NO_CRL_NUMBER 130 -#define X509_R_PUBLIC_KEY_DECODE_ERROR 125 -#define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 -#define X509_R_SHOULD_RETRY 106 -#define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107 -#define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108 -#define X509_R_UNKNOWN_KEY_TYPE 117 -#define X509_R_UNKNOWN_NID 109 -#define X509_R_UNKNOWN_PURPOSE_ID 121 -#define X509_R_UNKNOWN_SIGID_ALGS 144 -#define X509_R_UNKNOWN_TRUST_ID 120 -#define X509_R_UNSUPPORTED_ALGORITHM 111 -#define X509_R_UNSUPPORTED_VERSION 145 -#define X509_R_WRONG_LOOKUP_TYPE 112 -#define X509_R_WRONG_TYPE 122 - -#endif diff --git a/include/openssl/x509v3.h.in b/include/openssl/x509v3.h.in index 21def64b947a4..34f1c6e69bf64 100644 --- a/include/openssl/x509v3.h.in +++ b/include/openssl/x509v3.h.in @@ -931,6 +931,7 @@ DECLARE_ASN1_FUNCTIONS(IPAddressRange) DECLARE_ASN1_FUNCTIONS(IPAddressOrRange) DECLARE_ASN1_FUNCTIONS(IPAddressChoice) DECLARE_ASN1_FUNCTIONS(IPAddressFamily) +DECLARE_ASN1_FUNCTIONS(IPAddrBlocks) /* * API tag for elements of the ASIdentifier SEQUENCE. diff --git a/include/openssl/x509v3err.h b/include/openssl/x509v3err.h deleted file mode 100644 index 19f938626bd84..0000000000000 --- a/include/openssl/x509v3err.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OPENSSL_X509V3ERR_H -#define OPENSSL_X509V3ERR_H -#pragma once - -#include -#include -#include - -/* - * X509V3 reason codes. - */ -#define X509V3_R_BAD_IP_ADDRESS 118 -#define X509V3_R_BAD_OBJECT 119 -#define X509V3_R_BAD_OPTION 170 -#define X509V3_R_BAD_VALUE 171 -#define X509V3_R_BN_DEC2BN_ERROR 100 -#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 -#define X509V3_R_DIRNAME_ERROR 149 -#define X509V3_R_DISTPOINT_ALREADY_SET 160 -#define X509V3_R_DUPLICATE_ZONE_ID 133 -#define X509V3_R_EMPTY_KEY_USAGE 169 -#define X509V3_R_ERROR_CONVERTING_ZONE 131 -#define X509V3_R_ERROR_CREATING_EXTENSION 144 -#define X509V3_R_ERROR_IN_EXTENSION 128 -#define X509V3_R_EXPECTED_A_SECTION_NAME 137 -#define X509V3_R_EXTENSION_EXISTS 145 -#define X509V3_R_EXTENSION_NAME_ERROR 115 -#define X509V3_R_EXTENSION_NOT_FOUND 102 -#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103 -#define X509V3_R_EXTENSION_VALUE_ERROR 116 -#define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151 -#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152 -#define X509V3_R_INVALID_ASNUMBER 162 -#define X509V3_R_INVALID_ASRANGE 163 -#define X509V3_R_INVALID_BOOLEAN_STRING 104 -#define X509V3_R_INVALID_CERTIFICATE 158 -#define X509V3_R_INVALID_EMPTY_NAME 108 -#define X509V3_R_INVALID_EXTENSION_STRING 105 -#define X509V3_R_INVALID_INHERITANCE 165 -#define X509V3_R_INVALID_IPADDRESS 166 -#define X509V3_R_INVALID_MULTIPLE_RDNS 161 -#define X509V3_R_INVALID_NAME 106 -#define X509V3_R_INVALID_NULL_ARGUMENT 107 -#define X509V3_R_INVALID_NULL_VALUE 109 -#define X509V3_R_INVALID_NUMBER 140 -#define X509V3_R_INVALID_NUMBERS 141 -#define X509V3_R_INVALID_OBJECT_IDENTIFIER 110 -#define X509V3_R_INVALID_OPTION 138 -#define X509V3_R_INVALID_POLICY_IDENTIFIER 134 -#define X509V3_R_INVALID_PROXY_POLICY_SETTING 153 -#define X509V3_R_INVALID_PURPOSE 146 -#define X509V3_R_INVALID_SAFI 164 -#define X509V3_R_INVALID_SECTION 135 -#define X509V3_R_INVALID_SYNTAX 143 -#define X509V3_R_ISSUER_DECODE_ERROR 126 -#define X509V3_R_MISSING_VALUE 124 -#define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 142 -#define X509V3_R_NEGATIVE_PATHLEN 168 -#define X509V3_R_NO_CONFIG_DATABASE 136 -#define X509V3_R_NO_ISSUER_CERTIFICATE 121 -#define X509V3_R_NO_ISSUER_DETAILS 127 -#define X509V3_R_NO_POLICY_IDENTIFIER 139 -#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 154 -#define X509V3_R_NO_PUBLIC_KEY 114 -#define X509V3_R_NO_SUBJECT_DETAILS 125 -#define X509V3_R_OPERATION_NOT_DEFINED 148 -#define X509V3_R_OTHERNAME_ERROR 147 -#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 155 -#define X509V3_R_POLICY_PATH_LENGTH 156 -#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 157 -#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159 -#define X509V3_R_PURPOSE_NOT_UNIQUE 173 -#define X509V3_R_SECTION_NOT_FOUND 150 -#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 122 -#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 123 -#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111 -#define X509V3_R_UNKNOWN_EXTENSION 129 -#define X509V3_R_UNKNOWN_EXTENSION_NAME 130 -#define X509V3_R_UNKNOWN_OPTION 120 -#define X509V3_R_UNKNOWN_VALUE 172 -#define X509V3_R_UNSUPPORTED_OPTION 117 -#define X509V3_R_UNSUPPORTED_TYPE 167 -#define X509V3_R_USER_TOO_LONG 132 - -#endif diff --git a/ms/applink.c b/ms/applink.c index 242b0bed74412..079abb0c957b0 100644 --- a/ms/applink.c +++ b/ms/applink.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/ms/uplink.c b/ms/uplink.c index c2d1bef80aa5a..e95113892162b 100644 --- a/ms/uplink.c +++ b/ms/uplink.c @@ -1,5 +1,5 @@ /* - * Copyright 2004-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/ms/uplink.h b/ms/uplink.h index 7e33f72df4fb6..0de07bf792d45 100644 --- a/ms/uplink.h +++ b/ms/uplink.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2004-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/pkcs11-provider b/pkcs11-provider index 5dcc876263c08..eb157e48066fd 160000 --- a/pkcs11-provider +++ b/pkcs11-provider @@ -1 +1 @@ -Subproject commit 5dcc876263c083d44944d84e6425497529f8ff54 +Subproject commit eb157e48066fdb2b5735f6f327ed7ae65c51eb6f diff --git a/providers/baseprov.c b/providers/baseprov.c index f517e5ae81b53..ad08765f006cf 100644 --- a/providers/baseprov.c +++ b/providers/baseprov.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/build.info b/providers/build.info index 9b75df100fdd0..2558cd2faa3cc 100644 --- a/providers/build.info +++ b/providers/build.info @@ -67,6 +67,10 @@ SOURCE[$LIBFIPS]=$LIBCOMMON DEPEND[$LIBLEGACY]=$LIBCOMMON DEPEND[$LIBDEFAULT]=$LIBCOMMON +IF[{- $target{needs_c99_snprintf_compat} -}] + SOURCE[$LIBFIPS]=../crypto/msvc2013_snprintf.c +ENDIF + # # Default provider stuff # diff --git a/providers/common/capabilities.c b/providers/common/capabilities.c index f461ec222ada4..13ad72ffb57b5 100644 --- a/providers/common/capabilities.c +++ b/providers/common/capabilities.c @@ -33,7 +33,7 @@ typedef struct tls_group_constants_st { int maxtls; /* Maximum TLS version (or 0 for undefined) */ int mindtls; /* Minimum DTLS version, -1 unsupported */ int maxdtls; /* Maximum DTLS version (or 0 for undefined) */ - int is_kem; /* Indicates utility as KEM */ + unsigned int is_kem; /* Indicates utility as KEM */ } TLS_GROUP_CONSTANTS; /* @@ -78,22 +78,24 @@ static const TLS_GROUP_CONSTANTS group_list[] = { /* 27 */ { OSSL_TLS_GROUP_ID_brainpoolP512r1, 256, TLS1_VERSION, TLS1_2_VERSION, DTLS1_VERSION, DTLS1_2_VERSION, 0 }, /* 28 */ { OSSL_TLS_GROUP_ID_x25519, 128, TLS1_VERSION, 0, DTLS1_VERSION, 0, 0 }, /* 29 */ { OSSL_TLS_GROUP_ID_x448, 224, TLS1_VERSION, 0, DTLS1_VERSION, 0, 0 }, - /* 30 */ { OSSL_TLS_GROUP_ID_brainpoolP256r1_tls13, 128, TLS1_3_VERSION, 0, -1, -1, 0 }, - /* 31 */ { OSSL_TLS_GROUP_ID_brainpoolP384r1_tls13, 192, TLS1_3_VERSION, 0, -1, -1, 0 }, - /* 32 */ { OSSL_TLS_GROUP_ID_brainpoolP512r1_tls13, 256, TLS1_3_VERSION, 0, -1, -1, 0 }, - /* 33 */ { OSSL_TLS_GROUP_ID_ffdhe2048, 112, TLS1_3_VERSION, 0, -1, -1, 0 }, - /* 34 */ { OSSL_TLS_GROUP_ID_ffdhe3072, 128, TLS1_3_VERSION, 0, -1, -1, 0 }, - /* 35 */ { OSSL_TLS_GROUP_ID_ffdhe4096, 128, TLS1_3_VERSION, 0, -1, -1, 0 }, - /* 36 */ { OSSL_TLS_GROUP_ID_ffdhe6144, 128, TLS1_3_VERSION, 0, -1, -1, 0 }, - /* 37 */ { OSSL_TLS_GROUP_ID_ffdhe8192, 192, TLS1_3_VERSION, 0, -1, -1, 0 }, - /* 38 */ { OSSL_TLS_GROUP_ID_mlkem512, ML_KEM_512_SECBITS, TLS1_3_VERSION, 0, -1, -1, 1 }, - /* 39 */ { OSSL_TLS_GROUP_ID_mlkem768, ML_KEM_768_SECBITS, TLS1_3_VERSION, 0, -1, -1, 1 }, - /* 40 */ { OSSL_TLS_GROUP_ID_mlkem1024, ML_KEM_1024_SECBITS, TLS1_3_VERSION, 0, -1, -1, 1 }, - /* 41 */ { OSSL_TLS_GROUP_ID_X25519MLKEM768, ML_KEM_768_SECBITS, TLS1_3_VERSION, 0, -1, -1, 1 }, - /* 42 */ { OSSL_TLS_GROUP_ID_SecP256r1MLKEM768, ML_KEM_768_SECBITS, TLS1_3_VERSION, 0, -1, -1, 1 }, - /* 43 */ { OSSL_TLS_GROUP_ID_SecP384r1MLKEM1024, ML_KEM_1024_SECBITS, TLS1_3_VERSION, 0, -1, -1, 1 }, - /* 44 */ { OSSL_TLS_GROUP_ID_curveSM2, 128, TLS1_3_VERSION, 0, -1, -1, 0 }, - /* 45 */ { OSSL_TLS_GROUP_ID_curveSM2MLKEM768, ML_KEM_768_SECBITS, TLS1_3_VERSION, 0, -1, -1, 1 }, + /* 30 */ { OSSL_TLS_GROUP_ID_brainpoolP256r1_tls13, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 0 }, + /* 31 */ { OSSL_TLS_GROUP_ID_brainpoolP384r1_tls13, 192, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 0 }, + /* 32 */ { OSSL_TLS_GROUP_ID_brainpoolP512r1_tls13, 256, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 0 }, + /* 33 */ { OSSL_TLS_GROUP_ID_ffdhe2048, 112, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 0 }, + /* 34 */ { OSSL_TLS_GROUP_ID_ffdhe3072, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 0 }, + /* 35 */ { OSSL_TLS_GROUP_ID_ffdhe4096, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 0 }, + /* 36 */ { OSSL_TLS_GROUP_ID_ffdhe6144, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 0 }, + /* 37 */ { OSSL_TLS_GROUP_ID_ffdhe8192, 192, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 0 }, + /* 38 */ { OSSL_TLS_GROUP_ID_mlkem512, ML_KEM_512_SECBITS, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 1 }, + /* 39 */ { OSSL_TLS_GROUP_ID_mlkem768, ML_KEM_768_SECBITS, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 1 }, + /* 40 */ { OSSL_TLS_GROUP_ID_mlkem1024, ML_KEM_1024_SECBITS, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 1 }, + /* 41 */ { OSSL_TLS_GROUP_ID_X25519MLKEM768, ML_KEM_768_SECBITS, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 1 }, + /* 42 */ { OSSL_TLS_GROUP_ID_SecP256r1MLKEM768, ML_KEM_768_SECBITS, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 1 }, + /* 43 */ { OSSL_TLS_GROUP_ID_SecP384r1MLKEM1024, ML_KEM_1024_SECBITS, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 1 }, + /* 44 */ { OSSL_TLS_GROUP_ID_curveSM2, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 0 }, + /* 45 */ { OSSL_TLS_GROUP_ID_curveSM2MLKEM768, ML_KEM_768_SECBITS, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 1 }, + /* 46 */ { OSSL_TLS_GROUP_ID_MLKEM512X25519, ML_KEM_512_SECBITS, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 1 }, + /* 47 */ { OSSL_TLS_GROUP_ID_SecP256r1MLKEM512, ML_KEM_512_SECBITS, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0, 1 }, }; #define TLS_GROUP_ENTRY(tlsname, realname, algorithm, idx) \ @@ -112,14 +114,14 @@ static const TLS_GROUP_CONSTANTS group_list[] = { OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_SECURITY_BITS, \ (unsigned int *)&group_list[idx].secbits), \ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_TLS, \ - (unsigned int *)&group_list[idx].mintls), \ + (int *)&group_list[idx].mintls), \ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_TLS, \ - (unsigned int *)&group_list[idx].maxtls), \ + (int *)&group_list[idx].maxtls), \ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MIN_DTLS, \ - (unsigned int *)&group_list[idx].mindtls), \ + (int *)&group_list[idx].mindtls), \ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_MAX_DTLS, \ - (unsigned int *)&group_list[idx].maxdtls), \ - OSSL_PARAM_int(OSSL_CAPABILITY_TLS_GROUP_IS_KEM, \ + (int *)&group_list[idx].maxdtls), \ + OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_GROUP_IS_KEM, \ (unsigned int *)&group_list[idx].is_kem), \ OSSL_PARAM_END \ } @@ -157,6 +159,7 @@ static const OSSL_PARAM param_group_list[][11] = { #ifndef OPENSSL_NO_EC #if !defined(OPENSSL_NO_ML_KEM) #if !defined(OPENSSL_NO_ECX) + TLS_GROUP_ENTRY("MLKEM512X25519", "", "MLKEM512X25519", 46), TLS_GROUP_ENTRY("X25519MLKEM768", "", "X25519MLKEM768", 41), #endif #endif @@ -198,6 +201,7 @@ static const OSSL_PARAM param_group_list[][11] = { #endif #endif #ifndef OPENSSL_NO_ML_KEM + TLS_GROUP_ENTRY("SecP256r1MLKEM512", "", "SecP256r1MLKEM512", 47), TLS_GROUP_ENTRY("SecP256r1MLKEM768", "", "SecP256r1MLKEM768", 42), TLS_GROUP_ENTRY("SecP384r1MLKEM1024", "", "SecP384r1MLKEM1024", 43), #endif @@ -294,22 +298,22 @@ typedef struct tls_sigalg_constants_st { } TLS_SIGALG_CONSTANTS; static const TLS_SIGALG_CONSTANTS sigalg_constants_list[] = { - { TLSEXT_SIGALG_mldsa44, 128, TLS1_3_VERSION, 0, -1, -1 }, - { TLSEXT_SIGALG_mldsa65, 192, TLS1_3_VERSION, 0, -1, -1 }, - { TLSEXT_SIGALG_mldsa87, 256, TLS1_3_VERSION, 0, -1, -1 }, - { TLSEXT_SIGALG_slhdsa_sha2_128s, 128, TLS1_3_VERSION, 0, -1, -1 }, - { TLSEXT_SIGALG_slhdsa_sha2_128f, 128, TLS1_3_VERSION, 0, -1, -1 }, - { TLSEXT_SIGALG_slhdsa_sha2_192s, 192, TLS1_3_VERSION, 0, -1, -1 }, - { TLSEXT_SIGALG_slhdsa_sha2_192f, 192, TLS1_3_VERSION, 0, -1, -1 }, - { TLSEXT_SIGALG_slhdsa_sha2_256s, 256, TLS1_3_VERSION, 0, -1, -1 }, - { TLSEXT_SIGALG_slhdsa_sha2_256f, 256, TLS1_3_VERSION, 0, -1, -1 }, - { TLSEXT_SIGALG_slhdsa_shake_128s, 128, TLS1_3_VERSION, 0, -1, -1 }, - { TLSEXT_SIGALG_slhdsa_shake_128f, 128, TLS1_3_VERSION, 0, -1, -1 }, - { TLSEXT_SIGALG_slhdsa_shake_192s, 192, TLS1_3_VERSION, 0, -1, -1 }, - { TLSEXT_SIGALG_slhdsa_shake_192f, 192, TLS1_3_VERSION, 0, -1, -1 }, - { TLSEXT_SIGALG_slhdsa_shake_256s, 256, TLS1_3_VERSION, 0, -1, -1 }, - { TLSEXT_SIGALG_slhdsa_shake_256f, 256, TLS1_3_VERSION, 0, -1, -1 }, - { TLSEXT_SIGALG_sm2sig_sm3, 128, TLS1_3_VERSION, 0, -1, -1 }, + { TLSEXT_SIGALG_mldsa44, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { TLSEXT_SIGALG_mldsa65, 192, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { TLSEXT_SIGALG_mldsa87, 256, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { TLSEXT_SIGALG_slhdsa_sha2_128s, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { TLSEXT_SIGALG_slhdsa_sha2_128f, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { TLSEXT_SIGALG_slhdsa_sha2_192s, 192, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { TLSEXT_SIGALG_slhdsa_sha2_192f, 192, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { TLSEXT_SIGALG_slhdsa_sha2_256s, 256, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { TLSEXT_SIGALG_slhdsa_sha2_256f, 256, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { TLSEXT_SIGALG_slhdsa_shake_128s, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { TLSEXT_SIGALG_slhdsa_shake_128f, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { TLSEXT_SIGALG_slhdsa_shake_192s, 192, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { TLSEXT_SIGALG_slhdsa_shake_192f, 192, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { TLSEXT_SIGALG_slhdsa_shake_256s, 256, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { TLSEXT_SIGALG_slhdsa_shake_256f, 256, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, + { TLSEXT_SIGALG_sm2sig_sm3, 128, TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, }; #define TLS_SIGALG_ENTRY(tlsname, algorithm, oid, idx) \ @@ -325,13 +329,13 @@ static const TLS_SIGALG_CONSTANTS sigalg_constants_list[] = { OSSL_PARAM_uint(OSSL_CAPABILITY_TLS_SIGALG_SECURITY_BITS, \ (unsigned int *)&sigalg_constants_list[idx].sec_bits), \ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS, \ - (unsigned int *)&sigalg_constants_list[idx].min_tls), \ + (int *)&sigalg_constants_list[idx].min_tls), \ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS, \ - (unsigned int *)&sigalg_constants_list[idx].max_tls), \ + (int *)&sigalg_constants_list[idx].max_tls), \ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MIN_DTLS, \ - (unsigned int *)&sigalg_constants_list[idx].min_dtls), \ + (int *)&sigalg_constants_list[idx].min_dtls), \ OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MAX_DTLS, \ - (unsigned int *)&sigalg_constants_list[idx].max_dtls), \ + (int *)&sigalg_constants_list[idx].max_dtls), \ OSSL_PARAM_END \ } diff --git a/providers/common/der/build.info b/providers/common/der/build.info index efa34700d1020..bee94fbe4bc65 100644 --- a/providers/common/der/build.info +++ b/providers/common/der/build.info @@ -86,6 +86,19 @@ IF[{- !$disabled{'ml-dsa'} -}] DEPEND[$DER_ML_DSA_H]=oids_to_c.pm ML_DSA.asn1 ENDIF +#----- composite +IF[{- !$disabled{'ml-dsa'} -}] + $COMPOSITE_H=$INCDIR/composite.h + $DER_COMPOSITE_GEN=der_composite_gen.c + + GENERATE[$COMPOSITE_H]=$INCDIR/composite.h.in + DEPEND[$COMPOSITE_H]=oids_to_c.pm composite.asn1 + + GENERATE[$DER_COMPOSITE_GEN]=der_composite_gen.c.in + DEPEND[$DER_COMPOSITE_GEN]=oids_to_c.pm composite.asn1 + DEPEND[${DER_COMPOSITE_GEN/.c/.o}]=$COMPOSITE_H +ENDIF + #----- KEY WRAP $DER_WRAP_H=$INCDIR/der_wrap.h $DER_WRAP_GEN=der_wrap_gen.c @@ -165,6 +178,10 @@ IF[{- !$disabled{'slh-dsa'} -}] $COMMON = $COMMON $DER_SLH_DSA_GEN $DER_SLH_DSA_AUX ENDIF +IF[{- !$disabled{'ml-dsa'} -}] + $COMMON = $COMMON $DER_COMPOSITE_GEN +ENDIF + SOURCE[../../libcommon.a]= $COMMON SOURCE[../../libfips.a]= $DER_RSA_FIPSABLE SOURCE[../../libdefault.a]= $DER_RSA_FIPSABLE $NONFIPS diff --git a/providers/common/der/composite.asn1 b/providers/common/der/composite.asn1 new file mode 100644 index 0000000000000..5a0d010541309 --- /dev/null +++ b/providers/common/der/composite.asn1 @@ -0,0 +1,31 @@ +-- Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +-- +-- Licensed under the Apache License 2.0 (the "License"). You may not use +-- this file except in compliance with the License. You can obtain a copy +-- in the file LICENSE in the source distribution or at +-- https://www.openssl.org/source/license.html + +-- ------------------------------------------------------------------- + +-- Taken from https://datatracker.ietf.org/doc/draft-ietf-lamps-pq-composite-sigs/ + +pkixAlgs OBJECT IDENTIFIER ::= { 1 3 6 1 5 5 7 6 } + +id-mldsa44-rsa2048-pss-sha256 OBJECT IDENTIFIER ::= { pkixAlgs 37 } +id-mldsa44-rsa2048-pkcs15-sha256 OBJECT IDENTIFIER ::= { pkixAlgs 38 } +id-mldsa44-ed25519-sha512 OBJECT IDENTIFIER ::= { pkixAlgs 39 } +id-mldsa44-ecdsa-p256-sha256 OBJECT IDENTIFIER ::= { pkixAlgs 40 } +id-mldsa65-rsa3072-pss-sha512 OBJECT IDENTIFIER ::= { pkixAlgs 41 } +id-mldsa65-rsa3072-pkcs15-sha512 OBJECT IDENTIFIER ::= { pkixAlgs 42 } +id-mldsa65-rsa4096-pss-sha512 OBJECT IDENTIFIER ::= { pkixAlgs 43 } +id-mldsa65-rsa4096-pkcs15-sha512 OBJECT IDENTIFIER ::= { pkixAlgs 44 } +id-mldsa65-ecdsa-p256-sha512 OBJECT IDENTIFIER ::= { pkixAlgs 45 } +id-mldsa65-ecdsa-p384-sha512 OBJECT IDENTIFIER ::= { pkixAlgs 46 } +id-mldsa65-ecdsa-brainpoolP256r1-sha512 OBJECT IDENTIFIER ::= { pkixAlgs 47 } +id-mldsa65-ed25519-sha512 OBJECT IDENTIFIER ::= { pkixAlgs 48 } +id-mldsa87-ecdsa-p384-sha512 OBJECT IDENTIFIER ::= { pkixAlgs 49 } +id-mldsa87-ecdsa-brainpoolp384r1-sha512 OBJECT IDENTIFIER ::= { pkixAlgs 50 } +id-mldsa87-ed448-shake256 OBJECT IDENTIFIER ::= { pkixAlgs 51 } +id-mldsa87-rsa3072-pss-sha512 OBJECT IDENTIFIER ::= { pkixAlgs 52 } +id-mldsa87-rsa4096-pss-sha512 OBJECT IDENTIFIER ::= { pkixAlgs 53 } +id-mldsa87-ecdsa-p521-sha512 OBJECT IDENTIFIER ::= { pkixAlgs 54 } diff --git a/providers/common/der/der_composite_gen.c.in b/providers/common/der/der_composite_gen.c.in new file mode 100644 index 0000000000000..57dbbc03e5104 --- /dev/null +++ b/providers/common/der/der_composite_gen.c.in @@ -0,0 +1,21 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "prov/composite.h" + +/* Well known OIDs precompiled */ +/* clang-format off */ +{- + $OUT = oids_to_c::process_leaves('providers/common/der/composite.asn1', + { dir => $config{sourcedir}, + filter => \&oids_to_c::filter_to_C }); +-} +/* clang-format on */ diff --git a/providers/common/der/oids_to_c.pm b/providers/common/der/oids_to_c.pm index c5137065a3e48..d8d0640dc5453 100644 --- a/providers/common/der/oids_to_c.pm +++ b/providers/common/der/oids_to_c.pm @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/providers/common/include/prov/bio.h b/providers/common/include/prov/bio.h index 72fe6b0d7a46b..33b1ff9023bd2 100644 --- a/providers/common/include/prov/bio.h +++ b/providers/common/include/prov/bio.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/common/include/prov/composite.h.in b/providers/common/include/prov/composite.h.in new file mode 100644 index 0000000000000..dffdfe5f8dfa7 --- /dev/null +++ b/providers/common/include/prov/composite.h.in @@ -0,0 +1,73 @@ +/* + * {- join("\n * ", @autowarntext) -} + * + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef PROV_COMPOSITE_H +#define PROV_COMPOSITE_H + +#include "internal/der.h" +#include "crypto/ml_dsa.h" +#include "prov/provider_ctx.h" + +#define COMPOSITE_PREFIX "436F6D706F73697465416C676F726974686D5369676E61747572657332303235" + +/* Well known OIDs precompiled */ +/* clang-format off */ +{- + $OUT = oids_to_c::process_leaves('providers/common/der/composite.asn1', + { dir => $config{sourcedir}, + filter => \&oids_to_c::filter_to_H }); +-} +/* clang-format on */ + +typedef struct { + ML_DSA_KEY *ml_dsa_key; + EVP_PKEY *classic_key; +} COMPOSITE_KEY; + +typedef struct { + OSSL_LIB_CTX *libctx; + const char *alg; + const unsigned char *oid; + size_t oid_sz; + uint8_t context_string[255]; /* ML_DSA_MAX_CONTEXT_STRING_LEN */ + size_t context_string_len; + /* + * Optional fixed entropy for the ML-DSA randomizer (test use only). + * When test_entropy_len != 0 the 32-byte value is used instead of + * RAND_priv_bytes_ex, enabling deterministic signing for test vectors. + * Mirrors OSSL_SIGNATURE_PARAM_TEST_ENTROPY in ml_dsa_sig.c. + */ + uint8_t test_entropy[ML_DSA_ENTROPY_LEN]; + size_t test_entropy_len; + const char *prehash_alg; + size_t prehash_len; + + /* CLASSIC */ + EVP_PKEY_CTX *classic_ctx; + + COMPOSITE_KEY *key; + + /* sign vs verify, drives which ctx params (e.g. "signature") apply */ + int operation; + /* 1 if the caller supplies PH(M) directly via OSSL_SIGNATURE_PARAM_COMPOSITE_PREHASH */ + int have_prehash; + /* streaming digest for PH(M); lazily created on the first msg_update() */ + EVP_MD_CTX *prehash_ctx; + /* signature to check against, set via "signature" for verify_message_final() */ + unsigned char *sig; + size_t siglen; +} PROV_COMPOSITE_CTX; + +COMPOSITE_KEY *ossl_prov_composite_new(PROV_CTX *ctx, const char *propq, + int ml_dsa_evp_type); +void ossl_composite_key_free(COMPOSITE_KEY *key); + +#endif /* PROV_COMPOSITE_H */ diff --git a/providers/common/include/prov/proverr.h b/providers/common/include/prov/proverr.h deleted file mode 100644 index 573bb212eb15b..0000000000000 --- a/providers/common/include/prov/proverr.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#ifndef OSSL_PROVERR_H -#define OSSL_PROVERR_H -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -int ossl_err_load_PROV_strings(void); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/providers/common/include/prov/provider_util.h b/providers/common/include/prov/provider_util.h index 1072fb1ad078c..06f66bb171157 100644 --- a/providers/common/include/prov/provider_util.h +++ b/providers/common/include/prov/provider_util.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/common/include/prov/providercommon.h b/providers/common/include/prov/providercommon.h index e470a49d69a44..b07b5097e8bdb 100644 --- a/providers/common/include/prov/providercommon.h +++ b/providers/common/include/prov/providercommon.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/common/include/prov/securitycheck.h b/providers/common/include/prov/securitycheck.h index e36c77c2180ff..a4974e9af1111 100644 --- a/providers/common/include/prov/securitycheck.h +++ b/providers/common/include/prov/securitycheck.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c deleted file mode 100644 index 33e7edb454b33..0000000000000 --- a/providers/common/provider_err.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include "include/prov/proverr.h" - -#ifndef OPENSSL_NO_ERR - -static const ERR_STRING_DATA PROV_str_reasons[] = { - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ADDITIONAL_INPUT_TOO_LONG), - "additional input too long" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ALGORITHM_MISMATCH), - "algorithm mismatch" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ALREADY_INSTANTIATED), - "already instantiated" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_DECRYPT), "bad decrypt" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_ENCODING), "bad encoding" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_LENGTH), "bad length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BAD_TLS_CLIENT_VERSION), - "bad tls client version" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_BN_ERROR), "bn error" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_CIPHER_OPERATION_FAILED), - "cipher operation failed" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_COFACTOR_REQUIRED), "cofactor required" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_DERIVATION_FUNCTION_INIT_FAILED), - "derivation function init failed" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_DIGEST_NOT_ALLOWED), - "digest not allowed" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_EMS_NOT_ENABLED), "ems not enabled" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ENTROPY_SOURCE_FAILED_CONTINUOUS_TESTS), - "entropy source failed continuous tests" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ENTROPY_SOURCE_STRENGTH_TOO_WEAK), - "entropy source strength too weak" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ERROR_INSTANTIATING_DRBG), - "error instantiating drbg" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ERROR_RETRIEVING_ENTROPY), - "error retrieving entropy" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ERROR_RETRIEVING_NONCE), - "error retrieving nonce" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_DURING_DERIVATION), - "failed during derivation" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_CREATE_LOCK), - "failed to create lock" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_DECRYPT), "failed to decrypt" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_GENERATE_KEY), - "failed to generate key" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_GET_PARAMETER), - "failed to get parameter" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SET_PARAMETER), - "failed to set parameter" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SIGN), "failed to sign" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FINAL_CALL_OUT_OF_ORDER), - "final call out of order" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR), - "fips module conditional error" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE), - "fips module entering error state" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_MODULE_IMPORT_PCT_ERROR), - "fips module import pct error" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_MODULE_IN_ERROR_STATE), - "fips module in error state" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_GENERATE_ERROR), "generate error" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE), - "illegal or unsupported padding mode" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INDICATOR_INTEGRITY_FAILURE), - "indicator integrity failure" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INIT_CALL_OUT_OF_ORDER), - "init call out of order" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INSUFFICIENT_DRBG_STRENGTH), - "insufficient drbg strength" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_AAD), "invalid aad" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_AEAD), "invalid aead" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CIPHER), "invalid cipher" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CONFIG_DATA), - "invalid config data" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CONSTANT_LENGTH), - "invalid constant length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CURVE), "invalid curve" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CUSTOM_LENGTH), - "invalid custom length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DATA), "invalid data" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DIGEST), "invalid digest" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DIGEST_LENGTH), - "invalid digest length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_DIGEST_SIZE), - "invalid digest size" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_EDDSA_INSTANCE_FOR_ATTEMPTED_OPERATION), - "invalid eddsa instance for attempted operation" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_FUNCTION_NAME), - "invalid function name" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_INDEX_LENGTH), - "invalid index length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_INPUT_LENGTH), - "invalid input length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_ITERATION_COUNT), - "invalid iteration count" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_IV_LENGTH), "invalid iv length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KDF), "invalid kdf" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KDR), "invalid kdr" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEY), "invalid key" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEY_LENGTH), - "invalid key length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_LABEL), "invalid label" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MAC), "invalid mac" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MEMORY_SIZE), - "invalid memory size" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MGF1_MD), "invalid mgf1 md" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MODE), "invalid mode" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_NONCE_LENGTH), - "invalid nonce length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_OUTPUT_LENGTH), - "invalid output length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_PADDING_MODE), - "invalid padding mode" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_PARAMETERS_FOR_DKM), - "invalid parameters for dkm" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_PREHASHED_DIGEST_LENGTH), - "invalid prehashed digest length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_PUBINFO), "invalid pubinfo" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SALT_LENGTH), - "invalid salt length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SECRET_LENGTH), - "invalid secret length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SEED_LENGTH), - "invalid seed length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SIGNATURE_SIZE), - "invalid signature size" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_STATE), "invalid state" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_TAG), "invalid tag" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_TAG_LENGTH), - "invalid tag length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_THREAD_POOL_SIZE), - "invalid thread pool size" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_UKM_LENGTH), - "invalid ukm length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_X931_DIGEST), - "invalid x931 digest" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_IN_ERROR_STATE), "in error state" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_KEY_IMMUTABLE_ONCE_SET), - "key immutable once set" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_KEY_SETUP_FAILED), "key setup failed" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_KEY_SIZE_TOO_SMALL), - "key size too small" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_LENGTH_TOO_LARGE), "length too large" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISMATCHING_DOMAIN_PARAMETERS), - "mismatching domain parameters" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CEK_ALG), "missing cek alg" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CIPHER), "missing cipher" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CONFIG_DATA), - "missing config data" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CONSTANT), "missing constant" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_DKM), "missing dkm" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_EID), "missing eid" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_KEY), "missing key" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_MAC), "missing mac" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_MESSAGE_DIGEST), - "missing message digest" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_NONCE), "missing nonce" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_OID), "missing OID" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_PASS), "missing pass" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_SALT), "missing salt" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_SECRET), "missing secret" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_SEED), "missing seed" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_SESSION_ID), - "missing session id" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_TYPE), "missing type" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_XCGHASH), "missing xcghash" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ML_DSA_NO_FORMAT), "ml dsa no format" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ML_KEM_NO_FORMAT), "ml kem no format" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MODULE_INTEGRITY_FAILURE), - "module integrity failure" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_A_PRIVATE_KEY), "not a private key" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_A_PUBLIC_KEY), "not a public key" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_INSTANTIATED), "not instantiated" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_PARAMETERS), "not parameters" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_SUPPORTED), "not supported" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_XOF_OR_INVALID_LENGTH), - "not xof or invalid length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NO_INSTANCE_ALLOWED), - "no instance allowed" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NO_KEY_SET), "no key set" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NO_PARAMETERS_SET), "no parameters set" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NULL_LENGTH_POINTER), - "null length pointer" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NULL_OUTPUT_BUFFER), - "null output buffer" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ONESHOT_CALL_OUT_OF_ORDER), - "oneshot call out of order" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), - "operation not supported for this keytype" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_OUTPUT_BUFFER_TOO_SMALL), - "output buffer too small" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PARENT_CANNOT_GENERATE_RANDOM_NUMBERS), - "parent cannot generate random numbers" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PARENT_CANNOT_SUPPLY_ENTROPY_SEED), - "parent cannot supply entropy seed" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PARENT_LOCKING_NOT_ENABLED), - "parent locking not enabled" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PARENT_STRENGTH_TOO_WEAK), - "parent strength too weak" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PASSWORD_STRENGTH_TOO_WEAK), - "password strength too weak" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PATH_MUST_BE_ABSOLUTE), - "path must be absolute" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PERSONALISATION_STRING_TOO_LONG), - "personalisation string too long" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_PSS_SALTLEN_TOO_SMALL), - "pss saltlen too small" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_REPEATED_PARAMETER), - "repeated parameter" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_REQUEST_TOO_LARGE_FOR_DRBG), - "request too large for drbg" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_REQUIRE_CTR_MODE_CIPHER), - "require ctr mode cipher" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_RESEED_ERROR), "reseed error" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SEARCH_ONLY_SUPPORTED_FOR_DIRECTORIES), - "search only supported for directories" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SEED_SOURCES_MUST_NOT_HAVE_A_PARENT), - "seed sources must not have a parent" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SELF_TEST_KAT_FAILURE), - "self test kat failure" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SELF_TEST_POST_FAILURE), - "self test post failure" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TAG_NOT_NEEDED), "tag not needed" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TAG_NOT_SET), "tag not set" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TOO_MANY_RECORDS), "too many records" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_FIND_CIPHERS), - "unable to find ciphers" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_GET_PARENT_STRENGTH), - "unable to get parent strength" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_GET_PASSPHRASE), - "unable to get passphrase" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_INITIALISE_CIPHERS), - "unable to initialise ciphers" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_LOAD_SHA256), - "unable to load sha256" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_LOCK_PARENT), - "unable to lock parent" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_RESEED), "unable to reseed" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNEXPECTED_KEY_PARAMETERS), - "unexpected key parameters" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_CEK_ALG), - "unsupported cek alg" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_KEY_SIZE), - "unsupported key size" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_MAC_TYPE), - "unsupported mac type" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS), - "unsupported number of rounds" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_SELECTION), - "unsupported selection" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UPDATE_CALL_OUT_OF_ORDER), - "update call out of order" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_URI_AUTHORITY_UNSUPPORTED), - "uri authority unsupported" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_VALUE_ERROR), "value error" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_WRONG_CIPHERTEXT_SIZE), - "wrong ciphertext size" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_WRONG_FINAL_BLOCK_LENGTH), - "wrong final block length" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_WRONG_OUTPUT_BUFFER_SIZE), - "wrong output buffer size" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_XOF_DIGESTS_NOT_ALLOWED), - "xof digests not allowed" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_XTS_DATA_UNIT_IS_TOO_LARGE), - "xts data unit is too large" }, - { ERR_PACK(ERR_LIB_PROV, 0, PROV_R_XTS_DUPLICATED_KEYS), - "xts duplicated keys" }, - { 0, NULL } -}; - -#endif - -int ossl_err_load_PROV_strings(void) -{ -#ifndef OPENSSL_NO_ERR - if (ERR_reason_error_string(PROV_str_reasons[0].error) == NULL) - ERR_load_strings_const(PROV_str_reasons); -#endif - return 1; -} diff --git a/providers/common/securitycheck_default.c b/providers/common/securitycheck_default.c index ca8f0b497d340..865f684d578c1 100644 --- a/providers/common/securitycheck_default.c +++ b/providers/common/securitycheck_default.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/common/securitycheck_fips.c b/providers/common/securitycheck_fips.c index aa9136ef092ae..cf28532494724 100644 --- a/providers/common/securitycheck_fips.c +++ b/providers/common/securitycheck_fips.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/decoders.inc b/providers/decoders.inc index 767df65997634..70649cc6971d5 100644 --- a/providers/decoders.inc +++ b/providers/decoders.inc @@ -126,6 +126,45 @@ DECODER_w_structure("ML-DSA-65", der, SubjectPublicKeyInfo, ml_dsa_65, yes, "SPK DECODER_w_structure("ML-DSA-87", der, SubjectPublicKeyInfo, ml_dsa_87, yes, "SPKItoML-DSA-87-DER"), #endif /* OPENSSL_NO_ML_DSA */ +#ifndef OPENSSL_NO_COMPOSITE +DECODER_w_structure("ML-DSA-44-RSA2048-PSS-SHA256", der, PrivateKeyInfo, mldsa44_rsa2048_pss_sha256, no, "PKItoMLDSA44-RSA2048-PSS-SHA256-DER"), +DECODER_w_structure("ML-DSA-44-RSA2048-PSS-SHA256", der, SubjectPublicKeyInfo, mldsa44_rsa2048_pss_sha256, no, "SPKItoMLDSA44-RSA2048-PSS-SHA256-DER"), +DECODER_w_structure("ML-DSA-44-RSA2048-PKCS15-SHA256", der, PrivateKeyInfo, mldsa44_rsa2048_pkcs15_sha256, no, "PKItoMLDSA44-RSA2048-PKCS15-SHA256-DER"), +DECODER_w_structure("ML-DSA-44-RSA2048-PKCS15-SHA256", der, SubjectPublicKeyInfo, mldsa44_rsa2048_pkcs15_sha256, no, "SPKItoMLDSA44-RSA2048-PKCS15-SHA256-DER"), +DECODER_w_structure("ML-DSA-44-Ed25519-SHA512", der, PrivateKeyInfo, mldsa44_ed25519_sha512, no, "PKItoMLDSA44-Ed25519-SHA512-DER"), +DECODER_w_structure("ML-DSA-44-Ed25519-SHA512", der, SubjectPublicKeyInfo, mldsa44_ed25519_sha512, no, "SPKItoMLDSA44-Ed25519-SHA512-DER"), +DECODER_w_structure("ML-DSA-44-ECDSA-P256-SHA256", der, PrivateKeyInfo, mldsa44_ecdsa_p256_sha256, no, "PKItoMLDSA44-ECDSA-P256-SHA256-DER"), +DECODER_w_structure("ML-DSA-44-ECDSA-P256-SHA256", der, SubjectPublicKeyInfo, mldsa44_ecdsa_p256_sha256, no, "SPKItoMLDSA44-ECDSA-P256-SHA256-DER"), +DECODER_w_structure("ML-DSA-65-RSA3072-PSS-SHA512", der, PrivateKeyInfo, mldsa65_rsa3072_pss_sha512, no, "PKItoMLDSA65-RSA3072-PSS-SHA512-DER"), +DECODER_w_structure("ML-DSA-65-RSA3072-PSS-SHA512", der, SubjectPublicKeyInfo, mldsa65_rsa3072_pss_sha512, no, "SPKItoMLDSA65-RSA3072-PSS-SHA512-DER"), +DECODER_w_structure("ML-DSA-65-RSA3072-PKCS15-SHA512", der, PrivateKeyInfo, mldsa65_rsa3072_pkcs15_sha512, no, "PKItoMLDSA65-RSA3072-PKCS15-SHA512-DER"), +DECODER_w_structure("ML-DSA-65-RSA3072-PKCS15-SHA512", der, SubjectPublicKeyInfo, mldsa65_rsa3072_pkcs15_sha512, no, "SPKItoMLDSA65-RSA3072-PKCS15-SHA512-DER"), +DECODER_w_structure("ML-DSA-65-RSA4096-PSS-SHA512", der, PrivateKeyInfo, mldsa65_rsa4096_pss_sha512, no, "PKItoMLDSA65-RSA4096-PSS-SHA512-DER"), +DECODER_w_structure("ML-DSA-65-RSA4096-PSS-SHA512", der, SubjectPublicKeyInfo, mldsa65_rsa4096_pss_sha512, no, "SPKItoMLDSA65-RSA4096-PSS-SHA512-DER"), +DECODER_w_structure("ML-DSA-65-RSA4096-PKCS15-SHA512", der, PrivateKeyInfo, mldsa65_rsa4096_pkcs15_sha512, no, "PKItoMLDSA65-RSA4096-PKCS15-SHA512-DER"), +DECODER_w_structure("ML-DSA-65-RSA4096-PKCS15-SHA512", der, SubjectPublicKeyInfo, mldsa65_rsa4096_pkcs15_sha512, no, "SPKItoMLDSA65-RSA4096-PKCS15-SHA512-DER"), +DECODER_w_structure("ML-DSA-65-ECDSA-P256-SHA512", der, PrivateKeyInfo, mldsa65_ecdsa_p256_sha512, no, "PKItoMLDSA65-ECDSA-P256-SHA512-DER"), +DECODER_w_structure("ML-DSA-65-ECDSA-P256-SHA512", der, SubjectPublicKeyInfo, mldsa65_ecdsa_p256_sha512, no, "SPKItoMLDSA65-ECDSA-P256-SHA512-DER"), +DECODER_w_structure("ML-DSA-65-ECDSA-P384-SHA512", der, PrivateKeyInfo, mldsa65_ecdsa_p384_sha512, no, "PKItoMLDSA65-ECDSA-P384-SHA512-DER"), +DECODER_w_structure("ML-DSA-65-ECDSA-P384-SHA512", der, SubjectPublicKeyInfo, mldsa65_ecdsa_p384_sha512, no, "SPKItoMLDSA65-ECDSA-P384-SHA512-DER"), +DECODER_w_structure("ML-DSA-65-ECDSA-brainpoolP256r1-SHA512", der, PrivateKeyInfo, mldsa65_ecdsa_brainpoolP256r1_sha512, no, "PKItoMLDSA65-ECDSA-brainpoolP256r1-SHA512-DER"), +DECODER_w_structure("ML-DSA-65-ECDSA-brainpoolP256r1-SHA512", der, SubjectPublicKeyInfo, mldsa65_ecdsa_brainpoolP256r1_sha512, no, "SPKItoMLDSA65-ECDSA-brainpoolP256r1-SHA512-DER"), +DECODER_w_structure("ML-DSA-65-Ed25519-SHA512", der, PrivateKeyInfo, mldsa65_ed25519_sha512, no, "PKItoMLDSA65-Ed25519-SHA512-DER"), +DECODER_w_structure("ML-DSA-65-Ed25519-SHA512", der, SubjectPublicKeyInfo, mldsa65_ed25519_sha512, no, "SPKItoMLDSA65-Ed25519-SHA512-DER"), +DECODER_w_structure("ML-DSA-87-ECDSA-P384-SHA512", der, PrivateKeyInfo, mldsa87_ecdsa_p384_sha512, no, "PKItoMLDSA87-ECDSA-P384-SHA512-DER"), +DECODER_w_structure("ML-DSA-87-ECDSA-P384-SHA512", der, SubjectPublicKeyInfo, mldsa87_ecdsa_p384_sha512, no, "SPKItoMLDSA87-ECDSA-P384-SHA512-DER"), +DECODER_w_structure("ML-DSA-87-ECDSA-brainpoolP384r1-SHA512", der, PrivateKeyInfo, mldsa87_ecdsa_brainpoolP384r1_sha512, no, "PKItoMLDSA87-ECDSA-brainpoolP384r1-SHA512-DER"), +DECODER_w_structure("ML-DSA-87-ECDSA-brainpoolP384r1-SHA512", der, SubjectPublicKeyInfo, mldsa87_ecdsa_brainpoolP384r1_sha512, no, "SPKItoMLDSA87-ECDSA-brainpoolP384r1-SHA512-DER"), +DECODER_w_structure("ML-DSA-87-Ed448-SHAKE256", der, PrivateKeyInfo, mldsa87_ed448_shake256, no, "PKItoMLDSA87-Ed448-SHAKE256-DER"), +DECODER_w_structure("ML-DSA-87-Ed448-SHAKE256", der, SubjectPublicKeyInfo, mldsa87_ed448_shake256, no, "SPKItoMLDSA87-Ed448-SHAKE256-DER"), +DECODER_w_structure("ML-DSA-87-RSA3072-PSS-SHA512", der, PrivateKeyInfo, mldsa87_rsa3072_pss_sha512, no, "PKItoMLDSA87-RSA3072-PSS-SHA512-DER"), +DECODER_w_structure("ML-DSA-87-RSA3072-PSS-SHA512", der, SubjectPublicKeyInfo, mldsa87_rsa3072_pss_sha512, no, "SPKItoMLDSA87-RSA3072-PSS-SHA512-DER"), +DECODER_w_structure("ML-DSA-87-RSA4096-PSS-SHA512", der, PrivateKeyInfo, mldsa87_rsa4096_pss_sha512, no, "PKItoMLDSA87-RSA4096-PSS-SHA512-DER"), +DECODER_w_structure("ML-DSA-87-RSA4096-PSS-SHA512", der, SubjectPublicKeyInfo, mldsa87_rsa4096_pss_sha512, no, "SPKItoMLDSA87-RSA4096-PSS-SHA512-DER"), +DECODER_w_structure("ML-DSA-87-ECDSA-P521-SHA512", der, PrivateKeyInfo, mldsa87_ecdsa_p521_sha512, no, "PKItoMLDSA87-ECDSA-P521-SHA512-DER"), +DECODER_w_structure("ML-DSA-87-ECDSA-P521-SHA512", der, SubjectPublicKeyInfo, mldsa87_ecdsa_p521_sha512, no, "SPKItoMLDSA87-ECDSA-P521-SHA512-DER"), +#endif /* OPENSSL_NO_COMPOSITE */ + #ifndef OPENSSL_NO_LMS DECODER("LMS", xdr, lms, yes, "XDRtoLMS"), DECODER_w_structure("LMS", der, SubjectPublicKeyInfo, lms, yes, "SPKItoLMS-DER"), diff --git a/providers/defltprov.c b/providers/defltprov.c index 1f39b34d6e1f6..6130d5e1a3196 100644 --- a/providers/defltprov.c +++ b/providers/defltprov.c @@ -205,6 +205,9 @@ static const OSSL_ALGORITHM_CAPABLE deflt_ciphers[] = { ALG(PROV_NAMES_AES_192_GCM_SIV, ossl_aes192gcm_siv_functions), ALG(PROV_NAMES_AES_256_GCM_SIV, ossl_aes256gcm_siv_functions), #endif /* OPENSSL_NO_SIV */ +#ifndef OPENSSL_NO_ASCON128 + ALG(PROV_NAMES_ASCON_AEAD128, ossl_ascon_aead128_functions), +#endif /* OPENSSL_NO_ASCON128 */ ALG(PROV_NAMES_AES_256_GCM, ossl_aes256gcm_functions), ALG(PROV_NAMES_AES_192_GCM, ossl_aes192gcm_functions), ALG(PROV_NAMES_AES_128_GCM, ossl_aes128gcm_functions), @@ -499,7 +502,63 @@ static const OSSL_ALGORITHM deflt_signature[] = { { PROV_NAMES_ML_DSA_44, "provider=default", ossl_ml_dsa_44_signature_functions }, { PROV_NAMES_ML_DSA_65, "provider=default", ossl_ml_dsa_65_signature_functions }, { PROV_NAMES_ML_DSA_87, "provider=default", ossl_ml_dsa_87_signature_functions }, -#endif +#ifndef OPENSSL_NO_COMPOSITE + { PROV_NAMES_MLDSA44_RSA2048_PSS_SHA256, "provider=default", + ossl_mldsa44_rsa2048_pss_sha256_signature_functions, + PROV_DESCS_MLDSA44_RSA2048_PSS_SHA256 }, + { PROV_NAMES_MLDSA44_RSA2048_PKCS15_SHA256, "provider=default", + ossl_mldsa44_rsa2048_pkcs15_sha256_signature_functions, + PROV_DESCS_MLDSA44_RSA2048_PKCS15_SHA256 }, + { PROV_NAMES_MLDSA44_ED25519_SHA512, "provider=default", + ossl_mldsa44_ed25519_sha512_signature_functions, + PROV_DESCS_MLDSA44_ED25519_SHA512 }, + { PROV_NAMES_MLDSA44_ECDSA_P256_SHA256, "provider=default", + ossl_mldsa44_ecdsa_p256_sha256_signature_functions, + PROV_DESCS_MLDSA44_ECDSA_P256_SHA256 }, + { PROV_NAMES_MLDSA65_RSA3072_PSS_SHA512, "provider=default", + ossl_mldsa65_rsa3072_pss_sha512_signature_functions, + PROV_DESCS_MLDSA65_RSA3072_PSS_SHA512 }, + { PROV_NAMES_MLDSA65_RSA3072_PKCS15_SHA512, "provider=default", + ossl_mldsa65_rsa3072_pkcs15_sha512_signature_functions, + PROV_DESCS_MLDSA65_RSA3072_PKCS15_SHA512 }, + { PROV_NAMES_MLDSA65_RSA4096_PSS_SHA512, "provider=default", + ossl_mldsa65_rsa4096_pss_sha512_signature_functions, + PROV_DESCS_MLDSA65_RSA4096_PSS_SHA512 }, + { PROV_NAMES_MLDSA65_RSA4096_PKCS15_SHA512, "provider=default", + ossl_mldsa65_rsa4096_pkcs15_sha512_signature_functions, + PROV_DESCS_MLDSA65_RSA4096_PKCS15_SHA512 }, + { PROV_NAMES_MLDSA65_ECDSA_P256_SHA512, "provider=default", + ossl_mldsa65_ecdsa_p256_sha512_signature_functions, + PROV_DESCS_MLDSA65_ECDSA_P256_SHA512 }, + { PROV_NAMES_MLDSA65_ECDSA_P384_SHA512, "provider=default", + ossl_mldsa65_ecdsa_p384_sha512_signature_functions, + PROV_DESCS_MLDSA65_ECDSA_P384_SHA512 }, + { PROV_NAMES_MLDSA65_ECDSA_BRAINPOOLP256R1_SHA512, "provider=default", + ossl_mldsa65_ecdsa_brainpoolP256r1_sha512_signature_functions, + PROV_DESCS_MLDSA65_ECDSA_BRAINPOOLP256R1_SHA512 }, + { PROV_NAMES_MLDSA65_ED25519_SHA512, "provider=default", + ossl_mldsa65_ed25519_sha512_signature_functions, + PROV_DESCS_MLDSA65_ED25519_SHA512 }, + { PROV_NAMES_MLDSA87_ECDSA_P384_SHA512, "provider=default", + ossl_mldsa87_ecdsa_p384_sha512_signature_functions, + PROV_DESCS_MLDSA87_ECDSA_P384_SHA512 }, + { PROV_NAMES_MLDSA87_ECDSA_BRAINPOOLP384R1_SHA512, "provider=default", + ossl_mldsa87_ecdsa_brainpoolP384r1_sha512_signature_functions, + PROV_DESCS_MLDSA87_ECDSA_BRAINPOOLP384R1_SHA512 }, + { PROV_NAMES_MLDSA87_ED448_SHAKE256, "provider=default", + ossl_mldsa87_ed448_shake256_signature_functions, + PROV_DESCS_MLDSA87_ED448_SHAKE256 }, + { PROV_NAMES_MLDSA87_RSA3072_PSS_SHA512, "provider=default", + ossl_mldsa87_rsa3072_pss_sha512_signature_functions, + PROV_DESCS_MLDSA87_RSA3072_PSS_SHA512 }, + { PROV_NAMES_MLDSA87_RSA4096_PSS_SHA512, "provider=default", + ossl_mldsa87_rsa4096_pss_sha512_signature_functions, + PROV_DESCS_MLDSA87_RSA4096_PSS_SHA512 }, + { PROV_NAMES_MLDSA87_ECDSA_P521_SHA512, "provider=default", + ossl_mldsa87_ecdsa_p521_sha512_signature_functions, + PROV_DESCS_MLDSA87_ECDSA_P521_SHA512 }, +#endif /* OPENSSL_NO_COMPOSITE */ +#endif /* OPENSSL_NO_ML_DSA */ { PROV_NAMES_HMAC, "provider=default", ossl_mac_legacy_hmac_signature_functions }, #ifndef OPENSSL_NO_SIPHASH { PROV_NAMES_SIPHASH, "provider=default", @@ -566,10 +625,12 @@ static const OSSL_ALGORITHM deflt_asym_kem[] = { { PROV_NAMES_ML_KEM_768, "provider=default", ossl_ml_kem_asym_kem_functions }, { PROV_NAMES_ML_KEM_1024, "provider=default", ossl_ml_kem_asym_kem_functions }, #if !defined(OPENSSL_NO_ECX) + { PROV_NAMES_MLKEM512X25519, "provider=default", ossl_mlx_kem_asym_kem_functions }, { PROV_NAMES_X25519MLKEM768, "provider=default", ossl_mlx_kem_asym_kem_functions }, { PROV_NAMES_X448MLKEM1024, "provider=default", ossl_mlx_kem_asym_kem_functions }, #endif #if !defined(OPENSSL_NO_EC) + { PROV_NAMES_SecP256r1MLKEM512, "provider=default", ossl_mlx_kem_asym_kem_functions }, { PROV_NAMES_SecP256r1MLKEM768, "provider=default", ossl_mlx_kem_asym_kem_functions }, { PROV_NAMES_SecP384r1MLKEM1024, "provider=default", ossl_mlx_kem_asym_kem_functions }, #endif @@ -616,6 +677,26 @@ static const OSSL_ALGORITHM deflt_keymgmt[] = { PROV_DESCS_ML_DSA_65 }, { PROV_NAMES_ML_DSA_87, "provider=default", ossl_ml_dsa_87_keymgmt_functions, PROV_DESCS_ML_DSA_87 }, +#ifndef OPENSSL_NO_COMPOSITE + { PROV_NAMES_MLDSA44_RSA2048_PSS_SHA256, "provider=default", ossl_mldsa44_rsa2048_pss_sha256_keymgmt_functions, PROV_DESCS_MLDSA44_RSA2048_PSS_SHA256 }, + { PROV_NAMES_MLDSA44_RSA2048_PKCS15_SHA256, "provider=default", ossl_mldsa44_rsa2048_pkcs15_sha256_keymgmt_functions, PROV_DESCS_MLDSA44_RSA2048_PKCS15_SHA256 }, + { PROV_NAMES_MLDSA44_ED25519_SHA512, "provider=default", ossl_mldsa44_ed25519_sha512_keymgmt_functions, PROV_DESCS_MLDSA44_ED25519_SHA512 }, + { PROV_NAMES_MLDSA44_ECDSA_P256_SHA256, "provider=default", ossl_mldsa44_ecdsa_p256_sha256_keymgmt_functions, PROV_DESCS_MLDSA44_ECDSA_P256_SHA256 }, + { PROV_NAMES_MLDSA65_RSA3072_PSS_SHA512, "provider=default", ossl_mldsa65_rsa3072_pss_sha512_keymgmt_functions, PROV_DESCS_MLDSA65_RSA3072_PSS_SHA512 }, + { PROV_NAMES_MLDSA65_RSA3072_PKCS15_SHA512, "provider=default", ossl_mldsa65_rsa3072_pkcs15_sha512_keymgmt_functions, PROV_DESCS_MLDSA65_RSA3072_PKCS15_SHA512 }, + { PROV_NAMES_MLDSA65_RSA4096_PSS_SHA512, "provider=default", ossl_mldsa65_rsa4096_pss_sha512_keymgmt_functions, PROV_DESCS_MLDSA65_RSA4096_PSS_SHA512 }, + { PROV_NAMES_MLDSA65_RSA4096_PKCS15_SHA512, "provider=default", ossl_mldsa65_rsa4096_pkcs15_sha512_keymgmt_functions, PROV_DESCS_MLDSA65_RSA4096_PKCS15_SHA512 }, + { PROV_NAMES_MLDSA65_ECDSA_P256_SHA512, "provider=default", ossl_mldsa65_ecdsa_p256_sha512_keymgmt_functions, PROV_DESCS_MLDSA65_ECDSA_P256_SHA512 }, + { PROV_NAMES_MLDSA65_ECDSA_P384_SHA512, "provider=default", ossl_mldsa65_ecdsa_p384_sha512_keymgmt_functions, PROV_DESCS_MLDSA65_ECDSA_P384_SHA512 }, + { PROV_NAMES_MLDSA65_ECDSA_BRAINPOOLP256R1_SHA512, "provider=default", ossl_mldsa65_ecdsa_brainpoolP256r1_sha512_keymgmt_functions, PROV_DESCS_MLDSA65_ECDSA_BRAINPOOLP256R1_SHA512 }, + { PROV_NAMES_MLDSA65_ED25519_SHA512, "provider=default", ossl_mldsa65_ed25519_sha512_keymgmt_functions, PROV_DESCS_MLDSA65_ED25519_SHA512 }, + { PROV_NAMES_MLDSA87_ECDSA_P384_SHA512, "provider=default", ossl_mldsa87_ecdsa_p384_sha512_keymgmt_functions, PROV_DESCS_MLDSA87_ECDSA_P384_SHA512 }, + { PROV_NAMES_MLDSA87_ECDSA_BRAINPOOLP384R1_SHA512, "provider=default", ossl_mldsa87_ecdsa_brainpoolP384r1_sha512_keymgmt_functions, PROV_DESCS_MLDSA87_ECDSA_BRAINPOOLP384R1_SHA512 }, + { PROV_NAMES_MLDSA87_ED448_SHAKE256, "provider=default", ossl_mldsa87_ed448_shake256_keymgmt_functions, PROV_DESCS_MLDSA87_ED448_SHAKE256 }, + { PROV_NAMES_MLDSA87_RSA3072_PSS_SHA512, "provider=default", ossl_mldsa87_rsa3072_pss_sha512_keymgmt_functions, PROV_DESCS_MLDSA87_RSA3072_PSS_SHA512 }, + { PROV_NAMES_MLDSA87_RSA4096_PSS_SHA512, "provider=default", ossl_mldsa87_rsa4096_pss_sha512_keymgmt_functions, PROV_DESCS_MLDSA87_RSA4096_PSS_SHA512 }, + { PROV_NAMES_MLDSA87_ECDSA_P521_SHA512, "provider=default", ossl_mldsa87_ecdsa_p521_sha512_keymgmt_functions, PROV_DESCS_MLDSA87_ECDSA_P521_SHA512 }, +#endif /* OPENSSL_NO_COMPOSITE */ #endif /* OPENSSL_NO_ML_DSA */ { PROV_NAMES_TLS1_PRF, "provider=default", ossl_kdf_keymgmt_functions, PROV_DESCS_TLS1_PRF_SIGN }, @@ -657,12 +738,16 @@ static const OSSL_ALGORITHM deflt_keymgmt[] = { { PROV_NAMES_ML_KEM_1024, "provider=default", ossl_ml_kem_1024_keymgmt_functions, PROV_DESCS_ML_KEM_1024 }, #if !defined(OPENSSL_NO_ECX) + { PROV_NAMES_MLKEM512X25519, "provider=default", ossl_mlx_x25519_512_kem_kmgmt_functions, + PROV_DESCS_MLKEM512X25519 }, { PROV_NAMES_X25519MLKEM768, "provider=default", ossl_mlx_x25519_kem_kmgmt_functions, PROV_DESCS_X25519MLKEM768 }, { PROV_NAMES_X448MLKEM1024, "provider=default", ossl_mlx_x448_kem_kmgmt_functions, PROV_DESCS_X448MLKEM1024 }, #endif #if !defined(OPENSSL_NO_EC) + { PROV_NAMES_SecP256r1MLKEM512, "provider=default", ossl_mlx_p256_512_kem_kmgmt_functions, + PROV_DESCS_SecP256r1MLKEM512 }, { PROV_NAMES_SecP256r1MLKEM768, "provider=default", ossl_mlx_p256_kem_kmgmt_functions, PROV_DESCS_SecP256r1MLKEM768 }, { PROV_NAMES_SecP384r1MLKEM1024, "provider=default", ossl_mlx_p384_kem_kmgmt_functions, diff --git a/providers/encoders.inc b/providers/encoders.inc index 1ab0d3a75d67b..04c5baa885da3 100644 --- a/providers/encoders.inc +++ b/providers/encoders.inc @@ -375,6 +375,152 @@ ENCODER_w_structure("ML-DSA-87", ml_dsa_87, yes, der, SubjectPublicKeyInfo), ENCODER_w_structure("ML-DSA-87", ml_dsa_87, yes, pem, SubjectPublicKeyInfo), # endif /* OPENSSL_NO_ML_DSA */ +# ifndef OPENSSL_NO_COMPOSITE +ENCODER_w_structure("ML-DSA-44-RSA2048-PSS-SHA256", mldsa44_rsa2048_pss_sha256, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-RSA2048-PSS-SHA256", mldsa44_rsa2048_pss_sha256, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-RSA2048-PSS-SHA256", mldsa44_rsa2048_pss_sha256, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-RSA2048-PSS-SHA256", mldsa44_rsa2048_pss_sha256, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-RSA2048-PSS-SHA256", mldsa44_rsa2048_pss_sha256, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-44-RSA2048-PSS-SHA256", mldsa44_rsa2048_pss_sha256, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-44-RSA2048-PSS-SHA256", mldsa44_rsa2048_pss_sha256, yes), + +ENCODER_w_structure("ML-DSA-44-RSA2048-PKCS15-SHA256", mldsa44_rsa2048_pkcs15_sha256, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-RSA2048-PKCS15-SHA256", mldsa44_rsa2048_pkcs15_sha256, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-RSA2048-PKCS15-SHA256", mldsa44_rsa2048_pkcs15_sha256, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-RSA2048-PKCS15-SHA256", mldsa44_rsa2048_pkcs15_sha256, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-RSA2048-PKCS15-SHA256", mldsa44_rsa2048_pkcs15_sha256, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-44-RSA2048-PKCS15-SHA256", mldsa44_rsa2048_pkcs15_sha256, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-44-RSA2048-PKCS15-SHA256", mldsa44_rsa2048_pkcs15_sha256, yes), + +ENCODER_w_structure("ML-DSA-44-Ed25519-SHA512", mldsa44_ed25519_sha512, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-Ed25519-SHA512", mldsa44_ed25519_sha512, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-Ed25519-SHA512", mldsa44_ed25519_sha512, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-Ed25519-SHA512", mldsa44_ed25519_sha512, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-Ed25519-SHA512", mldsa44_ed25519_sha512, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-44-Ed25519-SHA512", mldsa44_ed25519_sha512, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-44-Ed25519-SHA512", mldsa44_ed25519_sha512, yes), + +ENCODER_w_structure("ML-DSA-44-ECDSA-P256-SHA256", mldsa44_ecdsa_p256_sha256, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-ECDSA-P256-SHA256", mldsa44_ecdsa_p256_sha256, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-ECDSA-P256-SHA256", mldsa44_ecdsa_p256_sha256, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-ECDSA-P256-SHA256", mldsa44_ecdsa_p256_sha256, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-44-ECDSA-P256-SHA256", mldsa44_ecdsa_p256_sha256, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-44-ECDSA-P256-SHA256", mldsa44_ecdsa_p256_sha256, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-44-ECDSA-P256-SHA256", mldsa44_ecdsa_p256_sha256, yes), + +ENCODER_w_structure("ML-DSA-65-RSA3072-PSS-SHA512", mldsa65_rsa3072_pss_sha512, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA3072-PSS-SHA512", mldsa65_rsa3072_pss_sha512, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA3072-PSS-SHA512", mldsa65_rsa3072_pss_sha512, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA3072-PSS-SHA512", mldsa65_rsa3072_pss_sha512, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA3072-PSS-SHA512", mldsa65_rsa3072_pss_sha512, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA3072-PSS-SHA512", mldsa65_rsa3072_pss_sha512, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-65-RSA3072-PSS-SHA512", mldsa65_rsa3072_pss_sha512, yes), + +ENCODER_w_structure("ML-DSA-65-RSA3072-PKCS15-SHA512", mldsa65_rsa3072_pkcs15_sha512, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA3072-PKCS15-SHA512", mldsa65_rsa3072_pkcs15_sha512, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA3072-PKCS15-SHA512", mldsa65_rsa3072_pkcs15_sha512, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA3072-PKCS15-SHA512", mldsa65_rsa3072_pkcs15_sha512, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA3072-PKCS15-SHA512", mldsa65_rsa3072_pkcs15_sha512, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA3072-PKCS15-SHA512", mldsa65_rsa3072_pkcs15_sha512, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-65-RSA3072-PKCS15-SHA512", mldsa65_rsa3072_pkcs15_sha512, yes), + +ENCODER_w_structure("ML-DSA-65-RSA4096-PSS-SHA512", mldsa65_rsa4096_pss_sha512, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA4096-PSS-SHA512", mldsa65_rsa4096_pss_sha512, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA4096-PSS-SHA512", mldsa65_rsa4096_pss_sha512, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA4096-PSS-SHA512", mldsa65_rsa4096_pss_sha512, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA4096-PSS-SHA512", mldsa65_rsa4096_pss_sha512, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA4096-PSS-SHA512", mldsa65_rsa4096_pss_sha512, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-65-RSA4096-PSS-SHA512", mldsa65_rsa4096_pss_sha512, yes), + +ENCODER_w_structure("ML-DSA-65-RSA4096-PKCS15-SHA512", mldsa65_rsa4096_pkcs15_sha512, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA4096-PKCS15-SHA512", mldsa65_rsa4096_pkcs15_sha512, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA4096-PKCS15-SHA512", mldsa65_rsa4096_pkcs15_sha512, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA4096-PKCS15-SHA512", mldsa65_rsa4096_pkcs15_sha512, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA4096-PKCS15-SHA512", mldsa65_rsa4096_pkcs15_sha512, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-65-RSA4096-PKCS15-SHA512", mldsa65_rsa4096_pkcs15_sha512, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-65-RSA4096-PKCS15-SHA512", mldsa65_rsa4096_pkcs15_sha512, yes), + +ENCODER_w_structure("ML-DSA-65-ECDSA-P256-SHA512", mldsa65_ecdsa_p256_sha512, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-ECDSA-P256-SHA512", mldsa65_ecdsa_p256_sha512, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-ECDSA-P256-SHA512", mldsa65_ecdsa_p256_sha512, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-ECDSA-P256-SHA512", mldsa65_ecdsa_p256_sha512, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-ECDSA-P256-SHA512", mldsa65_ecdsa_p256_sha512, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-65-ECDSA-P256-SHA512", mldsa65_ecdsa_p256_sha512, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-65-ECDSA-P256-SHA512", mldsa65_ecdsa_p256_sha512, yes), + +ENCODER_w_structure("ML-DSA-65-ECDSA-P384-SHA512", mldsa65_ecdsa_p384_sha512, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-ECDSA-P384-SHA512", mldsa65_ecdsa_p384_sha512, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-ECDSA-P384-SHA512", mldsa65_ecdsa_p384_sha512, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-ECDSA-P384-SHA512", mldsa65_ecdsa_p384_sha512, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-ECDSA-P384-SHA512", mldsa65_ecdsa_p384_sha512, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-65-ECDSA-P384-SHA512", mldsa65_ecdsa_p384_sha512, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-65-ECDSA-P384-SHA512", mldsa65_ecdsa_p384_sha512, yes), + +ENCODER_w_structure("ML-DSA-65-ECDSA-brainpoolP256r1-SHA512", mldsa65_ecdsa_brainpoolP256r1_sha512, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-ECDSA-brainpoolP256r1-SHA512", mldsa65_ecdsa_brainpoolP256r1_sha512, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-ECDSA-brainpoolP256r1-SHA512", mldsa65_ecdsa_brainpoolP256r1_sha512, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-ECDSA-brainpoolP256r1-SHA512", mldsa65_ecdsa_brainpoolP256r1_sha512, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-ECDSA-brainpoolP256r1-SHA512", mldsa65_ecdsa_brainpoolP256r1_sha512, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-65-ECDSA-brainpoolP256r1-SHA512", mldsa65_ecdsa_brainpoolP256r1_sha512, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-65-ECDSA-brainpoolP256r1-SHA512", mldsa65_ecdsa_brainpoolP256r1_sha512, yes), + +ENCODER_w_structure("ML-DSA-65-Ed25519-SHA512", mldsa65_ed25519_sha512, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-Ed25519-SHA512", mldsa65_ed25519_sha512, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-Ed25519-SHA512", mldsa65_ed25519_sha512, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-Ed25519-SHA512", mldsa65_ed25519_sha512, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-65-Ed25519-SHA512", mldsa65_ed25519_sha512, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-65-Ed25519-SHA512", mldsa65_ed25519_sha512, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-65-Ed25519-SHA512", mldsa65_ed25519_sha512, yes), + +ENCODER_w_structure("ML-DSA-87-ECDSA-P384-SHA512", mldsa87_ecdsa_p384_sha512, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-ECDSA-P384-SHA512", mldsa87_ecdsa_p384_sha512, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-ECDSA-P384-SHA512", mldsa87_ecdsa_p384_sha512, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-ECDSA-P384-SHA512", mldsa87_ecdsa_p384_sha512, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-ECDSA-P384-SHA512", mldsa87_ecdsa_p384_sha512, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-87-ECDSA-P384-SHA512", mldsa87_ecdsa_p384_sha512, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-87-ECDSA-P384-SHA512", mldsa87_ecdsa_p384_sha512, yes), + +ENCODER_w_structure("ML-DSA-87-ECDSA-brainpoolP384r1-SHA512", mldsa87_ecdsa_brainpoolP384r1_sha512, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-ECDSA-brainpoolP384r1-SHA512", mldsa87_ecdsa_brainpoolP384r1_sha512, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-ECDSA-brainpoolP384r1-SHA512", mldsa87_ecdsa_brainpoolP384r1_sha512, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-ECDSA-brainpoolP384r1-SHA512", mldsa87_ecdsa_brainpoolP384r1_sha512, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-ECDSA-brainpoolP384r1-SHA512", mldsa87_ecdsa_brainpoolP384r1_sha512, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-87-ECDSA-brainpoolP384r1-SHA512", mldsa87_ecdsa_brainpoolP384r1_sha512, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-87-ECDSA-brainpoolP384r1-SHA512", mldsa87_ecdsa_brainpoolP384r1_sha512, yes), + +ENCODER_w_structure("ML-DSA-87-Ed448-SHAKE256", mldsa87_ed448_shake256, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-Ed448-SHAKE256", mldsa87_ed448_shake256, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-Ed448-SHAKE256", mldsa87_ed448_shake256, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-Ed448-SHAKE256", mldsa87_ed448_shake256, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-Ed448-SHAKE256", mldsa87_ed448_shake256, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-87-Ed448-SHAKE256", mldsa87_ed448_shake256, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-87-Ed448-SHAKE256", mldsa87_ed448_shake256, yes), + +ENCODER_w_structure("ML-DSA-87-RSA3072-PSS-SHA512", mldsa87_rsa3072_pss_sha512, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-RSA3072-PSS-SHA512", mldsa87_rsa3072_pss_sha512, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-RSA3072-PSS-SHA512", mldsa87_rsa3072_pss_sha512, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-RSA3072-PSS-SHA512", mldsa87_rsa3072_pss_sha512, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-RSA3072-PSS-SHA512", mldsa87_rsa3072_pss_sha512, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-87-RSA3072-PSS-SHA512", mldsa87_rsa3072_pss_sha512, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-87-RSA3072-PSS-SHA512", mldsa87_rsa3072_pss_sha512, yes), + +ENCODER_w_structure("ML-DSA-87-RSA4096-PSS-SHA512", mldsa87_rsa4096_pss_sha512, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-RSA4096-PSS-SHA512", mldsa87_rsa4096_pss_sha512, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-RSA4096-PSS-SHA512", mldsa87_rsa4096_pss_sha512, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-RSA4096-PSS-SHA512", mldsa87_rsa4096_pss_sha512, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-RSA4096-PSS-SHA512", mldsa87_rsa4096_pss_sha512, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-87-RSA4096-PSS-SHA512", mldsa87_rsa4096_pss_sha512, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-87-RSA4096-PSS-SHA512", mldsa87_rsa4096_pss_sha512, yes), + +ENCODER_w_structure("ML-DSA-87-ECDSA-P521-SHA512", mldsa87_ecdsa_p521_sha512, yes, der, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-ECDSA-P521-SHA512", mldsa87_ecdsa_p521_sha512, yes, pem, EncryptedPrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-ECDSA-P521-SHA512", mldsa87_ecdsa_p521_sha512, yes, der, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-ECDSA-P521-SHA512", mldsa87_ecdsa_p521_sha512, yes, pem, PrivateKeyInfo), +ENCODER_w_structure("ML-DSA-87-ECDSA-P521-SHA512", mldsa87_ecdsa_p521_sha512, yes, der, SubjectPublicKeyInfo), +ENCODER_w_structure("ML-DSA-87-ECDSA-P521-SHA512", mldsa87_ecdsa_p521_sha512, yes, pem, SubjectPublicKeyInfo), +ENCODER_TEXT("ML-DSA-87-ECDSA-P521-SHA512", mldsa87_ecdsa_p521_sha512, yes), +# endif /* OPENSSL_NO_COMPOSITE */ + /* * Entries for key type specific output formats. These are exactly the * same as the type specific above, except that they use the key type diff --git a/providers/fips-sources.checksums b/providers/fips-sources.checksums index 598c3bb44dce2..c7bd3a9e07435 100644 --- a/providers/fips-sources.checksums +++ b/providers/fips-sources.checksums @@ -1,600 +1,582 @@ 1adbe13eff4750e389446101753e40402977dacf1493eb7ba053654bb37bd0e8 crypto/aes/aes_cbc.c -170697bf22866d22f25a886a2f3c7206139c34bfab56fb1d57564995ae57a38c crypto/aes/aes_core.c +b77933ece99f9d639fa7aafc5cf4b5387c88febff563815434f73f80c0e8b4a7 crypto/aes/aes_cbc_vaes_intrinsic.c +a4b51eefc365fc994754d24237dca9308f0570c6329c51b493163cd1c343fdf7 crypto/aes/aes_core.c 3fac41ce96acb9189eac2d5571425c3ff33a34c884ae7e275e1fd3068b5fc662 crypto/aes/aes_ecb.c -da4942231014063d9e4fe1db91b6eb1b8f233904d169f3f1b8be7c6a59728d2e crypto/aes/aes_local.h +88204cb877dec5929e1f89dea7bc8bb3f453c993f3a05e0729d083cdb707dce7 crypto/aes/aes_local.h 7414fa4526ba20ee966125e8f7e428e4c75cd9021a79f1151a4bacb28d2f10da crypto/aes/aes_misc.c 793c1af13d28ec05895c2d33e2882df4cda6361004a9e0c6025447353ae86331 crypto/aes/asm/aes-586.pl -bbab787ebab9385502f5dd10ef63fd99e7bcca4e786d8a16981fe830581fc8db crypto/aes/asm/aes-armv4.pl -96e1ce4849089b7a467a4f622aec668a63624876a8b40cba26e84e7b471261ae crypto/aes/asm/aes-c64xplus.pl -4371307ab7dc22934dc206174fbe53bacbc28b54edc30544d53d637d3c0ebc8b crypto/aes/asm/aes-cfb-avx512.pl +b525b8796594270ecb9e43fdfe4c8934da916bd5c3f22b80868d10f0e5df200e crypto/aes/asm/aes-armv4.pl +579c923246d72d5ef0b9a56319c7922361fdb47a519362e2e60eb98d1ef47af5 crypto/aes/asm/aes-c64xplus.pl +cf2acf645134b87d8caf51764e08786ae28cc825bd64b460bad589d1ce9605a1 crypto/aes/asm/aes-cbc-vaes-x86_64.pl +88a6d4aba43ce09d2e40a7b234cdfeb51139f1575de32f88527eda4b729da533 crypto/aes/asm/aes-cfb-avx512.pl d0fa153afa8b6d86f5dd5e8b472458913d25a553425b0d4189e405eeca65b313 crypto/aes/asm/aes-ia64.S -b4ef595194fe1692e1ab2b561f385da01b277cf004902e8fc99e8ac5389bbd35 crypto/aes/asm/aes-mips.pl -aec8e840e21399d82a8727e9e1b545c78e5672bfeaa43209399ff5d802a281af crypto/aes/asm/aes-parisc.pl -37236228f6414d932fada6e5a7dca7d711c1de754672064e2aff79ec9e15fc72 crypto/aes/asm/aes-ppc.pl -e169a64f92b984f51792bf9bc491e54fbf1af52da76610c5ef1da0cd72893250 crypto/aes/asm/aes-riscv32-zkn.pl -5718962a86f1d737b410366280416a0595c7d8df96bd2e58c4c0d7289389d200 crypto/aes/asm/aes-riscv64-zkn.pl -8179f94715211cf8d69f17b5a785e4243f96d0728f31038e0016ad4fd860630c crypto/aes/asm/aes-riscv64-zvbb-zvkg-zvkned.pl -6a252373a3c20ab39b9e343b924af2182a1804a2c426b952d655c373927befe9 crypto/aes/asm/aes-riscv64-zvkb-zvkned.pl -3d185c92a25ba0815e05c3b55f6667c510703ed74dabd6e2f41238968e69cb31 crypto/aes/asm/aes-riscv64-zvkned.pl -ff7c8f37bbbdb7e1d3620506ee289651db8d8eda0675afb49de5ff3f6aeba6ab crypto/aes/asm/aes-riscv64.pl -79db6f8ca2c6aa40206fdd9882bbe67d5dd4089af8fe709dbee7d1ed6a0e89ff crypto/aes/asm/aes-s390x.pl -1d1fc6fc586d4f7268e7896729a37dec7bf2d7a5cbc13fe4a6654d31d6776688 crypto/aes/asm/aes-sha1-armv8.pl -442ace59e2f9a017fb0501a6e87cf78f2e90dd95e1d5406537730f1657b7872f crypto/aes/asm/aes-sha256-armv8.pl -67474f4cb9afe42c29d22400115ef5b900c4c30862681e26c4ff567edae0fdbb crypto/aes/asm/aes-sha512-armv8.pl -133ba35d77002abcd430414749c4e98c4a319630da898e45ff8dbc5800176df1 crypto/aes/asm/aes-sparcv9.pl -e507d1be7b7a1b2c35f8309f195de9edbf1f30891b99684c834b32f950f51970 crypto/aes/asm/aes-x86_64.pl -28dfb1a91d8b71287957960ee8d573a8f00065c96a9ee8af3f625ab4af769541 crypto/aes/asm/aesfx-sparcv9.pl -ab94a27e533e164bcf09898a6f6019f43609d51a3b374cf75482dcf2914d464e crypto/aes/asm/aesni-mb-x86_64.pl -a4ad4aa82414421416d416f58eb57a2a607c8d08c0ddd393450043f15415c35c crypto/aes/asm/aesni-sha1-x86_64.pl -c4b89a809a7796dede1b1937e53e892a891afc74901a1c963b960c1e3f9281f0 crypto/aes/asm/aesni-sha256-x86_64.pl +b812d010454eb3ed90f6ba44dc184a6768a5c007532739b84be94ef96b739110 crypto/aes/asm/aes-mips.pl +a8c16bb38388f8344dd32ef3186147c2c45f5943f0db6a323d1656e539ba229c crypto/aes/asm/aes-parisc.pl +47a648f58f6cc46a64be579b1a1499645699bd55ff348fb814ac72459714e87e crypto/aes/asm/aes-ppc.pl +f8cc2144b6cc9998d2c55ef446e451a31edde01eae624cb23de02b6b25b82420 crypto/aes/asm/aes-riscv32-zkn.pl +fe42d33e668beeadd43aa7e67cbe82d3ce3b92c3223c1cc0a34d5cac5b5d501d crypto/aes/asm/aes-riscv64-zkn.pl +88de0ee89df94d8514fcbfb8c3714701318eb07599a5f5ae39894bd29e9bf6ad crypto/aes/asm/aes-riscv64-zvbb-zvkg-zvkned.pl +ecd9bdfaf25cdd3d8ec0c50cb4306d98374da1c6056e27e0cf31a057dc5ee150 crypto/aes/asm/aes-riscv64-zvkb-zvkned.pl +fdda2d90b1598dc5c6a5f517af1ceaf3467f3ea1c2badb5d8a64daf3293380cb crypto/aes/asm/aes-riscv64-zvkned.pl +f1d8b7a3da1ec053d38be4fc776fef1e4fba328bfa2bfd928c2a2cd3b14f08ff crypto/aes/asm/aes-riscv64.pl +f03681748de029ace965133650f2eab5e5ffe97de0518f6867e466eff1d5d9d2 crypto/aes/asm/aes-s390x.pl +15390208374e5c9eef55d6a0366b2cb8d5e46c447e3fc6fd5eee63d70856e943 crypto/aes/asm/aes-sha1-armv8.pl +d8bf5123c51aa5ba673a46f2bf9f1d674f68e33c979abeac0d3e55459ffc9356 crypto/aes/asm/aes-sha256-armv8.pl +29286054fbf2354510090f23c25e553e40bfcc1e7b905cad18852952dc147fde crypto/aes/asm/aes-sha512-armv8.pl +4f3a1df6cca5eb5e23ca700756ab1d6bd8b83aaf1f2eb18e40f7b769feebe276 crypto/aes/asm/aes-sparcv9.pl +3c8b598fa1926f0aefb38ce99b30b08fcf40a09302376a8e2cf80e21e3d3dc75 crypto/aes/asm/aes-x86_64.pl +a9009ac21559a25e91e839bbbdd5a4a8fc0ff8f66886cd1de7d51768582a52f1 crypto/aes/asm/aesfx-sparcv9.pl +e220d630965eb2672dca757aefcb9654928288772fd495da3a495b405b5f21ff crypto/aes/asm/aesni-mb-x86_64.pl +458fea76c0ffb5881abd947d246f18d5446373bf8b25419d21e045ee741f1aa7 crypto/aes/asm/aesni-sha1-x86_64.pl +a6cb9dd725f3c9d08d6f9e9987a04d8a84b3f9ed94c3c8ffcb44074e0acf1c46 crypto/aes/asm/aesni-sha256-x86_64.pl a95ee8f58a6751e6e8375e62fb6fcd4cf79a2c96f328e634f5a03a787d0ce267 crypto/aes/asm/aesni-x86.pl -9d2628c860be50612f05c99ee3f8db2c2d127c50cb0ba85875b28522d6c76bc2 crypto/aes/asm/aesni-x86_64.pl -2977888731a429f7f0f73a4e8fb6898da954586dfabfc6c8cb31b7668d8c25a3 crypto/aes/asm/aesni-xts-avx512.pl -f5f0702f3c439df07dc5912ebf5232e17d4ece52ca87e99217851aac091d404d crypto/aes/asm/aesp8-ppc.pl -a5807ed92ec8a16d123061487c385bf1f65e50878cee95c8e8096844454129f8 crypto/aes/asm/aest4-sparcv9.pl -adc65ef913056df715ca0581d6946d83a032e0e24d7617a2ff67efd7fa872501 crypto/aes/asm/aesv8-armx.pl -1a9c4dd478dd825d258c989cd6861a74b46cf1a6ea00cca71e306d9a369e930e crypto/aes/asm/bsaes-armv7.pl -12cd3c8a9ce7153c577ff6238d81ec1947dfc43ee80cb15ee886cdf811969417 crypto/aes/asm/bsaes-armv8.pl -c22a4a276257db7c7a44ae8ddae3575f46dfdf65f14893985c73173294946c2a crypto/aes/asm/bsaes-x86_64.pl -6778dab09a2f6d65aea9af93079d81b5cd6f0a7ca11568f465e20dd50e6aed33 crypto/aes/asm/vpaes-armv8.pl -11e17be338aa5b5548902b84b7100156e2ab5492b6b2ba8df48c4390a410fe5a crypto/aes/asm/vpaes-loongarch64.pl -ef0f2fdd6a0b21d7aa594c2a1f83d2e6bc0f3c61655a1571c2ecb1d2eb193542 crypto/aes/asm/vpaes-ppc.pl +546a90333079f279d39091b6d6837893999d49a879bdabaa28b5920e43931a06 crypto/aes/asm/aesni-x86_64.pl +00dd3a64df71ebd61fd35d2a6179d07cc86fc156cce1541ef176ecafb815f4bb crypto/aes/asm/aesni-xts-avx512.pl +e51ae9b43503a53bf30b096e4823330d09edbdd87dc4fa1922f046c499cc68f5 crypto/aes/asm/aesp8-ppc.pl +f2c7e89354a9618b9805cafdf80c40398f5250e95617453fef27b7b7f28f0f8e crypto/aes/asm/aest4-sparcv9.pl +c72dd7528defa279a469939405ade53b5b905817c4666c8e31106b59f763b6f7 crypto/aes/asm/aesv8-armx.pl +373d15dcac88ec5b12d11df1551ad0b76e5ed66a6a308e72063601d0a01b1391 crypto/aes/asm/bsaes-armv7.pl +c5a5b5e5f72687c72c4bef688f0a2f83b170fc9028617704cd3ea813fceb56b1 crypto/aes/asm/bsaes-armv8.pl +c72f6cbf3b9900d956e05003ec8df758b29b43519c7801d677c3f992bc589d4e crypto/aes/asm/bsaes-x86_64.pl +069db852ed9e3e9f03c0812b1d324836400ab06caf96411415cc4b27a8b628a2 crypto/aes/asm/vpaes-armv8.pl +7ec25456a8ad4127c3bec83550d8ec411a12b506dfcbd4f1dadac2c66e468c22 crypto/aes/asm/vpaes-loongarch64.pl +608b2531cdbf7818c5e3aec5228aedde2eecba79f3c08148d4d1e479d3270682 crypto/aes/asm/vpaes-ppc.pl 3ec24185750a995377516bc2fb2eae8b1c52094c6fff093bff591837fc12d6c3 crypto/aes/asm/vpaes-x86.pl -0bdd2083d4454e46ec8d8ddd667a304684411f4d2ea9549237ae02260e13f009 crypto/aes/asm/vpaes-x86_64.pl +c6935d2ab7925022cb3d76446536ff01b1a1b8eb7eac619d034a29aad17ed45f crypto/aes/asm/vpaes-x86_64.pl 132c91241e571ea360250d28f8ae368a9efa07cd11afe014e316be07da38de8f crypto/aligned_alloc.c -46fe58bf9bd1b4a3e4b7688abc85fdd38328fe6baaf1db85bfd84cb0710d5914 crypto/alphacpuid.pl -92ce22da9063dc3ca88b5ef643b9ca02b72ec08bfe713b982370c1290a043f93 crypto/arm64cpuid.pl -3254c173f9dc41cf8b7163f1e09ba17fbe8420a8422b936c1b0e7af197c4a912 crypto/armcap.c -22888bce076f22f4a196e282ddbba01f03e5a53c759ba950c8679073de4b338d crypto/armv4cpuid.pl +d1df86b2e1ed3ecb59db54b89927973a7573e8395cfc26a9836a5b229e951ff5 crypto/alphacpuid.pl +e8b932f29ad759d5239af719bcd19a8cef20639d5c29aa3c5cf43dd9c61ca902 crypto/arm64cpuid.pl +e0e8987948f3c2e2ca6e3d08a77ec3dfa9836e505dfd9f15c205cf2198b06a3d crypto/armcap.c +23814e76ae6eab4dccfba2b82587aaa1c55a321a8f03e375602d5623608e4750 crypto/armv4cpuid.pl 779ea664cd73b8bf2e286cd4d01bfa04ff1543dbed821c79978b98fb80f76576 crypto/array_alloc.c e886d814c34492504cc9a2451c67fd8c0b4e83e8618f931632400cfe522b6e4d crypto/asn1_dsa.c -0a9477f2b8dfef0c34e5c215894605ea5860bd6fccad0f2c46f7575fc0a8bfec crypto/bn/asm/alpha-mont.pl -c06c6f3591131cb3532e07a17374689ba26dfe10f1566e8b0a739bea2ac9d25b crypto/bn/asm/armv4-gf2m.pl -c1d0e9e4e583a907e381303550290cfc0835cb29ef27521a8eb167468c2eb41c crypto/bn/asm/armv4-mont.pl -30e78a46dced48933cfd59d0ac96fa5d4063a3c5025d307c13c21f30865d165f crypto/bn/asm/armv8-mont.pl +64e34983cef730efd470b3db8b8127db11a7a3925e072092829474b7a67fbd72 crypto/bn/asm/alpha-mont.pl +27505cd06744a04a13e71a4bb38fe264aa5233473ab1405caf233703a44c14c2 crypto/bn/asm/armv4-gf2m.pl +7efe67a2d01c88ed44703a48d8d35459a7f53bc894851ca034215a4d74910533 crypto/bn/asm/armv4-mont.pl +8f7e661beff1a0e9d018137c674d758941d54b2cfd5d24c8641fd3a751729b1c crypto/bn/asm/armv8-mont.pl cb4ad7b7461fcb8e2a0d52881158d0211b79544842d4eae36fc566869a2d62c8 crypto/bn/asm/bn-586.pl -10fb73a6cc1bc064ebdcf6d7fe3c7407ea1c28b0d65ad0123046f8b1518fa75a crypto/bn/asm/c64xplus-gf2m.pl +636da7e2a66272a81f9c99e90b36c6f132ad6236c739e8b9f2e7315f30b72edd crypto/bn/asm/c64xplus-gf2m.pl c86664fb974362ee52a454c83c2c4b23fd5b7d64b3c9e23ef1e0dfd130a46ee5 crypto/bn/asm/co-586.pl -03b0fd6b7d0d5eda5f247ad16031e0475a9cd29231322b88adc21ea1c2e52963 crypto/bn/asm/ia64-mont.pl +ff2c606de5f1bad97eb7a5d25a856d5b6596c4c66b99710ec38501c187eab9d9 crypto/bn/asm/ia64-mont.pl f73e00dd24d22d664390e2d25397a45410094eb39e07f0c9ba9a421c6bb53358 crypto/bn/asm/ia64.S -dba7618bffdde638576c5e4f31d1fcabfaf67b89d028eb8ff04f0c8aa54fcc5d crypto/bn/asm/mips-mont.pl -29cbd1deb5f29bd4196755a74896b73ddd80bae23e79ff36e1ff42c596e70fca crypto/bn/asm/mips.pl -9a46c5171d34dbdf4b1605c41ded9503d92ae7ce8413ddb7b538b76defcfc150 crypto/bn/asm/parisc-mont.pl -37d90121a9026f8c21c21a1c3c817a27a21b643b357f31c40039ac8e54955bfe crypto/bn/asm/ppc-mont.pl -1c057083546fa1a3bb1b9819dc5110f5a3b11b7bf5a2fb275012323bd7412403 crypto/bn/asm/ppc.pl -04c9b5d2494c06e6f8a47c35274ddf53ae46b65e6abc297bd41e5beb735a3e8e crypto/bn/asm/ppc64-mont-fixed.pl -38820581b2ee29de8a88a5e3e7a6760d72174366452c1c6dfdf2bb2993e0df87 crypto/bn/asm/ppc64-mont.pl -eae1d6954ab3a5c2bcc17b3159755b81e80ea46ff2144ad5e6b6cc4bbfd63ef4 crypto/bn/asm/riscv64-mont.pl -4be4daa0a7873ea499e96fb3ce1a62c82e60228d0fad1d11b254308f051c35f2 crypto/bn/asm/rsaz-2k-avx512.pl -8ab49ff8b1ab9eae207112309c84f19e87f7d1140b3008164dfd46cc56b51a5c crypto/bn/asm/rsaz-2k-avxifma.pl -687ac0e5dc5cbd3e98af5ac54a79d659286a1104b984bb70825ed63d34184b99 crypto/bn/asm/rsaz-3k-avx512.pl -e75ea7d99334a9717b5db9c492ab6102d287f9de806772dad87fa2944499ce7f crypto/bn/asm/rsaz-3k-avxifma.pl -8ec08dd277ba252a4f28f2b664599526ce7d709dbcc01840780882f1ab19c46a crypto/bn/asm/rsaz-4k-avx512.pl -fd787df8d3e7c778e0f067fb22a049460ddf7f992678f908adccfcacc3677530 crypto/bn/asm/rsaz-4k-avxifma.pl -d9c8e45377eff220f0eca3e830f042423ed99e92b3c900e7b6e58685f27d69c0 crypto/bn/asm/rsaz-avx2.pl -f44e49a24a21d38ec415bdeaa7f8a2e33ada51ebe7a7ff7dd3fca52ddd25e1ce crypto/bn/asm/rsaz-x86_64.pl -3228692b32bdf96be6e033e6c24ee3610eb72dc6e28c3e8582857bcf3f0d2134 crypto/bn/asm/s390x-gf2m.pl -eaf166b509d192ac662d47f9d8c34a11e1c557e5c774256d96cfeb22a8cf78f0 crypto/bn/asm/s390x-mont.pl +0f4a74434df750c93dfc08108daab4ac9ce3ed43c3b079a777ca7a63435821e8 crypto/bn/asm/mips-mont.pl +d73cab6b8db2d6d0b20ec14f54da4bc95713c214cc0156419dbedba2d4b0ebb8 crypto/bn/asm/mips.pl +7899ad1b52b4986f8c241e200e02d9971f860c10590162d68b459a6fb4222900 crypto/bn/asm/parisc-mont.pl +cc89f4e101bdd25964b27f9c18e00690e0d1006831a2c86c2ce92f580839849c crypto/bn/asm/ppc-mont.pl +59cd27e1e10c4984b7fb684b27f491e7634473b1bcff197a07e0ca653124aa9a crypto/bn/asm/ppc.pl +0b3350f56d423a4df918a08e90c7c66227c4449a9f9c44096eacc254ebc65f9f crypto/bn/asm/ppc64-mont-fixed.pl +042fba38f786a505eaf10831719b5bebd55c627e348740b0b8a3170302ba8b10 crypto/bn/asm/ppc64-mont.pl +dc1e1841c2246a7a8201040758974192892b3fde3f60126ce079db707fb661dd crypto/bn/asm/riscv64-mont.pl +d48aded8547aa44a4af0d76d4675320628c66ba54e6fda865804953eefa8e853 crypto/bn/asm/rsaz-2k-avx512.pl +ae2e714dc003867c31136f939f8d47eb35eac3de36dbeea8f028a48d03b964ec crypto/bn/asm/rsaz-2k-avxifma.pl +6b5f35bf328f19b3add87a9715736ca92a8165920264311e20d3477a41a90a82 crypto/bn/asm/rsaz-3k-avx512.pl +b0ef4c3bb3a835066e9f7cafab22efc9d668b6debf5b9b9ec312cabae9412631 crypto/bn/asm/rsaz-3k-avxifma.pl +ca2d4486ee67f2015a8580664f3bbc28c23201205a2422d3a972cdf6ba59147a crypto/bn/asm/rsaz-4k-avx512.pl +80b0e7aca0ebee78fb3c651723e7f0eaac43a5b6a2bcf87b98a454a248abb945 crypto/bn/asm/rsaz-4k-avxifma.pl +7d686b484ea2bb65091c6ed3e74d5f4063ed4a8ecc09b7bef8d3a3aa57c4121e crypto/bn/asm/rsaz-avx2.pl +bec7e89c5a33652bbff20c95a6fe82bd96f7f2f61a3544c122f3af6f4f162110 crypto/bn/asm/rsaz-x86_64.pl +6049dd721f4663b94272bffcf8e6c872ae82fe7cd23c7b315170f8f2897d3b8a crypto/bn/asm/s390x-gf2m.pl +69bc9bc58b9f6ef8d8fe9ef459a7d01480de2e05749d166a76070ee20074f056 crypto/bn/asm/s390x-mont.pl aa02597f3dc09cfbc190aedb75711859ba0f3efff87067ebfba1ec78ebee40d7 crypto/bn/asm/s390x.S -87d49e83a7df467097fdfc577aa206be9ee622c40fcbbbe5133b35d9783b7816 crypto/bn/asm/sparct4-mont.pl +e2f139e5eba61317ed0fa334c935cefd49251432e0c4beb02a96e0fb5ef01ef6 crypto/bn/asm/sparct4-mont.pl f3b3f3ec50e38d02a82fb51d823d4449446f954a9ae8e5beb5874b907bdaa437 crypto/bn/asm/sparcv8.S 3c42b4fb3697b347f13dfdf556b3c209c10738b6234406f552af7519b4637750 crypto/bn/asm/sparcv8plus.S -503ea6aef1109b7dc0053e02e3b0b0541e3a133b956e17ef10671d97cc7ece22 crypto/bn/asm/sparcv9-gf2m.pl -07992e066b99f924373295585c10a1799cdb956d6ee92ab0f8c3fb2be639a6cd crypto/bn/asm/sparcv9-mont.pl -ad9d64c670c7d89d7c9de2772bb08478ed5efad1744876075e1eabf1b9f5bace crypto/bn/asm/sparcv9a-mont.pl +c2e6d5a97e0b9569ccf01921144140c61abe4315809ed18a92309b77f6e98d65 crypto/bn/asm/sparcv9-gf2m.pl +bdc9ee262593456dede4f40f4c11bed61d58bc4ec123725139952b90d66f5fb4 crypto/bn/asm/sparcv9-mont.pl +e7f32bd3b3a2b1d645b89c6db180551b75571ecec45c5d8aa37a8edbca1af33e crypto/bn/asm/sparcv9a-mont.pl bf3336df4063c29118961f411852df79b46c1a3981cdf055382f501339eeabb4 crypto/bn/asm/via-mont.pl -721b1bb921d8e8b82043df25348d45fea9a190cd7834b2bfa0661be0a9b6c460 crypto/bn/asm/vis3-mont.pl +b096f8347e7a71dd1681f41e5a76b3efbac068c9761c1f8a0b5bb2a51bae253e crypto/bn/asm/vis3-mont.pl fcdb8846dd6fb1b8297a8a2dc75915a2c5608434c7bc05e68a8b637b06961575 crypto/bn/asm/x86-gf2m.pl 0ed86280d18597b4a933609efffe1df991d0a0fc82e3cbe88f6ef06f947d7e55 crypto/bn/asm/x86-mont.pl -0e3e572cd864bcb9222cdad7ca4e8dae4250f6f76c2b66e1f0e46df1cc0cf371 crypto/bn/asm/x86_64-gcc.c -8dc17b03325a13540db8a40bd2f92a7ce8244e04daf0d59775596f376895c718 crypto/bn/asm/x86_64-gf2m.pl -d9abee54e5bee2a180d4215659c7f49fdc818e660d39029bfe906e6a0d84a972 crypto/bn/asm/x86_64-mont.pl -9dfeb5a18330e9c67060cc3de8dd5ec0236a0742b7874a3b7f80657907ad2a67 crypto/bn/asm/x86_64-mont5.pl -78dc1d8e7a63aa41cf837a2a4f9994cb6847fda1a24194caa44778e825639ec0 crypto/bn/bn_add.c +439b325e3b32858bfeaf673bb7cb76b8d1c68c663e2387f5f0648de524733b2e crypto/bn/asm/x86_64-gcc.c +6699333579a63579f58842d1c400ca9fc7dcfb07e9217f32876be8bafcc5f05c crypto/bn/asm/x86_64-gf2m.pl +4c51a5cb575e8d74f7b352f5832e523d54c57f6d99736da26bfc207fbe94ebad crypto/bn/asm/x86_64-mont.pl +02ce624f8ae7bb9420dfe8934e71f3d4fd4a284b8ba5916007743ba88134b7f4 crypto/bn/asm/x86_64-mont5.pl +74c8018546f8f72761a71c5d04c4301b07869168139ae0064b1932f86a828181 crypto/bn/bn_add.c 15e79a49cb16ceb28b33f1a06e5d4cd05b7899c8a92819cab72937212aa6639b crypto/bn/bn_asm.c cd5922b43407173e1331dede5a6d8d94f2d519a0d9f39b6017199392621c2ecc crypto/bn/bn_blind.c -d3b5f02a17ba1c71261f6dad0d4785846567c8a03368d41fc1a6ee7c45aaff78 crypto/bn/bn_const.c -eee3d2710144b0e860c57e84f5adc6b2bf64fc27cbd202a8ca2630aefed3b84c crypto/bn/bn_conv.c +1b8f89064c287669a834fe032ef823796f7355ed7e6da08d6c56c0a4cd0bba01 crypto/bn/bn_const.c +daad6ff1ad4912d05749978e87af5fe1985ae31160cb87202401fc8db7c7502a crypto/bn/bn_conv.c 33458c8fe9a56103f678a40d8cdc8cd2e222c229c1e079326403683872cea5a2 crypto/bn/bn_ctx.c b1b1c5fb8a45fde5755dfd5da62b68100b94f8c492c950719c108c384ea7f3c4 crypto/bn/bn_dh.c -4824f271f0ddc487b5991fbd92f7f7695aeeac234e076078f37da027999cdd88 crypto/bn/bn_div.c -a701560a4226e14f3a3de5f9ad125ae9e484d23fe9594622245e616ac791663d crypto/bn/bn_exp.c +559abf65c9dc7a4c80a92fef6bf6a5691acc9609c5a6587bb5377d25a950bed0 crypto/bn/bn_div.c +e3a43d63aea9c93bff0671b3c513ab9b713c7dd8b36cf8267906cb8524354801 crypto/bn/bn_exp.c ce5219203bf869561297978d6d416357a441864cd801865503dfd455c481960c crypto/bn/bn_exp2.c -c335361ed40e46f29641a99a9de6554fc45af07ef0697ee7e8b49f5bfb137537 crypto/bn/bn_gcd.c -6a2e8b4771ba9b2774483004c4777608cc32f455bfb4f6268922451bd8bc9781 crypto/bn/bn_gf2m.c +179e043e60d89243c0f66d74229296d713475c47262f997accb96fe4d66c98c8 crypto/bn/bn_gcd.c +6022e6f394c6e4b944f49f2ec4ea88f0caebebda784751ef08e38136f9ab89e5 crypto/bn/bn_gf2m.c 4fbb1dd8a5230cde13e59a8fe618c7cb371b197f21f8a4a3b8ae58dc2635a760 crypto/bn/bn_intern.c -ff147e5e032cc7c772b73a91fc6e24d8d9516e642d29354445d1f82d64b1d924 crypto/bn/bn_kron.c -a80481da8f1af0c19c6248f34ab9494dd4905d1781f63adfe290aee61e978b1b crypto/bn/bn_lib.c -21e080b81ed0fed6b4128068712b54e7854da7b621fd1298eeb0d3169ce75311 crypto/bn/bn_local.h -0d6e0928003c6d9f9ce153048370e94eb838c6840d207e09fc98b76aebed86b7 crypto/bn/bn_mod.c -6c438d456aec5940cac77381cdd2f0abc9436749a5201c3fe08eef9bc1b7781e crypto/bn/bn_mont.c +08762de7f117a35e5882bd3ee105aae89f2855609c55d55cd726483e2581e91b crypto/bn/bn_kron.c +63663297690fe443563a494ecc1e8e70fe8ca597a57276a9a77089ac9e4b8418 crypto/bn/bn_lib.c +5573802bf23ee99b41532bac5d36fecbaa18e03cb16098ea20253d1cef420ee8 crypto/bn/bn_local.h +ba379f0d86ba8112e164a658b4d1f3d6c3f3245e05aef8f2e1c9dcf90507e06a crypto/bn/bn_mod.c +b25a37dff27fc0ba2befebd363a97c1a460abe19ce32e9b7380ab158bcd31739 crypto/bn/bn_mont.c c2a5230efbda6844b7b2eb10447b054496ae5029130d332536de6c3b12dc58a3 crypto/bn/bn_mpi.c 4d1aaebf3ca938895ec2f42e24e06ab4d296a835ed75dbeff7168eec21631fd8 crypto/bn/bn_mul.c -e80177361897632ac9f013415dee8f6d2d942a8b51a4daf84fc7ba51d9d75270 crypto/bn/bn_nist.c -92e8043b4fa716b8f2fc5734b7225ce1121727f6112339df1735f76568dea557 crypto/bn/bn_prime.c -c56ad3073108a0de21c5820a48beae2bccdbf5aa8075ec21738878222eb9adc3 crypto/bn/bn_prime.h +ffc098f79d07f553032fdb77ed9e075e08db5a34bbcf30912d8277df71529c01 crypto/bn/bn_nist.c +2e3733db00275398a3fe074c22ad45d8b91ea150b199b77eb645c323d7d43c02 crypto/bn/bn_prime.c +df6527d679c9fa12923f9388281821614bb425ab108572bd417c271420128fa7 crypto/bn/bn_prime.pl af5af7057643ee8d35e3a2d5f7b55e37647db46700f2818edc295d727450d521 crypto/bn/bn_rand.c -b5cc902624b3af2149c9ea91f9d18bea56302144e87dfe49105ec6789b73764b crypto/bn/bn_recp.c +a2584cde4ab7f11544497ce5fba1d9391ddaed80f08ae13a38059df24d1958d8 crypto/bn/bn_recp.c d21093afc3d81b0ae37dc81717ba73229bf678ffe67283c83eb74f9cffd85df9 crypto/bn/bn_rsa_fips186_5.c e04f7460a2ab3b3bd9db332d99afbf8c7a3919866ad4314a5a5ad95b23ec6399 crypto/bn/bn_shift.c 1a92d0701a7b7660eab9bf861f63b831232896b88cf2b64e56a6713fc6ce34a9 crypto/bn/bn_sqr.c -c748baddfec6734bb50facbadf151a1f22f8a885c677acfb08b4f814e96f0d52 crypto/bn/bn_sqrt.c +101783b0311459bbd262dee87a5f9e6ede7c48011892c955f29c7d3991b25d29 crypto/bn/bn_sqrt.c f42996cdd94f18fe0858552be7123e75cb3ced0ebd7dcb90a0c73740090dcac9 crypto/bn/bn_word.c 2f048ca8e8ddc5e2b8b82775197f79334381dd90bab417b2855bfeee07b99db8 crypto/bn/rsaz_exp.c 45f7212a616e33db1310126e213fdaded8e3dc8a200b0520306cf423c485e58d crypto/bn/rsaz_exp.h 40a6f24c3575238dbb47958b613684d46c8c442f203cf07ef02f6cadcbebc31d crypto/bn/rsaz_exp_x2.c 72b85ca219bfdc7f990e07cc15decd9f46a12fd71cdc7c2331916c5009e5f48e crypto/bsearch.c 82117f6a7cfc31fc86ecd9629bd3bf614126b8e8b2c23717a03ff5c1db7c3c5c crypto/buffer/buffer.c -b99af1c5b04b34af14774966372dd90651c462797753b5f0576822671cd5c40f crypto/c64xpluscpuid.pl +06f0928291412621c133631da83ca200d60478897ccc2cfa4583cfeca6f823a0 crypto/c64xpluscpuid.pl 63835e57e16d3e463dc3ec8d1dbf907aa0824b59cbbc309983ff62546655d644 crypto/cmac/cmac.c -d2f9fcf7459b0c2b8a0de1a8c7c74e0f9ccd67fa664d9b32885f7c254ce65bba crypto/context.c +a43e38df1c793b8c7b0c92df683f34d2a5333ec95bc8f7a8f6aafde57d08f734 crypto/context.c ce92403350443d08cab02566b928013eabaf2d5ff5e2947f7e6d322cb8ec82fc crypto/core_algorithm.c -ab29529cca1308302d852999f2790c404a4dc0ef8cd6653260739f70b2f22758 crypto/core_fetch.c -a0637b8e324fc0970cec4f332fe07f7fd953f23586de8179dfeeebb4a7849433 crypto/core_namemap.c +f60bf67fe65d87f65f90d78bb276ea5902375b5310a29ceded2c00957705747c crypto/core_fetch.c +0ac6ca997cf3f30376fabd431cc395cda3fc06b5f89a713507b4618537b57a17 crypto/core_namemap.c a62f653b8a6ee765be704980425617e04e1d242f9735efaf35fc6e00815ff2a7 crypto/cpuid.c -3864c2bef2acf9d6fc7fa2486521236c382dfab4e813e49bf598ede68a6ff171 crypto/cryptlib.c -66dbfc58916709d5a6913777346083247942a8d9458ee9b2bf443f0ea4988d64 crypto/ctype.c +4a2185347200b40b7762182c68a0187df9f127240d3496a7c6daa57327b39b4b crypto/cryptlib.c +0145299d43dbb60e85ef6b97cf7496dec55cc37b75433e1403c11adfa3e90c5f crypto/ctype.c b9fabcf8480b8c9c7847a0c9af0fcc13b6c4b4a4558d5e445e6409221e6f8113 crypto/der_writer.c 135ef65f7602432f8c87ad18fdd90b867f1c46b1c631522d56181fbed2106b05 crypto/des/des_enc.c -7c2cea4c850398158b4aff172b242de0cc436b66f62fc701ccca3fe5489925a5 crypto/des/des_local.h +71bc23093274c53717e42cae83e3f56b57233f59cd2f23447f6b8de4068cc7e3 crypto/des/des_local.h eeef5722ad56bf1af2ff71681bcc8b8525bc7077e973c98cee920ce9bcc66c81 crypto/des/ecb3_enc.c c1e015556147b40c854bf0ab275c54235f99001d04c6d49f158fba6865eb5439 crypto/des/fcrypt_b.c 499513b3ad386fe694c4e04b3c8a9fd4c4e18fc44bb6c4f94d6bf2d9362a3a5a crypto/des/ncbc_enc.c dc2e7899593032fdf0fcab18f5549c52f12bad2225aac9a08c4622ffee34b193 crypto/des/set_key.c -41b7fc5e67814311b878684e3f29cff60e228f1516f670d81bf43130f2668ae8 crypto/des/spr.h +ed645417b91920caf3575d1086e6380663f2260ef2300702726fb7415810a836 crypto/des/spr.h 82b6cd90a74f0249bbf7e93c035d649d91fe3aef39cc8d507e61f4802ac652ce crypto/deterministic_nonce.c 3a852fcc48213f90caddcffd219a7f955be93eff519fe8b28086c68926314ce7 crypto/dh/dh_backend.c -091ec05b6316cce34305ae8f8014043c7c9b72098aa1abe9c35dcbcdb4b77cd0 crypto/dh/dh_check.c +380d55ea09a50ba3ece173e64db90782efae08ca56ac51cb4d31b9a303b429ea crypto/dh/dh_check.c c117ac4fd24369c7813ac9dc9685640700a82bb32b0f7e038e85afd6c8db75c7 crypto/dh/dh_gen.c 1149e214ed664540434912e284730a3c87385172e4c6d1c944ea56659e2dd762 crypto/dh/dh_group_params.c a539a8930035fee3b723d74a1d13e931ff69a2b523c83d4a2d0d9db6c78ba902 crypto/dh/dh_kdf.c -c9cb930fe7894703c1332af2d9fecbd515ff97ee1094c8ce9a705a8d916a0b70 crypto/dh/dh_key.c -3c364fa8d944a5f2d51af4377a7a07f3d8636dc04ffe63143e8d12ab66f6a019 crypto/dh/dh_lib.c -a9166c3cc60f4281e9d471c64145e0a78fc9dc43b8bc9e5de96d91eb7d277da3 crypto/dh/dh_local.h +b48d4c07adc4287c86623999e01eb33d7073cea4bfe77064ab062a18da1194db crypto/dh/dh_key.c +56dc245ef79b2c0e07884d5a177748e4e05b62def366d709df242321bf95c50e crypto/dh/dh_lib.c +e023c36aff127d1d6f691dce6b4b22c6ea9a139818801e1622a0ded64d3bad76 crypto/dh/dh_local.h 5dd3bc53fc951a30eb3c5cb8be7121032d3f4f482ce48e7cddb05d571956fd20 crypto/dsa/dsa_backend.c 786d6c65ced7ee4e25f5dd7c3150259ec95b6aa321a7590d905757b8139f8230 crypto/dsa/dsa_check.c ae727bf6319eb57e682de35d75ea357921987953b3688365c710e7fba51c7c58 crypto/dsa/dsa_gen.c -dee83cb278b3f712a62bd3477bdecf7b83e6df38ada2f3e1ca043d37327e2da4 crypto/dsa/dsa_key.c -daf1ed6345b83a416710c513b0258fe2382e23083ea17b51b1d6690390d55163 crypto/dsa/dsa_lib.c -02bd367be746e72268cc4df4adb069fe1b3bd570fc8e4fcd645ffbed56003132 crypto/dsa/dsa_local.h -602654e9894b3a4b7a1b48d93845338870543d6090eba1f6cbc2c1584afcba76 crypto/dsa/dsa_ossl.c +43f8fba4f50fbc94b1532a7667c9cfdc91b357e8658fd5fe0dcd302ea93ae9a0 crypto/dsa/dsa_key.c +47ff13f42316ce03d263976c6fb21232f28ab172be918b6317a93f9e995e4c23 crypto/dsa/dsa_lib.c +f0e66bdcab35a1cff2b1c16d6e452e3275ee27a49d35d370ad5a2f69ce02e483 crypto/dsa/dsa_local.h +be80e507b446b6b5c7c5a4adef95192e0a1312a2b668204a94bb7cf68ca82f82 crypto/dsa/dsa_ossl.c 3a38575de4b1409653f330f241848e6c7b554dec44c2415a5ae1baf90fb47ac0 crypto/dsa/dsa_sign.c 53fa10cc87ac63e35df661882852dc46ae68e6fee83b842f1aeefe00b8900ee1 crypto/dsa/dsa_vrf.c -103a3693afd8b1a9ba78f7e62a93442a87734419c9bb4a445590f675e86fcd7e crypto/ec/asm/ecp_nistp384-ppc64.pl -786779d7014bc04846832f80638743784a3850c7ee36e4a8062fe8eb7ac31c9b crypto/ec/asm/ecp_nistp521-ppc64.pl -1682a682f1e7d4c568dcfae1e24a01cb9ebfe4c4833b962090e0fd088027a684 crypto/ec/asm/ecp_nistz256-armv4.pl -41331cfcaa5c9c989fc7162e7d3af9e91779bd36d16de4d12b8f924437fad531 crypto/ec/asm/ecp_nistz256-armv8.pl -1dfc8df4833dd357544da06c6f846decb02dbcf53b61ffb365de868db77de669 crypto/ec/asm/ecp_nistz256-ppc64.pl -3c1c7b681ba3ea85b0fc78007a86ecedb7adc072ba1f0afdcf65dcdd95b8cd0d crypto/ec/asm/ecp_nistz256-sparcv9.pl +5335741d0f6c1afac107c9ec66e6b5436bd2164535f114c23cdc2a199560c28a crypto/ec/asm/ecp_nistp384-ppc64.pl +d9722ad8c6b6e209865a921f3cda831d09bf54a55cacd1edd9802edb6559190a crypto/ec/asm/ecp_nistp521-ppc64.pl +2426927feef9d778c0ad2e5c0142817ec22a7c857bd22b6cdf122cf25ce80156 crypto/ec/asm/ecp_nistz256-armv4.pl +07db85ba541701372027afeac98b560933a33ed1b5c451968be319bc6810f53e crypto/ec/asm/ecp_nistz256-armv8.pl +96c2348e134d17aa4b54016c58dcf1ebf3b6afd958298b704777163d776b4648 crypto/ec/asm/ecp_nistz256-ppc64.pl +4e443ef55be5ac62a5c1c22853f08b543cc12804e48ba46d7d7b42b448aece92 crypto/ec/asm/ecp_nistz256-sparcv9.pl 66064bb1a2cf6491b05c90dbfbf124298fc6a85db2c020dc65348bb9b7b52755 crypto/ec/asm/ecp_nistz256-x86.pl -c429416028457285cef0c24c5d07d4804eccef29b3be4efda37e8194c3fa9eb9 crypto/ec/asm/ecp_nistz256-x86_64.pl -e806141073aa3792e2748f6feeee6d3017124b3bc6059a9eca0d53a2f5785346 crypto/ec/asm/x25519-ppc64.pl -ce997e335e9c76f736434177907207b6799f7c161f54fad5d8be0a77b4bb77f3 crypto/ec/asm/x25519-x86_64.pl +f5c4f8c74a44c8723293e3bb64c0c2cf75dc354466ac9f93ebfdab1df34b64c4 crypto/ec/asm/ecp_nistz256-x86_64.pl +cc727533130f5f1a29229929b3d4e8454585d647be25d6344f3c6a0240998368 crypto/ec/asm/x25519-ppc64.pl +73c5567f25c891ce0e2e773e8d86b87204718af049fa5f1848fe196b9ee8f24a crypto/ec/asm/x25519-x86_64.pl 2e7b5d2a3eff0b8a90c1de3f28a7bf59b1057e7694c0e36909e774343cef609f crypto/ec/curve25519.c 784c03c3f81fd0c363cd0500fbd95f3e49c65f47a249f7ba25fad42a41d3eea2 crypto/ec/curve448/arch_32/f_impl32.c -8e75602d4d492316d318bac147eaa09d87b0eeda0d450e18683d935673ab61b0 crypto/ec/curve448/arch_64/arch_intrinsics.h -4cccf81b42c6b8caff7a641280b2b01400c5ca94f8124eeca774569c19e155e3 crypto/ec/curve448/arch_64/f_impl.h +5e012dbb838ec0533aed7689cd82324f9b4e239792777376e92f873f7318dca9 crypto/ec/curve448/arch_64/arch_intrinsics.inc fc28c768e210c98e8d77c7c57c48eacede226083b95c58dd0bdfdc4efb12cbfb crypto/ec/curve448/arch_64/f_impl64.c -385a8c6b68b212ab7ea8acd47cd2e0601a0b3ce7356e28b84842aa9acc1437fe crypto/ec/curve448/curve448.c +f79eb20d039357d8b7187d2ca1d68c2ed0a4727896588f30efd4dd50a885b704 crypto/ec/curve448/curve448.c 92a1cca23f4c139e679f61726d17d475a5eae016460b9cdaaf5b2d996d940ca5 crypto/ec/curve448/curve448_local.h 6bc188cae67754cfdc9e4420ca2a208292f34c0c3aa5a25930146b92111e9640 crypto/ec/curve448/curve448_tables.c 8d6546f15baec96755625593a9bc7f781092fa4dde846ba6b488a31585b47a8e crypto/ec/curve448/curve448utils.h -490496e1c06d1f3ba9474ddd98e07fe11cac2838dd3937f35541f69ae798e67a crypto/ec/curve448/ed448.h -b65aa613ee9f74bfc7fd00be16087c431bdf092a7e6943238eee9e54ca3adf00 crypto/ec/curve448/eddsa.c +14c1ae3dffa8f8f854fe2242c825aa48b2dcea06cd9402a2428982ffbc10c472 crypto/ec/curve448/ed448.h +eb36ed67152fc698d0ceb27870ead659006a5c44223bda501ee4c1f38103d818 crypto/ec/curve448/eddsa.c 5aa20e2a4a9ae3a30d7400f3d666238f890004c3dfb66933873e7daa0026fe3e crypto/ec/curve448/f_generic.c -81ab2c5bcf5b036f649804f494e1b2ee5d5b2f900dd56b5dc55bac04a63a57ad crypto/ec/curve448/field.h +ebca70eb99c3877118eb1967fdc542efe0e8567edf46aeca870790247748028c crypto/ec/curve448/field.h 77bc6dd8c7d14a21760eb5e0dbf336eecc78835faa2f6f846824798303109d41 crypto/ec/curve448/point_448.h -6d007474cb42b16f98059f6eea6c09ef23552049207558fe46d071a613c8a314 crypto/ec/curve448/scalar.c -c0b5e93f120c7a5e0c0aba9877a445d0f5db85440491853b182266ee5f323361 crypto/ec/curve448/word.h +e29e78402540a4eaa853b1b9931aba66be0fdf1c82c6334587a69235e42f759a crypto/ec/curve448/scalar.c +1d20868365c9f78a16de469756c3810a1f2db6c9b699dc9ec9a0868fa1bc7060 crypto/ec/curve448/word.h 1f0ae0a59de6141ac9dc1b294444807555e3b6e747c7fef7314f90fba77dd322 crypto/ec/ec2_oct.c -5d3567b3b6d3922fd82641acff29ed12b1028e83eb0c175132ce7f3470b9db6c crypto/ec/ec2_smpl.c +c23841b40837ddb4a07aecf2eeb7d39001bfd88b0fc35382580732d9eb702eea crypto/ec/ec2_smpl.c a1f22814f501780591da20de5e724895438094824fce440fd026850c46ad8149 crypto/ec/ec_asn1.c -51e017af328480fb77119b92a2dca1a69dda90218ecbe05025f58efe3a89728b crypto/ec/ec_backend.c +7f6d0eb80575a583e7e81f0b1e2c4bea070dffcadb32e44ea51c3f58ec12e533 crypto/ec/ec_backend.c 3a3c4f4767513b4fbbabdea2918d7c7d105eb573334a7fd893b866989463c4d2 crypto/ec/ec_check.c 236f02fe2602088a3ffdb3fcd6a8211db4f2014246bc90c134ce472b80a15208 crypto/ec/ec_curve.c 8cfd0dcfb5acbf6105691a2d5e2826dba1ff3906707bc9dd6ff9bffcc306468f crypto/ec/ec_cvt.c -c103eb5935688efb30a2112a29c069616268cd89e1aa74dec60ec95c53bba28b crypto/ec/ec_key.c -4518f19f669d02a25b757f54a7279fccf25bf86c0096734ce294e5d9b2d4b90a crypto/ec/ec_kmeth.c -bdeb873969ac1510e5361a3175e1cf7ac4aa0e23930348890264cc139c9fcf8c crypto/ec/ec_lib.c -aca82be16179cee0d452476e15e589cb9cde9492f44ace7c6f7038bea5ddcd58 crypto/ec/ec_local.h -34236e0035edf263c174c56cb5ac7066acedc0579521aaf60229794473cc1ed3 crypto/ec/ec_mult.c +040b00015f640eeb9db5e1589b0a314d80421a3cdd09fa92ba4939cb6d6486ac crypto/ec/ec_key.c +62bed8d5fd7389e991bdc4a6f0ab4a7dcd929952b2ee34e567c06b25bb06cfd9 crypto/ec/ec_kmeth.c +53414114df475556b196c24498e52dccee35ed0353e708c7444a3a35475ba527 crypto/ec/ec_lib.c +ebe9ca2a6d10c484a65e8106e657b495873c1a34c9d5a1e8b78d7d9f360e2bdc crypto/ec/ec_local.h +91b0f6c7d234b3de2951c22458017ecc5f794705687f4d6a23d0c6b1ece26ee1 crypto/ec/ec_mult.c c2a81f5f56d304038183ba6b02fdcba8767833f61773ec483e73b330b67ae59b crypto/ec/ec_oct.c c7fba2f2c33f67dafa23caef8c3abd12f5336274a9a07d412b83be0366969ee6 crypto/ec/ecdh_kdf.c b86a943ae62145438a7214539ceb3e0de5a30e17a6e59742c6e30991db730ab6 crypto/ec/ecdh_ossl.c f698d8d3f57b38e1ecd96ee06e76c503b4b7d52b07cd6927c0fdedc7b86036f8 crypto/ec/ecdsa_ossl.c 927661d7d67d93209ce21691d4604c25a3f643eef924e8bf1c03d29f196bef22 crypto/ec/ecdsa_sign.c f686cea8c8a3259d95c1e6142813d9da47b6d624c62f26c7e4a16d5607cddb35 crypto/ec/ecdsa_vrf.c -141cfc1459214555b623517a054a9e8d5e4065a11301237b7247be2c6f397a0a crypto/ec/ecp_mont.c +1c6e9f8bec7028b5bfb8faf1231f9d65ecde89fb131beb04d3e513fe8014505e crypto/ec/ecp_mont.c 13b30f34aeeb0c98747239bfe91b5f0f14e91b2c1f11db62ebb5950c7219daa0 crypto/ec/ecp_nist.c -27b2a6a86c24c044f354d4e09aa2217985e7e886aa0efdf7c1027d1d15357e22 crypto/ec/ecp_nistz256.c +dfbed11b7fe019acf377f40aacbcf2366018776cbc3754e55e0a387c41db669c crypto/ec/ecp_nistz256.c d6e604cb04490bd604fbfca00a5095d62b1763ce0812fec7d3fad122a226e741 crypto/ec/ecp_oct.c -eaea07825ffaf1c7b6d0bf8c6e0786134ffb60f25ef2fffb5b5008b55980c4fd crypto/ec/ecp_smpl.c +6648cbee3c740f7c8b6c2ae2b20468247a3f4f2648c950f5c77ba2fccca180dd crypto/ec/ecp_smpl.c f58e722dfcbe74a1ed28ca0716685ce9dd3c49ca0e585d10adda3e7f273968c6 crypto/ec/ecx_backend.c -5ee19c357c318b2948ff5d9118a626a6207af2b2eade7d8536051d4a522668d3 crypto/ec/ecx_backend.h -8e50fd1e60ad1ac824e704375096e41f4ae535e533a3334d78c481e34d9d0fb8 crypto/ec/ecx_key.c -69635b077fb305700ef8e81dc91bcbd19feeaa978c6c8b57fb56ee07b0071069 crypto/evp/asymcipher.c +8310da9236c29d3491db25cf9aaf64f4fb2c3273a31f19a1cc789e555a962910 crypto/ec/ecx_backend.h +28c82ee212123c7da522747cbec521eda5640e977abcc02ced0f586fa6177113 crypto/ec/ecx_key.c +ec4ce97d492fa4418a706aadc8d24ee7255772aeea19b5e6e6bd8cc74625f3c6 crypto/evp/asymcipher.c 1f64d4752074f954af4f290788e4332e3874ba3282bd03d3e1d1f5ce4b0888bc crypto/evp/dh_support.c -51bf6d42b6c7bc1d423b2da6d94b8f91d6a4dd3d0a8694447dd48321cf4fd8b2 crypto/evp/digest.c -4ffc3fc5ee5f0dcadf1516f1cc29338f0f4d85c59881c06d5a777cf4e47a6d5f crypto/evp/ec_support.c -505690bb2efd19d6010ff4589d52d4cdc8d604d293a694469738bd600d1847e8 crypto/evp/evp_enc.c -a8e92e692a901523e9b0a3d4fdfd300d7f771e134ed48194a27bdcdaeac03efe crypto/evp/evp_fetch.c -49f272f4c8e59d2f031855786372e76c1c78a675eabbe9b43c686665183df3df crypto/evp/evp_lib.c -f19c24925525de7c5b08ed4e9689522b3d6c140501d6c5013f08384f8ee7794e crypto/evp/evp_local.h +3791ccf51401ba76e793d46bb82021510f3832afad128a416f3a0192b0ca5d7d crypto/evp/digest.c +392e18d618024188db1987f420fbc0cd7b896e33083bfdb36247dd718cf1ed5a crypto/evp/ec_support.c +8258f083541b3dcb63f06fc91561f4c5a2ac6d611927d191b0205e14fb3c5f9f crypto/evp/evp_enc.c +667a17cfcc7c5a3aa52e05f3ba319b52e87f3b1c2d08f0d9cc4bff623a8533e8 crypto/evp/evp_fetch.c +7b0fd301ef9954007ab4db2f6e8572dc6270ca17761cdf9757fc7ea225849e48 crypto/evp/evp_lib.c +b36dae47360b48ff92773de8d8affbacf85456a29a3576d136ffda2682ab64cc crypto/evp/evp_local.h dff5f95e7ce972915f260b6e0bb542b57c8a7771e1db9376b2fe8181915d2a35 crypto/evp/evp_pkey_type.c -bf235d15f96ec1b3a6a8f5857c4a1f74d14287e314a7bd2251ab5f9a71a0420c crypto/evp/evp_rand.c +2a26c96c465eb751b7544d952af444b34e7eeb79ebb6f2e94c9097b0295735c7 crypto/evp/evp_rand.c 0bdae4714221662282dccd5b1f2485370d24e463c11bdbb71a310f34616954fe crypto/evp/evp_utils.c -b6e8b49611bf8d04a703698ff44428fa4bbc6b4e3b5e1fd1078eb90d7e7b26f8 crypto/evp/exchange.c -0a2e5c9a4079fa408b6ff00b7c8b57f93f331de343c5898e240a136452404ecc crypto/evp/kdf_lib.c -aa0755dae61191c420032d7a4f2a5d753715d547c0e011e9e20a07c40fd7aad1 crypto/evp/kdf_meth.c -4e60c9e37106b9c28d646f7234d857e8520da953ed7d319531467d334b77a72e crypto/evp/kem.c -1cd1fdb9e1d569ecacdfa40e69e671538402933fd6fc9b78d16608ae12bf53e0 crypto/evp/keymgmt_lib.c -8b4c50066f33fe5006a23f220c43c387b9138fc183390623e8eea222ea304fca crypto/evp/keymgmt_meth.c +611547a86fa5c07932d348760ca838a483ee201946c86889d30da8a461d3b221 crypto/evp/exchange.c +c55e3b0a2e8e9fab282343463909b4c4139a40449e9c2eaf1c81aad2b9001f17 crypto/evp/kdf_lib.c +d2f75dcd0f0194a464b8ed4035c988599e8cdc1cb63711b9a30939401c671c22 crypto/evp/kdf_meth.c +955b84ca25e9118fcf0b9dfdfa77c57cd0c8608c431c71e1a0a05a2a27f81d0c crypto/evp/kem.c +a7ed6f797fe62f950f549aab6c13bc7357bd59de140feb8af9437c7a3117422e crypto/evp/keymgmt_lib.c +94ef431b1bb2c96cca3806b8fdb100bb9d9f7afc1fbf417d6f03b7043657eeae crypto/evp/keymgmt_meth.c b68fa4796b20a4735f4779371859b27b5d55f145f791d7cade8ef90c7d85bca7 crypto/evp/mac_lib.c -8f9d191eda167c24fb579818d432dc12321fc559ba59b9be96ab4c9c3953911c crypto/evp/mac_meth.c -7b4d2ae311b377c5ddedf45db5212ef5a35fec717406316a18aad478b9c50cbc crypto/evp/p_lib.c +9b812a03bf763f3fe2dc9b86daeef05d8b9946f7efe43b6d312bc487340f8aed crypto/evp/mac_meth.c +b09d2c6cb6307a287af190aa744ea6ac78618cb9522e7cedf324de76d24bbab3 crypto/evp/p_lib.c eb7ad84686854874250101adf52a3498c7e08ea63e5de17845d35f2a66461148 crypto/evp/pmeth_check.c 05c6934d0d8befa8f551323db31a9a908bba7e9cfebe1161a2bfb0eb4c3b36a5 crypto/evp/pmeth_gn.c 10de135d3bf315ea2f1e97a2aff46e0911dd074a3af5fd429a437192ea72f2c3 crypto/evp/pmeth_lib.c -d6489744c04a80c3a8610db90a1b02bf1f4f672b877de3d4ddfa733c0baee8e3 crypto/evp/s_lib.c -58fdb0b2219c8ee148189574ea99307d0ebd45f6f0c502fc23b1b25b013387bb crypto/evp/signature.c -30af153213f8b008955486000c5a92507dc694c4af9ac6ed6fef3f290efa3e52 crypto/evp/skeymgmt_meth.c +1d4ac1c4a0bf0a5e7a99d98dcfc96f8569bbc718df3a2ae208f776dc681e4eb8 crypto/evp/signature.c +82738dd892e0cfa1897f58ed21a8ba66b5505ad774a484eaa0edf70d1b69b359 crypto/evp/skeymgmt_meth.c d40ee57a311a8aed79b1995e4667c6191d4a6d073eec343a6d9ce432830e9a16 crypto/ex_data.c d986ec74995b05ff65a68df320ab45894ba35d7be4906f8d78ca5fca294a4e6c crypto/ffc/ffc_backend.c f4f84cade98907fa9905334b6c3c046b430b12b1460edac0617d82ca763620ab crypto/ffc/ffc_dh.c 854378f57707e31ad02cca6eec94369f91f327288d3665713e249c12f7b13211 crypto/ffc/ffc_key_generate.c 4e973d956d4ec2087994de8e963be1a512da1441f22e6e7b9cd7ee536e3ff834 crypto/ffc/ffc_key_validate.c -06f7749102b9917dc9c28e46055c5066acb0fdb2ee5b53cceb828d292d1c5542 crypto/ffc/ffc_params.c -9d56d969bb1f1aa6f85d52339588f0f4a92ea4de24db697b2a8af67b0bf754a4 crypto/ffc/ffc_params_generate.c +66d6e500db31398dcce7e3b402ccf5f333b9912561157848776b8977f5e756b4 crypto/ffc/ffc_params.c +56c52c6df6cd9282296f24b395e6a78deb35248e79a26186a75fc508262c47f7 crypto/ffc/ffc_params_generate.c e9a500ddbe96cb5b302fd2db74fac0924a6ac45732df5ee1c09e82b19d06ccfd crypto/ffc/ffc_params_validate.c f172c8c2112ee82716a7bc3a3e05d5cc26188c66b9d768ac1ff906845063d2cc crypto/hashtable/hashfunc.c -49599084eb85f841718d3b3821b794c9fa44566397fb2812d3b7f1795b8c66b9 crypto/hashtable/hashtable.c -4349fd4b1b6cb4f19a43e25346aa4f3372351822cad753fb1884d9de911e4c14 crypto/hmac/hmac.c +21b74f0abd0f84390c90398bb2812565e183e0f35b2561ff20a52941ae67a86b crypto/hashtable/hashtable.c +95cbfbdd853f415d886928834f59d01a5fd08c71a154268c881dcbcc1131abc0 crypto/hmac/hmac.c f1e386f65db354b5a0c4248d3df6ee690881aaa3fd4049fdc443f9eeb635f8e7 crypto/hmac/hmac_local.h f9743f1646fbd8b61a2dd0422f42934912c1bfc95f6dcc38fa0a567e3e6b4e95 crypto/ia64cpuid.S 99727373714d17bfaadf837581cb82b95100604fabb5926c22dc68e4fda08d57 crypto/initthread.c 863a23d7441e71e065c4d1a29c17eb2e575bbb03ab31407ead9e7ad2c16a2c9a crypto/lhash/lhash.c -22261096a117533e78012f5f18586b6a81edb3e09ae8b206b5eb9a0a5c054adc crypto/lhash/lhash_local.h -f66ff2d5e6fcf5c858b46bce16ee991126d362df0bc0ebe26213272c7f02db7f crypto/loongarch64cpuid.pl -460a7af09cde89a820b091522ada1310cfcec99c60aee505f94c48c35e9a29e8 crypto/loongarchcap.c +256d8ee6275df46ba94b882cdb7b3c7210ac1b4b0602748ff6fe8af3b27981f5 crypto/lhash/lhash_local.h +899ba6a9049a61d5b175637907f747f58863cd8950409cefac8fbc8f574f970c crypto/loongarch64cpuid.pl +cc1c483ec235a35d8cbda000956c224e776aee9e9f924cd10c0f9fb6f62efbb3 crypto/loongarchcap.c f866aafae928db1b439ac950dc90744a2397dfe222672fe68b3798396190c8b0 crypto/mem_clr.c -5e33547e2f6775a89701b311712e6a3ee6e2a64a8f283eae9e61a4a01c392e69 crypto/ml_dsa/asm/ml_dsa_ntt-x86_64.pl -3d0191bba6c23ae191f7a63fe7c2229a00de3f9aaf0128f5503d4e20bd2d1cda crypto/ml_dsa/ml_dsa_encoders.c -825105b0a2c4844b2b4229001650ff7e61e1348e52f1072210f70b97cd4adb71 crypto/ml_dsa/ml_dsa_hash.h -24455e1918d8efd3d99b6ff77f50c2df5d156cc645e80eb8e56960b3429b9769 crypto/ml_dsa/ml_dsa_key.c -579c1a12a5c5f014476a6bf695dc271f63074fb187e23ffc3f9ccb5b7ea044f1 crypto/ml_dsa/ml_dsa_key.h +93603569d050b9752cad6508b5de6c4ccb6e77398628fce7cbc7270c53bf6733 crypto/ml_dsa/asm/ml_dsa_ntt-x86_64.pl +023bf73b6e04d9c999815d7ec84297943aa9766e1ab5a72a1869c95a377ce851 crypto/ml_dsa/ml_dsa_encoders.c +39c6f4c50a388eb16197539132a97cc15b0b74b93ecfc2263a36a0423c2e15b0 crypto/ml_dsa/ml_dsa_hash.h +7c7431a60e0729ebca444a8e91d16fa928b61c99396cc0538aed9ddcd5942e61 crypto/ml_dsa/ml_dsa_key.c +44cde1c60f0df46f8e44d2e0e070782314b4c623e8b44862f939f397e702d367 crypto/ml_dsa/ml_dsa_key.h 3f98eb0467033d0a40867ef1c1036dcfea5d231eeac2321196f7d7c7243edace crypto/ml_dsa/ml_dsa_key_compress.c -01d9ba6431280512b96b0344780cee9fbbfa7c6744b7535491165cda4223f7fe crypto/ml_dsa/ml_dsa_local.h -0490a89372b79d98c2fdc294f836fddd7a54a148202ffbd50c2d4371816a94d8 crypto/ml_dsa/ml_dsa_matrix.c -ff65c82c56e341f47df03d0c74de7fb537de0e68a4fa23fa07a9fdb51c511f1c crypto/ml_dsa/ml_dsa_matrix.h -3cd70debaa737f8edc87fd636545b9fdbb973a631688b273dd7986dadf12b651 crypto/ml_dsa/ml_dsa_ntt.c +5b349bf96432658dd8b02c6e9ad60d6fc154d704d0116adb5697c6ae65debbee crypto/ml_dsa/ml_dsa_local.h +6ac18f9ef27efc7fddc38ad5edec94fcf76a972ca9fcb6bdc5472673d885d238 crypto/ml_dsa/ml_dsa_matrix.c +e2704808c86c370d2bbedf14c20746f8ccb3436cc59b7d458ec93adb8c6f8f06 crypto/ml_dsa/ml_dsa_matrix.h +9054eb27f005696fc7cb9d35ac4e4ec6f06f1486f9d355fd9aee049a6d1481c1 crypto/ml_dsa/ml_dsa_ntt.c 3e0980e67842c4d8637fa449ac41e9d650c614c1074c29f1021605d229a4f73d crypto/ml_dsa/ml_dsa_params.c -10e37ab3ee09a45d99007665e073efb2b062c819f30af8694c6b0f411eb33822 crypto/ml_dsa/ml_dsa_poly.h -26be5266a9f1a33999a5a68c96cffc7932ba64521d9554dabe7397591611c852 crypto/ml_dsa/ml_dsa_sample.c -9e57d844f2acedb490b6e8f32e125240078ddab380a7faa533baa9c447dee262 crypto/ml_dsa/ml_dsa_sample_hw_x86_64.inc -2127303173eff12cb2b71f92179d10370b555c26e7a305e87ce7066580d57689 crypto/ml_dsa/ml_dsa_sign.c -5217ef237e21872205703b95577290c34898423466a465c7bd609b2eb4627964 crypto/ml_dsa/ml_dsa_sign.h -e3ef4cf1598420c94eee4f53d13491ff0f9dc8cfb1fe1cacd3a1225e2073fa56 crypto/ml_dsa/ml_dsa_vector.h -15e663f9d706812e7e89207fd0c4050ff82d02e06a868585f1e77dee431424c5 crypto/ml_kem/ml_kem.c -6906e197c84ae0d828748d47c47d565fd912076c35a65ea304e306fee4a17157 crypto/modes/asm/aes-gcm-armv8-unroll8_64.pl -a1d87ada629d7c1e487524f475b9c2b01a700d981e092ef6895e3f32d2dd79e8 crypto/modes/asm/aes-gcm-armv8_64.pl -6b98d90b233d87f4d99f54a553b242199cd621f9c09b5cf64923831cd98ba054 crypto/modes/asm/aes-gcm-avx512.pl -7ec48551ef004c2f48a51c46b31c1a5f5b88c1075da4e7860def699a58b2a000 crypto/modes/asm/aes-gcm-ppc.pl -b7104ee749d555127a08609c7df5056b56d9aee19c90f3c42b42d69cf7caba03 crypto/modes/asm/aes-gcm-riscv64-zvkb-zvkg-zvkned.pl -85574283333dcd839873770c4d7fb309afc978059c623dcab1a4a40e9b697312 crypto/modes/asm/aesni-gcm-x86_64.pl -0d10ce3c9ee1016312ba124de3beb8740bc13d5a1bc06dd6c4693a22df05e954 crypto/modes/asm/ghash-alpha.pl -9b523f96aa97bbb50c0102caee46d5b07d68aabd8b606bfb148aec88e125681c crypto/modes/asm/ghash-armv4.pl -326b715e289adc979840d8037cce526e6ec4d0917495c75ffc53e78ed39d8ed0 crypto/modes/asm/ghash-c64xplus.pl -4fa4a0dc1a96252f6c2369ee55ad753e6c41402d3e8cbe7afeea71a7e35c9cc1 crypto/modes/asm/ghash-ia64.pl -175c15708f8749fdd8f85f729ced44e8c2bd1d42528f5f1fbd908c71213a07ae crypto/modes/asm/ghash-parisc.pl -9140d35aa157dae5c98b2c950248d15dffddd16c11a0f092c4a79b0a460b2d54 crypto/modes/asm/ghash-riscv64-zvkb-zvbc.pl -c786210922836f2ee9f7806b6cb7a5749511285004cf7eed95b3979bf5685bb7 crypto/modes/asm/ghash-riscv64-zvkg.pl -b353c76f30ed3bcde79e1280a53acbd7172d1924124c33bf2fd5830396e7ac0f crypto/modes/asm/ghash-riscv64.pl -03269b327d5055e7c37992e989b75e1e6cbdf3878a6709f8ffd8e3e13d171e07 crypto/modes/asm/ghash-s390x.pl -920385de6904c52e69d093d5abb75774964e46f96d343262b88a58aa8e7f64d7 crypto/modes/asm/ghash-sparcv9.pl +083df153906787ab2eb39a0aa4bc774d85fab2a2aa10e80e535a909c5dccd6ab crypto/ml_dsa/ml_dsa_poly.h +d80307d35ccf787dc1595692093c71e705d51989051feccecb38cb09130ba087 crypto/ml_dsa/ml_dsa_sample.c +e170630ab923d95eacded0018f350528ce0013f68872c11e0b5d3548226d1994 crypto/ml_dsa/ml_dsa_sample_hw_x86_64.inc +e48950e5753ed1175dddc7da22cafc8da3ca45ddb85368b90b3f1bccde4baa74 crypto/ml_dsa/ml_dsa_sign.c +22b263740ae86950030206a0c421c31983491e56759f3a4621bcdb7badca0d36 crypto/ml_dsa/ml_dsa_sign.h +7bd522972de2539857984908ba665a693c002e337682d52f90e2df63158cd5b4 crypto/ml_dsa/ml_dsa_vector.h +9ae4228f321a845cc5125492ed31eb39b55ac38832ccebbd05509a2fe9346cca crypto/ml_kem/ml_kem.c +20fa6176803656a41ff950817e037dda93f543a0188562d894f56a996fb6bb77 crypto/modes/asm/aes-gcm-armv8-unroll8_64.pl +0bc2a7b75b7b8615a5104795fd4194285cafd7bc9e3cf8440ebc551787f92870 crypto/modes/asm/aes-gcm-armv8_64.pl +573c286991352233cb068d0e218c5cb1e6fe5d07a924496dbccca95fa82e1d4d crypto/modes/asm/aes-gcm-avx512.pl +8fab6574aa99ee635d564dbe68b014562b61af37fa4f151210690837cdae6707 crypto/modes/asm/aes-gcm-ppc.pl +dd0de5ca8913a941cfff781a42fba43227e133976a24d0fddebf63909f7e010a crypto/modes/asm/aes-gcm-riscv64-zvkb-zvkg-zvkned.pl +ed5b8569e757b9c23edcaad64bb3b6094aab999ba7394fa79e402bb6955d4277 crypto/modes/asm/aesni-gcm-x86_64.pl +6d5d8d7d3cb1c7378156129b19d36633e845d1d15de73e45a407e45ebd06bc3c crypto/modes/asm/ghash-alpha.pl +1eb73d1351db8a57c219f92dd7e13f10bed4bdd46a417cc8e5a88a09d1670289 crypto/modes/asm/ghash-armv4.pl +bf7553a03c9fd058a7432c4790e661de464ebf9ff26e303af4dd0dc52c5df478 crypto/modes/asm/ghash-c64xplus.pl +2934a53c930f252539fc114615ac34f9145d2c92abc936095e9afe2e811a218b crypto/modes/asm/ghash-ia64.pl +65bc6d4c2405e1b51dc3a498eb4557436536f041cbd6c28d8ae7f6816ec1e02e crypto/modes/asm/ghash-parisc.pl +e6d6ce559210aee1e97f098683e290c221cc90f6f4f8047b331e8071a8387559 crypto/modes/asm/ghash-riscv64-zvkb-zvbc.pl +b08e0ca3f0e1d53fdd4d1ee831885c92c1a0b8798e84426edeba9b356386e720 crypto/modes/asm/ghash-riscv64-zvkg.pl +494b4b36fd7c7d0e464be76f723c46ae7ad173593ff0556525edfdc974e66c32 crypto/modes/asm/ghash-riscv64.pl +875b21d8a7c70267a21ff4e5bd0e8ab8c19e48421af7e41a62d345d43ca99f13 crypto/modes/asm/ghash-s390x.pl +d8759e6e76861e0f978017bee2ed2ae8854e2c09655acef3b7f1df6da3a1f1ac crypto/modes/asm/ghash-sparcv9.pl f41a5e32029807f239a10f39573033149266564bab65c0e460b2b4dbe75e1ea7 crypto/modes/asm/ghash-x86.pl -b2351b8097fec165e8d467b395b6334283857f04817e0960bb11a3dd0baaf732 crypto/modes/asm/ghash-x86_64.pl -270757e9893c605162a1f96db1927aa2a98b758a640a6f69cbd124433c9e603a crypto/modes/asm/ghashp8-ppc.pl -6046fa0334247fa4a2d57dcfb5a7df4ad3b4208b74f4ee9b94f168556a59531c crypto/modes/asm/ghashv8-armx.pl +96b243353459bfe90bd57d5308091391857fa1a9a9101ede8631c639d618a96c crypto/modes/asm/ghash-x86_64.pl +a19f8e9e1c1a45a4052df6d87c1a1acec56af7676428b7b3e306e89b5c5f603c crypto/modes/asm/ghashp8-ppc.pl +1b870056206ff39200d7c28fc2185c3f61a218174464b90530e199ebe1668395 crypto/modes/asm/ghashv8-armx.pl ca4be187fc1805d498f2adb823509f0519e214644029c18d331b5b01a0891a9d crypto/modes/cbc128.c -979ec7af2df2bd6cad5218ba1dac44316e04447c0a1420bf849ad2ee3402a373 crypto/modes/ccm128.c +2a6e6a6d617ca931ba38f07850c547b920a9ac654ec1f5249f0a8abcd609c935 crypto/modes/ccm128.c 00d68c071ecc99c471ec0af7e393f5b5ad38bd89483227291cf4cab08ad74964 crypto/modes/cfb128.c -2a0ab07286b70ce4aa0caf3b5b4be2c00eed3a6d855e9542ae94d0e1f586b1e3 crypto/modes/ctr128.c -59be0f955b16434efc2618109a01571884c6876af785f1db5dad69786124b341 crypto/modes/gcm128.c +bdab424f63a346d60f6d07fb4c0d9fab48cc85b4c64583d9801cb43392be2c48 crypto/modes/ctr128.c +2ac13ae869304fce0f248115bd0e7f48edc08152b0e20e4f2e666e8767bc45fa crypto/modes/gcm128.c b431ff38c3a85943f71be0d76b063dbe2930967629b8721465b8152ab7867296 crypto/modes/ofb128.c -79e5e7f10d5b0709f119d1a0a9ed26e35649e0ce087ecfadc269be027b62c11e crypto/modes/wrap128.c -0a10e0cae6f4ac164afe97a64df09c8412145c8a25f387ff3a53ff7495572cbc crypto/modes/xts128.c -9a34ad9ae361f689b0b98c454092e89567d0bfc969c08a14c8001e60976920b2 crypto/modes/xts128gb.c -8bb331184f903c84f6959abc106c4ca13acd6d461f8cf6bf0ff454224510fa94 crypto/o_str.c -44594139dab6ada1f34f9c6887c97e258c1204b833a6c20f58097f17d0f1645e crypto/packet.c -2041b36f24c4a9dd2bd5626a49638f00f473867654692be64c836f30d6c6a70a crypto/param_build.c -cae7bd4973d36edbdc3bdd8d2c8d157f2c4fcfae00fdf821b67aebb789bc8aa6 crypto/param_build_set.c +4c2cdcc761cea83f65144acb094103b26d252278ec80db7ea7032b17b25a8e3b crypto/modes/wrap128.c +cdd53ad2af48dbad3b68dec8cb902d4cd26bfb5fef43c2469140fe0be97c620d crypto/modes/xts128.c +217561385ce8d6bc343d9724eaed448d53fa97446deee3bbcb9956ed0d625e2f crypto/modes/xts128gb.c +3b1fa6a6158a42cd186a9c2f25909a13f4dc4e37ef18425dd22995ab8575f1a9 crypto/o_str.c +b110c946016da9d0f1afd83886f380879159c11d17c5b6242ea5ddf8ca60a83f crypto/objects/objects.pl +334ca8ee920a8b00a698e1f2f239b33d70056b866333129902bc1e1e83798ef2 crypto/packet.c +f061cf845509153d3aa301746a9182a94cc7cf3e09720223e817b9b55594f5a9 crypto/param_build.c +01d89a771ab23f96857539fb0149d2e4db92269228089d86dfeecf0bf1893ac4 crypto/param_build_set.c d880778d542d5d4d1788ac54df26bb842726d3344d8f1b83254c9e36bac20ab7 crypto/params.c 538c45b8c28e54a0ccc7c3ca446ff5cedbf8ed711b69d67dba7e1acc3327fc80 crypto/params_dup.c 6c193cfc31c3ba5d6234a09d32198a15ab8a40258824ad7d79ac9fed8faf54e7 crypto/params_from_text.c -f30334eb0a8679a4b605ac74d65c479535475b4fb6749db9153215cbaa8ab741 crypto/ppccap.c -bc316512d4f520323fdda48c5236799b7438db66d1743924ee731df68964ba11 crypto/ppccpuid.pl +f05472fb0cb8104f21eb2381dc4fd314425a3e4e93622f89595ca58c0d22ea0e crypto/ppccap.c +56699c7486998cb6c4979eaf79affafe528aa0d7e3b9ec38d7f52091c447a4e6 crypto/ppccpuid.pl 42eff8da564cd8004f2d17fb01686d24977d931c37c7e6de693e7d414c2d7914 crypto/property/defn_cache.c -384339a8b418f2a773eaa6aa6d030f2f09ba519627b6a228ada125e905fb8431 crypto/property/property.c -7f936270992015923e5f6e81b1afad0148b9034693d3cf4665465f839a28c81f crypto/property/property_local.h -71ccd54b74799afe44ec12e1ec8b6b7ece60bc25a00b9b49044ade025a2c39f8 crypto/property/property_parse.c +709886b72802a4203d134766cf4b68f736e5067b5cc1c6fe8ed97e43b9b004c8 crypto/property/property.c +e8100495a62f53f95e38a7c4748ce47973a2a70b799468de1d5a26ca8639f5bb crypto/property/property_local.h +2577c6f712200633fd27236928d4e857248ff9ace2c8858e9295185e0b07571c crypto/property/property_parse.c fce93d3e7da046501120573317248945945845a7aca1344e36a386d44504f441 crypto/property/property_query.c 5b35510efa119157e9e217996870778d1ab5f69612cc1bcc8a6df372a625e875 crypto/property/property_string.c -f2bcb311e4725e4b8262c2c9d4670b2891882d8eec8b3a4cb458bda17356ed8b crypto/provider_core.c -aa58d7800d3ccf2989b0de3c2e2710dfac36c88dc51659129897b0dfd2162527 crypto/provider_local.h +112d12387a54c61024c70ca276067a82b6d78649e2e372a97e911e4044996da7 crypto/provider_core.c +2142e38017cb142e0901eeb38dc12bc435ca367fdba05a613e8506076133a6f2 crypto/provider_local.h 5ba2e1c74ddcd0453d02e32612299d1eef18eff8493a7606c15d0dc3738ad1d9 crypto/provider_predefined.c -082be396f304ad23859ac18c819661958825a7e4e181e8fba20a4df654ea3cd2 crypto/rand/rand_lib.c +fea6fedc3cb6dade8d84e96f5b6a3e716a0968e1383892f97c76b30dcfea3d30 crypto/rand/rand_lib.c 9e162caba63741e3df4d0f1c49a7555263ebc120cfb643546ea7e34d3f5eb862 crypto/rand/rand_local.h -dce7413b4c4e588c9a099c6fd7c6c9a397e034f259a2027d4ea8bdfe149164fa crypto/rcu_internal.h -6ff9cac4f1fe14d1b588f952391bfdb8c982d97c32d21a1894c26537ad76ca0b crypto/riscv32cpuid.pl -b7c97c6ae3468d0d86005adb0939263164d37281406cca031a120a21e506dece crypto/riscv64cpuid.pl -576bff6e8284f6102ab5affc6dd9c4fa518febb1e5dee482f55a9bf37a0d94da crypto/riscvcap.c -f0c8792a99132e0b9c027cfa7370f45594a115934cdc9e8f23bdd64abecaf7fd crypto/rsa/rsa_acvp_test_params.c -f6d0ddac7d1402595de729dc80b39a4f7e7970be177e3732218dc7f28f0638b7 crypto/rsa/rsa_backend.c +9e523dff5c62a0a779135f76db25b846d90bf36973417b4c3fac682e4ced5705 crypto/rcu_internal.h +0c1d3e0e857e9e4f84752a8ef0b619d8af0d81427b52facbd0174e685dac9a47 crypto/riscv32cpuid.pl +231263dffc16987f5288592ebf4c0738902d5146bfc16bcd8a157e044cb697da crypto/riscv64cpuid.pl +759c3d109401d500748e57137025f2a6070d36f72c729a65a6b39f33255eed4b crypto/riscvcap.c +eac38a6e61721c1a6c769a6854b6b0158b99bc696aabe30bda37197d9220ef94 crypto/rsa/rsa_acvp_test_params.c +6b04a82053d271ac15ff48a02c12025e9fcf56032e393bfe95d1007a15bd6596 crypto/rsa/rsa_backend.c 38a102cd1da1f6ca5a46e6a22f018237964336274385f5c70cbedcaa6997647e crypto/rsa/rsa_chk.c 793fbad15585312a0a1452eaea2c7590c6bdb4a8d8083eaa0ed0539b5021f913 crypto/rsa/rsa_crpt.c -ca8d150835c483801a06c347a5f90ae798183b5cdf552f3c8bd45fedb0d176de crypto/rsa/rsa_gen.c -fe5ed26c0481b13b499fc2db1768e732f0f50bfe20ba98e8f12efed9ce3579e1 crypto/rsa/rsa_lib.c +4e2bb2f1bdba81c6a13f09857f3cf5e8f8bb3ebf263a4b8201f3455a3eb7af87 crypto/rsa/rsa_gen.c +fe3a05a150a0377584c3acb30d4349aac801ab302b87752c0ae9c0415c18218a crypto/rsa/rsa_lib.c 47b04c9ec369f85037f78a5f84f281180eb99c91518f8576fe92c7a3b21e1181 crypto/rsa/rsa_local.h cf0b75cd54b61b9b9a290ef18d0ddce9fb26a029a54eb3f720d9b25188440f00 crypto/rsa/rsa_mp_names.c 5c60f6e05db82e13178d805deb1947b8eee4a905e6e77523d3b288da70a46bb5 crypto/rsa/rsa_none.c cf7e95467a6e6681069ba0c6a0befeb631b499d9b2ab12db0e93967746686f11 crypto/rsa/rsa_oaep.c -9127300e1cf79310b44463ded80e5bc6c22a7abb3e58f187c0945b373b37aa94 crypto/rsa/rsa_ossl.c +269dbeab273200fc5e7f35cedb5e2b748c59cb816c23d4d3a7cf4c69cac47a3d crypto/rsa/rsa_ossl.c a7e1d7e68d93c1956d69547e2ccf7052965832a2254b2181cdb80580cb76059a crypto/rsa/rsa_pk1.c 1ab7069966decfbd479179f137d6d33be2b48eaf4aca5a44c996e86df7aee7d2 crypto/rsa/rsa_pss.c bf6d300b7e7e9e512a47c5bd1f8713806ae3033a140d83dfae4a16ad58d11170 crypto/rsa/rsa_schemes.c 58db0509f34d970a2f206d468f718c17513970315d5d5ec92822fe6f4b6523fa crypto/rsa/rsa_sign.c -5ded8ea2bfd59110420f865699a2036e59ea5d2c547d02d751b20aa415fb3050 crypto/rsa/rsa_sp800_56b_check.c +94015adec5a97f80a45dbeffcb4af9fb7edd4f2d8991a7cb6b162c9214d1a60d crypto/rsa/rsa_sp800_56b_check.c 05a1b9e1ab8b456d6b1ee35dd28a535e3bfa00ae23b87ffe5ba62109a391e670 crypto/rsa/rsa_sp800_56b_gen.c 1c1c2aeeb18bf1d69e8f134315b7e50d8f43d30eb1aa5bf42983eec9136a2fdc crypto/rsa/rsa_x931.c -230546c5b027d30d42d90f5143014a158daf007a9e113fde56c3ff60555ee36a crypto/s390xcap.c -e754a236fe8a7b90f3280d9e22301571ed337c81a2fc120e2355d7d89a0bbd21 crypto/s390xcpuid.pl +72e25c2393a6d0901f50d145ca540cee71d74065fe3e8dd838ca415bf4f0dea6 crypto/s390xcap.c +2b35fdf635cf34dd5d3e2667fefa23e4e02f6e61e3bc02483b46e0c9ab853b4b crypto/s390xcpuid.pl 5208fa95788e28d0ce9a22a6199329bf235a203bc70c3bc4c5aa0ba1052d56ae crypto/self_test_core.c -3e5ee4eb747472c88551edd6a48eb7b4330a4fc452eea263ad8aa4255df0000c crypto/sha/asm/keccak1600-armv4.pl -87ef49f2f47357c1f0912b22eca1305641a5873a4d959379140e92a7432832b1 crypto/sha/asm/keccak1600-armv8.pl -7c27d9c9da79214ccecb240629019f4e2debdba27210f5170a6f3a3857bbe94c crypto/sha/asm/keccak1600-avx2.pl -143130638124b6d07f3bc4f8677a286db31d524a71625152629eb1f9bd434a53 crypto/sha/asm/keccak1600-avx512.pl -b7f1f4e69d41812dba39226aea0942fb2e3a638308c3130b0c83bb636a258ce6 crypto/sha/asm/keccak1600-avx512vl.pl -18e5996c0a32335587b2f06bc0c6071acd2c1f9e94d9ea284d02dcffc7879dcb crypto/sha/asm/keccak1600-c64x.pl +d930a73ecefbf19a5dee23db4d4c29374e2a0a02ec76f7e22b9219d62fc2e1d8 crypto/sha/asm/keccak1600-armv4.pl +0174bfec43e851c582ff013ca6dc5bceb49f8a10e44919b3121ebeb01d7bcd4d crypto/sha/asm/keccak1600-armv8.pl +d56474cae546601c705ea1bc4638c75b3d8e6d88907a59fb4bdff56c2980352e crypto/sha/asm/keccak1600-avx2.pl +c9b0255759ec71ce0ba8943663971889f1cb95d6d0285061a30d91f530485edb crypto/sha/asm/keccak1600-avx512.pl +4b8c44211d1d9262e992a2acba093a5358c166628facf168600ac943d2620de9 crypto/sha/asm/keccak1600-avx512vl.pl +964e9cc9f3eecc272e540a1435834d6ad337314c840f65a87bb656acd05b585b crypto/sha/asm/keccak1600-c64x.pl 2395b8b2e66dcfe8edcb402275000f6e0b2ef360f702c9af6b9bc94d7f1dc159 crypto/sha/asm/keccak1600-mmx.pl -520154ccd4914696da01fa63c0edc814ae31ad3d61dc8923fea4dd87d8ba776b crypto/sha/asm/keccak1600-ppc64.pl -82a84e6ae5ffe90e76530de560f6261c5004c23923fa9fd9aa2aae3852976426 crypto/sha/asm/keccak1600-s390x.pl -e485942ed7f7bf1f376059ed2e5e194907348f44a4308dfc4bbc2d8be05fed99 crypto/sha/asm/keccak1600-x86_64.pl -af173b53537e18453705a3843e0629334b37e8ca03483a2b164fd48252289da3 crypto/sha/asm/keccak1600p8-ppc.pl -d27078e0478f34536f596e037887ad673b05537d9cd4b79376e902774a4c8340 crypto/sha/asm/keccak1600x4-avx512vl.pl -3dd5e288f70b684d337f4054119935ab46af4042a40dffdca203868fe943bae0 crypto/sha/asm/sha1-586.pl -58378cb694b61022d70956ab344331d7577f9a26431acd00a60bed91229b29eb crypto/sha/asm/sha1-alpha.pl -8576b406e8596c8ac56a351a92175accfcf4121dd3dbffc59bae7d0ece0b0dab crypto/sha/asm/sha1-armv4-large.pl -45e94fb91cc4b4a620bc6f7e1f402d2d2ec174f0e95052b7aee903e8ae43cbd5 crypto/sha/asm/sha1-armv8.pl -790680438c562a88df6c6f57414f61e2f1de696aae564c82e6ff833bd5a6d7b3 crypto/sha/asm/sha1-c64xplus.pl -9e898aa25b009746ae1b6d59bd3bb250e845b96c0c2c0de47262f36e3bdb8030 crypto/sha/asm/sha1-ia64.pl -ac3a51a60944aacb1f5254af491bc0d2afa1a8d8c47ba810fb38f322c3f2eaf9 crypto/sha/asm/sha1-mb-x86_64.pl -bac612ad4f4468d37029e28668226145bc91b0ea5de0c01fe01a7699d3b155c1 crypto/sha/asm/sha1-mips.pl -c7ab165675d451820ebb0779eb127ec7e1292019d067ac9695688097156a6c5d crypto/sha/asm/sha1-parisc.pl -901ba1ccd75ae6cfdc8332ff2365540a652a214317be28178e6a9791dfdfdb0d crypto/sha/asm/sha1-ppc.pl -94bdf0d13c27f5e0fb326903bef2a98569a884b7e5f5d51e55854276c91105ad crypto/sha/asm/sha1-s390x.pl -68db366f13e563ee846b44803a83e47e5909f77ffa75d12ae75daf6c19250219 crypto/sha/asm/sha1-sparcv9.pl -13276a3511fc0ff4ca0ae0f2c9bd8823f95ed88ac336528ba112329d845a1e29 crypto/sha/asm/sha1-sparcv9a.pl -2f22676d49707cedff20a3a3cff21934b93da164ff2849c5eeff1caf85672bdb crypto/sha/asm/sha1-thumb.pl -877a6147742f47ffe46d7da5a0c84b73428d6872b08f25fa50c67c3be6a9d7e9 crypto/sha/asm/sha1-x86_64.pl -36347a3d023cb843df237bce38d853b9c707d7220b60cac92a0314f39aa1e2f3 crypto/sha/asm/sha256-586.pl -0863e4bc9abcff3ddb85366b85aeb96a0ed55f4cedb3d02ccbbf01f670e553ea crypto/sha/asm/sha256-armv4.pl -6b8967b077d436936ed35edff401f3849a0ee9584d72eaa0fa5b14b838584827 crypto/sha/asm/sha256-c64xplus.pl -70a60ee1dd87d63def18ce29e852371815d8160504d12cff56bd7d1c05ef7cbd crypto/sha/asm/sha256-loongarch64.pl -8c481dac264c04b8bd238e13906846469ce6a3acfa0d22e7535c5f8928d534d8 crypto/sha/asm/sha256-mb-x86_64.pl -9df59c692cf3fe82c9fee5ca6ceb7841380e1afa0d79d68d96dd9d38be509211 crypto/sha/asm/sha256-riscv64-zbb.pl -8bd86c98b6ca967d351582bad71f0a6586f7e084ed337c78c6e7d7d927fdf078 crypto/sha/asm/sha256-riscv64-zvkb-zvknha_or_zvknhb.pl +e00d9184904272baa04ab3102e8317afe607316ddc78db5c855889e3d672b689 crypto/sha/asm/keccak1600-ppc64.pl +0767b1be357af4b3a218f1f07ef436e5d98afca3022ac9311200f6e5ae9b3461 crypto/sha/asm/keccak1600-s390x.pl +76af6d6e11c85785a3f18bf3c0752720a0f4dd06a446bce727f497c7433e830c crypto/sha/asm/keccak1600-x86_64.pl +477aad2b2a0c2c37a7c77954ac57bf689083849fb4ce08775d142194811082a5 crypto/sha/asm/keccak1600p8-ppc.pl +3233f062832f2fb001ef16321d8cdc113200c47ee95dd1573e2fd5445736c8e1 crypto/sha/asm/keccak1600x4-avx512vl.pl +88fcd1affd6248cecced55943233123e83200724bdb4375dc50db9c7c8d10c58 crypto/sha/asm/sha1-586.pl +7f39b1520b56fd73c12816c5c77a7ea6135f2d7ef89f554da3051e1940231624 crypto/sha/asm/sha1-alpha.pl +05840aea1ef6d241251bebd0868839fb913d3f096f24113cd760188c398be2a6 crypto/sha/asm/sha1-armv4-large.pl +3599df0b8ddb675a2b5ccdf4b70e082cdc8b5f8ec1637a60a87e92804686c54b crypto/sha/asm/sha1-armv8.pl +6381f1889846bdaa24f75e1185f4c97ec5ac5dfff626597faff236eef9e63788 crypto/sha/asm/sha1-c64xplus.pl +d176b9e6afa31d78fcb8e4910c47470ab64147905c07f4c5fb9fc213069b715c crypto/sha/asm/sha1-ia64.pl +77b7cd02401f4027d5021850edce3bd671c47a7acbad6f6e91fcb6c28e66b376 crypto/sha/asm/sha1-mb-x86_64.pl +d8441688572a1fede172218fc5acb992ccdf71dde1922f4534415bb305e98877 crypto/sha/asm/sha1-mips.pl +ca4e704100b80846d8d9d2d32eb93771a92017caa232132c6327e62f75091940 crypto/sha/asm/sha1-parisc.pl +25a2fc55400d704949791b7d8228e3df55a9776a1babb21dc4223a041119fa76 crypto/sha/asm/sha1-ppc.pl +802f030552d864fa9a9fbd309b37811ecab5da948cdb1fa40826cbc947286e33 crypto/sha/asm/sha1-s390x.pl +8867342f71353242ed838f081f2781b6484ec934f4c0ef91711eb847aef48020 crypto/sha/asm/sha1-sparcv9.pl +df6b90dae6339b4dcc0e352b76709a46011cf595ed608ebab19cafbcb368424d crypto/sha/asm/sha1-sparcv9a.pl +eb2dfd8215310afcaa691bc2a46f81b8db8290ebc4e6f54cda8c2d32848fed61 crypto/sha/asm/sha1-thumb.pl +528f3fa188aaefd686163aaab96d3456a759edeb0f129d899c23f5c97053423e crypto/sha/asm/sha1-x86_64.pl +7274c02e3a418c354afeb447bd565c7d2fcef8db60fadfd5a336d196c9830561 crypto/sha/asm/sha256-586.pl +808684cbbc806c2c6e61a9900a5d30949bd9f38fede216f2b3e9e5ef11524f88 crypto/sha/asm/sha256-armv4.pl +a86031a4bbf6331d12ab0e907acdadf5aabd37414cd45090ef81854775f25aec crypto/sha/asm/sha256-c64xplus.pl +a797bed66d8b75b5025e241e954766d6a2da27dd6eaf80c6c2f7b72b752319e0 crypto/sha/asm/sha256-loongarch64.pl +c5952c63a9edb1371f15ff4894c1d8322374cc3ee38abbc938a7ce7ce4d3ae4c crypto/sha/asm/sha256-mb-x86_64.pl +54d7834e65765333506ba40456c1a137d76cfef5a1a4b371633f031bbfe12903 crypto/sha/asm/sha256-riscv64-zbb.pl +0e8f7b84df31911e29e9d433758a9ad25baec6c5e266cc658fb49cf11d6aba52 crypto/sha/asm/sha256-riscv64-zvkb-zvknha_or_zvknhb.pl 6023a473eafb92cd4bc0584d0e85f92c2bf57b4cde6cc2f6d2a930e3955d7d7d crypto/sha/asm/sha512-586.pl -5ff8a22efdbb049af001804fe788ab3718e387aad8a98e533e52f7f3f18f82b2 crypto/sha/asm/sha512-armv4.pl -2ebb034955ff154a8432c5c21d414bb9781232559eddd14edcc135ad72e712e4 crypto/sha/asm/sha512-armv8.pl -b620385bb40853156a1a0e4ad1169eb45c66583c7fb045c818d388f54e5a2b20 crypto/sha/asm/sha512-c64xplus.pl -feb4283e1bb2a36f0a98d4cd7b43ac78c40b72efeab8d58b4f0aad8b65a1d2ba crypto/sha/asm/sha512-ia64.pl -03302cb8fd3d580ae9dbad2eb65fd6d542893a86e481caef2286d42fbcd0b5fc crypto/sha/asm/sha512-loongarch64.pl -25c2bbaf0da5fe56c663ff7b926cf3284a2845df9911172316a8384e15ab7ef5 crypto/sha/asm/sha512-mips.pl -3b9ba893f84e56bd26e40907ad178884aa61ee529133691d87b7746c9ad13ed3 crypto/sha/asm/sha512-parisc.pl -952ef1b10e8bbe3f638cc798b91ab9c5b47b66ed8fe94647b1beec9874f2e71e crypto/sha/asm/sha512-ppc.pl -97d3701a260bdd16c26633dfe8c00d3f4fafe09a0fc8fd3d667098d1e2a94066 crypto/sha/asm/sha512-riscv64-zbb.pl -901cc96f156549f4ecca65d0315aa7d1c2c108f911aef3c4884cbaebbac2bc08 crypto/sha/asm/sha512-riscv64-zvkb-zvknhb.pl -648db5b748d07367579dd60cb551526081fd45c5dfaac989c5b1496d8af631e9 crypto/sha/asm/sha512-s390x.pl -58ed1513cd35553f83424bb0441a77af0efd467165a190b91990b124ecdb9b84 crypto/sha/asm/sha512-sparcv9.pl -93202a363880831a69bd3833be729645cfedfa97acbf27d4e3147cbc9b55e234 crypto/sha/asm/sha512-x86_64.pl -16ecc37bb09a47ad590fe8d8bbb4c9f583812348464bc83e1eaf117a05f50fec crypto/sha/asm/sha512p8-ppc.pl +c8325d40ef658a434e6faf88316c508c9b0d24ecfb4a693c1aedac96e7b0164c crypto/sha/asm/sha512-armv4.pl +819682a0a43fdab4e720045c9c393e311a74f2f4348f7569dc2317e9e9705923 crypto/sha/asm/sha512-armv8.pl +78baa4f179ca31cc7c9960d23cb5859c1c77f1b9a8cbaef899d834fab9ce81c7 crypto/sha/asm/sha512-c64xplus.pl +514a52bf4480f30b0f481be60bacedf24c8459785acf407e00ea78ca459bda92 crypto/sha/asm/sha512-ia64.pl +3f7ee296ee0c4cd15bd74e44bc2c5caf8a6a0584a2b790a9e9fce58a88bb7e86 crypto/sha/asm/sha512-loongarch64.pl +95907297ab1cd7fe7d9e9aa78306a80a8872bae9888beb7f2e8120d46616dcc7 crypto/sha/asm/sha512-mips.pl +52a73a7fd9d02e7cf46be05d4f643d427f20e47897fdd657607e8eb698882f96 crypto/sha/asm/sha512-parisc.pl +7c0c490ce6bb11a228853aecad5e164ce84e5bdabb8a6658ae7184782076c7d3 crypto/sha/asm/sha512-ppc.pl +e9241b71795c6c0ccc767c5a5fd1025e72396b6c693f4c3bf66d41f265ee8e28 crypto/sha/asm/sha512-riscv64-zbb.pl +2945418ff51f148435d6da5bd2c708d1332f7715a290d626300305f8bac0c733 crypto/sha/asm/sha512-riscv64-zvkb-zvknhb.pl +de1a04aa146382ebc9065fffe1ad2987cb731860d63488bec72a78ccb7a2431a crypto/sha/asm/sha512-s390x.pl +e416eb206a985da933f84612eaeffe186aeea582144b323e09a59b46638915f7 crypto/sha/asm/sha512-sparcv9.pl +ec06dbdd2afdfd9fd034e499c0d8246445092e3dd8b4f39c6d47013abf088d17 crypto/sha/asm/sha512-x86_64.pl +a2fcc3bf2a0604e15c5ba12b068e4417fa1f9f494b9c23b7ca155e1cd439d422 crypto/sha/asm/sha512p8-ppc.pl 93858e3b530333a129127b8df8cd3326cf55b770238b4fff2474c4e6e3def1dd crypto/sha/keccak1600.c 306cacd3f86e5cacaca74c58ef862516515e5c0cafaff48636d537fd84f1c2fb crypto/sha/sha1dgst.c -f6021e6e5f4694579ba5a014e2aba44b6d436b2fd25c18ecd474a7383042b027 crypto/sha/sha256.c -ed6049496d9786296d011a4582ffcfe0859a609b37f1f4ce57cee36136ee526c crypto/sha/sha3.c +977a5eec2260fb431c4f0f2342510b754099c981e7a0a71fe8ad44b61812561f crypto/sha/sha256.c +28aa674a4132986ee1897c136da6da2c80ae79fc87b01ce652f3e449bad11adf crypto/sha/sha3.c db0f16a4cb9c86f971b4defbee9dccd77345766f64efc45e0f1bc8d448bfb3e3 crypto/sha/sha3_encode.c -8def0b2e5996f2a2e187abcb7443e5e98edd4be0f71ff918a1b8c717cb97eb27 crypto/sha/sha3_x4_avx512vl.c -833e0990a4b8590a40990bfe1cfe59542ece6923fde37d3dd6faddfe1b9418fc crypto/sha/sha512.c -7b99b3c9fa26c5e58a56cbbb62b6e2bfe62542a662799f910387e76e5688a13a crypto/sha/sha_local.h +a11b8ddd91272bfa7c16b44e7245c46bc64d3fa69189f10d090b2e7e9c5f9199 crypto/sha/sha3_x4_avx512vl.c +e6ec6fa358faecd55e8f34896836027cddfa9817434dc82fb2d15fab4679b2b4 crypto/sha/sha512.c +c23f344a1a288741e76c4280f24999a8f83fed4b3f721c9c5e3f803829709e95 crypto/sha/sha_local.h dfd99e02830973ab349409ac6ba0ee901ba7736216030965bd7e5a54356abd7c crypto/slh_dsa/slh_adrs.c -c9b270de1259d9fa71a4d352786357bcf1dd3d22075edab84501e2f8e550b271 crypto/slh_dsa/slh_adrs.h -2aa41787214996542778a42eaf1bc754809f7d4d31185ac77424a3c686d6759c crypto/slh_dsa/slh_dsa.c -a48a4d00db9002872b1e45614a5e6f07b414c35875e8ba97ad63d0f9ff0134d7 crypto/slh_dsa/slh_dsa_hash_ctx.c -19700f0e69d6cee82fd9431321c9b0b1306ec50bf3ec65639199cfd5422f2768 crypto/slh_dsa/slh_dsa_key.c -c2958f29237fa77b3f3ab37aa716caf836e4b38815701155fa86c831b3532e9b crypto/slh_dsa/slh_dsa_key.h -43c6339d529f80b0a92292c5bb5dfa81a8203cdbbf52082dbc8fe84b78f0f09b crypto/slh_dsa/slh_dsa_local.h -adb3f4dea52396935b8442df7b36ed99324d3f3e8ce3fdf714d6dfd683e1f9f0 crypto/slh_dsa/slh_fors.c -36b2968d2e79dcb9314fddecd9c4618247bd4fe3bf1d63d5c7572c430eedafe2 crypto/slh_dsa/slh_hash.c -5877632817d6950b75a0670153bad3c9c844216e387e0cd8eeefc22e056050f3 crypto/slh_dsa/slh_hash.h -6402664fbb259808a6f7b5a5d6be2b4a3cc8a905399d97b160cdb3e4a97c02c4 crypto/slh_dsa/slh_hypertree.c +247a37a0a6763fd2472e01d27c9162d0821bf5787719ca10a2774f9a643e8392 crypto/slh_dsa/slh_adrs.h +26566d0e641456101bd17338dbbb16f59dfacd34f76cff5882133a0ab7323130 crypto/slh_dsa/slh_dsa.c +af39e0ae447d88ec8fa16dc3b05588d68527540d96821ac6d6f1c1ac368ea72b crypto/slh_dsa/slh_dsa_hash_ctx.c +3e2f65a316bf8b13319c9f2ea911feb55eba973f8a171c1702f1ba426774dd76 crypto/slh_dsa/slh_dsa_key.c +8c12c3b167708727ad3ecf33cb854870106512a2d5c2ce4846f9ed0cf7c999c8 crypto/slh_dsa/slh_dsa_key.h +2fd9f207756ada903e54d7b6bdad8ce53215e6f985b2a98572e5d843f270c269 crypto/slh_dsa/slh_dsa_local.h +6d3f3c0be706c1dd871db863f2344f709a2b7fbb60a0d91298aeb2222f767a87 crypto/slh_dsa/slh_fors.c +0b30525e0c5436dbf120f133522dc767d86d546530e6456e97aa322ad1ed3f79 crypto/slh_dsa/slh_hash.c +2eddb199ee2e08d9d1929de29adb91a92eed04dd51b61d055ef8d19e03a28b5e crypto/slh_dsa/slh_hash.h +1eebf59ebd0859be5a8deddd2f664f99158060904234532af608a44dd6d92d19 crypto/slh_dsa/slh_hypertree.c 1ce9b4f4f90a6f82005c9cdc0ea1f6b6876556c76f8bfd95f4c003a1c195a266 crypto/slh_dsa/slh_params.c -86b16a2c36d708cb880ba49648bb3051c2997188c8ea6aec9292534b97232c7f crypto/slh_dsa/slh_params.h -c84761d4e089bbb5bf2a42a9e4dc2b5ea380e1cf95c6b97528ae2a4d98e9b7f2 crypto/slh_dsa/slh_wots.c -59db81a3342c0c89b030756168b9a7f09c938b2cd3498335108e0a32c041b6e7 crypto/slh_dsa/slh_xmss.c -8701465c481b58fc7420ed577332586aec4c6696a5daecb2ff5071c7a6056245 crypto/sparccpuid.S -b462d1efe0acd798e1ec5f37fd1c824a587e1773e6a6f984d5a332581573ecbc crypto/sparcv9cap.c +fd3ec58cfd1a5b9473dad3cc8061376c0fca5a87bc917bd44123bd960227703d crypto/slh_dsa/slh_params.h +9730bc92de7d84035899f6bd146e235d2239a85266d98c4ffa59ec57646f2aaf crypto/slh_dsa/slh_wots.c +37fff5f88dd8bcd0ad8cdbab130c5a9a018422fe59b141bdb11bcee8fd1b046f crypto/slh_dsa/slh_xmss.c +567e7a1c118691b36c2484bbcd32d1b7ffd47add996eeb35b3ad0e7810c21161 crypto/sparccpuid.S +11dc0907c256e37a0da3075906e6868e1dc3a0d0dd612a39a281e40dad75dedc crypto/sparcv9cap.c 51b5a944b67582044afc852e2d16135f382835c3b519271f820878a933ebe348 crypto/sparse_array.c -6704975a0f11799e82e6e136ba52c610e4930fb95ecff7e10e29ba07ce698994 crypto/stack/stack.c +32c5f00b33508ecf709f0b8b9979af7d7958db12ebbf948c00d96bf23d74317a crypto/stack/stack.c c0c4fd0f112465c6766072e25268c2f9019430e2c08c3c0a4271603d24d79f04 crypto/thread/api.c e298c753be277ad9a2ac0132d9897cb4c85607dbb2d11cfefd0c98e0f6a723d9 crypto/thread/arch.c 5c02ff77d290ca0deb19672c1ed6fc0f47a0d630f61398a204a2684a7d418f0a crypto/thread/arch/thread_none.c cb214ad206ea69ab98d24a727a47d3a4c614fce709e6b7fe6997dbaeed92f0fc crypto/thread/arch/thread_posix.c -5db84d4b3c5799051df8e8db85322b156c7e696e23544422479735156e29d6cc crypto/thread/arch/thread_win.c +619d77aa1275cb3eb3db63ecd3bfa225ab3bc97f38ff0b2f0b9024f60f3544c9 crypto/thread/arch/thread_win.c 55953eb5a84d03e8d915ee867ddf8ec8be8c5eb444ea0b21b12a040a57e2c2c1 crypto/thread/internal.c 828d68c5fb820f4e270954ad940b60ff194d361eefd87f581bc56a3c4461174a crypto/threads_common.c 2e5955d706b96c487e4875ffbe208fac15bdca06b33cee916d5343978c14efa1 crypto/threads_lib.c -483ac173f53acb89035ff1fc7a3c54fe3aa5b22b00517194d59ee9357bd2b8c0 crypto/threads_none.c -bc684682c5b4669abfe8798ab05583b96d8d1b95c046b1043a11c48e6fef7def crypto/threads_pthread.c -698baaded1a5f1d3430e1b5cbd75cadba173a969f83de67850090bfaa52b7a42 crypto/threads_win.c +8ce87fc586d2665d6d53c601cb22f656558a4caadfa7b6088fb689d59a91a114 crypto/threads_none.c +33441fef79bbfc8264312d0d203c001aa7260cc7163c116057db62a6a491ae27 crypto/threads_pthread.c +bb9eb8d1a6f5713c54622c4ed36a9c3134c3eb0ac22602be063e9fb46fae820f crypto/threads_win.c 93f8fe09f96492a6be6772ddbf0cc37912fc2a90acb7faea378da1735fe20f6f crypto/time.c -7bb1345172689dabc21287a5775ab95062c33634064796631efde07e8b75f035 crypto/x86_64cpuid.pl -e2c6e8ade621e4b0fbeacef2908d042ae93bd7bbb916bb1ff25a4d11e917faf0 crypto/x86cpuid.pl -68dc7e15fbf2193f2d8e1138721f7f80c34578b5025465cc99270d796b537bf1 include/crypto/aes_platform.h -0cf9115128d082e5cbe94b3f961dabd045c1dff339fefe3aa5066d48517a1aa1 include/crypto/asn1.h +148cb7eff07f42f5e932673ea78eb8dfd225a541d8fbb54bcd457db0f2b40d4b crypto/x86_64cpuid.pl +980c86ea30dabb27f318ac3bf7441155caca85530e5c9688f82c3ca153e26cda crypto/x86cpuid.pl +c4dd8a542ebba1ae20cee48e5ff20a4ddf68ee46be439b90f1e0709f825cf487 include/crypto/aes_platform.h +6cf2b1cca0e2689a6a53e30805bea9321be49597cf3c41381c4175fa600c8699 include/crypto/asn1.h 9acd69adc80fbf9fa88fed4bcc7b3c0ba87e2add98d7ba311d8b092a2d5a0d2c include/crypto/asn1_dsa.h 3bf019778a3cde9d296c4e400e23aa6ccd14b12f42b6a5d9e18ba987b28ee3da include/crypto/bn.h -7a43a4898fcc8446065e6c99249bcc14e475716e8c1d40d50408c0ab179520e6 include/crypto/bn_dh.h +2f4961d93df8332e58e0500925c7c35dccd179f46b389e3258ec712222297151 include/crypto/bn_dh.h 8ca9d3c460dfcc437cf99b9412208a555d2dbdc01081c327765729c94ac133c1 include/crypto/cmac.h -7e45c76bfb2ff324d39442439077fdbf5edfc45e2e0ecd2fd80f664be0be9abb include/crypto/context.h +348ef240d54ee43d95e40936c571b218f27fb5a7ba21369dbeed7a29c571ba03 include/crypto/context.h 273da25316489e04e5dd0675a5e8baf2f9e51080de06bfcd85b29ebbbd7c063d include/crypto/cryptlib.h 8a55e7d62cd241e1f37e48ebc0deee22ed793ccfe094c46138a41d856f26e015 include/crypto/ctype.h -fb109231b7f7fc2e83dd39ec6ef14d88f6ee60cc91ef1efd0c49fa7eeaa50ace include/crypto/decoder.h -96632debc11dad16535e48708a3d89df7c2c0cef9843e4bee271071bcd3d15d9 include/crypto/des_platform.h +2bf927a09b5a409aa2ddf8390500f549b425ff4a0c4bc24c9520cd38295cc5f5 include/crypto/decoder.h +60fae5119740085488c0c96efdc278b17915c29f04cc5ffd7503b288ec9030e0 include/crypto/des_platform.h 1f94e0ce9b3e4b3bf80e8777261d22fe6d5bbecfc79fb3be805daba738b7551a include/crypto/dh.h 07da49c53dab98e3a50b3d8a21953227ead3aedae570c80584b9c2ce5988d20b include/crypto/dsa.h -2a146319aa6f2788d0c072fcf197b23fd394910a11366df34c1dc4fa2d896e0f include/crypto/ec.h +c88b1ecda000ed04f1384fe9656d9daf6ce0ad6f6bdaeaff5975318e66f5eaed include/crypto/ec.h +1358210d72d55cf7f5a10049e8c2cb704a3a4825f51067ca1b67ef1173492270 include/crypto/ec_params.h.in 8eef8896afdccc8c90c548e0d11b290c004df3231a1777e8205b88c04645c4b5 include/crypto/ecx.h -4af06cb0219605fdbb606b0b6de51e34aa0503b42457a424f80c7c0c39dcc985 include/crypto/evp.h +356c020bb43ef9cc74196ba5202b6ba27a556c5c1634d813934acab81776c874 include/crypto/evp.h fc22d8a6d80875c8c45c51a449069b936eadb9621aa9c0bcc8c5d493eed1e52c include/crypto/lhash.h -0651a33eb67395c48ca64650dc2912326b7c0b7b47832e0c59bc4139e7f271c6 include/crypto/md32_common.inc +ab213f48a42742b4c206e90c3b25a73a9de2911b8f5e0b0a3b1ef2429abebd61 include/crypto/md32_common.inc 47a92e596adaf252ed86d3c363e1b7d1893445aaef302eb50cf18473c3c08541 include/crypto/ml_dsa.h 60b558f2990b9f390dee864dbd15372a98dc2dd95c4701c088a5a804198e7421 include/crypto/ml_kem.h -b7a00f7e37fb4054d371438f270e67eb584eacb9b13fe29536dac90e8371436d include/crypto/modes.h -f20e5cd691a360e9d12a7d41fb33b7f1639922543271d642534532edf85564b8 include/crypto/rand.h +10bfb1eb1af9617d47b6a6575249d01123c64523022b0dd07a22a82d9390eb97 include/crypto/modes.h +7a873c39719cc5a2c5f03fb5652e1acb72c76147eacfbb8c6e393de985726484 include/crypto/rand.h b4fc407f0ed2c4a1795bcdbef3ccdc68be327ae40bd401fcb1066df0a63bda7b include/crypto/rand_pool.h -9724de5c6aca5a2ad2f95f137543eef5070d76a9b6775913b00242fd6e338d1d include/crypto/rsa.h -3f28391ed526d791a578e76a40961592e15ae2bf62b81d5924525e1f21684659 include/crypto/security_bits.h +439cbdd09695d1c55870c27a89ccad4e91f1852ff8f8b2914e5e3f5b7414c2a4 include/crypto/rsa.h +e0333468855777f69f0dc54d5c98a8c37da4ce7c469b486e2810d2c2af916790 include/crypto/rsa_params.h.in +0f42d85c523845a1baeeb68534a088435bb32c9c49fd6058ad2c9bbd3566c232 include/crypto/security_bits.h 95904882055bb9a1732c38b99ec45a2895d41e6009ab952e36264bef5389ba45 include/crypto/sha.h 169800966e382419cdcb30265fe786708f9b9ccc4fbb1b8c17641a7fbf4cb369 include/crypto/slh_dsa.h -df915f569207111cdb011e85ee0f40bcd169ac0a413cc858ccee0b5001cefbb5 include/crypto/sparse_array.h +be63011d904f3e7900dc5a147e0207489031ecf24ce077bfba197da5618756ce include/crypto/sparse_array.h eb1f4f50bafdd357aa15b54f60f5ecde10876253038f00bf518fbf60840addc1 include/crypto/types.h -fb45d44ba49848c67551f008f97d3686628c3c59641a727eac99ac2e28cfba4a include/internal/bio.h -63ae5eec130d8cc15d19bc6b1e655023a0e4590b3a2054230e58dd1e107fa4f6 include/internal/common.h -fe75a08a48dec0ec0bfa02875b21d20ac3a0e9e8d05cdbbd5d5299978495385e include/internal/conf.h -31a4cb7ee45d243fcf71673fa22c9b6e93456e6ffc5b0a0460531db68e040e44 include/internal/constant_time.h -306412e987e63cf2354268c3dbf9e9e19f8253d577561a3cb77f48ba74100e11 include/internal/core.h -f08179621d19535c0fe8a5aff3525b75de61f883b8bd80b8dfab4a68b5615b2e include/internal/cryptlib.h +8901a5cd447c85fc4703203732cd1e9b5abec3057dc6e81d42a723ddaf141a54 include/internal/bio.h +77f0ae1270615845f9c7c882c0bdafe6cfd78222195b8f4b07530bd15a7ded3e include/internal/common.h +9d5b2446c6079b16a978fa7ea7331b86c196958a14282bec87ae2fb0f4314310 include/internal/conf.h +7428e90224e06ec45ed9637cffad5997e668da0e0b7b00842bc968375b5f87f6 include/internal/constant_time.h +3042ba0527a0925e01c3ccdc9f451d73e3774dc1113baaecfc16532dcfb01648 include/internal/core.h +911d7522863ab8c2259e708386e4d208b7a8a1b5b44ce6fcff08c05c5b604c45 include/internal/cryptlib.h cd215e01800987b008be87ccf85823fc98be0c578262a7720cbb6e9ac3dd81fa include/internal/deprecated.h 178940dc972f22a8a481a16fd63a86e7468e88cbaa1db5fd68c2b1ae64cb6865 include/internal/der.h 0dba4a6565caebfef82a8dc90d6ba208b2c61445123724769d5ee84ebbb0a610 include/internal/deterministic_nonce.h 984b04ad2f0a2036fa157099c3b1ed5300c079a665c8d26d3451eefd06fc1e25 include/internal/dso.h -e5fcc33def2500935c7706ab8dc1b5d44a4a4135ec8135b9bde55f4d8a4c191a include/internal/dsoerr.h -97baa18b5dece75e7445a80494b2db2462e012287fa3b9454a74750363b757bd include/internal/e_os.h -4c6d7d437065e39b8609d10aee66855a7820b25569fa06477ec5db818cd2d406 include/internal/e_winsock.h +beb309cb070ffb3c3c6a39d973f5b0c433a6269f3e720285a777d62731f2521b include/internal/e_os.h +998d9abd4b6a542b7f419fbe451495c6f798b3a8be24a24d2009a09eba5d5601 include/internal/e_winsock.h f799af7ba63ccbe14c468625c4bf3669cb9405825ffea57435eee7e7973f2fbe include/internal/encoder.h b41a5d9a7bdf60df169e327b41f16489830b82393dd663d1f89f81da4483eaa7 include/internal/endian.h 18007208e049b62e62a416543c37c4b64f81ef6e00188ec0b2016f206e260a2f include/internal/ffc.h -09d5d6683c1d688409d1619dd303f938f02b2e2b9e3a2d5186c54f73ca49b114 include/internal/fips.h +357f4769dbe44383685576a644a4b3aefa3071b8b02c95efb8d3f64bf4f3054d include/internal/fips.h 923d4fb14a08f9b251b9bf9727bc50930d0279e8b63243faf85374bdcbbfc4e0 include/internal/hashfunc.h -65bc8c144bec1e91f6126ca8c0e5e39a520970c4fe1dcf36f2a3817d06a7f2d6 include/internal/hashtable.h +99d94123b69d42b4d91342a07d2122cf4235e7744baad6a077f84b93d71cc285 include/internal/hashtable.h +3744e3f5bf42c001d454e6f004cf23ffc50a79840fbe45373f62a158a2a181bc include/internal/list.h e93523559408ad5ded0fc87ccbc43213f4dd449ad98c2df3d3b6116f2d3a217c include/internal/mem_alloc_utils.h -14cbf044dbf0f4052c74f14954042a8b8ddf90b56123fa0f2b1264f77baddc75 include/internal/namemap.h +3fd1c5ab0038214039112e1f74f30e572fe9db13a120dcdaddce34950dd90290 include/internal/namemap.h c367e6120d26a2b629f4db7e179973e33fb095e1102d5c7a69c744b88ebe4469 include/internal/nelem.h f95b3f0ef8a5c47b8be185f4f4ec3baaa6304ed3f7a608fa3aec3c99af0e10d6 include/internal/numbers.h -2287c91ae739fea5178768cc3376d59f730fca046fb71c3432037e061e569ad4 include/internal/packet.h -52686e2cd1049e7b0cd6c6a4085952bb83a04823215c42b1b8e6da19b2511d83 include/internal/param_build_set.h -677c7271c8bb9c2a9ed1b79aefc7a06b8746f71afa8557833167da62eee205f2 include/internal/params.h +2d851ff441c835518d6a4328c614a7d1d49bbaf88fb57b7a41312006bb164e68 include/internal/packet.h +677319c4ee2abaa8752a1a60e6002eb54bd2cbb8601e4227ff1b75ee2a6c837e include/internal/param_build_set.h +84b4977424564d536834bea5a913173ba55d7cb280e28ad01cb24d8a96dee53d include/internal/params.h ee75ecd35b3ae90c51ace957ab7ce06de3c7d5064b97a878241ff65cc943a6db include/internal/property.h -7aeac9a78efb9ea5147f639cd474e6c2538acc1b9d255ba19dc661fe22bcd94d include/internal/propertyerr.h 5b108c19f064ec47fffe1b3fe310d4693b6db3920b8cc2e5dc05595751ab0f3b include/internal/provider.h -3f476694478c1125574dfb2e75c4c0c0d04c7d3d763176686a4730028513fcd5 include/internal/rcu.h -b6e33da6011b2b74d27e39f27cf98e6f123fe47826562b6479d0dbd5c758c4c2 include/internal/refcount.h +0a16bdf16ba4e75f70535ffbd3e27acd9df32b2c9ef30af901e5a112b9e8649f include/internal/rcu.h +e0c4611145ef33bd025953105d088eb7fe268fbb3c7dd149b1707e88d278aa81 include/internal/refcount.h f77c0844cc44bd92965647cd8cb6addb210f0300a8d1090da8c26e4382e87c2c include/internal/safe_math.h 17f6585bc81ad324d00aaacd558e0176dbe22cc7cbdb353c8c9072fa40000a58 include/internal/sha3.h 8e672cc0620606b044f63b8446125f5233d64e3eea59df54c1fcca6bc90ba537 include/internal/sizes.h -188be736ff23a2202fe594e6d49a7ccf4c23a7baa86e2dac5d58360f21d9c986 include/internal/skey.h -abf03dc8635f2925bdc2299feabe115f8d5d6eaa450b421172ded222872386ba include/internal/ssl3_cbc.h +6b1d59c45ed2bd1b049796e67c4d08309fa25914741bf7ac72e3e41447e27916 include/internal/skey.h +13f5026187ffd14e25b07c7599cef394056816f4a396d0ed0d2da1b5a67e775e include/internal/ssl3_cbc.h 780bf5e9a5852e8776a3b9984993a91f27f3f7b1501e1b2185f5a8f448b0d848 include/internal/symhacks.h fb5bdada32614d7214569dc111b8bbc43592886799f0536b844a64a2541727cb include/internal/thread.h -a8fa7ddc1e54ca296bda9ee05a7a39bb7e803eb0567cc75a9b949b80cada7552 include/internal/thread_arch.h +0b643d952f420db92958ba36651efcc48af3569c297efe6c66b31970fc686e44 include/internal/thread_arch.h 1cc86957e734ce34acd949b9e9e9d588a6c82afb68a09c787fb69f5e4cb20b1a include/internal/thread_once.h -fe4d85ab26d1a6f0933c28044b0f6b62d67ef1c30fea336a5446da88f646a14a include/internal/threads_common.h +62743b397c0664019fa3b64163b043d5fcca1d936b99ab121ca85fe8b83172fb include/internal/threads_common.h e9f51092f519bcd826942a5310c05c9f943fd63a92c5d0053d49a2489531be33 include/internal/time.h -30045240c1f070530b8360e3ae4b372bf1eddb4e7bbd51649cc86193857f6217 include/internal/tlsgroups.h -ea4e067f1b4cb0f896f0f8b7e2ff9e1161c528f5038d84f52c7c96b25488ce9d include/internal/tlssigalgs.h -79db205cd380711f09748b4ab020442050acaa0a8a940e2be38c4916e23dd1ff include/internal/to_hex.h -426c2eccbb31696175b2680b91bed727e0bf6e632657bd9e6c25fce7c8375d92 include/internal/tsan_assist.h +2383f5a41e656e374ef76d32bbf85cfaac9f852608ab3f618f1da2d1f273c7a8 include/internal/tlsgroups.h +b25e3644be98a7ec10dee5f62d5ee514fd352436184acd8c5428142aaecd89d9 include/internal/tlssigalgs.h +302629396c89b383fa202d540458f8a156f4ff506e7d0a87d5128514d9e9e040 include/internal/to_hex.h +411ae2d50baeb706c63bd276f9d35b6c2acbfa003061af517fe5977d2ae135aa include/internal/tsan_assist.h +2b9c5270ece34eb081176cf94f7a998725b7b53c70e9eb9bf8a4ccdec10c099f include/internal/zeroization.h 3e6bbff5295764bfee6fec91a8807e9fa345a7dcba70d55062df1a8d6f98758c include/openssl/aes.h -945f6d797dbebe5738e549d814f71222a20a070a062fdb4c33650a45aa611e93 include/openssl/asn1.h.in -0e28b492fc1f2da095ea42267480c9961a4f8cde3314e409f90395af8c65357e include/openssl/asn1err.h -77a9f9595cee6448c6217a8388127593a34a0d0a585197a5f8100fcb792f76ec include/openssl/asn1t.h.in -598935a01d51a1d74401e12c5f4717f86b5c085afe4835a0878619ec09af2e95 include/openssl/bio.h.in -40491414172d977a4667589fa2f269d7deaae675555b8348d96f315d1a6253bb include/openssl/bioerr.h -e58f86e76a8b46ea7ea2cf4bc5641023b7199572a77d0ab243b845545f3c40d3 include/openssl/bn.h -c506c9bfbac7368335fb2a8a627755ce2b8547a251d885242a89c9f8ff3bf079 include/openssl/bnerr.h +839f50fa340c8c3b041c7ac0ea071ef70ee32164dd80ac2741c77fe7e9df0e7f include/openssl/asn1.h.in +7b78d6a39e77c8f537968fd89cf8696e318170074e48ff5ee50ff4df6fd4a14a include/openssl/asn1t.h.in +619f726ec5b75fc83cbcc24ac7182d99d1ef70eda8dab1a1e41099501393d85b include/openssl/bio.h.in +ba17c035e356438090eb963766707b968e668022470e1669b8230d95aeae944a include/openssl/bn.h c70499c9109b083beb69d1b17807266b041d0ff28694d5bc1ab7cf2a59331c39 include/openssl/buffer.h -5bce6559638266f060eaa16b3b90738bbd5292d62230b6b3b1e22b88836a5030 include/openssl/buffererr.h 2a83e38101abb3c2da0e07f9bf7012d8167a3c1588df65c36652c4f72aeafc27 include/openssl/byteorder.h 0d499118db0c65974b768a048460a5ce2aa9b80154763856571fbfa6490703a6 include/openssl/cmac.h -c5b95f844eaa367cc6f608b51c2b1f6ffebcdcb8ca6c3ec2fc2bd355d000f2ba include/openssl/cms.h.in -e99dccb7d94349e8b4431df4be60a93c2698f59a3101698985acb640b61a5efc include/openssl/cmserr.h +b5b67e56450ac882e39c1a82d46e446f46c747c7771d850f488261575c1df162 include/openssl/cms.h.in 1cd9648cc536f25cff10656096ebb1d9353adf3ad855d1c25a22b142ec1705e0 include/openssl/conf.h.in -3517c480b3211d384d4b36fa48d8dce8923fcccd99fefae68635b3f82eb0acb6 include/openssl/conferr.h 4e195b6f7a734756e21c4269cc245b292e1a563aaec5644402929d0eac423c41 include/openssl/configuration.h.in f76830b31c947d86c2e6a302ab8df6b83076f8d29120bce9a58195551eb48e1a include/openssl/conftypes.h a013fca5cc6b5cc26eb1c76eaeba31e99408e88fe89c343a44cc0b22f8e63eab include/openssl/core.h -834f08e9531aa5ccfdd34e5fa8bc759d6ee4a3f91ce42de9877ce5bd71840d87 include/openssl/core_dispatch.h -13dd8d11be44ba25e9a0e362d5ce8b797bfafaa271661b1c7e866faf72b0a4dd include/openssl/core_names.h.in -d4ac103754c2ee212d0f97823d7f4237baa32b2acd66875aef4aad12d0884963 include/openssl/crypto.h.in -128ef415305b704d51461ab98c688c69fde868acb5f5f74c92b2d0517823e71a include/openssl/cryptoerr.h +b374269dd2f45187e9aff9055df2de82829e783943a8e554359f8ac20ddc8f71 include/openssl/core_dispatch.h +72acc617c93ee36ec7f4a279a8b32edd7bee68546c8a23f24351f32b1c2d6043 include/openssl/core_names.h.in +5ae850f05cddf04205fe946bc226918430e68b2740c62b85ef13bc8dc3576602 include/openssl/crypto.h.in 2e5b0109741b7d37a0d1a5c0c8ae9b9320bc9b0e71c3e05093d27f14f598295e include/openssl/cryptoerr_legacy.h a147bf48583b902b3db0d30dd2a9565f1c9f3ec94dd57652e31be4c67b7d2593 include/openssl/decoder.h -8d8a2f1286cf40264a80e090d377edaabfa4b040dc0e5314ac41406e0dcb0fdc include/openssl/decodererr.h 402c76d3a33378f6dad64778503581e4f80e2ec46ac24c84646234a06acac5dc include/openssl/des.h 148f89bd4ce3a7e24d70b7ee459b666961f1a43e961bb6936f41026f6ed7c278 include/openssl/dh.h -5658c7f5cd57d74c7644c63c6328e80469fab9d3e29dd734f1433cf3019dd4ab include/openssl/dherr.h 181833ed01a0ddd7ee9977c65e34c6aaedf63afbed74e7340c0faca42ee7b3ec include/openssl/dsa.h -d526f8def9e4bb31ff85dbc9494e6b3fe1ab15f424a8e53b3b8fff9dcc40c803 include/openssl/dsaerr.h -9a6478f1536f171dc1478eb39cede4d8834ed01447ce50e06030426697a68a7e include/openssl/e_os2.h +f0ae483215cfaa5d61a55374a06a0fc987f2ab3d1af437f1dc61a619f5943613 include/openssl/e_os2.h fcb8e2174725eef1279ba8ed046e56c99805796a13eb789ff78aadf7a73e6c76 include/openssl/ebcdic.h -64a56b81cdc7a45bca5bc3d24ecc8db22839d90b8d843318cd79306aeae94811 include/openssl/ec.h -9c56b594bfde630c9b8df2fe0c691c74cf79fffb1c1b5e2034ade844e6e3c7d3 include/openssl/ecerr.h +fab81b1fdd6df131a62f06380dd7ab361f235cb7abcf0e591d729bcd9e7126a5 include/openssl/ec.h 07d47054034660f93646c0aa86aaa1314e8c973ea4eb0642e5b09820359a5571 include/openssl/encoder.h -165f96bd4637e057b6500b91b99667b9095b8c3bf53caa28e5fb9fd74e748a29 include/openssl/encodererr.h d6ca2a3ad4ded065bcfd8cb8de68215186662c277631bd17bd7b542b7fefd1e5 include/openssl/err.h.in -5adfaf02d7051e5513e90b921c2cf1731661d34a50960559af9b80f1bfbc28e8 include/openssl/evp.h -b353076927c4273840c8f72377f7b9c6f28730e3f8a353c69d7ac3215532d738 include/openssl/evperr.h +084348c607a97b2e91967a79aee19bfe3ded6afe2202d4551b7481f6ea0b3a19 include/openssl/evp.h 0399e15a86163ebe1bd31da2de617d4455f63fce42da741ceca0c1df08066b80 include/openssl/fips_names.h f29f8b7f23486e11b5307234d0f3efc56afc9a1321ac9792429493fadeb4a08e include/openssl/fipskey.h.in 24d2351e5cd9ff4608b4262519cbd806d267f62c2f480adc4169a150d6355f34 include/openssl/hmac.h a7c65894dd0f3730769d56a46bc6e4777c9bd7c8826998373d2ccdd9a346f840 include/openssl/http.h 1dc0dce58de44226fc0afb51073c39933fb65dfd3a0131c4eff17bcb93018665 include/openssl/indicator.h -972e54ea69ac234315ad4616ee0546f47fb61afed727eb3a1c2e718a3b5d6999 include/openssl/kdf.h +9606f8f3728b3edd1b95be84c6df79b118018a51b9f7ff0b1e53325eb93d307a include/openssl/kdf.h f4a6b9adcd0158222878f5c55e3b40c620361d328bc624ce22d4937c0c054fbf include/openssl/lhash.h.in -d862fa698982ba613990fd4da07598a32d0fdef091a71dc39a280218a780b7c5 include/openssl/macros.h +f22ee02bbe0ad86f49ae4ffd1dd5d0cbf6de266fb9c094857dffac1a1fce51fe include/openssl/macros.h 0da95b5743f5c12ba1a30c1ef84f9fe57ccd5816febb1b5fd3a4f573ec885cd8 include/openssl/ml_kem.h 06f0d4621c344401f280a4e69e48ba987a0600b7f52ee16b25c4620277b081f9 include/openssl/modes.h -fae2bcfa44744276acdec4693badd9663904a0e60311e968aa912f4f167162e7 include/openssl/obj_mac.h a4127bd23a35828e90addb54b6a1cdfa6a1864038690fcc63053604629fb6f3f include/openssl/objects.h -884f19dffa0b6e0f03fb565cc61cf800993eafe7fc9df0ca2feef67e3b199963 include/openssl/objectserr.h 429571177fe9a2ce5fffce21697ecf197bd9b645bdbc578a146418ce8286e9eb include/openssl/opensslconf.h 76386f806a801eba4c0172c52dc0e04e2deb192aa867f9d3e9d98a4d5a932d4a include/openssl/opensslv.h.in 4c4640740b5de9debbc82bcb5b3e02282c145e440e40dea478a804b8c3498065 include/openssl/param_build.h 3a9bfb4f64a2cba78546c02aa1b6f4593ce7adfd8ed7b37e007916bcc954e8cc include/openssl/params.h -86abdfafc2b5a9467eb20830b96dd7cd9a95c72aec7dd3a798dd70541853f3c3 include/openssl/pkcs7.h.in -2b25ec134dace5f5e1b0d52650d72c61c2243720358c0b3e645ad956b27d897b include/openssl/pkcs7err.h -a15b0b69bc1e31d0091ad32f04021d4fba9750cf9e3c9c0d2509358543cac380 include/openssl/prov_ssl.h -e783f0de83be4c120573090c646281d25f3eb3cd3475f7f2e9d78afe28b63629 include/openssl/proverr.h +3b0bdeaaeeb584692d2126b82e4d853f4f936d46694e9cbef95b79f3d8000767 include/openssl/pkcs7.h.in +2f72e2a9ad00bdb14d003b28220e3e1ef59a3fd19c4f6a7bd931ddd8799827eb include/openssl/prov_ssl.h d0fffeeaf8a20f6c86e8a6bfaeb1eab7c00188b1844c109ead4232c8dfb3705b include/openssl/provider.h c712b7eeca499c968893efbc2964e100d257fb5add90152f6c35403192744040 include/openssl/rand.h -23d76dfea708747bdc2ffac41e25b156a22d2d0cb744323a3b9859c54bfbb98a include/openssl/randerr.h 4c93d2209b91002ed5f0e4abd4591e6949e60ff044a37da03172a13cc9067151 include/openssl/rsa.h -8ce33ec31a1652646286f921726e3da41be0a06ffe2e348a00b29887a8061a4f include/openssl/rsaerr.h -f123ff856086475f6147a89f3ce27ff646143f91bba1da45d4419db2b2731108 include/openssl/safestack.h.in -a7acbdc844ca0bcaef392ff3e9b0c5b40c906b0b69477cfa57f8503a96d3daaa include/openssl/self_test.h +6110f3dbde2b83456f4d8fe36885c8422ba49daf06308458d37466daea58aa2f include/openssl/safestack.h.in +8a942b471f64248a420bde94f91347469cf429b22d7a0a5f0da6342b6fba2236 include/openssl/self_test.h 1e5408273c5d453a35b00bbff90c899f31acef09da52f63e80b0ad7f93c7f1e7 include/openssl/sha.h -d01e26cccbd89ad20196b83ebaf9dde1ebeeb7344e9d4cec52786f54121ef3c5 include/openssl/stack.h +b254fc24197cadeb1eacf992501573f25ae6a2a2705189775a3d469dbda4490a include/openssl/stack.h d381d0b4113f0fa18b3e421eae303fc84daf84eacb1236cb6e9976409a2d33a9 include/openssl/symhacks.h fc527427bafa6862d9e3847c961dd6cbbcccc39d25762c65ad3b99fae9599e2e include/openssl/thread.h 2f0b0b7d7384d901bd5a6f161f821cdd4a4d0db07148431fc3d549aa553d129f include/openssl/trace.h 52c3892ddc32bb44bda1e41f659f8bb94e946dd677323d96ee39935176659167 include/openssl/types.h 76683d46aba0e790ba708d2eacb751a8bbff0796091d30dcd2b344f3f1e8461f include/openssl/x509.h.in -32abce4cd052c706f5efbe803044807f27b87d61797fb023d811ddc2162974e9 include/openssl/x509_vfy.h.in -2b2f987b082a69f1eeb7c56e11ffab485a9203a2aaba9d50004a67fb029db729 include/openssl/x509err.h -aa3a3001c8d92e5b5376a40fa599eb58bb9536d06494a2a6e2f0e35bb6d49cba include/openssl/x509v3.h.in -16b57e962c0b6c35f16f6c0790ab72c279e1c5743024546ef5830d8f5acc0ad8 include/openssl/x509v3err.h +382ecfb0f0fc07299c2b5cb03c45a9deaab899785ea8f148660e0f9d43c61529 include/openssl/x509_vfy.h.in +761b4894e9f48094a875401323c18631263e1922a90dc182ff3c4c2fa3b965bc include/openssl/x509v3.h.in c0a9551efccf43f3dd748d4fd8ec897ddaabbc629c00ec1ad76ce983e1195a13 providers/common/bio_prov.c -aacfd1289e0fecd66a3fecb28c0870752bf1bc375084d7d1ec018db032cfe955 providers/common/capabilities.c +12cd8976df7d50210939a1ef21aa1e59a057b7e088716beed3cd257145828344 providers/common/capabilities.c f94b7435d4ec888ec30df1c611afa8b9eedbb59e905a2c7cb17cfc8c4b9b85b8 providers/common/der/der_digests_gen.c.in 424d7b2ece984a0904b80c73e541400c6e2d50a285c397dd323b440a4f2a8d8e providers/common/der/der_dsa_gen.c.in 27ff361a5fbfc97cd41690ab26639708961d0507b60912f55f5919649842c6ae providers/common/der/der_dsa_key.c @@ -614,155 +596,153 @@ f3b089fd3dcccc8e3ebfbbdbf87c47d58330f82bd0e2a1223da74977930cccf1 providers/comm 5d0e18a680f82632bda6ee9fb9ef61993ce0f2bc9884451e946a25130f27fc99 providers/common/der/der_slh_dsa_key.c 0b18bc007f296e16f6210956f5b6ab612b77d8a95170f12ae32764125901db6d providers/common/der/der_wrap_gen.c.in d447cd774869da68a2cc0bbb19c547ee6ed4858c7aee1f3d5bba7796f97823a9 providers/common/digest_to_nid.c -440c8ce0a4ca9f63157202bbfa26e12fec25847215fbae3416274124604ada6e providers/common/include/prov/bio.h +da16552c0d4cb90c116c55c7cbc739b8c957c97b5e4180fa1ba524599390bdab providers/common/include/prov/bio.h 18ce379903b078446945da9116026da8639b4b0d81d357f86f9674a2a5cb94ef providers/common/include/prov/der_digests.h.in c0a020765feb7ededc7e6f20b2b140dca09f347cc72404a5c7971df82b2f9ad0 providers/common/include/prov/der_dsa.h.in 6024645ac9e165685b0a44a20feb342355eb06c07b7c7954508a125348570aea providers/common/include/prov/der_ec.h.in 5b6b7d8d12011c48195b7db8f65bc4bc4a48fb753763a3ce5006dc227b5139d7 providers/common/include/prov/der_ecx.h.in d0bdefe8353562f61c8c58cdba46b67e6a1fa5cc3b9b21605f619f7605fbeb60 providers/common/include/prov/der_hkdf.h.in ceea7616712e6ec4ff475a806998d66354d228f634e733a75e345bf78da32958 providers/common/include/prov/der_ml_dsa.h.in -b9c85795c2c45fbf301ec8077df54ff9d570cfa82407eb07420c366dd7ff2486 providers/common/include/prov/der_pq_dsa.h +8eda99cba58c342dcd1418b0fa7c367a0520686f6f9f2fbb235661b7a5f5d94d providers/common/include/prov/der_pq_dsa.h ce605f32413b09d33ce5795de9498a08183895c3347f33344f9ae5d31c29ccac providers/common/include/prov/der_rsa.h.in a36d6762f74d9ac4f437e634e60f2b4de1ff5416bb6dd5d2cffe2e4556556b1b providers/common/include/prov/der_slh_dsa.h.in 6c1fa3f229c6f049c3ac152c4c265f3eb056d94221b82df95a15400649690e93 providers/common/include/prov/der_wrap.h.in -e5c7da25b919ac4d2d84f21c9d552f29c2b06ba4445401bd4e361be45f4f8d30 providers/common/include/prov/proverr.h dff610c91cb41d9d6ea4084119d496a7e1d7973fc7831323d4b353f2b57acdfb providers/common/include/prov/provider_ctx.h -7c41320b73d85db6f07dec1e11bce0bd8ff620c8f1d81cd9c0ec4926f902f597 providers/common/include/prov/provider_util.h -5bfd27719e282266273a4a2eb63d79833d3e0b94c2fd683ba1ccf565be0072d7 providers/common/include/prov/providercommon.h -bc0f539ef10023aa818ba2cfaed31e2be9cb80141fce89d3d2c23f0906711677 providers/common/include/prov/securitycheck.h +3e85dba040878ad0a437bcfb08965aff4c4c1179679658b61e7ad5eb55771ab3 providers/common/include/prov/provider_util.h +87b2c2fabd81dc0e1e8fb7fb8aa99a7bad58d3aac420afa778c9811dd0b0f959 providers/common/include/prov/providercommon.h +7c6743102724255c28a6ac1085263ea4b7ce064ae665815289c96e78f0149e2d providers/common/include/prov/securitycheck.h f3e31bd6776b55c924bbba8ad0f0727096b1d407b1d8b22f1f1a0f969a03fc4f providers/common/provider_ctx.c -4b46687c8d14d7ff4227d03f6fdff5e25cc1a3e7d74a76473d87ffaf182f2181 providers/common/provider_err.c 9c835f67256a6657b04ad7c2bb7e724aa40cc8b636a06e9409026758bede799f providers/common/provider_seeding.c bf6193d6a5ff6222e2382f0d0c3321ffeb1534a9ad78fe594aa838761aad3162 providers/common/provider_util.c b10730f4d302344579c09f43d5f9c5538bb6b4acd60de7430c24269fc522d5a5 providers/common/securitycheck.c b8550dadf2f12a98b30ae39eba026f5f959e8f889df39fcf9eea0cbe7f4a3244 providers/common/securitycheck_fips.c abd5997bc33b681a4ab275978b92aebca0806a4a3f0c2f41dacf11b3b6f4e101 providers/fips/fips_entry.c 8b07ece9ea02de5648f95719668e0e7d2167c9162ae68c8c35be66db20c1fa8b providers/fips/fipsindicator.c -8759568b4f3882131913739090f9638109b36e686a5f3b68f167398d61247fc9 providers/fips/fipsprov.c -8f4f57148aec16d44948b21f21f7eaa7145cc296e3c4201451d6a783aa4f8e4d providers/fips/include/fips/fipsindicator.h -c35c84f9c7033fc44ce7942b63a94e2619bc4cd8c7fda0d6024c3af4febfebd1 providers/fips/include/fipscommon.h -b757e583f8bbd767f8c59bbb788c30e3c6ab8ec94f98430fdce3d73ad565f952 providers/fips/self_test.c -5d313319a66425f0b54076570807961d5f433a73674f4300fd34b43ea9d4c232 providers/fips/self_test.h -bcb310a409affe057f9785e2a5a3e1ba5ddec65fcf7ecdf0ff7b2420d884c857 providers/fips/self_test_data.c -56fc365c9f73990b826d4b1dedc6e62f28f67d7d986af4651bf4ab3a587c0ad6 providers/fips/self_test_kats.c +4d1268debd72b6b5d078d21062dcea72f9cfb17fd0c95477c1e874e62d66bbef providers/fips/fipsprov.c +5ddcfdfc9a50ae44399f4500ba6d776f90c3bf0ce1d9b457d5e906ed3541fedb providers/fips/include/fips/fipsindicator.h +4816988279bfd01c4dec1352489099c58a300fba70a28714d29d0ac57bd1f210 providers/fips/include/fipscommon.h +5e00a45680b9f283005d63354aa05c29ee343a0b564e0d73861877fcae8f30a7 providers/fips/self_test.c +dc13c409d5957dfbb0e5879bd9c714334f2fe619824ab424ca98b46db66045bd providers/fips/self_test.h +6ec16306973f6d52fe5462b326badb8691ae3c09b6b33c50c1b9fa7900e9f658 providers/fips/self_test_data.c +de7b698cf016eff809715b72e2a838532679b38d55b7756f7e2f3a3f2649b2ba providers/fips/self_test_kats.c 775b222ef65c2ef3d877356f65ba4c7f12a4b7ec17f45524b716c966bebe8871 providers/implementations/asymciphers/rsa_enc.c -6cbd516c15416a32a4ddf6d3b96e8abe0facf675ba78c6299443fdc44b7af5f5 providers/implementations/ciphers/cipher_aes.c -72d028079f13774171668297bba0072208450c4fb82fc9585aebd8ead793c8a8 providers/implementations/ciphers/cipher_aes.h -cdfba3a1512d8e358daf681bec9dc3d00450d279bf47fe41aaf0fdf62f96554d providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c -1b4f19be0c2bbea99e5fce0f93189c687a03cac634f0e37a51466ee7e3510735 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.h +ee8dcd4e46ff407797872f5594d04404fff8202e2cffb4685c37ef5d543560ef providers/implementations/ciphers/cipher_aes.c +a326ab08a90c13a7e3c6c16e17b4dc6d55f5e698824c776d18bad8d3873166d7 providers/implementations/ciphers/cipher_aes.h +6cd2fe215eee7711d23f4cc0be7ec295350706e820d40f1ffda7d44c2d238f81 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c +78f960c104f089f43487e0beb9633b7bd0fc168312a6db0c4ab4b9e3fbca4ec8 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.h 348e680f78849c37cb87bf0c95212f73e364165958c8c6aa7c947d9d0dbd6a57 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_etm_hw.c -b2375518a1eb4e6427ca38c7df19e71fb3a15c6d66d1a2ee564bc973a95a743e providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c +e411dd8ab774a6368df12b08dea29ee2494ea4174c66b1999e53d80beb7777c8 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c 56a70eed1965425cf9dd6b3b693679359b56127d3e9e7eff50f4bed8491095a8 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_etm_hw.c -faedf7c0941640a56664ccbfb53c2803bdcc674e8d955a5bd386806930b4ce88 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c +761ca489c440e56d1146dc2d56d85086f9e7e6192e9a4f1703e28c579bdca593 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c 6fd920324e43b2ac621dc96a9a2973e3d652cb50f85e7e480050fc499a1a8e43 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha512_etm_hw.c -6d8486d3448471b046ab5ad75fa99620c20707d270edc7a833240c3bc4e335a1 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha_etm.c -6293f6028f2c79cf1a16d3407f3d96ec47cbf7adaae9233885a2bc5ee38dc29c providers/implementations/ciphers/cipher_aes_cbc_hmac_sha_etm.h +3ceb53650e3fc3642acbe13b6683006e43e0f79b5457045ebbd7d826bd4a3557 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha_etm.c +2c5b070e0561b61763b0a0b559d205822e4a3cb5eaa0edba0315f1b073287df3 providers/implementations/ciphers/cipher_aes_cbc_hmac_sha_etm.h dbde94765165b5ba43ab2f9a58499c7b08f85403fc0be5606ffcbd299e2dfbcc providers/implementations/ciphers/cipher_aes_ccm.c -00f36bf48e522dbb5ec71df0ec13e387955fa3672e6ff90e8a412ae95c4a642f providers/implementations/ciphers/cipher_aes_ccm.h -5df10f5f682b706d562516aca5efd2ffbaab29b9e877a43713341a6fb341c8ab providers/implementations/ciphers/cipher_aes_ccm_hw.c -302b3819ff9fdfed750185421616b248b0e1233d75b45a065490fe4762b42f55 providers/implementations/ciphers/cipher_aes_ccm_hw_aesni.inc -1b8172b09f87b743bc7fa256f875ac0e98271311e4952ad2beac2a08d4b760c6 providers/implementations/ciphers/cipher_aes_cfb.h -68e666bc49149b5cbfe480d88a6ec503d111aca110d842466d82cc9626863ac1 providers/implementations/ciphers/cipher_aes_cfb_hw.c -55a80c4153eb94907e08bf6d99c7dfa564d338a61ce07bb57cf24df0950648ef providers/implementations/ciphers/cipher_aes_cfb_hw_aesni.inc -a8eaca99a71521ff8ac4ffcf08315e59220f7e0b7f505ecddad04fadd021ec14 providers/implementations/ciphers/cipher_aes_cts.inc +241c0b2f84c6e00f650764559ee3798b9d55f27840b5c772eb3c36eb4fdb74d0 providers/implementations/ciphers/cipher_aes_ccm.h +dc74f6180f52f917477969d25ccfa5114c28e955a8f4a4b4f7ef0f3f821d241f providers/implementations/ciphers/cipher_aes_ccm_hw.c a80320d377d8dd8ba8d82c99b144401a03329ba157e62171813da72bee0ce88e providers/implementations/ciphers/cipher_aes_gcm.c -79f5a732820d2512a7f4fc2a99ece7e6e2523a51e62561eb67a4b70d5538b0c4 providers/implementations/ciphers/cipher_aes_gcm.h -68fcbf7b1a8e801fcd2f5bbc2ed1f834feeb5572cac83c1f8aae82ccfb2815ab providers/implementations/ciphers/cipher_aes_gcm_hw.c -be18c20e0197f25fe7b9e0268657a2271a69d216b89cb100f082fa5fcaad1e07 providers/implementations/ciphers/cipher_aes_gcm_hw_aesni.inc -470538c167d9345acc52d027459b8b28f59a82972e6436644d3154d3ba5fe949 providers/implementations/ciphers/cipher_aes_gcm_hw_vaes_avx512.inc -4004f50a151cdf089e918aeec42b44cda97b4547454383cb79f9b7746f384df0 providers/implementations/ciphers/cipher_aes_hw.c -d8bd5a78bfd52e6623d5a7b1764487b7a1ab828caa11ce41f8cca3c96b6339cd providers/implementations/ciphers/cipher_aes_hw_aesni.inc -b848fad5d9973e2cda10f83d0937e095a3df39ee3db610d828a0cb1d4a1eeebc providers/implementations/ciphers/cipher_aes_ocb.c -88138a1aff9705e608c0557653be92eb4de65b152555a2b79ec8b2a8fae73e8f providers/implementations/ciphers/cipher_aes_ocb.h +59ba5d733162436bd2f925a24a89ddcfcd4d7b1c5436588d3659e30c7e8e4d9d providers/implementations/ciphers/cipher_aes_gcm.h +fb4656171d8a05256c3f489249233d0b8d063cd1738267b618dc86f564c60da2 providers/implementations/ciphers/cipher_aes_gcm_hw.c +a145887f536869acf924f19942084cfd16b288a0de7db7ccbfd8023a77a0d630 providers/implementations/ciphers/cipher_aes_gcm_hw_ppc.c +b68a7a78691306dc0158722a78804240ca0a522b22264d9e69662b297ac480ab providers/implementations/ciphers/cipher_aes_hw.c +668616bfe6524644f8833e3fbf7f8945640c73266723c4f6b70aab46f011c7af providers/implementations/ciphers/cipher_aes_hw_aesni.c +5ce9cf7b79f17e5016e2785ffb8ca1f8a6b6202832a8974f70137f271e8f8688 providers/implementations/ciphers/cipher_aes_hw_armv8.c +006ab6cfd93eb2ca3f2b1cc3858c04087e6c78e528999821d2bc9ee82cda162d providers/implementations/ciphers/cipher_aes_hw_rv32i.c +548fc02c2fd384047950a692e008cb28e4b3bcc49e5e3fae0aa7b6ecf2474266 providers/implementations/ciphers/cipher_aes_hw_rv64i.c +ede48034be45a6c0a0ee66a37bc42c07945146c437897e6e90043d10c6db42d1 providers/implementations/ciphers/cipher_aes_hw_s390x.c +c58f79911106ec449818578d5bee79718ca7eef2e8ead1f3b4e07d8aad3d54ba providers/implementations/ciphers/cipher_aes_hw_t4.c +dd5134041a455f56987146900b7cd376642022e64166a4ad7d4f1a9440073c09 providers/implementations/ciphers/cipher_aes_ocb.c +cc1aab4ef55dd459d3240ddde6c9a7023301f9da61a76938e8b3eec3cb0caf5e providers/implementations/ciphers/cipher_aes_ocb.h b9cb159602c57cf06a8eeecb9f301aa3673dac0a9154dcc60dc24e8e4bd55df8 providers/implementations/ciphers/cipher_aes_ocb_hw.c -d89e435abb8cfaa8f3a6aea4b21cd25b8cae05c44a1887562e4ad19b2b0690da providers/implementations/ciphers/cipher_aes_wrp.c -3d4b18b18fe894922ae7cb6243f07754e56ae3011a8dbfe1b1fc5d2d1e5bc43b providers/implementations/ciphers/cipher_aes_xts.c -ff870fcdc063e2e9f99693e4dad5f2128130591b05928bb5395f60ddcf81b1cf providers/implementations/ciphers/cipher_aes_xts.h +fb6a566d1d1ec28bb3449dc60b86084f94b3a4ab8bbe834f78d608a4bc3f0cee providers/implementations/ciphers/cipher_aes_wrp.c +9471a9daf1fcb7766c3fd3cc3fd8ea42d373c35961d34b1c83196ac25987a8e2 providers/implementations/ciphers/cipher_aes_xts.c +4f6a0a049878cdde40c2537b45f1cd16f219366d9da3b942a558ed70a9f54fdf providers/implementations/ciphers/cipher_aes_xts.h 281157d1da4d7285d878978e6d42d0d33b3a6bc16e3bc5b6879e39093a7d70da providers/implementations/ciphers/cipher_aes_xts_fips.c -f2fc918672bc9b9d3b696934cdbac486832625953595e26943d94c8c8a30fa71 providers/implementations/ciphers/cipher_aes_xts_hw.c -dc4626becaabc3990549483d9ef5f05c7dd9a9c2cf9be96ade3ba6a6e203f7f5 providers/implementations/ciphers/cipher_cts.c -83c892e95bb3f0e0d0824f92d9792033265de1a224d8a92f119abb94994552d9 providers/implementations/ciphers/cipher_cts.h +30c226c7768d59e49d078738d9a360aae3e11c0971cd109a0f4faecdea83110d providers/implementations/ciphers/cipher_aes_xts_hw.c +97f2f84bd44aa1b9c97768e7d14d6d132ffce80663488f184fa789d7ea1b8ec7 providers/implementations/ciphers/cipher_cts.c +bc3ec200e5f13b36e5d682c589ce171b6d6e1da3a76f0ceedb916ed28eca0ec4 providers/implementations/ciphers/cipher_cts.h 1fce446497c98a84043257700ff02bb8ba04cdbb8ac92b15ca09404490e48016 providers/implementations/ciphers/cipher_tdes.c -9cfdcc860a03b6e7ced8cc21bcbbc1c070c89aefab04b07f213c7a3db1895553 providers/implementations/ciphers/cipher_tdes.h -79e01dad1d0144c9e908e29584797aa6a8d76754bf0ce9403e68b3bdd37ae180 providers/implementations/ciphers/cipher_tdes_common.c +5351100e7e262b46db84f06b8653802f1166dc3a1965c6f18fc920dc91749b30 providers/implementations/ciphers/cipher_tdes.h +8a6d64a4876f0159ca18b47025f1c78acb09429223c80f73717821110f3951ea providers/implementations/ciphers/cipher_tdes_common.c cca34f1c7baf3a98964f7ce19a59e06d1eaf2ada121a0d4a438f4078a072b325 providers/implementations/ciphers/cipher_tdes_hw.c -d1eca5f5d0eb4886f4aa9fafc9f458be97819d7f7d83641712a567d615750d4e providers/implementations/ciphers/ciphercommon.c -ab9a2edb23aa61cf31da6addd8674a6028f93399eceeeee35a56ee770338fd6c providers/implementations/ciphers/ciphercommon_block.c -cd95d8dc7e87578afa5ba62c157fc5adc92a98aeef096e11ecca15eda7d6c3b3 providers/implementations/ciphers/ciphercommon_ccm.c +5fa2f02b8de00a9c8b34e71e619062bfce0413c9cb3e3e3107ced4fca265009f providers/implementations/ciphers/ciphercommon.c +2afe5bdf23e7facf956f8a1591c10ad06088fe82b3af846ef3132c7e17bdaf82 providers/implementations/ciphers/ciphercommon_block.c +bb7632f5e32c5993eda21ae3ba87fca538e9a99022404473c4890cafea48c5be providers/implementations/ciphers/ciphercommon_ccm.c 6632a555d5bcd5af67d0355ce46c2906bb3a0dcdf1651595b29189c40a5ca675 providers/implementations/ciphers/ciphercommon_ccm_hw.c -fe8a53b6667537f72d5a352d7f795cc26f24a5d4b26dd09c5f1d7a1fd338e986 providers/implementations/ciphers/ciphercommon_gcm.c +d27bf27838ae4d24cb7184c30327321eacef1d6bc68bdd57ccee8ae4b6c4189c providers/implementations/ciphers/ciphercommon_gcm.c bb67eaa7a98494ca938726f9218213870fc97dd87b56bda950626cc794baf20b providers/implementations/ciphers/ciphercommon_gcm_hw.c 8bf2b4bef8167740ae3fffc9f0cf73327a1b4ee361e63da22c257cca0e1e2971 providers/implementations/ciphers/ciphercommon_hw.c -c4b1cb143de15acc396ce2e03fdd165defd25ebc831de9cdfacf408ea883c666 providers/implementations/ciphers/ciphercommon_local.h +6292f6f2fb30a0c93e000d5a30d8703e25764ef0b38d38f1172d59c08bbcb97d providers/implementations/ciphers/ciphercommon_local.h a639cb1b3285e41fa4372bda7b74c66a358a0b7a038cfc9a9c171e5f15beb932 providers/implementations/digests/cshake_prov.c cc9b9d6515fecfe2170b256c424e1eecb53a9849e49b1ac324c081a07d004b39 providers/implementations/digests/digestcommon.c -ff74278756bc06d7719f27e7a313c482b7d548c6eb41032b37b3383cfc332ded providers/implementations/digests/ml_dsa_mu_prov.c +f9891e1ca2945103d8ec1ba8cb0864761e46602dda3ee8a56e0b9c813e0e26b5 providers/implementations/digests/ml_dsa_mu_prov.c 794505a44c44f8d835d8e5232691ccc809ab1eb03ebcd62a2432b6c75ab0c1af providers/implementations/digests/sha2_prov.c -110a47f50d1606e49c67b236ed432f05301eb22d6b9e4eaf11d3b3e3f26761b9 providers/implementations/digests/sha3_prov.c -85c7b5945cc335871b291f38f3b9902784645323a63c44a4a38a45d6d3222ed7 providers/implementations/exchange/dh_exch.c +40e97e604772fb3e3bffc9f5d8157a511325e0e465deb6cf9e194de9ef08afe9 providers/implementations/digests/sha3_prov.c +611f6ec04fb043973b92aa7d7b851b1f458f89efae2d5c5311aaccf4d97fd304 providers/implementations/exchange/dh_exch.c eb00f306a98ac77fc6f2fe7f34d2ae5766e72c37b76145e892793173a879c590 providers/implementations/exchange/ecdh_exch.c 85d51569b5fcd2b341d86b1f4eb78174812a02d4c00e6d4983b4453d0796fd40 providers/implementations/exchange/ecx_exch.c b1115636f53bf70f417b183cafeb6d38e230d11d8de731e6896ba60cc850d931 providers/implementations/exchange/kdf_exch.c -2af71a41c00247bd6414362816f3045e138074ec563e92640c422d1c94d9f3c3 providers/implementations/include/prov/ciphercommon.h +667239515197b375b39e99cbc7d5707f63b8be7753b340c247f46b70bd621b37 providers/implementations/include/prov/ciphercommon.h 138b7525ad6c672dd0aefd3badcd683f5dbe36414031c99d893e19b0a2a3fc9f providers/implementations/include/prov/ciphercommon_aead.h -86eea720369a305488118de7bea8424802cd8bfa0641d26f4a81c24ad928b116 providers/implementations/include/prov/ciphercommon_ccm.h -97bfe62d6d191818d924575b36e2222de0c86b788b691e8c2e0253b191fcb976 providers/implementations/include/prov/ciphercommon_gcm.h +81027be248ea67351ea3a99cb8ce444a26931ba23fca4101f743ca9453138aea providers/implementations/include/prov/ciphercommon_ccm.h +cc1f569b7496736510fe643e0e12e97111a62b44b3bce228079d80c66e0789c7 providers/implementations/include/prov/ciphercommon_gcm.h 927be1df476263ba84e1561cf848e1723f9d57bb7b5bd27242db79abd028e145 providers/implementations/include/prov/digestcommon.h -92e66fb2825009f9b64051109ea40e6822b10893e3712462533547f67d1f810b providers/implementations/include/prov/drbg.h -1baf1c06b20a0eb8ec271452544922d67c1cc168dbe9853b259191de4bd99918 providers/implementations/include/prov/ecx.h +904c8e419cdb7396191e2929cdac5ee32d6edfd620730742ad894b7f007ca7b5 providers/implementations/include/prov/drbg.h +a728d88d639e090c8ac4d402a44688f1ff43690ca6a82cc659143c119404526d providers/implementations/include/prov/ecx.h b0d1f6fc3c9220fe6d4656e487bad8df16b6f840054018b95b2752ea9aef822d providers/implementations/include/prov/hmac_drbg.h -e6cdbc04157b3009a6a478670d2ba7ca8dc896967031040f104d7d0fb30c2896 providers/implementations/include/prov/implementations.h -05eedab6b16c80025f72281fa619d9480c437b800cb821b761fe4c05bc9d3af0 providers/implementations/include/prov/kdfexchange.h -4014246d44fa3f34aad5372c75d3f7eea528f1cf1798e30d5627e7620a356631 providers/implementations/include/prov/macsignature.h -b41c9a4e90d951a2d0e796b1cbbdbe8cb6fc18306d9b70be7a489249c11c294a providers/implementations/include/prov/ml_dsa.h -511ad835639f071e99eaff6dcbf516999d108ea8b3f5f3f027e0982a916cf3c3 providers/implementations/include/prov/ml_kem.h +b5d93d2cf0197319695dca610cb525129dae5900ec6987847719fb8da2dd4bc6 providers/implementations/include/prov/implementations.h +fff5e4e34ffac0520ee8b351ef8445f2040d3b1d7d467d93eddcc8f015756937 providers/implementations/include/prov/kdfexchange.h +0b6a6b74f335e10a2233f70fc02ea2673393a3668fa5be409f8ae560c4893338 providers/implementations/include/prov/macsignature.h +88cb1046cda544e67db055a4c7e57b075a94950130ac0463d11dcfd7e4ce8107 providers/implementations/include/prov/ml_dsa.h +20e07d060977d08ffc9d568633e702d5c8537b366ae87ec83822faea20043a3f providers/implementations/include/prov/ml_kem.h 8b678d26c077e9135171aa27a8038041f320aa17a3441240865c54859c864ebb providers/implementations/include/prov/mlx_kem.h -31615d056bbab02da153cc408071640af27978eb0e4cd8bbf448a01c4a32b86f providers/implementations/include/prov/names.h -b9f8781167f274ccd8b643b3bb6c4e1108fb27b2aae588518261af9415228dae providers/implementations/include/prov/seeding.h -194f0a3fd18f87467a1c311970155cf2668f1abcbbc8c16a96765bc5b152d5a6 providers/implementations/include/prov/skeymgmt_lcl.h +42c3dfee2b33f4216afd165df9ce28d38ba0c84cbfc090e238f03cc22d62299b providers/implementations/include/prov/names.h +462dbc1209f0281c1c4301e19fbb0b180d951584010da1430d9cd043cc5778b3 providers/implementations/include/prov/seeding.h +a8ce7c57945c6209da1be94dcb35b5067a088139e0918ae0723bcc17df3792bc providers/implementations/include/prov/skeymgmt_lcl.h ab4c9694d2d918304991ca85772e6ac65cdc33e44ae6de3efbdc45bd49d9f706 providers/implementations/kdfs/hkdf.c e8b4e8ebd10872ee42beeeffff7458b1d2991833edbc763e2275ce4060867b0c providers/implementations/kdfs/hmacdrbg_kdf.c +821d4b8166f151c95ab9eb27f7fd661b26ac08dc7b77deccd593dcc59206de91 providers/implementations/kdfs/ikev2kdf.c 84a83391cd7215a0d3d822f59cd08a465f82467b0e7ab4c369a266a248a99e27 providers/implementations/kdfs/kbkdf.c -80197ea75099756e7e2c66ddf2a69792a8b89942a23c60a8c21e9d87a1e1a8db providers/implementations/kdfs/pbkdf2.c -2993dfc00659a85dfad152a0ce2fea0d457213fe60e03922a0dcd6a89c6827b4 providers/implementations/kdfs/snmpkdf.c -b1b79d9d728c6d2c61e9d895c341d5f0ae882948ac6628e2cb732b3933048c92 providers/implementations/kdfs/srtpkdf.c +ac8b12984dd6712d5edf372575e381fc98c05d56ab03047434d0366ac698c954 providers/implementations/kdfs/pbkdf2.c +7d9923c486d6751c3065c6748ea5d186fa2302f802818306cdee9ffdc3ac9d2f providers/implementations/kdfs/snmpkdf.c +cc5c3ef45a6016756d25e0bb14aef4c53301231c3ae6e97579b6cfb3dde8d7b0 providers/implementations/kdfs/srtpkdf.c 4f70b937d163759b713335a194ca44ca084ce2e58c8a6d15c27e5f1bc61b17c3 providers/implementations/kdfs/sshkdf.c ecac95b5cfe9864793c0d9339acbdd2f0c07938a3e3ab7a007fcf5120f57ff83 providers/implementations/kdfs/sskdf.c 85d950d15affed86179aaae679c13cef87c35261922227bf6599b53703f54a1e providers/implementations/kdfs/tls1_prf.c 384b45edc8246a7d43a8bb6c80b55374fd0e597c7d8fb42648d30cf47104e2e2 providers/implementations/kdfs/x942kdf.c -d46253d805193b2b05fb7389178ac2479505b327b8ed383543cdd800c6532964 providers/implementations/kem/ml_kem_kem.c -35549cec7031452bb5b46aa8a86028abc7a3a2b39f9f6564fa4bd402451bc647 providers/implementations/kem/mlx_kem.c -dc82a1648da73e5b4317b3e9923da2ed9f7eb1419383b562cd9ff5613b72af5e providers/implementations/kem/rsa_kem.c -6e7674572b3824a76270bf51d528c79ecea8e7867aefcda06fcc7d6b75db35b6 providers/implementations/keymgmt/dh_kmgmt.c +ee562a2a09048ebb141addda9d4197235a67599441cfb5f702d78b07807368d9 providers/implementations/kem/ml_kem_kem.c +926e08e60171cc867220e0f106533ed155132a034690bddea1e7793a879ebf73 providers/implementations/kem/mlx_kem.c +45fbb2d6229202ac99ccbd23e4cd1a424080c5ece1332a787c9ddc0f6441c6cb providers/implementations/kem/rsa_kem.c +67e4a5b07baf8141d6c48c747873c3b642f3f5e379c59b9994102569e68c2092 providers/implementations/keymgmt/dh_kmgmt.c d34296ae8595aa1ed90b5652ab7e8fb7e2c5131f5dac7b69eeed7f0fdc2cb6ad providers/implementations/keymgmt/dsa_kmgmt.c -036ef3ffd9452f3079aa07792ce9ad0fcc28d8e66c9fec429e1015c749c81ba7 providers/implementations/keymgmt/ec_kmgmt.c -c3035535ca629fc9a85f64f62412b550b5c8185e57e6382937dc6de374fc5972 providers/implementations/keymgmt/ec_kmgmt_imexport.inc -4f549f95a1781038b107c11c0f961f7e95fe5e002812fb291ecf1ab45a45a20f providers/implementations/keymgmt/ecx_kmgmt.c -daf35a7ab961ef70aefca981d80407935904c5da39dca6692432d6e6bc98759d providers/implementations/keymgmt/kdf_legacy_kmgmt.c -487f2b99c0dd9c51c63df758884c3f9bff45cc52b302c402df1fda578f4851ef providers/implementations/keymgmt/mac_legacy_kmgmt.c -bdf5f65254440afed4386c7a9cc8f94db6807b5c38c65bde58bd4e73dec61ba8 providers/implementations/keymgmt/ml_dsa_kmgmt.c -623db74c37a81db77e2d6449a79d72f59eec739465210df468696b597e35efa2 providers/implementations/keymgmt/ml_kem_kmgmt.c -6266925c99fa47f502aedef4403a6f93dbb4db2459d84babd347176939af45fe providers/implementations/keymgmt/mlx_kmgmt.c -e9e85e25dbb14f835947cfa53c10e7f1aa9868bbc8f1c43827365a39733ecbb0 providers/implementations/keymgmt/rsa_kmgmt.c -fe6c78fb84507d912c506f1553f85145212ce0fdc0828eaafeb5f277d3b9539b providers/implementations/keymgmt/slh_dsa_kmgmt.c -d090dc16657b4de57feef133d21f1f5f9892352f8fb30b905b9ac7c1271ddc72 providers/implementations/macs/cmac_prov.c +eb2d1166a10fa324cd5bded35a739729cd0e693253d927df6737a252ce426e67 providers/implementations/keymgmt/ec_kmgmt.c +256336add29bdd34db7d79960b20641c44071616d6d2154c84c947f018fa66f4 providers/implementations/keymgmt/ecx_kmgmt.c +dc53ca39327f8ebf9f065afe57ccf74df497056dada597f6929f8bc265e7b732 providers/implementations/keymgmt/kdf_legacy_kmgmt.c +fdb1d563e26977c42bccaf13ffa003ab0f28a3e0d8e67078f6c59098fd378b90 providers/implementations/keymgmt/mac_legacy_kmgmt.c +c127c37f7bf6d3d5251ec6b991d9308b66475999605feb98b679d7df5345030a providers/implementations/keymgmt/ml_dsa_kmgmt.c +08af030445f51890648f9e78f5d9b05567eb3c59ac63c7ccd1e46b99703af97b providers/implementations/keymgmt/ml_kem_kmgmt.c +9edbccd16241fe072dbdc36fd0b1b657217db9b0455f0634da4c0c28b2c2ea18 providers/implementations/keymgmt/mlx_kmgmt.c +bceba26310804081290a92507896f35cb3fcc5c69ac8f1c16e81ddcbd9a5164e providers/implementations/keymgmt/rsa_kmgmt.c +37c4e938914a6acbee48b914bda9855838448d70bdf78f8c3675dbdabe443a53 providers/implementations/keymgmt/slh_dsa_kmgmt.c +b254f523171368c68b74978282811b22c406744ba8a3982aa46db12cd6eae961 providers/implementations/macs/cmac_prov.c 2183fc7defac5ae173b1fc449dbeb2a4ffcbe510631e525acbf3e2be6b2baf61 providers/implementations/macs/gmac_prov.c -0187e76d4b6a8528f9b8b056c6e175186e650c9007c46a0f772d963c8fd539aa providers/implementations/macs/hmac_prov.c +f0271cadea2c0c182d2ba7bd744e60557c543d55028956a8062de04dfe0f6189 providers/implementations/macs/hmac_prov.c ce7866f670bb5b80b8fec42c79ed439e3f1f7edbab561f9a10042ccdbec2e855 providers/implementations/macs/kmac_prov.c 9a796599b6aa54cd7851a04e4929b47f172b9818259b5debd22858a1faee6e2e providers/implementations/rands/drbg.c -8e970f917e4e9a9327130181de6949324634101f942ef3c74ad8dc479c2696eb providers/implementations/rands/drbg_ctr.c -8f78fc29274a8f702eea977dc1dd0d250de3346714ef4ae2d104b0200538518e providers/implementations/rands/drbg_hash.c -d8320cb81503fb2a80fb96a65eac4c36a5d43a1ef0f05cf6dd91d72306a5b8ff providers/implementations/rands/drbg_hmac.c +7a4ddd75c4df60342154a1e08da480e4bde0c3607d2ae825f43e1ddd71f4d819 providers/implementations/rands/drbg_ctr.c +a65fb53d9b840f0e1c67fe64de2268e20b51f87c4e5fd2f4f057e9f549c8644e providers/implementations/rands/drbg_hash.c +232ca3e184258eef7cd83611975f0c77fff557dd7dd7c3b6147266efd2d103a0 providers/implementations/rands/drbg_hmac.c 5fd5e9999104c827c7df524cad88309d28ea01c376096a23ba7e227af936dde6 providers/implementations/rands/fips_crng_test.c -dffbf7811597d68635e811915c76f3a85c351a482692f029a2e01f21cad377b3 providers/implementations/rands/test_rng.c -a4e24f5472d4c39a8e490e36164dc43a70d8aaaa49b21f892d20c070d5d6f36b providers/implementations/signature/dsa_sig.c -66475b29b483968ecab15e5f909f7bd506d47283d039e5784a63bba5eb7ad538 providers/implementations/signature/ecdsa_sig.c -1a58e66cb9bc1815dc1d0523792f92119a24a5900d35fe93e97022613e93b867 providers/implementations/signature/eddsa_sig.c -c0fc1e0349777e063b477026e8d3086b6f81956256258c2c35ee8f32d628e60a providers/implementations/signature/mac_legacy_sig.c -f5c756422350efb6f67001ac52585c05f57cca2c24a3c9ae8d91d63d11617aea providers/implementations/signature/ml_dsa_sig.c -5ebef1095f95ad836bd679f2453bb3f762321f45104d2f2632846172e89634bb providers/implementations/signature/rsa_sig.c -7695ad423763b51abfbdfd1d04a902df2ec9c137e2b7a30ea214d82025840b68 providers/implementations/signature/slh_dsa_sig.c -7f5472f4ff5f4394844edb9c189a740cd98d083d828b80b5d7bb8bf08f0271de providers/implementations/skeymgmt/aes_skmgmt.c -7c72db8df7e8caa9c995d92f8c27a62655f3ddb885d6ddf3946fd199e982371f providers/implementations/skeymgmt/generic.c -d57ca33b29da0658c130128363f3c005e915e9ae8ecfe2c4e355416900ebe828 ssl/record/methods/ssl3_cbc.c -f8fb441366e59328f29ccecdb2e1e978b9eeb9e7aeb793b9a8b547c741534a7f ssl/record/methods/tls_pad.c +e5e41c1246cd779057adb86f7bc06cd74b606f02127dcc55afc020789825fcd3 providers/implementations/rands/test_rng.c +1c589393350cb573929f0604fba9f3abfb78ea3a77f892b8b497874be22b41a3 providers/implementations/signature/dsa_sig.c +6a9d86fbcdd83f372837e8a78abc699e669f95e28bcf99a1668f071621a5cdfe providers/implementations/signature/ecdsa_sig.c +6f496e72102ce535452c36e8998e3987f020a5936151d937c8f6703e8675bbec providers/implementations/signature/eddsa_sig.c +fb084a4a80b3d5dcb0b461ee0c4283ee948bbcbfcdfa856159276f899d2ef8a6 providers/implementations/signature/mac_legacy_sig.c +98219031d44ca4534289ecece366290a2cbc1a05a067e8c80bfa74834f31f703 providers/implementations/signature/ml_dsa_sig.c +b99cbe9f2c3e19be563660af693cea3911fb11816034c4e77528008e601cd886 providers/implementations/signature/rsa_sig.c +79f7d1c01cf0755a67e6b3d10211b06592559f7e751b91c06824a958017e9d20 providers/implementations/signature/slh_dsa_sig.c +6d3fa2d15a1a5ce52954a30574554f80cd401fac8e3175aa136204b2888fed6d providers/implementations/skeymgmt/aes_skmgmt.c +3d39d2293b9642c722e65e46c1689c42a30b981730c1e6c317ffcf197b9b1ac7 providers/implementations/skeymgmt/generic.c +aa5a7a9e521c3281fdd55cc6a5deb5721c8d067ac1433979c6f2748871ca8d2f ssl/record/methods/ssl3_cbc.c +04f33a330e073222366d31b3498c775ec77bf491e9d27aa7ed65c8ab5f615897 ssl/record/methods/tls_pad.c +ac6512b47b41ab01927d91774e69999327123fb3900997f657404b214fc477de util/mkerr.pl diff --git a/providers/fips.checksum b/providers/fips.checksum index 2c7bab5eab1cf..a3b78f828a5bf 100644 --- a/providers/fips.checksum +++ b/providers/fips.checksum @@ -1 +1 @@ -864d3535e188440ca60b8268ce8137e0cffb870be990531fd9f68a23f0ffa898 providers/fips-sources.checksums +f1a0bd58b43534cf6d135e834d8765cf25ea1f527eafe030df9d10f3e0ef04ae providers/fips-sources.checksums diff --git a/providers/fips.module.sources b/providers/fips.module.sources index 5358458573215..cb4777e976093 100644 --- a/providers/fips.module.sources +++ b/providers/fips.module.sources @@ -1,4 +1,5 @@ crypto/aes/aes_cbc.c +crypto/aes/aes_cbc_vaes_intrinsic.c crypto/aes/aes_core.c crypto/aes/aes_ecb.c crypto/aes/aes_local.h @@ -6,6 +7,7 @@ crypto/aes/aes_misc.c crypto/aes/asm/aes-586.pl crypto/aes/asm/aes-armv4.pl crypto/aes/asm/aes-c64xplus.pl +crypto/aes/asm/aes-cbc-vaes-x86_64.pl crypto/aes/asm/aes-cfb-avx512.pl crypto/aes/asm/aes-ia64.S crypto/aes/asm/aes-mips.pl @@ -112,7 +114,7 @@ crypto/bn/bn_mpi.c crypto/bn/bn_mul.c crypto/bn/bn_nist.c crypto/bn/bn_prime.c -crypto/bn/bn_prime.h +crypto/bn/bn_prime.pl crypto/bn/bn_rand.c crypto/bn/bn_recp.c crypto/bn/bn_rsa_fips186_5.c @@ -172,8 +174,7 @@ crypto/ec/asm/x25519-ppc64.pl crypto/ec/asm/x25519-x86_64.pl crypto/ec/curve25519.c crypto/ec/curve448/arch_32/f_impl32.c -crypto/ec/curve448/arch_64/arch_intrinsics.h -crypto/ec/curve448/arch_64/f_impl.h +crypto/ec/curve448/arch_64/arch_intrinsics.inc crypto/ec/curve448/arch_64/f_impl64.c crypto/ec/curve448/curve448.c crypto/ec/curve448/curve448_local.h @@ -235,7 +236,6 @@ crypto/evp/p_lib.c crypto/evp/pmeth_check.c crypto/evp/pmeth_gn.c crypto/evp/pmeth_lib.c -crypto/evp/s_lib.c crypto/evp/signature.c crypto/evp/skeymgmt_meth.c crypto/ex_data.c @@ -305,6 +305,7 @@ crypto/modes/wrap128.c crypto/modes/xts128.c crypto/modes/xts128gb.c crypto/o_str.c +crypto/objects/objects.pl crypto/packet.c crypto/param_build.c crypto/param_build_set.c @@ -453,6 +454,7 @@ include/crypto/des_platform.h include/crypto/dh.h include/crypto/dsa.h include/crypto/ec.h +include/crypto/ec_params.h.in include/crypto/ecx.h include/crypto/evp.h include/crypto/lhash.h @@ -463,6 +465,7 @@ include/crypto/modes.h include/crypto/rand.h include/crypto/rand_pool.h include/crypto/rsa.h +include/crypto/rsa_params.h.in include/crypto/security_bits.h include/crypto/sha.h include/crypto/slh_dsa.h @@ -478,7 +481,6 @@ include/internal/deprecated.h include/internal/der.h include/internal/deterministic_nonce.h include/internal/dso.h -include/internal/dsoerr.h include/internal/e_os.h include/internal/e_winsock.h include/internal/encoder.h @@ -487,6 +489,7 @@ include/internal/ffc.h include/internal/fips.h include/internal/hashfunc.h include/internal/hashtable.h +include/internal/list.h include/internal/mem_alloc_utils.h include/internal/namemap.h include/internal/nelem.h @@ -495,7 +498,6 @@ include/internal/packet.h include/internal/param_build_set.h include/internal/params.h include/internal/property.h -include/internal/propertyerr.h include/internal/provider.h include/internal/rcu.h include/internal/refcount.h @@ -514,46 +516,34 @@ include/internal/tlsgroups.h include/internal/tlssigalgs.h include/internal/to_hex.h include/internal/tsan_assist.h +include/internal/zeroization.h include/openssl/aes.h include/openssl/asn1.h.in -include/openssl/asn1err.h include/openssl/asn1t.h.in include/openssl/bio.h.in -include/openssl/bioerr.h include/openssl/bn.h -include/openssl/bnerr.h include/openssl/buffer.h -include/openssl/buffererr.h include/openssl/byteorder.h include/openssl/cmac.h include/openssl/cms.h.in -include/openssl/cmserr.h include/openssl/conf.h.in -include/openssl/conferr.h include/openssl/configuration.h.in include/openssl/conftypes.h include/openssl/core.h include/openssl/core_dispatch.h include/openssl/core_names.h.in include/openssl/crypto.h.in -include/openssl/cryptoerr.h include/openssl/cryptoerr_legacy.h include/openssl/decoder.h -include/openssl/decodererr.h include/openssl/des.h include/openssl/dh.h -include/openssl/dherr.h include/openssl/dsa.h -include/openssl/dsaerr.h include/openssl/e_os2.h include/openssl/ebcdic.h include/openssl/ec.h -include/openssl/ecerr.h include/openssl/encoder.h -include/openssl/encodererr.h include/openssl/err.h.in include/openssl/evp.h -include/openssl/evperr.h include/openssl/fips_names.h include/openssl/fipskey.h.in include/openssl/hmac.h @@ -564,22 +554,16 @@ include/openssl/lhash.h.in include/openssl/macros.h include/openssl/ml_kem.h include/openssl/modes.h -include/openssl/obj_mac.h include/openssl/objects.h -include/openssl/objectserr.h include/openssl/opensslconf.h include/openssl/opensslv.h.in include/openssl/param_build.h include/openssl/params.h include/openssl/pkcs7.h.in -include/openssl/pkcs7err.h include/openssl/prov_ssl.h -include/openssl/proverr.h include/openssl/provider.h include/openssl/rand.h -include/openssl/randerr.h include/openssl/rsa.h -include/openssl/rsaerr.h include/openssl/safestack.h.in include/openssl/self_test.h include/openssl/sha.h @@ -590,9 +574,7 @@ include/openssl/trace.h include/openssl/types.h include/openssl/x509.h.in include/openssl/x509_vfy.h.in -include/openssl/x509err.h include/openssl/x509v3.h.in -include/openssl/x509v3err.h providers/common/bio_prov.c providers/common/capabilities.c providers/common/der/der_digests_gen.c.in @@ -625,13 +607,11 @@ providers/common/include/prov/der_pq_dsa.h providers/common/include/prov/der_rsa.h.in providers/common/include/prov/der_slh_dsa.h.in providers/common/include/prov/der_wrap.h.in -providers/common/include/prov/proverr.h providers/common/include/prov/provider_ctx.h providers/common/include/prov/provider_util.h providers/common/include/prov/providercommon.h providers/common/include/prov/securitycheck.h providers/common/provider_ctx.c -providers/common/provider_err.c providers/common/provider_seeding.c providers/common/provider_util.c providers/common/securitycheck.c @@ -663,24 +643,17 @@ providers/implementations/ciphers/cipher_aes_cbc_hmac_sha_etm.h providers/implementations/ciphers/cipher_aes_ccm.c providers/implementations/ciphers/cipher_aes_ccm.h providers/implementations/ciphers/cipher_aes_ccm_hw.c -providers/implementations/ciphers/cipher_aes_cts.inc providers/implementations/ciphers/cipher_aes_gcm.c providers/implementations/ciphers/cipher_aes_gcm.h providers/implementations/ciphers/cipher_aes_gcm_hw.c -providers/implementations/ciphers/cipher_aes_gcm_hw_aesni.c -providers/implementations/ciphers/cipher_aes_gcm_hw_s390x.c -providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.c providers/implementations/ciphers/cipher_aes_gcm_hw_ppc.c -providers/implementations/ciphers/cipher_aes_gcm_hw_rv32i.c -providers/implementations/ciphers/cipher_aes_gcm_hw_rv64i.c -providers/implementations/ciphers/cipher_aes_gcm_hw_t4.c +providers/implementations/ciphers/cipher_aes_hw.c providers/implementations/ciphers/cipher_aes_hw_aesni.c providers/implementations/ciphers/cipher_aes_hw_armv8.c providers/implementations/ciphers/cipher_aes_hw_rv32i.c providers/implementations/ciphers/cipher_aes_hw_rv64i.c providers/implementations/ciphers/cipher_aes_hw_s390x.c providers/implementations/ciphers/cipher_aes_hw_t4.c -providers/implementations/ciphers/cipher_aes_hw.c providers/implementations/ciphers/cipher_aes_ocb.c providers/implementations/ciphers/cipher_aes_ocb.h providers/implementations/ciphers/cipher_aes_ocb.inc.in @@ -694,8 +667,10 @@ providers/implementations/ciphers/cipher_aes_xts_fips.c providers/implementations/ciphers/cipher_aes_xts_hw.c providers/implementations/ciphers/cipher_cts.c providers/implementations/ciphers/cipher_cts.h +providers/implementations/ciphers/cipher_cts.inc.in providers/implementations/ciphers/cipher_tdes.c providers/implementations/ciphers/cipher_tdes.h +providers/implementations/ciphers/cipher_tdes.inc.in providers/implementations/ciphers/cipher_tdes_common.c providers/implementations/ciphers/cipher_tdes_hw.c providers/implementations/ciphers/ciphercommon.c @@ -747,6 +722,8 @@ providers/implementations/kdfs/hkdf.c providers/implementations/kdfs/hkdf.inc.in providers/implementations/kdfs/hmacdrbg_kdf.c providers/implementations/kdfs/hmacdrbg_kdf.inc.in +providers/implementations/kdfs/ikev2kdf.c +providers/implementations/kdfs/ikev2kdf.inc.in providers/implementations/kdfs/kbkdf.c providers/implementations/kdfs/kbkdf.inc.in providers/implementations/kdfs/pbkdf2.c @@ -774,7 +751,6 @@ providers/implementations/keymgmt/dh_kmgmt.inc.in providers/implementations/keymgmt/dsa_kmgmt.c providers/implementations/keymgmt/dsa_kmgmt.inc.in providers/implementations/keymgmt/ec_kmgmt.c -providers/implementations/keymgmt/ec_kmgmt_imexport.inc providers/implementations/keymgmt/ecx_kmgmt.c providers/implementations/keymgmt/ecx_kmgmt.inc.in providers/implementations/keymgmt/kdf_legacy_kmgmt.c @@ -815,6 +791,7 @@ providers/implementations/signature/ecdsa_sig.inc.in providers/implementations/signature/eddsa_sig.c providers/implementations/signature/eddsa_sig.inc.in providers/implementations/signature/mac_legacy_sig.c +providers/implementations/signature/mac_legacy_sig.inc.in providers/implementations/signature/ml_dsa_sig.c providers/implementations/signature/ml_dsa_sig.inc.in providers/implementations/signature/rsa_sig.c @@ -826,3 +803,4 @@ providers/implementations/skeymgmt/generic.c providers/implementations/skeymgmt/generic.inc.in ssl/record/methods/ssl3_cbc.c ssl/record/methods/tls_pad.c +util/mkerr.pl diff --git a/providers/fips/fipsindicator.c b/providers/fips/fipsindicator.c index 55f287324bfd8..57e6e4407de2b 100644 --- a/providers/fips/fipsindicator.c +++ b/providers/fips/fipsindicator.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index 5f331920ba732..033f685c22132 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -101,7 +101,7 @@ typedef struct fips_global_st { } FIPS_GLOBAL; -static inline FIPS_PARAMS *get_fips_params(FIPS_GLOBAL *fgbl) +static ossl_inline FIPS_PARAMS *get_fips_params(FIPS_GLOBAL *fgbl) { return &fgbl->fips_params; } @@ -585,10 +585,12 @@ static const OSSL_ALGORITHM fips_asym_kem[] = { { PROV_NAMES_ML_KEM_768, FIPS_DEFAULT_PROPERTIES, ossl_ml_kem_asym_kem_functions }, { PROV_NAMES_ML_KEM_1024, FIPS_DEFAULT_PROPERTIES, ossl_ml_kem_asym_kem_functions }, #if !defined(OPENSSL_NO_ECX) + { PROV_NAMES_MLKEM512X25519, FIPS_DEFAULT_PROPERTIES, ossl_mlx_kem_asym_kem_functions }, { PROV_NAMES_X25519MLKEM768, FIPS_DEFAULT_PROPERTIES, ossl_mlx_kem_asym_kem_functions }, { PROV_NAMES_X448MLKEM1024, FIPS_UNAPPROVED_PROPERTIES, ossl_mlx_kem_asym_kem_functions }, #endif #if !defined(OPENSSL_NO_EC) + { PROV_NAMES_SecP256r1MLKEM512, FIPS_DEFAULT_PROPERTIES, ossl_mlx_kem_asym_kem_functions }, { PROV_NAMES_SecP256r1MLKEM768, FIPS_DEFAULT_PROPERTIES, ossl_mlx_kem_asym_kem_functions }, { PROV_NAMES_SecP384r1MLKEM1024, FIPS_DEFAULT_PROPERTIES, ossl_mlx_kem_asym_kem_functions }, #endif @@ -655,12 +657,16 @@ static const OSSL_ALGORITHM fips_keymgmt[] = { { PROV_NAMES_ML_KEM_1024, FIPS_DEFAULT_PROPERTIES, ossl_ml_kem_1024_keymgmt_functions, PROV_DESCS_ML_KEM_1024 }, #if !defined(OPENSSL_NO_ECX) + { PROV_NAMES_MLKEM512X25519, FIPS_DEFAULT_PROPERTIES, ossl_mlx_x25519_512_kem_kmgmt_functions, + PROV_DESCS_MLKEM512X25519 }, { PROV_NAMES_X25519MLKEM768, FIPS_DEFAULT_PROPERTIES, ossl_mlx_x25519_kem_kmgmt_functions, PROV_DESCS_X25519MLKEM768 }, - { PROV_NAMES_X448MLKEM1024, FIPS_DEFAULT_PROPERTIES, ossl_mlx_x448_kem_kmgmt_functions, + { PROV_NAMES_X448MLKEM1024, FIPS_UNAPPROVED_PROPERTIES, ossl_mlx_x448_kem_kmgmt_functions, PROV_DESCS_X448MLKEM1024 }, #endif #if !defined(OPENSSL_NO_EC) + { PROV_NAMES_SecP256r1MLKEM512, FIPS_DEFAULT_PROPERTIES, ossl_mlx_p256_512_kem_kmgmt_functions, + PROV_DESCS_SecP256r1MLKEM512 }, { PROV_NAMES_SecP256r1MLKEM768, FIPS_DEFAULT_PROPERTIES, ossl_mlx_p256_kem_kmgmt_functions, PROV_DESCS_SecP256r1MLKEM768 }, { PROV_NAMES_SecP384r1MLKEM1024, FIPS_DEFAULT_PROPERTIES, ossl_mlx_p384_kem_kmgmt_functions, @@ -1190,6 +1196,17 @@ void *CRYPTO_aligned_alloc(size_t num, size_t align, void **freeptr, return ossl_malloc_align(num, align, freeptr, file, line); } +/* + * The public BIO_snprintf() prototype is hidden when the public headers + * are built with OPENSSL_NO_DEPRECATED_4_1, but the FIPS module still + * defines and exports the symbol for callers compiled into the module. + * Provide a local prototype in that configuration so the definition is + * well-formed. + */ +#ifdef OPENSSL_NO_DEPRECATED_4_1 +int BIO_snprintf(char *buf, size_t n, const char *format, ...); +#endif + int BIO_snprintf(char *buf, size_t n, const char *format, ...) { va_list args; diff --git a/providers/fips/include/fips/fipsindicator.h b/providers/fips/include/fips/fipsindicator.h index 1c1846b1a73ab..b46580d07a6a6 100644 --- a/providers/fips/include/fips/fipsindicator.h +++ b/providers/fips/include/fips/fipsindicator.h @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/fips/include/fipscommon.h b/providers/fips/include/fipscommon.h index 61d4adef532ba..31970a589b0ed 100644 --- a/providers/fips/include/fipscommon.h +++ b/providers/fips/include/fipscommon.h @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/fips/self_test.c b/providers/fips/self_test.c index 364fd0ef6585f..391e3686263d6 100644 --- a/providers/fips/self_test.c +++ b/providers/fips/self_test.c @@ -325,11 +325,14 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, void *fips_global, return 0; } - if (st == NULL - || st->module_checksum_data == NULL) { + if (st == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA); goto end; } + if (st->module_checksum_data == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_MISSING_CHECKSUM); + goto end; + } ev = OSSL_SELF_TEST_new(st->cb, st->cb_arg); if (ev == NULL) diff --git a/providers/implementations/ciphers/build.info b/providers/implementations/ciphers/build.info index 2460b0183da1a..315778492d3ce 100644 --- a/providers/implementations/ciphers/build.info +++ b/providers/implementations/ciphers/build.info @@ -26,6 +26,7 @@ $CHACHA_GOAL=../../libdefault.a $CHACHAPOLY_GOAL=../../libdefault.a $SIV_GOAL=../../libdefault.a $SIV_GCM_GOAL=../../libdefault.a +$ASCON_GOAL=../../libdefault.a IF[{- !$disabled{asm} -}] $GHASHDEF_x86=GHASH_ASM @@ -92,8 +93,9 @@ SOURCE[$COMMON_GOAL]=\ INCLUDE[cipher_aes_cbc_hmac_sha.o cipher_aes_cbc_hmac_sha_etm.o \ cipher_aes_gcm_siv.o cipher_aes_ocb.o cipher_aes_siv.o \ - cipher_aes_wrp.o cipher_aes_xts.o ciphercommon.o cipher_chacha20.o \ - cipher_chacha20_poly1305.o cipher_rc4_hmac_md5.o cipher_sm4_xts.o]=. + cipher_aes_wrp.o cipher_aes_xts.o cipher_ascon_aead128.o ciphercommon.o \ + cipher_chacha20.o cipher_chacha20_poly1305.o cipher_rc4_hmac_md5.o \ + cipher_sm4_xts.o]=. IF[{- !$disabled{des} -}] SOURCE[$TDES_1_GOAL]=cipher_tdes.c cipher_tdes_common.c cipher_tdes_hw.c @@ -132,6 +134,12 @@ IF[{- !$disabled{siv} -}] SOURCE[$SIV_GOAL]=cipher_aes_siv.c cipher_aes_siv_hw.c ENDIF +IF[{- !$disabled{ascon128} -}] + SOURCE[$ASCON_GOAL]=\ + cipher_ascon_aead128.c + INCLUDE[$ASCON_GOAL]=../include +ENDIF + IF[{- !$disabled{des} -}] SOURCE[$TDES_2_GOAL]=\ cipher_tdes_default.c cipher_tdes_default_hw.c \ diff --git a/providers/implementations/ciphers/cipher_aes.c b/providers/implementations/ciphers/cipher_aes.c index 3638919aeb65f..5508890f20d26 100644 --- a/providers/implementations/ciphers/cipher_aes.c +++ b/providers/implementations/ciphers/cipher_aes.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,14 +14,17 @@ */ #include "internal/deprecated.h" -/* Dispatch functions for AES cipher modes ecb, cbc, ofb, cfb, ctr */ +/* Dispatch functions for AES cipher modes ecb, cbc, cts, ofb, cfb, ctr */ +#include "cipher_cts.h" #include "cipher_aes.h" #include "prov/implementations.h" #include "prov/providercommon.h" static OSSL_FUNC_cipher_freectx_fn aes_freectx; static OSSL_FUNC_cipher_dupctx_fn aes_dupctx; +static OSSL_FUNC_cipher_encrypt_init_fn aes_cbc_cts_einit; +static OSSL_FUNC_cipher_decrypt_init_fn aes_cbc_cts_dinit; static void aes_freectx(void *vctx) { @@ -43,10 +46,31 @@ static void *aes_dupctx(void *ctx) if (ret == NULL) return NULL; in->base.hw->copyctx(&ret->base, &in->base); - + if (!ossl_cipher_generic_dupctx_tlsmac(&ret->base, &in->base)) { + OPENSSL_clear_free(ret, sizeof(*ret)); + return NULL; + } return ret; } +static int aes_cbc_cts_einit(void *ctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen, + const OSSL_PARAM params[]) +{ + if (!ossl_cipher_generic_einit(ctx, key, keylen, iv, ivlen, NULL)) + return 0; + return ossl_cipher_cbc_cts_set_ctx_params(ctx, params); +} + +static int aes_cbc_cts_dinit(void *ctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen, + const OSSL_PARAM params[]) +{ + if (!ossl_cipher_generic_dinit(ctx, key, keylen, iv, ivlen, NULL)) + return 0; + return ossl_cipher_cbc_cts_set_ctx_params(ctx, params); +} + /* ossl_aes256ecb_functions */ IMPLEMENT_generic_cipher(aes, AES, ecb, ECB, 0, 256, 128, 0, block) /* ossl_aes192ecb_functions */ @@ -90,4 +114,9 @@ IMPLEMENT_generic_cipher(aes, AES, ctr, CTR, 0, 192, 8, 128, stream) /* ossl_aes128ctr_functions */ IMPLEMENT_generic_cipher(aes, AES, ctr, CTR, 0, 128, 8, 128, stream) -#include "cipher_aes_cts.inc" +/* ossl_aes256cbc_cts_functions */ +IMPLEMENT_cts_cipher(aes, AES, cbc, CBC, PROV_CIPHER_FLAG_CTS, 256, 128, 128, block) +/* ossl_aes192cbc_cts_functions */ +IMPLEMENT_cts_cipher(aes, AES, cbc, CBC, PROV_CIPHER_FLAG_CTS, 192, 128, 128, block) +/* ossl_aes128cbc_cts_functions */ +IMPLEMENT_cts_cipher(aes, AES, cbc, CBC, PROV_CIPHER_FLAG_CTS, 128, 128, 128, block) diff --git a/providers/implementations/ciphers/cipher_aes.h b/providers/implementations/ciphers/cipher_aes.h index 4e71678fd197d..78bd8dcef46e8 100644 --- a/providers/implementations/ciphers/cipher_aes.h +++ b/providers/implementations/ciphers/cipher_aes.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c index 747a30f287832..b1dddce8ad7d6 100644 --- a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c +++ b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.c @@ -35,6 +35,21 @@ #define AES_CBC_HMAC_SHA_FLAGS (PROV_CIPHER_FLAG_AEAD \ | PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) +#if !defined(OPENSSL_NO_MULTIBLOCK) +static int aes_get_multiblock_interleave(const OSSL_PARAM *p, + unsigned int *interleave) +{ + return p != NULL + && OSSL_PARAM_get_uint(p, interleave) + && (*interleave == 4 || *interleave == 8); +} + +static unsigned int tls1_aad_plaintext_len(const unsigned char *aad) +{ + return ((unsigned int)aad[11] << 8) | aad[12]; +} +#endif /* !defined(OPENSSL_NO_MULTIBLOCK) */ + static OSSL_FUNC_cipher_encrypt_init_fn aes_einit; static OSSL_FUNC_cipher_decrypt_init_fn aes_dinit; static OSSL_FUNC_cipher_freectx_fn aes_cbc_hmac_sha1_freectx; @@ -112,8 +127,12 @@ static int aes_set_ctx_params(void *vctx, const OSSL_PARAM params[]) */ if (p.mb_aad != NULL) { if (p.mb_aad->data_type != OSSL_PARAM_OCTET_STRING - || p.ileave == NULL - || !OSSL_PARAM_get_uint(p.ileave, &mb_param.interleave)) { + || p.mb_aad->data == NULL + || p.mb_aad->data_size < EVP_AEAD_TLS1_AAD_LEN + || !aes_get_multiblock_interleave(p.ileave, &mb_param.interleave) + || tls1_aad_plaintext_len(p.mb_aad->data) > SSL3_RT_MAX_PLAIN_LENGTH + || p.mb_aad->data_size + > (size_t)SSL3_RT_MAX_PLAIN_LENGTH * mb_param.interleave) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } @@ -134,10 +153,15 @@ static int aes_set_ctx_params(void *vctx, const OSSL_PARAM params[]) */ if (p.enc != NULL) { if (p.enc->data_type != OSSL_PARAM_OCTET_STRING + || p.enc->data == NULL || p.enc_in == NULL || p.enc_in->data_type != OSSL_PARAM_OCTET_STRING - || p.ileave == NULL - || !OSSL_PARAM_get_uint(p.ileave, &mb_param.interleave)) { + || p.enc_in->data == NULL + || p.enc_in->data_size == 0 + || p.enc->data_size != p.enc_in->data_size + || !aes_get_multiblock_interleave(p.ileave, &mb_param.interleave) + || p.enc_in->data_size + > (size_t)SSL3_RT_MAX_PLAIN_LENGTH * mb_param.interleave) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } @@ -306,6 +330,7 @@ static void *aes_cbc_hmac_sha1_newctx(void *provctx, size_t kbits, static void *aes_cbc_hmac_sha1_dupctx(void *provctx) { PROV_AES_HMAC_SHA1_CTX *ctx = provctx; + PROV_AES_HMAC_SHA1_CTX *dctx; if (!ossl_prov_is_running()) return NULL; @@ -313,7 +338,14 @@ static void *aes_cbc_hmac_sha1_dupctx(void *provctx) if (ctx == NULL) return NULL; - return OPENSSL_memdup(ctx, sizeof(*ctx)); + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL + && !ossl_cipher_generic_dupctx_tlsmac(&dctx->base_ctx.base, + &ctx->base_ctx.base)) { + OPENSSL_clear_free(dctx, sizeof(*dctx)); + return NULL; + } + return dctx; } static void aes_cbc_hmac_sha1_freectx(void *vctx) @@ -355,11 +387,22 @@ static void *aes_cbc_hmac_sha256_newctx(void *provctx, size_t kbits, static void *aes_cbc_hmac_sha256_dupctx(void *provctx) { PROV_AES_HMAC_SHA256_CTX *ctx = provctx; + PROV_AES_HMAC_SHA256_CTX *dctx; if (!ossl_prov_is_running()) return NULL; - return OPENSSL_memdup(ctx, sizeof(*ctx)); + if (ctx == NULL) + return NULL; + + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL + && !ossl_cipher_generic_dupctx_tlsmac(&dctx->base_ctx.base, + &ctx->base_ctx.base)) { + OPENSSL_clear_free(dctx, sizeof(*dctx)); + return NULL; + } + return dctx; } static void aes_cbc_hmac_sha256_freectx(void *vctx) diff --git a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.h b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.h index b2cd2d4019ba1..67050cdd5e7d0 100644 --- a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.h +++ b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.inc.in b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.inc.in index 53348960703f3..31e4e572eae5a 100644 --- a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.inc.in +++ b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha.inc.in @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the \"License\"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -15,7 +15,7 @@ use OpenSSL::paramnames qw(produce_param_decoder); (['OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_MAX_SEND_FRAGMENT', 'maxfrag', 'size_t', "#if !defined(OPENSSL_NO_MULTIBLOCK)"], ['OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD', - 'mb_aad', 'size_t', "#if !defined(OPENSSL_NO_MULTIBLOCK)"], + 'mb_aad', 'octet_string', "#if !defined(OPENSSL_NO_MULTIBLOCK)"], ['OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE', 'ileave', 'uint', "#if !defined(OPENSSL_NO_MULTIBLOCK)"], ['OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_ENC', diff --git a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c index 47ab95d6fae29..2554dc13afd4c 100644 --- a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c +++ b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha1_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c index 15d75d6372530..a55f38bbb42ad 100644 --- a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c +++ b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha256_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha_etm.c b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha_etm.c index 12037ff3b9778..f1b6cefbd2e9a 100644 --- a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha_etm.c +++ b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha_etm.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -203,11 +203,19 @@ static void aes_cbc_hmac_sha1_etm_freectx(void *vctx) static void *aes_cbc_hmac_sha1_etm_dupctx(void *provctx) { PROV_AES_HMAC_SHA1_ETM_CTX *ctx = provctx; + PROV_AES_HMAC_SHA1_ETM_CTX *dctx; if (ctx == NULL) return NULL; - return OPENSSL_memdup(ctx, sizeof(*ctx)); + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL + && !ossl_cipher_generic_dupctx_tlsmac(&dctx->base_ctx.base, + &ctx->base_ctx.base)) { + OPENSSL_clear_free(dctx, sizeof(*dctx)); + return NULL; + } + return dctx; } static void *aes_cbc_hmac_sha256_etm_newctx(void *provctx, size_t kbits, @@ -240,11 +248,19 @@ static void aes_cbc_hmac_sha256_etm_freectx(void *vctx) static void *aes_cbc_hmac_sha256_etm_dupctx(void *provctx) { PROV_AES_HMAC_SHA256_ETM_CTX *ctx = provctx; + PROV_AES_HMAC_SHA256_ETM_CTX *dctx; if (ctx == NULL) return NULL; - return OPENSSL_memdup(ctx, sizeof(*ctx)); + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL + && !ossl_cipher_generic_dupctx_tlsmac(&dctx->base_ctx.base, + &ctx->base_ctx.base)) { + OPENSSL_clear_free(dctx, sizeof(*dctx)); + return NULL; + } + return dctx; } static void *aes_cbc_hmac_sha512_etm_newctx(void *provctx, size_t kbits, @@ -277,11 +293,19 @@ static void aes_cbc_hmac_sha512_etm_freectx(void *vctx) static void *aes_cbc_hmac_sha512_etm_dupctx(void *provctx) { PROV_AES_HMAC_SHA512_ETM_CTX *ctx = provctx; + PROV_AES_HMAC_SHA512_ETM_CTX *dctx; if (ctx == NULL) return NULL; - return OPENSSL_memdup(ctx, sizeof(*ctx)); + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL + && !ossl_cipher_generic_dupctx_tlsmac(&dctx->base_ctx.base, + &ctx->base_ctx.base)) { + OPENSSL_clear_free(dctx, sizeof(*dctx)); + return NULL; + } + return dctx; } #define IMPLEMENT_CIPHER(nm, sub, kbits, blkbits, ivbits, flags) \ diff --git a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha_etm.h b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha_etm.h index fb28056f8c86c..179891b38f858 100644 --- a/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha_etm.h +++ b/providers/implementations/ciphers/cipher_aes_cbc_hmac_sha_etm.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_ccm.h b/providers/implementations/ciphers/cipher_aes_ccm.h index 9fe8ba2e07564..5359c44f92b70 100644 --- a/providers/implementations/ciphers/cipher_aes_ccm.h +++ b/providers/implementations/ciphers/cipher_aes_ccm.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_ccm_hw.c b/providers/implementations/ciphers/cipher_aes_ccm_hw.c index 638715774082e..57d00f7f9cc07 100644 --- a/providers/implementations/ciphers/cipher_aes_ccm_hw.c +++ b/providers/implementations/ciphers/cipher_aes_ccm_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_cts.inc b/providers/implementations/ciphers/cipher_aes_cts.inc deleted file mode 100644 index 1fb5ec3553f99..0000000000000 --- a/providers/implementations/ciphers/cipher_aes_cts.inc +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* Dispatch functions for AES CBC CTS ciphers */ - -#include -#include "cipher_cts.h" - -#define CTS_FLAGS PROV_CIPHER_FLAG_CTS - -static OSSL_FUNC_cipher_encrypt_init_fn aes_cbc_cts_einit; -static OSSL_FUNC_cipher_decrypt_init_fn aes_cbc_cts_dinit; -static OSSL_FUNC_cipher_get_ctx_params_fn aes_cbc_cts_get_ctx_params; -static OSSL_FUNC_cipher_set_ctx_params_fn aes_cbc_cts_set_ctx_params; -static OSSL_FUNC_cipher_gettable_ctx_params_fn aes_cbc_cts_gettable_ctx_params; -static OSSL_FUNC_cipher_settable_ctx_params_fn aes_cbc_cts_settable_ctx_params; - -CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(aes_cbc_cts) -OSSL_PARAM_utf8_string(OSSL_CIPHER_PARAM_CTS_MODE, NULL, 0), -CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(aes_cbc_cts) - -static int aes_cbc_cts_einit(void *ctx, const unsigned char *key, size_t keylen, - const unsigned char *iv, size_t ivlen, - const OSSL_PARAM params[]) -{ - if (!ossl_cipher_generic_einit(ctx, key, keylen, iv, ivlen, NULL)) - return 0; - return aes_cbc_cts_set_ctx_params(ctx, params); -} - -static int aes_cbc_cts_dinit(void *ctx, const unsigned char *key, size_t keylen, - const unsigned char *iv, size_t ivlen, - const OSSL_PARAM params[]) -{ - if (!ossl_cipher_generic_dinit(ctx, key, keylen, iv, ivlen, NULL)) - return 0; - return aes_cbc_cts_set_ctx_params(ctx, params); -} - -static int aes_cbc_cts_get_ctx_params(void *vctx, OSSL_PARAM params[]) -{ - PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; - OSSL_PARAM *p; - - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS_MODE); - if (p != NULL) { - const char *name = ossl_cipher_cbc_cts_mode_id2name(ctx->cts_mode); - - if (name == NULL || !OSSL_PARAM_set_utf8_string(p, name)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - } - return ossl_cipher_generic_get_ctx_params(vctx, params); -} - -CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(aes_cbc_cts) -OSSL_PARAM_utf8_string(OSSL_CIPHER_PARAM_CTS_MODE, NULL, 0), -CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(aes_cbc_cts) - -static int aes_cbc_cts_set_ctx_params(void *vctx, const OSSL_PARAM params[]) -{ - PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; - const OSSL_PARAM *p; - int id; - - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_CTS_MODE); - if (p != NULL) { - if (p->data_type != OSSL_PARAM_UTF8_STRING) - goto err; - id = ossl_cipher_cbc_cts_mode_name2id(p->data); - if (id < 0) - goto err; - - ctx->cts_mode = (unsigned int)id; - } - return ossl_cipher_generic_set_ctx_params(vctx, params); -err: - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; -} - -/* ossl_aes256cbc_cts_functions */ -IMPLEMENT_cts_cipher(aes, AES, cbc, CBC, CTS_FLAGS, 256, 128, 128, block) -/* ossl_aes192cbc_cts_functions */ -IMPLEMENT_cts_cipher(aes, AES, cbc, CBC, CTS_FLAGS, 192, 128, 128, block) -/* ossl_aes128cbc_cts_functions */ -IMPLEMENT_cts_cipher(aes, AES, cbc, CBC, CTS_FLAGS, 128, 128, 128, block) diff --git a/providers/implementations/ciphers/cipher_aes_gcm.h b/providers/implementations/ciphers/cipher_aes_gcm.h index b041248b3ccb2..d5db88e9bae05 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm.h +++ b/providers/implementations/ciphers/cipher_aes_gcm.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw.c b/providers/implementations/ciphers/cipher_aes_gcm_hw.c index bbb7e21c31fc8..d5699ddf91e4b 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw.c +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_ppc.c b/providers/implementations/ciphers/cipher_aes_gcm_hw_ppc.c index c5d8d27c94a67..71bf11ffd4422 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_hw_ppc.c +++ b/providers/implementations/ciphers/cipher_aes_gcm_hw_ppc.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_gcm_siv.c b/providers/implementations/ciphers/cipher_aes_gcm_siv.c index 2f4a86dc56b06..ea343eb810c3d 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_siv.c +++ b/providers/implementations/ciphers/cipher_aes_gcm_siv.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_gcm_siv.h b/providers/implementations/ciphers/cipher_aes_gcm_siv.h index 7333c39b0bf9c..e6842bb89231c 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_siv.h +++ b/providers/implementations/ciphers/cipher_aes_gcm_siv.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c b/providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c index 452c9f00fea9d..d387973894d54 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c +++ b/providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c @@ -15,6 +15,7 @@ #include "internal/deprecated.h" #include +#include #include #include #include "cipher_aes_gcm_siv.h" @@ -151,8 +152,6 @@ static int aes_gcm_siv_encrypt(PROV_AES_GCM_SIV_CTX *ctx, const unsigned char *i DECLARE_IS_ENDIAN; ctx->generated_tag = 0; - if (!ctx->speed && ctx->used_enc) - return 0; /* need to check the size of the input! */ if (len64 > ((int64_t)1 << 36)) return 0; @@ -212,8 +211,6 @@ static int aes_gcm_siv_decrypt(PROV_AES_GCM_SIV_CTX *ctx, const unsigned char *i DECLARE_IS_ENDIAN; ctx->generated_tag = 0; - if (!ctx->speed && ctx->used_dec) - return 0; /* need to check the size of the input! */ if (len64 > ((int64_t)1 << 36)) return 0; @@ -267,12 +264,23 @@ static int aes_gcm_siv_finish(PROV_AES_GCM_SIV_CTX *ctx) { int ret = 0; - if (ctx->enc) + if (ctx->enc) { + /* + * generate the tag on FINAL so an init/final with no update + * (an empty message) still produces it, matching the other AEADs + */ + if (ctx->generated_tag == 0 + && aes_gcm_siv_encrypt(ctx, NULL, NULL, 0) == 0) + return 0; return ctx->generated_tag; - if (!ctx->generated_tag) - aes_gcm_siv_decrypt(ctx, NULL, NULL, 0); - ret = !CRYPTO_memcmp(ctx->tag, ctx->user_tag, sizeof(ctx->tag)); + } + if (ctx->generated_tag == 0 + && aes_gcm_siv_decrypt(ctx, NULL, NULL, 0) == 0) + return 0; + ret = CRYPTO_memcmp(ctx->tag, ctx->user_tag, sizeof(ctx->tag)) == 0; ret &= ctx->have_user_tag; + if (ret == 0 && ctx->have_user_tag) + ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT); return ret; } @@ -285,6 +293,18 @@ static int aes_gcm_siv_cipher(void *vctx, unsigned char *out, if (in == NULL) return aes_gcm_siv_finish(ctx); + /* + * SIV derives the CTR IV from the tag, which depends on the whole plaintext, + * so the payload cannot be streamed. + * Payload must arrive in a single update, after which the tag is fixed. + * Any later AAD or payload update is therefore out of order and errors out. + * The speed benchmark test is exempt. + */ + if (!ctx->speed && (ctx->used_enc || ctx->used_dec)) { + ERR_raise(ERR_LIB_PROV, PROV_R_UPDATE_CALL_OUT_OF_ORDER); + return 0; + } + /* Deal with associated data */ if (out == NULL) return aes_gcm_siv_aad(ctx, in, len); diff --git a/providers/implementations/ciphers/cipher_aes_gcm_siv_polyval.c b/providers/implementations/ciphers/cipher_aes_gcm_siv_polyval.c index 08188c8aafcce..6c7a717eb18b8 100644 --- a/providers/implementations/ciphers/cipher_aes_gcm_siv_polyval.c +++ b/providers/implementations/ciphers/cipher_aes_gcm_siv_polyval.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_hw_aesni.c b/providers/implementations/ciphers/cipher_aes_hw_aesni.c index f8ae45129bf9f..8a9cc264bbb8e 100644 --- a/providers/implementations/ciphers/cipher_aes_hw_aesni.c +++ b/providers/implementations/ciphers/cipher_aes_hw_aesni.c @@ -68,6 +68,35 @@ static const PROV_CIPHER_HW aesni_cbc = { ossl_cipher_aes_copyctx }; +#if VAES_CBC_ELIGIBLE +/* + * CBC decryption is fully parallel, so VAES accelerates it; CBC encryption is + * inherently serial and stays on the aesni_cbc_encrypt assembly routine. VAES + * is only worthwhile once the payload is large enough to amortize the per-call + * key broadcast, so small buffers also fall back to the assembly routine. + */ +static int aes_cbc_vaes_wrapper( + PROV_CIPHER_CTX *ctx, + unsigned char *out, + const unsigned char *in, + size_t len) +{ + if (!ctx->enc && len >= 256) { + ossl_aes_cbc_vaes_decrypt(in, out, len, ctx->ks, ctx->iv, ctx->enc); + return 1; + } + + aesni_cbc_encrypt(in, out, len, ctx->ks, ctx->iv, ctx->enc); + return 1; +} + +static const PROV_CIPHER_HW aesni_vaes_cbc = { + cipher_hw_aesni_initkey, + aes_cbc_vaes_wrapper, + ossl_cipher_aes_copyctx +}; +#endif /* VAES_CBC_ELIGIBLE */ + #if (defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)) /* active in 64-bit builds when AES-NI, AVX512F, and VAES are detected */ #define VAES_CFB128_ELIGIBLE 1 @@ -133,6 +162,35 @@ static const PROV_CIPHER_HW aesni_ofb128 = { ossl_cipher_aes_copyctx }; +#if VAES_CTR_ELIGIBLE +/* + * VAES accelerates CTR once the payload is large enough to amortize the + * per-call counter setup; small buffers fall back to the generic driver, + * which also preserves the partial-block state in ctx->buf/ctx->num. + */ +static int aes_ctr_vaes_wrapper(PROV_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + const AES_KEY *key = (const AES_KEY *)ctx->ks; + unsigned int num; + + if (len >= 64) { + num = ctx->num; + ossl_aes_ctr_vaes(in, out, len, key, ctx->iv, ctx->buf, &num); + ctx->num = num; + return 1; + } + + return ossl_cipher_hw_generic_ctr(ctx, out, in, len); +} + +static const PROV_CIPHER_HW aesni_vaes_ctr = { + cipher_hw_aesni_initkey, + aes_ctr_vaes_wrapper, + ossl_cipher_aes_copyctx +}; +#endif /* VAES_CTR_ELIGIBLE */ + static const PROV_CIPHER_HW aesni_ctr = { cipher_hw_aesni_initkey, ossl_cipher_hw_generic_ctr, @@ -146,6 +204,10 @@ const PROV_CIPHER_HW *ossl_prov_cipher_hw_aesni(enum aes_modes mode) case AES_MODE_ECB: return &aesni_ecb; case AES_MODE_CBC: +#if VAES_CBC_ELIGIBLE + if (ossl_aes_cbc_vaes_eligible()) + return &aesni_vaes_cbc; +#endif return &aesni_cbc; case AES_MODE_CFB128: #if VAES_CFB128_ELIGIBLE @@ -160,6 +222,10 @@ const PROV_CIPHER_HW *ossl_prov_cipher_hw_aesni(enum aes_modes mode) case AES_MODE_OFB128: return &aesni_ofb128; case AES_MODE_CTR: +#if VAES_CTR_ELIGIBLE + if (ossl_aes_ctr_vaes_eligible()) + return &aesni_vaes_ctr; +#endif return &aesni_ctr; default: return NULL; diff --git a/providers/implementations/ciphers/cipher_aes_ocb.c b/providers/implementations/ciphers/cipher_aes_ocb.c index 1bd5281cc28f6..433e0265980fa 100644 --- a/providers/implementations/ciphers/cipher_aes_ocb.c +++ b/providers/implementations/ciphers/cipher_aes_ocb.c @@ -68,7 +68,14 @@ static ossl_inline int aes_generic_ocb_gettag(PROV_AES_OCB_CTX *ctx, static ossl_inline int aes_generic_ocb_final(PROV_AES_OCB_CTX *ctx) { - return (CRYPTO_ocb128_finish(&ctx->ocb, ctx->tag, ctx->taglen) == 0); + int ret = CRYPTO_ocb128_finish(&ctx->ocb, ctx->tag, ctx->taglen); + + /* ret: -1 = bad tag length, 0 = tag verified, otherwise = tag mismatch */ + if (ret == -1) + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG_LENGTH); + else if (ret != 0) + ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT); + return ret == 0; } static ossl_inline void aes_generic_ocb_cleanup(PROV_AES_OCB_CTX *ctx) @@ -497,6 +504,14 @@ static int aes_ocb_cipher(void *vctx, unsigned char *out, size_t *outl, if (!ossl_prov_is_running()) return 0; + /* + * EVP_Cipher() MUST CHECK THE TAG + * in == NULL indicates finalize, so hand it to the finalize path + * (which checks the tag on decrypt / produces it on encrypt) + */ + if (in == NULL) + return aes_ocb_block_final(vctx, out, outl, outsize); + if (outsize < inl) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; diff --git a/providers/implementations/ciphers/cipher_aes_ocb.h b/providers/implementations/ciphers/cipher_aes_ocb.h index dfea8a1fc8c4a..4825761a95731 100644 --- a/providers/implementations/ciphers/cipher_aes_ocb.h +++ b/providers/implementations/ciphers/cipher_aes_ocb.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_siv.c b/providers/implementations/ciphers/cipher_aes_siv.c index f67c015f8645c..3c358f33e1046 100644 --- a/providers/implementations/ciphers/cipher_aes_siv.c +++ b/providers/implementations/ciphers/cipher_aes_siv.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_siv.h b/providers/implementations/ciphers/cipher_aes_siv.h index cd1ce9c06b55a..ef58aa6a61afb 100644 --- a/providers/implementations/ciphers/cipher_aes_siv.h +++ b/providers/implementations/ciphers/cipher_aes_siv.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_wrp.c b/providers/implementations/ciphers/cipher_aes_wrp.c index c1dc05e3a9bff..ec94ea7fd42b3 100644 --- a/providers/implementations/ciphers/cipher_aes_wrp.c +++ b/providers/implementations/ciphers/cipher_aes_wrp.c @@ -76,14 +76,10 @@ static void *aes_wrap_dupctx(void *wctx) if (ctx == NULL) return NULL; dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); - - if (dctx != NULL && dctx->base.tlsmac != NULL && dctx->base.alloced) { - dctx->base.tlsmac = OPENSSL_memdup(dctx->base.tlsmac, - dctx->base.tlsmacsize); - if (dctx->base.tlsmac == NULL) { - OPENSSL_free(dctx); - dctx = NULL; - } + if (dctx != NULL + && !ossl_cipher_generic_dupctx_tlsmac(&dctx->base, &ctx->base)) { + OPENSSL_clear_free(dctx, sizeof(*dctx)); + return NULL; } return dctx; } diff --git a/providers/implementations/ciphers/cipher_aes_xts.h b/providers/implementations/ciphers/cipher_aes_xts.h index 49ee66ac88fef..45bb7980dbcf3 100644 --- a/providers/implementations/ciphers/cipher_aes_xts.h +++ b/providers/implementations/ciphers/cipher_aes_xts.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aes_xts_hw.c b/providers/implementations/ciphers/cipher_aes_xts_hw.c index 162f8e4593ee8..5e2be9238215d 100644 --- a/providers/implementations/ciphers/cipher_aes_xts_hw.c +++ b/providers/implementations/ciphers/cipher_aes_xts_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aria.h b/providers/implementations/ciphers/cipher_aria.h index 61f2f1b459f2e..059e742017ff8 100644 --- a/providers/implementations/ciphers/cipher_aria.h +++ b/providers/implementations/ciphers/cipher_aria.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aria_ccm.h b/providers/implementations/ciphers/cipher_aria_ccm.h index 51b084e65ea8f..fadb6c40799d7 100644 --- a/providers/implementations/ciphers/cipher_aria_ccm.h +++ b/providers/implementations/ciphers/cipher_aria_ccm.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aria_gcm.h b/providers/implementations/ciphers/cipher_aria_gcm.h index 984d2b83964fb..906c61d4b109d 100644 --- a/providers/implementations/ciphers/cipher_aria_gcm.h +++ b/providers/implementations/ciphers/cipher_aria_gcm.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aria_gcm_hw.c b/providers/implementations/ciphers/cipher_aria_gcm_hw.c index 35f3257d8977d..5ada0c0efc1d5 100644 --- a/providers/implementations/ciphers/cipher_aria_gcm_hw.c +++ b/providers/implementations/ciphers/cipher_aria_gcm_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_aria_hw.c b/providers/implementations/ciphers/cipher_aria_hw.c index ec515295b06d8..3046e86d54394 100644 --- a/providers/implementations/ciphers/cipher_aria_hw.c +++ b/providers/implementations/ciphers/cipher_aria_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_ascon_aead128.c b/providers/implementations/ciphers/cipher_ascon_aead128.c new file mode 100644 index 0000000000000..be28b49a7d876 --- /dev/null +++ b/providers/implementations/ciphers/cipher_ascon_aead128.c @@ -0,0 +1,597 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "cipher_ascon_aead128.h" +#include +#include +#include +#include +#include "prov/implementations.h" +#include "prov/providercommon.h" +#include "prov/ciphercommon.h" +#include "prov/ciphercommon_aead.h" +#include "internal/common.h" +#include "providers/implementations/ciphers/cipher_ascon_aead128.inc" + +static OSSL_FUNC_cipher_newctx_fn ascon_aead128_newctx; +static OSSL_FUNC_cipher_freectx_fn ascon_aead128_freectx; +static OSSL_FUNC_cipher_dupctx_fn ascon_aead128_dupctx; +static OSSL_FUNC_cipher_encrypt_init_fn ascon_aead128_einit; +static OSSL_FUNC_cipher_decrypt_init_fn ascon_aead128_dinit; +static OSSL_FUNC_cipher_update_fn ascon_aead128_update; +static OSSL_FUNC_cipher_final_fn ascon_aead128_final; +static OSSL_FUNC_cipher_cipher_fn ascon_aead128_cipher; +static OSSL_FUNC_cipher_get_params_fn ascon_aead128_get_params; +static OSSL_FUNC_cipher_get_ctx_params_fn ascon_aead128_get_ctx_params; +static OSSL_FUNC_cipher_set_ctx_params_fn ascon_aead128_set_ctx_params; +static OSSL_FUNC_cipher_gettable_ctx_params_fn ascon_aead128_gettable_ctx_params; +static OSSL_FUNC_cipher_settable_ctx_params_fn ascon_aead128_settable_ctx_params; +#define ascon_aead128_gettable_params ossl_cipher_generic_gettable_params + +#define ASCON_AEAD128_FLAGS (PROV_CIPHER_FLAG_AEAD | PROV_CIPHER_FLAG_CUSTOM_IV) + +static void ascon_aead128_cleanctx(void *vctx) +{ + struct ascon_aead128_ctx_st *ctx = vctx; + + ctx->is_tag_set = 0; + ctx->is_ongoing = 0; + ctx->assoc_data_not_allowed = 0; + ctx->iv_set = 0; + if (ctx->internal_ctx != NULL) + ossl_ascon_aead_cleanup(ctx->internal_ctx); + OPENSSL_cleanse(ctx->tag, sizeof(ctx->tag)); + OPENSSL_cleanse(ctx->iv, sizeof(ctx->iv)); + /* Note: key is not cleared here to allow reinitialization with NULL key */ +} + +static void *ascon_aead128_newctx(void *provctx) +{ + struct ascon_aead128_ctx_st *ctx; + ASCON_AEAD_CTX *intctx; + + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(*ctx)); + if (ctx == NULL) + return NULL; + + ctx->provctx = provctx; + ctx->is_tag_set = 0; + ctx->is_ongoing = 0; + ctx->assoc_data_not_allowed = 0; + ctx->iv_set = 0; + ctx->key_set = 0; + + intctx = OPENSSL_zalloc(sizeof(*intctx)); + if (intctx == NULL) { + OPENSSL_free(ctx); + return NULL; + } + ctx->internal_ctx = intctx; + + return ctx; +} + +static void *ascon_aead128_dupctx(void *vctx) +{ + struct ascon_aead128_ctx_st *src = vctx; + struct ascon_aead128_ctx_st *dst = NULL; + ASCON_AEAD_CTX *saved_internal_ctx; + + if (src == NULL || !ossl_prov_is_running()) + return NULL; + + /* Create new context using the same provider context */ + if ((dst = ascon_aead128_newctx(src->provctx)) == NULL) + return NULL; + + /* Save the newly allocated internal_ctx pointer before overwriting */ + saved_internal_ctx = dst->internal_ctx; + + /* Copy all context fields */ + *dst = *src; + + /* Restore the newly allocated internal_ctx pointer */ + dst->internal_ctx = saved_internal_ctx; + + /* Deep copy the internal LibAscon context */ + if (src->internal_ctx != NULL && dst->internal_ctx != NULL) + memcpy(dst->internal_ctx, src->internal_ctx, sizeof(*dst->internal_ctx)); + + return dst; +} + +static void ascon_aead128_freectx(void *vctx) +{ + struct ascon_aead128_ctx_st *ctx = vctx; + + if (ctx == NULL) + return; + + ctx->provctx = NULL; + ascon_aead128_cleanctx(ctx); + OPENSSL_cleanse(ctx->key, sizeof(ctx->key)); + OPENSSL_free(ctx->internal_ctx); + OPENSSL_free(ctx); +} + +/* Internal initialization function (shared by encrypt and decrypt init) */ + +static int ascon_aead128_internal_init(void *vctx, direction_t direction, + const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen, + const OSSL_PARAM params[]) +{ + struct ascon_aead128_ctx_st *ctx = vctx; + uint8_t saved_tag[ASCON_AEAD_TAG_LEN]; + int tag_was_set; + unsigned char ivcopy[ASCON_AEAD_NONCE_LEN]; + + if (ctx == NULL) + return 0; + + if (key == NULL && iv == NULL) { + ctx->direction = direction; + if (params != NULL && !ascon_aead128_set_ctx_params(ctx, params)) + return 0; + return 1; + } + + if (key != NULL) { + if (keylen != ASCON_AEAD128_KEY_LEN) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } + memcpy(ctx->key, key, ASCON_AEAD128_KEY_LEN); + ctx->key_set = 1; + } + + if (iv != NULL) { + if (ivlen != ASCON_AEAD_NONCE_LEN) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); + return 0; + } + memcpy(ctx->iv, iv, ASCON_AEAD_NONCE_LEN); + ctx->iv_set = 1; + } + + ctx->direction = direction; + + tag_was_set = ctx->is_tag_set; + if (tag_was_set && direction == DECRYPTION) + memcpy(saved_tag, ctx->tag, ASCON_AEAD_TAG_LEN); + + if (ctx->key_set && ctx->iv_set) { + memcpy(ivcopy, ctx->iv, sizeof(ivcopy)); + ascon_aead128_cleanctx(ctx); + ctx->key_set = 1; + memcpy(ctx->iv, ivcopy, sizeof(ivcopy)); + ctx->iv_set = 1; + if (tag_was_set && direction == DECRYPTION) { + memcpy(ctx->tag, saved_tag, ASCON_AEAD_TAG_LEN); + ctx->is_tag_set = 1; + } + ossl_ascon_aead128_init(ctx->internal_ctx, ctx->key, ctx->iv); + ctx->is_ongoing = 1; + } else { + ctx->is_ongoing = 0; + ctx->assoc_data_not_allowed = 0; + ctx->is_tag_set = 0; + if (ctx->internal_ctx != NULL) + ossl_ascon_aead_cleanup(ctx->internal_ctx); + OPENSSL_cleanse(ctx->tag, sizeof(ctx->tag)); + if (!ctx->key_set) + OPENSSL_cleanse(ctx->key, sizeof(ctx->key)); + if (!ctx->iv_set) + OPENSSL_cleanse(ctx->iv, sizeof(ctx->iv)); + } + + if (params != NULL && !ascon_aead128_set_ctx_params(ctx, params)) + return 0; + + return 1; +} + +static int ascon_aead128_einit(void *vctx, const unsigned char *key, + size_t keylen, const unsigned char *iv, + size_t ivlen, const OSSL_PARAM params[]) +{ + return ascon_aead128_internal_init(vctx, ENCRYPTION, key, keylen, iv, ivlen, params); +} + +static int ascon_aead128_dinit(void *vctx, const unsigned char *key, + size_t keylen, const unsigned char *iv, + size_t ivlen, const OSSL_PARAM params[]) +{ + return ascon_aead128_internal_init(vctx, DECRYPTION, key, keylen, iv, ivlen, params); +} + +static int ascon_aead128_update(void *vctx, unsigned char *out, size_t *outl, + size_t outsize, const unsigned char *in, size_t inl) +{ + struct ascon_aead128_ctx_st *ctx = vctx; + + if (ctx == NULL) { + /* Context must be set before update */ + return 0; + } + + if (!ctx->is_ongoing) { + ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); + return 0; + } + + /* Handle AAD operation (out == NULL) - process associated data */ + if (out == NULL) { + /* Can only add AAD before encryption/decryption updates start */ + if (ctx->assoc_data_not_allowed) { + /* AAD already processed or encryption started - cannot add more */ + ERR_raise(ERR_LIB_PROV, PROV_R_UPDATE_CALL_OUT_OF_ORDER); + return 0; + } + + /* Process AAD if provided */ + if (inl > 0 && in != NULL) { + if (ctx->internal_ctx == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); + return 0; + } + ossl_ascon_aead128_assoc_data_update(ctx->internal_ctx, in, inl); + } + if (outl != NULL) + *outl = 0; + return 1; + } + + if (outsize < inl) { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + if (inl > 0 && in == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_INPUT_LENGTH); + return 0; + } + + if (ctx->direction == ENCRYPTION) { + const uint8_t *plaintext = in; + size_t plaintext_len = inl; + uint8_t *ciphertext = out; + size_t ciphertext_len; + + /* Mark that we've started encryption - AAD cannot be added after this */ + /* LibAscon encrypt_update will finalize AAD automatically if needed */ + ctx->assoc_data_not_allowed = 1; + + if (ctx->internal_ctx == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); + return 0; + } + + ciphertext_len = ossl_ascon_aead128_encrypt_update(ctx->internal_ctx, + ciphertext, + plaintext, + plaintext_len); + if (outl != NULL) + *outl = ciphertext_len; + return 1; + } else if (ctx->direction == DECRYPTION) { + uint8_t *plaintext = out; + size_t plaintext_len; + const uint8_t *ciphertext = in; + size_t ciphertext_len = inl; + + /* Mark that we've started decryption - AAD cannot be added after this */ + /* LibAscon decrypt_update will finalize AAD automatically if needed */ + ctx->assoc_data_not_allowed = 1; + + if (ctx->internal_ctx == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); + return 0; + } + + plaintext_len = ossl_ascon_aead128_decrypt_update(ctx->internal_ctx, + plaintext, + ciphertext, + ciphertext_len); + if (outl != NULL) + *outl = plaintext_len; + return 1; + } + return 0; +} + +/* PROVIDER'S FINAL FUNCTION */ + +static int ascon_aead128_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) +{ + struct ascon_aead128_ctx_st *ctx = vctx; + + if (!ossl_prov_is_running()) + return 0; + + if (ctx == NULL) { + /* Context must be set before final */ + return 0; + } + + if (!ctx->is_ongoing) { + ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); + return 0; + } + + if (ctx->direction == ENCRYPTION) { + uint8_t *ciphertext = out; + uint8_t *tag = ctx->tag; + size_t tag_len = ASCON_AEAD_TAG_LEN; + size_t ret; + + ret = ossl_ascon_aead128_encrypt_final((ASCON_AEAD_CTX *)ctx->internal_ctx, + ciphertext, tag, tag_len); + *outl = ret; + ctx->is_tag_set = 1; + + return 1; + } else if (ctx->direction == DECRYPTION) { + uint8_t *plaintext = out; + int is_tag_valid = 0; + size_t ret; + + if (ctx->is_tag_set) { + const uint8_t *expected_tag = ctx->tag; + size_t expected_tag_len = ASCON_AEAD_TAG_LEN; + + ret = ossl_ascon_aead128_decrypt_final((ASCON_AEAD_CTX *)ctx->internal_ctx, + plaintext, &is_tag_valid, + expected_tag, + expected_tag_len); + + if (is_tag_valid) { + *outl = ret; + return 1; + } + ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT); + return 0; + } else { + ERR_raise(ERR_LIB_PROV, PROV_R_TAG_NOT_SET); + return 0; + } + } + + *outl = 0; + return 1; +} + +static int ascon_aead128_get_params(OSSL_PARAM params[]) +{ + return ossl_cipher_generic_get_params(params, 0, ASCON_AEAD128_FLAGS, + ASCON_AEAD128_KEY_LEN * 8, + 1 * 8, + ASCON_AEAD_NONCE_LEN * 8); +} + +static const OSSL_PARAM *ascon_aead128_gettable_ctx_params(ossl_unused void *cctx, + ossl_unused void *provctx) +{ + return ascon_aead128_get_ctx_params_list; +} + +static int ascon_aead128_get_ctx_params(void *vctx, OSSL_PARAM params[]) +{ + struct ascon_aead128_ctx_st *ctx = vctx; + struct ascon_aead128_get_ctx_params_st p; + + if (ctx == NULL || !ascon_aead128_get_ctx_params_decoder(params, &p)) + return 0; + + if (p.keylen != NULL + && !OSSL_PARAM_set_size_t(p.keylen, ASCON_AEAD128_KEY_LEN)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + + if (p.ivlen != NULL + && !OSSL_PARAM_set_size_t(p.ivlen, ASCON_AEAD_NONCE_LEN)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + + if (p.taglen != NULL + && !OSSL_PARAM_set_size_t(p.taglen, ASCON_AEAD_TAG_LEN)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + + if (p.tag != NULL) { + /* + * reject the tag read in two cases: + * - decrypting, a tag is an input to be verified, never an output + * - encrypting, but final has not yet generated (set) the tag + */ + if (ctx->direction != ENCRYPTION || !ctx->is_tag_set) { + ERR_raise(ERR_LIB_PROV, PROV_R_TAG_NOT_SET); + return 0; + } + if (!OSSL_PARAM_set_octet_string(p.tag, ctx->tag, ASCON_AEAD_TAG_LEN)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + } + + if (p.upd_iv != NULL) { + if (!ctx->iv_set) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + if (!OSSL_PARAM_set_octet_string(p.upd_iv, ctx->iv, ASCON_AEAD_NONCE_LEN)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + } + + return 1; +} + +static const OSSL_PARAM *ascon_aead128_settable_ctx_params(ossl_unused void *cctx, + ossl_unused void *provctx) +{ + return ascon_aead128_set_ctx_params_list; +} + +static int ascon_aead128_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + struct ascon_aead128_ctx_st *ctx = vctx; + struct ascon_aead128_set_ctx_params_st p; + + if (ctx == NULL || !ascon_aead128_set_ctx_params_decoder(params, &p)) + return 0; + + if (p.taglen != NULL) { + size_t tag_len = 0; + + if (!OSSL_PARAM_get_size_t(p.taglen, &tag_len)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + if (tag_len != ASCON_AEAD_TAG_LEN) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG_LENGTH); + return 0; + } + } + + if (p.tag != NULL) { + /* when data is NULL, this is a request to set tag length */ + if (p.tag->data == NULL) { + /* + * this implementation only supports fixed, full-length tags of + * length ASCON_AEAD_TAG_LEN, so do nothing and return success + */ + return 1; + } + + /* only take tags as input during decryption */ + if (ctx->direction == ENCRYPTION) { + ERR_raise(ERR_LIB_PROV, PROV_R_TAG_NOT_NEEDED); + return 0; + } + + if (p.tag->data_type != OSSL_PARAM_OCTET_STRING) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + + /* We only accept strictly 16-byte tags here */ + if (p.tag->data_size != ASCON_AEAD_TAG_LEN) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG_LENGTH); + return 0; + } + memcpy(ctx->tag, p.tag->data, ASCON_AEAD_TAG_LEN); + ctx->is_tag_set = 1; + } + + return 1; +} + +/* + * One-shot cipher function for OSSL_FUNC_CIPHER_CIPHER + * This function handles one-shot encryption/decryption operations. + * Based on AES-SIV pattern: handles final (in == NULL), AAD (out == NULL), + * and regular encryption/decryption operations. + * For AEAD ciphers, CIPHER and UPDATE should behave the same way. + */ +static int ascon_aead128_cipher(void *vctx, unsigned char *out, size_t *outl, + size_t outsize, const unsigned char *in, + size_t inl) +{ + struct ascon_aead128_ctx_st *ctx = vctx; + size_t update_outl = 0; + + if (!ossl_prov_is_running()) + return 0; + + if (ctx == NULL) + return 0; + + /* Handle final operation (in == NULL) */ + if (in == NULL) { + size_t final_outl = 0; + + if (ascon_aead128_final(ctx, out, &final_outl, outsize) == 1) { + if (outl != NULL) + *outl = final_outl; + return 1; + } + return 0; + } + + /* Handle AAD operation (out == NULL) - process associated data */ + if (out == NULL) { + if (!ctx->is_ongoing) { + ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); + return 0; + } + if (ctx->assoc_data_not_allowed) { + ERR_raise(ERR_LIB_PROV, PROV_R_UPDATE_CALL_OUT_OF_ORDER); + return 0; + } + if (inl > 0) + ossl_ascon_aead128_assoc_data_update(ctx->internal_ctx, in, inl); + if (outl != NULL) + *outl = 0; + return 1; + } + + /* Check output buffer size */ + if (outsize < inl) { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + /* Handle regular encryption/decryption (streaming update) */ + if (!ctx->is_ongoing) { + ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); + return 0; + } + + /* Use the same logic as update */ + if (ascon_aead128_update(ctx, out, &update_outl, outsize, in, inl) + == 1) { + if (outl != NULL) + *outl = update_outl; + return 1; + } + + return 0; +} + +/********************************************************************* + * + * Setup + * + *****/ + +/* The dispatch table for ASCON-AEAD128 */ +const OSSL_DISPATCH ossl_ascon_aead128_functions[] = { + { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))ascon_aead128_newctx }, + { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))ascon_aead128_freectx }, + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))ascon_aead128_dupctx }, + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ascon_aead128_einit }, + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ascon_aead128_dinit }, + { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ascon_aead128_update }, + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ascon_aead128_final }, + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ascon_aead128_cipher }, + { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))ascon_aead128_get_params }, + { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, (void (*)(void))ascon_aead128_gettable_params }, + { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, (void (*)(void))ascon_aead128_get_ctx_params }, + { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, (void (*)(void))ascon_aead128_gettable_ctx_params }, + { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, (void (*)(void))ascon_aead128_set_ctx_params }, + { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, (void (*)(void))ascon_aead128_settable_ctx_params }, + OSSL_DISPATCH_END +}; diff --git a/providers/implementations/ciphers/cipher_ascon_aead128.h b/providers/implementations/ciphers/cipher_ascon_aead128.h new file mode 100644 index 0000000000000..7c8362aa32b33 --- /dev/null +++ b/providers/implementations/ciphers/cipher_ascon_aead128.h @@ -0,0 +1,60 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_PROV_CIPHER_ASCON_AEAD128_H +#define OSSL_PROV_CIPHER_ASCON_AEAD128_H + +#include +#ifndef OPENSSL_NO_ASCON128 + +#include +#include +#include "crypto/ascon.h" /* ASCON algorithm header */ + +/********************************************************************* + * + * ASCON-AEAD128 Context Structure and Types + * + *****/ + +/* Direction enum for encryption/decryption */ +typedef enum direction_et { + ENCRYPTION, + DECRYPTION +} direction_t; + +/* ASCON-AEAD128 AEAD cipher context structure */ +struct ascon_aead128_ctx_st { + void *provctx; + ASCON_AEAD_CTX *internal_ctx; /* a handle for the implementation internal context */ + + uint8_t tag[ASCON_AEAD_TAG_LEN]; /* storing the tag with fixed length */ + uint8_t iv[ASCON_AEAD_NONCE_LEN]; /* storing the IV (nonce) for get_updated_iv */ + uint8_t key[ASCON_AEAD128_KEY_LEN]; /* storing the key for reinitialization */ + + direction_t direction; /* either encryption or decryption */ + int is_tag_set; /* whether a tag has been computed or set */ + int is_ongoing; /* nonzero once an operation has started */ + int assoc_data_not_allowed; /* nonzero once payload begins; no more AAD accepted */ + int iv_set; /* whether the IV has been set */ + int key_set; /* whether the key has been set */ +}; + +/********************************************************************* + * + * ASCON-AEAD128 AEAD Function Declarations + * + *****/ + +/* Dispatch table for ASCON-AEAD128 */ +extern const OSSL_DISPATCH ossl_ascon_aead128_functions[]; + +#endif /* OPENSSL_NO_ASCON128 */ + +#endif /* OSSL_PROV_CIPHER_ASCON_AEAD128_H */ diff --git a/providers/implementations/ciphers/cipher_ascon_aead128.inc.in b/providers/implementations/ciphers/cipher_ascon_aead128.inc.in new file mode 100644 index 0000000000000..407b9a29c9008 --- /dev/null +++ b/providers/implementations/ciphers/cipher_ascon_aead128.inc.in @@ -0,0 +1,26 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the \"License\"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::paramnames qw(produce_param_decoder); +-} + +{- produce_param_decoder('ascon_aead128_get_ctx_params', + (['OSSL_CIPHER_PARAM_KEYLEN', 'keylen', 'size_t'], + ['OSSL_CIPHER_PARAM_IVLEN', 'ivlen', 'size_t'], + ['OSSL_CIPHER_PARAM_AEAD_TAGLEN', 'taglen', 'size_t'], + ['OSSL_CIPHER_PARAM_AEAD_TAG', 'tag', 'octet_string'], + ['OSSL_CIPHER_PARAM_UPDATED_IV', 'upd_iv', 'octet_string'], + )); -} + +{- produce_param_decoder('ascon_aead128_set_ctx_params', + (['OSSL_CIPHER_PARAM_AEAD_TAG', 'tag', 'octet_string'], + ['OSSL_CIPHER_PARAM_AEAD_TAGLEN', 'taglen', 'size_t'], + )); -} + diff --git a/providers/implementations/ciphers/cipher_blowfish.h b/providers/implementations/ciphers/cipher_blowfish.h index 8c3366866f3e5..30063fc22ec48 100644 --- a/providers/implementations/ciphers/cipher_blowfish.h +++ b/providers/implementations/ciphers/cipher_blowfish.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_camellia.c b/providers/implementations/ciphers/cipher_camellia.c index 0d4bab73c8cee..43040b7a0458f 100644 --- a/providers/implementations/ciphers/cipher_camellia.c +++ b/providers/implementations/ciphers/cipher_camellia.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -13,14 +13,17 @@ */ #include "internal/deprecated.h" -/* Dispatch functions for CAMELLIA cipher modes ecb, cbc, ofb, cfb, ctr */ +/* Dispatch functions for CAMELLIA cipher modes ecb, cbc, cts, ofb, cfb, ctr */ +#include "cipher_cts.h" #include "cipher_camellia.h" #include "prov/implementations.h" #include "prov/providercommon.h" static OSSL_FUNC_cipher_freectx_fn camellia_freectx; static OSSL_FUNC_cipher_dupctx_fn camellia_dupctx; +static OSSL_FUNC_cipher_encrypt_init_fn camellia_cbc_cts_einit; +static OSSL_FUNC_cipher_decrypt_init_fn camellia_cbc_cts_dinit; static void camellia_freectx(void *vctx) { @@ -46,6 +49,24 @@ static void *camellia_dupctx(void *ctx) return ret; } +static int camellia_cbc_cts_einit(void *ctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen, + const OSSL_PARAM params[]) +{ + if (!ossl_cipher_generic_einit(ctx, key, keylen, iv, ivlen, NULL)) + return 0; + return ossl_cipher_cbc_cts_set_ctx_params(ctx, params); +} + +static int camellia_cbc_cts_dinit(void *ctx, const unsigned char *key, size_t keylen, + const unsigned char *iv, size_t ivlen, + const OSSL_PARAM params[]) +{ + if (!ossl_cipher_generic_dinit(ctx, key, keylen, iv, ivlen, NULL)) + return 0; + return ossl_cipher_cbc_cts_set_ctx_params(ctx, params); +} + /* ossl_camellia256ecb_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, ecb, ECB, 0, 256, 128, 0, block) /* ossl_camellia192ecb_functions */ @@ -89,4 +110,9 @@ IMPLEMENT_generic_cipher(camellia, CAMELLIA, ctr, CTR, 0, 192, 8, 128, stream) /* ossl_camellia128ctr_functions */ IMPLEMENT_generic_cipher(camellia, CAMELLIA, ctr, CTR, 0, 128, 8, 128, stream) -#include "cipher_camellia_cts.inc" +/* ossl_camellia256cbc_cts_functions */ +IMPLEMENT_cts_cipher(camellia, CAMELLIA, cbc, CBC, PROV_CIPHER_FLAG_CTS, 256, 128, 128, block) +/* ossl_camellia192cbc_cts_functions */ +IMPLEMENT_cts_cipher(camellia, CAMELLIA, cbc, CBC, PROV_CIPHER_FLAG_CTS, 192, 128, 128, block) +/* ossl_camellia128cbc_cts_functions */ +IMPLEMENT_cts_cipher(camellia, CAMELLIA, cbc, CBC, PROV_CIPHER_FLAG_CTS, 128, 128, 128, block) diff --git a/providers/implementations/ciphers/cipher_camellia.h b/providers/implementations/ciphers/cipher_camellia.h index 1ef9106823298..e2cd5d26a203b 100644 --- a/providers/implementations/ciphers/cipher_camellia.h +++ b/providers/implementations/ciphers/cipher_camellia.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_camellia_cts.inc b/providers/implementations/ciphers/cipher_camellia_cts.inc deleted file mode 100644 index 84ea992b8da9a..0000000000000 --- a/providers/implementations/ciphers/cipher_camellia_cts.inc +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -/* Dispatch functions for CAMELLIA CBC CTS ciphers */ - -#include -#include "cipher_cts.h" - -#define CTS_FLAGS PROV_CIPHER_FLAG_CTS - -static OSSL_FUNC_cipher_encrypt_init_fn camellia_cbc_cts_einit; -static OSSL_FUNC_cipher_decrypt_init_fn camellia_cbc_cts_dinit; -static OSSL_FUNC_cipher_get_ctx_params_fn camellia_cbc_cts_get_ctx_params; -static OSSL_FUNC_cipher_set_ctx_params_fn camellia_cbc_cts_set_ctx_params; -static OSSL_FUNC_cipher_gettable_ctx_params_fn camellia_cbc_cts_gettable_ctx_params; -static OSSL_FUNC_cipher_settable_ctx_params_fn camellia_cbc_cts_settable_ctx_params; - -CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(camellia_cbc_cts) -OSSL_PARAM_utf8_string(OSSL_CIPHER_PARAM_CTS_MODE, NULL, 0), -CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(camellia_cbc_cts) - -static int camellia_cbc_cts_einit(void *ctx, const unsigned char *key, size_t keylen, - const unsigned char *iv, size_t ivlen, - const OSSL_PARAM params[]) -{ - if (!ossl_cipher_generic_einit(ctx, key, keylen, iv, ivlen, NULL)) - return 0; - return camellia_cbc_cts_set_ctx_params(ctx, params); -} - -static int camellia_cbc_cts_dinit(void *ctx, const unsigned char *key, size_t keylen, - const unsigned char *iv, size_t ivlen, - const OSSL_PARAM params[]) -{ - if (!ossl_cipher_generic_dinit(ctx, key, keylen, iv, ivlen, NULL)) - return 0; - return camellia_cbc_cts_set_ctx_params(ctx, params); -} - -static int camellia_cbc_cts_get_ctx_params(void *vctx, OSSL_PARAM params[]) -{ - PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; - OSSL_PARAM *p; - - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS_MODE); - if (p != NULL) { - const char *name = ossl_cipher_cbc_cts_mode_id2name(ctx->cts_mode); - - if (name == NULL || !OSSL_PARAM_set_utf8_string(p, name)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; - } - } - return ossl_cipher_generic_get_ctx_params(vctx, params); -} - -CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(camellia_cbc_cts) -OSSL_PARAM_utf8_string(OSSL_CIPHER_PARAM_CTS_MODE, NULL, 0), -CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(camellia_cbc_cts) - -static int camellia_cbc_cts_set_ctx_params(void *vctx, const OSSL_PARAM params[]) -{ - PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; - const OSSL_PARAM *p; - int id; - - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_CTS_MODE); - if (p != NULL) { - if (p->data_type != OSSL_PARAM_UTF8_STRING) - goto err; - id = ossl_cipher_cbc_cts_mode_name2id(p->data); - if (id < 0) - goto err; - - ctx->cts_mode = (unsigned int)id; - } - return ossl_cipher_generic_set_ctx_params(vctx, params); -err: - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); - return 0; -} - -/* ossl_camellia256cbc_cts_functions */ -IMPLEMENT_cts_cipher(camellia, CAMELLIA, cbc, CBC, CTS_FLAGS, 256, 128, 128, block) -/* ossl_camellia192cbc_cts_functions */ -IMPLEMENT_cts_cipher(camellia, CAMELLIA, cbc, CBC, CTS_FLAGS, 192, 128, 128, block) -/* ossl_camellia128cbc_cts_functions */ -IMPLEMENT_cts_cipher(camellia, CAMELLIA, cbc, CBC, CTS_FLAGS, 128, 128, 128, block) diff --git a/providers/implementations/ciphers/cipher_camellia_hw.c b/providers/implementations/ciphers/cipher_camellia_hw.c index e8dfbe15172fa..cb600fc976b9d 100644 --- a/providers/implementations/ciphers/cipher_camellia_hw.c +++ b/providers/implementations/ciphers/cipher_camellia_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2001-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_cast.h b/providers/implementations/ciphers/cipher_cast.h index 11164f543f613..5dc07b1026344 100644 --- a/providers/implementations/ciphers/cipher_cast.h +++ b/providers/implementations/ciphers/cipher_cast.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_chacha20.c b/providers/implementations/ciphers/cipher_chacha20.c index 19b77d77aaeed..67a95f8d8c114 100644 --- a/providers/implementations/ciphers/cipher_chacha20.c +++ b/providers/implementations/ciphers/cipher_chacha20.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -79,16 +79,14 @@ static void *chacha20_dupctx(void *vctx) PROV_CHACHA20_CTX *ctx = (PROV_CHACHA20_CTX *)vctx; PROV_CHACHA20_CTX *dupctx = NULL; - if (ctx != NULL) { - dupctx = OPENSSL_memdup(ctx, sizeof(*dupctx)); - if (dupctx != NULL && dupctx->base.tlsmac != NULL && dupctx->base.alloced) { - dupctx->base.tlsmac = OPENSSL_memdup(dupctx->base.tlsmac, - dupctx->base.tlsmacsize); - if (dupctx->base.tlsmac == NULL) { - OPENSSL_free(dupctx); - dupctx = NULL; - } - } + if (ctx == NULL) + return NULL; + + dupctx = OPENSSL_memdup(ctx, sizeof(*dupctx)); + if (dupctx != NULL + && !ossl_cipher_generic_dupctx_tlsmac(&dupctx->base, &ctx->base)) { + OPENSSL_clear_free(dupctx, sizeof(*dupctx)); + return NULL; } return dupctx; } diff --git a/providers/implementations/ciphers/cipher_chacha20.h b/providers/implementations/ciphers/cipher_chacha20.h index 5338ad949ccd0..4b92c149e5f5f 100644 --- a/providers/implementations/ciphers/cipher_chacha20.h +++ b/providers/implementations/ciphers/cipher_chacha20.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305.c b/providers/implementations/ciphers/cipher_chacha20_poly1305.c index a48b9c3725166..45032d86ad7b4 100644 --- a/providers/implementations/ciphers/cipher_chacha20_poly1305.c +++ b/providers/implementations/ciphers/cipher_chacha20_poly1305.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -68,13 +68,10 @@ static void *chacha20_poly1305_dupctx(void *provctx) if (ctx == NULL) return NULL; dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); - if (dctx != NULL && dctx->base.tlsmac != NULL && dctx->base.alloced) { - dctx->base.tlsmac = OPENSSL_memdup(dctx->base.tlsmac, - dctx->base.tlsmacsize); - if (dctx->base.tlsmac == NULL) { - OPENSSL_free(dctx); - dctx = NULL; - } + if (dctx != NULL + && !ossl_cipher_generic_dupctx_tlsmac(&dctx->base, &ctx->base)) { + OPENSSL_clear_free(dctx, sizeof(*dctx)); + return NULL; } return dctx; } @@ -291,11 +288,6 @@ static int chacha20_poly1305_cipher(void *vctx, unsigned char *out, if (!ossl_prov_is_running()) return 0; - if (inl == 0) { - *outl = 0; - return 1; - } - if (outsize < inl) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; @@ -316,6 +308,15 @@ static int chacha20_poly1305_update(void *vctx, unsigned char *out, if (ctx->iv_state == IV_STATE_FINISHED) return 0; + /* + * a zero-length update is a nop, ALWAYS SUCCEED via early exit + * NB: ONLY EVP_Cipher() / final produce or check the tag + */ + if (inl == 0) { + *outl = 0; + return 1; + } + return chacha20_poly1305_cipher(vctx, out, outl, outsize, in, inl); } diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305.h b/providers/implementations/ciphers/cipher_chacha20_poly1305.h index 6914966f6e6d8..55e2d254259fb 100644 --- a/providers/implementations/ciphers/cipher_chacha20_poly1305.h +++ b/providers/implementations/ciphers/cipher_chacha20_poly1305.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305_hw.c b/providers/implementations/ciphers/cipher_chacha20_poly1305_hw.c index 31a163e57e730..cd93e338c7a5e 100644 --- a/providers/implementations/ciphers/cipher_chacha20_poly1305_hw.c +++ b/providers/implementations/ciphers/cipher_chacha20_poly1305_hw.c @@ -247,6 +247,7 @@ static int chacha20_poly1305_tls_cipher(PROV_CIPHER_CTX *bctx, if (bctx->enc) { memcpy(out, ctx->tag, POLY1305_BLOCK_SIZE); } else { + /* TODO: raise PROV_R_BAD_DECRYPT here too? TLS record path, silent for now */ if (CRYPTO_memcmp(tohash, in, POLY1305_BLOCK_SIZE)) { if (len > POLY1305_BLOCK_SIZE) memset(out - (len - POLY1305_BLOCK_SIZE), 0, @@ -381,6 +382,7 @@ static int chacha20_poly1305_aead_cipher(PROV_CIPHER_CTX *bctx, if (bctx->enc) { memcpy(out, ctx->tag, POLY1305_BLOCK_SIZE); } else { + /* TODO: raise PROV_R_BAD_DECRYPT here too? TLS record path, silent for now */ if (CRYPTO_memcmp(temp, in, POLY1305_BLOCK_SIZE)) { memset(out - plen, 0, plen); goto err; @@ -389,8 +391,10 @@ static int chacha20_poly1305_aead_cipher(PROV_CIPHER_CTX *bctx, inl -= POLY1305_BLOCK_SIZE; } } else if (!bctx->enc) { - if (CRYPTO_memcmp(temp, ctx->tag, ctx->tag_len)) + if (CRYPTO_memcmp(temp, ctx->tag, ctx->tag_len) != 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT); goto err; + } } } finish: diff --git a/providers/implementations/ciphers/cipher_cts.c b/providers/implementations/ciphers/cipher_cts.c index 54c6d49d9f526..e3578c9162de2 100644 --- a/providers/implementations/ciphers/cipher_cts.c +++ b/providers/implementations/ciphers/cipher_cts.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,7 +11,7 @@ * Helper functions for 128 bit CBC CTS ciphers (Currently AES and Camellia). * * The function dispatch tables are embedded into cipher_aes.c - * and cipher_camellia.c using cipher_aes_cts.inc and cipher_camellia_cts.inc + * and cipher_camellia.c */ /* @@ -47,10 +47,25 @@ */ #include +#include #include "prov/ciphercommon.h" #include "internal/nelem.h" #include "cipher_cts.h" +struct cipher_cts_get_ctx_param_list_st { + struct ossl_cipher_get_ctx_param_list_st common; + OSSL_PARAM *mode; +}; + +struct cipher_cts_set_ctx_param_list_st { + OSSL_PARAM *mode; +}; + +#define cipher_cts_get_ctx_params_st cipher_cts_get_ctx_param_list_st +#define cipher_cts_set_ctx_params_st cipher_cts_set_ctx_param_list_st + +#include "providers/implementations/ciphers/cipher_cts.inc" + /* The value assigned to 0 is the default */ #define CTS_CS1 0 #define CTS_CS2 1 @@ -96,6 +111,63 @@ int ossl_cipher_cbc_cts_mode_name2id(const char *name) return -1; } +int ossl_cipher_cbc_cts_get_ctx_params(void *vctx, OSSL_PARAM params[]) +{ + PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; + struct cipher_cts_get_ctx_param_list_st p; + + if (ctx == NULL || !cipher_cts_get_ctx_params_decoder(params, &p)) + return 0; + + if (!ossl_cipher_common_get_ctx_params(ctx, &p.common)) + return 0; + + if (p.mode != NULL) { + const char *name = ossl_cipher_cbc_cts_mode_id2name(ctx->cts_mode); + + if (name == NULL || !OSSL_PARAM_set_utf8_string(p.mode, name)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + } + return 1; +} + +const OSSL_PARAM *ossl_cipher_cbc_cts_gettable_ctx_params( + ossl_unused void *cctx, ossl_unused void *provctx) +{ + return cipher_cts_get_ctx_params_list; +} + +int ossl_cipher_cbc_cts_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; + struct cipher_cts_set_ctx_param_list_st p; + + if (ctx == NULL || !cipher_cts_set_ctx_params_decoder(params, &p)) + return 0; + + if (p.mode != NULL) { + int id; + + if (p.mode->data_type != OSSL_PARAM_UTF8_STRING + || p.mode->data == NULL + || (id = ossl_cipher_cbc_cts_mode_name2id(p.mode->data)) < 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); + return 0; + } + ctx->cts_mode = (unsigned int)id; + } + + return 1; +} + +const OSSL_PARAM *ossl_cipher_cbc_cts_settable_ctx_params( + ossl_unused void *cctx, ossl_unused void *provctx) +{ + return cipher_cts_set_ctx_params_list; +} + static size_t cts128_cs1_encrypt(PROV_CIPHER_CTX *ctx, const unsigned char *in, unsigned char *out, size_t len) { diff --git a/providers/implementations/ciphers/cipher_cts.h b/providers/implementations/ciphers/cipher_cts.h index 8bae4f8d3baa3..43e94e415a010 100644 --- a/providers/implementations/ciphers/cipher_cts.h +++ b/providers/implementations/ciphers/cipher_cts.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -38,18 +38,22 @@ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ (void (*)(void))ossl_cipher_generic_gettable_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ - (void (*)(void))alg##_cbc_cts_get_ctx_params }, \ + (void (*)(void))ossl_cipher_cbc_cts_get_ctx_params }, \ { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ - (void (*)(void))alg##_cbc_cts_set_ctx_params }, \ + (void (*)(void))ossl_cipher_cbc_cts_set_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ - (void (*)(void))alg##_cbc_cts_gettable_ctx_params }, \ + (void (*)(void))ossl_cipher_cbc_cts_gettable_ctx_params }, \ { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ - (void (*)(void))alg##_cbc_cts_settable_ctx_params }, \ + (void (*)(void))ossl_cipher_cbc_cts_settable_ctx_params }, \ OSSL_DISPATCH_END \ }; OSSL_FUNC_cipher_update_fn ossl_cipher_cbc_cts_block_update; OSSL_FUNC_cipher_final_fn ossl_cipher_cbc_cts_block_final; +OSSL_FUNC_cipher_get_ctx_params_fn ossl_cipher_cbc_cts_get_ctx_params; +OSSL_FUNC_cipher_set_ctx_params_fn ossl_cipher_cbc_cts_set_ctx_params; +OSSL_FUNC_cipher_gettable_ctx_params_fn ossl_cipher_cbc_cts_gettable_ctx_params; +OSSL_FUNC_cipher_settable_ctx_params_fn ossl_cipher_cbc_cts_settable_ctx_params; const char *ossl_cipher_cbc_cts_mode_id2name(unsigned int id); int ossl_cipher_cbc_cts_mode_name2id(const char *name); diff --git a/providers/implementations/ciphers/cipher_cts.inc.in b/providers/implementations/ciphers/cipher_cts.inc.in new file mode 100644 index 0000000000000..d5b921729b7cb --- /dev/null +++ b/providers/implementations/ciphers/cipher_cts.inc.in @@ -0,0 +1,24 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::paramnames qw(produce_param_decoder); +-} + +{- produce_param_decoder('cipher_cts_get_ctx_params', + (['OSSL_CIPHER_PARAM_KEYLEN', 'common.keylen', 'size_t'], + ['OSSL_CIPHER_PARAM_IVLEN', 'common.ivlen', 'size_t'], + ['OSSL_CIPHER_PARAM_IV', 'common.iv', 'octet_string'], + ['OSSL_CIPHER_PARAM_UPDATED_IV', 'common.updiv', 'octet_string'], + ['OSSL_CIPHER_PARAM_CTS_MODE', 'mode', 'utf8_string'], + )); -} + +{- produce_param_decoder('cipher_cts_set_ctx_params', + (['OSSL_CIPHER_PARAM_CTS_MODE', 'mode', 'utf8_string'], + )); -} diff --git a/providers/implementations/ciphers/cipher_des.c b/providers/implementations/ciphers/cipher_des.c index c9073939697f7..60396db2cbda7 100644 --- a/providers/implementations/ciphers/cipher_des.c +++ b/providers/implementations/ciphers/cipher_des.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -20,6 +20,15 @@ #include "prov/implementations.h" #include "prov/providercommon.h" +struct des_get_ctx_param_list_st { + struct ossl_cipher_get_ctx_param_list_st common; + OSSL_PARAM *rand; +}; + +#define des_get_ctx_params_st des_get_ctx_param_list_st + +#include "providers/implementations/ciphers/cipher_des.inc" + #define DES_FLAGS PROV_CIPHER_FLAG_RAND_KEY static OSSL_FUNC_cipher_freectx_fn des_freectx; @@ -117,7 +126,6 @@ static int des_dinit(void *vctx, const unsigned char *key, size_t keylen, static int des_generatekey(PROV_CIPHER_CTX *ctx, void *ptr) { - DES_cblock *deskey = ptr; size_t kl = ctx->keylen; @@ -127,20 +135,24 @@ static int des_generatekey(PROV_CIPHER_CTX *ctx, void *ptr) return 1; } -CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(des) -OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, NULL, 0), - CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(des) +static const OSSL_PARAM *des_gettable_ctx_params(ossl_unused void *cctx, + ossl_unused void *provctx) +{ + return des_get_ctx_params_list; +} - static int des_get_ctx_params(void *vctx, OSSL_PARAM params[]) +static int des_get_ctx_params(void *vctx, OSSL_PARAM params[]) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; - OSSL_PARAM *p; + struct des_get_ctx_param_list_st p; + + if (ctx == NULL || !des_get_ctx_params_decoder(params, &p)) + return 0; - if (!ossl_cipher_generic_get_ctx_params(vctx, params)) + if (!ossl_cipher_common_get_ctx_params(ctx, &p.common)) return 0; - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RANDOM_KEY); - if (p != NULL && !des_generatekey(ctx, p->data)) { + if (p.rand != NULL && !des_generatekey(ctx, p.rand->data)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY); return 0; } diff --git a/providers/implementations/ciphers/cipher_des.h b/providers/implementations/ciphers/cipher_des.h index afbb66566207a..6be5a91ea6003 100644 --- a/providers/implementations/ciphers/cipher_des.h +++ b/providers/implementations/ciphers/cipher_des.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_des.inc.in b/providers/implementations/ciphers/cipher_des.inc.in new file mode 100644 index 0000000000000..5accd2a49d652 --- /dev/null +++ b/providers/implementations/ciphers/cipher_des.inc.in @@ -0,0 +1,22 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::paramnames qw(produce_param_decoder); +-} + +{- produce_param_decoder('des_get_ctx_params', + (['OSSL_CIPHER_PARAM_KEYLEN', 'common.keylen', 'size_t'], + ['OSSL_CIPHER_PARAM_IVLEN', 'common.ivlen', 'size_t'], + ['OSSL_CIPHER_PARAM_PADDING', 'common.pad', 'uint'], + ['OSSL_CIPHER_PARAM_NUM', 'common.num', 'uint'], + ['OSSL_CIPHER_PARAM_IV', 'common.iv', 'octet_string'], + ['OSSL_CIPHER_PARAM_UPDATED_IV', 'common.updiv', 'octet_string'], + ['OSSL_CIPHER_PARAM_RANDOM_KEY', 'rand', 'octet_string'], + )); -} diff --git a/providers/implementations/ciphers/cipher_des_hw.c b/providers/implementations/ciphers/cipher_des_hw.c index a36118260c457..854acb0c0a2f6 100644 --- a/providers/implementations/ciphers/cipher_des_hw.c +++ b/providers/implementations/ciphers/cipher_des_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_idea.h b/providers/implementations/ciphers/cipher_idea.h index dbb5c332c15dd..11727973a566a 100644 --- a/providers/implementations/ciphers/cipher_idea.h +++ b/providers/implementations/ciphers/cipher_idea.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_rc2.c b/providers/implementations/ciphers/cipher_rc2.c index 546e020133f30..93b55fb3be82a 100644 --- a/providers/implementations/ciphers/cipher_rc2.c +++ b/providers/implementations/ciphers/cipher_rc2.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -20,6 +20,24 @@ #include "prov/implementations.h" #include "prov/providercommon.h" +struct rc2_get_ctx_param_list_st { + struct ossl_cipher_get_ctx_param_list_st common; + OSSL_PARAM *bits; + OSSL_PARAM *algid; + OSSL_PARAM *oldid; +}; + +struct rc2_set_ctx_param_list_st { + struct ossl_cipher_set_ctx_param_list_st common; + OSSL_PARAM *bits; + OSSL_PARAM *algid; +}; + +#define rc2_get_ctx_params_st rc2_get_ctx_param_list_st +#define rc2_set_ctx_params_st rc2_set_ctx_param_list_st + +#include "providers/implementations/ciphers/cipher_rc2.inc" + #define RC2_40_MAGIC 0xa0 #define RC2_64_MAGIC 0x78 #define RC2_128_MAGIC 0x3a @@ -106,17 +124,20 @@ static int rc2_dinit(void *ctx, const unsigned char *key, size_t keylen, static int rc2_get_ctx_params(void *vctx, OSSL_PARAM params[]) { PROV_RC2_CTX *ctx = (PROV_RC2_CTX *)vctx; + struct rc2_get_ctx_param_list_st prms; OSSL_PARAM *p, *p1, *p2; - if (!ossl_cipher_generic_get_ctx_params(vctx, params)) + if (ctx == NULL || !rc2_get_ctx_params_decoder(params, &prms)) + return 0; + if (!ossl_cipher_common_get_ctx_params(&ctx->base, &prms.common)) return 0; - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RC2_KEYBITS); + p = prms.bits; if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->key_bits)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } - p1 = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS); - p2 = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS_OLD); + p1 = prms.algid; + p2 = prms.oldid; if (p1 != NULL || p2 != NULL) { long num; int i; @@ -174,21 +195,24 @@ static int rc2_get_ctx_params(void *vctx, OSSL_PARAM params[]) static int rc2_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { PROV_RC2_CTX *ctx = (PROV_RC2_CTX *)vctx; + struct rc2_set_ctx_param_list_st prms; const OSSL_PARAM *p; if (ossl_param_is_empty(params)) return 1; - if (!ossl_cipher_var_keylen_set_ctx_params(vctx, params)) + if (ctx == NULL || !rc2_set_ctx_params_decoder(params, &prms)) return 0; - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_RC2_KEYBITS); + if (!ossl_cipher_common_set_ctx_params(&ctx->base, &prms.common)) + return 0; + p = prms.bits; if (p != NULL) { if (!OSSL_PARAM_get_size_t(p, &ctx->key_bits)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } } - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS); + p = prms.algid; if (p != NULL) { ASN1_TYPE *type = NULL; long num = 0; @@ -220,16 +244,17 @@ static int rc2_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 1; } -CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(rc2) -OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_RC2_KEYBITS, NULL), - OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS, NULL, 0), - CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(rc2) +static const OSSL_PARAM *rc2_gettable_ctx_params(ossl_unused void *cctx, + ossl_unused void *provctx) +{ + return rc2_get_ctx_params_list; +} - CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(rc2) - OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), - OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_RC2_KEYBITS, NULL), - OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS, NULL, 0), - CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(rc2) +static const OSSL_PARAM *rc2_settable_ctx_params(ossl_unused void *cctx, + ossl_unused void *provctx) +{ + return rc2_set_ctx_params_list; +} #define IMPLEMENT_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, blkbits, \ ivbits, typ) \ @@ -280,8 +305,8 @@ OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_RC2_KEYBITS, NULL), OSSL_DISPATCH_END \ }; - /* ossl_rc2128ecb_functions */ - IMPLEMENT_cipher(rc2, RC2, ecb, ECB, RC2_FLAGS, 128, 64, 0, block) +/* ossl_rc2128ecb_functions */ +IMPLEMENT_cipher(rc2, RC2, ecb, ECB, RC2_FLAGS, 128, 64, 0, block) /* ossl_rc2128cbc_functions */ IMPLEMENT_cipher(rc2, RC2, cbc, CBC, RC2_FLAGS, 128, 64, 64, block) /* ossl_rc240cbc_functions */ diff --git a/providers/implementations/ciphers/cipher_rc2.h b/providers/implementations/ciphers/cipher_rc2.h index 025f331507f3c..1c32089c1b826 100644 --- a/providers/implementations/ciphers/cipher_rc2.h +++ b/providers/implementations/ciphers/cipher_rc2.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_rc2.inc.in b/providers/implementations/ciphers/cipher_rc2.inc.in new file mode 100644 index 0000000000000..98d54bf8940a8 --- /dev/null +++ b/providers/implementations/ciphers/cipher_rc2.inc.in @@ -0,0 +1,32 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::paramnames qw(produce_param_decoder); +-} + +{- produce_param_decoder('rc2_get_ctx_params', + (['OSSL_CIPHER_PARAM_KEYLEN', 'common.keylen', 'size_t'], + ['OSSL_CIPHER_PARAM_IVLEN', 'common.ivlen', 'size_t'], + ['OSSL_CIPHER_PARAM_PADDING', 'common.pad', 'uint'], + ['OSSL_CIPHER_PARAM_NUM', 'common.num', 'uint'], + ['OSSL_CIPHER_PARAM_IV', 'common.iv', 'octet_string'], + ['OSSL_CIPHER_PARAM_UPDATED_IV', 'common.updiv', 'octet_string'], + ['OSSL_CIPHER_PARAM_RC2_KEYBITS', 'bits', 'size_t'], + ['OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS', 'algid', 'octet_string'], + ['OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS_OLD', 'oldid', 'octet_string'], + )); -} + +{- produce_param_decoder('rc2_set_ctx_params', + (['OSSL_CIPHER_PARAM_PADDING', 'common.pad', 'uint'], + ['OSSL_CIPHER_PARAM_NUM', 'common.num', 'uint'], + ['OSSL_CIPHER_PARAM_KEYLEN', 'common.keylen', 'size_t'], + ['OSSL_CIPHER_PARAM_RC2_KEYBITS', 'bits', 'size_t'], + ['OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS', 'algid', 'octet_string'], + )); -} diff --git a/providers/implementations/ciphers/cipher_rc4.h b/providers/implementations/ciphers/cipher_rc4.h index ed7ffe23393a1..2842f36153a2d 100644 --- a/providers/implementations/ciphers/cipher_rc4.h +++ b/providers/implementations/ciphers/cipher_rc4.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_rc4_hmac_md5.c b/providers/implementations/ciphers/cipher_rc4_hmac_md5.c index f3fbf2e1c4025..5683a63f9db61 100644 --- a/providers/implementations/ciphers/cipher_rc4_hmac_md5.c +++ b/providers/implementations/ciphers/cipher_rc4_hmac_md5.c @@ -76,10 +76,18 @@ static void rc4_hmac_md5_freectx(void *vctx) static void *rc4_hmac_md5_dupctx(void *vctx) { PROV_RC4_HMAC_MD5_CTX *ctx = vctx; + PROV_RC4_HMAC_MD5_CTX *dctx; if (ctx == NULL) return NULL; - return OPENSSL_memdup(ctx, sizeof(*ctx)); + + dctx = OPENSSL_memdup(ctx, sizeof(*ctx)); + if (dctx != NULL + && !ossl_cipher_generic_dupctx_tlsmac(&dctx->base, &ctx->base)) { + OPENSSL_clear_free(dctx, sizeof(*dctx)); + return NULL; + } + return dctx; } static int rc4_hmac_md5_einit(void *ctx, const unsigned char *key, diff --git a/providers/implementations/ciphers/cipher_rc4_hmac_md5.h b/providers/implementations/ciphers/cipher_rc4_hmac_md5.h index ad243cd0a358e..871a35cd73cc0 100644 --- a/providers/implementations/ciphers/cipher_rc4_hmac_md5.h +++ b/providers/implementations/ciphers/cipher_rc4_hmac_md5.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_rc5.c b/providers/implementations/ciphers/cipher_rc5.c index 4bfb40de4efec..b25c2e6c46724 100644 --- a/providers/implementations/ciphers/cipher_rc5.c +++ b/providers/implementations/ciphers/cipher_rc5.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -20,6 +20,21 @@ #include "prov/implementations.h" #include "prov/providercommon.h" +struct rc5_get_ctx_param_list_st { + struct ossl_cipher_get_ctx_param_list_st common; + OSSL_PARAM *rounds; +}; + +struct rc5_set_ctx_param_list_st { + struct ossl_cipher_set_ctx_param_list_st common; + OSSL_PARAM *rounds; +}; + +#define rc5_get_ctx_params_st rc5_get_ctx_param_list_st +#define rc5_set_ctx_params_st rc5_set_ctx_param_list_st + +#include "providers/implementations/ciphers/cipher_rc5.inc" + #define RC5_FLAGS PROV_CIPHER_FLAG_VARIABLE_LENGTH static OSSL_FUNC_cipher_encrypt_init_fn rc5_einit; @@ -75,19 +90,18 @@ static int rc5_dinit(void *ctx, const unsigned char *key, size_t keylen, static int rc5_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { PROV_RC5_CTX *ctx = (PROV_RC5_CTX *)vctx; - const OSSL_PARAM *p; + struct rc5_set_ctx_param_list_st p; - if (ossl_param_is_empty(params)) - return 1; + if (ctx == NULL || !rc5_set_ctx_params_decoder(params, &p)) + return 0; - if (!ossl_cipher_var_keylen_set_ctx_params(vctx, params)) + if (!ossl_cipher_common_set_ctx_params(&ctx->base, &p.common)) return 0; - p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_ROUNDS); - if (p != NULL) { + if (p.rounds != NULL) { unsigned int rounds; - if (!OSSL_PARAM_get_uint(p, &rounds)) { + if (!OSSL_PARAM_get_uint(p.rounds, &rounds)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } @@ -102,24 +116,30 @@ static int rc5_set_ctx_params(void *vctx, const OSSL_PARAM params[]) return 1; } -CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(rc5) -OSSL_PARAM_uint(OSSL_CIPHER_PARAM_ROUNDS, NULL), - CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(rc5) +const OSSL_PARAM *rc5_gettable_ctx_params(ossl_unused void *cctx, + ossl_unused void *provctx) +{ + return rc5_get_ctx_params_list; +} - CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(rc5) - OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), - OSSL_PARAM_uint(OSSL_CIPHER_PARAM_ROUNDS, NULL), - CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(rc5) +const OSSL_PARAM *rc5_settable_ctx_params(ossl_unused void *cctx, + ossl_unused void *provctx) +{ + return rc5_set_ctx_params_list; +} - static int rc5_get_ctx_params(void *vctx, OSSL_PARAM params[]) +static int rc5_get_ctx_params(void *vctx, OSSL_PARAM params[]) { PROV_RC5_CTX *ctx = (PROV_RC5_CTX *)vctx; - OSSL_PARAM *p; + struct rc5_get_ctx_param_list_st p; - if (!ossl_cipher_generic_get_ctx_params(vctx, params)) + if (ctx == NULL || !rc5_get_ctx_params_decoder(params, &p)) return 0; - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_ROUNDS); - if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->rounds)) { + + if (!ossl_cipher_common_get_ctx_params(&ctx->base, &p.common)) + return 0; + + if (p.rounds != NULL && !OSSL_PARAM_set_uint(p.rounds, ctx->rounds)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } diff --git a/providers/implementations/ciphers/cipher_rc5.h b/providers/implementations/ciphers/cipher_rc5.h index 131c34f520115..4141475f11122 100644 --- a/providers/implementations/ciphers/cipher_rc5.h +++ b/providers/implementations/ciphers/cipher_rc5.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_rc5.inc.in b/providers/implementations/ciphers/cipher_rc5.inc.in new file mode 100644 index 0000000000000..5f96c2b7fc44a --- /dev/null +++ b/providers/implementations/ciphers/cipher_rc5.inc.in @@ -0,0 +1,29 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::paramnames qw(produce_param_decoder); +-} + +{- produce_param_decoder('rc5_get_ctx_params', + (['OSSL_CIPHER_PARAM_KEYLEN', 'common.keylen', 'size_t'], + ['OSSL_CIPHER_PARAM_IVLEN', 'common.ivlen', 'size_t'], + ['OSSL_CIPHER_PARAM_PADDING', 'common.pad', 'uint'], + ['OSSL_CIPHER_PARAM_NUM', 'common.num', 'uint'], + ['OSSL_CIPHER_PARAM_IV', 'common.iv', 'octet_string'], + ['OSSL_CIPHER_PARAM_UPDATED_IV', 'common.updiv', 'octet_string'], + ['OSSL_CIPHER_PARAM_ROUNDS', 'rounds', 'uint'], + )); -} + +{- produce_param_decoder('rc5_set_ctx_params', + (['OSSL_CIPHER_PARAM_PADDING', 'common.pad', 'uint'], + ['OSSL_CIPHER_PARAM_NUM', 'common.num', 'uint'], + ['OSSL_CIPHER_PARAM_KEYLEN', 'common.keylen', 'size_t'], + ['OSSL_CIPHER_PARAM_ROUNDS', 'rounds', 'uint'], + )); -} diff --git a/providers/implementations/ciphers/cipher_seed.h b/providers/implementations/ciphers/cipher_seed.h index 50460d1fa7a4a..656b96284c5fe 100644 --- a/providers/implementations/ciphers/cipher_seed.h +++ b/providers/implementations/ciphers/cipher_seed.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_sm4.h b/providers/implementations/ciphers/cipher_sm4.h index e11ad45e1f6ee..19f16249c3346 100644 --- a/providers/implementations/ciphers/cipher_sm4.h +++ b/providers/implementations/ciphers/cipher_sm4.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_sm4_ccm.h b/providers/implementations/ciphers/cipher_sm4_ccm.h index 2409f862dea3b..8fa57ff488e8a 100644 --- a/providers/implementations/ciphers/cipher_sm4_ccm.h +++ b/providers/implementations/ciphers/cipher_sm4_ccm.h @@ -1,5 +1,5 @@ /* - * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_sm4_gcm.h b/providers/implementations/ciphers/cipher_sm4_gcm.h index cd38a75a65c81..669c4ad825d4f 100644 --- a/providers/implementations/ciphers/cipher_sm4_gcm.h +++ b/providers/implementations/ciphers/cipher_sm4_gcm.h @@ -1,5 +1,5 @@ /* - * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_sm4_hw.c b/providers/implementations/ciphers/cipher_sm4_hw.c index 2c9fdd9f0b3df..fdffd3ce3012d 100644 --- a/providers/implementations/ciphers/cipher_sm4_hw.c +++ b/providers/implementations/ciphers/cipher_sm4_hw.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_sm4_xts.h b/providers/implementations/ciphers/cipher_sm4_xts.h index 3693eaa4df354..5ab1b4d314cf3 100644 --- a/providers/implementations/ciphers/cipher_sm4_xts.h +++ b/providers/implementations/ciphers/cipher_sm4_xts.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/cipher_tdes.h b/providers/implementations/ciphers/cipher_tdes.h index d3c383506fa3f..7f04b86a23194 100644 --- a/providers/implementations/ciphers/cipher_tdes.h +++ b/providers/implementations/ciphers/cipher_tdes.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -65,7 +65,7 @@ typedef struct prov_tdes_ctx_st { { OSSL_FUNC_CIPHER_GET_PARAMS, \ (void (*)(void))tdes_##type##_##lcmode##_get_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ - (void (*)(void))ossl_cipher_generic_gettable_params }, \ + (void (*)(void))ossl_tdes_gettable_params }, \ { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ (void (*)(void))ossl_tdes_get_ctx_params }, \ { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ @@ -87,6 +87,7 @@ OSSL_FUNC_cipher_freectx_fn ossl_tdes_freectx; OSSL_FUNC_cipher_encrypt_init_fn ossl_tdes_einit; OSSL_FUNC_cipher_decrypt_init_fn ossl_tdes_dinit; OSSL_FUNC_cipher_get_ctx_params_fn ossl_tdes_get_ctx_params; +OSSL_FUNC_cipher_gettable_params_fn ossl_tdes_gettable_params; OSSL_FUNC_cipher_gettable_ctx_params_fn ossl_tdes_gettable_ctx_params; OSSL_FUNC_cipher_set_ctx_params_fn ossl_tdes_set_ctx_params; OSSL_FUNC_cipher_settable_ctx_params_fn ossl_tdes_settable_ctx_params; diff --git a/providers/implementations/ciphers/cipher_tdes.inc.in b/providers/implementations/ciphers/cipher_tdes.inc.in new file mode 100644 index 0000000000000..d4d884e47da54 --- /dev/null +++ b/providers/implementations/ciphers/cipher_tdes.inc.in @@ -0,0 +1,47 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::paramnames qw(produce_param_decoder); +-} + +{- produce_param_decoder('tdes_get_params', + (['OSSL_CIPHER_PARAM_MODE', 'common.mode', 'uint'], + ['OSSL_CIPHER_PARAM_KEYLEN', 'common.keylen', 'size_t'], + ['OSSL_CIPHER_PARAM_IVLEN', 'common.ivlen', 'size_t'], + ['OSSL_CIPHER_PARAM_BLOCK_SIZE', 'common.bsize', 'size_t'], + ['OSSL_CIPHER_PARAM_AEAD', 'common.aead', 'int' ], + ['OSSL_CIPHER_PARAM_CUSTOM_IV', 'common.custiv', 'int'], + ['OSSL_CIPHER_PARAM_CTS', 'common.cts', 'int' ], + ['OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK', 'common.mb', 'int' ], + ['OSSL_CIPHER_PARAM_HAS_RAND_KEY', 'common.rand', 'int'], + ['OSSL_CIPHER_PARAM_ENCRYPT_THEN_MAC', 'common.etm', 'int' ], + ['OSSL_CIPHER_PARAM_DECRYPT_ONLY', 'decrypt', 'int'], + )); -} + +{- produce_param_decoder('tdes_get_ctx_params', + (['OSSL_CIPHER_PARAM_KEYLEN', 'common.keylen', 'size_t'], + ['OSSL_CIPHER_PARAM_IVLEN', 'common.ivlen', 'size_t'], + ['OSSL_CIPHER_PARAM_PADDING', 'common.pad', 'uint'], + ['OSSL_CIPHER_PARAM_NUM', 'common.num', 'uint'], + ['OSSL_CIPHER_PARAM_IV', 'common.iv', 'octet_string'], + ['OSSL_CIPHER_PARAM_UPDATED_IV', 'common.updiv', 'octet_string'], + ['OSSL_CIPHER_PARAM_TLS_MAC', 'common.tlsmac', 'octet_ptr'], + ['OSSL_CIPHER_PARAM_RANDOM_KEY', 'rand', 'octet_string'], + ['OSSL_CIPHER_PARAM_FIPS_APPROVED_INDICATOR', 'ind', 'int', 'fips'], + )); -} + +{- produce_param_decoder('tdes_set_ctx_params', + (['OSSL_CIPHER_PARAM_PADDING', 'common.pad', 'uint'], + ['OSSL_CIPHER_PARAM_NUM', 'common.num', 'uint'], + ['OSSL_CIPHER_PARAM_USE_BITS', 'common.bits', 'uint'], + ['OSSL_CIPHER_PARAM_TLS_VERSION', 'common.tlsvers', 'uint'], + ['OSSL_CIPHER_PARAM_TLS_MAC_SIZE', 'common.tlsmacsize', 'size_t'], + ['OSSL_CIPHER_PARAM_FIPS_ENCRYPT_CHECK', 'ind', 'int', 'fips'], + )); -} diff --git a/providers/implementations/ciphers/cipher_tdes_common.c b/providers/implementations/ciphers/cipher_tdes_common.c index 20dc77f32c8be..765ed5b8e7a21 100644 --- a/providers/implementations/ciphers/cipher_tdes_common.c +++ b/providers/implementations/ciphers/cipher_tdes_common.c @@ -20,6 +20,32 @@ #include "prov/implementations.h" #include "prov/providercommon.h" +struct tdes_get_param_list_st { + struct ossl_cipher_get_param_list_st common; + OSSL_PARAM *decrypt; +}; + +struct tdes_get_ctx_param_list_st { + struct ossl_cipher_get_ctx_param_list_st common; + OSSL_PARAM *rand; +#ifdef FIPS_MODULE + OSSL_PARAM *ind; +#endif +}; + +struct tdes_set_ctx_param_list_st { + struct ossl_cipher_set_ctx_param_list_st common; +#ifdef FIPS_MODULE + OSSL_PARAM *ind; +#endif +}; + +#define tdes_get_params_st tdes_get_param_list_st +#define tdes_get_ctx_params_st tdes_get_ctx_param_list_st +#define tdes_set_ctx_params_st tdes_set_ctx_param_list_st + +#include "providers/implementations/ciphers/cipher_tdes.inc" + void *ossl_tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits, size_t ivbits, uint64_t flags, const PROV_CIPHER_HW *hw) { @@ -130,12 +156,7 @@ int ossl_tdes_dinit(void *vctx, const unsigned char *key, size_t keylen, return tdes_init(vctx, key, keylen, iv, ivlen, params, 0); } -CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(ossl_tdes) -OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, NULL, 0), - OSSL_FIPS_IND_GETTABLE_CTX_PARAM() - CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(ossl_tdes) - - static int tdes_generatekey(PROV_CIPHER_CTX *ctx, void *ptr) +static int tdes_generatekey(PROV_CIPHER_CTX *ctx, void *ptr) { DES_cblock *deskey = ptr; size_t kl = ctx->keylen; @@ -151,35 +172,54 @@ OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_RANDOM_KEY, NULL, 0), return 1; } +const OSSL_PARAM *ossl_tdes_gettable_ctx_params(ossl_unused void *cctx, + ossl_unused void *provctx) +{ + return tdes_get_ctx_params_list; +} + int ossl_tdes_get_ctx_params(void *vctx, OSSL_PARAM params[]) { PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; - OSSL_PARAM *p; + struct tdes_get_ctx_param_list_st p; - if (!ossl_cipher_generic_get_ctx_params(vctx, params)) + if (ctx == NULL || !tdes_get_ctx_params_decoder(params, &p)) return 0; - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RANDOM_KEY); - if (p != NULL && !tdes_generatekey(ctx, p->data)) { + if (!ossl_cipher_common_get_ctx_params(ctx, &p.common)) + return 0; + + if (p.rand != NULL && !tdes_generatekey(ctx, p.rand->data)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY); return 0; } - if (!OSSL_FIPS_IND_GET_CTX_PARAM((PROV_TDES_CTX *)vctx, params)) + if (!OSSL_FIPS_IND_GET_CTX_FROM_PARAM((PROV_TDES_CTX *)vctx, p.ind)) return 0; return 1; } -CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(ossl_tdes) -OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_CIPHER_PARAM_FIPS_ENCRYPT_CHECK) -CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(ossl_tdes) +const OSSL_PARAM *ossl_tdes_settable_ctx_params(ossl_unused void *cctx, + ossl_unused void *provctx) +{ + return tdes_set_ctx_params_list; +} int ossl_tdes_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { - if (!OSSL_FIPS_IND_SET_CTX_PARAM((PROV_TDES_CTX *)vctx, - OSSL_FIPS_IND_SETTABLE0, params, - OSSL_CIPHER_PARAM_FIPS_ENCRYPT_CHECK)) + PROV_TDES_CTX *ctx = (PROV_TDES_CTX *)vctx; + struct tdes_set_ctx_param_list_st p; + + if (ctx == NULL || !tdes_set_ctx_params_decoder(params, &p)) + return 0; + if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, p.ind)) return 0; - return ossl_cipher_generic_set_ctx_params(vctx, params); + + return ossl_cipher_common_set_ctx_params(&ctx->base, &p.common); +} + +const OSSL_PARAM *ossl_tdes_gettable_params(ossl_unused void *provctx) +{ + return tdes_get_params_list; } int ossl_tdes_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags, @@ -190,14 +230,16 @@ int ossl_tdes_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags, #else const int decrypt_only = 0; #endif - OSSL_PARAM *p; + struct tdes_get_param_list_st p; + + if (!tdes_get_params_decoder(params, &p)) + return 0; - p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_DECRYPT_ONLY); - if (p != NULL && !OSSL_PARAM_set_int(p, decrypt_only)) { + if (p.decrypt != NULL && !OSSL_PARAM_set_int(p.decrypt, decrypt_only)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } - return ossl_cipher_generic_get_params(params, md, flags, - kbits, blkbits, ivbits); + return ossl_cipher_common_get_params(&p.common, md, flags, kbits, blkbits, + ivbits); } diff --git a/providers/implementations/ciphers/cipher_tdes_default.h b/providers/implementations/ciphers/cipher_tdes_default.h index adc3af7b3b481..66e549fd78953 100644 --- a/providers/implementations/ciphers/cipher_tdes_default.h +++ b/providers/implementations/ciphers/cipher_tdes_default.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/ciphercommon.c b/providers/implementations/ciphers/ciphercommon.c index a6320d2d81619..889f7cb4174d4 100644 --- a/providers/implementations/ciphers/ciphercommon.c +++ b/providers/implementations/ciphers/ciphercommon.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -22,6 +22,7 @@ #include "internal/e_os.h" #include "crypto/types.h" +#define ossl_cipher_generic_get_params_st ossl_cipher_get_param_list_st #define cipher_generic_get_ctx_params_st ossl_cipher_get_ctx_param_list_st #define cipher_generic_set_ctx_params_st ossl_cipher_set_ctx_param_list_st #define cipher_var_keylen_set_ctx_params_st ossl_cipher_set_ctx_param_list_st @@ -41,54 +42,69 @@ int ossl_cipher_generic_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags, size_t kbits, size_t blkbits, size_t ivbits) { - struct ossl_cipher_generic_get_params_st p; + struct ossl_cipher_get_param_list_st p; if (!ossl_cipher_generic_get_params_decoder(params, &p)) return 0; - if (p.mode != NULL && !OSSL_PARAM_set_uint(p.mode, md)) { + return ossl_cipher_common_get_params(&p, md, flags, kbits, blkbits, + ivbits); +} + +int ossl_cipher_common_get_params(const struct ossl_cipher_get_param_list_st *p, + unsigned int md, uint64_t flags, size_t kbits, size_t blkbits, + size_t ivbits) +{ + if (p->mode != NULL && !OSSL_PARAM_set_uint(p->mode, md)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } - if (p.aead != NULL - && !OSSL_PARAM_set_int(p.aead, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) { + if (p->aead != NULL + && !OSSL_PARAM_set_int(p->aead, (flags & PROV_CIPHER_FLAG_AEAD) != 0)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } - if (p.custiv != NULL - && !OSSL_PARAM_set_int(p.custiv, (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) { + if (p->custiv != NULL + && !OSSL_PARAM_set_int(p->custiv, + (flags & PROV_CIPHER_FLAG_CUSTOM_IV) != 0)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } - if (p.cts != NULL - && !OSSL_PARAM_set_int(p.cts, (flags & PROV_CIPHER_FLAG_CTS) != 0)) { + if (p->cts != NULL + && !OSSL_PARAM_set_int(p->cts, (flags & PROV_CIPHER_FLAG_CTS) != 0)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } - if (p.mb != NULL - && !OSSL_PARAM_set_int(p.mb, (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != 0)) { + if (p->mb != NULL + && !OSSL_PARAM_set_int(p->mb, + (flags & PROV_CIPHER_FLAG_TLS1_MULTIBLOCK) != 0)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } - if (p.rand != NULL - && !OSSL_PARAM_set_int(p.rand, (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) { + if (p->rand != NULL + && !OSSL_PARAM_set_int(p->rand, + (flags & PROV_CIPHER_FLAG_RAND_KEY) != 0)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } - if (p.etm != NULL - && !OSSL_PARAM_set_int(p.etm, (flags & EVP_CIPH_FLAG_ENC_THEN_MAC) != 0)) { + if (p->etm != NULL + && !OSSL_PARAM_set_int(p->etm, + (flags & EVP_CIPH_FLAG_ENC_THEN_MAC) != 0)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } - if (p.keylen != NULL && !OSSL_PARAM_set_size_t(p.keylen, kbits / 8)) { + if (p->keylen != NULL + && !OSSL_PARAM_set_size_t(p->keylen, kbits / 8)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } - if (p.bsize != NULL && !OSSL_PARAM_set_size_t(p.bsize, blkbits / 8)) { + if (p->bsize != NULL + && !OSSL_PARAM_set_size_t(p->bsize, blkbits / 8)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } - if (p.ivlen != NULL && !OSSL_PARAM_set_size_t(p.ivlen, ivbits / 8)) { + if (p->ivlen != NULL + && !OSSL_PARAM_set_size_t(p->ivlen, ivbits / 8)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } @@ -119,24 +135,9 @@ int ossl_cipher_var_keylen_set_ctx_params(void *vctx, const OSSL_PARAM params[]) PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx; struct ossl_cipher_set_ctx_param_list_st p; - if (ctx == NULL - || !cipher_var_keylen_set_ctx_params_decoder(params, &p) - || !ossl_cipher_common_set_ctx_params(ctx, &p)) + if (ctx == NULL || !cipher_var_keylen_set_ctx_params_decoder(params, &p)) return 0; - - if (p.keylen != NULL) { - size_t keylen; - - if (!OSSL_PARAM_get_size_t(p.keylen, &keylen)) { - ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); - return 0; - } - if (ctx->keylen != keylen) { - ctx->keylen = keylen; - ctx->key_set = 0; - } - } - return 1; + return ossl_cipher_common_set_ctx_params(ctx, &p); } void ossl_cipher_generic_reset_ctx(PROV_CIPHER_CTX *ctx) @@ -148,6 +149,25 @@ void ossl_cipher_generic_reset_ctx(PROV_CIPHER_CTX *ctx) } } +/* + * Deep-copy the tlsmac buffer after a shallow dupctx copy. + * Must be called after OPENSSL_memdup or *dctx = *sctx to avoid + * double-free when both contexts are freed. + * Returns 1 on success, 0 on allocation failure. + */ +int ossl_cipher_generic_dupctx_tlsmac(PROV_CIPHER_CTX *dst, + const PROV_CIPHER_CTX *src) +{ + if (src->tlsmac != NULL && src->alloced) { + dst->tlsmac = OPENSSL_memdup(src->tlsmac, src->tlsmacsize); + if (dst->tlsmac == NULL) { + dst->alloced = 0; + return 0; + } + } + return 1; +} + static int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx, const unsigned char *key, size_t keylen, const unsigned char *iv, size_t ivlen, @@ -650,6 +670,19 @@ int ossl_cipher_common_set_ctx_params(PROV_CIPHER_CTX *ctx, const struct ossl_ci } ctx->num = num; } + + if (p->keylen != NULL) { + size_t keylen; + + if (!OSSL_PARAM_get_size_t(p->keylen, &keylen)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); + return 0; + } + if (ctx->keylen != keylen) { + ctx->keylen = keylen; + ctx->key_set = 0; + } + } return 1; } diff --git a/providers/implementations/ciphers/ciphercommon.inc.in b/providers/implementations/ciphers/ciphercommon.inc.in index 997453d24befa..1492e03a19c3d 100644 --- a/providers/implementations/ciphers/ciphercommon.inc.in +++ b/providers/implementations/ciphers/ciphercommon.inc.in @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the \"License\"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -31,7 +31,7 @@ use OpenSSL::paramnames qw(produce_param_decoder); ['OSSL_CIPHER_PARAM_NUM', 'num', 'uint' ], ['OSSL_CIPHER_PARAM_IV', 'iv', 'octet_string' ], ['OSSL_CIPHER_PARAM_UPDATED_IV', 'updiv', 'octet_string' ], - ['OSSL_CIPHER_PARAM_TLS_MAC', 'tlsmac', 'octet_string' ], + ['OSSL_CIPHER_PARAM_TLS_MAC', 'tlsmac', 'octet_ptr' ], )); -} {- produce_param_decoder('cipher_generic_set_ctx_params', diff --git a/providers/implementations/ciphers/ciphercommon_block.c b/providers/implementations/ciphers/ciphercommon_block.c index 8ce491ddcaed7..9c44c332f088b 100644 --- a/providers/implementations/ciphers/ciphercommon_block.c +++ b/providers/implementations/ciphers/ciphercommon_block.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/ciphers/ciphercommon_ccm.c b/providers/implementations/ciphers/ciphercommon_ccm.c index 79a61fde8ade4..70e16aee0a82c 100644 --- a/providers/implementations/ciphers/ciphercommon_ccm.c +++ b/providers/implementations/ciphers/ciphercommon_ccm.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -286,13 +286,19 @@ int ossl_ccm_stream_final(void *vctx, unsigned char *out, size_t *outl, size_t outsize) { PROV_CCM_CTX *ctx = (PROV_CCM_CTX *)vctx; - int i; + unsigned char dummy_in = 0, dummy_out = 0; if (!ossl_prov_is_running()) return 0; - i = ccm_cipher_internal(ctx, out, outl, NULL, 0); - if (i <= 0) + /* + * Encryption sets tag_set after processing the payload, while successful + * decryption clears iv_set. Use those transitions to avoid processing an + * operation twice. + */ + if (!ctx->key_set + || (ctx->iv_set && (!ctx->enc || !ctx->tag_set) + && ccm_cipher_internal(ctx, &dummy_out, outl, &dummy_in, 0) <= 0)) return 0; *outl = 0; @@ -307,6 +313,9 @@ int ossl_ccm_cipher(void *vctx, unsigned char *out, size_t *outl, size_t outsize if (!ossl_prov_is_running()) return 0; + if (in == NULL) + return ossl_ccm_stream_final(vctx, out, outl, outsize); + if (outsize < inl) { ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); return 0; diff --git a/providers/implementations/ciphers/ciphercommon_gcm.c b/providers/implementations/ciphers/ciphercommon_gcm.c index c93b0767b0659..f8a027f701f46 100644 --- a/providers/implementations/ciphers/ciphercommon_gcm.c +++ b/providers/implementations/ciphers/ciphercommon_gcm.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -213,14 +213,19 @@ int ossl_gcm_get_ctx_params(void *vctx, OSSL_PARAM params[]) } if (p.tag != NULL) { - sz = p.tag->data_size; if (!ctx->enc || ctx->taglen == UNINITIALISED_SIZET) { ERR_raise(ERR_LIB_PROV, PROV_R_TAG_NOT_SET); return 0; } - if (p.tag->data != NULL && (sz > EVP_GCM_TLS_TAG_LEN || sz == 0)) { - ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG); - return 0; + if (p.tag->data == NULL) { + /* size query: report the tag length, as for the iv above */ + sz = ctx->taglen; + } else { + sz = p.tag->data_size; + if (sz > EVP_GCM_TLS_TAG_LEN || sz == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_TAG); + return 0; + } } if (!OSSL_PARAM_set_octet_string(p.tag, ctx->buf, sz)) { @@ -470,8 +475,11 @@ static int gcm_cipher_internal(PROV_GCM_CTX *ctx, unsigned char *out, ERR_raise(ERR_LIB_PROV, PROV_R_TAG_NOT_SET); goto err; } - if (!hw->cipherfinal(ctx, ctx->buf)) + if (hw->cipherfinal(ctx, ctx->buf) == 0) { + if (ctx->enc == 0) + ERR_raise(ERR_LIB_PROV, PROV_R_BAD_DECRYPT); goto err; + } ctx->iv_state = IV_STATE_FINISHED; /* Don't reuse the IV */ goto finish; } @@ -525,8 +533,9 @@ static int gcm_tls_iv_set_fixed(PROV_GCM_CTX *ctx, unsigned char *iv, return 1; } /* Fixed field must be at least 4 bytes and invocation field at least 8 */ - if ((len < EVP_GCM_TLS_FIXED_IV_LEN) - || (ctx->ivlen - (int)len) < EVP_GCM_TLS_EXPLICIT_IV_LEN) + if (len < EVP_GCM_TLS_FIXED_IV_LEN + || len > ctx->ivlen + || (ctx->ivlen - len) < EVP_GCM_TLS_EXPLICIT_IV_LEN) return 0; if (len > 0) memcpy(ctx->iv, iv, len); diff --git a/providers/implementations/ciphers/ciphercommon_local.h b/providers/implementations/ciphers/ciphercommon_local.h index 05ada2dd17ab8..ff84d65681e09 100644 --- a/providers/implementations/ciphers/ciphercommon_local.h +++ b/providers/implementations/ciphers/ciphercommon_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/digests/blake2_impl.h b/providers/implementations/digests/blake2_impl.h index 389f2473a620c..c8ff2efe0505f 100644 --- a/providers/implementations/digests/blake2_impl.h +++ b/providers/implementations/digests/blake2_impl.h @@ -1,5 +1,5 @@ /* - * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/digests/ml_dsa_mu_prov.c b/providers/implementations/digests/ml_dsa_mu_prov.c index e2857c056d299..0f1866ed0cfc7 100644 --- a/providers/implementations/digests/ml_dsa_mu_prov.c +++ b/providers/implementations/digests/ml_dsa_mu_prov.c @@ -83,7 +83,7 @@ static void mu_freectx(void *vctx) OPENSSL_free(ctx->propq); EVP_MD_free(ctx->md); EVP_MD_CTX_free(ctx->mdctx); - OPENSSL_free(ctx); + OPENSSL_clear_free(ctx, sizeof(*ctx)); } static void *mu_dupctx(void *ctx) diff --git a/providers/implementations/encode_decode/build.info b/providers/implementations/encode_decode/build.info index 2347ef865f3c8..08e301de17842 100644 --- a/providers/implementations/encode_decode/build.info +++ b/providers/implementations/encode_decode/build.info @@ -34,3 +34,11 @@ ENDIF IF[{- !$disabled{'ml-dsa'} || !$disabled{'ml-kem'} -}] SOURCE[$DECODER_GOAL]=ml_common_codecs.c ENDIF + +IF[{- !$disabled{'ml-dsa'} -}] + SOURCE[$DECODER_GOAL]=composite_codecs.c + DEPEND[composite_codecs.o]=../../common/include/prov/composite.h + DEPEND[decode_der2key.o]=../../common/include/prov/composite.h + DEPEND[encode_key2any.o]=../../common/include/prov/composite.h + DEPEND[encode_key2text.o]=../../common/include/prov/composite.h +ENDIF diff --git a/providers/implementations/encode_decode/composite_codecs.c b/providers/implementations/encode_decode/composite_codecs.c new file mode 100644 index 0000000000000..ac2545f2c7cce --- /dev/null +++ b/providers/implementations/encode_decode/composite_codecs.c @@ -0,0 +1,487 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include "crypto/ml_dsa.h" +#include "prov/composite_codecs.h" +#include "prov/ml_dsa_codecs.h" +#include "prov/provider_ctx.h" + +#ifndef OPENSSL_NO_COMPOSITE + +/* + * Encode the classic sub-key public component to its raw wire format + * (draft-ietf-lamps-pq-composite-sigs): + * + * RSA: RSAPublicKey DER (PKCS#1) + * EC: Uncompressed X9.62 point 0x04||x||y + * Ed25519: raw 32 bytes + * Ed448: raw 57 bytes + * + * On success, *out is a newly-allocated buffer of *out_len bytes. + * Caller must OPENSSL_free(*out). + */ +static int composite_encode_classic_pub(const EVP_PKEY *pkey, + unsigned char **out, + size_t *out_len) +{ + int keytype = EVP_PKEY_get_base_id(pkey); + OSSL_ENCODER_CTX *ectx; + size_t len; + + *out = NULL; + *out_len = 0; + + if (keytype == EVP_PKEY_RSA) { + ectx = OSSL_ENCODER_CTX_new_for_pkey( + pkey, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, + "DER", "type-specific", NULL); + if (ectx == NULL) + return 0; + if (!OSSL_ENCODER_to_data(ectx, out, out_len)) + *out = NULL; + OSSL_ENCODER_CTX_free(ectx); + } else if (keytype == EVP_PKEY_EC) { + /* Uncompressed point: 0x04 || x || y */ + if (!EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, + NULL, 0, &len)) + return 0; + *out = OPENSSL_malloc(len); + if (*out == NULL) + return 0; + if (!EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, + *out, len, out_len)) { + OPENSSL_free(*out); + *out = NULL; + } + } else if (keytype == EVP_PKEY_ED25519 || keytype == EVP_PKEY_ED448) { + if (!EVP_PKEY_get_raw_public_key(pkey, NULL, &len)) + return 0; + *out = OPENSSL_malloc(len); + if (*out == NULL) + return 0; + if (!EVP_PKEY_get_raw_public_key(pkey, *out, &len)) { + OPENSSL_free(*out); + *out = NULL; + } else { + *out_len = len; + } + } else { + ERR_raise_data(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED, + "unsupported classic key type %d", keytype); + return 0; + } + + return *out != NULL; +} + +/* + * Encode the classic sub-key private component to its raw wire format: + * + * RSA: RSAPrivateKey DER (PKCS#1) + * EC: ECPrivateKey DER with NamedCurve (RFC5915) + * Ed25519: raw 32 bytes + * Ed448: raw 57 bytes + * + * On success, *out is a newly-allocated buffer of *out_len bytes. + * Caller must OPENSSL_clear_free(*out, *out_len). + */ +static int composite_encode_classic_priv(const EVP_PKEY *pkey, + unsigned char **out, + size_t *out_len) +{ + int keytype = EVP_PKEY_get_base_id(pkey); + OSSL_ENCODER_CTX *ectx; + size_t len; + + *out = NULL; + *out_len = 0; + + if (keytype == EVP_PKEY_RSA) { + ectx = OSSL_ENCODER_CTX_new_for_pkey( + pkey, OSSL_KEYMGMT_SELECT_PRIVATE_KEY, + "DER", "type-specific", NULL); + if (ectx == NULL) + return 0; + if (!OSSL_ENCODER_to_data(ectx, out, out_len)) + *out = NULL; + OSSL_ENCODER_CTX_free(ectx); + } else if (keytype == EVP_PKEY_EC) { + /* + * ECPrivateKey DER (RFC5915) with NamedCurve but WITHOUT publicKey, + * per composite draft section 4: + * "The private key MUST be encoded as ECPrivateKey specified in + * [RFC5915] with the 'NamedCurve' parameter set to the OID of + * the curve, but without the 'publicKey' field." + */ + int include_pub = 0; + OSSL_PARAM params[] = { + OSSL_PARAM_construct_int(OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, + &include_pub), + OSSL_PARAM_construct_end() + }; + EVP_PKEY *ec_copy = EVP_PKEY_dup((EVP_PKEY *)pkey); + + if (ec_copy == NULL) + return 0; + if (!EVP_PKEY_set_params(ec_copy, params)) { + EVP_PKEY_free(ec_copy); + return 0; + } + ectx = OSSL_ENCODER_CTX_new_for_pkey( + ec_copy, OSSL_KEYMGMT_SELECT_PRIVATE_KEY, + "DER", "type-specific", NULL); + if (ectx != NULL) { + if (!OSSL_ENCODER_to_data(ectx, out, out_len)) + *out = NULL; + OSSL_ENCODER_CTX_free(ectx); + } + EVP_PKEY_free(ec_copy); + } else if (keytype == EVP_PKEY_ED25519 || keytype == EVP_PKEY_ED448) { + if (!EVP_PKEY_get_raw_private_key(pkey, NULL, &len)) + return 0; + *out = OPENSSL_malloc(len); + if (*out == NULL) + return 0; + if (!EVP_PKEY_get_raw_private_key(pkey, *out, &len)) { + OPENSSL_clear_free(*out, len); + *out = NULL; + } else { + *out_len = len; + } + } else { + ERR_raise_data(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED, + "unsupported classic key type %d", keytype); + return 0; + } + + return *out != NULL; +} + +/* + * Encode the composite public key: mldsaPK || tradPK + * Returns total byte length (>0) on success, 0 on error. + * If |out| is NULL, only the length is computed (no allocation). + */ +int ossl_composite_i2d_pubkey(const COMPOSITE_KEY *key, unsigned char **out) +{ + const ML_DSA_PARAMS *kp; + const uint8_t *ml_dsa_pub; + unsigned char *classic_pub = NULL; + size_t classic_pub_len = 0; + int total, ret = 0; + + if (key == NULL || key->classic_key == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); + return 0; + } + + kp = ossl_ml_dsa_key_params(key->ml_dsa_key); + ml_dsa_pub = ossl_ml_dsa_key_get_pub(key->ml_dsa_key); + if (ml_dsa_pub == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); + return 0; + } + + if (!composite_encode_classic_pub(key->classic_key, + &classic_pub, &classic_pub_len)) + return 0; + + total = (int)(kp->pk_len + classic_pub_len); + + if (out != NULL) { + *out = OPENSSL_malloc((size_t)total); + if (*out == NULL) + goto done; + memcpy(*out, ml_dsa_pub, kp->pk_len); + memcpy(*out + kp->pk_len, classic_pub, classic_pub_len); + } + + ret = total; +done: + OPENSSL_free(classic_pub); + return ret; +} + +/* + * Encode the composite private key: mldsaSeed[32] || tradSK + * Returns total byte length (>0) on success, 0 on error. + * If |out| is NULL, only the length is computed (no allocation). + */ +int ossl_composite_i2d_prvkey(const COMPOSITE_KEY *key, unsigned char **out) +{ + const uint8_t *seed; + unsigned char *classic_priv = NULL; + size_t classic_priv_len = 0; + int total, ret = 0; + + if (key == NULL || key->classic_key == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); + return 0; + } + + seed = ossl_ml_dsa_key_get_seed(key->ml_dsa_key); + if (seed == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); + return 0; + } + + if (!composite_encode_classic_priv(key->classic_key, + &classic_priv, &classic_priv_len)) + return 0; + + total = (int)(ML_DSA_SEED_BYTES + classic_priv_len); + + if (out != NULL) { + *out = OPENSSL_malloc((size_t)total); + if (*out == NULL) + goto done; + memcpy(*out, seed, ML_DSA_SEED_BYTES); + memcpy(*out + ML_DSA_SEED_BYTES, classic_priv, classic_priv_len); + } + + ret = total; +done: + OPENSSL_clear_free(classic_priv, classic_priv_len); + return ret; +} + +/* + * Print a human-readable description of a composite key to |out|. + */ +int ossl_composite_key_to_text(BIO *out, const COMPOSITE_KEY *key, + int selection) +{ + const ML_DSA_PARAMS *kp; + int is_priv = (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0; + int ret = 0; + + if (out == NULL || key == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + kp = ossl_ml_dsa_key_params(key->ml_dsa_key); + + if (BIO_printf(out, "Composite %s Key (%s)\n", + is_priv ? "Private" : "Public", + kp != NULL ? kp->alg : "unknown") + <= 0) + return 0; + + /* ML-DSA component */ + if (BIO_printf(out, "ML-DSA component:\n") <= 0) + return 0; + if (!ossl_ml_dsa_key_to_text(out, key->ml_dsa_key, selection)) + return 0; + + /* Classic component */ + if (BIO_printf(out, "Classic component:\n") <= 0) + return 0; + if (key->classic_key == NULL) { + if (BIO_printf(out, " (none)\n") <= 0) + return 0; + } else { + if (is_priv) + ret = EVP_PKEY_print_private(out, key->classic_key, 4, NULL); + else + ret = EVP_PKEY_print_public(out, key->classic_key, 4, NULL); + if (ret <= 0) + return 0; + } + + return 1; +} + +/* + * Decode the classic sub-key from its raw wire format. + * Used by ossl_composite_d2i_pubkey() and ossl_composite_d2i_prvkey(). + */ +static EVP_PKEY *composite_codecs_decode_classic_pub(OSSL_LIB_CTX *libctx, + const char *classic_alg, + const char *ec_curve, + const unsigned char *buf, + size_t buf_len) +{ + EVP_PKEY *pkey = NULL; + const unsigned char *ptr = buf; + size_t ptrlen = buf_len; + OSSL_DECODER_CTX *dctx; + OSSL_PARAM params[3]; + EVP_PKEY_CTX *pctx; + + if (strcmp(classic_alg, "RSA") == 0) { + dctx = OSSL_DECODER_CTX_new_for_pkey( + &pkey, "DER", "type-specific", "RSA", + OSSL_KEYMGMT_SELECT_PUBLIC_KEY, libctx, NULL); + if (dctx == NULL) + return NULL; + if (!OSSL_DECODER_from_data(dctx, &ptr, &ptrlen)) + pkey = NULL; + OSSL_DECODER_CTX_free(dctx); + } else if (strcmp(classic_alg, "EC") == 0) { + params[0] = OSSL_PARAM_construct_utf8_string( + OSSL_PKEY_PARAM_GROUP_NAME, (char *)ec_curve, 0); + params[1] = OSSL_PARAM_construct_octet_string( + OSSL_PKEY_PARAM_PUB_KEY, (void *)buf, buf_len); + params[2] = OSSL_PARAM_construct_end(); + pctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", NULL); + if (pctx == NULL) + return NULL; + if (EVP_PKEY_fromdata_init(pctx) <= 0 + || EVP_PKEY_fromdata(pctx, &pkey, + EVP_PKEY_PUBLIC_KEY, params) + <= 0) + pkey = NULL; + EVP_PKEY_CTX_free(pctx); + } else if (strcmp(classic_alg, "ED25519") == 0) { + pkey = EVP_PKEY_new_raw_public_key_ex(libctx, "ED25519", NULL, + buf, buf_len); + } else if (strcmp(classic_alg, "ED448") == 0) { + pkey = EVP_PKEY_new_raw_public_key_ex(libctx, "ED448", NULL, + buf, buf_len); + } + return pkey; +} + +static EVP_PKEY *composite_codecs_decode_classic_priv(OSSL_LIB_CTX *libctx, + const char *classic_alg, + const char *ec_curve, + const unsigned char *buf, + size_t buf_len) +{ + EVP_PKEY *pkey = NULL; + const unsigned char *ptr = buf; + size_t ptrlen = buf_len; + OSSL_DECODER_CTX *dctx; + + if (strcmp(classic_alg, "RSA") == 0) { + dctx = OSSL_DECODER_CTX_new_for_pkey( + &pkey, "DER", "type-specific", "RSA", + OSSL_KEYMGMT_SELECT_PRIVATE_KEY, libctx, NULL); + if (dctx == NULL) + return NULL; + if (!OSSL_DECODER_from_data(dctx, &ptr, &ptrlen)) + pkey = NULL; + OSSL_DECODER_CTX_free(dctx); + } else if (strcmp(classic_alg, "EC") == 0) { + dctx = OSSL_DECODER_CTX_new_for_pkey( + &pkey, "DER", "type-specific", "EC", + OSSL_KEYMGMT_SELECT_PRIVATE_KEY, libctx, NULL); + if (dctx == NULL) + return NULL; + if (!OSSL_DECODER_from_data(dctx, &ptr, &ptrlen)) + pkey = NULL; + OSSL_DECODER_CTX_free(dctx); + } else if (strcmp(classic_alg, "ED25519") == 0) { + pkey = EVP_PKEY_new_raw_private_key_ex(libctx, "ED25519", NULL, + buf, buf_len); + } else if (strcmp(classic_alg, "ED448") == 0) { + pkey = EVP_PKEY_new_raw_private_key_ex(libctx, "ED448", NULL, + buf, buf_len); + } + return pkey; +} + +COMPOSITE_KEY *ossl_composite_d2i_pubkey(const unsigned char *pk, + int pk_len, + int ml_dsa_evp_type, + const char *classic_alg, + const char *ec_curve, + PROV_CTX *provctx, + const char *propq) +{ + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); + const ML_DSA_PARAMS *kp; + COMPOSITE_KEY *key; + size_t ml_dsa_len; + + if (pk == NULL || pk_len <= 0 || classic_alg == NULL) + return NULL; + + key = ossl_prov_composite_new(provctx, propq, ml_dsa_evp_type); + if (key == NULL) + return NULL; + + kp = ossl_ml_dsa_key_params(key->ml_dsa_key); + if (kp == NULL) + goto err; + + ml_dsa_len = kp->pk_len; + if ((size_t)pk_len <= ml_dsa_len) + goto err; + + if (!ossl_ml_dsa_pk_decode(key->ml_dsa_key, pk, ml_dsa_len)) { + ERR_raise(ERR_LIB_PROV, PROV_R_BAD_ENCODING); + goto err; + } + + key->classic_key = composite_codecs_decode_classic_pub( + libctx, classic_alg, ec_curve, + pk + ml_dsa_len, (size_t)pk_len - ml_dsa_len); + if (key->classic_key == NULL) + goto err; + + return key; + +err: + ossl_composite_key_free(key); + return NULL; +} + +COMPOSITE_KEY *ossl_composite_d2i_prvkey(const unsigned char *priv, + int priv_len, + int ml_dsa_evp_type, + const char *classic_alg, + const char *ec_curve, + PROV_CTX *provctx, + const char *propq) +{ + OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); + COMPOSITE_KEY *key; + + if (priv == NULL || priv_len <= ML_DSA_SEED_BYTES || classic_alg == NULL) + return NULL; + + key = ossl_prov_composite_new(provctx, propq, ml_dsa_evp_type); + if (key == NULL) + return NULL; + + /* Load the 32-byte seed and derive the full ML-DSA key pair */ + if (!ossl_ml_dsa_set_prekey(key->ml_dsa_key, 0, 0, + priv, ML_DSA_SEED_BYTES, NULL, 0)) { + ERR_raise(ERR_LIB_PROV, PROV_R_BAD_ENCODING); + goto err; + } + if (!ossl_ml_dsa_generate_key(key->ml_dsa_key)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY); + goto err; + } + + key->classic_key = composite_codecs_decode_classic_priv( + libctx, classic_alg, ec_curve, + priv + ML_DSA_SEED_BYTES, + (size_t)priv_len - ML_DSA_SEED_BYTES); + if (key->classic_key == NULL) + goto err; + + return key; + +err: + ossl_composite_key_free(key); + return NULL; +} + +#endif /* OPENSSL_NO_COMPOSITE */ diff --git a/providers/implementations/encode_decode/decode_der2key.c b/providers/implementations/encode_decode/decode_der2key.c index 6ed99e68fa5c7..98d05811eaac1 100644 --- a/providers/implementations/encode_decode/decode_der2key.c +++ b/providers/implementations/encode_decode/decode_der2key.c @@ -45,6 +45,7 @@ #include "prov/ml_dsa_codecs.h" #include "prov/ml_kem_codecs.h" #include "prov/lms_codecs.h" +#include "prov/composite_codecs.h" #include "providers/implementations/encode_decode/decode_der2key.inc" #ifndef OPENSSL_NO_SLH_DSA @@ -1042,6 +1043,332 @@ static ossl_inline void *ml_dsa_d2i_PUBKEY(const uint8_t **der, long der_len, /* ---------------------------------------------------------------------- */ +#ifndef OPENSSL_NO_COMPOSITE +/* + * Composite SPKI/PKCS8 decoder helpers. + * The d2i_PUBKEY callback receives the full SubjectPublicKeyInfo DER. + * The d2i_PKCS8 callback receives the full PrivateKeyInfo DER. + */ + +/* + * Parse SubjectPublicKeyInfo by hand to extract the BIT STRING body + * (mldsaPK || tradPK) without calling d2i_X509_PUBKEY (which would + * re-enter the OSSL_DECODER chain and recurse infinitely). + * + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING + * } + * + * On success returns a pointer into |der| at the start of the BIT STRING + * payload and sets |*out_len|. Returns NULL on parse failure. + */ +static const unsigned char * +composite_spki_bitstring_body(const unsigned char *der, long der_len, + int *out_len) +{ + const unsigned char *p = der; + long outer_len, algo_len, bs_len; + int tag, xclass, inf; + + /* Outer SEQUENCE */ + inf = ASN1_get_object(&p, &outer_len, &tag, &xclass, der_len); + if ((inf & 0x80) || tag != V_ASN1_SEQUENCE || (size_t)(p + outer_len) > (size_t)(der + der_len)) + return NULL; + + /* AlgorithmIdentifier (SEQUENCE) — skip it */ + { + const unsigned char *save = p; + inf = ASN1_get_object(&p, &algo_len, &tag, &xclass, outer_len); + if ((inf & 0x80) || tag != V_ASN1_SEQUENCE) + return NULL; + p += algo_len; /* skip AlgorithmIdentifier body */ + outer_len -= (long)(p - save); + } + + /* BIT STRING */ + inf = ASN1_get_object(&p, &bs_len, &tag, &xclass, outer_len); + if ((inf & 0x80) || tag != V_ASN1_BIT_STRING || bs_len < 1) + return NULL; + + /* First byte is the unused-bits count; payload starts at p+1 */ + *out_len = (int)(bs_len - 1); + return p + 1; +} + +static COMPOSITE_KEY * +composite_d2i_pubkey_common(const unsigned char *der, long der_len, + int ml_dsa_evp_type, + const char *classic_alg, const char *ec_curve, + struct der2key_ctx_st *ctx) +{ + const unsigned char *pk; + const unsigned char *p = der; + long outer_len, algo_len; + int tag, xclass, inf, pk_len; + ASN1_OBJECT *oid = NULL; + + /* + * Peek at the AlgorithmIdentifier OID to reject structures that don't + * belong to this composite variant, without calling d2i_X509_PUBKEY + * (which would re-enter the OSSL_DECODER chain and recurse infinitely). + */ + + /* Outer SEQUENCE */ + inf = ASN1_get_object(&p, &outer_len, &tag, &xclass, der_len); + if ((inf & 0x80) || tag != V_ASN1_SEQUENCE) + return NULL; + + /* AlgorithmIdentifier SEQUENCE header */ + inf = ASN1_get_object(&p, &algo_len, &tag, &xclass, outer_len); + if ((inf & 0x80) || tag != V_ASN1_SEQUENCE || algo_len <= 0) + return NULL; + + /* OID inside AlgorithmIdentifier */ + oid = d2i_ASN1_OBJECT(NULL, &p, algo_len); + if (oid == NULL) + return NULL; + if (OBJ_obj2nid(oid) != ctx->desc->evp_type) { + ASN1_OBJECT_free(oid); + return NULL; + } + ASN1_OBJECT_free(oid); + + pk = composite_spki_bitstring_body(der, der_len, &pk_len); + if (pk == NULL) + return NULL; + + return ossl_composite_d2i_pubkey(pk, pk_len, ml_dsa_evp_type, + classic_alg, ec_curve, + ctx->provctx, ctx->propq); +} + +static COMPOSITE_KEY * +composite_d2i_prvkey_common(const unsigned char *der, long der_len, + int ml_dsa_evp_type, + const char *classic_alg, const char *ec_curve, + struct der2key_ctx_st *ctx) +{ + PKCS8_PRIV_KEY_INFO *p8inf = NULL; + const unsigned char *ptr = der; + COMPOSITE_KEY *key = NULL; + const unsigned char *privbytes; + const X509_ALGOR *alg = NULL; + int privlen; + + p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &ptr, der_len); + if (p8inf == NULL) + return NULL; + + if (!PKCS8_pkey_get0(NULL, &privbytes, &privlen, &alg, p8inf)) + goto done; + + /* Reject structures whose OID doesn't match this composite variant. */ + if (alg == NULL || OBJ_obj2nid(alg->algorithm) != ctx->desc->evp_type) + goto done; + + key = ossl_composite_d2i_prvkey(privbytes, privlen, ml_dsa_evp_type, + classic_alg, ec_curve, + ctx->provctx, ctx->propq); +done: + PKCS8_PRIV_KEY_INFO_free(p8inf); + return key; +} + +/* + * MAKE_COMPOSITE_D2I: per-algorithm d2i_PUBKEY, d2i_PKCS8, and the + * supporting #defines consumed by MAKE_DECODER. + */ +#define MAKE_COMPOSITE_D2I(alg, ml_dsa_evp_type_, classic_alg_, ec_curve_) \ + static void * \ + alg##_d2i_PUBKEY(const unsigned char **der, long der_len, \ + struct der2key_ctx_st *ctx) \ + { \ + COMPOSITE_KEY *key = composite_d2i_pubkey_common(*der, der_len, ml_dsa_evp_type_, \ + classic_alg_, ec_curve_, ctx); \ + if (key != NULL) \ + *der += der_len; \ + return key; \ + } \ + static void * \ + alg##_d2i_PKCS8(const unsigned char **der, long der_len, \ + struct der2key_ctx_st *ctx) \ + { \ + COMPOSITE_KEY *key = composite_d2i_prvkey_common(*der, der_len, ml_dsa_evp_type_, \ + classic_alg_, ec_curve_, ctx); \ + if (key != NULL) \ + *der += der_len; \ + return key; \ + } + +MAKE_COMPOSITE_D2I(mldsa44_rsa2048_pss_sha256, EVP_PKEY_ML_DSA_44, "RSA", NULL) +MAKE_COMPOSITE_D2I(mldsa44_rsa2048_pkcs15_sha256, EVP_PKEY_ML_DSA_44, "RSA", NULL) +MAKE_COMPOSITE_D2I(mldsa44_ed25519_sha512, EVP_PKEY_ML_DSA_44, "ED25519", NULL) +MAKE_COMPOSITE_D2I(mldsa44_ecdsa_p256_sha256, EVP_PKEY_ML_DSA_44, "EC", "P-256") +MAKE_COMPOSITE_D2I(mldsa65_rsa3072_pss_sha512, EVP_PKEY_ML_DSA_65, "RSA", NULL) +MAKE_COMPOSITE_D2I(mldsa65_rsa3072_pkcs15_sha512, EVP_PKEY_ML_DSA_65, "RSA", NULL) +MAKE_COMPOSITE_D2I(mldsa65_rsa4096_pss_sha512, EVP_PKEY_ML_DSA_65, "RSA", NULL) +MAKE_COMPOSITE_D2I(mldsa65_rsa4096_pkcs15_sha512, EVP_PKEY_ML_DSA_65, "RSA", NULL) +MAKE_COMPOSITE_D2I(mldsa65_ecdsa_p256_sha512, EVP_PKEY_ML_DSA_65, "EC", "P-256") +MAKE_COMPOSITE_D2I(mldsa65_ecdsa_p384_sha512, EVP_PKEY_ML_DSA_65, "EC", "P-384") +MAKE_COMPOSITE_D2I(mldsa65_ecdsa_brainpoolP256r1_sha512, EVP_PKEY_ML_DSA_65, "EC", "brainpoolP256r1") +MAKE_COMPOSITE_D2I(mldsa65_ed25519_sha512, EVP_PKEY_ML_DSA_65, "ED25519", NULL) +MAKE_COMPOSITE_D2I(mldsa87_ecdsa_p384_sha512, EVP_PKEY_ML_DSA_87, "EC", "P-384") +MAKE_COMPOSITE_D2I(mldsa87_ecdsa_brainpoolP384r1_sha512, EVP_PKEY_ML_DSA_87, "EC", "brainpoolP384r1") +MAKE_COMPOSITE_D2I(mldsa87_ed448_shake256, EVP_PKEY_ML_DSA_87, "ED448", NULL) +MAKE_COMPOSITE_D2I(mldsa87_rsa3072_pss_sha512, EVP_PKEY_ML_DSA_87, "RSA", NULL) +MAKE_COMPOSITE_D2I(mldsa87_rsa4096_pss_sha512, EVP_PKEY_ML_DSA_87, "RSA", NULL) +MAKE_COMPOSITE_D2I(mldsa87_ecdsa_p521_sha512, EVP_PKEY_ML_DSA_87, "EC", "P-521") + +/* Supporting #defines consumed by DO_SubjectPublicKeyInfo / DO_PrivateKeyInfo macros */ +#define mldsa44_rsa2048_pss_sha256_evp_type NID_ML_DSA_44_RSA2048_PSS_SHA256 +#define mldsa44_rsa2048_pss_sha256_d2i_private_key NULL +#define mldsa44_rsa2048_pss_sha256_d2i_public_key NULL +#define mldsa44_rsa2048_pss_sha256_d2i_key_params NULL +#define mldsa44_rsa2048_pss_sha256_check NULL +#define mldsa44_rsa2048_pss_sha256_adjust NULL +#define mldsa44_rsa2048_pss_sha256_free (free_key_fn *)ossl_composite_key_free + +#define mldsa44_rsa2048_pkcs15_sha256_evp_type NID_ML_DSA_44_RSA2048_PKCS15_SHA256 +#define mldsa44_rsa2048_pkcs15_sha256_d2i_private_key NULL +#define mldsa44_rsa2048_pkcs15_sha256_d2i_public_key NULL +#define mldsa44_rsa2048_pkcs15_sha256_d2i_key_params NULL +#define mldsa44_rsa2048_pkcs15_sha256_check NULL +#define mldsa44_rsa2048_pkcs15_sha256_adjust NULL +#define mldsa44_rsa2048_pkcs15_sha256_free (free_key_fn *)ossl_composite_key_free + +#define mldsa44_ed25519_sha512_evp_type NID_ML_DSA_44_Ed25519_SHA512 +#define mldsa44_ed25519_sha512_d2i_private_key NULL +#define mldsa44_ed25519_sha512_d2i_public_key NULL +#define mldsa44_ed25519_sha512_d2i_key_params NULL +#define mldsa44_ed25519_sha512_check NULL +#define mldsa44_ed25519_sha512_adjust NULL +#define mldsa44_ed25519_sha512_free (free_key_fn *)ossl_composite_key_free + +#define mldsa44_ecdsa_p256_sha256_evp_type NID_ML_DSA_44_ECDSA_P256_SHA256 +#define mldsa44_ecdsa_p256_sha256_d2i_private_key NULL +#define mldsa44_ecdsa_p256_sha256_d2i_public_key NULL +#define mldsa44_ecdsa_p256_sha256_d2i_key_params NULL +#define mldsa44_ecdsa_p256_sha256_check NULL +#define mldsa44_ecdsa_p256_sha256_adjust NULL +#define mldsa44_ecdsa_p256_sha256_free (free_key_fn *)ossl_composite_key_free + +#define mldsa65_rsa3072_pss_sha512_evp_type NID_ML_DSA_65_RSA3072_PSS_SHA512 +#define mldsa65_rsa3072_pss_sha512_d2i_private_key NULL +#define mldsa65_rsa3072_pss_sha512_d2i_public_key NULL +#define mldsa65_rsa3072_pss_sha512_d2i_key_params NULL +#define mldsa65_rsa3072_pss_sha512_check NULL +#define mldsa65_rsa3072_pss_sha512_adjust NULL +#define mldsa65_rsa3072_pss_sha512_free (free_key_fn *)ossl_composite_key_free + +#define mldsa65_rsa3072_pkcs15_sha512_evp_type NID_ML_DSA_65_RSA3072_PKCS15_SHA512 +#define mldsa65_rsa3072_pkcs15_sha512_d2i_private_key NULL +#define mldsa65_rsa3072_pkcs15_sha512_d2i_public_key NULL +#define mldsa65_rsa3072_pkcs15_sha512_d2i_key_params NULL +#define mldsa65_rsa3072_pkcs15_sha512_check NULL +#define mldsa65_rsa3072_pkcs15_sha512_adjust NULL +#define mldsa65_rsa3072_pkcs15_sha512_free (free_key_fn *)ossl_composite_key_free + +#define mldsa65_rsa4096_pss_sha512_evp_type NID_ML_DSA_65_RSA4096_PSS_SHA512 +#define mldsa65_rsa4096_pss_sha512_d2i_private_key NULL +#define mldsa65_rsa4096_pss_sha512_d2i_public_key NULL +#define mldsa65_rsa4096_pss_sha512_d2i_key_params NULL +#define mldsa65_rsa4096_pss_sha512_check NULL +#define mldsa65_rsa4096_pss_sha512_adjust NULL +#define mldsa65_rsa4096_pss_sha512_free (free_key_fn *)ossl_composite_key_free + +#define mldsa65_rsa4096_pkcs15_sha512_evp_type NID_ML_DSA_65_RSA4096_PKCS15_SHA512 +#define mldsa65_rsa4096_pkcs15_sha512_d2i_private_key NULL +#define mldsa65_rsa4096_pkcs15_sha512_d2i_public_key NULL +#define mldsa65_rsa4096_pkcs15_sha512_d2i_key_params NULL +#define mldsa65_rsa4096_pkcs15_sha512_check NULL +#define mldsa65_rsa4096_pkcs15_sha512_adjust NULL +#define mldsa65_rsa4096_pkcs15_sha512_free (free_key_fn *)ossl_composite_key_free + +#define mldsa65_ecdsa_p256_sha512_evp_type NID_ML_DSA_65_ECDSA_P256_SHA512 +#define mldsa65_ecdsa_p256_sha512_d2i_private_key NULL +#define mldsa65_ecdsa_p256_sha512_d2i_public_key NULL +#define mldsa65_ecdsa_p256_sha512_d2i_key_params NULL +#define mldsa65_ecdsa_p256_sha512_check NULL +#define mldsa65_ecdsa_p256_sha512_adjust NULL +#define mldsa65_ecdsa_p256_sha512_free (free_key_fn *)ossl_composite_key_free + +#define mldsa65_ecdsa_p384_sha512_evp_type NID_ML_DSA_65_ECDSA_P384_SHA512 +#define mldsa65_ecdsa_p384_sha512_d2i_private_key NULL +#define mldsa65_ecdsa_p384_sha512_d2i_public_key NULL +#define mldsa65_ecdsa_p384_sha512_d2i_key_params NULL +#define mldsa65_ecdsa_p384_sha512_check NULL +#define mldsa65_ecdsa_p384_sha512_adjust NULL +#define mldsa65_ecdsa_p384_sha512_free (free_key_fn *)ossl_composite_key_free + +#define mldsa65_ecdsa_brainpoolP256r1_sha512_evp_type NID_ML_DSA_65_ECDSA_brainpoolP256r1_SHA512 +#define mldsa65_ecdsa_brainpoolP256r1_sha512_d2i_private_key NULL +#define mldsa65_ecdsa_brainpoolP256r1_sha512_d2i_public_key NULL +#define mldsa65_ecdsa_brainpoolP256r1_sha512_d2i_key_params NULL +#define mldsa65_ecdsa_brainpoolP256r1_sha512_check NULL +#define mldsa65_ecdsa_brainpoolP256r1_sha512_adjust NULL +#define mldsa65_ecdsa_brainpoolP256r1_sha512_free (free_key_fn *)ossl_composite_key_free + +#define mldsa65_ed25519_sha512_evp_type NID_ML_DSA_65_Ed25519_SHA512 +#define mldsa65_ed25519_sha512_d2i_private_key NULL +#define mldsa65_ed25519_sha512_d2i_public_key NULL +#define mldsa65_ed25519_sha512_d2i_key_params NULL +#define mldsa65_ed25519_sha512_check NULL +#define mldsa65_ed25519_sha512_adjust NULL +#define mldsa65_ed25519_sha512_free (free_key_fn *)ossl_composite_key_free + +#define mldsa87_ecdsa_p384_sha512_evp_type NID_ML_DSA_87_ECDSA_P384_SHA512 +#define mldsa87_ecdsa_p384_sha512_d2i_private_key NULL +#define mldsa87_ecdsa_p384_sha512_d2i_public_key NULL +#define mldsa87_ecdsa_p384_sha512_d2i_key_params NULL +#define mldsa87_ecdsa_p384_sha512_check NULL +#define mldsa87_ecdsa_p384_sha512_adjust NULL +#define mldsa87_ecdsa_p384_sha512_free (free_key_fn *)ossl_composite_key_free + +#define mldsa87_ecdsa_brainpoolP384r1_sha512_evp_type NID_ML_DSA_87_ECDSA_brainpoolP384r1_SHA512 +#define mldsa87_ecdsa_brainpoolP384r1_sha512_d2i_private_key NULL +#define mldsa87_ecdsa_brainpoolP384r1_sha512_d2i_public_key NULL +#define mldsa87_ecdsa_brainpoolP384r1_sha512_d2i_key_params NULL +#define mldsa87_ecdsa_brainpoolP384r1_sha512_check NULL +#define mldsa87_ecdsa_brainpoolP384r1_sha512_adjust NULL +#define mldsa87_ecdsa_brainpoolP384r1_sha512_free (free_key_fn *)ossl_composite_key_free + +#define mldsa87_ed448_shake256_evp_type NID_ML_DSA_87_Ed448_SHAKE256 +#define mldsa87_ed448_shake256_d2i_private_key NULL +#define mldsa87_ed448_shake256_d2i_public_key NULL +#define mldsa87_ed448_shake256_d2i_key_params NULL +#define mldsa87_ed448_shake256_check NULL +#define mldsa87_ed448_shake256_adjust NULL +#define mldsa87_ed448_shake256_free (free_key_fn *)ossl_composite_key_free + +#define mldsa87_rsa3072_pss_sha512_evp_type NID_ML_DSA_87_RSA3072_PSS_SHA512 +#define mldsa87_rsa3072_pss_sha512_d2i_private_key NULL +#define mldsa87_rsa3072_pss_sha512_d2i_public_key NULL +#define mldsa87_rsa3072_pss_sha512_d2i_key_params NULL +#define mldsa87_rsa3072_pss_sha512_check NULL +#define mldsa87_rsa3072_pss_sha512_adjust NULL +#define mldsa87_rsa3072_pss_sha512_free (free_key_fn *)ossl_composite_key_free + +#define mldsa87_rsa4096_pss_sha512_evp_type NID_ML_DSA_87_RSA4096_PSS_SHA512 +#define mldsa87_rsa4096_pss_sha512_d2i_private_key NULL +#define mldsa87_rsa4096_pss_sha512_d2i_public_key NULL +#define mldsa87_rsa4096_pss_sha512_d2i_key_params NULL +#define mldsa87_rsa4096_pss_sha512_check NULL +#define mldsa87_rsa4096_pss_sha512_adjust NULL +#define mldsa87_rsa4096_pss_sha512_free (free_key_fn *)ossl_composite_key_free + +#define mldsa87_ecdsa_p521_sha512_evp_type NID_ML_DSA_87_ECDSA_P521_SHA512 +#define mldsa87_ecdsa_p521_sha512_d2i_private_key NULL +#define mldsa87_ecdsa_p521_sha512_d2i_public_key NULL +#define mldsa87_ecdsa_p521_sha512_d2i_key_params NULL +#define mldsa87_ecdsa_p521_sha512_check NULL +#define mldsa87_ecdsa_p521_sha512_adjust NULL +#define mldsa87_ecdsa_p521_sha512_free (free_key_fn *)ossl_composite_key_free + +#endif /* OPENSSL_NO_COMPOSITE */ + +/* ---------------------------------------------------------------------- */ + #ifndef OPENSSL_NO_LMS static void lms_free_key(void *key) { @@ -1369,6 +1696,45 @@ MAKE_DECODER("ML-DSA-87", ml_dsa_87, ml_dsa_87, PrivateKeyInfo); MAKE_DECODER("ML-DSA-87", ml_dsa_87, ml_dsa_87, SubjectPublicKeyInfo); #endif +#ifndef OPENSSL_NO_COMPOSITE +MAKE_DECODER("ML-DSA-44-RSA2048-PSS-SHA256", mldsa44_rsa2048_pss_sha256, mldsa44_rsa2048_pss_sha256, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-44-RSA2048-PSS-SHA256", mldsa44_rsa2048_pss_sha256, mldsa44_rsa2048_pss_sha256, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-44-RSA2048-PKCS15-SHA256", mldsa44_rsa2048_pkcs15_sha256, mldsa44_rsa2048_pkcs15_sha256, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-44-RSA2048-PKCS15-SHA256", mldsa44_rsa2048_pkcs15_sha256, mldsa44_rsa2048_pkcs15_sha256, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-44-Ed25519-SHA512", mldsa44_ed25519_sha512, mldsa44_ed25519_sha512, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-44-Ed25519-SHA512", mldsa44_ed25519_sha512, mldsa44_ed25519_sha512, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-44-ECDSA-P256-SHA256", mldsa44_ecdsa_p256_sha256, mldsa44_ecdsa_p256_sha256, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-44-ECDSA-P256-SHA256", mldsa44_ecdsa_p256_sha256, mldsa44_ecdsa_p256_sha256, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-65-RSA3072-PSS-SHA512", mldsa65_rsa3072_pss_sha512, mldsa65_rsa3072_pss_sha512, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-65-RSA3072-PSS-SHA512", mldsa65_rsa3072_pss_sha512, mldsa65_rsa3072_pss_sha512, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-65-RSA3072-PKCS15-SHA512", mldsa65_rsa3072_pkcs15_sha512, mldsa65_rsa3072_pkcs15_sha512, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-65-RSA3072-PKCS15-SHA512", mldsa65_rsa3072_pkcs15_sha512, mldsa65_rsa3072_pkcs15_sha512, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-65-RSA4096-PSS-SHA512", mldsa65_rsa4096_pss_sha512, mldsa65_rsa4096_pss_sha512, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-65-RSA4096-PSS-SHA512", mldsa65_rsa4096_pss_sha512, mldsa65_rsa4096_pss_sha512, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-65-RSA4096-PKCS15-SHA512", mldsa65_rsa4096_pkcs15_sha512, mldsa65_rsa4096_pkcs15_sha512, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-65-RSA4096-PKCS15-SHA512", mldsa65_rsa4096_pkcs15_sha512, mldsa65_rsa4096_pkcs15_sha512, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-65-ECDSA-P256-SHA512", mldsa65_ecdsa_p256_sha512, mldsa65_ecdsa_p256_sha512, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-65-ECDSA-P256-SHA512", mldsa65_ecdsa_p256_sha512, mldsa65_ecdsa_p256_sha512, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-65-ECDSA-P384-SHA512", mldsa65_ecdsa_p384_sha512, mldsa65_ecdsa_p384_sha512, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-65-ECDSA-P384-SHA512", mldsa65_ecdsa_p384_sha512, mldsa65_ecdsa_p384_sha512, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-65-ECDSA-brainpoolP256r1-SHA512", mldsa65_ecdsa_brainpoolP256r1_sha512, mldsa65_ecdsa_brainpoolP256r1_sha512, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-65-ECDSA-brainpoolP256r1-SHA512", mldsa65_ecdsa_brainpoolP256r1_sha512, mldsa65_ecdsa_brainpoolP256r1_sha512, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-65-Ed25519-SHA512", mldsa65_ed25519_sha512, mldsa65_ed25519_sha512, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-65-Ed25519-SHA512", mldsa65_ed25519_sha512, mldsa65_ed25519_sha512, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-87-ECDSA-P384-SHA512", mldsa87_ecdsa_p384_sha512, mldsa87_ecdsa_p384_sha512, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-87-ECDSA-P384-SHA512", mldsa87_ecdsa_p384_sha512, mldsa87_ecdsa_p384_sha512, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-87-ECDSA-brainpoolP384r1-SHA512", mldsa87_ecdsa_brainpoolP384r1_sha512, mldsa87_ecdsa_brainpoolP384r1_sha512, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-87-ECDSA-brainpoolP384r1-SHA512", mldsa87_ecdsa_brainpoolP384r1_sha512, mldsa87_ecdsa_brainpoolP384r1_sha512, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-87-Ed448-SHAKE256", mldsa87_ed448_shake256, mldsa87_ed448_shake256, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-87-Ed448-SHAKE256", mldsa87_ed448_shake256, mldsa87_ed448_shake256, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-87-RSA3072-PSS-SHA512", mldsa87_rsa3072_pss_sha512, mldsa87_rsa3072_pss_sha512, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-87-RSA3072-PSS-SHA512", mldsa87_rsa3072_pss_sha512, mldsa87_rsa3072_pss_sha512, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-87-RSA4096-PSS-SHA512", mldsa87_rsa4096_pss_sha512, mldsa87_rsa4096_pss_sha512, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-87-RSA4096-PSS-SHA512", mldsa87_rsa4096_pss_sha512, mldsa87_rsa4096_pss_sha512, SubjectPublicKeyInfo); +MAKE_DECODER("ML-DSA-87-ECDSA-P521-SHA512", mldsa87_ecdsa_p521_sha512, mldsa87_ecdsa_p521_sha512, PrivateKeyInfo); +MAKE_DECODER("ML-DSA-87-ECDSA-P521-SHA512", mldsa87_ecdsa_p521_sha512, mldsa87_ecdsa_p521_sha512, SubjectPublicKeyInfo); +#endif + #ifndef OPENSSL_NO_LMS MAKE_DECODER("LMS", lms, lms, SubjectPublicKeyInfo); #endif diff --git a/providers/implementations/encode_decode/encode_key2any.c b/providers/implementations/encode_decode/encode_key2any.c index 1d12bf1e9e720..76148211b6be8 100644 --- a/providers/implementations/encode_decode/encode_key2any.c +++ b/providers/implementations/encode_decode/encode_key2any.c @@ -42,6 +42,10 @@ #include "prov/ml_dsa_codecs.h" #include "prov/ml_kem_codecs.h" #include "prov/lms_codecs.h" +#ifndef OPENSSL_NO_COMPOSITE +#include "prov/composite_codecs.h" +#include +#endif #include "providers/implementations/encode_decode/encode_key2any.inc" #include @@ -106,6 +110,7 @@ static PKCS8_PRIV_KEY_INFO *key_to_p8info(const void *key, int key_nid, params_type, params, der, derlen)) { ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); PKCS8_PRIV_KEY_INFO_free(p8info); + free_asn1_data(params_type, params); OPENSSL_free(der); p8info = NULL; } @@ -144,9 +149,7 @@ static X509_SIG *key_to_encp8(const void *key, int key_nid, PKCS8_PRIV_KEY_INFO *p8info = key_to_p8info(key, key_nid, params, params_type, k2d, ctx); X509_SIG *p8 = NULL; - if (p8info == NULL) { - free_asn1_data(params_type, params); - } else { + if (p8info != NULL) { p8 = p8info_to_encp8(p8info, ctx); PKCS8_PRIV_KEY_INFO_free(p8info); } @@ -171,6 +174,7 @@ static X509_PUBKEY *key_to_pubkey(const void *key, int key_nid, ERR_raise(ERR_LIB_PROV, ERR_R_X509_LIB); X509_PUBKEY_free(xpk); OPENSSL_free(der); + free_asn1_data(params_type, params); xpk = NULL; } @@ -273,8 +277,6 @@ static int key_to_pki_der_priv_bio(BIO *out, const void *key, if (p8info != NULL) ret = i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8info); - else - free_asn1_data(strtype, str); PKCS8_PRIV_KEY_INFO_free(p8info); @@ -304,8 +306,6 @@ static int key_to_pki_pem_priv_bio(BIO *out, const void *key, if (p8info != NULL) ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info); - else - free_asn1_data(strtype, str); PKCS8_PRIV_KEY_INFO_free(p8info); @@ -356,8 +356,6 @@ static int key_to_spki_pem_pub_bio(BIO *out, const void *key, if (xpk != NULL) ret = PEM_write_bio_X509_PUBKEY(out, xpk); - else - free_asn1_data(strtype, str); /* Also frees |str| */ X509_PUBKEY_free(xpk); @@ -646,8 +644,8 @@ static int dsa_pki_priv_to_der(const void *dsa, unsigned char **pder, } k2d_NOCTX(dsa_prv, i2d_DSAPrivateKey) - k2d_NOCTX(dsa_pub, i2d_DSAPublicKey) - k2d_NOCTX(dsa_param, i2d_DSAparams) +k2d_NOCTX(dsa_pub, i2d_DSAPublicKey) +k2d_NOCTX(dsa_param, i2d_DSAparams) #define dsa_epki_priv_to_der dsa_pki_priv_to_der @@ -663,8 +661,9 @@ k2d_NOCTX(dsa_prv, i2d_DSAPrivateKey) /* ---------------------------------------------------------------------- */ #ifndef OPENSSL_NO_EC - static int prepare_ec_explicit_params(const void *eckey, - void **pstr, int *pstrtype) + +static int prepare_ec_explicit_params(const void *eckey, void **pstr, + int *pstrtype) { ASN1_STRING *params = ASN1_STRING_new(); @@ -755,7 +754,7 @@ static int ec_pki_priv_to_der(const void *veckey, unsigned char **pder, } k2d_NOCTX(ec_param, i2d_ECParameters) - k2d_NOCTX(ec_prv, i2d_ECPrivateKey) +k2d_NOCTX(ec_prv, i2d_ECPrivateKey) #define ec_epki_priv_to_der ec_pki_priv_to_der @@ -786,8 +785,8 @@ k2d_NOCTX(ec_param, i2d_ECParameters) #ifndef OPENSSL_NO_ECX #define prepare_ecx_params NULL - static int ecx_spki_pub_to_der(const void *vecxkey, unsigned char **pder, - ossl_unused void *ctx) +static int ecx_spki_pub_to_der(const void *vecxkey, unsigned char **pder, + ossl_unused void *ctx) { const ECX_KEY *ecxkey = vecxkey; unsigned char *keyblob; @@ -991,7 +990,7 @@ static int prepare_rsa_params(const void *rsa, int nid, int save, } k2d_NOCTX(rsa_prv, i2d_RSAPrivateKey) - k2d_NOCTX(rsa_pub, i2d_RSAPublicKey) +k2d_NOCTX(rsa_pub, i2d_RSAPublicKey) /* * RSA is extremely simple, as PKCS#1 is used for the PKCS#8 |privateKey| @@ -1004,7 +1003,7 @@ k2d_NOCTX(rsa_prv, i2d_RSAPrivateKey) #define rsa_type_specific_pub_to_der rsa_pub_k2d #define rsa_type_specific_params_to_der NULL - static int rsa_check_key_type(const void *rsa, int expected_type) +static int rsa_check_key_type(const void *rsa, int expected_type) { switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { case RSA_FLAG_TYPE_RSA: @@ -1787,3 +1786,185 @@ MAKE_ENCODER(ml_dsa_87, ml_dsa, SubjectPublicKeyInfo, pem); MAKE_ENCODER(lms, lms, SubjectPublicKeyInfo, der); MAKE_ENCODER(lms, lms, SubjectPublicKeyInfo, pem); #endif + +#ifndef OPENSSL_NO_COMPOSITE +static int composite_spki_pub_to_der(const void *vkey, unsigned char **pder, + ossl_unused void *ctx) +{ + return ossl_composite_i2d_pubkey((const COMPOSITE_KEY *)vkey, pder); +} + +static int composite_pki_priv_to_der(const void *vkey, unsigned char **pder, + ossl_unused void *ctx) +{ + return ossl_composite_i2d_prvkey((const COMPOSITE_KEY *)vkey, pder); +} + +#define composite_epki_priv_to_der composite_pki_priv_to_der +#define prepare_composite_params NULL +#define composite_check_key_type NULL + +/* evp_type and pem_type defines for all 18 composite variants */ +#define mldsa44_rsa2048_pss_sha256_evp_type NID_ML_DSA_44_RSA2048_PSS_SHA256 +#define mldsa44_rsa2048_pss_sha256_pem_type LN_ML_DSA_44_RSA2048_PSS_SHA256 +#define mldsa44_rsa2048_pkcs15_sha256_evp_type NID_ML_DSA_44_RSA2048_PKCS15_SHA256 +#define mldsa44_rsa2048_pkcs15_sha256_pem_type LN_ML_DSA_44_RSA2048_PKCS15_SHA256 +#define mldsa44_ed25519_sha512_evp_type NID_ML_DSA_44_Ed25519_SHA512 +#define mldsa44_ed25519_sha512_pem_type LN_ML_DSA_44_Ed25519_SHA512 +#define mldsa44_ecdsa_p256_sha256_evp_type NID_ML_DSA_44_ECDSA_P256_SHA256 +#define mldsa44_ecdsa_p256_sha256_pem_type LN_ML_DSA_44_ECDSA_P256_SHA256 +#define mldsa65_rsa3072_pss_sha512_evp_type NID_ML_DSA_65_RSA3072_PSS_SHA512 +#define mldsa65_rsa3072_pss_sha512_pem_type LN_ML_DSA_65_RSA3072_PSS_SHA512 +#define mldsa65_rsa3072_pkcs15_sha512_evp_type NID_ML_DSA_65_RSA3072_PKCS15_SHA512 +#define mldsa65_rsa3072_pkcs15_sha512_pem_type LN_ML_DSA_65_RSA3072_PKCS15_SHA512 +#define mldsa65_rsa4096_pss_sha512_evp_type NID_ML_DSA_65_RSA4096_PSS_SHA512 +#define mldsa65_rsa4096_pss_sha512_pem_type LN_ML_DSA_65_RSA4096_PSS_SHA512 +#define mldsa65_rsa4096_pkcs15_sha512_evp_type NID_ML_DSA_65_RSA4096_PKCS15_SHA512 +#define mldsa65_rsa4096_pkcs15_sha512_pem_type LN_ML_DSA_65_RSA4096_PKCS15_SHA512 +#define mldsa65_ecdsa_p256_sha512_evp_type NID_ML_DSA_65_ECDSA_P256_SHA512 +#define mldsa65_ecdsa_p256_sha512_pem_type LN_ML_DSA_65_ECDSA_P256_SHA512 +#define mldsa65_ecdsa_p384_sha512_evp_type NID_ML_DSA_65_ECDSA_P384_SHA512 +#define mldsa65_ecdsa_p384_sha512_pem_type LN_ML_DSA_65_ECDSA_P384_SHA512 +#define mldsa65_ecdsa_brainpoolP256r1_sha512_evp_type NID_ML_DSA_65_ECDSA_brainpoolP256r1_SHA512 +#define mldsa65_ecdsa_brainpoolP256r1_sha512_pem_type LN_ML_DSA_65_ECDSA_brainpoolP256r1_SHA512 +#define mldsa65_ed25519_sha512_evp_type NID_ML_DSA_65_Ed25519_SHA512 +#define mldsa65_ed25519_sha512_pem_type LN_ML_DSA_65_Ed25519_SHA512 +#define mldsa87_ecdsa_p384_sha512_evp_type NID_ML_DSA_87_ECDSA_P384_SHA512 +#define mldsa87_ecdsa_p384_sha512_pem_type LN_ML_DSA_87_ECDSA_P384_SHA512 +#define mldsa87_ecdsa_brainpoolP384r1_sha512_evp_type NID_ML_DSA_87_ECDSA_brainpoolP384r1_SHA512 +#define mldsa87_ecdsa_brainpoolP384r1_sha512_pem_type LN_ML_DSA_87_ECDSA_brainpoolP384r1_SHA512 +#define mldsa87_ed448_shake256_evp_type NID_ML_DSA_87_Ed448_SHAKE256 +#define mldsa87_ed448_shake256_pem_type LN_ML_DSA_87_Ed448_SHAKE256 +#define mldsa87_rsa3072_pss_sha512_evp_type NID_ML_DSA_87_RSA3072_PSS_SHA512 +#define mldsa87_rsa3072_pss_sha512_pem_type LN_ML_DSA_87_RSA3072_PSS_SHA512 +#define mldsa87_rsa4096_pss_sha512_evp_type NID_ML_DSA_87_RSA4096_PSS_SHA512 +#define mldsa87_rsa4096_pss_sha512_pem_type LN_ML_DSA_87_RSA4096_PSS_SHA512 +#define mldsa87_ecdsa_p521_sha512_evp_type NID_ML_DSA_87_ECDSA_P521_SHA512 +#define mldsa87_ecdsa_p521_sha512_pem_type LN_ML_DSA_87_ECDSA_P521_SHA512 + +MAKE_ENCODER(mldsa44_rsa2048_pss_sha256, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa44_rsa2048_pss_sha256, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa44_rsa2048_pss_sha256, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa44_rsa2048_pss_sha256, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa44_rsa2048_pss_sha256, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa44_rsa2048_pss_sha256, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa44_rsa2048_pkcs15_sha256, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa44_rsa2048_pkcs15_sha256, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa44_rsa2048_pkcs15_sha256, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa44_rsa2048_pkcs15_sha256, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa44_rsa2048_pkcs15_sha256, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa44_rsa2048_pkcs15_sha256, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa44_ed25519_sha512, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa44_ed25519_sha512, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa44_ed25519_sha512, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa44_ed25519_sha512, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa44_ed25519_sha512, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa44_ed25519_sha512, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa44_ecdsa_p256_sha256, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa44_ecdsa_p256_sha256, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa44_ecdsa_p256_sha256, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa44_ecdsa_p256_sha256, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa44_ecdsa_p256_sha256, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa44_ecdsa_p256_sha256, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa65_rsa3072_pss_sha512, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_rsa3072_pss_sha512, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_rsa3072_pss_sha512, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_rsa3072_pss_sha512, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_rsa3072_pss_sha512, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa65_rsa3072_pss_sha512, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa65_rsa3072_pkcs15_sha512, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_rsa3072_pkcs15_sha512, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_rsa3072_pkcs15_sha512, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_rsa3072_pkcs15_sha512, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_rsa3072_pkcs15_sha512, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa65_rsa3072_pkcs15_sha512, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa65_rsa4096_pss_sha512, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_rsa4096_pss_sha512, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_rsa4096_pss_sha512, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_rsa4096_pss_sha512, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_rsa4096_pss_sha512, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa65_rsa4096_pss_sha512, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa65_rsa4096_pkcs15_sha512, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_rsa4096_pkcs15_sha512, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_rsa4096_pkcs15_sha512, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_rsa4096_pkcs15_sha512, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_rsa4096_pkcs15_sha512, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa65_rsa4096_pkcs15_sha512, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa65_ecdsa_p256_sha512, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_ecdsa_p256_sha512, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_ecdsa_p256_sha512, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_ecdsa_p256_sha512, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_ecdsa_p256_sha512, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa65_ecdsa_p256_sha512, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa65_ecdsa_p384_sha512, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_ecdsa_p384_sha512, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_ecdsa_p384_sha512, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_ecdsa_p384_sha512, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_ecdsa_p384_sha512, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa65_ecdsa_p384_sha512, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa65_ecdsa_brainpoolP256r1_sha512, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_ecdsa_brainpoolP256r1_sha512, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_ecdsa_brainpoolP256r1_sha512, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_ecdsa_brainpoolP256r1_sha512, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_ecdsa_brainpoolP256r1_sha512, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa65_ecdsa_brainpoolP256r1_sha512, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa65_ed25519_sha512, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_ed25519_sha512, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_ed25519_sha512, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa65_ed25519_sha512, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa65_ed25519_sha512, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa65_ed25519_sha512, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa87_ecdsa_p384_sha512, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa87_ecdsa_p384_sha512, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa87_ecdsa_p384_sha512, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa87_ecdsa_p384_sha512, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa87_ecdsa_p384_sha512, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa87_ecdsa_p384_sha512, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa87_ecdsa_brainpoolP384r1_sha512, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa87_ecdsa_brainpoolP384r1_sha512, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa87_ecdsa_brainpoolP384r1_sha512, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa87_ecdsa_brainpoolP384r1_sha512, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa87_ecdsa_brainpoolP384r1_sha512, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa87_ecdsa_brainpoolP384r1_sha512, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa87_ed448_shake256, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa87_ed448_shake256, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa87_ed448_shake256, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa87_ed448_shake256, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa87_ed448_shake256, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa87_ed448_shake256, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa87_rsa3072_pss_sha512, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa87_rsa3072_pss_sha512, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa87_rsa3072_pss_sha512, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa87_rsa3072_pss_sha512, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa87_rsa3072_pss_sha512, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa87_rsa3072_pss_sha512, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa87_rsa4096_pss_sha512, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa87_rsa4096_pss_sha512, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa87_rsa4096_pss_sha512, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa87_rsa4096_pss_sha512, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa87_rsa4096_pss_sha512, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa87_rsa4096_pss_sha512, composite, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(mldsa87_ecdsa_p521_sha512, composite, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(mldsa87_ecdsa_p521_sha512, composite, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(mldsa87_ecdsa_p521_sha512, composite, PrivateKeyInfo, der); +MAKE_ENCODER(mldsa87_ecdsa_p521_sha512, composite, PrivateKeyInfo, pem); +MAKE_ENCODER(mldsa87_ecdsa_p521_sha512, composite, SubjectPublicKeyInfo, der); +MAKE_ENCODER(mldsa87_ecdsa_p521_sha512, composite, SubjectPublicKeyInfo, pem); +#endif /* OPENSSL_NO_COMPOSITE */ diff --git a/providers/implementations/encode_decode/encode_key2ms.c b/providers/implementations/encode_decode/encode_key2ms.c index 87b4242923566..a5301822de233 100644 --- a/providers/implementations/encode_decode/encode_key2ms.c +++ b/providers/implementations/encode_decode/encode_key2ms.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/encode_decode/encode_key2text.c b/providers/implementations/encode_decode/encode_key2text.c index 965113426b200..17c5e27aa45ea 100644 --- a/providers/implementations/encode_decode/encode_key2text.c +++ b/providers/implementations/encode_decode/encode_key2text.c @@ -34,6 +34,9 @@ #include "prov/ml_dsa_codecs.h" #include "prov/ml_kem_codecs.h" #include "prov/lms_codecs.h" +#ifndef OPENSSL_NO_COMPOSITE +#include "prov/composite_codecs.h" +#endif DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) @@ -630,6 +633,14 @@ static int lms_to_text(BIO *out, const void *key, int selection) } #endif /* OPENSSL_NO_LMS */ +#ifndef OPENSSL_NO_COMPOSITE +static int composite_to_text(BIO *out, const void *key, int selection) +{ + return ossl_composite_key_to_text(out, (const COMPOSITE_KEY *)key, + selection); +} +#endif /* OPENSSL_NO_COMPOSITE */ + /* ---------------------------------------------------------------------- */ static void *key2text_newctx(void *provctx) @@ -756,3 +767,24 @@ MAKE_TEXT_ENCODER(slh_dsa_shake_256f, slh_dsa); #ifndef OPENSSL_NO_LMS MAKE_TEXT_ENCODER(lms, lms); #endif + +#ifndef OPENSSL_NO_COMPOSITE +MAKE_TEXT_ENCODER(mldsa44_rsa2048_pss_sha256, composite); +MAKE_TEXT_ENCODER(mldsa44_rsa2048_pkcs15_sha256, composite); +MAKE_TEXT_ENCODER(mldsa44_ed25519_sha512, composite); +MAKE_TEXT_ENCODER(mldsa44_ecdsa_p256_sha256, composite); +MAKE_TEXT_ENCODER(mldsa65_rsa3072_pss_sha512, composite); +MAKE_TEXT_ENCODER(mldsa65_rsa3072_pkcs15_sha512, composite); +MAKE_TEXT_ENCODER(mldsa65_rsa4096_pss_sha512, composite); +MAKE_TEXT_ENCODER(mldsa65_rsa4096_pkcs15_sha512, composite); +MAKE_TEXT_ENCODER(mldsa65_ecdsa_p256_sha512, composite); +MAKE_TEXT_ENCODER(mldsa65_ecdsa_p384_sha512, composite); +MAKE_TEXT_ENCODER(mldsa65_ecdsa_brainpoolP256r1_sha512, composite); +MAKE_TEXT_ENCODER(mldsa65_ed25519_sha512, composite); +MAKE_TEXT_ENCODER(mldsa87_ecdsa_p384_sha512, composite); +MAKE_TEXT_ENCODER(mldsa87_ecdsa_brainpoolP384r1_sha512, composite); +MAKE_TEXT_ENCODER(mldsa87_ed448_shake256, composite); +MAKE_TEXT_ENCODER(mldsa87_rsa3072_pss_sha512, composite); +MAKE_TEXT_ENCODER(mldsa87_rsa4096_pss_sha512, composite); +MAKE_TEXT_ENCODER(mldsa87_ecdsa_p521_sha512, composite); +#endif /* OPENSSL_NO_COMPOSITE */ diff --git a/providers/implementations/encode_decode/ml_dsa_codecs.c b/providers/implementations/encode_decode/ml_dsa_codecs.c index 8d84a098ee6b2..ad1bfc9b1ca88 100644 --- a/providers/implementations/encode_decode/ml_dsa_codecs.c +++ b/providers/implementations/encode_decode/ml_dsa_codecs.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/encode_decode/ml_kem_codecs.c b/providers/implementations/encode_decode/ml_kem_codecs.c index 21bff4174f25f..8eab4959afa44 100644 --- a/providers/implementations/encode_decode/ml_kem_codecs.c +++ b/providers/implementations/encode_decode/ml_kem_codecs.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/ciphercommon.h b/providers/implementations/include/prov/ciphercommon.h index 39f3c363970fb..7cdfcdade02ae 100644 --- a/providers/implementations/include/prov/ciphercommon.h +++ b/providers/implementations/include/prov/ciphercommon.h @@ -106,6 +106,8 @@ struct prov_cipher_hw_st { }; void ossl_cipher_generic_reset_ctx(PROV_CIPHER_CTX *ctx); +int ossl_cipher_generic_dupctx_tlsmac(PROV_CIPHER_CTX *dst, + const PROV_CIPHER_CTX *src); OSSL_FUNC_cipher_encrypt_init_fn ossl_cipher_generic_einit; OSSL_FUNC_cipher_decrypt_init_fn ossl_cipher_generic_dinit; OSSL_FUNC_cipher_update_fn ossl_cipher_generic_block_update; @@ -346,38 +348,18 @@ PROV_CIPHER_HW_FN ossl_cipher_hw_chunked_ofb128; dst->ks = &dctx->ks.ks; \ } -#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(name) \ - static const OSSL_PARAM name##_known_gettable_ctx_params[] = { \ - OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), \ - OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL), \ - OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), \ - OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL), \ - OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0), \ - OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_UPDATED_IV, NULL, 0), - -#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(name) \ - OSSL_PARAM_END \ - } \ - ; \ - const OSSL_PARAM *name##_gettable_ctx_params(ossl_unused void *cctx, \ - ossl_unused void *provctx) \ - { \ - return name##_known_gettable_ctx_params; \ - } - -#define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(name) \ - static const OSSL_PARAM name##_known_settable_ctx_params[] = { \ - OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL), \ - OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL), -#define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(name) \ - OSSL_PARAM_END \ - } \ - ; \ - const OSSL_PARAM *name##_settable_ctx_params(ossl_unused void *cctx, \ - ossl_unused void *provctx) \ - { \ - return name##_known_settable_ctx_params; \ - } +struct ossl_cipher_get_param_list_st { + OSSL_PARAM *mode; + OSSL_PARAM *keylen; + OSSL_PARAM *ivlen; + OSSL_PARAM *bsize; + OSSL_PARAM *aead; + OSSL_PARAM *custiv; + OSSL_PARAM *cts; + OSSL_PARAM *mb; + OSSL_PARAM *rand; + OSSL_PARAM *etm; +}; struct ossl_cipher_get_ctx_param_list_st { OSSL_PARAM *keylen; /* all ciphers */ @@ -398,8 +380,13 @@ struct ossl_cipher_set_ctx_param_list_st { OSSL_PARAM *keylen; /* variable key length ciphers */ }; -int ossl_cipher_common_get_ctx_params(PROV_CIPHER_CTX *ctx, const struct ossl_cipher_get_ctx_param_list_st *p); -int ossl_cipher_common_set_ctx_params(PROV_CIPHER_CTX *ctx, const struct ossl_cipher_set_ctx_param_list_st *p); +int ossl_cipher_common_get_params(const struct ossl_cipher_get_param_list_st *p, + unsigned int md, uint64_t flags, size_t kbits, size_t blkbits, + size_t ivbits); +int ossl_cipher_common_get_ctx_params(PROV_CIPHER_CTX *ctx, + const struct ossl_cipher_get_ctx_param_list_st *p); +int ossl_cipher_common_set_ctx_params(PROV_CIPHER_CTX *ctx, + const struct ossl_cipher_set_ctx_param_list_st *p); int ossl_cipher_generic_initiv(PROV_CIPHER_CTX *ctx, const unsigned char *iv, size_t ivlen); diff --git a/providers/implementations/include/prov/ciphercommon_ccm.h b/providers/implementations/include/prov/ciphercommon_ccm.h index 2040eaade7a67..43baf74b8e582 100644 --- a/providers/implementations/include/prov/ciphercommon_ccm.h +++ b/providers/implementations/include/prov/ciphercommon_ccm.h @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/ciphercommon_gcm.h b/providers/implementations/include/prov/ciphercommon_gcm.h index 08865b7595907..9668be41d41bf 100644 --- a/providers/implementations/include/prov/ciphercommon_gcm.h +++ b/providers/implementations/include/prov/ciphercommon_gcm.h @@ -1,6 +1,6 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/composite_codecs.h b/providers/implementations/include/prov/composite_codecs.h new file mode 100644 index 0000000000000..34c18898faa90 --- /dev/null +++ b/providers/implementations/include/prov/composite_codecs.h @@ -0,0 +1,77 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef PROV_COMPOSITE_CODECS_H +#define PROV_COMPOSITE_CODECS_H +#pragma once + +#ifndef OPENSSL_NO_COMPOSITE +#include +#include +#include "prov/composite.h" +#include "prov/provider_ctx.h" + +/* + * Encode the composite public key (mldsaPK || tradPK) into *out. + * Returns the total byte length on success, 0 on error. + * If out is NULL, only the length is returned (no allocation). + */ +__owur int ossl_composite_i2d_pubkey(const COMPOSITE_KEY *key, + unsigned char **out); + +/* + * Encode the composite private key (mldsaSeed[32] || tradSK) into *out. + * Returns the total byte length on success, 0 on error. + * If out is NULL, only the length is returned (no allocation). + */ +__owur int ossl_composite_i2d_prvkey(const COMPOSITE_KEY *key, + unsigned char **out); + +/* + * Print a human-readable description of the composite key to |out|. + * |selection| is an OSSL_KEYMGMT_SELECT_* mask. + */ +__owur int ossl_composite_key_to_text(BIO *out, const COMPOSITE_KEY *key, + int selection); + +/* + * Decode a composite public key from its wire format (mldsaPK || tradPK). + * |pk|/|pk_len|: raw concatenated public key bytes (BIT STRING content + * from SubjectPublicKeyInfo). + * |ml_dsa_evp_type|: EVP_PKEY_ML_DSA_44/65/87 selecting the ML-DSA variant. + * |classic_alg|: "RSA", "EC", "ED25519", or "ED448". + * |ec_curve|: curve name for EC (e.g. "P-256"), NULL for non-EC. + * |provctx|: provider context for library context and propq. + * |propq|: property query string (may be NULL). + * Returns a newly allocated COMPOSITE_KEY on success, NULL on failure. + */ +__owur COMPOSITE_KEY *ossl_composite_d2i_pubkey(const unsigned char *pk, + int pk_len, + int ml_dsa_evp_type, + const char *classic_alg, + const char *ec_curve, + PROV_CTX *provctx, + const char *propq); + +/* + * Decode a composite private key from its wire format (mldsaSeed[32] || tradSK). + * |priv|/|priv_len|: raw concatenated private key bytes. + * Other params: same as ossl_composite_d2i_pubkey. + * Returns a newly allocated COMPOSITE_KEY on success, NULL on failure. + */ +__owur COMPOSITE_KEY *ossl_composite_d2i_prvkey(const unsigned char *priv, + int priv_len, + int ml_dsa_evp_type, + const char *classic_alg, + const char *ec_curve, + PROV_CTX *provctx, + const char *propq); + +#endif /* OPENSSL_NO_COMPOSITE */ +#endif /* PROV_COMPOSITE_CODECS_H */ diff --git a/providers/implementations/include/prov/decoders.h b/providers/implementations/include/prov/decoders.h index 84a822f04e927..420b189a01027 100644 --- a/providers/implementations/include/prov/decoders.h +++ b/providers/implementations/include/prov/decoders.h @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/drbg.h b/providers/implementations/include/prov/drbg.h index 42fd8212aca44..5a4adfb43af6c 100644 --- a/providers/implementations/include/prov/drbg.h +++ b/providers/implementations/include/prov/drbg.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/eckem.h b/providers/implementations/include/prov/eckem.h index 9fa48323b2657..8911027f731b7 100644 --- a/providers/implementations/include/prov/eckem.h +++ b/providers/implementations/include/prov/eckem.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/ecx.h b/providers/implementations/include/prov/ecx.h index 455554a5a4f3f..b573852cc88b6 100644 --- a/providers/implementations/include/prov/ecx.h +++ b/providers/implementations/include/prov/ecx.h @@ -1,5 +1,5 @@ /* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/endecoder_local.h b/providers/implementations/include/prov/endecoder_local.h index e6c2eaff27692..6343a4b20f3ff 100644 --- a/providers/implementations/include/prov/endecoder_local.h +++ b/providers/implementations/include/prov/endecoder_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/file_store_local.h b/providers/implementations/include/prov/file_store_local.h index 61047ba2ecd2f..2196d4d2c699a 100644 --- a/providers/implementations/include/prov/file_store_local.h +++ b/providers/implementations/include/prov/file_store_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h index 2b0782bd0b46a..d059ac2affa7f 100644 --- a/providers/implementations/include/prov/implementations.h +++ b/providers/implementations/include/prov/implementations.h @@ -266,6 +266,10 @@ extern const OSSL_DISPATCH ossl_aes192gcm_siv_functions[]; extern const OSSL_DISPATCH ossl_aes256gcm_siv_functions[]; #endif /* OPENSSL_NO_SIV */ +#ifndef OPENSSL_NO_ASCON128 +extern const OSSL_DISPATCH ossl_ascon_aead128_functions[]; +#endif /* OPENSSL_NO_ASCON128 */ + /* MACs */ extern const OSSL_DISPATCH ossl_blake2bmac_functions[]; extern const OSSL_DISPATCH ossl_blake2smac_functions[]; @@ -358,9 +362,11 @@ extern const OSSL_DISPATCH ossl_ml_kem_768_keymgmt_functions[]; extern const OSSL_DISPATCH ossl_ml_kem_1024_keymgmt_functions[]; #ifndef OPENSSL_NO_EC #ifndef OPENSSL_NO_ECX +extern const OSSL_DISPATCH ossl_mlx_x25519_512_kem_kmgmt_functions[]; extern const OSSL_DISPATCH ossl_mlx_x25519_kem_kmgmt_functions[]; extern const OSSL_DISPATCH ossl_mlx_x448_kem_kmgmt_functions[]; #endif +extern const OSSL_DISPATCH ossl_mlx_p256_512_kem_kmgmt_functions[]; extern const OSSL_DISPATCH ossl_mlx_p256_kem_kmgmt_functions[]; extern const OSSL_DISPATCH ossl_mlx_p384_kem_kmgmt_functions[]; #ifndef OPENSSL_NO_SM2 @@ -470,6 +476,45 @@ extern const OSSL_DISPATCH ossl_slh_dsa_shake_256s_signature_functions[]; extern const OSSL_DISPATCH ossl_slh_dsa_shake_256f_signature_functions[]; #endif /* OPENSSL_NO_SLH_DSA */ +/* Composite signature algorithms (draft-ietf-lamps-pq-composite-sigs) */ +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pss_sha256_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pkcs15_sha256_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ed25519_sha512_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ecdsa_p256_sha256_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pss_sha512_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pkcs15_sha512_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pss_sha512_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pkcs15_sha512_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p256_sha512_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p384_sha512_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_brainpoolP256r1_sha512_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ed25519_sha512_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p384_sha512_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_brainpoolP384r1_sha512_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ed448_shake256_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa3072_pss_sha512_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa4096_pss_sha512_signature_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p521_sha512_signature_functions[]; +/* Composite key management */ +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pss_sha256_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pkcs15_sha256_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ed25519_sha512_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ecdsa_p256_sha256_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pss_sha512_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pkcs15_sha512_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pss_sha512_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pkcs15_sha512_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p256_sha512_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p384_sha512_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_brainpoolP256r1_sha512_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ed25519_sha512_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p384_sha512_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_brainpoolP384r1_sha512_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ed448_shake256_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa3072_pss_sha512_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa4096_pss_sha512_keymgmt_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p521_sha512_keymgmt_functions[]; + /* Asym Cipher */ extern const OSSL_DISPATCH ossl_rsa_asym_cipher_functions[]; #ifndef OPENSSL_NO_SM2 @@ -653,6 +698,150 @@ extern const OSSL_DISPATCH ossl_ml_dsa_87_to_SubjectPublicKeyInfo_pem_encoder_fu extern const OSSL_DISPATCH ossl_ml_dsa_87_to_OSSL_current_der_encoder_functions[]; extern const OSSL_DISPATCH ossl_ml_dsa_87_to_text_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pss_sha256_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pss_sha256_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pss_sha256_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pss_sha256_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pss_sha256_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pss_sha256_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pss_sha256_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pkcs15_sha256_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pkcs15_sha256_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pkcs15_sha256_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pkcs15_sha256_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pkcs15_sha256_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pkcs15_sha256_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_rsa2048_pkcs15_sha256_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa44_ed25519_sha512_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ed25519_sha512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ed25519_sha512_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ed25519_sha512_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ed25519_sha512_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ed25519_sha512_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ed25519_sha512_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa44_ecdsa_p256_sha256_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ecdsa_p256_sha256_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ecdsa_p256_sha256_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ecdsa_p256_sha256_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ecdsa_p256_sha256_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ecdsa_p256_sha256_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa44_ecdsa_p256_sha256_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pss_sha512_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pss_sha512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pss_sha512_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pss_sha512_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pss_sha512_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pss_sha512_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pss_sha512_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pkcs15_sha512_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pkcs15_sha512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pkcs15_sha512_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pkcs15_sha512_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pkcs15_sha512_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pkcs15_sha512_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa3072_pkcs15_sha512_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pss_sha512_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pss_sha512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pss_sha512_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pss_sha512_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pss_sha512_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pss_sha512_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pss_sha512_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pkcs15_sha512_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pkcs15_sha512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pkcs15_sha512_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pkcs15_sha512_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pkcs15_sha512_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pkcs15_sha512_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_rsa4096_pkcs15_sha512_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p256_sha512_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p256_sha512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p256_sha512_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p256_sha512_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p256_sha512_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p256_sha512_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p256_sha512_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p384_sha512_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p384_sha512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p384_sha512_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p384_sha512_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p384_sha512_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p384_sha512_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_p384_sha512_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_brainpoolP256r1_sha512_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_brainpoolP256r1_sha512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_brainpoolP256r1_sha512_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_brainpoolP256r1_sha512_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_brainpoolP256r1_sha512_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_brainpoolP256r1_sha512_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ecdsa_brainpoolP256r1_sha512_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa65_ed25519_sha512_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ed25519_sha512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ed25519_sha512_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ed25519_sha512_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ed25519_sha512_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ed25519_sha512_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa65_ed25519_sha512_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p384_sha512_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p384_sha512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p384_sha512_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p384_sha512_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p384_sha512_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p384_sha512_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p384_sha512_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_brainpoolP384r1_sha512_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_brainpoolP384r1_sha512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_brainpoolP384r1_sha512_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_brainpoolP384r1_sha512_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_brainpoolP384r1_sha512_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_brainpoolP384r1_sha512_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_brainpoolP384r1_sha512_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa87_ed448_shake256_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ed448_shake256_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ed448_shake256_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ed448_shake256_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ed448_shake256_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ed448_shake256_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ed448_shake256_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa87_rsa3072_pss_sha512_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa3072_pss_sha512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa3072_pss_sha512_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa3072_pss_sha512_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa3072_pss_sha512_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa3072_pss_sha512_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa3072_pss_sha512_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa87_rsa4096_pss_sha512_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa4096_pss_sha512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa4096_pss_sha512_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa4096_pss_sha512_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa4096_pss_sha512_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa4096_pss_sha512_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_rsa4096_pss_sha512_to_text_encoder_functions[]; + +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p521_sha512_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p521_sha512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p521_sha512_to_PrivateKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p521_sha512_to_PrivateKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p521_sha512_to_SubjectPublicKeyInfo_der_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p521_sha512_to_SubjectPublicKeyInfo_pem_encoder_functions[]; +extern const OSSL_DISPATCH ossl_mldsa87_ecdsa_p521_sha512_to_text_encoder_functions[]; + extern const OSSL_DISPATCH ossl_slh_dsa_sha2_128s_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; extern const OSSL_DISPATCH ossl_slh_dsa_sha2_128f_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; extern const OSSL_DISPATCH ossl_slh_dsa_sha2_192s_to_EncryptedPrivateKeyInfo_der_encoder_functions[]; @@ -885,6 +1074,44 @@ extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ml_dsa_65_decoder_fu extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_ml_dsa_87_decoder_functions[]; extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ml_dsa_87_decoder_functions[]; +/* Composite decoders (all 18 variants) */ +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa44_rsa2048_pss_sha256_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa44_rsa2048_pss_sha256_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa44_rsa2048_pkcs15_sha256_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa44_rsa2048_pkcs15_sha256_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa44_ed25519_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa44_ed25519_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa44_ecdsa_p256_sha256_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa44_ecdsa_p256_sha256_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa65_rsa3072_pss_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa65_rsa3072_pss_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa65_rsa3072_pkcs15_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa65_rsa3072_pkcs15_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa65_rsa4096_pss_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa65_rsa4096_pss_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa65_rsa4096_pkcs15_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa65_rsa4096_pkcs15_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa65_ecdsa_p256_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa65_ecdsa_p256_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa65_ecdsa_p384_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa65_ecdsa_p384_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa65_ecdsa_brainpoolP256r1_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa65_ecdsa_brainpoolP256r1_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa65_ed25519_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa65_ed25519_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa87_ecdsa_p384_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa87_ecdsa_p384_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa87_ecdsa_brainpoolP384r1_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa87_ecdsa_brainpoolP384r1_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa87_ed448_shake256_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa87_ed448_shake256_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa87_rsa3072_pss_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa87_rsa3072_pss_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa87_rsa4096_pss_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa87_rsa4096_pss_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_mldsa87_ecdsa_p521_sha512_decoder_functions[]; +extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_mldsa87_ecdsa_p521_sha512_decoder_functions[]; + extern const OSSL_DISPATCH ossl_generic_skeymgmt_functions[]; extern const OSSL_DISPATCH ossl_aes_skeymgmt_functions[]; diff --git a/providers/implementations/include/prov/kdfexchange.h b/providers/implementations/include/prov/kdfexchange.h index 497e4736d2a9a..4ccf74871ef2d 100644 --- a/providers/implementations/include/prov/kdfexchange.h +++ b/providers/implementations/include/prov/kdfexchange.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/macsignature.h b/providers/implementations/include/prov/macsignature.h index d1cebdacf091f..843a67b4b11b6 100644 --- a/providers/implementations/include/prov/macsignature.h +++ b/providers/implementations/include/prov/macsignature.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/ml_dsa.h b/providers/implementations/include/prov/ml_dsa.h index d94dbd55eadbd..b26fc15cc8b40 100644 --- a/providers/implementations/include/prov/ml_dsa.h +++ b/providers/implementations/include/prov/ml_dsa.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/ml_dsa_codecs.h b/providers/implementations/include/prov/ml_dsa_codecs.h index f440dc3bc1bda..49c34420adcae 100644 --- a/providers/implementations/include/prov/ml_dsa_codecs.h +++ b/providers/implementations/include/prov/ml_dsa_codecs.h @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/ml_kem.h b/providers/implementations/include/prov/ml_kem.h index 33e0efc28bcca..3d291ac7a768d 100644 --- a/providers/implementations/include/prov/ml_kem.h +++ b/providers/implementations/include/prov/ml_kem.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/ml_kem_codecs.h b/providers/implementations/include/prov/ml_kem_codecs.h index ad72c9f5d7809..463e1f0888785 100644 --- a/providers/implementations/include/prov/ml_kem_codecs.h +++ b/providers/implementations/include/prov/ml_kem_codecs.h @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/names.h b/providers/implementations/include/prov/names.h index 09146dd01ed72..b11d260f4e1f8 100644 --- a/providers/implementations/include/prov/names.h +++ b/providers/implementations/include/prov/names.h @@ -135,6 +135,7 @@ #define PROV_NAMES_ARIA_256_CTR "ARIA-256-CTR:1.2.410.200046.1.1.15" #define PROV_NAMES_ARIA_192_CTR "ARIA-192-CTR:1.2.410.200046.1.1.10" #define PROV_NAMES_ARIA_128_CTR "ARIA-128-CTR:1.2.410.200046.1.1.5" +#define PROV_NAMES_ASCON_AEAD128 "ASCON-AEAD128:ascon-aead128" #define PROV_NAMES_CAMELLIA_256_ECB "CAMELLIA-256-ECB:0.3.4401.5.3.1.9.41" #define PROV_NAMES_CAMELLIA_192_ECB "CAMELLIA-192-ECB:0.3.4401.5.3.1.9.21" #define PROV_NAMES_CAMELLIA_128_ECB "CAMELLIA-128-ECB:0.3.4401.5.3.1.9.1" @@ -434,10 +435,14 @@ #define PROV_DESCS_ML_KEM_768 "OpenSSL ML-KEM-768 implementation" #define PROV_NAMES_ML_KEM_1024 "ML-KEM-1024:MLKEM1024:id-alg-ml-kem-1024:2.16.840.1.101.3.4.4.3" #define PROV_DESCS_ML_KEM_1024 "OpenSSL ML-KEM-1024 implementation" +#define PROV_NAMES_MLKEM512X25519 "MLKEM512X25519" +#define PROV_DESCS_MLKEM512X25519 "ML-KEM-512+X25519 TLS hybrid implementation" #define PROV_NAMES_X25519MLKEM768 "X25519MLKEM768" #define PROV_DESCS_X25519MLKEM768 "X25519+ML-KEM-768 TLS hybrid implementation" #define PROV_NAMES_X448MLKEM1024 "X448MLKEM1024" #define PROV_DESCS_X448MLKEM1024 "X448+ML-KEM-1024 TLS hybrid implementation" +#define PROV_NAMES_SecP256r1MLKEM512 "SecP256r1MLKEM512" +#define PROV_DESCS_SecP256r1MLKEM512 "P-256+ML-KEM-512 TLS hybrid implementation" #define PROV_NAMES_SecP256r1MLKEM768 "SecP256r1MLKEM768" #define PROV_DESCS_SecP256r1MLKEM768 "P-256+ML-KEM-768 TLS hybrid implementation" #define PROV_NAMES_SecP384r1MLKEM1024 "SecP384r1MLKEM1024" @@ -469,4 +474,78 @@ #define PROV_DESCS_SLH_DSA_SHAKE_256S "OpenSSL SLH-DSA-SHAKE-256s implementation" #define PROV_DESCS_SLH_DSA_SHAKE_256F "OpenSSL SLH-DSA-SHAKE-256f implementation" +/* Composite signature algorithms (draft-ietf-lamps-pq-composite-sigs) */ +#define PROV_NAMES_MLDSA44_RSA2048_PSS_SHA256 \ + "ML-DSA-44-RSA2048-PSS-SHA256:id-mldsa44-rsa2048-pss-sha256:1.3.6.1.5.5.7.6.37" +#define PROV_DESCS_MLDSA44_RSA2048_PSS_SHA256 \ + "OpenSSL ML-DSA-44-RSA2048-PSS-SHA256 composite implementation" +#define PROV_NAMES_MLDSA44_RSA2048_PKCS15_SHA256 \ + "ML-DSA-44-RSA2048-PKCS15-SHA256:id-mldsa44-rsa2048-pkcs15-sha256:1.3.6.1.5.5.7.6.38" +#define PROV_DESCS_MLDSA44_RSA2048_PKCS15_SHA256 \ + "OpenSSL ML-DSA-44-RSA2048-PKCS15-SHA256 composite implementation" +#define PROV_NAMES_MLDSA44_ED25519_SHA512 \ + "ML-DSA-44-Ed25519-SHA512:id-mldsa44-ed25519-sha512:1.3.6.1.5.5.7.6.39" +#define PROV_DESCS_MLDSA44_ED25519_SHA512 \ + "OpenSSL ML-DSA-44-Ed25519-SHA512 composite implementation" +#define PROV_NAMES_MLDSA44_ECDSA_P256_SHA256 \ + "ML-DSA-44-ECDSA-P256-SHA256:id-mldsa44-ecdsa-p256-sha256:1.3.6.1.5.5.7.6.40" +#define PROV_DESCS_MLDSA44_ECDSA_P256_SHA256 \ + "OpenSSL ML-DSA-44-ECDSA-P256-SHA256 composite implementation" +#define PROV_NAMES_MLDSA65_RSA3072_PSS_SHA512 \ + "ML-DSA-65-RSA3072-PSS-SHA512:id-mldsa65-rsa3072-pss-sha512:1.3.6.1.5.5.7.6.41" +#define PROV_DESCS_MLDSA65_RSA3072_PSS_SHA512 \ + "OpenSSL ML-DSA-65-RSA3072-PSS-SHA512 composite implementation" +#define PROV_NAMES_MLDSA65_RSA3072_PKCS15_SHA512 \ + "ML-DSA-65-RSA3072-PKCS15-SHA512:id-mldsa65-rsa3072-pkcs15-sha512:1.3.6.1.5.5.7.6.42" +#define PROV_DESCS_MLDSA65_RSA3072_PKCS15_SHA512 \ + "OpenSSL ML-DSA-65-RSA3072-PKCS15-SHA512 composite implementation" +#define PROV_NAMES_MLDSA65_RSA4096_PSS_SHA512 \ + "ML-DSA-65-RSA4096-PSS-SHA512:id-mldsa65-rsa4096-pss-sha512:1.3.6.1.5.5.7.6.43" +#define PROV_DESCS_MLDSA65_RSA4096_PSS_SHA512 \ + "OpenSSL ML-DSA-65-RSA4096-PSS-SHA512 composite implementation" +#define PROV_NAMES_MLDSA65_RSA4096_PKCS15_SHA512 \ + "ML-DSA-65-RSA4096-PKCS15-SHA512:id-mldsa65-rsa4096-pkcs15-sha512:1.3.6.1.5.5.7.6.44" +#define PROV_DESCS_MLDSA65_RSA4096_PKCS15_SHA512 \ + "OpenSSL ML-DSA-65-RSA4096-PKCS15-SHA512 composite implementation" +#define PROV_NAMES_MLDSA65_ECDSA_P256_SHA512 \ + "ML-DSA-65-ECDSA-P256-SHA512:id-mldsa65-ecdsa-p256-sha512:1.3.6.1.5.5.7.6.45" +#define PROV_DESCS_MLDSA65_ECDSA_P256_SHA512 \ + "OpenSSL ML-DSA-65-ECDSA-P256-SHA512 composite implementation" +#define PROV_NAMES_MLDSA65_ECDSA_P384_SHA512 \ + "ML-DSA-65-ECDSA-P384-SHA512:id-mldsa65-ecdsa-p384-sha512:1.3.6.1.5.5.7.6.46" +#define PROV_DESCS_MLDSA65_ECDSA_P384_SHA512 \ + "OpenSSL ML-DSA-65-ECDSA-P384-SHA512 composite implementation" +#define PROV_NAMES_MLDSA65_ECDSA_BRAINPOOLP256R1_SHA512 \ + "ML-DSA-65-ECDSA-brainpoolP256r1-SHA512:id-mldsa65-ecdsa-brainpoolP256r1-sha512:1.3.6.1.5.5.7.6.47" +#define PROV_DESCS_MLDSA65_ECDSA_BRAINPOOLP256R1_SHA512 \ + "OpenSSL ML-DSA-65-ECDSA-brainpoolP256r1-SHA512 composite implementation" +#define PROV_NAMES_MLDSA65_ED25519_SHA512 \ + "ML-DSA-65-Ed25519-SHA512:id-mldsa65-ed25519-sha512:1.3.6.1.5.5.7.6.48" +#define PROV_DESCS_MLDSA65_ED25519_SHA512 \ + "OpenSSL ML-DSA-65-Ed25519-SHA512 composite implementation" +#define PROV_NAMES_MLDSA87_ECDSA_P384_SHA512 \ + "ML-DSA-87-ECDSA-P384-SHA512:id-mldsa87-ecdsa-p384-sha512:1.3.6.1.5.5.7.6.49" +#define PROV_DESCS_MLDSA87_ECDSA_P384_SHA512 \ + "OpenSSL ML-DSA-87-ECDSA-P384-SHA512 composite implementation" +#define PROV_NAMES_MLDSA87_ECDSA_BRAINPOOLP384R1_SHA512 \ + "ML-DSA-87-ECDSA-brainpoolP384r1-SHA512:id-mldsa87-ecdsa-brainpoolp384r1-sha512:1.3.6.1.5.5.7.6.50" +#define PROV_DESCS_MLDSA87_ECDSA_BRAINPOOLP384R1_SHA512 \ + "OpenSSL ML-DSA-87-ECDSA-brainpoolP384r1-SHA512 composite implementation" +#define PROV_NAMES_MLDSA87_ED448_SHAKE256 \ + "ML-DSA-87-Ed448-SHAKE256:id-mldsa87-ed448-shake256:1.3.6.1.5.5.7.6.51" +#define PROV_DESCS_MLDSA87_ED448_SHAKE256 \ + "OpenSSL ML-DSA-87-Ed448-SHAKE256 composite implementation" +#define PROV_NAMES_MLDSA87_RSA3072_PSS_SHA512 \ + "ML-DSA-87-RSA3072-PSS-SHA512:id-mldsa87-rsa3072-pss-sha512:1.3.6.1.5.5.7.6.52" +#define PROV_DESCS_MLDSA87_RSA3072_PSS_SHA512 \ + "OpenSSL ML-DSA-87-RSA3072-PSS-SHA512 composite implementation" +#define PROV_NAMES_MLDSA87_RSA4096_PSS_SHA512 \ + "ML-DSA-87-RSA4096-PSS-SHA512:id-mldsa87-rsa4096-pss-sha512:1.3.6.1.5.5.7.6.53" +#define PROV_DESCS_MLDSA87_RSA4096_PSS_SHA512 \ + "OpenSSL ML-DSA-87-RSA4096-PSS-SHA512 composite implementation" +#define PROV_NAMES_MLDSA87_ECDSA_P521_SHA512 \ + "ML-DSA-87-ECDSA-P521-SHA512:id-mldsa87-ecdsa-p521-sha512:1.3.6.1.5.5.7.6.54" +#define PROV_DESCS_MLDSA87_ECDSA_P521_SHA512 \ + "OpenSSL ML-DSA-87-ECDSA-P521-SHA512 composite implementation" + #endif /* !defined(OSSL_PROVIDERS_IMPLEMENTATIONS_INCLUDE_PROV_NAMES_H) */ diff --git a/providers/implementations/include/prov/seeding.h b/providers/implementations/include/prov/seeding.h index 7bdc0cbe5d8dc..47989f0814613 100644 --- a/providers/implementations/include/prov/seeding.h +++ b/providers/implementations/include/prov/seeding.h @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/include/prov/skeymgmt_lcl.h b/providers/implementations/include/prov/skeymgmt_lcl.h index 7e35b2cc9ea5c..946136294bc12 100644 --- a/providers/implementations/include/prov/skeymgmt_lcl.h +++ b/providers/implementations/include/prov/skeymgmt_lcl.h @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -16,5 +16,8 @@ OSSL_FUNC_skeymgmt_import_fn generic_import; OSSL_FUNC_skeymgmt_export_fn generic_export; OSSL_FUNC_skeymgmt_free_fn generic_free; OSSL_FUNC_skeymgmt_imp_settable_params_fn generic_imp_settable_params; +OSSL_FUNC_skeymgmt_get_key_id_fn generic_get_key_id; +OSSL_FUNC_skeymgmt_get_local_keyid_fn generic_get_local_keyid; +OSSL_FUNC_skeymgmt_get_algorithm_id_fn generic_get_algorithm_id; #endif diff --git a/providers/implementations/kdfs/krb5kdf.c b/providers/implementations/kdfs/krb5kdf.c index 15d9e0a95f972..4ebe3825d5ca5 100644 --- a/providers/implementations/kdfs/krb5kdf.c +++ b/providers/implementations/kdfs/krb5kdf.c @@ -416,7 +416,7 @@ static int KRB5KDF(const EVP_CIPHER *cipher, goto out; } - if (constant_len > blocksize) { + if (constant_len == 0 || constant_len > blocksize) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONSTANT_LENGTH); ret = 0; goto out; diff --git a/providers/implementations/kdfs/x942kdf.c b/providers/implementations/kdfs/x942kdf.c index 3565243cc9e83..10466c132da92 100644 --- a/providers/implementations/kdfs/x942kdf.c +++ b/providers/implementations/kdfs/x942kdf.c @@ -260,9 +260,11 @@ x942_encode_otherinfo(size_t keylen, goto err; *out_ctr = (pcounter + 2); *der = der_buf; + der_buf = NULL; *der_len = der_buflen; ret = 1; err: + OPENSSL_free(der_buf); WPACKET_cleanup(&pkt); return ret; } diff --git a/providers/implementations/kem/ml_kem_kem.c b/providers/implementations/kem/ml_kem_kem.c index df3bcb5cd84d4..456b15db3a8be 100644 --- a/providers/implementations/kem/ml_kem_kem.c +++ b/providers/implementations/kem/ml_kem_kem.c @@ -128,6 +128,7 @@ static int ml_kem_set_ctx_params(void *vctx, const OSSL_PARAM params[]) /* Possibly, but much less likely wrong type */ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH); + OPENSSL_cleanse((void *)ctx->entropy_buf, sizeof(ctx->entropy_buf)); ctx->entropy = NULL; return 0; } diff --git a/providers/implementations/kem/mlx_kem.c b/providers/implementations/kem/mlx_kem.c index 376b3342ddfa8..a917fa93d5ca7 100644 --- a/providers/implementations/kem/mlx_kem.c +++ b/providers/implementations/kem/mlx_kem.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -118,7 +118,7 @@ static int mlx_kem_encapsulate(void *vctx, unsigned char *ctext, size_t *clen, if (!mlx_kem_have_pubkey(key)) { ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY); - goto end; + return 0; } encap_clen = key->minfo->ctext_bytes + key->xinfo->pubkey_bytes; encap_slen = ML_KEM_SHARED_SECRET_BYTES + key->xinfo->shsec_bytes; @@ -236,6 +236,10 @@ static int mlx_kem_encapsulate(void *vctx, unsigned char *ctext, size_t *clen, ret = 1; end: + /* Erase any partial shared secret on failure */ + if (ret == 0) + OPENSSL_cleanse(shsec, + ML_KEM_SHARED_SECRET_BYTES + key->xinfo->shsec_bytes); EVP_PKEY_free(xkey); EVP_PKEY_CTX_free(ctx); return ret; @@ -324,6 +328,10 @@ static int mlx_kem_decapsulate(void *vctx, uint8_t *shsec, size_t *slen, ret = 1; end: + /* Erase any partial shared secret on failure */ + if (ret == 0) + OPENSSL_cleanse(shsec, + ML_KEM_SHARED_SECRET_BYTES + key->xinfo->shsec_bytes); EVP_PKEY_CTX_free(ctx); EVP_PKEY_free(xkey); return ret; diff --git a/providers/implementations/kem/rsa_kem.c b/providers/implementations/kem/rsa_kem.c index ab28a3a1a2808..675409ba33def 100644 --- a/providers/implementations/kem/rsa_kem.c +++ b/providers/implementations/kem/rsa_kem.c @@ -140,6 +140,7 @@ static int rsakem_init(void *vprsactx, void *vrsa, const char *desc) { PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx; + const BIGNUM *e = NULL; int protect = 0; if (!ossl_prov_is_running()) @@ -155,6 +156,18 @@ static int rsakem_init(void *vprsactx, void *vrsa, RSA_free(prsactx->rsa); prsactx->rsa = vrsa; + /* + * Reject the trivial public exponent e <= 1. The FIPS module enforces the + * full SP 800-56B §6.4.1.1 constraints via ossl_fips_ind_rsa_key_check() + * below; non-FIPS callers wanting the complete §6.4.2 vetting can use + * EVP_PKEY_public_check(). + */ + RSA_get0_key(prsactx->rsa, NULL, &e, NULL); + if (e == NULL || BN_cmp(e, BN_value_one()) <= 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); + return 0; + } + OSSL_FIPS_IND_SET_APPROVED(prsactx) if (!rsakem_set_ctx_params(prsactx, params)) return 0; @@ -387,6 +400,44 @@ static int rsasve_recover(PROV_RSA_CTX *prsactx, return 0; } +#ifndef FIPS_MODULE + /* + * Reject clearly degenerate ciphertexts, c in {0, 1, n-1}. + * + * SP 800-56B Rev 2, 7.1.2.1 requires RSADP to enforce 1 < c < n-1. In a + * FIPS build that bound is applied by the RSADP primitive itself (see + * crypto/rsa/rsa_ossl.c, guarded by FIPS_MODULE), where it is also needed + * for KTS-OAEP; the primitive does not apply it in a non-FIPS build, so + * enforce it here for RSASVE. Raise the same errors as the primitive so + * the behaviour matches in both builds; keep the two sites in step. + */ + { + const BIGNUM *n = RSA_get0_n(prsactx->rsa); + BIGNUM *c = BN_new(); + BIGNUM *nminus1 = BN_new(); + int reason = 0; + + if (n == NULL || c == NULL || nminus1 == NULL + || BN_bin2bn(in, (int)inlen, c) == NULL + || BN_copy(nminus1, n) == NULL + || !BN_sub_word(nminus1, 1)) { + BN_free(c); + BN_free(nminus1); + return 0; + } + if (BN_ucmp(c, BN_value_one()) <= 0) + reason = RSA_R_DATA_TOO_SMALL; + else if (BN_ucmp(c, nminus1) >= 0) + reason = RSA_R_DATA_TOO_LARGE_FOR_MODULUS; + BN_free(c); + BN_free(nminus1); + if (reason != 0) { + ERR_raise(ERR_LIB_RSA, reason); + return 0; + } + } +#endif + /* Step (3): out = RSADP((n,d), in) */ ret = RSA_private_decrypt((int)inlen, in, out, prsactx->rsa, RSA_NO_PADDING); if (ret > 0 && outlen != NULL) diff --git a/providers/implementations/kem/template_kem.c b/providers/implementations/kem/template_kem.c index 448b1caf4ebdd..06ecf7c5d7dcb 100644 --- a/providers/implementations/kem/template_kem.c +++ b/providers/implementations/kem/template_kem.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/keymgmt/build.info b/providers/implementations/keymgmt/build.info index 347904c7e7580..f13d0d18aa1ab 100644 --- a/providers/implementations/keymgmt/build.info +++ b/providers/implementations/keymgmt/build.info @@ -14,6 +14,7 @@ $ML_DSA_GOAL=../../libdefault.a ../../libfips.a $ML_KEM_GOAL=../../libdefault.a ../../libfips.a $TLS_ML_KEM_HYBRID_GOAL=../../libdefault.a ../../libfips.a $SLH_DSA_GOAL=../../libdefault.a ../../libfips.a +$COMPOSITE_GOAL=../../libdefault.a IF[{- !$disabled{dh} -}] SOURCE[$DH_GOAL]=dh_kmgmt.c @@ -69,3 +70,8 @@ ENDIF IF[{- !$disabled{'slh-dsa'} -}] SOURCE[$SLH_DSA_GOAL]=slh_dsa_kmgmt.c ENDIF + +IF[{- !$disabled{'ml-dsa'} -}] + SOURCE[$COMPOSITE_GOAL]=composite_kmgmt.c + DEPEND[composite_kmgmt.o]=../../common/include/prov/composite.h +ENDIF \ No newline at end of file diff --git a/providers/implementations/keymgmt/composite_kmgmt.c b/providers/implementations/keymgmt/composite_kmgmt.c new file mode 100644 index 0000000000000..88199df7244be --- /dev/null +++ b/providers/implementations/keymgmt/composite_kmgmt.c @@ -0,0 +1,1084 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "crypto/evp.h" +#include "crypto/ml_dsa.h" +#include "internal/param_build_set.h" +#include "prov/implementations.h" +#include "prov/providercommon.h" +#include "prov/provider_ctx.h" +#include "prov/ml_dsa.h" +#include "prov/composite.h" +#include "providers/implementations/keymgmt/composite_kmgmt.inc" + +/* + * Per-algorithm generation context. + * Allocated in composite_gen_init(), freed in composite_gen_cleanup(). + */ +typedef struct { + PROV_CTX *provctx; /* full provider context (not just libctx) */ + char *propq; + /* Algorithm-specific constants are passed directly to composite_gen() + * from the per-algorithm wrapper in MAKE_KEYMGMT_FUNCTIONS; they are + * compile-time literals and do not need to live in the context. */ + uint8_t *priv_seed; /* optional: mldsaSeed||tradSK for deterministic gen */ + size_t priv_seed_len; +} COMPOSITE_GEN_CTX; + +/* Forward declarations of all static keymgmt functions */ +static OSSL_FUNC_keymgmt_free_fn composite_free_key; +static OSSL_FUNC_keymgmt_has_fn composite_has; +static OSSL_FUNC_keymgmt_match_fn composite_match; +static OSSL_FUNC_keymgmt_dup_fn composite_dup_key; +static OSSL_FUNC_keymgmt_validate_fn composite_validate; +static OSSL_FUNC_keymgmt_export_fn composite_export; +static OSSL_FUNC_keymgmt_import_types_fn composite_import_types; +static OSSL_FUNC_keymgmt_export_types_fn composite_export_types; +static OSSL_FUNC_keymgmt_gettable_params_fn composite_gettable_params; +static OSSL_FUNC_keymgmt_get_params_fn composite_get_params; +static OSSL_FUNC_keymgmt_load_fn composite_load; +static OSSL_FUNC_keymgmt_gen_init_fn composite_gen_init; +static OSSL_FUNC_keymgmt_gen_cleanup_fn composite_gen_cleanup; +static OSSL_FUNC_keymgmt_gen_set_params_fn composite_gen_set_params; +static OSSL_FUNC_keymgmt_gen_settable_params_fn composite_gen_settable_params; + +/* ========================================================================= + * Key management helpers + * ========================================================================= */ + +static COMPOSITE_KEY *ossl_composite_key_new(OSSL_LIB_CTX *libctx, + const char *propq, + int ml_dsa_evp_type) +{ + COMPOSITE_KEY *key = OPENSSL_zalloc(sizeof(*key)); + + if (key == NULL) + return NULL; + key->ml_dsa_key = ossl_ml_dsa_key_new(libctx, propq, ml_dsa_evp_type); + if (key->ml_dsa_key == NULL) { + OPENSSL_free(key); + return NULL; + } + return key; +} + +void ossl_composite_key_free(COMPOSITE_KEY *key) +{ + if (key == NULL) + return; + ossl_ml_dsa_key_free(key->ml_dsa_key); + EVP_PKEY_free(key->classic_key); + OPENSSL_free(key); +} + +/* True only if the ML-DSA half satisfies selection AND the classic half is present. */ +static int ossl_composite_key_has(const COMPOSITE_KEY *key, int selection) +{ + if (!ossl_ml_dsa_key_has(key->ml_dsa_key, selection)) + return 0; + if (key->classic_key == NULL) + return 0; + return 1; +} + +/* + * Approximate combined public key length in bytes (ML-DSA pk_len plus + * ceil(classic bits / 8)). Not the exact DER/point-encoded size — only + * valid for reporting OSSL_PKEY_PARAM_BITS, never for buffer sizing. + */ +static size_t ossl_composite_key_get_pub_len(const COMPOSITE_KEY *key) +{ + size_t ml_dsa_len = ossl_ml_dsa_key_get_pub_len(key->ml_dsa_key); + + if (key->classic_key == NULL) + return ml_dsa_len; // if there is not classic key, composite is malformed + return ml_dsa_len + (size_t)((EVP_PKEY_get_bits(key->classic_key) + 7) / 8); +} + +/* + * Security bits of the composite = minimum of ML-DSA collision strength and + * the classic component's security bits. + */ +static int ossl_composite_key_get_security_bits(const COMPOSITE_KEY *key) +{ + size_t ml_dsa_sec = ossl_ml_dsa_key_get_collision_strength_bits(key->ml_dsa_key); + int classic_sec = (key->classic_key != NULL) + ? EVP_PKEY_get_security_bits(key->classic_key) + : 0; + + if (classic_sec <= 0) + return (int)ml_dsa_sec; + return (int)ml_dsa_sec < classic_sec ? (int)ml_dsa_sec : classic_sec; +} + +/* + * Maximum composite signature size: ML-DSA fixed sig_len plus the classic + * component's maximum signature size. + */ +static int ossl_composite_key_get_max_size(const COMPOSITE_KEY *key) +{ + size_t ml_dsa_sig = ossl_ml_dsa_key_get_sig_len(key->ml_dsa_key); + int classic_sig = (key->classic_key != NULL) + ? EVP_PKEY_get_size(key->classic_key) + : 0; + + return (int)ml_dsa_sig + (classic_sig > 0 ? classic_sig : 0); +} + +/* Forward declarations for helpers defined later in this file */ +static int composite_encode_classic_key(const EVP_PKEY *pkey, int include_priv, + unsigned char **out, size_t *out_len); +static EVP_PKEY *composite_decode_classic_key(OSSL_LIB_CTX *libctx, + const char *classic_alg, const char *ec_curve, int include_priv, + const unsigned char *buf, size_t buf_len); + +COMPOSITE_KEY *ossl_prov_composite_new(PROV_CTX *ctx, const char *propq, + int ml_dsa_evp_type) +{ + if (!ossl_prov_is_running()) + return NULL; + + return ossl_composite_key_new(PROV_LIBCTX_OF(ctx), propq, ml_dsa_evp_type); +} + +static void composite_free_key(void *keydata) +{ + ossl_composite_key_free((COMPOSITE_KEY *)keydata); +} + +static int composite_has(const void *keydata, int selection) +{ + const COMPOSITE_KEY *key = keydata; + + if (!ossl_prov_is_running() || key == NULL) + return 0; + if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) + return 1; /* the selection is not missing */ + + return ossl_composite_key_has(key, selection); +} + +static void *composite_gen_init(void *provctx, int selection, + const OSSL_PARAM params[]) +{ + COMPOSITE_GEN_CTX *gctx = NULL; + + if (!ossl_prov_is_running()) + return NULL; + + if ((gctx = OPENSSL_zalloc(sizeof(*gctx))) != NULL) { + gctx->provctx = provctx; + if (!composite_gen_set_params(gctx, params)) { + OPENSSL_free(gctx); + gctx = NULL; + } + } + + return gctx; +} + +static void composite_gen_cleanup(void *genctx) +{ + COMPOSITE_GEN_CTX *gctx = genctx; + + if (gctx == NULL) + return; + + OPENSSL_secure_clear_free(gctx->priv_seed, gctx->priv_seed_len); + OPENSSL_free(gctx->propq); + OPENSSL_free(gctx); +} + +static const OSSL_PARAM *composite_gen_settable_params(void *genctx, + void *provctx) +{ + return composite_gen_set_params_list; +} + +static int composite_gen_set_params(void *genctx, const OSSL_PARAM params[]) +{ + COMPOSITE_GEN_CTX *gctx = genctx; + struct composite_gen_set_params_st p; + + if (gctx == NULL || !composite_gen_set_params_decoder(params, &p)) + return 0; + + if (p.privkey != NULL) { + const void *seed_ptr; + size_t seed_len; + + if (!OSSL_PARAM_get_octet_string_ptr(p.privkey, &seed_ptr, &seed_len)) + return 0; + OPENSSL_secure_clear_free(gctx->priv_seed, gctx->priv_seed_len); + gctx->priv_seed = OPENSSL_secure_malloc(seed_len); + if (gctx->priv_seed == NULL) + return 0; + memcpy(gctx->priv_seed, seed_ptr, seed_len); + gctx->priv_seed_len = seed_len; + } + + if (p.propq != NULL) { + OPENSSL_free(gctx->propq); + gctx->propq = NULL; + if (!OSSL_PARAM_get_utf8_string(p.propq, &gctx->propq, 0)) + return 0; + } + return 1; +} + +static void *composite_gen(void *genctx, int evp_type, + const char *classic_alg, int classic_bits, + const char *ec_curve) +{ + COMPOSITE_GEN_CTX *gctx = genctx; + COMPOSITE_KEY *key = NULL; + EVP_PKEY_CTX *ctx = NULL; + + if (!ossl_prov_is_running()) + return NULL; + + key = ossl_prov_composite_new(gctx->provctx, gctx->propq, evp_type); + if (key == NULL) + return NULL; + + if (gctx->priv_seed_len != 0) { + /* + * Deterministic keygen: caller supplied mldsaSeed(32) || tradSK. + * Expand the ML-DSA seed and import the classic private key directly. + */ + if (gctx->priv_seed_len <= ML_DSA_SEED_BYTES) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH); + goto err; + } + if (!ossl_ml_dsa_set_prekey(key->ml_dsa_key, 0, 0, + gctx->priv_seed, ML_DSA_SEED_BYTES, NULL, 0)) + goto err; + if (!ossl_ml_dsa_generate_key(key->ml_dsa_key)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY); + goto err; + } + key->classic_key = composite_decode_classic_key( + PROV_LIBCTX_OF(gctx->provctx), classic_alg, ec_curve, 1, + gctx->priv_seed + ML_DSA_SEED_BYTES, + gctx->priv_seed_len - ML_DSA_SEED_BYTES); + if (key->classic_key == NULL) + goto err; + } else if (!ossl_ml_dsa_generate_key(key->ml_dsa_key)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY); + goto err; + } else if (strcmp(classic_alg, "RSA") == 0) { + unsigned int rsa_bits = (unsigned int)classic_bits; + OSSL_PARAM rsa_params[2]; + + rsa_params[0] = OSSL_PARAM_construct_uint(OSSL_PKEY_PARAM_RSA_BITS, + &rsa_bits); + rsa_params[1] = OSSL_PARAM_construct_end(); + ctx = EVP_PKEY_CTX_new_from_name(PROV_LIBCTX_OF(gctx->provctx), + "RSA", gctx->propq); + if (ctx == NULL) + goto err; + if (EVP_PKEY_keygen_init(ctx) <= 0) + goto err; + if (EVP_PKEY_CTX_set_params(ctx, rsa_params) <= 0) + goto err; + if (EVP_PKEY_keygen(ctx, &key->classic_key) <= 0) + goto err; + } else if (strcmp(classic_alg, "EC") == 0) { + ctx = EVP_PKEY_CTX_new_from_name(PROV_LIBCTX_OF(gctx->provctx), + "EC", gctx->propq); + if (ctx == NULL) + goto err; + if (EVP_PKEY_keygen_init(ctx) <= 0) + goto err; + if (EVP_PKEY_CTX_set_group_name(ctx, ec_curve) <= 0) + goto err; + if (EVP_PKEY_keygen(ctx, &key->classic_key) <= 0) + goto err; + /* composite draft requires ECPrivateKey without publicKey field */ + EVP_PKEY_set_int_param(key->classic_key, + OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, 0); + } else if (strcmp(classic_alg, "ED25519") == 0 + || strcmp(classic_alg, "ED448") == 0) { + ctx = EVP_PKEY_CTX_new_from_name(PROV_LIBCTX_OF(gctx->provctx), + classic_alg, gctx->propq); + if (ctx == NULL) + goto err; + if (EVP_PKEY_keygen_init(ctx) <= 0) + goto err; + if (EVP_PKEY_keygen(ctx, &key->classic_key) <= 0) + goto err; + } else { + ERR_raise_data(ERR_LIB_PROV, PROV_R_NOT_SUPPORTED, + "unsupported classic algorithm: %s", classic_alg); + goto err; + } + + EVP_PKEY_CTX_free(ctx); + return key; +err: + EVP_PKEY_CTX_free(ctx); + ossl_composite_key_free(key); + return NULL; +} + +static const OSSL_PARAM *composite_gettable_params(void *provctx) +{ + return composite_get_params_list; +} + +static int composite_get_params(void *keydata, OSSL_PARAM params[]) +{ + COMPOSITE_KEY *key = keydata; + struct composite_get_params_st p; + + if (key == NULL || !composite_get_params_decoder(params, &p)) + return 0; + + if (p.bits != NULL && !OSSL_PARAM_set_int(p.bits, (int)(8 * ossl_composite_key_get_pub_len(key)))) + return 0; + + if (p.secbits != NULL && !OSSL_PARAM_set_int(p.secbits, ossl_composite_key_get_security_bits(key))) + return 0; + + if (p.maxsize != NULL && !OSSL_PARAM_set_int(p.maxsize, ossl_composite_key_get_max_size(key))) + return 0; + + if (p.privkey != NULL) { + /* Build mldsaSeed(32) || tradSK from the composite key */ + const uint8_t *ml_dsa_seed = ossl_ml_dsa_key_get_seed(key->ml_dsa_key); + unsigned char *classic_priv = NULL; + size_t classic_priv_len = 0; + unsigned char *priv_buf = NULL; + size_t priv_len; + int ok = 0; + + if (ml_dsa_seed == NULL || key->classic_key == NULL) + return 0; + if (!composite_encode_classic_key(key->classic_key, 1, + &classic_priv, &classic_priv_len)) + return 0; + priv_len = ML_DSA_SEED_BYTES + classic_priv_len; + priv_buf = OPENSSL_secure_malloc(priv_len); + if (priv_buf != NULL) { + memcpy(priv_buf, ml_dsa_seed, ML_DSA_SEED_BYTES); + memcpy(priv_buf + ML_DSA_SEED_BYTES, classic_priv, classic_priv_len); + ok = OSSL_PARAM_set_octet_string(p.privkey, priv_buf, priv_len); + OPENSSL_secure_clear_free(priv_buf, priv_len); + } + OPENSSL_clear_free(classic_priv, classic_priv_len); + if (!ok) + return 0; + } + + if (p.pubkey != NULL) { + /* Build mldsaPK || tradPK from the composite key */ + const ML_DSA_PARAMS *kp = ossl_ml_dsa_key_params(key->ml_dsa_key); + const uint8_t *ml_dsa_pub = ossl_ml_dsa_key_get_pub(key->ml_dsa_key); + unsigned char *classic_pub = NULL; + size_t classic_pub_len = 0; + unsigned char *pub_buf = NULL; + size_t pub_len; + int ok = 0; + + if (ml_dsa_pub == NULL || key->classic_key == NULL) + return 0; + if (!composite_encode_classic_key(key->classic_key, 0, + &classic_pub, &classic_pub_len)) + return 0; + pub_len = kp->pk_len + classic_pub_len; + pub_buf = OPENSSL_malloc(pub_len); + if (pub_buf != NULL) { + memcpy(pub_buf, ml_dsa_pub, kp->pk_len); + memcpy(pub_buf + kp->pk_len, classic_pub, classic_pub_len); + ok = OSSL_PARAM_set_octet_string(p.pubkey, pub_buf, pub_len); + OPENSSL_free(pub_buf); + } + OPENSSL_free(classic_pub); + if (!ok) + return 0; + } + + return 1; +} + +/* + * Validates the key material itself (pairwise pub/priv consistency for + * both sub-keys). + */ +static int composite_validate(const void *keydata, int selection, + int check_type) +{ + const COMPOSITE_KEY *key = keydata; + + if (!composite_has(keydata, selection)) + return 0; + + if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == OSSL_KEYMGMT_SELECT_KEYPAIR) { + if (!ossl_ml_dsa_key_pairwise_check(key->ml_dsa_key)) + return 0; + + if (key->classic_key == NULL || !evp_pkey_is_provided(key->classic_key)) + return 0; + return evp_keymgmt_validate(key->classic_key->keymgmt, + key->classic_key->keydata, + selection, check_type); + } + return 1; +} + +static const OSSL_PARAM *composite_import_types(int selection) +{ + if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) + return NULL; + return composite_import_params_list; +} + +static const OSSL_PARAM *composite_export_types(int selection) +{ + if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) + return NULL; + return composite_export_params_list; +} + +/* + * Decode the traditional sub-key from its raw wire format as defined in + * draft-ietf-lamps-pq-composite-sigs: + * + * RSA: RSAPublicKey DER (pub) / RSAPrivateKey DER (priv) — PKCS#1 + * EC: Uncompressed X9.62 point 0x04||x||y (pub) + * / ECPrivateKey DER with NamedCurve (priv) — RFC5915 + * Ed25519: raw 32 bytes + * Ed448: raw 57 bytes + */ +/* Extract the privateKey OCTET STRING content from an RFC 5915 ECPrivateKey DER. */ +static const unsigned char *rfc5915_extract_privkey(const unsigned char *buf, + size_t buf_len, size_t *priv_len) +{ + const unsigned char *p = buf; + const unsigned char *end = buf + buf_len; + size_t seq_len, key_len; + + /* Outer SEQUENCE tag */ + if (p >= end || *p++ != 0x30) + return NULL; + /* DER length of SEQUENCE content */ + if (p >= end) + return NULL; + if (*p & 0x80) { + int nb = (int)(*p++ & 0x7f); + if (nb == 0 || nb > 4 || p + nb > end) + return NULL; + seq_len = 0; + while (nb--) + seq_len = (seq_len << 8) | (unsigned char)*p++; + } else { + seq_len = (unsigned char)*p++; + } + if ((size_t)(end - p) < seq_len) + return NULL; + end = p + seq_len; + + /* version: 02 01 01 */ + if (end - p < 3 || p[0] != 0x02 || p[1] != 0x01 || p[2] != 0x01) + return NULL; + p += 3; + + /* privateKey OCTET STRING: 04 */ + if (p >= end || *p++ != 0x04) + return NULL; + if (p >= end) + return NULL; + if (*p & 0x80) { + int nb = (int)(*p++ & 0x7f); + if (nb == 0 || nb > 2 || p + nb > end) + return NULL; + key_len = 0; + while (nb--) + key_len = (key_len << 8) | (unsigned char)*p++; + } else { + key_len = (unsigned char)*p++; + } + if ((size_t)(end - p) < key_len) + return NULL; + *priv_len = key_len; + return p; +} + +static EVP_PKEY *composite_decode_classic_key(OSSL_LIB_CTX *libctx, + const char *classic_alg, + const char *ec_curve, + int include_priv, + const unsigned char *buf, + size_t buf_len) +{ + EVP_PKEY *pkey = NULL; + const unsigned char *ptr; + size_t ptrlen; + OSSL_DECODER_CTX *dctx; + OSSL_PARAM params[4]; + EVP_PKEY_CTX *pctx; + + if (strcmp(classic_alg, "RSA") == 0) { + /* + * RSAPublicKey (pub) or RSAPrivateKey (priv) — PKCS#1 DER. + * The "type-specific" OSSL_DECODER structure handles both via + * d2i_RSAPublicKey / d2i_RSAPrivateKey. + */ + ptr = buf; + ptrlen = buf_len; + dctx = OSSL_DECODER_CTX_new_for_pkey( + &pkey, "DER", "type-specific", "RSA", + include_priv ? OSSL_KEYMGMT_SELECT_PRIVATE_KEY + : OSSL_KEYMGMT_SELECT_PUBLIC_KEY, + libctx, NULL); + if (dctx == NULL) + return NULL; + if (!OSSL_DECODER_from_data(dctx, &ptr, &ptrlen)) + pkey = NULL; + OSSL_DECODER_CTX_free(dctx); + } else if (strcmp(classic_alg, "EC") == 0) { + if (include_priv) { + /* Try the standard decoder first; fall back to manual RFC 5915 + * parsing on targets where the decoder chain is unavailable. */ + ptr = buf; + ptrlen = buf_len; + dctx = OSSL_DECODER_CTX_new_for_pkey( + &pkey, "DER", "type-specific", "EC", + OSSL_KEYMGMT_SELECT_PRIVATE_KEY, libctx, NULL); + if (dctx != NULL) { + if (!OSSL_DECODER_from_data(dctx, &ptr, &ptrlen)) + pkey = NULL; + OSSL_DECODER_CTX_free(dctx); + } + if (pkey == NULL) { + const unsigned char *priv_bytes; + size_t priv_len; + BIGNUM *priv_bn = NULL; + OSSL_PARAM_BLD *bld = NULL; + OSSL_PARAM *built = NULL; + + ERR_clear_error(); + priv_bytes = rfc5915_extract_privkey(buf, buf_len, &priv_len); + if (priv_bytes == NULL) + return NULL; + + priv_bn = BN_bin2bn(priv_bytes, (int)priv_len, NULL); + bld = priv_bn != NULL ? OSSL_PARAM_BLD_new() : NULL; + if (bld == NULL + || !OSSL_PARAM_BLD_push_utf8_string(bld, + OSSL_PKEY_PARAM_GROUP_NAME, ec_curve, 0) + || !OSSL_PARAM_BLD_push_BN(bld, + OSSL_PKEY_PARAM_PRIV_KEY, priv_bn) + || (built = OSSL_PARAM_BLD_to_param(bld)) == NULL) { + OSSL_PARAM_BLD_free(bld); + BN_free(priv_bn); + return NULL; + } + OSSL_PARAM_BLD_free(bld); + BN_free(priv_bn); + + pctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", NULL); + if (pctx == NULL) { + OSSL_PARAM_free(built); + return NULL; + } + if (EVP_PKEY_fromdata_init(pctx) <= 0 + || EVP_PKEY_fromdata(pctx, &pkey, + OSSL_KEYMGMT_SELECT_PRIVATE_KEY + | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, + built) + <= 0) + pkey = NULL; + EVP_PKEY_CTX_free(pctx); + OSSL_PARAM_free(built); + } + /* composite draft requires ECPrivateKey without publicKey field */ + if (pkey != NULL) + EVP_PKEY_set_int_param(pkey, + OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, 0); + } else { + /* + * Uncompressed X9.62 public key point: 0x04 || x || y. + * No DER wrapper — import directly via EVP_PKEY_fromdata with + * the curve name and raw point bytes. + */ + params[0] = OSSL_PARAM_construct_utf8_string( + OSSL_PKEY_PARAM_GROUP_NAME, (char *)ec_curve, 0); + params[1] = OSSL_PARAM_construct_octet_string( + OSSL_PKEY_PARAM_PUB_KEY, (void *)buf, buf_len); + params[2] = OSSL_PARAM_construct_end(); + + pctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", NULL); + if (pctx == NULL) + return NULL; + if (EVP_PKEY_fromdata_init(pctx) <= 0 + || EVP_PKEY_fromdata(pctx, &pkey, + OSSL_KEYMGMT_SELECT_PUBLIC_KEY + | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, + params) + <= 0) + pkey = NULL; + EVP_PKEY_CTX_free(pctx); + } + } else if (strcmp(classic_alg, "ED25519") == 0) { + /* Raw 32-byte public or private key per RFC8032 */ + if (include_priv) + pkey = EVP_PKEY_new_raw_private_key_ex(libctx, "ED25519", NULL, + buf, buf_len); + else + pkey = EVP_PKEY_new_raw_public_key_ex(libctx, "ED25519", NULL, + buf, buf_len); + } else if (strcmp(classic_alg, "ED448") == 0) { + /* Raw 57-byte public or private key per RFC8032 */ + if (include_priv) + pkey = EVP_PKEY_new_raw_private_key_ex(libctx, "ED448", NULL, + buf, buf_len); + else + pkey = EVP_PKEY_new_raw_public_key_ex(libctx, "ED448", NULL, + buf, buf_len); + } + + return pkey; +} + +/* + * Reconstruct a COMPOSITE_KEY from raw bytes in params[], using the wire + * format defined in draft-ietf-lamps-pq-composite-sigs: + * + * Public key: mldsaPK(fixed size) || tradPK(raw) + * Private key: mldsaSeed(32 bytes) || tradSK(raw) + * + * classic_alg: "RSA", "EC", "ED25519", or "ED448" + * ec_curve: curve name for EC (e.g. "P-256"), NULL for non-EC + */ +static int composite_import_internal(void *keydata, int selection, + const OSSL_PARAM params[], + const char *classic_alg, + const char *ec_curve) +{ + COMPOSITE_KEY *key = keydata; + const ML_DSA_PARAMS *kp; + const uint8_t *buf; + size_t buf_len, ml_dsa_len; + OSSL_LIB_CTX *libctx; + const char *pname; + const OSSL_PARAM *p; + int include_priv; + + if (!ossl_prov_is_running() || key == NULL) + return 0; + + if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) + return 0; + + include_priv = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0); + kp = ossl_ml_dsa_key_params(key->ml_dsa_key); + libctx = ossl_ml_dsa_key_get0_libctx(key->ml_dsa_key); + + /* 1. Extract the combined octet string (ml_dsa_bytes || classic_bytes). + * + * EVP_PKEY_new_raw_public_key_ex() calls EVP_PKEY_fromdata() with + * EVP_PKEY_KEYPAIR as the selection but only provides PUB_KEY in params. + * Fall back to PUB_KEY when the caller asked for private but only supplied + * a public-key blob. + */ + pname = include_priv ? OSSL_PKEY_PARAM_PRIV_KEY : OSSL_PKEY_PARAM_PUB_KEY; + p = OSSL_PARAM_locate_const(params, pname); + if (p == NULL && include_priv) { + /* No private key in params — try loading as public key only */ + include_priv = 0; + pname = OSSL_PKEY_PARAM_PUB_KEY; + p = OSSL_PARAM_locate_const(params, pname); + } + if (p == NULL + || !OSSL_PARAM_get_octet_string_ptr(p, (const void **)&buf, &buf_len)) + return 0; + + /* + * 2. Split at the ML-DSA boundary per the draft spec: + * - Private key: first ML_DSA_SEED_BYTES (32) bytes are the seed, + * NOT the expanded key (sk_len is 4032/3936/etc.). + * - Public key: first kp->pk_len bytes (1312/1952/2592). + */ + ml_dsa_len = include_priv ? ML_DSA_SEED_BYTES : kp->pk_len; + if (buf_len <= ml_dsa_len) + return 0; + + if (include_priv) { + /* + * Load the 32-byte seed and expand it into the full key pair. + * ossl_ml_dsa_set_prekey stores the seed; ossl_ml_dsa_generate_key + * derives rho, K, A, s1, s2, t0, t1 from it. + */ + if (!ossl_ml_dsa_set_prekey(key->ml_dsa_key, 0, 0, + buf, ML_DSA_SEED_BYTES, NULL, 0)) + return 0; + if (!ossl_ml_dsa_generate_key(key->ml_dsa_key)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY); + return 0; + } + } else { + if (!ossl_ml_dsa_pk_decode(key->ml_dsa_key, buf, ml_dsa_len)) + return 0; + } + + /* 3. Decode the classic portion from its raw wire format */ + key->classic_key = composite_decode_classic_key(libctx, + classic_alg, ec_curve, + include_priv, + buf + ml_dsa_len, + buf_len - ml_dsa_len); + return key->classic_key != NULL; +} + +/* + * Encode the traditional sub-key to its raw wire format per + * draft-ietf-lamps-pq-composite-sigs: + * + * RSA: RSAPublicKey DER (pub) / RSAPrivateKey DER (priv) — PKCS#1 + * EC: Uncompressed X9.62 point 0x04||x||y (pub) + * / ECPrivateKey DER (priv) — RFC5915 + * Ed25519: raw 32 bytes + * Ed448: raw 57 bytes + * + * On success, *out points to a newly-allocated buffer and *out_len holds its + * length. The caller must OPENSSL_free(*out) (or OPENSSL_clear_free for priv). + */ +static int composite_encode_classic_key(const EVP_PKEY *pkey, + int include_priv, + unsigned char **out, + size_t *out_len) +{ + int keytype = EVP_PKEY_get_base_id(pkey); + OSSL_ENCODER_CTX *ectx; + size_t len; + + *out = NULL; + *out_len = 0; + + if (keytype == EVP_PKEY_RSA) { + /* + * RSAPublicKey (pub) or RSAPrivateKey (priv) — PKCS#1 DER. + * OSSL_ENCODER "type-specific" uses i2d_RSAPublicKey / i2d_RSAPrivateKey. + */ + ectx = OSSL_ENCODER_CTX_new_for_pkey( + pkey, + include_priv ? OSSL_KEYMGMT_SELECT_PRIVATE_KEY + : OSSL_KEYMGMT_SELECT_PUBLIC_KEY, + "DER", "type-specific", NULL); + if (ectx == NULL) + return 0; + if (!OSSL_ENCODER_to_data(ectx, out, out_len)) + *out = NULL; + OSSL_ENCODER_CTX_free(ectx); + } else if (keytype == EVP_PKEY_EC) { + if (include_priv) { + ectx = OSSL_ENCODER_CTX_new_for_pkey( + pkey, OSSL_KEYMGMT_SELECT_ALL, "DER", "type-specific", NULL); + if (ectx == NULL) + return 0; + if (!OSSL_ENCODER_to_data(ectx, out, out_len)) + *out = NULL; + OSSL_ENCODER_CTX_free(ectx); + } else { + /* + * Uncompressed X9.62 point: 0x04 || x || y. + * OSSL_PKEY_PARAM_PUB_KEY returns the point in uncompressed form. + * (There is no "type-specific" EC public encoder.) + */ + if (!EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, + NULL, 0, &len)) + return 0; + *out = OPENSSL_malloc(len); + if (*out == NULL) + return 0; + if (!EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, + *out, len, out_len)) { + OPENSSL_free(*out); + *out = NULL; + } + } + } else if (keytype == EVP_PKEY_ED25519 || keytype == EVP_PKEY_ED448) { + /* Raw 32-byte (Ed25519) or 57-byte (Ed448) key per RFC8032 */ + if (include_priv) { + if (!EVP_PKEY_get_raw_private_key(pkey, NULL, &len)) + return 0; + *out = OPENSSL_malloc(len); + if (*out == NULL) + return 0; + if (!EVP_PKEY_get_raw_private_key(pkey, *out, &len)) { + OPENSSL_free(*out); + *out = NULL; + } else { + *out_len = len; + } + } else { + if (!EVP_PKEY_get_raw_public_key(pkey, NULL, &len)) + return 0; + *out = OPENSSL_malloc(len); + if (*out == NULL) + return 0; + if (!EVP_PKEY_get_raw_public_key(pkey, *out, &len)) { + OPENSSL_free(*out); + *out = NULL; + } else { + *out_len = len; + } + } + } else { + return 0; + } + + return *out != NULL; +} + +/* + * composite_export: + * Serialize both sub-keys into the caller's OSSL_PARAM array. + * Wire format per draft-ietf-lamps-pq-composite-sigs: + * Public key: mldsaPK(pk_len bytes) || tradPK(raw) + * Private key: mldsaSeed(32 bytes) || tradSK(raw) + */ +static int composite_export(void *keydata, int selection, + OSSL_CALLBACK *param_cb, void *cbarg) +{ + COMPOSITE_KEY *key = keydata; + const ML_DSA_PARAMS *kp; + const uint8_t *ml_dsa_bytes; + unsigned char *priv_buf = NULL, *pub_buf = NULL; + unsigned char *classic_priv = NULL, *classic_pub = NULL; + size_t classic_priv_len = 0, classic_pub_len = 0; + size_t priv_len = 0, pub_len = 0; + OSSL_PARAM params[3]; + int include_priv, pnum = 0, ret = 0; + + if (!ossl_prov_is_running() || key == NULL) + return 0; + if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) + return 0; + if (!composite_has(keydata, selection)) + return 0; + + kp = ossl_ml_dsa_key_params(key->ml_dsa_key); + include_priv = ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0); + + /* ---- Private key: mldsaSeed(32) || tradSK(raw) ---- */ + if (include_priv) { + ml_dsa_bytes = ossl_ml_dsa_key_get_seed(key->ml_dsa_key); + if (ml_dsa_bytes == NULL) + goto done; /* seed required; key was not loaded from seed */ + if (!composite_encode_classic_key(key->classic_key, 1, + &classic_priv, &classic_priv_len)) + goto done; + priv_len = ML_DSA_SEED_BYTES + classic_priv_len; + priv_buf = OPENSSL_secure_malloc(priv_len); + if (priv_buf == NULL) + goto done; + memcpy(priv_buf, ml_dsa_bytes, ML_DSA_SEED_BYTES); + memcpy(priv_buf + ML_DSA_SEED_BYTES, classic_priv, classic_priv_len); + params[pnum++] = OSSL_PARAM_construct_octet_string( + OSSL_PKEY_PARAM_PRIV_KEY, priv_buf, priv_len); + } + + /* ---- Public key: mldsaPK(pk_len) || tradPK(raw) ---- */ + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { + ml_dsa_bytes = ossl_ml_dsa_key_get_pub(key->ml_dsa_key); + if (ml_dsa_bytes == NULL) + goto done; + if (!composite_encode_classic_key(key->classic_key, 0, + &classic_pub, &classic_pub_len)) + goto done; + pub_len = kp->pk_len + classic_pub_len; + pub_buf = OPENSSL_malloc(pub_len); + if (pub_buf == NULL) + goto done; + memcpy(pub_buf, ml_dsa_bytes, kp->pk_len); + memcpy(pub_buf + kp->pk_len, classic_pub, classic_pub_len); + params[pnum++] = OSSL_PARAM_construct_octet_string( + OSSL_PKEY_PARAM_PUB_KEY, pub_buf, pub_len); + } + + if (pnum == 0) + goto done; + params[pnum] = OSSL_PARAM_construct_end(); + ret = param_cb(params, cbarg); + +done: + if (priv_buf != NULL) + OPENSSL_secure_clear_free(priv_buf, priv_len); + if (classic_priv != NULL) + OPENSSL_clear_free(classic_priv, classic_priv_len); + OPENSSL_free(pub_buf); + OPENSSL_free(classic_pub); + return ret; +} + +static void *composite_dup_key(const void *keydata_from, int selection) +{ + const COMPOSITE_KEY *src = keydata_from; + COMPOSITE_KEY *key; + + if (!ossl_prov_is_running() || src == NULL) + return NULL; + + key = OPENSSL_zalloc(sizeof(*key)); + if (key == NULL) + return NULL; + + key->ml_dsa_key = ossl_ml_dsa_key_dup(src->ml_dsa_key, selection); + if (key->ml_dsa_key == NULL) + goto err; + + key->classic_key = EVP_PKEY_dup(src->classic_key); + if (key->classic_key == NULL) + goto err; + + return key; +err: + ossl_ml_dsa_key_free(key->ml_dsa_key); + OPENSSL_free(key); + return NULL; +} + +static int composite_match(const void *keydata1, const void *keydata2, + int selection) +{ + const COMPOSITE_KEY *key1 = keydata1; + const COMPOSITE_KEY *key2 = keydata2; + + if (!ossl_prov_is_running()) + return 0; + if (key1 == NULL || key2 == NULL) + return 0; + if (!ossl_ml_dsa_key_equal(key1->ml_dsa_key, key2->ml_dsa_key, selection)) + return 0; + if (!EVP_PKEY_eq(key1->classic_key, key2->classic_key)) + return 0; + return 1; +} + +static void *composite_load(const void *reference, size_t reference_sz) +{ + COMPOSITE_KEY *key = NULL; + const uint8_t *seed; + + if (!ossl_prov_is_running() || reference == NULL + || reference_sz != sizeof(key)) + return NULL; + + /* The contents of the reference is the address to our object */ + key = *(COMPOSITE_KEY **)reference; + /* We grabbed, so we detach it */ + *(COMPOSITE_KEY **)reference = NULL; + + if (key == NULL) + return NULL; + + /* + * Classic half must be a fully-loaded, provider-side key. + * Unlike ML-DSA there is no "prekey" mechanism for EVP_PKEY — + * the classic component must already be complete in the reference. + */ + if (key->classic_key == NULL || !evp_pkey_is_provided(key->classic_key)) + goto err; + + /* All done if the ML-DSA public key is already present. */ + if (ossl_ml_dsa_key_get_pub(key->ml_dsa_key) != NULL) + return key; + + /* + * Handle ML-DSA prekey: composite wire format stores only the 32-byte + * seed (never the expanded sk), so the only valid prekey state here is + * seed-present. Expand it to derive the full key pair. + */ + seed = ossl_ml_dsa_key_get_seed(key->ml_dsa_key); + if (seed != NULL) { + if (ossl_ml_dsa_generate_key(key->ml_dsa_key)) + return key; + } else { + /* No pub and no seed: public-key-only reference, return as-is. */ + return key; + } + +err: + ossl_ml_dsa_key_free(key->ml_dsa_key); + EVP_PKEY_free(key->classic_key); + OPENSSL_free(key); + return NULL; +} + +#define MAKE_KEYMGMT_FUNCTIONS(alg, ml_dsa_evp_type, classic_alg_, classic_bits_, ec_curve_) \ + static OSSL_FUNC_keymgmt_new_fn composite_##alg##_new_key; \ + static OSSL_FUNC_keymgmt_gen_fn composite_##alg##_gen; \ + static OSSL_FUNC_keymgmt_import_fn composite_##alg##_import; \ + static void *composite_##alg##_new_key(void *provctx) \ + { \ + return ossl_prov_composite_new(provctx, NULL, ml_dsa_evp_type); \ + } \ + static void *composite_##alg##_gen(void *genctx, \ + OSSL_CALLBACK *osslcb, void *cbarg) \ + { \ + return composite_gen(genctx, ml_dsa_evp_type, \ + classic_alg_, classic_bits_, ec_curve_); \ + } \ + static int composite_##alg##_import(void *keydata, int selection, \ + const OSSL_PARAM params[]) \ + { \ + return composite_import_internal(keydata, selection, params, \ + classic_alg_, ec_curve_); \ + } \ + const OSSL_DISPATCH ossl_##alg##_keymgmt_functions[] = { \ + { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))composite_##alg##_new_key }, \ + { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))composite_free_key }, \ + { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))composite_has }, \ + { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))composite_match }, \ + { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))composite_##alg##_import }, \ + { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))composite_import_types }, \ + { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))composite_export }, \ + { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))composite_export_types }, \ + { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))composite_load }, \ + { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))composite_get_params }, \ + { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))composite_gettable_params }, \ + { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))composite_validate }, \ + { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))composite_gen_init }, \ + { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))composite_##alg##_gen }, \ + { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))composite_gen_cleanup }, \ + { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))composite_gen_set_params }, \ + { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (void (*)(void))composite_gen_settable_params }, \ + { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))composite_dup_key }, \ + OSSL_DISPATCH_END \ + } + +/* alg ml_dsa_evp_type classic_alg bits ec_curve */ +MAKE_KEYMGMT_FUNCTIONS(mldsa44_rsa2048_pss_sha256, EVP_PKEY_ML_DSA_44, "RSA", 2048, NULL); +MAKE_KEYMGMT_FUNCTIONS(mldsa44_rsa2048_pkcs15_sha256, EVP_PKEY_ML_DSA_44, "RSA", 2048, NULL); +MAKE_KEYMGMT_FUNCTIONS(mldsa44_ed25519_sha512, EVP_PKEY_ML_DSA_44, "ED25519", 0, NULL); +MAKE_KEYMGMT_FUNCTIONS(mldsa44_ecdsa_p256_sha256, EVP_PKEY_ML_DSA_44, "EC", 256, "P-256"); +MAKE_KEYMGMT_FUNCTIONS(mldsa65_rsa3072_pss_sha512, EVP_PKEY_ML_DSA_65, "RSA", 3072, NULL); +MAKE_KEYMGMT_FUNCTIONS(mldsa65_rsa3072_pkcs15_sha512, EVP_PKEY_ML_DSA_65, "RSA", 3072, NULL); +MAKE_KEYMGMT_FUNCTIONS(mldsa65_rsa4096_pss_sha512, EVP_PKEY_ML_DSA_65, "RSA", 4096, NULL); +MAKE_KEYMGMT_FUNCTIONS(mldsa65_rsa4096_pkcs15_sha512, EVP_PKEY_ML_DSA_65, "RSA", 4096, NULL); +MAKE_KEYMGMT_FUNCTIONS(mldsa65_ecdsa_p256_sha512, EVP_PKEY_ML_DSA_65, "EC", 256, "P-256"); +MAKE_KEYMGMT_FUNCTIONS(mldsa65_ecdsa_p384_sha512, EVP_PKEY_ML_DSA_65, "EC", 384, "P-384"); +MAKE_KEYMGMT_FUNCTIONS(mldsa65_ecdsa_brainpoolP256r1_sha512, EVP_PKEY_ML_DSA_65, "EC", 256, "brainpoolP256r1"); +MAKE_KEYMGMT_FUNCTIONS(mldsa65_ed25519_sha512, EVP_PKEY_ML_DSA_65, "ED25519", 0, NULL); +MAKE_KEYMGMT_FUNCTIONS(mldsa87_ecdsa_p384_sha512, EVP_PKEY_ML_DSA_87, "EC", 384, "P-384"); +MAKE_KEYMGMT_FUNCTIONS(mldsa87_ecdsa_brainpoolP384r1_sha512, EVP_PKEY_ML_DSA_87, "EC", 384, "brainpoolP384r1"); +MAKE_KEYMGMT_FUNCTIONS(mldsa87_ed448_shake256, EVP_PKEY_ML_DSA_87, "ED448", 0, NULL); +MAKE_KEYMGMT_FUNCTIONS(mldsa87_rsa3072_pss_sha512, EVP_PKEY_ML_DSA_87, "RSA", 3072, NULL); +MAKE_KEYMGMT_FUNCTIONS(mldsa87_rsa4096_pss_sha512, EVP_PKEY_ML_DSA_87, "RSA", 4096, NULL); +MAKE_KEYMGMT_FUNCTIONS(mldsa87_ecdsa_p521_sha512, EVP_PKEY_ML_DSA_87, "EC", 521, "P-521"); diff --git a/providers/implementations/keymgmt/composite_kmgmt.inc.in b/providers/implementations/keymgmt/composite_kmgmt.inc.in new file mode 100644 index 0000000000000..7468e335bb110 --- /dev/null +++ b/providers/implementations/keymgmt/composite_kmgmt.inc.in @@ -0,0 +1,52 @@ +/* + * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::paramnames qw(produce_param_decoder); +-} + +/* + * composite_import_params: only the list and struct are needed. + * Params are parsed manually in composite_import_internal() via + * OSSL_PARAM_locate_const(), so the generated decoder is omitted. + */ +#ifndef composite_import_params_list +static const OSSL_PARAM composite_import_params_list[] = { + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_END +}; +#endif + +/* + * composite_export_params: only the list is needed. + * Params are assembled manually in composite_export(), so the generated + * decoder is omitted. + */ +#ifndef composite_export_params_list +static const OSSL_PARAM composite_export_params_list[] = { + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0), + OSSL_PARAM_END +}; +#endif + +{- produce_param_decoder('composite_get_params', + (['OSSL_PKEY_PARAM_BITS', 'bits', 'int'], + ['OSSL_PKEY_PARAM_SECURITY_BITS', 'secbits', 'int'], + ['OSSL_PKEY_PARAM_MAX_SIZE', 'maxsize', 'int'], + ['OSSL_PKEY_PARAM_PUB_KEY', 'pubkey', 'octet_string'], + ['OSSL_PKEY_PARAM_PRIV_KEY', 'privkey', 'octet_string'], + )); -} + +{- produce_param_decoder('composite_gen_set_params', + (['OSSL_PKEY_PARAM_PROPERTIES', 'propq', 'utf8_string'], + ['OSSL_PKEY_PARAM_PRIV_KEY', 'privkey', 'octet_string'], + )); -} diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c index 28404502eb864..391cc6b3c6e1f 100644 --- a/providers/implementations/keymgmt/ec_kmgmt.c +++ b/providers/implementations/keymgmt/ec_kmgmt.c @@ -23,6 +23,7 @@ #include #include "crypto/bn.h" #include "crypto/ec.h" +#include "crypto/ec_params.h" #include "prov/implementations.h" #include "prov/providercommon.h" #include "prov/provider_ctx.h" @@ -65,11 +66,16 @@ static OSSL_FUNC_keymgmt_dup_fn ec_dup; #ifndef OPENSSL_NO_SM2 static OSSL_FUNC_keymgmt_new_fn sm2_newdata; static OSSL_FUNC_keymgmt_gen_init_fn sm2_gen_init; +static OSSL_FUNC_keymgmt_gen_set_params_fn sm2_gen_set_params; +static OSSL_FUNC_keymgmt_gen_settable_params_fn sm2_gen_settable_params; static OSSL_FUNC_keymgmt_gen_fn sm2_gen; static OSSL_FUNC_keymgmt_get_params_fn sm2_get_params; static OSSL_FUNC_keymgmt_gettable_params_fn sm2_gettable_params; static OSSL_FUNC_keymgmt_settable_params_fn sm2_settable_params; +static OSSL_FUNC_keymgmt_set_params_fn sm2_set_params; static OSSL_FUNC_keymgmt_import_fn sm2_import; +static OSSL_FUNC_keymgmt_import_types_fn sm2_import_types; +static OSSL_FUNC_keymgmt_export_types_fn sm2_export_types; static OSSL_FUNC_keymgmt_query_operation_name_fn sm2_query_operation_name; static OSSL_FUNC_keymgmt_query_operation_name_fn curve_sm2_query_operation_name; static OSSL_FUNC_keymgmt_validate_fn sm2_validate; @@ -119,7 +125,7 @@ static const char *curve_sm2_query_operation_name(int operation_id) * parameters are exported separately. */ static ossl_inline int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl, - OSSL_PARAM params[], int include_private, + const EC_PARAMS *params, int include_private, unsigned char **pub_key) { BIGNUM *x = NULL, *y = NULL; @@ -148,10 +154,10 @@ static ossl_inline int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl, goto err; /* If we are doing a get then check first before decoding the point */ - if (tmpl == NULL) { - p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY); - px = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_X); - py = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_Y); + if (tmpl == NULL && params != NULL) { + p = params->pub; + px = params->pub_x; + py = params->pub_y; } if (p != NULL || tmpl != NULL) { @@ -234,7 +240,8 @@ static ossl_inline int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl, goto err; sz = (ecbits + 7) / 8; - if (!ossl_param_build_set_bn_pad(tmpl, params, + if (!ossl_param_build_set_bn_pad(tmpl, + params == NULL ? NULL : params->priv, OSSL_PKEY_PARAM_PRIV_KEY, priv_key, sz)) goto err; @@ -246,7 +253,7 @@ static ossl_inline int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl, } static ossl_inline int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *tmpl, - OSSL_PARAM params[]) + const EC_PARAMS *params) { int ecdh_cofactor_mode = 0, group_check = 0; const char *name = NULL; @@ -257,18 +264,21 @@ static ossl_inline int otherparams_to_params(const EC_KEY *ec, OSSL_PARAM_BLD *t group_check = EC_KEY_get_flags(ec) & EC_FLAG_CHECK_NAMED_GROUP_MASK; name = ossl_ec_check_group_type_id2name(group_check); if (name != NULL - && !ossl_param_build_set_utf8_string(tmpl, params, + && !ossl_param_build_set_utf8_string(tmpl, + params == NULL ? NULL : params->group_check, OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE, name)) return 0; if ((EC_KEY_get_enc_flags(ec) & EC_PKEY_NO_PUBKEY) != 0 - && !ossl_param_build_set_int(tmpl, params, + && !ossl_param_build_set_int(tmpl, + params == NULL ? NULL : params->include_public, OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, 0)) return 0; ecdh_cofactor_mode = (EC_KEY_get_flags(ec) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0; - return ossl_param_build_set_int(tmpl, params, + return ossl_param_build_set_int(tmpl, + params == NULL ? NULL : params->use_cofactor, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, ecdh_cofactor_mode); } @@ -416,10 +426,47 @@ static int common_check_sm2(const EC_KEY *ec, int sm2_wanted) return 1; } +typedef int (*ec_import_decoder_fn)(const OSSL_PARAM *, EC_PARAMS *); + +static const ec_import_decoder_fn ec_import_decoders[] = { + NULL, + ec_imexport_types_1_decoder, + ec_imexport_types_2_decoder, + ec_imexport_types_3_decoder, + ec_imexport_types_4_decoder, + ec_imexport_types_5_decoder, + ec_imexport_types_6_decoder, + ec_imexport_types_7_decoder, + ec_imexport_types_8_decoder, + ec_imexport_types_9_decoder, + ec_imexport_types_10_decoder, + ec_imexport_types_11_decoder, + ec_imexport_types_12_decoder, + ec_imexport_types_13_decoder, + ec_imexport_types_14_decoder, + ec_imexport_types_15_decoder, +}; + +static int ec_imexport_type_select(int selection) +{ + int type_select = 0; + + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) + type_select += 1; + if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) + type_select += 2; + if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) + type_select += 4; + if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) + type_select += 8; + return type_select; +} + static int common_import(void *keydata, int selection, const OSSL_PARAM params[], - int sm2_wanted) + const ec_import_decoder_fn decoders[], int sm2_wanted) { EC_KEY *ec = keydata; + EC_PARAMS p; int ok = 1; if (!ossl_prov_is_running() || ec == NULL) @@ -441,7 +488,10 @@ static int common_import(void *keydata, int selection, const OSSL_PARAM params[] if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) == 0) return 0; - ok = ok && ossl_ec_group_fromdata(ec, params); + if (!decoders[ec_imexport_type_select(selection)](params, &p)) + return 0; + + ok = ok && ossl_ec_group_fromdata_parsed(ec, &p); if (!common_check_sm2(ec, sm2_wanted)) return 0; @@ -449,24 +499,24 @@ static int common_import(void *keydata, int selection, const OSSL_PARAM params[] if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { int include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0; - ok = ok && ossl_ec_key_fromdata(ec, params, include_private); + ok = ok && ossl_ec_key_fromdata_parsed(ec, &p, include_private); } if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) - ok = ok && ossl_ec_key_otherparams_fromdata(ec, params); + ok = ok && ossl_ec_key_otherparams_fromdata_parsed(ec, &p); return ok; } static int ec_import(void *keydata, int selection, const OSSL_PARAM params[]) { - return common_import(keydata, selection, params, 0); + return common_import(keydata, selection, params, ec_import_decoders, 0); } #ifndef FIPS_MODULE #ifndef OPENSSL_NO_SM2 static int sm2_import(void *keydata, int selection, const OSSL_PARAM params[]) { - return common_import(keydata, selection, params, 1); + return common_import(keydata, selection, params, ec_import_decoders, 1); } #endif #endif @@ -544,64 +594,48 @@ static int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, } /* IMEXPORT = IMPORT + EXPORT */ +static const OSSL_PARAM *const ec_types[] = { + NULL, + ec_imexport_types_1_list, + ec_imexport_types_2_list, + ec_imexport_types_3_list, + ec_imexport_types_4_list, + ec_imexport_types_5_list, + ec_imexport_types_6_list, + ec_imexport_types_7_list, + ec_imexport_types_8_list, + ec_imexport_types_9_list, + ec_imexport_types_10_list, + ec_imexport_types_11_list, + ec_imexport_types_12_list, + ec_imexport_types_13_list, + ec_imexport_types_14_list, + ec_imexport_types_15_list, +}; -#define EC_IMEXPORTABLE_DOM_PARAMETERS \ - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), \ - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0), \ - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, NULL, 0), \ - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_P, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_A, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_B, NULL, 0), \ - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0), \ - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0), \ - OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, NULL) - -#define EC_IMEXPORTABLE_PUBLIC_KEY \ - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0) -#define EC_IMEXPORTABLE_PRIVATE_KEY \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0) -#define EC_IMEXPORTABLE_OTHER_PARAMETERS \ - OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL), \ - OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, NULL) - -/* - * Include all the possible combinations of OSSL_PARAM arrays for - * ec_imexport_types(). - * - * They are in a separate file as it is ~100 lines of unreadable and - * uninteresting machine generated stuff. - */ -#include "ec_kmgmt_imexport.inc" - -static ossl_inline const OSSL_PARAM *ec_imexport_types(int selection) +static const OSSL_PARAM *ec_import_types(int selection) { - int type_select = 0; + return ec_types[ec_imexport_type_select(selection)]; +} - if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) - type_select += 1; - if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) - type_select += 2; - if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) - type_select += 4; - if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) - type_select += 8; - return ec_types[type_select]; +static const OSSL_PARAM *ec_export_types(int selection) +{ + return ec_types[ec_imexport_type_select(selection)]; } -static const OSSL_PARAM *ec_import_types(int selection) +#if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_SM2) +static const OSSL_PARAM *sm2_import_types(int selection) { - return ec_imexport_types(selection); + return ec_types[ec_imexport_type_select(selection)]; } -static const OSSL_PARAM *ec_export_types(int selection) +static const OSSL_PARAM *sm2_export_types(int selection) { - return ec_imexport_types(selection); + return ec_types[ec_imexport_type_select(selection)]; } +#endif -static int ec_get_ecm_params(const EC_GROUP *group, OSSL_PARAM params[]) +static int ec_get_ecm_params(const EC_GROUP *group, const EC_PARAMS *params) { #ifdef OPENSSL_NO_EC2M return 1; @@ -624,25 +658,26 @@ static int ec_get_ecm_params(const EC_GROUP *group, OSSL_PARAM params[]) goto err; m = EC_GROUP_get_degree(group); - if (!ossl_param_build_set_int(NULL, params, OSSL_PKEY_PARAM_EC_CHAR2_M, m) - || !ossl_param_build_set_utf8_string(NULL, params, + if (!ossl_param_build_set_int(NULL, params->char2_m, + OSSL_PKEY_PARAM_EC_CHAR2_M, m) + || !ossl_param_build_set_utf8_string(NULL, params->char2_type, OSSL_PKEY_PARAM_EC_CHAR2_TYPE, basis_name)) goto err; if (basis_nid == NID_X9_62_tpBasis) { if (!EC_GROUP_get_trinomial_basis(group, &k1) - || !ossl_param_build_set_int(NULL, params, + || !ossl_param_build_set_int(NULL, params->char2_tp, OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, (int)k1)) goto err; } else { if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3) - || !ossl_param_build_set_int(NULL, params, + || !ossl_param_build_set_int(NULL, params->char2_k1, OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, (int)k1) - || !ossl_param_build_set_int(NULL, params, + || !ossl_param_build_set_int(NULL, params->char2_k2, OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, (int)k2) - || !ossl_param_build_set_int(NULL, params, + || !ossl_param_build_set_int(NULL, params->char2_k3, OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, (int)k3)) goto err; } @@ -656,8 +691,8 @@ static int common_get_params(void *key, OSSL_PARAM params[], int sm2) { int ret = 0; EC_KEY *eck = key; + EC_PARAMS p; const EC_GROUP *ecg = NULL; - OSSL_PARAM *p; unsigned char *pub_key = NULL, *genbuf = NULL; OSSL_LIB_CTX *libctx; const char *propq; @@ -668,6 +703,9 @@ static int common_get_params(void *key, OSSL_PARAM params[], int sm2) ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET); return 0; } + if (!(sm2 ? sm2_get_params_decoder(params, &p) + : ec_get_params_decoder(params, &p))) + return 0; libctx = ossl_ec_key_get_libctx(eck); propq = ossl_ec_key_get0_propq(eck); @@ -677,67 +715,57 @@ static int common_get_params(void *key, OSSL_PARAM params[], int sm2) return 0; BN_CTX_start(bnctx); - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL - && !OSSL_PARAM_set_int(p, ECDSA_size(eck))) + if (p.maxsize != NULL && !OSSL_PARAM_set_int(p.maxsize, ECDSA_size(eck))) goto err; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL - && !OSSL_PARAM_set_int(p, EC_GROUP_order_bits(ecg))) + if (p.bits != NULL && !OSSL_PARAM_set_int(p.bits, EC_GROUP_order_bits(ecg))) goto err; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_FIELD_DEGREE)) != NULL - && !OSSL_PARAM_set_int(p, EC_GROUP_get_degree(ecg))) + if (p.field_degree != NULL + && !OSSL_PARAM_set_int(p.field_degree, EC_GROUP_get_degree(ecg))) goto err; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL - && !OSSL_PARAM_set_int(p, EC_GROUP_security_bits(ecg))) + if (p.secbits != NULL + && !OSSL_PARAM_set_int(p.secbits, EC_GROUP_security_bits(ecg))) goto err; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_CATEGORY)) != NULL) - if (!OSSL_PARAM_set_int(p, 0)) + if (p.seccat != NULL) + if (!OSSL_PARAM_set_int(p.seccat, 0)) goto err; - if ((p = OSSL_PARAM_locate(params, - OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS)) - != NULL) { + if (p.decoded != NULL) { int explicitparams = EC_KEY_decoded_from_explicit_params(eck); - if (explicitparams < 0 - || !OSSL_PARAM_set_int(p, explicitparams)) + if (explicitparams < 0 || !OSSL_PARAM_set_int(p.decoded, explicitparams)) goto err; } if (!sm2) { - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL - && !OSSL_PARAM_set_utf8_string(p, EC_DEFAULT_MD)) + if (p.default_digest != NULL + && !OSSL_PARAM_set_utf8_string(p.default_digest, EC_DEFAULT_MD)) goto err; } else { - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL - && !OSSL_PARAM_set_utf8_string(p, SM2_DEFAULT_MD)) + if (p.default_digest != NULL + && !OSSL_PARAM_set_utf8_string(p.default_digest, SM2_DEFAULT_MD)) goto err; } /* SM2 doesn't support this PARAM */ - if (!sm2) { - p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH); - if (p != NULL) { - int ecdh_cofactor_mode = 0; + if (!sm2 && p.use_cofactor != NULL) { + int ecdh_cofactor_mode = 0; - ecdh_cofactor_mode = (EC_KEY_get_flags(eck) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0; + ecdh_cofactor_mode = (EC_KEY_get_flags(eck) & EC_FLAG_COFACTOR_ECDH) ? 1 : 0; - if (!OSSL_PARAM_set_int(p, ecdh_cofactor_mode)) - goto err; - } + if (!OSSL_PARAM_set_int(p.use_cofactor, ecdh_cofactor_mode)) + goto err; } - if ((p = OSSL_PARAM_locate(params, - OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY)) - != NULL) { + if (p.encoded_pub != NULL) { const EC_POINT *ecp = EC_KEY_get0_public_key(key); if (ecp == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); goto err; } - p->return_size = EC_POINT_point2oct(ecg, ecp, + p.encoded_pub->return_size = EC_POINT_point2oct(ecg, ecp, POINT_CONVERSION_UNCOMPRESSED, - p->data, p->data_size, bnctx); - if (p->return_size == 0) + p.encoded_pub->data, p.encoded_pub->data_size, bnctx); + if (p.encoded_pub->return_size == 0) goto err; } @@ -745,11 +773,11 @@ static int common_get_params(void *key, OSSL_PARAM params[], int sm2) * OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT is added based on the group's * asn1_form by ossl_ec_group_todata() below. */ - ret = ec_get_ecm_params(ecg, params) - && ossl_ec_group_todata(ecg, NULL, params, libctx, propq, bnctx, + ret = ec_get_ecm_params(ecg, &p) + && ossl_ec_group_todata_parsed(ecg, NULL, &p, libctx, propq, bnctx, &genbuf) - && key_to_params(eck, NULL, params, 1, &pub_key) - && otherparams_to_params(eck, NULL, params); + && key_to_params(eck, NULL, &p, 1, &pub_key) + && otherparams_to_params(eck, NULL, &p); err: OPENSSL_free(genbuf); OPENSSL_free(pub_key); @@ -763,86 +791,55 @@ static int ec_get_params(void *key, OSSL_PARAM params[]) return common_get_params(key, params, 0); } -#ifndef OPENSSL_NO_EC2M -#define EC2M_GETTABLE_DOM_PARAMS \ - OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_M, NULL), \ - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_CHAR2_TYPE, NULL, 0), \ - OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_TP_BASIS, NULL), \ - OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_PP_K1, NULL), \ - OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_PP_K2, NULL), \ - OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_CHAR2_PP_K3, NULL), -#else -#define EC2M_GETTABLE_DOM_PARAMS -#endif - -static const OSSL_PARAM ec_known_gettable_params[] = { - OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), - OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_FIELD_DEGREE, NULL), - OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), - OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), - OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_CATEGORY, NULL), - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0), - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), - OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, NULL), - EC_IMEXPORTABLE_DOM_PARAMETERS, - EC2M_GETTABLE_DOM_PARAMS - EC_IMEXPORTABLE_PUBLIC_KEY, - OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_PUB_X, NULL, 0), - OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_PUB_Y, NULL, 0), - EC_IMEXPORTABLE_PRIVATE_KEY, - EC_IMEXPORTABLE_OTHER_PARAMETERS, - OSSL_PARAM_END -}; - static const OSSL_PARAM *ec_gettable_params(void *provctx) { - return ec_known_gettable_params; + return ec_get_params_list; } -static const OSSL_PARAM ec_known_settable_params[] = { - OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL), - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0), - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, NULL, 0), - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0), - OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, NULL), - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE, NULL, 0), - OSSL_PARAM_END -}; - static const OSSL_PARAM *ec_settable_params(void *provctx) { - return ec_known_settable_params; + return ec_set_params_list; } -static int ec_set_params(void *key, const OSSL_PARAM params[]) +static int common_set_params(void *key, const EC_PARAMS *params) { EC_KEY *eck = key; - const OSSL_PARAM *p; if (key == NULL) return 0; - if (ossl_param_is_empty(params)) - return 1; - if (!ossl_ec_group_set_params((EC_GROUP *)EC_KEY_get0_group(key), params)) + if (!ossl_ec_group_set_params_parsed( + (EC_GROUP *)EC_KEY_get0_group(key), params)) return 0; - p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY); - if (p != NULL) { + if (params->encoded_pub != NULL) { BN_CTX *ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(key)); int ret = 1; if (ctx == NULL - || p->data_type != OSSL_PARAM_OCTET_STRING - || !EC_KEY_oct2key(key, p->data, p->data_size, ctx)) + || params->encoded_pub->data_type != OSSL_PARAM_OCTET_STRING + || !EC_KEY_oct2key(key, params->encoded_pub->data, + params->encoded_pub->data_size, ctx)) ret = 0; BN_CTX_free(ctx); if (!ret) return 0; } - return ossl_ec_key_otherparams_fromdata(eck, params); + return ossl_ec_key_otherparams_fromdata_parsed(eck, params); +} + +static int ec_set_params(void *key, const OSSL_PARAM params[]) +{ + EC_PARAMS p; + + if (key == NULL) + return 0; + if (ossl_param_is_empty(params)) + return 1; + if (!ec_set_params_decoder(params, &p)) + return 0; + return common_set_params(key, &p); } #ifndef FIPS_MODULE @@ -852,35 +849,27 @@ static int sm2_get_params(void *key, OSSL_PARAM params[]) return common_get_params(key, params, 1); } -static const OSSL_PARAM sm2_known_gettable_params[] = { - OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), - OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_FIELD_DEGREE, NULL), - OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), - OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0), - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), - OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, NULL), - EC_IMEXPORTABLE_DOM_PARAMETERS, - EC_IMEXPORTABLE_PUBLIC_KEY, - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_X, NULL, 0), - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_Y, NULL, 0), - EC_IMEXPORTABLE_PRIVATE_KEY, - OSSL_PARAM_END -}; - static const OSSL_PARAM *sm2_gettable_params(ossl_unused void *provctx) { - return sm2_known_gettable_params; + return sm2_get_params_list; } -static const OSSL_PARAM sm2_known_settable_params[] = { - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0), - OSSL_PARAM_END -}; - static const OSSL_PARAM *sm2_settable_params(ossl_unused void *provctx) { - return sm2_known_settable_params; + return sm2_set_params_list; +} + +static int sm2_set_params(void *key, const OSSL_PARAM params[]) +{ + EC_PARAMS p; + + if (key == NULL) + return 0; + if (ossl_param_is_empty(params)) + return 1; + if (!sm2_set_params_decoder(params, &p)) + return 0; + return common_set_params(key, &p); } static int sm2_validate(const void *keydata, int selection, int checktype) @@ -1008,15 +997,18 @@ static void *ec_gen_init(void *provctx, int selection, static void *sm2_gen_init(void *provctx, int selection, const OSSL_PARAM params[]) { - struct ec_gen_ctx *gctx = ec_gen_init(provctx, selection, params); + struct ec_gen_ctx *gctx = ec_gen_init(provctx, selection, NULL); if (gctx != NULL) { + if (!sm2_gen_set_params(gctx, params)) + goto err; if (gctx->group_name != NULL) return gctx; if ((gctx->group_name = OPENSSL_strdup("sm2")) != NULL) return gctx; - ec_gen_cleanup(gctx); } +err: + ec_gen_cleanup(gctx); return NULL; } #endif @@ -1050,79 +1042,96 @@ static int ec_gen_set_template(void *genctx, void *templ) return ec_gen_set_group(gctx, ec_group); } -#define COPY_INT_PARAM(params, key, val) \ - p = OSSL_PARAM_locate_const(params, key); \ - if (p != NULL && !OSSL_PARAM_get_int(p, &val)) \ +#define COPY_INT_PARAM(param, val) \ + if ((param) != NULL && !OSSL_PARAM_get_int(param, &val)) \ goto err; -#define COPY_UTF8_PARAM(params, key, val) \ - p = OSSL_PARAM_locate_const(params, key); \ - if (p != NULL) { \ - if (p->data_type != OSSL_PARAM_UTF8_STRING) \ - goto err; \ - OPENSSL_free(val); \ - val = OPENSSL_strdup(p->data); \ - if (val == NULL) \ - goto err; \ +#define COPY_UTF8_PARAM(param, val) \ + if ((param) != NULL) { \ + if ((param)->data_type != OSSL_PARAM_UTF8_STRING) \ + goto err; \ + OPENSSL_free(val); \ + val = OPENSSL_strdup((param)->data); \ + if (val == NULL) \ + goto err; \ } -#define COPY_OCTET_PARAM(params, key, val, len) \ - p = OSSL_PARAM_locate_const(params, key); \ - if (p != NULL) { \ - if (p->data_type != OSSL_PARAM_OCTET_STRING) \ - goto err; \ - OPENSSL_free(val); \ - len = p->data_size; \ - val = OPENSSL_memdup(p->data, p->data_size); \ - if (val == NULL) \ - goto err; \ +#define COPY_OCTET_PARAM(param, val, len) \ + if ((param) != NULL) { \ + if ((param)->data_type != OSSL_PARAM_OCTET_STRING) \ + goto err; \ + OPENSSL_free(val); \ + len = (param)->data_size; \ + val = OPENSSL_memdup((param)->data, (param)->data_size); \ + if (val == NULL) \ + goto err; \ } -#define COPY_BN_PARAM(params, key, bn) \ - p = OSSL_PARAM_locate_const(params, key); \ - if (p != NULL) { \ - if (bn == NULL) \ - bn = BN_new(); \ - if (bn == NULL || !OSSL_PARAM_get_BN(p, &bn)) \ - goto err; \ +#define COPY_BN_PARAM(param, bn) \ + if ((param) != NULL) { \ + if (bn == NULL) \ + bn = BN_new(); \ + if (bn == NULL || !OSSL_PARAM_get_BN(param, &bn)) \ + goto err; \ } -static int ec_gen_set_params(void *genctx, const OSSL_PARAM params[]) +static int ec_gen_set_params_parsed(struct ec_gen_ctx *gctx, + const EC_PARAMS *p) { int ret = 0; - struct ec_gen_ctx *gctx = genctx; - const OSSL_PARAM *p; - if (!OSSL_FIPS_IND_SET_CTX_PARAM(gctx, OSSL_FIPS_IND_SETTABLE0, params, - OSSL_PKEY_PARAM_FIPS_KEY_CHECK)) + if (gctx == NULL || p == NULL) + goto err; + if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(gctx, OSSL_FIPS_IND_SETTABLE0, + p->fips_key_check)) goto err; - COPY_INT_PARAM(params, OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, gctx->ecdh_mode); + COPY_INT_PARAM(p->use_cofactor, gctx->ecdh_mode); - COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_GROUP_NAME, gctx->group_name); - COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_FIELD_TYPE, gctx->field_type); - COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_ENCODING, gctx->encoding); - COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, gctx->pt_format); - COPY_UTF8_PARAM(params, OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE, gctx->group_check); + COPY_UTF8_PARAM(p->group_name, gctx->group_name); + COPY_UTF8_PARAM(p->field_type, gctx->field_type); + COPY_UTF8_PARAM(p->encoding, gctx->encoding); + COPY_UTF8_PARAM(p->pt_format, gctx->pt_format); + COPY_UTF8_PARAM(p->group_check, gctx->group_check); - COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_P, gctx->p); - COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_A, gctx->a); - COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_B, gctx->b); - COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_ORDER, gctx->order); - COPY_BN_PARAM(params, OSSL_PKEY_PARAM_EC_COFACTOR, gctx->cofactor); + COPY_BN_PARAM(p->p, gctx->p); + COPY_BN_PARAM(p->a, gctx->a); + COPY_BN_PARAM(p->b, gctx->b); + COPY_BN_PARAM(p->order, gctx->order); + COPY_BN_PARAM(p->cofactor, gctx->cofactor); - COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_SEED, gctx->seed, gctx->seed_len); - COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_EC_GENERATOR, gctx->gen, - gctx->gen_len); + COPY_OCTET_PARAM(p->seed, gctx->seed, gctx->seed_len); + COPY_OCTET_PARAM(p->generator, gctx->gen, gctx->gen_len); - COPY_OCTET_PARAM(params, OSSL_PKEY_PARAM_DHKEM_IKM, gctx->dhkem_ikm, - gctx->dhkem_ikmlen); + COPY_OCTET_PARAM(p->dhkem_ikm, gctx->dhkem_ikm, gctx->dhkem_ikmlen); ret = 1; err: return ret; } +static int ec_gen_set_params(void *genctx, const OSSL_PARAM params[]) +{ + EC_PARAMS p; + + if (!ec_gen_set_params_decoder(params, &p)) + return 0; + return ec_gen_set_params_parsed(genctx, &p); +} + +#ifndef FIPS_MODULE +#ifndef OPENSSL_NO_SM2 +static int sm2_gen_set_params(void *genctx, const OSSL_PARAM params[]) +{ + EC_PARAMS p; + + if (!sm2_gen_set_params_decoder(params, &p)) + return 0; + return ec_gen_set_params_parsed(genctx, &p); +} +#endif +#endif + static int ec_gen_set_group_from_params(struct ec_gen_ctx *gctx) { int ret = 0; @@ -1203,44 +1212,34 @@ static int ec_gen_set_group_from_params(struct ec_gen_ctx *gctx) static const OSSL_PARAM *ec_gen_settable_params(ossl_unused void *genctx, ossl_unused void *provctx) { - static const OSSL_PARAM settable[] = { - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, NULL, 0), - OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL), - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, NULL, 0), - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, NULL, 0), - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_FIELD_TYPE, NULL, 0), - OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_P, NULL, 0), - OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_A, NULL, 0), - OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_B, NULL, 0), - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0), - OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0), - OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0), - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0), - OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_DHKEM_IKM, NULL, 0), - OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_PKEY_PARAM_FIPS_KEY_CHECK) - OSSL_PARAM_END - }; - return settable; + return ec_gen_set_params_list; } +#ifndef FIPS_MODULE +#ifndef OPENSSL_NO_SM2 +static const OSSL_PARAM *sm2_gen_settable_params(ossl_unused void *genctx, + ossl_unused void *provctx) +{ + return sm2_gen_set_params_list; +} +#endif +#endif + static const OSSL_PARAM *ec_gen_gettable_params(ossl_unused void *genctx, ossl_unused void *provctx) { - static const OSSL_PARAM known_ec_gen_gettable_ctx_params[] = { - OSSL_FIPS_IND_GETTABLE_CTX_PARAM() - OSSL_PARAM_END - }; - return known_ec_gen_gettable_ctx_params; + return ec_gen_get_params_list; } static int ec_gen_get_params(void *genctx, OSSL_PARAM *params) { struct ec_gen_ctx *gctx = genctx; + EC_PARAMS p; - if (gctx == NULL) + if (gctx == NULL || !ec_gen_get_params_decoder(params, &p)) return 0; - if (!OSSL_FIPS_IND_GET_CTX_PARAM(gctx, params)) + if (!OSSL_FIPS_IND_GET_CTX_FROM_PARAM(gctx, p.fips_indicator)) return 0; return 1; @@ -1503,24 +1502,24 @@ const OSSL_DISPATCH ossl_ec_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_GEN_INIT, (void (*)(void))sm2_gen_init }, \ { OSSL_FUNC_KEYMGMT_GEN_SET_TEMPLATE, \ (void (*)(void))ec_gen_set_template }, \ - { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))ec_gen_set_params }, \ + { OSSL_FUNC_KEYMGMT_GEN_SET_PARAMS, (void (*)(void))sm2_gen_set_params }, \ { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, \ - (void (*)(void))ec_gen_settable_params }, \ + (void (*)(void))sm2_gen_settable_params }, \ { OSSL_FUNC_KEYMGMT_GEN, (void (*)(void))sm2_gen }, \ { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))ec_gen_cleanup }, \ { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))sm2_load }, \ { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ec_freedata }, \ { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))sm2_get_params }, \ { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))sm2_gettable_params }, \ - { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))ec_set_params }, \ + { OSSL_FUNC_KEYMGMT_SET_PARAMS, (void (*)(void))sm2_set_params }, \ { OSSL_FUNC_KEYMGMT_SETTABLE_PARAMS, (void (*)(void))sm2_settable_params }, \ { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ec_has }, \ { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ec_match }, \ { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))sm2_validate }, \ { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))sm2_import }, \ - { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))ec_import_types }, \ + { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))sm2_import_types }, \ { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))ec_export }, \ - { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))ec_export_types }, \ + { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))sm2_export_types }, \ { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, \ (void (*)(void))variant##_query_operation_name }, \ { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ec_dup }, \ diff --git a/providers/implementations/keymgmt/ec_kmgmt_imexport.inc b/providers/implementations/keymgmt/ec_kmgmt_imexport.inc deleted file mode 100644 index b242fd17eef27..0000000000000 --- a/providers/implementations/keymgmt/ec_kmgmt_imexport.inc +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html -*/ - -/* - * This file is meant to be included from ec_kmgmt.c - */ - -static const OSSL_PARAM ec_private_key_types[] = { - EC_IMEXPORTABLE_PRIVATE_KEY, - OSSL_PARAM_END -}; -static const OSSL_PARAM ec_public_key_types[] = { - EC_IMEXPORTABLE_PUBLIC_KEY, - OSSL_PARAM_END -}; -static const OSSL_PARAM ec_key_types[] = { - EC_IMEXPORTABLE_PRIVATE_KEY, - EC_IMEXPORTABLE_PUBLIC_KEY, - OSSL_PARAM_END -}; -static const OSSL_PARAM ec_dom_parameters_types[] = { - EC_IMEXPORTABLE_DOM_PARAMETERS, - OSSL_PARAM_END -}; -static const OSSL_PARAM ec_5_types[] = { - EC_IMEXPORTABLE_PRIVATE_KEY, - EC_IMEXPORTABLE_DOM_PARAMETERS, - OSSL_PARAM_END -}; -static const OSSL_PARAM ec_6_types[] = { - EC_IMEXPORTABLE_PUBLIC_KEY, - EC_IMEXPORTABLE_DOM_PARAMETERS, - OSSL_PARAM_END -}; -static const OSSL_PARAM ec_key_domp_types[] = { - EC_IMEXPORTABLE_PRIVATE_KEY, - EC_IMEXPORTABLE_PUBLIC_KEY, - EC_IMEXPORTABLE_DOM_PARAMETERS, - OSSL_PARAM_END -}; -static const OSSL_PARAM ec_other_parameters_types[] = { - EC_IMEXPORTABLE_OTHER_PARAMETERS, - OSSL_PARAM_END -}; -static const OSSL_PARAM ec_9_types[] = { - EC_IMEXPORTABLE_PRIVATE_KEY, - EC_IMEXPORTABLE_OTHER_PARAMETERS, - OSSL_PARAM_END -}; -static const OSSL_PARAM ec_10_types[] = { - EC_IMEXPORTABLE_PUBLIC_KEY, - EC_IMEXPORTABLE_OTHER_PARAMETERS, - OSSL_PARAM_END -}; -static const OSSL_PARAM ec_11_types[] = { - EC_IMEXPORTABLE_PRIVATE_KEY, - EC_IMEXPORTABLE_PUBLIC_KEY, - EC_IMEXPORTABLE_OTHER_PARAMETERS, - OSSL_PARAM_END -}; -static const OSSL_PARAM ec_all_parameters_types[] = { - EC_IMEXPORTABLE_DOM_PARAMETERS, - EC_IMEXPORTABLE_OTHER_PARAMETERS, - OSSL_PARAM_END -}; -static const OSSL_PARAM ec_13_types[] = { - EC_IMEXPORTABLE_PRIVATE_KEY, - EC_IMEXPORTABLE_DOM_PARAMETERS, - EC_IMEXPORTABLE_OTHER_PARAMETERS, - OSSL_PARAM_END -}; -static const OSSL_PARAM ec_14_types[] = { - EC_IMEXPORTABLE_PUBLIC_KEY, - EC_IMEXPORTABLE_DOM_PARAMETERS, - EC_IMEXPORTABLE_OTHER_PARAMETERS, - OSSL_PARAM_END -}; -static const OSSL_PARAM ec_all_types[] = { - EC_IMEXPORTABLE_PRIVATE_KEY, - EC_IMEXPORTABLE_PUBLIC_KEY, - EC_IMEXPORTABLE_DOM_PARAMETERS, - EC_IMEXPORTABLE_OTHER_PARAMETERS, - OSSL_PARAM_END -}; - -static const OSSL_PARAM *const ec_types[] = { - NULL, - ec_private_key_types, - ec_public_key_types, - ec_key_types, - ec_dom_parameters_types, - ec_5_types, - ec_6_types, - ec_key_domp_types, - ec_other_parameters_types, - ec_9_types, - ec_10_types, - ec_11_types, - ec_all_parameters_types, - ec_13_types, - ec_14_types, - ec_all_types -}; diff --git a/providers/implementations/keymgmt/ecx_kmgmt.c b/providers/implementations/keymgmt/ecx_kmgmt.c index dd9c029a4ac58..8989ece58c942 100644 --- a/providers/implementations/keymgmt/ecx_kmgmt.c +++ b/providers/implementations/keymgmt/ecx_kmgmt.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/keymgmt/kdf_legacy_kmgmt.c b/providers/implementations/keymgmt/kdf_legacy_kmgmt.c index deb49600066d9..1027bb1787504 100644 --- a/providers/implementations/keymgmt/kdf_legacy_kmgmt.c +++ b/providers/implementations/keymgmt/kdf_legacy_kmgmt.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -75,8 +75,7 @@ int ossl_kdf_data_up_ref(KDF_DATA *kdfdata) if (!ossl_prov_is_running()) return 0; - CRYPTO_UP_REF(&kdfdata->refcnt, &ref); - return 1; + return CRYPTO_UP_REF(&kdfdata->refcnt, &ref); } static void *kdf_newdata(void *provctx) diff --git a/providers/implementations/keymgmt/mac_legacy_kmgmt.c b/providers/implementations/keymgmt/mac_legacy_kmgmt.c index d3082ca772e80..8c54537a33f66 100644 --- a/providers/implementations/keymgmt/mac_legacy_kmgmt.c +++ b/providers/implementations/keymgmt/mac_legacy_kmgmt.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -110,8 +110,7 @@ int ossl_mac_key_up_ref(MAC_KEY *mackey) if (!ossl_prov_is_running()) return 0; - CRYPTO_UP_REF(&mackey->refcnt, &ref); - return 1; + return CRYPTO_UP_REF(&mackey->refcnt, &ref); } static void *mac_new(void *provctx) diff --git a/providers/implementations/keymgmt/ml_dsa_kmgmt.c b/providers/implementations/keymgmt/ml_dsa_kmgmt.c index 24406ac602ab9..97de656676c21 100644 --- a/providers/implementations/keymgmt/ml_dsa_kmgmt.c +++ b/providers/implementations/keymgmt/ml_dsa_kmgmt.c @@ -100,6 +100,7 @@ static int ml_dsa_pairwise_test(const ML_DSA_KEY *key) err: OSSL_SELF_TEST_onend(st, ret); OSSL_SELF_TEST_free(st); + OPENSSL_cleanse(sig, sizeof(sig)); return ret; } #endif @@ -144,6 +145,23 @@ ML_DSA_KEY *ossl_prov_ml_dsa_new(PROV_CTX *ctx, const char *propq, int evp_type) return key; } +static ML_DSA_KEY *ossl_prov_ml_dsa_new_ex(PROV_CTX *ctx, const OSSL_PARAM params[], int evp_type) +{ + struct ml_dsa_new_key_ex_params_st p; + const char *propq = NULL; + + if (!ml_dsa_new_key_ex_params_decoder(params, &p)) + return 0; + + if (p.propq != NULL) { + if (p.propq->data_type != OSSL_PARAM_UTF8_STRING) + return 0; + propq = p.propq->data; + } + + return ossl_prov_ml_dsa_new(ctx, propq, evp_type); +} + static void ml_dsa_free_key(void *keydata) { ossl_ml_dsa_key_free((ML_DSA_KEY *)keydata); @@ -565,7 +583,7 @@ static void ml_dsa_gen_cleanup(void *genctx) if (gctx == NULL) return; - OPENSSL_cleanse(gctx->entropy, gctx->entropy_len); + OPENSSL_cleanse(gctx->entropy, sizeof(gctx->entropy)); OPENSSL_free(gctx->propq); OPENSSL_free(gctx); } @@ -584,12 +602,17 @@ static void ml_dsa_gen_cleanup(void *genctx) { \ return ossl_prov_ml_dsa_new(provctx, NULL, EVP_PKEY_ML_DSA_##alg); \ } \ + static void *ml_dsa_##alg##_new_key_ex(void *provctx, const OSSL_PARAM params[]) \ + { \ + return ossl_prov_ml_dsa_new_ex(provctx, params, EVP_PKEY_ML_DSA_##alg); \ + } \ static void *ml_dsa_##alg##_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) \ { \ return ml_dsa_gen(genctx, EVP_PKEY_ML_DSA_##alg); \ } \ const OSSL_DISPATCH ossl_ml_dsa_##alg##_keymgmt_functions[] = { \ { OSSL_FUNC_KEYMGMT_NEW, (void (*)(void))ml_dsa_##alg##_new_key }, \ + { OSSL_FUNC_KEYMGMT_NEW_EX, (void (*)(void))ml_dsa_##alg##_new_key_ex }, \ { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))ml_dsa_free_key }, \ { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))ml_dsa_has }, \ { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))ml_dsa_match }, \ diff --git a/providers/implementations/keymgmt/ml_dsa_kmgmt.inc.in b/providers/implementations/keymgmt/ml_dsa_kmgmt.inc.in index 9ab17f5f65f45..b26909c88ce0c 100644 --- a/providers/implementations/keymgmt/ml_dsa_kmgmt.inc.in +++ b/providers/implementations/keymgmt/ml_dsa_kmgmt.inc.in @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the \"License\"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -39,3 +39,7 @@ use OpenSSL::paramnames qw(produce_param_decoder); (['OSSL_PKEY_PARAM_ML_DSA_SEED', 'seed', 'octet_string'], ['OSSL_PKEY_PARAM_PROPERTIES', 'propq', 'utf8_string'], )); -} + +{- produce_param_decoder('ml_dsa_new_key_ex_params', + (['OSSL_PKEY_PARAM_PROPERTIES', 'propq', 'utf8_string'], + )); -} diff --git a/providers/implementations/keymgmt/ml_kem_kmgmt.c b/providers/implementations/keymgmt/ml_kem_kmgmt.c index d7f2d876857b7..9101b6ad5d74e 100644 --- a/providers/implementations/keymgmt/ml_kem_kmgmt.c +++ b/providers/implementations/keymgmt/ml_kem_kmgmt.c @@ -118,10 +118,6 @@ static int ml_kem_pairwise_test(const ML_KEM_KEY *key, int key_flags) memset(out, 0, sizeof(out)); - /* - * The pairwise test is skipped unless either RANDOM or FIXED entropy PCTs - * are enabled. - */ if (key_flags & ML_KEM_KEY_RANDOM_PCT) { operation_result = ossl_ml_kem_encap_rand(ctext, v->ctext_bytes, secret, sizeof(secret), key); @@ -156,7 +152,10 @@ static int ml_kem_pairwise_test(const ML_KEM_KEY *key, int key_flags) v->algorithm_name); } #endif - OPENSSL_free(ctext); + OPENSSL_cleanse((void *)entropy, sizeof(entropy)); + OPENSSL_cleanse((void *)secret, sizeof(secret)); + OPENSSL_cleanse((void *)out, sizeof(out)); + OPENSSL_clear_free(ctext, v->ctext_bytes); return ret; } @@ -338,7 +337,7 @@ static int ml_kem_export(void *vkey, int selection, OSSL_CALLBACK *param_cb, OSSL_PARAM_BLD_free(tmpl); OPENSSL_secure_clear_free(seedenc, seedlen); OPENSSL_secure_clear_free(prvenc, prvlen); - OPENSSL_free(pubenc); + OPENSSL_clear_free(pubenc, v->pubkey_bytes); return ret; } @@ -549,12 +548,14 @@ static void *ml_kem_load(const void *reference, size_t reference_sz) goto err; } OPENSSL_secure_clear_free(encoded_dk, key->vinfo->prvkey_bytes); + OPENSSL_cleanse((void *)seed, sizeof(seed)); return key; } err: if (key != NULL && key->vinfo != NULL) OPENSSL_secure_clear_free(encoded_dk, key->vinfo->prvkey_bytes); + OPENSSL_cleanse((void *)seed, sizeof(seed)); ossl_ml_kem_key_free(key); return NULL; } @@ -722,6 +723,7 @@ static int ml_kem_gen_set_params(void *vgctx, const OSSL_PARAM params[]) /* Possibly, but less likely wrong data type */ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH); + OPENSSL_cleanse((void *)gctx->seedbuf, sizeof(gctx->seedbuf)); gctx->seed = NULL; return 0; } @@ -778,8 +780,10 @@ static void *ml_kem_gen(void *vgctx, OSSL_CALLBACK *osslcb, void *cbarg) if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) return key; - if (seed != NULL && !ossl_ml_kem_set_seed(seed, ML_KEM_SEED_BYTES, key)) + if (seed != NULL && !ossl_ml_kem_set_seed(seed, ML_KEM_SEED_BYTES, key)) { + ossl_ml_kem_key_free(key); return NULL; + } genok = ossl_ml_kem_genkey(nopub, 0, key); /* Erase the single-use seed */ diff --git a/providers/implementations/keymgmt/ml_kem_kmgmt.inc.in b/providers/implementations/keymgmt/ml_kem_kmgmt.inc.in index 76ef7fd571fcc..fa749ebe1667c 100644 --- a/providers/implementations/keymgmt/ml_kem_kmgmt.inc.in +++ b/providers/implementations/keymgmt/ml_kem_kmgmt.inc.in @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the \"License\"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/keymgmt/mlx_kmgmt.c b/providers/implementations/keymgmt/mlx_kmgmt.c index 00ac258682a18..4612250570e84 100644 --- a/providers/implementations/keymgmt/mlx_kmgmt.c +++ b/providers/implementations/keymgmt/mlx_kmgmt.c @@ -45,14 +45,17 @@ static const int minimal_selection = OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS /* Must match DECLARE_DISPATCH invocations at the end of the file */ static const ECDH_VINFO hybrid_vtable[] = { + { "EC", "P-256", 65, 32, 32, 1, EVP_PKEY_ML_KEM_512 }, { "EC", "P-256", 65, 32, 32, 1, EVP_PKEY_ML_KEM_768 }, { "EC", "P-384", 97, 48, 48, 1, EVP_PKEY_ML_KEM_1024 }, #if !defined(OPENSSL_NO_ECX) + { "X25519", NULL, 32, 32, 32, 0, EVP_PKEY_ML_KEM_512 }, { "X25519", NULL, 32, 32, 32, 0, EVP_PKEY_ML_KEM_768 }, { "X448", NULL, 56, 56, 56, 0, EVP_PKEY_ML_KEM_1024 }, #else { NULL, NULL, 0, 0, 0, 0, NID_undef }, { NULL, NULL, 0, 0, 0, 0, NID_undef }, + { NULL, NULL, 0, 0, 0, 0, NID_undef }, #endif #if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_SM2) { "curveSM2", "SM2", 65, 32, 32, 1, EVP_PKEY_ML_KEM_768 }, @@ -200,9 +203,8 @@ static int export_sub_cb(const OSSL_PARAM *params, void *varg) return 0; if (len != sub_arg->prvlen) { ERR_raise_data(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR, - "Unexpected %s private key length %lu != %lu", - sub_arg->algorithm_name, (unsigned long)len, - (unsigned long)sub_arg->publen); + "Unexpected %s private key length %zu != %zu", + sub_arg->algorithm_name, len, sub_arg->prvlen); return 0; } ++sub_arg->prvcount; @@ -320,7 +322,7 @@ static int mlx_kem_export(void *vkey, int selection, OSSL_CALLBACK *param_cb, err: OSSL_PARAM_BLD_free(tmpl); OPENSSL_secure_clear_free(sub_arg.prvenc, prvlen); - OPENSSL_free(sub_arg.pubenc); + OPENSSL_clear_free(sub_arg.pubenc, publen); return ret; } @@ -393,7 +395,9 @@ load_keys(MLX_KEY *key, } else if (publen) { /* Absent private key data, import public keys */ if (!load_slot(key->libctx, key->propq, OSSL_PKEY_PARAM_PUB_KEY, - minimal_selection, key, slot, pubenc, + OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS + | OSSL_KEYMGMT_SELECT_PUBLIC_KEY, + key, slot, pubenc, (int)key->minfo->pubkey_bytes, (int)key->xinfo->pubkey_bytes)) goto err; @@ -564,12 +568,18 @@ static int mlx_kem_get_params(void *vkey, OSSL_PARAM params[]) selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS; /* Extract sub-component key material */ - if (!export_sub(&sub_arg, selection, key)) - return 0; - - if ((pub != NULL && sub_arg.pubcount != 2) - || (prv != NULL && sub_arg.prvcount != 2)) + if (!export_sub(&sub_arg, selection, key) + || (pub != NULL && sub_arg.pubcount != 2) + || (prv != NULL && sub_arg.prvcount != 2)) { + /* Erase any partial key material on failure */ + if (sub_arg.pubenc != NULL) + OPENSSL_cleanse(sub_arg.pubenc, + key->minfo->pubkey_bytes + key->xinfo->pubkey_bytes); + if (sub_arg.prvenc != NULL) + OPENSSL_cleanse(sub_arg.prvenc, + key->minfo->prvkey_bytes + key->xinfo->prvkey_bytes); return 0; + } return 1; } @@ -797,12 +807,14 @@ static void *mlx_kem_dup(const void *vkey, int selection) OSSL_DISPATCH_END \ } /* See |hybrid_vtable| above */ -DECLARE_DISPATCH(p256, 0); -DECLARE_DISPATCH(p384, 1); +DECLARE_DISPATCH(p256_512, 0); +DECLARE_DISPATCH(p256, 1); +DECLARE_DISPATCH(p384, 2); #if !defined(OPENSSL_NO_ECX) -DECLARE_DISPATCH(x25519, 2); -DECLARE_DISPATCH(x448, 3); +DECLARE_DISPATCH(x25519_512, 3); +DECLARE_DISPATCH(x25519, 4); +DECLARE_DISPATCH(x448, 5); #endif #if !defined(FIPS_MODULE) && !defined(OPENSSL_NO_SM2) -DECLARE_DISPATCH(curve_sm2, 4); +DECLARE_DISPATCH(curve_sm2, 6); #endif diff --git a/providers/implementations/keymgmt/rsa_kmgmt.c b/providers/implementations/keymgmt/rsa_kmgmt.c index 06b4312998366..ceb6f02cda52e 100644 --- a/providers/implementations/keymgmt/rsa_kmgmt.c +++ b/providers/implementations/keymgmt/rsa_kmgmt.c @@ -24,6 +24,7 @@ #include "prov/providercommon.h" #include "prov/provider_ctx.h" #include "crypto/rsa.h" +#include "crypto/rsa_params.h" #include "crypto/cryptlib.h" #include "internal/fips.h" #include "internal/param_build_set.h" @@ -43,14 +44,18 @@ static OSSL_FUNC_keymgmt_load_fn rsa_load; static OSSL_FUNC_keymgmt_load_fn rsapss_load; static OSSL_FUNC_keymgmt_free_fn rsa_freedata; static OSSL_FUNC_keymgmt_get_params_fn rsa_get_params; +static OSSL_FUNC_keymgmt_get_params_fn rsapss_get_params; static OSSL_FUNC_keymgmt_gettable_params_fn rsa_gettable_params; +static OSSL_FUNC_keymgmt_gettable_params_fn rsapss_gettable_params; static OSSL_FUNC_keymgmt_has_fn rsa_has; static OSSL_FUNC_keymgmt_match_fn rsa_match; static OSSL_FUNC_keymgmt_validate_fn rsa_validate; static OSSL_FUNC_keymgmt_import_fn rsa_import; static OSSL_FUNC_keymgmt_import_types_fn rsa_import_types; +static OSSL_FUNC_keymgmt_import_types_fn rsapss_import_types; static OSSL_FUNC_keymgmt_export_fn rsa_export; static OSSL_FUNC_keymgmt_export_types_fn rsa_export_types; +static OSSL_FUNC_keymgmt_export_types_fn rsapss_export_types; static OSSL_FUNC_keymgmt_query_operation_name_fn rsa_query_operation_name; static OSSL_FUNC_keymgmt_dup_fn rsa_dup; @@ -62,11 +67,11 @@ DEFINE_STACK_OF(BIGNUM) DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) static int pss_params_fromdata(RSA_PSS_PARAMS_30 *pss_params, int *defaults_set, - const OSSL_PARAM params[], int rsa_type, + const RSA_PARAMS *p, int rsa_type, OSSL_LIB_CTX *libctx) { - if (!ossl_rsa_pss_params_30_fromdata(pss_params, defaults_set, - params, libctx)) + if (!ossl_rsa_pss_params_30_fromdata_parsed(pss_params, defaults_set, + p, libctx)) return 0; /* If not a PSS type RSA, sending us PSS parameters is wrong */ @@ -227,9 +232,79 @@ static int rsa_match(const void *keydata1, const void *keydata2, int selection) return ok; } +enum { + RSA_IMEXPORT_TYPE_NONE = 0, + RSA_IMEXPORT_TYPE_OTHER = 1, + RSA_IMEXPORT_TYPE_KEY = 2, + RSA_IMEXPORT_TYPE_ALL = RSA_IMEXPORT_TYPE_OTHER | RSA_IMEXPORT_TYPE_KEY, + RSA_IMEXPORT_TYPE_COUNT +}; + +typedef int (*rsa_import_types_decoder_fn)(const OSSL_PARAM *, RSA_PARAMS *); + +struct rsa_imexport_types_st { + const OSSL_PARAM *import_types; + rsa_import_types_decoder_fn import_decoder; + const OSSL_PARAM *export_types; +}; + +static const struct rsa_imexport_types_st + rsa_imexport_types[RSA_IMEXPORT_TYPE_COUNT] + = { + [RSA_IMEXPORT_TYPE_OTHER] = { + rsa_other_import_types_list, + rsa_other_import_types_decoder, + rsa_other_export_types_list, + }, + [RSA_IMEXPORT_TYPE_KEY] = { + rsa_key_import_types_list, + rsa_key_import_types_decoder, + rsa_key_export_types_list, + }, + [RSA_IMEXPORT_TYPE_ALL] = { + rsa_all_import_types_list, + rsa_all_import_types_decoder, + rsa_all_export_types_list, + }, + }; + +static const struct rsa_imexport_types_st + rsapss_imexport_types[RSA_IMEXPORT_TYPE_COUNT] + = { + [RSA_IMEXPORT_TYPE_OTHER] = { + rsapss_other_import_types_list, + rsapss_other_import_types_decoder, + rsapss_other_export_types_list, + }, + [RSA_IMEXPORT_TYPE_KEY] = { + rsapss_key_import_types_list, + rsapss_key_import_types_decoder, + rsapss_key_export_types_list, + }, + [RSA_IMEXPORT_TYPE_ALL] = { + rsapss_all_import_types_list, + rsapss_all_import_types_decoder, + rsapss_all_export_types_list, + }, + }; + +static int rsa_imexport_type_select(int selection) +{ + int type_select = RSA_IMEXPORT_TYPE_NONE; + + if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) + type_select |= RSA_IMEXPORT_TYPE_OTHER; + if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) + type_select |= RSA_IMEXPORT_TYPE_KEY; + return type_select; +} + static int rsa_import(void *keydata, int selection, const OSSL_PARAM params[]) { RSA *rsa = keydata; + RSA_PARAMS p; + const struct rsa_imexport_types_st *types; + int type_select; int rsa_type; int ok = 1; int pss_defaults_set = 0; @@ -237,17 +312,21 @@ static int rsa_import(void *keydata, int selection, const OSSL_PARAM params[]) if (!ossl_prov_is_running() || rsa == NULL) return 0; - if ((selection & RSA_POSSIBLE_SELECTIONS) == 0) - return 0; - + type_select = rsa_imexport_type_select(selection); rsa_type = RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK); + types = rsa_type == RSA_FLAG_TYPE_RSASSAPSS + ? rsapss_imexport_types + : rsa_imexport_types; + if (type_select == RSA_IMEXPORT_TYPE_NONE + || !types[type_select].import_decoder(params, &p)) + return 0; if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) - ok = ok && pss_params_fromdata(ossl_rsa_get0_pss_params_30(rsa), &pss_defaults_set, params, rsa_type, ossl_rsa_get0_libctx(rsa)); + ok = ok && pss_params_fromdata(ossl_rsa_get0_pss_params_30(rsa), &pss_defaults_set, &p, rsa_type, ossl_rsa_get0_libctx(rsa)); if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) { int include_private = selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY ? 1 : 0; - ok = ok && ossl_rsa_fromdata(rsa, params, include_private); + ok = ok && ossl_rsa_fromdata_parsed(rsa, &p, include_private); } return ok; @@ -260,12 +339,14 @@ static int rsa_export(void *keydata, int selection, const RSA_PSS_PARAMS_30 *pss_params = ossl_rsa_get0_pss_params_30(rsa); OSSL_PARAM_BLD *tmpl; OSSL_PARAM *params = NULL; + int type_select; int ok = 1; if (!ossl_prov_is_running() || rsa == NULL) return 0; - if ((selection & RSA_POSSIBLE_SELECTIONS) == 0) + type_select = rsa_imexport_type_select(selection); + if (type_select == RSA_IMEXPORT_TYPE_NONE) return 0; tmpl = OSSL_PARAM_BLD_new(); @@ -292,121 +373,64 @@ static int rsa_export(void *keydata, int selection, return ok; } -#ifdef FIPS_MODULE -/* In fips mode there are no multi-primes. */ -#define RSA_KEY_MP_TYPES() \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR1, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR2, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT1, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT2, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, NULL, 0), -#else -/* - * We allow up to 10 prime factors (starting with p, q). - * NOTE: there is only 9 OSSL_PKEY_PARAM_RSA_COEFFICIENT - */ -#define RSA_KEY_MP_TYPES() \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR1, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR2, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR3, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR4, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR5, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR6, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR7, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR8, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR9, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_FACTOR10, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT1, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT2, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT3, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT4, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT5, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT6, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT7, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT8, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT9, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_EXPONENT10, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT2, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT3, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT4, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT5, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT6, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT7, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT8, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_COEFFICIENT9, NULL, 0), -#endif - -#define RSA_KEY_TYPES() \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_N, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_E, NULL, 0), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_D, NULL, 0), \ - RSA_KEY_MP_TYPES() - -/* - * This provider can export everything in an RSA key, so we use the exact - * same type description for export as for import. Other providers might - * choose to import full keys, but only export the public parts, and will - * therefore have the importkey_types and importkey_types functions return - * different arrays. - */ -static const OSSL_PARAM rsa_key_types[] = { - RSA_KEY_TYPES() - OSSL_PARAM_END -}; -/* - * We lied about the amount of factors, exponents and coefficients, the - * export and import functions can really deal with an infinite amount - * of these numbers. However, RSA keys with too many primes are futile, - * so we at least pretend to have some limits. - */ - -static const OSSL_PARAM *rsa_imexport_types(int selection) +static const OSSL_PARAM *rsa_import_types(int selection) { - if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) - return rsa_key_types; - return NULL; + return rsa_imexport_types[rsa_imexport_type_select(selection)].import_types; } -static const OSSL_PARAM *rsa_import_types(int selection) +static const OSSL_PARAM *rsapss_import_types(int selection) { - return rsa_imexport_types(selection); + return rsapss_imexport_types[rsa_imexport_type_select(selection)] + .import_types; } static const OSSL_PARAM *rsa_export_types(int selection) { - return rsa_imexport_types(selection); + return rsa_imexport_types[rsa_imexport_type_select(selection)].export_types; } -static int rsa_get_params(void *key, OSSL_PARAM params[]) +static const OSSL_PARAM *rsapss_export_types(int selection) +{ + return rsapss_imexport_types[rsa_imexport_type_select(selection)] + .export_types; +} + +typedef int (*rsa_get_params_decoder_fn)(const OSSL_PARAM *, RSA_PARAMS *); + +static int common_get_params(void *key, OSSL_PARAM params[], + rsa_get_params_decoder_fn decoder) { RSA *rsa = key; - const RSA_PSS_PARAMS_30 *pss_params = ossl_rsa_get0_pss_params_30(rsa); - int rsa_type = RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK); - OSSL_PARAM *p; - int empty = RSA_get0_n(rsa) == NULL; + RSA_PARAMS p; + const RSA_PSS_PARAMS_30 *pss_params; + int rsa_type, empty; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_BITS)) != NULL - && (empty || !OSSL_PARAM_set_int(p, RSA_bits(rsa)))) + if (rsa == NULL || !decoder(params, &p)) return 0; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_BITS)) != NULL - && (empty || !OSSL_PARAM_set_int(p, RSA_security_bits(rsa)))) + pss_params = ossl_rsa_get0_pss_params_30(rsa); + rsa_type = RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK); + empty = RSA_get0_n(rsa) == NULL; + + if (p.bits != NULL && (empty || !OSSL_PARAM_set_int(p.bits, RSA_bits(rsa)))) + return 0; + if (p.secbits != NULL + && (empty || !OSSL_PARAM_set_int(p.secbits, RSA_security_bits(rsa)))) return 0; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_MAX_SIZE)) != NULL - && (empty || !OSSL_PARAM_set_int(p, RSA_size(rsa)))) + if (p.maxsize != NULL + && (empty || !OSSL_PARAM_set_int(p.maxsize, RSA_size(rsa)))) return 0; - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_SECURITY_CATEGORY)) != NULL) - if (!OSSL_PARAM_set_int(p, 0)) + if (p.seccat != NULL) + if (!OSSL_PARAM_set_int(p.seccat, 0)) return 0; /* * For restricted RSA-PSS keys, we ignore the default digest request. * With RSA-OAEP keys, this may need to be amended. */ - if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_DEFAULT_DIGEST)) != NULL + if (p.default_digest != NULL && (rsa_type != RSA_FLAG_TYPE_RSASSAPSS || ossl_rsa_pss_params_30_is_unrestricted(pss_params))) { - if (!OSSL_PARAM_set_utf8_string(p, RSA_DEFAULT_MD)) + if (!OSSL_PARAM_set_utf8_string(p.default_digest, RSA_DEFAULT_MD)) return 0; } @@ -414,34 +438,38 @@ static int rsa_get_params(void *key, OSSL_PARAM params[]) * For non-RSA-PSS keys, we ignore the mandatory digest request. * With RSA-OAEP keys, this may need to be amended. */ - if ((p = OSSL_PARAM_locate(params, - OSSL_PKEY_PARAM_MANDATORY_DIGEST)) - != NULL + if (p.mandatory_digest != NULL && rsa_type == RSA_FLAG_TYPE_RSASSAPSS && !ossl_rsa_pss_params_30_is_unrestricted(pss_params)) { const char *mdname = ossl_rsa_oaeppss_nid2name(ossl_rsa_pss_params_30_hashalg(pss_params)); - if (mdname == NULL || !OSSL_PARAM_set_utf8_string(p, mdname)) + if (mdname == NULL + || !OSSL_PARAM_set_utf8_string(p.mandatory_digest, mdname)) return 0; } return (rsa_type != RSA_FLAG_TYPE_RSASSAPSS - || ossl_rsa_pss_params_30_todata(pss_params, NULL, params)) - && ossl_rsa_todata(rsa, NULL, params, 1); -} - -static const OSSL_PARAM rsa_params[] = { - OSSL_PARAM_int(OSSL_PKEY_PARAM_BITS, NULL), - OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL), - OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL), - OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_CATEGORY, NULL), - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_DEFAULT_DIGEST, NULL, 0), - RSA_KEY_TYPES() - OSSL_PARAM_END -}; + || ossl_rsa_pss_params_30_todata_parsed(pss_params, NULL, &p)) + && ossl_rsa_todata_parsed(rsa, NULL, &p, 1); +} + +static int rsa_get_params(void *key, OSSL_PARAM params[]) +{ + return common_get_params(key, params, rsa_get_params_decoder); +} + +static int rsapss_get_params(void *key, OSSL_PARAM params[]) +{ + return common_get_params(key, params, rsapss_get_params_decoder); +} static const OSSL_PARAM *rsa_gettable_params(void *provctx) { - return rsa_params; + return rsa_get_params_list; +} + +static const OSSL_PARAM *rsapss_gettable_params(void *provctx) +{ + return rsapss_get_params_list; } static int rsa_validate(const void *keydata, int selection, int checktype) @@ -559,27 +587,37 @@ static void *rsapss_gen_init(void *provctx, int selection, static int rsa_gen_set_params(void *genctx, const OSSL_PARAM params[]) { struct rsa_gen_ctx *gctx = genctx; - const OSSL_PARAM *p; + RSA_PARAMS p; - if (ossl_param_is_empty(params)) - return 1; + if (gctx == NULL) + return 0; + switch (gctx->rsa_type) { + case RSA_FLAG_TYPE_RSA: + if (!rsa_gen_set_params_decoder(params, &p)) + return 0; + break; + case RSA_FLAG_TYPE_RSASSAPSS: + if (!rsapss_gen_set_params_decoder(params, &p)) + return 0; + break; + default: + return 0; + } - if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_BITS)) != NULL) { - if (!OSSL_PARAM_get_size_t(p, &gctx->nbits)) + if (p.bits != NULL) { + if (!OSSL_PARAM_get_size_t(p.bits, &gctx->nbits)) return 0; if (gctx->nbits < RSA_MIN_MODULUS_BITS) { ERR_raise(ERR_LIB_PROV, PROV_R_KEY_SIZE_TOO_SMALL); return 0; } } - if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_PRIMES)) != NULL - && !OSSL_PARAM_get_size_t(p, &gctx->primes)) + if (p.primes != NULL && !OSSL_PARAM_get_size_t(p.primes, &gctx->primes)) return 0; - if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_E)) != NULL - && !OSSL_PARAM_get_BN(p, &gctx->pub_exp)) + if (p.e != NULL && !OSSL_PARAM_get_BN(p.e, &gctx->pub_exp)) return 0; - if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_A)) != NULL) { - if (!OSSL_PARAM_get_uint32(p, &gctx->a)) + if (p.a != NULL) { + if (!OSSL_PARAM_get_uint32(p.a, &gctx->a)) return 0; /* a is an optional value that should be one of (0, 1, 3, 5, 7) */ if (gctx->a != 0 && (gctx->a > 7 || (gctx->a & 1) == 0)) { @@ -587,8 +625,8 @@ static int rsa_gen_set_params(void *genctx, const OSSL_PARAM params[]) return 0; } } - if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_B)) != NULL) { - if (!OSSL_PARAM_get_uint32(p, &gctx->b)) + if (p.b != NULL) { + if (!OSSL_PARAM_get_uint32(p.b, &gctx->b)) return 0; /* b is an optional value that should be one of (0, 1, 3, 5, 7) */ if (gctx->b != 0 && (gctx->b > 7 || (gctx->b & 1) == 0)) { @@ -599,55 +637,27 @@ static int rsa_gen_set_params(void *genctx, const OSSL_PARAM params[]) /* Only attempt to get PSS parameters when generating an RSA-PSS key */ if (gctx->rsa_type == RSA_FLAG_TYPE_RSASSAPSS - && !pss_params_fromdata(&gctx->pss_params, &gctx->pss_defaults_set, params, + && !pss_params_fromdata(&gctx->pss_params, &gctx->pss_defaults_set, &p, gctx->rsa_type, gctx->libctx)) return 0; #if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS) /* Any ACVP test related parameters are copied into a params[] */ - if (!ossl_rsa_acvp_test_gen_params_new(&gctx->acvp_test_params, params)) + if (!ossl_rsa_acvp_test_gen_params_new_parsed(&gctx->acvp_test_params, &p)) return 0; #endif return 1; } -#define rsa_gen_basic \ - OSSL_PARAM_size_t(OSSL_PKEY_PARAM_RSA_BITS, NULL), \ - OSSL_PARAM_size_t(OSSL_PKEY_PARAM_RSA_PRIMES, NULL), \ - OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_E, NULL, 0), \ - OSSL_PARAM_uint32(OSSL_PKEY_PARAM_RSA_A, NULL), \ - OSSL_PARAM_uint32(OSSL_PKEY_PARAM_RSA_B, NULL) -/* - * The following must be kept in sync with ossl_rsa_pss_params_30_fromdata() - * in crypto/rsa/rsa_backend.c - */ -#define rsa_gen_pss \ - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_RSA_DIGEST, NULL, 0), \ - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_RSA_DIGEST_PROPS, NULL, 0), \ - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_RSA_MASKGENFUNC, NULL, 0), \ - OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_RSA_MGF1_DIGEST, NULL, 0), \ - OSSL_PARAM_int(OSSL_PKEY_PARAM_RSA_PSS_SALTLEN, NULL) - static const OSSL_PARAM *rsa_gen_settable_params(ossl_unused void *genctx, ossl_unused void *provctx) { - static const OSSL_PARAM settable[] = { - rsa_gen_basic, - OSSL_PARAM_END - }; - - return settable; + return rsa_gen_set_params_list; } static const OSSL_PARAM *rsapss_gen_settable_params(ossl_unused void *genctx, ossl_unused void *provctx) { - static const OSSL_PARAM settable[] = { - rsa_gen_basic, - rsa_gen_pss, - OSSL_PARAM_END - }; - - return settable; + return rsapss_gen_set_params_list; } static void *rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg) @@ -807,15 +817,16 @@ const OSSL_DISPATCH ossl_rsapss_keymgmt_functions[] = { { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (void (*)(void))rsa_gen_cleanup }, { OSSL_FUNC_KEYMGMT_LOAD, (void (*)(void))rsapss_load }, { OSSL_FUNC_KEYMGMT_FREE, (void (*)(void))rsa_freedata }, - { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))rsa_get_params }, - { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, (void (*)(void))rsa_gettable_params }, + { OSSL_FUNC_KEYMGMT_GET_PARAMS, (void (*)(void))rsapss_get_params }, + { OSSL_FUNC_KEYMGMT_GETTABLE_PARAMS, + (void (*)(void))rsapss_gettable_params }, { OSSL_FUNC_KEYMGMT_HAS, (void (*)(void))rsa_has }, { OSSL_FUNC_KEYMGMT_MATCH, (void (*)(void))rsa_match }, { OSSL_FUNC_KEYMGMT_VALIDATE, (void (*)(void))rsa_validate }, { OSSL_FUNC_KEYMGMT_IMPORT, (void (*)(void))rsa_import }, - { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))rsa_import_types }, + { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (void (*)(void))rsapss_import_types }, { OSSL_FUNC_KEYMGMT_EXPORT, (void (*)(void))rsa_export }, - { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))rsa_export_types }, + { OSSL_FUNC_KEYMGMT_EXPORT_TYPES, (void (*)(void))rsapss_export_types }, { OSSL_FUNC_KEYMGMT_QUERY_OPERATION_NAME, (void (*)(void))rsa_query_operation_name }, { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))rsa_dup }, diff --git a/providers/implementations/keymgmt/slh_dsa_kmgmt.c b/providers/implementations/keymgmt/slh_dsa_kmgmt.c index 766953d265b85..0e90796912f4d 100644 --- a/providers/implementations/keymgmt/slh_dsa_kmgmt.c +++ b/providers/implementations/keymgmt/slh_dsa_kmgmt.c @@ -303,7 +303,7 @@ static int slh_dsa_fips140_pairwise_test(const SLH_DSA_KEY *key, uint8_t msg[16] = { 0 }; size_t msg_len = sizeof(msg); uint8_t *sig = NULL; - size_t sig_len; + size_t sig_len = 0; OSSL_LIB_CTX *lib_ctx; int alloc_ctx = 0; @@ -347,7 +347,7 @@ static int slh_dsa_fips140_pairwise_test(const SLH_DSA_KEY *key, err: if (alloc_ctx) ossl_slh_dsa_hash_ctx_free(ctx); - OPENSSL_free(sig); + OPENSSL_clear_free(sig, sig_len); OSSL_SELF_TEST_onend(st, ret); OSSL_SELF_TEST_free(st); return ret; @@ -425,7 +425,7 @@ static void slh_dsa_gen_cleanup(void *genctx) if (gctx == NULL) return; - OPENSSL_cleanse(gctx->entropy, gctx->entropy_len); + OPENSSL_cleanse(gctx->entropy, sizeof(gctx->entropy)); OPENSSL_free(gctx->propq); OPENSSL_free(gctx); } diff --git a/providers/implementations/macs/cmac_prov.c b/providers/implementations/macs/cmac_prov.c index 7e9a3a9c21460..a4a0674d56eef 100644 --- a/providers/implementations/macs/cmac_prov.c +++ b/providers/implementations/macs/cmac_prov.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/macs/hmac_prov.c b/providers/implementations/macs/hmac_prov.c index 201d311bfe8ba..dfb378b68bdd4 100644 --- a/providers/implementations/macs/hmac_prov.c +++ b/providers/implementations/macs/hmac_prov.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/macs/poly1305_prov.c b/providers/implementations/macs/poly1305_prov.c index a9ca6e4f68803..325fb0bdfb714 100644 --- a/providers/implementations/macs/poly1305_prov.c +++ b/providers/implementations/macs/poly1305_prov.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/rands/drbg.c b/providers/implementations/rands/drbg.c index 50027b9b0b9bc..000b4a2f699e1 100644 --- a/providers/implementations/rands/drbg.c +++ b/providers/implementations/rands/drbg.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/rands/drbg_ctr.c b/providers/implementations/rands/drbg_ctr.c index f99f8f198f973..77a0a6a8aa1b2 100644 --- a/providers/implementations/rands/drbg_ctr.c +++ b/providers/implementations/rands/drbg_ctr.c @@ -599,6 +599,18 @@ static int drbg_ctr_init(PROV_DRBG *drbg) drbg->strength = (unsigned int)(keylen * 8); drbg->seedlen = keylen + 16; +#ifdef FIPS_MODULE + /* + * FIPS requires that we use a derivation function since our + * entropy source is outside the fips boundary + */ + if (ctr->use_df == 0) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_DERIVATION_FUNCTION_INIT_FAILED, + "FIPS requires the use of a derivation function"); + goto err; + } +#endif + if (ctr->use_df) { /* df initialisation */ static const unsigned char df_key[32] = { @@ -726,7 +738,6 @@ static int drbg_ctr_set_ctx_params_locked(PROV_DRBG *ctx, { PROV_DRBG_CTR *ctr = (PROV_DRBG_CTR *)ctx->data; OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); - OSSL_PROVIDER *prov = NULL; char *ecb; const char *propquery = NULL; int i, cipher_init = 0; @@ -737,20 +748,12 @@ static int drbg_ctr_set_ctx_params_locked(PROV_DRBG *ctx, cipher_init = 1; } - if (p->propq != NULL) { - if (p->propq->data_type != OSSL_PARAM_UTF8_STRING) - return 0; +#ifndef FIPS_MODULE + propquery = "provider=default"; + if (p->propq != NULL + && p->propq->data_type == OSSL_PARAM_UTF8_STRING) propquery = (const char *)p->propq->data; - } - - if (p->prov != NULL) { - if (p->prov->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - if ((prov = ossl_provider_find(libctx, - (const char *)p->prov->data, 1)) - == NULL) - return 0; - } +#endif if (p->cipher != NULL) { const char *base = (const char *)p->cipher->data; @@ -759,50 +762,33 @@ static int drbg_ctr_set_ctx_params_locked(PROV_DRBG *ctx, if (p->cipher->data_type != OSSL_PARAM_UTF8_STRING || p->cipher->data_size < ctr_str_len) { - ossl_provider_free(prov); return 0; } if (OPENSSL_strcasecmp("CTR", base + p->cipher->data_size - ctr_str_len) != 0) { ERR_raise(ERR_LIB_PROV, PROV_R_REQUIRE_CTR_MODE_CIPHER); - ossl_provider_free(prov); return 0; } if ((ecb = OPENSSL_strndup(base, p->cipher->data_size)) == NULL) { - ossl_provider_free(prov); return 0; } strcpy(ecb + p->cipher->data_size - ecb_str_len, "ECB"); EVP_CIPHER_free(ctr->cipher_ecb); EVP_CIPHER_free(ctr->cipher_ctr); + ctr->cipher_ctr = NULL; + ctr->cipher_ecb = NULL; /* * Try to fetch algorithms from our own provider code, fallback * to generic fetch only if that fails */ - (void)ERR_set_mark(); - ctr->cipher_ctr = evp_cipher_fetch_from_prov(prov, base, NULL); - if (ctr->cipher_ctr == NULL) { - (void)ERR_pop_to_mark(); - ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery); - } else { - (void)ERR_clear_last_mark(); - } - (void)ERR_set_mark(); - ctr->cipher_ecb = evp_cipher_fetch_from_prov(prov, ecb, NULL); - if (ctr->cipher_ecb == NULL) { - (void)ERR_pop_to_mark(); - ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery); - } else { - (void)ERR_clear_last_mark(); - } + ctr->cipher_ctr = EVP_CIPHER_fetch(libctx, base, propquery); + ctr->cipher_ecb = EVP_CIPHER_fetch(libctx, ecb, propquery); OPENSSL_free(ecb); if (ctr->cipher_ctr == NULL || ctr->cipher_ecb == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_FIND_CIPHERS); - ossl_provider_free(prov); return 0; } cipher_init = 1; } - ossl_provider_free(prov); if (cipher_init && !drbg_ctr_init(ctx)) return 0; diff --git a/providers/implementations/rands/drbg_ctr.inc.in b/providers/implementations/rands/drbg_ctr.inc.in index 74396fb019bd9..b3191fa1d78f6 100644 --- a/providers/implementations/rands/drbg_ctr.inc.in +++ b/providers/implementations/rands/drbg_ctr.inc.in @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the \"License\"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -33,7 +33,7 @@ use OpenSSL::paramnames qw(produce_param_decoder); {- produce_param_decoder('drbg_ctr_set_ctx_params', (['OSSL_DRBG_PARAM_PROPERTIES', 'propq', 'utf8_string'], ['OSSL_DRBG_PARAM_CIPHER', 'cipher', 'utf8_string'], - ['OSSL_DRBG_PARAM_USE_DF', 'df', 'int'], + ['OSSL_DRBG_PARAM_USE_DF', 'df', 'int', '!fips'], ['OSSL_PROV_PARAM_CORE_PROV_NAME', 'prov', 'utf8_string'], ['OSSL_DRBG_PARAM_RESEED_REQUESTS', 'reseed_req', 'uint'], ['OSSL_DRBG_PARAM_RESEED_TIME_INTERVAL', 'reseed_time', 'uint64'], diff --git a/providers/implementations/rands/drbg_hash.c b/providers/implementations/rands/drbg_hash.c index d024336d58c85..4188c2938194b 100644 --- a/providers/implementations/rands/drbg_hash.c +++ b/providers/implementations/rands/drbg_hash.c @@ -525,18 +525,21 @@ static const OSSL_PARAM *drbg_hash_gettable_ctx_params(ossl_unused void *vctx, static int drbg_fetch_digest_from_prov(const struct drbg_set_ctx_params_st *p, OSSL_LIB_CTX *libctx, - EVP_MD **digest) + EVP_MD **digest, + const char *propq) { - OSSL_PROVIDER *prov = NULL; EVP_MD *md = NULL; int ret = 0; + const char *propquery = NULL; - if (digest == NULL) - return 0; +#ifndef FIPS_MODULE + if (propq == NULL) + propquery = "provider=default"; + else + propquery = propq; +#endif - if (p->prov == NULL || p->prov->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - if ((prov = ossl_provider_find(libctx, (const char *)p->prov->data, 1)) == NULL) + if (digest == NULL) return 0; if (p->digest == NULL) { @@ -547,15 +550,13 @@ static int drbg_fetch_digest_from_prov(const struct drbg_set_ctx_params_st *p, if (p->digest->data_type != OSSL_PARAM_UTF8_STRING) goto done; - md = evp_digest_fetch_from_prov(prov, (const char *)p->digest->data, NULL); + md = EVP_MD_fetch(libctx, p->digest->data, propquery); if (md) { EVP_MD_free(*digest); *digest = md; ret = 1; } - done: - ossl_provider_free(prov); return ret; } @@ -572,7 +573,8 @@ static int drbg_hash_set_ctx_params_locked(PROV_DRBG *ctx, const struct drbg_set /* try to fetch digest from provider */ (void)ERR_set_mark(); - if (!drbg_fetch_digest_from_prov(p, libctx, &prov_md)) { + if (!drbg_fetch_digest_from_prov(p, libctx, &prov_md, + (p->propq != NULL && p->propq->data_type == OSSL_PARAM_UTF8_STRING) ? p->propq->data : NULL)) { (void)ERR_pop_to_mark(); /* fall back to full implementation search */ if (!ossl_prov_digest_load(&hash->digest, p->digest, p->propq, libctx)) diff --git a/providers/implementations/rands/drbg_hmac.c b/providers/implementations/rands/drbg_hmac.c index 371767acb2464..c576eecdef4f1 100644 --- a/providers/implementations/rands/drbg_hmac.c +++ b/providers/implementations/rands/drbg_hmac.c @@ -418,25 +418,26 @@ static const OSSL_PARAM *drbg_hmac_gettable_ctx_params(ossl_unused void *vctx, static int drbg_fetch_algs_from_prov(const struct drbg_set_ctx_params_st *p, OSSL_LIB_CTX *libctx, EVP_MAC_CTX **macctx, - EVP_MD **digest) + EVP_MD **digest, const char *propq) { - OSSL_PROVIDER *prov = NULL; EVP_MD *md = NULL; int ret = 0; + const char *propquery = NULL; - if (macctx == NULL || digest == NULL) - return 0; +#ifndef FIPS_MODULE + if (propq == NULL) + propquery = "provider=default"; + else + propquery = propq; +#endif - if (p->prov == NULL || p->prov->data_type != OSSL_PARAM_UTF8_STRING) - return 0; - if ((prov = ossl_provider_find(libctx, (const char *)p->prov->data, 1)) == NULL) + if (macctx == NULL || digest == NULL) return 0; if (p->digest != NULL) { if (p->digest->data_type != OSSL_PARAM_UTF8_STRING) goto done; - - md = evp_digest_fetch_from_prov(prov, (const char *)p->digest->data, NULL); + md = EVP_MD_fetch(libctx, p->digest->data, propquery); if (md) { EVP_MD_free(*digest); *digest = md; @@ -451,7 +452,6 @@ static int drbg_fetch_algs_from_prov(const struct drbg_set_ctx_params_st *p, ret = 1; done: - ossl_provider_free(prov); return ret; } @@ -468,7 +468,8 @@ static int drbg_hmac_set_ctx_params_locked(PROV_DRBG *ctx, const struct drbg_set /* try to fetch mac and digest from provider */ (void)ERR_set_mark(); - if (!drbg_fetch_algs_from_prov(p, libctx, &hmac->ctx, &prov_md)) { + if (!drbg_fetch_algs_from_prov(p, libctx, &hmac->ctx, &prov_md, + (p->propq != NULL && p->propq->data_type == OSSL_PARAM_UTF8_STRING) ? p->propq->data : NULL)) { (void)ERR_pop_to_mark(); if (p->digest != NULL) { /* fall back to full implementation search */ diff --git a/providers/implementations/rands/seeding/rand_cpu_arm64.c b/providers/implementations/rands/seeding/rand_cpu_arm64.c index 083b4826ae4f9..a3c2bf8ffa944 100644 --- a/providers/implementations/rands/seeding/rand_cpu_arm64.c +++ b/providers/implementations/rands/seeding/rand_cpu_arm64.c @@ -1,5 +1,5 @@ /* - * Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/rands/seeding/rand_unix.c b/providers/implementations/rands/seeding/rand_unix.c index 67b38cb719910..95c4ff8a93f0d 100644 --- a/providers/implementations/rands/seeding/rand_unix.c +++ b/providers/implementations/rands/seeding/rand_unix.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -451,9 +451,19 @@ static int wait_random_seeded(void) * this alternative but essentially identical source moot. */ if (uname(&un) == 0) { - kernel[0] = atoi(un.release); + int val; + char *end; + + kernel[0] = (ossl_strtoint(un.release, &end, 10, &val) + && (*end == '.' || *end == '\0')) + ? val + : 0; p = strchr(un.release, '.'); - kernel[1] = p == NULL ? 0 : atoi(p + 1); + kernel[1] = (p != NULL + && ossl_strtoint(p + 1, &end, 10, &val) + && (*end == '.' || *end == '\0')) + ? val + : 0; if (kernel[0] > kernel_version[0] || (kernel[0] == kernel_version[0] && kernel[1] >= kernel_version[1])) { diff --git a/providers/implementations/rands/seeding/rand_win.c b/providers/implementations/rands/seeding/rand_win.c index e1350f7d806fb..663246c56c979 100644 --- a/providers/implementations/rands/seeding/rand_win.c +++ b/providers/implementations/rands/seeding/rand_win.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/rands/test_rng.c b/providers/implementations/rands/test_rng.c index c073b3e5bff85..7c03238b67d69 100644 --- a/providers/implementations/rands/test_rng.c +++ b/providers/implementations/rands/test_rng.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/providers/implementations/signature/build.info b/providers/implementations/signature/build.info index 579045f2c58a2..180b49806bfe7 100644 --- a/providers/implementations/signature/build.info +++ b/providers/implementations/signature/build.info @@ -9,6 +9,7 @@ $SM2_GOAL=../../libdefault.a $LMS_GOAL=../../libdefault.a ../../libfips.a $ML_DSA_GOAL=../../libdefault.a ../../libfips.a $SLH_DSA_GOAL=../../libdefault.a ../../libfips.a +$COMPOSITE_GOAL=../../libdefault.a IF[{- !$disabled{dsa} -}] SOURCE[$DSA_GOAL]=dsa_sig.c @@ -48,3 +49,8 @@ ENDIF IF[{- !$disabled{'slh-dsa'} -}] SOURCE[$DSA_GOAL]=slh_dsa_sig.c ENDIF + +IF[{- !$disabled{'ml-dsa'} -}] + SOURCE[$COMPOSITE_GOAL]=composite_sig.c + DEPEND[composite_sig.o]=../../common/include/prov/composite.h +ENDIF \ No newline at end of file diff --git a/providers/implementations/signature/composite_sig.c b/providers/implementations/signature/composite_sig.c new file mode 100644 index 0000000000000..12477439c8d65 --- /dev/null +++ b/providers/implementations/signature/composite_sig.c @@ -0,0 +1,1017 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/deprecated.h" + +#include +#include +#include +#include +#include "crypto/evp.h" +#include "crypto/ml_dsa.h" +#include "internal/der.h" +#include "internal/packet.h" +#include "prov/implementations.h" +#include "prov/provider_ctx.h" +#include "prov/providercommon.h" +#include "prov/composite.h" +#include "prov/names.h" + +#define composite_set_ctx_params_st composite_verifymsg_set_ctx_params_st +#define composite_set_ctx_params_decoder composite_verifymsg_set_ctx_params_decoder +#include "providers/implementations/signature/composite_sig.inc" +#include +#include +#include + +/* + * Fixed 32-byte domain separation prefix per draft-ietf-lamps-pq-composite-sigs. + * Byte encoding of the ASCII string "CompositeAlgorithmSignatures2025": + * 436F6D706F73697465416C676F726974686D5369676E61747572657332303235 + */ +static const uint8_t composite_sig_prefix[32] = { + 0x43, 0x6F, 0x6D, 0x70, 0x6F, 0x73, 0x69, 0x74, /* Composit */ // codespell:ignore + 0x65, 0x41, 0x6C, 0x67, 0x6F, 0x72, 0x69, 0x74, /* eAlgorit */ + 0x68, 0x6D, 0x53, 0x69, 0x67, 0x6E, 0x61, 0x74, /* hmSignat */ + 0x75, 0x72, 0x65, 0x73, 0x32, 0x30, 0x32, 0x35 /* ures2025 */ +}; + +static OSSL_FUNC_signature_sign_fn composite_sign; + +static void *composite_newctx(void *provctx, int evp_type, const char *propq) +{ + PROV_COMPOSITE_CTX *ctx; + + if (!ossl_prov_is_running()) + return NULL; + + ctx = OPENSSL_zalloc(sizeof(PROV_COMPOSITE_CTX)); + if (ctx == NULL) + return NULL; + + ctx->libctx = PROV_LIBCTX_OF(provctx); + return ctx; +} + +typedef enum { + COMPOSITE_CLASSIC_RSA_PSS, + COMPOSITE_CLASSIC_RSA_PKCS15, + COMPOSITE_CLASSIC_ECDSA, + COMPOSITE_CLASSIC_ED25519, + COMPOSITE_CLASSIC_ED448 +} COMPOSITE_CLASSIC_TYPE; + +typedef struct { + const char *name; + const char *label; /* ASCII label for M' and ML-DSA ctx per draft §6 */ + const unsigned char *oid; + size_t oid_sz; + const char *prehash_alg; /* hash for composite PH(M) only */ + size_t prehash_len; /* prehash output length in bytes */ + const char *classic_hash; /* hash for traditional component signing (may differ + * from prehash_alg per draft-ietf-lamps-pq-composite-sigs §6); + * NULL for EdDSA (no digest arg needed) */ + COMPOSITE_CLASSIC_TYPE classic_type; + int pss_salt_len; /* RSA-PSS only; 0 otherwise */ + const char *mgf1_hash; /* RSA-PSS MGF1 hash; NULL = same as classic_hash */ +} COMPOSITE_ALG_INFO; + +/* + * prehash_alg: hash used for the composite PH(M) step. + * classic_hash: hash used by the traditional component signature algorithm, + * which may differ from prehash_alg per draft-ietf-lamps-pq-composite-sigs §6; + * NULL for EdDSA variants (no digest argument). + * mgf1_hash: RSA-PSS MGF1 hash override; NULL = same as classic_hash. + */ +static const COMPOSITE_ALG_INFO composite_alg_table[] = { + /* name, label, oid, oid_sz, prehash, phlen, classic_hash, + classic_type, pss_salt_len, mgf1_hash */ + { "ML-DSA-44-RSA2048-PSS-SHA256", + "COMPSIG-MLDSA44-RSA2048-PSS-SHA256", + ossl_der_oid_id_mldsa44_rsa2048_pss_sha256, + DER_OID_SZ_id_mldsa44_rsa2048_pss_sha256, + "SHA-256", 32, "SHA-256", COMPOSITE_CLASSIC_RSA_PSS, 32, NULL }, + { "ML-DSA-44-RSA2048-PKCS15-SHA256", + "COMPSIG-MLDSA44-RSA2048-PKCS15-SHA256", + ossl_der_oid_id_mldsa44_rsa2048_pkcs15_sha256, + DER_OID_SZ_id_mldsa44_rsa2048_pkcs15_sha256, + "SHA-256", 32, "SHA-256", COMPOSITE_CLASSIC_RSA_PKCS15, 0, NULL }, + { "ML-DSA-44-Ed25519-SHA512", + "COMPSIG-MLDSA44-Ed25519-SHA512", + ossl_der_oid_id_mldsa44_ed25519_sha512, + DER_OID_SZ_id_mldsa44_ed25519_sha512, + "SHA-512", 64, NULL, COMPOSITE_CLASSIC_ED25519, 0, NULL }, + { "ML-DSA-44-ECDSA-P256-SHA256", + "COMPSIG-MLDSA44-ECDSA-P256-SHA256", + ossl_der_oid_id_mldsa44_ecdsa_p256_sha256, + DER_OID_SZ_id_mldsa44_ecdsa_p256_sha256, + "SHA-256", 32, "SHA-256", COMPOSITE_CLASSIC_ECDSA, 0, NULL }, + { "ML-DSA-65-RSA3072-PSS-SHA512", + "COMPSIG-MLDSA65-RSA3072-PSS-SHA512", + ossl_der_oid_id_mldsa65_rsa3072_pss_sha512, + DER_OID_SZ_id_mldsa65_rsa3072_pss_sha512, + "SHA-512", 64, "SHA-256", COMPOSITE_CLASSIC_RSA_PSS, 32, NULL }, + { "ML-DSA-65-RSA3072-PKCS15-SHA512", /* sha256WithRSAEncryption */ + "COMPSIG-MLDSA65-RSA3072-PKCS15-SHA512", + ossl_der_oid_id_mldsa65_rsa3072_pkcs15_sha512, + DER_OID_SZ_id_mldsa65_rsa3072_pkcs15_sha512, + "SHA-512", 64, "SHA-256", COMPOSITE_CLASSIC_RSA_PKCS15, 0, NULL }, + { "ML-DSA-65-RSA4096-PSS-SHA512", + "COMPSIG-MLDSA65-RSA4096-PSS-SHA512", + ossl_der_oid_id_mldsa65_rsa4096_pss_sha512, + DER_OID_SZ_id_mldsa65_rsa4096_pss_sha512, + "SHA-512", 64, "SHA-384", COMPOSITE_CLASSIC_RSA_PSS, 48, NULL }, + { "ML-DSA-65-RSA4096-PKCS15-SHA512", /* sha384WithRSAEncryption */ + "COMPSIG-MLDSA65-RSA4096-PKCS15-SHA512", + ossl_der_oid_id_mldsa65_rsa4096_pkcs15_sha512, + DER_OID_SZ_id_mldsa65_rsa4096_pkcs15_sha512, + "SHA-512", 64, "SHA-384", COMPOSITE_CLASSIC_RSA_PKCS15, 0, NULL }, + { "ML-DSA-65-ECDSA-P256-SHA512", /* ecdsa-with-SHA256 */ + "COMPSIG-MLDSA65-ECDSA-P256-SHA512", + ossl_der_oid_id_mldsa65_ecdsa_p256_sha512, + DER_OID_SZ_id_mldsa65_ecdsa_p256_sha512, + "SHA-512", 64, "SHA-256", COMPOSITE_CLASSIC_ECDSA, 0, NULL }, + { "ML-DSA-65-ECDSA-P384-SHA512", /* ecdsa-with-SHA384 */ + "COMPSIG-MLDSA65-ECDSA-P384-SHA512", + ossl_der_oid_id_mldsa65_ecdsa_p384_sha512, + DER_OID_SZ_id_mldsa65_ecdsa_p384_sha512, + "SHA-512", 64, "SHA-384", COMPOSITE_CLASSIC_ECDSA, 0, NULL }, + { "ML-DSA-65-ECDSA-brainpoolP256r1-SHA512", /* ecdsa-with-SHA256 */ + "COMPSIG-MLDSA65-ECDSA-BP256-SHA512", + ossl_der_oid_id_mldsa65_ecdsa_brainpoolP256r1_sha512, + DER_OID_SZ_id_mldsa65_ecdsa_brainpoolP256r1_sha512, + "SHA-512", 64, "SHA-256", COMPOSITE_CLASSIC_ECDSA, 0, NULL }, + { "ML-DSA-65-Ed25519-SHA512", + "COMPSIG-MLDSA65-Ed25519-SHA512", + ossl_der_oid_id_mldsa65_ed25519_sha512, + DER_OID_SZ_id_mldsa65_ed25519_sha512, + "SHA-512", 64, NULL, COMPOSITE_CLASSIC_ED25519, 0, NULL }, + { "ML-DSA-87-ECDSA-P384-SHA512", /* ecdsa-with-SHA384 */ + "COMPSIG-MLDSA87-ECDSA-P384-SHA512", + ossl_der_oid_id_mldsa87_ecdsa_p384_sha512, + DER_OID_SZ_id_mldsa87_ecdsa_p384_sha512, + "SHA-512", 64, "SHA-384", COMPOSITE_CLASSIC_ECDSA, 0, NULL }, + { "ML-DSA-87-ECDSA-brainpoolP384r1-SHA512", /* ecdsa-with-SHA384 */ + "COMPSIG-MLDSA87-ECDSA-BP384-SHA512", + ossl_der_oid_id_mldsa87_ecdsa_brainpoolp384r1_sha512, + DER_OID_SZ_id_mldsa87_ecdsa_brainpoolp384r1_sha512, + "SHA-512", 64, "SHA-384", COMPOSITE_CLASSIC_ECDSA, 0, NULL }, + { "ML-DSA-87-Ed448-SHAKE256", + "COMPSIG-MLDSA87-Ed448-SHAKE256", + ossl_der_oid_id_mldsa87_ed448_shake256, + DER_OID_SZ_id_mldsa87_ed448_shake256, + "SHAKE256", 64, NULL, COMPOSITE_CLASSIC_ED448, 0, NULL }, + { "ML-DSA-87-RSA3072-PSS-SHA512", + "COMPSIG-MLDSA87-RSA3072-PSS-SHA512", + ossl_der_oid_id_mldsa87_rsa3072_pss_sha512, + DER_OID_SZ_id_mldsa87_rsa3072_pss_sha512, + "SHA-512", 64, "SHA-256", COMPOSITE_CLASSIC_RSA_PSS, 32, NULL }, + { "ML-DSA-87-RSA4096-PSS-SHA512", + "COMPSIG-MLDSA87-RSA4096-PSS-SHA512", + ossl_der_oid_id_mldsa87_rsa4096_pss_sha512, + DER_OID_SZ_id_mldsa87_rsa4096_pss_sha512, + "SHA-512", 64, "SHA-384", COMPOSITE_CLASSIC_RSA_PSS, 48, NULL }, + { "ML-DSA-87-ECDSA-P521-SHA512", /* ecdsa-with-SHA512 */ + "COMPSIG-MLDSA87-ECDSA-P521-SHA512", + ossl_der_oid_id_mldsa87_ecdsa_p521_sha512, + DER_OID_SZ_id_mldsa87_ecdsa_p521_sha512, + "SHA-512", 64, "SHA-512", COMPOSITE_CLASSIC_ECDSA, 0, NULL }, +}; +#define COMPOSITE_NUM_ALGS \ + (sizeof(composite_alg_table) / sizeof(composite_alg_table[0])) + +static const COMPOSITE_ALG_INFO *composite_find_alg_info(const char *name) +{ + size_t i; + + if (name == NULL) + return NULL; + for (i = 0; i < COMPOSITE_NUM_ALGS; i++) { + if (OPENSSL_strcasecmp(name, composite_alg_table[i].name) == 0) + return &composite_alg_table[i]; + } + return NULL; +} + +/* + * Compute PH(M) for M' construction. Handles both regular digests and the + * SHAKE256 XOF used by ML-DSA-87-Ed448-SHAKE256. + */ +static int composite_compute_prehash(OSSL_LIB_CTX *libctx, + const COMPOSITE_ALG_INFO *info, + const uint8_t *msg, size_t msg_len, + uint8_t *out) +{ + if (OPENSSL_strcasecmp(info->prehash_alg, "SHAKE256") == 0) { + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); + EVP_MD *md = EVP_MD_fetch(libctx, "SHAKE256", NULL); + int ok = (mctx != NULL && md != NULL + && EVP_DigestInit_ex(mctx, md, NULL) + && EVP_DigestUpdate(mctx, msg, msg_len) + && EVP_DigestFinalXOF(mctx, out, info->prehash_len)); + EVP_MD_CTX_free(mctx); + EVP_MD_free(md); + return ok; + } + return EVP_Q_digest(libctx, info->prehash_alg, NULL, msg, msg_len, out, NULL); +} + +/* + * Build M' = Prefix(32) || Label || uint8(ctx_len) || ctx || PH(M) into a + * newly allocated buffer, per draft-ietf-lamps-pq-composite-sigs §2.2. + * Caller must OPENSSL_free() (or OPENSSL_clear_free()) the result. + */ +static uint8_t *composite_build_mprime(PROV_COMPOSITE_CTX *ctx, + const COMPOSITE_ALG_INFO *info, + const uint8_t *ph, size_t ph_len, + size_t *tbs_len) +{ + uint8_t *tbs; + size_t offset; + + if (ph_len != info->prehash_len) + return NULL; + + *tbs_len = 32 + strlen(info->label) + 1 + ctx->context_string_len + info->prehash_len; + tbs = OPENSSL_malloc(*tbs_len); + if (tbs == NULL) + return NULL; + + offset = 0; + memcpy(tbs + offset, composite_sig_prefix, 32); + offset += 32; + memcpy(tbs + offset, info->label, strlen(info->label)); + offset += strlen(info->label); + tbs[offset++] = (uint8_t)ctx->context_string_len; + if (ctx->context_string_len > 0) { + memcpy(tbs + offset, ctx->context_string, ctx->context_string_len); + offset += ctx->context_string_len; + } + memcpy(tbs + offset, ph, info->prehash_len); + return tbs; +} + +/* + * Sign tbs/tbs_len with the traditional (non-ML-DSA) component key. + */ +static int composite_classic_sign(PROV_COMPOSITE_CTX *ctx, + const COMPOSITE_ALG_INFO *info, + const uint8_t *tbs, size_t tbs_len, + uint8_t *sig, size_t *siglen) +{ + EVP_MD_CTX *md_ctx = EVP_MD_CTX_new(); + EVP_PKEY_CTX *pctx = NULL; + int ret = 0; + + if (md_ctx == NULL) + return 0; + + switch (info->classic_type) { + case COMPOSITE_CLASSIC_ED25519: + case COMPOSITE_CLASSIC_ED448: + /* Pure EdDSA: no external digest */ + if (!EVP_DigestSignInit_ex(md_ctx, NULL, NULL, + ctx->libctx, NULL, + ctx->key->classic_key, NULL)) + goto err; + break; + + case COMPOSITE_CLASSIC_ECDSA: + if (!EVP_DigestSignInit_ex(md_ctx, NULL, info->classic_hash, + ctx->libctx, NULL, + ctx->key->classic_key, NULL)) + goto err; + break; + + case COMPOSITE_CLASSIC_RSA_PSS: + if (!EVP_DigestSignInit_ex(md_ctx, &pctx, info->classic_hash, + ctx->libctx, NULL, + ctx->key->classic_key, NULL)) + goto err; + { + const char *mgf1 = (info->mgf1_hash != NULL) + ? info->mgf1_hash + : info->classic_hash; + if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) <= 0 + || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, info->pss_salt_len) <= 0 + || EVP_PKEY_CTX_set_rsa_mgf1_md_name(pctx, mgf1, NULL) <= 0) + goto err; + } + break; + + case COMPOSITE_CLASSIC_RSA_PKCS15: + if (!EVP_DigestSignInit_ex(md_ctx, &pctx, info->classic_hash, + ctx->libctx, NULL, + ctx->key->classic_key, NULL)) + goto err; + if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PADDING) <= 0) + goto err; + break; + + default: + ERR_raise(ERR_LIB_PROV, ERR_R_UNSUPPORTED); + goto err; + } + + if (!EVP_DigestSign(md_ctx, sig, siglen, tbs, tbs_len)) + goto err; + + ret = 1; +err: + EVP_MD_CTX_free(md_ctx); + return ret; +} + +/* + * Shared core of signing: given an already-computed PH(M) — whether from + * hashing the whole message in one shot, from the streaming msg_update()/ + * msg_final() path, or supplied directly by the caller via + * OSSL_SIGNATURE_PARAM_COMPOSITE_PREHASH — build M' and produce the + * composite signature (ML-DSA component || classic component). + */ +static int composite_sign_ph(PROV_COMPOSITE_CTX *ctx, + const COMPOSITE_ALG_INFO *info, + uint8_t *sig, size_t *siglen, size_t sigsize, + const uint8_t *ph, size_t ph_len) +{ + uint8_t *tbs = NULL; + size_t tbs_len = 0; + uint8_t rnd[32]; + size_t ml_dsa_siglen, classic_siglen, ml_dsa_sig_max; + int ret = 0; + + ml_dsa_sig_max = ossl_ml_dsa_key_get_sig_len(ctx->key->ml_dsa_key); + + /* + * Size query: upper bound only (EVP_PKEY_get_size() for EC is the max + * DER size, not exact); real length is set after signing below. + */ + if (sig == NULL) { + *siglen = ml_dsa_sig_max + + (size_t)EVP_PKEY_get_size(ctx->key->classic_key); + return 1; + } + + tbs = composite_build_mprime(ctx, info, ph, ph_len, &tbs_len); + if (tbs == NULL) + goto err; + + /* ML-DSA component: pure ML-DSA on M', with Label as mldsa_ctx per §3.1 */ + if (ctx->test_entropy_len != 0) { + /* Fixed entropy for deterministic test vectors (non-PSS algorithms). */ + memcpy(rnd, ctx->test_entropy, sizeof(rnd)); + } else if (RAND_priv_bytes_ex(ctx->libctx, rnd, sizeof(rnd), 0) <= 0) { + goto err; + } + + ml_dsa_siglen = ml_dsa_sig_max; + if (!ossl_ml_dsa_sign(ctx->key->ml_dsa_key, 0, + tbs, tbs_len, + (const unsigned char *)info->label, strlen(info->label), + rnd, sizeof(rnd), 1, + sig, &ml_dsa_siglen, sigsize)) + goto err; + + /* Traditional component: sign M' with the classic key */ + classic_siglen = sigsize - ml_dsa_siglen; + if (!composite_classic_sign(ctx, info, tbs, tbs_len, + sig + ml_dsa_siglen, &classic_siglen)) + goto err; + + /* Wire format: mldsaSig || tradSig (flat concatenation) */ + *siglen = ml_dsa_siglen + classic_siglen; + ret = 1; + +err: + OPENSSL_clear_free(tbs, tbs_len); + return ret; +} + +static int composite_sign(void *vctx, uint8_t *sig, size_t *siglen, size_t sigsize, + const uint8_t *msg, size_t msg_len) +{ + PROV_COMPOSITE_CTX *ctx = (PROV_COMPOSITE_CTX *)vctx; + const COMPOSITE_ALG_INFO *info; + uint8_t prehash[64]; /* max prehash output size */ + const uint8_t *ph = NULL; + size_t ph_len = 0; + + if (!ossl_prov_is_running()) + return 0; + + if (ctx->key == NULL || ctx->alg == NULL) + return 0; + + info = composite_find_alg_info(ctx->alg); + if (info == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_UNSUPPORTED); + return 0; + } + + if (sig != NULL) { + if (ctx->have_prehash) { + /* Caller pre-computed PH(M) itself and passed it in as msg. */ + ph = msg; + ph_len = msg_len; + } else { + if (!composite_compute_prehash(ctx->libctx, info, msg, msg_len, prehash)) + return 0; + ph = prehash; + ph_len = info->prehash_len; + } + } + + return composite_sign_ph(ctx, info, sig, siglen, sigsize, ph, ph_len); +} + +static void composite_freectx(void *vctx) +{ + PROV_COMPOSITE_CTX *ctx = (PROV_COMPOSITE_CTX *)vctx; + + EVP_MD_CTX_free(ctx->prehash_ctx); + OPENSSL_free(ctx->sig); + OPENSSL_cleanse(ctx->test_entropy, sizeof(ctx->test_entropy)); + OPENSSL_free(ctx); +} + +static void *composite_dupctx(void *vctx) +{ + PROV_COMPOSITE_CTX *src = (PROV_COMPOSITE_CTX *)vctx; + PROV_COMPOSITE_CTX *dst; + + dst = OPENSSL_memdup(src, sizeof(*src)); + if (dst == NULL) + return NULL; + + dst->prehash_ctx = NULL; + dst->sig = NULL; + + if (src->prehash_ctx != NULL) { + dst->prehash_ctx = EVP_MD_CTX_dup(src->prehash_ctx); + if (dst->prehash_ctx == NULL) + goto err; + } + + if (src->sig != NULL) { + dst->sig = OPENSSL_memdup(src->sig, src->siglen); + if (dst->sig == NULL) + goto err; + } + + return dst; +err: + EVP_MD_CTX_free(dst->prehash_ctx); + OPENSSL_free(dst->sig); + OPENSSL_free(dst); + return NULL; +} + +static int composite_set_ctx_params(void *vctx, const OSSL_PARAM params[]); + +static int composite_sign_init(void *vctx, void *vkey, const OSSL_PARAM params[]) +{ + PROV_COMPOSITE_CTX *ctx = (PROV_COMPOSITE_CTX *)vctx; + const COMPOSITE_ALG_INFO *info; + + if (ctx == NULL || vkey == NULL) + return 0; + + ctx->key = (COMPOSITE_KEY *)vkey; + ctx->operation = EVP_PKEY_OP_SIGN; + + info = composite_find_alg_info(ctx->alg); + if (info == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_UNSUPPORTED); + return 0; + } + + ctx->oid = info->oid; + ctx->oid_sz = info->oid_sz; + ctx->prehash_alg = info->prehash_alg; + ctx->prehash_len = info->prehash_len; + + return composite_set_ctx_params(ctx, params); +} + +static int composite_verify_init(void *vctx, void *vkey, const OSSL_PARAM params[]) +{ + PROV_COMPOSITE_CTX *ctx = (PROV_COMPOSITE_CTX *)vctx; + const COMPOSITE_ALG_INFO *info; + + if (ctx == NULL || vkey == NULL) + return 0; + + ctx->key = (COMPOSITE_KEY *)vkey; + ctx->operation = EVP_PKEY_OP_VERIFY; + + info = composite_find_alg_info(ctx->alg); + if (info == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_UNSUPPORTED); + return 0; + } + + ctx->oid = info->oid; + ctx->oid_sz = info->oid_sz; + ctx->prehash_alg = info->prehash_alg; + ctx->prehash_len = info->prehash_len; + + return composite_set_ctx_params(ctx, params); +} + +/* + * Shared core of verification: mirrors composite_sign_ph(), taking an + * already-computed PH(M) from any of the same three sources. + */ +static int composite_verify_ph(PROV_COMPOSITE_CTX *ctx, + const COMPOSITE_ALG_INFO *info, + const uint8_t *sig, size_t siglen, + const uint8_t *ph, size_t ph_len) +{ + uint8_t *tbs = NULL; + size_t tbs_len = 0; + size_t ml_dsa_sig_len; + EVP_MD_CTX *md_ctx = NULL; + EVP_PKEY_CTX *pctx = NULL; + int ret = 0; + + ml_dsa_sig_len = ossl_ml_dsa_key_get_sig_len(ctx->key->ml_dsa_key); + if (siglen <= ml_dsa_sig_len) { + ERR_raise(ERR_LIB_PROV, PROV_R_BAD_ENCODING); + return 0; + } + + tbs = composite_build_mprime(ctx, info, ph, ph_len, &tbs_len); + if (tbs == NULL) + goto err; + + /* Verify ML-DSA component, with Label as mldsa_ctx per §3.2 */ + if (!ossl_ml_dsa_verify(ctx->key->ml_dsa_key, 0, + tbs, tbs_len, + (const unsigned char *)info->label, strlen(info->label), + 1, sig, ml_dsa_sig_len)) + goto err; + + /* Verify classic component */ + md_ctx = EVP_MD_CTX_new(); + if (md_ctx == NULL) + goto err; + + switch (info->classic_type) { + case COMPOSITE_CLASSIC_ED25519: + case COMPOSITE_CLASSIC_ED448: + if (!EVP_DigestVerifyInit_ex(md_ctx, NULL, NULL, + ctx->libctx, NULL, + ctx->key->classic_key, NULL)) + goto err; + break; + + case COMPOSITE_CLASSIC_ECDSA: + if (!EVP_DigestVerifyInit_ex(md_ctx, NULL, info->classic_hash, + ctx->libctx, NULL, + ctx->key->classic_key, NULL)) + goto err; + break; + + case COMPOSITE_CLASSIC_RSA_PSS: + if (!EVP_DigestVerifyInit_ex(md_ctx, &pctx, info->classic_hash, + ctx->libctx, NULL, + ctx->key->classic_key, NULL)) + goto err; + { + const char *mgf1 = (info->mgf1_hash != NULL) + ? info->mgf1_hash + : info->classic_hash; + if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) <= 0 + || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, info->pss_salt_len) <= 0 + || EVP_PKEY_CTX_set_rsa_mgf1_md_name(pctx, mgf1, NULL) <= 0) + goto err; + } + break; + + case COMPOSITE_CLASSIC_RSA_PKCS15: + if (!EVP_DigestVerifyInit_ex(md_ctx, &pctx, info->classic_hash, + ctx->libctx, NULL, + ctx->key->classic_key, NULL)) + goto err; + if (EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PADDING) <= 0) + goto err; + break; + + default: + ERR_raise(ERR_LIB_PROV, ERR_R_UNSUPPORTED); + goto err; + } + + if (EVP_DigestVerify(md_ctx, + sig + ml_dsa_sig_len, + siglen - ml_dsa_sig_len, + tbs, tbs_len) + != 1) + goto err; + + ret = 1; +err: + EVP_MD_CTX_free(md_ctx); + OPENSSL_clear_free(tbs, tbs_len); + return ret; +} + +static int composite_verify(void *vctx, const uint8_t *sig, size_t siglen, + const uint8_t *msg, size_t msg_len) +{ + PROV_COMPOSITE_CTX *ctx = (PROV_COMPOSITE_CTX *)vctx; + const COMPOSITE_ALG_INFO *info; + uint8_t prehash[64]; /* max prehash output size */ + const uint8_t *ph; + size_t ph_len; + + if (!ossl_prov_is_running()) + return 0; + + if (ctx->key == NULL || ctx->alg == NULL || sig == NULL || msg == NULL) + return 0; + + info = composite_find_alg_info(ctx->alg); + if (info == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_UNSUPPORTED); + return 0; + } + + if (ctx->have_prehash) { + /* Caller pre-computed PH(M) itself and passed it in as msg. */ + ph = msg; + ph_len = msg_len; + } else { + if (!composite_compute_prehash(ctx->libctx, info, msg, msg_len, prehash)) + return 0; + ph = prehash; + ph_len = info->prehash_len; + } + + return composite_verify_ph(ctx, info, sig, siglen, ph, ph_len); +} + +static const COMPOSITE_ALG_INFO *composite_ctx_alg_info(PROV_COMPOSITE_CTX *ctx) +{ + if (ctx == NULL || ctx->alg == NULL) + return NULL; + return composite_find_alg_info(ctx->alg); +} + +/* + * Finalize the streaming PH(M) digest, mirroring composite_compute_prehash(): + * SHAKE256 is a XOF and must use EVP_DigestFinalXOF() with the algorithm's + * fixed prehash_len, since EVP_DigestFinal_ex() would truncate it to the + * digest's default fixed output size instead. + */ +static int composite_prehash_final(PROV_COMPOSITE_CTX *ctx, + const COMPOSITE_ALG_INFO *info, + uint8_t *ph, unsigned int *ph_len) +{ + if (OPENSSL_strcasecmp(info->prehash_alg, "SHAKE256") == 0) { + if (!EVP_DigestFinalXOF(ctx->prehash_ctx, ph, info->prehash_len)) + return 0; + *ph_len = (unsigned int)info->prehash_len; + return 1; + } + return EVP_DigestFinal_ex(ctx->prehash_ctx, ph, ph_len); +} + +/* + * Lazily start (on the first update) a streaming digest of the message for + * PH(M), using the algorithm's prehash digest (e.g. SHA-512). + */ +static int composite_signverify_msg_update(void *vctx, + const unsigned char *data, + size_t datalen) +{ + PROV_COMPOSITE_CTX *ctx = (PROV_COMPOSITE_CTX *)vctx; + const COMPOSITE_ALG_INFO *info; + EVP_MD *md; + + if (ctx == NULL || !ossl_prov_is_running()) + return 0; + + if (ctx->prehash_ctx == NULL) { + info = composite_ctx_alg_info(ctx); + if (info == NULL) + return 0; + + md = EVP_MD_fetch(ctx->libctx, info->prehash_alg, NULL); + if (md == NULL) + return 0; + + ctx->prehash_ctx = EVP_MD_CTX_new(); + if (ctx->prehash_ctx == NULL || !EVP_DigestInit_ex2(ctx->prehash_ctx, md, NULL)) { + EVP_MD_CTX_free(ctx->prehash_ctx); + ctx->prehash_ctx = NULL; + EVP_MD_free(md); + return 0; + } + EVP_MD_free(md); + } + + return EVP_DigestUpdate(ctx->prehash_ctx, data, datalen); +} + +static int composite_sign_msg_init(void *vctx, void *vkey, + const OSSL_PARAM params[]) +{ + return composite_sign_init(vctx, vkey, params); +} + +static int composite_sign_msg_final(void *vctx, unsigned char *sig, + size_t *siglen, size_t sigsize) +{ + PROV_COMPOSITE_CTX *ctx = (PROV_COMPOSITE_CTX *)vctx; + const COMPOSITE_ALG_INFO *info; + uint8_t ph[64]; + unsigned int ph_len; + + if (ctx == NULL || !ossl_prov_is_running()) + return 0; + + info = composite_ctx_alg_info(ctx); + if (info == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_UNSUPPORTED); + return 0; + } + + if (sig == NULL) + return composite_sign_ph(ctx, info, sig, siglen, sigsize, NULL, 0); + + if (ctx->prehash_ctx == NULL) + return 0; /* no data was ever fed via msg_update() */ + + if (!composite_prehash_final(ctx, info, ph, &ph_len)) + return 0; + EVP_MD_CTX_free(ctx->prehash_ctx); + ctx->prehash_ctx = NULL; + + return composite_sign_ph(ctx, info, sig, siglen, sigsize, ph, ph_len); +} + +static int composite_verify_msg_init(void *vctx, void *vkey, + const OSSL_PARAM params[]) +{ + return composite_verify_init(vctx, vkey, params); +} + +/* + * Per provider-signature.pod, the signature to check is supplied out of + * band via OSSL_SIGNATURE_PARAM_SIGNATURE (see composite_set_ctx_params()), + * not as an argument here. + */ +static int composite_verify_msg_final(void *vctx) +{ + PROV_COMPOSITE_CTX *ctx = (PROV_COMPOSITE_CTX *)vctx; + const COMPOSITE_ALG_INFO *info; + uint8_t ph[64]; + unsigned int ph_len; + + if (ctx == NULL || !ossl_prov_is_running()) + return 0; + + if (ctx->sig == NULL || ctx->prehash_ctx == NULL) + return 0; + + info = composite_ctx_alg_info(ctx); + if (info == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_UNSUPPORTED); + return 0; + } + + if (!composite_prehash_final(ctx, info, ph, &ph_len)) + return 0; + EVP_MD_CTX_free(ctx->prehash_ctx); + ctx->prehash_ctx = NULL; + + return composite_verify_ph(ctx, info, ctx->sig, ctx->siglen, ph, ph_len); +} + +static int composite_get_ctx_params(void *vctx, OSSL_PARAM params[]) +{ + PROV_COMPOSITE_CTX *ctx = (PROV_COMPOSITE_CTX *)vctx; + struct composite_get_ctx_params_st p; + + if (ctx == NULL || !composite_get_ctx_params_decoder(params, &p)) + return 0; + + if (p.id != NULL) { + /* DER AlgorithmIdentifier = SEQUENCE { OID }, built like the other signature providers */ + WPACKET pkt; + unsigned char aid_buf[32]; + unsigned char *aid; + size_t aid_len; + int ok; + + if (ctx->oid == NULL || ctx->oid_sz == 0) + return 0; + + if (!WPACKET_init_der(&pkt, aid_buf, sizeof(aid_buf))) + return 0; + + ok = ossl_DER_w_begin_sequence(&pkt, -1) + && ossl_DER_w_precompiled(&pkt, -1, ctx->oid, ctx->oid_sz) + && ossl_DER_w_end_sequence(&pkt, -1) + && WPACKET_finish(&pkt); + if (ok) { + WPACKET_get_total_written(&pkt, &aid_len); + aid = WPACKET_get_curr(&pkt); + ok = OSSL_PARAM_set_octet_string(p.id, aid, aid_len); + } + WPACKET_cleanup(&pkt); + if (!ok) + return 0; + } + + return 1; +} + +static const OSSL_PARAM *composite_gettable_ctx_params(void *vctx, void *provctx) +{ + return composite_get_ctx_params_list; +} + +static int composite_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + PROV_COMPOSITE_CTX *ctx = (PROV_COMPOSITE_CTX *)vctx; + struct composite_verifymsg_set_ctx_params_st p; + + if (ctx == NULL || !composite_verifymsg_set_ctx_params_decoder(params, &p)) + return 0; + + if (p.ctx != NULL) { + void *vp = ctx->context_string; + + if (!OSSL_PARAM_get_octet_string(p.ctx, &vp, sizeof(ctx->context_string), + &ctx->context_string_len)) { + ctx->context_string_len = 0; + return 0; + } + } + + if (p.ent != NULL) { + void *vp = ctx->test_entropy; + + ctx->test_entropy_len = 0; + if (!OSSL_PARAM_get_octet_string(p.ent, &vp, sizeof(ctx->test_entropy), + &ctx->test_entropy_len)) + return 0; + if (ctx->test_entropy_len != sizeof(ctx->test_entropy)) { + ctx->test_entropy_len = 0; + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_SEED_LENGTH); + return 0; + } + } + + if (p.ph != NULL && !OSSL_PARAM_get_int(p.ph, &ctx->have_prehash)) + return 0; + + if (p.sig != NULL && ctx->operation == EVP_PKEY_OP_VERIFY) { + OPENSSL_free(ctx->sig); + ctx->sig = NULL; + ctx->siglen = 0; + if (!OSSL_PARAM_get_octet_string(p.sig, (void **)&ctx->sig, 0, &ctx->siglen)) + return 0; + } + + return 1; +} + +static const OSSL_PARAM *composite_settable_ctx_params(void *vctx, void *provctx) +{ + PROV_COMPOSITE_CTX *ctx = (PROV_COMPOSITE_CTX *)vctx; + + if (ctx != NULL && ctx->operation == EVP_PKEY_OP_VERIFY) + return composite_verifymsg_set_ctx_params_list; + return composite_set_ctx_params_list; +} + +static int composite_digest_signverify_init(void *vctx, const char *mdname, + void *vkey, + const OSSL_PARAM params[]) +{ + if (mdname != NULL && mdname[0] != '\0') { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_DIGEST, + "Explicit digest not supported for composite " + "signature operations"); + return 0; + } + return composite_sign_init(vctx, vkey, params); +} + +static int composite_digest_sign(void *vctx, uint8_t *sig, size_t *siglen, + size_t sigsize, const uint8_t *tbs, + size_t tbslen) +{ + return composite_sign(vctx, sig, siglen, sigsize, tbs, tbslen); +} + +static int composite_digest_verify(void *vctx, const uint8_t *sig, + size_t siglen, const uint8_t *tbs, + size_t tbslen) +{ + return composite_verify(vctx, sig, siglen, tbs, tbslen); +} + +/* + * Per-algorithm newctx functions and dispatch tables. + * The alg string is stored in the context for domain separator selection. + */ +#define MAKE_COMPOSITE_FUNCTIONS(name, namestr) \ + static void *composite_##name##_newctx(void *provctx, const char *propq) \ + { \ + PROV_COMPOSITE_CTX *ctx = composite_newctx(provctx, 0, propq); \ + if (ctx != NULL) \ + ctx->alg = namestr; \ + return ctx; \ + } \ + const OSSL_DISPATCH ossl_##name##_signature_functions[] = { \ + { OSSL_FUNC_SIGNATURE_NEWCTX, \ + (void (*)(void))composite_##name##_newctx }, \ + { OSSL_FUNC_SIGNATURE_FREECTX, \ + (void (*)(void))composite_freectx }, \ + { OSSL_FUNC_SIGNATURE_DUPCTX, \ + (void (*)(void))composite_dupctx }, \ + { OSSL_FUNC_SIGNATURE_SIGN_INIT, \ + (void (*)(void))composite_sign_init }, \ + { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_INIT, \ + (void (*)(void))composite_sign_msg_init }, \ + { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_UPDATE, \ + (void (*)(void))composite_signverify_msg_update }, \ + { OSSL_FUNC_SIGNATURE_SIGN_MESSAGE_FINAL, \ + (void (*)(void))composite_sign_msg_final }, \ + { OSSL_FUNC_SIGNATURE_SIGN, \ + (void (*)(void))composite_sign }, \ + { OSSL_FUNC_SIGNATURE_VERIFY_INIT, \ + (void (*)(void))composite_verify_init }, \ + { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_INIT, \ + (void (*)(void))composite_verify_msg_init }, \ + { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_UPDATE, \ + (void (*)(void))composite_signverify_msg_update }, \ + { OSSL_FUNC_SIGNATURE_VERIFY_MESSAGE_FINAL, \ + (void (*)(void))composite_verify_msg_final }, \ + { OSSL_FUNC_SIGNATURE_VERIFY, \ + (void (*)(void))composite_verify }, \ + { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, \ + (void (*)(void))composite_digest_signverify_init }, \ + { OSSL_FUNC_SIGNATURE_DIGEST_SIGN, \ + (void (*)(void))composite_digest_sign }, \ + { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, \ + (void (*)(void))composite_digest_signverify_init }, \ + { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY, \ + (void (*)(void))composite_digest_verify }, \ + { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, \ + (void (*)(void))composite_get_ctx_params }, \ + { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, \ + (void (*)(void))composite_gettable_ctx_params }, \ + { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, \ + (void (*)(void))composite_set_ctx_params }, \ + { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, \ + (void (*)(void))composite_settable_ctx_params }, \ + OSSL_DISPATCH_END \ + } + +MAKE_COMPOSITE_FUNCTIONS(mldsa44_rsa2048_pss_sha256, + "ML-DSA-44-RSA2048-PSS-SHA256"); +MAKE_COMPOSITE_FUNCTIONS(mldsa44_rsa2048_pkcs15_sha256, + "ML-DSA-44-RSA2048-PKCS15-SHA256"); +MAKE_COMPOSITE_FUNCTIONS(mldsa44_ed25519_sha512, + "ML-DSA-44-Ed25519-SHA512"); +MAKE_COMPOSITE_FUNCTIONS(mldsa44_ecdsa_p256_sha256, + "ML-DSA-44-ECDSA-P256-SHA256"); +MAKE_COMPOSITE_FUNCTIONS(mldsa65_rsa3072_pss_sha512, + "ML-DSA-65-RSA3072-PSS-SHA512"); +MAKE_COMPOSITE_FUNCTIONS(mldsa65_rsa3072_pkcs15_sha512, + "ML-DSA-65-RSA3072-PKCS15-SHA512"); +MAKE_COMPOSITE_FUNCTIONS(mldsa65_rsa4096_pss_sha512, + "ML-DSA-65-RSA4096-PSS-SHA512"); +MAKE_COMPOSITE_FUNCTIONS(mldsa65_rsa4096_pkcs15_sha512, + "ML-DSA-65-RSA4096-PKCS15-SHA512"); +MAKE_COMPOSITE_FUNCTIONS(mldsa65_ecdsa_p256_sha512, + "ML-DSA-65-ECDSA-P256-SHA512"); +MAKE_COMPOSITE_FUNCTIONS(mldsa65_ecdsa_p384_sha512, + "ML-DSA-65-ECDSA-P384-SHA512"); +MAKE_COMPOSITE_FUNCTIONS(mldsa65_ecdsa_brainpoolP256r1_sha512, + "ML-DSA-65-ECDSA-brainpoolP256r1-SHA512"); +MAKE_COMPOSITE_FUNCTIONS(mldsa65_ed25519_sha512, + "ML-DSA-65-Ed25519-SHA512"); +MAKE_COMPOSITE_FUNCTIONS(mldsa87_ecdsa_p384_sha512, + "ML-DSA-87-ECDSA-P384-SHA512"); +MAKE_COMPOSITE_FUNCTIONS(mldsa87_ecdsa_brainpoolP384r1_sha512, + "ML-DSA-87-ECDSA-brainpoolP384r1-SHA512"); +MAKE_COMPOSITE_FUNCTIONS(mldsa87_ed448_shake256, + "ML-DSA-87-Ed448-SHAKE256"); +MAKE_COMPOSITE_FUNCTIONS(mldsa87_rsa3072_pss_sha512, + "ML-DSA-87-RSA3072-PSS-SHA512"); +MAKE_COMPOSITE_FUNCTIONS(mldsa87_rsa4096_pss_sha512, + "ML-DSA-87-RSA4096-PSS-SHA512"); +MAKE_COMPOSITE_FUNCTIONS(mldsa87_ecdsa_p521_sha512, + "ML-DSA-87-ECDSA-P521-SHA512"); diff --git a/providers/implementations/signature/composite_sig.inc.in b/providers/implementations/signature/composite_sig.inc.in new file mode 100644 index 0000000000000..8307c91a794a1 --- /dev/null +++ b/providers/implementations/signature/composite_sig.inc.in @@ -0,0 +1,29 @@ +/* + * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +{- +use OpenSSL::paramnames qw(produce_param_decoder); +-} + +{- produce_param_decoder('composite_set_ctx_params', + (['OSSL_SIGNATURE_PARAM_CONTEXT_STRING', 'ctx', 'octet_string'], + ['OSSL_SIGNATURE_PARAM_TEST_ENTROPY', 'ent', 'octet_string'], + ['OSSL_SIGNATURE_PARAM_COMPOSITE_PREHASH', 'ph', 'int'], + )); -} + +{- produce_param_decoder('composite_verifymsg_set_ctx_params', + (['OSSL_SIGNATURE_PARAM_CONTEXT_STRING', 'ctx', 'octet_string'], + ['OSSL_SIGNATURE_PARAM_TEST_ENTROPY', 'ent', 'octet_string'], + ['OSSL_SIGNATURE_PARAM_COMPOSITE_PREHASH', 'ph', 'int'], + ['OSSL_SIGNATURE_PARAM_SIGNATURE', 'sig', 'octet_string'], + )); -} + +{- produce_param_decoder('composite_get_ctx_params', + (['OSSL_SIGNATURE_PARAM_ALGORITHM_ID', 'id', 'octet_string'], + )); -} diff --git a/providers/implementations/signature/ml_dsa_sig.c b/providers/implementations/signature/ml_dsa_sig.c index c661ab67b8725..79d523ce17a90 100644 --- a/providers/implementations/signature/ml_dsa_sig.c +++ b/providers/implementations/signature/ml_dsa_sig.c @@ -280,14 +280,17 @@ static int ml_dsa_sign_msg_final(void *vctx, unsigned char *sig, return 0; } - if (!ossl_ml_dsa_mu_finalize(ctx->md_ctx, mu, sizeof(mu))) + if (!ossl_ml_dsa_mu_finalize(ctx->md_ctx, mu, sizeof(mu))) { + OPENSSL_cleanse(mu, sizeof(mu)); return 0; + } } ret = ossl_ml_dsa_sign(ctx->key, 1, mu, sizeof(mu), NULL, 0, rnd, sizeof(rand_tmp), 0, sig, siglen, sigsize); if (rnd != ctx->test_entropy) OPENSSL_cleanse(rand_tmp, sizeof(rand_tmp)); + OPENSSL_cleanse(mu, sizeof(mu)); return ret; } @@ -338,6 +341,7 @@ static int ml_dsa_verify_msg_final(void *vctx) { PROV_ML_DSA_CTX *ctx = (PROV_ML_DSA_CTX *)vctx; uint8_t mu[ML_DSA_MU_BYTES]; + int ret = 0; if (!ossl_prov_is_running()) return 0; @@ -345,11 +349,12 @@ static int ml_dsa_verify_msg_final(void *vctx) if (ctx->md_ctx == NULL) return 0; - if (!ossl_ml_dsa_mu_finalize(ctx->md_ctx, mu, sizeof(mu))) - return 0; + if (ossl_ml_dsa_mu_finalize(ctx->md_ctx, mu, sizeof(mu))) + ret = ossl_ml_dsa_verify(ctx->key, 1, mu, sizeof(mu), NULL, 0, 0, + ctx->sig, ctx->siglen); - return ossl_ml_dsa_verify(ctx->key, 1, mu, sizeof(mu), NULL, 0, 0, - ctx->sig, ctx->siglen); + OPENSSL_cleanse(mu, sizeof(mu)); + return ret; } static int ml_dsa_verify(void *vctx, const uint8_t *sig, size_t siglen, diff --git a/providers/implementations/signature/rsa_sig.c b/providers/implementations/signature/rsa_sig.c index 3d56bd0185ca1..6a7ab4a1500d1 100644 --- a/providers/implementations/signature/rsa_sig.c +++ b/providers/implementations/signature/rsa_sig.c @@ -13,6 +13,7 @@ */ #include "internal/deprecated.h" +#include #include #include #include @@ -1026,7 +1027,13 @@ static int rsa_verify_recover(void *vprsactx, } ret = RSA_public_decrypt((int)siglen, sig, rout, prsactx->rsa, prsactx->pad_mode); - if (ret <= 0) { + /* + * RSA_public_decrypt() returns -1 on error and otherwise the number + * of recovered bytes, which may legitimately be zero for a raw + * PKCS#1 v1.5 signature that encodes an empty payload. Treat only + * a negative result as an error. + */ + if (ret < 0) { ERR_raise(ERR_LIB_PROV, ERR_R_RSA_LIB); return 0; } @@ -1483,10 +1490,10 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params) value = OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX; break; default: { - int len = BIO_snprintf(p.slen->data, p.slen->data_size, "%d", + int len = snprintf(p.slen->data, p.slen->data_size, "%d", prsactx->saltlen); - if (len <= 0) + if (len <= 0 || (size_t)len >= p.slen->data_size) return 0; p.slen->return_size = len; break; @@ -1689,8 +1696,11 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[]) saltlen = RSA_PSS_SALTLEN_AUTO; else if (strcmp(p.slen->data, OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX) == 0) saltlen = RSA_PSS_SALTLEN_AUTO_DIGEST_MAX; - else - saltlen = atoi(p.slen->data); + else if (!ossl_strtoint(p.slen->data, NULL, 10, &saltlen)) { + ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_SALT_LENGTH, + "invalid RSA-PSS saltlen value"); + return 0; + } } /* diff --git a/providers/implementations/signature/slh_dsa_sig.c b/providers/implementations/signature/slh_dsa_sig.c index fa315a7b84a45..a6deef7048090 100644 --- a/providers/implementations/signature/slh_dsa_sig.c +++ b/providers/implementations/signature/slh_dsa_sig.c @@ -80,7 +80,7 @@ static void slh_dsa_freectx(void *vctx) ossl_slh_dsa_hash_ctx_free(ctx->hash_ctx); OPENSSL_free(ctx->propq); - OPENSSL_cleanse(ctx->add_random, ctx->add_random_len); + OPENSSL_cleanse(ctx->add_random, sizeof(ctx->add_random)); OPENSSL_free(ctx); } diff --git a/providers/implementations/skeymgmt/aes_skmgmt.c b/providers/implementations/skeymgmt/aes_skmgmt.c index 87bd76d08bd88..cc26e657e5f6d 100644 --- a/providers/implementations/skeymgmt/aes_skmgmt.c +++ b/providers/implementations/skeymgmt/aes_skmgmt.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -50,5 +50,10 @@ const OSSL_DISPATCH ossl_aes_skeymgmt_functions[] = { { OSSL_FUNC_SKEYMGMT_EXPORT, (void (*)(void))aes_export }, { OSSL_FUNC_SKEYMGMT_IMP_SETTABLE_PARAMS, (void (*)(void))generic_imp_settable_params }, + { OSSL_FUNC_SKEYMGMT_GET_KEY_ID, (void (*)(void))generic_get_key_id }, + { OSSL_FUNC_SKEYMGMT_GET_LOCAL_KEYID, + (void (*)(void))generic_get_local_keyid }, + { OSSL_FUNC_SKEYMGMT_GET_ALGORITHM_ID, + (void (*)(void))generic_get_algorithm_id }, OSSL_DISPATCH_END }; diff --git a/providers/implementations/skeymgmt/generic.c b/providers/implementations/skeymgmt/generic.c index 9508c3a5fb133..a4f443f30718c 100644 --- a/providers/implementations/skeymgmt/generic.c +++ b/providers/implementations/skeymgmt/generic.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -29,10 +29,62 @@ void generic_free(void *keydata) return; OPENSSL_clear_free(generic->data, generic->length); + OPENSSL_free(generic->alias); + OPENSSL_free(generic->local_keyid); + OPENSSL_free(generic->algorithm_oid); + OPENSSL_free(generic->algorithm_params); OPENSSL_free(generic); } -void *generic_import(void *provctx, int selection, const OSSL_PARAM params[]) +static int generic_import_metadata(PROV_SKEY *skey, + const struct generic_skey_import_st *p) +{ + if (p->alias != NULL + && p->alias->data_type == OSSL_PARAM_UTF8_STRING + && skey->alias == NULL) { + skey->alias = OPENSSL_strndup(p->alias->data, p->alias->data_size); + if (skey->alias == NULL) + return 0; + if (strlen(skey->alias) != p->alias->data_size) { + ERR_raise(ERR_R_PROV_LIB, PROV_R_INVALID_DATA); + return 0; + } + } + + if (p->local_keyid != NULL + && p->local_keyid->data_type == OSSL_PARAM_OCTET_STRING + && skey->local_keyid == NULL) { + skey->local_keyid = OPENSSL_memdup(p->local_keyid->data, + p->local_keyid->data_size); + if (skey->local_keyid == NULL) + return 0; + skey->local_keyid_len = p->local_keyid->data_size; + } + + if (p->algorithm_oid != NULL + && p->algorithm_oid->data_type == OSSL_PARAM_OCTET_STRING + && skey->algorithm_oid == NULL) { + skey->algorithm_oid = OPENSSL_memdup(p->algorithm_oid->data, + p->algorithm_oid->data_size); + if (skey->algorithm_oid == NULL) + return 0; + skey->algorithm_oid_len = p->algorithm_oid->data_size; + } + + if (p->algorithm_params != NULL + && p->algorithm_params->data_type == OSSL_PARAM_OCTET_STRING + && skey->algorithm_params == NULL) { + skey->algorithm_params = OPENSSL_memdup(p->algorithm_params->data, + p->algorithm_params->data_size); + if (skey->algorithm_params == NULL) + return 0; + skey->algorithm_params_len = p->algorithm_params->data_size; + } + + return 1; +} + +void *generic_import(void *provctx, int selection ossl_unused, const OSSL_PARAM params[]) { OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(provctx); struct generic_skey_import_st p; @@ -42,9 +94,6 @@ void *generic_import(void *provctx, int selection, const OSSL_PARAM params[]) if (!ossl_prov_is_running()) return NULL; - if ((selection & OSSL_SKEYMGMT_SELECT_SECRET_KEY) == 0) - return NULL; - if (!generic_skey_import_decoder(params, &p)) return NULL; @@ -65,6 +114,10 @@ void *generic_import(void *provctx, int selection, const OSSL_PARAM params[]) == NULL) goto end; generic->length = p.raw_bytes->data_size; + + if (!generic_import_metadata(generic, &p)) + goto end; + ok = 1; end: @@ -84,27 +137,107 @@ int generic_export(void *keydata, int selection, OSSL_CALLBACK *param_callback, void *cbarg) { PROV_SKEY *gen = keydata; - OSSL_PARAM params[2]; + OSSL_PARAM params[6]; + int idx = 0; - if (!ossl_prov_is_running() || gen == NULL) + if (!ossl_prov_is_running() || gen == NULL || selection == 0) return 0; /* If we use generic SKEYMGMT as a "base class", we shouldn't check the type */ - if ((selection & OSSL_SKEYMGMT_SELECT_SECRET_KEY) == 0) - return 0; + if ((selection & OSSL_SKEYMGMT_SELECT_SECRET_KEY) != 0) + params[idx++] = OSSL_PARAM_construct_octet_string(OSSL_SKEY_PARAM_RAW_BYTES, + gen->data, gen->length); + + if ((selection & OSSL_SKEYMGMT_SELECT_PARAMETERS) != 0) { + if (gen->alias != NULL) + params[idx++] = OSSL_PARAM_construct_utf8_string( + OSSL_SKEY_PARAM_ALIAS, gen->alias, 0); + + if (gen->local_keyid != NULL) + params[idx++] = OSSL_PARAM_construct_octet_string( + OSSL_SKEY_PARAM_LOCAL_KEYID, + gen->local_keyid, gen->local_keyid_len); + + if (gen->algorithm_oid != NULL) + params[idx++] = OSSL_PARAM_construct_octet_string( + OSSL_SKEY_PARAM_ALGORITHM_OID, + gen->algorithm_oid, gen->algorithm_oid_len); + + if (gen->algorithm_params != NULL) + params[idx++] = OSSL_PARAM_construct_octet_string( + OSSL_SKEY_PARAM_ALGORITHM_PARAMS, + gen->algorithm_params, gen->algorithm_params_len); + } - params[0] = OSSL_PARAM_construct_octet_string(OSSL_SKEY_PARAM_RAW_BYTES, - gen->data, gen->length); - params[1] = OSSL_PARAM_construct_end(); + params[idx] = OSSL_PARAM_construct_end(); return param_callback(params, cbarg); } +const char *generic_get_key_id(void *keydata) +{ + PROV_SKEY *gen = keydata; + + if (gen == NULL) + return NULL; + + return gen->alias; +} + +int generic_get_local_keyid(void *keydata, + const unsigned char **id, size_t *len) +{ + PROV_SKEY *gen = keydata; + + if (gen == NULL) + return 0; + if (id == NULL || len == NULL) + return 0; + + *id = gen->local_keyid; + *len = gen->local_keyid_len; + return 1; +} + +int generic_get_algorithm_id(void *keydata, + const unsigned char **oid, size_t *oid_len, + const unsigned char **params, size_t *params_len) +{ + PROV_SKEY *gen = keydata; + int ret_oid = 0, ret_params = 0; + + if (gen == NULL) + return 0; + + if (oid != NULL && oid_len != NULL) + ret_oid = 1; + if (params != NULL && params_len != NULL) + ret_params = 1; + + if (ret_oid == 0 && ret_params == 0) + return 0; + + if (ret_oid == 1) { + *oid = gen->algorithm_oid; + *oid_len = gen->algorithm_oid_len; + } + if (ret_params == 1) { + *params = gen->algorithm_params; + *params_len = gen->algorithm_params_len; + } + return 1; +} + const OSSL_DISPATCH ossl_generic_skeymgmt_functions[] = { { OSSL_FUNC_SKEYMGMT_FREE, (void (*)(void))generic_free }, { OSSL_FUNC_SKEYMGMT_IMPORT, (void (*)(void))generic_import }, { OSSL_FUNC_SKEYMGMT_EXPORT, (void (*)(void))generic_export }, { OSSL_FUNC_SKEYMGMT_IMP_SETTABLE_PARAMS, (void (*)(void))generic_imp_settable_params }, + { OSSL_FUNC_SKEYMGMT_GET_KEY_ID, (void (*)(void))generic_get_key_id }, + { OSSL_FUNC_SKEYMGMT_GET_LOCAL_KEYID, + (void (*)(void))generic_get_local_keyid }, + { OSSL_FUNC_SKEYMGMT_GET_ALGORITHM_ID, + (void (*)(void))generic_get_algorithm_id }, OSSL_DISPATCH_END }; diff --git a/providers/implementations/skeymgmt/generic.inc.in b/providers/implementations/skeymgmt/generic.inc.in index 6f30d5bce1e9a..440f373dafd7d 100644 --- a/providers/implementations/skeymgmt/generic.inc.in +++ b/providers/implementations/skeymgmt/generic.inc.in @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,5 +11,9 @@ use OpenSSL::paramnames qw(produce_param_decoder); -} {- produce_param_decoder('generic_skey_import', - (['OSSL_SKEY_PARAM_RAW_BYTES', 'raw_bytes', 'octet_string'], + (['OSSL_SKEY_PARAM_RAW_BYTES', 'raw_bytes', 'octet_string'], + ['OSSL_SKEY_PARAM_ALIAS', 'alias', 'utf8_string'], + ['OSSL_SKEY_PARAM_LOCAL_KEYID', 'local_keyid', 'octet_string'], + ['OSSL_SKEY_PARAM_ALGORITHM_OID', 'algorithm_oid', 'octet_string'], + ['OSSL_SKEY_PARAM_ALGORITHM_PARAMS','algorithm_params', 'octet_string'], )); -} diff --git a/providers/implementations/storemgmt/file_store.c b/providers/implementations/storemgmt/file_store.c index 894685ce8cd1f..3dc028d1045d4 100644 --- a/providers/implementations/storemgmt/file_store.c +++ b/providers/implementations/storemgmt/file_store.c @@ -9,6 +9,7 @@ /* This file has quite some overlap with engines/e_loader_attic.c */ +#include #include #include "internal/e_os.h" /* for stat() */ #include /* for struct stat */ @@ -368,7 +369,7 @@ static int file_set_ctx_params(void *loaderctx, const OSSL_PARAM params[]) hash = X509_NAME_hash_ex(x509_name, ossl_prov_ctx_get0_libctx(ctx->provctx), NULL, &ok); - BIO_snprintf(ctx->_.dir.search_name, sizeof(ctx->_.dir.search_name), + snprintf(ctx->_.dir.search_name, sizeof(ctx->_.dir.search_name), "%08lx", hash); end: X509_NAME_free(x509_name); @@ -586,7 +587,8 @@ static int file_load_file(struct file_ctx_st *ctx, data.object_cb = object_cb; data.object_cbarg = object_cbarg; - OSSL_DECODER_CTX_set_construct_data(ctx->_.file.decoderctx, &data); + if (!OSSL_DECODER_CTX_set_construct_data(ctx->_.file.decoderctx, &data)) + return 0; OSSL_DECODER_CTX_set_passphrase_cb(ctx->_.file.decoderctx, pw_cb, pw_cbarg); /* Launch */ diff --git a/providers/implementations/storemgmt/file_store_any2obj.c b/providers/implementations/storemgmt/file_store_any2obj.c index 2592ab04abf29..0eaae47af3bd9 100644 --- a/providers/implementations/storemgmt/file_store_any2obj.c +++ b/providers/implementations/storemgmt/file_store_any2obj.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -193,6 +193,10 @@ static int msblob2obj_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, ok = 0; mem_want = ossl_blob_length(bitlen, isdss, ispub); + + if (mem_want > BLOB_MAX_LENGTH) { + goto next; + } if (!BUF_MEM_grow(mem, mem_len + mem_want)) { ERR_raise(ERR_LIB_PEM, ERR_R_BUF_LIB); goto err; diff --git a/providers/implementations/storemgmt/winstore_store.c b/providers/implementations/storemgmt/winstore_store.c index 59318e7547641..f525469cc6f00 100644 --- a/providers/implementations/storemgmt/winstore_store.c +++ b/providers/implementations/storemgmt/winstore_store.c @@ -275,7 +275,8 @@ static int winstore_load_using(struct winstore_ctx_st *ctx, data.object_cb = object_cb; data.object_cbarg = object_cbarg; - OSSL_DECODER_CTX_set_construct_data(ctx->dctx, &data); + if (!OSSL_DECODER_CTX_set_construct_data(ctx->dctx, &data)) + return 0; OSSL_DECODER_CTX_set_passphrase_cb(ctx->dctx, pw_cb, pw_cbarg); if (OSSL_DECODER_from_data(ctx->dctx, &der_, &der_len_) == 0) diff --git a/providers/legacyprov.c b/providers/legacyprov.c index cf3365f4fb0c1..e5faff9bcbd61 100644 --- a/providers/legacyprov.c +++ b/providers/legacyprov.c @@ -255,6 +255,10 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, } #endif +#ifndef STATIC_LEGACY + OPENSSL_init_crypto(OPENSSL_INIT_NO_ATEXIT, NULL); +#endif + if ((*provctx = ossl_prov_ctx_new()) == NULL || (libctx = OSSL_LIB_CTX_new_child(handle, in)) == NULL) { OSSL_LIB_CTX_free(libctx); diff --git a/pyca-cryptography b/pyca-cryptography index 0e855f952693c..e83bbe58e3735 160000 --- a/pyca-cryptography +++ b/pyca-cryptography @@ -1 +1 @@ -Subproject commit 0e855f952693c8b730abb2fc5a84dfc69562f210 +Subproject commit e83bbe58e373536636baaa7c33a64a6e8f04c953 diff --git a/ssl/build.info b/ssl/build.info index 1bc57b43206df..e94b1591d439b 100644 --- a/ssl/build.info +++ b/ssl/build.info @@ -12,7 +12,7 @@ SOURCE[../libssl]=\ statem/statem_lib.c statem/extensions.c statem/extensions_srvr.c \ statem/extensions_clnt.c statem/extensions_cust.c s3_msg.c \ methods.c t1_lib.c t1_enc.c tls13_enc.c \ - d1_lib.c d1_msg.c \ + d1_lib.c d1_msg.c d1_transcript.c \ statem/statem_dtls.c d1_srtp.c \ ssl_lib.c ssl_cert.c ssl_sess.c \ ssl_ciph.c ssl_stat.c ssl_rsa.c \ @@ -25,18 +25,36 @@ SOURCE[../libssl]=\ # For shared builds we need to include the libcrypto packet.c and quic_vlint.c # in libssl as well. SHARED_SOURCE[../libssl]=\ - ../crypto/packet.c ../crypto/quic_vlint.c ../crypto/time.c + ../crypto/packet.c ../crypto/quic_vlint.c ../crypto/time.c \ + ../crypto/rbtree/rbtree.c IF[{- !$disabled{'deprecated-3.0'} -}] SOURCE[../libssl]=ssl_rsa_legacy.c ENDIF +IF[{- !$disabled{dtls} || !$disabled{quic} -}] + # Datagram demux is shared between DTLS listener and QUIC + SOURCE[../libssl]=dgram_demux.c +ENDIF + +IF[{- !$disabled{dtls} -}] + # DTLS listener support: connection lookup and RX handling + SOURCE[../libssl]=dtls_conn_lookup.c dtls_record_rx.c + # hashfunc.c is needed by dtls_conn_lookup.c for address hashing + SHARED_SOURCE[../libssl]=../crypto/hashtable/hashfunc.c +ENDIF + IF[{- !$disabled{quic} -}] SOURCE[../libssl]=priority_queue.c SHARED_SOURCE[../libssl] = ../crypto/hashtable/hashfunc.c - IF[{- $disabled{siphash} -}] - SOURCE[../libssl]=../crypto/siphash/siphash.c - ELSE - SHARED_SOURCE[../libssl]=../crypto/siphash/siphash.c - ENDIF +ENDIF + +# siphash.c is needed by dtls_conn_lookup.c (DTLS) and quic_lcidm.c (QUIC) +# for hash-flooding resistant connection lookup +IF[{- !$disabled{dtls} || !$disabled{quic} -}] + SHARED_SOURCE[../libssl]=../crypto/siphash/siphash.c +ENDIF + +IF[{- $target{needs_c99_snprintf_compat} -}] + SOURCE[../libssl]=../crypto/msvc2013_snprintf.c ENDIF diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index d7e1d740ca7a8..3f19be1743a75 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -12,12 +12,22 @@ #include #include #include +#include +#include #include "ssl_local.h" #include "internal/time.h" #include "internal/ssl_unwrap.h" +#include "internal/hashfunc.h" +#include "internal/dtls_record_rx.h" +#include "internal/dgram_demux.h" +#include "internal/dgram_conn_lookup.h" +#include "internal/rio_notifier.h" static int dtls1_handshake_write(SSL_CONNECTION *s); static const size_t dtls1_link_min_mtu = 256; +#ifndef OPENSSL_NO_DTLS +static OSSL_TIME dtls_listener_get_time_direct(DTLS_LISTENER *dl); +#endif const SSL3_ENC_METHOD DTLSv1_enc_data = { tls1_setup_key_block, @@ -50,6 +60,21 @@ const SSL3_ENC_METHOD DTLSv1_2_enc_data = { dtls1_handshake_write }; +const SSL3_ENC_METHOD DTLSv1_3_enc_data = { + tls13_setup_key_block, + tls13_generate_master_secret, + tls13_change_cipher_state, + tls13_final_finish_mac, + TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, + tls13_alert_code, + tls13_export_keying_material, + SSL_ENC_FLAG_DTLS | SSL_ENC_FLAG_SIGALGS | SSL_ENC_FLAG_SHA256_PRF, + dtls1_set_handshake_header, + dtls1_close_construct_packet, + dtls1_handshake_write +}; + OSSL_TIME dtls1_default_timeout(void) { /* @@ -78,16 +103,7 @@ int dtls1_new(SSL *ssl) return 0; } - d1->buffered_messages = pqueue_new(); - d1->sent_messages = pqueue_new(); - - if (d1->buffered_messages == NULL || d1->sent_messages == NULL) { - pqueue_free(d1->buffered_messages); - pqueue_free(d1->sent_messages); - OPENSSL_free(d1); - ssl3_free(ssl); - return 0; - } + d1->hello_verify_request = SSL_HVR_NONE; s->d1 = d1; @@ -100,15 +116,17 @@ int dtls1_new(SSL *ssl) static void dtls1_clear_queues(SSL_CONNECTION *s) { dtls1_clear_received_buffer(s); - dtls1_clear_sent_buffer(s); + dtls1_clear_sent_buffer(s, 0); + ossl_list_record_number_elem_free(&s->d1->ack_rec_num); } void dtls1_clear_received_buffer(SSL_CONNECTION *s) { pitem *item = NULL; hm_fragment *frag = NULL; + pqueue *rcvd_messages = &s->d1->rcvd_messages; - while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { + while ((item = pqueue_pop(rcvd_messages)) != NULL) { frag = (hm_fragment *)item->data; dtls1_hm_fragment_free(frag); pitem_free(item); @@ -116,58 +134,193 @@ void dtls1_clear_received_buffer(SSL_CONNECTION *s) s->d1->has_change_cipher_spec = 0; } -void dtls1_clear_sent_buffer(SSL_CONNECTION *s) +void ossl_list_record_number_elem_free(OSSL_LIST(record_number) * p_list) +{ + DTLS1_RECORD_NUMBER *p_elem; + DTLS1_RECORD_NUMBER *p_elem_next = NULL; + + if (p_list != NULL) + p_elem_next = ossl_list_record_number_head(p_list); + + while ((p_elem = p_elem_next) != NULL) { + p_elem_next = ossl_list_record_number_next(p_elem_next); + ossl_list_record_number_remove(p_list, p_elem); + OPENSSL_free(p_elem); + } +} + +DTLS1_RECORD_NUMBER *dtls1_record_number_new(uint64_t epoch, uint64_t seqnum) +{ + DTLS1_RECORD_NUMBER *recnum = OPENSSL_zalloc(sizeof(*recnum)); + + if (recnum != NULL) { + recnum->epoch = epoch; + recnum->seqnum = seqnum; + } + + return recnum; +} + +void dtls1_acknowledge_sent_buffer(SSL_CONNECTION *s, uint64_t before_epoch) { pitem *item = NULL; - hm_fragment *frag = NULL; + piterator iter = pqueue_iterator(&s->d1->sent_messages); - while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { - frag = (hm_fragment *)item->data; + while ((item = pqueue_next(&iter)) != NULL) { + dtls_sent_msg *sent_msg = (dtls_sent_msg *)item->data; + DTLS1_RECORD_NUMBER *recnum; + DTLS1_RECORD_NUMBER *recnum_next = ossl_list_record_number_head(&sent_msg->rec_nums); + + while ((recnum = recnum_next) != NULL) { + recnum_next = ossl_list_record_number_next(recnum_next); + + if (recnum->epoch < before_epoch) { + ossl_list_record_number_remove(&sent_msg->rec_nums, recnum); + OPENSSL_free(recnum); + } + } + } +} - if (frag->msg_header.is_ccs - && frag->msg_header.saved_retransmit_state.wrlmethod != NULL - && s->rlayer.wrl != frag->msg_header.saved_retransmit_state.wrl) { +void dtls1_clear_sent_buffer(SSL_CONNECTION *s, int keep_unacked_msgs) +{ + pitem *item = NULL; + pqueue *remaining_sent_messages = pqueue_new(); + pqueue *sent_messages = &s->d1->sent_messages; + + while ((item = pqueue_pop(sent_messages)) != NULL) { + dtls_sent_msg *sent_msg = (dtls_sent_msg *)item->data; + unsigned char msg_type = sent_msg->msg_info.msg_type; + unsigned char record_type = sent_msg->msg_info.record_type; + + if (SSL_CONNECTION_IS_DTLS13(s) + && !ossl_list_record_number_is_empty(&sent_msg->rec_nums) + && keep_unacked_msgs) { + pqueue_insert(remaining_sent_messages, item); + continue; + } + + if (((!SSL_CONNECTION_IS_DTLS13(s) && record_type == SSL3_RT_CHANGE_CIPHER_SPEC) + || (SSL_CONNECTION_IS_DTLS13(s) + && (msg_type == SSL3_MT_FINISHED + || msg_type == SSL3_MT_SERVER_HELLO + || msg_type == SSL3_MT_KEY_UPDATE))) + && sent_msg->saved_retransmit_state.wrlmethod != NULL + && s->rlayer.wrl != sent_msg->saved_retransmit_state.wrl) { /* * If we're freeing the CCS then we're done with the old wrl and it * can bee freed */ - frag->msg_header.saved_retransmit_state.wrlmethod->free(frag->msg_header.saved_retransmit_state.wrl); + sent_msg->saved_retransmit_state.wrlmethod->free(sent_msg->saved_retransmit_state.wrl); } - dtls1_hm_fragment_free(frag); + dtls1_sent_msg_free(sent_msg); pitem_free(item); } + + if (SSL_CONNECTION_IS_DTLS13(s)) + while ((item = pqueue_pop(remaining_sent_messages)) != NULL) + pqueue_insert(&s->d1->sent_messages, item); + + pqueue_free(remaining_sent_messages); +} + +/* + * Before RECORD_LAYER_clear() frees s->rlayer.wrl, null out any + * saved_retransmit_state.wrl pointers in the sent_messages queue that + * reference it. This transfers ownership of that free exclusively to + * RECORD_LAYER_clear and prevents dtls1_clear_sent_buffer from freeing + * the same pointer a second time. Entries with a different (older) wrl + * pointer are left untouched and will be freed correctly later. + */ +void dtls1_clear_current_wrl_from_sent_buffer(SSL_CONNECTION *s) +{ + pitem *item; + piterator iter = pqueue_iterator(&s->d1->sent_messages); + + while ((item = pqueue_next(&iter)) != NULL) { + dtls_sent_msg *sent_msg = (dtls_sent_msg *)item->data; + + if (sent_msg->saved_retransmit_state.wrl == s->rlayer.wrl) { + sent_msg->saved_retransmit_state.wrl = NULL; + sent_msg->saved_retransmit_state.wrlmethod = NULL; + } + } +} + +int dtls_any_sent_messages_are_missing_acknowledge(SSL_CONNECTION *s) +{ + pitem *item; + piterator iter = pqueue_iterator(&s->d1->sent_messages); + + while ((item = pqueue_next(&iter)) != NULL) { + dtls_sent_msg *msg = (dtls_sent_msg *)item->data; + + if (!ossl_list_record_number_is_empty(&msg->rec_nums)) + return 1; + } + + return 0; } void dtls1_free(SSL *ssl) { - SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + SSL_CONNECTION *s; + +#ifndef OPENSSL_NO_DTLS + if (IS_DTLS_LISTENER(ssl)) { + ossl_dtls_listener_free(ssl); + return; + } +#endif + + s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); if (s == NULL) return; - if (s->d1 != NULL) { +#ifndef OPENSSL_NO_DTLS + /* + * If this connection was created by a listener, unregister it from the + * listener's established_conns lookup table to prevent use-after-free. + * The listener routes incoming packets to connections via this table, + * so we must remove ourselves before freeing. + */ + if (s->d1 != NULL && s->d1->listener != NULL) + ossl_dtls_listener_unregister_established_conn(s->d1->listener, + &s->d1->peer_addr); +#endif + + if (s->d1 != NULL) dtls1_clear_queues(s); - pqueue_free(s->d1->buffered_messages); - pqueue_free(s->d1->sent_messages); + +#ifndef OPENSSL_NO_DTLS + if (s->d1 != NULL) { + ossl_dtls_rx_free(s->d1->rx); + + if (s->d1->listener != NULL) + SSL_free(s->d1->listener); } +#endif DTLS_RECORD_LAYER_free(&s->rlayer); - ssl3_free(ssl); - OPENSSL_free(s->d1); s->d1 = NULL; } int dtls1_clear(SSL *ssl) { - pqueue *buffered_messages; - pqueue *sent_messages; size_t mtu; size_t link_mtu; + SSL_CONNECTION *s; - SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); +#ifndef OPENSSL_NO_DTLS + if (IS_DTLS_LISTENER(ssl)) + return 1; +#endif + + s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); if (s == NULL) return 0; @@ -176,9 +329,18 @@ int dtls1_clear(SSL *ssl) if (s->d1) { DTLS_timer_cb timer_cb = s->d1->timer_cb; +#ifndef OPENSSL_NO_SOCK + BIO_ADDR peer_addr = s->d1->peer_addr; +#endif +#ifndef OPENSSL_NO_DTLS + DTLS_RX *rx = s->d1->rx; + SSL *listener = s->d1->listener; + OSSL_TIME created_at = s->d1->created_at; + unsigned int req_blocking_mode = s->d1->req_blocking_mode; + unsigned int force_nonblocking = s->d1->force_nonblocking; + unsigned int being_driven = s->d1->being_driven; +#endif - buffered_messages = s->d1->buffered_messages; - sent_messages = s->d1->sent_messages; mtu = s->d1->mtu; link_mtu = s->d1->link_mtu; @@ -189,13 +351,44 @@ int dtls1_clear(SSL *ssl) /* Restore the timer callback from previous state */ s->d1->timer_cb = timer_cb; +#ifndef OPENSSL_NO_SOCK + /* + * Restore peer address, DTLS_RX, listener, and created_at for + * listener-created connections. These are set via + * SSL_set1_initial_peer_addr(), ossl_dtls_rx_new(), and + * dtls_listener_create_conn_ssl() before the handshake starts, + * and must be preserved across SSL_clear(). + */ + s->d1->peer_addr = peer_addr; +#endif +#ifndef OPENSSL_NO_DTLS + s->d1->rx = rx; + s->d1->listener = listener; + /* + * The blocking mode is a property of the connection as the application + * configured it, not of the handshake, so it survives a clear. + */ + s->d1->req_blocking_mode = req_blocking_mode; + /* + * SSL_clear() can be called from inside the very SSL_accept() the + * listener is driving, so losing this would let the connection block + * there and stall the listener. + */ + s->d1->force_nonblocking = force_nonblocking; + /* + * being_driven says the listener is driving this connection's + * handshake, and is what keeps a concurrent tick from collecting it a + * second time. Losing it would let two threads into the state machine + * for one connection. + */ + s->d1->being_driven = being_driven; + s->d1->created_at = created_at; +#endif + if (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU) { s->d1->mtu = mtu; s->d1->link_mtu = link_mtu; } - - s->d1->buffered_messages = buffered_messages; - s->d1->sent_messages = sent_messages; } if (!ssl3_clear(ssl)) @@ -217,7 +410,12 @@ long dtls1_ctrl(SSL *ssl, int cmd, long larg, void *parg) { int ret = 0; OSSL_TIME t; - SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + SSL_CONNECTION *s; + + if (IS_DTLS_LISTENER(ssl)) + return 0; + + s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); if (s == NULL) return 0; @@ -269,7 +467,7 @@ void dtls1_start_timer(SSL_CONNECTION *s) #ifndef OPENSSL_NO_SCTP /* Disable timer for SCTP */ - if (BIO_dgram_is_sctp(SSL_get_wbio(ssl))) { + if (SSL_get_wbio(ssl) != NULL && BIO_dgram_is_sctp(SSL_get_wbio(ssl))) { s->d1->next_timeout = ossl_time_zero(); return; } @@ -347,7 +545,7 @@ void dtls1_stop_timer(SSL_CONNECTION *s) s->d1->timeout_duration_us = 1000000; dtls1_bio_set_next_timeout(s->rbio, s->d1); /* Clear retransmission buffer */ - dtls1_clear_sent_buffer(s); + dtls1_clear_sent_buffer(s, 0); } int dtls1_check_timeout_num(SSL_CONNECTION *s) @@ -388,13 +586,20 @@ int dtls1_handle_timeout(SSL_CONNECTION *s) dtls1_double_timeout(s); if (dtls1_check_timeout_num(s) < 0) { - /* SSLfatal() already called */ + /* + * SSLfatal() already called, so the connection is finished. Stop the + * timer rather than returning with next_timeout left in the past: + * nothing will re-arm or clear it from here, so DTLSv1_get_timeout() + * would report "due now" for ever and spin any caller which waits on + * it. + */ + dtls1_stop_timer(s); return -1; } dtls1_start_timer(s); /* Calls SSLfatal() if required */ - return dtls1_retransmit_buffered_messages(s); + return dtls1_retransmit_sent_messages(s); } #define LISTEN_SUCCESS 2 @@ -409,6 +614,7 @@ int DTLSv1_listen(SSL *ssl, BIO_ADDR *client) const unsigned char *data; unsigned char *buf = NULL, *wbuf; size_t fragoff, fraglen, msglen; + uint64_t record_sequence = 0; unsigned int rectype, versmajor, versminor, msgseq, msgtype, clientvers, cookielen; BIO *rbio, *wbio; BIO_ADDR *tmpclient = NULL; @@ -449,6 +655,40 @@ int DTLSv1_listen(SSL *ssl, BIO_ADDR *client) return -1; } + /* + * DTLSv1_listen() only supports the legacy HelloVerifyRequest mechanism + * which is not used in DTLS 1.3. For DTLS 1.3, use the SSL_new_listener() + * API instead which supports HelloRetryRequest with cookies. + * + * If the SSL object is configured for DTLS 1.3 only (both min and max + * are set to DTLS 1.3), we must fail since there's no room to downgrade. + * Otherwise, if max allows DTLS 1.3, we clamp it down to DTLS 1.2 so + * that the handshake will use HelloVerifyRequest. + */ + if (SSL_CONNECTION_IS_DTLS(s)) { + int min_version = s->min_proto_version; + int max_version = s->max_proto_version; + + /* + * Check if configured for DTLS 1.3 only - this is not supported. + * min_proto_version of 0 means "use default" which includes older versions, + * so only fail if min is explicitly set to DTLS 1.3. + */ + if (min_version == DTLS1_3_VERSION + && (max_version == 0 || max_version == DTLS1_3_VERSION)) { + ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_SSL_VERSION); + return -1; + } + + /* max_proto_version of 0 means "use default" which could include 1.3 */ + if (max_version == 0 || DTLS_VERSION_GE(max_version, DTLS1_3_VERSION)) { + if (!SSL_set_max_proto_version(ssl, DTLS1_2_VERSION)) { + ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_SSL_VERSION); + return -1; + } + } + } + buf = OPENSSL_malloc(DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_PLAIN_LENGTH); if (buf == NULL) return -1; @@ -535,6 +775,12 @@ int DTLSv1_listen(SSL *ssl, BIO_ADDR *client) ERR_raise(ERR_LIB_SSL, SSL_R_UNEXPECTED_MESSAGE); goto end; } + record_sequence = ((uint64_t)seq[2]) << 40; + record_sequence |= ((uint64_t)seq[3]) << 32; + record_sequence |= ((uint64_t)seq[4]) << 24; + record_sequence |= ((uint64_t)seq[5]) << 16; + record_sequence |= ((uint64_t)seq[6]) << 8; + record_sequence |= ((uint64_t)seq[7]); /* Get a pointer to the raw message for the later callback */ data = PACKET_data(&msgpkt); @@ -789,7 +1035,13 @@ int DTLSv1_listen(SSL *ssl, BIO_ADDR *client) s->d1->handshake_read_seq = 1; s->d1->handshake_write_seq = 1; s->d1->next_handshake_write_seq = 1; - s->rlayer.wrlmethod->increment_sequence_ctr(s->rlayer.wrl); + if (s->rlayer.wrlmethod->set_sequence == NULL + || !s->rlayer.wrlmethod->set_sequence(s->rlayer.wrl, + record_sequence)) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + ret = -1; + goto end; + } /* * We are doing cookie exchange, so make sure we set that option in the @@ -820,12 +1072,11 @@ int DTLSv1_listen(SSL *ssl, BIO_ADDR *client) * Reset the record layer - but this time we can use the record we just * buffered in s->rlayer.rrlnext */ - if (!ssl_set_new_record_layer(s, - DTLS_ANY_VERSION, + if (!ssl_set_new_record_layer(s, DTLS_ANY_VERSION, OSSL_RECORD_DIRECTION_READ, OSSL_RECORD_PROTECTION_LEVEL_NONE, NULL, 0, - NULL, 0, NULL, 0, NULL, 0, NULL, 0, - NID_undef, NULL, NULL, NULL)) { + NULL, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, + 0, NID_undef, NULL, NULL, NULL)) { /* SSLfatal already called */ ret = -1; goto end; @@ -912,7 +1163,7 @@ size_t dtls1_min_mtu(SSL_CONNECTION *s) size_t DTLS_get_data_mtu(const SSL *ssl) { - size_t mac_overhead, int_overhead, blocksize, ext_overhead; + size_t mac_overhead, int_overhead, blocksize, ext_overhead, rechdrlen = 0; const SSL_CIPHER *ciph = SSL_get_current_cipher(ssl); size_t mtu; const SSL_CONNECTION *s = SSL_CONNECTION_FROM_CONST_SSL_ONLY(ssl); @@ -925,8 +1176,8 @@ size_t DTLS_get_data_mtu(const SSL *ssl) if (ciph == NULL) return 0; - if (!ssl_cipher_get_overhead(ciph, &mac_overhead, &int_overhead, - &blocksize, &ext_overhead)) + if (!ssl_cipher_get_overhead(ciph, SSL_version(ssl), &mac_overhead, + &int_overhead, &blocksize, &ext_overhead)) return 0; if (SSL_READ_ETM(s)) @@ -934,10 +1185,36 @@ size_t DTLS_get_data_mtu(const SSL *ssl) else int_overhead += mac_overhead; + if (SSL_version(ssl) == DTLS1_3_VERSION) { + switch (SSL_get_state(ssl)) { + case TLS_ST_BEFORE: + case DTLS_ST_CR_HELLO_VERIFY_REQUEST: + case TLS_ST_CR_SRVR_HELLO: + case TLS_ST_CW_CLNT_HELLO: + case TLS_ST_CW_COMP_CERT: + case TLS_ST_CW_KEY_EXCH: + case TLS_ST_SW_HELLO_REQ: + case TLS_ST_SR_CLNT_HELLO: + case DTLS_ST_SW_HELLO_VERIFY_REQUEST: + case TLS_ST_SW_SRVR_HELLO: + case TLS_ST_CR_HELLO_REQ: + rechdrlen = DTLS1_RT_HEADER_LENGTH; + break; + default: + rechdrlen = DTLS13_UNI_HDR_FIXED_LENGTH; + break; + } + + /* Added record type at the end of the data */ + int_overhead++; + } else { + rechdrlen = DTLS1_RT_HEADER_LENGTH; + } + /* Subtract external overhead (e.g. IV/nonce, separate MAC) */ - if (ext_overhead + DTLS1_RT_HEADER_LENGTH >= mtu) + if (ext_overhead + rechdrlen >= mtu) return 0; - mtu -= ext_overhead + DTLS1_RT_HEADER_LENGTH; + mtu -= ext_overhead + rechdrlen; /* Round encrypted payload down to cipher block size (for CBC etc.) * No check for overflow since 'mtu % blocksize' cannot exceed mtu. */ @@ -961,3 +1238,2181 @@ void DTLS_set_timer_cb(SSL *ssl, DTLS_timer_cb cb) s->d1->timer_cb = cb; } + +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) +/* + * dtls_listener_connection_free - free an SSL connection owned by the listener. + * + * This function is used to free SSL connections that are in the listener's + * pending_conns or incoming_connections queues. These connections are owned + * by the listener, NOT by the application. + * + * Connections in pending_conns and incoming_connections do NOT hold a reference + * to the listener, even though sc->d1->listener points to it. This is intentional: + * if these connections held a reference to the listener, the listener's reference + * count would never reach zero, and ossl_dtls_listener_free() would never be + * called to clean up the pending/incoming connections - creating a circular + * dependency. + * + * Only when a connection is returned to the application via SSL_accept_connection() + * does it take a reference on the listener. At that point, ownership transfers + * to the application, and the normal SSL_free() path is used. + * + * The assert on ssl->references == 1 ensures that nobody else has taken a + * reference to this connection while it was in the listener's queues. If + * this assert fires, something has gone wrong with ownership tracking. + */ +static void dtls_listener_connection_free(SSL *ssl) +{ + SSL_CONNECTION *sc; + + if (ssl == NULL) + return; + + sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc != NULL && sc->d1 != NULL) { + /* + * Clear listener reference to prevent dtls1_free() from calling + * SSL_free() on the listener. The connection does not own the listener + * and SSL_free must not free the listener + */ + sc->d1->listener = NULL; + } + SSL_free(ssl); +} + +/* + * dtls_listener_create_conn_ssl - create an SSL object for a new connection. + * + * Creates and initializes an SSL object for handling a new incoming + * connection. Sets up the DTLS_RX for URXE-based packet injection, with + * the write BIO connected to the listener's network BIO. + * + * Returns: new SSL object on success, NULL on failure + */ +static SSL *dtls_listener_create_conn_ssl(DTLS_LISTENER *dl, + const BIO_ADDR *peer) +{ + SSL *ssl = NULL; + SSL_CONNECTION *sc = NULL; + BIO *wbio = NULL; + + ssl = SSL_new(dl->ssl.ctx); + if (ssl == NULL) + goto err; + + sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + if (sc == NULL || sc->d1 == NULL) + goto err; + + SSL_set_accept_state(ssl); + + /* + * Create DTLS_RX for this connection. The demux is owned by the listener + * and will outlive this connection. DTLS_RX manages the URXE queue for + * incoming packets. + */ + sc->d1->rx = ossl_dtls_rx_new(dl->demux); + if (sc->d1->rx == NULL) + goto err; + + /* + * Update the read record layer to use the URXE queue if it already exists. + * This is needed because the record layer may have been created before + * sc->d1->rx was set, similar to how SSL_set1_initial_peer_addr() updates + * the peer address on existing record layers. + */ + if (sc->rlayer.rrlmethod != NULL && sc->rlayer.rrl != NULL + && sc->rlayer.rrlmethod->set_use_urxe != NULL) + sc->rlayer.rrlmethod->set_use_urxe(sc->rlayer.rrl, 1); + + /* + * Store reference to parent listener. This allows the connection to + * trigger the listener's demux pump when reading data. + */ + sc->d1->listener = &dl->ssl; + + /* + * Record when this connection was created. This is used to detect and + * clean up stale pending connections that haven't completed their + * handshake within the timeout period. + */ + sc->d1->created_at = dtls_listener_get_time_direct(dl); + + /* + * For writes, use the shared network wbio. The peer address is NOT set + * on the BIO itself (which would affect all connections sharing this BIO). + * Instead, the peer address will be passed to the record layer during + * SSL_do_handshake(), and the record layer will use BIO_sendmmsg() with + * the peer address for each write. + */ + wbio = dl->net_wbio; + + if (wbio == NULL) { + ERR_raise(ERR_LIB_SSL, SSL_R_BIO_NOT_SET); + goto err; + } + + if (!BIO_up_ref(wbio)) + goto err; + + SSL_set0_rbio(ssl, NULL); + SSL_set0_wbio(ssl, wbio); + wbio = NULL; /* ownership transferred */ + + /* + * Store the peer address in the SSL connection. This will be passed to + * the record layer when it is created during SSL_do_handshake(). + */ + if (!SSL_set1_initial_peer_addr(ssl, peer)) + goto err; + + /* + * Enable cookie exchange if required by listener flags. + * This tells the state machine to perform HVR (DTLS 1.2) or + * HRR with cookie (DTLS 1.3) validation. + */ + if (dl->require_hvr_cookie || dl->require_hrr_cookie) + SSL_set_options(ssl, SSL_OP_COOKIE_EXCHANGE); + + return ssl; + +err: + dtls_listener_connection_free(ssl); + return NULL; +} + +/* + * dtls_listener_signal_notifier - wake threads blocked on this listener. + * + * Readiness may be produced by the thread which pumps the demux while a + * different thread is blocked in poll() on the network socket. That socket + * will not necessarily become readable again from the blocked thread's point + * of view, so the notifier is used to wake it. + * + * The caller must hold dl->mutex. + */ +static void dtls_listener_signal_notifier(DTLS_LISTENER *dl) +{ + if (dl->have_notifier && dl->cur_blocking_waiters > 0 + && !dl->signalled_notifier) { + ossl_rio_notifier_signal(&dl->notifier); + dl->signalled_notifier = 1; + } +} + +/* + * dtls_listener_packet_handler - callback for handling incoming datagrams. + * + * This callback is invoked by the demux for each received datagram. It routes + * the URXE to the appropriate connection based on peer address, creating a + * new pending connection if necessary. + * + * The URXE ownership is transferred to the connection's DTLS_RX queue. + * If routing fails, the URXE is released back to the demux. + */ +static void dtls_listener_packet_handler(DGRAM_URXE *urxe, void *arg) +{ + DTLS_LISTENER *dl = arg; + SSL *conn_ssl = NULL; + SSL_CONNECTION *sc = NULL; + + ossl_crypto_mutex_lock(dl->mutex); + + /* Check established connections first */ + if (dl->established_conns != NULL) + conn_ssl = ossl_dgram_conn_lookup_find(dl->established_conns, urxe); + + /* Check pending connections */ + if (conn_ssl == NULL) + conn_ssl = ossl_dgram_conn_lookup_find(dl->pending_conns, urxe); + + /* Create new pending connection if needed */ + if (conn_ssl == NULL) { + /* + * Reject before allocating anything if we have reached the pending + * connection limit. The LHASH item count is O(1), and this check does + * not need a conn_ssl, so performing it first avoids creating and then + * immediately freeing a connection when we are at capacity. + */ + if (ossl_dgram_conn_lookup_num_items(dl->pending_conns) >= dl->max_pending_conns) + goto release; + + conn_ssl = dtls_listener_create_conn_ssl(dl, &urxe->peer); + if (conn_ssl == NULL) + goto release; + + /* + * Register the connection in pending_conns before running the + * application callback. This is to avoid a race condition where + * another thread grabs the lock and tries to register a connection + * for this address. + */ + if (!ossl_dgram_conn_lookup_register(dl->pending_conns, urxe, conn_ssl)) { + dtls_listener_connection_free(conn_ssl); + goto release; + } + + /* + * Give the application a chance to decorate or veto the new + * pending connection via SSL_CTX_set_new_pending_conn_cb(). + * + * A return value of 0 from the callback means "discard this + * connection". On a non-zero return there is nothing more to do here: + * we already registered the connection above. + */ + if (dl->ssl.ctx->new_pending_conn_cb != NULL) { + int keep; + + sc = SSL_CONNECTION_FROM_SSL_ONLY(conn_ssl); + if (sc == NULL || sc->d1 == NULL) { + ossl_dgram_conn_lookup_unregister(dl->pending_conns, &urxe->peer); + dtls_listener_connection_free(conn_ssl); + goto release; + } + + /* + * Mark the connection being_driven while the mutex is dropped for + * the callback. This keeps the tick loop away from this connection. + */ + sc->d1->being_driven = 1; + ossl_crypto_mutex_unlock(dl->mutex); + keep = dl->ssl.ctx->new_pending_conn_cb(dl->ssl.ctx, conn_ssl, + dl->ssl.ctx->new_pending_conn_arg); + ossl_crypto_mutex_lock(dl->mutex); + + if (!keep) { + /* + * The pending callback doesn't want this connection, so + * unregister and free it. While the mutex was dropped a + * concurrent handler may have found this same connection and + * injected datagrams into its RX queue; freeing releases them + * back to the demux via ossl_dtls_rx_free(), so nothing leaks. + * being_driven kept the tick away, so the connection still + * holds only its single reference and the free is safe. + */ + ossl_dgram_conn_lookup_unregister(dl->pending_conns, &urxe->peer); + dtls_listener_connection_free(conn_ssl); + goto release; + } + + sc->d1->being_driven = 0; + } + } + + sc = SSL_CONNECTION_FROM_SSL_ONLY(conn_ssl); + if (sc == NULL || sc->d1 == NULL || sc->d1->rx == NULL) + goto release; + + /* Inject packet into connection's URXE queue */ + ossl_dtls_rx_inject_urxe(sc->d1->rx, urxe); + + /* Signal notifier if needed */ + dtls_listener_signal_notifier(dl); + + ossl_crypto_mutex_unlock(dl->mutex); + return; + +release: + ossl_crypto_mutex_unlock(dl->mutex); + ossl_dgram_demux_release_urxe(dl->demux, urxe); +} + +/* + * DTLS Listener Internal Cookie Callbacks + * + * These callbacks are used internally by the DTLS listener to generate and + * verify cookies for address validation. They use HMAC-SHA256 with the + * SSL_CTX's cookie_hmac_key to create cookies that bind to the client's + * address. + * + * Cookie format: + * - 8 bytes: timestamp (seconds since epoch) + * - 32 bytes: HMAC-SHA256(timestamp || peer_address) + * + * Total cookie size: 40 bytes + */ +#define DTLS_LISTENER_COOKIE_TIMESTAMP_LEN 8 +#define DTLS_LISTENER_COOKIE_HMAC_LEN 32 +#define DTLS_LISTENER_COOKIE_LEN (DTLS_LISTENER_COOKIE_TIMESTAMP_LEN + DTLS_LISTENER_COOKIE_HMAC_LEN) + +/* Maximum age of a cookie in seconds (default: 60 seconds) */ +#define DTLS_LISTENER_COOKIE_MAX_AGE 60 + +/* + * dtls_listener_get_time - get current time from the listener + * + * Returns the current time using the listener's time callback if set, + * otherwise uses ossl_time_now(). + * + * If ssl is not associated with a listener, returns ossl_time_now(). + */ +static OSSL_TIME dtls_listener_get_time(SSL *ssl) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + DTLS_LISTENER *dl; + + if (sc == NULL || sc->d1 == NULL || sc->d1->listener == NULL) + return ossl_time_now(); + + dl = (DTLS_LISTENER *)sc->d1->listener; + + if (dl->now_cb == NULL) + return ossl_time_now(); + + return dl->now_cb(dl->now_cb_arg); +} + +/* + * dtls_listener_get_time_direct - get current time directly from listener + * + * Same as dtls_listener_get_time but takes the listener directly. + * Used during connection creation before listener reference is fully set up. + */ +static OSSL_TIME dtls_listener_get_time_direct(DTLS_LISTENER *dl) +{ + if (dl == NULL) + return ossl_time_now(); + + if (dl->now_cb == NULL) + return ossl_time_now(); + + return dl->now_cb(dl->now_cb_arg); +} + +/* + * dtls_listener_cookie_hmac - compute HMAC for cookie validation + * + * Computes HMAC-SHA256(timestamp || port || raw_address) using the + * context's cookie_hmac_key. + * + * Returns 1 on success, 0 on failure. + */ +static int dtls_listener_cookie_hmac(SSL *ssl, uint64_t timestamp, + unsigned char *hmac_out) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + SSL_CTX *ctx; + EVP_MAC_CTX *mctx = NULL; + OSSL_PARAM params[2]; + /* 8 (timestamp) + 2 (port) + max address size */ + unsigned char data[8 + sizeof(uint16_t) + 64]; + unsigned char addr_buf[64]; + size_t data_len = 0; + size_t addr_len = 0; + size_t hmac_len = DTLS_LISTENER_COOKIE_HMAC_LEN; + uint16_t port; + WPACKET pkt; + int ret = 0; + + if (sc == NULL || sc->d1 == NULL) + return 0; + + ctx = SSL_CONNECTION_GET_CTX(sc); + if (ctx == NULL) + return 0; + + /* Get port and raw address */ + port = BIO_ADDR_rawport(&sc->d1->peer_addr); + + if (!BIO_ADDR_rawaddress(&sc->d1->peer_addr, addr_buf, &addr_len)) + return 0; + + /* Build data to HMAC: timestamp || port || raw_address */ + if (!WPACKET_init_static_len(&pkt, data, sizeof(data), 0) + || !WPACKET_put_bytes_u64(&pkt, timestamp) + || !WPACKET_put_bytes_u16(&pkt, port) + || !WPACKET_memcpy(&pkt, addr_buf, addr_len) + || !WPACKET_get_total_written(&pkt, &data_len) + || !WPACKET_finish(&pkt)) { + WPACKET_cleanup(&pkt); + return 0; + } + + mctx = EVP_MAC_CTX_new(ctx->hmac); + if (mctx == NULL) + goto err; + + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST, + "SHA2-256", 0); + params[1] = OSSL_PARAM_construct_end(); + + if (!EVP_MAC_init(mctx, ctx->ext.cookie_hmac_key, + sizeof(ctx->ext.cookie_hmac_key), params)) + goto err; + + if (!EVP_MAC_update(mctx, data, data_len)) + goto err; + + if (!EVP_MAC_final(mctx, hmac_out, &hmac_len, hmac_len)) + goto err; + + ret = 1; + +err: + EVP_MAC_CTX_free(mctx); + return ret; +} + +/* + * ossl_dtls_listener_gen_cookie_cb - internal HVR cookie generate callback + * + * Generates a cookie for HelloVerifyRequest (DTLS 1.2). + * Cookie format: timestamp (8 bytes) || HMAC (32 bytes) + */ +int ossl_dtls_listener_gen_cookie_cb(SSL *ssl, unsigned char *cookie, + unsigned int *cookie_len) +{ + uint64_t now = ossl_time2seconds(dtls_listener_get_time(ssl)); + + /* Write timestamp */ + cookie[0] = (unsigned char)(now >> 56); + cookie[1] = (unsigned char)(now >> 48); + cookie[2] = (unsigned char)(now >> 40); + cookie[3] = (unsigned char)(now >> 32); + cookie[4] = (unsigned char)(now >> 24); + cookie[5] = (unsigned char)(now >> 16); + cookie[6] = (unsigned char)(now >> 8); + cookie[7] = (unsigned char)(now); + + /* Compute and append HMAC */ + if (!dtls_listener_cookie_hmac(ssl, now, cookie + DTLS_LISTENER_COOKIE_TIMESTAMP_LEN)) + return 0; + + *cookie_len = DTLS_LISTENER_COOKIE_LEN; + return 1; +} + +/* + * ossl_dtls_listener_verify_cookie_cb - internal HVR cookie verify callback + * + * Verifies a cookie from ClientHello (DTLS 1.2). + * Checks that: + * 1. Cookie length is correct + * 2. Timestamp is not too old + * 3. HMAC matches + */ +int ossl_dtls_listener_verify_cookie_cb(SSL *ssl, const unsigned char *cookie, + unsigned int cookie_len) +{ + uint64_t cookie_time, now; + unsigned char expected_hmac[DTLS_LISTENER_COOKIE_HMAC_LEN]; + + if (cookie_len != DTLS_LISTENER_COOKIE_LEN) + return 0; + + /* Extract timestamp from cookie */ + cookie_time = ((uint64_t)cookie[0] << 56) + | ((uint64_t)cookie[1] << 48) + | ((uint64_t)cookie[2] << 40) + | ((uint64_t)cookie[3] << 32) + | ((uint64_t)cookie[4] << 24) + | ((uint64_t)cookie[5] << 16) + | ((uint64_t)cookie[6] << 8) + | ((uint64_t)cookie[7]); + + /* Check timestamp is not too old */ + now = ossl_time2seconds(dtls_listener_get_time(ssl)); + if (now > cookie_time && (now - cookie_time) > DTLS_LISTENER_COOKIE_MAX_AGE) + return 0; + + /* Compute expected HMAC and compare */ + if (!dtls_listener_cookie_hmac(ssl, cookie_time, expected_hmac)) + return 0; + + if (CRYPTO_memcmp(cookie + DTLS_LISTENER_COOKIE_TIMESTAMP_LEN, + expected_hmac, DTLS_LISTENER_COOKIE_HMAC_LEN) + != 0) + return 0; + + return 1; +} + +/* + * ossl_dtls_listener_gen_stateless_cookie_cb - internal HRR cookie generate callback + * + * Generates a cookie for HelloRetryRequest (DTLS 1.3). + * Uses the same format as the HVR cookie. + */ +int ossl_dtls_listener_gen_stateless_cookie_cb(SSL *ssl, unsigned char *cookie, + size_t *cookie_len) +{ + uint64_t now = ossl_time2seconds(dtls_listener_get_time(ssl)); + + /* Write timestamp */ + cookie[0] = (unsigned char)(now >> 56); + cookie[1] = (unsigned char)(now >> 48); + cookie[2] = (unsigned char)(now >> 40); + cookie[3] = (unsigned char)(now >> 32); + cookie[4] = (unsigned char)(now >> 24); + cookie[5] = (unsigned char)(now >> 16); + cookie[6] = (unsigned char)(now >> 8); + cookie[7] = (unsigned char)(now); + + /* Compute and append HMAC */ + if (!dtls_listener_cookie_hmac(ssl, now, cookie + DTLS_LISTENER_COOKIE_TIMESTAMP_LEN)) + return 0; + + *cookie_len = DTLS_LISTENER_COOKIE_LEN; + return 1; +} + +/* + * ossl_dtls_listener_verify_stateless_cookie_cb - internal HRR cookie verify callback + * + * Verifies a cookie from ClientHello (DTLS 1.3). + * Uses the same verification logic as the HVR cookie. + */ +int ossl_dtls_listener_verify_stateless_cookie_cb(SSL *ssl, + const unsigned char *cookie, + size_t cookie_len) +{ + uint64_t cookie_time, now; + unsigned char expected_hmac[DTLS_LISTENER_COOKIE_HMAC_LEN]; + + if (cookie_len != DTLS_LISTENER_COOKIE_LEN) + return 0; + + /* Extract timestamp from cookie */ + cookie_time = ((uint64_t)cookie[0] << 56) + | ((uint64_t)cookie[1] << 48) + | ((uint64_t)cookie[2] << 40) + | ((uint64_t)cookie[3] << 32) + | ((uint64_t)cookie[4] << 24) + | ((uint64_t)cookie[5] << 16) + | ((uint64_t)cookie[6] << 8) + | ((uint64_t)cookie[7]); + + /* Check timestamp is not too old */ + now = ossl_time2seconds(dtls_listener_get_time(ssl)); + if (now > cookie_time && (now - cookie_time) > DTLS_LISTENER_COOKIE_MAX_AGE) + return 0; + + /* Compute expected HMAC and compare */ + if (!dtls_listener_cookie_hmac(ssl, cookie_time, expected_hmac)) + return 0; + + if (CRYPTO_memcmp(cookie + DTLS_LISTENER_COOKIE_TIMESTAMP_LEN, + expected_hmac, DTLS_LISTENER_COOKIE_HMAC_LEN) + != 0) + return 0; + + return 1; +} + +SSL *ossl_dtls_new_listener(SSL_CTX *ctx, uint64_t flags) +{ + DTLS_LISTENER *dl = NULL; + int ssl_init_done = 0; + + if (ctx == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if ((dl = OPENSSL_zalloc(sizeof(*dl))) == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + goto err; + } + + /* + * Use ossl_ssl_init to initialize the SSL object header consistently + * with other SSL object types. + */ + if (!ossl_ssl_init(&dl->ssl, ctx, ctx->method, SSL_TYPE_DTLS_LISTENER)) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + goto err; + } + ssl_init_done = 1; + + dl->mutex = ossl_crypto_mutex_new(); +#ifdef OPENSSL_THREADS + if (dl->mutex == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + goto err; + } +#endif + + /* Create demux with internal locking for thread safety. */ + dl->demux = ossl_dgram_demux_new(NULL, 1, NULL, NULL); + if (dl->demux == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + goto err; + } + + /* Set up the packet handler callback for routing datagrams to connections */ + ossl_dgram_demux_set_default_handler(dl->demux, dtls_listener_packet_handler, dl); + + dl->incoming_connections = sk_SSL_new_null(); + if (dl->incoming_connections == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + goto err; + } + + dl->pending_conns = ossl_dgram_conn_lookup_new_addr(); + if (dl->pending_conns == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + goto err; + } + + dl->established_conns = ossl_dgram_conn_lookup_new_addr(); + if (dl->established_conns == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + goto err; + } + + dl->net_rbio = NULL; + dl->net_wbio = NULL; + tsan_store(&dl->listening, 0); + dl->fatal = 0; + + /* Default timeout for pending connections: 30 seconds */ + dl->pending_timeout = ossl_seconds2time(30); + + /* Default maximum pending connections */ + dl->max_pending_conns = DTLS_LISTENER_DEFAULT_MAX_PENDING_CONNS; + + /* + * The listener owns its receive-buffer size independent of any + * network BIO's send-path MTU. + */ + dl->max_dgram_size = DTLS_LISTENER_DEFAULT_MAX_DGRAM_SIZE; + ossl_dgram_demux_set_mtu(dl->demux, (unsigned int)dl->max_dgram_size); + + /* + * Address validation is performed by default: HelloVerifyRequest for + * DTLS 1.0/1.2 and a HelloRetryRequest cookie for DTLS 1.3. It can be + * requested explicitly with SSL_LISTENER_FLAG_ADDRESS_VALIDATION, or + * disabled with SSL_LISTENER_FLAG_NO_VALIDATE. If both are specified we + * fail safe and validate: SSL_LISTENER_FLAG_ADDRESS_VALIDATION wins. + */ + if ((flags & SSL_LISTENER_FLAG_NO_VALIDATE) == 0 + || (flags & SSL_LISTENER_FLAG_ADDRESS_VALIDATION) != 0) { + dl->require_hvr_cookie = 1; + dl->require_hrr_cookie = 1; + } + + dl->have_notifier = 0; + dl->signalled_notifier = 0; + dl->cur_blocking_waiters = 0; + + if ((flags & SSL_LISTENER_FLAG_SINGLE_THREAD) == 0) { + if (!ossl_rio_notifier_init(&dl->notifier)) + goto err; + + dl->notifier_cv = ossl_crypto_condvar_new(); + if (dl->notifier_cv == NULL) { + ossl_rio_notifier_cleanup(&dl->notifier); + goto err; + } + + dl->have_notifier = 1; + } + + return &dl->ssl; + +err: + if (dl == NULL) + return NULL; + + /* + * If ossl_ssl_init succeeded, SSL_free handles all cleanup + * including incoming_connections, notifier_cv, and OPENSSL_free(dl) + * itself via ossl_dtls_listener_free. Otherwise ossl_ssl_init + * did not run or partially failed, so we must free the raw + * allocation directly. + */ + if (ssl_init_done) + SSL_free(&dl->ssl); + else + OPENSSL_free(dl); + return NULL; +} + +/* + * Callback to free SSL objects in pending_conns hash table. + * The pending_conns hash table owns the SSL objects it contains, + * so we must free them before freeing the hash table itself. + */ +static void dtls_free_pending_ssl_cb(SSL *ssl, const BIO_ADDR *peer, void *arg) +{ + dtls_listener_connection_free(ssl); +} + +void ossl_dtls_listener_free(SSL *s) +{ + DTLS_LISTENER *dl; + + if (!IS_DTLS_LISTENER(s)) + return; + + dl = (DTLS_LISTENER *)s; + + /* Free any pending incoming connections */ + if (dl->incoming_connections != NULL) { + while (sk_SSL_num(dl->incoming_connections) > 0) { + SSL *conn = sk_SSL_pop(dl->incoming_connections); + + dtls_listener_connection_free(conn); + } + sk_SSL_free(dl->incoming_connections); + dl->incoming_connections = NULL; + } + + /* + * Free all pending connections in the hash table. + */ + if (dl->pending_conns != NULL) { + ossl_dgram_conn_lookup_foreach(dl->pending_conns, dtls_free_pending_ssl_cb, NULL); + ossl_dgram_conn_lookup_free(dl->pending_conns); + dl->pending_conns = NULL; + } + + /* Free all established connections in the hash table (no SSL ownership) */ + if (dl->established_conns != NULL) { + ossl_dgram_conn_lookup_free(dl->established_conns); + dl->established_conns = NULL; + } + + ossl_crypto_mutex_free(&dl->mutex); + + /* Free the demux after all connections that reference it are freed */ + if (dl->demux != NULL) + ossl_dgram_demux_free(dl->demux); + + BIO_free_all(dl->net_wbio); + BIO_free_all(dl->net_rbio); + + if (dl->have_notifier) { + ossl_crypto_condvar_free(&dl->notifier_cv); + ossl_rio_notifier_cleanup(&dl->notifier); + } +} + +SSL *ossl_dtls_get0_listener(const SSL *ssl) +{ + if (!IS_DTLS_LISTENER(ssl)) + return NULL; + + return (SSL *)ssl; +} + +/* + * ossl_dtls_listen - start a DTLS listener accepting incoming connections. + */ +int ossl_dtls_listen(SSL *ssl) +{ + DTLS_LISTENER *dl; + + if (!IS_DTLS_LISTENER(ssl)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + dl = (DTLS_LISTENER *)ssl; + + /* Already listening is not an error. */ + if (tsan_load(&dl->listening)) + return 1; + + tsan_store(&dl->listening, 1); + return 1; +} + +/* + * dtls_listener_conn_ready - check if connection is ready for accept queue. + * + * Determines whether the SSL object has completed cookie validation (if required) + * or has received a valid ClientHello (if no validation) and is ready to be + * moved to the incoming_connections queue. + * + * The connection is returned to the application BEFORE the handshake completes, + * allowing the application to finish the handshake itself. This provides more + * control over the handshake process. + * + * For HRR (DTLS 1.3 with validation): Ready when sc->ext.cookieok is set + * For HVR (DTLS 1.2 with validation): Ready when sc->d1->cookie_verified is set + * For no validation: Ready after receiving the first ClientHello + * + * Returns: 1 if ready, 0 if still in progress + */ +static int dtls_listener_conn_ready(SSL *ssl, DTLS_LISTENER *dl) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + + if (sc == NULL) + return 0; + + /* + * No validation required (SSL_LISTENER_FLAG_NO_VALIDATE): + * Ready immediately after receiving the first ClientHello. + * The connection exists in pending_conns, so it's ready. + */ + if (!dl->require_hrr_cookie && !dl->require_hvr_cookie) + return 1; + + /* + * For DTLS 1.3 with HRR requirement: + * Ready when the cookie has been validated (second ClientHello received + * with valid cookie after HRR was sent). The cookieok flag is set during + * ClientHello processing when the HRR cookie is successfully verified. + */ + if (dl->require_hrr_cookie && sc->ext.cookieok) + return 1; + + /* + * For DTLS 1.2 (and earlier) with HVR requirement: + * Ready when the cookie has been validated (second ClientHello received + * with valid cookie after HVR was sent). The cookie_verified flag is set + * during ClientHello processing when the HVR cookie is successfully verified. + */ + if (dl->require_hvr_cookie && sc->d1 != NULL && sc->d1->cookie_verified) + return 1; + + /* Not ready yet - still waiting for cookie validation */ + return 0; +} + +/* + * dtls_listener_conn_needs_retry - check if connection is waiting for more data. + * + * Determines whether the SSL object has sent an HRR/HVR and is waiting + * for the client's response. + * + * Returns: 1 if waiting for retry, 0 otherwise + */ +static int dtls_listener_conn_needs_retry(SSL *ssl) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + + if (sc == NULL) + return 0; + + /* + * For DTLS 1.3: HRR has been sent, waiting for second ClientHello + */ + if (sc->hello_retry_request == SSL_HRR_PENDING + && !ossl_statem_in_error(sc)) + return 1; + + /* + * For DTLS 1.2: Check if we're in a state that indicates HVR was sent. + * The state machine will be waiting for the next ClientHello. + */ + if (sc->statem.hand_state == DTLS_ST_SW_HELLO_VERIFY_REQUEST) + return 1; + + return 0; +} + +/* + * Context for drive_pending iteration. + */ +typedef struct { + DTLS_LISTENER *dl; + int ready_count; /* Connections ready to move to established */ + int error_count; /* Connections with fatal errors */ + STACK_OF(SSL) *to_drive; /* Connections to drive (collected in phase 1) */ + STACK_OF(SSL) *ready_conns; /* Connections to move */ + STACK_OF(SSL) *failed_conns; /* Connections to remove */ +} DRIVE_PENDING_CTX; + +/* + * Callback for collecting pending connections to drive. + * Called with dl->mutex held. Marks connections as being_driven and up-refs them. + * Also checks for timed-out connections and marks them as failed. + */ +static void collect_pending_cb(SSL *ssl, const BIO_ADDR *peer, void *arg) +{ + DRIVE_PENDING_CTX *ctx = arg; + DTLS_LISTENER *dl = ctx->dl; + SSL_CONNECTION *sc; + + sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + if (sc == NULL) + return; + + if (sc->d1 == NULL || sc->d1->rx == NULL) + return; + + /* + * Skip if already being driven by another thread. + */ + if (sc->d1->being_driven) + return; + + /* + * Check if this pending connection has exceeded the timeout. + * Stale connections that haven't completed their handshake are removed + * to prevent resource exhaustion from incomplete handshakes. + */ + if (!ossl_time_is_infinite(dl->pending_timeout)) { + OSSL_TIME now = dtls_listener_get_time_direct(dl); + OSSL_TIME age = ossl_time_subtract(now, sc->d1->created_at); + + if (ossl_time_compare(age, dl->pending_timeout) > 0) { + /* + * Connection has timed out - mark for removal + * + * Set being_driven so that a concurrent ossl_dtls_tick() running + * phase 1 hits the being_driven check above and skips this + * connection, instead of collecting it and freeing it a second + * time (double-free). + * + * No up-ref is needed: phase 1 runs under dl->mutex, so collection + * is serialized, and being_driven keeps any other tick away until + * our phase 3 frees this connection. The single pending-queue + * reference is released by dtls_listener_connection_free() in the + * failed_conns loop. + * + * We intentionally do not handle a failed push specially: if the + * push fails (allocation failure) the connection stays registered + * in pending_conns and is simply retried on the next tick. + */ + if (ctx->failed_conns != NULL && sk_SSL_push(ctx->failed_conns, ssl) > 0) { + sc->d1->being_driven = 1; + ctx->error_count++; + } + return; + } + } + + /* + * Up-ref and add to list first, then mark as being driven. + * The up-ref ensures the connection stays valid while we drive it + * without holding the mutex. + */ + if (!SSL_up_ref(ssl)) + return; + + if (sk_SSL_push(ctx->to_drive, ssl) <= 0) { + SSL_free(ssl); /* Release the ref we just took */ + return; + } + + sc->d1->being_driven = 1; +} + +/* + * Drive a single connection's handshake. + * Called WITHOUT holding dl->mutex so demux_pump can be called safely. + */ +static void drive_single_connection(SSL *ssl, DTLS_LISTENER *dl, + DRIVE_PENDING_CTX *ctx) +{ + SSL_CONNECTION *sc; + int ret, ssl_err; + + sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + if (sc == NULL) + return; + + /* + * Drive the state machine with SSL_accept(). + * + * We MUST set TLS1_FLAGS_STATELESS to prevent the state machine from + * calling SSL_clear() when entering the handshake. + * + * Without the flag, the state machine in state_machine() calls SSL_clear() + * when SSL_in_before() is true, which wipes out our restored state. + */ + if (dl->require_hrr_cookie || dl->require_hvr_cookie) + sc->s3.flags |= TLS1_FLAGS_STATELESS; + + /* + * We are inside the listener's own tick, so this must not block: nothing + * else can make progress while it does, including whatever it would be + * waiting for. + */ + sc->d1->force_nonblocking = 1; + ret = SSL_accept(ssl); + sc->d1->force_nonblocking = 0; + + /* + * Always clear the stateless flag after SSL_accept() completes. + */ + if (dl->require_hrr_cookie || dl->require_hvr_cookie) + sc->s3.flags &= ~TLS1_FLAGS_STATELESS; + + /* Check if connection is ready to move to established */ + if (dtls_listener_conn_ready(ssl, dl)) { + if (ctx->ready_conns != NULL && sk_SSL_push(ctx->ready_conns, ssl) > 0) + ctx->ready_count++; + return; + } + + /* Check if connection needs retry (HRR/HVR sent) */ + if (dtls_listener_conn_needs_retry(ssl)) + return; + + /* Check SSL error */ + ssl_err = SSL_get_error(ssl, ret); + + if (ssl_err == SSL_ERROR_WANT_READ || ssl_err == SSL_ERROR_WANT_WRITE) { + /* Handshake in progress, needs more data - keep pending */ + return; + } + + /* Fatal error on this connection - mark for removal */ + if (ssl_err == SSL_ERROR_SYSCALL || ssl_err == SSL_ERROR_SSL) { + if (ctx->failed_conns != NULL && sk_SSL_push(ctx->failed_conns, ssl) > 0) + ctx->error_count++; + } +} + +/* + * dtls_listener_drive_pending - drive handshakes for all pending connections. + * + * Uses a three-phase approach to minimize lock contention: + * Phase 1: LOCK - collect connections to drive, mark as being_driven, up-ref + * Phase 2: UNLOCK - drive each connection (can safely call demux_pump) + * Phase 3: LOCK - update data structures, clear being_driven, release refs + * + * This approach allows SSL_accept() to call demux_pump() without deadlock, + * since the mutex is not held during phase 2. + * + * Returns: + * 1 At least one connection was moved to incoming_connections + * 0 No connections completed (all still pending or failed) + * -1 Fatal error + */ +static int dtls_listener_drive_pending(DTLS_LISTENER *dl) +{ + DRIVE_PENDING_CTX ctx; + SSL *ssl; + SSL_CONNECTION *sc; + int i, result = 0; + + memset(&ctx, 0, sizeof(ctx)); + ctx.dl = dl; + ctx.to_drive = sk_SSL_new_null(); + ctx.ready_conns = sk_SSL_new_null(); + ctx.failed_conns = sk_SSL_new_null(); + + if (ctx.to_drive == NULL || ctx.ready_conns == NULL + || ctx.failed_conns == NULL) { + sk_SSL_free(ctx.to_drive); + sk_SSL_free(ctx.ready_conns); + sk_SSL_free(ctx.failed_conns); + return -1; + } + + /* + * Phase 1: Collect connections to drive. + * Hold mutex while iterating pending_conns, mark connections as being_driven, + * and up-ref them so they stay valid after we release the mutex. + */ + ossl_crypto_mutex_lock(dl->mutex); + ossl_dgram_conn_lookup_foreach(dl->pending_conns, collect_pending_cb, &ctx); + ossl_crypto_mutex_unlock(dl->mutex); + + /* + * Phase 2: Drive connections WITHOUT holding mutex. + * This allows SSL_accept() to call demux_pump() which may invoke + * packet_handler(), which needs to acquire the mutex. + */ + for (i = 0; i < sk_SSL_num(ctx.to_drive); i++) { + ssl = sk_SSL_value(ctx.to_drive, i); + drive_single_connection(ssl, dl, &ctx); + } + + /* + * Phase 3: Update data structures. + * Re-acquire mutex to move ready connections to established, + * remove failed connections, clear being_driven flags, and release refs. + */ + ossl_crypto_mutex_lock(dl->mutex); + + /* + * Since we have the mutex, clear the driven flag and release the + * up-ref for each connection. + */ + for (i = 0; i < sk_SSL_num(ctx.to_drive); i++) { + ssl = sk_SSL_value(ctx.to_drive, i); + sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + + if (sc != NULL && sc->d1 != NULL) + sc->d1->being_driven = 0; + + SSL_free(ssl); /* Release reference from phase 1 */ + } + + /* Move ready connections to established and incoming queue */ + for (i = 0; i < sk_SSL_num(ctx.ready_conns); i++) { + ssl = sk_SSL_value(ctx.ready_conns, i); + sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + + if (sc == NULL || sc->d1 == NULL) + continue; + + /* Get peer address from the connection */ + if (BIO_ADDR_family(&sc->d1->peer_addr) != AF_UNSPEC) { + + /* Remove from pending */ + ossl_dgram_conn_lookup_unregister(dl->pending_conns, &sc->d1->peer_addr); + + /* Add to established connections (inline, we already hold mutex) */ + if (dl->established_conns == NULL || !ossl_dgram_conn_lookup_register_addr(dl->established_conns, &sc->d1->peer_addr, ssl)) { + dtls_listener_connection_free(ssl); + continue; + } + + /* Add to incoming queue */ + if (sk_SSL_push(dl->incoming_connections, ssl) > 0) { + result = 1; + } else { + /* Failed to add to queue, unregister and free */ + ossl_dgram_conn_lookup_unregister(dl->established_conns, + &sc->d1->peer_addr); + dtls_listener_connection_free(ssl); + } + } + } + + /* + * A connection became acceptable. Any thread blocked waiting for one is + * polling the network socket, which will not necessarily become readable + * again on its behalf, so wake it explicitly. + */ + if (result) + dtls_listener_signal_notifier(dl); + + /* Remove failed connections (after releasing refs so ref count is 1) */ + for (i = 0; i < sk_SSL_num(ctx.failed_conns); i++) { + ssl = sk_SSL_value(ctx.failed_conns, i); + sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + + if (sc != NULL && sc->d1 != NULL) + ossl_dgram_conn_lookup_unregister(dl->pending_conns, &sc->d1->peer_addr); + + dtls_listener_connection_free(ssl); + } + + ossl_crypto_mutex_unlock(dl->mutex); + + sk_SSL_free(ctx.to_drive); + sk_SSL_free(ctx.ready_conns); + sk_SSL_free(ctx.failed_conns); + + return result; +} + +/* + * ossl_dtls_tick - drive one iteration of the DTLS listener I/O loop. + * + * Uses the demux pump/callback architecture for efficient packet handling: + * 1. Call ossl_dgram_demux_pump() to read datagrams from the network + * 2. The demux invokes dtls_listener_packet_handler() for each datagram + * 3. The handler routes URXEs to connections (established or pending) + * 4. Drive handshakes for pending connections + * 5. Move completed connections to established_conns and incoming queue + * + * Return values: + * 1 A verified connection was pushed onto dl->incoming_connections. + * 0 Exchange incomplete (HRR/HVR sent, or no data yet); call again. + * -1 Fatal error; dl->fatal is set. + */ +int ossl_dtls_tick(DTLS_LISTENER *dl) +{ + int pump_ret; + + if (dl == NULL || dl->net_rbio == NULL) + return 0; + + /* + * Get datagrams from the network and route them to connections. + */ + pump_ret = ossl_dgram_demux_pump(dl->demux); + + if (pump_ret == DGRAM_DEMUX_PUMP_RES_PERMANENT_FAIL) { + /* Fatal BIO or allocation error */ + ossl_crypto_mutex_lock(dl->mutex); + dl->fatal = 1; + ossl_crypto_mutex_unlock(dl->mutex); + return -1; + } + + /* + * Drive Handshakes for pending connections. + * call even if pump_ret indicates no data or temporary failure, + * to allow handshakes to progress even when no new data is arriving + */ + return dtls_listener_drive_pending(dl); +} + +SSL *ossl_dtls_accept_connection(SSL *ssl, uint64_t flags) +{ + DTLS_LISTENER *dl; + SSL *conn = NULL; + SSL_CONNECTION *sc = NULL; + int no_block = ((flags & SSL_ACCEPT_CONNECTION_NO_BLOCK) != 0); + + if (!IS_DTLS_LISTENER(ssl)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + return NULL; + } + + dl = (DTLS_LISTENER *)ssl; + + if (!ossl_dtls_listen(ssl)) + return NULL; + + /* If a previous tick produced a fatal BIO error, do not try again. */ + ossl_crypto_mutex_lock(dl->mutex); + if (dl->fatal) { + ossl_crypto_mutex_unlock(dl->mutex); + return NULL; + } + + /* Fast path: return any already-queued connection immediately. */ + conn = sk_SSL_shift(dl->incoming_connections); + ossl_crypto_mutex_unlock(dl->mutex); + if (conn != NULL) + goto end; + + /* + * Wait only if the caller has not asked us not to and the listener is in + * blocking mode. Note that the check for a network BIO below is deliberately + * left ahead of this, so that asking to wait on a listener which has none + * remains an error rather than silently returning nothing. + */ + if (!no_block && !ossl_dtls_blocking(ssl) && dl->net_rbio != NULL) + no_block = 1; + + if (no_block) { + /* + * Non-blocking: run one tick to drain any pending datagram, then + * return whatever is in the queue + */ + if (dl->net_rbio != NULL) { + if (ossl_dtls_tick(dl) < 0) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return NULL; + } + } + ossl_crypto_mutex_lock(dl->mutex); + conn = sk_SSL_shift(dl->incoming_connections); + ossl_crypto_mutex_unlock(dl->mutex); + goto end; + } + + /* Blocking path: we need a BIO to make any progress. */ + if (dl->net_rbio == NULL) { + ERR_raise(ERR_LIB_SSL, SSL_R_BIO_NOT_SET); + return NULL; + } + + /* + * Blocking path: tick to make whatever progress is possible now, and if + * that did not produce a connection, wait for readiness before ticking + * again. + * + * The wait is what stops this from being a busy loop. The network BIO is + * non-blocking, so a tick which finds no datagram returns immediately; + * without waiting in between, this loop would spin. + */ + for (;;) { + if (ossl_dtls_tick(dl) < 0) { + /* fatal BIO error */ + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + break; + } + + ossl_crypto_mutex_lock(dl->mutex); + conn = sk_SSL_shift(dl->incoming_connections); + ossl_crypto_mutex_unlock(dl->mutex); + if (conn != NULL) + break; + + /* + * Nothing yet, so wait for the listener to become ready before ticking + * again. What that amounts to is decided by the poll translation for a + * listener: the network socket becoming readable, or another thread + * signalling the notifier because it produced readiness on our behalf. + */ + if (!ossl_dtls_block_until_ready(ssl, SSL_POLL_EVENT_IC, + ossl_time_infinite(), /*bound_by_event_timeout=*/1)) + break; + } + +end: + if (conn != NULL) { + sc = SSL_CONNECTION_FROM_SSL(conn); + /* + * Take a reference on the listener now that ownership of the connection + * is transferring to the application. While in incoming_connections, + * the connection did not hold a reference to avoid circular dependencies. + * Now that the application owns the connection, it must hold a reference + * to ensure the listener stays alive - the connection needs the listener + * for packet routing + */ + if (sc == NULL || sc->d1 == NULL || sc->d1->listener == NULL + || !SSL_up_ref(sc->d1->listener)) { + /* + * Ownership did not transfer to the application. A connection taken + * from incoming_connections is still registered in established_conns; + */ + if (sc != NULL && sc->d1 != NULL) + ossl_dtls_listener_unregister_established_conn(ssl, &sc->d1->peer_addr); + dtls_listener_connection_free(conn); + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return NULL; + } + } + return conn; +} + +/* + * ossl_dtls_listener_set0_net_rbio - set the network read BIO for a listener. + * + * Thread safety: The caller must ensure that this function is not called + * concurrently with any other operations on the listener or its connections. + * This includes SSL_accept_connection(), SSL_poll(), SSL_tick(), and any + * I/O operations on connections created from this listener. + * + * The BIO must not be changed while other threads are actively using the + * listener. Typically, the BIO should be set once before calling SSL_listen() + * and not modified afterward. + */ +void ossl_dtls_listener_set0_net_rbio(SSL *s, BIO *bio) +{ + DTLS_LISTENER *dl; + BIO *old_rbio; + + if (!IS_DTLS_LISTENER(s)) + return; + + dl = (DTLS_LISTENER *)s; + + /* + * The listener demultiplexes one socket to many connections, so it can + * never afford to block inside a read: a read for one connection would + * stall every other, and the demux lock is held across it. Blocking + * behaviour is provided by waiting for readiness instead, so configure the + * BIO for non-blocking operation on the application's behalf, as QUIC does. + */ + if (bio != NULL) + BIO_set_nbio(bio, 1); /* best effort autoconfig */ + + ossl_crypto_mutex_lock(dl->mutex); + + /* + * The demux receive-buffer size is the listener's configured maximum + * datagram size, independent of the network BIO's path MTU. Size the demux + * to that value for whatever BIO is attached. + */ + ossl_dgram_demux_set_bio(dl->demux, bio); + ossl_dgram_demux_set_mtu(dl->demux, (unsigned int)dl->max_dgram_size); + + old_rbio = dl->net_rbio; + + /* No change - nothing to do */ + if (old_rbio == bio) { + ossl_crypto_mutex_unlock(dl->mutex); + return; + } + + dl->net_rbio = bio; + + ossl_crypto_mutex_unlock(dl->mutex); + + /* Free the old BIO now that we've taken ownership of the new one */ + BIO_free_all(old_rbio); +} + +/* + * update_conn_wbio - callback to update the wbio on a single connection. + * + * Used by ossl_dtls_listener_set0_net_wbio() to propagate wbio changes + * to all pending and established connections + */ +static void update_conn_wbio(SSL *ssl, const BIO_ADDR *peer, void *arg) +{ + BIO *new_wbio = arg; + + if (SSL_get_wbio(ssl) == new_wbio) + return; + + if (new_wbio != NULL && !BIO_up_ref(new_wbio)) + return; + + SSL_set0_wbio(ssl, new_wbio); +} + +/* + * ossl_dtls_listener_set0_net_wbio - set the network write BIO for a listener. + * + * Thread safety: The caller must ensure that this function is not called + * concurrently with any other operations on the listener or its connections. + * This includes SSL_accept_connection(), SSL_poll(), SSL_tick(), and any + * I/O operations on connections created from this listener. + * + * The BIO must not be changed while other threads are actively using the + * listener. Typically, the BIO should be set once before calling SSL_listen() + * and not modified afterward. + */ +void ossl_dtls_listener_set0_net_wbio(SSL *s, BIO *bio) +{ + DTLS_LISTENER *dl; + BIO *old_wbio; + + if (!IS_DTLS_LISTENER(s)) + return; + + dl = (DTLS_LISTENER *)s; + + /* See ossl_dtls_listener_set0_net_rbio() as to why. */ + if (bio != NULL) + BIO_set_nbio(bio, 1); /* best effort autoconfig */ + + old_wbio = dl->net_wbio; + + /* No change - nothing to do */ + if (old_wbio == bio) { + return; + } + + /* Update wbio in all pending connections */ + if (dl->pending_conns != NULL) + ossl_dgram_conn_lookup_foreach(dl->pending_conns, update_conn_wbio, bio); + + /* Update wbio in all established connections */ + if (dl->established_conns != NULL) + ossl_dgram_conn_lookup_foreach(dl->established_conns, update_conn_wbio, bio); + + dl->net_wbio = bio; + + /* Free the old BIO now that we've taken ownership of the new one */ + BIO_free_all(old_wbio); +} + +/* + * ossl_dtls_listener_get_net_rbio - get the network read BIO for a listener. + * + * Thread safety: The caller must ensure that the BIO is not being changed + * concurrently via SSL_set0_rbio(). The returned BIO pointer is only valid + * as long as no other thread modifies it. + */ +BIO *ossl_dtls_listener_get_net_rbio(const SSL *s) +{ + const DTLS_LISTENER *dl; + + if (!IS_DTLS_LISTENER(s)) + return NULL; + + dl = (const DTLS_LISTENER *)s; + + return dl->net_rbio; +} + +/* + * ossl_dtls_listener_get_net_wbio - get the network write BIO for a listener. + * + * Thread safety: The caller must ensure that the BIO is not being changed + * concurrently via SSL_set0_wbio(). The returned BIO pointer is only valid + * as long as no other thread modifies it. + */ +BIO *ossl_dtls_listener_get_net_wbio(const SSL *s) +{ + const DTLS_LISTENER *dl; + + if (!IS_DTLS_LISTENER(s)) + return NULL; + + dl = (const DTLS_LISTENER *)s; + + return dl->net_wbio; +} + +/* + * Established connections API - these handle their own locking. + * + * The established_conns lookup table is accessed from multiple threads: + * - Listener thread: looking up and registering connections + * - Connection thread: unregistering via SSL_free -> dtls1_free + */ + +/* + * ossl_dtls_listener_find_established_conn - find an established connection. + * + * Looks up a connection in the established_conns table by peer address. + * Returns the SSL connection if found, NULL otherwise. + */ +SSL *ossl_dtls_listener_find_established_conn(DTLS_LISTENER *dl, + const DGRAM_URXE *urxe) +{ + SSL *result = NULL; + + if (dl == NULL || urxe == NULL) + return NULL; + + ossl_crypto_mutex_lock(dl->mutex); + + if (dl->established_conns != NULL) + result = ossl_dgram_conn_lookup_find(dl->established_conns, urxe); + + ossl_crypto_mutex_unlock(dl->mutex); + return result; +} + +/* + * ossl_dtls_listener_unregister_established_conn - unregister an established + * connection from the listener. + * + * Called when a DTLS connection created by this listener is being freed. + */ +void ossl_dtls_listener_unregister_established_conn(SSL *s, const BIO_ADDR *peer_addr) +{ + DTLS_LISTENER *dl; + + if (!IS_DTLS_LISTENER(s)) + return; + + if (peer_addr == NULL || BIO_ADDR_family(peer_addr) == AF_UNSPEC) + return; + + dl = (DTLS_LISTENER *)s; + + ossl_crypto_mutex_lock(dl->mutex); + + if (dl->established_conns != NULL) + ossl_dgram_conn_lookup_unregister(dl->established_conns, peer_addr); + + ossl_crypto_mutex_unlock(dl->mutex); +} + +/* + * ossl_dtls_listener_clear_established_conns - clear and recreate the + * established_conns table. + */ +void ossl_dtls_listener_clear_established_conns(DTLS_LISTENER *dl) +{ + if (dl == NULL) + return; + + ossl_crypto_mutex_lock(dl->mutex); + + if (dl->established_conns != NULL) + ossl_dgram_conn_lookup_free(dl->established_conns); + dl->established_conns = ossl_dgram_conn_lookup_new_addr(); + + ossl_crypto_mutex_unlock(dl->mutex); +} + +size_t ossl_dtls_get_accept_connection_queue_len(SSL *ssl) +{ + DTLS_LISTENER *dl; + size_t len; + + if (!IS_DTLS_LISTENER(ssl)) + return 0; + + dl = (DTLS_LISTENER *)ssl; + + ossl_crypto_mutex_lock(dl->mutex); + len = (size_t)sk_SSL_num(dl->incoming_connections); + ossl_crypto_mutex_unlock(dl->mutex); + + return len; +} + +/* + * Set an override time callback for the DTLS listener. + * This is primarily for testing purposes to allow time injection. + * If now_cb is NULL, the listener will use ossl_time_now(). + */ +int ossl_dtls_listener_set_override_now_cb(SSL *s, + OSSL_TIME (*now_cb)(void *arg), + void *now_cb_arg) +{ + DTLS_LISTENER *dl; + + if (!IS_DTLS_LISTENER(s)) + return 0; + + dl = (DTLS_LISTENER *)s; + dl->now_cb = now_cb; + dl->now_cb_arg = now_cb_arg; + + return 1; +} + +/* + * ossl_dtls_get_value_uint - read a tunable value from a DTLS listener. + * + * DTLS-side implementation backing SSL_get_value_uint(3) when the target + * SSL object is a DTLS listener created by SSL_new_listener(). + * + * Supported (id) values: + * SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS + * Current cap on the number of pending (handshake-in-progress) + * connections the listener will track. + * SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT + * Current reap timeout for pending connections, in milliseconds. + * UINT64_MAX means "infinite / disabled". + * SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE + * Maximum size in bytes of a datagram the listener will receive. + * + * Only SSL_VALUE_CLASS_GENERIC is accepted for class_; other + * classes are rejected with a return of 0 + * + * Parameters: + * s - listener SSL. Must satisfy IS_DTLS_LISTENER(s). + * class_ - value class; must be SSL_VALUE_CLASS_GENERIC. + * id - one of the SSL_VALUE_DTLS_LISTENER_* ids listed above. + * value - out-parameter receiving the current value. Must be non-NULL. + * + * Returns: + * 1 on success (*value populated). + * 0 on failure (unsupported id, wrong class, NULL value, or not a + * DTLS listener). + */ +int ossl_dtls_get_value_uint(SSL *s, uint32_t class_, uint32_t id, uint64_t *value) +{ + DTLS_LISTENER *dl; + int ret = 1; + + if (!IS_DTLS_LISTENER(s)) { + ERR_raise(ERR_LIB_SSL, SSL_R_LISTENER_USE_ONLY); + return 0; + } + if (class_ != SSL_VALUE_CLASS_GENERIC) { + ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS); + return 0; + } + if (value == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + dl = (DTLS_LISTENER *)s; + + ossl_crypto_mutex_lock(dl->mutex); + + switch (id) { + case SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS: + *value = (uint64_t)dl->max_pending_conns; + break; + case SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT: + if (ossl_time_is_infinite(dl->pending_timeout)) + *value = UINT64_MAX; + else + *value = ossl_time2ms(dl->pending_timeout); + break; + case SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE: + *value = (uint64_t)dl->max_dgram_size; + break; + default: + ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_CONFIG_VALUE); + ret = 0; + break; + } + + ossl_crypto_mutex_unlock(dl->mutex); + return ret; +} + +/* + * ossl_dtls_set_value_uint - write a tunable value on a DTLS listener. + * + * DTLS-side implementation backing SSL_set_value_uint(3) when the target + * SSL object is a DTLS listener created by SSL_new_listener(). + * + * Supported (id) values -- see ossl_dtls_get_value_uint() above. + * + * Per-id policy: + * SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS + * value == 0 is rejected (a zero cap would reject every incoming + * connection). Values larger than SIZE_MAX are clamped to SIZE_MAX + * to avoid silent truncation on 32-bit builds. + * SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT + * Interpreted as milliseconds. value == 0 is rejected. UINT64_MAX is + * treated as "infinite / disabled". + * SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE + * Clamped to the maximum UDP payload (DTLS_LISTENER_MAX_DGRAM_SIZE); + * values below the demux minimum receive size are rejected. + * + * Only SSL_VALUE_CLASS_GENERIC is accepted for class_. + * + * Parameters: + * s - listener SSL. Must satisfy IS_DTLS_LISTENER(s). + * class_ - value class; must be SSL_VALUE_CLASS_GENERIC. + * id - one of the SSL_VALUE_DTLS_LISTENER_* ids. + * value - new value to store, in the units documented per id. + * + * Returns: + * 1 on success. + * 0 on failure (unsupported id, wrong class, not a DTLS listener, + * or policy rejection such as 0 on the cap). + */ +int ossl_dtls_set_value_uint(SSL *s, uint32_t class_, uint32_t id, uint64_t value) +{ + DTLS_LISTENER *dl; + int ret = 1; + + if (!IS_DTLS_LISTENER(s)) { + ERR_raise(ERR_LIB_SSL, SSL_R_LISTENER_USE_ONLY); + return 0; + } + if (class_ != SSL_VALUE_CLASS_GENERIC) { + ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS); + return 0; + } + + dl = (DTLS_LISTENER *)s; + + ossl_crypto_mutex_lock(dl->mutex); + + switch (id) { + case SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS: + if (value == 0) { + /* A zero cap would reject every connection (num_items >= 0). */ + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + ret = 0; + break; + } + /* Clamp to SIZE_MAX to prevent silent truncation on 32-bit. */ + dl->max_pending_conns = (value > SIZE_MAX) ? SIZE_MAX : (size_t)value; + break; + case SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT: + if (value == 0) { + /* + * A zero timeout will remove all pending connections on the next + * tick, before the handshake could complete. + */ + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + ret = 0; + break; + } + /* + * ossl_ms2time() scales by OSSL_TIME_MS (10^6 ns/ms), so any value + * above UINT64_MAX / OSSL_TIME_MS would overflow the product and + * silently wrap to a tiny timeout. Treat those (which includes the + * UINT64_MAX "infinite" sentinel) as an infinite timeout. + */ + if (value > UINT64_MAX / OSSL_TIME_MS) + dl->pending_timeout = ossl_time_infinite(); + else + dl->pending_timeout = ossl_ms2time(value); + break; + case SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE: + /* Nothing larger than the maximum UDP payload can ever arrive. */ + if (value > DTLS_LISTENER_MAX_DGRAM_SIZE) + value = DTLS_LISTENER_MAX_DGRAM_SIZE; + /* set_mtu returns 0 (rejecting) for values below the demux minimum. */ + if (!ossl_dgram_demux_set_mtu(dl->demux, (unsigned int)value)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + ret = 0; + } else { + dl->max_dgram_size = (size_t)value; + } + break; + default: + ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_CONFIG_VALUE); + ret = 0; + break; + } + + ossl_crypto_mutex_unlock(dl->mutex); + return ret; +} + +/* + * Resolve the requested blocking mode of a DTLS listener, or of a connection + * created from one, following the inheritance chain. + * + * A connection set to INHERIT follows its listener; a listener set to INHERIT + * is blocking, there being nothing further to inherit from. Blocking is + * therefore the default unless the application asks otherwise. + * + * Returns 1 if blocking is wanted, which says nothing about whether it can be + * provided - see ossl_dtls_can_support_blocking(). + */ +static int ossl_dtls_desires_blocking(const SSL *s) +{ + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s); + const DTLS_LISTENER *dl = NULL; + + if (sc != NULL && sc->d1 != NULL) { + /* The listener is driving this connection; it must not block. */ + if (sc->d1->force_nonblocking) + return 0; + + if (sc->d1->req_blocking_mode != DTLS_BLOCKING_MODE_INHERIT) + return sc->d1->req_blocking_mode == DTLS_BLOCKING_MODE_BLOCKING; + + dl = (const DTLS_LISTENER *)sc->d1->listener; + } else if (IS_DTLS_LISTENER(s)) { + dl = (const DTLS_LISTENER *)s; + } + + if (dl == NULL) + return 0; + + return dl->req_blocking_mode != DTLS_BLOCKING_MODE_NONBLOCKING; +} + +/* + * Report whether blocking mode can be provided for a DTLS listener or a + * connection created from one. + * + * Blocking is emulated by waiting for readiness of the listener's network + * socket, so it requires a BIO which can supply a poll descriptor to wait on. + * A memory BIO cannot, and such a listener is therefore non-blocking whatever + * was requested, as is the case for QUIC. + */ +static int ossl_dtls_can_support_blocking(const SSL *s) +{ + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s); + const SSL *listener = NULL; + BIO_POLL_DESCRIPTOR desc; + BIO *rbio; + + if (sc != NULL && sc->d1 != NULL) + listener = sc->d1->listener; + else if (IS_DTLS_LISTENER(s)) + listener = s; + + if (listener == NULL) + return 0; + + rbio = SSL_get_rbio(listener); + if (rbio == NULL) + return 0; + + return BIO_get_rpoll_descriptor(rbio, &desc) != 0 + && desc.type == BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD; +} + +/* + * Report whether a call on this object should block, which is the case when + * blocking is both wanted and possible. + */ +int ossl_dtls_blocking(const SSL *s) +{ + return ossl_dtls_desires_blocking(s) && ossl_dtls_can_support_blocking(s); +} + +int ossl_dtls_set_blocking_mode(SSL *s, int blocking) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + unsigned int mode = (blocking != 0) + ? DTLS_BLOCKING_MODE_BLOCKING + : DTLS_BLOCKING_MODE_NONBLOCKING; + + /* + * Only a listener, or a connection created from one, has a blocking mode. + * Any other DTLS object takes its behaviour from its own BIO in the + * traditional way, so there is nothing here to configure. + */ + if (!IS_DTLS_LISTENER(s) + && (sc == NULL || sc->d1 == NULL || sc->d1->listener == NULL)) { + ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); + return 0; + } + + /* + * Refuse to claim blocking we cannot deliver, as QUIC does. Checked before + * anything is written, so that a call which fails leaves the mode alone + * rather than reporting failure having already changed it. + */ + if (blocking && !ossl_dtls_can_support_blocking(s)) { + ERR_raise(ERR_LIB_SSL, ERR_R_UNSUPPORTED); + return 0; + } + + if (IS_DTLS_LISTENER(s)) + ((DTLS_LISTENER *)s)->req_blocking_mode = mode; + else + sc->d1->req_blocking_mode = mode; + + return 1; +} + +int ossl_dtls_get_blocking_mode(const SSL *s) +{ + const SSL_CONNECTION *sc = SSL_CONNECTION_FROM_CONST_SSL_ONLY(s); + + if (!IS_DTLS_LISTENER(s) + && (sc == NULL || sc->d1 == NULL || sc->d1->listener == NULL)) + return -1; + + return ossl_dtls_blocking(s); +} + +/* + * Wait until a datagram has been demultiplexed to this connection's receive + * queue, for a connection which is in blocking mode. + * + * This is what makes a blocking read on a listener based connection block. Such + * a connection has no BIO of its own to block in: it reads from a queue which + * the listener fills, so the wait has to happen here instead. + * + * A wakeup does not mean the datagram was ours - the listener's socket is + * shared, and another connection may be the one with data - so this loops until + * something actually lands in our queue. Events are handled after each wait + * because nothing else will do it while we are in here, and the retransmission + * timer needs servicing if it is what woke us. + * + * A datagram which is already waiting costs nothing: the wait pumps the + * listener's demux while translating the poll, and returns without sleeping if + * anything has been queued for us by then. + * + * Returns 1 if a datagram is now queued for this connection, or 0 if the wait + * could not be performed or the listener has failed. + */ +int ossl_dtls_conn_wait_for_datagram(SSL *s) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + DTLS_LISTENER *dl; + int empty; + + if (sc == NULL || sc->d1 == NULL || sc->d1->rx == NULL + || sc->d1->listener == NULL) + return 0; + + dl = (DTLS_LISTENER *)sc->d1->listener; + + for (;;) { + ossl_crypto_mutex_lock(dl->mutex); + if (dl->fatal) { + ossl_crypto_mutex_unlock(dl->mutex); + return 0; + } + ossl_crypto_mutex_unlock(dl->mutex); + + /* + * An infinite deadline here is bounded by the connection's own event + * timeout, which the poll translation folds in, so this still wakes in + * time to retransmit. + */ + if (!ossl_dtls_block_until_ready(s, SSL_POLL_EVENT_R, + ossl_time_infinite(), /*bound_by_event_timeout=*/1)) + return 0; + + if (!SSL_handle_events(s)) + return 0; + + ossl_dgram_demux_pump(sc->d1->rx->demux); + + ossl_crypto_mutex_lock(sc->d1->rx->mutex); + empty = ossl_list_urxe_is_empty(&sc->d1->rx->urxe_pending); + ossl_crypto_mutex_unlock(sc->d1->rx->mutex); + + if (!empty) + return 1; + } +} + +/* + * Wait until the listener's socket can accept another datagram, for a + * connection which is in blocking mode. + * + * The socket is shared with every other connection and is always + * non-blocking, so a send which cannot be completed has nowhere to wait. For + * DTLS the record layer would otherwise discard the datagram - a reasonable + * default for an unreliable transport, but not what an application which asked + * for blocking writes expects. + * + * Only one wait is performed. The caller retries the send, and comes back here + * if it still cannot proceed, so a wakeup which turns out not to leave room in + * the socket buffer costs an extra attempt rather than a lost datagram. + * + * The retransmission timer deliberately does not shorten this wait, unlike the + * one for a datagram above. There the wakeup is useful, because the wait can + * service the timer itself; here it cannot. Servicing it would mean + * retransmitting a flight from inside tls_retry_write_records(), which is + * part-way through sending one and holds write buffer state that a + * re-entrant do_dtls1_write() would clobber. Waking for a timer nothing then + * services would be worse than not waking: the timeout stays expired, and an + * expired timeout reads as a zero deadline, so every later wait would return + * at once and the caller's retry loop would spin without sleeping. Waiting for + * the socket alone is also what the send actually needs. Retransmission is not + * the right response to a flight which has not finished going out, and once it + * has, the state machine handles the timer as usual. + * + * Returns 1 if the send should be retried, or 0 if the wait could not be + * performed or the listener has failed. + */ +int ossl_dtls_conn_wait_for_write(SSL *s) +{ + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + DTLS_LISTENER *dl; + int fatal; + + if (sc == NULL || sc->d1 == NULL || sc->d1->listener == NULL) + return 0; + + dl = (DTLS_LISTENER *)sc->d1->listener; + + ossl_crypto_mutex_lock(dl->mutex); + fatal = dl->fatal; + ossl_crypto_mutex_unlock(dl->mutex); + if (fatal) + return 0; + + return ossl_dtls_block_until_ready(s, SSL_POLL_EVENT_W, + ossl_time_infinite(), /*bound_by_event_timeout=*/0); +} + +void ossl_dtls_listener_enter_blocking_section(SSL *s) +{ + DTLS_LISTENER *dl; + + if (!IS_DTLS_LISTENER(s)) + return; + + dl = (DTLS_LISTENER *)s; + + if (dl->have_notifier) { + ossl_crypto_mutex_lock(dl->mutex); + dl->cur_blocking_waiters++; + ossl_crypto_mutex_unlock(dl->mutex); + } +} + +void ossl_dtls_listener_leave_blocking_section(SSL *s) +{ + DTLS_LISTENER *dl; + + if (!IS_DTLS_LISTENER(s)) + return; + + dl = (DTLS_LISTENER *)s; + + if (dl->have_notifier) { + ossl_crypto_mutex_lock(dl->mutex); + + assert(dl->cur_blocking_waiters > 0); + --dl->cur_blocking_waiters; + + if (dl->signalled_notifier) { + if (dl->cur_blocking_waiters == 0) { + ossl_rio_notifier_unsignal(&dl->notifier); + dl->signalled_notifier = 0; + + /* + * Release the other threads which have woken up + */ + ossl_crypto_condvar_broadcast(dl->notifier_cv); + } else { + /* We are not the last waiter out - so wait for that one. */ + while (dl->signalled_notifier) + ossl_crypto_condvar_wait(dl->notifier_cv, dl->mutex); + } + } + + ossl_crypto_mutex_unlock(dl->mutex); + } +} + +int ossl_dtls_listener_poll_events(SSL *s, uint64_t events, int do_tick, + uint64_t *revents) +{ + DTLS_LISTENER *dl; + uint64_t result = 0; + + if (!ossl_assert(IS_DTLS_LISTENER(s))) + return 0; + + dl = (DTLS_LISTENER *)s; + + if (do_tick) + ossl_dtls_tick(dl); + + if ((events & SSL_POLL_EVENT_IC) != 0) { + if (SSL_get_accept_connection_queue_len(s) > 0) + result |= SSL_POLL_EVENT_IC; + } + + if ((events & SSL_POLL_EVENT_R) != 0) { + BIO *rbio = SSL_get_rbio(s); + if (rbio != NULL && BIO_pending(rbio) > 0) + result |= SSL_POLL_EVENT_R; + } + + *revents = result; + return 1; +} + +int ossl_dtls_conn_poll_events(SSL *s, uint64_t events, int do_tick, + uint64_t *revents) +{ + SSL_CONNECTION *sc; + uint64_t result = 0; + BIO_POLL_DESCRIPTOR desc; + int has_pending; + + sc = SSL_CONNECTION_FROM_SSL(s); + if (sc == NULL || sc->d1 == NULL) + return 0; + + /* + * For DTLS connections that came from a listener, data arrives via + * URXEs injected by the listener's demux. When do_tick is set and + * we have a listener reference, pump the demux to get new data. + */ + if (do_tick && sc->d1->listener != NULL) { + DTLS_LISTENER *dl = (DTLS_LISTENER *)sc->d1->listener; + ossl_dtls_tick(dl); + } + + /* + * Handle events for the connection itself, which for DTLS means servicing + * the retransmission timer. The caller may have blocked until that timer + * expired, so if nothing retransmits here then nothing will, and the + * deadline would be recomputed as "now" on every subsequent wait. + * + * A failure here leaves the connection in a fatal error state, which the + * SSL_POLL_EVENT_EC check below reports. + */ + if (do_tick) + SSL_handle_events(s); + + if ((events & SSL_POLL_EVENT_R) != 0) { + if (SSL_has_pending(s) || SSL_pending(s) > 0) { + result |= SSL_POLL_EVENT_R; + } else if (sc->d1->rx != NULL) { + /* Listener-based connection: check URXE queue */ + ossl_crypto_mutex_lock(sc->d1->rx->mutex); + has_pending = !ossl_list_urxe_is_empty(&sc->d1->rx->urxe_pending); + ossl_crypto_mutex_unlock(sc->d1->rx->mutex); + if (has_pending) + result |= SSL_POLL_EVENT_R; + } else { + /* + * Standalone DTLS SSL object (not from a listener). + * Check the underlying socket for readability. + */ + BIO *rbio = SSL_get_rbio(s); + + if (rbio != NULL) { + if (BIO_get_rpoll_descriptor(rbio, &desc) + && desc.type == BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD + && desc.value.fd >= 0) { + if (BIO_socket_ready(desc.value.fd, 1) > 0) + result |= SSL_POLL_EVENT_R; + } else { + /* Checking non-socket BIO */ + if (BIO_pending(rbio) > 0) + result |= SSL_POLL_EVENT_R; + } + } + } + } + + if ((events & SSL_POLL_EVENT_W) != 0) { + result |= SSL_POLL_EVENT_W; + } + + if ((events & (SSL_POLL_EVENT_EC | SSL_POLL_EVENT_F)) != 0) { + if (SSL_get_error(s, 0) == SSL_ERROR_SSL || SSL_get_shutdown(s) != 0) + result |= SSL_POLL_EVENT_EC; + } + + *revents = result; + return 1; +} + +#endif /* !OPENSSL_NO_DTLS && !OPENSSL_NO_SOCK */ diff --git a/ssl/d1_msg.c b/ssl/d1_msg.c index 50676a1cda381..5d49e3cd1b930 100644 --- a/ssl/d1_msg.c +++ b/ssl/d1_msg.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -19,6 +19,13 @@ int dtls1_write_app_data_bytes(SSL *s, uint8_t type, const void *buf_, if (sc == NULL) return -1; + /* + * If we are supposed to be sending a KeyUpdate or NewSessionTicket then go + * into init - in which case we should finish doing that first. + */ + if (sc->key_update != SSL_KEY_UPDATE_NONE || sc->ext.extra_tickets_expected > 0) + ossl_statem_set_in_init(sc, 1); + if (SSL_in_init(s) && !ossl_statem_get_in_handshake(sc)) { i = sc->handshake_func(s); if (i < 0) diff --git a/ssl/d1_transcript.c b/ssl/d1_transcript.c new file mode 100644 index 0000000000000..f14bddd267c70 --- /dev/null +++ b/ssl/d1_transcript.c @@ -0,0 +1,45 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "ssl_local.h" + +/* + * RFC 9147 §5.2: strip msg_seq, fragment_offset, and fragment_length from + * each DTLS handshake message header before feeding into the transcript hash. + * Used by both ssl3_finish_mac and tls13_change_cipher_state. + */ +int dtls13_transcript_hash_update(EVP_MD_CTX *mdctx, + const unsigned char *buf, size_t len) +{ + while (len > 0) { + PACKET hmhdr; + unsigned long hmbodylen; + unsigned int msgtype; + size_t hmhdrlen; + + if (!ossl_assert(len >= SSL3_HM_HEADER_LENGTH) + || !PACKET_buf_init(&hmhdr, buf, SSL3_HM_HEADER_LENGTH) + || !PACKET_get_1(&hmhdr, &msgtype) + || !PACKET_get_net_3(&hmhdr, &hmbodylen)) + return 0; + + hmhdrlen = (msgtype == SSL3_MT_MESSAGE_HASH) + ? SSL3_HM_HEADER_LENGTH + : DTLS1_HM_HEADER_LENGTH; + + if (!ossl_assert(hmhdrlen + hmbodylen <= len) + || !EVP_DigestUpdate(mdctx, buf, SSL3_HM_HEADER_LENGTH) + || !EVP_DigestUpdate(mdctx, buf + hmhdrlen, hmbodylen)) + return 0; + + buf += hmhdrlen + hmbodylen; + len -= hmhdrlen + hmbodylen; + } + return 1; +} diff --git a/ssl/dgram_demux.c b/ssl/dgram_demux.c new file mode 100644 index 0000000000000..a23de37a2a4f3 --- /dev/null +++ b/ssl/dgram_demux.c @@ -0,0 +1,547 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "internal/e_os.h" +#include "internal/dgram_demux.h" +#include "internal/thread_arch.h" +#include "internal/common.h" +#include +#include + +#if !defined(OPENSSL_NO_QUIC) || !defined(OPENSSL_NO_DTLS) + +/* URXE_DEMUX_STATE_* are defined in dgram_demux.h */ + +#define DEMUX_MAX_MSGS_PER_CALL 32 +#define DEMUX_DEFAULT_MTU 1500 +#define DEMUX_MIN_INITIAL_DGRAM_LEN 1200 + +struct dgram_demux_st { + /* The underlying transport BIO with datagram semantics. */ + BIO *net_bio; + + /* + * Our current understanding of the upper bound on an incoming datagram size + * in bytes. + */ + size_t mtu; + + /* The datagram_id to use for the next datagram we receive. */ + uint64_t next_datagram_id; + + /* Time retrieval callback. */ + OSSL_TIME (*now)(void *arg); + void *now_arg; + + /* The default packet handler, if any. */ + ossl_dgram_demux_cb_fn *default_cb; + void *default_cb_arg; + + /* + * List of URXEs which are not currently in use (i.e., not filled with + * unconsumed data). These are moved to the pending list as they are filled. + */ + DGRAM_URXE_LIST urx_free; + + /* + * List of URXEs which are filled with received encrypted data. These are + * removed from this list as we invoke the callbacks for each of them. They + * are then not on any list managed by us; we forget about them until our + * user calls ossl_dgram_demux_release_urxe to return the URXE to us, at + * which point we add it to the free list. + */ + DGRAM_URXE_LIST urx_pending; + + /* Whether to use local address support. */ + char use_local_addr; + + /* Whether internal locking is required */ + char require_mutex; + + /* + * Mutex protecting the URXE lists (urx_free and urx_pending). + */ + CRYPTO_MUTEX *mutex; +}; + +/* List management helpers */ +void ossl_dgram_urxe_remove(DGRAM_URXE_LIST *l, DGRAM_URXE *e) +{ + ossl_list_urxe_remove(l, e); +} + +void ossl_dgram_urxe_insert_head(DGRAM_URXE_LIST *l, DGRAM_URXE *e) +{ + ossl_list_urxe_insert_head(l, e); +} + +void ossl_dgram_urxe_insert_tail(DGRAM_URXE_LIST *l, DGRAM_URXE *e) +{ + ossl_list_urxe_insert_tail(l, e); +} + +DGRAM_DEMUX *ossl_dgram_demux_new(BIO *net_bio, + int threadsafe, + OSSL_TIME (*now)(void *arg), + void *now_arg) +{ + DGRAM_DEMUX *demux; + + demux = OPENSSL_zalloc(sizeof(DGRAM_DEMUX)); + if (demux == NULL) + return NULL; + + if (threadsafe) { + demux->require_mutex = 1; + demux->mutex = ossl_crypto_mutex_new(); +#ifdef OPENSSL_THREADS + if (demux->mutex == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + OPENSSL_free(demux); + return NULL; + } +#endif + } + + /* We update this if possible when we get a BIO. */ + demux->mtu = DEMUX_DEFAULT_MTU; + demux->now = now; + demux->now_arg = now_arg; + + ossl_dgram_demux_set_bio(demux, net_bio); + + return demux; +} + +static void dgram_demux_free_urxl(DGRAM_URXE_LIST *l) +{ + DGRAM_URXE *e, *enext; + + for (e = ossl_list_urxe_head(l); e != NULL; e = enext) { + enext = ossl_list_urxe_next(e); + ossl_list_urxe_remove(l, e); + OPENSSL_free(e); + } +} + +void ossl_dgram_demux_free(DGRAM_DEMUX *demux) +{ + if (demux == NULL) + return; + + /* Free all URXEs we are holding. */ + dgram_demux_free_urxl(&demux->urx_free); + dgram_demux_free_urxl(&demux->urx_pending); + + if (demux->require_mutex) + ossl_crypto_mutex_free(&demux->mutex); + + OPENSSL_free(demux); +} + +void ossl_dgram_demux_set_bio(DGRAM_DEMUX *demux, BIO *net_bio) +{ + unsigned int mtu; + + demux->net_bio = net_bio; + + if (net_bio != NULL) { + /* + * Try to determine our MTU if possible. The BIO is not required to + * support this, in which case we remain at the last known MTU, or our + * initial default. + */ + mtu = BIO_dgram_get_mtu(net_bio); + if (mtu >= DEMUX_MIN_INITIAL_DGRAM_LEN) + ossl_dgram_demux_set_mtu(demux, mtu); + + if (BIO_dgram_get_local_addr_cap(net_bio) + && BIO_dgram_set_local_addr_enable(net_bio, 1)) + demux->use_local_addr = 1; + } +} + +int ossl_dgram_demux_set_mtu(DGRAM_DEMUX *demux, unsigned int mtu) +{ + if (mtu < DEMUX_MIN_INITIAL_DGRAM_LEN) + return 0; + + /* + * mtu is read under demux->mutex by the receive path + * so take the lock here. + */ + if (demux->require_mutex) + ossl_crypto_mutex_lock(demux->mutex); + demux->mtu = mtu; + if (demux->require_mutex) + ossl_crypto_mutex_unlock(demux->mutex); + return 1; +} + +void ossl_dgram_demux_set_default_handler(DGRAM_DEMUX *demux, + ossl_dgram_demux_cb_fn *cb, + void *cb_arg) +{ + demux->default_cb = cb; + demux->default_cb_arg = cb_arg; +} + +static DGRAM_URXE *dgram_demux_alloc_urxe(size_t alloc_len) +{ + DGRAM_URXE *e; + + if (alloc_len >= SIZE_MAX - sizeof(DGRAM_URXE)) + return NULL; + + e = OPENSSL_zalloc(sizeof(DGRAM_URXE) + alloc_len); + if (e == NULL) + return NULL; + + ossl_list_urxe_init_elem(e); + e->alloc_len = alloc_len; + e->data_len = 0; + return e; +} + +static DGRAM_URXE *dgram_demux_resize_urxe(DGRAM_DEMUX *demux, DGRAM_URXE *e, + size_t new_alloc_len) +{ + DGRAM_URXE *e2, *prev; + + if (!ossl_assert(e->demux_state == URXE_DEMUX_STATE_FREE)) + /* Never attempt to resize a URXE which is not on the free list. */ + return NULL; + + prev = ossl_list_urxe_prev(e); + ossl_list_urxe_remove(&demux->urx_free, e); + + if (new_alloc_len >= SIZE_MAX - sizeof(DGRAM_URXE)) + goto rollback; + + e2 = OPENSSL_realloc(e, sizeof(DGRAM_URXE) + new_alloc_len); + + /* Failed to resize, abort. */ + if (e2 == NULL) + goto rollback; + + if (prev == NULL) + ossl_list_urxe_insert_head(&demux->urx_free, e2); + else + ossl_list_urxe_insert_after(&demux->urx_free, prev, e2); + + e2->alloc_len = new_alloc_len; + return e2; + +rollback: + /* Reinsert e back into the list on failures */ + if (prev == NULL) + ossl_list_urxe_insert_head(&demux->urx_free, e); + else + ossl_list_urxe_insert_after(&demux->urx_free, prev, e); + + return NULL; +} + +static DGRAM_URXE *dgram_demux_reserve_urxe(DGRAM_DEMUX *demux, DGRAM_URXE *e, + size_t alloc_len) +{ + return e->alloc_len < alloc_len + ? dgram_demux_resize_urxe(demux, e, alloc_len) + : e; +} + +static int dgram_demux_ensure_free_urxe(DGRAM_DEMUX *demux, size_t min_num_free) +{ + DGRAM_URXE *e; + + /* Caller must hold the lock */ + while (ossl_list_urxe_num(&demux->urx_free) < min_num_free) { + e = dgram_demux_alloc_urxe(demux->mtu); + if (e == NULL) + return 0; + + ossl_list_urxe_insert_tail(&demux->urx_free, e); + e->demux_state = URXE_DEMUX_STATE_FREE; + } + + return 1; +} + +/* + * Receive datagrams from network, placing them into URXEs. + * + * Returns DGRAM_DEMUX_PUMP_RES_* value. + * + * Precondition: at least one URXE is free + * Precondition: there are no pending URXEs + * Precondition: Caller holds the demux lock + */ +static int dgram_demux_recv(DGRAM_DEMUX *demux) +{ + BIO_MSG msg[DEMUX_MAX_MSGS_PER_CALL]; + size_t rd, i; + DGRAM_URXE *urxe = ossl_list_urxe_head(&demux->urx_free), *unext; + OSSL_TIME now; + + /* This should never be called when we have any pending URXE. */ + assert(ossl_list_urxe_head(&demux->urx_pending) == NULL); + assert(urxe->demux_state == URXE_DEMUX_STATE_FREE); + + if (demux->net_bio == NULL) + /* + * If no BIO is plugged in, treat this as no datagram being available. + */ + return DGRAM_DEMUX_PUMP_RES_TRANSIENT_FAIL; + + /* + * Opportunistically receive as many messages as possible in a single + * syscall, determined by how many free URXEs are available. + */ + for (i = 0; i < (ossl_ssize_t)OSSL_NELEM(msg); + ++i, urxe = ossl_list_urxe_next(urxe)) { + if (urxe == NULL) { + /* We need at least one URXE to receive into. */ + if (!ossl_assert(i > 0)) + return DGRAM_DEMUX_PUMP_RES_PERMANENT_FAIL; + + break; + } + + /* Ensure the URXE is big enough. */ + urxe = dgram_demux_reserve_urxe(demux, urxe, demux->mtu); + if (urxe == NULL) + /* Allocation error, fail. */ + return DGRAM_DEMUX_PUMP_RES_PERMANENT_FAIL; + + /* Ensure we zero any fields added to BIO_MSG at a later date. */ + memset(&msg[i], 0, sizeof(BIO_MSG)); + msg[i].data = ossl_dgram_urxe_data(urxe); + msg[i].data_len = urxe->alloc_len; + msg[i].peer = &urxe->peer; + BIO_ADDR_clear(&urxe->peer); + if (demux->use_local_addr) + msg[i].local = &urxe->local; + else + BIO_ADDR_clear(&urxe->local); + } + + ERR_set_mark(); + if (!BIO_recvmmsg(demux->net_bio, msg, sizeof(BIO_MSG), i, 0, &rd)) { + if (BIO_err_is_non_fatal(ERR_peek_last_error())) { + /* Transient error, clear the error and stop. */ + ERR_pop_to_mark(); + return DGRAM_DEMUX_PUMP_RES_TRANSIENT_FAIL; + } else { + /* Non-transient error, do not clear the error. */ + ERR_clear_last_mark(); + return DGRAM_DEMUX_PUMP_RES_PERMANENT_FAIL; + } + } + + ERR_clear_last_mark(); + now = demux->now != NULL ? demux->now(demux->now_arg) : ossl_time_zero(); + + urxe = ossl_list_urxe_head(&demux->urx_free); + for (i = 0; i < rd; ++i, urxe = unext) { + unext = ossl_list_urxe_next(urxe); + /* Set URXE with actual length of received datagram. */ + urxe->data_len = msg[i].data_len; + /* Time we received datagram. */ + urxe->time = now; + urxe->datagram_id = demux->next_datagram_id++; + /* Move from free list to pending list. */ + ossl_list_urxe_remove(&demux->urx_free, urxe); + ossl_list_urxe_insert_tail(&demux->urx_pending, urxe); + urxe->demux_state = URXE_DEMUX_STATE_PENDING; + } + + return DGRAM_DEMUX_PUMP_RES_OK; +} + +/* + * Process a single pending URXE. + * Returning 1 on success, 0 on failure. + * + * Precondition: Caller holds the demux lock + * Note: Lock is released before callback and reacquired after. + */ +static int dgram_demux_process_pending_urxe(DGRAM_DEMUX *demux, DGRAM_URXE *e) +{ + /* The next URXE we process should be at the head of the pending list. */ + if (!ossl_assert(e == ossl_list_urxe_head(&demux->urx_pending))) + return 0; + + assert(e->demux_state == URXE_DEMUX_STATE_PENDING); + + ossl_list_urxe_remove(&demux->urx_pending, e); + if (demux->default_cb != NULL) { + /* + * Pass to handler for routing. The URXE now belongs to the callback. + * Release lock before callback to avoid deadlock if callback calls + * release_urxe or reinject_urxe. + */ + e->demux_state = URXE_DEMUX_STATE_ISSUED; + if (demux->require_mutex) + ossl_crypto_mutex_unlock(demux->mutex); + demux->default_cb(e, demux->default_cb_arg); + if (demux->require_mutex) + ossl_crypto_mutex_lock(demux->mutex); + } else { + /* No handler, discard. */ + ossl_list_urxe_insert_tail(&demux->urx_free, e); + e->demux_state = URXE_DEMUX_STATE_FREE; + } + + return 1; /* keep processing pending URXEs */ +} + +/* + * Process pending URXEs to generate callbacks. + * Precondition: Caller holds the demux lock + */ +static int dgram_demux_process_pending_urxl(DGRAM_DEMUX *demux) +{ + DGRAM_URXE *e; + int ret; + + while ((e = ossl_list_urxe_head(&demux->urx_pending)) != NULL) + if ((ret = dgram_demux_process_pending_urxe(demux, e)) <= 0) + return ret; + + return 1; +} + +/* + * Drain the pending URXE list, processing any pending URXEs by making their + * callbacks. If no URXEs are pending, a network read is attempted first. + */ +int ossl_dgram_demux_pump(DGRAM_DEMUX *demux) +{ + int ret; + + if (demux->require_mutex) + ossl_crypto_mutex_lock(demux->mutex); + + if (ossl_list_urxe_head(&demux->urx_pending) == NULL) { + if (!dgram_demux_ensure_free_urxe(demux, DEMUX_MAX_MSGS_PER_CALL)) { + ret = DGRAM_DEMUX_PUMP_RES_PERMANENT_FAIL; + goto end; + } + + ret = dgram_demux_recv(demux); + if (ret != DGRAM_DEMUX_PUMP_RES_OK) + goto end; + + /* + * If dgram_demux_recv returned successfully, we should always have + * something. + */ + assert(ossl_list_urxe_head(&demux->urx_pending) != NULL); + } + + if (dgram_demux_process_pending_urxl(demux) <= 0) { + ret = DGRAM_DEMUX_PUMP_RES_PERMANENT_FAIL; + goto end; + } + + ret = DGRAM_DEMUX_PUMP_RES_OK; + +end: + if (demux->require_mutex) + ossl_crypto_mutex_unlock(demux->mutex); + return ret; +} + +/* Artificially inject a packet into the demuxer for testing purposes. */ +int ossl_dgram_demux_inject(DGRAM_DEMUX *demux, + const unsigned char *buf, + size_t buf_len, + const BIO_ADDR *peer, + const BIO_ADDR *local) +{ + int ret = 0; + DGRAM_URXE *urxe; + + if (demux->require_mutex) + ossl_crypto_mutex_lock(demux->mutex); + + if (!dgram_demux_ensure_free_urxe(demux, 1)) + goto end; + + urxe = ossl_list_urxe_head(&demux->urx_free); + + assert(urxe->demux_state == URXE_DEMUX_STATE_FREE); + + urxe = dgram_demux_reserve_urxe(demux, urxe, buf_len); + if (urxe == NULL) + goto end; + + memcpy(ossl_dgram_urxe_data(urxe), buf, buf_len); + urxe->data_len = buf_len; + + if (peer != NULL) + BIO_ADDR_copy(&urxe->peer, peer); + else + BIO_ADDR_clear(&urxe->peer); + + if (local != NULL) + BIO_ADDR_copy(&urxe->local, local); + else + BIO_ADDR_clear(&urxe->local); + + urxe->time + = demux->now != NULL ? demux->now(demux->now_arg) : ossl_time_zero(); + + /* Move from free list to pending list. */ + ossl_list_urxe_remove(&demux->urx_free, urxe); + urxe->datagram_id = demux->next_datagram_id++; + ossl_list_urxe_insert_tail(&demux->urx_pending, urxe); + urxe->demux_state = URXE_DEMUX_STATE_PENDING; + + ret = dgram_demux_process_pending_urxl(demux) > 0; + +end: + if (demux->require_mutex) + ossl_crypto_mutex_unlock(demux->mutex); + return ret; +} + +/* Called by our user to return a URXE to the free list. */ +void ossl_dgram_demux_release_urxe(DGRAM_DEMUX *demux, DGRAM_URXE *e) +{ + assert(ossl_list_urxe_prev(e) == NULL && ossl_list_urxe_next(e) == NULL); + assert(e->demux_state == URXE_DEMUX_STATE_ISSUED); + + if (demux->require_mutex) + ossl_crypto_mutex_lock(demux->mutex); + ossl_list_urxe_insert_tail(&demux->urx_free, e); + e->demux_state = URXE_DEMUX_STATE_FREE; + if (demux->require_mutex) + ossl_crypto_mutex_unlock(demux->mutex); +} + +void ossl_dgram_demux_reinject_urxe(DGRAM_DEMUX *demux, DGRAM_URXE *e) +{ + assert(ossl_list_urxe_prev(e) == NULL && ossl_list_urxe_next(e) == NULL); + assert(e->demux_state == URXE_DEMUX_STATE_ISSUED); + + if (demux->require_mutex) + ossl_crypto_mutex_lock(demux->mutex); + ossl_list_urxe_insert_head(&demux->urx_pending, e); + e->demux_state = URXE_DEMUX_STATE_PENDING; + if (demux->require_mutex) + ossl_crypto_mutex_unlock(demux->mutex); +} + +int ossl_dgram_demux_has_pending(const DGRAM_DEMUX *demux) +{ + return ossl_list_urxe_head(&demux->urx_pending) != NULL; +} + +#endif /* !OPENSSL_NO_QUIC || !OPENSSL_NO_DTLS */ diff --git a/ssl/dtls_conn_lookup.c b/ssl/dtls_conn_lookup.c new file mode 100644 index 0000000000000..27f4c66076f32 --- /dev/null +++ b/ssl/dtls_conn_lookup.c @@ -0,0 +1,538 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/common.h" +#include "internal/dgram_conn_lookup.h" +#include "crypto/siphash.h" + +#ifndef OPENSSL_NO_DTLS + +/* + * Internal entry structure for address-based connection lookup. + * Stores a connection keyed by peer address. + */ +typedef struct dgram_conn_entry_st { + BIO_ADDR peer; /* Peer address (key) */ + SSL *ssl; /* The SSL connection object */ + uint8_t *hashkey; /* Pre-built hash key (family + port + addr) */ + size_t hashkey_len; /* Length of the hash key */ + uint64_t *siphash_key; /* Pointer to shared SipHash key (hash-flooding defense) */ +} DGRAM_CONN_ENTRY; + +DEFINE_LHASH_OF_EX(DGRAM_CONN_ENTRY); + +/* + * Wrapper structure for address-based lookup implementation data. + * Contains the hash table and SipHash key for hash-flooding defense. + */ +typedef struct addr_lookup_data_st { + LHASH_OF(DGRAM_CONN_ENTRY) *htable; + uint64_t hash_key[2]; /* 128-bit SipHash key */ +} ADDR_LOOKUP_DATA; + +/* + * Build a hash key from a BIO_ADDR. + * The key format is: family (int) + port (uint16_t) + raw address bytes. + * + * Returns allocated hashkey buffer on success, NULL on failure. + */ +static uint8_t *build_hashkey(const BIO_ADDR *peer, size_t *out_len) +{ + size_t hashkey_len = 0; + size_t addr_len = 0; + int family; + uint16_t port; + uint8_t *hashkey; + int *famptr; + uint16_t *portptr; + uint8_t *addrptr; + + family = BIO_ADDR_family(peer); + + /* For AF_UNSPEC (no peer address), use a minimal key */ + if (family == AF_UNSPEC) { + hashkey_len = sizeof(int); + hashkey = OPENSSL_zalloc(hashkey_len); + if (hashkey == NULL) + return NULL; + famptr = (int *)hashkey; + *famptr = family; + *out_len = hashkey_len; + return hashkey; + } + + if (!BIO_ADDR_rawaddress(peer, NULL, &addr_len)) + return NULL; + + port = BIO_ADDR_rawport(peer); + + hashkey_len += sizeof(int); /* family */ + hashkey_len += sizeof(uint16_t); /* port */ + hashkey_len += addr_len; /* address */ + + hashkey = OPENSSL_zalloc(hashkey_len); + if (hashkey == NULL) + return NULL; + + famptr = (int *)hashkey; + portptr = (uint16_t *)(famptr + 1); + addrptr = (uint8_t *)(portptr + 1); + + *famptr = family; + *portptr = port; + if (!BIO_ADDR_rawaddress(peer, addrptr, NULL)) { + OPENSSL_free(hashkey); + return NULL; + } + + *out_len = hashkey_len; + return hashkey; +} + +/* + * Hash function for DGRAM_CONN_ENTRY. + * Uses SipHash with a per-instance random key to defend against + * hash-flooding CPU DoS attacks + */ +static unsigned long conn_entry_hash(const DGRAM_CONN_ENTRY *e) +{ + SIPHASH siphash = { 0 }; + unsigned long hashval = 0; + + if (e->hashkey == NULL || e->hashkey_len == 0 || e->siphash_key == NULL) + return 0; + + if (!SipHash_set_hash_size(&siphash, sizeof(unsigned long))) + return 0; + if (!SipHash_Init(&siphash, (const unsigned char *)e->siphash_key, 0, 0)) + return 0; + SipHash_Update(&siphash, e->hashkey, e->hashkey_len); + if (!SipHash_Final(&siphash, (unsigned char *)&hashval, sizeof(unsigned long))) + return 0; + + return hashval; +} + +/* + * Compare function for DGRAM_CONN_ENTRY - compares pre-built hashkeys. + * Returns 0 if equal, non-zero otherwise. + */ +static int conn_entry_cmp(const DGRAM_CONN_ENTRY *a, const DGRAM_CONN_ENTRY *b) +{ + if (a->hashkey_len != b->hashkey_len) + return 1; + if (a->hashkey == NULL || b->hashkey == NULL) + return (a->hashkey == b->hashkey) ? 0 : 1; + return memcmp(a->hashkey, b->hashkey, a->hashkey_len); +} + +/* + * Free a connection entry (but not the connection itself). + */ +static void conn_entry_free(DGRAM_CONN_ENTRY *e) +{ + if (e == NULL) + return; + OPENSSL_free(e->hashkey); + OPENSSL_free(e); +} + +/* + * Callback for lh_DGRAM_CONN_ENTRY_doall to free all entries. + */ +static void conn_entry_free_cb(DGRAM_CONN_ENTRY *e) +{ + conn_entry_free(e); +} + +/* + * Lookup a connection by peer address from URXE. + */ +static SSL *addr_lookup(DGRAM_CONN_LOOKUP *lookup, const DGRAM_URXE *e) +{ + ADDR_LOOKUP_DATA *data; + DGRAM_CONN_ENTRY key; + DGRAM_CONN_ENTRY *result; + + if (lookup == NULL || lookup->impl_data == NULL || e == NULL) + return NULL; + + data = (ADDR_LOOKUP_DATA *)lookup->impl_data; + + memset(&key, 0, sizeof(key)); + BIO_ADDR_copy(&key.peer, &e->peer); + + /* Build hashkey for the lookup key */ + key.hashkey = build_hashkey(&e->peer, &key.hashkey_len); + if (key.hashkey == NULL) + return NULL; + + /* Set SipHash key pointer for hash function */ + key.siphash_key = data->hash_key; + + result = lh_DGRAM_CONN_ENTRY_retrieve(data->htable, &key); + + OPENSSL_free(key.hashkey); + + if (result == NULL) + return NULL; + + return result->ssl; +} + +/* + * Register a connection with peer address from URXE. + */ +static int addr_register_conn(DGRAM_CONN_LOOKUP *lookup, const DGRAM_URXE *e, + SSL *ssl) +{ + ADDR_LOOKUP_DATA *data; + DGRAM_CONN_ENTRY *entry, *old; + + if (lookup == NULL || lookup->impl_data == NULL || e == NULL || ssl == NULL) + return 0; + + data = (ADDR_LOOKUP_DATA *)lookup->impl_data; + + entry = OPENSSL_zalloc(sizeof(*entry)); + if (entry == NULL) + return 0; + + BIO_ADDR_copy(&entry->peer, &e->peer); + entry->ssl = ssl; + entry->hashkey = build_hashkey(&e->peer, &entry->hashkey_len); + if (entry->hashkey == NULL) { + OPENSSL_free(entry); + return 0; + } + + /* Set SipHash key pointer for hash function */ + entry->siphash_key = data->hash_key; + + old = lh_DGRAM_CONN_ENTRY_insert(data->htable, entry); + + /* Check if insert failed due to allocation error */ + if (lh_DGRAM_CONN_ENTRY_error(data->htable)) { + conn_entry_free(entry); + /* Don't free old since it is still in the hash table since insert failed */ + return 0; + } + + /* + * A non-NULL return from lh_DGRAM_CONN_ENTRY_insert means an entry with the + * same key (peer address) was already present and has just been replaced. + * This must not happen: callers always look up an address and only register + * when no entry exists, all while holding the listener mutex, so the same peer + * is never registered twice. We therefore expect old == NULL here. + * + * We deliberately do NOT free old->ssl: this lookup table is an + * ownership-agnostic index and does not own the SSL objects it stores. + * The owning layer (the DTLS listener) is responsible for the lifecycle of + * those SSL objects. Freeing one here would be a use-after-free for the + * non-owning established_conns table. + */ + if (!ossl_assert(old == NULL)) + conn_entry_free(old); + + return 1; +} + +/* + * Register a connection by peer address from BIO_ADDR directly. + * This is used when we don't have a URXE available. + */ +static int addr_register_conn_addr(DGRAM_CONN_LOOKUP *lookup, const BIO_ADDR *peer, + SSL *ssl) +{ + ADDR_LOOKUP_DATA *data; + DGRAM_CONN_ENTRY *entry, *old; + + if (lookup == NULL || lookup->impl_data == NULL || peer == NULL || ssl == NULL) + return 0; + + data = (ADDR_LOOKUP_DATA *)lookup->impl_data; + + entry = OPENSSL_zalloc(sizeof(*entry)); + if (entry == NULL) + return 0; + + BIO_ADDR_copy(&entry->peer, peer); + entry->ssl = ssl; + entry->hashkey = build_hashkey(peer, &entry->hashkey_len); + if (entry->hashkey == NULL) { + OPENSSL_free(entry); + return 0; + } + + /* Set SipHash key pointer for hash function */ + entry->siphash_key = data->hash_key; + + old = lh_DGRAM_CONN_ENTRY_insert(data->htable, entry); + + /* Check if insert failed due to allocation error */ + if (lh_DGRAM_CONN_ENTRY_error(data->htable)) { + conn_entry_free(entry); + /* Don't free old since it is still in the hash table since insert failed */ + return 0; + } + + /* + * A non-NULL return from lh_DGRAM_CONN_ENTRY_insert means an entry with the + * same key(peer address) was already present and has just been replaced. This + * must not happen: callers always look up an address and only register when no + * entry exists, all while holding the listener mutex, so the same peer is + * never registered twice. We therefore expect old == NULL here. + * + * We deliberately do NOT free old->ssl: this lookup table is an + * ownership-agnostic index and does not own the SSL objects it stores. + * The owning layer (the DTLS listener) is responsible for the lifecycle of + * those SSL objects. Freeing one here would be a use-after-free for the + * non-owning established_conns table. + */ + if (!ossl_assert(old == NULL)) + conn_entry_free(old); + + return 1; +} + +/* + * Unregister a connection by peer address. + */ +static int addr_unregister_conn(DGRAM_CONN_LOOKUP *lookup, const BIO_ADDR *peer) +{ + ADDR_LOOKUP_DATA *data; + DGRAM_CONN_ENTRY lookup_key; + DGRAM_CONN_ENTRY *removed; + + if (lookup == NULL || lookup->impl_data == NULL || peer == NULL) + return 0; + + data = (ADDR_LOOKUP_DATA *)lookup->impl_data; + + memset(&lookup_key, 0, sizeof(lookup_key)); + BIO_ADDR_copy(&lookup_key.peer, peer); + + lookup_key.hashkey = build_hashkey(peer, &lookup_key.hashkey_len); + if (lookup_key.hashkey == NULL) + return 0; + + /* Set SipHash key pointer for hash function */ + lookup_key.siphash_key = data->hash_key; + + removed = lh_DGRAM_CONN_ENTRY_delete(data->htable, &lookup_key); + + OPENSSL_free(lookup_key.hashkey); + + if (removed != NULL) { + conn_entry_free(removed); + return 1; + } + + return 0; +} + +/* + * Free the lookup structure and all entries. + */ +static void addr_free(DGRAM_CONN_LOOKUP *lookup) +{ + ADDR_LOOKUP_DATA *data; + + if (lookup == NULL) + return; + + if (lookup->impl_data != NULL) { + data = (ADDR_LOOKUP_DATA *)lookup->impl_data; + if (data->htable != NULL) { + lh_DGRAM_CONN_ENTRY_doall(data->htable, conn_entry_free_cb); + lh_DGRAM_CONN_ENTRY_free(data->htable); + } + OPENSSL_free(data); + } + + OPENSSL_free(lookup); +} + +/* + * Context structure for iteration callback. + */ +typedef struct { + ossl_dgram_conn_lookup_iter_fn user_cb; + void *user_arg; +} ADDR_FOREACH_CTX; + +/* + * Internal callback for lh_doall_arg that invokes the user's callback. + */ +static void addr_foreach_cb(DGRAM_CONN_ENTRY *e, void *arg) +{ + ADDR_FOREACH_CTX *ctx = arg; + + if (ctx->user_cb != NULL) + ctx->user_cb(e->ssl, &e->peer, ctx->user_arg); +} + +IMPLEMENT_LHASH_DOALL_ARG(DGRAM_CONN_ENTRY, void); + +/* + * Iterate over all connections, calling the callback for each. + */ +static void addr_foreach(DGRAM_CONN_LOOKUP *lookup, + ossl_dgram_conn_lookup_iter_fn cb, void *arg) +{ + ADDR_LOOKUP_DATA *data; + ADDR_FOREACH_CTX ctx; + + if (lookup == NULL || lookup->impl_data == NULL || cb == NULL) + return; + + data = (ADDR_LOOKUP_DATA *)lookup->impl_data; + ctx.user_cb = cb; + ctx.user_arg = arg; + + lh_DGRAM_CONN_ENTRY_doall_void(data->htable, addr_foreach_cb, &ctx); +} + +static size_t addr_num_items(const DGRAM_CONN_LOOKUP *lookup) +{ + ADDR_LOOKUP_DATA *data; + + if (lookup == NULL || lookup->impl_data == NULL) + return 0; + + data = (ADDR_LOOKUP_DATA *)lookup->impl_data; + return lh_DGRAM_CONN_ENTRY_num_items(data->htable); +} + +static const DGRAM_CONN_LOOKUP_METHODS addr_methods = { + addr_lookup, + addr_register_conn, + addr_register_conn_addr, + addr_unregister_conn, + addr_foreach, + addr_free, + addr_num_items +}; + +/* + * Create a new address-based connection lookup for DTLS. + */ +DGRAM_CONN_LOOKUP *ossl_dgram_conn_lookup_new_addr(void) +{ + DGRAM_CONN_LOOKUP *lookup; + ADDR_LOOKUP_DATA *data; + + lookup = OPENSSL_zalloc(sizeof(*lookup)); + if (lookup == NULL) + return NULL; + + data = OPENSSL_zalloc(sizeof(*data)); + if (data == NULL) { + OPENSSL_free(lookup); + return NULL; + } + + /* Generate random SipHash key for hash-flooding defense */ + if (RAND_priv_bytes((unsigned char *)data->hash_key, + sizeof(data->hash_key)) + <= 0) { + OPENSSL_free(data); + OPENSSL_free(lookup); + return NULL; + } + + data->htable = lh_DGRAM_CONN_ENTRY_new(conn_entry_hash, conn_entry_cmp); + if (data->htable == NULL) { + OPENSSL_free(data); + OPENSSL_free(lookup); + return NULL; + } + + lookup->methods = &addr_methods; + lookup->impl_data = data; + + return lookup; +} + +/* + * Public API wrappers - call through methods table. + */ +SSL *ossl_dgram_conn_lookup_find(DGRAM_CONN_LOOKUP *lookup, const DGRAM_URXE *e) +{ + if (lookup == NULL || lookup->methods == NULL + || lookup->methods->lookup == NULL) + return NULL; + return lookup->methods->lookup(lookup, e); +} + +int ossl_dgram_conn_lookup_register(DGRAM_CONN_LOOKUP *lookup, + const DGRAM_URXE *e, SSL *ssl) +{ + if (lookup == NULL || lookup->methods == NULL + || lookup->methods->register_conn == NULL) + return 0; + return lookup->methods->register_conn(lookup, e, ssl); +} + +int ossl_dgram_conn_lookup_register_addr(DGRAM_CONN_LOOKUP *lookup, + const BIO_ADDR *peer, SSL *ssl) +{ + if (lookup == NULL || lookup->methods == NULL + || lookup->methods->register_conn_addr == NULL) + return 0; + return lookup->methods->register_conn_addr(lookup, peer, ssl); +} + +int ossl_dgram_conn_lookup_unregister(DGRAM_CONN_LOOKUP *lookup, + const BIO_ADDR *peer) +{ + if (lookup == NULL || lookup->methods == NULL + || lookup->methods->unregister_conn == NULL) + return 0; + return lookup->methods->unregister_conn(lookup, peer); +} + +void ossl_dgram_conn_lookup_foreach(DGRAM_CONN_LOOKUP *lookup, + ossl_dgram_conn_lookup_iter_fn cb, void *arg) +{ + if (lookup == NULL || lookup->methods == NULL + || lookup->methods->foreach == NULL) + return; + lookup->methods->foreach(lookup, cb, arg); +} + +void ossl_dgram_conn_lookup_free(DGRAM_CONN_LOOKUP *lookup) +{ + if (lookup == NULL || lookup->methods == NULL + || lookup->methods->free == NULL) + return; + lookup->methods->free(lookup); +} + +/* + * Return the number of entries currently registered. + * + * The lookup is not internally synchronised: like the other lookup + * operations, the caller must hold the lock that serialises access to it. + * Reading the count without that lock held races with concurrent + * register/unregister. + */ +size_t ossl_dgram_conn_lookup_num_items(const DGRAM_CONN_LOOKUP *lookup) +{ + if (lookup == NULL || lookup->methods == NULL + || lookup->methods->num_items == NULL) + return 0; + return lookup->methods->num_items(lookup); +} + +#endif /* OPENSSL_NO_DTLS */ diff --git a/ssl/dtls_record_rx.c b/ssl/dtls_record_rx.c new file mode 100644 index 0000000000000..e216f96395282 --- /dev/null +++ b/ssl/dtls_record_rx.c @@ -0,0 +1,105 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "ssl_local.h" + +#ifndef OPENSSL_NO_DTLS + +/* + * Creates a new DTLS_RX structure. The demuxer is + * provided and owned by the DTLS listener. + */ +DTLS_RX *ossl_dtls_rx_new(DGRAM_DEMUX *demux) +{ + DTLS_RX *rx = OPENSSL_malloc(sizeof(*rx)); + if (rx == NULL) + return NULL; + + rx->demux = demux; + ossl_list_urxe_init(&rx->urxe_pending); + rx->mutex = ossl_crypto_mutex_new(); + +#ifdef OPENSSL_THREADS + if (rx->mutex == NULL) { + OPENSSL_free(rx); + return NULL; + } +#endif + + return rx; +} + +/* + * Frees a DTLS_RX struct. The demuxer is not freed, as it is + * owned by the DTLS listener. The list is walked and freed. + */ +void ossl_dtls_rx_free(DTLS_RX *rx) +{ + DGRAM_URXE *urxe, *urxe_next; + + if (rx == NULL) + return; + + for (urxe = ossl_list_urxe_head(&rx->urxe_pending); urxe != NULL; + urxe = urxe_next) { + urxe_next = ossl_list_urxe_next(urxe); + ossl_list_urxe_remove(&rx->urxe_pending, urxe); + ossl_dgram_demux_release_urxe(rx->demux, urxe); + } + + /* + * The demuxer is not freed, as it is owned by the DTLS listener. + */ + rx->demux = NULL; + + ossl_crypto_mutex_free(&rx->mutex); + OPENSSL_free(rx); +} + +/* + * Injects a received URXE into the DTLS_RX struct. + */ +void ossl_dtls_rx_inject_urxe(DTLS_RX *rx, DGRAM_URXE *e) +{ + ossl_crypto_mutex_lock(rx->mutex); + ossl_list_urxe_insert_tail(&rx->urxe_pending, e); + ossl_crypto_mutex_unlock(rx->mutex); +} + +/* + * Release the URXE from the DTLS_RX struct. + */ +void ossl_dtls_rx_release_urxe(DTLS_RX *rx, DGRAM_URXE *e) +{ + ossl_dgram_demux_release_urxe(rx->demux, e); +} + +/* + * Reads a datagram from the DTLS_RX struct. + */ +DGRAM_URXE *ossl_dtls_read_datagram(DTLS_RX *rx) +{ + DGRAM_URXE *e; + + ossl_crypto_mutex_lock(rx->mutex); + + if (ossl_list_urxe_is_empty(&rx->urxe_pending)) { + ossl_crypto_mutex_unlock(rx->mutex); + return NULL; + } + + e = ossl_list_urxe_head(&rx->urxe_pending); + ossl_list_urxe_remove(&rx->urxe_pending, e); + e->demux_state = URXE_DEMUX_STATE_ISSUED; + + ossl_crypto_mutex_unlock(rx->mutex); + return e; +} + +#endif /* OPENSSL_NO_DTLS */ diff --git a/ssl/ech/ech_store.c b/ssl/ech/ech_store.c index dd05bf3702c66..2bd4915f1f4a1 100644 --- a/ssl/ech/ech_store.c +++ b/ssl/ech/ech_store.c @@ -254,6 +254,10 @@ static int ech_final_config_checks(OSSL_ECHSTORE_ENTRY *ee) char *lastlabel = NULL; size_t lllen; + if (vpm == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + goto err; + } /* check local support for some suite */ for (ind = 0; ind != (int)ee->nsuites; ind++) { /* diff --git a/ssl/methods.c b/ssl/methods.c index 4c7d46efdb2f8..22f0f6cab2fae 100644 --- a/ssl/methods.c +++ b/ssl/methods.c @@ -114,6 +114,10 @@ IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2, ossl_statem_accept, ossl_statem_connect, DTLSv1_2_enc_data) #endif +IMPLEMENT_dtls1_meth_func(DTLS1_3_VERSION, 0, SSL_OP_NO_DTLSv1_3, + dtlsv1_3_method, + ossl_statem_accept, + ossl_statem_connect, DTLSv1_3_enc_data) IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0, DTLS_method, ossl_statem_accept, @@ -134,6 +138,10 @@ IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2, ossl_statem_accept, ssl_undefined_function, DTLSv1_2_enc_data) #endif +IMPLEMENT_dtls1_meth_func(DTLS1_3_VERSION, 0, SSL_OP_NO_DTLSv1_3, + dtlsv1_3_server_method, + ossl_statem_accept, + ssl_undefined_function, DTLSv1_3_enc_data) IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0, DTLS_server_method, ossl_statem_accept, @@ -158,6 +166,10 @@ IMPLEMENT_dtls1_meth_func(DTLS1_2_VERSION, 0, SSL_OP_NO_DTLSv1_2, ssl_undefined_function, ossl_statem_connect, DTLSv1_2_enc_data) #endif +IMPLEMENT_dtls1_meth_func(DTLS1_3_VERSION, 0, SSL_OP_NO_DTLSv1_3, + dtlsv1_3_client_method, + ssl_undefined_function, + ossl_statem_connect, DTLSv1_3_enc_data) IMPLEMENT_dtls1_meth_func(DTLS_ANY_VERSION, 0, 0, DTLS_client_method, ssl_undefined_function, diff --git a/ssl/pqueue.c b/ssl/pqueue.c index 87918e5e2bc9e..d984de01ab550 100644 --- a/ssl/pqueue.c +++ b/ssl/pqueue.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,11 +10,6 @@ #include "ssl_local.h" #include -struct pqueue_st { - pitem *items; - int count; -}; - pitem *pitem_new(unsigned char *prio64be, void *data) { pitem *item = OPENSSL_malloc(sizeof(*item)); @@ -25,6 +20,23 @@ pitem *pitem_new(unsigned char *prio64be, void *data) memcpy(item->priority, prio64be, sizeof(item->priority)); item->data = data; item->next = NULL; + + return item; +} + +pitem *pitem_new_u64(uint64_t prio, void *data) +{ + pitem *item = OPENSSL_malloc(sizeof(*item)); + unsigned char *p_item_prio; + + if (item == NULL) + return NULL; + + p_item_prio = item->priority; + l2n8(prio, p_item_prio); + item->data = data; + item->next = NULL; + return item; } @@ -121,6 +133,15 @@ pitem *pqueue_find(pqueue *pq, unsigned char *prio64be) return found; } +pitem *pqueue_find_u64(pqueue *pq, uint64_t prio) +{ + unsigned char prio64be[8], *p_prio64be = prio64be; + + l2n8(prio, p_prio64be); + + return pqueue_find(pq, prio64be); +} + pitem *pqueue_iterator(pqueue *pq) { return pqueue_peek(pq); diff --git a/ssl/quic/qlog.c b/ssl/quic/qlog.c index a09c76ca2afc1..6b5a9b4af3c5d 100644 --- a/ssl/quic/qlog.c +++ b/ssl/quic/qlog.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,6 +8,7 @@ */ #include +#include #include "internal/qlog.h" #include "internal/json_enc.h" #include "internal/common.h" @@ -131,12 +132,21 @@ QLOG *ossl_qlog_new_from_env(const QLOG_TRACE_INFO *info) if (qlogdir_sep != '\0') filename[l++] = qlogdir_sep; - for (i = 0; i < info->odcid.id_len; ++i) - l += BIO_snprintf(filename + l, strl - l, "%02x", info->odcid.id[i]); + for (i = 0; i < info->odcid.id_len; ++i) { + int n = snprintf(filename + l, strl - l, "%02x", info->odcid.id[i]); - l += BIO_snprintf(filename + l, strl - l, "_%s.sqlog", + if (n < 0 || (size_t)n >= strl - l) + goto err; + l += n; + } + + int n = snprintf(filename + l, strl - l, "_%s.sqlog", info->is_server ? "server" : "client"); + if (n < 0 || (size_t)n >= strl - l) + goto err; + l += n; + qlog = ossl_qlog_new(info); if (qlog == NULL) goto err; @@ -340,7 +350,7 @@ static void qlog_event_seq_header(QLOG *qlog) if (qlog->info.override_impl_name != NULL) { p = qlog->info.override_impl_name; } else { - BIO_snprintf(buf, sizeof(buf), "OpenSSL/%s (%s)", + snprintf(buf, sizeof(buf), "OpenSSL/%s (%s)", OpenSSL_version(OPENSSL_FULL_VERSION_STRING), OpenSSL_version(OPENSSL_PLATFORM) + 10); } diff --git a/ssl/quic/qlog_event_helpers.c b/ssl/quic/qlog_event_helpers.c index 83eebe82ad4f8..bbe6d5f4520bb 100644 --- a/ssl/quic/qlog_event_helpers.c +++ b/ssl/quic/qlog_event_helpers.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,6 +7,8 @@ * https://www.openssl.org/source/license.html */ +#include + #include "internal/qlog_event_helpers.h" #include "internal/common.h" #include "internal/packet.h" @@ -130,7 +132,7 @@ void ossl_qlog_event_connectivity_connection_closed(QLOG *qlog, if (tcause->error_code >= OSSL_QUIC_ERR_CRYPTO_ERR_BEGIN && tcause->error_code <= OSSL_QUIC_ERR_CRYPTO_ERR_END) { - BIO_snprintf(ce, sizeof(ce), "crypto_error_0x%03llx", + snprintf(ce, sizeof(ce), "crypto_error_0x%03llx", (unsigned long long)tcause->error_code); m = ce; } diff --git a/ssl/quic/quic_ackm.c b/ssl/quic/quic_ackm.c index 24acb8635cbb7..5da8af882adee 100644 --- a/ssl/quic/quic_ackm.c +++ b/ssl/quic/quic_ackm.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -1135,6 +1135,38 @@ int ossl_ackm_on_tx_packet(OSSL_ACKM *ackm, OSSL_ACKM_TX_PKT *pkt) return 1; } +int ossl_ackm_on_tx_ack_only_packet(OSSL_ACKM *ackm, OSSL_ACKM_TX_PKT *pkt) +{ + struct tx_pkt_history_st *h; + unsigned int pkt_space; + + if (pkt == NULL || pkt->pkt_space >= QUIC_PN_SPACE_NUM) + return 0; + + /* + * A packet containing only an ACK frame must not be treated as + * in-flight or ack-eliciting; if it were, ossl_ackm_on_tx_packet() + * below would (correctly) perform bytes-in-flight/timer/CC bookkeeping + * for a packet we are about to discard from history, which would be + * incorrect. + */ + if (pkt->is_inflight || pkt->is_ack_eliciting) + return 0; + + pkt_space = pkt->pkt_space; + + /* + * No one can expect ACK for packet which carries ACK frames only + * (ack_only packet). The ACKM does not need to keep record for ack_only + * packet. For ack_only packet the ACKM manager must be updated by the + * highest packet number which got sent. + */ + h = get_tx_history(ackm, pkt_space); + h->highest_sent = pkt->pkt_num; + + return 1; +} + int ossl_ackm_on_rx_datagram(OSSL_ACKM *ackm, size_t num_bytes) { /* No-op on the client. */ diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index aaabf5a432eb7..117bf50eb15c1 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -169,7 +169,7 @@ static int ch_init(QUIC_CHANNEL *ch) qtx_args.get_qlog_cb = ch_get_qlog_cb; qtx_args.get_qlog_cb_arg = ch; qtx_args.mdpl = QUIC_MIN_INITIAL_DGRAM_LEN; - ch->rx_max_udp_payload_size = qtx_args.mdpl; + ch->rx_max_udp_payload_size = QUIC_DEFAULT_MAX_UDP_PAYLOAD_SIZE; ch->ping_deadline = ossl_time_infinite(); @@ -582,20 +582,19 @@ SSL *ossl_quic_channel_get0_tls(QUIC_CHANNEL *ch) return ch->tls; } -void ossl_quic_channel_set0_tls(QUIC_CHANNEL *ch, SSL *ssl) +int ossl_quic_channel_set0_tls(QUIC_CHANNEL *ch, SSL *ssl) { - SSL_free(ch->tls); - ch->tls = ssl; -#ifndef OPENSSL_NO_QLOG /* - * If we're using qlog, make sure the tls gets further configured properly + * Rebind the handshake layer first, so that a failure leaves the channel + * entirely unmodified rather than with a TLS connection the handshake + * layer does not know about. */ - ch->use_qlog = 1; - if (ch->tls->ctx->qlog_title != NULL) { - OPENSSL_free(ch->qlog_title); - ch->qlog_title = OPENSSL_strdup(ch->tls->ctx->qlog_title); - } -#endif + if (!ossl_assert(ch != NULL && ssl != NULL && ch->tls == NULL) + || !ossl_quic_tls_set0_ssl(ch->qtls, ssl)) + return 0; + + ch->tls = ssl; + return 1; } static void free_buf_mem(unsigned char *buf, size_t buf_len, void *arg) @@ -3325,7 +3324,8 @@ static int ch_enqueue_retire_conn_id(QUIC_CHANNEL *ch, uint64_t seq_num) WPACKET wpkt; size_t l; - ossl_quic_srtm_remove(ch->srtm, ch, seq_num); + if (!ossl_quic_srtm_remove(ch->srtm, ch, seq_num, NULL)) + goto err; if ((buf_mem = BUF_MEM_new()) == NULL) goto err; @@ -4023,6 +4023,8 @@ void ossl_quic_channel_set_incoming_stream_auto_reject(QUIC_CHANNEL *ch, void ossl_quic_channel_reject_stream(QUIC_CHANNEL *ch, QUIC_STREAM *qs) { + OSSL_RTT_INFO rtt_info; + ossl_quic_stream_map_stop_sending_recv_part(&ch->qsm, qs, ch->incoming_stream_auto_reject_aec); @@ -4030,6 +4032,15 @@ void ossl_quic_channel_reject_stream(QUIC_CHANNEL *ch, QUIC_STREAM *qs) ch->incoming_stream_auto_reject_aec); qs->deleted = 1; + /* + * A rejected stream is never placed on the accept queue, so it would + * otherwise never be retired and would consume the peer's stream credit + * for the lifetime of the connection. + */ + ossl_statm_get_rtt_info(ossl_quic_channel_get_statm(ch), &rtt_info); + ossl_quic_stream_map_retire_stream_credit(&ch->qsm, qs, + rtt_info.smoothed_rtt); + ossl_quic_stream_map_update_state(&ch->qsm, qs); } diff --git a/ssl/quic/quic_demux.c b/ssl/quic/quic_demux.c index 8fb4adb8c1db9..6a7abe762e452 100644 --- a/ssl/quic/quic_demux.c +++ b/ssl/quic/quic_demux.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -9,21 +9,26 @@ #include "internal/quic_demux.h" #include "internal/quic_wire_pkt.h" +#include "internal/dgram_demux.h" #include "internal/common.h" #include #include -#define URXE_DEMUX_STATE_FREE 0 /* on urx_free list */ -#define URXE_DEMUX_STATE_PENDING 1 /* on urx_pending list */ -#define URXE_DEMUX_STATE_ISSUED 2 /* on neither list */ - -#define DEMUX_MAX_MSGS_PER_CALL 32 - -#define DEMUX_DEFAULT_MTU 1500 - +/* + * QUIC Demuxer Implementation + * =========================== + * + * The QUIC demuxer wraps the generic DGRAM_DEMUX to add QUIC-specific + * functionality: + * - Extraction of DCID from the first packet in each datagram + * - QUIC-specific callback signature that includes the DCID + * + * QUIC_URXE is a typedef to DGRAM_URXE, so all URXE management is delegated + * to the underlying DGRAM_DEMUX. + */ struct quic_demux_st { - /* The underlying transport BIO with datagram semantics. */ - BIO *net_bio; + /* The underlying generic datagram demuxer. */ + DGRAM_DEMUX *dgram_demux; /* * QUIC short packets do not contain the length of the connection ID field, @@ -32,41 +37,38 @@ struct quic_demux_st { */ size_t short_conn_id_len; - /* - * Our current understanding of the upper bound on an incoming datagram size - * in bytes. - */ - size_t mtu; - - /* The datagram_id to use for the next datagram we receive. */ - uint64_t next_datagram_id; - - /* Time retrieval callback. */ - OSSL_TIME (*now)(void *arg); - void *now_arg; - - /* The default packet handler, if any. */ + /* The QUIC-specific packet handler callback (includes DCID). */ ossl_quic_demux_cb_fn *default_cb; void *default_cb_arg; +}; - /* - * List of URXEs which are not currently in use (i.e., not filled with - * unconsumed data). These are moved to the pending list as they are filled. - */ - QUIC_URXE_LIST urx_free; +/* + * Internal callback that wraps the QUIC callback. This is called by + * DGRAM_DEMUX for each received datagram. We extract the DCID and forward + * to the QUIC-specific callback. + */ +static void quic_demux_dgram_cb(DGRAM_URXE *e, void *arg) +{ + QUIC_DEMUX *demux = arg; - /* - * List of URXEs which are filled with received encrypted data. These are - * removed from this list as we invoke the callbacks for each of them. They - * are then not on any list managed by us; we forget about them until our - * user calls ossl_quic_demux_release_urxe to return the URXE to us, at - * which point we add it to the free list. - */ - QUIC_URXE_LIST urx_pending; + if (demux->default_cb != NULL) { + QUIC_CONN_ID dst_conn_id; + int dst_conn_id_ok; - /* Whether to use local address support. */ - char use_local_addr; -}; + /* Extract DCID from the first packet in the datagram. */ + dst_conn_id_ok = ossl_quic_wire_get_pkt_hdr_dst_conn_id( + ossl_quic_urxe_data(e), + e->data_len, + demux->short_conn_id_len, + &dst_conn_id); + + demux->default_cb(e, demux->default_cb_arg, + dst_conn_id_ok ? &dst_conn_id : NULL); + } else { + /* No handler set, release the URXE back to the demuxer. */ + ossl_dgram_demux_release_urxe(demux->dgram_demux, e); + } +} QUIC_DEMUX *ossl_quic_demux_new(BIO *net_bio, size_t short_conn_id_len, @@ -79,30 +81,24 @@ QUIC_DEMUX *ossl_quic_demux_new(BIO *net_bio, if (demux == NULL) return NULL; - demux->net_bio = net_bio; demux->short_conn_id_len = short_conn_id_len; - /* We update this if possible when we get a BIO. */ - demux->mtu = DEMUX_DEFAULT_MTU; - demux->now = now; - demux->now_arg = now_arg; - - if (net_bio != NULL - && BIO_dgram_get_local_addr_cap(net_bio) - && BIO_dgram_set_local_addr_enable(net_bio, 1)) - demux->use_local_addr = 1; - return demux; -} + /* Create the underlying generic demuxer (no internal locking for QUIC). */ + demux->dgram_demux = ossl_dgram_demux_new(net_bio, 0, now, now_arg); + if (demux->dgram_demux == NULL) { + OPENSSL_free(demux); + return NULL; + } -static void demux_free_urxl(QUIC_URXE_LIST *l) -{ - QUIC_URXE *e, *enext; + /* + * Set our internal wrapper callback on the DGRAM_DEMUX. This will be + * called for every received datagram, and we'll extract the DCID and + * forward to the QUIC-specific callback. + */ + ossl_dgram_demux_set_default_handler(demux->dgram_demux, + quic_demux_dgram_cb, demux); - for (e = ossl_list_urxe_head(l); e != NULL; e = enext) { - enext = ossl_list_urxe_next(e); - ossl_list_urxe_remove(l, e); - OPENSSL_free(e); - } + return demux; } void ossl_quic_demux_free(QUIC_DEMUX *demux) @@ -110,38 +106,18 @@ void ossl_quic_demux_free(QUIC_DEMUX *demux) if (demux == NULL) return; - /* Free all URXEs we are holding. */ - demux_free_urxl(&demux->urx_free); - demux_free_urxl(&demux->urx_pending); - + ossl_dgram_demux_free(demux->dgram_demux); OPENSSL_free(demux); } void ossl_quic_demux_set_bio(QUIC_DEMUX *demux, BIO *net_bio) { - unsigned int mtu; - - demux->net_bio = net_bio; - - if (net_bio != NULL) { - /* - * Try to determine our MTU if possible. The BIO is not required to - * support this, in which case we remain at the last known MTU, or our - * initial default. - */ - mtu = BIO_dgram_get_mtu(net_bio); - if (mtu >= QUIC_MIN_INITIAL_DGRAM_LEN) - ossl_quic_demux_set_mtu(demux, mtu); /* best effort */ - } + ossl_dgram_demux_set_bio(demux->dgram_demux, net_bio); } int ossl_quic_demux_set_mtu(QUIC_DEMUX *demux, unsigned int mtu) { - if (mtu < QUIC_MIN_INITIAL_DGRAM_LEN) - return 0; - - demux->mtu = mtu; - return 1; + return ossl_dgram_demux_set_mtu(demux->dgram_demux, mtu); } void ossl_quic_demux_set_default_handler(QUIC_DEMUX *demux, @@ -152,257 +128,25 @@ void ossl_quic_demux_set_default_handler(QUIC_DEMUX *demux, demux->default_cb_arg = cb_arg; } -static QUIC_URXE *demux_alloc_urxe(size_t alloc_len) -{ - QUIC_URXE *e; - - if (alloc_len >= SIZE_MAX - sizeof(QUIC_URXE)) - return NULL; - - e = OPENSSL_malloc(sizeof(QUIC_URXE) + alloc_len); - if (e == NULL) - return NULL; - - ossl_list_urxe_init_elem(e); - e->alloc_len = alloc_len; - e->data_len = 0; - return e; -} - -static QUIC_URXE *demux_resize_urxe(QUIC_DEMUX *demux, QUIC_URXE *e, - size_t new_alloc_len) -{ - QUIC_URXE *e2, *prev; - - if (!ossl_assert(e->demux_state == URXE_DEMUX_STATE_FREE)) - /* Never attempt to resize a URXE which is not on the free list. */ - return NULL; - - prev = ossl_list_urxe_prev(e); - ossl_list_urxe_remove(&demux->urx_free, e); - - if (new_alloc_len >= SIZE_MAX - sizeof(QUIC_URXE)) - return NULL; - - e2 = OPENSSL_realloc(e, sizeof(QUIC_URXE) + new_alloc_len); - if (e2 == NULL) { - /* Failed to resize, abort. */ - if (prev == NULL) - ossl_list_urxe_insert_head(&demux->urx_free, e); - else - ossl_list_urxe_insert_after(&demux->urx_free, prev, e); - - return NULL; - } - - if (prev == NULL) - ossl_list_urxe_insert_head(&demux->urx_free, e2); - else - ossl_list_urxe_insert_after(&demux->urx_free, prev, e2); - - e2->alloc_len = new_alloc_len; - return e2; -} - -static QUIC_URXE *demux_reserve_urxe(QUIC_DEMUX *demux, QUIC_URXE *e, - size_t alloc_len) -{ - return e->alloc_len < alloc_len ? demux_resize_urxe(demux, e, alloc_len) : e; -} - -static int demux_ensure_free_urxe(QUIC_DEMUX *demux, size_t min_num_free) -{ - QUIC_URXE *e; - - while (ossl_list_urxe_num(&demux->urx_free) < min_num_free) { - e = demux_alloc_urxe(demux->mtu); - if (e == NULL) - return 0; - - ossl_list_urxe_insert_tail(&demux->urx_free, e); - e->demux_state = URXE_DEMUX_STATE_FREE; - } - - return 1; -} - -/* - * Receive datagrams from network, placing them into URXEs. - * - * Returns 1 on success or 0 on failure. - * - * Precondition: at least one URXE is free - * Precondition: there are no pending URXEs - */ -static int demux_recv(QUIC_DEMUX *demux) -{ - BIO_MSG msg[DEMUX_MAX_MSGS_PER_CALL]; - size_t rd, i; - QUIC_URXE *urxe = ossl_list_urxe_head(&demux->urx_free), *unext; - OSSL_TIME now; - - /* This should never be called when we have any pending URXE. */ - assert(ossl_list_urxe_head(&demux->urx_pending) == NULL); - assert(urxe->demux_state == URXE_DEMUX_STATE_FREE); - - if (demux->net_bio == NULL) - /* - * If no BIO is plugged in, treat this as no datagram being available. - */ - return QUIC_DEMUX_PUMP_RES_TRANSIENT_FAIL; - - /* - * Opportunistically receive as many messages as possible in a single - * syscall, determined by how many free URXEs are available. - */ - for (i = 0; i < (ossl_ssize_t)OSSL_NELEM(msg); - ++i, urxe = ossl_list_urxe_next(urxe)) { - if (urxe == NULL) { - /* We need at least one URXE to receive into. */ - if (!ossl_assert(i > 0)) - return QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL; - - break; - } - - /* Ensure the URXE is big enough. */ - urxe = demux_reserve_urxe(demux, urxe, demux->mtu); - if (urxe == NULL) - /* Allocation error, fail. */ - return QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL; - - /* Ensure we zero any fields added to BIO_MSG at a later date. */ - memset(&msg[i], 0, sizeof(BIO_MSG)); - msg[i].data = ossl_quic_urxe_data(urxe); - msg[i].data_len = urxe->alloc_len; - msg[i].peer = &urxe->peer; - BIO_ADDR_clear(&urxe->peer); - if (demux->use_local_addr) - msg[i].local = &urxe->local; - else - BIO_ADDR_clear(&urxe->local); - } - - ERR_set_mark(); - if (!BIO_recvmmsg(demux->net_bio, msg, sizeof(BIO_MSG), i, 0, &rd)) { - if (BIO_err_is_non_fatal(ERR_peek_last_error())) { - /* Transient error, clear the error and stop. */ - ERR_pop_to_mark(); - return QUIC_DEMUX_PUMP_RES_TRANSIENT_FAIL; - } else { - /* Non-transient error, do not clear the error. */ - ERR_clear_last_mark(); - return QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL; - } - } - - ERR_clear_last_mark(); - now = demux->now != NULL ? demux->now(demux->now_arg) : ossl_time_zero(); - - urxe = ossl_list_urxe_head(&demux->urx_free); - for (i = 0; i < rd; ++i, urxe = unext) { - unext = ossl_list_urxe_next(urxe); - /* Set URXE with actual length of received datagram. */ - urxe->data_len = msg[i].data_len; - /* Time we received datagram. */ - urxe->time = now; - urxe->datagram_id = demux->next_datagram_id++; - /* Move from free list to pending list. */ - ossl_list_urxe_remove(&demux->urx_free, urxe); - ossl_list_urxe_insert_tail(&demux->urx_pending, urxe); - urxe->demux_state = URXE_DEMUX_STATE_PENDING; - } - - return QUIC_DEMUX_PUMP_RES_OK; -} - -/* Extract destination connection ID from the first packet in a datagram. */ -static int demux_identify_conn_id(QUIC_DEMUX *demux, - QUIC_URXE *e, - QUIC_CONN_ID *dst_conn_id) -{ - return ossl_quic_wire_get_pkt_hdr_dst_conn_id(ossl_quic_urxe_data(e), - e->data_len, - demux->short_conn_id_len, - dst_conn_id); -} - -/* - * Process a single pending URXE. - * Returning 1 on success, 0 on failure. - */ -static int demux_process_pending_urxe(QUIC_DEMUX *demux, QUIC_URXE *e) -{ - QUIC_CONN_ID dst_conn_id; - int dst_conn_id_ok = 0; - - /* The next URXE we process should be at the head of the pending list. */ - if (!ossl_assert(e == ossl_list_urxe_head(&demux->urx_pending))) - return 0; - - assert(e->demux_state == URXE_DEMUX_STATE_PENDING); - - /* Determine the DCID of the first packet in the datagram. */ - dst_conn_id_ok = demux_identify_conn_id(demux, e, &dst_conn_id); - - ossl_list_urxe_remove(&demux->urx_pending, e); - if (demux->default_cb != NULL) { - /* - * Pass to default handler for routing. The URXE now belongs to the - * callback. - */ - e->demux_state = URXE_DEMUX_STATE_ISSUED; - demux->default_cb(e, demux->default_cb_arg, - dst_conn_id_ok ? &dst_conn_id : NULL); - } else { - /* Discard. */ - ossl_list_urxe_insert_tail(&demux->urx_free, e); - e->demux_state = URXE_DEMUX_STATE_FREE; - } - - return 1; /* keep processing pending URXEs */ -} - -/* Process pending URXEs to generate callbacks. */ -static int demux_process_pending_urxl(QUIC_DEMUX *demux) -{ - QUIC_URXE *e; - int ret; - - while ((e = ossl_list_urxe_head(&demux->urx_pending)) != NULL) - if ((ret = demux_process_pending_urxe(demux, e)) <= 0) - return ret; - - return 1; -} - -/* - * Drain the pending URXE list, processing any pending URXEs by making their - * callbacks. If no URXEs are pending, a network read is attempted first. - */ int ossl_quic_demux_pump(QUIC_DEMUX *demux) { int ret; - if (ossl_list_urxe_head(&demux->urx_pending) == NULL) { - ret = demux_ensure_free_urxe(demux, DEMUX_MAX_MSGS_PER_CALL); - if (ret != 1) - return QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL; + ret = ossl_dgram_demux_pump(demux->dgram_demux); - ret = demux_recv(demux); - if (ret != QUIC_DEMUX_PUMP_RES_OK) - return ret; - - /* - * If demux_recv returned successfully, we should always have something. - */ - assert(ossl_list_urxe_head(&demux->urx_pending) != NULL); - } - - if ((ret = demux_process_pending_urxl(demux)) <= 0) + /* + * Map DGRAM_DEMUX_PUMP_RES_* to QUIC_DEMUX_PUMP_RES_*. The values are + * identical, but this provides documentation and future-proofing. + */ + switch (ret) { + case DGRAM_DEMUX_PUMP_RES_OK: + return QUIC_DEMUX_PUMP_RES_OK; + case DGRAM_DEMUX_PUMP_RES_TRANSIENT_FAIL: + return QUIC_DEMUX_PUMP_RES_TRANSIENT_FAIL; + case DGRAM_DEMUX_PUMP_RES_PERMANENT_FAIL: + default: return QUIC_DEMUX_PUMP_RES_PERMANENT_FAIL; - - return QUIC_DEMUX_PUMP_RES_OK; + } } /* Artificially inject a packet into the demuxer for testing purposes. */ @@ -412,66 +156,22 @@ int ossl_quic_demux_inject(QUIC_DEMUX *demux, const BIO_ADDR *peer, const BIO_ADDR *local) { - int ret; - QUIC_URXE *urxe; - - ret = demux_ensure_free_urxe(demux, 1); - if (ret != 1) - return 0; - - urxe = ossl_list_urxe_head(&demux->urx_free); - - assert(urxe->demux_state == URXE_DEMUX_STATE_FREE); - - urxe = demux_reserve_urxe(demux, urxe, buf_len); - if (urxe == NULL) - return 0; - - memcpy(ossl_quic_urxe_data(urxe), buf, buf_len); - urxe->data_len = buf_len; - - if (peer != NULL) - urxe->peer = *peer; - else - BIO_ADDR_clear(&urxe->peer); - - if (local != NULL) - urxe->local = *local; - else - BIO_ADDR_clear(&urxe->local); - - urxe->time - = demux->now != NULL ? demux->now(demux->now_arg) : ossl_time_zero(); - - /* Move from free list to pending list. */ - ossl_list_urxe_remove(&demux->urx_free, urxe); - urxe->datagram_id = demux->next_datagram_id++; - ossl_list_urxe_insert_tail(&demux->urx_pending, urxe); - urxe->demux_state = URXE_DEMUX_STATE_PENDING; - - return demux_process_pending_urxl(demux) > 0; + return ossl_dgram_demux_inject(demux->dgram_demux, buf, buf_len, + peer, local); } /* Called by our user to return a URXE to the free list. */ -void ossl_quic_demux_release_urxe(QUIC_DEMUX *demux, - QUIC_URXE *e) +void ossl_quic_demux_release_urxe(QUIC_DEMUX *demux, QUIC_URXE *e) { - assert(ossl_list_urxe_prev(e) == NULL && ossl_list_urxe_next(e) == NULL); - assert(e->demux_state == URXE_DEMUX_STATE_ISSUED); - ossl_list_urxe_insert_tail(&demux->urx_free, e); - e->demux_state = URXE_DEMUX_STATE_FREE; + ossl_dgram_demux_release_urxe(demux->dgram_demux, e); } -void ossl_quic_demux_reinject_urxe(QUIC_DEMUX *demux, - QUIC_URXE *e) +void ossl_quic_demux_reinject_urxe(QUIC_DEMUX *demux, QUIC_URXE *e) { - assert(ossl_list_urxe_prev(e) == NULL && ossl_list_urxe_next(e) == NULL); - assert(e->demux_state == URXE_DEMUX_STATE_ISSUED); - ossl_list_urxe_insert_head(&demux->urx_pending, e); - e->demux_state = URXE_DEMUX_STATE_PENDING; + ossl_dgram_demux_reinject_urxe(demux->dgram_demux, e); } int ossl_quic_demux_has_pending(const QUIC_DEMUX *demux) { - return ossl_list_urxe_head(&demux->urx_pending) != NULL; + return ossl_dgram_demux_has_pending(demux->dgram_demux); } diff --git a/ssl/quic/quic_engine.c b/ssl/quic/quic_engine.c index 370b9c3987f17..f6a9da8134961 100644 --- a/ssl/quic/quic_engine.c +++ b/ssl/quic/quic_engine.c @@ -136,8 +136,8 @@ void ossl_quic_engine_update_poll_descriptors(QUIC_ENGINE *qeng, int force) * the engine level in future when we can have multiple ports. This is not * important currently as the port list has a single entry. */ - OSSL_LIST_FOREACH(port, port, &qeng->port_list) - ossl_quic_port_update_poll_descriptors(port, force); + OSSL_LIST_FOREACH (port, port, &qeng->port_list) + ossl_quic_port_update_poll_descriptors(port, force); } /* @@ -185,8 +185,7 @@ static void qeng_tick(QUIC_TICK_RESULT *res, void *arg, uint32_t flags) return; /* Iterate through all ports and service them. */ - OSSL_LIST_FOREACH(port, port, &qeng->port_list) - { + OSSL_LIST_FOREACH (port, port, &qeng->port_list) { QUIC_TICK_RESULT subr = { 0 }; ossl_quic_port_subtick(port, &subr, flags); diff --git a/ssl/quic/quic_fifd.c b/ssl/quic/quic_fifd.c index e80483b501d72..0d99a8748a780 100644 --- a/ssl/quic/quic_fifd.c +++ b/ssl/quic/quic_fifd.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -78,17 +78,21 @@ static void on_acked(void *arg) sstream = fifd->get_sstream_by_id(chunks[i].stream_id, pkt->ackm_pkt.pkt_space, fifd->get_sstream_by_id_arg); - if (sstream == NULL) - continue; - if (chunks[i].end >= chunks[i].start) - /* coverity[check_return]: Best effort - we cannot fail here. */ - ossl_quic_sstream_mark_acked(sstream, - chunks[i].start, chunks[i].end); + if (sstream != NULL) { + if (chunks[i].end >= chunks[i].start) + /* coverity[check_return]: Best effort - we cannot fail here. */ + ossl_quic_sstream_mark_acked(sstream, + chunks[i].start, chunks[i].end); - if (chunks[i].has_fin && chunks[i].stream_id != UINT64_MAX) - ossl_quic_sstream_mark_acked_fin(sstream); + if (chunks[i].has_fin && chunks[i].stream_id != UINT64_MAX) + ossl_quic_sstream_mark_acked_fin(sstream); + } + /* + * Resetting the send part frees the send stream, so these must be + * confirmed even when it is already gone. + */ if (chunks[i].has_stop_sending && chunks[i].stream_id != UINT64_MAX) fifd->confirm_frame(OSSL_QUIC_FRAME_TYPE_STOP_SENDING, chunks[i].stream_id, pkt, @@ -99,7 +103,7 @@ static void on_acked(void *arg) chunks[i].stream_id, pkt, fifd->confirm_frame_arg); - if (ossl_quic_sstream_is_totally_acked(sstream)) + if (sstream != NULL && ossl_quic_sstream_is_totally_acked(sstream)) fifd->sstream_updated(chunks[i].stream_id, fifd->sstream_updated_arg); } diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index 087c0dd582aa6..6ea7734b0993f 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -307,8 +307,10 @@ static int expect_quic_as(const SSL *s, QCTX *ctx, uint32_t flags) case SSL_TYPE_QUIC_CONNECTION: qc = (QUIC_CONNECTION *)s; ctx->obj = &qc->obj; - ctx->qd = qc->domain; - ctx->ql = qc->listener; /* never changes, so can be read without lock */ + ctx->qd = qc->domain != NULL + ? qc->domain + : (qc->listener != NULL ? qc->listener->domain : NULL); + ctx->ql = qc->listener; ctx->qc = qc; if ((flags & QCTX_AUTO_S) != 0) { @@ -357,7 +359,11 @@ static int expect_quic_as(const SSL *s, QCTX *ctx, uint32_t flags) xso = (QUIC_XSO *)s; ctx->obj = &xso->obj; - ctx->qd = xso->conn->domain; + ctx->qd = xso->conn->domain != NULL + ? xso->conn->domain + : (xso->conn->listener != NULL + ? xso->conn->listener->domain + : NULL); ctx->ql = xso->conn->listener; ctx->qc = xso->conn; ctx->xso = xso; @@ -2149,6 +2155,23 @@ struct quic_wait_for_stream_args { uint64_t expect_id; }; +QUIC_NEEDS_LOCK +static QUIC_STREAM *quic_get_incoming_default_stream(QUIC_CONNECTION *qc, + uint64_t expect_id) +{ + QUIC_STREAM_MAP *qsm = ossl_quic_channel_get_qsm(qc->ch); + QUIC_STREAM *qs; + + qs = ossl_quic_stream_map_get_by_id(qsm, + expect_id | QUIC_STREAM_DIR_BIDI); + if (qs == NULL) + qs = ossl_quic_stream_map_get_by_id(qsm, + expect_id | QUIC_STREAM_DIR_UNI); + + /* Auto-rejected streams remain in the map until garbage collection. */ + return qs != NULL && qs->accept_node.next != NULL ? qs : NULL; +} + QUIC_NEEDS_LOCK static int quic_wait_for_stream(void *arg) { @@ -2160,11 +2183,7 @@ static int quic_wait_for_stream(void *arg) return -1; } - args->qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(args->qc->ch), - args->expect_id | QUIC_STREAM_DIR_BIDI); - if (args->qs == NULL) - args->qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(args->qc->ch), - args->expect_id | QUIC_STREAM_DIR_UNI); + args->qs = quic_get_incoming_default_stream(args->qc, args->expect_id); if (args->qs != NULL) return 1; /* stream now exists */ @@ -2201,17 +2220,12 @@ static int qc_wait_for_default_xso_for_read(QCTX *ctx, int peek) ? QUIC_STREAM_INITIATOR_CLIENT : QUIC_STREAM_INITIATOR_SERVER; - qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(qc->ch), - expect_id | QUIC_STREAM_DIR_BIDI); - if (qs == NULL) - qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(qc->ch), - expect_id | QUIC_STREAM_DIR_UNI); + qs = quic_get_incoming_default_stream(qc, expect_id); if (qs == NULL) { qctx_maybe_autotick(ctx); - qs = ossl_quic_stream_map_get_by_id(ossl_quic_channel_get_qsm(qc->ch), - expect_id); + qs = quic_get_incoming_default_stream(qc, expect_id); } if (qs == NULL) { @@ -3991,6 +4005,33 @@ static int qc_getset_max_ack_delay(QCTX *ctx, uint32_t class_, return ret; } +QUIC_TAKES_LOCK +static int qc_getset_max_pending_channels(QCTX *ctx, uint32_t class_, + uint64_t *p_value_out, uint64_t *p_value_in) +{ + int ret = 0; + uint64_t value_out = 0; + + qctx_lock(ctx); + + if (class_ == SSL_VALUE_CLASS_GENERIC && ctx->is_listener) { + value_out = ossl_quic_port_get_max_pending_channels(ctx->ql->port); + if (p_value_in != NULL) + ossl_quic_port_set_max_pending_channels(ctx->ql->port, *p_value_in); + ret = 1; + } else { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS, NULL); + ret = 0; + } + + qctx_unlock(ctx); + + if (ret && p_value_out != NULL) + *p_value_out = value_out; + + return ret; +} + QUIC_TAKES_LOCK static int qc_get_stream_avail(QCTX *ctx, uint32_t class_, int is_uni, int is_remote, @@ -4133,6 +4174,7 @@ static int expect_quic_for_value(SSL *s, QCTX *ctx, uint32_t id) case SSL_VALUE_QUIC_WINDOWUSTR: case SSL_VALUE_QUIC_ACK_DELAY_EXPONENT: case SSL_VALUE_QUIC_ACK_DELAY_MAX: + case SSL_VALUE_QUIC_MAX_PENDING_CONNS: return expect_quic_cl(s, ctx); default: return expect_quic_conn_only(s, ctx); @@ -4167,6 +4209,8 @@ int ossl_quic_get_value_uint(SSL *s, uint32_t class_, uint32_t id, return qc_getset_ack_delay_exponent(&ctx, class_, value, NULL); case SSL_VALUE_QUIC_ACK_DELAY_MAX: return qc_getset_max_ack_delay(&ctx, class_, value, NULL); + case SSL_VALUE_QUIC_MAX_PENDING_CONNS: + return qc_getset_max_pending_channels(&ctx, class_, value, NULL); case SSL_VALUE_QUIC_STREAM_BIDI_LOCAL_AVAIL: return qc_get_stream_avail(&ctx, class_, /*uni=*/0, /*remote=*/0, value); @@ -4225,6 +4269,8 @@ int ossl_quic_set_value_uint(SSL *s, uint32_t class_, uint32_t id, return qc_getset_ack_delay_exponent(&ctx, class_, NULL, &value); case SSL_VALUE_QUIC_ACK_DELAY_MAX: return qc_getset_max_ack_delay(&ctx, class_, NULL, &value); + case SSL_VALUE_QUIC_MAX_PENDING_CONNS: + return qc_getset_max_pending_channels(&ctx, class_, NULL, &value); default: return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, @@ -4979,10 +5025,16 @@ int ossl_quic_peeloff_conn(SSL *listener, SSL *new_conn) { QCTX lctx; QCTX cctx; - QUIC_CHANNEL *new_ch; + QUIC_CHANNEL *new_ch, *old_ch, *popped_ch; + QUIC_PORT *old_port; + QUIC_ENGINE *old_engine; +#if defined(OPENSSL_THREADS) + CRYPTO_MUTEX *old_mutex = NULL; +#endif QUIC_CONNECTION *qc = NULL; QUIC_LISTENER *ql = NULL; SSL *tls = NULL; + SSL_CONNECTION *tls_conn = NULL; int ret = 0; if (!expect_quic_listener(listener, &lctx)) @@ -4991,6 +5043,30 @@ int ossl_quic_peeloff_conn(SSL *listener, SSL *new_conn) if (!expect_quic_c(new_conn, &cctx)) return -1; +#if !defined(OPENSSL_NO_QUIC_THREAD_ASSIST) + if (cctx.qc->is_thread_assisted) { + QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_PASSED_INVALID_ARGUMENT, + "SSL_listen_ex requires new_conn without thread assistance"); + return -1; + } +#endif + + /* The standalone transport is replaced, so new_conn must be unused. */ + if (cctx.qc->started || cctx.qc->shutting_down + || cctx.qc->num_xso != 0 + || cctx.qc->default_xso_created + || cctx.qc->listener != NULL + || ossl_quic_port_get_net_rbio(cctx.qc->port) != NULL + || ossl_quic_port_get_net_wbio(cctx.qc->port) != NULL + || ossl_quic_channel_is_active(cctx.qc->ch) + || ossl_quic_channel_is_term_any(cctx.qc->ch) + || !cctx.obj->is_event_leader || !cctx.obj->is_port_leader + || cctx.obj->parent_obj != NULL) { + QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_PASSED_INVALID_ARGUMENT, + "SSL_listen_ex requires a fresh connection created by SSL_new()"); + return -1; + } + qctx_lock_for_io(&lctx); if (!ossl_quic_port_test_and_set_peeloff(lctx.ql->port, PEELOFF_LISTEN)) { @@ -5000,53 +5076,109 @@ int ossl_quic_peeloff_conn(SSL *listener, SSL *new_conn) goto out; } - new_ch = ossl_quic_port_pop_incoming(lctx.ql->port); - if (new_ch != NULL) { - tls = ossl_ssl_connection_new_int(ossl_quic_port_get_channel_ctx(lctx.ql->port), - new_conn, TLS_method()); - if (tls == NULL) - goto out; + /* Do all fallible setup before consuming the queued channel. */ + new_ch = ossl_quic_port_peek_incoming(lctx.ql->port); + if (new_ch == NULL) + goto out; - qc = cctx.qc; - ql = lctx.ql; - /* - * Need to ensure that we take a reference on our new listener - * so that we don't free it before this connection - */ - if (!SSL_up_ref(&ql->obj.ssl)) - goto out; + qc = cctx.qc; + ql = lctx.ql; - ossl_quic_channel_free(qc->ch); - ossl_quic_port_free(qc->port); - ossl_quic_engine_free(qc->engine); - /* - * Ensure that we point to our listener so we can drop - * the above refcount when this SSL object is freed - */ - qc->listener = ql; - qc->obj.engine = ql->engine; - qc->engine = ql->engine; - qc->port = ql->port; - qc->pending = 1; + tls = ossl_ssl_connection_new_int( + ossl_quic_port_get_channel_ctx(ql->port), new_conn, TLS_method()); + if (tls == NULL) { + /* An internal failure is not "no connection available" */ + ret = -1; + goto out; + } + + tls_conn = SSL_CONNECTION_FROM_SSL(tls); + if (tls_conn == NULL) { + QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL); + SSL_free(tls); + ret = -1; + goto out; + } + + tls_conn->s3.flags |= TLS1_FLAGS_QUIC | TLS1_FLAGS_QUIC_INTERNAL; + tls_conn->options &= OSSL_QUIC_PERMITTED_OPTIONS_CONN; + tls_conn->pha_enabled = 0; + + /* The connection keeps its listener alive. */ + if (!SSL_up_ref(&ql->obj.ssl)) { + QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL); + SSL_free(tls); + ret = -1; + goto out; + } + + /* Bind TLS before adopting the deferred incoming channel. */ + if (!ossl_quic_channel_set0_tls(new_ch, tls)) { + QUIC_RAISE_NON_NORMAL_ERROR(NULL, ERR_R_INTERNAL_ERROR, NULL); + SSL_free(tls); + SSL_free(&ql->obj.ssl); + ret = -1; + goto out; + } + + ossl_quic_channel_set_msg_callback(new_ch, + ql->obj.ssl.ctx->msg_callback, new_conn); + ossl_quic_channel_set_msg_callback_arg(new_ch, + ql->obj.ssl.ctx->msg_callback_arg); + + /* The listener lock guarantees that the queue head has not changed. */ + popped_ch = ossl_quic_port_pop_incoming(ql->port); + assert(popped_ch == new_ch); + (void)popped_ch; + + old_ch = qc->ch; + old_port = qc->port; + old_engine = qc->engine; #if defined(OPENSSL_THREADS) - ossl_crypto_mutex_free(&qc->mutex); - qc->mutex = ql->mutex; + old_mutex = qc->mutex; #endif - qc->ch = new_ch; - SSL_free(qc->tls); - ossl_quic_channel_set0_tls(new_ch, tls); - qc->tls = tls; - ossl_quic_channel_get_peer_addr(new_ch, &qc->init_peer_addr); /* best effort */ - qc->started = 1; - qc->as_server = 1; - qc->as_server_state = 1; - qc->default_stream_mode = SSL_DEFAULT_STREAM_MODE_AUTO_BIDI; - qc->default_ssl_options = ql->obj.ssl.ctx->options & OSSL_QUIC_PERMITTED_OPTIONS; - qc->incoming_stream_policy = SSL_INCOMING_STREAM_POLICY_AUTO; - qc->last_error = SSL_ERROR_NONE; - qc_update_reject_policy(qc); - ret = 1; - } + + /* Ensure that SSL_free() drops the listener reference. */ + qc->listener = ql; + qc->engine = ql->engine; + qc->port = ql->port; + /* The connection is handed to the caller, as in SSL_accept_connection() */ + qc->pending = 0; + /* Demote the standalone object into the listener's hierarchy. */ + ossl_quic_obj_reparent(&qc->obj, &ql->obj); + + /* Release the resources the connection owned as a standalone object. */ + ossl_quic_channel_free(old_ch); + quic_unref_port_bios(old_port); + ossl_quic_port_free(old_port); + ossl_quic_engine_free(old_engine); +#if defined(OPENSSL_THREADS) + /* The standalone mutex was borrowed by all three resources above. */ + qc->mutex = ql->mutex; + ossl_crypto_mutex_free(&old_mutex); +#endif + + qc->ch = new_ch; + SSL_free(qc->tls); + qc->tls = tls; + ossl_quic_channel_get_peer_addr(new_ch, + &qc->init_peer_addr); /* best effort */ + qc->started = 1; + qc->as_server = 1; + qc->as_server_state = 1; + /* Reinitialise configuration to the accepted-connection defaults. */ + qc->default_stream_mode = SSL_DEFAULT_STREAM_MODE_AUTO_BIDI; + qc->default_ssl_mode = ql->obj.ssl.ctx->mode; + qc->default_ssl_options + = ql->obj.ssl.ctx->options & OSSL_QUIC_PERMITTED_OPTIONS; + qc->incoming_stream_policy = SSL_INCOMING_STREAM_POLICY_AUTO; + qc->incoming_stream_aec = 0; + qc->last_error = SSL_ERROR_NONE; + ossl_quic_obj_set_blocking_mode(&qc->obj, QUIC_BLOCKING_MODE_INHERIT); + qc->obj.event_handling_mode = SSL_VALUE_EVENT_HANDLING_MODE_INHERIT; + qc_update_reject_policy(qc); + ret = 1; + out: qctx_unlock(&lctx); return ret; @@ -5433,9 +5565,8 @@ int ossl_quic_get_peer_token(SSL_CTX *ctx, BIO_ADDR *peer, ossl_crypto_mutex_lock(c->mutex); tok = lh_QUIC_TOKEN_retrieve(c->cache, key); - if (tok != NULL) { + if (tok != NULL && CRYPTO_UP_REF(&tok->references, &ret)) { *token = tok; - CRYPTO_UP_REF(&tok->references, &ret); rc = 1; } @@ -5917,6 +6048,19 @@ QUIC_CHANNEL *ossl_quic_conn_get_channel(SSL *s) return ctx.qc->ch; } +QUIC_PORT *ossl_quic_listener_get_port(SSL *s) +{ + QCTX ctx; + + /* + * expect listerner only + */ + if (!expect_quic_listener(s, &ctx)) + return NULL; + + return ctx.ql->port; +} + int ossl_quic_set_diag_title(SSL_CTX *ctx, const char *title) { #ifndef OPENSSL_NO_QLOG diff --git a/ssl/quic/quic_lcidm.c b/ssl/quic/quic_lcidm.c index e23c16ce44ba5..89ee95055dc1d 100644 --- a/ssl/quic/quic_lcidm.c +++ b/ssl/quic/quic_lcidm.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/ssl/quic/quic_obj.c b/ssl/quic/quic_obj.c index 0c0a3faa2ee54..2aba3fb4bdeaf 100644 --- a/ssl/quic/quic_obj.c +++ b/ssl/quic/quic_obj.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -20,11 +20,13 @@ int ossl_quic_obj_init(QUIC_OBJ *obj, QUIC_ENGINE *engine, QUIC_PORT *port) { + QUIC_OBJ *parent = (QUIC_OBJ *)parent_obj; int is_event_leader = (engine != NULL); int is_port_leader = (port != NULL); if (!ossl_assert(obj != NULL && !obj->init_done && SSL_TYPE_IS_QUIC(type) - && (parent_obj == NULL || IS_QUIC(parent_obj)))) + && (parent_obj == NULL + || (IS_QUIC(parent_obj) && parent->init_done)))) return 0; /* Event leader is always the root object. */ @@ -34,8 +36,9 @@ int ossl_quic_obj_init(QUIC_OBJ *obj, if (!ossl_ssl_init(&obj->ssl, ctx, ctx->method, type)) goto err; - obj->domain_flags = ctx->domain_flags; - obj->parent_obj = (QUIC_OBJ *)parent_obj; + obj->domain_flags + = parent != NULL ? parent->domain_flags : ctx->domain_flags; + obj->parent_obj = parent; obj->is_event_leader = is_event_leader; obj->is_port_leader = is_port_leader; obj->engine = engine; @@ -53,6 +56,21 @@ int ossl_quic_obj_init(QUIC_OBJ *obj, return 0; } +void ossl_quic_obj_reparent(QUIC_OBJ *obj, QUIC_OBJ *parent) +{ + if (!ossl_assert(obj != NULL && obj->init_done + && parent != NULL && parent->init_done + && obj->is_event_leader && obj->is_port_leader + && obj->parent_obj == NULL)) + return; + + obj->parent_obj = parent; + obj->is_event_leader = 0; + obj->is_port_leader = 0; + obj->domain_flags = parent->domain_flags; + (void)obj_update_cache(obj); +} + static int obj_update_cache(QUIC_OBJ *obj) { QUIC_OBJ *p; diff --git a/ssl/quic/quic_obj_local.h b/ssl/quic/quic_obj_local.h index d454ade330bbc..0d7627c24194b 100644 --- a/ssl/quic/quic_obj_local.h +++ b/ssl/quic/quic_obj_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -100,7 +100,7 @@ struct quic_obj_st { */ QUIC_PORT *port; - /* SSL_DOMAIN_FLAG values taken from SSL_CTX at construction time. */ + /* Effective SSL_DOMAIN_FLAG values inherited from the object hierarchy. */ uint64_t domain_flags; unsigned int init_done : 1; @@ -155,6 +155,9 @@ int ossl_quic_obj_init(QUIC_OBJ *obj, QUIC_ENGINE *engine, QUIC_PORT *port); +/* Reparent a standalone leader; the caller must release its old resources. */ +void ossl_quic_obj_reparent(QUIC_OBJ *obj, QUIC_OBJ *parent); + /* * Returns a pointer to the handshake layer object which should be accessible on * obj for purposes of handshake API autoforwarding, if any. diff --git a/ssl/quic/quic_port.c b/ssl/quic/quic_port.c index 9115143f528fe..a0d9076470b25 100644 --- a/ssl/quic/quic_port.c +++ b/ssl/quic/quic_port.c @@ -101,6 +101,8 @@ typedef struct validation_token { #define DEFAULT_INIT_CONN_MAX_STREAMS 100 +#define DEFAULT_MAX_PENDING_CONNS 256 + DEFINE_LIST_OF_IMPL(ch, QUIC_CHANNEL); DEFINE_LIST_OF_IMPL(incoming_ch, QUIC_CHANNEL); DEFINE_LIST_OF_IMPL(port, QUIC_PORT); @@ -118,6 +120,7 @@ QUIC_PORT *ossl_quic_port_new(const QUIC_PORT_ARGS *args) port->validate_addr = args->do_addr_validation; port->get_conn_user_ssl = args->get_conn_user_ssl; port->ql = args->ql; + port->max_pending_channels = DEFAULT_MAX_PENDING_CONNS; if (!port_init(port)) { OPENSSL_free(port); @@ -474,8 +477,8 @@ int ossl_quic_port_set_net_wbio(QUIC_PORT *port, BIO *net_wbio) if (!port_update_poll_desc(port, net_wbio, /*for_write=*/1)) return 0; - OSSL_LIST_FOREACH(ch, ch, &port->channel_list) - ossl_qtx_set_bio(ch->qtx, net_wbio); + OSSL_LIST_FOREACH (ch, ch, &port->channel_list) + ossl_qtx_set_bio(ch->qtx, net_wbio); port->net_wbio = net_wbio; port_update_addressing_mode(port); @@ -588,6 +591,9 @@ static QUIC_CHANNEL *port_make_channel(QUIC_PORT *port, SSL *tls, OSSL_QRX *qrx, QUIC_CHANNEL_ARGS args = { 0 }; QUIC_CHANNEL *ch; SSL *user_ssl = NULL; +#ifndef OPENSSL_NO_QLOG + SSL_CTX *qlog_ctx; +#endif args.port = port; args.is_server = is_server; @@ -621,8 +627,10 @@ static QUIC_CHANNEL *port_make_channel(QUIC_PORT *port, SSL *tls, OSSL_QRX *qrx, * start by allocation and provisioning as much of the channel as we can */ ch = ossl_quic_channel_alloc(&args); - if (ch == NULL) + if (ch == NULL) { + ossl_qrx_free(qrx); return NULL; + } if (tls != NULL) { ch->tls = tls; @@ -644,12 +652,15 @@ static QUIC_CHANNEL *port_make_channel(QUIC_PORT *port, SSL *tls, OSSL_QRX *qrx, } #ifndef OPENSSL_NO_QLOG /* - * If we're using qlog, make sure the tls get further configured properly + * A deferred SSL_listen_ex() channel does not have its TLS object yet, but + * it still uses the port's channel context. Configure its qlog title before + * the first packet can cause the qlog object to be instantiated. */ ch->use_qlog = 1; - if (ch->tls != NULL && ch->tls->ctx->qlog_title != NULL) { + qlog_ctx = ch->tls != NULL ? ch->tls->ctx : port->channel_ctx; + if (qlog_ctx != NULL && qlog_ctx->qlog_title != NULL) { OPENSSL_free(ch->qlog_title); - if ((ch->qlog_title = OPENSSL_strdup(ch->tls->ctx->qlog_title)) == NULL) + if ((ch->qlog_title = OPENSSL_strdup(qlog_ctx->qlog_title)) == NULL) goto err; } #endif @@ -708,9 +719,14 @@ QUIC_CHANNEL *ossl_quic_port_pop_incoming(QUIC_PORT *port) return ch; } +QUIC_CHANNEL *ossl_quic_port_peek_incoming(QUIC_PORT *port) +{ + return ossl_list_incoming_ch_head(&port->incoming_channel_list); +} + int ossl_quic_port_have_incoming(QUIC_PORT *port) { - return ossl_list_incoming_ch_head(&port->incoming_channel_list) != NULL; + return ossl_quic_port_peek_incoming(port) != NULL; } void ossl_quic_port_drop_incoming(QUIC_PORT *port) @@ -726,6 +742,12 @@ void ossl_quic_port_drop_incoming(QUIC_PORT *port) break; tls = ossl_quic_channel_get0_tls(ch); + if (tls == NULL) { + /* Unpeeled SSL_listen_ex() channels have no user SSL. */ + ossl_quic_channel_free(ch); + continue; + } + /* * The user ssl may or may not have been created via the * get_conn_user_ssl callback in the QUIC stack. The @@ -799,8 +821,7 @@ void ossl_quic_port_subtick(QUIC_PORT *port, QUIC_TICK_RESULT *res, port_rx_pre(port); /* Iterate through all channels and service them. */ - OSSL_LIST_FOREACH(ch, ch, &port->channel_list) - { + OSSL_LIST_FOREACH (ch, ch, &port->channel_list) { QUIC_TICK_RESULT subr = { 0 }; ossl_quic_channel_subtick(ch, &subr, flags); @@ -1244,7 +1265,7 @@ static void port_send_retry(QUIC_PORT *port, */ unsigned char buffer[512]; unsigned char ct_buf[ENCRYPTED_TOKEN_MAX_LEN]; - WPACKET wpkt; + WPACKET wpkt = { 0 }; size_t written, token_buf_len, ct_len; QUIC_PKT_HDR hdr = { 0 }; QUIC_VALIDATION_TOKEN token = { 0 }; @@ -1330,6 +1351,7 @@ static void port_send_retry(QUIC_PORT *port, "port retry send failed due to network BIO I/O error"); err: + WPACKET_cleanup(&wpkt); cleanup_validation_token(&token); } @@ -1396,21 +1418,21 @@ static void port_send_version_negotiation(QUIC_PORT *port, BIO_ADDR *peer, if (!ossl_quic_wire_encode_pkt_hdr(&wpkt, client_hdr->dst_conn_id.id_len, &hdr, NULL)) - return; + goto err; /* * Add the array of supported versions to the end of the packet */ for (i = 0; i < OSSL_NELEM(supported_versions); i++) { if (!WPACKET_put_bytes_u32(&wpkt, supported_versions[i])) - return; + goto err; } if (!WPACKET_get_total_written(&wpkt, &msg[0].data_len)) - return; + goto err; if (!WPACKET_finish(&wpkt)) - return; + goto err; /* * Send it back to the client attempting to connect @@ -1420,6 +1442,10 @@ static void port_send_version_negotiation(QUIC_PORT *port, BIO_ADDR *peer, if (!BIO_sendmmsg(port->net_wbio, msg, sizeof(BIO_MSG), 1, 0, &written)) ERR_raise_data(ERR_LIB_SSL, SSL_R_QUIC_NETWORK_ERROR, "port version negotiation send failed"); + return; +err: + WPACKET_cleanup(&wpkt); + return; } /** @@ -1615,7 +1641,7 @@ static void port_default_packet_handler(QUIC_URXE *e, void *arg, QUIC_CHANNEL *ch = NULL, *new_ch = NULL; QUIC_CONN_ID odcid; uint8_t gen_new_token = 0; - OSSL_QRX *qrx = NULL; + OSSL_QRX *qrx = NULL, *qrx_ref; OSSL_QRX *qrx_src = NULL; OSSL_QRX_ARGS qrx_args = { 0 }; uint64_t cause_flags = 0; @@ -1708,6 +1734,9 @@ static void port_default_packet_handler(QUIC_URXE *e, void *arg, if (hdr.type != QUIC_PKT_TYPE_INITIAL) goto undesirable; + if (port->max_pending_channels > 0 && ossl_list_incoming_ch_num(&port->incoming_channel_list) >= port->max_pending_channels) + goto undesirable; + odcid.id_len = 0; /* @@ -1805,8 +1834,22 @@ static void port_default_packet_handler(QUIC_URXE *e, void *arg, } } + qrx_ref = NULL; + if (qrx != NULL) { + /* + * if we are here, then client is validated via retry packet + * (client sent a valid token). In this case the qrx has valid + * secrets set for QUIC initial level encryption. We can pass + * reference to qrx to newly created channel. + * + * Note: port_bind_channel()/channel becomes owner of qrx_ref. + */ + qrx_ref = ossl_qrx_newref(qrx); + if (qrx_ref == NULL) + goto undesirable; + } port_bind_channel(port, &e->peer, &hdr.dst_conn_id, - &odcid, qrx, &new_ch); + &odcid, qrx_ref, &new_ch); /* * if packet validates it gets moved to channel, we've just bound @@ -1821,19 +1864,19 @@ static void port_default_packet_handler(QUIC_URXE *e, void *arg, if (gen_new_token == 1) generate_new_token(new_ch, &e->peer); - if (qrx != NULL) { + if (qrx_src != NULL) { /* - * The qrx belongs to channel now, so don't free it. - */ - qrx = NULL; - } else { - /* - * We still need to salvage packets from almost forgotten qrx - * and pass them to channel. + * Time to reinject packets from qrx to channel before + * qrx will be destroyed here. */ while (ossl_qrx_read_pkt(qrx_src, &qrx_pkt) == 1) ossl_quic_channel_inject_pkt(new_ch, qrx_pkt); ossl_qrx_update_pn_space(qrx_src, new_ch->qrx); + /* + * transfer ownership back to qrx; + */ + qrx = qrx_src; + qrx_src = NULL; } /* @@ -1850,7 +1893,7 @@ static void port_default_packet_handler(QUIC_URXE *e, void *arg, */ undesirable: - ossl_qrx_free(qrx); + ossl_qrx_free(qrx); /* releases reference */ ossl_qrx_free(qrx_src); ossl_quic_demux_release_urxe(port->demux, e); } @@ -1877,9 +1920,9 @@ void ossl_quic_port_raise_net_error(QUIC_PORT *port, if (triggering_ch != NULL) ossl_quic_channel_raise_net_error(triggering_ch); - OSSL_LIST_FOREACH(ch, ch, &port->channel_list) - if (ch != triggering_ch) - ossl_quic_channel_raise_net_error(ch); + OSSL_LIST_FOREACH (ch, ch, &port->channel_list) + if (ch != triggering_ch) + ossl_quic_channel_raise_net_error(ch); } void ossl_quic_port_restore_err_state(const QUIC_PORT *port) @@ -1991,3 +2034,13 @@ uint64_t ossl_quic_port_get_active_conn_id_limit(const QUIC_PORT *port) { return port->active_conn_id_limit; } + +uint64_t ossl_quic_port_get_max_pending_channels(const QUIC_PORT *port) +{ + return port->max_pending_channels; +} + +void ossl_quic_port_set_max_pending_channels(QUIC_PORT *port, uint64_t max_pending_channels) +{ + port->max_pending_channels = max_pending_channels; +} diff --git a/ssl/quic/quic_port_local.h b/ssl/quic/quic_port_local.h index c0962108633db..8f7ccf5318929 100644 --- a/ssl/quic/quic_port_local.h +++ b/ssl/quic/quic_port_local.h @@ -135,6 +135,7 @@ struct quic_port_st { uint64_t active_conn_id_limit; unsigned char ack_delay_exponent; unsigned char disable_active_migration; + uint64_t max_pending_channels; }; #endif diff --git a/ssl/quic/quic_rcidm.c b/ssl/quic/quic_rcidm.c index 9a92ec6e351d1..d4ee12549c12f 100644 --- a/ssl/quic/quic_rcidm.c +++ b/ssl/quic/quic_rcidm.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -191,7 +191,7 @@ struct quic_rcidm_st { uint64_t retire_prior_to; /* (SORT BY seq_num ASC) -> (RCID *) */ - PRIORITY_QUEUE_OF(RCID) * rcids; + PRIORITY_QUEUE_OF(RCID) *rcids; /* * Current RCID object we are using. This may differ from the first item in @@ -314,8 +314,8 @@ void ossl_quic_rcidm_free(QUIC_RCIDM *rcidm) while ((rcid = ossl_pqueue_RCID_pop(rcidm->rcids)) != NULL) OPENSSL_free(rcid); - OSSL_LIST_FOREACH_DELSAFE(rcid, rnext, retiring, &rcidm->retiring_list) - OPENSSL_free(rcid); + OSSL_LIST_FOREACH_DELSAFE (rcid, rnext, retiring, &rcidm->retiring_list) + OPENSSL_free(rcid); ossl_pqueue_RCID_free(rcidm->rcids); OPENSSL_free(rcidm); diff --git a/ssl/quic/quic_reactor_wait_ctx.c b/ssl/quic/quic_reactor_wait_ctx.c index ae3b7cb3efe3b..b805d70cbf818 100644 --- a/ssl/quic/quic_reactor_wait_ctx.c +++ b/ssl/quic/quic_reactor_wait_ctx.c @@ -45,9 +45,9 @@ int ossl_quic_reactor_wait_ctx_enter(QUIC_REACTOR_WAIT_CTX *ctx, { QUIC_REACTOR_WAIT_SLOT *slot; - OSSL_LIST_FOREACH(slot, quic_reactor_wait_slot, &ctx->slots) - if (slot->rtor == rtor) - break; + OSSL_LIST_FOREACH (slot, quic_reactor_wait_slot, &ctx->slots) + if (slot->rtor == rtor) + break; if (slot == NULL) { if ((slot = OPENSSL_zalloc(sizeof(QUIC_REACTOR_WAIT_SLOT))) == NULL) @@ -66,9 +66,9 @@ void ossl_quic_reactor_wait_ctx_leave(QUIC_REACTOR_WAIT_CTX *ctx, { QUIC_REACTOR_WAIT_SLOT *slot; - OSSL_LIST_FOREACH(slot, quic_reactor_wait_slot, &ctx->slots) - if (slot->rtor == rtor) - break; + OSSL_LIST_FOREACH (slot, quic_reactor_wait_slot, &ctx->slots) + if (slot->rtor == rtor) + break; assert(slot != NULL); slot_deactivate(slot); @@ -78,8 +78,7 @@ void ossl_quic_reactor_wait_ctx_cleanup(QUIC_REACTOR_WAIT_CTX *ctx) { QUIC_REACTOR_WAIT_SLOT *slot, *nslot; - OSSL_LIST_FOREACH_DELSAFE(slot, nslot, quic_reactor_wait_slot, &ctx->slots) - { + OSSL_LIST_FOREACH_DELSAFE (slot, nslot, quic_reactor_wait_slot, &ctx->slots) { assert(slot->blocking_count == 0); OPENSSL_free(slot); } diff --git a/ssl/quic/quic_record_rx.c b/ssl/quic/quic_record_rx.c index 868650a6127f0..e69d19207e14b 100644 --- a/ssl/quic/quic_record_rx.c +++ b/ssl/quic/quic_record_rx.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,6 +10,7 @@ #include #include "internal/quic_record_rx.h" #include "quic_record_shared.h" +#include "quic_record_rx_local.h" #include "internal/common.h" #include "internal/list.h" #include "../ssl_local.h" @@ -32,61 +33,6 @@ static ossl_inline int pkt_is_marked(const uint64_t *bitf, size_t pkt_idx) return (*bitf & (((uint64_t)1) << pkt_idx)) != 0; } -/* - * RXE - * === - * - * RX Entries (RXEs) store processed (i.e., decrypted) data received from the - * network. One RXE is used per received QUIC packet. - */ -typedef struct rxe_st RXE; - -struct rxe_st { - OSSL_QRX_PKT pkt; - OSSL_LIST_MEMBER(rxe, RXE); - size_t data_len, alloc_len, refcount; - - /* Extra fields for per-packet information. */ - QUIC_PKT_HDR hdr; /* data/len are decrypted payload */ - - /* Decoded packet number. */ - QUIC_PN pn; - - /* Addresses copied from URXE. */ - BIO_ADDR peer, local; - - /* Time we received the packet (not when we processed it). */ - OSSL_TIME time; - - /* Total length of the datagram which contained this packet. */ - size_t datagram_len; - - /* - * The key epoch the packet was received with. Always 0 for non-1-RTT - * packets. - */ - uint64_t key_epoch; - - /* - * Monotonically increases with each datagram received. - * For diagnostic use only. - */ - uint64_t datagram_id; - - /* - * alloc_len allocated bytes (of which data_len bytes are valid) follow this - * structure. - */ -}; - -DEFINE_LIST_OF(rxe, RXE); -typedef OSSL_LIST(rxe) RXE_LIST; - -static ossl_inline unsigned char *rxe_data(const RXE *e) -{ - return (unsigned char *)(e + 1); -} - /* * QRL * === @@ -171,6 +117,8 @@ struct ossl_qrx_st { ossl_msg_cb msg_callback; void *msg_callback_arg; SSL *msg_callback_ssl; + + uint32_t refcount; }; static RXE *qrx_ensure_free_rxe(OSSL_QRX *qrx, size_t alloc_len); @@ -212,6 +160,7 @@ OSSL_QRX *ossl_qrx_new(const OSSL_QRX_ARGS *args) qrx->short_conn_id_len = args->short_conn_id_len; qrx->init_key_phase_bit = args->init_key_phase_bit; qrx->max_deferred = args->max_deferred; + qrx->refcount = 1; return qrx; } @@ -247,13 +196,10 @@ void ossl_qrx_update_pn_space(OSSL_QRX *src, OSSL_QRX *dst) return; } -void ossl_qrx_free(OSSL_QRX *qrx) +static void qrx_destroy(OSSL_QRX *qrx) { uint32_t i; - if (qrx == NULL) - return; - /* Free RXE queue data. */ qrx_cleanup_rxl(&qrx->rx_free); qrx_cleanup_rxl(&qrx->rx_pending); @@ -267,6 +213,30 @@ void ossl_qrx_free(OSSL_QRX *qrx) OPENSSL_free(qrx); } +void ossl_qrx_free(OSSL_QRX *qrx) +{ + if (qrx == NULL) + return; + + qrx->refcount--; + if (qrx->refcount == 0) + qrx_destroy(qrx); +} + +OSSL_QRX *ossl_qrx_newref(OSSL_QRX *qrx) +{ + OSSL_QRX *rv_qrx; + + if (qrx != NULL && qrx->refcount != (uint32_t)~0) { + qrx->refcount++; + rv_qrx = qrx; + } else { + rv_qrx = NULL; + } + + return rv_qrx; +} + void ossl_qrx_inject_urxe(OSSL_QRX *qrx, QUIC_URXE *urxe) { /* Initialize our own fields inside the URXE and add to the pending list. */ @@ -1024,6 +994,7 @@ static int qrx_process_pkt(OSSL_QRX *qrx, QUIC_URXE *urxe, uint32_t pn_space, enc_level; OSSL_QRL_ENC_LEVEL *el = NULL; uint64_t rx_key_epoch = UINT64_MAX; + const unsigned char *token = NULL; /* * Get a free RXE. If we need to allocate a new one, use the packet length @@ -1157,7 +1128,7 @@ static int qrx_process_pkt(OSSL_QRX *qrx, QUIC_URXE *urxe, * Relocate token buffer and fix pointer. */ if (rxe->hdr.type == QUIC_PKT_TYPE_INITIAL) { - const unsigned char *token = rxe->hdr.token; + token = rxe->hdr.token; /* * This may change the value of rxe and change the value of the token @@ -1191,6 +1162,12 @@ static int qrx_process_pkt(OSSL_QRX *qrx, QUIC_URXE *urxe, 0, 0, &rxe->hdr, NULL, NULL) != 1) goto malformed; + /* + * Restore the relocated token value here, since the above decode reset it + * to be within the packet + */ + if (token != NULL) + rxe->hdr.token = token; } /* Validate header and decode PN. */ diff --git a/ssl/quic/quic_record_rx_local.h b/ssl/quic/quic_record_rx_local.h new file mode 100644 index 0000000000000..4a2fd8c0e1b8a --- /dev/null +++ b/ssl/quic/quic_record_rx_local.h @@ -0,0 +1,80 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_QUIC_RECORD_RX_LOCAL_H +#define OSSL_QUIC_RECORD_RX_LOCAL_H + +#include "internal/quic_record_rx.h" +#include "internal/list.h" + +#ifndef OPENSSL_NO_QUIC + +/* + * RXE + * === + * + * RX Entries (RXEs) store processed (i.e., decrypted) data received from the + * network. One RXE is used per received QUIC packet. + * + * The OSSL_QRX_PKT handed out to users of the QRX is the first member, so a + * packet pointer can be cast back to its RXE. It is intended that only the + * QRX implementation access this structure directly, tests which need to + * construct a packet without a QRX being the exception. + */ +typedef struct rxe_st RXE; + +struct rxe_st { + OSSL_QRX_PKT pkt; + OSSL_LIST_MEMBER(rxe, RXE); + size_t data_len, alloc_len, refcount; + + /* Extra fields for per-packet information. */ + QUIC_PKT_HDR hdr; /* data/len are decrypted payload */ + + /* Decoded packet number. */ + QUIC_PN pn; + + /* Addresses copied from URXE. */ + BIO_ADDR peer, local; + + /* Time we received the packet (not when we processed it). */ + OSSL_TIME time; + + /* Total length of the datagram which contained this packet. */ + size_t datagram_len; + + /* + * The key epoch the packet was received with. Always 0 for non-1-RTT + * packets. + */ + uint64_t key_epoch; + + /* + * Monotonically increases with each datagram received. + * For diagnostic use only. + */ + uint64_t datagram_id; + + /* + * alloc_len allocated bytes (of which data_len bytes are valid) follow this + * structure. + */ +}; + +DEFINE_LIST_OF(rxe, RXE); +typedef OSSL_LIST(rxe) RXE_LIST; + +static ossl_inline unsigned char *rxe_data(const RXE *e) +{ + return (unsigned char *)(e + 1); +} + +#endif + +#endif diff --git a/ssl/quic/quic_rx_depack.c b/ssl/quic/quic_rx_depack.c index 74cfceed05897..59d16b2f362c7 100644 --- a/ssl/quic/quic_rx_depack.c +++ b/ssl/quic/quic_rx_depack.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/ssl/quic/quic_srtm.c b/ssl/quic/quic_srtm.c index 1cc2ae6962a56..e17433a6aa0a3 100644 --- a/ssl/quic/quic_srtm.c +++ b/ssl/quic/quic_srtm.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -382,16 +382,24 @@ static int srtm_remove_from_rev(QUIC_SRTM *srtm, SRTM_ITEM *item) return 1; } -int ossl_quic_srtm_remove(QUIC_SRTM *srtm, void *opaque, uint64_t seq_num) +int ossl_quic_srtm_remove(QUIC_SRTM *srtm, void *opaque, uint64_t seq_num, + uint8_t *match) { SRTM_ITEM *item, *prev = NULL; + uint8_t match_sink; + + if (match == NULL) + match = &match_sink; + *match = 0; if (srtm->alloc_failed) return 0; if ((item = srtm_find(srtm, opaque, seq_num, NULL, &prev)) == NULL) /* No match */ - return 0; + return 1; + + *match = 1; /* Remove from forward mapping. */ if (prev == NULL) { @@ -485,8 +493,8 @@ static void check_mark(SRTM_ITEM *item, void *arg) { struct check_args *arg_ = arg; uint32_t token = arg_->token; - uint64_t prev_seq_num = 0; - void *prev_opaque = NULL; + ossl_unused uint64_t prev_seq_num = 0; + ossl_unused void *prev_opaque = NULL; int have_prev = 0; assert(item != NULL); @@ -514,7 +522,7 @@ static void check_mark(SRTM_ITEM *item, void *arg) static void check_count(SRTM_ITEM *item, void *arg) { struct check_args *arg_ = arg; - uint32_t token = arg_->token; + ossl_unused uint32_t token = arg_->token; assert(item != NULL); @@ -535,7 +543,8 @@ void ossl_quic_srtm_check(const QUIC_SRTM *srtm) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION struct check_args args = { 0 }; - size_t tokens_expected, tokens_expected_old; + size_t tokens_expected; + ossl_unused size_t tokens_expected_old; args.token = token_next; ++token_next; diff --git a/ssl/quic/quic_stream_map.c b/ssl/quic/quic_stream_map.c index f707bf71d8ab0..2d58d08a80780 100644 --- a/ssl/quic/quic_stream_map.c +++ b/ssl/quic/quic_stream_map.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -791,20 +791,27 @@ static QUIC_RXFC *qsm_get_max_streams_rxfc(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s) : qsm->max_streams_uni_rxfc; } -void ossl_quic_stream_map_remove_from_accept_queue(QUIC_STREAM_MAP *qsm, +void ossl_quic_stream_map_retire_stream_credit(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s, OSSL_TIME rtt) { QUIC_RXFC *max_streams_rxfc; + if ((max_streams_rxfc = qsm_get_max_streams_rxfc(qsm, s)) != NULL) + (void)ossl_quic_rxfc_on_retire(max_streams_rxfc, 1, rtt); +} + +void ossl_quic_stream_map_remove_from_accept_queue(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *s, + OSSL_TIME rtt) +{ list_remove(&qsm->accept_list, &s->accept_node); if (ossl_quic_stream_is_bidi(s)) --qsm->num_accept_bidi; else --qsm->num_accept_uni; - if ((max_streams_rxfc = qsm_get_max_streams_rxfc(qsm, s)) != NULL) - (void)ossl_quic_rxfc_on_retire(max_streams_rxfc, 1, rtt); + ossl_quic_stream_map_retire_stream_credit(qsm, s, rtt); } size_t ossl_quic_stream_map_get_accept_queue_len(QUIC_STREAM_MAP *qsm, int is_uni) diff --git a/ssl/quic/quic_tls.c b/ssl/quic/quic_tls.c index 96adb6299ca20..4d57ecbf810ce 100644 --- a/ssl/quic/quic_tls.c +++ b/ssl/quic/quic_tls.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -97,15 +97,18 @@ static int quic_free(OSSL_RECORD_LAYER *r); static int quic_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, - int role, int direction, int level, uint16_t epoch, + int role, int direction, int level, uint64_t epoch, unsigned char *secret, size_t secretlen, - unsigned char *key, size_t keylen, unsigned char *iv, - size_t ivlen, unsigned char *mackey, size_t mackeylen, + unsigned char *snkey, unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *snciph, const EVP_CIPHER *ciph, size_t taglen, int mactype, const EVP_MD *md, COMP_METHOD *comp, const EVP_MD *kdfdigest, BIO *prev, BIO *transport, BIO *next, + int use_urxe, const OSSL_PARAM *settings, const OSSL_PARAM *options, const OSSL_DISPATCH *fns, void *cbarg, void *rlarg, OSSL_RECORD_LAYER **retrl) @@ -363,8 +366,8 @@ static int quic_retry_write_records(OSSL_RECORD_LAYER *rl) static int quic_read_record(OSSL_RECORD_LAYER *rl, void **rechandle, int *rversion, uint8_t *type, const unsigned char **data, - size_t *datalen, uint16_t *epoch, - unsigned char *seq_num) + size_t *datalen, uint64_t *epoch, + uint64_t *seq_num) { if (rl->recread != 0 || rl->recunreleased != 0) return OSSL_RECORD_RETURN_FATAL; @@ -581,6 +584,8 @@ static const OSSL_RECORD_METHOD quic_tls_record_method = { quic_release_record, quic_get_alert_code, quic_set1_bio, + NULL, /* set1_peer: Not used for QUIC */ + NULL, /* set_use_urxe: Not used for QUIC */ quic_set_protocol_version, quic_set_plain_alerts, quic_set_first_handshake, @@ -592,6 +597,11 @@ static const OSSL_RECORD_METHOD quic_tls_record_method = { quic_set_max_frag_len, quic_get_max_record_overhead, /* Never called */ quic_increment_sequence_ctr, /* Never called */ + NULL, + NULL, + NULL, + NULL, + NULL, quic_alloc_buffers, quic_free_buffers }; @@ -654,6 +664,16 @@ QUIC_TLS *ossl_quic_tls_new(const QUIC_TLS_ARGS *args) return qtls; } +int ossl_quic_tls_set0_ssl(QUIC_TLS *qtls, SSL *ssl) +{ + if (!ossl_assert(qtls != NULL && ssl != NULL + && qtls->args.s == NULL && !qtls->configured)) + return 0; + + qtls->args.s = ssl; + return 1; +} + void ossl_quic_tls_free(QUIC_TLS *qtls) { if (qtls == NULL) @@ -757,6 +777,10 @@ int ossl_quic_tls_tick(QUIC_TLS *qtls) if (qtls->inerror) return 0; + /* SSL_listen_ex() attaches the SSL after the channel is queued. */ + if (qtls->args.s == NULL) + return 1; + /* * SSL_get_error does not truly know what the cause of an SSL_read failure * is and to some extent guesses based on contextual information. In diff --git a/ssl/quic/quic_txp.c b/ssl/quic/quic_txp.c index bd026af3a4056..9058c92a4fe4e 100644 --- a/ssl/quic/quic_txp.c +++ b/ssl/quic/quic_txp.c @@ -2947,6 +2947,20 @@ static int txp_generate_for_el(OSSL_QUIC_TX_PACKETISER *txp, return TXP_ERR_INTERNAL; } +static int txp_pkt_is_ack_only(const QUIC_TXPIM_PKT *tpkt) +{ + return tpkt->had_ack_frame + && !tpkt->ackm_pkt.is_inflight + && !tpkt->ackm_pkt.is_ack_eliciting + && !tpkt->had_handshake_done_frame + && !tpkt->had_max_data_frame + && !tpkt->had_max_streams_bidi_frame + && !tpkt->had_max_streams_uni_frame + && !tpkt->had_conn_close + && tpkt->retx_head == NULL + && ossl_quic_txpim_pkt_get_num_chunks(tpkt) == 0; +} + /* * Commits and queues a packet for transmission. There is no backing out after * this. @@ -2955,8 +2969,9 @@ static int txp_generate_for_el(OSSL_QUIC_TX_PACKETISER *txp, * * - Sends the packet to the QTX for encryption and transmission; * - * - Records the packet as having been transmitted in FIFM. ACKM is informed, - * etc. and the TXPIM record is filed. + * - Records non-ACK-only packets as having been transmitted in FIFM. ACKM is + * informed, etc. and the TXPIM record is filed only when later callbacks + * need it. * * - Informs various subsystems of frames that were sent and clears frame * wanted flags so that we do not generate the same frames again. @@ -2983,7 +2998,7 @@ static int txp_pkt_commit(OSSL_QUIC_TX_PACKETISER *txp, uint32_t archetype, int *txpim_pkt_reffed) { - int rc = 1; + int ack_only, rc = 1; uint32_t enc_level = pkt->h.enc_level; uint32_t pn_space = ossl_quic_enc_level_to_pn_space(enc_level); QUIC_TXPIM_PKT *tpkt = pkt->tpkt; @@ -3027,28 +3042,35 @@ static int txp_pkt_commit(OSSL_QUIC_TX_PACKETISER *txp, return 0; /* alloc error */ } - /* Dispatch to FIFD. */ - if (!ossl_quic_fifd_pkt_commit(&txp->fifd, tpkt)) + ack_only = txp_pkt_is_ack_only(tpkt); + + /* Dispatch packets that need loss/retransmit callbacks to FIFD. */ + if (!ack_only && !ossl_quic_fifd_pkt_commit(&txp->fifd, tpkt)) return 0; /* * Transmission and Post-Packet Generation Bookkeeping * =================================================== * - * No backing out anymore - at this point the ACKM has recorded the packet - * as having been sent, so we need to increment our next PN counter, or - * the ACKM will complain when we try to record a duplicate packet with - * the same PN later. At this point actually sending the packet may still - * fail. In this unlikely event it will simply be handled as though it - * were a lost packet. + * No backing out anymore - at this point we need to increment our next PN + * counter, or the ACKM will complain when we try to record a duplicate + * packet with the same PN later. Non-ACK-only packets have also been + * recorded in ACKM, so if QTX write fails they are handled as though they + * were lost. ACK-only packets are not recorded and will be cleaned up by + * the caller. */ ++txp->next_pn[pn_space]; - *txpim_pkt_reffed = 1; + if (!ack_only) + *txpim_pkt_reffed = 1; /* Send the packet. */ if (!ossl_qtx_write_pkt(txp->args.qtx, &txpkt)) return 0; + if (ack_only + && !ossl_ackm_on_tx_ack_only_packet(txp->args.ackm, &tpkt->ackm_pkt)) + rc = 0; + /* * Record FC and stream abort frames as sent; deactivate streams which no * longer have anything to do. diff --git a/ssl/quic/quic_wire_pkt.c b/ssl/quic/quic_wire_pkt.c index 368a585072900..3244d3b1a1de8 100644 --- a/ssl/quic/quic_wire_pkt.c +++ b/ssl/quic/quic_wire_pkt.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/ssl/quic/uint_set.c b/ssl/quic/uint_set.c index b01110a58ef37..4b723869e853d 100644 --- a/ssl/quic/uint_set.c +++ b/ssl/quic/uint_set.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/ssl/record/methods/dtls_meth.c b/ssl/record/methods/dtls_meth.c index 434316507da12..96bba977b5748 100644 --- a/ssl/record/methods/dtls_meth.c +++ b/ssl/record/methods/dtls_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,41 +11,42 @@ #include "../../ssl_local.h" #include "../record_local.h" #include "recmethod_local.h" +#include "internal/safe_math.h" -/* mod 128 saturating subtract of two 64-bit values in big-endian order */ -static int satsub64be(const unsigned char *v1, const unsigned char *v2) +OSSL_SAFE_MATH_UNSIGNED(uint64_t, uint64_t) + +static int dtls_increment_sequence_ctr(OSSL_RECORD_LAYER *rl); + +/* mod 128 saturating subtract of two 64-bit values */ +static int satsub64(uint64_t l1, uint64_t l2) { - int64_t ret; - uint64_t l1, l2; - - n2l8(v1, l1); - n2l8(v2, l2); - - ret = l1 - l2; - - /* We do not permit wrap-around */ - if (l1 > l2 && ret < 0) - return 128; - else if (l2 > l1 && ret > 0) - return -128; - - if (ret > 128) - return 128; - else if (ret < -128) - return -128; - else - return (int)ret; + uint64_t max, min; + int sign; + + if (l1 > l2) { + max = l1; + min = l2; + sign = 1; + } else { + max = l2; + min = l1; + sign = -1; + } + + if (max - min > 128) + return sign * 128; + + return sign * ((int)(max - min)); } static int dtls_record_replay_check(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap) { int cmp; unsigned int shift; - const unsigned char *seq = rl->sequence; - cmp = satsub64be(seq, bitmap->max_seq_num); + cmp = satsub64(rl->sequence, bitmap->max_seq_num); if (cmp > 0) { - ossl_tls_rl_record_set_seq_num(&rl->rrec[0], seq); + rl->rrec[0].seq_num = rl->sequence; return 1; /* this record in new */ } shift = -cmp; @@ -54,25 +55,23 @@ static int dtls_record_replay_check(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap) else if (bitmap->map & ((uint64_t)1 << shift)) return 0; /* record previously received */ - ossl_tls_rl_record_set_seq_num(&rl->rrec[0], seq); + rl->rrec[0].seq_num = rl->sequence; return 1; } -static void dtls_record_bitmap_update(OSSL_RECORD_LAYER *rl, - DTLS_BITMAP *bitmap) +static void dtls_record_bitmap_update(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap) { int cmp; unsigned int shift; - const unsigned char *seq = rl->sequence; - cmp = satsub64be(seq, bitmap->max_seq_num); + cmp = satsub64(rl->sequence, bitmap->max_seq_num); if (cmp > 0) { shift = cmp; if (shift < sizeof(bitmap->map) * 8) bitmap->map <<= shift, bitmap->map |= 1UL; else bitmap->map = 1UL; - memcpy(bitmap->max_seq_num, seq, SEQ_NUM_SIZE); + bitmap->max_seq_num = rl->sequence; } else { shift = -cmp; if (shift < sizeof(bitmap->map) * 8) @@ -86,15 +85,24 @@ static DTLS_BITMAP *dtls_get_bitmap(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rr, *is_next_epoch = 0; /* In current epoch, accept HM, CCS, DATA, & ALERT */ - if (rr->epoch == rl->epoch) + if (rr->epoch == rl->epoch) { return &rl->bitmap; - - /* - * Check if the message is from the next epoch - */ - else if (rr->epoch == rl->epoch + 1) { + /* + * DTLS 1.3 uses encrypted sequence numbers. Therefore we + * cannot check future bitmaps since the sequence number + * is encrypted. The dtls_record_bitmap_update is only called + * once the record layer with the correct epoch has + * processed the record. + * We are concerned during the DTLS 1.3 handshake if a record + * from a future handshake epoch is received. + */ + } else if ((rl->version == DTLS1_3_VERSION || rl->version == DTLS_ANY_VERSION) && rl->epoch == 0 && rr->epoch == 2) { + *is_next_epoch = 1; + /* + * Check if the message is from the next epoch + */ + } else if (rr->epoch == rl->epoch + 1) { *is_next_epoch = 1; - return &rl->next_bitmap; } return NULL; @@ -105,6 +113,24 @@ static void dtls_set_in_init(OSSL_RECORD_LAYER *rl, int in_init) rl->in_init = in_init; } +size_t dtls_get_rec_header_size(uint8_t hdr_first_byte) +{ + size_t size = 0; + + if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(hdr_first_byte) + && ossl_assert(!DTLS13_UNI_HDR_CID_BIT_IS_SET(hdr_first_byte))) { + /* DTLSv1.3 unified record header */ + size = 1; + size += DTLS13_UNI_HDR_SEQ_BIT_IS_SET(hdr_first_byte) ? 2 : 1; + size += DTLS13_UNI_HDR_LEN_BIT_IS_SET(hdr_first_byte) ? 2 : 0; + } else { + /* DTLSv1.0, DTLSv1.2 or unencrypted DTLSv1.3 record header */ + size = DTLS1_RT_HEADER_LENGTH; + } + + return size; +} + static int dtls_process_record(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap) { int i; @@ -112,6 +138,7 @@ static int dtls_process_record(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap) TLS_RL_RECORD *rr; int imac_size; size_t mac_size = 0; + size_t rechdrsize = dtls_get_rec_header_size(rl->packet[0]); unsigned char md[EVP_MAX_MD_SIZE]; SSL_MAC_BUF macbuf = { NULL, 0 }; int ret = 0; @@ -119,10 +146,10 @@ static int dtls_process_record(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap) rr = &rl->rrec[0]; /* - * At this point, rl->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length, + * At this point, rl->packet_length == rechdrsize + rr->length, * and we have that many bytes in rl->packet */ - rr->input = &(rl->packet[DTLS1_RT_HEADER_LENGTH]); + rr->input = rl->packet + rechdrsize; /* * ok, we can now read from 'rl->packet' data into 'rr'. rr->input @@ -281,17 +308,17 @@ static int dtls_process_record(OSSL_RECORD_LAYER *rl, DTLS_BITMAP *bitmap) } static int dtls_rlayer_buffer_record(OSSL_RECORD_LAYER *rl, struct pqueue_st *queue, - unsigned char *priority) + uint64_t priority) { DTLS_RLAYER_RECORD_DATA *rdata; pitem *item; /* Limit the size of the queue to prevent DOS attacks */ - if (pqueue_size(queue) >= 100) + if (pqueue_size(queue) >= 16) return 0; rdata = OPENSSL_malloc(sizeof(*rdata)); - item = pitem_new(priority, rdata); + item = pitem_new_u64(priority, rdata); if (rdata == NULL || item == NULL) { OPENSSL_free(rdata); pitem_free(item); @@ -299,29 +326,26 @@ static int dtls_rlayer_buffer_record(OSSL_RECORD_LAYER *rl, struct pqueue_st *qu return -1; } - rdata->packet = rl->packet; + /* + * Take a copy of just this record's on-wire bytes (header + ciphertext) + * rather than the whole (much larger) read buffer. The live rl->rbuf is + * left untouched and continues to be used for subsequent reads. + */ rdata->packet_length = rl->packet_length; - memcpy(&(rdata->rbuf), &rl->rbuf, sizeof(TLS_BUFFER)); - memcpy(&(rdata->rrec), &rl->rrec[0], sizeof(TLS_RL_RECORD)); - - item->data = rdata; - - rl->packet = NULL; - rl->packet_length = 0; - memset(&rl->rbuf, 0, sizeof(TLS_BUFFER)); - memset(&rl->rrec[0], 0, sizeof(rl->rrec[0])); - - if (!tls_setup_read_buffer(rl)) { - /* RLAYERfatal() already called */ - OPENSSL_free(rdata->rbuf.buf); + rdata->packet = OPENSSL_memdup(rl->packet, rl->packet_length); + if (rdata->packet == NULL) { OPENSSL_free(rdata); pitem_free(item); + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); return -1; } + memcpy(&(rdata->rrec), &rl->rrec[0], sizeof(TLS_RL_RECORD)); + + item->data = rdata; if (pqueue_insert(queue, item) == NULL) { /* Must be a duplicate so ignore it */ - OPENSSL_free(rdata->rbuf.buf); + OPENSSL_free(rdata->packet); OPENSSL_free(rdata); pitem_free(item); } @@ -329,42 +353,104 @@ static int dtls_rlayer_buffer_record(OSSL_RECORD_LAYER *rl, struct pqueue_st *qu return 1; } -/* copy buffered record into OSSL_RECORD_LAYER structure */ -static int dtls_copy_rlayer_record(OSSL_RECORD_LAYER *rl, pitem *item) +/* rfc9147 section 4.2.3 */ +int dtls_crypt_sequence_number(EVP_CIPHER_CTX *ctx, unsigned char *seq, size_t seqlen, + unsigned char *rec_data) { - DTLS_RLAYER_RECORD_DATA *rdata; + unsigned char mask[16]; + int outlen, inlen; + unsigned char *in, *iv; + size_t i; + unsigned char zeros[16] = { 0 }; - rdata = (DTLS_RLAYER_RECORD_DATA *)item->data; + inlen = (int)(sizeof(mask)); - ossl_tls_buffer_release(&rl->rbuf); + in = rec_data; + iv = NULL; + memset(mask, 0, sizeof(mask)); - rl->packet = rdata->packet; - rl->packet_length = rdata->packet_length; - memcpy(&rl->rbuf, &(rdata->rbuf), sizeof(TLS_BUFFER)); - memcpy(&rl->rrec[0], &(rdata->rrec), sizeof(TLS_RL_RECORD)); + /* + * When the AEAD is based on ChaCha20, the first 4 bytes of the ciphertext + * are treated as the block counter and the next 12 bytes as the nonce. + * These are passed together as the IV (counter || nonce) to reinitialise + * the cipher, and a zero block is encrypted to produce the mask. + */ + if (EVP_CIPHER_CTX_get_nid(ctx) == NID_chacha20) { + iv = rec_data; + in = zeros; + inlen = sizeof(zeros); + } + + if (!ossl_assert(inlen >= 0) + || (size_t)inlen > sizeof(mask) + || !EVP_CIPHER_CTX_set_padding(ctx, 0) + || EVP_CipherInit_ex2(ctx, NULL, NULL, iv, 1, NULL) <= 0 + || EVP_CipherUpdate(ctx, mask, &outlen, in, inlen) <= 0 + || outlen != inlen + || EVP_CipherFinal_ex(ctx, mask + outlen, &outlen) <= 0 + || outlen != 0) + return 0; + + if (!ossl_assert(seqlen <= sizeof(mask))) + return 0; + + for (i = 0; i < seqlen; i++) + seq[i] ^= mask[i]; - /* Set proper sequence number for mac calculation */ - memcpy(&(rl->sequence[2]), &(rdata->packet[5]), 6); + OPENSSL_cleanse(mask, sizeof(mask)); return 1; } -static int dtls_retrieve_rlayer_buffered_record(OSSL_RECORD_LAYER *rl, - struct pqueue_st *queue) +/* + * Reconstruct the full sequence number as recommended by rfc9147 section + * 4.2.2. Select the candidate closest to the replay window's right edge plus + * one, ignore candidates outside the uint64_t range, and break ties forward. + * An empty replay window is represented by max_seq_num == 0. + */ +uint64_t dtls13_reconstruct_seq_num(uint64_t max_seq_num, uint64_t truncated, + size_t seqlen) { - pitem *item; - - item = pqueue_pop(queue); - if (item) { - dtls_copy_rlayer_record(rl, item); - - OPENSSL_free(item->data); - pitem_free(item); + uint64_t mask, period, expected, candidate, alt, best, best_dist, dist; + + mask = DTLS13_UNI_HDR_SEQ_MASK(seqlen); + period = mask + 1; + + /* At the end of the range only candidates in the last block can be valid. */ + if (max_seq_num == UINT64_MAX) + return (UINT64_MAX & ~mask) | truncated; + + expected = max_seq_num + 1; + + /* The candidate in the same period-sized block as |expected| */ + candidate = (expected & ~mask) | truncated; + best = candidate; + best_dist = candidate > expected ? candidate - expected + : expected - candidate; + + /* The candidate one period behind, if it does not underflow */ + if (candidate >= period) { + alt = candidate - period; + dist = alt > expected ? alt - expected : expected - alt; + /* Strictly closer only: a tie goes to the forward candidate */ + if (dist < best_dist) { + best = alt; + best_dist = dist; + } + } - return 1; + /* The candidate one period ahead, if it does not overflow */ + if (candidate <= UINT64_MAX - period) { + alt = candidate + period; + dist = alt > expected ? alt - expected : expected - alt; + /* Ties go forward */ + if (dist <= best_dist) { + best = alt; + best_dist = dist; + } } - return 0; + return best; } /*- @@ -378,13 +464,16 @@ static int dtls_retrieve_rlayer_buffered_record(OSSL_RECORD_LAYER *rl, */ int dtls_get_more_records(OSSL_RECORD_LAYER *rl) { - int ssl_major, ssl_minor; int rret; - size_t more, n; + size_t more, nread = 0; TLS_RL_RECORD *rr; - unsigned char *p = NULL; DTLS_BITMAP *bitmap; unsigned int is_next_epoch; + unsigned char recseqnum[6]; + size_t recseqnumlen = 0; + size_t rechdrlen = 0; + size_t recseqnumoffs = 0; + int buffered_record = 0; rl->num_recs = 0; rl->curr_rec = 0; @@ -400,18 +489,28 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl) } again: - /* if we're renegotiating, then there may be buffered records */ - if (dtls_retrieve_rlayer_buffered_record(rl, rl->processed_rcds)) { - rl->num_recs = 1; - return OSSL_RECORD_RETURN_SUCCESS; - } + memset(recseqnum, 0, sizeof(recseqnum)); /* get something from the wire */ /* check if we have the header */ - if ((rl->rstate != SSL_ST_READ_BODY) || (rl->packet_length < DTLS1_RT_HEADER_LENGTH)) { + if (rl->rstate != SSL_ST_READ_BODY + || rl->packet_length < DTLS1_RT_HEADER_LENGTH) { + PACKET dtlsrecord; + unsigned int record_type, record_version, epoch, length; + uint64_t epoch64; + + /* + * If we have buffered records and the original BIO READ has all been processed + * let's leave and allow the Record Layer to update. + */ + if (rl->version == DTLS1_3_VERSION + && buffered_record == 1 && rl->rbuf.left == 0) { + return OSSL_RECORD_RETURN_RETRY; + } + rret = rl->funcs->read_n(rl, DTLS1_RT_HEADER_LENGTH, - TLS_BUFFER_get_len(&rl->rbuf), 0, 1, &n); + TLS_BUFFER_get_len(&rl->rbuf), 0, 1, &nread); /* read timeout is handled by dtls1_read_bytes */ if (rret < OSSL_RECORD_RETURN_SUCCESS) { /* RLAYERfatal() already called if appropriate */ @@ -426,31 +525,125 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl) rl->rstate = SSL_ST_READ_BODY; - p = rl->packet; + if (!PACKET_buf_init(&dtlsrecord, rl->packet, rl->packet_length) + || !PACKET_get_1(&dtlsrecord, &record_type)) { + rl->packet_length = 0; + goto again; + } /* Pull apart the header into the DTLS1_RECORD */ - rr->type = *(p++); - ssl_major = *(p++); - ssl_minor = *(p++); - rr->rec_version = (ssl_major << 8) | ssl_minor; + rr->type = (int)record_type; + + /*- + * rfc9147: + * Implementations can demultiplex DTLS 1.3 records by examining the first + * byte as follows: + * * If the first byte is alert(21), handshake(22), or ack(proposed, 26), + * the record MUST be interpreted as a DTLSPlaintext record. + * * If the first byte is any other value, then receivers MUST check to + * see if the leading bits of the first byte are 001. If so, the implementation + * MUST process the record as DTLSCiphertext; the true content type + * will be inside the protected portion. + * * Otherwise, the record MUST be rejected as if it had failed deprotection, + * as described in Section 4.5.2. + */ + if (rl->version == DTLS1_3_VERSION + && rr->type != SSL3_RT_ALERT + && rr->type != SSL3_RT_HANDSHAKE + && rr->type != SSL3_RT_ACK + && !DTLS13_UNI_HDR_FIX_BITS_IS_SET(rr->type)) { + /* Silently discard */ + rr->length = 0; + rl->packet_length = 0; + goto again; + } - /* sequence number is 64 bits, with top 2 bytes = epoch */ - n2s(p, rr->epoch); + if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(rr->type)) { + /* + * rfc9147: + * receivers MUST check to if the leading bits of the first byte are 001. + * If so, the implementation MUST process the record as DTLSCiphertext; + */ + int cbitisset = DTLS13_UNI_HDR_CID_BIT_IS_SET(rr->type); + int sbitisset = DTLS13_UNI_HDR_SEQ_BIT_IS_SET(rr->type); + int lbitisset = DTLS13_UNI_HDR_LEN_BIT_IS_SET(rr->type); + uint16_t eebits = rr->type & DTLS13_UNI_HDR_EPOCH_BITS_MASK; + + record_version = DTLS1_2_VERSION; + epoch64 = rl->epoch; + recseqnumlen = sbitisset ? 2 : 1; + recseqnumoffs = sizeof(recseqnum) - recseqnumlen; + + if (/* OpenSSL does not support connection IDs: silently discard */ + cbitisset + /* + * Naive approach? We expect sequence number to be filled already + * and then override the last bytes of the sequence number. + */ + || !PACKET_copy_bytes(&dtlsrecord, recseqnum + recseqnumoffs, recseqnumlen) + /* + * rfc9147: + * The length field MAY be omitted by clearing the L bit, which means + * that the record consumes the entire rest of the datagram in the + * lower level transport + */ + || (lbitisset ? !PACKET_get_net_2(&dtlsrecord, &length) + : (length = (unsigned int)TLS_BUFFER_get_len(&rl->rbuf)) > 0)) { + rr->length = 0; + rl->packet_length = 0; + goto again; + } - memcpy(&(rl->sequence[2]), p, 6); - p += 6; + /* + * RFC 9147 Section 4.2.2 Says that after the handshake phase (epoch 3+) + * if the epoch bits do not match the current epoch we should use the + * last epoch value. That would result in dropping the packet. + */ + if ((epoch64 & DTLS13_UNI_HDR_EPOCH_BITS_MASK) != eebits) { + /* + * Since we do not transition out of epoch 0 or early data until after + * we receive the next record if we are in epoch 0 or Early Data (epoch 1) + * and get an epoch 2 record we must update the epoch + */ + if (eebits == 2 && (epoch64 == 1 || epoch64 == 0)) { + epoch64 = 2; + } else { + rr->length = 0; + rl->packet_length = 0; + goto again; + } + } + } else { + if (!PACKET_get_net_2(&dtlsrecord, &record_version) + || !PACKET_get_net_2(&dtlsrecord, &epoch) + || !PACKET_copy_bytes(&dtlsrecord, recseqnum, 6) + || !PACKET_get_net_2(&dtlsrecord, &length)) { + rr->length = 0; + rl->packet_length = 0; + goto again; + } + epoch64 = epoch; + recseqnumoffs = 0; + recseqnumlen = 6; + } - n2s(p, rr->length); + rechdrlen = PACKET_data(&dtlsrecord) - rl->packet; + rr->rec_version = (int)record_version; + rr->epoch = epoch64; + rr->length = length; if (rl->msg_callback != NULL) - rl->msg_callback(0, rr->rec_version, SSL3_RT_HEADER, rl->packet, DTLS1_RT_HEADER_LENGTH, - rl->cbarg); + rl->msg_callback(0, rr->rec_version, SSL3_RT_HEADER, rl->packet, + rechdrlen, rl->cbarg); /* * Lets check the version. We tolerate alerts that don't have the exact * version number (e.g. because of protocol version errors) */ - if (!rl->is_first_record && rr->type != SSL3_RT_ALERT) { + if (!rl->is_first_record && rr->type != SSL3_RT_ALERT + /* DTLSv1.3 records sets the legacy version field to DTLSv1.2 */ + && !(rr->rec_version == DTLS1_2_VERSION + && rl->version == DTLS1_3_VERSION)) { if (rr->rec_version != rl->version) { /* unexpected version, silently discard */ rr->length = 0; @@ -459,7 +652,7 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl) } } - if (ssl_major != (rl->version == DTLS_ANY_VERSION ? DTLS1_VERSION_MAJOR : rl->version >> 8)) { + if (rr->rec_version >> 8 != (rl->version == DTLS_ANY_VERSION ? DTLS1_VERSION_MAJOR : rl->version >> 8)) { /* wrong version, silently discard record */ rr->length = 0; rl->packet_length = 0; @@ -491,10 +684,10 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl) if (rr->length > rl->packet_length - DTLS1_RT_HEADER_LENGTH) { /* now rl->packet_length == DTLS1_RT_HEADER_LENGTH */ - more = rr->length; - rret = rl->funcs->read_n(rl, more, more, 1, 1, &n); + more = rr->length - (nread - rechdrlen); + rret = rl->funcs->read_n(rl, more, more, 1, 1, &nread); /* this packet contained a partial record, dump it */ - if (rret < OSSL_RECORD_RETURN_SUCCESS || n != more) { + if (rret < OSSL_RECORD_RETURN_SUCCESS || nread != more) { if (rl->alert != SSL_AD_NO_ALERT) { /* read_n() called RLAYERfatal() */ return OSSL_RECORD_RETURN_FATAL; @@ -512,30 +705,77 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl) /* set state for later operations */ rl->rstate = SSL_ST_READ_HEADER; + /* + * RFC 9147 permits DTLSPlaintext only in epoch 0. Silently discard it + * after reading the fragment so later records remain framed. + */ + if (rl->version == DTLS1_3_VERSION + && rl->epoch != 0 + && !DTLS13_UNI_HDR_FIX_BITS_IS_SET(rr->type)) { + rr->length = 0; + rl->packet_length = 0; + goto again; + } + + /* + * rfc9147: + * This procedure requires the ciphertext length to be at least 16 bytes. + * Receivers MUST reject shorter records as if they had failed deprotection + */ + if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(rr->type) + && rl->version == DTLS1_3_VERSION + && !(rl->in_init && rl->epoch == 0) + && ((rl->packet_length < rechdrlen + DTLS13_CIPHERTEXT_MINSIZE) + || (rl->sn_enc_ctx == NULL && rl->mac_ctx == NULL) + || (rl->sn_enc_ctx != NULL + && !dtls_crypt_sequence_number(rl->sn_enc_ctx, + recseqnum + recseqnumoffs, + recseqnumlen, + rl->packet + rechdrlen)))) { + /* sequence number encryption failed dump record */ + rr->length = 0; + rl->packet_length = 0; + goto again; + } + + if (rl->version == DTLS1_3_VERSION && rr->epoch == rl->epoch + && DTLS13_UNI_HDR_FIX_BITS_IS_SET(rr->type)) { + /* Reconstruct current-epoch unified records using its replay window. */ + uint64_t truncated = 0; + size_t i; + + /* A unified header carries 8 or 16 bits of the sequence number */ + if (!ossl_assert(recseqnumlen == 1 || recseqnumlen == 2)) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + for (i = 0; i < recseqnumlen; i++) + truncated = (truncated << 8) | recseqnum[recseqnumoffs + i]; + + rl->sequence = dtls13_reconstruct_seq_num(rl->bitmap.max_seq_num, + truncated, recseqnumlen); + } else { + /* + * DTLSPlaintext carries 48 bits. A buffered next-epoch unified record + * is re-parsed after that epoch's record layer is installed, so this + * provisional value is unused. + */ + rl->sequence = ((uint64_t)recseqnum[0]) << 40; + rl->sequence |= ((uint64_t)recseqnum[1]) << 32; + rl->sequence |= ((uint64_t)recseqnum[2]) << 24; + rl->sequence |= ((uint64_t)recseqnum[3]) << 16; + rl->sequence |= ((uint64_t)recseqnum[4]) << 8; + rl->sequence |= ((uint64_t)recseqnum[5]) << 0; + } + /* match epochs. NULL means the packet is dropped on the floor */ bitmap = dtls_get_bitmap(rl, rr, &is_next_epoch); - if (bitmap == NULL) { + if (bitmap == NULL && !is_next_epoch) { rr->length = 0; rl->packet_length = 0; /* dump this record */ goto again; /* get another record */ } -#ifndef OPENSSL_NO_SCTP - /* Only do replay check if no SCTP bio */ - if (!BIO_dgram_is_sctp(rl->bio)) { -#endif - /* Check whether this is a repeat, or aged record. */ - if (!dtls_record_replay_check(rl, bitmap)) { - rr->length = 0; - rl->packet_length = 0; /* dump this record */ - goto again; /* get another record */ - } -#ifndef OPENSSL_NO_SCTP - } -#endif - - /* just read a 0 length packet */ - if (rr->length == 0) - goto again; /* * If this record is from the next epoch (either HM or ALERT), and a @@ -543,19 +783,64 @@ int dtls_get_more_records(OSSL_RECORD_LAYER *rl) * processed at this time. */ if (is_next_epoch) { - if (rl->in_init) { - if (dtls_rlayer_buffer_record(rl, rl->unprocessed_rcds, - rr->seq_num) + /* + * DTLS 1.3 has two scenarios when to buffer the record + * from the next epoch + * 1) during handshake when rl->in_init is set and + * we got an epoch 0 record and the record layer + * is at epoch 2 + * 2) during early data when rl-epoch is 1 and we + * got an epoch 2 record + */ + if ((rl->in_init && rl->version != DTLS1_3_VERSION) + || (rl->in_init && rl->epoch == 0 && rr->epoch == 2) + || (rl->version == DTLS1_3_VERSION + && ((rl->in_init && rl->epoch == 0 && rr->epoch == 2) + || (rl->epoch == 1 && rr->epoch == 2)))) { + + uint64_t unprocessed_record_priority = rr->seq_num; + + /* + * DTLS1.3 uses encrypted sequence numbers so we want to set the + * priority base off of epoch. + */ + if (rl->version == DTLS1_3_VERSION || (rr->epoch == 2 && rl->epoch == 0)) { + if (rr->epoch == 1) + unprocessed_record_priority = rl->dtls13_epoch_1_seq++; + else if (rr->epoch == 2) + unprocessed_record_priority = rl->dtls13_epoch_2_seq++; + } + if (dtls_rlayer_buffer_record(rl, &rl->unprocessed_rcds, + unprocessed_record_priority) < 0) { /* RLAYERfatal() already called */ return OSSL_RECORD_RETURN_FATAL; } + buffered_record = 1; } rr->length = 0; rl->packet_length = 0; goto again; } +#ifndef OPENSSL_NO_SCTP + /* Only do replay check if no SCTP bio (also check for NULL bio) */ + if (rl->bio == NULL || !BIO_dgram_is_sctp(rl->bio)) { +#endif + /* Check whether this is a repeat, or aged record. */ + if (!dtls_record_replay_check(rl, bitmap)) { + rr->length = 0; + rl->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } +#ifndef OPENSSL_NO_SCTP + } +#endif + + /* just read a 0 length packet */ + if (rr->length == 0) + goto again; + if (!dtls_process_record(rl, bitmap)) { if (rl->alert != SSL_AD_NO_ALERT) { /* dtls_process_record() called RLAYERfatal */ @@ -601,27 +886,15 @@ static int dtls_free(OSSL_RECORD_LAYER *rl) rbuf->left = 0; } - if (rl->unprocessed_rcds != NULL) { - while ((item = pqueue_pop(rl->unprocessed_rcds)) != NULL) { - rdata = (DTLS_RLAYER_RECORD_DATA *)item->data; - /* Push to the next record layer */ - ret &= BIO_write_ex(rl->next, rdata->packet, rdata->packet_length, - &written); - OPENSSL_free(rdata->rbuf.buf); - OPENSSL_free(item->data); - pitem_free(item); - } - pqueue_free(rl->unprocessed_rcds); - } + while ((item = pqueue_pop(&rl->unprocessed_rcds)) != NULL) { + rdata = (DTLS_RLAYER_RECORD_DATA *)item->data; - if (rl->processed_rcds != NULL) { - while ((item = pqueue_pop(rl->processed_rcds)) != NULL) { - rdata = (DTLS_RLAYER_RECORD_DATA *)item->data; - OPENSSL_free(rdata->rbuf.buf); - OPENSSL_free(item->data); - pitem_free(item); - } - pqueue_free(rl->processed_rcds); + /* Push to the next record layer */ + ret &= BIO_write_ex(rl->next, rdata->packet, rdata->packet_length, + &written); + OPENSSL_free(rdata->packet); + OPENSSL_free(item->data); + pitem_free(item); } return tls_free(rl) && ret; @@ -629,15 +902,18 @@ static int dtls_free(OSSL_RECORD_LAYER *rl) static int dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, - int role, int direction, int level, uint16_t epoch, + int role, int direction, int level, uint64_t epoch, unsigned char *secret, size_t secretlen, - unsigned char *key, size_t keylen, unsigned char *iv, - size_t ivlen, unsigned char *mackey, size_t mackeylen, + unsigned char *snkey, unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *snciph, const EVP_CIPHER *ciph, size_t taglen, int mactype, const EVP_MD *md, COMP_METHOD *comp, const EVP_MD *kdfdigest, BIO *prev, BIO *transport, BIO *next, + int use_urxe, const OSSL_PARAM *settings, const OSSL_PARAM *options, const OSSL_DISPATCH *fns, void *cbarg, void *rlarg, OSSL_RECORD_LAYER **retrl) @@ -652,25 +928,20 @@ dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, if (ret != OSSL_RECORD_RETURN_SUCCESS) return ret; - (*retrl)->unprocessed_rcds = pqueue_new(); - (*retrl)->processed_rcds = pqueue_new(); - - if ((*retrl)->unprocessed_rcds == NULL - || (*retrl)->processed_rcds == NULL) { - dtls_free(*retrl); - *retrl = NULL; - ERR_raise(ERR_LIB_SSL, ERR_R_SSL_LIB); - return OSSL_RECORD_RETURN_FATAL; - } - (*retrl)->isdtls = 1; (*retrl)->epoch = epoch; (*retrl)->in_init = 1; + (*retrl)->dtls13_epoch_1_seq = 0; + (*retrl)->dtls13_epoch_2_seq = 100; + (*retrl)->use_urxe = use_urxe; switch (vers) { case DTLS_ANY_VERSION: (*retrl)->funcs = &dtls_any_funcs; break; + case DTLS1_3_VERSION: + (*retrl)->funcs = &dtls_1_3_funcs; + break; case DTLS1_2_VERSION: case DTLS1_VERSION: case DTLS1_BAD_VER: @@ -683,9 +954,10 @@ dtls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, goto err; } - ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv, - ivlen, mackey, mackeylen, ciph, - taglen, mactype, md, comp); + ret = (*retrl)->funcs->set_crypto_state(*retrl, level, snkey, key, keylen, + iv, ivlen, mackey, mackeylen, + snciph, ciph, taglen, mactype, md, + comp); err: if (ret != OSSL_RECORD_RETURN_SUCCESS) { @@ -702,25 +974,52 @@ int dtls_prepare_record_header(OSSL_RECORD_LAYER *rl, unsigned char **recdata) { size_t maxcomplen; + int unifiedheader = rl->version == DTLS1_3_VERSION && rl->epoch > 0; + templ->sequence_number = rl->sequence; + templ->epoch = rl->epoch; *recdata = NULL; - maxcomplen = templ->buflen; + if (rl->compctx != NULL) maxcomplen += SSL3_RT_MAX_COMPRESSED_OVERHEAD; - if (!WPACKET_put_bytes_u8(thispkt, rectype) - || !WPACKET_put_bytes_u16(thispkt, templ->version) - || !WPACKET_put_bytes_u16(thispkt, rl->epoch) - || !WPACKET_memcpy(thispkt, &(rl->sequence[2]), 6) - || !WPACKET_start_sub_packet_u16(thispkt) - || (rl->eivlen > 0 - && !WPACKET_allocate_bytes(thispkt, rl->eivlen, NULL)) - || (maxcomplen > 0 - && !WPACKET_reserve_bytes(thispkt, maxcomplen, - recdata))) { - RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + if (unifiedheader) { + uint8_t fixedbits = 0x20; + uint8_t cbit = 0; + uint8_t sbit = DTLS13_UNI_HDR_SEQ_BIT; + uint8_t lbit = DTLS13_UNI_HDR_LEN_BIT; + uint8_t ebits = rl->epoch & DTLS13_UNI_HDR_EPOCH_BITS_MASK; + uint8_t unifiedhdrbits = fixedbits | cbit | sbit | lbit | ebits; + uint64_t seqnum; + + /* Truncate only the wire encoding, not the AEAD nonce counter. */ + seqnum = rl->sequence & DTLS13_UNI_HDR_SEQ_MASK(sbit ? 2 : 1); + + if (!WPACKET_put_bytes_u8(thispkt, unifiedhdrbits) + || (sbit ? !WPACKET_put_bytes_u16(thispkt, seqnum) + : !WPACKET_put_bytes_u8(thispkt, seqnum)) + || !WPACKET_start_sub_packet_u16(thispkt) + || (rl->eivlen > 0 + && !WPACKET_allocate_bytes(thispkt, rl->eivlen, NULL)) + || (maxcomplen > 0 + && !WPACKET_reserve_bytes(thispkt, maxcomplen, recdata))) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + } else { + if (!WPACKET_put_bytes_u8(thispkt, rectype) + || !WPACKET_put_bytes_u16(thispkt, templ->version) + || !WPACKET_put_bytes_u16(thispkt, templ->epoch) + || !WPACKET_put_bytes_u48(thispkt, templ->sequence_number) + || !WPACKET_start_sub_packet_u16(thispkt) + || (rl->eivlen > 0 + && !WPACKET_allocate_bytes(thispkt, rl->eivlen, NULL)) + || (maxcomplen > 0 + && !WPACKET_reserve_bytes(thispkt, maxcomplen, recdata))) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } } return 1; @@ -738,16 +1037,35 @@ int dtls_post_encryption_processing(OSSL_RECORD_LAYER *rl, return 0; } - return tls_increment_sequence_ctr(rl); + return dtls_increment_sequence_ctr(rl); +} + +static int dtls_increment_sequence_ctr(OSSL_RECORD_LAYER *rl) +{ + if (rl->version == DTLS1_3_VERSION) + return tls_increment_sequence_ctr(rl); + + if (rl->sequence >= 0xffffffffffffULL) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_SEQUENCE_CTR_WRAPPED); + return 0; + } + + rl->sequence++; + return 1; } static size_t dtls_get_max_record_overhead(OSSL_RECORD_LAYER *rl) { - size_t blocksize = 0; + size_t blocksize = 0, contenttypelen = 0; + size_t rchdrlen = tls_get_record_header_len(rl); if (rl->enc_ctx != NULL && (EVP_CIPHER_CTX_get_mode(rl->enc_ctx) == EVP_CIPH_CBC_MODE)) blocksize = EVP_CIPHER_CTX_get_block_size(rl->enc_ctx); + /* DTLSv1.3 adds an extra content type byte after payload data */ + if (rl->version == DTLS1_3_VERSION) + contenttypelen = 1; + /* * If we have a cipher in place then the tag is mandatory. If the cipher is * CBC mode then an explicit IV is also mandatory. If we know the digest, @@ -769,7 +1087,36 @@ static size_t dtls_get_max_record_overhead(OSSL_RECORD_LAYER *rl) * MTU size - so isn't very helpful. We just ignore potential expansion * due to compression. */ - return DTLS1_RT_HEADER_LENGTH + rl->eivlen + blocksize + rl->taglen; + return rchdrlen + rl->eivlen + blocksize + rl->taglen + contenttypelen; +} + +static int dtls_get_sequence_number(OSSL_RECORD_LAYER *rl, uint64_t *sequence) +{ + *sequence = rl->sequence; + return 1; +} + +static int dtls_set_sequence_number(OSSL_RECORD_LAYER *rl, uint64_t sequence) +{ + rl->sequence = sequence; + return 1; +} + +static int dtls_get_epoch(OSSL_RECORD_LAYER *rl, uint64_t *epoch) +{ + *epoch = rl->epoch; + return 1; +} + +static int dtls_set_curr_mtu(OSSL_RECORD_LAYER *rl, size_t mtu) +{ + rl->curr_mtu = mtu; + return 1; +} + +static size_t dtls_unprocessed_records(OSSL_RECORD_LAYER *rl) +{ + return pqueue_size(&rl->unprocessed_rcds); } const OSSL_RECORD_METHOD ossl_dtls_record_method = { @@ -785,8 +1132,14 @@ const OSSL_RECORD_METHOD ossl_dtls_record_method = { tls_release_record, tls_get_alert_code, tls_set1_bio, - tls_set_protocol_version, +#ifndef OPENSSL_NO_SOCK + tls_set1_peer, +#else NULL, +#endif + tls_set_use_urxe, + tls_set_protocol_version, + tls_set_plain_alerts, tls_set_first_handshake, tls_set_max_pipelines, dtls_set_in_init, @@ -795,7 +1148,12 @@ const OSSL_RECORD_METHOD ossl_dtls_record_method = { tls_get_compression, tls_set_max_frag_len, dtls_get_max_record_overhead, - tls_increment_sequence_ctr, + dtls_increment_sequence_ctr, + dtls_get_sequence_number, + dtls_set_sequence_number, + dtls_get_epoch, + dtls_set_curr_mtu, + dtls_unprocessed_records, tls_alloc_buffers, tls_free_buffers }; diff --git a/ssl/record/methods/ktls_meth.c b/ssl/record/methods/ktls_meth.c index fa29f5a175a3a..f09acd987efb6 100644 --- a/ssl/record/methods/ktls_meth.c +++ b/ssl/record/methods/ktls_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -284,9 +284,11 @@ static int ktls_configure_crypto(OSSL_LIB_CTX *libctx, int version, const EVP_CI #endif /* OPENSSL_SYS_LINUX */ static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, + unsigned char *snkey, unsigned char *key, size_t keylen, unsigned char *iv, size_t ivlen, unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *snciph, const EVP_CIPHER *ciph, size_t taglen, int mactype, @@ -294,6 +296,9 @@ static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, COMP_METHOD *comp) { ktls_crypto_info_t crypto_info; + unsigned char recseq[SEQ_NUM_SIZE], *p_recseq = recseq; + + l2n8(rl->sequence, p_recseq); /* * Check if we are suitable for KTLS. If not suitable we return @@ -322,7 +327,7 @@ static int ktls_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, return OSSL_RECORD_RETURN_NON_FATAL_ERR; } - if (!ktls_configure_crypto(rl->libctx, rl->version, ciph, md, rl->sequence, + if (!ktls_configure_crypto(rl->libctx, rl->version, ciph, md, recseq, &crypto_info, rl->direction == OSSL_RECORD_DIRECTION_WRITE, iv, ivlen, key, keylen, mackey, mackeylen)) @@ -397,15 +402,18 @@ static int ktls_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec) static int ktls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, - int role, int direction, int level, uint16_t epoch, + int role, int direction, int level, uint64_t epoch, unsigned char *secret, size_t secretlen, - unsigned char *key, size_t keylen, unsigned char *iv, - size_t ivlen, unsigned char *mackey, size_t mackeylen, + unsigned char *snkey, unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *snciph, const EVP_CIPHER *ciph, size_t taglen, int mactype, const EVP_MD *md, COMP_METHOD *comp, const EVP_MD *kdfdigest, BIO *prev, BIO *transport, BIO *next, + int use_urxe, const OSSL_PARAM *settings, const OSSL_PARAM *options, const OSSL_DISPATCH *fns, void *cbarg, void *rlarg, OSSL_RECORD_LAYER **retrl) @@ -422,9 +430,10 @@ ktls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, (*retrl)->funcs = &ossl_ktls_funcs; - ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv, - ivlen, mackey, mackeylen, ciph, - taglen, mactype, md, comp); + ret = (*retrl)->funcs->set_crypto_state(*retrl, level, snkey, key, keylen, + iv, ivlen, mackey, mackeylen, + snciph, ciph, taglen, mactype, md, + comp); if (ret != OSSL_RECORD_RETURN_SUCCESS) { tls_free(*retrl); @@ -586,6 +595,8 @@ const OSSL_RECORD_METHOD ossl_ktls_record_method = { tls_release_record, tls_get_alert_code, tls_set1_bio, + NULL, /* set1_peer: Not used for KTLS */ + NULL, /* set_use_urxe: Not used for KTLS */ tls_set_protocol_version, tls_set_plain_alerts, tls_set_first_handshake, @@ -597,6 +608,11 @@ const OSSL_RECORD_METHOD ossl_ktls_record_method = { tls_set_max_frag_len, NULL, tls_increment_sequence_ctr, + NULL, + NULL, + NULL, + NULL, + NULL, ktls_alloc_buffers, tls_free_buffers }; diff --git a/ssl/record/methods/recmethod_local.h b/ssl/record/methods/recmethod_local.h index c5cdfc6cfc6c6..6363f826955af 100644 --- a/ssl/record/methods/recmethod_local.h +++ b/ssl/record/methods/recmethod_local.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -19,8 +19,8 @@ typedef struct dtls_bitmap_st { /* Track 64 packets */ uint64_t map; - /* Max record number seen so far, 64-bit value in big-endian encoding */ - unsigned char max_seq_num[SEQ_NUM_SIZE]; + /* Max record number seen so far */ + uint64_t max_seq_num; } DTLS_BITMAP; typedef struct ssl_mac_buf_st { @@ -75,10 +75,10 @@ typedef struct tls_rl_record_st { unsigned char *comp; /* epoch number, needed by DTLS1 */ /* r */ - uint16_t epoch; + uint64_t epoch; /* sequence number, needed by DTLS1 */ /* r */ - unsigned char seq_num[SEQ_NUM_SIZE]; + uint64_t seq_num; } TLS_RL_RECORD; /* Macros/functions provided by the TLS_RL_RECORD component */ @@ -100,9 +100,11 @@ struct record_functions_st { * alternative record layer. */ int (*set_crypto_state)(OSSL_RECORD_LAYER *rl, int level, + unsigned char *snkey, unsigned char *key, size_t keylen, unsigned char *iv, size_t ivlen, unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *snciph, const EVP_CIPHER *ciph, size_t taglen, int mactype, @@ -220,7 +222,7 @@ struct ossl_record_layer_st { int level; const EVP_MD *md; /* DTLS only */ - uint16_t epoch; + uint64_t epoch; /* * A BIO containing any data read in the previous epoch that was destined @@ -272,7 +274,7 @@ struct ossl_record_layer_st { size_t packet_length; /* Sequence number for the next record */ - unsigned char sequence[SEQ_NUM_SIZE]; + uint64_t sequence; /* Alert code to be used if an error occurs */ int alert; @@ -293,6 +295,8 @@ struct ossl_record_layer_st { /* cryptographic state */ EVP_CIPHER_CTX *enc_ctx; + /* cryptographic state for DTLS 1.3 encrypted sequence numbers */ + EVP_CIPHER_CTX *sn_enc_ctx; /* TLSv1.3 MAC ctx, only used with integrity-only cipher */ EVP_MAC_CTX *mac_ctx; @@ -343,26 +347,53 @@ struct ossl_record_layer_st { size_t taglen; - /* DTLS received handshake records (processed and unprocessed) */ - struct pqueue_st *unprocessed_rcds; - struct pqueue_st *processed_rcds; + /* DTLS received handshake records awaiting the next epoch */ + pqueue unprocessed_rcds; /* records being received in the current epoch */ DTLS_BITMAP bitmap; - /* renegotiation starts a new set of sequence numbers */ - DTLS_BITMAP next_bitmap; + + /* DTLS curr mtu size */ + size_t curr_mtu; + +#ifndef OPENSSL_NO_SOCK + /* + * DTLS peer address for writes. When set (family != AF_UNSPEC), the + * record layer will use BIO_sendmmsg() with this address instead of + * BIO_write(). This is used by listener-created connections that share + * the listener's network BIO. + */ + BIO_ADDR peer; +#endif + + /* + * Use URXE queue for reading instead of BIO. Only set for listener-created + * DTLS connections where s->d1->rx exists. + */ + unsigned int use_urxe : 1; /* * Whether we are currently in a handshake or not. Only maintained for DTLS */ int in_init; + /* + * DTLSv1.3 uses encrypted sequence numbers in epoch 1 and beyond. + * For records that are buffered we need to put a priority on the + * buffered records. + */ + int dtls13_epoch_1_seq; + int dtls13_epoch_2_seq; + /* Callbacks */ void *cbarg; OSSL_FUNC_rlayer_skip_early_data_fn *skip_early_data; OSSL_FUNC_rlayer_msg_callback_fn *msg_callback; OSSL_FUNC_rlayer_security_fn *security; OSSL_FUNC_rlayer_padding_fn *padding; + OSSL_FUNC_rlayer_get_urxe_packet_fn *get_urxe_packet; + OSSL_FUNC_rlayer_release_urxe_packet_fn *release_urxe_packet; + OSSL_FUNC_rlayer_block_for_write_fn *block_for_write; size_t max_pipelines; @@ -373,7 +404,6 @@ struct ossl_record_layer_st { typedef struct dtls_rlayer_record_data_st { unsigned char *packet; size_t packet_length; - TLS_BUFFER rbuf; TLS_RL_RECORD rrec; } DTLS_RLAYER_RECORD_DATA; @@ -381,6 +411,7 @@ extern const struct record_functions_st tls_1_funcs; extern const struct record_functions_st tls_1_3_funcs; extern const struct record_functions_st tls_any_funcs; extern const struct record_functions_st dtls_1_funcs; +extern const struct record_functions_st dtls_1_3_funcs; extern const struct record_functions_st dtls_any_funcs; void ossl_rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason, @@ -398,9 +429,6 @@ void ossl_rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason, || (rl)->version == DTLS1_VERSION \ || (rl)->version == DTLS1_2_VERSION) -void ossl_tls_rl_record_set_seq_num(TLS_RL_RECORD *r, - const unsigned char *seq_num); - int ossl_set_tls_provider_parameters(OSSL_RECORD_LAYER *rl, EVP_CIPHER_CTX *ctx, const EVP_CIPHER *ciph, @@ -413,6 +441,33 @@ int tls_free_buffers(OSSL_RECORD_LAYER *rl); int tls_default_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend, int clearold, size_t *readbytes); int tls_get_more_records(OSSL_RECORD_LAYER *rl); + +/* Returns true if the unified header fixed bits are set (rfc9147 section 4) */ +#define DTLS13_UNI_HDR_FIX_BITS_IS_SET(byte) \ + (((byte) & DTLS13_UNI_HDR_FIX_BITS_MASK) == DTLS13_UNI_HDR_FIX_BITS) + +/* Returns true if the unified header connection id bit is set (rfc9147 section 4) */ +#define DTLS13_UNI_HDR_CID_BIT_IS_SET(byte) \ + (((byte) & DTLS13_UNI_HDR_CID_BIT) == DTLS13_UNI_HDR_CID_BIT) + +/* Returns true if the unified header sequence number bit is set (rfc9147 section 4) */ +#define DTLS13_UNI_HDR_SEQ_BIT_IS_SET(byte) \ + (((byte) & DTLS13_UNI_HDR_SEQ_BIT) == DTLS13_UNI_HDR_SEQ_BIT) + +/* Returns true if the unified header length bit is set (rfc9147 section 4) */ +#define DTLS13_UNI_HDR_LEN_BIT_IS_SET(byte) \ + (((byte) & DTLS13_UNI_HDR_LEN_BIT) == DTLS13_UNI_HDR_LEN_BIT) + +/* Low-order sequence number bits carried by a DTLS 1.3 unified header. */ +#define DTLS13_UNI_HDR_SEQ_MASK(len) \ + ((((uint64_t)1) << ((len) * 8)) - 1) + +uint64_t dtls13_reconstruct_seq_num(uint64_t max_seq_num, uint64_t truncated, + size_t seqlen); + +size_t dtls_get_rec_header_size(uint8_t hdr_first_byte); +int dtls_crypt_sequence_number(EVP_CIPHER_CTX *ctx, unsigned char *seq, size_t seqlen, + unsigned char *rec_data); int dtls_get_more_records(OSSL_RECORD_LAYER *rl); int dtls_prepare_record_header(OSSL_RECORD_LAYER *rl, @@ -428,6 +483,7 @@ int dtls_post_encryption_processing(OSSL_RECORD_LAYER *rl, int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version); int tls_default_validate_record_header(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *re); +size_t tls_get_record_header_len(OSSL_RECORD_LAYER *rl); int tls_do_compress(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *wr); int tls_do_uncompress(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec); int tls_default_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec); @@ -452,11 +508,14 @@ int tls_write_records(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates, int tls_retry_write_records(OSSL_RECORD_LAYER *rl); int tls_get_alert_code(OSSL_RECORD_LAYER *rl); int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio); +#ifndef OPENSSL_NO_SOCK +int tls_set1_peer(OSSL_RECORD_LAYER *rl, const BIO_ADDR *peer); +#endif +void tls_set_use_urxe(OSSL_RECORD_LAYER *rl, int use_urxe); int tls_read_record(OSSL_RECORD_LAYER *rl, void **rechandle, int *rversion, uint8_t *type, const unsigned char **data, size_t *datalen, - uint16_t *epoch, unsigned char *seq_num); + uint64_t *epoch, uint64_t *seq_num); int tls_release_record(OSSL_RECORD_LAYER *rl, void *rechandle, size_t length); -int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version); int tls_set_protocol_version(OSSL_RECORD_LAYER *rl, int version); void tls_set_plain_alerts(OSSL_RECORD_LAYER *rl, int allow); void tls_set_first_handshake(OSSL_RECORD_LAYER *rl, int first); @@ -480,6 +539,8 @@ size_t tls_get_max_records_default(OSSL_RECORD_LAYER *rl, uint8_t type, size_t tls_get_max_records_multiblock(OSSL_RECORD_LAYER *rl, uint8_t type, size_t len, size_t maxfrag, size_t *preffrag); +size_t tls_get_record_body_alignment_offset(OSSL_RECORD_LAYER *rl, + const unsigned char *rec); int tls_allocate_write_buffers_default(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates, size_t numtempl, size_t *prefix); diff --git a/ssl/record/methods/ssl3_cbc.c b/ssl/record/methods/ssl3_cbc.c index 133067ab15194..3f7ecfdbb58c2 100644 --- a/ssl/record/methods/ssl3_cbc.c +++ b/ssl/record/methods/ssl3_cbc.c @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2012-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/ssl/record/methods/tls13_meth.c b/ssl/record/methods/tls13_meth.c index e091d8d38216b..8fea9f7292be3 100644 --- a/ssl/record/methods/tls13_meth.c +++ b/ssl/record/methods/tls13_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -14,9 +14,11 @@ #include "recmethod_local.h" static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, + unsigned char *snkey, unsigned char *key, size_t keylen, unsigned char *iv, size_t ivlen, unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *snciph, const EVP_CIPHER *ciph, size_t taglen, int mactype, @@ -80,6 +82,26 @@ static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); return OSSL_RECORD_RETURN_FATAL; } + + if (rl->isdtls && snciph != NULL) { + EVP_CIPHER_CTX *sn_ciph_ctx; + + sn_ciph_ctx = rl->sn_enc_ctx = EVP_CIPHER_CTX_new(); + + if (sn_ciph_ctx == NULL) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + + if (EVP_CIPHER_CTX_set_padding(sn_ciph_ctx, 0) + || EVP_CipherInit_ex(sn_ciph_ctx, snciph, NULL, + snkey, NULL, 1) + <= 0) { + ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); + return OSSL_RECORD_RETURN_FATAL; + } + } + end: return OSSL_RECORD_RETURN_SUCCESS; } @@ -91,10 +113,12 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, EVP_CIPHER_CTX *enc_ctx; unsigned char recheader[SSL3_RT_HEADER_LENGTH]; unsigned char tag[EVP_MAX_MD_SIZE]; - size_t nonce_len, offset, loop, hdrlen, taglen; + size_t nonce_len, offset, loop, hdrlen, taglen, exphdrlen; + int isdtls, sbit = 0, addlen; unsigned char *staticiv; unsigned char *nonce; - unsigned char *seq = rl->sequence; + unsigned char seq[SEQ_NUM_SIZE], *p_seq = seq; + uint64_t seqnum = 0; int lenu, lenf; TLS_RL_RECORD *rec = &recs[0]; WPACKET wpkt; @@ -111,6 +135,8 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, enc_ctx = rl->enc_ctx; /* enc_ctx is ignored when rl->mac_ctx != NULL */ staticiv = rl->iv; nonce = rl->nonce; + isdtls = rl->isdtls; + l2n8(rl->sequence, p_seq); if (enc_ctx == NULL && rl->mac_ctx == NULL) { RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -118,17 +144,21 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, } /* - * If we're sending an alert and ctx != NULL then we must be forcing - * plaintext alerts. If we're reading and ctx != NULL then we allow - * plaintext alerts at certain points in the handshake. If we've got this - * far then we have already validated that a plaintext alert is ok here. + * Plaintext alerts are allowed only when explicitly enabled. DTLS needs + * this check here because it does not run the TLS header validator. */ if (rec->type == SSL3_RT_ALERT) { + if (!rl->allow_plain_alerts) + return 0; memmove(rec->data, rec->input, rec->length); rec->input = rec->data; return 1; } + /* Keyed DTLS 1.3 layers accept only unified headers. */ + if (isdtls && !DTLS13_UNI_HDR_FIX_BITS_IS_SET(rec->type)) + return 0; + /* For integrity-only ciphers, nonce_len is same as MAC size */ if (rl->mac_ctx != NULL) { nonce_len = EVP_MAC_CTX_get_mac_size(rl->mac_ctx); @@ -164,18 +194,57 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, for (loop = 0; loop < SEQ_NUM_SIZE; loop++) nonce[offset + loop] = staticiv[offset + loop] ^ seq[loop]; - if (!tls_increment_sequence_ctr(rl)) { + if (!isdtls && !tls_increment_sequence_ctr(rl)) { /* RLAYERfatal already called */ return 0; } - /* Set up the AAD */ + /*- + * Set up the additional data as described in rfc8446 section 5.2: + * "and the additional data input is the record header. + * I.e., + * additional_data = TLSCiphertext.opaque_type || + * TLSCiphertext.legacy_record_version || + * TLSCiphertext.length" + * and in rfc1947 section 4: + * "The entire header value shown in Figure 4 (but prior to record number + * encryption; see Section 4.2.3) is used as the additional data value for + * the AEAD function. For instance, if the minimal variant is used, the + * Associated Data (AD) is 2 octets long." + * + * For DTLS: at this point rec->type is just the first byte of the variable + * header. So it is not an actual record type. The record type is set in + * tls13_post_process_record() for incoming records. + */ + if (isdtls) { + exphdrlen = dtls_get_rec_header_size(rec->type); + sbit = DTLS13_UNI_HDR_SEQ_BIT_IS_SET(rec->type); + addlen = DTLS13_UNI_HDR_LEN_BIT_IS_SET(rec->type); + /* Match the truncated value encoded in the unified header. */ + seqnum = rl->sequence & DTLS13_UNI_HDR_SEQ_MASK(sbit ? 2 : 1); + } else { + exphdrlen = SSL3_RT_HEADER_LENGTH; + addlen = 1; + } + + /* + * Reject unsupported CID before WPACKET setup so cleanup cannot touch + * an uninitialised packet. + */ + if (isdtls && !ossl_assert(!DTLS13_UNI_HDR_CID_BIT_IS_SET(rec->type))) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + if (!WPACKET_init_static_len(&wpkt, recheader, sizeof(recheader), 0) || !WPACKET_put_bytes_u8(&wpkt, rec->type) - || !WPACKET_put_bytes_u16(&wpkt, rec->rec_version) - || !WPACKET_put_bytes_u16(&wpkt, rec->length + rl->taglen) + || (isdtls + && (sbit ? !WPACKET_put_bytes_u16(&wpkt, seqnum) + : !WPACKET_put_bytes_u8(&wpkt, seqnum))) + || (!isdtls && !WPACKET_put_bytes_u16(&wpkt, rec->rec_version)) + || (addlen && !WPACKET_put_bytes_u16(&wpkt, rec->length + rl->taglen)) || !WPACKET_get_total_written(&wpkt, &hdrlen) - || hdrlen != SSL3_RT_HEADER_LENGTH + || hdrlen != exphdrlen || !WPACKET_finish(&wpkt)) { RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); WPACKET_cleanup(&wpkt); @@ -187,7 +256,7 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, if ((mac_ctx = EVP_MAC_CTX_dup(rl->mac_ctx)) == NULL || !EVP_MAC_update(mac_ctx, nonce, nonce_len) - || !EVP_MAC_update(mac_ctx, recheader, sizeof(recheader)) + || !EVP_MAC_update(mac_ctx, recheader, hdrlen) || !EVP_MAC_update(mac_ctx, rec->input, rec->length) || !EVP_MAC_final(mac_ctx, tag, &taglen, rl->taglen)) { RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -226,15 +295,9 @@ static int tls13_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, * any AAD. */ if ((mode == EVP_CIPH_CCM_MODE - && EVP_CipherUpdate(enc_ctx, NULL, &lenu, NULL, - (unsigned int)rec->length) - <= 0) - || EVP_CipherUpdate(enc_ctx, NULL, &lenu, recheader, - sizeof(recheader)) - <= 0 - || EVP_CipherUpdate(enc_ctx, rec->data, &lenu, rec->input, - (unsigned int)rec->length) - <= 0 + && EVP_CipherUpdate(enc_ctx, NULL, &lenu, NULL, (int)rec->length) <= 0) + || EVP_CipherUpdate(enc_ctx, NULL, &lenu, recheader, (int)hdrlen) <= 0 + || EVP_CipherUpdate(enc_ctx, rec->data, &lenu, rec->input, (int)rec->length) <= 0 || EVP_CipherFinal_ex(enc_ctx, rec->data + lenu, &lenf) <= 0 || (size_t)lenu + lenf != rec->length) { return 0; @@ -284,7 +347,9 @@ static int tls13_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec) size_t end; if (rec->length == 0 - || rec->type != SSL3_RT_APPLICATION_DATA) { + || (rl->isdtls + ? !DTLS13_UNI_HDR_FIX_BITS_IS_SET(rec->type) + : rec->type != SSL3_RT_APPLICATION_DATA)) { RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE); return 0; @@ -322,6 +387,15 @@ static uint8_t tls13_get_record_type(OSSL_RECORD_LAYER *rl, * when encrypting in TLSv1.3. The "inner" record type encodes the "real" * record type from the template. */ + if (rl->isdtls) { + const unsigned char fixed = DTLS13_UNI_HDR_FIX_BITS; + const unsigned char sbit = DTLS13_UNI_HDR_SEQ_BIT; + const unsigned char lbit = DTLS13_UNI_HDR_LEN_BIT; + const unsigned char epochbits = DTLS13_UNI_HDR_EPOCH_BITS_MASK & rl->epoch; + + return fixed | sbit | lbit | epochbits; + } + return SSL3_RT_APPLICATION_DATA; } @@ -331,6 +405,10 @@ static int tls13_add_record_padding(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *thiswr) { size_t rlen; + size_t max_frag_len = rl->max_frag_len; + int isdtls = rl->isdtls; + size_t mac_size = 0; + size_t taglen = rl->taglen; /* Nothing to be done in the case of a plaintext alert */ if (rl->allow_plain_alerts && thistempl->type != SSL3_RT_ALERT) @@ -342,11 +420,14 @@ static int tls13_add_record_padding(OSSL_RECORD_LAYER *rl, } TLS_RL_RECORD_add_length(thiswr, 1); + if (rl->isdtls && rl->curr_mtu != 0 && rl->curr_mtu < max_frag_len) + max_frag_len = rl->curr_mtu; + /* Add TLS1.3 padding */ rlen = TLS_RL_RECORD_get_length(thiswr); - if (rlen < rl->max_frag_len) { + if (rlen < max_frag_len) { size_t padding = 0; - size_t max_padding = rl->max_frag_len - rlen; + size_t max_padding = max_frag_len - rlen; /* * We might want to change the "else if" below so that @@ -394,6 +475,19 @@ static int tls13_add_record_padding(OSSL_RECORD_LAYER *rl, padding = bp - remainder; } } + + /* + * DTLS1.3 RFC 9147 Section 4.2.3 says records should be padded + * if the ciphertext is less than 16 bytes. + */ + if (isdtls) { + if (rl->mac_ctx != NULL) + mac_size = EVP_MAC_CTX_get_mac_size(rl->mac_ctx); + + if (padding + rlen + taglen + mac_size < DTLS13_CIPHERTEXT_MINSIZE) + padding += DTLS13_CIPHERTEXT_MINSIZE - (padding + rlen + taglen + mac_size); + } + if (padding > 0) { /* do not allow the record to exceed max plaintext length */ if (padding > max_padding) @@ -430,3 +524,28 @@ const struct record_functions_st tls_1_3_funcs = { tls_post_encryption_processing_default, NULL }; + +const struct record_functions_st dtls_1_3_funcs = { + tls13_set_crypto_state, + tls13_cipher, + NULL, + tls_default_set_protocol_version, + tls_default_read_n, + dtls_get_more_records, + /* + * Keep this NULL: the TLS validator raises fatal errors, while DTLS must + * silently discard invalid records (RFC 9147 section 4.5.2). + */ + NULL, + tls13_post_process_record, + NULL, + tls_write_records_default, + tls_allocate_write_buffers_default, + tls_initialise_write_packets_default, + tls13_get_record_type, + dtls_prepare_record_header, + tls13_add_record_padding, + tls_prepare_for_encryption_default, + dtls_post_encryption_processing, + NULL +}; diff --git a/ssl/record/methods/tls1_meth.c b/ssl/record/methods/tls1_meth.c index 717e1ed3ffb7b..94d4b6879ba47 100644 --- a/ssl/record/methods/tls1_meth.c +++ b/ssl/record/methods/tls1_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,9 +17,11 @@ #include "recmethod_local.h" static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, + unsigned char *snkey, unsigned char *key, size_t keylen, unsigned char *iv, size_t ivlen, unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *snciph, const EVP_CIPHER *ciph, size_t taglen, int mactype, @@ -167,6 +169,31 @@ static int tls1_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, return OSSL_RECORD_RETURN_SUCCESS; } +static int setup_record_header(const OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec, + unsigned char *buf, size_t buflen) +{ + WPACKET hdr; + size_t hdrsize; + + if (buflen < EVP_AEAD_TLS1_AAD_LEN) + return 0; + if (!WPACKET_init_static_len(&hdr, buf, EVP_AEAD_TLS1_AAD_LEN, 0) + || (rl->isdtls && !WPACKET_put_bytes_u16(&hdr, rl->epoch)) + || (rl->isdtls ? !WPACKET_put_bytes_u48(&hdr, rl->sequence) + : !WPACKET_put_bytes_u64(&hdr, rl->sequence)) + || !WPACKET_put_bytes_u8(&hdr, rec->type) + || !WPACKET_put_bytes_u16(&hdr, rl->version) + || !WPACKET_put_bytes_u16(&hdr, rec->length) + || !WPACKET_finish(&hdr) + || !WPACKET_get_total_written(&hdr, &hdrsize) + || hdrsize != EVP_AEAD_TLS1_AAD_LEN) { + WPACKET_cleanup(&hdr); + return 0; + } + + return 1; +} + #define MAX_PADDING 256 /*- * tls1_cipher encrypts/decrypts |n_recs| in |recs|. Calls RLAYERfatal on @@ -265,29 +292,16 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, if ((EVP_CIPHER_get_flags(EVP_CIPHER_CTX_get0_cipher(ds)) & EVP_CIPH_FLAG_AEAD_CIPHER) != 0) { - unsigned char *seq; - - seq = rl->sequence; - - if (rl->isdtls) { - unsigned char dtlsseq[8], *p = dtlsseq; + if (!setup_record_header(rl, &recs[ctr], buf[ctr], sizeof(buf[ctr]))) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } - s2n(rl->epoch, p); - memcpy(p, &seq[2], 6); - memcpy(buf[ctr], dtlsseq, 8); - } else { - memcpy(buf[ctr], seq, 8); - if (!tls_increment_sequence_ctr(rl)) { - /* RLAYERfatal already called */ - return 0; - } + if (!rl->isdtls && !tls_increment_sequence_ctr(rl)) { + /* RLAYERfatal already called */ + return 0; } - buf[ctr][8] = recs[ctr].type; - buf[ctr][9] = (unsigned char)(rl->version >> 8); - buf[ctr][10] = (unsigned char)(rl->version); - buf[ctr][11] = (unsigned char)(recs[ctr].length >> 8); - buf[ctr][12] = (unsigned char)(recs[ctr].length & 0xff); pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD, EVP_AEAD_TLS1_AAD_LEN, buf[ctr]); if (pad <= 0) { @@ -336,6 +350,9 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, if (!rl->isdtls && rl->tlstree) { int decrement_seq = 0; + unsigned char recseq[SEQ_NUM_SIZE], *p_recseq = recseq; + + l2n8(rl->sequence, p_recseq); /* * When sending, seq is incremented after MAC calculation. @@ -345,10 +362,7 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, if (sending && !rl->use_etm) decrement_seq = 1; - if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_TLSTREE, decrement_seq, - rl->sequence) - <= 0) { - + if (EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_TLSTREE, decrement_seq, recseq) <= 0) { RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } @@ -361,7 +375,7 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, } if (!EVP_CipherUpdate(ds, recs[0].data, &outlen, recs[0].input, - (unsigned int)reclen[0])) + (int)reclen[0])) return 0; recs[0].length = outlen; @@ -410,7 +424,7 @@ static int tls1_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, static int tls1_mac(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec, unsigned char *md, int sending) { - unsigned char *seq = rl->sequence; + unsigned char seq[SEQ_NUM_SIZE], *p_seq = seq; EVP_MD_CTX *hash; size_t md_size; EVP_MD_CTX *hmac = NULL, *mac_ctx; @@ -420,6 +434,7 @@ static int tls1_mac(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec, unsigned char *md int ret = 0; hash = rl->md_ctx; + l2n8(rl->sequence, p_seq); t = EVP_MD_CTX_get_size(hash); if (!ossl_assert(t >= 0)) @@ -441,22 +456,8 @@ static int tls1_mac(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec, unsigned char *md && EVP_MD_CTX_ctrl(mac_ctx, EVP_MD_CTRL_TLSTREE, 0, seq) <= 0) goto end; - if (rl->isdtls) { - unsigned char dtlsseq[8], *p = dtlsseq; - - s2n(rl->epoch, p); - memcpy(p, &seq[2], 6); - - memcpy(header, dtlsseq, 8); - } else { - memcpy(header, seq, 8); - } - - header[8] = rec->type; - header[9] = (unsigned char)(rl->version >> 8); - header[10] = (unsigned char)(rl->version); - header[11] = (unsigned char)(rec->length >> 8); - header[12] = (unsigned char)(rec->length & 0xff); + if (!setup_record_header(rl, rec, header, sizeof(header))) + goto end; if (!sending && !rl->use_etm && EVP_CIPHER_CTX_get_mode(rl->enc_ctx) == EVP_CIPH_CBC_MODE @@ -578,12 +579,7 @@ int tls1_initialise_write_packets(OSSL_RECORD_LAYER *rl, prefixtempl->type = SSL3_RT_APPLICATION_DATA; wb = &bufs[0]; - -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0 - align = (size_t)TLS_BUFFER_get_buf(wb) + SSL3_RT_HEADER_LENGTH; - align = SSL3_ALIGN_PAYLOAD - 1 - - ((align - 1) % SSL3_ALIGN_PAYLOAD); -#endif + align = tls_get_record_body_alignment_offset(rl, TLS_BUFFER_get_buf(wb)); TLS_BUFFER_set_offset(wb, align); if (!WPACKET_init_static_len(&pkt[0], TLS_BUFFER_get_buf(wb), diff --git a/ssl/record/methods/tls_common.c b/ssl/record/methods/tls_common.c index 0363bf23bf2b0..180993bf20599 100644 --- a/ssl/record/methods/tls_common.c +++ b/ssl/record/methods/tls_common.c @@ -17,6 +17,7 @@ #include "internal/e_os.h" #include "internal/packet.h" #include "internal/ssl3_cbc.h" +#include "internal/dtls_record_rx.h" #include "../../ssl_local.h" #include "../record_local.h" #include "recmethod_local.h" @@ -39,12 +40,6 @@ static void TLS_RL_RECORD_release(TLS_RL_RECORD *r, size_t num_recs) } } -void ossl_tls_rl_record_set_seq_num(TLS_RL_RECORD *r, - const unsigned char *seq_num) -{ - memcpy(r->seq_num, seq_num, SEQ_NUM_SIZE); -} - void ossl_rlayer_fatal(OSSL_RECORD_LAYER *rl, int al, int reason, const char *fmt, ...) { @@ -148,15 +143,13 @@ int tls_setup_write_buffer(OSSL_RECORD_LAYER *rl, size_t numwpipes, size_t currpipe; size_t defltlen = 0; size_t contenttypelen = 0; + const int version1_3 = rl->isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION; if (firstlen == 0 || (numwpipes > 1 && nextlen == 0)) { - if (rl->isdtls) - headerlen = DTLS1_RT_HEADER_LENGTH + 1; - else - headerlen = SSL3_RT_HEADER_LENGTH; + headerlen = tls_get_record_header_len(rl); - /* TLSv1.3 adds an extra content type byte after payload data */ - if (rl->version == TLS1_3_VERSION) + /* (D)TLSv1.3 adds an extra content type byte after payload data */ + if (rl->version == version1_3) contenttypelen = 1; #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0 @@ -234,10 +227,7 @@ int tls_setup_read_buffer(OSSL_RECORD_LAYER *rl) b = &rl->rbuf; - if (rl->isdtls) - headerlen = DTLS1_RT_HEADER_LENGTH; - else - headerlen = SSL3_RT_HEADER_LENGTH; + headerlen = tls_get_record_header_len(rl); #if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0 maxalign = SSL3_ALIGN_PAYLOAD - 1; @@ -402,7 +392,43 @@ int tls_default_read_n(OSSL_RECORD_LAYER *rl, size_t n, size_t max, int extend, */ clear_sys_error(); - if (bio != NULL) { + + /* + * For listener-based connections, read from the packet queue instead + * of the BIO. These connections are identified by having peer set and + * a get_packet callback. + * + * However, we must first check rl->prev for buffered records from + * a previous epoch's record layer. + */ +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + if (rl->isdtls && rl->use_urxe + && rl->prev == NULL && rl->get_urxe_packet != NULL) { + unsigned char *pkt_data = NULL; + size_t pkt_len = 0; + void *pkt_handle = NULL; + + if (rl->get_urxe_packet(rl->cbarg, &pkt_data, &pkt_len, &pkt_handle)) { + size_t urxe_data_read = pkt_len; + + if (urxe_data_read > max - left) + urxe_data_read = max - left; + + /* TODO: DTLS1.3 QUIC avoids the copy can we avoid the copy here */ + memcpy(pkt + len + left, pkt_data, urxe_data_read); + bioread = urxe_data_read; + ret = OSSL_RECORD_RETURN_SUCCESS; + + /* Release packet back via callback */ + if (rl->release_urxe_packet != NULL) + rl->release_urxe_packet(rl->cbarg, pkt_handle); + } else { + /* No packets available */ + ret = OSSL_RECORD_RETURN_RETRY; + } + } else +#endif + if (bio != NULL) { ret = BIO_read(bio, pkt + len + left, (int)(max - left)); if (ret > 0) { bioread = ret; @@ -596,7 +622,7 @@ int tls_get_more_records(OSSL_RECORD_LAYER *rl) || !PACKET_get_net_2(&pkt, &version) || !PACKET_get_net_2_len(&pkt, &thisrr->length)) { if (rl->msg_callback != NULL) - rl->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, rl->cbarg); + rl->msg_callback(0, 0, SSL3_RT_HEADER, p, SSL3_RT_HEADER_LENGTH, rl->cbarg); RLAYERfatal(rl, SSL_AD_DECODE_ERROR, ERR_R_INTERNAL_ERROR); return OSSL_RECORD_RETURN_FATAL; } @@ -604,7 +630,7 @@ int tls_get_more_records(OSSL_RECORD_LAYER *rl) thisrr->rec_version = version; if (rl->msg_callback != NULL) - rl->msg_callback(0, version, SSL3_RT_HEADER, p, 5, rl->cbarg); + rl->msg_callback(0, version, SSL3_RT_HEADER, p, SSL3_RT_HEADER_LENGTH, rl->cbarg); if (!rl->funcs->validate_record_header(rl, thisrr)) { /* RLAYERfatal already called */ @@ -800,7 +826,7 @@ int tls_get_more_records(OSSL_RECORD_LAYER *rl) rl->curr_rec = 0; rl->num_released = 0; /* Reset the read sequence */ - memset(rl->sequence, 0, sizeof(rl->sequence)); + rl->sequence = 0; ret = 1; goto end; } @@ -1028,7 +1054,8 @@ int tls13_common_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec) { if (rec->type != SSL3_RT_APPLICATION_DATA && rec->type != SSL3_RT_ALERT - && rec->type != SSL3_RT_HANDSHAKE) { + && rec->type != SSL3_RT_HANDSHAKE + && (!rl->isdtls || rec->type != SSL3_RT_ACK)) { RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE); return 0; } @@ -1055,7 +1082,7 @@ int tls13_common_post_process_record(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec) int tls_read_record(OSSL_RECORD_LAYER *rl, void **rechandle, int *rversion, uint8_t *type, const unsigned char **data, size_t *datalen, - uint16_t *epoch, unsigned char *seq_num) + uint64_t *epoch, uint64_t *seq_num) { TLS_RL_RECORD *rec; @@ -1092,7 +1119,7 @@ int tls_read_record(OSSL_RECORD_LAYER *rl, void **rechandle, int *rversion, *datalen = rec->length; if (rl->isdtls) { *epoch = rec->epoch; - memcpy(seq_num, rec->seq_num, sizeof(rec->seq_num)); + *seq_num = rec->seq_num; } return OSSL_RECORD_RETURN_SUCCESS; @@ -1213,6 +1240,8 @@ int tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, */ rl->max_frag_len = SSL3_RT_MAX_PLAIN_LENGTH; + rl->curr_mtu = 0; + /* Loop through all the settings since they must all be understood */ if (settings != NULL) { for (p = settings; p->key != NULL; p++) { @@ -1298,6 +1327,16 @@ int tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, break; case OSSL_FUNC_RLAYER_PADDING: rl->padding = OSSL_FUNC_rlayer_padding(fns); + break; + case OSSL_FUNC_RLAYER_GET_URXE_PACKET: + rl->get_urxe_packet = OSSL_FUNC_rlayer_get_urxe_packet(fns); + break; + case OSSL_FUNC_RLAYER_RELEASE_URXE_PACKET: + rl->release_urxe_packet = OSSL_FUNC_rlayer_release_urxe_packet(fns); + break; + case OSSL_FUNC_RLAYER_BLOCK_FOR_WRITE: + rl->block_for_write = OSSL_FUNC_rlayer_block_for_write(fns); + break; default: /* Just ignore anything we don't understand */ break; @@ -1330,15 +1369,18 @@ int tls_int_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, static int tls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, - int role, int direction, int level, uint16_t epoch, + int role, int direction, int level, uint64_t epoch, unsigned char *secret, size_t secretlen, - unsigned char *key, size_t keylen, unsigned char *iv, - size_t ivlen, unsigned char *mackey, size_t mackeylen, + unsigned char *snkey, unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen, + unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *snciph, const EVP_CIPHER *ciph, size_t taglen, int mactype, const EVP_MD *md, COMP_METHOD *comp, const EVP_MD *kdfdigest, BIO *prev, BIO *transport, BIO *next, + int use_urxe, const OSSL_PARAM *settings, const OSSL_PARAM *options, const OSSL_DISPATCH *fns, void *cbarg, void *rlarg, OSSL_RECORD_LAYER **retrl) @@ -1372,9 +1414,10 @@ tls_new_record_layer(OSSL_LIB_CTX *libctx, const char *propq, int vers, goto err; } - ret = (*retrl)->funcs->set_crypto_state(*retrl, level, key, keylen, iv, - ivlen, mackey, mackeylen, ciph, - taglen, mactype, md, comp); + ret = (*retrl)->funcs->set_crypto_state(*retrl, level, snkey, key, keylen, + iv, ivlen, mackey, mackeylen, + snciph, ciph, taglen, mactype, md, + comp); err: if (ret != OSSL_RECORD_RETURN_SUCCESS) { @@ -1394,6 +1437,7 @@ static void tls_int_free(OSSL_RECORD_LAYER *rl) tls_release_write_buffer(rl); EVP_CIPHER_CTX_free(rl->enc_ctx); + EVP_CIPHER_CTX_free(rl->sn_enc_ctx); EVP_MAC_CTX_free(rl->mac_ctx); EVP_MD_CTX_free(rl->md_ctx); #ifndef OPENSSL_NO_COMP @@ -1499,6 +1543,21 @@ int tls_allocate_write_buffers_default(OSSL_RECORD_LAYER *rl, return 1; } +size_t tls_get_record_body_alignment_offset(OSSL_RECORD_LAYER *rl, + const unsigned char *rec) +{ + size_t alignoffset = 0; + size_t headersize = tls_get_record_header_len(rl); + +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0 + alignoffset = (size_t)rec; + alignoffset += headersize; + alignoffset = SSL3_ALIGN_PAYLOAD - 1 - ((alignoffset - 1) % SSL3_ALIGN_PAYLOAD); +#endif + + return alignoffset; +} + int tls_initialise_write_packets_default(OSSL_RECORD_LAYER *rl, OSSL_RECORD_TEMPLATE *templates, size_t numtempl, @@ -1516,13 +1575,7 @@ int tls_initialise_write_packets_default(OSSL_RECORD_LAYER *rl, wb = &bufs[j]; wb->type = templates[j].type; - -#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0 - align = (size_t)TLS_BUFFER_get_buf(wb); - align += rl->isdtls ? DTLS1_RT_HEADER_LENGTH : SSL3_RT_HEADER_LENGTH; - align = SSL3_ALIGN_PAYLOAD - 1 - - ((align - 1) % SSL3_ALIGN_PAYLOAD); -#endif + align = tls_get_record_body_alignment_offset(rl, TLS_BUFFER_get_buf(wb)); TLS_BUFFER_set_offset(wb, align); if (!WPACKET_init_static_len(thispkt, TLS_BUFFER_get_buf(wb), @@ -1625,8 +1678,9 @@ int tls_post_encryption_processing_default(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *thiswr) { size_t origlen, len; - size_t headerlen = rl->isdtls ? DTLS1_RT_HEADER_LENGTH - : SSL3_RT_HEADER_LENGTH; + unsigned char *recordstart; + size_t rechdrlen; + size_t written; /* Allocate bytes for the encryption overhead */ if (!WPACKET_get_length(thispkt, &origlen) @@ -1656,19 +1710,39 @@ int tls_post_encryption_processing_default(OSSL_RECORD_LAYER *rl, } if (!WPACKET_get_length(thispkt, &len) - || !WPACKET_close(thispkt)) { + || !WPACKET_close(thispkt) + || !WPACKET_get_total_written(thispkt, &written)) { RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } + recordstart = WPACKET_get_curr(thispkt) - written; + recordstart += tls_get_record_body_alignment_offset(rl, recordstart); + + if (rl->isdtls) + rechdrlen = dtls_get_rec_header_size(*recordstart); + else + rechdrlen = SSL3_RT_HEADER_LENGTH; + + if (rl->isdtls && DTLS13_UNI_HDR_FIX_BITS_IS_SET(*recordstart)) { + size_t seqnumlen = DTLS13_UNI_HDR_SEQ_BIT_IS_SET(*recordstart) ? 2 : 1; + + if (!ossl_assert(DTLS13_UNI_HDR_SEQ_OFF + seqnumlen <= rechdrlen) + || (rl->sn_enc_ctx != NULL + && !dtls_crypt_sequence_number(rl->sn_enc_ctx, recordstart + DTLS13_UNI_HDR_SEQ_OFF, + seqnumlen, recordstart + rechdrlen))) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + } + if (rl->msg_callback != NULL) { - unsigned char *recordstart; + const int version1_3 = rl->isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION; - recordstart = WPACKET_get_curr(thispkt) - len - headerlen; rl->msg_callback(1, thiswr->rec_version, SSL3_RT_HEADER, recordstart, - headerlen, rl->cbarg); + rechdrlen, rl->cbarg); - if (rl->version == TLS1_3_VERSION && rl->enc_ctx != NULL) { + if (rl->version == version1_3 && rl->enc_ctx != NULL) { unsigned char ctype = thistempl->type; rl->msg_callback(1, thiswr->rec_version, SSL3_RT_INNER_CONTENT_TYPE, @@ -1681,7 +1755,7 @@ int tls_post_encryption_processing_default(OSSL_RECORD_LAYER *rl, return 0; } - TLS_RL_RECORD_add_length(thiswr, headerlen); + TLS_RL_RECORD_add_length(thiswr, rechdrlen); return 1; } @@ -1849,13 +1923,14 @@ int tls_retry_write_records(OSSL_RECORD_LAYER *rl) { int i, ret; TLS_BUFFER *thiswb; - size_t tmpwrit = 0; + size_t tmpwrit = 0, left; if (rl->nextwbuf >= rl->numwpipes) return OSSL_RECORD_RETURN_SUCCESS; for (;;) { thiswb = &rl->wbuf[rl->nextwbuf]; + left = TLS_BUFFER_get_left(thiswb); clear_sys_error(); if (rl->bio != NULL) { @@ -1864,21 +1939,94 @@ int tls_retry_write_records(OSSL_RECORD_LAYER *rl) if (ret != OSSL_RECORD_RETURN_SUCCESS) return ret; } - i = BIO_write(rl->bio, (char *)&(TLS_BUFFER_get_buf(thiswb)[TLS_BUFFER_get_offset(thiswb)]), - (unsigned int)TLS_BUFFER_get_left(thiswb)); - if (i >= 0) { - tmpwrit = i; - if (i == 0 && BIO_should_retry(rl->bio)) - ret = OSSL_RECORD_RETURN_RETRY; - else + +#ifndef OPENSSL_NO_SOCK + /* + * For DTLS connections created via a listener we need to + * call BIO_sendmmsg() to send the datagrams to the correct + * peer address. + */ + if (rl->isdtls && BIO_ADDR_family(&rl->peer) != AF_UNSPEC) { + BIO_MSG msg; + size_t processed = 0; + + memset(&msg, 0, sizeof(msg)); + msg.data = (char *)&(TLS_BUFFER_get_buf(thiswb)[TLS_BUFFER_get_offset(thiswb)]); + msg.data_len = left; + msg.peer = &rl->peer; + + ERR_set_mark(); + if (BIO_sendmmsg(rl->bio, &msg, sizeof(msg), 1, 0, &processed) + && processed == 1) { + ERR_clear_last_mark(); + tmpwrit = msg.data_len; ret = OSSL_RECORD_RETURN_SUCCESS; - } else { - if (BIO_should_retry(rl->bio)) { - ret = OSSL_RECORD_RETURN_RETRY; + i = (int)tmpwrit; + } else { + unsigned long err = ERR_peek_last_error(); + /* + * For BIO_sendmmsg, we use BIO_err_is_non_fatal() instead + * of BIO_should_retry() to check for transient errors. + */ + if (BIO_err_is_non_fatal(err)) { + ERR_pop_to_mark(); + + /* + * A connection in blocking mode waits for the socket to + * become writable and sends again, rather than reporting + * a retry. Nothing has been consumed, so the next time + * round the loop repeats this same send. + * + * Only listener based connections install this callback. + * Anything else either has a socket of its own to block + * in or is genuinely non-blocking, and keeps the + * behaviour below. + */ + if (rl->block_for_write != NULL + && rl->block_for_write(rl->cbarg)) + continue; + + ret = OSSL_RECORD_RETURN_RETRY; + i = 0; + tmpwrit = 0; + } else { + ERR_clear_last_mark(); + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "tls_retry_write_records BIO_sendmmsg failure"); + ret = OSSL_RECORD_RETURN_FATAL; + i = -1; + } + } + } else +#endif + { + i = BIO_write(rl->bio, (char *)&(TLS_BUFFER_get_buf(thiswb)[TLS_BUFFER_get_offset(thiswb)]), + (unsigned int)left); + if (i >= 0) { + tmpwrit = i; + if (i == 0 && left != 0) { + if (BIO_should_retry(rl->bio)) { + ret = OSSL_RECORD_RETURN_RETRY; + } else { + /* + * Treat this as a fatal I/O condition. Do not queue an + * SSL reason: a zero return with no retry flag may come + * from a custom BIO and does not imply an SSL library + * or protocol error. + */ + ret = OSSL_RECORD_RETURN_FATAL; + } + } else { + ret = OSSL_RECORD_RETURN_SUCCESS; + } } else { - ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), - "tls_retry_write_records failure"); - ret = OSSL_RECORD_RETURN_FATAL; + if (BIO_should_retry(rl->bio)) { + ret = OSSL_RECORD_RETURN_RETRY; + } else { + ERR_raise_data(ERR_LIB_SYS, get_last_sys_error(), + "tls_retry_write_records failure"); + ret = OSSL_RECORD_RETURN_FATAL; + } } } } else { @@ -1894,7 +2042,7 @@ int tls_retry_write_records(OSSL_RECORD_LAYER *rl) * Treat i == 0 as success rather than an error for zero byte * writes to permit this case. */ - if (i >= 0 && tmpwrit == TLS_BUFFER_get_left(thiswb)) { + if (i >= 0 && tmpwrit == left) { TLS_BUFFER_set_left(thiswb, 0); TLS_BUFFER_add_offset(thiswb, tmpwrit); if (++(rl->nextwbuf) < rl->numwpipes) @@ -1912,9 +2060,9 @@ int tls_retry_write_records(OSSL_RECORD_LAYER *rl) */ if (TLS_BUFFER_is_app_buffer(thiswb) && (rl->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) != 0) { - size_t left = TLS_BUFFER_get_left(thiswb); unsigned char *buf; + left = TLS_BUFFER_get_left(thiswb); buf = OPENSSL_malloc(left); if (buf == NULL) { RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -1959,6 +2107,43 @@ int tls_set1_bio(OSSL_RECORD_LAYER *rl, BIO *bio) return 1; } +#ifndef OPENSSL_NO_SOCK +int tls_set1_peer(OSSL_RECORD_LAYER *rl, const BIO_ADDR *peer) +{ + if (!rl->isdtls) { + /* Non-DTLS record layers don't use peer address - no-op */ + return 1; + } + + if (peer != NULL) + return BIO_ADDR_copy(&rl->peer, peer); + + BIO_ADDR_clear(&rl->peer); + return 1; +} +#endif + +void tls_set_use_urxe(OSSL_RECORD_LAYER *rl, int use_urxe) +{ + rl->use_urxe = use_urxe; +} + +size_t tls_get_record_header_len(OSSL_RECORD_LAYER *rl) +{ + size_t headerlen; + + if (rl->isdtls) { + if (rl->version == DTLS1_3_VERSION && rl->epoch > 0) + headerlen = DTLS13_UNI_HDR_FIXED_LENGTH; + else + headerlen = DTLS1_RT_HEADER_LENGTH; + } else { + headerlen = SSL3_RT_HEADER_LENGTH; + } + + return headerlen; +} + /* Shared by most methods except tlsany_meth */ int tls_default_set_protocol_version(OSSL_RECORD_LAYER *rl, int version) { @@ -2037,15 +2222,8 @@ void tls_set_max_frag_len(OSSL_RECORD_LAYER *rl, size_t max_frag_len) int tls_increment_sequence_ctr(OSSL_RECORD_LAYER *rl) { - int i; - /* Increment the sequence counter */ - for (i = SEQ_NUM_SIZE; i > 0; i--) { - ++(rl->sequence[i - 1]); - if (rl->sequence[i - 1] != 0) - break; - } - if (i == 0) { + if (++rl->sequence == 0) { /* Sequence has wrapped */ RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, SSL_R_SEQUENCE_CTR_WRAPPED); return 0; @@ -2129,6 +2307,8 @@ const OSSL_RECORD_METHOD ossl_tls_record_method = { tls_release_record, tls_get_alert_code, tls_set1_bio, + NULL, /* set1_peer: Not used for TLS */ + NULL, /* set_use_urxe: Not used for TLS */ tls_set_protocol_version, tls_set_plain_alerts, tls_set_first_handshake, @@ -2140,6 +2320,11 @@ const OSSL_RECORD_METHOD ossl_tls_record_method = { tls_set_max_frag_len, NULL, tls_increment_sequence_ctr, + NULL, + NULL, + NULL, + NULL, + NULL, tls_alloc_buffers, tls_free_buffers }; diff --git a/ssl/record/methods/tls_multib.c b/ssl/record/methods/tls_multib.c index 20acadd2e7387..b311bc0b91b65 100644 --- a/ssl/record/methods/tls_multib.c +++ b/ssl/record/methods/tls_multib.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -66,9 +66,10 @@ static int tls_write_records_multiblock_int(OSSL_RECORD_LAYER *rl, { #if !defined(OPENSSL_NO_MULTIBLOCK) && EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK size_t i; - size_t totlen; + size_t totlen, aad_written; TLS_BUFFER *wb; unsigned char aad[13]; + WPACKET aad_pkt; EVP_CTRL_TLS1_1_MULTIBLOCK_PARAM mb_param; size_t packlen; int packleni; @@ -116,13 +117,20 @@ static int tls_write_records_multiblock_int(OSSL_RECORD_LAYER *rl, } wb = &rl->wbuf[0]; + if (!WPACKET_init_static_len(&aad_pkt, aad, sizeof(aad), 0) + || !WPACKET_put_bytes_u64(&aad_pkt, rl->sequence) + || !WPACKET_put_bytes_u8(&aad_pkt, templates[0].type) + || !WPACKET_put_bytes_u16(&aad_pkt, templates[0].version) + || !WPACKET_put_bytes_u16(&aad_pkt, 0) + || !WPACKET_get_total_written(&aad_pkt, &aad_written) + || aad_written != sizeof(aad) + || !WPACKET_finish(&aad_pkt)) { + WPACKET_cleanup(&aad_pkt); + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return -1; + } + mb_param.interleave = (unsigned int)numtempl; - memcpy(aad, rl->sequence, 8); - aad[8] = templates[0].type; - aad[9] = (unsigned char)(templates[0].version >> 8); - aad[10] = (unsigned char)(templates[0].version); - aad[11] = 0; - aad[12] = 0; mb_param.out = NULL; mb_param.inp = aad; mb_param.len = totlen; @@ -148,13 +156,13 @@ static int tls_write_records_multiblock_int(OSSL_RECORD_LAYER *rl, return -1; } - rl->sequence[7] += mb_param.interleave; - if (rl->sequence[7] < mb_param.interleave) { - int j = 6; - while (j >= 0 && (++rl->sequence[j--]) == 0) - ; + if (rl->sequence > UINT64_MAX - mb_param.interleave) { + RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return -1; } + rl->sequence += mb_param.interleave; + wb->offset = 0; wb->left = packlen; diff --git a/ssl/record/methods/tls_pad.c b/ssl/record/methods/tls_pad.c index a017e9221ee30..5b2c888315fda 100644 --- a/ssl/record/methods/tls_pad.c +++ b/ssl/record/methods/tls_pad.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/ssl/record/methods/tlsany_meth.c b/ssl/record/methods/tlsany_meth.c index 2b9a02146e948..f6b362eb5e611 100644 --- a/ssl/record/methods/tlsany_meth.c +++ b/ssl/record/methods/tlsany_meth.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -15,9 +15,11 @@ #define MIN_SSL2_RECORD_LEN 9 static int tls_any_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, + unsigned char *snkey, unsigned char *key, size_t keylen, unsigned char *iv, size_t ivlen, unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *snciph, const EVP_CIPHER *ciph, size_t taglen, int mactype, @@ -43,6 +45,8 @@ static int tls_any_cipher(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *recs, static int tls_validate_record_header(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec) { + const int version1_3 = rl->isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION; + if (rl->version == TLS_ANY_VERSION) { if ((rec->rec_version >> 8) != SSL3_VERSION_MAJOR) { if (rl->is_first_record) { @@ -72,7 +76,7 @@ static int tls_validate_record_header(OSSL_RECORD_LAYER *rl, TLS_RL_RECORD *rec) return 0; } } - } else if (rl->version == TLS1_3_VERSION) { + } else if (rl->version == version1_3) { /* * In this case we know we are going to negotiate TLSv1.3, but we've * had an HRR, so we haven't actually done so yet. In TLSv1.3 we diff --git a/ssl/record/rec_layer_d1.c b/ssl/record/rec_layer_d1.c index b95e2c222cb2a..ef73bc6b4450f 100644 --- a/ssl/record/rec_layer_d1.c +++ b/ssl/record/rec_layer_d1.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -87,7 +87,7 @@ static int dtls_buffer_record(SSL_CONNECTION *s, TLS_RECORD *rec) return -1; rdata = OPENSSL_malloc(sizeof(*rdata)); - item = pitem_new(rec->seq_num, rdata); + item = pitem_new_u64(rec->seq_num, rdata); if (rdata == NULL || item == NULL) { OPENSSL_free(rdata); pitem_free(item); @@ -118,7 +118,7 @@ static int dtls_buffer_record(SSL_CONNECTION *s, TLS_RECORD *rec) #ifndef OPENSSL_NO_SCTP /* Store bio_dgram_sctp_rcvinfo struct */ - if (BIO_dgram_is_sctp(s->rbio) && (ossl_statem_get_state(s) == TLS_ST_SR_FINISHED || ossl_statem_get_state(s) == TLS_ST_CR_FINISHED)) { + if (s->rbio != NULL && BIO_dgram_is_sctp(s->rbio) && (ossl_statem_get_state(s) == TLS_ST_SR_FINISHED || ossl_statem_get_state(s) == TLS_ST_CR_FINISHED)) { BIO_ctrl(s->rbio, BIO_CTRL_DGRAM_SCTP_GET_RCVINFO, sizeof(rdata->recordinfo), &rdata->recordinfo); } @@ -154,7 +154,7 @@ static void dtls_unbuffer_record(SSL_CONNECTION *s) #ifndef OPENSSL_NO_SCTP /* Restore bio_dgram_sctp_rcvinfo struct */ - if (BIO_dgram_is_sctp(s->rbio)) { + if (s->rbio != NULL && BIO_dgram_is_sctp(s->rbio)) { BIO_ctrl(s->rbio, BIO_CTRL_DGRAM_SCTP_SET_RCVINFO, sizeof(rdata->recordinfo), &rdata->recordinfo); } @@ -203,10 +203,15 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, TLS_RECORD *rr; void (*cb)(const SSL *ssl, int type2, int val) = NULL; SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + int is_dtls13; + int in_early_data; + int current_state; if (sc == NULL) return -1; + is_dtls13 = SSL_CONNECTION_IS_DTLS13(sc); + if ((type && (type != SSL3_RT_APPLICATION_DATA) && (type != SSL3_RT_HANDSHAKE)) || (peek && (type != SSL3_RT_APPLICATION_DATA))) { SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return -1; @@ -224,6 +229,7 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, start: sc->rwstate = SSL_NOTHING; + in_early_data = (sc->early_data_state == SSL_EARLY_DATA_READING); /* * We are not handshaking and have no data yet, so process data buffered @@ -251,7 +257,45 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, &rr->rechandle, &rr->version, &rr->type, &rr->data, &rr->length, - &rr->epoch, rr->seq_num)); + &rr->epoch, &rr->seq_num)); + + /* + * DTLS1.3 will move the Server and Client's Read Record + * during the handshake once it has received a record + * in the new Epoch. + * + * We cannot move to the next epoch (1 or 2) until we + * have read the client/server hello. + */ + if (ret <= 0 && is_dtls13 + && sc->rlayer.rrlmethod->unprocessed_records(sc->rlayer.rrl) > 0 + && ((SSL_in_init(s) && sc->dtls13_process_hello) || in_early_data)) { + int which = SSL3_CC_HANDSHAKE; + + if (sc->server) + which |= SSL3_CHANGE_CIPHER_SERVER_READ; + else + which |= SSL3_CHANGE_CIPHER_CLIENT_READ; + /* + * Change the Read Record Layer to next read epoch + */ + if (!s->method->ssl3_enc->change_cipher_state(sc, + which)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return -1; + } + + /* + * Read the Buffered epoch + */ + ret = HANDLE_RLAYER_READ_RETURN(sc, + sc->rlayer.rrlmethod->read_record(sc->rlayer.rrl, + &rr->rechandle, + &rr->version, &rr->type, + &rr->data, &rr->length, + &rr->epoch, &rr->seq_num)); + } + if (ret <= 0) { ret = dtls1_read_failed(sc, ret); /* @@ -278,14 +322,33 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, sc->rlayer.alert_count = 0; /* we now have a packet which can be read and processed */ - - if (sc->s3.change_cipher_spec /* set when we receive ChangeCipherSpec, - * reset by ssl3_get_finished */ - && (rr->type != SSL3_RT_HANDSHAKE)) { + current_state = SSL_get_state(s); + if ((sc->s3.change_cipher_spec /* set when we receive ChangeCipherSpec, + * reset by ssl3_get_finished */ + && (rr->type != SSL3_RT_HANDSHAKE)) + || (is_dtls13 && rr->epoch >= 3 /* For DTLS 1.3 we can receive + * Application Data before we + * receive an expecting ACK + * message */ + && (current_state == TLS_ST_CW_FINISHED + || current_state == TLS_ST_CW_KEY_UPDATE + || current_state == TLS_ST_SW_KEY_UPDATE + || current_state == TLS_ST_SW_SESSION_TICKET + || (current_state == TLS_ST_OK && SSL_in_init(s))) + && rr->type == SSL3_RT_APPLICATION_DATA)) { /* - * We now have application data between CCS and Finished. Most likely - * the packets were reordered on their way, so buffer the application - * data for later processing rather than dropping the connection. + * For DTLS 1.3 we received Application Data while we are + * waiting for an Acknowledgement record. Buffer this data so + * it can be processed once we have received the Acknowledgement. + * When DTLS 1.3 receives application data and it is already + * in TLS_ST_OK and is processing a handshake message like + * NewSessionTicket or KeyUpdate the application data is + * buffered. + * + * For non-DTLS 1.3 we now have application data between CCS and + * Finished. Most likely the packets were reordered on their way, + * so buffer the application data for later processing rather than + * dropping the connection. */ if (dtls_buffer_record(sc, rr) < 0) { /* SSLfatal() already called */ @@ -293,6 +356,10 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, } if (!ssl_release_record(sc, rr, 0)) return -1; + + if (is_dtls13 && current_state == TLS_ST_OK && SSL_in_init(s)) { + return -1; + } goto start; } @@ -307,13 +374,20 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, return 0; } + if (rr->type == SSL3_RT_HANDSHAKE && SSL_CONNECTION_IS_DTLS13(sc)) { + sc->s3.tmp.record_epoch = rr->epoch; + sc->s3.tmp.record_seq_num = rr->seq_num; + } + if (type == rr->type - || (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC - && type == SSL3_RT_HANDSHAKE && recvd_type != NULL)) { + || (type == SSL3_RT_HANDSHAKE + && ((!is_dtls13 && recvd_type != NULL && rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) + || (is_dtls13 && rr->type == SSL3_RT_ACK)))) { /* * SSL3_RT_APPLICATION_DATA or * SSL3_RT_HANDSHAKE or - * SSL3_RT_CHANGE_CIPHER_SPEC + * SSL3_RT_CHANGE_CIPHER_SPEC or + * SSL3_RT_ACK */ /* * make sure that we are not getting application data when we are @@ -359,7 +433,7 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, * app data. If there was an alert and there is no message to read * anymore, finally set shutdown. */ - if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && sc->d1->shutdown_received + if (SSL_get_rbio(s) != NULL && BIO_dgram_is_sctp(SSL_get_rbio(s)) && sc->d1->shutdown_received && BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)) <= 0) { sc->shutdown |= SSL_RECEIVED_SHUTDOWN; return 0; @@ -401,7 +475,8 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, cb(s, SSL_CB_READ_ALERT, j); } - if (alert_level == SSL3_AL_WARNING) { + if ((!is_dtls13 && alert_level == SSL3_AL_WARNING) + || (is_dtls13 && alert_descr == SSL_AD_USER_CANCELLED)) { sc->s3.warn_alert = alert_descr; if (!ssl_release_record(sc, rr, 0)) return -1; @@ -412,37 +487,33 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, SSL_R_TOO_MANY_WARN_ALERTS); return -1; } + } - if (alert_descr == SSL_AD_CLOSE_NOTIFY) { + /* + * Apart from close_notify the only other warning alert in DTLSv1.3 + * is user_cancelled - which we just ignore. + */ + if (is_dtls13 && alert_descr == SSL_AD_USER_CANCELLED) { + goto start; + } else if (alert_descr == SSL_AD_CLOSE_NOTIFY + && (is_dtls13 || alert_level == SSL3_AL_WARNING)) { #ifndef OPENSSL_NO_SCTP - /* - * With SCTP and streams the socket may deliver app data - * after a close_notify alert. We have to check this first so - * that nothing gets discarded. - */ - if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)) > 0) { - sc->d1->shutdown_received = 1; - sc->rwstate = SSL_READING; - BIO_clear_retry_flags(SSL_get_rbio(s)); - BIO_set_retry_read(SSL_get_rbio(s)); - return -1; - } -#endif - sc->shutdown |= SSL_RECEIVED_SHUTDOWN; - return 0; - } else if (alert_descr == SSL_AD_NO_RENEGOTIATION) { - /* - * This is a warning but we receive it if we requested - * renegotiation and the peer denied it. Terminate with a fatal - * alert because if the application tried to renegotiate it - * presumably had a good reason and expects it to succeed. In - * the future we might have a renegotiation where we don't care - * if the peer refused it where we carry on. - */ - SSLfatal(sc, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_RENEGOTIATION); + /* + * With SCTP and streams the socket may deliver app data + * after a close_notify alert. We have to check this first so + * that nothing gets discarded. + */ + if (SSL_get_rbio(s) != NULL && BIO_dgram_is_sctp(SSL_get_rbio(s)) && BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s)) > 0) { + sc->d1->shutdown_received = 1; + sc->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); return -1; } - } else if (alert_level == SSL3_AL_FATAL) { +#endif + sc->shutdown |= SSL_RECEIVED_SHUTDOWN; + return 0; + } else if (alert_level == SSL3_AL_FATAL || is_dtls13) { sc->rwstate = SSL_NOTHING; sc->s3.fatal_alert = alert_descr; SSLfatal_data(sc, SSL_AD_NO_ALERT, @@ -453,12 +524,24 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, return -1; SSL_CTX_remove_session(sc->session_ctx, sc->session); return 0; - } else { - SSLfatal(sc, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_ALERT_TYPE); + } else if (alert_descr == SSL_AD_NO_RENEGOTIATION) { + /* + * This is a warning but we receive it if we requested + * renegotiation and the peer denied it. Terminate with a fatal + * alert because if the application tried to renegotiate it + * presumably had a good reason and expects it to succeed. In + * the future we might have a renegotiation where we don't care + * if the peer refused it where we carry on. + */ + SSLfatal(sc, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_RENEGOTIATION); return -1; + } else if (alert_level == SSL3_AL_WARNING) { + /* We ignore any other warning alert in (D)TLSv1.2 and below */ + goto start; } - goto start; + SSLfatal(sc, SSL_AD_ILLEGAL_PARAMETER, SSL_R_UNKNOWN_ALERT_TYPE); + return -1; } if (sc->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a @@ -482,33 +565,33 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, /* * Unexpected handshake message (Client Hello, or protocol violation) */ - if (rr->type == SSL3_RT_HANDSHAKE && !ossl_statem_get_in_handshake(sc)) { - struct hm_header_st msg_hdr; + if (!ossl_statem_get_in_handshake(sc) && rr->type == SSL3_RT_HANDSHAKE && !in_early_data) { + unsigned char msg_type; /* * This may just be a stale retransmit. Also sanity check that we have * at least enough record bytes for a message header */ - if (rr->epoch != sc->rlayer.d->r_epoch + if (rr->epoch != dtls1_get_epoch(sc, SSL3_CC_READ) || rr->length < DTLS1_HM_HEADER_LENGTH) { if (!ssl_release_record(sc, rr, 0)) return -1; goto start; } - dtls1_get_message_header(rr->data, &msg_hdr); + msg_type = *rr->data; /* * If we are server, we may have a repeated FINISHED of the client * here, then retransmit our CCS and FINISHED. */ - if (msg_hdr.type == SSL3_MT_FINISHED) { + if (msg_type == SSL3_MT_FINISHED) { if (dtls1_check_timeout_num(sc) < 0) { /* SSLfatal) already called */ return -1; } - if (dtls1_retransmit_buffered_messages(sc) <= 0) { + if (dtls1_retransmit_sent_messages(sc) <= 0) { /* Fail if we encountered a fatal error */ if (ossl_statem_in_error(sc)) return -1; @@ -529,17 +612,16 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, } goto start; } + } + + if (!ossl_statem_get_in_handshake(sc) + && (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ACK)) { /* * To get here we must be trying to read app data but found handshake - * data. But if we're trying to read app data, and we're not in init - * (which is tested for at the top of this function) then init must be - * finished + * data. This can be because we are in early data and receive the rest + * of the handshake. */ - if (!ossl_assert(SSL_is_init_finished(s))) { - SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return -1; - } /* We found handshake data, so we're going back into init */ ossl_statem_set_in_init(sc, 1); @@ -548,9 +630,18 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, /* SSLfatal() called if appropriate */ if (i < 0) return i; + if (i == 0) return -1; + /* + * If we were actually trying to read early data and we found a + * handshake message, then we don't want to continue to try and read + * the application data any more. It won't be "early" now. + */ + if (in_early_data) + return -1; + if (!(sc->mode & SSL_MODE_AUTO_RETRY)) { if (!sc->rlayer.rrlmethod->unprocessed_read_pending(sc->rlayer.rrl)) { /* no read-ahead left? */ @@ -585,6 +676,34 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, */ SSLfatal(sc, SSL_AD_UNEXPECTED_MESSAGE, ERR_R_INTERNAL_ERROR); return -1; + + case SSL3_RT_ACK: + switch (sc->negotiated_version) { + case DTLS1_3_VERSION: + /* ACK should have been handled if DTLSv1.3 has been negotiated. */ + SSLfatal(sc, SSL_AD_UNEXPECTED_MESSAGE, ERR_R_INTERNAL_ERROR); + return -1; + + case DTLS_ANY_VERSION: + /* + * This must be an ACK from a DTLSv1.3 server for a partial + * ClientHello. We always send the full message again if the + * ClientHello is not responded to with a ServerHello before the + * timer runs out. Drop the record. + */ + if (!ssl_release_record(sc, rr, 0)) + return -1; + goto start; + + default: + /* + * If we receive an ACK record when we have negotiated a lower version + * than DTLSv1.3 then we respond with an unexpected record fatal alert. + */ + SSLfatal(sc, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD); + return -1; + } + case SSL3_RT_APPLICATION_DATA: /* * At this point, we were expecting handshake data, but have @@ -596,6 +715,12 @@ int dtls1_read_bytes(SSL *s, uint8_t type, uint8_t *recvd_type, if (sc->s3.in_read_app_data && (sc->s3.total_renegotiations != 0) && ossl_statem_app_data_allowed(sc)) { sc->s3.in_read_app_data = 2; return -1; + } else if (sc->version == DTLS1_3_VERSION) { + /* + * Let's let DTLS ACK and retransmits fix this problem. + */ + ssl_release_record(sc, rr, 0); + return -1; } else { SSLfatal(sc, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_RECORD); return -1; @@ -631,15 +756,17 @@ int do_dtls1_write(SSL_CONNECTION *sc, uint8_t type, const unsigned char *buf, int ret; /* If we have an alert to send, lets send it */ - if (sc->s3.alert_dispatch > 0) { + if (sc->s3.alert_dispatch != SSL_ALERT_DISPATCH_NONE) { i = s->method->ssl_dispatch_alert(s); if (i <= 0) return i; /* if it went, fall through and send more stuff */ } - if (len == 0) - return 0; + if (len == 0) { + *written = 0; + return 1; + } if (len > ssl_get_max_send_fragment(sc)) { SSLfatal(sc, SSL_AD_INTERNAL_ERROR, SSL_R_EXCEEDS_MAX_FRAGMENT_SIZE); @@ -647,12 +774,14 @@ int do_dtls1_write(SSL_CONNECTION *sc, uint8_t type, const unsigned char *buf, } tmpl.type = type; + if (sc->version == DTLS1_3_VERSION) + tmpl.version = DTLS1_2_VERSION; /* * Special case: for hello verify request, client version 1.0 and we * haven't decided which version to use yet send back using version 1.0 * header: otherwise some clients will ignore it. */ - if (s->method->version == DTLS_ANY_VERSION + else if (s->method->version == DTLS_ANY_VERSION && sc->max_proto_version != DTLS1_BAD_VER) tmpl.version = DTLS1_VERSION; else @@ -666,32 +795,75 @@ int do_dtls1_write(SSL_CONNECTION *sc, uint8_t type, const unsigned char *buf, if (ret > 0) *written = len; + /* + * Add record number to the buffered sent message + */ + if (type == SSL3_RT_HANDSHAKE && ret > 0 && SSL_CONNECTION_IS_DTLS13(sc)) { + pitem *item; + unsigned char prio[8]; + dtls_sent_msg *sent_msg; + DTLS1_RECORD_NUMBER *rec_num; + + dtls1_get_queue_priority(prio, sc->d1->w_msg.msg_seq, 0); + item = pqueue_find(&sc->d1->sent_messages, prio); + + if (item == NULL) + return ret; + + sent_msg = (dtls_sent_msg *)item->data; + rec_num = dtls1_record_number_new(tmpl.epoch, tmpl.sequence_number); + + if (rec_num == NULL) + return -1; + + ossl_list_record_number_insert_tail(&sent_msg->rec_nums, rec_num); + } + return ret; } -void dtls1_increment_epoch(SSL_CONNECTION *s, int rw) +int dtls1_increment_epoch(SSL_CONNECTION *s, int rw) { if (rw & SSL3_CC_READ) { - s->rlayer.d->r_epoch++; + if (!SSL_CONNECTION_IS_DTLS13(s) && s->rlayer.d->r_conn_epoch == UINT16_MAX) + return 0; + + s->rlayer.d->r_conn_epoch++; /* * We must not use any buffered messages received from the previous * epoch */ dtls1_clear_received_buffer(s); + + if (s->rlayer.d->r_conn_epoch == 0) + /* We've wrapped around, so clear the buffer just in case */ + return 0; } else { - s->rlayer.d->w_epoch++; + if (!SSL_CONNECTION_IS_DTLS13(s) && s->rlayer.d->w_conn_epoch == DTLS1_MAX_EPOCH) + return 0; + + /* + * RFC 9147 Section 8: sending implementations MUST NOT allow the + * epoch to exceed 2^48-1. + */ + if (SSL_CONNECTION_IS_DTLS13(s) && s->rlayer.d->w_conn_epoch == DTLS1_3_MAX_EPOCH) + return 0; + + s->rlayer.d->w_conn_epoch++; } + + return 1; } -uint16_t dtls1_get_epoch(SSL_CONNECTION *s, int rw) +uint64_t dtls1_get_epoch(SSL_CONNECTION *s, int rw) { - uint16_t epoch; + uint64_t epoch; if (rw & SSL3_CC_READ) - epoch = s->rlayer.d->r_epoch; + epoch = s->rlayer.d->r_conn_epoch; else - epoch = s->rlayer.d->w_epoch; + epoch = s->rlayer.d->w_conn_epoch; return epoch; } diff --git a/ssl/record/rec_layer_s3.c b/ssl/record/rec_layer_s3.c index d87001ad7b33f..c24f467fabfe7 100644 --- a/ssl/record/rec_layer_s3.c +++ b/ssl/record/rec_layer_s3.c @@ -82,8 +82,8 @@ int RECORD_LAYER_reset(RECORD_LAYER *rl) : TLS_ANY_VERSION, OSSL_RECORD_DIRECTION_READ, OSSL_RECORD_PROTECTION_LEVEL_NONE, NULL, 0, - NULL, 0, NULL, 0, NULL, 0, NULL, 0, - NID_undef, NULL, NULL, NULL); + NULL, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, + 0, NID_undef, NULL, NULL, NULL); ret &= ssl_set_new_record_layer(rl->s, SSL_CONNECTION_IS_DTLS(rl->s) @@ -91,8 +91,8 @@ int RECORD_LAYER_reset(RECORD_LAYER *rl) : TLS_ANY_VERSION, OSSL_RECORD_DIRECTION_WRITE, OSSL_RECORD_PROTECTION_LEVEL_NONE, NULL, 0, - NULL, 0, NULL, 0, NULL, 0, NULL, 0, - NID_undef, NULL, NULL, NULL); + NULL, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, + 0, NID_undef, NULL, NULL, NULL); /* SSLfatal already called in the event of failure */ return ret; @@ -126,14 +126,8 @@ static uint32_t ossl_get_max_early_data(SSL_CONNECTION *s) * session/psksession. Otherwise we go with the lowest out of the max early * data set in the session and the configured max_early_data. */ - if (!s->server && sess->ext.max_early_data == 0) { - if (!ossl_assert(s->psksession != NULL - && s->psksession->ext.max_early_data > 0)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; - } - sess = s->psksession; - } + if (!s->server && s->ext.early_data_session != NULL) + sess = s->ext.early_data_session; if (!s->server) max_early_data = sess->ext.max_early_data; @@ -366,7 +360,7 @@ int ssl3_write_bytes(SSL *ssl, uint8_t type, const void *buf_, size_t len, } /* If we have an alert to send, lets send it */ - if (s->s3.alert_dispatch > 0) { + if (s->s3.alert_dispatch != SSL_ALERT_DISPATCH_NONE) { i = ssl->method->ssl_dispatch_alert(ssl); if (i <= 0) { /* SSLfatal() already called if appropriate */ @@ -1152,11 +1146,91 @@ static size_t rlayer_padding_wrapper(void *cbarg, int type, size_t len) s->rlayer.record_padding_arg); } +/* + * Callbacks for URXE listener-based connections to read packets from their + * receive queue. + */ +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) +static OSSL_FUNC_rlayer_get_urxe_packet_fn rlayer_dtls_get_urxe_packet; +static int rlayer_dtls_get_urxe_packet(void *cbarg, unsigned char **data, + size_t *len, void **packet_handle) +{ + SSL_CONNECTION *s = cbarg; + DGRAM_URXE *urxe; + + if (s == NULL || s->d1 == NULL || s->d1->rx == NULL) + return 0; + + urxe = ossl_dtls_read_datagram(s->d1->rx); + + /* + * If no datagrams available and we have a parent listener, try to pump + * the demux to get more data from the network. + * + * This is safe because dtls_listener_drive_pending() releases the mutex + * before calling SSL_accept() on connections, so the packet handler + * callback can acquire the mutex when needed. + */ + if (urxe == NULL && s->d1->listener != NULL) { + ossl_dgram_demux_pump(s->d1->rx->demux); + urxe = ossl_dtls_read_datagram(s->d1->rx); + } + + /* + * Still nothing. In blocking mode this is where the caller waits: the + * connection has no BIO of its own to block in, so returning here would + * report SSL_ERROR_WANT_READ instead of blocking. Waiting inside this + * callback keeps that out of the record layer and the state machine, which + * see only a read which took a while, exactly as a blocking BIO would give + * them. + */ + if (urxe == NULL && s->d1->listener != NULL + && ossl_dtls_blocking(SSL_CONNECTION_GET_SSL(s)) + && ossl_dtls_conn_wait_for_datagram(SSL_CONNECTION_GET_SSL(s))) + urxe = ossl_dtls_read_datagram(s->d1->rx); + + if (urxe == NULL) + return 0; + + *data = ossl_dgram_urxe_data(urxe); + *len = urxe->data_len; + *packet_handle = urxe; + return 1; +} + +static OSSL_FUNC_rlayer_release_urxe_packet_fn rlayer_dtls_release_urxe_packet; +static void rlayer_dtls_release_urxe_packet(void *cbarg, void *packet_handle) +{ + SSL_CONNECTION *s = cbarg; + DGRAM_URXE *urxe = packet_handle; + + if (s != NULL && s->d1 != NULL && s->d1->rx != NULL && urxe != NULL) + ossl_dtls_rx_release_urxe(s->d1->rx, urxe); +} + +static OSSL_FUNC_rlayer_block_for_write_fn rlayer_dtls_block_for_write; +static int rlayer_dtls_block_for_write(void *cbarg) +{ + SSL_CONNECTION *s = cbarg; + + if (s == NULL || s->d1 == NULL || s->d1->listener == NULL + || !ossl_dtls_blocking(SSL_CONNECTION_GET_SSL(s))) + return 0; + + return ossl_dtls_conn_wait_for_write(SSL_CONNECTION_GET_SSL(s)); +} +#endif + static const OSSL_DISPATCH rlayer_dispatch[] = { { OSSL_FUNC_RLAYER_SKIP_EARLY_DATA, (void (*)(void))ossl_statem_skip_early_data }, { OSSL_FUNC_RLAYER_MSG_CALLBACK, (void (*)(void))rlayer_msg_callback_wrapper }, { OSSL_FUNC_RLAYER_SECURITY, (void (*)(void))rlayer_security_wrapper }, { OSSL_FUNC_RLAYER_PADDING, (void (*)(void))rlayer_padding_wrapper }, +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + { OSSL_FUNC_RLAYER_GET_URXE_PACKET, (void (*)(void))rlayer_dtls_get_urxe_packet }, + { OSSL_FUNC_RLAYER_RELEASE_URXE_PACKET, (void (*)(void))rlayer_dtls_release_urxe_packet }, + { OSSL_FUNC_RLAYER_BLOCK_FOR_WRITE, (void (*)(void))rlayer_dtls_block_for_write }, +#endif OSSL_DISPATCH_END }; @@ -1230,9 +1304,11 @@ static int ssl_post_record_layer_select(SSL_CONNECTION *s, int direction) int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, int direction, int level, unsigned char *secret, size_t secretlen, + unsigned char *snkey, unsigned char *key, size_t keylen, unsigned char *iv, size_t ivlen, unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *snciph, const EVP_CIPHER *ciph, size_t taglen, int mactype, const EVP_MD *md, const SSL_COMP *comp, const EVP_MD *kdfdigest) @@ -1251,6 +1327,9 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, int use_early_data = 0; uint32_t max_early_data; COMP_METHOD *compm = (comp == NULL) ? NULL : comp->method; + uint64_t epoch_zero; + uint64_t seq; + int use_urxe = 0; if (direction == OSSL_RECORD_DIRECTION_READ) { if (SSL_CONNECTION_IS_DTLS(s)) { @@ -1378,11 +1457,30 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, *set = OSSL_PARAM_construct_end(); + /* + * For DTLS save off the sequence number for epoch 0 when we are setting up + * a new write record layer. This is needed for handling in case of HRR + * and we create a new write record layer for epoch 0. + */ + if (direction == OSSL_RECORD_DIRECTION_WRITE + && SSL_CONNECTION_IS_DTLS(s) + && s->rlayer.wrl != NULL + && meth->get_epoch(s->rlayer.wrl, &epoch_zero) == 1 + && epoch_zero == 0) { + if (meth->get_sequence(s->rlayer.wrl, + &seq) + != 1) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + s->rlayer.wlayer_epoch_zero_sequence = seq; + } + for (;;) { int rlret; BIO *prev = NULL; BIO *next = NULL; - unsigned int epoch = 0; + uint64_t epoch = 0; OSSL_DISPATCH rlayer_dispatch_tmp[OSSL_NELEM(rlayer_dispatch)]; size_t i, j; @@ -1430,12 +1528,25 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, rlayer_dispatch_tmp[j++] = rlayer_dispatch[i]; } +#ifndef OPENSSL_NO_DTLS + if (SSL_CONNECTION_IS_DTLS(s) && s->d1 != NULL) { + + /* + * For DTLS listener-created connections, use the URXE queue for + * reading. This is determined by the existence of s->d1->rx. + */ + if (direction == OSSL_RECORD_DIRECTION_READ && s->d1->rx != NULL) + use_urxe = 1; + } +#endif + rlret = meth->new_record_layer(sctx->libctx, sctx->propq, version, s->server, direction, level, epoch, - secret, secretlen, key, keylen, iv, - ivlen, mackey, mackeylen, ciph, taglen, - mactype, md, compm, kdfdigest, prev, - thisbio, next, settings, + secret, secretlen, snkey, key, keylen, + iv, + ivlen, mackey, mackeylen, snciph, ciph, + taglen, mactype, md, compm, kdfdigest, + prev, thisbio, next, use_urxe, settings, options, rlayer_dispatch_tmp, s, s->rlayer.rlarg, &newrl); BIO_free(prev); @@ -1476,13 +1587,47 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, */ if (!SSL_CONNECTION_IS_DTLS(s) || direction == OSSL_RECORD_DIRECTION_READ - || pqueue_peek(s->d1->sent_messages) == NULL) { + || pqueue_peek(&s->d1->sent_messages) == NULL) { if (*thismethod != NULL && !(*thismethod)->free(*thisrl)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } } + /* + * For DTLS if we created a new write record layer + * for epoch zero we need to set the sequence number. + * This is needed for handling HRR case. + */ + if (direction == OSSL_RECORD_DIRECTION_WRITE + && SSL_CONNECTION_IS_DTLS(s) + && meth->get_epoch(newrl, &epoch_zero) == 1 + && epoch_zero == 0) { + + if (meth->set_sequence(newrl, + s->rlayer.wlayer_epoch_zero_sequence) + != 1) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + /* + * For DTLS listener-created connections the peer address must be applied + * to every record layer as it is created (including the encrypted layers + * built during the handshake). SSL_set1_initial_peer_addr() only updates + * the record layers that exist when it is called, so writes on a later + * layer would otherwise fall back to BIO_write() on the shared listener + * BIO instead of BIO_sendmmsg() to the peer. + */ +#ifndef OPENSSL_NO_SOCK + if (SSL_CONNECTION_IS_DTLS(s) + && s->d1 != NULL + && meth->set1_peer != NULL + && BIO_ADDR_family(&s->d1->peer_addr) != AF_UNSPEC) + meth->set1_peer(newrl, &s->d1->peer_addr); +#endif + *thisrl = newrl; *thismethod = meth; @@ -1491,11 +1636,14 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, int ssl_set_record_protocol_version(SSL_CONNECTION *s, int vers) { - if (!ossl_assert(s->rlayer.rrlmethod != NULL) - || !ossl_assert(s->rlayer.wrlmethod != NULL)) + if ((s->negotiated_version != PROTO_VERSION_UNSET && s->negotiated_version != vers) + || !ossl_assert(s->rlayer.rrlmethod != NULL) + || !ossl_assert(s->rlayer.wrlmethod != NULL) + || !s->rlayer.rrlmethod->set_protocol_version(s->rlayer.rrl, vers) + || !s->rlayer.wrlmethod->set_protocol_version(s->rlayer.wrl, vers)) return 0; - s->rlayer.rrlmethod->set_protocol_version(s->rlayer.rrl, s->version); - s->rlayer.wrlmethod->set_protocol_version(s->rlayer.wrl, s->version); + + s->negotiated_version = vers; return 1; } diff --git a/ssl/record/record.h b/ssl/record/record.h index 192052367b005..13b709c2bf9a8 100644 --- a/ssl/record/record.h +++ b/ssl/record/record.h @@ -39,23 +39,31 @@ typedef struct tls_record_st { size_t length; /* Offset into the data buffer where to start reading */ size_t off; - /* epoch number. DTLS only */ - uint16_t epoch; + /* Serialized DTLS epoch */ + uint64_t epoch; /* sequence number. DTLS only */ - unsigned char seq_num[SEQ_NUM_SIZE]; + uint64_t seq_num; #ifndef OPENSSL_NO_SCTP struct bio_dgram_sctp_rcvinfo recordinfo; #endif } TLS_RECORD; +/* + * RFC 9147 Section 8: sending implementations MUST NOT allow the epoch to + * exceed 2^48-1. This margin (rather than the 2^64-1 wire/representation + * ceiling of Section 6.1) is what actually bounds w_conn_epoch for DTLS 1.3. + */ +#define DTLS1_3_MAX_EPOCH ((uint64_t)0xFFFFFFFFFFFFULL) +#define DTLS1_MAX_EPOCH UINT16_MAX + typedef struct dtls_record_layer_st { /* - * The current data and handshake epoch. This is initially + * The current data and handshake epoch. This is initially * undefined, and starts at zero once the initial handshake is * completed */ - uint16_t r_epoch; - uint16_t w_epoch; + uint64_t r_conn_epoch; + uint64_t w_conn_epoch; /* * Buffered application records. Only for records between CCS and @@ -127,6 +135,8 @@ typedef struct record_layer_st { /* Record layer data to be processed */ TLS_RECORD tlsrecs[SSL_MAX_PIPELINES]; + /* DTLS epoch zero write sequence number */ + uint64_t wlayer_epoch_zero_sequence; } RECORD_LAYER; /***************************************************************************** @@ -162,8 +172,9 @@ __owur int dtls1_write_bytes(SSL_CONNECTION *s, uint8_t type, const void *buf, size_t len, size_t *written); int do_dtls1_write(SSL_CONNECTION *s, uint8_t type, const unsigned char *buf, size_t len, size_t *written); -void dtls1_increment_epoch(SSL_CONNECTION *s, int rw); -uint16_t dtls1_get_epoch(SSL_CONNECTION *s, int rw); +int dtls1_increment_epoch(SSL_CONNECTION *s, int rw); +uint64_t dtls1_get_epoch(SSL_CONNECTION *s, int rw); +uint64_t dtls1_get_record_sequence_number(SSL_CONNECTION *s); int ssl_release_record(SSL_CONNECTION *s, TLS_RECORD *rr, size_t length); #define HANDLE_RLAYER_READ_RETURN(s, ret) \ @@ -178,9 +189,11 @@ int ossl_tls_handle_rlayer_return(SSL_CONNECTION *s, int writing, int ret, int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, int direction, int level, unsigned char *secret, size_t secretlen, + unsigned char *snkey, unsigned char *key, size_t keylen, unsigned char *iv, size_t ivlen, unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *snciph, const EVP_CIPHER *ciph, size_t taglen, int mactype, const EVP_MD *md, const SSL_COMP *comp, const EVP_MD *kdfdigest); @@ -195,4 +208,27 @@ OSSL_CORE_MAKE_FUNC(int, rlayer_security, (void *cbarg, int op, int bits, int ni #define OSSL_FUNC_RLAYER_PADDING 4 OSSL_CORE_MAKE_FUNC(size_t, rlayer_padding, (void *cbarg, int type, size_t len)) +/* + * Callback for listener-based connections to read data from their receive + * queue. Used by DTLS listener connections (and future TLS listener). + * Returns 1 on success with data/len set, 0 if no data available. + * The caller must call the release callback when done with the data. + */ +#define OSSL_FUNC_RLAYER_GET_URXE_PACKET 5 +OSSL_CORE_MAKE_FUNC(int, rlayer_get_urxe_packet, (void *cbarg, unsigned char **data, size_t *len, void **packet_handle)) +#define OSSL_FUNC_RLAYER_RELEASE_URXE_PACKET 6 +OSSL_CORE_MAKE_FUNC(void, rlayer_release_urxe_packet, (void *cbarg, void *packet_handle)) + +/* + * Callback for listener-based connections to wait until their shared socket can + * accept a datagram, for a connection which is in blocking mode. Such a + * connection cannot block in the socket itself, because the socket is shared + * with every other connection and is always non-blocking. + * + * Returns 1 if the send should be attempted again, or 0 to report the write as + * needing a retry in the usual way. + */ +#define OSSL_FUNC_RLAYER_BLOCK_FOR_WRITE 7 +OSSL_CORE_MAKE_FUNC(int, rlayer_block_for_write, (void *cbarg)) + #endif /* !defined(OSSL_SSL_RECORD_RECORD_H) */ diff --git a/ssl/record/record_local.h b/ssl/record/record_local.h index 7fa24a14b27e1..d6ed50b644740 100644 --- a/ssl/record/record_local.h +++ b/ssl/record/record_local.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/ssl/rio/build.info b/ssl/rio/build.info index 8e8ebaba46867..b042a878810df 100644 --- a/ssl/rio/build.info +++ b/ssl/rio/build.info @@ -1,6 +1,9 @@ $LIBSSL=../../libssl SOURCE[$LIBSSL]=poll_immediate.c -IF[{- !$disabled{quic} -}] - SOURCE[$LIBSSL]=rio_notifier.c poll_builder.c +IF[{- !$disabled{quic} || !$disabled{dtls} -}] + SOURCE[$LIBSSL]=rio_notifier.c +ENDIF +IF[{- !$disabled{quic} || !$disabled{dtls} -}] + SOURCE[$LIBSSL]=poll_builder.c ENDIF diff --git a/ssl/rio/poll_builder.c b/ssl/rio/poll_builder.c index 28d93ee1947a9..509c79918fcc9 100644 --- a/ssl/rio/poll_builder.c +++ b/ssl/rio/poll_builder.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -120,8 +120,10 @@ int ossl_rio_poll_builder_add_fd(RIO_POLL_BUILDER *rpb, int fd, assert((rpb->pfd_heap != NULL && rpb->pfd_heap == pfds) || (rpb->pfd_heap == NULL && rpb->pfds == pfds)); assert(i <= rpb->pfd_num && rpb->pfd_num <= rpb->pfd_alloc); + /* Check the index first because an appended entry is uninitialised. */ + if (i == rpb->pfd_num || pfds[i].fd == -1) + pfds[i].events = 0; pfds[i].fd = fd; - pfds[i].events = 0; if (want_read) pfds[i].events |= POLLIN; @@ -135,10 +137,40 @@ int ossl_rio_poll_builder_add_fd(RIO_POLL_BUILDER *rpb, int fd, #endif } +/* Returns 1 if no file descriptors have been added to the poll builder. */ +static int rio_poll_builder_is_empty(const RIO_POLL_BUILDER *rpb) +{ +#if RIO_POLL_METHOD == RIO_POLL_METHOD_SELECT + return rpb->hwm_fd < 0; +#elif RIO_POLL_METHOD == RIO_POLL_METHOD_POLL + return rpb->pfd_num == 0; +#else + return 1; +#endif +} + int ossl_rio_poll_builder_poll(RIO_POLL_BUILDER *rpb, OSSL_TIME deadline) { int rc; + /* + * Waiting with no file descriptors is legitimate: a DTLS connection whose + * BIO cannot provide a poll descriptor has no readiness to wait for, but + * still has a retransmission deadline to wake for. Handle that here rather + * than leaving it to the OS, because poll() treats an empty descriptor set + * as a plain sleep whereas Windows' select() rejects it outright. + * + * With no descriptors and no deadline nothing could ever wake us, so that + * is a caller error rather than an indefinite sleep. + */ + if (rio_poll_builder_is_empty(rpb)) { + if (ossl_time_is_infinite(deadline)) + return 0; + + OSSL_sleep(ossl_time2ms(ossl_time_subtract(deadline, ossl_time_now()))); + return 1; + } + #if RIO_POLL_METHOD == RIO_POLL_METHOD_SELECT do { struct timeval timeout, *p_timeout = &timeout; diff --git a/ssl/rio/poll_builder.h b/ssl/rio/poll_builder.h index 1fe13eacbaba4..48605d7182234 100644 --- a/ssl/rio/poll_builder.h +++ b/ssl/rio/poll_builder.h @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -76,4 +76,17 @@ int ossl_rio_poll_builder_poll(RIO_POLL_BUILDER *rpb, OSSL_TIME deadline); * it is currently not needed. */ +#ifndef OPENSSL_NO_QUIC +/* + * Test instrumentation only. If set, poll_translate() (see poll_immediate.c) + * calls this with the index of each item immediately before translating it, + * once all earlier items (if any) have finished translation. This lets + * tests inject a readiness change into the gap between translation of + * consecutive items, in order to deterministically exercise the + * abort-blocking path. Always NULL in production use. + */ +extern void (*ossl_quic_poll_translate_test_step_cb)(size_t idx, void *arg); +extern void *ossl_quic_poll_translate_test_step_cb_arg; +#endif + #endif diff --git a/ssl/rio/poll_immediate.c b/ssl/rio/poll_immediate.c index 24b82f3a6a438..a0346aac8cb23 100644 --- a/ssl/rio/poll_immediate.c +++ b/ssl/rio/poll_immediate.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,11 +10,17 @@ #include "internal/common.h" #include "internal/quic_ssl.h" #include "internal/quic_reactor_wait_ctx.h" +#include "internal/ssl_unwrap.h" #include #include #include "../ssl_local.h" #include "poll_builder.h" +#ifdef OPENSSL_NO_QUIC +/* Stub type when QUIC is disabled so function signatures remain consistent */ +typedef int QUIC_REACTOR_WAIT_CTX; +#endif + #if defined(_AIX) /* * Some versions of AIX define macros for events and revents for use when @@ -49,6 +55,13 @@ } while (0) #ifndef OPENSSL_NO_QUIC +/* + * Test instrumentation only; see poll_builder.h. Always NULL in production + * use. + */ +void (*ossl_quic_poll_translate_test_step_cb)(size_t idx, void *arg) = NULL; +void *ossl_quic_poll_translate_test_step_cb_arg = NULL; + static int poll_translate_ssl_quic(SSL *ssl, QUIC_REACTOR_WAIT_CTX *wctx, RIO_POLL_BUILDER *rpb, @@ -158,11 +171,238 @@ static void postpoll_translation_cleanup_ssl_quic(SSL *ssl, if (ossl_quic_get_notifier_fd(ssl) != -1) ossl_quic_leave_blocking_section(ssl, wctx); } +#endif /* OPENSSL_NO_QUIC */ + +#ifndef OPENSSL_NO_DTLS +static int poll_translate_ssl_dtls_listener(SSL *ssl, + RIO_POLL_BUILDER *rpb, + uint64_t events, + int *abort_blocking) +{ + BIO *rbio; + BIO_POLL_DESCRIPTOR desc; + DTLS_LISTENER *dl = (DTLS_LISTENER *)ssl; + uint64_t revents = 0; + int nfd; + + rbio = SSL_get_rbio(ssl); + if (rbio == NULL) + return 0; + + if (!BIO_get_rpoll_descriptor(rbio, &desc) + || desc.type != BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) { + ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED, + "DTLS listener requires a socket BIO for blocking poll"); + return 0; + } + + /* + * Watch the socket for readability whatever was asked for. Every event a + * listener reports is ultimately driven by a datagram arriving, both an + * incoming connection and data pending on the listener itself, so there is + * no event for which this is the wrong thing to wait on. events is + * therefore only consulted for the readiness re-check below. + */ + if (!ossl_rio_poll_builder_add_fd(rpb, desc.value.fd, /*r=*/1, /*w=*/0)) + return 0; + + /* + * Add the notifier FD for the DTLS listener (if multi-threaded mode is + * enabled). Another thread may queue an incoming connection for us, or + * demux data to one of our connections, without the underlying network + * socket ever becoming readable from our perspective. + */ + if (dl->have_notifier) { + nfd = ossl_rio_notifier_as_fd(&dl->notifier); + if (nfd != -1) { + if (!ossl_rio_poll_builder_add_fd(rpb, nfd, /*r=*/1, /*w=*/0)) + return 0; + + /* Tell the listener we need to receive notifications. */ + ossl_dtls_listener_enter_blocking_section(ssl); + + /* + * Only after the above call returns is it guaranteed that any + * readiness events will cause the notifier to become readable. + * Therefore it is possible the listener became ready after the + * readout which decided we needed to block. Re-check now. + */ + if (!ossl_dtls_listener_poll_events(ssl, events, /*do_tick=*/0, + &revents)) { + ossl_dtls_listener_leave_blocking_section(ssl); + return 0; + } + + if (revents != 0) { + ossl_dtls_listener_leave_blocking_section(ssl); + *abort_blocking = 1; + return 1; + } + } + } + + return 1; +} + +static int poll_translate_ssl_dtls_conn(SSL *ssl, + RIO_POLL_BUILDER *rpb, + uint64_t events, + int *abort_blocking) +{ + BIO *rbio, *wbio; + BIO_POLL_DESCRIPTOR rdesc, wdesc; + int rfd = -1, wfd = -1, nfd = -1; + SSL_CONNECTION *sc; + DTLS_LISTENER *dl = NULL; + int has_pending; + + sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + + if (sc != NULL && sc->d1 != NULL && sc->d1->listener != NULL) + dl = (DTLS_LISTENER *)sc->d1->listener; + + if ((events & SSL_POLL_EVENT_R) != 0) { + rbio = SSL_get_rbio(ssl); + + if (rbio == NULL && dl != NULL) { + /* + * Listener-based DTLS connection. First, pump the listener's + * demux to ensure any pending datagrams on the socket are + * routed to their respective connection URXE queues. + */ + ossl_dtls_tick(dl); + + /* + * Now check the URXE buffer. If data has been demuxed into + * this connection's receive queue, abort blocking immediately - + * there is no need to wait on the socket FD. + */ + if (sc->d1->rx != NULL) { + ossl_crypto_mutex_lock(sc->d1->rx->mutex); + has_pending = !ossl_list_urxe_is_empty(&sc->d1->rx->urxe_pending); + ossl_crypto_mutex_unlock(sc->d1->rx->mutex); + if (has_pending) { + *abort_blocking = 1; + return 1; + } + } + + /* + * Add the notifier FD for the DTLS listener (if multi-threaded + * mode is enabled). This ensures we get woken up if another thread + * demuxes data to this connection's URXE queue without the + * underlying network socket ever becoming readable from our + * perspective. + */ + if (dl->have_notifier) { + nfd = ossl_rio_notifier_as_fd(&dl->notifier); + if (nfd != -1) { + if (!ossl_rio_poll_builder_add_fd(rpb, nfd, /*r=*/1, /*w=*/0)) + return 0; + + /* Tell listener we need to receive notifications. */ + ossl_dtls_listener_enter_blocking_section(sc->d1->listener); + + /* + * Only after the above call returns is it guaranteed that + * any readiness events will cause the notifier to become + * readable. Therefore, it is possible data was demuxed to + * our URXE queue after our initial check above but before + * we entered the blocking section. Re-check now. + */ + if (sc->d1->rx != NULL) { + ossl_crypto_mutex_lock(sc->d1->rx->mutex); + has_pending = !ossl_list_urxe_is_empty(&sc->d1->rx->urxe_pending); + ossl_crypto_mutex_unlock(sc->d1->rx->mutex); + if (has_pending) { + ossl_dtls_listener_leave_blocking_section(sc->d1->listener); + *abort_blocking = 1; + return 1; + } + } + } + } + + /* + * URXE buffer is empty. Fall back to the listener's rbio so the + * OS-level poll() wakes us up when the shared socket becomes + * readable and new datagrams may arrive. + */ + rbio = SSL_get_rbio(sc->d1->listener); + } + + if (rbio != NULL) { + if (BIO_get_rpoll_descriptor(rbio, &rdesc) + && rdesc.type == BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) + rfd = rdesc.value.fd; + } + } + + if ((events & SSL_POLL_EVENT_W) != 0) { + wbio = SSL_get_wbio(ssl); + if (wbio != NULL) { + if (BIO_get_wpoll_descriptor(wbio, &wdesc) + && wdesc.type == BIO_POLL_DESCRIPTOR_TYPE_SOCK_FD) + wfd = wdesc.value.fd; + } + } + + /* If same FD for read and write, combine them */ + if (rfd != -1 && wfd == rfd) { + if (!ossl_rio_poll_builder_add_fd(rpb, rfd, /*r=*/1, /*w=*/1)) + return 0; + } else { + if (rfd != -1) + if (!ossl_rio_poll_builder_add_fd(rpb, rfd, /*r=*/1, /*w=*/0)) + return 0; + if (wfd != -1) + if (!ossl_rio_poll_builder_add_fd(rpb, wfd, /*r=*/0, /*w=*/1)) + return 0; + } + + return 1; +} + +static void postpoll_translation_cleanup_ssl_dtls_listener(SSL *ssl) +{ + DTLS_LISTENER *dl = (DTLS_LISTENER *)ssl; + + /* Need to mirror the enter blocking section call */ + if (dl->have_notifier && ossl_rio_notifier_as_fd(&dl->notifier) != -1) + ossl_dtls_listener_leave_blocking_section(ssl); +} + +static void postpoll_translation_cleanup_ssl_dtls_conn(SSL *ssl, uint64_t events) +{ + SSL_CONNECTION *sc; + DTLS_LISTENER *dl; + + /* + * We only enter blocking section when read events are requested. + * Don't call leave if we never entered. + */ + if ((events & SSL_POLL_EVENT_R) == 0) + return; + + sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + if (sc == NULL || sc->d1 == NULL || sc->d1->listener == NULL) + return; + + /* Need to mirror the enter blocking section call */ + if (SSL_get_rbio(ssl) != NULL) + return; + + dl = (DTLS_LISTENER *)sc->d1->listener; + if (dl->have_notifier && ossl_rio_notifier_as_fd(&dl->notifier) != -1) + ossl_dtls_listener_leave_blocking_section(sc->d1->listener); +} +#endif /* OPENSSL_NO_DTLS */ +#if !defined(OPENSSL_NO_QUIC) || !defined(OPENSSL_NO_DTLS) static void postpoll_translation_cleanup(SSL_POLL_ITEM *items, size_t num_items, size_t stride, - QUIC_REACTOR_WAIT_CTX *wctx) + ossl_unused QUIC_REACTOR_WAIT_CTX *wctx) { SSL_POLL_ITEM *item; SSL *ssl; @@ -185,6 +425,17 @@ static void postpoll_translation_cleanup(SSL_POLL_ITEM *items, postpoll_translation_cleanup_ssl_quic(ssl, wctx); break; #endif + +#ifndef OPENSSL_NO_DTLS + case SSL_TYPE_DTLS_LISTENER: + postpoll_translation_cleanup_ssl_dtls_listener(ssl); + break; + case SSL_TYPE_SSL_CONNECTION: + if (SSL_is_dtls(ssl)) + postpoll_translation_cleanup_ssl_dtls_conn(ssl, item->events); + break; +#endif + default: break; } @@ -198,10 +449,11 @@ static void postpoll_translation_cleanup(SSL_POLL_ITEM *items, static int poll_translate(SSL_POLL_ITEM *items, size_t num_items, size_t stride, - QUIC_REACTOR_WAIT_CTX *wctx, + ossl_unused QUIC_REACTOR_WAIT_CTX *wctx, RIO_POLL_BUILDER *rpb, OSSL_TIME *p_earliest_wakeup_deadline, int *abort_blocking, + int bound_by_event_timeout, size_t *p_result_count) { int ok = 1; @@ -209,13 +461,21 @@ static int poll_translate(SSL_POLL_ITEM *items, size_t result_count = 0; SSL *ssl; OSSL_TIME earliest_wakeup_deadline = ossl_time_infinite(); +#if !defined(OPENSSL_NO_QUIC) || !defined(OPENSSL_NO_DTLS) struct timeval timeout; int is_infinite = 0; +#endif size_t i; for (i = 0; i < num_items; ++i) { item = &ITEM_N(items, stride, i); +#ifndef OPENSSL_NO_QUIC + if (ossl_quic_poll_translate_test_step_cb != NULL) + ossl_quic_poll_translate_test_step_cb(i, + ossl_quic_poll_translate_test_step_cb_arg); +#endif + switch (item->desc.type) { case BIO_POLL_DESCRIPTOR_TYPE_SSL: ssl = item->desc.value.ssl; @@ -233,7 +493,7 @@ static int poll_translate(SSL_POLL_ITEM *items, FAIL_ITEM(i); if (*abort_blocking) - return 1; + goto out; if (!SSL_get_event_timeout(ssl, &timeout, &is_infinite)) FAIL_ITEM(i++); /* need to clean up this item too */ @@ -247,6 +507,53 @@ static int poll_translate(SSL_POLL_ITEM *items, break; #endif +#ifndef OPENSSL_NO_DTLS + case SSL_TYPE_DTLS_LISTENER: + if (!poll_translate_ssl_dtls_listener(ssl, rpb, item->events, + abort_blocking)) + FAIL_ITEM(i); + + if (*abort_blocking) + goto out; + + break; + case SSL_TYPE_SSL_CONNECTION: + if (SSL_is_dtls(ssl)) { + if (!poll_translate_ssl_dtls_conn(ssl, rpb, item->events, + abort_blocking)) + FAIL_ITEM(i); + + if (*abort_blocking) + goto out; + + /* + * Bound the wait by the DTLS retransmission timer, + * otherwise a poll with no timeout sleeps straight through + * the point at which we should be retransmitting. + * + * Unless the caller has told us not to. A waiter which + * cannot service the timer must not be woken by it: it + * would find the timeout still expired on the next wait, + * which reads as a zero deadline, and spin. + */ + if (bound_by_event_timeout) { + if (!SSL_get_event_timeout(ssl, &timeout, &is_infinite)) + FAIL_ITEM(i++); /* need to clean up this item too */ + + if (!is_infinite) + earliest_wakeup_deadline + = ossl_time_min(earliest_wakeup_deadline, + ossl_time_add(ossl_time_now(), + ossl_time_from_timeval(timeout))); + } + + } else { + ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED, + "SSL_poll currently only supports DTLS listeners for DTLS connections"); + } + break; +#endif + default: ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED, "SSL_poll currently only supports QUIC SSL " @@ -271,7 +578,12 @@ static int poll_translate(SSL_POLL_ITEM *items, } out: - if (!ok) + /* + * On abort_blocking, the item which triggered the abort has already + * balanced its own enter/leave of the blocking section (see + * poll_translate_ssl_quic()); only items 0..i-1 still need cleanup here. + */ + if (!ok || *abort_blocking) postpoll_translation_cleanup(items, i, stride, wctx); *p_earliest_wakeup_deadline = earliest_wakeup_deadline; @@ -283,6 +595,7 @@ static int poll_block(SSL_POLL_ITEM *items, size_t num_items, size_t stride, OSSL_TIME user_deadline, + int bound_by_event_timeout, size_t *p_result_count) { int ok = 0, abort_blocking = 0; @@ -311,17 +624,27 @@ static int poll_block(SSL_POLL_ITEM *items, * TODO(QUIC POLLING): In the future we will do reverse translation here * also to facilitate a more efficient readout. */ +#ifndef OPENSSL_NO_QUIC ossl_quic_reactor_wait_ctx_init(&wctx); +#endif ossl_rio_poll_builder_init(&rpb); if (!poll_translate(items, num_items, stride, &wctx, &rpb, &earliest_wakeup_deadline, &abort_blocking, + bound_by_event_timeout, p_result_count)) goto out; - if (abort_blocking) + if (abort_blocking) { + /* + * Nothing actually failed; we just shouldn't block because an item + * may have become ready while we were setting up. The caller's + * retry loop will call poll_readout() again to pick this up. + */ + ok = 1; goto out; + } earliest_wakeup_deadline = ossl_time_min(earliest_wakeup_deadline, user_deadline); @@ -332,9 +655,50 @@ static int poll_block(SSL_POLL_ITEM *items, out: ossl_rio_poll_builder_cleanup(&rpb); +#ifndef OPENSSL_NO_QUIC ossl_quic_reactor_wait_ctx_cleanup(&wctx); +#endif return ok; } + +#ifndef OPENSSL_NO_DTLS +/* + * Wait until the given DTLS listener or listener-based connection may have + * become ready for one of the given events, or until the deadline expires. + * + * This is the wait that libssl itself performs when a DTLS object is used in + * blocking mode. It is the same wait SSL_poll() performs, and reuses it, so a + * blocking call is woken by the same means an application polling the object + * would be: readiness of the listener's socket, or the listener's notifier if + * another thread produces readiness without the socket becoming readable here. + * + * No readout is performed. A spurious wakeup is always possible - the socket + * becoming readable says nothing about which connection the datagram is for - + * so the caller must re-test its own condition and wait again if needed. + * + * bound_by_event_timeout says whether the connection's own event timeout, which + * for DTLS is the retransmission timer, should shorten the wait. Pass 1 unless + * the caller is unable to service that timer when it fires: waking for a + * timeout nothing then handles leaves it expired, and an expired timeout reads + * as a zero deadline, so every later wait returns at once. + * + * Returns 1 if the wait completed and 0 on error. + */ +int ossl_dtls_block_until_ready(SSL *ssl, uint64_t events, OSSL_TIME deadline, + int bound_by_event_timeout) +{ + SSL_POLL_ITEM item; + size_t result_count = 0; + + item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + item.desc.value.ssl = ssl; + item.events = events; + item.revents = 0; + + return poll_block(&item, 1, sizeof(item), deadline, bound_by_event_timeout, + &result_count); +} +#endif /* OPENSSL_NO_DTLS */ #endif static int poll_readout(SSL_POLL_ITEM *items, @@ -347,14 +711,14 @@ static int poll_readout(SSL_POLL_ITEM *items, size_t i, result_count = 0; SSL_POLL_ITEM *item; SSL *ssl; -#ifndef OPENSSL_NO_QUIC +#if !defined(OPENSSL_NO_QUIC) || !defined(OPENSSL_NO_DTLS) uint64_t events; #endif uint64_t revents; for (i = 0; i < num_items; ++i) { item = &ITEM_N(items, stride, i); -#ifndef OPENSSL_NO_QUIC +#if !defined(OPENSSL_NO_QUIC) || !defined(OPENSSL_NO_DTLS) events = item->events; #endif revents = 0; @@ -381,10 +745,35 @@ static int poll_readout(SSL_POLL_ITEM *items, break; #endif +#ifndef OPENSSL_NO_DTLS + case SSL_TYPE_DTLS_LISTENER: + if (!ossl_dtls_listener_poll_events(ssl, events, do_tick, &revents)) + /* above call raises ERR */ + FAIL_ITEM(i); + + if (revents != 0) + ++result_count; + break; + case SSL_TYPE_SSL_CONNECTION: + if (SSL_is_dtls(ssl)) { + if (!ossl_dtls_conn_poll_events(ssl, events, do_tick, &revents)) + /* above call raises ERR */ + FAIL_ITEM(i); + + if (revents != 0) + ++result_count; + } else { + /* TLS Connections not supported */ + ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED, + "SSL_poll currently only supports QUIC and DTLS SSL objects"); + FAIL_ITEM(i); + } + break; +#endif + default: ERR_raise_data(ERR_LIB_SSL, SSL_R_POLL_REQUEST_NOT_SUPPORTED, - "SSL_poll currently only supports QUIC SSL " - "objects"); + "SSL_poll currently only supports QUIC and DTLS SSL objects"); FAIL_ITEM(i); } break; @@ -462,8 +851,9 @@ int SSL_poll(SSL_POLL_ITEM *items, * point onwards. */ do_tick = 1; -#ifndef OPENSSL_NO_QUIC - if (!poll_block(items, num_items, stride, deadline, &result_count)) { +#if !defined(OPENSSL_NO_QUIC) || !defined(OPENSSL_NO_DTLS) + if (!poll_block(items, num_items, stride, deadline, + /*bound_by_event_timeout=*/1, &result_count)) { ok = 0; goto out; } diff --git a/ssl/rio/rio_notifier.c b/ssl/rio/rio_notifier.c index 3f5225db0e567..6a57e61c9fce6 100644 --- a/ssl/rio/rio_notifier.c +++ b/ssl/rio/rio_notifier.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/ssl/s3_enc.c b/ssl/s3_enc.c index 2f5a3945fa065..ca0dc8e6f5252 100644 --- a/ssl/s3_enc.c +++ b/ssl/s3_enc.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2005 Nokia. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -65,10 +65,29 @@ int ssl3_finish_mac(SSL_CONNECTION *s, const unsigned char *buf, size_t len) return 0; } } else { - ret = EVP_DigestUpdate(s->s3.handshake_dgst, buf, len); - if (!ret) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + /* + * rfc9147: + * In DTLS 1.3, the message transcript is computed over the + * original TLS 1.3-style Handshake messages without the + * message_seq, fragment_offset, and fragment_length values. Note + * that this is a change from DTLS 1.2 where those values were + * included in the transcript. + * + * So this means that we record the full handshake messages in + * s->s3.handshake_buffer while s->s3.handshake_dgst is not in use and then + * we calculate the digest when initiating s->s3.handshake_dgst at which + * point we know what the protocol version is. + */ + if (s->negotiated_version == DTLS1_3_VERSION) { + if (!dtls13_transcript_hash_update(s->s3.handshake_dgst, buf, len)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + } else { + if (!EVP_DigestUpdate(s->s3.handshake_dgst, buf, len)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } } } return 1; @@ -99,11 +118,14 @@ int ssl3_digest_cached_records(SSL_CONNECTION *s, int keep) SSL_R_NO_SUITABLE_DIGEST_ALGORITHM); return 0; } - if (!EVP_DigestInit_ex(s->s3.handshake_dgst, md, NULL) - || !EVP_DigestUpdate(s->s3.handshake_dgst, hdata, hdatalen)) { + if (!EVP_DigestInit_ex(s->s3.handshake_dgst, md, NULL)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } + if (!ssl3_finish_mac(s, hdata, hdatalen)) { + /* SSLfatal() already called */ + return 0; + } } if (keep == 0) { BIO_free(s->s3.handshake_buffer); diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 1e2b05235456f..af320478bf557 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -28,7 +28,7 @@ #define SSL3_NUM_CIPHERS OSSL_NELEM(ssl3_ciphers) #define SSL3_NUM_SCSVS OSSL_NELEM(ssl3_scsvs) -/* TLSv1.3 downgrade protection sentinel values */ +/* TLSv1.3 downgrade protection sentinel values (rfc8446 4.1.3.) */ const unsigned char tls11downgrade[] = { 0x44, 0x4f, 0x57, 0x4e, 0x47, 0x52, 0x44, 0x00 }; @@ -49,8 +49,8 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_AEAD, TLS1_3_VERSION, TLS1_3_VERSION, - 0, - 0, + DTLS1_3_VERSION, + DTLS1_3_VERSION, SSL_HIGH, SSL_HANDSHAKE_MAC_SHA256 | SSL_QUIC, 128, @@ -67,8 +67,8 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_AEAD, TLS1_3_VERSION, TLS1_3_VERSION, - 0, - 0, + DTLS1_3_VERSION, + DTLS1_3_VERSION, SSL_HIGH, SSL_HANDSHAKE_MAC_SHA384 | SSL_QUIC, 256, @@ -85,8 +85,8 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_AEAD, TLS1_3_VERSION, TLS1_3_VERSION, - 0, - 0, + DTLS1_3_VERSION, + DTLS1_3_VERSION, SSL_HIGH, SSL_HANDSHAKE_MAC_SHA256 | SSL_QUIC, 256, @@ -103,8 +103,8 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_AEAD, TLS1_3_VERSION, TLS1_3_VERSION, - 0, - 0, + DTLS1_3_VERSION, + DTLS1_3_VERSION, SSL_NOT_DEFAULT | SSL_HIGH, SSL_HANDSHAKE_MAC_SHA256, 128, @@ -121,6 +121,11 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_AEAD, TLS1_3_VERSION, TLS1_3_VERSION, + /* + * RFC 9147 (DTLS 1.3): "TLS_AES_128_CCM_8_SHA256 MUST NOT be used in + * DTLS without additional safeguards against forgery." We implement + * no such safeguards, so this cipher is not available under DTLS. + */ 0, 0, SSL_NOT_DEFAULT | SSL_MEDIUM, @@ -140,8 +145,8 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_SHA256, TLS1_3_VERSION, TLS1_3_VERSION, - 0, - 0, + DTLS1_3_VERSION, + DTLS1_3_VERSION, SSL_NOT_DEFAULT | SSL_STRONG_NONE, SSL_HANDSHAKE_MAC_SHA256, 0, @@ -158,8 +163,8 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_SHA384, TLS1_3_VERSION, TLS1_3_VERSION, - 0, - 0, + DTLS1_3_VERSION, + DTLS1_3_VERSION, SSL_NOT_DEFAULT | SSL_STRONG_NONE, SSL_HANDSHAKE_MAC_SHA384, 0, @@ -177,8 +182,8 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_AEAD, TLS1_3_VERSION, TLS1_3_VERSION, - 0, - 0, + DTLS1_3_VERSION, + DTLS1_3_VERSION, SSL_NOT_DEFAULT | SSL_HIGH, SSL_HANDSHAKE_MAC_SM3, 128, @@ -195,8 +200,8 @@ static SSL_CIPHER tls13_ciphers[] = { SSL_AEAD, TLS1_3_VERSION, TLS1_3_VERSION, - 0, - 0, + DTLS1_3_VERSION, + DTLS1_3_VERSION, SSL_NOT_DEFAULT | SSL_HIGH, SSL_HANDSHAKE_MAC_SM3, 128, @@ -3850,6 +3855,7 @@ void ssl3_free(SSL *s) } ssl_evp_cipher_free(sc->s3.tmp.new_sym_enc); + ssl_evp_cipher_free(sc->s3.tmp.new_sym_enc_sn); ssl_evp_md_free(sc->s3.tmp.new_hash); OPENSSL_free(sc->s3.tmp.ctype); @@ -4258,7 +4264,7 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) case SSL_CTRL_GET_NEGOTIATED_GROUP: { unsigned int id; - if (SSL_CONNECTION_IS_TLS13(sc) && sc->s3.did_kex) + if (SSL_CONNECTION_IS_VERSION13(sc) && sc->s3.did_kex) id = sc->s3.group_id; else id = (sc->session != NULL) ? sc->session->kex_group : NID_undef; @@ -4876,7 +4882,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *cl allow = srvr; } - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { #ifndef OPENSSL_NO_PSK size_t j; @@ -4909,7 +4915,8 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *cl maxversion = SSL_CONNECTION_IS_DTLS(s) ? c->max_dtls : c->max_tls; /* Skip ciphers not supported by the protocol version */ - if (ssl_version_cmp(s, s->version, minversion) < 0 + if (minversion <= 0 || maxversion <= 0 + || ssl_version_cmp(s, s->version, minversion) < 0 || ssl_version_cmp(s, s->version, maxversion) > 0) continue; @@ -4917,7 +4924,7 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL_CONNECTION *s, STACK_OF(SSL_CIPHER) *cl * Since TLS 1.3 ciphersuites can be used with any auth or * key exchange scheme skip tests. */ - if (!SSL_CONNECTION_IS_TLS13(s)) { + if (!SSL_CONNECTION_IS_VERSION13(s)) { mask_k = s->s3.tmp.mask_k; mask_a = s->s3.tmp.mask_a; #ifndef OPENSSL_NO_SRP @@ -5083,9 +5090,9 @@ int ssl3_shutdown(SSL *s) * our shutdown alert has been sent now, and if it still needs to be * written, s->s3.alert_dispatch will be > 0 */ - if (sc->s3.alert_dispatch > 0) + if (sc->s3.alert_dispatch != SSL_ALERT_DISPATCH_NONE) return -1; /* return WANT_WRITE */ - } else if (sc->s3.alert_dispatch > 0) { + } else if (sc->s3.alert_dispatch != SSL_ALERT_DISPATCH_NONE) { /* resend it if not sent */ ret = s->method->ssl_dispatch_alert(s); if (ret == -1) { @@ -5307,8 +5314,10 @@ int ssl_generate_master_secret(SSL_CONNECTION *s, unsigned char *pms, pskpmslen = 4 + pmslen + psklen; pskpms = OPENSSL_malloc(pskpmslen); - if (pskpms == NULL) + if (pskpms == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); goto err; + } t = pskpms; s2n(pmslen, t); if (alg_k & SSL_kPSK) @@ -5332,6 +5341,7 @@ int ssl_generate_master_secret(SSL_CONNECTION *s, unsigned char *pms, OPENSSL_clear_free(pskpms, pskpmslen); #else /* Should never happen */ + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; #endif } else { @@ -5461,7 +5471,7 @@ int ssl_gensecret(SSL_CONNECTION *s, unsigned char *pms, size_t pmslen) int rv = 0; /* SSLfatal() called as appropriate in the below functions */ - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { /* * If we are resuming then we already generated the early secret * when we created the ClientHello, so don't recreate it. @@ -5504,7 +5514,7 @@ int ssl_derive(SSL_CONNECTION *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gense goto err; } - if (SSL_CONNECTION_IS_TLS13(s) && EVP_PKEY_is_a(privkey, "DH")) + if (SSL_CONNECTION_IS_VERSION13(s) && EVP_PKEY_is_a(privkey, "DH")) EVP_PKEY_CTX_set_dh_pad(pctx, 1); pms = OPENSSL_malloc(pmslen); @@ -5659,7 +5669,7 @@ const char *SSL_get0_group_name(SSL *s) if (sc == NULL) return NULL; - if (SSL_CONNECTION_IS_TLS13(sc) && sc->s3.did_kex) + if (SSL_CONNECTION_IS_VERSION13(sc) && sc->s3.did_kex) id = sc->s3.group_id; else id = sc->session->kex_group; diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index 2a51ada2a1d3d..49831e812a2b0 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -434,6 +434,7 @@ static int ssl_verify_internal(SSL_CONNECTION *s, STACK_OF(X509) *sk, EVP_PKEY * SSL_CTX *sctx; #ifndef OPENSSL_NO_OCSP SSL *ssl; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; #endif /* Something must be passed in */ @@ -496,10 +497,8 @@ static int ssl_verify_internal(SSL_CONNECTION *s, STACK_OF(X509) *sk, EVP_PKEY * */ #ifndef OPENSSL_NO_OCSP ssl = SSL_CONNECTION_GET_SSL(s); - /* - * TODO(DTLS-1.3): in future DTLS should also be considered - */ - if (!SSL_is_dtls(ssl) && SSL_version(ssl) >= TLS1_3_VERSION) { + + if (ssl_version_cmp(s, SSL_version(ssl), version1_3) >= 0) { /* ignore status_request_v2 if TLS version < 1.3 */ int status = SSL_get_tlsext_status_type(ssl); @@ -982,22 +981,20 @@ int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) continue; #endif - if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) { - ERR_raise(ERR_LIB_SSL, SSL_R_PATH_TOO_LONG); - goto err; - } #ifdef OPENSSL_SYS_VMS - r = BIO_snprintf(buf, sizeof(buf), "%s%s", dir, filename); + r = snprintf(buf, sizeof(buf), "%s%s", dir, filename); #else - r = BIO_snprintf(buf, sizeof(buf), "%s/%s", dir, filename); + r = snprintf(buf, sizeof(buf), "%s/%s", dir, filename); #endif + if (r < 0 || (size_t)r >= sizeof(buf)) { + ERR_raise(ERR_LIB_SSL, SSL_R_PATH_TOO_LONG); + goto err; + } #ifndef OPENSSL_NO_POSIX_IO /* Skip subdirectories */ if (!stat(buf, &st) && S_ISDIR(st.st_mode)) continue; #endif - if (r <= 0 || r >= (int)sizeof(buf)) - goto err; if (!add_file_cert_subjects_to_stack(stack, buf, name_hash)) goto err; } @@ -1248,8 +1245,10 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, int op, int bits, int nid, void *other, void *ex) { - int level, minbits, pfs_mask; + int level, minbits, pfs_mask, minversion; const SSL_CONNECTION *sc; + const int version1_3 = SSL_is_dtls(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + const int version1_2 = SSL_is_dtls(s) ? DTLS1_2_VERSION : TLS1_2_VERSION; minbits = ssl_get_security_level_bits(s, ctx, &level); @@ -1279,24 +1278,21 @@ static int ssl_security_default_callback(const SSL *s, const SSL_CTX *ctx, /* SHA1 HMAC is 160 bits of security */ if (minbits > 160 && c->algorithm_mac & SSL_SHA1) return 0; + /* Level 3: forward secure ciphersuites only */ pfs_mask = SSL_kDHE | SSL_kECDHE | SSL_kDHEPSK | SSL_kECDHEPSK; - if (level >= 3 && c->min_tls != TLS1_3_VERSION && !(c->algorithm_mkey & pfs_mask)) + minversion = SSL_is_dtls(s) ? c->min_dtls : c->min_tls; + + if (level >= 3 && minversion != version1_3 && !(c->algorithm_mkey & pfs_mask)) return 0; break; } case SSL_SECOP_VERSION: if ((sc = SSL_CONNECTION_FROM_CONST_SSL(s)) == NULL) return 0; - if (!SSL_CONNECTION_IS_DTLS(sc)) { - /* SSLv3, TLS v1.0 and TLS v1.1 only allowed at level 0 */ - if (nid <= TLS1_1_VERSION && level > 0) - return 0; - } else { - /* DTLS v1.0 only allowed at level 0 */ - if (DTLS_VERSION_LT(nid, DTLS1_2_VERSION) && level > 0) - return 0; - } + /* SSLv3, TLS v1.0 and TLS v1.1 and DTLS v1.0 only allowed at level 0 */ + if (ssl_version_cmp(sc, nid, version1_2) < 0 && level > 0) + return 0; break; case SSL_SECOP_COMPRESSION: diff --git a/ssl/ssl_cert_comp.c b/ssl/ssl_cert_comp.c index 2c297178e5196..9ff30948423fd 100644 --- a/ssl/ssl_cert_comp.c +++ b/ssl/ssl_cert_comp.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -151,7 +151,7 @@ int OSSL_COMP_CERT_up_ref(OSSL_COMP_CERT *cc) { int i; - if (CRYPTO_UP_REF(&cc->references, &i) <= 0) + if (!CRYPTO_UP_REF(&cc->references, &i)) return 0; REF_PRINT_COUNT("OSSL_COMP_CERT", i, cc); diff --git a/ssl/ssl_cert_table.h b/ssl/ssl_cert_table.h index 940ef7a5c9436..9f5b2a31e07d8 100644 --- a/ssl/ssl_cert_table.h +++ b/ssl/ssl_cert_table.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/ssl/ssl_ciph.c b/ssl/ssl_ciph.c index 47e3ff4df3fa5..1d9f239afea9c 100644 --- a/ssl/ssl_ciph.c +++ b/ssl/ssl_ciph.c @@ -457,8 +457,47 @@ int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc, return 1; } +int ssl_cipher_get_evp_cipher_sn(SSL_CTX *ctx, const SSL_CIPHER *sslc, + const EVP_CIPHER **enc) +{ + int i = ssl_cipher_info_lookup(ssl_cipher_table_cipher, sslc->algorithm_enc); + + if (i == -1) { + *enc = NULL; + } else { + if (i == SSL_ENC_NULL_IDX) { + /* + * We assume we don't care about this coming from an ENGINE so + * just do a normal EVP_CIPHER_fetch instead of + * ssl_evp_cipher_fetch() + */ + *enc = EVP_CIPHER_fetch(ctx->libctx, "NULL", ctx->propq); + } else { + int ecbnid = NID_undef; + + *enc = NULL; + + if ((sslc->algorithm_enc & SSL_AES128_ANY) != 0) + ecbnid = NID_aes_128_ecb; + else if ((sslc->algorithm_enc & SSL_AES256_ANY) != 0) + ecbnid = NID_aes_256_ecb; + else if (ossl_assert((sslc->algorithm_enc & SSL_CHACHA20) != 0)) + ecbnid = NID_chacha20; + + if (ecbnid != NID_undef) + *enc = ssl_evp_cipher_fetch(ctx->libctx, OBJ_nid2sn(ecbnid), ctx->propq); + } + + if (*enc == NULL) + return 0; + } + return 1; +} + int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s, - const EVP_CIPHER **enc, const EVP_MD **md, + const EVP_CIPHER **snenc, + const EVP_CIPHER **enc, + const EVP_MD **md, int *mac_pkey_type, size_t *mac_secret_size, SSL_COMP **comp, int use_etm) { @@ -488,12 +527,18 @@ int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s, if ((enc == NULL) || (md == NULL)) return 0; - if (!ssl_cipher_get_evp_cipher(ctx, c, enc)) + if (!ssl_cipher_get_evp_cipher(ctx, c, enc) + || (snenc != NULL + && !ssl_cipher_get_evp_cipher_sn(ctx, c, snenc))) return 0; if (!ssl_cipher_get_evp_md_mac(ctx, c, md, mac_pkey_type, mac_secret_size)) { ssl_evp_cipher_free(*enc); + + if (snenc != NULL) + ssl_evp_cipher_free(*snenc); + return 0; } @@ -1314,15 +1359,23 @@ static int update_cipher_list(SSL_CTX *ctx, return 0; /* - * Delete any existing TLSv1.3 ciphersuites. These are always first in the + * Delete any existing (D)TLSv1.3 ciphersuites. These are always first in the * list. */ - while (sk_SSL_CIPHER_num(tmp_cipher_list) > 0 - && sk_SSL_CIPHER_value(tmp_cipher_list, 0)->min_tls - == TLS1_3_VERSION) + + while (sk_SSL_CIPHER_num(tmp_cipher_list) > 0) { + const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(tmp_cipher_list, 0); + const int version1_3 = SSL_CTX_IS_DTLS(ctx) ? DTLS1_3_VERSION + : TLS1_3_VERSION; + const int minversion = SSL_CTX_IS_DTLS(ctx) ? cipher->min_dtls + : cipher->min_tls; + + if (minversion != version1_3) + break; (void)sk_SSL_CIPHER_delete(tmp_cipher_list, 0); + } - /* Insert the new TLSv1.3 ciphersuites */ + /* Insert the new (D)TLSv1.3 ciphersuites */ for (i = sk_SSL_CIPHER_num(tls13_ciphersuites) - 1; i >= 0; i--) { const SSL_CIPHER *sslc = sk_SSL_CIPHER_value(tls13_ciphersuites, i); @@ -1841,7 +1894,7 @@ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) break; } - BIO_snprintf(buf, len, format, cipher->name, ver, kx, au, enc, mac); + snprintf(buf, len, format, cipher->name, ver, kx, au, enc, mac); return buf; } @@ -2115,13 +2168,22 @@ int ssl_get_md_idx(int md_nid) return -1; } -const EVP_MD *SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *c) +int ssl_cipher_get_handshake_digest_nid(const SSL_CIPHER *c) { int idx = c->algorithm2 & SSL_HANDSHAKE_MAC_MASK; if (idx < 0 || idx >= SSL_MD_NUM_IDX) + return NID_undef; + return ssl_cipher_table_mac[idx].nid; +} + +const EVP_MD *SSL_CIPHER_get_handshake_digest(const SSL_CIPHER *c) +{ + int nid = ssl_cipher_get_handshake_digest_nid(c); + + if (nid == NID_undef) return NULL; - return EVP_get_digestbynid(ssl_cipher_table_mac[idx].nid); + return EVP_get_digestbynid(nid); } int SSL_CIPHER_is_aead(const SSL_CIPHER *c) @@ -2129,20 +2191,29 @@ int SSL_CIPHER_is_aead(const SSL_CIPHER *c) return (c->algorithm_mac & SSL_AEAD) ? 1 : 0; } -int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead, - size_t *int_overhead, size_t *blocksize, - size_t *ext_overhead) +int ssl_cipher_get_overhead(const SSL_CIPHER *c, int version, + size_t *mac_overhead, size_t *int_overhead, + size_t *blocksize, size_t *ext_overhead) { int mac = 0, in = 0, blk = 0, out = 0; /* Some hard-coded numbers for the CCM/Poly1305 MAC overhead * because there are no handy #defines for those. */ if (c->algorithm_enc & (SSL_AESGCM | SSL_ARIAGCM)) { - out = EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; + out = EVP_GCM_TLS_TAG_LEN; + /* DTLS 1.3 uses an implicit nonce, so no explicit IV on the wire. */ + if (version != DTLS1_3_VERSION) + out += EVP_GCM_TLS_EXPLICIT_IV_LEN; } else if (c->algorithm_enc & (SSL_AES128CCM | SSL_AES256CCM)) { - out = EVP_CCM_TLS_EXPLICIT_IV_LEN + 16; + out = 16; + /* DTLS 1.3 uses an implicit nonce, so no explicit IV on the wire. */ + if (version != DTLS1_3_VERSION) + out += EVP_CCM_TLS_EXPLICIT_IV_LEN; } else if (c->algorithm_enc & (SSL_AES128CCM8 | SSL_AES256CCM8)) { - out = EVP_CCM_TLS_EXPLICIT_IV_LEN + 8; + out = 8; + /* DTLS 1.3 uses an implicit nonce, so no explicit IV on the wire. */ + if (version != DTLS1_3_VERSION) + out += EVP_CCM_TLS_EXPLICIT_IV_LEN; } else if (c->algorithm_enc & SSL_CHACHA20POLY1305) { out = 16; } else if (c->algorithm_mac & SSL_AEAD) { diff --git a/ssl/ssl_conf.c b/ssl/ssl_conf.c index a7293512b9b1e..a7ba0fd11bc46 100644 --- a/ssl/ssl_conf.c +++ b/ssl/ssl_conf.c @@ -9,6 +9,7 @@ #include "internal/e_os.h" +#include #include #include "ssl_local.h" #include @@ -288,7 +289,8 @@ static int cmd_Protocol(SSL_CONF_CTX *cctx, const char *value) SSL_FLAG_TBL_INV("TLSv1.2", SSL_OP_NO_TLSv1_2), SSL_FLAG_TBL_INV("TLSv1.3", SSL_OP_NO_TLSv1_3), SSL_FLAG_TBL_INV("DTLSv1", SSL_OP_NO_DTLSv1), - SSL_FLAG_TBL_INV("DTLSv1.2", SSL_OP_NO_DTLSv1_2) + SSL_FLAG_TBL_INV("DTLSv1.2", SSL_OP_NO_DTLSv1_2), + SSL_FLAG_TBL_INV("DTLSv1.3", SSL_OP_NO_DTLSv1_3) }; cctx->tbl = ssl_protocol_list; cctx->ntbl = OSSL_NELEM(ssl_protocol_list); @@ -321,7 +323,8 @@ static int protocol_from_string(const char *value) { "TLSv1.2", TLS1_2_VERSION }, { "TLSv1.3", TLS1_3_VERSION }, { "DTLSv1", DTLS1_VERSION }, - { "DTLSv1.2", DTLS1_2_VERSION } + { "DTLSv1.2", DTLS1_2_VERSION }, + { "DTLSv1.3", DTLS1_3_VERSION } }; size_t i; size_t n = OSSL_NELEM(versions); @@ -723,9 +726,11 @@ static int cmd_RecordPadding(SSL_CONF_CTX *cctx, const char *value) static int cmd_NumTickets(SSL_CONF_CTX *cctx, const char *value) { int rv = 0; - int num_tickets = atoi(value); + unsigned long ul; + + if (OPENSSL_strtoul(value, NULL, 10, &ul) && ul <= INT_MAX) { + int num_tickets = (int)ul; - if (num_tickets >= 0) { if (cctx->ctx) rv = SSL_CTX_set_num_tickets(cctx->ctx, num_tickets); if (cctx->ssl) diff --git a/ssl/ssl_init.c b/ssl/ssl_init.c index 634fd392374d8..5b31b0a2df693 100644 --- a/ssl/ssl_init.c +++ b/ssl/ssl_init.c @@ -19,7 +19,6 @@ static int stopped; static CRYPTO_ONCE ssl_base = CRYPTO_ONCE_STATIC_INIT; -static int ssl_base_inited = 0; DEFINE_RUN_ONCE_STATIC(ossl_init_ssl_base) { #ifndef OPENSSL_NO_COMP @@ -33,7 +32,6 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_ssl_base) #endif ssl_sort_cipher_list(); OSSL_TRACE(INIT, "ossl_init_ssl_base: SSL_add_ssl_module()\n"); - ssl_base_inited = 1; return 1; } diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index a900ad557af31..48e3fe19ee7e7 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -471,7 +471,11 @@ static int ssl_check_allowed_versions(int min_version, int max_version) /* Ignore DTLS1_BAD_VER */ min_version = DTLS1_VERSION; if (max_version == 0) + max_version = DTLS1_3_VERSION; +#ifdef OPENSSL_NO_DTLS1_3 + if (max_version == DTLS1_3_VERSION) max_version = DTLS1_2_VERSION; +#endif #ifdef OPENSSL_NO_DTLS1_2 if (max_version == DTLS1_2_VERSION) max_version = DTLS1_VERSION; @@ -489,6 +493,10 @@ static int ssl_check_allowed_versions(int min_version, int max_version) #ifdef OPENSSL_NO_DTLS1_2 || (DTLS_VERSION_GE(min_version, DTLS1_2_VERSION) && DTLS_VERSION_GE(DTLS1_2_VERSION, max_version)) +#endif +#ifdef OPENSSL_NO_DTLS1_3 + || (DTLS_VERSION_GE(min_version, DTLS1_3_VERSION) + && DTLS_VERSION_GE(DTLS1_3_VERSION, max_version)) #endif ) return 0; @@ -586,6 +594,12 @@ int ossl_ssl_connection_reset(SSL *s) sc->error = 0; sc->hit = 0; sc->shutdown = 0; + sc->ext.early_data_suppressed = 0; + sc->ext.early_exporter_ready = 0; + SSL_SESSION_free(sc->ext.early_data_session); + sc->ext.early_data_session = NULL; + sc->ext.tick_age_checked = 0; + sc->ext.tick_age_ms = 0; if (sc->renegotiate) { ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); @@ -630,10 +644,76 @@ int ossl_ssl_connection_reset(SSL *s) * back. */ if (s->method != s->defltmeth) { + /* + * For DTLS listener-created connections, we need to preserve the + * peer_addr, rx (DTLS_RX), listener, and created_at across method changes. + * These are set during connection creation and must survive SSL_clear(). + * The ssl_deinit/ssl_init sequence would otherwise free the old d1 + * structure and allocate a new one, losing these values. + */ +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + BIO_ADDR saved_peer_addr = { 0 }; + DTLS_RX *saved_rx = NULL; + SSL *saved_listener = NULL; + OSSL_TIME saved_created_at = ossl_time_zero(); + unsigned int saved_req_blocking_mode = DTLS_BLOCKING_MODE_INHERIT; + unsigned int saved_force_nonblocking = 0; + unsigned int saved_being_driven = 0; + int is_dtls_listener_conn = 0; + + if (SSL_CONNECTION_IS_DTLS(sc) && sc->d1 != NULL + && sc->d1->listener != NULL) { + is_dtls_listener_conn = 1; + saved_peer_addr = sc->d1->peer_addr; + saved_rx = sc->d1->rx; + saved_listener = sc->d1->listener; + saved_created_at = sc->d1->created_at; + saved_req_blocking_mode = sc->d1->req_blocking_mode; + saved_force_nonblocking = sc->d1->force_nonblocking; + saved_being_driven = sc->d1->being_driven; + /* + * Prevent dtls1_free from freeing rx and releasing the listener + * reference - we'll restore them after ssl_init. + */ + sc->d1->rx = NULL; + sc->d1->listener = NULL; + } +#endif + s->method->ssl_deinit(s); s->method = s->defltmeth; - if (!s->method->ssl_init(s)) + if (!s->method->ssl_init(s)) { +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + if (is_dtls_listener_conn) { + ossl_dtls_rx_free(saved_rx); + SSL_free(saved_listener); + } +#endif return 0; + } + +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + /* Restore DTLS listener connection state */ + if (is_dtls_listener_conn && sc->d1 != NULL) { + sc->d1->peer_addr = saved_peer_addr; + sc->d1->rx = saved_rx; + sc->d1->listener = saved_listener; + sc->d1->created_at = saved_created_at; + /* + * The blocking mode is how the application configured this + * connection, not handshake state, so it survives a clear. + */ + sc->d1->req_blocking_mode = saved_req_blocking_mode; + /* + * Both of these say something about the call this SSL_clear() may + * be nested inside: that the listener is driving the handshake and + * that it must not block while doing so. dtls1_clear() carries them + * over for the same reason. + */ + sc->d1->force_nonblocking = saved_force_nonblocking; + sc->d1->being_driven = saved_being_driven; + } +#endif } else { if (!s->method->ssl_clear(s)) return 0; @@ -942,6 +1022,7 @@ SSL *ossl_ssl_connection_new_int(SSL_CTX *ctx, SSL *user_ssl, #endif s->ssl_pkey_num = SSL_PKEY_NUM + ctx->sigalg_list_len; + s->dtls13_process_hello = 0; return ssl; cerr: ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); @@ -965,11 +1046,20 @@ int SSL_is_dtls(const SSL *s) { SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); + if (s == NULL) + return 0; + #ifndef OPENSSL_NO_QUIC if (s->type == SSL_TYPE_QUIC_CONNECTION || s->type == SSL_TYPE_QUIC_XSO) return 0; #endif +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + /* DTLS listener is always DTLS */ + if (IS_DTLS_LISTENER(s)) + return 1; +#endif + if (sc == NULL) return 0; @@ -1012,7 +1102,7 @@ int SSL_up_ref(SSL *s) { int i; - if (CRYPTO_UP_REF(&s->references, &i) <= 0) + if (!CRYPTO_UP_REF(&s->references, &i)) return 0; REF_PRINT_COUNT("SSL", i, s); @@ -1482,8 +1572,18 @@ void ossl_ssl_connection_free(SSL *ssl) SSL_CONNECTION *s; s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); - if (s == NULL) + if (s == NULL) { + /* + * This is not an SSL_CONNECTION (e.g., DTLS listener). + * Still need to call ssl_deinit which handles type-specific cleanup. + */ + if (ssl != NULL && ssl->method != NULL) + ssl->method->ssl_deinit(ssl); return; + } + + if (s->d1 != NULL && s->rlayer.wrl != NULL) + dtls1_clear_current_wrl_from_sent_buffer(s); /* * Ignore return values. This could result in user callbacks being called @@ -1510,6 +1610,7 @@ void ossl_ssl_connection_free(SSL *ssl) SSL_SESSION_free(s->session); } SSL_SESSION_free(s->psksession); + SSL_SESSION_free(s->ext.early_data_session); OPENSSL_free(s->psksession_id); ssl_cert_free(s->cert); @@ -1594,6 +1695,13 @@ void SSL_set0_rbio(SSL *s, BIO *rbio) } #endif +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + if (IS_DTLS_LISTENER(s)) { + ossl_dtls_listener_set0_net_rbio(s, rbio); + return; + } +#endif + if (sc == NULL) return; @@ -1613,6 +1721,13 @@ void SSL_set0_wbio(SSL *s, BIO *wbio) } #endif +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + if (IS_DTLS_LISTENER(s)) { + ossl_dtls_listener_set0_net_wbio(s, wbio); + return; + } +#endif + if (sc == NULL) return; @@ -1683,6 +1798,11 @@ BIO *SSL_get_rbio(const SSL *s) return ossl_quic_conn_get_net_rbio(s); #endif +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + if (IS_DTLS_LISTENER(s)) + return ossl_dtls_listener_get_net_rbio(s); +#endif + if (sc == NULL) return NULL; @@ -1698,6 +1818,11 @@ BIO *SSL_get_wbio(const SSL *s) return ossl_quic_conn_get_net_wbio(s); #endif +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + if (IS_DTLS_LISTENER(s)) + return ossl_dtls_listener_get_net_wbio(s); +#endif + if (sc == NULL) return NULL; @@ -2088,7 +2213,9 @@ int SSL_copy_session_id(SSL *t, const SSL *f) return 0; } - CRYPTO_UP_REF(&fsc->cert->references, &i); + if (!CRYPTO_UP_REF(&fsc->cert->references, &i)) + return 0; + ssl_cert_free(tsc->cert); tsc->cert = fsc->cert; if (!SSL_set_session_id_context(t, fsc->sid_ctx, (int)fsc->sid_ctx_length)) { @@ -2751,7 +2878,7 @@ ossl_ssize_t SSL_sendfile(SSL *s, int fd, off_t offset, size_t size, int flags) } /* If we have an alert to send, lets send it */ - if (sc->s3.alert_dispatch > 0) { + if (sc->s3.alert_dispatch != SSL_ALERT_DISPATCH_NONE) { ret = (ossl_ssize_t)s->method->ssl_dispatch_alert(s); ssl_update_error_state(sc); if (ret <= 0) { @@ -2856,6 +2983,32 @@ int SSL_write_early_data(SSL *s, const void *buf, size_t num, size_t *written) switch (sc->early_data_state) { case SSL_EARLY_DATA_NONE: + /* + * tls_construct_ctos_early_data() decided not to advertise the + * early_data extension. + * + * Succeed and report num bytes as written so the handshake can + * continue without 0-RTT; early data rejection can be detected via + * SSL_get_early_data_status(). + */ + if (!sc->server && sc->ext.early_data_suppressed && !SSL_in_before(s)) { + /* + * 0-RTT was suppressed. Complete the handshake behind the scenes + * and report success so the application's early data write loop + * finishes. Run the internal SSL_connect() in the CONNECTING state, + * as the non-suppressed path does, so ossl_statem_check_finish_init() + * does not mistake it for the application leaving the early data + * write sequence. + */ + sc->early_data_state = SSL_EARLY_DATA_CONNECTING; + ret = SSL_connect(s); + sc->early_data_state = SSL_EARLY_DATA_NONE; + if (ret <= 0) + return 0; + *written = num; + return 1; + } + if (sc->server || !SSL_in_before(s) || ((sc->session == NULL || sc->session->ext.max_early_data == 0) @@ -2870,10 +3023,25 @@ int SSL_write_early_data(SSL *s, const void *buf, size_t num, size_t *written) sc->early_data_state = SSL_EARLY_DATA_CONNECTING; ret = SSL_connect(s); if (ret <= 0) { - /* NBIO or error */ - sc->early_data_state = SSL_EARLY_DATA_CONNECT_RETRY; + /* + * NBIO or error. Normally we stamp the state back to + * SSL_EARLY_DATA_CONNECT_RETRY so the next SSL_write_early_data() + * call resumes here. However tls_construct_ctos_early_data() may + * have reset early_data_state to SSL_EARLY_DATA_NONE because it + * decided not to send the early_data extension. + * + * In that case leave the state alone so the handshake can complete + * normally without 0-RTT. + */ + if (!sc->ext.early_data_suppressed) + sc->early_data_state = SSL_EARLY_DATA_CONNECT_RETRY; return 0; } + if (sc->early_data_state == SSL_EARLY_DATA_NONE + && sc->ext.early_data_suppressed) { + *written = num; + return 1; + } /* fall through */ case SSL_EARLY_DATA_WRITE_RETRY: @@ -2984,7 +3152,7 @@ int SSL_key_update(SSL *s, int updatetype) if (sc == NULL) return 0; - if (!SSL_CONNECTION_IS_TLS13(sc)) { + if (!SSL_CONNECTION_IS_VERSION13(sc)) { ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION); return 0; } @@ -3031,7 +3199,7 @@ int SSL_get_key_update_type(const SSL *s) */ static int can_renegotiate(const SSL_CONNECTION *sc) { - if (SSL_CONNECTION_IS_TLS13(sc)) { + if (SSL_CONNECTION_IS_VERSION13(sc)) { ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION); return 0; } @@ -3098,7 +3266,7 @@ int SSL_new_session_ticket(SSL *s) /* If we are in init because we're sending tickets, okay to send more. */ if ((SSL_in_init(s) && sc->ext.extra_tickets_expected == 0) || SSL_IS_FIRST_HANDSHAKE(sc) || !sc->server - || !SSL_CONNECTION_IS_TLS13(sc)) + || !SSL_CONNECTION_IS_VERSION13(sc)) return 0; sc->ext.extra_tickets_expected++; if (!RECORD_LAYER_write_pending(&sc->rlayer) && !SSL_in_init(s)) @@ -3513,16 +3681,21 @@ STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx) * Distinguish between ciphers controlled by set_ciphersuite() and * set_cipher_list() when counting. */ -static int cipher_list_tls12_num(STACK_OF(SSL_CIPHER) *sk) +static int cipher_list_tls12_num(STACK_OF(SSL_CIPHER) *sk, int isdtls) { int i, num = 0; const SSL_CIPHER *c; + const int version1_3 = isdtls ? DTLS1_3_VERSION : TLS1_3_VERSION; if (sk == NULL) return 0; for (i = 0; i < sk_SSL_CIPHER_num(sk); ++i) { + int minversion; + c = sk_SSL_CIPHER_value(sk, i); - if (c->min_tls >= TLS1_3_VERSION) + minversion = isdtls ? c->min_dtls : c->min_tls; + + if (PROTOCOL_VERSION_CMP(isdtls, minversion, version1_3) >= 0) continue; num++; } @@ -3546,7 +3719,8 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) */ if (sk == NULL) return 0; - if (ctx->method->num_ciphers() > 0 && cipher_list_tls12_num(sk) == 0) { + if (ctx->method->num_ciphers() > 0 + && cipher_list_tls12_num(sk, SSL_CTX_IS_DTLS(ctx)) == 0) { ERR_raise(ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH); return 0; } @@ -3570,7 +3744,8 @@ int SSL_set_cipher_list(SSL *s, const char *str) /* see comment in SSL_CTX_set_cipher_list */ if (sk == NULL) return 0; - if (ctx->method->num_ciphers() > 0 && cipher_list_tls12_num(sk) == 0) { + if (ctx->method->num_ciphers() > 0 + && cipher_list_tls12_num(sk, SSL_CONNECTION_IS_DTLS(sc)) == 0) { ERR_raise(ERR_LIB_SSL, SSL_R_NO_CIPHER_MATCH); return 0; } @@ -3655,21 +3830,21 @@ const char *SSL_get_servername(const SSL *s, int type) if (server) { /** * Server side - * In TLSv1.3 on the server SNI is not associated with the session - * but in TLSv1.2 or below it is. + * In (D)TLSv1.3 on the server SNI is not associated with the session + * but in (D)TLSv1.2 or below it is. * * Before the handshake: * - return NULL * - * During/after the handshake (TLSv1.2 or below resumption occurred): + * During/after the handshake ((D)TLSv1.2 or below resumption occurred): * - If a servername was accepted by the server in the original * handshake then it will return that servername, or NULL otherwise. * - * During/after the handshake (TLSv1.2 or below resumption did not occur): + * During/after the handshake ((D)TLSv1.2 or below resumption did not occur): * - The function will return the servername requested by the client in * this handshake or NULL if none was requested. */ - if (sc->hit && !SSL_CONNECTION_IS_TLS13(sc)) + if (sc->hit && !SSL_CONNECTION_IS_VERSION13(sc)) return sc->session->ext.hostname; } else { /** @@ -3678,29 +3853,32 @@ const char *SSL_get_servername(const SSL *s, int type) * Before the handshake: * - If a servername has been set via a call to * SSL_set_tlsext_host_name() then it will return that servername - * - If one has not been set, but a TLSv1.2 resumption is being + * - If one has not been set, but a (D)TLSv1.2 resumption is being * attempted and the session from the original handshake had a * servername accepted by the server then it will return that * servername * - Otherwise it returns NULL * - * During/after the handshake (TLSv1.2 or below resumption occurred): + * During/after the handshake ((D)TLSv1.2 or below resumption occurred): * - If the session from the original handshake had a servername accepted * by the server then it will return that servername. * - Otherwise it returns the servername set via * SSL_set_tlsext_host_name() (or NULL if it was not called). * - * During/after the handshake (TLSv1.2 or below resumption did not occur): + * During/after the handshake ((D)TLSv1.2 or below resumption did not occur): * - It will return the servername set via SSL_set_tlsext_host_name() * (or NULL if it was not called). */ if (SSL_in_before(s)) { + const int version1_3 = SSL_CONNECTION_IS_DTLS(sc) ? DTLS1_3_VERSION + : TLS1_3_VERSION; + if (sc->ext.hostname == NULL && sc->session != NULL - && sc->session->ssl_version != TLS1_3_VERSION) + && sc->session->ssl_version != version1_3) return sc->session->ext.hostname; } else { - if (!SSL_CONNECTION_IS_TLS13(sc) && sc->hit + if (!SSL_CONNECTION_IS_VERSION13(sc) && sc->hit && sc->session->ext.hostname != NULL) return sc->session->ext.hostname; } @@ -4046,12 +4224,15 @@ int SSL_export_keying_material_early(SSL *s, unsigned char *out, size_t olen, const unsigned char *context, size_t contextlen) { + int version1_3; SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(s); if (sc == NULL) return -1; - if (sc->version != TLS1_3_VERSION) + version1_3 = SSL_CONNECTION_IS_DTLS(sc) ? DTLS1_3_VERSION : TLS1_3_VERSION; + + if (sc->version != version1_3) return 0; return tls13_export_keying_material_early(sc, out, olen, label, llen, @@ -4532,7 +4713,7 @@ int SSL_CTX_up_ref(SSL_CTX *ctx) { int i; - if (CRYPTO_UP_REF(&ctx->references, &i) <= 0) + if (!CRYPTO_UP_REF(&ctx->references, &i)) return 0; REF_PRINT_COUNT("SSL_CTX", i, ctx); @@ -4939,7 +5120,7 @@ void ssl_update_cache(SSL_CONNECTION *s, int mode) i = s->session_ctx->session_cache_mode; if ((i & mode) != 0 - && (!s->hit || SSL_CONNECTION_IS_TLS13(s))) { + && (!s->hit || SSL_CONNECTION_IS_VERSION13(s))) { /* * Add the session to the internal cache. In server side TLSv1.3 we * normally don't do this because by default it's a full stateless ticket @@ -4952,7 +5133,7 @@ void ssl_update_cache(SSL_CONNECTION *s, int mode) * - SSL_OP_NO_TICKET is set in which case it is a stateful ticket */ if ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) == 0 - && (!SSL_CONNECTION_IS_TLS13(s) + && (!SSL_CONNECTION_IS_VERSION13(s) || !s->server || (s->max_early_data > 0 && (s->options & SSL_OP_NO_ANTI_REPLAY) == 0) @@ -5064,6 +5245,19 @@ int ossl_ssl_get_error(const SSL *s, int i, int check_err) { if (SSL_want_read(s)) { bio = SSL_get_rbio(s); + /* + * rbio can be NULL for DTLS listener-created connections that + * read from DTLS_RX queue instead of a BIO. + */ + if (bio == NULL) { +#ifndef OPENSSL_NO_DTLS + if (sc != NULL && SSL_CONNECTION_IS_DTLS(sc) + && sc->d1 != NULL && sc->d1->listener != NULL) + return SSL_ERROR_WANT_READ; +#endif + /* Unexpected NULL BIO */ + return SSL_ERROR_SYSCALL; + } if (BIO_should_read(bio)) return SSL_ERROR_WANT_READ; else if (BIO_should_write(bio)) @@ -5094,6 +5288,19 @@ int ossl_ssl_get_error(const SSL *s, int i, int check_err) * present */ bio = sc->wbio; + /* + * wbio can be NULL for DTLS listener-created connections that + * use the listener's shared BIO via BIO_sendmmsg(). + */ + if (bio == NULL) { +#ifndef OPENSSL_NO_DTLS + if (sc != NULL && SSL_CONNECTION_IS_DTLS(sc) + && sc->d1 != NULL && sc->d1->listener != NULL) + return SSL_ERROR_WANT_WRITE; +#endif + /* Unexpected NULL BIO */ + return SSL_ERROR_SYSCALL; + } if (BIO_should_write(bio)) return SSL_ERROR_WANT_WRITE; else if (BIO_should_read(bio)) @@ -5273,6 +5480,9 @@ const char *ssl_protocol_to_string(int version) case DTLS1_2_VERSION: return "DTLSv1.2"; + case DTLS1_3_VERSION: + return "DTLSv1.3"; + default: return "unknown"; } @@ -5352,7 +5562,8 @@ SSL *SSL_dup(SSL *s) /* If we're not quiescent, just up_ref! */ if (!SSL_in_init(s) || !SSL_in_before(s)) { - CRYPTO_UP_REF(&s->references, &i); + if (!CRYPTO_UP_REF(&s->references, &i)) + return NULL; return s; } @@ -5444,6 +5655,31 @@ SSL *SSL_dup(SSL *s) || !dup_ca_names(&retsc->client_ca_names, sc->client_ca_names)) goto err; + if (sc->server_cert_type != NULL) { + OPENSSL_free(retsc->server_cert_type); + retsc->server_cert_type = OPENSSL_memdup(sc->server_cert_type, + sc->server_cert_type_len); + if (retsc->server_cert_type == NULL) + goto err; + retsc->server_cert_type_len = sc->server_cert_type_len; + } + + if (sc->client_cert_type != NULL) { + OPENSSL_free(retsc->client_cert_type); + retsc->client_cert_type = OPENSSL_memdup(sc->client_cert_type, + sc->client_cert_type_len); + if (retsc->client_cert_type == NULL) + goto err; + retsc->client_cert_type_len = sc->client_cert_type_len; + } + +#ifndef OPENSSL_NO_CT + retsc->ct_validation_callback = sc->ct_validation_callback; + retsc->ct_validation_callback_arg = sc->ct_validation_callback_arg; +#endif + + retsc->ext.status_type = sc->ext.status_type; + return ret; err: @@ -7210,8 +7446,10 @@ static int nss_keylog_int(const char *prefix, */ prefix_len = strlen(prefix); out_len = prefix_len + (2 * parameter_1_len) + (2 * parameter_2_len) + 3; - if ((out = cursor = OPENSSL_malloc(out_len)) == NULL) + if ((out = cursor = OPENSSL_malloc(out_len)) == NULL) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); return 0; + } memcpy(cursor, prefix, prefix_len); cursor += prefix_len; @@ -7260,9 +7498,32 @@ int ssl_log_secret(SSL_CONNECTION *sc, const uint8_t *secret, size_t secret_len) { + const uint8_t *client_random = sc->s3.client_random; + + /* + * If the client attempted ECH, secrets are logged against the inner + * ClientHello random. CLIENT_EARLY_LABEL and EARLY_EXPORTER_SECRET_LABEL + * are special-cased because they are logged before the server's + * acceptance of ECH is known, but are always derived from the inner + * ClientHello (see tls13_change_cipher_state()), so they use the inner + * random regardless of ech.success. On rejection the early secrets + * therefore carry the inner random while later ones carry the outer: + * each line is tagged with the random of the ClientHello its secret + * was derived from, and since a rejecting server never derives the + * early secrets, both peers still log identical material for every label + * they both log. + */ +#ifndef OPENSSL_NO_ECH + if (!sc->server && sc->ext.ech.attempted == 1 + && (sc->ext.ech.success == 1 + || strcmp(label, CLIENT_EARLY_LABEL) == 0 + || strcmp(label, EARLY_EXPORTER_SECRET_LABEL) == 0)) + client_random = sc->ext.ech.client_random; +#endif + return nss_keylog_int(label, sc, - sc->s3.client_random, + client_random, SSL3_RANDOM_SIZE, secret, secret_len); @@ -7529,7 +7790,7 @@ int SSL_verify_client_post_handshake(SSL *ssl) if (sc == NULL) return 0; - if (!SSL_CONNECTION_IS_TLS13(sc)) { + if (!SSL_CONNECTION_IS_VERSION13(sc)) { ERR_raise(ERR_LIB_SSL, SSL_R_WRONG_SSL_VERSION); return 0; } @@ -7819,37 +8080,70 @@ int SSL_net_write_desired(SSL *s) int SSL_set_blocking_mode(SSL *s, int blocking) { #ifndef OPENSSL_NO_QUIC - if (!IS_QUIC(s)) - return 0; + if (IS_QUIC(s)) + return ossl_quic_conn_set_blocking_mode(s, blocking); +#endif - return ossl_quic_conn_set_blocking_mode(s, blocking); -#else - return 0; +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + if (IS_DTLS(s)) + return ossl_dtls_set_blocking_mode(s, blocking); #endif + + return 0; } int SSL_get_blocking_mode(SSL *s) { #ifndef OPENSSL_NO_QUIC - if (!IS_QUIC(s)) - return -1; + if (IS_QUIC(s)) + return ossl_quic_conn_get_blocking_mode(s); +#endif - return ossl_quic_conn_get_blocking_mode(s); -#else - return -1; +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + if (IS_DTLS(s)) + return ossl_dtls_get_blocking_mode(s); #endif + + return -1; } int SSL_set1_initial_peer_addr(SSL *s, const BIO_ADDR *peer_addr) { #ifndef OPENSSL_NO_QUIC - if (!IS_QUIC(s)) - return 0; + if (IS_QUIC(s)) + return ossl_quic_conn_set_initial_peer_addr(s, peer_addr); +#endif - return ossl_quic_conn_set_initial_peer_addr(s, peer_addr); -#else - return 0; +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + /* Handle DTLS connections */ + if (IS_DTLS(s)) { + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL_ONLY(s); + + if (sc == NULL || sc->d1 == NULL) + return 0; + + if (peer_addr != NULL) { + if (!BIO_ADDR_copy(&sc->d1->peer_addr, peer_addr)) + return 0; + } else { + BIO_ADDR_clear(&sc->d1->peer_addr); + } + + /* + * Update the record layers' peer address if they exist. + * This is needed for listener-created connections where the record + * layer is created before the peer address is set. + */ + if (sc->rlayer.wrlmethod != NULL && sc->rlayer.wrl != NULL) + sc->rlayer.wrlmethod->set1_peer(sc->rlayer.wrl, peer_addr); + if (sc->rlayer.rrlmethod != NULL && sc->rlayer.rrl != NULL) + sc->rlayer.rrlmethod->set1_peer(sc->rlayer.rrl, peer_addr); + + return 1; + } #endif + + return 0; } int SSL_shutdown_ex(SSL *ssl, uint64_t flags, @@ -7910,13 +8204,16 @@ int SSL_is_connection(SSL *s) SSL *SSL_get0_listener(SSL *s) { #ifndef OPENSSL_NO_QUIC - if (!IS_QUIC(s)) - return NULL; + if (IS_QUIC(s)) + return ossl_quic_get0_listener(s); +#endif - return ossl_quic_get0_listener(s); -#else - return NULL; +#ifndef OPENSSL_NO_DTLS + if (IS_DTLS(s)) + return ossl_dtls_get0_listener(s); #endif + + return NULL; } SSL *SSL_get0_domain(SSL *s) @@ -8108,6 +8405,11 @@ int SSL_get_value_uint(SSL *s, uint32_t class_, uint32_t id, return ossl_quic_get_value_uint(s, class_, id, value); #endif +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + if (IS_DTLS_LISTENER(s)) + return ossl_dtls_get_value_uint(s, class_, id, value); +#endif + ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_PROTOCOL); return 0; } @@ -8120,20 +8422,32 @@ int SSL_set_value_uint(SSL *s, uint32_t class_, uint32_t id, return ossl_quic_set_value_uint(s, class_, id, value); #endif +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + if (IS_DTLS_LISTENER(s)) + return ossl_dtls_set_value_uint(s, class_, id, value); +#endif + ERR_raise(ERR_LIB_SSL, SSL_R_UNSUPPORTED_PROTOCOL); return 0; } SSL *SSL_new_listener(SSL_CTX *ctx, uint64_t flags) { -#ifndef OPENSSL_NO_QUIC - if (!IS_QUIC_CTX(ctx)) + if (ctx == NULL) { + ERR_raise(ERR_LIB_SSL, SSL_R_NULL_SSL_CTX); return NULL; + } - return ossl_quic_new_listener(ctx, flags); -#else - return NULL; +#ifndef OPENSSL_NO_QUIC + if (IS_QUIC_CTX(ctx)) + return ossl_quic_new_listener(ctx, flags); +#endif + +#ifndef OPENSSL_NO_DTLS + if (SSL_CTX_IS_DTLS(ctx)) + return ossl_dtls_new_listener(ctx, flags); #endif + return NULL; } SSL *SSL_new_listener_from(SSL *ssl, uint64_t flags) @@ -8141,7 +8455,6 @@ SSL *SSL_new_listener_from(SSL *ssl, uint64_t flags) #ifndef OPENSSL_NO_QUIC if (!IS_QUIC(ssl)) return NULL; - return ossl_quic_new_listener_from(ssl, flags); #else return NULL; @@ -8153,7 +8466,6 @@ SSL *SSL_new_from_listener(SSL *ssl, uint64_t flags) #ifndef OPENSSL_NO_QUIC if (!IS_QUIC(ssl)) return NULL; - return ossl_quic_new_from_listener(ssl, flags); #else return NULL; @@ -8163,37 +8475,52 @@ SSL *SSL_new_from_listener(SSL *ssl, uint64_t flags) SSL *SSL_accept_connection(SSL *ssl, uint64_t flags) { #ifndef OPENSSL_NO_QUIC - if (!IS_QUIC(ssl)) - return NULL; + if (IS_QUIC(ssl)) + return ossl_quic_accept_connection(ssl, flags); +#endif - return ossl_quic_accept_connection(ssl, flags); -#else - return NULL; +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + if (IS_DTLS(ssl)) + return ossl_dtls_accept_connection(ssl, flags); #endif + + return NULL; } size_t SSL_get_accept_connection_queue_len(SSL *ssl) { #ifndef OPENSSL_NO_QUIC - if (!IS_QUIC(ssl)) - return 0; + if (IS_QUIC(ssl)) + return ossl_quic_get_accept_connection_queue_len(ssl); +#endif - return ossl_quic_get_accept_connection_queue_len(ssl); -#else - return 0; +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + if (IS_DTLS(ssl)) + return ossl_dtls_get_accept_connection_queue_len(ssl); #endif + + return 0; } int SSL_get_peer_addr(SSL *ssl, BIO_ADDR *peer_addr) { #ifndef OPENSSL_NO_QUIC - if (!IS_QUIC(ssl)) - return 0; + if (IS_QUIC(ssl)) + return ossl_quic_get_peer_addr(ssl, peer_addr); +#endif - return ossl_quic_get_peer_addr(ssl, peer_addr); -#else - return 0; +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + SSL_CONNECTION *sc = SSL_CONNECTION_FROM_SSL(ssl); + + if (sc != NULL && sc->d1 != NULL + && BIO_ADDR_family(&sc->d1->peer_addr) != AF_UNSPEC) { + if (!BIO_ADDR_copy(peer_addr, &sc->d1->peer_addr)) + return 0; + return 1; + } #endif + + return 0; } int SSL_listen_ex(SSL *listener, SSL *new_conn) @@ -8205,19 +8532,22 @@ int SSL_listen_ex(SSL *listener, SSL *new_conn) #endif ERR_raise_data(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT, "SSL_listen_ex only operates on QUIC SSL objects"); - return 0; + return -1; } int SSL_listen(SSL *ssl) { #ifndef OPENSSL_NO_QUIC - if (!IS_QUIC(ssl)) - return 0; + if (IS_QUIC(ssl)) + return ossl_quic_listen(ssl); +#endif - return ossl_quic_listen(ssl); -#else - return 0; +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) + if (IS_DTLS(ssl)) + return ossl_dtls_listen(ssl); #endif + + return 0; } SSL *SSL_new_domain(SSL_CTX *ctx, uint64_t flags) diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index 978f627290004..d31574648b802 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -36,6 +36,7 @@ #include "internal/tsan_assist.h" #include "internal/bio.h" #include "internal/ktls.h" +#include "internal/list.h" #include "internal/time.h" #include "internal/ssl.h" #include "internal/cryptlib.h" @@ -43,17 +44,36 @@ #include "record/record.h" #include "internal/quic_predef.h" #include "internal/quic_tls.h" +#include "internal/thread_arch.h" +#include "internal/bio_addr.h" +#include "internal/dtls_record_rx.h" +#include "internal/dgram_conn_lookup.h" +#include "internal/rio_notifier.h" #ifndef OPENSSL_NO_ECH #include "ech/ech_local.h" #endif +/* + * Forward declarations for DTLS listener types. These are defined in the + * headers above when DTLS is enabled, but we need forward declarations + * for the pointer types used in structures when DTLS is disabled. + * DGRAM_DEMUX requires either QUIC or DTLS to be enabled. + */ +#if defined(OPENSSL_NO_QUIC) && defined(OPENSSL_NO_DTLS) +typedef struct dgram_demux_st DGRAM_DEMUX; +#endif +#ifdef OPENSSL_NO_DTLS +typedef struct dtls_rx_st DTLS_RX; +typedef struct dgram_conn_lookup_st DGRAM_CONN_LOOKUP; +#endif + #ifdef OPENSSL_BUILD_SHLIBSSL #undef OPENSSL_EXTERN #define OPENSSL_EXTERN OPENSSL_EXPORT #endif #define TLS_MAX_VERSION_INTERNAL TLS1_3_VERSION -#define DTLS_MAX_VERSION_INTERNAL DTLS1_2_VERSION +#define DTLS_MAX_VERSION_INTERNAL DTLS1_3_VERSION /* * DTLS version numbers are strange because they're inverted. Except for @@ -67,6 +87,47 @@ /* TLS/DTLS version for the given SSL object: XTLS(ssl, 1, 2) == TLS 1.2 or DTLS 1.2 */ #define XTLS(ssl, m, n) (SSL_is_dtls(ssl) ? (((0xFF - m) << 8) | (0xFF - n)) : (((0x02 + m) << 8) | (0x01 + n))) +/* + * SSL/TLS version comparison + * + * Returns + * 0 if versiona is equal to versionb or if either are 0 or less + * 1 if versiona is greater than versionb + * -1 if versiona is less than versionb + */ +#define TLS_VERSION_CMP(versiona, versionb) \ + ((!ossl_assert((versiona) > 0) || !ossl_assert((versionb) > 0) \ + || (versiona) == (versionb)) \ + ? 0 \ + : ((versiona) < (versionb) ? -1 : 1)) +/* + * DTLS version comparison + * + * Returns + * 0 if versiona is equal to versionb or if either are 0 or less + * 1 if versiona is greater than versionb + * -1 if versiona is less than versionb + */ +#define DTLS_VERSION_CMP(versiona, versionb) \ + ((!ossl_assert((versiona) > 0) || !ossl_assert((versionb) > 0) \ + || (versiona) == (versionb)) \ + ? 0 \ + : (DTLS_VERSION_LT((versiona), \ + (versionb)) \ + ? -1 \ + : 1)) +/* + * SSL/TLS/DTLS version comparison + * + * Returns + * 0 if versiona is equal to versionb or if either are 0 or less + * 1 if versiona is greater than versionb + * -1 if versiona is less than versionb + */ +#define PROTOCOL_VERSION_CMP(isdtls, versiona, versionb) \ + ((isdtls) ? DTLS_VERSION_CMP(versiona, versionb) \ + : TLS_VERSION_CMP(versiona, versionb)) + #define SSL_AD_NO_ALERT -1 /* @@ -164,6 +225,10 @@ #define SSL_AESGCM (SSL_AES128GCM | SSL_AES256GCM) #define SSL_AESCCM (SSL_AES128CCM | SSL_AES256CCM | SSL_AES128CCM8 | SSL_AES256CCM8) #define SSL_AES (SSL_AES128 | SSL_AES256 | SSL_AESGCM | SSL_AESCCM) +#define SSL_AES128_ANY (SSL_AES128 | SSL_AES128CCM | SSL_AES128CCM8 \ + | SSL_AES128GCM) +#define SSL_AES256_ANY (SSL_AES256 | SSL_AES256CCM | SSL_AES256CCM8 \ + | SSL_AES256GCM) #define SSL_CAMELLIA (SSL_CAMELLIA128 | SSL_CAMELLIA256) #define SSL_CHACHA20 (SSL_CHACHA20POLY1305) #define SSL_ARIAGCM (SSL_ARIA128GCM | SSL_ARIA256GCM) @@ -268,17 +333,31 @@ #define SSL_CONNECTION_IS_DTLS(s) \ (SSL_CONNECTION_GET_SSL(s)->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) +/* Check if an SSL structure is using DTLS */ +#define SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s) \ + ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0 \ + && !SSL_CONNECTION_IS_DTLS(s)) + +/* Check if we are using DTLSv1.3 */ +#define SSL_CONNECTION_IS_DTLS13(s) (SSL_CONNECTION_IS_DTLS(s) \ + && DTLS_VERSION_GE(SSL_CONNECTION_GET_SSL(s)->method->version, DTLS1_3_VERSION) \ + && SSL_CONNECTION_GET_SSL(s)->method->version != DTLS_ANY_VERSION) + /* Check if an SSL_CTX structure is using DTLS */ #define SSL_CTX_IS_DTLS(ctx) \ - (ctx->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) + ((ctx->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_DTLS) != 0) /* Check if we are using TLSv1.3 */ #define SSL_CONNECTION_IS_TLS13(s) (!SSL_CONNECTION_IS_DTLS(s) \ && SSL_CONNECTION_GET_SSL(s)->method->version >= TLS1_3_VERSION \ && SSL_CONNECTION_GET_SSL(s)->method->version != TLS_ANY_VERSION) +/* Check if we are using (D)TLSv1.3 */ +#define SSL_CONNECTION_IS_VERSION13(s) \ + (SSL_CONNECTION_IS_DTLS13(s) || SSL_CONNECTION_IS_TLS13(s)) + #define SSL_CONNECTION_TREAT_AS_TLS13(s) \ - (SSL_CONNECTION_IS_TLS13(s) \ + (SSL_CONNECTION_IS_VERSION13(s) \ || (s)->early_data_state == SSL_EARLY_DATA_CONNECTING \ || (s)->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY \ || (s)->early_data_state == SSL_EARLY_DATA_WRITING \ @@ -294,12 +373,6 @@ */ #define SSL_USE_SIGALGS(s) \ (SSL_CONNECTION_GET_SSL(s)->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SIGALGS) -/* - * Allow TLS 1.2 ciphersuites: applies to DTLS 1.2 as well as TLS 1.2: may - * apply to others in future. - */ -#define SSL_USE_TLS1_2_CIPHERS(s) \ - (SSL_CONNECTION_GET_SSL(s)->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_TLS1_2_CIPHERS) #define IS_MAX_FRAGMENT_LENGTH_EXT_VALID(value) \ (((value) >= TLSEXT_max_fragment_length_512) && ((value) <= TLSEXT_max_fragment_length_4096)) @@ -315,7 +388,7 @@ #define SSL_IS_QUIC_INT_HANDSHAKE(s) (((s)->s3.flags & TLS1_FLAGS_QUIC_INTERNAL) != 0) /* no end of early data */ -#define SSL_NO_EOED(s) SSL_IS_QUIC_HANDSHAKE(s) +#define SSL_NO_EOED(s) (SSL_IS_QUIC_HANDSHAKE(s) || SSL_CONNECTION_IS_DTLS13(s)) /* alert_dispatch values */ @@ -518,6 +591,21 @@ struct ssl_session_st { * to disable session caching and tickets. */ int not_resumable; + /* + * Set when this session's master key was resolved from an external PSK + * identity (psk_find_session_cb(), or the legacy psk_server_callback()) + * rather than from a resumption ticket or session-cache lookup. + * ssl_get_prev_session() uses this to exempt such sessions from sid_ctx + * checks that only make sense for a real cache lookup. + * + * Deliberately not part of the SSL_SESSION ASN.1 encoding: it must not + * survive a real ticket round-trip (a session reconstructed by + * d2i_SSL_SESSION() from a genuine, previously-issued ticket is by + * definition not an external-PSK match, and should get the ordinary + * sid_ctx treatment). ssl_session_dup() resets it to 0 on every copy, + * mirroring not_resumable just above, for the same reason. + */ + int psk_external; /* Peer raw public key, if available */ EVP_PKEY *peer_rpk; /* This is the cert and type for the other end. */ @@ -702,7 +790,6 @@ typedef enum tlsext_index_en { TLSEXT_IDX_outer_extensions, TLSEXT_IDX_grease1, TLSEXT_IDX_grease2, - TLSEXT_IDX_padding, TLSEXT_IDX_psk, /* Dummy index - must always be the last entry */ TLSEXT_IDX_num_builtins @@ -800,16 +887,6 @@ typedef struct { uint32_t amask; /* authmask corresponding to key type */ } SSL_CERT_LOOKUP; -/* flags values */ -#define TLS_GROUP_TYPE 0x0000000FU /* Mask for group type */ -#define TLS_GROUP_CURVE_PRIME 0x00000001U -#define TLS_GROUP_CURVE_CHAR2 0x00000002U -#define TLS_GROUP_CURVE_CUSTOM 0x00000004U -#define TLS_GROUP_FFDHE 0x00000008U -#define TLS_GROUP_ONLY_FOR_TLS1_3 0x00000010U - -#define TLS_GROUP_FFDHE_FOR_TLS1_3 (TLS_GROUP_FFDHE | TLS_GROUP_ONLY_FOR_TLS1_3) - #if !defined(OPENSSL_NO_TLS1) \ || !defined(OPENSSL_NO_TLS1_1) \ || !defined(OPENSSL_NO_TLS1_2) \ @@ -1248,8 +1325,11 @@ typedef struct cert_pkey_st CERT_PKEY; #define SSL_TYPE_QUIC_XSO 0x81 #define SSL_TYPE_QUIC_LISTENER 0x82 #define SSL_TYPE_QUIC_DOMAIN 0x83 +#define SSL_TYPE_DTLS_LISTENER 0x01 #define SSL_TYPE_IS_QUIC(x) (((x) & 0x80) != 0) +#define IS_DTLS_LISTENER(ssl) \ + ((ssl) != NULL && (ssl)->type == SSL_TYPE_DTLS_LISTENER) struct ssl_st { int type; @@ -1273,9 +1353,17 @@ struct ssl_connection_st { SSL *user_ssl; /* - * protocol version (one of TLS1_VERSION, DTLS1_VERSION) + * protocol version (one of TLS1_VERSION, TLS1_1_VERSION, TLS1_2_VERSION, + * TLS1_3_VERSION, DTLS1_VERSION, DTLS1_2_VERSION, DTLS1_3_VERSION) */ int version; + + /* + * The negotiated version for the connection. Initially PROTO_VERSION_UNSET. + * Set by ssl_set_negotiated_protocol_version(). + */ + int negotiated_version; + /* * There are 2 BIO's even though they are normally both the same. This * is so data can be read and written to different handlers @@ -1375,6 +1463,8 @@ struct ssl_connection_st { size_t peer_finish_md_len; size_t message_size; int message_type; + uint64_t record_epoch; + uint64_t record_seq_num; /* used to hold the new cipher we are going to use */ const SSL_CIPHER *new_cipher; EVP_PKEY *pkey; /* holds short lived key exchange key */ @@ -1392,6 +1482,7 @@ struct ssl_connection_st { size_t key_block_length; unsigned char *key_block; const EVP_CIPHER *new_sym_enc; + const EVP_CIPHER *new_sym_enc_sn; const EVP_MD *new_hash; int new_mac_pkey_type; size_t new_mac_secret_size; @@ -1740,6 +1831,23 @@ struct ssl_connection_st { */ int tick_identity; + /* + * Cached result of the resumption ticket age/lifetime check for the + * ClientHello under construction. Time-dependent, double-checked + * within the same flight (see tls13_check_tick_lifetime_hint()). + */ + uint32_t tick_age_ms; + + /* + * The first-offered PSK, the one that keys any 0-RTT, recorded while + * the ClientHello is built -- the resumption session when we offer it, + * else the external psksession; NULL when no 0-RTT is offered. Held + * (up-ref'd) so it stays valid across the post-ServerHello swap, and + * read by the binder, the early-key derivation, the early exporter and + * the byte-budget lookup. Freed at handshake reset and connection free. + */ + SSL_SESSION *early_data_session; + /* This is the list of algorithms the peer supports that we also support */ int compress_certificate_from_peer[TLSEXT_comp_cert_limit]; @@ -1767,9 +1875,50 @@ struct ssl_connection_st { /* Set to one if we have negotiated ETM */ bool use_etm; - /* Is the session suitable for early data? */ + /* Is the session perhaps suitable for early data? */ bool early_data_ok; + /* Was the session found unsuitable for early data? */ + bool early_data_suppressed; + + /* + * Cached result of the resumption ticket age/lifetime check for the + * ClientHello under construction. Time-dependent, double-checked + * within the same flight (see tls13_check_tick_lifetime_hint()). + */ + bool tick_age_checked; + bool tick_age_ok; + + /* + * Client-only. Whether the loaded resumption ticket (s->session) + * qualifies as an offered PSK for the ClientHello under construction. + * Frozen once by tls_construct_ctos_early_data() (the first consumer, + * which also decides 0-RTT from it) so tls_construct_ctos_psk() offers + * exactly the same identity 0 -- never re-evaluating the SECOP-dependent + * tls13_digest_offered() a second time, which could otherwise drop the + * ticket after early_data was already committed and leave the early + * secret underived. + */ + bool psk_resumption_offered; + + /* + * Client-only. Set in tls_psk_do_binder() when the first-offered PSK's + * binder derives s->early_secret for the current ClientHello flight; + * reset at the top of tls_construct_ctos_early_data(). The early-write + * key install (tls13_change_cipher_state()) refuses to proceed unless it + * is set, so 0-RTT can never be keyed off an underived (all-zero) + * s->early_secret even if the offer and early_data decisions somehow + * diverge. + */ + bool early_secret_derived; + + /* + * Records that an early exporter secret actually exists. It may not + * yet be computed if the CH1 write blocks early enough. Remains + * unchanged after CH2. + */ + bool early_exporter_ready; + /* Have we received a cookie from the client? */ bool cookieok; @@ -1901,6 +2050,9 @@ struct ssl_connection_st { size_t client_cert_type_len; unsigned char *server_cert_type; size_t server_cert_type_len; + + /* DTLS 1.3 needs to know when we have processed the Client/Server Hello */ + int dtls13_process_hello; }; /* @@ -1937,6 +2089,12 @@ typedef struct sigalg_lookup_st { int maxdtls; } SIGALG_LOOKUP; +typedef enum downgrade_en { + DOWNGRADE_NONE, + DOWNGRADE_TO_1_2, + DOWNGRADE_TO_1_1 +} DOWNGRADE; + /* DTLS structures */ #ifndef OPENSSL_NO_SCTP @@ -1957,8 +2115,6 @@ struct hm_header_st { unsigned short seq; size_t frag_off; size_t frag_len; - unsigned int is_ccs; - struct dtls1_retransmit_state saved_retransmit_state; }; typedef struct hm_fragment_st { @@ -1970,6 +2126,11 @@ typedef struct hm_fragment_st { typedef struct pqueue_st pqueue; typedef struct pitem_st pitem; +struct pqueue_st { + pitem *items; + int count; +}; + struct pitem_st { unsigned char priority[8]; /* 64-bit value in big-endian encoding */ void *data; @@ -1979,6 +2140,7 @@ struct pitem_st { typedef struct pitem_st *piterator; pitem *pitem_new(unsigned char *prio64be, void *data); +pitem *pitem_new_u64(uint64_t prio, void *data); void pitem_free(pitem *item); pqueue *pqueue_new(void); void pqueue_free(pqueue *pq); @@ -1986,10 +2148,62 @@ pitem *pqueue_insert(pqueue *pq, pitem *item); pitem *pqueue_peek(pqueue *pq); pitem *pqueue_pop(pqueue *pq); pitem *pqueue_find(pqueue *pq, unsigned char *prio64be); +pitem *pqueue_find_u64(pqueue *pq, uint64_t prio); pitem *pqueue_iterator(pqueue *pq); pitem *pqueue_next(piterator *iter); size_t pqueue_size(pqueue *pq); +typedef struct dtls_msg_info_st { + unsigned char record_type; + unsigned char msg_type; + size_t msg_body_len; + unsigned short msg_seq; +} dtls_msg_info; + +/* rfc9147, section 4 */ +typedef struct dtls1_record_number_st DTLS1_RECORD_NUMBER; + +struct dtls1_record_number_st { + uint64_t epoch; + uint64_t seqnum; + OSSL_LIST_MEMBER(record_number, DTLS1_RECORD_NUMBER); +}; + +DEFINE_LIST_OF(record_number, DTLS1_RECORD_NUMBER); + +DTLS1_RECORD_NUMBER *dtls1_record_number_new(uint64_t epoch, uint64_t seqnum); + +void ossl_list_record_number_elem_free(OSSL_LIST(record_number) * p_list); + +typedef struct dtls_sent_msg_st { + dtls_msg_info msg_info; + OSSL_LIST(record_number) + rec_nums; + unsigned char *msg_buf; + struct dtls1_retransmit_state saved_retransmit_state; +} dtls_sent_msg; + +int dtls_any_sent_messages_are_missing_acknowledge(SSL_CONNECTION *s); + +static ossl_inline int dtls_msg_needs_ack(int sentbyserver, unsigned char msgtype) +{ + switch (msgtype) { + case SSL3_MT_NEWSESSION_TICKET: + case SSL3_MT_KEY_UPDATE: + return 1; + + case SSL3_MT_CERTIFICATE: + case SSL3_MT_COMPRESSED_CERTIFICATE: + case SSL3_MT_CERTIFICATE_VERIFY: + case SSL3_MT_FINISHED: + if (!sentbyserver) + return 1; + /* fall-through */ + default: + return 0; + } +} + typedef struct dtls1_state_st { unsigned char cookie[DTLS1_COOKIE_LENGTH]; size_t cookie_len; @@ -1998,14 +2212,19 @@ typedef struct dtls1_state_st { unsigned short handshake_write_seq; unsigned short next_handshake_write_seq; unsigned short handshake_read_seq; - /* Buffered handshake messages */ - pqueue *buffered_messages; + /* Buffered received handshake messages */ + pqueue rcvd_messages; /* Buffered (sent) handshake records */ - pqueue *sent_messages; + pqueue sent_messages; + /* Flag to indicate current HelloVerifyRequest status */ + enum { SSL_HVR_NONE = 0, + SSL_HVR_RECEIVED, + SSL_HVR_SENT } hello_verify_request; + DOWNGRADE downgrade_after_hvr; /* Only used by a stateful server */ size_t link_mtu; /* max on-the-wire DTLS packet size */ size_t mtu; /* max DTLS packet size */ - struct hm_header_st w_msg_hdr; - struct hm_header_st r_msg_hdr; + dtls_msg_info w_msg; + unsigned short r_msg_seq; /* Number of alerts received so far */ unsigned int timeout_num_alerts; /* @@ -2021,10 +2240,223 @@ typedef struct dtls1_state_st { int shutdown_received; #endif + /* Sequence numbers that are to be acknowledged */ + OSSL_LIST(record_number) + ack_rec_num; + DTLS_timer_cb timer_cb; +#ifndef OPENSSL_NO_SOCK + /* + * Peer address for listener-created connections. When set, the record + * layer will use BIO_sendmmsg() with this address for writes instead + * of BIO_write(). This allows multiple connections to share the + * listener's network BIO. + */ + BIO_ADDR peer_addr; +#endif + +#ifndef OPENSSL_NO_DTLS + /* + * DTLS_RX structure is used by the DTLS Listener and + * contains the DGRAM_DEMUX and DGRAM_URXE_LIST of + * pending packets. + */ + DTLS_RX *rx; + + /* + * Reference to the parent listener for connections created via + * SSL_accept_connection(). This allows the connection to trigger + * the listener's demux pump when reading data. + */ + SSL *listener; + + /* + * Timestamp when this connection was created (for listener-created + * connections). Used to detect and clean up stale pending connections + * that haven't completed their handshake within the timeout period. + */ + OSSL_TIME created_at; + + /* + * Set when this connection is being driven by dtls_listener_drive_pending(). + * Used to prevent multiple threads from driving the same connection + * concurrently and to allow the demux pump to be called without holding + * the listener mutex. + */ + unsigned int being_driven : 1; + + /* + * Blocking mode requested for this connection, as a DTLS_BLOCKING_MODE. + * Defaults to inheriting from the listener it came from. + */ + unsigned int req_blocking_mode : 2; + + /* + * Set while the listener itself is driving this connection's handshake, to + * stop it blocking. The listener drives pending connections from inside its + * own tick, so a connection which blocked there would stop the listener + * making any further progress, including the progress being waited for. + */ + unsigned int force_nonblocking : 1; +#endif + } DTLS1_STATE; +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) +/* + * Blocking mode of a DTLS listener or of a connection created from one. + * + * A connection set to INHERIT follows its listener, and a listener set to + * INHERIT means blocking, so blocking is the default throughout unless an + * application asks otherwise. This mirrors QUIC_BLOCKING_MODE. + */ +enum { + DTLS_BLOCKING_MODE_INHERIT, + DTLS_BLOCKING_MODE_NONBLOCKING, + DTLS_BLOCKING_MODE_BLOCKING +}; + +/* + * Define stack of SSL for DTLS listener incoming connections. + */ +DEFINE_STACK_OF(SSL) + +/* + * Default maximum number of pending connections for DTLS listeners. + */ +#define DTLS_LISTENER_DEFAULT_MAX_PENDING_CONNS 256 + +/* + * Default maximum size in bytes of a datagram a DTLS listener will receive. + * A DTLS 1.3 ClientHello carrying large (e.g. post-quantum) key shares can + * exceed the 1500-byte Ethernet MTU; default a little above it so that such a + * ClientHello, when sent unfragmented, is received whole rather than truncated. + * Applied to the listener's demuxer. + */ +#define DTLS_LISTENER_DEFAULT_MAX_DGRAM_SIZE 2000 + +/* + * Upper bound for the DTLS listener receive datagram size: nothing larger than + * the maximum UDP payload can ever arrive. It may be raised up to this ceiling + * via SSL_set_value_uint(SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE). + */ +#define DTLS_LISTENER_MAX_DGRAM_SIZE 65535 + +/* + * DTLS listener SSL object type. This implements the API personality + * layer for DTLS listener objects, providing server-side connection + * demultiplexing for DTLS 1.3. + */ +typedef struct dtls_listener_st { + /* SSL object common header. */ + struct ssl_st ssl; + + /* + * Mutex protecting listener-owned data structures accessed across threads: + * - pending_conns: pending connection lookup table + * - established_conns: established connection lookup table + * - incoming_connections: queue of completed connections awaiting accept + * + * Accessed from: + * - Listener thread: packet handling, driving handshakes + * - Connection thread: unregistering via SSL_free -> dtls1_free + */ + CRYPTO_MUTEX *mutex; + + /* Datagram demultiplexer for incoming connections. */ + DGRAM_DEMUX *demux; + + /* The network BIOs for sending and receiving datagrams. */ + BIO *net_rbio; + BIO *net_wbio; + + /* Queue of incoming connections awaiting accept. */ + STACK_OF(SSL) *incoming_connections; + + /* + * Use DGRAM_CONN_LOOKUP to find pending connections. + */ + DGRAM_CONN_LOOKUP *pending_conns; + + /* + * Use DGRAM_CONN_LOOKUP to keep track of established connections. + */ + DGRAM_CONN_LOOKUP *established_conns; + + /* Have we started listening yet? */ + TSAN_QUALIFIER int listening; + + /* + * Set by ossl_dtls_tick() when the network BIO returns a hard error. + * Once set, ossl_dtls_accept_connection() returns NULL immediately. + */ + int fatal; + + /* Require HelloVerifyRequest + cookie for DTLS 1.0/1.2 */ + unsigned int require_hvr_cookie : 1; + + /* Require HelloRetryRequest + cookie for DTLS 1.3 */ + unsigned int require_hrr_cookie : 1; + + /* Using the notifier architecture */ + unsigned int have_notifier : 1; + + /* Notifier has been signalled */ + int signalled_notifier; + + /* + * Time callback for customizable time source (primarily for testing). + * If NULL, ossl_time_now() is used. + */ + OSSL_TIME (*now_cb)(void *arg); + void *now_cb_arg; + + /* + * Timeout for pending connections. Connections that haven't completed + * their handshake within this duration are considered stale and removed. + * Default: 30 seconds. Set to ossl_time_infinite() to disable. + */ + OSSL_TIME pending_timeout; + + /* + * Maximum number of pending connections allowed. + * When this limit is reached, new connection attempts are rejected. + * + * Default: DTLS_LISTENER_DEFAULT_MAX_PENDING_CONNS + * This limit cannot be disabled. + */ + size_t max_pending_conns; + + /* + * Largest datagram the listener will receive, chosen by the application. + * + * Default: DTLS_LISTENER_DEFAULT_MAX_DGRAM_SIZE + */ + size_t max_dgram_size; + + CRYPTO_CONDVAR *notifier_cv; + + /* + * Notifier for signaling events related to this listener. + */ + RIO_NOTIFIER notifier; + + /* + * Count of threads currently blocked waiting in poll(). + */ + size_t cur_blocking_waiters; + + /* + * Blocking mode requested for this listener, as a DTLS_BLOCKING_MODE. + * INHERIT here means blocking, there being nothing further to inherit + * from. + */ + unsigned int req_blocking_mode : 2; +} DTLS_LISTENER; + +#endif /* !OPENSSL_NO_DTLS && !OPENSSL_NO_SOCK */ + /* * From ECC-TLS draft, used in encoding the curve type in ECParameters */ @@ -2234,12 +2666,6 @@ typedef struct ssl3_enc_method { */ #define SSL_ENC_FLAG_TLS1_2_CIPHERS 0x10 -typedef enum downgrade_en { - DOWNGRADE_NONE, - DOWNGRADE_TO_1_2, - DOWNGRADE_TO_1_1 -} DOWNGRADE; - /* * Dummy status type for the status_type extension. Indicates no status type * set @@ -2284,6 +2710,9 @@ __owur const SSL_METHOD *dtls_bad_ver_client_method(void); __owur const SSL_METHOD *dtlsv1_2_method(void); __owur const SSL_METHOD *dtlsv1_2_server_method(void); __owur const SSL_METHOD *dtlsv1_2_client_method(void); +__owur const SSL_METHOD *dtlsv1_3_method(void); +__owur const SSL_METHOD *dtlsv1_3_server_method(void); +__owur const SSL_METHOD *dtlsv1_3_client_method(void); extern const SSL3_ENC_METHOD TLSv1_enc_data; extern const SSL3_ENC_METHOD TLSv1_1_enc_data; @@ -2291,6 +2720,7 @@ extern const SSL3_ENC_METHOD TLSv1_2_enc_data; extern const SSL3_ENC_METHOD TLSv1_3_enc_data; extern const SSL3_ENC_METHOD DTLSv1_enc_data; extern const SSL3_ENC_METHOD DTLSv1_2_enc_data; +extern const SSL3_ENC_METHOD DTLSv1_3_enc_data; /* * Flags for SSL methods @@ -2482,16 +2912,20 @@ __owur int ossl_bytes_to_cipher_list(SSL_CONNECTION *s, PACKET *cipher_suites, void ssl_update_cache(SSL_CONNECTION *s, int mode); __owur int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc, const EVP_CIPHER **enc); +__owur int ssl_cipher_get_evp_cipher_sn(SSL_CTX *ctx, const SSL_CIPHER *sslc, + const EVP_CIPHER **enc); __owur int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc, const EVP_MD **md, int *mac_pkey_type, size_t *mac_secret_size); -__owur int ssl_cipher_get_evp(SSL_CTX *ctxc, const SSL_SESSION *s, - const EVP_CIPHER **enc, const EVP_MD **md, +__owur int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s, + const EVP_CIPHER **snenc, + const EVP_CIPHER **enc, + const EVP_MD **md, int *mac_pkey_type, size_t *mac_secret_size, SSL_COMP **comp, int use_etm); -__owur int ssl_cipher_get_overhead(const SSL_CIPHER *c, size_t *mac_overhead, - size_t *int_overhead, size_t *blocksize, - size_t *ext_overhead); +__owur int ssl_cipher_get_overhead(const SSL_CIPHER *c, int version, + size_t *mac_overhead, size_t *int_overhead, + size_t *blocksize, size_t *ext_overhead); __owur int ssl_cert_is_disabled(SSL_CTX *ctx, size_t idx); __owur const SSL_CIPHER *ssl_get_cipher_by_char(SSL_CONNECTION *ssl, const unsigned char *ptr, @@ -2508,7 +2942,6 @@ void ssl_cert_set_cert_cb(CERT *c, int (*cb)(SSL *ssl, void *arg), void *arg); __owur int ssl_verify_cert_chain(SSL_CONNECTION *s, STACK_OF(X509) *sk); __owur int ssl_verify_rpk(SSL_CONNECTION *s, EVP_PKEY *rpk); -__owur int ssl_verify_ocsp(SSL *s, STACK_OF(X509) *sk); __owur int ssl_build_cert_chain(SSL_CONNECTION *s, SSL_CTX *ctx, int flags); __owur int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref); @@ -2633,25 +3066,22 @@ __owur int ssl_get_min_max_version(const SSL_CONNECTION *s, int *min_version, int *max_version, int *real_max); __owur OSSL_TIME tls1_default_timeout(void); -__owur int dtls1_do_write(SSL_CONNECTION *s, uint8_t type); -void dtls1_set_message_header(SSL_CONNECTION *s, - unsigned char mt, - size_t len, - size_t frag_off, size_t frag_len); +__owur int dtls1_do_write(SSL_CONNECTION *s, uint8_t recordtype); int dtls1_write_app_data_bytes(SSL *s, uint8_t type, const void *buf_, size_t len, size_t *written); +int dtls13_transcript_hash_update(EVP_MD_CTX *mdctx, + const unsigned char *buf, size_t len); __owur int dtls1_read_failed(SSL_CONNECTION *s, int code); -__owur int dtls1_buffer_message(SSL_CONNECTION *s, int ccs); -__owur int dtls1_retransmit_message(SSL_CONNECTION *s, unsigned short seq, - int *found); -__owur int dtls1_get_queue_priority(unsigned short seq, int is_ccs); -int dtls1_retransmit_buffered_messages(SSL_CONNECTION *s); +__owur int dtls1_buffer_sent_message(SSL_CONNECTION *s, int record_type); +__owur int dtls1_retransmit_message(SSL_CONNECTION *s, dtls_sent_msg *sent_msg); +void dtls1_get_queue_priority(unsigned char *prio64be, unsigned short seq, + int record_type); +int dtls1_retransmit_sent_messages(SSL_CONNECTION *s); void dtls1_clear_received_buffer(SSL_CONNECTION *s); -void dtls1_clear_sent_buffer(SSL_CONNECTION *s); -void dtls1_get_message_header(const unsigned char *data, - struct hm_header_st *msg_hdr); +void dtls1_clear_sent_buffer(SSL_CONNECTION *s, int keep_unacked_msgs); +void dtls1_acknowledge_sent_buffer(SSL_CONNECTION *s, uint64_t before_epoch); __owur OSSL_TIME dtls1_default_timeout(void); __owur int dtls1_get_timeout(const SSL_CONNECTION *s, OSSL_TIME *timeleft); __owur int dtls1_check_timeout_num(SSL_CONNECTION *s); @@ -2659,12 +3089,68 @@ __owur int dtls1_handle_timeout(SSL_CONNECTION *s); void dtls1_start_timer(SSL_CONNECTION *s); void dtls1_stop_timer(SSL_CONNECTION *s); __owur int dtls1_is_timer_expired(SSL_CONNECTION *s); +void dtls1_clear_current_wrl_from_sent_buffer(SSL_CONNECTION *s); __owur int dtls_raw_hello_verify_request(WPACKET *pkt, unsigned char *cookie, size_t cookie_len); __owur size_t dtls1_min_mtu(SSL_CONNECTION *s); void dtls1_hm_fragment_free(hm_fragment *frag); +void dtls1_sent_msg_free(dtls_sent_msg *msg); __owur int dtls1_query_mtu(SSL_CONNECTION *s); +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_SOCK) +SSL *ossl_dtls_new_listener(SSL_CTX *ctx, uint64_t flags); +void ossl_dtls_listener_free(SSL *ssl); +SSL *ossl_dtls_get0_listener(const SSL *ssl); +int ossl_dtls_listen(SSL *ssl); +SSL *ossl_dtls_accept_connection(SSL *ssl, uint64_t flags); +void ossl_dtls_listener_set0_net_rbio(SSL *s, BIO *bio); +void ossl_dtls_listener_set0_net_wbio(SSL *s, BIO *bio); +BIO *ossl_dtls_listener_get_net_rbio(const SSL *s); +BIO *ossl_dtls_listener_get_net_wbio(const SSL *s); + +/* Established connections API - these handle their own locking */ +SSL *ossl_dtls_listener_find_established_conn(DTLS_LISTENER *dl, + const DGRAM_URXE *urxe); +void ossl_dtls_listener_unregister_established_conn(SSL *s, + const BIO_ADDR *peer_addr); +void ossl_dtls_listener_clear_established_conns(DTLS_LISTENER *dl); + +size_t ossl_dtls_get_accept_connection_queue_len(SSL *ssl); +int ossl_dtls_listener_set_override_now_cb(SSL *s, + OSSL_TIME (*now_cb)(void *arg), + void *now_cb_arg); + +int ossl_dtls_get_value_uint(SSL *s, uint32_t class_, uint32_t id, uint64_t *value); +int ossl_dtls_set_value_uint(SSL *s, uint32_t class_, uint32_t id, uint64_t value); + +/* DTLS poll event functions - used by SSL_poll() */ +int ossl_dtls_listener_poll_events(SSL *s, uint64_t events, int do_tick, + uint64_t *revents); +int ossl_dtls_conn_poll_events(SSL *s, uint64_t events, int do_tick, + uint64_t *revents); +void ossl_dtls_listener_enter_blocking_section(SSL *s); +void ossl_dtls_listener_leave_blocking_section(SSL *s); +int ossl_dtls_block_until_ready(SSL *ssl, uint64_t events, OSSL_TIME deadline, + int bound_by_event_timeout); +int ossl_dtls_blocking(const SSL *s); +int ossl_dtls_set_blocking_mode(SSL *s, int blocking); +int ossl_dtls_get_blocking_mode(const SSL *s); +int ossl_dtls_conn_wait_for_datagram(SSL *s); +int ossl_dtls_conn_wait_for_write(SSL *s); +int ossl_dtls_tick(DTLS_LISTENER *dl); + +/* DTLS Listener internal cookie callbacks */ +int ossl_dtls_listener_gen_cookie_cb(SSL *ssl, unsigned char *cookie, + unsigned int *cookie_len); +int ossl_dtls_listener_verify_cookie_cb(SSL *ssl, const unsigned char *cookie, + unsigned int cookie_len); +int ossl_dtls_listener_gen_stateless_cookie_cb(SSL *ssl, unsigned char *cookie, + size_t *cookie_len); +int ossl_dtls_listener_verify_stateless_cookie_cb(SSL *ssl, + const unsigned char *cookie, + size_t cookie_len); +#endif /* !OPENSSL_NO_DTLS && !OPENSSL_NO_SOCK */ + __owur int tls1_new(SSL *s); void tls1_free(SSL *s); int tls1_clear(SSL *s); @@ -2850,6 +3336,7 @@ __owur int ssl_handshake_hash(SSL_CONNECTION *s, unsigned char *out, size_t outlen, size_t *hashlen); __owur const EVP_MD *ssl_md(SSL_CTX *ctx, int idx); +__owur int ssl_cipher_get_handshake_digest_nid(const SSL_CIPHER *c); int ssl_get_md_idx(int md_nid); __owur const EVP_MD *ssl_handshake_md(SSL_CONNECTION *s); __owur const EVP_MD *ssl_prf_md(SSL_CONNECTION *s); diff --git a/ssl/ssl_mcnf.c b/ssl/ssl_mcnf.c index 2480f527ceb67..cf073bfb40cb4 100644 --- a/ssl/ssl_mcnf.c +++ b/ssl/ssl_mcnf.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c index 7cfd59d6d0863..52f19b00423ab 100644 --- a/ssl/ssl_rsa.c +++ b/ssl/ssl_rsa.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index 5604ca135422b..472cb6dbc9813 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -279,8 +279,16 @@ SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket) { SSL_SESSION *sess = ssl_session_dup_intern(src, ticket); - if (sess != NULL) + if (sess != NULL) { sess->not_resumable = 0; + /* + * A duplicated session can land in the stateful session cache, and is + * not necessarily a live session just built for an external PSK. The + * caller must explicitly set this field non-zero after duplication as + * needed. + */ + sess->psk_external = 0; + } return sess; } @@ -358,6 +366,7 @@ int ssl_generate_session_id(SSL_CONNECTION *s, SSL_SESSION *ss) case DTLS1_BAD_VER: case DTLS1_VERSION: case DTLS1_2_VERSION: + case DTLS1_3_VERSION: ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; break; default: @@ -386,8 +395,10 @@ int ssl_generate_session_id(SSL_CONNECTION *s, SSL_SESSION *ss) } /* Choose which callback will set the session ID */ - if (!CRYPTO_THREAD_read_lock(SSL_CONNECTION_GET_SSL(s)->lock)) + if (!CRYPTO_THREAD_read_lock(SSL_CONNECTION_GET_SSL(s)->lock)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; + } if (!CRYPTO_THREAD_read_lock(s->session_ctx->lock)) { CRYPTO_THREAD_unlock(ssl->lock); SSLfatal(s, SSL_AD_INTERNAL_ERROR, @@ -452,7 +463,7 @@ int ssl_get_new_session(SSL_CONNECTION *s, int session) s->session = NULL; if (session) { - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { /* * We generate the session id while constructing the * NewSessionTicket in TLSv1.3. @@ -589,7 +600,7 @@ int ssl_get_prev_session(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello) int try_session_cache = 0; SSL_TICKET_STATUS r; - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { SSL_SESSION_free(s->session); s->session = NULL; /* @@ -648,7 +659,13 @@ int ssl_get_prev_session(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello) goto err; /* treat like cache miss */ } - if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) { + /* + * sid_ctx exists to keep multiple services that happen to share one + * session cache from resuming each other's sessions. This check is not + * relevant to external PSK sessions that are not restored from a cache. + */ + if (!ret->psk_external + && (s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) { /* * We can't be sure if this session is being used out of context, * which is especially important for SSL_VERIFY_PEER. The application @@ -687,8 +704,8 @@ int ssl_get_prev_session(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello) goto err; } - if (!SSL_CONNECTION_IS_TLS13(s)) { - /* We already did this for TLS1.3 */ + if (!SSL_CONNECTION_IS_VERSION13(s)) { + /* We already did this for (D)TLS1.3 */ SSL_SESSION_free(s->session); s->session = ret; } @@ -712,7 +729,7 @@ int ssl_get_prev_session(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello) * Refusing resumption and falling back to a full handshake is the correct * response. */ - if (!SSL_CONNECTION_IS_TLS13(s) && hello->session_id_len > 0 + if (!SSL_CONNECTION_IS_VERSION13(s) && hello->session_id_len > 0 && (s->session->session_id_length != hello->session_id_len || memcmp(s->session->session_id, hello->session_id, hello->session_id_len) @@ -726,8 +743,8 @@ int ssl_get_prev_session(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello) err: if (ret != NULL) { SSL_SESSION_free(ret); - /* In TLSv1.3 s->session was already set to ret, so we NULL it out */ - if (SSL_CONNECTION_IS_TLS13(s)) + /* In (D)TLSv1.3 s->session was already set to ret, so we NULL it out */ + if (SSL_CONNECTION_IS_VERSION13(s)) s->session = NULL; if (!try_session_cache) { @@ -932,7 +949,7 @@ int SSL_SESSION_up_ref(SSL_SESSION *ss) { int i; - if (CRYPTO_UP_REF(&ss->references, &i) <= 0) + if (!CRYPTO_UP_REF(&ss->references, &i)) return 0; REF_PRINT_COUNT("SSL_SESSION", i, ss); diff --git a/ssl/ssl_stat.c b/ssl/ssl_stat.c index 3c6e5d051d1f6..c6776ba83129d 100644 --- a/ssl/ssl_stat.c +++ b/ssl/ssl_stat.c @@ -21,79 +21,79 @@ const char *SSL_state_string_long(const SSL *s) switch (SSL_get_state(s)) { case TLS_ST_CR_CERT_STATUS: - return "SSLv3/TLS read certificate status"; + return "TLS read certificate status"; case TLS_ST_CW_NEXT_PROTO: - return "SSLv3/TLS write next proto"; + return "TLS write next proto"; case TLS_ST_SR_NEXT_PROTO: - return "SSLv3/TLS read next proto"; + return "TLS read next proto"; case TLS_ST_SW_CERT_STATUS: - return "SSLv3/TLS write certificate status"; + return "TLS write certificate status"; case TLS_ST_BEFORE: return "before SSL initialization"; case TLS_ST_OK: - return "SSL negotiation finished successfully"; + return "TLS negotiation finished successfully"; case TLS_ST_CW_CLNT_HELLO: - return "SSLv3/TLS write client hello"; + return "TLS write client hello"; case TLS_ST_CR_SRVR_HELLO: - return "SSLv3/TLS read server hello"; + return "TLS read server hello"; case TLS_ST_CR_CERT: - return "SSLv3/TLS read server certificate"; + return "TLS read server certificate"; case TLS_ST_CR_COMP_CERT: return "TLSv1.3 read server compressed certificate"; case TLS_ST_CR_KEY_EXCH: - return "SSLv3/TLS read server key exchange"; + return "TLS read server key exchange"; case TLS_ST_CR_CERT_REQ: - return "SSLv3/TLS read server certificate request"; + return "TLS read server certificate request"; case TLS_ST_CR_SESSION_TICKET: - return "SSLv3/TLS read server session ticket"; + return "TLS read server session ticket"; case TLS_ST_CR_SRVR_DONE: - return "SSLv3/TLS read server done"; + return "TLS read server done"; case TLS_ST_CW_CERT: - return "SSLv3/TLS write client certificate"; + return "TLS write client certificate"; case TLS_ST_CW_COMP_CERT: return "TLSv1.3 write client compressed certificate"; case TLS_ST_CW_KEY_EXCH: - return "SSLv3/TLS write client key exchange"; + return "TLS write client key exchange"; case TLS_ST_CW_CERT_VRFY: - return "SSLv3/TLS write certificate verify"; + return "TLS write certificate verify"; case TLS_ST_CW_CHANGE: case TLS_ST_SW_CHANGE: - return "SSLv3/TLS write change cipher spec"; + return "TLS write change cipher spec"; case TLS_ST_CW_FINISHED: case TLS_ST_SW_FINISHED: - return "SSLv3/TLS write finished"; + return "TLS write finished"; case TLS_ST_CR_CHANGE: case TLS_ST_SR_CHANGE: - return "SSLv3/TLS read change cipher spec"; + return "TLS read change cipher spec"; case TLS_ST_CR_FINISHED: case TLS_ST_SR_FINISHED: - return "SSLv3/TLS read finished"; + return "TLS read finished"; case TLS_ST_SR_CLNT_HELLO: - return "SSLv3/TLS read client hello"; + return "TLS read client hello"; case TLS_ST_SW_HELLO_REQ: - return "SSLv3/TLS write hello request"; + return "TLS write hello request"; case TLS_ST_SW_SRVR_HELLO: - return "SSLv3/TLS write server hello"; + return "TLS write server hello"; case TLS_ST_SW_CERT: - return "SSLv3/TLS write certificate"; + return "TLS write certificate"; case TLS_ST_SW_COMP_CERT: return "TLSv1.3 write server compressed certificate"; case TLS_ST_SW_KEY_EXCH: - return "SSLv3/TLS write key exchange"; + return "TLS write key exchange"; case TLS_ST_SW_CERT_REQ: - return "SSLv3/TLS write certificate request"; + return "TLS write certificate request"; case TLS_ST_SW_SESSION_TICKET: - return "SSLv3/TLS write session ticket"; + return "TLS write session ticket"; case TLS_ST_SW_SRVR_DONE: - return "SSLv3/TLS write server done"; + return "TLS write server done"; case TLS_ST_SR_CERT: - return "SSLv3/TLS read client certificate"; + return "TLS read client certificate"; case TLS_ST_SR_COMP_CERT: return "TLSv1.3 read client compressed certificate"; case TLS_ST_SR_KEY_EXCH: - return "SSLv3/TLS read client key exchange"; + return "TLS read client key exchange"; case TLS_ST_SR_CERT_VRFY: - return "SSLv3/TLS read certificate verify"; + return "TLS read certificate verify"; case DTLS_ST_CR_HELLO_VERIFY_REQUEST: return "DTLS1 read hello verify request"; case DTLS_ST_SW_HELLO_VERIFY_REQUEST: @@ -107,7 +107,7 @@ const char *SSL_state_string_long(const SSL *s) case TLS_ST_SW_CERT_VRFY: return "TLSv1.3 write server certificate verify"; case TLS_ST_CR_HELLO_REQ: - return "SSLv3/TLS read hello request"; + return "TLS read hello request"; case TLS_ST_SW_KEY_UPDATE: return "TLSv1.3 write server key update"; case TLS_ST_CW_KEY_UPDATE: @@ -124,6 +124,14 @@ const char *SSL_state_string_long(const SSL *s) return "TLSv1.3 write end of early data"; case TLS_ST_SR_END_OF_EARLY_DATA: return "TLSv1.3 read end of early data"; + case TLS_ST_CR_ACK: + return "DTLSv1.3 read client ack"; + case TLS_ST_CW_ACK: + return "DTLSv1.3 write client ack"; + case TLS_ST_SR_ACK: + return "DTLSv1.3 read server ack"; + case TLS_ST_SW_ACK: + return "DTLSv1.3 write server ack"; default: return "unknown state"; } @@ -241,6 +249,14 @@ const char *SSL_state_string(const SSL *s) return "TWEOED"; case TLS_ST_SR_END_OF_EARLY_DATA: return "TWEOED"; + case TLS_ST_CR_ACK: + return "TRCACK"; + case TLS_ST_CW_ACK: + return "TWCACK"; + case TLS_ST_SR_ACK: + return "TRSACK"; + case TLS_ST_SW_ACK: + return "TWSACK"; default: return "UNKWN"; } diff --git a/ssl/ssl_txt.c b/ssl/ssl_txt.c index 0fc3e5a334b1c..530e339a9f7fb 100644 --- a/ssl/ssl_txt.c +++ b/ssl/ssl_txt.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright 2005 Nokia. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -35,11 +35,12 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) { size_t i; const char *s; - int istls13; + int isversion13; if (x == NULL) goto err; - istls13 = (x->ssl_version == TLS1_3_VERSION); + isversion13 = (x->ssl_version == TLS1_3_VERSION) + || (x->ssl_version == DTLS1_3_VERSION); if (BIO_puts(bp, "SSL-Session:\n") <= 0) goto err; s = ssl_protocol_to_string(x->ssl_version); @@ -77,7 +78,7 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) if (BIO_printf(bp, "%02X", x->sid_ctx[i]) <= 0) goto err; } - if (istls13) { + if (isversion13) { if (BIO_puts(bp, "\n Resumption PSK: ") <= 0) goto err; } else if (BIO_puts(bp, "\n Master-Key: ") <= 0) @@ -120,7 +121,7 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) if (x->compress_meth != 0) { SSL_COMP *comp = NULL; - if (!ssl_cipher_get_evp(NULL, x, NULL, NULL, NULL, NULL, &comp, 0)) + if (!ssl_cipher_get_evp(NULL, x, NULL, NULL, NULL, NULL, NULL, &comp, 0)) goto err; if (comp == NULL) { if (BIO_printf(bp, "\n Compression: %u", x->compress_meth) <= 0) @@ -160,7 +161,7 @@ int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) <= 0) goto err; - if (istls13) { + if (isversion13) { if (BIO_printf(bp, " Max Early Data: %u\n", (unsigned int)x->ext.max_early_data) <= 0) diff --git a/ssl/ssl_utst.c b/ssl/ssl_utst.c index 7ff8932e42d04..c562090126dbc 100644 --- a/ssl/ssl_utst.c +++ b/ssl/ssl_utst.c @@ -1,5 +1,5 @@ /* - * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index c3ef683d75793..d09a43d616728 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -229,7 +229,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { * to indicate to the client the complete list of groups supported * by the server, with the server instead just indicating the * selected group for this connection in the ServerKeyExchange - * message. TLS 1.3 adds a scheme for the server to indicate + * message. (D)TLS 1.3 adds a scheme for the server to indicate * to the client its list of supported groups in the * EncryptedExtensions message, but none of the relevant * specifications permit sending supported_groups in the ServerHello. @@ -239,7 +239,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { * ServerHello anyway. Up to and including the 1.1.0 release, * we did not check for the presence of nonpermitted extensions, * so to avoid a regression, we must permit this extension in the - * TLS 1.2 ServerHello as well. + * (D)TLS 1.2 ServerHello as well. * * Note that there is no tls_parse_stoc_supported_groups function, * so we do not perform any additional parsing, validation, or @@ -378,7 +378,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { tls_construct_ctos_sig_algs, final_sig_algs }, { TLSEXT_TYPE_supported_versions, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO - | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST | SSL_EXT_TLS_IMPLEMENTATION_ONLY, + | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST, OSSL_ECH_HANDLING_COMPRESS, NULL, /* Processed inline as part of version selection */ @@ -386,8 +386,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { tls_construct_stoc_supported_versions, tls_construct_ctos_supported_versions, final_supported_versions }, { TLSEXT_TYPE_psk_kex_modes, - SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS_IMPLEMENTATION_ONLY - | SSL_EXT_TLS1_3_ONLY, + SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_ONLY, OSSL_ECH_HANDLING_COMPRESS, init_psk_kex_modes, tls_parse_ctos_psk_kex_modes, NULL, NULL, tls_construct_ctos_psk_kex_modes, NULL }, @@ -397,7 +396,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { */ TLSEXT_TYPE_key_share, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO - | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST | SSL_EXT_TLS_IMPLEMENTATION_ONLY + | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST | SSL_EXT_TLS1_3_ONLY, OSSL_ECH_HANDLING_COMPRESS, NULL, tls_parse_ctos_key_share, tls_parse_stoc_key_share, @@ -406,7 +405,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { { /* Must be after key_share */ TLSEXT_TYPE_cookie, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST - | SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY, + | SSL_EXT_TLS1_3_ONLY, OSSL_ECH_HANDLING_COMPRESS, NULL, tls_parse_ctos_cookie, tls_parse_stoc_cookie, tls_construct_stoc_cookie, tls_construct_ctos_cookie, NULL }, @@ -422,7 +421,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { NULL, NULL, NULL, tls_construct_stoc_cryptopro_bug, NULL, NULL }, { TLSEXT_TYPE_compress_certificate, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_CERTIFICATE_REQUEST - | SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY, + | SSL_EXT_TLS1_3_ONLY, OSSL_ECH_HANDLING_COMPRESS, tls_init_compress_certificate, tls_parse_compress_certificate, tls_parse_compress_certificate, @@ -478,17 +477,10 @@ static const EXTENSION_DEFINITION ext_defs[] = { 0, NULL, NULL, NULL, NULL, tls_construct_ctos_grease2, NULL }, - { /* Must be immediately before pre_shared_key */ - TLSEXT_TYPE_padding, - SSL_EXT_CLIENT_HELLO, - OSSL_ECH_HANDLING_CALL_BOTH, - NULL, - /* We send this, but don't read it */ - NULL, NULL, NULL, tls_construct_ctos_padding, NULL }, - { /* Required by the TLSv1.3 spec to always be the last extension */ + { /* Required by the (D)TLSv1.3 spec to always be the last extension */ TLSEXT_TYPE_psk, SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_SERVER_HELLO - | SSL_EXT_TLS_IMPLEMENTATION_ONLY | SSL_EXT_TLS1_3_ONLY, + | SSL_EXT_TLS1_3_ONLY, OSSL_ECH_HANDLING_CALL_BOTH, NULL, tls_parse_ctos_psk, tls_parse_stoc_psk, tls_construct_stoc_psk, tls_construct_ctos_psk, final_psk } @@ -798,6 +790,62 @@ static int tls_parse_ec_pt_formats(SSL_CONNECTION *s, PACKET *pkt, return 1; } +/* + * Verify that all extensions in |packet| are known built-in or custom + * extension types. This is used for TLS 1.3 server extension responses where + * unknown extensions are not ignored. + */ +int tls_validate_no_unknown_extensions(SSL_CONNECTION *s, PACKET *packet, + unsigned int context) +{ + PACKET extensions = *packet; + custom_ext_methods *exts = &s->cert->custext; + ENDPOINT role = ENDPOINT_BOTH; + + if ((context & SSL_EXT_CLIENT_HELLO) != 0) { +#ifndef OPENSSL_NO_ECH + if (s->ext.ech.attempted == 1 && s->ext.ech.ch_depth == 1) + role = ENDPOINT_CLIENT; + else + role = ENDPOINT_SERVER; +#else + role = ENDPOINT_SERVER; +#endif + } else if ((context & SSL_EXT_TLS1_2_SERVER_HELLO) != 0) { + role = ENDPOINT_CLIENT; + } + + while (PACKET_remaining(&extensions) > 0) { + unsigned int type; + size_t i; + PACKET extension; + const EXTENSION_DEFINITION *thisext; + + if (!PACKET_get_net_2(&extensions, &type) + || !PACKET_get_length_prefixed_2(&extensions, &extension)) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); + return 0; + } + + for (i = 0, thisext = ext_defs; i < OSSL_NELEM(ext_defs); + i++, thisext++) { + if (type == thisext->type) + break; + } + if (i < OSSL_NELEM(ext_defs)) + continue; + + if (exts != NULL && custom_ext_find(exts, role, type, NULL) != NULL) + continue; + + SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, + SSL_R_UNSOLICITED_EXTENSION); + return 0; + } + + return 1; +} + /* * Check whether the context defined for an extension |extctx| means whether * the extension is relevant for the current context |thisctx| or not. Returns @@ -806,31 +854,31 @@ static int tls_parse_ec_pt_formats(SSL_CONNECTION *s, PACKET *pkt, int extension_is_relevant(SSL_CONNECTION *s, unsigned int extctx, unsigned int thisctx) { - int is_tls13; + int is_version13; /* * For HRR we haven't selected the version yet but we know it will be - * TLSv1.3 + * (D)TLSv1.3 */ if ((thisctx & SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST) != 0) - is_tls13 = 1; + is_version13 = 1; else - is_tls13 = SSL_CONNECTION_IS_TLS13(s); + is_version13 = SSL_CONNECTION_IS_VERSION13(s); if ((SSL_CONNECTION_IS_DTLS(s) && (extctx & SSL_EXT_TLS_IMPLEMENTATION_ONLY) != 0) /* - * Note that SSL_IS_TLS13() means "TLS 1.3 has been negotiated", + * Note that is_version13 means "(D)TLS 1.3 has been negotiated", * which is never true when generating the ClientHello. * However, version negotiation *has* occurred by the time the * ClientHello extensions are being parsed. - * Be careful to allow TLS 1.3-only extensions when generating + * Be careful to allow (D)TLS 1.3-only extensions when generating * the ClientHello. */ - || (is_tls13 && (extctx & SSL_EXT_TLS1_2_AND_BELOW_ONLY) != 0) - || (!is_tls13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0 + || (is_version13 && (extctx & SSL_EXT_TLS1_2_AND_BELOW_ONLY) != 0) + || (!is_version13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0 && (thisctx & SSL_EXT_CLIENT_HELLO) == 0) - || (s->server && !is_tls13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0) + || (s->server && !is_version13 && (extctx & SSL_EXT_TLS1_3_ONLY) != 0) || (s->hit && (extctx & SSL_EXT_IGNORE_ON_RESUMPTION) != 0)) return 0; return 1; @@ -907,7 +955,6 @@ int tls_collect_extensions(SSL_CONNECTION *s, PACKET *packet, SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_EXTENSION); goto err; } - /* The server must tolerate the unknown extension and complete. */ if (thisex == NULL) continue; @@ -1079,6 +1126,8 @@ int tls_parse_all_extensions(SSL_CONNECTION *s, int context, int should_add_extension(SSL_CONNECTION *s, unsigned int extctx, unsigned int thisctx, int max_version) { + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + /* Skip if not relevant for our context */ if ((extctx & thisctx) == 0) return 0; @@ -1087,7 +1136,7 @@ int should_add_extension(SSL_CONNECTION *s, unsigned int extctx, if (!extension_is_relevant(s, extctx, thisctx) || ((extctx & SSL_EXT_TLS1_3_ONLY) != 0 && (thisctx & SSL_EXT_CLIENT_HELLO) != 0 - && (SSL_CONNECTION_IS_DTLS(s) || max_version < TLS1_3_VERSION))) + && ssl_version_cmp(s, max_version, version1_3) < 0)) return 0; return 1; @@ -1117,7 +1166,7 @@ int tls_construct_extensions(SSL_CONNECTION *s, WPACKET *pkt, /* * If extensions are of zero length then we don't even add the * extensions length bytes to a ClientHello/ServerHello - * (for non-TLSv1.3). + * (for non-(D)TLSv1.3). */ || ((context & (SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO)) != 0 && !WPACKET_set_flags(pkt, @@ -1398,8 +1447,8 @@ static int final_server_name(SSL_CONNECTION *s, unsigned int context, int sent) return 0; case SSL_TLSEXT_ERR_ALERT_WARNING: - /* TLSv1.3 doesn't have warning alerts so we suppress this */ - if (!SSL_CONNECTION_IS_TLS13(s)) + /* (D)TLSv1.3 doesn't have warning alerts so we suppress this */ + if (!SSL_CONNECTION_IS_VERSION13(s)) ssl3_send_alert(s, SSL3_AL_WARNING, altmp); s->servername_done = 0; return 1; @@ -1470,15 +1519,15 @@ static int final_alpn(SSL_CONNECTION *s, unsigned int context, int sent) if (!s->server && !sent && s->session->ext.alpn_selected != NULL) s->ext.early_data_ok = 0; - if (!s->server || !SSL_CONNECTION_IS_TLS13(s)) + if (!s->server || !SSL_CONNECTION_IS_VERSION13(s)) return 1; /* * Call alpn_select callback if needed. Has to be done after SNI and - * cipher negotiation (HTTP/2 restricts permitted ciphers). In TLSv1.3 + * cipher negotiation (HTTP/2 restricts permitted ciphers). In (D)TLSv1.3 * we also have to do this before we decide whether to accept early_data. - * In TLSv1.3 we've already negotiated our cipher so we do this call now. - * For < TLSv1.3 we defer it until after cipher negotiation. + * In (D)TLSv1.3 we've already negotiated our cipher so we do this call now. + * For < (D)TLSv1.3 we defer it until after cipher negotiation. * * On failure SSLfatal() already called. */ @@ -1629,7 +1678,7 @@ static int init_srtp(SSL_CONNECTION *s, unsigned int context) static int final_sig_algs(SSL_CONNECTION *s, unsigned int context, int sent) { - if (!sent && SSL_CONNECTION_IS_TLS13(s) && !s->hit) { + if (!sent && SSL_CONNECTION_IS_VERSION13(s) && !s->hit) { SSLfatal(s, TLS13_AD_MISSING_EXTENSION, SSL_R_MISSING_SIGALGS_EXTENSION); return 0; @@ -1652,8 +1701,8 @@ static int final_supported_versions(SSL_CONNECTION *s, unsigned int context, static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent) { -#if !defined(OPENSSL_NO_TLS1_3) - if (!SSL_CONNECTION_IS_TLS13(s)) +#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3)) + if (!SSL_CONNECTION_IS_VERSION13(s)) return 1; /* Nothing to do for key_share in an HRR */ @@ -1788,7 +1837,7 @@ static int final_key_share(SSL_CONNECTION *s, unsigned int context, int sent) return 0; } } -#endif /* !defined(OPENSSL_NO_TLS1_3) */ +#endif /* !defined(OPENSSL_NO_TLS1_3) && !defined(OPENSSL_NO_DTLS1_3) */ return 1; } @@ -1813,8 +1862,8 @@ int tls_psk_do_binder(SSL_CONNECTION *s, const EVP_MD *md, static const unsigned char resumption_label[] = "\x72\x65\x73\x20\x62\x69\x6E\x64\x65\x72"; /* ASCII: "ext binder", in hex for EBCDIC compatibility */ static const unsigned char external_label[] = "\x65\x78\x74\x20\x62\x69\x6E\x64\x65\x72"; - const unsigned char *label; - size_t bindersize, labelsize, hashsize; + const unsigned char *label, *msgbodystart; + size_t bindersize, labelsize, hashsize, msgbodylen; int hashsizei = EVP_MD_get_size(md); int ret = -1; int usepskfored = 0; @@ -1830,8 +1879,7 @@ int tls_psk_do_binder(SSL_CONNECTION *s, const EVP_MD *md, if (external && s->early_data_state == SSL_EARLY_DATA_CONNECTING - && s->session->ext.max_early_data == 0 - && sess->ext.max_early_data > 0) + && sess == s->ext.early_data_session) usepskfored = 1; if (external) { @@ -1861,6 +1909,16 @@ int tls_psk_do_binder(SSL_CONNECTION *s, const EVP_MD *md, goto err; } + /* + * Client-only: record that this flight's first-offered PSK has derived + * s->early_secret, so the early-write key install can refuse to key 0-RTT + * off an underived (zero) secret. early_secret aliases s->early_secret + * exactly for the identity that 0-RTT is keyed on (the resumption PSK, or + * an external PSK selected for early data via usepskfored). + */ + if (!s->server && early_secret == (unsigned char *)s->early_secret) + s->ext.early_secret_derived = 1; + /* * Create the handshake hash for the binder key...the messages so far are * empty! @@ -1899,7 +1957,7 @@ int tls_psk_do_binder(SSL_CONNECTION *s, const EVP_MD *md, if (s->hello_retry_request == SSL_HRR_PENDING) { size_t hdatalen; long hdatalen_l; - void *hdata; + unsigned char *hdata; #ifndef OPENSSL_NO_ECH /* handle the hashing as per ECH needs (on client) */ @@ -1919,32 +1977,89 @@ int tls_psk_do_binder(SSL_CONNECTION *s, const EVP_MD *md, } #endif - /* - * For servers the handshake buffer data will include the second - * ClientHello - which we don't want - so we need to take that bit off. - */ - if (s->server) { + if (s->negotiated_version == DTLS1_3_VERSION) { PACKET hashprefix, msg; + unsigned long dtlsbodylen; + unsigned int dtls_offset = DTLS1_HM_HEADER_LENGTH - SSL3_HM_HEADER_LENGTH; - /* Find how many bytes are left after the first two messages */ + /* + * RFC 9147 states that for DTLS 1.3 all transcripts should be + * calculated without the message_seq, fragment_offset and + * fragment_length values. See Section 5.2 + * + * Since the data is coming from handshake_buffer it hasn't + * been processed in ssl3_finish_mac where these values are + * removed. Therefore for both the server and client we will + * need to not supply them to the Digest Update + */ if (!PACKET_buf_init(&hashprefix, hdata, hdatalen) || !PACKET_forward(&hashprefix, 1) || !PACKET_get_length_prefixed_3(&hashprefix, &msg) || !PACKET_forward(&hashprefix, 1) - || !PACKET_get_length_prefixed_3(&hashprefix, &msg)) { + || !PACKET_get_net_3(&hashprefix, &dtlsbodylen)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } + hdatalen -= PACKET_remaining(&hashprefix); - } - if (EVP_DigestUpdate(mctx, hdata, hdatalen) <= 0) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - goto err; + if (EVP_DigestUpdate(mctx, hdata, hdatalen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* + * Now skip the four bytes for the part of the DTLS header to not + * include in the transcript. + */ + if (EVP_DigestUpdate(mctx, hdata + hdatalen + dtls_offset, dtlsbodylen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + } else { + /* + * For servers the handshake buffer data will include the second + * ClientHello - which we don't want - so we need to take that bit off. + */ + if (s->server) { + PACKET hashprefix, msg; + + /* Find how many bytes are left after the first two messages */ + if (!PACKET_buf_init(&hashprefix, hdata, hdatalen) + || !PACKET_forward(&hashprefix, 1) + || !PACKET_get_length_prefixed_3(&hashprefix, &msg) + || !PACKET_forward(&hashprefix, 1) + || !PACKET_get_length_prefixed_3(&hashprefix, &msg)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + hdatalen -= PACKET_remaining(&hashprefix); + } + + if (EVP_DigestUpdate(mctx, hdata, hdatalen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } } } - if (EVP_DigestUpdate(mctx, msgstart, binderoffset) <= 0 + if (SSL_CONNECTION_IS_DTLS(s)) { + msgbodystart = msgstart + DTLS1_HM_HEADER_LENGTH; + msgbodylen = binderoffset - DTLS1_HM_HEADER_LENGTH; + } else { + msgbodystart = msgstart + SSL3_HM_HEADER_LENGTH; + msgbodylen = binderoffset - SSL3_HM_HEADER_LENGTH; + } + + /* + * RFC9147 (DTLSv1.3) + * The transcript consists of complete TLS Handshake messages + * (reassembled as necessary). Note that this requires removing the + * message_seq, fragment_offset, and fragment_length fields to create + * the Handshake structure. + */ + if (EVP_DigestUpdate(mctx, msgstart, SSL3_HM_HEADER_LENGTH) <= 0 + || EVP_DigestUpdate(mctx, msgbodystart, msgbodylen) <= 0 || EVP_DigestFinal_ex(mctx, hash, NULL) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; diff --git a/ssl/statem/extensions_clnt.c b/ssl/statem/extensions_clnt.c index e3e713f5f6557..368436082979a 100644 --- a/ssl/statem/extensions_clnt.c +++ b/ssl/statem/extensions_clnt.c @@ -8,13 +8,13 @@ */ #include +#include #include "../ssl_local.h" #include "internal/cryptlib.h" #include "internal/ssl_unwrap.h" #include "internal/tlsgroups.h" #include "statem_local.h" #ifndef OPENSSL_NO_ECH -#include #include "internal/ech_helpers.h" #endif @@ -30,16 +30,15 @@ EXT_RETURN tls_construct_ctos_renegotiate(SSL_CONNECTION *s, WPACKET *pkt, size_t chainidx) { if (!s->renegotiate) { - /* If not renegotiating, send an empty RI extension to indicate support */ + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION + : TLS1_3_VERSION; -#if DTLS_MAX_VERSION_INTERNAL != DTLS1_2_VERSION -#error Internal DTLS version error -#endif - - if (!SSL_CONNECTION_IS_DTLS(s) - && (s->min_proto_version >= TLS1_3_VERSION - || (ssl_security(s, SSL_SECOP_VERSION, 0, TLS1_VERSION, NULL) - && s->min_proto_version <= TLS1_VERSION))) { + /* If not renegotiating, send an empty RI extension to indicate support */ + if ((s->min_proto_version != 0 + && ssl_version_cmp(s, s->min_proto_version, version1_3) >= 0) + || (!SSL_CONNECTION_IS_DTLS(s) + && ssl_security(s, SSL_SECOP_VERSION, 0, TLS1_VERSION, NULL) + && s->min_proto_version <= TLS1_VERSION)) { /* * For TLS <= 1.0 SCSV is used instead, and for TLS 1.3 this * extension isn't used at all. @@ -309,6 +308,7 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, const uint16_t *pgroups = NULL; size_t num_groups = 0, i, tls13added = 0, added = 0; int min_version, max_version, reason; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; int dtls = SSL_CONNECTION_IS_DTLS(s); int use_ecdhe, use_ffdhe; @@ -374,7 +374,7 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } - if (okfortls13 && max_version == TLS1_3_VERSION) + if (okfortls13 && max_version == version1_3) tls13added++; added++; } @@ -387,7 +387,7 @@ EXT_RETURN tls_construct_ctos_supported_groups(SSL_CONNECTION *s, WPACKET *pkt, return EXT_RETURN_FAIL; } - if (tls13added == 0 && max_version == TLS1_3_VERSION) { + if (tls13added == 0 && max_version == version1_3) { SSLfatal_data(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_SUITABLE_GROUPS, "No groups enabled for max supported SSL/TLS version"); return EXT_RETURN_FAIL; @@ -401,6 +401,7 @@ EXT_RETURN tls_construct_ctos_session_ticket(SSL_CONNECTION *s, WPACKET *pkt, size_t chainidx) { size_t ticklen; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (!tls_use_ticket(s)) return EXT_RETURN_NOT_SENT; @@ -410,7 +411,7 @@ EXT_RETURN tls_construct_ctos_session_ticket(SSL_CONNECTION *s, WPACKET *pkt, if (!s->new_session && s->session != NULL && s->session->ext.tick != NULL - && s->session->ssl_version != TLS1_3_VERSION) { + && s->session->ssl_version != version1_3) { ticklen = s->session->ext.ticklen; } else if (s->session && s->ext.session_ticket != NULL && s->ext.session_ticket->data != NULL) { @@ -748,6 +749,8 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt size_t chainidx) { int currv, min_version, max_version, reason; + const int isdtls = SSL_CONNECTION_IS_DTLS(s); + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; reason = ssl_get_min_max_version(s, &min_version, &max_version, NULL); if (reason != 0) { @@ -756,10 +759,9 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt } /* - * Don't include this if we can't negotiate TLSv1.3. We can do a straight - * comparison here because we will never be called in DTLS. + * Don't include this if we can't negotiate (D)TLSv1.3. */ - if (max_version < TLS1_3_VERSION) + if (ssl_version_cmp(s, max_version, version1_3) < 0) return EXT_RETURN_NOT_SENT; #ifndef OPENSSL_NO_ECH ECH_SAME_EXT(s, context, pkt) @@ -780,7 +782,8 @@ EXT_RETURN tls_construct_ctos_supported_versions(SSL_CONNECTION *s, WPACKET *pkt return EXT_RETURN_FAIL; } } - for (currv = max_version; currv >= min_version; currv--) { + for (currv = max_version; ssl_version_cmp(s, currv, min_version) >= 0; + isdtls ? currv++ : currv--) { if (!WPACKET_put_bytes_u16(pkt, currv)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; @@ -801,7 +804,7 @@ EXT_RETURN tls_construct_ctos_psk_kex_modes(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { -#ifndef OPENSSL_NO_TLS1_3 +#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3)) int nodhe = s->options & SSL_OP_ALLOW_NO_DHE_KEX; #ifndef OPENSSL_NO_ECH @@ -827,7 +830,7 @@ EXT_RETURN tls_construct_ctos_psk_kex_modes(SSL_CONNECTION *s, WPACKET *pkt, return EXT_RETURN_SENT; } -#ifndef OPENSSL_NO_TLS1_3 +#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3)) static int add_key_share(SSL_CONNECTION *s, WPACKET *pkt, unsigned int group_id, size_t loop_num) { unsigned char *encoded_pubkey = NULL; @@ -835,13 +838,15 @@ static int add_key_share(SSL_CONNECTION *s, WPACKET *pkt, unsigned int group_id, size_t encodedlen; if (loop_num < s->s3.tmp.num_ks_pkey) { - if (!ossl_assert(s->hello_retry_request == SSL_HRR_PENDING) + if (!ossl_assert(s->hello_retry_request == SSL_HRR_PENDING + || s->d1->hello_verify_request == SSL_HVR_RECEIVED) || !ossl_assert(s->s3.tmp.ks_pkey[loop_num] != NULL)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; } /* - * Could happen if we got an HRR that wasn't requesting a new key_share + * Could happen if we got a HRR that wasn't requesting a new key_share + * or if we got a HelloVerifyRequest */ key_share_key = s->s3.tmp.ks_pkey[loop_num]; } else { @@ -892,7 +897,7 @@ EXT_RETURN tls_construct_ctos_key_share(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { -#ifndef OPENSSL_NO_TLS1_3 +#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3)) size_t i, num_groups = 0; const uint16_t *pgroups = NULL; uint16_t group_id = 0; @@ -913,8 +918,14 @@ EXT_RETURN tls_construct_ctos_key_share(SSL_CONNECTION *s, WPACKET *pkt, return EXT_RETURN_FAIL; } - /* RFC 8701: prepend a GREASE key share entry (1 byte of 0x00) */ - if ((s->options & SSL_OP_GREASE) && !s->server) { + /* + * RFC 8701: prepend a GREASE key share entry (1 byte of 0x00). After an + * HRR requesting a new key share, RFC 9846 requires the requested entry + * to be the only one in the second ClientHello. + */ + if ((s->options & SSL_OP_GREASE) && !s->server + && !(s->hello_retry_request == SSL_HRR_PENDING + && s->s3.group_id != 0 && s->s3.tmp.pkey == NULL)) { uint16_t grease_group = ossl_grease_value(s, OSSL_GREASE_GROUP); if (!WPACKET_put_bytes_u16(pkt, grease_group) @@ -954,9 +965,13 @@ EXT_RETURN tls_construct_ctos_key_share(SSL_CONNECTION *s, WPACKET *pkt, add_only_one = 1; for (i = 0; i < num_groups; i++) { + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION + : TLS1_3_VERSION; + if (!tls_group_allowed(s, pgroups[i], SSL_SECOP_CURVE_SUPPORTED)) continue; - if (!tls_valid_group(s, pgroups[i], TLS1_3_VERSION, TLS1_3_VERSION, + + if (!tls_valid_group(s, pgroups[i], version1_3, version1_3, NULL, NULL)) continue; @@ -1032,6 +1047,167 @@ EXT_RETURN tls_construct_ctos_cookie(SSL_CONNECTION *s, WPACKET *pkt, return ret; } +static int tls13_check_tick_lifetime_hint(SSL_CONNECTION *s) +{ + OSSL_TIME t; + uint32_t agesec; + + if (s->ext.tick_age_checked) + return s->ext.tick_age_ok; + s->ext.tick_age_ok = 1; + + /* + * Technically the C standard just says time() returns a time_t and says + * nothing about the encoding of that type. In practice most + * implementations follow POSIX which holds it as an integral type in + * seconds since epoch. We've already made the assumption that we can do + * this in multiple places in the code, so portability shouldn't be an + * issue. + */ + t = ossl_time_subtract(ossl_time_now(), s->session->time); + agesec = (uint32_t)ossl_time2seconds(t); + + /* + * We calculate the age in seconds but the server may work in ms. Due to + * rounding errors we could overestimate the age by up to 1s. It is + * better to underestimate it. Otherwise, if the RTT is very short, when + * the server calculates the age reported by the client it could be + * bigger than the age calculated on the server - which should never + * happen. + */ + if (agesec > 0) + agesec--; + + /* + * Calculate age in ms. We're just doing it to nearest second. Should be + * good enough. + */ + s->ext.tick_age_ms = agesec * (uint32_t)1000; + + /* + * Ticket is too old. Ignore it. Overflow. Shouldn't happen unless this is a + * *really* old session. If so we just ignore it. + */ + if (s->session->ext.tick_lifetime_hint < agesec) + s->ext.tick_age_ok = 0; + else if (agesec != 0 && s->ext.tick_age_ms / (uint32_t)1000 != agesec) + s->ext.tick_age_ok = 0; + + s->ext.tick_age_checked = 1; + return s->ext.tick_age_ok; +} + +/* + * True if a TLS 1.3 ciphersuite carrying the same handshake digest as |cipher| + * is being offered on this handshake. |cipher| must itself be a TLS 1.3 cipher: + * the algorithm2 handshake-MAC bits read here mean something else in a TLS 1.2 + * suite, so a non-TLS-1.3 cipher (e.g. from a bogus callback PSK) is never viable. + */ +static int tls13_digest_offered(SSL_CONNECTION *s, const SSL_CIPHER *cipher) +{ + STACK_OF(SSL_CIPHER) *ciphers; + int i, n, want; + + if (cipher == NULL || cipher->min_tls <= TLS1_2_VERSION) + return 0; + want = ssl_cipher_get_handshake_digest_nid(cipher); + if (want == NID_undef) + return 0; + ciphers = ssl_get_ciphers_by_id(s); + n = sk_SSL_CIPHER_num(ciphers); + for (i = 0; i < n; i++) { + const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i); + + /* + * SSL_SECOP_CIPHER_SUPPORTED matches the ssl_cipher_list_to_bytes() + * ciphersuite filter. + */ + if (c->min_tls > TLS1_2_VERSION + && ssl_cipher_get_handshake_digest_nid(c) == want + && !ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED)) + return 1; + } + return 0; +} + +/* + * Mirrors the ticket-resumption gating checks in tls_construct_ctos_psk() so + * that early_data is only advertised when the resumption PSK will actually + * be sent. + */ +static int tls13_check_resumption_psk(SSL_CONNECTION *s, const EVP_MD *handmd) +{ + SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + const EVP_MD *mdres; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + + if (s->session == NULL + || s->session->ssl_version != version1_3 + || s->session->ext.ticklen == 0 + || s->session->cipher == NULL) + return 0; + + mdres = ssl_md(sctx, s->session->cipher->algorithm2); + if (mdres == NULL) + return 0; + if (s->hello_retry_request == SSL_HRR_PENDING && mdres != handmd) + return 0; + /* An offered TLS 1.3 ciphersuite must carry the ticket's digest. */ + if (!tls13_digest_offered(s, s->session->cipher)) + return 0; + if (tls13_check_tick_lifetime_hint(s) == 0) + return 0; + + return 1; +} + +/* + * 0-RTT early data is protected with the PSK's own cipher, and per RFC 9846 + * section 4.3.10 the server accepts it only if it negotiates that exact + * cipher. So if we are not even offering that cipher on this handshake, 0-RTT + * cannot be accepted and early data must be suppressed -- the client-side + * mirror of the server's cipher-commitment check. The PSK is still offered for + * 1-RTT resumption, which needs only a digest-compatible cipher. + */ +static int tls13_early_cipher_offered(SSL_CONNECTION *s, const SSL_SESSION *sess) +{ + const SSL_CIPHER *c = sess->cipher; + + /* + * SSL_SECOP_CIPHER_SUPPORTED matches the ssl_cipher_list_to_bytes() + * ciphersuite filter. + */ + return c != NULL + && !ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED) + && sk_SSL_CIPHER_find(ssl_get_ciphers_by_id(s), c) >= 0; +} + +/* + * 0-RTT is bound to the session's ALPN protocol, and the server accepts + * it only if it negotiates that protocol. So early data is viable only if that + * protocol is among the ones we offer -- we cannot know which the server will + * pick, so being present in our list is enough. A session with no ALPN imposes + * no constraint; a session with one while we offer none cannot match. ALPN + * affects 0-RTT only: resumption itself permits an ALPN change after the + * transition. + */ +static int tls13_early_alpn_offered(SSL_CONNECTION *s, const SSL_SESSION *sess) +{ + PACKET prots, alpnpkt; + + if (sess->ext.alpn_selected == NULL) + return 1; + if (s->ext.alpn == NULL + || !PACKET_buf_init(&prots, s->ext.alpn, s->ext.alpn_len)) + return 0; + while (PACKET_get_length_prefixed_1(&prots, &alpnpkt)) { + if (PACKET_equal(&alpnpkt, sess->ext.alpn_selected, + sess->ext.alpn_selected_len)) + return 1; + } + return 0; +} + EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) @@ -1045,6 +1221,9 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, SSL_SESSION *edsess = NULL; const EVP_MD *handmd = NULL; SSL *ussl = SSL_CONNECTION_GET_USER_SSL(s); + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + + s->ext.tick_age_checked = 0; #ifndef OPENSSL_NO_ECH /* @@ -1073,13 +1252,22 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, } } #endif + + /* + * Reset the early-secret-derived marker here, past the ECH outer-CH no-op + * above, so the outer pass preserves the value the inner pass's binder set + * (the outer CH derives no early secret of its own). + */ + s->ext.early_secret_derived = 0; + if (s->hello_retry_request == SSL_HRR_PENDING) handmd = ssl_handshake_md(s); if (s->psk_use_session_cb != NULL && (!s->psk_use_session_cb(ussl, handmd, &id, &idlen, &psksess) || (psksess != NULL - && psksess->ssl_version != TLS1_3_VERSION))) { + && (psksess->ssl_version != version1_3 + || psksess->master_key_length == 0)))) { SSL_SESSION_free(psksess); SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_PSK); return EXT_RETURN_FAIL; @@ -1111,7 +1299,7 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, /* * We found a PSK using an old style callback. We don't know - * the digest so we default to SHA256 as per the TLSv1.3 spec + * the digest so we default to SHA256 as per the (D)TLSv1.3 spec */ cipher = SSL_CIPHER_find(SSL_CONNECTION_GET_SSL(s), tls13_aes128gcmsha256_id); @@ -1121,10 +1309,11 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, } psksess = SSL_SESSION_new(); + if (psksess == NULL || !SSL_SESSION_set1_master_key(psksess, psk, psklen) || !SSL_SESSION_set_cipher(psksess, cipher) - || !SSL_SESSION_set_protocol_version(psksess, TLS1_3_VERSION)) { + || !SSL_SESSION_set_protocol_version(psksess, version1_3)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); OPENSSL_cleanse(psk, psklen); return EXT_RETURN_FAIL; @@ -1134,6 +1323,17 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, } #endif /* OPENSSL_NO_PSK */ + /* + * If no offered ciphersuite carries the callback PSK's digest -- or its + * cipher isn't a TLS 1.3 cipher -- it can never be used, so drop it here and + * proceed as if the callback had returned no PSK. Every later s->psksession + * check then handles it for free. + */ + if (psksess != NULL && !tls13_digest_offered(s, psksess->cipher)) { + SSL_SESSION_free(psksess); + psksess = NULL; + } + SSL_SESSION_free(s->psksession); s->psksession = psksess; if (psksess != NULL) { @@ -1147,14 +1347,68 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, s->psksession_id_len = idlen; } + /* + * Suppress early_data unless a PSK is available and will be sent. + * + * RFC 9846 4.3.10: When a PSK is used and early data is allowed for that + * PSK, the client can send Application Data in its first flight of + * messages. If the client opts to do so, it MUST supply both the + * "pre_shared_key" and "early_data" extensions. + * + * The PSK used to encrypt the early data MUST be the first PSK listed in + * the client's "pre_shared_key" extension. + */ + /* + * The first PSK identity we offer is the only one that can key 0-RTT: the + * resumption session when we are offering it, else the external psksession. + * Offer early_data only when that first PSK is itself 0-RTT-capable; never + * key it off a PSK offered later. + */ + /* + * Freeze the resumption-ticket offer decision here, at the first consumer, + * so tls_construct_ctos_psk() offers the very same identity 0 and its binder + * derives s->early_secret for whatever session early_data is keyed on. See + * s->ext.psk_resumption_offered. + */ + s->ext.psk_resumption_offered = tls13_check_resumption_psk(s, handmd); + edsess = s->ext.psk_resumption_offered ? s->session : psksess; if (s->early_data_state != SSL_EARLY_DATA_CONNECTING - || (s->session->ext.max_early_data == 0 - && (psksess == NULL || psksess->ext.max_early_data == 0))) { + || edsess == NULL + || edsess->ext.max_early_data == 0 + || !tls13_early_cipher_offered(s, edsess) + || !tls13_early_alpn_offered(s, edsess)) { s->max_early_data = 0; + if (s->early_data_state == SSL_EARLY_DATA_CONNECTING) { + s->ext.early_data_suppressed = 1; + /* + * We report REJECTED rather than NOT_SENT, so that suppressing + * 0-RTT locally looks to the application just like a server that + * declined it. + * + * The early exporter is a separate question: no early secret is + * derived on this path, so s->ext.early_exporter_ready stays clear + * and SSL_export_keying_material_early() remains unavailable. + */ + s->ext.early_data = SSL_EARLY_DATA_REJECTED; + } + s->early_data_state = SSL_EARLY_DATA_NONE; return EXT_RETURN_NOT_SENT; } - edsess = s->session->ext.max_early_data != 0 ? s->session : psksess; s->max_early_data = edsess->ext.max_early_data; + /* + * Record the first-offered PSK so the binder, the early-key derivation, the + * early exporter, the byte-budget lookup and the post-ServerHello fixup all + * key off it rather than guessing the source from + * s->session->ext.max_early_data. Held (up-ref'd) so it stays valid across + * the swap that later folds a selected psksession into s->session. + */ + SSL_SESSION_free(s->ext.early_data_session); + s->ext.early_data_session = edsess; + if (!SSL_SESSION_up_ref(edsess)) { + s->ext.early_data_session = NULL; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return EXT_RETURN_FAIL; + } if (edsess->ext.hostname != NULL) { if (s->ext.hostname == NULL @@ -1166,37 +1420,6 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, } } - if ((s->ext.alpn == NULL && edsess->ext.alpn_selected != NULL)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_INCONSISTENT_EARLY_DATA_ALPN); - return EXT_RETURN_FAIL; - } - - /* - * Verify that we are offering an ALPN protocol consistent with the early - * data. - */ - if (edsess->ext.alpn_selected != NULL) { - PACKET prots, alpnpkt; - int found = 0; - - if (!PACKET_buf_init(&prots, s->ext.alpn, s->ext.alpn_len)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - while (PACKET_get_length_prefixed_1(&prots, &alpnpkt)) { - if (PACKET_equal(&alpnpkt, edsess->ext.alpn_selected, - edsess->ext.alpn_selected_len)) { - found = 1; - break; - } - } - if (!found) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, - SSL_R_INCONSISTENT_EARLY_DATA_ALPN); - return EXT_RETURN_FAIL; - } - } - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_early_data) || !WPACKET_start_sub_packet_u16(pkt) || !WPACKET_close(pkt)) { @@ -1214,97 +1437,6 @@ EXT_RETURN tls_construct_ctos_early_data(SSL_CONNECTION *s, WPACKET *pkt, return EXT_RETURN_SENT; } -#define F5_WORKAROUND_MIN_MSG_LEN 0xff -#define F5_WORKAROUND_MAX_MSG_LEN 0x200 - -/* - * PSK pre binder overhead = - * 2 bytes for TLSEXT_TYPE_psk - * 2 bytes for extension length - * 2 bytes for identities list length - * 2 bytes for identity length - * 4 bytes for obfuscated_ticket_age - * 2 bytes for binder list length - * 1 byte for binder length - * The above excludes the number of bytes for the identity itself and the - * subsequent binder bytes - */ -#define PSK_PRE_BINDER_OVERHEAD (2 + 2 + 2 + 2 + 4 + 2 + 1) - -EXT_RETURN tls_construct_ctos_padding(SSL_CONNECTION *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx) -{ - unsigned char *padbytes; - size_t hlen; - - if ((s->options & SSL_OP_TLSEXT_PADDING) == 0) - return EXT_RETURN_NOT_SENT; -#ifndef OPENSSL_NO_ECH - ECH_SAME_EXT(s, context, pkt); -#endif - - /* - * Add padding to workaround bugs in F5 terminators. See RFC7685. - * This code calculates the length of all extensions added so far but - * excludes the PSK extension (because that MUST be written last). Therefore - * this extension MUST always appear second to last. - */ - if (!WPACKET_get_total_written(pkt, &hlen)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - - /* - * If we're going to send a PSK then that will be written out after this - * extension, so we need to calculate how long it is going to be. - */ - if (s->session->ssl_version == TLS1_3_VERSION - && s->session->ext.ticklen != 0 - && s->session->cipher != NULL) { - const EVP_MD *md = ssl_md(SSL_CONNECTION_GET_CTX(s), - s->session->cipher->algorithm2); - - if (md != NULL) { - /* - * Add the fixed PSK overhead, the identity length and the binder - * length. - */ - int md_size = EVP_MD_get_size(md); - - if (md_size <= 0) - return EXT_RETURN_FAIL; - hlen += PSK_PRE_BINDER_OVERHEAD + s->session->ext.ticklen - + md_size; - } - } - - if (hlen > F5_WORKAROUND_MIN_MSG_LEN && hlen < F5_WORKAROUND_MAX_MSG_LEN) { - /* Calculate the amount of padding we need to add */ - hlen = F5_WORKAROUND_MAX_MSG_LEN - hlen; - - /* - * Take off the size of extension header itself (2 bytes for type and - * 2 bytes for length bytes), but ensure that the extension is at least - * 1 byte long so as not to have an empty extension last (WebSphere 7.x, - * 8.x are intolerant of that condition) - */ - if (hlen > 4) - hlen -= 4; - else - hlen = 1; - - if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_padding) - || !WPACKET_sub_allocate_bytes_u16(pkt, hlen, &padbytes)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_FAIL; - } - memset(padbytes, 0, hlen); - } - - return EXT_RETURN_SENT; -} - /* * Construct the pre_shared_key extension */ @@ -1312,32 +1444,40 @@ EXT_RETURN tls_construct_ctos_psk(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { -#ifndef OPENSSL_NO_TLS1_3 - uint32_t agesec, agems = 0; +#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3)) + uint32_t agems = 0; size_t binderoffset, msglen; int reshashsize = 0, pskhashsize = 0; unsigned char *resbinder = NULL, *pskbinder = NULL, *msgstart = NULL; const EVP_MD *handmd = NULL, *mdres = NULL, *mdpsk = NULL; int dores = 0; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); - OSSL_TIME t; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; s->ext.tick_identity = 0; - /* - * Note: At this stage of the code we only support adding a single - * resumption PSK. If we add support for multiple PSKs then the length - * calculations in the padding extension will need to be adjusted. - */ - /* * If this is an incompatible or new session then we have nothing to resume * so don't add this extension. */ - if (s->session->ssl_version != TLS1_3_VERSION + if (s->session->ssl_version != version1_3 || (s->session->ext.ticklen == 0 && s->psksession == NULL)) return EXT_RETURN_NOT_SENT; + /* + * After a HelloRetryRequest, do not introduce a pre_shared_key extension + * that the first ClientHello (CH1) did not carry. RFC 9846 4.2.2 lets CH2 + * update or drop PSKs, but not add one -- let alone add the whole + * extension. This could otherwise happen if a psk_use_session callback + * only yields a digest-compatible PSK once the retry has settled the + * ciphersuite. While a misbehaving callback could still introduce a + * novel PSK only after HRR, that's an application bug, expected rare and + * likely harmless if it occurs. + */ + if (s->hello_retry_request == SSL_HRR_PENDING + && (s->ext.extflags[TLSEXT_IDX_psk] & SSL_EXT_FLAG_SENT) == 0) + return EXT_RETURN_NOT_SENT; + if (s->hello_retry_request == SSL_HRR_PENDING) handmd = ssl_handshake_md(s); @@ -1378,45 +1518,18 @@ EXT_RETURN tls_construct_ctos_psk(SSL_CONNECTION *s, WPACKET *pkt, #endif /* - * Technically the C standard just says time() returns a time_t and says - * nothing about the encoding of that type. In practice most - * implementations follow POSIX which holds it as an integral type in - * seconds since epoch. We've already made the assumption that we can do - * this in multiple places in the code, so portability shouldn't be an - * issue. - */ - t = ossl_time_subtract(ossl_time_now(), s->session->time); - agesec = (uint32_t)ossl_time2seconds(t); - - /* - * We calculate the age in seconds but the server may work in ms. Due to - * rounding errors we could overestimate the age by up to 1s. It is - * better to underestimate it. Otherwise, if the RTT is very short, when - * the server calculates the age reported by the client it could be - * bigger than the age calculated on the server - which should never - * happen. + * Consume the offer decision frozen by tls_construct_ctos_early_data() + * rather than re-running the SECOP-dependent tls13_digest_offered() a + * second time: an answer that flipped between the two calls would drop + * the ticket after early_data was already committed, leaving + * s->early_secret underived and 0-RTT keyed off a zero secret. */ - if (agesec > 0) - agesec--; - - if (s->session->ext.tick_lifetime_hint < agesec) { - /* Ticket is too old. Ignore it. */ + if (!s->ext.psk_resumption_offered) goto dopsksess; - } - - /* - * Calculate age in ms. We're just doing it to nearest second. Should be - * good enough. - */ - agems = agesec * (uint32_t)1000; - - if (agesec != 0 && agems / (uint32_t)1000 != agesec) { - /* - * Overflow. Shouldn't happen unless this is a *really* old session. - * If so we just ignore it. - */ + if (tls13_check_tick_lifetime_hint(s) == 0) goto dopsksess; - } + /* tls13_check_tick_lifetime_hint() updates the tick_age_ms value. */ + agems = s->ext.tick_age_ms; /* * Obfuscate the age. Overflow here is fine, this addition is supposed @@ -1581,10 +1694,7 @@ EXT_RETURN tls_construct_ctos_psk(SSL_CONNECTION *s, WPACKET *pkt, msgstart = WPACKET_get_curr(pkt) - msglen; - if (dores - && tls_psk_do_binder(s, mdres, msgstart, binderoffset, NULL, - resbinder, s->session, 1, 0) - != 1) { + if (dores && tls_psk_do_binder(s, mdres, msgstart, binderoffset, NULL, resbinder, s->session, 1, 0) != 1) { /* SSLfatal() already called */ return EXT_RETURN_FAIL; } @@ -1608,7 +1718,7 @@ EXT_RETURN tls_construct_ctos_post_handshake_auth(SSL_CONNECTION *s, WPACKET *pk ossl_unused X509 *x, ossl_unused size_t chainidx) { -#ifndef OPENSSL_NO_TLS1_3 +#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3)) if (!s->pha_enabled) return EXT_RETURN_NOT_SENT; #ifndef OPENSSL_NO_ECH @@ -1800,18 +1910,18 @@ int tls_parse_stoc_status_request(SSL_CONNECTION *s, PACKET *pkt, /* * MUST only be sent if we've requested a status - * request message. In TLS <= 1.2 it must also be empty. + * request message. In (D)TLS <= 1.2 it must also be empty. */ if (s->ext.status_type != TLSEXT_STATUSTYPE_ocsp) { SSLfatal(s, SSL_AD_UNSUPPORTED_EXTENSION, SSL_R_BAD_EXTENSION); return 0; } - if (!SSL_CONNECTION_IS_TLS13(s) && PACKET_remaining(pkt) > 0) { + if (!SSL_CONNECTION_IS_VERSION13(s) && PACKET_remaining(pkt) > 0) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_BAD_EXTENSION); return 0; } - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { /* SSLfatal() already called */ return tls_process_cert_status_body(s, chainidx, pkt); } @@ -2076,7 +2186,7 @@ int tls_parse_stoc_use_srtp(SSL_CONNECTION *s, PACKET *pkt, /* Throw an error if the server gave us an unsolicited extension */ clnt = SSL_get_srtp_profiles(SSL_CONNECTION_GET_SSL(s)); if (clnt == NULL) { - SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_NO_SRTP_PROFILES); + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_NO_SRTP_PROFILES); return 0; } @@ -2093,7 +2203,7 @@ int tls_parse_stoc_use_srtp(SSL_CONNECTION *s, PACKET *pkt, } } - SSLfatal(s, SSL_AD_DECODE_ERROR, + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); return 0; } @@ -2132,6 +2242,7 @@ int tls_parse_stoc_supported_versions(SSL_CONNECTION *s, PACKET *pkt, X509 *x, size_t chainidx) { unsigned int version; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (!PACKET_get_net_2(pkt, &version) || PACKET_remaining(pkt) != 0) { @@ -2141,9 +2252,9 @@ int tls_parse_stoc_supported_versions(SSL_CONNECTION *s, PACKET *pkt, /* * The only protocol version we support which is valid in this extension in - * a ServerHello is TLSv1.3 therefore we shouldn't be getting anything else. + * a ServerHello is (D)TLSv1.3 therefore we shouldn't be getting anything else. */ - if (version != TLS1_3_VERSION) { + if ((int)version != version1_3) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_PROTOCOL_VERSION_NUMBER); return 0; @@ -2167,7 +2278,7 @@ int tls_parse_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { -#ifndef OPENSSL_NO_TLS1_3 +#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3)) unsigned int group_id; PACKET encoded_pt; EVP_PKEY *ckey = s->s3.tmp.pkey, *skey = NULL; @@ -2196,6 +2307,8 @@ int tls_parse_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt, if ((context & SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST) != 0) { const uint16_t *pgroups = NULL; size_t num_groups; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION + : TLS1_3_VERSION; if (PACKET_remaining(pkt) != 0) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); @@ -2219,10 +2332,10 @@ int tls_parse_stoc_key_share(SSL_CONNECTION *s, PACKET *pkt, if (group_id == pgroups[i]) break; } + if (i >= num_groups || !tls_group_allowed(s, group_id, SSL_SECOP_CURVE_SUPPORTED) - || !tls_valid_group(s, group_id, TLS1_3_VERSION, TLS1_3_VERSION, - NULL, NULL)) { + || !tls_valid_group(s, group_id, version1_3, version1_3, NULL, NULL)) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_KEY_SHARE); return 0; } @@ -2414,7 +2527,8 @@ int tls_parse_stoc_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { -#ifndef OPENSSL_NO_TLS1_3 +#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3)) + SSL_SESSION *sesstmp; unsigned int identity; if (!PACKET_get_net_2(pkt, &identity) || PACKET_remaining(pkt) != 0) { @@ -2452,10 +2566,28 @@ int tls_parse_stoc_psk(SSL_CONNECTION *s, PACKET *pkt, */ if ((s->early_data_state != SSL_EARLY_DATA_WRITE_RETRY && s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING) - || s->session->ext.max_early_data > 0 - || s->psksession->ext.max_early_data == 0) + || s->ext.early_data_session != s->psksession) memcpy(s->early_secret, s->psksession->early_secret, EVP_MAX_MD_SIZE); + /* + * The psk_use_session_cb()/psk_client_callback() may reuse + * the session across connections we can't mutate it directly. + */ + if ((sesstmp = ssl_session_dup(s->psksession, 0)) == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return 0; + } + SSL_SESSION_free(s->psksession); + s->psksession = sesstmp; + + /* + * s->psksession (now our private copy) was built by the callback, not via + * ssl_get_new_session(), so it was never stamped with our own sid_ctx. Do + * so now, to avoid rejection of the PSK session in tls_process_server_hello(). + */ + memcpy(s->psksession->sid_ctx, s->sid_ctx, s->sid_ctx_length); + s->psksession->sid_ctx_length = s->sid_ctx_length; + SSL_SESSION_free(s->session); s->session = s->psksession; s->psksession = NULL; @@ -2617,7 +2749,7 @@ EXT_RETURN tls_construct_ctos_ech(SSL_CONNECTION *s, WPACKET *pkt, s->ext.ech.attempted_type = TLSEXT_TYPE_ech; if (ossl_ech_send_grease(s, pkt) != 1) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return EXT_RETURN_NOT_SENT; + return EXT_RETURN_FAIL; } return EXT_RETURN_SENT; } diff --git a/ssl/statem/extensions_cust.c b/ssl/statem/extensions_cust.c index 71fb169c31673..b1a369847e701 100644 --- a/ssl/statem/extensions_cust.c +++ b/ssl/statem/extensions_cust.c @@ -626,7 +626,6 @@ int SSL_extension_supported(unsigned int ext_type) #ifndef OPENSSL_NO_NEXTPROTONEG case TLSEXT_TYPE_next_proto_neg: #endif - case TLSEXT_TYPE_padding: case TLSEXT_TYPE_renegotiate: case TLSEXT_TYPE_max_fragment_length: case TLSEXT_TYPE_server_name: diff --git a/ssl/statem/extensions_srvr.c b/ssl/statem/extensions_srvr.c index 12c06eef9b54d..ad652861d873b 100644 --- a/ssl/statem/extensions_srvr.c +++ b/ssl/statem/extensions_srvr.c @@ -40,8 +40,8 @@ * + 2 bytes for extension block length + 6 bytes for key_share extension * + 4 bytes for cookie extension header + the number of bytes in the cookie */ -#define MAX_HRR_SIZE (SSL3_HM_HEADER_LENGTH + 2 + SSL3_RANDOM_SIZE + 1 \ - + SSL_MAX_SSL_SESSION_ID_LENGTH + 2 + 1 + 2 + 6 + 4 \ +#define MAX_HRR_SIZE (DTLS1_HM_HEADER_LENGTH + 2 + SSL3_RANDOM_SIZE + 1 \ + + SSL_MAX_SSL_SESSION_ID_LENGTH + 2 + 1 + 2 + 6 + 4 \ + MAX_COOKIE_SIZE) /* @@ -142,10 +142,10 @@ int tls_parse_ctos_server_name(SSL_CONNECTION *s, PACKET *pkt, } /* - * In TLSv1.2 and below the SNI is associated with the session. In TLSv1.3 + * In (D)TLSv1.2 and below the SNI is associated with the session. In (D)TLSv1.3 * we always use the SNI value from the handshake. */ - if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) { + if (!s->hit || SSL_CONNECTION_IS_VERSION13(s)) { if (PACKET_remaining(&hostname) > TLSEXT_MAXLEN_host_name) { SSLfatal(s, SSL_AD_UNRECOGNIZED_NAME, SSL_R_BAD_EXTENSION); return 0; @@ -170,9 +170,9 @@ int tls_parse_ctos_server_name(SSL_CONNECTION *s, PACKET *pkt, s->servername_done = 1; } else { /* - * In TLSv1.2 and below we should check if the SNI is consistent between - * the initial handshake and the resumption. In TLSv1.3 SNI is not - * associated with the session. + * In (D)TLSv1.2 and below we should check if the SNI is consistent + * between the initial handshake and the resumption. In (D)TLSv1.3 SNI + * is not associated with the session. */ s->servername_done = (s->session->ext.hostname != NULL) && PACKET_equal(&hostname, s->session->ext.hostname, @@ -562,7 +562,7 @@ int tls_parse_ctos_psk_kex_modes(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { -#ifndef OPENSSL_NO_TLS1_3 +#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3)) PACKET psk_kex_modes; unsigned int mode; @@ -605,7 +605,7 @@ int tls_parse_ctos_psk_kex_modes(SSL_CONNECTION *s, PACKET *pkt, * received in the ClientHello and to select the group used of the key exchange */ -#ifndef OPENSSL_NO_TLS1_3 +#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3)) /* * Accept a key share group by setting the related variables in s->s3 and * by generating a pubkey for this group @@ -702,7 +702,7 @@ static KS_EXTRACTION_RESULT extract_keyshares(SSL_CONNECTION *s, PACKET *key_sha /* * Check if this share is in supported_groups sent from client - * RFC 8446 also mandates that clients send keyshares in the same + * RFC 9846 also mandates that clients send keyshares in the same * order as listed in the supported groups extension, but its not * required that the server check that, and some clients violate this * so instead of failing the connection when that occurs, log a trace @@ -714,7 +714,7 @@ static KS_EXTRACTION_RESULT extract_keyshares(SSL_CONNECTION *s, PACKET *key_sha } if (key_share_pos < previous_key_share_pos) - OSSL_TRACE1(TLS, "key share group id %d is out of RFC 8446 order\n", group_id); + OSSL_TRACE1(TLS, "key share group id %d is out of RFC 9846 order\n", group_id); previous_key_share_pos = key_share_pos; @@ -764,7 +764,7 @@ static KS_EXTRACTION_RESULT extract_keyshares(SSL_CONNECTION *s, PACKET *key_sha * assign to selected_group and also set the related index in the candidate group list, * or set selected_group to 0 if no overlap */ -#ifndef OPENSSL_NO_TLS1_3 +#if !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_DTLS1_3) static void check_overlap(SSL_CONNECTION *s, const uint16_t *prio_groups, size_t prio_num_groups, const uint16_t *candidate_groups, size_t candidate_num_groups, @@ -774,6 +774,7 @@ static void check_overlap(SSL_CONNECTION *s, uint16_t current_group; size_t group_idx = prio_num_groups; size_t new_group_idx = 0; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; *candidate_group_idx = 0; *prio_group_idx = 0; @@ -784,8 +785,8 @@ static void check_overlap(SSL_CONNECTION *s, prio_num_groups, 1, &new_group_idx) || !tls_group_allowed(s, candidate_groups[current_group], SSL_SECOP_CURVE_SUPPORTED) - || !tls_valid_group(s, candidate_groups[current_group], TLS1_3_VERSION, - TLS1_3_VERSION, NULL, NULL)) + || !tls_valid_group(s, candidate_groups[current_group], version1_3, + version1_3, NULL, NULL)) /* No overlap or group not suitable, check next group */ continue; @@ -806,7 +807,7 @@ static void check_overlap(SSL_CONNECTION *s, int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { -#ifndef OPENSSL_NO_TLS1_3 +#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3)) PACKET key_share_list; const uint16_t *clntgroups, *srvrgroups; const size_t *srvrtuples; @@ -825,10 +826,14 @@ int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt, if (s->hit && (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE_DHE) == 0) return 1; - /* Sanity check */ + /* + * If prior Client Hello in HRR set the peer_temp clear it out to process + * the key share in the second client hello + */ if (s->s3.peer_tmp != NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - return 0; + EVP_PKEY_free(s->s3.peer_tmp); + s->s3.peer_tmp = NULL; + s->s3.group_id = 0; } if (!PACKET_as_length_prefixed_2(pkt, &key_share_list)) { @@ -984,7 +989,7 @@ int tls_parse_ctos_key_share(SSL_CONNECTION *s, PACKET *pkt, int tls_parse_ctos_cookie(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { -#ifndef OPENSSL_NO_TLS1_3 +#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3)) unsigned int format, version, key_share, group_id; EVP_MD_CTX *hctx; EVP_PKEY *pkey; @@ -997,10 +1002,25 @@ int tls_parse_ctos_cookie(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, uint64_t tm, now; SSL *ssl = SSL_CONNECTION_GET_SSL(s); SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + const int version1_2 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_2_VERSION : TLS1_2_VERSION; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + size_t msgbody_offs = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_HM_HEADER_LENGTH + - SSL3_HM_HEADER_LENGTH + : 0; + int verify_ret = 0; + +#if !defined(OPENSSL_NO_DTLS) + DTLS_LISTENER *dl = (s->d1 != NULL && s->d1->listener != NULL) + ? (DTLS_LISTENER *)s->d1->listener + : NULL; + int have_verify_cb = (sctx->verify_stateless_cookie_cb != NULL) + || (dl != NULL && dl->require_hrr_cookie); +#else + int have_verify_cb = (sctx->verify_stateless_cookie_cb != NULL); +#endif /* Ignore any cookie if we're not set up to verify it */ - if (sctx->verify_stateless_cookie_cb == NULL - || (s->s3.flags & TLS1_FLAGS_STATELESS) == 0) + if (!have_verify_cb || (s->s3.flags & TLS1_FLAGS_STATELESS) == 0) return 1; if (!PACKET_as_length_prefixed_2(pkt, &cookie)) { @@ -1071,7 +1091,7 @@ int tls_parse_ctos_cookie(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); return 0; } - if (version != TLS1_3_VERSION) { + if ((int)version != version1_3) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_PROTOCOL_VERSION_NUMBER); return 0; @@ -1115,10 +1135,21 @@ int tls_parse_ctos_cookie(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, } /* Verify the app cookie */ - if (sctx->verify_stateless_cookie_cb(SSL_CONNECTION_GET_USER_SSL(s), +#if !defined(OPENSSL_NO_DTLS) + if (dl != NULL && dl->require_hrr_cookie && sctx->verify_stateless_cookie_cb == NULL) { + verify_ret = ossl_dtls_listener_verify_stateless_cookie_cb( + SSL_CONNECTION_GET_USER_SSL(s), PACKET_data(&appcookie), - PACKET_remaining(&appcookie)) - == 0) { + PACKET_remaining(&appcookie)); + } else +#endif + if (sctx->verify_stateless_cookie_cb != NULL) { + verify_ret = sctx->verify_stateless_cookie_cb(SSL_CONNECTION_GET_USER_SSL(s), + PACKET_data(&appcookie), + PACKET_remaining(&appcookie)); + } + + if (verify_ret == 0) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_COOKIE_MISMATCH); return 0; } @@ -1133,8 +1164,15 @@ int tls_parse_ctos_cookie(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, return 0; } if (!WPACKET_put_bytes_u8(&hrrpkt, SSL3_MT_SERVER_HELLO) - || !WPACKET_start_sub_packet_u24(&hrrpkt) - || !WPACKET_put_bytes_u16(&hrrpkt, TLS1_2_VERSION) + || !WPACKET_start_sub_packet_u24_at_offset(&hrrpkt, msgbody_offs) + /* + * We are reconstructing the HRR to be able to calculate the + * transcript hash. + * Since HRR is only allowed for (D)TLSv1.3 and transcript hash does + * not include the values of message_seq, fragment_offset and + * fragment_length, setting these values is not required. + */ + || !WPACKET_put_bytes_u16(&hrrpkt, version1_2) || !WPACKET_memcpy(&hrrpkt, hrrrandom, SSL3_RANDOM_SIZE) || !WPACKET_sub_memcpy_u8(&hrrpkt, s->tmp_session_id, s->tmp_session_id_len) @@ -1208,7 +1246,7 @@ int tls_parse_ctos_supported_groups(SSL_CONNECTION *s, PACKET *pkt, return 0; } - if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) { + if (!s->hit || SSL_CONNECTION_IS_VERSION13(s)) { OPENSSL_free(s->ext.peer_supportedgroups); s->ext.peer_supportedgroups = NULL; s->ext.peer_supportedgroups_len = 0; @@ -1367,10 +1405,12 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, } else if (pskdatalen > 0) { const SSL_CIPHER *cipher; const unsigned char tls13_aes128gcmsha256_id[] = { 0x13, 0x01 }; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION + : TLS1_3_VERSION; /* * We found a PSK using an old style callback. We don't know - * the digest so we default to SHA256 as per the TLSv1.3 spec + * the digest so we default to SHA256 as per the (D)TLSv1.3 spec */ cipher = SSL_CIPHER_find(SSL_CONNECTION_GET_SSL(s), tls13_aes128gcmsha256_id); @@ -1381,12 +1421,12 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, } sess = SSL_SESSION_new(); + if (sess == NULL || !SSL_SESSION_set1_master_key(sess, pskdata, pskdatalen) || !SSL_SESSION_set_cipher(sess, cipher) - || !SSL_SESSION_set_protocol_version(sess, - TLS1_3_VERSION)) { + || !SSL_SESSION_set_protocol_version(sess, version1_3)) { OPENSSL_cleanse(pskdata, pskdatalen); SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; @@ -1397,7 +1437,10 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, #endif /* OPENSSL_NO_PSK */ if (sess != NULL) { - /* We found a PSK */ + /* + * We found an external (not a resumption) PSK - duplicate the + * session, set the session id to our own, and mark it as external. + */ SSL_SESSION *sesstmp = ssl_session_dup(sess, 0); if (sesstmp == NULL) { @@ -1413,7 +1456,7 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, */ memcpy(sess->sid_ctx, s->sid_ctx, s->sid_ctx_length); sess->sid_ctx_length = s->sid_ctx_length; - ext = 1; + sess->psk_external = ext = 1; if (id == 0) s->ext.early_data_ok = 1; s->ext.ticket_expected = 1; @@ -1484,6 +1527,8 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, */ s->ext.early_data_ok = 1; } + /* This PSK is not external, use the correct binder label, ... */ + ext = 0; } md = ssl_md(sctx, sess->cipher->algorithm2); @@ -1506,6 +1551,13 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, s->ext.ticket_expected = 1; continue; } + /* + * Same-hash ciphersuite changes are allowed for TLSv1.3 PSK + * resumption, but RFC 9846 Section 4.3.10 requires the selected + * ciphersuite to match the selected PSK before accepting early data. + */ + if (sess->cipher->id != s->s3.tmp.new_cipher->id) + s->ext.early_data_ok = 0; break; } @@ -1520,7 +1572,7 @@ int tls_parse_ctos_psk(SSL_CONNECTION *s, PACKET *pkt, unsigned int context, } /* * decrypt_error here to keep the alert the same as if the binder - * failed. See RFC8446 Appendix E.6. Note we make no attempt to do this + * failed. See RFC9846 Appendix F.6. Note we make no attempt to do this * in constant time compared to verifying the binder. None of this code * is constant time anyway. */ @@ -1617,10 +1669,10 @@ EXT_RETURN tls_construct_stoc_server_name(SSL_CONNECTION *s, WPACKET *pkt, return EXT_RETURN_NOT_SENT; /* - * Prior to TLSv1.3 we ignore any SNI in the current handshake if resuming. + * Prior to (D)TLSv1.3 we ignore any SNI in the current handshake if resuming. * We just use the servername from the initial handshake. */ - if (s->hit && !SSL_CONNECTION_IS_TLS13(s)) + if (s->hit && !SSL_CONNECTION_IS_VERSION13(s)) return EXT_RETURN_NOT_SENT; if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_server_name) @@ -1760,7 +1812,15 @@ EXT_RETURN tls_construct_stoc_session_ticket(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { - if (!s->ext.ticket_expected || !tls_use_ticket(s)) { + /* + * Don't tell the client to expect a NewSessionTicket when any + * ticket we'd mint would be rejected by ssl_get_prev_session() + * whenever SSL_VERIFY_PEER is set with no sid_ctx configured (see + * the checks there). In TLS 1.2, once promised the ticket MUST + * be sent. + */ + if (!s->ext.ticket_expected || !tls_use_ticket(s) + || ((s->verify_mode & SSL_VERIFY_PEER) != 0 && s->sid_ctx_length == 0)) { s->ext.ticket_expected = 0; return EXT_RETURN_NOT_SENT; } @@ -1802,11 +1862,11 @@ EXT_RETURN tls_construct_stoc_status_request(SSL_CONNECTION *s, WPACKET *pkt, } /* - * In TLSv1.3 we include the certificate status itself. In <= TLSv1.2 we + * In (D)TLSv1.3 we include the certificate status itself. In <= (D)TLSv1.2 we * send back an empty extension, with the certificate status appearing as a * separate message */ - if (SSL_CONNECTION_IS_TLS13(s) + if (SSL_CONNECTION_IS_VERSION13(s) && !tls_construct_cert_status_body(s, resp, pkt)) { /* SSLfatal() already called */ return EXT_RETURN_FAIL; @@ -1944,7 +2004,7 @@ EXT_RETURN tls_construct_stoc_supported_versions(SSL_CONNECTION *s, WPACKET *pkt unsigned int context, X509 *x, size_t chainidx) { - if (!ossl_assert(SSL_CONNECTION_IS_TLS13(s))) { + if (!ossl_assert(SSL_CONNECTION_IS_VERSION13(s))) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; } @@ -1964,7 +2024,7 @@ EXT_RETURN tls_construct_stoc_key_share(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { -#ifndef OPENSSL_NO_TLS1_3 +#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3)) unsigned char *encoded_pubkey; size_t encoded_pubkey_len = 0; EVP_PKEY *ckey = s->s3.peer_tmp, *skey = NULL; @@ -2094,6 +2154,7 @@ EXT_RETURN tls_construct_stoc_key_share(SSL_CONNECTION *s, WPACKET *pkt, s->s3.did_kex = 1; return EXT_RETURN_SENT; #else + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; #endif } @@ -2102,21 +2163,33 @@ EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx) { -#ifndef OPENSSL_NO_TLS1_3 +#if !(defined(OPENSSL_NO_TLS1_3) && defined(OPENSSL_NO_DTLS1_3)) unsigned char *hashval1, *hashval2, *appcookie1, *appcookie2, *cookie; unsigned char *hmac, *hmac2; - size_t startlen, ciphlen, totcookielen, hashlen, hmaclen, appcookielen; + size_t startlen, ciphlen, totcookielen, hashlen, hmaclen; + size_t appcookielen = 0; EVP_MD_CTX *hctx; EVP_PKEY *pkey; int ret = EXT_RETURN_FAIL; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); SSL *ssl = SSL_CONNECTION_GET_SSL(s); SSL *ussl = SSL_CONNECTION_GET_USER_SSL(s); + const int version = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + int gen_ret = 0; +#if !defined(OPENSSL_NO_DTLS) + DTLS_LISTENER *dl = (s->d1 != NULL && s->d1->listener != NULL) + ? (DTLS_LISTENER *)s->d1->listener + : NULL; + int have_gen_cb = (sctx->gen_stateless_cookie_cb != NULL) + || (dl != NULL && dl->require_hrr_cookie); +#else + int have_gen_cb = (sctx->gen_stateless_cookie_cb != NULL); +#endif if ((s->s3.flags & TLS1_FLAGS_STATELESS) == 0) return EXT_RETURN_NOT_SENT; - if (sctx->gen_stateless_cookie_cb == NULL) { + if (!have_gen_cb) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_NO_COOKIE_CALLBACK_SET); return EXT_RETURN_FAIL; } @@ -2127,7 +2200,7 @@ EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt, || !WPACKET_get_total_written(pkt, &startlen) || !WPACKET_reserve_bytes(pkt, MAX_COOKIE_SIZE, &cookie) || !WPACKET_put_bytes_u16(pkt, COOKIE_STATE_FORMAT_VERSION) - || !WPACKET_put_bytes_u16(pkt, TLS1_3_VERSION) + || !WPACKET_put_bytes_u16(pkt, version) || !WPACKET_put_bytes_u16(pkt, s->s3.group_id) || !ssl->method->put_cipher_by_char(s->s3.tmp.new_cipher, pkt, &ciphlen) @@ -2161,9 +2234,17 @@ EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt, } /* Generate the application cookie */ - if (sctx->gen_stateless_cookie_cb(ussl, appcookie1, - &appcookielen) - == 0) { +#if !defined(OPENSSL_NO_DTLS) + if (dl != NULL && dl->require_hrr_cookie && sctx->gen_stateless_cookie_cb == NULL) { + gen_ret = ossl_dtls_listener_gen_stateless_cookie_cb(ussl, appcookie1, + &appcookielen); + } else +#endif + if (sctx->gen_stateless_cookie_cb != NULL) { + gen_ret = sctx->gen_stateless_cookie_cb(ussl, appcookie1, &appcookielen); + } + + if (gen_ret == 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_COOKIE_GEN_CALLBACK_FAILURE); return EXT_RETURN_FAIL; } @@ -2226,6 +2307,7 @@ EXT_RETURN tls_construct_stoc_cookie(SSL_CONNECTION *s, WPACKET *pkt, EVP_PKEY_free(pkey); return ret; #else + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return EXT_RETURN_FAIL; #endif } @@ -2327,7 +2409,7 @@ EXT_RETURN tls_construct_stoc_client_cert_type(SSL_CONNECTION *sc, WPACKET *pkt, /* * Note: only supposed to send this if we are going to do a cert request, - * but TLSv1.3 could do a PHA request if the client supports it + * but (D)TLSv1.3 could do a PHA request if the client supports it */ if ((!send_certificate_request(sc) && sc->post_handshake_auth != SSL_PHA_EXT_RECEIVED) || sc->ext.client_cert_type_ctos != OSSL_CERT_TYPE_CTOS_GOOD diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c index 04887bc9d1e28..b8a31857bf012 100644 --- a/ssl/statem/statem.c +++ b/ssl/statem/statem.c @@ -134,6 +134,7 @@ void ossl_statem_clear(SSL_CONNECTION *s) s->statem.error_state = ERROR_STATE_NOERROR; ossl_statem_set_in_init(s, 1); s->statem.no_cert_verify = 0; + s->statem.ack_for_retransmit = 0; } /* @@ -245,6 +246,20 @@ int ossl_statem_skip_early_data(SSL_CONNECTION *s) */ int ossl_statem_check_finish_init(SSL_CONNECTION *s, int sending) { + /* + * A client that suppressed 0-RTT keeps SSL_write_early_data() reporting + * success while the application streams early data. Any ordinary read, + * write, or handshake call waits for the handshake to complete and so ends + * that sequence: clear the suppressed flag, after which a further + * SSL_write_early_data() returns the normal error instead of masking a + * state-machine mistake. The internal SSL_connect() issued from + * SSL_write_early_data() runs in the CONNECTING state and is excluded. + */ + if (!s->server + && s->ext.early_data_suppressed + && s->early_data_state == SSL_EARLY_DATA_NONE) + s->ext.early_data_suppressed = 0; + if (sending == -1) { if (s->statem.hand_state == TLS_ST_PENDING_EARLY_DATA_END || s->statem.hand_state == TLS_ST_EARLY_DATA) { @@ -404,7 +419,7 @@ static int state_machine(SSL_CONNECTION *s, int server) s->server = server; if (cb != NULL) { - if (SSL_IS_FIRST_HANDSHAKE(s) || !SSL_CONNECTION_IS_TLS13(s)) + if (SSL_IS_FIRST_HANDSHAKE(s) || !SSL_CONNECTION_IS_VERSION13(s)) cb(ussl, SSL_CB_HANDSHAKE_START, 1); } @@ -484,6 +499,8 @@ static int state_machine(SSL_CONNECTION *s, int server) if (ssret == SUB_STATE_FINISHED) { st->state = MSG_FLOW_WRITING; init_write_state_machine(s); + } else if (ssret == SUB_STATE_END_HANDSHAKE) { + st->state = MSG_FLOW_FINISHED; } else { /* NBIO or error */ goto end; @@ -604,6 +621,16 @@ static SUB_STATE_RETURN read_state_machine(SSL_CONNECTION *s) while (1) { switch (st->read_state) { case READ_STATE_HEADER: + /* + * Restore the state after an incomplete ACK before reading again: + * the DTLS record layer uses it to handle application data. + */ + if (SSL_CONNECTION_IS_DTLS13(s) + && (st->hand_state == TLS_ST_CR_ACK + || st->hand_state == TLS_ST_SR_ACK) + && !transition(s, SSL3_MT_DUMMY)) + return SUB_STATE_ERROR; + /* Get the state the peer wants to move to */ if (SSL_CONNECTION_IS_DTLS(s)) { /* @@ -615,6 +642,28 @@ static SUB_STATE_RETURN read_state_machine(SSL_CONNECTION *s) } if (ret == 0) { + /* Re-ACK a retransmission without completing our own flight. */ + if (st->ack_for_retransmit) + return SUB_STATE_FINISHED; + + /* + * If we're in DTLSv1.3 and in state TLS_ST_OK, then we must + * have received a post-handshake message. If we subsequently + * try to receive that message and get nothing back (and did not + * encounter a fatal error), then that message must have been + * dropped, so we need to end the handshake now, and return to + * reading app data. + */ + if (SSL_CONNECTION_IS_DTLS13(s) + && st->hand_state == TLS_ST_OK + && s->statem.state != MSG_FLOW_ERROR) { + if (!ssl_free_wbio_buffer(s)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return SUB_STATE_ERROR; + } + ossl_statem_set_in_init(s, 0); + return SUB_STATE_END_HANDSHAKE; + } /* Could be non-blocking IO */ return SUB_STATE_ERROR; } @@ -739,17 +788,28 @@ static SUB_STATE_RETURN read_state_machine(SSL_CONNECTION *s) */ static int statem_do_write(SSL_CONNECTION *s) { + int record_type; OSSL_STATEM *st = &s->statem; - if (st->hand_state == TLS_ST_CW_CHANGE - || st->hand_state == TLS_ST_SW_CHANGE) { - if (SSL_CONNECTION_IS_DTLS(s)) - return dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC); - else - return ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC); - } else { + switch (st->hand_state) { + case TLS_ST_CW_CHANGE: + case TLS_ST_SW_CHANGE: + record_type = SSL3_RT_CHANGE_CIPHER_SPEC; + + break; + case TLS_ST_CW_ACK: + case TLS_ST_SW_ACK: + record_type = SSL3_RT_ACK; + + break; + default: return ssl_do_write(s); } + + if (SSL_CONNECTION_IS_DTLS(s)) + return dtls1_do_write(s, record_type); + else + return ssl3_do_write(s, record_type); } /* @@ -804,6 +864,7 @@ static SUB_STATE_RETURN write_state_machine(SSL_CONNECTION *s) CON_FUNC_RETURN (**confunc)(SSL_CONNECTION *s, WPACKET *pkt), int *mt); + int (*dtls_use_timer)(SSL_CONNECTION *s); void (*cb)(const SSL *ssl, int type, int val) = NULL; CON_FUNC_RETURN (*confunc)(SSL_CONNECTION *s, WPACKET *pkt); int mt; @@ -817,11 +878,13 @@ static SUB_STATE_RETURN write_state_machine(SSL_CONNECTION *s) pre_work = ossl_statem_server_pre_work; post_work = ossl_statem_server_post_work; get_construct_message_f = ossl_statem_server_construct_message; + dtls_use_timer = ossl_statem_dtls_server_use_timer; } else { transition = ossl_statem_client_write_transition; pre_work = ossl_statem_client_pre_work; post_work = ossl_statem_client_post_work; get_construct_message_f = ossl_statem_client_construct_message; + dtls_use_timer = ossl_statem_dtls_client_use_timer; } while (1) { @@ -914,9 +977,9 @@ static SUB_STATE_RETURN write_state_machine(SSL_CONNECTION *s) /* Fall through */ case WRITE_STATE_SEND: - if (SSL_CONNECTION_IS_DTLS(s) && st->use_timer) { + if (SSL_CONNECTION_IS_DTLS(s) && dtls_use_timer(s)) dtls1_start_timer(s); - } + ret = statem_do_write(s); if (ret <= 0) { return SUB_STATE_ERROR; @@ -1022,11 +1085,5 @@ int ossl_statem_export_allowed(SSL_CONNECTION *s) */ int ossl_statem_export_early_allowed(SSL_CONNECTION *s) { - /* - * The early exporter secret is only present on the server if we - * have accepted early_data. It is present on the client as long - * as we have sent early_data. - */ - return s->ext.early_data == SSL_EARLY_DATA_ACCEPTED - || (!s->server && s->ext.early_data != SSL_EARLY_DATA_NOT_SENT); + return s->ext.early_exporter_ready; } diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 15ed8ef8d53bb..6f1ba3cfe2dfd 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -95,6 +95,12 @@ static int ossl_statem_client13_read_transition(SSL_CONNECTION *s, int mt) { OSSL_STATEM *st = &s->statem; + if (st->hand_state == TLS_ST_CR_ACK) { + st->hand_state = st->pre_ack_hand_state; + if (mt == SSL3_MT_DUMMY) + return 1; + } + /* * Note: There is no case for TLS_ST_CW_CLNT_HELLO, because we haven't * yet negotiated TLSv1.3 at that point so that is handled by @@ -177,7 +183,14 @@ static int ossl_statem_client13_read_transition(SSL_CONNECTION *s, int mt) } break; + case TLS_ST_CW_KEY_UPDATE: + case TLS_ST_CW_FINISHED: case TLS_ST_OK: + if (mt == DTLS13_MT_ACK) { + st->pre_ack_hand_state = st->hand_state; + st->hand_state = TLS_ST_CR_ACK; + return 1; + } if (mt == SSL3_MT_NEWSESSION_TICKET) { st->hand_state = TLS_ST_CR_SESSION_TICKET; return 1; @@ -187,19 +200,8 @@ static int ossl_statem_client13_read_transition(SSL_CONNECTION *s, int mt) return 1; } if (mt == SSL3_MT_CERTIFICATE_REQUEST) { -#if DTLS_MAX_VERSION_INTERNAL != DTLS1_2_VERSION - /* Restore digest for PHA before adding message.*/ -#error Internal DTLS version error -#endif - if (!SSL_CONNECTION_IS_DTLS(s) - && s->post_handshake_auth == SSL_PHA_EXT_SENT) { + if (s->post_handshake_auth == SSL_PHA_EXT_SENT) { s->post_handshake_auth = SSL_PHA_REQUESTED; - /* - * In TLS, this is called before the message is added to the - * digest. In DTLS, this is expected to be called after adding - * to the digest. Either move the digest restore, or add the - * message here after the swap, or do it after the clientFinished? - */ if (!tls13_restore_handshake_digest_for_pha(s)) { /* SSLfatal() already called */ return 0; @@ -233,7 +235,7 @@ int ossl_statem_client_read_transition(SSL_CONNECTION *s, int mt) * Note that after writing the first ClientHello we don't know what version * we are going to negotiate yet, so we don't take this branch until later. */ - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { if (!ossl_statem_client13_read_transition(s, mt)) goto err; return 1; @@ -423,6 +425,12 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL_CONNECTION *s) { OSSL_STATEM *st = &s->statem; + if (st->ack_for_retransmit && st->hand_state != TLS_ST_CW_ACK) { + st->deferred_ack_state = st->hand_state; + st->hand_state = TLS_ST_CW_ACK; + return WRITE_TRAN_CONTINUE; + } + /* * Note: There are no cases for TLS_ST_BEFORE because we haven't negotiated * TLSv1.3 yet at that point. They are handled by @@ -458,7 +466,7 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL_CONNECTION *s) if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY || s->early_data_state == SSL_EARLY_DATA_FINISHED_WRITING) st->hand_state = TLS_ST_PENDING_EARLY_DATA_END; - else if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0 + else if (SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s) && s->hello_retry_request == SSL_HRR_NONE) st->hand_state = TLS_ST_CW_CHANGE; else if (s->s3.tmp.cert_req == 0) @@ -472,6 +480,10 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL_CONNECTION *s) return WRITE_TRAN_CONTINUE; case TLS_ST_PENDING_EARLY_DATA_END: + /* + * RFC 9147 Section 5.6 states DTLS1.3 should omit the + * End of Early Data Message + */ if (s->ext.early_data == SSL_EARLY_DATA_ACCEPTED && !SSL_NO_EOED(s)) { st->hand_state = TLS_ST_CW_END_OF_EARLY_DATA; return WRITE_TRAN_CONTINUE; @@ -479,6 +491,12 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL_CONNECTION *s) /* Fall through */ case TLS_ST_CW_END_OF_EARLY_DATA: + if (SSL_CONNECTION_IS_DTLS13(s)) { + /* If we are done with early data we need to clean up Epoch 1 messages sent */ + dtls1_clear_sent_buffer(s, 0); + } + /* Fall through */ + case TLS_ST_CW_CHANGE: if (s->s3.tmp.cert_req == 0) st->hand_state = TLS_ST_CW_FINISHED; @@ -500,9 +518,36 @@ static WRITE_TRAN ossl_statem_client13_write_transition(SSL_CONNECTION *s) return WRITE_TRAN_CONTINUE; case TLS_ST_CR_KEY_UPDATE: - case TLS_ST_CW_KEY_UPDATE: case TLS_ST_CR_SESSION_TICKET: + if (SSL_CONNECTION_IS_DTLS13(s)) { + st->hand_state = TLS_ST_CW_ACK; + return WRITE_TRAN_CONTINUE; + } + /* Fall-through */ + case TLS_ST_CW_KEY_UPDATE: case TLS_ST_CW_FINISHED: + if (SSL_CONNECTION_IS_DTLS13(s)) + /* We wait for ACK */ + return WRITE_TRAN_FINISHED; + else + st->hand_state = TLS_ST_OK; + return WRITE_TRAN_CONTINUE; + + case TLS_ST_CR_ACK: + if (SSL_CONNECTION_IS_DTLS13(s) + && dtls_any_sent_messages_are_missing_acknowledge(s)) { + /* We wait for ACK */ + return WRITE_TRAN_FINISHED; + } + st->hand_state = TLS_ST_OK; + return WRITE_TRAN_CONTINUE; + + case TLS_ST_CW_ACK: + if (st->ack_for_retransmit) { + st->hand_state = st->deferred_ack_state; + st->ack_for_retransmit = 0; + return WRITE_TRAN_FINISHED; + } st->hand_state = TLS_ST_OK; return WRITE_TRAN_CONTINUE; @@ -530,7 +575,7 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL_CONNECTION *s) * version we are going to negotiate yet, so we don't take this branch until * later */ - if (SSL_CONNECTION_IS_TLS13(s)) + if (SSL_CONNECTION_IS_VERSION13(s)) return ossl_statem_client13_write_transition(s); switch (st->hand_state) { @@ -557,10 +602,10 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL_CONNECTION *s) if (s->early_data_state == SSL_EARLY_DATA_CONNECTING && !SSL_IS_QUIC_HANDSHAKE(s)) { /* - * We are assuming this is a TLSv1.3 connection, although we haven't + * We are assuming this is a (D)TLSv1.3 connection, although we haven't * actually selected a version yet. */ - if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0) + if (SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s)) st->hand_state = TLS_ST_CW_CHANGE; else st->hand_state = TLS_ST_EARLY_DATA; @@ -575,11 +620,11 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL_CONNECTION *s) case TLS_ST_CR_SRVR_HELLO: /* - * We only get here in TLSv1.3. We just received an HRR, so issue a + * We only get here in (D)TLSv1.3. We just received an HRR, so issue a * CCS unless middlebox compat mode is off, or we already issued one * because we did early data. */ - if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0 + if (SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s) && s->early_data_state != SSL_EARLY_DATA_FINISHED_WRITING) st->hand_state = TLS_ST_CW_CHANGE; else @@ -689,6 +734,48 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL_CONNECTION *s) } } +static int ossl_statem_dtls_client13_use_timer(SSL_CONNECTION *s) +{ + OSSL_STATEM *st = &s->statem; + + switch (st->hand_state) { + default: + break; + + case TLS_ST_CW_ACK: + /* Fall through */ + + case TLS_ST_OK: + return 0; + } + + return 1; +} + +int ossl_statem_dtls_client_use_timer(SSL_CONNECTION *s) +{ + OSSL_STATEM *st = &s->statem; + + if (SSL_CONNECTION_IS_DTLS13(s)) + return ossl_statem_dtls_client13_use_timer(s); + + switch (st->hand_state) { + default: + break; + + case TLS_ST_CW_CHANGE: + /* + * We're into the last flight so we don't retransmit these + * messages unless we need to. + */ + if (s->hit) + st->use_timer = 0; + break; + } + + return st->use_timer; +} + /* * Perform any pre work that needs to be done prior to sending a message from * the client to the server. @@ -696,6 +783,7 @@ WRITE_TRAN ossl_statem_client_write_transition(SSL_CONNECTION *s) WORK_STATE ossl_statem_client_pre_work(SSL_CONNECTION *s, WORK_STATE wst) { OSSL_STATEM *st = &s->statem; + const int versionany = SSL_CONNECTION_IS_DTLS(s) ? DTLS_ANY_VERSION : TLS_ANY_VERSION; switch (st->hand_state) { default: @@ -704,7 +792,7 @@ WORK_STATE ossl_statem_client_pre_work(SSL_CONNECTION *s, WORK_STATE wst) case TLS_ST_CW_CLNT_HELLO: s->shutdown = 0; - if (SSL_CONNECTION_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s) && s->hello_retry_request != SSL_HRR_PENDING) { /* every DTLS ClientHello resets Finished MAC */ if (!ssl3_init_finished_mac(s)) { /* SSLfatal() already called */ @@ -718,12 +806,12 @@ WORK_STATE ossl_statem_client_pre_work(SSL_CONNECTION *s, WORK_STATE wst) * write record layer in order to write in plaintext again. */ if (!ssl_set_new_record_layer(s, - TLS_ANY_VERSION, + versionany, OSSL_RECORD_DIRECTION_WRITE, OSSL_RECORD_PROTECTION_LEVEL_NONE, - NULL, 0, NULL, 0, NULL, 0, NULL, 0, - NULL, 0, NID_undef, NULL, NULL, - NULL)) { + NULL, 0, NULL, NULL, 0, NULL, 0, + NULL, 0, NULL, NULL, 0, NID_undef, + NULL, NULL, NULL)) { /* SSLfatal already called */ return WORK_ERROR; } @@ -732,13 +820,6 @@ WORK_STATE ossl_statem_client_pre_work(SSL_CONNECTION *s, WORK_STATE wst) case TLS_ST_CW_CHANGE: if (SSL_CONNECTION_IS_DTLS(s)) { - if (s->hit) { - /* - * We're into the last flight so we don't retransmit these - * messages unless we need to. - */ - st->use_timer = 0; - } #ifndef OPENSSL_NO_SCTP if (BIO_dgram_is_sctp(SSL_get_wbio(SSL_CONNECTION_GET_SSL(s)))) { /* Calls SSLfatal() as required */ @@ -790,11 +871,11 @@ WORK_STATE ossl_statem_client_post_work(SSL_CONNECTION *s, WORK_STATE wst) if (s->early_data_state == SSL_EARLY_DATA_CONNECTING && s->max_early_data > 0) { /* - * We haven't selected TLSv1.3 yet so we don't call the change + * We haven't selected (D)TLSv1.3 yet so we don't call the change * cipher state function associated with the SSL_METHOD. Instead * we call tls13_change_cipher_state() directly. */ - if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) == 0) { + if (!SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s)) { if (!tls13_change_cipher_state(s, SSL3_CC_EARLY | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { /* SSLfatal() already called */ @@ -820,13 +901,13 @@ WORK_STATE ossl_statem_client_post_work(SSL_CONNECTION *s, WORK_STATE wst) break; case TLS_ST_CW_CHANGE: - if (SSL_CONNECTION_IS_TLS13(s) + if (SSL_CONNECTION_IS_VERSION13(s) || s->hello_retry_request == SSL_HRR_PENDING) break; if (s->early_data_state == SSL_EARLY_DATA_CONNECTING && s->max_early_data > 0) { /* - * We haven't selected TLSv1.3 yet so we don't call the change + * We haven't selected (D)TLSv1.3 yet so we don't call the change * cipher state function associated with the SSL_METHOD. Instead * we call tls13_change_cipher_state() directly. */ @@ -848,7 +929,6 @@ WORK_STATE ossl_statem_client_post_work(SSL_CONNECTION *s, WORK_STATE wst) /* SSLfatal() already called */ return WORK_ERROR; } - if (!ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { /* SSLfatal() already called */ @@ -881,7 +961,7 @@ WORK_STATE ossl_statem_client_post_work(SSL_CONNECTION *s, WORK_STATE wst) if (statem_flush(s) != 1) return WORK_MORE_B; - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { if (!tls13_save_handshake_digest_for_pha(s)) { /* SSLfatal() already called */ return WORK_ERROR; @@ -892,6 +972,7 @@ WORK_STATE ossl_statem_client_post_work(SSL_CONNECTION *s, WORK_STATE wst) /* SSLfatal() already called */ return WORK_ERROR; } + /* * For QUIC we deferred setting up these keys until now so * that we can ensure write keys are always set up before read @@ -915,6 +996,11 @@ WORK_STATE ossl_statem_client_post_work(SSL_CONNECTION *s, WORK_STATE wst) return WORK_ERROR; } break; + + case TLS_ST_CW_ACK: + if (statem_flush(s) != 1) + return WORK_MORE_A; + break; } return WORK_FINISHED_CONTINUE; @@ -999,6 +1085,11 @@ int ossl_statem_client_construct_message(SSL_CONNECTION *s, *confunc = tls_construct_key_update; *mt = SSL3_MT_KEY_UPDATE; break; + + case TLS_ST_CW_ACK: + *confunc = dtls_construct_ack; + *mt = DTLS13_MT_ACK; + break; } return 1; @@ -1053,8 +1144,8 @@ size_t ossl_statem_client_max_message_size(SSL_CONNECTION *s) return CCS_MAX_LENGTH; case TLS_ST_CR_SESSION_TICKET: - return (SSL_CONNECTION_IS_TLS13(s)) ? SESSION_TICKET_MAX_LENGTH_TLS13 - : SESSION_TICKET_MAX_LENGTH_TLS12; + return SSL_CONNECTION_IS_VERSION13(s) ? SESSION_TICKET_MAX_LENGTH_TLS13 + : SESSION_TICKET_MAX_LENGTH_TLS12; case TLS_ST_CR_FINISHED: return FINISHED_MAX_LENGTH; @@ -1064,6 +1155,9 @@ size_t ossl_statem_client_max_message_size(SSL_CONNECTION *s) case TLS_ST_CR_KEY_UPDATE: return KEY_UPDATE_MAX_LENGTH; + + case TLS_ST_CR_ACK: + return ACK_MAX_LENGTH; } } @@ -1127,6 +1221,9 @@ MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL_CONNECTION *s, case TLS_ST_CR_KEY_UPDATE: return tls_process_key_update(s, pkt); + + case TLS_ST_CR_ACK: + return dtls_process_ack(s, pkt); } } @@ -1385,7 +1482,8 @@ __owur CON_FUNC_RETURN tls_construct_client_hello(SSL_CONNECTION *s, WPACKET *pk { unsigned char *p; size_t sess_id_len; - int i, protverr; + int do_fill_random, protverr; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; #ifndef OPENSSL_NO_COMP SSL_COMP *comp; #endif @@ -1427,20 +1525,20 @@ __owur CON_FUNC_RETURN tls_construct_client_hello(SSL_CONNECTION *s, WPACKET *pk * for DTLS if client_random is initialized, reuse it, we are * required to use same upon reply to HelloVerify */ - if (SSL_CONNECTION_IS_DTLS(s)) { + if (SSL_CONNECTION_IS_DTLS(s) && s->hello_retry_request == SSL_HRR_NONE) { size_t idx; - i = 1; + do_fill_random = 1; for (idx = 0; idx < sizeof(s->s3.client_random); idx++) { if (p[idx]) { - i = 0; + do_fill_random = 0; break; } } } else { - i = (s->hello_retry_request == SSL_HRR_NONE); + do_fill_random = (s->hello_retry_request == SSL_HRR_NONE); } - if (i && ssl_fill_hello_random(s, 0, p, sizeof(s->s3.client_random), DOWNGRADE_NONE) <= 0) { + if (do_fill_random && ssl_fill_hello_random(s, 0, p, sizeof(s->s3.client_random), DOWNGRADE_NONE) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return CON_FUNC_ERROR; } @@ -1499,7 +1597,7 @@ __owur CON_FUNC_RETURN tls_construct_client_hello(SSL_CONNECTION *s, WPACKET *pk sess_id_len = 0; } else { #endif - if (s->new_session || s->session->ssl_version == TLS1_3_VERSION) { + if (s->new_session || s->session->ssl_version == version1_3) { if (s->version == TLS1_3_VERSION && (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0) { sess_id_len = sizeof(s->tmp_session_id); @@ -1518,7 +1616,7 @@ __owur CON_FUNC_RETURN tls_construct_client_hello(SSL_CONNECTION *s, WPACKET *pk } else { assert(s->session->session_id_length <= sizeof(s->session->session_id)); sess_id_len = s->session->session_id_length; - if (s->version == TLS1_3_VERSION) { + if (s->version == version1_3) { s->tmp_session_id_len = sess_id_len; memcpy(s->tmp_session_id, s->session->session_id, sess_id_len); } @@ -1568,9 +1666,10 @@ __owur CON_FUNC_RETURN tls_construct_client_hello(SSL_CONNECTION *s, WPACKET *pk #ifndef OPENSSL_NO_COMP if (ssl_allow_compression(s) && sctx->comp_methods - && (SSL_CONNECTION_IS_DTLS(s) - || s->s3.tmp.max_ver < TLS1_3_VERSION)) { + && ssl_version_cmp(s, s->s3.tmp.max_ver, version1_3) < 0) { + int i; int compnum = sk_SSL_COMP_num(sctx->comp_methods); + for (i = 0; i < compnum; i++) { comp = sk_SSL_COMP_value(sctx->comp_methods, i); if (!WPACKET_put_bytes_u8(pkt, comp->id)) { @@ -1599,6 +1698,8 @@ MSG_PROCESS_RETURN dtls_process_hello_verify(SSL_CONNECTION *s, PACKET *pkt) { size_t cookie_len; PACKET cookiepkt; + int min_version; + SSL *ssl = SSL_CONNECTION_GET_SSL(s); if (!PACKET_forward(pkt, 2) || !PACKET_get_length_prefixed_1(pkt, &cookiepkt)) { @@ -1618,6 +1719,25 @@ MSG_PROCESS_RETURN dtls_process_hello_verify(SSL_CONNECTION *s, PACKET *pkt) } s->d1->cookie_len = cookie_len; + if (ssl == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return MSG_PROCESS_ERROR; + } + + min_version = SSL_get_min_proto_version(ssl); + + /* + * Server responds with a HelloVerify which means we cannot negotiate a + * higher version than DTLSv1.2. + */ + if (min_version != 0 + && ssl_version_cmp(s, min_version, DTLS1_2_VERSION) > 0) { + SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_UNSUPPORTED_PROTOCOL); + return MSG_PROCESS_ERROR; + } + + s->d1->hello_verify_request = SSL_HVR_RECEIVED; + return MSG_PROCESS_FINISHED_READING; } @@ -1652,7 +1772,7 @@ static int set_client_ciphersuite(SSL_CONNECTION *s, return 0; } - if (SSL_CONNECTION_IS_TLS13(s) && s->s3.tmp.new_cipher != NULL + if (SSL_CONNECTION_IS_VERSION13(s) && s->s3.tmp.new_cipher != NULL && s->s3.tmp.new_cipher->id != c->id) { /* ServerHello selected a different ciphersuite to that in the HRR */ SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CIPHER_RETURNED); @@ -1667,7 +1787,7 @@ static int set_client_ciphersuite(SSL_CONNECTION *s, if (s->session->cipher != NULL) s->session->cipher_id = s->session->cipher->id; if (s->hit && (s->session->cipher_id != c->id)) { - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { const EVP_MD *md = ssl_md(sctx, c->algorithm2); if (!ossl_assert(s->session->cipher != NULL)) { @@ -1709,6 +1829,9 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt) unsigned int sversion; unsigned int context; RAW_EXTENSION *extensions = NULL; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + const unsigned int version1_2 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_2_VERSION + : TLS1_2_VERSION; SSL *ssl = SSL_CONNECTION_GET_SSL(s); SSL *ussl = SSL_CONNECTION_GET_USER_SSL(s); #ifndef OPENSSL_NO_COMP @@ -1739,8 +1862,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt) } /* load the server random */ - if (s->version == TLS1_3_VERSION - && sversion == TLS1_2_VERSION + if (s->version == version1_3 && sversion == version1_2 && PACKET_remaining(pkt) >= SSL3_RANDOM_SIZE && memcmp(hrrrandom, PACKET_data(pkt), SSL3_RANDOM_SIZE) == 0) { if (s->hello_retry_request != SSL_HRR_NONE) { @@ -1799,6 +1921,8 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt) if (hrr) { if (!tls_collect_extensions(s, &extpkt, SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST, &extensions, NULL, 1) + || !tls_validate_no_unknown_extensions(s, &extpkt, + SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST) || !tls_parse_extension(s, TLSEXT_IDX_ech, SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST, extensions, NULL, 0)) { @@ -1919,19 +2043,26 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt) } } - if (SSL_CONNECTION_IS_TLS13(s) || hrr) { + if (SSL_CONNECTION_IS_VERSION13(s) || hrr) { if (compression != 0) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_INVALID_COMPRESSION_ALGORITHM); goto err; } - if (session_id_len != s->tmp_session_id_len - || memcmp(PACKET_data(&session_id), s->tmp_session_id, - session_id_len) - != 0) { - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_INVALID_SESSION_ID); - goto err; + if (SSL_CONNECTION_IS_DTLS(s)) { + if (session_id_len != 0) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_INVALID_SESSION_ID); + goto err; + } + } else { + if (session_id_len != s->tmp_session_id_len + || memcmp(PACKET_data(&session_id), s->tmp_session_id, + session_id_len) + != 0) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_INVALID_SESSION_ID); + goto err; + } } } @@ -1953,16 +2084,20 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt) * Now we have chosen the version we need to check again that the extensions * are appropriate for this version. */ - context = SSL_CONNECTION_IS_TLS13(s) ? SSL_EXT_TLS1_3_SERVER_HELLO - : SSL_EXT_TLS1_2_SERVER_HELLO; + context = SSL_CONNECTION_IS_VERSION13(s) ? SSL_EXT_TLS1_3_SERVER_HELLO + : SSL_EXT_TLS1_2_SERVER_HELLO; if (!tls_validate_all_contexts(s, context, extensions)) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_EXTENSION); goto err; } + if (SSL_CONNECTION_IS_TLS13(s) + && !tls_validate_no_unknown_extensions(s, &extpkt, context)) + /* SSLfatal() already called */ + goto err; s->hit = 0; - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { /* * In TLSv1.3 a ServerHello message signals a key change so the end of * the message must be on a record boundary. @@ -2055,7 +2190,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt) * echo of what we originally sent in the ClientHello and should not be * used for resumption. */ - if (!SSL_CONNECTION_IS_TLS13(s)) { + if (!SSL_CONNECTION_IS_VERSION13(s)) { s->session->session_id_length = session_id_len; /* session_id_len could be 0 */ if (session_id_len > 0) @@ -2127,7 +2262,12 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt) } #ifndef OPENSSL_NO_SCTP - if (SSL_CONNECTION_IS_DTLS(s) && s->hit) { + /* + * Before exporting the SCTP auth key we check if DTLSv1.3 has been negotiated + * which is not supported. + * Refer to draft-tuexen-tsvwg-rfc6083-bis-04 for more info. + */ + if (SSL_CONNECTION_IS_DTLS(s) && !SSL_CONNECTION_IS_DTLS13(s) && s->hit) { unsigned char sctpauthkey[64]; char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; size_t labellen; @@ -2163,7 +2303,7 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt) * In TLSv1.3 we have some post-processing to change cipher state, otherwise * we're done with this message */ - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { if (!ssl->method->ssl3_enc->setup_key_block(s) || !tls13_store_handshake_traffic_hash(s)) { /* SSLfatal() already called */ @@ -2180,17 +2320,21 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt) */ if (SSL_IS_QUIC_HANDSHAKE(s) || (s->early_data_state == SSL_EARLY_DATA_NONE - && (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) == 0)) { + && !SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s))) { if (!ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE)) { /* SSLfatal() already called */ goto err; } } - if (!ssl->method->ssl3_enc->change_cipher_state(s, + + if (!SSL_CONNECTION_IS_DTLS13(s) + && !ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_READ)) { /* SSLfatal() already called */ goto err; + } else { + s->dtls13_process_hello = 1; } } @@ -2204,22 +2348,31 @@ MSG_PROCESS_RETURN tls_process_server_hello(SSL_CONNECTION *s, PACKET *pkt) static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL_CONNECTION *s, RAW_EXTENSION *extensions) { + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + const int versionany = SSL_CONNECTION_IS_DTLS(s) ? DTLS_ANY_VERSION : TLS_ANY_VERSION; + const size_t msghdrlen = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_HM_HEADER_LENGTH + : SSL3_HM_HEADER_LENGTH; + /* * If we were sending early_data then any alerts should not be sent using * the old wrlmethod. */ if (s->early_data_state == SSL_EARLY_DATA_FINISHED_WRITING - && !ssl_set_new_record_layer(s, - TLS_ANY_VERSION, + && !ssl_set_new_record_layer(s, versionany, OSSL_RECORD_DIRECTION_WRITE, OSSL_RECORD_PROTECTION_LEVEL_NONE, - NULL, 0, NULL, 0, NULL, 0, NULL, 0, - NULL, 0, NID_undef, NULL, NULL, NULL)) { + NULL, 0, NULL, NULL, 0, NULL, 0, NULL, + 0, NULL, NULL, 0, NID_undef, NULL, + NULL, NULL)) { /* SSLfatal already called */ goto err; } - /* We are definitely going to be using TLSv1.3 */ - s->rlayer.wrlmethod->set_protocol_version(s->rlayer.wrl, TLS1_3_VERSION); + + /* We are definitely going to be using (D)TLSv1.3 */ + if (!s->rlayer.wrlmethod->set_protocol_version(s->rlayer.wrl, version1_3)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } if (!tls_parse_all_extensions(s, SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST, extensions, NULL, 0, 1)) { @@ -2252,7 +2405,7 @@ static MSG_PROCESS_RETURN tls_process_as_hello_retry_request(SSL_CONNECTION *s, * for HRR messages. */ if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, - s->init_num + SSL3_HM_HEADER_LENGTH)) { + s->init_num + msghdrlen)) { /* SSLfatal() already called */ goto err; } @@ -2323,7 +2476,7 @@ static WORK_STATE tls_post_process_server_rpk(SSL_CONNECTION *sc, * skip check since TLS 1.3 ciphersuites can be used with any certificate * type. */ - if (!SSL_CONNECTION_IS_TLS13(sc)) { + if (!SSL_CONNECTION_IS_VERSION13(sc)) { if ((clu->amask & sc->s3.tmp.new_cipher->algorithm_auth) == 0) { SSLfatal(sc, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_RPK_TYPE); return WORK_ERROR; @@ -2338,7 +2491,7 @@ static WORK_STATE tls_post_process_server_rpk(SSL_CONNECTION *sc, sc->session->verify_result = sc->verify_result; /* Save the current hash state for when we receive the CertificateVerify */ - if (SSL_CONNECTION_IS_TLS13(sc) + if (SSL_CONNECTION_IS_VERSION13(sc) && !ssl_handshake_hash(sc, sc->cert_verify_hash, sizeof(sc->cert_verify_hash), &sc->cert_verify_hash_len)) { @@ -2373,7 +2526,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL_CONNECTION *s, goto err; } - if ((SSL_CONNECTION_IS_TLS13(s) && !PACKET_get_1(pkt, &context)) + if ((SSL_CONNECTION_IS_VERSION13(s) && !PACKET_get_1(pkt, &context)) || context != 0 || !PACKET_get_net_3(pkt, &cert_list_len) || PACKET_remaining(pkt) != cert_list_len @@ -2406,7 +2559,7 @@ MSG_PROCESS_RETURN tls_process_server_certificate(SSL_CONNECTION *s, goto err; } - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { RAW_EXTENSION *rawexts = NULL; PACKET extensions; @@ -2513,7 +2666,7 @@ WORK_STATE tls_post_process_server_certificate(SSL_CONNECTION *s, * skip check since TLS 1.3 ciphersuites can be used with any certificate * type. */ - if (!SSL_CONNECTION_IS_TLS13(s)) { + if (!SSL_CONNECTION_IS_VERSION13(s)) { if ((clu->amask & s->s3.tmp.new_cipher->algorithm_auth) == 0) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CERTIFICATE_TYPE); return WORK_ERROR; @@ -2533,7 +2686,7 @@ WORK_STATE tls_post_process_server_certificate(SSL_CONNECTION *s, s->session->peer_rpk = NULL; /* Save the current hash state for when we receive the CertificateVerify */ - if (SSL_CONNECTION_IS_TLS13(s) + if (SSL_CONNECTION_IS_VERSION13(s) && !ssl_handshake_hash(s, s->cert_verify_hash, sizeof(s->cert_verify_hash), &s->cert_verify_hash_len)) { @@ -2971,7 +3124,7 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL_CONNECTION *s, return MSG_PROCESS_ERROR; } - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { PACKET reqctx, extensions; RAW_EXTENSION *rawexts = NULL; @@ -3075,7 +3228,7 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL_CONNECTION *s, * SSL_get1_peer_certificate() returns something sensible in * client_cert_cb. */ - if (SSL_CONNECTION_IS_TLS13(s) + if (SSL_CONNECTION_IS_VERSION13(s) && s->post_handshake_auth != SSL_PHA_REQUESTED) return MSG_PROCESS_CONTINUE_READING; @@ -3095,13 +3248,13 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL_CONNECTION *s, PACKET_null_init(&nonce); if (!PACKET_get_net_4(pkt, &ticket_lifetime_hint) - || (SSL_CONNECTION_IS_TLS13(s) + || (SSL_CONNECTION_IS_VERSION13(s) && (!PACKET_get_net_4(pkt, &age_add) || !PACKET_get_length_prefixed_1(pkt, &nonce))) || !PACKET_get_net_2(pkt, &ticklen) - || (SSL_CONNECTION_IS_TLS13(s) ? (ticklen == 0 - || PACKET_remaining(pkt) < ticklen) - : PACKET_remaining(pkt) != ticklen)) { + || (SSL_CONNECTION_IS_VERSION13(s) ? (ticklen == 0 + || PACKET_remaining(pkt) < ticklen) + : PACKET_remaining(pkt) != ticklen)) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } @@ -3122,7 +3275,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL_CONNECTION *s, * post-handshake and the session may have already gone into the session * cache. */ - if (SSL_CONNECTION_IS_TLS13(s) || s->session->session_id_length > 0) { + if (SSL_CONNECTION_IS_VERSION13(s) || s->session->session_id_length > 0) { SSL_SESSION *new_sess; /* @@ -3135,7 +3288,7 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL_CONNECTION *s, } if ((s->session_ctx->session_cache_mode & SSL_SESS_CACHE_CLIENT) != 0 - && !SSL_CONNECTION_IS_TLS13(s)) { + && !SSL_CONNECTION_IS_VERSION13(s)) { /* * In TLSv1.2 and below the arrival of a new tickets signals that * any old ticket we were using is now out of date, so we remove the @@ -3169,15 +3322,15 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL_CONNECTION *s, s->session->ext.tick_age_add = age_add; s->session->ext.ticklen = ticklen; - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { PACKET extpkt; /* - * Fulfilling RFC8446:4.6.1 requirement: Clients MUST NOT cache + * Fulfilling RFC9846:4.7.1 requirement: Clients MUST NOT cache * tickets for longer than 7 days. */ if (ticket_lifetime_hint > 604800) { - ticket_lifetime_hint = 604800; + s->session->ext.tick_lifetime_hint = 604800; } if (!PACKET_as_length_prefixed_2(pkt, &extpkt) @@ -3220,8 +3373,36 @@ MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL_CONNECTION *s, s->session->session_id_length = sess_len; s->session->not_resumable = 0; + /* + * Refresh the session's recollection of the negotiated ALPN protocol to + * match this connection, rather than leaving it as whatever the session + * (or the session it was duplicated from, on a resumption) previously + * carried. Without this, a connection that resumes a session but + * negotiates no ALPN (or a different one) leaves the stale protocol + * name in place, and a later 0-RTT attempt against this ticket can + * incorrectly trip the "inconsistent early data alpn" check -- or, if + * the client happens to offer that same stale protocol again by + * coincidence, incorrectly appear consistent. This mirrors, on the + * client, the server-side fix for issue #11197 in + * tls_construct_new_session_ticket(). + */ + OPENSSL_free(s->session->ext.alpn_selected); + if (s->s3.alpn_selected != NULL) { + s->session->ext.alpn_selected = OPENSSL_memdup(s->s3.alpn_selected, + s->s3.alpn_selected_len); + if (s->session->ext.alpn_selected == NULL) { + s->session->ext.alpn_selected_len = 0; + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_CRYPTO_LIB); + goto err; + } + s->session->ext.alpn_selected_len = s->s3.alpn_selected_len; + } else { + s->session->ext.alpn_selected = NULL; + s->session->ext.alpn_selected_len = 0; + } + /* This is a standalone message in TLSv1.3, so there is no more to read */ - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { const EVP_MD *md = ssl_handshake_md(s); int hashleni = EVP_MD_get_size(md); size_t hashlen; @@ -3287,10 +3468,7 @@ int tls_process_cert_status_body(SSL_CONNECTION *s, size_t chainidx, PACKET *pkt if (s->ext.ocsp.resp_ex == NULL) s->ext.ocsp.resp_ex = sk_OCSP_RESPONSE_new_null(); - /* - * TODO(DTLS-1.3): in future DTLS should also be considered - */ - if (!SSL_CONNECTION_IS_TLS13(s) && type == TLSEXT_STATUSTYPE_ocsp) { + if (!SSL_CONNECTION_IS_VERSION13(s) && type == TLSEXT_STATUSTYPE_ocsp) { sk_OCSP_RESPONSE_pop_free(s->ext.ocsp.resp_ex, OCSP_RESPONSE_free); s->ext.ocsp.resp_ex = sk_OCSP_RESPONSE_new_null(); } @@ -4068,7 +4246,12 @@ int tls_client_key_exchange_post_work(SSL_CONNECTION *s) pmslen = 0; #ifndef OPENSSL_NO_SCTP - if (SSL_CONNECTION_IS_DTLS(s)) { + /* + * Before exporting the SCTP auth key we check if DTLSv1.3 has been negotiated + * which is not supported. + * Refer to draft-tuexen-tsvwg-rfc6083-bis-04 for more info. + */ + if (SSL_CONNECTION_IS_DTLS(s) && !SSL_CONNECTION_IS_DTLS13(s)) { unsigned char sctpauthkey[64]; char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; size_t labellen; @@ -4191,7 +4374,7 @@ WORK_STATE tls_prepare_client_certificate(SSL_CONNECTION *s, WORK_STATE wst) return WORK_ERROR; } - if (!SSL_CONNECTION_IS_TLS13(s) + if (!SSL_CONNECTION_IS_VERSION13(s) || (s->options & SSL_OP_NO_TX_CERTIFICATE_COMPRESSION) != 0) s->ext.compress_certificate_from_peer[0] = TLSEXT_comp_cert_none; @@ -4211,7 +4394,7 @@ CON_FUNC_RETURN tls_construct_client_certificate(SSL_CONNECTION *s, CERT_PKEY *cpk = NULL; SSL *ssl = SSL_CONNECTION_GET_SSL(s); - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { if (s->pha_context == NULL) { /* no context available, add 0-length context */ if (!WPACKET_put_bytes_u8(pkt, 0)) { @@ -4248,11 +4431,11 @@ CON_FUNC_RETURN tls_construct_client_certificate(SSL_CONNECTION *s, * then we deferred changing the handshake write keys to the last possible * moment. We need to do it now. */ - if (SSL_CONNECTION_IS_TLS13(s) + if (SSL_CONNECTION_IS_VERSION13(s) && !SSL_IS_QUIC_HANDSHAKE(s) && SSL_IS_FIRST_HANDSHAKE(s) && (s->early_data_state != SSL_EARLY_DATA_NONE - || (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0) + || SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s)) && (!ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE))) { /* @@ -4344,7 +4527,7 @@ CON_FUNC_RETURN tls_construct_client_compressed_certificate(SSL_CONNECTION *sc, && (sc->early_data_state != SSL_EARLY_DATA_NONE || (sc->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0) && (!ssl->method->ssl3_enc->change_cipher_state(sc, - SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE))) { + SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE | SSL3_CC_COMP_CERT))) { /* * This is a fatal error, which leaves sc->enc_write_ctx in an * inconsistent state and thus ssl3_send_alert may crash. diff --git a/ssl/statem/statem_dtls.c b/ssl/statem/statem_dtls.c index 860d4c1c005b5..db1023e6699d1 100644 --- a/ssl/statem/statem_dtls.c +++ b/ssl/statem/statem_dtls.c @@ -55,15 +55,6 @@ static const unsigned char bitmask_end_values[] = { 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f }; -static void dtls1_fix_message_header(SSL_CONNECTION *s, size_t frag_off, - size_t frag_len); -static unsigned char *dtls1_write_message_header(SSL_CONNECTION *s, - unsigned char *p); -static void dtls1_set_message_header_int(SSL_CONNECTION *s, unsigned char mt, - size_t len, - unsigned short seq_num, - size_t frag_off, - size_t frag_len); static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, size_t *len); @@ -120,64 +111,116 @@ static int dtls_ccs_expected(SSL_CONNECTION *s) } } +static dtls_sent_msg *dtls1_sent_msg_new(size_t msg_len) +{ + dtls_sent_msg *msg = OPENSSL_malloc(sizeof(*msg) + msg_len); + + if (msg == NULL) + return NULL; + + memset(msg, 0, sizeof(*msg)); + + /* zero length msg gets msg->msg_buf == NULL */ + if (msg_len > 0) + msg->msg_buf = (unsigned char *)(msg + 1); + + return msg; +} + +void dtls1_sent_msg_free(dtls_sent_msg *msg) +{ + if (msg != NULL) + ossl_list_record_number_elem_free(&msg->rec_nums); + + OPENSSL_free(msg); +} + static hm_fragment *dtls1_hm_fragment_new(size_t frag_len, int reassembly) { - hm_fragment *frag = NULL; - unsigned char *buf = NULL; - unsigned char *bitmask = NULL; + const size_t bitmask_len = (reassembly ? RSMBLY_BITMASK_SIZE(frag_len) : 0); + hm_fragment *frag = OPENSSL_malloc(sizeof(*frag) + frag_len + bitmask_len); - if ((frag = OPENSSL_zalloc(sizeof(*frag))) == NULL) + if (frag == NULL) return NULL; - if (frag_len) { - if ((buf = OPENSSL_malloc(frag_len)) == NULL) { - OPENSSL_free(frag); - return NULL; - } - } + memset(frag, 0, sizeof(*frag)); /* zero length fragment gets zero frag->fragment */ - frag->fragment = buf; + if (frag_len > 0) + frag->fragment = (unsigned char *)(frag + 1); /* Initialize reassembly bitmask if necessary */ - if (reassembly) { - bitmask = OPENSSL_zalloc(RSMBLY_BITMASK_SIZE(frag_len)); - if (bitmask == NULL) { - OPENSSL_free(buf); - OPENSSL_free(frag); - return NULL; - } - } + if (bitmask_len > 0) { + if (frag->fragment == NULL) + frag->reassembly = (unsigned char *)(frag + 1); + else + frag->reassembly = frag->fragment + frag_len; - frag->reassembly = bitmask; + memset(frag->reassembly, 0, bitmask_len); + } return frag; } void dtls1_hm_fragment_free(hm_fragment *frag) { - if (!frag) - return; - - OPENSSL_free(frag->fragment); - OPENSSL_free(frag->reassembly); OPENSSL_free(frag); } +static int dtls1_write_hm_header(unsigned char *msgheaderstart, + unsigned char msg_type, size_t msg_len, + unsigned short msg_seq, size_t fragoff, + size_t fraglen) +{ + WPACKET msgheader; + size_t msgheaderlen; + + if (!WPACKET_init_static_len(&msgheader, msgheaderstart, + DTLS1_HM_HEADER_LENGTH, 0) + || !WPACKET_put_bytes_u8(&msgheader, msg_type) + || !WPACKET_put_bytes_u24(&msgheader, msg_len) + || !WPACKET_put_bytes_u16(&msgheader, msg_seq) + || !WPACKET_put_bytes_u24(&msgheader, fragoff) + || !WPACKET_put_bytes_u24(&msgheader, fraglen) + || !WPACKET_get_total_written(&msgheader, &msgheaderlen) + || msgheaderlen != DTLS1_HM_HEADER_LENGTH + || !WPACKET_finish(&msgheader)) { + WPACKET_cleanup(&msgheader); + return 0; + } + + return 1; +} + /* * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or * SSL3_RT_CHANGE_CIPHER_SPEC) + * + * When sending a fragmented handshake message this function will re-use + * s->init_buf->data but overwrite previously sent data to fill out the handshake + * message header for the next fragment. + * + * E.g. + * |-------------------------s->init_buf->data------------------------------| + * |-- header1 --||-- fragment1 --| + * |-- header2 --||-- fragment2 --| + * |-- header3 --||-- fragment3 --| + * ......... */ -int dtls1_do_write(SSL_CONNECTION *s, uint8_t type) +int dtls1_do_write(SSL_CONNECTION *s, uint8_t recordtype) { int ret; size_t written; size_t curr_mtu; int retry = 1; - size_t len, frag_off, overhead, used_len; + size_t len, overhead, used_len; SSL *ssl = SSL_CONNECTION_GET_SSL(s); SSL *ussl = SSL_CONNECTION_GET_USER_SSL(s); uint8_t saved_payload[DTLS1_HM_HEADER_LENGTH]; + /* msg_len, msg_seq, msg_type are only used for recordtype == SSL3_RT_HANDSHAKE */ + const size_t msg_len = s->d1->w_msg.msg_body_len; + const unsigned short msg_seq = s->d1->w_msg.msg_seq; + const unsigned char msg_type = s->d1->w_msg.msg_type; if (!dtls1_query_mtu(s)) return -1; @@ -186,50 +229,41 @@ int dtls1_do_write(SSL_CONNECTION *s, uint8_t type) /* should have something reasonable now */ return -1; - if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE) { - if (!ossl_assert(s->init_num == s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH)) + if (s->init_off == 0 && recordtype == SSL3_RT_HANDSHAKE) { + if (!ossl_assert(s->init_num == msg_len + DTLS1_HM_HEADER_LENGTH)) return -1; } overhead = s->rlayer.wrlmethod->get_max_record_overhead(s->rlayer.wrl); - frag_off = 0; s->rwstate = SSL_NOTHING; /* s->init_num shouldn't ever be < 0...but just in case */ while (s->init_num > 0) { - if (type == SSL3_RT_HANDSHAKE && s->init_off != 0) { - /* We must be writing a fragment other than the first one */ + unsigned char *msgstart; - if (frag_off > 0) { - /* This is the first attempt at writing out this fragment */ - - if (s->init_off <= DTLS1_HM_HEADER_LENGTH) { - /* - * Each fragment that was already sent must at least have - * contained the message header plus one other byte. - * Therefore |init_off| must have progressed by at least - * |DTLS1_HM_HEADER_LENGTH + 1| bytes. If not something went - * wrong. - */ - return -1; - } - - /* - * Adjust |init_off| and |init_num| to allow room for a new - * message header for this fragment. - */ - s->init_off -= DTLS1_HM_HEADER_LENGTH; - s->init_num += DTLS1_HM_HEADER_LENGTH; - } else { + if (recordtype == SSL3_RT_HANDSHAKE && s->init_off > 0) { + /* + * We must be writing a fragment other than the first one + * and this is the first attempt at writing out this fragment + */ + if (s->init_off <= DTLS1_HM_HEADER_LENGTH) { /* - * We must have been called again after a retry so use the - * fragment offset from our last attempt. We do not need - * to adjust |init_off| and |init_num| as above, because - * that should already have been done before the retry. + * Each fragment that was already sent must at least have + * contained the message header plus one other byte. + * Therefore |init_off| must have progressed by at least + * |DTLS1_HM_HEADER_LENGTH + 1| bytes. If not something went + * wrong. */ - frag_off = s->d1->w_msg_hdr.frag_off; + return -1; } + + /* + * Adjust |init_off| and |init_num| to allow room for a new + * message header for this fragment. + */ + s->init_off -= DTLS1_HM_HEADER_LENGTH; + s->init_num += DTLS1_HM_HEADER_LENGTH; } used_len = BIO_wpending(s->wbio) + overhead; @@ -255,10 +289,7 @@ int dtls1_do_write(SSL_CONNECTION *s, uint8_t type) } } - /* - * We just checked that s->init_num > 0 so this cast should be safe - */ - if (((unsigned int)s->init_num) > curr_mtu) + if (s->init_num > curr_mtu) len = curr_mtu; else len = s->init_num; @@ -267,37 +298,41 @@ int dtls1_do_write(SSL_CONNECTION *s, uint8_t type) len = ssl_get_max_send_fragment(s); /* - * XDTLS: this function is too long. split out the CCS part + * For DTLS1.3 and padding lets update the max fragment size + * accordingly */ - if (type == SSL3_RT_HANDSHAKE) { - if (len < DTLS1_HM_HEADER_LENGTH) { - /* - * len is so small that we really can't do anything sensible - * so fail - */ - return -1; - } - dtls1_fix_message_header(s, frag_off, len - DTLS1_HM_HEADER_LENGTH); + if (SSL_CONNECTION_IS_DTLS13(s)) + s->rlayer.wrlmethod->set_curr_mtu(s->rlayer.wrl, curr_mtu); + + msgstart = (unsigned char *)&s->init_buf->data[s->init_off]; + + if (recordtype == SSL3_RT_HANDSHAKE) { + const size_t fragoff = s->init_off; + const size_t fraglen = len - DTLS1_HM_HEADER_LENGTH; /* * Save the data that will be overwritten by - * dtls1_write_messsage_header so no corruption occurs when using + * the following code so no corruption occurs when using * a msg callback. */ if (s->msg_callback && s->init_off != 0) - memcpy(saved_payload, &s->init_buf->data[s->init_off], - sizeof(saved_payload)); + memcpy(saved_payload, msgstart, sizeof(saved_payload)); - dtls1_write_message_header(s, - (unsigned char *)&s->init_buf->data[s->init_off]); + if (len < DTLS1_HM_HEADER_LENGTH + || !dtls1_write_hm_header(msgstart, msg_type, msg_len, + msg_seq, fragoff, fraglen)) + /* + * len is so small that we really can't do anything sensible + * so fail + */ + return -1; } - ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], len, + ret = dtls1_write_bytes(s, recordtype, msgstart, len, &written); - if (type == SSL3_RT_HANDSHAKE && s->msg_callback && s->init_off != 0) - memcpy(&s->init_buf->data[s->init_off], saved_payload, - sizeof(saved_payload)); + if (recordtype == SSL3_RT_HANDSHAKE && s->msg_callback && s->init_off != 0) + memcpy(msgstart, saved_payload, sizeof(saved_payload)); if (ret <= 0) { /* @@ -306,17 +341,13 @@ int dtls1_do_write(SSL_CONNECTION *s, uint8_t type) * retransmit anything. continue as if everything is fine and * wait for an alert to handle the retransmit */ - if (retry && BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0) { - if (!(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { - if (!dtls1_query_mtu(s)) - return -1; - /* Have one more go */ - retry = 0; - } else - return -1; - } else { + if (retry && BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0 + && !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU) + && dtls1_query_mtu(s)) + /* Have one more go */ + retry = 0; + else return -1; - } } else { /* @@ -336,39 +367,49 @@ int dtls1_do_write(SSL_CONNECTION *s, uint8_t type) assert(s->s3.tmp.new_compression != NULL || BIO_wpending(s->wbio) <= (int)s->d1->mtu); - if (type == SSL3_RT_HANDSHAKE && !s->d1->retransmitting) { - /* - * should not be done for 'Hello Request's, but in that case - * we'll ignore the result anyway - */ - unsigned char *p = (unsigned char *)&s->init_buf->data[s->init_off]; - const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - size_t xlen; + if (recordtype == SSL3_RT_HANDSHAKE && !s->d1->retransmitting + && s->init_off == 0) { + size_t xlen = s->init_num; - if (frag_off == 0 && s->version != DTLS1_BAD_VER) { + if (s->version == DTLS1_BAD_VER) { + msgstart += DTLS1_HM_HEADER_LENGTH; + xlen -= DTLS1_HM_HEADER_LENGTH; + } else { /* - * reconstruct message header is if it is being sent in - * single fragment + * Now prepare to calculate the transcript hash. For + * versions prior to DTLSv1.3 this means: + * + * rfc6347: Hash calculations include entire handshake + * messages, including DTLS-specific fields: message_seq, + * fragment_offset, and fragment_length. However, the + * Finished MAC MUST be computed as if each handshake + * message had been sent as a single fragment. + * + * For DTLSv1.3 DTLS-specific fields: message_seq, + * fragment_offset, and fragment_length are not used in the + * calculation i.e. the MAC-calculation is the same as TLS + * even though DTLS handshake messages may be fragmented. */ - *p++ = msg_hdr->type; - l2n3(msg_hdr->msg_len, p); - s2n(msg_hdr->seq, p); - l2n3(0, p); - l2n3(msg_hdr->msg_len, p); - p -= DTLS1_HM_HEADER_LENGTH; - xlen = written; - } else { - p += DTLS1_HM_HEADER_LENGTH; - xlen = written - DTLS1_HM_HEADER_LENGTH; + if (!dtls1_write_hm_header(msgstart, msg_type, msg_len, + msg_seq, 0, msg_len)) + return -1; } - if (!ssl3_finish_mac(s, p, xlen)) - return -1; + /* + * should not be done for 'Hello Request's, but in that case we'll + * ignore the result anyway + * DTLS1.3 KeyUpdate and NewSessionTicket do not need to be added + */ + if (!SSL_CONNECTION_IS_DTLS13(s) + || (s->statem.hand_state != TLS_ST_SW_SESSION_TICKET + && s->statem.hand_state != TLS_ST_CW_KEY_UPDATE + && s->statem.hand_state != TLS_ST_SW_KEY_UPDATE)) + if (!ssl3_finish_mac(s, msgstart, xlen)) + return -1; } - if (written == s->init_num) { if (s->msg_callback) - s->msg_callback(1, s->version, type, s->init_buf->data, + s->msg_callback(1, s->version, recordtype, s->init_buf->data, s->init_off + s->init_num, ussl, s->msg_callback_arg); @@ -380,15 +421,6 @@ int dtls1_do_write(SSL_CONNECTION *s, uint8_t type) s->init_off += written; s->init_num -= written; written -= DTLS1_HM_HEADER_LENGTH; - frag_off += written; - - /* - * We save the fragment offset for the next fragment so we have it - * available in case of an IO retry. We don't know the length of the - * next fragment yet so just set that to 0 for now. It will be - * updated again later. - */ - dtls1_fix_message_header(s, frag_off, 0); } } return 0; @@ -396,17 +428,16 @@ int dtls1_do_write(SSL_CONNECTION *s, uint8_t type) int dtls_get_message(SSL_CONNECTION *s, int *mt) { - struct hm_header_st *msg_hdr; - unsigned char *p; - size_t msg_len; + unsigned char *rec_data; size_t tmplen; int errtype; - msg_hdr = &s->d1->r_msg_hdr; - memset(msg_hdr, 0, sizeof(*msg_hdr)); + s->d1->r_msg_seq = 0; again: if (!dtls_get_reassembled_message(s, &errtype, &tmplen)) { + if (s->statem.ack_for_retransmit) + return 0; if (errtype == DTLS1_HM_BAD_FRAGMENT || errtype == DTLS1_HM_FRAGMENT_RETRY) { /* bad fragment received */ @@ -417,30 +448,19 @@ int dtls_get_message(SSL_CONNECTION *s, int *mt) *mt = s->s3.tmp.message_type; - p = (unsigned char *)s->init_buf->data; + rec_data = (unsigned char *)s->init_buf->data; - if (*mt == SSL3_MT_CHANGE_CIPHER_SPEC) { - if (s->msg_callback) { - s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, - p, 1, SSL_CONNECTION_GET_USER_SSL(s), - s->msg_callback_arg); - } - /* - * This isn't a real handshake message so skip the processing below. - */ + /* + * If this isn't a real handshake message skip the processing below. + */ + if (*mt == SSL3_MT_CHANGE_CIPHER_SPEC || *mt == DTLS13_MT_ACK) return 1; - } - - msg_len = msg_hdr->msg_len; /* reconstruct message header */ - *(p++) = msg_hdr->type; - l2n3(msg_len, p); - s2n(msg_hdr->seq, p); - l2n3(0, p); - l2n3(msg_len, p); + dtls1_write_hm_header(rec_data, s->s3.tmp.message_type, s->s3.tmp.message_size, + s->d1->r_msg_seq, 0, s->s3.tmp.message_size); - memset(msg_hdr, 0, sizeof(*msg_hdr)); + s->d1->r_msg_seq = 0; s->d1->handshake_read_seq++; @@ -457,12 +477,27 @@ int dtls_get_message(SSL_CONNECTION *s, int *mt) int dtls_get_message_body(SSL_CONNECTION *s, size_t *len) { unsigned char *msg = (unsigned char *)s->init_buf->data; - size_t msg_len = s->init_num + DTLS1_HM_HEADER_LENGTH; + size_t msg_len; + int recordtype; + + switch (s->s3.tmp.message_type) { + default: + recordtype = SSL3_RT_HANDSHAKE; + msg_len = s->init_num + DTLS1_HM_HEADER_LENGTH; + + break; + case DTLS13_MT_ACK: + recordtype = SSL3_RT_ACK; + msg_len = s->init_num; + + goto end; + case SSL3_MT_CHANGE_CIPHER_SPEC: + recordtype = SSL3_RT_CHANGE_CIPHER_SPEC; + msg_len = 1; - if (s->s3.tmp.message_type == SSL3_MT_CHANGE_CIPHER_SPEC) { - /* Nothing to be done */ goto end; } + /* * If receiving Finished, record MAC of prior handshake messages for * Finished verification. @@ -472,20 +507,14 @@ int dtls_get_message_body(SSL_CONNECTION *s, size_t *len) return 0; } - if (s->version == DTLS1_BAD_VER) { - msg += DTLS1_HM_HEADER_LENGTH; - msg_len -= DTLS1_HM_HEADER_LENGTH; - } - - if (!ssl3_finish_mac(s, msg, msg_len)) + if (!tls_common_finish_mac(s)) return 0; +end: if (s->msg_callback) - s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, - s->init_buf->data, s->init_num + DTLS1_HM_HEADER_LENGTH, + s->msg_callback(0, s->version, recordtype, msg, msg_len, SSL_CONNECTION_GET_USER_SSL(s), s->msg_callback_arg); -end: *len = s->init_num; return 1; } @@ -504,7 +533,7 @@ static size_t dtls1_max_handshake_message_len(const SSL_CONNECTION *s) } static int dtls1_preprocess_fragment(SSL_CONNECTION *s, - struct hm_header_st *msg_hdr) + const struct hm_header_st *const msg_hdr) { size_t frag_off, frag_len, msg_len; @@ -519,30 +548,43 @@ static int dtls1_preprocess_fragment(SSL_CONNECTION *s, return 0; } - if (s->d1->r_msg_hdr.frag_off == 0) { /* first fragment */ - /* - * msg_len is limited to 2^24, but is effectively checked against - * dtls_max_handshake_message_len(s) above - */ - if (!BUF_MEM_grow_clean(s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BUF_LIB); - return 0; - } - - s->s3.tmp.message_size = msg_len; - s->d1->r_msg_hdr.msg_len = msg_len; - s->s3.tmp.message_type = msg_hdr->type; - s->d1->r_msg_hdr.type = msg_hdr->type; - s->d1->r_msg_hdr.seq = msg_hdr->seq; - } else if (msg_len != s->d1->r_msg_hdr.msg_len) { - /* - * They must be playing with us! BTW, failure to enforce upper limit - * would open possibility for buffer overrun. - */ - SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_EXCESSIVE_MESSAGE_SIZE); + /* + * msg_len is limited to 2^24, but is effectively checked against + * dtls_max_handshake_message_len(s) above + */ + if (!BUF_MEM_grow_clean(s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_BUF_LIB); return 0; } + s->s3.tmp.message_size = msg_len; + s->s3.tmp.message_type = msg_hdr->type; + s->d1->r_msg_seq = msg_hdr->seq; + + return 1; +} + +static int add_record_to_ack_list(SSL_CONNECTION *sc) +{ + DTLS1_RECORD_NUMBER *recnum; + uint64_t epoch = sc->s3.tmp.record_epoch; + uint64_t sequence = sc->s3.tmp.record_seq_num; + + for (recnum = ossl_list_record_number_head(&sc->d1->ack_rec_num); + recnum != NULL; + recnum = ossl_list_record_number_next(recnum)) { + /* Is the record number already in the list? */ + if (recnum->epoch == epoch && recnum->seqnum == sequence) + return 1; + } + + recnum = dtls1_record_number_new(epoch, sequence); + + if (recnum == NULL) + return 0; + + ossl_list_record_number_insert_tail(&sc->d1->ack_rec_num, recnum); + return 1; } @@ -563,8 +605,9 @@ static int dtls1_retrieve_buffered_fragment(SSL_CONNECTION *s, size_t *len) hm_fragment *frag; int ret; int chretran = 0; + pqueue *rcvd_messages = &s->d1->rcvd_messages; - iter = pqueue_iterator(s->d1->buffered_messages); + iter = pqueue_iterator(rcvd_messages); do { item = pqueue_next(&iter); if (item == NULL) @@ -585,7 +628,7 @@ static int dtls1_retrieve_buffered_fragment(SSL_CONNECTION *s, size_t *len) * It is safe to pop this message from the queue even though * we have an active iterator */ - pqueue_pop(s->d1->buffered_messages); + pqueue_pop(rcvd_messages); dtls1_hm_fragment_free(frag); pitem_free(item); item = NULL; @@ -605,7 +648,7 @@ static int dtls1_retrieve_buffered_fragment(SSL_CONNECTION *s, size_t *len) * We have fragments for both a ClientHello without * cookie and one with. Ditch the one without. */ - pqueue_pop(s->d1->buffered_messages); + pqueue_pop(rcvd_messages); dtls1_hm_fragment_free(frag); pitem_free(item); item = next; @@ -626,7 +669,8 @@ static int dtls1_retrieve_buffered_fragment(SSL_CONNECTION *s, size_t *len) if (s->d1->handshake_read_seq == frag->msg_header.seq || chretran) { size_t frag_len = frag->msg_header.frag_len; - pqueue_pop(s->d1->buffered_messages); + + pqueue_pop(rcvd_messages); /* Calls SSLfatal() as required */ ret = dtls1_preprocess_fragment(s, &frag->msg_header); @@ -669,12 +713,12 @@ static int dtls1_reassemble_fragment(SSL_CONNECTION *s, hm_fragment *frag = NULL; pitem *item = NULL; int i = -1, is_complete; - unsigned char seq64be[8]; size_t frag_len = msg_hdr->frag_len; size_t readbytes; SSL *ssl = SSL_CONNECTION_GET_SSL(s); - if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len || msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) + if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len + || msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) goto err; if (frag_len == 0) { @@ -682,10 +726,7 @@ static int dtls1_reassemble_fragment(SSL_CONNECTION *s, } /* Try to find item in queue */ - memset(seq64be, 0, sizeof(seq64be)); - seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); - seq64be[7] = (unsigned char)msg_hdr->seq; - item = pqueue_find(s->d1->buffered_messages, seq64be); + item = pqueue_find_u64(&s->d1->rcvd_messages, msg_hdr->seq); if (item == NULL) { frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1); @@ -727,8 +768,6 @@ static int dtls1_reassemble_fragment(SSL_CONNECTION *s, frag->fragment + msg_hdr->frag_off, frag_len, 0, &readbytes); if (i <= 0 || readbytes != frag_len) - i = -1; - if (i <= 0) goto err; RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off, @@ -739,22 +778,18 @@ static int dtls1_reassemble_fragment(SSL_CONNECTION *s, RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len, is_complete); - if (is_complete) { - OPENSSL_free(frag->reassembly); + if (is_complete) frag->reassembly = NULL; - } if (item == NULL) { - item = pitem_new(seq64be, frag); - if (item == NULL) { - i = -1; + item = pitem_new_u64(msg_hdr->seq, frag); + if (item == NULL) goto err; - } - item = pqueue_insert(s->d1->buffered_messages, item); + item = pqueue_insert(&s->d1->rcvd_messages, item); /* * pqueue_insert fails iff a duplicate item is inserted. However, - * |item| cannot be a duplicate. If it were, |pqueue_find|, above, + * |item| cannot be a duplicate. If it were, |pqueue_find_u64|, above, * would have returned it and control would never have reached this * branch. */ @@ -762,6 +797,10 @@ static int dtls1_reassemble_fragment(SSL_CONNECTION *s, goto err; } + if (dtls_msg_needs_ack(!s->server, msg_hdr->type) + && !add_record_to_ack_list(s)) + goto err; + return DTLS1_HM_FRAGMENT_RETRY; err: @@ -776,7 +815,6 @@ static int dtls1_process_out_of_seq_message(SSL_CONNECTION *s, int i = -1; hm_fragment *frag = NULL; pitem *item = NULL; - unsigned char seq64be[8]; size_t frag_len = msg_hdr->frag_len; size_t readbytes; SSL *ssl = SSL_CONNECTION_GET_SSL(s); @@ -785,10 +823,7 @@ static int dtls1_process_out_of_seq_message(SSL_CONNECTION *s, goto err; /* Try to find item in queue, to prevent duplicate entries */ - memset(seq64be, 0, sizeof(seq64be)); - seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); - seq64be[7] = (unsigned char)msg_hdr->seq; - item = pqueue_find(s->d1->buffered_messages, seq64be); + item = pqueue_find_u64(&s->d1->rcvd_messages, msg_hdr->seq); /* * If we already have an entry and this one is a fragment, don't discard @@ -813,6 +848,18 @@ static int dtls1_process_out_of_seq_message(SSL_CONNECTION *s, goto err; frag_len -= readbytes; } + /* + * A lost ACK can cause an already processed post-handshake message to + * be retransmitted in a new record. ACK it without processing it again. + */ + if (SSL_CONNECTION_IS_DTLS13(s) + && s->s3.tmp.record_epoch >= 3 + && msg_hdr->seq < s->d1->handshake_read_seq + && dtls_msg_needs_ack(!s->server, msg_hdr->type)) { + if (!add_record_to_ack_list(s)) + goto err; + s->statem.ack_for_retransmit = 1; + } } else { if (frag_len != msg_hdr->msg_len) { return dtls1_reassemble_fragment(s, msg_hdr); @@ -835,16 +882,21 @@ static int dtls1_process_out_of_seq_message(SSL_CONNECTION *s, frag->fragment, frag_len, 0, &readbytes); if (i <= 0 || readbytes != frag_len) - i = -1; - if (i <= 0) goto err; } - item = pitem_new(seq64be, frag); + item = pitem_new_u64(msg_hdr->seq, frag); if (item == NULL) goto err; - item = pqueue_insert(s->d1->buffered_messages, item); + if (dtls_msg_needs_ack(!s->server, msg_hdr->type) + && !add_record_to_ack_list(s)) { + pitem_free(item); + item = NULL; + goto err; + } + + item = pqueue_insert(&s->d1->rcvd_messages, item); /* * pqueue_insert fails iff a duplicate item is inserted. However, * |item| cannot be a duplicate. If it were, |pqueue_find|, above, @@ -865,10 +917,53 @@ static int dtls1_process_out_of_seq_message(SSL_CONNECTION *s, return 0; } +static int dtls1_read_hm_header(unsigned char *msgheaderstart, + struct hm_header_st *msg_hdr) +{ + unsigned long msg_len, frag_off, frag_len; + unsigned int msg_seq, msg_type; + PACKET msgheader; + + if (!PACKET_buf_init(&msgheader, msgheaderstart, DTLS1_HM_HEADER_LENGTH) + || !PACKET_get_1(&msgheader, &msg_type) + || !PACKET_get_net_3(&msgheader, &msg_len) + || !PACKET_get_net_2(&msgheader, &msg_seq) + || !PACKET_get_net_3(&msgheader, &frag_off) + || !PACKET_get_net_3(&msgheader, &frag_len) + || PACKET_remaining(&msgheader) != 0) { + return 0; + } + + /* We just checked that values did not exceed max size so cast must be alright */ + msg_hdr->type = (unsigned char)msg_type; + msg_hdr->msg_len = (size_t)msg_len; + msg_hdr->seq = (unsigned short)msg_seq; + msg_hdr->frag_off = (size_t)frag_off; + msg_hdr->frag_len = (size_t)frag_len; + + return 1; +} + +/* + * DTLS 1.3 reserves handshake message type 0, so a HelloRequest must reach the + * state machine and be rejected there whenever DTLS 1.3 is still possible. + * + * s->version is the negotiated, or maximum version: before ServerHello this is + * the effective maximum, and after ServerHello or during renegotiation it is the + * selected version. + */ +static int dtls_should_skip_hello_request(const SSL_CONNECTION *s) +{ + if (SSL_CONNECTION_IS_DTLS13(s)) + return 0; + + return s->version > 0 + && ssl_version_cmp(s, s->version, DTLS1_3_VERSION) < 0; +} + static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, size_t *len) { - size_t mlen, frag_off, frag_len; int i, ret; uint8_t recvd_type; struct hm_header_st msg_hdr; @@ -906,14 +1001,14 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, } /* see if we have the required fragment already */ - ret = dtls1_retrieve_buffered_fragment(s, &frag_len); + ret = dtls1_retrieve_buffered_fragment(s, &msg_hdr.frag_len); if (ret < 0) { /* SSLfatal() already called */ return 0; } if (ret > 0) { - s->init_num = frag_len; - *len = frag_len; + s->init_num = msg_hdr.frag_len; + *len = msg_hdr.frag_len; return 1; } @@ -949,6 +1044,44 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, SSL_R_BAD_CHANGE_CIPHER_SPEC); goto f_err; } + if (recvd_type == SSL3_RT_ACK) { + /* + * An ACK has no handshake message header: the bytes already read + * are body, and an ACK never spans records (RFC 9147 section 4), + * so the rest of the body - if any - is whatever is left in the + * current record. Take it directly to avoid re-entering the + * timeout path while assembling the ACK. + */ + if (readbytes == DTLS1_HM_HEADER_LENGTH + && s->rlayer.curr_rec < s->rlayer.num_recs) { + TLS_RECORD *rr = &s->rlayer.tlsrecs[s->rlayer.curr_rec]; + + /* + * DTLS currently processes one record at a time, so an exhausted + * record is excluded above. Keep these checks to avoid consuming + * a following record if pipelining is added. + */ + if (rr->off > 0 && rr->length > 0) { + /* + * init_buf has capacity for a full plaintext record, whose size + * has already been checked by the record layer. + */ + memcpy(p + DTLS1_HM_HEADER_LENGTH, rr->data + rr->off, + rr->length); + readbytes += rr->length; + if (!ssl_release_record(s, rr, rr->length)) { + /* SSLfatal() already called */ + goto f_err; + } + } + } + s->init_num = readbytes; + s->init_msg = s->init_buf->data; + s->s3.tmp.message_type = DTLS13_MT_ACK; + s->s3.tmp.message_size = readbytes; + *len = readbytes; + return 1; + } /* Handshake fails if message header is incomplete */ if (readbytes != DTLS1_HM_HEADER_LENGTH) { @@ -957,17 +1090,16 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, } /* parse the message fragment header */ - dtls1_get_message_header(p, &msg_hdr); - - mlen = msg_hdr.msg_len; - frag_off = msg_hdr.frag_off; - frag_len = msg_hdr.frag_len; + if (!dtls1_read_hm_header(p, &msg_hdr)) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_LENGTH); + goto f_err; + } /* * We must have at least frag_len bytes left in the record to be read. * Fragments must not span records. */ - if (frag_len > s->rlayer.tlsrecs[s->rlayer.curr_rec].length) { + if (msg_hdr.frag_len > s->rlayer.tlsrecs[s->rlayer.curr_rec].length) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_LENGTH); goto f_err; } @@ -982,7 +1114,7 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, if (!s->server || msg_hdr.seq != 0 || s->d1->handshake_read_seq != 1 - || p[0] != SSL3_MT_CLIENT_HELLO + || msg_hdr.type != SSL3_MT_CLIENT_HELLO || s->statem.hand_state != DTLS_ST_SW_HELLO_VERIFY_REQUEST) { *errtype = dtls1_process_out_of_seq_message(s, &msg_hdr); return 0; @@ -995,21 +1127,21 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, chretran = 1; } - if (frag_len && frag_len < mlen) { + if (msg_hdr.frag_len > 0 && msg_hdr.frag_len < msg_hdr.msg_len) { *errtype = dtls1_reassemble_fragment(s, &msg_hdr); return 0; } if (!s->server - && s->d1->r_msg_hdr.frag_off == 0 && s->statem.hand_state != TLS_ST_OK - && p[0] == SSL3_MT_HELLO_REQUEST) { + && msg_hdr.type == SSL3_MT_HELLO_REQUEST + && dtls_should_skip_hello_request(s)) { /* * The server may always send 'Hello Request' messages -- we are * doing a handshake anyway now, so ignore them if their format is * correct. Does not count for 'Finished' MAC. */ - if (p[1] == 0 && p[2] == 0 && p[3] == 0) { + if (msg_hdr.msg_len == 0) { if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, p, DTLS1_HM_HEADER_LENGTH, ussl, @@ -1017,8 +1149,8 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, s->init_num = 0; goto redo; - } else { /* Incorrectly formatted Hello request */ - + } else { + /* Incorrectly formatted Hello request */ SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); goto f_err; } @@ -1029,12 +1161,12 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, goto f_err; } - if (frag_len > 0) { + if (msg_hdr.frag_len > 0) { /* dtls1_preprocess_fragment() above could reallocate init_buf */ - p = (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + p = (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH + msg_hdr.frag_off; i = ssl->method->ssl_read_bytes(ssl, SSL3_RT_HANDSHAKE, NULL, - &p[frag_off], frag_len, 0, &readbytes); + p, msg_hdr.frag_len, 0, &readbytes); /* * This shouldn't ever fail due to NBIO because we already checked @@ -1053,7 +1185,7 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, * XDTLS: an incorrectly formatted fragment should cause the handshake * to fail */ - if (readbytes != frag_len) { + if (readbytes != msg_hdr.frag_len) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_BAD_LENGTH); goto f_err; } @@ -1069,13 +1201,19 @@ static int dtls_get_reassembled_message(SSL_CONNECTION *s, int *errtype, s->d1->next_handshake_write_seq = 0; } + if (dtls_msg_needs_ack(!s->server, msg_hdr.type) + && !add_record_to_ack_list(s)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto f_err; + } + /* * Note that s->init_num is *not* used as current offset in * s->init_buf->data, but as a counter summing up fragments' lengths: as * soon as they sum up to handshake packet length, we assume we have got * all the fragments. */ - *len = s->init_num = frag_len; + *len = s->init_num = msg_hdr.frag_len; return 1; f_err: @@ -1105,6 +1243,111 @@ CON_FUNC_RETURN dtls_construct_change_cipher_spec(SSL_CONNECTION *s, return CON_FUNC_SUCCESS; } +CON_FUNC_RETURN dtls_construct_ack(SSL_CONNECTION *s, WPACKET *pkt) +{ + DTLS1_RECORD_NUMBER *recnum; + DTLS1_RECORD_NUMBER *recnumnext = ossl_list_record_number_head(&s->d1->ack_rec_num); + + if (!WPACKET_start_sub_packet_u16(pkt)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return CON_FUNC_ERROR; + } + + while ((recnum = recnumnext) != NULL) { + /* + * rfc9147: section 4. + * + * Record numbers are encoded as + * struct { + * uint64 epoch; + * uint64 sequence_number; + * } RecordNumber; + */ + + recnumnext = ossl_list_record_number_next(recnum); + + if (!SSL_IS_FIRST_HANDSHAKE(s) + || recnum->epoch <= dtls1_get_epoch(s, SSL3_CC_WRITE)) { + /* + * rfc9147: + * During the handshake, ACK records MUST be sent with an epoch which + * is equal to or higher than the record which is being acknowledged. + * After the handshake, the sending and receiving epochs can differ. + */ + if (!WPACKET_put_bytes_u64(pkt, recnum->epoch) + || !WPACKET_put_bytes_u64(pkt, recnum->seqnum)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return CON_FUNC_ERROR; + } + + ossl_list_record_number_remove(&s->d1->ack_rec_num, recnum); + OPENSSL_free(recnum); + } + } + + if (!WPACKET_close(pkt)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + return CON_FUNC_ERROR; + } + + return CON_FUNC_SUCCESS; +} + +MSG_PROCESS_RETURN dtls_process_ack(SSL_CONNECTION *s, PACKET *pkt) +{ + PACKET record_numbers; + + if (!PACKET_as_length_prefixed_2(pkt, &record_numbers)) { + SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_LENGTH_TOO_LONG); + return MSG_PROCESS_ERROR; + } + + while (PACKET_remaining(&record_numbers) > 0) { + /* + * rfc9147: section 4. + * + * Record numbers are encoded as + * struct { + * uint64 epoch; + * uint64 sequence_number; + * } RecordNumber; + */ + pitem *item; + piterator iter; + uint64_t epoch; + uint64_t sequence_number; + + if (!PACKET_get_net_8(&record_numbers, &epoch) + || !PACKET_get_net_8(&record_numbers, &sequence_number)) { + SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_TOO_SHORT); + return MSG_PROCESS_ERROR; + } + + iter = pqueue_iterator(&s->d1->sent_messages); + + while ((item = pqueue_next(&iter)) != NULL) { + dtls_sent_msg *msg = (dtls_sent_msg *)item->data; + DTLS1_RECORD_NUMBER *recnum; + DTLS1_RECORD_NUMBER *recnum_next = ossl_list_record_number_head(&msg->rec_nums); + + while ((recnum = recnum_next) != NULL) { + recnum_next = ossl_list_record_number_next(recnum_next); + + if (recnum->epoch == epoch && recnum->seqnum == sequence_number) { + ossl_list_record_number_remove(&msg->rec_nums, recnum); + OPENSSL_free(recnum); + } + } + } + } + + /* Keep the retransmit timer running until the whole flight is ACKed. */ + if (dtls_any_sent_messages_are_missing_acknowledge(s)) + return MSG_PROCESS_CONTINUE_READING; + + return MSG_PROCESS_FINISHED_READING; +} + #ifndef OPENSSL_NO_SCTP /* * Wait for a dry event. Should only be called at a point in the handshake @@ -1171,7 +1414,8 @@ int dtls1_read_failed(SSL_CONNECTION *s, int code) return dtls1_handle_timeout(s); } -int dtls1_get_queue_priority(unsigned short seq, int is_ccs) +void dtls1_get_queue_priority(unsigned char *prio64be, unsigned short seq, + int record_type) { /* * The index of the retransmission queue actually is the message sequence @@ -1183,33 +1427,40 @@ int dtls1_get_queue_priority(unsigned short seq, int is_ccs) * Finished, it also maintains the order of the index (important for * priority queues) and fits in the unsigned short variable. */ - return seq * 2 - is_ccs; + int lsb = (record_type == SSL3_RT_CHANGE_CIPHER_SPEC); + const uint16_t prio = seq * 2 - lsb; + + memset(prio64be, 0, 8); + prio64be[6] = (unsigned char)(prio >> 8); + prio64be[7] = (unsigned char)(prio); } -int dtls1_retransmit_buffered_messages(SSL_CONNECTION *s) +int dtls1_retransmit_sent_messages(SSL_CONNECTION *s) { - pqueue *sent = s->d1->sent_messages; - piterator iter; + piterator iter = pqueue_iterator(&s->d1->sent_messages); pitem *item; - hm_fragment *frag; - int found = 0; - - iter = pqueue_iterator(sent); for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) { - frag = (hm_fragment *)item->data; - if (dtls1_retransmit_message(s, (unsigned short)dtls1_get_queue_priority(frag->msg_header.seq, frag->msg_header.is_ccs), &found) <= 0) + dtls_sent_msg *sent_msg = (dtls_sent_msg *)item->data; + + if (SSL_CONNECTION_IS_DTLS13(s) + && ossl_list_record_number_is_empty(&sent_msg->rec_nums)) + /* rfc9147: Implementations must not retransmit acknowledged msgs */ + continue; + + if (dtls1_retransmit_message(s, sent_msg) <= 0) return -1; } return 1; } -int dtls1_buffer_message(SSL_CONNECTION *s, int is_ccs) +int dtls1_buffer_sent_message(SSL_CONNECTION *s, int record_type) { pitem *item; - hm_fragment *frag; + dtls_sent_msg *sent_msg; unsigned char seq64be[8]; + size_t headerlen; /* * this function is called immediately after a message has been @@ -1218,96 +1469,64 @@ int dtls1_buffer_message(SSL_CONNECTION *s, int is_ccs) if (!ossl_assert(s->init_off == 0)) return 0; - frag = dtls1_hm_fragment_new(s->init_num, 0); - if (frag == NULL) + sent_msg = dtls1_sent_msg_new(s->init_num); + if (sent_msg == NULL) return 0; - memcpy(frag->fragment, s->init_buf->data, s->init_num); + memcpy(sent_msg->msg_buf, s->init_buf->data, s->init_num); - if (is_ccs) { + if (record_type == SSL3_RT_CHANGE_CIPHER_SPEC) /* For DTLS1_BAD_VER the header length is non-standard */ - if (!ossl_assert(s->d1->w_msg_hdr.msg_len + ((s->version == DTLS1_BAD_VER) ? 3 : DTLS1_CCS_HEADER_LENGTH) - == (unsigned int)s->init_num)) { - dtls1_hm_fragment_free(frag); - return 0; - } - } else { - if (!ossl_assert(s->d1->w_msg_hdr.msg_len + DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num)) { - dtls1_hm_fragment_free(frag); - return 0; - } + headerlen = (s->version == DTLS1_BAD_VER) ? 3 : DTLS1_CCS_HEADER_LENGTH; + else + headerlen = DTLS1_HM_HEADER_LENGTH; + + if (!ossl_assert(s->d1->w_msg.msg_body_len + headerlen == s->init_num)) { + dtls1_sent_msg_free(sent_msg); + return 0; } - frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; - frag->msg_header.seq = s->d1->w_msg_hdr.seq; - frag->msg_header.type = s->d1->w_msg_hdr.type; - frag->msg_header.frag_off = 0; - frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; - frag->msg_header.is_ccs = is_ccs; + memcpy(&sent_msg->msg_info, &s->d1->w_msg, sizeof(s->d1->w_msg)); /* save current state */ - frag->msg_header.saved_retransmit_state.wrlmethod = s->rlayer.wrlmethod; - frag->msg_header.saved_retransmit_state.wrl = s->rlayer.wrl; + sent_msg->saved_retransmit_state.wrlmethod = s->rlayer.wrlmethod; + sent_msg->saved_retransmit_state.wrl = s->rlayer.wrl; - memset(seq64be, 0, sizeof(seq64be)); - seq64be[6] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.seq, - frag->msg_header.is_ccs) - >> 8); - seq64be[7] = (unsigned char)(dtls1_get_queue_priority(frag->msg_header.seq, - frag->msg_header.is_ccs)); + dtls1_get_queue_priority(seq64be, sent_msg->msg_info.msg_seq, sent_msg->msg_info.record_type); - item = pitem_new(seq64be, frag); + item = pitem_new(seq64be, sent_msg); if (item == NULL) { - dtls1_hm_fragment_free(frag); + dtls1_sent_msg_free(sent_msg); return 0; } - if (pqueue_insert(s->d1->sent_messages, item) == NULL) { - dtls1_hm_fragment_free(frag); + if (pqueue_insert(&s->d1->sent_messages, item) == NULL) { + dtls1_sent_msg_free(sent_msg); pitem_free(item); return 0; } return 1; } -int dtls1_retransmit_message(SSL_CONNECTION *s, unsigned short seq, int *found) +int dtls1_retransmit_message(SSL_CONNECTION *s, dtls_sent_msg *sent_msg) { int ret; - /* XDTLS: for now assuming that read/writes are blocking */ - pitem *item; - hm_fragment *frag; unsigned long header_length; - unsigned char seq64be[8]; struct dtls1_retransmit_state saved_state; - /* XDTLS: the requested message ought to be found, otherwise error */ - memset(seq64be, 0, sizeof(seq64be)); - seq64be[6] = (unsigned char)(seq >> 8); - seq64be[7] = (unsigned char)seq; - - item = pqueue_find(s->d1->sent_messages, seq64be); - if (item == NULL) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); - *found = 0; - return 0; - } - - *found = 1; - frag = (hm_fragment *)item->data; - - if (frag->msg_header.is_ccs) + if (sent_msg->msg_info.record_type == SSL3_RT_CHANGE_CIPHER_SPEC) header_length = DTLS1_CCS_HEADER_LENGTH; else header_length = DTLS1_HM_HEADER_LENGTH; - memcpy(s->init_buf->data, frag->fragment, - frag->msg_header.msg_len + header_length); - s->init_num = frag->msg_header.msg_len + header_length; + /* Clear the record number list to be acked for retransmitted messages */ + ossl_list_record_number_elem_free(&sent_msg->rec_nums); - dtls1_set_message_header_int(s, frag->msg_header.type, - frag->msg_header.msg_len, - frag->msg_header.seq, 0, - frag->msg_header.frag_len); + memcpy(s->init_buf->data, sent_msg->msg_buf, + sent_msg->msg_info.msg_body_len + header_length); + s->init_num = sent_msg->msg_info.msg_body_len + header_length; + + memcpy(&s->d1->w_msg, &sent_msg->msg_info, sizeof(sent_msg->msg_info)); /* save current state */ saved_state.wrlmethod = s->rlayer.wrlmethod; @@ -1316,8 +1535,8 @@ int dtls1_retransmit_message(SSL_CONNECTION *s, unsigned short seq, int *found) s->d1->retransmitting = 1; /* restore state in which the message was originally sent */ - s->rlayer.wrlmethod = frag->msg_header.saved_retransmit_state.wrlmethod; - s->rlayer.wrl = frag->msg_header.saved_retransmit_state.wrl; + s->rlayer.wrlmethod = sent_msg->saved_retransmit_state.wrlmethod; + s->rlayer.wrl = sent_msg->saved_retransmit_state.wrl; /* * The old wrl may be still pointing at an old BIO. Update it to what we're @@ -1325,7 +1544,7 @@ int dtls1_retransmit_message(SSL_CONNECTION *s, unsigned short seq, int *found) */ s->rlayer.wrlmethod->set1_bio(s->rlayer.wrl, s->wbio); - ret = dtls1_do_write(s, frag->msg_header.is_ccs ? SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); + ret = dtls1_do_write(s, sent_msg->msg_info.record_type); /* restore current state */ s->rlayer.wrlmethod = saved_state.wrlmethod; @@ -1337,87 +1556,35 @@ int dtls1_retransmit_message(SSL_CONNECTION *s, unsigned short seq, int *found) return ret; } -void dtls1_set_message_header(SSL_CONNECTION *s, - unsigned char mt, size_t len, - size_t frag_off, size_t frag_len) -{ - if (frag_off == 0) { - s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; - s->d1->next_handshake_write_seq++; - } - - dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, - frag_off, frag_len); -} - -/* don't actually do the writing, wait till the MTU has been retrieved */ -static void -dtls1_set_message_header_int(SSL_CONNECTION *s, unsigned char mt, - size_t len, unsigned short seq_num, - size_t frag_off, size_t frag_len) -{ - struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - - msg_hdr->type = mt; - msg_hdr->msg_len = len; - msg_hdr->seq = seq_num; - msg_hdr->frag_off = frag_off; - msg_hdr->frag_len = frag_len; -} - -static void -dtls1_fix_message_header(SSL_CONNECTION *s, size_t frag_off, size_t frag_len) -{ - struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - - msg_hdr->frag_off = frag_off; - msg_hdr->frag_len = frag_len; -} - -static unsigned char *dtls1_write_message_header(SSL_CONNECTION *s, - unsigned char *p) -{ - struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; - - *p++ = msg_hdr->type; - l2n3(msg_hdr->msg_len, p); - - s2n(msg_hdr->seq, p); - l2n3(msg_hdr->frag_off, p); - l2n3(msg_hdr->frag_len, p); - - return p; -} - -void dtls1_get_message_header(const unsigned char *data, struct hm_header_st *msg_hdr) -{ - memset(msg_hdr, 0, sizeof(*msg_hdr)); - msg_hdr->type = *(data++); - n2l3(data, msg_hdr->msg_len); - - n2s(data, msg_hdr->seq); - n2l3(data, msg_hdr->frag_off); - n2l3(data, msg_hdr->frag_len); -} - int dtls1_set_handshake_header(SSL_CONNECTION *s, WPACKET *pkt, int htype) { - unsigned char *header; + s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; + s->d1->w_msg.msg_seq = s->d1->handshake_write_seq; + s->d1->w_msg.msg_body_len = 0; if (htype == SSL3_MT_CHANGE_CIPHER_SPEC) { - s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; - dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, - s->d1->handshake_write_seq, 0, 0); + s->d1->w_msg.record_type = SSL3_RT_CHANGE_CIPHER_SPEC; + s->d1->w_msg.msg_type = SSL3_MT_CCS; + if (!WPACKET_put_bytes_u8(pkt, SSL3_MT_CCS)) return 0; + } else if (htype == DTLS13_MT_ACK) { + s->d1->w_msg.record_type = SSL3_RT_ACK; + s->d1->w_msg.msg_type = 0; } else { - dtls1_set_message_header(s, htype, 0, 0, 0); - /* - * We allocate space at the start for the message header. This gets - * filled in later - */ - if (!WPACKET_allocate_bytes(pkt, DTLS1_HM_HEADER_LENGTH, &header) - || !WPACKET_start_sub_packet(pkt)) + size_t subpacket_offset = DTLS1_HM_HEADER_LENGTH - SSL3_HM_HEADER_LENGTH; + + s->d1->next_handshake_write_seq++; + s->d1->w_msg.record_type = SSL3_RT_HANDSHAKE; + s->d1->w_msg.msg_type = htype; + + /* Set the content type and 3 bytes for the message len */ + if (!WPACKET_put_bytes_u8(pkt, htype) + /* + * We allocate space for DTLS specific fields. + * These gets filled later. + */ + || !WPACKET_start_sub_packet_u24_at_offset(pkt, subpacket_offset)) return 0; } @@ -1428,21 +1595,21 @@ int dtls1_close_construct_packet(SSL_CONNECTION *s, WPACKET *pkt, int htype) { size_t msglen; - if ((htype != SSL3_MT_CHANGE_CIPHER_SPEC && !WPACKET_close(pkt)) + if ((s->d1->w_msg.record_type == SSL3_RT_HANDSHAKE && !WPACKET_close(pkt)) || !WPACKET_get_length(pkt, &msglen) || msglen > INT_MAX) return 0; - if (htype != SSL3_MT_CHANGE_CIPHER_SPEC) { - s->d1->w_msg_hdr.msg_len = msglen - DTLS1_HM_HEADER_LENGTH; - s->d1->w_msg_hdr.frag_len = msglen - DTLS1_HM_HEADER_LENGTH; - } - s->init_num = (int)msglen; + if (s->d1->w_msg.record_type == SSL3_RT_HANDSHAKE) + s->d1->w_msg.msg_body_len = msglen - DTLS1_HM_HEADER_LENGTH; + + s->init_num = msglen; s->init_off = 0; - if (htype != DTLS1_MT_HELLO_VERIFY_REQUEST) { + if (htype != DTLS1_MT_HELLO_VERIFY_REQUEST + && s->d1->w_msg.record_type != SSL3_RT_ACK) { /* Buffer the message to handle re-xmits */ - if (!dtls1_buffer_message(s, htype == SSL3_MT_CHANGE_CIPHER_SPEC ? 1 : 0)) + if (!dtls1_buffer_sent_message(s, s->d1->w_msg.record_type)) return 0; } diff --git a/ssl/statem/statem_lib.c b/ssl/statem/statem_lib.c index 465d2eff33c97..fcc10320aa91d 100644 --- a/ssl/statem/statem_lib.c +++ b/ssl/statem/statem_lib.c @@ -132,7 +132,7 @@ int tls_close_construct_packet(SSL_CONNECTION *s, WPACKET *pkt, int htype) || !WPACKET_get_length(pkt, &msglen) || msglen > INT_MAX) return 0; - s->init_num = (int)msglen; + s->init_num = msglen; s->init_off = 0; return 1; @@ -159,13 +159,13 @@ int tls_setup_handshake(SSL_CONNECTION *s) /* Sanity check that we have MD5-SHA1 if we need it */ if (sctx->ssl_digest_methods[SSL_MD_MD5_SHA1_IDX] == NULL) { - int negotiated_minversion; - int md5sha1_needed_maxversion = SSL_CONNECTION_IS_DTLS(s) - ? DTLS1_VERSION - : TLS1_1_VERSION; + const int version1_2 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_2_VERSION + : TLS1_2_VERSION; + const int version1_1 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_VERSION + : TLS1_1_VERSION; /* We don't have MD5-SHA1 - do we need it? */ - if (ssl_version_cmp(s, ver_max, md5sha1_needed_maxversion) <= 0) { + if (ssl_version_cmp(s, ver_max, version1_1) <= 0) { SSLfatal_data(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_NO_SUITABLE_DIGEST_ALGORITHM, "The max supported SSL/TLS version needs the" @@ -178,9 +178,8 @@ int tls_setup_handshake(SSL_CONNECTION *s) ok = 1; /* Don't allow TLSv1.1 or below to be negotiated */ - negotiated_minversion = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_2_VERSION : TLS1_2_VERSION; - if (ssl_version_cmp(s, ver_min, negotiated_minversion) < 0) - ok = SSL_set_min_proto_version(ssl, negotiated_minversion); + if (ssl_version_cmp(s, ver_min, version1_2) < 0) + ok = SSL_set_min_proto_version(ssl, version1_2); if (!ok) { /* Shouldn't happen */ SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, ERR_R_INTERNAL_ERROR); @@ -207,7 +206,8 @@ int tls_setup_handshake(SSL_CONNECTION *s) ? c->max_dtls : c->max_tls; - if (ssl_version_cmp(s, ver_max, cipher_minprotover) >= 0 + if (cipher_minprotover > 0 && cipher_maxprotover > 0 + && ssl_version_cmp(s, ver_max, cipher_minprotover) >= 0 && ssl_version_cmp(s, ver_max, cipher_maxprotover) <= 0) { ok = 1; break; @@ -266,7 +266,7 @@ static int get_cert_verify_tbs_data(SSL_CONNECTION *s, unsigned char *tls13tbs, static const char clientcontext[] = "\x54\x4c\x53\x20\x31\x2e\x33\x2c\x20\x63\x6c\x69" "\x65\x6e\x74\x20\x43\x65\x72\x74\x69\x66\x69\x63\x61\x74\x65\x56\x65\x72\x69\x66\x79"; - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { size_t hashlen; /* Set the first 64 bytes of to-be-signed data to octet 32 */ @@ -579,14 +579,14 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL_CONNECTION *s, PACKET *pkt) } /* - * In TLSv1.3 on the client side we make sure we prepare the client + * In (D)TLSv1.3 on the client side we make sure we prepare the client * certificate after the CertVerify instead of when we get the - * CertificateRequest. This is because in TLSv1.3 the CertificateRequest - * comes *before* the Certificate message. In TLSv1.2 it comes after. We + * CertificateRequest. This is because in (D)TLSv1.3 the CertificateRequest + * comes *before* the Certificate message. In (D)TLSv1.2 it comes after. We * want to make sure that SSL_get1_peer_certificate() will return the actual * server certificate from the client_cert_cb callback. */ - if (!s->server && SSL_CONNECTION_IS_TLS13(s) && s->s3.tmp.cert_req == 1) + if (!s->server && SSL_CONNECTION_IS_VERSION13(s) && s->s3.tmp.cert_req == 1) ret = MSG_PROCESS_CONTINUE_PROCESSING; else ret = MSG_PROCESS_CONTINUE_READING; @@ -617,11 +617,11 @@ CON_FUNC_RETURN tls_construct_finished(SSL_CONNECTION *s, WPACKET *pkt) * moment. If we didn't already do this when we sent the client certificate * then we need to do it now. */ - if (SSL_CONNECTION_IS_TLS13(s) + if (SSL_CONNECTION_IS_VERSION13(s) && !s->server && !SSL_IS_QUIC_HANDSHAKE(s) && (s->early_data_state != SSL_EARLY_DATA_NONE - || (s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0) + || SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s)) && s->s3.tmp.cert_req == 0 && (!ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_CLIENT_WRITE))) { @@ -655,9 +655,9 @@ CON_FUNC_RETURN tls_construct_finished(SSL_CONNECTION *s, WPACKET *pkt) /* * Log the master secret, if logging is enabled. We don't log it for - * TLSv1.3: there's a different key schedule for that. + * (D)TLSv1.3: there's a different key schedule for that. */ - if (!SSL_CONNECTION_IS_TLS13(s) + if (!SSL_CONNECTION_IS_VERSION13(s) && !ssl_log_secret(s, MASTER_SECRET_LABEL, s->session->master_key, s->session->master_key_length)) { /* SSLfatal() already called */ @@ -837,13 +837,13 @@ MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt) /* * To get this far we must have read encrypted data from the client. We * no longer tolerate unencrypted alerts. This is ignored if less than - * TLSv1.3 + * (D)TLSv1.3 */ if (s->rlayer.rrlmethod->set_plain_alerts != NULL) s->rlayer.rrlmethod->set_plain_alerts(s->rlayer.rrl, 0); if (s->post_handshake_auth != SSL_PHA_REQUESTED) s->statem.cleanuphand = 1; - if (SSL_CONNECTION_IS_TLS13(s) + if (SSL_CONNECTION_IS_VERSION13(s) && !tls13_save_handshake_digest_for_pha(s)) { /* SSLfatal() already called */ return MSG_PROCESS_ERROR; @@ -854,14 +854,14 @@ MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt) * In TLSv1.3 a Finished message signals a key change so the end of the * message must be on a record boundary. */ - if (SSL_CONNECTION_IS_TLS13(s) + if (SSL_CONNECTION_IS_VERSION13(s) && RECORD_LAYER_processed_read_pending(&s->rlayer)) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_NOT_ON_RECORD_BOUNDARY); return MSG_PROCESS_ERROR; } /* If this occurs, we have missed a message */ - if (!SSL_CONNECTION_IS_TLS13(s) && !s->s3.change_cipher_spec) { + if (!SSL_CONNECTION_IS_VERSION13(s) && !s->s3.change_cipher_spec) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_GOT_A_FIN_BEFORE_A_CCS); return MSG_PROCESS_ERROR; } @@ -909,14 +909,14 @@ MSG_PROCESS_RETURN tls_process_finished(SSL_CONNECTION *s, PACKET *pkt) * In TLS1.3 we also have to change cipher state and do any final processing * of the initial server flight (if we are a client) */ - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { if (s->server) { if (s->post_handshake_auth != SSL_PHA_REQUESTED && !ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_APPLICATION | SSL3_CHANGE_CIPHER_SERVER_READ)) { /* SSLfatal() already called */ return MSG_PROCESS_ERROR; } } else { - /* TLS 1.3 gets the secret size from the handshake md */ + /* (D)TLS 1.3 gets the secret size from the handshake md */ size_t dummy; if (!ssl->method->ssl3_enc->generate_master_secret(s, s->master_secret, s->handshake_secret, 0, @@ -992,7 +992,7 @@ static int ssl_add_cert_to_wpacket(SSL_CONNECTION *s, WPACKET *pkt, return 0; } - if ((SSL_CONNECTION_IS_TLS13(s) || for_comp) + if ((SSL_CONNECTION_IS_VERSION13(s) || for_comp) && !tls_construct_extensions(s, pkt, context, x, chain)) { /* SSLfatal() already called */ return 0; @@ -1124,9 +1124,9 @@ int tls_process_rpk(SSL_CONNECTION *sc, PACKET *pkt, EVP_PKEY **peer_rpk) /*- * ---------------------------- - * TLS 1.3 Certificate message: + * (D)TLS 1.3 Certificate message: * ---------------------------- - * https://datatracker.ietf.org/doc/html/rfc8446#section-4.4.2 + * https://datatracker.ietf.org/doc/html/rfc9846#section-4.5.1 * * enum { * X509(0), @@ -1184,21 +1184,21 @@ int tls_process_rpk(SSL_CONNECTION *sc, PACKET *pkt, EVP_PKEY **peer_rpk) * ------------- * Consequently: * ------------- - * After the (TLS 1.3 only) context octet string (1 byte length + data) the + * After the ((D)TLS 1.3 only) context octet string (1 byte length + data) the * Certificate message has a 3-byte length that is zero in the client to * server message when the client has no RPK to send. In that case, there - * are no (TLS 1.3 only) per-certificate extensions either, because the + * are no ((D)TLS 1.3 only) per-certificate extensions either, because the * [CertificateEntry] list is empty. * * In the server to client direction, or when the client had an RPK to send, - * the TLS 1.3 message just prepends the length of the RPK+extensions, + * the (D)TLS 1.3 message just prepends the length of the RPK+extensions, * while TLS <= 1.2 sends just the RPK (octet-string). * * The context must be zero-length in the server to client direction, and * must match the value recorded in the certificate request in the client * to server direction. */ - if (SSL_CONNECTION_IS_TLS13(sc)) { + if (SSL_CONNECTION_IS_VERSION13(sc)) { if (!PACKET_get_length_prefixed_1(pkt, &context)) { SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_INVALID_CONTEXT); goto err; @@ -1240,7 +1240,7 @@ int tls_process_rpk(SSL_CONNECTION *sc, PACKET *pkt, EVP_PKEY **peer_rpk) if (cert_len == 0) return 1; - if (SSL_CONNECTION_IS_TLS13(sc)) { + if (SSL_CONNECTION_IS_VERSION13(sc)) { /* * With TLS 1.3, a non-empty explicit-length RPK octet-string followed * by a possibly empty extension block. @@ -1275,7 +1275,7 @@ int tls_process_rpk(SSL_CONNECTION *sc, PACKET *pkt, EVP_PKEY **peer_rpk) } /* Process the Extensions block */ - if (SSL_CONNECTION_IS_TLS13(sc)) { + if (SSL_CONNECTION_IS_VERSION13(sc)) { if (PACKET_remaining(pkt) != (cert_len - 3 - spki_len)) { SSLfatal(sc, SSL_AD_DECODE_ERROR, SSL_R_BAD_LENGTH); goto err; @@ -1352,7 +1352,7 @@ unsigned long tls_output_rpk(SSL_CONNECTION *sc, WPACKET *pkt, CERT_PKEY *cpk) * TLSv1.2 is _just_ the raw public key * TLSv1.3 includes extensions, so there's a length wrapper */ - if (SSL_CONNECTION_IS_TLS13(sc)) { + if (SSL_CONNECTION_IS_VERSION13(sc)) { if (!WPACKET_start_sub_packet_u24(pkt)) { SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; @@ -1364,7 +1364,7 @@ unsigned long tls_output_rpk(SSL_CONNECTION *sc, WPACKET *pkt, CERT_PKEY *cpk) goto err; } - if (SSL_CONNECTION_IS_TLS13(sc)) { + if (SSL_CONNECTION_IS_VERSION13(sc)) { /* * Only send extensions relevant to raw public keys. Until such * extensions are defined, this will be an empty set of extensions. @@ -1448,7 +1448,7 @@ WORK_STATE tls_finish_handshake(SSL_CONNECTION *s, ossl_unused WORK_STATE wst, s->init_num = 0; } - if (SSL_CONNECTION_IS_TLS13(s) && !s->server + if (SSL_CONNECTION_IS_VERSION13(s) && !s->server && s->post_handshake_auth == SSL_PHA_REQUESTED) s->post_handshake_auth = SSL_PHA_EXT_SENT; @@ -1470,14 +1470,14 @@ WORK_STATE tls_finish_handshake(SSL_CONNECTION *s, ossl_unused WORK_STATE wst, * In TLSv1.3 we update the cache as part of constructing the * NewSessionTicket */ - if (!SSL_CONNECTION_IS_TLS13(s)) + if (!SSL_CONNECTION_IS_VERSION13(s)) ssl_update_cache(s, SSL_SESS_CACHE_SERVER); /* N.B. s->ctx may not equal s->session_ctx */ ssl_tsan_counter(sctx, &sctx->stats.sess_accept_good); s->handshake_func = ossl_statem_accept; } else { - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { /* * We encourage applications to only use TLSv1.3 tickets once, * so we remove this one from the cache. @@ -1504,9 +1504,16 @@ WORK_STATE tls_finish_handshake(SSL_CONNECTION *s, ossl_unused WORK_STATE wst, if (SSL_CONNECTION_IS_DTLS(s)) { /* done with handshaking */ - s->d1->handshake_read_seq = 0; - s->d1->handshake_write_seq = 0; - s->d1->next_handshake_write_seq = 0; + /* + * In DTLS 1.3, we must not reset the handshake sequence numbers + * because post-handshake messages like NewSessionTicket need to + * continue the sequence numbering from where the handshake left off. + */ + if (!SSL_CONNECTION_IS_DTLS13(s)) { + s->d1->handshake_read_seq = 0; + s->d1->handshake_write_seq = 0; + s->d1->next_handshake_write_seq = 0; + } dtls1_clear_received_buffer(s); } } @@ -1521,7 +1528,7 @@ WORK_STATE tls_finish_handshake(SSL_CONNECTION *s, ossl_unused WORK_STATE wst, if (cb != NULL) { if (cleanuphand - || !SSL_CONNECTION_IS_TLS13(s) + || !SSL_CONNECTION_IS_VERSION13(s) || SSL_IS_FIRST_HANDSHAKE(s)) cb(ssl, SSL_CB_HANDSHAKE_DONE, 1); } @@ -1664,6 +1671,52 @@ static int grow_init_buf(SSL_CONNECTION *s, size_t size) return 1; } +int tls_common_finish_mac(SSL_CONNECTION *s) +{ + unsigned char *msg = (unsigned char *)s->init_buf->data; + size_t msg_len = s->init_num; + size_t hdr_len = 0; + + if (SSL_CONNECTION_IS_DTLS(s)) { + if (s->version != DTLS1_BAD_VER) + hdr_len = DTLS1_HM_HEADER_LENGTH; + else + msg += DTLS1_HM_HEADER_LENGTH; + } else { + hdr_len = SSL3_HM_HEADER_LENGTH; + } + + msg_len += hdr_len; + + /* Feed this message into MAC computation. */ + + /* + * We defer feeding in the HRR until later. We'll do it as part of + * the message processing. + * The (D)TLSv1.3 handshake transcript stops at the ClientFinished + * message. + */ + const size_t srvhellorandom_offs = hdr_len + 2; + + /* KeyUpdate and NewSessionTicket do not need to be added */ + if (!SSL_CONNECTION_IS_VERSION13(s) + || (s->s3.tmp.message_type != SSL3_MT_NEWSESSION_TICKET + && s->s3.tmp.message_type != SSL3_MT_KEY_UPDATE)) { + if (s->s3.tmp.message_type != SSL3_MT_SERVER_HELLO + || s->init_num < srvhellorandom_offs + SSL3_RANDOM_SIZE + || memcmp(hrrrandom, + s->init_buf->data + srvhellorandom_offs, + SSL3_RANDOM_SIZE) + != 0) { + if (!ssl3_finish_mac(s, msg, msg_len)) + /* SSLfatal() already called */ + return 0; + } + } + + return 1; +} + int tls_get_message_body(SSL_CONNECTION *s, size_t *len) { size_t toread, readbytes; @@ -1714,31 +1767,12 @@ int tls_get_message_body(SSL_CONNECTION *s, size_t *len) return 0; } - /* - * We defer feeding in the HRR until later. We'll do it as part of - * processing the message - * The TLsv1.3 handshake transcript stops at the ClientFinished - * message. - */ -#define SERVER_HELLO_RANDOM_OFFSET (SSL3_HM_HEADER_LENGTH + 2) - /* KeyUpdate and NewSessionTicket do not need to be added */ - if (!SSL_CONNECTION_IS_TLS13(s) - || (s->s3.tmp.message_type != SSL3_MT_NEWSESSION_TICKET - && s->s3.tmp.message_type != SSL3_MT_KEY_UPDATE)) { - if (s->s3.tmp.message_type != SSL3_MT_SERVER_HELLO - || s->init_num < SERVER_HELLO_RANDOM_OFFSET + SSL3_RANDOM_SIZE - || memcmp(hrrrandom, - s->init_buf->data + SERVER_HELLO_RANDOM_OFFSET, - SSL3_RANDOM_SIZE) - != 0) { - if (!ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, - s->init_num + SSL3_HM_HEADER_LENGTH)) { - /* SSLfatal() already called */ - *len = 0; - return 0; - } - } + if (!tls_common_finish_mac(s)) { + /* SSLfatal() already called */ + *len = 0; + return 0; } + if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, ussl, @@ -1865,12 +1899,17 @@ static const version_info tls_version_table[] = { { 0, NULL, NULL }, }; -#if DTLS_MAX_VERSION_INTERNAL != DTLS1_2_VERSION -#error Code needs update for DTLS_method() support beyond DTLS1_2_VERSION. +#if DTLS_MAX_VERSION_INTERNAL != DTLS1_3_VERSION +#error Code needs update for DTLS_method() support beyond DTLS1_3_VERSION. #endif /* Must be in order high to low */ static const version_info dtls_version_table[] = { +#ifndef OPENSSL_NO_DTLS1_3 + { DTLS1_3_VERSION, dtlsv1_3_client_method, dtlsv1_3_server_method }, +#else + { DTLS1_3_VERSION, NULL, NULL }, +#endif #ifndef OPENSSL_NO_DTLS1_2 { DTLS1_2_VERSION, dtlsv1_2_client_method, dtlsv1_2_server_method }, #else @@ -1961,7 +2000,7 @@ static int is_tls13_capable(const SSL_CONNECTION *s) /* * Prior to TLSv1.3 sig algs allowed any curve to be used. TLSv1.3 is * more restrictive so check that our sig algs are consistent with this - * EC cert. See section 4.2.3 of RFC8446. + * EC cert. See section 4.3.3 of RFC9846. */ curve = ssl_get_EC_curve_nid(s->cert->pkeys[SSL_PKEY_ECC].privatekey); if (tls_check_sigalg_curve(s, curve)) @@ -2008,7 +2047,7 @@ int ssl_version_supported(const SSL_CONNECTION *s, int version, && ssl_version_cmp(s, version, vent->version) == 0 && ssl_method_error(s, thismeth()) == 0 && (!s->server - || version != TLS1_3_VERSION + || (version != TLS1_3_VERSION && version != DTLS1_3_VERSION) || is_tls13_capable(s))) { if (meth != NULL) *meth = thismeth(); @@ -2126,23 +2165,27 @@ int ssl_set_version_bound(int method_version, int version, int *bound) static void check_for_downgrade(SSL_CONNECTION *s, int vers, DOWNGRADE *dgrd) { - if (vers == TLS1_2_VERSION - && ssl_version_supported(s, TLS1_3_VERSION, NULL)) { + int version12 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_2_VERSION : TLS1_2_VERSION; + int version13 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; + + if (vers == version12 && ssl_version_supported(s, version13, NULL)) { *dgrd = DOWNGRADE_TO_1_2; - } else if (!SSL_CONNECTION_IS_DTLS(s) - && vers < TLS1_2_VERSION + } else if (ssl_version_cmp(s, vers, version12) < 0 /* - * We need to ensure that a server that disables TLSv1.2 - * (creating a hole between TLSv1.3 and TLSv1.1) can still - * complete handshakes with clients that support TLSv1.2 and - * below. Therefore we do not enable the sentinel if TLSv1.3 is - * enabled and TLSv1.2 is not. + * We need to ensure that a server that disables (D)TLSv1.2 + * (creating a hole between (D)TLSv1.3 and (D)TLSv1.1) can still + * complete handshakes with clients that support (D)TLSv1.2 and + * below. Therefore we do not enable the sentinel if (D)TLSv1.3 is + * enabled and (D)TLSv1.2 is not. */ - && ssl_version_supported(s, TLS1_2_VERSION, NULL)) { + && ssl_version_supported(s, version12, NULL)) { *dgrd = DOWNGRADE_TO_1_1; } else { *dgrd = DOWNGRADE_NONE; } + + if (SSL_CONNECTION_IS_DTLS(s)) + s->d1->downgrade_after_hvr = *dgrd; } /* @@ -2173,15 +2216,35 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello, const version_info *table; int disabled = 0; RAW_EXTENSION *suppversions; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION + : TLS1_3_VERSION; + const int version1_2 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_2_VERSION + : TLS1_2_VERSION; + + if (client_version <= 0) + return SSL_R_WRONG_SSL_VERSION; s->client_version = client_version; switch (server_version) { default: - if (!SSL_CONNECTION_IS_TLS13(s)) { + if (!SSL_CONNECTION_IS_VERSION13(s)) { if (ssl_version_cmp(s, client_version, s->version) < 0) return SSL_R_WRONG_SSL_VERSION; - *dgrd = DOWNGRADE_NONE; + + /* + * The downgrade sentinel is selected when parsing the first + * ClientHello. If this server has sent a HelloVerifyRequest, the + * sentinel is recovered while parsing the second ClientHello in + * order to apply it to the ServerHello random value. + */ + if (SSL_CONNECTION_IS_DTLS(s) + && s->d1->hello_verify_request != SSL_HVR_NONE) { + *dgrd = s->d1->downgrade_after_hvr; + } else { + *dgrd = DOWNGRADE_NONE; + } + /* * If this SSL handle is not from a version flexible method we don't * (and never did) check min/max FIPS or Suite B constraints. Hope @@ -2222,9 +2285,11 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello, if (!suppversions->present && s->hello_retry_request != SSL_HRR_NONE) return SSL_R_UNSUPPORTED_PROTOCOL; - if (suppversions->present && !SSL_CONNECTION_IS_DTLS(s)) { - unsigned int candidate_vers = 0; - unsigned int best_vers = 0; + if (suppversions->present) { + int candidate_vers = 0; + const int best_vers_init = SSL_CONNECTION_IS_DTLS(s) ? INT_MAX + : 0; + int best_vers = best_vers_init; const SSL_METHOD *best_method = NULL; PACKET versionslist; @@ -2247,9 +2312,23 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello, if (client_version <= SSL3_VERSION) return SSL_R_BAD_LEGACY_VERSION; - while (PACKET_get_net_2(&versionslist, &candidate_vers)) { - if (ssl_version_cmp(s, candidate_vers, best_vers) <= 0) + while (PACKET_get_net_2(&versionslist, (unsigned int *)&candidate_vers)) { + if (candidate_vers <= 0 + || (best_vers != best_vers_init + && ssl_version_cmp(s, candidate_vers, best_vers) <= 0)) + continue; +#ifndef OPENSSL_NO_SCTP + /* + * DTLS 1.3 is not supported over SCTP. If the client offers + * DTLSv1.3 but the transport is SCTP, thus fall back to + * DTLSv1.2 (or lower) during server-version selection. + */ + if (SSL_CONNECTION_IS_DTLS(s) + && candidate_vers == DTLS1_3_VERSION + && BIO_dgram_is_sctp(SSL_get_wbio( + SSL_CONNECTION_GET_SSL(s)))) continue; +#endif if (ssl_version_supported(s, candidate_vers, &best_method)) best_vers = candidate_vers; } @@ -2258,7 +2337,8 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello, return SSL_R_LENGTH_MISMATCH; } - if (best_vers > 0) { + /* Did best_vers change from the initial value? */ + if (best_vers != best_vers_init) { #ifndef OPENSSL_NO_ECH /* ECH needs TLSV1.3 also */ if (s->ext.ech.success == 1 && best_vers != TLS1_3_VERSION) @@ -2267,9 +2347,9 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello, if (s->hello_retry_request != SSL_HRR_NONE) { /* * This is after a HelloRetryRequest so we better check that we - * negotiated TLSv1.3 + * negotiated (D)TLSv1.3 */ - if (best_vers != TLS1_3_VERSION) + if (best_vers != version1_3) return SSL_R_UNSUPPORTED_PROTOCOL; return 0; } @@ -2286,10 +2366,10 @@ int ssl_choose_server_version(SSL_CONNECTION *s, CLIENTHELLO_MSG *hello, /* * If the supported versions extension isn't present, then the highest - * version we can negotiate is TLSv1.2 + * version we can negotiate is (D)TLSv1.2 */ - if (ssl_version_cmp(s, client_version, TLS1_3_VERSION) >= 0) - client_version = TLS1_2_VERSION; + if (ssl_version_cmp(s, client_version, version1_3) >= 0) + client_version = version1_2; /* * No supported versions extension, so we just use the version supplied in @@ -2333,6 +2413,8 @@ int ssl_choose_client_version(SSL_CONNECTION *s, int version, const version_info *table; int ret, ver_min, ver_max, real_max, origv; SSL *ssl = SSL_CONNECTION_GET_SSL(s); + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION + : TLS1_3_VERSION; origv = s->version; s->version = version; @@ -2347,13 +2429,27 @@ int ssl_choose_client_version(SSL_CONNECTION *s, int version, return 0; } - if (s->hello_retry_request != SSL_HRR_NONE - && s->version != TLS1_3_VERSION) { + if (s->hello_retry_request != SSL_HRR_NONE && s->version != version1_3) { s->version = origv; SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_WRONG_SSL_VERSION); return 0; } +#ifndef OPENSSL_NO_SCTP + /* + * DTLS 1.3 over SCTP is not supported. If the server selected + * DTLSv1.3 but the transport is SCTP, treat it as a protocol + * version mismatch so the handshake is aborted cleanly. + */ + if (SSL_CONNECTION_IS_DTLS(s) + && s->version == DTLS1_3_VERSION + && BIO_dgram_is_sctp(SSL_get_wbio(ssl))) { + s->version = origv; + SSLfatal(s, SSL_AD_PROTOCOL_VERSION, SSL_R_UNSUPPORTED_PROTOCOL); + return 0; + } +#endif + switch (ssl->method->version) { default: if (s->version != ssl->method->version) { @@ -2398,8 +2494,7 @@ int ssl_choose_client_version(SSL_CONNECTION *s, int version, real_max = ver_max; /* Check for downgrades */ - /* TODO(DTLSv1.3): Update this code for DTLSv1.3 */ - if (!SSL_CONNECTION_IS_DTLS(s) && real_max > s->version) { + if (ssl_version_cmp(s, real_max, s->version) > 0) { /* Signal applies to all versions */ if (memcmp(tls11downgrade, s->s3.server_random + SSL3_RANDOM_SIZE @@ -2411,8 +2506,8 @@ int ssl_choose_client_version(SSL_CONNECTION *s, int version, SSL_R_INAPPROPRIATE_FALLBACK); return 0; } - /* Only when accepting TLS1.3 */ - if (real_max == TLS1_3_VERSION + /* Only when accepting (D)TLS1.3 */ + if (ssl_version_cmp(s, s->version, version1_3) && memcmp(tls12downgrade, s->s3.server_random + SSL3_RANDOM_SIZE - sizeof(tls12downgrade), @@ -2534,6 +2629,18 @@ int ssl_get_min_max_version(const SSL_CONNECTION *s, int *min_version, tmp_real_max = 0; continue; } +/* + * DTLS 1.3 over SCTP is not supported. RFC 6083 and its successors only + * define key-material export for DTLS 1.2 and below. + */ +#ifndef OPENSSL_NO_SCTP + if (SSL_CONNECTION_IS_DTLS(s) && DTLS_VERSION_GT(vent->version, DTLS1_2_VERSION)) { + BIO *wbio = SSL_get_wbio(SSL_CONNECTION_GET_SSL(s)); + + if (wbio != NULL && BIO_dgram_is_sctp(wbio)) + continue; + } +#endif method = vent->cmeth(); if (hole == 1 && tmp_real_max == 0) @@ -2572,6 +2679,7 @@ int ssl_get_min_max_version(const SSL_CONNECTION *s, int *min_version, int ssl_set_client_hello_version(SSL_CONNECTION *s) { int ver_min, ver_max, ret; + const int version1_2 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_2_VERSION : TLS1_2_VERSION; /* * In a renegotiation we always send the same client_version that we sent @@ -2587,21 +2695,19 @@ int ssl_set_client_hello_version(SSL_CONNECTION *s) s->version = ver_max; - if (SSL_CONNECTION_IS_DTLS(s)) { - if (ver_max == DTLS1_BAD_VER) { - /* - * Even though this is technically before version negotiation, - * because we have asked for DTLS1_BAD_VER we will never negotiate - * anything else, and this has impacts on the record layer for when - * we read the ServerHello. So we need to tell the record layer - * about this immediately. - */ - if (!ssl_set_record_protocol_version(s, ver_max)) - return 0; - } - } else if (ver_max > TLS1_2_VERSION) { - /* TLS1.3 always uses TLS1.2 in the legacy_version field */ - ver_max = TLS1_2_VERSION; + if (SSL_CONNECTION_IS_DTLS(s) && ver_max == DTLS1_BAD_VER) { + /* + * Even though this is technically before version negotiation, + * because we have asked for DTLS1_BAD_VER we will never negotiate + * anything else, and this has impacts on the record layer for when + * we read the ServerHello. So we need to tell the record layer + * about this immediately. + */ + if (!ssl_set_record_protocol_version(s, ver_max)) + return 0; + } else if (ssl_version_cmp(s, ver_max, version1_2) > 0) { + /* (D)TLS1.3 always uses (D)TLS1.2 in the legacy_version field */ + ver_max = version1_2; } s->client_version = ver_max; @@ -2644,21 +2750,27 @@ int create_synthetic_message_hash(SSL_CONNECTION *s, size_t hashlen, const unsigned char *hrr, size_t hrrlen) { - unsigned char hashvaltmp[EVP_MAX_MD_SIZE]; - unsigned char msghdr[SSL3_HM_HEADER_LENGTH]; + unsigned char *hashvaltmp; + unsigned char synmsg[SSL3_HM_HEADER_LENGTH + EVP_MAX_MD_SIZE]; + size_t currmsghdr_len = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_HM_HEADER_LENGTH + : SSL3_HM_HEADER_LENGTH; - memset(msghdr, 0, sizeof(msghdr)); + memset(synmsg, 0, SSL3_HM_HEADER_LENGTH); + hashvaltmp = synmsg + SSL3_HM_HEADER_LENGTH; if (hashval == NULL) { - hashval = hashvaltmp; - hashlen = 0; /* Get the hash of the initial ClientHello */ if (!ssl3_digest_cached_records(s, 0) - || !ssl_handshake_hash(s, hashvaltmp, sizeof(hashvaltmp), + || !ssl_handshake_hash(s, hashvaltmp, EVP_MAX_MD_SIZE, &hashlen)) { /* SSLfatal() already called */ return 0; } + } else { + if (!ossl_assert(hashlen <= EVP_MAX_MD_SIZE)) + return 0; + + memcpy(hashvaltmp, hashval, hashlen); } /* Reinitialise the transcript hash */ @@ -2668,10 +2780,9 @@ int create_synthetic_message_hash(SSL_CONNECTION *s, } /* Inject the synthetic message_hash message */ - msghdr[0] = SSL3_MT_MESSAGE_HASH; - msghdr[SSL3_HM_HEADER_LENGTH - 1] = (unsigned char)hashlen; - if (!ssl3_finish_mac(s, msghdr, SSL3_HM_HEADER_LENGTH) - || !ssl3_finish_mac(s, hashval, hashlen)) { + synmsg[0] = SSL3_MT_MESSAGE_HASH; + synmsg[SSL3_HM_HEADER_LENGTH - 1] = (unsigned char)hashlen; + if (!ssl3_finish_mac(s, synmsg, SSL3_HM_HEADER_LENGTH + hashlen)) { /* SSLfatal() already called */ return 0; } @@ -2684,8 +2795,7 @@ int create_synthetic_message_hash(SSL_CONNECTION *s, if (hrr != NULL && (!ssl3_finish_mac(s, hrr, hrrlen) || !ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, - s->s3.tmp.message_size - + SSL3_HM_HEADER_LENGTH))) { + s->s3.tmp.message_size + currmsghdr_len))) { /* SSLfatal() already called */ return 0; } diff --git a/ssl/statem/statem_local.h b/ssl/statem/statem_local.h index b73c1e100f191..5cdb953eac7ca 100644 --- a/ssl/statem/statem_local.h +++ b/ssl/statem/statem_local.h @@ -36,11 +36,12 @@ #define SERVER_HELLO_DONE_MAX_LENGTH 0 #define KEY_UPDATE_MAX_LENGTH 1 #define CCS_MAX_LENGTH 1 +#define ACK_MAX_LENGTH 65538 -/* Max ServerHello size permitted by RFC 8446 */ +/* Max ServerHello size permitted by RFC 9846 */ #define SERVER_HELLO_MAX_LENGTH 65607 -/* Max CertificateVerify size permitted by RFC 8446 */ +/* Max CertificateVerify size permitted by RFC 9846 */ #define CERTIFICATE_VERIFY_MAX_LENGTH 65539 /* Max should actually be 36 but we are generous */ @@ -104,6 +105,7 @@ MSG_PROCESS_RETURN ossl_statem_client_process_message(SSL_CONNECTION *s, PACKET *pkt); WORK_STATE ossl_statem_client_post_process_message(SSL_CONNECTION *s, WORK_STATE wst); +int ossl_statem_dtls_client_use_timer(SSL_CONNECTION *s); /* * TLS/DTLS server state machine functions @@ -119,12 +121,14 @@ MSG_PROCESS_RETURN ossl_statem_server_process_message(SSL_CONNECTION *s, PACKET *pkt); WORK_STATE ossl_statem_server_post_process_message(SSL_CONNECTION *s, WORK_STATE wst); +int ossl_statem_dtls_server_use_timer(SSL_CONNECTION *s); /* Functions for getting new message data */ __owur int tls_get_message_header(SSL_CONNECTION *s, int *mt); __owur int tls_get_message_body(SSL_CONNECTION *s, size_t *len); __owur int dtls_get_message(SSL_CONNECTION *s, int *mt); __owur int dtls_get_message_body(SSL_CONNECTION *s, size_t *len); +__owur int tls_common_finish_mac(SSL_CONNECTION *s); /* Message construction and processing functions */ __owur int tls_process_initial_server_flight(SSL_CONNECTION *s); @@ -135,6 +139,7 @@ __owur CON_FUNC_RETURN tls_construct_change_cipher_spec(SSL_CONNECTION *s, WPACKET *pkt); __owur CON_FUNC_RETURN dtls_construct_change_cipher_spec(SSL_CONNECTION *s, WPACKET *pkt); +__owur CON_FUNC_RETURN dtls_construct_ack(SSL_CONNECTION *s, WPACKET *pkt); __owur CON_FUNC_RETURN tls_construct_finished(SSL_CONNECTION *s, WPACKET *pkt); __owur CON_FUNC_RETURN tls_construct_key_update(SSL_CONNECTION *s, WPACKET *pkt); @@ -206,6 +211,7 @@ __owur CON_FUNC_RETURN tls_construct_next_proto(SSL_CONNECTION *s, WPACKET *pkt) #endif __owur MSG_PROCESS_RETURN tls_process_hello_req(SSL_CONNECTION *s, PACKET *pkt); __owur MSG_PROCESS_RETURN dtls_process_hello_verify(SSL_CONNECTION *s, PACKET *pkt); +__owur MSG_PROCESS_RETURN dtls_process_ack(SSL_CONNECTION *s, PACKET *pkt); __owur CON_FUNC_RETURN tls_construct_end_of_early_data(SSL_CONNECTION *s, WPACKET *pkt); @@ -232,6 +238,8 @@ __owur CON_FUNC_RETURN tls_construct_server_done(SSL_CONNECTION *s, WPACKET *pkt); __owur MSG_PROCESS_RETURN tls_process_client_certificate(SSL_CONNECTION *s, PACKET *pkt); +__owur WORK_STATE tls_post_process_client_certificate(SSL_CONNECTION *s, + WORK_STATE wst); #ifndef OPENSSL_NO_COMP_ALG __owur MSG_PROCESS_RETURN tls_process_client_compressed_certificate(SSL_CONNECTION *sc, PACKET *pkt); @@ -269,6 +277,8 @@ __owur int tls_validate_all_contexts(SSL_CONNECTION *s, unsigned int thisctx, RAW_EXTENSION *exts); __owur int extension_is_relevant(SSL_CONNECTION *s, unsigned int extctx, unsigned int thisctx); +__owur int tls_validate_no_unknown_extensions(SSL_CONNECTION *s, + PACKET *packet, unsigned int context); __owur int tls_collect_extensions(SSL_CONNECTION *s, PACKET *packet, unsigned int context, RAW_EXTENSION **res, size_t *len, int init); @@ -493,9 +503,6 @@ EXT_RETURN tls_construct_ctos_grease1(SSL_CONNECTION *s, WPACKET *pkt, EXT_RETURN tls_construct_ctos_grease2(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); -EXT_RETURN tls_construct_ctos_padding(SSL_CONNECTION *s, WPACKET *pkt, - unsigned int context, X509 *x, - size_t chainidx); EXT_RETURN tls_construct_ctos_psk(SSL_CONNECTION *s, WPACKET *pkt, unsigned int context, X509 *x, size_t chainidx); diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index a90d401679124..8f1def3c9ff2b 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -75,6 +75,12 @@ static int ossl_statem_server13_read_transition(SSL_CONNECTION *s, int mt) { OSSL_STATEM *st = &s->statem; + if (st->hand_state == TLS_ST_SR_ACK) { + st->hand_state = st->pre_ack_hand_state; + if (mt == SSL3_MT_DUMMY) + return 1; + } + /* * Note: There is no case for TLS_ST_BEFORE because at that stage we have * not negotiated TLSv1.3 yet, so that case is handled by @@ -91,6 +97,10 @@ static int ossl_statem_server13_read_transition(SSL_CONNECTION *s, int mt) return 1; } break; + /* + * RFC 9147 Section 5.6 states DTLS1.3 should omit the + * End of Early Data Message + */ } else if (s->ext.early_data == SSL_EARLY_DATA_ACCEPTED && !SSL_NO_EOED(s)) { if (mt == SSL3_MT_END_OF_EARLY_DATA) { @@ -98,6 +108,11 @@ static int ossl_statem_server13_read_transition(SSL_CONNECTION *s, int mt) return 1; } break; + } else if (SSL_CONNECTION_IS_DTLS13(s) && s->ext.early_data == SSL_EARLY_DATA_ACCEPTED) { + /* + * Let DTLS1.3 fallthrough to the Finished processing below + */ + s->early_data_state = SSL_EARLY_DATA_FINISHED_READING; } /* Fall through */ @@ -145,6 +160,15 @@ static int ossl_statem_server13_read_transition(SSL_CONNECTION *s, int mt) } break; + case TLS_ST_SW_KEY_UPDATE: + case TLS_ST_SW_SESSION_TICKET: + if (mt == DTLS13_MT_ACK) { + st->pre_ack_hand_state = st->hand_state; + st->hand_state = TLS_ST_SR_ACK; + return 1; + } + break; + case TLS_ST_OK: /* * Its never ok to start processing handshake messages in the middle of @@ -171,6 +195,12 @@ static int ossl_statem_server13_read_transition(SSL_CONNECTION *s, int mt) st->hand_state = TLS_ST_SR_KEY_UPDATE; return 1; } + + if (mt == DTLS13_MT_ACK) { + st->pre_ack_hand_state = st->hand_state; + st->hand_state = TLS_ST_SR_ACK; + return 1; + } break; } @@ -191,7 +221,7 @@ int ossl_statem_server_read_transition(SSL_CONNECTION *s, int mt) { OSSL_STATEM *st = &s->statem; - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { if (!ossl_statem_server13_read_transition(s, mt)) goto err; return 1; @@ -392,7 +422,7 @@ int send_certificate_request(SSL_CONNECTION *s) * don't request if post-handshake-only unless doing * post-handshake in TLSv1.3: */ - && (!SSL_CONNECTION_IS_TLS13(s) + && (!SSL_CONNECTION_IS_VERSION13(s) || !(s->verify_mode & SSL_VERIFY_POST_HANDSHAKE) || s->post_handshake_auth == SSL_PHA_REQUEST_PENDING) /* @@ -581,8 +611,15 @@ static int do_compressed_cert(SSL_CONNECTION *sc) */ static WRITE_TRAN ossl_statem_server13_write_transition(SSL_CONNECTION *s) { + OSSL_HANDSHAKE_STATE next_state; OSSL_STATEM *st = &s->statem; + if (st->ack_for_retransmit && st->hand_state != TLS_ST_SW_ACK) { + st->deferred_ack_state = st->hand_state; + st->hand_state = TLS_ST_SW_ACK; + return WRITE_TRAN_CONTINUE; + } + /* * No case for TLS_ST_BEFORE, because at that stage we have not negotiated * TLSv1.3 yet, so that is handled by ossl_statem_server_write_transition() @@ -615,7 +652,7 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL_CONNECTION *s) return WRITE_TRAN_CONTINUE; case TLS_ST_SW_SRVR_HELLO: - if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0 + if (SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s) && s->hello_retry_request != SSL_HRR_COMPLETE) st->hand_state = TLS_ST_SW_CHANGE; else if (s->hello_retry_request == SSL_HRR_PENDING) @@ -685,7 +722,13 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL_CONNECTION *s) * If we're not going to renew the ticket then we just finish the * handshake at this point. */ - st->hand_state = TLS_ST_OK; + if (SSL_CONNECTION_IS_DTLS13(s)) { + st->deferred_ack_state = TLS_ST_OK; + st->hand_state = TLS_ST_SW_ACK; + } else { + st->hand_state = TLS_ST_OK; + } + return WRITE_TRAN_CONTINUE; } /* @@ -701,7 +744,7 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL_CONNECTION *s) * parameters such as new_session_count = 0 or resumption_count = 0, is * effectively signaling no interest in session tickets or resumption. * - * RFC 8446 section 4.2.9: Servers MUST NOT select a key exchange mode + * RFC 9846 section 4.3.9: Servers MUST NOT select a key exchange mode * that is not listed by the client. This extension also restricts the * modes for use with PSK resumption. Servers SHOULD NOT send * NewSessionTicket with tickets that are not compatible with the @@ -712,22 +755,42 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL_CONNECTION *s) * session tickets or resumption (e.g. new_session_count = 0 or * resumption_count = 0), this implementation does not currently * interpret or enforce those parameters. + * + * Also skip issuance when SSL_VERIFY_PEER is set with no sid_ctx + * configured: any ticket minted here would be rejected by + * ssl_get_prev_session() in that configuration. */ - if (((s->options & SSL_OP_NO_TICKET) != 0 + if (s->num_tickets <= s->sent_tickets + || ((s->options & SSL_OP_NO_TICKET) != 0 && (SSL_CONNECTION_GET_CTX(s)->session_cache_mode & SSL_SESS_CACHE_SERVER) == 0) - || s->ext.psk_kex_mode == TLSEXT_KEX_MODE_FLAG_NONE) { - st->hand_state = TLS_ST_OK; - } else if (s->num_tickets > s->sent_tickets) { - st->hand_state = TLS_ST_SW_SESSION_TICKET; + || s->ext.psk_kex_mode == TLSEXT_KEX_MODE_FLAG_NONE + || ((s->verify_mode & SSL_VERIFY_PEER) != 0 && s->sid_ctx_length == 0)) + next_state = TLS_ST_OK; + else + next_state = TLS_ST_SW_SESSION_TICKET; + + if (SSL_CONNECTION_IS_DTLS13(s)) { + st->deferred_ack_state = next_state; + st->hand_state = TLS_ST_SW_ACK; } else { - st->hand_state = TLS_ST_OK; + st->hand_state = next_state; } return WRITE_TRAN_CONTINUE; case TLS_ST_SR_KEY_UPDATE: + if (SSL_CONNECTION_IS_DTLS13(s)) { + st->deferred_ack_state = TLS_ST_OK; + st->hand_state = TLS_ST_SW_ACK; + return WRITE_TRAN_CONTINUE; + } + /* Fall through */ case TLS_ST_SW_KEY_UPDATE: - st->hand_state = TLS_ST_OK; + if (SSL_CONNECTION_IS_DTLS13(s)) + /* We wait for ACK */ + return WRITE_TRAN_FINISHED; + else + st->hand_state = TLS_ST_OK; return WRITE_TRAN_CONTINUE; case TLS_ST_SW_SESSION_TICKET: @@ -735,13 +798,30 @@ static WRITE_TRAN ossl_statem_server13_write_transition(SSL_CONNECTION *s) * Following an initial handshake we send the number of tickets we have * been configured for. */ - if (!SSL_IS_FIRST_HANDSHAKE(s) && s->ext.extra_tickets_expected > 0) { - return WRITE_TRAN_CONTINUE; - } else if (s->hit || s->num_tickets <= s->sent_tickets) { + if ((SSL_IS_FIRST_HANDSHAKE(s) || s->ext.extra_tickets_expected <= 0) + && (s->hit || s->num_tickets <= s->sent_tickets)) { /* We've written enough tickets out. */ st->hand_state = TLS_ST_OK; } return WRITE_TRAN_CONTINUE; + + case TLS_ST_SR_ACK: + if (SSL_CONNECTION_IS_DTLS13(s) + && dtls_any_sent_messages_are_missing_acknowledge(s)) { + /* We wait for ACK */ + return WRITE_TRAN_FINISHED; + } + st->hand_state = TLS_ST_OK; + return WRITE_TRAN_CONTINUE; + + case TLS_ST_SW_ACK: + st->hand_state = st->deferred_ack_state; + if (st->ack_for_retransmit) { + st->ack_for_retransmit = 0; + return WRITE_TRAN_FINISHED; + } + + return WRITE_TRAN_CONTINUE; } } @@ -758,7 +838,7 @@ WRITE_TRAN ossl_statem_server_write_transition(SSL_CONNECTION *s) * to negotiate yet, so we don't take this branch until later */ - if (SSL_CONNECTION_IS_TLS13(s)) + if (SSL_CONNECTION_IS_VERSION13(s)) return ossl_statem_server13_write_transition(s); switch (st->hand_state) { @@ -790,7 +870,7 @@ WRITE_TRAN ossl_statem_server_write_transition(SSL_CONNECTION *s) return WRITE_TRAN_CONTINUE; case TLS_ST_SR_CLNT_HELLO: - if (SSL_CONNECTION_IS_DTLS(s) && !s->d1->cookie_verified + if (SSL_CONNECTION_IS_DTLS(s) && !SSL_CONNECTION_IS_DTLS13(s) && !s->d1->cookie_verified && (SSL_get_options(SSL_CONNECTION_GET_SSL(s)) & SSL_OP_COOKIE_EXCHANGE)) { st->hand_state = DTLS_ST_SW_HELLO_VERIFY_REQUEST; } else if (s->renegotiate == 0 && !SSL_IS_FIRST_HANDSHAKE(s)) { @@ -884,6 +964,70 @@ WRITE_TRAN ossl_statem_server_write_transition(SSL_CONNECTION *s) } } +static int ossl_statem_dtls_server13_use_timer(SSL_CONNECTION *s) +{ + OSSL_STATEM *st = &s->statem; + + switch (st->hand_state) { + default: + break; + + case TLS_ST_SW_ACK: + /* Fall through */ + + case TLS_ST_OK: + return 0; + } + + return 1; +} + +int ossl_statem_dtls_server_use_timer(SSL_CONNECTION *s) +{ + OSSL_STATEM *st = &s->statem; + + if (SSL_CONNECTION_IS_DTLS13(s)) + return ossl_statem_dtls_server13_use_timer(s); + + switch (st->hand_state) { + default: + break; + + case TLS_ST_SW_SESSION_TICKET: + /* + * We're into the last flight. We don't retransmit the last flight + * unless we need to, so we don't use the timer + */ + st->use_timer = 0; + break; + + case TLS_ST_SW_CHANGE: + /* + * We're into the last flight. We don't retransmit the last flight + * unless we need to, so we don't use the timer. This might have + * already been set to 0 if we sent a NewSessionTicket message, + * but we'll set it again here in case we didn't. + */ + st->use_timer = 0; + break; + + case DTLS_ST_SW_HELLO_VERIFY_REQUEST: + /* We don't buffer this message so don't use the timer */ + st->use_timer = 0; + break; + + case TLS_ST_SW_SRVR_HELLO: + /* + * Messages we write from now on should be buffered and + * retransmitted if necessary, so we need to use the timer now + */ + st->use_timer = 1; + break; + } + + return st->use_timer; +} + /* * Perform any pre work that needs to be done prior to sending a message from * the server to the client. @@ -899,28 +1043,12 @@ WORK_STATE ossl_statem_server_pre_work(SSL_CONNECTION *s, WORK_STATE wst) break; case TLS_ST_SW_HELLO_REQ: - s->shutdown = 0; - if (SSL_CONNECTION_IS_DTLS(s)) - dtls1_clear_sent_buffer(s); - break; - + /* fall-through */ case DTLS_ST_SW_HELLO_VERIFY_REQUEST: s->shutdown = 0; - if (SSL_CONNECTION_IS_DTLS(s)) { - dtls1_clear_sent_buffer(s); - /* We don't buffer this message so don't use the timer */ - st->use_timer = 0; - } - break; + if (SSL_CONNECTION_IS_DTLS(s)) + dtls1_clear_sent_buffer(s, 0); - case TLS_ST_SW_SRVR_HELLO: - if (SSL_CONNECTION_IS_DTLS(s)) { - /* - * Messages we write from now on should be buffered and - * retransmitted if necessary, so we need to use the timer now - */ - st->use_timer = 1; - } break; case TLS_ST_SW_SRVR_DONE: @@ -933,7 +1061,7 @@ WORK_STATE ossl_statem_server_pre_work(SSL_CONNECTION *s, WORK_STATE wst) return WORK_FINISHED_CONTINUE; case TLS_ST_SW_SESSION_TICKET: - if (SSL_CONNECTION_IS_TLS13(s) && s->sent_tickets == 0 + if (SSL_CONNECTION_IS_VERSION13(s) && s->sent_tickets == 0 && s->ext.extra_tickets_expected == 0) { /* * Actually this is the end of the handshake, but we're going @@ -944,17 +1072,10 @@ WORK_STATE ossl_statem_server_pre_work(SSL_CONNECTION *s, WORK_STATE wst) */ return tls_finish_handshake(s, wst, 0, 0); } - if (SSL_CONNECTION_IS_DTLS(s)) { - /* - * We're into the last flight. We don't retransmit the last flight - * unless we need to, so we don't use the timer - */ - st->use_timer = 0; - } break; case TLS_ST_SW_CHANGE: - if (SSL_CONNECTION_IS_TLS13(s)) + if (SSL_CONNECTION_IS_VERSION13(s)) break; /* Writes to s->session are only safe for initial handshakes */ if (s->session->cipher == NULL) { @@ -967,15 +1088,6 @@ WORK_STATE ossl_statem_server_pre_work(SSL_CONNECTION *s, WORK_STATE wst) /* SSLfatal() already called */ return WORK_ERROR; } - if (SSL_CONNECTION_IS_DTLS(s)) { - /* - * We're into the last flight. We don't retransmit the last flight - * unless we need to, so we don't use the timer. This might have - * already been set to 0 if we sent a NewSessionTicket message, - * but we'll set it again here in case we didn't. - */ - st->use_timer = 0; - } return WORK_FINISHED_CONTINUE; case TLS_ST_EARLY_DATA: @@ -987,7 +1099,7 @@ WORK_STATE ossl_statem_server_pre_work(SSL_CONNECTION *s, WORK_STATE wst) * In QUIC with 0-RTT we just carry on when otherwise we would stop * to allow the server to read early data */ - if (SSL_NO_EOED(s) && s->ext.early_data == SSL_EARLY_DATA_ACCEPTED + if (SSL_IS_QUIC_HANDSHAKE(s) && s->ext.early_data == SSL_EARLY_DATA_ACCEPTED && s->early_data_state != SSL_EARLY_DATA_FINISHED_READING) { s->early_data_state = SSL_EARLY_DATA_FINISHED_READING; if (!ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_READ)) { @@ -1067,15 +1179,20 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst) break; case TLS_ST_SW_SRVR_HELLO: - if (SSL_CONNECTION_IS_TLS13(s) + if (SSL_CONNECTION_IS_VERSION13(s) && s->hello_retry_request == SSL_HRR_PENDING) { - if ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) == 0 + if (!SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s) && statem_flush(s) != 1) return WORK_MORE_A; break; } #ifndef OPENSSL_NO_SCTP - if (SSL_CONNECTION_IS_DTLS(s) && s->hit) { + /* + * Before exporting the SCTP auth key we check if DTLSv1.3 has been negotiated + * which is not supported. + * Refer to draft-tuexen-tsvwg-rfc6083-bis-04 for more info. + */ + if (SSL_CONNECTION_IS_DTLS(s) && !SSL_CONNECTION_IS_DTLS13(s) && s->hit) { unsigned char sctpauthkey[64]; char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; size_t labellen; @@ -1105,8 +1222,8 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst) sizeof(sctpauthkey), sctpauthkey); } #endif - if (!SSL_CONNECTION_IS_TLS13(s) - || ((s->options & SSL_OP_ENABLE_MIDDLEBOX_COMPAT) != 0 + if (!SSL_CONNECTION_IS_VERSION13(s) + || (SSL_CONNECTION_MIDDLEBOX_IS_ENABLED(s) && s->hello_retry_request != SSL_HRR_COMPLETE)) break; /* Fall through */ @@ -1118,7 +1235,7 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst) break; } - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { if (!ssl->method->ssl3_enc->setup_key_block(s) || !tls13_store_handshake_traffic_hash(s) || !ssl->method->ssl3_enc->change_cipher_state(s, @@ -1127,11 +1244,14 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst) return WORK_ERROR; } - if (s->ext.early_data != SSL_EARLY_DATA_ACCEPTED + if (!SSL_CONNECTION_IS_DTLS13(s) + && s->ext.early_data != SSL_EARLY_DATA_ACCEPTED && !ssl->method->ssl3_enc->change_cipher_state(s, SSL3_CC_HANDSHAKE | SSL3_CHANGE_CIPHER_SERVER_READ)) { /* SSLfatal() already called */ return WORK_ERROR; + } else { + s->dtls13_process_hello = 1; } /* * We don't yet know whether the next record we are going to receive @@ -1178,8 +1298,8 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst) 0, NULL); } #endif - if (SSL_CONNECTION_IS_TLS13(s)) { - /* TLS 1.3 gets the secret size from the handshake md */ + if (SSL_CONNECTION_IS_VERSION13(s)) { + /* (D)TLS 1.3 gets the secret size from the handshake md */ size_t dummy; if (!ssl->method->ssl3_enc->generate_master_secret(s, s->master_secret, s->handshake_secret, 0, @@ -1197,7 +1317,7 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst) if (statem_flush(s) != 1) return WORK_MORE_A; } else { - if (!SSL_CONNECTION_IS_TLS13(s) + if (!SSL_CONNECTION_IS_VERSION13(s) || (s->options & SSL_OP_NO_TX_CERTIFICATE_COMPRESSION) != 0) s->ext.compress_certificate_from_peer[0] = TLSEXT_comp_cert_none; } @@ -1205,7 +1325,7 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst) case TLS_ST_SW_ENCRYPTED_EXTENSIONS: if (!s->hit && !send_certificate_request(s)) { - if (!SSL_CONNECTION_IS_TLS13(s) + if (!SSL_CONNECTION_IS_VERSION13(s) || (s->options & SSL_OP_NO_TX_CERTIFICATE_COMPRESSION) != 0) s->ext.compress_certificate_from_peer[0] = TLSEXT_comp_cert_none; } @@ -1222,7 +1342,7 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst) case TLS_ST_SW_SESSION_TICKET: clear_sys_error(); - if (SSL_CONNECTION_IS_TLS13(s) && statem_flush(s) != 1) { + if (SSL_CONNECTION_IS_VERSION13(s) && statem_flush(s) != 1) { if (SSL_get_error(ssl, 0) == SSL_ERROR_SYSCALL && conn_is_closed()) { /* @@ -1240,6 +1360,11 @@ WORK_STATE ossl_statem_server_post_work(SSL_CONNECTION *s, WORK_STATE wst) } ERR_clear_last_mark(); break; + + case TLS_ST_SW_ACK: + if (statem_flush(s) != 1) + return WORK_MORE_A; + break; } return WORK_FINISHED_CONTINUE; @@ -1349,6 +1474,11 @@ int ossl_statem_server_construct_message(SSL_CONNECTION *s, *confunc = tls_construct_key_update; *mt = SSL3_MT_KEY_UPDATE; break; + + case TLS_ST_SW_ACK: + *confunc = dtls_construct_ack; + *mt = DTLS13_MT_ACK; + break; } return 1; @@ -1416,6 +1546,9 @@ size_t ossl_statem_server_max_message_size(SSL_CONNECTION *s) case TLS_ST_SR_KEY_UPDATE: return KEY_UPDATE_MAX_LENGTH; + + case TLS_ST_SR_ACK: + return ACK_MAX_LENGTH; } } @@ -1466,6 +1599,9 @@ MSG_PROCESS_RETURN ossl_statem_server_process_message(SSL_CONNECTION *s, case TLS_ST_SR_KEY_UPDATE: return tls_process_key_update(s, pkt); + + case TLS_ST_SR_ACK: + return dtls_process_ack(s, pkt); } } @@ -1487,6 +1623,12 @@ WORK_STATE ossl_statem_server_post_process_message(SSL_CONNECTION *s, case TLS_ST_SR_CLNT_HELLO: return tls_post_process_client_hello(s, wst); + case TLS_ST_SR_CERT: +#ifndef OPENSSL_NO_COMP_ALG + case TLS_ST_SR_COMP_CERT: +#endif + return tls_post_process_client_certificate(s, wst); + case TLS_ST_SR_KEY_EXCH: return tls_post_process_client_key_exchange(s, wst); } @@ -1539,14 +1681,23 @@ int dtls_raw_hello_verify_request(WPACKET *pkt, unsigned char *cookie, CON_FUNC_RETURN dtls_construct_hello_verify_request(SSL_CONNECTION *s, WPACKET *pkt) { - unsigned int cookie_leni; + unsigned int cookie_leni = 0; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + SSL *ussl = SSL_CONNECTION_GET_USER_SSL(s); + int cb_ret = 0; + +#if !defined(OPENSSL_NO_DTLS) + DTLS_LISTENER *dl = (DTLS_LISTENER *)s->d1->listener; + + if (dl != NULL && dl->require_hvr_cookie && sctx->app_gen_cookie_cb == NULL) { + cb_ret = ossl_dtls_listener_gen_cookie_cb(ussl, s->d1->cookie, &cookie_leni); + } else +#endif + if (sctx->app_gen_cookie_cb != NULL) { + cb_ret = sctx->app_gen_cookie_cb(ussl, s->d1->cookie, &cookie_leni); + } - if (sctx->app_gen_cookie_cb == NULL - || sctx->app_gen_cookie_cb(SSL_CONNECTION_GET_USER_SSL(s), s->d1->cookie, - &cookie_leni) - == 0 - || cookie_leni > sizeof(s->d1->cookie)) { + if (cb_ret == 0 || cookie_leni > sizeof(s->d1->cookie)) { SSLfatal(s, SSL_AD_NO_ALERT, SSL_R_COOKIE_GEN_CALLBACK_FAILURE); return CON_FUNC_ERROR; } @@ -1558,6 +1709,12 @@ CON_FUNC_RETURN dtls_construct_hello_verify_request(SSL_CONNECTION *s, return CON_FUNC_ERROR; } + /* + * Server must recover the downgrade sentinel in case it sends a + * HelloVerifyRequest. + */ + s->d1->hello_verify_request = SSL_HVR_SENT; + return CON_FUNC_SUCCESS; } @@ -1757,7 +1914,7 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL_CONNECTION *s, PACKET *pkt) /* Check if this is actually an unexpected renegotiation ClientHello */ if (s->renegotiate == 0 && !SSL_IS_FIRST_HANDSHAKE(s)) { - if (!ossl_assert(!SSL_CONNECTION_IS_TLS13(s))) { + if (!ossl_assert(!SSL_CONNECTION_IS_VERSION13(s))) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } @@ -1799,26 +1956,35 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL_CONNECTION *s, PACKET *pkt) } if (SSL_CONNECTION_IS_DTLS(s)) { + int minversion, maxversion; + if (!PACKET_get_length_prefixed_1(pkt, &cookie)) { SSLfatal(s, SSL_AD_DECODE_ERROR, SSL_R_LENGTH_MISMATCH); goto err; } if (!PACKET_copy_all(&cookie, clienthello->dtls_cookie, - DTLS1_COOKIE_LENGTH, + sizeof(clienthello->dtls_cookie), &clienthello->dtls_cookie_len)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } + /* - * If we require cookies and this ClientHello doesn't contain one, - * just return since we do not want to allocate any memory yet. - * So check cookie length... + * If the connection supports DTLSv1.3: + * We continue to process ClientHello's without cookies + * + * Otherwise, if we require cookies and this ClientHello doesn't + * contain one: + * Return since we do not want to allocate any memory yet */ - if (SSL_get_options(SSL_CONNECTION_GET_SSL(s)) & SSL_OP_COOKIE_EXCHANGE) { - if (clienthello->dtls_cookie_len == 0) { - OPENSSL_free(clienthello); - return MSG_PROCESS_FINISHED_READING; - } + if ((SSL_get_options(SSL_CONNECTION_GET_SSL(s)) & SSL_OP_COOKIE_EXCHANGE) + && clienthello->dtls_cookie_len == 0 + && ossl_assert(ssl_get_min_max_version(s, &minversion, + &maxversion, NULL) + == 0) + && ssl_version_cmp(s, maxversion, DTLS1_3_VERSION) < 0) { + OPENSSL_free(clienthello); + return MSG_PROCESS_FINISHED_READING; } } @@ -1858,6 +2024,32 @@ MSG_PROCESS_RETURN tls_process_client_hello(SSL_CONNECTION *s, PACKET *pkt) /* SSLfatal already been called */ goto err; } + + if (SSL_CONNECTION_IS_DTLS(s)) { + int minversion, maxversion; + + /* + * If the connection supports DTLSv1.3 or if the ClientHello was sent + * with the SupportedVersions extension: + * We continue to process ClientHello's without cookies + * + * Otherwise, if we require cookies and this ClientHello doesn't + * contain one: + * Return since we do not want to allocate any memory yet + */ + if ((SSL_get_options(SSL_CONNECTION_GET_SSL(s)) & SSL_OP_COOKIE_EXCHANGE) + && clienthello->dtls_cookie_len == 0 + && ossl_assert(ssl_get_min_max_version(s, &minversion, + &maxversion, NULL) + == 0) + && ssl_version_cmp(s, maxversion, DTLS1_3_VERSION) < 0 + && !clienthello->pre_proc_exts[TLSEXT_IDX_supported_versions].present) { + OPENSSL_free(clienthello->pre_proc_exts); + OPENSSL_free(clienthello); + return MSG_PROCESS_FINISHED_READING; + } + } + s->clienthello = clienthello; return MSG_PROCESS_CONTINUE_PROCESSING; @@ -1932,29 +2124,38 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) } /* TLSv1.3 specifies that a ClientHello must end on a record boundary */ - if (SSL_CONNECTION_IS_TLS13(s) + if (SSL_CONNECTION_IS_VERSION13(s) && RECORD_LAYER_processed_read_pending(&s->rlayer)) { SSLfatal(s, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_NOT_ON_RECORD_BOUNDARY); goto err; } - if (SSL_CONNECTION_IS_DTLS(s)) { - /* Empty cookie was already handled above by returning early. */ - if (SSL_get_options(ssl) & SSL_OP_COOKIE_EXCHANGE) { - if (sctx->app_verify_cookie_cb != NULL) { - if (sctx->app_verify_cookie_cb(ussl, clienthello->dtls_cookie, - (unsigned int)clienthello->dtls_cookie_len) - == 0) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, - SSL_R_COOKIE_MISMATCH); - goto err; - /* else cookie verification succeeded */ - } - /* default verification */ - } else if (s->d1->cookie_len != clienthello->dtls_cookie_len - || memcmp(clienthello->dtls_cookie, s->d1->cookie, + if ((SSL_get_options(ssl) & SSL_OP_COOKIE_EXCHANGE) && clienthello->dtls_cookie_len != 0) { + int verify_ret = 0; + +#if !defined(OPENSSL_NO_DTLS) + DTLS_LISTENER *dl = (s->d1 != NULL && s->d1->listener != NULL) + ? (DTLS_LISTENER *)s->d1->listener + : NULL; + + if (dl != NULL && dl->require_hvr_cookie && sctx->app_verify_cookie_cb == NULL) { + verify_ret = ossl_dtls_listener_verify_cookie_cb(ussl, + clienthello->dtls_cookie, + (unsigned int)clienthello->dtls_cookie_len); + } else +#endif + if (sctx->app_verify_cookie_cb != NULL) { + verify_ret = sctx->app_verify_cookie_cb(ussl, clienthello->dtls_cookie, + (unsigned int)clienthello->dtls_cookie_len); + } else if (s->d1->cookie_len == clienthello->dtls_cookie_len + && memcmp(clienthello->dtls_cookie, s->d1->cookie, s->d1->cookie_len) - != 0) { + == 0) { + /* default verification succeeded */ + verify_ret = 1; + } + + if (verify_ret == 0) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_COOKIE_MISMATCH); goto err; } @@ -1999,7 +2200,7 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) } /* For TLSv1.3 we must select the ciphersuite *before* session resumption */ - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { const SSL_CIPHER *cipher = ssl3_choose_cipher(s, ciphers, SSL_get_ciphers(ssl)); if (cipher == NULL) { @@ -2065,7 +2266,7 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) } } - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { memcpy(s->tmp_session_id, s->clienthello->session_id, s->clienthello->session_id_len); s->tmp_session_id_len = s->clienthello->session_id_len; @@ -2075,7 +2276,7 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) * If it is a hit, check that the cipher is in the list. In TLSv1.3 we check * ciphersuite compatibility with the session as part of resumption. */ - if (!SSL_CONNECTION_IS_TLS13(s) && s->hit) { + if (!SSL_CONNECTION_IS_VERSION13(s) && s->hit) { j = 0; id = s->session->cipher->id; @@ -2165,7 +2366,7 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) #endif !s->hit && s->version >= TLS1_VERSION - && !SSL_CONNECTION_IS_TLS13(s) + && !SSL_CONNECTION_IS_VERSION13(s) && !SSL_CONNECTION_IS_DTLS(s) && s->ext.session_secret_cb != NULL) { const SSL_CIPHER *pref_cipher = NULL; @@ -2225,7 +2426,7 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) * algorithms from the client, starting at q. */ s->s3.tmp.new_compression = NULL; - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { /* * We already checked above that the NULL compression method appears in * the list. Now we check there aren't any others (which is illegal in @@ -2312,7 +2513,7 @@ static int tls_early_post_process_client_hello(SSL_CONNECTION *s) * Given s->peer_ciphers and SSL_get_ciphers, we must pick a cipher */ - if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) { + if (!s->hit || SSL_CONNECTION_IS_VERSION13(s)) { sk_SSL_CIPHER_free(s->peer_ciphers); s->peer_ciphers = ciphers; if (ciphers == NULL) { @@ -2502,7 +2703,7 @@ WORK_STATE tls_post_process_client_hello(SSL_CONNECTION *s, WORK_STATE wst) wst = WORK_MORE_B; } if (wst == WORK_MORE_B) { - if (!s->hit || SSL_CONNECTION_IS_TLS13(s)) { + if (!s->hit || SSL_CONNECTION_IS_VERSION13(s)) { /* Let cert callback update server certificates if required */ if (!s->hit && s->cert->cert_cb != NULL) { int rv = s->cert->cert_cb(ussl, s->cert->cert_cb_arg); @@ -2519,7 +2720,7 @@ WORK_STATE tls_post_process_client_hello(SSL_CONNECTION *s, WORK_STATE wst) } /* In TLSv1.3 we selected the ciphersuite before resumption */ - if (!SSL_CONNECTION_IS_TLS13(s)) { + if (!SSL_CONNECTION_IS_VERSION13(s)) { cipher = ssl3_choose_cipher(s, s->peer_ciphers, SSL_get_ciphers(ssl)); @@ -2564,7 +2765,7 @@ WORK_STATE tls_post_process_client_hello(SSL_CONNECTION *s, WORK_STATE wst) * we already did this because cipher negotiation happens earlier, and * we must handle ALPN before we decide whether to accept early_data. */ - if (!SSL_CONNECTION_IS_TLS13(s) && !tls_handle_alpn(s)) { + if (!SSL_CONNECTION_IS_VERSION13(s) && !tls_handle_alpn(s)) { /* SSLfatal() already called */ goto err; } @@ -2600,9 +2801,13 @@ CON_FUNC_RETURN tls_construct_server_hello(SSL_CONNECTION *s, WPACKET *pkt) int version; unsigned char *session_id; int usetls13 = SSL_CONNECTION_IS_TLS13(s) - || s->hello_retry_request == SSL_HRR_PENDING; + || (!SSL_CONNECTION_IS_DTLS(s) + && s->hello_retry_request == SSL_HRR_PENDING); + int usedtls13 = SSL_CONNECTION_IS_DTLS13(s) + || (SSL_CONNECTION_IS_DTLS(s) + && s->hello_retry_request == SSL_HRR_PENDING); - version = usetls13 ? TLS1_2_VERSION : s->version; + version = usetls13 ? TLS1_2_VERSION : (usedtls13 ? DTLS1_2_VERSION : s->version); if (!WPACKET_put_bytes_u16(pkt, version) /* * Random stuff. Filling of the server_random takes place in @@ -2631,6 +2836,7 @@ CON_FUNC_RETURN tls_construct_server_hello(SSL_CONNECTION *s, WPACKET *pkt) * we send back a 0-length session ID. * - In TLSv1.3 we echo back the session id sent to us by the client * regardless + * - In DTLSv1.3 we must not echo the session id sent by the client * s->hit is non-zero in either case of session reuse, * so the following won't overwrite an ID that we're supposed * to send back. @@ -2642,6 +2848,9 @@ CON_FUNC_RETURN tls_construct_server_hello(SSL_CONNECTION *s, WPACKET *pkt) if (usetls13) { sl = s->tmp_session_id_len; session_id = s->tmp_session_id; + } else if (usedtls13) { + sl = 0; + session_id = NULL; } else { sl = s->session->session_id_length; session_id = s->session->session_id; @@ -2656,7 +2865,7 @@ CON_FUNC_RETURN tls_construct_server_hello(SSL_CONNECTION *s, WPACKET *pkt) #ifdef OPENSSL_NO_COMP compm = 0; #else - if (usetls13 || s->s3.tmp.new_compression == NULL) + if (usetls13 || usedtls13 || s->s3.tmp.new_compression == NULL) compm = 0; else compm = s->s3.tmp.new_compression->id; @@ -2673,7 +2882,7 @@ CON_FUNC_RETURN tls_construct_server_hello(SSL_CONNECTION *s, WPACKET *pkt) if (!tls_construct_extensions(s, pkt, s->hello_retry_request == SSL_HRR_PENDING ? SSL_EXT_TLS1_3_HELLO_RETRY_REQUEST - : (SSL_CONNECTION_IS_TLS13(s) + : (SSL_CONNECTION_IS_VERSION13(s) ? SSL_EXT_TLS1_3_SERVER_HELLO : SSL_EXT_TLS1_2_SERVER_HELLO), NULL, 0)) { @@ -3178,7 +3387,7 @@ CON_FUNC_RETURN tls_construct_server_key_exchange(SSL_CONNECTION *s, CON_FUNC_RETURN tls_construct_certificate_request(SSL_CONNECTION *s, WPACKET *pkt) { - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { /* Send random context when doing post-handshake auth */ if (s->post_handshake_auth == SSL_PHA_REQUEST_PENDING) { OPENSSL_free(s->pha_context); @@ -3562,7 +3771,8 @@ static int tls_process_cke_gost(SSL_CONNECTION *s, PACKET *pkt) EVP_PKEY *client_pub_pkey = NULL, *pk = NULL; unsigned char premaster_secret[32]; const unsigned char *start; - size_t outlen = sizeof(premaster_secret), inlen; + size_t outlen = sizeof(premaster_secret); + size_t inlen; unsigned long alg_a; GOST_KX_MESSAGE *pKX = NULL; const unsigned char *ptr; @@ -3628,7 +3838,10 @@ static int tls_process_cke_gost(SSL_CONNECTION *s, PACKET *pkt) goto err; } - inlen = ASN1_STRING_length(pKX->kxBlob->value.sequence); + inlen = ASN1_STRING_get_length(pKX->kxBlob->value.sequence); + if (inlen > INT_MAX) + goto err; + start = ASN1_STRING_get0_data(pKX->kxBlob->value.sequence); if (EVP_PKEY_decrypt(pkey_ctx, premaster_secret, &outlen, start, @@ -3811,7 +4024,12 @@ WORK_STATE tls_post_process_client_key_exchange(SSL_CONNECTION *s, { #ifndef OPENSSL_NO_SCTP if (wst == WORK_MORE_A) { - if (SSL_CONNECTION_IS_DTLS(s)) { + /* + * Before exporting the SCTP auth key we check if DTLSv1.3 has been + * negotiated which is not supported. + * Refer to draft-tuexen-tsvwg-rfc6083-bis-04 for more info. + */ + if (SSL_CONNECTION_IS_DTLS(s) && !SSL_CONNECTION_IS_DTLS13(s)) { unsigned char sctpauthkey[64]; char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; size_t labellen; @@ -3873,27 +4091,50 @@ WORK_STATE tls_post_process_client_key_exchange(SSL_CONNECTION *s, MSG_PROCESS_RETURN tls_process_client_rpk(SSL_CONNECTION *sc, PACKET *pkt) { - MSG_PROCESS_RETURN ret = MSG_PROCESS_ERROR; - SSL_SESSION *new_sess = NULL; EVP_PKEY *peer_rpk = NULL; if (!tls_process_rpk(sc, pkt, &peer_rpk)) { /* SSLfatal already called */ - goto err; + return MSG_PROCESS_ERROR; } + /* Stash the parsed RPK; verification runs in the post-process step. */ + EVP_PKEY_free(sc->session->peer_rpk); + sc->session->peer_rpk = peer_rpk; + + return MSG_PROCESS_CONTINUE_PROCESSING; +} + +/* Verify the parked RPK; may pause via SSL_set_retry_verify(). */ +static WORK_STATE tls_post_process_client_rpk(SSL_CONNECTION *sc, + WORK_STATE wst) +{ + EVP_PKEY *peer_rpk = sc->session->peer_rpk; + SSL_SESSION *new_sess = NULL; + + (void)wst; + if (peer_rpk == NULL) { if ((sc->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) && (sc->verify_mode & SSL_VERIFY_PEER)) { SSLfatal(sc, SSL_AD_CERTIFICATE_REQUIRED, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); - goto err; + return WORK_ERROR; } } else { - if (ssl_verify_rpk(sc, peer_rpk) <= 0) { + int v_ok; + + if (sc->rwstate == SSL_RETRY_VERIFY) + sc->rwstate = SSL_NOTHING; + v_ok = ssl_verify_rpk(sc, peer_rpk); + if (v_ok > 0 && sc->rwstate == SSL_RETRY_VERIFY) { + /* The verify callback asked to pause; resume here on retry. */ + return WORK_MORE_A; + } + if (v_ok <= 0) { SSLfatal(sc, ssl_x509err2alert(sc->verify_result), SSL_R_CERTIFICATE_VERIFY_FAILED); - goto err; + return WORK_ERROR; } } @@ -3904,11 +4145,10 @@ MSG_PROCESS_RETURN tls_process_client_rpk(SSL_CONNECTION *sc, PACKET *pkt) * a new RPK (or certificate) is received via post-handshake authentication, * as the session may have already gone into the session cache. */ - if (sc->post_handshake_auth == SSL_PHA_REQUESTED) { if ((new_sess = ssl_session_dup(sc->session, 0)) == NULL) { SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_MALLOC_FAILURE); - goto err; + return WORK_ERROR; } SSL_SESSION_free(sc->session); @@ -3920,10 +4160,6 @@ MSG_PROCESS_RETURN tls_process_client_rpk(SSL_CONNECTION *sc, PACKET *pkt) sc->session->peer = NULL; sk_X509_pop_free(sc->session->peer_chain, X509_free); sc->session->peer_chain = NULL; - /* Save RPK */ - EVP_PKEY_free(sc->session->peer_rpk); - sc->session->peer_rpk = peer_rpk; - peer_rpk = NULL; sc->session->verify_result = sc->verify_result; @@ -3931,35 +4167,30 @@ MSG_PROCESS_RETURN tls_process_client_rpk(SSL_CONNECTION *sc, PACKET *pkt) * Freeze the handshake buffer. For cert_verify_hash, sizeof(sc->cert_verify_hash), &sc->cert_verify_hash_len)) { - /* SSLfatal() already called */; - goto err; + /* SSLfatal() already called */ + return WORK_ERROR; } /* resend session tickets */ sc->sent_tickets = 0; } - ret = MSG_PROCESS_CONTINUE_READING; - -err: - EVP_PKEY_free(peer_rpk); - return ret; + return WORK_FINISHED_CONTINUE; } MSG_PROCESS_RETURN tls_process_client_certificate(SSL_CONNECTION *s, PACKET *pkt) { - int i; MSG_PROCESS_RETURN ret = MSG_PROCESS_ERROR; X509 *x = NULL; unsigned long l; @@ -3967,7 +4198,6 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL_CONNECTION *s, STACK_OF(X509) *sk = NULL; PACKET spkt, context; size_t chainidx; - SSL_SESSION *new_sess = NULL; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); /* @@ -3991,7 +4221,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL_CONNECTION *s, goto err; } - if (SSL_CONNECTION_IS_TLS13(s) + if (SSL_CONNECTION_IS_VERSION13(s) && (!PACKET_get_length_prefixed_1(pkt, &context) || (s->pha_context == NULL && PACKET_remaining(&context) != 0) || (s->pha_context != NULL @@ -4030,7 +4260,7 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL_CONNECTION *s, goto err; } - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { RAW_EXTENSION *rawexts = NULL; PACKET extensions; @@ -4057,31 +4287,78 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL_CONNECTION *s, x = NULL; } - if (sk_X509_num(sk) <= 0) { + /* + * Stash the parsed chain so that tls_post_process_client_certificate() can + * run verification and may pause the handshake via SSL_set_retry_verify(). + */ + OSSL_STACK_OF_X509_free(s->session->peer_chain); + s->session->peer_chain = sk; + + return MSG_PROCESS_CONTINUE_PROCESSING; + +err: + X509_free(x); + OSSL_STACK_OF_X509_free(sk); + return ret; +} + +/* + * Verify s->session->peer_chain (parked by tls_process_client_certificate()) + * and finalize the peer cert / TLS 1.3 handshake-hash bookkeeping. + * Allows the verify callback to defer via SSL_set_retry_verify(), in which + * case we return WORK_MORE_A and the state machine re-enters this function + * once the application has supplied a verdict. + */ +WORK_STATE tls_post_process_client_certificate(SSL_CONNECTION *s, + WORK_STATE wst) +{ + STACK_OF(X509) *sk; + SSL_SESSION *new_sess = NULL; + EVP_PKEY *pkey; + int i; + + if (s->ext.client_cert_type == TLSEXT_cert_type_rpk) + return tls_post_process_client_rpk(s, wst); + + sk = s->session->peer_chain; + (void)wst; + + if (sk == NULL || sk_X509_num(sk) <= 0) { /* Fail only if we required a certificate */ - if ((s->verify_mode & SSL_VERIFY_PEER) && (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { + if ((s->verify_mode & SSL_VERIFY_PEER) + && (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { SSLfatal(s, SSL_AD_CERTIFICATE_REQUIRED, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); - goto err; + return WORK_ERROR; } /* No client certificate so digest cached records */ if (s->s3.handshake_buffer && !ssl3_digest_cached_records(s, 0)) { /* SSLfatal() already called */ - goto err; + return WORK_ERROR; } } else { - EVP_PKEY *pkey; + if (s->rwstate == SSL_RETRY_VERIFY) + s->rwstate = SSL_NOTHING; i = ssl_verify_cert_chain(s, sk); + if (i > 0 && s->rwstate == SSL_RETRY_VERIFY) { + /* + * The application's verify callback asked us to pause via + * SSL_set_retry_verify(); SSL_do_handshake() will return + * SSL_ERROR_WANT_RETRY_VERIFY and the state machine resumes here + * once the callback is invoked again. + */ + return WORK_MORE_A; + } if (i <= 0) { SSLfatal(s, ssl_x509err2alert(s->verify_result), SSL_R_CERTIFICATE_VERIFY_FAILED); - goto err; + return WORK_ERROR; } pkey = X509_get0_pubkey(sk_X509_value(sk, 0)); if (pkey == NULL) { SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_R_UNKNOWN_CERTIFICATE_TYPE); - goto err; + return WORK_ERROR; } } @@ -4092,24 +4369,25 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL_CONNECTION *s, * a new certificate is received via post-handshake authentication, as the * session may have already gone into the session cache. */ - if (s->post_handshake_auth == SSL_PHA_REQUESTED) { if ((new_sess = ssl_session_dup(s->session, 0)) == 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_SSL_LIB); - goto err; + return WORK_ERROR; } SSL_SESSION_free(s->session); s->session = new_sess; + /* peer_chain follows the session via ssl_session_dup(); refresh sk. */ + sk = s->session->peer_chain; } - X509_free(s->session->peer); - s->session->peer = sk_X509_shift(sk); - s->session->verify_result = s->verify_result; + if (sk != NULL && sk_X509_num(sk) > 0) { + X509_free(s->session->peer); + /* Server keeps the EE cert in session->peer; peer_chain holds issuers only. */ + s->session->peer = sk_X509_shift(sk); + s->session->verify_result = s->verify_result; + } - OSSL_STACK_OF_X509_free(s->session->peer_chain); - s->session->peer_chain = sk; - sk = NULL; /* Ensure there is no RPK */ EVP_PKEY_free(s->session->peer_rpk); s->session->peer_rpk = NULL; @@ -4118,35 +4396,25 @@ MSG_PROCESS_RETURN tls_process_client_certificate(SSL_CONNECTION *s, * Freeze the handshake buffer. For cert_verify_hash, sizeof(s->cert_verify_hash), &s->cert_verify_hash_len)) { /* SSLfatal() already called */ - goto err; + return WORK_ERROR; } /* Resend session tickets */ s->sent_tickets = 0; } - ret = MSG_PROCESS_CONTINUE_READING; - -err: - X509_free(x); - OSSL_STACK_OF_X509_free(sk); - return ret; + return WORK_FINISHED_CONTINUE; } #ifndef OPENSSL_NO_COMP_ALG @@ -4177,7 +4445,7 @@ CON_FUNC_RETURN tls_construct_server_certificate(SSL_CONNECTION *s, WPACKET *pkt * In TLSv1.3 the certificate chain is always preceded by a 0 length context * for the server Certificate message */ - if (SSL_CONNECTION_IS_TLS13(s) && !WPACKET_put_bytes_u8(pkt, 0)) { + if (SSL_CONNECTION_IS_VERSION13(s) && !WPACKET_put_bytes_u8(pkt, 0)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return CON_FUNC_ERROR; } @@ -4220,8 +4488,10 @@ CON_FUNC_RETURN tls_construct_server_compressed_certificate(SSL_CONNECTION *sc, || !WPACKET_put_bytes_u24(pkt, cc->orig_len) || !WPACKET_start_sub_packet_u24(pkt) || !WPACKET_memcpy(pkt, cc->data, cc->len) - || !WPACKET_close(pkt)) + || !WPACKET_close(pkt)) { + SSLfatal(sc, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; + } sc->s3.tmp.cert->cert_comp_used++; return 1; @@ -4236,13 +4506,13 @@ static int create_ticket_prequel(SSL_CONNECTION *s, WPACKET *pkt, /* * Ticket lifetime hint: * In TLSv1.3 we reset the "time" field above, and always specify the - * timeout, limited to a 1 week period per RFC8446. + * timeout, limited to a 1 week period per RFC9846. * For TLSv1.2 this is advisory only and we leave this unspecified for * resumed session (for simplicity). */ #define ONE_WEEK_SEC (7 * 24 * 60 * 60) - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { if (ossl_time_compare(s->session->timeout, ossl_seconds2time(ONE_WEEK_SEC)) > 0) @@ -4255,7 +4525,7 @@ static int create_ticket_prequel(SSL_CONNECTION *s, WPACKET *pkt, return 0; } - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { if (!WPACKET_put_bytes_u32(pkt, age_add) || !WPACKET_sub_memcpy_u8(pkt, tick_nonce, TICKET_NONCE_SIZE)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -4381,7 +4651,7 @@ static CON_FUNC_RETURN construct_stateless_ticket(SSL_CONNECTION *s, * length ticket is not allowed so we abort construction of the * ticket */ - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { ok = CON_FUNC_DONT_SEND; goto err; } @@ -4513,7 +4783,7 @@ CON_FUNC_RETURN tls_construct_new_session_ticket(SSL_CONNECTION *s, WPACKET *pkt age_add_u.age_add = 0; - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { size_t i, hashlen; uint64_t nonce; /* ASCII: "resumption", in hex for EBCDIC compatibility */ @@ -4538,7 +4808,7 @@ CON_FUNC_RETURN tls_construct_new_session_ticket(SSL_CONNECTION *s, WPACKET *pkt SSL_SESSION *new_sess = ssl_session_dup(s->session, 0); if (new_sess == NULL) { - /* SSLfatal already called */ + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_SSL_LIB); goto err; } @@ -4587,6 +4857,18 @@ CON_FUNC_RETURN tls_construct_new_session_ticket(SSL_CONNECTION *s, WPACKET *pkt goto err; } s->session->ext.alpn_selected_len = s->s3.alpn_selected_len; + } else { + /* + * No ALPN was negotiated on this handshake. If we resumed a + * session that had previously negotiated ALPN, the stale value + * must be cleared from the (copied) session before it is stored + * in the new ticket. Otherwise a subsequent 0-RTT attempt using + * that ticket would incorrectly assume an ALPN protocol had been + * negotiated. See tls_handle_alpn(). + */ + OPENSSL_free(s->session->ext.alpn_selected); + s->session->ext.alpn_selected = NULL; + s->session->ext.alpn_selected_len = 0; } s->session->ext.max_early_data = s->max_early_data; } @@ -4600,7 +4882,7 @@ CON_FUNC_RETURN tls_construct_new_session_ticket(SSL_CONNECTION *s, WPACKET *pkt * SSL_OP_NO_TICKET is set - we are caching tickets anyway so there * is no point in using full stateless tickets. */ - if (SSL_CONNECTION_IS_TLS13(s) + if (SSL_CONNECTION_IS_VERSION13(s) && ((s->options & SSL_OP_NO_TICKET) != 0 || (s->max_early_data > 0 && (s->options & SSL_OP_NO_ANTI_REPLAY) == 0))) { @@ -4625,7 +4907,7 @@ CON_FUNC_RETURN tls_construct_new_session_ticket(SSL_CONNECTION *s, WPACKET *pkt } } - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { if (!tls_construct_extensions(s, pkt, SSL_EXT_TLS1_3_NEW_SESSION_TICKET, NULL, 0)) { diff --git a/ssl/t1_enc.c b/ssl/t1_enc.c index bcd3082d6bf11..417c58672dcad 100644 --- a/ssl/t1_enc.c +++ b/ssl/t1_enc.c @@ -231,14 +231,16 @@ int tls1_change_cipher_state(SSL_CONNECTION *s, int which) direction = OSSL_RECORD_DIRECTION_WRITE; } - if (SSL_CONNECTION_IS_DTLS(s)) - dtls1_increment_epoch(s, which); + if (SSL_CONNECTION_IS_DTLS(s) && !dtls1_increment_epoch(s, which)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } if (!ssl_set_new_record_layer(s, s->version, direction, OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, - NULL, 0, key, cl, iv, (size_t)k, mac_secret, - mac_secret_size, c, taglen, mac_type, - m, comp, NULL)) { + NULL, 0, NULL, key, cl, iv, (size_t)k, + mac_secret, mac_secret_size, NULL, c, taglen, + mac_type, m, comp, NULL)) { /* SSLfatal already called */ goto err; } @@ -271,8 +273,8 @@ int tls1_setup_key_block(SSL_CONNECTION *s) if (s->s3.tmp.key_block_length != 0) return 1; - if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, &c, &hash, - &mac_type, &mac_secret_size, &comp, + if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, NULL, &c, + &hash, &mac_type, &mac_secret_size, &comp, s->ext.use_etm)) { /* Error is already recorded */ SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index 5d0276a5a190f..e9575fdfe6086 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -570,8 +570,6 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data) ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); goto err; } - /* No provider sigalgs are supported in DTLS, reset after checking. */ - sinf->mindtls = sinf->maxdtls = -1; /* The remaining parameters below are mandatory again */ p = OSSL_PARAM_locate_const(params, OSSL_CAPABILITY_TLS_SIGALG_MIN_TLS); @@ -584,13 +582,20 @@ static int add_provider_sigalgs(const OSSL_PARAM params[], void *data) ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); goto err; } - if ((sinf->maxtls != 0) && (sinf->maxtls != -1) && ((sinf->maxtls < sinf->mintls))) { + /* + * There are no discrepancies for signature algs between comparable + * versions of tls and dtls. Hence we check tls versions only. + */ + if ((sinf->maxtls != 0) && (sinf->maxtls != -1) + && ((sinf->maxtls < sinf->mintls))) { ERR_raise(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT); goto err; } - if ((sinf->mintls != 0) && (sinf->mintls != -1) && ((sinf->mintls > TLS1_3_VERSION))) + if ((sinf->mintls != 0) && (sinf->mintls != -1) + && ((sinf->mintls > TLS1_3_VERSION))) sinf->mintls = sinf->maxtls = -1; - if ((sinf->maxtls != 0) && (sinf->maxtls != -1) && ((sinf->maxtls < TLS1_3_VERSION))) + if ((sinf->maxtls != 0) && (sinf->maxtls != -1) + && ((sinf->maxtls < TLS1_3_VERSION))) sinf->mintls = sinf->maxtls = -1; /* Ignore unusable sigalgs */ @@ -879,6 +884,7 @@ int tls_valid_group(SSL_CONNECTION *s, uint16_t group_id, group_id); int ret = 0; int group_minversion, group_maxversion; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION : TLS1_3_VERSION; if (okfortls13 != NULL) *okfortls13 = 0; @@ -898,11 +904,9 @@ int tls_valid_group(SSL_CONNECTION *s, uint16_t group_id, if (group_minversion > 0) ret &= (ssl_version_cmp(s, maxversion, group_minversion) >= 0); - if (!SSL_CONNECTION_IS_DTLS(s)) { - if (ret && okfortls13 != NULL && maxversion == TLS1_3_VERSION) - *okfortls13 = (group_maxversion == 0) - || (group_maxversion >= TLS1_3_VERSION); - } + if (ret && okfortls13 != NULL && maxversion == version1_3) + *okfortls13 = (group_maxversion == 0) + || (ssl_version_cmp(s, group_maxversion, maxversion) >= 0); end: if (giptr != NULL) *giptr = ginfo; @@ -1255,6 +1259,17 @@ static const char prefixes[] = { TUPLE_DELIMITER_CHARACTER, * Those callback functions are (indirectly) called by CONF_parse_list with * different separators (nominally ':' or '/'), a variable based on gid_cb_st * is used to keep track of the parsing results between the various calls + * + * Bookkeeping invariants maintained throughout parsing (see gid_cb_st below): + * - gid_arr[0..gidcnt) is the flat list of groups, partitioned into tuples in + * order: tuple t occupies a contiguous run of tuplcnt_arr[t] entries. + * - The per-tuple counts therefore sum to the group count: + * sum(tuplcnt_arr[0..tplcnt]) == gidcnt + * (indices 0..tplcnt-1 are closed tuples, index tplcnt is the active one). + * - ksid_arr[0..ksidcnt) holds keyshare group IDs; each is one of the groups + * in gid_arr and they appear in the same relative order as their groups. + * Every add/remove path must preserve these; an OOB read in the remove path + * (GitHub #31315) was a symptom of the first invariant being violated. */ typedef struct { @@ -1542,9 +1557,16 @@ static int gid_cb(const char *elem, int len, void *arg) * Otherwise, iterate through the tuple check whether any keyshares * remain *after* the index of the group we're removing. The first * of these, if any, is at index `k+1` in the keyshare list, which - * is the only slow we need to check. + * is the only slot we need to check. + * + * If the removal emptied the tuple (tuplcnt_arr[j] == 0 after the + * decrement above) there is no remaining group to float onto: + * gid_arr[tpl_start_idx] would now name a group belonging to the + * next tuple (or be past gid_arr entirely). Drop the keyshare in + * that case too. */ - drop_ks = ks_check_idx > tpl_start_idx || j >= garg->tplcnt; + drop_ks = ks_check_idx > tpl_start_idx || j >= garg->tplcnt + || garg->tuplcnt_arr[j] == 0; if (!drop_ks) { size_t end; /* End index of affected tuple */ @@ -1573,11 +1595,19 @@ static int gid_cb(const char *elem, int len, void *arg) * Adjust closed or current tuple's group count, if a closed tuple * count reaches zero excise the resulting empty tuple. The current * (not yet closed) tuple at the end of the list stays even if empty. + * + * The active tuple lives at index tplcnt, so the slots in use are + * tuplcnt_arr[0..tplcnt] (tplcnt + 1 entries). Excising closed tuple + * j must therefore shift the closed tuples j+1..tplcnt-1 *and* the + * active tuple at index tplcnt down by one, i.e. (tplcnt - j) entries + * counted with the pre-decrement tplcnt. Decrement tplcnt only after + * the move so the active-tuple slot is not left behind (which would + * inflate the per-tuple counts and desynchronise them from gid_arr). */ if (garg->tuplcnt_arr[j] == 0 && j < garg->tplcnt) { - garg->tplcnt--; memmove(garg->tuplcnt_arr + j, garg->tuplcnt_arr + j + 1, (garg->tplcnt - j) * sizeof(size_t)); + garg->tplcnt--; } } else { /* Processing addition of a single new group */ @@ -2117,19 +2147,19 @@ static const SIGALG_LOOKUP sigalg_lookup_tbl[] = { TLSEXT_SIGALG_ecdsa_brainpoolP256r1_sha256, NID_sha256, SSL_MD_SHA256_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, NID_ecdsa_with_SHA256, NID_brainpoolP256r1, 1, 0, - TLS1_3_VERSION, 0, -1, -1 }, + TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, { TLSEXT_SIGALG_ecdsa_brainpoolP384r1_sha384_name, TLSEXT_SIGALG_ecdsa_brainpoolP384r1_sha384_alias, TLSEXT_SIGALG_ecdsa_brainpoolP384r1_sha384, NID_sha384, SSL_MD_SHA384_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, NID_ecdsa_with_SHA384, NID_brainpoolP384r1, 1, 0, - TLS1_3_VERSION, 0, -1, -1 }, + TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, { TLSEXT_SIGALG_ecdsa_brainpoolP512r1_sha512_name, TLSEXT_SIGALG_ecdsa_brainpoolP512r1_sha512_alias, TLSEXT_SIGALG_ecdsa_brainpoolP512r1_sha512, NID_sha512, SSL_MD_SHA512_IDX, EVP_PKEY_EC, SSL_PKEY_ECC, NID_ecdsa_with_SHA512, NID_brainpoolP512r1, 1, 0, - TLS1_3_VERSION, 0, -1, -1 }, + TLS1_3_VERSION, 0, DTLS1_3_VERSION, 0 }, { TLSEXT_SIGALG_rsa_pss_rsae_sha256_name, "PSS+SHA256", TLSEXT_SIGALG_rsa_pss_rsae_sha256, @@ -2282,14 +2312,11 @@ int ssl_setup_sigalgs(SSL_CTX *ctx) SIGALG_LOOKUP *cache = NULL; uint16_t *tls12_sigalgs_list = NULL; EVP_PKEY *tmpkey = EVP_PKEY_new(); - int istls; int ret = 0; if (ctx == NULL) goto err; - istls = !SSL_CTX_IS_DTLS(ctx); - sigalgs_len = OSSL_NELEM(sigalg_lookup_tbl) + ctx->sigalg_list_len; cache = OPENSSL_calloc(sigalgs_len, sizeof(const SIGALG_LOOKUP)); @@ -2349,10 +2376,10 @@ int ssl_setup_sigalgs(SSL_CTX *ctx) cache[cache_idx].curve = NID_undef; cache[cache_idx].mintls = TLS1_3_VERSION; cache[cache_idx].maxtls = TLS1_3_VERSION; - cache[cache_idx].mindtls = -1; - cache[cache_idx].maxdtls = -1; + cache[cache_idx].mindtls = DTLS1_3_VERSION; + cache[cache_idx].maxdtls = DTLS1_3_VERSION; /* Compatibility with TLS 1.3 is checked on load */ - cache[cache_idx].available = istls; + cache[cache_idx].available = 1; cache[cache_idx].advertise = 0; cache_idx++; } @@ -2805,13 +2832,13 @@ int tls12_check_peer_sigalg(SSL_CONNECTION *s, uint16_t sig, EVP_PKEY *pkey) pkeyid = EVP_PKEY_get_id(pkey); - if (SSL_CONNECTION_IS_TLS13(s)) { - /* Disallow DSA for TLS 1.3 */ + if (SSL_CONNECTION_IS_VERSION13(s)) { + /* Disallow DSA for (D)TLS 1.3 */ if (pkeyid == EVP_PKEY_DSA) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_SIGNATURE_TYPE); return 0; } - /* Only allow PSS for TLS 1.3 */ + /* Only allow PSS for (D)TLS 1.3 */ if (pkeyid == EVP_PKEY_RSA) pkeyid = EVP_PKEY_RSA_PSS; } @@ -2841,10 +2868,10 @@ int tls12_check_peer_sigalg(SSL_CONNECTION *s, uint16_t sig, EVP_PKEY *pkey) } /* - * Check sigalgs is known. Disallow SHA1/SHA224 with TLS 1.3. Check key type + * Check sigalgs is known. Disallow SHA1/SHA224 with (D)TLS 1.3. Check key type * is consistent with signature: RSA keys can be used for RSA-PSS */ - if ((SSL_CONNECTION_IS_TLS13(s) + if ((SSL_CONNECTION_IS_VERSION13(s) && (lu->hash == NID_sha1 || lu->hash == NID_sha224)) || (pkeyid != lu->sig && (lu->sig != EVP_PKEY_RSA_PSS || pkeyid != EVP_PKEY_RSA))) { @@ -2867,8 +2894,8 @@ int tls12_check_peer_sigalg(SSL_CONNECTION *s, uint16_t sig, EVP_PKEY *pkey) * have. */ - /* For TLS 1.3 or Suite B check curve matches signature algorithm */ - if (SSL_CONNECTION_IS_TLS13(s) || tls1_suiteb(s)) { + /* For (D)TLS 1.3 or Suite B check curve matches signature algorithm */ + if (SSL_CONNECTION_IS_VERSION13(s) || tls1_suiteb(s)) { int curve = ssl_get_EC_curve_nid(pkey); if (lu->curve != NID_undef && curve != lu->curve) { @@ -2876,7 +2903,7 @@ int tls12_check_peer_sigalg(SSL_CONNECTION *s, uint16_t sig, EVP_PKEY *pkey) return 0; } } - if (!SSL_CONNECTION_IS_TLS13(s)) { + if (!SSL_CONNECTION_IS_VERSION13(s)) { /* Check curve matches extensions */ if (!tls1_check_group_id(s, tls1_get_group_id(pkey), 1)) { SSLfatal(s, SSL_AD_ILLEGAL_PARAMETER, SSL_R_WRONG_CURVE); @@ -3109,7 +3136,7 @@ SSL_TICKET_STATUS tls_get_ticket_from_client(SSL_CONNECTION *s, s->ext.ticket_expected = 0; /* - * If tickets disabled or not supported by the protocol version + * If tickets are disabled or not supported by the protocol version * (e.g. TLSv1.3) behave as if no ticket present to permit stateful * resumption. */ @@ -3175,7 +3202,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL_CONNECTION *s, ret = SSL_TICKET_EMPTY; goto end; } - if (!SSL_CONNECTION_IS_TLS13(s) && s->ext.session_secret_cb) { + if (!SSL_CONNECTION_IS_VERSION13(s) && s->ext.session_secret_cb) { /* * Indicate that the ticket couldn't be decrypted rather than * generating the session from ticket now, trigger @@ -3255,7 +3282,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL_CONNECTION *s, ret = SSL_TICKET_FATAL_ERR_OTHER; goto end; } - if (SSL_CONNECTION_IS_TLS13(s)) + if (SSL_CONNECTION_IS_VERSION13(s)) renew_ticket = 1; } /* @@ -3400,7 +3427,7 @@ SSL_TICKET_STATUS tls_decrypt_ticket(SSL_CONNECTION *s, } } - if (s->ext.session_secret_cb == NULL || SSL_CONNECTION_IS_TLS13(s)) { + if (s->ext.session_secret_cb == NULL || SSL_CONNECTION_IS_VERSION13(s)) { switch (ret) { case SSL_TICKET_NO_DECRYPT: case SSL_TICKET_SUCCESS_RENEW: @@ -3420,18 +3447,20 @@ static int tls12_sigalg_allowed(const SSL_CONNECTION *s, int op, { unsigned char sigalgstr[2]; int secbits; + const int version1_3 = SSL_CONNECTION_IS_DTLS(s) ? DTLS1_3_VERSION + : TLS1_3_VERSION; if (lu == NULL || !lu->available) return 0; - /* DSA is not allowed in TLS 1.3 */ - if (SSL_CONNECTION_IS_TLS13(s) && lu->sig == EVP_PKEY_DSA) + /* DSA is not allowed in (D)TLSv1.3 */ + if (SSL_CONNECTION_IS_VERSION13(s) && lu->sig == EVP_PKEY_DSA) return 0; /* - * At some point we should fully axe DSA/etc. in ClientHello as per TLS 1.3 + * At some point we should fully axe DSA/etc. in ClientHello as per (D)TLSv1.3 * spec */ - if (!s->server && !SSL_CONNECTION_IS_DTLS(s) - && s->s3.tmp.min_ver >= TLS1_3_VERSION + if (!s->server && s->s3.tmp.min_ver != 0 + && ssl_version_cmp(s, s->s3.tmp.min_ver, version1_3) >= 0 && (lu->sig == EVP_PKEY_DSA || lu->hash_idx == SSL_MD_SHA1_IDX || lu->hash_idx == SSL_MD_MD5_IDX || lu->hash_idx == SSL_MD_SHA224_IDX)) @@ -3444,22 +3473,26 @@ static int tls12_sigalg_allowed(const SSL_CONNECTION *s, int op, if (lu->sig == NID_id_GostR3410_2012_256 || lu->sig == NID_id_GostR3410_2012_512 || lu->sig == NID_id_GostR3410_2001) { - /* We never allow GOST sig algs on the server with TLSv1.3 */ - if (s->server && SSL_CONNECTION_IS_TLS13(s)) + int any_version = SSL_CONNECTION_IS_DTLS(s) ? DTLS_ANY_VERSION : TLS_ANY_VERSION; + + /* We never allow GOST sig algs on the server with (D)TLSv1.3 */ + if (s->server && SSL_CONNECTION_IS_VERSION13(s)) return 0; if (!s->server - && SSL_CONNECTION_GET_SSL(s)->method->version == TLS_ANY_VERSION - && s->s3.tmp.max_ver >= TLS1_3_VERSION) { + && SSL_CONNECTION_GET_SSL(s)->method->version == any_version + && s->s3.tmp.max_ver != 0 + && ssl_version_cmp(s, s->s3.tmp.max_ver, version1_3) >= 0) { int i, num; STACK_OF(SSL_CIPHER) *sk; /* - * We're a client that could negotiate TLSv1.3. We only allow GOST - * sig algs if we could negotiate TLSv1.2 or below and we have GOST + * We're a client that could negotiate (D)TLSv1.3. We only allow GOST + * sig algs if we could negotiate (D)TLSv1.2 or below and we have GOST * ciphersuites enabled. */ - if (s->s3.tmp.min_ver >= TLS1_3_VERSION) + if (s->s3.tmp.min_ver != 0 + && ssl_version_cmp(s, s->s3.tmp.min_ver, version1_3) >= 0) return 0; sk = SSL_get_ciphers(SSL_CONNECTION_GET_SSL(s)); @@ -3540,7 +3573,7 @@ int tls12_copy_sigalgs(SSL_CONNECTION *s, WPACKET *pkt, * If TLS 1.3 must have at least one valid TLS 1.3 message * signing algorithm: i.e. neither RSA nor SHA1/SHA224 */ - if (rv == 0 && (!SSL_CONNECTION_IS_TLS13(s) || (lu->sig != EVP_PKEY_RSA && lu->hash != NID_sha1 && lu->hash != NID_sha224))) + if (rv == 0 && (!SSL_CONNECTION_IS_VERSION13(s) || (lu->sig != EVP_PKEY_RSA && lu->hash != NID_sha1 && lu->hash != NID_sha224))) rv = 1; } if (rv == 0) @@ -3698,7 +3731,7 @@ int tls1_process_sigalgs(SSL_CONNECTION *s) int idx = sigptr->sig_idx; /* Ignore PKCS1 based sig algs in TLSv1.3 */ - if (SSL_CONNECTION_IS_TLS13(s) && sigptr->sig == EVP_PKEY_RSA) + if (SSL_CONNECTION_IS_VERSION13(s) && sigptr->sig == EVP_PKEY_RSA) continue; /* If not disabled indicate we can explicitly sign */ if (pvalid[idx] == 0 @@ -4054,7 +4087,7 @@ static int tls1_check_sig_alg(SSL_CONNECTION *s, X509 *x, int default_nid) size_t sigalgslen; /*- - * RFC 8446, section 4.2.3: + * RFC 9846, section 4.3.3: * * The signatures on certificates that are self-signed or certificates * that are trust anchors are not validated, since they begin a @@ -4069,7 +4102,7 @@ static int tls1_check_sig_alg(SSL_CONNECTION *s, X509 *x, int default_nid) if (default_nid) return sig_nid == default_nid ? 1 : 0; - if (SSL_CONNECTION_IS_TLS13(s) && s->s3.tmp.peer_cert_sigalgs != NULL) { + if (SSL_CONNECTION_IS_VERSION13(s) && s->s3.tmp.peer_cert_sigalgs != NULL) { /* * If we're in TLSv1.3 then we only get here if we're checking the * chain. If the peer has specified peer_cert_sigalgs then we use them @@ -4281,7 +4314,7 @@ int tls1_check_chain(SSL_CONNECTION *s, X509 *x, EVP_PKEY *pk, } } /* Check signature algorithm of each cert in chain */ - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { /* * We only get here if the application has called SSL_check_chain(), * so check_flags is always set. @@ -4615,6 +4648,20 @@ static int check_cert_usable(SSL_CONNECTION *s, const SIGALG_LOOKUP *sig, if (supported <= 0) return 0; + /* + * When RPK is negotiated there are no certificate signatures to + * constrain, and there may not even be a certificate configured. + */ + if (TLSEXT_cert_type_rpk == (s->server ? s->ext.server_cert_type : s->ext.client_cert_type)) + return 1; + + /* + * RPK was enabled, adding candidate private-key-only slots, but was not + * negotiated, so the key-only slot is not usable. + */ + if (x == NULL) + return 0; + /* * The TLS 1.3 signature_algorithms_cert extension places restrictions * on the sigalg with which the certificate was signed (by its issuer). @@ -4758,7 +4805,7 @@ int tls_choose_sigalg(SSL_CONNECTION *s, int fatalerrs) s->s3.tmp.cert = NULL; s->s3.tmp.sigalg = NULL; - if (SSL_CONNECTION_IS_TLS13(s)) { + if (SSL_CONNECTION_IS_VERSION13(s)) { lu = find_sig_alg(s, NULL, NULL); if (lu == NULL) { if (!fatalerrs) diff --git a/ssl/t1_trce.c b/ssl/t1_trce.c index 0e8ddbb8f87f1..d9e6c9f1d1936 100644 --- a/ssl/t1_trce.c +++ b/ssl/t1_trce.c @@ -69,6 +69,7 @@ static const ssl_trace_tbl ssl_version_tbl[] = { { TLS1_3_VERSION, "TLS 1.3" }, { DTLS1_VERSION, "DTLS 1.0" }, { DTLS1_2_VERSION, "DTLS 1.2" }, + { DTLS1_3_VERSION, "DTLS 1.3" }, { DTLS1_BAD_VER, "DTLS 1.0 (bad)" } }; @@ -1108,7 +1109,7 @@ static int ssl_print_server_hello(BIO *bio, int indent, return 0; if (!ssl_print_random(bio, indent, &msg, &msglen)) return 0; - if (vers != TLS1_3_VERSION + if (vers != TLS1_3_VERSION && vers != DTLS1_3_VERSION && !ssl_print_hexbuf(bio, indent, "session_id", 1, &msg, &msglen)) return 0; if (msglen < 2) @@ -1119,7 +1120,7 @@ static int ssl_print_server_hello(BIO *bio, int indent, msg[0], msg[1], ssl_trace_str(cs, ssl_ciphers_tbl)); msg += 2; msglen -= 2; - if (vers != TLS1_3_VERSION) { + if (vers != TLS1_3_VERSION && vers != DTLS1_3_VERSION) { if (msglen < 1) return 0; BIO_indent(bio, indent, 80); @@ -1386,7 +1387,7 @@ static int ssl_print_certificates(BIO *bio, const SSL_CONNECTION *sc, int server { size_t clen; - if (SSL_CONNECTION_IS_TLS13(sc) + if (SSL_CONNECTION_IS_VERSION13(sc) && !ssl_print_hexbuf(bio, indent, "context", 1, &msg, &msglen)) return 0; @@ -1400,7 +1401,7 @@ static int ssl_print_certificates(BIO *bio, const SSL_CONNECTION *sc, int server || (!server && sc->ext.client_cert_type == TLSEXT_cert_type_rpk)) { if (!ssl_print_raw_public_key(bio, sc, server, indent, &msg, &clen)) return 0; - if (SSL_CONNECTION_IS_TLS13(sc) + if (SSL_CONNECTION_IS_VERSION13(sc) && !ssl_print_extensions(bio, indent + 2, server, SSL3_MT_CERTIFICATE, &msg, &clen)) return 0; @@ -1411,7 +1412,7 @@ static int ssl_print_certificates(BIO *bio, const SSL_CONNECTION *sc, int server while (clen > 0) { if (!ssl_print_certificate(bio, sc, indent + 2, &msg, &clen)) return 0; - if (SSL_CONNECTION_IS_TLS13(sc) + if (SSL_CONNECTION_IS_VERSION13(sc) && !ssl_print_extensions(bio, indent + 2, server, SSL3_MT_CERTIFICATE, &msg, &clen)) return 0; @@ -1498,7 +1499,7 @@ static int ssl_print_cert_request(BIO *bio, int indent, const SSL_CONNECTION *sc size_t xlen; unsigned int sigalg; - if (SSL_CONNECTION_IS_TLS13(sc)) { + if (SSL_CONNECTION_IS_VERSION13(sc)) { if (!ssl_print_hexbuf(bio, indent, "request_context", 1, &msg, &msglen)) return 0; if (!ssl_print_extensions(bio, indent, 1, @@ -1573,7 +1574,7 @@ static int ssl_print_cert_request(BIO *bio, int indent, const SSL_CONNECTION *sc xlen -= dlen + 2; msg += dlen; } - if (SSL_CONNECTION_IS_TLS13(sc)) { + if (SSL_CONNECTION_IS_VERSION13(sc)) { if (!ssl_print_hexbuf(bio, indent, "request_extensions", 2, &msg, &msglen)) return 0; @@ -1601,7 +1602,7 @@ static int ssl_print_ticket(BIO *bio, int indent, const SSL_CONNECTION *sc, msg += 4; BIO_indent(bio, indent + 2, 80); BIO_printf(bio, "ticket_lifetime_hint=%u\n", tick_life); - if (SSL_CONNECTION_IS_TLS13(sc)) { + if (SSL_CONNECTION_IS_VERSION13(sc)) { unsigned int ticket_age_add; if (msglen < 4) @@ -1620,7 +1621,7 @@ static int ssl_print_ticket(BIO *bio, int indent, const SSL_CONNECTION *sc, } if (!ssl_print_hexbuf(bio, indent + 2, "ticket", 2, &msg, &msglen)) return 0; - if (SSL_CONNECTION_IS_TLS13(sc) + if (SSL_CONNECTION_IS_VERSION13(sc) && !ssl_print_extensions(bio, indent + 2, 0, SSL3_MT_NEWSESSION_TICKET, &msg, &msglen)) return 0; diff --git a/ssl/tls13_enc.c b/ssl/tls13_enc.c index ae47f5301cd71..1dc0f69e027e9 100644 --- a/ssl/tls13_enc.c +++ b/ssl/tls13_enc.c @@ -19,20 +19,24 @@ #define TLS13_MAX_LABEL_LEN 249 +/* ASCII: "dtls13", in hex for EBCDIC compatibility */ +static const unsigned char label_prefix_dtls13[] = "\x64\x74\x6C\x73\x31\x33"; /* ASCII: "tls13 ", in hex for EBCDIC compatibility */ -static const unsigned char label_prefix[] = "\x74\x6C\x73\x31\x33\x20"; +static const unsigned char label_prefix_tls13[] = "\x74\x6C\x73\x31\x33\x20"; /* - * Given a |secret|; a |label| of length |labellen|; and |data| of length - * |datalen| (e.g. typically a hash of the handshake messages), derive a new - * secret |outlen| bytes long and store it in the location pointed to be |out|. + * Given a |secret|; a |label_prefix| of length |label_prefix_len|; a |label| + * of length |labellen|; and |data| of length |datalen| (e.g. typically a hash + * of the handshake messages), derive a new secret |outlen| bytes long and + * store it in the location pointed to be |out|. * The |data| value may be zero length. Any errors will be treated as fatal if * |fatal| is set. Returns 1 on success 0 on failure. * If |raise_error| is set, ERR_raise is called on failure. */ -int tls13_hkdf_expand_ex(OSSL_LIB_CTX *libctx, const char *propq, +static int hkdf_expand(OSSL_LIB_CTX *libctx, const char *propq, const EVP_MD *md, const unsigned char *secret, + const unsigned char *label_prefix, size_t label_prefix_len, const unsigned char *label, size_t labellen, const unsigned char *data, size_t datalen, unsigned char *out, size_t outlen, int raise_error) @@ -77,7 +81,7 @@ int tls13_hkdf_expand_ex(OSSL_LIB_CTX *libctx, const char *propq, (unsigned char *)secret, hashlen); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX, (unsigned char *)label_prefix, - sizeof(label_prefix) - 1); + label_prefix_len); *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_LABEL, (unsigned char *)label, labellen); if (data != NULL) @@ -101,6 +105,20 @@ int tls13_hkdf_expand_ex(OSSL_LIB_CTX *libctx, const char *propq, return ret == 0; } +int tls13_hkdf_expand_ex(OSSL_LIB_CTX *libctx, const char *propq, + const EVP_MD *md, + const unsigned char *secret, + const unsigned char *label, size_t labellen, + const unsigned char *data, size_t datalen, + unsigned char *out, size_t outlen, int raise_error) +{ + /* This function only supports TLSv1.3 and not DTLSv1.3 */ + return hkdf_expand(libctx, propq, md, secret, label_prefix_tls13, + sizeof(label_prefix_tls13) - 1, + label, labellen, data, datalen, out, outlen, + raise_error); +} + int tls13_hkdf_expand(SSL_CONNECTION *s, const EVP_MD *md, const unsigned char *secret, const unsigned char *label, size_t labellen, @@ -109,10 +127,15 @@ int tls13_hkdf_expand(SSL_CONNECTION *s, const EVP_MD *md, { int ret; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); - - ret = tls13_hkdf_expand_ex(sctx->libctx, sctx->propq, md, - secret, label, labellen, data, datalen, - out, outlen, !fatal); + const int isdtls = SSL_CONNECTION_IS_DTLS(s); + const unsigned char *label_prefix = isdtls ? label_prefix_dtls13 + : label_prefix_tls13; + const size_t label_prefix_len = isdtls ? sizeof(label_prefix_dtls13) - 1 + : sizeof(label_prefix_tls13) - 1; + + ret = hkdf_expand(sctx->libctx, sctx->propq, md, secret, label_prefix, + label_prefix_len, label, labellen, data, + datalen, out, outlen, !fatal); if (ret == 0 && fatal) SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); @@ -160,6 +183,21 @@ int tls13_derive_finishedkey(SSL_CONNECTION *s, const EVP_MD *md, sizeof(finishedlabel) - 1, NULL, 0, fin, finlen, 1); } +/* + * Given a |secret| generate a |snkey| of length |snkeylen| bytes. Returns 1 on + * success 0 on failure. (rfc9147 section 4.2.3) + */ +static int dtls13_derive_snkey(SSL_CONNECTION *s, const EVP_MD *md, + const unsigned char *secret, + unsigned char *snkey, size_t keylen) +{ + /* ASCII: "sn", in hex for EBCDIC compatibility */ + static const unsigned char sn_str[] = "\x73\x6E"; + + return tls13_hkdf_expand(s, md, secret, sn_str, sizeof(sn_str) - 1, + NULL, 0, snkey, keylen, 1); +} + /* * Given the previous secret |prevsecret| and a new input secret |insecret| of * length |insecretlen|, generate a new secret and store it in the location @@ -182,6 +220,7 @@ int tls13_generate_secret(SSL_CONNECTION *s, const EVP_MD *md, /* ASCII: "derived", in hex for EBCDIC compatibility */ static const char derived_secret_label[] = "\x64\x65\x72\x69\x76\x65\x64"; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); + int isdtls = SSL_CONNECTION_IS_DTLS(s); kdf = EVP_KDF_fetch(sctx->libctx, OSSL_KDF_NAME_TLS1_3_KDF, sctx->propq); kctx = EVP_KDF_CTX_new(kdf); @@ -210,9 +249,15 @@ int tls13_generate_secret(SSL_CONNECTION *s, const EVP_MD *md, if (prevsecret != NULL) *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, (unsigned char *)prevsecret, mdlen); - *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX, - (unsigned char *)label_prefix, - sizeof(label_prefix) - 1); + if (isdtls) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX, + (unsigned char *)label_prefix_dtls13, + sizeof(label_prefix_dtls13) - 1); + else + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_PREFIX, + (unsigned char *)label_prefix_tls13, + sizeof(label_prefix_tls13) - 1); + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_LABEL, (unsigned char *)derived_secret_label, sizeof(derived_secret_label) - 1); @@ -280,8 +325,10 @@ size_t tls13_final_finish_mac(SSL_CONNECTION *s, const char *str, size_t slen, OSSL_PARAM params[2], *p = params; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); - if (md == NULL) + if (md == NULL) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); return 0; + } /* Safe to cast away const here since we're not "getting" any data */ if (sctx->propq != NULL) @@ -327,13 +374,14 @@ size_t tls13_final_finish_mac(SSL_CONNECTION *s, const char *str, size_t slen, int tls13_setup_key_block(SSL_CONNECTION *s) { const EVP_CIPHER *c; + const EVP_CIPHER *snc = NULL, **p_snc = SSL_CONNECTION_IS_DTLS(s) ? &snc : NULL; const EVP_MD *hash; int mac_type = NID_undef; size_t mac_secret_size = 0; s->session->cipher = s->s3.tmp.new_cipher; - if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, &c, &hash, - &mac_type, &mac_secret_size, NULL, 0)) { + if (!ssl_cipher_get_evp(SSL_CONNECTION_GET_CTX(s), s->session, p_snc, &c, + &hash, &mac_type, &mac_secret_size, NULL, 0)) { /* Error is already recorded */ SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); return 0; @@ -341,6 +389,8 @@ int tls13_setup_key_block(SSL_CONNECTION *s) ssl_evp_cipher_free(s->s3.tmp.new_sym_enc); s->s3.tmp.new_sym_enc = c; + ssl_evp_cipher_free(s->s3.tmp.new_sym_enc_sn); + s->s3.tmp.new_sym_enc_sn = snc; ssl_evp_md_free(s->s3.tmp.new_hash); s->s3.tmp.new_hash = hash; s->s3.tmp.new_mac_pkey_type = mac_type; @@ -357,6 +407,7 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md, const unsigned char *hash, const unsigned char *label, size_t labellen, unsigned char *secret, + unsigned char *snkey, unsigned char *key, size_t *keylen, unsigned char **iv, size_t *ivlen, size_t *taglen) @@ -442,7 +493,9 @@ static int derive_secret_key_and_iv(SSL_CONNECTION *s, const EVP_MD *md, } if (!tls13_derive_key(s, md, secret, key, *keylen) - || !tls13_derive_iv(s, md, secret, *iv, *ivlen)) { + || !tls13_derive_iv(s, md, secret, *iv, *ivlen) + || (SSL_CONNECTION_IS_DTLS(s) + && !dtls13_derive_snkey(s, md, secret, snkey, *keylen))) { /* SSLfatal() already called */ return 0; } @@ -496,6 +549,7 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) unsigned char iv_intern[EVP_MAX_IV_LENGTH]; unsigned char *iv = iv_intern; unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char snkey[EVP_MAX_KEY_LENGTH]; unsigned char secret[EVP_MAX_MD_SIZE]; unsigned char hashval[EVP_MAX_MD_SIZE]; unsigned char *hash = hashval; @@ -507,7 +561,7 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) size_t labellen, hashlen = 0; int ret = 0; const EVP_MD *md = NULL, *mac_md = NULL; - const EVP_CIPHER *cipher = NULL; + const EVP_CIPHER *cipher = NULL, *sncipher = NULL; int mac_pkey_type = NID_undef; SSL_CTX *sctx = SSL_CONNECTION_GET_CTX(s); size_t keylen, ivlen = EVP_MAX_IV_LENGTH, taglen; @@ -529,6 +583,19 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) labellen = sizeof(client_early_traffic) - 1; log_label = CLIENT_EARLY_LABEL; + /* + * Client: never install early-write keys from an underived (zero) + * s->early_secret. It is set only when the first-offered PSK's + * binder derived it this ClientHello flight (see + * s->ext.early_secret_derived). If it is not set, the PSK offer and + * the early_data decision diverged; fail closed rather than protect + * 0-RTT under a secret a passive observer could reconstruct. + */ + if ((which & SSL3_CC_CLIENT) != 0 && !s->ext.early_secret_derived) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + #ifndef OPENSSL_NO_ECH /* if ECH worked then use the innerch and not the h/s buffer here */ if (((which & SSL3_CC_SERVER) && s->ext.ech.success == 1) @@ -550,20 +617,18 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) } } + /* + * 0-RTT keys off the recorded first-offered PSK, which may be the + * external psksession rather than s->session. + */ if (s->early_data_state == SSL_EARLY_DATA_CONNECTING - && s->max_early_data > 0 - && s->session->ext.max_early_data == 0) { - /* - * If we are attempting to send early data, and we've decided to - * actually do it but max_early_data in s->session is 0 then we - * must be using an external PSK. - */ - if (!ossl_assert(s->psksession != NULL - && s->max_early_data == s->psksession->ext.max_early_data)) { + && s->ext.early_data_session != NULL) { + if (!ossl_assert(s->max_early_data + == s->ext.early_data_session->ext.max_early_data)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); goto err; } - sslcipher = SSL_SESSION_get0_cipher(s->psksession); + sslcipher = SSL_SESSION_get0_cipher(s->ext.early_data_session); } if (sslcipher == NULL) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_R_BAD_PSK); @@ -574,7 +639,9 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) * This ups the ref count on cipher so we better make sure we free * it again */ - if (!ssl_cipher_get_evp_cipher(sctx, sslcipher, &cipher)) { + if (!ssl_cipher_get_evp_cipher(sctx, sslcipher, &cipher) + || (SSL_CONNECTION_IS_DTLS(s) + && !ssl_cipher_get_evp_cipher_sn(sctx, sslcipher, &sncipher))) { /* Error is already recorded */ SSLfatal_alert(s, SSL_AD_INTERNAL_ERROR); goto err; @@ -599,9 +666,28 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) } md = ssl_md(sctx, sslcipher->algorithm2); - if (md == NULL || !EVP_DigestInit_ex(mdctx, md, NULL) - || !EVP_DigestUpdate(mdctx, hdata, handlen) - || !EVP_DigestFinal_ex(mdctx, hashval, &hashlenui)) { + if (md == NULL || !EVP_DigestInit_ex(mdctx, md, NULL)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + EVP_MD_CTX_free(mdctx); + goto err; + } + + if (SSL_CONNECTION_IS_DTLS(s)) { + if (!dtls13_transcript_hash_update(mdctx, hdata, + (size_t)handlen)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + EVP_MD_CTX_free(mdctx); + goto err; + } + } else { + if (!EVP_DigestUpdate(mdctx, hdata, handlen)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + EVP_MD_CTX_free(mdctx); + goto err; + } + } + + if (!EVP_DigestFinal_ex(mdctx, hashval, &hashlenui)) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); EVP_MD_CTX_free(mdctx); goto err; @@ -621,9 +707,10 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) if (!ssl_log_secret(s, EARLY_EXPORTER_SECRET_LABEL, s->early_exporter_master_secret, hashlen)) { - SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + /* SSLfatal() already called */ goto err; } + s->ext.early_exporter_ready = 1; } else if (which & SSL3_CC_HANDSHAKE) { insecret = s->handshake_secret; finsecret = s->client_finished_secret; @@ -685,6 +772,10 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) cipher = s->s3.tmp.new_sym_enc; mac_md = s->s3.tmp.new_hash; mac_pkey_type = s->s3.tmp.new_mac_pkey_type; + + if (SSL_CONNECTION_IS_DTLS(s)) { + sncipher = s->s3.tmp.new_sym_enc_sn; + } if (!ssl3_digest_cached_records(s, 1) || !ssl_handshake_hash(s, hashval, sizeof(hashval), &hashlen)) { /* SSLfatal() already called */; @@ -712,8 +803,8 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) goto err; if (!derive_secret_key_and_iv(s, md, cipher, mac_pkey_type, mac_md, - insecret, hash, label, labellen, secret, key, - &keylen, &iv, &ivlen, &taglen)) { + insecret, hash, label, labellen, secret, + snkey, key, &keylen, &iv, &ivlen, &taglen)) { /* SSLfatal() already called */ goto err; } @@ -763,10 +854,39 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) ? OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE : OSSL_RECORD_PROTECTION_LEVEL_APPLICATION); - if (!ssl_set_new_record_layer(s, s->version, - direction, - level, secret, hashlen, key, keylen, iv, - ivlen, NULL, 0, cipher, taglen, + if (SSL_CONNECTION_IS_DTLS(s)) { + /* + * For DTLS1.3 The Compressed Certificate should still be sent in Epoch 2 + * not Epoch 3. + */ + if (s->version != DTLS1_3_VERSION || (which & SSL3_CC_COMP_CERT) == 0) { + if (!dtls1_increment_epoch(s, which)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (level == OSSL_RECORD_PROTECTION_LEVEL_HANDSHAKE && dtls1_get_epoch(s, which) == 1) { + /* + * We must manually increment epoch because + * client early traffic was not sent/recv + */ + if (!dtls1_increment_epoch(s, which)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + /* We have moved to the next flight lets clear out old messages */ + if (direction == OSSL_RECORD_DIRECTION_READ) + dtls1_clear_received_buffer(s); + + dtls1_clear_sent_buffer(s, 1); + } + + if (!ssl_set_new_record_layer(s, s->version, direction, level, secret, + hashlen, snkey, key, keylen, iv, ivlen, + NULL, 0, sncipher, cipher, taglen, mac_pkey_type, mac_md, NULL, md)) { /* SSLfatal already called */ goto err; @@ -779,8 +899,10 @@ int tls13_change_cipher_state(SSL_CONNECTION *s, int which) if ((EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) == 0) ssl_evp_md_free(mac_md); ssl_evp_cipher_free(cipher); + ssl_evp_cipher_free(sncipher); } OPENSSL_cleanse(key, sizeof(key)); + OPENSSL_cleanse(snkey, sizeof(snkey)); OPENSSL_cleanse(secret, sizeof(secret)); if (iv != iv_intern) OPENSSL_free(iv); @@ -794,6 +916,8 @@ int tls13_update_key(SSL_CONNECTION *s, int sending) const EVP_MD *md = ssl_handshake_md(s); size_t hashlen; unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char snkey[EVP_MAX_KEY_LENGTH]; + const EVP_CIPHER *snenc = NULL; unsigned char *insecret; unsigned char secret[EVP_MAX_MD_SIZE]; char *log_label; @@ -801,6 +925,7 @@ int tls13_update_key(SSL_CONNECTION *s, int sending) int ret = 0, l; int direction = sending ? OSSL_RECORD_DIRECTION_WRITE : OSSL_RECORD_DIRECTION_READ; + int which = sending ? SSL3_CC_WRITE : SSL3_CC_READ; unsigned char iv_intern[EVP_MAX_IV_LENGTH]; unsigned char *iv = iv_intern; @@ -820,20 +945,29 @@ int tls13_update_key(SSL_CONNECTION *s, int sending) s->s3.tmp.new_mac_pkey_type, s->s3.tmp.new_hash, insecret, NULL, application_traffic, - sizeof(application_traffic) - 1, secret, key, - &keylen, &iv, &ivlen, &taglen)) { + sizeof(application_traffic) - 1, secret, snkey, + key, &keylen, &iv, &ivlen, &taglen)) { /* SSLfatal() already called */ goto err; } memcpy(insecret, secret, hashlen); - if (!ssl_set_new_record_layer(s, s->version, - direction, + if (SSL_CONNECTION_IS_DTLS(s)) { + if (!dtls1_increment_epoch(s, which)) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); + goto err; + } + snenc = s->s3.tmp.new_sym_enc_sn; + } + + if (!ssl_set_new_record_layer(s, s->version, direction, OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, - insecret, hashlen, key, keylen, iv, ivlen, NULL, 0, - s->s3.tmp.new_sym_enc, taglen, NID_undef, NULL, - NULL, md)) { + insecret, hashlen, snkey, key, keylen, + iv, ivlen, NULL, 0, + snenc, + s->s3.tmp.new_sym_enc, + taglen, NID_undef, NULL, NULL, md)) { /* SSLfatal already called */ goto err; } @@ -847,6 +981,7 @@ int tls13_update_key(SSL_CONNECTION *s, int sending) ret = 1; err: OPENSSL_cleanse(key, sizeof(key)); + OPENSSL_cleanse(snkey, sizeof(snkey)); OPENSSL_cleanse(secret, sizeof(secret)); if (iv != iv_intern) OPENSSL_free(iv); @@ -921,11 +1056,12 @@ int tls13_export_keying_material_early(SSL_CONNECTION *s, if (ctx == NULL || !ossl_statem_export_early_allowed(s)) goto err; - if (!s->server && s->max_early_data > 0 - && s->session->ext.max_early_data == 0) - sslcipher = SSL_SESSION_get0_cipher(s->psksession); + if (!s->server && s->ext.early_data_session != NULL) + sslcipher = SSL_SESSION_get0_cipher(s->ext.early_data_session); else sslcipher = SSL_SESSION_get0_cipher(s->session); + if (sslcipher == NULL) + goto err; md = ssl_md(SSL_CONNECTION_GET_CTX(s), sslcipher->algorithm2); diff --git a/ssl/tls_depr.c b/ssl/tls_depr.c index 194e06b33b41a..277df205a293c 100644 --- a/ssl/tls_depr.c +++ b/ssl/tls_depr.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/README.md b/test/README.md index 1575fb69dc773..4437f1543684a 100644 --- a/test/README.md +++ b/test/README.md @@ -149,6 +149,29 @@ To run up to four tests in parallel at any given time: $ make HARNESS_JOBS=4 test +Test time limit +--------------- + +Each test program is run under a watchdog so that a test which hangs is +identified rather than silently stalling the run. If a test program runs for +longer than a fixed time limit the watchdog assumes it has hung and aborts it +(via `abort()`). The abort marks that specific test as failed - so a hang is +attributed to the test responsible rather than appearing as an anonymous +stalled run - and, where the environment is configured to produce them, leaves +a core dump capturing every thread's stack, so it can be seen where the test +was wedged. + +The limit defaults to 1800 seconds (30 minutes) per test program and can be +changed with the `OPENSSL_TEST_TIMEOUT` environment variable, which gives the +limit in seconds. Setting it to `0` (or a negative value) disables the +watchdog entirely. + + $ make OPENSSL_TEST_TIMEOUT=600 test + +The limit applies to each individual test program, not to the test run as a +whole. It only covers test programs built on the test framework; helper +invocations of the `openssl` application are not affected. + Random numbers in tests ----------------------- diff --git a/test/aeswrap_test.c b/test/aeswrap_test.c index 1ec763e8f5b19..f15cfe9d0bcd8 100644 --- a/test/aeswrap_test.c +++ b/test/aeswrap_test.c @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ +#include #include "testutil.h" #include "internal/nelem.h" @@ -83,11 +84,84 @@ static int aeswrap_null_key_init_fail_test(int idx) return ret; } +#define GUARD_BYTE 0x7f +#define GUARD_LEN 8 + +/* + * Wrap with one ICV, unwrap with a different ICV so the AIV check fails. + * The output buffer has guard bytes to detect buffer overwriting on error. + */ +static int aeswrap_unwrap_pad_overflow_test(int plaintext_len) +{ + int ret = 0; + EVP_CIPHER_CTX *ctx = NULL; + EVP_CIPHER *cipher = NULL; + static const unsigned char aeswrap_test_key[16] = { 0 }; + unsigned char plaintext[16] = { 0 }, ciphertext[40], expected[24] = { 0 }; + int ct_len = 0, tmplen = 0; + size_t out_len; + unsigned char *out = NULL; + static const unsigned char wrap_icv[4] = { 0xA6, 0x59, 0x59, 0xA7 }; + static const unsigned char unwrap_icv[4] = { 0xA6, 0x59, 0x59, 0xA6 }; + + if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new()) + || !TEST_ptr(cipher = EVP_CIPHER_fetch(NULL, "AES-128-WRAP-PAD", NULL))) + goto err; + + if (!TEST_int_eq(EVP_CipherInit_ex2(ctx, cipher, aeswrap_test_key, + wrap_icv, 1, NULL), + 1) + || !TEST_int_eq(EVP_CipherUpdate(ctx, ciphertext, &ct_len, + plaintext, plaintext_len), + 1) + || !TEST_int_gt(ct_len, GUARD_LEN)) + goto err; + + out_len = (size_t)(ct_len - 8); + if (!TEST_ptr(out = OPENSSL_malloc(out_len + GUARD_LEN))) + goto err; + memset(out, GUARD_BYTE, out_len + GUARD_LEN); + + if (!TEST_int_eq(EVP_CipherInit_ex2(ctx, cipher, aeswrap_test_key, + unwrap_icv, 0, NULL), + 1) + || !TEST_int_eq(EVP_CipherUpdate(ctx, out, &tmplen, + ciphertext, ct_len), + 0)) + goto err; + + /* output area cleansed to zero, guard bytes untouched */ + memset(expected + out_len, GUARD_BYTE, GUARD_LEN); + if (!TEST_mem_eq(out, out_len + GUARD_LEN, expected, out_len + GUARD_LEN)) + goto err; + + ret = 1; +err: + OPENSSL_free(out); + EVP_CIPHER_free(cipher); + EVP_CIPHER_CTX_free(ctx); + return ret; +} + +/* 1 byte plaintext -> 16-byte ciphertext */ +static int aeswrap_unwrap_pad_n1_overflow_test(void) +{ + return aeswrap_unwrap_pad_overflow_test(1); +} + +/* 16 bytes plaintext -> 24-byte ciphertext */ +static int aeswrap_unwrap_pad_n2_overflow_test(void) +{ + return aeswrap_unwrap_pad_overflow_test(16); +} + int setup_tests(void) { ADD_TEST(aeswrap_input_size_fail_test); ADD_TEST(aeswrap_multi_update_fail_test); ADD_ALL_TESTS(aeswrap_null_key_init_fail_test, OSSL_NELEM(aeswrap_null_key_ciphers)); + ADD_TEST(aeswrap_unwrap_pad_n1_overflow_test); + ADD_TEST(aeswrap_unwrap_pad_n2_overflow_test); return 1; } diff --git a/test/ascon_aead128_parse.py b/test/ascon_aead128_parse.py new file mode 100644 index 0000000000000..7e8025be333b3 --- /dev/null +++ b/test/ascon_aead128_parse.py @@ -0,0 +1,214 @@ +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# Parse ASCON-AEAD128 test vectors from Ascon-C reference format to OpenSSL format. +# +# Input format: +# Count = N +# Key = ... +# Nonce = ... +# PT = ... +# AD = ... +# CT = ... (Ciphertext + Tag concatenated, where Tag is the last 16 bytes) +# Result = ... (optional; "valid ..." or "invalid ...") +# +# Output format: +# # (if Result was present) +# Cipher = ascon-aead128 +# Key = ... +# IV = ... +# Plaintext = ... +# AAD = ... +# Tag = ... (last 16 bytes of CT) +# Ciphertext = ... (CT without the last 16 bytes) +# Operation = DECRYPT (only if Result text started with "invalid") +# Result = CIPHERFINAL_ERROR (only if Result text started with "invalid") +# Reason = bad decrypt (only if Result text started with "invalid") +# +# NB "bad decrypt" = PROV_R_BAD_DECRYPT + +import hashlib +import os +import re +import sys + + +def parse_hex_field(value): + """Parse a hex field value, handling empty strings.""" + if not value or value.strip() == '': + return '' + # Remove any whitespace + return value.strip().upper() + + +def hex_to_bytes(hex_str): + """Convert hex string to bytes.""" + if not hex_str: + return b'' + return bytes.fromhex(hex_str) + + +def bytes_to_hex(byte_data): + """Convert bytes to hex string (uppercase, no spaces).""" + if not byte_data: + return '' + return byte_data.hex().upper() + + +def parse_test_vectors(input_file): + """Parse test vectors from the input file.""" + vectors = [] + current_vector = {} + + with open(input_file, 'r') as f: + for line in f: + line = line.strip() + + # Skip comments and empty lines (but empty lines end a vector) + if line.startswith('#'): + continue + + if not line: + # Empty line ends current vector + if current_vector: + vectors.append(current_vector) + current_vector = {} + continue + + # Parse key-value pairs + match = re.match(r'(\w+)\s*=\s*(.*)', line) + if match: + key = match.group(1).strip() + value = match.group(2).strip() + + if key == 'Count': + # Start of new vector + if current_vector: + vectors.append(current_vector) + current_vector = {} + elif key == 'Key': + current_vector['Key'] = parse_hex_field(value) + elif key == 'Nonce': + current_vector['Nonce'] = parse_hex_field(value) + elif key == 'PT': + current_vector['PT'] = parse_hex_field(value) + elif key == 'AD': + current_vector['AD'] = parse_hex_field(value) + elif key == 'CT': + current_vector['CT'] = parse_hex_field(value) + elif key == 'Result': + current_vector['Result'] = value + + # Don't forget the last vector if file doesn't end with blank line + if current_vector: + vectors.append(current_vector) + + return vectors + + +def format_output(vectors, input_file): + """Format vectors in the output format.""" + output_lines = [] + + # Header: sha256 digest and source filename + with open(input_file, 'rb') as f: + digest = hashlib.sha256(f.read()).hexdigest() + basename = os.path.basename(input_file) + output_lines.append(f"# {digest}") + output_lines.append(f"Title = {basename}") + output_lines.append("") + + for vec in vectors: + # Get fields with defaults + key = vec.get('Key', '') + nonce = vec.get('Nonce', '') + pt = vec.get('PT', '') + ad = vec.get('AD', '') + ct = vec.get('CT', '') + result = vec.get('Result', '') + + # Split CT into Ciphertext (all but last 16 bytes) and Tag (last 16 bytes) + ct_bytes = hex_to_bytes(ct) + + if len(ct_bytes) >= 16: + # Tag is the last 16 bytes + tag_bytes = ct_bytes[-16:] + ciphertext_bytes = ct_bytes[:-16] + else: + # If CT is less than 16 bytes, it's all ciphertext, tag is empty + tag_bytes = b'' + ciphertext_bytes = ct_bytes + + tag_hex = bytes_to_hex(tag_bytes) + ciphertext_hex = bytes_to_hex(ciphertext_bytes) + + # Emit comment from Result field if present + if result: + output_lines.append(f"# {result}") + + # Format output + output_lines.append("Cipher = ascon-aead128") + output_lines.append(f"Key = {key}") + output_lines.append(f"IV = {nonce}") + output_lines.append(f"Plaintext = {pt}") + output_lines.append(f"AAD = {ad}") + output_lines.append(f"Tag = {tag_hex}") + output_lines.append(f"Ciphertext = {ciphertext_hex}") + + # Negative test: Result starts with "invalid" + if result.lower().startswith('invalid'): + output_lines.append("Operation = DECRYPT") + output_lines.append("Result = CIPHERFINAL_ERROR") + output_lines.append("Reason = bad decrypt") + + output_lines.append("") # Blank line between vectors + + # Footer: test count + output_lines.append(f"# TestCount: {len(vectors)}") + output_lines.append("") + + return '\n'.join(output_lines) + + +def write_to_file(output_file, vectors, input_file): + """Write parsed vectors to the output file.""" + try: + with open(output_file, 'w') as f: + output = format_output(vectors, input_file) + f.write(output) + except IOError as e: + print(f"Error writing to file '{output_file}': {e}", file=sys.stderr) + sys.exit(1) + + +def main(): + if len(sys.argv) < 2 or len(sys.argv) > 3: + print("Usage: python3 ascon_aead128_parse.py [output_file]", file=sys.stderr) + print(" If output_file is provided, results will be appended to it.", file=sys.stderr) + print(" Otherwise, results will be printed to stdout.", file=sys.stderr) + sys.exit(1) + + input_file = sys.argv[1] + output_file = sys.argv[2] if len(sys.argv) == 3 else None + + try: + vectors = parse_test_vectors(input_file) + if output_file: + write_to_file(output_file, vectors, input_file) + else: + output = format_output(vectors, input_file) + print(output) + except FileNotFoundError: + print(f"Error: File '{input_file}' not found", file=sys.stderr) + sys.exit(1) + except Exception as e: + print(f"Error: {e}", file=sys.stderr) + sys.exit(1) + + +if __name__ == '__main__': + main() diff --git a/test/asn1_decode_test.c b/test/asn1_decode_test.c index 8a9629c21dc30..5fd9aad61fdb8 100644 --- a/test/asn1_decode_test.c +++ b/test/asn1_decode_test.c @@ -427,6 +427,52 @@ static int test_d2i_read_bio_partial_header(void) return ret; } +/* + * Regression test for reading multiple ASN1_INTEGERs written + * into a memory BIO. ASN1_item_d2i_bio() must consume exactly the + * bytes belonging to each object, since ASN.1 integer uses only 3 bytes. + */ +static int test_d2i_bio_concatenated_integers(void) +{ + ASN1_INTEGER *int0 = NULL, *int1 = NULL, *int2 = NULL; + BIO *writer = NULL, *reader = NULL; + char *buf; + long len; + int ret = 0; + + if (!TEST_ptr(int0 = ASN1_INTEGER_new()) + || !TEST_true(ASN1_INTEGER_set(int0, 1))) + goto err; + + if (!TEST_ptr(writer = BIO_new(BIO_s_mem())) + || !TEST_int_eq(ASN1_item_i2d_bio(ASN1_INTEGER_it(), writer, int0), 1) + || !TEST_int_eq(ASN1_item_i2d_bio(ASN1_INTEGER_it(), writer, int0), 1)) + goto err; + + if (!TEST_int_gt(len = BIO_get_mem_data(writer, &buf), 0) + || !TEST_ptr(reader = BIO_new_mem_buf(buf, len))) + goto err; + + if (!TEST_ptr(int1 = (ASN1_INTEGER *)ASN1_item_d2i_bio(ASN1_INTEGER_it(), + reader, NULL)) + || !TEST_int_eq(ASN1_INTEGER_cmp(int0, int1), 0)) + goto err; + + if (!TEST_ptr(int2 = (ASN1_INTEGER *)ASN1_item_d2i_bio(ASN1_INTEGER_it(), + reader, NULL)) + || !TEST_int_eq(ASN1_INTEGER_cmp(int0, int2), 0)) + goto err; + + ret = 1; +err: + ASN1_INTEGER_free(int0); + ASN1_INTEGER_free(int1); + ASN1_INTEGER_free(int2); + BIO_free(reader); + BIO_free(writer); + return ret; +} + int setup_tests(void) { #ifndef OPENSSL_NO_DEPRECATED_3_0 @@ -444,5 +490,6 @@ int setup_tests(void) ADD_TEST(test_d2i_read_bio_truncated); ADD_TEST(test_d2i_read_bio_indefinite_truncated); ADD_TEST(test_d2i_read_bio_partial_header); + ADD_TEST(test_d2i_bio_concatenated_integers); return 1; } diff --git a/test/asn1_internal_test.c b/test/asn1_internal_test.c index 469daafc4ca26..172636c71fdb4 100644 --- a/test/asn1_internal_test.c +++ b/test/asn1_internal_test.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "testutil.h" #include "internal/nelem.h" @@ -265,12 +266,16 @@ static int test_asn1_time_conversion(char *time_string, const char *file, V_ASN1_GENERALIZEDTIME))) goto err; } - if (!TEST_true((strcmp(time_string, - (const char *)ASN1_STRING_get0_data(result)) - == 0))) { - TEST_info("Expected time: %s, Got time: %s\n", time_string, - ASN1_STRING_get0_data(result)); - goto err; + { + size_t rlen = ASN1_STRING_get_length(result); + const char *rdata = (const char *)ASN1_STRING_get0_data(result); + + if (!TEST_size_t_eq(strlen(time_string), rlen) + || !TEST_int_eq(memcmp(time_string, rdata, rlen), 0)) { + TEST_info("Expected time: %s, Got time: %.*s\n", time_string, + (int)rlen, rdata); + goto err; + } } ret = 1; @@ -587,6 +592,171 @@ static int test_ossl_uni2utf8(void) return ok; } +static int test_empty_uni_conversions(void) +{ + char *out = NULL; + int ok = 0; + + /* + * A decoded empty BMPString is a NULL data pointer with a zero length, + * which is how an empty PKCS12 friendlyName reaches these functions by + * way of ASN1_STRING_get0_data(). + */ + if (!TEST_ptr(out = OPENSSL_uni2asc(NULL, 0)) + || !TEST_str_eq(out, "")) + goto err; + OPENSSL_free(out); + out = NULL; + + if (!TEST_ptr(out = OPENSSL_uni2utf8(NULL, 0)) + || !TEST_str_eq(out, "")) + goto err; + + ok = 1; +err: + OPENSSL_free(out); + return ok; +} + +static int test_asn1_string_to_utf8(void) +{ + static const unsigned char bmp[] = { 0x00, 'A', 0x00, 'B' }; + ASN1_STRING in; + unsigned char *out = NULL; + int len, ok = 0; + + in.flags = 0; + + /* UTF8String in: same-format path of ASN1_mbstring_copy() */ + in.type = V_ASN1_UTF8STRING; + in.data = (unsigned char *)"ABC"; + in.length = 3; + len = ASN1_STRING_to_UTF8(&out, &in); + if (!TEST_int_eq(len, 3) + || !TEST_ptr(out) + || !TEST_mem_eq(out, len, "ABC", 3) + || !TEST_true(out[len] == '\0')) + goto err; + OPENSSL_free(out); + out = NULL; + + /* BMPString in: converting path */ + in.type = V_ASN1_BMPSTRING; + in.data = (unsigned char *)bmp; + in.length = (int)sizeof(bmp); + len = ASN1_STRING_to_UTF8(&out, &in); + if (!TEST_int_eq(len, 2) + || !TEST_ptr(out) + || !TEST_mem_eq(out, len, "AB", 2) + || !TEST_true(out[len] == '\0')) + goto err; + OPENSSL_free(out); + out = NULL; + + /* Empty input still yields a NUL terminated buffer */ + in.type = V_ASN1_UTF8STRING; + in.data = (unsigned char *)""; + in.length = 0; + len = ASN1_STRING_to_UTF8(&out, &in); + if (!TEST_int_eq(len, 0) + || !TEST_ptr(out) + || !TEST_true(out[0] == '\0')) + goto err; + OPENSSL_free(out); + out = NULL; + + /* + * The decoder represents an empty string as a NULL data pointer with a + * zero length, not as a pointer to zero bytes, so cover that separately. + */ + in.type = V_ASN1_UTF8STRING; + in.data = NULL; + in.length = 0; + len = ASN1_STRING_to_UTF8(&out, &in); + if (!TEST_int_eq(len, 0) + || !TEST_ptr(out) + || !TEST_true(out[0] == '\0')) + goto err; + + ok = 1; +err: + OPENSSL_free(out); + return ok; +} + +static int asn1_dup_test_op_dup_post_count; +static int asn1_dup_test_op_free_post_count; +static int asn1_dup_test_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_DUP_POST) { + asn1_dup_test_op_dup_post_count++; + return 0; + } + if (operation == ASN1_OP_FREE_POST) + asn1_dup_test_op_free_post_count++; + return 1; +} + +typedef struct { + ASN1_INTEGER *value; +} ASN1_DUP_TEST; + +ASN1_SEQUENCE_cb(ASN1_DUP_TEST, asn1_dup_test_cb) = { + ASN1_SIMPLE(ASN1_DUP_TEST, value, ASN1_INTEGER) +} static_ASN1_SEQUENCE_END_cb(ASN1_DUP_TEST, ASN1_DUP_TEST) + +IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(ASN1_DUP_TEST) + +static int test_asn1_item_dup_failure_frees(void) +{ + ASN1_DUP_TEST *src = NULL, *dup = NULL; + int ret = 0; + + if (!TEST_ptr(src = ASN1_DUP_TEST_new()) + || !TEST_true(ASN1_INTEGER_set(src->value, 1))) + goto end; + + asn1_dup_test_op_dup_post_count = 0; + asn1_dup_test_op_free_post_count = 0; + dup = ASN1_item_dup(ASN1_ITEM_rptr(ASN1_DUP_TEST), src); + + ret = TEST_ptr_null(dup) + && TEST_int_eq(asn1_dup_test_op_dup_post_count, 1) + && TEST_int_eq(asn1_dup_test_op_free_post_count, 1); +end: + ASN1_DUP_TEST_free(src); + ASN1_DUP_TEST_free(dup); + return ret; +} + +#ifndef OPENSSL_NO_ECX +static int test_asn1_item_dup_mfail(void) +{ + EVP_PKEY *key = NULL; + X509_REQ *src = NULL, *dup = NULL; + int ret = -1; + + if (!TEST_ptr(key = EVP_PKEY_Q_keygen(NULL, NULL, "ED25519")) + || !TEST_ptr(src = X509_REQ_new_ex(NULL, "")) + || !TEST_true(X509_REQ_set_version(src, X509_REQ_VERSION_1)) + || !TEST_true(X509_REQ_set_pubkey(src, key)) + || !TEST_int_gt(X509_REQ_sign(src, key, NULL), 0)) + goto end; + + MFAIL_start(); + dup = X509_REQ_dup(src); + MFAIL_end(); + + ret = dup != NULL; +end: + EVP_PKEY_free(key); + X509_REQ_free(src); + X509_REQ_free(dup); + return ret; +} +#endif + int setup_tests(void) { ADD_TEST(test_tbl_standard); @@ -600,5 +770,11 @@ int setup_tests(void) ADD_TEST(test_asn1_time_tm_conversions); ADD_TEST(test_mbstring_ncopy); ADD_TEST(test_ossl_uni2utf8); + ADD_TEST(test_empty_uni_conversions); + ADD_TEST(test_asn1_string_to_utf8); + ADD_TEST(test_asn1_item_dup_failure_frees); +#ifndef OPENSSL_NO_ECX + ADD_MFAIL_NO_CHECK_TEST(test_asn1_item_dup_mfail); +#endif return 1; } diff --git a/test/asn1_string_poison_test.c b/test/asn1_string_poison_test.c new file mode 100644 index 0000000000000..76508117c59f8 --- /dev/null +++ b/test/asn1_string_poison_test.c @@ -0,0 +1,114 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/** + * @file asn1_string_poison_test.c + * Checks that the NUL terminator libcrypto writes after ASN1_STRING data is + * inaccessible under AddressSanitizer, MemorySanitizer and Valgrind. Run + * with no argument the program reads the terminator with strlen() and is + * expected to be killed by the sanitizer; run with "counted" it reads only + * the counted bytes and is expected to exit successfully. Without a + * sanitizer the strlen() run exits with failure itself; with one, surviving + * the strlen() exits successfully, which the recipe reports as a failure. + * Under Valgrind the process survives the strlen() and memcheck reports the + * read. When OSSL_VALGRIND_CT is set the test framework runs memcheck with + * --error-exitcode=1, and the program exits successfully after the strlen() + * the same way, leaving the exit status to memcheck; under any other + * Valgrind wrapper it exits with failure. + */ + +#include +#include +#include + +#include "testutil.h" + +#if defined(__has_feature) +#if __has_feature(address_sanitizer) || __has_feature(memory_sanitizer) +#define HAVE_SANITIZER 1 +#endif +#endif /* defined(__has_feature) */ +#if defined(__SANITIZE_ADDRESS__) && !defined(HAVE_SANITIZER) +#define HAVE_SANITIZER 1 +#endif +#if defined __has_include +/* Any compiler you're going to run valgrind on has this */ +#if __has_include() +#include +#endif +#endif /* defined(__has_include) */ + +/* DER UTF8String "hello" */ +static const unsigned char der[] = { 0x0c, 0x05, 'h', 'e', 'l', 'l', 'o' }; + +/** + * @brief Report whether a checker decides this run's exit status. + * That is a sanitizer, or memcheck run by the test framework with + * --error-exitcode=1 (OSSL_VALGRIND_CT). + * @returns 1 when the checker sets the exit status, 0 otherwise + */ +static int checker_sets_exit_status(void) +{ +#if defined(HAVE_SANITIZER) + return 1; +#else +#if defined(RUNNING_ON_VALGRIND) + if (RUNNING_ON_VALGRIND && getenv("OSSL_VALGRIND_CT") != NULL) + return 1; +#endif + return 0; +#endif /* defined(HAVE_SANITIZER) */ +} + +/* + * A plain main() rather than the test framework's: the failing run is + * expected to die inside the sanitizer, which the framework would report + * as a crash. + */ +int main(int argc, char *argv[]) +{ + const unsigned char *p = der; + ASN1_UTF8STRING *str = d2i_ASN1_UTF8STRING(NULL, &p, sizeof(der)); + const unsigned char *data; + volatile size_t sink; + int exitcode = EXIT_FAILURE; + + if (!TEST_ptr(str) + || !TEST_size_t_eq(ASN1_STRING_get_length(str), 5)) + goto end; + data = ASN1_STRING_get0_data(str); + + if (argc > 1 && strcmp(argv[1], "counted") == 0) { + /* Counted access never touches the terminator. */ + if (TEST_mem_eq(data, ASN1_STRING_get_length(str), "hello", 5)) + exitcode = EXIT_SUCCESS; + goto end; + } + + /* + * Reads the terminator; a sanitizer kills the process here, memcheck + * reports the read and lets the process continue. + */ + sink = strlen((const char *)data); + (void)sink; + if (checker_sets_exit_status()) { + /* + * Reached under a sanitizer only when it did not report the read. + * The recipe expects this run to fail: under a sanitizer a + * successful exit is that failure; under memcheck the exit status + * is replaced by --error-exitcode when the read was reported. + */ + TEST_note("strlen() on ASN1_STRING data survived"); + exitcode = EXIT_SUCCESS; + } + +end: + ASN1_UTF8STRING_free(str); + return exitcode; +} diff --git a/test/asn1_string_test.c b/test/asn1_string_test.c index 6edc7619f742e..4efe63ebe6f55 100644 --- a/test/asn1_string_test.c +++ b/test/asn1_string_test.c @@ -410,13 +410,13 @@ asn1_string_new_not_owned_test(void) if (!TEST_ptr(tmp = ASN1_STRING_new_not_owned(V_ASN1_OCTET_STRING, data, sizeof(data)))) goto err; - if (!TEST_true(ASN1_STRING_set(tmp, "muppet", (int)strlen("muppet")))) + if (!TEST_true(ASN1_STRING_set1_string(tmp, "muppet"))) goto err; if (!TEST_mem_eq(data, sizeof(data), data2, sizeof(data2))) goto err; - if (!TEST_int_eq(ASN1_STRING_length(tmp), (int)strlen("muppet"))) + if (!TEST_size_t_eq(ASN1_STRING_get_length(tmp), strlen("muppet"))) goto err; if (!TEST_mem_eq(ASN1_STRING_get0_data(tmp), strlen("muppet"), "muppet", strlen("muppet"))) @@ -436,13 +436,13 @@ asn1_string_new_not_owned_test(void) if (!TEST_mem_eq(data, sizeof(data), data2, sizeof(data2))) goto err; - if (!TEST_int_eq(ASN1_STRING_length(tmp), 4)) + if (!TEST_size_t_eq(ASN1_STRING_get_length(tmp), 4)) goto err; if (!TEST_mem_eq(ASN1_STRING_get0_data(tmp), strlen("puppet"), "puppet", strlen("puppet"))) goto err; - memset((uint8_t *)ASN1_STRING_get0_data(tmp), 'z', ASN1_STRING_length(tmp)); + memset((uint8_t *)ASN1_STRING_get0_data(tmp), 'z', ASN1_STRING_get_length(tmp)); if (!TEST_mem_eq(data, sizeof(data), data2, sizeof(data2))) goto err; @@ -474,10 +474,196 @@ asn1_string_new_not_owned_test(void) return success; } +static int +asn1_string_set_data_test(void) +{ + int success = 0; + ASN1_STRING *str = NULL; + const uint8_t *data; + + if (!TEST_ptr(str = ASN1_STRING_new())) + goto err; + + if (!TEST_false(ASN1_STRING_set1_data(str, (uint8_t *)"hoobla", -1))) + goto err; + + if (!TEST_false(ASN1_STRING_set1_data(str, (uint8_t *)"hoobla", (size_t)INT_MAX + 1))) + goto err; + + if (!TEST_true(ASN1_STRING_set1_data(str, NULL, 10))) + goto err; + + if (!TEST_true(ASN1_STRING_set1_data(str, (uint8_t *)"hoobla", strlen("hoobla")))) + goto err; + + data = ASN1_STRING_get0_data(str); + + if (!TEST_size_t_eq(ASN1_STRING_get_length(str), 6)) + goto err; + + if (!TEST_int_eq(memcmp("hoobla", data, strlen("hoobla")), 0)) + goto err; + + if (!TEST_true(ASN1_STRING_set1_data(str, (uint8_t *)"hoobla", strlen("hoobla") + 1))) + goto err; + + data = ASN1_STRING_get0_data(str); + + if (!TEST_size_t_eq(ASN1_STRING_get_length(str), 7)) + goto err; + + if (!TEST_int_eq(strcmp("hoobla", (char *)data), 0)) + goto err; + + success = 1; + +err: + ASN1_STRING_free(str); + return success; +} + +static int +asn1_string_set_string_test(void) +{ + int success = 0; + ASN1_STRING *str = NULL; + + if (!TEST_ptr(str = ASN1_STRING_new())) + goto err; + + if (!TEST_true(ASN1_STRING_set1_string(str, "foo"))) + goto err; + + if (!TEST_size_t_eq(ASN1_STRING_get_length(str), 3)) + goto err; + + if (!TEST_true(ASN1_STRING_set1_string(str, "hoob\0la"))) + goto err; + + if (!TEST_size_t_eq(ASN1_STRING_get_length(str), 4)) + goto err; + + success = 1; + +err: + ASN1_STRING_free(str); + return success; +} + +static int +asn1_string_set0_test(void) +{ + int success = 0; + ASN1_STRING *str = NULL; + uint8_t *data = NULL; + + if (!TEST_ptr(str = ASN1_STRING_new())) + goto err; + + if (!TEST_ptr(data = (uint8_t *)OPENSSL_strdup("hoobla"))) + goto err; + + /* A negative length can never be valid and is treated as empty */ + ASN1_STRING_set0(str, data, -1); + + if (!TEST_size_t_eq(ASN1_STRING_get_length(str), 0)) + goto err; + + /* The string takes ownership of the data even so */ + if (!TEST_ptr_eq(ASN1_STRING_get0_data(str), data)) + goto err; + + data = NULL; + + if (!TEST_ptr(data = (uint8_t *)OPENSSL_strdup("hoobla"))) + goto err; + + ASN1_STRING_set0(str, data, (int)strlen("hoobla")); + + if (!TEST_size_t_eq(ASN1_STRING_get_length(str), 6)) + goto err; + + if (!TEST_ptr_eq(ASN1_STRING_get0_data(str), data)) + goto err; + + data = NULL; + + success = 1; + +err: + OPENSSL_free(data); + ASN1_STRING_free(str); + return success; +} + +static int +asn1_universalstring_to_string_test(void) +{ + int success = 0; + ASN1_STRING *str = NULL; + static const uint8_t abc[] = { 0, 0, 0, 'A', 0, 0, 0, 'B', 0, 0, 0, 'C' }; + + /* + * An empty UniversalString, as decoded from an empty string, has + * data == NULL and length == 0. Conversion succeeds and leaves it + * empty, with the type rewritten like any successful conversion. + */ + if (!TEST_ptr(str = ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING))) + goto err; + + if (!TEST_true(ASN1_UNIVERSALSTRING_to_string(str))) + goto err; + + if (!TEST_size_t_eq(ASN1_STRING_get_length(str), 0)) + goto err; + + if (!TEST_ptr_null(ASN1_STRING_get0_data(str))) + goto err; + + if (!TEST_int_eq(ASN1_STRING_type(str), V_ASN1_PRINTABLESTRING)) + goto err; + + /* The type is no longer UniversalString, so a second conversion fails. */ + if (!TEST_false(ASN1_UNIVERSALSTRING_to_string(str))) + goto err; + + ASN1_STRING_free(str); + str = NULL; + + /* A non-empty UniversalString converts to its compacted form. */ + if (!TEST_ptr(str = ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING))) + goto err; + + if (!TEST_true(ASN1_STRING_set1_data(str, abc, sizeof(abc)))) + goto err; + + if (!TEST_true(ASN1_UNIVERSALSTRING_to_string(str))) + goto err; + + if (!TEST_size_t_eq(ASN1_STRING_get_length(str), 3)) + goto err; + + if (!TEST_mem_eq(ASN1_STRING_get0_data(str), 3, "ABC", 3)) + goto err; + + if (!TEST_int_eq(ASN1_STRING_type(str), V_ASN1_PRINTABLESTRING)) + goto err; + + success = 1; + +err: + ASN1_STRING_free(str); + return success; +} + int setup_tests(void) { ADD_ALL_TESTS(asn1_bit_string_get_length_test, OSSL_NELEM(abs_get_length_tests)); ADD_ALL_TESTS(asn1_bit_string_set1_test, OSSL_NELEM(abs_set1_tests)); ADD_TEST(asn1_string_new_not_owned_test); + ADD_TEST(asn1_string_set_data_test); + ADD_TEST(asn1_string_set_string_test); + ADD_TEST(asn1_string_set0_test); + ADD_TEST(asn1_universalstring_to_string_test); return 1; } diff --git a/test/asn1_time_test.c b/test/asn1_time_test.c index 19ec1c3aa9432..d6d73cbfa14cf 100644 --- a/test/asn1_time_test.c +++ b/test/asn1_time_test.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -674,7 +674,7 @@ static int test_table(struct testdata *tbl, int idx) int day, sec; atime.data = (unsigned char *)td->data; - atime.length = (int)strlen((char *)atime.data); + atime.length = (int)strlen(td->data); atime.type = td->type; atime.flags = 0; @@ -719,8 +719,8 @@ static int test_table(struct testdata *tbl, int idx) } else { int local_error = 0; if (!TEST_int_eq(ASN1_TIME_cmp_time_t(ptime, td->t), 0)) { - TEST_info("ASN1_TIME_set(%ld) compare failed (%s->%s)", - (long)td->t, td->data, ptime->data); + TEST_info("ASN1_TIME_set(%ld) compare failed (%s->%.*s)", + (long)td->t, td->data, ptime->length, ptime->data); local_error = error = 1; } if (!TEST_int_eq(ptime->type, td->expected_type)) { @@ -728,7 +728,7 @@ static int test_table(struct testdata *tbl, int idx) local_error = error = 1; } if (local_error) - TEST_info("ASN1_TIME_set() = %*s", ptime->length, ptime->data); + TEST_info("ASN1_TIME_set() = %.*s", ptime->length, ptime->data); ASN1_TIME_free(ptime); } @@ -760,7 +760,7 @@ static int test_table(struct testdata *tbl, int idx) local_error = error = 1; } if (local_error) - TEST_info("ASN1_TIME_set_string_gmt() = %*s", ptime->length, ptime->data); + TEST_info("ASN1_TIME_set_string_gmt() = %.*s", ptime->length, ptime->data); ASN1_TIME_free(ptime); } @@ -784,7 +784,7 @@ static int test_table(struct testdata *tbl, int idx) local_error = error = 1; } if (local_error) - TEST_info("ASN1_TIME_set_string() = %*s", ptime->length, ptime->data); + TEST_info("ASN1_TIME_set_string() = %.*s", ptime->length, ptime->data); ASN1_TIME_free(ptime); } @@ -798,7 +798,8 @@ static int test_table(struct testdata *tbl, int idx) error = 1; } if (ptime != NULL && !TEST_int_eq(ASN1_TIME_cmp_time_t(ptime, td->t), 0)) { - TEST_info("ASN1_TIME_to_generalizedtime(%s->%s) bad result", atime.data, ptime->data); + TEST_info("ASN1_TIME_to_generalizedtime(%s->%.*s) bad result", atime.data, + ptime->length, ptime->data); error = 1; } ASN1_TIME_free(ptime); diff --git a/test/bad_dtls_test.c b/test/bad_dtls_test.c index 368921021d75e..fe874061cd6af 100644 --- a/test/bad_dtls_test.c +++ b/test/bad_dtls_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/bftest.c b/test/bftest.c index 3b6d2ee4b6d32..17ed49dc589d5 100644 --- a/test/bftest.c +++ b/test/bftest.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/bio_base64_test.c b/test/bio_base64_test.c index 9d9ef4dfa0f9f..2ef639e45fab9 100644 --- a/test/bio_base64_test.c +++ b/test/bio_base64_test.c @@ -50,6 +50,159 @@ static unsigned linelengths[] = { }; static unsigned wscnts[] = { 0, 1, 2, 4, 8, 16, 0xFFFF }; +#define B64_WRITE_INJECT_RETRY_NEG 0 +#define B64_WRITE_INJECT_RETRY_ZERO 1 +#define B64_WRITE_INJECT_SHORT 2 +#define B64_WRITE_INJECT_SHORT_THEN_RETRY 3 +#define B64_WRITE_INJECT_NONE (-1) +#define B64_WRITE_INJECT_AFTER_SHORT_RETRY (-2) +#define B64_WRITE_INJECT_COUNT 4 +#define B64_WRITE_TEST_LINE_INPUT_LEN 48 +#define B64_WRITE_TEST_INPUT_LEN_ALIGNED 96 +#define B64_WRITE_TEST_INPUT_LEN_TAIL 97 +#define B64_WRITE_TEST_INPUT_COUNT 2 +#define B64_WRITE_TEST_SECOND_INPUT_LEN 49 +#define B64_WRITE_TEST_SHORT_LEN 5 +#define B64_WRITE_SCENARIO_FLUSH_ONLY 0 +#define B64_WRITE_SCENARIO_SECOND_WRITE_DRAINS 1 +#define B64_WRITE_SCENARIO_SECOND_WRITE_INJECTS 2 +#define B64_WRITE_SCENARIO_COUNT 3 + +typedef struct { + int inject; +} b64_write_test_data; + +static BIO_METHOD *b64_write_test_method = NULL; +static const int b64_write_test_input_lens[B64_WRITE_TEST_INPUT_COUNT] = { + B64_WRITE_TEST_INPUT_LEN_ALIGNED, + B64_WRITE_TEST_INPUT_LEN_TAIL +}; + +static int b64_write_test_update_len(int inl, int no_nl) +{ + int update_inl = inl - inl % B64_WRITE_TEST_LINE_INPUT_LEN; + int ret = update_inl / 3 * 4; + + if (!no_nl) + ret += update_inl / B64_WRITE_TEST_LINE_INPUT_LEN; + return ret; +} + +static int b64_write_test_update_len_since(int previous_inl, int inl, + int no_nl) +{ + return b64_write_test_update_len(previous_inl + inl, no_nl) + - b64_write_test_update_len(previous_inl, no_nl); +} + +static int b64_write_test_final_pending(int inl) +{ + return inl % B64_WRITE_TEST_LINE_INPUT_LEN != 0; +} + +static int b64_write_test_new(BIO *bio) +{ + b64_write_test_data *data = OPENSSL_zalloc(sizeof(*data)); + + if (data == NULL) + return 0; + + BIO_set_data(bio, data); + BIO_set_init(bio, 1); + return 1; +} + +static int b64_write_test_free(BIO *bio) +{ + b64_write_test_data *data = BIO_get_data(bio); + + OPENSSL_free(data); + BIO_set_data(bio, NULL); + BIO_set_init(bio, 0); + return 1; +} + +static int b64_write_test_write(BIO *bio, const char *in, int inl) +{ + b64_write_test_data *data = BIO_get_data(bio); + BIO *next = BIO_next(bio); + int ret; + + BIO_clear_retry_flags(bio); + if (data == NULL || next == NULL) + return 0; + + switch (data->inject) { + case B64_WRITE_INJECT_RETRY_NEG: + case B64_WRITE_INJECT_AFTER_SHORT_RETRY: + data->inject = B64_WRITE_INJECT_NONE; + BIO_set_retry_write(bio); + return -1; + + case B64_WRITE_INJECT_RETRY_ZERO: + data->inject = B64_WRITE_INJECT_NONE; + BIO_set_retry_write(bio); + return 0; + + case B64_WRITE_INJECT_SHORT: + data->inject = B64_WRITE_INJECT_NONE; + if (inl > B64_WRITE_TEST_SHORT_LEN) + inl = B64_WRITE_TEST_SHORT_LEN; + break; + + case B64_WRITE_INJECT_SHORT_THEN_RETRY: + data->inject = B64_WRITE_INJECT_AFTER_SHORT_RETRY; + if (inl > B64_WRITE_TEST_SHORT_LEN) + inl = B64_WRITE_TEST_SHORT_LEN; + break; + } + + ret = BIO_write(next, in, inl); + BIO_copy_next_retry(bio); + return ret; +} + +static long b64_write_test_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + BIO *next = BIO_next(bio); + long ret; + + if (next == NULL) + return 0; + + BIO_clear_retry_flags(bio); + ret = BIO_ctrl(next, cmd, num, ptr); + BIO_copy_next_retry(bio); + return ret; +} + +static const BIO_METHOD *bio_f_b64_write_test(void) +{ + int type; + + if (b64_write_test_method == NULL) { + type = BIO_get_new_index(); + if (type == -1) + return NULL; + + if ((b64_write_test_method = BIO_meth_new(type | BIO_TYPE_FILTER, "b64 write test")) == NULL + || !BIO_meth_set_write(b64_write_test_method, + b64_write_test_write) + || !BIO_meth_set_ctrl(b64_write_test_method, + b64_write_test_ctrl) + || !BIO_meth_set_create(b64_write_test_method, + b64_write_test_new) + || !BIO_meth_set_destroy(b64_write_test_method, + b64_write_test_free)) { + BIO_meth_free(b64_write_test_method); + b64_write_test_method = NULL; + return NULL; + } + } + + return b64_write_test_method; +} + /* Generate `len` random octets */ static unsigned char *genbytes(unsigned len) { @@ -428,6 +581,195 @@ static int test_bio_base64_corner_case_bug(int idx) return generic_case(&t, 0); } +static int base64_encode_reference(const char *in, int inl, int no_nl, + unsigned char **out, size_t *out_len) +{ + BIO *b64 = NULL; + BIO *mem = NULL; + BUF_MEM *bptr = NULL; + int ok = 0; + + *out = NULL; + *out_len = 0; + + if (!TEST_ptr(b64 = BIO_new(BIO_f_base64())) + || !TEST_ptr(mem = BIO_new(BIO_s_mem()))) + goto done; + + if (no_nl) + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + + if (!TEST_ptr_eq(BIO_push(b64, mem), b64) + || !TEST_int_eq(BIO_write(b64, in, inl), inl) + || !TEST_true(BIO_flush(b64))) + goto done; + + BIO_get_mem_ptr(mem, &bptr); + if (!TEST_ptr(bptr)) + goto done; + + if (bptr->length > 0) { + if (!TEST_ptr(*out = OPENSSL_memdup(bptr->data, bptr->length))) + goto done; + *out_len = bptr->length; + } + ok = 1; + +done: + BIO_free_all(b64); + return ok; +} + +static int b64_write_test_check_injected_state(BIO *b64, int mode, + int update_len, + int final_pending) +{ + switch (mode) { + case B64_WRITE_INJECT_RETRY_NEG: + case B64_WRITE_INJECT_RETRY_ZERO: + return TEST_true(BIO_should_retry(b64)) + && TEST_int_eq(BIO_wpending(b64), update_len); + + case B64_WRITE_INJECT_SHORT_THEN_RETRY: + return TEST_true(BIO_should_retry(b64)) + && TEST_int_eq(BIO_wpending(b64), + update_len - B64_WRITE_TEST_SHORT_LEN); + + case B64_WRITE_INJECT_SHORT: + return TEST_false(BIO_should_retry(b64)) + && TEST_int_eq(BIO_wpending(b64), final_pending); + + default: + TEST_error("Invalid base64 write injection mode: %d", mode); + return 0; + } +} + +static int test_bio_base64_write_retry(int idx) +{ + char msg[B64_WRITE_TEST_INPUT_LEN_TAIL + B64_WRITE_TEST_SECOND_INPUT_LEN]; + BIO *b64 = NULL; + BIO *inject = NULL; + BIO *mem = NULL; + BIO *membio = NULL; + BUF_MEM *bptr = NULL; + b64_write_test_data *data; + unsigned char *expected = NULL; + size_t expected_len = 0; + int mode; + int no_nl; + int scenario; + int input_idx; + int in_len; + int total_len; + int update_len; + int first_final_pending; + int q = idx; + int ret; + int ok = 0; + + mode = quotrem(q, B64_WRITE_INJECT_COUNT, &q); + no_nl = quotrem(q, 2, &q); + scenario = quotrem(q, B64_WRITE_SCENARIO_COUNT, &q); + input_idx = quotrem(q, B64_WRITE_TEST_INPUT_COUNT, &q); + if (q != 0) { + fprintf(stderr, "Test index out of range: %d", idx); + return 0; + } + in_len = b64_write_test_input_lens[input_idx]; + total_len = in_len; + if (scenario != B64_WRITE_SCENARIO_FLUSH_ONLY) + total_len += B64_WRITE_TEST_SECOND_INPUT_LEN; + update_len = b64_write_test_update_len_since(0, in_len, no_nl); + first_final_pending = b64_write_test_final_pending(in_len); + memset(msg, 'A', in_len); + memset(msg + in_len, 'B', B64_WRITE_TEST_SECOND_INPUT_LEN); + + if (!TEST_true(base64_encode_reference(msg, total_len, no_nl, + &expected, &expected_len)) + || !TEST_ptr(b64 = BIO_new(BIO_f_base64())) + || !TEST_ptr(inject = BIO_new(bio_f_b64_write_test())) + || !TEST_ptr(mem = BIO_new(BIO_s_mem()))) + goto done; + + data = BIO_get_data(inject); + if (!TEST_ptr(data)) + goto done; + data->inject = scenario == B64_WRITE_SCENARIO_SECOND_WRITE_INJECTS + ? B64_WRITE_INJECT_NONE + : mode; + + if (no_nl) + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + + membio = mem; + if (!TEST_ptr_eq(BIO_push(inject, mem), inject)) + goto done; + mem = NULL; + + if (!TEST_ptr_eq(BIO_push(b64, inject), b64)) + goto done; + inject = NULL; + + ret = BIO_write(b64, msg, in_len); + if (!TEST_int_eq(ret, in_len)) + goto done; + + if (scenario == B64_WRITE_SCENARIO_SECOND_WRITE_INJECTS) { + if (!TEST_false(BIO_should_retry(b64)) + || !TEST_int_eq(BIO_wpending(b64), first_final_pending)) + goto done; + } else if (!b64_write_test_check_injected_state(b64, mode, update_len, + first_final_pending)) { + goto done; + } + + /* + * Verify both second-write paths: pending encoded output is flushed before + * newly supplied input is accepted, and an injected second write with no + * prior encoded-output pending retains its own unwritten output. + */ + if (scenario != B64_WRITE_SCENARIO_FLUSH_ONLY) { + if (scenario == B64_WRITE_SCENARIO_SECOND_WRITE_INJECTS) + data->inject = mode; + + ret = BIO_write(b64, msg + in_len, B64_WRITE_TEST_SECOND_INPUT_LEN); + if (!TEST_int_eq(ret, B64_WRITE_TEST_SECOND_INPUT_LEN)) + goto done; + + if (scenario == B64_WRITE_SCENARIO_SECOND_WRITE_INJECTS) { + update_len = b64_write_test_update_len_since(in_len, + B64_WRITE_TEST_SECOND_INPUT_LEN, + no_nl); + if (!b64_write_test_check_injected_state( + b64, mode, update_len, + b64_write_test_final_pending(total_len))) + goto done; + } else if (!TEST_false(BIO_should_retry(b64)) + || !TEST_int_eq(BIO_wpending(b64), + b64_write_test_final_pending(total_len))) { + goto done; + } + } + + if (!TEST_true(BIO_flush(b64))) + goto done; + + BIO_get_mem_ptr(membio, &bptr); + if (!TEST_ptr(bptr) + || !TEST_mem_eq(expected, expected_len, bptr->data, bptr->length)) + goto done; + + ok = 1; + +done: + BIO_free_all(b64); + BIO_free_all(inject); + BIO_free(mem); + OPENSSL_free(expected); + return ok; +} + #define MEM_CHK "QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB" \ "QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB" \ "QUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFB" @@ -522,6 +864,15 @@ int setup_tests(void) numidx = 2 * 2; ADD_ALL_TESTS(test_bio_base64_corner_case_bug, numidx); + ADD_ALL_TESTS(test_bio_base64_write_retry, + B64_WRITE_INJECT_COUNT * 2 * B64_WRITE_SCENARIO_COUNT + * B64_WRITE_TEST_INPUT_COUNT); ADD_TEST(test_bio_base64_no_nl); return 1; } + +void cleanup_tests(void) +{ + BIO_meth_free(b64_write_test_method); + b64_write_test_method = NULL; +} diff --git a/test/bio_core_test.c b/test/bio_core_test.c index 26ff787eec2be..9dc2300bc8c6d 100644 --- a/test/bio_core_test.c +++ b/test/bio_core_test.c @@ -1,3 +1,4 @@ + /* * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * @@ -7,6 +8,8 @@ * https://www.openssl.org/source/license.html */ +#include +#include #include #include #include "testutil.h" @@ -64,6 +67,22 @@ static const OSSL_DISPATCH biocbs[] = { OSSL_DISPATCH_END }; +#ifndef OPENSSL_NO_DEPRECATED_4_1 +static int call_bio_vsnprintf(char *buf, size_t n, const char *format, ...) +{ + va_list args; + int ret; + + va_start(args, format); + OSSL_BEGIN_ALLOW_DEPRECATED + ret = BIO_vsnprintf(buf, n, format, args); + OSSL_END_ALLOW_DEPRECATED + va_end(args); + + return ret; +} +#endif + static int test_bio_core(void) { BIO *cbio = NULL, *cbiobad = NULL; @@ -140,6 +159,77 @@ static int test_bio_vprintf_boundary(void) return testresult; } +static int test_bio_printf_c99_length_modifiers(void) +{ + static const char expected[] = "zu=12345 zd=-42 zx=3039 td=-7 ju=4294967338 jx=10000002a"; + static const char long_tail[] = "12345"; + BIO *bio = NULL; + char *memdata = NULL; + long memlen; + size_t z = (size_t)12345; + ossl_ssize_t zs = (ossl_ssize_t)-42; + ptrdiff_t t = (ptrdiff_t)-7; + ossl_uintmax_t j = (((ossl_uintmax_t)1) << 32) + 42; + int expected_len = (int)strlen(expected); + size_t long_tail_len = strlen(long_tail); + int testresult = 0; +#ifndef OPENSSL_NO_DEPRECATED_4_1 + char buf[128]; + + OSSL_BEGIN_ALLOW_DEPRECATED + if (!TEST_int_eq(BIO_snprintf(buf, sizeof(buf), + "zu=%zu zd=%zd zx=%zx td=%td ju=%ju jx=%jx", + z, zs, z, t, j, j), + expected_len) + || !TEST_str_eq(buf, expected)) + goto err; + + if (!TEST_int_eq(call_bio_vsnprintf(buf, sizeof(buf), + "zu=%zu zd=%zd zx=%zx td=%td ju=%ju jx=%jx", + z, zs, z, t, j, j), + expected_len) + || !TEST_str_eq(buf, expected)) + goto err; + OSSL_END_ALLOW_DEPRECATED +#endif + if (!TEST_ptr(bio = BIO_new(BIO_s_mem())) + || !TEST_int_eq(BIO_printf(bio, + "zu=%zu zd=%zd zx=%zx td=%td ju=%ju jx=%jx", + z, zs, z, t, j, j), + expected_len)) + goto err; + + memlen = BIO_get_mem_data(bio, &memdata); + if (!TEST_long_eq(memlen, (long)strlen(expected)) + || !TEST_mem_eq(memdata, (size_t)memlen, expected, strlen(expected))) + goto err; + + BIO_free(bio); + bio = NULL; + memdata = NULL; + if (!TEST_ptr(bio = BIO_new(BIO_s_mem())) + || !TEST_int_eq(BIO_printf(bio, "%600zu", z), 600)) + goto err; + + memlen = BIO_get_mem_data(bio, &memdata); + if (!TEST_long_eq(memlen, 600) + || !TEST_mem_eq(memdata + (size_t)memlen - long_tail_len, + long_tail_len, long_tail, long_tail_len)) + goto err; + +#ifndef OPENSSL_NO_DEPRECATED_4_1 + OSSL_BEGIN_ALLOW_DEPRECATED + if (!TEST_int_eq(BIO_snprintf(buf, 4, "%zu", z), -1)) + goto err; + OSSL_END_ALLOW_DEPRECATED +#endif + + testresult = 1; +err: + BIO_free(bio); + return testresult; +} + int setup_tests(void) { if (!test_skip_common_options()) { @@ -149,5 +239,6 @@ int setup_tests(void) ADD_TEST(test_bio_core); ADD_TEST(test_bio_vprintf_boundary); + ADD_TEST(test_bio_printf_c99_length_modifiers); return 1; } diff --git a/test/bio_dgram_test.c b/test/bio_dgram_test.c index fab840537ca1a..fdbc3d340fa1b 100644 --- a/test/bio_dgram_test.c +++ b/test/bio_dgram_test.c @@ -9,6 +9,7 @@ #include #include +#include #include #include "testutil.h" #include "internal/sockets.h" @@ -777,6 +778,216 @@ static int test_bio_dgram_pair(int idx) } #endif /* !defined(OPENSSL_NO_CHACHA) */ +/* Checks that a half without a usable peer fails cleanly. */ +static int check_detached(BIO *bio, int reason) +{ + char buf[16]; + BIO_MSG msg; + size_t num_processed = 1; + + memset(&msg, 0, sizeof(msg)); + msg.data = buf; + msg.data_len = sizeof(buf); + + if (!TEST_int_eq(BIO_eof(bio), 1) + || !TEST_int_eq(BIO_pending(bio), 0)) + return 0; + + /* Ctrls reaching for peer data must not touch the freed half. */ + if (!TEST_uint_eq(BIO_dgram_get_effective_caps(bio), 0) + || !TEST_int_eq(BIO_dgram_get_local_addr_cap(bio), 0) + || !TEST_true(BIO_dgram_set_mtu(bio, 1506)) + || !TEST_uint_eq(BIO_dgram_get_mtu(bio), 1506)) + return 0; + + ERR_clear_error(); + if (!TEST_int_lt(BIO_read(bio, buf, sizeof(buf)), 0) + || !TEST_false(BIO_should_retry(bio)) + || !TEST_int_eq(ERR_GET_REASON(ERR_peek_error()), reason)) + return 0; + + ERR_clear_error(); + if (!TEST_int_lt(BIO_write(bio, "x", 1), 0) + || !TEST_false(BIO_should_retry(bio)) + || !TEST_int_eq(ERR_GET_REASON(ERR_peek_error()), reason)) + return 0; + + ERR_clear_error(); + if (!TEST_false(BIO_recvmmsg(bio, &msg, sizeof(msg), 1, 0, &num_processed)) + || !TEST_size_t_eq(num_processed, 0) + || !TEST_int_eq(ERR_GET_REASON(ERR_peek_error()), reason)) + return 0; + + num_processed = 1; + ERR_clear_error(); + if (!TEST_false(BIO_sendmmsg(bio, &msg, sizeof(msg), 1, 0, &num_processed)) + || !TEST_size_t_eq(num_processed, 0) + || !TEST_int_eq(ERR_GET_REASON(ERR_peek_error()), reason)) + return 0; + + ERR_clear_error(); + return 1; +} + +static int test_bio_dgram_pair_free_half(void) +{ + int testresult = 0; + BIO *bio1 = NULL, *bio2 = NULL, *bio3 = NULL; + char buf[16]; + + if (!TEST_true(BIO_new_bio_dgram_pair(&bio1, 0, &bio2, 0)) + || !TEST_int_eq(BIO_write(bio1, "hello", 5), 5) + || !TEST_int_eq(BIO_write(bio2, "world", 5), 5)) + goto err; + + /* Freeing one half must leave the other detached but usable. */ + BIO_free(bio1); + bio1 = NULL; + if (!check_detached(bio2, BIO_R_BROKEN_PIPE)) + goto err; + + /* Which includes pairing it with a new peer. */ + if (!TEST_ptr(bio3 = BIO_new(BIO_s_dgram_pair())) + || !TEST_true(BIO_destroy_bio_pair(bio2)) + || !TEST_true(BIO_make_bio_pair(bio2, bio3)) + || !TEST_int_eq(BIO_eof(bio2), 0) + || !TEST_int_eq(BIO_write(bio2, "again", 5), 5) + || !TEST_int_eq(BIO_read(bio3, buf, sizeof(buf)), 5) + || !TEST_mem_eq(buf, 5, "again", 5)) + goto err; + + /* Destroying the pair on the survivor must cope with a freed peer. */ + BIO_free(bio3); + bio3 = NULL; + if (!TEST_true(BIO_destroy_bio_pair(bio2)) + || !check_detached(bio2, BIO_R_UNINITIALIZED)) + goto err; + + testresult = 1; +err: + BIO_free(bio1); + BIO_free(bio2); + BIO_free(bio3); + return testresult; +} + +static int test_bio_dgram_pair_destroy(int idx) +{ + int testresult = 0; + BIO *bio1 = NULL, *bio2 = NULL; + BIO_ADDR *addr; + char buf[16]; + + if (!TEST_true(BIO_new_bio_dgram_pair(&bio1, 0, &bio2, 0)) + || !TEST_ptr(addr = BIO_ADDR_new()) + || !TEST_true(BIO_dgram_set0_local_addr(bio1, addr))) + goto err; + + if (!TEST_int_eq(BIO_write(bio1, "hello", 5), 5) + || !TEST_int_eq(BIO_read(bio2, buf, sizeof(buf)), 5) + || !TEST_int_eq(BIO_write(bio2, "world", 5), 5) + || !TEST_int_eq(BIO_read(bio1, buf, sizeof(buf)), 5)) + goto err; + + /* Destroying the pair on either half must detach both cleanly. */ + if (!TEST_true(BIO_destroy_bio_pair(idx == 0 ? bio1 : bio2)) + || !check_detached(bio1, idx == 0 ? BIO_R_UNINITIALIZED : BIO_R_BROKEN_PIPE) + || !check_detached(bio2, idx == 0 ? BIO_R_BROKEN_PIPE : BIO_R_UNINITIALIZED) + || !TEST_true(BIO_destroy_bio_pair(bio1)) + || !TEST_true(BIO_destroy_bio_pair(bio2))) + goto err; + + /* Both halves are free to be paired again. */ + if (!TEST_true(BIO_make_bio_pair(bio1, bio2)) + || !TEST_int_eq(BIO_write(bio1, "again", 5), 5) + || !TEST_int_eq(BIO_read(bio2, buf, sizeof(buf)), 5) + || !TEST_mem_eq(buf, 5, "again", 5)) + goto err; + + testresult = 1; +err: + BIO_free(bio1); + BIO_free(bio2); + return testresult; +} + +#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) +#include "threadstest.h" + +static BIO *reader_bio; +static int reader_reason, reader_eof, reader_write; + +/* Keeps receiving on its half until the peer is freed underneath it. */ +static void free_race_reader(void) +{ + char buf[16]; + BIO_MSG msg; + size_t num_processed; + int r; + + memset(&msg, 0, sizeof(msg)); + msg.data = buf; + msg.data_len = sizeof(buf); + + for (;;) { + if (BIO_recvmmsg(reader_bio, &msg, sizeof(msg), 1, 0, &num_processed)) + continue; + /* Writes look at the peer too, so keep them in the mix. */ + ERR_clear_error(); + r = BIO_write(reader_bio, "x", 1); + if (r < 0 && !BIO_should_retry(reader_bio)) + break; + ERR_clear_error(); + r = BIO_read(reader_bio, buf, sizeof(buf)); + if (r < 0 && !BIO_should_retry(reader_bio)) + break; + } + + reader_reason = ERR_GET_REASON(ERR_peek_error()); + reader_eof = BIO_eof(reader_bio); + reader_write = BIO_write(reader_bio, "x", 1); + ERR_clear_error(); +} + +static int test_bio_dgram_pair_free_race(void) +{ + int testresult = 0, written = 0, r; + BIO *bio1 = NULL, *bio2 = NULL; + thread_t thread; + + if (!TEST_true(BIO_new_bio_dgram_pair(&bio1, 0, &bio2, 0))) + goto err; + + reader_bio = bio2; + if (!TEST_true(run_thread(&thread, free_race_reader))) + goto err; + + /* Keep the reader busy, then pull its peer out from under it. */ + while (written < 1000) { + r = BIO_write(bio1, "ping", 4); + if (r == 4) + written++; + else if (!BIO_should_retry(bio1)) + break; + } + BIO_free(bio1); + bio1 = NULL; + + if (!TEST_true(wait_for_thread(thread)) + || !TEST_int_eq(written, 1000) + || !TEST_int_eq(reader_reason, BIO_R_BROKEN_PIPE) + || !TEST_int_eq(reader_eof, 1) + || !TEST_int_lt(reader_write, 0)) + goto err; + + testresult = 1; +err: + BIO_free(bio1); + BIO_free(bio2); + return testresult; +} +#endif + static int test_bio_dgram_mfail(void) { BIO *bio; @@ -805,6 +1016,11 @@ int setup_tests(void) ADD_ALL_TESTS(test_bio_dgram, OSSL_NELEM(bio_dgram_cases)); #if !defined(OPENSSL_NO_CHACHA) ADD_ALL_TESTS(test_bio_dgram_pair, 3); +#endif + ADD_TEST(test_bio_dgram_pair_free_half); + ADD_ALL_TESTS(test_bio_dgram_pair_destroy, 2); +#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) + ADD_TEST(test_bio_dgram_pair_free_race); #endif ADD_MFAIL_TEST(test_bio_dgram_mfail); #endif diff --git a/test/bio_enc_test.c b/test/bio_enc_test.c index bfc43af761b50..d795a0dee9b39 100644 --- a/test/bio_enc_test.c +++ b/test/bio_enc_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -327,6 +327,28 @@ static int test_bio_enc_eof_read_flush(void) return ret; } +static int test_bio_enc_dup(void) +{ + BIO *b = NULL, *dup = NULL; + EVP_CIPHER_CTX *ctx = NULL; + int ret = 0; + + if (!TEST_ptr(b = BIO_new(BIO_f_cipher())) + || !TEST_int_gt(BIO_get_cipher_ctx(b, &ctx), 0) + || !TEST_true(EVP_CipherInit_ex(ctx, EVP_aes_256_cbc(), NULL, + KEY, IV, ENCRYPT))) + goto err; + + if (!TEST_ptr(dup = BIO_dup_chain(b))) + goto err; + + ret = 1; +err: + BIO_free_all(dup); + BIO_free_all(b); + return ret; +} + int setup_tests(void) { ADD_ALL_TESTS(test_bio_enc_aes_128_cbc, 2); @@ -340,5 +362,6 @@ int setup_tests(void) #endif #endif ADD_TEST(test_bio_enc_eof_read_flush); + ADD_TEST(test_bio_enc_dup); return 1; } diff --git a/test/bio_ndef_test.c b/test/bio_ndef_test.c new file mode 100644 index 0000000000000..b6f3be4cdb769 --- /dev/null +++ b/test/bio_ndef_test.c @@ -0,0 +1,237 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Tests of BIO_new_NDEF() against a minimal streamable ASN.1 structure, + * independent of CMS and PKCS7. The structure's callback implements the + * stream operations described in ASN1_aux_cb(3), and can be made to + * misbehave in ways a third-party callback plausibly would, to pin down + * how BIO_new_NDEF() holds up. See also BIO_new_NDEF(3). + */ + +#include + +#include +#include +#include + +#include "testutil.h" + +typedef struct { + ASN1_OCTET_STRING *content; +} NDEF_TEST_VAL; + +DECLARE_ASN1_FUNCTIONS(NDEF_TEST_VAL) + +/* How ndef_test_cb() behaves; a well written callback uses CB_NORMAL */ +enum { + CB_NORMAL, + CB_FAIL_STREAM_PRE, /* fail ASN1_OP_STREAM_PRE */ + CB_NO_CONTENT, /* leave ASN1_OP_GET0_STREAM_CONTENT unhandled */ + CB_CONTENT_THEN_FAIL /* store the content string, then report failure */ +}; +static int cb_mode = CB_NORMAL; + +static int ndef_test_cb(int operation, ASN1_VALUE **pval, + const ASN1_ITEM *it, void *exarg) +{ + NDEF_TEST_VAL *v = (NDEF_TEST_VAL *)*pval; + ASN1_STREAM_ARG *sarg = exarg; + + switch (operation) { + case ASN1_OP_STREAM_PRE: + if (cb_mode == CB_FAIL_STREAM_PRE || v->content == NULL) + return 0; + /* Nothing to digest or encrypt: stream straight through */ + sarg->ndef_bio = sarg->out; + break; + + case ASN1_OP_GET0_STREAM_CONTENT: + if (cb_mode == CB_NO_CONTENT) + break; + *(ASN1_STRING **)exarg = v->content; + if (cb_mode == CB_CONTENT_THEN_FAIL) + return 0; + break; + } + return 1; +} + +ASN1_NDEF_SEQUENCE_cb(NDEF_TEST_VAL, ndef_test_cb) = { + ASN1_SIMPLE(NDEF_TEST_VAL, content, ASN1_OCTET_STRING_NDEF) +} ASN1_NDEF_SEQUENCE_END_cb(NDEF_TEST_VAL, NDEF_TEST_VAL) + +IMPLEMENT_ASN1_FUNCTIONS(NDEF_TEST_VAL) + +static const unsigned char payload[] = "0123456789abcdefghijklmnopqrstuvwxyz"; +#define PAYLOAD_LEN ((int)sizeof(payload) - 1) +#define PAYLOAD_SPLIT 10 + +/* Free the filter BIOs down to, but not including, out */ +static void free_filter_bios(BIO *bio, BIO *out) +{ + while (bio != NULL && bio != out) { + BIO *next = BIO_pop(bio); + + BIO_free(bio); + bio = next; + } +} + +/* Stream a payload in two writes and check that it round-trips */ +static int test_ndef_stream_ok(void) +{ + NDEF_TEST_VAL *v = NULL, *parsed = NULL; + BIO *out = NULL, *bio = NULL; + unsigned char *encoded = NULL; + const unsigned char *der; + long encoded_len; + int ret = 0; + + cb_mode = CB_NORMAL; + + if (!TEST_ptr(v = NDEF_TEST_VAL_new()) + || !TEST_ptr(out = BIO_new(BIO_s_mem())) + || !TEST_ptr(bio = BIO_new_NDEF(out, (ASN1_VALUE *)v, + ASN1_ITEM_rptr(NDEF_TEST_VAL)))) + goto err; + + if (!TEST_int_eq(BIO_write(bio, payload, PAYLOAD_SPLIT), PAYLOAD_SPLIT) + || !TEST_int_eq(BIO_write(bio, payload + PAYLOAD_SPLIT, + PAYLOAD_LEN - PAYLOAD_SPLIT), + PAYLOAD_LEN - PAYLOAD_SPLIT) + || !TEST_int_gt(BIO_flush(bio), 0)) + goto err; + + free_filter_bios(bio, out); + bio = NULL; + + encoded_len = BIO_get_mem_data(out, &encoded); + if (!TEST_long_gt(encoded_len, 0)) + goto err; + + der = encoded; + if (!TEST_ptr(parsed = d2i_NDEF_TEST_VAL(NULL, &der, encoded_len)) + || !TEST_mem_eq(ASN1_STRING_get0_data(parsed->content), + ASN1_STRING_get_length(parsed->content), + payload, PAYLOAD_LEN)) + goto err; + + ret = 1; +err: + free_filter_bios(bio, out); + BIO_free(out); + NDEF_TEST_VAL_free(parsed); + NDEF_TEST_VAL_free(v); + return ret; +} + +/* An item with no callback cannot stream; out must stay usable */ +static int test_ndef_not_supported(void) +{ + ASN1_OCTET_STRING *os = NULL; + BIO *out = NULL; + int ret = 0; + + if (!TEST_ptr(os = ASN1_OCTET_STRING_new()) + || !TEST_ptr(out = BIO_new(BIO_s_mem()))) + goto err; + + ERR_clear_error(); + if (!TEST_ptr_null(BIO_new_NDEF(out, (ASN1_VALUE *)os, + ASN1_ITEM_rptr(ASN1_OCTET_STRING))) + || !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), + ASN1_R_STREAMING_NOT_SUPPORTED)) + goto err; + + /* On failure out remains owned by the caller and usable */ + if (!TEST_int_eq(BIO_write(out, "x", 1), 1)) + goto err; + + ret = 1; +err: + BIO_free(out); + ASN1_OCTET_STRING_free(os); + return ret; +} + +/* A failed ASN1_OP_STREAM_PRE must unwind the half-built chain */ +static int test_ndef_stream_pre_fails(void) +{ + NDEF_TEST_VAL *v = NULL; + BIO *out = NULL; + int ret = 0; + + cb_mode = CB_FAIL_STREAM_PRE; + + if (!TEST_ptr(v = NDEF_TEST_VAL_new()) + || !TEST_ptr(out = BIO_new(BIO_s_mem()))) + goto err; + + if (!TEST_ptr_null(BIO_new_NDEF(out, (ASN1_VALUE *)v, + ASN1_ITEM_rptr(NDEF_TEST_VAL)))) + goto err; + + /* On failure out remains owned by the caller and usable */ + if (!TEST_int_eq(BIO_write(out, "x", 1), 1)) + goto err; + + ret = 1; +err: + cb_mode = CB_NORMAL; + BIO_free(out); + NDEF_TEST_VAL_free(v); + return ret; +} + +/* + * A callback that does not provide the content string, either by leaving + * ASN1_OP_GET0_STREAM_CONTENT unhandled (idx 0, the shape of a callback written + * before that operation existed) or by storing the string and then + * reporting failure (idx 1). Setting up the BIO chain still succeeds, + * because the stream callbacks have already modified it, but the first + * write must fail cleanly instead of encoding through a content string + * that the encoder is not recording the content position in. + */ +static int test_ndef_content_missing(int idx) +{ + NDEF_TEST_VAL *v = NULL; + BIO *out = NULL, *bio = NULL; + int ret = 0; + + cb_mode = idx == 0 ? CB_NO_CONTENT : CB_CONTENT_THEN_FAIL; + + /* Content with data present makes a stale-position mistake detectable */ + if (!TEST_ptr(v = NDEF_TEST_VAL_new()) + || !TEST_true(ASN1_OCTET_STRING_set(v->content, payload, PAYLOAD_LEN)) + || !TEST_ptr(out = BIO_new(BIO_s_mem())) + || !TEST_ptr(bio = BIO_new_NDEF(out, (ASN1_VALUE *)v, + ASN1_ITEM_rptr(NDEF_TEST_VAL)))) + goto err; + + if (!TEST_int_le(BIO_write(bio, payload, PAYLOAD_LEN), 0)) + goto err; + + ret = 1; +err: + cb_mode = CB_NORMAL; + free_filter_bios(bio, out); + BIO_free(out); + NDEF_TEST_VAL_free(v); + return ret; +} + +int setup_tests(void) +{ + ADD_TEST(test_ndef_stream_ok); + ADD_TEST(test_ndef_not_supported); + ADD_TEST(test_ndef_stream_pre_fails); + ADD_ALL_TESTS(test_ndef_content_missing, 2); + return 1; +} diff --git a/test/bio_tfo_test.c b/test/bio_tfo_test.c index 6b7b1414a24fc..7d274a055fac0 100644 --- a/test/bio_tfo_test.c +++ b/test/bio_tfo_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/bntest.c b/test/bntest.c index 5c8f76e1bc407..d15af9dbe5450 100644 --- a/test/bntest.c +++ b/test/bntest.c @@ -1800,15 +1800,16 @@ static int file_modexp(STANZA *s) } /* Regression test for carry propagation bug in sqr8x_reduction */ - BN_hex2bn(&a, "050505050505"); - BN_hex2bn(&b, "02"); - BN_hex2bn(&c, - "4141414141414141414141274141414141414141414141414141414141414141" - "4141414141414141414141414141414141414141414141414141414141414141" - "4141414141414141414141800000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000001"); + if (!TEST_true(BN_hex2bn(&a, "050505050505")) + || !TEST_true(BN_hex2bn(&b, "02")) + || !TEST_true(BN_hex2bn(&c, + "4141414141414141414141274141414141414141414141414141414141414141" + "4141414141414141414141414141414141414141414141414141414141414141" + "4141414141414141414141800000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000001"))) + goto err; if (!TEST_true(BN_mod_exp(d, a, b, c, ctx)) || !TEST_true(BN_mul(e, a, a, ctx)) || !TEST_BN_eq(d, e)) diff --git a/test/build.info b/test/build.info index 5c730f54825a9..ea0234ae50186 100644 --- a/test/build.info +++ b/test/build.info @@ -37,6 +37,9 @@ IF[{- !$disabled{tests} -}] testutil/options.c testutil/test_options.c testutil/provider.c \ testutil/apps_shims.c testutil/random.c testutil/helper.c \ testutil/compare.c mfail/mfail.c $LIBAPPSSRC + IF[{- $target{needs_c99_snprintf_compat} -}] + SOURCE[libtestutil.a]=../crypto/msvc2013_snprintf.c + ENDIF INCLUDE[libtestutil.a]=../include ../apps/include .. mfail DEPEND[libtestutil.a]=../libcrypto @@ -53,18 +56,20 @@ IF[{- !$disabled{tests} -}] v3nametest v3ext byteorder_test punycode_test evp_byname_test \ crltest danetest bad_dtls_test lhash_test sparse_array_test \ conf_include_test params_api_test params_conversion_test \ - constant_time_test crypto_memcmp_test safe_math_test verify_extra_test clienthellotest \ + constant_time_test crypto_memcmp_test ct_validation_helpers_test \ + safe_math_test verify_extra_test clienthellotest \ packettest asynctest secmemtest srptest memleaktest stack_test \ - dtlsv1listentest ct_test threadstest d2i_test \ + asn1_string_poison_test \ + ct_test threadstest d2i_test \ ssl_test_ctx_test ssl_test x509aux cipherlist_test asynciotest \ - bio_callback_test bio_memleak_test bio_core_test bio_dgram_test param_build_test \ + bio_callback_test bio_memleak_test bio_ndef_test bio_core_test bio_dgram_test param_build_test \ sslapitest ssl_handshake_rtt_test dtlstest sslcorrupttest \ bio_base64_test bio_enc_test pkey_meth_kdf_test evp_kdf_test uitest \ cipherbytes_test threadstest_fips threadpool_test \ asn1_encode_test asn1_decode_test asn1_string_table_test asn1_stable_parse_test \ x509_time_test x509_dup_cert_test x509_check_cert_pkey_test \ recordlentest drbgtest rand_status_test sslbuffertest \ - time_offset_test pemtest ssl_cert_table_internal_test ciphername_test \ + time_offset_test pemtest dtls13_internal_test ssl_cert_table_internal_test ciphername_test \ servername_test ocspapitest ocsptest fatalerrtest tls13ccstest \ sysdefaulttest errtest ssl_ctx_test build_wincrypt_test \ context_internal_test aesgcmtest params_test evp_pkey_dparams_test \ @@ -75,7 +80,7 @@ IF[{- !$disabled{tests} -}] fips_version_test x509_test hpke_test pairwise_fail_test \ nodefltctxtest evp_xof_test x509_load_cert_file_test bio_meth_test \ x509_acert_test x509_req_test strtoultest bio_pw_callback_test \ - engine_stubs_test base64_simdutf_test bio_eof_test ech_test + engine_stubs_test base64_simdutf_test bio_eof_test ech_test ossl_rbtree_test IF[{- !$disabled{'ech'} -}] PROGRAMS{noinst}=ech_corrupt_test @@ -86,12 +91,13 @@ IF[{- !$disabled{tests} -}] ENDIF IF[{- !$disabled{'allocfail-tests'} -}] - PROGRAMS{noinst}=handshake-memfail x509-memfail load_key_certs_crls_memfail + PROGRAMS{noinst}=handshake-memfail load_key_certs_crls_memfail ENDIF IF[{- !$disabled{quic} -}] PROGRAMS{noinst}=priority_queue_test quicfaultstest quicapitest \ - quic_newcid_test quic_srt_gen_test rio_notifier_test + quic_newcid_test quic_srt_gen_test rio_notifier_test \ + rio_poll_builder_test ENDIF IF[{- !$disabled{quic} && !$disabled{qlog} -}] @@ -106,10 +112,14 @@ IF[{- !$disabled{tests} -}] PROGRAMS{noinst}=cert_comp_test ENDIF - IF[{- !$disabled{dtls} -}] + IF[{- !$disabled{dtls1} || !$disabled{dtls1_2} -}] PROGRAMS{noinst}=dtls_ccs_reorder_test ENDIF + IF[{- !$disabled{dtls1_2} -}] + PROGRAMS{noinst}=dtlsv1listentest + ENDIF + SOURCE[confdump]=confdump.c INCLUDE[confdump]=../include ../apps/include DEPEND[confdump]=../libcrypto @@ -157,6 +167,18 @@ IF[{- !$disabled{tests} -}] INCLUDE[ecstresstest]=../include ../apps/include DEPEND[ecstresstest]=../libcrypto libtestutil.a + IF[{- !$disabled{ec} -}] + PROGRAMS{noinst}=genec_test + SOURCE[genec_test]=genec_test.c + INCLUDE[genec_test]=../include ../apps/include + DEPEND[genec_test]=../libcrypto libtestutil.a + + PROGRAMS{noinst}=ecparam_test + SOURCE[ecparam_test]=ecparam_test.c + INCLUDE[ecparam_test]=../include ../apps/include + DEPEND[ecparam_test]=../libcrypto libtestutil.a + ENDIF + SOURCE[gmdifftest]=gmdifftest.c INCLUDE[gmdifftest]=../include ../apps/include DEPEND[gmdifftest]=../libcrypto libtestutil.a @@ -288,7 +310,7 @@ IF[{- !$disabled{tests} -}] DEPEND[acvp_test]=../libcrypto libtestutil.a ENDIF - SOURCE[ossl_store_test]=ossl_store_test.c + SOURCE[ossl_store_test]=ossl_store_test.c fake_storeprov.c INCLUDE[ossl_store_test]=../include ../apps/include DEPEND[ossl_store_test]=../libcrypto libtestutil.a @@ -343,6 +365,13 @@ IF[{- !$disabled{tests} -}] DEPEND[ml_dsa_internal_test]=../libcrypto.a libtestutil.a ENDIF + IF[{- !$disabled{'composite'} -}] + PROGRAMS{noinst}=composite_sig_test + SOURCE[composite_sig_test]=composite_sig_test.c + INCLUDE[composite_sig_test]=../include ../apps/include + DEPEND[composite_sig_test]=../libcrypto.a libtestutil.a + ENDIF + PROGRAMS{noinst}=aeswrap_test SOURCE[aeswrap_test]=aeswrap_test.c INCLUDE[aeswrap_test]=../include ../apps/include @@ -376,6 +405,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[crypto_memcmp_test]=../include ../apps/include DEPEND[crypto_memcmp_test]=../libcrypto libtestutil.a + SOURCE[ct_validation_helpers_test]=ct_validation_helpers_test.c + INCLUDE[ct_validation_helpers_test]=../include ../apps/include + DEPEND[ct_validation_helpers_test]=../libcrypto libtestutil.a + SOURCE[safe_math_test]=safe_math_test.c INCLUDE[safe_math_test]=../include ../apps/include DEPEND[safe_math_test]=../libcrypto libtestutil.a @@ -401,6 +434,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[rio_notifier_test]=.. ../include ../apps/include DEPEND[rio_notifier_test]=../libcrypto.a ../libssl.a libtestutil.a + SOURCE[rio_poll_builder_test]=rio_poll_builder_test.c + INCLUDE[rio_poll_builder_test]=.. ../include ../apps/include + DEPEND[rio_poll_builder_test]=../libcrypto.a ../libssl.a libtestutil.a + SOURCE[quic_wire_test]=quic_wire_test.c INCLUDE[quic_wire_test]=../include ../apps/include DEPEND[quic_wire_test]=../libcrypto.a ../libssl.a libtestutil.a @@ -493,6 +530,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[memleaktest]=../include ../apps/include DEPEND[memleaktest]=../libcrypto libtestutil.a + SOURCE[asn1_string_poison_test]=asn1_string_poison_test.c + INCLUDE[asn1_string_poison_test]=../include ../apps/include + DEPEND[asn1_string_poison_test]=../libcrypto libtestutil.a + SOURCE[pkcs12_format_test]=pkcs12_format_test.c helpers/pkcs12.c INCLUDE[pkcs12_format_test]=../include ../apps/include DEPEND[pkcs12_format_test]=../libcrypto libtestutil.a @@ -525,9 +566,27 @@ IF[{- !$disabled{tests} -}] INCLUDE[lhash_test]=../include ../apps/include DEPEND[lhash_test]=../libcrypto.a libtestutil.a - SOURCE[dtlsv1listentest]=dtlsv1listentest.c - INCLUDE[dtlsv1listentest]=../include ../apps/include - DEPEND[dtlsv1listentest]=../libssl libtestutil.a + IF[{- !$disabled{dtls1_2} -}] + SOURCE[dtlsv1listentest]=dtlsv1listentest.c helpers/ssltestlib.c + INCLUDE[dtlsv1listentest]=../include ../apps/include + DEPEND[dtlsv1listentest]=../libcrypto ../libssl libtestutil.a + ENDIF + + IF[{- !$disabled{sock} && !$disabled{dtls} -}] + PROGRAMS{noinst}=dtlsssllistenertest + + SOURCE[dtlsssllistenertest]=dtlsssllistenertest.c helpers/ssltestlib.c + INCLUDE[dtlsssllistenertest]=../include ../apps/include + DEPEND[dtlsssllistenertest]=../libcrypto.a ../libssl.a libtestutil.a + ENDIF + + IF[{- !$disabled{sock} && !$disabled{dtls} && !$disabled{threads}-}] + PROGRAMS{noinst}=dtls_multithread_test + + SOURCE[dtls_multithread_test]=dtls_multithread_test.c helpers/ssltestlib.c + INCLUDE[dtls_multithread_test]=../include ../apps/include + DEPEND[dtls_multithread_test]=../libcrypto.a ../libssl.a libtestutil.a + ENDIF SOURCE[ct_test]=ct_test.c INCLUDE[ct_test]=../include ../apps/include @@ -590,6 +649,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[bio_memleak_test]=../include ../apps/include DEPEND[bio_memleak_test]=../libcrypto libtestutil.a + SOURCE[bio_ndef_test]=bio_ndef_test.c + INCLUDE[bio_ndef_test]=../include ../apps/include + DEPEND[bio_ndef_test]=../libcrypto libtestutil.a + SOURCE[bio_meth_test]=bio_meth_test.c INCLUDE[bio_meth_test]=../include ../apps/include DEPEND[bio_meth_test]=../libcrypto libtestutil.a @@ -648,10 +711,6 @@ IF[{- !$disabled{tests} -}] INCLUDE[handshake-memfail]=../include ../apps/include DEPEND[handshake-memfail]=../libcrypto.a ../libssl.a libtestutil.a - SOURCE[x509-memfail]=x509_memfail.c - INCLUDE[x509-memfail]=../include ../apps/include - DEPEND[x509-memfail]=../libcrypto.a libtestutil.a - SOURCE[load_key_certs_crls_memfail]=load_key_certs_crls_memfail.c ../apps/lib/apps.c \ ../apps/lib/app_rand.c ../apps/lib/app_provider.c ../apps/lib/app_libctx.c \ ../apps/lib/fmt.c ../apps/lib/apps_ui.c ../apps/lib/app_x509.c \ @@ -696,7 +755,7 @@ IF[{- !$disabled{tests} -}] ENDIF SOURCE[dtlstest]=dtlstest.c helpers/ssltestlib.c - INCLUDE[dtlstest]=../include ../apps/include + INCLUDE[dtlstest]=.. ../include ../apps/include DEPEND[dtlstest]=../libcrypto ../libssl libtestutil.a IF[{- !$disabled{dtls} -}] @@ -774,6 +833,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[pemtest]=../include ../apps/include DEPEND[pemtest]=../libcrypto libtestutil.a + SOURCE[dtls13_internal_test]=dtls13_internal_test.c helpers/ssltestlib.c + INCLUDE[dtls13_internal_test]=.. ../include ../apps/include + DEPEND[dtls13_internal_test]=../libssl.a ../libcrypto.a libtestutil.a + SOURCE[ssl_cert_table_internal_test]=ssl_cert_table_internal_test.c INCLUDE[ssl_cert_table_internal_test]=.. ../include ../apps/include DEPEND[ssl_cert_table_internal_test]=../libcrypto libtestutil.a @@ -817,6 +880,11 @@ IF[{- !$disabled{tests} -}] INCLUDE[cipher_overhead_test]=.. ../include ../apps/include DEPEND[cipher_overhead_test]=../libcrypto.a ../libssl.a libtestutil.a + PROGRAMS{noinst}=cipher_dupctx_test + SOURCE[cipher_dupctx_test]=cipher_dupctx_test.c + INCLUDE[cipher_dupctx_test]=../include ../apps/include + DEPEND[cipher_dupctx_test]=../libcrypto libtestutil.a + SOURCE[uitest]=uitest.c ../apps/lib/apps_ui.c INCLUDE[uitest]=.. ../include ../apps/include DEPEND[uitest]=../libcrypto ../libssl libtestutil.a @@ -852,7 +920,7 @@ IF[{- !$disabled{tests} -}] IF[{- !$disabled{cmp} -}] PROGRAMS{noinst}=cmp_asn_test cmp_ctx_test cmp_status_test cmp_hdr_test \ cmp_protect_test cmp_msg_test cmp_vfy_test \ - cmp_server_test cmp_client_test + cmp_server_test cmp_client_test cmp_extracerts_dos_test ENDIF SOURCE[cmp_asn_test]=cmp_asn_test.c helpers/cmp_testlib.c @@ -879,6 +947,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[cmp_msg_test]=.. ../include ../apps/include DEPEND[cmp_msg_test]=../libcrypto.a libtestutil.a + SOURCE[cmp_extracerts_dos_test]=cmp_extracerts_dos_test.c helpers/cmp_testlib.c + INCLUDE[cmp_extracerts_dos_test]=.. ../include ../apps/include + DEPEND[cmp_extracerts_dos_test]=../libcrypto.a libtestutil.a + SOURCE[cmp_vfy_test]=cmp_vfy_test.c helpers/cmp_testlib.c INCLUDE[cmp_vfy_test]=.. ../include ../apps/include DEPEND[cmp_vfy_test]=../libcrypto.a libtestutil.a @@ -894,9 +966,9 @@ IF[{- !$disabled{tests} -}] SOURCE[ca_internals_test]=ca_internals_test.c ../apps/ca.c ../apps/lib/apps.c \ ../apps/lib/app_rand.c ../apps/lib/app_provider.c \ ../apps/lib/app_libctx.c ../apps/lib/fmt.c ../apps/lib/apps_ui.c \ - ../apps/lib/app_x509.c ../crypto/asn1/a_time.c ../crypto/ctype.c + ../apps/lib/app_x509.c INCLUDE[ca_internals_test]=.. ../include ../apps/include - DEPEND[ca_internals_test]=libtestutil.a ../libssl + DEPEND[ca_internals_test]=libtestutil.a ../libssl.a ../libcrypto.a # Internal test programs. These are essentially a collection of internal # test routines. Some of them need to reach internal symbols that aren't @@ -1142,6 +1214,7 @@ IF[{- !$disabled{tests} -}] SOURCE[bn_internal_test]=bn_internal_test.c INCLUDE[bn_internal_test]=.. ../include ../crypto/bn ../apps/include DEPEND[bn_internal_test]=../libcrypto.a libtestutil.a + DEPEND[bn_internal_test.o]=../crypto/bn/bn_prime.h SOURCE[asn1_dsa_internal_test]=asn1_dsa_internal_test.c INCLUDE[asn1_dsa_internal_test]=.. ../include ../apps/include @@ -1179,6 +1252,11 @@ IF[{- !$disabled{tests} -}] INCLUDE[ssl_old_test]=.. ../include ../apps/include DEPEND[ssl_old_test]=../libcrypto.a ../libssl.a libtestutil.a + PROGRAMS{noinst}=tls_groups_list_test + SOURCE[tls_groups_list_test]=tls_groups_list_test.c + INCLUDE[tls_groups_list_test]=.. ../include ../apps/include + DEPEND[tls_groups_list_test]=../libcrypto.a ../libssl.a libtestutil.a + PROGRAMS{noinst}=ext_internal_test SOURCE[ext_internal_test]=ext_internal_test.c INCLUDE[ext_internal_test]=.. ../include ../apps/include @@ -1196,10 +1274,9 @@ IF[{- !$disabled{tests} -}] ENDIF PROGRAMS{noinst}=asn1_time_test - SOURCE[asn1_time_test]=asn1_time_test.c ../crypto/ctype.c \ - ../crypto/asn1/a_time.c + SOURCE[asn1_time_test]=asn1_time_test.c INCLUDE[asn1_time_test]=../include ../apps/include - DEPEND[asn1_time_test]=../libcrypto libtestutil.a + DEPEND[asn1_time_test]=../libcrypto.a libtestutil.a PROGRAMS{noinst}=asn1_string_test SOURCE[asn1_string_test]=asn1_string_test.c @@ -1213,7 +1290,7 @@ IF[{- !$disabled{tests} -}] PROGRAMS{noinst}=tls13secretstest SOURCE[tls13secretstest]=tls13secretstest.c DEFINE[tls13secretstest]=OPENSSL_NO_KTLS - SOURCE[tls13secretstest]= ../ssl/tls13_enc.c ../crypto/packet.c ../crypto/quic_vlint.c + SOURCE[tls13secretstest]= ../ssl/tls13_enc.c ../ssl/d1_transcript.c ../crypto/packet.c ../crypto/quic_vlint.c INCLUDE[tls13secretstest]=.. ../include ../apps/include DEPEND[tls13secretstest]=../libcrypto ../libssl libtestutil.a ENDIF @@ -1294,6 +1371,10 @@ IF[{- !$disabled{tests} -}] ENDIF DEPEND[]=provider_internal_test.cnf GENERATE[provider_internal_test.cnf]=provider_internal_test.cnf.in + DEPEND[]=pathed.cnf + GENERATE[pathed.cnf]=pathed.cnf.in + DEPEND[]=nocache-and-default.cnf + GENERATE[nocache-and-default.cnf]=nocache-and-default.cnf.in PROGRAMS{noinst}=provider_fallback_test SOURCE[provider_fallback_test]=provider_fallback_test.c @@ -1330,6 +1411,11 @@ IF[{- !$disabled{tests} -}] INCLUDE[trace_api_test]=.. ../include ../apps/include DEPEND[trace_api_test]=../libcrypto libtestutil.a + PROGRAMS{noinst}=endecode_api_test + SOURCE[endecode_api_test]=endecode_api_test.c $INITSRC + INCLUDE[endecode_api_test]=../include ../apps/include + DEPEND[endecode_api_test]=../libcrypto libtestutil.a + PROGRAMS{noinst}=endecode_test SOURCE[endecode_test]=endecode_test.c helpers/predefined_dhparams.c INCLUDE[endecode_test]=.. ../include ../apps/include @@ -1429,7 +1515,7 @@ ENDIF SOURCE[strtoultest]=strtoultest.c INCLUDE[strtoultest]=../include ../apps/include - DEPEND[strtoultest]=../libcrypto libtestutil.a + DEPEND[strtoultest]=../libcrypto.a libtestutil.a SOURCE[bio_pw_callback_test]=bio_pw_callback_test.c INCLUDE[bio_pw_callback_test]=../include ../apps/include @@ -1439,6 +1525,10 @@ ENDIF INCLUDE[engine_stubs_test]=../include ../apps/include DEPEND[engine_stubs_test]=../libcrypto libtestutil.a + SOURCE[ossl_rbtree_test]=ossl_rbtree_test.c + INCLUDE[ossl_rbtree_test]=../include ../apps/include + DEPEND[ossl_rbtree_test]=../libcrypto.a libtestutil.a + {- use File::Spec::Functions; use File::Basename; diff --git a/test/ca-and-certs.cnf b/test/ca-and-certs.cnf index 30838831be3f4..56219f148d6cf 100644 --- a/test/ca-and-certs.cnf +++ b/test/ca-and-certs.cnf @@ -99,6 +99,9 @@ organizationalUnitName = optional commonName = supplied emailAddress = optional +[ crl_ext ] +authorityKeyIdentifier = keyid:always + [ v3_ca ] subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:nonss,issuer:nonss diff --git a/test/ca_internals_test.c b/test/ca_internals_test.c index 218ec98f52853..9087179b9f840 100644 --- a/test/ca_internals_test.c +++ b/test/ca_internals_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/certs/ee-cert-dsa-sha384.pem b/test/certs/ee-cert-dsa-sha384.pem new file mode 100644 index 0000000000000..ab3fe146874b5 --- /dev/null +++ b/test/certs/ee-cert-dsa-sha384.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEdjCCBCSgAwIBAgIUNbayaptPn6T0hvP2mKuB8L/W9k8wCwYJYIZIAWUDBAMD +MCgxJjAkBgNVBAMMHU9wZW5TU0wgVGVzdCBEU0EgU0hBLTM4NCBSb290MB4XDTI2 +MDQxMDA3MzMzMFoXDTM2MDQwNzA3MzMzMFowJjEkMCIGA1UEAwwbT3BlblNTTCBU +ZXN0IERTQSBTSEEtMzg0IEVFMIIDQjCCAjUGByqGSM44BAEwggIoAoIBAQDA154m +/UL7G6MMLDAr2BoxQzgT8eNaOV2Ls89BvjF3SS9qgOMQSv9TK8gcb16jpqd6aQ6G +WLedKu3fRUrXCihRaZZaeftJCntAVaDIhtYaYdsua6IDGjWd1SHHmFdQnH3AYLxV +dRmnq3Jjt6oelPQYKDbpWAtT8DsFJ/d6bGpQ6mxW4J1u1FnmKwzuxbR/ZxOV1gQy +D08gfkct7+UtQ5rJUIiIeK2RWsJhF6tdvH+g8VhBXsXo0ZprA/iQHst/aeXSGUBC ++vby1LYog2VFLXD+zl5rzXZUNJLXPt/9Dvs/qYknPlUEboQ8J/afbyuA8S10gsAu +8bnyQ/oTzmA+4Uy5Ah0A0QDXg1zTwGDdtB3OqMZOhhyL+oLzZeFsowwBzwKCAQAs +wjjcjD2G/brbwZuNaZWDHqrpTmmAhvg17+QGp9gaWWb/08TfZ+PbhIL4jV8kf5PZ +kPZVJyocYGduRJsIxiJDlssdaYzgkJ4zJG0A6gYtpBpaD/h6di0E0nzjm+80a9jo +xrgq3jRxkGVHpHvDd4ps0q2UXH44nFCEPWaoebpR4BXCLzXuFw30gUldrClqcMWt +OqQUwf7/ZndhQvLA2PiJEC/5EQFzeMzjl+XAOjW+781rO8BPmniFVXmRGAVWCycL +Qj0pQzvfDDi1M4LZBAw+g6RAa/IAB1mpKNOfsh2wDYS+nJn6q77COZRVn0DZLiVz +M8ENRqH0uRF1osCgqAuBA4IBBQACggEAXj8recOQ2JRABFgypUmG2PA0ibD5z1j3 +Xx7i5UXdwzOMJrtPtzjTmykgg73JpYA38kyqUtaZLKqtR2up+M9Bpj0l8GPZ5brM +E5zJbWukvSw8pnAUvq92izRHlmEK7QUPrkYM2e+NjJKYEOeJ8I1O7mZUBHNsbYGW +jGi0FW+LpcUywCUH7ccxHLFBXJnMUS7zipc6fwBjumFtYTyjsoeE5pyVGs6Cau0o +dzCgR3Ss0gc73qnHv+7t4NP2385AaTKhNeykrtwhrFL6MDGYf0Bs2Y5SE5vEnIZJ +Rb4I+8YnhsxaPGiKy9N6R+1CisnBg+4cx1mEVl3moQtAT6POruJaMqNCMEAwHQYD +VR0OBBYEFNfDDHDjB5VsPYFzEcuRXWZilvyIMB8GA1UdIwQYMBaAFDXj0oV+Bxtx +dRByLwz7g8OjZg/ZMAsGCWCGSAFlAwQDAwM/ADA8AhwezQQknbLR8wtcYnQJLvlv +tILlrOxyRlvUCUGtAhxGW+R77sJNGghc76jH+g3Kkent+0+G3VxrgrOc +-----END CERTIFICATE----- diff --git a/test/certs/ee-cert-dsa-sha512.pem b/test/certs/ee-cert-dsa-sha512.pem new file mode 100644 index 0000000000000..e3741ed0dd4e4 --- /dev/null +++ b/test/certs/ee-cert-dsa-sha512.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEdzCCBCSgAwIBAgIUG0h9XyzEews1+X1q3CMHaNZuXhkwCwYJYIZIAWUDBAME +MCgxJjAkBgNVBAMMHU9wZW5TU0wgVGVzdCBEU0EgU0hBLTUxMiBSb290MB4XDTI2 +MDQxMDA3MzMzMFoXDTM2MDQwNzA3MzMzMFowJjEkMCIGA1UEAwwbT3BlblNTTCBU +ZXN0IERTQSBTSEEtNTEyIEVFMIIDQjCCAjUGByqGSM44BAEwggIoAoIBAQDA154m +/UL7G6MMLDAr2BoxQzgT8eNaOV2Ls89BvjF3SS9qgOMQSv9TK8gcb16jpqd6aQ6G +WLedKu3fRUrXCihRaZZaeftJCntAVaDIhtYaYdsua6IDGjWd1SHHmFdQnH3AYLxV +dRmnq3Jjt6oelPQYKDbpWAtT8DsFJ/d6bGpQ6mxW4J1u1FnmKwzuxbR/ZxOV1gQy +D08gfkct7+UtQ5rJUIiIeK2RWsJhF6tdvH+g8VhBXsXo0ZprA/iQHst/aeXSGUBC ++vby1LYog2VFLXD+zl5rzXZUNJLXPt/9Dvs/qYknPlUEboQ8J/afbyuA8S10gsAu +8bnyQ/oTzmA+4Uy5Ah0A0QDXg1zTwGDdtB3OqMZOhhyL+oLzZeFsowwBzwKCAQAs +wjjcjD2G/brbwZuNaZWDHqrpTmmAhvg17+QGp9gaWWb/08TfZ+PbhIL4jV8kf5PZ +kPZVJyocYGduRJsIxiJDlssdaYzgkJ4zJG0A6gYtpBpaD/h6di0E0nzjm+80a9jo +xrgq3jRxkGVHpHvDd4ps0q2UXH44nFCEPWaoebpR4BXCLzXuFw30gUldrClqcMWt +OqQUwf7/ZndhQvLA2PiJEC/5EQFzeMzjl+XAOjW+781rO8BPmniFVXmRGAVWCycL +Qj0pQzvfDDi1M4LZBAw+g6RAa/IAB1mpKNOfsh2wDYS+nJn6q77COZRVn0DZLiVz +M8ENRqH0uRF1osCgqAuBA4IBBQACggEADpK5z3E7aC/bPkHbIApYwMui0PlPm9mZ +fJcOUYkUxrGwsVB7MLlFKaYogohKW/6llyTQ9KVv0GhXGBU8KZAwYi2IvEqZWt96 +QWMReZkr85mcfWPPr0nhPaiKPFLuzbrJS5+8pRZ0JZICAs7fWK2ieTFzF5T52+uU +HW3d8hRW0faGy3JVChySx2zKhznax0ugOeO6xpw+GIhh7DtoLN9+WCUD4gHxcT1e +ngH3SPr9kSAc179ZheLPV8K96D6h62xLyDOv66jKqxuEuwKMezKhI8NoWlIjFlwq +qeg+/URRSKaemF7CeEtjfxfyhPyWFBA3ied6v8lgcvm8xEK1fOuWtaNCMEAwHQYD +VR0OBBYEFG70aEHyZTHkRfESJAk59LuyXqj2MB8GA1UdIwQYMBaAFLO3mEJ4Js8i +80dWuZffkE17675DMAsGCWCGSAFlAwQDBANAADA9AhxQI/S0oZhUBxth3amipFkw +px3NJNYZEdKm1x4hAh0AotKopAK/hiDc2IGgHC+L2kjsvg/tqofl54aZ6w== +-----END CERTIFICATE----- diff --git a/test/certs/ee-cert1.pem b/test/certs/ee-cert1.pem new file mode 100644 index 0000000000000..f9fb6ae7377a9 --- /dev/null +++ b/test/certs/ee-cert1.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJzCCAg+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290 +IENBMCAXDTI2MDYxOTA3NTU0NVoYDzIxMjYwNjE5MDc1NTQ1WjAaMRgwFgYDVQQD +DA9zZXJ2ZXIuZXhhbXBsZTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCo/4lYYYWu3tssD9Vz++K3qBt6dWAr1H08c3a1rt6TL38kkG3JHPSKOM2fooAW +Vsu0LLuT5Rcf/w3GQ/4xNPgo2HXpo7uIgu+jcuJTYgVFTeAxl++qnRDSWA2eBp4y +uxsIVl1lDz9mjsI2oBH/wFk1/Ukc3RxCMwZ4rgQ4I+XndWfTlK1aqUAfrFkQ9QzB +ZK1KxMY1U7OWaoIbFYvRmavknm+UqtKW5Vf7jJFkijwkFsbSGb6CYBM7YrDtPh2z +yvlr3zG5ep5LR2inKcc/SuIiJ7TvkGPX79ByST5brbkb1Ctvhmjd1XMSuEPJ3EEP +oqNGT4tniIQPYf55NB9KiR+3AgMBAAGjfjB8MB0GA1UdDgQWBBTnm+IqrYpsOst2 +UeWOB5gil+FzojAfBgNVHSMEGDAWgBSO9SWvHptrhD18gJrJU5xNcvejUjAJBgNV +HRMEAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMBoGA1UdEQQTMBGCD3NlcnZlci5l +eGFtcGxlMTANBgkqhkiG9w0BAQsFAAOCAQEALEErPqzg89OMMS51cKZaLOA6Aemi +kriioN8NEOJFKoOOSoz4/YlDiLKDeBeloVPn7MKu6+3L85v7E1yD6PbFJR6uYQ9g +54DmqbTLqDRbpxs1sNhf9ExAWACaIkcUaMlkZzcpXeFxM3XlN9/KHMdJztasgzZ3 +z9rd/1Ts6r07caBvQ6/W1lFczuDJip1ZxSeLlrMjKxLk+Qp1EHmmFQ2pdTfREoPy +QOBWpI7bzOidBGz4uU4h+CoHQMJweHSHgFK1DcmZG8TCpezKmPAULjHB4qSbxrBZ +3i4X0bhXtjCrXBxWkS/upEEvw6a4jP/Y2IfNYy+o54bqbKHGYz4OdtGoDQ== +-----END CERTIFICATE----- diff --git a/test/certs/mixed-ca-cert.pem b/test/certs/mixed-ca-cert.pem new file mode 100644 index 0000000000000..b13221a9bcd1a --- /dev/null +++ b/test/certs/mixed-ca-cert.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICNTCCAR2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290 +IENBMCAXDTI2MDgyNjA2NDU1MFoYDzIxMjYwODI2MDY0NTUwWjARMQ8wDQYDVQQD +DAZFQ0MgQ0EwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQ6kBXIVAhdGlu7oAXO +KXbHZDmzstAX2H+xiLWcPNL95h/m5+66YM1EyqdZOd3Smfn9AEdp0LM+iA4to58F +xvVLo2AwXjAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQU +jgOuoPFFR3/WUu6Dmy9LlSaSqtQwHwYDVR0jBBgwFoAUjvUlrx6ba4Q9fICayVOc +TXL3o1IwDQYJKoZIhvcNAQELBQADggEBANE/H0nkpWNrb6JzWAFauPfgrkS5nL9T +fAUe5itZI04SlS/lA61/GzebhCm4M78wZ89Oxzcy4hTstIirxbZbiVDQ8tNgJZxN +WXfCbBFZr0Kx7qISllFIltEUlIO08cQDnu5uDCdxU54hVjIlWj69a75H8w00ubLh +zbQZi7Tk1vDDtgeIqaF6klAmIccU49QdFV/PyzrrFSeuhd1yqvS8ATW7wpT7dfVm +AyTe8OcwemVb7HV5/H/fQOWVqRIu8c8dpNtNSzBCpVp7OXsm6puo1RxvgCj+vgr9 +Wcn0G3ITMpSWmORaR6AirdzYjJO5Gxk8IwusGrJhm6yrN8Zgx+KWbAs= +-----END CERTIFICATE----- diff --git a/test/certs/mixed-ca-key.pem b/test/certs/mixed-ca-key.pem new file mode 100644 index 0000000000000..89c53b9166b07 --- /dev/null +++ b/test/certs/mixed-ca-key.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgDD4017Lvk96sqd9f +A3Ae2ZnpVkQOLU1WYZF+68wLOTOhRANCAAQ6kBXIVAhdGlu7oAXOKXbHZDmzstAX +2H+xiLWcPNL95h/m5+66YM1EyqdZOd3Smfn9AEdp0LM+iA4to58FxvVL +-----END PRIVATE KEY----- diff --git a/test/certs/mixed-ee-cert.pem b/test/certs/mixed-ee-cert.pem new file mode 100644 index 0000000000000..19014ae13b351 --- /dev/null +++ b/test/certs/mixed-ee-cert.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICcjCCAhegAwIBAgIBAjAKBggqhkjOPQQDAjARMQ8wDQYDVQQDDAZFQ0MgQ0Ew +IBcNMjYwODI2MDY1NjA1WhgPMjEyNjA4MjYwNjU2MDVaMB8xHTAbBgNVBAMMFHNl +cnZlciBtaXhlZCBFQ0MvUlNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA4FIzcg3wxMVqFFCFXG7ZTNi4vz31ghEXdDy6wiiRZW6FjWwrzRMqY73imzxG +9AWUppIrRx76toJGdJVCC0A4JVKLiQwX7yhtoMbfUns0X1aShp+O81tgV310Ut0m +WA/yfXdeUjMdDD6hTynPUz0It/5yH+Shwbz8GWNeC+7VeB4JVGj1rvnU9+ljekCT +q11QZNJaJCPAkqjXzLJMPZMuV6nsyzNBQOJxvmwtVcfGvYc4ytszPwQQKeg3iFpm +s+jpwOk93jwWRsEr5Uku8WFarxH40rpTDy0HlmDUwiD/N1SBk4xUKur2iDBCMvzC +Bb4GDCFpxvQSFPKo5UnuuzvRkQIDAQABo4GEMIGBMB0GA1UdDgQWBBTgABQ2S34t +6BygRV9+yezITphvnjAfBgNVHSMEGDAWgBSOA66g8UVHf9ZS7oObL0uVJpKq1DAJ +BgNVHRMEAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMB8GA1UdEQQYMBaCFHNlcnZl +ciBtaXhlZCBFQ0MvUlNBMAoGCCqGSM49BAMCA0kAMEYCIQCPBR01cg5ayHE5Po9T +vpxjC5TJpyQ6Auti9bzRSUHIjgIhAOjFQ0c7chZzUXNQdY6oeFWiC2QUZ+lKb+SW +GZDUG4sV +-----END CERTIFICATE----- diff --git a/test/certs/mixed-ee-key.pem b/test/certs/mixed-ee-key.pem new file mode 100644 index 0000000000000..e1c327bebda52 --- /dev/null +++ b/test/certs/mixed-ee-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDgUjNyDfDExWoU +UIVcbtlM2Li/PfWCERd0PLrCKJFlboWNbCvNEypjveKbPEb0BZSmkitHHvq2gkZ0 +lUILQDglUouJDBfvKG2gxt9SezRfVpKGn47zW2BXfXRS3SZYD/J9d15SMx0MPqFP +Kc9TPQi3/nIf5KHBvPwZY14L7tV4HglUaPWu+dT36WN6QJOrXVBk0lokI8CSqNfM +skw9ky5XqezLM0FA4nG+bC1Vx8a9hzjK2zM/BBAp6DeIWmaz6OnA6T3ePBZGwSvl +SS7xYVqvEfjSulMPLQeWYNTCIP83VIGTjFQq6vaIMEIy/MIFvgYMIWnG9BIU8qjl +Se67O9GRAgMBAAECggEAB5l5UTScMspeWuRUdEp0Faik76OteNPT59Xz3MaLkHRj +VWR0Am1TCxCAiBJNdBBpVhBPI4hu5XZ55RK2a1OoY0lN3V15xRopRqBeKfjvEAjK +i4GF0gRHOgePxIvl8+dMZ4g++4lsQ0Eu7VPlCHShojweSSrReRMKNmD5q21SsZBA +q83roNYFGOpgT90yEF73xMKWmnOOf5ZnhW6tdMTxdcJt7u1ty4F4i2PS8nJKOQwS +3p65QVRB2BaSr3QLDBsdl/qqe48aer8FzR2Ew5TO1UnYLQN2wT7TYkb4vB9JO3pu +fcRVHfsMRolaLpWEmYs0xls88NfUJqJDQxHME7l0PQKBgQD+pjMVa7Hyfma3Nvjv +dsH9qV3IXbIHb3IfIta8SsdwvH3w7obIUZxuruzrSO/D7RDBdA2RoKXhnz0yOsoa +KC53hEgJz8XssjNwEPRlrT2gesd8DB83RNJPGglUJsDwGHU2wn9awAiPTdaS39YP +zaSf/bhQpu4SKyaYXl484BnH9QKBgQDhgtFA8W2J30vvivfcSts+AlqdAzgMisuX +ytcMrs7TzqrD7ZTWrtizFela3dwOTkCSaaxaJ2c97GzXWhrzMrmWWCgyrP4KslSJ +zRaCDjLXgj5igNT1mesJEfaW4NesVWuPoROPVQP7/K18BcoAL2qQR0+NoPVAsEzP +xnlpyh9NrQKBgBo6R/ym0Pcm6bFpKg6P7r8PmKcwb0uwwNJQJknSceQ8pcQQ7TTo +ovILdj9tjbRiUF18dIFRSISKgCUSRQqYpOCOcVUBX2NXn1CljmaCh1xmCPHP1c89 +eWPITLmsHCcefcQcGD3ilX8dB0KtZ0DNb21DFp7H8rFQXHNJFO+0LTOZAoGAUR/W +Vx6C4U5K6ul7MOxc4nnGTyWRTDHB++Eka5OXI+r8027sVC6iFgqT3/Rf7WWJJSKO +tf/mzAf5P59SgpqE2OjtzQ0edoqgjtIQfsjM0WoxNw5RjejI/IJRywUnkP9Jqmmv +t6hFvqivYCZU/KwSEcUVgUWd9J93gmdL1hq4GCECgYEA+2fMsJCchaxH7h/5mngN +oQp0mqV6+CULGXpwrjhRCZu3zf/UJaZPLHY5PF2KQwzqxW8+7Bnbq7K8gnfu2+y2 +opKnCV28P3c2S01/jJpc+KGuEn5r4xzsIrr8O50u45RUBZY9dGIvO/ddE18CjIxj +1bQ+CzDjDUL4LXJTBkDtXd4= +-----END PRIVATE KEY----- diff --git a/test/certs/mkcert.sh b/test/certs/mkcert.sh index 087dc343d77ed..b94e1472c4221 100755 --- a/test/certs/mkcert.sh +++ b/test/certs/mkcert.sh @@ -1,6 +1,6 @@ #! /bin/bash # -# Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2016 Viktor Dukhovni . # All rights reserved. # @@ -14,7 +14,7 @@ # 100 years should be enough for now if [ -z "$DAYS" ]; then - DAYS=36525 + DAYS=36524 # there are 24 leap years per 100 years fi if [ -z "$OPENSSL_SIGALG" ]; then @@ -56,6 +56,11 @@ key() { dsa) args=(-paramfile "$bits");; ed25519) ;; ed448) ;; + ML-KEM*) ;; + MLKEM*) ;; + ML-DSA*) ;; + MLDSA*) ;; + SLH-DSA*) ;; *) printf "Unsupported key algorithm: %s\n" "$alg" >&2; return 1;; esac stderr_onerror \ diff --git a/test/certs/rollover-ca.pem b/test/certs/rollover-ca.pem new file mode 100644 index 0000000000000..01c357a3e4762 --- /dev/null +++ b/test/certs/rollover-ca.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFDCCAfygAwIBAgICA+kwDQYJKoZIhvcNAQELBQAwGzEZMBcGA1UEAwwQVGVz +dCBSb2xsb3ZlciBDQTAgFw0yMDAxMDEwMDAwMDBaGA8yMTI2MDkxMjAxMDAzN1ow +GzEZMBcGA1UEAwwQVGVzdCBSb2xsb3ZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAJadpD0ASxxfxsvdj9IxsogVzMSGLFziaYuE9KejU9+R479R +ifvwfBANO62sNWJ19X//9G5UjwWmkiOzn1k50DkYsBBA3mJzik6wjt/c58lBIlSE +gAgpvDU8ht8w3t20JP9+YqXAeugqFj/Wl9rFQtsvaWSRywjXVlp5fxuEQelNnXcJ +EKhsKTNExsBUZebo4/J1BWpklWzA9P0lYW5INvDAAwcF1nzlEf0Y6Eot03IMNyg2 +MTE4hehxjdgCSci8GYnFirE/ojXqqpAcZGh7r2dqWgZUD1Dh+bT2vjrUzj8eTH3G +dzI+oljt29102JIUaqj3yzRYkah8FLF9CLNNsUcCAwEAAaNgMF4wDwYDVR0TAQH/ +BAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFLQRM/HX4l73U54gIhBPhga/ +H8leMB8GA1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMA0GCSqGSIb3DQEB +CwUAA4IBAQAh0VU8trrRoT8l3EC+EqcVsrtjxCdL/+0f3sfue0tc/WICCEFH2AFi +HxSlMd4xdJ0TMBLwLbRI8Jpnt1ORFw4Vf7hkWEdewFTXfqM79zMGQZd3YEko1ron +CWNWcQ7314xl+C+ND/HCQXMFuCINOHh7Tufwc4NTphiuFli2tQCoeTfjQTRDKWjL +OyqFx7OTG7Doh/8yHv5ZuSQnV2OUlJP4AJ0jJRZZvRC7EqV2CEyHXc+zASxOheeM +GejDtJ0fDNTU1lN7wWbrICy4/vLt54ihNvMFGO5vLre8lss8T8zrIgVCM0wJDrkI +mULWdN8itYwLYYRXZsxVNHn90yToOFOK +-----END CERTIFICATE----- diff --git a/test/certs/rollover-ee.pem b/test/certs/rollover-ee.pem new file mode 100644 index 0000000000000..a09af78d40060 --- /dev/null +++ b/test/certs/rollover-ee.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+owDQYJKoZIhvcNAQELBQAwGzEZMBcGA1UEAwwQVGVz +dCBSb2xsb3ZlciBDQTAgFw0yMDAxMDEwMDAwMDBaGA8yMTI2MDkxMjAxMDAzN1ow +GzEZMBcGA1UEAwwQVGVzdCBSb2xsb3ZlciBFRTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAKj/iVhhha7e2ywP1XP74reoG3p1YCvUfTxzdrWu3pMvfySQ +bckc9Io4zZ+igBZWy7Qsu5PlFx//DcZD/jE0+CjYdemju4iC76Ny4lNiBUVN4DGX +76qdENJYDZ4GnjK7GwhWXWUPP2aOwjagEf/AWTX9SRzdHEIzBniuBDgj5ed1Z9OU +rVqpQB+sWRD1DMFkrUrExjVTs5ZqghsVi9GZq+Seb5Sq0pblV/uMkWSKPCQWxtIZ +voJgEztisO0+HbPK+WvfMbl6nktHaKcpxz9K4iIntO+QY9fv0HJJPlutuRvUK2+G +aN3VcxK4Q8ncQQ+io0ZPi2eIhA9h/nk0H0qJH7cCAwEAAaN8MHowDAYDVR0TAQH/ +BAIwADALBgNVHQ8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC +MB0GA1UdDgQWBBTnm+IqrYpsOst2UeWOB5gil+FzojAfBgNVHSMEGDAWgBS0ETPx +1+Je91OeICIQT4YGvx/JXjANBgkqhkiG9w0BAQsFAAOCAQEAPijP7kjgPCA0BxhU +mqOOxRS36O4r0Yb+h2t1acvz0NnzlrkjrbVjK2fZcEDHT+brtA177T73iFKRMwrD +MIJzYDCBPeLhVDrydtOEzB9AFDrBGPXVzfTDMNI/uY9216RGe7mb1lojUe+OhNCj +LdIb/2nDnyemRGLb7+eBLabv31idrKtiCzzCxNkORBvBa1ocl0dkLCv2jksTWdVH +S6rh6sjFumTygsqHQbA1ErDBtRkBb1VDk79EhcS02V2Md3vW/XLHMJhlCr94/3rb +0vPzYXqT4BAfmyh5huBSOHmo2dxVKJ9Reay5itEiwzh+IUfXvNgaowZ5viEBH+zM +YYF1uA== +-----END CERTIFICATE----- diff --git a/test/certs/rollover-root.pem b/test/certs/rollover-root.pem new file mode 100644 index 0000000000000..bdd70c9679d5e --- /dev/null +++ b/test/certs/rollover-root.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFDCCAfygAwIBAgICA+gwDQYJKoZIhvcNAQELBQAwGzEZMBcGA1UEAwwQVGVz +dCBSb2xsb3ZlciBDQTAgFw0yMDAxMDEwMDAwMDBaGA8yMTI2MDkxMjAxMDAzN1ow +GzEZMBcGA1UEAwwQVGVzdCBSb2xsb3ZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAOHmAPUGvKBGOHkPPx5xGRNtAt8rm3Zr/KywIe3WkQhCO6Vj +NexSW6CiSsXWAJQDl1o9uWco0n3jIVyk7cY8jY6E0Z1Uwz3ZdKKWdmdx+cYaUHez +/XjuW+DjjIkjwpoi7D7UN54HzcArVREXOjRCHGkNOhiw7RWUXsb9nofGHOeUGpLA +XwXBc0PlA94JkckkztiOi34u4DFI0YYqalUmeugLNk6XseCkydpcaUsDgAhWg6Mf +siq4wUz+xbFN1MABqu2+ziW97mmt9gfNbiuhiVT1aOuYCe3JYGbLM2JKA7Bo1g6r +X8E1VX79Ru6669y2oqPthX9337VoIkN+ZiQjr8UCAwEAAaNgMF4wDwYDVR0TAQH/ +BAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFI71Ja8em2uEPXyAmslTnE1y +96NSMB8GA1UdIwQYMBaAFI71Ja8em2uEPXyAmslTnE1y96NSMA0GCSqGSIb3DQEB +CwUAA4IBAQAjkLgEO/nYCmDHMv6R76lNFeERjwk/c/JsCOUpDg+5G+GRQtNR42p7 +BTreJerDEqxEDadEIgyLq9gyw8+iNeII1UZymIYAZmAtVcjP1ecBoW7lCI8PwApu +cf5NweIDEcAkm7X0g3p9iToy/4z/0KYqV8sRkhcqbJQci/TlO887pSAebTEAogH4 +e2GuYGDOEnmuEP4+L+FSk0rSOmOPrrkYXcUe8bbRM0ypxdxkJitUS5sOR+Kshu2k +37Q0uKxwwW8HKa5ZNiPaTh9Iq3Si/UYT40LG58ZfORVSV2oeeCd2B2uzddwiSg/9 +/z1HxedkOo/0MqvDP7vjcKL5d/ms+lQL +-----END CERTIFICATE----- diff --git a/test/certs/root-cert-dsa-sha384.pem b/test/certs/root-cert-dsa-sha384.pem new file mode 100644 index 0000000000000..107e855b42639 --- /dev/null +++ b/test/certs/root-cert-dsa-sha384.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEizCCBDigAwIBAgIUL44kPKEDy7eaEgXNH4xXTuVw77owCwYJYIZIAWUDBAMD +MCgxJjAkBgNVBAMMHU9wZW5TU0wgVGVzdCBEU0EgU0hBLTM4NCBSb290MB4XDTI2 +MDQxMDA3MzMzMFoXDTM2MDQwNzA3MzMzMFowKDEmMCQGA1UEAwwdT3BlblNTTCBU +ZXN0IERTQSBTSEEtMzg0IFJvb3QwggNDMIICNQYHKoZIzjgEATCCAigCggEBAMDX +nib9QvsbowwsMCvYGjFDOBPx41o5XYuzz0G+MXdJL2qA4xBK/1MryBxvXqOmp3pp +DoZYt50q7d9FStcKKFFpllp5+0kKe0BVoMiG1hph2y5rogMaNZ3VIceYV1CcfcBg +vFV1GaercmO3qh6U9BgoNulYC1PwOwUn93psalDqbFbgnW7UWeYrDO7FtH9nE5XW +BDIPTyB+Ry3v5S1DmslQiIh4rZFawmEXq128f6DxWEFexejRmmsD+JAey39p5dIZ +QEL69vLUtiiDZUUtcP7OXmvNdlQ0ktc+3/0O+z+piSc+VQRuhDwn9p9vK4DxLXSC +wC7xufJD+hPOYD7hTLkCHQDRANeDXNPAYN20Hc6oxk6GHIv6gvNl4WyjDAHPAoIB +ACzCONyMPYb9utvBm41plYMequlOaYCG+DXv5Aan2BpZZv/TxN9n49uEgviNXyR/ +k9mQ9lUnKhxgZ25EmwjGIkOWyx1pjOCQnjMkbQDqBi2kGloP+Hp2LQTSfOOb7zRr +2OjGuCreNHGQZUeke8N3imzSrZRcfjicUIQ9Zqh5ulHgFcIvNe4XDfSBSV2sKWpw +xa06pBTB/v9md2FC8sDY+IkQL/kRAXN4zOOX5cA6Nb7vzWs7wE+aeIVVeZEYBVYL +JwtCPSlDO98MOLUzgtkEDD6DpEBr8gAHWako05+yHbANhL6cmfqrvsI5lFWfQNku +JXMzwQ1GofS5EXWiwKCoC4EDggEGAAKCAQEAqBWUzoivwm10KhCOVj4dLJ376hik +coO7wh8szq+0lBCKVQu0XgZdpR67ibiInCslpi4D31QX1ciP8Ds3Tnr92Xq9fp6F +Q9+M94it5BWvXq8uWnsCYRLIXds+8DKnUMTPc0U5Qc/HnfkdgHockBya5ZKRLzgW +THC5n29NjBoIH9TBFddxanUqOqM2a0+0uC23jC/rmsmIXKKLIRnBjDjCfWGkpvDR +V0TmgU+wBN7Fu6/PDdb2h1omgx5iJ0hR9bSQMevPzxKWIIYt3jBa3JWRJVshZbCX +zGSycHIM4IPPEWtDEMR/s/aO5+HcQdV42itClvOQxhVfYTtBCV8TiMYFAKNTMFEw +HQYDVR0OBBYEFDXj0oV+BxtxdRByLwz7g8OjZg/ZMB8GA1UdIwQYMBaAFDXj0oV+ +BxtxdRByLwz7g8OjZg/ZMA8GA1UdEwEB/wQFMAMBAf8wCwYJYIZIAWUDBAMDA0AA +MD0CHQC/zbfFT+FeeYr9PmYtblMAGmtUgM2VyUcargqPAhwnaYxJwO0tJHKZDXOG +38UfhwBTUj0PNyAwbOG/ +-----END CERTIFICATE----- diff --git a/test/certs/root-cert-dsa-sha512.pem b/test/certs/root-cert-dsa-sha512.pem new file mode 100644 index 0000000000000..5dbe393aeaefa --- /dev/null +++ b/test/certs/root-cert-dsa-sha512.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEiTCCBDagAwIBAgITGBs2j74eZNOfebavEYuJJZKVKTALBglghkgBZQMEAwQw +KDEmMCQGA1UEAwwdT3BlblNTTCBUZXN0IERTQSBTSEEtNTEyIFJvb3QwHhcNMjYw +NDEwMDczMzMwWhcNMzYwNDA3MDczMzMwWjAoMSYwJAYDVQQDDB1PcGVuU1NMIFRl +c3QgRFNBIFNIQS01MTIgUm9vdDCCA0IwggI1BgcqhkjOOAQBMIICKAKCAQEAwNee +Jv1C+xujDCwwK9gaMUM4E/HjWjldi7PPQb4xd0kvaoDjEEr/UyvIHG9eo6anemkO +hli3nSrt30VK1wooUWmWWnn7SQp7QFWgyIbWGmHbLmuiAxo1ndUhx5hXUJx9wGC8 +VXUZp6tyY7eqHpT0GCg26VgLU/A7BSf3emxqUOpsVuCdbtRZ5isM7sW0f2cTldYE +Mg9PIH5HLe/lLUOayVCIiHitkVrCYRerXbx/oPFYQV7F6NGaawP4kB7Lf2nl0hlA +Qvr28tS2KINlRS1w/s5ea812VDSS1z7f/Q77P6mJJz5VBG6EPCf2n28rgPEtdILA +LvG58kP6E85gPuFMuQIdANEA14Nc08Bg3bQdzqjGToYci/qC82XhbKMMAc8CggEA +LMI43Iw9hv2628GbjWmVgx6q6U5pgIb4Ne/kBqfYGllm/9PE32fj24SC+I1fJH+T +2ZD2VScqHGBnbkSbCMYiQ5bLHWmM4JCeMyRtAOoGLaQaWg/4enYtBNJ845vvNGvY +6Ma4Kt40cZBlR6R7w3eKbNKtlFx+OJxQhD1mqHm6UeAVwi817hcN9IFJXawpanDF +rTqkFMH+/2Z3YULywNj4iRAv+REBc3jM45flwDo1vu/NazvAT5p4hVV5kRgFVgsn +C0I9KUM73ww4tTOC2QQMPoOkQGvyAAdZqSjTn7IdsA2EvpyZ+qu+wjmUVZ9A2S4l +czPBDUah9LkRdaLAoKgLgQOCAQUAAoIBAAHb5mq9RGf+mLtQi12GnLIlWF45bhHr +0+gNYMzTA7PBzb/E+SfeizOnNuJtNU3LSiNE+sHNMnn/WY4KvjMCryuRxz7b8Y8+ +0nGwN0YfyY/cK5CehRa+lfhahlTorF8VY98gcQJOyKjG0eloZ8H29MhPhYTF0qTS +5dbDb4nf5r5Uqx5/6gBmskpMG+xiXA2I7q2aLW92pZrFWYrkrNgaAAQqSl0whhG6 +EZXP6fAbndJbt706xFlySr/ZHkgWybEAXYO8TbjyDkZP/h9UyR6CnKeb3L6qw8be +8U5scYfx2HjhCv5GLqqauRm+0oJwbXmOWuMpeynGHy24O+wKAX/ePhujUzBRMB0G +A1UdDgQWBBSzt5hCeCbPIvNHVrmX35BNe+u+QzAfBgNVHSMEGDAWgBSzt5hCeCbP +IvNHVrmX35BNe+u+QzAPBgNVHRMBAf8EBTADAQH/MAsGCWCGSAFlAwQDBANAADA9 +AhxgdnguNQoOQZyseelUWc5tD7m/ESvTuAV2aiEwAh0Apmc4SMIg7nKTA2jp7M1E +V7kA7INPUKKx/+iWgA== +-----END CERTIFICATE----- diff --git a/test/certs/setup.sh b/test/certs/setup.sh index 3bee78ec3261e..e3dcc5b43c359 100755 --- a/test/certs/setup.sh +++ b/test/certs/setup.sh @@ -86,6 +86,39 @@ openssl x509 -in sroot-cert.pem -trustout \ ./mkcert.sh genca "CA2" ca-key ca-name2 root-key root-cert ./mkcert.sh genca "CA" ca-key ca-root2 root-key2 root-cert2 DAYS=-1 ./mkcert.sh genca "CA" ca-key ca-expired root-key root-cert +# CA key rollover chain: a self-issued transition certificate carries the +# new CA key (ca-key) but is signed by the old key (root-key), so its SKID +# differs from its AKID keyIdentifier and it must not be classified as +# self-signed. The old root reuses root-key, the leaf ee-key. Explicit +# serials 1000-1002 keep the same-named issuers of these certificates +# distinct for X509_STORE lookups. +./mkcert.sh req root-key "CN = Test Rollover CA" | + openssl x509 -req -sha256 -signkey root-key.pem -set_serial 1000 \ + -not_before 20200101000000Z -days 36525 -out rollover-root.pem \ + -extfile <(printf "%s\n" \ + "basicConstraints = critical,CA:true" \ + "keyUsage = keyCertSign,cRLSign" \ + "subjectKeyIdentifier = hash" \ + "authorityKeyIdentifier = keyid") +./mkcert.sh req ca-key "CN = Test Rollover CA" | + openssl x509 -req -sha256 -CA rollover-root.pem -CAkey root-key.pem \ + -set_serial 1001 -not_before 20200101000000Z -days 36525 \ + -out rollover-ca.pem \ + -extfile <(printf "%s\n" \ + "basicConstraints = critical,CA:true" \ + "keyUsage = keyCertSign,cRLSign" \ + "subjectKeyIdentifier = hash" \ + "authorityKeyIdentifier = keyid") +./mkcert.sh req ee-key "CN = Test Rollover EE" | + openssl x509 -req -sha256 -CA rollover-ca.pem -CAkey ca-key.pem \ + -set_serial 1002 -not_before 20200101000000Z -days 36525 \ + -out rollover-ee.pem \ + -extfile <(printf "%s\n" \ + "basicConstraints = critical,CA:false" \ + "keyUsage = digitalSignature,keyEncipherment" \ + "extendedKeyUsage = serverAuth,clientAuth" \ + "subjectKeyIdentifier = hash" \ + "authorityKeyIdentifier = keyid") # trust variants: +serverAuth, -serverAuth, +clientAuth, -clientAuth openssl x509 -in ca-cert.pem -trustout \ -addtrust serverAuth -out ca+serverAuth.pem @@ -163,6 +196,8 @@ openssl x509 -in sca-cert.pem -trustout \ ./mkcert.sh genee server.example ee-key ee-name2 ca-key ca-name2 ./mkcert.sh genee server.example ee-key ee-pathlen ca-key ca-cert \ -extfile <(echo "basicConstraints=CA:false,pathlen:0") # bash needed here +# ee variant: issued directly by root CA (2-level chain) +./mkcert.sh genee server.example1 ee-key ee-cert1 root-key root-cert # purpose variants: clientAuth ./mkcert.sh genee -p clientAuth server.example ee-key ee-client ca-key ca-cert # trust variants: +serverAuth, -serverAuth, +clientAuth, -clientAuth @@ -497,7 +532,44 @@ OPENSSL_SIGALG="sha3-256" ./mkcert.sh genee server.example ee-key-ec-named-named OPENSSL_SIGALG="sha3-384" ./mkcert.sh genee server.example ee-key-ec-named-named ee-cert-ec-sha3-384 ca-key-ec-named ca-cert-ec-named OPENSSL_SIGALG="sha3-512" ./mkcert.sh genee server.example ee-key-ec-named-named ee-cert-ec-sha3-512 ca-key-ec-named ca-cert-ec-named -# EC cert seigned RSA intermediate CA +# DSA roots and EE certs: id-dsa-with-sha384 / id-dsa-with-sha512 +# (regression for https://github.com/openssl/openssl/issues/30432) +_DSA_CERT_DIR=$(cd "$(dirname "$0")" && pwd) +( + set -e + d=$(mktemp -d) + trap 'rm -rf "$d"' EXIT + cd "$d" + openssl dsaparam -out dsap.pem 2048 + openssl gendsa -out ca384k.pem dsap.pem + openssl req -new -x509 -key ca384k.pem -sha384 -out root-cert-dsa-sha384.pem \ + -days 3650 -subj "/CN=OpenSSL Test DSA SHA-384 Root" -nodes + openssl gendsa -out ee384k.pem dsap.pem + openssl req -new -key ee384k.pem -out ee384.csr \ + -subj "/CN=OpenSSL Test DSA SHA-384 EE" + openssl x509 -req -in ee384.csr -CA root-cert-dsa-sha384.pem -CAkey ca384k.pem \ + -CAcreateserial -out ee-cert-dsa-sha384.pem -days 3650 -sha384 + openssl gendsa -out ca512k.pem dsap.pem + openssl req -new -x509 -key ca512k.pem -sha512 -out root-cert-dsa-sha512.pem \ + -days 3650 -subj "/CN=OpenSSL Test DSA SHA-512 Root" -nodes + openssl gendsa -out ee512k.pem dsap.pem + openssl req -new -key ee512k.pem -out ee512.csr \ + -subj "/CN=OpenSSL Test DSA SHA-512 EE" + openssl x509 -req -in ee512.csr -CA root-cert-dsa-sha512.pem -CAkey ca512k.pem \ + -CAcreateserial -out ee-cert-dsa-sha512.pem -days 3650 -sha512 + cp root-cert-dsa-sha384.pem ee-cert-dsa-sha384.pem \ + root-cert-dsa-sha512.pem ee-cert-dsa-sha512.pem \ + "$_DSA_CERT_DIR" +) +unset _DSA_CERT_DIR + +# EC end-entity cert signed by RSA intermediate CA OPENSSL_KEYALG=ec OPENSSL_KEYBITS=prime256v1 ./mkcert.sh genee \ "P-256 cert EE issuer" p256-ee-rsa-ca-key \ p256-ee-rsa-ca-cert ca-key ca-cert + +# Mixed chain: RSA root -> ECC intermediate CA -> RSA end entity +OPENSSL_KEYALG=ec OPENSSL_KEYBITS=prime256v1 ./mkcert.sh genca \ + "ECC CA" mixed-ca-key mixed-ca-cert root-key root-cert +OPENSSL_KEYALG=rsa OPENSSL_KEYBITS=2048 ./mkcert.sh genee \ + "server mixed ECC/RSA" mixed-ee-key mixed-ee-cert mixed-ca-key mixed-ca-cert diff --git a/test/chacha_internal_test.c b/test/chacha_internal_test.c index effdc26b883e1..f4ff4bbda064d 100644 --- a/test/chacha_internal_test.c +++ b/test/chacha_internal_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/cipher_dupctx_test.c b/test/cipher_dupctx_test.c new file mode 100644 index 0000000000000..acbe12bf54c5d --- /dev/null +++ b/test/cipher_dupctx_test.c @@ -0,0 +1,118 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Test that EVP_CIPHER_CTX_copy correctly deep-copies the tlsmac buffer + * to prevent double-free when both contexts are freed. + * See https://github.com/openssl/openssl/issues/30548 + */ + +#include +#include +#include +#include +#include +#include +#include "testutil.h" + +/* + * Test that duplicating a cipher context with a heap-allocated tlsmac + * buffer does not cause a double-free when both contexts are freed. + * + * The tlsmac buffer is allocated during TLS CBC decryption via + * ossl_cipher_tlsunpadblock -> ssl3_cbc_copy_mac -> OPENSSL_malloc. + * Without the fix, the shallow copy in dupctx causes both the original + * and duplicated context to share the same pointer, leading to a + * double-free in ossl_cipher_generic_reset_ctx. + */ +static int test_dupctx_tlsmac(int idx) +{ + static const char *cipher_names[] = { + "AES-128-CBC", + "AES-256-CBC" + }; + const char *name = cipher_names[idx]; + EVP_CIPHER_CTX *ctx = NULL, *dupctx = NULL; + EVP_CIPHER *cipher = NULL; + unsigned char key[32] = { 0 }; + unsigned char iv[16] = { 0 }; + unsigned char buf[64]; + int outl = 0; + int ret = 0; + unsigned int tls_ver = TLS1_VERSION; + size_t mac_size = 20; /* SHA1 */ + OSSL_PARAM params[3]; + + cipher = EVP_CIPHER_fetch(NULL, name, NULL); + if (!TEST_ptr(cipher)) + goto err; + + ctx = EVP_CIPHER_CTX_new(); + if (!TEST_ptr(ctx)) + goto err; + + if (!TEST_true(EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv))) + goto err; + + /* Set TLS parameters to trigger tlsmac allocation */ + params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_TLS_VERSION, + &tls_ver); + params[1] = OSSL_PARAM_construct_size_t(OSSL_CIPHER_PARAM_TLS_MAC_SIZE, + &mac_size); + params[2] = OSSL_PARAM_construct_end(); + + if (!TEST_true(EVP_CIPHER_CTX_set_params(ctx, params))) + goto err; + + /* + * Perform a decrypt update with enough data to trigger tlsmac + * allocation. Buffer needs at least: block_size + mac_size + 1. + * For AES-CBC: 16 + 20 + 1 = 37 minimum. Use 64 for safety. + * Last byte is padding length (0 = 1 byte of padding). + */ + memset(buf, 0, sizeof(buf)); + ERR_clear_error(); + if (!EVP_DecryptUpdate(ctx, buf, &outl, buf, sizeof(buf))) + ERR_clear_error(); + + /* + * Duplicate the context. Before the fix, this created a shallow + * copy that shared the tlsmac pointer. + */ + dupctx = EVP_CIPHER_CTX_new(); + if (!TEST_ptr(dupctx)) + goto err; + + if (!TEST_true(EVP_CIPHER_CTX_copy(dupctx, ctx))) + goto err; + + /* + * Free both contexts. Without the fix, the second free triggers + * a double-free on the shared tlsmac pointer. + * With ASan enabled, this would be detected as "attempting double-free". + */ + EVP_CIPHER_CTX_free(ctx); + ctx = NULL; + EVP_CIPHER_CTX_free(dupctx); + dupctx = NULL; + + ret = 1; + +err: + EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_CTX_free(dupctx); + EVP_CIPHER_free(cipher); + return ret; +} + +int setup_tests(void) +{ + ADD_ALL_TESTS(test_dupctx_tlsmac, 2); + return 1; +} diff --git a/test/cipher_overhead_test.c b/test/cipher_overhead_test.c index 176d6cc8770b5..b32a5280e2e8b 100644 --- a/test/cipher_overhead_test.c +++ b/test/cipher_overhead_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ +#include #include "internal/nelem.h" #include "testutil.h" #include "../ssl/ssl_local.h" @@ -30,6 +31,7 @@ static int cipher_enabled(const SSL_CIPHER *ciph) return 1; } +/* The DTLS 1.2 (and earlier) ciphers live in the ssl3_ciphers[] table. */ static int cipher_overhead(void) { int ret = 1, i, n = ssl3_num_ciphers(); @@ -44,7 +46,8 @@ static int cipher_overhead(void) TEST_skip("Skipping disabled cipher %s", ciph->name); continue; } - if (!TEST_true(ssl_cipher_get_overhead(ciph, &mac, &in, &blk, &ex))) { + if (!TEST_true(ssl_cipher_get_overhead(ciph, DTLS1_2_VERSION, + &mac, &in, &blk, &ex))) { TEST_info("Failed getting %s", ciph->name); ret = 0; } else { @@ -55,8 +58,51 @@ static int cipher_overhead(void) return ret; } +/* + * The DTLS 1.3 ciphers are the TLS 1.3 ciphersuites, which are not reachable + * through ssl3_get_cipher(), so look them up by id instead. + */ +static const struct { + uint32_t id; + size_t ext; /* expected external overhead in DTLS 1.3 (no explicit IV) */ +} dtls13_ciphers[] = { + { TLS1_3_CK_AES_128_GCM_SHA256, EVP_GCM_TLS_TAG_LEN }, + { TLS1_3_CK_AES_256_GCM_SHA384, EVP_GCM_TLS_TAG_LEN }, + { TLS1_3_CK_CHACHA20_POLY1305_SHA256, 16 }, + { TLS1_3_CK_AES_128_CCM_SHA256, 16 }, + { TLS1_3_CK_AES_128_CCM_8_SHA256, 8 }, +}; + +static int dtls13_cipher_overhead(int idx) +{ + const SSL_CIPHER *ciph = ssl3_get_cipher_by_id(dtls13_ciphers[idx].id); + size_t mac, in, blk, ex; + + if (!TEST_ptr(ciph)) + return 0; + if (!cipher_enabled(ciph)) { + TEST_skip("Skipping disabled cipher %s", ciph->name); + return 1; + } + + /* DTLS 1.3 uses an implicit nonce, so there is no explicit IV on the wire. */ + if (!TEST_true(ssl_cipher_get_overhead(ciph, DTLS1_3_VERSION, + &mac, &in, &blk, &ex))) { + TEST_info("Failed getting %s (DTLSv1.3)", ciph->name); + return 0; + } + TEST_info("Cipher %s (DTLSv1.3): %zu %zu %zu %zu", + ciph->name, mac, in, blk, ex); + if (!TEST_size_t_eq(ex, dtls13_ciphers[idx].ext)) + return 0; + + return 1; +} + int setup_tests(void) { + OPENSSL_init_ssl(0, NULL); ADD_TEST(cipher_overhead); + ADD_ALL_TESTS(dtls13_cipher_overhead, OSSL_NELEM(dtls13_ciphers)); return 1; } diff --git a/test/cipherlist_test.c b/test/cipherlist_test.c index a0e1704d49284..921afe6234a7a 100644 --- a/test/cipherlist_test.c +++ b/test/cipherlist_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/clienthellotest.c b/test/clienthellotest.c index 068bc8e9f1318..50774f23aa972 100644 --- a/test/clienthellotest.c +++ b/test/clienthellotest.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -23,30 +23,13 @@ #define CLIENT_VERSION_LEN 2 -#define TOTAL_NUM_TESTS 3 +#define TOTAL_NUM_TESTS 1 /* * Test that explicitly setting ticket data results in it appearing in the * ClientHello for a negotiated SSL/TLS version */ #define TEST_SET_SESSION_TICK_DATA_VER_NEG 0 -/* Enable padding and make sure ClientHello is long enough to require it */ -#define TEST_ADD_PADDING 1 -/* Enable padding and make sure ClientHello is short enough to not need it */ -#define TEST_PADDING_NOT_NEEDED 2 - -#define F5_WORKAROUND_MIN_MSG_LEN 0x7f -#define F5_WORKAROUND_MAX_MSG_LEN 0x200 - -/* Dummy ALPN protocols used to pad out the size of the ClientHello */ -/* ASCII 'O' = 79 = 0x4F = EBCDIC '|'*/ -#ifdef CHARSET_EBCDIC -static const char alpn_prots[] = "|1234567890123456789012345678901234567890123456789012345678901234567890123456789" - "|1234567890123456789012345678901234567890123456789012345678901234567890123456789"; -#else -static const char alpn_prots[] = "O1234567890123456789012345678901234567890123456789012345678901234567890123456789" - "O1234567890123456789012345678901234567890123456789012345678901234567890123456789"; -#endif static int test_client_hello(int currtest) { @@ -60,7 +43,6 @@ static int test_client_hello(int currtest) char *dummytick = "Hello World!"; unsigned int type = 0; int testresult = 0; - size_t msglen; BIO *sessbio = NULL; SSL_SESSION *sess = NULL; @@ -91,37 +73,6 @@ static int test_client_hello(int currtest) #endif break; - case TEST_ADD_PADDING: - case TEST_PADDING_NOT_NEEDED: - SSL_CTX_set_options(ctx, SSL_OP_TLSEXT_PADDING); - /* Make sure we get a consistent size across TLS versions */ - SSL_CTX_clear_options(ctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT); - /* Avoid large keyshares */ - if (!TEST_true(SSL_CTX_set1_groups_list(ctx, - "?X25519:?secp256r1:?ffdhe2048:?ffdhe3072"))) - goto end; - /* - * Add some dummy ALPN protocols so that the ClientHello is at least - * F5_WORKAROUND_MIN_MSG_LEN bytes long - meaning padding will be - * needed. - */ - if (currtest == TEST_ADD_PADDING) { - if (!TEST_false(SSL_CTX_set_alpn_protos(ctx, - (unsigned char *)alpn_prots, - sizeof(alpn_prots) - 1))) - goto end; - /* - * Otherwise we need to make sure we have a small enough message to - * not need padding. - */ - } else if (!TEST_true(SSL_CTX_set_cipher_list(ctx, - "AES128-SHA")) - || !TEST_true(SSL_CTX_set_ciphersuites(ctx, - "TLS_AES_128_GCM_SHA256"))) { - goto end; - } - break; - default: goto end; } @@ -158,8 +109,6 @@ static int test_client_hello(int currtest) || !PACKET_forward(&pkt, SSL3_RT_HEADER_LENGTH)) goto end; - msglen = PACKET_remaining(&pkt); - /* Skip the handshake message header */ if (!TEST_true(PACKET_forward(&pkt, SSL3_HM_HEADER_LENGTH)) /* Skip client version and random */ @@ -191,17 +140,8 @@ static int test_client_hello(int currtest) goto end; } } - if (type == TLSEXT_TYPE_padding) { - if (!TEST_false(currtest == TEST_PADDING_NOT_NEEDED)) - goto end; - else if (TEST_true(currtest == TEST_ADD_PADDING)) - testresult = TEST_true(msglen == F5_WORKAROUND_MAX_MSG_LEN); - } } - if (currtest == TEST_PADDING_NOT_NEEDED) - testresult = 1; - end: SSL_free(con); SSL_CTX_free(ctx); diff --git a/test/cmactest.c b/test/cmactest.c index 36e2a3c61dba0..4c05226ff855e 100644 --- a/test/cmactest.c +++ b/test/cmactest.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -307,7 +307,7 @@ static char *pt(unsigned char *md, size_t len) static char buf[81]; for (i = 0; i < len && (i + 1) * OSSL_HEX_CHARS_PER_BYTE < sizeof(buf); i++) - BIO_snprintf(buf + i * OSSL_HEX_CHARS_PER_BYTE, + snprintf(buf + i * OSSL_HEX_CHARS_PER_BYTE, OSSL_HEX_CHARS_PER_BYTE + 1, "%02x", md[i]); return buf; } diff --git a/test/cmp_client_test.c b/test/cmp_client_test.c index cd51d3d0e7735..a4a2842cd6f52 100644 --- a/test/cmp_client_test.c +++ b/test/cmp_client_test.c @@ -140,16 +140,18 @@ static int execute_exec_GENM_ses_test_single(CMP_SES_TEST_FIXTURE *fixture) ASN1_OBJECT *type = OBJ_txt2obj("1.3.6.1.5.5.7.4.2", 1); OSSL_CMP_ITAV *itav = OSSL_CMP_ITAV_create(type, NULL); STACK_OF(OSSL_CMP_ITAV) *itavs; + int ret; OSSL_CMP_CTX_push0_genm_ITAV(ctx, itav); itavs = OSSL_CMP_exec_GENM_ses(ctx); print_errors_PKIStatusInfo(ctx); + ret = TEST_int_eq(OSSL_CMP_CTX_get_status(ctx), fixture->expected) + && (fixture->expected == OSSL_CMP_PKISTATUS_accepted + ? TEST_ptr(itavs) + : TEST_ptr_null(itavs)); sk_OSSL_CMP_ITAV_pop_free(itavs, OSSL_CMP_ITAV_free); - return TEST_int_eq(OSSL_CMP_CTX_get_status(ctx), fixture->expected) - && fixture->expected == OSSL_CMP_PKISTATUS_accepted - ? TEST_ptr(itavs) - : TEST_ptr_null(itavs); + return ret; } static int execute_exec_GENM_ses_test(CMP_SES_TEST_FIXTURE *fixture) diff --git a/test/cmp_extracerts_dos_test.c b/test/cmp_extracerts_dos_test.c new file mode 100644 index 0000000000000..edb2dc8c4acc4 --- /dev/null +++ b/test/cmp_extracerts_dos_test.c @@ -0,0 +1,349 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Regression test for: CMP server unauthenticated memory/CPU DoS via + * cached extraCerts on failed protection checks. + * + * Root cause (crypto/cmp/cmp_vfy.c, ossl_cmp_msg_check_update(), current + * master as of this writing): + * + * res = ossl_x509_add_certs_new(&ctx->untrusted, msg->extraCerts, ...); + * ... + * res = OSSL_CMP_validate_msg(ctx, msg) || (cb...); // may be 0 (rejected) + * + * if (ctx->noCacheExtraCerts) // <-- rollback is + * while (num_added-- > 0) // gated on this + * X509_free(sk_X509_shift(ctx->untrusted)); // flag only, NOT + * // on the + * // validation + * // result (res) + * + * if (!res) { ...; return 0; } // certs from a REJECTED msg are kept + * + * This test exercises ossl_cmp_msg_check_update() directly -- no sockets, + * no HTTP server, no apps/cmp.c -- and asserts on the resulting size of + * ctx->untrusted. It builds a genuinely PBM-protected OSSL_CMP_MSG using + * the project's own internal message-creation function + * (ossl_cmp_genm_new(), same one exercised in test/cmp_msg_test.c) so the + * message is not hand-crafted to "look" rejectable -- it is rejected for a + * real reason (the receiving ctx has no matching secret configured), the + * same way OSSL_CMP_validate_msg() would reject any unauthenticated CMP + * request in the field. + * + * Expected results: + * - BEFORE the fix: untrusted_count_after == untrusted_count_before + N + * (every rejected message's extraCerts persist) + * - AFTER the fix: untrusted_count_after == untrusted_count_before + * (rejected messages leave no residue) + */ + +#include "helpers/cmp_testlib.h" + +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +/* + * In fuzzing builds ossl_cmp_msg_check_update() deliberately lets invalid + * messages pass (see cmp_vfy.c), so the rejection path under test here + * cannot be exercised. + */ + +#define NUM_REJECTED_REQUESTS 25 /* "attacker" sends this many distinct certs */ + +typedef struct test_fixture { + const char *test_case_name; + OSSL_CMP_CTX *server_ctx; /* long-lived ctx under test, mirrors srv_ctx->ctx */ +} CMP_DOS_TEST_FIXTURE; + +static OSSL_LIB_CTX *libctx = NULL; + +static CMP_DOS_TEST_FIXTURE *set_up(const char *const test_case_name) +{ + CMP_DOS_TEST_FIXTURE *fixture; + + if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture)))) + return NULL; + fixture->test_case_name = test_case_name; + + if (!TEST_ptr(fixture->server_ctx = OSSL_CMP_CTX_new(libctx, NULL))) { + OPENSSL_free(fixture); + return NULL; + } + /* + * Deliberately do NOT call OSSL_CMP_CTX_set1_secretValue() on the + * server ctx. Per OSSL_CMP_validate_msg() (crypto/cmp/cmp_vfy.c): + * case NID_id_PasswordBasedMAC: + * if (ctx->secretValue == NULL) { + * ossl_cmp_info(ctx, "no secret available for verifying.."); + * ERR_raise(ERR_LIB_CMP, CMP_R_ERROR_VALIDATING_PROTECTION); + * return 0; + * } + * so every PBM-protected message this ctx receives is unconditionally + * rejected -- a deterministic, content-independent rejection path that + * models "missing or invalid protection" from the report's repro + * steps, without needing to forge a bad MAC by hand. + * ctx->noCacheExtraCerts is left at its default (0), exactly as in the + * vulnerable deployment ("not setting -no_cache_extracerts"). + */ + return fixture; +} + +static void tear_down(CMP_DOS_TEST_FIXTURE *fixture) +{ + if (fixture == NULL) + return; + OSSL_CMP_CTX_free(fixture->server_ctx); + OPENSSL_free(fixture); +} + +/* Generates a throwaway EC P-256 keypair; cheap, and key strength is + * irrelevant to this test. */ +static EVP_PKEY *generate_throwaway_keypair(void) +{ + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY *pkey = NULL; + + if (!TEST_ptr(pctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", NULL))) + return NULL; + if (!TEST_int_gt(EVP_PKEY_keygen_init(pctx), 0) + || !TEST_int_gt(EVP_PKEY_CTX_set_group_name(pctx, "P-256"), 0) + || !TEST_int_gt(EVP_PKEY_generate(pctx, &pkey), 0)) + pkey = NULL; + EVP_PKEY_CTX_free(pctx); + return pkey; +} + +/* + * Builds a minimal, self-signed, syntactically valid X509 with a unique + * subject/issuer per index, so X509_ADD_FLAG_NO_DUP cannot collapse it + * with any other generated cert (matching the report's exploitation + * requirement of "unique certificates across requests"). + */ +static X509 *generate_unique_self_signed_cert(EVP_PKEY *pkey, int index) +{ + X509 *cert = NULL; + X509_NAME *name = NULL; + ASN1_INTEGER *serial = NULL; + char cn[64]; + + snprintf(cn, sizeof(cn), "attacker-cert-%d", index); + + if (!TEST_ptr(cert = X509_new()) + || !TEST_true(X509_set_version(cert, X509_VERSION_3))) + goto err; + + if (!TEST_ptr(serial = ASN1_INTEGER_new()) + || !TEST_true(ASN1_INTEGER_set(serial, 1000L + index)) + || !TEST_true(X509_set_serialNumber(cert, serial))) + goto err; + + if (!TEST_ptr(X509_gmtime_adj(X509_getm_notBefore(cert), 0)) + || !TEST_ptr(X509_gmtime_adj(X509_getm_notAfter(cert), + 60L * 60L * 24L * 365L))) + goto err; + + if (!TEST_true(X509_set_pubkey(cert, pkey))) + goto err; + + if (!TEST_ptr(name = X509_NAME_new()) + || !TEST_true(X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC, + (unsigned char *)"cmp-dos-test", + -1, -1, 0)) + || !TEST_true(X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, + (unsigned char *)cn, + -1, -1, 0)) + || !TEST_true(X509_set_subject_name(cert, name)) + || !TEST_true(X509_set_issuer_name(cert, name))) + goto err; + + if (!TEST_int_gt(X509_sign(cert, pkey, EVP_sha256()), 0)) + goto err; + + X509_NAME_free(name); + ASN1_INTEGER_free(serial); + return cert; + +err: + X509_NAME_free(name); + ASN1_INTEGER_free(serial); + X509_free(cert); + return NULL; +} + +/* + * Builds a real, internally consistent, PBM-protected CMP GenMsg carrying + * exactly one never-before-seen self-signed cert as its sole extraCert. + * Uses a throwaway *client*-side OSSL_CMP_CTX purely to drive message + * creation/protection (ossl_cmp_genm_new() both builds the body and calls + * ossl_cmp_msg_protect() internally, same as in test/cmp_msg_test.c). The + * client ctx's secret is intentionally never shared with the server ctx + * under test, so the message is protected (syntactically well-formed, + * non-empty protection field) but NOT verifiable by the receiver -- this + * is what "missing or invalid protection" means for a real attacker who + * has no credentials, not an empty/garbage protection field. + */ +static OSSL_CMP_MSG *build_rejectable_msg_with_unique_cert(int index) +{ + OSSL_CMP_CTX *client_ctx = NULL; + OSSL_CMP_MSG *msg = NULL; + EVP_PKEY *pkey = NULL; + X509 *fresh_cert = NULL; + STACK_OF(X509) *extra = NULL; + unsigned char ref[16], secret[16]; + + if (!TEST_ptr(client_ctx = OSSL_CMP_CTX_new(libctx, NULL))) + goto err; + + if (!TEST_ptr(pkey = generate_throwaway_keypair()) + || !TEST_ptr(fresh_cert = generate_unique_self_signed_cert(pkey, index))) + goto err; + + if (!TEST_ptr(extra = sk_X509_new_null()) + || !TEST_true(sk_X509_push(extra, fresh_cert))) + goto err; + fresh_cert = NULL; /* ownership now with the stack */ + + if (!TEST_true(OSSL_CMP_CTX_set1_extraCertsOut(client_ctx, extra))) + goto err; + + /* PBM protection with a secret the server ctx will never be given */ + memset(ref, (unsigned char)(0xA0 + (index & 0x0F)), sizeof(ref)); + memset(secret, (unsigned char)(0x50 + (index & 0x0F)), sizeof(secret)); + if (!TEST_true(OSSL_CMP_CTX_set_option(client_ctx, + OSSL_CMP_OPT_UNPROTECTED_SEND, 0)) + || !TEST_true(OSSL_CMP_CTX_set1_referenceValue(client_ctx, ref, + sizeof(ref))) + || !TEST_true(OSSL_CMP_CTX_set1_secretValue(client_ctx, secret, + sizeof(secret)))) + goto err; + + /* GenMsg is the lightest standard body type for this purpose */ + if (!TEST_ptr(msg = ossl_cmp_genm_new(client_ctx))) + goto err; + + sk_X509_pop_free(extra, X509_free); + X509_free(fresh_cert); + EVP_PKEY_free(pkey); + OSSL_CMP_CTX_free(client_ctx); + return msg; + +err: + sk_X509_pop_free(extra, X509_free); + X509_free(fresh_cert); + EVP_PKEY_free(pkey); + OSSL_CMP_CTX_free(client_ctx); + OSSL_CMP_MSG_free(msg); + return NULL; +} + +/* + * Core assertion: N distinct rejected requests must not grow + * server_ctx->untrusted at all. + * + * Before the fix this fails with e.g.: + * ERROR: untrusted count after (25) != count before (0) + */ +static int execute_no_unbounded_growth_test(CMP_DOS_TEST_FIXTURE *fixture) +{ + OSSL_CMP_CTX *server_ctx = fixture->server_ctx; + int count_before, count_after, i; + + count_before = sk_X509_num(OSSL_CMP_CTX_get0_untrusted(server_ctx)); + if (count_before < 0) + count_before = 0; + + for (i = 0; i < NUM_REJECTED_REQUESTS; i++) { + OSSL_CMP_MSG *msg = build_rejectable_msg_with_unique_cert(i); + int check_result; + + if (!TEST_ptr(msg)) + return 0; + + check_result = ossl_cmp_msg_check_update(server_ctx, msg, NULL, 0); + OSSL_CMP_MSG_free(msg); + + if (!TEST_int_eq(check_result, 0)) { + TEST_note("expected request #%d to be rejected (server ctx has" + " no matching PBM secret) but it was accepted -- test" + " setup is wrong, not exercising the rejection path", + i); + return 0; + } + } + + count_after = sk_X509_num(OSSL_CMP_CTX_get0_untrusted(server_ctx)); + if (count_after < 0) + count_after = 0; + + if (!TEST_int_eq(count_after, count_before)) { + TEST_note("server_ctx->untrusted grew from %d to %d after %d" + " rejected requests -- failed-request extraCerts caching" + " bug is present (see ossl_cmp_msg_check_update() in" + " crypto/cmp/cmp_vfy.c)", + count_before, count_after, + NUM_REJECTED_REQUESTS); + return 0; + } + return 1; +} + +/* + * Single-request variant of the same check, useful in isolation since it + * pins down that even ONE rejected request leaves no residue -- ruling out + * X509_ADD_FLAG_NO_DUP coincidentally masking the bug in the N-request test. + */ +static int execute_single_rejected_request_test(CMP_DOS_TEST_FIXTURE *fixture) +{ + OSSL_CMP_CTX *server_ctx = fixture->server_ctx; + OSSL_CMP_MSG *msg = build_rejectable_msg_with_unique_cert(999); + int count_before, count_after; + + if (!TEST_ptr(msg)) + return 0; + + count_before = sk_X509_num(OSSL_CMP_CTX_get0_untrusted(server_ctx)); + if (count_before < 0) + count_before = 0; + + if (!TEST_int_eq(ossl_cmp_msg_check_update(server_ctx, msg, NULL, 0), 0)) { + OSSL_CMP_MSG_free(msg); + return 0; + } + OSSL_CMP_MSG_free(msg); + + count_after = sk_X509_num(OSSL_CMP_CTX_get0_untrusted(server_ctx)); + if (count_after < 0) + count_after = 0; + + return TEST_int_eq(count_after, count_before); +} + +static int test_single_rejected_request_leaves_no_residue(void) +{ + SETUP_TEST_FIXTURE(CMP_DOS_TEST_FIXTURE, set_up); + EXECUTE_TEST(execute_single_rejected_request_test, tear_down); + return result; +} + +static int test_no_unbounded_growth_on_rejected_requests(void) +{ + SETUP_TEST_FIXTURE(CMP_DOS_TEST_FIXTURE, set_up); + EXECUTE_TEST(execute_no_unbounded_growth_test, tear_down); + return result; +} + +#endif + +int setup_tests(void) +{ +#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + ADD_TEST(test_single_rejected_request_leaves_no_residue); + ADD_TEST(test_no_unbounded_growth_on_rejected_requests); +#endif + return 1; +} diff --git a/test/cmp_hdr_test.c b/test/cmp_hdr_test.c index cbffb87b23e14..2ee01f3cb5114 100644 --- a/test/cmp_hdr_test.c +++ b/test/cmp_hdr_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -78,7 +78,8 @@ static int execute_HDR_get0_senderNonce_test(CMP_HDR_TEST_FIXTURE *fixture) if (!TEST_ptr(sender)) goto err; - X509_NAME_ADD(sender, "CN", "A common sender name"); + if (!TEST_true(X509_NAME_ADD(sender, "CN", "A common sender name"))) + goto err; if (!TEST_int_eq(OSSL_CMP_CTX_set1_subjectName(fixture->cmp_ctx, sender), 1)) goto err; @@ -113,7 +114,8 @@ static int execute_HDR_set1_sender_test(CMP_HDR_TEST_FIXTURE *fixture) if (!TEST_ptr(x509name)) goto err; - X509_NAME_ADD(x509name, "CN", "A common sender name"); + if (!TEST_true(X509_NAME_ADD(x509name, "CN", "A common sender name"))) + goto err; if (!TEST_int_eq(ossl_cmp_hdr_set1_sender(fixture->hdr, x509name), 1)) goto err; @@ -148,7 +150,8 @@ static int execute_HDR_set1_recipient_test(CMP_HDR_TEST_FIXTURE *fixture) if (!TEST_ptr(x509name)) goto err; - X509_NAME_ADD(x509name, "CN", "A common recipient name"); + if (!TEST_true(X509_NAME_ADD(x509name, "CN", "A common recipient name"))) + goto err; if (!TEST_int_eq(ossl_cmp_hdr_set1_recipient(fixture->hdr, x509name), 1)) goto err; @@ -252,7 +255,7 @@ static int execute_HDR_push0_freeText_test(CMP_HDR_TEST_FIXTURE *fixture) if (!TEST_ptr(text)) return 0; - if (!ASN1_STRING_set(text, "A free text", -1)) + if (!ASN1_STRING_set1_string(text, "A free text")) goto err; if (!TEST_int_eq(ossl_cmp_hdr_push0_freeText(fixture->hdr, text), 1)) @@ -279,13 +282,14 @@ static int test_HDR_push0_freeText(void) static int execute_HDR_push1_freeText_test(CMP_HDR_TEST_FIXTURE *fixture) { ASN1_UTF8STRING *text = ASN1_UTF8STRING_new(); + ASN1_UTF8STRING *empty = ASN1_UTF8STRING_new(); ASN1_UTF8STRING *pushed_text; int res = 0; - if (!TEST_ptr(text)) + if (!TEST_ptr(text) || !TEST_ptr(empty)) goto err; - if (!ASN1_STRING_set(text, "A free text", -1)) + if (!ASN1_STRING_set1_string(text, "A free text")) goto err; if (!TEST_int_eq(ossl_cmp_hdr_push1_freeText(fixture->hdr, text), 1)) @@ -295,9 +299,23 @@ static int execute_HDR_push1_freeText_test(CMP_HDR_TEST_FIXTURE *fixture) if (!TEST_int_eq(ASN1_STRING_cmp(text, pushed_text), 0)) goto err; + /* + * An empty ASN1_UTF8STRING, as decoded from an empty UTF8String, has + * data == NULL and length == 0 and must still push successfully. + */ + if (!TEST_int_eq(ossl_cmp_hdr_push1_freeText(fixture->hdr, empty), 1)) + goto err; + + if (!TEST_ptr(pushed_text = sk_ASN1_UTF8STRING_value(fixture->hdr->freeText, 1))) + goto err; + + if (!TEST_int_eq(pushed_text->length, 0)) + goto err; + res = 1; err: ASN1_UTF8STRING_free(text); + ASN1_UTF8STRING_free(empty); return res; } diff --git a/test/cmp_protect_test.c b/test/cmp_protect_test.c index a8d673e5e1f66..80ce1fb7581b5 100644 --- a/test/cmp_protect_test.c +++ b/test/cmp_protect_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -185,6 +185,38 @@ static int test_cmp_calc_protection_pbmac(void) EXECUTE_TEST(execute_calc_protection_pbmac_test, tear_down); return result; } + +/* + * Regression test for the ossl_cmp_calc_protection() protectionAlg + * type-confusion DoS: a PKIMessage whose protectionAlg has the + * id-PasswordBasedMAC OID but carries a BOOLEAN parameter instead of the + * expected PBMParameter SEQUENCE. X509_ALGOR_get0() then returns the boolean's + * union member (0xff) via ppval; the unpatched code took the non-NULL ppval as + * a valid ASN1_STRING * and dereferenced 0xff, crashing with a near-NULL + * access. The fixed code must reject the malformed parameter and return NULL. + */ +static int test_cmp_calc_protection_pbmac_bad_alg_param(void) +{ + unsigned char sec_insta[] = { 'i', 'n', 's', 't', 'a' }; + X509_ALGOR *alg = NULL; + + SETUP_TEST_FIXTURE(CMP_PROTECT_TEST_FIXTURE, set_up); + if (!TEST_true(OSSL_CMP_CTX_set1_secretValue(fixture->cmp_ctx, + sec_insta, sizeof(sec_insta))) + || !TEST_ptr(fixture->msg = load_pkimsg(ip_PBM_f, libctx)) + || !TEST_ptr(alg = X509_ALGOR_new()) + || !TEST_true(X509_ALGOR_set0(alg, OBJ_nid2obj(NID_id_PasswordBasedMAC), + V_ASN1_BOOLEAN, (void *)1))) { + X509_ALGOR_free(alg); + tear_down(fixture); + fixture = NULL; + } else { + X509_ALGOR_free(fixture->msg->header->protectionAlg); + fixture->msg->header->protectionAlg = alg; + } + EXECUTE_TEST(execute_calc_protection_fails_test, tear_down); + return result; +} static int execute_MSG_protect_test(CMP_PROTECT_TEST_FIXTURE *fixture) { return TEST_int_eq(fixture->expected, @@ -609,6 +641,7 @@ int setup_tests(void) ADD_TEST(test_cmp_calc_protection_pkey_Ed); #endif ADD_TEST(test_cmp_calc_protection_pbmac); + ADD_TEST(test_cmp_calc_protection_pbmac_bad_alg_param); ADD_TEST(test_MSG_protect_with_msg_sig_alg_protection_plus_rsa_key); ADD_TEST(test_MSG_protect_with_certificate_and_key); diff --git a/test/cmp_vfy_test.c b/test/cmp_vfy_test.c index ec7131a8613b8..5c7fc247e34de 100644 --- a/test/cmp_vfy_test.c +++ b/test/cmp_vfy_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2007-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright Nokia 2007-2019 * Copyright Siemens AG 2015-2019 * @@ -34,6 +34,10 @@ typedef struct test_fixture { OSSL_CMP_CTX *cmp_ctx; OSSL_CMP_MSG *msg; X509 *cert; + /* + * With execute_validate_msg_test(), this is the expected validated cert or NULL. + * With execute_validate_cert_path_test(), this is the target cert to be validated. + */ ossl_cmp_allow_unprotected_cb_t allow_unprotected_cb; int additional_arg; } CMP_VFY_TEST_FIXTURE; @@ -48,7 +52,7 @@ static void tear_down(CMP_VFY_TEST_FIXTURE *fixture) OPENSSL_free(fixture); } -static time_t test_time_valid = 0, test_time_after_expiration = 0; +static time_t test_time_valid = 0, test_time_after_expiration = 0; /* for Insta certs */ static CMP_VFY_TEST_FIXTURE *set_up(const char *const test_case_name) { @@ -68,6 +72,7 @@ static CMP_VFY_TEST_FIXTURE *set_up(const char *const test_case_name) X509_STORE_free(ts); return NULL; } + /* by default, set validation time relevant for Insta certs: */ X509_VERIFY_PARAM_set_time(X509_STORE_get0_param(ts), test_time_valid); X509_STORE_set_verify_cb(ts, X509_STORE_CTX_print_verify_cb); return fixture; @@ -75,11 +80,9 @@ static CMP_VFY_TEST_FIXTURE *set_up(const char *const test_case_name) static X509 *srvcert = NULL; static X509 *clcert = NULL; -/* chain */ -static X509 *endentity1 = NULL, *endentity2 = NULL, - *intermediate = NULL, *root = NULL; -/* INSTA chain */ -static X509 *insta_cert = NULL, *instaca_cert = NULL; +static X509 *endentity2 = NULL, *intermediate = NULL, *root = NULL; /* 3-level chain */ +static X509 *endentity1 = NULL; /* 2-level chain together with same root as before */ +static X509 *insta_cert = NULL, *instaca_cert = NULL; /* 2-level Insta chain */ static unsigned char rand_data[OSSL_CMP_TRANSACTIONID_LENGTH]; static OSSL_CMP_MSG *ir_unprotected, *ir_rmprotection, *error_protected; @@ -132,7 +135,7 @@ static int test_verify_popo_bad(void) } #endif -/* indirectly checks also OSSL_CMP_validate_msg() */ +/* indirectly checks also OSSL_CMP_validate_msg(), uses only Insta or self-signed EE certs */ static int execute_validate_msg_test(CMP_VFY_TEST_FIXTURE *fixture) { int res = TEST_int_eq(fixture->expected, @@ -143,17 +146,6 @@ static int execute_validate_msg_test(CMP_VFY_TEST_FIXTURE *fixture) return res && (!fixture->expected || TEST_ptr_eq(validated, fixture->cert)); } -static int execute_validate_cert_path_test(CMP_VFY_TEST_FIXTURE *fixture) -{ - X509_STORE *ts = OSSL_CMP_CTX_get0_trusted(fixture->cmp_ctx); - int res = TEST_int_eq(fixture->expected, - OSSL_CMP_validate_cert_path(fixture->cmp_ctx, - ts, fixture->cert)); - - OSSL_CMP_CTX_print_errors(fixture->cmp_ctx); - return res; -} - static int test_validate_msg_mac_alg_protection(int miss, int wrong) { SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); @@ -220,6 +212,8 @@ static int add_untrusted(OSSL_CMP_CTX *ctx, X509 *cert) X509_ADD_FLAG_UP_REF); } +/* Message validation tests using self-signed certs for signature-based protection */ + static int test_validate_msg_signature_partial_chain(int expired) { X509_STORE *ts; @@ -299,6 +293,33 @@ static int test_validate_msg_signature_sender_cert_srvcert(void) return test_validate_msg_signature_srvcert(0, 0, 0); } +static int test_validate_msg_with_sender(const X509_NAME *name, int expected) +{ + SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); + fixture->cert = srvcert; + fixture->expected = expected; + if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_f, libctx)) + || !TEST_true(OSSL_CMP_CTX_set1_expected_sender(fixture->cmp_ctx, name)) + || !TEST_true(OSSL_CMP_CTX_set1_srvCert(fixture->cmp_ctx, srvcert))) { + tear_down(fixture); + fixture = NULL; + } + EXECUTE_TEST(execute_validate_msg_test, tear_down); + return result; +} + +static int test_validate_msg_signature_expected_sender(void) +{ + return test_validate_msg_with_sender(X509_get_subject_name(srvcert), 1); +} + +static int test_validate_msg_signature_unexpected_sender(void) +{ + return test_validate_msg_with_sender(X509_get_subject_name(root), 0); +} + +/* Message validation tests using Insta or other certs for signature-based protection */ + static int test_validate_msg_signature_sender_cert_untrusted(void) { SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); @@ -358,31 +379,6 @@ static int test_validate_msg_signature_sender_cert_absent(void) } #endif -static int test_validate_with_sender(const X509_NAME *name, int expected) -{ - SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - fixture->cert = srvcert; - fixture->expected = expected; - if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_f, libctx)) - || !TEST_true(OSSL_CMP_CTX_set1_expected_sender(fixture->cmp_ctx, name)) - || !TEST_true(OSSL_CMP_CTX_set1_srvCert(fixture->cmp_ctx, srvcert))) { - tear_down(fixture); - fixture = NULL; - } - EXECUTE_TEST(execute_validate_msg_test, tear_down); - return result; -} - -static int test_validate_msg_signature_expected_sender(void) -{ - return test_validate_with_sender(X509_get_subject_name(srvcert), 1); -} - -static int test_validate_msg_signature_unexpected_sender(void) -{ - return test_validate_with_sender(X509_get_subject_name(root), 0); -} - #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION static int test_validate_msg_unprotected_request(void) { @@ -397,48 +393,6 @@ static int test_validate_msg_unprotected_request(void) } #endif -static void setup_path(CMP_VFY_TEST_FIXTURE **fixture, X509 *wrong, int expired) -{ - (*fixture)->cert = endentity2; - (*fixture)->expected = wrong == NULL && !expired; - if (expired) { - X509_STORE *ts = OSSL_CMP_CTX_get0_trusted((*fixture)->cmp_ctx); - X509_VERIFY_PARAM *vpm = X509_STORE_get0_param(ts); - - X509_VERIFY_PARAM_set_time(vpm, test_time_after_expiration); - } - if (!add_trusted((*fixture)->cmp_ctx, wrong == NULL ? root : wrong) - || !add_untrusted((*fixture)->cmp_ctx, endentity1) - || !add_untrusted((*fixture)->cmp_ctx, intermediate)) { - tear_down((*fixture)); - (*fixture) = NULL; - } -} - -static int test_validate_cert_path_ok(void) -{ - SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_path(&fixture, NULL, 0); - EXECUTE_TEST(execute_validate_cert_path_test, tear_down); - return result; -} - -static int test_validate_cert_path_wrong_anchor(void) -{ - SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_path(&fixture, srvcert /* wrong/non-root cert */, 0); - EXECUTE_TEST(execute_validate_cert_path_test, tear_down); - return result; -} - -static int test_validate_cert_path_expired(void) -{ - SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); - setup_path(&fixture, NULL, 1); - EXECUTE_TEST(execute_validate_cert_path_test, tear_down); - return result; -} - static int execute_msg_check_test(CMP_VFY_TEST_FIXTURE *fixture) { const OSSL_CMP_PKIHEADER *hdr = OSSL_CMP_MSG_get0_header(fixture->msg); @@ -595,6 +549,123 @@ static int test_msg_check_recipient_nonce_error(void) return result; } +/* Regression test for CVE-2026-63073, uses self-signed cert for signature-based protection */ + +static int execute_msg_check_update_malicious_sender(CMP_VFY_TEST_FIXTURE *fixture) +{ + const char *data = NULL; + unsigned long err; + + if (!TEST_int_eq(ossl_cmp_msg_check_update(fixture->cmp_ctx, fixture->msg, NULL, 0), 0) + || !TEST_int_ne((err = ERR_peek_last_error_all(NULL, NULL, NULL, &data, NULL)), 0) + || !TEST_int_eq(ERR_GET_LIB(err), ERR_LIB_CMP) + || !TEST_int_eq(ERR_GET_REASON(err), CMP_R_UNEXPECTED_SENDER) + || !TEST_ptr(data) + || !TEST_str_eq(data, "/CN=%n")) + return 0; + return 1; +} + +static int test_msg_check_update_malicious_sender(void) +{ + OSSL_CMP_PKIHEADER *hdr; + X509_NAME *expected = X509_NAME_new(); + X509_NAME *actual = X509_NAME_new(); + + if (expected == NULL || actual == NULL) { + X509_NAME_free(expected); + X509_NAME_free(actual); + return 0; + } + + SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); + if (!TEST_ptr(fixture->msg = load_pkimsg(ir_protected_f, libctx)) + || !TEST_ptr(hdr = OSSL_CMP_MSG_get0_header(fixture->msg)) + || !TEST_int_eq(X509_NAME_add_entry_by_txt(expected, "CN", MBSTRING_ASC, + (unsigned char *)"%n", -1, -1, 0), + 1) + || !TEST_int_eq(X509_NAME_add_entry_by_txt(actual, "CN", MBSTRING_ASC, + (unsigned char *)"actual", -1, -1, 0), + 1) + || !TEST_int_eq(ossl_cmp_hdr_set1_sender(hdr, expected), 1) + || !TEST_int_eq(OSSL_CMP_CTX_set1_expected_sender(fixture->cmp_ctx, actual), 1)) { + X509_NAME_free(expected); + X509_NAME_free(actual); + tear_down(fixture); + return 0; + } + EXECUTE_TEST(execute_msg_check_update_malicious_sender, tear_down); + X509_NAME_free(expected); + X509_NAME_free(actual); + return result; +} + +/* + * The functions below use the normal OpenSSL test certs from test/certs/, + * forming a 2-level and mostly 3-level chains, + * all of which are kept valid (for tests using the current time). + */ + +static void setup_path(CMP_VFY_TEST_FIXTURE **fixture, X509 *wrong, int not_yet_valid) +{ + X509_STORE *ts = OSSL_CMP_CTX_get0_trusted((*fixture)->cmp_ctx); + X509_VERIFY_PARAM *vpm = X509_STORE_get0_param(ts); + + X509_VERIFY_PARAM_set_time(vpm, not_yet_valid ? 0 /* January 1st, 1970 */ + : time(NULL) /* override default validation time (set for Insta certs) by current time */); + (*fixture)->cert = endentity2; + (*fixture)->expected = wrong == NULL && !not_yet_valid; + if (!add_trusted((*fixture)->cmp_ctx, wrong == NULL ? root : wrong) + || !add_untrusted((*fixture)->cmp_ctx, endentity1) + || !add_untrusted((*fixture)->cmp_ctx, intermediate)) { + tear_down((*fixture)); + (*fixture) = NULL; + } +} + +static int execute_validate_cert_path_test(CMP_VFY_TEST_FIXTURE *fixture) +{ + X509_STORE *ts = OSSL_CMP_CTX_get0_trusted(fixture->cmp_ctx); + int res = TEST_int_eq(fixture->expected, + OSSL_CMP_validate_cert_path(fixture->cmp_ctx, ts, fixture->cert)); + + OSSL_CMP_CTX_print_errors(fixture->cmp_ctx); + return res; +} + +static int test_validate_cert_path_2_level_ok(void) +{ + SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); + setup_path(&fixture, NULL, 0); + fixture->cert = endentity1; + EXECUTE_TEST(execute_validate_cert_path_test, tear_down); + return result; +} + +static int test_validate_cert_path_ok(void) +{ + SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); + setup_path(&fixture, NULL, 0); + EXECUTE_TEST(execute_validate_cert_path_test, tear_down); + return result; +} + +static int test_validate_cert_path_wrong_anchor(void) +{ + SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); + setup_path(&fixture, srvcert /* wrong/non-root cert */, 0); + EXECUTE_TEST(execute_validate_cert_path_test, tear_down); + return result; +} + +static int test_validate_cert_path_not_yet_valid(void) +{ + SETUP_TEST_FIXTURE(CMP_VFY_TEST_FIXTURE, set_up); + setup_path(&fixture, NULL, 1); + EXECUTE_TEST(execute_validate_cert_path_test, tear_down); + return result; +} + void cleanup_tests(void) { X509_free(srvcert); @@ -633,8 +704,8 @@ int setup_tests(void) ts.tm_year = 2018 - 1900; /* 2018 */ ts.tm_mon = 1; /* February */ ts.tm_mday = 18; /* 18th */ - test_time_valid = mktime(&ts); /* February 18th 2018 */ - ts.tm_year += 10; /* February 18th 2028 */ + test_time_valid = mktime(&ts); /* February 18th 2018, within validity of insta_cert */ + ts.tm_year += 10; /* February 18th 2028, past validity of instaca_cert */ test_time_after_expiration = mktime(&ts); if (!test_skip_common_options()) { @@ -665,7 +736,7 @@ int setup_tests(void) if (!test_arg_libctx(&libctx, &default_null_provider, &provider, 15, USAGE)) return 0; - /* Load certificates for cert chain */ + /* Load certificates for 2-level and mixed 3-level chains */ if (!TEST_ptr(endentity1 = load_cert_pem(endentity1_f, libctx)) || !TEST_ptr(endentity2 = load_cert_pem(endentity2_f, libctx)) || !TEST_ptr(root = load_cert_pem(root_f, NULL)) @@ -687,11 +758,13 @@ int setup_tests(void) || !TEST_ptr(error_protected = load_pkimsg(error_protected_f, libctx))) goto err; - /* Message validation tests */ + /* CRMF proof-of-possession self-signature tests */ ADD_TEST(test_verify_popo); #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION ADD_TEST(test_verify_popo_bad); #endif + + /* Message validation tests using self-signed certs for signature-based protection */ ADD_TEST(test_validate_msg_signature_trusted_ok); #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION ADD_TEST(test_validate_msg_signature_trusted_expired); @@ -702,15 +775,16 @@ int setup_tests(void) ADD_TEST(test_validate_msg_signature_bad); #endif ADD_TEST(test_validate_msg_signature_sender_cert_srvcert); + ADD_TEST(test_validate_msg_signature_expected_sender); + ADD_TEST(test_validate_msg_signature_unexpected_sender); + ADD_TEST(test_msg_check_update_malicious_sender); + + /* Message validation tests using Insta or other certs for signature-based protection */ ADD_TEST(test_validate_msg_signature_sender_cert_untrusted); ADD_TEST(test_validate_msg_signature_sender_cert_trusted); ADD_TEST(test_validate_msg_signature_sender_cert_extracert); #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION ADD_TEST(test_validate_msg_signature_sender_cert_absent); -#endif - ADD_TEST(test_validate_msg_signature_expected_sender); - ADD_TEST(test_validate_msg_signature_unexpected_sender); -#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION ADD_TEST(test_validate_msg_unprotected_request); #endif ADD_TEST(test_validate_msg_mac_alg_protection_ok); @@ -720,11 +794,6 @@ int setup_tests(void) ADD_TEST(test_validate_msg_mac_alg_protection_bad); #endif - /* Cert path validation tests */ - ADD_TEST(test_validate_cert_path_ok); - ADD_TEST(test_validate_cert_path_expired); - ADD_TEST(test_validate_cert_path_wrong_anchor); - #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION ADD_TEST(test_msg_check_no_protection_no_cb); ADD_TEST(test_msg_check_no_protection_restrictive_cb); @@ -741,6 +810,12 @@ int setup_tests(void) #endif ADD_TEST(test_msg_check_recipient_nonce_error); + /* Cert path validation tests, using normal OpenSSL test certs */ + ADD_TEST(test_validate_cert_path_2_level_ok); + ADD_TEST(test_validate_cert_path_ok); + ADD_TEST(test_validate_cert_path_not_yet_valid); + ADD_TEST(test_validate_cert_path_wrong_anchor); + return 1; err: diff --git a/test/cmsapitest.c b/test/cmsapitest.c index e583b33f2c7e2..ac34f7ef9e480 100644 --- a/test/cmsapitest.c +++ b/test/cmsapitest.c @@ -19,9 +19,15 @@ static X509 *cert = NULL; static EVP_PKEY *privkey = NULL; +static X509 *ed448_cert = NULL; +static EVP_PKEY *ed448_privkey = NULL; +static X509 *cert2 = NULL; +static EVP_PKEY *privkey2 = NULL; static char *derin = NULL; static char *too_long_iv_cms_in = NULL; static char *pwri_kek_oob_der_in = NULL; +static char *pwri_kek_no_iv_in = NULL; +static char *ec_recip_in = NULL; /* * This is our bad cms data, it contains an AuthEnvelopedData field @@ -275,6 +281,89 @@ static int test_encrypt_decrypt_aes_256_gcm(void) return test_encrypt_decrypt(EVP_aes_256_gcm()); } +static int smimecap_has_nid(STACK_OF(X509_ALGOR) *smcap, int nid) +{ + int i; + + for (i = 0; i < sk_X509_ALGOR_num(smcap); i++) { + X509_ALGOR *alg = sk_X509_ALGOR_value(smcap, i); + if (OBJ_obj2nid(alg->algorithm) == nid) + return 1; + } + return 0; +} + +static int test_CMS_add_standard_smimecap_ex(void) +{ + STACK_OF(X509_ALGOR) *smcap = NULL; + int ret = 0; + + if (!TEST_true(CMS_add_standard_smimecap_ex(&smcap, NULL, NULL)) + || !TEST_int_eq(ERR_peek_error(), 0)) + goto end; + + /* AES ciphers must be present with the default provider */ + if (!TEST_true(smimecap_has_nid(smcap, NID_aes_256_cbc)) + || !TEST_true(smimecap_has_nid(smcap, NID_aes_192_cbc)) + || !TEST_true(smimecap_has_nid(smcap, NID_aes_128_cbc))) + goto end; + + /* RC2, DES, and GOST must NOT be present with just the default provider */ + if (!TEST_false(smimecap_has_nid(smcap, NID_rc2_cbc)) + || !TEST_false(smimecap_has_nid(smcap, NID_des_cbc)) + || !TEST_false(smimecap_has_nid(smcap, NID_id_Gost28147_89))) + goto end; + + ret = 1; +end: + sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); + return ret; +} + +static int test_decrypt_with_wrong_key(void) +{ + int testresult = 0; + STACK_OF(X509) *certstack = sk_X509_new_null(); + const char *msg = "Hello world"; + BIO *msgbio = BIO_new_mem_buf(msg, (int)strlen(msg)); + BIO *outmsgbio; + CMS_ContentInfo *content = NULL; + BIO *contentbio = NULL; + const EVP_CIPHER *cipher = EVP_aes_128_cbc(); + + if (!TEST_ptr(certstack) || !TEST_ptr(msgbio)) + goto end; + + if (!TEST_int_gt(sk_X509_push(certstack, cert), 0)) + goto end; + + content = CMS_encrypt(certstack, msgbio, cipher, 0); + if (!TEST_ptr(content)) + goto end; + + for (int i = 0; i < 1000; ++i) { + outmsgbio = BIO_new(BIO_s_mem()); + if (!TEST_false(CMS_decrypt(content, privkey2, cert, NULL, outmsgbio, + 0) + == 1)) { + BIO_free(outmsgbio); + goto end; + } + BIO_free(outmsgbio); + } + + ERR_clear_error(); + + testresult = 1; +end: + BIO_free(contentbio); + sk_X509_free(certstack); + BIO_free(msgbio); + CMS_ContentInfo_free(content); + + return testresult; +} + static int test_CMS_add1_cert(void) { CMS_ContentInfo *cms = NULL; @@ -288,6 +377,81 @@ static int test_CMS_add1_cert(void) return ret; } +static int test_CMS_SignerInfo_verify_sigalg_oid(void) +{ + static const char msg[] = "Hello World!\r\n"; + BIO *msgbio = NULL; + CMS_ContentInfo *cms = NULL; + CMS_SignerInfo *si; + X509_ALGOR *dalg = NULL; + int ret = 0; + + if (!TEST_ptr(msgbio = BIO_new_mem_buf(msg, sizeof(msg) - 1)) + || !TEST_ptr(cms = CMS_sign(NULL, NULL, NULL, NULL, CMS_PARTIAL)) + || !TEST_ptr(si = CMS_add1_signer(cms, cert, privkey, EVP_sha256(), 0)) + || !TEST_true(CMS_final(cms, msgbio, NULL, 0))) + goto end; + + if (!TEST_int_gt(CMS_SignerInfo_verify(si), 0)) + goto end; + + /* A signature algorithm OID as digestAlgorithm must not verify */ + CMS_SignerInfo_get0_algs(si, NULL, NULL, &dalg, NULL); + if (!TEST_true(X509_ALGOR_set0(dalg, + OBJ_nid2obj(NID_sha256WithRSAEncryption), + V_ASN1_UNDEF, NULL)) + || !TEST_int_le(CMS_SignerInfo_verify(si), 0)) + goto end; + + ret = 1; +end: + ERR_clear_error(); + CMS_ContentInfo_free(cms); + BIO_free(msgbio); + return ret; +} + +static int test_CMS_add1_signer_ed448(const EVP_MD *md, unsigned int flags, + int expect_success) +{ + CMS_ContentInfo *cms = NULL; + CMS_SignerInfo *si = NULL; + int ret = 0; + + if (!TEST_ptr(cms = CMS_ContentInfo_new())) + goto end; + + si = CMS_add1_signer(cms, ed448_cert, ed448_privkey, md, flags); + if (expect_success) { + if (!TEST_ptr(si)) + goto end; + } else if (!TEST_ptr_null(si)) { + goto end; + } + + ret = 1; +end: + if (!expect_success && ret) + ERR_clear_error(); + CMS_ContentInfo_free(cms); + return ret; +} + +static int test_CMS_add1_signer_ed448_signed_attrs(void) +{ + return test_CMS_add1_signer_ed448(NULL, 0, 0); +} + +static int test_CMS_add1_signer_ed448_signed_attrs_md(void) +{ + return test_CMS_add1_signer_ed448(EVP_shake256(), 0, 0); +} + +static int test_CMS_add1_signer_ed448_noattr(void) +{ + return test_CMS_add1_signer_ed448(NULL, CMS_NOATTR, 1); +} + static int test_d2i_CMS_bio_NULL(void) { BIO *bio, *content = NULL; @@ -739,12 +903,140 @@ static int test_pwri_kek_unwrap_short_encrypted_key(void) return ret; } -OPT_TEST_DECLARE_USAGE("certfile privkeyfile derfile tooLongIVpem pwriKekOobDer\n") +static int test_pwri_kek_unwrap_no_iv_key(void) +{ + BIO *in = NULL; + CMS_ContentInfo *cms = NULL; + unsigned long err = 0; + int ret = 0; + + if (!TEST_ptr(in = BIO_new_file(pwri_kek_no_iv_in, "rb")) + || !TEST_ptr(cms = d2i_CMS_bio(in, NULL))) + goto end; + + /* + * Due to the missing IV, the unwrap must fail with + * CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR. + */ + if (!TEST_false(CMS_decrypt_set1_password(cms, + (unsigned char *)"password", -1))) + goto end; + + err = ERR_peek_last_error(); + if (!TEST_int_eq(ERR_GET_LIB(err), ERR_LIB_CMS) + || !TEST_int_eq(ERR_GET_REASON(err), + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR)) + goto end; + + ERR_clear_error(); + ret = 1; +end: + CMS_ContentInfo_free(cms); + BIO_free(in); + return ret; +} + +#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_X963KDF) +/* + * Regression test for CVE-2026-63072: an 8-byte out-of-bounds heap write + * reachable through CMS_decrypt() when a KeyAgreeRecipientInfo names an + * id-aesNNN-wrap-pad key-wrap OID. CMS sizes the unwrap output buffer from + * the cipher's length query (inlen - 8), but AES-WRAP-PAD unwrap cleanses + * inlen bytes of it on every RFC 5649 integrity-failure path. + * + * We build a valid ECDH KARI message (which uses non-padded id-aes256-wrap), + * flip the single OID byte an attacker would flip on the wire to turn it into + * id-aes256-wrap-pad (key length unchanged), and decrypt with the matching + * private key. The unwrap must fail its integrity check without writing past + * the CMS-allocated buffer; CMS_decrypt() must fail cleanly. Under a + * memory-checking build (e.g. valgrind) the overflow is flagged directly. + */ +static int test_kari_wrap_pad_unwrap_overflow(void) +{ + /* DER encoding of the id-aes256-wrap OID (2.16.840.1.101.3.4.1.45). */ + static const unsigned char aes256_wrap_oid[] = { + 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2d + }; + int ret = 0; + X509 *eccert = NULL; + EVP_PKEY *eckey = NULL; + BIO *certbio = NULL, *keybio = NULL, *msgbio = NULL, *outbio = NULL; + STACK_OF(X509) *recips = NULL; + CMS_ContentInfo *cms = NULL, *cms2 = NULL; + unsigned char *der = NULL; + const unsigned char *p; + int derlen, i, patched = 0; + const char *msg = "secret content for kari"; + + if ((certbio = BIO_new_file(ec_recip_in, "r")) == NULL + || PEM_read_bio_X509(certbio, &eccert, NULL, NULL) == NULL + || (keybio = BIO_new_file(ec_recip_in, "r")) == NULL + || PEM_read_bio_PrivateKey(keybio, &eckey, NULL, NULL) == NULL) { + goto end; + } + + if (!TEST_ptr(recips = sk_X509_new_null()) + || !TEST_int_gt(sk_X509_push(recips, eccert), 0)) + goto end; + + /* Build a normal ECDH KARI message; it uses non-padded id-aes256-wrap. */ + if (!TEST_ptr(msgbio = BIO_new_mem_buf(msg, (int)strlen(msg))) + || !TEST_ptr(cms = CMS_encrypt(recips, msgbio, EVP_aes_256_cbc(), + CMS_BINARY))) + goto end; + + if (!TEST_int_gt(derlen = i2d_CMS_ContentInfo(cms, &der), 0)) + goto end; + + /* Swap id-aes256-wrap -> id-aes256-wrap-pad (0x2d -> 0x30). */ + for (i = 0; i + (int)sizeof(aes256_wrap_oid) <= derlen; i++) { + if (memcmp(der + i, aes256_wrap_oid, sizeof(aes256_wrap_oid)) == 0) { + der[i + sizeof(aes256_wrap_oid) - 1] = 0x30; + patched = 1; + break; + } + } + if (!TEST_true(patched)) + goto end; + + p = der; + if (!TEST_ptr(cms2 = d2i_CMS_ContentInfo(NULL, &p, derlen))) + goto end; + + /* + * The wrap-pad unwrap fails the AIV check; with the fix it does so without + * writing past the CMS-allocated buffer. CMS_decrypt() must fail cleanly. + */ + if (!TEST_ptr(outbio = BIO_new(BIO_s_mem())) + || !TEST_false(CMS_decrypt(cms2, eckey, eccert, NULL, outbio, 0))) + goto end; + + ret = 1; +end: + ERR_clear_error(); + OPENSSL_free(der); + sk_X509_free(recips); + CMS_ContentInfo_free(cms); + CMS_ContentInfo_free(cms2); + BIO_free(certbio); + BIO_free(keybio); + BIO_free(msgbio); + BIO_free(outbio); + X509_free(eccert); + EVP_PKEY_free(eckey); + return ret; +} +#endif + +OPT_TEST_DECLARE_USAGE("certfile privkeyfile derfile tooLongIVpem pwriKekOobDer" + " pwriKekNoIv ecrecip certfile2 privkeyfile2" + " [ed448certfile ed448privkeyfile]\n") int setup_tests(void) { char *certin = NULL, *privkeyin = NULL; - BIO *certbio = NULL, *privkeybio = NULL; + char *ed448_certin = NULL, *ed448_privkeyin = NULL; + char *certin2 = NULL, *privkeyin2 = NULL; if (!test_skip_common_options()) { TEST_error("Error parsing test options\n"); @@ -755,31 +1047,41 @@ int setup_tests(void) || !TEST_ptr(privkeyin = test_get_argument(1)) || !TEST_ptr(derin = test_get_argument(2)) || !TEST_ptr(too_long_iv_cms_in = test_get_argument(3)) - || !TEST_ptr(pwri_kek_oob_der_in = test_get_argument(4))) - return 0; - - certbio = BIO_new_file(certin, "r"); - if (!TEST_ptr(certbio)) - return 0; - if (!TEST_true(PEM_read_bio_X509(certbio, &cert, NULL, NULL))) { - BIO_free(certbio); + || !TEST_ptr(pwri_kek_oob_der_in = test_get_argument(4)) + || !TEST_ptr(pwri_kek_no_iv_in = test_get_argument(5)) + || !TEST_ptr(ec_recip_in = test_get_argument(6)) + || !TEST_ptr(certin2 = test_get_argument(7)) + || !TEST_ptr(privkeyin2 = test_get_argument(8))) return 0; - } - BIO_free(certbio); - privkeybio = BIO_new_file(privkeyin, "r"); - if (!TEST_ptr(privkeybio)) { + if (!TEST_ptr(cert = load_cert_pem(certin, NULL)) + || !TEST_ptr(privkey = load_pkey_pem(privkeyin, NULL)) + || !TEST_ptr(cert2 = load_cert_pem(certin2, NULL)) + || !TEST_ptr(privkey2 = load_pkey_pem(privkeyin2, NULL))) { X509_free(cert); cert = NULL; + EVP_PKEY_free(privkey); + privkey = NULL; + X509_free(cert2); + cert2 = NULL; + EVP_PKEY_free(privkey2); + privkey2 = NULL; return 0; } - if (!TEST_true(PEM_read_bio_PrivateKey(privkeybio, &privkey, NULL, NULL))) { - BIO_free(privkeybio); - X509_free(cert); - cert = NULL; - return 0; + + if (test_get_argument_count() >= 11) { + ed448_certin = test_get_argument(9); + ed448_privkeyin = test_get_argument(10); + + if (!TEST_ptr(ed448_cert = load_cert_pem(ed448_certin, NULL)) + || !TEST_ptr(ed448_privkey = load_pkey_pem(ed448_privkeyin, NULL))) { + X509_free(ed448_cert); + ed448_cert = NULL; + EVP_PKEY_free(ed448_privkey); + ed448_privkey = NULL; + return 0; + } } - BIO_free(privkeybio); ADD_TEST(test_encrypt_decrypt_aes_cbc); ADD_TEST(test_encrypt_decrypt_aes_128_gcm); @@ -788,7 +1090,10 @@ int setup_tests(void) ADD_TEST(test_non_aead_on_auth_envelope_enc); ADD_TEST(test_non_aead_on_auth_envelope_dec); ADD_TEST(test_short_mac_on_auth_envelope_data); + ADD_TEST(test_CMS_add_standard_smimecap_ex); + ADD_TEST(test_decrypt_with_wrong_key); ADD_TEST(test_CMS_add1_cert); + ADD_TEST(test_CMS_SignerInfo_verify_sigalg_oid); ADD_TEST(test_d2i_CMS_bio_NULL); ADD_TEST(test_CMS_set1_key_mem_leak); ADD_TEST(test_encrypted_data); @@ -796,6 +1101,16 @@ int setup_tests(void) ADD_ALL_TESTS(test_d2i_CMS_decode, 2); ADD_TEST(test_cms_aesgcm_iv_too_long); ADD_TEST(test_pwri_kek_unwrap_short_encrypted_key); + ADD_TEST(test_pwri_kek_unwrap_no_iv_key); + if (ed448_cert != NULL && ed448_privkey != NULL) { + ADD_TEST(test_CMS_add1_signer_ed448_signed_attrs); + ADD_TEST(test_CMS_add1_signer_ed448_signed_attrs_md); + ADD_TEST(test_CMS_add1_signer_ed448_noattr); + } + +#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_X963KDF) + ADD_TEST(test_kari_wrap_pad_unwrap_overflow); +#endif return 1; } @@ -803,4 +1118,8 @@ void cleanup_tests(void) { X509_free(cert); EVP_PKEY_free(privkey); + X509_free(ed448_cert); + EVP_PKEY_free(ed448_privkey); + X509_free(cert2); + EVP_PKEY_free(privkey2); } diff --git a/test/composite_sig.inc b/test/composite_sig.inc new file mode 100644 index 0000000000000..72ccf6e7f6ab9 --- /dev/null +++ b/test/composite_sig.inc @@ -0,0 +1,2626 @@ +/* + * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may + * not use this file except in compliance with the License. You can + * obtain a copy in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Deterministic composite-signature test vectors. + * Generated by this implementation + * Message : "OpenSSL composite signature deterministic test vector\0" + * Entropy : 32 zero bytes + * Excluded : RSA-PSS (random salt), ECDSA (random k). + */ + +static const uint8_t composite_test_msg[] = + "OpenSSL composite signature deterministic test vector"; + +/* --- ML-DSA-44-RSA2048-PKCS15-SHA256 --- */ +static const uint8_t composite44_rsa2048pkcs15_priv[] = { + 0xdf, 0x7e, 0x6c, 0x24, 0xb8, 0xf1, 0xef, 0xdc, 0xcc, 0x55, 0x5d, 0x42, 0xc5, 0x1e, 0x6d, 0x68, + 0xea, 0x2d, 0x04, 0x8f, 0xaf, 0xcd, 0xf0, 0xee, 0x16, 0xd2, 0x29, 0x97, 0x68, 0xbd, 0xa4, 0x74, + 0x30, 0x82, 0x04, 0xa5, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xcf, 0x35, 0x54, 0x5f, + 0x18, 0x6b, 0x62, 0xe0, 0xcc, 0x0e, 0x0c, 0xd7, 0x1e, 0x09, 0x02, 0x97, 0xe0, 0xac, 0x87, 0xb0, + 0x15, 0x97, 0x7f, 0x79, 0x0f, 0xab, 0x44, 0xe8, 0x05, 0xcd, 0xfa, 0x8c, 0x77, 0x89, 0x22, 0x81, + 0x02, 0xc7, 0xd3, 0x01, 0x9c, 0x68, 0xe3, 0x49, 0x68, 0x51, 0x08, 0x35, 0xd0, 0x96, 0x29, 0x00, + 0x8a, 0xeb, 0xb1, 0x41, 0x40, 0x37, 0x37, 0x11, 0x92, 0x56, 0x44, 0x90, 0xd4, 0xaf, 0xef, 0xf1, + 0x71, 0x7d, 0xd7, 0x0a, 0x7d, 0x1c, 0xe1, 0x17, 0x42, 0x7d, 0xda, 0x84, 0x4b, 0x42, 0xcc, 0xa1, + 0x67, 0xa3, 0x01, 0xb2, 0x94, 0xdf, 0x65, 0xfa, 0xbe, 0xf5, 0xfa, 0x38, 0x37, 0x61, 0xc1, 0x2e, + 0xa1, 0x49, 0xea, 0x65, 0x66, 0x66, 0x2d, 0x23, 0x92, 0x14, 0xee, 0x5a, 0xc3, 0xa3, 0xe2, 0x6d, + 0x93, 0x21, 0x16, 0xba, 0x61, 0x6e, 0xc6, 0x05, 0x2b, 0x2b, 0xb8, 0x7b, 0xec, 0x83, 0xfd, 0x44, + 0x5c, 0x21, 0x32, 0x7f, 0xab, 0x3d, 0x10, 0xa2, 0x4a, 0x42, 0xad, 0x1f, 0x6f, 0xc7, 0x8f, 0xd3, + 0x2a, 0x7a, 0xb2, 0x52, 0x52, 0x6d, 0x63, 0x96, 0x2c, 0x2f, 0x2e, 0x6d, 0xf1, 0xf9, 0xfc, 0x31, + 0x82, 0xb0, 0x9b, 0x03, 0x80, 0xa3, 0x59, 0x54, 0x58, 0xd9, 0x37, 0x30, 0x33, 0x54, 0x46, 0x14, + 0x79, 0x36, 0xfa, 0xe8, 0x30, 0x54, 0xc9, 0x2c, 0xa5, 0xd2, 0xc9, 0xac, 0xa4, 0xd2, 0x0b, 0xfb, + 0x72, 0xc4, 0xad, 0xb8, 0x7a, 0x11, 0xbe, 0x95, 0x41, 0xd7, 0x05, 0x1c, 0xe6, 0x95, 0x70, 0xfc, + 0xd3, 0xdb, 0x31, 0x23, 0x7b, 0x94, 0xa2, 0xc9, 0xee, 0x63, 0x55, 0x45, 0x4f, 0x9d, 0x23, 0x27, + 0x62, 0x08, 0x33, 0x67, 0xa0, 0x4f, 0x98, 0x1d, 0x54, 0xc9, 0xba, 0xa3, 0xfc, 0x1c, 0xdd, 0xee, + 0x1d, 0x79, 0xfe, 0x8f, 0xbd, 0x3a, 0x3e, 0xda, 0xbb, 0x13, 0x94, 0xa5, 0x02, 0x03, 0x01, 0x00, + 0x01, 0x02, 0x82, 0x01, 0x00, 0x12, 0x36, 0xb9, 0x1b, 0xa1, 0xd1, 0x20, 0xb0, 0x2b, 0x67, 0xa9, + 0xc3, 0xc8, 0x01, 0x59, 0x3f, 0xc1, 0xf1, 0x50, 0x7d, 0x0f, 0x2c, 0xd1, 0xb8, 0xf1, 0xc2, 0x67, + 0x8c, 0x70, 0xa4, 0x2e, 0x3b, 0xa6, 0x2f, 0x40, 0xff, 0xef, 0x9f, 0x62, 0x82, 0x1f, 0xfe, 0x4d, + 0x4a, 0x50, 0xd7, 0xdc, 0x9d, 0xa4, 0x5f, 0xea, 0xab, 0x40, 0x4a, 0xde, 0xfa, 0x22, 0x1b, 0xa8, + 0x64, 0xcc, 0x44, 0xf6, 0x82, 0x77, 0x9b, 0x9e, 0x7f, 0x0d, 0xef, 0x96, 0x95, 0x36, 0xb1, 0xb0, + 0xec, 0x83, 0x3c, 0xfe, 0x56, 0x06, 0x2a, 0x91, 0x43, 0xb7, 0xd1, 0x29, 0x8f, 0x49, 0xcc, 0x48, + 0x51, 0xcd, 0xf2, 0xdf, 0xc3, 0x8c, 0xc4, 0xb4, 0x3f, 0x35, 0xd0, 0xc2, 0x40, 0x97, 0x0b, 0x70, + 0xb8, 0xd1, 0x78, 0xb3, 0x09, 0xf9, 0xec, 0x00, 0x35, 0x8b, 0x0b, 0x0b, 0xcd, 0x26, 0xce, 0xde, + 0xab, 0xaa, 0x23, 0x8d, 0xf3, 0xf8, 0x00, 0xc7, 0x2d, 0x74, 0x58, 0x15, 0x18, 0xef, 0x3a, 0xdf, + 0xa6, 0xc1, 0x9e, 0x1d, 0xa1, 0x45, 0x1f, 0x86, 0xe0, 0xec, 0xcc, 0x85, 0xdd, 0xe0, 0xd6, 0x42, + 0x52, 0x63, 0x24, 0xf2, 0x00, 0x38, 0xb5, 0x09, 0xc7, 0x56, 0xd8, 0x36, 0x03, 0xa4, 0x6c, 0xcd, + 0xa5, 0x34, 0xb6, 0x1e, 0xa0, 0x96, 0x3c, 0xa5, 0x57, 0x18, 0xde, 0x91, 0xd8, 0xeb, 0x23, 0xd9, + 0x9a, 0xa7, 0xb5, 0x75, 0x82, 0xef, 0x80, 0x24, 0xfc, 0x32, 0xad, 0xea, 0x94, 0x0a, 0x51, 0xc4, + 0x21, 0x38, 0xa6, 0xa9, 0x28, 0xc2, 0x9e, 0x5c, 0xfd, 0xdf, 0x40, 0x93, 0xaf, 0xa2, 0x2d, 0x5b, + 0x08, 0x75, 0xb2, 0xfe, 0x04, 0xb0, 0x1d, 0x55, 0x9a, 0x7b, 0x61, 0x06, 0x0a, 0xa0, 0xe3, 0x13, + 0x63, 0x52, 0x4d, 0x5b, 0xd7, 0x7c, 0x66, 0x1d, 0xb2, 0xd8, 0x16, 0xb7, 0x3c, 0x0d, 0x2d, 0xe3, + 0x44, 0x62, 0xd8, 0x79, 0x01, 0x02, 0x81, 0x81, 0x00, 0xfe, 0xa0, 0xe8, 0x33, 0x8e, 0x05, 0x15, + 0x1a, 0x81, 0x8a, 0x74, 0xb0, 0xed, 0x9b, 0x1d, 0x7f, 0xdd, 0x9f, 0x0d, 0xd1, 0xba, 0xd7, 0x0a, + 0x70, 0xcc, 0xbf, 0x3e, 0xfe, 0xde, 0xa7, 0x90, 0xae, 0xc0, 0x75, 0xef, 0xe8, 0x9c, 0xd3, 0x76, + 0x6a, 0xef, 0x2c, 0x51, 0x0f, 0x5b, 0xf1, 0x6e, 0x42, 0x3d, 0xd2, 0xbc, 0xaf, 0x1e, 0x8b, 0x3e, + 0x1e, 0xfc, 0xf3, 0x62, 0x7a, 0x2f, 0x75, 0x74, 0x6b, 0x26, 0x90, 0x0a, 0xcd, 0xfa, 0xc4, 0xc5, + 0x0d, 0x43, 0x10, 0xcf, 0xce, 0x16, 0x02, 0x92, 0xbf, 0x71, 0x5d, 0x73, 0x4a, 0x3f, 0xf5, 0x22, + 0x3d, 0x9c, 0x31, 0xe6, 0x6d, 0xf6, 0x42, 0x3e, 0x35, 0xde, 0x7b, 0x8d, 0x29, 0x32, 0x8b, 0xb2, + 0x8b, 0x88, 0x2b, 0x06, 0x2e, 0x6d, 0x53, 0x42, 0x5a, 0x6f, 0xfb, 0xa2, 0x5e, 0x6e, 0x55, 0xea, + 0xea, 0x92, 0x16, 0x16, 0xc2, 0x7c, 0x49, 0xdb, 0x01, 0x02, 0x81, 0x81, 0x00, 0xd0, 0x53, 0x09, + 0x97, 0x13, 0x57, 0xf7, 0x16, 0x9a, 0x5e, 0x8c, 0x2e, 0xfc, 0x84, 0x66, 0x27, 0xf1, 0x21, 0xf6, + 0xd3, 0x6c, 0x4f, 0x06, 0xaf, 0x21, 0x7c, 0xb8, 0x57, 0xd2, 0xe0, 0x19, 0x25, 0x45, 0x58, 0x9c, + 0x1d, 0xad, 0x03, 0x71, 0xb9, 0xcc, 0xc8, 0x29, 0xbe, 0x14, 0x19, 0x5a, 0x2d, 0xe1, 0x02, 0x6a, + 0x9f, 0x59, 0x32, 0x6b, 0xdf, 0xf1, 0x58, 0x03, 0x85, 0x5a, 0xb5, 0x22, 0x4f, 0xc4, 0xc1, 0x96, + 0xaf, 0xf7, 0x77, 0x83, 0xe2, 0x44, 0x8e, 0x0f, 0xa1, 0x3d, 0xcf, 0x80, 0x11, 0x19, 0x94, 0xa9, + 0xb5, 0x8b, 0x55, 0xdb, 0x84, 0x7a, 0xf1, 0x95, 0xea, 0xba, 0xaf, 0x0f, 0xda, 0x6e, 0x8a, 0xa9, + 0x9c, 0x10, 0xd2, 0xcb, 0xb0, 0x0c, 0x33, 0xb6, 0x1f, 0x39, 0x05, 0x9c, 0x8b, 0x87, 0x31, 0x4d, + 0xd3, 0xcb, 0xbc, 0x0a, 0xe6, 0xaf, 0xa0, 0x6e, 0x84, 0x8f, 0x3a, 0x6d, 0xa5, 0x02, 0x81, 0x81, + 0x00, 0xb5, 0xca, 0x9f, 0xbd, 0x9f, 0x19, 0xd5, 0xd5, 0x54, 0xc3, 0x4b, 0x48, 0xbe, 0x7b, 0x4e, + 0x76, 0x69, 0xfe, 0x12, 0xd9, 0xb8, 0x31, 0xab, 0x8c, 0x99, 0x41, 0xb9, 0x72, 0x31, 0xf9, 0x24, + 0x7c, 0xff, 0x7f, 0xb4, 0x47, 0x39, 0x20, 0x68, 0x9d, 0x34, 0x21, 0x49, 0xc6, 0x53, 0x78, 0x6d, + 0xa5, 0xf1, 0x89, 0xb1, 0x98, 0xbd, 0x8f, 0xe0, 0x4c, 0x33, 0x80, 0x78, 0xc0, 0x8f, 0x7d, 0xa6, + 0x1e, 0x92, 0x2b, 0xa8, 0xeb, 0x22, 0xac, 0xb5, 0x9b, 0x20, 0x54, 0xb2, 0x68, 0x8a, 0xa2, 0x4f, + 0xaf, 0x4a, 0xfa, 0xd3, 0x43, 0x21, 0xa2, 0x9c, 0x4d, 0xac, 0x64, 0x9c, 0x05, 0xca, 0x19, 0xc5, + 0x5c, 0xa4, 0x79, 0x45, 0x71, 0x32, 0x5b, 0x36, 0xa0, 0x14, 0x19, 0xd3, 0x91, 0xf6, 0x0f, 0xc9, + 0x81, 0xd4, 0x0d, 0xae, 0x01, 0x09, 0x79, 0x61, 0xfd, 0x13, 0x4b, 0x9d, 0xf8, 0x40, 0xd0, 0x62, + 0x01, 0x02, 0x81, 0x81, 0x00, 0xcc, 0xc8, 0x83, 0xc9, 0xdd, 0xba, 0xff, 0xea, 0x59, 0x2f, 0x0d, + 0xf0, 0x76, 0x4c, 0x14, 0x3b, 0xb9, 0x3e, 0xe0, 0xea, 0x6e, 0x32, 0xb4, 0xe8, 0x5d, 0x2b, 0xc3, + 0xee, 0x99, 0x1d, 0xaf, 0xba, 0x42, 0x93, 0xdb, 0x4b, 0x14, 0xb3, 0x29, 0x0d, 0x32, 0xef, 0xa4, + 0x90, 0xf4, 0x23, 0x03, 0xd1, 0xcb, 0xb9, 0x5b, 0x64, 0x6f, 0x03, 0x30, 0xa5, 0xc0, 0x11, 0xfb, + 0xcc, 0x10, 0x21, 0xb4, 0xab, 0xe3, 0x47, 0x45, 0xc0, 0x8e, 0xac, 0x0e, 0x99, 0xd3, 0x38, 0x2e, + 0xc7, 0x1b, 0x02, 0xa9, 0xea, 0xa5, 0x51, 0xcd, 0x0d, 0xe7, 0xfd, 0x2b, 0x3f, 0xec, 0xb7, 0x24, + 0xde, 0xcc, 0x4a, 0xa0, 0x73, 0xe1, 0x6c, 0x2f, 0x54, 0x79, 0xf9, 0x2d, 0x3f, 0x4e, 0x8f, 0x5a, + 0xbd, 0x10, 0x89, 0xa2, 0x9c, 0x49, 0xf6, 0x3e, 0x82, 0x2f, 0x69, 0x16, 0xf2, 0x33, 0xbc, 0xaa, + 0x47, 0x66, 0xa0, 0x51, 0xfd, 0x02, 0x81, 0x81, 0x00, 0xdd, 0xcc, 0x9f, 0x76, 0xa9, 0x95, 0x2c, + 0x55, 0x83, 0xfe, 0xa6, 0x23, 0x04, 0x64, 0xe0, 0x4f, 0xc1, 0x3e, 0xe6, 0x35, 0x1a, 0x16, 0x71, + 0xf9, 0x9a, 0xb0, 0xff, 0x8a, 0x20, 0xd0, 0x9a, 0x23, 0xf3, 0x35, 0xf4, 0xd4, 0xb2, 0x5a, 0x25, + 0xc0, 0xf1, 0x46, 0x45, 0xa7, 0x25, 0x5a, 0x9f, 0x43, 0xd5, 0x8f, 0xe8, 0xd0, 0xd3, 0x50, 0x90, + 0x2a, 0x29, 0xa3, 0xac, 0x14, 0x8b, 0xc1, 0x90, 0x43, 0x82, 0x3e, 0xf9, 0xf2, 0xec, 0xc2, 0xe9, + 0xb6, 0x40, 0x04, 0x48, 0x6d, 0xf9, 0xda, 0x28, 0xdf, 0x92, 0x48, 0x13, 0x7b, 0xe9, 0x96, 0x5c, + 0xdb, 0x50, 0x71, 0x87, 0xe1, 0x9e, 0x4f, 0x0b, 0x38, 0x10, 0x08, 0x6e, 0x74, 0x7b, 0x74, 0x51, + 0x84, 0x2b, 0xf5, 0x0a, 0x37, 0x7b, 0x95, 0x2a, 0x5e, 0xe6, 0x1c, 0x94, 0xc5, 0xdd, 0xad, 0x66, + 0x14, 0x91, 0xaa, 0x1b, 0x00, 0x3e, 0xdd, 0x30, 0x2c +}; + +static const uint8_t composite44_rsa2048pkcs15_pub[] = { + 0xdd, 0x25, 0xe8, 0x80, 0x46, 0xd1, 0x6b, 0xc7, 0x1f, 0x61, 0xae, 0xf2, 0xfc, 0x26, 0x33, 0xd7, + 0xe1, 0x36, 0xb2, 0x3b, 0xfd, 0x8d, 0x36, 0x50, 0xc3, 0x73, 0xc2, 0xf5, 0x2b, 0xbc, 0x4e, 0xd4, + 0x6c, 0x76, 0x2b, 0xc3, 0xfd, 0x92, 0xbf, 0x10, 0x5c, 0x01, 0x78, 0x3b, 0x86, 0x48, 0x1c, 0xed, + 0x3a, 0x96, 0xd0, 0x03, 0x03, 0xb1, 0x95, 0x90, 0xe1, 0x5d, 0x4f, 0x99, 0x0e, 0x62, 0x9c, 0x32, + 0x4d, 0x46, 0x81, 0x43, 0x87, 0x4b, 0xfd, 0xf8, 0xe6, 0x9a, 0x9c, 0xd1, 0x08, 0x3f, 0x9d, 0xca, + 0xef, 0x98, 0x54, 0x3b, 0x77, 0x86, 0x49, 0xdc, 0x17, 0xa1, 0xa3, 0xc7, 0x50, 0x9d, 0x9e, 0x93, + 0xf1, 0x77, 0xa7, 0x3a, 0xd1, 0xc9, 0x25, 0x9c, 0x07, 0x34, 0x7d, 0xe4, 0xcd, 0x48, 0x70, 0xdb, + 0x35, 0xc1, 0x42, 0x67, 0xa0, 0xf2, 0x03, 0xcd, 0x4a, 0x25, 0xad, 0x4d, 0x24, 0x30, 0x66, 0xe8, + 0x3c, 0x71, 0xda, 0x4d, 0xf4, 0x01, 0x13, 0xd3, 0xe1, 0xe2, 0x75, 0x0a, 0x52, 0xdf, 0x5e, 0x54, + 0x50, 0xc5, 0xd4, 0x13, 0xc8, 0xec, 0x21, 0xf5, 0x9b, 0xe3, 0x82, 0x37, 0xde, 0x87, 0xa9, 0x77, + 0x4e, 0xdd, 0x58, 0xa5, 0x71, 0xb1, 0xc1, 0xbe, 0xcb, 0x10, 0x8a, 0x9d, 0x1c, 0x8e, 0x14, 0xab, + 0x6b, 0x74, 0x97, 0xeb, 0xd3, 0xa1, 0x14, 0xd5, 0x60, 0x2e, 0x39, 0xd7, 0xee, 0xde, 0xcd, 0x2a, + 0x1a, 0xfd, 0xa0, 0x39, 0xc6, 0xe9, 0x65, 0xa5, 0x8e, 0x32, 0x13, 0x41, 0xad, 0x70, 0x37, 0xfc, + 0x2d, 0xb2, 0xde, 0x4d, 0x50, 0xb2, 0x83, 0xdc, 0x04, 0xfc, 0x6d, 0x48, 0x3b, 0x64, 0x7d, 0x31, + 0xc3, 0x2f, 0xe0, 0xe9, 0x20, 0x2f, 0x25, 0x2d, 0x5c, 0x50, 0x52, 0x33, 0xb1, 0x12, 0x6a, 0xe9, + 0x06, 0xac, 0xed, 0x4e, 0x92, 0x5c, 0xc5, 0x53, 0x9a, 0x8c, 0xf3, 0x3b, 0x5c, 0xe3, 0xb4, 0x74, + 0x90, 0x8d, 0x3f, 0x92, 0x5f, 0xc8, 0xff, 0xa1, 0x02, 0xd4, 0x9d, 0x31, 0x10, 0x09, 0xf0, 0x80, + 0xad, 0xa7, 0xc8, 0xc1, 0x57, 0x3c, 0xe2, 0x7e, 0x02, 0x3f, 0x1d, 0x47, 0x99, 0x23, 0xe6, 0x55, + 0x44, 0x6a, 0xdd, 0xab, 0x9a, 0x9e, 0x25, 0xa0, 0xcf, 0xff, 0xb9, 0x15, 0xf2, 0x3d, 0x39, 0xbf, + 0xa6, 0x4b, 0xb2, 0x0b, 0xe3, 0xd1, 0xfd, 0xb6, 0x18, 0xb0, 0x8a, 0x08, 0xf8, 0x93, 0x8b, 0x1d, + 0xa1, 0x01, 0xb6, 0x77, 0x27, 0x1b, 0x37, 0x7a, 0xac, 0x21, 0x50, 0x2e, 0xe7, 0x05, 0x35, 0x37, + 0xf2, 0x73, 0x64, 0xa2, 0x47, 0x8c, 0xb4, 0xa5, 0x02, 0x7b, 0x1f, 0x2e, 0xb9, 0xe9, 0x51, 0x63, + 0x3a, 0xcd, 0x07, 0xd4, 0xf0, 0x8a, 0x15, 0x00, 0x97, 0x5c, 0x8b, 0x54, 0x01, 0x8a, 0x4e, 0xa1, + 0x30, 0x3f, 0x2a, 0x79, 0x05, 0xd3, 0xbe, 0xdb, 0x2f, 0x7e, 0x53, 0x26, 0x16, 0x54, 0xb4, 0x65, + 0xa7, 0x15, 0x91, 0x14, 0xba, 0x61, 0x3a, 0xf3, 0x43, 0x61, 0xaf, 0x8d, 0x07, 0x0b, 0x8a, 0x82, + 0x3a, 0x21, 0x1f, 0x35, 0x55, 0x9b, 0x81, 0x96, 0xfc, 0xd1, 0x0d, 0xd3, 0x3d, 0x5c, 0x92, 0x11, + 0xf0, 0x20, 0xae, 0x3e, 0x34, 0xd9, 0x2d, 0xcc, 0x77, 0x42, 0x56, 0x07, 0x23, 0xf6, 0x9b, 0xe7, + 0xf0, 0x4b, 0xc0, 0xea, 0xd9, 0x2d, 0xde, 0x52, 0x71, 0x77, 0x15, 0xb9, 0x41, 0x03, 0x4c, 0x33, + 0xdb, 0x2e, 0x76, 0x03, 0xd3, 0x69, 0x2c, 0x96, 0xf2, 0xf6, 0x1d, 0x4e, 0xfc, 0xd3, 0xb2, 0x7c, + 0x98, 0xd0, 0xda, 0x97, 0x58, 0xed, 0x8a, 0xd8, 0xe7, 0x42, 0xa1, 0x64, 0xe9, 0xb1, 0x02, 0x72, + 0xcf, 0xe8, 0x85, 0x02, 0xa1, 0x3a, 0x3d, 0xd6, 0xcd, 0xb7, 0x25, 0x63, 0xdc, 0x72, 0x5c, 0xcd, + 0x34, 0xb6, 0xcc, 0xef, 0x1f, 0x1a, 0x95, 0xe9, 0xf0, 0x0f, 0xc1, 0x78, 0xad, 0x58, 0x9a, 0xf5, + 0x14, 0x18, 0xa0, 0x47, 0x14, 0xe4, 0xe7, 0xdc, 0x8d, 0x4a, 0x07, 0xef, 0x88, 0x7d, 0x9b, 0x6d, + 0xbf, 0x49, 0x7f, 0x4c, 0xe0, 0xf5, 0xf1, 0x6a, 0x9e, 0x7c, 0x2e, 0xf7, 0x99, 0x9f, 0x64, 0x06, + 0xa1, 0x9d, 0xf6, 0xfb, 0x2e, 0xe8, 0xc0, 0x76, 0x27, 0xb0, 0xb3, 0x01, 0x21, 0x46, 0xf6, 0x91, + 0x0d, 0x09, 0x4f, 0x3c, 0x25, 0x65, 0x76, 0x01, 0xc1, 0x94, 0x79, 0x53, 0x1d, 0x6a, 0xed, 0xb7, + 0x1b, 0x3d, 0x3d, 0xa9, 0x8a, 0xf5, 0x3f, 0x8c, 0x6c, 0x50, 0x4f, 0x34, 0xba, 0xc8, 0xd7, 0x53, + 0x76, 0xf1, 0x18, 0x70, 0x96, 0xf7, 0xc3, 0xef, 0x6d, 0xba, 0x1d, 0x9f, 0x0e, 0xf4, 0x6a, 0xae, + 0x14, 0x27, 0xdc, 0x6e, 0xff, 0x90, 0x63, 0xbd, 0x2d, 0xac, 0x97, 0x0e, 0x04, 0x7f, 0x22, 0xf1, + 0x2a, 0x94, 0xd5, 0x1d, 0x25, 0x24, 0x53, 0x98, 0xd6, 0x01, 0x68, 0xa3, 0x9f, 0x25, 0xab, 0x8e, + 0xb2, 0x94, 0xb0, 0x56, 0x43, 0x98, 0x76, 0xb7, 0xfd, 0x50, 0xa2, 0xca, 0x47, 0xc8, 0x39, 0xbb, + 0x4e, 0x6b, 0x63, 0xc2, 0xbe, 0x6a, 0x1c, 0x65, 0x14, 0x25, 0x0b, 0x6d, 0x2f, 0xab, 0x74, 0xa4, + 0x52, 0x93, 0xb0, 0xd1, 0x67, 0xea, 0xa6, 0x3d, 0x34, 0x38, 0x6d, 0x4f, 0x78, 0x6a, 0xe6, 0x5b, + 0x2f, 0x9e, 0xb7, 0x84, 0xb6, 0xa2, 0x44, 0x9e, 0x58, 0x81, 0xb2, 0xc8, 0xbc, 0x83, 0x3d, 0x0b, + 0x73, 0xd0, 0xbc, 0x88, 0xf5, 0xb7, 0xb6, 0x00, 0x72, 0x3f, 0x21, 0x60, 0x4a, 0xb5, 0xf4, 0x66, + 0x2a, 0x99, 0x31, 0x9f, 0x24, 0x83, 0x1c, 0x48, 0x2f, 0xa7, 0xf9, 0x9a, 0xbd, 0xb1, 0xc5, 0x5f, + 0xf7, 0x1e, 0x51, 0x81, 0xc3, 0x47, 0x5e, 0x7a, 0x0b, 0x87, 0xc9, 0x2a, 0xe5, 0x8a, 0xb4, 0x3a, + 0x04, 0xbd, 0x92, 0xdb, 0xd6, 0x5d, 0x45, 0x07, 0x34, 0xfe, 0x46, 0x87, 0xda, 0x51, 0x6a, 0x2f, + 0xb2, 0x25, 0x01, 0x81, 0x60, 0x91, 0xb1, 0x63, 0x61, 0x50, 0x23, 0xea, 0x76, 0x10, 0x27, 0xbb, + 0xe4, 0x37, 0x5e, 0x37, 0xdf, 0x59, 0x0e, 0x5f, 0xa9, 0x8c, 0x44, 0x63, 0x68, 0x78, 0x2a, 0x75, + 0xa5, 0x08, 0xba, 0xf1, 0x3c, 0xb5, 0x90, 0xdb, 0x43, 0xaf, 0xf0, 0xa2, 0x23, 0xad, 0x18, 0x04, + 0xed, 0xaa, 0x7f, 0xe9, 0x15, 0x12, 0x4a, 0x13, 0x09, 0xd7, 0xb8, 0xba, 0x70, 0x12, 0xe7, 0xe0, + 0xe3, 0xea, 0x06, 0xd6, 0x75, 0xb7, 0xd5, 0x89, 0x2d, 0x82, 0x77, 0x18, 0x1a, 0x83, 0x2a, 0x87, + 0x39, 0x7d, 0x72, 0x33, 0xdd, 0xc1, 0x94, 0x02, 0x1b, 0x66, 0x7f, 0xce, 0xa4, 0x13, 0x2f, 0x44, + 0x13, 0x4c, 0xb9, 0x79, 0xf4, 0x5f, 0x3a, 0xf9, 0x6a, 0xa4, 0x7b, 0xa1, 0x72, 0xe9, 0x8a, 0xa9, + 0xc6, 0x30, 0x84, 0x76, 0xe5, 0x9a, 0xcc, 0xb3, 0x98, 0xe9, 0xe0, 0xe5, 0xde, 0x35, 0xcd, 0x37, + 0xd1, 0xd7, 0x96, 0x05, 0xb3, 0x4b, 0x24, 0x19, 0xee, 0x72, 0x37, 0xab, 0x08, 0x93, 0x00, 0x8a, + 0xed, 0x27, 0x90, 0x55, 0xce, 0xee, 0xf8, 0xfe, 0x52, 0x3e, 0x4d, 0xf2, 0x77, 0xc4, 0xbb, 0xb2, + 0x8c, 0x50, 0xd4, 0x6b, 0x0a, 0xed, 0x4f, 0x06, 0x19, 0x30, 0x3f, 0x3b, 0xb4, 0xb1, 0xb6, 0x55, + 0x88, 0x5a, 0xf9, 0x07, 0x49, 0x64, 0xb5, 0x5c, 0x23, 0x22, 0xb0, 0x2c, 0x31, 0x98, 0x85, 0x1a, + 0x42, 0x0c, 0x1a, 0xe6, 0xaf, 0x62, 0x3a, 0xc9, 0x17, 0x2c, 0xc0, 0xf2, 0x2f, 0x62, 0x4a, 0x41, + 0xa6, 0x82, 0x85, 0x99, 0x51, 0x6c, 0x0a, 0xa2, 0x25, 0xaa, 0x22, 0xce, 0x37, 0x29, 0x12, 0x3f, + 0xcd, 0x86, 0xd7, 0x02, 0x16, 0x05, 0xa7, 0x66, 0x60, 0xdd, 0xa3, 0x94, 0x7b, 0x84, 0x54, 0xb9, + 0xbd, 0x82, 0xe0, 0x77, 0x71, 0xc6, 0x76, 0x5e, 0x01, 0xed, 0x0d, 0x3f, 0x66, 0x87, 0x01, 0x8b, + 0xa1, 0x19, 0x41, 0x58, 0x82, 0xed, 0xf9, 0xab, 0x4a, 0x53, 0xce, 0x93, 0x35, 0xd8, 0xf6, 0xc4, + 0x49, 0xde, 0x8f, 0x7a, 0xde, 0x24, 0x1b, 0x64, 0x3a, 0xe9, 0x48, 0xca, 0x68, 0x8e, 0x72, 0xcd, + 0xc4, 0xc8, 0x8c, 0x6f, 0x5a, 0xad, 0xd4, 0x5b, 0x6d, 0xad, 0x65, 0x78, 0x0f, 0xee, 0xf0, 0xbf, + 0x2a, 0x81, 0xb4, 0xa8, 0x79, 0xac, 0x11, 0x14, 0x53, 0x1e, 0x6e, 0x88, 0x95, 0x71, 0xae, 0x5c, + 0xac, 0x66, 0x11, 0x09, 0x36, 0x31, 0xa9, 0x84, 0xe3, 0x3b, 0xe4, 0x62, 0x1f, 0xc2, 0x42, 0x44, + 0x66, 0xdf, 0x09, 0x42, 0x0d, 0x53, 0x20, 0x66, 0x74, 0x06, 0x65, 0xc3, 0xe0, 0x57, 0xbe, 0x41, + 0x84, 0x27, 0x35, 0x50, 0xf7, 0x78, 0xcb, 0xc6, 0xb9, 0x7f, 0x17, 0x47, 0x7f, 0x01, 0xb7, 0x20, + 0xc5, 0xdc, 0xdb, 0x8f, 0x73, 0x47, 0x87, 0xb8, 0x69, 0xd9, 0xd7, 0x09, 0x0f, 0x76, 0xe7, 0x60, + 0x13, 0x7e, 0x8b, 0x8c, 0xbc, 0x4f, 0x62, 0xd1, 0xc0, 0x6a, 0xe2, 0x39, 0x79, 0x0b, 0xa2, 0x23, + 0x0f, 0x58, 0xce, 0x68, 0x09, 0x08, 0x66, 0xbf, 0xe0, 0x45, 0xe1, 0x8d, 0x09, 0x4e, 0x0b, 0x8f, + 0x77, 0x20, 0x4b, 0xfc, 0x34, 0xae, 0xd7, 0x0a, 0xe4, 0xfa, 0xd7, 0x52, 0xac, 0x18, 0x41, 0x61, + 0x4d, 0x5f, 0xf4, 0xbb, 0x68, 0x4a, 0xfb, 0x0d, 0x21, 0x76, 0x74, 0x82, 0x69, 0xe2, 0x9d, 0xb4, + 0x7b, 0x99, 0xeb, 0x3a, 0x32, 0xb9, 0x35, 0xef, 0x4e, 0xa5, 0xa8, 0xf1, 0x1e, 0x8b, 0x71, 0xbb, + 0x58, 0xdb, 0xa7, 0x67, 0xa0, 0x44, 0xde, 0xfe, 0x47, 0xc9, 0xaf, 0x47, 0x78, 0x51, 0x77, 0xdf, + 0xb9, 0x41, 0x09, 0x9b, 0xf2, 0x3a, 0x3c, 0x89, 0x24, 0xa0, 0x98, 0xe7, 0xfa, 0x3f, 0x27, 0xeb, + 0x2e, 0x13, 0x17, 0x91, 0xc3, 0xac, 0x19, 0x69, 0x0e, 0x6a, 0x84, 0x3f, 0x1c, 0x51, 0xc4, 0x32, + 0xf5, 0x7c, 0xad, 0xe7, 0x69, 0x7c, 0xb6, 0x26, 0x66, 0x84, 0x47, 0x67, 0x80, 0x97, 0x92, 0x2e, + 0x67, 0xe5, 0xf0, 0xbc, 0x14, 0x26, 0x25, 0x80, 0xdd, 0x94, 0xe6, 0xe4, 0x41, 0xe3, 0x2e, 0xeb, + 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xcf, 0x35, 0x54, 0x5f, 0x18, 0x6b, 0x62, + 0xe0, 0xcc, 0x0e, 0x0c, 0xd7, 0x1e, 0x09, 0x02, 0x97, 0xe0, 0xac, 0x87, 0xb0, 0x15, 0x97, 0x7f, + 0x79, 0x0f, 0xab, 0x44, 0xe8, 0x05, 0xcd, 0xfa, 0x8c, 0x77, 0x89, 0x22, 0x81, 0x02, 0xc7, 0xd3, + 0x01, 0x9c, 0x68, 0xe3, 0x49, 0x68, 0x51, 0x08, 0x35, 0xd0, 0x96, 0x29, 0x00, 0x8a, 0xeb, 0xb1, + 0x41, 0x40, 0x37, 0x37, 0x11, 0x92, 0x56, 0x44, 0x90, 0xd4, 0xaf, 0xef, 0xf1, 0x71, 0x7d, 0xd7, + 0x0a, 0x7d, 0x1c, 0xe1, 0x17, 0x42, 0x7d, 0xda, 0x84, 0x4b, 0x42, 0xcc, 0xa1, 0x67, 0xa3, 0x01, + 0xb2, 0x94, 0xdf, 0x65, 0xfa, 0xbe, 0xf5, 0xfa, 0x38, 0x37, 0x61, 0xc1, 0x2e, 0xa1, 0x49, 0xea, + 0x65, 0x66, 0x66, 0x2d, 0x23, 0x92, 0x14, 0xee, 0x5a, 0xc3, 0xa3, 0xe2, 0x6d, 0x93, 0x21, 0x16, + 0xba, 0x61, 0x6e, 0xc6, 0x05, 0x2b, 0x2b, 0xb8, 0x7b, 0xec, 0x83, 0xfd, 0x44, 0x5c, 0x21, 0x32, + 0x7f, 0xab, 0x3d, 0x10, 0xa2, 0x4a, 0x42, 0xad, 0x1f, 0x6f, 0xc7, 0x8f, 0xd3, 0x2a, 0x7a, 0xb2, + 0x52, 0x52, 0x6d, 0x63, 0x96, 0x2c, 0x2f, 0x2e, 0x6d, 0xf1, 0xf9, 0xfc, 0x31, 0x82, 0xb0, 0x9b, + 0x03, 0x80, 0xa3, 0x59, 0x54, 0x58, 0xd9, 0x37, 0x30, 0x33, 0x54, 0x46, 0x14, 0x79, 0x36, 0xfa, + 0xe8, 0x30, 0x54, 0xc9, 0x2c, 0xa5, 0xd2, 0xc9, 0xac, 0xa4, 0xd2, 0x0b, 0xfb, 0x72, 0xc4, 0xad, + 0xb8, 0x7a, 0x11, 0xbe, 0x95, 0x41, 0xd7, 0x05, 0x1c, 0xe6, 0x95, 0x70, 0xfc, 0xd3, 0xdb, 0x31, + 0x23, 0x7b, 0x94, 0xa2, 0xc9, 0xee, 0x63, 0x55, 0x45, 0x4f, 0x9d, 0x23, 0x27, 0x62, 0x08, 0x33, + 0x67, 0xa0, 0x4f, 0x98, 0x1d, 0x54, 0xc9, 0xba, 0xa3, 0xfc, 0x1c, 0xdd, 0xee, 0x1d, 0x79, 0xfe, + 0x8f, 0xbd, 0x3a, 0x3e, 0xda, 0xbb, 0x13, 0x94, 0xa5, 0x02, 0x03, 0x01, 0x00, 0x01 +}; + +#define composite44_rsa2048pkcs15_msg composite_test_msg + +static const uint8_t composite44_rsa2048pkcs15_add_random[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const uint8_t composite44_rsa2048pkcs15_sig_digest[] = { + 0xa4, 0x1f, 0xf4, 0xf4, 0xf7, 0x47, 0x45, 0xab, 0x8b, 0x2e, 0x6f, 0xad, 0x2c, 0x71, 0xa7, 0x2f, + 0x8a, 0x3a, 0x3e, 0x7d, 0xe8, 0x8c, 0xf0, 0x05, 0x89, 0x4b, 0x03, 0xeb, 0x59, 0x9e, 0x7b, 0x4a +}; + +static const uint8_t composite44_rsa2048pkcs15_sig[] = { + 0x76, 0x80, 0xab, 0x24, 0x91, 0x05, 0xdf, 0x57, 0x87, 0xbb, 0xfd, 0x89, 0xd6, 0xa2, 0x80, 0x80, + 0xb2, 0x0a, 0xe8, 0x25, 0x12, 0x35, 0x84, 0x00, 0xfc, 0x52, 0xdd, 0x2b, 0xfd, 0x4a, 0xf5, 0xfb, + 0x64, 0x9b, 0x78, 0x36, 0x0b, 0x1a, 0x84, 0xf7, 0x53, 0x95, 0x70, 0x58, 0x64, 0x3d, 0xe2, 0x2a, + 0x86, 0x03, 0x4c, 0xe4, 0x13, 0x6c, 0x2d, 0x28, 0xeb, 0xf2, 0x78, 0x96, 0x12, 0x30, 0x34, 0x27, + 0xf2, 0x0a, 0xb7, 0x36, 0x23, 0x9e, 0x07, 0x47, 0x68, 0x04, 0xc5, 0x79, 0x91, 0x63, 0x37, 0x66, + 0x65, 0xc1, 0xec, 0x1e, 0x68, 0x7a, 0x6d, 0xa1, 0xa3, 0x03, 0x99, 0x02, 0xa9, 0x0e, 0xaa, 0x07, + 0x98, 0x3d, 0xaa, 0xbd, 0x6f, 0xe6, 0xa3, 0x8f, 0x9e, 0xee, 0x86, 0x7d, 0x81, 0x61, 0x49, 0x0c, + 0x5c, 0x6f, 0x85, 0x78, 0x97, 0xfa, 0xfd, 0x86, 0x31, 0xa9, 0xda, 0xe7, 0x60, 0xc1, 0x60, 0x45, + 0x38, 0x93, 0x57, 0xe4, 0xd5, 0x00, 0xe1, 0x61, 0x5d, 0x40, 0x8b, 0xb3, 0xab, 0x0a, 0x6b, 0x3f, + 0x42, 0x5a, 0x29, 0xb7, 0x9c, 0x0a, 0x7c, 0x64, 0x26, 0xd1, 0x33, 0x7d, 0x93, 0xe8, 0x84, 0xb8, + 0x75, 0x04, 0x77, 0xc3, 0x08, 0x91, 0x8a, 0x12, 0x45, 0x43, 0x98, 0x5f, 0xde, 0xff, 0x3f, 0x6c, + 0x0b, 0xc1, 0xd0, 0x38, 0xe5, 0xc9, 0xdc, 0xa3, 0xe0, 0x50, 0x95, 0x83, 0xbd, 0x91, 0xb5, 0x5e, + 0xaf, 0xe2, 0xe6, 0x15, 0x97, 0xfc, 0x98, 0xdb, 0x39, 0x28, 0x5f, 0x8c, 0xf5, 0x60, 0x9d, 0x25, + 0x30, 0x7d, 0xc6, 0x10, 0xe9, 0x50, 0x5f, 0x49, 0x5c, 0x3b, 0x3c, 0x39, 0x79, 0x44, 0x78, 0x96, + 0x01, 0x32, 0xcd, 0x87, 0xb2, 0x8e, 0x59, 0x3c, 0xda, 0x0a, 0xec, 0x48, 0xac, 0xcb, 0xfa, 0x65, + 0xf1, 0x6e, 0x6e, 0xdd, 0x2c, 0x96, 0x5d, 0x66, 0xf6, 0x91, 0x44, 0x80, 0x57, 0x21, 0x0f, 0xe6, + 0x0e, 0xe7, 0xe7, 0x26, 0x2b, 0x7e, 0x47, 0x50, 0x7b, 0x7e, 0x93, 0xd4, 0x9c, 0xe5, 0xfc, 0xa3, + 0xd5, 0x68, 0x35, 0x33, 0xb6, 0xdb, 0x18, 0x80, 0x17, 0xe8, 0x71, 0x92, 0x48, 0x67, 0x06, 0x3c, + 0xac, 0xab, 0x0b, 0x48, 0xd7, 0x14, 0x1b, 0x1d, 0x46, 0x15, 0xbb, 0x1f, 0x37, 0x5e, 0xf4, 0x02, + 0xc9, 0x5e, 0x72, 0x50, 0x76, 0x10, 0xcc, 0x4f, 0x69, 0x55, 0x23, 0x61, 0x52, 0xa5, 0xb7, 0xd9, + 0x20, 0xca, 0x4e, 0x62, 0xcd, 0xf0, 0x05, 0x16, 0x4c, 0xd1, 0x6f, 0x55, 0x67, 0x56, 0x79, 0xe8, + 0x11, 0x5a, 0x5b, 0xbe, 0x20, 0xce, 0x4f, 0xaf, 0xa4, 0x0a, 0x2b, 0x80, 0x0a, 0x29, 0x5f, 0x3e, + 0x5f, 0x1a, 0xb3, 0x26, 0xc5, 0xd9, 0xda, 0x08, 0xbb, 0xb0, 0x36, 0x16, 0x6a, 0x55, 0xc7, 0xba, + 0x3a, 0x1a, 0xef, 0x1f, 0x53, 0x17, 0x8e, 0xa3, 0x71, 0xe4, 0x9e, 0x1b, 0xbe, 0x48, 0x8a, 0x32, + 0x5b, 0x19, 0xac, 0x35, 0xa6, 0xb2, 0x6a, 0xdc, 0xc0, 0x69, 0xfd, 0xc4, 0xbb, 0x3b, 0xa4, 0x08, + 0x25, 0xd6, 0x86, 0x0c, 0xe0, 0x9d, 0x56, 0x45, 0x89, 0x2c, 0x72, 0xef, 0x2b, 0x9a, 0xcb, 0x92, + 0xe3, 0xc7, 0x08, 0xa3, 0x22, 0x43, 0xf4, 0x12, 0xd2, 0xb1, 0xd3, 0x74, 0x89, 0x55, 0xfc, 0x0b, + 0xc5, 0x23, 0x9f, 0x27, 0x28, 0x79, 0xe0, 0x7b, 0xa1, 0x92, 0x22, 0x57, 0x46, 0x1c, 0xb2, 0x3e, + 0x60, 0x01, 0x08, 0x06, 0x85, 0x5e, 0x1c, 0xea, 0x56, 0xe9, 0x67, 0x9d, 0x12, 0x51, 0x53, 0xbb, + 0xb2, 0x53, 0x01, 0xee, 0xc5, 0xed, 0xc6, 0x51, 0x36, 0xf5, 0x7c, 0x5c, 0x6b, 0xe9, 0x0f, 0x5f, + 0x50, 0xd8, 0x96, 0x2a, 0xa4, 0xf0, 0x07, 0xf0, 0x71, 0x56, 0x31, 0xa3, 0x40, 0x46, 0x61, 0x00, + 0x7f, 0x5a, 0x3b, 0xe7, 0x94, 0xfe, 0xf5, 0x33, 0x0b, 0x5c, 0xb0, 0xcd, 0x1b, 0x8b, 0x46, 0x18, + 0x46, 0xb0, 0x58, 0x24, 0x29, 0x32, 0x36, 0x65, 0x0b, 0x06, 0xbe, 0x99, 0xba, 0xff, 0x2d, 0xbf, + 0xea, 0x0a, 0x8d, 0x71, 0x84, 0x93, 0xd9, 0xc8, 0xbb, 0x1c, 0x43, 0x64, 0xa6, 0x4a, 0x5d, 0x8c, + 0xc5, 0x8a, 0xdf, 0x1f, 0x36, 0x66, 0x29, 0x31, 0xa7, 0xd6, 0x0c, 0xba, 0x99, 0xcd, 0x10, 0x18, + 0x9d, 0x6c, 0x8d, 0x57, 0xf9, 0xe8, 0x9a, 0xf5, 0x6f, 0x17, 0x2e, 0x69, 0xbd, 0xf2, 0x7a, 0xa1, + 0x30, 0x69, 0xf7, 0xc9, 0xb3, 0x0a, 0x93, 0xff, 0x83, 0x49, 0xf1, 0xc1, 0xc0, 0xd9, 0x98, 0x26, + 0x34, 0xb4, 0x03, 0x48, 0x38, 0xb7, 0x7d, 0x8a, 0x8a, 0x3f, 0xf3, 0x7a, 0x1b, 0x39, 0x92, 0x3d, + 0x16, 0x29, 0x63, 0x3a, 0xf4, 0xde, 0x2f, 0x61, 0x44, 0x5a, 0x43, 0x7a, 0x6c, 0x7c, 0x64, 0x48, + 0xe2, 0x13, 0xf0, 0x0f, 0x42, 0x9b, 0x54, 0xb1, 0xe1, 0xd5, 0x06, 0xd1, 0xf8, 0x9e, 0xb7, 0x86, + 0x74, 0xdf, 0x84, 0x6b, 0x6b, 0xbc, 0xbd, 0x83, 0xd3, 0x6c, 0x5c, 0x86, 0xe3, 0x75, 0xa7, 0x63, + 0xd9, 0x97, 0x07, 0x50, 0xdf, 0x73, 0xb5, 0xfa, 0xed, 0x9c, 0x7a, 0x31, 0xba, 0x79, 0xfd, 0x71, + 0x1a, 0xbb, 0x63, 0xed, 0xcc, 0x55, 0xbf, 0xb8, 0x95, 0x2c, 0xc5, 0x71, 0xa9, 0x19, 0x47, 0x47, + 0x7c, 0x22, 0x10, 0xe2, 0xcb, 0x2f, 0x3f, 0x52, 0xda, 0x6a, 0x64, 0x57, 0xa9, 0xae, 0x5f, 0x3c, + 0xe8, 0x4b, 0xbc, 0xc4, 0xcb, 0x67, 0x9b, 0xdf, 0xc3, 0xaa, 0x1c, 0x85, 0xff, 0x53, 0x10, 0x62, + 0x0e, 0xa5, 0x00, 0x28, 0xca, 0x6a, 0x58, 0x24, 0xd7, 0x72, 0x53, 0xc6, 0x5c, 0x05, 0xe1, 0x1e, + 0x9f, 0x2d, 0x39, 0xb4, 0xa7, 0xaa, 0x61, 0xad, 0x6b, 0xcf, 0x03, 0x54, 0x5c, 0x60, 0x69, 0x0b, + 0x51, 0x2e, 0x87, 0x1f, 0xb8, 0x85, 0x3f, 0xe0, 0xf2, 0x50, 0x64, 0xd3, 0x67, 0xaa, 0xb1, 0x0d, + 0x19, 0xf2, 0x59, 0xc0, 0x0c, 0x99, 0x3c, 0x4e, 0x03, 0xde, 0xc6, 0x83, 0xe0, 0x4c, 0x62, 0x17, + 0xff, 0x32, 0x1b, 0xb1, 0x21, 0xbd, 0x9f, 0x80, 0x1d, 0x17, 0x32, 0xa3, 0x2b, 0x70, 0x0d, 0x3e, + 0x5c, 0x12, 0x3f, 0xab, 0x03, 0xd6, 0x26, 0x93, 0xe6, 0xe2, 0x84, 0x31, 0x0e, 0x43, 0xb3, 0xc6, + 0x22, 0x95, 0x1f, 0xdf, 0x63, 0x4e, 0xd1, 0xa7, 0xf8, 0x0a, 0x1f, 0x3b, 0x8a, 0x3a, 0x33, 0xb7, + 0xd6, 0x24, 0x02, 0x05, 0x67, 0xed, 0x95, 0x23, 0xa6, 0x77, 0xe7, 0x5b, 0xed, 0x7b, 0xca, 0x50, + 0xaa, 0xf9, 0xa6, 0x09, 0x42, 0xff, 0x71, 0x1f, 0xef, 0x01, 0xc6, 0xcb, 0x76, 0x87, 0x20, 0x14, + 0x14, 0xa0, 0x9a, 0xe6, 0x6d, 0xc4, 0x4e, 0x2d, 0x68, 0xe9, 0xed, 0xa4, 0x15, 0x9f, 0x35, 0x64, + 0xf8, 0x7d, 0x58, 0xa6, 0x54, 0x04, 0x58, 0x2d, 0x8a, 0x0a, 0x61, 0xca, 0x12, 0xd2, 0xbf, 0x76, + 0xcc, 0x37, 0xc2, 0x97, 0xff, 0xc5, 0x10, 0x99, 0xbf, 0x05, 0xc1, 0x34, 0x86, 0x27, 0xa6, 0x42, + 0xb2, 0x34, 0x74, 0x2b, 0xd2, 0x72, 0x47, 0x6e, 0xac, 0x6f, 0x65, 0x60, 0xff, 0x43, 0x45, 0xfe, + 0xc3, 0x44, 0xc2, 0x96, 0x59, 0x47, 0x52, 0x29, 0xc6, 0x5b, 0xd8, 0x7d, 0x4b, 0x4a, 0x30, 0xaf, + 0x85, 0x53, 0x36, 0xe5, 0x15, 0x3a, 0xc2, 0xc1, 0x42, 0x4f, 0xc2, 0xa9, 0x28, 0xaa, 0x86, 0xd5, + 0x7f, 0xbb, 0xed, 0xe1, 0xa3, 0xfd, 0xe1, 0xb6, 0xb5, 0x84, 0x49, 0xb8, 0x70, 0xda, 0x6a, 0xd2, + 0xbc, 0x6a, 0xe9, 0x77, 0x87, 0x9c, 0xd4, 0xba, 0x68, 0xf6, 0x6c, 0x6e, 0x4c, 0xa0, 0x13, 0xc4, + 0xd8, 0xee, 0xc3, 0xfb, 0xeb, 0xfe, 0xb7, 0x18, 0xd8, 0x0c, 0x11, 0x42, 0xe2, 0x53, 0xd1, 0x5a, + 0x79, 0xb4, 0xe9, 0x47, 0xa8, 0xf6, 0x7b, 0x69, 0xa6, 0x6c, 0xa0, 0x9b, 0x89, 0x83, 0xc3, 0x55, + 0xc7, 0xb5, 0x7f, 0x20, 0xf6, 0x36, 0xb6, 0x19, 0x06, 0x8c, 0x1a, 0xdf, 0x32, 0x76, 0x46, 0x43, + 0x10, 0xf7, 0x16, 0x7d, 0x53, 0x02, 0xfc, 0x34, 0x63, 0xe3, 0xd6, 0xb8, 0x33, 0x57, 0x66, 0x2b, + 0xac, 0xf7, 0x01, 0xb2, 0xad, 0xc0, 0xbb, 0xce, 0x91, 0xec, 0x5f, 0xb8, 0xd5, 0xa1, 0x00, 0x2f, + 0x04, 0xcb, 0xde, 0x52, 0xd9, 0x47, 0x57, 0x3c, 0x1c, 0x3c, 0x12, 0x9b, 0xfb, 0x29, 0x48, 0xff, + 0x30, 0x26, 0x70, 0xf3, 0x75, 0xbe, 0x19, 0xbc, 0x8f, 0x4d, 0xcd, 0x0d, 0xe0, 0xcf, 0x6e, 0x19, + 0x80, 0x3f, 0x70, 0x97, 0xa4, 0xda, 0x79, 0xc1, 0x07, 0x72, 0x8f, 0x0f, 0x2b, 0xa3, 0xb8, 0x5a, + 0x92, 0xb7, 0x68, 0x68, 0x3d, 0x5c, 0xc6, 0x49, 0x9c, 0xf5, 0xc9, 0x7a, 0xa3, 0x79, 0x97, 0xbe, + 0xfd, 0xf9, 0x96, 0xb1, 0x77, 0xcf, 0x90, 0x90, 0x28, 0xa1, 0xb4, 0xc6, 0x5f, 0x25, 0x68, 0xa5, + 0x52, 0x20, 0xc6, 0x67, 0xbb, 0x70, 0x96, 0xb7, 0x62, 0x7a, 0x31, 0x9f, 0xbc, 0x7b, 0xce, 0xb7, + 0x58, 0x34, 0xbc, 0x69, 0xad, 0x9a, 0x1a, 0x48, 0xe0, 0x26, 0x24, 0x99, 0xe7, 0x43, 0x9a, 0xbe, + 0x53, 0x4d, 0x8a, 0x03, 0xb9, 0xbf, 0xf8, 0xfc, 0x8e, 0xa2, 0x80, 0x61, 0xad, 0x14, 0xc2, 0xd7, + 0xfa, 0x15, 0xcb, 0x6f, 0x70, 0x10, 0x35, 0x4e, 0x3b, 0x6b, 0x88, 0x49, 0xe5, 0xbd, 0x88, 0xff, + 0x47, 0xee, 0xdc, 0x2c, 0xac, 0x9a, 0x46, 0x80, 0xcb, 0x1d, 0x20, 0x99, 0xfe, 0xe0, 0x22, 0x21, + 0x9b, 0xc8, 0x0f, 0x5c, 0xd1, 0xc5, 0xef, 0xcb, 0x07, 0xa1, 0x24, 0x7e, 0x76, 0x59, 0x30, 0xdd, + 0xf4, 0xd3, 0x55, 0x1b, 0x85, 0xba, 0xa4, 0x12, 0x8a, 0x90, 0x8e, 0x05, 0xb6, 0x0b, 0x3e, 0x9a, + 0x61, 0x32, 0x63, 0x9b, 0x1e, 0x17, 0x31, 0x40, 0x4b, 0x93, 0x5a, 0x77, 0x19, 0x08, 0x5e, 0x9b, + 0xae, 0x74, 0x77, 0x22, 0xf0, 0x50, 0xe0, 0x4a, 0xe5, 0xba, 0x35, 0xb2, 0x46, 0xf0, 0x82, 0x3b, + 0x6a, 0xf3, 0xf4, 0xfc, 0x02, 0xf2, 0x29, 0x35, 0xae, 0x22, 0xb8, 0x7d, 0x35, 0x63, 0x4d, 0xf1, + 0x38, 0xfb, 0xf0, 0x33, 0xb2, 0xef, 0xa6, 0xbc, 0xff, 0x4d, 0xd7, 0xdf, 0x86, 0x7f, 0xd4, 0x2d, + 0xa6, 0x25, 0xca, 0x7a, 0xe3, 0x8e, 0xa4, 0xf6, 0x90, 0xdb, 0xb2, 0x5b, 0xe0, 0x3e, 0x4c, 0x80, + 0x80, 0x96, 0x6c, 0x80, 0x63, 0x41, 0x0a, 0xa5, 0x4c, 0x83, 0x37, 0x77, 0x64, 0x77, 0xdd, 0x54, + 0x11, 0xf4, 0x50, 0xb8, 0x4e, 0x83, 0x2c, 0x4b, 0x3b, 0x7d, 0xa3, 0x47, 0xaa, 0x88, 0xa0, 0x59, + 0xbf, 0xaf, 0x89, 0x50, 0x30, 0x3b, 0x21, 0x90, 0xf0, 0xd3, 0x1f, 0xfc, 0xfa, 0x40, 0x3d, 0xa8, + 0x43, 0xaa, 0xb8, 0x7a, 0x1a, 0x96, 0xf2, 0xbc, 0xd6, 0xfb, 0xdb, 0xe2, 0xd9, 0x4e, 0x7a, 0xff, + 0x03, 0xb0, 0xc2, 0x15, 0x09, 0x8a, 0x98, 0x64, 0x47, 0x43, 0xf7, 0xec, 0x6b, 0xaa, 0x47, 0x64, + 0xac, 0x55, 0x84, 0x31, 0xc9, 0xf4, 0x03, 0x0e, 0x1e, 0xd7, 0xdf, 0x43, 0x72, 0xfc, 0xe5, 0xb5, + 0x30, 0x0e, 0xd3, 0x4e, 0x24, 0xef, 0xd7, 0x31, 0x5c, 0x6a, 0x17, 0xef, 0x15, 0xcf, 0xcd, 0xc7, + 0xd6, 0xd6, 0xdf, 0xb7, 0x5b, 0xf4, 0x00, 0xf1, 0xe3, 0xd6, 0x82, 0x8b, 0x66, 0x6f, 0x61, 0x36, + 0xaa, 0x4e, 0x54, 0x42, 0xfc, 0x5f, 0xa6, 0x3d, 0xfc, 0xaf, 0xcb, 0xbd, 0x4a, 0xdc, 0xdd, 0xc1, + 0xfd, 0xde, 0xdf, 0xa0, 0x2d, 0xc5, 0x56, 0x24, 0x70, 0x9e, 0xa3, 0x27, 0xee, 0x5a, 0xb6, 0xe7, + 0xb6, 0xf7, 0x55, 0x38, 0x11, 0x38, 0xec, 0xbb, 0x67, 0x8c, 0xe2, 0x35, 0x3a, 0x08, 0xfe, 0x22, + 0x7e, 0xb0, 0x87, 0xdb, 0x16, 0x11, 0x8a, 0x85, 0xba, 0x5d, 0x43, 0xeb, 0x53, 0x22, 0xf4, 0x30, + 0xaf, 0x5e, 0x09, 0x9a, 0x28, 0x95, 0x86, 0xf3, 0xb1, 0xc7, 0xf0, 0x8b, 0x20, 0xe4, 0xb7, 0x76, + 0x6e, 0x90, 0xda, 0xa6, 0x5f, 0xfa, 0xed, 0xc2, 0x86, 0x11, 0x41, 0x26, 0x0d, 0xda, 0x3b, 0x76, + 0x1c, 0xab, 0x76, 0x84, 0x87, 0xed, 0x86, 0xe8, 0x73, 0xdd, 0x43, 0x6b, 0x9b, 0xc1, 0x2d, 0xa7, + 0x7e, 0xfd, 0x89, 0x67, 0x64, 0x67, 0xa6, 0x1b, 0x6c, 0x90, 0xe5, 0x36, 0x34, 0x80, 0x26, 0x74, + 0x24, 0xfe, 0xc9, 0x6b, 0xb0, 0x1d, 0xd5, 0xbb, 0xca, 0x5e, 0x17, 0x51, 0xa7, 0xab, 0x2a, 0x42, + 0xe9, 0x0b, 0x87, 0xec, 0xad, 0xd8, 0x5f, 0xe9, 0x8d, 0x2d, 0x8e, 0x35, 0x10, 0x38, 0x8e, 0xe0, + 0xb3, 0x6a, 0x75, 0x41, 0x93, 0xaf, 0x5c, 0xac, 0x90, 0x39, 0x48, 0xee, 0xe6, 0x3c, 0xf2, 0x22, + 0x41, 0x23, 0xdd, 0x78, 0xb9, 0x86, 0x86, 0x84, 0x6e, 0x07, 0x02, 0x1c, 0xf4, 0x02, 0xad, 0xe1, + 0xac, 0xb4, 0x3c, 0x93, 0x5c, 0x81, 0x36, 0x7f, 0x90, 0xcc, 0xe5, 0xaa, 0x50, 0xba, 0x00, 0xf6, + 0x32, 0x07, 0xd7, 0xca, 0xb2, 0x03, 0xe6, 0xd7, 0x30, 0x56, 0x3d, 0x24, 0xc0, 0xf5, 0x77, 0x17, + 0xba, 0xb5, 0x94, 0x5c, 0x03, 0x40, 0x42, 0x01, 0x9c, 0xa9, 0x64, 0x83, 0xa2, 0x7d, 0xa2, 0xf8, + 0xb0, 0xa2, 0xde, 0x4a, 0xaf, 0x74, 0x10, 0x12, 0x3c, 0xe4, 0x3e, 0x2a, 0x8d, 0x7a, 0x95, 0x9e, + 0xc7, 0x8d, 0x7a, 0xa7, 0x13, 0xa5, 0xd9, 0xdc, 0x9c, 0x3f, 0xc8, 0xc2, 0x6f, 0x60, 0xdc, 0x92, + 0x55, 0x29, 0x08, 0xbb, 0x80, 0xec, 0x50, 0x83, 0x8e, 0x93, 0x0d, 0x54, 0x74, 0xc1, 0x24, 0xd6, + 0x2b, 0xf2, 0x3d, 0x82, 0x38, 0x16, 0x77, 0xfe, 0xd6, 0x60, 0x74, 0xd3, 0xa4, 0x09, 0xf2, 0xfd, + 0x8e, 0x51, 0x88, 0xec, 0xe9, 0xfc, 0xbb, 0x7a, 0xd5, 0x02, 0xae, 0x25, 0xd2, 0x45, 0x51, 0x86, + 0x6d, 0x51, 0xfc, 0xf7, 0x74, 0x2e, 0x59, 0xe1, 0x14, 0x9a, 0x67, 0x97, 0x1f, 0x28, 0x4d, 0x71, + 0x02, 0xb3, 0xa8, 0x07, 0xed, 0x91, 0x96, 0xb2, 0x66, 0x41, 0x02, 0xf0, 0xf1, 0x06, 0x86, 0x62, + 0x9f, 0x80, 0xb0, 0xa6, 0xff, 0xe4, 0x95, 0xa7, 0xab, 0x07, 0x21, 0xef, 0x4b, 0x8f, 0x30, 0xe0, + 0xa1, 0xc3, 0x9e, 0xed, 0xc7, 0xac, 0x49, 0xc5, 0x31, 0x5a, 0x9b, 0xb0, 0x10, 0x4e, 0x8f, 0x70, + 0xdc, 0x7c, 0x7f, 0xd0, 0x51, 0x6d, 0x30, 0x4b, 0x66, 0x16, 0x96, 0x56, 0x66, 0x6c, 0xf3, 0x47, + 0x30, 0x06, 0xfe, 0xe9, 0x6f, 0x02, 0xd9, 0x03, 0xb5, 0x17, 0xc8, 0x5d, 0xa7, 0x17, 0x1c, 0x39, + 0xc4, 0x3c, 0xb1, 0xc9, 0x93, 0x1d, 0x7e, 0x8f, 0xfb, 0x1a, 0xde, 0xc9, 0xa3, 0x91, 0x4b, 0x0e, + 0xa1, 0x47, 0x81, 0x41, 0x2d, 0xd2, 0x06, 0x86, 0xec, 0x2f, 0x0f, 0xae, 0x79, 0xad, 0x15, 0x18, + 0xec, 0x1a, 0xd1, 0xde, 0xc7, 0xa5, 0x10, 0x60, 0x4f, 0xcd, 0x6f, 0x34, 0x97, 0x51, 0xda, 0x3b, + 0x00, 0xdd, 0x31, 0xde, 0x7b, 0x19, 0xc9, 0x98, 0xb2, 0x7e, 0x22, 0x7f, 0x4a, 0xcb, 0xf4, 0xa6, + 0x15, 0xcd, 0xc5, 0xac, 0x07, 0x9e, 0x28, 0x98, 0x4f, 0xa9, 0xb4, 0x65, 0xab, 0x91, 0x98, 0xf2, + 0x9c, 0x14, 0xe8, 0x7e, 0x2b, 0x67, 0x61, 0x14, 0x9c, 0x63, 0xfa, 0xa2, 0x39, 0xb4, 0xe7, 0xe9, + 0xf8, 0x7d, 0xe1, 0xda, 0xbb, 0x78, 0xb2, 0x2e, 0x5a, 0xc9, 0x96, 0xf4, 0xe3, 0xe2, 0xe1, 0xc7, + 0x80, 0xa3, 0x9e, 0x19, 0x87, 0x7d, 0x2d, 0x78, 0x1c, 0x23, 0x91, 0xaa, 0x45, 0x1d, 0x22, 0xcd, + 0x14, 0x36, 0xab, 0xc2, 0xfe, 0x69, 0xb7, 0xb6, 0x11, 0x03, 0x71, 0x38, 0xf2, 0x19, 0xfb, 0xc1, + 0x17, 0xca, 0x5c, 0x2a, 0xdc, 0x7a, 0x1b, 0x29, 0xa8, 0xeb, 0xe1, 0xa5, 0x6e, 0xc4, 0x12, 0xcd, + 0x57, 0xce, 0x72, 0x71, 0xbe, 0x56, 0xa4, 0xca, 0xf8, 0x40, 0x8e, 0x7b, 0xfa, 0xb0, 0xb0, 0x43, + 0x2f, 0x56, 0xb5, 0x08, 0x74, 0xa0, 0xd4, 0xc1, 0x7f, 0x36, 0x3e, 0x40, 0xf7, 0x74, 0x35, 0x4b, + 0xcb, 0x8b, 0x58, 0x0b, 0x67, 0x9c, 0x15, 0x7c, 0x12, 0x6b, 0xc2, 0x9c, 0xa4, 0xa7, 0xf3, 0xb9, + 0xa2, 0xce, 0x1f, 0xfe, 0xcd, 0x38, 0xde, 0x43, 0x38, 0x18, 0xbb, 0xf6, 0xe4, 0x5d, 0x4a, 0x97, + 0x5f, 0x83, 0x33, 0x47, 0x91, 0xa3, 0xe2, 0x63, 0x30, 0x42, 0x5e, 0x10, 0x8e, 0xc5, 0x38, 0x12, + 0xbd, 0xa1, 0x72, 0x4c, 0xe0, 0x36, 0xb5, 0xeb, 0xf0, 0xd4, 0x3c, 0xe6, 0xc5, 0xd8, 0x42, 0x99, + 0xb6, 0x18, 0x63, 0x6a, 0x23, 0x30, 0x3d, 0xae, 0x1a, 0xfb, 0x5c, 0x49, 0x0a, 0xff, 0x1d, 0x47, + 0x70, 0x87, 0x48, 0x8f, 0xf2, 0x06, 0x8a, 0xdf, 0xc1, 0xcd, 0x4f, 0xd1, 0x89, 0xd6, 0xe7, 0x58, + 0x42, 0xc2, 0x36, 0x18, 0x3f, 0x67, 0xfd, 0xdd, 0x06, 0x2e, 0xdb, 0x89, 0xbe, 0x8e, 0xa1, 0xb5, + 0x8c, 0x9b, 0x60, 0x13, 0xf1, 0x26, 0x11, 0xbd, 0x84, 0x92, 0x80, 0xba, 0xa7, 0xf0, 0xe9, 0xc7, + 0x5b, 0x9d, 0xe0, 0x05, 0x33, 0x10, 0x91, 0x9f, 0x9d, 0x7c, 0x9d, 0x78, 0x4f, 0x8c, 0x54, 0xb5, + 0x32, 0xd5, 0x66, 0x01, 0xc1, 0x28, 0x64, 0x7f, 0x8f, 0x55, 0x21, 0x54, 0xe0, 0xcb, 0x64, 0x06, + 0x9a, 0x44, 0x70, 0x11, 0x39, 0x14, 0x5b, 0xd7, 0xf8, 0x9b, 0xd1, 0x67, 0x2e, 0x1a, 0xcf, 0xa6, + 0xbf, 0x9a, 0x5b, 0x7d, 0xed, 0xc2, 0x5c, 0x5c, 0x4a, 0x3e, 0x1e, 0xe9, 0xa7, 0xfc, 0xe3, 0xf7, + 0x0e, 0xc1, 0x12, 0xad, 0xb6, 0xad, 0xf3, 0xab, 0x39, 0x76, 0x91, 0x70, 0x23, 0x4a, 0x55, 0x5c, + 0x1d, 0x71, 0x21, 0xb2, 0x9d, 0x28, 0xee, 0xa6, 0x14, 0xa3, 0xfc, 0xa8, 0x97, 0x91, 0x16, 0xf1, + 0x07, 0x11, 0x66, 0x43, 0x56, 0x6f, 0xa0, 0x82, 0xc0, 0xce, 0xc7, 0xc7, 0xe1, 0xce, 0xc1, 0x35, + 0x3d, 0xc5, 0xf3, 0x1d, 0x23, 0xe3, 0x60, 0x25, 0x44, 0xd1, 0x3b, 0xf7, 0xc5, 0xb5, 0xe3, 0x36, + 0x0c, 0x0f, 0x17, 0x5c, 0x65, 0x78, 0x7c, 0x7f, 0x8a, 0x96, 0x9e, 0xb7, 0xba, 0xcf, 0xfd, 0x10, + 0x23, 0x8b, 0x90, 0x95, 0x9d, 0x9f, 0xa8, 0xb5, 0xcc, 0xd0, 0xee, 0x02, 0x11, 0x2d, 0x35, 0x37, + 0x40, 0x55, 0x5e, 0x68, 0x84, 0x88, 0x8a, 0x99, 0xa8, 0xb1, 0xc9, 0xf6, 0x08, 0x10, 0x1a, 0x1e, + 0x22, 0x29, 0x31, 0x36, 0x3a, 0x49, 0x54, 0x60, 0x8d, 0x95, 0x97, 0x9a, 0xa3, 0xe0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0f, 0x1b, 0x2c, 0x3e, 0xbe, 0xb5, 0x12, 0xf6, 0xb1, 0xd8, 0x4f, 0xab, 0x17, 0xb3, 0x23, 0x0c, + 0xbf, 0xff, 0xe5, 0xa9, 0x3e, 0x62, 0x05, 0x95, 0xac, 0x0c, 0x25, 0xdf, 0xe9, 0x77, 0x2e, 0x8b, + 0x6c, 0x0e, 0xd5, 0xfc, 0x1e, 0x71, 0xb2, 0x7f, 0xaa, 0x38, 0x92, 0x31, 0x3c, 0xa5, 0x90, 0xd3, + 0xcd, 0xe7, 0xf2, 0xb8, 0x5d, 0x4b, 0xa4, 0xe1, 0x61, 0xd2, 0xe5, 0x36, 0xac, 0x85, 0x16, 0x51, + 0x28, 0x90, 0x92, 0x05, 0x6a, 0xfa, 0xe5, 0x60, 0x2b, 0x4c, 0x67, 0x36, 0xf8, 0x11, 0x54, 0xcf, + 0x53, 0x71, 0x15, 0x45, 0xc0, 0x85, 0x1f, 0x1e, 0x2f, 0xc4, 0xd5, 0xcb, 0x72, 0xa8, 0x1c, 0xbb, + 0x27, 0xf9, 0x9c, 0x0b, 0x76, 0x9f, 0x02, 0x4e, 0xc2, 0x30, 0xf0, 0xa8, 0x15, 0x7a, 0xc8, 0x8b, + 0x60, 0x40, 0x0e, 0xd0, 0xed, 0xa6, 0x78, 0xdf, 0x76, 0xde, 0x1d, 0x75, 0xba, 0xa2, 0xb7, 0xb0, + 0x41, 0xbf, 0x6a, 0x08, 0xc7, 0xa4, 0xcf, 0xaf, 0xad, 0xa7, 0x99, 0x63, 0x05, 0xaf, 0xfe, 0x42, + 0x3f, 0x26, 0x93, 0x83, 0x40, 0xe0, 0xfe, 0xf5, 0x21, 0xce, 0x79, 0x88, 0xd4, 0x61, 0x3f, 0x67, + 0xee, 0x81, 0xc3, 0x81, 0xa5, 0xe4, 0x75, 0x2b, 0xcb, 0xc3, 0xf2, 0x7f, 0x82, 0xec, 0xd1, 0x61, + 0xa2, 0x60, 0xa7, 0xe3, 0xb4, 0x9d, 0x08, 0x23, 0x9c, 0xeb, 0x7e, 0x29, 0xfd, 0xc1, 0x97, 0x7f, + 0x40, 0xa3, 0xbb, 0x48, 0x1a, 0x2d, 0x41, 0x21, 0xd5, 0x76, 0x1c, 0x65, 0xf4, 0xfd, 0xae, 0x52, + 0x38, 0xfa, 0xad, 0xcf, 0x5c, 0x83, 0x72, 0xb7, 0x62, 0xd2, 0xc3, 0x7e, 0xb2, 0xf0, 0x85, 0x28, + 0x74, 0xe3, 0x16, 0x00, 0x37, 0xa5, 0xc3, 0x04, 0x77, 0x15, 0x31, 0xca, 0x1a, 0xe6, 0x43, 0xc0, + 0xb9, 0x4a, 0x86, 0x7f, 0x1b, 0x3f, 0x5e, 0xad, 0xb0, 0x6c, 0x93, 0x61, 0x00, 0x4e, 0xb2, 0xa7, + 0x88, 0x90, 0xe5, 0xb3 +}; + +/* --- ML-DSA-44-Ed25519-SHA512 --- */ +static const uint8_t composite44_ed25519_priv[] = { + 0x89, 0x92, 0x1d, 0xeb, 0xc3, 0x13, 0x46, 0xb1, 0x6d, 0xa2, 0xbf, 0x4f, 0xff, 0xa2, 0x2c, 0x4a, + 0x7c, 0xd0, 0x29, 0x35, 0x40, 0x54, 0x2c, 0x26, 0x77, 0x25, 0xd9, 0x3e, 0xa4, 0x9c, 0x0e, 0x07, + 0x41, 0x34, 0xb1, 0x01, 0xd6, 0xd0, 0x6e, 0xdb, 0x3c, 0xe5, 0xcf, 0xc9, 0x47, 0x94, 0xe6, 0xbf, + 0x6c, 0xa0, 0x40, 0x12, 0xd2, 0x5e, 0xa8, 0xd0, 0x1f, 0xfd, 0x96, 0xd7, 0x9d, 0x0b, 0x64, 0xbc +}; + +static const uint8_t composite44_ed25519_pub[] = { + 0x68, 0x55, 0x91, 0x3f, 0x00, 0x86, 0xb6, 0x3b, 0x6d, 0xf2, 0x20, 0x35, 0x63, 0x5a, 0x9c, 0x0d, + 0xa4, 0xc7, 0x3e, 0xb0, 0xa8, 0x7d, 0x2b, 0x05, 0x43, 0x25, 0xc8, 0x32, 0xb9, 0x7e, 0x26, 0x4f, + 0x3a, 0x67, 0x58, 0x48, 0x01, 0xd7, 0x0f, 0xbd, 0xa7, 0x8a, 0xa7, 0x8c, 0xeb, 0xbd, 0x03, 0x3d, + 0xce, 0xcc, 0x7c, 0x0a, 0x2d, 0xe5, 0x10, 0x84, 0xc4, 0x0b, 0xbf, 0x49, 0xc8, 0xc6, 0xc6, 0x24, + 0x0f, 0xb2, 0xd4, 0x7c, 0x18, 0x05, 0x52, 0xa4, 0xf7, 0xb5, 0x86, 0xcb, 0x8a, 0xd0, 0x6e, 0x6e, + 0xf6, 0xef, 0x1f, 0xcd, 0xf3, 0x86, 0x76, 0x03, 0x79, 0x17, 0x3d, 0x5f, 0x0b, 0xdb, 0xb5, 0xac, + 0x57, 0xef, 0x6f, 0x21, 0x44, 0x8b, 0x6a, 0x6f, 0x48, 0xa0, 0x5f, 0x1e, 0xf2, 0x63, 0xa4, 0xeb, + 0x38, 0xd5, 0xed, 0x88, 0x8d, 0xe5, 0x75, 0xbf, 0x61, 0x8c, 0x4b, 0x8a, 0xb5, 0xbf, 0x1b, 0xe2, + 0xe5, 0x34, 0xf2, 0x77, 0x7c, 0x80, 0xa5, 0x1f, 0x58, 0xb2, 0xf7, 0x47, 0xfe, 0xc9, 0x23, 0xce, + 0x2a, 0x36, 0xf5, 0xb5, 0x27, 0x02, 0x74, 0x10, 0x4d, 0x33, 0x1b, 0x8e, 0x97, 0x13, 0x99, 0xcc, + 0x53, 0x8c, 0xad, 0xec, 0x40, 0xbf, 0x44, 0xd8, 0xa5, 0x66, 0x26, 0x7c, 0x63, 0x76, 0xc9, 0xc9, + 0xf7, 0x4c, 0x2d, 0xe0, 0x21, 0x4b, 0xd0, 0x1c, 0x28, 0x13, 0x6a, 0x71, 0x1a, 0x76, 0x15, 0x6c, + 0xe2, 0x56, 0xe0, 0xa7, 0x83, 0xd7, 0x12, 0xe2, 0x63, 0x1a, 0xe3, 0x23, 0x5a, 0x9b, 0xd5, 0x00, + 0x69, 0xa7, 0xb0, 0x28, 0x58, 0xfb, 0xe3, 0x14, 0xfe, 0x6c, 0xeb, 0x70, 0xb3, 0xfa, 0x7d, 0x0a, + 0xdb, 0xdf, 0xce, 0x08, 0xa9, 0x3f, 0xfa, 0x20, 0x6c, 0xd3, 0x2e, 0x12, 0xa8, 0x13, 0xf2, 0x28, + 0x88, 0x9a, 0xb0, 0x64, 0xaf, 0x9e, 0x1c, 0x4b, 0x52, 0xc9, 0x19, 0xa8, 0x31, 0x9c, 0x95, 0x98, + 0x62, 0xab, 0x6c, 0x87, 0x87, 0xf1, 0xd0, 0x4a, 0xdd, 0x4f, 0xb1, 0x21, 0xdb, 0x50, 0x2f, 0x81, + 0xd9, 0xea, 0xe4, 0x52, 0xdd, 0x2c, 0x72, 0x48, 0x3d, 0xe1, 0x74, 0x30, 0x89, 0x58, 0xe0, 0x8d, + 0xe0, 0x86, 0xf9, 0x07, 0x54, 0x9a, 0x0e, 0xef, 0xf9, 0x48, 0xe6, 0x9b, 0x93, 0xc1, 0xa0, 0xd9, + 0x8c, 0x27, 0x7d, 0xb4, 0xf6, 0x23, 0x2a, 0xf8, 0x24, 0xc1, 0x40, 0xf1, 0x7a, 0xc4, 0x0c, 0x17, + 0x1a, 0xfa, 0x95, 0xdf, 0xbd, 0x1d, 0x40, 0x22, 0xf0, 0x82, 0x4f, 0xcd, 0xfd, 0xea, 0x89, 0x7b, + 0x07, 0xbb, 0x9e, 0x9a, 0x30, 0xbb, 0xb1, 0xa7, 0x62, 0x5a, 0xc4, 0xdb, 0x0d, 0x97, 0x5f, 0xc7, + 0x21, 0xd6, 0x3e, 0x7a, 0xae, 0x61, 0xfd, 0x50, 0xeb, 0xe5, 0x78, 0x22, 0x59, 0x48, 0x02, 0x43, + 0xbd, 0x2e, 0xca, 0x2b, 0x1e, 0x67, 0x46, 0x7c, 0xab, 0xd1, 0x16, 0x2b, 0x31, 0x71, 0x1f, 0x22, + 0xa7, 0x2c, 0x7a, 0x9b, 0xbb, 0x0f, 0x67, 0x1c, 0x62, 0xf1, 0xbb, 0x43, 0x0e, 0x4c, 0x0f, 0x74, + 0xeb, 0x35, 0x2e, 0x27, 0x22, 0x45, 0xb3, 0xae, 0xcf, 0xcf, 0x26, 0x20, 0xad, 0x1f, 0xf9, 0x90, + 0x69, 0xbf, 0x4d, 0x4c, 0x1d, 0xee, 0xd9, 0x93, 0x8e, 0x58, 0x58, 0xe8, 0x0b, 0x16, 0x86, 0x70, + 0x97, 0x9f, 0xe0, 0x1d, 0xd9, 0x2b, 0x0d, 0x85, 0x62, 0x94, 0x13, 0x29, 0x51, 0x8c, 0x03, 0x18, + 0xdf, 0x6d, 0x01, 0xa3, 0x43, 0x53, 0x17, 0x85, 0x10, 0xd4, 0xcd, 0x20, 0x05, 0xd2, 0xda, 0x99, + 0x84, 0xd7, 0x36, 0xba, 0xd5, 0x25, 0x95, 0x2e, 0xa7, 0xd2, 0xf0, 0xfe, 0x88, 0xce, 0x81, 0xd6, + 0x0e, 0x89, 0x53, 0xab, 0x2b, 0xd7, 0x3e, 0x7b, 0xe7, 0x34, 0x84, 0x7c, 0xc8, 0x9c, 0xa6, 0x03, + 0x28, 0x13, 0xaf, 0x41, 0x35, 0xc8, 0xbb, 0x8d, 0x78, 0xff, 0x69, 0x3a, 0x20, 0xc9, 0xcf, 0x39, + 0xec, 0x51, 0xd1, 0xce, 0x43, 0x4e, 0x02, 0x06, 0xca, 0x1a, 0xb2, 0x64, 0xd9, 0xb4, 0x40, 0xc8, + 0xb2, 0x5e, 0x2c, 0x26, 0x7e, 0xea, 0xd9, 0x6d, 0xf3, 0x06, 0xa7, 0x53, 0x8a, 0x49, 0x81, 0x8b, + 0x6b, 0xec, 0xe5, 0xeb, 0x07, 0xdf, 0xfb, 0x66, 0xc2, 0x47, 0x98, 0x2f, 0xd5, 0x6e, 0x75, 0x6a, + 0x07, 0xb2, 0xdc, 0xc0, 0xfa, 0x3f, 0xd7, 0x3c, 0xc4, 0x92, 0xaa, 0x53, 0xd9, 0x28, 0x45, 0x06, + 0xcf, 0x01, 0x6a, 0xeb, 0xf9, 0x6f, 0x03, 0x0e, 0x80, 0x89, 0x46, 0xb0, 0x2d, 0xe8, 0xd7, 0x87, + 0xa4, 0xd9, 0x04, 0xd9, 0xcf, 0xd2, 0xa9, 0xe0, 0x37, 0x4d, 0xb0, 0x7b, 0x99, 0xdb, 0xa2, 0x60, + 0xc0, 0xa7, 0x1e, 0x71, 0xba, 0x37, 0xf6, 0x6e, 0xc5, 0xdd, 0x52, 0x44, 0x0e, 0x21, 0x0a, 0xec, + 0xdb, 0x00, 0x28, 0xf3, 0x1c, 0x2e, 0x0f, 0x8b, 0x67, 0x20, 0xeb, 0xf2, 0x7e, 0x6e, 0x01, 0x5b, + 0x73, 0x33, 0xb0, 0xd7, 0x07, 0x8e, 0xf2, 0x57, 0x47, 0x65, 0x17, 0xf8, 0x2a, 0x95, 0x45, 0x6b, + 0x66, 0xf7, 0x71, 0x68, 0x6f, 0x7a, 0x2e, 0x4c, 0xaa, 0x40, 0x14, 0x92, 0xaa, 0xe3, 0x69, 0xb3, + 0xbf, 0x3b, 0xb4, 0xb0, 0x41, 0x2e, 0xd0, 0xd0, 0xb4, 0x17, 0x87, 0xb7, 0x82, 0xf0, 0xf0, 0x52, + 0x0b, 0xf2, 0xa5, 0x58, 0xf3, 0x45, 0x2f, 0x62, 0xe1, 0x3e, 0xe2, 0xe3, 0x65, 0x9a, 0xcf, 0x05, + 0x37, 0x1a, 0xb5, 0xc7, 0x08, 0xac, 0x52, 0xba, 0x12, 0xc8, 0x7c, 0xce, 0x45, 0xae, 0x9d, 0xe2, + 0x0c, 0xd3, 0x95, 0xdb, 0xd0, 0x0c, 0xd8, 0x6c, 0x82, 0x0c, 0xbf, 0xe7, 0xc0, 0x60, 0xc4, 0x21, + 0x1e, 0x91, 0x55, 0x59, 0x79, 0x0f, 0x05, 0x78, 0xfd, 0x6e, 0x0b, 0x59, 0xaa, 0xb8, 0x86, 0x9e, + 0xc9, 0xaa, 0xe1, 0x1c, 0xd2, 0xcf, 0x31, 0xd0, 0x4b, 0x49, 0xe6, 0x93, 0x3d, 0xe3, 0x1d, 0x00, + 0x7a, 0xf5, 0x35, 0x37, 0x51, 0xf4, 0x11, 0xcb, 0xe8, 0x33, 0x21, 0x26, 0x3c, 0xe2, 0xc5, 0x37, + 0xcb, 0x94, 0xbf, 0xf0, 0x96, 0x50, 0xd5, 0x35, 0x2d, 0x86, 0x3b, 0x37, 0x90, 0xea, 0x38, 0x72, + 0x8d, 0xec, 0xdc, 0x70, 0x2b, 0x80, 0xd5, 0x6d, 0x3f, 0x85, 0x35, 0xe5, 0x4c, 0xb5, 0x97, 0x0c, + 0x4a, 0x51, 0x46, 0x89, 0x60, 0xc0, 0x63, 0x3b, 0x40, 0x01, 0xfe, 0xec, 0x26, 0x23, 0x34, 0xf1, + 0xa8, 0x36, 0x0c, 0x42, 0x49, 0xdb, 0x0a, 0x1e, 0xd0, 0xf7, 0xa7, 0xc6, 0x5f, 0xf4, 0x8b, 0x3b, + 0x71, 0x02, 0x96, 0x17, 0x24, 0x96, 0x28, 0x96, 0xd6, 0x00, 0xa3, 0x1c, 0xd9, 0x2c, 0xeb, 0x99, + 0x51, 0xa3, 0xd2, 0x75, 0xc6, 0x55, 0xaa, 0xb2, 0xa9, 0x5b, 0xee, 0xdf, 0x96, 0x38, 0xe8, 0xe0, + 0x7b, 0xbd, 0x39, 0x3c, 0xd9, 0x6d, 0x55, 0xae, 0xf9, 0x2c, 0x00, 0x5e, 0x1a, 0xd4, 0xd1, 0xce, + 0x4b, 0x5c, 0xfe, 0x1b, 0x37, 0xa8, 0xa3, 0x27, 0x52, 0x91, 0xf9, 0x79, 0x62, 0x85, 0x09, 0xa4, + 0xe6, 0xf3, 0x7d, 0xa1, 0x6f, 0x7f, 0xef, 0x0a, 0x3e, 0x29, 0xb8, 0xab, 0x2c, 0xef, 0xbb, 0x59, + 0xe8, 0x98, 0x51, 0xa2, 0xae, 0x77, 0x9a, 0x9c, 0x47, 0x76, 0x30, 0x38, 0xed, 0xb8, 0x82, 0x9b, + 0xee, 0x4b, 0x67, 0x82, 0xec, 0x74, 0xee, 0x51, 0x84, 0x99, 0x77, 0xa0, 0x50, 0x13, 0xb8, 0x75, + 0x51, 0x1f, 0xce, 0x06, 0x1d, 0x3f, 0x5a, 0x65, 0x72, 0x9a, 0x8f, 0x1a, 0xfc, 0x2d, 0x68, 0x09, + 0x66, 0x9a, 0xc4, 0xb2, 0x67, 0x2e, 0x19, 0x8d, 0x3d, 0x23, 0x84, 0x7b, 0xd4, 0x19, 0x2b, 0x1a, + 0x7c, 0x70, 0xe6, 0x21, 0x2d, 0x02, 0x8c, 0xf5, 0xf9, 0x8b, 0x4f, 0x90, 0xb4, 0xb4, 0x51, 0x7f, + 0x10, 0x3c, 0xe3, 0xe7, 0x44, 0xd2, 0x9d, 0x31, 0xa9, 0xf4, 0x83, 0xe2, 0x69, 0x08, 0x84, 0x29, + 0xa6, 0x6d, 0x88, 0x7e, 0xd1, 0xba, 0x75, 0x2c, 0x42, 0x93, 0xb8, 0xd6, 0x66, 0xff, 0x9c, 0x4a, + 0x74, 0xcb, 0x71, 0xa0, 0x9f, 0x5e, 0x49, 0x67, 0x2f, 0x93, 0x4f, 0x1c, 0xa3, 0x87, 0x34, 0x1a, + 0x73, 0xc2, 0x8e, 0x8e, 0x99, 0x5e, 0x3a, 0x60, 0x0d, 0x82, 0x87, 0xf5, 0x38, 0x2c, 0xd4, 0x8a, + 0x23, 0x88, 0x98, 0x76, 0xd3, 0x4f, 0xe7, 0x39, 0x5e, 0x0e, 0x97, 0x8c, 0x71, 0x99, 0x67, 0x9b, + 0x45, 0x75, 0xbf, 0x11, 0x2a, 0x6c, 0x08, 0x39, 0x6a, 0x52, 0x74, 0x21, 0xce, 0xb6, 0xd3, 0x42, + 0x46, 0x91, 0x5d, 0x98, 0x40, 0xfd, 0xed, 0x09, 0xbb, 0xe2, 0xce, 0x77, 0xa1, 0xf2, 0x56, 0x10, + 0x33, 0x7b, 0xc2, 0x3a, 0x95, 0xfd, 0xf3, 0x49, 0x42, 0x4e, 0x9a, 0x7b, 0xce, 0x66, 0xe4, 0xba, + 0x3b, 0x2d, 0x63, 0x42, 0xb4, 0xa5, 0x74, 0x61, 0xa0, 0xe0, 0x48, 0xfc, 0xa1, 0x2d, 0xa2, 0xf7, + 0x69, 0x48, 0xb8, 0xcc, 0x38, 0x04, 0x54, 0x0a, 0x12, 0xf8, 0xe5, 0xe8, 0x89, 0x7d, 0x7c, 0x33, + 0xa1, 0xce, 0xc4, 0x4d, 0x71, 0x2d, 0x65, 0x43, 0xe5, 0x8f, 0xb8, 0x49, 0x4f, 0x95, 0x76, 0x4c, + 0x36, 0xb9, 0x4a, 0xfb, 0x1c, 0x21, 0x21, 0xd8, 0x1f, 0x45, 0x2d, 0x99, 0xab, 0x50, 0xca, 0xc2, + 0x6e, 0xe5, 0x6a, 0xce, 0xd1, 0x0c, 0x19, 0xdc, 0x3b, 0x61, 0x6a, 0x6b, 0x7d, 0xb8, 0x20, 0x08, + 0x16, 0x90, 0x37, 0x72, 0xb6, 0xdf, 0xf0, 0xaf, 0xf3, 0xbc, 0x0a, 0xc4, 0xa5, 0xfe, 0x52, 0xe2, + 0x58, 0x66, 0x1c, 0xaa, 0x0e, 0xfa, 0xd5, 0xce, 0x86, 0x07, 0x89, 0x6b, 0xac, 0x49, 0xa3, 0x8a, + 0xa2, 0xbd, 0x49, 0x1a, 0x99, 0x8f, 0xb0, 0xb3, 0x84, 0x5f, 0xe7, 0x69, 0x67, 0xf8, 0xd3, 0xc8, + 0x27, 0x60, 0x2d, 0x68, 0x91, 0xb7, 0xf4, 0x8c, 0x01, 0xf9, 0xcb, 0xe8, 0x26, 0x28, 0xdf, 0x6f, + 0xc7, 0x8a, 0x55, 0x2a, 0x8a, 0x0f, 0x23, 0x2c, 0x3c, 0x51, 0x03, 0xcb, 0xb7, 0x82, 0x6d, 0x92, + 0xec, 0x5d, 0xf4, 0x67, 0x72, 0x9c, 0xb7, 0xc1, 0x78, 0x9b, 0x8f, 0x31, 0x61, 0x1d, 0x6d, 0x0e, + 0xfd, 0x00, 0xa1, 0x34, 0x56, 0x8b, 0xe0, 0x6e, 0xba, 0xfd, 0x03, 0x45, 0x82, 0x36, 0xb1, 0x88, + 0x9b, 0x33, 0xd5, 0xd9, 0xeb, 0xa6, 0x95, 0xbc, 0xdc, 0xbf, 0xdb, 0x6e, 0x4c, 0xbf, 0x56, 0x3f +}; + +#define composite44_ed25519_msg composite_test_msg + +static const uint8_t composite44_ed25519_add_random[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const uint8_t composite44_ed25519_sig_digest[] = { + 0x60, 0x61, 0x06, 0x7a, 0xa0, 0x87, 0xfa, 0x2d, 0x77, 0xbb, 0x97, 0xeb, 0xe5, 0xc5, 0xc6, 0x34, + 0xee, 0x36, 0x51, 0xb9, 0xc4, 0xce, 0xbb, 0xa1, 0x4e, 0x25, 0x87, 0x7d, 0x43, 0xc7, 0xc5, 0x72 +}; + +static const uint8_t composite44_ed25519_sig[] = { + 0x2d, 0x49, 0xaa, 0x8a, 0x67, 0x9c, 0xde, 0x9c, 0x55, 0xec, 0xf3, 0x1c, 0xa2, 0xf2, 0xcd, 0x13, + 0x73, 0x7a, 0x0b, 0x04, 0x98, 0xeb, 0x91, 0xf4, 0x8f, 0xa9, 0x8a, 0x63, 0xab, 0xfa, 0x7b, 0xca, + 0x5b, 0xd5, 0xcf, 0x85, 0xc8, 0x02, 0xd0, 0x46, 0xb3, 0xe6, 0xec, 0x70, 0x09, 0xa3, 0xe6, 0xd1, + 0x6e, 0x80, 0x7e, 0x19, 0xf9, 0x38, 0x9d, 0xf2, 0xdd, 0xf0, 0xf8, 0x22, 0x32, 0x3e, 0xa7, 0x55, + 0x48, 0x4f, 0x8a, 0x22, 0x89, 0xe3, 0xf9, 0xdb, 0x0c, 0xb7, 0xdd, 0x52, 0x19, 0x09, 0x32, 0x87, + 0x8a, 0x2f, 0xac, 0xb6, 0x5d, 0x2f, 0x2c, 0xe3, 0x63, 0x6d, 0xb6, 0xc8, 0xfa, 0xd8, 0x0b, 0x66, + 0x10, 0xd3, 0x4c, 0x27, 0xda, 0x72, 0xa4, 0x64, 0xd1, 0x83, 0xa2, 0x9e, 0xc0, 0xde, 0x9a, 0xea, + 0x38, 0x68, 0x29, 0xc2, 0x73, 0x76, 0x4f, 0x51, 0xa1, 0x79, 0xb4, 0x08, 0xa8, 0xc3, 0x16, 0x35, + 0xdd, 0x3f, 0x4a, 0xd3, 0x9c, 0xb8, 0x90, 0x3c, 0xb4, 0x8d, 0x34, 0x0d, 0x3d, 0x09, 0xdd, 0x5a, + 0xa9, 0x9b, 0x75, 0x5a, 0x83, 0xee, 0xb6, 0x81, 0xcb, 0xb2, 0x30, 0xe6, 0x9b, 0xc7, 0x88, 0xb0, + 0xab, 0x3e, 0x23, 0x7d, 0x10, 0x9b, 0x9c, 0x67, 0xeb, 0x12, 0x27, 0x56, 0xa1, 0x31, 0x89, 0x27, + 0x3a, 0x43, 0x7d, 0x6e, 0x3f, 0x5c, 0x85, 0xc5, 0x5d, 0xec, 0xff, 0x79, 0xc7, 0xb8, 0xe2, 0x00, + 0x7c, 0x7f, 0xad, 0xf1, 0x8c, 0x9d, 0x08, 0x34, 0x14, 0x16, 0x3c, 0x57, 0x93, 0xaf, 0xa2, 0xfc, + 0x2f, 0x19, 0x5a, 0xc7, 0xd1, 0x66, 0x1d, 0x19, 0xb2, 0x1c, 0x33, 0x98, 0x85, 0x3a, 0x68, 0x3e, + 0x69, 0x02, 0x2c, 0xdc, 0x47, 0xb8, 0xb6, 0x6c, 0xf5, 0x0c, 0x87, 0xd8, 0x1b, 0x0b, 0xa7, 0xf4, + 0xf5, 0x0e, 0xcf, 0x13, 0x7a, 0x02, 0x90, 0x95, 0x8a, 0xbc, 0x7a, 0x2b, 0xe8, 0x9c, 0xb6, 0x05, + 0xb3, 0x65, 0xc6, 0xf6, 0x5b, 0xe7, 0xef, 0x1d, 0x30, 0x1a, 0xa9, 0x09, 0xc7, 0xcd, 0xd2, 0x0a, + 0xaf, 0x62, 0xf9, 0xba, 0x22, 0xbe, 0x65, 0xce, 0x42, 0xe5, 0xe3, 0x53, 0xf3, 0x14, 0x64, 0xf0, + 0x1e, 0xf4, 0x08, 0x7f, 0x83, 0x69, 0xa5, 0x96, 0x64, 0xcd, 0x56, 0x95, 0x50, 0x9e, 0xda, 0x59, + 0x7d, 0x73, 0xd9, 0xef, 0xa3, 0xef, 0xb4, 0xa8, 0x76, 0x65, 0x60, 0xe4, 0xb0, 0xbe, 0x9e, 0xde, + 0x84, 0x45, 0xa9, 0x48, 0xdb, 0xda, 0x02, 0x4c, 0x73, 0x8f, 0x4c, 0x2e, 0x21, 0x24, 0x1a, 0xa1, + 0xfc, 0xe9, 0x2d, 0xde, 0xb0, 0x39, 0x13, 0xc9, 0x36, 0x04, 0x9a, 0x12, 0x6b, 0x02, 0xb4, 0x2e, + 0xe0, 0x87, 0xd5, 0xa7, 0x0c, 0x74, 0xea, 0x61, 0xb5, 0x5d, 0x75, 0xc8, 0xee, 0xb8, 0x42, 0x4f, + 0x63, 0xd2, 0x6e, 0xc0, 0xaf, 0xcb, 0xd0, 0xad, 0xc2, 0x11, 0xc9, 0x23, 0xda, 0x81, 0x20, 0x90, + 0x4d, 0xdd, 0xf5, 0x4c, 0x2b, 0xd4, 0x2d, 0x41, 0x48, 0xbb, 0x2b, 0xc7, 0xbd, 0x19, 0x54, 0x78, + 0xd7, 0xb4, 0x89, 0x28, 0x9e, 0x43, 0x8c, 0xd9, 0xf2, 0xe7, 0xc7, 0x72, 0x6e, 0xf0, 0x7e, 0xcb, + 0x93, 0xe2, 0xf2, 0x30, 0x01, 0xb7, 0x6a, 0x66, 0x27, 0x45, 0x9f, 0x0a, 0x90, 0xfb, 0xab, 0x82, + 0xa6, 0x37, 0xb5, 0x3a, 0xde, 0x95, 0x07, 0x61, 0x48, 0xd3, 0xd6, 0x9e, 0x55, 0x1a, 0x2f, 0xe1, + 0xaf, 0x20, 0x4e, 0x0c, 0xac, 0x9f, 0xde, 0x0a, 0x30, 0x5e, 0x17, 0xf5, 0x3b, 0xb3, 0x4e, 0xb1, + 0x12, 0x32, 0x2d, 0xd7, 0xe9, 0x5a, 0xea, 0x75, 0x70, 0x0f, 0xd8, 0x2b, 0x05, 0xd6, 0xbd, 0x62, + 0x5f, 0xa9, 0x90, 0x88, 0xca, 0x02, 0x83, 0xc1, 0x11, 0xd4, 0xd8, 0x27, 0x2b, 0x39, 0xd1, 0x96, + 0x69, 0x78, 0x84, 0x14, 0xa7, 0x17, 0x67, 0xa8, 0x00, 0x5e, 0xa7, 0x61, 0xe1, 0xa4, 0xc2, 0x46, + 0x45, 0xe9, 0x29, 0xfa, 0x8d, 0xbb, 0x67, 0xf4, 0xc7, 0x50, 0x29, 0xc4, 0x64, 0x84, 0x64, 0xb2, + 0x1a, 0x65, 0x45, 0x7d, 0x2f, 0x39, 0x7b, 0x96, 0xe4, 0x01, 0x74, 0x26, 0x4b, 0xe4, 0xba, 0x90, + 0x62, 0xf0, 0x6c, 0x00, 0xf7, 0x58, 0x0e, 0xd0, 0xed, 0x4c, 0xcc, 0x4f, 0x35, 0xa3, 0x29, 0xd7, + 0x42, 0x1d, 0x5c, 0xed, 0x63, 0x4a, 0xe5, 0xd0, 0x2b, 0x04, 0x16, 0xd5, 0x1a, 0xa1, 0xde, 0xe4, + 0x4d, 0xe5, 0xe6, 0x60, 0x3c, 0x47, 0x3f, 0x16, 0x6c, 0xea, 0xde, 0xd3, 0xd0, 0x22, 0x15, 0xeb, + 0x1a, 0x29, 0x9b, 0x43, 0x68, 0x11, 0x76, 0x3e, 0x88, 0xe3, 0x1d, 0x1e, 0x0d, 0xf1, 0x08, 0x9c, + 0xd2, 0x23, 0x4a, 0x05, 0x4e, 0x35, 0xba, 0x3d, 0xc3, 0xf7, 0xc7, 0x26, 0xeb, 0x8f, 0x07, 0xa4, + 0x93, 0xc3, 0x06, 0x56, 0xb1, 0xdc, 0x02, 0x55, 0x66, 0x4e, 0x67, 0x9d, 0xaf, 0x24, 0x0e, 0x5b, + 0x70, 0x90, 0x55, 0x3d, 0x41, 0x3e, 0xbb, 0xc0, 0xd2, 0x4e, 0x0a, 0xd7, 0x3e, 0x3b, 0x43, 0xef, + 0xb7, 0xad, 0x8f, 0x49, 0x9c, 0xcd, 0x1c, 0x0e, 0xb0, 0x0d, 0xbc, 0x3d, 0xd1, 0x83, 0x04, 0xc4, + 0x7d, 0x00, 0x35, 0x29, 0xb8, 0x33, 0x51, 0xf7, 0x23, 0xf9, 0xeb, 0xc4, 0x80, 0x6d, 0xa9, 0xc6, + 0x72, 0x19, 0x2d, 0xb5, 0xaf, 0x82, 0x58, 0x5b, 0x83, 0xe8, 0x35, 0xb2, 0xd9, 0x17, 0x0e, 0xbb, + 0x9e, 0x46, 0xed, 0xe2, 0x4e, 0x34, 0x0d, 0x77, 0x85, 0x5d, 0xc8, 0x0c, 0x3b, 0xe0, 0xf9, 0x5e, + 0xca, 0x4c, 0xbd, 0x92, 0xe7, 0xbe, 0x98, 0x7b, 0xee, 0x99, 0xf3, 0x4f, 0xa6, 0x86, 0x24, 0xbc, + 0x90, 0xfa, 0x2d, 0xe5, 0xc2, 0xd6, 0xeb, 0x32, 0xc4, 0x09, 0x10, 0xd6, 0x14, 0xeb, 0x49, 0x7f, + 0x1a, 0xfd, 0xa0, 0x4f, 0x9a, 0xb4, 0xe9, 0xbc, 0x5c, 0xc6, 0x33, 0xd0, 0x8d, 0x1f, 0x23, 0xef, + 0xfb, 0xd7, 0x3f, 0x82, 0xf0, 0xd3, 0xa0, 0xee, 0x71, 0xb4, 0x2d, 0x69, 0x51, 0x83, 0x68, 0xa1, + 0xe7, 0x84, 0xaf, 0x77, 0xcd, 0xb4, 0x83, 0xe6, 0x77, 0x1a, 0x1d, 0xed, 0x16, 0x23, 0xe4, 0x03, + 0x57, 0x78, 0xf1, 0x83, 0xc2, 0x50, 0xea, 0x90, 0x3e, 0x5a, 0x58, 0x20, 0x84, 0x92, 0xed, 0xf2, + 0x79, 0x7c, 0x5f, 0x16, 0xbd, 0xc4, 0x33, 0xa4, 0x1f, 0x8a, 0x5a, 0x24, 0x6e, 0xf6, 0x18, 0xd1, + 0x3e, 0x3a, 0x0c, 0xcc, 0x04, 0xe0, 0x1b, 0xa4, 0xef, 0x09, 0x88, 0x79, 0x98, 0x09, 0xf8, 0x1e, + 0x0a, 0xf2, 0xfb, 0x81, 0x23, 0xb7, 0x1a, 0xae, 0x61, 0xa6, 0xa4, 0x96, 0x9f, 0xd2, 0x76, 0xd5, + 0x0c, 0x7e, 0x14, 0x72, 0x8c, 0x38, 0xff, 0x58, 0x42, 0x66, 0x75, 0xcc, 0xc6, 0x31, 0xc8, 0x81, + 0x69, 0x60, 0x57, 0x48, 0x1b, 0x38, 0x61, 0xcc, 0xde, 0xca, 0x89, 0x8a, 0xf3, 0x5e, 0x8c, 0xfa, + 0x72, 0x58, 0x29, 0x5f, 0xc6, 0x7b, 0x75, 0x04, 0x7e, 0x4d, 0xc1, 0xd5, 0x3e, 0x5c, 0x25, 0x68, + 0x10, 0xea, 0xbc, 0xd4, 0x58, 0x8c, 0x1c, 0xdd, 0xe6, 0x1c, 0x6d, 0xaf, 0x83, 0x55, 0x7d, 0x3d, + 0xbf, 0xb7, 0xe7, 0x32, 0x84, 0x87, 0xf3, 0x5e, 0x6a, 0x1a, 0xe8, 0x02, 0x8b, 0x4c, 0xea, 0x6b, + 0xd2, 0xe7, 0x36, 0xdb, 0x27, 0xf3, 0x54, 0x46, 0x1a, 0xa8, 0x2b, 0xcc, 0x60, 0xc6, 0x95, 0x21, + 0xf8, 0x12, 0x41, 0x49, 0xf6, 0x9a, 0x81, 0x13, 0x6c, 0x64, 0x8f, 0x83, 0x4b, 0xb9, 0x8e, 0xc7, + 0xaa, 0x03, 0xb5, 0xcf, 0xfc, 0x52, 0x93, 0x7f, 0x12, 0xf1, 0x52, 0x41, 0x2e, 0x58, 0x6b, 0x05, + 0xc4, 0x54, 0xcd, 0x50, 0xfd, 0x1b, 0x9c, 0xc4, 0xa3, 0x52, 0xaa, 0xa3, 0xa5, 0x3f, 0xb3, 0x4b, + 0x80, 0xc4, 0xec, 0x91, 0xaf, 0xc2, 0xfa, 0x95, 0x87, 0x1c, 0xb9, 0xf6, 0x70, 0x7a, 0x2e, 0x10, + 0x90, 0x05, 0xab, 0xe1, 0x6f, 0x54, 0x82, 0x0e, 0x98, 0xd1, 0x50, 0x56, 0x18, 0x99, 0xbf, 0xf6, + 0x0c, 0x11, 0x59, 0x0c, 0x46, 0xbe, 0x67, 0x4a, 0x4b, 0x3f, 0x79, 0x51, 0xc5, 0x30, 0x51, 0x4a, + 0x7f, 0x84, 0x8b, 0xc4, 0x80, 0x1a, 0x1b, 0x27, 0x64, 0xb6, 0xb6, 0xb2, 0x81, 0xcf, 0x6c, 0x4e, + 0xfe, 0x3b, 0x31, 0x27, 0x48, 0x87, 0x1f, 0x52, 0xa0, 0xe6, 0x6e, 0x32, 0xe0, 0xdb, 0x5f, 0x82, + 0x79, 0x68, 0x2c, 0x07, 0x27, 0xdc, 0x80, 0xdb, 0xa0, 0x65, 0x23, 0x35, 0xea, 0xec, 0x95, 0x70, + 0x26, 0xf0, 0x43, 0x9e, 0x11, 0xfd, 0x17, 0x10, 0x29, 0x71, 0x2c, 0x67, 0x39, 0xe7, 0x0f, 0x29, + 0x12, 0x70, 0x20, 0x3c, 0xe5, 0xa3, 0x98, 0x0d, 0xa8, 0x68, 0x59, 0xe0, 0xd4, 0x63, 0xdb, 0xb1, + 0x0d, 0x27, 0xb6, 0x3e, 0x6a, 0x87, 0x88, 0x90, 0x2b, 0xa7, 0xda, 0x24, 0x3a, 0x88, 0x8a, 0x74, + 0xbf, 0x8d, 0x5f, 0x71, 0x7e, 0xb2, 0xa9, 0xde, 0xf4, 0x2f, 0x07, 0x71, 0xdd, 0xe1, 0x07, 0xee, + 0x71, 0xe8, 0x1a, 0xd8, 0xcd, 0x79, 0x2d, 0xa9, 0xf5, 0xb1, 0x8a, 0x9b, 0xe2, 0xfd, 0xad, 0x2f, + 0x4b, 0x0b, 0x35, 0xd7, 0xe1, 0xc1, 0x28, 0x71, 0x2c, 0x78, 0xef, 0x1f, 0x91, 0xb8, 0x94, 0x5f, + 0x42, 0xb2, 0xcb, 0xe2, 0x86, 0xce, 0x1b, 0xec, 0x98, 0xfb, 0x6f, 0xf5, 0x46, 0xfc, 0x48, 0x26, + 0x67, 0x91, 0x61, 0x43, 0x1f, 0x09, 0x0f, 0x6d, 0xf6, 0xd2, 0x90, 0xef, 0xc9, 0xf2, 0x1b, 0x31, + 0x7c, 0x9c, 0xa1, 0xb7, 0x70, 0x52, 0x00, 0x0a, 0x32, 0x0d, 0x28, 0xca, 0x2c, 0x32, 0x87, 0xfd, + 0xdd, 0xd6, 0x68, 0x63, 0xc0, 0x34, 0xb4, 0xd9, 0x44, 0xbf, 0x07, 0xdd, 0x72, 0xec, 0x3e, 0xcf, + 0x9e, 0x51, 0x08, 0x04, 0x65, 0xc9, 0x98, 0x4f, 0x83, 0x80, 0x10, 0x00, 0xff, 0x61, 0x73, 0xfd, + 0xcb, 0x2d, 0x83, 0xf6, 0xfd, 0x5e, 0xf1, 0xf8, 0x5f, 0xc0, 0xc4, 0xe2, 0xf3, 0xf5, 0x31, 0x82, + 0xae, 0x61, 0xb2, 0xec, 0x97, 0x15, 0xf7, 0x42, 0xdc, 0xb2, 0x75, 0x24, 0xe9, 0x50, 0x71, 0xea, + 0xac, 0x0f, 0x67, 0x4f, 0x6b, 0x35, 0xf2, 0x49, 0xf2, 0xdc, 0x0c, 0xd8, 0xd5, 0x60, 0x67, 0x24, + 0xe5, 0x66, 0x0f, 0xa6, 0xd1, 0xb9, 0x8d, 0x8a, 0xdd, 0xb3, 0x2b, 0xbf, 0xf5, 0xae, 0x6b, 0x55, + 0xb1, 0xbc, 0xfc, 0x4d, 0xf9, 0xa4, 0x0b, 0x31, 0x97, 0x74, 0x2c, 0xf8, 0x5e, 0xc3, 0x88, 0x94, + 0x64, 0x78, 0x9a, 0x46, 0xc1, 0x41, 0xe9, 0x4c, 0xc5, 0x78, 0x60, 0x36, 0x81, 0xaf, 0xa0, 0x54, + 0x77, 0xf1, 0xfb, 0x1b, 0xe2, 0xf9, 0xae, 0xc5, 0xb3, 0x0b, 0xa5, 0x4f, 0x43, 0xd3, 0xf7, 0xf2, + 0x91, 0xc7, 0xf4, 0xeb, 0x69, 0x3c, 0x28, 0xaa, 0x5b, 0x6a, 0xc1, 0xf5, 0x6a, 0x7d, 0x72, 0x11, + 0x5a, 0x4e, 0x46, 0x34, 0x73, 0x97, 0x5d, 0xab, 0x73, 0xe9, 0xdb, 0xb6, 0x19, 0xd7, 0xb1, 0x36, + 0x9b, 0xce, 0x14, 0x0e, 0xeb, 0x99, 0xd2, 0x57, 0x72, 0xb1, 0x75, 0x07, 0xdd, 0x22, 0x7f, 0x9b, + 0xef, 0xab, 0xc2, 0x12, 0x97, 0x10, 0xa4, 0x8f, 0xf7, 0xe0, 0xe9, 0xd9, 0x8a, 0xb8, 0x31, 0x55, + 0xb5, 0x75, 0xd6, 0xce, 0x88, 0x13, 0x2b, 0x22, 0xa4, 0x1b, 0xeb, 0x0a, 0xdd, 0x20, 0xc0, 0x00, + 0xa8, 0x86, 0x35, 0x30, 0x2b, 0x6f, 0xdf, 0x40, 0x60, 0xb8, 0xb3, 0xf7, 0x9e, 0xd5, 0xf3, 0xb3, + 0xad, 0x4c, 0xcb, 0xa8, 0xaa, 0x63, 0x25, 0xc4, 0x1f, 0x47, 0xe6, 0x55, 0x48, 0xf2, 0x30, 0xa8, + 0x21, 0xd2, 0x6b, 0x81, 0xc3, 0xaa, 0x71, 0x8a, 0x32, 0x0c, 0x21, 0xd3, 0x06, 0x1d, 0xcc, 0xb5, + 0x69, 0xbc, 0x2f, 0xd4, 0x0c, 0x13, 0xd1, 0xcd, 0x46, 0x96, 0xd2, 0x55, 0xf5, 0x6a, 0x6c, 0x1e, + 0x9d, 0x95, 0x72, 0x91, 0x83, 0x46, 0x8c, 0x0e, 0x80, 0xaa, 0xec, 0x32, 0xa3, 0x97, 0x87, 0x40, + 0x87, 0xb3, 0x83, 0xff, 0xa2, 0x1b, 0xad, 0xad, 0x99, 0xdb, 0xdb, 0xe6, 0x61, 0x69, 0x03, 0x03, + 0xfa, 0xd0, 0x9d, 0x8f, 0x7c, 0x5e, 0x7b, 0x8a, 0x8f, 0xc6, 0x21, 0x86, 0xf2, 0x5f, 0x18, 0xfd, + 0x84, 0x66, 0xff, 0xa7, 0x4d, 0xab, 0x7d, 0x72, 0x31, 0xef, 0xb4, 0x91, 0x66, 0xb9, 0x82, 0xe5, + 0xea, 0x4a, 0xc2, 0xb1, 0x94, 0xe8, 0x3e, 0xdd, 0xd6, 0x50, 0x57, 0x65, 0x5d, 0x28, 0xdc, 0xec, + 0xb3, 0x20, 0x05, 0x45, 0xcb, 0x85, 0xd4, 0x86, 0x1c, 0x58, 0xe2, 0x26, 0x6e, 0x00, 0x99, 0x1d, + 0x7a, 0xfc, 0x8f, 0x78, 0xf9, 0xf9, 0x5f, 0x67, 0x75, 0x95, 0x68, 0xfe, 0xdb, 0x85, 0x23, 0x32, + 0xfa, 0x43, 0x17, 0x35, 0x80, 0xf7, 0x0b, 0xb3, 0x47, 0x04, 0x7a, 0x1f, 0xf4, 0xb5, 0xbe, 0x32, + 0x61, 0xc8, 0xd3, 0x02, 0x1b, 0xad, 0x98, 0x8a, 0x4c, 0x80, 0xa1, 0x05, 0xd8, 0x4d, 0xaa, 0xcb, + 0x74, 0x71, 0xe9, 0x3e, 0x37, 0xb4, 0x73, 0x97, 0x4d, 0x32, 0xc8, 0x74, 0x1f, 0x18, 0x33, 0xca, + 0x36, 0x8d, 0x0f, 0xec, 0xae, 0x20, 0x59, 0xee, 0x81, 0x40, 0x76, 0x19, 0x37, 0x50, 0xfe, 0x5f, + 0x21, 0x2e, 0xf0, 0x11, 0xf0, 0x14, 0x53, 0xf5, 0x45, 0xb2, 0x51, 0x0f, 0xf2, 0xa4, 0x76, 0x46, + 0xda, 0xfa, 0x0f, 0x00, 0x33, 0x6b, 0x9a, 0x5d, 0x75, 0x8e, 0xb8, 0xe8, 0xf2, 0xf1, 0xe4, 0x30, + 0x5e, 0xd9, 0x3c, 0xdb, 0xe6, 0xb0, 0x23, 0xa6, 0xf1, 0x3a, 0x92, 0x83, 0x9f, 0x10, 0x5d, 0x45, + 0x02, 0x75, 0x73, 0x6a, 0x8a, 0x3c, 0x50, 0x1b, 0x6a, 0x65, 0x83, 0x5e, 0xcc, 0x44, 0x26, 0xa7, + 0x17, 0xe1, 0x17, 0x81, 0xc3, 0x53, 0xe1, 0xab, 0xc0, 0x8a, 0x5e, 0x92, 0x4a, 0x3b, 0xb5, 0xe5, + 0xd6, 0x94, 0xcb, 0x2e, 0x72, 0x6d, 0x1a, 0xd0, 0x79, 0xd4, 0x5d, 0xa1, 0x09, 0x45, 0x5a, 0x2c, + 0x43, 0xaf, 0x68, 0x62, 0x40, 0x8c, 0xf3, 0x32, 0xaa, 0xc6, 0xc4, 0xa1, 0xda, 0x44, 0xa8, 0xee, + 0xdb, 0x1f, 0x00, 0x3e, 0xb1, 0x00, 0x6d, 0x69, 0x5d, 0x9c, 0x8c, 0xb1, 0xb3, 0x19, 0x05, 0xda, + 0x98, 0x40, 0xf3, 0x8c, 0x31, 0x65, 0x3f, 0xd0, 0xa0, 0x7a, 0x1b, 0x02, 0x0d, 0xaa, 0x6e, 0x58, + 0xa0, 0x27, 0x91, 0x5c, 0x29, 0xfe, 0xbd, 0x68, 0x8d, 0x0d, 0xad, 0x43, 0xf7, 0xaf, 0x66, 0x3b, + 0x08, 0xac, 0x73, 0x0e, 0xd5, 0x5b, 0x46, 0xbf, 0x10, 0xde, 0x80, 0xec, 0x53, 0xb9, 0x37, 0x37, + 0xdd, 0xf6, 0x0d, 0xbf, 0xf2, 0xc7, 0xb6, 0x78, 0xe8, 0xf0, 0x0f, 0xd7, 0xc7, 0xc9, 0x3e, 0xbb, + 0x78, 0x0a, 0x05, 0x71, 0xde, 0x35, 0x9d, 0xd8, 0x42, 0xcc, 0x39, 0x6f, 0x6c, 0x47, 0x98, 0x11, + 0x6f, 0x88, 0x20, 0x8b, 0xa3, 0x24, 0xa4, 0x76, 0x23, 0xd9, 0xb1, 0x11, 0xb9, 0x74, 0xe2, 0x26, + 0xcf, 0xf8, 0x2e, 0x6c, 0x4c, 0x48, 0xfa, 0x89, 0xa6, 0x88, 0xfa, 0x32, 0xa9, 0x8b, 0x7c, 0xcd, + 0x34, 0x2b, 0xda, 0x3b, 0x6e, 0x06, 0x07, 0xbd, 0x96, 0x5a, 0x00, 0x1e, 0x35, 0x33, 0x26, 0xa9, + 0xa0, 0x90, 0x98, 0x39, 0x16, 0x8c, 0xec, 0x45, 0x42, 0x7d, 0x25, 0x65, 0x6e, 0xc7, 0x12, 0x3a, + 0x8f, 0xd1, 0x1c, 0x62, 0x1b, 0x70, 0xa6, 0x84, 0xea, 0xc7, 0x3a, 0x94, 0xb8, 0xbd, 0x8c, 0x47, + 0x8d, 0xc5, 0x4b, 0x59, 0xd8, 0x97, 0x8b, 0x45, 0xa9, 0x1a, 0x5e, 0x13, 0xd0, 0x58, 0xa5, 0x4a, + 0x0d, 0x12, 0x2d, 0xb9, 0x9e, 0x16, 0xb4, 0x5d, 0xe2, 0x0c, 0x89, 0xf7, 0xa1, 0xe7, 0x8b, 0x8a, + 0x9e, 0x01, 0x18, 0x66, 0x08, 0xaa, 0x4c, 0x15, 0x3d, 0xc0, 0x56, 0x3e, 0x3c, 0xfd, 0x28, 0x81, + 0x7f, 0xd7, 0xc5, 0xc2, 0x29, 0x2d, 0x9c, 0xe5, 0xc4, 0xe1, 0x86, 0xeb, 0x5f, 0xa8, 0x01, 0xb5, + 0x9a, 0x18, 0x15, 0x40, 0xe9, 0x25, 0xfb, 0x8d, 0xc8, 0x83, 0x1a, 0x93, 0x13, 0x3b, 0x14, 0xc0, + 0x38, 0xb2, 0xa1, 0x4e, 0x61, 0xf2, 0x3b, 0x39, 0xc3, 0x1e, 0x17, 0xed, 0x93, 0x29, 0xfd, 0xb0, + 0x32, 0x11, 0x9b, 0xce, 0x2b, 0x05, 0xc4, 0x67, 0xc7, 0xa5, 0x7b, 0x20, 0x49, 0x90, 0x02, 0x3c, + 0xd7, 0xb3, 0x73, 0x7b, 0x00, 0xd9, 0x44, 0xeb, 0x73, 0x29, 0x8b, 0x52, 0x51, 0xba, 0xe0, 0xb1, + 0x9f, 0xe3, 0x1c, 0x13, 0x51, 0xd5, 0x13, 0x32, 0xee, 0xe4, 0xb5, 0x2a, 0x50, 0xb9, 0x3c, 0x78, + 0xf7, 0xf7, 0xd2, 0xe2, 0x0c, 0xcb, 0x1d, 0xa7, 0xb2, 0xc6, 0xeb, 0xaa, 0xc9, 0x3b, 0xb3, 0x55, + 0x3a, 0x81, 0xa7, 0x05, 0x3a, 0xd5, 0x6e, 0xfc, 0xa5, 0x8a, 0x59, 0xf5, 0x07, 0xea, 0x53, 0xb2, + 0x60, 0x3c, 0xa6, 0xe7, 0xf4, 0x61, 0x8e, 0xe7, 0x7b, 0xa8, 0x03, 0xe1, 0xe4, 0xba, 0xeb, 0x26, + 0xb4, 0x9d, 0x6b, 0xa4, 0x19, 0x2a, 0xfd, 0x7e, 0x03, 0x82, 0x67, 0x7e, 0x71, 0x7c, 0x85, 0xa1, + 0x04, 0x0b, 0xf3, 0xac, 0xdd, 0x79, 0xb2, 0x1e, 0x71, 0x9e, 0x6f, 0xeb, 0xff, 0xe5, 0x06, 0xe4, + 0x9e, 0x65, 0xe4, 0x94, 0x4c, 0x64, 0x80, 0x77, 0xa6, 0x8e, 0x2c, 0x20, 0x4f, 0xe1, 0x0d, 0x90, + 0xa5, 0xfb, 0x8a, 0x31, 0x55, 0x8a, 0x60, 0x99, 0xf2, 0x31, 0x2d, 0x45, 0x07, 0xeb, 0x2c, 0x48, + 0x83, 0x88, 0x7d, 0x3a, 0xeb, 0x4e, 0x25, 0x1a, 0x9b, 0x0b, 0x16, 0x7b, 0xe6, 0x34, 0x0f, 0x84, + 0x23, 0x7a, 0x62, 0x4e, 0x65, 0x89, 0xea, 0x09, 0x8f, 0xb4, 0x03, 0x6c, 0x57, 0x1b, 0xf4, 0xf3, + 0xa9, 0x6a, 0x51, 0xdb, 0x2e, 0xbd, 0x86, 0x67, 0xba, 0x3a, 0x49, 0xec, 0xd3, 0x58, 0xd0, 0xef, + 0x78, 0xbf, 0xc3, 0x7f, 0x71, 0x92, 0x52, 0xd6, 0x57, 0xa5, 0x13, 0xa9, 0x42, 0x35, 0x34, 0x7b, + 0xe3, 0xfd, 0x95, 0xf6, 0xc9, 0x54, 0x3e, 0xfc, 0x7a, 0xae, 0xfb, 0x43, 0xfc, 0xad, 0xb6, 0x6d, + 0x42, 0x6c, 0x7b, 0x84, 0xac, 0xb1, 0xce, 0xdd, 0xe2, 0xe6, 0xe9, 0xec, 0xed, 0xee, 0x0a, 0x11, + 0x3f, 0x5f, 0x69, 0xa6, 0xd2, 0xd5, 0xe1, 0xe6, 0xf7, 0x00, 0x0f, 0x12, 0x15, 0x18, 0x1a, 0x1b, + 0x1f, 0x28, 0x2d, 0x2e, 0x34, 0x35, 0x40, 0x5a, 0x68, 0x6a, 0x76, 0x82, 0x8a, 0x9b, 0xad, 0xae, + 0xba, 0xc9, 0xf0, 0xfc, 0x2d, 0x30, 0x35, 0x64, 0x7a, 0x91, 0x92, 0xaa, 0xad, 0xb0, 0xbd, 0xbe, + 0xd3, 0xdc, 0xdf, 0xeb, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0e, 0x19, 0x34, 0x45, 0xbd, 0x63, 0x89, 0xed, 0xca, 0x1f, 0x95, 0x21, 0x91, 0x47, 0xab, 0x3e, + 0x48, 0x25, 0x9b, 0x08, 0x44, 0xb6, 0xea, 0x2a, 0x54, 0x32, 0x37, 0x31, 0xf3, 0x1d, 0x33, 0xb1, + 0xc9, 0x34, 0x74, 0x61, 0x29, 0xae, 0xb2, 0xf5, 0x5f, 0x57, 0xeb, 0x6a, 0x51, 0x5f, 0x23, 0xc0, + 0xea, 0xd3, 0x4b, 0xc1, 0xef, 0x12, 0xcc, 0x61, 0xf9, 0x86, 0x57, 0xdd, 0x87, 0x98, 0xfb, 0x50, + 0xab, 0x22, 0x51, 0x02 +}; + +/* --- ML-DSA-65-RSA3072-PKCS15-SHA512 --- */ +static const uint8_t composite65_rsa3072pkcs15_priv[] = { + 0x07, 0xba, 0x47, 0xb2, 0x3a, 0xb8, 0xac, 0xe7, 0x75, 0xba, 0x55, 0x3c, 0xae, 0x8e, 0xdc, 0xf6, + 0x91, 0xc9, 0x67, 0x3e, 0x7a, 0x94, 0xf1, 0x7d, 0x3d, 0x74, 0x3e, 0x0b, 0xac, 0x78, 0x97, 0x7f, + 0x30, 0x82, 0x06, 0xe3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x81, 0x00, 0x8b, 0xb4, 0xad, 0x5e, + 0x8c, 0xdf, 0x45, 0x97, 0x89, 0x36, 0x6b, 0x3c, 0xa2, 0x34, 0x3a, 0x10, 0x92, 0x8d, 0xd3, 0x2d, + 0x88, 0x65, 0xd2, 0xb2, 0x44, 0x28, 0xe7, 0xc9, 0x86, 0x19, 0x6e, 0xfe, 0x49, 0x6f, 0xe9, 0x34, + 0xd1, 0x92, 0x73, 0x7e, 0x80, 0x3c, 0xaf, 0x98, 0x86, 0x1e, 0x56, 0x89, 0x83, 0xb0, 0x7f, 0x61, + 0x09, 0x28, 0x65, 0xd8, 0x25, 0xfa, 0xac, 0x50, 0xc4, 0xc0, 0x13, 0xca, 0xad, 0xf1, 0xc1, 0x51, + 0x35, 0xa8, 0x75, 0xd7, 0xe3, 0xb7, 0xdb, 0xb4, 0x6a, 0xec, 0xf2, 0x0f, 0x73, 0x01, 0xcd, 0x67, + 0x4a, 0x0b, 0xaa, 0xfc, 0x58, 0x9c, 0x95, 0x4b, 0x79, 0xce, 0xc0, 0x43, 0x58, 0xec, 0x59, 0x97, + 0xd6, 0x91, 0x76, 0xfd, 0x43, 0xba, 0x4a, 0x41, 0x63, 0x49, 0x17, 0xe3, 0x4e, 0xf8, 0xc2, 0x35, + 0x63, 0x4e, 0xe2, 0x68, 0xc8, 0xb7, 0x2c, 0x1b, 0x9f, 0x70, 0x71, 0x4c, 0xb1, 0xfb, 0x1f, 0x77, + 0xff, 0xae, 0xf2, 0xd6, 0x9e, 0xbc, 0xff, 0x73, 0x7a, 0x49, 0x58, 0x27, 0x53, 0x1e, 0x6e, 0x66, + 0x16, 0xec, 0x97, 0x69, 0x68, 0xbd, 0xc8, 0x02, 0x7b, 0x47, 0x2d, 0xf5, 0xf9, 0xfc, 0xab, 0x3d, + 0x97, 0x1f, 0x02, 0x08, 0xce, 0x23, 0x33, 0xb0, 0xf5, 0xe6, 0xf3, 0xc6, 0x7b, 0x74, 0xb6, 0x99, + 0x7a, 0x2c, 0x54, 0xe8, 0xd0, 0xc6, 0x31, 0x35, 0x2a, 0x41, 0xf4, 0x78, 0x27, 0x25, 0x68, 0x4b, + 0x1e, 0xb2, 0x98, 0x00, 0xf2, 0x46, 0x4b, 0x30, 0x0f, 0x4f, 0x0a, 0x88, 0xfb, 0x9d, 0x5d, 0x9d, + 0x53, 0x1a, 0x88, 0x61, 0x6f, 0x2c, 0xa2, 0xcd, 0x11, 0x16, 0x29, 0xcb, 0xfa, 0x1a, 0x5d, 0xaa, + 0x5a, 0x52, 0xf7, 0xf0, 0x31, 0xf5, 0xb5, 0x7f, 0xfd, 0x32, 0x2e, 0xce, 0x24, 0x9c, 0xf2, 0x0a, + 0x6d, 0x8d, 0xfc, 0x6b, 0x29, 0x7b, 0x3f, 0x10, 0xd3, 0x24, 0x21, 0x79, 0x2f, 0x35, 0x6a, 0x41, + 0x3a, 0x65, 0x93, 0x4f, 0x9c, 0x4c, 0xed, 0x1e, 0x6e, 0x9b, 0xc1, 0x38, 0x9e, 0xa0, 0x5d, 0x78, + 0x2d, 0x91, 0x6d, 0x08, 0x64, 0x7e, 0x14, 0x06, 0xd5, 0x76, 0x81, 0x23, 0x9e, 0x2a, 0xa0, 0xb0, + 0xb9, 0x0d, 0x8d, 0x41, 0x38, 0xe7, 0xe6, 0x23, 0x11, 0x15, 0x86, 0xc4, 0x36, 0xf6, 0x4f, 0x1b, + 0x9e, 0xbc, 0xac, 0x88, 0xc8, 0xec, 0x8d, 0xf0, 0xdf, 0xa4, 0xed, 0x78, 0xc9, 0x80, 0xa5, 0xac, + 0xac, 0x41, 0xb5, 0x42, 0xae, 0x34, 0x58, 0x82, 0xd8, 0x17, 0x47, 0x10, 0x32, 0xba, 0x54, 0xa1, + 0xdf, 0xa8, 0x42, 0x24, 0x30, 0xac, 0xcf, 0xdb, 0xa3, 0x3f, 0x47, 0xe1, 0x3d, 0xea, 0x8d, 0x05, + 0x08, 0x44, 0xe9, 0xc1, 0x48, 0x1c, 0x0b, 0xcb, 0x39, 0x8e, 0x4f, 0x12, 0x59, 0x27, 0x02, 0xe4, + 0xb8, 0x27, 0x29, 0xd1, 0xe4, 0x0b, 0xfb, 0x74, 0x76, 0xd1, 0x41, 0x83, 0x02, 0x03, 0x01, 0x00, + 0x01, 0x02, 0x82, 0x01, 0x80, 0x0c, 0x83, 0xd0, 0xc7, 0x63, 0x09, 0x8f, 0x3e, 0x38, 0xc1, 0xa2, + 0x0f, 0xf4, 0xf1, 0xdb, 0xc5, 0x11, 0xf3, 0xd8, 0x2d, 0x40, 0x86, 0x3f, 0xe9, 0x23, 0x42, 0x4c, + 0xd2, 0x98, 0x8b, 0x87, 0xb8, 0xb4, 0xd3, 0x17, 0x1f, 0x84, 0x54, 0x96, 0x64, 0x5d, 0xd0, 0x27, + 0x3a, 0x1b, 0xc2, 0xf4, 0xfa, 0x98, 0x4c, 0x43, 0xcf, 0x94, 0x01, 0x45, 0x44, 0xfc, 0x7b, 0x52, + 0x5b, 0x61, 0x3c, 0xae, 0xfe, 0x88, 0x35, 0x86, 0x1d, 0x4f, 0x18, 0x0f, 0xb2, 0x6e, 0xc8, 0xfb, + 0x75, 0x53, 0xe2, 0x1f, 0xa4, 0x5d, 0xa7, 0x95, 0x83, 0x16, 0xb6, 0xd3, 0xdd, 0x8b, 0x81, 0xea, + 0x12, 0x85, 0xa4, 0xb7, 0xee, 0xc5, 0xdf, 0xaa, 0x53, 0xa2, 0x9a, 0x36, 0x55, 0x65, 0x6f, 0x4c, + 0x93, 0xed, 0xf5, 0x25, 0x74, 0x2c, 0x90, 0xb6, 0x89, 0x0f, 0x79, 0x33, 0x69, 0x5d, 0x42, 0xf7, + 0x6b, 0x0e, 0xb8, 0x85, 0x15, 0xc5, 0xed, 0xda, 0x8e, 0xfb, 0xdd, 0xc1, 0x62, 0xe8, 0xd1, 0x17, + 0xcb, 0x26, 0xf3, 0x12, 0x0d, 0x62, 0x71, 0xf1, 0x44, 0x28, 0xf2, 0x8f, 0x1f, 0xc2, 0x0d, 0x1a, + 0x31, 0x35, 0x62, 0x40, 0xce, 0x43, 0xa8, 0xd6, 0xf2, 0xe0, 0xaa, 0x46, 0x45, 0x8b, 0xfd, 0xca, + 0xf5, 0x79, 0x19, 0xc9, 0x7b, 0x08, 0x22, 0x82, 0x47, 0x09, 0x12, 0xeb, 0xea, 0x4d, 0x3a, 0xd6, + 0x91, 0x4e, 0x29, 0xf4, 0x0b, 0x26, 0x2c, 0x8c, 0x4e, 0x1a, 0xc4, 0x20, 0x97, 0x86, 0x4a, 0x24, + 0x37, 0x66, 0x80, 0x9b, 0x26, 0xde, 0xb8, 0x51, 0xca, 0x63, 0xa4, 0x65, 0xf5, 0x02, 0x01, 0x03, + 0x93, 0xbe, 0x05, 0x58, 0x11, 0x61, 0xde, 0x3b, 0xce, 0x38, 0x82, 0xc4, 0x5e, 0xa2, 0x36, 0xa4, + 0x56, 0x38, 0x1b, 0xa2, 0x10, 0x90, 0xb0, 0x8f, 0xc7, 0xac, 0x7f, 0xeb, 0x4e, 0x3b, 0x25, 0xfd, + 0x3e, 0xd9, 0xac, 0x6a, 0x72, 0x99, 0x96, 0xf3, 0x9c, 0x11, 0xb2, 0x0c, 0x76, 0x74, 0xde, 0xb0, + 0xeb, 0xa5, 0x1c, 0x1e, 0x38, 0xfc, 0x60, 0xed, 0xda, 0xc4, 0x89, 0xe2, 0xfd, 0x4d, 0x33, 0xc4, + 0xef, 0xf2, 0x27, 0x3a, 0x19, 0x9e, 0x59, 0xcc, 0xb5, 0x94, 0xc9, 0x5a, 0xf4, 0xfe, 0xd2, 0xf0, + 0x81, 0x13, 0x56, 0x7d, 0xc8, 0x34, 0xec, 0x01, 0x5c, 0x83, 0x71, 0x24, 0x13, 0x39, 0x18, 0x73, + 0x79, 0x62, 0x0f, 0xee, 0xd0, 0x37, 0x52, 0xad, 0x82, 0xe2, 0x9e, 0xc8, 0xfe, 0x8f, 0x9f, 0x21, + 0x82, 0x15, 0x00, 0xe9, 0xa9, 0xde, 0x73, 0x10, 0xbf, 0x16, 0x58, 0xaa, 0x06, 0x82, 0x4a, 0xe5, + 0xf2, 0xa2, 0x13, 0x1b, 0x9d, 0xb1, 0xfa, 0xdf, 0x0c, 0x33, 0x66, 0x77, 0x43, 0x11, 0xc1, 0x8b, + 0xfe, 0x71, 0x1f, 0x7b, 0x4c, 0xae, 0x8b, 0xe4, 0x76, 0x23, 0x9a, 0x8d, 0xb8, 0x78, 0x98, 0xd2, + 0x4c, 0x48, 0x0a, 0x34, 0xb1, 0x02, 0x81, 0xc1, 0x00, 0xc4, 0xba, 0x4b, 0x13, 0x8d, 0x11, 0x60, + 0xeb, 0xa6, 0x40, 0x4d, 0xf6, 0xcb, 0x48, 0xf0, 0x52, 0x77, 0xca, 0xd6, 0x94, 0x39, 0x77, 0x85, + 0x4b, 0xe9, 0xb1, 0xb8, 0x7b, 0x9f, 0x14, 0x8f, 0xe0, 0xdc, 0x7c, 0xc9, 0x88, 0x3a, 0x69, 0x90, + 0x57, 0xd0, 0x69, 0x30, 0xf9, 0x68, 0x4c, 0x3a, 0x07, 0x33, 0x1a, 0x0a, 0x06, 0x4f, 0x64, 0xde, + 0xfc, 0x1f, 0x38, 0xd8, 0x9d, 0x5b, 0x2e, 0x26, 0x62, 0xb2, 0x82, 0x67, 0x69, 0x23, 0x4b, 0xba, + 0x36, 0x92, 0x10, 0x66, 0x08, 0xf5, 0xa6, 0x01, 0xaa, 0xcc, 0x3c, 0xe0, 0xc6, 0x7c, 0x49, 0x32, + 0x1c, 0x4b, 0x5e, 0xf1, 0x7c, 0x3f, 0x20, 0xf2, 0x9c, 0x4d, 0x51, 0x10, 0x5c, 0xe4, 0x94, 0x2e, + 0xf5, 0x81, 0x45, 0x4d, 0x92, 0x97, 0xf5, 0x6c, 0x0e, 0xaf, 0x58, 0xc1, 0xc5, 0x19, 0x91, 0xfd, + 0xb3, 0xab, 0x85, 0x9d, 0x6e, 0x3f, 0x49, 0x0e, 0x9c, 0xde, 0xe9, 0x62, 0x09, 0x71, 0x24, 0x6c, + 0x22, 0xa9, 0xb0, 0xe6, 0x2e, 0x71, 0x64, 0x9e, 0x8c, 0xab, 0x5b, 0x42, 0xd9, 0x2c, 0xd0, 0xa6, + 0xfd, 0x33, 0x34, 0x9b, 0x29, 0xca, 0xd5, 0x0c, 0x9b, 0xf8, 0xdf, 0x77, 0xd8, 0xdb, 0xbd, 0x92, + 0xae, 0x9d, 0x38, 0xfe, 0xd9, 0x9f, 0x77, 0x2d, 0xef, 0xf0, 0xb6, 0x74, 0x55, 0xef, 0x15, 0x9f, + 0xdb, 0x3f, 0x2f, 0xd9, 0x92, 0x2a, 0xb5, 0x9a, 0x53, 0x02, 0x81, 0xc1, 0x00, 0xb5, 0xcc, 0x40, + 0xd9, 0xbd, 0xd2, 0x2b, 0x1d, 0x39, 0x49, 0xa2, 0xa9, 0x25, 0xca, 0x5d, 0x11, 0x7e, 0x05, 0x98, + 0xa0, 0xe4, 0xb9, 0x3f, 0x18, 0xb1, 0x17, 0x83, 0x65, 0xf3, 0x3b, 0xfe, 0x04, 0xee, 0xd0, 0x8b, + 0xb8, 0x2d, 0xc7, 0x5e, 0x5c, 0xcc, 0x44, 0xb2, 0x89, 0x13, 0xaa, 0x64, 0x14, 0x19, 0x6d, 0x33, + 0x0c, 0xfa, 0xb4, 0x92, 0xd1, 0xf7, 0xdb, 0x06, 0x11, 0x7d, 0xa5, 0xa3, 0xcd, 0xbe, 0x91, 0xfa, + 0x85, 0x97, 0x0e, 0x4c, 0xdc, 0xd5, 0xe3, 0x94, 0xf1, 0x68, 0xd6, 0x17, 0x3d, 0x6a, 0x95, 0x19, + 0x90, 0x2d, 0xdd, 0x00, 0xd6, 0xc4, 0x48, 0xc3, 0xc5, 0x2a, 0xc9, 0xdb, 0x17, 0x83, 0x84, 0x00, + 0x07, 0x22, 0xb2, 0x9a, 0xb5, 0xd5, 0x55, 0x50, 0x19, 0x4a, 0xbd, 0xaa, 0xcd, 0x3f, 0xdc, 0x5c, + 0x4f, 0x66, 0x36, 0xf6, 0xe1, 0xbd, 0x0a, 0x87, 0x84, 0x05, 0x2b, 0x04, 0x20, 0xbd, 0xd5, 0xa6, + 0x21, 0xd7, 0x38, 0xb7, 0x38, 0x8a, 0x65, 0x3c, 0xa8, 0x1d, 0xa1, 0x48, 0x0f, 0x97, 0x76, 0xf1, + 0x30, 0x86, 0xb9, 0x71, 0xa9, 0x57, 0x82, 0xef, 0xd3, 0x6d, 0x85, 0x37, 0x07, 0x13, 0xb3, 0x6d, + 0x69, 0x85, 0x90, 0x49, 0x64, 0xd1, 0xbd, 0xd4, 0x68, 0xec, 0x48, 0x57, 0x6c, 0x5a, 0xda, 0x75, + 0xa0, 0xee, 0x00, 0x4b, 0x1a, 0xee, 0x7f, 0x24, 0x23, 0xc3, 0x69, 0xb6, 0x11, 0x02, 0x81, 0xc0, + 0x2b, 0xa4, 0x94, 0x81, 0x3a, 0xdb, 0x6f, 0x1f, 0xf8, 0x1a, 0xed, 0xf0, 0xe1, 0x3a, 0x46, 0x2e, + 0x55, 0x6b, 0x07, 0x5d, 0x8c, 0xbe, 0x2a, 0x31, 0x24, 0x20, 0x0c, 0x28, 0x48, 0xab, 0x5c, 0x1b, + 0xeb, 0x6e, 0x37, 0x9b, 0x64, 0x32, 0x05, 0x16, 0xa6, 0x22, 0x9f, 0xfd, 0xc4, 0x98, 0x9c, 0x8a, + 0xfa, 0x58, 0x3d, 0x7f, 0x16, 0xdf, 0xee, 0xe4, 0x09, 0xdd, 0x27, 0x99, 0x09, 0x20, 0x5c, 0xdd, + 0xaa, 0x72, 0x69, 0x94, 0x96, 0x82, 0xf7, 0x45, 0xa1, 0xf3, 0xc7, 0x5f, 0x17, 0x78, 0x03, 0x88, + 0xab, 0x94, 0x99, 0xdd, 0x0e, 0xb7, 0x82, 0x49, 0x6a, 0xa3, 0x1e, 0x79, 0x8c, 0xdb, 0xb7, 0x56, + 0xdb, 0x84, 0x2f, 0x58, 0x1c, 0x51, 0x8f, 0x75, 0x61, 0x7f, 0x49, 0x6d, 0x4b, 0x0e, 0xe4, 0x31, + 0x01, 0xcf, 0x73, 0xf5, 0x50, 0xed, 0xe5, 0x55, 0x95, 0xa8, 0xa7, 0xbb, 0x4c, 0x88, 0xdd, 0x98, + 0x09, 0x8f, 0xc6, 0xf3, 0x07, 0x49, 0xa8, 0x3f, 0xac, 0x5b, 0x95, 0x45, 0x1a, 0x5c, 0xd3, 0x1b, + 0xab, 0xec, 0x2c, 0x11, 0x57, 0xf2, 0xd6, 0x08, 0xf7, 0xf2, 0x24, 0xb6, 0x09, 0xcc, 0x67, 0xe6, + 0xb6, 0x38, 0x85, 0x32, 0xf3, 0xd4, 0xc3, 0x94, 0xbf, 0x46, 0x64, 0xab, 0x4c, 0xc8, 0x38, 0xc5, + 0xb1, 0x26, 0x18, 0xfa, 0xf3, 0x76, 0x5d, 0xa7, 0x5b, 0x06, 0x37, 0x83, 0x48, 0xbc, 0x4f, 0x07, + 0x02, 0x81, 0xc0, 0x57, 0x7a, 0xe1, 0xf9, 0xe5, 0x0d, 0xad, 0x11, 0x72, 0xef, 0xac, 0x06, 0x18, + 0xd9, 0x37, 0xcf, 0xa3, 0x04, 0xae, 0x5d, 0x3d, 0xb2, 0xa6, 0x5a, 0x0b, 0x5d, 0x75, 0x2d, 0x29, + 0xce, 0x44, 0x7d, 0xbb, 0x2d, 0x3f, 0x0e, 0x71, 0x78, 0xee, 0x3f, 0x59, 0x4b, 0xf5, 0x5d, 0x60, + 0xc9, 0x2d, 0x3f, 0x3e, 0xbc, 0xfd, 0x43, 0xd1, 0x9f, 0xf2, 0xc6, 0x76, 0xae, 0x3e, 0x4d, 0x4c, + 0x58, 0xd8, 0x69, 0xb8, 0xba, 0x26, 0x03, 0x02, 0x9d, 0x2e, 0xff, 0x55, 0x2d, 0x1e, 0x0e, 0xcc, + 0x93, 0xb8, 0xbb, 0x24, 0xfe, 0x7a, 0x3e, 0x96, 0xd3, 0x32, 0x04, 0x26, 0x8f, 0x9d, 0x24, 0xd3, + 0x62, 0x2e, 0xbb, 0x31, 0xdd, 0xe2, 0xe5, 0x8c, 0x1c, 0xc5, 0xb5, 0x99, 0xe2, 0x63, 0x98, 0xc8, + 0x0e, 0x5c, 0x92, 0x47, 0x98, 0x92, 0x12, 0xe2, 0xec, 0xb0, 0x00, 0x10, 0x27, 0x70, 0xee, 0x66, + 0x4e, 0x3c, 0xbe, 0x44, 0x9a, 0xfa, 0x46, 0x6e, 0x7a, 0x2c, 0x30, 0x58, 0xe8, 0x3e, 0x37, 0xe7, + 0x8a, 0x24, 0x52, 0xdc, 0x5f, 0xaf, 0xcf, 0xda, 0x04, 0x82, 0x5d, 0x2a, 0x6f, 0x27, 0x58, 0x65, + 0xeb, 0x24, 0x7f, 0x93, 0x4b, 0x53, 0xea, 0xe3, 0x0a, 0x7b, 0x46, 0xb8, 0x66, 0xd0, 0x3f, 0x6c, + 0xf3, 0xa2, 0x9d, 0xd1, 0x5a, 0x2e, 0x20, 0x32, 0x66, 0x91, 0xbd, 0x73, 0xe6, 0x5a, 0x4d, 0x9b, + 0x4a, 0xd3, 0x01, 0x02, 0x81, 0xc1, 0x00, 0xb7, 0xe9, 0x99, 0xc7, 0x39, 0xff, 0x13, 0x25, 0x0c, + 0x0f, 0xed, 0x77, 0xa4, 0x80, 0x59, 0x9b, 0x2f, 0x14, 0xfa, 0x8d, 0x12, 0xcd, 0xcf, 0xab, 0x30, + 0x26, 0x2a, 0x56, 0x41, 0x48, 0xd0, 0x1a, 0x76, 0x5f, 0xf9, 0xe6, 0x80, 0x8a, 0x4f, 0xaf, 0x4d, + 0x14, 0x33, 0x3f, 0x1d, 0x3a, 0x67, 0x6b, 0x59, 0x09, 0x23, 0x59, 0x37, 0x38, 0xdd, 0xcf, 0x16, + 0x4c, 0x4e, 0xe2, 0x61, 0x35, 0x32, 0x40, 0xa2, 0xca, 0x01, 0xcd, 0x4c, 0x4a, 0x0f, 0x37, 0x95, + 0xbc, 0x6b, 0xce, 0x95, 0x28, 0xcf, 0x38, 0x65, 0xd9, 0x9c, 0x7a, 0x0d, 0xec, 0xfe, 0xa8, 0x10, + 0x13, 0x60, 0x88, 0x99, 0xc9, 0x71, 0x67, 0x72, 0xbd, 0xbe, 0x87, 0xb9, 0xc7, 0xa7, 0x24, 0x79, + 0x83, 0x65, 0xa5, 0x22, 0x94, 0x61, 0xef, 0x61, 0x65, 0xd3, 0x7b, 0x35, 0x00, 0xe6, 0x18, 0xd2, + 0x36, 0xad, 0x75, 0xb9, 0xbc, 0xa1, 0x50, 0xdc, 0xe8, 0x46, 0x23, 0xd7, 0xb1, 0x7d, 0xe8, 0x79, + 0x37, 0xde, 0x73, 0xcb, 0xd5, 0x02, 0x57, 0xf4, 0x3a, 0x08, 0x26, 0xfe, 0x9d, 0x5f, 0x81, 0xf1, + 0xfe, 0x02, 0x6a, 0x16, 0xcf, 0x97, 0xae, 0x61, 0x87, 0x48, 0x4b, 0x8a, 0x48, 0x4e, 0x3d, 0x01, + 0xc4, 0x88, 0x22, 0xca, 0xca, 0x32, 0x71, 0x4d, 0xaa, 0x26, 0x20, 0x56, 0xbd, 0x75, 0xcf, 0x52, + 0x7a, 0xd1, 0x12, 0xdf, 0x93, 0xd1, 0xa1 +}; + +static const uint8_t composite65_rsa3072pkcs15_pub[] = { + 0x98, 0x49, 0x03, 0x2f, 0xd3, 0x08, 0xf6, 0x4f, 0xd3, 0xff, 0x97, 0xc4, 0x2e, 0x41, 0x76, 0x9e, + 0xf3, 0xd8, 0x7f, 0xfe, 0x32, 0x74, 0xe6, 0x74, 0x34, 0xd1, 0x80, 0x74, 0x47, 0xbe, 0x02, 0x05, + 0xd8, 0x8b, 0x9d, 0xb1, 0xed, 0xbf, 0xae, 0xdb, 0xd1, 0x1e, 0x8b, 0xab, 0xde, 0xff, 0x56, 0xb1, + 0xa7, 0x4a, 0xff, 0x44, 0x3b, 0xb3, 0x8f, 0xd4, 0xd0, 0xe0, 0x31, 0xf7, 0x25, 0x27, 0xb3, 0xed, + 0x53, 0x90, 0x61, 0xc3, 0x83, 0x7d, 0x51, 0xd4, 0x33, 0x06, 0x76, 0x10, 0xb3, 0x16, 0xc7, 0x4c, + 0xb7, 0x3b, 0xed, 0x16, 0xd6, 0x0a, 0x10, 0x9a, 0x76, 0x1f, 0x98, 0x47, 0x54, 0x64, 0xa5, 0x9c, + 0x36, 0x9b, 0x7a, 0x9e, 0x11, 0xd6, 0x66, 0xb0, 0x1b, 0x3e, 0x8b, 0x1d, 0xcf, 0x29, 0x5b, 0x88, + 0x24, 0x5f, 0xcb, 0xae, 0x68, 0xf7, 0xb9, 0xcb, 0x7b, 0xa4, 0x56, 0x95, 0xdb, 0x60, 0x25, 0xd9, + 0x97, 0xd6, 0x17, 0xe1, 0xc5, 0xd4, 0x87, 0x4a, 0x4f, 0xde, 0x3b, 0x02, 0x24, 0x1d, 0xbf, 0x93, + 0xcd, 0x48, 0x8e, 0xbc, 0xcc, 0x56, 0xbc, 0xd5, 0xe5, 0x93, 0xad, 0xd4, 0xe9, 0x94, 0x40, 0xff, + 0x63, 0x02, 0xdc, 0x64, 0x2c, 0xb8, 0xf6, 0xbd, 0x78, 0xd5, 0xa9, 0xa7, 0x2f, 0x2e, 0x91, 0x6e, + 0x99, 0xa0, 0xd7, 0x46, 0xa9, 0x94, 0x58, 0x3f, 0x40, 0xc9, 0x75, 0x76, 0xcf, 0xd2, 0x97, 0xf7, + 0x16, 0x33, 0xea, 0xe4, 0x87, 0x54, 0xcd, 0x23, 0x6d, 0xc9, 0xc2, 0x1c, 0x59, 0xd7, 0xc9, 0x0d, + 0xfe, 0x23, 0xc8, 0xae, 0x62, 0x9b, 0xab, 0xbf, 0x6e, 0x7f, 0x39, 0xe0, 0xb2, 0x2a, 0x30, 0x33, + 0x9a, 0xef, 0x94, 0xde, 0xd5, 0xd9, 0x8b, 0x3b, 0xe2, 0xfa, 0x8c, 0x98, 0xac, 0xc1, 0xc5, 0x5a, + 0x5d, 0x0a, 0xb6, 0x01, 0x7f, 0x30, 0x1d, 0xc3, 0x6b, 0x06, 0x49, 0x4b, 0x2a, 0x08, 0xf8, 0xcc, + 0x71, 0x98, 0xc8, 0x3a, 0xb2, 0x30, 0xda, 0x93, 0x13, 0xc6, 0xfb, 0x0e, 0x71, 0x52, 0xc1, 0xca, + 0x4e, 0x2b, 0x72, 0xef, 0x1f, 0xf2, 0x86, 0xe3, 0xea, 0x0b, 0x3e, 0x39, 0x32, 0x70, 0x74, 0xa0, + 0x74, 0x32, 0xd3, 0xe7, 0x92, 0xc4, 0x33, 0xf3, 0x4e, 0x33, 0x3a, 0x09, 0xe6, 0x18, 0x2f, 0xad, + 0xd1, 0x48, 0xae, 0x7a, 0x91, 0xff, 0xac, 0x9a, 0x28, 0xfe, 0x2b, 0xf8, 0x48, 0xb7, 0x58, 0x60, + 0x42, 0x7f, 0xe8, 0x16, 0x85, 0x90, 0xd3, 0x9c, 0xd1, 0x21, 0x40, 0xe4, 0x6c, 0x9c, 0x98, 0xde, + 0x7f, 0x62, 0x19, 0x8d, 0xa0, 0x13, 0xb6, 0x0e, 0x3b, 0xe1, 0xff, 0xd9, 0xda, 0xbb, 0xbf, 0x79, + 0xd1, 0x62, 0xf7, 0xfc, 0xdc, 0xbf, 0x9f, 0x9b, 0x9c, 0x0c, 0x05, 0x65, 0xc4, 0x26, 0x36, 0x3c, + 0x93, 0x05, 0x62, 0x4d, 0x5b, 0xd8, 0x6e, 0x4d, 0x81, 0x9e, 0x0f, 0xe2, 0xe2, 0x43, 0xc3, 0xd1, + 0x9e, 0x7b, 0x75, 0xfb, 0x84, 0x90, 0xcd, 0x10, 0xcd, 0x71, 0x31, 0x81, 0x8f, 0x84, 0xab, 0x1a, + 0x9c, 0x6a, 0xdf, 0xdd, 0xba, 0x85, 0xb6, 0xe4, 0x9b, 0x83, 0xdc, 0xcf, 0xac, 0xaf, 0x2c, 0x88, + 0x49, 0xe5, 0xd4, 0x00, 0x84, 0x13, 0x62, 0x65, 0x9f, 0xc9, 0x6e, 0x22, 0x58, 0xf8, 0x46, 0x7f, + 0x12, 0x87, 0xe1, 0x88, 0x29, 0xcd, 0x54, 0x6d, 0xa7, 0x5e, 0x49, 0xbc, 0x06, 0x96, 0x87, 0x96, + 0xe6, 0x2b, 0x8f, 0xd8, 0xb7, 0x56, 0xef, 0xff, 0x8f, 0x73, 0x89, 0x19, 0x73, 0xe1, 0xda, 0xac, + 0x92, 0x33, 0x1d, 0x79, 0x6d, 0x33, 0xe8, 0xc6, 0x5c, 0xc4, 0x67, 0x48, 0x30, 0xb4, 0x4f, 0x04, + 0xca, 0x50, 0x16, 0xe7, 0x97, 0x99, 0xdd, 0x4b, 0x92, 0x5c, 0xe9, 0xd7, 0xc2, 0x96, 0x18, 0x43, + 0x3b, 0x6c, 0x90, 0xb4, 0xcc, 0x2e, 0x94, 0x28, 0x66, 0xa6, 0x27, 0xfa, 0x42, 0x94, 0xaa, 0xb6, + 0x8d, 0x51, 0x1c, 0x58, 0xb3, 0x17, 0x97, 0x4b, 0xab, 0xc0, 0x58, 0x31, 0x51, 0xed, 0x9f, 0xa4, + 0x19, 0xf5, 0xdb, 0xf9, 0x57, 0x09, 0x2e, 0x68, 0x72, 0x2e, 0xec, 0x32, 0x8b, 0xf9, 0x8b, 0x5a, + 0x72, 0x36, 0xe0, 0x8d, 0x62, 0xc7, 0x33, 0xb8, 0x93, 0xf9, 0xc6, 0x2a, 0xe9, 0x8c, 0x0f, 0x5a, + 0xa6, 0xb1, 0xcd, 0x06, 0xfa, 0xe9, 0x24, 0xf1, 0x64, 0x66, 0xeb, 0xe9, 0xe8, 0x5c, 0x6a, 0x5e, + 0xfe, 0xca, 0x3e, 0x32, 0x42, 0xbf, 0x32, 0x2d, 0x1e, 0x79, 0xd5, 0x39, 0x7b, 0x00, 0xef, 0xa3, + 0x12, 0x54, 0x78, 0xd8, 0x85, 0xb6, 0x81, 0xde, 0x5e, 0x3c, 0xd1, 0x2b, 0x48, 0xd7, 0xb8, 0x0f, + 0x1f, 0xf6, 0xcf, 0xfb, 0xf5, 0xda, 0x6f, 0xab, 0x0c, 0xc4, 0xa3, 0x4c, 0xa3, 0x4a, 0xb7, 0xec, + 0x82, 0x16, 0x75, 0xcd, 0xa5, 0xdd, 0x85, 0x91, 0x27, 0x37, 0x05, 0x04, 0xcb, 0x97, 0xd4, 0xeb, + 0x65, 0x73, 0x32, 0x1e, 0xe8, 0x03, 0x9b, 0x53, 0x84, 0x95, 0x9a, 0xc9, 0x0f, 0x6e, 0x01, 0x00, + 0x91, 0x36, 0x08, 0x65, 0xab, 0xff, 0x81, 0xa9, 0x6c, 0x13, 0x2d, 0x32, 0xa9, 0xb0, 0x77, 0x10, + 0x6d, 0x06, 0x4c, 0x24, 0xa2, 0xc2, 0x68, 0x22, 0x09, 0x0c, 0xd5, 0x2a, 0x8d, 0x60, 0x15, 0xf6, + 0xbf, 0xbc, 0xc5, 0x53, 0xbc, 0xec, 0x89, 0x81, 0x11, 0xfc, 0xbb, 0x08, 0xfb, 0x4c, 0xb7, 0xd0, + 0xee, 0x50, 0xb8, 0xd7, 0x84, 0x02, 0xe0, 0x3c, 0x47, 0x05, 0x16, 0x71, 0xcf, 0x12, 0x44, 0x5d, + 0x49, 0x3b, 0xab, 0x05, 0xca, 0x3e, 0x31, 0x96, 0xdd, 0x6d, 0x88, 0xbe, 0x25, 0x9d, 0x6e, 0xe7, + 0x80, 0x50, 0xc4, 0xc2, 0x54, 0xbf, 0x04, 0x2b, 0x2d, 0x83, 0x06, 0xd1, 0x5e, 0x68, 0x75, 0xd9, + 0x13, 0x08, 0x29, 0x79, 0x58, 0xa3, 0xfb, 0x28, 0x84, 0x78, 0x87, 0x35, 0x9f, 0x04, 0x6a, 0x37, + 0x75, 0x90, 0x68, 0x4c, 0xc6, 0x85, 0xc0, 0x16, 0x79, 0x1f, 0x73, 0x15, 0x97, 0xd3, 0xd7, 0x5d, + 0x73, 0xf0, 0x56, 0xe9, 0x93, 0xee, 0xcb, 0x62, 0xc6, 0xd9, 0x6c, 0xc5, 0xce, 0xf5, 0x5a, 0x1e, + 0x5f, 0x82, 0x53, 0xf1, 0x2b, 0x4d, 0x50, 0xf8, 0xb8, 0x8f, 0x6c, 0x09, 0x2f, 0xdf, 0x7e, 0x14, + 0x29, 0xd9, 0x67, 0xe6, 0xef, 0x61, 0xe8, 0xc8, 0x76, 0xe2, 0x31, 0x06, 0xd7, 0x55, 0x51, 0x1a, + 0x76, 0x8a, 0x63, 0x2f, 0x93, 0x47, 0x5a, 0x73, 0x52, 0x9a, 0x5d, 0xfb, 0x5b, 0x60, 0xde, 0xa5, + 0x57, 0x43, 0xa3, 0xac, 0x30, 0x8e, 0x94, 0x02, 0x25, 0x0f, 0x02, 0x65, 0xc4, 0x06, 0x61, 0x4b, + 0x0f, 0x01, 0xd2, 0xe1, 0x6a, 0x48, 0xce, 0x90, 0xf7, 0x6e, 0xcb, 0xc0, 0xfc, 0xaf, 0x58, 0x7f, + 0xf4, 0x5c, 0x90, 0xab, 0xdb, 0x3e, 0x20, 0x13, 0x56, 0x3e, 0xeb, 0xac, 0x2d, 0x80, 0xce, 0x9e, + 0xd4, 0x4d, 0x5e, 0xd1, 0xd8, 0xf9, 0xd9, 0xb8, 0x46, 0xd7, 0x18, 0x0a, 0x3c, 0xf5, 0x61, 0xc3, + 0x9d, 0xa4, 0x12, 0x22, 0xf6, 0x92, 0xac, 0x6b, 0xb1, 0xd9, 0x12, 0x59, 0x7b, 0x20, 0x2a, 0xd6, + 0xf2, 0xb4, 0x8c, 0x1f, 0xc8, 0x47, 0x3f, 0xba, 0xec, 0x7b, 0xeb, 0x53, 0xdf, 0x31, 0xab, 0x98, + 0x60, 0x63, 0x62, 0x28, 0xad, 0x48, 0xef, 0x63, 0xb3, 0x24, 0xa8, 0xd5, 0xe0, 0x25, 0x57, 0xe3, + 0x9a, 0x91, 0x05, 0x08, 0xe5, 0x65, 0xf3, 0x51, 0x30, 0x33, 0x84, 0x5b, 0xd9, 0xe9, 0x3a, 0x50, + 0x26, 0xe4, 0x77, 0x5a, 0x8a, 0x29, 0xf8, 0x68, 0x89, 0x71, 0x79, 0x55, 0xb8, 0xc0, 0xd4, 0x9d, + 0xcf, 0x5e, 0x9c, 0x1f, 0x95, 0x69, 0x81, 0x84, 0x69, 0x61, 0x4c, 0x50, 0x93, 0x25, 0x64, 0xbe, + 0x59, 0x53, 0xb7, 0xc3, 0xd1, 0x16, 0xee, 0xf8, 0x81, 0xfd, 0xec, 0xa5, 0x7e, 0x82, 0xbd, 0x67, + 0xbf, 0x79, 0x00, 0xa9, 0xe4, 0xb1, 0x67, 0x2d, 0x98, 0x8f, 0xdf, 0x33, 0x99, 0xd6, 0xf0, 0x53, + 0x0f, 0x02, 0xe4, 0x10, 0xb8, 0xf6, 0xc1, 0x07, 0xcb, 0x2e, 0x55, 0xce, 0x58, 0x42, 0x50, 0x6d, + 0xb7, 0x51, 0x6d, 0x3a, 0x04, 0x49, 0x66, 0x15, 0xd5, 0x09, 0x2a, 0xd6, 0xdb, 0xe4, 0xe1, 0xc0, + 0xb8, 0xd1, 0xf0, 0x9b, 0xc1, 0x8f, 0x17, 0x3f, 0x5d, 0x97, 0x8e, 0x1b, 0x98, 0x60, 0x98, 0x29, + 0x01, 0x52, 0xd7, 0x3a, 0x1a, 0xb2, 0x5f, 0x67, 0x17, 0x8e, 0x2f, 0xc1, 0x51, 0x8a, 0x67, 0xee, + 0x7c, 0x3d, 0xd7, 0xaa, 0xbc, 0xa4, 0x3e, 0x94, 0xe8, 0x5e, 0xb8, 0x0a, 0x70, 0x65, 0xaa, 0x5c, + 0xfb, 0x49, 0x97, 0x6b, 0xf0, 0xd4, 0x3f, 0x10, 0x05, 0x02, 0x5d, 0xd2, 0xf2, 0xf2, 0x42, 0xd5, + 0x5f, 0xe4, 0x5c, 0xad, 0x89, 0x98, 0x65, 0x37, 0x81, 0xed, 0x47, 0x86, 0xda, 0x10, 0xd2, 0xc9, + 0xbd, 0x47, 0xcb, 0xe8, 0xae, 0x6d, 0xfd, 0x4b, 0x05, 0xdc, 0x54, 0x8b, 0xaa, 0xe3, 0xdf, 0xc4, + 0xfb, 0xde, 0x9f, 0x76, 0x44, 0xb5, 0xd6, 0x58, 0xae, 0xfe, 0xd4, 0x32, 0x39, 0x37, 0x47, 0xab, + 0x23, 0x73, 0x55, 0x64, 0x12, 0x2e, 0x27, 0x59, 0x1a, 0x58, 0x41, 0x3e, 0x0b, 0x82, 0x0b, 0xe2, + 0x24, 0x0f, 0x3d, 0x6d, 0x14, 0x48, 0xd0, 0x19, 0xfe, 0x03, 0x72, 0x32, 0x05, 0xda, 0x97, 0x2f, + 0xa7, 0x6c, 0x0a, 0x64, 0xa0, 0xba, 0x35, 0x6a, 0x89, 0x44, 0xf9, 0x16, 0xc0, 0xd8, 0x2d, 0x66, + 0x88, 0xfd, 0x5a, 0x7f, 0x28, 0xc9, 0x95, 0x15, 0xf2, 0x49, 0xb6, 0xa2, 0x51, 0xe4, 0xa1, 0xd4, + 0xd5, 0x88, 0x21, 0x26, 0x78, 0x50, 0xd1, 0x4d, 0xc6, 0xad, 0x29, 0x31, 0xea, 0xaa, 0xa3, 0x58, + 0x6a, 0xe3, 0xbe, 0x25, 0x40, 0xf3, 0x37, 0x54, 0x82, 0x88, 0x8a, 0x97, 0x3e, 0xa1, 0x22, 0xec, + 0xc7, 0x06, 0x4b, 0x31, 0x4f, 0xf8, 0xd1, 0x13, 0xa5, 0x0b, 0xca, 0x36, 0xa2, 0x28, 0x72, 0x81, + 0xc5, 0x10, 0x98, 0xd1, 0xc9, 0x36, 0xa7, 0x59, 0x17, 0x90, 0xdd, 0x4c, 0x9b, 0x64, 0x88, 0xfd, + 0x14, 0x7c, 0x66, 0x62, 0x3c, 0x80, 0x9d, 0xa5, 0xa8, 0xc6, 0xc0, 0xc7, 0xff, 0x55, 0x95, 0x09, + 0x68, 0x2d, 0x2b, 0x32, 0x61, 0x7b, 0x5f, 0x22, 0x8e, 0x1b, 0x3b, 0x6b, 0x2d, 0xad, 0x18, 0xa4, + 0x3e, 0xbb, 0x1e, 0x74, 0x87, 0x45, 0x33, 0x0b, 0x7a, 0x3c, 0xe7, 0x76, 0x5a, 0x8c, 0xd5, 0xe7, + 0x21, 0xca, 0xde, 0x4e, 0x64, 0x1f, 0x06, 0xf8, 0x5b, 0x5c, 0x52, 0x8c, 0xd1, 0xec, 0xed, 0x4d, + 0x10, 0x41, 0x6d, 0x8c, 0xd7, 0x55, 0x79, 0x9a, 0x57, 0x84, 0x9a, 0xee, 0xfc, 0xb7, 0x2d, 0xe8, + 0x98, 0xc9, 0x37, 0xc3, 0x80, 0x5d, 0x80, 0x36, 0x68, 0xa6, 0x12, 0x92, 0x34, 0x69, 0xc2, 0x18, + 0x0e, 0x93, 0x4a, 0xba, 0x29, 0x38, 0x30, 0x05, 0xe9, 0x11, 0x79, 0x4c, 0x0e, 0xe7, 0x3c, 0xb5, + 0xe8, 0x53, 0x3e, 0x50, 0x1a, 0x4e, 0xcd, 0x6f, 0x43, 0xd5, 0xb9, 0xa2, 0x71, 0xf5, 0x8f, 0x7e, + 0x95, 0x04, 0x53, 0x82, 0xe0, 0xfe, 0x6d, 0x59, 0xee, 0x30, 0x55, 0xc0, 0x83, 0xf7, 0x81, 0xcb, + 0xb3, 0x5d, 0xfb, 0xb7, 0x71, 0x48, 0x53, 0x17, 0xb8, 0xde, 0xba, 0xe2, 0x18, 0xf5, 0x5b, 0x3f, + 0x9d, 0x0a, 0x0a, 0xf7, 0x35, 0x83, 0x56, 0x74, 0x77, 0x21, 0x2c, 0xf5, 0xc0, 0x8c, 0x8f, 0x13, + 0x69, 0xc6, 0xb3, 0xdb, 0x24, 0x7c, 0xbf, 0x92, 0x7c, 0x2e, 0xae, 0x91, 0x5b, 0x61, 0x4e, 0x52, + 0x80, 0x2d, 0x0b, 0xf1, 0xd4, 0x0c, 0xc9, 0x31, 0xba, 0xb2, 0x7a, 0x16, 0x6a, 0xb5, 0x9e, 0x9b, + 0x31, 0xf9, 0x4b, 0x9f, 0xf6, 0x4d, 0xd3, 0x29, 0x82, 0x9b, 0xd3, 0x11, 0x02, 0xb7, 0xce, 0xc5, + 0xff, 0x11, 0xb4, 0x6e, 0xc1, 0x3a, 0x2e, 0xa4, 0xb3, 0x0e, 0xa3, 0x5a, 0xe6, 0x09, 0x62, 0x36, + 0x14, 0x16, 0xc6, 0x38, 0xdb, 0x2e, 0x5f, 0x16, 0x72, 0xde, 0x60, 0x10, 0xd0, 0x90, 0x3f, 0xd3, + 0x53, 0xc7, 0x0a, 0xb7, 0x5e, 0xf4, 0x66, 0x32, 0x7d, 0x05, 0x8e, 0x23, 0x54, 0xc1, 0xfb, 0x31, + 0x1f, 0x60, 0xdf, 0x96, 0xfc, 0x8d, 0x4c, 0x82, 0x6e, 0x15, 0x4c, 0x2f, 0x45, 0xa1, 0x96, 0xfb, + 0x28, 0x2d, 0x78, 0x44, 0x07, 0x7c, 0x78, 0x03, 0xe8, 0x01, 0x28, 0x44, 0x73, 0xd4, 0xac, 0x15, + 0x15, 0x20, 0xc2, 0xa2, 0x7d, 0x0c, 0xf8, 0x1b, 0xfb, 0xcc, 0x5b, 0x0a, 0x85, 0x81, 0xd6, 0x79, + 0xe1, 0xcd, 0x45, 0x12, 0xd8, 0xd4, 0x41, 0x5a, 0xd0, 0x3f, 0x35, 0x6c, 0x56, 0x4e, 0x53, 0x0d, + 0xa8, 0x62, 0xfd, 0xfb, 0x70, 0x38, 0xb9, 0x39, 0x30, 0x99, 0xe0, 0x4a, 0xf7, 0x6a, 0xce, 0x40, + 0xbb, 0x7d, 0x75, 0x11, 0xd0, 0xd4, 0x5b, 0x53, 0xcd, 0x32, 0x10, 0xaf, 0x0c, 0x03, 0xc8, 0x7e, + 0xd7, 0xd6, 0xb8, 0xf0, 0xab, 0x63, 0x69, 0xf2, 0x8b, 0xb7, 0x27, 0x86, 0xc2, 0xc6, 0x58, 0x46, + 0x19, 0x29, 0x39, 0xb6, 0x26, 0x60, 0xa1, 0x82, 0x25, 0x8f, 0x6c, 0x0c, 0x33, 0x2f, 0xd8, 0xa0, + 0x66, 0x5f, 0xd9, 0x91, 0x2e, 0xc9, 0x44, 0x84, 0xe3, 0x98, 0x06, 0xa3, 0x3c, 0x2f, 0x7b, 0x70, + 0x26, 0x59, 0x6d, 0x7a, 0x3f, 0x18, 0xce, 0xf5, 0x44, 0xd4, 0x0c, 0x16, 0x66, 0x87, 0xb2, 0x94, + 0x14, 0x3b, 0x60, 0xdf, 0xb7, 0x92, 0x56, 0x84, 0x15, 0xf8, 0xa8, 0x9a, 0x45, 0xd4, 0xa4, 0xa8, + 0x0f, 0xc0, 0xe8, 0xd8, 0xfd, 0x84, 0x4a, 0x5d, 0xb4, 0xbf, 0x6e, 0x7c, 0x5c, 0xd3, 0xa1, 0xab, + 0x06, 0x4d, 0x6e, 0xf4, 0xc9, 0x8a, 0x3a, 0x23, 0x70, 0x00, 0x14, 0x21, 0x08, 0xed, 0xdf, 0x7c, + 0xd9, 0xe5, 0x70, 0xf6, 0xb8, 0xc6, 0x63, 0x0c, 0x0d, 0x77, 0xe1, 0x0f, 0x27, 0x8c, 0xcc, 0xdf, + 0x4a, 0xee, 0x5c, 0x73, 0xa3, 0x67, 0x14, 0xeb, 0x7f, 0xb4, 0x37, 0xf5, 0xe4, 0x04, 0xca, 0x7f, + 0x44, 0x00, 0xaa, 0x33, 0x23, 0xa1, 0x90, 0xc4, 0xac, 0xdd, 0x01, 0x89, 0xa3, 0x56, 0xb3, 0x7c, + 0xc6, 0xe1, 0x66, 0x73, 0x33, 0x29, 0xec, 0xf6, 0x43, 0x5b, 0xc7, 0xf4, 0xb5, 0xc3, 0xdc, 0x96, + 0x6d, 0x85, 0x50, 0x17, 0xc4, 0xc1, 0x53, 0x03, 0xa7, 0xe5, 0x21, 0x76, 0x12, 0xa7, 0x7f, 0xe6, + 0x8f, 0x0a, 0x7d, 0xdd, 0xb6, 0xde, 0x0a, 0x63, 0x8f, 0xf2, 0xee, 0xe9, 0x32, 0x43, 0x27, 0xfc, + 0xda, 0xee, 0x15, 0xba, 0x3e, 0xa0, 0x45, 0x93, 0xeb, 0x22, 0x95, 0xaf, 0xfc, 0x6f, 0x2d, 0x49, + 0x8a, 0x00, 0x16, 0x02, 0x17, 0xeb, 0xb5, 0x7d, 0xdc, 0xc9, 0xf6, 0xce, 0x83, 0xa5, 0xcf, 0x8e, + 0xf1, 0x6e, 0xd3, 0x00, 0x0f, 0x6e, 0xa4, 0x56, 0xe9, 0xd7, 0x76, 0xb5, 0xa3, 0x23, 0x29, 0x5f, + 0x23, 0x9e, 0xca, 0xbe, 0x4f, 0x01, 0xcc, 0xef, 0xf9, 0x3c, 0xb1, 0x5b, 0xc7, 0xb3, 0xa8, 0x2f, + 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0x8b, 0xb4, 0xad, 0x5e, 0x8c, 0xdf, 0x45, + 0x97, 0x89, 0x36, 0x6b, 0x3c, 0xa2, 0x34, 0x3a, 0x10, 0x92, 0x8d, 0xd3, 0x2d, 0x88, 0x65, 0xd2, + 0xb2, 0x44, 0x28, 0xe7, 0xc9, 0x86, 0x19, 0x6e, 0xfe, 0x49, 0x6f, 0xe9, 0x34, 0xd1, 0x92, 0x73, + 0x7e, 0x80, 0x3c, 0xaf, 0x98, 0x86, 0x1e, 0x56, 0x89, 0x83, 0xb0, 0x7f, 0x61, 0x09, 0x28, 0x65, + 0xd8, 0x25, 0xfa, 0xac, 0x50, 0xc4, 0xc0, 0x13, 0xca, 0xad, 0xf1, 0xc1, 0x51, 0x35, 0xa8, 0x75, + 0xd7, 0xe3, 0xb7, 0xdb, 0xb4, 0x6a, 0xec, 0xf2, 0x0f, 0x73, 0x01, 0xcd, 0x67, 0x4a, 0x0b, 0xaa, + 0xfc, 0x58, 0x9c, 0x95, 0x4b, 0x79, 0xce, 0xc0, 0x43, 0x58, 0xec, 0x59, 0x97, 0xd6, 0x91, 0x76, + 0xfd, 0x43, 0xba, 0x4a, 0x41, 0x63, 0x49, 0x17, 0xe3, 0x4e, 0xf8, 0xc2, 0x35, 0x63, 0x4e, 0xe2, + 0x68, 0xc8, 0xb7, 0x2c, 0x1b, 0x9f, 0x70, 0x71, 0x4c, 0xb1, 0xfb, 0x1f, 0x77, 0xff, 0xae, 0xf2, + 0xd6, 0x9e, 0xbc, 0xff, 0x73, 0x7a, 0x49, 0x58, 0x27, 0x53, 0x1e, 0x6e, 0x66, 0x16, 0xec, 0x97, + 0x69, 0x68, 0xbd, 0xc8, 0x02, 0x7b, 0x47, 0x2d, 0xf5, 0xf9, 0xfc, 0xab, 0x3d, 0x97, 0x1f, 0x02, + 0x08, 0xce, 0x23, 0x33, 0xb0, 0xf5, 0xe6, 0xf3, 0xc6, 0x7b, 0x74, 0xb6, 0x99, 0x7a, 0x2c, 0x54, + 0xe8, 0xd0, 0xc6, 0x31, 0x35, 0x2a, 0x41, 0xf4, 0x78, 0x27, 0x25, 0x68, 0x4b, 0x1e, 0xb2, 0x98, + 0x00, 0xf2, 0x46, 0x4b, 0x30, 0x0f, 0x4f, 0x0a, 0x88, 0xfb, 0x9d, 0x5d, 0x9d, 0x53, 0x1a, 0x88, + 0x61, 0x6f, 0x2c, 0xa2, 0xcd, 0x11, 0x16, 0x29, 0xcb, 0xfa, 0x1a, 0x5d, 0xaa, 0x5a, 0x52, 0xf7, + 0xf0, 0x31, 0xf5, 0xb5, 0x7f, 0xfd, 0x32, 0x2e, 0xce, 0x24, 0x9c, 0xf2, 0x0a, 0x6d, 0x8d, 0xfc, + 0x6b, 0x29, 0x7b, 0x3f, 0x10, 0xd3, 0x24, 0x21, 0x79, 0x2f, 0x35, 0x6a, 0x41, 0x3a, 0x65, 0x93, + 0x4f, 0x9c, 0x4c, 0xed, 0x1e, 0x6e, 0x9b, 0xc1, 0x38, 0x9e, 0xa0, 0x5d, 0x78, 0x2d, 0x91, 0x6d, + 0x08, 0x64, 0x7e, 0x14, 0x06, 0xd5, 0x76, 0x81, 0x23, 0x9e, 0x2a, 0xa0, 0xb0, 0xb9, 0x0d, 0x8d, + 0x41, 0x38, 0xe7, 0xe6, 0x23, 0x11, 0x15, 0x86, 0xc4, 0x36, 0xf6, 0x4f, 0x1b, 0x9e, 0xbc, 0xac, + 0x88, 0xc8, 0xec, 0x8d, 0xf0, 0xdf, 0xa4, 0xed, 0x78, 0xc9, 0x80, 0xa5, 0xac, 0xac, 0x41, 0xb5, + 0x42, 0xae, 0x34, 0x58, 0x82, 0xd8, 0x17, 0x47, 0x10, 0x32, 0xba, 0x54, 0xa1, 0xdf, 0xa8, 0x42, + 0x24, 0x30, 0xac, 0xcf, 0xdb, 0xa3, 0x3f, 0x47, 0xe1, 0x3d, 0xea, 0x8d, 0x05, 0x08, 0x44, 0xe9, + 0xc1, 0x48, 0x1c, 0x0b, 0xcb, 0x39, 0x8e, 0x4f, 0x12, 0x59, 0x27, 0x02, 0xe4, 0xb8, 0x27, 0x29, + 0xd1, 0xe4, 0x0b, 0xfb, 0x74, 0x76, 0xd1, 0x41, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01 +}; + +#define composite65_rsa3072pkcs15_msg composite_test_msg + +static const uint8_t composite65_rsa3072pkcs15_add_random[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const uint8_t composite65_rsa3072pkcs15_sig_digest[] = { + 0xd5, 0x85, 0xab, 0x93, 0x9e, 0xaa, 0x86, 0x26, 0xd9, 0x4e, 0xcf, 0x34, 0x91, 0x07, 0xeb, 0x16, + 0xc8, 0x59, 0xa7, 0x2b, 0xbe, 0x5c, 0x6d, 0xc9, 0x06, 0x64, 0x09, 0x8f, 0x5d, 0xf4, 0x5f, 0x0f +}; + +static const uint8_t composite65_rsa3072pkcs15_sig[] = { + 0xdb, 0xff, 0x99, 0xe9, 0x76, 0x40, 0xea, 0x82, 0x66, 0x15, 0x0d, 0x3e, 0x19, 0x8a, 0x43, 0xa8, + 0x9f, 0x71, 0x41, 0x42, 0x89, 0xb2, 0x0f, 0x29, 0x8b, 0xd7, 0xc5, 0x85, 0xa0, 0x96, 0x47, 0xa4, + 0xb4, 0x43, 0x07, 0xbf, 0x89, 0x45, 0x3b, 0xb0, 0xe2, 0x65, 0xea, 0x50, 0x3a, 0x33, 0x97, 0x24, + 0x96, 0xb2, 0x67, 0xbb, 0x30, 0x82, 0x65, 0xd9, 0x9c, 0x47, 0x45, 0x79, 0x5d, 0x8e, 0x5d, 0x67, + 0x8a, 0x03, 0xdd, 0x2a, 0x2d, 0xf3, 0x53, 0x8c, 0xdc, 0x05, 0xcf, 0x86, 0x91, 0x46, 0xf2, 0x4a, + 0xf9, 0xec, 0x24, 0x34, 0xc4, 0x96, 0x79, 0x93, 0xe0, 0x9b, 0x08, 0xe2, 0xe3, 0x5e, 0x17, 0x3c, + 0x45, 0xdb, 0x10, 0x05, 0x04, 0x39, 0x42, 0xdc, 0x4c, 0xd0, 0x04, 0x9e, 0x01, 0x59, 0xab, 0xa6, + 0xd7, 0x62, 0xcd, 0xf9, 0xdb, 0x1a, 0x59, 0x70, 0xec, 0xd9, 0x9f, 0xdf, 0xab, 0x84, 0x24, 0x94, + 0x50, 0x8b, 0xf4, 0x34, 0x43, 0xc1, 0xf4, 0x0a, 0x6c, 0x78, 0x06, 0xac, 0x1e, 0xbe, 0x37, 0xe5, + 0xed, 0x1f, 0x7a, 0x92, 0xca, 0xcc, 0x7d, 0x67, 0x79, 0x98, 0x4a, 0x83, 0x8f, 0xa5, 0x95, 0x6a, + 0xd1, 0x86, 0xa8, 0x4e, 0x9d, 0x76, 0x04, 0x82, 0xdb, 0xdf, 0x28, 0xcc, 0x83, 0x3a, 0xa1, 0xb8, + 0xbd, 0xfb, 0x40, 0xae, 0x59, 0xcf, 0x1a, 0x09, 0x51, 0x98, 0x06, 0x25, 0x81, 0x2c, 0x4b, 0x5a, + 0xb2, 0x1b, 0x3f, 0xf0, 0xbc, 0xdf, 0xc9, 0x77, 0xd7, 0x74, 0x8d, 0x56, 0x7b, 0xda, 0x65, 0x46, + 0x53, 0x1c, 0xea, 0xe7, 0x9f, 0xee, 0x6f, 0x39, 0x7b, 0x5a, 0x55, 0xaf, 0x5a, 0x02, 0xcc, 0x47, + 0x2e, 0xed, 0x01, 0xf6, 0xcd, 0x49, 0x8a, 0x2e, 0x50, 0xac, 0x5b, 0x27, 0x71, 0x27, 0x25, 0x65, + 0x88, 0x2a, 0x90, 0x11, 0xc5, 0x2d, 0xf0, 0x63, 0x90, 0x6f, 0xf9, 0xc5, 0xbc, 0xe2, 0x1e, 0x12, + 0xc0, 0x2f, 0xb5, 0x11, 0xc3, 0x97, 0xd3, 0xc0, 0xa1, 0x92, 0x6f, 0x46, 0x7a, 0xb4, 0x78, 0xe9, + 0x51, 0x40, 0x1b, 0x19, 0x3f, 0x12, 0xe1, 0x7f, 0x01, 0x1a, 0xa8, 0xc1, 0xe6, 0xe1, 0x05, 0xd7, + 0x2c, 0xa8, 0xfd, 0xcf, 0xe7, 0xe6, 0xb2, 0x8e, 0x18, 0x1e, 0x2a, 0xd9, 0xa8, 0xe0, 0x3e, 0x65, + 0xf3, 0x11, 0xb9, 0x64, 0xb9, 0x00, 0xaa, 0xaa, 0x62, 0xf4, 0x3d, 0xc3, 0xa6, 0xfb, 0xf3, 0xc4, + 0x62, 0x53, 0xa8, 0x5d, 0xa3, 0xe5, 0x51, 0x99, 0xb1, 0x10, 0x19, 0x35, 0x2c, 0x88, 0x35, 0xaa, + 0x3f, 0x7b, 0xc6, 0x5d, 0x5d, 0xc4, 0xf0, 0xd4, 0xaf, 0x88, 0x08, 0xf7, 0xc3, 0xf6, 0x2d, 0x32, + 0x81, 0xc4, 0xb6, 0x04, 0x7c, 0x9d, 0x6c, 0xf0, 0x3a, 0x7a, 0x2c, 0xcf, 0x12, 0xf3, 0xde, 0x84, + 0x54, 0xab, 0xdd, 0xd1, 0x5b, 0x94, 0xcd, 0x6c, 0xc3, 0x6f, 0x91, 0x06, 0xd1, 0x51, 0xab, 0x20, + 0x55, 0xed, 0x94, 0xe9, 0x32, 0x26, 0x2d, 0x06, 0xf6, 0xff, 0xe6, 0xc3, 0x55, 0x74, 0xfd, 0x26, + 0x9a, 0x70, 0x62, 0x6b, 0x67, 0xb7, 0x04, 0x89, 0xaa, 0xfc, 0x3c, 0xc6, 0x24, 0x5b, 0x94, 0x11, + 0x50, 0xb5, 0xf5, 0x05, 0x0f, 0x18, 0x60, 0xcf, 0x06, 0xc2, 0x18, 0xaf, 0xf3, 0x2d, 0xb5, 0xe4, + 0xb2, 0x11, 0xcf, 0xf2, 0x5a, 0x1e, 0x36, 0x4c, 0x5f, 0x1a, 0xec, 0x3d, 0xee, 0xf3, 0x08, 0xe8, + 0x46, 0xd6, 0x0d, 0x1c, 0xff, 0xed, 0xef, 0x20, 0x5f, 0x2b, 0x93, 0xe3, 0x4b, 0x88, 0x29, 0x3a, + 0x88, 0xf5, 0xd1, 0xee, 0xd1, 0x40, 0xd8, 0x87, 0x43, 0x00, 0x44, 0x5a, 0x02, 0xe8, 0x1e, 0x9f, + 0xa1, 0xcc, 0xaf, 0x91, 0x8a, 0x01, 0x99, 0x8d, 0x1d, 0x5a, 0x07, 0x1b, 0x39, 0xa0, 0x16, 0x52, + 0xa7, 0x64, 0x6a, 0xb9, 0x71, 0x04, 0x12, 0xca, 0x04, 0x5a, 0x54, 0xdc, 0x10, 0x2f, 0xa5, 0x62, + 0xfb, 0x96, 0x54, 0xfe, 0x3a, 0xb4, 0x6b, 0xe5, 0x35, 0x40, 0x12, 0xb4, 0x8b, 0xcb, 0x98, 0x13, + 0x2b, 0xca, 0x0a, 0x3d, 0xc3, 0xb9, 0x45, 0xaf, 0xd5, 0xb5, 0x84, 0x92, 0x87, 0xdf, 0x92, 0xe2, + 0xeb, 0x8d, 0x5a, 0x72, 0x84, 0x0d, 0x1e, 0xe1, 0xe4, 0x4e, 0x21, 0x3a, 0xfe, 0xe8, 0x32, 0x7c, + 0xfd, 0x85, 0x4d, 0xd6, 0x28, 0x40, 0xd3, 0x74, 0x02, 0x88, 0x83, 0x19, 0xfe, 0x81, 0xe9, 0x46, + 0xe6, 0xc8, 0xac, 0xbc, 0x52, 0x06, 0xec, 0x3c, 0x1d, 0x41, 0xbd, 0x8d, 0x60, 0xe1, 0xa2, 0xa9, + 0x47, 0xa1, 0xac, 0x22, 0x0f, 0x80, 0x26, 0xbc, 0x85, 0xd5, 0x5b, 0x68, 0x73, 0x16, 0x42, 0x08, + 0x76, 0x31, 0x62, 0x18, 0x8b, 0xa8, 0xb2, 0xf5, 0x73, 0xf5, 0x8b, 0xab, 0xf3, 0x52, 0x0d, 0xa5, + 0x58, 0xb4, 0x51, 0xba, 0xa5, 0xff, 0xa1, 0x29, 0x0b, 0x85, 0x0a, 0xa1, 0xc6, 0x7a, 0x33, 0x75, + 0x2f, 0x8d, 0x11, 0xab, 0x4e, 0xd4, 0x2a, 0x6a, 0x72, 0x29, 0x4a, 0x30, 0x26, 0x41, 0x24, 0xfa, + 0xb0, 0x3c, 0x28, 0xed, 0x2a, 0xc2, 0xcd, 0x99, 0xc1, 0x35, 0x98, 0x22, 0xbd, 0xbd, 0xdb, 0xdc, + 0xbf, 0x69, 0x6f, 0x75, 0x33, 0xe7, 0xae, 0x9f, 0x51, 0xd2, 0x2e, 0x82, 0xfc, 0x76, 0xa9, 0x6b, + 0xf4, 0x6f, 0xc8, 0x06, 0xb7, 0x2e, 0xc6, 0x3f, 0xd9, 0xf3, 0xf0, 0x42, 0x32, 0xc3, 0x73, 0x5f, + 0xca, 0x7d, 0xc2, 0x6f, 0x52, 0x7d, 0xe1, 0x6b, 0xc8, 0xc5, 0xc1, 0xba, 0xd9, 0x60, 0x03, 0x0a, + 0x54, 0xe3, 0x89, 0x64, 0x46, 0xa7, 0x11, 0x15, 0x14, 0xb3, 0xe2, 0x8c, 0xf4, 0x30, 0xb6, 0x43, + 0x42, 0x32, 0xcc, 0x4d, 0xec, 0x3a, 0xb5, 0x3c, 0x45, 0x16, 0x00, 0x96, 0x5a, 0x4b, 0xa2, 0xf9, + 0xd2, 0x04, 0x9e, 0x91, 0xd5, 0xda, 0x4e, 0x5e, 0xde, 0x7c, 0xbe, 0x1a, 0x7f, 0x8d, 0x5b, 0x0d, + 0x16, 0x08, 0x4e, 0xcb, 0xa4, 0x94, 0x2d, 0x90, 0x0d, 0x5e, 0x2b, 0x1f, 0x39, 0x75, 0x50, 0xe7, + 0x04, 0x49, 0xb4, 0x6d, 0x16, 0x75, 0xcf, 0xa4, 0x42, 0x83, 0x6d, 0x3d, 0x2e, 0x7a, 0xb2, 0x59, + 0xd7, 0xe7, 0x88, 0x49, 0xdb, 0xce, 0x81, 0x69, 0x07, 0xa7, 0xd4, 0x48, 0x5f, 0xd2, 0xbf, 0xe7, + 0x21, 0x33, 0x7a, 0x80, 0xdf, 0x00, 0x0d, 0x4c, 0xad, 0xdd, 0x0e, 0xb3, 0x9f, 0x3a, 0x19, 0x12, + 0x58, 0x8d, 0x95, 0x58, 0xd0, 0x1e, 0x3f, 0x40, 0xa7, 0x60, 0xfc, 0x41, 0x59, 0x28, 0xe8, 0x10, + 0x07, 0x7a, 0x29, 0xd2, 0xa8, 0x90, 0x94, 0x49, 0x71, 0xd9, 0xed, 0xa9, 0xfc, 0x4d, 0xec, 0xb8, + 0x85, 0xab, 0x19, 0x1c, 0xeb, 0x71, 0x10, 0xae, 0xd0, 0x0c, 0x4f, 0x68, 0xa0, 0xbd, 0xdf, 0x63, + 0x92, 0x12, 0x71, 0x43, 0x2e, 0x0f, 0x88, 0x02, 0x32, 0x9e, 0xb3, 0xc2, 0x84, 0x8f, 0x64, 0x7a, + 0xaf, 0xd5, 0xc6, 0x8e, 0x09, 0xd3, 0x39, 0x82, 0x4c, 0xa6, 0x6e, 0x65, 0x43, 0x56, 0x78, 0xfc, + 0xb8, 0xb9, 0x47, 0x85, 0x70, 0x85, 0xa3, 0x34, 0x06, 0xe4, 0x69, 0x24, 0xee, 0x65, 0xeb, 0x17, + 0xf3, 0xd4, 0x1e, 0x12, 0x00, 0x2b, 0x44, 0x46, 0xae, 0x68, 0xdb, 0x28, 0x33, 0x50, 0x45, 0x5d, + 0x3b, 0x4a, 0x30, 0x4e, 0xa8, 0x14, 0xb8, 0xea, 0xc1, 0x88, 0x4d, 0x25, 0x0f, 0x25, 0xcb, 0x5d, + 0x6e, 0x48, 0xb7, 0xcc, 0x86, 0x98, 0x76, 0x2a, 0x13, 0x08, 0xd7, 0x38, 0x6e, 0xcc, 0xa9, 0xda, + 0x20, 0x65, 0xd3, 0x83, 0x88, 0x9b, 0xc0, 0x62, 0x90, 0xaf, 0xa7, 0x92, 0x48, 0xdf, 0xb6, 0x21, + 0x08, 0x6d, 0x77, 0x91, 0xf9, 0x4f, 0x80, 0x14, 0xf0, 0xa8, 0xa8, 0xb8, 0x6e, 0x42, 0xcb, 0x04, + 0xd5, 0x66, 0xad, 0x37, 0xfd, 0xfc, 0x66, 0x8e, 0x1f, 0x1f, 0x6b, 0xcc, 0xc6, 0xc0, 0x90, 0xc6, + 0x9f, 0x66, 0x95, 0xee, 0x5e, 0x74, 0xf8, 0x3d, 0x72, 0xb8, 0xe5, 0x2b, 0x09, 0x05, 0x8a, 0xa9, + 0x1f, 0xdb, 0xe4, 0x85, 0x71, 0x4b, 0x20, 0x05, 0x1a, 0xe5, 0xa3, 0xc1, 0x17, 0xec, 0xa2, 0x16, + 0x8e, 0xc6, 0x70, 0x69, 0x7b, 0x42, 0x01, 0xd9, 0xd6, 0xc6, 0x4b, 0x7b, 0x54, 0x6c, 0x9e, 0x85, + 0xfc, 0x85, 0xe1, 0x9d, 0x4a, 0x34, 0x11, 0x2c, 0x7a, 0x6b, 0x8d, 0xdd, 0x0b, 0xc5, 0x55, 0x15, + 0x2a, 0x3b, 0x34, 0xb7, 0x5a, 0x66, 0x50, 0x34, 0xbd, 0x2a, 0x98, 0xf4, 0x30, 0xf6, 0x05, 0xd0, + 0x93, 0x82, 0x1d, 0xd9, 0xaf, 0xbc, 0x16, 0xb0, 0x9d, 0xe0, 0x60, 0xc2, 0x34, 0xef, 0xca, 0x09, + 0xac, 0x6f, 0x9e, 0x35, 0xc6, 0x81, 0xa7, 0x4f, 0xbc, 0x1b, 0x33, 0xa3, 0xfe, 0xca, 0xd3, 0x64, + 0x38, 0x54, 0x13, 0x67, 0xb6, 0x36, 0xdd, 0xda, 0x41, 0x5b, 0x2b, 0xc1, 0x1a, 0x58, 0x82, 0x90, + 0x1c, 0xe1, 0xed, 0xb5, 0x59, 0x27, 0x99, 0x75, 0xd8, 0x56, 0xbd, 0x76, 0x9e, 0xa8, 0xf9, 0xd7, + 0x09, 0x26, 0xdf, 0xf9, 0xf4, 0x2d, 0x70, 0x4b, 0x76, 0x8f, 0x5e, 0x87, 0xa9, 0x94, 0x9e, 0xd7, + 0x71, 0x36, 0x47, 0x9b, 0x38, 0xcf, 0x73, 0xbe, 0x7b, 0x98, 0xb9, 0xd4, 0xd3, 0xf8, 0x58, 0x25, + 0x8a, 0x08, 0x4a, 0xfb, 0xb6, 0x80, 0x4b, 0xd0, 0x1a, 0x72, 0x5c, 0x33, 0x43, 0x6c, 0x18, 0x3c, + 0x33, 0x3c, 0xc3, 0x62, 0xcf, 0x28, 0x7f, 0xea, 0xa8, 0x22, 0x21, 0xd4, 0xee, 0xcd, 0xee, 0xc8, + 0x2c, 0xcc, 0xfc, 0x97, 0x2c, 0x46, 0x08, 0x4e, 0xd0, 0x67, 0xca, 0xff, 0x5b, 0x1b, 0xe1, 0xe6, + 0x76, 0x13, 0x89, 0x39, 0xc7, 0xca, 0x03, 0xd7, 0xaf, 0x59, 0xaa, 0x12, 0x46, 0xeb, 0xb7, 0x22, + 0xa0, 0x28, 0xd3, 0xa1, 0x3f, 0x1b, 0x82, 0x7c, 0xcb, 0x31, 0xd0, 0x4f, 0x5c, 0x14, 0xbc, 0x96, + 0xd4, 0x6d, 0xcf, 0x0b, 0xeb, 0xa2, 0xc5, 0x59, 0xe7, 0x7b, 0xce, 0xed, 0x44, 0x79, 0xfd, 0x6a, + 0xa9, 0xec, 0x8b, 0x42, 0x21, 0x75, 0x4f, 0xba, 0x19, 0x83, 0xda, 0x81, 0x4d, 0x43, 0xce, 0x7e, + 0x92, 0x2d, 0x41, 0x93, 0x7e, 0x7c, 0xb0, 0xc6, 0x7b, 0xee, 0x73, 0xa6, 0x44, 0xe8, 0xd3, 0x7d, + 0xaa, 0x31, 0x71, 0x63, 0x26, 0x35, 0xef, 0x45, 0xe3, 0x52, 0xec, 0x58, 0x2f, 0xce, 0xb4, 0xc8, + 0xda, 0xd1, 0xab, 0x01, 0x2e, 0x15, 0x59, 0x42, 0x56, 0xe2, 0x97, 0xf8, 0xff, 0xfd, 0xd7, 0x75, + 0x53, 0xd2, 0x59, 0x36, 0xbb, 0x7f, 0xbd, 0x4f, 0xc7, 0x54, 0x66, 0xea, 0x16, 0x6c, 0x13, 0x5d, + 0x79, 0xc1, 0x82, 0x0d, 0x3b, 0x9b, 0xd0, 0x27, 0x31, 0x48, 0x30, 0xb2, 0x26, 0xdb, 0x34, 0x71, + 0xfe, 0x94, 0x13, 0xc3, 0xda, 0xa1, 0x3d, 0xa4, 0x0b, 0x47, 0x4c, 0xd9, 0xe2, 0x60, 0xfe, 0x9d, + 0x7c, 0x70, 0x84, 0xa5, 0x08, 0x25, 0x11, 0x41, 0xa5, 0x71, 0x7f, 0x5d, 0xa3, 0x57, 0xdb, 0xe2, + 0xc1, 0x17, 0x09, 0x9e, 0xc0, 0xd6, 0x15, 0x45, 0x7d, 0xfd, 0x85, 0x28, 0xd3, 0x69, 0x65, 0x74, + 0xd5, 0x57, 0x3f, 0xa6, 0x1c, 0x28, 0x47, 0xd1, 0xee, 0x96, 0x62, 0xf7, 0x5b, 0xd6, 0xb1, 0x6c, + 0x49, 0x61, 0xb4, 0x32, 0xc4, 0xe2, 0x6e, 0x89, 0x1f, 0xd0, 0xb6, 0xe4, 0x73, 0x5e, 0x73, 0x7c, + 0x52, 0xf9, 0x29, 0xf5, 0xd5, 0x11, 0x1c, 0x27, 0x40, 0xb3, 0x1f, 0xd0, 0x0b, 0x67, 0xd3, 0xc0, + 0xe8, 0x16, 0x5f, 0x4f, 0xb1, 0xc9, 0x35, 0x67, 0xf0, 0xa6, 0x2a, 0x9d, 0x9a, 0x3c, 0x4c, 0x41, + 0x6e, 0x39, 0xde, 0x90, 0x79, 0x0f, 0x6d, 0x51, 0x53, 0xba, 0x89, 0xda, 0xbb, 0x23, 0xff, 0x62, + 0xe8, 0xde, 0x00, 0x92, 0x6a, 0x5c, 0x91, 0x0f, 0xd6, 0x2d, 0xb1, 0xd2, 0xae, 0x13, 0xba, 0xd0, + 0x34, 0xbd, 0xa4, 0x88, 0xbf, 0xaa, 0x63, 0x2b, 0x86, 0x72, 0x22, 0xd4, 0xaa, 0x9d, 0x9d, 0xca, + 0x52, 0x6a, 0x45, 0xe5, 0xbd, 0xff, 0xec, 0x48, 0x71, 0x64, 0xc6, 0xc6, 0x2a, 0x53, 0x1d, 0xb2, + 0x08, 0xa7, 0x0c, 0x82, 0xc0, 0x3a, 0xbf, 0xbd, 0x38, 0x7d, 0xa1, 0x56, 0x8b, 0x88, 0xb0, 0xb3, + 0x29, 0xe7, 0x3b, 0xd5, 0x05, 0xc2, 0x39, 0x79, 0x97, 0x6c, 0xac, 0x1a, 0xb5, 0x50, 0x1b, 0x42, + 0x44, 0x45, 0x08, 0xdc, 0xdf, 0xb4, 0x9d, 0x4d, 0xb0, 0x33, 0xba, 0xe2, 0xd3, 0xbb, 0xd9, 0xac, + 0x17, 0x52, 0xad, 0xab, 0xe7, 0x22, 0x0e, 0x50, 0xd7, 0xde, 0x5d, 0x96, 0x4c, 0x11, 0xf7, 0x33, + 0xb3, 0x00, 0x12, 0x41, 0xa8, 0x26, 0xf4, 0xff, 0x7e, 0xab, 0x25, 0x9b, 0x59, 0x69, 0x5f, 0x4e, + 0x9c, 0x56, 0x37, 0x83, 0x2a, 0x72, 0xb1, 0x5e, 0x9f, 0xa8, 0xc1, 0xf8, 0xa5, 0x25, 0xbd, 0x0f, + 0x0f, 0xf4, 0x25, 0xf5, 0x0f, 0x9c, 0xbc, 0x49, 0x5e, 0xfc, 0x2c, 0x65, 0xe8, 0xc9, 0x0b, 0x6c, + 0xe9, 0x4d, 0x45, 0xe0, 0xcf, 0x45, 0x89, 0x1f, 0xc6, 0xf2, 0x00, 0x8b, 0x4d, 0x9f, 0xdf, 0x6c, + 0x11, 0x22, 0xc9, 0x8c, 0x32, 0xf0, 0x20, 0xca, 0xa2, 0xba, 0x41, 0x57, 0x47, 0xff, 0x67, 0x8e, + 0xa6, 0x4c, 0x67, 0x3c, 0x5d, 0x28, 0x29, 0xa3, 0x09, 0x6a, 0x76, 0x88, 0x35, 0x6f, 0x52, 0xbc, + 0x3d, 0x9f, 0x4c, 0x18, 0xe8, 0xc6, 0x64, 0xe9, 0x32, 0x64, 0xc3, 0xed, 0x30, 0x1d, 0xb6, 0x28, + 0xf9, 0x9a, 0xed, 0x28, 0x5d, 0x02, 0xdc, 0x43, 0x34, 0x15, 0x16, 0x36, 0x7e, 0x07, 0xb6, 0xee, + 0x70, 0xf0, 0x4f, 0x21, 0x5c, 0xfa, 0x71, 0xe4, 0x4a, 0x0c, 0x0d, 0x29, 0x6d, 0xdc, 0xfe, 0x0d, + 0xb5, 0x7d, 0x62, 0xec, 0x10, 0x6a, 0x63, 0x90, 0x23, 0x60, 0xd3, 0xb6, 0xba, 0x40, 0x24, 0x1d, + 0xc1, 0x44, 0x8d, 0xef, 0x83, 0x2b, 0xa1, 0x8a, 0x0a, 0xdd, 0x00, 0xaf, 0x6f, 0x2a, 0xf7, 0xe9, + 0xbc, 0x88, 0xaf, 0x99, 0xd9, 0x34, 0xdd, 0xf4, 0x66, 0x07, 0xc8, 0xce, 0x2e, 0xab, 0x84, 0xd1, + 0x7b, 0x77, 0xc9, 0xd1, 0x4b, 0xcb, 0xc0, 0xf3, 0x73, 0x74, 0x62, 0x79, 0x27, 0xd1, 0x52, 0x1e, + 0x0d, 0xc5, 0xba, 0x04, 0x40, 0x49, 0xf4, 0x46, 0xed, 0xea, 0x4a, 0xb1, 0xda, 0x1f, 0xfe, 0x42, + 0xb2, 0x14, 0x02, 0x62, 0xcb, 0xdc, 0x09, 0x8e, 0x22, 0xeb, 0x63, 0x72, 0x5f, 0x62, 0x8d, 0x3e, + 0xe2, 0xaa, 0xd2, 0x5b, 0x65, 0x77, 0x01, 0x2d, 0x8b, 0xa1, 0x09, 0x84, 0x31, 0x38, 0x1b, 0x45, + 0xc0, 0x5d, 0x74, 0x61, 0xeb, 0x13, 0x11, 0x1b, 0x74, 0xb4, 0xc8, 0x87, 0x95, 0x3a, 0x30, 0x2e, + 0x1f, 0x4b, 0xa8, 0x73, 0x69, 0x72, 0xba, 0xda, 0x14, 0x65, 0x23, 0x24, 0xb6, 0xc5, 0xd0, 0xb7, + 0x64, 0x38, 0xa7, 0x31, 0x54, 0x08, 0xaf, 0x32, 0x44, 0x32, 0x97, 0x27, 0x84, 0x64, 0x59, 0x06, + 0xfe, 0xb8, 0x01, 0x14, 0x6a, 0x79, 0xe7, 0x89, 0x39, 0x59, 0xf1, 0x5d, 0x55, 0x72, 0x21, 0x64, + 0xb2, 0x94, 0xa8, 0xd5, 0x65, 0x11, 0xe4, 0x15, 0x02, 0xd6, 0xa7, 0xbb, 0xe8, 0x2b, 0x07, 0x18, + 0x86, 0x95, 0x3d, 0x56, 0xf8, 0x4c, 0x68, 0x99, 0xc5, 0xbc, 0x25, 0xe7, 0xb6, 0x27, 0x4f, 0x26, + 0x39, 0x18, 0x47, 0x4e, 0x4d, 0xa4, 0xae, 0x05, 0xef, 0x07, 0xd6, 0x43, 0xd8, 0xc0, 0xbc, 0x7c, + 0xc2, 0xcb, 0xe7, 0xb6, 0x54, 0xfe, 0x1f, 0x7b, 0x94, 0x48, 0x9a, 0x09, 0x68, 0x9c, 0x36, 0xe4, + 0xdb, 0xd7, 0xa2, 0xcd, 0xdd, 0xfc, 0x8d, 0x42, 0x09, 0xce, 0x88, 0x2e, 0x3e, 0xc8, 0xc6, 0x39, + 0xec, 0x81, 0xa1, 0x46, 0x65, 0xbd, 0x34, 0x45, 0x28, 0xc8, 0x9f, 0xfe, 0x7c, 0x55, 0x02, 0x15, + 0x40, 0x11, 0x3e, 0x3d, 0xd2, 0x98, 0x7c, 0xd3, 0x9c, 0xf8, 0x3f, 0x80, 0xc0, 0xee, 0x40, 0x3d, + 0x5d, 0x19, 0x05, 0x71, 0x05, 0x09, 0x37, 0xd9, 0x8c, 0x43, 0x35, 0xa0, 0xdf, 0x1b, 0x25, 0xec, + 0x22, 0x35, 0xfe, 0x8f, 0xa6, 0x2c, 0x77, 0xdd, 0x82, 0x50, 0x6c, 0xc8, 0x6d, 0xd8, 0x06, 0x58, + 0x51, 0x37, 0xb1, 0xd1, 0xea, 0xc6, 0xc0, 0x34, 0xb5, 0x8e, 0x81, 0xd5, 0x7f, 0xd8, 0xd9, 0x5b, + 0xdc, 0x69, 0x3b, 0x9c, 0x15, 0xad, 0x92, 0x23, 0xe7, 0xae, 0x8a, 0x36, 0xed, 0xf9, 0xc0, 0x68, + 0xc9, 0x66, 0xb2, 0xd5, 0x75, 0x33, 0xb5, 0x20, 0xd9, 0x63, 0xef, 0xb8, 0x7a, 0x1c, 0xfd, 0xde, + 0x94, 0x08, 0x04, 0x94, 0xbf, 0xef, 0x5e, 0xbd, 0xfe, 0x2e, 0x0a, 0xea, 0x21, 0x96, 0x4c, 0x90, + 0xf2, 0x76, 0x0c, 0x9c, 0x21, 0x94, 0x49, 0x0c, 0x03, 0xa4, 0x00, 0x16, 0x75, 0xbb, 0x09, 0x44, + 0xd1, 0x2f, 0x6a, 0xa2, 0x19, 0x01, 0x82, 0x3b, 0xa8, 0x3a, 0x18, 0x13, 0x24, 0xae, 0xcf, 0x5c, + 0x10, 0xf2, 0xb9, 0x6d, 0xa3, 0x59, 0x5e, 0x2c, 0x55, 0xdd, 0xf8, 0xa7, 0x18, 0x29, 0x75, 0x3a, + 0x6e, 0x26, 0x27, 0x99, 0x0c, 0xac, 0xed, 0x56, 0x3e, 0x07, 0xed, 0xe6, 0xcc, 0x30, 0xa0, 0xa7, + 0x22, 0x53, 0x60, 0xdc, 0x81, 0x70, 0xb4, 0xc2, 0x99, 0x47, 0xe1, 0x1d, 0xfc, 0x68, 0x42, 0x13, + 0xbb, 0xa3, 0xba, 0xd0, 0x9f, 0x3a, 0x7d, 0xfc, 0xeb, 0xf7, 0xda, 0x25, 0x3c, 0x6b, 0x96, 0x52, + 0x72, 0x3a, 0x78, 0xa5, 0xef, 0xcd, 0xb8, 0x99, 0xbd, 0x4d, 0x94, 0x11, 0x86, 0x7b, 0xef, 0xa7, + 0xa9, 0xef, 0x7c, 0x97, 0x93, 0x70, 0x54, 0x73, 0x2b, 0x8e, 0x0f, 0x23, 0x13, 0xaa, 0xcd, 0x91, + 0xc9, 0x9e, 0x54, 0x95, 0x55, 0x8d, 0x35, 0xab, 0xfa, 0x90, 0xa8, 0xfe, 0x26, 0xee, 0x3d, 0xda, + 0x8c, 0x5c, 0x38, 0x35, 0x32, 0x6f, 0x67, 0xc8, 0x54, 0x6f, 0x29, 0xec, 0x4f, 0x14, 0x99, 0xdc, + 0xcf, 0x31, 0xbf, 0xd5, 0x83, 0x94, 0x94, 0xc4, 0x5f, 0xef, 0x9e, 0xf7, 0x46, 0x63, 0x35, 0xf9, + 0x5e, 0xf8, 0x95, 0x6d, 0xc9, 0x71, 0xb0, 0x44, 0xbd, 0x2a, 0x2c, 0x95, 0xed, 0x03, 0x55, 0xc9, + 0xa8, 0x95, 0xb6, 0xb1, 0x14, 0x37, 0xd2, 0xab, 0xb5, 0x9c, 0x2e, 0x35, 0x13, 0xd0, 0xce, 0xce, + 0x27, 0x40, 0xc1, 0x0b, 0x96, 0xf4, 0x9a, 0xa4, 0xec, 0x17, 0xac, 0x05, 0x9b, 0xba, 0x1b, 0x22, + 0xab, 0xa8, 0xb2, 0x2e, 0x8a, 0x9f, 0xd1, 0x6c, 0xc6, 0x32, 0xcc, 0x45, 0x45, 0xc3, 0x4b, 0x1e, + 0x2f, 0xa8, 0xb7, 0x7a, 0x89, 0x36, 0xe6, 0xd1, 0x5d, 0x72, 0x4a, 0x55, 0xa2, 0x5f, 0x3e, 0x66, + 0xed, 0x29, 0xa4, 0xfa, 0x64, 0x48, 0x38, 0xa2, 0x37, 0x5b, 0xb6, 0x7d, 0x6e, 0xb1, 0x64, 0x6c, + 0x8f, 0xd6, 0xb9, 0x88, 0xdf, 0x52, 0xa0, 0xf6, 0xab, 0xcc, 0xaa, 0x7f, 0xbf, 0xf7, 0x90, 0x54, + 0x67, 0x15, 0x13, 0xd7, 0x64, 0x36, 0xef, 0xe1, 0x6d, 0x0f, 0xc3, 0x56, 0xd1, 0xd8, 0x78, 0xca, + 0xc2, 0x40, 0xbf, 0xfb, 0xf0, 0x1c, 0x54, 0x8a, 0xdb, 0x86, 0xb1, 0xe6, 0x8e, 0xdf, 0x52, 0x83, + 0x6a, 0x58, 0x09, 0x01, 0x85, 0xdd, 0x04, 0xd3, 0x0b, 0x9e, 0x6f, 0xac, 0xf7, 0x6a, 0xe7, 0xe0, + 0x75, 0x3a, 0x21, 0x01, 0xdf, 0x1d, 0xd8, 0xca, 0x5c, 0xdf, 0x88, 0x9d, 0x52, 0xee, 0x66, 0x0b, + 0x37, 0x68, 0x4d, 0x61, 0x6a, 0x92, 0xff, 0xf3, 0x01, 0x48, 0x76, 0x83, 0xd3, 0x8e, 0xcd, 0x95, + 0x28, 0x9b, 0xb7, 0xe1, 0xf4, 0x69, 0x5b, 0x91, 0x0a, 0x47, 0x49, 0x1c, 0x0b, 0xc6, 0x54, 0x6d, + 0xc2, 0x95, 0xb2, 0x9d, 0xd0, 0x30, 0x60, 0x17, 0x4b, 0x44, 0xcd, 0x9e, 0xdd, 0xcc, 0x3d, 0x0d, + 0xda, 0x67, 0xf9, 0xdf, 0xc4, 0x77, 0xe6, 0xdd, 0xc2, 0xa1, 0xd2, 0xb5, 0x49, 0x1a, 0x4a, 0x38, + 0x23, 0x53, 0x4a, 0x66, 0xdf, 0x7c, 0xd7, 0xd2, 0x87, 0xba, 0xf1, 0xd8, 0x15, 0x36, 0x7d, 0x56, + 0x65, 0x0c, 0x84, 0x9b, 0x2a, 0x25, 0xc7, 0xfe, 0x24, 0xe1, 0x38, 0xce, 0x98, 0xa9, 0xf7, 0x65, + 0x3f, 0x78, 0xaf, 0xc5, 0xa4, 0x68, 0x9c, 0x00, 0x8e, 0x04, 0x18, 0x67, 0x9c, 0x9e, 0x3f, 0xec, + 0x1f, 0xb8, 0xb7, 0x7f, 0x9d, 0x64, 0xd2, 0x47, 0x23, 0x41, 0xa4, 0xc2, 0x3b, 0x1f, 0x0e, 0xf1, + 0x6c, 0xbf, 0xf0, 0x03, 0x23, 0xc4, 0x44, 0xc5, 0x4c, 0xce, 0x00, 0xc8, 0x65, 0x57, 0x8c, 0x4a, + 0xd2, 0x6d, 0x76, 0x52, 0x41, 0x80, 0x30, 0x4d, 0x9d, 0xda, 0xc8, 0x64, 0x2f, 0x16, 0x9e, 0xfe, + 0x0f, 0xd8, 0xb5, 0x40, 0x22, 0x6a, 0x2d, 0xe9, 0xae, 0xee, 0x45, 0x16, 0x5e, 0x54, 0xf9, 0xd3, + 0x81, 0x4f, 0x62, 0xb0, 0xe7, 0xd2, 0xed, 0x88, 0x50, 0x13, 0x06, 0x3a, 0xf1, 0xf2, 0x37, 0x7d, + 0x0a, 0xbe, 0xbd, 0x0e, 0xa7, 0xaf, 0x6c, 0x48, 0x05, 0xc5, 0x6f, 0xe3, 0x33, 0x20, 0xc7, 0xc2, + 0xf4, 0xaa, 0xb8, 0xea, 0x08, 0x4a, 0x63, 0x93, 0xeb, 0xd4, 0x64, 0x47, 0x09, 0x2a, 0xf6, 0x80, + 0x52, 0xd9, 0xcb, 0x82, 0x2a, 0xcd, 0x5d, 0x61, 0xe2, 0xc4, 0x64, 0xe3, 0x36, 0x1d, 0x0b, 0x66, + 0x56, 0xf7, 0x8f, 0x1a, 0x52, 0xbb, 0x71, 0x64, 0x21, 0x27, 0x8a, 0xe9, 0x8d, 0x83, 0xac, 0xac, + 0x5d, 0xc8, 0xd0, 0x04, 0x9a, 0x6b, 0x3f, 0x7b, 0x83, 0xb9, 0x5a, 0x0d, 0x33, 0xb2, 0xd6, 0x1c, + 0xc4, 0x1a, 0xe0, 0x64, 0xb1, 0xa4, 0x6e, 0xb8, 0x83, 0xc0, 0xa0, 0xce, 0xfc, 0xd4, 0x2b, 0x9f, + 0xd4, 0x04, 0x10, 0x12, 0x59, 0x8b, 0x02, 0x2a, 0x34, 0x07, 0x16, 0x1a, 0x5e, 0x7d, 0x8f, 0xe1, + 0xf4, 0x00, 0xa8, 0xfc, 0x15, 0x68, 0xfa, 0x1e, 0x1a, 0x82, 0xee, 0xec, 0x52, 0xe2, 0xc2, 0xbd, + 0x2b, 0x3f, 0xac, 0x7d, 0x1d, 0x8f, 0x9a, 0x5d, 0x09, 0xda, 0x6a, 0x22, 0xa5, 0x16, 0xd3, 0x4c, + 0x28, 0xaf, 0x88, 0x31, 0x74, 0x35, 0x73, 0x1d, 0xda, 0xf3, 0x23, 0x46, 0xdf, 0x29, 0x24, 0x29, + 0x77, 0x5f, 0x31, 0xd1, 0x28, 0xfe, 0x3e, 0x49, 0x6b, 0x3f, 0x71, 0xcc, 0x57, 0xb1, 0x73, 0xce, + 0xd8, 0x30, 0xde, 0x34, 0xf9, 0xcb, 0x03, 0x7a, 0x5a, 0x47, 0xc6, 0x13, 0x0b, 0xfa, 0xac, 0x51, + 0xd0, 0x08, 0xe9, 0xbb, 0xc2, 0xbd, 0x18, 0xb7, 0x04, 0xe6, 0xd1, 0x89, 0x28, 0x68, 0x85, 0xd0, + 0x2a, 0x45, 0x99, 0xa5, 0x91, 0xe8, 0x33, 0x89, 0xd8, 0x04, 0x99, 0xce, 0x90, 0x2d, 0x9c, 0x1e, + 0xc5, 0x2a, 0xe5, 0xd4, 0x64, 0xc6, 0x53, 0x7b, 0xaf, 0x68, 0x15, 0x2a, 0xb8, 0x62, 0x3c, 0x54, + 0x3b, 0x95, 0x39, 0x56, 0xf2, 0x89, 0x34, 0xd3, 0x83, 0x05, 0xf2, 0xd2, 0x95, 0xd3, 0xbc, 0x3a, + 0x7e, 0x88, 0xd6, 0xc1, 0xb4, 0x69, 0x53, 0x6e, 0xe7, 0x12, 0x5f, 0x37, 0x76, 0xad, 0x74, 0x39, + 0x41, 0xc4, 0xf0, 0xd8, 0x71, 0x56, 0xa2, 0x4d, 0x64, 0x67, 0x86, 0x64, 0x08, 0xe8, 0xf3, 0x1c, + 0x67, 0x4e, 0xbf, 0x65, 0x54, 0xdc, 0x65, 0x9c, 0x36, 0x68, 0x83, 0x82, 0x4b, 0x5a, 0xd7, 0x3e, + 0xa5, 0x8c, 0x48, 0x80, 0xf0, 0x04, 0xaf, 0x76, 0x30, 0xce, 0xa7, 0xe5, 0xf7, 0x83, 0x2d, 0xb0, + 0xc2, 0x92, 0x0c, 0x68, 0x8f, 0x39, 0x6f, 0x4d, 0x2c, 0x04, 0xc0, 0x05, 0x95, 0x09, 0x6b, 0xcf, + 0xa5, 0x8f, 0x5e, 0xb2, 0x74, 0x7d, 0x3d, 0x73, 0x34, 0x22, 0x51, 0x93, 0x40, 0x7b, 0x5b, 0x6e, + 0xf7, 0xe4, 0xf6, 0x81, 0x4d, 0x13, 0xb6, 0x9b, 0x72, 0xce, 0x2b, 0x36, 0x20, 0xff, 0x37, 0xfe, + 0x61, 0xe6, 0xd0, 0x37, 0x9f, 0x65, 0x3d, 0xdc, 0x7e, 0xf6, 0x07, 0x9e, 0x57, 0xb9, 0xb9, 0x9f, + 0x9b, 0xc3, 0x19, 0xf7, 0xa1, 0x33, 0x69, 0xb5, 0xb9, 0xe5, 0x54, 0x07, 0x40, 0xf0, 0xcb, 0xef, + 0x8c, 0x32, 0x0f, 0x57, 0x1f, 0x86, 0xa4, 0x0f, 0x1d, 0xdd, 0xf3, 0x3c, 0xd8, 0x3f, 0x3e, 0x80, + 0x0a, 0x20, 0x17, 0x7e, 0xc4, 0x77, 0xb9, 0x55, 0xb5, 0xd7, 0xb0, 0x9c, 0xae, 0x9f, 0xf9, 0xe4, + 0x12, 0x43, 0x56, 0xc4, 0x88, 0xf0, 0xe5, 0x3f, 0x54, 0xb0, 0x24, 0xf9, 0x24, 0x46, 0x8d, 0xa2, + 0x4d, 0x58, 0x9b, 0x03, 0xee, 0x57, 0xbc, 0xd5, 0x93, 0xcb, 0xa8, 0xb0, 0xb7, 0x4e, 0x45, 0xa1, + 0x3b, 0x8b, 0xb3, 0x84, 0xf5, 0x82, 0xfb, 0xf0, 0x9b, 0xa4, 0xc3, 0xd9, 0xd9, 0x2a, 0x12, 0xd8, + 0x94, 0xbc, 0x61, 0x78, 0x5b, 0xa4, 0x1c, 0x54, 0x33, 0xb7, 0x78, 0xd3, 0xd7, 0x58, 0xc4, 0xa5, + 0x2e, 0x88, 0x00, 0x01, 0xa8, 0x7a, 0x28, 0x14, 0x18, 0x50, 0xff, 0xbd, 0x70, 0xe3, 0x8a, 0x4e, + 0xc8, 0xc4, 0x8e, 0x2c, 0xae, 0x07, 0x92, 0xd2, 0xbe, 0x6d, 0xf1, 0x9c, 0x70, 0x9e, 0xe7, 0xfb, + 0x8f, 0x8c, 0xf0, 0x8e, 0x9b, 0x82, 0x46, 0x86, 0xa1, 0x97, 0xa7, 0x38, 0xf4, 0xf7, 0xc5, 0x42, + 0x28, 0x29, 0x98, 0xac, 0xe4, 0x20, 0x51, 0xa6, 0xb9, 0xc8, 0x37, 0x3a, 0xa9, 0xcc, 0x28, 0x36, + 0x43, 0xa1, 0xca, 0xd9, 0xea, 0x1c, 0x4f, 0x6f, 0x76, 0x8b, 0x8f, 0xc7, 0xe6, 0xe8, 0x3f, 0x43, + 0x6d, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0a, 0x0e, 0x15, 0x1e, 0x22, 0x5d, 0x23, 0x25, + 0x56, 0xea, 0x4d, 0x84, 0x72, 0x68, 0x33, 0x3c, 0x2f, 0x10, 0x89, 0x2e, 0x00, 0x2e, 0x69, 0x4e, + 0x61, 0x66, 0x41, 0x31, 0x8f, 0x37, 0x81, 0x36, 0x47, 0xc2, 0xc7, 0x3e, 0x9a, 0x92, 0x52, 0xf3, + 0x40, 0x22, 0x4c, 0xcf, 0x5e, 0x80, 0xdf, 0x5b, 0xb3, 0x37, 0x9f, 0x99, 0xc8, 0xc9, 0xed, 0x2d, + 0x0c, 0x23, 0xfe, 0x6d, 0x60, 0x22, 0x7e, 0x87, 0x20, 0x65, 0xdb, 0x12, 0xa3, 0xca, 0x0d, 0xc5, + 0x09, 0xb6, 0x42, 0x45, 0x9e, 0x86, 0x89, 0x24, 0x20, 0x58, 0x12, 0x22, 0xf3, 0x31, 0xc3, 0x93, + 0x3d, 0xd8, 0x76, 0xb3, 0xa0, 0xe8, 0x08, 0x72, 0x4a, 0xec, 0x23, 0x81, 0xe3, 0xe9, 0xff, 0x05, + 0x32, 0x61, 0x29, 0xe6, 0xae, 0x6e, 0x74, 0x91, 0xaa, 0x43, 0x60, 0x6e, 0x35, 0xec, 0x51, 0xc2, + 0xb7, 0xce, 0x5e, 0x47, 0x1e, 0x67, 0x23, 0x49, 0x8e, 0xe7, 0xcb, 0xea, 0x95, 0x16, 0x14, 0x36, + 0x5f, 0xc4, 0xa6, 0xc7, 0xab, 0xa9, 0x14, 0x16, 0x74, 0x40, 0xad, 0x23, 0x65, 0x93, 0x19, 0xa7, + 0xa6, 0xa4, 0x88, 0x2b, 0xa7, 0x2c, 0xd3, 0x5c, 0xd9, 0xef, 0x1d, 0x5e, 0x29, 0x14, 0x0c, 0x67, + 0x0a, 0x7f, 0x9c, 0x9b, 0xe8, 0x2d, 0xef, 0x0d, 0xa9, 0x79, 0x77, 0x5f, 0xbf, 0x86, 0x61, 0x83, + 0x47, 0xb6, 0x09, 0xc1, 0xe7, 0x58, 0x1c, 0x65, 0x61, 0x9b, 0x8f, 0x35, 0x0e, 0x4b, 0x09, 0xcd, + 0xb2, 0x99, 0x4d, 0xd9, 0x76, 0x1e, 0xdc, 0x07, 0x69, 0xf8, 0x34, 0x86, 0xab, 0xd6, 0xf3, 0x7e, + 0x1d, 0xaf, 0x0c, 0x04, 0x60, 0x7c, 0xa5, 0x94, 0x99, 0xdf, 0x37, 0xb1, 0xd0, 0x5b, 0x25, 0x3b, + 0x63, 0xf8, 0x3d, 0x3f, 0xa7, 0x50, 0x61, 0x27, 0xb3, 0xfc, 0xb0, 0x7b, 0x08, 0x7f, 0x87, 0xf0, + 0x34, 0x09, 0x3f, 0x39, 0xe1, 0xd4, 0xcf, 0xe3, 0x99, 0x22, 0xe3, 0xc0, 0x21, 0x5f, 0xbb, 0x76, + 0x80, 0x77, 0x36, 0x52, 0xbd, 0x9a, 0x84, 0x26, 0xd5, 0x09, 0x6b, 0x92, 0xc3, 0xfd, 0x7b, 0xc1, + 0xab, 0x51, 0xc7, 0xa1, 0x3e, 0x99, 0xef, 0x05, 0x37, 0x53, 0xf5, 0xa3, 0x7b, 0x4e, 0xfe, 0x06, + 0xfe, 0x9a, 0x63, 0x66, 0xa1, 0x54, 0x66, 0xd7, 0x4a, 0x72, 0xb6, 0xc1, 0x2e, 0x85, 0xc5, 0xcf, + 0xdb, 0x93, 0x6d, 0x3e, 0x8e, 0x9c, 0x55, 0x12, 0x9b, 0x5f, 0x81, 0x1f, 0xa0, 0x11, 0x0c, 0xd6, + 0xac, 0x1e, 0xab, 0x37, 0x22, 0x3c, 0xd2, 0xc6, 0x02, 0x6a, 0xb9, 0xdf, 0xe4, 0xce, 0x60, 0x01, + 0x87, 0x4d, 0xf2, 0xee, 0x8e, 0xa4, 0xcc, 0xbd, 0x73, 0x33, 0x55, 0xc9, 0x90, 0x6b, 0x13, 0xe2, + 0x0f, 0x74, 0x6f, 0x41, 0xdc, 0x5a, 0xdf, 0x38, 0xac, 0xc2, 0x9c, 0x89, 0xa3, 0xa3, 0x42, 0xa1, + 0xd6, 0x5d, 0x31, 0x17, 0x45, 0x09, 0xba, 0xaa, 0xed, 0xae, 0x98, 0x05, 0x75 +}; + +/* --- ML-DSA-65-RSA4096-PKCS15-SHA512 --- */ +static const uint8_t composite65_rsa4096pkcs15_priv[] = { + 0x1b, 0xeb, 0xbb, 0x80, 0x20, 0x54, 0x9a, 0x4b, 0xda, 0x34, 0x5c, 0x03, 0xc4, 0x48, 0xaf, 0x4b, + 0xe4, 0xda, 0x58, 0x29, 0xc6, 0xb9, 0x38, 0x2f, 0x96, 0x81, 0xb4, 0x40, 0x0d, 0x68, 0x1e, 0x1b, + 0x30, 0x82, 0x09, 0x29, 0x02, 0x01, 0x00, 0x02, 0x82, 0x02, 0x01, 0x00, 0xb2, 0x40, 0x23, 0x3c, + 0x5b, 0x4f, 0xda, 0xe5, 0x29, 0x4d, 0x41, 0xf1, 0x1c, 0x74, 0xae, 0xcc, 0x1f, 0xd2, 0x9f, 0x3b, + 0x42, 0x8d, 0x00, 0x03, 0xec, 0xfc, 0x15, 0xef, 0xaa, 0xa4, 0x42, 0x96, 0xbb, 0x5c, 0x24, 0xc7, + 0x83, 0x31, 0xf1, 0x7c, 0x40, 0x85, 0x62, 0x08, 0xf0, 0xb3, 0x9f, 0xd1, 0x0e, 0xdd, 0xde, 0x28, + 0xbb, 0x3c, 0x1b, 0xbe, 0xbb, 0x88, 0x61, 0xf7, 0x07, 0xe7, 0x19, 0xb9, 0x7c, 0xfc, 0xc0, 0xcd, + 0x59, 0x8d, 0x06, 0xfe, 0x62, 0xef, 0xc9, 0x09, 0x70, 0x5f, 0x8a, 0x9c, 0x01, 0x4e, 0xbe, 0xe7, + 0xdf, 0xbd, 0x91, 0x27, 0x62, 0x14, 0x92, 0xf8, 0x66, 0xa0, 0xb4, 0xf1, 0x2c, 0x89, 0xcd, 0xc1, + 0xc4, 0x15, 0x18, 0x49, 0x54, 0x3e, 0x39, 0xd2, 0xfd, 0x17, 0x73, 0x04, 0xbf, 0x10, 0x45, 0xd5, + 0x09, 0x82, 0x7c, 0xd5, 0x80, 0x8c, 0xb8, 0x6f, 0x78, 0x11, 0xe1, 0x0a, 0xe5, 0x21, 0xaa, 0x63, + 0x49, 0xb4, 0x94, 0xcf, 0xfa, 0xc3, 0x88, 0xb6, 0xb8, 0x86, 0xc1, 0xcd, 0x9d, 0x26, 0x77, 0x2f, + 0x73, 0x78, 0x25, 0x6b, 0xa8, 0x1c, 0xb7, 0x3f, 0x87, 0x2f, 0x27, 0xe5, 0x25, 0xe3, 0x71, 0xb6, + 0x06, 0x8f, 0xdd, 0xc9, 0x19, 0xb2, 0xf5, 0xd6, 0x38, 0x22, 0x92, 0x36, 0x20, 0xdf, 0x47, 0xe7, + 0x44, 0x2f, 0x0b, 0xaa, 0xe4, 0x14, 0x88, 0x75, 0xe4, 0xb7, 0x2b, 0x02, 0x3f, 0x95, 0x75, 0x5a, + 0x78, 0x90, 0x09, 0x47, 0xeb, 0xf6, 0x29, 0xf4, 0x7c, 0x40, 0xb9, 0xcb, 0xad, 0xe3, 0xe3, 0x9e, + 0xce, 0xd0, 0x02, 0xfd, 0xca, 0x1d, 0xfc, 0xb7, 0xf8, 0x4d, 0x11, 0x73, 0x3a, 0x7e, 0xf2, 0x57, + 0xba, 0xab, 0xc7, 0x06, 0xba, 0xd5, 0x39, 0x08, 0x9b, 0xba, 0x74, 0x69, 0x01, 0xc9, 0xa1, 0x61, + 0x1f, 0x49, 0x06, 0x76, 0x60, 0x28, 0xa4, 0x27, 0xf1, 0x70, 0x19, 0x22, 0x04, 0xe5, 0xfc, 0x77, + 0x07, 0xc5, 0x6c, 0xf3, 0x0b, 0x34, 0x2a, 0x9a, 0x72, 0x68, 0x33, 0x65, 0xc0, 0x42, 0xdf, 0xdf, + 0xe9, 0xa2, 0x8d, 0xfe, 0x25, 0x78, 0x9e, 0x55, 0x08, 0xbc, 0xe5, 0xbc, 0xdd, 0x02, 0x0a, 0x22, + 0xfc, 0x1f, 0x79, 0xc4, 0x9f, 0x90, 0xdc, 0x7e, 0x66, 0x70, 0x6d, 0x31, 0xf7, 0xed, 0x61, 0x12, + 0xf3, 0xf0, 0x48, 0x78, 0xa2, 0x6e, 0x82, 0x3d, 0xc1, 0x7b, 0xa4, 0xb6, 0x9c, 0xf0, 0x13, 0x49, + 0xfb, 0x98, 0x3f, 0xaf, 0xd5, 0xf0, 0x8f, 0x4a, 0x52, 0x35, 0xe3, 0xab, 0x0f, 0x0b, 0x64, 0xf5, + 0x55, 0x03, 0x9f, 0x12, 0x02, 0x60, 0xf1, 0x04, 0x42, 0xa0, 0x52, 0x02, 0x87, 0xe3, 0x3a, 0x74, + 0xe3, 0xb0, 0xde, 0x0c, 0xb2, 0xdb, 0xd3, 0xc5, 0x78, 0xe6, 0xb3, 0xdc, 0x23, 0x3e, 0x2c, 0x5d, + 0x7d, 0x74, 0x71, 0x61, 0x9c, 0xd7, 0xc8, 0x39, 0x34, 0x5a, 0x41, 0x17, 0xc9, 0xe5, 0x80, 0x8d, + 0xca, 0x1d, 0xd6, 0x4c, 0xe3, 0x19, 0xd5, 0x77, 0x2f, 0x26, 0x89, 0x76, 0x8b, 0x73, 0xfe, 0x60, + 0xe1, 0xb6, 0x79, 0x2b, 0x0a, 0xc3, 0xd9, 0x10, 0xeb, 0x9a, 0x31, 0x16, 0x38, 0x9f, 0x7e, 0x20, + 0xc4, 0xde, 0xc4, 0xc3, 0xe0, 0x6f, 0x53, 0xe2, 0x41, 0x15, 0x17, 0xa1, 0x46, 0x54, 0x35, 0xca, + 0xc0, 0x9c, 0xb5, 0x96, 0xf3, 0x2d, 0xd1, 0xdb, 0x08, 0x74, 0xf7, 0x34, 0x1c, 0x01, 0x97, 0xfb, + 0xb5, 0x8e, 0x54, 0xbf, 0x94, 0x73, 0x01, 0x6b, 0x09, 0x8d, 0xea, 0x9c, 0x98, 0x3b, 0xda, 0x14, + 0xe4, 0xb4, 0xd5, 0x81, 0x87, 0xa1, 0xff, 0x20, 0x04, 0x54, 0x46, 0x65, 0xf4, 0x26, 0xd6, 0x32, + 0x9f, 0x4f, 0x12, 0x7a, 0x99, 0x04, 0xb9, 0x95, 0xd2, 0x27, 0x9c, 0x71, 0x1e, 0x09, 0x4c, 0x30, + 0x27, 0x9d, 0x7b, 0xe3, 0xce, 0x43, 0x5b, 0x62, 0x8f, 0xa1, 0xed, 0xd7, 0x02, 0x03, 0x01, 0x00, + 0x01, 0x02, 0x82, 0x02, 0x00, 0x34, 0xea, 0x7c, 0x6b, 0x5d, 0x12, 0x2a, 0x41, 0xf0, 0x8e, 0x6a, + 0x5e, 0x89, 0x1b, 0x8c, 0x8e, 0xb5, 0x7d, 0xc1, 0xde, 0x86, 0x45, 0xb4, 0x74, 0xf5, 0xe3, 0xea, + 0x21, 0x31, 0x8f, 0xbc, 0xe2, 0xe1, 0x71, 0x1b, 0xcc, 0x0c, 0xc3, 0x05, 0x54, 0xe5, 0x14, 0x93, + 0xc3, 0x62, 0xad, 0x78, 0x6a, 0xc8, 0x16, 0x8e, 0x6e, 0x9a, 0x12, 0xe0, 0x8b, 0xb1, 0x41, 0x6e, + 0x0f, 0xb7, 0x4d, 0x60, 0x62, 0x23, 0xdc, 0x26, 0xe2, 0x6f, 0x4c, 0xc2, 0x00, 0x3f, 0xdf, 0xbe, + 0x57, 0x2a, 0x80, 0x7a, 0x76, 0x10, 0x9f, 0x4f, 0x66, 0x27, 0x92, 0x2f, 0xa6, 0xb8, 0xe3, 0xb1, + 0xb3, 0xc3, 0x47, 0xbf, 0x1f, 0x7f, 0xa0, 0xd3, 0x2f, 0xcc, 0x25, 0x95, 0x05, 0xa3, 0xd8, 0x2b, + 0x33, 0x5b, 0x06, 0x1c, 0x93, 0x92, 0xa2, 0xe2, 0x90, 0x39, 0x57, 0xfe, 0xf6, 0x24, 0xc8, 0xe1, + 0xb1, 0xd9, 0xbb, 0xb9, 0x0a, 0x92, 0x75, 0xf9, 0x8e, 0xab, 0x21, 0x4c, 0x32, 0x27, 0xd7, 0xe7, + 0x5c, 0x93, 0x10, 0x12, 0x35, 0x97, 0x8b, 0x05, 0x43, 0xd5, 0x6c, 0x1b, 0xf3, 0xc7, 0x3e, 0xeb, + 0x19, 0x95, 0x68, 0xa6, 0xd7, 0xcc, 0x75, 0x26, 0x5b, 0x2a, 0xbc, 0x87, 0xd3, 0x3c, 0xe9, 0x57, + 0x38, 0xc6, 0x86, 0x60, 0xd0, 0x67, 0xd6, 0xd1, 0x12, 0x33, 0x38, 0x22, 0x27, 0x13, 0xb9, 0x92, + 0xbf, 0x28, 0xec, 0x45, 0x7c, 0xcf, 0xe2, 0x6f, 0x29, 0xb1, 0xf3, 0xd4, 0x85, 0x80, 0xe3, 0x9d, + 0x95, 0xe2, 0x53, 0x16, 0xb5, 0x04, 0x04, 0xcc, 0x9c, 0x66, 0xf9, 0xf2, 0x81, 0x64, 0x00, 0x9d, + 0xf7, 0x01, 0x63, 0xe3, 0xa3, 0xc9, 0x00, 0x49, 0xb2, 0x48, 0x8c, 0xd9, 0x33, 0x42, 0xc0, 0xac, + 0xc3, 0x44, 0xf3, 0xc7, 0xbe, 0x2a, 0x95, 0x30, 0x6e, 0xd4, 0x2a, 0x4a, 0x1c, 0x57, 0x34, 0x89, + 0x73, 0x00, 0x26, 0x4e, 0x97, 0x3d, 0xf6, 0xfa, 0x45, 0x77, 0x92, 0x87, 0x5b, 0x1e, 0xf2, 0xe7, + 0x18, 0x36, 0x69, 0x0f, 0xad, 0xf1, 0xa0, 0xa0, 0xef, 0x71, 0xa1, 0xa3, 0xb7, 0x2b, 0xd8, 0x91, + 0x6f, 0x91, 0x63, 0x6d, 0x59, 0x43, 0xf8, 0xf9, 0x15, 0xae, 0x56, 0x40, 0x7d, 0xb2, 0x3e, 0xcf, + 0x08, 0x37, 0xc9, 0xa4, 0xd6, 0x22, 0x6d, 0xf1, 0x19, 0xf8, 0xb2, 0xe6, 0x95, 0x1e, 0x62, 0x4e, + 0xbb, 0x6c, 0x61, 0xe7, 0x17, 0xaa, 0x28, 0x14, 0xa9, 0xee, 0x7a, 0x34, 0xa7, 0x65, 0x31, 0x43, + 0x66, 0x43, 0x6e, 0xc4, 0xc7, 0x4a, 0x7d, 0x39, 0x7c, 0x80, 0xa6, 0x1b, 0xd1, 0x3c, 0xf5, 0x3a, + 0x13, 0xe3, 0x6f, 0xc6, 0xf7, 0x8c, 0x86, 0x7c, 0x4e, 0xe1, 0x24, 0x20, 0x65, 0xca, 0xfa, 0x74, + 0xb0, 0x91, 0xb1, 0xb1, 0x0e, 0x55, 0x17, 0xb5, 0xb9, 0x42, 0xe3, 0xc7, 0x9a, 0xa1, 0x27, 0x35, + 0xd6, 0xd0, 0x37, 0xa3, 0x6c, 0xc7, 0x10, 0xb3, 0x55, 0x0a, 0x09, 0x47, 0xfb, 0x58, 0x83, 0xe2, + 0xfc, 0x00, 0xa1, 0xcd, 0xae, 0xcc, 0xf2, 0x83, 0xc8, 0x0e, 0x01, 0xdc, 0x5c, 0xe7, 0x19, 0x00, + 0x65, 0x21, 0x72, 0xec, 0x69, 0x10, 0xd0, 0xaf, 0x7d, 0xe2, 0x94, 0x68, 0x67, 0xbe, 0x3c, 0x5d, + 0x3d, 0x79, 0xd5, 0x99, 0x98, 0x83, 0xc4, 0x51, 0xaf, 0x71, 0x3a, 0xf8, 0x35, 0x6f, 0x36, 0x60, + 0x7d, 0xe3, 0x07, 0x9d, 0xdd, 0x13, 0x67, 0xe5, 0x78, 0x9b, 0x7c, 0x50, 0xa9, 0x4d, 0x45, 0x3c, + 0xa7, 0x17, 0x82, 0x0e, 0xe8, 0xea, 0x24, 0xd2, 0xca, 0x8e, 0x8f, 0x14, 0x6f, 0xc8, 0x67, 0x12, + 0x38, 0x6a, 0x47, 0xbb, 0x9e, 0x60, 0x9e, 0xcf, 0x70, 0xff, 0x54, 0x61, 0x6c, 0xfe, 0xf6, 0x02, + 0x33, 0xe6, 0x98, 0x83, 0x70, 0x39, 0xfa, 0x3b, 0xc4, 0xa5, 0x98, 0x0e, 0x54, 0xe8, 0xfd, 0x09, + 0x21, 0x5a, 0x8d, 0x5a, 0x41, 0x02, 0x82, 0x01, 0x01, 0x00, 0xf9, 0x19, 0xa0, 0x90, 0x5f, 0x5f, + 0x86, 0xd7, 0x5b, 0xb6, 0xb9, 0x40, 0x9d, 0xbc, 0xcf, 0x00, 0x9c, 0xe7, 0xd6, 0xce, 0xcb, 0x12, + 0x82, 0x9a, 0xd2, 0xa9, 0x52, 0xb1, 0x8f, 0xdf, 0x2a, 0x15, 0x5d, 0x09, 0xff, 0x15, 0x8f, 0x5e, + 0x57, 0xf0, 0xd6, 0x00, 0x70, 0x79, 0xfc, 0xe2, 0x07, 0x41, 0xd7, 0xca, 0xa7, 0xa3, 0x02, 0x98, + 0x2c, 0xc0, 0x7b, 0x9c, 0x76, 0x34, 0x97, 0xc2, 0x9d, 0x2d, 0xbf, 0x77, 0x77, 0xfa, 0xa1, 0xad, + 0x93, 0xe0, 0x8f, 0x89, 0xae, 0xf8, 0x4e, 0x60, 0x9d, 0x4c, 0x4f, 0x11, 0x71, 0xab, 0x0a, 0x1d, + 0x7c, 0x14, 0xb3, 0x30, 0x78, 0xfe, 0xd9, 0x44, 0x16, 0x7c, 0x30, 0xc9, 0x4d, 0xfe, 0x67, 0xe6, + 0x0f, 0xc1, 0x11, 0x18, 0xca, 0xa6, 0xa0, 0x5f, 0xbd, 0x95, 0x34, 0x99, 0x18, 0x7e, 0xa2, 0xb8, + 0xd1, 0x42, 0x31, 0x2a, 0x48, 0xce, 0xa1, 0xd7, 0xc4, 0x6b, 0xdb, 0x5a, 0x5f, 0x12, 0x45, 0xad, + 0x14, 0x43, 0x3f, 0xa7, 0x1d, 0x4d, 0xab, 0x76, 0x61, 0xfb, 0x5d, 0xe6, 0xb9, 0xf4, 0x16, 0x44, + 0xde, 0x8a, 0xe4, 0xc8, 0xef, 0xda, 0xd8, 0x14, 0xfd, 0xf9, 0x76, 0x77, 0x6b, 0x9a, 0x8d, 0x81, + 0xa0, 0xc0, 0x60, 0xc6, 0x7c, 0xfd, 0x09, 0xc0, 0xca, 0x4f, 0x9b, 0x77, 0x6f, 0xa0, 0xe6, 0x59, + 0x73, 0xfd, 0xb6, 0xbe, 0xb6, 0x67, 0x9a, 0xe7, 0x40, 0x2c, 0xcf, 0x13, 0xf5, 0x6c, 0xa4, 0x18, + 0x9d, 0xf5, 0x70, 0x73, 0x33, 0x8f, 0x34, 0x08, 0x35, 0x16, 0x0c, 0xbc, 0x67, 0x03, 0x77, 0x07, + 0xfd, 0x67, 0x6a, 0x36, 0x17, 0x96, 0xb8, 0xf0, 0x91, 0x90, 0x01, 0x4e, 0xea, 0x9d, 0x34, 0x6c, + 0x53, 0x77, 0x4e, 0xa5, 0xaa, 0xd3, 0x0d, 0x9f, 0x3d, 0x6f, 0xff, 0x84, 0xa2, 0xca, 0x64, 0x1e, + 0x05, 0xa5, 0xec, 0xb9, 0xbd, 0xce, 0x32, 0x7e, 0xe9, 0x41, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb7, + 0x30, 0x1d, 0x72, 0x39, 0x00, 0x20, 0xa0, 0x9e, 0x7e, 0xef, 0x87, 0xbf, 0x0f, 0x61, 0x61, 0xbb, + 0x90, 0x00, 0xc8, 0x66, 0x47, 0xd0, 0x7b, 0x26, 0xf8, 0x4e, 0x53, 0xdf, 0xab, 0xe6, 0x51, 0x3c, + 0xa2, 0x96, 0x16, 0x3d, 0xeb, 0x27, 0xbc, 0x6b, 0xfb, 0x94, 0x35, 0x6d, 0xda, 0xae, 0x71, 0x59, + 0x5a, 0x6c, 0x39, 0xd5, 0x07, 0x82, 0xa9, 0x9b, 0x0c, 0x52, 0xc3, 0xcc, 0x3f, 0xbc, 0xb7, 0x4d, + 0xc7, 0xad, 0x47, 0x01, 0xce, 0xae, 0x8d, 0x44, 0xcd, 0x11, 0x86, 0x75, 0x95, 0xea, 0x4b, 0x6a, + 0xbc, 0xb4, 0xa7, 0x6e, 0x6c, 0xbb, 0x91, 0x5b, 0x06, 0x8f, 0x34, 0x55, 0x69, 0x04, 0x5a, 0xc5, + 0xff, 0x96, 0xf4, 0xb1, 0x01, 0x07, 0xc8, 0xe9, 0xbd, 0x9e, 0x69, 0xd9, 0x69, 0x75, 0x3d, 0x94, + 0xd1, 0xd1, 0x6a, 0x4d, 0xcb, 0x66, 0xfb, 0xfb, 0x6b, 0x9d, 0x53, 0x1c, 0x45, 0x3d, 0x79, 0x45, + 0xd2, 0x83, 0xfb, 0x5b, 0x9e, 0x91, 0x6f, 0xa0, 0xc2, 0xc2, 0xcb, 0xa4, 0x5c, 0xcf, 0xfa, 0x40, + 0x79, 0xcd, 0xa1, 0xac, 0x80, 0xd7, 0xcb, 0x73, 0xdf, 0x1d, 0x43, 0x72, 0x73, 0x1d, 0x92, 0x8c, + 0x46, 0xdf, 0x2a, 0xb1, 0x77, 0xe7, 0x9b, 0xdb, 0x22, 0x57, 0xc6, 0x9a, 0x3e, 0xcd, 0x69, 0xb3, + 0xe7, 0x7f, 0xa8, 0x82, 0x1d, 0xeb, 0xa9, 0xd6, 0x12, 0x70, 0x0c, 0x5b, 0xf6, 0x02, 0x2d, 0xe2, + 0x2b, 0x57, 0x96, 0xfb, 0xc3, 0x4e, 0x62, 0x52, 0xb4, 0x30, 0xfd, 0x10, 0x25, 0x96, 0xda, 0xa5, + 0x22, 0x2f, 0x4e, 0x04, 0x79, 0x2a, 0x4d, 0xa5, 0x09, 0xeb, 0x87, 0xae, 0xbe, 0xcf, 0x09, 0xf5, + 0xbf, 0xba, 0x5f, 0xd8, 0xc7, 0x3f, 0xa7, 0xeb, 0xd5, 0xff, 0xd5, 0x80, 0x48, 0x36, 0x0b, 0xd4, + 0xc4, 0x4f, 0xb9, 0xc9, 0x91, 0x58, 0x4b, 0x45, 0x99, 0x9d, 0x48, 0xf1, 0xeb, 0xb9, 0x17, 0x02, + 0x82, 0x01, 0x01, 0x00, 0xdc, 0xa4, 0x88, 0x86, 0x99, 0x14, 0x02, 0x5a, 0x4b, 0xd0, 0x84, 0x32, + 0xea, 0x05, 0x4d, 0xce, 0x1b, 0x2d, 0x78, 0x25, 0xdf, 0xd6, 0x5b, 0x7d, 0x4b, 0xcf, 0xd3, 0x81, + 0x98, 0x10, 0x72, 0x34, 0x4e, 0x1f, 0x06, 0xa5, 0x50, 0x42, 0x9e, 0xde, 0xa2, 0x8f, 0xed, 0x11, + 0x00, 0xa0, 0x2d, 0x11, 0x73, 0x54, 0xfc, 0x3b, 0xf5, 0x96, 0x59, 0x3d, 0x7d, 0xc0, 0x4f, 0x2b, + 0xb2, 0xa9, 0x1d, 0x94, 0x62, 0x1e, 0x2e, 0x56, 0x00, 0x53, 0xc1, 0xc2, 0x8d, 0x21, 0xc5, 0xac, + 0x07, 0xb0, 0xa8, 0x63, 0xe9, 0x3d, 0x68, 0x53, 0xba, 0x37, 0xf7, 0xaa, 0x56, 0x36, 0x3f, 0x56, + 0x6d, 0x98, 0x53, 0xda, 0x59, 0x54, 0x56, 0x13, 0x5c, 0x70, 0x79, 0xcf, 0xe7, 0x96, 0xf0, 0x19, + 0xbb, 0xc0, 0x52, 0x2b, 0x11, 0x55, 0xf2, 0x4e, 0x69, 0x50, 0x0f, 0x7a, 0xf4, 0x15, 0xa2, 0x3b, + 0xf5, 0x3b, 0x2b, 0xae, 0xe5, 0xb3, 0x1c, 0xb7, 0x10, 0xa4, 0x88, 0x68, 0x30, 0xbf, 0x93, 0xc3, + 0x32, 0x77, 0x3f, 0xbe, 0xe9, 0xa3, 0xef, 0x5e, 0x77, 0x43, 0x35, 0x64, 0x0d, 0xd6, 0xb6, 0x2e, + 0x40, 0x6c, 0x07, 0xb2, 0xa9, 0xee, 0x89, 0x8f, 0x72, 0x7c, 0x39, 0xa9, 0x6d, 0x8f, 0x23, 0x32, + 0xf7, 0x2a, 0x9f, 0x88, 0xf8, 0x0a, 0x49, 0x04, 0x5a, 0x45, 0x2d, 0xea, 0xb3, 0xae, 0x25, 0xdf, + 0x8b, 0x63, 0xfe, 0x82, 0x32, 0x42, 0x59, 0x87, 0x8b, 0xaa, 0x8a, 0x6f, 0xd6, 0xd5, 0x13, 0xfc, + 0x6a, 0x78, 0x42, 0x9d, 0x6f, 0x56, 0x8a, 0x60, 0x95, 0x54, 0xac, 0x6e, 0xa7, 0xb3, 0x96, 0x1d, + 0x59, 0x5f, 0x2d, 0x70, 0x42, 0xd8, 0x66, 0x14, 0x2d, 0x55, 0x2e, 0x71, 0x65, 0x66, 0x74, 0xf3, + 0x51, 0x03, 0x95, 0xe5, 0xd8, 0x8c, 0xe1, 0xad, 0x28, 0x15, 0x37, 0xa7, 0x8b, 0x11, 0xd3, 0x40, + 0x0b, 0x96, 0x42, 0x81, 0x02, 0x82, 0x01, 0x00, 0x40, 0x38, 0xde, 0x19, 0xed, 0x61, 0xde, 0x0e, + 0x71, 0x82, 0x8e, 0xf7, 0x48, 0x44, 0x5c, 0x1f, 0xa7, 0x62, 0x14, 0xe4, 0x2c, 0xf7, 0x80, 0x5f, + 0xac, 0x89, 0xe0, 0xec, 0x06, 0xbe, 0x7d, 0x40, 0x7d, 0xc1, 0x82, 0x5c, 0xc9, 0xd8, 0x67, 0x55, + 0xe7, 0x85, 0x8b, 0xb0, 0x2f, 0x93, 0x3b, 0x15, 0x01, 0xfe, 0x71, 0x72, 0xd4, 0xfc, 0x8d, 0x12, + 0x69, 0x09, 0x28, 0xfa, 0xfb, 0xe0, 0x5c, 0x88, 0xe6, 0xfb, 0xda, 0x03, 0xca, 0xde, 0x6a, 0xd3, + 0x9c, 0x0b, 0x48, 0xd9, 0x9a, 0xdf, 0xb4, 0x04, 0x3c, 0xa7, 0x6b, 0xae, 0x47, 0x48, 0x57, 0x79, + 0xde, 0x2f, 0xae, 0x84, 0xea, 0x6c, 0xa6, 0xda, 0x2c, 0x10, 0x2f, 0x1c, 0x19, 0xf2, 0x02, 0x88, + 0xad, 0x69, 0x8c, 0xe0, 0x0f, 0x18, 0xa9, 0xc1, 0xad, 0x2a, 0xe2, 0x00, 0x22, 0xc5, 0xec, 0x94, + 0xea, 0xd0, 0x0f, 0x97, 0xd3, 0x91, 0x72, 0xbb, 0xd1, 0x7e, 0xbc, 0x46, 0xa3, 0x18, 0x34, 0x64, + 0xae, 0x37, 0x99, 0x93, 0x4b, 0x4c, 0x3e, 0x9d, 0xbd, 0x7c, 0xf6, 0x5a, 0x77, 0xdf, 0xb3, 0xc7, + 0xe0, 0x17, 0x98, 0x6a, 0xcc, 0xf5, 0x0e, 0xa9, 0x12, 0x04, 0xc6, 0xb8, 0x70, 0xff, 0x58, 0x73, + 0x8b, 0x9f, 0xbe, 0xa6, 0x21, 0xed, 0x62, 0x96, 0x6c, 0x3b, 0xfc, 0xc5, 0x56, 0xd8, 0xa6, 0x86, + 0x24, 0x46, 0xd2, 0x81, 0x82, 0xbb, 0xfc, 0x87, 0x99, 0x83, 0x18, 0x72, 0x16, 0x51, 0xa2, 0x69, + 0x56, 0x15, 0x56, 0x17, 0x62, 0x51, 0xcb, 0x51, 0x5c, 0x13, 0x60, 0x02, 0x3a, 0x0f, 0x40, 0x85, + 0x78, 0x16, 0xc2, 0x3c, 0x0f, 0x47, 0x55, 0xce, 0x68, 0x19, 0x8f, 0x7d, 0x8a, 0xc2, 0x4f, 0xce, + 0xcf, 0x1f, 0x77, 0x51, 0xa2, 0x67, 0xae, 0x8a, 0xf7, 0x4c, 0xdb, 0xa6, 0x86, 0xc4, 0x2d, 0xf0, + 0x35, 0xb6, 0x65, 0x2d, 0xed, 0xa2, 0x76, 0x81, 0x02, 0x82, 0x01, 0x01, 0x00, 0xea, 0xb4, 0xcd, + 0x32, 0x1c, 0xcf, 0xdb, 0x03, 0x08, 0x66, 0xaf, 0x93, 0xdf, 0xce, 0x8e, 0x0d, 0xfd, 0x69, 0x27, + 0xe0, 0xe4, 0x5b, 0xd8, 0x5c, 0xdd, 0x11, 0x37, 0xa0, 0x88, 0xdd, 0x51, 0xa3, 0xd1, 0x12, 0xe2, + 0x50, 0x58, 0xa0, 0x42, 0x39, 0x58, 0xac, 0x70, 0xcc, 0x57, 0xe2, 0x51, 0x05, 0xba, 0x35, 0xdc, + 0x01, 0xd4, 0xb1, 0x5b, 0xbc, 0xe8, 0x90, 0x09, 0x08, 0x00, 0x4e, 0x1d, 0xf4, 0xef, 0x72, 0x53, + 0x71, 0x01, 0x8b, 0xa4, 0xdf, 0x70, 0xa7, 0x88, 0xd7, 0x1e, 0x44, 0x85, 0xfa, 0xa9, 0xde, 0x76, + 0x4c, 0x15, 0xc3, 0x37, 0xd3, 0x85, 0x64, 0x71, 0x7b, 0xc7, 0xc0, 0x10, 0x67, 0x21, 0x34, 0xf3, + 0xda, 0x2b, 0x29, 0x42, 0x20, 0xd6, 0xeb, 0xe0, 0x61, 0xe7, 0x59, 0xb6, 0xed, 0x11, 0x64, 0x96, + 0x6e, 0xb0, 0x99, 0x5d, 0x01, 0xd7, 0xb2, 0xc6, 0xd4, 0xeb, 0x75, 0x66, 0x11, 0xff, 0x55, 0x33, + 0x02, 0x22, 0x37, 0xea, 0xf9, 0x7b, 0x8c, 0x19, 0x39, 0xdc, 0x2b, 0x24, 0xad, 0x99, 0xe8, 0x59, + 0xc9, 0x83, 0xd3, 0x2b, 0x12, 0xe2, 0xff, 0x03, 0x08, 0x41, 0xd5, 0x98, 0xd8, 0x7d, 0x0b, 0xc4, + 0xe2, 0xca, 0x25, 0x5f, 0xf9, 0x57, 0xbe, 0xc1, 0x0d, 0xd7, 0xb7, 0x4d, 0x86, 0x35, 0x16, 0xa9, + 0xab, 0x90, 0x1c, 0xc6, 0xee, 0x1f, 0xd6, 0xfa, 0xd2, 0xe0, 0x4b, 0xc3, 0x7f, 0xe7, 0xb1, 0x84, + 0x89, 0xbe, 0x45, 0x40, 0x56, 0x75, 0xd0, 0x21, 0x70, 0x09, 0x64, 0xd7, 0xb5, 0xa2, 0xec, 0x5e, + 0xbe, 0x03, 0x2f, 0x8c, 0x20, 0x4f, 0x88, 0xfe, 0xbd, 0x2c, 0xa9, 0x70, 0xcd, 0x85, 0xb2, 0x11, + 0x24, 0xe4, 0x5c, 0xf4, 0x5f, 0xaa, 0x6d, 0x43, 0xa1, 0xfc, 0xd4, 0x57, 0xb8, 0xa9, 0x37, 0xf0, + 0x77, 0x6a, 0x37, 0x9b, 0xc5, 0xc3, 0x40, 0x27, 0x90, 0x15, 0x6b, 0x22, 0x11 +}; + +static const uint8_t composite65_rsa4096pkcs15_pub[] = { + 0x07, 0xa5, 0xae, 0x70, 0xf5, 0xb7, 0x2a, 0x6e, 0x03, 0xdb, 0xbb, 0x3f, 0x32, 0x83, 0xed, 0xe3, + 0x77, 0x53, 0xa8, 0x2e, 0x65, 0x64, 0x3c, 0xa4, 0x92, 0x97, 0x24, 0xc8, 0x22, 0xe9, 0xde, 0xe1, + 0xc4, 0x27, 0x82, 0xb9, 0x5a, 0x21, 0x3c, 0xb8, 0x2f, 0x65, 0x48, 0x49, 0x20, 0x27, 0x67, 0xa2, + 0x6c, 0x28, 0x02, 0x32, 0x4a, 0x71, 0x79, 0x5f, 0x93, 0x90, 0x98, 0xde, 0x90, 0x84, 0x29, 0x0c, + 0x99, 0x23, 0xd2, 0xe8, 0xbf, 0x6c, 0xcd, 0x44, 0xbb, 0xe2, 0x30, 0x50, 0x65, 0x38, 0x0c, 0x4f, + 0x3d, 0xe9, 0xbc, 0x11, 0x28, 0xfd, 0x15, 0xa8, 0xb8, 0x7a, 0x37, 0x16, 0xc5, 0x6b, 0x74, 0x98, + 0xc6, 0x94, 0x13, 0xb4, 0x94, 0x5d, 0xdf, 0x38, 0xf8, 0x89, 0x17, 0x98, 0x1d, 0x0d, 0x7c, 0xc6, + 0x10, 0x12, 0x86, 0x6e, 0x0f, 0xb5, 0xf3, 0xd0, 0x06, 0xd7, 0xcb, 0xa1, 0xe9, 0xb1, 0xe0, 0xb8, + 0xed, 0x0c, 0x61, 0x37, 0x1e, 0x3f, 0x09, 0x3e, 0x89, 0x19, 0xd5, 0x05, 0x92, 0x0c, 0x2b, 0xd7, + 0x86, 0xf2, 0xa8, 0xe2, 0xdb, 0x73, 0xf1, 0xcb, 0xf1, 0x3a, 0xb1, 0x14, 0x4f, 0x1c, 0xf0, 0xa9, + 0xd6, 0x53, 0xc9, 0x1a, 0x69, 0x9e, 0xd5, 0x33, 0xc8, 0xec, 0x7a, 0xb0, 0xc4, 0x20, 0xa7, 0xc1, + 0xdf, 0x16, 0xf0, 0xf0, 0xd5, 0xd0, 0xaf, 0x7b, 0x46, 0x2a, 0x5d, 0x48, 0xc6, 0x7a, 0x90, 0xec, + 0x52, 0xef, 0xfa, 0xc2, 0x55, 0x87, 0xaf, 0x8b, 0xff, 0xa4, 0x20, 0xf1, 0x42, 0xfd, 0xf8, 0x29, + 0xe9, 0x7b, 0xa8, 0x2a, 0xef, 0x88, 0x24, 0xbc, 0x9f, 0x21, 0xf3, 0xfe, 0xeb, 0x61, 0x11, 0xa5, + 0x83, 0x11, 0x40, 0xc6, 0xc2, 0xda, 0x2b, 0x19, 0xb9, 0x65, 0x06, 0x59, 0xe7, 0x58, 0x29, 0xf7, + 0x02, 0x7b, 0xc9, 0x12, 0x52, 0x80, 0x15, 0x95, 0x64, 0x2e, 0x3c, 0x3d, 0xb0, 0x68, 0x3e, 0xd0, + 0x24, 0xe3, 0xef, 0x20, 0xe6, 0x62, 0xfc, 0xad, 0xac, 0x86, 0x48, 0xad, 0x04, 0x48, 0xc6, 0x21, + 0x67, 0x22, 0xac, 0x8f, 0x5d, 0x21, 0xe7, 0x66, 0x8f, 0x94, 0x82, 0xe9, 0x42, 0xd6, 0xf2, 0x83, + 0x68, 0xce, 0x7d, 0x1a, 0x67, 0x0b, 0xf2, 0x2f, 0x25, 0xc2, 0xc7, 0x38, 0xda, 0xd9, 0x39, 0x0b, + 0xaf, 0xe1, 0x56, 0xa7, 0x2a, 0xb0, 0x7d, 0x54, 0x73, 0x37, 0x38, 0x26, 0x27, 0x55, 0x6b, 0x22, + 0xe1, 0x11, 0x43, 0xf7, 0xbd, 0xa5, 0x67, 0x05, 0x81, 0x2d, 0x1e, 0x7e, 0x27, 0x8e, 0x5b, 0x9d, + 0x8e, 0xe2, 0x19, 0x89, 0x14, 0x45, 0xdf, 0xef, 0xa2, 0x46, 0x26, 0xd2, 0x06, 0xc7, 0x5d, 0x30, + 0xc5, 0xc5, 0xee, 0xff, 0xae, 0x57, 0xc4, 0x55, 0xbe, 0x52, 0x37, 0x9d, 0x9c, 0x95, 0x6a, 0xa1, + 0xde, 0xa8, 0xf8, 0x9c, 0x9d, 0xe8, 0x79, 0x30, 0x4c, 0x76, 0xd1, 0xf5, 0x85, 0xf6, 0xb1, 0x0d, + 0x41, 0x9b, 0x7b, 0xa0, 0x8d, 0x73, 0x75, 0x6b, 0xd5, 0x20, 0x15, 0x69, 0xdb, 0x2a, 0xd8, 0x67, + 0x28, 0x1c, 0x3f, 0x43, 0x3e, 0x80, 0xd9, 0x16, 0xbf, 0x14, 0xde, 0xcc, 0x56, 0xae, 0x3c, 0x0d, + 0x99, 0x6c, 0x2c, 0xfa, 0xc2, 0x98, 0x39, 0x66, 0x17, 0xd7, 0x1a, 0xe5, 0x23, 0xb8, 0x80, 0x7e, + 0x8e, 0x65, 0x13, 0x2a, 0x80, 0xe8, 0xda, 0xb7, 0xd4, 0xcb, 0x41, 0x18, 0xe7, 0xe9, 0x16, 0x41, + 0x11, 0x92, 0x2d, 0x2c, 0x3c, 0x1d, 0xcb, 0xc9, 0x16, 0x33, 0x12, 0x0c, 0x6f, 0x4a, 0x21, 0x0e, + 0xa9, 0xf6, 0xdf, 0xa2, 0xaf, 0x85, 0x41, 0xea, 0x0f, 0xe1, 0x8a, 0xf2, 0x13, 0xd1, 0x2c, 0x6c, + 0x13, 0x0d, 0x7f, 0xd0, 0x82, 0xcd, 0xcf, 0x67, 0xea, 0x83, 0x13, 0xd8, 0x68, 0xd2, 0xc6, 0x29, + 0x3d, 0x56, 0x55, 0x12, 0xf4, 0x8b, 0x40, 0xfc, 0x04, 0xd1, 0x52, 0xd0, 0xeb, 0x3e, 0x89, 0xef, + 0x86, 0xec, 0xeb, 0x65, 0x1c, 0x77, 0xeb, 0x36, 0x2b, 0x3b, 0x68, 0x91, 0x3e, 0x63, 0xae, 0x6c, + 0xe8, 0xdc, 0xa1, 0xd8, 0x28, 0x6d, 0x21, 0xd4, 0x8c, 0xe1, 0xdf, 0x93, 0xbb, 0xc9, 0xd5, 0x8e, + 0x7d, 0x9b, 0x20, 0x0b, 0x11, 0x9a, 0xbd, 0x84, 0x20, 0x36, 0xe3, 0x85, 0x35, 0x27, 0xfb, 0x2d, + 0x4f, 0xc2, 0xb5, 0x35, 0xad, 0x28, 0xf3, 0x52, 0x31, 0x31, 0x90, 0x14, 0x10, 0x8b, 0x2d, 0x61, + 0x2b, 0x1e, 0x06, 0x2e, 0x32, 0xa1, 0x37, 0xaf, 0xc2, 0x98, 0x57, 0x59, 0xb9, 0x2b, 0x1a, 0x93, + 0x03, 0x8c, 0x2c, 0xe3, 0x90, 0xfb, 0x2e, 0x9b, 0xf4, 0x5a, 0x91, 0x7a, 0xcd, 0x9c, 0x08, 0x64, + 0x52, 0xad, 0x6f, 0x24, 0xab, 0x99, 0x28, 0x0f, 0x70, 0xa7, 0xdc, 0xdd, 0x43, 0xb3, 0xdd, 0x2a, + 0x55, 0x5a, 0x10, 0xdb, 0x41, 0x79, 0xa2, 0xe3, 0x41, 0x35, 0x90, 0xef, 0xd4, 0xad, 0xaa, 0x26, + 0xc5, 0xca, 0x20, 0xb1, 0x5a, 0xb8, 0x86, 0x16, 0x1f, 0x87, 0x08, 0x85, 0xbd, 0x7c, 0x95, 0x5d, + 0x30, 0x0c, 0xb0, 0xa6, 0x7a, 0xdd, 0x5c, 0xeb, 0xdc, 0xbf, 0x06, 0x75, 0x46, 0x11, 0xb0, 0xd2, + 0x4e, 0x0f, 0x25, 0x0c, 0xff, 0xb9, 0xbc, 0xdf, 0xce, 0x5f, 0x67, 0x3d, 0x49, 0x34, 0xbb, 0x06, + 0xc6, 0x28, 0xdc, 0x70, 0x3c, 0xb2, 0x85, 0x12, 0x76, 0x55, 0x22, 0x78, 0x33, 0x26, 0x52, 0x09, + 0x2e, 0xb5, 0xc0, 0x70, 0xf2, 0x64, 0x5e, 0x66, 0x53, 0x55, 0x37, 0x2d, 0xec, 0xd6, 0xd0, 0x0b, + 0x4c, 0xcc, 0x2b, 0x33, 0x2e, 0x7d, 0x9b, 0xc1, 0x08, 0x60, 0xb7, 0x73, 0xee, 0xdb, 0xfd, 0xd7, + 0x3e, 0xaa, 0x74, 0x8b, 0xf5, 0xe6, 0x51, 0xf8, 0xa2, 0x01, 0xa0, 0xfe, 0x6e, 0xd7, 0xed, 0x8c, + 0x32, 0xff, 0x61, 0x26, 0x98, 0xb8, 0xd1, 0x31, 0x62, 0x51, 0x9e, 0x4d, 0x4c, 0x33, 0xc3, 0x18, + 0x7c, 0x5f, 0xe8, 0x8d, 0x71, 0x4b, 0x25, 0x6d, 0x5c, 0xa7, 0xd7, 0x62, 0xee, 0x24, 0x8d, 0xa0, + 0x26, 0xae, 0xd1, 0x7d, 0xe6, 0xa0, 0xe3, 0xa5, 0xc9, 0x97, 0x88, 0xe6, 0x60, 0x53, 0x8f, 0xd3, + 0xad, 0x72, 0xc8, 0x16, 0xe3, 0xa3, 0x98, 0xa1, 0x66, 0xba, 0x9c, 0xb3, 0xe6, 0x13, 0x59, 0xec, + 0x7e, 0x83, 0x3f, 0x3c, 0xca, 0xfa, 0x6a, 0xa5, 0xe1, 0x58, 0x65, 0x95, 0x92, 0x3c, 0x8c, 0x33, + 0xb9, 0xd6, 0xa7, 0xbd, 0xe2, 0xb8, 0xf4, 0x9e, 0x8b, 0xc7, 0x30, 0x6f, 0xf0, 0x9c, 0xce, 0xe1, + 0xa7, 0x76, 0x97, 0x73, 0xa0, 0xb2, 0x58, 0x05, 0x2d, 0xd0, 0xbd, 0x13, 0x24, 0x57, 0x9a, 0x4b, + 0xa5, 0x35, 0x33, 0x23, 0x4c, 0xaf, 0xcf, 0x52, 0x61, 0x72, 0x5f, 0xce, 0x08, 0xbd, 0xde, 0x29, + 0xd8, 0x3f, 0xd0, 0x40, 0x84, 0xeb, 0xd9, 0x9d, 0x78, 0xfa, 0x3c, 0xa5, 0x88, 0x08, 0x6d, 0x3d, + 0x16, 0x7f, 0x8b, 0x47, 0xbe, 0xec, 0x15, 0x85, 0x79, 0xba, 0x32, 0x10, 0xa0, 0xd7, 0xf3, 0x2f, + 0xd4, 0xa0, 0x9c, 0x68, 0x5a, 0x73, 0x86, 0x4a, 0xce, 0xdf, 0x45, 0x33, 0x31, 0x5e, 0xb7, 0x04, + 0x88, 0x8f, 0x50, 0x3b, 0x40, 0xc6, 0x48, 0xee, 0xcd, 0x9d, 0xf3, 0x6f, 0xfb, 0x90, 0x7d, 0x6b, + 0x36, 0x18, 0x8a, 0x53, 0xad, 0x14, 0x2c, 0x98, 0x31, 0x6e, 0xf4, 0x55, 0x47, 0xd1, 0xda, 0x3f, + 0x8e, 0x1b, 0x03, 0xd9, 0x41, 0x85, 0x16, 0xd3, 0xad, 0x0b, 0x47, 0xa0, 0x46, 0xff, 0xd6, 0x81, + 0x18, 0xff, 0xd6, 0x1a, 0x23, 0x1e, 0xff, 0xce, 0xd4, 0xa7, 0x74, 0xcf, 0x4f, 0x10, 0xf5, 0x10, + 0xad, 0xcf, 0x41, 0xb1, 0xb9, 0xb3, 0x7e, 0xa7, 0x09, 0x43, 0xa8, 0x03, 0x4b, 0xfc, 0x69, 0xe8, + 0x27, 0xb5, 0xe4, 0x27, 0x45, 0x2f, 0x5f, 0x9f, 0x7f, 0x30, 0x65, 0x24, 0x36, 0xc9, 0x69, 0xa7, + 0x8d, 0xf8, 0xc6, 0xf1, 0x17, 0xfc, 0x8a, 0x40, 0x72, 0x0e, 0xc7, 0x83, 0x26, 0xd8, 0x5b, 0x30, + 0xc3, 0xe7, 0xff, 0x8e, 0x08, 0x42, 0xb3, 0x61, 0xed, 0x1e, 0xc7, 0x58, 0xc3, 0xf4, 0xad, 0x5e, + 0x28, 0x56, 0x80, 0xe6, 0x21, 0xf5, 0xb9, 0xa3, 0x6c, 0x28, 0x7d, 0x52, 0xe5, 0x26, 0xb3, 0x1a, + 0xca, 0x86, 0xf1, 0xea, 0x0d, 0x77, 0x65, 0xb8, 0x0e, 0xe3, 0x1f, 0x66, 0x6e, 0x67, 0x5c, 0xbb, + 0x29, 0x92, 0xea, 0xe3, 0x39, 0xad, 0x14, 0x00, 0x36, 0xdc, 0xff, 0x04, 0x7d, 0x68, 0xff, 0x26, + 0xf1, 0x63, 0x19, 0xdc, 0x3a, 0x90, 0x60, 0xa1, 0x42, 0x8c, 0xcf, 0xa2, 0x1c, 0xca, 0x95, 0x69, + 0x2e, 0x41, 0x94, 0x92, 0x58, 0xfd, 0x05, 0x07, 0x3d, 0xef, 0x9e, 0x0e, 0x9e, 0xa7, 0x4e, 0x81, + 0x88, 0x16, 0x4b, 0xdf, 0x5d, 0x2a, 0x0e, 0x30, 0x74, 0x2b, 0x3a, 0x64, 0xfd, 0xc7, 0x36, 0x4e, + 0x5d, 0x87, 0x3c, 0xca, 0x2a, 0x63, 0x60, 0xeb, 0x77, 0x88, 0xfc, 0x7f, 0xe1, 0x91, 0x2e, 0x07, + 0x2b, 0x23, 0x6d, 0x10, 0xe1, 0x7a, 0x1e, 0x16, 0xc7, 0x0a, 0x1f, 0x8f, 0xad, 0x06, 0xcb, 0xf9, + 0x7d, 0xe8, 0xa1, 0xfa, 0x7c, 0xbf, 0x07, 0x6e, 0x7f, 0xf5, 0xae, 0x7e, 0x5a, 0xc1, 0xf2, 0xe3, + 0xc9, 0x63, 0x25, 0xf6, 0x2d, 0x3d, 0xdd, 0x12, 0x39, 0x51, 0x30, 0x26, 0x74, 0x08, 0x0e, 0x98, + 0x67, 0x57, 0xa6, 0x8f, 0xef, 0xd6, 0x46, 0x93, 0xa3, 0x8d, 0x75, 0xbb, 0x03, 0xf4, 0x25, 0xa2, + 0x73, 0x5f, 0x8e, 0x62, 0xc4, 0xf7, 0x5f, 0x44, 0x95, 0x6f, 0x74, 0x4f, 0x3e, 0x83, 0x17, 0xc7, + 0x1e, 0x40, 0xd0, 0x10, 0xb1, 0xe1, 0x16, 0xd7, 0x73, 0xe7, 0xba, 0x70, 0x93, 0x70, 0x46, 0x9e, + 0xa3, 0x02, 0xf7, 0xbf, 0xbb, 0xc4, 0xb6, 0xb2, 0xb5, 0xc7, 0x2c, 0x87, 0xd6, 0x12, 0x11, 0x1b, + 0x57, 0x34, 0x31, 0x36, 0xd7, 0xfd, 0x8c, 0xac, 0x80, 0xac, 0xf3, 0xcd, 0xfd, 0x27, 0x41, 0x13, + 0xee, 0x27, 0x2f, 0x23, 0x34, 0x87, 0xfa, 0xdd, 0xd5, 0x3c, 0x04, 0x39, 0xa9, 0x48, 0xea, 0x1d, + 0xeb, 0x5d, 0x6b, 0x9d, 0xcd, 0x06, 0x50, 0x25, 0xb5, 0x4b, 0x5a, 0x24, 0x60, 0x2c, 0x97, 0xf7, + 0xb4, 0x0a, 0x3a, 0x24, 0x98, 0x73, 0x7d, 0xab, 0x14, 0x5f, 0x32, 0xcc, 0x3d, 0x66, 0xa4, 0x3e, + 0x48, 0xc4, 0xc1, 0xcb, 0x19, 0xa4, 0x63, 0x25, 0xf6, 0x93, 0xd9, 0xed, 0xb1, 0x77, 0x58, 0x53, + 0x2c, 0x76, 0xad, 0x84, 0x05, 0x84, 0x1e, 0x87, 0x46, 0xa1, 0x1c, 0x37, 0x89, 0x76, 0xcd, 0xc9, + 0xcf, 0x38, 0x72, 0x6c, 0x1a, 0x7d, 0x01, 0x6c, 0xc9, 0x49, 0x37, 0xf2, 0xe8, 0x03, 0x35, 0x81, + 0x27, 0x4b, 0x19, 0x50, 0xd0, 0x19, 0x06, 0x14, 0xcd, 0xdc, 0x7d, 0x08, 0xdd, 0x68, 0x39, 0xf8, + 0xcb, 0xaf, 0x36, 0x14, 0xf3, 0x98, 0x43, 0xff, 0x62, 0x14, 0x1a, 0xac, 0x32, 0x37, 0xeb, 0x0d, + 0xd5, 0xe2, 0x64, 0x05, 0x2f, 0xd4, 0x3a, 0x0d, 0x85, 0x31, 0x0b, 0xb2, 0xde, 0x64, 0xe4, 0x34, + 0xf2, 0x81, 0x7b, 0x93, 0xe0, 0xc9, 0xa5, 0x87, 0x29, 0xed, 0xda, 0xb9, 0x8a, 0xc4, 0x5e, 0x6a, + 0x27, 0x5d, 0xaa, 0x00, 0xed, 0x97, 0x6d, 0x24, 0x38, 0xa2, 0xee, 0x06, 0x9b, 0x67, 0x18, 0xfb, + 0x9d, 0x16, 0x7b, 0x5b, 0xdb, 0x16, 0xec, 0x09, 0xb4, 0xd3, 0xdb, 0xa2, 0x86, 0xf5, 0x43, 0xee, + 0x18, 0x8d, 0x4d, 0x67, 0xf1, 0x04, 0x13, 0x36, 0xef, 0x9a, 0x5d, 0x98, 0xf4, 0x77, 0xcd, 0x3a, + 0x9b, 0x1b, 0xeb, 0xd5, 0xc9, 0xbb, 0x65, 0xff, 0xdf, 0xe9, 0x01, 0x77, 0x13, 0xac, 0x91, 0x7d, + 0x92, 0x26, 0x5e, 0xdd, 0x1a, 0xf0, 0x77, 0x5f, 0x75, 0xc3, 0x8b, 0x2b, 0xca, 0xab, 0xb5, 0x2d, + 0xef, 0x61, 0x98, 0xd3, 0x9c, 0x4a, 0x41, 0xbf, 0x47, 0xa8, 0x5c, 0xa2, 0xb7, 0x08, 0xc3, 0xc3, + 0x6f, 0x79, 0x91, 0x79, 0x1c, 0xb5, 0x1d, 0x1f, 0x88, 0x27, 0x48, 0xda, 0x4c, 0x05, 0x44, 0xa8, + 0x36, 0xb6, 0xb4, 0xc5, 0xc4, 0x9d, 0xa3, 0x07, 0x69, 0xad, 0x26, 0xab, 0xa0, 0x02, 0x03, 0xda, + 0x33, 0xa6, 0x85, 0x93, 0xee, 0xbf, 0x59, 0x89, 0x70, 0x3e, 0xdc, 0x49, 0x6d, 0xf1, 0x55, 0x5d, + 0xea, 0x3c, 0x8d, 0xe4, 0xe9, 0x29, 0x9b, 0xa5, 0x5f, 0xa5, 0x37, 0xe6, 0xa4, 0x32, 0x4d, 0x1c, + 0xc3, 0x4a, 0x63, 0x67, 0xda, 0x58, 0x41, 0xe6, 0x61, 0x8e, 0xc9, 0x66, 0x20, 0x86, 0x67, 0x01, + 0x96, 0x86, 0x36, 0x8b, 0xca, 0x0c, 0x44, 0x5b, 0xcb, 0xff, 0xcc, 0x88, 0x47, 0x05, 0x68, 0x60, + 0xd3, 0x06, 0xad, 0x96, 0xd9, 0xdb, 0xcf, 0x49, 0x6f, 0x85, 0x04, 0x0f, 0x3c, 0xbc, 0xcb, 0xa7, + 0xcb, 0x1f, 0xc7, 0xbf, 0xad, 0x12, 0xf9, 0x72, 0x99, 0x9d, 0x36, 0xf4, 0xde, 0x28, 0x81, 0xfc, + 0xfb, 0xb0, 0xe2, 0xfa, 0xe6, 0xf0, 0xc5, 0x70, 0xe4, 0x9c, 0xfc, 0x3c, 0x2e, 0xab, 0x3b, 0x23, + 0x0e, 0xb1, 0x35, 0x13, 0x66, 0xb4, 0xf4, 0x3a, 0xe3, 0x11, 0xd0, 0x21, 0x6a, 0x10, 0x50, 0x71, + 0x3d, 0xf2, 0xfe, 0xb0, 0x7a, 0xd1, 0xfa, 0x25, 0x36, 0x42, 0xaf, 0x4d, 0x95, 0x7c, 0xac, 0xa5, + 0xe9, 0x45, 0xa1, 0x0c, 0x8b, 0x87, 0xf2, 0xc5, 0x66, 0x6e, 0x66, 0x2d, 0x9a, 0x78, 0x5e, 0x57, + 0xbb, 0xda, 0x28, 0xd4, 0x1e, 0x8c, 0x80, 0xb3, 0x60, 0x34, 0xb3, 0x9d, 0x51, 0x78, 0xae, 0xb3, + 0x4d, 0xa5, 0xcc, 0x54, 0xe6, 0xb3, 0x31, 0x92, 0xea, 0xe5, 0xd4, 0x4c, 0xe4, 0x6d, 0xd5, 0xd8, + 0xc7, 0x67, 0x23, 0x51, 0x02, 0x29, 0xd1, 0xf3, 0xf5, 0x63, 0x14, 0x9d, 0xa5, 0x81, 0xb4, 0xee, + 0xe6, 0xdf, 0x18, 0x26, 0xef, 0x60, 0x7a, 0x91, 0xeb, 0x68, 0xc1, 0xfc, 0x24, 0x4c, 0x01, 0xc6, + 0x42, 0x89, 0x47, 0xae, 0xba, 0x82, 0x5c, 0x9d, 0x5e, 0x9e, 0x90, 0xdf, 0x72, 0xc3, 0xa2, 0x15, + 0xdf, 0x75, 0x56, 0x24, 0xc3, 0x03, 0x10, 0x0c, 0x5a, 0xca, 0xfe, 0xaf, 0xc5, 0x7d, 0x6f, 0x11, + 0x04, 0xb9, 0x2c, 0x30, 0xf4, 0xc9, 0xb3, 0x0c, 0x29, 0x70, 0xd2, 0x73, 0xb2, 0xcc, 0x6e, 0xd8, + 0x17, 0x97, 0xe2, 0xd8, 0x56, 0x27, 0x71, 0x32, 0xad, 0xbf, 0x26, 0x36, 0xba, 0x24, 0x6a, 0xf5, + 0x22, 0x8f, 0x82, 0x45, 0x78, 0x2f, 0xdf, 0x95, 0x98, 0x2d, 0x27, 0x54, 0x4e, 0xbb, 0x1c, 0x09, + 0x8e, 0x03, 0xe1, 0xc8, 0x4a, 0xad, 0x70, 0xe8, 0x5d, 0x30, 0xe3, 0x3e, 0x66, 0xb2, 0x91, 0xe3, + 0xb1, 0x46, 0x97, 0x54, 0xee, 0x07, 0xeb, 0xf5, 0xda, 0xc1, 0x16, 0xe2, 0x74, 0xb6, 0x1e, 0xad, + 0xd3, 0xc3, 0x3e, 0x2c, 0xca, 0xf6, 0x4e, 0x68, 0xa0, 0x5a, 0x4c, 0xfa, 0xa9, 0x58, 0xaa, 0x5c, + 0xca, 0x05, 0x72, 0xc8, 0x30, 0x41, 0x6a, 0x79, 0x2c, 0x17, 0x8c, 0xd6, 0x01, 0x53, 0x25, 0x90, + 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xb2, 0x40, 0x23, 0x3c, 0x5b, 0x4f, 0xda, + 0xe5, 0x29, 0x4d, 0x41, 0xf1, 0x1c, 0x74, 0xae, 0xcc, 0x1f, 0xd2, 0x9f, 0x3b, 0x42, 0x8d, 0x00, + 0x03, 0xec, 0xfc, 0x15, 0xef, 0xaa, 0xa4, 0x42, 0x96, 0xbb, 0x5c, 0x24, 0xc7, 0x83, 0x31, 0xf1, + 0x7c, 0x40, 0x85, 0x62, 0x08, 0xf0, 0xb3, 0x9f, 0xd1, 0x0e, 0xdd, 0xde, 0x28, 0xbb, 0x3c, 0x1b, + 0xbe, 0xbb, 0x88, 0x61, 0xf7, 0x07, 0xe7, 0x19, 0xb9, 0x7c, 0xfc, 0xc0, 0xcd, 0x59, 0x8d, 0x06, + 0xfe, 0x62, 0xef, 0xc9, 0x09, 0x70, 0x5f, 0x8a, 0x9c, 0x01, 0x4e, 0xbe, 0xe7, 0xdf, 0xbd, 0x91, + 0x27, 0x62, 0x14, 0x92, 0xf8, 0x66, 0xa0, 0xb4, 0xf1, 0x2c, 0x89, 0xcd, 0xc1, 0xc4, 0x15, 0x18, + 0x49, 0x54, 0x3e, 0x39, 0xd2, 0xfd, 0x17, 0x73, 0x04, 0xbf, 0x10, 0x45, 0xd5, 0x09, 0x82, 0x7c, + 0xd5, 0x80, 0x8c, 0xb8, 0x6f, 0x78, 0x11, 0xe1, 0x0a, 0xe5, 0x21, 0xaa, 0x63, 0x49, 0xb4, 0x94, + 0xcf, 0xfa, 0xc3, 0x88, 0xb6, 0xb8, 0x86, 0xc1, 0xcd, 0x9d, 0x26, 0x77, 0x2f, 0x73, 0x78, 0x25, + 0x6b, 0xa8, 0x1c, 0xb7, 0x3f, 0x87, 0x2f, 0x27, 0xe5, 0x25, 0xe3, 0x71, 0xb6, 0x06, 0x8f, 0xdd, + 0xc9, 0x19, 0xb2, 0xf5, 0xd6, 0x38, 0x22, 0x92, 0x36, 0x20, 0xdf, 0x47, 0xe7, 0x44, 0x2f, 0x0b, + 0xaa, 0xe4, 0x14, 0x88, 0x75, 0xe4, 0xb7, 0x2b, 0x02, 0x3f, 0x95, 0x75, 0x5a, 0x78, 0x90, 0x09, + 0x47, 0xeb, 0xf6, 0x29, 0xf4, 0x7c, 0x40, 0xb9, 0xcb, 0xad, 0xe3, 0xe3, 0x9e, 0xce, 0xd0, 0x02, + 0xfd, 0xca, 0x1d, 0xfc, 0xb7, 0xf8, 0x4d, 0x11, 0x73, 0x3a, 0x7e, 0xf2, 0x57, 0xba, 0xab, 0xc7, + 0x06, 0xba, 0xd5, 0x39, 0x08, 0x9b, 0xba, 0x74, 0x69, 0x01, 0xc9, 0xa1, 0x61, 0x1f, 0x49, 0x06, + 0x76, 0x60, 0x28, 0xa4, 0x27, 0xf1, 0x70, 0x19, 0x22, 0x04, 0xe5, 0xfc, 0x77, 0x07, 0xc5, 0x6c, + 0xf3, 0x0b, 0x34, 0x2a, 0x9a, 0x72, 0x68, 0x33, 0x65, 0xc0, 0x42, 0xdf, 0xdf, 0xe9, 0xa2, 0x8d, + 0xfe, 0x25, 0x78, 0x9e, 0x55, 0x08, 0xbc, 0xe5, 0xbc, 0xdd, 0x02, 0x0a, 0x22, 0xfc, 0x1f, 0x79, + 0xc4, 0x9f, 0x90, 0xdc, 0x7e, 0x66, 0x70, 0x6d, 0x31, 0xf7, 0xed, 0x61, 0x12, 0xf3, 0xf0, 0x48, + 0x78, 0xa2, 0x6e, 0x82, 0x3d, 0xc1, 0x7b, 0xa4, 0xb6, 0x9c, 0xf0, 0x13, 0x49, 0xfb, 0x98, 0x3f, + 0xaf, 0xd5, 0xf0, 0x8f, 0x4a, 0x52, 0x35, 0xe3, 0xab, 0x0f, 0x0b, 0x64, 0xf5, 0x55, 0x03, 0x9f, + 0x12, 0x02, 0x60, 0xf1, 0x04, 0x42, 0xa0, 0x52, 0x02, 0x87, 0xe3, 0x3a, 0x74, 0xe3, 0xb0, 0xde, + 0x0c, 0xb2, 0xdb, 0xd3, 0xc5, 0x78, 0xe6, 0xb3, 0xdc, 0x23, 0x3e, 0x2c, 0x5d, 0x7d, 0x74, 0x71, + 0x61, 0x9c, 0xd7, 0xc8, 0x39, 0x34, 0x5a, 0x41, 0x17, 0xc9, 0xe5, 0x80, 0x8d, 0xca, 0x1d, 0xd6, + 0x4c, 0xe3, 0x19, 0xd5, 0x77, 0x2f, 0x26, 0x89, 0x76, 0x8b, 0x73, 0xfe, 0x60, 0xe1, 0xb6, 0x79, + 0x2b, 0x0a, 0xc3, 0xd9, 0x10, 0xeb, 0x9a, 0x31, 0x16, 0x38, 0x9f, 0x7e, 0x20, 0xc4, 0xde, 0xc4, + 0xc3, 0xe0, 0x6f, 0x53, 0xe2, 0x41, 0x15, 0x17, 0xa1, 0x46, 0x54, 0x35, 0xca, 0xc0, 0x9c, 0xb5, + 0x96, 0xf3, 0x2d, 0xd1, 0xdb, 0x08, 0x74, 0xf7, 0x34, 0x1c, 0x01, 0x97, 0xfb, 0xb5, 0x8e, 0x54, + 0xbf, 0x94, 0x73, 0x01, 0x6b, 0x09, 0x8d, 0xea, 0x9c, 0x98, 0x3b, 0xda, 0x14, 0xe4, 0xb4, 0xd5, + 0x81, 0x87, 0xa1, 0xff, 0x20, 0x04, 0x54, 0x46, 0x65, 0xf4, 0x26, 0xd6, 0x32, 0x9f, 0x4f, 0x12, + 0x7a, 0x99, 0x04, 0xb9, 0x95, 0xd2, 0x27, 0x9c, 0x71, 0x1e, 0x09, 0x4c, 0x30, 0x27, 0x9d, 0x7b, + 0xe3, 0xce, 0x43, 0x5b, 0x62, 0x8f, 0xa1, 0xed, 0xd7, 0x02, 0x03, 0x01, 0x00, 0x01 +}; + +#define composite65_rsa4096pkcs15_msg composite_test_msg + +static const uint8_t composite65_rsa4096pkcs15_add_random[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const uint8_t composite65_rsa4096pkcs15_sig_digest[] = { + 0x2c, 0xbe, 0xb7, 0xa5, 0x18, 0xdd, 0xca, 0x89, 0x73, 0x73, 0xd6, 0xbc, 0x58, 0xc1, 0x04, 0xce, + 0xf7, 0x9e, 0xa6, 0x6b, 0x6e, 0xf6, 0xd0, 0xc2, 0x02, 0xfa, 0x0e, 0x32, 0x1b, 0xae, 0xb2, 0x60 +}; + +static const uint8_t composite65_rsa4096pkcs15_sig[] = { + 0x81, 0x05, 0xc8, 0xf6, 0xfb, 0xd5, 0x4e, 0xf8, 0x0d, 0xa1, 0x92, 0x0a, 0x4c, 0x9e, 0x5e, 0x86, + 0x89, 0x32, 0x5c, 0x34, 0x1f, 0x04, 0xd0, 0x8a, 0x69, 0xb6, 0x63, 0xe3, 0x78, 0x29, 0x34, 0x54, + 0x89, 0xa3, 0x2e, 0x80, 0xd3, 0xb3, 0xcf, 0x5e, 0x74, 0x2d, 0x3f, 0x90, 0x04, 0xb4, 0x97, 0x33, + 0xc7, 0xd7, 0x0a, 0xf9, 0x85, 0xf0, 0x9e, 0xd9, 0xa4, 0xc4, 0x01, 0xd8, 0xaf, 0x29, 0xf7, 0xfe, + 0x47, 0x28, 0xce, 0xaf, 0x16, 0x35, 0xf7, 0xdc, 0x06, 0x2c, 0x6d, 0xfa, 0x90, 0x8d, 0x17, 0x5f, + 0xfd, 0xf9, 0x3d, 0x3f, 0x7f, 0x48, 0x09, 0xed, 0xda, 0x85, 0x45, 0xb8, 0xf0, 0xe9, 0x58, 0x1f, + 0x48, 0x36, 0x81, 0x15, 0xdb, 0xf7, 0x2d, 0x5e, 0x42, 0x4a, 0x45, 0x60, 0x47, 0x63, 0x82, 0xf7, + 0x29, 0xed, 0x67, 0xa9, 0x14, 0x5e, 0xa8, 0x02, 0x77, 0x64, 0x66, 0xd1, 0x08, 0x44, 0x9d, 0xc9, + 0x94, 0x40, 0x78, 0xd0, 0xc5, 0x72, 0x05, 0x96, 0xe9, 0x71, 0xcc, 0x0c, 0xac, 0xd3, 0xdf, 0x5b, + 0x79, 0xba, 0x0c, 0x53, 0x26, 0x33, 0xb2, 0x24, 0x2c, 0x9e, 0x5a, 0xd4, 0x98, 0xd6, 0x22, 0xdf, + 0x63, 0xa6, 0x1c, 0xc4, 0x8b, 0xea, 0x14, 0xda, 0x4e, 0x83, 0x3f, 0x73, 0x8f, 0xe7, 0x22, 0xbc, + 0xbd, 0xe4, 0xcd, 0xe6, 0x26, 0x05, 0xee, 0x8a, 0x4f, 0xaf, 0x03, 0x14, 0xa0, 0xde, 0xbb, 0xc5, + 0x9b, 0x33, 0x84, 0x61, 0x9e, 0x29, 0x80, 0x32, 0xf2, 0x5f, 0x77, 0xe1, 0x62, 0x11, 0xc2, 0x4e, + 0xaa, 0x78, 0x25, 0xdc, 0x05, 0x73, 0xa7, 0x14, 0x79, 0x89, 0x40, 0x69, 0x2f, 0x47, 0x62, 0xba, + 0x33, 0xc3, 0x27, 0xc2, 0x71, 0xff, 0x44, 0xe8, 0xe6, 0x2b, 0x48, 0x1d, 0xdd, 0x39, 0xbc, 0xf0, + 0xa5, 0x76, 0x1d, 0x25, 0xa6, 0xee, 0xbd, 0x69, 0x4a, 0x6d, 0x79, 0x6e, 0x95, 0xd8, 0xeb, 0x57, + 0x9f, 0x50, 0x64, 0xfb, 0x21, 0x85, 0x98, 0xa9, 0x6a, 0x33, 0x7e, 0x33, 0xcc, 0x0b, 0x22, 0x4b, + 0xc2, 0xcd, 0xb1, 0x23, 0x5e, 0x0f, 0xeb, 0x40, 0xe9, 0x60, 0x8d, 0x2c, 0x95, 0xcf, 0x8c, 0xe3, + 0x42, 0x48, 0xc5, 0xbc, 0x31, 0xcc, 0x2b, 0x40, 0x0a, 0x01, 0xa0, 0x33, 0x86, 0x49, 0x46, 0x5e, + 0xe8, 0x09, 0x2a, 0x98, 0x36, 0x14, 0xb3, 0x4d, 0x6a, 0xab, 0xd4, 0x3d, 0x00, 0xc0, 0xf6, 0xa5, + 0x8f, 0x49, 0x88, 0x4e, 0xe9, 0x09, 0x5e, 0x4d, 0x51, 0x4e, 0xe4, 0xf1, 0xc7, 0xd5, 0xae, 0x93, + 0x07, 0x1f, 0x3f, 0xb5, 0xfa, 0x07, 0xc2, 0x40, 0x9e, 0xf6, 0x1f, 0x6f, 0x01, 0xc7, 0xbd, 0xbd, + 0x21, 0x0c, 0x3b, 0xad, 0x76, 0x61, 0xf3, 0xea, 0x3c, 0xed, 0x51, 0x11, 0x04, 0x2d, 0x6c, 0x7c, + 0xb6, 0x8b, 0xac, 0x4c, 0xd3, 0xa2, 0x4e, 0xd5, 0x14, 0x96, 0xe9, 0xfa, 0x00, 0xaa, 0x6a, 0xe5, + 0x9c, 0x23, 0x6a, 0x81, 0x96, 0x44, 0x99, 0xcf, 0xf9, 0xd7, 0x98, 0xcd, 0x3a, 0xb7, 0xed, 0xff, + 0xde, 0x8c, 0x46, 0xc3, 0x57, 0xf8, 0xf0, 0x34, 0xa1, 0x8e, 0x00, 0x9f, 0x17, 0x28, 0xb4, 0x6e, + 0x9d, 0x0f, 0xaa, 0x13, 0x64, 0xcf, 0x36, 0xe8, 0x31, 0x59, 0xa7, 0x34, 0xc1, 0x8a, 0x55, 0x82, + 0x31, 0x8e, 0xd2, 0x10, 0xdf, 0x15, 0xf8, 0xba, 0x4a, 0x5f, 0x3c, 0x95, 0xd5, 0x0c, 0x2e, 0xea, + 0xdc, 0xe0, 0x50, 0xab, 0x5a, 0xb6, 0x1c, 0xf1, 0xc7, 0xcc, 0xeb, 0x98, 0xbe, 0xc1, 0x44, 0x0b, + 0x6f, 0x05, 0x58, 0xc0, 0x47, 0x37, 0x1b, 0xb5, 0x4b, 0xa9, 0x62, 0xa1, 0xf3, 0x06, 0x68, 0x96, + 0x1e, 0xc1, 0x6b, 0x95, 0x05, 0xe1, 0x04, 0xae, 0xe2, 0xb3, 0xe6, 0x62, 0x2d, 0x82, 0x94, 0x2f, + 0x83, 0xa6, 0x62, 0xa6, 0x0f, 0x89, 0x40, 0x1b, 0xa1, 0xca, 0xd8, 0xb3, 0xe6, 0x72, 0xf7, 0x2c, + 0xb9, 0x9e, 0x00, 0x08, 0x75, 0x6a, 0x76, 0x4e, 0xa8, 0xcb, 0x47, 0x7d, 0x68, 0x74, 0x3b, 0x55, + 0x73, 0x19, 0xb7, 0xc5, 0x8b, 0xe8, 0x8a, 0x65, 0x4f, 0x5a, 0x21, 0xaf, 0x69, 0x28, 0x6d, 0x2d, + 0x61, 0x09, 0xad, 0x6c, 0x4c, 0x6e, 0x2b, 0xf0, 0x3c, 0x53, 0xa6, 0x9c, 0x32, 0xa8, 0x82, 0xb0, + 0x3e, 0x5c, 0x09, 0x99, 0xed, 0x76, 0xa1, 0x9b, 0xa2, 0xaf, 0xb7, 0x07, 0x0a, 0x46, 0xac, 0xfc, + 0x89, 0x75, 0xc5, 0x84, 0x8b, 0xa4, 0xe1, 0xc3, 0x07, 0xde, 0x7a, 0xd1, 0xd4, 0x27, 0xaf, 0xbe, + 0x38, 0x4c, 0xbc, 0x00, 0x9e, 0x86, 0x02, 0xd4, 0xb7, 0xfd, 0x18, 0xb4, 0x9e, 0xab, 0xc3, 0x91, + 0xc8, 0x9b, 0x0a, 0xb5, 0x14, 0xea, 0x50, 0x6e, 0x09, 0x8b, 0x48, 0xa0, 0x68, 0x8f, 0xd3, 0xf2, + 0x8d, 0x0a, 0x9f, 0xa8, 0x7c, 0x25, 0x94, 0x7e, 0x10, 0x44, 0xfd, 0x05, 0x0a, 0x24, 0xf4, 0xee, + 0x79, 0x45, 0x78, 0xf8, 0xe4, 0xbc, 0x4c, 0x9a, 0xe4, 0xe8, 0xc6, 0xaa, 0x15, 0x2e, 0xc0, 0xda, + 0x0d, 0x4f, 0xab, 0xbd, 0x00, 0xec, 0xa0, 0x45, 0x74, 0xab, 0x5c, 0xb9, 0x60, 0x39, 0xc0, 0x94, + 0xa2, 0xb5, 0x7f, 0x21, 0x01, 0x49, 0xe3, 0x7f, 0x59, 0xc3, 0xef, 0x04, 0xdc, 0x6d, 0x2b, 0xfd, + 0xb2, 0x88, 0xda, 0x6b, 0x9c, 0xa9, 0x14, 0xb7, 0xb5, 0x4d, 0x45, 0x6a, 0x78, 0xca, 0x31, 0xaf, + 0x6f, 0x7d, 0x00, 0x86, 0xaf, 0xaa, 0xa8, 0xa4, 0xe0, 0x86, 0x9f, 0xcc, 0xaf, 0x15, 0xeb, 0x17, + 0xcd, 0x56, 0xd3, 0x13, 0xa9, 0x6a, 0x1c, 0x8c, 0x2e, 0xea, 0xde, 0x47, 0x37, 0xa0, 0x8b, 0x13, + 0xe3, 0x76, 0x52, 0x40, 0x16, 0x09, 0xc5, 0xea, 0x25, 0xba, 0xe7, 0xec, 0xca, 0xb1, 0x20, 0x8d, + 0x12, 0x95, 0x53, 0x11, 0xe8, 0xfb, 0x47, 0xf1, 0x48, 0xb6, 0x82, 0x08, 0xf0, 0x37, 0xc9, 0xb3, + 0x0d, 0x67, 0xf5, 0x06, 0x86, 0xf4, 0x8d, 0x8e, 0xe0, 0xc7, 0xe4, 0x20, 0x65, 0xc6, 0x33, 0xc4, + 0xab, 0x7f, 0x0f, 0x34, 0x88, 0xa6, 0xd5, 0x6b, 0xb7, 0xf4, 0x6f, 0x1a, 0x82, 0x32, 0xf3, 0xb6, + 0x23, 0x75, 0x6f, 0xdf, 0x01, 0x88, 0x5b, 0xae, 0x96, 0x81, 0x57, 0x9e, 0xb0, 0xf3, 0x7a, 0x9b, + 0x9c, 0x37, 0xff, 0x0c, 0x42, 0x9d, 0x50, 0xe2, 0x9d, 0x00, 0x39, 0x9d, 0x4d, 0x7a, 0xf5, 0x26, + 0x13, 0xc3, 0xa9, 0xb0, 0xce, 0xe9, 0x2f, 0x9d, 0x9a, 0xff, 0x4e, 0x06, 0x63, 0x53, 0x0a, 0x9a, + 0x28, 0x2d, 0xa4, 0x47, 0x67, 0x0e, 0xe6, 0xff, 0x11, 0x56, 0xbe, 0xad, 0xb5, 0x09, 0xfd, 0xff, + 0x13, 0xf8, 0xe2, 0xdc, 0x0f, 0xf8, 0x69, 0x9a, 0x55, 0x15, 0xeb, 0x97, 0xfe, 0xef, 0x6a, 0x1e, + 0x63, 0xbc, 0x8c, 0xaa, 0x8f, 0xdd, 0x0e, 0x03, 0x85, 0x61, 0xe4, 0xf0, 0x58, 0x93, 0x3c, 0x18, + 0x13, 0x4c, 0x50, 0x1a, 0x99, 0xd3, 0x59, 0xf6, 0x73, 0x8a, 0x45, 0xce, 0x72, 0x44, 0xde, 0x79, + 0xab, 0x10, 0x66, 0x30, 0x04, 0x9d, 0x4e, 0x09, 0x7a, 0x4a, 0xf5, 0x6f, 0x4f, 0x94, 0x54, 0x09, + 0xe9, 0x43, 0x66, 0x1c, 0x96, 0x08, 0x0e, 0xa5, 0x20, 0x48, 0x48, 0x6e, 0x0f, 0x07, 0x16, 0x60, + 0x61, 0x9d, 0x1c, 0xc8, 0xc8, 0xae, 0x04, 0xc6, 0xa1, 0x43, 0xf6, 0x8e, 0x1c, 0xb3, 0x7a, 0xc8, + 0x2d, 0xf5, 0xa7, 0xf0, 0x96, 0x9d, 0x49, 0x6e, 0xbd, 0xdd, 0x78, 0x26, 0x31, 0x24, 0xb2, 0x23, + 0xb1, 0xe1, 0x4d, 0xeb, 0x92, 0xc9, 0x80, 0x0b, 0x8f, 0x0e, 0x40, 0xf8, 0xc8, 0xfe, 0x1b, 0x80, + 0x75, 0x23, 0x18, 0xe8, 0xa6, 0xd2, 0x4f, 0x19, 0xfd, 0x46, 0xeb, 0xd6, 0xde, 0x1b, 0x51, 0xc0, + 0x94, 0x2b, 0x04, 0x32, 0x98, 0xed, 0x17, 0x23, 0x9c, 0x8f, 0x1a, 0xca, 0xd4, 0x70, 0xf4, 0x89, + 0x35, 0x33, 0x83, 0xd7, 0x74, 0x67, 0x55, 0x60, 0x45, 0xdb, 0xaa, 0x40, 0x4e, 0x2e, 0x5e, 0x71, + 0x67, 0x9a, 0x50, 0x8f, 0x98, 0xce, 0x46, 0x2b, 0x86, 0x16, 0xd7, 0xa1, 0x1f, 0x6d, 0xec, 0x46, + 0xa8, 0x3b, 0xe4, 0x5a, 0xfb, 0x56, 0x08, 0x59, 0xa6, 0x97, 0xaa, 0x7d, 0x3a, 0xdd, 0xd3, 0xcd, + 0xbf, 0x8a, 0x5f, 0x13, 0x4d, 0x6d, 0x76, 0x07, 0x58, 0xc6, 0x97, 0x40, 0xd3, 0xb7, 0x63, 0xc1, + 0x8b, 0xb4, 0x24, 0xa0, 0x7b, 0xa3, 0xae, 0x84, 0xf7, 0x19, 0x35, 0xd8, 0x31, 0xcb, 0x76, 0x9f, + 0x4e, 0xe5, 0xd9, 0x3c, 0xdf, 0x43, 0x7c, 0xe0, 0x99, 0x1d, 0xd2, 0x21, 0x73, 0xe2, 0x44, 0x74, + 0xd3, 0x5b, 0x3d, 0x61, 0xa2, 0x7e, 0x6a, 0x1f, 0x8b, 0x80, 0xe5, 0xb8, 0xcf, 0x53, 0xe9, 0x2b, + 0x69, 0x93, 0xec, 0xe4, 0x54, 0x4b, 0xbe, 0x07, 0xc7, 0x2a, 0x71, 0x63, 0xb7, 0xfd, 0xb9, 0x53, + 0xf2, 0x1d, 0x1a, 0x61, 0xbf, 0xe0, 0x79, 0xae, 0x56, 0x56, 0xdc, 0xa7, 0xe0, 0x6d, 0xee, 0x1c, + 0x33, 0x46, 0x71, 0xd4, 0x1d, 0x82, 0x12, 0x29, 0x05, 0x69, 0x25, 0xd7, 0xf9, 0xad, 0x72, 0x7e, + 0xdd, 0x60, 0x88, 0x1b, 0xa3, 0x9e, 0x79, 0xa9, 0x69, 0x4d, 0x97, 0xfd, 0x08, 0x73, 0x01, 0x34, + 0x65, 0xbe, 0x2c, 0x44, 0x02, 0xa2, 0x36, 0x3d, 0x6d, 0x9a, 0xab, 0xa8, 0x29, 0xfc, 0x8b, 0x84, + 0x4c, 0xfc, 0x89, 0x17, 0xbe, 0xa6, 0x61, 0x3f, 0x72, 0x5d, 0xdb, 0x29, 0xff, 0x5b, 0x85, 0x38, + 0x3a, 0x71, 0x77, 0xb9, 0x51, 0x33, 0x37, 0x73, 0x53, 0xc5, 0x6b, 0x8a, 0xf9, 0x84, 0x14, 0x4b, + 0xb3, 0xe5, 0xa6, 0x88, 0x8b, 0x43, 0x36, 0x65, 0x82, 0x61, 0x07, 0x7b, 0x5a, 0x05, 0xe2, 0xbd, + 0x94, 0x22, 0x82, 0x3b, 0x7f, 0xa7, 0x6a, 0xb9, 0x9f, 0x3e, 0x41, 0x2e, 0xf0, 0xb5, 0x39, 0x3a, + 0xe0, 0x8a, 0xb6, 0x35, 0x29, 0x67, 0x01, 0x12, 0x8b, 0xfc, 0xa9, 0x21, 0x58, 0x61, 0x5b, 0x54, + 0xd9, 0x8e, 0x10, 0xf2, 0x80, 0x47, 0x82, 0x3f, 0xa2, 0x1e, 0xab, 0x40, 0xbb, 0x7b, 0xe5, 0xe8, + 0x7a, 0x61, 0x39, 0x84, 0x4e, 0xd7, 0x5b, 0xfb, 0x30, 0xa4, 0x6f, 0x60, 0xe4, 0xbd, 0x16, 0xa8, + 0xec, 0x82, 0x7f, 0x20, 0xfc, 0x73, 0x24, 0x71, 0x83, 0x55, 0x41, 0xc3, 0xcb, 0xd7, 0x11, 0x3a, + 0x15, 0x06, 0xfb, 0x6b, 0xcb, 0x3d, 0x55, 0x3e, 0xaf, 0x7a, 0x58, 0x2a, 0xd1, 0x65, 0xa4, 0xee, + 0xe7, 0x84, 0x8d, 0xd1, 0x2f, 0x4a, 0xd2, 0xcf, 0x57, 0xb9, 0xfc, 0x6a, 0x32, 0x9a, 0x3d, 0x3a, + 0x55, 0x6f, 0x10, 0x8e, 0xac, 0x9d, 0x7f, 0x2c, 0x71, 0x93, 0x19, 0x12, 0xd0, 0xd5, 0x17, 0x07, + 0x4f, 0xc5, 0xb5, 0x5a, 0xd0, 0x04, 0xd7, 0x2e, 0x39, 0xa3, 0xd7, 0x30, 0xf1, 0x61, 0xa6, 0x64, + 0x99, 0x22, 0x6f, 0x9f, 0x62, 0xbf, 0xf1, 0x8f, 0x95, 0x46, 0xfd, 0x23, 0xe7, 0x2f, 0xd3, 0x44, + 0x07, 0xbb, 0xe8, 0x23, 0x59, 0x73, 0x37, 0x8f, 0x06, 0xb9, 0x44, 0x84, 0x77, 0xba, 0x57, 0x93, + 0xaf, 0x32, 0x1b, 0xa7, 0x40, 0x83, 0xee, 0x87, 0x1a, 0xcf, 0xa8, 0x47, 0xbd, 0xbf, 0x4f, 0xa7, + 0x67, 0x95, 0xf2, 0xfc, 0x28, 0xae, 0xcb, 0xb3, 0x29, 0x40, 0x67, 0xb6, 0x7c, 0x46, 0xdb, 0x60, + 0x92, 0xad, 0x5a, 0x07, 0xa4, 0xb6, 0xcf, 0xd3, 0x46, 0x98, 0xf3, 0x7e, 0xbd, 0x72, 0x44, 0x1c, + 0x32, 0xf3, 0x8b, 0x4b, 0x43, 0x47, 0xdc, 0x59, 0x40, 0xd3, 0xb3, 0xdc, 0x83, 0x0b, 0xee, 0x66, + 0x4b, 0xb5, 0xa6, 0xec, 0x29, 0x05, 0x64, 0x4a, 0x05, 0x16, 0x8f, 0xc2, 0x60, 0x19, 0xc4, 0xd5, + 0x12, 0x2c, 0xde, 0x9e, 0x0a, 0x97, 0x5e, 0xc7, 0x09, 0x3a, 0xc3, 0x9f, 0x45, 0xef, 0xb3, 0x54, + 0xc5, 0xa3, 0x6f, 0x32, 0x0c, 0xa7, 0xe7, 0x51, 0xe4, 0xac, 0xb7, 0x0f, 0xfb, 0xa6, 0x82, 0x1c, + 0x22, 0x6c, 0xbc, 0xd3, 0x88, 0xcf, 0xb0, 0x07, 0x56, 0x45, 0xbb, 0xc7, 0x21, 0x87, 0x84, 0x53, + 0x79, 0x1a, 0xd8, 0x1c, 0xf5, 0xfa, 0x37, 0xc7, 0x73, 0xd0, 0x04, 0x4b, 0x02, 0x94, 0x64, 0x24, + 0x57, 0xc5, 0xb7, 0x24, 0xdf, 0x43, 0x27, 0x75, 0xb4, 0x9c, 0x52, 0x08, 0xb5, 0x8c, 0xa6, 0xe2, + 0xfd, 0x06, 0xa0, 0xa6, 0x79, 0xb4, 0x54, 0x1a, 0x5f, 0x92, 0x76, 0x7b, 0x47, 0xdd, 0xf4, 0x2a, + 0xff, 0x5a, 0x3a, 0xe5, 0x09, 0x17, 0xbb, 0x80, 0x3f, 0x4a, 0x11, 0xe4, 0x86, 0xa4, 0x05, 0x82, + 0x9c, 0xdc, 0x7f, 0x17, 0x96, 0xea, 0xbd, 0x20, 0x6a, 0x76, 0xa8, 0xb3, 0x14, 0x7d, 0xa4, 0x6c, + 0xd2, 0xdb, 0x77, 0x1b, 0x65, 0x4b, 0xbe, 0x25, 0x16, 0x38, 0xe4, 0xb6, 0xa0, 0x90, 0xa7, 0xe7, + 0x71, 0x04, 0x20, 0x9e, 0x00, 0x8b, 0x15, 0xaf, 0xc9, 0x97, 0xc8, 0x9f, 0x3b, 0x31, 0xe7, 0xb5, + 0xc4, 0xbc, 0xa3, 0x38, 0x02, 0x3e, 0xc4, 0x0a, 0x7c, 0x16, 0xea, 0x49, 0xe9, 0xf4, 0x06, 0xb2, + 0x5d, 0xc5, 0x70, 0x7d, 0xce, 0xc2, 0x3e, 0x2f, 0x7e, 0x07, 0x74, 0x50, 0x68, 0x4e, 0x6a, 0x4e, + 0xcc, 0x4a, 0xd2, 0xdd, 0x64, 0x63, 0x56, 0x3c, 0xe5, 0x65, 0x96, 0x83, 0xe0, 0x54, 0xdd, 0x9d, + 0xa8, 0xc1, 0x30, 0x7e, 0x54, 0xce, 0x9a, 0x32, 0xba, 0x63, 0xda, 0x40, 0x94, 0x7f, 0x42, 0x26, + 0xa4, 0x37, 0x9d, 0x31, 0x04, 0x16, 0x59, 0xc4, 0x4c, 0xff, 0xc6, 0x9a, 0x2b, 0x42, 0xf5, 0x75, + 0x2d, 0x6b, 0xed, 0xd7, 0xfd, 0xfc, 0x0e, 0xe0, 0x2a, 0x5c, 0x7e, 0x59, 0x04, 0x8d, 0xdb, 0x97, + 0x2c, 0xa6, 0x6d, 0xa9, 0x04, 0xac, 0xa4, 0x61, 0x40, 0x2d, 0xb5, 0xf4, 0x80, 0x0d, 0x5a, 0xb8, + 0x9d, 0xb1, 0x3c, 0xad, 0x64, 0x07, 0x7e, 0xfa, 0x5b, 0xc1, 0xd6, 0x8f, 0x3d, 0x85, 0xb8, 0xb0, + 0xde, 0x35, 0x09, 0xf5, 0x3f, 0x09, 0x5c, 0x95, 0xea, 0xbe, 0xd6, 0x89, 0xfc, 0x25, 0xed, 0x19, + 0x5c, 0xf1, 0x4d, 0x61, 0x7f, 0x89, 0x7f, 0xf2, 0xcf, 0xe9, 0xb9, 0x0f, 0xb3, 0x46, 0x74, 0x77, + 0x5c, 0xad, 0xd3, 0x42, 0x03, 0xf7, 0xc6, 0xc0, 0x3c, 0xad, 0x94, 0x91, 0x8e, 0x67, 0x9f, 0x4f, + 0xca, 0x11, 0xdc, 0xa0, 0x41, 0xe4, 0xfe, 0x29, 0x99, 0x91, 0xcb, 0x75, 0xd0, 0xd7, 0xb8, 0xae, + 0xba, 0xee, 0x9f, 0xbe, 0x56, 0x87, 0x4b, 0x7d, 0x82, 0xf6, 0xf6, 0x4a, 0x93, 0x7f, 0x2d, 0x48, + 0xee, 0x19, 0x92, 0x6e, 0xfa, 0xcd, 0x5a, 0xf1, 0xaa, 0x67, 0xa2, 0x37, 0xf6, 0x15, 0xcc, 0x1d, + 0xa9, 0xeb, 0x72, 0xae, 0x5f, 0x00, 0x8e, 0x34, 0x92, 0x7e, 0x00, 0x4a, 0x50, 0xd5, 0x08, 0x4b, + 0x73, 0xc1, 0x6b, 0x7a, 0x65, 0x75, 0xba, 0x7f, 0xb5, 0xe7, 0xd0, 0xc1, 0x4a, 0x90, 0xae, 0xe0, + 0x3b, 0x3d, 0xe0, 0xaf, 0x5f, 0x99, 0xc4, 0x5e, 0xd3, 0x9f, 0x4e, 0x63, 0x78, 0xb5, 0x93, 0xf0, + 0x4b, 0x0f, 0xe3, 0x42, 0xee, 0x50, 0x9b, 0x0d, 0x10, 0xfd, 0x6f, 0xfb, 0x67, 0x88, 0xcb, 0x0c, + 0x32, 0x00, 0xa9, 0x2a, 0x4c, 0x4d, 0x36, 0x27, 0x19, 0x17, 0x36, 0xa6, 0xaf, 0xe4, 0xde, 0xc5, + 0xe1, 0x71, 0x5f, 0x6b, 0xf0, 0x67, 0x03, 0x9d, 0x45, 0x0e, 0x1a, 0xfe, 0x91, 0x2e, 0x6d, 0xb6, + 0x25, 0x33, 0xcd, 0x9b, 0x2f, 0xb7, 0xcd, 0xfb, 0xb2, 0xce, 0x78, 0x11, 0xb5, 0xf7, 0x6b, 0xc1, + 0xa2, 0xca, 0x5c, 0x5d, 0x3a, 0xbd, 0x36, 0xc3, 0xbe, 0x62, 0x46, 0x34, 0xc1, 0x25, 0x54, 0x84, + 0x9a, 0xfa, 0xe7, 0xff, 0x9b, 0xc4, 0x93, 0x41, 0xe9, 0xe8, 0xc7, 0x18, 0x65, 0x4e, 0xd6, 0x4b, + 0xd2, 0x50, 0x84, 0x80, 0xce, 0x47, 0x42, 0xfd, 0xb8, 0x80, 0x44, 0x82, 0x96, 0x41, 0x85, 0xcb, + 0x16, 0x85, 0xa0, 0x9b, 0x56, 0x3e, 0x3f, 0x10, 0xb9, 0xb5, 0xea, 0xf6, 0xc0, 0x5c, 0xb5, 0x8c, + 0xa4, 0x65, 0xe7, 0xbb, 0x53, 0xc4, 0xb7, 0x4a, 0x3b, 0xb4, 0x87, 0x5a, 0xfe, 0x0f, 0xf8, 0xeb, + 0xe3, 0x7e, 0x20, 0x12, 0xdf, 0xba, 0x82, 0xf5, 0x4c, 0xeb, 0x5f, 0x97, 0x43, 0x44, 0x21, 0x12, + 0x62, 0xf0, 0x05, 0x2c, 0xf4, 0x9a, 0xe0, 0x95, 0xca, 0xd7, 0xea, 0x14, 0x7e, 0x0e, 0x3f, 0x8f, + 0x5c, 0x5f, 0x15, 0x5d, 0xaf, 0x36, 0x59, 0x7f, 0xa4, 0x95, 0xb9, 0x06, 0x7e, 0xd7, 0xf2, 0x0f, + 0x11, 0x0e, 0xf7, 0x84, 0xaa, 0x5f, 0x79, 0x3d, 0xe3, 0x81, 0xfa, 0x6e, 0x7c, 0xb4, 0xdc, 0xa1, + 0x8d, 0x27, 0xf4, 0x40, 0xfc, 0x43, 0xfc, 0x36, 0xc2, 0x04, 0xa2, 0xec, 0x8d, 0xa7, 0x30, 0xc1, + 0xc6, 0x6e, 0xa2, 0x96, 0x64, 0x1e, 0x73, 0x30, 0x2f, 0x7e, 0x1e, 0x31, 0xca, 0x78, 0xc1, 0xc0, + 0x54, 0xd5, 0xe7, 0xfa, 0x9f, 0xab, 0xa7, 0xa3, 0xda, 0x3d, 0x96, 0x5b, 0x44, 0xb0, 0x91, 0xdc, + 0xa5, 0xfa, 0xf5, 0x32, 0xdf, 0xc6, 0x0f, 0xf0, 0xa1, 0x41, 0x09, 0x35, 0x96, 0x94, 0x21, 0xa1, + 0x4e, 0xf9, 0x04, 0xcb, 0xef, 0x6e, 0xb6, 0x4c, 0x58, 0xcd, 0x55, 0x54, 0x8a, 0x70, 0xb3, 0x4c, + 0x0c, 0xcb, 0xf7, 0x3f, 0x0a, 0x79, 0xc6, 0xf5, 0xae, 0xdf, 0xce, 0xfa, 0xfd, 0xb6, 0x8c, 0x56, + 0xca, 0x8d, 0x1f, 0xdd, 0x2d, 0x14, 0xff, 0x1c, 0x96, 0xa1, 0x30, 0x78, 0x5b, 0xd1, 0x12, 0x50, + 0x17, 0x1b, 0x37, 0x46, 0x6f, 0xe6, 0x3c, 0x10, 0xb9, 0x32, 0xd7, 0x8e, 0xf5, 0xd5, 0x2b, 0xbd, + 0x0c, 0xec, 0x07, 0x77, 0x8e, 0xb3, 0xee, 0xcf, 0x3d, 0xc9, 0x19, 0xca, 0x70, 0x3c, 0xde, 0x88, + 0xb4, 0x13, 0x4d, 0x98, 0x73, 0x69, 0x4f, 0x36, 0x15, 0x5a, 0x7c, 0x61, 0xdd, 0x21, 0x22, 0x35, + 0x82, 0x22, 0x83, 0x23, 0x75, 0xe2, 0x8d, 0xc3, 0xd4, 0xaa, 0x3d, 0x66, 0x16, 0x72, 0x32, 0x5d, + 0xbc, 0xf1, 0x4e, 0xf9, 0x41, 0x64, 0xbe, 0xf6, 0x3f, 0x92, 0x53, 0x47, 0xc1, 0xb0, 0xde, 0x98, + 0xc7, 0x1b, 0xc7, 0x15, 0x21, 0x75, 0xb1, 0xcd, 0x44, 0x93, 0xda, 0x0f, 0xe0, 0x85, 0x9a, 0x58, + 0xa8, 0x4c, 0x78, 0x00, 0xbc, 0xa1, 0xc6, 0x39, 0x63, 0x74, 0x44, 0x87, 0x48, 0x63, 0x69, 0xae, + 0x31, 0x46, 0x8d, 0x49, 0x60, 0xfe, 0x93, 0x66, 0x26, 0xf4, 0xff, 0x58, 0xff, 0x98, 0x23, 0x79, + 0x3a, 0xb1, 0xf1, 0x2a, 0x50, 0xf6, 0xe4, 0x98, 0x68, 0xb9, 0x4b, 0x33, 0x70, 0x61, 0x55, 0x94, + 0xa9, 0xe8, 0x0d, 0xf2, 0xc6, 0x78, 0xab, 0x8b, 0xe8, 0x64, 0xe7, 0xab, 0x41, 0xbc, 0xab, 0x2b, + 0x08, 0x5e, 0x64, 0x04, 0x22, 0x66, 0x41, 0x22, 0xf7, 0x2f, 0xa4, 0xd0, 0x20, 0x51, 0xaf, 0x7e, + 0xf2, 0x0a, 0x08, 0x3c, 0xda, 0xc3, 0xdd, 0x61, 0xbf, 0xe4, 0x0b, 0xb9, 0x57, 0x4d, 0xf8, 0x31, + 0xa9, 0x65, 0xa3, 0xba, 0xf4, 0x7b, 0x39, 0x13, 0x5c, 0x9e, 0xc8, 0x69, 0x40, 0x8d, 0xfb, 0xfe, + 0xd8, 0xe5, 0x8b, 0x29, 0x53, 0x1e, 0xa2, 0x1e, 0x6c, 0xa0, 0xaa, 0x2b, 0xd1, 0x76, 0x59, 0x38, + 0x86, 0x3c, 0xce, 0x74, 0xb1, 0xb2, 0xdd, 0x6c, 0x4c, 0x39, 0x02, 0x44, 0xaa, 0xc8, 0x23, 0x02, + 0x08, 0xc4, 0xde, 0x82, 0x19, 0xe8, 0x11, 0x60, 0xcf, 0x7c, 0x5f, 0x35, 0x13, 0x61, 0x40, 0xcc, + 0x4e, 0x66, 0x3d, 0x96, 0x15, 0xd1, 0xe0, 0x64, 0x41, 0x8c, 0x6a, 0x33, 0x34, 0xd8, 0x10, 0xf7, + 0x22, 0x9f, 0x2c, 0xf2, 0x21, 0x1f, 0x8f, 0x8c, 0x34, 0xb4, 0xb0, 0x40, 0x70, 0x70, 0xc4, 0xf1, + 0x53, 0xb9, 0xcb, 0x60, 0x5b, 0xd6, 0x42, 0xf4, 0x92, 0x42, 0xe7, 0x24, 0xfa, 0xe4, 0xe9, 0x2a, + 0x42, 0x4b, 0xb6, 0x8c, 0x9b, 0xb8, 0xf4, 0x8a, 0x8d, 0x1d, 0xf5, 0x93, 0xc5, 0x3c, 0xb1, 0x27, + 0xcd, 0x40, 0xe6, 0xdd, 0x2f, 0x75, 0xf0, 0x08, 0xa0, 0x66, 0x1a, 0xf2, 0x7c, 0xa4, 0x75, 0xe5, + 0x45, 0xa0, 0x25, 0xde, 0xc3, 0xbe, 0xe0, 0x64, 0x74, 0x92, 0x5d, 0xc2, 0xc6, 0x4b, 0xb6, 0xa1, + 0x39, 0x2f, 0x3b, 0xbe, 0xb7, 0x9d, 0x59, 0x6b, 0x4e, 0x99, 0x6c, 0xa3, 0xb7, 0xf8, 0x32, 0xba, + 0xae, 0x30, 0x7a, 0x83, 0xe2, 0xe6, 0xc0, 0x04, 0x1e, 0xf9, 0x4b, 0x4e, 0xe6, 0xed, 0x2d, 0xf2, + 0xa9, 0xb4, 0xf2, 0x0c, 0x9c, 0xaf, 0x8d, 0x40, 0xd3, 0xee, 0xd4, 0xd8, 0x4a, 0x11, 0x08, 0x1a, + 0x5b, 0x59, 0x67, 0x53, 0xb4, 0x4e, 0x6f, 0xaf, 0x9c, 0x96, 0x0e, 0xd2, 0x3c, 0x0b, 0xb4, 0xec, + 0xec, 0x28, 0xd5, 0xda, 0xeb, 0x43, 0x94, 0xaf, 0x0e, 0x78, 0xa5, 0x9a, 0x85, 0x68, 0x9c, 0x3c, + 0x19, 0x8d, 0x9b, 0x5c, 0xa2, 0xef, 0x42, 0x36, 0x87, 0xe9, 0xcc, 0x7d, 0x2b, 0x00, 0xd4, 0x81, + 0x31, 0xa8, 0x45, 0x22, 0x57, 0xf1, 0xe4, 0x82, 0x29, 0xc1, 0x9f, 0x4f, 0x00, 0xd8, 0x53, 0x49, + 0x8d, 0x6b, 0xc7, 0xf7, 0xa1, 0x92, 0xd2, 0x5c, 0xc5, 0xb3, 0xcf, 0x77, 0xcf, 0x83, 0x37, 0xe2, + 0x17, 0x7a, 0xb9, 0x1a, 0xab, 0xce, 0x95, 0x69, 0x0a, 0xfd, 0x95, 0x40, 0xc7, 0x1e, 0xee, 0x2b, + 0x4c, 0xc1, 0x1f, 0xf8, 0x55, 0xf3, 0x21, 0x60, 0xfd, 0x11, 0x7f, 0x50, 0x81, 0x7e, 0x33, 0x14, + 0x5a, 0xdd, 0xf8, 0x0e, 0x23, 0xb4, 0x54, 0xc4, 0x80, 0x89, 0x50, 0x16, 0x20, 0xdf, 0x84, 0x88, + 0x49, 0xd6, 0x3a, 0xa5, 0x08, 0x67, 0x73, 0x52, 0xc7, 0x5e, 0xbb, 0xb4, 0x6d, 0xc9, 0xc4, 0x51, + 0xbe, 0xc3, 0x7b, 0x6c, 0xfe, 0x38, 0x76, 0xdb, 0x1e, 0xa3, 0x06, 0xb8, 0xb3, 0x11, 0xdd, 0x9b, + 0xfd, 0xec, 0x20, 0x3d, 0x81, 0x0c, 0x2c, 0xce, 0xa8, 0x27, 0x8a, 0x0e, 0x57, 0x5d, 0x4f, 0x3e, + 0x7a, 0x9e, 0x0e, 0x87, 0x1d, 0x84, 0x71, 0xe4, 0x49, 0xd4, 0xe7, 0x45, 0x07, 0x2b, 0x19, 0xca, + 0x1b, 0x44, 0x65, 0xe3, 0x71, 0x2d, 0x06, 0xe2, 0x65, 0x68, 0x42, 0xeb, 0x09, 0xbd, 0x88, 0x18, + 0x5a, 0xe3, 0x04, 0x14, 0xdb, 0x6b, 0xd3, 0x3d, 0x22, 0x52, 0xa0, 0xa6, 0x6f, 0xfb, 0x1e, 0xf9, + 0xfe, 0xbd, 0x2e, 0xba, 0x3a, 0xd2, 0x43, 0xd4, 0x34, 0xc1, 0xc5, 0x32, 0x19, 0xf3, 0x52, 0x3f, + 0x32, 0x0a, 0x66, 0x26, 0xc1, 0xbb, 0x7f, 0xf0, 0x47, 0x9c, 0xfb, 0x03, 0x31, 0x2d, 0x87, 0xcb, + 0xa2, 0xf2, 0x2d, 0x3a, 0x26, 0xeb, 0x0f, 0x5b, 0x4a, 0xc4, 0xcb, 0x1b, 0x3f, 0xf1, 0x55, 0x63, + 0x02, 0x33, 0xe6, 0xd4, 0xc8, 0xf1, 0xa9, 0x91, 0xe2, 0x77, 0xe2, 0x8c, 0x00, 0xf1, 0xe0, 0x4d, + 0x0e, 0xb3, 0x59, 0x9c, 0x70, 0x4f, 0x2c, 0x92, 0x06, 0x46, 0xde, 0x9a, 0x69, 0x10, 0x0a, 0x9e, + 0xdc, 0x4a, 0x42, 0x3a, 0x2c, 0xd4, 0xde, 0x3b, 0x18, 0x26, 0x1e, 0x8c, 0x09, 0xeb, 0x57, 0x92, + 0x89, 0x1c, 0xd8, 0x21, 0xb5, 0xea, 0x3f, 0x7b, 0x50, 0xb7, 0xec, 0xfc, 0x1a, 0xd5, 0x32, 0x3c, + 0xc2, 0x3a, 0x44, 0xcc, 0x54, 0x26, 0xf2, 0xa9, 0x53, 0x1e, 0xb5, 0x5d, 0x87, 0x25, 0x92, 0xdf, + 0xc7, 0x13, 0xfd, 0x38, 0x7b, 0x8e, 0x14, 0x20, 0x29, 0xb0, 0xfd, 0x59, 0xf0, 0xea, 0x55, 0x91, + 0x69, 0x56, 0x8b, 0x6f, 0x95, 0x5c, 0xa7, 0xc7, 0x55, 0xd1, 0x66, 0xeb, 0xba, 0x41, 0x4d, 0x7a, + 0xba, 0x05, 0xbb, 0xfc, 0x4a, 0x98, 0xda, 0x50, 0x6f, 0xf4, 0x1e, 0x76, 0x2e, 0x9d, 0xe1, 0x46, + 0xe6, 0xbf, 0x6f, 0x4c, 0x0c, 0x47, 0xdc, 0xa1, 0x23, 0x2c, 0x78, 0xb2, 0x29, 0x5f, 0xae, 0x25, + 0x38, 0x68, 0x3d, 0x80, 0x87, 0x16, 0xee, 0x5c, 0x37, 0x9f, 0x2a, 0x77, 0xa9, 0x18, 0x7d, 0x7b, + 0x4c, 0xf1, 0x8f, 0x21, 0x00, 0x73, 0x1f, 0xa1, 0xbd, 0xa5, 0xef, 0xb4, 0x77, 0x4d, 0x69, 0x27, + 0x70, 0x06, 0xa5, 0xc6, 0x34, 0xb9, 0xb4, 0xfa, 0xd6, 0xf6, 0xfb, 0x71, 0xd2, 0xf5, 0x05, 0x69, + 0xbb, 0x85, 0x70, 0x55, 0xd6, 0x51, 0x1f, 0xe1, 0xd6, 0x3f, 0x7d, 0x63, 0xbf, 0x80, 0xbc, 0x1f, + 0x7e, 0xcc, 0x39, 0x96, 0xe4, 0x85, 0x02, 0xed, 0x04, 0xff, 0x71, 0x81, 0xa3, 0xbb, 0xdd, 0xce, + 0x48, 0xca, 0x42, 0xce, 0xc9, 0x1c, 0xac, 0x7d, 0x2b, 0xf4, 0x67, 0x55, 0xb5, 0x6f, 0x5e, 0xc2, + 0x2a, 0x17, 0xca, 0xa9, 0xd5, 0x5d, 0x35, 0xf6, 0x6e, 0xf9, 0x20, 0xe5, 0x78, 0xc3, 0xcb, 0x58, + 0x4b, 0x3f, 0x91, 0xc2, 0x42, 0xec, 0xbc, 0xea, 0xfc, 0xe5, 0x71, 0x99, 0x3f, 0x95, 0x52, 0x67, + 0xa0, 0xd6, 0x9d, 0xd0, 0x67, 0x77, 0xda, 0xf3, 0xe4, 0x5a, 0xf6, 0xe7, 0xd2, 0xba, 0x5c, 0xfc, + 0xc3, 0x02, 0x49, 0x52, 0x7b, 0x39, 0x4b, 0x7d, 0xb9, 0x36, 0x8e, 0xa4, 0x96, 0xbb, 0xd3, 0xfe, + 0x24, 0x2e, 0x36, 0xa5, 0xb4, 0xca, 0xdd, 0x0a, 0x48, 0x4a, 0x4c, 0x8e, 0xc4, 0xd2, 0xee, 0xf9, + 0xff, 0x67, 0x84, 0xcf, 0xee, 0x03, 0x09, 0x49, 0x51, 0x68, 0x8b, 0xd8, 0x68, 0x15, 0x3e, 0x43, + 0x65, 0x87, 0xaa, 0xe3, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x11, 0x15, 0x1c, 0x1d, 0x25, 0x70, 0x6b, 0xf2, + 0xa8, 0x93, 0x12, 0xe0, 0xf1, 0x45, 0x8e, 0x6e, 0x2a, 0x4b, 0x36, 0x65, 0x08, 0x48, 0x13, 0x12, + 0x7f, 0x5b, 0x35, 0x55, 0x77, 0xa8, 0x2b, 0x7f, 0xc9, 0x04, 0xdc, 0xf0, 0x1e, 0xcb, 0x46, 0xe9, + 0x60, 0x3f, 0x90, 0x29, 0x1b, 0x1d, 0x5b, 0x06, 0x4a, 0x88, 0xae, 0xb2, 0xd9, 0x81, 0x97, 0xca, + 0x02, 0x15, 0x25, 0x03, 0x89, 0xa6, 0x80, 0xc6, 0x9a, 0xb1, 0x38, 0x02, 0xef, 0xd5, 0xac, 0x3f, + 0xa3, 0x59, 0xb7, 0x9e, 0xe6, 0xb9, 0xcd, 0x9d, 0x9d, 0xeb, 0x39, 0x85, 0xb8, 0x6d, 0x5d, 0xa2, + 0xb7, 0xa2, 0xa0, 0x7e, 0x7c, 0x69, 0x44, 0x52, 0x22, 0x0a, 0x25, 0x8a, 0xbb, 0x45, 0x64, 0xc4, + 0x01, 0xcc, 0x3b, 0x5f, 0x22, 0x2b, 0x7f, 0xab, 0xb6, 0x24, 0x08, 0x9d, 0xc1, 0x44, 0x7b, 0xfc, + 0xcd, 0x2c, 0x71, 0x56, 0x62, 0xc6, 0xb2, 0xc3, 0x48, 0x20, 0x44, 0xf5, 0x0a, 0x9b, 0x71, 0xf0, + 0x15, 0x9b, 0x2e, 0x9d, 0x75, 0xda, 0x1a, 0xee, 0xcd, 0x44, 0x0f, 0x8c, 0x92, 0x08, 0x3b, 0x51, + 0x54, 0x76, 0x47, 0x8c, 0xdd, 0xd8, 0xe3, 0x2f, 0x87, 0x69, 0xc5, 0x07, 0x52, 0xcc, 0x3b, 0x89, + 0x6a, 0x3e, 0x03, 0x3d, 0x1a, 0x0d, 0xe0, 0xfa, 0xea, 0x9e, 0xc0, 0x71, 0xfa, 0x98, 0x74, 0xc9, + 0x18, 0x40, 0x00, 0x6e, 0x7f, 0xc2, 0x8a, 0xa2, 0xf0, 0x49, 0x48, 0xe6, 0x94, 0x12, 0x80, 0x4c, + 0x04, 0xe5, 0xfc, 0x06, 0xc6, 0xd6, 0x63, 0x93, 0x2e, 0x77, 0x37, 0x34, 0x45, 0x17, 0x7a, 0x6f, + 0x02, 0xae, 0xa9, 0xe8, 0xd1, 0xcd, 0x3c, 0x52, 0x48, 0x6c, 0xbc, 0x97, 0xcf, 0x04, 0x54, 0x0d, + 0xb0, 0xef, 0x8e, 0x9a, 0xb4, 0x6c, 0x54, 0x10, 0xc4, 0x63, 0x23, 0x85, 0x23, 0x05, 0x2c, 0xe1, + 0x0a, 0xc5, 0x6e, 0x22, 0xb4, 0x4a, 0x94, 0xfa, 0x0d, 0xc0, 0x83, 0x47, 0x3b, 0xa3, 0xff, 0x4e, + 0x78, 0x77, 0x48, 0x48, 0xfe, 0x02, 0xa2, 0xc9, 0x34, 0x04, 0xf4, 0x18, 0x80, 0x2f, 0xeb, 0x3d, + 0x01, 0x12, 0x77, 0xde, 0x1f, 0x8d, 0xd8, 0x05, 0x8c, 0xc5, 0xf4, 0xd5, 0xbc, 0x98, 0xa1, 0x2c, + 0x35, 0x4b, 0xa5, 0x7a, 0xd4, 0x40, 0x4c, 0x08, 0x61, 0x9e, 0xa7, 0xd9, 0x2c, 0x44, 0xaf, 0xc1, + 0xe8, 0xf3, 0x39, 0x95, 0x5f, 0xfe, 0xcf, 0xbc, 0xc1, 0xe5, 0xec, 0xb8, 0x2c, 0xd2, 0x8c, 0x46, + 0x76, 0xe9, 0x3f, 0x56, 0x97, 0x41, 0xd4, 0xf4, 0x82, 0x32, 0xce, 0x04, 0xac, 0x66, 0xb9, 0x37, + 0xb5, 0x57, 0x9a, 0xc2, 0x0d, 0xac, 0x2a, 0x00, 0xe2, 0xc6, 0x25, 0x5f, 0xe2, 0x1f, 0x95, 0xe0, + 0xe3, 0x74, 0xd3, 0x77, 0xdf, 0xe6, 0xe0, 0x54, 0xd2, 0x5c, 0xb8, 0xa5, 0x09, 0xbf, 0x5c, 0xa9, + 0x8c, 0xc9, 0xca, 0xa9, 0xaf, 0x38, 0xff, 0xa8, 0xcd, 0xb5, 0x19, 0xc1, 0xd4, 0x1f, 0x17, 0x34, + 0x50, 0x4f, 0x45, 0xca, 0xf8, 0x60, 0xe5, 0x9b, 0xa9, 0x68, 0xd2, 0x38, 0x00, 0xc3, 0xcb, 0x5d, + 0x17, 0xcb, 0x3d, 0x2f, 0x25, 0xe3, 0x2a, 0xdf, 0xe1, 0xf7, 0x44, 0x9c, 0x86, 0x5a, 0xd3, 0xcb, + 0xe7, 0xf8, 0x55, 0x8d, 0xc6, 0x5a, 0x4e, 0x19, 0xb8, 0x5d, 0xc5, 0x4d, 0x80, 0xc0, 0x6a, 0xbf, + 0xe0, 0x9b, 0x00, 0xb9, 0xd4, 0x39, 0x91, 0x3d, 0x75, 0x95, 0x26, 0xfd, 0x75, 0x0f, 0x7a, 0xef, + 0x10, 0xa4, 0x0e, 0x9c, 0x5e, 0x6a, 0xbf, 0x24, 0xf8, 0x09, 0x29, 0x33, 0xdc, 0xce, 0x8f, 0x4c, + 0x6c, 0x1a, 0x0b, 0xfb, 0x63, 0x9e, 0xec, 0x2f, 0x5b, 0x22, 0x81, 0xdc, 0xb4, 0x4f, 0xc9, 0xb9, + 0x9f, 0xc5, 0xf7, 0x67, 0xf6, 0x94, 0xcb, 0xc1, 0xc4, 0xc8, 0xc9, 0x26, 0xf2, 0x2c, 0x0f, 0x99, + 0xac, 0x0e, 0xac, 0x74, 0x6c, 0x51, 0x6f, 0xdf, 0xf1, 0x9c, 0xfe, 0x19, 0xad +}; + +/* --- ML-DSA-65-Ed25519-SHA512 --- */ +static const uint8_t composite65_ed25519_priv[] = { + 0x29, 0xdb, 0x4c, 0xf6, 0xa2, 0xb9, 0x64, 0xc7, 0xfc, 0x46, 0xf1, 0x29, 0x58, 0x9a, 0xf1, 0xb1, + 0x9a, 0x84, 0xca, 0xa3, 0x86, 0xc3, 0x20, 0xd2, 0x72, 0x1a, 0x56, 0xcc, 0x5a, 0x7c, 0xbb, 0xc3, + 0x17, 0xed, 0xa5, 0x5d, 0x17, 0xa0, 0x64, 0xd5, 0xb5, 0xdd, 0x9e, 0x51, 0xf5, 0x00, 0x6c, 0xab, + 0x22, 0x8e, 0xe2, 0x9f, 0xdb, 0xa6, 0x4a, 0xc2, 0x53, 0xcd, 0x77, 0xfb, 0x5a, 0xf7, 0x96, 0x3a +}; + +static const uint8_t composite65_ed25519_pub[] = { + 0xfa, 0x5f, 0x34, 0x7b, 0xc3, 0xc7, 0x81, 0x1b, 0xfe, 0x19, 0xc1, 0xbd, 0xc6, 0x4f, 0x5c, 0xe4, + 0x4b, 0xc3, 0xbb, 0xe8, 0x77, 0xb7, 0x4f, 0xad, 0x33, 0x09, 0xac, 0x2d, 0xe2, 0x55, 0xb8, 0xb0, + 0xcf, 0x24, 0x30, 0xa1, 0xe4, 0xc9, 0xcf, 0x72, 0xa6, 0xb4, 0x32, 0xc5, 0x5e, 0x81, 0x1d, 0x84, + 0xdd, 0x8d, 0xd8, 0x26, 0xbc, 0xad, 0x01, 0x22, 0xbf, 0x17, 0xb6, 0x0c, 0x58, 0x49, 0x2b, 0x53, + 0x4d, 0xfb, 0x9a, 0x42, 0x18, 0x1d, 0x70, 0x24, 0xf3, 0xca, 0xec, 0x50, 0x38, 0xee, 0x98, 0xc1, + 0xa2, 0x66, 0x53, 0xea, 0x06, 0x79, 0x56, 0xff, 0xb9, 0x2c, 0x3e, 0x3c, 0xc3, 0x5d, 0xba, 0x64, + 0x9a, 0x55, 0x85, 0x48, 0x3d, 0x09, 0x21, 0xd9, 0x1f, 0xa5, 0x82, 0xee, 0x76, 0x98, 0x9e, 0x52, + 0xfb, 0x8e, 0xb4, 0xae, 0x7d, 0x27, 0x17, 0xda, 0xf0, 0x22, 0x89, 0xa0, 0x2e, 0x61, 0x41, 0xf5, + 0x18, 0xc2, 0x23, 0x78, 0xfe, 0x6d, 0xd7, 0x65, 0x5c, 0xce, 0x92, 0xb0, 0xa2, 0xf2, 0xea, 0xd0, + 0x2a, 0x15, 0x7b, 0x4c, 0xeb, 0xd9, 0x80, 0x68, 0x75, 0x5a, 0x04, 0x89, 0x82, 0x2d, 0xd6, 0x2e, + 0xca, 0x58, 0xa9, 0x39, 0x02, 0x39, 0xa0, 0x51, 0x77, 0xe1, 0x71, 0xd1, 0x2e, 0xb2, 0x0f, 0x8e, + 0x3f, 0x31, 0x7e, 0xd5, 0x18, 0x1f, 0x0d, 0x8e, 0x8d, 0xab, 0xc1, 0x20, 0xbe, 0xc3, 0x4c, 0x1a, + 0x3b, 0x1e, 0xb3, 0x00, 0xf9, 0x90, 0x94, 0xfc, 0x90, 0xf5, 0xc7, 0x36, 0x4e, 0x8c, 0xae, 0x0c, + 0x3f, 0x0f, 0xd7, 0x9c, 0x23, 0x09, 0x68, 0x8d, 0x83, 0x18, 0x77, 0x06, 0xca, 0x65, 0x8a, 0x9c, + 0x3f, 0xad, 0xbc, 0x98, 0xc3, 0x4d, 0x30, 0x97, 0xdd, 0xc1, 0x94, 0x1a, 0xf3, 0xee, 0xd0, 0x53, + 0x47, 0x72, 0xf2, 0x7f, 0x3f, 0x0f, 0x72, 0xce, 0x25, 0x7d, 0xcf, 0x43, 0xd2, 0xf5, 0xda, 0xef, + 0x41, 0xe2, 0x44, 0x0c, 0xce, 0x88, 0xd6, 0x6a, 0x6d, 0xfd, 0x42, 0x74, 0x93, 0x69, 0x28, 0x8a, + 0x75, 0xcd, 0x7e, 0xbf, 0x7c, 0xec, 0x55, 0x7f, 0x6f, 0xf8, 0xe1, 0x01, 0x99, 0x5d, 0xa8, 0xe8, + 0xa6, 0xb6, 0xbf, 0xbb, 0xf9, 0xce, 0x58, 0x88, 0x02, 0xbc, 0x65, 0x7d, 0x17, 0x92, 0x82, 0xaf, + 0x9c, 0x64, 0xf9, 0xe9, 0x1a, 0x52, 0x9a, 0x6a, 0x2b, 0xb7, 0xf2, 0xde, 0xe9, 0xac, 0x95, 0x13, + 0x02, 0x2e, 0x6d, 0x1b, 0xeb, 0x2b, 0x81, 0xcb, 0x2c, 0x5d, 0x3e, 0xab, 0x19, 0x21, 0xe2, 0x5d, + 0x1d, 0x24, 0x4e, 0x84, 0x25, 0x25, 0x87, 0x31, 0x56, 0x24, 0x11, 0x1b, 0xb4, 0x7b, 0x46, 0x9b, + 0xf5, 0x52, 0xe8, 0x75, 0xf4, 0x6f, 0x2c, 0x44, 0x4d, 0x57, 0xf2, 0x76, 0x79, 0x52, 0x3a, 0xe4, + 0x53, 0xd4, 0xe2, 0x57, 0x3e, 0x5b, 0x2d, 0xdf, 0x20, 0x41, 0xdc, 0xe3, 0x72, 0x54, 0x6d, 0x30, + 0xed, 0x77, 0x61, 0x72, 0x09, 0xb7, 0x51, 0x36, 0xee, 0x73, 0xb3, 0xce, 0x4a, 0xde, 0x42, 0x15, + 0xc3, 0x69, 0x6e, 0x00, 0x35, 0x55, 0xee, 0xaa, 0xd3, 0xe0, 0x0a, 0x59, 0x6a, 0x42, 0xbd, 0x74, + 0xf9, 0x82, 0xa8, 0x7f, 0xd1, 0xe7, 0x48, 0x58, 0x4a, 0x7a, 0xf8, 0xb0, 0x97, 0xbc, 0xbe, 0xbf, + 0xb5, 0x47, 0x18, 0x6a, 0x6e, 0x5a, 0x93, 0xc4, 0x7a, 0xfb, 0x87, 0x96, 0x5d, 0x12, 0xf6, 0x64, + 0xcc, 0xd0, 0x8e, 0xb7, 0x93, 0x6d, 0x60, 0x6e, 0x0c, 0x91, 0xd1, 0x3d, 0xbc, 0x71, 0x17, 0x04, + 0xe5, 0x99, 0xe0, 0xb6, 0x44, 0xd7, 0x6b, 0x83, 0xd3, 0xae, 0xe3, 0x2c, 0x32, 0xd8, 0xa1, 0xda, + 0x0a, 0x0b, 0xa1, 0x1a, 0x99, 0xce, 0x65, 0xf1, 0xb1, 0x68, 0x64, 0xf7, 0xa7, 0xdf, 0x96, 0xc3, + 0xa6, 0xd8, 0x58, 0xf1, 0x2a, 0x8a, 0xd0, 0x5c, 0x55, 0x2a, 0x04, 0x62, 0x9b, 0x5c, 0x1a, 0xf0, + 0x46, 0xf3, 0x7d, 0x8c, 0x46, 0x3f, 0x7e, 0x19, 0x19, 0x28, 0x3d, 0xcc, 0x1c, 0x96, 0x42, 0x47, + 0x17, 0xb0, 0x99, 0xbb, 0x47, 0xbc, 0x3d, 0xf1, 0xfb, 0x42, 0xa6, 0x5f, 0x4b, 0x12, 0xa7, 0x0a, + 0x9c, 0x62, 0x8a, 0xbb, 0x9d, 0xc2, 0x26, 0xf9, 0xd1, 0xeb, 0x38, 0x33, 0x9e, 0x2d, 0x59, 0x61, + 0x93, 0xb5, 0x10, 0xb7, 0xd4, 0x8e, 0xa4, 0x6f, 0xc8, 0xab, 0x70, 0x55, 0x81, 0x6b, 0xd9, 0xa1, + 0x90, 0x5c, 0xa5, 0xc6, 0xcf, 0x2d, 0x2a, 0x50, 0xea, 0xff, 0xe3, 0x54, 0xfd, 0x29, 0x14, 0x56, + 0x27, 0xb8, 0xcd, 0x82, 0x05, 0xae, 0x6e, 0x76, 0x90, 0x3e, 0x32, 0x88, 0xb9, 0x96, 0xbf, 0xaa, + 0x79, 0x3f, 0xce, 0xed, 0x44, 0xdc, 0x2f, 0x59, 0x3b, 0x70, 0xeb, 0xd3, 0x38, 0x55, 0xd9, 0xec, + 0x29, 0xbb, 0x4d, 0x03, 0xf3, 0x42, 0xda, 0x4a, 0x57, 0xaf, 0x8e, 0x74, 0xa5, 0x0f, 0x93, 0xf7, + 0xe6, 0xab, 0x7e, 0x38, 0x81, 0xc4, 0x9d, 0x68, 0xcd, 0x68, 0x8a, 0xd6, 0x5a, 0x9e, 0x7a, 0x75, + 0xb1, 0x75, 0xfe, 0xaf, 0x3d, 0x73, 0x51, 0x64, 0x73, 0x6b, 0xc7, 0xb6, 0x70, 0x41, 0x3b, 0xf6, + 0xde, 0x74, 0x6a, 0xce, 0xd5, 0x60, 0x4a, 0x05, 0x9d, 0x2c, 0x23, 0x39, 0xce, 0xbf, 0xec, 0xb2, + 0x40, 0x43, 0xf2, 0xbe, 0xfd, 0x46, 0x10, 0x97, 0x8a, 0x23, 0xe2, 0xec, 0xb3, 0xeb, 0xc6, 0xfa, + 0x98, 0x06, 0x7e, 0x73, 0x95, 0x39, 0xeb, 0x9e, 0xcb, 0xc2, 0xea, 0x71, 0x96, 0xcb, 0x64, 0xb1, + 0x95, 0x46, 0x23, 0xc9, 0x47, 0x84, 0x75, 0xd9, 0xec, 0xec, 0x43, 0x23, 0xf2, 0x14, 0x67, 0x36, + 0xbc, 0xef, 0xd4, 0x64, 0xbd, 0x03, 0x10, 0x2c, 0x10, 0xe0, 0x56, 0x47, 0x73, 0x3a, 0x61, 0xf1, + 0x0b, 0xea, 0xce, 0x34, 0x89, 0xbd, 0xab, 0x0b, 0x03, 0xe8, 0x0a, 0x83, 0x67, 0xc3, 0x39, 0x56, + 0x3f, 0x45, 0x6b, 0x80, 0x41, 0xf2, 0x6c, 0x31, 0xd9, 0x15, 0x21, 0xbb, 0x78, 0xaa, 0x65, 0xa7, + 0xa2, 0x0c, 0xc8, 0xaa, 0x44, 0xfe, 0x37, 0x1e, 0x4b, 0x58, 0x99, 0x14, 0x0c, 0xe7, 0xa7, 0x42, + 0x76, 0x94, 0x85, 0x25, 0x8c, 0x6e, 0x9a, 0x51, 0x3f, 0x7c, 0x94, 0x39, 0x6c, 0xe1, 0x7c, 0x5d, + 0x0c, 0x39, 0xa3, 0x81, 0x46, 0x4d, 0x60, 0x5c, 0xe6, 0x5a, 0x87, 0x72, 0xee, 0x6e, 0x4d, 0xd7, + 0x64, 0x9b, 0x92, 0x99, 0xab, 0x42, 0xf4, 0x89, 0xd2, 0xac, 0x71, 0xc2, 0x04, 0x9d, 0x4c, 0xdb, + 0x72, 0x1b, 0x2b, 0x58, 0x95, 0xfb, 0x93, 0x1e, 0x08, 0x44, 0xb5, 0xb1, 0xf7, 0x04, 0xa6, 0xe8, + 0x56, 0x1f, 0x26, 0x59, 0x39, 0xc3, 0x2c, 0x91, 0x04, 0x0f, 0xfe, 0x34, 0xfc, 0xf2, 0x0a, 0xe5, + 0x34, 0x58, 0x4e, 0x50, 0xb1, 0xfa, 0x5b, 0xd5, 0x89, 0x88, 0x5b, 0xe7, 0xb0, 0x17, 0xdd, 0x0e, + 0xee, 0x4b, 0x0e, 0xe6, 0x43, 0x1b, 0x23, 0x00, 0x7d, 0xcc, 0x1b, 0xad, 0x3b, 0x18, 0xf3, 0xc4, + 0x6b, 0x25, 0x39, 0xfc, 0x32, 0x09, 0xba, 0x9c, 0xb8, 0x5e, 0x07, 0x4a, 0xf8, 0x49, 0x37, 0x42, + 0xe2, 0xfe, 0x45, 0x3a, 0xb6, 0x13, 0xb4, 0xea, 0xf2, 0xd8, 0x06, 0x74, 0x61, 0x45, 0xc8, 0x46, + 0xe9, 0x86, 0x59, 0x87, 0x32, 0x71, 0xd2, 0xa3, 0xef, 0x3a, 0x77, 0x5e, 0xe8, 0x73, 0x0c, 0xd3, + 0x82, 0x35, 0x1b, 0xfc, 0xcb, 0xc7, 0x32, 0xd5, 0xae, 0x15, 0xcc, 0x99, 0x6f, 0x56, 0x3f, 0xb6, + 0xe2, 0x1a, 0x14, 0x3f, 0xf0, 0x9a, 0xe8, 0x6c, 0x49, 0xcc, 0x7e, 0xc1, 0x90, 0xf9, 0xee, 0xdf, + 0x58, 0x40, 0xdc, 0xd9, 0x43, 0x97, 0x55, 0x2f, 0x42, 0x62, 0xf9, 0xa9, 0x18, 0xf9, 0xa0, 0x4a, + 0x17, 0x59, 0x35, 0xcd, 0x2a, 0x26, 0xda, 0x3f, 0x27, 0x5f, 0xd5, 0x59, 0x67, 0xc0, 0x5e, 0x8e, + 0x97, 0xb7, 0x8b, 0x2b, 0x4e, 0x70, 0xfb, 0x43, 0xc7, 0x03, 0x0f, 0xdd, 0x0f, 0x71, 0xdf, 0x29, + 0xa0, 0x21, 0x71, 0x87, 0xfe, 0xe6, 0xd2, 0x9f, 0x99, 0x90, 0x68, 0x4b, 0x2b, 0x37, 0x8c, 0x2e, + 0xfe, 0xe8, 0x43, 0x54, 0xed, 0x9d, 0x29, 0x96, 0x70, 0x7c, 0xfa, 0x9a, 0x24, 0x99, 0x54, 0xda, + 0x7f, 0x8b, 0xf7, 0xd9, 0x66, 0x8f, 0x90, 0x05, 0x9b, 0x91, 0x1e, 0x2b, 0x59, 0xb6, 0x9a, 0x43, + 0x00, 0x7c, 0xfd, 0x22, 0xf0, 0x85, 0xa4, 0x98, 0x17, 0xb4, 0x80, 0x4e, 0x9a, 0x40, 0xf9, 0x11, + 0x69, 0x0c, 0x39, 0xae, 0xf2, 0xeb, 0xb0, 0x3c, 0x16, 0xa7, 0x8a, 0x11, 0xf0, 0x6c, 0x4f, 0x33, + 0x26, 0x06, 0x99, 0x02, 0x4a, 0xec, 0x6c, 0xae, 0x85, 0x9e, 0xb4, 0xfd, 0x68, 0xb6, 0x09, 0x3f, + 0x27, 0x55, 0x7c, 0x07, 0x3a, 0x77, 0xb0, 0x17, 0x13, 0xab, 0x65, 0x95, 0x2d, 0x31, 0x92, 0x11, + 0x62, 0xa3, 0xe2, 0xd4, 0x86, 0xf9, 0xf4, 0x46, 0x6c, 0x53, 0x63, 0x72, 0x91, 0x3f, 0x38, 0xfc, + 0x4a, 0x96, 0xa8, 0x95, 0x33, 0xff, 0xe0, 0x66, 0x5e, 0x51, 0xfc, 0xbe, 0x89, 0xee, 0xc0, 0x7b, + 0xa6, 0x11, 0x1d, 0x23, 0x9c, 0x25, 0x62, 0xf6, 0x23, 0x56, 0x96, 0xa3, 0x09, 0xb4, 0x44, 0x84, + 0xbb, 0xd2, 0xf5, 0x5d, 0x9a, 0xb7, 0x43, 0xa4, 0x96, 0x27, 0x82, 0xb8, 0xf1, 0xfb, 0xfe, 0x84, + 0x00, 0xd7, 0xd6, 0xd3, 0xf6, 0x57, 0x4a, 0x3e, 0x86, 0x2f, 0x28, 0x70, 0x17, 0x8a, 0x5a, 0x96, + 0x2e, 0x83, 0x13, 0x73, 0xca, 0x7a, 0x47, 0x35, 0xdf, 0x11, 0xd1, 0x8a, 0x58, 0x9c, 0x2c, 0xaa, + 0xe7, 0xb5, 0x00, 0xcd, 0x2f, 0x0b, 0x5c, 0xcd, 0x04, 0xd7, 0x33, 0x87, 0xf4, 0x38, 0x6b, 0x86, + 0x43, 0xa1, 0x73, 0xad, 0x4e, 0xef, 0xcd, 0x80, 0x59, 0x2d, 0x27, 0xc4, 0x1c, 0x35, 0xe9, 0xf9, + 0xc2, 0x82, 0x6c, 0xff, 0x63, 0x21, 0x20, 0x15, 0xff, 0x3f, 0xfd, 0x62, 0xf8, 0x10, 0xdc, 0xec, + 0xfa, 0x35, 0xc0, 0xa8, 0x3e, 0x6a, 0xe6, 0x7f, 0xd4, 0xd0, 0x0f, 0xbb, 0xb0, 0xed, 0xf9, 0x37, + 0x89, 0x66, 0x1c, 0xa8, 0x96, 0xa1, 0xd0, 0x91, 0x2d, 0x4c, 0x0d, 0x6d, 0xc4, 0x2a, 0xf9, 0x69, + 0xa6, 0x67, 0x01, 0xf0, 0x20, 0xa9, 0xad, 0xee, 0x01, 0xac, 0x76, 0x91, 0x3c, 0xa3, 0x97, 0x1f, + 0x0a, 0x32, 0x68, 0xd3, 0xfe, 0x68, 0xbf, 0xb4, 0x9c, 0x4d, 0x46, 0x4b, 0x96, 0xd1, 0x03, 0x79, + 0x6d, 0x8d, 0xa2, 0xa3, 0x0c, 0xa7, 0xfa, 0xbc, 0xf0, 0x30, 0xcb, 0xfd, 0x08, 0x50, 0xd8, 0x86, + 0xe2, 0x2c, 0x24, 0xc4, 0x53, 0xf3, 0xc3, 0x0a, 0x61, 0x84, 0x87, 0x25, 0x13, 0x63, 0xe7, 0x7e, + 0xd7, 0x37, 0x4d, 0x2e, 0xaf, 0x4f, 0x02, 0x71, 0xa7, 0xe8, 0x00, 0xe1, 0x97, 0xa2, 0x25, 0x75, + 0xa9, 0x8c, 0xe2, 0x1f, 0xaa, 0x77, 0x50, 0x6a, 0x7d, 0xd2, 0x2e, 0x57, 0xdd, 0x7c, 0xd3, 0xa0, + 0xaf, 0x51, 0x2e, 0x9c, 0x56, 0xfa, 0xd2, 0xae, 0xa3, 0xcc, 0xd8, 0x8f, 0x30, 0x07, 0xf5, 0x68, + 0xb6, 0x73, 0x0b, 0x44, 0xef, 0x1e, 0x79, 0xe7, 0x8e, 0x59, 0x68, 0x9e, 0x7c, 0x0b, 0x93, 0x2e, + 0xe9, 0x09, 0x6e, 0xc3, 0x29, 0x74, 0xe4, 0x2c, 0x94, 0x96, 0x24, 0x3b, 0x7f, 0x65, 0xe9, 0xf8, + 0x19, 0xaa, 0xc8, 0xce, 0xc7, 0xca, 0xe2, 0x96, 0xc3, 0x5e, 0xdc, 0x9f, 0x65, 0x3c, 0x9c, 0xd1, + 0xf6, 0x82, 0x1b, 0xd7, 0x10, 0x16, 0xb7, 0xb2, 0xda, 0x4f, 0x16, 0xc6, 0x04, 0xc8, 0xf0, 0xec, + 0x0e, 0xc8, 0x6f, 0x0f, 0x39, 0x1e, 0x57, 0xd3, 0xbd, 0xbe, 0x39, 0x2d, 0xe3, 0x6c, 0xf2, 0x9c, + 0x3c, 0x82, 0xdf, 0x49, 0x72, 0x8c, 0x57, 0x9b, 0x13, 0xa5, 0xdc, 0xa9, 0x6e, 0x54, 0x3d, 0xac, + 0x35, 0xe2, 0x49, 0x2c, 0x7b, 0x2a, 0x8d, 0x49, 0x1f, 0x29, 0xd3, 0x58, 0x38, 0xcf, 0x11, 0x84, + 0x5a, 0x1e, 0xb6, 0xcf, 0x0b, 0xe3, 0xf7, 0x0e, 0x17, 0xa3, 0x32, 0x31, 0x17, 0x5d, 0xda, 0xe1, + 0x4f, 0x51, 0xbe, 0xc9, 0x24, 0x38, 0x60, 0xf0, 0x89, 0x07, 0xc0, 0x3c, 0x50, 0x9e, 0x37, 0x68, + 0x33, 0x4d, 0x47, 0x29, 0x74, 0x56, 0x9a, 0xe0, 0x33, 0x7d, 0x76, 0x66, 0xf5, 0x8e, 0xce, 0x2f, + 0xd0, 0x04, 0x3d, 0x46, 0xee, 0xb6, 0xd6, 0x0e, 0xbf, 0x21, 0x64, 0x3c, 0xbf, 0xaa, 0xdc, 0xa1, + 0x1a, 0x4a, 0x39, 0x45, 0x01, 0xbd, 0x18, 0x53, 0xa4, 0x83, 0x5a, 0xb3, 0xa2, 0xad, 0x0b, 0x9c, + 0xd2, 0x89, 0x06, 0x2c, 0x22, 0xe5, 0x29, 0xa1, 0xc9, 0xca, 0xc6, 0xd2, 0x40, 0xc0, 0x9a, 0xb6, + 0x73, 0xc6, 0xb6, 0x9b, 0x52, 0xe4, 0x41, 0x24, 0x6e, 0x7f, 0xd4, 0x21, 0x9d, 0xb1, 0x8e, 0x87, + 0x85, 0x15, 0xfb, 0x58, 0xdb, 0xf4, 0xe2, 0x7e, 0xa2, 0xb4, 0x85, 0x4a, 0x28, 0x0b, 0x4c, 0xb8, + 0x1d, 0x49, 0x2b, 0x83, 0x33, 0xa9, 0xa0, 0xfc, 0x11, 0xca, 0xc7, 0x26, 0xca, 0x3a, 0x43, 0xc0, + 0x64, 0x44, 0x16, 0xee, 0xcb, 0x2f, 0x00, 0x6f, 0xf7, 0xc7, 0xcf, 0xda, 0xec, 0x43, 0x3f, 0x29, + 0x23, 0xda, 0x1d, 0x69, 0xde, 0xd7, 0x8e, 0x67, 0x67, 0xc9, 0x59, 0xa9, 0xe6, 0x8f, 0x2f, 0xfc, + 0xd5, 0xd8, 0xe1, 0x8a, 0xdd, 0x39, 0x25, 0xb9, 0xfa, 0x55, 0x38, 0x64, 0xd8, 0x05, 0x1c, 0xba, + 0x43, 0x87, 0x4d, 0x82, 0x5c, 0xbb, 0x5e, 0x82, 0xb4, 0x64, 0x8b, 0x25, 0x65, 0xc1, 0xed, 0x74, + 0xc6, 0x06, 0xea, 0xba, 0x75, 0x6d, 0x3c, 0xec, 0xfa, 0x86, 0xeb, 0xa1, 0x84, 0x06, 0xa6, 0x42, + 0x62, 0x10, 0xa4, 0xc5, 0xdc, 0x6b, 0xdd, 0x47, 0x1c, 0x1a, 0x86, 0x76, 0xb4, 0xa1, 0xb4, 0x86, + 0x6d, 0xd3, 0xb4, 0xf8, 0x4c, 0x06, 0x36, 0xd6, 0x8a, 0x6e, 0x69, 0x49, 0x06, 0x28, 0x6f, 0x4f, + 0x2f, 0xc4, 0x3f, 0x2f, 0x73, 0x4f, 0xa0, 0x69, 0x10, 0x29, 0x23, 0xf1, 0x72, 0x2f, 0x3c, 0xf3, + 0x68, 0x8a, 0xda, 0x67, 0xc6, 0x80, 0xe3, 0xe1, 0x9b, 0x55, 0xb3, 0x0c, 0x81, 0x13, 0xf9, 0xb8, + 0xd8, 0x85, 0xc1, 0xb3, 0x18, 0x65, 0x60, 0xb0, 0x3e, 0xa3, 0x81, 0xb5, 0x18, 0x4a, 0xc6, 0xbd, + 0xb9, 0x97, 0xe2, 0x44, 0x1d, 0x72, 0x12, 0xee, 0x3e, 0xbb, 0xfa, 0x6c, 0x8f, 0x44, 0x91, 0xb4, + 0x8b, 0xaa, 0x6f, 0xc7, 0x0b, 0x72, 0x30, 0x3b, 0x95, 0x0c, 0xcf, 0x2a, 0x5c, 0x21, 0x68, 0xd9, + 0xc2, 0x2e, 0xa3, 0x0d, 0x69, 0xf4, 0x6c, 0x81, 0xe2, 0x7f, 0x3c, 0xc7, 0x96, 0x45, 0x74, 0xb0, + 0xc7, 0x9c, 0x41, 0x0e, 0xfa, 0xe9, 0x10, 0x4a, 0x84, 0x20, 0x05, 0x83, 0x59, 0x09, 0x87, 0xab, + 0x02, 0xae, 0xde, 0x36, 0x65, 0xc4, 0x55, 0x67, 0x22, 0x5b, 0xf0, 0x9b, 0x9b, 0xfd, 0xcd, 0x1c, + 0xcd, 0x76, 0x55, 0x00, 0x94, 0x3e, 0x12, 0x7b, 0x06, 0xf1, 0x40, 0xdf, 0xaa, 0x47, 0xf8, 0x58, + 0xf1, 0x52, 0x36, 0x39, 0x16, 0x43, 0x79, 0xfa, 0x24, 0x26, 0x71, 0x40, 0x15, 0xd5, 0x44, 0x55, + 0xc4, 0x87, 0xb9, 0xa1, 0xb4, 0x80, 0x82, 0x0e, 0xa8, 0xd0, 0x6b, 0xb9, 0xa2, 0x35, 0x86, 0x11 +}; + +#define composite65_ed25519_msg composite_test_msg + +static const uint8_t composite65_ed25519_add_random[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const uint8_t composite65_ed25519_sig_digest[] = { + 0xb1, 0x29, 0x27, 0x7a, 0x59, 0x11, 0xdd, 0x29, 0x16, 0xa4, 0xe2, 0x1d, 0x0a, 0xe3, 0x69, 0xe5, + 0xeb, 0x6a, 0xda, 0xc3, 0x4b, 0x34, 0x9e, 0x75, 0x59, 0x89, 0xcf, 0xf9, 0x13, 0xa8, 0x6f, 0x4c +}; + +static const uint8_t composite65_ed25519_sig[] = { + 0x48, 0x9b, 0x82, 0x0c, 0x91, 0x7d, 0x80, 0x27, 0xde, 0xb2, 0x4d, 0x53, 0xcc, 0xe9, 0x60, 0x8b, + 0x80, 0xcd, 0xd9, 0xcf, 0x29, 0xaf, 0xf7, 0xca, 0x7d, 0x0a, 0xa0, 0xa8, 0x8c, 0x82, 0x82, 0x11, + 0x25, 0xdb, 0x46, 0x9c, 0x27, 0x37, 0x81, 0xbd, 0xc8, 0xbd, 0xf8, 0x88, 0xfb, 0x92, 0x15, 0x2e, + 0xe9, 0x0e, 0x9b, 0x23, 0xae, 0x4a, 0x2f, 0x38, 0x0a, 0x8f, 0x99, 0x34, 0x8e, 0x57, 0x2a, 0x86, + 0xad, 0x30, 0x53, 0xdc, 0x6d, 0x34, 0x33, 0x4e, 0x46, 0x9b, 0x78, 0x4c, 0xab, 0xc8, 0x94, 0xc9, + 0xa7, 0xd2, 0x87, 0x06, 0xd0, 0x49, 0xf1, 0x25, 0x22, 0x1f, 0x48, 0xb3, 0xc3, 0x5b, 0xf4, 0x4a, + 0x87, 0xcd, 0x1e, 0x32, 0x93, 0x35, 0xea, 0x85, 0xa7, 0xe1, 0x9a, 0xe1, 0xb4, 0xec, 0x2e, 0x68, + 0xc9, 0xa8, 0xfe, 0x34, 0x51, 0x10, 0x3c, 0xf8, 0xd6, 0xcd, 0x39, 0x86, 0xd3, 0x20, 0xbd, 0x74, + 0x02, 0xc6, 0x0d, 0xbb, 0x48, 0xa6, 0x68, 0xc9, 0x23, 0xb5, 0xe5, 0xf5, 0x7a, 0xd2, 0xe9, 0xee, + 0xe6, 0x77, 0xf6, 0x6b, 0x35, 0xb9, 0xc8, 0xc3, 0x0e, 0xf0, 0xc6, 0xbb, 0x28, 0x11, 0x0e, 0x2d, + 0xac, 0xd7, 0x5d, 0xd4, 0x36, 0x7f, 0x27, 0x73, 0x9e, 0x39, 0x2f, 0xd8, 0xeb, 0x6e, 0xf4, 0x4a, + 0x2a, 0x09, 0x74, 0x86, 0xf7, 0x0d, 0x25, 0x8e, 0x9f, 0x05, 0x2c, 0x3b, 0xe9, 0x59, 0xc0, 0x89, + 0xad, 0x95, 0x30, 0x22, 0x13, 0x06, 0x1c, 0x89, 0x8d, 0x7e, 0x79, 0xc1, 0x32, 0x4b, 0x5e, 0xe7, + 0x59, 0xc5, 0xc3, 0x4f, 0x44, 0xe2, 0x2f, 0x47, 0x18, 0xb3, 0xa4, 0x21, 0xc3, 0x70, 0x5d, 0xdb, + 0x98, 0xee, 0x5a, 0x68, 0xa8, 0x89, 0x37, 0x9f, 0x9e, 0x4b, 0x83, 0x25, 0xcd, 0xe5, 0x6a, 0x8a, + 0x24, 0xe5, 0x29, 0x41, 0xf4, 0x43, 0x96, 0x81, 0x3b, 0x32, 0x39, 0x7d, 0xd3, 0xb6, 0xe5, 0xf1, + 0x6b, 0x73, 0x21, 0xe2, 0xeb, 0x5f, 0x08, 0xac, 0x6e, 0x15, 0x35, 0x46, 0xa8, 0x31, 0x43, 0x8f, + 0x09, 0x37, 0xe3, 0x8a, 0x6d, 0x8b, 0x1a, 0xfa, 0xed, 0xd8, 0x22, 0xa7, 0x77, 0x93, 0xd5, 0x30, + 0xa9, 0x0c, 0x6d, 0xd5, 0x5d, 0x4b, 0x8f, 0x80, 0x37, 0x4d, 0xe2, 0xa6, 0x65, 0xd8, 0x05, 0xc7, + 0x2c, 0x72, 0x13, 0x66, 0xc2, 0xd9, 0xe0, 0x2c, 0xcc, 0x10, 0xb2, 0x98, 0xdb, 0x23, 0x9f, 0xbc, + 0xa0, 0xdd, 0x3e, 0x74, 0x2f, 0x87, 0x05, 0xd3, 0x47, 0xd3, 0xfb, 0x1f, 0xbb, 0x07, 0xa2, 0xc4, + 0xe8, 0x74, 0xd5, 0x22, 0x01, 0x44, 0xf3, 0x45, 0x13, 0xeb, 0x92, 0x10, 0x74, 0x29, 0xcc, 0xee, + 0x7f, 0x9a, 0x6e, 0x18, 0x91, 0xdf, 0xdf, 0x3f, 0x8b, 0x68, 0x33, 0x9f, 0x1b, 0xbc, 0xfc, 0xf4, + 0x9c, 0x6a, 0x09, 0xc0, 0x15, 0x31, 0xa1, 0x4f, 0xba, 0x07, 0x8b, 0x2b, 0xe9, 0xc0, 0x38, 0x2d, + 0x3e, 0x2c, 0xdd, 0x8c, 0x73, 0x30, 0x73, 0xec, 0xd7, 0x0d, 0xc8, 0x8c, 0xc3, 0x24, 0x0a, 0xa9, + 0xd7, 0x37, 0xd2, 0xcb, 0x01, 0xe4, 0xdd, 0x14, 0x88, 0x1d, 0xcf, 0x93, 0x75, 0x38, 0x51, 0x1b, + 0xd3, 0x82, 0x38, 0xa4, 0x6b, 0xd1, 0xd3, 0x62, 0x38, 0xc5, 0x1c, 0x46, 0xcf, 0xb4, 0x35, 0x66, + 0x8a, 0x88, 0x47, 0x10, 0x2e, 0x5a, 0x8f, 0xcf, 0xe9, 0x4c, 0xd3, 0x73, 0x2b, 0x65, 0x47, 0x53, + 0x3c, 0x1f, 0xef, 0x0a, 0xff, 0xd4, 0xab, 0x11, 0x36, 0x53, 0x8a, 0xa5, 0x2f, 0xb6, 0x43, 0x08, + 0xce, 0x80, 0xa5, 0x78, 0x4f, 0x41, 0x4d, 0xa9, 0x57, 0xf0, 0xeb, 0x12, 0x90, 0x5c, 0x4e, 0x4d, + 0xa9, 0x4f, 0x14, 0xf0, 0xc5, 0x82, 0x81, 0x9d, 0xf1, 0x64, 0x24, 0x24, 0x3e, 0x71, 0x19, 0xbe, + 0xa9, 0x41, 0x29, 0xd8, 0x9d, 0xa9, 0x79, 0x22, 0x54, 0xc9, 0x8e, 0x4e, 0xb8, 0xbe, 0x26, 0x4b, + 0xc4, 0xf4, 0x67, 0x88, 0xcc, 0xcf, 0x71, 0x69, 0x18, 0x2e, 0x14, 0xe3, 0x7f, 0x3d, 0x82, 0x86, + 0xa6, 0xad, 0x6e, 0x9d, 0xf6, 0x82, 0xbd, 0x2e, 0xfb, 0x63, 0xb6, 0x97, 0xb2, 0xa4, 0x3e, 0xd3, + 0xe7, 0xf7, 0x33, 0xff, 0x2d, 0x68, 0x7f, 0x05, 0x66, 0x7d, 0x12, 0x35, 0x5c, 0x5d, 0x53, 0xd9, + 0x13, 0xe3, 0x4f, 0xa7, 0x0a, 0x72, 0x96, 0xb0, 0x49, 0xd4, 0x2b, 0x88, 0x97, 0x0b, 0x6c, 0x28, + 0x7e, 0xb4, 0x04, 0xf6, 0xbc, 0x44, 0xed, 0x02, 0x58, 0x0c, 0xa9, 0x11, 0x82, 0xf0, 0x36, 0xf8, + 0xb1, 0x9c, 0x64, 0x7c, 0x4c, 0x04, 0x15, 0xc5, 0xb7, 0xde, 0x8c, 0x54, 0xb6, 0xe0, 0xaf, 0xd2, + 0xbd, 0xdd, 0xf7, 0x33, 0x31, 0xae, 0x57, 0x08, 0xc0, 0x4c, 0x5c, 0x80, 0x04, 0x9f, 0xaf, 0x51, + 0x7a, 0x36, 0x73, 0x50, 0x75, 0x71, 0x38, 0x99, 0x4e, 0xcf, 0xcf, 0x2b, 0x01, 0xea, 0x46, 0x10, + 0x62, 0xc9, 0xdc, 0xa2, 0x21, 0x17, 0xa2, 0xaf, 0x8a, 0x4d, 0x61, 0xac, 0x52, 0x3b, 0x44, 0xcb, + 0x41, 0xe7, 0x39, 0xa4, 0x95, 0x5e, 0xeb, 0xa7, 0x87, 0x94, 0xae, 0x45, 0x3d, 0x6b, 0xb3, 0xa1, + 0x88, 0xc1, 0x7f, 0x59, 0x8e, 0x89, 0x58, 0x8c, 0x4d, 0xff, 0x39, 0x40, 0xb4, 0x89, 0x43, 0x3a, + 0x69, 0x03, 0x88, 0xbb, 0x45, 0xef, 0x1b, 0x26, 0x8e, 0x85, 0x73, 0x91, 0xb1, 0x44, 0x6b, 0xe8, + 0x2d, 0xe4, 0xdf, 0xb8, 0xb4, 0x5e, 0xed, 0x8f, 0x52, 0x49, 0x7b, 0x98, 0x99, 0x7e, 0x5a, 0x82, + 0xc9, 0xa6, 0xdd, 0x5d, 0x1d, 0x5c, 0x69, 0x9f, 0x26, 0xc0, 0x84, 0xd7, 0xcd, 0x93, 0x83, 0xbe, + 0x29, 0xf9, 0xc4, 0xed, 0x73, 0x10, 0x53, 0x37, 0xb8, 0x66, 0xac, 0x34, 0x08, 0x6e, 0xb3, 0x20, + 0x60, 0x12, 0x91, 0x29, 0xcc, 0x30, 0x93, 0x24, 0x81, 0xdb, 0x31, 0x7c, 0x06, 0x0c, 0x07, 0xc2, + 0x3f, 0xaf, 0xbd, 0x8b, 0x45, 0x4f, 0x9d, 0xdd, 0x96, 0x33, 0x73, 0x59, 0x41, 0x64, 0x3f, 0x01, + 0x0d, 0x9e, 0x3e, 0xd7, 0xa9, 0xda, 0xb5, 0x0c, 0xa8, 0x34, 0xa0, 0xf1, 0x61, 0x75, 0x1d, 0xbe, + 0xc2, 0xb5, 0x20, 0xee, 0xce, 0xae, 0x2f, 0x93, 0x90, 0x07, 0x94, 0x60, 0x55, 0x4e, 0x73, 0x1e, + 0xd2, 0x9e, 0xd6, 0x71, 0xab, 0x69, 0x8e, 0xcb, 0x64, 0x37, 0x92, 0x19, 0x41, 0x0a, 0x53, 0x5b, + 0xb7, 0x07, 0xd0, 0x1e, 0xe4, 0x6e, 0x77, 0xfd, 0x11, 0xf8, 0x50, 0x26, 0x15, 0x47, 0xbc, 0x6b, + 0xa9, 0x71, 0x58, 0x84, 0x1e, 0x61, 0x27, 0x10, 0x6e, 0xcf, 0xb9, 0xa8, 0x27, 0x19, 0x2b, 0xb9, + 0x8a, 0xdf, 0xed, 0xc4, 0xfe, 0x5d, 0xeb, 0x1a, 0x36, 0x0c, 0x02, 0xb0, 0x2d, 0xc2, 0xcb, 0x21, + 0x57, 0xdd, 0x8c, 0x1e, 0x82, 0x54, 0x59, 0x49, 0x4f, 0x40, 0xe9, 0x62, 0x4c, 0x27, 0x9a, 0xdd, + 0x97, 0xca, 0xb4, 0x83, 0xb0, 0x57, 0x6b, 0x5d, 0xe4, 0xd8, 0xcb, 0xb3, 0x0c, 0x08, 0x01, 0xdc, + 0xb1, 0xee, 0xc5, 0xce, 0x7d, 0xa0, 0xda, 0x17, 0x00, 0x04, 0x3c, 0xac, 0x37, 0xa4, 0x7d, 0xdf, + 0xff, 0x8e, 0x91, 0xac, 0xe7, 0x6b, 0x6c, 0xef, 0xf2, 0x96, 0xb4, 0xcb, 0xb5, 0x35, 0x17, 0x67, + 0x43, 0x82, 0xf1, 0x40, 0x6e, 0x5e, 0x92, 0x96, 0x99, 0x72, 0x3f, 0x22, 0x8a, 0x20, 0xfb, 0x50, + 0xb1, 0x04, 0xac, 0x92, 0xec, 0xc5, 0x22, 0xcc, 0xab, 0x37, 0xc0, 0x54, 0x84, 0x8f, 0xed, 0x00, + 0x19, 0x1b, 0xc7, 0xad, 0x3c, 0x29, 0x77, 0xe8, 0x28, 0xfa, 0xb7, 0x39, 0x0f, 0x12, 0xbe, 0xde, + 0xbe, 0xbd, 0x68, 0xbc, 0xb4, 0x40, 0xe5, 0xd3, 0x1b, 0xf8, 0x6d, 0xe4, 0x0d, 0xc7, 0x99, 0xef, + 0x07, 0x73, 0x3f, 0x3b, 0x4b, 0xd5, 0x30, 0xc0, 0xa0, 0x66, 0x1b, 0xdf, 0x0d, 0x2c, 0xc8, 0x0c, + 0xf3, 0xd5, 0xa3, 0x97, 0xb8, 0xc1, 0x7a, 0x26, 0x32, 0xae, 0x2f, 0x6b, 0xd0, 0xe5, 0x2c, 0x57, + 0xbc, 0x59, 0xa2, 0xfa, 0x47, 0x6b, 0x15, 0xcf, 0x56, 0x43, 0x84, 0xa7, 0x02, 0x6e, 0x07, 0xd7, + 0xff, 0xfb, 0x26, 0x46, 0x00, 0xd6, 0x2e, 0xb8, 0x36, 0xbd, 0x62, 0x09, 0x83, 0x0f, 0x0f, 0xde, + 0xf9, 0x6b, 0x7c, 0xec, 0x02, 0xf9, 0x3f, 0x72, 0xdb, 0x85, 0x84, 0x3a, 0x31, 0xdb, 0x62, 0x29, + 0x80, 0x75, 0x85, 0x1e, 0x2b, 0xd4, 0xa9, 0xf9, 0xf0, 0xd2, 0x09, 0x5f, 0x72, 0x6b, 0x3c, 0x51, + 0x06, 0xe3, 0x4b, 0x59, 0xce, 0xf2, 0x6f, 0xb9, 0xd1, 0x05, 0x15, 0x3f, 0x86, 0xaf, 0x53, 0x78, + 0x99, 0x1f, 0xc2, 0xc3, 0xd6, 0xde, 0x1c, 0x61, 0x62, 0x8f, 0x62, 0x54, 0x38, 0x56, 0x08, 0x8d, + 0xf8, 0x0e, 0x30, 0x3c, 0x19, 0xc7, 0x3b, 0xa8, 0x94, 0x08, 0xe6, 0x30, 0x7a, 0xef, 0xd2, 0x9c, + 0xf4, 0x70, 0x82, 0x9d, 0x35, 0x03, 0x33, 0x1b, 0x36, 0x32, 0x1d, 0x14, 0xdc, 0x52, 0x4e, 0x97, + 0xe4, 0x21, 0x29, 0xa0, 0x25, 0x2b, 0x84, 0x2a, 0xdf, 0xb1, 0xf5, 0x32, 0x46, 0x97, 0x32, 0x15, + 0x4b, 0xf6, 0xf1, 0x87, 0x26, 0xfb, 0x42, 0x8a, 0xaf, 0x1b, 0xe5, 0xed, 0x32, 0xbc, 0x4f, 0x34, + 0xaf, 0x20, 0x5d, 0x20, 0x3d, 0xa1, 0x04, 0x9e, 0x38, 0x89, 0xd3, 0x93, 0x74, 0x23, 0x3f, 0x4f, + 0x2b, 0xaa, 0x66, 0x1f, 0x8a, 0xf6, 0x28, 0x4c, 0x6f, 0xdc, 0x7e, 0xa3, 0x1b, 0xd6, 0x88, 0x97, + 0xdc, 0xd4, 0x72, 0x61, 0x17, 0x05, 0x8a, 0xcc, 0x30, 0xd6, 0xdb, 0x26, 0xd0, 0x90, 0x0f, 0x0c, + 0x14, 0x03, 0xc0, 0x40, 0x4d, 0x8c, 0xc0, 0xa7, 0x36, 0xa8, 0xbf, 0xf9, 0xb2, 0xb0, 0x4c, 0x7b, + 0x7c, 0xb4, 0xbf, 0x26, 0x35, 0x62, 0x48, 0x83, 0x14, 0xad, 0x33, 0x37, 0x74, 0x3a, 0xf5, 0x15, + 0x6f, 0xd3, 0x0d, 0x15, 0x10, 0xec, 0xd9, 0xa7, 0xff, 0x23, 0xa4, 0xb2, 0x5d, 0x27, 0x3b, 0xcc, + 0x3e, 0xd5, 0x8e, 0x62, 0x2d, 0xa4, 0x73, 0x51, 0xc8, 0xb9, 0xc4, 0x9b, 0xee, 0x78, 0x98, 0x31, + 0xea, 0xd3, 0x2a, 0x67, 0x83, 0x0d, 0x13, 0x00, 0x68, 0x32, 0x3d, 0x60, 0xbd, 0x22, 0xbc, 0x4f, + 0xf0, 0xdf, 0xf8, 0x52, 0xa0, 0xb1, 0x5d, 0x62, 0xda, 0x10, 0x24, 0x6b, 0x8e, 0x69, 0x79, 0xc2, + 0x87, 0xc9, 0xb1, 0x33, 0x94, 0x76, 0xf9, 0x08, 0xde, 0x4a, 0xa0, 0x0c, 0x85, 0xad, 0x6e, 0x57, + 0x61, 0xb7, 0x6f, 0xdb, 0x68, 0x16, 0x8e, 0x36, 0xa8, 0x71, 0xb4, 0x91, 0xdb, 0xd2, 0x74, 0x64, + 0xf7, 0xbb, 0x86, 0x25, 0x56, 0xfd, 0x56, 0x16, 0x63, 0xd4, 0xe9, 0x9e, 0x54, 0x2c, 0x12, 0x24, + 0x68, 0x14, 0xa0, 0xe3, 0xdc, 0x14, 0xa1, 0xe7, 0x11, 0x05, 0x74, 0xd2, 0xcf, 0xfc, 0x8c, 0x48, + 0xb4, 0x4b, 0x78, 0xbb, 0xfc, 0x33, 0x0c, 0x41, 0xa4, 0xd3, 0x64, 0xa1, 0xe7, 0x36, 0x83, 0x09, + 0xdf, 0x84, 0x63, 0x78, 0x7a, 0x0a, 0xf5, 0x7d, 0xb2, 0x0a, 0xd9, 0x24, 0x8f, 0x30, 0xe8, 0xc4, + 0x23, 0x75, 0x37, 0xb5, 0xe1, 0x53, 0x29, 0x85, 0xab, 0x75, 0x72, 0x61, 0xf3, 0x5d, 0xe8, 0x17, + 0x63, 0x5a, 0x46, 0x59, 0x25, 0x9c, 0x8c, 0x42, 0x7d, 0xe8, 0xa5, 0xe5, 0x2c, 0x66, 0x33, 0x40, + 0x1e, 0x56, 0xbb, 0xac, 0x98, 0x00, 0x0a, 0x7a, 0x3d, 0x6a, 0xa1, 0x10, 0xde, 0x2e, 0xca, 0x6f, + 0x59, 0x6d, 0x38, 0x13, 0x21, 0x65, 0xff, 0x57, 0x31, 0x1f, 0x02, 0x5f, 0x87, 0x07, 0xc1, 0xfa, + 0x19, 0x89, 0x16, 0x61, 0xd9, 0xfb, 0xf6, 0xa1, 0xf8, 0xbe, 0x59, 0x1d, 0xe2, 0x91, 0x54, 0x77, + 0x32, 0x89, 0x0f, 0x41, 0x71, 0x58, 0x61, 0x69, 0x90, 0x9f, 0xd8, 0x29, 0xd0, 0x21, 0x42, 0x9a, + 0x08, 0x50, 0x57, 0x66, 0xd1, 0xa8, 0x4f, 0x20, 0x8a, 0x82, 0x8a, 0xed, 0xd3, 0x69, 0xe5, 0x35, + 0xa9, 0x7c, 0xf2, 0x2e, 0xa4, 0x28, 0xed, 0x18, 0x6f, 0x2c, 0x9b, 0x29, 0x7c, 0xd9, 0xce, 0x6e, + 0xac, 0x8d, 0x09, 0xbe, 0xd2, 0x7e, 0x22, 0x2a, 0x8d, 0xdf, 0x5d, 0x91, 0xea, 0xb2, 0xc1, 0x48, + 0x94, 0xc4, 0x94, 0x2d, 0x69, 0x84, 0xbc, 0x1d, 0x4e, 0xc9, 0x58, 0xa1, 0x6e, 0x0e, 0xc8, 0xea, + 0xe5, 0x40, 0x38, 0xf3, 0x40, 0x33, 0xbf, 0xfe, 0x42, 0x60, 0xbf, 0x00, 0xd3, 0x08, 0x6e, 0x7c, + 0x78, 0xc4, 0x7f, 0x24, 0x4c, 0x40, 0xe0, 0x7f, 0x4a, 0xea, 0x61, 0x62, 0x79, 0xe7, 0x42, 0xab, + 0xc1, 0x0b, 0xd1, 0x07, 0x83, 0x36, 0x9c, 0xe6, 0x6c, 0xf2, 0xa7, 0x09, 0x42, 0x47, 0x9c, 0x85, + 0x7d, 0x44, 0x36, 0x66, 0x87, 0x20, 0xb7, 0xc9, 0x80, 0x9a, 0xfa, 0xb2, 0xab, 0x46, 0xf4, 0x6b, + 0x3a, 0xa7, 0xc1, 0x2b, 0xa6, 0xaf, 0x32, 0x87, 0xd1, 0x52, 0xc2, 0xfc, 0xfc, 0x7c, 0xf5, 0xe6, + 0x2a, 0x70, 0x68, 0xb3, 0xda, 0xc4, 0xe8, 0xc6, 0x09, 0x1d, 0x75, 0x34, 0x60, 0x4c, 0x13, 0x4d, + 0x2d, 0xde, 0x16, 0xb4, 0x26, 0xfe, 0xf0, 0x2f, 0x39, 0xc2, 0xbe, 0xba, 0x11, 0xd3, 0x97, 0xd6, + 0xe5, 0x27, 0x31, 0x73, 0x88, 0x4b, 0xa0, 0x43, 0xc5, 0x98, 0xa7, 0xb2, 0x86, 0x06, 0xa3, 0xc5, + 0x55, 0x6a, 0x4a, 0x00, 0x68, 0xe9, 0xdc, 0x03, 0xc2, 0x31, 0xf8, 0x37, 0x03, 0xd1, 0xb3, 0x0b, + 0x46, 0x5b, 0x0d, 0xb0, 0x6a, 0x25, 0xaa, 0xc6, 0xa1, 0xb6, 0xc6, 0x35, 0x15, 0x8b, 0xc1, 0xf8, + 0x73, 0xc7, 0x51, 0x5b, 0x8c, 0x9e, 0x83, 0x34, 0xfc, 0x8c, 0x9f, 0x77, 0xb0, 0x90, 0x60, 0x05, + 0x73, 0xbe, 0x7b, 0x1f, 0x6c, 0x6a, 0xef, 0x16, 0x67, 0x58, 0xe3, 0x6d, 0xfe, 0x52, 0xf8, 0x00, + 0xcc, 0xff, 0x62, 0x1c, 0x48, 0x15, 0x77, 0x8f, 0x38, 0x21, 0x2c, 0x03, 0xb0, 0xbf, 0x0f, 0x15, + 0x67, 0xdf, 0x6e, 0x55, 0x45, 0x43, 0x36, 0xdf, 0x29, 0x8f, 0xc0, 0xde, 0x5e, 0xba, 0xc8, 0xb9, + 0xb1, 0xf9, 0x6e, 0x77, 0x4c, 0xfe, 0xba, 0xd5, 0xf9, 0x3f, 0xdd, 0x95, 0xb2, 0x0b, 0x84, 0x14, + 0x3d, 0x38, 0x3c, 0xd1, 0xd4, 0x5d, 0x8a, 0x6f, 0xa6, 0x5d, 0x3f, 0x32, 0x88, 0x3b, 0x2e, 0xeb, + 0xd8, 0x6a, 0x4e, 0x95, 0x4f, 0xca, 0x75, 0x6a, 0xd1, 0x7a, 0x48, 0xbe, 0x32, 0x13, 0x81, 0x53, + 0x6e, 0x51, 0x43, 0x74, 0x01, 0xc7, 0xfb, 0xd9, 0x42, 0x9c, 0x9d, 0xb4, 0x8d, 0x10, 0x29, 0xf1, + 0x71, 0xd2, 0xbe, 0xe9, 0xa4, 0x2c, 0x12, 0x39, 0xca, 0x7a, 0xe0, 0x4b, 0xe8, 0xb9, 0xcf, 0x97, + 0xe8, 0x8e, 0x06, 0xd8, 0xb7, 0xa3, 0x14, 0x08, 0xc8, 0x9c, 0xc9, 0xc8, 0x46, 0x99, 0x0a, 0x60, + 0xe3, 0x5e, 0x86, 0x73, 0x55, 0x6b, 0x2f, 0x08, 0x95, 0x4c, 0xf3, 0x33, 0x36, 0xb7, 0x20, 0xa6, + 0x51, 0x8d, 0xfe, 0xdd, 0x5b, 0xed, 0x69, 0xaf, 0xc5, 0xd2, 0x49, 0x78, 0xbe, 0x82, 0xc4, 0x25, + 0x1f, 0x7d, 0x82, 0x7c, 0xec, 0x97, 0xaf, 0xac, 0x3d, 0xaa, 0x5f, 0x89, 0x56, 0x50, 0x40, 0xe7, + 0x39, 0x1d, 0x9a, 0x45, 0xd9, 0x04, 0x44, 0xdb, 0xea, 0xfe, 0x19, 0xdc, 0x59, 0x40, 0xe3, 0xa4, + 0x80, 0x54, 0x3b, 0xa4, 0x56, 0x8a, 0xf8, 0xd4, 0x76, 0x0a, 0xb1, 0xba, 0x40, 0xac, 0xdf, 0x71, + 0xaa, 0x51, 0x7e, 0x7c, 0x18, 0xfd, 0x91, 0x44, 0x6f, 0x46, 0x86, 0x79, 0x32, 0xcc, 0x08, 0x09, + 0xd5, 0xe4, 0xc0, 0xaa, 0x99, 0xcc, 0x70, 0x7a, 0xda, 0x11, 0xcd, 0x1b, 0x5a, 0xa4, 0x79, 0xff, + 0xa5, 0x9c, 0x36, 0x8d, 0x96, 0x5b, 0xe7, 0x97, 0x7c, 0x8a, 0xbc, 0xed, 0x49, 0x83, 0xc3, 0x35, + 0x6b, 0x03, 0xcf, 0xeb, 0xbd, 0x50, 0x93, 0x32, 0xd2, 0xf9, 0xfd, 0x39, 0x0b, 0xd8, 0xd8, 0x83, + 0xb9, 0x05, 0x92, 0x96, 0x2b, 0x78, 0x68, 0x51, 0xd0, 0x94, 0xd7, 0x24, 0x32, 0xbe, 0x94, 0xea, + 0x5b, 0x95, 0x3a, 0x9c, 0xc7, 0xf1, 0x59, 0xea, 0xfc, 0x4d, 0x93, 0xcf, 0x1e, 0x87, 0xc9, 0xcb, + 0x2e, 0x97, 0xf7, 0xd0, 0xb3, 0x23, 0x61, 0xcc, 0x3c, 0xd5, 0xa3, 0x78, 0x3b, 0xa6, 0x64, 0xc7, + 0x97, 0x6d, 0x85, 0x8f, 0xa9, 0x45, 0xbb, 0x68, 0x1e, 0x7d, 0x85, 0x6c, 0xc8, 0x96, 0xf5, 0x66, + 0x7c, 0x35, 0x13, 0x9a, 0x13, 0x1a, 0x30, 0x7d, 0xf9, 0x44, 0x1b, 0xc5, 0xec, 0xc5, 0xde, 0x5e, + 0xc7, 0x00, 0x97, 0x6f, 0xeb, 0x00, 0x40, 0xce, 0xb2, 0x04, 0xf0, 0x65, 0x1a, 0xd0, 0x3f, 0xf9, + 0xa4, 0xde, 0x64, 0x52, 0x3c, 0xb9, 0x97, 0xa5, 0x35, 0x54, 0x90, 0xe7, 0xb3, 0xd2, 0x7f, 0x89, + 0x0a, 0x97, 0x47, 0x83, 0xe8, 0xcd, 0x18, 0x96, 0x4a, 0x39, 0x9a, 0xb2, 0xd0, 0xe6, 0x0e, 0xdf, + 0x19, 0x9d, 0x0d, 0xe1, 0x00, 0x35, 0xf1, 0x0f, 0x38, 0x20, 0x7b, 0x2a, 0x83, 0x54, 0x4d, 0x61, + 0xb8, 0x76, 0x15, 0x47, 0xbc, 0x93, 0x27, 0xf7, 0xc6, 0x4e, 0x94, 0x3f, 0xa3, 0x0b, 0xdc, 0x3a, + 0x76, 0x51, 0xc6, 0xf0, 0x11, 0x23, 0x1d, 0x94, 0x6c, 0x55, 0xee, 0xb8, 0xf2, 0x27, 0xba, 0x21, + 0x7d, 0x0a, 0x75, 0xaf, 0xd8, 0x4f, 0x6a, 0x9c, 0xe3, 0xa0, 0xb5, 0x51, 0x13, 0x02, 0xdb, 0x1e, + 0x4f, 0xa9, 0x04, 0xf4, 0xb0, 0xa7, 0xca, 0x35, 0x53, 0x63, 0xb8, 0xc4, 0xd3, 0x95, 0x36, 0x9e, + 0x02, 0xe3, 0x0c, 0x14, 0x08, 0xa7, 0x68, 0xa0, 0x15, 0x04, 0x24, 0xa5, 0x1a, 0x4b, 0xf9, 0x9a, + 0x97, 0x8d, 0xbf, 0x53, 0x54, 0x5e, 0xb6, 0x0c, 0xcb, 0xdd, 0x43, 0x44, 0x2f, 0x83, 0xc7, 0x86, + 0xc4, 0x79, 0x83, 0xb0, 0x64, 0x0e, 0x5a, 0xd7, 0x9c, 0x35, 0x5a, 0x7e, 0xde, 0x97, 0x14, 0xa4, + 0x53, 0x88, 0x49, 0x0c, 0x03, 0x11, 0x4b, 0x03, 0x28, 0x0c, 0x74, 0x26, 0x3d, 0x8a, 0xaf, 0x0a, + 0x29, 0x38, 0xbb, 0x40, 0x01, 0xe6, 0x07, 0xee, 0xef, 0xfd, 0x48, 0x9e, 0xfe, 0x54, 0x2d, 0x18, + 0xaa, 0x52, 0x31, 0x5b, 0x65, 0x83, 0x1e, 0xb8, 0x00, 0xf0, 0x87, 0xf1, 0x37, 0x96, 0x87, 0x89, + 0xf0, 0xe5, 0x21, 0xd8, 0xdf, 0xda, 0xc8, 0xf5, 0x75, 0x1e, 0xae, 0xc3, 0x67, 0x78, 0x72, 0x25, + 0x78, 0xda, 0x3f, 0x20, 0x5f, 0xd8, 0x9f, 0x0e, 0x90, 0x7f, 0xab, 0xd0, 0xcf, 0x96, 0xe4, 0x9f, + 0x9d, 0xbc, 0xd8, 0x46, 0x04, 0xde, 0x1a, 0x12, 0xe5, 0x84, 0x49, 0x8c, 0x6e, 0xfd, 0x5a, 0x1d, + 0x38, 0xae, 0x97, 0xa4, 0x4c, 0xd0, 0xdd, 0x30, 0x91, 0xc1, 0x3a, 0x3d, 0x49, 0xd1, 0x45, 0x28, + 0x4b, 0xcb, 0xe6, 0x06, 0x40, 0xaf, 0xd0, 0x39, 0x5d, 0xbc, 0xf1, 0xae, 0xdf, 0x86, 0x01, 0x52, + 0x6a, 0x1d, 0x48, 0x4f, 0x16, 0x88, 0x92, 0xf4, 0x2b, 0x8f, 0x24, 0x95, 0x73, 0xfb, 0xcf, 0x37, + 0x07, 0x1e, 0xcf, 0x46, 0xa7, 0x3d, 0xa1, 0x9c, 0xe3, 0xe4, 0xa2, 0x95, 0x74, 0x67, 0x6d, 0xea, + 0x34, 0xd5, 0x5e, 0xaf, 0x40, 0x2f, 0x41, 0x53, 0x34, 0x8b, 0xed, 0x66, 0x8f, 0xff, 0x06, 0xc0, + 0xc3, 0xfd, 0x20, 0x3d, 0xba, 0xf0, 0xdf, 0xb4, 0x42, 0x04, 0x28, 0x71, 0x10, 0xb0, 0x57, 0xe6, + 0xe2, 0x8e, 0x7b, 0x3a, 0x01, 0xbf, 0x40, 0xe9, 0xce, 0xe6, 0x6d, 0x8f, 0x98, 0xa1, 0x52, 0x88, + 0x13, 0x9d, 0xca, 0xbc, 0xfe, 0x3d, 0x44, 0x36, 0x94, 0x40, 0x13, 0x13, 0x63, 0x45, 0x54, 0x6b, + 0x6e, 0x24, 0x22, 0x09, 0x8d, 0x64, 0x7d, 0x13, 0x11, 0x45, 0xdf, 0xb9, 0x25, 0xb2, 0x79, 0x62, + 0x4d, 0x8f, 0x6f, 0x76, 0x8e, 0x7b, 0x94, 0x0c, 0xd2, 0x37, 0xb4, 0x20, 0xb4, 0x89, 0x5f, 0x35, + 0x3a, 0xea, 0xee, 0xd5, 0xbe, 0xfe, 0xe6, 0x5e, 0x0e, 0x1b, 0x97, 0xb4, 0x44, 0xb3, 0x2e, 0x14, + 0x5e, 0xe6, 0x7c, 0x6b, 0xcf, 0x01, 0x55, 0x7d, 0x13, 0xa5, 0xed, 0xf0, 0xc1, 0xc7, 0xcd, 0x94, + 0x8d, 0x71, 0x3c, 0x63, 0x0b, 0x7f, 0xa3, 0x3c, 0x43, 0xd7, 0x5f, 0xea, 0x01, 0xde, 0xff, 0x35, + 0x91, 0x8e, 0x20, 0x4e, 0x7c, 0xb3, 0xd7, 0x57, 0x13, 0x34, 0xc0, 0x2f, 0xbc, 0x4d, 0x1b, 0x1c, + 0xf3, 0xbf, 0x93, 0x81, 0xa4, 0x4c, 0x59, 0xd9, 0x41, 0x3a, 0x42, 0x55, 0x08, 0xc5, 0x5b, 0x3c, + 0x2d, 0xaa, 0x10, 0x9b, 0x23, 0x5a, 0x48, 0x57, 0xb1, 0xfc, 0xcc, 0x7f, 0xcd, 0x91, 0xbe, 0x5f, + 0x68, 0xd1, 0x8e, 0x61, 0xf2, 0xe9, 0x3d, 0xe9, 0xb3, 0x64, 0x0f, 0x7a, 0xf9, 0xf4, 0xdf, 0xb2, + 0x3c, 0x8e, 0xbb, 0x0e, 0x78, 0xe9, 0x38, 0x9d, 0xc7, 0xa9, 0x2c, 0xc1, 0x5d, 0x6e, 0xb1, 0x1d, + 0x7c, 0x3e, 0xf0, 0x8d, 0xaf, 0x2c, 0xca, 0x5b, 0xa2, 0xa3, 0xdb, 0x53, 0x5a, 0x5f, 0x4a, 0x73, + 0x9c, 0xaf, 0x91, 0x55, 0x59, 0xc0, 0x2c, 0x6e, 0x32, 0x25, 0x59, 0x02, 0xaf, 0xd4, 0xb9, 0x1f, + 0x1f, 0xdb, 0x5e, 0x32, 0xf0, 0xcf, 0xa4, 0xf9, 0x8a, 0x01, 0x65, 0x62, 0xeb, 0xcf, 0x2e, 0xac, + 0x43, 0x7b, 0x8c, 0x25, 0x7c, 0x6b, 0x97, 0x6a, 0x99, 0x3f, 0x80, 0x6a, 0xc8, 0xc3, 0xe6, 0x34, + 0x1c, 0x9e, 0xdb, 0x47, 0xa4, 0xcc, 0x3a, 0x84, 0x8e, 0xa0, 0xa7, 0x7d, 0x50, 0xc2, 0xa8, 0x5e, + 0xb9, 0x51, 0x85, 0x9a, 0xd5, 0x34, 0x09, 0xb9, 0x5a, 0x51, 0x6a, 0x63, 0x9d, 0xda, 0x86, 0x3b, + 0xcc, 0xf6, 0x11, 0xa9, 0x43, 0x6e, 0xfe, 0xee, 0xde, 0x2e, 0x93, 0x52, 0xe9, 0x53, 0x98, 0x61, + 0x69, 0x9b, 0xae, 0x06, 0x94, 0x79, 0x46, 0x29, 0x3d, 0xa9, 0x0d, 0x23, 0x8c, 0x00, 0x65, 0xd3, + 0x0d, 0x0e, 0x88, 0x18, 0x36, 0xdf, 0xaf, 0x6f, 0x83, 0x75, 0x55, 0xa1, 0xac, 0x36, 0x25, 0xad, + 0xcf, 0xc0, 0x62, 0x75, 0x91, 0x6d, 0x91, 0x67, 0x47, 0x9a, 0xc5, 0xe5, 0xe8, 0x17, 0xf6, 0x60, + 0x00, 0xcb, 0xdc, 0xfc, 0xee, 0x92, 0x1a, 0xc7, 0x29, 0xcb, 0x5b, 0x1e, 0x93, 0xcf, 0xb4, 0xbc, + 0x46, 0xe5, 0xc8, 0xc1, 0xab, 0xd1, 0x38, 0x6f, 0x7a, 0x6c, 0xb8, 0x67, 0xcf, 0xdf, 0xd5, 0x87, + 0x76, 0xfd, 0xce, 0x9f, 0x2a, 0x3b, 0xe5, 0x84, 0xdf, 0xdc, 0x57, 0x70, 0x48, 0xc1, 0x51, 0x31, + 0x4d, 0x9f, 0xc1, 0xf8, 0x45, 0x7f, 0xf8, 0xd9, 0xbd, 0x25, 0xe1, 0xcc, 0x58, 0x5c, 0x67, 0x50, + 0xd3, 0x50, 0xcc, 0x8a, 0x13, 0x84, 0x2e, 0xec, 0x75, 0xf0, 0xa4, 0x94, 0x96, 0x3e, 0x51, 0xf5, + 0x0a, 0xd2, 0x67, 0xb0, 0x7e, 0x36, 0x97, 0x38, 0x58, 0x98, 0x44, 0x0c, 0x58, 0xb3, 0x57, 0x08, + 0x8a, 0x01, 0x0f, 0xd7, 0x44, 0x08, 0x7b, 0x1b, 0x6c, 0xe6, 0x58, 0x13, 0x34, 0x78, 0xa4, 0x19, + 0xd8, 0x48, 0x04, 0xfc, 0x26, 0x2a, 0x19, 0xd7, 0xd9, 0x8f, 0x86, 0x88, 0x3d, 0xe4, 0xf3, 0x35, + 0xa1, 0x81, 0x26, 0x33, 0x9b, 0x8b, 0xbd, 0xa3, 0xfa, 0x65, 0x92, 0x9a, 0xac, 0xeb, 0xfd, 0x12, + 0xcf, 0x2b, 0x4d, 0xf7, 0xc4, 0x4b, 0x72, 0xea, 0x7d, 0x01, 0xf7, 0xdf, 0xb0, 0x1f, 0x81, 0x83, + 0xdb, 0x2c, 0x94, 0xb5, 0xf0, 0xee, 0x1a, 0x12, 0x4a, 0x7f, 0x65, 0x8c, 0x83, 0x49, 0xf4, 0xf2, + 0x17, 0x4b, 0x79, 0xa6, 0x90, 0x09, 0xc7, 0x26, 0xf8, 0xd5, 0x0c, 0x1d, 0xb3, 0x6e, 0x4c, 0xf5, + 0x31, 0x43, 0xfc, 0xe7, 0x46, 0x23, 0xd7, 0x38, 0x95, 0x11, 0x4f, 0x3d, 0x05, 0x49, 0xd5, 0x3e, + 0xe6, 0x64, 0xed, 0x8e, 0x7d, 0x7b, 0xde, 0xb1, 0xf4, 0x83, 0xb2, 0xd2, 0xca, 0xe2, 0xf5, 0x2a, + 0x64, 0xb3, 0xdb, 0x97, 0xfa, 0x3a, 0x57, 0x87, 0x34, 0x44, 0x5b, 0x62, 0x25, 0x6e, 0x0d, 0x57, + 0xf0, 0xf4, 0x71, 0x82, 0x1a, 0x60, 0x57, 0x5f, 0xb1, 0xad, 0xa6, 0x8e, 0xed, 0x0a, 0x2c, 0x39, + 0xeb, 0xf5, 0x91, 0x6f, 0x3e, 0xe4, 0x35, 0x55, 0x13, 0x7d, 0x9a, 0x8f, 0x04, 0x98, 0xea, 0xf3, + 0x91, 0x2d, 0xa9, 0xe6, 0x53, 0xbf, 0xfd, 0xb0, 0x42, 0xf6, 0xb6, 0x04, 0x58, 0xd6, 0x9f, 0x4e, + 0xf5, 0xb1, 0xba, 0x63, 0xf1, 0x6e, 0xca, 0xa4, 0x38, 0x36, 0x0a, 0x5f, 0x86, 0x17, 0x42, 0xe0, + 0xd8, 0xbf, 0xc4, 0xb1, 0xa0, 0x8c, 0x7a, 0x55, 0x1e, 0x8b, 0xdf, 0x2f, 0x25, 0x50, 0x10, 0x2f, + 0xb0, 0x1d, 0xcc, 0x4c, 0x8e, 0x9c, 0xf8, 0x82, 0x9e, 0x85, 0x50, 0xc3, 0x26, 0xc7, 0x80, 0xa3, + 0x95, 0x41, 0x28, 0x3d, 0x28, 0x4d, 0x00, 0xb2, 0x4b, 0x98, 0x0b, 0xd6, 0x61, 0x98, 0xdf, 0x16, + 0xfa, 0x59, 0x5c, 0x12, 0x7d, 0x42, 0x4c, 0x63, 0xfa, 0x7d, 0xf9, 0xf8, 0xc2, 0xa2, 0xbc, 0x7a, + 0xe3, 0x73, 0x8b, 0x49, 0x02, 0xef, 0x44, 0xda, 0xbd, 0xa6, 0x3c, 0x4f, 0x2e, 0x7c, 0x6d, 0x79, + 0x34, 0x4c, 0x91, 0xc4, 0xcb, 0xf3, 0x0f, 0x7c, 0x0a, 0x24, 0x25, 0x05, 0x0b, 0x2b, 0x3b, 0x60, + 0xa4, 0xc9, 0xe3, 0xf4, 0x25, 0x4b, 0x6b, 0x80, 0xa6, 0xd7, 0x24, 0x27, 0x2c, 0x75, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x08, 0x0b, 0x14, 0x1a, 0x1e, 0xb1, 0xa7, 0xfb, + 0x18, 0xd8, 0x3e, 0xdc, 0xeb, 0x39, 0x15, 0x38, 0xb7, 0x67, 0x16, 0xb1, 0x4d, 0xbb, 0x48, 0x19, + 0x8f, 0x9d, 0x68, 0x86, 0x36, 0xdc, 0xb7, 0xf6, 0xa2, 0x1a, 0xee, 0xd7, 0x65, 0xac, 0x09, 0x10, + 0xa4, 0xb7, 0xf1, 0x71, 0x5c, 0xb5, 0x48, 0x18, 0xad, 0x8b, 0x7b, 0x55, 0x28, 0x2b, 0xc5, 0xa5, + 0xa7, 0x65, 0x66, 0x6b, 0x04, 0xb2, 0xc8, 0xb4, 0x1e, 0xb5, 0x2a, 0xef, 0x05 +}; + +/* --- ML-DSA-87-Ed448-SHAKE256 --- */ +static const uint8_t composite87_ed448_priv[] = { + 0x2d, 0xc8, 0x5e, 0x04, 0x2d, 0xd5, 0xe4, 0xe1, 0xd8, 0x6d, 0x45, 0x18, 0x44, 0x64, 0x72, 0x32, + 0xbb, 0x43, 0x1e, 0xf1, 0xb9, 0x82, 0x3b, 0xf4, 0x79, 0x2b, 0x67, 0xae, 0x2b, 0xc0, 0xb7, 0x24, + 0x53, 0x9b, 0xb6, 0xf2, 0x89, 0xef, 0x2c, 0x3f, 0x98, 0xbb, 0x7d, 0xfa, 0xec, 0x5e, 0xaf, 0x41, + 0xb4, 0x37, 0x42, 0xe4, 0xd3, 0x99, 0xf3, 0x17, 0x78, 0x8a, 0xbf, 0x0f, 0xdb, 0x56, 0x8a, 0x2f, + 0x8b, 0x5a, 0x27, 0xb0, 0xf1, 0x98, 0x28, 0xfd, 0x79, 0x62, 0x3d, 0x3c, 0xa2, 0x70, 0x24, 0x2a, + 0x46, 0x39, 0xb1, 0xe0, 0xbb, 0x12, 0x12, 0xda, 0xbb +}; + +static const uint8_t composite87_ed448_pub[] = { + 0x87, 0xe2, 0x46, 0x2a, 0x3e, 0x60, 0xe7, 0x07, 0x0f, 0xbe, 0x10, 0xd1, 0x11, 0xfa, 0x97, 0x0f, + 0xd6, 0xc6, 0xed, 0x9a, 0x2a, 0x81, 0x28, 0xd5, 0x47, 0x85, 0x40, 0xac, 0x73, 0x01, 0x53, 0xca, + 0x68, 0xa5, 0x59, 0x4b, 0x6e, 0x54, 0x86, 0x69, 0xe1, 0xe6, 0xb6, 0x3b, 0x23, 0x2b, 0x29, 0xd2, + 0xf9, 0x57, 0xe6, 0xf4, 0x8b, 0x40, 0xfe, 0x26, 0xb8, 0xb4, 0x51, 0xd8, 0x35, 0xcc, 0x60, 0xd0, + 0xce, 0x09, 0x46, 0x34, 0xb5, 0xdd, 0x93, 0xe0, 0x5d, 0x51, 0x89, 0x65, 0xa4, 0x40, 0x3d, 0xe8, + 0xcb, 0xe6, 0xe4, 0x64, 0x8e, 0xfd, 0x31, 0x6c, 0x3b, 0x34, 0x3b, 0x7a, 0xc1, 0x4c, 0x2f, 0x10, + 0x49, 0xfe, 0xc0, 0x4e, 0x61, 0xbd, 0xa8, 0xfb, 0x63, 0x94, 0x61, 0xbf, 0x1e, 0xa2, 0xc2, 0x52, + 0x91, 0xe3, 0xb0, 0x99, 0x72, 0x79, 0x29, 0x12, 0x12, 0xae, 0x46, 0x53, 0xe4, 0x9c, 0x2d, 0xe5, + 0xb9, 0x43, 0xf3, 0x6d, 0x26, 0xc1, 0xf8, 0x09, 0x0b, 0xff, 0x59, 0xb1, 0xad, 0x9d, 0x11, 0xfe, + 0x8c, 0xd8, 0x96, 0xc8, 0x2e, 0x2e, 0x38, 0x5f, 0x90, 0xcc, 0xd2, 0xad, 0x95, 0x43, 0x73, 0xba, + 0x55, 0x27, 0x82, 0x31, 0x1b, 0x80, 0x82, 0xe5, 0xac, 0x3b, 0xf1, 0x01, 0xf9, 0x21, 0x80, 0x80, + 0x99, 0x89, 0xf8, 0xab, 0x8f, 0xec, 0x72, 0x3a, 0x99, 0x25, 0x7f, 0x5b, 0x0a, 0x6c, 0x26, 0x79, + 0x6f, 0x89, 0xf2, 0xbd, 0xdf, 0xc6, 0x59, 0x14, 0x86, 0xd0, 0x8f, 0x8e, 0x81, 0x42, 0xcf, 0x37, + 0xa4, 0x55, 0x0f, 0x5d, 0xfe, 0x8e, 0x66, 0x3e, 0x2c, 0x89, 0x3f, 0x6e, 0x36, 0xe9, 0x1f, 0x52, + 0x32, 0x1e, 0x58, 0x61, 0x73, 0x14, 0xc0, 0x0d, 0xbe, 0x71, 0x38, 0x39, 0xd7, 0x51, 0xc8, 0xce, + 0xb4, 0x71, 0x28, 0xcc, 0x38, 0x0c, 0xe0, 0x8f, 0x0b, 0x33, 0x19, 0x59, 0x93, 0xcc, 0x6f, 0x80, + 0xb7, 0x04, 0x00, 0xf6, 0x9c, 0xc6, 0xfc, 0x11, 0xca, 0x73, 0x70, 0x10, 0xdc, 0x15, 0xaa, 0x06, + 0xf7, 0x0a, 0x26, 0x4d, 0x16, 0x10, 0x6c, 0xdf, 0x91, 0xa3, 0x5f, 0x90, 0xb9, 0x12, 0x24, 0xef, + 0xc7, 0xc1, 0x12, 0xe5, 0xf3, 0x27, 0x6f, 0xb5, 0xec, 0x25, 0x6f, 0x1d, 0x1d, 0xb4, 0x42, 0xe5, + 0x5e, 0x59, 0x5e, 0x2f, 0xb3, 0x84, 0xe9, 0x03, 0x26, 0xa4, 0x21, 0xa3, 0xc2, 0xa9, 0x6e, 0x76, + 0x19, 0x5c, 0xe3, 0xef, 0x55, 0x73, 0x6b, 0xd8, 0x35, 0xfa, 0x3f, 0xb0, 0x80, 0x8b, 0x1b, 0x41, + 0xc5, 0xeb, 0xc6, 0x62, 0x2c, 0xd3, 0xba, 0x57, 0xa1, 0xc8, 0x1b, 0x96, 0x94, 0xca, 0x2e, 0x75, + 0xdb, 0x79, 0x1b, 0x59, 0x90, 0x26, 0x29, 0xd3, 0xc5, 0xb8, 0x35, 0x4b, 0x85, 0x5f, 0xb2, 0xe3, + 0x4f, 0x5e, 0x64, 0x6c, 0x3d, 0xdb, 0xfa, 0x89, 0x94, 0x28, 0xb4, 0x5b, 0xd6, 0x8b, 0x83, 0xf5, + 0x07, 0x8b, 0x84, 0x56, 0x36, 0x78, 0xb0, 0xc6, 0xf2, 0xd7, 0xb3, 0x4c, 0xce, 0x5c, 0x81, 0x4f, + 0x1d, 0x82, 0xe5, 0x29, 0x53, 0xf3, 0x7c, 0x61, 0xfe, 0xe1, 0x05, 0xcb, 0x1b, 0x2c, 0x09, 0x55, + 0x07, 0x9c, 0x68, 0x9f, 0xe1, 0x0f, 0x18, 0x7c, 0x09, 0x9b, 0x6f, 0xbe, 0x84, 0xb7, 0x0c, 0xe6, + 0xeb, 0xfb, 0x4b, 0x09, 0x31, 0x13, 0x1a, 0x7d, 0x5d, 0xd1, 0xf7, 0xb3, 0x23, 0xdf, 0x66, 0x1b, + 0x7d, 0xc0, 0xe9, 0x84, 0xd9, 0x58, 0x36, 0x17, 0x36, 0x9e, 0x3e, 0xf7, 0x71, 0xfc, 0xa7, 0xa5, + 0x39, 0x26, 0xbc, 0x4f, 0x0f, 0xda, 0x51, 0xbc, 0x89, 0xc9, 0x76, 0x2c, 0x43, 0x1b, 0x7d, 0x29, + 0xf8, 0x1e, 0xd6, 0xb9, 0xe7, 0x07, 0x72, 0x83, 0x8e, 0x38, 0x8a, 0xfd, 0x13, 0xe9, 0xdb, 0x7e, + 0x9f, 0x55, 0xac, 0x20, 0x47, 0xa7, 0x68, 0x4f, 0xad, 0x67, 0x4c, 0x7f, 0x2a, 0x8f, 0x19, 0xf3, + 0xae, 0x06, 0xea, 0xa3, 0x8a, 0x8a, 0x7e, 0xd8, 0xed, 0x10, 0xaa, 0xbe, 0xb6, 0xcd, 0x10, 0x2d, + 0x82, 0x38, 0x08, 0x09, 0x2f, 0x19, 0x3d, 0x85, 0xcf, 0xc6, 0x89, 0xc8, 0xa8, 0x35, 0x14, 0x78, + 0x3f, 0x04, 0x76, 0xe5, 0xac, 0xf0, 0xf4, 0xf0, 0x70, 0x71, 0x98, 0x94, 0x5b, 0x2c, 0xb0, 0xcd, + 0xf2, 0x53, 0x3a, 0x27, 0x4f, 0xc1, 0x95, 0x3a, 0x22, 0x0f, 0xa6, 0xce, 0x51, 0xbc, 0x3c, 0x97, + 0xfb, 0xba, 0x7a, 0xd5, 0xf7, 0xf5, 0xc5, 0xf0, 0xf1, 0xef, 0x49, 0x4f, 0xf3, 0xd4, 0x39, 0x07, + 0x1f, 0x30, 0x72, 0x04, 0xf4, 0x91, 0x4c, 0x75, 0x7f, 0x8a, 0xf2, 0x04, 0x7d, 0xd5, 0xb1, 0x45, + 0x93, 0xf4, 0x44, 0x2e, 0x93, 0xc9, 0x33, 0xda, 0x87, 0x62, 0x48, 0x9e, 0x53, 0x34, 0xaf, 0xe9, + 0xe0, 0x66, 0xd7, 0x30, 0xe2, 0xb3, 0xb8, 0xfe, 0x7f, 0x71, 0xf1, 0x07, 0xf6, 0xc8, 0xdd, 0xb1, + 0x0f, 0x45, 0xb0, 0x3d, 0xf6, 0x64, 0x4d, 0xf7, 0x68, 0x27, 0xec, 0xc0, 0x0e, 0x0d, 0x7a, 0x30, + 0x71, 0xdf, 0xf2, 0x61, 0xd1, 0xe2, 0x22, 0xc6, 0xec, 0x7e, 0x2e, 0x51, 0xb5, 0x71, 0x53, 0xc0, + 0x4a, 0x87, 0x59, 0xc3, 0x99, 0x4a, 0x66, 0x0c, 0x62, 0x32, 0x61, 0x94, 0x09, 0x47, 0x64, 0x48, + 0x46, 0xf5, 0x1e, 0xfd, 0xbe, 0x12, 0x44, 0x7a, 0x07, 0x37, 0xe1, 0x67, 0x95, 0x0d, 0x48, 0xa0, + 0x03, 0x7a, 0x9f, 0x26, 0xfc, 0xa9, 0xf9, 0x1d, 0x93, 0x76, 0x67, 0x91, 0x1c, 0x1b, 0xa7, 0x66, + 0x68, 0xc4, 0x3d, 0x5e, 0x0f, 0xb7, 0x9e, 0xbc, 0x09, 0x03, 0x6e, 0x72, 0x27, 0xb9, 0x77, 0xac, + 0x62, 0x70, 0x6d, 0x8c, 0xe6, 0x6a, 0xcb, 0x40, 0x5c, 0xe1, 0x43, 0x07, 0x28, 0xd0, 0xd9, 0x49, + 0xf6, 0xf1, 0xeb, 0x15, 0xaa, 0x76, 0x24, 0x94, 0x9c, 0x4e, 0xb2, 0xba, 0xb6, 0x58, 0x78, 0x68, + 0x25, 0x4e, 0xc4, 0xbf, 0x98, 0xd7, 0x24, 0xf9, 0xc0, 0xa2, 0x5b, 0xc4, 0xed, 0xd9, 0xe3, 0xb2, + 0x31, 0xab, 0xe1, 0x4e, 0x53, 0x86, 0x11, 0x22, 0x28, 0xbd, 0x9d, 0x5a, 0x83, 0xfa, 0x1c, 0x0b, + 0x0f, 0x20, 0x57, 0x30, 0xc0, 0xbd, 0x20, 0xc4, 0x44, 0x91, 0xc1, 0x1c, 0x95, 0x43, 0x54, 0x35, + 0xa9, 0xc6, 0x33, 0xa6, 0xd8, 0xac, 0x78, 0xb5, 0x65, 0xff, 0xe4, 0x5a, 0xd4, 0x09, 0x82, 0x0a, + 0xf2, 0xd5, 0xb0, 0xd5, 0x06, 0x17, 0x6e, 0x52, 0x58, 0x30, 0x7c, 0x46, 0xd9, 0x7e, 0x9c, 0x23, + 0x6a, 0x72, 0x5c, 0xf1, 0x7a, 0x65, 0x60, 0xb2, 0x3e, 0x57, 0xc6, 0x57, 0x53, 0x30, 0xc3, 0xba, + 0x5b, 0xde, 0x01, 0xc6, 0xbb, 0x04, 0x94, 0xd1, 0xa1, 0xcc, 0xf7, 0xaf, 0xc1, 0xda, 0x91, 0x70, + 0x8b, 0x0f, 0x1e, 0xf5, 0xc3, 0x62, 0xe8, 0x81, 0x61, 0x0e, 0x04, 0x6e, 0x82, 0xdc, 0xd7, 0xba, + 0xc9, 0xa7, 0x3d, 0x0c, 0x99, 0x39, 0x8a, 0x2d, 0xf2, 0x0f, 0xb8, 0x8c, 0x7c, 0xe4, 0xa1, 0xc7, + 0xde, 0xe2, 0x25, 0x79, 0x9e, 0x20, 0x2d, 0xef, 0xcb, 0xde, 0xdf, 0xc5, 0x4d, 0xb8, 0x48, 0x04, + 0x8f, 0x14, 0xa7, 0x3a, 0x59, 0xc4, 0xc9, 0x27, 0xc1, 0xb2, 0x8b, 0xb4, 0x8e, 0xe8, 0x92, 0xf1, + 0xcc, 0x65, 0x59, 0xe1, 0x66, 0x44, 0xa5, 0xd1, 0x59, 0x0a, 0xcc, 0xe5, 0x80, 0xe7, 0xbe, 0x02, + 0x18, 0x82, 0x81, 0x82, 0x42, 0x5d, 0xf5, 0x83, 0x80, 0xa5, 0x2f, 0xbd, 0x62, 0xff, 0xca, 0x14, + 0xe1, 0x2e, 0xda, 0x42, 0xd8, 0x11, 0xc1, 0x44, 0x22, 0x3e, 0xc8, 0x6d, 0x3d, 0x91, 0xfe, 0xc4, + 0xb2, 0x19, 0x05, 0x80, 0xef, 0xd8, 0x57, 0x3a, 0xc6, 0x65, 0x2a, 0x4a, 0x2d, 0x45, 0x6c, 0xdf, + 0x96, 0xaa, 0x30, 0x82, 0xfa, 0xf2, 0xde, 0xc9, 0x4d, 0xca, 0x7f, 0xcc, 0x66, 0xd5, 0x7c, 0x61, + 0x7a, 0x1e, 0x14, 0x0a, 0x23, 0x1e, 0x6e, 0xe7, 0x94, 0x01, 0x91, 0x26, 0xfd, 0x56, 0x88, 0xe6, + 0xdd, 0xf9, 0x0d, 0x5f, 0xb5, 0x80, 0xcb, 0x33, 0xe2, 0x76, 0xc7, 0xb4, 0x1c, 0xa3, 0xb8, 0x56, + 0xe0, 0xde, 0x21, 0xed, 0xbc, 0x2c, 0xc5, 0xfc, 0x0e, 0x1f, 0x21, 0xf8, 0x1b, 0x5b, 0x0d, 0x65, + 0xcf, 0x4b, 0x92, 0x0b, 0xf6, 0x5a, 0x3a, 0x29, 0xe1, 0x43, 0x3b, 0x40, 0x01, 0xd2, 0x28, 0xf9, + 0x79, 0xc7, 0x58, 0x34, 0xa3, 0x0c, 0x06, 0x9e, 0xde, 0x3f, 0xfb, 0x9c, 0x35, 0xc6, 0x4e, 0x47, + 0x3c, 0x2b, 0x2f, 0x22, 0x9d, 0x4d, 0x0a, 0x2d, 0x02, 0xa0, 0xbf, 0x5a, 0xca, 0x51, 0xc8, 0x8a, + 0x30, 0xf9, 0xbc, 0x69, 0xc4, 0x36, 0x83, 0xe7, 0xf0, 0xb9, 0xb8, 0x49, 0x7e, 0x0d, 0x1b, 0xaf, + 0x99, 0xfa, 0x53, 0x49, 0xba, 0xe7, 0x8b, 0x37, 0xfd, 0x3c, 0x40, 0x34, 0xf7, 0x6e, 0x2f, 0x30, + 0xa7, 0x70, 0x1e, 0xa7, 0xe3, 0xef, 0x94, 0x04, 0x99, 0xf2, 0x16, 0x71, 0x66, 0xa3, 0xb0, 0x92, + 0x41, 0x86, 0xa6, 0x8a, 0xad, 0x1a, 0xbe, 0x44, 0xc0, 0xb4, 0x8e, 0x8a, 0x99, 0x53, 0x2e, 0x6c, + 0xd7, 0xb6, 0x15, 0x4a, 0x54, 0xf0, 0x4c, 0xbe, 0x5d, 0x84, 0x9b, 0x37, 0x58, 0xd6, 0x9d, 0x33, + 0x21, 0xed, 0x33, 0x06, 0x18, 0x75, 0x8a, 0x85, 0xda, 0x08, 0xea, 0x51, 0xa8, 0x69, 0x7c, 0x8d, + 0x9f, 0x1f, 0xa4, 0xc4, 0xca, 0xa0, 0x66, 0xf3, 0x22, 0xd9, 0x0b, 0xb5, 0xd9, 0x64, 0x7e, 0xe7, + 0xf9, 0xd5, 0x1d, 0x59, 0x3a, 0x35, 0x44, 0x1f, 0x71, 0x6f, 0xea, 0xe0, 0x2d, 0x38, 0x7f, 0x6a, + 0x9a, 0x2e, 0x4b, 0x9b, 0x4a, 0xd1, 0xc8, 0x0f, 0xc8, 0x33, 0xb7, 0x3f, 0x36, 0x6e, 0xe7, 0x9c, + 0x18, 0x67, 0x03, 0x88, 0xbf, 0xdf, 0x7c, 0x09, 0x99, 0xc3, 0x0f, 0x9d, 0xe1, 0x56, 0xc4, 0xc2, + 0xc4, 0x1c, 0xfd, 0xd4, 0xc8, 0x96, 0x7e, 0x91, 0xed, 0xba, 0xa0, 0xbd, 0x5d, 0xd2, 0xed, 0x16, + 0x0a, 0x92, 0xa9, 0xac, 0x91, 0x70, 0x47, 0x8b, 0x19, 0x47, 0x81, 0xea, 0xe5, 0x4e, 0x9c, 0xee, + 0xde, 0x9f, 0x49, 0x5a, 0x07, 0xab, 0xa8, 0x2f, 0x6d, 0x46, 0xae, 0x08, 0x06, 0x34, 0xd1, 0xbf, + 0xdc, 0x3d, 0x61, 0x17, 0x90, 0x95, 0x39, 0x0b, 0x8d, 0xa6, 0x4d, 0x8c, 0xed, 0x74, 0x5f, 0x1b, + 0xab, 0xa0, 0x72, 0x76, 0xe6, 0x5f, 0x48, 0xb0, 0xb0, 0x78, 0xe0, 0xb9, 0xb2, 0x45, 0x57, 0x4e, + 0x23, 0xd1, 0xad, 0xd4, 0x9c, 0x71, 0x44, 0x38, 0x3b, 0xd9, 0x5e, 0x80, 0xcf, 0x28, 0x45, 0xaa, + 0x63, 0x98, 0x0e, 0xcf, 0xb9, 0x37, 0xb1, 0x32, 0xec, 0x1f, 0xfa, 0xa1, 0xc1, 0x80, 0x2d, 0xc5, + 0xa6, 0x93, 0xcb, 0x02, 0xb7, 0xa6, 0xbb, 0x7b, 0xcc, 0x81, 0xe0, 0x21, 0x42, 0xd9, 0x68, 0xc3, + 0x1f, 0xf7, 0x99, 0xeb, 0x78, 0xd9, 0x2b, 0x1b, 0x78, 0x4f, 0xf5, 0xec, 0x49, 0x5a, 0x96, 0x3d, + 0x9a, 0x46, 0xc0, 0x8d, 0xe0, 0xbc, 0xa5, 0x32, 0xff, 0x6c, 0x34, 0xc1, 0x79, 0x0a, 0xe1, 0xdc, + 0x55, 0xa8, 0x81, 0x63, 0x6b, 0x65, 0x08, 0xcd, 0xc2, 0x97, 0xa3, 0x1a, 0x62, 0x02, 0x19, 0xba, + 0x0c, 0xc4, 0x74, 0xd8, 0xc4, 0x2f, 0xca, 0xbb, 0xfd, 0xdd, 0xa8, 0x66, 0x93, 0x5c, 0xf3, 0xd0, + 0xe0, 0x94, 0x27, 0xef, 0x98, 0x93, 0xb7, 0x5d, 0x8b, 0x29, 0x38, 0xbb, 0xa3, 0xf3, 0xc5, 0xc0, + 0xab, 0x26, 0x64, 0xf1, 0x97, 0x2b, 0xca, 0x37, 0x68, 0x28, 0x46, 0xbb, 0xc0, 0xbc, 0xeb, 0x7c, + 0x9e, 0x7d, 0x4b, 0x2f, 0x63, 0xfe, 0x4b, 0x90, 0xe0, 0x64, 0xc8, 0x81, 0x48, 0xd2, 0x6a, 0xf1, + 0x4a, 0x59, 0xce, 0xa5, 0x3d, 0xb0, 0x91, 0x19, 0xde, 0xac, 0x7b, 0x09, 0xa7, 0xa9, 0x96, 0xea, + 0xeb, 0xaa, 0x2e, 0xd6, 0x89, 0x3e, 0x71, 0xac, 0x28, 0x2c, 0xf4, 0xe2, 0xa3, 0xb8, 0xf4, 0xdf, + 0x77, 0xf9, 0xd5, 0x7f, 0xb2, 0x2e, 0xa4, 0xb9, 0x2e, 0xd3, 0x5b, 0x80, 0xee, 0xa2, 0x63, 0x92, + 0x61, 0x81, 0x62, 0x40, 0x21, 0x04, 0xf4, 0x21, 0xa3, 0x38, 0x84, 0x27, 0xc3, 0x2e, 0x15, 0x94, + 0x26, 0x9d, 0xb8, 0x8a, 0x8d, 0xcf, 0x91, 0x34, 0x32, 0xc5, 0x73, 0xdc, 0xd2, 0x18, 0x16, 0xb0, + 0xc6, 0x32, 0xd9, 0xcb, 0x6f, 0xaa, 0xb8, 0x98, 0x13, 0xf9, 0x63, 0x71, 0xc7, 0xf3, 0xb6, 0x9c, + 0x8d, 0x91, 0x8c, 0xb2, 0x8a, 0xab, 0xda, 0xa0, 0x25, 0x10, 0x6d, 0xdf, 0x74, 0x29, 0x7c, 0x7f, + 0x92, 0x66, 0x2f, 0xbb, 0x1c, 0x41, 0xa6, 0xa0, 0xec, 0xd4, 0xc2, 0xf5, 0x3d, 0x3f, 0x92, 0x1a, + 0xea, 0xb2, 0x87, 0xa0, 0x8d, 0x0b, 0x5c, 0x7c, 0x2c, 0xc1, 0x41, 0xb5, 0x00, 0xff, 0xd9, 0x62, + 0x5f, 0x9d, 0xf0, 0x86, 0xce, 0xa6, 0x3c, 0x6f, 0x6a, 0xf7, 0x1e, 0x6d, 0x73, 0x51, 0x69, 0xbc, + 0xcf, 0xe4, 0xf5, 0xf8, 0xb7, 0x51, 0xe5, 0xd9, 0x01, 0x9a, 0xce, 0xeb, 0x0f, 0x18, 0xbe, 0xd3, + 0x3a, 0xc6, 0xf0, 0x9c, 0x3a, 0xf4, 0xb2, 0x3a, 0x9d, 0x22, 0x9c, 0x06, 0x13, 0xef, 0xdd, 0x4a, + 0xcc, 0xb1, 0x92, 0xcf, 0x8f, 0xff, 0x54, 0x41, 0xda, 0x63, 0xbd, 0x94, 0xb3, 0x27, 0xb0, 0xfa, + 0x64, 0xda, 0xca, 0x76, 0xc9, 0x47, 0xe1, 0x74, 0x15, 0x1b, 0x65, 0x2a, 0xa1, 0xcd, 0x84, 0x0b, + 0xde, 0x6b, 0x3a, 0x67, 0x2e, 0x1e, 0xf0, 0xaf, 0x61, 0x35, 0x61, 0xac, 0x35, 0x36, 0xe7, 0x03, + 0x93, 0xc6, 0xd1, 0x03, 0x2d, 0x5b, 0x03, 0x2f, 0x2c, 0x4e, 0xe9, 0x2e, 0xa7, 0x8a, 0x51, 0x8b, + 0x21, 0x54, 0x66, 0x38, 0x43, 0x70, 0x74, 0x01, 0xda, 0x9e, 0x91, 0x6b, 0x97, 0x60, 0x55, 0x63, + 0x58, 0x35, 0xcc, 0xb0, 0xdf, 0xd5, 0x9d, 0x82, 0x6c, 0x59, 0x57, 0x44, 0x15, 0xbb, 0xda, 0x15, + 0xcb, 0x6f, 0xc0, 0x78, 0xf7, 0x21, 0x7b, 0xb9, 0xa1, 0x44, 0xc7, 0xd0, 0x49, 0xe6, 0x0c, 0x2a, + 0x81, 0xad, 0xbb, 0x0a, 0x92, 0x93, 0x0b, 0x5d, 0x4b, 0xab, 0xe3, 0xff, 0xf9, 0x9c, 0x7e, 0xd3, + 0x5e, 0xa8, 0xab, 0xa4, 0x10, 0x3e, 0x28, 0x26, 0xfa, 0x50, 0x77, 0x8b, 0x5c, 0xbe, 0x92, 0x6d, + 0x5c, 0x2f, 0x0f, 0x8d, 0xac, 0x72, 0x45, 0xfd, 0xc0, 0xda, 0x00, 0x9f, 0x0a, 0x28, 0x5b, 0xf0, + 0x90, 0x42, 0x8e, 0x0f, 0x30, 0x2c, 0x40, 0x46, 0x26, 0xcf, 0x95, 0xb1, 0x3a, 0x7b, 0xe3, 0xf2, + 0x97, 0xcf, 0x55, 0x4b, 0xe4, 0xa6, 0x02, 0xd6, 0xa6, 0x43, 0x91, 0x73, 0x78, 0x9d, 0xa3, 0xc1, + 0x8b, 0x58, 0x6a, 0x2b, 0xc9, 0xbf, 0xde, 0x3e, 0x71, 0xeb, 0xb8, 0xda, 0xfe, 0xad, 0xef, 0xec, + 0x47, 0xf4, 0xcf, 0x93, 0x2e, 0x6b, 0xe5, 0xb4, 0x35, 0xe4, 0x80, 0x33, 0x61, 0xce, 0xff, 0x9b, + 0x18, 0xa8, 0x0f, 0xe1, 0x44, 0x28, 0xbb, 0xd7, 0x05, 0x99, 0x66, 0x92, 0x68, 0xd9, 0x5e, 0xc3, + 0x39, 0xea, 0x0a, 0xfd, 0xa6, 0xa4, 0x2e, 0x4f, 0xee, 0x7e, 0xcc, 0x03, 0x51, 0xfb, 0xa8, 0xfc, + 0x0d, 0xf2, 0x2c, 0xab, 0x37, 0xe1, 0x15, 0x70, 0x11, 0x58, 0x9c, 0xff, 0xcb, 0xf5, 0x9b, 0xc4, + 0xd5, 0x38, 0x5d, 0xd6, 0x56, 0x17, 0x43, 0x14, 0xf9, 0x84, 0x3e, 0xdd, 0x34, 0x7e, 0xae, 0xaf, + 0x79, 0x94, 0xf6, 0xd2, 0xb6, 0x8c, 0x1b, 0x5f, 0x42, 0x0b, 0x02, 0x1a, 0xac, 0xda, 0x1f, 0x67, + 0x48, 0xe1, 0xd7, 0xb3, 0xcc, 0x0b, 0x83, 0xc8, 0x0a, 0xb3, 0x1c, 0xf6, 0x09, 0xb4, 0x66, 0x5b, + 0xb5, 0xfb, 0xd7, 0x20, 0x55, 0x07, 0xe9, 0xf6, 0x57, 0xec, 0x7c, 0x68, 0x4e, 0x26, 0x0b, 0x9c, + 0xc3, 0xb6, 0x20, 0x31, 0xe5, 0x87, 0xc1, 0x48, 0x90, 0xb6, 0x16, 0xb2, 0x71, 0xaf, 0xb1, 0xef, + 0x2e, 0x27, 0x6d, 0x91, 0x59, 0xef, 0x0e, 0xaa, 0xb9, 0x6e, 0xae, 0x76, 0xca, 0x7d, 0xea, 0x66, + 0x3a, 0xa8, 0xf5, 0x08, 0x56, 0x1c, 0x0c, 0x12, 0x66, 0x68, 0x23, 0x88, 0xef, 0x86, 0xc9, 0x6e, + 0x13, 0x3b, 0x3e, 0x09, 0x75, 0xeb, 0xa6, 0x82, 0xd2, 0x6e, 0x2d, 0x59, 0x0f, 0x7e, 0x60, 0xab, + 0x3c, 0xb2, 0x91, 0x61, 0x50, 0xcd, 0x39, 0xa9, 0x07, 0xaa, 0xc3, 0xaa, 0x89, 0x15, 0x3a, 0xed, + 0xed, 0x05, 0xfe, 0x3d, 0x80, 0xd7, 0xf8, 0x37, 0x47, 0x60, 0xd6, 0x3b, 0xb5, 0x4d, 0x96, 0x2b, + 0xc9, 0xb0, 0xb4, 0x7d, 0xc0, 0x9d, 0x4b, 0x18, 0x6a, 0x55, 0x47, 0xd2, 0x3b, 0x06, 0x3c, 0x0f, + 0x46, 0xba, 0x2f, 0x36, 0x20, 0xc4, 0x6f, 0xba, 0x68, 0x43, 0x6b, 0x54, 0xbf, 0xe3, 0xcf, 0x53, + 0xea, 0x1c, 0x02, 0x54, 0xff, 0x31, 0x8e, 0x21, 0x81, 0x6e, 0x4f, 0x7d, 0xbb, 0xec, 0xf4, 0x19, + 0xb0, 0xc0, 0x33, 0xc1, 0x46, 0xd8, 0x96, 0xc6, 0x6b, 0x07, 0x0c, 0xbf, 0x81, 0x46, 0xac, 0xbb, + 0x45, 0x74, 0x64, 0x4e, 0x62, 0xe1, 0x44, 0xee, 0xcd, 0x9d, 0xe4, 0xcc, 0xd4, 0x56, 0x4b, 0xbf, + 0x80, 0x55, 0x21, 0xa7, 0xa7, 0x2a, 0x1b, 0x11, 0x52, 0x2e, 0xb9, 0x2c, 0x56, 0x38, 0x53, 0x2b, + 0x69, 0x10, 0x79, 0x3c, 0x87, 0x88, 0x87, 0x54, 0xe3, 0x52, 0x38, 0x68, 0x54, 0x77, 0x7f, 0xc7, + 0xb8, 0x32, 0xc9, 0xfb, 0x74, 0x0b, 0xee, 0x4c, 0x4f, 0xe6, 0x1c, 0xb9, 0xfe, 0x61, 0x8b, 0xa3, + 0x07, 0xdc, 0x1d, 0x62, 0xe6, 0xcb, 0xa8, 0x02, 0x8f, 0x21, 0xee, 0xc7, 0x9e, 0xe4, 0xd0, 0xbb, + 0xda, 0x31, 0xdd, 0x94, 0x16, 0x6b, 0xf6, 0x65, 0x04, 0x26, 0xd1, 0xd6, 0x50, 0xfa, 0xda, 0x99, + 0x9c, 0x38, 0xaa, 0x91, 0xc5, 0x47, 0xc2, 0x4a, 0x83, 0xb9, 0xa9, 0x43, 0x3d, 0x20, 0xf3, 0xed, + 0x93, 0x66, 0xbc, 0x1a, 0x89, 0x99, 0xf5, 0xe5, 0x83, 0x4b, 0xf9, 0x1e, 0x34, 0xa0, 0xdb, 0xcb, + 0x71, 0xd0, 0xe9, 0x34, 0x85, 0x85, 0x34, 0xb3, 0x0e, 0x23, 0x92, 0x6d, 0xaf, 0xe2, 0x30, 0x70, + 0x04, 0xbb, 0xb8, 0x2a, 0xca, 0x7f, 0x38, 0xc3, 0xfe, 0x41, 0x58, 0xa6, 0x66, 0xcc, 0x9e, 0xef, + 0xe2, 0x4e, 0x44, 0x7c, 0x76, 0x67, 0xcf, 0x9a, 0x09, 0x43, 0x7f, 0xa6, 0xd8, 0x47, 0x1f, 0x55, + 0x4f, 0xa1, 0x24, 0x22, 0x47, 0x27, 0xec, 0x5c, 0xa1, 0xcf, 0x29, 0x63, 0x67, 0x4e, 0x5a, 0xbe, + 0x26, 0xbd, 0xc6, 0xce, 0x5d, 0x61, 0xce, 0xab, 0x56, 0x76, 0x2c, 0xf7, 0xcc, 0x3d, 0xb2, 0x95, + 0x7f, 0xe2, 0x7e, 0xdf, 0x50, 0xb0, 0x2e, 0x83, 0x21, 0x21, 0x70, 0x1f, 0x51, 0xc6, 0x65, 0x4b, + 0xb1, 0x68, 0xc9, 0xe7, 0xc7, 0x80, 0xae, 0xff, 0x1c, 0x5f, 0xee, 0x2c, 0x7f, 0x76, 0x5b, 0x79, + 0xcc, 0x3e, 0x04, 0x07, 0x00, 0x01, 0x84, 0x62, 0xc8, 0xb2, 0xd1, 0xba, 0xb1, 0xa4, 0x24, 0x5e, + 0x8e, 0x8c, 0xf4, 0x84, 0xfb, 0xef, 0x00, 0xfd, 0x13, 0x34, 0xb3, 0x16, 0xe1, 0x64, 0xf1, 0x25, + 0xee, 0x77, 0x7f, 0xa9, 0xda, 0x22, 0xae, 0x72, 0xf2, 0x81, 0x55, 0x98, 0x67, 0x04, 0xe6, 0x15, + 0x34, 0xaf, 0x7f, 0x9d, 0x49, 0xe9, 0xea, 0x9f, 0x31, 0x60, 0xa8, 0x82, 0x16, 0x0e, 0xba, 0x78, + 0x74, 0x76, 0x36, 0x13, 0xb0, 0x66, 0xb0, 0xf3, 0xa6, 0x02, 0xaf, 0xc8, 0xf4, 0x1e, 0x38, 0x61, + 0x61, 0x00, 0x8a, 0xca, 0xa3, 0xe4, 0x0d, 0xb9, 0x8a, 0x74, 0xdc, 0x1a, 0xf3, 0xf8, 0x99, 0x85, + 0x22, 0x88, 0x90, 0x1e, 0xec, 0x7a, 0x77, 0xfc, 0x8d, 0x82, 0x18, 0x41, 0x81, 0xab, 0x9f, 0x27, + 0x25, 0x84, 0x79, 0x22, 0xb1, 0x91, 0xc5, 0x41, 0xa5, 0x20, 0x05, 0x0c, 0x72, 0x48, 0xd9, 0x77, + 0x8b, 0x5d, 0x32, 0xcc, 0xac, 0x9d, 0x93, 0xb8, 0x44, 0x19, 0xfa, 0x30, 0x36, 0xc8, 0x31, 0x4c, + 0xa2, 0xe7, 0xa1, 0x1b, 0x1c, 0xc4, 0xe7, 0x8e, 0x2a, 0x94, 0xf9, 0x1a, 0x24, 0xbc, 0x7c, 0x1d, + 0x08, 0xd6, 0x29, 0xd0, 0xf9, 0x7a, 0xc6, 0x4f, 0xac, 0x11, 0x04, 0x15, 0x3c, 0xae, 0x25, 0x85, + 0xed, 0xf3, 0xa3, 0x27, 0x66, 0x01, 0x98, 0x56, 0x83, 0xa9, 0x44, 0x9c, 0x8b, 0x5b, 0xf9, 0xe3, + 0x3e, 0x90, 0x85, 0x51, 0xdd, 0x1b, 0x19, 0x33, 0x00 +}; + +#define composite87_ed448_msg composite_test_msg + +static const uint8_t composite87_ed448_add_random[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static const uint8_t composite87_ed448_sig_digest[] = { + 0xc1, 0xd0, 0xd3, 0x8a, 0x79, 0x88, 0xfb, 0x79, 0xef, 0x80, 0x58, 0x8c, 0xbc, 0x1d, 0x07, 0x56, + 0xce, 0x8e, 0x6c, 0xf8, 0xd7, 0xfa, 0xd4, 0x53, 0x71, 0x65, 0x9d, 0xa9, 0x22, 0x1a, 0x25, 0x1f +}; + +static const uint8_t composite87_ed448_sig[] = { + 0xaf, 0x9d, 0x98, 0x77, 0xee, 0x32, 0xf2, 0xbc, 0xc5, 0x91, 0x4e, 0x88, 0xd1, 0xd8, 0x9c, 0x34, + 0x76, 0xda, 0x5f, 0x34, 0x76, 0xd8, 0xea, 0x17, 0x89, 0x30, 0xbb, 0x32, 0xa1, 0x25, 0x93, 0xc3, + 0xf0, 0x49, 0x46, 0xa7, 0xca, 0xc6, 0x56, 0xb1, 0xb4, 0x2b, 0xa1, 0x4c, 0xe2, 0x63, 0xe9, 0x09, + 0x8c, 0xf2, 0xe4, 0xf8, 0x0e, 0x6e, 0x22, 0xa5, 0xd8, 0x85, 0x21, 0xc1, 0xe2, 0x2a, 0x45, 0xb4, + 0x1b, 0xe1, 0x50, 0xd4, 0x21, 0x7d, 0x64, 0x7e, 0x81, 0xbe, 0x16, 0xff, 0x17, 0x78, 0xfb, 0xbc, + 0x43, 0x58, 0x20, 0xb4, 0xb2, 0xb2, 0xde, 0x7c, 0xc6, 0x72, 0xb1, 0xa5, 0x06, 0x10, 0xd2, 0x03, + 0x08, 0x69, 0x35, 0x8e, 0x6d, 0xc1, 0xda, 0x9c, 0x06, 0xa7, 0xb9, 0x65, 0x8b, 0x20, 0xaf, 0x11, + 0xf1, 0x83, 0xce, 0x7e, 0x62, 0x23, 0xf7, 0x90, 0x5c, 0xc5, 0xf0, 0x77, 0xef, 0x37, 0x69, 0xf6, + 0xbb, 0xcd, 0xe8, 0x5b, 0x70, 0xee, 0xd9, 0x6e, 0x6c, 0xcf, 0x24, 0x7d, 0x6f, 0x6d, 0xb9, 0x8a, + 0x7c, 0x66, 0x5f, 0xb2, 0xb6, 0xfc, 0x9a, 0xf2, 0x9e, 0x65, 0xe3, 0x8e, 0x8f, 0x67, 0x9f, 0xd3, + 0xf3, 0x4c, 0x34, 0xe4, 0x04, 0x07, 0x6b, 0x5d, 0x01, 0xa0, 0x9e, 0xbe, 0x3e, 0x3c, 0x66, 0x23, + 0xfe, 0xfb, 0x5b, 0xe5, 0x48, 0xf1, 0x0c, 0xc4, 0x12, 0x8e, 0x27, 0x09, 0x8d, 0x0e, 0xcb, 0xf3, + 0x09, 0xd7, 0x55, 0x9e, 0x4a, 0xe2, 0x0d, 0xc3, 0x0b, 0x9b, 0xb9, 0xeb, 0xaa, 0x8b, 0x21, 0xa8, + 0x0b, 0xcc, 0x30, 0xf2, 0x79, 0xc9, 0xfc, 0xf1, 0xee, 0xee, 0x82, 0x48, 0x03, 0x51, 0x82, 0x6b, + 0x20, 0x21, 0xb8, 0x6c, 0x03, 0xec, 0xaf, 0x77, 0x55, 0xd5, 0xf9, 0x64, 0xdb, 0x61, 0xb2, 0xbe, + 0x08, 0x01, 0x0d, 0x9e, 0x72, 0x0b, 0x71, 0x10, 0xc3, 0xd6, 0x0f, 0x0a, 0x42, 0xca, 0x42, 0x43, + 0x3d, 0x2f, 0xaf, 0xfe, 0x1f, 0x49, 0xb5, 0x01, 0x22, 0x92, 0x04, 0x7b, 0xe8, 0x90, 0xfb, 0x6b, + 0xdb, 0xde, 0xee, 0x62, 0x8a, 0x65, 0x78, 0x62, 0xe5, 0xaa, 0x50, 0x38, 0xce, 0xab, 0xab, 0x98, + 0x9b, 0x0b, 0x24, 0x0d, 0x16, 0xb9, 0xee, 0x96, 0xe2, 0xac, 0x2d, 0x3a, 0x01, 0xad, 0x9c, 0x37, + 0xc0, 0xb7, 0x7a, 0x76, 0x62, 0x44, 0xcd, 0xb1, 0xed, 0xd3, 0xec, 0xaa, 0x84, 0x31, 0xa0, 0x22, + 0x1b, 0x2b, 0xc7, 0xef, 0xed, 0xf4, 0x32, 0x3c, 0x09, 0xe8, 0x0c, 0xbe, 0xe8, 0xd2, 0xba, 0x8f, + 0xdf, 0x8c, 0x23, 0xf2, 0xe3, 0x79, 0x17, 0x6a, 0x27, 0xfa, 0x40, 0xb6, 0x4f, 0x39, 0x38, 0xee, + 0x20, 0x43, 0xd5, 0xbf, 0x1b, 0xe7, 0x58, 0x04, 0xbb, 0x04, 0x84, 0x4c, 0x06, 0x46, 0x31, 0x27, + 0x1f, 0x27, 0xe1, 0x53, 0x3e, 0xce, 0x19, 0x7b, 0x34, 0x70, 0xd1, 0x31, 0xd0, 0xcf, 0xa6, 0x74, + 0x62, 0xd8, 0x7d, 0x5d, 0xad, 0x5a, 0x1a, 0x78, 0x8f, 0x40, 0x70, 0x95, 0xed, 0xa0, 0x59, 0x0b, + 0x80, 0xad, 0x06, 0x0a, 0xd1, 0xc1, 0xc1, 0xc2, 0x6b, 0x4a, 0x89, 0x75, 0x6c, 0x65, 0x3b, 0x65, + 0x64, 0xbc, 0x5a, 0x2a, 0x77, 0x62, 0x7c, 0xc5, 0x21, 0x6d, 0x79, 0xb0, 0x7f, 0xc1, 0x2c, 0xcb, + 0xea, 0x8d, 0x55, 0x0e, 0x8a, 0xa3, 0xb1, 0x13, 0xf8, 0xf7, 0xbc, 0xdf, 0xad, 0x76, 0x70, 0x76, + 0x8a, 0x08, 0xab, 0x89, 0x3c, 0xa5, 0x05, 0xf9, 0x68, 0xae, 0x54, 0xa3, 0xce, 0x6a, 0x22, 0x6c, + 0xef, 0x2f, 0xee, 0x3b, 0x92, 0x26, 0x00, 0xf9, 0xb0, 0x2f, 0xce, 0x31, 0x7b, 0x49, 0x09, 0x92, + 0x99, 0x30, 0xb7, 0x4a, 0x0c, 0xb2, 0x0a, 0x86, 0x56, 0xf2, 0x01, 0xff, 0x37, 0xda, 0x61, 0x8c, + 0x79, 0xed, 0x69, 0xe6, 0x86, 0x83, 0x9e, 0x2f, 0xe5, 0xfb, 0x53, 0x8b, 0x02, 0xed, 0x07, 0x59, + 0xb2, 0x41, 0x04, 0x38, 0x9f, 0x42, 0xb2, 0x5c, 0x01, 0xa3, 0xbe, 0xf1, 0x24, 0x80, 0xd8, 0x56, + 0xbd, 0x31, 0x27, 0xbb, 0x35, 0xa0, 0x0b, 0x42, 0x5a, 0x07, 0x51, 0xf0, 0xa5, 0x07, 0xbe, 0xf7, + 0x8b, 0xc0, 0xf9, 0x0a, 0x67, 0x80, 0x58, 0xe6, 0x35, 0x3b, 0xb1, 0xa0, 0x27, 0x4b, 0xf3, 0x8c, + 0xb0, 0x68, 0x80, 0xb6, 0x77, 0x10, 0xc7, 0xfb, 0x7d, 0x57, 0x15, 0x5e, 0xf4, 0x71, 0x54, 0xc3, + 0x59, 0x9d, 0x2c, 0x44, 0x16, 0xf6, 0x68, 0xa1, 0xc6, 0x94, 0x55, 0x39, 0x15, 0x4f, 0x88, 0xf3, + 0x0a, 0x49, 0xab, 0x12, 0xc8, 0xb9, 0xfb, 0xcb, 0x35, 0x30, 0x1e, 0xda, 0xd6, 0x7f, 0x45, 0x2b, + 0xb9, 0xd4, 0x04, 0x4a, 0xe1, 0xa9, 0xad, 0x2d, 0x14, 0x92, 0x7d, 0x3e, 0x9e, 0x50, 0x3a, 0x97, + 0xf1, 0xee, 0xc3, 0xe1, 0x2b, 0x68, 0x97, 0x46, 0x32, 0xf3, 0xee, 0xb3, 0x53, 0x7b, 0x28, 0x0a, + 0xe2, 0x3a, 0x9c, 0x79, 0x86, 0x48, 0x05, 0x6e, 0xeb, 0xbf, 0x55, 0xd9, 0x3c, 0xc0, 0x71, 0x44, + 0xf1, 0xd2, 0x15, 0xe9, 0x5d, 0xbe, 0x12, 0x93, 0xca, 0x11, 0xf5, 0xf8, 0xfc, 0x29, 0x6d, 0x11, + 0x42, 0x21, 0x67, 0xea, 0xa4, 0x1b, 0x8b, 0xec, 0x43, 0xbd, 0x40, 0xb8, 0x4c, 0xf9, 0x50, 0xa0, + 0xe6, 0xad, 0xe1, 0x5f, 0x76, 0xa7, 0x53, 0xf1, 0x22, 0xc9, 0x88, 0xd2, 0xbf, 0x68, 0x7a, 0x47, + 0x62, 0x7c, 0x3e, 0xda, 0x97, 0x13, 0x45, 0x15, 0x90, 0xd1, 0x92, 0xd9, 0x54, 0x74, 0xdf, 0x0e, + 0x44, 0xa6, 0xc7, 0x4d, 0x4b, 0x79, 0x0a, 0x52, 0xbd, 0xbe, 0x5e, 0xb9, 0xd8, 0x5e, 0x71, 0x5f, + 0xe9, 0x10, 0x1d, 0x0e, 0x39, 0xdb, 0x73, 0xcb, 0xde, 0x58, 0x10, 0xd7, 0x69, 0x33, 0x33, 0x8e, + 0xbd, 0x85, 0xff, 0x5d, 0x3f, 0x8d, 0x66, 0x99, 0x10, 0xb8, 0x78, 0x8a, 0x8b, 0x43, 0xb8, 0x32, + 0x7f, 0x53, 0x77, 0x03, 0xf5, 0x6a, 0x33, 0xe3, 0x25, 0xd1, 0xe7, 0xeb, 0xe8, 0xc4, 0x46, 0x35, + 0xd4, 0x39, 0x88, 0xeb, 0xaf, 0xa9, 0x6f, 0x73, 0x56, 0x70, 0xcf, 0xcc, 0xcd, 0xaf, 0xf7, 0x97, + 0x36, 0x22, 0x55, 0x85, 0xcf, 0x50, 0xf1, 0xd2, 0xf9, 0xde, 0x24, 0x6e, 0xcb, 0x01, 0x0a, 0x6d, + 0x3d, 0x6c, 0xd1, 0xa2, 0x40, 0xb4, 0x7a, 0xc2, 0x7b, 0x7d, 0x88, 0x6f, 0xc2, 0xdb, 0xba, 0x2f, + 0x6d, 0x8b, 0x28, 0xe7, 0xd4, 0x55, 0x88, 0x3c, 0x5b, 0x9d, 0xf6, 0xca, 0x77, 0xdf, 0x58, 0x46, + 0x54, 0x92, 0x49, 0x38, 0x87, 0x3f, 0xdd, 0xd3, 0x8f, 0x17, 0x0a, 0x9f, 0x20, 0x62, 0x88, 0x55, + 0x73, 0xd4, 0xeb, 0x20, 0x4b, 0x3e, 0x61, 0x59, 0xd3, 0xf6, 0x34, 0x52, 0x5c, 0x62, 0x03, 0x19, + 0xd3, 0x8d, 0x16, 0xe8, 0x30, 0xbc, 0xd2, 0xfd, 0x8a, 0x45, 0xef, 0x7f, 0x52, 0x18, 0x98, 0xbb, + 0x0e, 0x2c, 0xea, 0x8a, 0x3e, 0xb8, 0xe7, 0x57, 0x2e, 0x26, 0x85, 0xb9, 0x50, 0x82, 0xff, 0x01, + 0x5e, 0x11, 0xb5, 0x68, 0x01, 0xdb, 0xa9, 0xba, 0xaa, 0x6a, 0x47, 0x3f, 0xef, 0xa8, 0x54, 0xc3, + 0x58, 0xe9, 0xf8, 0xef, 0xb8, 0x2d, 0x9a, 0x6a, 0xa7, 0x41, 0x90, 0x70, 0x18, 0xcf, 0x00, 0x13, + 0xcd, 0xfb, 0xf9, 0xd3, 0xf0, 0x8f, 0x5c, 0x70, 0x1f, 0x1b, 0xf5, 0xd1, 0x50, 0x4f, 0x29, 0xb0, + 0xd0, 0x81, 0x39, 0x19, 0x31, 0xb6, 0xa3, 0x96, 0x7c, 0xd0, 0xb4, 0x7c, 0x6e, 0x32, 0x8e, 0x94, + 0x69, 0x82, 0x3d, 0x5e, 0x4b, 0x5f, 0x47, 0x76, 0x9b, 0x29, 0x47, 0x39, 0xb8, 0x6f, 0xa3, 0xd7, + 0x3e, 0x78, 0x65, 0x45, 0x19, 0xe5, 0x27, 0x7b, 0x4c, 0x8d, 0x7e, 0x03, 0x70, 0x7d, 0x0a, 0xe7, + 0xfb, 0x60, 0x5a, 0x48, 0xb4, 0x18, 0xd4, 0xfd, 0x1c, 0xc8, 0x14, 0x7d, 0x3a, 0x64, 0x5e, 0x7b, + 0x5d, 0x2d, 0xb1, 0x54, 0x90, 0xba, 0x56, 0x30, 0xfb, 0x70, 0x82, 0x2b, 0xd1, 0x8f, 0x6e, 0xab, + 0x02, 0x46, 0x24, 0x23, 0x4f, 0x7e, 0x21, 0x7a, 0x3b, 0xaf, 0x6d, 0x1e, 0xb3, 0x8e, 0xf0, 0xab, + 0xfe, 0x91, 0x3b, 0xf7, 0x8c, 0x30, 0x75, 0x3f, 0x25, 0xc3, 0x0c, 0x68, 0xac, 0x3e, 0x33, 0xc8, + 0x43, 0xb0, 0xb5, 0x16, 0x22, 0xb9, 0x95, 0xab, 0x1a, 0xd6, 0xb8, 0x6d, 0x17, 0x85, 0xaf, 0x34, + 0x2f, 0x25, 0x37, 0xc0, 0x44, 0x51, 0x0e, 0xb8, 0x6c, 0xd5, 0x57, 0x40, 0x39, 0xcd, 0x6c, 0x08, + 0x44, 0xa1, 0x00, 0xfe, 0x85, 0x65, 0x02, 0xb4, 0x7e, 0x54, 0x47, 0x53, 0xa7, 0x0b, 0x76, 0xa8, + 0x3f, 0x33, 0x15, 0x99, 0xdc, 0xf4, 0xff, 0x35, 0x2a, 0x8d, 0x3e, 0x70, 0xa1, 0x62, 0x4e, 0xad, + 0xd5, 0x1d, 0xf7, 0x54, 0x41, 0xc1, 0x28, 0x50, 0x8a, 0x36, 0x15, 0x17, 0x0e, 0xd1, 0xe7, 0x3f, + 0x10, 0x6e, 0x21, 0xf7, 0xe2, 0x81, 0x9e, 0x8b, 0x9a, 0x9f, 0x0d, 0x2d, 0xf8, 0x4e, 0xda, 0xac, + 0x92, 0xe5, 0xa9, 0x5c, 0xd4, 0x50, 0x89, 0x31, 0xd2, 0x52, 0xf6, 0x05, 0xca, 0x4d, 0xf1, 0xe7, + 0xc6, 0x8d, 0x51, 0xd3, 0x2c, 0x53, 0x51, 0x61, 0x36, 0xaf, 0x0b, 0x0c, 0x9e, 0x9c, 0xcf, 0xb3, + 0xc6, 0xf5, 0x76, 0x4d, 0xf6, 0x99, 0x56, 0x56, 0xac, 0x25, 0x9c, 0x89, 0xad, 0x8e, 0xdb, 0xcf, + 0x73, 0x0f, 0x1b, 0xd1, 0x2c, 0xb0, 0xf0, 0xe0, 0x1d, 0xae, 0x10, 0x20, 0x6d, 0x7f, 0xd9, 0x3f, + 0x73, 0x30, 0xb4, 0xd1, 0x80, 0xdf, 0x1c, 0x8a, 0xe7, 0x3c, 0xd7, 0x89, 0x7b, 0x2e, 0x6c, 0x3b, + 0x23, 0x1d, 0x71, 0x81, 0x77, 0x3f, 0x69, 0xd4, 0x14, 0x73, 0x90, 0x56, 0xee, 0x9c, 0x08, 0x55, + 0xc8, 0x45, 0x09, 0xc7, 0x1d, 0x44, 0x53, 0x8c, 0x62, 0xc1, 0xb8, 0x17, 0x01, 0xa3, 0xec, 0xa7, + 0x59, 0xae, 0x4e, 0x9f, 0xa8, 0x73, 0x23, 0x01, 0x6c, 0x32, 0xc0, 0xc5, 0x26, 0xe9, 0xa5, 0x75, + 0xd5, 0x3a, 0x62, 0x93, 0x26, 0x26, 0x80, 0xcb, 0x92, 0x5c, 0xe2, 0x1f, 0x8b, 0xb5, 0x39, 0x8f, + 0xe9, 0xd5, 0x96, 0x5a, 0xc5, 0xa3, 0x8e, 0x03, 0xee, 0xb5, 0x92, 0x9b, 0x9d, 0x3e, 0xdf, 0xab, + 0x0c, 0xa2, 0x25, 0x81, 0x7d, 0x8a, 0x27, 0xff, 0x37, 0x74, 0xca, 0xa6, 0x98, 0xb4, 0x5c, 0x13, + 0x0f, 0x25, 0xfc, 0x37, 0x94, 0xf5, 0xdd, 0xce, 0xfd, 0x36, 0x02, 0xab, 0xc9, 0x3d, 0x54, 0x8d, + 0x65, 0x3c, 0xb5, 0xe7, 0x28, 0xcd, 0x54, 0x69, 0xd0, 0xec, 0x54, 0xbf, 0x09, 0xdb, 0x32, 0x10, + 0xba, 0x8c, 0x70, 0x48, 0x7b, 0x77, 0x97, 0x77, 0x14, 0xc6, 0xe4, 0x57, 0x67, 0x56, 0x66, 0x6c, + 0xda, 0xbc, 0x2d, 0x3b, 0x28, 0x14, 0xc1, 0x25, 0x27, 0x5c, 0x6f, 0x5f, 0x9d, 0xbb, 0xd1, 0xdb, + 0x2f, 0x62, 0xbe, 0x86, 0xeb, 0x5f, 0xcb, 0xa5, 0xb4, 0x1a, 0x57, 0x4a, 0xbd, 0xca, 0xba, 0xc3, + 0xc1, 0xb4, 0x50, 0x41, 0xec, 0x2a, 0xa1, 0x79, 0x54, 0xd3, 0x52, 0x53, 0x94, 0x33, 0x28, 0x79, + 0x90, 0xec, 0x76, 0x71, 0x3d, 0x0e, 0xb9, 0xb3, 0x19, 0x8e, 0x28, 0xc0, 0x0f, 0x09, 0x14, 0x6d, + 0xb2, 0x10, 0xfa, 0xda, 0x02, 0x1a, 0x59, 0xfc, 0xa3, 0xdf, 0x8c, 0x5b, 0x70, 0x50, 0x30, 0x2c, + 0x25, 0x88, 0x6a, 0xe1, 0x40, 0xd3, 0x38, 0xa9, 0xee, 0xa9, 0xb3, 0xc8, 0x6b, 0xb5, 0xae, 0x12, + 0xb9, 0x1b, 0x35, 0x17, 0x0d, 0x76, 0x62, 0xa5, 0x0d, 0x69, 0xe1, 0x9e, 0x38, 0x67, 0x7c, 0xa5, + 0x0b, 0x3b, 0xe5, 0xac, 0xa6, 0x63, 0xfc, 0xa3, 0xa5, 0x5e, 0xb8, 0x46, 0xc1, 0x9f, 0xac, 0x6a, + 0xc5, 0x35, 0x5f, 0xc6, 0x20, 0x56, 0x22, 0x94, 0xf9, 0x18, 0xaf, 0xa2, 0xaa, 0x19, 0xe2, 0x97, + 0x6c, 0xa4, 0x60, 0x21, 0x5d, 0xfb, 0x92, 0x78, 0xd5, 0x1d, 0x7c, 0x07, 0x88, 0x6d, 0xf9, 0x52, + 0x2a, 0xc3, 0x77, 0x21, 0x8b, 0xf9, 0x74, 0xdb, 0x6c, 0xfb, 0x90, 0x69, 0xd1, 0x6e, 0x54, 0x85, + 0xe2, 0xca, 0xd5, 0x5b, 0xb5, 0x12, 0x1b, 0x7e, 0xe6, 0x42, 0xaf, 0x3b, 0x2d, 0x08, 0xe5, 0xd3, + 0x92, 0x1c, 0xe5, 0x20, 0xd8, 0x6f, 0x17, 0xbe, 0xb2, 0x1f, 0xef, 0xf9, 0xb2, 0x88, 0x7d, 0x3a, + 0xa0, 0x16, 0x59, 0x5c, 0x04, 0x43, 0x35, 0x18, 0x35, 0xfe, 0xba, 0x0a, 0x17, 0xa5, 0x89, 0x6d, + 0xba, 0xee, 0xd9, 0x97, 0x19, 0x4c, 0xc6, 0x1b, 0x9c, 0xfc, 0x1d, 0x95, 0x0f, 0xa0, 0x57, 0xa2, + 0x76, 0xf6, 0x7c, 0x52, 0xd3, 0xda, 0x15, 0x88, 0x91, 0x3e, 0x41, 0x9f, 0x5d, 0x9e, 0x71, 0xa0, + 0x61, 0x99, 0x36, 0x82, 0x65, 0xa7, 0x9c, 0xc8, 0xa1, 0xd4, 0x4a, 0x9c, 0x84, 0x0a, 0xd6, 0xfd, + 0xd2, 0xac, 0xb8, 0x02, 0x80, 0x63, 0xba, 0x45, 0x84, 0x94, 0x31, 0xbd, 0xff, 0x26, 0xbf, 0x9b, + 0x67, 0xa9, 0x61, 0x50, 0xb9, 0x09, 0x97, 0x08, 0x54, 0x0f, 0xcf, 0xc6, 0xb0, 0xd4, 0x76, 0x2f, + 0x3e, 0x87, 0x78, 0x84, 0x15, 0x00, 0xf9, 0x94, 0xbe, 0x6e, 0x2b, 0xaf, 0xc8, 0xdd, 0x79, 0x08, + 0x31, 0x5c, 0xee, 0xd8, 0x75, 0xcf, 0xb3, 0xdc, 0xcd, 0x2f, 0x84, 0x88, 0x3f, 0x15, 0x87, 0xd9, + 0x3f, 0x81, 0x17, 0xbf, 0x4a, 0xbb, 0x2a, 0xa8, 0xa2, 0xb4, 0x97, 0xae, 0xd1, 0xa4, 0xc6, 0xdd, + 0x6b, 0x40, 0x3c, 0xff, 0xd5, 0xec, 0x12, 0x36, 0xfc, 0xb4, 0xc3, 0xbb, 0xdc, 0xb5, 0xe6, 0xa1, + 0x2d, 0x42, 0x77, 0x43, 0xf9, 0xe7, 0x51, 0x01, 0x2c, 0x80, 0xa5, 0xc5, 0xbe, 0xec, 0xa2, 0x43, + 0x96, 0xc7, 0x6c, 0x33, 0xed, 0x83, 0x48, 0x8b, 0x10, 0x7d, 0xea, 0x90, 0x90, 0x05, 0xa2, 0x25, + 0x6f, 0xaf, 0xd5, 0x04, 0x78, 0x59, 0x50, 0x0d, 0xd6, 0xcd, 0x4a, 0x73, 0xa3, 0x37, 0x85, 0xa0, + 0x8d, 0x24, 0xf7, 0x7c, 0xb7, 0x2f, 0x0f, 0x55, 0xd3, 0xc9, 0xd9, 0x08, 0xc4, 0x93, 0x55, 0x90, + 0x7a, 0xe6, 0x21, 0x14, 0xa9, 0x5e, 0x66, 0x80, 0xd3, 0x41, 0x6e, 0x2e, 0x7e, 0xaf, 0xcd, 0x2d, + 0xaa, 0xee, 0xc1, 0xef, 0xba, 0x38, 0x39, 0x70, 0x06, 0xff, 0x1a, 0x57, 0x0c, 0x6e, 0x38, 0x25, + 0xa6, 0x90, 0x70, 0xb4, 0xfc, 0xef, 0xcb, 0xc1, 0x69, 0x9e, 0x62, 0x39, 0xe5, 0x1f, 0x44, 0xc4, + 0xa9, 0x93, 0xbf, 0xde, 0x46, 0x8d, 0x70, 0x6f, 0x01, 0x9c, 0x49, 0xdb, 0xba, 0xd3, 0x25, 0x1c, + 0xb0, 0x10, 0xb9, 0x9f, 0x88, 0x80, 0xc9, 0x40, 0x66, 0x9d, 0x99, 0x8c, 0xad, 0x55, 0x24, 0x06, + 0xd2, 0x18, 0x3c, 0xc6, 0x9a, 0x1c, 0xf5, 0xae, 0xbb, 0x51, 0x91, 0xa7, 0x82, 0x0e, 0x3c, 0x84, + 0x8e, 0x57, 0xca, 0x1d, 0x0a, 0x7d, 0xcc, 0x0c, 0x84, 0x81, 0xb3, 0x69, 0x87, 0x70, 0x9b, 0x10, + 0x21, 0xae, 0xc7, 0x1a, 0xd2, 0x35, 0x3f, 0xd5, 0xca, 0x19, 0x61, 0xab, 0x5b, 0xb9, 0x29, 0x8a, + 0xca, 0x33, 0x6e, 0xca, 0x95, 0xfe, 0x19, 0x3e, 0x52, 0xc7, 0xb7, 0xf1, 0x1e, 0xa3, 0x5b, 0x72, + 0x4b, 0xe9, 0x64, 0xf5, 0x07, 0xc2, 0x86, 0x97, 0x9e, 0x15, 0x63, 0x58, 0x02, 0x64, 0x77, 0x8c, + 0x7c, 0xa2, 0x61, 0x3b, 0x8a, 0xbd, 0x4c, 0x87, 0x14, 0x6e, 0x69, 0xab, 0xc4, 0x2b, 0x63, 0x24, + 0x1d, 0x1c, 0x06, 0x44, 0xd8, 0xf4, 0x30, 0x64, 0x25, 0x6b, 0x9e, 0xc8, 0x5d, 0x6e, 0x50, 0x81, + 0xd2, 0xc1, 0x68, 0xcc, 0xb4, 0xd2, 0x82, 0x05, 0x88, 0x77, 0x2b, 0xb8, 0xf0, 0x29, 0x3d, 0x93, + 0x00, 0x1a, 0xef, 0x97, 0x14, 0x68, 0x30, 0x43, 0x01, 0xea, 0x9c, 0x28, 0x39, 0x48, 0x43, 0x94, + 0xaa, 0x5f, 0x6a, 0x89, 0x27, 0x4d, 0x6d, 0xcb, 0x0f, 0xa8, 0xd9, 0x53, 0xdd, 0xdb, 0xf0, 0x5e, + 0xc8, 0x74, 0x02, 0xdd, 0x8b, 0x2d, 0x99, 0x25, 0x83, 0xb0, 0xfc, 0x27, 0x35, 0xe8, 0x62, 0xc2, + 0x32, 0x93, 0x23, 0x9e, 0x23, 0x25, 0x27, 0xb1, 0x38, 0x29, 0xf3, 0xe3, 0x27, 0xb7, 0x99, 0x6b, + 0x4d, 0xb2, 0xc6, 0xde, 0x00, 0xce, 0x39, 0xc5, 0x41, 0xfd, 0x2e, 0xc5, 0x83, 0xce, 0x5a, 0x68, + 0x11, 0x42, 0x6e, 0x16, 0x72, 0xba, 0xa0, 0xb8, 0x75, 0xf8, 0xe1, 0x1d, 0x30, 0x00, 0xcb, 0x4b, + 0xc7, 0x27, 0x82, 0x39, 0x06, 0xf7, 0x22, 0x4c, 0x06, 0x4a, 0x22, 0x84, 0xcb, 0xbe, 0x67, 0x71, + 0x1b, 0xc4, 0xc2, 0x98, 0x44, 0x46, 0x77, 0xd8, 0xb1, 0xc7, 0xcb, 0x57, 0xab, 0xc2, 0x1d, 0xcd, + 0xaa, 0x29, 0xa5, 0xe1, 0xb4, 0xf9, 0x81, 0xad, 0x47, 0xdb, 0x4f, 0xb5, 0x10, 0x1e, 0x91, 0x57, + 0xa2, 0x37, 0x23, 0x1f, 0xaf, 0x56, 0xd2, 0x92, 0x00, 0x70, 0x71, 0x08, 0x99, 0x7c, 0x20, 0xbd, + 0xf7, 0xd3, 0xb9, 0x0e, 0x9b, 0x3b, 0x34, 0xe1, 0xa9, 0xda, 0xe0, 0xe5, 0xde, 0x8e, 0x78, 0x5f, + 0xcb, 0x0e, 0x08, 0xf5, 0x90, 0xb2, 0x12, 0x4e, 0x7d, 0x3e, 0xb0, 0x85, 0xfc, 0xc5, 0xc6, 0x97, + 0xb2, 0x12, 0xb4, 0x93, 0x1e, 0x8d, 0x56, 0x56, 0x17, 0x76, 0x14, 0xde, 0x50, 0x6e, 0x92, 0xce, + 0xee, 0x5b, 0x9e, 0x93, 0x68, 0x8b, 0x93, 0xc5, 0x75, 0x48, 0x34, 0xb4, 0x52, 0xd6, 0xe1, 0xcf, + 0x8a, 0xc8, 0x99, 0xa8, 0x64, 0xee, 0x4d, 0xa5, 0x7c, 0x6e, 0xc1, 0x48, 0x0f, 0x19, 0x29, 0x8e, + 0x43, 0x07, 0xd7, 0xbe, 0x83, 0xb3, 0x56, 0x31, 0x4d, 0xeb, 0xc4, 0xa8, 0x0d, 0x6e, 0x93, 0xda, + 0x33, 0x85, 0x35, 0x98, 0xd4, 0xcf, 0xd3, 0x34, 0x81, 0x06, 0x5b, 0x4e, 0x2b, 0x22, 0x05, 0x43, + 0x95, 0x60, 0x83, 0x08, 0x03, 0x54, 0x5f, 0x9e, 0xdd, 0x0f, 0xd2, 0x22, 0xac, 0x6c, 0xb2, 0x28, + 0xce, 0x0c, 0x55, 0xac, 0x4c, 0xaf, 0x78, 0xf3, 0x05, 0x37, 0x58, 0x69, 0x82, 0x24, 0xaf, 0xa8, + 0x58, 0x8a, 0x2b, 0x3c, 0x72, 0xdd, 0x7a, 0x92, 0xb8, 0x20, 0x9c, 0x34, 0xf1, 0xed, 0xf1, 0x67, + 0x2e, 0x90, 0x82, 0xab, 0x84, 0x92, 0x77, 0xde, 0x78, 0xd0, 0xc0, 0x01, 0xf8, 0xf5, 0x0a, 0x0b, + 0x29, 0x00, 0xe4, 0x7b, 0x1a, 0xfd, 0x96, 0x74, 0x9f, 0x5b, 0xb5, 0x95, 0x08, 0x87, 0xb2, 0x67, + 0x64, 0x18, 0x25, 0x15, 0x27, 0xca, 0xa8, 0x9e, 0x0e, 0x13, 0xf0, 0x13, 0x56, 0x99, 0x8f, 0x73, + 0x3b, 0x0b, 0xfe, 0x4e, 0xd5, 0x64, 0x40, 0x84, 0x8f, 0x93, 0x4f, 0xde, 0x0f, 0x19, 0x3d, 0xbd, + 0x75, 0x27, 0xa1, 0xd8, 0x69, 0xc2, 0xf9, 0xfb, 0x84, 0x01, 0xec, 0x11, 0x4c, 0xb9, 0x6a, 0xa7, + 0xb9, 0xd8, 0xb4, 0x95, 0xe4, 0xfd, 0x47, 0xc4, 0x7b, 0x02, 0x6b, 0x2d, 0xc6, 0xba, 0x56, 0x7f, + 0x16, 0x25, 0x79, 0xa9, 0x81, 0x6e, 0x8e, 0x35, 0xc1, 0x6c, 0x2e, 0x05, 0xd2, 0x30, 0x20, 0xc7, + 0xcc, 0x94, 0xb0, 0xa6, 0xe7, 0x45, 0x8e, 0xe4, 0xd1, 0x68, 0xaf, 0x54, 0xb7, 0x04, 0x1e, 0x6a, + 0xfb, 0x17, 0x5d, 0x21, 0x76, 0x9a, 0xa6, 0x03, 0xb6, 0xae, 0xac, 0x55, 0xaa, 0x72, 0xca, 0x86, + 0x96, 0xf6, 0x0d, 0xc2, 0xee, 0xbe, 0x5f, 0x90, 0xef, 0xd6, 0xbb, 0x34, 0x86, 0xe2, 0xa2, 0xf9, + 0xc3, 0xdd, 0x2c, 0x03, 0xdc, 0x4f, 0x51, 0x6b, 0xa1, 0xc9, 0x48, 0xae, 0x6d, 0xb0, 0x29, 0x2c, + 0x42, 0xd7, 0x57, 0x51, 0xe8, 0xfa, 0xd2, 0xd0, 0x94, 0xdf, 0x70, 0x49, 0x48, 0xae, 0xe2, 0xf2, + 0x1f, 0xe0, 0x98, 0x61, 0x89, 0x4c, 0x22, 0x61, 0x98, 0xdc, 0x26, 0x11, 0x40, 0x49, 0x37, 0x8c, + 0x40, 0xfb, 0xf6, 0xfb, 0xf4, 0x77, 0x9e, 0x58, 0xa0, 0xfe, 0x0e, 0xaa, 0xa4, 0xb6, 0xb5, 0x45, + 0xe6, 0xfe, 0x90, 0x8f, 0x0b, 0x13, 0xd7, 0xc1, 0x54, 0x1b, 0x9d, 0x65, 0x98, 0xc1, 0x7e, 0x5c, + 0x8b, 0xa8, 0xd0, 0x5b, 0x68, 0x5e, 0x11, 0x4d, 0x8b, 0x9c, 0x88, 0x57, 0x75, 0x15, 0x07, 0x26, + 0x27, 0x2b, 0x37, 0xa4, 0x2d, 0x3e, 0x19, 0x25, 0x97, 0x91, 0xac, 0xf7, 0xdc, 0xed, 0x71, 0xf8, + 0x5d, 0x1a, 0xf3, 0x48, 0x49, 0x23, 0x32, 0x2d, 0x4c, 0x47, 0x7d, 0x0c, 0xa1, 0x7d, 0x94, 0x06, + 0x1b, 0xbf, 0x54, 0x46, 0x91, 0xde, 0x6f, 0xad, 0x81, 0x34, 0xff, 0x14, 0xac, 0x0d, 0x86, 0x87, + 0x04, 0x29, 0xce, 0xe5, 0xe6, 0x7b, 0xc9, 0x7d, 0xb0, 0xce, 0x2b, 0xe2, 0xf6, 0xca, 0xec, 0x7d, + 0x26, 0xf8, 0xb7, 0xb0, 0x01, 0xa2, 0x18, 0x37, 0xb8, 0xe5, 0xba, 0x78, 0x38, 0x33, 0x7f, 0x67, + 0xa3, 0x71, 0x03, 0x88, 0xaf, 0x33, 0x4e, 0x5b, 0xb8, 0x2f, 0xe4, 0x8a, 0x19, 0x3e, 0x5c, 0x35, + 0x67, 0x4a, 0xec, 0xea, 0x86, 0x32, 0x49, 0xea, 0xee, 0x69, 0xd2, 0xdb, 0x02, 0x15, 0x9d, 0xad, + 0x87, 0xc7, 0xf4, 0x55, 0xd8, 0x53, 0x10, 0xec, 0x36, 0x2e, 0xda, 0x89, 0xae, 0x1d, 0x7e, 0xcd, + 0x5b, 0x79, 0x5e, 0x1a, 0xfa, 0xa6, 0xd4, 0x68, 0x04, 0x4b, 0x40, 0x5a, 0x83, 0xa7, 0xb5, 0x1b, + 0x88, 0xc6, 0xcb, 0xf0, 0x80, 0x29, 0x25, 0x2d, 0xb2, 0xa3, 0x94, 0x89, 0x08, 0x46, 0x2d, 0x22, + 0x50, 0x6d, 0xa5, 0xa0, 0xde, 0xbe, 0x68, 0xc1, 0xb0, 0xb2, 0xae, 0x0f, 0xb4, 0xdf, 0xb6, 0xd5, + 0x0c, 0x87, 0xbf, 0x02, 0x04, 0x04, 0x28, 0x56, 0xe3, 0x95, 0x9e, 0x6f, 0x92, 0xfe, 0x5e, 0x62, + 0xdc, 0xc0, 0x44, 0xcc, 0xfe, 0x76, 0xfb, 0x5f, 0x1a, 0xd6, 0x47, 0xf4, 0x20, 0xf1, 0x29, 0x21, + 0xab, 0x6e, 0x2f, 0x19, 0x93, 0xca, 0xb2, 0x66, 0xa2, 0x70, 0x63, 0xbf, 0x32, 0x9f, 0xc8, 0xae, + 0x52, 0xaa, 0x01, 0x4e, 0x55, 0x80, 0xa6, 0xfa, 0xdd, 0xb9, 0x18, 0x48, 0xa3, 0xdf, 0x8a, 0x26, + 0xf0, 0xf6, 0xdb, 0x7b, 0x4a, 0x84, 0x9a, 0x65, 0xfe, 0xd7, 0x06, 0x27, 0xca, 0xa6, 0x6d, 0x95, + 0x92, 0xc4, 0xb6, 0xdb, 0xf5, 0xf9, 0x7c, 0xd6, 0x5e, 0x11, 0xff, 0x95, 0xe7, 0x97, 0xc2, 0x5b, + 0x17, 0x1f, 0x10, 0x2d, 0x1e, 0x40, 0x92, 0x48, 0xc8, 0x6d, 0xef, 0x12, 0x02, 0x80, 0x66, 0x73, + 0xbb, 0x53, 0xe9, 0xaa, 0x91, 0xa3, 0x86, 0x6e, 0xcd, 0xdb, 0x7f, 0x97, 0x3b, 0xcf, 0x61, 0xc1, + 0x1f, 0xdb, 0xc5, 0xa3, 0x56, 0x08, 0x5c, 0x0a, 0x04, 0x11, 0x1d, 0x19, 0x49, 0x2e, 0xc5, 0x00, + 0x77, 0x76, 0x5a, 0x44, 0xea, 0x40, 0xcc, 0x86, 0xe0, 0x66, 0xef, 0x19, 0x9d, 0xd4, 0xbe, 0xa1, + 0xa6, 0xa7, 0xd8, 0x05, 0x79, 0x0c, 0x9e, 0x5c, 0x70, 0x73, 0xf4, 0x2d, 0xd0, 0xfa, 0xf4, 0x02, + 0xb7, 0xc4, 0xa0, 0xfd, 0x07, 0x6a, 0x9d, 0x0a, 0x9c, 0x98, 0xb2, 0x6e, 0x76, 0xf0, 0x5e, 0x16, + 0xaa, 0xa8, 0x36, 0x59, 0xba, 0xd7, 0x91, 0xf2, 0x02, 0x7c, 0xcf, 0x60, 0x1a, 0x79, 0x95, 0x5e, + 0x8a, 0xe2, 0x4c, 0xf0, 0x8e, 0x0d, 0x8e, 0x1c, 0xa7, 0x32, 0x66, 0x80, 0x50, 0xf1, 0xee, 0x59, + 0x9d, 0xdc, 0xd7, 0x28, 0xe3, 0xd5, 0x8b, 0xe5, 0x14, 0x23, 0x53, 0xa1, 0x04, 0x21, 0x82, 0x4b, + 0xeb, 0x05, 0x04, 0x63, 0x1a, 0xde, 0x78, 0xc1, 0xe7, 0x73, 0xee, 0xf9, 0x04, 0x11, 0x58, 0x81, + 0x8c, 0x17, 0x71, 0x43, 0x13, 0x10, 0x3a, 0x4b, 0x0b, 0x14, 0x2b, 0x27, 0x50, 0x78, 0x59, 0x9e, + 0x82, 0x4a, 0x7e, 0x1d, 0x02, 0xbf, 0x74, 0x6c, 0x20, 0x9d, 0x05, 0x17, 0x76, 0x6b, 0x94, 0x6d, + 0xdc, 0xaf, 0x91, 0xd8, 0x43, 0x85, 0x15, 0xc3, 0xac, 0x6b, 0x74, 0x41, 0x2a, 0xf8, 0xe8, 0x6f, + 0xb3, 0x61, 0xb0, 0x2e, 0x1b, 0x97, 0xdd, 0x98, 0xc7, 0x7a, 0x11, 0x7c, 0x29, 0xf4, 0x1c, 0x1e, + 0x4d, 0x1e, 0xb7, 0xbb, 0x88, 0x10, 0x15, 0x8c, 0xec, 0x1f, 0x51, 0xfe, 0x68, 0xeb, 0x79, 0x14, + 0xa3, 0xe1, 0xa0, 0x0f, 0x85, 0x1d, 0x3b, 0xb9, 0x50, 0x9d, 0x08, 0x9b, 0x58, 0x45, 0x9f, 0x04, + 0xe6, 0x2d, 0xf1, 0x13, 0x5e, 0xfb, 0xa7, 0xe1, 0x32, 0x19, 0x92, 0xc7, 0xd3, 0x42, 0xfc, 0x1b, + 0xb0, 0x2a, 0x21, 0x2d, 0xd9, 0x0b, 0xf0, 0x84, 0x5d, 0xf2, 0xc7, 0x28, 0x4a, 0x73, 0xf0, 0x6d, + 0x4d, 0xa1, 0x12, 0x4d, 0x77, 0x83, 0x80, 0xc6, 0xa4, 0x28, 0xa6, 0xe8, 0xf0, 0x78, 0x2b, 0x0e, + 0x94, 0xfe, 0x28, 0x37, 0xea, 0x1e, 0xf2, 0x9b, 0xad, 0xc7, 0x8e, 0x67, 0x65, 0x16, 0x2b, 0x33, + 0x20, 0x00, 0x3f, 0xea, 0x7e, 0x5d, 0xba, 0xed, 0x8c, 0x5a, 0xe3, 0x4c, 0xb4, 0x9f, 0x0d, 0x81, + 0xa4, 0xd4, 0xde, 0x81, 0xee, 0xfd, 0x31, 0x32, 0xc9, 0xe3, 0x26, 0xe1, 0x96, 0x42, 0x8a, 0x3d, + 0xc5, 0xa2, 0xa4, 0x79, 0x91, 0x8f, 0xab, 0x80, 0xa0, 0x7c, 0x7f, 0x37, 0xd1, 0xd2, 0x37, 0xc6, + 0x9d, 0xc9, 0x8c, 0xd5, 0xce, 0x68, 0x8c, 0x0f, 0x57, 0x7b, 0xfe, 0xf9, 0x0c, 0x03, 0x6a, 0xe9, + 0x78, 0xe4, 0x38, 0x8b, 0xba, 0x33, 0xbf, 0x72, 0xc2, 0xa8, 0x0f, 0x7d, 0xd2, 0x9b, 0x7c, 0xe1, + 0x7c, 0xd1, 0x18, 0x7c, 0x2b, 0x55, 0xef, 0x82, 0xdf, 0xcd, 0xbe, 0x8c, 0xae, 0x0b, 0x83, 0xbb, + 0x98, 0xd8, 0x46, 0xfe, 0xe1, 0x6a, 0xe9, 0x69, 0xd8, 0x06, 0x9a, 0x01, 0x8e, 0x9d, 0x3b, 0x94, + 0xc2, 0xb7, 0xd6, 0x1d, 0xcd, 0x1f, 0x15, 0x9b, 0x04, 0x4a, 0x42, 0x5a, 0xc8, 0xa1, 0x64, 0x55, + 0x39, 0x65, 0xd6, 0x78, 0x37, 0x97, 0x74, 0x0c, 0x0f, 0x94, 0x22, 0x68, 0xfd, 0xf0, 0xf9, 0x90, + 0x1c, 0x77, 0x83, 0xb2, 0x3a, 0x07, 0x1f, 0x0b, 0xee, 0xe3, 0x9c, 0x42, 0x4e, 0x93, 0x0d, 0xda, + 0x00, 0x20, 0xa6, 0x5c, 0xdf, 0x64, 0x37, 0x79, 0x77, 0x01, 0xfb, 0xc1, 0x14, 0x9a, 0x7a, 0x83, + 0xe7, 0xd1, 0x47, 0xfc, 0xd5, 0xea, 0xca, 0xbc, 0x03, 0x18, 0x7d, 0x46, 0x8d, 0xf5, 0x2d, 0xd1, + 0x34, 0x61, 0x1b, 0xcf, 0x38, 0xc7, 0x3e, 0xe5, 0x87, 0xaa, 0xc1, 0xd1, 0x07, 0x55, 0x4d, 0x4e, + 0x41, 0xa5, 0x6d, 0x48, 0xeb, 0x82, 0x54, 0x54, 0xaf, 0x0b, 0x8a, 0x73, 0x16, 0x5c, 0xe0, 0x25, + 0x7c, 0xfe, 0xe1, 0xf1, 0x45, 0xa2, 0xc2, 0x7a, 0x3a, 0x84, 0xdc, 0xc4, 0x1e, 0xda, 0x69, 0x73, + 0x08, 0xdd, 0x36, 0x29, 0xec, 0x05, 0x41, 0x86, 0x2e, 0x2f, 0xb0, 0xc1, 0xbc, 0xb5, 0x97, 0x41, + 0xb2, 0x89, 0x4f, 0x15, 0x62, 0x0e, 0x85, 0xf2, 0xf8, 0xbb, 0xa4, 0xcc, 0x30, 0x44, 0xcb, 0xa2, + 0x3b, 0x6b, 0x83, 0x24, 0x08, 0xd7, 0x02, 0x29, 0x71, 0x71, 0x64, 0x4c, 0xbb, 0x6b, 0xc8, 0xa7, + 0x52, 0xfc, 0x0f, 0x11, 0xc1, 0x9a, 0x55, 0x72, 0x2d, 0x58, 0xc4, 0x17, 0x93, 0x45, 0x4a, 0x87, + 0x20, 0xc7, 0xec, 0x4e, 0xec, 0x50, 0xfd, 0x91, 0x2d, 0xfa, 0x6c, 0x0b, 0x28, 0x89, 0x21, 0x78, + 0x98, 0x12, 0x5b, 0x1c, 0xcc, 0xaf, 0x6b, 0x44, 0x43, 0xeb, 0x0f, 0x8e, 0xb3, 0x07, 0x60, 0x1f, + 0x69, 0xde, 0x97, 0xc3, 0xfd, 0x1a, 0xaa, 0x91, 0xa1, 0xe8, 0x93, 0xa8, 0x3c, 0x7d, 0x69, 0xbd, + 0x37, 0xf3, 0xaf, 0xed, 0xc3, 0x37, 0x1f, 0x0f, 0xc4, 0xbd, 0x5b, 0x8c, 0xbd, 0x3e, 0x62, 0xfc, + 0xd9, 0x66, 0x9d, 0x4a, 0xf1, 0xe2, 0xc1, 0xc0, 0x11, 0xd3, 0xa6, 0x48, 0x34, 0xc2, 0x34, 0xd8, + 0xad, 0xd1, 0x61, 0xd9, 0xfa, 0x9a, 0xac, 0xe2, 0xe5, 0x18, 0x4e, 0xb1, 0x19, 0xf1, 0x31, 0x6b, + 0xe1, 0xa5, 0x8d, 0x5f, 0x3a, 0x24, 0x50, 0x48, 0x86, 0xb8, 0x12, 0x54, 0xec, 0x76, 0x79, 0x08, + 0x6f, 0xbe, 0xfe, 0xa9, 0xe0, 0xb4, 0x59, 0x58, 0x99, 0x64, 0xbd, 0x16, 0xa5, 0x59, 0xca, 0x16, + 0x2f, 0x5d, 0xc3, 0xa0, 0x13, 0x66, 0xfc, 0xb1, 0x78, 0x6a, 0x6e, 0x7d, 0xb3, 0xec, 0x15, 0xb2, + 0xc1, 0x64, 0xa4, 0x20, 0xb0, 0x97, 0x20, 0x0e, 0x37, 0x5b, 0x4d, 0xfc, 0x0e, 0x1d, 0x2c, 0xff, + 0x09, 0x7f, 0x56, 0xae, 0x0c, 0xe1, 0xa0, 0xf0, 0x80, 0xf2, 0x43, 0x5e, 0x82, 0x63, 0x4e, 0x69, + 0xfb, 0x03, 0xbc, 0x9a, 0xcf, 0x0e, 0xbd, 0x95, 0xa6, 0x43, 0xa6, 0xf3, 0xd9, 0x64, 0xa9, 0x47, + 0x3a, 0x4a, 0xbf, 0x13, 0xc4, 0x2b, 0x61, 0x93, 0xaa, 0xc7, 0x5f, 0xc4, 0x65, 0x90, 0xba, 0xb4, + 0x74, 0x33, 0x88, 0xcf, 0xa1, 0xb5, 0xaf, 0x84, 0x87, 0x50, 0x7d, 0x68, 0x4b, 0x76, 0x3f, 0xf6, + 0x8a, 0xef, 0xe0, 0xcb, 0x86, 0x51, 0x93, 0x95, 0x75, 0x61, 0x45, 0xab, 0xfd, 0xd0, 0x64, 0x68, + 0x26, 0x33, 0x2a, 0xbe, 0x2a, 0xf3, 0x1c, 0x98, 0x60, 0xc1, 0xa8, 0x47, 0x14, 0x3b, 0x9f, 0xa3, + 0x77, 0x32, 0x87, 0x6d, 0x14, 0x7c, 0xd3, 0xaa, 0x60, 0xfa, 0xa6, 0xea, 0xa0, 0x99, 0x15, 0x12, + 0xa8, 0x34, 0x52, 0xfb, 0x2a, 0x45, 0x1a, 0x5e, 0x0a, 0xf2, 0xd5, 0xb0, 0xf4, 0xf8, 0x5c, 0x42, + 0x3f, 0x9b, 0x21, 0xf5, 0x41, 0xd9, 0x23, 0xc9, 0xd8, 0x90, 0xee, 0x9f, 0x0f, 0x8a, 0x7f, 0xb3, + 0x84, 0x8d, 0x00, 0x87, 0x3b, 0x99, 0xe0, 0xc2, 0x04, 0x07, 0xe6, 0xae, 0x75, 0x29, 0x43, 0xe5, + 0x4d, 0x7c, 0x0c, 0x72, 0x19, 0x15, 0xaf, 0x92, 0x3b, 0xea, 0x78, 0xfb, 0x57, 0xee, 0xa3, 0x50, + 0x0c, 0x1d, 0x1e, 0xf8, 0x06, 0x7e, 0xb5, 0x23, 0x43, 0x6a, 0x58, 0xea, 0x96, 0x36, 0x63, 0x47, + 0xee, 0x5f, 0x2c, 0x1c, 0x4b, 0xfd, 0x89, 0x49, 0x81, 0x67, 0x72, 0xde, 0xdb, 0xa3, 0xda, 0xed, + 0xf3, 0xea, 0x6b, 0x6e, 0x20, 0x09, 0x12, 0xa2, 0x38, 0x3b, 0x66, 0x07, 0x09, 0x75, 0xca, 0x6a, + 0x1b, 0xfc, 0x16, 0xf1, 0xe8, 0x67, 0xa1, 0xa1, 0x13, 0xe4, 0x14, 0x6e, 0xc0, 0xde, 0x2a, 0x15, + 0x97, 0xad, 0xe4, 0x34, 0x8e, 0x77, 0x78, 0x17, 0xe8, 0xa6, 0x6a, 0x91, 0x89, 0x68, 0x91, 0xd9, + 0xbc, 0x6f, 0xee, 0xe9, 0xe6, 0x9e, 0x31, 0xe7, 0x24, 0xe9, 0x14, 0x67, 0x34, 0xc9, 0xa6, 0xed, + 0x52, 0x78, 0x19, 0xe7, 0xbd, 0x4d, 0x6a, 0x27, 0xa9, 0xc2, 0x65, 0xbb, 0x9e, 0x48, 0x02, 0xf3, + 0x21, 0xae, 0xaf, 0x4b, 0xa9, 0x0b, 0x27, 0x05, 0x31, 0xb8, 0xcd, 0x0d, 0x6c, 0x29, 0xbb, 0xec, + 0x0b, 0x4d, 0x0f, 0xc9, 0x41, 0x70, 0xf7, 0xab, 0x04, 0x62, 0xee, 0xd4, 0xcd, 0x75, 0x91, 0x8e, + 0x13, 0xcf, 0x60, 0x57, 0x71, 0xe1, 0x8f, 0x98, 0x30, 0x34, 0x47, 0xd0, 0x15, 0x6f, 0x83, 0xfd, + 0xdb, 0x4c, 0xcf, 0x3f, 0xa8, 0x65, 0xce, 0xba, 0xe0, 0xfb, 0x95, 0xb5, 0x19, 0xad, 0x6a, 0x0e, + 0x5c, 0x83, 0x6f, 0x4e, 0x0a, 0xd2, 0xcd, 0xee, 0xee, 0x0c, 0x32, 0xa5, 0x91, 0x86, 0x51, 0x15, + 0xe5, 0xb6, 0x8e, 0xc4, 0x56, 0xa4, 0x79, 0x1e, 0x9f, 0x39, 0xa4, 0xd9, 0x85, 0xcf, 0xed, 0x2b, + 0x05, 0xab, 0x66, 0x74, 0xde, 0xd7, 0x07, 0xc4, 0x8a, 0x5a, 0xea, 0xf2, 0x96, 0xf2, 0x3c, 0x52, + 0x2e, 0x7c, 0x7e, 0x81, 0xb7, 0xe8, 0x06, 0x18, 0x40, 0x2b, 0xa8, 0xfc, 0x3e, 0x5a, 0xda, 0xb7, + 0xa0, 0x20, 0x3c, 0x34, 0xca, 0x25, 0xb8, 0x4b, 0x5f, 0x16, 0x41, 0x38, 0x75, 0x64, 0x3a, 0xe0, + 0x75, 0xcb, 0x7e, 0x59, 0xf2, 0x8e, 0xb8, 0x48, 0x08, 0x8d, 0x48, 0x9f, 0xaf, 0x58, 0xbb, 0x38, + 0x6b, 0x02, 0x30, 0x3e, 0x37, 0xc3, 0x1c, 0xa3, 0xea, 0x45, 0xab, 0xf9, 0x58, 0x95, 0x7d, 0x63, + 0x56, 0x55, 0x12, 0x2a, 0xf5, 0x04, 0x96, 0x88, 0xa0, 0x53, 0xa4, 0xee, 0x26, 0xfc, 0x44, 0x9e, + 0xb8, 0xee, 0xf1, 0x81, 0xa3, 0x9b, 0x47, 0x0d, 0xb3, 0xe0, 0x49, 0x58, 0x61, 0x8f, 0xbf, 0xc2, + 0xc7, 0x34, 0x42, 0x1e, 0x94, 0x4b, 0xe6, 0x41, 0x35, 0x2e, 0x75, 0x5a, 0x6d, 0xc8, 0x42, 0x1c, + 0x41, 0x65, 0xaa, 0x6e, 0x41, 0x81, 0x1a, 0x08, 0x42, 0xdf, 0x89, 0xec, 0x7e, 0x88, 0x8c, 0xb2, + 0xab, 0xd5, 0x91, 0xdb, 0xde, 0xd3, 0xa4, 0x64, 0xd6, 0x5f, 0x4b, 0x05, 0xc5, 0x15, 0xf5, 0x96, + 0xe6, 0x96, 0xd2, 0xd6, 0x8b, 0xec, 0xd7, 0xaa, 0x0e, 0x62, 0x04, 0x7f, 0xc1, 0x97, 0x48, 0x85, + 0xbb, 0x8b, 0x62, 0x04, 0x97, 0x98, 0xfa, 0x15, 0x99, 0x6a, 0xf6, 0x4d, 0xb6, 0x1c, 0xb8, 0xde, + 0x59, 0x94, 0xee, 0x36, 0x16, 0x8b, 0x44, 0x29, 0x53, 0x35, 0xb1, 0xc1, 0x41, 0x25, 0x45, 0xe3, + 0x7a, 0xbc, 0x6b, 0xf6, 0xea, 0xab, 0x3d, 0xe0, 0xf8, 0xac, 0x40, 0x92, 0xfd, 0xf5, 0xc8, 0xb1, + 0xba, 0xb5, 0x98, 0x62, 0xc8, 0xf4, 0x6c, 0xa4, 0x81, 0xdb, 0x9d, 0xdc, 0x12, 0x4e, 0x23, 0x18, + 0x91, 0xbe, 0x51, 0x34, 0xd4, 0x4d, 0x68, 0xf8, 0xda, 0x5d, 0x75, 0xd2, 0x48, 0xff, 0x33, 0x52, + 0xf2, 0xc5, 0xba, 0xdb, 0x8e, 0x77, 0x12, 0x03, 0xc6, 0x3c, 0x2b, 0xd4, 0x45, 0xcc, 0x4f, 0xf2, + 0x8a, 0xb7, 0xac, 0x66, 0x1e, 0x11, 0xa9, 0x0c, 0x32, 0xed, 0x18, 0x09, 0x30, 0x9e, 0x55, 0x02, + 0xc8, 0x14, 0xcd, 0x5f, 0x80, 0xc4, 0x72, 0xe9, 0x94, 0x33, 0xaa, 0x89, 0x43, 0x5d, 0x86, 0x5a, + 0xe5, 0xe1, 0xdf, 0x1d, 0xb5, 0x18, 0x4b, 0x94, 0xf2, 0xf0, 0xa8, 0x2d, 0xb8, 0x6b, 0xed, 0xc7, + 0x4e, 0x7a, 0x97, 0xe6, 0xf4, 0xbb, 0xbd, 0x54, 0x89, 0x73, 0xdc, 0x2a, 0xdc, 0xaf, 0xca, 0x54, + 0x4b, 0xfb, 0x8c, 0x31, 0x4f, 0xc1, 0x17, 0x02, 0x24, 0xc0, 0x38, 0x91, 0xd5, 0x3e, 0x83, 0x75, + 0xda, 0x46, 0xc0, 0x76, 0xd1, 0xa9, 0x7e, 0xed, 0x4a, 0xf4, 0x4c, 0xf3, 0x19, 0x37, 0x4d, 0x62, + 0x0e, 0x20, 0x61, 0x1f, 0x07, 0xdc, 0xf2, 0x17, 0xa2, 0xb6, 0x39, 0x6d, 0x9f, 0x53, 0x2b, 0x0a, + 0xe2, 0x4f, 0x79, 0xed, 0x24, 0xf8, 0x01, 0x1c, 0xbc, 0xd7, 0x1e, 0xcb, 0x8d, 0x27, 0xf1, 0x83, + 0x67, 0xe6, 0xcc, 0xbd, 0xc2, 0x37, 0x9a, 0x52, 0x9e, 0xae, 0x61, 0x10, 0x6a, 0xe4, 0x87, 0x80, + 0x5f, 0xa7, 0x47, 0xbb, 0x5a, 0xc6, 0x5d, 0xdc, 0x9c, 0x0d, 0xfa, 0x73, 0x37, 0x82, 0x3e, 0x32, + 0xff, 0xe6, 0x07, 0x51, 0x8d, 0x2d, 0xbd, 0x46, 0x59, 0x21, 0x0f, 0x4e, 0x8b, 0x96, 0x06, 0x52, + 0x82, 0x51, 0x98, 0x0e, 0x5b, 0x15, 0xcf, 0xdc, 0x90, 0xc8, 0xd6, 0x10, 0xda, 0xd3, 0xde, 0x97, + 0x6d, 0x78, 0x68, 0xf6, 0x40, 0x29, 0x2b, 0xb2, 0xd2, 0x17, 0x42, 0x1e, 0x9e, 0x50, 0x0d, 0x13, + 0xd6, 0x22, 0x23, 0xe4, 0x39, 0x16, 0x76, 0x75, 0xc2, 0x9c, 0x1b, 0xe9, 0x3d, 0x68, 0x13, 0x0a, + 0x09, 0x38, 0x47, 0x54, 0x5c, 0x90, 0x98, 0xa0, 0x27, 0x37, 0x3d, 0x68, 0x6f, 0x8f, 0xcc, 0xcf, + 0x41, 0x73, 0x7a, 0x94, 0xb0, 0xe1, 0x25, 0x2c, 0x30, 0x3a, 0x43, 0x98, 0xb6, 0xc4, 0xe4, 0xf4, + 0xf6, 0x17, 0x49, 0x64, 0xa2, 0xaf, 0xb3, 0xf9, 0x01, 0x1a, 0x1d, 0x2c, 0x84, 0xa8, 0xaa, 0xab, + 0xc8, 0xf8, 0x02, 0x0e, 0x5d, 0x72, 0x78, 0x91, 0xaa, 0xc4, 0x08, 0x1c, 0x40, 0x46, 0x48, 0x90, + 0x92, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x16, 0x21, 0x28, + 0x32, 0x3a, 0x42, 0xd3, 0xc2, 0xa6, 0x15, 0x3c, 0x57, 0x0a, 0xef, 0x06, 0xba, 0x22, 0x9d, 0x76, + 0x1d, 0x73, 0x90, 0xc4, 0x68, 0xb0, 0xeb, 0xfe, 0x2a, 0xbd, 0xc5, 0x75, 0x19, 0xb9, 0xf0, 0xd0, + 0xc8, 0x05, 0x37, 0x4b, 0x8c, 0xea, 0x5d, 0xbc, 0xeb, 0x6c, 0xdb, 0xda, 0xea, 0xe2, 0xca, 0x65, + 0x74, 0x87, 0x26, 0x44, 0x91, 0x09, 0x40, 0x87, 0x1c, 0x35, 0x07, 0x80, 0xb5, 0xec, 0x9e, 0x12, + 0xc3, 0xd0, 0x59, 0x53, 0xe9, 0x7e, 0x61, 0x88, 0x9f, 0x35, 0x6c, 0x1b, 0x36, 0x25, 0xbc, 0x0a, + 0xda, 0x3d, 0xa1, 0x72, 0xe2, 0xa2, 0xb7, 0x70, 0xc7, 0xb0, 0xd1, 0xd3, 0xfe, 0xf5, 0x22, 0x10, + 0xde, 0x15, 0x26, 0xe3, 0xae, 0x82, 0x5c, 0xd6, 0xea, 0x15, 0x95, 0x2c, 0x67, 0x7b, 0x05, 0x55, + 0xd4, 0xb2, 0xc7, 0x38, 0x00 +}; + +#define COMPOSITE_SIG_GEN_ITEM(alg, name) { \ + alg, \ + name##_priv, sizeof(name##_priv), \ + name##_msg, sizeof(name##_msg), \ + name##_sig_digest, sizeof(name##_sig_digest), \ + name##_add_random, sizeof(name##_add_random), \ +} + +typedef struct composite_sig_gen_test_data_st { + const char *alg; + const unsigned char *priv; + size_t priv_len; + const unsigned char *msg; + size_t msg_len; + /* SHA-256 of signature (compact regression check) */ + const unsigned char *sig_digest; + size_t sig_digest_len; + const unsigned char *add_random; /* fixed ML-DSA entropy */ + size_t add_random_len; +} COMPOSITE_SIG_GEN_TEST_DATA; + +#define COMPOSITE_SIGGEN_TESTDATA_COUNT 6 + +static COMPOSITE_SIG_GEN_TEST_DATA composite_siggen_testdata[] = { + COMPOSITE_SIG_GEN_ITEM("ML-DSA-44-RSA2048-PKCS15-SHA256", composite44_rsa2048pkcs15), + COMPOSITE_SIG_GEN_ITEM("ML-DSA-44-Ed25519-SHA512", composite44_ed25519), + COMPOSITE_SIG_GEN_ITEM("ML-DSA-65-RSA3072-PKCS15-SHA512", composite65_rsa3072pkcs15), + COMPOSITE_SIG_GEN_ITEM("ML-DSA-65-RSA4096-PKCS15-SHA512", composite65_rsa4096pkcs15), + COMPOSITE_SIG_GEN_ITEM("ML-DSA-65-Ed25519-SHA512", composite65_ed25519), + COMPOSITE_SIG_GEN_ITEM("ML-DSA-87-Ed448-SHAKE256", composite87_ed448), +}; + +typedef struct composite_sig_ver_test_data_st { + const char *alg; + const unsigned char *pub; + size_t pub_len; + const unsigned char *msg; + size_t msg_len; + const unsigned char *sig; + size_t sig_len; + int expected; +} COMPOSITE_SIG_VER_TEST_DATA; + +#define COMPOSITE_SIGVER_TESTDATA_COUNT 0 diff --git a/test/composite_sig_test.c b/test/composite_sig_test.c new file mode 100644 index 0000000000000..7292fd651eba2 --- /dev/null +++ b/test/composite_sig_test.c @@ -0,0 +1,819 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include "testutil.h" +#include "composite_sig.inc" + +typedef enum OPTION_choice { + OPT_ERR = -1, + OPT_EOF = 0, + OPT_CONFIG_FILE, + OPT_TEST_ENUM +} OPTION_CHOICE; + +static OSSL_LIB_CTX *lib_ctx = NULL; +static OSSL_PROVIDER *null_prov = NULL; +static OSSL_PROVIDER *lib_prov = NULL; + +/* ========================================================================= + * Key helpers + * ========================================================================= */ + +/* + * Generate a composite keypair using DRBG (no fixed seed). + * The algorithm name must be one of the 18 composite names, e.g. + * "ML-DSA-44-RSA2048-PSS-SHA256". + */ +static EVP_PKEY *do_gen_key(const char *alg) +{ + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + + if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(lib_ctx, alg, NULL)) + || !TEST_int_eq(EVP_PKEY_keygen_init(ctx), 1) + || !TEST_int_eq(EVP_PKEY_generate(ctx, &pkey), 1)) + pkey = NULL; + + EVP_PKEY_CTX_free(ctx); + return pkey; +} + +/* + * Load a composite private key from raw DER bytes via EVP_PKEY_fromdata. + * |priv| is the concatenated composite private key blob as exported by the + * keymgmt (OSSL_PKEY_PARAM_PRIV_KEY). + */ +#if COMPOSITE_SIGGEN_TESTDATA_COUNT > 0 +static EVP_PKEY *composite_key_from_priv(const char *alg, + const uint8_t *priv, size_t priv_len) +{ + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM params[2]; + + params[0] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, + (void *)priv, priv_len); + params[1] = OSSL_PARAM_construct_end(); + + if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(lib_ctx, alg, NULL)) + || !TEST_int_eq(EVP_PKEY_fromdata_init(ctx), 1) + || !TEST_int_eq(EVP_PKEY_fromdata(ctx, &pkey, + OSSL_KEYMGMT_SELECT_PRIVATE_KEY, + params), + 1)) + pkey = NULL; + + EVP_PKEY_CTX_free(ctx); + return pkey; +} +#endif /* COMPOSITE_SIGGEN_TESTDATA_COUNT > 0 */ + +/* + * Load a composite public key from raw DER bytes via EVP_PKEY_fromdata. + */ +#if COMPOSITE_SIGVER_TESTDATA_COUNT > 0 +static EVP_PKEY *composite_key_from_pub(const char *alg, + const uint8_t *pub, size_t pub_len) +{ + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM params[2]; + + params[0] = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PUB_KEY, + (void *)pub, pub_len); + params[1] = OSSL_PARAM_construct_end(); + + if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(lib_ctx, alg, NULL)) + || !TEST_int_eq(EVP_PKEY_fromdata_init(ctx), 1) + || !TEST_int_eq(EVP_PKEY_fromdata(ctx, &pkey, + OSSL_KEYMGMT_SELECT_PUBLIC_KEY, + params), + 1)) + pkey = NULL; + + EVP_PKEY_CTX_free(ctx); + return pkey; +} +#endif /* COMPOSITE_SIGVER_TESTDATA_COUNT > 0 */ + +/* ========================================================================= + * DRBG round-trip tests (keygen → sign → verify) + * ========================================================================= */ + +/* + * Sign |msg| with |key| using algorithm |alg|, verify the result. + * Also checks the buffer-too-small path (sig_len - 1). + */ +static int do_sign_verify(EVP_PKEY *key, const char *alg, + const uint8_t *msg, size_t msg_len) +{ + int ret = 0; + EVP_PKEY_CTX *sctx = NULL, *vctx = NULL; + EVP_SIGNATURE *sig_alg = NULL; + uint8_t *sig = NULL; + size_t sig_len = 0; + + if (!TEST_ptr(sctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)) + || !TEST_ptr(sig_alg = EVP_SIGNATURE_fetch(lib_ctx, alg, NULL)) + || !TEST_int_eq(EVP_PKEY_sign_message_init(sctx, sig_alg, NULL), 1) + /* query required buffer size */ + || !TEST_int_eq(EVP_PKEY_sign(sctx, NULL, &sig_len, msg, msg_len), 1) + || !TEST_ptr(sig = OPENSSL_zalloc(sig_len))) + goto err; + + /* Sign with one byte too few — must fail */ + sig_len--; + if (!TEST_int_eq(EVP_PKEY_sign(sctx, sig, &sig_len, msg, msg_len), 0)) + goto err; + sig_len++; + + /* Actual sign */ + if (!TEST_int_eq(EVP_PKEY_sign(sctx, sig, &sig_len, msg, msg_len), 1)) + goto err; + + /* Verify the signature we just produced */ + if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)) + || !TEST_int_eq(EVP_PKEY_verify_message_init(vctx, sig_alg, NULL), 1) + || !TEST_int_eq(EVP_PKEY_verify(vctx, sig, sig_len, msg, msg_len), 1)) + goto err; + + ret = 1; +err: + EVP_SIGNATURE_free(sig_alg); + OPENSSL_free(sig); + EVP_PKEY_CTX_free(sctx); + EVP_PKEY_CTX_free(vctx); + return ret; +} + +/* Table of all 18 composite algorithm names */ +static const char *composite_alg_names[] = { + "ML-DSA-44-RSA2048-PSS-SHA256", + "ML-DSA-44-RSA2048-PKCS15-SHA256", + "ML-DSA-44-Ed25519-SHA512", + "ML-DSA-44-ECDSA-P256-SHA256", + "ML-DSA-65-RSA3072-PSS-SHA512", + "ML-DSA-65-RSA3072-PKCS15-SHA512", + "ML-DSA-65-RSA4096-PSS-SHA512", + "ML-DSA-65-RSA4096-PKCS15-SHA512", + "ML-DSA-65-ECDSA-P256-SHA512", + "ML-DSA-65-ECDSA-P384-SHA512", + "ML-DSA-65-ECDSA-brainpoolP256r1-SHA512", + "ML-DSA-65-Ed25519-SHA512", + "ML-DSA-87-ECDSA-P384-SHA512", + "ML-DSA-87-ECDSA-brainpoolP384r1-SHA512", + "ML-DSA-87-Ed448-SHAKE256", + "ML-DSA-87-RSA3072-PSS-SHA512", + "ML-DSA-87-RSA4096-PSS-SHA512", + "ML-DSA-87-ECDSA-P521-SHA512", +}; +#define NUM_COMPOSITE_ALGS (int)(sizeof(composite_alg_names) / sizeof(composite_alg_names[0])) + +static uint8_t test_msg[] = "OpenSSL composite signature test message"; + +/* + * DRBG keygen + sign + verify for each of the 18 algorithms. + * Parameterised by tst_id (0..17). + */ +static int composite_drbg_sign_verify_test(int tst_id) +{ + int ret = 0; + const char *alg = composite_alg_names[tst_id]; + EVP_PKEY *key = NULL; + +#ifdef OPENSSL_NO_EC + if (strstr(alg, "ECDSA") != NULL) { + TEST_note("Skipping %s - EC not available", alg); + return 1; + } +#endif +#ifdef OPENSSL_NO_ECX + if (strstr(alg, "Ed25519") != NULL || strstr(alg, "Ed448") != NULL) { + TEST_note("Skipping %s - ECX (Ed25519/Ed448) not available", alg); + return 1; + } +#endif + if (!TEST_ptr(key = do_gen_key(alg))) + goto err; + + if (!TEST_true(do_sign_verify(key, alg, test_msg, sizeof(test_msg) - 1))) + goto err; + + ret = 1; +err: + EVP_PKEY_free(key); + return ret; +} + +/* + * Two DRBG-generated keys of the same algorithm must not be equal. + * Two keys of different algorithms must return -1 (incompatible types). + * Checks EVP_PKEY_eq() and EVP_PKEY_dup() round-trips. + */ +static int composite_keygen_drbg_test(void) +{ + int ret = 0; + EVP_PKEY *k1 = NULL, *k2 = NULL, *k3 = NULL, *k1_dup = NULL; + +#ifdef OPENSSL_NO_ECX + TEST_note("Skipping composite_keygen_drbg_test - requires ECX (Ed25519)"); + return 1; +#endif + if (!TEST_ptr(k1 = do_gen_key("ML-DSA-44-Ed25519-SHA512")) + || !TEST_ptr(k2 = do_gen_key("ML-DSA-44-Ed25519-SHA512")) + || !TEST_ptr(k3 = do_gen_key("ML-DSA-44-RSA2048-PSS-SHA256")) + /* same algorithm, different keys */ + || !TEST_int_eq(EVP_PKEY_eq(k1, k2), 0) + /* different algorithm */ + || !TEST_int_eq(EVP_PKEY_eq(k1, k3), -1) + /* dup must produce an equal key */ + || !TEST_ptr(k1_dup = EVP_PKEY_dup(k1)) + || !TEST_int_eq(EVP_PKEY_eq(k1, k1_dup), 1)) + goto err; + + ret = 1; +err: + EVP_PKEY_free(k1); + EVP_PKEY_free(k2); + EVP_PKEY_free(k3); + EVP_PKEY_free(k1_dup); + return ret; +} + +/* ========================================================================= + * Deterministic vector tests (composite_sig.inc) + * ========================================================================= */ + +/* + * siggen: load private key from vector, sign the fixed message, compare the + * SHA-256 digest of the output signature against the stored reference. + * (Same SHA-256-of-sig trick used by ml_dsa_siggen_test to keep the .inc + * file small while still providing a complete bit-exact check.) + */ +#if COMPOSITE_SIGGEN_TESTDATA_COUNT > 0 +static int composite_siggen_test(int tst_id) +{ + int ret = 0; + const COMPOSITE_SIG_GEN_TEST_DATA *td = &composite_siggen_testdata[tst_id]; + EVP_PKEY_CTX *sctx = NULL; + +#ifdef OPENSSL_NO_ECX + if (strstr(td->alg, "Ed25519") != NULL || strstr(td->alg, "Ed448") != NULL) { + TEST_note("Skipping %s - ECX (Ed25519/Ed448) not available", td->alg); + return 1; + } +#endif + EVP_PKEY *pkey = NULL; + EVP_SIGNATURE *sig_alg = NULL; + OSSL_PARAM params[2], *p = params; + uint8_t *psig = NULL; + size_t psig_len = 0; + uint8_t digest[32]; + size_t digest_len = sizeof(digest); + + if (td->add_random != NULL) + *p++ = OSSL_PARAM_construct_octet_string( + OSSL_SIGNATURE_PARAM_TEST_ENTROPY, + (void *)td->add_random, td->add_random_len); + *p = OSSL_PARAM_construct_end(); + + if (!TEST_ptr(pkey = composite_key_from_priv(td->alg, td->priv, td->priv_len))) + goto err; + + if (!TEST_ptr(sctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, pkey, NULL)) + || !TEST_ptr(sig_alg = EVP_SIGNATURE_fetch(lib_ctx, td->alg, NULL)) + || !TEST_int_eq(EVP_PKEY_sign_message_init(sctx, sig_alg, params), 1) + || !TEST_int_eq(EVP_PKEY_sign(sctx, NULL, &psig_len, + td->msg, td->msg_len), + 1) + || !TEST_ptr(psig = OPENSSL_zalloc(psig_len)) + || !TEST_int_eq(EVP_PKEY_sign(sctx, psig, &psig_len, + td->msg, td->msg_len), + 1) + || !TEST_int_eq(EVP_Q_digest(lib_ctx, "SHA256", NULL, + psig, psig_len, + digest, &digest_len), + 1) + || !TEST_mem_eq(digest, digest_len, + td->sig_digest, td->sig_digest_len)) + goto err; + + ret = 1; +err: + EVP_SIGNATURE_free(sig_alg); + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(sctx); + OPENSSL_free(psig); + return ret; +} +#endif /* COMPOSITE_SIGGEN_TESTDATA_COUNT > 0 */ + +/* + * sigver: load public key from vector, verify the stored signature. + * td->expected == 1 for valid, 0 for deliberately invalid vectors. + */ +#if COMPOSITE_SIGVER_TESTDATA_COUNT > 0 +static int composite_sigver_test(int tst_id) +{ + int ret = 0; + const COMPOSITE_SIG_VER_TEST_DATA *td = &composite_sigver_testdata[tst_id]; + EVP_PKEY_CTX *vctx = NULL; + EVP_PKEY *pkey = NULL; + EVP_SIGNATURE *sig_alg = NULL; + + if (!TEST_ptr(pkey = composite_key_from_pub(td->alg, td->pub, td->pub_len))) + goto err; + + if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, pkey, NULL)) + || !TEST_ptr(sig_alg = EVP_SIGNATURE_fetch(lib_ctx, td->alg, NULL)) + || !TEST_int_eq(EVP_PKEY_verify_message_init(vctx, sig_alg, NULL), 1) + || !TEST_int_eq(EVP_PKEY_verify(vctx, td->sig, td->sig_len, + td->msg, td->msg_len), + td->expected)) + goto err; + + ret = 1; +err: + EVP_SIGNATURE_free(sig_alg); + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(vctx); + return ret; +} +#endif /* COMPOSITE_SIGVER_TESTDATA_COUNT > 0 */ + +/* ========================================================================= + * Negative tests + * ========================================================================= */ + +/* + * A signature produced by one composite algorithm must not verify under a + * different composite algorithm that happens to share the same ML-DSA level + * (cross-algorithm mismatch). + */ +static int composite_cross_alg_mismatch_test(void) +{ + int ret = 0; + EVP_PKEY *key_pss = NULL, *key_pkcs = NULL; + EVP_PKEY_CTX *sctx = NULL, *vctx = NULL; + EVP_SIGNATURE *sig_pss = NULL, *sig_pkcs = NULL; + uint8_t *sig = NULL; + size_t sig_len = 0; + const char *alg_a = "ML-DSA-44-RSA2048-PSS-SHA256"; + const char *alg_b = "ML-DSA-44-RSA2048-PKCS15-SHA256"; + + if (!TEST_ptr(key_pss = do_gen_key(alg_a)) + || !TEST_ptr(key_pkcs = do_gen_key(alg_b)) + || !TEST_ptr(sctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key_pss, NULL)) + || !TEST_ptr(sig_pss = EVP_SIGNATURE_fetch(lib_ctx, alg_a, NULL)) + || !TEST_int_eq(EVP_PKEY_sign_message_init(sctx, sig_pss, NULL), 1) + || !TEST_int_eq(EVP_PKEY_sign(sctx, NULL, &sig_len, + test_msg, sizeof(test_msg) - 1), + 1) + || !TEST_ptr(sig = OPENSSL_zalloc(sig_len)) + || !TEST_int_eq(EVP_PKEY_sign(sctx, sig, &sig_len, + test_msg, sizeof(test_msg) - 1), + 1)) + goto err; + + /* + * Verify alg_a signature under alg_b key — must fail. + * EVP_PKEY_verify returns 0 for "bad signature" (not -1). + */ + if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key_pkcs, NULL)) + || !TEST_ptr(sig_pkcs = EVP_SIGNATURE_fetch(lib_ctx, alg_b, NULL)) + || !TEST_int_eq(EVP_PKEY_verify_message_init(vctx, sig_pkcs, NULL), 1) + || !TEST_int_eq(EVP_PKEY_verify(vctx, sig, sig_len, + test_msg, sizeof(test_msg) - 1), + 0)) + goto err; + + ret = 1; +err: + EVP_PKEY_free(key_pss); + EVP_PKEY_free(key_pkcs); + EVP_SIGNATURE_free(sig_pss); + EVP_SIGNATURE_free(sig_pkcs); + OPENSSL_free(sig); + EVP_PKEY_CTX_free(sctx); + EVP_PKEY_CTX_free(vctx); + return ret; +} + +/* + * A tampered signature (single bit flip) must not verify. + */ +static int composite_tampered_sig_test(int tst_id) +{ + int ret = 0; + const char *alg = composite_alg_names[tst_id]; + EVP_PKEY *key = NULL; + EVP_PKEY_CTX *sctx = NULL, *vctx = NULL; + EVP_SIGNATURE *sig_alg = NULL; + uint8_t *sig = NULL; + size_t sig_len = 0; + +#ifdef OPENSSL_NO_EC + if (strstr(alg, "ECDSA") != NULL) { + TEST_note("Skipping %s - EC not available", alg); + return 1; + } +#endif +#ifdef OPENSSL_NO_ECX + if (strstr(alg, "Ed25519") != NULL || strstr(alg, "Ed448") != NULL) { + TEST_note("Skipping %s - ECX (Ed25519/Ed448) not available", alg); + return 1; + } +#endif + if (!TEST_ptr(key = do_gen_key(alg)) + || !TEST_ptr(sctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)) + || !TEST_ptr(sig_alg = EVP_SIGNATURE_fetch(lib_ctx, alg, NULL)) + || !TEST_int_eq(EVP_PKEY_sign_message_init(sctx, sig_alg, NULL), 1) + || !TEST_int_eq(EVP_PKEY_sign(sctx, NULL, &sig_len, + test_msg, sizeof(test_msg) - 1), + 1) + || !TEST_ptr(sig = OPENSSL_zalloc(sig_len)) + || !TEST_int_eq(EVP_PKEY_sign(sctx, sig, &sig_len, + test_msg, sizeof(test_msg) - 1), + 1)) + goto err; + + /* Tamper: flip a bit near the middle of the signature */ + sig[sig_len / 2] ^= 0x01; + + if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)) + || !TEST_int_eq(EVP_PKEY_verify_message_init(vctx, sig_alg, NULL), 1) + || !TEST_int_eq(EVP_PKEY_verify(vctx, sig, sig_len, + test_msg, sizeof(test_msg) - 1), + 0)) + goto err; + + ret = 1; +err: + EVP_PKEY_free(key); + EVP_SIGNATURE_free(sig_alg); + OPENSSL_free(sig); + EVP_PKEY_CTX_free(sctx); + EVP_PKEY_CTX_free(vctx); + return ret; +} + +/* ========================================================================= + * Streaming (sign/verify_message_update) tests + * ========================================================================= */ + +/* + * Feed the message in two chunks via the streaming API, then verify the + * result both via the streaming API (EVP_PKEY_CTX_set_signature() + + * verify_message_update()/_final()) and via the one-shot API, to confirm + * both paths agree. + */ +static int composite_streaming_sign_verify_test(int tst_id) +{ + int ret = 0; + const char *alg = composite_alg_names[tst_id]; + EVP_PKEY *key = NULL; + EVP_PKEY_CTX *sctx = NULL, *vctx = NULL; + EVP_SIGNATURE *sig_alg = NULL; + uint8_t *sig = NULL; + size_t sig_len = 0; + size_t msg_len = sizeof(test_msg) - 1; + size_t half = msg_len / 2; + +#ifdef OPENSSL_NO_EC + if (strstr(alg, "ECDSA") != NULL) { + TEST_note("Skipping %s - EC not available", alg); + return 1; + } +#endif +#ifdef OPENSSL_NO_ECX + if (strstr(alg, "Ed25519") != NULL || strstr(alg, "Ed448") != NULL) { + TEST_note("Skipping %s - ECX (Ed25519/Ed448) not available", alg); + return 1; + } +#endif + + if (!TEST_ptr(key = do_gen_key(alg)) + || !TEST_ptr(sctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)) + || !TEST_ptr(sig_alg = EVP_SIGNATURE_fetch(lib_ctx, alg, NULL)) + || !TEST_int_eq(EVP_PKEY_sign_message_init(sctx, sig_alg, NULL), 1) + || !TEST_int_eq(EVP_PKEY_sign_message_update(sctx, test_msg, half), 1) + || !TEST_int_eq(EVP_PKEY_sign_message_update(sctx, test_msg + half, + msg_len - half), + 1) + || !TEST_int_eq(EVP_PKEY_sign_message_final(sctx, NULL, &sig_len), 1) + || !TEST_ptr(sig = OPENSSL_zalloc(sig_len)) + || !TEST_int_eq(EVP_PKEY_sign_message_final(sctx, sig, &sig_len), 1)) + goto err; + + /* Verify via the streaming API, fed in different-size chunks */ + if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)) + || !TEST_int_eq(EVP_PKEY_verify_message_init(vctx, sig_alg, NULL), 1) + || !TEST_int_eq(EVP_PKEY_CTX_set_signature(vctx, sig, sig_len), 1) + || !TEST_int_eq(EVP_PKEY_verify_message_update(vctx, test_msg, 1), 1) + || !TEST_int_eq(EVP_PKEY_verify_message_update(vctx, test_msg + 1, + msg_len - 1), + 1) + || !TEST_int_eq(EVP_PKEY_verify_message_final(vctx), 1)) + goto err; + EVP_PKEY_CTX_free(vctx); + vctx = NULL; + + /* The same signature must also verify via the one-shot API */ + if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)) + || !TEST_int_eq(EVP_PKEY_verify_message_init(vctx, sig_alg, NULL), 1) + || !TEST_int_eq(EVP_PKEY_verify(vctx, sig, sig_len, test_msg, msg_len), 1)) + goto err; + + ret = 1; +err: + EVP_PKEY_free(key); + EVP_SIGNATURE_free(sig_alg); + OPENSSL_free(sig); + EVP_PKEY_CTX_free(sctx); + EVP_PKEY_CTX_free(vctx); + return ret; +} + +/* + * A tampered signature must not verify via the streaming API either. + */ +static int composite_streaming_tampered_sig_test(int tst_id) +{ + int ret = 0; + const char *alg = composite_alg_names[tst_id]; + EVP_PKEY *key = NULL; + EVP_PKEY_CTX *sctx = NULL, *vctx = NULL; + EVP_SIGNATURE *sig_alg = NULL; + uint8_t *sig = NULL; + size_t sig_len = 0; + +#ifdef OPENSSL_NO_EC + if (strstr(alg, "ECDSA") != NULL) { + TEST_note("Skipping %s - EC not available", alg); + return 1; + } +#endif +#ifdef OPENSSL_NO_ECX + if (strstr(alg, "Ed25519") != NULL || strstr(alg, "Ed448") != NULL) { + TEST_note("Skipping %s - ECX (Ed25519/Ed448) not available", alg); + return 1; + } +#endif + + if (!TEST_ptr(key = do_gen_key(alg)) + || !TEST_ptr(sctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)) + || !TEST_ptr(sig_alg = EVP_SIGNATURE_fetch(lib_ctx, alg, NULL)) + || !TEST_int_eq(EVP_PKEY_sign_message_init(sctx, sig_alg, NULL), 1) + || !TEST_int_eq(EVP_PKEY_sign_message_update(sctx, test_msg, + sizeof(test_msg) - 1), + 1) + || !TEST_int_eq(EVP_PKEY_sign_message_final(sctx, NULL, &sig_len), 1) + || !TEST_ptr(sig = OPENSSL_zalloc(sig_len)) + || !TEST_int_eq(EVP_PKEY_sign_message_final(sctx, sig, &sig_len), 1)) + goto err; + + sig[sig_len / 2] ^= 0x01; + + if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)) + || !TEST_int_eq(EVP_PKEY_verify_message_init(vctx, sig_alg, NULL), 1) + || !TEST_int_eq(EVP_PKEY_CTX_set_signature(vctx, sig, sig_len), 1) + || !TEST_int_eq(EVP_PKEY_verify_message_update(vctx, test_msg, + sizeof(test_msg) - 1), + 1) + || !TEST_int_eq(EVP_PKEY_verify_message_final(vctx), 0)) + goto err; + + ret = 1; +err: + EVP_PKEY_free(key); + EVP_SIGNATURE_free(sig_alg); + OPENSSL_free(sig); + EVP_PKEY_CTX_free(sctx); + EVP_PKEY_CTX_free(vctx); + return ret; +} + +/* ========================================================================= + * Externally pre-computed PH(M) tests (OSSL_SIGNATURE_PARAM_COMPOSITE_PREHASH) + * ========================================================================= */ + +/* Mirrors each entry's prehash_alg/prehash_len in composite_sig.c's composite_alg_table */ +typedef struct { + const char *prehash_alg; + size_t prehash_len; +} COMPOSITE_PREHASH_INFO; + +static const COMPOSITE_PREHASH_INFO composite_alg_prehash[] = { + { "SHA-256", 32 }, /* ML-DSA-44-RSA2048-PSS-SHA256 */ + { "SHA-256", 32 }, /* ML-DSA-44-RSA2048-PKCS15-SHA256 */ + { "SHA-512", 64 }, /* ML-DSA-44-Ed25519-SHA512 */ + { "SHA-256", 32 }, /* ML-DSA-44-ECDSA-P256-SHA256 */ + { "SHA-512", 64 }, /* ML-DSA-65-RSA3072-PSS-SHA512 */ + { "SHA-512", 64 }, /* ML-DSA-65-RSA3072-PKCS15-SHA512 */ + { "SHA-512", 64 }, /* ML-DSA-65-RSA4096-PSS-SHA512 */ + { "SHA-512", 64 }, /* ML-DSA-65-RSA4096-PKCS15-SHA512 */ + { "SHA-512", 64 }, /* ML-DSA-65-ECDSA-P256-SHA512 */ + { "SHA-512", 64 }, /* ML-DSA-65-ECDSA-P384-SHA512 */ + { "SHA-512", 64 }, /* ML-DSA-65-ECDSA-brainpoolP256r1-SHA512 */ + { "SHA-512", 64 }, /* ML-DSA-65-Ed25519-SHA512 */ + { "SHA-512", 64 }, /* ML-DSA-87-ECDSA-P384-SHA512 */ + { "SHA-512", 64 }, /* ML-DSA-87-ECDSA-brainpoolP384r1-SHA512 */ + { "SHAKE256", 64 }, /* ML-DSA-87-Ed448-SHAKE256 (XOF) */ + { "SHA-512", 64 }, /* ML-DSA-87-RSA3072-PSS-SHA512 */ + { "SHA-512", 64 }, /* ML-DSA-87-RSA4096-PSS-SHA512 */ + { "SHA-512", 64 }, /* ML-DSA-87-ECDSA-P521-SHA512 */ +}; + +/* SHAKE256 is a XOF and needs EVP_DigestFinalXOF(), not a plain digest final */ +static int test_compute_prehash(const COMPOSITE_PREHASH_INFO *info, + const uint8_t *msg, size_t msg_len, uint8_t *out, size_t *out_len) +{ + if (OPENSSL_strcasecmp(info->prehash_alg, "SHAKE256") == 0) { + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); + EVP_MD *md = EVP_MD_fetch(lib_ctx, "SHAKE256", NULL); + int ok = (mctx != NULL && md != NULL + && EVP_DigestInit_ex(mctx, md, NULL) + && EVP_DigestUpdate(mctx, msg, msg_len) + && EVP_DigestFinalXOF(mctx, out, info->prehash_len)); + + EVP_MD_CTX_free(mctx); + EVP_MD_free(md); + if (ok) + *out_len = info->prehash_len; + return ok; + } + return EVP_Q_digest(lib_ctx, info->prehash_alg, NULL, msg, msg_len, out, out_len); +} + +/* + * A caller may compute PH(M) itself (e.g. on another machine) and hand it + * to sign()/verify() in place of the raw message, by setting + * OSSL_SIGNATURE_PARAM_COMPOSITE_PREHASH. This must produce a signature + * that verifies both via the same flag and via a normal, independently + * computed PH(M); it must also be interchangeable with a signature made the + * ordinary way (raw message, no flag). + */ +static int composite_external_prehash_test(int tst_id) +{ + int ret = 0; + const char *alg = composite_alg_names[tst_id]; + const COMPOSITE_PREHASH_INFO *phinfo = &composite_alg_prehash[tst_id]; + EVP_PKEY *key = NULL; + EVP_PKEY_CTX *sctx = NULL, *vctx = NULL; + EVP_SIGNATURE *sig_alg = NULL; + uint8_t *sig = NULL, *sig2 = NULL; + size_t sig_len = 0, sig2_len = 0; + uint8_t prehash[64]; + size_t prehash_len = sizeof(prehash); + int have_prehash = 1; + OSSL_PARAM params[2]; + +#ifdef OPENSSL_NO_EC + if (strstr(alg, "ECDSA") != NULL) { + TEST_note("Skipping %s - EC not available", alg); + return 1; + } +#endif +#ifdef OPENSSL_NO_ECX + if (strstr(alg, "Ed25519") != NULL || strstr(alg, "Ed448") != NULL) { + TEST_note("Skipping %s - ECX (Ed25519/Ed448) not available", alg); + return 1; + } +#endif + + params[0] = OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_COMPOSITE_PREHASH, + &have_prehash); + params[1] = OSSL_PARAM_construct_end(); + + if (!TEST_ptr(key = do_gen_key(alg)) + || !TEST_int_eq(test_compute_prehash(phinfo, test_msg, sizeof(test_msg) - 1, + prehash, &prehash_len), + 1)) + goto err; + + /* Sign by feeding the pre-computed PH(M) directly, no raw message */ + if (!TEST_ptr(sctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)) + || !TEST_ptr(sig_alg = EVP_SIGNATURE_fetch(lib_ctx, alg, NULL)) + || !TEST_int_eq(EVP_PKEY_sign_message_init(sctx, sig_alg, params), 1) + || !TEST_int_eq(EVP_PKEY_sign(sctx, NULL, &sig_len, prehash, prehash_len), 1) + || !TEST_ptr(sig = OPENSSL_zalloc(sig_len)) + || !TEST_int_eq(EVP_PKEY_sign(sctx, sig, &sig_len, prehash, prehash_len), 1)) + goto err; + + /* Verify the same way, using only the pre-computed hash */ + if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)) + || !TEST_int_eq(EVP_PKEY_verify_message_init(vctx, sig_alg, params), 1) + || !TEST_int_eq(EVP_PKEY_verify(vctx, sig, sig_len, prehash, prehash_len), 1)) + goto err; + EVP_PKEY_CTX_free(vctx); + vctx = NULL; + + /* + * A signature made the ordinary way (raw message, no flag) must also + * verify against the independently computed PH(M), confirming both + * code paths build the same M'. + */ + EVP_PKEY_CTX_free(sctx); + if (!TEST_ptr(sctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)) + || !TEST_int_eq(EVP_PKEY_sign_message_init(sctx, sig_alg, NULL), 1) + || !TEST_int_eq(EVP_PKEY_sign(sctx, NULL, &sig2_len, + test_msg, sizeof(test_msg) - 1), + 1) + || !TEST_ptr(sig2 = OPENSSL_zalloc(sig2_len)) + || !TEST_int_eq(EVP_PKEY_sign(sctx, sig2, &sig2_len, + test_msg, sizeof(test_msg) - 1), + 1)) + goto err; + + if (!TEST_ptr(vctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, key, NULL)) + || !TEST_int_eq(EVP_PKEY_verify_message_init(vctx, sig_alg, params), 1) + || !TEST_int_eq(EVP_PKEY_verify(vctx, sig2, sig2_len, prehash, prehash_len), 1)) + goto err; + + ret = 1; +err: + EVP_PKEY_free(key); + EVP_SIGNATURE_free(sig_alg); + OPENSSL_free(sig); + OPENSSL_free(sig2); + EVP_PKEY_CTX_free(sctx); + EVP_PKEY_CTX_free(vctx); + return ret; +} + +/* ========================================================================= + * Test registration + * ========================================================================= */ + +const OPTIONS *test_get_options(void) +{ + static const OPTIONS options[] = { + OPT_TEST_OPTIONS_DEFAULT_USAGE, + { "config", OPT_CONFIG_FILE, '<', + "The configuration file to use for the libctx" }, + { NULL } + }; + return options; +} + +int setup_tests(void) +{ + OPTION_CHOICE o; + char *config_file = NULL; + + while ((o = opt_next()) != OPT_EOF) { + switch (o) { + case OPT_CONFIG_FILE: + config_file = opt_arg(); + break; + case OPT_TEST_CASES: + break; + default: + case OPT_ERR: + return 0; + } + } + if (!test_get_libctx(&lib_ctx, &null_prov, config_file, &lib_prov, NULL)) + return 0; + + /* Strategy 1: DRBG round-trips for all 18 algorithms */ + ADD_ALL_TESTS(composite_drbg_sign_verify_test, NUM_COMPOSITE_ALGS); + ADD_TEST(composite_keygen_drbg_test); + + /* Strategy 2: deterministic vector tests from composite_sig.inc */ +#if COMPOSITE_SIGGEN_TESTDATA_COUNT > 0 + ADD_ALL_TESTS(composite_siggen_test, COMPOSITE_SIGGEN_TESTDATA_COUNT); +#endif +#if COMPOSITE_SIGVER_TESTDATA_COUNT > 0 + ADD_ALL_TESTS(composite_sigver_test, COMPOSITE_SIGVER_TESTDATA_COUNT); +#endif + + /* Negative tests */ + ADD_TEST(composite_cross_alg_mismatch_test); + ADD_ALL_TESTS(composite_tampered_sig_test, NUM_COMPOSITE_ALGS); + + /* Streaming (sign/verify_message_update) tests */ + ADD_ALL_TESTS(composite_streaming_sign_verify_test, NUM_COMPOSITE_ALGS); + ADD_ALL_TESTS(composite_streaming_tampered_sig_test, NUM_COMPOSITE_ALGS); + + /* Externally pre-computed PH(M) tests */ + ADD_ALL_TESTS(composite_external_prehash_test, NUM_COMPOSITE_ALGS); + + return 1; +} + +void cleanup_tests(void) +{ + OSSL_PROVIDER_unload(null_prov); + OSSL_PROVIDER_unload(lib_prov); + OSSL_LIB_CTX_free(lib_ctx); +} diff --git a/test/conf_include_test.c b/test/conf_include_test.c index cd1d4881b9264..acbd60744c0bb 100644 --- a/test/conf_include_test.c +++ b/test/conf_include_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -186,7 +186,11 @@ static int test_check_overflow(void) char max[(sizeof(long) * 8) / 3 + 3]; char *p; - p = max + BIO_snprintf(max, sizeof(max), "0%ld", LONG_MAX) - 1; + int n = snprintf(max, sizeof(max), "0%ld", LONG_MAX); + + if (!TEST_true(n > 0 && (size_t)n < sizeof(max))) + return 0; + p = max + n - 1; setenv("FNORD", max, 1); if (!TEST_true(NCONF_get_number(NULL, "missing", "FNORD", &val)) || !TEST_long_eq(val, LONG_MAX)) diff --git a/test/ct_validation_helpers_test.c b/test/ct_validation_helpers_test.c new file mode 100644 index 0000000000000..68f3465a956f8 --- /dev/null +++ b/test/ct_validation_helpers_test.c @@ -0,0 +1,203 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Tests for the constant-time validation helpers in constant_time.h: + * - CONSTTIME_SECRET + * - CONSTTIME_DECLASSIFY + * - constant_time_declassify_u32() + * + * Most of the modes below check whether Valgrind flags code that is + * deliberately NOT constant-time. The accompanying recipe asserts that the + * harness flags it. Each such mode is a separate process because Valgrind's + * verdict is delivered as a process exit code via Valgrind's --error-exitcode. + * + * The "identity" mode is different: It ensures constant_time_declassify_u32() + * still exists and functions correctly when used OUTSIDE enable-ct-validation. + * Thus this mode uses the ordinary test framework pass/fail signal + * and does not require Valgrind. + */ + +#include + +#include + +#include "internal/constant_time.h" +#include "internal/nelem.h" +#include "testutil.h" + +#define SECRET_LEN 32 + +/* + * Volatile sink for results computed by tests below. + * + * Must be volatile so that the compiler cannot delete the offending code as + * dead, which would silently cause tests to check nothing and pass falsely. + */ +static volatile unsigned int sink; + +static const unsigned char lut[16] = { + 3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3 /* arbitrary values */ +}; + +static void fill_secret(unsigned char *secret) +{ + size_t i; + + for (i = 0; i < SECRET_LEN; i++) + secret[i] = (unsigned char)(i * 7 + 1); +} + +/* + * "branch" mode: Ensure Valgrind flags a branch (a loop iteration count) on a + * secret marked with CONSTTIME_SECRET. + * + * Valgrind should report: + * "Conditional jump or move depends on uninitialised value(s)". + */ +static int test_secret_dependent_branch(void) +{ + unsigned char secret[SECRET_LEN]; + unsigned int i, n; + + fill_secret(secret); + CONSTTIME_SECRET(secret, sizeof(secret)); + + n = secret[0] & 0x0f; + for (i = 0; i < n; i++) + sink = i; + + CONSTTIME_DECLASSIFY(secret, sizeof(secret)); + return 1; +} + +/* + * "index" mode: Ensure Valgrind flags a lookup table index derived from a + * secret marked with CONSTTIME_SECRET. + * + * Valgrind should report: + * "Use of uninitialised value". + */ +static int test_secret_dependent_index(void) +{ + unsigned char secret[SECRET_LEN]; + + fill_secret(secret); + CONSTTIME_SECRET(secret, sizeof(secret)); + + sink = lut[secret[0] & 0x0f]; + + CONSTTIME_DECLASSIFY(secret, sizeof(secret)); + return 1; +} + +/* + * "control" mode: Ensure Valgrind does NOT flag a branch on a secret that has + * been declassified by CONSTTIME_DECLASSIFY. + */ +static int test_constant_time_control(void) +{ + unsigned char secret[SECRET_LEN]; + unsigned int acc = 0; + size_t i; + + fill_secret(secret); + CONSTTIME_SECRET(secret, sizeof(secret)); + + for (i = 0; i < sizeof(secret); i++) + acc |= secret[i]; + + CONSTTIME_DECLASSIFY(&acc, sizeof(acc)); + CONSTTIME_DECLASSIFY(secret, sizeof(secret)); + + if (acc == 0) + sink = 1; + else + sink = 2; + + return TEST_uint_eq(sink, 2); +} + +/* + * "mask" mode: Ensure Valgrind does NOT flag a branch on the result of + * constant_time_declassify_u32(). + * + * Uses the same calling pattern as constant_time_declassify_u32's current + * unique caller: + * - A constant_time_ge()/constant_time_lt() mask (0 or all-ones) computed from + * secret data is declassified and immediately branched on. The boolean + * outcome of a rejection-sampling check is safe to leak even though the data + * behind it is not. + */ +static int test_declassify_mask(void) +{ + unsigned char secret[SECRET_LEN]; + unsigned int mask; + + fill_secret(secret); + CONSTTIME_SECRET(secret, sizeof(secret)); + + mask = constant_time_ge(secret[0], 0x80); + + if (constant_time_declassify_u32(mask)) + sink = 1; + else + sink = 2; + + CONSTTIME_DECLASSIFY(secret, sizeof(secret)); + return 1; +} + +/* + * "identity" mode: Ensure constant_time_declassify_u32() returns its input + * unmodified, independent of whether Valgrind or enable-ct-validation are + * enabled. + */ +static int test_declassify_u32_identity(void) +{ + static const uint32_t values[] = { 0, 1, 0xdeadbeef, 0xffffffff }; + size_t i; + int ret = 1; + + for (i = 0; i < OSSL_NELEM(values); i++) + ret &= TEST_uint_eq(constant_time_declassify_u32(values[i]), values[i]); + return ret; +} + +OPT_TEST_DECLARE_USAGE("branch|index|control|mask|identity\n") + +int setup_tests(void) +{ + const char *mode; + + if (!test_skip_common_options()) { + TEST_error("Error parsing test options\n"); + return 0; + } + + if (!TEST_ptr(mode = test_get_argument(0))) + return 0; + + if (strcmp(mode, "branch") == 0) + ADD_TEST(test_secret_dependent_branch); + else if (strcmp(mode, "index") == 0) + ADD_TEST(test_secret_dependent_index); + else if (strcmp(mode, "control") == 0) + ADD_TEST(test_constant_time_control); + else if (strcmp(mode, "mask") == 0) + ADD_TEST(test_declassify_mask); + else if (strcmp(mode, "identity") == 0) + ADD_TEST(test_declassify_u32_identity); + else { + TEST_error("Unknown mode '%s'\n", mode); + return 0; + } + + return 1; +} diff --git a/test/danetest.c b/test/danetest.c index f9e30388e1972..2c2bb4afcbf65 100644 --- a/test/danetest.c +++ b/test/danetest.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/defltfips_test.c b/test/defltfips_test.c index c962f14385a3d..24e099e2d1d12 100644 --- a/test/defltfips_test.c +++ b/test/defltfips_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/destest.c b/test/destest.c index a5fa3b51a5683..4cdad22977192 100644 --- a/test/destest.c +++ b/test/destest.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/drbgtest.c b/test/drbgtest.c index 0828ebf7b5566..b8809b3761ef9 100644 --- a/test/drbgtest.c +++ b/test/drbgtest.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -415,7 +415,7 @@ static int test_rand_reseed_on_fork(EVP_RAND_CTX *primary, presult[0].pindex = presult[1].pindex = i; - BIO_snprintf(presult[0].name, sizeof(presult[0].name), "child %d", i); + snprintf(presult[0].name, sizeof(presult[0].name), "child %d", i); strcpy(presult[1].name, presult[0].name); /* collect the random output of the children */ diff --git a/test/dsatest.c b/test/dsatest.c index 2c739854f3393..ab3a83ba1be6b 100644 --- a/test/dsatest.c +++ b/test/dsatest.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/dtls13_internal_test.c b/test/dtls13_internal_test.c new file mode 100644 index 0000000000000..3d78654dac7e7 --- /dev/null +++ b/test/dtls13_internal_test.c @@ -0,0 +1,650 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "../ssl/record/methods/recmethod_local.h" +#include "../ssl/ssl_local.h" +#include "../ssl/statem/statem_local.h" +#include "internal/nelem.h" +#include "internal/ssl_unwrap.h" +#include "helpers/ssltestlib.h" +#include "testutil.h" +#include +#include +#include + +static char *cert = NULL; +static char *privkey = NULL; + +static const char *cipher_names[] = { + "aes-128-ecb", + "aes-256-ecb", +#if !defined(OPENSSL_NO_CHACHA) + "chacha20", +#endif +}; + +static int test_dtls_crypt_sequence_number(int idx) +{ + /* + * Test all possiblie Encryption Algorithms for dtls_crypt_sequence_number function + * aes-128-ecb, "aes-256-ecb" and "chacha20" + */ + EVP_CIPHER_CTX *ctx = NULL; + EVP_CIPHER *cipher = NULL; + unsigned char key[32] = { 0 }; + unsigned char iv[16] = { 0 }; + unsigned char initial_seq[2] = { 0, 0 }; + unsigned char zero_seq[2] = { 0, 0 }; + unsigned char rec_data[16] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + }; + + cipher = EVP_CIPHER_fetch(NULL, cipher_names[idx], NULL); + if (!TEST_ptr(cipher)) + goto err; + + ctx = EVP_CIPHER_CTX_new(); + if (!TEST_ptr(ctx)) + goto err; + + if (!TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, 1))) + goto err; + + if (!TEST_int_eq(dtls_crypt_sequence_number(ctx, initial_seq, sizeof(initial_seq), rec_data), 1)) + goto err; + + /* Verify Sequence Number is no longer zero */ + if (!TEST_mem_ne(initial_seq, sizeof(initial_seq), zero_seq, sizeof(zero_seq))) + goto err; + + if (!TEST_int_eq(dtls_crypt_sequence_number(ctx, initial_seq, sizeof(initial_seq), rec_data), 1)) + goto err; + + /* Verify Sequence Number is back to zero */ + if (!TEST_mem_eq(initial_seq, sizeof(initial_seq), zero_seq, sizeof(zero_seq))) + goto err; + + EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_free(cipher); + return 1; +err: + if (ctx != NULL) + EVP_CIPHER_CTX_free(ctx); + if (cipher != NULL) + EVP_CIPHER_free(cipher); + return 0; +} + +/* rfc9147 section 4.2.2 sequence number reconstruction vectors. */ +typedef struct seq_num_test_st { + /* Zero also represents the initial empty replay window. */ + uint64_t max_seq_num; + uint64_t truncated; + size_t seqlen; + uint64_t seq_num; +} SEQ_NUM_TEST; + +static const SEQ_NUM_TEST seq_num_tests[] = { + /* Empty window and first-period lower-bound cases. */ + { 0, 0, 1, 0 }, + { 0, 1, 1, 1 }, + { 0, 0x7f, 1, 0x7f }, + { 0, 0x80, 1, 0x80 }, + { 0, 0x81, 1, 0x81 }, + { 0, 0xff, 1, 0xff }, + { 0, 0, 2, 0 }, + { 0, 1, 2, 1 }, + { 0, 0x7fff, 2, 0x7fff }, + { 0, 0x8000, 2, 0x8000 }, + { 0, 0x8001, 2, 0x8001 }, + { 0, 0x8002, 2, 0x8002 }, + { 0, 40000, 2, 40000 }, + { 0, 0xffff, 2, 0xffff }, + + /* Ordinary forward progression */ + { 5, 6, 2, 6 }, + { 5, 6, 1, 6 }, + { 200, 201, 2, 201 }, + { 0x1234, 0x1235, 2, 0x1235 }, + + /* 8- and 16-bit wraps */ + { 0xfe, 0xff, 1, 0xff }, + { 0xff, 0x00, 1, 0x100 }, + { 0x100, 0x01, 1, 0x101 }, + { 0x1fe, 0xff, 1, 0x1ff }, + { 0x1ff, 0x00, 1, 0x200 }, + { 0xfffe, 0xffff, 2, 0xffff }, + { 0xffff, 0x0000, 2, 0x10000 }, + { 0x10000, 0x0001, 2, 0x10001 }, + { 0x1fffe, 0xffff, 2, 0x1ffff }, + { 0x1ffff, 0x0000, 2, 0x20000 }, + { 0x20000, 0x0001, 2, 0x20001 }, + + /* Reordered records */ + { 0x100, 0xff, 2, 0xff }, + { 0x100, 0xfe, 2, 0xfe }, + { 0x10010, 0x000f, 2, 0x1000f }, + { 300, 40, 1, 296 }, + + /* Half-period ties select the forward candidate in either phase. */ + { 199, 72, 1, 328 }, /* candidate 72, 128 behind: pick 328 */ + { 299, 172, 1, 428 }, /* candidate 428, 128 ahead: keep it */ + { 0x180ff, 0x0100, 2, 0x20100 }, /* candidate 0x10100: pick 0x20100 */ + { 0x100ff, 0x8100, 2, 0x18100 }, /* candidate 0x18100: keep it */ + + /* Top-of-uint64_t fallback and overflow boundaries */ + { UINT64_MAX, 0, 2, UINT64_MAX & ~UINT64_C(0xffff) }, + { UINT64_MAX, 0xffff, 2, UINT64_MAX }, + { UINT64_MAX, 0xffc0, 2, (UINT64_MAX & ~UINT64_C(0xffff)) | 0xffc0 }, + { UINT64_MAX, 5, 1, (UINT64_MAX & ~UINT64_C(0xff)) | 5 }, + { UINT64_MAX - 1, 0, 2, UINT64_MAX & ~UINT64_C(0xffff) }, + { UINT64_MAX - 0x10000, 0, 2, UINT64_MAX - 0xffff }, + { UINT64_MAX - 0x10000, 1, 2, UINT64_MAX - 0xffff + 1 }, + { UINT64_MAX - 0x10000, 0x8000, 2, + (UINT64_MAX - 0xffff) | 0x8000 }, +}; + +static int test_seq_num_reconstruction(int idx) +{ + const SEQ_NUM_TEST *t = &seq_num_tests[idx]; + uint64_t seq_num = 0; + + seq_num = dtls13_reconstruct_seq_num(t->max_seq_num, t->truncated, + t->seqlen); + + if (!TEST_uint64_t_eq(seq_num, t->seq_num)) + return 0; + + /* The reconstructed value must retain the wire bits used in the AAD. */ + return TEST_uint64_t_eq(seq_num & DTLS13_UNI_HDR_SEQ_MASK(t->seqlen), + t->truncated); +} + +#ifndef OPENSSL_NO_DTLS1_3 +/* Empty and single-entry ACK vectors, with and without trailing data. */ +static int test_dtls13_ack_length(int idx) +{ + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + SSL_CONNECTION *sc; + BIO *wbio; + unsigned char ack[2 + 16 + 1] = { 0 }; + size_t len = idx < 2 ? 2 : 18; + int trailing = idx % 2; + PACKET pkt; + int testresult = 0; + + ack[1] = (unsigned char)(len - 2); + ack[len] = 0xff; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_method())) + || !TEST_ptr(ssl = SSL_new(ctx)) + || !TEST_ptr(sc = SSL_CONNECTION_FROM_SSL(ssl)) + || !TEST_true(PACKET_buf_init(&pkt, ack, len + trailing)) + || !TEST_ptr(wbio = BIO_new(BIO_s_mem()))) + goto end; + + SSL_set0_wbio(ssl, wbio); + + if (!TEST_int_eq(dtls_process_ack(sc, &pkt), + trailing ? MSG_PROCESS_ERROR : MSG_PROCESS_FINISHED_READING)) + goto end; + + if (trailing + && !TEST_int_eq(ERR_GET_REASON(ERR_peek_last_error()), + SSL_R_LENGTH_TOO_LONG)) + goto end; + + testresult = 1; +end: + SSL_free(ssl); + SSL_CTX_free(ctx); + ERR_clear_error(); + return testresult; +} + +/* + * Test that dtls1_increment_epoch() enforces the RFC 9147 Section 8 limit + * on the write (sending) epoch for DTLS 1.3: "sending implementations MUST + * NOT allow the epoch to exceed 2^48-1". This is stricter than the 2^64-1 + * wrap-around ceiling in Section 6.1, and applies only to the write side + * and only for DTLS 1.3 -- DTLS 1.2 keeps its existing UINT16_MAX limit. + * + * There's no way to actually drive 2^48 real KeyUpdates in a test, so this + * drives one real DTLS 1.3 handshake to get a genuinely-typed connection + * (SSL_CONNECTION_IS_DTLS13() depends on the negotiated method, not + * anything that can be poked directly), then writes w_conn_epoch directly + * to one below the limit before calling the real increment function at and + * past the boundary. + */ +static int test_dtls13_increment_epoch_max(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + SSL_CONNECTION *sc = NULL; + int testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + DTLS1_3_VERSION, DTLS1_3_VERSION, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL))) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + if (!TEST_int_eq(SSL_version(serverssl), DTLS1_3_VERSION)) + goto end; + + if (!TEST_ptr(sc = SSL_CONNECTION_FROM_SSL(serverssl))) + goto end; + + if (!TEST_true(SSL_CONNECTION_IS_DTLS13(sc))) + goto end; + + /* One below the Section 8 limit: incrementing must still succeed. */ + sc->rlayer.d->w_conn_epoch = DTLS1_3_MAX_EPOCH - 1; + if (!TEST_true(dtls1_increment_epoch(sc, SSL3_CC_WRITE))) + goto end; + if (!TEST_uint64_t_eq(sc->rlayer.d->w_conn_epoch, DTLS1_3_MAX_EPOCH)) + goto end; + + /* Already at the limit: incrementing further must be rejected. */ + if (!TEST_false(dtls1_increment_epoch(sc, SSL3_CC_WRITE))) + goto end; + if (!TEST_uint64_t_eq(sc->rlayer.d->w_conn_epoch, DTLS1_3_MAX_EPOCH)) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* Exercise ACK coverage for the client's final flight and the server's tickets. */ +static int test_dtls13_ack_coverage(int server) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl = NULL, *clientssl = NULL, *sender, *peer; + SSL_CONNECTION *sc, *psc; + dtls_sent_msg *msg = NULL; + DTLS1_RECORD_NUMBER *recnum; + pitem *item; + piterator iter; + unsigned char ack[18], buf, discard[2048]; + WPACKET pkt; + uint64_t epoch, seqnum; + size_t acklen, written; + OSSL_TIME timeout; + int i, ret, testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), DTLS1_3_VERSION, DTLS1_3_VERSION, + &sctx, &cctx, cert, privkey))) + goto end; + + /* An empty client Certificate and Finished give us two messages to ACK. */ + if (!server) + SSL_CTX_set_verify(sctx, SSL_VERIFY_PEER, NULL); + if (!TEST_true(SSL_CTX_set_num_tickets(sctx, server ? 2 : 0)) + || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL))) + goto end; + + ret = SSL_connect(clientssl); + if (!TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_WANT_READ)) + goto end; + ret = SSL_accept(serverssl); + if (!TEST_int_eq(SSL_get_error(serverssl, ret), SSL_ERROR_WANT_READ)) + goto end; + ret = SSL_connect(clientssl); + if (!TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_WANT_READ)) + goto end; + if (!TEST_int_eq(SSL_accept(serverssl), 1)) + goto end; + /* SSL_write() must not finish the peer's handshake and ACK our test flight. */ + if (!server + && (!TEST_int_gt(BIO_read(SSL_get_rbio(clientssl), discard, sizeof(discard)), 0) + || !TEST_size_t_eq(BIO_ctrl_pending(SSL_get_rbio(clientssl)), 0))) + goto end; + + sender = server ? serverssl : clientssl; + peer = server ? clientssl : serverssl; + sc = SSL_CONNECTION_FROM_SSL(sender); + psc = SSL_CONNECTION_FROM_SSL(peer); + if (!TEST_size_t_eq(pqueue_size(&sc->d1->sent_messages), 2) + || !TEST_false(ossl_time_is_zero(sc->d1->next_timeout))) + goto end; + + /* ACK the last message first, keeping the earlier message outstanding. */ + iter = pqueue_iterator(&sc->d1->sent_messages); + while ((item = pqueue_next(&iter)) != NULL) + msg = item->data; + if (!TEST_ptr(msg) + || !TEST_ptr(recnum = ossl_list_record_number_head(&msg->rec_nums))) + goto end; + epoch = recnum->epoch; + seqnum = recnum->seqnum; + + /* Avoid timer expiry while inspecting ACK processing. */ + timeout = sc->d1->next_timeout = ossl_time_add(ossl_time_now(), ossl_seconds2time(3600)); + + for (i = 0; i < 5; i++) { + int complete = i == 4; + int appdata = server || complete; + + /* Empty, nonmatching, partial, duplicate, then the remaining record. */ + if (complete) { + dtls_sent_msg *unacked = pqueue_peek(&sc->d1->sent_messages)->data; + uint64_t oldseq; + + if (!TEST_ptr(recnum = ossl_list_record_number_head(&unacked->rec_nums))) + goto end; + oldseq = recnum->seqnum; + sc->d1->next_timeout = ossl_time_subtract(ossl_time_now(), ossl_seconds2time(1)); + if (!TEST_int_gt(DTLSv1_handle_timeout(sender), 0) + || !TEST_true(ossl_list_record_number_is_empty(&msg->rec_nums)) + || !TEST_ptr(recnum = ossl_list_record_number_head(&unacked->rec_nums)) + || !TEST_uint64_t_gt(recnum->seqnum, oldseq)) + goto end; + sc->d1->next_timeout = timeout; + /* Only the unacknowledged message should have been retransmitted. */ + msg = pqueue_peek(&sc->d1->sent_messages)->data; + if (!TEST_ptr(recnum = ossl_list_record_number_head(&msg->rec_nums))) + goto end; + epoch = recnum->epoch; + seqnum = recnum->seqnum; + } + if (!TEST_true(WPACKET_init_static_len(&pkt, ack, sizeof(ack), 2))) + goto end; + if ((i != 0 + && (!TEST_true(WPACKET_put_bytes_u64(&pkt, epoch)) + || !TEST_true(WPACKET_put_bytes_u64(&pkt, + i == 1 ? seqnum + 1000 : seqnum)))) + || !TEST_true(WPACKET_finish(&pkt)) + || !TEST_true(WPACKET_get_total_written(&pkt, &acklen))) { + WPACKET_cleanup(&pkt); + goto end; + } + WPACKET_cleanup(&pkt); + if (!TEST_int_eq(dtls1_write_bytes(psc, SSL3_RT_ACK, + ack, acklen, &written), + 1) + || !TEST_size_t_eq(written, acklen) + || !TEST_int_eq(SSL_write(peer, "x", 1), 1) + || !TEST_int_gt(BIO_flush(psc->wbio), 0)) + goto end; + + /* Application data is buffered until the client's final ACK arrives. */ + ret = SSL_read(sender, &buf, sizeof(buf)); + if (!TEST_int_eq(SSL_get_error(sender, ret), + appdata ? SSL_ERROR_NONE : SSL_ERROR_WANT_READ) + || (appdata && !TEST_uchar_eq(buf, 'x')) + || !TEST_int_eq(SSL_get_state(sender), appdata ? TLS_ST_OK : TLS_ST_CW_FINISHED) + || !TEST_size_t_eq(pqueue_size(&sc->d1->sent_messages), complete ? 0 : 2) + || !TEST_int_eq(ossl_time_compare(sc->d1->next_timeout, + complete ? ossl_time_zero() : timeout), + 0) + || (!appdata && !TEST_size_t_eq(pqueue_size(sc->rlayer.d->buffered_app_data), i + 1)) + || (!complete && !TEST_int_eq(ossl_list_record_number_is_empty(&msg->rec_nums), i >= 2))) + goto end; + } + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +static int ticket_count; + +static int count_ticket(SSL *ssl, SSL_SESSION *session) +{ + ticket_count++; + return 0; +} + +/* + * Replace lost ticket ACKs after another loss or WANT_WRITE, with whole or + * fragmented retransmissions, and with or without an outstanding local flight. + */ +static int test_dtls13_ticket_ack_retransmit(int idx) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *server = NULL, *client = NULL; + SSL_CONNECTION *sc, *cc; + BIO *retry = NULL; + piterator iter; + pitem *item; + unsigned char buf[2048]; + unsigned int readseq, writeseq; + OSSL_TIME client_timeout = ossl_time_zero(); + int i, ret, dropped, testresult = 0; + int pending_key_update = idx / 4; + int fragmented = (idx / 2) % 2; + int retry_write = idx % 2; + + ticket_count = 0; + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), DTLS1_3_VERSION, DTLS1_3_VERSION, + &sctx, &cctx, cert, privkey))) + goto end; + SSL_CTX_set_session_cache_mode(cctx, SSL_SESS_CACHE_CLIENT); + SSL_CTX_sess_set_new_cb(cctx, count_ticket); + if (!TEST_true(create_ssl_objects(sctx, cctx, &server, &client, NULL, NULL)) + || !TEST_true(create_ssl_connection(server, client, SSL_ERROR_NONE))) + goto end; + sc = SSL_CONNECTION_FROM_SSL(server); + cc = SSL_CONNECTION_FROM_SSL(client); + readseq = cc->d1->handshake_read_seq; + writeseq = cc->d1->next_handshake_write_seq; + if (!TEST_int_eq(ticket_count, 2) + || !TEST_size_t_eq(pqueue_size(&sc->d1->sent_messages), 2)) + goto end; + + if (pending_key_update) { + if (!TEST_true(SSL_key_update(client, SSL_KEY_UPDATE_NOT_REQUESTED))) + goto end; + ret = SSL_do_handshake(client); + if (!TEST_int_eq(SSL_get_error(client, ret), SSL_ERROR_WANT_READ) + || !TEST_size_t_eq(pqueue_size(&cc->d1->sent_messages), 1)) + goto end; + client_timeout = cc->d1->next_timeout = ossl_time_add(ossl_time_now(), ossl_seconds2time(3600)); + writeseq = cc->d1->next_handshake_write_seq; + } + + if (fragmented) { + /* Refragment the tickets on retransmission, after processing them whole. */ + SSL_set_options(server, SSL_OP_NO_QUERY_MTU); + if (!TEST_long_gt(SSL_set_mtu(server, 256), 0)) + goto end; + } + if (retry_write) { + if (!TEST_ptr(retry = BIO_new(bio_s_maybe_retry())) + || !TEST_true(BIO_up_ref(SSL_get_wbio(client)))) + goto end; + SSL_set0_wbio(client, BIO_push(retry, SSL_get_wbio(client))); + retry = NULL; + } + + for (i = 0; i < 2; i++) { + /* + * Lose the initial ACKs, then also lose the first replacement ACKs. + * In the pending-flight cases, discard the KeyUpdate too: the server + * must not process it or send an ACK for the client's local flight. + */ + dropped = 0; + while (BIO_read(SSL_get_rbio(server), buf, sizeof(buf)) > 0) + dropped++; + if (!TEST_int_gt(dropped, 0)) + goto end; + sc->d1->next_timeout = ossl_time_subtract(ossl_time_now(), ossl_seconds2time(1)); + if (!TEST_int_gt(DTLSv1_handle_timeout(server), 0)) + goto end; + iter = pqueue_iterator(&sc->d1->sent_messages); + while ((item = pqueue_next(&iter)) != NULL) { + dtls_sent_msg *msg = item->data; + size_t records = ossl_list_record_number_num(&msg->rec_nums); + + if (fragmented ? !TEST_size_t_gt(records, 1) : !TEST_size_t_eq(records, 1)) + goto end; + } + + if (retry_write) { + if (!TEST_long_eq(BIO_ctrl(SSL_get_wbio(client), + MAYBE_RETRY_CTRL_SET_RETRY_AFTER_CNT, 0, NULL), + 1)) + goto end; + ret = SSL_read(client, buf, 1); + if (!TEST_int_eq(SSL_get_error(client, ret), SSL_ERROR_WANT_WRITE)) + goto end; + ret = SSL_read(client, buf, 1); + if (!TEST_int_eq(SSL_get_error(client, ret), SSL_ERROR_WANT_WRITE) + || !TEST_long_eq(BIO_ctrl(SSL_get_wbio(client), + MAYBE_RETRY_CTRL_SET_RETRY_AFTER_CNT, 100, NULL), + 1)) + goto end; + } + ret = SSL_read(client, buf, 1); + if (!TEST_int_eq(SSL_get_error(client, ret), SSL_ERROR_WANT_READ) + || !TEST_int_eq(SSL_get_state(client), pending_key_update ? TLS_ST_CW_KEY_UPDATE : TLS_ST_OK) + || !TEST_int_eq(ticket_count, 2) + || !TEST_uint_eq(cc->d1->handshake_read_seq, readseq) + || !TEST_uint_eq(cc->d1->next_handshake_write_seq, writeseq) + || !TEST_size_t_gt(BIO_ctrl_pending(SSL_get_rbio(server)), 0) + || !TEST_size_t_eq(pqueue_size(&sc->d1->sent_messages), 2) + || !TEST_false(ossl_time_is_zero(sc->d1->next_timeout)) + || !TEST_size_t_eq(pqueue_size(&cc->d1->sent_messages), pending_key_update ? 1 : 0) + || !TEST_int_eq(ossl_time_compare(cc->d1->next_timeout, client_timeout), 0)) + goto end; + } + + /* The deliberately lost KeyUpdate must still be waiting for its own ACK. */ + if (pending_key_update) { + testresult = 1; + goto end; + } + + ret = SSL_read(server, buf, 1); + if (!TEST_int_eq(SSL_get_error(server, ret), SSL_ERROR_WANT_READ) + || !TEST_size_t_eq(pqueue_size(&sc->d1->sent_messages), 0) + || !TEST_true(ossl_time_is_zero(sc->d1->next_timeout)) + || !TEST_int_eq(DTLSv1_handle_timeout(server), 0) + || !TEST_int_eq(SSL_write(server, "s", 1), 1) + || !TEST_int_eq(SSL_read(client, buf, 1), 1) + || !TEST_uchar_eq(buf[0], 's') + || !TEST_int_eq(SSL_write(client, "c", 1), 1) + || !TEST_int_eq(SSL_read(server, buf, 1), 1) + || !TEST_uchar_eq(buf[0], 'c')) + goto end; + + testresult = 1; +end: + BIO_free(retry); + SSL_free(server); + SSL_free(client); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +static int test_dtls13_pha_ack_retransmit(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *server = NULL, *client = NULL; + SSL_CONNECTION *sc, *cc; + unsigned char buf, discard[2048]; + int ret, testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), DTLS1_3_VERSION, DTLS1_3_VERSION, + &sctx, &cctx, cert, privkey)) + || !TEST_true(SSL_CTX_set_num_tickets(sctx, 0))) + goto end; + SSL_CTX_set_post_handshake_auth(cctx, 1); + if (!TEST_true(create_ssl_objects(sctx, cctx, &server, &client, NULL, NULL)) + || !TEST_true(create_ssl_connection(server, client, SSL_ERROR_NONE))) + goto end; + sc = SSL_CONNECTION_FROM_SSL(server); + cc = SSL_CONNECTION_FROM_SSL(client); + SSL_set_verify(server, SSL_VERIFY_PEER, NULL); + if (!TEST_true(SSL_verify_client_post_handshake(server)) + || !TEST_int_eq(SSL_do_handshake(server), 1) + || !TEST_size_t_eq(pqueue_size(&sc->d1->sent_messages), 1)) + goto end; + ret = SSL_read(client, &buf, 1); + if (!TEST_int_eq(SSL_get_error(client, ret), SSL_ERROR_WANT_READ)) + goto end; + ret = SSL_read(server, &buf, 1); + if (!TEST_int_eq(SSL_get_error(server, ret), SSL_ERROR_WANT_READ) + || !TEST_size_t_eq(pqueue_size(&cc->d1->sent_messages), 2)) + goto end; + + /* Drop the ACK for the PHA response and let the client retransmit. */ + if (!TEST_int_gt(BIO_read(SSL_get_rbio(client), discard, sizeof(discard)), 0) + || !TEST_size_t_eq(BIO_ctrl_pending(SSL_get_rbio(client)), 0)) + goto end; + cc->d1->next_timeout = ossl_time_subtract(ossl_time_now(), ossl_seconds2time(1)); + if (!TEST_int_gt(DTLSv1_handle_timeout(client), 0)) + goto end; + ret = SSL_read(server, &buf, 1); + if (!TEST_int_eq(SSL_get_error(server, ret), SSL_ERROR_WANT_READ) + || !TEST_size_t_gt(BIO_ctrl_pending(SSL_get_rbio(client)), 0)) + goto end; + ret = SSL_read(client, &buf, 1); + if (!TEST_int_eq(SSL_get_error(client, ret), SSL_ERROR_WANT_READ) + || !TEST_true(SSL_is_init_finished(server)) + || !TEST_true(SSL_is_init_finished(client)) + || !TEST_size_t_eq(pqueue_size(&cc->d1->sent_messages), 0) + || !TEST_true(ossl_time_is_zero(cc->d1->next_timeout)) + || !TEST_int_eq(sc->post_handshake_auth, SSL_PHA_EXT_RECEIVED)) + goto end; + testresult = 1; +end: + SSL_free(server); + SSL_free(client); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} +#endif /* OPENSSL_NO_DTLS1_3 */ + +int setup_tests(void) +{ + if (!TEST_ptr(cert = test_get_argument(0)) + || !TEST_ptr(privkey = test_get_argument(1))) + return 0; + + ADD_ALL_TESTS(test_dtls_crypt_sequence_number, OSSL_NELEM(cipher_names)); + ADD_ALL_TESTS(test_seq_num_reconstruction, OSSL_NELEM(seq_num_tests)); +#ifndef OPENSSL_NO_DTLS1_3 + ADD_ALL_TESTS(test_dtls13_ack_length, 4); + ADD_TEST(test_dtls13_increment_epoch_max); + ADD_ALL_TESTS(test_dtls13_ack_coverage, 2); + ADD_ALL_TESTS(test_dtls13_ticket_ack_retransmit, 8); + ADD_TEST(test_dtls13_pha_ack_retransmit); +#endif + return 1; +} + +void cleanup_tests(void) +{ + bio_s_maybe_retry_free(); +} diff --git a/test/dtls_mtu_test.c b/test/dtls_mtu_test.c index 9a2d8caab0e60..3ad8301f5f030 100644 --- a/test/dtls_mtu_test.c +++ b/test/dtls_mtu_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -22,13 +22,15 @@ #include "internal/ssl_unwrap.h" static int debug = 0; +static char *cert = NULL; +static char *privkey = NULL; static unsigned int clnt_psk_callback(SSL *ssl, const char *hint, char *ident, unsigned int max_ident_len, unsigned char *psk, unsigned int max_psk_len) { - BIO_snprintf(ident, max_ident_len, "psk"); + snprintf(ident, max_ident_len, "psk"); if (max_psk_len > 20) max_psk_len = 20; @@ -47,7 +49,8 @@ static unsigned int srvr_psk_callback(SSL *ssl, const char *identity, return max_psk_len; } -static int mtu_test(SSL_CTX *ctx, const char *cs, int no_etm) +static int mtu_test(SSL_CTX *sctx, SSL_CTX *cctx, const char *cs, int no_etm, + int dtls_version) { SSL *srvr_ssl = NULL, *clnt_ssl = NULL; BIO *sc_bio = NULL; @@ -60,27 +63,55 @@ static int mtu_test(SSL_CTX *ctx, const char *cs, int no_etm) memset(buf, 0x5a, sizeof(buf)); - if (!TEST_true(create_ssl_objects(ctx, ctx, &srvr_ssl, &clnt_ssl, + if (!TEST_true(create_ssl_objects(sctx, cctx, &srvr_ssl, &clnt_ssl, NULL, NULL))) goto end; if (no_etm) SSL_set_options(srvr_ssl, SSL_OP_NO_ENCRYPT_THEN_MAC); - if (!TEST_true(SSL_set_cipher_list(srvr_ssl, cs)) - || !TEST_true(SSL_set_cipher_list(clnt_ssl, cs)) - || !TEST_ptr(sc_bio = SSL_get_rbio(srvr_ssl)) - || !TEST_true(create_ssl_connection(clnt_ssl, srvr_ssl, + if (dtls_version == DTLS1_3_VERSION) { + if (!TEST_true(SSL_set_ciphersuites(srvr_ssl, cs)) + || !TEST_true(SSL_set_ciphersuites(clnt_ssl, cs))) + goto end; + } else { + if (!TEST_true(SSL_set_max_proto_version(srvr_ssl, DTLS1_2_VERSION)) + || !TEST_true(SSL_set_max_proto_version(clnt_ssl, DTLS1_2_VERSION)) + || !TEST_true(SSL_set_cipher_list(srvr_ssl, cs)) + || !TEST_true(SSL_set_cipher_list(clnt_ssl, cs))) + goto end; + } + + if (!TEST_ptr(sc_bio = SSL_get_rbio(srvr_ssl)) + || !TEST_true(create_ssl_connection(srvr_ssl, clnt_ssl, SSL_ERROR_NONE))) goto end; if (debug) TEST_info("Channel established"); + /* + * DTLS 1.3 sends ACKs for post-handshake messages (e.g. NewSessionTicket). + * Those ACKs land in sc_bio before we start measuring. Drain them so the + * BIO contains only the application records we write below. + */ + if (dtls_version == DTLS1_3_VERSION) { + unsigned char tmp[1]; + size_t nread; + + while (BIO_pending(sc_bio) > 0) { + if (!TEST_false(SSL_read_ex(srvr_ssl, tmp, sizeof(tmp), &nread)) + || !TEST_int_eq(SSL_get_error(srvr_ssl, 0), + SSL_ERROR_WANT_READ)) + goto end; + } + } + /* For record MTU values between 500 and 539, call DTLS_get_data_mtu() * to query the payload MTU which will fit. */ for (i = 0; i < 30; i++) { - SSL_set_mtu(clnt_ssl, 500 + i); + if (!TEST_true(SSL_set_mtu(clnt_ssl, 500 + i))) + goto end; mtus[i] = DTLS_get_data_mtu(clnt_ssl); if (debug) TEST_info("%s%s MTU for record mtu %d = %zu", @@ -93,18 +124,23 @@ static int mtu_test(SSL_CTX *ctx, const char *cs, int no_etm) } /* Now get out of the way */ - SSL_set_mtu(clnt_ssl, 1000); + if (!TEST_true(SSL_set_mtu(clnt_ssl, 1000))) + goto end; /* * Now for all values in the range of payload MTUs, send a payload of * that size and see what actual record size we end up with. */ for (s = mtus[0]; s <= mtus[29]; s++) { + int rlen; size_t reclen; if (!TEST_int_eq(SSL_write(clnt_ssl, buf, (int)s), (int)s)) goto end; - reclen = BIO_read(sc_bio, buf, sizeof(buf)); + rlen = BIO_read(sc_bio, buf, sizeof(buf)); + if (!TEST_int_gt(rlen, 0)) + goto end; + reclen = (size_t)rlen; if (debug) TEST_info("record %zu for payload %zu", reclen, s); @@ -148,6 +184,17 @@ static int run_mtu_tests(void) SSL_CTX *ctx = NULL; STACK_OF(SSL_CIPHER) *ciphers; int i, ret = 0; +#ifndef OPENSSL_NO_DTLS1_3 + static const char *const dtls13_ciphers[] = { + "TLS_AES_128_GCM_SHA256", + "TLS_AES_256_GCM_SHA384", +#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) + "TLS_CHACHA20_POLY1305_SHA256", +#endif + }; + SSL_CTX *sctx13 = NULL, *cctx13 = NULL; + size_t j; +#endif if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_method()))) goto end; @@ -157,9 +204,11 @@ static int run_mtu_tests(void) SSL_CTX_set_security_level(ctx, 0); /* + * DTLS 1.2: iterate over each enc/mac variant using PSK ciphers. * We only care about iterating over each enc/mac; we don't want to * repeat the test for each auth/kx variant. So keep life simple and - * only do (non-DH) PSK. + * only do (non-DH) PSK. Pin to DTLS 1.2 so the intended ciphers are + * actually negotiated rather than being overridden by DTLS 1.3. */ if (!TEST_true(SSL_CTX_set_cipher_list(ctx, "PSK"))) goto end; @@ -173,20 +222,45 @@ static int run_mtu_tests(void) if (!HAS_PREFIX(cipher_name, "PSK-")) continue; - if (!TEST_int_gt(ret = mtu_test(ctx, cipher_name, 0), 0)) - break; + if (!TEST_int_gt(ret = mtu_test(ctx, ctx, cipher_name, 0, DTLS1_2_VERSION), 0)) + goto end; TEST_info("%s OK", cipher_name); if (ret == 1) continue; /* mtu_test() returns 2 if it used Encrypt-then-MAC */ - if (!TEST_int_gt(ret = mtu_test(ctx, cipher_name, 1), 0)) - break; + if (!TEST_int_gt(ret = mtu_test(ctx, ctx, cipher_name, 1, DTLS1_2_VERSION), 0)) + goto end; TEST_info("%s without EtM OK", cipher_name); } +#ifndef OPENSSL_NO_DTLS1_3 + /* + * DTLS 1.3: test each ciphersuite using certificate-based auth. + * PSK is not needed here — auth method doesn't affect record overhead. + */ + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + DTLS1_3_VERSION, DTLS1_3_VERSION, + &sctx13, &cctx13, cert, privkey))) + goto end; + + for (j = 0; j < OSSL_NELEM(dtls13_ciphers); j++) { + if (!TEST_int_gt(ret = mtu_test(sctx13, cctx13, dtls13_ciphers[j], + 0, DTLS1_3_VERSION), + 0)) + goto end; + TEST_info("%s OK", dtls13_ciphers[j]); + } +#endif + + ret = 1; end: SSL_CTX_free(ctx); +#ifndef OPENSSL_NO_DTLS1_3 + SSL_CTX_free(sctx13); + SSL_CTX_free(cctx13); +#endif return ret; } @@ -231,8 +305,18 @@ static int test_server_mtu_larger_than_max_fragment_length(void) return rv; } +OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n") + int setup_tests(void) { + if (!test_skip_common_options()) { + TEST_error("Error parsing test options\n"); + return 0; + } + + cert = test_get_argument(0); + privkey = test_get_argument(1); + ADD_TEST(run_mtu_tests); ADD_TEST(test_server_mtu_larger_than_max_fragment_length); return 1; diff --git a/test/dtls_multithread_test.c b/test/dtls_multithread_test.c new file mode 100644 index 0000000000000..48918ffb1987f --- /dev/null +++ b/test/dtls_multithread_test.c @@ -0,0 +1,802 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include "internal/sockets.h" +#include "internal/thread_arch.h" +#include "helpers/ssltestlib.h" +#include "testutil.h" + +static char *cert = NULL; +static char *privkey = NULL; + +#define NUM_CLIENTS 3 +#define CLIENT_TO_SERVER_MSG "Hello from client" +#define SERVER_TO_CLIENT_MSG "Hello from server" +#define POLL_TIMEOUT_SEC 5 +#define MAX_POLL_RETRIES 50 + +/* + * Per-thread state for server connection handlers + */ +struct server_thread_args { + SSL *conn; /* Server-side connection for this thread */ + int thread_idx; + CRYPTO_THREAD *thread; + int result; /* 1 = success, 0 = failure */ +}; + +/* + * Per-thread state for client connection handlers + */ +struct client_thread_args { + SSL *conn; /* Client-side connection for this thread */ + int thread_idx; + CRYPTO_THREAD *thread; + int result; /* 1 = success, 0 = failure */ +}; + +/* + * Thread function: waits for data on a server connection using SSL_poll, + * reads the message from client, and sends a response. + * + * Uses a retry loop because SSL_poll() returning SSL_POLL_EVENT_R doesn't + * guarantee SSL_read_ex() will succeed - there may be encrypted records + * but not yet a complete application data message. + */ +static unsigned int server_conn_thread(void *arg) +{ + struct server_thread_args *ta = (struct server_thread_args *)arg; + SSL_POLL_ITEM item; + struct timeval timeout; + size_t result_count, readbytes, written; + char buf[256] = { 0 }; + int ret, err, retries; + + ta->result = 0; + readbytes = 0; + + item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + item.desc.value.ssl = ta->conn; + item.events = SSL_POLL_EVENT_R; + item.revents = 0; + + timeout.tv_sec = POLL_TIMEOUT_SEC; + timeout.tv_usec = 0; + + /* Poll and receive message from client */ + for (retries = 0; retries < MAX_POLL_RETRIES; retries++) { + item.revents = 0; + + if (!TEST_true(SSL_poll(&item, 1, sizeof(item), &timeout, 0, &result_count))) + return 0; + + if (result_count == 0 || (item.revents & SSL_POLL_EVENT_R) == 0) + continue; + + ret = SSL_read_ex(ta->conn, buf, sizeof(buf) - 1, &readbytes); + if (ret == 1) + break; + + err = SSL_get_error(ta->conn, ret); + if (!TEST_int_eq(err, SSL_ERROR_WANT_READ)) + return 0; + } + + if (!TEST_int_lt(retries, MAX_POLL_RETRIES)) + return 0; + + buf[readbytes] = '\0'; + if (!TEST_str_eq(buf, CLIENT_TO_SERVER_MSG)) + return 0; + + if (!TEST_true(SSL_write_ex(ta->conn, SERVER_TO_CLIENT_MSG, + strlen(SERVER_TO_CLIENT_MSG), &written))) + return 0; + + ta->result = 1; + return 0; +} + +/* + * Thread function: sends a message to the server and waits for the response. + * + * Uses SSL_poll to wait for readable data from server, then verifies the response. + */ +static unsigned int client_conn_thread(void *arg) +{ + struct client_thread_args *ta = (struct client_thread_args *)arg; + SSL_POLL_ITEM item; + struct timeval timeout; + size_t result_count, written; + size_t readbytes = 0; + char buf[256] = { 0 }; + int ret, err, retries; + + ta->result = 0; + + /* Send message to server */ + if (!TEST_true(SSL_write_ex(ta->conn, CLIENT_TO_SERVER_MSG, + strlen(CLIENT_TO_SERVER_MSG), &written))) + return 0; + + /* Wait for and receive response from server */ + item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + item.desc.value.ssl = ta->conn; + item.events = SSL_POLL_EVENT_R; + item.revents = 0; + + timeout.tv_sec = POLL_TIMEOUT_SEC; + timeout.tv_usec = 0; + + for (retries = 0; retries < MAX_POLL_RETRIES; retries++) { + item.revents = 0; + + if (!TEST_true(SSL_poll(&item, 1, sizeof(item), &timeout, 0, &result_count))) + return 0; + + if (result_count == 0 || (item.revents & SSL_POLL_EVENT_R) == 0) + continue; + + ret = SSL_read_ex(ta->conn, buf, sizeof(buf) - 1, &readbytes); + if (ret == 1) + break; + + err = SSL_get_error(ta->conn, ret); + if (!TEST_int_eq(err, SSL_ERROR_WANT_READ)) + return 0; + } + + if (!TEST_int_lt(retries, MAX_POLL_RETRIES)) + return 0; + + buf[readbytes] = '\0'; + if (!TEST_str_eq(buf, SERVER_TO_CLIENT_MSG)) + return 0; + + ta->result = 1; + return 0; +} + +/* + * Helper: create DTLS listener with real UDP socket + */ +static int create_listener(SSL_CTX *ctx, SSL **listener, BIO_ADDR **addr, int *fd) +{ + BIO *bio = NULL; + struct in_addr ina; + union BIO_sock_info_u info; + int ret = 0; + + *listener = NULL; + *addr = NULL; + *fd = -1; + + ina.s_addr = htonl(INADDR_LOOPBACK); + + *fd = BIO_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0); + if (!TEST_int_ge(*fd, 0)) + goto err; + + if (!TEST_true(BIO_socket_nbio(*fd, 1))) + goto err; + + if (!TEST_ptr(*addr = BIO_ADDR_new())) + goto err; + + if (!TEST_true(BIO_ADDR_rawmake(*addr, AF_INET, &ina, sizeof(ina), 0))) + goto err; + + if (!TEST_true(BIO_bind(*fd, *addr, 0))) + goto err; + + info.addr = *addr; + if (!TEST_true(BIO_sock_info(*fd, BIO_SOCK_INFO_ADDRESS, &info))) + goto err; + + if (!TEST_ptr(bio = BIO_new_dgram(*fd, BIO_NOCLOSE))) + goto err; + + if (!TEST_ptr(*listener = SSL_new_listener(ctx, 0))) + goto err; + + SSL_set_bio(*listener, bio, bio); + bio = NULL; + + if (!TEST_int_eq(SSL_listen(*listener), 1)) + goto err; + + ret = 1; + +err: + BIO_free(bio); + if (ret == 0) { + SSL_free(*listener); + BIO_ADDR_free(*addr); + if (*fd >= 0) + BIO_closesocket(*fd); + *listener = NULL; + *addr = NULL; + *fd = -1; + } + return ret; +} + +/* + * Helper: create DTLS client connected to server address + */ +static int create_client(SSL_CTX *ctx, const BIO_ADDR *server_addr, + SSL **client, int *fd) +{ + BIO *bio = NULL; + int ret = 0; + + *client = NULL; + *fd = -1; + + *fd = BIO_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0); + if (!TEST_int_ge(*fd, 0)) + goto err; + + if (!TEST_true(BIO_socket_nbio(*fd, 1))) + goto err; + + if (!TEST_ptr(bio = BIO_new_dgram(*fd, BIO_NOCLOSE))) + goto err; + + if (!TEST_true(BIO_dgram_set_peer(bio, server_addr))) + goto err; + + if (!TEST_ptr(*client = SSL_new(ctx))) + goto err; + + SSL_set_bio(*client, bio, bio); + bio = NULL; + + ret = 1; + +err: + BIO_free(bio); + if (ret == 0) { + SSL_free(*client); + if (*fd >= 0) + BIO_closesocket(*fd); + *client = NULL; + *fd = -1; + } + return ret; +} + +/* + * Helper: drive handshake between client and listener, return accepted connection. + */ +static int do_handshake(SSL *client, SSL *listener, SSL **server_conn) +{ + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int retc, err_code; + int abortctr = 0; + + *server_conn = NULL; + + SSL_set_connect_state(client); + + while (*server_conn == NULL) { + if (!TEST_int_le(++abortctr, 100)) + return 0; + + retc = SSL_connect(client); + err_code = SSL_get_error(client, retc); + if (retc <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) + return 0; + + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 100000; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), + &poll_timeout, 0, &poll_result))) + return 0; + + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + *server_conn = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + + if (!TEST_ptr(*server_conn)) + return 0; + + if (!TEST_true(create_ssl_connection(*server_conn, client, SSL_ERROR_NONE))) + return 0; + + return 1; +} + +/* + * Main test: multiple threads polling on different DTLS connections + */ +static int test_dtls_multithread(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *clients[NUM_CLIENTS] = { NULL }; + SSL *server_conns[NUM_CLIENTS] = { NULL }; + int client_fds[NUM_CLIENTS] = { -1, -1, -1 }; + struct server_thread_args server_args[NUM_CLIENTS]; + struct client_thread_args client_args[NUM_CLIENTS]; + BIO_ADDR *server_addr = NULL; + int server_fd = -1; + int testresult = 0; + int i; + + memset(server_args, 0, sizeof(server_args)); + memset(client_args, 0, sizeof(client_args)); + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto err; + + if (!TEST_true(create_listener(sctx, &listener, &server_addr, &server_fd))) + goto err; + + /* + * do_handshake() below drives both ends from this thread, so the server + * side must not block: a blocking read would wait for a client which only + * this thread can advance. Connections accepted from the listener inherit + * this. The worker threads which follow use SSL_poll() and expect + * SSL_ERROR_WANT_READ, so they need it too. + */ + if (!TEST_true(SSL_set_blocking_mode(listener, 0))) + goto err; + + for (i = 0; i < NUM_CLIENTS; i++) { + if (!TEST_true(create_client(cctx, server_addr, &clients[i], &client_fds[i]))) + goto err; + + if (!TEST_true(do_handshake(clients[i], listener, &server_conns[i]))) + goto err; + } + + /* Start server threads - each will poll and wait for data */ + for (i = 0; i < NUM_CLIENTS; i++) { + server_args[i].conn = server_conns[i]; + server_args[i].thread_idx = i; + server_args[i].result = 0; + + server_args[i].thread = ossl_crypto_thread_native_start( + server_conn_thread, &server_args[i], 1); + if (!TEST_ptr(server_args[i].thread)) + goto err; + } + + /* Start client threads - each will send data and wait for response */ + for (i = 0; i < NUM_CLIENTS; i++) { + client_args[i].conn = clients[i]; + client_args[i].thread_idx = i; + client_args[i].result = 0; + + client_args[i].thread = ossl_crypto_thread_native_start( + client_conn_thread, &client_args[i], 1); + if (!TEST_ptr(client_args[i].thread)) + goto err; + } + + /* Wait for all server threads to complete */ + for (i = 0; i < NUM_CLIENTS; i++) { + ossl_crypto_thread_native_join(server_args[i].thread, NULL); + ossl_crypto_thread_native_clean(server_args[i].thread); + server_args[i].thread = NULL; + + if (!TEST_int_eq(server_args[i].result, 1)) + goto err; + } + + /* Wait for all client threads to complete */ + for (i = 0; i < NUM_CLIENTS; i++) { + ossl_crypto_thread_native_join(client_args[i].thread, NULL); + ossl_crypto_thread_native_clean(client_args[i].thread); + client_args[i].thread = NULL; + + if (!TEST_int_eq(client_args[i].result, 1)) + goto err; + } + + testresult = 1; + +err: + /* Clean up any remaining server threads */ + for (i = 0; i < NUM_CLIENTS; i++) { + if (server_args[i].thread != NULL) { + ossl_crypto_thread_native_join(server_args[i].thread, NULL); + ossl_crypto_thread_native_clean(server_args[i].thread); + } + } + + /* Clean up any remaining client threads */ + for (i = 0; i < NUM_CLIENTS; i++) { + if (client_args[i].thread != NULL) { + ossl_crypto_thread_native_join(client_args[i].thread, NULL); + ossl_crypto_thread_native_clean(client_args[i].thread); + } + } + + for (i = 0; i < NUM_CLIENTS; i++) { + SSL_free(clients[i]); + SSL_free(server_conns[i]); + if (client_fds[i] >= 0) + BIO_closesocket(client_fds[i]); + } + + SSL_free(listener); + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} + +/* + * Per-thread state for the blocking accept + */ +struct accept_thread_args { + SSL *listener; + SSL *conn; /* connection the accept returned */ + CRYPTO_THREAD *thread; + int result; /* 1 = success, 0 = failure */ +}; + +/* + * Thread function: block in SSL_accept_connection() until a connection turns + * up. This is the accept path which ticks the listener itself, so no other + * thread needs to drive it. + */ +static unsigned int blocking_accept_thread(void *arg) +{ + struct accept_thread_args *ta = (struct accept_thread_args *)arg; + + ta->conn = SSL_accept_connection(ta->listener, 0); + ta->result = (ta->conn != NULL); + return 1; +} + +/* + * Test that a blocking SSL_accept_connection() waits for a connection and + * returns it. + * + * The listener demultiplexes one socket to many connections, so it cannot + * block inside a read: doing so would stall every other connection, and the + * demux lock is held across it. Blocking accept therefore has to wait for + * readiness rather than for a datagram, which is what this exercises - a + * client is only created once the accepting thread is already in the call. + * + * Note that this cannot distinguish waiting from spinning: the accept returns + * the connection either way, and the difference is CPU consumed rather than + * anything observable through the API. It is a test that the blocking path + * works at all, which was previously only covered for the failure case of + * having no BIO set. + */ +static int test_dtls_blocking_accept(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL, *client = NULL; + struct accept_thread_args accept_args; + BIO_ADDR *server_addr = NULL; + int server_fd = -1, client_fd = -1; + int testresult = 0; + int i, ret, err; + + memset(&accept_args, 0, sizeof(accept_args)); + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), 0, 0, &sctx, &cctx, cert, privkey))) + goto err; + + if (!TEST_true(create_listener(sctx, &listener, &server_addr, &server_fd))) + goto err; + + /* + * This test needs the blocking accept, so ask for it rather than relying + * on the default. + */ + if (!TEST_true(SSL_set_blocking_mode(listener, 1))) + goto err; + + /* + * Create the client's socket first, but do not connect with it yet. There + * is no way to cancel a blocking SSL_accept_connection(), so a thread + * parked in one is released only by a connection arriving - which means + * nothing between starting the thread and the exchange completing may bail + * out, or the join below would wait for ever. Anything which can fail is + * therefore done up front. The accept still has to wait, since no datagram + * is sent until SSL_connect() below. + */ + if (!TEST_true(create_client(cctx, server_addr, &client, &client_fd))) + goto err; + + accept_args.listener = listener; + accept_args.thread = ossl_crypto_thread_native_start(blocking_accept_thread, + &accept_args, 1); + if (!TEST_ptr(accept_args.thread)) + goto err; + + /* + * Drive the client's side of the cookie exchange. The accepting thread + * ticks the listener, so this only has to keep the client moving. + */ + SSL_set_connect_state(client); + for (i = 0; i < 200 && accept_args.result == 0; i++) { + ret = SSL_connect(client); + err = SSL_get_error(client, ret); + if (ret <= 0 && err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect failed (err %d)", err); + goto err; + } + OSSL_sleep(10); + } + + ossl_crypto_thread_native_join(accept_args.thread, NULL); + ossl_crypto_thread_native_clean(accept_args.thread); + accept_args.thread = NULL; + + if (!TEST_int_eq(accept_args.result, 1) || !TEST_ptr(accept_args.conn)) + goto err; + + testresult = 1; +err: + if (accept_args.thread != NULL) { + ossl_crypto_thread_native_join(accept_args.thread, NULL); + ossl_crypto_thread_native_clean(accept_args.thread); + } + SSL_free(accept_args.conn); + SSL_free(client); + SSL_free(listener); + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + if (client_fd >= 0) + BIO_closesocket(client_fd); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * How long the client waits, in milliseconds, after its handshake completes + * before sending anything. The server thread has to still be inside its + * blocking read when the write finally happens, or the test proves nothing. + * + * A machine slow enough to get there late does not make the test fail: the read + * then finds the datagram already queued and returns it, which is a pass with + * nothing demonstrated. Only the absence of blocking turns it into a failure. + */ +#define BLOCKING_READ_QUIET_MS 250 + +/* + * Per-thread state for the blocking read + */ +struct read_thread_args { + SSL *listener; + SSL *conn; /* connection the accept returned */ + CRYPTO_THREAD *thread; + char buf[256]; + size_t readbytes; + int nonblocking_handshake; /* handshake without blocking mode */ + int result; /* 1 = success, 0 = failure */ +}; + +/* + * Helper: complete the handshake with the connection in non-blocking mode, + * driving the listener by hand, so that the blocking read which follows is the + * only thing relying on the emulation. + */ +static int nonblocking_handshake(struct read_thread_args *ta) +{ + int i, ret = -1, err; + + if (!TEST_true(SSL_set_blocking_mode(ta->conn, 0))) + return 0; + + for (i = 0; i < 200; i++) { + ret = SSL_accept(ta->conn); + if (ret == 1) + break; + err = SSL_get_error(ta->conn, ret); + if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_accept failed (err %d)", err); + return 0; + } + /* Nothing else will service the listener while we are in here. */ + if (!TEST_true(SSL_handle_events(ta->listener))) + return 0; + OSSL_sleep(10); + } + + if (!TEST_int_eq(ret, 1)) + return 0; + + return TEST_true(SSL_set_blocking_mode(ta->conn, 1)); +} + +/* + * Thread function: accept a connection, complete its handshake and read from + * it, so that the thread never has to handle WANT_READ. + */ +static unsigned int blocking_read_thread(void *arg) +{ + struct read_thread_args *ta = (struct read_thread_args *)arg; + + ta->conn = SSL_accept_connection(ta->listener, 0); + if (!TEST_ptr(ta->conn)) + return 0; + + /* + * A listener-created connection has no BIO of its own to block in - it + * reads from a queue the listener demultiplexes into - so without the + * emulation these calls return immediately with WANT_READ instead of + * waiting. + */ + if (ta->nonblocking_handshake) { + if (!nonblocking_handshake(ta)) + return 0; + } else if (!TEST_int_gt(SSL_accept(ta->conn), 0)) { + return 0; + } + + if (!TEST_true(SSL_read_ex(ta->conn, ta->buf, sizeof(ta->buf) - 1, + &ta->readbytes))) + return 0; + + ta->result = 1; + return 0; +} + +/* + * Test that a blocking listener connection waits for a datagram rather than + * reporting WANT_READ. + * + * The client stays silent for BLOCKING_READ_QUIET_MS after its own handshake + * completes, so by the time it writes, the server thread is already parked in + * SSL_read_ex() with nothing to return. A non-blocking connection reports + * WANT_READ immediately, so the absence of the emulation shows up as a failed + * assertion rather than as a hang. + * + * idx 0 blocks in the handshake as well as in the read. idx 1 handshakes in + * non-blocking mode and only then switches the connection to blocking, which + * leaves the read as the sole assertion the emulation has to satisfy - without + * it, idx 0 fails at SSL_accept() and never reaches the read, so on its own it + * would not tell us the read path works. + * + * Only the client is driven from this thread: the accepting thread ticks the + * listener itself, which is what lets a blocked connection make progress at + * all. + */ +static int test_dtls_blocking_read(int idx) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL, *client = NULL; + struct read_thread_args read_args; + BIO_ADDR *server_addr = NULL; + int server_fd = -1, client_fd = -1; + int testresult = 0; + size_t written; + int i, ret = -1, err; + + memset(&read_args, 0, sizeof(read_args)); + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), 0, 0, &sctx, &cctx, cert, privkey))) + goto err; + + if (!TEST_true(create_listener(sctx, &listener, &server_addr, &server_fd))) + goto err; + + /* Blocking is the default, but this test depends on it, so be explicit. */ + if (!TEST_true(SSL_set_blocking_mode(listener, 1))) + goto err; + + /* + * As in test_dtls_blocking_accept, create the client's socket before the + * thread which will park in the blocking accept, because nothing can + * release that thread except a connection arriving. Nothing is sent until + * SSL_connect() below, so the accept still waits. + */ + if (!TEST_true(create_client(cctx, server_addr, &client, &client_fd))) + goto err; + + read_args.listener = listener; + read_args.nonblocking_handshake = idx; + read_args.thread = ossl_crypto_thread_native_start(blocking_read_thread, + &read_args, 1); + if (!TEST_ptr(read_args.thread)) + goto err; + + /* Drive the client's handshake to completion. */ + SSL_set_connect_state(client); + for (i = 0; i < 200; i++) { + ret = SSL_connect(client); + if (ret == 1) + break; + err = SSL_get_error(client, ret); + if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect failed (err %d)", err); + goto err; + } + OSSL_sleep(10); + } + if (!TEST_int_eq(ret, 1)) + goto err; + + /* Let the server thread reach its read and find nothing there. */ + OSSL_sleep(BLOCKING_READ_QUIET_MS); + + if (!TEST_true(SSL_write_ex(client, CLIENT_TO_SERVER_MSG, + strlen(CLIENT_TO_SERVER_MSG), &written))) + goto err; + + ossl_crypto_thread_native_join(read_args.thread, NULL); + ossl_crypto_thread_native_clean(read_args.thread); + read_args.thread = NULL; + + if (!TEST_int_eq(read_args.result, 1)) + goto err; + + read_args.buf[read_args.readbytes] = '\0'; + if (!TEST_str_eq(read_args.buf, CLIENT_TO_SERVER_MSG)) + goto err; + + testresult = 1; +err: + if (read_args.thread != NULL) { + ossl_crypto_thread_native_join(read_args.thread, NULL); + ossl_crypto_thread_native_clean(read_args.thread); + } + SSL_free(read_args.conn); + SSL_free(client); + SSL_free(listener); + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + if (client_fd >= 0) + BIO_closesocket(client_fd); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n") + +int setup_tests(void) +{ + if (!test_skip_common_options()) { + TEST_error("Error parsing test options\n"); + return 0; + } + + if (!TEST_ptr(cert = test_get_argument(0)) + || !TEST_ptr(privkey = test_get_argument(1))) + return 0; + + ADD_TEST(test_dtls_multithread); + ADD_TEST(test_dtls_blocking_accept); + ADD_ALL_TESTS(test_dtls_blocking_read, 2); + return 1; +} diff --git a/test/dtlsssllistenertest.c b/test/dtlsssllistenertest.c new file mode 100644 index 0000000000000..d25d690aed298 --- /dev/null +++ b/test/dtlsssllistenertest.c @@ -0,0 +1,6066 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Tests for SSL_new_listener() API for DTLS. + * + * This test file covers the new DTLS SSL Listener API: + * - SSL_new_listener() + * - SSL_is_listener() + * - SSL_get0_listener() + * - SSL_listen() + * - SSL_accept_connection() + * - SSL_get_accept_connection_queue_len() + * - SSL_poll() + */ + +#include +#include +#include +#include +#include +#include "internal/time.h" +#include "internal/sockets.h" +#include "internal/dgram_demux.h" +#include "internal/ssl_unwrap.h" +#include "helpers/ssltestlib.h" +#include "testutil.h" +#include "../ssl/ssl_local.h" + +static char *cert = NULL; +static char *privkey = NULL; + +/* + * Fake time support for timeout testing. + * timeout_test_fake_time holds the simulated current time, and + * timeout_test_now_cb is passed to the listener to override its time source. + */ +static OSSL_TIME timeout_test_fake_time; + +static OSSL_TIME timeout_test_now_cb(void *arg) +{ + return timeout_test_fake_time; +} + +/* + * Helper function that waits for data using SSL_poll and then reads. + * Uses SSL_poll() to wait for data since server connections from a listener + * don't have their own socket fd. + * + * This function retries in a loop because SSL_poll() may report data is + * available (based on the URXE queue having encrypted records) but SSL_read_ex() + * may return SSL_ERROR_WANT_READ if those records don't yet constitute a + * complete application data message. The retry loop allows the + * demux to pump additional packets and complete the message. + */ +#define DTLS_READ_TIMEOUT_SEC 2 +#define DTLS_READ_MAX_RETRIES 10 + +static int dtls_read_with_retry(SSL *ssl, void *buf, size_t bufsize, + size_t *readbytes) +{ + SSL_POLL_ITEM item; + struct timeval timeout; + size_t result_count; + int ret, err, retries; + + item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + item.desc.value.ssl = ssl; + item.events = SSL_POLL_EVENT_R; + item.revents = 0; + + timeout.tv_sec = DTLS_READ_TIMEOUT_SEC; + timeout.tv_usec = 0; + + for (retries = 0; retries < DTLS_READ_MAX_RETRIES; retries++) { + item.revents = 0; + if (!SSL_poll(&item, 1, sizeof(item), &timeout, 0, &result_count)) { + TEST_error("SSL_poll failed"); + return 0; + } + + /* No data yet or not read-ready, continue polling */ + if (result_count == 0 || (item.revents & SSL_POLL_EVENT_R) == 0) + continue; + + ret = SSL_read_ex(ssl, buf, bufsize, readbytes); + if (ret == 1) + return 1; + + err = SSL_get_error(ssl, ret); + if (err != SSL_ERROR_WANT_READ) { + TEST_error("SSL_read_ex failed with error %d", err); + return 0; + } + /* SSL_ERROR_WANT_READ: retry the poll/read cycle */ + } + + TEST_error("dtls_read_with_retry exhausted retries"); + return 0; +} + +/* + * Helper to create a DTLS listener with real UDP sockets. + * + * This sets up: + * - Server UDP socket bound to loopback with ephemeral port + * - DTLS listener attached to that socket (with SSL_listen() called) + * + * Returns 1 on success, 0 on failure. + * On success, caller is responsible for cleanup using the returned pointers/fds. + */ +static int create_dtls_listener_unconfigured(SSL_CTX *sctx, uint64_t listener_flags, + SSL **listener, BIO_ADDR **server_addr, int *server_fd) +{ + BIO *listener_bio = NULL; + struct in_addr ina; + union BIO_sock_info_u info; + int ret = 0; + + *listener = NULL; + *server_addr = NULL; + *server_fd = -1; + + ina.s_addr = htonl(INADDR_LOOPBACK); + + /* Create and bind server UDP socket */ + *server_fd = BIO_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0); + if (!TEST_int_ge(*server_fd, 0)) + goto err; + + if (!TEST_true(BIO_socket_nbio(*server_fd, 1))) + goto err; + + *server_addr = BIO_ADDR_new(); + if (!TEST_ptr(*server_addr)) + goto err; + + if (!TEST_true(BIO_ADDR_rawmake(*server_addr, AF_INET, &ina, sizeof(ina), 0))) + goto err; + + if (!TEST_true(BIO_bind(*server_fd, *server_addr, 0))) + goto err; + + /* Get the actual bound address (with assigned port) */ + info.addr = *server_addr; + if (!TEST_true(BIO_sock_info(*server_fd, BIO_SOCK_INFO_ADDRESS, &info))) + goto err; + + /* Create listener BIO and attach to listener */ + listener_bio = BIO_new_dgram(*server_fd, BIO_NOCLOSE); + if (!TEST_ptr(listener_bio)) + goto err; + + if (!TEST_ptr(*listener = SSL_new_listener(sctx, listener_flags))) + goto err; + + SSL_set_bio(*listener, listener_bio, listener_bio); + listener_bio = NULL; + + /* Start listening */ + if (!TEST_int_eq(SSL_listen(*listener), 1)) + goto err; + + ret = 1; + +err: + BIO_free(listener_bio); + if (ret == 0) { + SSL_free(*listener); + BIO_ADDR_free(*server_addr); + if (*server_fd >= 0) + BIO_closesocket(*server_fd); + *listener = NULL; + *server_addr = NULL; + *server_fd = -1; + } + return ret; +} + +/* + * As create_dtls_listener_unconfigured(), but also opts out of blocking mode. + * + * These tests drive both ends of a handshake from a single thread, so the server + * side must not block: a blocking read would wait for a client which only this + * thread can advance. A listener is blocking by default, so opt out here rather + * than in each test, and note that connections accepted from it inherit this. + * + * A test which needs to observe the default, or to exercise blocking mode, should + * use create_dtls_listener_unconfigured() and configure what it needs. + */ +static int create_dtls_listener(SSL_CTX *sctx, uint64_t listener_flags, + SSL **listener, BIO_ADDR **server_addr, int *server_fd) +{ + if (!create_dtls_listener_unconfigured(sctx, listener_flags, listener, + server_addr, server_fd)) + return 0; + + if (!TEST_true(SSL_set_blocking_mode(*listener, 0))) { + SSL_free(*listener); + BIO_ADDR_free(*server_addr); + if (*server_fd >= 0) + BIO_closesocket(*server_fd); + *listener = NULL; + *server_addr = NULL; + *server_fd = -1; + return 0; + } + + return 1; +} + +/* + * Helper to create a DTLS client connected to a server address. + * + * This sets up: + * - Client UDP socket + * - Client SSL connected to the server address + * + * Returns 1 on success, 0 on failure. + * On success, caller is responsible for cleanup using the returned pointers/fds. + */ +static int create_dtls_client_for_addr(SSL_CTX *cctx, const BIO_ADDR *server_addr, + SSL **clientssl, int *client_fd) +{ + BIO *c_bio = NULL; + int ret = 0; + + *clientssl = NULL; + *client_fd = -1; + + /* Create client UDP socket */ + *client_fd = BIO_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0); + if (!TEST_int_ge(*client_fd, 0)) + goto err; + + if (!TEST_true(BIO_socket_nbio(*client_fd, 1))) + goto err; + + c_bio = BIO_new_dgram(*client_fd, BIO_NOCLOSE); + if (!TEST_ptr(c_bio)) + goto err; + + if (!TEST_true(BIO_dgram_set_peer(c_bio, server_addr))) + goto err; + + /* Create client SSL and attach BIO */ + if (!TEST_ptr(*clientssl = SSL_new(cctx))) + goto err; + + SSL_set_bio(*clientssl, c_bio, c_bio); + c_bio = NULL; + + ret = 1; + +err: + BIO_free(c_bio); + if (ret == 0) { + SSL_free(*clientssl); + if (*client_fd >= 0) + BIO_closesocket(*client_fd); + *clientssl = NULL; + *client_fd = -1; + } + return ret; +} + +#ifndef OPENSSL_NO_DTLS1_3 +/* + * Helper to create a DTLS client with a bound local address. + * + * Similar to create_dtls_client_for_addr but also binds to an ephemeral + * local port so the client can be identified by its source address. + * This is useful for tests that need to match accepted server connections + * back to their corresponding clients. + * + * Returns 1 on success, 0 on failure. + * On success, caller is responsible for cleanup using the returned pointers/fds. + * The local_addr will be filled with the actual bound address (including port). + */ +static int create_dtls_client_bound(SSL_CTX *cctx, const BIO_ADDR *server_addr, + SSL **clientssl, int *client_fd, BIO_ADDR *local_addr) +{ + BIO *c_bio = NULL; + struct in_addr ina; + union BIO_sock_info_u info; + int ret = 0; + + *clientssl = NULL; + *client_fd = -1; + + ina.s_addr = htonl(INADDR_LOOPBACK); + + /* Create client UDP socket */ + *client_fd = BIO_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0); + if (!TEST_int_ge(*client_fd, 0)) + goto err; + + if (!TEST_true(BIO_socket_nbio(*client_fd, 1))) + goto err; + + /* Bind to ephemeral port so we can identify this client later */ + if (!TEST_true(BIO_ADDR_rawmake(local_addr, AF_INET, &ina, sizeof(ina), 0))) + goto err; + + if (!TEST_true(BIO_bind(*client_fd, local_addr, 0))) + goto err; + + /* Get the actual assigned port */ + info.addr = local_addr; + if (!TEST_true(BIO_sock_info(*client_fd, BIO_SOCK_INFO_ADDRESS, &info))) + goto err; + + c_bio = BIO_new_dgram(*client_fd, BIO_NOCLOSE); + if (!TEST_ptr(c_bio)) + goto err; + + if (!TEST_true(BIO_dgram_set_peer(c_bio, server_addr))) + goto err; + + /* Create client SSL and attach BIO */ + if (!TEST_ptr(*clientssl = SSL_new(cctx))) + goto err; + + SSL_set_bio(*clientssl, c_bio, c_bio); + c_bio = NULL; + + ret = 1; + +err: + BIO_free(c_bio); + if (ret == 0) { + SSL_free(*clientssl); + if (*client_fd >= 0) + BIO_closesocket(*client_fd); + *clientssl = NULL; + *client_fd = -1; + } + return ret; +} +#endif /* OPENSSL_NO_DTLS1_3 */ + +/* + * Helper to create a DTLS listener and client using memory BIOs. + * + * This uses BIO_new_bio_dgram_pair() to create a connected pair of dgram BIOs + * for in-memory testing without real sockets. + */ +static int create_dtls_listener_and_client_mem(SSL_CTX *sctx, SSL_CTX *cctx, + uint64_t listener_flags, + SSL **listener, SSL **clientssl, + BIO_ADDR **client_addr) +{ + BIO *server_bio = NULL, *client_bio = NULL; + BIO_ADDR *server_addr = NULL; + BIO_ADDR *client_local_addr = NULL; + struct in_addr ina; + int ret = 0; + int bio_caps = BIO_DGRAM_CAP_HANDLES_DST_ADDR | BIO_DGRAM_CAP_HANDLES_SRC_ADDR; + + *listener = NULL; + *clientssl = NULL; + *client_addr = NULL; + + /* Create dgram BIO pair for in-memory communication */ + if (!TEST_int_eq(BIO_new_bio_dgram_pair(&server_bio, 0, &client_bio, 0), 1)) + goto err; + + /* Set capabilities on both BIOs to support addressed mode */ + if (!TEST_true(BIO_dgram_set_caps(server_bio, bio_caps)) + || !TEST_true(BIO_dgram_set_caps(client_bio, bio_caps))) + goto err; + + ina.s_addr = htonl(INADDR_LOOPBACK); + + /* Create and set server's local address (127.0.0.1:54321) */ + if (!TEST_ptr(server_addr = BIO_ADDR_new())) + goto err; + if (!TEST_true(BIO_ADDR_rawmake(server_addr, AF_INET, &ina, + sizeof(ina), htons(54321)))) + goto err; + if (!TEST_int_eq(BIO_dgram_set0_local_addr(server_bio, server_addr), 1)) + goto err; + server_addr = NULL; /* ownership transferred */ + + /* Create and set client's local address (127.0.0.1:12345) */ + if (!TEST_ptr(client_local_addr = BIO_ADDR_new())) + goto err; + if (!TEST_true(BIO_ADDR_rawmake(client_local_addr, AF_INET, &ina, + sizeof(ina), htons(12345)))) + goto err; + if (!TEST_int_eq(BIO_dgram_set0_local_addr(client_bio, client_local_addr), 1)) + goto err; + client_local_addr = NULL; /* ownership transferred */ + + /* Create the listener and attach the server BIO */ + if (!TEST_ptr(*listener = SSL_new_listener(sctx, listener_flags))) + goto err; + + SSL_set_bio(*listener, server_bio, server_bio); + server_bio = NULL; /* ownership transferred */ + + /* Start listening */ + if (!TEST_int_eq(SSL_listen(*listener), 1)) + goto err; + + /* Create client SSL */ + if (!TEST_ptr(*clientssl = SSL_new(cctx))) + goto err; + + /* + * NOTE: For regular DTLS clients with dgram pair BIOs, we do NOT call + * SSL_set1_initial_peer_addr(). That function is for listener-created + * connections. For dgram pairs, the BIOs are already connected and + * BIO_write() will work without an explicit peer address. + */ + + /* Attach the client BIO */ + SSL_set_bio(*clientssl, client_bio, client_bio); + client_bio = NULL; /* ownership transferred */ + + /* Create the returned client_addr for the caller */ + if (!TEST_ptr(*client_addr = BIO_ADDR_new())) + goto err; + if (!TEST_true(BIO_ADDR_rawmake(*client_addr, AF_INET, &ina, + sizeof(ina), htons(12345)))) + goto err; + + ret = 1; + +err: + BIO_free(server_bio); + BIO_free(client_bio); + BIO_ADDR_free(server_addr); + BIO_ADDR_free(client_local_addr); + if (ret == 0) { + SSL_free(*listener); + SSL_free(*clientssl); + BIO_ADDR_free(*client_addr); + *listener = NULL; + *clientssl = NULL; + *client_addr = NULL; + } + return ret; +} + +/* + * Test SSL_new_listener for DTLS. + * Verifies that a DTLS listener can be created from a DTLS context. + */ +static int test_dtls_new_listener(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + /* Create a DTLS listener */ + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto err; + /* Verify the listener is valid */ + if (!TEST_true(SSL_is_dtls(listener))) + goto err; + success = 1; +err: + SSL_free(listener); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test BIO management for DTLS listener. + * Tests SSL_set0_rbio, SSL_set0_wbio, SSL_get_rbio, SSL_get_wbio, and SSL_set_bio. + */ +static int test_dtls_listener_bio(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + BIO *bio = NULL; + BIO *bio2 = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto err; + + /* Initially, there should be no BIO */ + if (!TEST_ptr_null(SSL_get_rbio(listener)) + || !TEST_ptr_null(SSL_get_wbio(listener))) + goto err; + + /* Test SSL_set0_rbio/SSL_get_rbio */ + if (!TEST_ptr(bio = BIO_new(BIO_s_mem()))) + goto err; + SSL_set0_rbio(listener, bio); + if (!TEST_ptr_eq(SSL_get_rbio(listener), bio)) + goto err; + /* bio is now owned by listener, will be freed by SSL_free */ + + /* Test SSL_set0_wbio/SSL_get_wbio */ + if (!TEST_ptr(bio2 = BIO_new(BIO_s_mem()))) + goto err; + SSL_set0_wbio(listener, bio2); + if (!TEST_ptr_eq(SSL_get_wbio(listener), bio2)) + goto err; + /* bio2 is now owned by listener, will be freed by SSL_free */ + + /* Clear pointers since ownership transferred - SSL_free will clean up */ + bio = NULL; + bio2 = NULL; + + success = 1; +err: + SSL_free(listener); + SSL_CTX_free(ctx); + BIO_free(bio); + BIO_free(bio2); + return success; +} + +/* + * Test SSL_new_listener with DTLS 1.2 only context. + * Verifies that listeners work with DTLS 1.2. + */ +#ifndef OPENSSL_NO_DTLS1_2 +static int test_dtls_new_listener_dtls12(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method())) + || !TEST_true(SSL_CTX_set_min_proto_version(ctx, DTLS1_2_VERSION)) + || !TEST_true(SSL_CTX_set_max_proto_version(ctx, DTLS1_2_VERSION))) + goto err; + + /* Create a DTLS listener */ + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto err; + + /* Verify the listener is valid */ + if (!TEST_true(SSL_is_dtls(listener))) + goto err; + + if (!TEST_true(SSL_is_listener(listener))) + goto err; + + success = 1; +err: + SSL_free(listener); + SSL_CTX_free(ctx); + return success; +} +#endif /* OPENSSL_NO_DTLS1_2 */ + +/* + * Test SSL_get0_listener and SSL_is_listener on a non-listener DTLS SSL object. + */ +static int test_dtls_get0_listener_non_dtls_listener(void) +{ + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + /* Create a DTLS connection object */ + if (!TEST_ptr(ssl = SSL_new(ctx))) + goto err; + /* A normal DTLS connection has no associated listener */ + if (!TEST_ptr_null(SSL_get0_listener(ssl))) + goto err; + /* And it is not itself a listener */ + if (!TEST_int_eq(SSL_is_listener(ssl), 0)) + goto err; + success = 1; +err: + SSL_free(ssl); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test SSL_get0_listener and SSL_is_listener on a DTLS_LISTENER object. + */ +static int test_dtls_get0_listener_listener(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + /* Create a DTLS listener */ + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto err; + /* The listener should identify itself as the listener */ + if (!TEST_ptr_eq(SSL_get0_listener(listener), listener)) + goto err; + /* And SSL_is_listener should confirm it */ + if (!TEST_int_eq(SSL_is_listener(listener), 1)) + goto err; + success = 1; +err: + SSL_free(listener); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test SSL_listen on a DTLS_LISTENER object. + * The first call should set listening=1 and return 1. + */ +static int test_dtls_listen_basic(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto err; + /* SSL_listen on a fresh listener must succeed */ + if (!TEST_int_eq(SSL_listen(listener), 1)) + goto err; + success = 1; +err: + SSL_free(listener); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test that SSL_listen returns 0 when given a normal DTLS Connection + */ +static int test_dtls_listen_wrong_type(void) +{ + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + if (!TEST_ptr(ssl = SSL_new(ctx))) + goto err; + + if (!TEST_int_eq(SSL_listen(ssl), 0)) + goto err; + success = 1; +err: + SSL_free(ssl); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test SSL_accept_connection with a non-listener DTLS SSL object. + */ +static int test_dtls_accept_connection_wrong_type(void) +{ + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + if (!TEST_ptr(ssl = SSL_new(ctx))) + goto err; + /* IS_DTLS routes to ossl_dtls_accept_connection, which must reject this */ + if (!TEST_ptr_null(SSL_accept_connection(ssl, SSL_ACCEPT_CONNECTION_NO_BLOCK))) + goto err; + success = 1; +err: + SSL_free(ssl); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test SSL_accept_connection on an empty queue with NO_BLOCK. + * No connections have been queued, so NULL must be returned immediately. + */ +static int test_dtls_accept_connection_empty_no_block(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto err; + /* Empty queue + NO_BLOCK -> NULL, no error */ + if (!TEST_ptr_null(SSL_accept_connection(listener, + SSL_ACCEPT_CONNECTION_NO_BLOCK))) + goto err; + success = 1; +err: + SSL_free(listener); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test SSL_get_accept_connection_queue_len with a non-listener DTLS object. + * A plain SSL_CONNECTION must return 0. + */ +static int test_dtls_queue_len_wrong_type(void) +{ + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + if (!TEST_ptr(ssl = SSL_new(ctx))) + goto err; + if (!TEST_size_t_eq(SSL_get_accept_connection_queue_len(ssl), 0)) + goto err; + success = 1; +err: + SSL_free(ssl); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test SSL_get_accept_connection_queue_len on an empty listener. + * A freshly created listener with no queued connections must return 0. + */ +static int test_dtls_queue_len_empty(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto err; + if (!TEST_size_t_eq(SSL_get_accept_connection_queue_len(listener), 0)) + goto err; + success = 1; +err: + SSL_free(listener); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test SSL_accept_connection with no net_bio and the + * SSL_ACCEPT_CONNECTION_NO_BLOCK flag, so that the caller is not asking to + * wait. The function must return NULL immediately without raising an error, + * the absence of a BIO being indistinguishable from having nothing queued. + */ +static int test_dtls_accept_connection_no_bio_no_block(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + SSL *conn = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto err; + + /* No BIO has been set on the listener */ + + ERR_clear_error(); + conn = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + + /* Must return NULL - no connection available, no blocking */ + if (!TEST_ptr_null(conn)) + goto err; + + /* + * With NO_BLOCK, returning NULL without an error is correct behavior. + * it means "no connection available, try again later". + * This is not an error condition, just an indication to poll/retry. + */ + if (!TEST_int_eq((int)ERR_peek_error(), 0)) + goto err; + + success = 1; +err: + SSL_free(conn); + SSL_free(listener); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test SSL_accept_connection with no net_bio and without the + * SSL_ACCEPT_CONNECTION_NO_BLOCK flag, so that the caller is asking to wait. + * When there is no BIO the function must return NULL and raise + * SSL_R_BIO_NOT_SET rather than waiting, since nothing could ever arrive. + */ +static int test_dtls_accept_connection_no_bio_block(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + SSL *conn = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto err; + + /* No BIO has been set on the listener */ + + ERR_clear_error(); + conn = SSL_accept_connection(listener, 0); + + /* Must return NULL */ + if (!TEST_ptr_null(conn)) + goto err; + + /* Must have raised SSL_R_BIO_NOT_SET */ + if (!TEST_int_eq((int)ERR_GET_REASON(ERR_peek_error()), SSL_R_BIO_NOT_SET)) + goto err; + + success = 1; +err: + ERR_clear_error(); + SSL_free(conn); + SSL_free(listener); + SSL_CTX_free(ctx); + return success; +} + +#ifndef OPENSSL_NO_DTLS1_3 +/* + * Test DTLS 1.3 connection WITH HelloRetryRequest (HRR). + * + * This test uses SSL_new_listener API to create a DTLS 1.3 server that + * performs a HelloRetryRequest cookie exchange before the handshake completes. + * The server is configured to always request a cookie via HRR using the + * stateless cookie callbacks. + * + * Flow: + * 1. Create SSL contexts for DTLS 1.3 only + * 2. Create listener (address validation is on by default) and client using helper + * 3. Drive connection loop: client SSL_connect() + poll listener for IC event + * 4. SSL_accept_connection() returns server SSL after HRR cookie validation + * 5. Complete handshake with create_ssl_connection() + * 6. Verify DTLS 1.3 is negotiated + * 7. Exchange bidirectional application data + */ +static int test_dtls13_connection_with_hrr(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + BIO_ADDR *client_addr = NULL; + const char msg[] = "Hello DTLS 1.3 with HRR"; + const char reply[] = "Reply from server"; + char buf[64]; + size_t written, readbytes; + int testresult = 0; + int retc = -1, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr = 0; + + /* Both server and client restricted to DTLS 1.3 only */ + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + DTLS1_3_VERSION, DTLS1_3_VERSION, + &sctx, &cctx, cert, privkey))) + goto end; + + /* Create listener and client using memory BIO helper */ + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + /* + * Drive the connection until SSL_accept_connection returns a server SSL. + * We need to interleave client SSL_connect() calls with polling the listener + * since both sides need to make progress for the HRR exchange to complete. + */ + SSL_set_connect_state(clientssl); + while (serverssl == NULL) { + if (++abortctr > 100) { + TEST_error("HRR cookie exchange loop did not converge"); + goto end; + } + + /* Advance the client state machine */ + retc = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, retc); + if (retc <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect failed (err %d)", err_code); + goto end; + } + + /* Poll the listener for incoming connection */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + serverssl = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + + if (!TEST_ptr(serverssl)) + goto end; + + /* + * SSL_accept_connection() returns after cookie validation but before the + * handshake is complete. We need to finish the handshake ourselves. + */ + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + /* Confirm DTLS 1.3 was negotiated */ + if (!TEST_int_eq(SSL_version(serverssl), DTLS1_3_VERSION) + || !TEST_int_eq(SSL_version(clientssl), DTLS1_3_VERSION)) + goto end; + + /* Exchange application data to verify the connection works */ + if (!TEST_true(SSL_write_ex(clientssl, msg, sizeof(msg), &written)) + || !TEST_size_t_eq(written, sizeof(msg))) + goto end; + + if (!TEST_true(dtls_read_with_retry(serverssl, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(msg)) + || !TEST_mem_eq(buf, readbytes, msg, sizeof(msg))) + goto end; + + /* Verify bidirectional: server sends, client receives */ + if (!TEST_true(SSL_write_ex(serverssl, reply, sizeof(reply), &written)) + || !TEST_size_t_eq(written, sizeof(reply))) + goto end; + + if (!TEST_true(dtls_read_with_retry(clientssl, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(reply)) + || !TEST_mem_eq(buf, readbytes, reply, sizeof(reply))) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test DTLS 1.3 connection WITHOUT HelloRetryRequest (no HRR). + * + * This test uses SSL_new_listener API with the SSL_LISTENER_FLAG_NO_VALIDATE + * flag to skip the HRR cookie exchange. The connection is added to the accept + * queue immediately after receiving the first ClientHello. + * + * Flow: + * 1. Create SSL contexts for DTLS 1.3 only + * 2. Create listener (with NO_VALIDATE flag) and client using helper + * 3. Drive connection loop: client SSL_connect() + poll listener for IC event + * 4. SSL_accept_connection() returns server SSL immediately after ClientHello + * 5. Complete handshake with create_ssl_connection() + * 6. Verify DTLS 1.3 is negotiated + * 7. Exchange bidirectional application data + */ +static int test_dtls13_connection_without_hrr(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + BIO_ADDR *client_addr = NULL; + const char msg[] = "Hello DTLS 1.3 without HRR"; + const char reply[] = "Reply from server"; + char buf[64]; + size_t written, readbytes; + int testresult = 0; + int retc = -1, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr = 0; + + /* Both server and client restricted to DTLS 1.3 only */ + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + DTLS1_3_VERSION, DTLS1_3_VERSION, + &sctx, &cctx, cert, privkey))) + goto end; + + /* + * Create listener and client using memory BIO helper. + * Use NO_VALIDATE flag to skip HRR - server won't send HelloRetryRequest. + */ + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_NO_VALIDATE | SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + /* + * Drive the connection until SSL_accept_connection returns a server SSL. + * Without HRR (using SSL_LISTENER_FLAG_NO_VALIDATE), SSL_accept_connection + * returns immediately after receiving the first ClientHello, but BEFORE the + * handshake is complete. The application must finish the handshake. + */ + SSL_set_connect_state(clientssl); + while (serverssl == NULL) { + if (++abortctr > 100) { + TEST_error("Connection loop did not converge"); + goto end; + } + + /* Advance the client state machine */ + retc = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, retc); + if (retc <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect failed (err %d)", err_code); + goto end; + } + + /* Poll the listener for incoming connection */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + serverssl = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + + if (!TEST_ptr(serverssl)) + goto end; + + /* + * SSL_accept_connection() returns after receiving ClientHello but before the + * handshake is complete. We need to finish the handshake ourselves. + */ + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + /* Confirm DTLS 1.3 was negotiated */ + if (!TEST_int_eq(SSL_version(serverssl), DTLS1_3_VERSION) + || !TEST_int_eq(SSL_version(clientssl), DTLS1_3_VERSION)) + goto end; + + /* Exchange application data to verify the connection works */ + if (!TEST_true(SSL_write_ex(clientssl, msg, sizeof(msg), &written)) + || !TEST_size_t_eq(written, sizeof(msg))) + goto end; + + if (!TEST_true(dtls_read_with_retry(serverssl, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(msg)) + || !TEST_mem_eq(buf, readbytes, msg, sizeof(msg))) + goto end; + + /* Verify bidirectional: server sends, client receives */ + if (!TEST_true(SSL_write_ex(serverssl, reply, sizeof(reply), &written)) + || !TEST_size_t_eq(written, sizeof(reply))) + goto end; + + if (!TEST_true(dtls_read_with_retry(clientssl, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(reply)) + || !TEST_mem_eq(buf, readbytes, reply, sizeof(reply))) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +#ifndef OPENSSL_NO_DTLS1_2 +/* + * Test mixed DTLS versions: DTLS 1.2 with HVR and DTLS 1.3 with HRR. + * + * This test demonstrates that a single listener can handle both DTLS 1.2 + * and DTLS 1.3 clients, each using their appropriate cookie exchange mechanism: + * - DTLS 1.2 clients use HelloVerifyRequest (HVR) + * - DTLS 1.3 clients use HelloRetryRequest (HRR) + * + * The test: + * 1. Creates a listener that supports both DTLS 1.2 and DTLS 1.3 + * 2. Connects a DTLS 1.2-only client with HVR exchange + * 3. Connects a DTLS 1.3-only client with HRR exchange + * 4. Verifies both connections negotiate the expected version + * 5. Verifies data can be exchanged on both connections + */ +static int test_dtls_mixed_12_hvr_and_13_hrr(void) +{ + SSL_CTX *sctx = NULL; + SSL_CTX *cctx_12 = NULL, *cctx_13 = NULL; + SSL *listener = NULL; + SSL *server_12 = NULL, *client_12 = NULL; + SSL *server_13 = NULL, *client_13 = NULL; + BIO_ADDR *server_addr = NULL; + int server_fd = -1; + int client_12_fd = -1, client_13_fd = -1; + const char msg_12[] = "Hello DTLS 1.2"; + const char msg_13[] = "Hello DTLS 1.3"; + char buf[32]; + size_t written, readbytes; + int testresult = 0; + int retc, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr; + + /* + * Create server context that supports both DTLS 1.2 and DTLS 1.3. + * Note: We need to create separate client contexts for version pinning. + */ + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + DTLS1_2_VERSION, DTLS1_3_VERSION, + &sctx, &cctx_12, cert, privkey))) + goto end; + + /* Pin the first client context to DTLS 1.2 only */ + if (!TEST_true(SSL_CTX_set_max_proto_version(cctx_12, DTLS1_2_VERSION))) + goto end; + + /* Create a second client context for DTLS 1.3 only */ + cctx_13 = SSL_CTX_new(DTLS_client_method()); + if (!TEST_ptr(cctx_13)) + goto end; + if (!TEST_true(SSL_CTX_set_min_proto_version(cctx_13, DTLS1_3_VERSION)) + || !TEST_true(SSL_CTX_set_max_proto_version(cctx_13, DTLS1_3_VERSION))) + goto end; + + /* + * Create a DTLS listener with both HVR and HRR requirements. + * This ensures DTLS 1.2 clients go through HVR and DTLS 1.3 clients + * go through HRR cookie validation. + */ + if (!TEST_true(create_dtls_listener(sctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &server_addr, &server_fd))) + goto end; + + /* + * --- Phase 1: Connect DTLS 1.2 client with HVR --- + */ + + /* Create DTLS 1.2 client */ + if (!TEST_true(create_dtls_client_for_addr(cctx_12, server_addr, + &client_12, &client_12_fd))) + goto end; + + /* Drive the DTLS 1.2 connection with HVR exchange */ + retc = -1; + abortctr = 0; + SSL_set_connect_state(client_12); + while (server_12 == NULL) { + if (++abortctr > 100) { + TEST_error("DTLS 1.2 HVR exchange loop did not converge"); + goto end; + } + + retc = SSL_connect(client_12); + err_code = SSL_get_error(client_12, retc); + if (retc <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect (DTLS 1.2) failed (err %d)", err_code); + goto end; + } + + /* Poll the listener for incoming connection with short timeout */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 100000; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + server_12 = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + + if (!TEST_ptr(server_12)) + goto end; + + /* + * SSL_accept_connection() returns after cookie validation but before the + * handshake is complete. We need to finish the handshake ourselves. + */ + if (!TEST_true(create_ssl_connection(server_12, client_12, SSL_ERROR_NONE))) + goto end; + + /* Verify DTLS 1.2 was negotiated */ + if (!TEST_int_eq(SSL_version(server_12), DTLS1_2_VERSION) + || !TEST_int_eq(SSL_version(client_12), DTLS1_2_VERSION)) + goto end; + + /* + * --- Phase 2: Connect DTLS 1.3 client with HRR --- + */ + + /* Create DTLS 1.3 client */ + if (!TEST_true(create_dtls_client_for_addr(cctx_13, server_addr, + &client_13, &client_13_fd))) + goto end; + + /* Drive the DTLS 1.3 connection with HRR exchange */ + retc = -1; + abortctr = 0; + SSL_set_connect_state(client_13); + while (server_13 == NULL) { + if (++abortctr > 100) { + TEST_error("DTLS 1.3 HRR exchange loop did not converge"); + goto end; + } + + retc = SSL_connect(client_13); + err_code = SSL_get_error(client_13, retc); + if (retc <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect (DTLS 1.3) failed (err %d)", err_code); + goto end; + } + + /* Poll the listener for incoming connection with short timeout */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 100000; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + server_13 = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + + if (!TEST_ptr(server_13)) + goto end; + + /* + * SSL_accept_connection() returns after cookie validation but before the + * handshake is complete. We need to finish the handshake ourselves. + */ + if (!TEST_true(create_ssl_connection(server_13, client_13, SSL_ERROR_NONE))) + goto end; + + /* Verify DTLS 1.3 was negotiated */ + if (!TEST_int_eq(SSL_version(server_13), DTLS1_3_VERSION) + || !TEST_int_eq(SSL_version(client_13), DTLS1_3_VERSION)) + goto end; + + /* + * --- Phase 3: Verify both connections can exchange data --- + */ + + /* Exchange data on DTLS 1.2 connection */ + if (!TEST_true(SSL_write_ex(client_12, msg_12, sizeof(msg_12), &written)) + || !TEST_size_t_eq(written, sizeof(msg_12))) + goto end; + memset(buf, 0, sizeof(buf)); + if (!TEST_true(dtls_read_with_retry(server_12, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(msg_12)) + || !TEST_mem_eq(buf, readbytes, msg_12, sizeof(msg_12))) + goto end; + + /* Exchange data on DTLS 1.3 connection */ + if (!TEST_true(SSL_write_ex(client_13, msg_13, sizeof(msg_13), &written)) + || !TEST_size_t_eq(written, sizeof(msg_13))) + goto end; + memset(buf, 0, sizeof(buf)); + if (!TEST_true(dtls_read_with_retry(server_13, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(msg_13)) + || !TEST_mem_eq(buf, readbytes, msg_13, sizeof(msg_13))) + goto end; + + testresult = 1; +end: + SSL_free(server_12); + SSL_free(client_12); + SSL_free(server_13); + SSL_free(client_13); + SSL_free(listener); + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + if (client_12_fd >= 0) + BIO_closesocket(client_12_fd); + if (client_13_fd >= 0) + BIO_closesocket(client_13_fd); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx_12); + SSL_CTX_free(cctx_13); + return testresult; +} +#endif /* OPENSSL_NO_DTLS1_2 */ + +/* + * Test true concurrent multi-client with real UDP sockets (shared socket). + * + * This test verifies that: + * 1. A DTLS listener can accept multiple concurrent clients using real sockets + * 2. All connections share the listener's socket via the demux + * 3. All connections can exchange data simultaneously + * 4. The listener continues to accept new connections while others are active + */ +static int test_dtls_concurrent_clients_real_sockets(void) +{ + SSL_CTX *sctx = NULL; + SSL_CTX *cctx = NULL; + SSL *listener = NULL; + SSL *server1 = NULL, *client1 = NULL; + SSL *server2 = NULL, *client2 = NULL; + SSL *accepted1 = NULL, *accepted2 = NULL; + BIO_ADDR *server_addr = NULL; + BIO_ADDR *client1_local_addr = NULL; + BIO_ADDR *client2_local_addr = NULL; + BIO_ADDR *server_peer_addr = NULL; + int server_fd = -1; + int client1_fd = -1, client2_fd = -1; + const char msg1[] = "Hello from client 1"; + const char msg2[] = "Hello from client 2"; + const char reply1[] = "Reply to client 1"; + const char reply2[] = "Reply to client 2"; + char buf[64]; + size_t written, readbytes; + int testresult = 0; + int ret, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr; + + /* Create server and client contexts */ + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + /* + * Create DTLS listener with both HVR and HRR requirements. + * This ensures address validation for both DTLS 1.2 and 1.3 clients. + */ + if (!TEST_true(create_dtls_listener(sctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &server_addr, &server_fd))) + goto end; + + if (!TEST_int_gt(BIO_ADDR_rawport(server_addr), 0)) + goto end; + + /* + * Allocate BIO_ADDRs for tracking client local addresses + */ + client1_local_addr = BIO_ADDR_new(); + client2_local_addr = BIO_ADDR_new(); + server_peer_addr = BIO_ADDR_new(); + if (!TEST_ptr(client1_local_addr) || !TEST_ptr(client2_local_addr) + || !TEST_ptr(server_peer_addr)) + goto end; + + /* + * --- Create Client 1 --- + */ + if (!TEST_true(create_dtls_client_bound(cctx, server_addr, + &client1, &client1_fd, client1_local_addr))) + goto end; + + /* + * --- Create Client 2 --- + */ + if (!TEST_true(create_dtls_client_bound(cctx, server_addr, + &client2, &client2_fd, client2_local_addr))) + goto end; + + /* + * --- Drive both clients concurrently through handshake --- + * + * We alternate between driving client1 and client2, while also + * accepting connections on the listener. This simulates true + * concurrent operation. + */ + SSL_set_connect_state(client1); + SSL_set_connect_state(client2); + abortctr = 0; + while (accepted1 == NULL || accepted2 == NULL) { + if (++abortctr > 500) { + TEST_error("Concurrent handshake loop did not converge"); + goto end; + } + + /* Drive client 1 if not yet connected */ + if (accepted1 == NULL || accepted2 == NULL) { + ret = SSL_connect(client1); + err_code = SSL_get_error(client1, ret); + if (ret <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect (client1) failed: err=%d", err_code); + goto end; + } + } + + /* Drive client 2 if not yet connected */ + if (accepted1 == NULL || accepted2 == NULL) { + ret = SSL_connect(client2); + err_code = SSL_get_error(client2, ret); + if (ret <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect (client2) failed: err=%d", err_code); + goto end; + } + } + + /* Poll the listener for incoming connection with short timeout */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 100000; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* Accept connections from listener if poll indicates availability */ + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) { + if (accepted1 == NULL) + accepted1 = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + else if (accepted2 == NULL) + accepted2 = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + } + + if (!TEST_ptr(accepted1) || !TEST_ptr(accepted2)) + goto end; + + /* + * Match accepted connections to clients based on peer address. + * The server's peer address should match the client's local address. + */ + if (!TEST_true(SSL_get_peer_addr(accepted1, server_peer_addr))) { + TEST_error("Could not get peer addr from accepted1"); + goto end; + } + + /* Check if accepted1's peer matches client1's local address */ + if (BIO_ADDR_rawport(server_peer_addr) == BIO_ADDR_rawport(client1_local_addr)) { + server1 = accepted1; + server2 = accepted2; + } else { + /* accepted1's peer should match client2 */ + server1 = accepted2; + server2 = accepted1; + } + + /* Finish the handshakes for both connections */ + if (!TEST_true(create_ssl_connection(server1, client1, SSL_ERROR_NONE))) { + TEST_error("server1/client1 handshake failed"); + goto end; + } + + if (!TEST_true(create_ssl_connection(server2, client2, SSL_ERROR_NONE))) { + TEST_error("server2/client2 handshake failed"); + goto end; + } + + /* Client 1 sends to server 1 */ + if (!TEST_true(SSL_write_ex(client1, msg1, sizeof(msg1), &written)) + || !TEST_size_t_eq(written, sizeof(msg1))) { + TEST_error("client1 write failed"); + goto end; + } + + /* Client 2 sends to server 2 */ + if (!TEST_true(SSL_write_ex(client2, msg2, sizeof(msg2), &written)) + || !TEST_size_t_eq(written, sizeof(msg2))) { + TEST_error("client2 write failed"); + goto end; + } + + /* Server 1 reads from client 1 */ + memset(buf, 0, sizeof(buf)); + if (!TEST_true(dtls_read_with_retry(server1, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(msg1)) + || !TEST_mem_eq(buf, readbytes, msg1, sizeof(msg1))) { + TEST_error("server1 read failed or data mismatch"); + goto end; + } + + /* Server 2 reads from client 2 */ + memset(buf, 0, sizeof(buf)); + if (!TEST_true(dtls_read_with_retry(server2, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(msg2)) + || !TEST_mem_eq(buf, readbytes, msg2, sizeof(msg2))) { + TEST_error("server2 read failed or data mismatch"); + goto end; + } + + /* Server 1 replies to client 1 */ + if (!TEST_true(SSL_write_ex(server1, reply1, sizeof(reply1), &written)) + || !TEST_size_t_eq(written, sizeof(reply1))) { + TEST_error("server1 reply failed"); + goto end; + } + + /* Server 2 replies to client 2 */ + if (!TEST_true(SSL_write_ex(server2, reply2, sizeof(reply2), &written)) + || !TEST_size_t_eq(written, sizeof(reply2))) { + TEST_error("server2 reply failed"); + goto end; + } + + /* Client 1 receives reply using dtls_read_with_retry */ + memset(buf, 0, sizeof(buf)); + if (!TEST_true(dtls_read_with_retry(client1, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(reply1)) + || !TEST_mem_eq(buf, readbytes, reply1, sizeof(reply1))) { + TEST_error("client1 read reply failed or data mismatch"); + goto end; + } + + /* Client 2 receives reply using dtls_read_with_retry */ + memset(buf, 0, sizeof(buf)); + if (!TEST_true(dtls_read_with_retry(client2, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(reply2)) + || !TEST_mem_eq(buf, readbytes, reply2, sizeof(reply2))) { + TEST_error("client2 read reply failed or data mismatch"); + goto end; + } + + testresult = 1; + +end: + /* + * Note: server1/server2 are aliases to accepted1/accepted2 (just reordered), + * so only free accepted1/accepted2 to avoid double-free. + */ + SSL_free(accepted1); + SSL_free(accepted2); + SSL_free(client1); + SSL_free(client2); + SSL_free(listener); + BIO_ADDR_free(server_addr); + BIO_ADDR_free(client1_local_addr); + BIO_ADDR_free(client2_local_addr); + BIO_ADDR_free(server_peer_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + if (client1_fd >= 0) + BIO_closesocket(client1_fd); + if (client2_fd >= 0) + BIO_closesocket(client2_fd); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} +#endif /* OPENSSL_NO_DTLS1_3 */ + +#ifndef OPENSSL_NO_DTLS1_2 +/* + * Test DTLS 1.2 connection WITH HelloVerifyRequest (HVR). + * + * This test uses SSL_new_listener API to create a DTLS 1.2 server that + * performs a HelloVerifyRequest cookie exchange. The connection is added + * to the accept queue after cookie validation but before handshake completion. + * + * Flow: + * 1. Create SSL contexts for DTLS 1.2 only + * 2. Create listener (address validation is on by default) and client using helper + * 3. Drive connection loop: client SSL_connect() + poll listener for IC event + * 4. SSL_accept_connection() returns server SSL after HVR cookie validation + * 5. Complete handshake with create_ssl_connection() + * 6. Verify DTLS 1.2 is negotiated + * 7. Exchange bidirectional application data (client->server, server->client) + */ +static int test_dtls12_connection_with_hvr(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + BIO_ADDR *client_addr = NULL; + const char msg[] = "Hello DTLS 1.2 with HVR"; + const char reply[] = "Reply from server"; + char buf[64]; + size_t written, readbytes; + int testresult = 0; + int retc = -1, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr = 0; + + /* Both server and client restricted to DTLS 1.2 only */ + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + DTLS1_2_VERSION, DTLS1_2_VERSION, + &sctx, &cctx, cert, privkey))) + goto end; + + /* Create listener and client using memory BIO helper */ + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + /* + * Drive the connection until SSL_accept_connection returns a server SSL. + * For DTLS 1.2 with HVR, SSL_accept_connection returns AFTER cookie validation + * (i.e., after receiving the second ClientHello with valid cookie), but BEFORE + * the handshake is complete. The application must finish the handshake. + */ + SSL_set_connect_state(clientssl); + while (serverssl == NULL) { + if (++abortctr > 100) { + TEST_error("HVR cookie exchange loop did not converge"); + goto end; + } + + /* Advance the client state machine */ + retc = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, retc); + if (retc <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect failed (err %d)", err_code); + goto end; + } + + /* Poll the listener for incoming connection */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + serverssl = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + + if (!TEST_ptr(serverssl)) + goto end; + + /* + * SSL_accept_connection() returns after cookie validation but before the + * handshake is complete. We need to finish the handshake ourselves. + */ + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + /* Confirm DTLS 1.2 was negotiated */ + if (!TEST_int_eq(SSL_version(serverssl), DTLS1_2_VERSION) + || !TEST_int_eq(SSL_version(clientssl), DTLS1_2_VERSION)) + goto end; + + /* Exchange application data to verify the connection works */ + if (!TEST_true(SSL_write_ex(clientssl, msg, sizeof(msg), &written)) + || !TEST_size_t_eq(written, sizeof(msg))) + goto end; + + if (!TEST_true(dtls_read_with_retry(serverssl, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(msg)) + || !TEST_mem_eq(buf, readbytes, msg, sizeof(msg))) + goto end; + + /* Verify bidirectional: server sends, client receives */ + if (!TEST_true(SSL_write_ex(serverssl, reply, sizeof(reply), &written)) + || !TEST_size_t_eq(written, sizeof(reply))) + goto end; + + if (!TEST_true(dtls_read_with_retry(clientssl, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(reply)) + || !TEST_mem_eq(buf, readbytes, reply, sizeof(reply))) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test DTLS 1.2 connection WITHOUT HelloVerifyRequest (no HVR). + * + * This test uses SSL_new_listener API with the SSL_LISTENER_FLAG_NO_VALIDATE + * flag to skip the cookie validation/HVR exchange. The connection is added + * to the accept queue immediately after receiving the first ClientHello. + * + * Flow: + * 1. Create SSL contexts for DTLS 1.2 only + * 2. Create listener (with NO_VALIDATE flag) and client using helper + * 3. Drive connection loop: client SSL_connect() + poll listener for IC event + * 4. SSL_accept_connection() returns server SSL immediately after ClientHello + * 5. Complete handshake with create_ssl_connection() + * 6. Verify DTLS 1.2 is negotiated + * 7. Exchange bidirectional application data (client->server, server->client) + */ +static int test_dtls12_connection_without_hvr(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + BIO_ADDR *client_addr = NULL; + const char msg[] = "Hello DTLS 1.2 without HVR"; + const char reply[] = "Reply from server"; + char buf[64]; + size_t written, readbytes; + int testresult = 0; + int retc = -1, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr = 0; + + /* Both server and client restricted to DTLS 1.2 only */ + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + DTLS1_2_VERSION, DTLS1_2_VERSION, + &sctx, &cctx, cert, privkey))) + goto end; + + /* + * Create listener and client using memory BIO helper. + * Use NO_VALIDATE flag to skip HVR - server won't send HelloVerifyRequest. + */ + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_NO_VALIDATE | SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + /* + * Drive the connection until SSL_accept_connection returns a server SSL. + * Without HVR (using SSL_LISTENER_FLAG_NO_VALIDATE), SSL_accept_connection + * returns immediately after receiving the first ClientHello, but BEFORE the + * handshake is complete. The application must finish the handshake. + */ + SSL_set_connect_state(clientssl); + while (serverssl == NULL) { + if (++abortctr > 100) { + TEST_error("Connection loop did not converge"); + goto end; + } + + /* Advance the client state machine */ + retc = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, retc); + if (retc <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect failed (err %d)", err_code); + goto end; + } + + /* Poll the listener for incoming connection */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + serverssl = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + + if (!TEST_ptr(serverssl)) + goto end; + + /* + * SSL_accept_connection() returns after receiving ClientHello but before the + * handshake is complete. We need to finish the handshake ourselves. + */ + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + /* Confirm DTLS 1.2 was negotiated */ + if (!TEST_int_eq(SSL_version(serverssl), DTLS1_2_VERSION) + || !TEST_int_eq(SSL_version(clientssl), DTLS1_2_VERSION)) + goto end; + + /* Exchange application data to verify the connection works */ + if (!TEST_true(SSL_write_ex(clientssl, msg, sizeof(msg), &written)) + || !TEST_size_t_eq(written, sizeof(msg))) + goto end; + + if (!TEST_true(dtls_read_with_retry(serverssl, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(msg)) + || !TEST_mem_eq(buf, readbytes, msg, sizeof(msg))) + goto end; + + /* Verify bidirectional: server sends, client receives */ + if (!TEST_true(SSL_write_ex(serverssl, reply, sizeof(reply), &written)) + || !TEST_size_t_eq(written, sizeof(reply))) + goto end; + + if (!TEST_true(dtls_read_with_retry(clientssl, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(reply)) + || !TEST_mem_eq(buf, readbytes, reply, sizeof(reply))) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} +#endif /* OPENSSL_NO_DTLS1_2 */ + +/* + * Test SSL_get_peer_addr on a fresh SSL object with no peer. + * A connection that has not completed handshake should return 0. + */ +static int test_dtls_get_peer_addr_no_peer(void) +{ + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + BIO_ADDR *peer_addr = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + + if (!TEST_ptr(ssl = SSL_new(ctx))) + goto err; + + peer_addr = BIO_ADDR_new(); + if (!TEST_ptr(peer_addr)) + goto err; + + /* Fresh SSL has no peer, should return 0 */ + if (!TEST_int_eq(SSL_get_peer_addr(ssl, peer_addr), 0)) + goto err; + + success = 1; +err: + BIO_ADDR_free(peer_addr); + SSL_free(ssl); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test SSL_get_peer_addr on a listener object. + * A listener doesn't have a peer address, should return 0. + */ +static int test_dtls_get_peer_addr_listener(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + BIO_ADDR *peer_addr = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto err; + + peer_addr = BIO_ADDR_new(); + if (!TEST_ptr(peer_addr)) + goto err; + + /* Listener has no peer, should return 0 */ + if (!TEST_int_eq(SSL_get_peer_addr(listener, peer_addr), 0)) + goto err; + + success = 1; +err: + BIO_ADDR_free(peer_addr); + SSL_free(listener); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test SSL_new_listener with NULL context. + * Should return NULL and not crash. + */ +static int test_dtls_new_listener_null_ctx(void) +{ + SSL *listener = NULL; + int success = 0; + + /* SSL_new_listener with NULL ctx should return NULL */ + listener = SSL_new_listener(NULL, 0); + if (!TEST_ptr_null(listener)) + goto err; + + success = 1; +err: + SSL_free(listener); + return success; +} + +/* + * Test SSL_new_listener with a TLS (non-DTLS) context. + * Should return NULL because listeners are only for DTLS/QUIC. + */ +static int test_tls_new_listener_fails(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + int success = 0; + + /* Create a TLS context (not DTLS) */ + if (!TEST_ptr(ctx = SSL_CTX_new(TLS_server_method()))) + goto err; + + /* SSL_new_listener should fail for TLS contexts */ + listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD); + if (!TEST_ptr_null(listener)) + goto err; + + success = 1; +err: + SSL_free(listener); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test SSL_new_listener_from for DTLS. + * Currently SSL_new_listener_from is QUIC-only, so it should return NULL for DTLS. + */ +static int test_dtls_new_listener_from_returns_null(void) +{ + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + SSL *listener = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + + if (!TEST_ptr(ssl = SSL_new(ctx))) + goto err; + + /* SSL_new_listener_from should return NULL for DTLS */ + listener = SSL_new_listener_from(ssl, 0); + if (!TEST_ptr_null(listener)) + goto err; + + success = 1; +err: + SSL_free(listener); + SSL_free(ssl); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test SSL_listen_ex for DTLS. + * SSL_listen_ex is QUIC-only, so it should reject DTLS objects. + */ +static int test_dtls_listen_ex_returns_error(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + SSL *new_conn = NULL; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto err; + + if (!TEST_ptr(new_conn = SSL_new(ctx))) + goto err; + + if (!TEST_int_eq(SSL_listen_ex(listener, new_conn), -1) + || !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), + ERR_R_PASSED_INVALID_ARGUMENT)) + goto err; + + success = 1; +err: + SSL_free(new_conn); + SSL_free(listener); + SSL_CTX_free(ctx); + return success; +} + +/* + * Counter to track how many times the test time callback is invoked. + */ +static int test_now_cb_call_count = 0; + +/* + * Test time callback that returns a fixed time and tracks invocation count. + */ +static OSSL_TIME test_fake_now_cb(void *arg) +{ + uint64_t *fake_time_secs = (uint64_t *)arg; + + test_now_cb_call_count++; + return ossl_seconds2time(*fake_time_secs); +} + +/* + * Test ossl_dtls_listener_set_override_now_cb basic functionality. + * + * This test verifies that: + * 1. The time callback can be set on a DTLS listener + * 2. Setting a NULL callback is allowed (resets to default behavior) + * 3. The function returns success/failure appropriately + */ +static int test_dtls_listener_time_callback_basic(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + uint64_t fake_time = 1700000000; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto err; + + /* Setting the time callback should succeed */ + if (!TEST_true(ossl_dtls_listener_set_override_now_cb(listener, + test_fake_now_cb, + &fake_time))) + goto err; + + /* Setting callback to NULL should also succeed (resets to default) */ + if (!TEST_true(ossl_dtls_listener_set_override_now_cb(listener, NULL, NULL))) + goto err; + + success = 1; +err: + SSL_free(listener); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test ossl_dtls_listener_set_override_now_cb with invalid arguments. + * + * This test verifies that the function handles invalid arguments gracefully: + * 1. NULL SSL pointer should return 0 + * 2. Non-listener SSL should return 0 + */ +static int test_dtls_listener_time_callback_invalid(void) +{ + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + SSL *listener = NULL; + uint64_t fake_time = 1700000000; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + + /* Create a regular SSL connection (not a listener) */ + if (!TEST_ptr(ssl = SSL_new(ctx))) + goto err; + + /* Setting time callback on NULL should fail */ + if (!TEST_false(ossl_dtls_listener_set_override_now_cb(NULL, + test_fake_now_cb, + &fake_time))) + goto err; + + /* Setting time callback on a non-listener SSL should fail */ + if (!TEST_false(ossl_dtls_listener_set_override_now_cb(ssl, + test_fake_now_cb, + &fake_time))) + goto err; + + /* Verify that a listener succeeds for contrast */ + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto err; + + if (!TEST_true(ossl_dtls_listener_set_override_now_cb(listener, + test_fake_now_cb, + &fake_time))) + goto err; + + success = 1; +err: + SSL_free(listener); + SSL_free(ssl); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT basic functionality. + * + * This test verifies that: + * 1. The pending timeout can be set and retrieved on a DTLS listener via + * SSL_set_value_uint() / SSL_get_value_uint() + * 2. Different timeout values can be set + * 3. UINT64_MAX can be used to disable timeout + */ +static int test_dtls_listener_pending_timeout_basic(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + uint64_t timeout, retrieved; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto err; + + /* Default timeout should be 30 seconds (30000 ms) */ + if (!TEST_true(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT, &retrieved))) + goto err; + if (!TEST_uint64_t_eq(retrieved, 30000)) + goto err; + + /* Set a custom timeout of 60 seconds (60000 ms) */ + timeout = 60000; + if (!TEST_true(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT, timeout))) + goto err; + + /* Verify the timeout was set */ + if (!TEST_true(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT, &retrieved))) + goto err; + if (!TEST_uint64_t_eq(retrieved, timeout)) + goto err; + + /* Set timeout to UINT64_MAX (disable) */ + if (!TEST_true(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT, UINT64_MAX))) + goto err; + + /* Verify infinite timeout */ + if (!TEST_true(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT, &retrieved))) + goto err; + if (!TEST_uint64_t_eq(retrieved, UINT64_MAX)) + goto err; + + /* Set a very short timeout (1 second = 1000 ms) */ + timeout = 1000; + if (!TEST_true(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT, timeout))) + goto err; + + if (!TEST_true(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT, &retrieved))) + goto err; + if (!TEST_uint64_t_eq(retrieved, timeout)) + goto err; + + success = 1; +err: + SSL_free(listener); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT with invalid arguments. + * + * This test verifies that the underlying dispatch handles invalid arguments + * gracefully: + * 1. Non-listener SSL should fail + * 2. Get on non-listener should fail + */ +static int test_dtls_listener_pending_timeout_invalid(void) +{ + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + SSL *listener = NULL; + uint64_t timeout; + uint64_t retrieved; + int success = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto err; + + /* Create a regular SSL connection (not a listener) */ + if (!TEST_ptr(ssl = SSL_new(ctx))) + goto err; + + timeout = 60000; + + /* Setting timeout on a non-listener SSL should fail */ + if (!TEST_false(SSL_set_generic_value_uint(ssl, + SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT, timeout))) + goto err; + + /* Get on non-listener should fail */ + if (!TEST_false(SSL_get_generic_value_uint(ssl, + SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT, &retrieved))) + goto err; + + /* Verify that a listener succeeds for contrast */ + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto err; + + if (!TEST_true(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT, timeout))) + goto err; + + if (!TEST_false(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT, 0))) + goto err; + + success = 1; +err: + SSL_free(listener); + SSL_free(ssl); + SSL_CTX_free(ctx); + return success; +} + +/* + * Test: Free listener with connection in pending_conns only. + * + * This test creates a listener and starts a client handshake but does NOT + * complete it. The connection will be in pending_conns when the listener + * is freed. The listener should properly free the SSL object. + */ +static int test_ssl_ownership_pending_conn_leak(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *clientssl = NULL; + BIO_ADDR *client_addr = NULL; + int testresult = 0; + int ret, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + SSL_set_connect_state(clientssl); + ret = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, ret); + if (!TEST_int_le(ret, 0) + || !TEST_true(err_code == SSL_ERROR_WANT_READ + || err_code == SSL_ERROR_WANT_WRITE)) + goto end; + + /* + * Listener processes the ClientHello. + * This creates a pending connection in pending_conns and sends HVR. + */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* + * The connection is pending so it is not yet queued in + * incoming_connections: no readiness event should be reported. + */ + if (!TEST_size_t_eq(poll_result, 0) + || !TEST_true((poll_item.revents & SSL_POLL_EVENT_IC) == 0)) + goto end; + + /* + * Now the pending connection is in pending_conns and if we have a + * leak the ASAN tests will detect it + */ + testresult = 1; + +end: + /* Clean up - listener should free pending_conns SSL objects */ + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test: Free listener with connection in incoming_connections. + * + * This test creates a listener, completes a handshake so the connection + * moves to incoming_connections, but does NOT call SSL_accept_connection(). + * This means the connection will be in the incoming_connections queue. + * The listener should properly free the SSL object when destroyed. + */ +static int test_ssl_ownership_incoming_conn_leak(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *clientssl = NULL; + BIO_ADDR *client_addr = NULL; + int testresult = 0; + int ret, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr = 0; + int conn_ready = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + SSL_set_connect_state(clientssl); + while (!conn_ready) { + if (++abortctr > 100) { + TEST_error("Handshake did not converge"); + goto end; + } + + /* Drive the client side */ + ret = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, ret); + if (ret <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + /* Only fail if we haven't seen the connection ready yet */ + if (!conn_ready) { + TEST_error("SSL_connect failed (err %d)", err_code); + goto end; + } + } + + /* Poll the listener to drive server-side handshake */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* + * Check if a connection is ready (in incoming_connections). + * Do NOT call SSL_accept_connection() - we want to leave it there. + */ + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + conn_ready = 1; + } + + /* + * When we free the listener, it should free the SSL in incoming_connections. + * If there's a leak, ASAN will detect it. + */ + testresult = 1; + +end: + /* + * We do NOT free any serverssl here because we never called accept. + * The listener owns the connection and should free it. + */ + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +#ifndef OPENSSL_NO_DTLS1_3 +/* + * Test: Three connections with different ownership states. + * + * This test creates three connections: + * 1. One accepted by user (user owns) + * 2. One in incoming_connections (complete, not accepted, listener owns) + * 3. One in pending_conns (handshake in progress, listener owns) + * + * When the listener is freed: + * - Connection 1 should NOT be freed by listener (user frees it) + * - Connection 2 should be freed by listener + * - Connection 3 should be freed by listener + */ +static int test_ssl_ownership_three_conn_states(void) +{ + SSL_CTX *sctx = NULL; + SSL_CTX *cctx = NULL; + SSL *listener = NULL; + SSL *client1 = NULL, *client2 = NULL, *client3 = NULL; + SSL *accepted1 = NULL; + BIO_ADDR *server_addr = NULL; + int server_fd = -1; + int client1_fd = -1, client2_fd = -1, client3_fd = -1; + int testresult = 0; + int ret, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr; + int conn2_ready = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + DTLS1_3_VERSION, DTLS1_3_VERSION, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(create_dtls_listener(sctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &server_addr, &server_fd))) + goto end; + + /* + * --- Connection 1: Complete handshake AND accept (user owns) --- + */ + if (!TEST_true(create_dtls_client_for_addr(cctx, server_addr, + &client1, &client1_fd))) + goto end; + + SSL_set_connect_state(client1); + abortctr = 0; + while (accepted1 == NULL) { + if (++abortctr > 100) { + TEST_error("Connection 1 handshake did not converge"); + goto end; + } + + ret = SSL_connect(client1); + err_code = SSL_get_error(client1, ret); + if (ret <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) + break; + + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 100000; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + accepted1 = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + + if (!TEST_ptr(accepted1)) + goto end; + + if (!TEST_true(create_ssl_connection(accepted1, client1, SSL_ERROR_NONE))) + goto end; + + /* + * --- Connection 2: Complete handshake but don't accept (listener owns) --- + * + * Drive handshake to completion via listener tick, but do NOT call + * SSL_accept_connection(). The connection will be in incoming_connections. + */ + if (!TEST_true(create_dtls_client_for_addr(cctx, server_addr, + &client2, &client2_fd))) + goto end; + + SSL_set_connect_state(client2); + abortctr = 0; + while (!conn2_ready) { + if (++abortctr > 100) { + TEST_error("Connection 2 handshake did not converge"); + goto end; + } + + ret = SSL_connect(client2); + err_code = SSL_get_error(client2, ret); + if (ret <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE + && !conn2_ready) { + TEST_error("Connection 2 handshake failed unexpectedly"); + goto end; + } + + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 100000; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* + * Check if connection is ready. Do NOT call SSL_accept_connection() + * - we want it to stay in incoming_connections. + */ + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + conn2_ready = 1; + } + + /* + * --- Connection 3: Start handshake but don't complete (listener owns) --- + */ + if (!TEST_true(create_dtls_client_for_addr(cctx, server_addr, + &client3, &client3_fd))) + goto end; + + SSL_set_connect_state(client3); + ret = SSL_connect(client3); + err_code = SSL_get_error(client3, ret); + if (!TEST_int_le(ret, 0) + || !TEST_true(err_code == SSL_ERROR_WANT_READ + || err_code == SSL_ERROR_WANT_WRITE)) + goto end; + + /* Listener processes the ClientHello - creates SSL in pending_conns */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_R; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 100000; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* + * The tick consumed the ClientHello and the connection is now pending in + * pending_conns; no data remains buffered on the listener's read BIO, so + * no readable event should be reported. + */ + if (!TEST_size_t_eq(poll_result, 0) + || !TEST_true((poll_item.revents & SSL_POLL_EVENT_R) == 0)) + goto end; + + /* + * Now we have: + * - Connection 1 (accepted1): accepted by user (user owns) + * - Connection 2: in incoming_connections (listener owns) + * - Connection 3: in pending_conns (listener owns) + * + * When we free the listener, it should: + * - NOT double-free accepted1 (we free it ourselves) + * - Free the incoming connection for client2 + * - Free the pending connection for client3 + */ + testresult = 1; + +end: + /* User-owned connection - we free it */ + SSL_free(accepted1); + + /* Client SSLs - we always own these */ + SSL_free(client1); + SSL_free(client2); + SSL_free(client3); + + /* Listener frees pending_conns and incoming_connections */ + SSL_free(listener); + + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + if (client1_fd >= 0) + BIO_closesocket(client1_fd); + if (client2_fd >= 0) + BIO_closesocket(client2_fd); + if (client3_fd >= 0) + BIO_closesocket(client3_fd); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} +#endif /* OPENSSL_NO_DTLS1_3 */ + +/* + * Test: SSL_set0_rbio with pending connections causes leak. + * + * This test verifies that when SSL_set0_rbio is called on a listener + * with connections in pending_conns, those connections are properly freed. + */ +static int test_ssl_ownership_set_rbio_pending_leak(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *clientssl = NULL; + BIO_ADDR *client_addr = NULL; + BIO *new_server_bio = NULL; + int testresult = 0; + int ret, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + /* + * Client sends initial ClientHello. + */ + SSL_set_connect_state(clientssl); + ret = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, ret); + if (!TEST_int_le(ret, 0) + || !TEST_true(err_code == SSL_ERROR_WANT_READ + || err_code == SSL_ERROR_WANT_WRITE)) + goto end; + + /* + * Listener processes the ClientHello. + * This creates a pending connection in pending_conns and sends HVR. + */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* + * The connection is pending so it is not yet queued in + * incoming_connections: no readiness event should be reported. + */ + if (!TEST_size_t_eq(poll_result, 0) + || !TEST_true((poll_item.revents & SSL_POLL_EVENT_IC) == 0)) + goto end; + + /* + * The pending connection is still in pending_conns, NOT in incoming_connections. + * Now we call SSL_set0_rbio which should free the pending connections. + * If there's a leak, ASAN will detect it. + */ + + /* Create a new dgram mem BIO for the replacement */ + if (!TEST_ptr(new_server_bio = BIO_new(BIO_s_dgram_mem()))) + goto end; + + /* + * Replace the BIO - this should trigger cleanup of pending_conns. + * If there's a leak, ASAN will detect it. + */ + SSL_set0_rbio(listener, new_server_bio); + new_server_bio = NULL; + + testresult = 1; + +end: + SSL_free(clientssl); + SSL_free(listener); + BIO_free(new_server_bio); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test: SSL_set0_rbio with completed connection in incoming_connections. + * + * This test verifies that when SSL_set0_rbio is called on a listener + * with connections in incoming_connections (completed but not accepted), + * those connections are properly freed. + */ +static int test_ssl_ownership_set_rbio_incoming_leak(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *clientssl = NULL; + BIO_ADDR *client_addr = NULL; + BIO *new_server_bio = NULL; + int testresult = 0; + int ret, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr = 0; + int conn_ready = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + SSL_set_connect_state(clientssl); + while (!conn_ready) { + if (++abortctr > 100) { + TEST_error("Handshake did not converge"); + goto end; + } + + /* Drive the client side */ + ret = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, ret); + if (ret <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + /* Only fail if we haven't seen the connection ready yet */ + if (!conn_ready) { + TEST_error("SSL_connect failed with error %d", err_code); + goto end; + } + } + + /* Poll the listener to drive server-side handshake */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* + * Check if a connection is ready (in incoming_connections). + * Do NOT call SSL_accept_connection() - we want to leave it there. + */ + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + conn_ready = 1; + } + + /* + * Now call SSL_set0_rbio which should free the incoming connections. + * If there's a leak, ASAN will detect it. + */ + + /* Create a new dgram mem BIO for the replacement */ + if (!TEST_ptr(new_server_bio = BIO_new(BIO_s_dgram_mem()))) + goto end; + + SSL_set0_rbio(listener, new_server_bio); + new_server_bio = NULL; + + testresult = 1; + +end: + /* Do NOT free serverssl - we never called SSL_accept_connection() */ + SSL_free(clientssl); + SSL_free(listener); + BIO_free(new_server_bio); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test: User accepts connection and frees it - no double-free. + * + * This test verifies that when a user accepts a connection and frees it, + * the listener does not double-free when it is destroyed. + */ +static int test_ssl_ownership_accept_free_no_double_free(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *clientssl = NULL; + SSL *serverssl = NULL; + BIO_ADDR *client_addr = NULL; + int testresult = 0; + int ret, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + SSL_set_connect_state(clientssl); + while (serverssl == NULL) { + if (++abortctr > 100) { + TEST_error("Handshake did not converge"); + goto end; + } + + ret = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, ret); + + if (ret <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect failed with error %d", err_code); + goto end; + } + + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + serverssl = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + + if (!TEST_ptr(serverssl)) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + /* + * User owns serverssl now. Free it before freeing the listener. + * The listener should NOT try to free it again. + */ + SSL_free(serverssl); + serverssl = NULL; + + /* + * Now free the listener. If there's a double-free bug, ASAN will catch it. + */ + SSL_free(listener); + listener = NULL; + + testresult = 1; + +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test: Multiple pending connections, free listener mid-handshake. + * + * This test creates multiple clients that start handshakes but don't + * complete them. All pending connections should be freed when the + * listener is destroyed. + */ +static int test_ssl_ownership_multiple_pending_leak(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *clients[3] = { NULL, NULL, NULL }; + BIO_ADDR *server_addr = NULL; + int server_fd = -1; + int client_fds[3] = { -1, -1, -1 }; + int testresult = 0; + int ret, err_code; + int i; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(create_dtls_listener(sctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &server_addr, &server_fd))) + goto end; + + for (i = 0; i < 3; i++) { + /* Create client */ + if (!TEST_true(create_dtls_client_for_addr(cctx, server_addr, + &clients[i], &client_fds[i]))) + goto end; + + /* Client sends initial ClientHello */ + SSL_set_connect_state(clients[i]); + ret = SSL_connect(clients[i]); + err_code = SSL_get_error(clients[i], ret); + if (!TEST_int_le(ret, 0) + || !TEST_true(err_code == SSL_ERROR_WANT_READ + || err_code == SSL_ERROR_WANT_WRITE)) + goto end; + + /* Listener processes the ClientHello - creates SSL in pending_conns */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* + * The connection is pending (HVR in flight), so it is not yet queued + * in incoming_connections: no readiness event should be reported. + */ + if (!TEST_size_t_eq(poll_result, 0) + || !TEST_true((poll_item.revents & SSL_POLL_EVENT_IC) == 0)) + goto end; + } + + /* + * Now we have 3 connections in pending_conns. + * Free the listener - it should free all pending SSL objects. + * If there's a leak, ASAN will detect it. + */ + testresult = 1; + +end: + for (i = 0; i < 3; i++) { + SSL_free(clients[i]); + if (client_fds[i] >= 0) + BIO_closesocket(client_fds[i]); + } + SSL_free(listener); + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +static int test_ssl_ownership_pending_timeout_cleanup(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *clientssl = NULL; + BIO_ADDR *client_addr = NULL; + int testresult = 0; + int ret, err_code; + int count_after_hello; + uint64_t fake_now_secs = 1700000000; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + if (!TEST_true(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT, 1000))) + goto end; + + /* + * Setting test_now_cb_call_count to 0 before the test. + */ + test_now_cb_call_count = 0; + if (!TEST_true(ossl_dtls_listener_set_override_now_cb(listener, + test_fake_now_cb, &fake_now_secs))) + goto end; + + /* + * Client sends initial ClientHello. + */ + SSL_set_connect_state(clientssl); + ret = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, ret); + if (!TEST_int_le(ret, 0) + || !TEST_true(err_code == SSL_ERROR_WANT_READ + || err_code == SSL_ERROR_WANT_WRITE)) + goto end; + + /* + * Listener processes the ClientHello. + */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* + * The connection is pending (HVR in flight), so it is not yet queued in + * incoming_connections: no readiness event should be reported. + */ + if (!TEST_size_t_eq(poll_result, 0) + || !TEST_true((poll_item.revents & SSL_POLL_EVENT_IC) == 0)) + goto end; + + /* + * Processing the ClientHello (creating the pending connection and + * generating the HelloVerifyRequest cookie) must have consulted the + * listener's time override, so the callback should have been invoked at + * least once by now. + */ + if (!TEST_int_gt(test_now_cb_call_count, 0)) + goto end; + count_after_hello = test_now_cb_call_count; + + /* + * Advance the fake time past the timeout (more than 1 second). + * The next tick should detect the timeout and free the pending connection. + */ + fake_now_secs += 5; + + /* Trigger a tick to process the timeout */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* + * The timed-out pending connection was cleaned up, so nothing is queued in + * incoming_connections: no readiness event should be reported. + */ + if (!TEST_size_t_eq(poll_result, 0) + || !TEST_true((poll_item.revents & SSL_POLL_EVENT_IC) == 0)) + goto end; + + /* + * The timeout check during the tick reads the (now advanced) time through + * the override as well, so the callback must have been invoked again. + */ + if (!TEST_int_gt(test_now_cb_call_count, count_after_hello)) + goto end; + + /* + * The pending connection should have been timed out and freed by the listener. + * If there's a leak (timeout didn't free the SSL), ASAN will detect it. + * + * Now free the listener - it should have nothing left in pending_conns + * since the timeout already cleaned it up. + */ + testresult = 1; + +end: + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test: SSL_poll() with SSL_POLL_EVENT_W on established connection. + * + * This test verifies that SSL_POLL_EVENT_W (writable) always returns + * true on an established DTLS connection, since DTLS connections are + * always ready for writing. + */ +static int test_dtls_poll_conn_event_w(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + BIO_ADDR *client_addr = NULL; + int testresult = 0; + int retc, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + SSL_set_connect_state(clientssl); + while (serverssl == NULL) { + if (++abortctr > 100) { + TEST_error("Connection loop did not converge"); + goto end; + } + + retc = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, retc); + if (retc <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect failed (err %d)", err_code); + goto end; + } + + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + serverssl = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + + if (!TEST_ptr(serverssl)) + goto end; + + /* Complete the handshake */ + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + /* + * Now poll the established server connection for SSL_POLL_EVENT_W. + * This should always return true since DTLS connections are always writable. + */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = serverssl; + poll_item.events = SSL_POLL_EVENT_W; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* Verify SSL_POLL_EVENT_W is returned */ + if (!TEST_size_t_gt(poll_result, 0)) + goto end; + if (!TEST_true((poll_item.revents & SSL_POLL_EVENT_W) != 0)) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test: SSL_poll() with SSL_POLL_EVENT_R on dgram pair BIO connection. + * + * This test validates the fix to ossl_dtls_conn_poll_events() that allows + * polling for readable data on connections using dgram pair BIOs. + */ +static int test_dtls_poll_conn_dgram_pair_readable(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + BIO_ADDR *client_addr = NULL; + const char msg[] = "Test data for poll readable"; + char buf[64]; + unsigned char drain[256]; + size_t written, readbytes, drain_len = 0; + int testresult = 0; + int retc, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + SSL_set_connect_state(clientssl); + while (serverssl == NULL) { + if (++abortctr > 100) { + TEST_error("Connection loop did not converge"); + goto end; + } + + retc = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, retc); + if (retc <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect failed (err %d)", err_code); + goto end; + } + + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + serverssl = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + + if (!TEST_ptr(serverssl)) + goto end; + + /* Complete the handshake */ + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + /* + * Drain any pending post-handshake records (e.g., DTLS 1.3 ACKs for + * NewSessionTicket). These are not application data but appear as readable. + * Expect SSL_read_ex to return 0 (no app data) with zero bytes read. + */ + if (!TEST_false(SSL_read_ex(serverssl, drain, sizeof(drain), &drain_len)) + || !TEST_size_t_eq(drain_len, 0)) + goto end; + + /* + * Poll server connection for SSL_POLL_EVENT_R BEFORE any data is sent. + * This should return revents=0 since no data is pending. + */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = serverssl; + poll_item.events = SSL_POLL_EVENT_R; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* No data pending, so revents should be 0 */ + if (!TEST_true((poll_item.revents & SSL_POLL_EVENT_R) == 0)) + goto end; + + /* Now have the client send data */ + if (!TEST_true(SSL_write_ex(clientssl, msg, sizeof(msg), &written)) + || !TEST_size_t_eq(written, sizeof(msg))) + goto end; + + /* + * Poll server connection for SSL_POLL_EVENT_R AFTER data is sent. + * This should return SSL_POLL_EVENT_R since data is now pending. + * This is the key test for the dgram pair BIO fix - it uses BIO_pending() + * instead of BIO_get_fd() + BIO_socket_ready(). + */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = serverssl; + poll_item.events = SSL_POLL_EVENT_R; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* Data is pending, so SSL_POLL_EVENT_R should be set */ + if (!TEST_size_t_gt(poll_result, 0)) + goto end; + if (!TEST_true((poll_item.revents & SSL_POLL_EVENT_R) != 0)) + goto end; + + /* Verify we can actually read the data */ + if (!TEST_true(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(msg)) + || !TEST_mem_eq(buf, readbytes, msg, sizeof(msg))) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test: SSL_poll() returns no events when no data is pending. + * + * This test verifies that polling a connection for SSL_POLL_EVENT_R + * returns revents=0 and result_count=0 when no data is available. + */ +static int test_dtls_poll_conn_no_events_before_data(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + BIO_ADDR *client_addr = NULL; + unsigned char drain[256]; + size_t drain_len = 0; + int testresult = 0; + int retc, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + SSL_set_connect_state(clientssl); + while (serverssl == NULL) { + if (++abortctr > 100) { + TEST_error("Connection loop did not converge"); + goto end; + } + + retc = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, retc); + if (retc <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect failed (err %d)", err_code); + goto end; + } + + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + serverssl = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + + if (!TEST_ptr(serverssl)) + goto end; + + /* Complete the handshake */ + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + /* + * Drain any pending post-handshake records (e.g., DTLS 1.3 ACKs for + * NewSessionTicket). These are not application data but appear as readable. + * Expect SSL_read_ex to return 0 (no app data) with zero bytes read. + */ + if (!TEST_false(SSL_read_ex(serverssl, drain, sizeof(drain), &drain_len)) + || !TEST_size_t_eq(drain_len, 0)) + goto end; + + /* + * Poll server connection for SSL_POLL_EVENT_R with no data pending. + * Use zero timeout for non-blocking behavior. + */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = serverssl; + poll_item.events = SSL_POLL_EVENT_R; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* No data pending - verify revents has no SSL_POLL_EVENT_R */ + if (!TEST_true((poll_item.revents & SSL_POLL_EVENT_R) == 0)) + goto end; + + /* poll_result should be 0 since no events fired */ + if (!TEST_size_t_eq(poll_result, 0)) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test: SSL_poll() on listener with multiple event types. + * + * This test verifies that polling a listener with both SSL_POLL_EVENT_IC + * and SSL_POLL_EVENT_R works correctly. + */ +static int test_dtls_poll_listener_multiple_events(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *clientssl = NULL; + BIO_ADDR *client_addr = NULL; + int testresult = 0; + int retc, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + /* + * This test drives a single ClientHello and expects the listener to + * report the incoming connection immediately, so disable address + * validation (otherwise the connection is not ready until the HVR/HRR + * cookie round-trip completes). + */ + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_NO_VALIDATE | SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + /* + * Poll listener with multiple events BEFORE client sends anything. + * Should return revents=0 since no incoming connection yet. + */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC | SSL_POLL_EVENT_R; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* No incoming connection yet */ + if (!TEST_true((poll_item.revents & SSL_POLL_EVENT_IC) == 0)) + goto end; + + /* Have client initiate the handshake (send ClientHello) */ + SSL_set_connect_state(clientssl); + retc = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, retc); + if (!TEST_int_le(retc, 0) + || !TEST_true(err_code == SSL_ERROR_WANT_READ + || err_code == SSL_ERROR_WANT_WRITE)) + goto end; + + /* + * Poll listener with multiple events AFTER client sends ClientHello. + * Should return SSL_POLL_EVENT_R since data is available on the BIO. + */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC | SSL_POLL_EVENT_R; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* Should have at least one event */ + if (!TEST_size_t_gt(poll_result, 0)) + goto end; + + /* + * The listener should report SSL_POLL_EVENT_R since there's data + * on the underlying BIO (the ClientHello). + */ + if (!TEST_true((poll_item.revents & SSL_POLL_EVENT_IC) != 0)) + goto end; + + testresult = 1; +end: + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test: SSL_poll() with SSL_POLL_EVENT_EC after shutdown. + * + * This test verifies that SSL_POLL_EVENT_EC (exception condition) is + * returned after SSL_shutdown() is called on the connection. + */ +static int test_dtls_poll_conn_event_ec(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + BIO_ADDR *client_addr = NULL; + int testresult = 0; + int retc, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + SSL_set_connect_state(clientssl); + while (serverssl == NULL) { + if (++abortctr > 100) { + TEST_error("Connection loop did not converge"); + goto end; + } + + retc = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, retc); + if (retc <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect failed (err %d)", err_code); + goto end; + } + + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + serverssl = SSL_accept_connection(listener, SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + + if (!TEST_ptr(serverssl)) + goto end; + + /* Complete the handshake */ + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + /* + * Poll server connection for SSL_POLL_EVENT_EC before shutdown. + * Should return revents=0 since no error/shutdown condition. + */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = serverssl; + poll_item.events = SSL_POLL_EVENT_EC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* No error condition yet */ + if (!TEST_true((poll_item.revents & SSL_POLL_EVENT_EC) == 0)) + goto end; + + /* Initiate shutdown on the server connection */ + SSL_shutdown(serverssl); + + /* + * Poll server connection for SSL_POLL_EVENT_EC after shutdown. + * Should return SSL_POLL_EVENT_EC since shutdown is in progress. + */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = serverssl; + poll_item.events = SSL_POLL_EVENT_EC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result))) + goto end; + + /* Shutdown is in progress, so SSL_POLL_EVENT_EC should be set */ + if (!TEST_size_t_gt(poll_result, 0)) + goto end; + if (!TEST_true((poll_item.revents & SSL_POLL_EVENT_EC) != 0)) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test: SSL_poll() with NULL SSL in descriptor. + * + * This test verifies that SSL_poll() handles a NULL SSL pointer in the + * poll descriptor gracefully. + */ +static int test_dtls_poll_null_item(void) +{ + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int testresult = 0; + + /* Create a poll item with NULL SSL */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = NULL; + poll_item.events = SSL_POLL_EVENT_R | SSL_POLL_EVENT_W; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + /* + * Call SSL_poll with a NULL SSL descriptor. + * Expected behavior: Should either return success with revents=0 (no-op), + * or return failure. Either way, it should not crash. + */ + if (SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, &poll_result)) { + /* If it succeeds, revents should be 0 (no events for NULL) */ + if (!TEST_true(poll_item.revents == 0)) + goto end; + } + /* If SSL_poll returns 0 (failure), that's also acceptable behavior */ + + testresult = 1; +end: + return testresult; +} + +#ifndef OPENSSL_NO_DTLS1_3 +/* + * Test DTLS 1.3 SSL Listener handshake message buffering. + * + * This test verifies that when a DTLS 1.3 SSL Listener sends handshake + * messages, multiple records are buffered into a single datagram + * rather than being sent as separate datagrams. + * + * Expected behavior with buffering: + * - At least one datagram contains multiple DTLS records + * + * Without buffering (the bug this tests for): + * - Each record would be in its own datagram + */ +static int test_dtls13_listener_msg_buffering(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + BIO_ADDR *client_addr = NULL; + int testresult = 0; + int retc, rets, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr = 0; + unsigned char buf[16384]; + size_t datagram_len; + BIO_MSG msg; + size_t msgs_processed; + int record_count, max_records_in_datagram = 0; + BIO *client_rbio; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + DTLS1_3_VERSION, DTLS1_3_VERSION, + &sctx, &cctx, cert, privkey))) + goto end; + + /* + * Set NO_QUERY_MTU on the context so connections inherit it. + * This prevents the MTU from being queried before we can set it. + */ + SSL_CTX_set_options(sctx, SSL_OP_NO_QUERY_MTU); + + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_NO_VALIDATE | SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &clientssl, &client_addr))) + goto end; + + SSL_set_connect_state(clientssl); + + retc = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, retc); + if (!TEST_true(retc <= 0 + && (err_code == SSL_ERROR_WANT_READ + || err_code == SSL_ERROR_WANT_WRITE))) + goto end; + + while (serverssl == NULL) { + if (!TEST_int_le(++abortctr, 100)) + goto end; + + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), + &poll_timeout, 0, &poll_result))) + goto end; + + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + serverssl = SSL_accept_connection(listener, + SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + + if (!TEST_ptr(serverssl)) + goto end; + + /* Set a large MTU to prevent message fragmentation */ + SSL_set_mtu(serverssl, 1500); + + abortctr = 0; + while (1) { + if (!TEST_int_le(++abortctr, 100)) + goto end; + + rets = SSL_do_handshake(serverssl); + err_code = SSL_get_error(serverssl, rets); + + if (rets > 0) + break; + + if (err_code == SSL_ERROR_WANT_READ) + break; + + if (!TEST_int_eq(err_code, SSL_ERROR_WANT_WRITE)) + goto end; + } + + /* + * The server has sent its flight, which should be buffered into one or + * more datagrams. We read each datagram and count the DTLS records + * within it. With proper buffering, at least one datagram should + * contain multiple records. + */ + client_rbio = SSL_get_rbio(clientssl); + if (!TEST_ptr(client_rbio)) + goto end; + + /* Read all available datagrams */ + while (1) { + memset(&msg, 0, sizeof(msg)); + msg.data = buf; + msg.data_len = sizeof(buf); + + if (!BIO_recvmmsg(client_rbio, &msg, sizeof(msg), 1, 0, &msgs_processed) + || msgs_processed == 0) + break; + + datagram_len = msg.data_len; + + /* Count DTLS records in this datagram */ + record_count = 0; + { + size_t offset = 0; + + while (offset < datagram_len) { + unsigned char hdr = buf[offset]; + size_t rec_len, hdr_len; + + /* + * Check that the first three bits are set to 001 to verify + * that the DTLS 1.3 Unified Header is present. Otherwise, + * assume DTLS 1.2 record format. + */ + if ((hdr & 0xE0) == 0x20) { + /* DTLS 1.3 unified header */ + if (offset + 4 > datagram_len) + break; + + if (hdr & 0x04) { + /* Length field present */ + hdr_len = 1 + ((hdr & 0x08) ? 2 : 1); + if (offset + hdr_len + 2 > datagram_len) + break; + rec_len = (buf[offset + hdr_len] << 8) + | buf[offset + hdr_len + 1]; + hdr_len += 2; + } else { + /* No length field - record extends to end of datagram */ + rec_len = datagram_len - offset - 1 + - ((hdr & 0x08) ? 2 : 1); + hdr_len = 1 + ((hdr & 0x08) ? 2 : 1); + } + + offset += hdr_len + rec_len; + } else if (hdr >= 20 && hdr <= 25) { + /* DTLS 1.2 style record header (13 bytes) */ + if (offset + 13 > datagram_len) + break; + rec_len = (buf[offset + 11] << 8) | buf[offset + 12]; + offset += 13 + rec_len; + } else { + break; + } + + record_count++; + } + } + + if (record_count > max_records_in_datagram) + max_records_in_datagram = record_count; + } + + /* + * The key assertion: with buffering enabled, at least one datagram should + * contain multiple records. + */ + if (!TEST_int_gt(max_records_in_datagram, 1)) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(client_addr); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} +#endif /* OPENSSL_NO_DTLS1_3 */ + +static int test_dtls_listener_max_pending_conns_api(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + uint64_t max_conns, retrieved_max_conns; + int testresult = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto end; + + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto end; + + /* Retrieve default maximum pending connections (256) */ + if (!TEST_true(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, &retrieved_max_conns))) + goto end; + + if (!TEST_uint64_t_eq(retrieved_max_conns, 256)) + goto end; + + max_conns = 10; + if (!TEST_true(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, max_conns))) + goto end; + + if (!TEST_true(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, &retrieved_max_conns))) + goto end; + if (!TEST_uint64_t_eq(retrieved_max_conns, max_conns)) + goto end; + + if (!TEST_false(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, 0))) + goto end; + + if (!TEST_true(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, &retrieved_max_conns))) + goto end; + if (!TEST_uint64_t_eq(retrieved_max_conns, max_conns)) + goto end; + + testresult = 1; + +end: + SSL_free(listener); + SSL_CTX_free(ctx); + return testresult; +} + +static int test_dtls_listener_max_dgram_size_api(void) +{ + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + uint64_t size, retrieved_size; + int testresult = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto end; + + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto end; + + /* Retrieve default maximum datagram size (2000) */ + if (!TEST_true(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE, &retrieved_size))) + goto end; + if (!TEST_uint64_t_eq(retrieved_size, 2000)) + goto end; + + /* Set and read back a larger value */ + size = 9000; + if (!TEST_true(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE, size))) + goto end; + if (!TEST_true(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE, &retrieved_size))) + goto end; + if (!TEST_uint64_t_eq(retrieved_size, size)) + goto end; + + /* Values above the maximum UDP payload are clamped to 65535 */ + if (!TEST_true(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE, 100000))) + goto end; + if (!TEST_true(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE, &retrieved_size))) + goto end; + if (!TEST_uint64_t_eq(retrieved_size, 65535)) + goto end; + + /* Values below the minimum receive size are rejected... */ + if (!TEST_false(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE, 100))) + goto end; + /* ...and leave the previous value unchanged. */ + if (!TEST_true(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE, &retrieved_size))) + goto end; + if (!TEST_uint64_t_eq(retrieved_size, 65535)) + goto end; + + testresult = 1; + +end: + SSL_free(listener); + SSL_CTX_free(ctx); + return testresult; +} + +/* + * A large dummy ClientHello extension used to inflate the ClientHello beyond + * the default receive-buffer size, so the functional test below only succeeds + * once SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE has been raised. The server has no + * callback registered for this extension type, so per TLS 1.3 rules it simply + * ignores it. + */ +#define BIG_CH_EXT_TYPE 65280 /* IANA "Reserved for Private Use" range */ +#define BIG_CH_EXT_LEN 2500 /* pushes the ClientHello over the 2000 default */ + +static int big_ch_ext_add_cb(SSL *s, unsigned int ext_type, + unsigned int context, const unsigned char **out, size_t *outlen, + X509 *x, size_t chainidx, int *al, void *add_arg) +{ + static const unsigned char padding[BIG_CH_EXT_LEN]; /* zero-filled */ + + *out = padding; + *outlen = sizeof(padding); + return 1; +} + +/* + * Helper to create a DTLS client on a *connected* UDP socket. Unlike the + * BIO_dgram_set_peer() helpers above (which use an unconnected socket and so + * cause DTLS to fragment the ClientHello into sub-MTU datagrams), a connected + * socket lets DTLS discover the large loopback path MTU and send the whole + * ClientHello in a single datagram - which is what exercises the listener demux + * receive-buffer sizing. + */ +static int create_dtls_client_connected(SSL_CTX *cctx, + const BIO_ADDR *server_addr, SSL **clientssl, int *client_fd) +{ + BIO *c_bio = NULL; + int ret = 0; + + *clientssl = NULL; + *client_fd = -1; + + *client_fd = BIO_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0); + if (!TEST_int_ge(*client_fd, 0)) + goto err; + + if (!TEST_true(BIO_connect(*client_fd, server_addr, 0))) + goto err; + + if (!TEST_true(BIO_socket_nbio(*client_fd, 1))) + goto err; + + c_bio = BIO_new_dgram(*client_fd, BIO_NOCLOSE); + if (!TEST_ptr(c_bio)) + goto err; + + if (!TEST_ptr(*clientssl = SSL_new(cctx))) + goto err; + + SSL_set_bio(*clientssl, c_bio, c_bio); + c_bio = NULL; + + ret = 1; + +err: + BIO_free(c_bio); + if (ret == 0) { + SSL_free(*clientssl); + if (*client_fd >= 0) + BIO_closesocket(*client_fd); + *clientssl = NULL; + *client_fd = -1; + } + return ret; +} + +/* + * Functional test for SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE. + * + * A connected client sends a ClientHello inflated (via a large custom + * extension) past the default 2000-byte receive buffer, as a single datagram. + * With the listener's max datagram size raised above the ClientHello size, the + * demux receives it whole and the HRR handshake completes. With the default + * size the oversized ClientHello would be truncated and the handshake would + * stall - so this test passing demonstrates the tunable takes effect. (The + * other listener tests avoid the issue only because they use unconnected + * clients that fragment the ClientHello.) + */ +static int test_dtls_listener_max_dgram_size_functional(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + BIO_ADDR *server_addr = NULL; + int server_fd = -1, client_fd = -1; + const char msg[] = "Hello large ClientHello"; + char buf[64]; + size_t written, readbytes; + int testresult = 0; + int retc, err_code; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int abortctr = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), 0, 0, + &sctx, &cctx, cert, privkey))) + goto end; + + /* Inflate the ClientHello past the 2000-byte default receive buffer. */ + if (!TEST_true(SSL_CTX_add_custom_ext(cctx, BIG_CH_EXT_TYPE, + SSL_EXT_CLIENT_HELLO, big_ch_ext_add_cb, NULL, NULL, NULL, NULL))) + goto end; + + if (!TEST_true(create_dtls_listener(sctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &server_addr, &server_fd))) + goto end; + + /* Raise the receive size above the inflated ClientHello. */ + if (!TEST_true(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE, 9000))) + goto end; + + if (!TEST_true(create_dtls_client_connected(cctx, server_addr, + &clientssl, &client_fd))) + goto end; + + SSL_set_connect_state(clientssl); + while (serverssl == NULL) { + if (++abortctr > 100) { + TEST_error("connection did not converge (oversized ClientHello)"); + goto end; + } + + retc = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, retc); + if (retc <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect failed (err %d)", err_code); + goto end; + } + + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), + &poll_timeout, 0, &poll_result))) + goto end; + + if (poll_result > 0 && (poll_item.revents & SSL_POLL_EVENT_IC) != 0) + serverssl = SSL_accept_connection(listener, + SSL_ACCEPT_CONNECTION_NO_BLOCK); + } + + if (!TEST_ptr(serverssl)) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + if (!TEST_true(SSL_write_ex(clientssl, msg, sizeof(msg), &written)) + || !TEST_size_t_eq(written, sizeof(msg))) + goto end; + + if (!TEST_true(dtls_read_with_retry(serverssl, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(msg)) + || !TEST_mem_eq(buf, readbytes, msg, sizeof(msg))) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + if (client_fd >= 0) + BIO_closesocket(client_fd); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +static int test_dtls_listener_max_pending_conns_invalid(void) +{ + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + SSL *listener = NULL; + uint64_t retrieved_max_conns; + int testresult = 0; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method()))) + goto end; + + if (!TEST_ptr(listener = SSL_new_listener(ctx, SSL_LISTENER_FLAG_SINGLE_THREAD))) + goto end; + + /* Retrieve default maximum pending connections (256) */ + if (!TEST_true(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, &retrieved_max_conns))) + goto end; + + if (!TEST_uint64_t_eq(retrieved_max_conns, 256)) + goto end; + + /* Setting the cap to 0 must fail - the cap cannot be disabled */ + if (!TEST_false(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, 0))) + goto end; + + if (!TEST_true(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, &retrieved_max_conns))) + goto end; + if (!TEST_uint64_t_eq(retrieved_max_conns, 256)) + goto end; + + /* Setting on a non-listener SSL should fail */ + if (!TEST_ptr(ssl = SSL_new(ctx))) + goto end; + if (!TEST_false(SSL_set_generic_value_uint(ssl, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, 100))) + goto end; + + /* Get on non-listener should fail */ + if (!TEST_false(SSL_get_generic_value_uint(ssl, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, &retrieved_max_conns))) + goto end; + + /* Get with a NULL out-value must fail */ + if (!TEST_false(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, NULL))) + goto end; + + /* + * A non-GENERIC value class must be rejected: these tunables are local + * configuration and do not participate in feature negotiation. + */ + if (!TEST_false(SSL_set_value_uint(listener, SSL_VALUE_CLASS_FEATURE_REQUEST, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, 100))) + goto end; + if (!TEST_false(SSL_get_value_uint(listener, SSL_VALUE_CLASS_FEATURE_REQUEST, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, &retrieved_max_conns))) + goto end; + + testresult = 1; + +end: + SSL_free(ssl); + SSL_free(listener); + SSL_CTX_free(ctx); + return testresult; +} + +#define PENDING_CAP_TEST_LIMIT 3 +#define PENDING_CAP_TEST_CLIENTS 5 + +/* + * Helper for the pending-connection cap tests. + * + * Creates a single DTLS client, sends its initial ClientHello + * then drives the listener once via SSL_poll() so it processes the ClientHello + * - either admitting a pending connection (and sending an HVR/HRR) or rejecting + * it once the cap has been reached. + * + * On success the new client SSL and its socket fd are returned via *client and + * *client_fd for the caller to clean up. + * + * Returns 1 on success, 0 on failure. + */ +static int cap_test_send_clienthello(SSL_CTX *cctx, const BIO_ADDR *server_addr, + SSL *listener, SSL **client, int *client_fd) +{ + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int ret, err_code; + + if (!TEST_true(create_dtls_client_for_addr(cctx, server_addr, client, client_fd))) + return 0; + + /* Client sends initial ClientHello */ + SSL_set_connect_state(*client); + ret = SSL_connect(*client); + err_code = SSL_get_error(*client, ret); + + /* The ClientHello should be sent but the handshake should not complete */ + if (!TEST_int_le(ret, 0)) + return 0; + if (!TEST_true(err_code == SSL_ERROR_WANT_READ || err_code == SSL_ERROR_WANT_WRITE)) + return 0; + + /* + * Drive the listener so it processes the ClientHello. Depending on the + * current pending count it either creates a pending connection and sends + * an HRR/HVR, or rejects the connection and releases the packet once the + * cap has been reached. + */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_R; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 100000; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), + &poll_timeout, 0, &poll_result))) + return 0; + + return 1; +} + +/* + * Test that pending connection cap is enforced. + * + * This test: + * 1. Creates a listener with max_pending_conns = 3 + * 2. Starts 5 clients that send ClientHello but don't complete handshake + * 3. Verifies only 3 pending connections are created + * 4. The 4th and 5th clients should be rejected (their packets released) + */ +static int test_pending_conn_cap_enforcement(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *clients[PENDING_CAP_TEST_CLIENTS] = { NULL }; + int client_fds[PENDING_CAP_TEST_CLIENTS] = { -1, -1, -1, -1, -1 }; + BIO_ADDR *server_addr = NULL; + int server_fd = -1; + int testresult = 0; + int i; + + /* Create SSL contexts */ + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto err; + + /* Create listener with HVR required (so connections stay pending) */ + if (!TEST_true(create_dtls_listener(sctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &server_addr, &server_fd))) + goto err; + + /* Set the pending connection cap to 3 */ + if (!TEST_true(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, PENDING_CAP_TEST_LIMIT))) + goto err; + + /* Verify the cap was set */ + { + uint64_t v; + if (!TEST_true(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, &v))) + goto err; + if (!TEST_uint64_t_eq(v, PENDING_CAP_TEST_LIMIT)) + goto err; + } + + /* + * Create 5 clients and have each send their ClientHello. + * The first three should end up in the pending connections. + * The 4th and 5th clients should be rejected due to the cap. + */ + for (i = 0; i < PENDING_CAP_TEST_CLIENTS; i++) + if (!TEST_true(cap_test_send_clienthello(cctx, server_addr, listener, + &clients[i], &client_fds[i]))) + goto err; + + /* + * Only PENDING_CAP_TEST_LIMIT connections should have been admitted to + * pending_conns; the remaining clients were rejected once the cap was + * reached. Read the count directly from the listener's pending lookup + * table (there is no public accessor by design - the cap is silent). + */ + if (!TEST_size_t_eq(ossl_dgram_conn_lookup_num_items( + ((DTLS_LISTENER *)listener)->pending_conns), + PENDING_CAP_TEST_LIMIT)) + goto err; + + testresult = 1; + +err: + for (i = 0; i < PENDING_CAP_TEST_CLIENTS; i++) { + SSL_free(clients[i]); + if (client_fds[i] >= 0) + BIO_closesocket(client_fds[i]); + } + + SSL_free(listener); + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test that pending connection cap and timeout interaction. + * + * This test: + * 1. Creates a listener with max_pending_conns = 3 + * 2. Starts 5 clients that send ClientHello but don't complete handshake + * 3. Verifies there are 3 pending connections + * 4. Waits for the pending connections to timeout and be released + * 5. Add the last two clients + * 6. Verifies there are 2 pending connections + */ +static int test_pending_cap_with_timeout(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *clients[PENDING_CAP_TEST_CLIENTS] = { NULL }; + int client_fds[PENDING_CAP_TEST_CLIENTS] = { -1, -1, -1, -1, -1 }; + BIO_ADDR *server_addr = NULL; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result; + int server_fd = -1; + int testresult = 0; + int i; + + /* Create SSL contexts */ + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto err; + + /* Create listener with HVR required (so connections stay pending) */ + if (!TEST_true(create_dtls_listener(sctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &server_addr, &server_fd))) + goto err; + + /* Set the pending connection cap to 3 */ + if (!TEST_true(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, PENDING_CAP_TEST_LIMIT))) + goto err; + + /* Verify the cap was set */ + { + uint64_t v; + if (!TEST_true(SSL_get_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, &v))) + goto err; + if (!TEST_uint64_t_eq(v, PENDING_CAP_TEST_LIMIT)) + goto err; + } + + if (!TEST_true(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT, 1000))) + goto err; + + timeout_test_fake_time = ossl_time_from_time_t(1700000000); + if (!TEST_true(ossl_dtls_listener_set_override_now_cb(listener, + /* Use a callback that returns timeout_test_fake_time */ + timeout_test_now_cb, NULL))) + goto err; + + /* + * Create 5 clients and have each send their ClientHello. + * The first three should end up in the pending connections. + * The 4th and 5th clients should be rejected due to the cap. + */ + for (i = 0; i < PENDING_CAP_TEST_LIMIT; i++) + if (!TEST_true(cap_test_send_clienthello(cctx, server_addr, listener, + &clients[i], &client_fds[i]))) + goto err; + + if (!TEST_size_t_eq(ossl_dgram_conn_lookup_num_items( + ((DTLS_LISTENER *)listener)->pending_conns), + PENDING_CAP_TEST_LIMIT)) + goto err; + + /* Advance time past timeout (5 seconds > 1 second timeout) */ + timeout_test_fake_time = ossl_time_add(timeout_test_fake_time, + ossl_seconds2time(5)); + + /* Trigger a tick to process timeouts */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_R; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), + &poll_timeout, 0, &poll_result))) + goto err; + + for (i = PENDING_CAP_TEST_LIMIT; i < PENDING_CAP_TEST_CLIENTS; i++) + if (!TEST_true(cap_test_send_clienthello(cctx, server_addr, listener, + &clients[i], &client_fds[i]))) + goto err; + + if (!TEST_size_t_eq(ossl_dgram_conn_lookup_num_items( + ((DTLS_LISTENER *)listener)->pending_conns), + PENDING_CAP_TEST_CLIENTS - PENDING_CAP_TEST_LIMIT)) + goto err; + + testresult = 1; + +err: + for (i = 0; i < PENDING_CAP_TEST_CLIENTS; i++) { + SSL_free(clients[i]); + if (client_fds[i] >= 0) + BIO_closesocket(client_fds[i]); + } + + SSL_free(listener); + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * ============================================================================ + * new_pending_conn_cb tests + * ============================================================================ + * + * These tests exercise SSL_CTX_set_new_pending_conn_cb() on the DTLS listener + * path. The callback fires from dtls_listener_packet_handler() after the + * max_pending_conns cap check but before the new pending connection is + * registered in the listener's pending_conns table. A callback return of 0 + * causes the listener to discard the newly-allocated conn_ssl; a non-zero + * return admits it as a normal pending connection. + * + * Scenarios covered: + * 1. Callback allows every connection (small workload, cap not a factor). + * 2. Callback rejects every connection (small workload, cap not a factor). + * 3. Cap set to LIMIT; callback always allows; more than LIMIT clients + * attempt to connect. The cap must win: exactly LIMIT connections are + * admitted, and the callback is invoked at most LIMIT times (because + * the cap is checked first and short-circuits before the callback). + * 4. Cap set well above the client count; callback rejects everything. + * No pending connections are admitted; the cap is not the reason. + */ + +/* --- Callback helpers ---------------------------------------------------- */ + +static int new_pending_cb_call_count; +static int new_pending_cb_allow_remaining; +static SSL_CTX *new_pending_cb_expected_ctx; +static void *new_pending_cb_expected_arg; +static int new_pending_cb_ctx_matched; +static int new_pending_cb_arg_matched; + +/* + * Reset the file-scope callback state before registering the callback for + * a new scenario. These globals persist across tests, so leftover values + * from a previous run would corrupt this run's assertions (e.g. an + * inflated call_count or a sticky ctx_matched == 0). + * + * ctx - SSL_CTX the caller is about to register the callback + * on; stored so the callback can verify it is passed + * back unchanged. + * arg - opaque cookie the caller will pass to + * SSL_CTX_set_new_pending_conn_cb(); same round-trip + * check. + * allow_remaining - number of admissions the callback should grant before + * it starts denying. 0 means "always deny". Pass a + * value comfortably larger than the number of clients + * to mean "always allow". Each admission decrements + * this counter until it reaches 0. + */ +static void new_pending_cb_reset(SSL_CTX *ctx, void *arg, int allow_remaining) +{ + new_pending_cb_call_count = 0; + new_pending_cb_allow_remaining = allow_remaining; + new_pending_cb_expected_ctx = ctx; + new_pending_cb_expected_arg = arg; + new_pending_cb_ctx_matched = 1; + new_pending_cb_arg_matched = 1; +} + +static int new_pending_cb_fn(SSL_CTX *ctx, SSL *new_ssl, void *arg) +{ + new_pending_cb_call_count++; + if (ctx != new_pending_cb_expected_ctx) + new_pending_cb_ctx_matched = 0; + if (arg != new_pending_cb_expected_arg) + new_pending_cb_arg_matched = 0; + if (new_pending_cb_allow_remaining > 0) { + new_pending_cb_allow_remaining--; + return 1; + } + return 0; +} + +/* + * Common test body for the new_pending_conn_cb DTLS listener tests. + * + * Sets up a DTLS 1.3 listener, applies the given max_pending_conns cap, + * registers new_pending_cb_fn on the SSL_CTX, drives ClientHellos through + * the listener from num_clients distinct peers, then asserts that the + * listener's pending_conns table and the callback invocation counter + * match the caller's expectations. + * + * Parameters: + * max_pending + * Value written to SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS on the + * listener before any traffic is driven. Governs when the cap + * check short-circuits ahead of the callback. + * + * allow_remaining + * Initial admission budget for the callback. Each callback + * invocation that returns 1 decrements this counter; once it + * reaches 0, subsequent invocations return 0. Pass a value + * comfortably larger than num_clients (e.g. 100) for "always + * allow"; pass 0 for "always deny"; pass 1..num_clients-1 for + * "admit the first N then deny the rest". + * + * num_clients + * Number of distinct DTLS clients the helper creates and drives + * through cap_test_send_clienthello(). Must not exceed + * PENDING_CAP_TEST_CLIENTS (the compile-time size of the internal + * clients[] / client_fds[] arrays); the helper asserts this at + * runtime. + * + * expected_pending + * Number of entries expected in the listener's pending_conns + * after all ClientHellos have been driven. + * + * expected_calls + * Expected number of new_pending_cb_fn invocations. Interpretation + * depends on strict_cb_count. + * + * strict_cb_count + * 0 -> assert (call_count >= expected_calls); use this whenever + * the callback ever denies, because denied peers do not + * receive an HVR and their DTLS retransmit timer can produce + * extra callback invocations during the drain window. + * Non-zero -> assert (call_count == expected_calls); safe only + * when either (a) every callback invocation admits (HVR + * quiets the peer, no retransmits), or (b) the cap + * short-circuits ahead of the callback for excess peers. + * + * Returns 1 on success, 0 on any assertion failure. All resources + * (clients, sockets, listener, contexts) are freed on both paths. + */ +static int run_new_pending_cb_scenario(uint64_t max_pending, int allow_remaining, + int num_clients, int expected_pending, + int expected_calls, int strict_cb_count) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL; + SSL *clients[PENDING_CAP_TEST_CLIENTS] = { NULL }; + int client_fds[PENDING_CAP_TEST_CLIENTS] = { -1, -1, -1, -1, -1 }; + BIO_ADDR *server_addr = NULL; + int server_fd = -1; + int testresult = 0; + int cb_arg_marker = 0; + int i; + + if (!TEST_int_le(num_clients, PENDING_CAP_TEST_CLIENTS)) + return 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + 0, 0, + &sctx, &cctx, cert, privkey))) + goto err; + + if (!TEST_true(create_dtls_listener(sctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &server_addr, &server_fd))) + goto err; + + if (!TEST_true(SSL_set_generic_value_uint(listener, + SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS, max_pending))) + goto err; + + new_pending_cb_reset(sctx, &cb_arg_marker, allow_remaining); + SSL_CTX_set_new_pending_conn_cb(sctx, new_pending_cb_fn, &cb_arg_marker); + + for (i = 0; i < num_clients; i++) + if (!TEST_true(cap_test_send_clienthello(cctx, server_addr, listener, + &clients[i], &client_fds[i]))) + goto err; + + /* Verify the number of pending connections matches expectation. */ + if (!TEST_size_t_eq(ossl_dgram_conn_lookup_num_items( + ((DTLS_LISTENER *)listener)->pending_conns), + (size_t)expected_pending)) + goto err; + + /* + * Verify the callback was invoked as expected. + * + * Strict counts are only meaningful when we know retransmits cannot + * reach the callback (either because we sent an HVR to quiet the + * client, or because the cap short-circuits ahead of the callback). + * Otherwise assert only the lower bound. + */ + if (strict_cb_count) { + if (!TEST_int_eq(new_pending_cb_call_count, expected_calls)) + goto err; + } else { + if (!TEST_int_ge(new_pending_cb_call_count, expected_calls)) + goto err; + } + + /* Verify ctx and arg were passed through correctly on every call. */ + if (!TEST_true(new_pending_cb_ctx_matched)) + goto err; + if (!TEST_true(new_pending_cb_arg_matched)) + goto err; + + testresult = 1; + +err: + /* Clear callback so nothing else re-enters new_pending_cb_fn. */ + if (sctx != NULL) + SSL_CTX_set_new_pending_conn_cb(sctx, NULL, NULL); + + for (i = 0; i < num_clients; i++) { + SSL_free(clients[i]); + if (client_fds[i] >= 0) + BIO_closesocket(client_fds[i]); + } + + SSL_free(listener); + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Scenario 1: Callback allows every connection; cap is high enough that it + * never fires. + * + * Sends 3 ClientHellos, expects 3 pending connections registered, expects + * the callback to have been invoked exactly 3 times (once per novel peer; + * HVR keeps clients from retransmitting during the drain window). + */ +static int test_new_pending_cb_allow_all(void) +{ + return run_new_pending_cb_scenario(100, 100, 3, 3, 3, 1); +} + +/* + * Scenario 2: Callback rejects every connection; cap is high enough that it + * never fires. + * + * Sends 3 ClientHellos, expects 0 pending connections registered, expects + * the callback to have been invoked at least 3 times. On rejection no HVR + * is sent, so the client's DTLS retransmit timer may re-fire the callback + * during the drain window - we can only assert a lower bound. + */ +static int test_new_pending_cb_reject_all(void) +{ + return run_new_pending_cb_scenario(100, 0, 3, 0, 3, 0); +} + +/* + * Scenario 3: Cap set to LIMIT (3); callback always allows; 5 clients try to + * connect. + * + * The cap is checked before the callback, so after the LIMIT-th pending + * connection is registered the cap short-circuits subsequent packets and + * the callback is not invoked for them (this holds even under retransmits). + * + * Expected: + * - exactly PENDING_CAP_TEST_LIMIT (3) pending connections registered + * - callback invoked exactly PENDING_CAP_TEST_LIMIT (3) times + */ +static int test_new_pending_cb_blocked_by_cap(void) +{ + return run_new_pending_cb_scenario(PENDING_CAP_TEST_LIMIT, 100, + PENDING_CAP_TEST_CLIENTS, + PENDING_CAP_TEST_LIMIT, + PENDING_CAP_TEST_LIMIT, 1); +} + +/* + * Scenario 4: Cap set well above the client count; callback rejects every + * connection. + * + * Verifies that callback-side rejection alone is sufficient to keep + * pending_conns empty, even when the cap is not a factor. Sends 5 + * ClientHellos, expects 0 pending connections registered, expects the + * callback to have been invoked at least 5 times (retransmits may inflate + * the count - see scenario 2 for the rationale on the lower bound). + */ +static int test_new_pending_cb_all_denied_under_cap(void) +{ + return run_new_pending_cb_scenario(100, 0, PENDING_CAP_TEST_CLIENTS, + 0, PENDING_CAP_TEST_CLIENTS, 0); +} + +/* + * Scenario 5: Callback allows the first invocation and denies the rest. + * + * Verifies that the callback's return value is honored per-invocation + * rather than cached from the first call. Sends 2 ClientHellos with a + * high cap so the callback is always reached: + * - client 1: callback returns 1, pending connection is registered, + * an HVR is sent (so this client does not retransmit and re-enter + * the callback). + * - client 2: callback returns 0, connection is discarded silently; + * retransmits from client 2 may re-invoke the callback (all + * subsequent returns are also 0). + * + * Expected: + * - exactly 1 pending connection registered + * - callback invoked at least 2 times (lower-bound: retransmits from + * the denied client can inflate this) + */ +static int test_new_pending_cb_alternate(void) +{ + return run_new_pending_cb_scenario(100, 1, 2, 1, 2, 0); +} + +/* + * The two tests below need a listener with a notifier, which only exists + * when the listener is created without SSL_LISTENER_FLAG_SINGLE_THREAD. In a + * no-threads build that listener cannot be created at all, because the + * condition variable it needs is unavailable. + */ +#if defined(OPENSSL_THREADS) +/* + * Test that queueing a connection for accept signals the listener's notifier. + * + * A thread waiting in SSL_poll() for SSL_POLL_EVENT_IC is blocked on the + * listener's network socket and on its notifier. Where another thread does the + * demuxing, that socket does not necessarily become readable on the waiter's + * behalf, so the notifier is what has to wake it. + * + * Most of the time the bug this covers is masked. Every connection reaching + * the accept queue got there because a datagram was demuxed into its receive + * queue, and the packet handler has always signalled on that injection, so the + * waiter is woken, ticks the listener itself during its readout, and finds the + * connection. What is not covered by that is the window in which the injection + * and the queue push straddle a waiter registering, because signalling is + * conditional on there being a waiter at the time. + * + * The numbered steps below are that window - the interleaving of two threads + * which the fix exists to handle. They are not what this test does, and are + * given only so that what it does assert makes sense; see the end of this + * comment for how it is actually checked. + * + * 1. Accept thread A polls the listener for SSL_POLL_EVENT_IC. Its readout + * ticks the listener, finds nothing, and it decides to block. It is not + * a registered waiter yet. + * 2. Worker thread B polls one of its own connections, which also ticks the + * listener. The pump reads a client's final ClientHello and injects it + * into that pending connection's queue. There are no waiters, so nothing + * is signalled. + * 3. A enters the blocking section. Its re-check runs without ticking, so it + * sees only the accept queue, which is still empty, and it blocks. + * 4. B's tick reaches dtls_listener_drive_pending(), which completes the + * connection against the buffered ClientHello and pushes it onto the + * accept queue. + * + * Without a signal at step 4, A sleeps on with a validated connection sitting + * ready, until some unrelated datagram makes the socket readable again. B + * consumed the only one in flight, and the client is now waiting on the + * server, so on a quiet listener that is until the client retransmits. + * + * That interleaving cannot be forced from outside the library, so rather than + * reproducing the steps above, this drives their essential part by hand and on + * one thread: pumping the demux directly performs step 2, the signal it raises + * is then cleared, and the tick which follows can only signal by way of step 4. + * Asserting that it did is therefore asserting that a queue push signals. + * + * signalled_notifier is protected by the listener mutex in the library, which + * has to assume concurrent access. This test is single threaded throughout, so + * it reads the field directly without holding the mutex. + */ +static int test_dtls_notifier_signalled_on_accept_queue_push(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL, *clientssl = NULL; + BIO_ADDR *server_addr = NULL; + DTLS_LISTENER *dl; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result = 0; + int server_fd = -1, client_fd = -1; + int in_blocking_section = 0; + int abortctr, retc, err_code; + int testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), DTLS1_VERSION, 0, &sctx, &cctx, cert, + privkey))) + goto end; + + /* + * Multi-threaded mode (no SSL_LISTENER_FLAG_SINGLE_THREAD) so that the + * listener has a notifier at all. + */ + if (!TEST_true(create_dtls_listener(sctx, + 0, + &listener, &server_addr, &server_fd))) + goto end; + + dl = (DTLS_LISTENER *)listener; + if (!TEST_true(dl->have_notifier)) + goto end; + + if (!TEST_true(create_dtls_client_for_addr(cctx, server_addr, &clientssl, + &client_fd))) + goto end; + + /* Pose as a thread waiting for readiness, so signalling is enabled. */ + ossl_dtls_listener_enter_blocking_section(listener); + in_blocking_section = 1; + + /* + * Drive the cookie exchange, splitting each round into its two halves so + * that the two signalling opportunities can be told apart: + * + * - demuxing a datagram to a connection's receive queue, which the + * packet handler has always signalled, and + * - completing a connection and pushing it onto the accept queue. + * + * Pumping the demux directly performs only the first. The signal it + * raises is then cleared, so when the listener is next ticked the pump + * finds nothing new and only the accept queue push can signal. + * + * There is no public API for that split: SSL_poll() and + * SSL_accept_connection() both tick the listener, which does the two + * together. + */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + SSL_set_connect_state(clientssl); + for (abortctr = 0; abortctr < 100; abortctr++) { + retc = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, retc); + if (retc <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect failed (err %d)", err_code); + goto end; + } + + ossl_dgram_demux_pump(dl->demux); + + ossl_dtls_listener_leave_blocking_section(listener); + in_blocking_section = 0; + if (!TEST_int_eq(dl->signalled_notifier, 0)) + goto end; + ossl_dtls_listener_enter_blocking_section(listener); + in_blocking_section = 1; + + /* + * A zero timeout, so this ticks the listener and reads out the result + * without ever blocking, and therefore without itself entering a + * blocking section and clearing the signal we are watching for. + */ + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, + 0, &poll_result))) + goto end; + + if ((poll_item.revents & SSL_POLL_EVENT_IC) != 0) + break; + } + + if (!TEST_size_t_gt(SSL_get_accept_connection_queue_len(listener), 0)) + goto end; + + /* The accept queue push must have woken any waiter. */ + if (!TEST_int_eq(dl->signalled_notifier, 1)) + goto end; + + testresult = 1; +end: + if (in_blocking_section) + ossl_dtls_listener_leave_blocking_section(listener); + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + if (client_fd >= 0) + BIO_closesocket(client_fd); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test that a blocking SSL_poll() on a listener enters a blocking section. + * + * Unless it does, three things follow: the notifier is not in the poll set, so + * it cannot wake this thread; cur_blocking_waiters is never incremented, and + * since signalling is conditional on there being a waiter, no other thread + * even attempts to signal; and there is no re-check after registering, so + * readiness arising between the readout and the wait is lost. + * + * Polling the socket alone is not enough, though not because a wakeup can be + * missed outright. poll() reports whatever is currently sitting in the socket + * buffer and returns immediately if there is any, so a thread cannot miss a + * datagram just by being outside poll() when it arrives. What it can miss is a + * datagram another thread has already taken. With several threads polling the + * one shared socket that happens constantly: an arriving datagram wakes all of + * them, only one gets it, and the rest find nothing. Any of them can be the + * one that takes it, because SSL_read() on a connection pumps the demux and + * SSL_poll() on a connection ticks the whole listener. + * + * 1. Accept thread A polls the listener for SSL_POLL_EVENT_IC. Its readout + * ticks the listener, finds nothing, and it decides to block. + * 2. A client's final ClientHello lands on the shared socket. + * 3. Worker thread B, polling one of its own connections, ticks the listener + * and is the one that takes the datagram. Its tick completes the pending + * connection and pushes it onto the accept queue. Signalling is attempted, + * but A never registered as a waiter, so nothing is signalled. + * 4. A reaches its poll, watching the socket alone. B drained it, so it is + * empty, and A sleeps with a validated connection sitting on the accept + * queue. + * + * A's readout, back at step 1, would have found that connection had it run + * after step 3 rather than before it. Registering as a waiter and re-checking + * is what removes the dependency on that ordering. + * + * Note that the signal added for the step 3 queue push is itself conditional on + * a registered waiter, so it does nothing for a thread polling the listener + * until that thread registers. The two fixes are complementary. + * + * None of that has a public observable, and this deliberately does not time + * the wait. Instead it relies on the last waiter out of a blocking section + * draining a raised notifier signal: raise one beforehand, poll briefly with + * nothing ready, and check afterwards. Drained means a blocking section was + * entered and left, since only a leave drains it and only an enter can be left; + * still standing means neither happened. + * + * signalled_notifier is protected by the listener mutex in the library, which + * has to assume concurrent access. This test is single threaded throughout, so + * it reads and writes the field directly without holding the mutex. + * + * Note what this does not cover. That the notifier is in the poll set, and so + * can actually deliver a wakeup, is not checked: with a signal raised the poll + * returns at once if the notifier is being watched and sleeps out its timeout + * if it is not, and only timing separates those. A longer timeout would not + * help, because the first iteration's leave drains the notifier and the next + * one sleeps out the remainder either way. The re-check after registering is + * not covered either, since readiness arriving between the readout and the + * registration cannot be produced from a single thread. + */ +static int test_dtls_poll_listener_enters_blocking_section(void) +{ + SSL_CTX *sctx = NULL; + SSL *listener = NULL; + BIO_ADDR *server_addr = NULL; + DTLS_LISTENER *dl; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result = 0; + int server_fd = -1, nfd = -1; + int testresult = 0; + + if (!TEST_ptr(sctx = SSL_CTX_new(DTLS_server_method()))) + goto end; + + if (!TEST_true(create_dtls_listener(sctx, 0, &listener, &server_addr, + &server_fd))) + goto end; + + dl = (DTLS_LISTENER *)listener; + if (!TEST_true(dl->have_notifier)) + goto end; + + /* + * Raise the notifier as another thread reporting readiness would, which + * means both writing to the notifier and recording that it is raised, as + * dtls_listener_signal_notifier() does. + */ + if (!TEST_true(ossl_rio_notifier_signal(&dl->notifier))) + goto end; + dl->signalled_notifier = 1; + + nfd = ossl_rio_notifier_as_fd(&dl->notifier); + if (!TEST_int_ge(nfd, 0) + || !TEST_int_gt(BIO_socket_ready(nfd, /*for_read=*/1), 0)) + goto end; + + /* + * Poll with a short timeout. No client exists, so nothing is ever ready + * and SSL_poll() must block, which is what drives the translation that + * enters the blocking section. + */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 100000; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, + &poll_result))) + goto end; + + if (!TEST_size_t_eq(poll_result, 0)) + goto end; + + /* + * Leaving the blocking section must have drained the notifier. Check the + * notifier itself and not only the flag recording its state, since it is + * the notifier being readable that would spuriously wake a later waiter. + */ + if (!TEST_int_eq(BIO_socket_ready(nfd, /*for_read=*/1), 0)) + goto end; + + if (!TEST_int_eq(dl->signalled_notifier, 0)) + goto end; + + if (!TEST_size_t_eq(dl->cur_blocking_waiters, 0)) + goto end; + + testresult = 1; +end: + SSL_free(listener); + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + SSL_CTX_free(sctx); + return testresult; +} + +#endif /* OPENSSL_THREADS */ + +static unsigned int short_timer_cb_count; + +/* Force a short retransmission timeout and count how often it is consulted. */ +static unsigned int short_timer_cb(SSL *s, unsigned int timer_us) +{ + ++short_timer_cb_count; + return 50000; /* 50ms */ +} + +/* + * Force a retransmission timeout short enough that it is always already + * expired, so the timeout can be driven repeatedly without waiting. Anything + * at or below 15ms is treated as expired by dtls1_get_timeout(). + */ +static unsigned int tiny_timer_cb(SSL *s, unsigned int timer_us) +{ + return 1000; /* 1ms */ +} + +/* + * Test that the DTLS retransmission timer is stopped once the connection gives + * up retransmitting. + * + * dtls1_handle_timeout() fails the connection after DTLS1_TMO_ALERT_COUNT + * unanswered retransmissions. It must not leave the timer armed in the past + * when it does: nothing will re-arm or clear it afterwards, so every later + * query reports the timeout as due immediately, and any caller which waits on + * it spins instead of sleeping - whether that is an application using + * DTLSv1_get_timeout() with select(), or SSL_poll() bounding its own wait. + */ +static int test_dtls_timer_stopped_when_retransmits_exhausted(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + struct timeval timer_left; + int is_infinite = 0; + int retc, rets; + int testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), DTLS1_VERSION, 0, &sctx, &cctx, cert, + privkey))) + goto end; + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL))) + goto end; + + DTLS_set_timer_cb(serverssl, tiny_timer_cb); + + retc = SSL_connect(clientssl); + if (!TEST_int_le(retc, 0) + || !TEST_int_eq(SSL_get_error(clientssl, retc), SSL_ERROR_WANT_READ)) + goto end; + + /* + * With a timeout this short the server's timer is expired on every read + * attempt, so the accept retransmits until the budget runs out and fails + * the connection by itself. The client is never fed, so nothing is ever + * acknowledged. + * + * The retransmissions happen in dtls1_read_bytes(), which calls + * dtls1_handle_timeout() and, when it reports that it retransmitted, goes + * back to its start label to try the read again. + */ + rets = SSL_accept(serverssl); + if (!TEST_int_le(rets, 0) + || !TEST_int_eq(SSL_get_error(serverssl, rets), SSL_ERROR_SSL)) + goto end; + + /* The timer must not have been left armed in the past. */ + if (!TEST_true(SSL_get_event_timeout(serverssl, &timer_left, &is_infinite)) + || !TEST_true(is_infinite)) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test that a blocking SSL_poll() on a DTLS connection honours the + * retransmission timer. + * + * SSL_poll() bounds its wait by the per-object event timeout so that timer + * driven work is not delayed. For a DTLS connection that timeout is the + * handshake retransmission timer: if it is ignored, a poll with a long user + * timeout sleeps straight through the point at which the flight should have + * been resent, and if the peer had lost that flight neither side progresses. + * + * This does not time the wait. The retransmission timeout is forced down to + * 50ms and the poll is given much longer, so a correct implementation must + * wake and retransmit at least once before the poll deadline; an + * implementation which ignores the timer retransmits not at all. + */ +static int test_dtls_poll_conn_honours_retransmit_timer(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout, timer_left; + size_t poll_result = 0; + int is_infinite = 0; + int retc, rets, err_code; + int testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), DTLS1_VERSION, 0, &sctx, &cctx, cert, + privkey))) + goto end; + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL))) + goto end; + + /* + * Install the short timeout before the server sends anything, so that it + * is picked up when the retransmission timer is first started rather than + * only on a later expiry. + */ + DTLS_set_timer_cb(serverssl, short_timer_cb); + + /* + * Drive just far enough for the server to send its first flight and start + * its retransmission timer. The client is then left alone, so the flight + * stays unacknowledged for the duration of the poll. + */ + retc = SSL_connect(clientssl); + if (!TEST_int_le(retc, 0) + || !TEST_int_eq(SSL_get_error(clientssl, retc), SSL_ERROR_WANT_READ)) + goto end; + + /* + * The server consumes the ClientHello, sends its flight and then waits for + * the client, so this does not complete the handshake. + */ + rets = SSL_accept(serverssl); + if (!TEST_int_le(rets, 0)) + goto end; + + err_code = SSL_get_error(serverssl, rets); + if (!TEST_true(err_code == SSL_ERROR_WANT_READ + || err_code == SSL_ERROR_WANT_WRITE)) + goto end; + + /* + * Assert the precondition through the same call SSL_poll() uses to compute + * its deadline: a running timer is reported as a finite timeout. + */ + if (!TEST_true(SSL_get_event_timeout(serverssl, &timer_left, &is_infinite)) + || !TEST_false(is_infinite)) + goto end; + + short_timer_cb_count = 0; + + /* + * Nothing will arrive for this connection during the poll, so it runs to + * its deadline. Along the way the retransmission timer must expire and be + * serviced, which re-arms the timer via the callback. + */ + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = serverssl; + poll_item.events = SSL_POLL_EVENT_R; + poll_item.revents = 0; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 500000; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, 0, + &poll_result))) + goto end; + + if (!TEST_uint_gt(short_timer_cb_count, 0)) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Drive a client's ClientHello, and any cookie exchange, at the listener until + * a connection is sitting on its accept queue, without accepting it. + * + * Returns 1 on success, 0 on failure. + */ +static int drive_until_connection_queued(SSL *listener, SSL *clientssl) +{ + SSL_POLL_ITEM poll_item; + struct timeval poll_timeout; + size_t poll_result = 0; + int abortctr, retc, err_code; + + poll_item.desc.type = BIO_POLL_DESCRIPTOR_TYPE_SSL; + poll_item.desc.value.ssl = listener; + poll_timeout.tv_sec = 0; + poll_timeout.tv_usec = 0; + + SSL_set_connect_state(clientssl); + + for (abortctr = 0; abortctr < 200; abortctr++) { + retc = SSL_connect(clientssl); + err_code = SSL_get_error(clientssl, retc); + if (retc <= 0 + && err_code != SSL_ERROR_WANT_READ + && err_code != SSL_ERROR_WANT_WRITE) { + TEST_error("SSL_connect failed (err %d)", err_code); + return 0; + } + + /* A zero timeout, so this ticks the listener without ever waiting. */ + poll_item.events = SSL_POLL_EVENT_IC; + poll_item.revents = 0; + + if (!TEST_true(SSL_poll(&poll_item, 1, sizeof(poll_item), &poll_timeout, + 0, &poll_result))) + return 0; + + if ((poll_item.revents & SSL_POLL_EVENT_IC) != 0) + return 1; + + /* Loopback delivery can lag and a lost datagram needs a retransmit */ + OSSL_sleep(10); + } + + TEST_error("cookie exchange loop did not converge"); + return 0; +} + +/* + * Test the blocking mode of a DTLS listener and of the connections it creates. + * + * Blocking is the default, as it is for QUIC: a listener which was never + * configured is blocking, and a connection follows its listener unless it was + * given a setting of its own. + * + * Blocking is emulated by waiting for readiness of the listener's socket, so it + * needs a BIO which can supply a poll descriptor to wait on. Where there is + * none the object is non-blocking whatever was asked for, and asking for + * blocking fails rather than claiming something which cannot be delivered. + */ +static int test_dtls_blocking_mode(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL, *clientssl = NULL, *serverssl = NULL; + SSL *memlistener = NULL, *memclient = NULL, *plainssl = NULL; + BIO_ADDR *server_addr = NULL, *client_addr = NULL; + SSL_CONNECTION *sc; + int server_fd = -1, client_fd = -1; + int testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), DTLS1_VERSION, 0, &sctx, &cctx, cert, + privkey))) + goto end; + + /* + * create_dtls_listener() turns blocking mode off on behalf of the single + * threaded tests, so it cannot be used here: this test has to see the mode + * a listener has when the application has never set it. Hence the + * unconfigured variant. + * + * A socket BIO supplies a poll descriptor, so blocking is available. + */ + if (!TEST_true(create_dtls_listener_unconfigured(sctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &server_addr, &server_fd))) + goto end; + + /* Blocking by default, having never been configured. */ + if (!TEST_int_eq(SSL_get_blocking_mode(listener), 1)) + goto end; + + /* Get a connection object accepted from the listener to examine. */ + if (!TEST_true(create_dtls_client_for_addr(cctx, server_addr, &clientssl, + &client_fd))) + goto end; + + if (!drive_until_connection_queued(listener, clientssl) + || !TEST_ptr(serverssl = SSL_accept_connection(listener, + SSL_ACCEPT_CONNECTION_NO_BLOCK))) + goto end; + + /* It inherits the listener's mode. */ + + if (!TEST_int_eq(SSL_get_blocking_mode(serverssl), 1)) + goto end; + + /* Setting the listener non-blocking is inherited by the connection. */ + if (!TEST_true(SSL_set_blocking_mode(listener, 0)) + || !TEST_int_eq(SSL_get_blocking_mode(listener), 0) + || !TEST_int_eq(SSL_get_blocking_mode(serverssl), 0)) + goto end; + + /* A setting on the connection overrides what it would inherit. */ + if (!TEST_true(SSL_set_blocking_mode(serverssl, 1)) + || !TEST_int_eq(SSL_get_blocking_mode(serverssl), 1) + || !TEST_int_eq(SSL_get_blocking_mode(listener), 0)) + goto end; + + /* + * A connection's own setting survives SSL_clear(). The mode is a property + * of the connection as the application configured it, not of the handshake, + * and dtls1_clear() memsets d1 and restores only selected fields. + * + * The listener and the connection must disagree for this to prove anything: + * were the connection's setting lost it would fall back to inheriting, and + * that is only visible if the listener says something different. + */ + if (!TEST_true(SSL_set_blocking_mode(listener, 1)) + || !TEST_true(SSL_set_blocking_mode(serverssl, 0)) + || !TEST_int_eq(SSL_get_blocking_mode(listener), 1) + || !TEST_int_eq(SSL_get_blocking_mode(serverssl), 0)) + goto end; + + /* + * being_driven has to survive a clear as well, for a different reason: it + * records that the listener is driving this connection's handshake, and is + * what stops a concurrent tick collecting the same connection a second + * time. The listener can reach SSL_clear() from inside the very + * SSL_accept() it is driving, so losing it there would admit a second + * thread to the state machine for this connection. + * + * It has to be set by hand, being held only for the duration of a call + * inside the listener's tick, which is not observable from out here. + */ + if (!TEST_ptr(sc = SSL_CONNECTION_FROM_SSL_ONLY(serverssl))) + goto end; + sc->d1->being_driven = 1; + + if (!TEST_true(SSL_clear(serverssl)) + || !TEST_int_eq(SSL_get_blocking_mode(serverssl), 0) + || !TEST_ptr(sc = SSL_CONNECTION_FROM_SSL_ONLY(serverssl)) + || !TEST_int_eq(sc->d1->being_driven, 1)) + goto end; + + /* + * Clear again. SSL_clear() resets the method to the default one, so the + * first call above went through the ssl_deinit/ssl_init path that + * reallocates d1 while this one goes through dtls1_clear(). Both discard + * d1, so both have to be covered. + */ + if (!TEST_true(SSL_clear(serverssl)) + || !TEST_int_eq(SSL_get_blocking_mode(serverssl), 0) + || !TEST_ptr(sc = SSL_CONNECTION_FROM_SSL_ONLY(serverssl)) + || !TEST_int_eq(sc->d1->being_driven, 1)) + goto end; + + sc->d1->being_driven = 0; + + /* And back the other way round. */ + if (!TEST_true(SSL_set_blocking_mode(listener, 1)) + || !TEST_true(SSL_set_blocking_mode(serverssl, 0)) + || !TEST_int_eq(SSL_get_blocking_mode(listener), 1) + || !TEST_int_eq(SSL_get_blocking_mode(serverssl), 0)) + goto end; + + /* + * A listener on BIOs which cannot supply a poll descriptor reports + * non-blocking however it was configured, and asking for blocking fails. + */ + if (!TEST_true(create_dtls_listener_and_client_mem(sctx, cctx, + SSL_LISTENER_FLAG_SINGLE_THREAD, &memlistener, &memclient, + &client_addr))) + goto end; + + if (!TEST_int_eq(SSL_get_blocking_mode(memlistener), 0)) + goto end; + + ERR_clear_error(); + if (!TEST_false(SSL_set_blocking_mode(memlistener, 1)) + || !TEST_int_eq((int)ERR_GET_REASON(ERR_peek_error()), ERR_R_UNSUPPORTED)) + goto end; + ERR_clear_error(); + + /* Asking for non-blocking is fine, that being what it already is. */ + if (!TEST_true(SSL_set_blocking_mode(memlistener, 0)) + || !TEST_int_eq(SSL_get_blocking_mode(memlistener), 0)) + goto end; + + /* + * A DTLS object which did not come from a listener has no blocking mode: + * it takes its behaviour from its own BIO in the traditional way. + */ + if (!TEST_ptr(plainssl = SSL_new(cctx))) + goto end; + + if (!TEST_int_eq(SSL_get_blocking_mode(plainssl), -1) + || !TEST_false(SSL_set_blocking_mode(plainssl, 1)) + || !TEST_false(SSL_set_blocking_mode(plainssl, 0))) + goto end; + + testresult = 1; +end: + ERR_clear_error(); + SSL_free(plainssl); + SSL_free(memclient); + SSL_free(memlistener); + SSL_free(serverssl); + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(client_addr); + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + if (client_fd >= 0) + BIO_closesocket(client_fd); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Test when SSL_accept_connection() waits and when it does not. + * + * It waits only if the caller did not pass SSL_ACCEPT_CONNECTION_NO_BLOCK and + * the listener is in blocking mode, which is the same rule QUIC applies. So + * either of the two saying not to wait is enough, and this checks both of those + * cases: no client exists, so anything which did wait would never return. + */ +static int test_dtls_accept_wait_requires_mode_and_flag(void) +{ + SSL_CTX *sctx = NULL; + SSL *listener = NULL; + BIO_ADDR *server_addr = NULL; + int server_fd = -1; + int testresult = 0; + + if (!TEST_ptr(sctx = SSL_CTX_new(DTLS_server_method()))) + goto end; + + if (!TEST_true(create_dtls_listener(sctx, SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &server_addr, &server_fd))) + goto end; + + /* Non-blocking mode, and no flag: the mode alone stops it waiting. */ + if (!TEST_true(SSL_set_blocking_mode(listener, 0)) + || !TEST_ptr_null(SSL_accept_connection(listener, 0))) + goto end; + + /* Blocking mode, but the flag overrides it. */ + if (!TEST_true(SSL_set_blocking_mode(listener, 1)) + || !TEST_int_eq(SSL_get_blocking_mode(listener), 1) + || !TEST_ptr_null(SSL_accept_connection(listener, + SSL_ACCEPT_CONNECTION_NO_BLOCK))) + goto end; + + testresult = 1; +end: + SSL_free(listener); + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + SSL_CTX_free(sctx); + return testresult; +} + +/* + * Test that a rejected SSL_set_blocking_mode() leaves the mode alone. + * + * Whether blocking can be supported depends on the listener's BIO, so a + * request can be refused now and be perfectly deliverable later. The refusal + * must therefore not record the mode it refused to set: the effect only becomes + * visible once a BIO which can supply a poll descriptor is in place, at which + * point the listener would be found blocking on the strength of a call which + * failed. + */ +static int test_dtls_blocking_mode_failed_set_is_inert(void) +{ + SSL_CTX *sctx = NULL; + SSL *listener = NULL; + BIO_ADDR *server_addr = NULL; + BIO *rbio = NULL; + int server_fd = -1; + int testresult = 0; + + if (!TEST_ptr(sctx = SSL_CTX_new(DTLS_server_method()))) + goto end; + + if (!TEST_true(create_dtls_listener(sctx, SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &server_addr, &server_fd))) + goto end; + + /* Ask for non-blocking explicitly, so the default cannot mask a change. */ + if (!TEST_true(SSL_set_blocking_mode(listener, 0)) + || !TEST_int_eq(SSL_get_blocking_mode(listener), 0)) + goto end; + + /* Keep the BIO, then take it away so blocking cannot be supported. */ + if (!TEST_ptr(rbio = SSL_get_rbio(listener)) + || !TEST_true(BIO_up_ref(rbio))) + goto end; + + SSL_set0_rbio(listener, NULL); + + ERR_clear_error(); + if (!TEST_false(SSL_set_blocking_mode(listener, 1)) + || !TEST_int_eq((int)ERR_GET_REASON(ERR_peek_error()), + ERR_R_UNSUPPORTED)) { + BIO_free(rbio); + goto end; + } + ERR_clear_error(); + + /* Give the BIO back, which makes blocking supportable once more. */ + SSL_set0_rbio(listener, rbio); + + /* The refused request must not have taken effect. */ + if (!TEST_int_eq(SSL_get_blocking_mode(listener), 0)) + goto end; + + testresult = 1; +end: + SSL_free(listener); + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + SSL_CTX_free(sctx); + return testresult; +} + +/* + * State for the filter BIO below. + */ +struct failing_send_data { + int fails_remaining; /* sends still to be rejected */ + int sends; /* sends attempted through the filter */ +}; + +static long failing_send_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + BIO *next = BIO_next(bio); + + if (next == NULL) + return 0; + + if (cmd == BIO_CTRL_DUP) + return 0L; + + /* + * Everything else, the poll descriptors in particular, has to reach the + * socket underneath: the blocking write waits on the descriptor this + * returns. + */ + return BIO_ctrl(next, cmd, num, ptr); +} + +static int failing_send_sendmmsg(BIO *bio, BIO_MSG *msg, size_t stride, + size_t num_msg, uint64_t flags, size_t *msgs_processed) +{ + struct failing_send_data *data = BIO_get_data(bio); + BIO *next = BIO_next(bio); + + if (data == NULL || next == NULL) + return 0; + + data->sends++; + + if (data->fails_remaining > 0) { + data->fails_remaining--; + *msgs_processed = 0; + /* + * BIO_err_is_non_fatal() accepts this, so the record layer treats the + * send as one to be attempted again rather than as an error. + */ + ERR_raise(ERR_LIB_BIO, BIO_R_NON_FATAL); + return 0; + } + + return BIO_sendmmsg(next, msg, stride, num_msg, flags, msgs_processed); +} + +/* Choose a sufficiently large type likely to be unused for this custom BIO */ +#define BIO_TYPE_FAILING_SEND_FILTER (0x83 | BIO_TYPE_FILTER) + +static BIO_METHOD *method_failing_send = NULL; + +/* Note: Not thread safe! */ +static const BIO_METHOD *bio_f_failing_send_filter(void) +{ + if (method_failing_send == NULL) { + method_failing_send = BIO_meth_new(BIO_TYPE_FAILING_SEND_FILTER, + "Failing datagram send filter"); + if (method_failing_send == NULL + || !BIO_meth_set_ctrl(method_failing_send, failing_send_ctrl) + || !BIO_meth_set_sendmmsg(method_failing_send, + failing_send_sendmmsg)) + return NULL; + } + return method_failing_send; +} + +/* + * Test that a write on a blocking listener connection waits for the socket and + * sends again, rather than reporting that it needs to be retried. + * + * A datagram which cannot be sent is normally dropped, which is reasonable for + * an unreliable transport but is not what an application asking for blocking + * writes expects: it gets no data sent and a WANT_WRITE it did not ask to have + * to handle. The listener's socket is shared and always non-blocking, so there + * is nothing for such a write to block in by itself. + * + * A loopback socket's send buffer does not fill, so a filter BIO supplies the + * transient failure instead. Only one send is rejected: the retry then goes + * through, and the client is read to confirm the datagram was really sent + * rather than merely reported as sent. + * + * The handshake runs with the listener non-blocking, so this test drives both + * ends from the one thread as the others here do, and only the connection is + * switched to blocking, for the write. + */ +static int test_dtls_blocking_write(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *listener = NULL, *clientssl = NULL, *serverssl = NULL; + BIO_ADDR *server_addr = NULL; + BIO *sockbio = NULL, *filter = NULL; + struct failing_send_data data; + int server_fd = -1, client_fd = -1; + int testresult = 0; + char buf[256]; + size_t written = 0, readbytes = 0; + int i, ret = -1; + + memset(&data, 0, sizeof(data)); + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), DTLS1_VERSION, 0, &sctx, &cctx, cert, + privkey))) + goto end; + + if (!TEST_true(create_dtls_listener(sctx, SSL_LISTENER_FLAG_SINGLE_THREAD, + &listener, &server_addr, &server_fd))) + goto end; + + /* + * Insert the filter in front of the listener's socket for writes only, + * leaving reads to reach the socket directly. The listener holds a + * reference for each direction, so the filter chain needs one of its own. + */ + if (!TEST_ptr(sockbio = SSL_get_wbio(listener)) + || !TEST_ptr(filter = BIO_new(bio_f_failing_send_filter()))) + goto end; + + BIO_set_data(filter, &data); + BIO_set_init(filter, 1); + + if (!TEST_true(BIO_up_ref(sockbio))) { + BIO_free(filter); + goto end; + } + + BIO_push(filter, sockbio); + SSL_set0_wbio(listener, filter); /* the listener owns the chain now */ + filter = NULL; + + if (!TEST_true(create_dtls_client_for_addr(cctx, server_addr, &clientssl, + &client_fd))) + goto end; + + if (!drive_until_connection_queued(listener, clientssl) + || !TEST_ptr(serverssl = SSL_accept_connection(listener, + SSL_ACCEPT_CONNECTION_NO_BLOCK))) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + /* + * Everything up to here, including any post-handshake traffic, has gone + * through the filter untouched. Reject the next send only. + */ + if (!TEST_true(SSL_set_blocking_mode(serverssl, 1)) + || !TEST_int_eq(SSL_get_blocking_mode(serverssl), 1)) + goto end; + + data.sends = 0; + data.fails_remaining = 1; + + if (!TEST_true(SSL_write_ex(serverssl, "msg", 3, &written)) + || !TEST_size_t_eq(written, 3)) + goto end; + + /* + * The send really was rejected, and was retried rather than reported: the + * count proves a second attempt was made, which is the whole behaviour + * under test. Without it, a write which never reached the filter at all + * would look the same as one which was retried. + */ + if (!TEST_int_eq(data.fails_remaining, 0) + || !TEST_int_ge(data.sends, 2)) + goto end; + + /* The datagram reached the client, so nothing was dropped on the way. */ + for (i = 0; i < 20; i++) { + ret = SSL_read_ex(clientssl, buf, sizeof(buf), &readbytes); + if (ret == 1) + break; + if (!TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_WANT_READ)) + goto end; + OSSL_sleep(10); + } + + if (!TEST_int_eq(ret, 1) + || !TEST_mem_eq(buf, readbytes, "msg", 3)) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_free(listener); + BIO_ADDR_free(server_addr); + if (server_fd >= 0) + BIO_closesocket(server_fd); + if (client_fd >= 0) + BIO_closesocket(client_fd); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + BIO_meth_free(method_failing_send); + method_failing_send = NULL; + return testresult; +} + +OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n") + +int setup_tests(void) +{ + if (!test_skip_common_options()) { + TEST_error("Error parsing test options\n"); + return 0; + } + + if (!TEST_ptr(cert = test_get_argument(0)) + || !TEST_ptr(privkey = test_get_argument(1))) + return 0; + + /* Basic listener creation and configuration tests */ + ADD_TEST(test_dtls_new_listener); +#ifndef OPENSSL_NO_DTLS1_2 + ADD_TEST(test_dtls_new_listener_dtls12); +#endif + + /* BIO management tests */ + ADD_TEST(test_dtls_listener_bio); + + /* Listener API tests */ + ADD_TEST(test_dtls_get0_listener_non_dtls_listener); + ADD_TEST(test_dtls_get0_listener_listener); + ADD_TEST(test_dtls_listen_basic); + ADD_TEST(test_dtls_listen_wrong_type); + + /* Accept connection tests */ + ADD_TEST(test_dtls_accept_connection_wrong_type); + ADD_TEST(test_dtls_accept_connection_empty_no_block); + ADD_TEST(test_dtls_accept_connection_no_bio_no_block); + ADD_TEST(test_dtls_accept_connection_no_bio_block); + + /* Queue length tests */ + ADD_TEST(test_dtls_queue_len_wrong_type); + ADD_TEST(test_dtls_queue_len_empty); + + /* Peer address tests */ + ADD_TEST(test_dtls_get_peer_addr_no_peer); + ADD_TEST(test_dtls_get_peer_addr_listener); + + /* Error handling and edge case tests */ + ADD_TEST(test_dtls_new_listener_null_ctx); + ADD_TEST(test_tls_new_listener_fails); + ADD_TEST(test_dtls_new_listener_from_returns_null); + ADD_TEST(test_dtls_listen_ex_returns_error); + + /* DTLS 1.2 connection tests */ +#ifndef OPENSSL_NO_DTLS1_2 + ADD_TEST(test_dtls12_connection_with_hvr); + ADD_TEST(test_dtls12_connection_without_hvr); +#endif + +#ifndef OPENSSL_NO_DTLS1_3 + /* DTLS 1.3 connection tests */ + ADD_TEST(test_dtls13_connection_with_hrr); + ADD_TEST(test_dtls13_connection_without_hrr); + + /* Mixed version tests */ +#ifndef OPENSSL_NO_DTLS1_2 + ADD_TEST(test_dtls_mixed_12_hvr_and_13_hrr); +#endif + + /* Concurrent client tests */ + ADD_TEST(test_dtls_concurrent_clients_real_sockets); +#endif /* OPENSSL_NO_DTLS1_3 */ + + /* SSL_poll() specific tests */ + ADD_TEST(test_dtls_poll_conn_event_w); + ADD_TEST(test_dtls_poll_conn_dgram_pair_readable); + ADD_TEST(test_dtls_poll_conn_no_events_before_data); + ADD_TEST(test_dtls_poll_listener_multiple_events); + ADD_TEST(test_dtls_poll_conn_event_ec); + ADD_TEST(test_dtls_poll_null_item); + +#ifndef OPENSSL_NO_DTLS1_3 + /* Message buffering test */ + ADD_TEST(test_dtls13_listener_msg_buffering); +#endif /* OPENSSL_NO_DTLS1_3 */ + + /* Time callback tests */ + ADD_TEST(test_dtls_listener_time_callback_basic); + ADD_TEST(test_dtls_listener_time_callback_invalid); + + /* Pending timeout tests */ + ADD_TEST(test_dtls_listener_pending_timeout_basic); + ADD_TEST(test_dtls_listener_pending_timeout_invalid); + + /* Blocking mode tests */ + ADD_TEST(test_dtls_blocking_mode); + ADD_TEST(test_dtls_blocking_mode_failed_set_is_inert); + ADD_TEST(test_dtls_accept_wait_requires_mode_and_flag); + ADD_TEST(test_dtls_blocking_write); + + /* SSL object ownership tests (run with ASAN to detect leaks/double-frees) */ + ADD_TEST(test_ssl_ownership_pending_conn_leak); + ADD_TEST(test_ssl_ownership_incoming_conn_leak); +#ifndef OPENSSL_NO_DTLS1_3 + ADD_TEST(test_ssl_ownership_three_conn_states); +#endif + ADD_TEST(test_ssl_ownership_set_rbio_pending_leak); + ADD_TEST(test_ssl_ownership_accept_free_no_double_free); + ADD_TEST(test_ssl_ownership_set_rbio_incoming_leak); + ADD_TEST(test_ssl_ownership_multiple_pending_leak); + ADD_TEST(test_ssl_ownership_pending_timeout_cleanup); + + /* Max number of pending connections tests */ + ADD_TEST(test_dtls_listener_max_pending_conns_api); + ADD_TEST(test_dtls_listener_max_pending_conns_invalid); + ADD_TEST(test_dtls_listener_max_dgram_size_api); + ADD_TEST(test_dtls_listener_max_dgram_size_functional); + ADD_TEST(test_pending_conn_cap_enforcement); + ADD_TEST(test_pending_cap_with_timeout); + + /* new_pending_conn_cb tests (DTLS listener) */ + ADD_TEST(test_new_pending_cb_allow_all); + ADD_TEST(test_new_pending_cb_reject_all); + ADD_TEST(test_new_pending_cb_blocked_by_cap); + ADD_TEST(test_new_pending_cb_all_denied_under_cap); + ADD_TEST(test_new_pending_cb_alternate); + /* Blocking SSL_poll() wakeup tests */ +#if defined(OPENSSL_THREADS) + ADD_TEST(test_dtls_notifier_signalled_on_accept_queue_push); + ADD_TEST(test_dtls_poll_listener_enters_blocking_section); +#endif + ADD_TEST(test_dtls_poll_conn_honours_retransmit_timer); + ADD_TEST(test_dtls_timer_stopped_when_retransmits_exhausted); + + return 1; +} diff --git a/test/dtlstest.c b/test/dtlstest.c index 725d7dc4f2b86..5ce53270dce7e 100644 --- a/test/dtlstest.c +++ b/test/dtlstest.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -13,6 +13,10 @@ #include #include +#include "internal/nelem.h" +#include "internal/ssl_unwrap.h" +#include "../ssl/ssl_local.h" +#include "../ssl/record/methods/recmethod_local.h" #include "helpers/ssltestlib.h" #include "testutil.h" @@ -114,8 +118,10 @@ static int test_dtls_unprocessed(int testidx) */ c_to_s_mempacket = SSL_get_wbio(clientssl1); c_to_s_mempacket = BIO_next(c_to_s_mempacket); - mempacket_test_inject(c_to_s_mempacket, (char *)certstatus, - sizeof(certstatus), 1, INJECT_PACKET_IGNORE_REC_SEQ); + if (!TEST_int_gt(mempacket_test_inject(c_to_s_mempacket, (char *)certstatus, + sizeof(certstatus), 1, INJECT_PACKET_IGNORE_REC_SEQ), + 0)) + goto end; /* * Create the connection. We use "create_bare_ssl_connection" here so that @@ -178,25 +184,160 @@ static int test_dtls_unprocessed(int testidx) #define TOTAL_RECORDS (TOTAL_FULL_HAND_RECORDS + TOTAL_RESUME_HAND_RECORDS) -/* - * We are assuming a ServerKeyExchange message is sent in this test. If we don't - * have either DH or EC, then it won't be - */ #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) -static int test_dtls_drop_records(int idx) +#ifndef OPENSSL_NO_DTLS +static int test_dtls_drop_records(int serverwbio, int minversion, int maxversion, + int doresumption, int epoch, int idx); +#endif +#ifndef OPENSSL_NO_DTLS1_2 +static int test_dtls_drop_records_dtls1(int idx) +{ + int doresumption; + int cli_to_srv_cookie, cli_to_srv_epoch0, cli_to_srv_epoch1; + int srv_to_cli_epoch0; + int serverwbio; + int epoch = 0; + + if (idx >= TOTAL_FULL_HAND_RECORDS) { + doresumption = 1; + cli_to_srv_epoch0 = CLI_TO_SRV_RESUME_EPOCH_0_RECS; + cli_to_srv_epoch1 = CLI_TO_SRV_RESUME_EPOCH_1_RECS; + srv_to_cli_epoch0 = SRV_TO_CLI_RESUME_EPOCH_0_RECS; + cli_to_srv_cookie = CLI_TO_SRV_RESUME_COOKIE_EXCH; + idx -= TOTAL_FULL_HAND_RECORDS; + } else { + doresumption = 0; + cli_to_srv_epoch0 = CLI_TO_SRV_EPOCH_0_RECS; + cli_to_srv_epoch1 = CLI_TO_SRV_EPOCH_1_RECS; + srv_to_cli_epoch0 = SRV_TO_CLI_EPOCH_0_RECS; + cli_to_srv_cookie = CLI_TO_SRV_COOKIE_EXCH; + } + /* Work out which record to drop based on the test number */ + if (idx >= cli_to_srv_cookie + cli_to_srv_epoch0 + cli_to_srv_epoch1) { + serverwbio = 1; + idx -= cli_to_srv_cookie + cli_to_srv_epoch0 + cli_to_srv_epoch1; + if (idx >= SRV_TO_CLI_COOKIE_EXCH + srv_to_cli_epoch0) { + epoch = 1; + idx -= SRV_TO_CLI_COOKIE_EXCH + srv_to_cli_epoch0; + } + } else { + serverwbio = 0; + if (idx >= cli_to_srv_cookie + cli_to_srv_epoch0) { + epoch = 1; + idx -= cli_to_srv_cookie + cli_to_srv_epoch0; + } + } + + return test_dtls_drop_records(serverwbio, DTLS1_VERSION, DTLS1_2_VERSION, + doresumption, epoch, idx); +} +#endif /* OPENSSL_NO_DTLS1_2 */ + +/* ClientHello */ +#define DTLS13_CLI_TO_SRV_EPOCH_0_RECS_FULL 1 +/* ServerHello */ +#define DTLS13_SRV_TO_CLI_EPOCH_0_RECS_FULL 1 +/* Finish */ +#define DTLS13_CLI_TO_SRV_EPOCH_2_RECS_FULL 1 +/* EncryptedExtensions, Certificate, CertificateVerify, Finish */ +#define DTLS13_SRV_TO_CLI_EPOCH_2_RECS_FULL 4 + +#define DTLS13_TOTAL_HAND_RECORDS_FULL \ + (DTLS13_CLI_TO_SRV_EPOCH_0_RECS_FULL + DTLS13_SRV_TO_CLI_EPOCH_0_RECS_FULL \ + + DTLS13_CLI_TO_SRV_EPOCH_2_RECS_FULL + DTLS13_SRV_TO_CLI_EPOCH_2_RECS_FULL) + +/* ClientHello */ +#define DTLS13_CLI_TO_SRV_EPOCH_0_RECS_RESM 1 +/* ServerHello */ +#define DTLS13_SRV_TO_CLI_EPOCH_0_RECS_RESM 1 +/* Finish */ +#define DTLS13_CLI_TO_SRV_EPOCH_2_RECS_RESM 1 +/* EncryptedExtensions, Finish */ +#define DTLS13_SRV_TO_CLI_EPOCH_2_RECS_RESM 2 + +#define DTLS13_TOTAL_HAND_RECORDS_RESM \ + (DTLS13_CLI_TO_SRV_EPOCH_0_RECS_RESM + DTLS13_SRV_TO_CLI_EPOCH_0_RECS_RESM \ + + DTLS13_CLI_TO_SRV_EPOCH_2_RECS_RESM + DTLS13_SRV_TO_CLI_EPOCH_2_RECS_RESM) + +#define DTLS13_TOTAL_RECORDS \ + (DTLS13_TOTAL_HAND_RECORDS_FULL + DTLS13_TOTAL_HAND_RECORDS_RESM) + +#if !defined(OPENSSL_NO_INTEGRITY_ONLY_CIPHERS) && !defined(OPENSSL_NO_DTLS1_3) +/** + * test_dtls_drop_records_dtls13 tests DTLS 1.3 implementation robustness against + * dropped records + * + * @param idx + * + * idx: + * 0) Tests drop of ClientHello (Client) + * 1) Tests drop of Finish (Client) + * 2) Tests drop of ServerHello (Server) + * 3) Tests drop of EncryptedExtensions (Server) + * 4) Tests drop of Certificate (Server) + * 5) Tests drop of CertificateVerify (Server) + * 6) Tests drop of Finish (Server) + * 7) Tests drop of ClientHello (Client) in resumption + * 8) Tests drop of Finish (Client) in resumption + * 9) Tests drop of ServerHello (Server) in resumption + * 10) Tests drop of EncryptedExtensions (Server) in resumption + * 11) Tests drop of Finish (Server) in resumption + * + * @return 1 on success, 0 on failure + */ + +static int test_dtls_drop_records_dtls13(int idx) +{ + int doresumption; + int srv_to_cli_epoch0, cli_to_srv_epoch0, cli_to_srv_epoch2; + int serverwbio; + int epoch = 0; + + if (idx >= DTLS13_TOTAL_HAND_RECORDS_FULL) { + doresumption = 1; + cli_to_srv_epoch0 = DTLS13_CLI_TO_SRV_EPOCH_0_RECS_RESM; + cli_to_srv_epoch2 = DTLS13_CLI_TO_SRV_EPOCH_2_RECS_RESM; + srv_to_cli_epoch0 = DTLS13_SRV_TO_CLI_EPOCH_0_RECS_RESM; + idx -= DTLS13_TOTAL_HAND_RECORDS_FULL; + } else { + doresumption = 0; + cli_to_srv_epoch0 = DTLS13_CLI_TO_SRV_EPOCH_0_RECS_FULL; + cli_to_srv_epoch2 = DTLS13_CLI_TO_SRV_EPOCH_2_RECS_FULL; + srv_to_cli_epoch0 = DTLS13_SRV_TO_CLI_EPOCH_0_RECS_FULL; + } + /* Work out which record to drop based on the test number */ + if (idx >= cli_to_srv_epoch0 + cli_to_srv_epoch2) { + serverwbio = 1; + idx -= cli_to_srv_epoch0 + cli_to_srv_epoch2; + if (idx >= srv_to_cli_epoch0) { + epoch = 2; + idx -= srv_to_cli_epoch0; + } + } else { + serverwbio = 0; + if (idx >= cli_to_srv_epoch0) { + epoch = 2; + idx -= cli_to_srv_epoch0; + } + } + + return test_dtls_drop_records(serverwbio, DTLS1_3_VERSION, 0, doresumption, epoch, idx); +} +#endif /* !defined(OPENSSL_NO_INTEGRITY_ONLY_CIPHERS) */ + +#ifndef OPENSSL_NO_DTLS +static int test_dtls_drop_records(int serverwbio, int minversion, int maxversion, + int doresumption, int epoch, int idx) { SSL_CTX *sctx = NULL, *cctx = NULL; SSL *serverssl = NULL, *clientssl = NULL; BIO *c_to_s_fbio, *mempackbio; int testresult = 0; - int epoch = 0; SSL_SESSION *sess = NULL; - int cli_to_srv_cookie, cli_to_srv_epoch0, cli_to_srv_epoch1; - int srv_to_cli_epoch0; if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), DTLS_client_method(), - DTLS1_VERSION, 0, + minversion, maxversion, &sctx, &cctx, cert, privkey))) return 0; @@ -215,7 +356,19 @@ static int test_dtls_drop_records(int idx) SSL_CTX_set_cookie_generate_cb(sctx, generate_cookie_cb); SSL_CTX_set_cookie_verify_cb(sctx, verify_cookie_cb); - if (idx >= TOTAL_FULL_HAND_RECORDS) { + if (minversion == DTLS1_3_VERSION) { + /* + * Use integrity only cipher see we can obtain the sequence number + * in ssltestlib.c mempacket_test_read + */ + SSL_CTX_set_security_level(sctx, 0); + SSL_CTX_set_security_level(cctx, 0); + if (!TEST_true(SSL_CTX_set_ciphersuites(sctx, "TLS_SHA256_SHA256")) + || !TEST_true(SSL_CTX_set_ciphersuites(cctx, "TLS_SHA256_SHA256"))) + goto end; + } + + if (doresumption) { /* We're going to do a resumption handshake. Get a session first. */ if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) @@ -229,17 +382,6 @@ static int test_dtls_drop_records(int idx) SSL_free(serverssl); SSL_free(clientssl); serverssl = clientssl = NULL; - - cli_to_srv_epoch0 = CLI_TO_SRV_RESUME_EPOCH_0_RECS; - cli_to_srv_epoch1 = CLI_TO_SRV_RESUME_EPOCH_1_RECS; - srv_to_cli_epoch0 = SRV_TO_CLI_RESUME_EPOCH_0_RECS; - cli_to_srv_cookie = CLI_TO_SRV_RESUME_COOKIE_EXCH; - idx -= TOTAL_FULL_HAND_RECORDS; - } else { - cli_to_srv_epoch0 = CLI_TO_SRV_EPOCH_0_RECS; - cli_to_srv_epoch1 = CLI_TO_SRV_EPOCH_1_RECS; - srv_to_cli_epoch0 = SRV_TO_CLI_EPOCH_0_RECS; - cli_to_srv_cookie = CLI_TO_SRV_COOKIE_EXCH; } c_to_s_fbio = BIO_new(bio_f_tls_dump_filter()); @@ -259,20 +401,21 @@ static int test_dtls_drop_records(int idx) DTLS_set_timer_cb(clientssl, timer_cb); DTLS_set_timer_cb(serverssl, timer_cb); + /* + * The MTU Size was changed to be something more reasonable + * but for this test lets have a lot of records to be dropped. + */ + SSL_set_options(serverssl, SSL_OP_NO_QUERY_MTU); + SSL_set_options(clientssl, SSL_OP_NO_QUERY_MTU); + SSL_set_mtu(serverssl, 256); + SSL_set_mtu(clientssl, 256); + /* Work out which record to drop based on the test number */ - if (idx >= cli_to_srv_cookie + cli_to_srv_epoch0 + cli_to_srv_epoch1) { + if (serverwbio) { mempackbio = SSL_get_wbio(serverssl); - idx -= cli_to_srv_cookie + cli_to_srv_epoch0 + cli_to_srv_epoch1; - if (idx >= SRV_TO_CLI_COOKIE_EXCH + srv_to_cli_epoch0) { - epoch = 1; - idx -= SRV_TO_CLI_COOKIE_EXCH + srv_to_cli_epoch0; - } } else { mempackbio = SSL_get_wbio(clientssl); - if (idx >= cli_to_srv_cookie + cli_to_srv_epoch0) { - epoch = 1; - idx -= cli_to_srv_cookie + cli_to_srv_epoch0; - } + mempackbio = BIO_next(mempackbio); } BIO_ctrl(mempackbio, MEMPACKET_CTRL_SET_DROP_EPOCH, epoch, NULL); @@ -300,6 +443,7 @@ static int test_dtls_drop_records(int idx) return testresult; } +#endif /* OPENSSL_NO_DTLS */ #endif /* !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) */ static int test_cookie(void) @@ -318,7 +462,7 @@ static int test_cookie(void) SSL_CTX_set_cookie_generate_cb(sctx, generate_cookie_cb); SSL_CTX_set_cookie_verify_cb(sctx, verify_cookie_cb); -#ifdef OPENSSL_NO_DTLS1_2 +#if defined(OPENSSL_NO_DTLS1_2) && defined(OPENSSL_NO_DTLS1_3) /* Default sigalgs are SHA1 based in rlayer.wrl->epoch, 0) + || !TEST_uint64_t_gt(ssc->rlayer.wrl->epoch, 0)) + goto end; + + /* Drain post-handshake ACKs before manipulating the record state. */ + while (SSL_read(sssl, rdbuf, sizeof(rdbuf)) > 0) + continue; + while (SSL_read(cssl, rdbuf, sizeof(rdbuf)) > 0) + continue; + ERR_clear_error(); + + for (j = 0; j < 2; j++) { + SSL *wssl = j == 0 ? cssl : sssl; + SSL *rssl = j == 0 ? sssl : cssl; + SSL_CONNECTION *wsc = j == 0 ? csc : ssc; + SSL_CONNECTION *rsc = j == 0 ? ssc : csc; + + /* The writer must not go backwards: that would reuse a nonce */ + if (!TEST_uint64_t_ge(t->start, wsc->rlayer.wrl->sequence)) + goto end; + + wsc->rlayer.wrl->sequence = t->start; + + if (t->move_reader) { + rsc->rlayer.rrl->bitmap.max_seq_num = t->start - 1; + rsc->rlayer.rrl->bitmap.map = 1; + } + + for (i = 0; i < t->num; i++) { + memset(wrbuf, 0, sizeof(wrbuf)); + wrbuf[0] = (unsigned char)(i + 1); + + if (!TEST_int_eq(SSL_write(wssl, wrbuf, sizeof(wrbuf)), + (int)sizeof(wrbuf))) + goto end; + + /* The full sequence number keeps increasing across the wrap */ + if (!TEST_uint64_t_eq(wsc->rlayer.wrl->sequence, + t->start + i + 1)) + goto end; + + memset(rdbuf, 0, sizeof(rdbuf)); + if (!TEST_int_eq(SSL_read(rssl, rdbuf, sizeof(rdbuf)), + (int)sizeof(rdbuf)) + || !TEST_mem_eq(rdbuf, sizeof(rdbuf), wrbuf, + sizeof(wrbuf))) + goto end; + + /* ... and the peer has to have reconstructed the same value */ + if (!TEST_uint64_t_eq(rsc->rlayer.rrl->bitmap.max_seq_num, + t->start + i)) + goto end; + } + } + + testresult = 1; +end: + SSL_free(cssl); + SSL_free(sssl); + SSL_CTX_free(cctx); + SSL_CTX_free(sctx); + + return testresult; +} + +/* + * Keyed DTLS 1.3 epochs must silently discard DTLSPlaintext records + * (RFC 9147 sections 4 and 4.5.2). + */ + +/* + * RFC 9147 section 6.1 assigns epoch 2 to handshake traffic and epoch 3 to + * the first application traffic keys. + */ +#define DTLS13_HANDSHAKE_EPOCH 2 +#define DTLS13_APPLICATION_EPOCH 3 + +/* + * Genuine sequence numbers are close to zero in these tests. A sequence + * number of 100 is beyond the 64 record replay window, so accepting it would + * make the next genuine record stale. + */ +#define DTLS13_FAR_AHEAD_SEQUENCE 100 + +/* + * DTLSPlaintext has a 48 bit sequence number. Its maximum moves the replay + * window as far forward as the record format permits. Sequence zero is the + * first protected record in a newly installed epoch. + */ +#define DTLS13_MAX_PLAINTEXT_SEQUENCE ((((uint64_t)1) << 48) - 1) +#define DTLS13_FIRST_PROTECTED_SEQUENCE 0 + +static size_t make_forged_plaintext_record(unsigned char *out, + unsigned int epoch, uint64_t seq, + unsigned int type, + const unsigned char *body, + size_t bodylen) +{ + out[0] = (unsigned char)type; + out[1] = 0xfe; + out[2] = 0xfd; + out[3] = (unsigned char)(epoch >> 8); + out[4] = (unsigned char)epoch; + out[5] = (unsigned char)(seq >> 40); + out[6] = (unsigned char)(seq >> 32); + out[7] = (unsigned char)(seq >> 24); + out[8] = (unsigned char)(seq >> 16); + out[9] = (unsigned char)(seq >> 8); + out[10] = (unsigned char)seq; + out[11] = (unsigned char)(bodylen >> 8); + out[12] = (unsigned char)bodylen; + memcpy(out + 13, body, bodylen); + return 13 + bodylen; +} + +static size_t make_forged_alert(unsigned char *out, unsigned int epoch, + uint64_t seq, unsigned int level, + unsigned int descr) +{ + unsigned char body[2]; + + body[0] = (unsigned char)level; + body[1] = (unsigned char)descr; + return make_forged_plaintext_record(out, epoch, seq, SSL3_RT_ALERT, + body, sizeof(body)); +} + +static int do_dtls13_handshake(SSL *sssl, SSL *cssl) +{ + int i; + + /* + * An in memory DTLS 1.3 handshake completes in far fewer than 64 calls, + * even when its flights are fragmented. This isn't a protocol limit: it + * leaves ample room while making a stalled handshake fail promptly. + */ + for (i = 0; i < 64; i++) { + int rc = SSL_connect(cssl); + int rs = SSL_accept(sssl); + + if (SSL_is_init_finished(cssl) && SSL_is_init_finished(sssl)) + return 1; + if (rc <= 0) { + int e = SSL_get_error(cssl, rc); + + if (e != SSL_ERROR_WANT_READ && e != SSL_ERROR_WANT_WRITE) + return 0; + } + if (rs <= 0) { + int e = SSL_get_error(sssl, rs); + + if (e != SSL_ERROR_WANT_READ && e != SSL_ERROR_WANT_WRITE) + return 0; + } + } + return 0; +} + +/* Drain pending ACK and NewSessionTicket records. */ +static int drain_ssl(SSL *ssl) +{ + unsigned char buf[256]; + int ret; + + do { + ret = SSL_read(ssl, buf, sizeof(buf)); + } while (ret > 0); + + if (!TEST_int_eq(SSL_get_error(ssl, ret), SSL_ERROR_WANT_READ)) + return 0; + ERR_clear_error(); + return 1; +} + +static int inject_client_datagram(SSL *cssl, const unsigned char *pkt, + size_t pktlen) +{ + BIO *bio = SSL_get_wbio(cssl); + + if (!TEST_ptr(bio)) + return 0; + return TEST_int_eq(mempacket_test_inject(bio, (const char *)pkt, + (int)pktlen, -1, + INJECT_PACKET_IGNORE_REC_SEQ), + (int)pktlen); +} + +/* Rejected plaintext must not change state or disrupt application data. */ +static int test_dtls13_forged_plaintext_alert(int idx) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *sssl = NULL, *cssl = NULL; + unsigned char pkt[5 * 15]; + size_t pktlen = 0; + char msg[] = { 0x00, 0x01, 0x02, 0x03 }; + char buf[16]; + int ret, i, testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + DTLS1_3_VERSION, DTLS1_3_VERSION, + &sctx, &cctx, cert, privkey))) + return 0; + + if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))) + goto end; + + if (!TEST_true(do_dtls13_handshake(sssl, cssl))) + goto end; + + /* Consume any post-handshake ACKs and NewSessionTickets */ + if (!TEST_true(drain_ssl(cssl)) || !TEST_true(drain_ssl(sssl))) + goto end; + + switch (idx) { + case 0: + /* Spoofed close_notify */ + pktlen = make_forged_alert(pkt, DTLS13_APPLICATION_EPOCH, + DTLS13_FAR_AHEAD_SEQUENCE, SSL3_AL_WARNING, + SSL3_AD_CLOSE_NOTIFY); + break; + case 1: + /* Spoofed fatal alert (handshake_failure) */ + pktlen = make_forged_alert(pkt, DTLS13_APPLICATION_EPOCH, + DTLS13_FAR_AHEAD_SEQUENCE, SSL3_AL_FATAL, + SSL3_AD_HANDSHAKE_FAILURE); + break; + case 2: + /* user_cancelled with seq 2^48-1 (replay-window poison) */ + pktlen = make_forged_alert(pkt, DTLS13_APPLICATION_EPOCH, + DTLS13_MAX_PLAINTEXT_SEQUENCE, SSL3_AL_WARNING, + SSL_AD_USER_CANCELLED); + break; + case 3: + /* Trip the warning limit while preserving record framing. */ + for (i = 0; i < 5; i++) + pktlen += make_forged_alert(pkt + pktlen, + DTLS13_APPLICATION_EPOCH, 10 + i, SSL3_AL_WARNING, + SSL_AD_USER_CANCELLED); + break; + case 4: + /* Malformed alert body (fragment length 3) */ + pktlen = make_forged_alert(pkt, DTLS13_APPLICATION_EPOCH, + DTLS13_FAR_AHEAD_SEQUENCE, SSL3_AL_FATAL, + SSL3_AD_HANDSHAKE_FAILURE); + pkt[12] = 3; + pkt[15] = 0xff; + pktlen = 16; + break; + case 5: + /* Alert with an overlong body (longer than content + tag) */ + pktlen = make_forged_alert(pkt, DTLS13_APPLICATION_EPOCH, + DTLS13_FAR_AHEAD_SEQUENCE, SSL3_AL_WARNING, + SSL3_AD_CLOSE_NOTIFY); + pkt[11] = 0; + pkt[12] = 40; + memset(pkt + 15, 0xaa, 40 - 2); + pktlen = 13 + 40; + break; + case 6: + /* Type 22 used to reach AAD setup with an uninitialised WPACKET. */ + { + unsigned char body[40]; + + memset(body, 0xbb, sizeof(body)); + pktlen = make_forged_plaintext_record(pkt, + DTLS13_APPLICATION_EPOCH, DTLS13_FAR_AHEAD_SEQUENCE, + SSL3_RT_HANDSHAKE, body, sizeof(body)); + } + break; + case 7: + /* Same as case 6 with outer type ack(26) */ + { + unsigned char body[40]; + + memset(body, 0xcc, sizeof(body)); + pktlen = make_forged_plaintext_record(pkt, + DTLS13_APPLICATION_EPOCH, DTLS13_FAR_AHEAD_SEQUENCE, + SSL3_RT_ACK, body, sizeof(body)); + } + break; + default: + goto end; + } + + if (!inject_client_datagram(cssl, pkt, pktlen)) + goto end; + + /* It must be silently discarded without changing shutdown state. */ + ret = SSL_read(sssl, buf, sizeof(buf)); + if (!TEST_int_le(ret, 0) + || !TEST_int_eq(SSL_get_error(sssl, ret), SSL_ERROR_WANT_READ) + || !TEST_int_eq(SSL_get_shutdown(sssl), 0)) + goto end; + ERR_clear_error(); + + /* The association must still work: application data keeps flowing */ + if (!TEST_int_eq(SSL_write(cssl, msg, sizeof(msg)), (int)sizeof(msg)) + || !TEST_int_eq(ret = SSL_read(sssl, buf, sizeof(buf)), + (int)sizeof(msg)) + || !TEST_mem_eq(buf, sizeof(msg), msg, sizeof(msg))) + goto end; + + testresult = 1; +end: + SSL_free(cssl); + SSL_free(sssl); + SSL_CTX_free(cctx); + SSL_CTX_free(sctx); + + return testresult; +} + +/* + * Plant epoch 2 plaintext after ClientHello and verify that it is discarded + * when reparsed under epoch 2. + * + * idx 0: far ahead sequence makes Finished stale + * idx 1: fatal alert aborts the handshake + * idx 2: sequence 0 makes the first protected record look replayed + */ +static int test_dtls13_forged_plaintext_alert_plant(int idx) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *sssl = NULL, *cssl = NULL; + unsigned char pkt[15]; + size_t pktlen = 0; + char msg[] = { 0x00, 0x01, 0x02, 0x03 }; + char buf[16]; + int testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + DTLS1_3_VERSION, DTLS1_3_VERSION, + &sctx, &cctx, cert, privkey))) + return 0; + + if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))) + goto end; + + /* Send flight 1: ClientHello */ + if (!TEST_int_le(SSL_connect(cssl), 0)) + goto end; + + switch (idx) { + case 0: + pktlen = make_forged_alert(pkt, DTLS13_HANDSHAKE_EPOCH, + DTLS13_MAX_PLAINTEXT_SEQUENCE, SSL3_AL_WARNING, + SSL_AD_USER_CANCELLED); + break; + case 1: + pktlen = make_forged_alert(pkt, DTLS13_HANDSHAKE_EPOCH, + DTLS13_FIRST_PROTECTED_SEQUENCE, SSL3_AL_FATAL, + SSL3_AD_HANDSHAKE_FAILURE); + break; + case 2: + pktlen = make_forged_alert(pkt, DTLS13_HANDSHAKE_EPOCH, + DTLS13_FIRST_PROTECTED_SEQUENCE, SSL3_AL_WARNING, + SSL_AD_USER_CANCELLED); + break; + default: + goto end; + } + + if (!inject_client_datagram(cssl, pkt, pktlen)) + goto end; + + /* The handshake must complete despite the plant */ + if (!TEST_true(do_dtls13_handshake(sssl, cssl))) + goto end; + + /* Application data must flow in both directions */ + if (!TEST_int_eq(SSL_write(cssl, msg, sizeof(msg)), (int)sizeof(msg)) + || !TEST_int_eq(SSL_read(sssl, buf, sizeof(buf)), (int)sizeof(msg)) + || !TEST_mem_eq(buf, sizeof(msg), msg, sizeof(msg)) + || !TEST_int_eq(SSL_write(sssl, msg, sizeof(msg)), (int)sizeof(msg)) + || !TEST_int_eq(SSL_read(cssl, buf, sizeof(buf)), (int)sizeof(msg)) + || !TEST_mem_eq(buf, sizeof(msg), msg, sizeof(msg))) + goto end; + + testresult = 1; +end: + SSL_free(cssl); + SSL_free(sssl); + SSL_CTX_free(cctx); + SSL_CTX_free(sctx); + + return testresult; +} + +/* Epoch 0 plaintext alerts must still reach the handshake. */ +static int test_dtls13_epoch0_plaintext_alert(void) +{ +#ifdef OPENSSL_NO_EC + const char *group = "ffdhe3072"; +#else + const char *group = "P-256"; +#endif + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *sssl = NULL, *cssl = NULL; + unsigned char pkt[15]; + size_t pktlen; + int ret, i, testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + DTLS1_3_VERSION, DTLS1_3_VERSION, + &sctx, &cctx, cert, privkey))) + return 0; + + /* Keep ClientHello in one record so sequence number 1 remains unused. */ + if (!TEST_true(SSL_CTX_set1_groups_list(sctx, group)) + || !TEST_true(SSL_CTX_set1_groups_list(cctx, group))) + goto end; + + if (!TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))) + goto end; + + /* Send flight 1: ClientHello */ + if (!TEST_int_le(SSL_connect(cssl), 0)) + goto end; + + /* ClientHello used sequence 0, so inject the alert with sequence 1. */ + pktlen = make_forged_alert(pkt, 0, 1, SSL3_AL_FATAL, + SSL3_AD_HANDSHAKE_FAILURE); + if (!inject_client_datagram(cssl, pkt, pktlen)) + goto end; + + /* The epoch 0 alert must fail the handshake. */ + ret = SSL_accept(sssl); + for (i = 0; i < 3 && ret <= 0 + && SSL_get_error(sssl, ret) == SSL_ERROR_WANT_READ; + i++) + ret = SSL_accept(sssl); + if (!TEST_int_le(ret, 0) + || !TEST_int_eq(SSL_get_error(sssl, ret), SSL_ERROR_SSL) + || !TEST_int_eq(ERR_GET_REASON(ERR_peek_last_error()), + SSL_AD_REASON_OFFSET + SSL3_AD_HANDSHAKE_FAILURE) + || !TEST_true((SSL_get_shutdown(sssl) & SSL_RECEIVED_SHUTDOWN) != 0)) + goto end; + ERR_clear_error(); + + testresult = 1; +end: + SSL_free(cssl); + SSL_free(sssl); + SSL_CTX_free(cctx); + SSL_CTX_free(sctx); + + return testresult; +} + +/* + * RFC 9147 (DTLS 1.3): TLS_AES_128_CCM_8_SHA256 MUST NOT be used in DTLS + * without additional safeguards against forgery, due to its short + * authentication tag. OpenSSL does not implement such safeguards, so a + * DTLS1.3 connection offering only this ciphersuite must fail to find a + * usable cipher rather than falling back to negotiating it anyway. + */ +static int test_dtls13_ccm8_not_offered(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + int testresult = 0; + int ret; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + DTLS1_3_VERSION, DTLS1_3_VERSION, + &sctx, &cctx, cert, privkey))) + return 0; + + /* CCM8 ciphers are considered low security due to their short tag */ + SSL_CTX_set_security_level(sctx, 0); + SSL_CTX_set_security_level(cctx, 0); + + if (!TEST_true(SSL_CTX_set_ciphersuites(sctx, TLS1_3_RFC_AES_128_CCM_8_SHA256)) + || !TEST_true(SSL_CTX_set_ciphersuites(cctx, TLS1_3_RFC_AES_128_CCM_8_SHA256))) + goto end; + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL))) + goto end; + + /* + * The client must fail before it can even construct a ClientHello: it + * has no cipher left that is permitted under DTLS to offer. + */ + if (!TEST_int_le(ret = SSL_connect(clientssl), 0) + || !TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_SSL) + || !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), + SSL_R_NO_CIPHERS_AVAILABLE)) + goto end; + ERR_clear_error(); + + /* The server independently has nothing usable configured either */ + if (!TEST_int_le(ret = SSL_accept(serverssl), 0) + || !TEST_int_eq(SSL_get_error(serverssl, ret), SSL_ERROR_SSL) + || !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), + SSL_R_NO_CIPHERS_AVAILABLE)) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} +#endif /* OPENSSL_NO_DTLS1_3 */ /* Confirm that we can create a connections using DTLSv1_listen() */ +#ifndef OPENSSL_NO_DTLS1_2 static int test_listen(void) { SSL_CTX *sctx = NULL, *cctx = NULL; @@ -694,14 +1550,6 @@ static int test_listen(void) &sctx, &cctx, cert, privkey))) return 0; -#ifdef OPENSSL_NO_DTLS1_2 - /* Default sigalgs are SHA1 based in 0 && processed != NULL && *processed > 0) { + /* A nonzero deadline in the past makes the next timeout check fire. */ + sc->d1->next_timeout = ossl_ticks2time(1); + BIO_set_callback_arg(b, NULL); + } + return ret; +} + +/* + * Drive a DTLS 1.3 handshake until the server has completed. At that point + * the client has sent its Finished flight with the retransmission timer + * armed, and the server's ACK is queued for the client, unread. + */ +static int drive_until_server_finished(SSL *sssl, SSL *cssl) +{ + int i, rc, rs, e; + + for (i = 0; i < 64 && !SSL_is_init_finished(sssl); i++) { + if (!SSL_is_init_finished(cssl)) { + rc = SSL_connect(cssl); + if (rc <= 0) { + e = SSL_get_error(cssl, rc); + if (!TEST_true(e == SSL_ERROR_WANT_READ + || e == SSL_ERROR_WANT_WRITE)) + return 0; + } + } + rs = SSL_accept(sssl); + if (rs <= 0) { + e = SSL_get_error(sssl, rs); + if (!TEST_true(e == SSL_ERROR_WANT_READ || e == SSL_ERROR_WANT_WRITE)) + return 0; + } + } + return SSL_is_init_finished(sssl); +} + +/* + * Expire the timer after the initial timeout check, while receiving the ACK. + * Reading the rest of the ACK must not retransmit and overwrite its prefix. + */ +static int test_dtls13_ack_read_timeout(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *sssl = NULL, *cssl = NULL; + SSL_CONNECTION *sc; + BIO *rbio = NULL; + int testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), DTLS1_3_VERSION, DTLS1_3_VERSION, + &sctx, &cctx, cert, privkey))) + return 0; + + /* Leave only the ACK queued for the client. */ + if (!TEST_true(SSL_CTX_set_num_tickets(sctx, 0)) + || !TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL)) + || !TEST_true(drive_until_server_finished(sssl, cssl))) + goto end; + + if (!TEST_ptr(sc = SSL_CONNECTION_FROM_SSL_ONLY(cssl)) + || !TEST_false(SSL_is_init_finished(cssl)) + || !TEST_false(ossl_time_is_zero(sc->d1->next_timeout))) + goto end; + + /* Prevent expiry before the BIO callback, independently of elapsed time. */ + sc->d1->next_timeout = ossl_time_infinite(); + rbio = SSL_get_rbio(cssl); + BIO_set_callback_arg(rbio, (char *)sc); + BIO_set_callback_ex(rbio, ack_read_timeout_cb); + + if (!TEST_int_eq(SSL_connect(cssl), 1) + || !TEST_ptr_null(BIO_get_callback_arg(rbio)) + || !TEST_true(SSL_is_init_finished(cssl)) + || !TEST_true(SSL_is_init_finished(sssl))) + goto end; + + testresult = 1; +end: + if (rbio != NULL) { + BIO_set_callback_ex(rbio, NULL); + BIO_set_callback_arg(rbio, NULL); + } + SSL_free(cssl); + SSL_free(sssl); + SSL_CTX_free(cctx); + SSL_CTX_free(sctx); + return testresult; +} +#endif /* OPENSSL_NO_DTLS1_3 */ OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n") @@ -745,14 +1693,36 @@ int setup_tests(void) ADD_ALL_TESTS(test_dtls_unprocessed, NUM_TESTS); #if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_EC) - ADD_ALL_TESTS(test_dtls_drop_records, TOTAL_RECORDS); +#ifndef OPENSSL_NO_DTLS1_2 + ADD_ALL_TESTS(test_dtls_drop_records_dtls1, TOTAL_RECORDS); +#endif +#if !defined(OPENSSL_NO_INTEGRITY_ONLY_CIPHERS) && !defined(OPENSSL_NO_DTLS1_3) + ADD_ALL_TESTS(test_dtls_drop_records_dtls13, DTLS13_TOTAL_RECORDS); +#endif #endif ADD_TEST(test_cookie); ADD_TEST(test_dtls_duplicate_records); ADD_TEST(test_just_finished); - ADD_ALL_TESTS(test_swap_records, 4); +#ifndef OPENSSL_NO_DTLS1_2 + ADD_ALL_TESTS(test_swap_records_dtls1, 4); +#endif +#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECX) && !defined(OPENSSL_NO_ML_KEM) \ + && !defined(OPENSSL_NO_DTLS1_3) + ADD_ALL_TESTS(test_swap_records_dtls13, 4); +#endif +#ifndef OPENSSL_NO_DTLS1_2 ADD_TEST(test_listen); - ADD_TEST(test_duplicate_app_data); + ADD_TEST(test_duplicate_app_data_dtls1); +#endif +#ifndef OPENSSL_NO_DTLS1_3 + ADD_TEST(test_duplicate_app_data_dtls13); + ADD_ALL_TESTS(test_seq_num_wrap, OSSL_NELEM(seqnum_tests)); + ADD_ALL_TESTS(test_dtls13_forged_plaintext_alert, 8); + ADD_ALL_TESTS(test_dtls13_forged_plaintext_alert_plant, 3); + ADD_TEST(test_dtls13_epoch0_plaintext_alert); + ADD_TEST(test_dtls13_ccm8_not_offered); + ADD_TEST(test_dtls13_ack_read_timeout); +#endif return 1; } diff --git a/test/dtlsv1listentest.c b/test/dtlsv1listentest.c index b4c15fb962f27..2f103ecfa38b8 100644 --- a/test/dtlsv1listentest.c +++ b/test/dtlsv1listentest.c @@ -7,15 +7,29 @@ * https://www.openssl.org/source/license.html */ +#include #include #include #include #include #include #include "internal/nelem.h" +#include "internal/ssl_unwrap.h" +#include "internal/time.h" +#include "../ssl/ssl_local.h" +#include "helpers/ssltestlib.h" #include "testutil.h" #ifndef OPENSSL_NO_SOCK +#include "internal/sockets.h" +#endif + +static char *cert = NULL; +static char *privkey = NULL; + +#ifndef OPENSSL_NO_SOCK + +#define DTLS_RECORD_EPOCH_AND_SEQ_LEN 8 /* Just a ClientHello without a cookie */ static const unsigned char clienthello_nocookie[] = { @@ -216,6 +230,208 @@ static const unsigned char record_short[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* Record sequence number */ }; +/* + * DTLSv1.3 packet variants. + * + * Per RFC 9147, epoch-0 ClientHellos use the same legacy 13-byte record + * header as DTLS 1.2, with legacy_record_version = 0xFEFD and + * legacy_client_version = 0xFEFD. DTLS 1.3 is signalled only via the + * supported_versions extension (type 0x002B, value 0xFEFC). + * + * Each packet below is derived from its DTLS 1.2 counterpart by replacing + * the empty extensions block (0x00 0x00) with a 9-byte block: + * 0x00 0x07 extensions_len = 7 + * 0x00 0x2B 0x00 0x03 supported_versions ext, 3 bytes of data + * 0x02 versions list len = 2 + * 0xFE 0xFC DTLSv1.3 + * and adjusting record_len / msg_len / frag_len accordingly (+7). + * Fragments that stop before the extensions block only have msg_len updated. + */ + +/* A DTLSv1.3 ClientHello without a cookie */ +static const unsigned char clienthello13_nocookie[] = { + 0x16, /* Handshake */ + 0xFE, 0xFF, /* legacy record version = DTLSv1.0 */ + 0x00, 0x00, /* Epoch */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */ + 0x00, 0x41, /* Record Length (0x3A + 7) */ + 0x01, /* ClientHello */ + 0x00, 0x00, 0x35, /* Message length (0x2E + 7) */ + 0x00, 0x00, /* Message sequence */ + 0x00, 0x00, 0x00, /* Fragment offset */ + 0x00, 0x00, 0x35, /* Fragment length (0x2E + 7) */ + 0xFE, 0xFD, /* legacy_client_version = DTLSv1.2 */ + 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90, + 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56, + 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */ + 0x00, /* Session id len */ + 0x00, /* Cookie len */ + 0x00, 0x04, /* Ciphersuites len */ + 0x13, 0x01, /* TLS_AES_128_GCM_SHA256 */ + 0x13, 0x02, /* TLS_AES_256_GCM_SHA384 */ + 0x01, /* Compression methods len */ + 0x00, /* Null compression */ + 0x00, 0x07, /* Extensions len */ + 0x00, 0x2B, /* supported_versions */ + 0x00, 0x03, /* ext data len */ + 0x02, /* versions list len */ + 0xFE, 0xFC /* DTLSv1.3 */ +}; + +/* + * First fragment of a DTLSv1.3 ClientHello without a cookie. + * Fragment stops after cookie len (before extensions); only msg_len is + * updated to reflect the full message size including extensions. + */ +static const unsigned char clienthello13_nocookie_frag[] = { + 0x16, /* Handshake */ + 0xFE, 0xFF, /* legacy record version = DTLSv1.0 */ + 0x00, 0x00, /* Epoch */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */ + 0x00, 0x30, /* Record Length (unchanged - fragment content same) */ + 0x01, /* ClientHello */ + 0x00, 0x00, 0x35, /* Message length (0x2E + 7 - full message size) */ + 0x00, 0x00, /* Message sequence */ + 0x00, 0x00, 0x00, /* Fragment offset */ + 0x00, 0x00, 0x24, /* Fragment length (unchanged) */ + 0xFE, 0xFD, /* legacy_client_version = DTLSv1.2 */ + 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90, + 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56, + 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */ + 0x00, /* Session id len */ + 0x00 /* Cookie len */ +}; + +/* A DTLSv1.3 ClientHello with a good cookie */ +static const unsigned char clienthello13_cookie[] = { + 0x16, /* Handshake */ + 0xFE, 0xFF, /* legacy record version = DTLSv1.0 */ + 0x00, 0x00, /* Epoch */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */ + 0x00, 0x55, /* Record Length (0x4E + 7) */ + 0x01, /* ClientHello */ + 0x00, 0x00, 0x49, /* Message length (0x42 + 7) */ + 0x00, 0x00, /* Message sequence */ + 0x00, 0x00, 0x00, /* Fragment offset */ + 0x00, 0x00, 0x49, /* Fragment length (0x42 + 7) */ + 0xFE, 0xFD, /* legacy_client_version = DTLSv1.2 */ + 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90, + 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56, + 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */ + 0x00, /* Session id len */ + 0x14, /* Cookie len */ + 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie */ + 0x00, 0x04, /* Ciphersuites len */ + 0x13, 0x01, /* TLS_AES_128_GCM_SHA256 */ + 0x13, 0x02, /* TLS_AES_256_GCM_SHA384 */ + 0x01, /* Compression methods len */ + 0x00, /* Null compression */ + 0x00, 0x07, /* Extensions len */ + 0x00, 0x2B, /* supported_versions */ + 0x00, 0x03, /* ext data len */ + 0x02, /* versions list len */ + 0xFE, 0xFC /* DTLSv1.3 */ +}; + +/* + * Second fragment of a DTLSv1.3 ClientHello without a cookie. + * Mirrors clienthello_2ndfrag but with the DTLSv1.3 full message length. + * Fragment offset 2 skips the legacy_client_version field sent in the first + * fragment. Because the fragment offset is non-zero, DTLSv1_listen must + * drop this packet (it cannot reconstruct a complete ClientHello from it). + * + * Full DTLSv1.3 nocookie message body = 0x35 bytes (0x2E + 7 for the + * supported_versions extension). Fragment skips first 2 bytes (version), + * so fragment length = 0x35 - 2 = 0x33. + * Record length = 1 + 3 + 2 + 3 + 3 + 0x33 = 0x3F. + */ +static const unsigned char clienthello13_2ndfrag[] = { + 0x16, /* Handshake */ + 0xFE, 0xFF, /* legacy record version = DTLSv1.0 */ + 0x00, 0x00, /* Epoch */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */ + 0x00, 0x3F, /* Record Length */ + 0x01, /* ClientHello */ + 0x00, 0x00, 0x35, /* Message length (0x2E + 7 - full nocookie message) */ + 0x00, 0x00, /* Message sequence */ + 0x00, 0x00, 0x02, /* Fragment offset */ + 0x00, 0x00, 0x33, /* Fragment length (0x35 - 2 bytes skipped) */ + /* legacy_client_version skipped - sent in first fragment */ + 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90, + 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56, + 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */ + 0x00, /* Session id len */ + 0x00, /* Cookie len */ + 0x00, 0x04, /* Ciphersuites len */ + 0x13, 0x01, /* TLS_AES_128_GCM_SHA256 */ + 0x13, 0x02, /* TLS_AES_256_GCM_SHA384 */ + 0x01, /* Compression methods len */ + 0x00, /* Null compression */ + 0x00, 0x07, /* Extensions len */ + 0x00, 0x2B, /* supported_versions */ + 0x00, 0x03, /* ext data len */ + 0x02, /* versions list len */ + 0xFE, 0xFC /* DTLSv1.3 */ +}; + +/* A DTLSv1.3 ClientHello with a bad cookie */ +static const unsigned char clienthello13_badcookie[] = { + 0x16, /* Handshake */ + 0xFE, 0xFF, /* legacy record version = DTLSv1.0 */ + 0x00, 0x00, /* Epoch */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */ + 0x00, 0x55, /* Record Length (0x4E + 7) */ + 0x01, /* ClientHello */ + 0x00, 0x00, 0x49, /* Message length (0x42 + 7) */ + 0x00, 0x00, /* Message sequence */ + 0x00, 0x00, 0x00, /* Fragment offset */ + 0x00, 0x00, 0x49, /* Fragment length (0x42 + 7) */ + 0xFE, 0xFD, /* legacy_client_version = DTLSv1.2 */ + 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90, + 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56, + 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */ + 0x00, /* Session id len */ + 0x14, /* Cookie len */ + 0x01, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, /* Cookie (first byte wrong) */ + 0x00, 0x04, /* Ciphersuites len */ + 0x13, 0x01, /* TLS_AES_128_GCM_SHA256 */ + 0x13, 0x02, /* TLS_AES_256_GCM_SHA384 */ + 0x01, /* Compression methods len */ + 0x00, /* Null compression */ + 0x00, 0x07, /* Extensions len */ + 0x00, 0x2B, /* supported_versions */ + 0x00, 0x03, /* ext data len */ + 0x02, /* versions list len */ + 0xFE, 0xFC /* DTLSv1.3 */ +}; + +/* + * A DTLSv1.3 fragmented ClientHello with the fragment boundary mid-cookie. + * Fragment stops mid-cookie (before extensions); only msg_len is updated. + */ +static const unsigned char clienthello13_cookie_short[] = { + 0x16, /* Handshake */ + 0xFE, 0xFF, /* legacy record version = DTLSv1.0 */ + 0x00, 0x00, /* Epoch */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Record sequence number */ + 0x00, 0x43, /* Record Length (unchanged - fragment content same) */ + 0x01, /* ClientHello */ + 0x00, 0x00, 0x49, /* Message length (0x42 + 7 - full message size) */ + 0x00, 0x00, /* Message sequence */ + 0x00, 0x00, 0x00, /* Fragment offset */ + 0x00, 0x00, 0x37, /* Fragment length (unchanged) */ + 0xFE, 0xFD, /* legacy_client_version = DTLSv1.2 */ + 0xCA, 0x18, 0x9F, 0x76, 0xEC, 0x57, 0xCE, 0xE5, 0xB3, 0xAB, 0x79, 0x90, + 0xAD, 0xAC, 0x6E, 0xD1, 0x58, 0x35, 0x03, 0x97, 0x16, 0x10, 0x82, 0x56, + 0xD8, 0x55, 0xFF, 0xE1, 0x8A, 0xA3, 0x2E, 0xF6, /* Random */ + 0x00, /* Session id len */ + 0x14, /* Cookie len */ + 0x00, 0x01, 0x02, 0x03, 0x04, 005, 0x06, 007, 0x08, 0x09, 0x0A, 0x0B, 0x0C, + 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12 /* Cookie (truncated) */ +}; + static const unsigned char verify[] = { 0x16, /* Handshake */ 0xFE, 0xFF, /* DTLSv1.0 */ @@ -246,7 +462,7 @@ typedef struct { DROP } outtype; } tests; -static tests testpackets[9] = { +static tests testpackets[] = { { clienthello_nocookie, sizeof(clienthello_nocookie), VERIFY }, { clienthello_nocookie_frag, sizeof(clienthello_nocookie_frag), VERIFY }, { clienthello_nocookie_short, sizeof(clienthello_nocookie_short), DROP }, @@ -258,6 +474,18 @@ static tests testpackets[9] = { { record_short, sizeof(record_short), DROP } }; +static tests testpackets13[] = { + { clienthello13_nocookie, sizeof(clienthello13_nocookie), VERIFY }, + { clienthello13_nocookie_frag, sizeof(clienthello13_nocookie_frag), VERIFY }, + { clienthello_nocookie_short, sizeof(clienthello_nocookie_short), DROP }, + { clienthello13_2ndfrag, sizeof(clienthello13_2ndfrag), DROP }, + { clienthello13_cookie, sizeof(clienthello13_cookie), GOOD }, + { clienthello_cookie_frag, sizeof(clienthello_cookie_frag), GOOD }, + { clienthello13_badcookie, sizeof(clienthello13_badcookie), VERIFY }, + { clienthello13_cookie_short, sizeof(clienthello13_cookie_short), DROP }, + { record_short, sizeof(record_short), DROP } +}; + #define COOKIE_LEN 20 static int cookie_gen(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len) @@ -287,6 +515,38 @@ static int cookie_verify(SSL *ssl, const unsigned char *cookie, return 1; } +/* + * Combined DTLS listen test covering both DTLS 1.2 and DTLS 1.3 packet + * variants. + * + * Note: DTLSv1_listen() only supports the legacy HelloVerifyRequest mechanism + * which is not used in DTLS 1.3. When processing DTLS 1.3 ClientHello packets + * (tests 9-17), the server is NOT constrained to DTLS 1.3 only - instead it + * uses the full version range and DTLSv1_listen() clamps to DTLS 1.2. These + * tests verify that DTLSv1_listen() correctly handles ClientHello packets + * that advertise DTLS 1.3 via supported_versions extension. + * + * 0: Test that DTLS 1.2 without a cookie is accepted by DTLSv1_listen(). + * 1: Test that a fragmented DTLS 1.2 ClientHello without a cookie is + * accepted by DTLSv1_listen(). + * 2: Test that a truncated DTLS 1.2 ClientHello without a cookie is + * dropped by DTLSv1_listen(). + * 3: Test that a second fragment of a DTLS 1.2 ClientHello without a + * cookie is dropped by DTLSv1_listen() (it cannot reconstruct a full + * ClientHello from it). + * 4: Test that a DTLS 1.2 ClientHello with a good cookie is accepted by + * DTLSv1_listen(). + * 5: Test that a fragmented DTLS 1.2 ClientHello with a good cookie is + * accepted by DTLSv1_listen(). + * 6: Test that a DTLS 1.2 ClientHello with a bad cookie is rejected by + * DTLSv1_listen() with a HelloVerifyRequest. + * 7: Test that a DTLS 1.2 ClientHello with a truncated cookie is dropped + * by DTLSv1_listen(). + * 8: Test that a short record is dropped by DTLSv1_listen(). + * 9-17: Same as 0-8 but with DTLS 1.3 format ClientHello packets (containing + * supported_versions extension). The server is clamped to DTLS 1.2 by + * DTLSv1_listen(), so these test packet parsing, not DTLS 1.3 negotiation. + */ static int dtls_listen_test(int i) { SSL_CTX *ctx = NULL; @@ -294,14 +554,26 @@ static int dtls_listen_test(int i) BIO *outbio = NULL; BIO *inbio = NULL; BIO_ADDR *peer = NULL; - tests *tp = &testpackets[i]; + tests *tp; + int is_dtls13 = (i >= (int)OSSL_NELEM(testpackets)); char *data; long datalen; int ret, success = 0; + if (is_dtls13) { + tp = &testpackets13[i - (int)OSSL_NELEM(testpackets)]; +#ifdef OPENSSL_NO_DTLS1_3 + success = TEST_skip("DTLSv1.3 not usable"); + goto err; +#endif + } else { + tp = &testpackets[i]; + } + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method())) || !TEST_ptr(peer = BIO_ADDR_new())) goto err; + SSL_CTX_set_cookie_generate_cb(ctx, cookie_gen); SSL_CTX_set_cookie_verify_cb(ctx, cookie_verify); @@ -347,12 +619,335 @@ static int dtls_listen_test(int i) OPENSSL_free(peer); return success; } + +#ifndef OPENSSL_NO_DTLS1_2 +static unsigned char *create_cookie_clienthello(int *outlen, + unsigned char *out_seq) +{ + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + SSL_CONNECTION *sc = NULL; + BIO *rbio = NULL, *wbio = NULL; + BIO *ssl_rbio = NULL, *ssl_wbio = NULL; + char *data = NULL; + long datalen; + unsigned char *ret = NULL; + int sslret; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_client_method())) + || !TEST_ptr(ssl = SSL_new(ctx)) + || !TEST_ptr(rbio = BIO_new(BIO_s_mem())) + || !TEST_ptr(wbio = BIO_new(BIO_s_mem()))) + goto err; + + ssl_rbio = rbio; + ssl_wbio = wbio; + SSL_set0_rbio(ssl, rbio); + SSL_set0_wbio(ssl, wbio); + rbio = wbio = NULL; + SSL_set_connect_state(ssl); + + if (!TEST_ptr(sc = SSL_CONNECTION_FROM_SSL_ONLY(ssl))) + goto err; + + /* Send the initial, cookie-less ClientHello: record sequence 0. */ + if (!TEST_int_le(sslret = SSL_connect(ssl), 0) + || !TEST_int_eq(SSL_get_error(ssl, sslret), SSL_ERROR_WANT_READ)) + goto err; + + /* + * Simulate the initial ClientHello (or the server's HelloVerifyRequest) + * being lost in transit: force the retransmit timer to look expired and + * drive a genuine retransmission of the buffered ClientHello through + * the normal write path. This consumes record sequence 1 for real, + * so the retried (with-cookie) ClientHello below naturally lands on + * sequence 2 -- rather than the test asserting that value by fiat. + */ + sc->d1->next_timeout = ossl_ms2time(1); + if (!TEST_long_eq(DTLSv1_handle_timeout(ssl), 1)) + goto err; + + /* Neither copy of the cookie-less ClientHello is needed -- discard both. */ + if (!TEST_int_gt(BIO_reset(ssl_wbio), 0) + || !TEST_int_eq(BIO_write(ssl_rbio, verify, sizeof(verify)), + sizeof(verify)) + || !TEST_int_le(sslret = SSL_connect(ssl), 0) + || !TEST_int_eq(SSL_get_error(ssl, sslret), SSL_ERROR_WANT_READ) + || !TEST_long_ge(datalen = BIO_get_mem_data(ssl_wbio, &data), + DTLS1_RT_HEADER_LENGTH) + || !TEST_long_le(datalen, INT_MAX)) + goto err; + + if (!TEST_ptr(ret = OPENSSL_memdup(data, datalen))) + goto err; + + *outlen = (int)datalen; + + /* + * Report back the epoch+sequence number (DTLS record header bytes + * 3..10) that the client's own record layer actually assigned to the + * first record of the retried ClientHello. The caller uses this to + * work out what it should expect back from the server, instead of the + * test dictating a fixed sequence number. + */ + memcpy(out_seq, ret + 3, DTLS_RECORD_EPOCH_AND_SEQ_LEN); + +err: + SSL_free(ssl); + SSL_CTX_free(ctx); + BIO_free(rbio); + BIO_free(wbio); + return ret; +} + +static int dtls_listen_write_seq_test(int tst) +{ + unsigned char actual_seq[DTLS_RECORD_EPOCH_AND_SEQ_LEN]; + unsigned char *inbuf = NULL; + int inbuflen = 0; + SSL_CONNECTION *s = NULL; + SSL_CTX *ctx = NULL; + SSL *ssl = NULL; + BIO *outbio = NULL; + BIO *inbio = NULL; + BIO_ADDR *peer = NULL; + char *data; + long datalen; + int ret, success = 0; + + if (!TEST_ptr(inbuf = create_cookie_clienthello(&inbuflen, actual_seq))) + goto err; + + if (!TEST_ptr(ctx = SSL_CTX_new(DTLS_server_method())) + || !TEST_ptr(peer = BIO_ADDR_new())) + goto err; + SSL_CTX_set_cookie_generate_cb(ctx, cookie_gen); + SSL_CTX_set_cookie_verify_cb(ctx, cookie_verify); + if (!TEST_true(SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM)) + || !TEST_true(SSL_CTX_use_PrivateKey_file(ctx, privkey, + SSL_FILETYPE_PEM))) + goto err; + + if (!TEST_ptr(ssl = SSL_new(ctx)) + || !TEST_ptr(outbio = BIO_new(BIO_s_mem()))) + goto err; + + SSL_set0_wbio(ssl, outbio); + if (!TEST_ptr(inbio = BIO_new_mem_buf(inbuf, inbuflen))) + goto err; + + BIO_set_mem_eof_return(inbio, -1); + SSL_set0_rbio(ssl, inbio); + inbio = NULL; + + if (!TEST_int_eq(ret = DTLSv1_listen(ssl, peer), 1)) + goto err; + + datalen = BIO_get_mem_data(outbio, &data); + if (!TEST_long_eq(datalen, 0)) + goto err; + + if (tst == 1) { + /* Drive the DTLS 1.2 write-side uint48 wrap path directly. */ + s = SSL_CONNECTION_FROM_SSL_ONLY(ssl); + if (!TEST_ptr(s) + || !TEST_true(s->rlayer.wrlmethod->set_sequence != NULL) + || !TEST_true(s->rlayer.wrlmethod->set_sequence(s->rlayer.wrl, + 0xffffffffffffULL))) + goto err; + } + + ret = SSL_accept(ssl); + if (tst == 1) { + if (!TEST_int_le(ret, 0) + || !TEST_int_eq(SSL_get_error(ssl, ret), SSL_ERROR_SSL) + || !TEST_int_eq(ERR_GET_REASON(ERR_peek_last_error()), + SSL_R_SEQUENCE_CTR_WRAPPED)) + goto err; + success = 1; + goto err; + } + + if (!TEST_int_le(ret, 0) + || !TEST_int_eq(SSL_get_error(ssl, ret), SSL_ERROR_WANT_READ)) + goto err; + + datalen = BIO_get_mem_data(outbio, &data); + if (!TEST_long_ge(datalen, DTLS1_RT_HEADER_LENGTH) + /* The server's response record is always DTLS1.2 once a cookie has + * been validated -- that's what DTLSv1_listen() negotiates down to. */ + || !TEST_uint_eq(((unsigned char)data[1] << 8) | (unsigned char)data[2], + DTLS1_2_VERSION) + /* + * This is the actual regression check: the server's write sequence + * must continue from the epoch/sequence number of the ClientHello + * record DTLSv1_listen() validated the cookie against -- whatever + * that value turned out to be, not one the test dictates. + */ + || !TEST_mem_eq(data + 3, DTLS_RECORD_EPOCH_AND_SEQ_LEN, + actual_seq, DTLS_RECORD_EPOCH_AND_SEQ_LEN)) + goto err; + + SSL_set0_rbio(ssl, NULL); + success = 1; + +err: + SSL_free(ssl); + SSL_CTX_free(ctx); + BIO_free(inbio); + OPENSSL_free(inbuf); + OPENSSL_free(peer); + return success; +} #endif +#ifndef OPENSSL_NO_DTLS1_3 +/* + * Test that DTLSv1_listen() clamps the max version to DTLS 1.2. + * + * DTLSv1_listen() only supports the legacy HelloVerifyRequest mechanism + * which is not used in DTLS 1.3. When called, it automatically clamps the + * max protocol version to DTLS 1.2 to ensure HelloVerifyRequest is used. + * + * This test verifies that when both client and server support DTLS 1.0-1.3, + * using DTLSv1_listen() results in a DTLS 1.2 connection (not 1.3). + * + * For DTLS 1.3 with HelloRetryRequest cookies, use SSL_new_listener() instead. + */ +static int test_dtls_listen_dtls13_negotiated_to_dtls12(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + const char msg[] = "Hello DTLS 1.2 via DTLSv1_listen"; + char buf[sizeof(msg)]; + size_t written, readbytes; + int testresult = 0; + + /* + * Both server and client support DTLS 1.0 through DTLS 1.3. + * DTLSv1_listen() should clamp the server's max to DTLS 1.2, + * resulting in a DTLS 1.2 negotiated connection. + */ + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + DTLS1_VERSION, DTLS1_3_VERSION, + &sctx, &cctx, cert, privkey))) + goto end; + + SSL_CTX_set_cookie_generate_cb(sctx, cookie_gen); + SSL_CTX_set_cookie_verify_cb(sctx, cookie_verify); + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL))) + goto end; + + /* + * Use DTLSv1_listen() which will clamp max version to DTLS 1.2. + */ + if (!TEST_true(create_bare_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE, 1, 1))) + goto end; + + /* + * Verify DTLS 1.2 was negotiated (not 1.3) because DTLSv1_listen() + * clamped the max version. + */ + if (!TEST_int_eq(SSL_version(serverssl), DTLS1_2_VERSION) + || !TEST_int_eq(SSL_version(clientssl), DTLS1_2_VERSION)) + goto end; + + /* Exchange a short application-data message to verify connection works */ + if (!TEST_true(SSL_write_ex(clientssl, msg, sizeof(msg), &written)) + || !TEST_size_t_eq(written, sizeof(msg))) + goto end; + + if (!TEST_true(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(msg)) + || !TEST_mem_eq(buf, readbytes, msg, sizeof(msg))) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * Use SSL_stateless with DTLS if you want to send a + * HelloRetryRequest and then continue with the handshake. + * DTLSv1_listen only support HelloVerifyRequest, so a pure DTLS 1.3 + * client is not supported with DTLSv1_listen. + */ +static int test_dtls13_listen_client_dtls13_only(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + int testresult = 0; + + /* Both server and client are restricted to DTLS 1.3 exclusively. */ + if (!TEST_true(create_ssl_ctx_pair(NULL, DTLS_server_method(), + DTLS_client_method(), + DTLS1_3_VERSION, DTLS1_3_VERSION, + &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(SSL_CTX_set_min_proto_version(cctx, DTLS1_3_VERSION)) + || !TEST_true(SSL_CTX_set_max_proto_version(cctx, DTLS1_3_VERSION))) + goto end; + + SSL_CTX_set_cookie_generate_cb(sctx, cookie_gen); + SSL_CTX_set_cookie_verify_cb(sctx, cookie_verify); + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL))) + goto end; + + /* + * Pass listen=1 so that create_bare_ssl_connection() calls + * Verify DTLSv1_listen does not work with a pure DTLS 1.3 client + */ + if (!TEST_false(create_bare_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE, 1, 1))) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +#endif /* OPENSSL_NO_DTLS1_3 */ +#endif /* OPENSSL_NO_SOCK */ + +OPT_TEST_DECLARE_USAGE("certfile privkeyfile\n") + int setup_tests(void) { + if (!test_skip_common_options()) { + TEST_error("Error parsing test options\n"); + return 0; + } + + if (!TEST_ptr(cert = test_get_argument(0)) + || !TEST_ptr(privkey = test_get_argument(1))) + return 0; + #ifndef OPENSSL_NO_SOCK - ADD_ALL_TESTS(dtls_listen_test, (int)OSSL_NELEM(testpackets)); + ADD_ALL_TESTS(dtls_listen_test, + (int)OSSL_NELEM(testpackets) + (int)OSSL_NELEM(testpackets13)); +#ifndef OPENSSL_NO_DTLS1_2 + ADD_ALL_TESTS(dtls_listen_write_seq_test, 2); +#endif +#ifndef OPENSSL_NO_DTLS1_3 + ADD_TEST(test_dtls_listen_dtls13_negotiated_to_dtls12); + ADD_TEST(test_dtls13_listen_client_dtls13_only); +#endif #endif return 1; } diff --git a/test/ech_corrupt_test.c b/test/ech_corrupt_test.c index 7070f4ef371f2..79d59844fdf4e 100644 --- a/test/ech_corrupt_test.c +++ b/test/ech_corrupt_test.c @@ -710,10 +710,10 @@ typedef struct { #define OSSL_ECH_BORK_GREASE (1 << 4) #define OSSL_ECH_BORK_REPLACE (1 << 5) -/* a truncated ECH, with another bogus ext to match overall length */ +/* a truncated ECH, padded with a known HRR ext to match overall length */ static unsigned char shortech[] = { 0xfe, 0x0d, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0xdd, 0xdd, 0x00, 0x00 + 0x00, 0x2c, 0x00, 0x00 }; /* a too-long ECH internal length */ diff --git a/test/ech_test.c b/test/ech_test.c index b383b4255a039..d2331c8b40798 100644 --- a/test/ech_test.c +++ b/test/ech_test.c @@ -1060,7 +1060,7 @@ static int ech_test_file_read(int run) fullname = OPENSSL_malloc(fnlen); if (fullname == NULL) goto end; - BIO_snprintf(fullname, fnlen, "%s/%s", certsdir, ft->fname); + snprintf(fullname, fnlen, "%s/%s", certsdir, ft->fname); if (verbose) TEST_info("testing read of %s", fullname); in = BIO_new_file(fullname, "r"); @@ -1320,7 +1320,7 @@ static int test_ech_roundtrip_helper(int idx, int combo) aeadind = idx % aeadsz; /* initialise early data stuff, just in case */ memset(ed, 'A', sizeof(ed)); - BIO_snprintf(suitestr, 100, "%s,%s,%s", kem_str_list[kemind], + snprintf(suitestr, 100, "%s,%s,%s", kem_str_list[kemind], kdf_str_list[kdfind], aead_str_list[aeadind]); if (verbose) TEST_info("Doing: iter: %d, suite: %s", idx, suitestr); @@ -2025,6 +2025,322 @@ static int ech_grease_test(int idx) return res; } +#define TEST_KEYLOG_SIZE 4096 +static char c_keylog[TEST_KEYLOG_SIZE]; +static char s_keylog[TEST_KEYLOG_SIZE]; +static int keylog_overflow = 0; + +static void keylog_add(char *buf, const char *line) +{ + if (strlen(buf) + strlen(line) + 2 > TEST_KEYLOG_SIZE) { + keylog_overflow = 1; + return; + } + OPENSSL_strlcat(buf, line, TEST_KEYLOG_SIZE); + OPENSSL_strlcat(buf, "\n", TEST_KEYLOG_SIZE); +} + +static void c_keylog_cb(const SSL *ssl, const char *line) +{ + keylog_add(c_keylog, line); +} + +static void s_keylog_cb(const SSL *ssl, const char *line) +{ + keylog_add(s_keylog, line); +} + +static const char *keylog_line(const char *log, const char *label) +{ + const char *p = log; + size_t label_len = strlen(label); + + while (p != NULL && *p != '\0') { + if (strncmp(p, label, label_len) == 0 && p[label_len] == ' ') + return p; + p = strchr(p, '\n'); + if (p != NULL) + p++; + } + return NULL; +} + +/* compare two keylog lines (each terminated by newline or NUL) */ +static int keylog_line_eq(const char *a, const char *b) +{ + size_t la = strcspn(a, "\n"), lb = strcspn(b, "\n"); + + return la == lb && memcmp(a, b, la) == 0; +} + +/* compare the client random fields of two keylog lines */ +static int keylog_line_rnd_same(const char *a, const char *b) +{ + a = strchr(a, ' '); + b = strchr(b, ' '); + if (a == NULL || b == NULL) + return 0; + return strncmp(a + 1, b + 1, 2 * SSL3_RANDOM_SIZE) == 0; +} + +/* check the client random field of a keylog line is the hex of rnd */ +static int keylog_line_rnd_eq(const char *line, const unsigned char *rnd) +{ + const char *hexdig = "0123456789abcdef"; + const char *p = strchr(line, ' '); + size_t i; + + if (p == NULL) + return 0; + p++; + for (i = 0; i < SSL3_RANDOM_SIZE; i++) { + if (p[2 * i] != hexdig[rnd[i] >> 4] + || p[2 * i + 1] != hexdig[rnd[i] & 0x0f]) + return 0; + } + return p[2 * SSL3_RANDOM_SIZE] == ' '; +} + +/* + * When ECH is negotiated, keylog callback output is tagged with the inner + * ClientHello random, so that client and server log identical lines for the + * same secret. The 1st iteration is a plain handshake, the 2nd adds a HRR and + * the 3rd resumes with early data, whose secrets are logged before the client + * knows if the server accepted the ECH. The 4th also resumes with early data, + * but the server rejects the ECH: the early secrets were derived from the + * inner CH so keep the inner random, while the handshake secrets belong to + * the outer handshake and must be tagged with the outer random. + */ +static int test_ech_keylog_random(int idx) +{ + int res = 0, clientstatus, serverstatus; + OSSL_ECHSTORE *es = NULL, *es2 = NULL; + OSSL_HPKE_SUITE hpke_suite = OSSL_HPKE_SUITE_DEFAULT; + SSL_CTX *c = NULL, *s = NULL; + SSL *cssl = NULL, *sssl = NULL; + SSL_SESSION *sess = NULL; + char *cinner = NULL, *couter = NULL, *sinner = NULL, *souter = NULL; + unsigned char inner_rnd[SSL3_RANDOM_SIZE], outer_rnd[SSL3_RANDOM_SIZE]; + unsigned char srv_rnd[SSL3_RANDOM_SIZE]; + unsigned char ed[21], buf[1024]; + size_t written = 0, readbytes = 0, l, lstart; + static const size_t both_sides[] = { 3, 5, 6 }; + static const char *labels[] = { + /* the early data labels only apply for the 3rd iteration */ + "CLIENT_EARLY_TRAFFIC_SECRET", + "EARLY_EXPORTER_SECRET", + "CLIENT_HANDSHAKE_TRAFFIC_SECRET", + "SERVER_HANDSHAKE_TRAFFIC_SECRET", + "CLIENT_TRAFFIC_SECRET_0", + "SERVER_TRAFFIC_SECRET_0", + "EXPORTER_SECRET" + }; + + c_keylog[0] = s_keylog[0] = '\0'; + keylog_overflow = 0; + memset(ed, 'A', sizeof(ed)); + if (!TEST_ptr(es = OSSL_ECHSTORE_new(libctx, propq)) + || !TEST_true(OSSL_ECHSTORE_new_config(es, OSSL_ECH_CURRENT_VERSION, + 0, "example.com", hpke_suite)) + || !TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, + &s, &c, cert, privkey))) + goto end; + if (idx >= 2 + && (!TEST_true(SSL_CTX_set_options(s, SSL_OP_NO_ANTI_REPLAY)) + || !TEST_true(SSL_CTX_set_max_early_data(s, + SSL3_RT_MAX_PLAIN_LENGTH)) + || !TEST_true(SSL_CTX_set_recv_max_early_data(s, + SSL3_RT_MAX_PLAIN_LENGTH)))) + goto end; + SSL_CTX_set_keylog_callback(c, c_keylog_cb); + SSL_CTX_set_keylog_callback(s, s_keylog_cb); + if (!TEST_true(SSL_CTX_set1_echstore(s, es)) + || !TEST_true(SSL_CTX_set1_echstore(c, es)) + || !TEST_true(create_ssl_objects(s, c, &sssl, + &cssl, NULL, NULL)) + || !TEST_true(SSL_set_tlsext_host_name(cssl, "server.example"))) + goto end; + /* force a HRR for the 2nd iteration */ + if (idx == 1 && !TEST_true(SSL_set1_groups_list(sssl, "P-384"))) + goto end; + if (!TEST_true(create_ssl_connection(sssl, cssl, + SSL_ERROR_NONE))) + goto end; + if (idx >= 2) { + /* resume with early data, checking only the 2nd connection */ + sess = SSL_get1_session(cssl); + SSL_shutdown(cssl); + SSL_shutdown(sssl); + SSL_free(sssl); + SSL_free(cssl); + sssl = cssl = NULL; + c_keylog[0] = s_keylog[0] = '\0'; + if (!TEST_ptr(sess) + || !TEST_true(create_ssl_objects(s, c, &sssl, + &cssl, NULL, NULL)) + || !TEST_true(SSL_set_tlsext_host_name(cssl, "server.example")) + || !TEST_true(SSL_set_session(cssl, sess))) + goto end; + /* + * for the 4th iteration give the client an ECHConfig whose key + * the server does not have, so that the server rejects the ECH + */ + if (idx == 3 + && (!TEST_ptr(es2 = OSSL_ECHSTORE_new(libctx, propq)) + || !TEST_true(OSSL_ECHSTORE_new_config(es2, + OSSL_ECH_CURRENT_VERSION, 0, "example.com", + hpke_suite)) + || !TEST_true(SSL_set1_echstore(cssl, es2)))) + goto end; + if (!TEST_true(SSL_write_early_data(cssl, ed, sizeof(ed), + &written)) + || !TEST_size_t_eq(written, sizeof(ed))) + goto end; + if (idx == 3) { + /* the server can neither decrypt the ECH nor resume */ + if (!TEST_int_eq(SSL_read_early_data(sssl, buf, sizeof(buf), + &readbytes), + SSL_READ_EARLY_DATA_FINISH) + || !TEST_int_eq(SSL_get_early_data_status(sssl), + SSL_EARLY_DATA_REJECTED) + /* the client aborts on finding its ECH was rejected */ + || !TEST_false(create_ssl_connection(sssl, cssl, + SSL_R_ECH_REQUIRED))) + goto end; + } else { + if (!TEST_int_eq(SSL_read_early_data(sssl, buf, sizeof(buf), + &readbytes), + SSL_READ_EARLY_DATA_SUCCESS) + || !TEST_size_t_eq(written, readbytes) + || !TEST_true(SSL_write_early_data(sssl, ed, sizeof(ed), + &written)) + || !TEST_true(SSL_read_ex(cssl, buf, sizeof(buf), + &readbytes))) + goto end; + /* drive the server through the client Finished */ + if (!TEST_true(SSL_write_ex(cssl, ed, sizeof(ed), &written)) + || !TEST_true(SSL_read_ex(sssl, buf, sizeof(buf), + &readbytes))) + goto end; + } + } + /* override cert verification */ + SSL_set_verify_result(cssl, X509_V_OK); + clientstatus = SSL_ech_get1_status(cssl, &cinner, &couter); + serverstatus = SSL_ech_get1_status(sssl, &sinner, &souter); + if (idx == 3) { + /* the server can't distinguish an ECH it can't decrypt from GREASE */ + if (!TEST_int_eq(clientstatus, SSL_ECH_STATUS_FAILED) + || !TEST_int_eq(serverstatus, SSL_ECH_STATUS_GREASE) + || !TEST_false(keylog_overflow)) + goto end; + /* + * the server never decrypted the inner CH, so both sides see + * the outer CH random as the client random + */ + if (!TEST_size_t_eq(SSL_get_client_random(cssl, outer_rnd, + sizeof(outer_rnd)), + sizeof(outer_rnd)) + || !TEST_size_t_eq(SSL_get_client_random(sssl, srv_rnd, + sizeof(srv_rnd)), + sizeof(srv_rnd)) + || !TEST_int_eq(memcmp(outer_rnd, srv_rnd, SSL3_RANDOM_SIZE), 0)) + goto end; + /* + * the client's early secrets were derived from the inner CH and + * keep its random, which the server (who logs no early lines) + * never learned + */ + for (l = 0; l < 2; l++) { + const char *cline; + + if (!TEST_ptr(cline = keylog_line(c_keylog, labels[l])) + || !TEST_ptr_null(keylog_line(s_keylog, labels[l])) + || !TEST_false(keylog_line_rnd_eq(cline, outer_rnd))) { + TEST_info("keylog mismatch for label %s", labels[l]); + goto end; + } + } + /* both early secrets must be tagged with the same (inner) random */ + if (!TEST_true(keylog_line_rnd_same(keylog_line(c_keylog, labels[0]), + keylog_line(c_keylog, labels[1])))) + goto end; + + /* + * the later secrets belong to the outer handshake and must be + * tagged with the outer random - the client aborts before ever + * using (and so logging) its own handshake or traffic keys, so + * only the server-side secrets and the exporter appear in both + * logs + */ + for (l = 0; l < OSSL_NELEM(both_sides); l++) { + const char *cline, *sline; + const char *label = labels[both_sides[l]]; + + if (!TEST_ptr(cline = keylog_line(c_keylog, label)) + || !TEST_ptr(sline = keylog_line(s_keylog, label)) + || !TEST_true(keylog_line_eq(cline, sline)) + || !TEST_true(keylog_line_rnd_eq(cline, outer_rnd))) { + TEST_info("keylog mismatch for label %s", label); + goto end; + } + } + res = 1; + goto end; + } + if (!TEST_int_eq(clientstatus, SSL_ECH_STATUS_SUCCESS) + || !TEST_int_eq(serverstatus, SSL_ECH_STATUS_SUCCESS) + || !TEST_false(keylog_overflow)) + goto end; + /* + * With ECH the client's s3.client_random is the outer CH random + * while the server, having decrypted the ECH, has the inner - so + * the server's value tells us the random the logs must be using + */ + if (!TEST_size_t_eq(SSL_get_client_random(cssl, outer_rnd, + sizeof(outer_rnd)), + sizeof(outer_rnd)) + || !TEST_size_t_eq(SSL_get_client_random(sssl, inner_rnd, + sizeof(inner_rnd)), + sizeof(inner_rnd)) + || !TEST_int_ne(memcmp(outer_rnd, inner_rnd, SSL3_RANDOM_SIZE), 0)) + goto end; + /* + * client and server must log identical lines, tagged with the + * inner CH random - before the fix in ssl_log_secret the client + * tagged these with the outer CH random while the server used + * the inner + */ + lstart = (idx == 2 ? 0 : 2); + for (l = lstart; l < OSSL_NELEM(labels); l++) { + const char *cline, *sline; + + if (!TEST_ptr(cline = keylog_line(c_keylog, labels[l])) + || !TEST_ptr(sline = keylog_line(s_keylog, labels[l])) + || !TEST_true(keylog_line_eq(cline, sline)) + || !TEST_true(keylog_line_rnd_eq(cline, inner_rnd))) { + TEST_info("keylog mismatch for label %s", labels[l]); + goto end; + } + } + res = 1; +end: + OSSL_ECHSTORE_free(es); + OSSL_ECHSTORE_free(es2); + OPENSSL_free(sinner); + OPENSSL_free(souter); + OPENSSL_free(cinner); + OPENSSL_free(couter); + SSL_SESSION_free(sess); + SSL_free(cssl); + SSL_free(sssl); + SSL_CTX_free(c); + SSL_CTX_free(s); + return res; +} + #endif int setup_tests(void) @@ -2074,6 +2390,7 @@ int setup_tests(void) ADD_ALL_TESTS(ech_in_out_test, 14); ADD_ALL_TESTS(ech_grease_test, 4); ADD_ALL_TESTS(test_ech_no_inner, suite_combos); + ADD_ALL_TESTS(test_ech_keylog_random, 4); return 1; err: return 0; diff --git a/test/ecparam_test.c b/test/ecparam_test.c new file mode 100644 index 0000000000000..5accee6177940 --- /dev/null +++ b/test/ecparam_test.c @@ -0,0 +1,323 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "testutil.h" + +/*- + * Sweep a corpus of EC parameter files, exercising what the ecparam and + * pkeyparam applications do to each one. The applications are covered + * separately in 20-test_app_ecparam.t; running the whole corpus through + * them costs a process per file per check, which is startup time rather + * than test coverage. + * + * Invoked as: + * + * ecparam_test valid|noncanon|invalid + * + * where the list file holds one file name per line. The list is passed + * this way because the corpus has more files in it than a test can be + * given arguments. + * + * Valid and non-canonically encoded parameters must load and check. + * Invalid ones must not. Only the canonically encoded valid files are + * expected to re-encode to exactly the bytes they were read from. + */ +typedef enum { + CORPUS_VALID, + CORPUS_NONCANON, + CORPUS_INVALID +} corpus_kind; + +static corpus_kind corpus; +static int expect_check; /* Whether loading and checking should succeed */ +static char **files; +static int num_files; + +static const char *corpus_file(int idx) +{ + return files[idx]; +} + +/* Read the corpus file names, one per line. */ +static int read_file_list(const char *path) +{ + BIO *bio = BIO_new_file(path, "r"); + char line[512]; + int n = 0, allocated = 0; + + if (bio == NULL) + return 0; + + while (BIO_gets(bio, line, sizeof(line)) > 0) { + size_t len = strlen(line); + + while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r')) + line[--len] = '\0'; + if (len == 0) + continue; + + if (n == allocated) { + char **tmp; + + allocated = allocated == 0 ? 64 : allocated * 2; + tmp = OPENSSL_realloc(files, allocated * sizeof(*files)); + if (tmp == NULL) + goto err; + files = tmp; + } + + if ((files[n] = OPENSSL_strdup(line)) == NULL) + goto err; + n++; + } + + BIO_free(bio); + num_files = n; + return n > 0; + +err: + num_files = n; + BIO_free(bio); + return 0; +} + +/* + * Load domain parameters the way the applications do. ecparam insists the + * result be an EC or SM2 key, pkeyparam takes whatever it is given. + */ +static EVP_PKEY *load_params(const char *file, int ec_only) +{ + EVP_PKEY *pkey = NULL; + OSSL_DECODER_CTX *dctx = NULL; + BIO *bio = BIO_new_file(file, "rb"); + + if (bio == NULL) + return NULL; + + dctx = OSSL_DECODER_CTX_new_for_pkey(&pkey, "PEM", NULL, NULL, + OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, NULL, NULL); + if (dctx == NULL) { + BIO_free(bio); + return NULL; + } + + if (!OSSL_DECODER_from_bio(dctx, bio)) { + EVP_PKEY_free(pkey); + pkey = NULL; + } + + OSSL_DECODER_CTX_free(dctx); + BIO_free(bio); + + if (pkey != NULL && ec_only + && !EVP_PKEY_is_a(pkey, "EC") && !EVP_PKEY_is_a(pkey, "SM2")) { + EVP_PKEY_free(pkey); + pkey = NULL; + } + + return pkey; +} + +/* Run EVP_PKEY_param_check() as the applications do after loading. */ +static int check_params(EVP_PKEY *pkey) +{ + EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); + int ret; + + if (ctx == NULL) + return 0; + + ret = EVP_PKEY_param_check(ctx) > 0; + EVP_PKEY_CTX_free(ctx); + return ret; +} + +/* + * Load and check, optionally restricting the check to named curves as + * "ecparam -check_named" does. Returns 1 if the outcome matched what the + * corpus expects. + */ +static int load_and_check(int idx, int ec_only, int named) +{ + const char *file = corpus_file(idx); + EVP_PKEY *pkey = load_params(file, ec_only); + int ok; + + if (pkey == NULL) + return TEST_int_eq(expect_check, 0); + + if (named + && !TEST_true(EVP_PKEY_set_utf8_string_param(pkey, + OSSL_PKEY_PARAM_EC_GROUP_CHECK_TYPE, + OSSL_PKEY_EC_GROUP_CHECK_NAMED))) { + EVP_PKEY_free(pkey); + return 0; + } + + ok = check_params(pkey); + EVP_PKEY_free(pkey); + + if (!TEST_int_eq(ok, expect_check)) { + TEST_info("%s", file); + return 0; + } + return 1; +} + +static int test_ecparam_check(int idx) +{ + return load_and_check(idx, 1, 0); +} + +static int test_ecparam_check_named(int idx) +{ + return load_and_check(idx, 1, 1); +} + +static int test_pkeyparam_check(int idx) +{ + return load_and_check(idx, 0, 0); +} + +/* Read a whole file, so the re-encoded form can be compared against it. */ +static int read_file(const char *file, unsigned char **out, long *out_len) +{ + BIO *bio = BIO_new_file(file, "rb"); + unsigned char *buf = NULL; + long len = 0, n, i, j; + + if (bio == NULL) + return 0; + + for (;;) { + unsigned char *tmp = OPENSSL_realloc(buf, (size_t)len + 4096); + + if (tmp == NULL) { + OPENSSL_free(buf); + BIO_free(bio); + return 0; + } + buf = tmp; + n = BIO_read(bio, buf + len, 4096); + if (n <= 0) + break; + len += n; + } + + BIO_free(bio); + + for (i = 0, j = 0; i < len; i++) + if (buf[i] != '\r') + buf[j++] = buf[i]; + + *out = buf; + *out_len = j; + return 1; +} + +/* + * Canonically encoded parameters must survive a decode and re-encode + * unchanged, which is what "ecparam -in x -out y" is checked to do. + */ +static int test_reencode(int idx) +{ + const char *file = corpus_file(idx); + EVP_PKEY *pkey = load_params(file, 1); + OSSL_ENCODER_CTX *ectx = NULL; + BIO *mem = NULL; + unsigned char *orig = NULL; + char *enc = NULL; + long orig_len = 0; + long enc_len; + int ret = 0; + + if (!TEST_ptr(pkey)) + goto err; + + if (!TEST_ptr(mem = BIO_new(BIO_s_mem()))) + goto err; + + ectx = OSSL_ENCODER_CTX_new_for_pkey(pkey, + OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, "PEM", NULL, NULL); + if (!TEST_ptr(ectx) || !TEST_true(OSSL_ENCODER_to_bio(ectx, mem))) + goto err; + + if (!TEST_true(read_file(file, &orig, &orig_len))) + goto err; + + enc_len = BIO_get_mem_data(mem, &enc); + if (!TEST_mem_eq(enc, (size_t)enc_len, orig, (size_t)orig_len)) { + TEST_info("%s", file); + goto err; + } + + ret = 1; +err: + OPENSSL_free(orig); + OSSL_ENCODER_CTX_free(ectx); + BIO_free(mem); + EVP_PKEY_free(pkey); + return ret; +} + +int setup_tests(void) +{ + const char *kind; + + if (!TEST_size_t_eq(test_get_argument_count(), 2)) { + TEST_error("usage: ecparam_test valid|noncanon|invalid "); + return 0; + } + + kind = test_get_argument(0); + if (strcmp(kind, "valid") == 0) { + corpus = CORPUS_VALID; + } else if (strcmp(kind, "noncanon") == 0) { + corpus = CORPUS_NONCANON; + } else if (strcmp(kind, "invalid") == 0) { + corpus = CORPUS_INVALID; + } else { + TEST_error("unknown corpus \"%s\"", kind); + return 0; + } + + expect_check = corpus != CORPUS_INVALID; + + if (!TEST_true(read_file_list(test_get_argument(1)))) { + TEST_error("cannot read corpus list %s", test_get_argument(1)); + return 0; + } + + ADD_ALL_TESTS(test_ecparam_check, num_files); + ADD_ALL_TESTS(test_ecparam_check_named, num_files); + ADD_ALL_TESTS(test_pkeyparam_check, num_files); + /* Only the canonical encodings are expected to be byte stable. */ + if (corpus == CORPUS_VALID) + ADD_ALL_TESTS(test_reencode, num_files); + + return 1; +} + +void cleanup_tests(void) +{ + int i; + + for (i = 0; i < num_files; i++) + OPENSSL_free(files[i]); + OPENSSL_free(files); +} diff --git a/test/ectest.c b/test/ectest.c index 36fcb500893eb..beafd5009970b 100644 --- a/test/ectest.c +++ b/test/ectest.c @@ -1127,16 +1127,18 @@ static int group_field_test(void) EC_GROUP *secp521r1_group = NULL; EC_GROUP *sect163r2_group = NULL; - BN_hex2bn(&secp521r1_field, - "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFFF"); - - BN_hex2bn(§163r2_field, - "08000000000000000000000000000000" - "00000000C9"); + if (!TEST_true(BN_hex2bn(&secp521r1_field, + "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFF")) + || !TEST_true(BN_hex2bn(§163r2_field, + "08000000000000000000000000000000" + "00000000C9"))) { + BN_free(secp521r1_field); + return 0; + } secp521r1_group = EC_GROUP_new_by_curve_name(NID_secp521r1); if (BN_cmp(secp521r1_field, EC_GROUP_get0_field(secp521r1_group))) @@ -2111,6 +2113,39 @@ static int ossl_parameter_test(void) return r; } +static int ossl_explicit_parameter_options_test(void) +{ + EC_GROUP *source = NULL, *imported = NULL; + OSSL_PARAM *params = NULL; + OSSL_PARAM *point_format; + int ret = 0; + + if (!TEST_ptr(source = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1))) + goto err; + EC_GROUP_set_curve_name(source, NID_undef); + EC_GROUP_set_asn1_flag(source, OPENSSL_EC_EXPLICIT_CURVE); + + if (!TEST_ptr(params = EC_GROUP_to_params(source, NULL, NULL, NULL)) + || !TEST_ptr(imported = EC_GROUP_new_from_params(params, NULL, NULL)) + || !TEST_int_eq(EC_GROUP_get_asn1_flag(imported), + OPENSSL_EC_EXPLICIT_CURVE) + || !TEST_ptr(point_format = OSSL_PARAM_locate(params, + OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT)) + || !TEST_true(OSSL_PARAM_set_utf8_string(point_format, "invalid"))) + goto err; + + EC_GROUP_free(imported); + imported = NULL; + if (!TEST_ptr_null(imported = EC_GROUP_new_from_params(params, NULL, NULL))) + goto err; + ret = 1; +err: + EC_GROUP_free(source); + EC_GROUP_free(imported); + OSSL_PARAM_free(params); + return ret; +} + #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES /*- * random 256-bit explicit parameters curve, cofactor absent @@ -3150,6 +3185,7 @@ int setup_tests(void) ADD_TEST(parameter_test); ADD_TEST(ossl_parameter_test); + ADD_TEST(ossl_explicit_parameter_options_test); #ifndef OPENSSL_NO_EC_EXPLICIT_CURVES ADD_TEST(cofactor_range_test); #endif diff --git a/test/endecode_api_test.c b/test/endecode_api_test.c new file mode 100644 index 0000000000000..0ed9c32c663ef --- /dev/null +++ b/test/endecode_api_test.c @@ -0,0 +1,993 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Low-level OSSL_ENCODER / OSSL_DECODER API tests, using a test provider + * that implements a two-stage encoder chain ("TEST-KEY" -> "inter" -> "pem") + * and the corresponding decoder chain in the opposite direction. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "testutil.h" + +#define KEY_NAME "TEST-KEY" +#define INTER_NAME "inter" +#define PEM_NAME "pem" +#define STRUCTURE_NAME "test-structure" + +#define PEM_HEADER "-----BEGIN " KEY_NAME "-----\n" +#define PEM_FOOTER "\n-----END " KEY_NAME "-----\n" +#define INTER_PREFIX "test-key-v1:" + +#define TEST_SELECTION 0x07 +/* A seed value that makes the "TEST-KEY" encoder implementation fail */ +#define FAIL_SEED 666 + +static OSSL_LIB_CTX *testctx = NULL; +static OSSL_PROVIDER *testprov = NULL; + +struct test_key_st { + unsigned int seed; + char label[32]; +}; + +/* + * The test provider. + * + * It supplies two encoders: one encoding a test key into an intermediate + * "inter" format, and one wrapping "inter" data into a PEM-like format. + * OSSL_ENCODER_to_bio() is expected to chain them, giving the deeper + * encoder an intermediate memory BIO and passing its output to the outer + * encoder as an abstract object. The decoders mirror the encoders. + * + * The provider context is a child library context, so that the codec + * implementations can use BIO_new_from_core_bio(). + */ + +static void *codec_newctx(void *provctx) +{ + return provctx; +} + +static void codec_freectx(void *vctx) +{ +} + +static int key2inter_encode(void *vctx, OSSL_CORE_BIO *cout, + const void *obj_raw, const OSSL_PARAM obj_abstract[], + int selection, + OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) +{ + const struct test_key_st *key = obj_raw; + BIO *out; + int ok; + + /* The deepest encoder is given the object as passed by the constructor */ + if (key == NULL || obj_abstract != NULL || selection != TEST_SELECTION) + return 0; + if (key->seed == FAIL_SEED) + return 0; + if ((out = BIO_new_from_core_bio(vctx, cout)) == NULL) + return 0; + ok = BIO_printf(out, INTER_PREFIX "%u:%s", key->seed, key->label) > 0; + BIO_free(out); + return ok; +} + +static const OSSL_DISPATCH key2inter_encoder_functions[] = { + { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))codec_newctx }, + { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))codec_freectx }, + { OSSL_FUNC_ENCODER_ENCODE, (void (*)(void))key2inter_encode }, + OSSL_DISPATCH_END +}; + +static int inter2pem_encode(void *vctx, OSSL_CORE_BIO *cout, + const void *obj_raw, const OSSL_PARAM obj_abstract[], + int selection, + OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) +{ + const OSSL_PARAM *p; + BIO *out; + int ok; + + /* A chained encoder is given an abstract object, not a raw one */ + if (obj_abstract == NULL || obj_raw != NULL) + return 0; + + /* The data structure of the previous encoding round must be passed on */ + p = OSSL_PARAM_locate_const(obj_abstract, OSSL_OBJECT_PARAM_DATA_STRUCTURE); + if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING + || p->data_size != strlen(STRUCTURE_NAME) + || memcmp(p->data, STRUCTURE_NAME, p->data_size) != 0) + return 0; + + /* Likewise the data type, naming the encoder that produced the data */ + p = OSSL_PARAM_locate_const(obj_abstract, OSSL_OBJECT_PARAM_DATA_TYPE); + if (p == NULL || p->data_type != OSSL_PARAM_UTF8_STRING + || p->data == NULL || p->data_size != strlen(KEY_NAME) + || memcmp(p->data, KEY_NAME, p->data_size) != 0) + return 0; + + p = OSSL_PARAM_locate_const(obj_abstract, OSSL_OBJECT_PARAM_DATA); + if (p == NULL || p->data_type != OSSL_PARAM_OCTET_STRING) + return 0; + + if ((out = BIO_new_from_core_bio(vctx, cout)) == NULL) + return 0; + ok = BIO_printf(out, "%s", PEM_HEADER) > 0 + && BIO_write(out, p->data, (int)p->data_size) == (int)p->data_size + && BIO_printf(out, "%s", PEM_FOOTER) > 0; + BIO_free(out); + return ok; +} + +static const OSSL_DISPATCH inter2pem_encoder_functions[] = { + { OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))codec_newctx }, + { OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))codec_freectx }, + { OSSL_FUNC_ENCODER_ENCODE, (void (*)(void))inter2pem_encode }, + OSSL_DISPATCH_END +}; + +static const OSSL_ALGORITHM test_encoders[] = { + { KEY_NAME, "provider=apitest,output=" INTER_NAME ",structure=" STRUCTURE_NAME, + key2inter_encoder_functions }, + { INTER_NAME, "provider=apitest,output=" PEM_NAME, + inter2pem_encoder_functions }, + { NULL, NULL, NULL } +}; + +/* Read everything from a core BIO into |buf| as a NUL terminated string */ +static int read_core_bio(void *provctx, OSSL_CORE_BIO *cin, + char *buf, size_t bufsz, size_t *readlen) +{ + BIO *in; + size_t total = 0; + int l; + + if ((in = BIO_new_from_core_bio(provctx, cin)) == NULL) + return 0; + while (total < bufsz - 1 + && (l = BIO_read(in, buf + total, (int)(bufsz - 1 - total))) > 0) + total += l; + BIO_free(in); + buf[total] = '\0'; + *readlen = total; + return 1; +} + +static int pem2inter_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, + OSSL_CALLBACK *data_cb, void *data_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + char buf[1024]; + size_t len, payload_len; + OSSL_PARAM params[5]; + + if (!read_core_bio(vctx, cin, buf, sizeof(buf), &len)) + return 0; + + /* If it isn't wrapped in our PEM-like format, it's not for us */ + if (len < sizeof(PEM_HEADER) - 1 + sizeof(PEM_FOOTER) - 1 + || strncmp(buf, PEM_HEADER, sizeof(PEM_HEADER) - 1) != 0 + || strcmp(buf + len - (sizeof(PEM_FOOTER) - 1), PEM_FOOTER) != 0) + return 1; + + payload_len = len - (sizeof(PEM_HEADER) - 1) - (sizeof(PEM_FOOTER) - 1); + params[0] = OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA, + buf + sizeof(PEM_HEADER) - 1, + payload_len); + params[1] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, + (char *)KEY_NAME, 0); + params[2] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE, + (char *)STRUCTURE_NAME, 0); + params[3] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_INPUT_TYPE, + (char *)INTER_NAME, 0); + params[4] = OSSL_PARAM_construct_end(); + + return data_cb(params, data_cbarg); +} + +static const OSSL_DISPATCH pem2inter_decoder_functions[] = { + { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))codec_newctx }, + { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))codec_freectx }, + { OSSL_FUNC_DECODER_DECODE, (void (*)(void))pem2inter_decode }, + OSSL_DISPATCH_END +}; + +static int inter2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, + OSSL_CALLBACK *data_cb, void *data_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + char buf[1024]; + size_t len; + unsigned long seed; + const char *label; + char *end; + struct test_key_st *key; + OSSL_PARAM params[4]; + int ok; + + if (!read_core_bio(vctx, cin, buf, sizeof(buf), &len)) + return 0; + + /* Data that doesn't parse simply isn't ours; no fatal error */ + if (strncmp(buf, INTER_PREFIX, sizeof(INTER_PREFIX) - 1) != 0) + return 1; + seed = strtoul(buf + sizeof(INTER_PREFIX) - 1, &end, 10); + if (end == buf + sizeof(INTER_PREFIX) - 1 || *end != ':') + return 1; + label = end + 1; + + if ((key = OPENSSL_zalloc(sizeof(*key))) == NULL) + return 0; + key->seed = (unsigned int)seed; + OPENSSL_strlcpy(key->label, label, sizeof(key->label)); + + params[0] = OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_REFERENCE, + &key, sizeof(key)); + params[1] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, + (char *)KEY_NAME, 0); + params[2] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE, + (char *)STRUCTURE_NAME, 0); + params[3] = OSSL_PARAM_construct_end(); + + ok = data_cb(params, data_cbarg); + OPENSSL_free(key); + return ok; +} + +static int key_export_object(void *vctx, const void *objref, size_t objref_sz, + OSSL_CALLBACK *export_cb, void *export_cbarg) +{ + struct test_key_st *key; + OSSL_PARAM params[3]; + + if (objref_sz != sizeof(key)) + return 0; + memcpy(&key, objref, sizeof(key)); + + params[0] = OSSL_PARAM_construct_uint("seed", &key->seed); + params[1] = OSSL_PARAM_construct_utf8_string("label", key->label, 0); + params[2] = OSSL_PARAM_construct_end(); + + return export_cb(params, export_cbarg); +} + +static const OSSL_DISPATCH inter2key_decoder_functions[] = { + { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))codec_newctx }, + { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))codec_freectx }, + { OSSL_FUNC_DECODER_DECODE, (void (*)(void))inter2key_decode }, + { OSSL_FUNC_DECODER_EXPORT_OBJECT, (void (*)(void))key_export_object }, + OSSL_DISPATCH_END +}; + +static const OSSL_ALGORITHM test_decoders[] = { + { KEY_NAME, "provider=apitest,input=" INTER_NAME ",structure=" STRUCTURE_NAME, + inter2key_decoder_functions }, + { INTER_NAME, "provider=apitest,input=" PEM_NAME, + pem2inter_decoder_functions }, + { NULL, NULL, NULL } +}; + +static const OSSL_ALGORITHM *apitest_query(void *provctx, int operation_id, + int *no_cache) +{ + *no_cache = 0; + switch (operation_id) { + case OSSL_OP_ENCODER: + return test_encoders; + case OSSL_OP_DECODER: + return test_decoders; + } + return NULL; +} + +static const OSSL_DISPATCH apitest_dispatch_table[] = { + { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))apitest_query }, + { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))OSSL_LIB_CTX_free }, + OSSL_DISPATCH_END +}; + +static int apitest_provider_init(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in, + const OSSL_DISPATCH **out, void **provctx) +{ + OSSL_LIB_CTX *libctx = OSSL_LIB_CTX_new_child(handle, in); + + if (libctx == NULL) + return 0; + *provctx = libctx; + *out = apitest_dispatch_table; + return 1; +} + +/* + * The encoder/decoder context callbacks used by the tests + */ + +struct enc_construct_data_st { + const struct test_key_st *key; + int fail_construct; + int cleanup_calls; +}; + +static const void *enc_construct(OSSL_ENCODER_INSTANCE *encoder_inst, + void *arg) +{ + struct enc_construct_data_st *data = arg; + + if (data->fail_construct) + return NULL; + /* The constructor gets the deepest matching encoder instance */ + if (!TEST_true(OSSL_ENCODER_is_a( + OSSL_ENCODER_INSTANCE_get_encoder(encoder_inst), KEY_NAME)) + || !TEST_ptr(OSSL_ENCODER_INSTANCE_get_encoder_ctx(encoder_inst)) + || !TEST_str_eq(OSSL_ENCODER_INSTANCE_get_output_type(encoder_inst), + INTER_NAME) + || !TEST_str_eq(OSSL_ENCODER_INSTANCE_get_output_structure( + encoder_inst), + STRUCTURE_NAME)) + return NULL; + return data->key; +} + +static void enc_cleanup(void *arg) +{ + struct enc_construct_data_st *data = arg; + + data->cleanup_calls++; +} + +struct dec_construct_data_st { + unsigned int seed; + char label[64]; + int constructed; + int construct_calls; + int cleanup_calls; +}; + +static int dec_export_cb(const OSSL_PARAM params[], void *arg) +{ + struct dec_construct_data_st *data = arg; + const OSSL_PARAM *p; + char *label = data->label; + + if (!TEST_ptr(p = OSSL_PARAM_locate_const(params, "seed")) + || !TEST_true(OSSL_PARAM_get_uint(p, &data->seed)) + || !TEST_ptr(p = OSSL_PARAM_locate_const(params, "label")) + || !TEST_true(OSSL_PARAM_get_utf8_string(p, &label, + sizeof(data->label)))) + return 0; + data->constructed = 1; + return 1; +} + +static int dec_construct(OSSL_DECODER_INSTANCE *decoder_inst, + const OSSL_PARAM *params, void *arg) +{ + struct dec_construct_data_st *data = arg; + const OSSL_PARAM *p; + int was_set = 0; + + data->construct_calls++; + + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_REFERENCE); + if (p == NULL) { + /* + * An intermediate decoding result (from the "inter" decoder); + * report it as not constructible so that processing continues + * with the next decoder in the chain. + */ + return 0; + } + + if (!TEST_true(OSSL_DECODER_is_a( + OSSL_DECODER_INSTANCE_get_decoder(decoder_inst), KEY_NAME)) + || !TEST_ptr(OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst)) + || !TEST_str_eq(OSSL_DECODER_INSTANCE_get_input_type(decoder_inst), + INTER_NAME) + || !TEST_str_eq(OSSL_DECODER_INSTANCE_get_input_structure(decoder_inst, + &was_set), + STRUCTURE_NAME)) + return 0; + if (!TEST_int_eq(p->data_type, OSSL_PARAM_OCTET_STRING)) + return 0; + + return OSSL_DECODER_export(decoder_inst, p->data, p->data_size, + dec_export_cb, data); +} + +static void dec_cleanup(void *arg) +{ + struct dec_construct_data_st *data = arg; + + data->cleanup_calls++; +} + +/* + * Test helpers + */ + +/* + * Create an encoder context with the "TEST-KEY" -> "inter" -> "pem" encoder + * chain set up. The construct data is allocated here because + * OSSL_ENCODER_CTX_free() frees it; |*cdata_out| is an alias that stays + * valid for as long as the returned context lives. + */ +static OSSL_ENCODER_CTX *make_encoder_ctx(const struct test_key_st *key, + const char *structure, + struct enc_construct_data_st **cdata_out) +{ + OSSL_ENCODER_CTX *ctx = NULL; + OSSL_ENCODER *e_key = NULL, *e_inter = NULL; + struct enc_construct_data_st *cdata = NULL; + int ok = 0; + + if (!TEST_ptr(ctx = OSSL_ENCODER_CTX_new()) + || !TEST_ptr(cdata = OPENSSL_zalloc(sizeof(*cdata))) + || !TEST_true(OSSL_ENCODER_CTX_set_construct_data(ctx, cdata))) + goto end; + cdata->key = key; + *cdata_out = cdata; + cdata = NULL; /* Owned by ctx now */ + + if (!TEST_ptr(e_key = OSSL_ENCODER_fetch(testctx, KEY_NAME, NULL)) + || !TEST_ptr(e_inter = OSSL_ENCODER_fetch(testctx, INTER_NAME, NULL))) + goto end; + + /* + * The encoder chain is walked from the last added encoder towards the + * first one, so the deepest encoder must be added first. + */ + if (!TEST_true(OSSL_ENCODER_CTX_add_encoder(ctx, e_key)) + || !TEST_true(OSSL_ENCODER_CTX_add_encoder(ctx, e_inter)) + || !TEST_int_eq(OSSL_ENCODER_CTX_get_num_encoders(ctx), 2) + || !TEST_true(OSSL_ENCODER_CTX_add_extra(ctx, testctx, NULL)) + || !TEST_true(OSSL_ENCODER_CTX_set_output_type(ctx, PEM_NAME)) + || (structure != NULL + && !TEST_true(OSSL_ENCODER_CTX_set_output_structure(ctx, + structure))) + || !TEST_true(OSSL_ENCODER_CTX_set_selection(ctx, TEST_SELECTION)) + || !TEST_true(OSSL_ENCODER_CTX_set_construct(ctx, enc_construct)) + || !TEST_true(OSSL_ENCODER_CTX_set_cleanup(ctx, enc_cleanup))) + goto end; + ok = 1; +end: + OSSL_ENCODER_free(e_key); + OSSL_ENCODER_free(e_inter); + OPENSSL_free(cdata); + if (!ok) { + OSSL_ENCODER_CTX_free(ctx); + ctx = NULL; + } + return ctx; +} + +static OSSL_DECODER_CTX *make_decoder_ctx(struct dec_construct_data_st *cdata) +{ + OSSL_DECODER_CTX *ctx = NULL; + OSSL_DECODER *d_key = NULL, *d_inter = NULL; + int ok = 0; + + if (!TEST_ptr(ctx = OSSL_DECODER_CTX_new()) + || !TEST_int_eq(OSSL_DECODER_CTX_get_num_decoders(ctx), 0) + || !TEST_ptr(d_key = OSSL_DECODER_fetch(testctx, KEY_NAME, NULL)) + || !TEST_ptr(d_inter = OSSL_DECODER_fetch(testctx, INTER_NAME, NULL))) + goto end; + + /* + * The decoder chain is walked from the last added decoder towards the + * first one, so the final decoder must be added first. + */ + if (!TEST_true(OSSL_DECODER_CTX_add_decoder(ctx, d_key)) + || !TEST_true(OSSL_DECODER_CTX_add_decoder(ctx, d_inter)) + || !TEST_int_eq(OSSL_DECODER_CTX_get_num_decoders(ctx), 2) + || !TEST_true(OSSL_DECODER_CTX_set_input_type(ctx, PEM_NAME)) + || !TEST_true(OSSL_DECODER_CTX_set_input_structure(ctx, + STRUCTURE_NAME)) + || !TEST_true(OSSL_DECODER_CTX_set_selection(ctx, TEST_SELECTION)) + || !TEST_true(OSSL_DECODER_CTX_set_construct(ctx, dec_construct)) + || !TEST_true(OSSL_DECODER_CTX_set_construct_data(ctx, cdata)) + || !TEST_true(OSSL_DECODER_CTX_set_cleanup(ctx, dec_cleanup))) + goto end; + ok = 1; +end: + OSSL_DECODER_free(d_key); + OSSL_DECODER_free(d_inter); + if (!ok) { + OSSL_DECODER_CTX_free(ctx); + ctx = NULL; + } + return ctx; +} + +static int make_expected(const struct test_key_st *key, char *buf, + size_t bufsz, size_t *len) +{ + int n = snprintf(buf, bufsz, + PEM_HEADER INTER_PREFIX "%u:%s" PEM_FOOTER, key->seed, key->label); + + if (n <= 0) + return 0; + *len = (size_t)n; + return 1; +} + +/* + * Encode a test key through the two-stage encoder chain into a BIO and + * check the result. + */ +static int test_chain_encode_to_bio(void) +{ + const struct test_key_st key = { 12345, "chained" }; + struct enc_construct_data_st *cdata = NULL; + OSSL_ENCODER_CTX *ectx = NULL; + BIO *out = NULL; + BUF_MEM *mem = NULL; + char expected[256]; + size_t expected_len = 0; + int ok = 0; + + if (!TEST_true(make_expected(&key, expected, sizeof(expected), &expected_len)) + || !TEST_ptr(ectx = make_encoder_ctx(&key, STRUCTURE_NAME, &cdata))) + goto end; + + if (!TEST_ptr(out = BIO_new(BIO_s_mem())) + || !TEST_true(OSSL_ENCODER_to_bio(ectx, out)) + || !TEST_true(BIO_get_mem_ptr(out, &mem) > 0) + || !TEST_mem_eq(mem->data, mem->length, expected, expected_len)) + goto end; + + /* The cleanup callback must have been called exactly once */ + if (!TEST_int_eq(cdata->cleanup_calls, 1)) + goto end; + + ok = 1; +end: + BIO_free(out); + OSSL_ENCODER_CTX_free(ectx); + return ok; +} + +/* Exercise the various OSSL_ENCODER_to_data() modes of operation */ +static int test_chain_encode_to_data(void) +{ + const struct test_key_st key = { 999, "to-data" }; + struct enc_construct_data_st *cdata = NULL; + OSSL_ENCODER_CTX *ectx = NULL; + unsigned char *buf = NULL, *p, *allocated = NULL; + char expected[256]; + size_t expected_len = 0, len, sz; + int ok = 0; + + if (!TEST_true(make_expected(&key, expected, sizeof(expected), &expected_len)) + /* No output structure this time; the chain works without one too */ + || !TEST_ptr(ectx = make_encoder_ctx(&key, NULL, &cdata))) + goto end; + + /* A NULL pdata_len is an error */ + if (!TEST_false(OSSL_ENCODER_to_data(ectx, NULL, NULL))) + goto end; + + /* Size query */ + len = 0; + if (!TEST_true(OSSL_ENCODER_to_data(ectx, NULL, &len)) + || !TEST_size_t_eq(len, expected_len)) + goto end; + + /* Encoding into a pre-allocated buffer of exactly the right size */ + if (!TEST_ptr(buf = OPENSSL_malloc(len))) + goto end; + p = buf; + sz = len; + if (!TEST_true(OSSL_ENCODER_to_data(ectx, &p, &sz)) + || !TEST_size_t_eq(sz, 0) + || !TEST_ptr_eq(p, buf + expected_len) + || !TEST_mem_eq(buf, expected_len, expected, expected_len)) + goto end; + + /* A too small pre-allocated buffer is an error */ + p = buf; + sz = expected_len - 1; + if (!TEST_false(OSSL_ENCODER_to_data(ectx, &p, &sz))) + goto end; + + /* With *pdata == NULL, the buffer is allocated for us */ + sz = 0; + if (!TEST_true(OSSL_ENCODER_to_data(ectx, &allocated, &sz)) + || !TEST_mem_eq(allocated, sz, expected, expected_len)) + goto end; + + ok = 1; +end: + OPENSSL_free(buf); + OPENSSL_free(allocated); + OSSL_ENCODER_CTX_free(ectx); + return ok; +} + +/* Decode through the decoder chain and check the constructed object */ +static int test_chain_decode_from_data(void) +{ + const struct test_key_st key = { 4711, "decode" }; + struct dec_construct_data_st dcdata; + OSSL_DECODER_CTX *dctx = NULL; + char encoded[256]; + size_t encoded_len = 0; + const unsigned char *pdata; + size_t pdata_len; + int ok = 0; + + memset(&dcdata, 0, sizeof(dcdata)); + if (!TEST_true(make_expected(&key, encoded, sizeof(encoded), &encoded_len)) + || !TEST_ptr(dctx = make_decoder_ctx(&dcdata))) + goto end; + + pdata = (unsigned char *)encoded; + pdata_len = encoded_len; + if (!TEST_true(OSSL_DECODER_from_data(dctx, &pdata, &pdata_len)) + || !TEST_size_t_eq(pdata_len, 0) + || !TEST_true(dcdata.constructed) + || !TEST_uint_eq(dcdata.seed, key.seed) + || !TEST_str_eq(dcdata.label, key.label) + /* Once for the intermediate decoder, once for the final one */ + || !TEST_int_eq(dcdata.construct_calls, 2)) + goto end; + + OSSL_DECODER_CTX_free(dctx); + dctx = NULL; + /* The cleanup callback is called when the context is freed */ + if (!TEST_int_eq(dcdata.cleanup_calls, 1)) + goto end; + + ok = 1; +end: + OSSL_DECODER_CTX_free(dctx); + return ok; +} + +#ifndef OPENSSL_NO_STDIO +/* Round-trip via OSSL_ENCODER_to_fp() and OSSL_DECODER_from_fp() */ +static int test_chain_roundtrip_fp(void) +{ + const struct test_key_st key = { 31337, "stdio" }; + struct enc_construct_data_st *ecdata = NULL; + struct dec_construct_data_st dcdata; + OSSL_ENCODER_CTX *ectx = NULL; + OSSL_DECODER_CTX *dctx = NULL; + const char *fname = "endecode_api_test.tmp"; + FILE *fp = NULL; + int ok = 0; + + memset(&dcdata, 0, sizeof(dcdata)); + if (!TEST_ptr(ectx = make_encoder_ctx(&key, STRUCTURE_NAME, &ecdata)) + || !TEST_ptr(dctx = make_decoder_ctx(&dcdata))) + goto end; + + if (!TEST_ptr(fp = fopen(fname, "w+b")) + || !TEST_true(OSSL_ENCODER_to_fp(ectx, fp))) + goto end; + rewind(fp); + if (!TEST_true(OSSL_DECODER_from_fp(dctx, fp)) + || !TEST_true(dcdata.constructed) + || !TEST_uint_eq(dcdata.seed, key.seed) + || !TEST_str_eq(dcdata.label, key.label)) + goto end; + + ok = 1; +end: + if (fp != NULL) { + fclose(fp); + remove(fname); + } + OSSL_ENCODER_CTX_free(ectx); + OSSL_DECODER_CTX_free(dctx); + return ok; +} +#endif + +/* + * A source BIO that doesn't support BIO_tell(), forcing + * OSSL_DECODER_from_bio() to wrap it with a read buffer filter BIO. + */ + +struct nonseek_state_st { + const unsigned char *data; + size_t len; + size_t pos; +}; + +static int nonseek_read(BIO *b, char *out, int outl) +{ + struct nonseek_state_st *st = BIO_get_data(b); + size_t n = st->len - st->pos; + + if (n == 0) + return 0; + if (n > (size_t)outl) + n = (size_t)outl; + memcpy(out, st->data + st->pos, n); + st->pos += n; + return (int)n; +} + +static long nonseek_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + struct nonseek_state_st *st = BIO_get_data(b); + + switch (cmd) { + case BIO_CTRL_EOF: + return st->pos >= st->len; + case BIO_C_FILE_TELL: + return -1; + } + return 0; +} + +static BIO_METHOD *nonseek_meth = NULL; + +static int test_decode_non_seekable_bio(void) +{ + const struct test_key_st key = { 2222, "nonseek" }; + struct dec_construct_data_st dcdata; + OSSL_DECODER_CTX *dctx = NULL; + struct nonseek_state_st st; + BIO *in = NULL; + char encoded[256]; + size_t encoded_len = 0; + int ok = 0; + + memset(&dcdata, 0, sizeof(dcdata)); + if (!TEST_true(make_expected(&key, encoded, sizeof(encoded), &encoded_len)) + || !TEST_ptr(dctx = make_decoder_ctx(&dcdata))) + goto end; + + st.data = (unsigned char *)encoded; + st.len = encoded_len; + st.pos = 0; + if (!TEST_ptr(in = BIO_new(nonseek_meth))) + goto end; + BIO_set_data(in, &st); + BIO_set_init(in, 1); + + if (!TEST_int_lt(BIO_tell(in), 0) + || !TEST_true(OSSL_DECODER_from_bio(dctx, in)) + || !TEST_true(dcdata.constructed) + || !TEST_uint_eq(dcdata.seed, key.seed) + || !TEST_str_eq(dcdata.label, key.label)) + goto end; + + ok = 1; +end: + BIO_free(in); + OSSL_DECODER_CTX_free(dctx); + return ok; +} + +/* Various ways an encoding attempt can fail */ +static int test_encode_failures(void) +{ + const struct test_key_st key = { 1, "fail" }; + const struct test_key_st failkey = { FAIL_SEED, "fail" }; + struct enc_construct_data_st *cdata = NULL; + OSSL_ENCODER_CTX *ectx = NULL; + OSSL_ENCODER *encoder = NULL; + BIO *out = NULL; + int ok = 0; + + if (!TEST_ptr(out = BIO_new(BIO_s_mem()))) + goto end; + + /* An empty encoder context finds no encoders */ + if (!TEST_ptr(ectx = OSSL_ENCODER_CTX_new()) + || !TEST_false(OSSL_ENCODER_to_bio(ectx, out))) + goto end; + OSSL_ENCODER_CTX_free(ectx); + ectx = NULL; + + /* A context without a constructor cannot encode */ + if (!TEST_ptr(ectx = OSSL_ENCODER_CTX_new()) + || !TEST_ptr(encoder = OSSL_ENCODER_fetch(testctx, INTER_NAME, NULL)) + || !TEST_true(OSSL_ENCODER_CTX_add_encoder(ectx, encoder)) + || !TEST_false(OSSL_ENCODER_to_bio(ectx, out))) + goto end; + OSSL_ENCODER_CTX_free(ectx); + ectx = NULL; + + /* An output structure that no encoder implements */ + if (!TEST_ptr(ectx = make_encoder_ctx(&key, "unknown-structure", &cdata)) + || !TEST_false(OSSL_ENCODER_to_bio(ectx, out))) + goto end; + OSSL_ENCODER_CTX_free(ectx); + ectx = NULL; + + /* A failing constructor makes the encoding fail */ + if (!TEST_ptr(ectx = make_encoder_ctx(&key, STRUCTURE_NAME, &cdata))) + goto end; + cdata->fail_construct = 1; + if (!TEST_false(OSSL_ENCODER_to_bio(ectx, out)) + || !TEST_int_eq(cdata->cleanup_calls, 0)) + goto end; + OSSL_ENCODER_CTX_free(ectx); + ectx = NULL; + + /* A failing encoder implementation makes the encoding fail */ + if (!TEST_ptr(ectx = make_encoder_ctx(&failkey, STRUCTURE_NAME, &cdata)) + || !TEST_false(OSSL_ENCODER_to_bio(ectx, out)) + /* The constructor succeeded, so the cleanup must have been called */ + || !TEST_int_eq(cdata->cleanup_calls, 1)) + goto end; + + ok = 1; +end: + OSSL_ENCODER_free(encoder); + OSSL_ENCODER_CTX_free(ectx); + BIO_free(out); + return ok; +} + +/* Undecodable input must fail without constructing anything */ +static int test_decode_garbage(void) +{ + struct dec_construct_data_st dcdata; + OSSL_DECODER_CTX *dctx = NULL; + static const char garbage[] = "this is not an encoded test key"; + const unsigned char *pdata = (const unsigned char *)garbage; + size_t pdata_len = sizeof(garbage) - 1; + int ok = 0; + + memset(&dcdata, 0, sizeof(dcdata)); + if (!TEST_ptr(dctx = make_decoder_ctx(&dcdata))) + goto end; + + if (!TEST_false(OSSL_DECODER_from_data(dctx, &pdata, &pdata_len)) + || !TEST_false(dcdata.constructed)) + goto end; + + ok = 1; +end: + OSSL_DECODER_CTX_free(dctx); + return ok; +} + +/* NULL argument checks on the encoder API */ +static int test_encoder_null_args(void) +{ + OSSL_ENCODER_CTX *ectx = NULL; + OSSL_ENCODER *encoder = NULL; + unsigned char *pdata = NULL; + int ok = 0; + + if (!TEST_ptr(ectx = OSSL_ENCODER_CTX_new()) + || !TEST_ptr(encoder = OSSL_ENCODER_fetch(testctx, KEY_NAME, NULL))) + goto end; + + if (!TEST_false(OSSL_ENCODER_CTX_set_selection(NULL, TEST_SELECTION)) + || !TEST_false(OSSL_ENCODER_CTX_set_selection(ectx, 0)) + || !TEST_false(OSSL_ENCODER_CTX_set_output_type(NULL, PEM_NAME)) + || !TEST_false(OSSL_ENCODER_CTX_set_output_type(ectx, NULL)) + || !TEST_false(OSSL_ENCODER_CTX_set_output_structure(NULL, STRUCTURE_NAME)) + || !TEST_false(OSSL_ENCODER_CTX_set_output_structure(ectx, NULL)) + || !TEST_false(OSSL_ENCODER_CTX_add_encoder(NULL, encoder)) + || !TEST_false(OSSL_ENCODER_CTX_add_encoder(ectx, NULL)) + || !TEST_false(OSSL_ENCODER_CTX_add_extra(NULL, testctx, NULL)) + || !TEST_false(OSSL_ENCODER_CTX_set_construct(NULL, enc_construct)) + || !TEST_false(OSSL_ENCODER_CTX_set_construct_data(NULL, NULL)) + || !TEST_false(OSSL_ENCODER_CTX_set_cleanup(NULL, enc_cleanup)) + || !TEST_int_eq(OSSL_ENCODER_CTX_get_num_encoders(NULL), 0) + || !TEST_false(OSSL_ENCODER_to_data(ectx, &pdata, NULL))) + goto end; + + if (!TEST_ptr_null(OSSL_ENCODER_INSTANCE_get_encoder(NULL)) + || !TEST_ptr_null(OSSL_ENCODER_INSTANCE_get_encoder_ctx(NULL)) + || !TEST_ptr_null(OSSL_ENCODER_INSTANCE_get_output_type(NULL)) + || !TEST_ptr_null(OSSL_ENCODER_INSTANCE_get_output_structure(NULL))) + goto end; + + ok = 1; +end: + OSSL_ENCODER_free(encoder); + OSSL_ENCODER_CTX_free(ectx); + return ok; +} + +/* NULL argument checks on the decoder API */ +static int test_decoder_null_args(void) +{ + OSSL_DECODER_CTX *dctx = NULL; + OSSL_DECODER *decoder = NULL; + const unsigned char *pdata = NULL; + unsigned char buf[16]; + const unsigned char *pbuf = buf; + size_t pdata_len = 0; + int was_set = 0; + int ok = 0; + + if (!TEST_ptr(dctx = OSSL_DECODER_CTX_new()) + || !TEST_ptr(decoder = OSSL_DECODER_fetch(testctx, KEY_NAME, NULL))) + goto end; + + if (!TEST_false(OSSL_DECODER_CTX_set_selection(NULL, TEST_SELECTION)) + || !TEST_false(OSSL_DECODER_CTX_set_input_type(NULL, PEM_NAME)) + || !TEST_false(OSSL_DECODER_CTX_set_input_structure(NULL, STRUCTURE_NAME)) + || !TEST_false(OSSL_DECODER_CTX_add_decoder(NULL, decoder)) + || !TEST_false(OSSL_DECODER_CTX_add_decoder(dctx, NULL)) + || !TEST_false(OSSL_DECODER_CTX_add_extra(NULL, testctx, NULL)) + || !TEST_false(OSSL_DECODER_CTX_set_construct(NULL, dec_construct)) + || !TEST_false(OSSL_DECODER_CTX_set_construct_data(NULL, NULL)) + || !TEST_false(OSSL_DECODER_CTX_set_cleanup(NULL, dec_cleanup)) + || !TEST_int_eq(OSSL_DECODER_CTX_get_num_decoders(NULL), 0) + || !TEST_false(OSSL_DECODER_from_data(dctx, NULL, &pdata_len)) + || !TEST_false(OSSL_DECODER_from_data(dctx, &pdata, &pdata_len)) + || !TEST_false(OSSL_DECODER_from_data(dctx, &pbuf, NULL)) + || !TEST_false(OSSL_DECODER_export(NULL, NULL, 0, NULL, NULL))) + goto end; + + if (!TEST_true(OSSL_DECODER_CTX_get_construct(NULL) == NULL) + || !TEST_ptr_null(OSSL_DECODER_CTX_get_construct_data(NULL)) + || !TEST_true(OSSL_DECODER_CTX_get_cleanup(NULL) == NULL) + || !TEST_ptr_null(OSSL_DECODER_INSTANCE_get_decoder(NULL)) + || !TEST_ptr_null(OSSL_DECODER_INSTANCE_get_decoder_ctx(NULL)) + || !TEST_ptr_null(OSSL_DECODER_INSTANCE_get_input_type(NULL)) + || !TEST_ptr_null(OSSL_DECODER_INSTANCE_get_input_structure(NULL, &was_set))) + goto end; + + ok = 1; +end: + OSSL_DECODER_free(decoder); + OSSL_DECODER_CTX_free(dctx); + return ok; +} + +int setup_tests(void) +{ + if (!TEST_ptr(testctx = OSSL_LIB_CTX_new()) + || !TEST_true(OSSL_PROVIDER_add_builtin(testctx, "apitest-prov", + apitest_provider_init)) + || !TEST_ptr(testprov = OSSL_PROVIDER_load(testctx, "apitest-prov"))) + return 0; + + if (!TEST_ptr(nonseek_meth = BIO_meth_new(BIO_TYPE_SOURCE_SINK, + "non-seekable source")) + || !TEST_true(BIO_meth_set_read(nonseek_meth, nonseek_read)) + || !TEST_true(BIO_meth_set_ctrl(nonseek_meth, nonseek_ctrl))) + return 0; + + ADD_TEST(test_chain_encode_to_bio); + ADD_TEST(test_chain_encode_to_data); + ADD_TEST(test_chain_decode_from_data); +#ifndef OPENSSL_NO_STDIO + ADD_TEST(test_chain_roundtrip_fp); +#endif + ADD_TEST(test_decode_non_seekable_bio); + ADD_TEST(test_encode_failures); + ADD_TEST(test_decode_garbage); + ADD_TEST(test_encoder_null_args); + ADD_TEST(test_decoder_null_args); + return 1; +} + +void cleanup_tests(void) +{ + BIO_meth_free(nonseek_meth); + OSSL_PROVIDER_unload(testprov); + OSSL_LIB_CTX_free(testctx); +} diff --git a/test/endecode_test.c b/test/endecode_test.c index a2c5d4009d108..ec02b86a02ab6 100644 --- a/test/endecode_test.c +++ b/test/endecode_test.c @@ -658,11 +658,15 @@ static int check_params_PEM(const char *file, const int line, { static char expected_pem_header[80]; - return TEST_FL_int_gt(BIO_snprintf(expected_pem_header, - sizeof(expected_pem_header), - "-----BEGIN %s PARAMETERS-----", type), - 0) - && TEST_FL_strn_eq(data, expected_pem_header, strlen(expected_pem_header)); + { + int n = snprintf(expected_pem_header, sizeof(expected_pem_header), + "-----BEGIN %s PARAMETERS-----", type); + + return TEST_FL_int_gt(n, 0) + && TEST_FL_true((size_t)n < sizeof(expected_pem_header)) + && TEST_FL_strn_eq(data, expected_pem_header, + strlen(expected_pem_header)); + } } static int test_params_via_DER(const char *type, EVP_PKEY *key) @@ -690,11 +694,15 @@ static int check_unprotected_legacy_PEM(const char *file, const int line, { static char expected_pem_header[80]; - return TEST_FL_int_gt(BIO_snprintf(expected_pem_header, - sizeof(expected_pem_header), - "-----BEGIN %s PRIVATE KEY-----", type), - 0) - && TEST_FL_strn_eq(data, expected_pem_header, strlen(expected_pem_header)); + { + int n = snprintf(expected_pem_header, sizeof(expected_pem_header), + "-----BEGIN %s PRIVATE KEY-----", type); + + return TEST_FL_int_gt(n, 0) + && TEST_FL_true((size_t)n < sizeof(expected_pem_header)) + && TEST_FL_strn_eq(data, expected_pem_header, + strlen(expected_pem_header)); + } } static int test_unprotected_via_legacy_PEM(const char *type, EVP_PKEY *key) @@ -810,12 +818,16 @@ static int check_protected_legacy_PEM(const char *file, const int line, { static char expected_pem_header[80]; - return TEST_FL_int_gt(BIO_snprintf(expected_pem_header, - sizeof(expected_pem_header), - "-----BEGIN %s PRIVATE KEY-----", type), - 0) - && TEST_FL_strn_eq(data, expected_pem_header, strlen(expected_pem_header)) - && TEST_FL_ptr(strstr(data, "\nDEK-Info: ")); + { + int n = snprintf(expected_pem_header, sizeof(expected_pem_header), + "-----BEGIN %s PRIVATE KEY-----", type); + + return TEST_FL_int_gt(n, 0) + && TEST_FL_true((size_t)n < sizeof(expected_pem_header)) + && TEST_FL_strn_eq(data, expected_pem_header, + strlen(expected_pem_header)) + && TEST_FL_ptr(strstr(data, "\nDEK-Info: ")); + } } static int test_protected_via_legacy_PEM(const char *type, EVP_PKEY *key) diff --git a/test/errtest.c b/test/errtest.c index 7183548080740..d686f257a75fd 100644 --- a/test/errtest.c +++ b/test/errtest.c @@ -83,11 +83,11 @@ static int test_print_error_format(void) reason = strerror(syserr); #else lib = "lib(2)"; - BIO_snprintf(reasonbuf, sizeof(reasonbuf), "reason(%lu)", reasoncode); + snprintf(reasonbuf, sizeof(reasonbuf), "reason(%lu)", reasoncode); reason = reasonbuf; #endif - BIO_snprintf(expected, sizeof(expected), expected_format, + snprintf(expected, sizeof(expected), expected_format, errorcode, lib, func, reason, file, line); if (!TEST_ptr(bio = BIO_new(BIO_s_mem()))) diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c index 5c37102088935..e170896d58865 100644 --- a/test/evp_extra_test.c +++ b/test/evp_extra_test.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include #include @@ -4244,6 +4246,76 @@ static int test_RSA_verify_recover_rejects_short_buffer(void) return ret; } +/* + * A raw RSA PKCS#1 v1.5 signature whose recovered data is empty must be + * recovered successfully with a length of zero, not rejected as an error. + */ +static int test_RSA_verify_recover_empty_payload(void) +{ + int ret = 0; + int recovered_cap = 0; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *sign_ctx = NULL, *verify_ctx = NULL; + unsigned char *sig = NULL, *recovered = NULL; + size_t sig_len = 0, recovered_len = 0; + /* + * The signed input has zero length, but a valid non-null address is still + * passed so the result does not depend on how lower layers treat NULL for + * zero-length data. + */ + const unsigned char empty[] = { 0 }; + + if (OSSL_PROVIDER_available(testctx, "fips")) + return TEST_skip("Test skipped for FIPS provider"); + + if (!TEST_ptr(pkey = load_example_rsa_key()) + || !TEST_ptr(sign_ctx = EVP_PKEY_CTX_new_from_pkey(testctx, pkey, NULL)) + || !TEST_int_gt(EVP_PKEY_sign_init(sign_ctx), 0) + || !TEST_int_gt(EVP_PKEY_CTX_set_rsa_padding(sign_ctx, RSA_PKCS1_PADDING), 0) + /* + * Deliberately do not configure a signature digest so that the raw + * PKCS#1 v1.5 sign and verify-recover paths are exercised. + */ + || !TEST_int_gt(EVP_PKEY_sign(sign_ctx, NULL, &sig_len, empty, 0), 0) + || !TEST_ptr(sig = OPENSSL_malloc(sig_len)) + || !TEST_int_gt(EVP_PKEY_sign(sign_ctx, sig, &sig_len, empty, 0), 0) + || !TEST_int_gt(recovered_cap = EVP_PKEY_get_size(pkey), 0) + || !TEST_ptr(recovered = OPENSSL_malloc(recovered_cap)) + || !TEST_ptr(verify_ctx = EVP_PKEY_CTX_new_from_pkey(testctx, pkey, NULL)) + || !TEST_int_gt(EVP_PKEY_verify_recover_init(verify_ctx), 0) + || !TEST_int_gt(EVP_PKEY_CTX_set_rsa_padding(verify_ctx, RSA_PKCS1_PADDING), + 0)) + goto done; + + /* Size-query call must succeed. */ + recovered_len = (size_t)recovered_cap; + if (!TEST_int_gt(EVP_PKEY_verify_recover(verify_ctx, NULL, + &recovered_len, sig, sig_len), + 0)) + goto done; + + /* + * The actual recovery call is essential: a NULL output buffer would only + * run the size-query path, which never decodes the signature and so would + * not reproduce the regression. + */ + recovered_len = (size_t)recovered_cap; + if (!TEST_int_gt(EVP_PKEY_verify_recover(verify_ctx, recovered, + &recovered_len, sig, sig_len), + 0) + || !TEST_size_t_eq(recovered_len, 0)) + goto done; + + ret = 1; +done: + EVP_PKEY_CTX_free(sign_ctx); + EVP_PKEY_CTX_free(verify_ctx); + EVP_PKEY_free(pkey); + OPENSSL_free(sig); + OPENSSL_free(recovered); + return ret; +} + static int test_RSA_encrypt(void) { int ret = 0; @@ -5217,6 +5289,215 @@ static int test_EVP_rsa_invalid_key(void) return ret; } +static int test_EVP_rsa_pss_utf8_ptr_params(void) +{ + char *digest = "SHA256"; + char *maskgenfunc = "MGF1"; + char *mgf1_digest = "SHA384"; + char *missing_provider = "provider=missing"; + OSSL_PARAM ptr_params[] = { + OSSL_PARAM_utf8_ptr(OSSL_PKEY_PARAM_RSA_DIGEST, &digest, 0), + OSSL_PARAM_utf8_ptr(OSSL_PKEY_PARAM_RSA_MASKGENFUNC, + &maskgenfunc, 0), + OSSL_PARAM_utf8_ptr(OSSL_PKEY_PARAM_RSA_MGF1_DIGEST, + &mgf1_digest, 0), + OSSL_PARAM_END + }; + OSSL_PARAM property_params[] = { + OSSL_PARAM_utf8_ptr(OSSL_PKEY_PARAM_RSA_DIGEST, &digest, 0), + OSSL_PARAM_utf8_ptr(OSSL_PKEY_PARAM_RSA_DIGEST_PROPS, + &missing_provider, 0), + OSSL_PARAM_END + }; + EVP_PKEY_CTX *ctx = NULL; + int ret = 0; + + if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(testctx, "RSA-PSS", + testpropq)) + || !TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0) + || !TEST_int_gt(EVP_PKEY_CTX_set_params(ctx, ptr_params), 0) + || !TEST_int_le(EVP_PKEY_CTX_set_params(ctx, property_params), 0)) + goto err; + ERR_clear_error(); + ret = 1; +err: + EVP_PKEY_CTX_free(ctx); + return ret; +} + +#ifndef OPENSSL_NO_EC +static int test_ec_fromdata_selection_params(void) +{ + char group_name[] = "prime256v1"; + unsigned char pub[] = { 0 }; + OSSL_PARAM params[] = { + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_GROUP_NAME, group_name, 0), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, pub, sizeof(pub)), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, pub, sizeof(pub)), + OSSL_PARAM_END + }; + EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY *pkey = NULL; + const OSSL_PARAM *settable = NULL; + int ret = 0; + + if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(testctx, "EC", testpropq)) + || !TEST_int_gt(EVP_PKEY_fromdata_init(ctx), 0) + || !TEST_ptr(settable = EVP_PKEY_fromdata_settable( + ctx, EVP_PKEY_KEY_PARAMETERS)) + || !TEST_ptr_null(OSSL_PARAM_locate_const( + settable, OSSL_PKEY_PARAM_PUB_KEY)) + || !TEST_int_gt(EVP_PKEY_fromdata_init(ctx), 0) + || !TEST_int_gt(EVP_PKEY_fromdata(ctx, &pkey, + EVP_PKEY_KEY_PARAMETERS, params), + 0)) + goto err; + ret = 1; +err: + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + return ret; +} +#endif + +#ifndef OPENSSL_NO_SM2 +static int test_sm2_common_set_params(void) +{ + static const unsigned char expected_seed[] = { 1, 2, 3, 4, 5 }; + char requested_encoding[] = "explicit"; + char requested_point_format[] = "compressed"; + unsigned char requested_seed[sizeof(expected_seed)]; + OSSL_PARAM set_params[] = { + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, + requested_encoding, 0), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, + requested_point_format, 0), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, requested_seed, + sizeof(requested_seed)), + OSSL_PARAM_END + }; + char encoding[16] = { 0 }; + char point_format[16] = { 0 }; + unsigned char seed[sizeof(expected_seed)] = { 0 }; + OSSL_PARAM get_params[] = { + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_ENCODING, encoding, + sizeof(encoding)), + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT, + point_format, sizeof(point_format)), + OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, seed, sizeof(seed)), + OSSL_PARAM_END + }; + EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY *pkey = NULL; + const OSSL_PARAM *settable; + int ret = 0; + + memcpy(requested_seed, expected_seed, sizeof(requested_seed)); + if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(testctx, "SM2", testpropq)) + || !TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0) + || !TEST_int_gt(EVP_PKEY_keygen(ctx, &pkey), 0) + || !TEST_ptr(settable = EVP_PKEY_settable_params(pkey)) + || !TEST_ptr(OSSL_PARAM_locate_const(settable, + OSSL_PKEY_PARAM_EC_ENCODING)) + || !TEST_ptr(OSSL_PARAM_locate_const(settable, + OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT)) + || !TEST_ptr(OSSL_PARAM_locate_const(settable, + OSSL_PKEY_PARAM_EC_SEED)) + || !TEST_int_gt(EVP_PKEY_set_params(pkey, set_params), 0) + || !TEST_int_gt(EVP_PKEY_get_params(pkey, get_params), 0) + || !TEST_str_eq(encoding, requested_encoding) + || !TEST_str_eq(point_format, requested_point_format) + || !TEST_size_t_eq(get_params[2].return_size, sizeof(expected_seed)) + || !TEST_mem_eq(seed, sizeof(seed), expected_seed, + sizeof(expected_seed))) + goto err; + ret = 1; +err: + EVP_PKEY_free(pkey); + EVP_PKEY_CTX_free(ctx); + return ret; +} +#endif + +static int param_is_advertised(const OSSL_PARAM *params, const char *name) +{ + return params != NULL && OSSL_PARAM_locate_const(params, name) != NULL; +} + +static int test_rsa_algorithm_param_lists(void) +{ + static const char *pss_names[] = { + OSSL_PKEY_PARAM_RSA_DIGEST, + OSSL_PKEY_PARAM_RSA_DIGEST_PROPS, + OSSL_PKEY_PARAM_RSA_MASKGENFUNC, + OSSL_PKEY_PARAM_RSA_MGF1_DIGEST, + OSSL_PKEY_PARAM_RSA_PSS_SALTLEN + }; + EVP_PKEY_CTX *rsa_ctx = NULL, *pss_ctx = NULL; + EVP_PKEY *rsa = NULL, *pss = NULL; + const OSSL_PARAM *rsa_import, *pss_import; + const OSSL_PARAM *rsa_gettable, *pss_gettable; + char untouched[16] = "unchanged"; + OSSL_PARAM ignored[] = { + OSSL_PARAM_utf8_string(OSSL_PKEY_PARAM_RSA_DIGEST, untouched, + sizeof(untouched)), + OSSL_PARAM_END + }; + size_t i; + int ret = 0; + int selection = EVP_PKEY_KEYPAIR + | OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS; + + if (!TEST_ptr(rsa_ctx = EVP_PKEY_CTX_new_from_name(testctx, "RSA", + testpropq)) + || !TEST_ptr(pss_ctx = EVP_PKEY_CTX_new_from_name(testctx, "RSA-PSS", + testpropq)) + || !TEST_int_gt(EVP_PKEY_fromdata_init(rsa_ctx), 0) + || !TEST_int_gt(EVP_PKEY_fromdata_init(pss_ctx), 0) + || !TEST_ptr(rsa_import = EVP_PKEY_fromdata_settable(rsa_ctx, + selection)) + || !TEST_ptr(pss_import = EVP_PKEY_fromdata_settable(pss_ctx, + selection))) + goto err; + for (i = 0; i < OSSL_NELEM(pss_names); i++) { + if (!TEST_false(param_is_advertised(rsa_import, pss_names[i])) + || !TEST_true(param_is_advertised(pss_import, pss_names[i]))) + goto err; + } + + if (!TEST_int_gt(EVP_PKEY_keygen_init(rsa_ctx), 0) + || !TEST_int_gt(EVP_PKEY_CTX_set_rsa_keygen_bits(rsa_ctx, 1024), 0) + || !TEST_int_gt(EVP_PKEY_keygen(rsa_ctx, &rsa), 0) + || !TEST_int_gt(EVP_PKEY_keygen_init(pss_ctx), 0) + || !TEST_int_gt(EVP_PKEY_CTX_set_rsa_keygen_bits(pss_ctx, 1024), 0) + || !TEST_int_gt(EVP_PKEY_keygen(pss_ctx, &pss), 0) + || !TEST_ptr(rsa_gettable = EVP_PKEY_gettable_params(rsa)) + || !TEST_ptr(pss_gettable = EVP_PKEY_gettable_params(pss))) + goto err; + for (i = 0; i < OSSL_NELEM(pss_names); i++) { + if (!TEST_false(param_is_advertised(rsa_gettable, pss_names[i]))) + goto err; + if (strcmp(pss_names[i], OSSL_PKEY_PARAM_RSA_DIGEST_PROPS) != 0 + && !TEST_true(param_is_advertised(pss_gettable, pss_names[i]))) + goto err; + } + if (!TEST_false(param_is_advertised(rsa_gettable, + OSSL_PKEY_PARAM_MANDATORY_DIGEST)) + || !TEST_true(param_is_advertised(pss_gettable, + OSSL_PKEY_PARAM_MANDATORY_DIGEST)) + || !TEST_int_gt(EVP_PKEY_get_params(rsa, ignored), 0) + || !TEST_size_t_eq(ignored[0].return_size, OSSL_PARAM_UNMODIFIED) + || !TEST_str_eq(untouched, "unchanged")) + goto err; + ret = 1; +err: + EVP_PKEY_free(rsa); + EVP_PKEY_free(pss); + EVP_PKEY_CTX_free(rsa_ctx); + EVP_PKEY_CTX_free(pss_ctx); + return ret; +} + static int success = 1; static void md_names(const char *name, void *vctx) { @@ -5775,12 +6056,29 @@ static int test_evp_diff_order_init(int idx) return testresult; } +static int prepare_ccm_no_payload(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER_TEST_INFO *info) +{ + static const unsigned char aad[] = "CCM empty-payload Final regression"; + int outlen = 0; + + if (info->mode != EVP_CIPH_CCM_MODE) + return 1; + + return EVP_CipherUpdate(ctx, NULL, &outlen, NULL, 0) > 0 + && EVP_CipherUpdate(ctx, NULL, &outlen, aad, + (int)sizeof(aad) - 1) + > 0; +} + /*- * A zero-length AEAD message driven through the one-shot EVP_Cipher() interface * must agree with the streaming EVP_CipherFinal_ex() path. This checks: * - an empty message yields the same tag via both interfaces * - the true tag passes verification on decrypt * - the modified tag fails verification on decrypt + * For CCM, each operation declares a zero payload length and supplies AAD, but + * deliberately omits the payload Update that would otherwise authenticate it. */ static int test_evp_oneshot_aead_zerolen(int idx) { @@ -5811,9 +6109,6 @@ static int test_evp_oneshot_aead_zerolen(int idx) /* filter out various modes */ if (info->taglen == 0 - || info->mode == EVP_CIPH_CCM_MODE - || info->mode == EVP_CIPH_OCB_MODE - || info->mode == EVP_CIPH_GCM_SIV_MODE /* skip TLS stitched MTE cipher */ || EVP_CIPHER_is_a(info->ciph, "AES-128-CBC-HMAC-SHA1") /* skip TLS stitched MTE cipher */ @@ -5821,8 +6116,7 @@ static int test_evp_oneshot_aead_zerolen(int idx) /* skip TLS stitched MTE cipher */ || EVP_CIPHER_is_a(info->ciph, "AES-128-CBC-HMAC-SHA256") /* skip TLS stitched MTE cipher */ - || EVP_CIPHER_is_a(info->ciph, "AES-256-CBC-HMAC-SHA256") - || EVP_CIPHER_is_a(info->ciph, "ChaCha20-Poly1305")) + || EVP_CIPHER_is_a(info->ciph, "AES-256-CBC-HMAC-SHA256")) return 1; for (i = 0; i < info->keylen && i < (int)sizeof(key); i++) @@ -5839,6 +6133,10 @@ static int test_evp_oneshot_aead_zerolen(int idx) errmsg = "STREAM_INIT"; goto err; } + if (!TEST_true(prepare_ccm_no_payload(ctx_stream, info))) { + errmsg = "STREAM_CCM_PREPARE"; + goto err; + } if (!TEST_true(EVP_EncryptFinal_ex(ctx_stream, ct, &finlen))) { errmsg = "STREAM_FINAL"; goto err; @@ -5872,6 +6170,10 @@ static int test_evp_oneshot_aead_zerolen(int idx) errmsg = "ONESHOT_INIT"; goto err; } + if (!TEST_true(prepare_ccm_no_payload(ctx_oneshot, info))) { + errmsg = "ONESHOT_CCM_PREPARE"; + goto err; + } oneshot_flen = EVP_Cipher(ctx_oneshot, ct, NULL, 0); if (!TEST_int_ge(oneshot_flen, 0)) { errmsg = "ONESHOT_FINAL_NULL"; @@ -5905,6 +6207,10 @@ static int test_evp_oneshot_aead_zerolen(int idx) errmsg = "DEC_SET_TAG"; goto err; } + if (!TEST_true(prepare_ccm_no_payload(ctx_dec, info))) { + errmsg = "DEC_CCM_PREPARE"; + goto err; + } dec_flen = EVP_Cipher(ctx_dec, ct, NULL, 0); if (!TEST_int_ge(dec_flen, 0)) { errmsg = "DEC_VERIFY_NULL"; @@ -5932,6 +6238,10 @@ static int test_evp_oneshot_aead_zerolen(int idx) errmsg = "DEC_BAD_SET_TAG"; goto err; } + if (!TEST_true(prepare_ccm_no_payload(ctx_dec_bad, info))) { + errmsg = "DEC_BAD_CCM_PREPARE"; + goto err; + } if (!TEST_int_lt(EVP_Cipher(ctx_dec_bad, ct, NULL, 0), 0)) { errmsg = "DEC_BADTAG_NOT_REJECTED"; goto err; @@ -5952,6 +6262,10 @@ static int test_evp_oneshot_aead_zerolen(int idx) errmsg = "DEC_STREAM_SET_TAG"; goto err; } + if (!TEST_true(prepare_ccm_no_payload(ctx_dec_s, info))) { + errmsg = "DEC_STREAM_CCM_PREPARE"; + goto err; + } if (!TEST_true(EVP_DecryptFinal_ex(ctx_dec_s, ct, &finlen))) { errmsg = "DEC_STREAM_VERIFY"; goto err; @@ -5972,6 +6286,10 @@ static int test_evp_oneshot_aead_zerolen(int idx) errmsg = "DEC_STREAM_BAD_SET_TAG"; goto err; } + if (!TEST_true(prepare_ccm_no_payload(ctx_dec_s_bad, info))) { + errmsg = "DEC_STREAM_BAD_CCM_PREPARE"; + goto err; + } if (!TEST_false(EVP_DecryptFinal_ex(ctx_dec_s_bad, ct, &finlen))) { errmsg = "DEC_STREAM_BADTAG_NOT_REJECTED"; goto err; @@ -6144,7 +6462,6 @@ static int test_evp_aead_late_aad(int idx) || info->mode == EVP_CIPH_GCM_MODE /* rejects, raises 102 PROV_R_CIPHER_OPERATION_FAILED */ || info->mode == EVP_CIPH_CCM_MODE /* fails at first AAD */ || info->mode == EVP_CIPH_OCB_MODE /* accepts late AAD */ - || info->mode == EVP_CIPH_GCM_SIV_MODE /* accepts late AAD */ /* skip TLS stitched MTE cipher */ || EVP_CIPHER_is_a(info->ciph, "AES-128-CBC-HMAC-SHA1") /* skip TLS stitched MTE cipher */ @@ -6245,6 +6562,99 @@ static int test_evp_aead_late_aad(int idx) return testresult; } +/* + * A decrypt with a wrong tag must be rejected by EVP_DecryptFinal_ex(). + * Negative test for the rejection, as well as the expected error reason. + * Does ct / aad / ct + aad variants. + */ +static int test_evp_aead_tag_reject(int idx) +{ + const EVP_CIPHER_TEST_INFO *info = &cipher_list[idx]; + EVP_CIPHER_CTX *ctx_ct = NULL; + EVP_CIPHER_CTX *ctx_aad = NULL; + EVP_CIPHER_CTX *ctx_ct_aad = NULL; + EVP_CIPHER_CTX *ctx_c_ct = NULL; + unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char aad[] = "aad"; + unsigned char ct[] = "ciphertext"; + unsigned char out[sizeof(ct) + EVP_MAX_BLOCK_LENGTH]; + unsigned char tag[EVPTEST_TAG_LEN_MAX] = { 0xd0 }; + OSSL_PARAM params[2]; + int i, len = 0, testresult = 0; + + if (info->taglen == 0 /* skip non-AEAD */ + || info->mode == EVP_CIPH_CCM_MODE /* verifies at update, not final */ + /* skip TLS stitched MTE ciphers */ + || EVP_CIPHER_is_a(info->ciph, "AES-128-CBC-HMAC-SHA1") + || EVP_CIPHER_is_a(info->ciph, "AES-256-CBC-HMAC-SHA1") + || EVP_CIPHER_is_a(info->ciph, "AES-128-CBC-HMAC-SHA256") + || EVP_CIPHER_is_a(info->ciph, "AES-256-CBC-HMAC-SHA256")) + return 1; + + for (i = 0; i < info->keylen && i < (int)sizeof(key); i++) + key[i] = (unsigned char)(0x11 + i); + for (i = 0; i < info->ivlen && i < (int)sizeof(iv); i++) + iv[i] = (unsigned char)(0x22 + i); + params[0] = OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, + tag, info->taglen); + params[1] = OSSL_PARAM_construct_end(); + + /* ciphertext only */ + ERR_clear_error(); + if (!TEST_ptr(ctx_ct = EVP_CIPHER_CTX_new()) + || !TEST_true(EVP_DecryptInit_ex2(ctx_ct, info->ciph, key, iv, params)) + || !TEST_true(EVP_DecryptUpdate(ctx_ct, out, &len, ct, sizeof(ct))) + || !TEST_int_le(EVP_DecryptFinal_ex(ctx_ct, out + len, &len), 0) + || !TEST_err_r(ERR_LIB_PROV, PROV_R_BAD_DECRYPT)) { + TEST_info("test_evp_aead_tag_reject %s: ciphertext variant", info->name); + goto err; + } + + /* AAD only */ + ERR_clear_error(); + if (!TEST_ptr(ctx_aad = EVP_CIPHER_CTX_new()) + || !TEST_true(EVP_DecryptInit_ex2(ctx_aad, info->ciph, key, iv, params)) + || !TEST_true(EVP_DecryptUpdate(ctx_aad, NULL, &len, aad, sizeof(aad))) + || !TEST_int_le(EVP_DecryptFinal_ex(ctx_aad, out, &len), 0) + || !TEST_err_r(ERR_LIB_PROV, PROV_R_BAD_DECRYPT)) { + TEST_info("test_evp_aead_tag_reject %s: AAD variant", info->name); + goto err; + } + + /* ciphertext + AAD */ + ERR_clear_error(); + if (!TEST_ptr(ctx_ct_aad = EVP_CIPHER_CTX_new()) + || !TEST_true(EVP_DecryptInit_ex2(ctx_ct_aad, info->ciph, key, iv, params)) + || !TEST_true(EVP_DecryptUpdate(ctx_ct_aad, NULL, &len, aad, sizeof(aad))) + || !TEST_true(EVP_DecryptUpdate(ctx_ct_aad, out, &len, ct, sizeof(ct))) + || !TEST_int_le(EVP_DecryptFinal_ex(ctx_ct_aad, out + len, &len), 0) + || !TEST_err_r(ERR_LIB_PROV, PROV_R_BAD_DECRYPT)) { + TEST_info("test_evp_aead_tag_reject %s: ciphertext + AAD variant", info->name); + goto err; + } + + /* ciphertext only, EVP_Cipher() interface */ + ERR_clear_error(); + if (!TEST_ptr(ctx_c_ct = EVP_CIPHER_CTX_new()) + || !TEST_true(EVP_DecryptInit_ex2(ctx_c_ct, info->ciph, key, iv, params)) + || !TEST_int_ge(EVP_Cipher(ctx_c_ct, out, ct, sizeof(ct)), 0) + || !TEST_int_lt(EVP_Cipher(ctx_c_ct, out, NULL, 0), 0) + || !TEST_err_r(ERR_LIB_PROV, PROV_R_BAD_DECRYPT)) { + TEST_info("test_evp_aead_tag_reject %s: ciphertext variant (EVP_Cipher)", + info->name); + goto err; + } + + testresult = 1; +err: + EVP_CIPHER_CTX_free(ctx_ct); + EVP_CIPHER_CTX_free(ctx_aad); + EVP_CIPHER_CTX_free(ctx_ct_aad); + EVP_CIPHER_CTX_free(ctx_c_ct); + return testresult; +} + /* * Verify stale key is not being used after providing a new key in multiple steps. * This test performs a full round of encryption and then changes the @@ -6924,6 +7334,102 @@ static int test_evp_reset(int idx) return testresult; } +static const char *const aes_cbc_decrypt_ciphers[] = { + "AES-128-CBC", "AES-192-CBC", "AES-256-CBC" +}; + +/* + * Lengths (in bytes, all block-aligned) chosen so that the block count modulo + * the 16-block main loop hits every tail path in the bulk CBC decrypt routine: + * exact multiple of 16 blocks, the 1/2/3-block lookahead variants, and the + * 8-block, 4-block and 1-3 block remainder paths. + */ +static const int aes_cbc_decrypt_lengths[] = { + 256, /* 16 blocks: main loop once, no lookahead */ + 272, /* 17 blocks: lookahead rem==1, 1-block tail */ + 288, /* 18 blocks: lookahead rem==2, 2-block tail */ + 304, /* 19 blocks: lookahead rem==3, 3-block tail */ + 320, /* 20 blocks: 4-block path */ + 384, /* 24 blocks: 8-block path */ + 448, /* 28 blocks: 8-block + nested lookahead + 4-block */ + 496, /* 31 blocks: 8 + 4 + 3-block tail */ + 512 /* 32 blocks: main loop twice */ +}; + +#define AES_CBC_DECRYPT_MAXLEN 512 + +/* + * For each length, decrypt the ciphertext in a single call (the >= 256 byte + * length exercises the bulk/VAES CBC decrypt path) and again one block at a + * time (keeping every call below the bulk threshold, i.e. an independent + * reference decrypt). The bulk output must match both the original plaintext + * and the reference, for AES-128/192/256 and across all length branches. + */ +static int test_aes_cbc_decrypt(int idx) +{ + const char *ciphername = aes_cbc_decrypt_ciphers[idx]; + unsigned char key[32], iv[16], pt[AES_CBC_DECRYPT_MAXLEN]; + unsigned char ct[AES_CBC_DECRYPT_MAXLEN]; + unsigned char bulk_out[AES_CBC_DECRYPT_MAXLEN]; + unsigned char ref_out[AES_CBC_DECRYPT_MAXLEN]; + int testresult = 0, i, outl, tmpl, off; + size_t li; + EVP_CIPHER *cipher = NULL; + EVP_CIPHER_CTX *ctx = NULL; + + for (i = 0; i < (int)sizeof(key); i++) + key[i] = (unsigned char)(i + 1); + for (i = 0; i < (int)sizeof(iv); i++) + iv[i] = (unsigned char)(0xf0 ^ i); + for (i = 0; i < AES_CBC_DECRYPT_MAXLEN; i++) + pt[i] = (unsigned char)(i * 7 + 3); + + if (!TEST_ptr(cipher = EVP_CIPHER_fetch(testctx, ciphername, testpropq)) + || !TEST_ptr(ctx = EVP_CIPHER_CTX_new())) + goto err; + + for (li = 0; li < OSSL_NELEM(aes_cbc_decrypt_lengths); li++) { + int buflen = aes_cbc_decrypt_lengths[li]; + + /* Reference encrypt (block-aligned input, padding disabled). */ + if (!TEST_true(EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv)) + || !TEST_true(EVP_CIPHER_CTX_set_padding(ctx, 0)) + || !TEST_true(EVP_EncryptUpdate(ctx, ct, &outl, pt, buflen)) + || !TEST_int_eq(outl, buflen)) + goto err; + + /* One-shot decrypt: exercises the bulk path for this length. */ + if (!TEST_true(EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv)) + || !TEST_true(EVP_CIPHER_CTX_set_padding(ctx, 0)) + || !TEST_true(EVP_DecryptUpdate(ctx, bulk_out, &outl, ct, buflen)) + || !TEST_int_eq(outl, buflen)) + goto err; + + /* Reference decrypt: one block per call bypasses the bulk path. */ + if (!TEST_true(EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv)) + || !TEST_true(EVP_CIPHER_CTX_set_padding(ctx, 0))) + goto err; + for (off = 0; off < buflen; off += 16) { + if (!TEST_true(EVP_DecryptUpdate(ctx, ref_out + off, &tmpl, + ct + off, 16)) + || !TEST_int_eq(tmpl, 16)) + goto err; + } + + if (!TEST_mem_eq(bulk_out, buflen, pt, buflen) + || !TEST_mem_eq(bulk_out, buflen, ref_out, buflen)) { + TEST_info("%s failed at length %d", ciphername, buflen); + goto err; + } + } + + testresult = 1; +err: + EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_free(cipher); + return testresult; +} + typedef struct { const char *cipher; int enc; @@ -7399,6 +7905,158 @@ static int test_keylen_change(int idx) return res; } +enum cipher_param_list_type { + CIPHER_ALGORITHM_PARAMS, + CIPHER_GETTABLE_CTX_PARAMS, + CIPHER_SETTABLE_CTX_PARAMS +}; + +struct cipher_param_test_st { + const char *cipher; + const char *properties; + const char *param; + unsigned int type; + size_t size; + enum cipher_param_list_type list_type; + int optional; +}; + +static const struct cipher_param_test_st cipher_param_tests[] = { + { "AES-128-CBC", "provider=default", OSSL_CIPHER_PARAM_TLS_MAC, + OSSL_PARAM_OCTET_PTR, 0, CIPHER_GETTABLE_CTX_PARAMS, 0 }, + { "AES-128-CBC-CTS", "provider=default", OSSL_CIPHER_PARAM_CTS_MODE, + OSSL_PARAM_UTF8_STRING, 0, CIPHER_GETTABLE_CTX_PARAMS, 0 }, +#if !defined(OPENSSL_NO_MULTIBLOCK) + { "AES-128-CBC-HMAC-SHA256", "provider=default", + OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD, OSSL_PARAM_OCTET_STRING, 0, + CIPHER_SETTABLE_CTX_PARAMS, 1 }, +#endif +#ifndef OPENSSL_NO_DES + { "DES-EDE3-CBC", "provider=default", OSSL_CIPHER_PARAM_DECRYPT_ONLY, + OSSL_PARAM_INTEGER, sizeof(int), CIPHER_ALGORITHM_PARAMS, 0 }, + { "DES-EDE3-CBC", "provider=default", OSSL_CIPHER_PARAM_RANDOM_KEY, + OSSL_PARAM_OCTET_STRING, 0, CIPHER_GETTABLE_CTX_PARAMS, 0 }, +#endif +#ifndef OPENSSL_NO_RC2 + { "RC2-CBC", "provider=legacy", + OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS_OLD, OSSL_PARAM_OCTET_STRING, 0, + CIPHER_GETTABLE_CTX_PARAMS, 0 }, +#endif +#ifndef OPENSSL_NO_RC5 + { "RC5-CBC", "provider=legacy", OSSL_CIPHER_PARAM_ROUNDS, + OSSL_PARAM_UNSIGNED_INTEGER, sizeof(unsigned int), + CIPHER_GETTABLE_CTX_PARAMS, 0 }, +#endif +}; + +static int test_cipher_param_types(int idx) +{ + const struct cipher_param_test_st *t = &cipher_param_tests[idx]; + const OSSL_PARAM *params, *p; + EVP_CIPHER *cipher = NULL; + int ret = 0; + + if (strcmp(t->properties, "provider=legacy") == 0 && lgcyprov == NULL) + return TEST_skip("Test requires legacy provider to be loaded"); + + cipher = EVP_CIPHER_fetch(testctx, t->cipher, t->properties); + if (cipher == NULL && t->optional) { + ERR_clear_error(); + return TEST_skip("Optional cipher is not available"); + } + if (!TEST_ptr(cipher)) + goto end; + + switch (t->list_type) { + case CIPHER_ALGORITHM_PARAMS: + params = EVP_CIPHER_gettable_params(cipher); + break; + case CIPHER_GETTABLE_CTX_PARAMS: + params = EVP_CIPHER_gettable_ctx_params(cipher); + break; + case CIPHER_SETTABLE_CTX_PARAMS: + params = EVP_CIPHER_settable_ctx_params(cipher); + break; + default: + goto end; + } + + if (!TEST_ptr(params) + || !TEST_ptr(p = OSSL_PARAM_locate_const(params, t->param)) + || !TEST_uint_eq(p->data_type, t->type) + || !TEST_size_t_eq(p->data_size, t->size)) + goto end; + ret = 1; +end: + EVP_CIPHER_free(cipher); + return ret; +} + +#if !defined(OPENSSL_NO_MULTIBLOCK) +static int test_aes_cbc_hmac_sha_reject_multiblock_params(const OSSL_PARAM *params) +{ + static const unsigned char key[16] = { 0 }; + static const unsigned char iv[16] = { 0 }; + EVP_CIPHER *cipher = NULL; + EVP_CIPHER_CTX *ctx = NULL; + int ret = 0; + + cipher = EVP_CIPHER_fetch(testctx, "AES-128-CBC-HMAC-SHA256", + "provider=default"); + if (cipher == NULL) { + ERR_clear_error(); + return TEST_skip("AES-CBC-HMAC-SHA multiblock cipher is not available"); + } + if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new()) + || !TEST_true(EVP_EncryptInit_ex2(ctx, cipher, key, iv, NULL)) + || !TEST_false(EVP_CIPHER_CTX_set_params(ctx, params))) + goto end; + + ERR_clear_error(); + ret = 1; +end: + EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_free(cipher); + return ret; +} + +static int test_aes_cbc_hmac_sha_short_multiblock_aad(void) +{ + unsigned char aad[EVP_AEAD_TLS1_AAD_LEN - 1] = { 0 }; + unsigned int interleave = 4; + OSSL_PARAM params[] = { + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD, aad, + sizeof(aad)), + OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, + &interleave), + OSSL_PARAM_END + }; + + return test_aes_cbc_hmac_sha_reject_multiblock_params(params); +} + +static int test_aes_cbc_hmac_sha_large_multiblock_aad(void) +{ + static const unsigned int oversized_len = SSL3_RT_MAX_PLAIN_LENGTH + 1; + unsigned char aad[EVP_AEAD_TLS1_AAD_LEN] = { 0 }; + unsigned int interleave = 4; + OSSL_PARAM params[] = { + OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_AAD, aad, + sizeof(aad)), + OSSL_PARAM_uint(OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK_INTERLEAVE, + &interleave), + OSSL_PARAM_END + }; + + aad[9] = (unsigned char)(TLS1_2_VERSION >> 8); + aad[10] = (unsigned char)TLS1_2_VERSION; + aad[11] = (unsigned char)(oversized_len >> 8); + aad[12] = (unsigned char)oversized_len; + + return test_aes_cbc_hmac_sha_reject_multiblock_params(params); +} +#endif + #ifndef OPENSSL_NO_ECX static int ecxnids[] = { NID_X25519, @@ -7669,8 +8327,9 @@ static int aes_gcm_encrypt(const unsigned char *gcm_key, size_t gcm_key_s, || !TEST_size_t_eq(params[0].return_size, gcm_ivlen) || !TEST_size_t_eq(params[1].return_size, gcm_ivlen) || !TEST_size_t_eq(params[2].return_size, sizeof(outtag))) + goto err; - ret = 1; + ret = 1; err: EVP_CIPHER_free(cipher); EVP_CIPHER_CTX_free(ctx); @@ -8010,6 +8669,94 @@ static int test_aes_siv_ctx_reuse(void) return ret; } +static int test_aes_siv_ctx_dec_retval(void) +{ + unsigned char key[32] = { 7 }; + unsigned char in[6] = "input"; + unsigned char ct[6] = { 0 }; + + unsigned char tagbuf[16], out[16] = { 0 }; + int len, ret = 0; + EVP_CIPHER_CTX *enc_ctx = NULL; + EVP_CIPHER_CTX *dec_ctx = NULL; + + EVP_CIPHER *cipher = EVP_CIPHER_fetch(NULL, "AES-128-SIV", NULL); + + if (cipher == NULL) + return TEST_skip("AES-128-SIV cipher is not available"); + + enc_ctx = EVP_CIPHER_CTX_new(); + if (!TEST_ptr(enc_ctx) + || !TEST_true(EVP_EncryptInit_ex(enc_ctx, cipher, NULL, key, NULL)) + || !TEST_true(EVP_EncryptUpdate(enc_ctx, ct, &len, in, sizeof(in))) + || !TEST_true(EVP_CIPHER_CTX_ctrl(enc_ctx, EVP_CTRL_AEAD_GET_TAG, sizeof(tagbuf), tagbuf)) + || !TEST_true(EVP_EncryptFinal_ex(enc_ctx, ct + len, &len))) + goto err; + + dec_ctx = EVP_CIPHER_CTX_new(); + if (!TEST_ptr(dec_ctx) + || !TEST_true(EVP_DecryptInit_ex(dec_ctx, cipher, NULL, key, NULL)) + || !TEST_true(EVP_CIPHER_CTX_ctrl(dec_ctx, EVP_CTRL_AEAD_SET_TAG, + sizeof(tagbuf), tagbuf)) + || !TEST_true(EVP_DecryptUpdate(dec_ctx, out, &len, ct, sizeof(in))) + || !TEST_true(EVP_DecryptFinal_ex(dec_ctx, out + len, &len)) + || !TEST_true(0 == memcmp(out, in, sizeof(in)))) { + goto err; + } + + /* + * Positive usecase successful, + * provoke the error, by repeating decrypt on same context. + */ + if (!TEST_false(EVP_DecryptUpdate(dec_ctx, out, &len, ct, sizeof(ct))) + || (!TEST_false(EVP_DecryptFinal_ex(dec_ctx, out + len, &len)))) + goto err; + + ret = 1; + +err: + EVP_CIPHER_CTX_free(dec_ctx); + EVP_CIPHER_CTX_free(enc_ctx); + EVP_CIPHER_free(cipher); + return ret; +} + +static int test_aes_siv_ctx_enc_retval(void) +{ + unsigned char key[32] = { 7 }; + unsigned char in[6] = "input"; + unsigned char ct[6] = { 0 }; + + unsigned char tagbuf[16]; + int len, ret = 0; + EVP_CIPHER_CTX *enc_ctx = NULL; + + EVP_CIPHER *cipher = EVP_CIPHER_fetch(NULL, "AES-128-SIV", NULL); + + if (cipher == NULL) + return TEST_skip("AES-128-SIV cipher is not available"); + + enc_ctx = EVP_CIPHER_CTX_new(); + if (!TEST_ptr(enc_ctx) + || !TEST_true(EVP_EncryptInit_ex(enc_ctx, cipher, NULL, key, NULL)) + || !TEST_true(EVP_EncryptUpdate(enc_ctx, ct, &len, in, sizeof(in))) + || !TEST_true(EVP_CIPHER_CTX_ctrl(enc_ctx, EVP_CTRL_AEAD_GET_TAG, sizeof(tagbuf), tagbuf)) + || !TEST_true(EVP_EncryptFinal_ex(enc_ctx, ct + len, &len))) + goto err; + + /* + * Encryption is fine, provoke error by repeating encrypt on same context. */ + if (!TEST_false(EVP_EncryptUpdate(enc_ctx, ct, &len, in, sizeof(in))) + || !TEST_false(EVP_EncryptFinal_ex(enc_ctx, ct + len, &len))) + goto err; + + ret = 1; +err: + EVP_CIPHER_CTX_free(enc_ctx); + EVP_CIPHER_free(cipher); + return ret; +} + static int test_invalid_ctx_for_digest(void) { int ret; @@ -8671,6 +9418,137 @@ static int test_evp_cipher_pipeline(void) return testresult; } +/* + * RSASVE (SP 800-56B 7.2) must reject mathematically degenerate inputs: + * a public exponent e <= 1, and a ciphertext c in {0, 1, n - 1}. Outside + * the FIPS module these were previously accepted; the checks now apply to + * every build, so exercise them in the default provider. + */ + +/* + * With e <= 1 the RSA public operation is the identity (or worse), so + * encapsulation setup must reject the key with PROV_R_INVALID_KEY. idx + * selects the exponent: 0 or 1. + */ +static int test_rsasve_degenerate_exponent(int idx) +{ + EVP_PKEY *rsakey = NULL; + EVP_PKEY *pubkey = NULL; + EVP_PKEY_CTX *genctx = NULL; + EVP_PKEY_CTX *ctx = NULL; + OSSL_PARAM_BLD *bld = NULL; + OSSL_PARAM *params = NULL; + BIGNUM *n = NULL; + BIGNUM *e = NULL; + int testresult = 0; + + /* Borrow a real modulus; only the exponent is degenerate. */ + if (!TEST_ptr(rsakey = load_example_rsa_key()) + || !TEST_true(EVP_PKEY_get_bn_param(rsakey, OSSL_PKEY_PARAM_RSA_N, &n))) + goto err; + + if (!TEST_ptr(e = BN_new()) + || !TEST_true(BN_set_word(e, (BN_ULONG)idx))) /* idx is 0 or 1 */ + goto err; + + if (!TEST_ptr(bld = OSSL_PARAM_BLD_new()) + || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, n)) + || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E, e)) + || !TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld))) + goto err; + + if (!TEST_ptr(genctx = EVP_PKEY_CTX_new_from_name(testctx, "RSA", NULL)) + || !TEST_int_gt(EVP_PKEY_fromdata_init(genctx), 0) + || !TEST_int_gt(EVP_PKEY_fromdata(genctx, &pubkey, EVP_PKEY_PUBLIC_KEY, + params), + 0)) + goto err; + + ERR_clear_error(); + if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(testctx, pubkey, NULL)) + || !TEST_int_eq(EVP_PKEY_encapsulate_init(ctx, NULL), 0) + || !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), PROV_R_INVALID_KEY)) + goto err; + + testresult = 1; +err: + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_CTX_free(genctx); + EVP_PKEY_free(pubkey); + EVP_PKEY_free(rsakey); + OSSL_PARAM_free(params); + OSSL_PARAM_BLD_free(bld); + BN_free(e); + BN_free(n); + return testresult; +} + +/* + * A ciphertext c in {0, 1, n - 1} is a fixed point or trivial case of RSADP, + * so RSASVE recovery must reject it. idx selects the ciphertext: 0, 1, or + * n - 1. The ciphertext length must equal the modulus length. + */ +static int test_rsasve_degenerate_ciphertext(int idx) +{ + EVP_PKEY *rsakey = NULL; + EVP_PKEY_CTX *ctx = NULL; + BIGNUM *n = NULL; + unsigned char *ct = NULL; + unsigned char *secret = NULL; + size_t ctlen = 0; + size_t secretlen = 0; + int expected_reason = 0; + int testresult = 0; + + if (!TEST_ptr(rsakey = load_example_rsa_key()) + || !TEST_true(EVP_PKEY_get_bn_param(rsakey, OSSL_PKEY_PARAM_RSA_N, &n))) + goto err; + + ctlen = secretlen = (size_t)EVP_PKEY_get_size(rsakey); + if (!TEST_size_t_gt(ctlen, 0)) + goto err; + if (!TEST_ptr(ct = OPENSSL_zalloc(ctlen)) + || !TEST_ptr(secret = OPENSSL_malloc(secretlen))) + goto err; + + switch (idx) { + case 0: /* c = 0 */ + expected_reason = RSA_R_DATA_TOO_SMALL; + break; + case 1: /* c = 1 */ + ct[ctlen - 1] = 1; + expected_reason = RSA_R_DATA_TOO_SMALL; + break; + case 2: /* c = n - 1 */ + if (!TEST_true(BN_sub_word(n, 1)) + || !TEST_int_eq(BN_bn2binpad(n, ct, (int)ctlen), (int)ctlen)) + goto err; + expected_reason = RSA_R_DATA_TOO_LARGE_FOR_MODULUS; + break; + default: + goto err; + } + + if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(testctx, rsakey, NULL)) + || !TEST_int_eq(EVP_PKEY_decapsulate_init(ctx, NULL), 1) + || !TEST_int_eq(EVP_PKEY_CTX_set_kem_op(ctx, "RSASVE"), 1)) + goto err; + + ERR_clear_error(); + if (!TEST_int_eq(EVP_PKEY_decapsulate(ctx, secret, &secretlen, ct, ctlen), 0) + || !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), expected_reason)) + goto err; + + testresult = 1; +err: + OPENSSL_free(secret); + OPENSSL_free(ct); + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(rsakey); + BN_free(n); + return testresult; +} + #ifndef OPENSSL_NO_DEPRECATED_3_0 static int sign_hits = 0; @@ -8895,8 +9773,10 @@ static int test_low_level_dsa_method(void) DSA *dsa = NULL; const DSA_METHOD *def = DSA_get_default_method(); DSA_METHOD *method = DSA_meth_dup(def); + DSA_SIG *dsa_sig = NULL; EVP_PKEY *pkey = NULL; int testresult = 0; + unsigned char dgst[32]; if (nullprov != NULL) { testresult = TEST_skip("Test does not support a non-default library context"); @@ -8916,6 +9796,12 @@ static int test_low_level_dsa_method(void) if (!TEST_true(DSA_generate_key(dsa))) goto err; + /* Warm the Montgomery cache so the finish slot touches it (Issue: 32541) */ + memset(dgst, 0, sizeof(dgst)); + if (!TEST_ptr(dsa_sig = DSA_do_sign(dgst, sizeof(dgst), dsa))) + goto err; + DSA_SIG_free(dsa_sig); + orig_dsa_sign = DSA_meth_get_sign(def); if (!TEST_true(DSA_meth_set_sign(method, tst_dsa_sign))) goto err; @@ -9067,12 +9953,7 @@ static int test_low_level_dh_method(void) if (!TEST_true(DH_set_ex_data(dh, dh_ex_idx, (void *)"test"))) goto err; - orig_dh_compute_key = DH_meth_get_compute_key(def); - if (!TEST_true(DH_meth_set_compute_key(method, tst_dh_compute_key))) - goto err; - if (!TEST_true(DH_set_method(dh, method))) - goto err; - + /* Prepare the API for warming the cache */ p = BN_dup(DH_get0_p(cdh)); g = BN_dup(DH_get0_g(cdh)); if (!TEST_ptr(p) || !TEST_ptr(g)) @@ -9084,6 +9965,21 @@ static int test_low_level_dh_method(void) if (!TEST_true(DH_generate_key(dh))) goto err; + /* Warm the Montgomery cache before the switch (Issue: #32541) */ + buf = OPENSSL_malloc(DH_size(dh)); + if (!TEST_ptr(buf)) + goto err; + if (!TEST_int_gt(DH_compute_key(buf, DH_get0_pub_key(dh), dh), 0)) + goto err; + OPENSSL_free(buf); + buf = NULL; + + orig_dh_compute_key = DH_meth_get_compute_key(def); + if (!TEST_true(DH_meth_set_compute_key(method, tst_dh_compute_key))) + goto err; + if (!TEST_true(DH_set_method(dh, method))) + goto err; + ctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL); if (!TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0)) goto err; @@ -9135,6 +10031,146 @@ static int test_low_level_dh_method(void) #endif /* OPENSSL_NO_DH */ #endif /* OPENSSL_NO_DEPRECATED_3_0 */ +/*- + * AES-CTR cases for the VAES/AVX-512 path: sizes spanning the 64-byte + * dispatch threshold, the 16/8/4-block tiers, odd tails, and the 2^64 + * counter carry. Each result is checked against an independent ECB-based + * CTR reference and a decrypt round-trip. + */ +static const struct { + int bits; + size_t len; + int ctr_carry; /* start the low 64 bits of the counter near overflow */ +} ctr_vaes_cases[] = { + { 128, 64, 0 }, + { 128, 65, 0 }, + { 128, 127, 0 }, + { 128, 128, 0 }, + { 128, 256, 0 }, + { 128, 512, 0 }, + { 128, 1024, 0 }, + { 128, 5000, 0 }, + { 192, 64, 0 }, + { 192, 240, 0 }, + { 192, 1024, 0 }, + { 192, 4096, 0 }, + { 256, 64, 0 }, + { 256, 129, 0 }, + { 256, 1024, 0 }, + { 256, 4096, 0 }, + { 128, 2048, 1 }, + { 192, 2048, 1 }, + { 256, 2048, 1 }, +}; + +static int ctr_reference(int bits, const unsigned char *key, + const unsigned char *iv, const unsigned char *in, + unsigned char *out, size_t len) +{ + static const char *ecbname[] = { + "AES-128-ECB", "AES-192-ECB", "AES-256-ECB" + }; + const char *name = ecbname[(bits - 128) / 64]; + EVP_CIPHER *ecb = NULL; + EVP_CIPHER_CTX *ctx = NULL; + unsigned char ctr[16], ks[16]; + size_t off = 0; + int outl, i, ok = 0; + + if (!TEST_ptr(ecb = EVP_CIPHER_fetch(testctx, name, NULL)) + || !TEST_ptr(ctx = EVP_CIPHER_CTX_new()) + || !TEST_true(EVP_EncryptInit_ex2(ctx, ecb, key, NULL, NULL)) + || !TEST_true(EVP_CIPHER_CTX_set_padding(ctx, 0))) + goto err; + + memcpy(ctr, iv, sizeof(ctr)); + while (off < len) { + size_t n = len - off < 16 ? len - off : 16; + + if (!TEST_true(EVP_EncryptUpdate(ctx, ks, &outl, ctr, 16)) + || !TEST_int_eq(outl, 16)) + goto err; + for (i = 0; i < (int)n; i++) + out[off + i] = in[off + i] ^ ks[i]; + off += n; + /* Increment the 128-bit counter as a big-endian integer. */ + for (i = 15; i >= 0; i--) + if (++ctr[i] != 0) + break; + } + ok = 1; +err: + EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_free(ecb); + return ok; +} + +static int test_aes_ctr_vaes(int idx) +{ + static const char *ctrname[] = { + "AES-128-CTR", "AES-192-CTR", "AES-256-CTR" + }; + int bits = ctr_vaes_cases[idx].bits; + size_t len = ctr_vaes_cases[idx].len; + const char *name = ctrname[(bits - 128) / 64]; + EVP_CIPHER *ctr = NULL; + EVP_CIPHER_CTX *ctx = NULL; + unsigned char key[32], iv[16]; + unsigned char *pt = NULL, *ref = NULL, *ct = NULL, *rt = NULL; + int outl, tmpl, ret = 0; + + if (!TEST_ptr(pt = OPENSSL_malloc(len)) + || !TEST_ptr(ref = OPENSSL_malloc(len)) + || !TEST_ptr(ct = OPENSSL_malloc(len)) + || !TEST_ptr(rt = OPENSSL_malloc(len))) + goto err; + + if (!TEST_int_gt(RAND_bytes_ex(testctx, key, bits / 8, 0), 0) + || !TEST_int_gt(RAND_bytes_ex(testctx, iv, sizeof(iv), 0), 0) + || !TEST_int_gt(RAND_bytes_ex(testctx, pt, len, 0), 0)) + goto err; + + if (ctr_vaes_cases[idx].ctr_carry) { + /* Low 64 bits (bytes 8..15, big-endian) just below overflow. */ + memset(iv + 8, 0xff, 8); + iv[15] = 0xf0; + } + + if (!TEST_ptr(ctr = EVP_CIPHER_fetch(testctx, name, NULL)) + || !TEST_ptr(ctx = EVP_CIPHER_CTX_new())) + goto err; + + /* Independent reference (single-block ECB keystream). */ + if (!ctr_reference(bits, key, iv, pt, ref, len)) + goto err; + + /* Encrypt: payloads >= 64 bytes select the VAES path on capable CPUs. */ + if (!TEST_true(EVP_EncryptInit_ex2(ctx, ctr, key, iv, NULL)) + || !TEST_true(EVP_EncryptUpdate(ctx, ct, &outl, pt, (int)len)) + || !TEST_true(EVP_EncryptFinal_ex(ctx, ct + outl, &tmpl)) + || !TEST_int_eq(outl + tmpl, (int)len) + || !TEST_mem_eq(ct, len, ref, len)) + goto err; + + /* Decrypt round-trip. */ + if (!TEST_true(EVP_DecryptInit_ex2(ctx, ctr, key, iv, NULL)) + || !TEST_true(EVP_DecryptUpdate(ctx, rt, &outl, ct, (int)len)) + || !TEST_true(EVP_DecryptFinal_ex(ctx, rt + outl, &tmpl)) + || !TEST_int_eq(outl + tmpl, (int)len) + || !TEST_mem_eq(rt, len, pt, len)) + goto err; + + ret = 1; +err: + EVP_CIPHER_CTX_free(ctx); + EVP_CIPHER_free(ctr); + OPENSSL_free(pt); + OPENSSL_free(ref); + OPENSSL_free(ct); + OPENSSL_free(rt); + return ret; +} + int setup_tests(void) { char *config_file = NULL; @@ -9228,9 +10264,13 @@ int setup_tests(void) #ifndef OPENSSL_NO_EC ADD_TEST(test_X509_PUBKEY_inplace); ADD_TEST(test_X509_PUBKEY_dup); + ADD_TEST(test_ec_fromdata_selection_params); ADD_ALL_TESTS(test_invalid_ec_char2_pub_range_decode, OSSL_NELEM(ec_der_pub_keys)); #endif +#ifndef OPENSSL_NO_SM2 + ADD_TEST(test_sm2_common_set_params); +#endif #ifndef OPENSSL_NO_DSA ADD_TEST(test_DSA_get_set_params); ADD_TEST(test_DSA_priv_pub); @@ -9239,7 +10279,10 @@ int setup_tests(void) ADD_TEST(test_RSA_OAEP_set_get_params); ADD_TEST(test_RSA_OAEP_set_null_label); ADD_TEST(test_RSA_verify_recover_rejects_short_buffer); + ADD_TEST(test_RSA_verify_recover_empty_payload); ADD_TEST(test_RSA_encrypt); + ADD_TEST(test_EVP_rsa_pss_utf8_ptr_params); + ADD_TEST(test_rsa_algorithm_param_lists); #ifndef OPENSSL_NO_DEPRECATED_3_0 ADD_TEST(test_RSA_legacy); #endif @@ -9289,9 +10332,11 @@ int setup_tests(void) ADD_ALL_TESTS(test_evp_oneshot_aead_zerolen, cipher_list_n); ADD_ALL_TESTS(test_evp_aead_tag_direction, cipher_list_n); ADD_ALL_TESTS(test_evp_aead_late_aad, cipher_list_n); + ADD_ALL_TESTS(test_evp_aead_tag_reject, cipher_list_n); ADD_ALL_TESTS(test_evp_init_seq, OSSL_NELEM(evp_init_tests)); ADD_ALL_TESTS(test_evp_reset, OSSL_NELEM(evp_reset_tests)); + ADD_ALL_TESTS(test_aes_cbc_decrypt, OSSL_NELEM(aes_cbc_decrypt_ciphers)); ADD_ALL_TESTS(test_evp_reinit_seq, OSSL_NELEM(evp_reinit_tests)); ADD_ALL_TESTS(test_gcm_reinit, OSSL_NELEM(gcm_reinit_tests)); ADD_ALL_TESTS(test_evp_updated_iv, OSSL_NELEM(evp_updated_iv_tests)); @@ -9301,6 +10346,11 @@ int setup_tests(void) ADD_ALL_TESTS(test_iv_reuse, OSSL_NELEM(iv_state_ciphers)); if (OSSL_NELEM(keylen_change_ciphers) - 1 > 0) ADD_ALL_TESTS(test_keylen_change, OSSL_NELEM(keylen_change_ciphers) - 1); + ADD_ALL_TESTS(test_cipher_param_types, OSSL_NELEM(cipher_param_tests)); +#if !defined(OPENSSL_NO_MULTIBLOCK) + ADD_TEST(test_aes_cbc_hmac_sha_short_multiblock_aad); + ADD_TEST(test_aes_cbc_hmac_sha_large_multiblock_aad); +#endif #ifndef OPENSSL_NO_ECX ADD_ALL_TESTS(test_ecx_short_keys, OSSL_NELEM(ecxnids)); @@ -9320,6 +10370,8 @@ int setup_tests(void) /* Test cases for CVE-2026-45446 */ ADD_TEST(test_aes_gcm_siv_empty_data); ADD_TEST(test_aes_siv_ctx_reuse); + ADD_TEST(test_aes_siv_ctx_dec_retval); + ADD_TEST(test_aes_siv_ctx_enc_retval); ADD_TEST(test_invalid_ctx_for_digest); @@ -9328,6 +10380,10 @@ int setup_tests(void) ADD_TEST(test_evp_cipher_pipeline); + ADD_ALL_TESTS(test_rsasve_degenerate_exponent, 2); + ADD_ALL_TESTS(test_rsasve_degenerate_ciphertext, 3); + ADD_ALL_TESTS(test_aes_ctr_vaes, OSSL_NELEM(ctr_vaes_cases)); + #ifndef OPENSSL_NO_ML_KEM ADD_ALL_TESTS(test_ml_kem_seed_only, 2); #endif diff --git a/test/evp_extra_test2.c b/test/evp_extra_test2.c index c9b64bbf26e83..54d82caf6856c 100644 --- a/test/evp_extra_test2.c +++ b/test/evp_extra_test2.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -178,6 +178,115 @@ static const unsigned char kExampleRSAKeyPKCS8[] = { 0x20, 0x1b, 0xe5, 0xdf }; +/* + * An RSA-PSS 2048-bit private key in ASN.1 DER form. Used by the + * table-driven checks instead of keygen to save CI cycles (RSA keygen + * at this size is slow). Generated with: + * > openssl genpkey -quiet -algorithm rsa-pss -outform DER > rsa-pss.der + * > xxd -i < rsa-pss.der + * Of course, never use this key for anything but tests. + */ +static const unsigned char kExampleRSAPSSKeyDER[] = { + 0x30, 0x82, 0x04, 0xba, 0x02, 0x01, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x0a, 0x04, 0x82, 0x04, 0xa6, 0x30, 0x82, 0x04, 0xa2, 0x02, 0x01, + 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa3, 0x32, 0x24, 0xdb, 0x9b, 0xec, 0x8f, 0x18, 0xbe, + 0xeb, 0xef, 0x9b, 0x0e, 0x06, 0x11, 0x78, 0x26, 0x66, 0x2b, 0x75, 0xff, 0x79, 0x50, 0xa9, + 0x96, 0xb2, 0xdf, 0xe1, 0x71, 0x2f, 0x8f, 0x3f, 0x08, 0x16, 0x3f, 0x53, 0x5a, 0x2c, 0x7c, + 0xbb, 0xb9, 0xa2, 0x54, 0x2c, 0x81, 0xaf, 0x58, 0xd1, 0xb4, 0xfe, 0xd6, 0x2a, 0x5c, 0x47, + 0xfe, 0x20, 0xf0, 0xce, 0xdc, 0xfe, 0x08, 0x7f, 0x3a, 0x24, 0xcd, 0xa0, 0x87, 0xcb, 0x0e, + 0xd7, 0xcf, 0xee, 0x26, 0x12, 0x1f, 0xdb, 0x8b, 0x0f, 0x12, 0x32, 0x05, 0x73, 0x8f, 0x60, + 0xfa, 0x75, 0x49, 0xb5, 0x50, 0x2d, 0x45, 0x72, 0x8b, 0x1d, 0x7f, 0xd3, 0x47, 0x2c, 0x5b, + 0x0e, 0x24, 0x28, 0xe2, 0xc6, 0x01, 0x74, 0x10, 0xbe, 0xe4, 0xc7, 0xd2, 0xe5, 0xf4, 0x90, + 0x10, 0xc0, 0x28, 0x66, 0xed, 0xc4, 0x84, 0xac, 0xb2, 0x01, 0x8e, 0x8a, 0xd1, 0x86, 0x82, + 0x77, 0x89, 0xd8, 0x64, 0xaa, 0xca, 0x1d, 0x27, 0x3e, 0xfd, 0x78, 0x4e, 0xd7, 0x8d, 0xc5, + 0x25, 0xab, 0xb1, 0xfb, 0x94, 0x86, 0xa1, 0x3d, 0xc4, 0x8d, 0x62, 0x5e, 0x59, 0x13, 0x25, + 0xb7, 0x77, 0x20, 0x7e, 0x0a, 0xf8, 0xd0, 0x4f, 0xf4, 0x9c, 0x6f, 0x19, 0x67, 0xe7, 0x6f, + 0x62, 0xd9, 0xc9, 0xe5, 0x97, 0x90, 0xaa, 0xd5, 0x94, 0x98, 0x61, 0xb7, 0xf9, 0xfc, 0x86, + 0x45, 0xd8, 0x6f, 0x37, 0x35, 0x51, 0x0d, 0x9f, 0xb0, 0x9f, 0xd5, 0x1b, 0x10, 0x87, 0xa2, + 0xb9, 0xe0, 0x5e, 0xc9, 0x6b, 0x1b, 0x5d, 0xf3, 0x3a, 0x16, 0x4a, 0x79, 0x25, 0xcf, 0x95, + 0xfc, 0xca, 0x8a, 0x7a, 0xac, 0x49, 0xd9, 0x36, 0xa5, 0x45, 0xc4, 0x9a, 0x01, 0x60, 0xed, + 0x8b, 0xcf, 0x66, 0xf2, 0xfb, 0x98, 0x93, 0x69, 0x84, 0xf2, 0xa8, 0x02, 0x12, 0x4d, 0x7b, + 0x48, 0xa1, 0xfb, 0x4d, 0x59, 0x96, 0x57, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, + 0x00, 0x0f, 0x43, 0x65, 0xda, 0x1a, 0x53, 0xbe, 0x30, 0x78, 0xce, 0xd5, 0x4a, 0xa1, 0xbd, + 0xa4, 0x8d, 0xa1, 0xbd, 0xc5, 0x8b, 0xd4, 0x38, 0x92, 0xf8, 0x41, 0x8d, 0x7a, 0x4d, 0xfa, + 0x09, 0x92, 0x32, 0xb9, 0x7d, 0x67, 0x2f, 0xd3, 0x0b, 0xbd, 0x20, 0xcb, 0xa4, 0x68, 0x8d, + 0xff, 0x15, 0x18, 0xd0, 0x08, 0x47, 0x1b, 0x5d, 0xbb, 0xe2, 0xc9, 0xdc, 0x67, 0xd9, 0x59, + 0x26, 0xf3, 0x41, 0x7e, 0xfd, 0x29, 0x34, 0x3d, 0xef, 0x1a, 0x74, 0xc9, 0xd0, 0x42, 0xc4, + 0x48, 0x31, 0x7e, 0xe8, 0x8a, 0x71, 0x9e, 0x3b, 0xe8, 0x29, 0x90, 0x53, 0x3e, 0xf1, 0x13, + 0xce, 0x20, 0x24, 0x2d, 0xe9, 0xb4, 0xe6, 0x5c, 0x4e, 0x44, 0x37, 0xe6, 0xde, 0xe2, 0x12, + 0xd5, 0xd8, 0xf6, 0xa5, 0xfb, 0xfc, 0xca, 0x77, 0x52, 0x6f, 0xd4, 0xf9, 0x3b, 0xee, 0x20, + 0x87, 0xd4, 0x46, 0xd8, 0xa1, 0x37, 0xa5, 0x39, 0x22, 0x5e, 0xb6, 0x2c, 0xe8, 0x49, 0xf4, + 0x78, 0x07, 0x23, 0xba, 0x19, 0x6e, 0x25, 0xb6, 0x7b, 0x2b, 0x9d, 0x7e, 0x19, 0x26, 0x95, + 0xe7, 0x20, 0xb8, 0x21, 0xd1, 0xf5, 0xb9, 0x6d, 0xa6, 0x2a, 0xcb, 0x46, 0xe4, 0x62, 0x71, + 0x63, 0xe1, 0xa0, 0x77, 0x1d, 0xf7, 0x10, 0xf6, 0x1e, 0x70, 0x27, 0x72, 0xf8, 0x68, 0x19, + 0x6d, 0x84, 0xa1, 0x46, 0xcd, 0x52, 0x0f, 0x86, 0x77, 0x7a, 0x92, 0x5c, 0xc6, 0x39, 0xc2, + 0x67, 0x12, 0xb0, 0x68, 0x6c, 0xe0, 0x19, 0xde, 0x61, 0xeb, 0x39, 0x1f, 0x14, 0xd0, 0xc7, + 0xd6, 0x77, 0xc2, 0x83, 0x9e, 0xe2, 0xa3, 0x3a, 0x22, 0x02, 0x45, 0xf1, 0x10, 0x86, 0x77, + 0x4a, 0x95, 0xf3, 0x75, 0x90, 0x22, 0x9b, 0xb2, 0xcd, 0xcd, 0x2f, 0x27, 0xff, 0xe7, 0xac, + 0x9c, 0xdb, 0x85, 0x31, 0xeb, 0x2b, 0xfa, 0x8f, 0x9e, 0xbe, 0x92, 0x1a, 0xcd, 0xd3, 0x98, + 0x1a, 0x75, 0x02, 0x81, 0x81, 0x00, 0xd5, 0x06, 0xa1, 0x08, 0x41, 0x02, 0xab, 0x3a, 0x00, + 0xf5, 0x74, 0x5f, 0xb7, 0xf0, 0xa7, 0x9d, 0x0a, 0x26, 0x32, 0x7e, 0x48, 0xa4, 0xf7, 0xbe, + 0xcf, 0xba, 0x27, 0x2a, 0x7d, 0x60, 0xd2, 0x16, 0x59, 0xc3, 0xf0, 0x78, 0x33, 0x3a, 0x36, + 0x86, 0xb5, 0xd4, 0x29, 0x25, 0x23, 0x5a, 0xeb, 0x5a, 0x96, 0x82, 0xfc, 0x08, 0x08, 0x1c, + 0xcc, 0xed, 0xb3, 0xf1, 0x27, 0xca, 0x1c, 0xa8, 0xe8, 0x36, 0x77, 0xa4, 0x57, 0x9a, 0x1d, + 0xde, 0x2b, 0x3b, 0xc3, 0x41, 0x7c, 0x58, 0x33, 0x11, 0x3b, 0xee, 0x7a, 0xc9, 0xe9, 0x4b, + 0xa2, 0x3b, 0xc3, 0x68, 0x19, 0x6a, 0x00, 0x7c, 0x59, 0x90, 0x77, 0x11, 0xed, 0x47, 0x4a, + 0x5a, 0xfe, 0x3a, 0x29, 0x3a, 0xad, 0x80, 0xe9, 0xff, 0xce, 0x07, 0x3f, 0x80, 0x5f, 0x98, + 0x14, 0x1a, 0xf0, 0x9c, 0xc7, 0x8d, 0x42, 0x06, 0xc4, 0xf8, 0x89, 0xe3, 0xe0, 0x23, 0x02, + 0x81, 0x81, 0x00, 0xc4, 0x1e, 0x20, 0x31, 0xfa, 0xe7, 0x6a, 0xa5, 0x18, 0xbe, 0xce, 0x45, + 0x15, 0x97, 0x67, 0x5f, 0xd0, 0xc6, 0x0f, 0xa2, 0x6c, 0x68, 0x5e, 0xe9, 0xca, 0x48, 0x8c, + 0x46, 0x08, 0x06, 0xc1, 0xe9, 0xac, 0x8c, 0x01, 0x55, 0xc7, 0xf2, 0x02, 0x98, 0x2b, 0x8d, + 0x4e, 0x24, 0x2d, 0x56, 0x7b, 0x40, 0x24, 0x28, 0xaa, 0x4a, 0xf7, 0x83, 0x88, 0x38, 0xa5, + 0x03, 0x2b, 0xb3, 0x1c, 0x4a, 0x95, 0x70, 0xf6, 0x80, 0xcc, 0x21, 0xd0, 0xab, 0x8a, 0x10, + 0xb2, 0xa6, 0x1a, 0x27, 0xb6, 0xae, 0x24, 0xed, 0xa9, 0xfe, 0xfc, 0x74, 0x7f, 0x97, 0x9b, + 0xe1, 0xc2, 0x46, 0x48, 0xed, 0x5f, 0x2f, 0x9e, 0x54, 0x77, 0x1f, 0x61, 0x46, 0x24, 0x08, + 0x7e, 0xb5, 0x63, 0xa1, 0xe2, 0x6f, 0x58, 0xc8, 0x76, 0x98, 0x8a, 0x9a, 0xa5, 0xb9, 0x15, + 0xfb, 0xf4, 0xb8, 0xfd, 0x84, 0xb6, 0xbc, 0x5f, 0x59, 0xfa, 0x3d, 0x02, 0x81, 0x80, 0x2a, + 0x97, 0x43, 0xb4, 0xf1, 0xc2, 0x85, 0xd7, 0x77, 0xff, 0x9b, 0x3f, 0xd3, 0xf7, 0xe2, 0x9b, + 0x2c, 0x3f, 0x4c, 0xd3, 0x20, 0xd5, 0x12, 0xcf, 0x6c, 0x9a, 0xcc, 0x5f, 0xdb, 0x67, 0x73, + 0x39, 0x92, 0xc2, 0xf1, 0x1e, 0x27, 0x27, 0xd9, 0x64, 0xff, 0x8f, 0xa6, 0x96, 0x4d, 0x46, + 0x4d, 0x4d, 0xf4, 0x4f, 0xc5, 0xf2, 0x19, 0x25, 0x20, 0xf7, 0xd9, 0x85, 0x3a, 0xae, 0x57, + 0x22, 0x92, 0x22, 0xe9, 0xb2, 0xca, 0xec, 0xfe, 0x51, 0xc0, 0x15, 0x17, 0xc9, 0xcd, 0x01, + 0x99, 0x5c, 0x35, 0xbe, 0x4d, 0x80, 0x77, 0x0b, 0x6f, 0x29, 0x41, 0xbd, 0x5b, 0x6f, 0x6d, + 0x1f, 0x6f, 0x8c, 0xc9, 0xb1, 0xa4, 0xde, 0x1f, 0x08, 0xa8, 0x51, 0x9a, 0x92, 0xa7, 0xc3, + 0xe1, 0x85, 0x0a, 0x7d, 0x3a, 0x7e, 0x01, 0x1e, 0xd7, 0xce, 0x37, 0x13, 0x31, 0x76, 0x95, + 0x9f, 0xe2, 0xdb, 0xca, 0x3d, 0xec, 0x3f, 0x02, 0x81, 0x80, 0x73, 0x99, 0x66, 0x54, 0xcf, + 0x96, 0x34, 0xd0, 0x58, 0x03, 0xb0, 0x46, 0x1c, 0x72, 0x00, 0x27, 0x04, 0x42, 0x9a, 0xd8, + 0x9c, 0x99, 0xf0, 0xc8, 0x51, 0xc9, 0xed, 0x95, 0x22, 0x0a, 0x09, 0xa7, 0x19, 0x63, 0xf5, + 0x2d, 0x81, 0x0b, 0xef, 0xe7, 0x8e, 0x54, 0x5e, 0x69, 0x08, 0xa8, 0x5f, 0x41, 0xf1, 0x8e, + 0x5e, 0xc2, 0x8d, 0x9e, 0xe4, 0x5e, 0xaf, 0x35, 0x6d, 0x3e, 0xc8, 0x40, 0x56, 0x52, 0x1d, + 0x9a, 0xd1, 0xb8, 0x64, 0xed, 0x98, 0x16, 0x3b, 0x97, 0x98, 0xf7, 0x2b, 0xc0, 0xfe, 0x57, + 0x70, 0xca, 0xb2, 0x38, 0x61, 0x35, 0x16, 0x57, 0x3e, 0x52, 0x7b, 0x8e, 0x1f, 0x7b, 0x4c, + 0x12, 0x71, 0x9c, 0xf7, 0x93, 0x86, 0x8d, 0xd3, 0x52, 0x4c, 0x06, 0x12, 0x18, 0x9b, 0xf6, + 0x9d, 0xa1, 0x50, 0xa1, 0xd3, 0x69, 0x83, 0xc1, 0xde, 0x00, 0x64, 0xbf, 0x23, 0x8f, 0x69, + 0x8c, 0xf9, 0xe9, 0x02, 0x81, 0x80, 0x02, 0xce, 0x66, 0x6b, 0x32, 0x73, 0x62, 0x60, 0x27, + 0x3e, 0x38, 0x1d, 0xd8, 0x70, 0xdb, 0x4e, 0x32, 0xf7, 0x7a, 0x7b, 0x22, 0x7b, 0x9b, 0xd7, + 0x49, 0x4f, 0x5b, 0x9b, 0xaa, 0x2c, 0x5b, 0x99, 0x22, 0x1e, 0x6e, 0x7e, 0x19, 0x8a, 0xf1, + 0x97, 0xfe, 0x3f, 0xcd, 0x9e, 0xa4, 0x46, 0xf0, 0x9a, 0x62, 0x0f, 0x1a, 0xcd, 0x77, 0xe1, + 0x88, 0xe1, 0x9a, 0x22, 0x84, 0x1b, 0xbf, 0xf0, 0x71, 0xf4, 0x64, 0xfd, 0xd5, 0xaa, 0xb4, + 0x28, 0xdc, 0xef, 0xd9, 0xec, 0x29, 0x11, 0xc4, 0x58, 0x0f, 0xeb, 0x3c, 0x41, 0x66, 0x4a, + 0x98, 0x18, 0x26, 0xfe, 0x3e, 0x7e, 0xc3, 0x36, 0xfa, 0xbc, 0x64, 0x69, 0x1f, 0xce, 0x1c, + 0xc1, 0xb5, 0xe9, 0xa8, 0x78, 0xf7, 0x6d, 0xb6, 0x0c, 0x58, 0x29, 0xe2, 0xbf, 0xd0, 0xbe, + 0x2e, 0x10, 0xfa, 0x74, 0x02, 0x9b, 0x48, 0xa5, 0xc9, 0x74, 0xed, 0xed, 0x7d, 0xa8 +}; + +#ifndef OPENSSL_NO_DH +static char group_ffdhe2048[] = "ffdhe2048"; +static const OSSL_PARAM dhx_keygen_params[] = { + OSSL_PARAM_utf8_string("group", group_ffdhe2048, + sizeof(group_ffdhe2048) - 1), + OSSL_PARAM_END +}; +#endif + +#ifndef OPENSSL_NO_EC +static char group_p256[] = "P-256"; +static const OSSL_PARAM ec_keygen_params[] = { + OSSL_PARAM_utf8_string("group", group_p256, sizeof(group_p256) - 1), + OSSL_PARAM_END +}; +#endif + #ifndef OPENSSL_NO_DH static const unsigned char kExampleDHPrivateKeyDER[] = { 0x30, 0x82, 0x02, 0x26, 0x02, 0x01, 0x00, 0x30, 0x82, 0x01, 0x17, 0x06, @@ -296,49 +405,73 @@ static APK_DATA keydata[] = { static int pkey_has_private(EVP_PKEY *key, const char *privtag, int use_octstring) { - int ret = 0; - if (use_octstring) { - unsigned char buf[64]; - - ret = EVP_PKEY_get_octet_string_param(key, privtag, buf, sizeof(buf), - NULL); + /* + * Existence probe only: pass NULL buffer, ignore the returned size. + * Avoids hard-coded fixed buffers that would cap at 64 bytes and + * fail for PQC private keys (ML-DSA-44 is ~2.5 KB). + */ + return EVP_PKEY_get_octet_string_param(key, privtag, NULL, 0, NULL); } else { BIGNUM *bn = NULL; + int ret = EVP_PKEY_get_bn_param(key, privtag, &bn); - ret = EVP_PKEY_get_bn_param(key, privtag, &bn); BN_free(bn); + return ret; } - return ret; } +/* + * Private-component tags we know about, in lookup order. Extend this + * list if a new algorithm adopts a different convention; do_pkey_tofrom + * _data_select() scans it on each key and only needs one match. + */ +static const char *const pkey_priv_tags[] = { + OSSL_PKEY_PARAM_PRIV_KEY, /* DH, DSA, EC, ECX, SM2, ML-*, SLH-DSA */ + OSSL_PKEY_PARAM_RSA_D, /* RSA, RSA-PSS */ +}; + static int do_pkey_tofrom_data_select(EVP_PKEY *key, const char *keytype) { int ret = 0; OSSL_PARAM *pub_params = NULL, *keypair_params = NULL; + const OSSL_PARAM *priv = NULL; EVP_PKEY *fromkey = NULL, *fromkeypair = NULL; EVP_PKEY_CTX *fromctx = NULL; - const char *privtag = strcmp(keytype, "RSA") == 0 ? "d" : "priv"; - const int use_octstring = strcmp(keytype, "X25519") == 0; + const char *privtag; + int use_octstring; + size_t t; /* - * Select only the public key component when using EVP_PKEY_todata() and - * check that the resulting param array does not contain a private key. + * Export the full keypair first so we can discover the algorithm's + * private-component tag from the emitted params rather than hand-coding + * it per keytype. */ - if (!TEST_int_eq(EVP_PKEY_todata(key, EVP_PKEY_PUBLIC_KEY, &pub_params), 1) - || !TEST_ptr_null(OSSL_PARAM_locate(pub_params, privtag))) + if (!TEST_int_eq(EVP_PKEY_todata(key, EVP_PKEY_KEYPAIR, &keypair_params), 1)) + goto end; + + for (t = 0; t < OSSL_NELEM(pkey_priv_tags); t++) + if ((priv = OSSL_PARAM_locate(keypair_params, pkey_priv_tags[t])) != NULL) + break; + if (priv == NULL) { + TEST_error("%s: KEYPAIR todata() emitted no known private component", + keytype); goto end; + } + privtag = priv->key; + use_octstring = priv->data_type == OSSL_PARAM_OCTET_STRING; + /* - * Select the keypair when using EVP_PKEY_todata() and check that - * the param array contains a private key. + * Select only the public key via EVP_PKEY_todata(): the private tag we + * just learned must be absent. */ - if (!TEST_int_eq(EVP_PKEY_todata(key, EVP_PKEY_KEYPAIR, &keypair_params), 1) - || !TEST_ptr(OSSL_PARAM_locate(keypair_params, privtag))) + if (!TEST_int_eq(EVP_PKEY_todata(key, EVP_PKEY_PUBLIC_KEY, &pub_params), 1) + || !TEST_ptr_null(OSSL_PARAM_locate(pub_params, privtag))) goto end; /* - * Select only the public key when using EVP_PKEY_fromdata() and check that - * the resulting key does not contain a private key. + * Round-trip: importing only the public selection from the full keypair + * params must yield a key that has no private component. */ if (!TEST_ptr(fromctx = EVP_PKEY_CTX_new_from_name(mainctx, keytype, NULL)) || !TEST_int_eq(EVP_PKEY_fromdata_init(fromctx), 1) @@ -347,10 +480,8 @@ static int do_pkey_tofrom_data_select(EVP_PKEY *key, const char *keytype) 1) || !TEST_false(pkey_has_private(fromkey, privtag, use_octstring))) goto end; - /* - * Select the keypair when using EVP_PKEY_fromdata() and check that - * the resulting key contains a private key. - */ + + /* Round-trip: a full keypair import must carry the private component. */ if (!TEST_int_eq(EVP_PKEY_fromdata(fromctx, &fromkeypair, EVP_PKEY_KEYPAIR, keypair_params), 1) @@ -366,35 +497,135 @@ static int do_pkey_tofrom_data_select(EVP_PKEY *key, const char *keytype) return ret; } -#ifndef OPENSSL_NO_DH -static int test_dh_tofrom_data_select(void) +/* + * Pass every advertised gettable parameter through EVP_PKEY_get_params() + * as a probe, twice: once with NULL data (size negotiation), then again + * with storage allocated for the advertised type. Either fetch must + * succeed as a whole. Pass 2 is what exercises the type-matching + * branches in the per-type OSSL_PARAM setters: a NULL-data probe + * succeeds before those branches are reached, which is why this check + * would otherwise miss gettable-table / getter mismatches (an entry + * advertised as OCTET_STRING whose getter populates it as a BIGNUM). + * + * The provider is free to leave individual entries unmodified, e.g. + * private-key data on a public-only key; only whole-fetch failure + * is treated as a regression. + */ +static int do_pkey_all_gettables_probe(EVP_PKEY *pkey, const char *keytype) { - int ret; - OSSL_PARAM params[2]; - EVP_PKEY *key = NULL; - EVP_PKEY_CTX *gctx = NULL; -#ifndef OPENSSL_NO_DEPRECATED_3_0 - const DH *dhkey; - const BIGNUM *privkey; -#endif + int ret = 0; + const OSSL_PARAM *gettable; + OSSL_PARAM *probe = NULL; + void **storage = NULL; + size_t n = 0, i; + int need_refetch = 0; - params[0] = OSSL_PARAM_construct_utf8_string("group", "ffdhe2048", 0); - params[1] = OSSL_PARAM_construct_end(); - ret = TEST_ptr(gctx = EVP_PKEY_CTX_new_from_name(mainctx, "DHX", NULL)) - && TEST_int_gt(EVP_PKEY_keygen_init(gctx), 0) - && TEST_true(EVP_PKEY_CTX_set_params(gctx, params)) - && TEST_int_gt(EVP_PKEY_generate(gctx, &key), 0) - && TEST_true(do_pkey_tofrom_data_select(key, "DHX")); -#ifndef OPENSSL_NO_DEPRECATED_3_0 - ret = ret && TEST_ptr(dhkey = EVP_PKEY_get0_DH(key)) - && TEST_ptr(privkey = DH_get0_priv_key(dhkey)) - && TEST_int_le(BN_num_bits(privkey), 225); -#endif - EVP_PKEY_free(key); - EVP_PKEY_CTX_free(gctx); + if (!TEST_ptr(gettable = EVP_PKEY_gettable_params(pkey))) + goto err; + + while (gettable[n].key != NULL) + n++; + if (!TEST_ptr(probe = OPENSSL_zalloc((n + 1) * sizeof(*probe))) + || (n > 0 + && !TEST_ptr(storage = OPENSSL_zalloc(n * sizeof(*storage))))) + goto err; + + for (i = 0; i < n; i++) { + /* + * Copy the advertised entry as a template, then reset the + * data fields to the "probe" state. For OCTET_PTR / UTF8_PTR + * the setter writes *data directly (no size negotiation), + * so hand it a pointer slot up front. + */ + probe[i] = gettable[i]; + probe[i].data = NULL; + probe[i].data_size = 0; + probe[i].return_size = OSSL_PARAM_UNMODIFIED; + if (gettable[i].data_type == OSSL_PARAM_OCTET_PTR + || gettable[i].data_type == OSSL_PARAM_UTF8_PTR) { + if (!TEST_ptr(storage[i] = OPENSSL_zalloc(sizeof(void *)))) + goto err; + probe[i].data = storage[i]; + } + } + probe[n] = OSSL_PARAM_construct_end(); + + /* Pass 1: NULL-data probe populates return_size for sized entries. */ + if (!TEST_true(EVP_PKEY_get_params(pkey, probe))) { + TEST_info("%s: Pass 1 (size probe) failed", keytype); + goto err; + } + + /* Allocate storage for each populated sized entry. */ + for (i = 0; i < n; i++) { + size_t need; + + if (!OSSL_PARAM_modified(&probe[i])) + continue; + switch (probe[i].data_type) { + case OSSL_PARAM_INTEGER: + case OSSL_PARAM_UNSIGNED_INTEGER: + case OSSL_PARAM_OCTET_STRING: + case OSSL_PARAM_REAL: + need = probe[i].return_size; + if (!TEST_ptr(storage[i] = OPENSSL_malloc(need == 0 ? 1 : need))) + goto err; + probe[i].data = storage[i]; + probe[i].data_size = need; + probe[i].return_size = OSSL_PARAM_UNMODIFIED; + need_refetch = 1; + break; + case OSSL_PARAM_UTF8_STRING: + /* Leave room for a trailing NUL beyond return_size. */ + need = probe[i].return_size + 1; + if (!TEST_ptr(storage[i] = OPENSSL_malloc(need))) + goto err; + probe[i].data = storage[i]; + probe[i].data_size = need; + probe[i].return_size = OSSL_PARAM_UNMODIFIED; + need_refetch = 1; + break; + default: + /* PTR types were populated in Pass 1; unknown types left as-is. */ + break; + } + } + + /* + * Pass 2: real fetch, with typed storage. This is what actually + * catches advertised-vs-populated type mismatches: the per-type + * OSSL_PARAM_set_*() setters only enforce data_type when data is + * non-NULL. + */ + if (need_refetch && !TEST_true(EVP_PKEY_get_params(pkey, probe))) { + TEST_info("%s: Pass 2 (real fetch) failed", keytype); + goto err; + } + ret = 1; +err: + if (storage != NULL) + for (i = 0; i < n; i++) + OPENSSL_free(storage[i]); + OPENSSL_free(storage); + OPENSSL_free(probe); return ret; } +/* + * Composite check: exercise both the selection-mask semantics of + * todata/fromdata and the advertised-vs-populated type consistency of + * every gettable parameter on the given key. The individual helpers are + * algorithm-agnostic, so this driver works for any asymmetric EVP_PKEY. + * Each keytype-specific test function reduces to (a) key generation and + * (b) invoking this driver. + */ +static int do_pkey_checks(EVP_PKEY *key, const char *keytype) +{ + return do_pkey_tofrom_data_select(key, keytype) + && do_pkey_all_gettables_probe(key, keytype); +} + +#ifndef OPENSSL_NO_DH static int test_dh_paramgen(void) { int ret; @@ -559,57 +790,7 @@ static int test_ec_d2i_i2d_pubkey(void) return ret; } -static int test_ec_tofrom_data_select(void) -{ - int ret; - EVP_PKEY *key = NULL; - - ret = TEST_ptr(key = EVP_PKEY_Q_keygen(mainctx, NULL, "EC", "P-256")) - && TEST_true(do_pkey_tofrom_data_select(key, "EC")); - EVP_PKEY_free(key); - return ret; -} - -#ifndef OPENSSL_NO_ECX -static int test_ecx_tofrom_data_select(void) -{ - int ret; - EVP_PKEY *key = NULL; - - ret = TEST_ptr(key = EVP_PKEY_Q_keygen(mainctx, NULL, "X25519")) - && TEST_true(do_pkey_tofrom_data_select(key, "X25519")); - EVP_PKEY_free(key); - return ret; -} -#endif -#endif - -#ifndef OPENSSL_NO_SM2 -static int test_sm2_tofrom_data_select(void) -{ - int ret; - EVP_PKEY *key = NULL; - - ret = TEST_ptr(key = EVP_PKEY_Q_keygen(mainctx, NULL, "SM2")) - && TEST_true(do_pkey_tofrom_data_select(key, "SM2")); - EVP_PKEY_free(key); - return ret; -} -#endif - -static int test_rsa_tofrom_data_select(void) -{ - int ret; - EVP_PKEY *key = NULL; - const unsigned char *pdata = kExampleRSAKeyDER; - int pdata_len = sizeof(kExampleRSAKeyDER); - - ret = TEST_ptr(key = d2i_AutoPrivateKey_ex(NULL, &pdata, pdata_len, - mainctx, NULL)) - && TEST_true(do_pkey_tofrom_data_select(key, "RSA")); - EVP_PKEY_free(key); - return ret; -} +#endif /* OPENSSL_NO_EC */ /* This is the equivalent of test_d2i_AutoPrivateKey in evp_extra_test */ static int test_d2i_AutoPrivateKey_ex(int i) @@ -1070,7 +1251,9 @@ static const unsigned char dsa_pub[] = { 0xcc, 0xe2, 0x46, 0xce, 0xf5, 0x6d, 0xd8, 0x18, 0x91, 0xc4, 0x20, 0xbf, 0x07, 0x48, 0x45, 0xfd }; +#endif +#ifndef OPENSSL_NO_DSA static int do_check_params(OSSL_PARAM key_params[], int expected) { EVP_PKEY_CTX *gen_ctx = NULL, *check_ctx = NULL; @@ -1117,20 +1300,6 @@ static int do_check_int(OSSL_PARAM params[], const char *key, int expected) && TEST_int_eq(val, expected); } -static int test_dsa_tofrom_data_select(void) -{ - int ret; - EVP_PKEY *key = NULL; - const unsigned char *pkeydata = dsa_key; - - ret = TEST_ptr(key = d2i_AutoPrivateKey_ex(NULL, &pkeydata, sizeof(dsa_key), - mainctx, NULL)) - && TEST_true(do_pkey_tofrom_data_select(key, "DSA")); - - EVP_PKEY_free(key); - return ret; -} - static int test_dsa_todata(void) { EVP_PKEY *pkey = NULL; @@ -1554,6 +1723,112 @@ static int evp_test_name_parsing(void) return 1; } +/* + * Table-driven driver for do_pkey_checks(). Each entry names the + * algorithm and supplies either (a) a prefabricated DER blob, loaded + * via d2i_AutoPrivateKey_ex(), or (b) an optional OSSL_PARAM array + * passed to EVP_PKEY_CTX_set_params() before EVP_PKEY_generate(). + * The downstream checks are algorithm-agnostic; only the per-algorithm + * inputs live in this table. + */ +typedef struct pkey_test_spec_st { + const char *name; /* algorithm name for keygen or logging */ + const unsigned char *der; /* prefab private key DER, or NULL */ + uint32_t der_len; /* size of the DER blob when set */ + const OSSL_PARAM *params; /* keygen params, or NULL for defaults */ +} PKEY_TEST_SPEC; + +static const PKEY_TEST_SPEC pkey_test_specs[] = { +#ifndef OPENSSL_NO_DH + { "DHX", NULL, 0, dhx_keygen_params }, +#endif +#ifndef OPENSSL_NO_DSA + { "DSA", dsa_key, sizeof(dsa_key), NULL }, +#endif + { "RSA", kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER), NULL }, + { "RSA-PSS", kExampleRSAPSSKeyDER, sizeof(kExampleRSAPSSKeyDER), NULL }, +#ifndef OPENSSL_NO_EC + { "EC", NULL, 0, ec_keygen_params }, +#ifndef OPENSSL_NO_ECX + { "X25519", NULL, 0, NULL }, + { "ED25519", NULL, 0, NULL }, +#endif +#ifndef OPENSSL_NO_SM2 + { "SM2", NULL, 0, NULL }, +#endif +#endif +#ifndef OPENSSL_NO_ML_KEM + { "ML-KEM-512", NULL, 0, NULL }, +#endif +#ifndef OPENSSL_NO_ML_DSA + { "ML-DSA-44", NULL, 0, NULL }, +#endif +#ifndef OPENSSL_NO_SLH_DSA + { "SLH-DSA-SHA2-128f", NULL, 0, NULL }, +#endif +}; + +static EVP_PKEY *pkey_from_spec(OSSL_LIB_CTX *libctx, + const PKEY_TEST_SPEC *spec) +{ + EVP_PKEY *key = NULL; + EVP_PKEY_CTX *gctx = NULL; + + if (spec->der != NULL) { + const unsigned char *p = spec->der; + + return d2i_AutoPrivateKey_ex(NULL, &p, spec->der_len, libctx, NULL); + } + + if ((gctx = EVP_PKEY_CTX_new_from_name(libctx, spec->name, NULL)) == NULL + || EVP_PKEY_keygen_init(gctx) <= 0 + || (spec->params != NULL + && EVP_PKEY_CTX_set_params(gctx, spec->params) <= 0) + || EVP_PKEY_generate(gctx, &key) <= 0) { + EVP_PKEY_free(key); + key = NULL; + } + EVP_PKEY_CTX_free(gctx); + return key; +} + +static int test_pkey_by_spec(int i) +{ + EVP_PKEY *key = pkey_from_spec(mainctx, &pkey_test_specs[i]); + int ret = TEST_ptr(key) + && do_pkey_checks(key, pkey_test_specs[i].name); + + EVP_PKEY_free(key); + return ret; +} + +#if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0) +/* + * DHX keygen with group "ffdhe2048" reduces the private exponent modulo + * the sub-group order, so the exposed BN_num_bits() should not exceed + * the sub-group size. This tail check is DHX-specific and therefore + * does not fit the generic spec-table driver. + */ +static int test_dh_priv_bits(void) +{ + static const PKEY_TEST_SPEC dhx_spec = { + "DHX", NULL, 0, dhx_keygen_params + }; + int ret; + EVP_PKEY *key; + const DH *dhkey; + const BIGNUM *privkey; + + if (!TEST_ptr(key = pkey_from_spec(mainctx, &dhx_spec))) + return 0; + ret = TEST_ptr(dhkey = EVP_PKEY_get0_DH(key)) + && TEST_ptr(privkey = DH_get0_priv_key(dhkey)) + && TEST_int_le(BN_num_bits(privkey), 225); + EVP_PKEY_free(key); + return ret; +} +#endif + int setup_tests(void) { if (!test_get_libctx(&mainctx, &nullprov, NULL, NULL, NULL)) { @@ -1568,28 +1843,22 @@ int setup_tests(void) ADD_TEST(test_new_keytype); #ifndef OPENSSL_NO_EC ADD_ALL_TESTS(test_d2i_PrivateKey_ex, 2); - ADD_TEST(test_ec_tofrom_data_select); -#ifndef OPENSSL_NO_ECX - ADD_TEST(test_ecx_tofrom_data_select); -#endif ADD_TEST(test_ec_d2i_i2d_pubkey); #else ADD_ALL_TESTS(test_d2i_PrivateKey_ex, 1); #endif -#ifndef OPENSSL_NO_SM2 - ADD_TEST(test_sm2_tofrom_data_select); -#endif #ifndef OPENSSL_NO_DSA ADD_TEST(test_dsa_todata); - ADD_TEST(test_dsa_tofrom_data_select); ADD_ALL_TESTS(test_dsa_fromdata_digest_prop, 2); #endif #ifndef OPENSSL_NO_DH - ADD_TEST(test_dh_tofrom_data_select); ADD_TEST(test_dh_paramgen); ADD_TEST(test_dh_paramfromdata); +#ifndef OPENSSL_NO_DEPRECATED_3_0 + ADD_TEST(test_dh_priv_bits); +#endif #endif - ADD_TEST(test_rsa_tofrom_data_select); + ADD_ALL_TESTS(test_pkey_by_spec, OSSL_NELEM(pkey_test_specs)); ADD_TEST(test_pkey_todata_null); ADD_TEST(test_pkey_export_null); diff --git a/test/evp_fetch_prov_test.c b/test/evp_fetch_prov_test.c index bcc7c59eb611b..6fa5eb1a38bc1 100644 --- a/test/evp_fetch_prov_test.c +++ b/test/evp_fetch_prov_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/evp_libctx_test.c b/test/evp_libctx_test.c index aa94474ac5d53..e95a756c97c8c 100644 --- a/test/evp_libctx_test.c +++ b/test/evp_libctx_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/evp_pkey_provided_test.c b/test/evp_pkey_provided_test.c index 0464d12b7b616..ef41c2320f1fb 100644 --- a/test/evp_pkey_provided_test.c +++ b/test/evp_pkey_provided_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -93,7 +93,7 @@ static int compare_with_file(const char *alg, int type, BIO *membio) goto err; } - BIO_snprintf(filename, sizeof(filename), "%s.%s", alg, suffix); + snprintf(filename, sizeof(filename), "%s.%s", alg, suffix); fullfile = test_mk_file_path(datadir, filename); if (!TEST_ptr(fullfile)) goto err; diff --git a/test/evp_skey_test.c b/test/evp_skey_test.c index 631a5a6287a67..3ff4d93676cfe 100644 --- a/test/evp_skey_test.c +++ b/test/evp_skey_test.c @@ -113,7 +113,7 @@ static int test_skey_skeymgmt(void) if (!TEST_ptr(deflprov)) return 0; - /* Fetch our SKYMGMT for Generic Secrets */ + /* Fetch our SKEYMGMT for Generic Secrets */ if (!TEST_ptr(skeymgmt = EVP_SKEYMGMT_fetch(libctx, OSSL_SKEY_TYPE_GENERIC, NULL))) goto end; @@ -308,6 +308,235 @@ static int test_des_raw_skey(void) } #endif +static int test_skey_metadata_import(int tst) +{ + int ret = 0; + EVP_SKEY *key = NULL; + OSSL_PARAM_BLD *bld = NULL; + OSSL_PARAM *params = NULL; + OSSL_PARAM *exp_params = NULL; + const unsigned char import_key[KEY_SIZE] = { + 0x53, 0x4B, 0x45, 0x59, 0x53, 0x4B, 0x45, 0x59, 0x53, 0x4B, + 0x45, 0x59, 0x53, 0x4B, 0x45, 0x59 + }; + const char *alias = "my friendly name"; + const unsigned char local_keyid[] = { 0x01, 0x02, 0x03, 0x04 }; + const unsigned char alg_oid[] = { 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x01, 0x02 }; + const unsigned char alg_params[] = { 0x04, 0x10, 0x00, 0x01, 0x02, 0x03 }; + const char *bad_alias = "bad\0alias"; + const unsigned char *out_id = NULL; + size_t out_len = 0; + const unsigned char *out_oid = NULL, *out_params = NULL; + size_t out_oid_len = 0, out_params_len = 0; + + deflprov = OSSL_PROVIDER_load(libctx, "default"); + if (!TEST_ptr(deflprov)) + return 0; + + if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())) + goto end; + + if (!TEST_int_gt(OSSL_PARAM_BLD_push_octet_string(bld, + OSSL_SKEY_PARAM_RAW_BYTES, + import_key, sizeof(import_key)), + 0)) + goto end; + + switch (tst) { + case 0: + /* Import with all metadata */ + if (!TEST_int_gt(OSSL_PARAM_BLD_push_utf8_string(bld, + OSSL_SKEY_PARAM_ALIAS, alias, 0), + 0) + || !TEST_int_gt(OSSL_PARAM_BLD_push_octet_string(bld, + OSSL_SKEY_PARAM_LOCAL_KEYID, + local_keyid, sizeof(local_keyid)), + 0) + || !TEST_int_gt(OSSL_PARAM_BLD_push_octet_string(bld, + OSSL_SKEY_PARAM_ALGORITHM_OID, + alg_oid, sizeof(alg_oid)), + 0) + || !TEST_int_gt(OSSL_PARAM_BLD_push_octet_string(bld, + OSSL_SKEY_PARAM_ALGORITHM_PARAMS, + alg_params, sizeof(alg_params)), + 0)) + goto end; + break; + case 1: + /* Import with no metadata — should succeed */ + break; + case 2: + /* Import with alias containing embedded NUL — should fail */ + if (!TEST_int_gt(OSSL_PARAM_BLD_push_utf8_string(bld, + OSSL_SKEY_PARAM_ALIAS, + bad_alias, sizeof("bad\0alias") - 1), + 0)) + goto end; + break; + default: + goto end; + } + + if (!TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld))) + goto end; + + key = EVP_SKEY_import(libctx, OSSL_SKEY_TYPE_GENERIC, NULL, + OSSL_SKEYMGMT_SELECT_ALL, params); + + if (tst == 2) { + /* Embedded NUL in alias must cause import failure */ + if (!TEST_ptr_null(key)) + goto end; + ret = 1; + goto end; + } + + if (!TEST_ptr(key)) + goto end; + + if (tst == 0) { + /* Verify alias via get0_key_id */ + if (!TEST_str_eq(EVP_SKEY_get0_key_id(key), alias)) + goto end; + + /* Verify local_keyid */ + if (!TEST_int_gt(EVP_SKEY_get0_local_keyid(key, &out_id, &out_len), 0) + || !TEST_mem_eq(out_id, out_len, local_keyid, sizeof(local_keyid))) + goto end; + + /* Verify algorithm_id */ + if (!TEST_int_gt(EVP_SKEY_get0_algorithm_id(key, + &out_oid, &out_oid_len, + &out_params, &out_params_len), + 0) + || !TEST_mem_eq(out_oid, out_oid_len, alg_oid, sizeof(alg_oid)) + || !TEST_mem_eq(out_params, out_params_len, + alg_params, sizeof(alg_params))) + goto end; + } + + if (tst == 1) { + /* No metadata — get0_key_id should return NULL */ + if (!TEST_ptr_null(EVP_SKEY_get0_key_id(key))) + goto end; + /* get0_local_keyid succeeds but returns NULL pointer */ + if (!TEST_int_gt(EVP_SKEY_get0_local_keyid(key, &out_id, &out_len), 0) + || !TEST_ptr_null(out_id) + || !TEST_size_t_eq(out_len, 0)) + goto end; + } + + ret = 1; +end: + OSSL_PARAM_free(params); + OSSL_PARAM_free(exp_params); + OSSL_PARAM_BLD_free(bld); + EVP_SKEY_free(key); + OSSL_PROVIDER_unload(deflprov); + return ret; +} + +static int test_skey_metadata_export(int tst) +{ + int ret = 0; + EVP_SKEY *key = NULL; + OSSL_PARAM_BLD *bld = NULL; + OSSL_PARAM *params = NULL; + OSSL_PARAM *exp_params = NULL; + const OSSL_PARAM *p; + const unsigned char import_key[KEY_SIZE] = { + 0x53, 0x4B, 0x45, 0x59, 0x53, 0x4B, 0x45, 0x59, 0x53, 0x4B, + 0x45, 0x59, 0x53, 0x4B, 0x45, 0x59 + }; + const char *alias = "export test alias"; + const unsigned char local_keyid[] = { 0xAA, 0xBB, 0xCC }; + int export_ret; + + deflprov = OSSL_PROVIDER_load(libctx, "default"); + if (!TEST_ptr(deflprov)) + return 0; + + if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())) + goto end; + + if (!TEST_int_gt(OSSL_PARAM_BLD_push_octet_string(bld, + OSSL_SKEY_PARAM_RAW_BYTES, + import_key, sizeof(import_key)), + 0) + || !TEST_int_gt(OSSL_PARAM_BLD_push_utf8_string(bld, + OSSL_SKEY_PARAM_ALIAS, alias, 0), + 0) + || !TEST_int_gt(OSSL_PARAM_BLD_push_octet_string(bld, + OSSL_SKEY_PARAM_LOCAL_KEYID, + local_keyid, sizeof(local_keyid)), + 0)) + goto end; + + if (!TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld))) + goto end; + + key = EVP_SKEY_import(libctx, OSSL_SKEY_TYPE_GENERIC, NULL, + OSSL_SKEYMGMT_SELECT_ALL, params); + if (!TEST_ptr(key)) + goto end; + + switch (tst) { + case 0: + /* Export SECRET_KEY only — should not include metadata params */ + if (!TEST_int_gt(EVP_SKEY_export(key, + OSSL_SKEYMGMT_SELECT_SECRET_KEY, + ossl_pkey_todata_cb, &exp_params), + 0)) + goto end; + if (!TEST_ptr(OSSL_PARAM_locate_const(exp_params, + OSSL_SKEY_PARAM_RAW_BYTES))) + goto end; + if (!TEST_ptr_null(OSSL_PARAM_locate_const(exp_params, + OSSL_SKEY_PARAM_ALIAS))) + goto end; + if (!TEST_ptr_null(OSSL_PARAM_locate_const(exp_params, + OSSL_SKEY_PARAM_LOCAL_KEYID))) + goto end; + break; + case 1: + /* Export PARAMETERS only — should not include raw bytes */ + if (!TEST_int_gt(EVP_SKEY_export(key, + OSSL_SKEYMGMT_SELECT_PARAMETERS, + ossl_pkey_todata_cb, &exp_params), + 0)) + goto end; + if (!TEST_ptr_null(OSSL_PARAM_locate_const(exp_params, + OSSL_SKEY_PARAM_RAW_BYTES))) + goto end; + if (!TEST_ptr(p = OSSL_PARAM_locate_const(exp_params, + OSSL_SKEY_PARAM_ALIAS))) + goto end; + if (!TEST_ptr(OSSL_PARAM_locate_const(exp_params, + OSSL_SKEY_PARAM_LOCAL_KEYID))) + goto end; + break; + case 2: + /* Export with selection 0 — should fail */ + export_ret = EVP_SKEY_export(key, 0, + ossl_pkey_todata_cb, &exp_params); + if (!TEST_int_le(export_ret, 0)) + goto end; + break; + default: + goto end; + } + + ret = 1; +end: + OSSL_PARAM_free(params); + OSSL_PARAM_free(exp_params); + OSSL_PARAM_BLD_free(bld); + EVP_SKEY_free(key); + OSSL_PROVIDER_unload(deflprov); + return ret; +} + static int test_skey_to_same_provider(void) { OSSL_PROVIDER *fake_prov = NULL; @@ -402,6 +631,8 @@ int setup_tests(void) ADD_TEST(test_skey_cipher); ADD_TEST(test_skey_skeymgmt); + ADD_ALL_TESTS(test_skey_metadata_import, 3); + ADD_ALL_TESTS(test_skey_metadata_export, 3); ADD_TEST(test_skey_to_same_provider); ADD_TEST(test_skey_to_diff_provider); ADD_TEST(test_aes_raw_skey); diff --git a/test/evp_test.c b/test/evp_test.c index 77029f40db9b9..ecad8583bead1 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -475,10 +475,9 @@ static int evp_test_buffer_ncopy(const char *value, EVP_TEST_BUFFER *db; unsigned char *tbuf, *p; size_t tbuflen; - int ncopy = atoi(value); - int i; + int ncopy = 0, i; - if (ncopy <= 0) + if (!test_strtoint(value, &ncopy) || ncopy <= 0) return 0; if (sk == NULL || sk_EVP_TEST_BUFFER_num(sk) == 0) return 0; @@ -501,9 +500,9 @@ static int evp_test_buffer_set_count(const char *value, STACK_OF(EVP_TEST_BUFFER) *sk) { EVP_TEST_BUFFER *db; - int count = atoi(value); + int count = 0; - if (count <= 0) + if (!test_strtoint(value, &count) || count <= 0) return 0; if (sk == NULL || sk_EVP_TEST_BUFFER_num(sk) == 0) @@ -764,14 +763,13 @@ static int digest_test_parse(EVP_TEST *t, if (strcmp(keyword, "Ncopy") == 0) return evp_test_buffer_ncopy(value, mdata->input); if (strcmp(keyword, "Padding") == 0) - return (mdata->pad_type = atoi(value)) > 0; + return test_strtoint(value, &mdata->pad_type) && mdata->pad_type > 0; if (strcmp(keyword, "XOF") == 0) - return (mdata->xof = atoi(value)) > 0; + return test_strtoint(value, &mdata->xof) && mdata->xof > 0; if (strcmp(keyword, "OutputSize") == 0) { int sz; - sz = atoi(value); - if (sz < 0) + if (!test_strtoint(value, &sz)) return -1; mdata->digest_size = sz; return 1; @@ -1065,8 +1063,7 @@ static int cipher_test_parse(EVP_TEST *t, const char *keyword, if (strcmp(keyword, "Key") == 0) return parse_bin(value, &cdat->key, &cdat->key_len); if (strcmp(keyword, "Rounds") == 0) { - i = atoi(value); - if (i < 0) + if (!test_strtoint(value, &i)) return -1; cdat->rounds = (unsigned int)i; return 1; @@ -1080,8 +1077,7 @@ static int cipher_test_parse(EVP_TEST *t, const char *keyword, if (strcmp(keyword, "Ciphertext") == 0) return parse_bin(value, &cdat->ciphertext, &cdat->ciphertext_len); if (strcmp(keyword, "KeyBits") == 0) { - i = atoi(value); - if (i < 0) + if (!test_strtoint(value, &i)) return -1; cdat->key_bits = (size_t)i; return 1; @@ -1652,12 +1648,12 @@ static int cipher_test_run(EVP_TEST *t) if (inp_misalign == 1 && in_place == 1) break; if (in_place == 1) { - BIO_snprintf(aux_err, sizeof(aux_err), + snprintf(aux_err, sizeof(aux_err), "%s in-place, %sfragmented", out_misalign ? "misaligned" : "aligned", frag ? "" : "not "); } else { - BIO_snprintf(aux_err, sizeof(aux_err), + snprintf(aux_err, sizeof(aux_err), "%s output and %s input, %sfragmented", out_misalign ? "misaligned" : "aligned", inp_misalign ? "misaligned" : "aligned", @@ -1838,14 +1834,12 @@ static int mac_test_parse(EVP_TEST *t, if (strcmp(keyword, "Ctrl") == 0) return ctrladd(mdata->controls, value); if (strcmp(keyword, "OutputSize") == 0) { - mdata->output_size = atoi(value); - if (mdata->output_size < 0) + if (!test_strtoint(value, &mdata->output_size)) return -1; return 1; } if (strcmp(keyword, "BlockSize") == 0) { - mdata->block_size = atoi(value); - if (mdata->block_size < 0) + if (!test_strtoint(value, &mdata->block_size)) return -1; return 1; } @@ -3451,8 +3445,7 @@ static int pbkdf2_test_parse(EVP_TEST *t, PBE_DATA *pdata = t->data; if (strcmp(keyword, "iter") == 0) { - pdata->iter = atoi(value); - if (pdata->iter <= 0) + if (!test_strtoint(value, &pdata->iter) || pdata->iter <= 0) return -1; return 1; } @@ -3471,8 +3464,7 @@ static int pkcs12_test_parse(EVP_TEST *t, PBE_DATA *pdata = t->data; if (strcmp(keyword, "id") == 0) { - pdata->id = atoi(value); - if (pdata->id <= 0) + if (!test_strtoint(value, &pdata->id) || pdata->id <= 0) return -1; return 1; } @@ -3901,7 +3893,8 @@ static int rand_test_parse(EVP_TEST *t, int n; if ((p = strchr(keyword, '.')) != NULL) { - n = atoi(++p); + if (!test_strtoint(++p, &n)) + return 0; if (n >= MAX_RAND_REPEATS) return 0; if (n > rdata->n) @@ -3935,17 +3928,21 @@ static int rand_test_parse(EVP_TEST *t, if (strcmp(keyword, "Digest") == 0) return TEST_ptr(rdata->digest = OPENSSL_strdup(value)); if (strcmp(keyword, "DerivationFunction") == 0) { - rdata->use_df = atoi(value) != 0; + n = 0; + (void)test_strtoint(value, &n); + rdata->use_df = n != 0; return 1; } if (strcmp(keyword, "GenerateBits") == 0) { - if ((n = atoi(value)) <= 0 || n % 8 != 0) + if (!test_strtoint(value, &n) || n <= 0 || n % 8 != 0) return 0; rdata->generate_bits = (unsigned int)n; return 1; } if (strcmp(keyword, "PredictionResistance") == 0) { - rdata->prediction_resistance = atoi(value) != 0; + n = 0; + (void)test_strtoint(value, &n); + rdata->prediction_resistance = n != 0; return 1; } if (strcmp(keyword, "CtrlInit") == 0) @@ -5612,7 +5609,10 @@ static int parse(EVP_TEST *t) } t->reason = take_value(pp); } else if (strcmp(pp->key, "Threads") == 0) { - if (OSSL_set_max_threads(libctx, atoi(pp->value)) == 0) { + int nthreads = 0; + + (void)test_strtoint(pp->value, &nthreads); + if (OSSL_set_max_threads(libctx, nthreads) == 0) { TEST_info("skipping, '%s' threads not available: %s:%d", pp->value, t->s.test_file, t->s.start); t->skip = 1; @@ -5630,8 +5630,9 @@ static int parse(EVP_TEST *t) TEST_info("Line %d: multiple security category lines", t->s.curr); return 0; } - t->security_category = atoi(pp->value); - if (t->security_category < 0 || t->security_category > 5) { + t->security_category = 0; + if (!test_strtoint(pp->value, &t->security_category) + || t->security_category > 5) { TEST_info("Line %d: invalid security category, should be 0..5", t->s.curr); return 0; diff --git a/test/exptest.c b/test/exptest.c index ebb8284899a50..e2e005421aff1 100644 --- a/test/exptest.c +++ b/test/exptest.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -236,6 +236,17 @@ static int test_mod_exp(int round) return ret; } +/*- + * The factor sizes are what matters; the rounds are repetition on fresh + * random inputs. A defect showing on a fraction f of inputs is caught by + * N rounds with probability 1 - (1 - f) ^ N, so twenty catch anything + * affecting a seventh of inputs or more. Rarer ones are not caught in a + * single run at any affordable count, and are left to the inputs being + * drawn afresh on every run. + */ +static const int factor_sizes[] = { 1024, 1536, 2048 }; +#define ROUNDS_PER_FACTOR_SIZE 20 + static int test_mod_exp_x2(int idx) { BN_CTX *ctx; @@ -250,14 +261,7 @@ static int test_mod_exp_x2(int idx) BIGNUM *a2 = NULL; BIGNUM *b2 = NULL; BIGNUM *m2 = NULL; - int factor_size = 0; - - if (idx <= 100) - factor_size = 1024; - else if (idx <= 200) - factor_size = 1536; - else if (idx <= 300) - factor_size = 2048; + int factor_size = factor_sizes[idx / ROUNDS_PER_FACTOR_SIZE]; if (!TEST_ptr(ctx = BN_CTX_new())) goto err; @@ -333,6 +337,7 @@ int setup_tests(void) { ADD_TEST(test_mod_exp_zero); ADD_ALL_TESTS(test_mod_exp, 200); - ADD_ALL_TESTS(test_mod_exp_x2, 300); + ADD_ALL_TESTS(test_mod_exp_x2, + OSSL_NELEM(factor_sizes) * ROUNDS_PER_FACTOR_SIZE); return 1; } diff --git a/test/ext_internal_test.c b/test/ext_internal_test.c index c88f026dee076..993f962b2af54 100644 --- a/test/ext_internal_test.c +++ b/test/ext_internal_test.c @@ -81,7 +81,6 @@ static EXT_LIST ext_list[] = { #endif EXT_ENTRY(grease1), EXT_ENTRY(grease2), - EXT_ENTRY(padding), EXT_ENTRY(psk), EXT_END(num_builtins) }; diff --git a/test/fake_cipherprov.c b/test/fake_cipherprov.c index ad28a6b94b7cb..8f3a02e95bd77 100644 --- a/test/fake_cipherprov.c +++ b/test/fake_cipherprov.c @@ -96,6 +96,27 @@ static void *fake_skeymgmt_generate(void *provctx, const OSSL_PARAM *params) return ctx; } +static const char *fake_skeymgmt_get_key_id(void *keydata) +{ + PROV_CIPHER_FAKE_CTX *ctx = (PROV_CIPHER_FAKE_CTX *)keydata; + + if (ctx == NULL || ctx->key_name[0] == '\0') + return NULL; + + return ctx->key_name; +} + +static const OSSL_PARAM fake_skeymgmt_known_settable_params[] = { + OSSL_PARAM_utf8_string(FAKE_CIPHER_PARAM_KEY_NAME, NULL, 0), + OSSL_PARAM_octet_string(OSSL_SKEY_PARAM_RAW_BYTES, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *fake_skeymgmt_settable_params(ossl_unused void *provctx) +{ + return fake_skeymgmt_known_settable_params; +} + static int fake_skeymgmt_export(void *keydata, int selection, OSSL_CALLBACK *param_callback, void *cbarg) { @@ -126,6 +147,11 @@ static const OSSL_DISPATCH fake_skeymgmt_funcs[] = { { OSSL_FUNC_SKEYMGMT_GENERATE, (void (*)(void))fake_skeymgmt_generate }, { OSSL_FUNC_SKEYMGMT_IMPORT, (void (*)(void))fake_skeymgmt_import }, { OSSL_FUNC_SKEYMGMT_EXPORT, (void (*)(void))fake_skeymgmt_export }, + { OSSL_FUNC_SKEYMGMT_GET_KEY_ID, (void (*)(void))fake_skeymgmt_get_key_id }, + { OSSL_FUNC_SKEYMGMT_IMP_SETTABLE_PARAMS, + (void (*)(void))fake_skeymgmt_settable_params }, + { OSSL_FUNC_SKEYMGMT_GEN_SETTABLE_PARAMS, + (void (*)(void))fake_skeymgmt_settable_params }, OSSL_DISPATCH_END }; diff --git a/test/fake_rsaprov.c b/test/fake_rsaprov.c index eb9f92af15ea8..408b858cb1f8d 100644 --- a/test/fake_rsaprov.c +++ b/test/fake_rsaprov.c @@ -540,8 +540,8 @@ static OSSL_FUNC_store_eof_fn fake_rsa_st_eof; static OSSL_FUNC_store_close_fn fake_rsa_st_close; static OSSL_FUNC_store_delete_fn fake_rsa_st_delete; -static const char fake_rsa_scheme[] = "fake_rsa:"; -static const char fake_rsa_openpwtest[] = "fake_rsa:openpwtest"; +static const char fake_rsa_scheme[] = "fake-rsa:"; +static const char fake_rsa_openpwtest[] = "fake-rsa:openpwtest"; static const char fake_rsa_prompt[] = "Fake Prompt Info"; static void *fake_rsa_st_open_ex(void *provctx, const char *uri, @@ -703,7 +703,7 @@ static const OSSL_DISPATCH fake_rsa_store_funcs[] = { }; static const OSSL_ALGORITHM fake_rsa_store_algs[] = { - { "fake_rsa", "provider=fake-rsa", fake_rsa_store_funcs }, + { "fake-rsa", "provider=fake-rsa", fake_rsa_store_funcs }, { NULL, NULL, NULL } }; @@ -1269,5 +1269,10 @@ OSSL_PROVIDER *fake_rsa_start(OSSL_LIB_CTX *libctx) void fake_rsa_finish(OSSL_PROVIDER *p) { + TEST_info("fake_rsa info: has_selection: %d imptypes_selection: %d" + "exptypes_selection: %d query_id: %d key_deleted: %d", + has_selection, imptypes_selection, + exptypes_selection, query_id, key_deleted); + OSSL_PROVIDER_unload(p); } diff --git a/test/fake_storeprov.c b/test/fake_storeprov.c new file mode 100644 index 0000000000000..e0cfbbdb34b01 --- /dev/null +++ b/test/fake_storeprov.c @@ -0,0 +1,276 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fake_storeprov.h" + +/* + * A minimal store loader that emits OSSL_STORE_INFO_NAME objects, so that + * no decoders or other providers are needed to exercise the OSSL_STORE API. + * The URI part after the scheme selects the loader behaviour, see the + * FAKE_STORE_CMD_* macros. + */ + +struct fake_store_ctx_st { + int remaining; + int fail_params; + int expected_type; +}; + +static unsigned int seen_params = 0; +static char last_deleted[256] = ""; + +unsigned int fake_store_get_seen_params(void) +{ + return seen_params; +} + +void fake_store_clear_state(void) +{ + seen_params = 0; + last_deleted[0] = '\0'; +} + +const char *fake_store_get0_last_deleted(void) +{ + return last_deleted; +} + +static OSSL_FUNC_store_open_fn fake_store_open; +static OSSL_FUNC_store_open_ex_fn fake_store_open_ex; +static OSSL_FUNC_store_attach_fn fake_store_attach; +static OSSL_FUNC_store_settable_ctx_params_fn fake_store_settable_ctx_params; +static OSSL_FUNC_store_set_ctx_params_fn fake_store_set_ctx_params; +static OSSL_FUNC_store_load_fn fake_store_load; +static OSSL_FUNC_store_eof_fn fake_store_eof; +static OSSL_FUNC_store_close_fn fake_store_close; +static OSSL_FUNC_store_delete_fn fake_store_delete; + +static void *fake_store_open(void *provctx, const char *uri) +{ + struct fake_store_ctx_st *ctx; + const char *cmd; + + if ((cmd = strchr(uri, ':')) == NULL) + return NULL; + cmd++; + + if (strcmp(cmd, FAKE_STORE_CMD_OPEN_FAIL) == 0) + return NULL; + + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) + return NULL; + ctx->remaining = strcmp(cmd, FAKE_STORE_CMD_TWO_NAMES) == 0 ? 2 : 1; + ctx->fail_params = strcmp(cmd, FAKE_STORE_CMD_PARAMS_FAIL) == 0; + return ctx; +} + +static void *fake_store_open_ex(void *provctx, const char *uri, + const OSSL_PARAM params[], + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + struct fake_store_ctx_st *ctx = fake_store_open(provctx, uri); + + if (ctx != NULL && params != NULL + && !fake_store_set_ctx_params(ctx, params)) { + OPENSSL_free(ctx); + return NULL; + } + return ctx; +} + +static void *fake_store_attach(void *provctx, OSSL_CORE_BIO *in) +{ + struct fake_store_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); + + if (ctx != NULL) + ctx->remaining = 1; + return ctx; +} + +static const OSSL_PARAM fake_store_settable_params_list[] = { + OSSL_PARAM_int(OSSL_STORE_PARAM_EXPECT, NULL), + OSSL_PARAM_octet_string(OSSL_STORE_PARAM_SUBJECT, NULL, 0), + OSSL_PARAM_octet_string(OSSL_STORE_PARAM_ISSUER, NULL, 0), + OSSL_PARAM_BN(OSSL_STORE_PARAM_SERIAL, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_STORE_PARAM_DIGEST, NULL, 0), + OSSL_PARAM_octet_string(OSSL_STORE_PARAM_FINGERPRINT, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_STORE_PARAM_ALIAS, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_STORE_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_STORE_PARAM_INPUT_TYPE, NULL, 0), + OSSL_PARAM_END +}; + +static const OSSL_PARAM *fake_store_settable_ctx_params(void *provctx) +{ + return fake_store_settable_params_list; +} + +static int fake_store_set_ctx_params(void *loaderctx, const OSSL_PARAM params[]) +{ + struct fake_store_ctx_st *ctx = loaderctx; + const OSSL_PARAM *p; + + if (ctx->fail_params) + return 0; + + if ((p = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_EXPECT)) != NULL) { + if (!OSSL_PARAM_get_int(p, &ctx->expected_type)) + return 0; + seen_params |= FAKE_STORE_SEEN_EXPECT; + } + if (OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SUBJECT) != NULL) + seen_params |= FAKE_STORE_SEEN_SUBJECT; + if (OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_ISSUER) != NULL) + seen_params |= FAKE_STORE_SEEN_ISSUER; + if (OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SERIAL) != NULL) + seen_params |= FAKE_STORE_SEEN_SERIAL; + if (OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_DIGEST) != NULL) + seen_params |= FAKE_STORE_SEEN_DIGEST; + if (OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_FINGERPRINT) != NULL) + seen_params |= FAKE_STORE_SEEN_FINGERPRINT; + if (OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_ALIAS) != NULL) + seen_params |= FAKE_STORE_SEEN_ALIAS; + if (OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_PROPERTIES) != NULL) + seen_params |= FAKE_STORE_SEEN_PROPERTIES; + return 1; +} + +static int fake_store_load(void *loaderctx, + OSSL_CALLBACK *object_cb, void *object_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + struct fake_store_ctx_st *ctx = loaderctx; + OSSL_PARAM params[4]; + int object_type = OSSL_OBJECT_NAME; + char name[16], desc[16]; + + if (ctx->remaining <= 0) + return 0; + snprintf(name, sizeof(name), "name%d", ctx->remaining); + snprintf(desc, sizeof(desc), "desc%d", ctx->remaining); + ctx->remaining--; + + params[0] = OSSL_PARAM_construct_int(OSSL_OBJECT_PARAM_TYPE, &object_type); + params[1] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA, + name, 0); + params[2] = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DESC, + desc, 0); + params[3] = OSSL_PARAM_construct_end(); + + return object_cb(params, object_cbarg); +} + +static int fake_store_eof(void *loaderctx) +{ + struct fake_store_ctx_st *ctx = loaderctx; + + return ctx->remaining <= 0; +} + +static int fake_store_close(void *loaderctx) +{ + OPENSSL_free(loaderctx); + return 1; +} + +static int fake_store_delete(void *provctx, const char *uri, + const OSSL_PARAM params[], + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + OPENSSL_strlcpy(last_deleted, uri, sizeof(last_deleted)); + return 1; +} + +static const OSSL_DISPATCH fake_store_funcs[] = { + { OSSL_FUNC_STORE_OPEN, (void (*)(void))fake_store_open }, + { OSSL_FUNC_STORE_ATTACH, (void (*)(void))fake_store_attach }, + { OSSL_FUNC_STORE_SETTABLE_CTX_PARAMS, + (void (*)(void))fake_store_settable_ctx_params }, + { OSSL_FUNC_STORE_SET_CTX_PARAMS, + (void (*)(void))fake_store_set_ctx_params }, + { OSSL_FUNC_STORE_LOAD, (void (*)(void))fake_store_load }, + { OSSL_FUNC_STORE_EOF, (void (*)(void))fake_store_eof }, + { OSSL_FUNC_STORE_CLOSE, (void (*)(void))fake_store_close }, + { OSSL_FUNC_STORE_DELETE, (void (*)(void))fake_store_delete }, + OSSL_DISPATCH_END +}; + +/* open() is required for a complete loader but open_ex() takes precedence */ +static const OSSL_DISPATCH fake_store_open_ex_funcs[] = { + { OSSL_FUNC_STORE_OPEN_EX, (void (*)(void))fake_store_open_ex }, + { OSSL_FUNC_STORE_OPEN, (void (*)(void))fake_store_open }, + { OSSL_FUNC_STORE_SETTABLE_CTX_PARAMS, + (void (*)(void))fake_store_settable_ctx_params }, + { OSSL_FUNC_STORE_SET_CTX_PARAMS, + (void (*)(void))fake_store_set_ctx_params }, + { OSSL_FUNC_STORE_LOAD, (void (*)(void))fake_store_load }, + { OSSL_FUNC_STORE_EOF, (void (*)(void))fake_store_eof }, + { OSSL_FUNC_STORE_CLOSE, (void (*)(void))fake_store_close }, + OSSL_DISPATCH_END +}; + +static const OSSL_ALGORITHM fake_store_store_algs[] = { + { FAKE_STORE_SCHEME, FAKE_STORE_FETCH_PROPS, fake_store_funcs, + "Fake store loader" }, + { FAKE_STORE_SCHEME_OPEN_EX, FAKE_STORE_FETCH_PROPS, + fake_store_open_ex_funcs, "Fake store loader with open_ex" }, + { NULL, NULL, NULL, NULL } +}; + +static const OSSL_ALGORITHM *fake_store_query(void *provctx, int operation_id, + int *no_cache) +{ + *no_cache = 0; + if (operation_id == OSSL_OP_STORE) + return fake_store_store_algs; + return NULL; +} + +/* Functions we provide to the core */ +static const OSSL_DISPATCH fake_store_method[] = { + { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))OSSL_LIB_CTX_free }, + { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fake_store_query }, + OSSL_DISPATCH_END +}; + +static int fake_store_provider_init(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in, + const OSSL_DISPATCH **out, void **provctx) +{ + if ((*provctx = OSSL_LIB_CTX_new()) == NULL) + return 0; + *out = fake_store_method; + return 1; +} + +OSSL_PROVIDER *fake_store_start(OSSL_LIB_CTX *libctx) +{ + OSSL_PROVIDER *p; + + if (!OSSL_PROVIDER_add_builtin(libctx, FAKE_STORE_PROV_NAME, + fake_store_provider_init) + || (p = OSSL_PROVIDER_try_load(libctx, FAKE_STORE_PROV_NAME, 1)) == NULL) + return NULL; + + return p; +} + +void fake_store_finish(OSSL_PROVIDER *p) +{ + OSSL_PROVIDER_unload(p); +} diff --git a/test/fake_storeprov.h b/test/fake_storeprov.h new file mode 100644 index 0000000000000..ab5bdbeae009c --- /dev/null +++ b/test/fake_storeprov.h @@ -0,0 +1,43 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include + +/* Fake store provider implementation */ +OSSL_PROVIDER *fake_store_start(OSSL_LIB_CTX *libctx); +void fake_store_finish(OSSL_PROVIDER *p); + +#define FAKE_STORE_PROV_NAME "fake-store" +#define FAKE_STORE_FETCH_PROPS "provider=fake-store" + +/* Scheme with a plain open() entry point and delete support */ +#define FAKE_STORE_SCHEME "fake" +/* Scheme with an open_ex() entry point and no delete support */ +#define FAKE_STORE_SCHEME_OPEN_EX "fake-ex" + +/* URI commands recognised after the scheme, e.g. "fake:two-names" */ +#define FAKE_STORE_CMD_ONE_NAME "one-name" +#define FAKE_STORE_CMD_TWO_NAMES "two-names" +#define FAKE_STORE_CMD_OPEN_FAIL "open-fail" +#define FAKE_STORE_CMD_PARAMS_FAIL "params-fail" + +/* Bitmask of ctx params the fake loader has observed */ +#define FAKE_STORE_SEEN_EXPECT (1u << 0) +#define FAKE_STORE_SEEN_SUBJECT (1u << 1) +#define FAKE_STORE_SEEN_ISSUER (1u << 2) +#define FAKE_STORE_SEEN_SERIAL (1u << 3) +#define FAKE_STORE_SEEN_DIGEST (1u << 4) +#define FAKE_STORE_SEEN_FINGERPRINT (1u << 5) +#define FAKE_STORE_SEEN_ALIAS (1u << 6) +#define FAKE_STORE_SEEN_PROPERTIES (1u << 7) + +unsigned int fake_store_get_seen_params(void); +void fake_store_clear_state(void); +const char *fake_store_get0_last_deleted(void); diff --git a/test/ffc_internal_test.c b/test/ffc_internal_test.c index d08f3b244deef..3a9b84a7457ee 100644 --- a/test/ffc_internal_test.c +++ b/test/ffc_internal_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2019-2020, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/test/fipsidentity.cnf b/test/fipsidentity.cnf new file mode 100644 index 0000000000000..30b7775275d6b --- /dev/null +++ b/test/fipsidentity.cnf @@ -0,0 +1,23 @@ +openssl_conf = openssl_init + +# Comment out the next line to ignore configuration errors +config_diagnostics = 1 + +.include fipsmodule.cnf + +[openssl_init] +providers = provider_sect +random = random_sect + +[provider_sect] +default = default_sect +fips = fips_sect + +[default_sect] +activate = yes + +[fips_sect] +identity = fips-identity + +[random_sect] +properties = fips=yes diff --git a/test/genec_test.c b/test/genec_test.c new file mode 100644 index 0000000000000..7504bed27092e --- /dev/null +++ b/test/genec_test.c @@ -0,0 +1,477 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/*- + * Table driven EC parameter and key generation tests. + * + * Every curve is exercised in this process. The generation is driven + * through EVP_PKEY_CTX_ctrl_str() with the same option names the + * "openssl genpkey" application passes to -pkeyopt, so the provider side + * of the application's code path is covered here. The application's own + * command line surface is covered separately by + * test/recipes/20-test_app_genec.t, which needs only a handful of curves + * because the option handling does not vary between them. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "testutil.h" + +static const char *const curves[] = { + "secp112r1", + "secp112r2", + "secp128r1", + "secp128r2", + "secp160k1", + "secp160r1", + "secp160r2", + "secp192k1", + "secp224k1", + "secp224r1", + "secp256k1", + "secp384r1", + "secp521r1", + "prime192v1", + "prime192v2", + "prime192v3", + "prime239v1", + "prime239v2", + "prime239v3", + "prime256v1", + "wap-wsg-idm-ecid-wtls6", + "wap-wsg-idm-ecid-wtls7", + "wap-wsg-idm-ecid-wtls8", + "wap-wsg-idm-ecid-wtls9", + "wap-wsg-idm-ecid-wtls12", + "brainpoolP160r1", + "brainpoolP160t1", + "brainpoolP192r1", + "brainpoolP192t1", + "brainpoolP224r1", + "brainpoolP224t1", + "brainpoolP256r1", + "brainpoolP256t1", + "brainpoolP320r1", + "brainpoolP320t1", + "brainpoolP384r1", + "brainpoolP384t1", + "brainpoolP512r1", + "brainpoolP512t1", +#if !defined(OPENSSL_NO_EC2M) + "sect113r1", + "sect113r2", + "sect131r1", + "sect131r2", + "sect163k1", + "sect163r1", + "sect163r2", + "sect193r1", + "sect193r2", + "sect233k1", + "sect233r1", + "sect239k1", + "sect283k1", + "sect283r1", + "sect409k1", + "sect409r1", + "sect571k1", + "sect571r1", + "c2pnb163v1", + "c2pnb163v2", + "c2pnb163v3", + "c2pnb176v1", + "c2tnb191v1", + "c2tnb191v2", + "c2tnb191v3", + "c2pnb208w1", + "c2tnb239v1", + "c2tnb239v2", + "c2tnb239v3", + "c2pnb272w1", + "c2pnb304w1", + "c2tnb359v1", + "c2pnb368w1", + "c2tnb431r1", + "wap-wsg-idm-ecid-wtls1", + "wap-wsg-idm-ecid-wtls3", + "wap-wsg-idm-ecid-wtls4", + "wap-wsg-idm-ecid-wtls5", + "wap-wsg-idm-ecid-wtls10", + "wap-wsg-idm-ecid-wtls11", +#endif /* !defined(OPENSSL_NO_EC2M) */ + /* + * The SM2 curve is deliberately absent. A key generated on it as an + * EC key decodes back as an SM2 key, so it does not satisfy the round + * trip below. It is covered by test/recipes/20-test_app_genec.t, + * which only requires that generation and output succeed. + */ + "P-192", + "P-224", + "P-256", + "P-384", + "P-521", +#if !defined(OPENSSL_NO_EC2M) + "B-163", + "B-233", + "B-283", + "B-409", + "B-571", + "K-163", + "K-233", + "K-283", + "K-409", + "K-571", +#endif /* !defined(OPENSSL_NO_EC2M) */ +}; + +#if !defined(OPENSSL_NO_EC2M) +/* Curves that have no assigned OID and so cannot use a named encoding. */ +static const char *const explicit_only_curves[] = { + "Oakley-EC2N-3", + "Oakley-EC2N-4", +}; +#endif /* !defined(OPENSSL_NO_EC2M) */ + +static const char *const param_encodings[] = { "named_curve", "explicit" }; + +static const char *const formats[] = { "PEM", "DER" }; + +/** + * @brief Generate EC parameters or an EC key on a named curve. + * + * The curve and the parameter encoding are set with the same option + * names the genpkey application accepts via -pkeyopt. No test + * assertions are made here so that callers can also use this to check + * that a combination is correctly rejected. + * + * @param curve the name of the curve to generate on + * @param param_enc the parameter encoding, "named_curve" or "explicit" + * @param params_only 1 to generate parameters only, 0 to generate a key + * @returns the generated EVP_PKEY, or NULL on failure + */ +static EVP_PKEY *gen_ec(const char *curve, const char *param_enc, + int params_only) +{ + EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY *pkey = NULL; + + if ((ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) == NULL) + return NULL; + + if (params_only) { + if (EVP_PKEY_paramgen_init(ctx) <= 0) + goto end; + } else { + if (EVP_PKEY_keygen_init(ctx) <= 0) + goto end; + } + + if (EVP_PKEY_CTX_ctrl_str(ctx, "ec_paramgen_curve", curve) <= 0 + || EVP_PKEY_CTX_ctrl_str(ctx, "ec_param_enc", param_enc) <= 0) + goto end; + + if (EVP_PKEY_generate(ctx, &pkey) <= 0) { + EVP_PKEY_free(pkey); + pkey = NULL; + } + +end: + EVP_PKEY_CTX_free(ctx); + return pkey; +} + +/** + * @brief Encode a key or parameter set into a freshly allocated buffer. + * + * No test assertions are made here so that callers can also use this to + * check that an encoding is correctly refused. + * + * @param pkey the key or parameter set to encode + * @param selection the EVP_PKEY_* selection to encode + * @param structure the encoder output structure name + * @param format the encoding to use, "PEM" or "DER" + * @param out where to store the allocated encoding, freed by the caller + * @param out_len where to store the length of the encoding + * @returns 1 on success, 0 on failure + */ +static int encode_pkey(EVP_PKEY *pkey, int selection, const char *structure, + const char *format, unsigned char **out, size_t *out_len) +{ + OSSL_ENCODER_CTX *ectx = NULL; + BIO *mem = NULL; + BUF_MEM *buf = NULL; + int ret = 0; + + ectx = OSSL_ENCODER_CTX_new_for_pkey(pkey, selection, format, structure, + NULL); + if (ectx == NULL || OSSL_ENCODER_CTX_get_num_encoders(ectx) == 0) + goto end; + + if ((mem = BIO_new(BIO_s_mem())) == NULL + || !OSSL_ENCODER_to_bio(ectx, mem) + || BIO_get_mem_ptr(mem, &buf) <= 0 + || buf->length == 0) + goto end; + + if ((*out = OPENSSL_memdup(buf->data, buf->length)) == NULL) + goto end; + *out_len = buf->length; + ret = 1; + +end: + BIO_free(mem); + OSSL_ENCODER_CTX_free(ectx); + return ret; +} + +/** + * @brief Encode a key, decode the result, and encode it a second time. + * + * The two encodings must be identical. This is compared rather than the + * key objects themselves because an explicit encoding of a curve that is + * an alias of another curve does not decode to an object that + * EVP_PKEY_eq() considers equal to the original, even though the key + * material survives intact. + * + * @param pkey the key or parameter set to round trip + * @param selection the EVP_PKEY_* selection to encode and decode + * @param structure the encoder output structure name + * @param format the encoding to use, "PEM" or "DER" + * @returns 1 if the re-encoding matched the original encoding, 0 otherwise + */ +static int round_trip(EVP_PKEY *pkey, int selection, const char *structure, + const char *format) +{ + OSSL_DECODER_CTX *dctx = NULL; + EVP_PKEY *decoded = NULL; + BIO *in = NULL; + unsigned char *first = NULL, *second = NULL; + size_t first_len = 0, second_len = 0; + int ret = 0; + + if (!TEST_true(encode_pkey(pkey, selection, structure, format, &first, + &first_len))) + goto end; + + /* + * Decode from a separate read only BIO. Resetting the BIO written to + * by the encoder would discard the encoding rather than rewind it. + */ + if (!TEST_ptr(in = BIO_new_mem_buf(first, (int)first_len)) + || !TEST_ptr(dctx = OSSL_DECODER_CTX_new_for_pkey(&decoded, format, + structure, NULL, selection, NULL, NULL)) + || !TEST_true(OSSL_DECODER_from_bio(dctx, in)) + || !TEST_ptr(decoded)) + goto end; + + if (!TEST_true(encode_pkey(decoded, selection, structure, format, &second, + &second_len))) + goto end; + + ret = TEST_mem_eq(first, first_len, second, second_len); + +end: + OPENSSL_free(first); + OPENSSL_free(second); + EVP_PKEY_free(decoded); + OSSL_DECODER_CTX_free(dctx); + BIO_free(in); + return ret; +} + +/** + * @brief Render a key as text, as the genpkey -text option does. + * + * @param pkey the key or parameter set to print + * @param params_only 1 if pkey holds parameters only, 0 if it holds a key + * @returns 1 on success, 0 on failure + */ +static int print_ec(EVP_PKEY *pkey, int params_only) +{ + BIO *bio = NULL; + int ret = 0; + + if (!TEST_ptr(bio = BIO_new(BIO_s_null()))) + return 0; + + if (params_only) + ret = TEST_int_gt(EVP_PKEY_print_params(bio, pkey, 0, NULL), 0); + else + ret = TEST_int_gt(EVP_PKEY_print_private(bio, pkey, 0, NULL), 0); + + BIO_free(bio); + return ret; +} + +/** + * @brief Generate parameters on one curve in every supported encoding. + * + * @param idx the index into the curve table + * @returns 1 on success, 0 on failure + */ +static int test_genec_params(int idx) +{ + const char *curve = curves[idx]; + EVP_PKEY *pkey = NULL; + size_t i, j; + int ret = 0; + + for (i = 0; i < OSSL_NELEM(param_encodings); i++) { + EVP_PKEY_free(pkey); + pkey = NULL; + + if (!TEST_ptr(pkey = gen_ec(curve, param_encodings[i], 1)) + || !print_ec(pkey, 1)) + goto end; + + for (j = 0; j < OSSL_NELEM(formats); j++) + if (!round_trip(pkey, EVP_PKEY_KEY_PARAMETERS, "type-specific", + formats[j])) + goto end; + } + ret = 1; + +end: + if (ret == 0) + TEST_info("EC parameter generation failed for curve %s", curve); + EVP_PKEY_free(pkey); + return ret; +} + +/** + * @brief Generate a key on one curve in every supported encoding. + * + * @param idx the index into the curve table + * @returns 1 on success, 0 on failure + */ +static int test_genec_key(int idx) +{ + const char *curve = curves[idx]; + EVP_PKEY *pkey = NULL; + size_t i, j; + int ret = 0; + + for (i = 0; i < OSSL_NELEM(param_encodings); i++) { + EVP_PKEY_free(pkey); + pkey = NULL; + + if (!TEST_ptr(pkey = gen_ec(curve, param_encodings[i], 0)) + || !print_ec(pkey, 0)) + goto end; + + for (j = 0; j < OSSL_NELEM(formats); j++) + if (!round_trip(pkey, EVP_PKEY_KEYPAIR, "PrivateKeyInfo", + formats[j]) + || !round_trip(pkey, EVP_PKEY_PUBLIC_KEY, + "SubjectPublicKeyInfo", formats[j])) + goto end; + } + ret = 1; + +end: + if (ret == 0) + TEST_info("EC key generation failed for curve %s", curve); + EVP_PKEY_free(pkey); + return ret; +} + +#if !defined(OPENSSL_NO_EC2M) +/** + * @brief Check a curve that only supports an explicit parameter encoding. + * + * Generation itself succeeds for either encoding; it is the structured + * encoding of a named curve that must be refused, because the curve has + * no OID to name it by. + * + * @param idx the index into the explicit only curve table + * @returns 1 on success, 0 on failure + */ +static int test_genec_explicit_only(int idx) +{ + const char *curve = explicit_only_curves[idx]; + EVP_PKEY *pkey = NULL; + unsigned char *enc = NULL; + size_t enc_len = 0, j; + int ret = 0; + + if (!TEST_ptr(pkey = gen_ec(curve, "named_curve", 1))) + goto end; + + for (j = 0; j < OSSL_NELEM(formats); j++) { + ERR_set_mark(); + ret = encode_pkey(pkey, EVP_PKEY_KEY_PARAMETERS, "type-specific", + formats[j], &enc, &enc_len); + ERR_pop_to_mark(); + OPENSSL_free(enc); + enc = NULL; + if (!TEST_false(ret)) { + ret = 0; + goto end; + } + } + ret = 0; + + EVP_PKEY_free(pkey); + if (!TEST_ptr(pkey = gen_ec(curve, "explicit", 1)) + || !print_ec(pkey, 1)) + goto end; + + for (j = 0; j < OSSL_NELEM(formats); j++) + if (!round_trip(pkey, EVP_PKEY_KEY_PARAMETERS, "type-specific", + formats[j])) + goto end; + ret = 1; + +end: + if (ret == 0) + TEST_info("explicit only curve %s failed", curve); + OPENSSL_free(enc); + EVP_PKEY_free(pkey); + return ret; +} +#endif /* !defined(OPENSSL_NO_EC2M) */ + +/** + * @brief Check that an unknown curve name is rejected. + * + * @returns 1 on success, 0 on failure + */ +static int test_genec_unknown_curve(void) +{ + EVP_PKEY *pkey; + + ERR_set_mark(); + pkey = gen_ec("bogus_foobar_curve", "named_curve", 1); + ERR_pop_to_mark(); + + if (!TEST_ptr_null(pkey)) { + EVP_PKEY_free(pkey); + return 0; + } + return 1; +} + +int setup_tests(void) +{ + ADD_ALL_TESTS(test_genec_params, OSSL_NELEM(curves)); + ADD_ALL_TESTS(test_genec_key, OSSL_NELEM(curves)); +#if !defined(OPENSSL_NO_EC2M) + ADD_ALL_TESTS(test_genec_explicit_only, OSSL_NELEM(explicit_only_curves)); +#endif /* !defined(OPENSSL_NO_EC2M) */ + ADD_TEST(test_genec_unknown_curve); + return 1; +} diff --git a/test/generate_ssl_tests.pl b/test/generate_ssl_tests.pl index f1c8027fb847b..2d9676d7361f5 100644 --- a/test/generate_ssl_tests.pl +++ b/test/generate_ssl_tests.pl @@ -140,6 +140,7 @@ sub read_config { my $fips_mode = $provider eq "fips"; local $ssltests::fips_3_4 = 0; local $ssltests::fips_3_5 = 0; + local $ssltests::fips_4_2 = 0; if ($fips_mode) { my $provconf = srctop_file("test", "fips-and-base.cnf"); @@ -148,9 +149,14 @@ sub read_config { run(test(["fips_version_test", "-config", $provconf, ">=3.4.0"]), capture => 1, statusvar => \$exit); $ssltests::fips_3_4 = $exit; + run(test(["fips_version_test", "-config", $provconf, ">=3.5.0"]), capture => 1, statusvar => \$exit); $ssltests::fips_3_5 = $exit; + + run(test(["fips_version_test", "-config", $provconf, ">=4.2.0"]), + capture => 1, statusvar => \$exit); + $ssltests::fips_4_2 = $exit; } local $ssltests::fips_mode = $fips_mode; diff --git a/test/handshake-memfail.c b/test/handshake-memfail.c index 7c560806ceb54..e189027d60e43 100644 --- a/test/handshake-memfail.c +++ b/test/handshake-memfail.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/helpers/handshake.c b/test/helpers/handshake.c index 6f7f7f9d21638..a974aeab01960 100644 --- a/test/helpers/handshake.c +++ b/test/helpers/handshake.c @@ -1816,13 +1816,13 @@ static HANDSHAKE_RESULT *do_handshake_internal( *serv_sess_out = SSL_SESSION_dup(tmp); } - if (SSL_get_peer_tmp_key(client.ssl, &tmp_key)) { + ret->tmp_key_type = SSL_get_negotiated_group(client.ssl); + if (ret->tmp_key_type == NID_undef + && SSL_get_peer_tmp_key(client.ssl, &tmp_key)) { ret->tmp_key_type = pkey_type(tmp_key); EVP_PKEY_free(tmp_key); if (ret->tmp_key_type == EVP_PKEY_KEYMGMT) ret->tmp_key_type = SSL_get_negotiated_group(client.ssl); - } else { - ret->tmp_key_type = SSL_get_negotiated_group(client.ssl); } SSL_get_peer_signature_nid(client.ssl, &ret->server_sign_hash); diff --git a/test/helpers/pkcs12.c b/test/helpers/pkcs12.c index abc70db1b7697..00965686ddb05 100644 --- a/test/helpers/pkcs12.c +++ b/test/helpers/pkcs12.c @@ -468,21 +468,21 @@ static int check_asn1_string(const ASN1_TYPE *av, const char *txt) switch (av->type) { case V_ASN1_BMPSTRING: value = OPENSSL_uni2asc(ASN1_STRING_get0_data(av->value.bmpstring), - ASN1_STRING_length(av->value.bmpstring)); + (int)ASN1_STRING_get_length(av->value.bmpstring)); if (!TEST_str_eq(txt, (char *)value)) goto err; break; case V_ASN1_UTF8STRING: if (!TEST_mem_eq(txt, strlen(txt), ASN1_STRING_get0_data(av->value.utf8string), - ASN1_STRING_length(av->value.utf8string))) + ASN1_STRING_get_length(av->value.utf8string))) goto err; break; case V_ASN1_OCTET_STRING: if (!TEST_mem_eq(txt, strlen(txt), (char *)ASN1_STRING_get0_data(av->value.octet_string), - ASN1_STRING_length(av->value.octet_string))) + ASN1_STRING_get_length(av->value.octet_string))) goto err; break; diff --git a/test/helpers/predefined_dhparams.c b/test/helpers/predefined_dhparams.c index 0fb7853d5c25f..8690d3eccd53c 100644 --- a/test/helpers/predefined_dhparams.c +++ b/test/helpers/predefined_dhparams.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/helpers/quictestlib.c b/test/helpers/quictestlib.c index 5405df6ebf3ed..7c0fbca84d6c9 100644 --- a/test/helpers/quictestlib.c +++ b/test/helpers/quictestlib.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -311,6 +311,8 @@ int qtest_create_quic_objects(OSSL_LIB_CTX *libctx, SSL_CTX *clientctx, } SSL_set_bio(*cssl, cbio, cbio); + /* Ownership of cbio is now held by *cssl */ + cbio = NULL; if (!TEST_true(SSL_set_blocking_mode(*cssl, (flags & QTEST_FLAG_BLOCK) != 0 ? 1 : 0))) @@ -1374,3 +1376,314 @@ int bio_msg_copy(BIO_MSG *dst, BIO_MSG *src) return 1; } + +static const unsigned char alpn[] = { + 8, 'o', 's', 's', 'l', 't', 'e', 's', 't' +}; + +static int select_alpn(SSL *ssl, const unsigned char **out, unsigned char *out_len, + const unsigned char *in, unsigned int in_len, void *arg) +{ + int e; + + e = SSL_select_next_proto((unsigned char **)out, out_len, alpn, sizeof(alpn), + in, in_len); + return (e == OPENSSL_NPN_NEGOTIATED) ? SSL_TLSEXT_ERR_OK : SSL_TLSEXT_ERR_ALERT_FATAL; +} + +int create_quic_ctx_pair(OSSL_LIB_CTX *libctx, SSL_CTX **c_sctx_p, SSL_CTX **s_sctx_p, + const char *certfile, const char *keyfile) +{ + int ok = 0; + SSL_CTX *c_sctx, *s_sctx; + + c_sctx = NULL; + s_sctx = NULL; + c_sctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()); + if (!TEST_ptr(c_sctx)) { + TEST_info("%s SSL_CTX_new_ex(OSSL_QUIC_client_method()) failed", OPENSSL_FUNC); + goto done; + } + + s_sctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_server_method()); + if (!TEST_ptr(s_sctx)) { + TEST_info("%s SSL_CTX_new_ex(OSSL_QUIC_server_method()) failed", OPENSSL_FUNC); + goto done; + } + + ok = SSL_CTX_use_certificate_file(s_sctx, certfile, SSL_FILETYPE_PEM); + if (ok != 1) { + TEST_info("%s SSL_CTX_use_certificate_file(%s) failed", OPENSSL_FUNC, certfile); + ok = 0; + goto done; + } + + ok = SSL_CTX_use_PrivateKey_file(s_sctx, keyfile, SSL_FILETYPE_PEM); + if (ok != 1) { + TEST_info("%s SSL_CTX_use_PrivateKey_file(%s) failed", OPENSSL_FUNC, keyfile); + ok = 0; + goto done; + } + SSL_CTX_set_alpn_select_cb(s_sctx, select_alpn, NULL); + + *c_sctx_p = c_sctx; + c_sctx = NULL; + *s_sctx_p = s_sctx; + s_sctx = NULL; + +done: + SSL_CTX_free(c_sctx); + SSL_CTX_free(s_sctx); + + return ok; +} + +static int create_dgram_pair(BIO **c_bio_p, BIO **s_bio_p) +{ + BIO *c_bio, *s_bio; + BIO_ADDR *localaddr = NULL; + struct in_addr ina; + int bio_flags = 0; + int ok; + + ina.s_addr = htonl(0x7f000001); + bio_flags |= BIO_DGRAM_CAP_HANDLES_DST_ADDR + | BIO_DGRAM_CAP_HANDLES_SRC_ADDR + | BIO_DGRAM_CAP_PROVIDES_DST_ADDR + | BIO_DGRAM_CAP_PROVIDES_SRC_ADDR; + + c_bio = NULL; + s_bio = NULL; + ok = BIO_new_bio_dgram_pair(&c_bio, 1500, &s_bio, 1500); + if (ok == 0) { + TEST_info("%s BIO_new_bio_dgram_pair() error", OPENSSL_FUNC); + goto done; + } + + ok = BIO_dgram_set_caps(c_bio, bio_flags); + if (ok == 0) { + TEST_info("%s BIO_dgram_set_caps(c_bio, bio_flags) failed", OPENSSL_FUNC); + goto done; + } + + ok = BIO_dgram_set_caps(s_bio, bio_flags); + if (ok == 0) { + TEST_info("%s BIO_dgram_set_caps(s_bio, bio_flags) failed", OPENSSL_FUNC); + goto done; + } + + ok = BIO_dgram_set_mtu(c_bio, 1500); + if (ok == 0) { + TEST_info("%s BIO_dgram_set_mtu(c_bio) error", OPENSSL_FUNC); + goto done; + } + + ok = BIO_dgram_set_mtu(s_bio, 1500); + if (ok == 0) { + TEST_info("%s BIO_dgram_set_mtu(s_bio) error", OPENSSL_FUNC); + goto done; + } + + localaddr = BIO_ADDR_new(); + if (!TEST_ptr(localaddr)) { + TEST_info("%s BIO_ADDR_new() error", OPENSSL_FUNC); + goto done; + } + ok = BIO_ADDR_rawmake(localaddr, AF_INET, &ina, sizeof(ina), htons(4080)); + if (ok == 0) { + TEST_info("%s BIO_ADDR_rawmake(4080) error", OPENSSL_FUNC); + goto done; + } + ok = BIO_dgram_set0_local_addr(c_bio, localaddr); + if (ok != 1) { + TEST_info("%s BIO_dgram_set0_local_addr(c_bio)", OPENSSL_FUNC); + ok = 0; + goto done; + } + + localaddr = BIO_ADDR_new(); + if (!TEST_ptr(localaddr)) { + TEST_info("%s BIO_ADDR_new() error", OPENSSL_FUNC); + goto done; + } + ok = BIO_ADDR_rawmake(localaddr, AF_INET, &ina, sizeof(ina), htons(8040)); + if (ok == 0) { + TEST_info("%s BIO_ADDR_rawmake(8040) error", OPENSSL_FUNC); + goto done; + } + ok = BIO_dgram_set0_local_addr(s_bio, localaddr); + if (ok != 1) { + TEST_info("%s BIO_dgram_set0_local_addr(c_bio)", OPENSSL_FUNC); + ok = 0; + goto done; + } + localaddr = NULL; + + ok = BIO_dgram_set_local_addr_enable(c_bio, 1); + if (ok == 0) { + TEST_info("%s BIO_dgram_set_local_addr_enable(c_bio)", OPENSSL_FUNC); + goto done; + } + + ok = BIO_dgram_set_local_addr_enable(s_bio, 1); + if (ok == 0) { + TEST_info("%s BIO_dgram_set_local_addr_enable(s_bio)", OPENSSL_FUNC); + goto done; + } + + *c_bio_p = c_bio; + c_bio = NULL; + *s_bio_p = s_bio; + s_bio = NULL; + +done: + BIO_free(c_bio); + BIO_free(s_bio); + BIO_ADDR_free(localaddr); + + return ok; +} + +static int init_client(SSL *c_ssl) +{ + BIO_ADDR *peer_addr = NULL; + struct in_addr ina; + int ok = 0; + + ina.s_addr = htonl(0x7f000001); + + ok = SSL_set_tlsext_host_name(c_ssl, "localhost"); + if (ok == 0) { + TEST_info("%s SSL_set_tlsext_host_name()", OPENSSL_FUNC); + goto done; + } + + ok = SSL_set1_dnsname(c_ssl, "localhost"); + if (ok == 0) { + TEST_info("%s SSL_set1_dnsname()", OPENSSL_FUNC); + goto done; + } + + ok = SSL_set_alpn_protos(c_ssl, alpn, sizeof(alpn)); + if (ok != 0) { + TEST_info("%s SSL_set_alpn_protos() failed", OPENSSL_FUNC); + ok = 0; + goto done; + } + + ok = SSL_set_blocking_mode(c_ssl, 0); + if (ok == 0) { + TEST_info("%s SSL_set_block_mode() failed", OPENSSL_FUNC); + goto done; + } + + peer_addr = BIO_ADDR_new(); + if (!TEST_ptr(peer_addr)) { + TEST_info("%s BIO_ADDR_new() failed", OPENSSL_FUNC); + goto done; + } + ok = BIO_ADDR_rawmake(peer_addr, AF_INET, &ina, sizeof(ina), htons(8040)); + if (ok == 0) { + TEST_info("%s BIO_ADDR_rawmake() failed", OPENSSL_FUNC); + goto done; + } + ok = SSL_set1_initial_peer_addr(c_ssl, peer_addr); + if (ok == 0) { + TEST_info("%s SSL_set1_initial_peer_addr() failed", OPENSSL_FUNC); + goto done; + } + +done: + BIO_ADDR_free(peer_addr); + + return ok; +} + +int create_quic_conn_objects(SSL_CTX *c_sctx, SSL_CTX *s_sctx, SSL **c_ssl_p, SSL **s_ssl_p) +{ + BIO *c_bio = NULL, *s_bio = NULL; + SSL *c_ssl = NULL, *s_ssl = NULL; + int ok; + + ok = create_dgram_pair(&c_bio, &s_bio); + if (ok == 0) + goto done; + + c_ssl = SSL_new(c_sctx); + if (!TEST_ptr(c_ssl)) { + TEST_info("%s SSL_new(c_sctx) failed", OPENSSL_FUNC); + ok = 0; + goto done; + } + + ok = init_client(c_ssl); + if (ok == 0) + goto done; + + s_ssl = SSL_new_listener(s_sctx, 0); + if (!TEST_ptr(s_ssl)) { + TEST_info("%s SSL_new_listener() failed", OPENSSL_FUNC); + ok = 0; + goto done; + } + + SSL_set_bio(c_ssl, c_bio, c_bio); + SSL_set_bio(s_ssl, s_bio, s_bio); + c_bio = NULL; + s_bio = NULL; + + ok = SSL_set_blocking_mode(s_ssl, 0); + if (ok == 0) { + TEST_info("%s SSL_set_blocking_mode() failed", OPENSSL_FUNC); + ok = 0; + goto done; + } + + *c_ssl_p = c_ssl; + c_ssl = NULL; + *s_ssl_p = s_ssl; + s_ssl = NULL; + +done: + BIO_free(c_bio); + BIO_free(s_bio); + SSL_free(c_ssl); + SSL_free(s_ssl); + + return ok; +} + +SSL *create_quic_client(SSL_CTX *c_sctx, BIO *c_bio) +{ + SSL *c_ssl; + + if (!TEST_ptr(c_bio)) + return NULL; + + c_ssl = SSL_new(c_sctx); + if (!TEST_ptr(c_ssl)) { + TEST_info("%s SSL_new(c_sctx) failed", OPENSSL_FUNC); + return NULL; + } + + if (BIO_up_ref(c_bio) == 0) { + TEST_info("%s BIO_up_ref() failed)", OPENSSL_FUNC); + goto error; + } + SSL_set_bio(c_ssl, c_bio, c_bio); + + if (init_client(c_ssl) == 0) + goto error; + + if (SSL_set_blocking_mode(c_ssl, 0) == 0) { + TEST_info("%s SSL_set_blocking_mode() failed", OPENSSL_FUNC); + goto error; + } + + return c_ssl; + +error: + SSL_free(c_ssl); + + return NULL; +} diff --git a/test/helpers/quictestlib.h b/test/helpers/quictestlib.h index 63c77f90b78be..c03bfac78fec9 100644 --- a/test/helpers/quictestlib.h +++ b/test/helpers/quictestlib.h @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -289,3 +289,7 @@ const BIO_METHOD *bio_f_pkt_split_dgram_filter(void); /* Free the BIO filter method object */ void bio_f_pkt_split_dgram_filter_free(void); + +int create_quic_ctx_pair(OSSL_LIB_CTX *libctx, SSL_CTX **c_sctx_p, SSL_CTX **s_sctx_p, const char *certfile, const char *keyfile); +int create_quic_conn_objects(SSL_CTX *c_sctx, SSL_CTX *s_ctx, SSL **c_ssl_p, SSL **s_ssl_p); +SSL *create_quic_client(SSL_CTX *c_sctx, BIO *c_bio); diff --git a/test/helpers/ssl_test_ctx.c b/test/helpers/ssl_test_ctx.c index 321d1a378a9a4..0997f93a0d6ed 100644 --- a/test/helpers/ssl_test_ctx.c +++ b/test/helpers/ssl_test_ctx.c @@ -56,7 +56,8 @@ static int parse_boolean(const char *value, int *result) #define IMPLEMENT_SSL_TEST_INT_OPTION(struct_type, name, field) \ static int parse_##name##_##field(struct_type *ctx, const char *value) \ { \ - ctx->field = atoi(value); \ + if (!test_strtoint(value, &ctx->field)) \ + ctx->field = 0; \ return 1; \ } @@ -158,6 +159,7 @@ static const test_enum ssl_protocols[] = { { "TLSv1", TLS1_VERSION }, { "DTLSv1", DTLS1_VERSION }, { "DTLSv1.2", DTLS1_2_VERSION }, + { "DTLSv1.3", DTLS1_3_VERSION }, }; __owur static int parse_protocol(SSL_TEST_CTX *test_ctx, const char *value) @@ -532,23 +534,27 @@ __owur static int parse_expected_key_type(int *ptype, const char *value) */ if (strcmp("RSA", value) == 0) { nid = OBJ_ln2nid("rsaEncryption"); - } else if (strcmp("RSA-PSS", value) == 0) { + } else if (OPENSSL_strcasecmp("RSA-PSS", value) == 0) { nid = OBJ_ln2nid("rsassaPss"); - } else if (strcmp("Ed448", value) == 0) { + } else if (OPENSSL_strcasecmp("Ed448", value) == 0) { nid = OBJ_sn2nid("ED448"); - } else if (strcmp("Ed25519", value) == 0) { + } else if (OPENSSL_strcasecmp("Ed25519", value) == 0) { nid = OBJ_sn2nid("ED25519"); - } else if (strcmp("EC", value) == 0) { + } else if (OPENSSL_strcasecmp("EC", value) == 0) { nid = OBJ_sn2nid("id-ecPublicKey"); - } else if (strcmp("curveSM2", value) == 0) { + } else if (OPENSSL_strcasecmp("curveSM2", value) == 0) { nid = TLSEXT_nid_unknown | OSSL_TLS_GROUP_ID_curveSM2; - } else if (strcmp("X25519MLKEM768", value) == 0) { + } else if (OPENSSL_strcasecmp("MLKEM512X25519", value) == 0) { + nid = TLSEXT_nid_unknown | OSSL_TLS_GROUP_ID_MLKEM512X25519; + } else if (OPENSSL_strcasecmp("X25519MLKEM768", value) == 0) { nid = TLSEXT_nid_unknown | OSSL_TLS_GROUP_ID_X25519MLKEM768; - } else if (strcmp("SecP256r1MLKEM768", value) == 0) { + } else if (OPENSSL_strcasecmp("SecP256r1MLKEM512", value) == 0) { + nid = TLSEXT_nid_unknown | OSSL_TLS_GROUP_ID_SecP256r1MLKEM512; + } else if (OPENSSL_strcasecmp("SecP256r1MLKEM768", value) == 0) { nid = TLSEXT_nid_unknown | OSSL_TLS_GROUP_ID_SecP256r1MLKEM768; - } else if (strcmp("SecP384r1MLKEM1024", value) == 0) { + } else if (OPENSSL_strcasecmp("SecP384r1MLKEM1024", value) == 0) { nid = TLSEXT_nid_unknown | OSSL_TLS_GROUP_ID_SecP384r1MLKEM1024; - } else if (strcmp("curveSM2MLKEM768", value) == 0) { + } else if (OPENSSL_strcasecmp("curveSM2MLKEM768", value) == 0) { nid = TLSEXT_nid_unknown | OSSL_TLS_GROUP_ID_curveSM2MLKEM768; } else { nid = OBJ_ln2nid(value); @@ -560,17 +566,6 @@ __owur static int parse_expected_key_type(int *ptype, const char *value) if (nid == NID_undef) nid = EC_curve_nist2nid(value); #endif - switch (nid) { - case NID_brainpoolP256r1tls13: - nid = NID_brainpoolP256r1; - break; - case NID_brainpoolP384r1tls13: - nid = NID_brainpoolP384r1; - break; - case NID_brainpoolP512r1tls13: - nid = NID_brainpoolP512r1; - break; - } if (nid == NID_undef) return 0; *ptype = nid; diff --git a/test/helpers/ssltestlib.c b/test/helpers/ssltestlib.c index 57b8c3e0403cb..c2978127916af 100644 --- a/test/helpers/ssltestlib.c +++ b/test/helpers/ssltestlib.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -34,11 +34,13 @@ static int tls_dump_puts(BIO *bp, const char *str); #define BIO_TYPE_MEMPACKET_TEST 0x81 #define BIO_TYPE_ALWAYS_RETRY 0x82 #define BIO_TYPE_MAYBE_RETRY (0x83 | BIO_TYPE_FILTER) +#define BIO_TYPE_NO_RETRY_ZERO (0x84 | BIO_TYPE_FILTER) static BIO_METHOD *method_tls_dump = NULL; static BIO_METHOD *meth_mem = NULL; static BIO_METHOD *meth_always_retry = NULL; static BIO_METHOD *meth_maybe_retry = NULL; +static BIO_METHOD *meth_no_retry_zero = NULL; static int retry_err = -1; /* Note: Not thread safe! */ @@ -111,6 +113,27 @@ static void copy_flags(BIO *bio) #define MSG_FRAG_LEN_MID 10 #define MSG_FRAG_LEN_LO 11 +/* Returns true if the unified header fixed bits are set (rfc9147 section 4) */ +#define DTLS13_UNI_HDR_FIX_BITS_IS_SET(byte) \ + (((byte) & DTLS13_UNI_HDR_FIX_BITS_MASK) == DTLS13_UNI_HDR_FIX_BITS) + +/* Returns true if the unified header connection id bit is set (rfc9147 section 4) */ +#define DTLS13_UNI_HDR_CID_BIT_IS_SET(byte) \ + (((byte) & DTLS13_UNI_HDR_CID_BIT) == DTLS13_UNI_HDR_CID_BIT) + +/* Returns true if the unified header sequence number bit is set (rfc9147 section 4) */ +#define DTLS13_UNI_HDR_SEQ_BIT_IS_SET(byte) \ + (((byte) & DTLS13_UNI_HDR_SEQ_BIT) == DTLS13_UNI_HDR_SEQ_BIT) + +/* Returns true if the unified header length bit is set (rfc9147 section 4) */ +#define DTLS13_UNI_HDR_LEN_BIT_IS_SET(byte) \ + (((byte) & DTLS13_UNI_HDR_LEN_BIT) == DTLS13_UNI_HDR_LEN_BIT) + +#define DTLS13_UNI_HDR_RECORD_SEQ_HI 1 +#define DTLS13_UNI_HDR_RECORD_SEQ_LO 2 +#define DTLS13_UNI_HDR_RECORD_LEN_HI 3 +#define DTLS13_UNI_HDR_RECORD_LEN_LO 4 + static void dump_data(const char *data, int len) { int rem, i, content, reclen, msglen, fragoff, fraglen, epoch; @@ -122,28 +145,51 @@ static void dump_data(const char *data, int len) rec = (unsigned char *)data; while (rem > 0) { + int rechdrlen; + + if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(*rec)) + rechdrlen = DTLS13_UNI_HDR_FIXED_LENGTH; + else + rechdrlen = DTLS1_RT_HEADER_LENGTH; + if (rem != len) printf("*\n"); printf("*---- START OF RECORD ----\n"); - if (rem < DTLS1_RT_HEADER_LENGTH) { + if (rem < rechdrlen) { printf("*---- RECORD TRUNCATED ----\n"); break; } - content = rec[RECORD_CONTENT_TYPE]; - printf("** Record Content-type: %d\n", content); - printf("** Record Version: %02x%02x\n", - rec[RECORD_VERSION_HI], rec[RECORD_VERSION_LO]); - epoch = (rec[RECORD_EPOCH_HI] << 8) | rec[RECORD_EPOCH_LO]; - printf("** Record Epoch: %d\n", epoch); - printf("** Record Sequence: "); - for (i = RECORD_SEQUENCE_START; i <= RECORD_SEQUENCE_END; i++) - printf("%02x", rec[i]); - reclen = (rec[RECORD_LEN_HI] << 8) | rec[RECORD_LEN_LO]; - printf("\n** Record Length: %d\n", reclen); - + if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(*rec)) { + content = SSL3_RT_APPLICATION_DATA; + printf("** Encrypted DTLS 1.3 Record Content\n"); + epoch = *rec & DTLS13_UNI_HDR_EPOCH_BITS_MASK; + + if (epoch == 0) + epoch = 4; + + printf("** Record Epoch: %d\n", epoch); + printf("** Record Sequence: "); + for (i = DTLS13_UNI_HDR_RECORD_SEQ_HI; i <= DTLS13_UNI_HDR_RECORD_SEQ_LO; i++) + printf("%02x", rec[i]); + reclen = (rec[DTLS13_UNI_HDR_RECORD_LEN_HI] << 8) + | rec[DTLS13_UNI_HDR_RECORD_LEN_LO]; + printf("\n** Record Length: %d\n", reclen); + } else { + content = rec[RECORD_CONTENT_TYPE]; + printf("** Record Content-type: %d\n", content); + printf("** Record Version: %02x%02x\n", + rec[RECORD_VERSION_HI], rec[RECORD_VERSION_LO]); + epoch = (rec[RECORD_EPOCH_HI] << 8) | rec[RECORD_EPOCH_LO]; + printf("** Record Epoch: %d\n", epoch); + printf("** Record Sequence: "); + for (i = RECORD_SEQUENCE_START; i <= RECORD_SEQUENCE_END; i++) + printf("%02x", rec[i]); + reclen = (rec[RECORD_LEN_HI] << 8) | rec[RECORD_LEN_LO]; + printf("\n** Record Length: %d\n", reclen); + } /* Now look at message */ - rec += DTLS1_RT_HEADER_LENGTH; - rem -= DTLS1_RT_HEADER_LENGTH; + rec += rechdrlen; + rem -= rechdrlen; if (content == SSL3_RT_HANDSHAKE) { printf("**---- START OF HANDSHAKE MESSAGE FRAGMENT ----\n"); if (epoch > 0) { @@ -328,13 +374,6 @@ static int mempacket_test_free(BIO *bio) return 1; } -/* Record Header values */ -#define EPOCH_HI 3 -#define EPOCH_LO 4 -#define RECORD_SEQUENCE 10 -#define RECORD_LEN_HI 11 -#define RECORD_LEN_LO 12 - #define STANDARD_PACKET 0 static int mempacket_test_read(BIO *bio, char *out, int outl) @@ -342,8 +381,7 @@ static int mempacket_test_read(BIO *bio, char *out, int outl) MEMPACKET_TEST_CTX *ctx = BIO_get_data(bio); MEMPACKET *thispkt; unsigned char *rec; - int rem; - unsigned int seq, offset, len, epoch; + unsigned int seq, offset, len, epoch, rem; BIO_clear_retry_flags(bio); if ((thispkt = sk_MEMPACKET_value(ctx->pkts, 0)) == NULL @@ -367,27 +405,48 @@ static int mempacket_test_read(BIO *bio, char *out, int outl) * with any packets that have been injected */ for (rem = thispkt->len, rec = thispkt->data; rem > 0; rem -= len) { - if (rem < DTLS1_RT_HEADER_LENGTH) + unsigned int rechdrlen; + + if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(*rec)) + rechdrlen = DTLS13_UNI_HDR_FIXED_LENGTH; + else + rechdrlen = DTLS1_RT_HEADER_LENGTH; + + if (rem < rechdrlen) return -1; - epoch = (rec[EPOCH_HI] << 8) | rec[EPOCH_LO]; + + if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(*rec)) + /* We don't expect epochs higher than 3 */ + epoch = *rec & DTLS13_UNI_HDR_EPOCH_BITS_MASK; + else + epoch = (rec[RECORD_EPOCH_HI] << 8) | rec[RECORD_EPOCH_LO]; + if (epoch != ctx->epoch) { ctx->epoch = epoch; ctx->currrec = 0; } seq = ctx->currrec; offset = 0; - do { - rec[RECORD_SEQUENCE - offset] = seq & 0xFF; - seq >>= 8; - offset++; - } while (seq > 0); - - len = ((rec[RECORD_LEN_HI] << 8) | rec[RECORD_LEN_LO]) - + DTLS1_RT_HEADER_LENGTH; - if (rem < (int)len) + if (!DTLS13_UNI_HDR_FIX_BITS_IS_SET(*rec)) { + do { + rec[RECORD_SEQUENCE_END - offset] = seq & 0xFF; + seq >>= 8; + offset++; + } while (seq > 0); + } + + if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(*rec)) + len = (rec[DTLS13_UNI_HDR_RECORD_LEN_HI] << 8) + | rec[DTLS13_UNI_HDR_RECORD_LEN_LO]; + else + len = (rec[RECORD_LEN_HI] << 8) | rec[RECORD_LEN_LO]; + + len += rechdrlen; + + if (rem < len) return -1; if (ctx->droprec == (int)ctx->currrec && ctx->dropepoch == epoch) { - if (rem > (int)len) + if (rem > len) memmove(rec, rec + len, rem - len); outl -= len; ctx->droprec = -1; @@ -431,11 +490,28 @@ int mempacket_swap_epoch(BIO *bio) return 0; for (rem = thispkt->len, rec = thispkt->data; rem > 0; rem -= len, rec += len) { - if (rem < DTLS1_RT_HEADER_LENGTH) + int rechdrlen; + + if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(*rec)) + rechdrlen = DTLS13_UNI_HDR_FIXED_LENGTH; + else + rechdrlen = DTLS1_RT_HEADER_LENGTH; + + if (rem < rechdrlen) return 0; - epoch = (rec[EPOCH_HI] << 8) | rec[EPOCH_LO]; - len = ((rec[RECORD_LEN_HI] << 8) | rec[RECORD_LEN_LO]) - + DTLS1_RT_HEADER_LENGTH; + if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(*rec)) { + epoch = *rec & DTLS13_UNI_HDR_EPOCH_BITS_MASK; + + if (epoch == 0) + epoch = 4; + + len = ((rec[DTLS13_UNI_HDR_RECORD_LEN_HI] << 8) + | rec[DTLS13_UNI_HDR_RECORD_LEN_LO]); + len += rechdrlen; + } else { + epoch = (rec[RECORD_EPOCH_HI] << 8) | rec[RECORD_EPOCH_LO]; + len = ((rec[RECORD_LEN_HI] << 8) | rec[RECORD_LEN_LO]) + rechdrlen; + } if (rem < len) return 0; @@ -489,6 +565,107 @@ int mempacket_swap_epoch(BIO *bio) return 0; } +/* + * Look for records from different epochs in the last datagram and swap them + * around + */ +int mempacket_swap_epoch_dtls13(BIO *bio) +{ + MEMPACKET_TEST_CTX *ctx = BIO_get_data(bio); + MEMPACKET *thispkt; + int rem, len, prevlen = 0; + unsigned char *rec, *prevrec = NULL, *tmp; + unsigned int epoch; + int numpkts = sk_MEMPACKET_num(ctx->pkts); + + if (numpkts <= 0) + return 0; + + /* + * We need to look at the packet that contains the last Epoch 0 and the + * first Epoch 1 record. This is in Packet 5. + */ + thispkt = sk_MEMPACKET_value(ctx->pkts, 5); + if (thispkt == NULL) + return 0; + + for (rem = thispkt->len, rec = thispkt->data; + rem > 0; rem -= len, rec += len) { + int rechdrlen; + + if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(*rec)) + rechdrlen = DTLS13_UNI_HDR_FIXED_LENGTH; + else + rechdrlen = DTLS1_RT_HEADER_LENGTH; + + if (rem < rechdrlen) + return 0; + if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(*rec)) { + epoch = *rec & DTLS13_UNI_HDR_EPOCH_BITS_MASK; + + if (epoch == 0) + epoch = 4; + + len = ((rec[DTLS13_UNI_HDR_RECORD_LEN_HI] << 8) + | rec[DTLS13_UNI_HDR_RECORD_LEN_LO]); + len += rechdrlen; + } else { + epoch = (rec[RECORD_EPOCH_HI] << 8) | rec[RECORD_EPOCH_LO]; + len = ((rec[RECORD_LEN_HI] << 8) | rec[RECORD_LEN_LO]) + rechdrlen; + } + if (rem < len) + return 0; + + /* Assumes the epoch change does not happen on the first record */ + if (epoch != ctx->epoch) { + if (prevrec == NULL) + return 0; + + /* + * We found 2 records with different epochs. Take a copy of the + * earlier record + */ + tmp = OPENSSL_malloc(prevlen); + if (tmp == NULL) + return 0; + + memcpy(tmp, prevrec, prevlen); + /* + * Move everything from this record onwards, including any trailing + * records, and overwrite the earlier record + */ + memmove(prevrec, rec, rem); + thispkt->len -= prevlen; + + /* + * Create a new packet for the earlier record that we took out and + * add it to the end of the packet list. + */ + thispkt = OPENSSL_malloc(sizeof(*thispkt)); + if (thispkt == NULL) { + OPENSSL_free(tmp); + return 0; + } + thispkt->type = INJECT_PACKET; + thispkt->data = tmp; + thispkt->len = prevlen; + thispkt->num = numpkts; + if (sk_MEMPACKET_insert(ctx->pkts, thispkt, numpkts) <= 0) { + OPENSSL_free(tmp); + OPENSSL_free(thispkt); + return 0; + } + /* We added a packet so increment lastpkt */ + ctx->lastpkt++; + return 1; + } + prevrec = rec; + prevlen = len; + } + + return 0; +} + /* Move packet from position s to position d in the list (d < s) */ int mempacket_move_packet(BIO *bio, int d, int s) { @@ -730,8 +907,24 @@ int mempacket_test_inject(BIO *bio, const char *in, int inl, int pktnum, MEMPACKET *thispkt = NULL, *looppkt, *nextpkt, *allpkts[3]; int i, duprec; const unsigned char *inu = (const unsigned char *)in; - size_t len = ((inu[RECORD_LEN_HI] << 8) | inu[RECORD_LEN_LO]) - + DTLS1_RT_HEADER_LENGTH; + size_t len; + + if (DTLS13_UNI_HDR_FIX_BITS_IS_SET(*in) + /* The following code does not handle connection ids */ + && ossl_assert(!DTLS13_UNI_HDR_CID_BIT_IS_SET(*in))) { + if (DTLS13_UNI_HDR_LEN_BIT_IS_SET(*in)) { + len = 3; /* 2 bytes for len field and 1 byte for record type */ + len += DTLS13_UNI_HDR_SEQ_BIT_IS_SET(*in) ? 2 : 1; + len += ((inu[DTLS13_UNI_HDR_RECORD_LEN_HI] << 8) + | inu[DTLS13_UNI_HDR_RECORD_LEN_LO]); + } else { + /* We assert that inl is the correct record length */ + len = inl; + } + } else { + len = ((inu[RECORD_LEN_HI] << 8) | inu[RECORD_LEN_LO]); + len += DTLS1_RT_HEADER_LENGTH; + } if (ctx == NULL) return -1; @@ -882,6 +1075,9 @@ static long mempacket_test_ctrl(BIO *bio, int cmd, long num, void *ptr) case MEMPACKET_CTRL_SET_DUPLICATE_REC: ctx->duprec = (int)num; break; + case BIO_CTRL_DGRAM_QUERY_MTU: + ret = 1500; + break; case BIO_CTRL_RESET: case BIO_CTRL_DUP: case BIO_CTRL_PUSH: @@ -1011,6 +1207,10 @@ static int maybe_retry_new(BIO *bi); static int maybe_retry_free(BIO *a); static int maybe_retry_write(BIO *b, const char *in, int inl); static long maybe_retry_ctrl(BIO *b, int cmd, long num, void *ptr); +static int no_retry_zero_new(BIO *bi); +static int no_retry_zero_free(BIO *a); +static int no_retry_zero_write(BIO *b, const char *in, int inl); +static long no_retry_zero_ctrl(BIO *b, int cmd, long num, void *ptr); const BIO_METHOD *bio_s_maybe_retry(void) { @@ -1097,6 +1297,61 @@ static long maybe_retry_ctrl(BIO *bio, int cmd, long num, void *ptr) } } +const BIO_METHOD *bio_s_no_retry_zero(void) +{ + if (meth_no_retry_zero == NULL) { + if (!TEST_ptr(meth_no_retry_zero = BIO_meth_new(BIO_TYPE_NO_RETRY_ZERO, + "No Retry Zero")) + || !TEST_true(BIO_meth_set_write(meth_no_retry_zero, + no_retry_zero_write)) + || !TEST_true(BIO_meth_set_ctrl(meth_no_retry_zero, + no_retry_zero_ctrl)) + || !TEST_true(BIO_meth_set_create(meth_no_retry_zero, + no_retry_zero_new)) + || !TEST_true(BIO_meth_set_destroy(meth_no_retry_zero, + no_retry_zero_free))) + return NULL; + } + return meth_no_retry_zero; +} + +void bio_s_no_retry_zero_free(void) +{ + BIO_meth_free(meth_no_retry_zero); +} + +static int no_retry_zero_new(BIO *bio) +{ + BIO_set_init(bio, 1); + return 1; +} + +static int no_retry_zero_free(BIO *bio) +{ + BIO_set_data(bio, NULL); + BIO_set_init(bio, 0); + return 1; +} + +static int no_retry_zero_write(BIO *bio, const char *in, int inl) +{ + BIO_clear_retry_flags(bio); + return 0; +} + +static long no_retry_zero_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + BIO *next = BIO_next(bio); + + switch (cmd) { + case BIO_CTRL_FLUSH: + return next == NULL ? 1 : BIO_ctrl(next, cmd, num, ptr); + + default: + return next == NULL ? 0 : BIO_ctrl(next, cmd, num, ptr); + } +} + int create_ssl_ctx_pair(OSSL_LIB_CTX *libctx, const SSL_METHOD *sm, const SSL_METHOD *cm, int min_proto_version, int max_proto_version, SSL_CTX **sctx, SSL_CTX **cctx, diff --git a/test/helpers/ssltestlib.h b/test/helpers/ssltestlib.h index 68a10b24bd1aa..caeca0abe8778 100644 --- a/test/helpers/ssltestlib.h +++ b/test/helpers/ssltestlib.h @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -59,6 +59,9 @@ void set_always_retry_err_val(int err); const BIO_METHOD *bio_s_maybe_retry(void); void bio_s_maybe_retry_free(void); +const BIO_METHOD *bio_s_no_retry_zero(void); +void bio_s_no_retry_zero_free(void); + /* Packet types - value 0 is reserved */ #define INJECT_PACKET 1 #define INJECT_PACKET_IGNORE_REC_SEQ 2 @@ -73,6 +76,8 @@ void bio_s_maybe_retry_free(void); #define MEMPACKET_CTRL_SET_DUPLICATE_REC (4 << 15) int mempacket_swap_epoch(BIO *bio); +int mempacket_swap_epoch_dtls13(BIO *bio); +int mempacket_iterate(BIO *bio); int mempacket_move_packet(BIO *bio, int d, int s); int mempacket_find_record(BIO *bio, int rectype, int hs_msg_type, int *pktidx, int *recidx); diff --git a/test/hmactest.c b/test/hmactest.c index 4d75a8d5f44b7..8f3574025f819 100644 --- a/test/hmactest.c +++ b/test/hmactest.c @@ -308,7 +308,7 @@ static char *pt(unsigned char *md, unsigned int len) if (md == NULL) return NULL; for (i = 0; i < len && (i + 1) * OSSL_HEX_CHARS_PER_BYTE < sizeof(buf); i++) - BIO_snprintf(buf + i * OSSL_HEX_CHARS_PER_BYTE, + snprintf(buf + i * OSSL_HEX_CHARS_PER_BYTE, OSSL_HEX_CHARS_PER_BYTE + 1, "%02x", md[i]); return buf; } diff --git a/test/hpke_test.c b/test/hpke_test.c index cd43c0e9a1dfd..f4e36419e8013 100644 --- a/test/hpke_test.c +++ b/test/hpke_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -1192,7 +1192,7 @@ static int test_hpke_suite_strs(void) for (kemind = 0; kemind != OSSL_NELEM(kem_str_list); kemind++) { for (kdfind = 0; kdfind != OSSL_NELEM(kdf_str_list); kdfind++) { for (aeadind = 0; aeadind != OSSL_NELEM(aead_str_list); aeadind++) { - BIO_snprintf(sstr, 128, "%s,%s,%s", kem_str_list[kemind], + snprintf(sstr, 128, "%s,%s,%s", kem_str_list[kemind], kdf_str_list[kdfind], aead_str_list[aeadind]); if (!TEST_true(OSSL_HPKE_str2suite(sstr, &stirred))) { if (verbose) diff --git a/test/http_test.c b/test/http_test.c index d122a454265f0..70921f5d8b40d 100644 --- a/test/http_test.c +++ b/test/http_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright Siemens AG 2020 * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -9,6 +9,7 @@ */ #include +#include #include #include #include @@ -165,7 +166,7 @@ static int test_http_method(int do_get, int do_txt, int suggested_status) int res = 0; int real_server = do_txt && 0; /* remove "&& 0" for using real server */ - BIO_snprintf(path, sizeof(path), "/%d%s", suggested_status, + snprintf(path, sizeof(path), "/%d%s", suggested_status, do_get > 1 ? "/will-be-redirected" : RPATH); if (do_txt) { content_type = "text/plain"; @@ -240,6 +241,82 @@ static int test_http_method(int do_get, int do_txt, int suggested_status) return res; } +static const struct { + const char *url; + const char *redirects[4]; + int success; +} redirect_tests[] = { + { "https://server/start", { "http://server/end" }, 0 }, + { "https://server/start", { "/relative", "http://server/end" }, 0 }, + { "http://server/start", + { "https://server/secure", "/relative", "http://server/end" }, 0 }, + { "http://server/start", { "/relative", "http://server/end" }, 1 }, + { "https://server/start", { "/relative", "https://server/end" }, 1 }, +}; + +/* Replace each flushed request with the next response, using a single mem BIO. */ +static long http_redirect_cb(BIO *bio, int oper, const char *argp, size_t len, + int cmd, long argl, int ret, size_t *processed) +{ + const char *const *redirect = (const char *const *)BIO_get_callback_arg(bio); + + if (oper != (BIO_CB_CTRL | BIO_CB_RETURN)) + return ret; + if (cmd == BIO_C_DO_STATE_MACHINE) + return 1; /* mock a successful connection */ + if (cmd != BIO_CTRL_FLUSH) + return ret; + if (!TEST_int_eq(BIO_reset(bio), 1)) + return 0; + if (*redirect != NULL) { + BIO_set_callback_arg(bio, (char *)(redirect + 1)); + return BIO_printf(bio, "HTTP/1.0 302 Found\r\nLocation: %s\r\n\r\n", + *redirect) + > 0; + } + return BIO_puts(bio, "HTTP/1.0 200 OK\r\nContent-Length: 5\r\n\r\n" text1) > 0; +} + +/* The redirect policy uses the requested protocol; no actual TLS is needed. */ +static BIO *http_noop_update(BIO *bio, void *arg, int connect, int detail) +{ + return bio; +} + +static int test_http_redirect(int idx) +{ + BIO *bio = BIO_new(BIO_s_mem()); + BIO *rsp = NULL; + char buf[sizeof(text1)]; + unsigned long err; + int res = 0; + + if (!TEST_ptr(bio)) + goto end; + BIO_set_callback_ex(bio, http_redirect_cb); + BIO_set_callback_arg(bio, (char *)redirect_tests[idx].redirects); + ERR_clear_error(); + rsp = OSSL_HTTP_get(redirect_tests[idx].url, NULL, NULL, bio, NULL, + http_noop_update, NULL, 0, NULL, NULL, 0, + OSSL_HTTP_DEFAULT_MAX_RESP_LEN, 0); + if (redirect_tests[idx].success) { + res = TEST_ptr(rsp) + && TEST_int_eq(BIO_read(rsp, buf, sizeof(buf)), sizeof(text1) - 1) + && TEST_mem_eq(buf, sizeof(text1) - 1, text1, sizeof(text1) - 1); + } else { + err = ERR_peek_last_error(); + res = TEST_ptr_null(rsp) + && TEST_int_eq(ERR_GET_LIB(err), ERR_LIB_HTTP) + && TEST_int_eq(ERR_GET_REASON(err), HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP); + } + +end: + BIO_free(rsp); + BIO_free(bio); + ERR_clear_error(); + return res; +} + static int test_http_keep_alive(char version, int keep_alive, int kept_alive) { BIO *wbio = BIO_new(BIO_s_mem()); @@ -682,6 +759,7 @@ int setup_tests(void) ADD_TEST(test_http_get_txt); ADD_TEST(test_http_get_txt_redirected); + ADD_ALL_TESTS(test_http_redirect, OSSL_NELEM(redirect_tests)); ADD_TEST(test_http_get_txt_fatal_status); ADD_TEST(test_http_get_txt_error_status); ADD_TEST(test_http_post_txt); diff --git a/test/ideatest.c b/test/ideatest.c index 4ad7f67054576..6254af32dbff8 100644 --- a/test/ideatest.c +++ b/test/ideatest.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/igetest.c b/test/igetest.c index 7e7ad0606f318..7eed4d615dc9c 100644 --- a/test/igetest.c +++ b/test/igetest.c @@ -1,5 +1,5 @@ /* - * Copyright 2006-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/json_test.c b/test/json_test.c index d8aa5db05137a..59540b5a7b2be 100644 --- a/test/json_test.c +++ b/test/json_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/lhash_test.c b/test/lhash_test.c index 87dc71f829a68..a62651052eebb 100644 --- a/test/lhash_test.c +++ b/test/lhash_test.c @@ -576,28 +576,67 @@ typedef struct test_mt_entry { static HT *m_ht = NULL; #define TEST_MT_POOL_SZ 256 -#define TEST_THREAD_ITERATIONS 1000000 -#define NUM_WORKERS 16 +/*- + * TEST_THREAD_ITERATIONS is chosen so that collisions between workers + * on the same key are exercised, not to make the test run for any + * particular length of time. + * + * Choosing too large a number consumes a multithreaded machine with the + * kernel madly exercising lock contention, for no real gain in coverage + * for our code, making the tests run excessively long. A million + * iterations is really painful. + * + * A race needs two workers on one key at once, so what must be covered is + * each ordered pair of behaviours -- NUM_BEHAVIORS squared, or 16 -- + * arriving together on a key. With W workers an operation collides with + * probability P = 1 - ((TEST_MT_POOL_SZ - 1) / TEST_MT_POOL_SZ) ^ (W - 1), + * and a collision is equally likely to be any of the 16, so each is seen + * an expected E = W * TEST_THREAD_ITERATIONS * P / 16 times per + * configuration. The chance of never seeing one is about 16 * exp(-E): + * + * workers E P(some combination never exercised) + * 2 73 1e-31 + * 4 438 1e-189 + * 8 2027 1e-879 + * 16 8553 1e-3713 + * + * Coverage rises with the square of the worker count but run time only + * linearly, so the value is sized for the fewest workers worth supporting. + * At two workers 10000 iterations would miss a combination one run in + * nine, and 20000 one run in a thousand; the value below is far enough + * past that to leave each combination met at many different points in the + * interleaving. More buys only further chances of landing in a narrow + * timing window, not more of the state space. + */ +#define TEST_THREAD_ITERATIONS 150000 +/*- + * Four workers is enough to interleave more than a pair of threads on a + * key, which two cannot do, without tying up a whole machine. + */ +#define MAX_NUM_WORKERS 4 static struct test_mt_entry test_mt_entries[TEST_MT_POOL_SZ]; static char **worker_exits; static thread_t *workers; -static int num_workers = NUM_WORKERS; +static int num_workers = MAX_NUM_WORKERS; static int setup_num_workers(void) { char *harness_jobs = getenv("HARNESS_JOBS"); char *lhash_workers = getenv("LHASH_WORKERS"); - /* If we have HARNESS_JOBS set, don't eat more than a quarter */ + /* If we have HARNESS_JOBS set, don't use more workers than that */ if (harness_jobs != NULL) { - int jobs = atoi(harness_jobs); - if (jobs > 0) - num_workers = jobs / 4; + int jobs; + + if (test_strtoint(harness_jobs, &jobs) && jobs > 0 + && jobs < num_workers) + num_workers = jobs; } /* But if we have explicitly set LHASH_WORKERS use that */ if (lhash_workers != NULL) { - int jobs = atoi(lhash_workers); - if (jobs > 0) + int jobs; + + if (test_strtoint(lhash_workers, &jobs) && jobs > 0) num_workers = jobs; } @@ -634,7 +673,11 @@ static void hashtable_mt_free(HT_VALUE *v) int pending_delete; int ret; - CRYPTO_atomic_load_int(&m->pending_delete, &pending_delete, worker_lock); + if (!TEST_true(CRYPTO_atomic_load_int(&m->pending_delete, &pending_delete, + worker_lock))) { + free_failure = 1; + return; + } if (shutting_down == 1) return; diff --git a/test/list_test.c b/test/list_test.c index a8a902554cf16..dc59460dd6e74 100644 --- a/test/list_test.c +++ b/test/list_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -175,9 +175,55 @@ static int test_insert(void) return 1; } +static int test_join(void) +{ + OSSL_LIST(int) + l_h, l_t; + INTL elem_h[20]; + INTL elem_t[20]; + int i; + + ossl_list_int_init(&l_h); + ossl_list_int_init(&l_t); + ossl_list_int_join(&l_h, &l_t); + if (!TEST_size_t_eq(ossl_list_int_num(&l_t), 0)) + return 0; + + for (i = 0; i < (int)OSSL_NELEM(elem_h); i++) { + ossl_list_int_init_elem(&elem_h[i]); + elem_h[i].n = i; + ossl_list_int_insert_head(&l_h, &elem_h[i]); + } + + for (i = 0; i < (int)OSSL_NELEM(elem_t); i++) { + ossl_list_int_init_elem(&elem_t[i]); + elem_t[i].n = i + 10; + ossl_list_int_insert_head(&l_t, &elem_t[i]); + } + + ossl_list_int_join(NULL, NULL); + + ossl_list_int_join(NULL, &l_t); + if (!TEST_size_t_eq(ossl_list_int_num(&l_t), OSSL_NELEM(elem_t))) + return 0; + + ossl_list_int_join(&l_h, NULL); + if (!TEST_size_t_eq(ossl_list_int_num(&l_h), OSSL_NELEM(elem_h))) + return 0; + + ossl_list_int_join(&l_h, &l_t); + if (!TEST_size_t_eq(ossl_list_int_num(&l_h), OSSL_NELEM(elem_h) + OSSL_NELEM(elem_t))) + return 0; + + if (!TEST_true(ossl_list_int_is_empty(&l_t))) + return 0; + + return 1; +} int setup_tests(void) { ADD_TEST(test_fizzbuzz); ADD_TEST(test_insert); + ADD_TEST(test_join); return 1; } diff --git a/test/load_key_certs_crls_memfail.c b/test/load_key_certs_crls_memfail.c index 6d6125c946ca8..90e079e7f7741 100644 --- a/test/load_key_certs_crls_memfail.c +++ b/test/load_key_certs_crls_memfail.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); you may not use * this file except in compliance with the License. You may obtain a copy diff --git a/test/mem_alloc_test.c b/test/mem_alloc_test.c index c6ae139ae1889..e961f4a17be28 100644 --- a/test/mem_alloc_test.c +++ b/test/mem_alloc_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/mfail/mfail.c b/test/mfail/mfail.c index ec391c8e85ecb..70f575afc92e8 100644 --- a/test/mfail/mfail.c +++ b/test/mfail/mfail.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #if defined(__has_feature) @@ -69,7 +70,12 @@ static int env_is_true(const char *name) static int env_int(const char *name, int dflt) { const char *value = getenv(name); - return (value != NULL && *value != '\0') ? atoi(value) : dflt; + unsigned long ul; + + if (value != NULL && *value != '\0' + && OPENSSL_strtoul(value, NULL, 10, &ul) && ul <= INT_MAX) + return (int)ul; + return dflt; } static void mfail_print_bt(void) diff --git a/test/ml_dsa_test.c b/test/ml_dsa_test.c index ca1c1225e28b9..3ae236b70ffc7 100644 --- a/test/ml_dsa_test.c +++ b/test/ml_dsa_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -17,9 +17,12 @@ #include "crypto/evp.h" #include "crypto/ml_dsa.h" +static int do_fips = 0; + typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, + OPT_FIPS, OPT_CONFIG_FILE, OPT_TEST_ENUM } OPTION_CHOICE; @@ -355,6 +358,32 @@ static int ml_dsa_key_internal_test(void) return ret; } +static int ml_dsa_newdata_bad_propq_test(void) +{ + int ret = 0; + EVP_KEYMGMT *keymgmt = NULL; + void *keydata = NULL; + OSSL_PARAM params[2]; + + if (do_fips) + return TEST_skip("FIPS not supported"); + + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_PROPERTIES, + "provider=fail", 0); + params[1] = OSSL_PARAM_construct_end(); + + if (!TEST_ptr(keymgmt = EVP_KEYMGMT_fetch(lib_ctx, "ML-DSA-44", NULL))) + goto end; + + if (!TEST_ptr_null(keydata = evp_keymgmt_newdata(keymgmt, params))) + goto end; + + ret = 1; +end: + EVP_KEYMGMT_free(keymgmt); + return ret; +} + static int from_data_invalid_public_test(void) { int ret = 0; @@ -753,6 +782,7 @@ const OPTIONS *test_get_options(void) { static const OPTIONS options[] = { OPT_TEST_OPTIONS_DEFAULT_USAGE, + { "fips", OPT_FIPS, '-', "Test with FIPS provider" }, { "config", OPT_CONFIG_FILE, '<', "The configuration file to use for the libctx" }, { NULL } @@ -767,6 +797,9 @@ int setup_tests(void) while ((o = opt_next()) != OPT_EOF) { switch (o) { + case OPT_FIPS: + do_fips = 1; + break; case OPT_CONFIG_FILE: config_file = opt_arg(); break; @@ -797,6 +830,7 @@ int setup_tests(void) ADD_TEST(from_data_bad_input_test); ADD_TEST(ml_dsa_digest_sign_verify_test); ADD_TEST(ml_dsa_priv_pub_bad_t0_test); + ADD_TEST(ml_dsa_newdata_bad_propq_test); /* * Tested only in the default configuration, with a non-default provider diff --git a/test/ml_kem_evp_extra_test.c b/test/ml_kem_evp_extra_test.c index 2aa704427ac49..1f282034cf489 100644 --- a/test/ml_kem_evp_extra_test.c +++ b/test/ml_kem_evp_extra_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -425,6 +425,7 @@ static int test_ml_kem_from_data_propq(void) #ifndef OPENSSL_NO_EC static const char *mlx_kem_algs[] = { #ifndef OPENSSL_NO_ECX + "MLKEM512X25519", "X25519MLKEM768", #endif "SecP256r1MLKEM768", diff --git a/test/ml_kem_internal_test.c b/test/ml_kem_internal_test.c index 14487dab942ee..995c2370a4cac 100644 --- a/test/ml_kem_internal_test.c +++ b/test/ml_kem_internal_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/nocache-and-default.cnf b/test/nocache-and-default.cnf.in similarity index 80% rename from test/nocache-and-default.cnf rename to test/nocache-and-default.cnf.in index cf5ca8d114151..b379a09ecdd97 100644 --- a/test/nocache-and-default.cnf +++ b/test/nocache-and-default.cnf.in @@ -1,3 +1,4 @@ +{- use platform -} openssl_conf = openssl_init # Comment out the next line to ignore configuration errors @@ -11,7 +12,7 @@ test = test_sect default = default_sect [test_sect] -module = ../test/p_test.so +module = ../test/{- platform->dso("p_test") -} activate = true [default_sect] diff --git a/test/ocspapitest.c b/test/ocspapitest.c index c4baca4a7d3b0..4e9861e5ed73a 100644 --- a/test/ocspapitest.c +++ b/test/ocspapitest.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/ossl_rbtree_test.c b/test/ossl_rbtree_test.c new file mode 100644 index 0000000000000..ef6f1d416380a --- /dev/null +++ b/test/ossl_rbtree_test.c @@ -0,0 +1,276 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#include "testutil.h" +#include "internal/nelem.h" +#include "internal/ossl_rbtree.h" + +static const char *test_data[] = { + "alpha", + "bravo", + "charlie", + "delta", + "echo", + "foxtrot", + "golf", + "hotel", + "india", + "juliet", + "kilo", + "lima", + "mike", + "november", + "oscar", + "papa", + "quebec", + "romeo", + "sierra", + "tango", + "uniform", + "victor", + "whiskey", + "x-ray", + "yankey", + "zulu", +}; + +typedef struct test_rbt { + OSSL_RBT_ENTRY(test_rbt) + rbt_entry; + const char *rbt_data; +} TEST_RBT_T; + +static OSSL_RBT_HEAD(ossl_rbt, test_rbt) + rbt_head; + +static TEST_RBT_T nodes_rbt[26]; + +static int cmp(const TEST_RBT_T *a, const TEST_RBT_T *b); + +OSSL_RBT_PROTOTYPE(ossl_rbt, test_rbt, rbt_entry, cmp) + +OSSL_RBT_GENERATE(ossl_rbt, test_rbt, rbt_entry, cmp); + +static int cmp(const TEST_RBT_T *a_rbt, const TEST_RBT_T *b_rbt) +{ + return strcmp(a_rbt->rbt_data, b_rbt->rbt_data); +} + +static int test_rbt_insert(void) +{ + unsigned int i; + TEST_RBT_T *found_rbt, *node_rbt; + + OSSL_RBT_INIT(ossl_rbt, &rbt_head); + + for (i = OSSL_NELEM(test_data); i != 0; i--) { + node_rbt = &nodes_rbt[i - 1]; + OSSL_RBT_INIT_RBE(ossl_rbt, node_rbt); + node_rbt->rbt_data = test_data[i - 1]; + found_rbt = OSSL_RBT_INSERT(ossl_rbt, &rbt_head, node_rbt); + if (!TEST_ptr_eq(found_rbt, NULL)) { + TEST_info("%s %p(%s) found already %p(%s) @ %u\n", OPENSSL_FUNC, + (void *)node_rbt, node_rbt->rbt_data, + (void *)found_rbt, found_rbt->rbt_data, i); + return 0; + } + } + + return 1; +} + +static int test_rbt_min(void) +{ + unsigned int i; + int match; + TEST_RBT_T *node_rbt; + + if (test_rbt_insert() == 0) + return 0; + + node_rbt = OSSL_RBT_MIN(ossl_rbt, &rbt_head); + if (!TEST_ptr(node_rbt)) { + TEST_info("%s OSSL_RBT_MIN() returns NULL", OPENSSL_FUNC); + return 0; + } + + for (i = 0; i < OSSL_NELEM(test_data); i++) { + match = strcmp(node_rbt->rbt_data, test_data[i]); + if (!TEST_int_eq(match, 0)) { + TEST_info("%s %s != %s @ %u", OPENSSL_FUNC, + node_rbt->rbt_data, test_data[i], i); + return 0; + } + node_rbt = OSSL_RBT_NEXT(ossl_rbt, node_rbt); + } + + if (!TEST_ptr_eq(node_rbt, NULL)) { + TEST_info("%s OSSL_RBT_NEXT() is not NULL", OPENSSL_FUNC); + return 0; + } + + return 1; +} + +static int test_rbt_max(void) +{ + unsigned int i; + int match; + TEST_RBT_T *node_rbt; + + if (test_rbt_insert() == 0) + return 0; + + node_rbt = OSSL_RBT_MAX(ossl_rbt, &rbt_head); + if (!TEST_ptr(node_rbt)) { + TEST_info("%s OSSL_RBT_MIN() returns NULL", OPENSSL_FUNC); + return 0; + } + + for (i = OSSL_NELEM(test_data); i > 0; i--) { + match = strcmp(node_rbt->rbt_data, test_data[i - 1]); + if (!TEST_int_eq(match, 0)) { + TEST_info("%s %s != %s @ %u", OPENSSL_FUNC, + node_rbt->rbt_data, test_data[i - 1], i); + return 0; + } + node_rbt = OSSL_RBT_PREV(ossl_rbt, node_rbt); + } + + if (!TEST_ptr_eq(node_rbt, NULL)) { + TEST_info("%s OSSL_RBT_PREV() is not NULL", OPENSSL_FUNC); + return 0; + } + + return 1; +} + +static int test_rbt_find_remove(void) +{ + unsigned int i; + TEST_RBT_T *node_rbt, *removed_rbt; + TEST_RBT_T key_rbt; + + if (test_rbt_insert() == 0) + return 0; + + for (i = 0; i < OSSL_NELEM(test_data); i++) { + key_rbt.rbt_data = test_data[i]; + node_rbt = OSSL_RBT_FIND(ossl_rbt, &rbt_head, &key_rbt); + if (!TEST_ptr(node_rbt)) { + TEST_info("%s %s not found in tree @ %u", OPENSSL_FUNC, + key_rbt.rbt_data, i); + return 0; + } + removed_rbt = OSSL_RBT_REMOVE(ossl_rbt, &rbt_head, node_rbt); + if (!TEST_ptr_eq(node_rbt, removed_rbt)) { + TEST_info("%s node_rbt(%p) != removed_rbt(%p) @ %u", + OPENSSL_FUNC, (void *)node_rbt, (void *)removed_rbt, i); + return 0; + } + + node_rbt = OSSL_RBT_FIND(ossl_rbt, &rbt_head, &key_rbt); + if (!TEST_ptr_eq(node_rbt, NULL)) { + TEST_info("%s %s(%p) still found after being removed @ %u", + OPENSSL_FUNC, node_rbt->rbt_data, (void *)node_rbt, i); + return 0; + } + } + + if (!TEST_int_ne(OSSL_RBT_EMPTY(ossl_rbt, &rbt_head), 0)) { + TEST_info("%s rbt is not empty", OPENSSL_FUNC); + return 0; + } + + return 1; +} + +static int test_rbt_dup_insert(void) +{ + unsigned int i; + int match; + TEST_RBT_T *conflict_rbt; + TEST_RBT_T insert_rbt; + + if (test_rbt_insert() == 0) + return 0; + + for (i = 0; i < OSSL_NELEM(test_data); i++) { + OSSL_RBT_INIT_RBE(ossl_rbt, &insert_rbt); + insert_rbt.rbt_data = test_data[i]; + conflict_rbt = OSSL_RBT_INSERT(ossl_rbt, &rbt_head, &insert_rbt); + if (!TEST_ptr(conflict_rbt)) { + TEST_info("%s %s not found in tree @ %u", OPENSSL_FUNC, + insert_rbt.rbt_data, i); + return 0; + } + match = strcmp(conflict_rbt->rbt_data, insert_rbt.rbt_data); + if (!TEST_int_eq(match, 0)) { + TEST_info("%s insert(%s) != conflict(%s) @ %u", + OPENSSL_FUNC, insert_rbt.rbt_data, conflict_rbt->rbt_data, i); + return 0; + } + } + + return 1; +} + +static int test_rbt_foreach(void) +{ + unsigned int i; + int match; + TEST_RBT_T *walk_rbt, *save_rbt; + + if (test_rbt_insert() == 0) + return 0; + + i = 0; + OSSL_RBT_FOREACH (walk_rbt, ossl_rbt, &rbt_head) { + match = strcmp(walk_rbt->rbt_data, test_data[i]); + if (!TEST_int_eq(match, 0)) { + TEST_info("%s expected: %s got: %s @ %u", + OPENSSL_FUNC, walk_rbt->rbt_data, test_data[i], i); + return 0; + } + i++; + } + + i = 0; + OSSL_RBT_FOREACH_SAFE (walk_rbt, ossl_rbt, &rbt_head, save_rbt) { + match = strcmp(walk_rbt->rbt_data, test_data[i]); + if (!TEST_int_eq(match, 0)) { + TEST_info("%s expected: %s got: %s @ %u", + OPENSSL_FUNC, walk_rbt->rbt_data, test_data[i], i); + return 0; + } + OSSL_RBT_REMOVE(ossl_rbt, &rbt_head, walk_rbt); + i++; + } + + if (!TEST_int_ne(OSSL_RBT_EMPTY(ossl_rbt, &rbt_head), 0)) { + TEST_info("%s rbt is not empty", OPENSSL_FUNC); + return 0; + } + + return 1; +} + +int setup_tests(void) +{ + ADD_TEST(test_rbt_insert); + ADD_TEST(test_rbt_min); + ADD_TEST(test_rbt_max); + ADD_TEST(test_rbt_find_remove); + ADD_TEST(test_rbt_dup_insert); + ADD_TEST(test_rbt_foreach); + + return 1; +} diff --git a/test/ossl_store_test.c b/test/ossl_store_test.c index 104ae3ad610bd..5453fe454cbfa 100644 --- a/test/ossl_store_test.c +++ b/test/ossl_store_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -11,7 +11,14 @@ #include #include #include +#include +#include +#include +#include +#include +#include #include "testutil.h" +#include "fake_storeprov.h" #ifndef PATH_MAX #if defined(_WIN32) && defined(_MAX_PATH) @@ -36,10 +43,13 @@ static const char *infile = NULL; static const char *sm2file = NULL; static const char *datadir = NULL; +static OSSL_LIB_CTX *fake_libctx = NULL; +static OSSL_PROVIDER *fake_prov = NULL; + static int test_store_open(void) { int ret = 0; - OSSL_STORE_CTX *sctx = NULL; + OSSL_STORE_CTX *sctx = NULL, *sctx2 = NULL; OSSL_STORE_SEARCH *search = NULL; UI_METHOD *ui_method = NULL; char *input = test_mk_file_path(inputdir, infile); @@ -49,11 +59,17 @@ static int test_store_open(void) && TEST_ptr(ui_method = UI_create_method("DummyUI")) && TEST_ptr(sctx = OSSL_STORE_open_ex(input, NULL, NULL, ui_method, NULL, NULL, NULL, NULL)) + && TEST_true(OSSL_STORE_supports_search(sctx, OSSL_STORE_SEARCH_BY_NAME)) + && TEST_false(OSSL_STORE_supports_search(sctx, + OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT)) && TEST_false(OSSL_STORE_find(sctx, NULL)) - && TEST_true(OSSL_STORE_find(sctx, search)); + && TEST_true(OSSL_STORE_find(sctx, search)) + && TEST_ptr(sctx2 = OSSL_STORE_open(input, ui_method, NULL, + NULL, NULL)); UI_destroy_method(ui_method); OSSL_STORE_SEARCH_free(search); OSSL_STORE_close(sctx); + OSSL_STORE_close(sctx2); OPENSSL_free(input); return ret; } @@ -208,8 +224,12 @@ static int test_store_get_params(int idx) urifmt = "%s%s-params.pem"; } #endif - if (!TEST_true(BIO_snprintf(uri, sizeof(uri), urifmt, datadir, type))) - return 0; + { + int n = snprintf(uri, sizeof(uri), urifmt, datadir, type); + + if (!TEST_true(n > 0 && (size_t)n < sizeof(uri))) + return 0; + } TEST_info("Testing uri: %s", uri); if (!TEST_true(get_params(uri, type))) @@ -249,12 +269,401 @@ static int test_store_attach_unregistered_scheme(void) return ret; } +static int test_store_attach_load_mfail(void) +{ + const unsigned char input[] = { 0x30, 0x00 }; + BIO *bio = NULL; + OSSL_STORE_CTX *store_ctx = NULL; + OSSL_STORE_INFO *info = NULL; + int ret = 0; + + if (!TEST_ptr(bio = BIO_new_mem_buf(input, sizeof(input)))) + goto err; + + MFAIL_start(); + store_ctx = OSSL_STORE_attach(bio, "file", + NULL, NULL, NULL, NULL, NULL, NULL, NULL); + if (store_ctx != NULL) + info = OSSL_STORE_load(store_ctx); + MFAIL_end(); + + ret = 1; + +err: + OSSL_STORE_INFO_free(info); + OSSL_STORE_close(store_ctx); + BIO_free(bio); + return ret; +} + +static int test_store_attach_invalid_params(void) +{ + const unsigned char input[] = { 0 }; + char invalid_expect[] = "invalid"; + OSSL_PARAM params[] = { + OSSL_PARAM_construct_utf8_string(OSSL_STORE_PARAM_EXPECT, invalid_expect, 0), + OSSL_PARAM_END + }; + BIO *bio = NULL; + int ret = 0; + + if (!TEST_ptr(bio = BIO_new_mem_buf(input, sizeof(input)))) + goto err; + + ret = TEST_ptr_null(OSSL_STORE_attach(bio, "file", + NULL, NULL, NULL, NULL, params, NULL, NULL)); + +err: + BIO_free(bio); + return ret; +} + static int test_store_delete_null_uri(void) { /* Passing NULL uri must return 0, not crash */ return TEST_int_eq(OSSL_STORE_delete(NULL, NULL, NULL, NULL, NULL, NULL), 0); } +static int test_fake_store_names(void) +{ + OSSL_STORE_CTX *sctx = NULL; + OSSL_STORE_INFO *info = NULL; + char *name = NULL, *desc = NULL; + int ret = 0; + + /* The authority prefix (//) invalidates the implicit 'file' scheme */ + if (!TEST_ptr(sctx = OSSL_STORE_open_ex("fake://" FAKE_STORE_CMD_ONE_NAME, + fake_libctx, FAKE_STORE_FETCH_PROPS, + NULL, NULL, NULL, NULL, NULL)) + || !TEST_true(OSSL_STORE_expect(sctx, OSSL_STORE_INFO_NAME)) + || !TEST_ptr(info = OSSL_STORE_load(sctx))) + goto err; + + if (!TEST_int_eq(OSSL_STORE_INFO_get_type(info), OSSL_STORE_INFO_NAME) + || !TEST_str_eq(OSSL_STORE_INFO_get0_NAME(info), "name1") + || !TEST_str_eq(OSSL_STORE_INFO_get0_NAME_description(info), "desc1") + || !TEST_ptr(name = OSSL_STORE_INFO_get1_NAME(info)) + || !TEST_str_eq(name, "name1") + || !TEST_ptr(desc = OSSL_STORE_INFO_get1_NAME_description(info)) + || !TEST_str_eq(desc, "desc1") + || !TEST_ptr(OSSL_STORE_INFO_get0_data(OSSL_STORE_INFO_NAME, info)) + || !TEST_ptr_null(OSSL_STORE_INFO_get0_data(OSSL_STORE_INFO_CERT, + info))) + goto err; + + /* Wrong-type accessors must fail cleanly */ + if (!TEST_ptr_null(OSSL_STORE_INFO_get0_PARAMS(info)) + || !TEST_ptr_null(OSSL_STORE_INFO_get1_PARAMS(info)) + || !TEST_ptr_null(OSSL_STORE_INFO_get0_PUBKEY(info)) + || !TEST_ptr_null(OSSL_STORE_INFO_get1_PUBKEY(info)) + || !TEST_ptr_null(OSSL_STORE_INFO_get0_PKEY(info)) + || !TEST_ptr_null(OSSL_STORE_INFO_get1_PKEY(info)) + || !TEST_ptr_null(OSSL_STORE_INFO_get0_CERT(info)) + || !TEST_ptr_null(OSSL_STORE_INFO_get1_CERT(info)) + || !TEST_ptr_null(OSSL_STORE_INFO_get0_CRL(info)) + || !TEST_ptr_null(OSSL_STORE_INFO_get1_CRL(info)) + || !TEST_ptr_null(OSSL_STORE_INFO_get0_SKEY(info)) + || !TEST_ptr_null(OSSL_STORE_INFO_get1_SKEY(info))) + goto err; + + if (!TEST_true(OSSL_STORE_eof(sctx)) + || !TEST_ptr_null(OSSL_STORE_load(sctx)) + || !TEST_false(OSSL_STORE_error(sctx))) + goto err; + + ret = 1; +err: + OPENSSL_free(name); + OPENSSL_free(desc); + OSSL_STORE_INFO_free(info); + OSSL_STORE_close(sctx); + return ret; +} + +static int test_fake_store_open_ex(void) +{ + OSSL_STORE_CTX *sctx = NULL; + OSSL_STORE_INFO *info = NULL; + OSSL_PARAM params[2]; + int expect = OSSL_STORE_INFO_NAME; + int ret = 0; + + params[0] = OSSL_PARAM_construct_int(OSSL_STORE_PARAM_EXPECT, &expect); + params[1] = OSSL_PARAM_construct_end(); + + fake_store_clear_state(); + if (!TEST_ptr(sctx = OSSL_STORE_open_ex( + FAKE_STORE_SCHEME_OPEN_EX ":" FAKE_STORE_CMD_ONE_NAME, + fake_libctx, FAKE_STORE_FETCH_PROPS, NULL, NULL, + params, NULL, NULL)) + || !TEST_true(fake_store_get_seen_params() & FAKE_STORE_SEEN_EXPECT) + || !TEST_ptr(info = OSSL_STORE_load(sctx)) + || !TEST_str_eq(OSSL_STORE_INFO_get0_NAME(info), "name1")) + goto err; + + /* Both open_ex() failure modes must result in a failed open */ + if (!TEST_ptr_null(OSSL_STORE_open_ex( + FAKE_STORE_SCHEME_OPEN_EX ":" FAKE_STORE_CMD_OPEN_FAIL, + fake_libctx, FAKE_STORE_FETCH_PROPS, NULL, NULL, + params, NULL, NULL)) + || !TEST_ptr_null(OSSL_STORE_open_ex( + FAKE_STORE_SCHEME_OPEN_EX ":" FAKE_STORE_CMD_PARAMS_FAIL, + fake_libctx, FAKE_STORE_FETCH_PROPS, NULL, NULL, + params, NULL, NULL))) + goto err; + + ret = 1; +err: + OSSL_STORE_INFO_free(info); + OSSL_STORE_close(sctx); + return ret; +} + +static int test_fake_store_params(void) +{ + OSSL_STORE_CTX *sctx = NULL; + OSSL_PARAM params[2]; + char propq[] = FAKE_STORE_FETCH_PROPS; + int expect = OSSL_STORE_INFO_NAME; + int ret = 0; + + /* Properties in params take precedence over the propq argument */ + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_STORE_PARAM_PROPERTIES, + propq, 0); + params[1] = OSSL_PARAM_construct_end(); + fake_store_clear_state(); + if (!TEST_ptr(sctx = OSSL_STORE_open_ex( + FAKE_STORE_SCHEME ":" FAKE_STORE_CMD_ONE_NAME, + fake_libctx, FAKE_STORE_FETCH_PROPS, NULL, NULL, + params, NULL, NULL)) + || !TEST_true(fake_store_get_seen_params() + & FAKE_STORE_SEEN_PROPERTIES)) + goto err; + OSSL_STORE_close(sctx); + sctx = NULL; + + /* A set_ctx_params failure at open time must make the open fail */ + params[0] = OSSL_PARAM_construct_int(OSSL_STORE_PARAM_EXPECT, &expect); + if (!TEST_ptr_null(OSSL_STORE_open_ex( + FAKE_STORE_SCHEME ":" FAKE_STORE_CMD_PARAMS_FAIL, + fake_libctx, FAKE_STORE_FETCH_PROPS, NULL, NULL, + params, NULL, NULL))) + goto err; + + ret = 1; +err: + OSSL_STORE_close(sctx); + return ret; +} + +static int test_fake_store_find(void) +{ + OSSL_STORE_CTX *sctx = NULL; + OSSL_STORE_SEARCH *search = NULL; + X509_NAME *nm = NULL; + ASN1_INTEGER *serial = NULL; + unsigned char fingerprint[32] = { 0 }; + const unsigned char *bytes = NULL; + size_t len = 0; + int ret = 0; + + if (!TEST_ptr(sctx = OSSL_STORE_open_ex( + FAKE_STORE_SCHEME ":" FAKE_STORE_CMD_ONE_NAME, + fake_libctx, FAKE_STORE_FETCH_PROPS, + NULL, NULL, NULL, NULL, NULL))) + goto err; + + if (!TEST_true(OSSL_STORE_supports_search(sctx, OSSL_STORE_SEARCH_BY_NAME)) + || !TEST_true(OSSL_STORE_supports_search(sctx, + OSSL_STORE_SEARCH_BY_ISSUER_SERIAL)) + || !TEST_true(OSSL_STORE_supports_search(sctx, + OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT)) + || !TEST_true(OSSL_STORE_supports_search(sctx, + OSSL_STORE_SEARCH_BY_ALIAS))) + goto err; + + if (!TEST_ptr(nm = X509_NAME_new()) + || !TEST_true(X509_NAME_add_entry_by_txt(nm, "CN", MBSTRING_ASC, + (const unsigned char *)"fake", -1, -1, 0)) + || !TEST_ptr(serial = ASN1_INTEGER_new()) + || !TEST_true(ASN1_INTEGER_set(serial, 42))) + goto err; + + fake_store_clear_state(); + if (!TEST_ptr(search = OSSL_STORE_SEARCH_by_name(nm)) + || !TEST_int_eq(OSSL_STORE_SEARCH_get_type(search), + OSSL_STORE_SEARCH_BY_NAME) + || !TEST_ptr_eq(OSSL_STORE_SEARCH_get0_name(search), nm) + || !TEST_true(OSSL_STORE_find(sctx, search)) + || !TEST_true(fake_store_get_seen_params() & FAKE_STORE_SEEN_SUBJECT)) + goto err; + OSSL_STORE_SEARCH_free(search); + search = NULL; + + fake_store_clear_state(); + if (!TEST_ptr(search = OSSL_STORE_SEARCH_by_issuer_serial(nm, serial)) + || !TEST_int_eq(OSSL_STORE_SEARCH_get_type(search), + OSSL_STORE_SEARCH_BY_ISSUER_SERIAL) + || !TEST_ptr_eq(OSSL_STORE_SEARCH_get0_serial(search), serial) + || !TEST_true(OSSL_STORE_find(sctx, search)) + || !TEST_true(fake_store_get_seen_params() & FAKE_STORE_SEEN_ISSUER) + || !TEST_true(fake_store_get_seen_params() & FAKE_STORE_SEEN_SERIAL)) + goto err; + OSSL_STORE_SEARCH_free(search); + search = NULL; + + fake_store_clear_state(); + if (!TEST_ptr(search = OSSL_STORE_SEARCH_by_key_fingerprint(EVP_sha256(), + fingerprint, sizeof(fingerprint))) + || !TEST_int_eq(OSSL_STORE_SEARCH_get_type(search), + OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT) + || !TEST_ptr_eq(OSSL_STORE_SEARCH_get0_digest(search), EVP_sha256()) + || !TEST_ptr(bytes = OSSL_STORE_SEARCH_get0_bytes(search, &len)) + || !TEST_ptr_eq(bytes, fingerprint) + || !TEST_size_t_eq(len, sizeof(fingerprint)) + || !TEST_true(OSSL_STORE_find(sctx, search)) + || !TEST_true(fake_store_get_seen_params() & FAKE_STORE_SEEN_DIGEST) + || !TEST_true(fake_store_get_seen_params() + & FAKE_STORE_SEEN_FINGERPRINT)) + goto err; + OSSL_STORE_SEARCH_free(search); + search = NULL; + + fake_store_clear_state(); + if (!TEST_ptr(search = OSSL_STORE_SEARCH_by_alias("myalias")) + || !TEST_int_eq(OSSL_STORE_SEARCH_get_type(search), + OSSL_STORE_SEARCH_BY_ALIAS) + || !TEST_str_eq(OSSL_STORE_SEARCH_get0_string(search), "myalias") + || !TEST_true(OSSL_STORE_find(sctx, search)) + || !TEST_true(fake_store_get_seen_params() & FAKE_STORE_SEEN_ALIAS)) + goto err; + + ret = 1; +err: + OSSL_STORE_SEARCH_free(search); + X509_NAME_free(nm); + ASN1_INTEGER_free(serial); + OSSL_STORE_close(sctx); + return ret; +} + +static int test_fake_store_loading_started(void) +{ + OSSL_STORE_CTX *sctx = NULL; + OSSL_STORE_INFO *info = NULL; + OSSL_STORE_SEARCH *search = NULL; + int ret = 0; + + if (!TEST_ptr(sctx = OSSL_STORE_open_ex( + FAKE_STORE_SCHEME ":" FAKE_STORE_CMD_TWO_NAMES, + fake_libctx, FAKE_STORE_FETCH_PROPS, + NULL, NULL, NULL, NULL, NULL)) + || !TEST_false(OSSL_STORE_expect(NULL, OSSL_STORE_INFO_CERT)) + || !TEST_false(OSSL_STORE_expect(sctx, -1)) + || !TEST_false(OSSL_STORE_expect(sctx, OSSL_STORE_INFO_SKEY + 1)) + || !TEST_ptr(search = OSSL_STORE_SEARCH_by_alias("myalias"))) + goto err; + + /* Once loading has started, expect() and find() must fail */ + if (!TEST_ptr(info = OSSL_STORE_load(sctx)) + || !TEST_false(OSSL_STORE_expect(sctx, OSSL_STORE_INFO_NAME)) + || !TEST_false(OSSL_STORE_find(sctx, search))) + goto err; + + ret = 1; +err: + OSSL_STORE_SEARCH_free(search); + OSSL_STORE_INFO_free(info); + OSSL_STORE_close(sctx); + return ret; +} + +static OSSL_STORE_INFO *filter_name2(OSSL_STORE_INFO *info, void *arg) +{ + int *calls = arg; + + (*calls)++; + if (strcmp(OSSL_STORE_INFO_get0_NAME(info), "name2") == 0) { + OSSL_STORE_INFO_free(info); + return NULL; + } + return info; +} + +static int test_fake_store_post_process(void) +{ + OSSL_STORE_CTX *sctx = NULL; + OSSL_STORE_INFO *info = NULL; + int calls = 0; + int ret = 0; + + if (!TEST_ptr(sctx = OSSL_STORE_open_ex( + FAKE_STORE_SCHEME ":" FAKE_STORE_CMD_TWO_NAMES, + fake_libctx, FAKE_STORE_FETCH_PROPS, NULL, NULL, NULL, + filter_name2, &calls)) + || !TEST_ptr(info = OSSL_STORE_load(sctx)) + || !TEST_str_eq(OSSL_STORE_INFO_get0_NAME(info), "name1") + || !TEST_int_eq(calls, 2) + || !TEST_true(OSSL_STORE_eof(sctx))) + goto err; + + ret = 1; +err: + OSSL_STORE_INFO_free(info); + OSSL_STORE_close(sctx); + return ret; +} + +static int test_fake_store_attach(void) +{ + OSSL_STORE_CTX *sctx = NULL; + OSSL_STORE_INFO *info = NULL; + BIO *bio = NULL; + OSSL_PARAM params[2]; + int expect = OSSL_STORE_INFO_NAME; + int ret = 0; + + params[0] = OSSL_PARAM_construct_int(OSSL_STORE_PARAM_EXPECT, &expect); + params[1] = OSSL_PARAM_construct_end(); + + fake_store_clear_state(); + if (!TEST_ptr(bio = BIO_new(BIO_s_mem())) + || !TEST_ptr(sctx = OSSL_STORE_attach(bio, FAKE_STORE_SCHEME, + fake_libctx, FAKE_STORE_FETCH_PROPS, + NULL, NULL, params, NULL, NULL)) + || !TEST_true(fake_store_get_seen_params() & FAKE_STORE_SEEN_EXPECT) + || !TEST_true(fake_store_get_seen_params() + & FAKE_STORE_SEEN_PROPERTIES) + || !TEST_ptr(info = OSSL_STORE_load(sctx)) + || !TEST_str_eq(OSSL_STORE_INFO_get0_NAME(info), "name1")) + goto err; + + ret = 1; +err: + OSSL_STORE_INFO_free(info); + OSSL_STORE_close(sctx); + BIO_free(bio); + return ret; +} + +static int test_fake_store_delete(void) +{ + fake_store_clear_state(); + if (!TEST_int_eq(OSSL_STORE_delete(FAKE_STORE_SCHEME ":object", + fake_libctx, FAKE_STORE_FETCH_PROPS, + NULL, NULL, NULL), + 1) + || !TEST_str_eq(fake_store_get0_last_deleted(), + FAKE_STORE_SCHEME ":object")) + return 0; + + /* The fake-ex loader has no delete support */ + return TEST_int_eq(OSSL_STORE_delete(FAKE_STORE_SCHEME_OPEN_EX ":object", + fake_libctx, FAKE_STORE_FETCH_PROPS, + NULL, NULL, NULL), + 0); +} + const OPTIONS *test_get_options(void) { static const OPTIONS test_options[] = { @@ -303,6 +712,10 @@ int setup_tests(void) return 0; } + if (!TEST_ptr(fake_libctx = OSSL_LIB_CTX_new()) + || !TEST_ptr(fake_prov = fake_store_start(fake_libctx))) + return 0; + if (infile != NULL) ADD_TEST(test_store_open); #ifndef OPENSSL_NO_WINSTORE @@ -310,8 +723,25 @@ int setup_tests(void) #endif ADD_TEST(test_store_search_by_key_fingerprint_fail); ADD_TEST(test_store_delete_null_uri); + ADD_MFAIL_NO_CHECK_TEST(test_store_attach_load_mfail); + ADD_TEST(test_store_attach_invalid_params); ADD_ALL_TESTS(test_store_get_params, 3); if (sm2file != NULL) ADD_TEST(test_store_attach_unregistered_scheme); + ADD_TEST(test_fake_store_names); + ADD_TEST(test_fake_store_open_ex); + ADD_TEST(test_fake_store_params); + ADD_TEST(test_fake_store_find); + ADD_TEST(test_fake_store_loading_started); + ADD_TEST(test_fake_store_post_process); + ADD_TEST(test_fake_store_attach); + ADD_TEST(test_fake_store_delete); return 1; } + +void cleanup_tests(void) +{ + if (fake_prov != NULL) + fake_store_finish(fake_prov); + OSSL_LIB_CTX_free(fake_libctx); +} diff --git a/test/p_ossltest.c b/test/p_ossltest.c index 2f545ebf16dd8..f79b800f07bd0 100644 --- a/test/p_ossltest.c +++ b/test/p_ossltest.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -19,6 +19,7 @@ * It implements the following algorithms * * The AES-128-CBC cipher + * The AES-128-ECB cipher * The AES-128-GCM cipher * The AES-128-CBC-HMAC-SHA1 cipher * The MD5 digest @@ -390,7 +391,7 @@ static void *ossl_test_aes128cbc_dupctx(void *vprovctx) } /** - * @brief Initialize an aes-129-cbc context for encryption. + * @brief Initialize an aes-128-cbc context for encryption. * * @param vprovctx void *vprovctx. * @param key const unsigned char *key. @@ -695,6 +696,343 @@ static const OSSL_DISPATCH ossl_testaes128_cbc_functions[] = { typedef struct { OSSL_LIB_CTX *libctx; EVP_CIPHER_CTX *sub_ctx; +} PROV_EVP_AES128_ECB_CTX; + +/** + * @brief Allocate and initialize a new aes-128-ecb context. + * + * @param provctx void *provctx. + * @return void *. + */ + +static void *ossl_testaes128_ecb_newctx(void *provctx) +{ + PROV_EVP_AES128_ECB_CTX *new; + EVP_CIPHER *cph = NULL; + int ret; + + if (!ossl_prov_is_running()) + return NULL; + + new = OPENSSL_zalloc(sizeof(PROV_EVP_AES128_ECB_CTX)); + if (new == NULL) + return NULL; + new->sub_ctx = EVP_CIPHER_CTX_new(); + if (new->sub_ctx == NULL) + goto err; + + new->libctx = PROV_LIBCTX_OF(provctx); + + cph = EVP_CIPHER_fetch(new->libctx, "AES-128-ECB", "provider=default"); + if (cph == NULL) + goto err; + + ret = EVP_CipherInit_ex2(new->sub_ctx, cph, NULL, NULL, 1, NULL); + + EVP_CIPHER_free(cph); + + if (ret <= 0) + goto err; + + return new; +err: + EVP_CIPHER_CTX_free(new->sub_ctx); + OPENSSL_free(new); + return NULL; +} + +/** + * @brief Release resources and clean up an aes-128-ecb context. + * + * @param vprovctx void *vprovctx. + * @return void. + */ + +static void ossl_test_aes128ecb_freectx(void *vprovctx) +{ + PROV_EVP_AES128_ECB_CTX *ctx = (PROV_EVP_AES128_ECB_CTX *)vprovctx; + + EVP_CIPHER_CTX_free(ctx->sub_ctx); + OPENSSL_free(ctx); +} + +/** + * @brief Duplicate an aes-128-ecb context. + * + * @param vprovctx void *vprovctx. + * @return void *. + */ + +static void *ossl_test_aes128ecb_dupctx(void *vprovctx) +{ + PROV_EVP_AES128_ECB_CTX *ctx = (PROV_EVP_AES128_ECB_CTX *)vprovctx; + PROV_EVP_AES128_ECB_CTX *dup; + + dup = OPENSSL_memdup(ctx, sizeof(PROV_EVP_AES128_ECB_CTX)); + + if (dup != NULL) { + dup->sub_ctx = EVP_CIPHER_CTX_dup(ctx->sub_ctx); + if (dup->sub_ctx == NULL) { + OPENSSL_free(dup); + dup = NULL; + } + } + return dup; +} + +/** + * @brief Initialize an aes-128-ecb context for encryption. + * + * @param vprovctx void *vprovctx. + * @param key const unsigned char *key. + * @param keylen size_t keylen. + * @param iv const unsigned char *iv. + * @param ivlen size_t ivlen. + * @param params const OSSL_PARAM params[]. + * @return int. + */ + +static int ossl_test_aes128ecb_einit(void *vprovctx, const unsigned char *key, + size_t keylen, const unsigned char *iv, + size_t ivlen, const OSSL_PARAM params[]) +{ + PROV_EVP_AES128_ECB_CTX *ctx = (PROV_EVP_AES128_ECB_CTX *)vprovctx; + + return EVP_CipherInit_ex2(ctx->sub_ctx, NULL, key, iv, 1, params); +} + +/** + * @brief Initialize an aes-128-ecb context for decryption + * + * @param vprovctx void *vprovctx. + * @param key const unsigned char *key. + * @param keylen size_t keylen. + * @param iv const unsigned char *iv. + * @param ivlen size_t ivlen. + * @param params const OSSL_PARAM params[]. + * @return int. + */ + +static int ossl_test_aes128ecb_dinit(void *vprovctx, const unsigned char *key, + size_t keylen, const unsigned char *iv, + size_t ivlen, const OSSL_PARAM params[]) +{ + PROV_EVP_AES128_ECB_CTX *ctx = (PROV_EVP_AES128_ECB_CTX *)vprovctx; + + return EVP_CipherInit_ex2(ctx->sub_ctx, NULL, key, iv, 0, params); +} + +/** + * @brief en/decrypt data for aes-128-ecb. + * + * + * @param vprovctx void *vprovctx. + * @param out char *out. + * @param outl size_t *outl. + * @param outsize size_t outsize. + * @param in const unsigned char *in. + * @param inl size_t inl. + * @return int. + */ + +static int ossl_test_aes128ecb_update(void *vprovctx, char *out, size_t *outl, + size_t outsize, const unsigned char *in, + size_t inl) +{ + PROV_EVP_AES128_ECB_CTX *ctx = (PROV_EVP_AES128_ECB_CTX *)vprovctx; + int soutl; + uint8_t *inbuf = NULL; + int ret = 0; + + *outl = 0; + + /* + * record our input buffer + */ + inbuf = OPENSSL_zalloc(inl); + if (inbuf == NULL) + return 0; + + memcpy(inbuf, in, inl); + + if (!EVP_CipherUpdate(ctx->sub_ctx, (unsigned char *)out, &soutl, in, (int)inl)) + goto err; + + /* + * replace the ciphertext with our plain text + */ + memcpy(out, inbuf, inl); + + ret = 1; + *outl = soutl; +err: + OPENSSL_free(inbuf); + return ret; +} + +/** + * @brief Finalize the operation and produce any remaining output for aes-ecb-128 + * + * @param vprovctx void *vprovctx. + * @param out unsigned char *out. + * @param outl size_t *outl. + * @param outsize size_t outsize. + * @return int. + */ + +static int ossl_test_aes128ecb_final(void *vprovctx, unsigned char *out, size_t *outl, + size_t outsize) +{ + PROV_EVP_AES128_ECB_CTX *ctx = (PROV_EVP_AES128_ECB_CTX *)vprovctx; + int soutl; + int ret; + + ret = EVP_CipherFinal_ex(ctx->sub_ctx, out, &soutl); + + if (ret == 0 || soutl < 0) + return 0; + + *outl = (size_t)soutl; + + return ret; +} + +/** + * @brief Implement ossl test aes128ecb cipher. + * + * Note, nothing in TLS should be using this function, as we are a provider + * we just need it for completeness. + * + * @param vprovctx void *vprovctx. + * @param out unsigned char *out. + * @param outl size_t *outl. + * @param outsize size_t outsize. + * @param in const unsigned char *in. + * @param inl size_t inl. + * @return int. + */ + +static int ossl_test_aes128ecb_cipher(void *vprovctx, unsigned char *out, size_t *outl, + size_t outsize, const unsigned char *in, size_t inl) +{ + PROV_EVP_AES128_ECB_CTX *ctx = (PROV_EVP_AES128_ECB_CTX *)vprovctx; + + return EVP_Cipher(ctx->sub_ctx, out, in, (int)inl); +} + +/** + * @brief Return provider or algorithm parameters. + * + * @param params OSSL_PARAM params[]. + * @return int. + */ + +static int ossl_test_aes128ecb_get_params(OSSL_PARAM params[]) +{ + return ossl_cipher_generic_get_params(params, EVP_CIPH_ECB_MODE, 0, 128, 128, 0); +} + +/** + * @brief Query parameters from the aes-128-ecb context. + * + * @param vprovctx void *vprovctx. + * @param params OSSL_PARAM params[]. + * @return int. + */ + +static int ossl_test_aes128ecb_get_ctx_params(void *vprovctx, OSSL_PARAM params[]) +{ + PROV_EVP_AES128_ECB_CTX *ctx = (PROV_EVP_AES128_ECB_CTX *)vprovctx; + + return EVP_CIPHER_CTX_get_params(ctx->sub_ctx, params); +} + +/** + * @brief Set parameters on the aes-128-ecb context. + * + * @param vprovctx void *vprovctx. + * @param params const OSSL_PARAM params[]. + * @return int. + */ + +static int ossl_test_aes128ecb_set_ctx_params(void *vprovctx, const OSSL_PARAM params[]) +{ + PROV_EVP_AES128_ECB_CTX *ctx = (PROV_EVP_AES128_ECB_CTX *)vprovctx; + + return EVP_CIPHER_CTX_set_params(ctx->sub_ctx, params); +} + +/** + * @brief Describe parameters that can be queried for aes-128-ecb + * + * @param vprovctx void *vprovctx. + * @return const OSSL_PARAM *. + */ + +static const OSSL_PARAM *ossl_test_aes128ecb_gettable_params(void *vprovctx) +{ + PROV_EVP_AES128_ECB_CTX *ctx = (PROV_EVP_AES128_ECB_CTX *)vprovctx; + + return EVP_CIPHER_gettable_params(EVP_CIPHER_CTX_get0_cipher(ctx->sub_ctx)); +} + +/** + * @brief Describe context parameters that can be queried for aes-128-ecb. + * + * @param cctx void *cctx. + * @param vprovctx void *vprovctx. + * @return const OSSL_PARAM *. + */ + +static const OSSL_PARAM *ossl_test_aes128ecb_gettable_ctx_params(void *cctx, void *vprovctx) +{ + return ossl_cipher_generic_gettable_ctx_params(cctx, vprovctx); +} + +/** + * @brief Describe context parameters that can be set for aes-128-ecb. + * + * @param cctx void *cctx. + * @param vprovctx void *vprovctx. + * @return const OSSL_PARAM *. + */ + +static const OSSL_PARAM *ossl_test_aes128ecb_settable_ctx_params(void *cctx, void *vprovctx) +{ + PROV_EVP_AES128_ECB_CTX *ctx = (PROV_EVP_AES128_ECB_CTX *)vprovctx; + + return EVP_CIPHER_CTX_settable_params(ctx->sub_ctx); +} + +static const OSSL_DISPATCH ossl_testaes128_ecb_functions[] = { + { OSSL_FUNC_CIPHER_NEWCTX, + (void (*)(void))ossl_testaes128_ecb_newctx }, + { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))ossl_test_aes128ecb_freectx }, + { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))ossl_test_aes128ecb_dupctx }, + { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))ossl_test_aes128ecb_einit }, + { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))ossl_test_aes128ecb_dinit }, + { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_test_aes128ecb_update }, + { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_test_aes128ecb_final }, + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_test_aes128ecb_cipher }, + { OSSL_FUNC_CIPHER_GET_PARAMS, + (void (*)(void))ossl_test_aes128ecb_get_params }, + { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, + (void (*)(void))ossl_test_aes128ecb_get_ctx_params }, + { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, + (void (*)(void))ossl_test_aes128ecb_set_ctx_params }, + { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, + (void (*)(void))ossl_test_aes128ecb_gettable_params }, + { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, + (void (*)(void))ossl_test_aes128ecb_gettable_ctx_params }, + { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, + (void (*)(void))ossl_test_aes128ecb_settable_ctx_params }, + OSSL_DISPATCH_END +}; + +typedef struct { + OSSL_LIB_CTX *libctx; + EVP_CIPHER_CTX *sub_ctx; + int tls1_aad; } PROV_EVP_AES128_GCM_CTX; /** @@ -838,10 +1176,16 @@ static int ossl_test_aes128gcm_update(void *vprovctx, char *out, size_t *outl, size_t inl) { PROV_EVP_AES128_GCM_CTX *ctx = (PROV_EVP_AES128_GCM_CTX *)vprovctx; - int ret, soutl; - uint8_t *inbuf; + int ret = 0, soutl = 0; + uint8_t *inbuf = NULL; - inbuf = OPENSSL_memdup(in, inl); + *outl = 0; + + if (in != NULL && inl > 0) { + inbuf = OPENSSL_memdup(in, inl); + if (inbuf == NULL) + goto end; + } if (EVP_CIPHER_CTX_is_encrypting(ctx->sub_ctx)) ret = EVP_EncryptUpdate(ctx->sub_ctx, (unsigned char *)out, @@ -849,16 +1193,31 @@ static int ossl_test_aes128gcm_update(void *vprovctx, char *out, size_t *outl, else ret = EVP_DecryptUpdate(ctx->sub_ctx, (unsigned char *)out, &soutl, in, (int)inl); - *outl = soutl; /* * Once the cipher is complete, throw it away and use the * plaintext as our output */ - if (inbuf != NULL && out != NULL) - memcpy(out, inbuf, inl); - OPENSSL_free(inbuf); + if (ret > 0 && inbuf != NULL && out != NULL) { + if (ctx->tls1_aad && EVP_CIPHER_CTX_is_encrypting(ctx->sub_ctx)) { + if (inl < EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN) { + ret = 0; + goto end; + } + + memcpy(out + EVP_GCM_TLS_EXPLICIT_IV_LEN, + inbuf + EVP_GCM_TLS_EXPLICIT_IV_LEN, + inl - EVP_GCM_TLS_EXPLICIT_IV_LEN - EVP_GCM_TLS_TAG_LEN); + } else { + memcpy(out, inbuf, inl); + } + } + *outl = soutl; + +end: + ctx->tls1_aad = 0; + OPENSSL_free(inbuf); return ret; } @@ -955,8 +1314,15 @@ static int ossl_test_aes128gcm_get_ctx_params(void *vprovctx, OSSL_PARAM params[ static int ossl_test_aes128gcm_set_ctx_params(void *vprovctx, const OSSL_PARAM params[]) { PROV_EVP_AES128_GCM_CTX *ctx = (PROV_EVP_AES128_GCM_CTX *)vprovctx; + int tls1_aad; + int ret; - return EVP_CIPHER_CTX_set_params(ctx->sub_ctx, params); + tls1_aad = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TLS1_AAD) != NULL; + ret = EVP_CIPHER_CTX_set_params(ctx->sub_ctx, params); + if (ret) + ctx->tls1_aad = tls1_aad; + + return ret; } /** @@ -1454,6 +1820,7 @@ static const OSSL_DISPATCH ossl_testaes128cbchmacsha1_functions[] = { static const OSSL_ALGORITHM ossltest_ciphers[] = { ALG(PROV_NAMES_AES_128_CBC, ossl_testaes128_cbc_functions), + ALG(PROV_NAMES_AES_128_ECB, ossl_testaes128_ecb_functions), ALG(PROV_NAMES_AES_128_GCM, ossl_testaes128_gcm_functions), ALG(PROV_NAMES_AES_128_CBC_HMAC_SHA1, ossl_testaes128cbchmacsha1_functions), { NULL, NULL, NULL } diff --git a/test/p_test.c b/test/p_test.c index 655cb7ce6fc8f..aca1707b05cb0 100644 --- a/test/p_test.c +++ b/test/p_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/pairwise_fail_test.c b/test/pairwise_fail_test.c index 3446d23166e52..628f123cb2711 100644 --- a/test/pairwise_fail_test.c +++ b/test/pairwise_fail_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/param_build_test.c b/test/param_build_test.c index bac0afcb34410..c860acb601700 100644 --- a/test/param_build_test.c +++ b/test/param_build_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use diff --git a/test/params_test.c b/test/params_test.c index f5f0623bc90bd..182fadfc39432 100644 --- a/test/params_test.c +++ b/test/params_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/pathed.cnf b/test/pathed.cnf.in similarity index 83% rename from test/pathed.cnf rename to test/pathed.cnf.in index 07bdc1fdb209a..661299ad0956a 100644 --- a/test/pathed.cnf +++ b/test/pathed.cnf.in @@ -1,3 +1,4 @@ +{- use platform -} openssl_conf = openssl_init # Comment out the next line to ignore configuration errors @@ -12,7 +13,7 @@ legacy = legacy_sect test = test_sect [test_sect] -module = ../test/p_test.so +module = ../test/{- platform->dso("p_test") -} activate = false [default_sect] diff --git a/test/pbetest.c b/test/pbetest.c index 42ae4a4da9c38..234d59b5b79b0 100644 --- a/test/pbetest.c +++ b/test/pbetest.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,6 +8,8 @@ */ #include +#include +#include #include "testutil.h" @@ -17,6 +19,7 @@ #include #include #include +#include #if !defined OPENSSL_NO_RC4 && !defined OPENSSL_NO_MD5 \ || !defined OPENSSL_NO_DES && !defined OPENSSL_NO_SHA1 @@ -125,6 +128,179 @@ static int test_pkcs5_pbe_des_sha1(void) } #endif +/* + * Regression test for negative EVP_CIPHER_get_iv_length() return in + * PKCS5_pbe2_set_scrypt(). + * + * A malicious/buggy provider advertises SIZE_MAX as IV length. + * evp_cipher_cache_constants() casts (size_t)SIZE_MAX to int => -1. + * Without the ivlen > 0 guard, this -1 is implicitly converted to SIZE_MAX + * in the memcpy call, causing a stack buffer overflow. + * + * This test verifies that PKCS5_pbe2_set_scrypt() handles negative IV + * lengths gracefully (returns NULL, no crash). + */ +#ifndef OPENSSL_NO_SCRYPT + +static void *bad_iv_cipher_newctx(void *provctx) +{ + static int dummy; + return &dummy; +} + +static void bad_iv_cipher_freectx(void *vctx) +{ +} + +static int bad_iv_cipher_cipher(void *vctx, + unsigned char *out, size_t *outl, + size_t outsz, + const unsigned char *in, size_t inl) +{ + if (outl != NULL) + *outl = 0; + return 1; +} + +/* + * Advertise SIZE_MAX as IV length. After evp_cipher_cache_constants() + * stores (int)SIZE_MAX, EVP_CIPHER_get_iv_length() returns -1. + */ +static int bad_iv_cipher_get_params(OSSL_PARAM params[]) +{ + OSSL_PARAM *p; + + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_BLOCK_SIZE); + if (p != NULL && !OSSL_PARAM_set_size_t(p, 16)) + return 0; + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN); + if (p != NULL && !OSSL_PARAM_set_size_t(p, 32)) + return 0; + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_MODE); + if (p != NULL && !OSSL_PARAM_set_uint(p, EVP_CIPH_CBC_MODE)) + return 0; + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); + if (p != NULL && !OSSL_PARAM_set_size_t(p, SIZE_MAX)) + return 0; + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD); + if (p != NULL && !OSSL_PARAM_set_int(p, 0)) + return 0; + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CUSTOM_IV); + if (p != NULL && !OSSL_PARAM_set_int(p, 0)) + return 0; + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_CTS); + if (p != NULL && !OSSL_PARAM_set_int(p, 0)) + return 0; + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_TLS1_MULTIBLOCK); + if (p != NULL && !OSSL_PARAM_set_int(p, 0)) + return 0; + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_HAS_RAND_KEY); + if (p != NULL && !OSSL_PARAM_set_int(p, 0)) + return 0; + p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_ENCRYPT_THEN_MAC); + if (p != NULL && !OSSL_PARAM_set_int(p, 0)) + return 0; + return 1; +} + +static const OSSL_DISPATCH bad_iv_cipher_fns[] = { + { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))bad_iv_cipher_newctx }, + { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))bad_iv_cipher_freectx }, + { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))bad_iv_cipher_cipher }, + { OSSL_FUNC_CIPHER_GET_PARAMS, (void (*)(void))bad_iv_cipher_get_params }, + OSSL_DISPATCH_END +}; + +static const OSSL_ALGORITHM bad_iv_cipher_algs[] = { + { "AES-256-CBC:AES256", "provider=bad-iv-prov", bad_iv_cipher_fns, + "Bad IV length cipher for regression testing" }, + { NULL, NULL, NULL, NULL } +}; + +static const OSSL_ALGORITHM *bad_iv_query(void *provctx, + int operation_id, + int *no_cache) +{ + *no_cache = 0; + if (operation_id == OSSL_OP_CIPHER) + return bad_iv_cipher_algs; + return NULL; +} + +static void bad_iv_teardown(void *provctx) { } + +static const OSSL_DISPATCH bad_iv_provider_fns[] = { + { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))bad_iv_teardown }, + { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))bad_iv_query }, + OSSL_DISPATCH_END +}; + +static int bad_iv_provider_init(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in, + const OSSL_DISPATCH **out, + void **provctx) +{ + static int ctx; + + *provctx = &ctx; + *out = bad_iv_provider_fns; + return 1; +} + +/* + * Test that PKCS5_pbe2_set_scrypt() does not crash when + * EVP_CIPHER_get_iv_length() returns a negative value. + */ +static int test_pkcs5_scrypt_bad_iv_length(void) +{ + int ret = 0; + OSSL_LIB_CTX *libctx = NULL; + OSSL_PROVIDER *bad_prov = NULL; + EVP_CIPHER *cipher = NULL; + X509_ALGOR *alg = NULL; + unsigned char salt[16] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 + }; + unsigned char iv[16] = { 0xAA }; + + if (!TEST_ptr(libctx = OSSL_LIB_CTX_new())) + goto err; + + if (!TEST_true(OSSL_PROVIDER_add_builtin(libctx, "bad-iv-prov", + bad_iv_provider_init))) + goto err; + + if (!TEST_ptr(bad_prov = OSSL_PROVIDER_load(libctx, "bad-iv-prov"))) + goto err; + + if (!TEST_ptr(cipher = EVP_CIPHER_fetch(libctx, "AES-256-CBC", + "provider=bad-iv-prov"))) + goto err; + + if (!TEST_int_lt(EVP_CIPHER_get_iv_length(cipher), 0)) + goto err; + + /* + * Before the fix, this would trigger memcpy(iv[16], aiv, SIZE_MAX) + * — a stack buffer overflow. After the fix, the function must + * return NULL. + */ + alg = PKCS5_pbe2_set_scrypt(cipher, salt, (int)sizeof(salt), + iv, 1024, 8, 1); + if (!TEST_ptr_null(alg)) + goto err; + + ret = 1; +err: + X509_ALGOR_free(alg); + EVP_CIPHER_free(cipher); + OSSL_PROVIDER_unload(bad_prov); + OSSL_LIB_CTX_free(libctx); + return ret; +} +#endif /* OPENSSL_NO_SCRYPT */ + #ifdef OPENSSL_NO_AUTOLOAD_CONFIG /* * For configurations where we are not autoloading configuration, we need @@ -152,6 +328,9 @@ int setup_tests(void) #if !defined OPENSSL_NO_DES && !defined OPENSSL_NO_SHA1 ADD_TEST(test_pkcs5_pbe_des_sha1); #endif +#ifndef OPENSSL_NO_SCRYPT + ADD_TEST(test_pkcs5_scrypt_bad_iv_length); +#endif return 1; } diff --git a/test/pkcs12_api_test.c b/test/pkcs12_api_test.c index 150a3cf29dd6a..940b7625f0531 100644 --- a/test/pkcs12_api_test.c +++ b/test/pkcs12_api_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -60,6 +60,12 @@ static const char *in_pass = ""; static int has_key = 0; static int has_cert = 0; static int has_ca = 0; +static int expected_ca_count = -1; +static const char *expected_cert_file = NULL; +static const char *expected_ca_file = NULL; +static const char *expected_key_file = NULL; +static int mismatched_key_pass = 0; +static int num_skeys = 0; static int changepass(PKCS12 *p12, EVP_PKEY *key, X509 *cert, STACK_OF(X509) *ca) { @@ -108,6 +114,9 @@ static int pkcs12_parse_test(void) X509 *cert = NULL; STACK_OF(X509) *ca = NULL; + if (mismatched_key_pass) + return TEST_skip("not applicable with mismatched key password"); + if (in_file != NULL) { p12 = PKCS12_load(in_file); if (!TEST_ptr(p12)) @@ -134,6 +143,155 @@ static int pkcs12_parse_test(void) return TEST_true(ret); } +static int test_parse_combinations(int idx) +{ + int ret = 0; + PKCS12 *p12 = NULL; + EVP_PKEY *key = NULL; + X509 *cert = NULL; + STACK_OF(X509) *ca = NULL; + int want_key = (idx >> 2) & 1; + int want_cert = (idx >> 1) & 1; + int want_ca = idx & 1; + + if (in_file == NULL || !has_key || !has_cert) + return 1; + + if (!TEST_int_ge(expected_ca_count, 0)) + return TEST_skip("test_parse_combinations requires -ca-count parameter"); + + TEST_info("combination %d: want_key=%d want_cert=%d want_ca=%d", + idx, want_key, want_cert, want_ca); + + if (!TEST_ptr(p12 = PKCS12_load(in_file))) + goto err; + if (!TEST_true(PKCS12_parse(p12, in_pass, + want_key ? &key : NULL, + want_cert ? &cert : NULL, + want_ca ? &ca : NULL))) + goto err; + + if (want_key) { + if (!TEST_ptr(key)) + goto err; + } + + if (want_cert) { + /* + * PKCS12_parse only sets *cert when the key is also requested and + * found, because it matches certs against *pkey. + */ + if (want_key) { + if (!TEST_ptr(cert)) + goto err; + } else { + if (!TEST_ptr_null(cert)) + goto err; + } + } + + if (want_ca) { + int actual_ca_count = ca == NULL ? 0 : sk_X509_num(ca); + int expected_count = expected_ca_count; + + /* + * The matching cert is only excluded from the CA stack when both + * key and cert pointers are provided. Otherwise it ends up in CA. + */ + if (!want_key || !want_cert) + expected_count++; + + if (!TEST_int_eq(actual_ca_count, expected_count)) + goto err; + } + + ret = 1; +err: + if (!ret) + TEST_info("failed combination %d: want_key=%d want_cert=%d want_ca=%d", + idx, want_key, want_cert, want_ca); + PKCS12_free(p12); + EVP_PKEY_free(key); + X509_free(cert); + OSSL_STACK_OF_X509_free(ca); + return ret; +} + +/* + * If appending an additional certificate to the CA stack fails, + * PKCS12_parse() should free its own allocated CA stack. + */ +static int pkcs12_parse_mfail_test(void) +{ + int ret; + PKCS12 *p12 = NULL; + STACK_OF(X509) *ca = NULL; + + if (!TEST_ptr(p12 = PKCS12_load(in_file))) + return -1; + + MFAIL_start(); + ret = PKCS12_parse(p12, in_pass, NULL, NULL, &ca); + MFAIL_end(); + + if (ret == 0 && !TEST_ptr_null(ca)) + ret = -1; + + /* + * Only free the stack on success, since PKCS12_parse() + * should free its own allocated stack on failure. + */ + if (ret == 1) + OSSL_STACK_OF_X509_free(ca); + + PKCS12_free(p12); + return ret; +} + +/* + * If appending an additional certificate to the CA stack fails, + * PKCS12_parse() should leave the original CA stack unmodified. + */ +static int pkcs12_parse_existing_ca_mfail_test(void) +{ + int i, ret = -1; + PKCS12 *p12 = NULL; + STACK_OF(X509) *ca = NULL, *initial_ca = NULL; + X509 *initial_certs[3] = { NULL }; + + if (!TEST_ptr(p12 = PKCS12_load(in_file)) + || !TEST_ptr(ca = sk_X509_new_null())) + goto err; + + for (i = 0; i < 3; i++) { + if (!TEST_ptr(initial_certs[i] = X509_new())) + goto err; + + if (!TEST_true(sk_X509_push(ca, initial_certs[i]))) { + X509_free(initial_certs[i]); + goto err; + } + } + initial_ca = ca; + + MFAIL_start(); + ret = PKCS12_parse(p12, in_pass, NULL, NULL, &ca); + MFAIL_end(); + + if (ret == 0 + && (!TEST_ptr_eq(ca, initial_ca) + || !TEST_int_eq(sk_X509_num(ca), 3) + || !TEST_ptr_eq(sk_X509_value(ca, 0), initial_certs[0]) + || !TEST_ptr_eq(sk_X509_value(ca, 1), initial_certs[1]) + || !TEST_ptr_eq(sk_X509_value(ca, 2), initial_certs[2]))) + ret = -1; + +err: + PKCS12_free(p12); + OSSL_STACK_OF_X509_free(ca); + return ret; +} + static int pkcs12_create_cb(PKCS12_SAFEBAG *bag, void *cbarg) { int cb_ret = *((int *)cbarg); @@ -226,6 +384,181 @@ static int pkcs12_create_ex2_test(int test) return TEST_true(ret); } +static int test_parse_ex_libctx(int idx) +{ + int ret = 0; + BIO *bio = NULL; + PKCS12 *p12 = NULL; + PKCS12_PARSE_CTX *ctx = NULL; + EVP_PKEY *key = NULL; + X509 *cert = NULL; + int prebound = (idx == 0); + + if (in_file == NULL || !has_key || !has_cert || mismatched_key_pass) + return 1; + + TEST_info("libctx propagation: %s decode", prebound ? "prebound" : "ordinary"); + + bio = BIO_new_file(in_file, "rb"); + if (!TEST_ptr(bio)) + goto err; + + if (prebound) { + p12 = PKCS12_init_ex(NID_pkcs7_data, testctx, "provider=default"); + if (!TEST_ptr(p12)) + goto err; + } + if (!TEST_ptr(d2i_PKCS12_bio(bio, &p12))) + goto err; + BIO_free(bio); + bio = NULL; + + if (!TEST_ptr(ctx = PKCS12_PARSE_CTX_new())) + goto err; + PKCS12_PARSE_CTX_set_pkey(ctx, &key); + PKCS12_PARSE_CTX_set_cert(ctx, &cert); + + if (!TEST_true(PKCS12_parse_ex(p12, in_pass, ctx, + testctx, "provider=default"))) + goto err; + + if (!TEST_ptr(key) || !TEST_ptr(cert)) + goto err; + + ret = 1; + +err: + BIO_free(bio); + PKCS12_PARSE_CTX_free(ctx); + PKCS12_free(p12); + EVP_PKEY_free(key); + X509_free(cert); + return ret; +} + +static int test_parse_ex_skey(void) +{ + PKCS12 *p12 = NULL; + PKCS12_PARSE_CTX *ctx = NULL; + EVP_PKEY *pkey = NULL; + X509 *cert = NULL; + STACK_OF(X509) *ca = NULL; + STACK_OF(EVP_SKEY) *skeys = NULL; + EVP_SKEY *skey = NULL; + const unsigned char *raw_key = NULL; + size_t raw_key_len = 0; + int ret = 0; + + if (in_file == NULL || mismatched_key_pass) + return 1; + + if (!TEST_ptr(p12 = PKCS12_load(in_file))) + goto err; + + if (!TEST_ptr(ctx = PKCS12_PARSE_CTX_new())) + goto err; + + PKCS12_PARSE_CTX_set_pkey(ctx, &pkey); + PKCS12_PARSE_CTX_set_cert(ctx, &cert); + PKCS12_PARSE_CTX_set_ca(ctx, &ca); + PKCS12_PARSE_CTX_set_skeys(ctx, &skeys); + + if (!TEST_true(PKCS12_parse_ex(p12, in_pass, ctx, + testctx, "provider=default"))) + goto err; + + if ((has_key && !TEST_ptr(pkey)) || (!has_key && !TEST_ptr_null(pkey))) + goto err; + if ((has_cert && !TEST_ptr(cert)) || (!has_cert && !TEST_ptr_null(cert))) + goto err; + if (num_skeys > 0) { + if (!TEST_ptr(skeys) + || !TEST_int_eq(sk_EVP_SKEY_num(skeys), num_skeys)) + goto err; + } else { + if (!TEST_ptr_null(skeys)) + goto err; + } + + if (num_skeys == 1 && skeys != NULL) { + skey = sk_EVP_SKEY_value(skeys, 0); + if (!TEST_ptr(skey)) + goto err; + if (!TEST_true(EVP_SKEY_get0_raw_key(skey, &raw_key, &raw_key_len))) + goto err; + if (!TEST_size_t_eq(raw_key_len, 32)) + goto err; + for (size_t i = 0; i < raw_key_len; i++) { + if (!TEST_uchar_eq(raw_key[i], 0x41)) + goto err; + } + if (!TEST_str_eq(EVP_SKEY_get0_skeymgmt_name(skey), "AES")) + goto err; + } + + ret = 1; + +err: + PKCS12_PARSE_CTX_free(ctx); + PKCS12_free(p12); + EVP_PKEY_free(pkey); + X509_free(cert); + OSSL_STACK_OF_X509_free(ca); + sk_EVP_SKEY_pop_free(skeys, EVP_SKEY_free); + return ret; +} + +static int test_parse_ex_skey_libctx(int idx) +{ + PKCS12 *src = NULL, *p12 = NULL; + STACK_OF(PKCS7) *safes = NULL; + PKCS12_PARSE_CTX *ctx = NULL; + STACK_OF(EVP_SKEY) *skeys = NULL; + int ret = 0; + + if (in_file == NULL || num_skeys == 0) + return 1; + + if (!TEST_ptr(src = PKCS12_load(in_file)) + || !TEST_ptr(safes = PKCS12_unpack_authsafes(src))) + goto err; + + if (!TEST_ptr(p12 = PKCS12_init_ex(NID_pkcs7_data, testctx, + idx < 2 ? "provider=missing" : "provider=default"))) + goto err; + + /* Omit the MAC so the test reaches decryption of the secret bag. */ + if (!TEST_true(PKCS12_pack_authsafes(p12, safes)) + || !TEST_ptr(ctx = PKCS12_PARSE_CTX_new())) + goto err; + PKCS12_PARSE_CTX_set_skeys(ctx, &skeys); + + if (idx < 2) { + /* Neither NULL nor an empty query should use the stored query. */ + if (!TEST_true(PKCS12_parse_ex(p12, in_pass, ctx, + testctx, idx == 0 ? NULL : "")) + || !TEST_ptr(skeys) + || !TEST_int_eq(sk_EVP_SKEY_num(skeys), num_skeys)) + goto err; + } else { + /* The default library context contains only the null provider. */ + if (!TEST_false(PKCS12_parse_ex(p12, in_pass, ctx, + NULL, idx == 2 ? NULL : "provider=default")) + || !TEST_ptr_null(skeys)) + goto err; + ERR_clear_error(); + } + + ret = 1; +err: + sk_EVP_SKEY_pop_free(skeys, EVP_SKEY_free); + PKCS12_PARSE_CTX_free(ctx); + sk_PKCS7_pop_free(safes, PKCS7_free); + PKCS12_free(p12); + PKCS12_free(src); + return ret; +} + typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, @@ -234,6 +567,12 @@ typedef enum OPTION_choice { OPT_IN_HAS_KEY, OPT_IN_HAS_CERT, OPT_IN_HAS_CA, + OPT_CA_COUNT, + OPT_EXPECTED_CERT, + OPT_EXPECTED_CA, + OPT_EXPECTED_KEY, + OPT_MISMATCHED_P12, + OPT_IN_NUM_SKEYS, OPT_LEGACY, OPT_TEST_ENUM } OPTION_CHOICE; @@ -247,6 +586,12 @@ const OPTIONS *test_get_options(void) { "has-key", OPT_IN_HAS_KEY, 'n', "Whether the input file does contain an user key" }, { "has-cert", OPT_IN_HAS_CERT, 'n', "Whether the input file does contain an user certificate" }, { "has-ca", OPT_IN_HAS_CA, 'n', "Whether the input file does contain other certificate" }, + { "ca-count", OPT_CA_COUNT, 'n', "Expected number of CA certificates" }, + { "expected-cert", OPT_EXPECTED_CERT, '<', "PEM file of expected main certificate" }, + { "expected-ca", OPT_EXPECTED_CA, '<', "PEM file of expected CA certificates in order" }, + { "expected-key", OPT_EXPECTED_KEY, '<', "PEM file of expected private key" }, + { "mismatched-key-pass", OPT_MISMATCHED_P12, '-', "Input has key encrypted with a different password" }, + { "num-skeys", OPT_IN_NUM_SKEYS, 'n', "Number of symmetric keys in the input file" }, { "legacy", OPT_LEGACY, '-', "Test the legacy APIs" }, { NULL } }; @@ -261,11 +606,20 @@ static int test_PKCS12_set_pbmac1_pbkdf2_saltlen_zero(void) STACK_OF(X509) *ca = NULL; PKCS12 *p12 = NULL; + if (mismatched_key_pass) + return TEST_skip("not applicable with mismatched key password"); + if (!TEST_ptr(p12 = PKCS12_load(in_file))) return 0; if (!TEST_true(PKCS12_parse(p12, in_pass, &key, &cert, &ca))) goto err; PKCS12_free(p12); + p12 = NULL; + + if (key == NULL && cert == NULL && ca == NULL) { + ret = 1; + goto err; + } if (!TEST_ptr(p12 = PKCS12_create_ex2("pass", NULL, key, cert, ca, NID_undef, NID_undef, 0, -1, 0, @@ -289,11 +643,20 @@ static int test_PKCS12_set_pbmac1_pbkdf2_invalid_saltlen(void) STACK_OF(X509) *ca = NULL; PKCS12 *p12 = NULL; + if (mismatched_key_pass) + return TEST_skip("not applicable with mismatched key password"); + if (!TEST_ptr(p12 = PKCS12_load(in_file))) return 0; if (!TEST_true(PKCS12_parse(p12, in_pass, &key, &cert, &ca))) goto err; PKCS12_free(p12); + p12 = NULL; + + if (key == NULL && cert == NULL && ca == NULL) { + ret = 1; + goto err; + } if (!TEST_ptr(p12 = PKCS12_create_ex2("pass", NULL, key, cert, ca, NID_undef, NID_undef, 0, -1, 0, @@ -309,6 +672,137 @@ static int test_PKCS12_set_pbmac1_pbkdf2_invalid_saltlen(void) return ret; } +static int test_parse_cert_placement(int idx) +{ + int ret = 0, i, pos = 0; + int want_key = (idx >> 2) & 1; + int want_cert = (idx >> 1) & 1; + int want_ca = idx & 1; + int selected = want_key && want_cert ? 1 : -1; + PKCS12 *p12 = NULL; + EVP_PKEY *key = NULL, *exp_key = NULL; + X509 *cert = NULL, *exp_cert = NULL; + X509 *ordered[3]; + STACK_OF(X509) *ca = NULL, *exp_ca = NULL, *all = NULL; + + if (expected_key_file == NULL && expected_cert_file == NULL + && expected_ca_file == NULL) + return 1; + + if (!TEST_ptr(exp_key = load_pkey_pem(expected_key_file, testctx)) + || !TEST_ptr(exp_cert = load_cert_pem(expected_cert_file, testctx)) + || !TEST_ptr(exp_ca = load_certs_pem(expected_ca_file)) + || !TEST_int_eq(sk_X509_num(exp_ca), 2) + || !TEST_int_ne(X509_cmp(exp_cert, sk_X509_value(exp_ca, 0)), 0) + || !TEST_ptr(all = sk_X509_new_null())) + goto err; + + /* extra_certs.pem contains the second match, then the unrelated cert. */ + ordered[0] = sk_X509_value(exp_ca, 1); + ordered[1] = exp_cert; + ordered[2] = sk_X509_value(exp_ca, 0); + for (i = 0; i < (int)OSSL_NELEM(ordered); i++) { + if (!TEST_int_gt(sk_X509_push(all, ordered[i]), 0)) + goto err; + } + + /* Passing all certificates through ca preserves the chosen order. */ + p12 = PKCS12_create_ex("", NULL, exp_key, NULL, all, + NID_undef, NID_undef, 0, -1, 0, testctx, "provider=default"); + if (!TEST_ptr(p12) + || !TEST_true(PKCS12_parse(p12, "", + want_key ? &key : NULL, + want_cert ? &cert : NULL, + want_ca ? &ca : NULL))) + goto err; + + if (want_key + && (!TEST_ptr(key) || !TEST_int_eq(EVP_PKEY_eq(key, exp_key), 1))) + goto err; + + if (want_cert) { + if (selected >= 0) { + if (!TEST_ptr(cert) + || !TEST_int_eq(X509_cmp(cert, exp_cert), 0)) + goto err; + } else if (!TEST_ptr_null(cert)) { + goto err; + } + } + + if (want_ca) { + if (!TEST_ptr(ca) + || !TEST_int_eq(sk_X509_num(ca), selected >= 0 ? 2 : 3)) + goto err; + for (i = 0; i < (int)OSSL_NELEM(ordered); i++) { + if (i == selected) + continue; + if (!TEST_int_eq(X509_cmp(sk_X509_value(ca, pos), ordered[i]), 0)) { + TEST_info("CA cert mismatch at index %d", pos); + goto err; + } + pos++; + } + } + + ret = 1; +err: + if (!ret) + TEST_info("failed placement combination %d", idx); + PKCS12_free(p12); + EVP_PKEY_free(key); + EVP_PKEY_free(exp_key); + X509_free(cert); + X509_free(exp_cert); + OSSL_STACK_OF_X509_free(ca); + OSSL_STACK_OF_X509_free(exp_ca); + sk_X509_free(all); + return ret; +} + +/* + * Load a pre-built PKCS#12 whose MAC and cert use one password but whose + * private key is encrypted with a different one. Parsing without requesting + * the key must succeed (cert lands in the CA stack); requesting it must fail. + */ +static int test_parse_mismatched_key_password(void) +{ + int ret = 0; + PKCS12 *p12 = NULL; + EVP_PKEY *key = NULL; + X509 *cert = NULL; + STACK_OF(X509) *ca = NULL; + + if (in_file == NULL || !mismatched_key_pass) + return 1; + + p12 = PKCS12_load(in_file); + if (!TEST_ptr(p12)) + goto err; + + /* Omitting the key pointer succeeds; cert lands in the CA stack */ + if (!TEST_true(PKCS12_parse(p12, in_pass, NULL, NULL, &ca))) + goto err; + if (!TEST_ptr(ca) || !TEST_int_eq(sk_X509_num(ca), 1)) + goto err; + OSSL_STACK_OF_X509_free(ca); + ca = NULL; + + /* Requesting the key fails: wrong password for the shrouded key bag */ + ERR_set_mark(); + if (!TEST_false(PKCS12_parse(p12, in_pass, &key, &cert, &ca))) + goto err; + ERR_pop_to_mark(); + + ret = 1; +err: + PKCS12_free(p12); + EVP_PKEY_free(key); + X509_free(cert); + OSSL_STACK_OF_X509_free(ca); + return ret; +} + int setup_tests(void) { OPTION_CHOICE o; @@ -332,6 +826,24 @@ int setup_tests(void) case OPT_IN_HAS_CA: has_ca = opt_int_arg(); break; + case OPT_CA_COUNT: + expected_ca_count = opt_int_arg(); + break; + case OPT_EXPECTED_CERT: + expected_cert_file = opt_arg(); + break; + case OPT_EXPECTED_CA: + expected_ca_file = opt_arg(); + break; + case OPT_EXPECTED_KEY: + expected_key_file = opt_arg(); + break; + case OPT_MISMATCHED_P12: + mismatched_key_pass = 1; + break; + case OPT_IN_NUM_SKEYS: + num_skeys = opt_int_arg(); + break; case OPT_TEST_CASES: break; default: @@ -347,9 +859,17 @@ int setup_tests(void) ADD_TEST(test_null_args); ADD_TEST(pkcs12_parse_test); + ADD_ALL_TESTS(test_parse_combinations, 8); + ADD_ALL_TESTS(test_parse_cert_placement, 8); + ADD_TEST(test_parse_mismatched_key_password); + ADD_MFAIL_NO_CHECK_TEST(pkcs12_parse_mfail_test); + ADD_MFAIL_NO_CHECK_TEST(pkcs12_parse_existing_ca_mfail_test); ADD_ALL_TESTS(pkcs12_create_ex2_test, 3); ADD_TEST(test_PKCS12_set_pbmac1_pbkdf2_saltlen_zero); ADD_TEST(test_PKCS12_set_pbmac1_pbkdf2_invalid_saltlen); + ADD_TEST(test_parse_ex_skey); + ADD_ALL_TESTS(test_parse_ex_libctx, 2); + ADD_ALL_TESTS(test_parse_ex_skey_libctx, 4); return 1; } diff --git a/test/pkcs12_format_test.c b/test/pkcs12_format_test.c index 4ae4cbfec5cb7..b353ef5ccf831 100644 --- a/test/pkcs12_format_test.c +++ b/test/pkcs12_format_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -443,7 +443,7 @@ static int test_single_key(PKCS12_ENC *enc) char fname[80]; PKCS12_BUILDER *pb; - BIO_snprintf(fname, sizeof(fname), "1key_ciph-%s_iter-%d.p12", + snprintf(fname, sizeof(fname), "1key_ciph-%s_iter-%d.p12", OBJ_nid2sn(enc->nid), enc->iter); pb = new_pkcs12_builder(fname); @@ -543,7 +543,7 @@ static int test_single_cert_mac(PKCS12_ENC *mac) char fname[80]; PKCS12_BUILDER *pb; - BIO_snprintf(fname, sizeof(fname), "1cert_mac-%s_iter-%d.p12", + snprintf(fname, sizeof(fname), "1cert_mac-%s_iter-%d.p12", OBJ_nid2sn(mac->nid), mac->iter); pb = new_pkcs12_builder(fname); @@ -704,7 +704,7 @@ static int test_single_secret(PKCS12_ENC *enc) char fname[80]; PKCS12_BUILDER *pb; - BIO_snprintf(fname, sizeof(fname), "1secret_ciph-%s_iter-%d.p12", + snprintf(fname, sizeof(fname), "1secret_ciph-%s_iter-%d.p12", OBJ_nid2sn(enc->nid), enc->iter); pb = new_pkcs12_builder(fname); custom_nid = get_custom_oid(); diff --git a/test/pkcs7_test.c b/test/pkcs7_test.c index 851410112110a..ea0f2fa5e3c9c 100644 --- a/test/pkcs7_test.c +++ b/test/pkcs7_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -15,6 +16,58 @@ #include "internal/nelem.h" #include "testutil.h" +static X509 *smimecap_cert = NULL; +static EVP_PKEY *smimecap_privkey = NULL; + +static int smimecap_has_nid(STACK_OF(X509_ALGOR) *smcap, int nid) +{ + int i; + + for (i = 0; i < sk_X509_ALGOR_num(smcap); i++) { + X509_ALGOR *alg = sk_X509_ALGOR_value(smcap, i); + if (OBJ_obj2nid(alg->algorithm) == nid) + return 1; + } + return 0; +} + +static int test_pkcs7_smimecap(void) +{ + PKCS7 *p7 = NULL; + PKCS7_SIGNER_INFO *si = NULL; + STACK_OF(X509_ALGOR) *smcap = NULL; + int ret = 0; + + if (!TEST_ptr(p7 = PKCS7_new()) + || !TEST_true(PKCS7_set_type(p7, NID_pkcs7_signed)) + || !TEST_true(PKCS7_content_new(p7, NID_pkcs7_data)) + || !TEST_ptr(si = PKCS7_sign_add_signer(p7, smimecap_cert, + smimecap_privkey, NULL, 0)) + || !TEST_int_eq(ERR_peek_error(), 0)) + goto end; + + if (!TEST_ptr(smcap = PKCS7_get_smimecap(si))) + goto end; + + /* AES ciphers must be present with the default provider */ + if (!TEST_true(smimecap_has_nid(smcap, NID_aes_256_cbc)) + || !TEST_true(smimecap_has_nid(smcap, NID_aes_192_cbc)) + || !TEST_true(smimecap_has_nid(smcap, NID_aes_128_cbc))) + goto end; + + /* RC2, DES, and GOST must NOT be present with just the default provider */ + if (!TEST_false(smimecap_has_nid(smcap, NID_rc2_cbc)) + || !TEST_false(smimecap_has_nid(smcap, NID_des_cbc)) + || !TEST_false(smimecap_has_nid(smcap, NID_id_Gost28147_89))) + goto end; + + ret = 1; +end: + sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); + PKCS7_free(p7); + return ret; +} + static int pkcs7_issuer_and_serial_negative_idx_test(void) { PKCS7 *p7 = NULL; @@ -181,6 +234,7 @@ static int pkcs7_verify_test(void) && TEST_int_eq(ERR_peek_error(), 0) && TEST_ptr(store = X509_STORE_new()) && TEST_true(X509_STORE_add_cert(store, cert)) + && TEST_true(X509_STORE_set_flags(store, X509_V_FLAG_NO_CHECK_TIME)) && TEST_ptr(p7 = SMIME_read_PKCS7(bio, NULL)) && TEST_int_eq(ERR_peek_error(), 0) && TEST_true(PKCS7_verify(p7, NULL, store, msg_bio, NULL, PKCS7_TEXT)) @@ -411,12 +465,130 @@ static int pkcs7_inner_content_verify_test(void) } #endif /* OPENSSL_NO_EC */ +static int pkcs7_stream_enveloped_no_content_test(void) +{ + int ret = 0; + PKCS7 *p7 = NULL; + BIO *sink = NULL; + BIO *bio = NULL; + + const unsigned char data_enveloped_no_body[] = { 0x30, 0x0b, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x03 }; + const unsigned char *ptr_env_no_body = data_enveloped_no_body; + + ret = TEST_ptr(p7 = d2i_PKCS7(NULL, &ptr_env_no_body, + sizeof(data_enveloped_no_body))) + && TEST_ptr(sink = BIO_new(BIO_s_null())) + && TEST_ptr_null(bio = BIO_new_PKCS7(sink, p7)) + && TEST_int_eq(ERR_GET_REASON(ERR_peek_last_error()), + PKCS7_R_NO_CONTENT); + + BIO_free(bio); + BIO_free(sink); + PKCS7_free(p7); + return ret; +} + +static int pkcs7_stream_enveloped_signed_no_content_test(void) +{ + int ret = 0; + PKCS7 *p7 = NULL; + BIO *sink = NULL; + BIO *bio = NULL; + + const unsigned char data_enveloped_signed_no_body[] = { 0x30, 0x0b, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x04 }; + const unsigned char *ptr_env_signed_no_body = data_enveloped_signed_no_body; + + ret = TEST_ptr(p7 = d2i_PKCS7(NULL, &ptr_env_signed_no_body, + sizeof(data_enveloped_signed_no_body))) + && TEST_ptr(sink = BIO_new(BIO_s_null())) + && TEST_ptr_null(bio = BIO_new_PKCS7(sink, p7)) + && TEST_int_eq(ERR_GET_REASON(ERR_peek_last_error()), + PKCS7_R_NO_CONTENT); + + BIO_free(bio); + BIO_free(sink); + PKCS7_free(p7); + return ret; +} + +static int pkcs7_stream_non_data_test(void) +{ + int ret = 0; + PKCS7 *p7 = NULL; + BIO *sink = NULL; + BIO *bio = NULL; + + /* clang-format off */ + static const unsigned char malformed_der[] = { + 0x30, 0x32, /* SEQUENCE, 50 bytes */ + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, /* pkcs7-signedData */ + 0xa0, 0x25, /* [0] EXPLICIT, 37 bytes */ + 0x30, 0x23, /* SEQUENCE PKCS7_SIGNED, 35 bytes */ + 0x02, 0x01, 0x01, /* INTEGER version=1 */ + 0x31, 0x00, /* SET{} md_algs */ + 0x30, 0x1a, /* SEQUENCE inner PKCS7 (contents), 26 bytes */ + 0x06, 0x0b, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x04, /* id-ct-TSTInfo */ + 0xa0, 0x0b, /* [0] EXPLICIT, 11 bytes (makes d.other non-NULL) */ + 0x30, 0x09, /* SEQUENCE */ + 0x02, 0x01, 0x01, /* INTEGER 1 */ + 0x04, 0x04, 0xde, 0xad, 0xbe, 0xef, /* OCTET STRING */ + 0x31, 0x00, /* SET{} signer_info */ + }; + /* clang-format on */ + + const unsigned char *ptr_malformed_der = malformed_der; + + ret = TEST_ptr(p7 = d2i_PKCS7(NULL, &ptr_malformed_der, sizeof(malformed_der))) + && TEST_ptr(sink = BIO_new(BIO_s_null())) + && TEST_ptr_null(bio = BIO_new_PKCS7(sink, p7)) + && TEST_int_eq(ERR_GET_REASON(ERR_peek_last_error()), PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + + BIO_free(bio); + BIO_free(sink); + PKCS7_free(p7); + return ret; +} + int setup_tests(void) { + const char *certin, *privkeyin; + BIO *bio = NULL; + + if (!test_skip_common_options()) { + TEST_error("Error parsing test options\n"); + return 0; + } + + certin = test_get_argument(0); + privkeyin = test_get_argument(1); + if (certin != NULL && privkeyin != NULL) { + if (TEST_ptr(bio = BIO_new_file(certin, "r"))) { + PEM_read_bio_X509(bio, &smimecap_cert, NULL, NULL); + BIO_free(bio); + } + if (TEST_ptr(bio = BIO_new_file(privkeyin, "r"))) { + PEM_read_bio_PrivateKey(bio, &smimecap_privkey, NULL, NULL); + BIO_free(bio); + } + } + ADD_TEST(pkcs7_issuer_and_serial_negative_idx_test); #ifndef OPENSSL_NO_EC ADD_TEST(pkcs7_verify_test); ADD_TEST(pkcs7_inner_content_verify_test); #endif /* OPENSSL_NO_EC */ + ADD_TEST(pkcs7_stream_enveloped_no_content_test); + ADD_TEST(pkcs7_stream_enveloped_signed_no_content_test); + if (smimecap_cert != NULL && smimecap_privkey != NULL) + ADD_TEST(test_pkcs7_smimecap); + ADD_TEST(pkcs7_stream_non_data_test); return 1; } + +void cleanup_tests(void) +{ + X509_free(smimecap_cert); + EVP_PKEY_free(smimecap_privkey); +} diff --git a/test/property_test.c b/test/property_test.c index ed868dbe8ca61..58bc92f6c0285 100644 --- a/test/property_test.c +++ b/test/property_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use @@ -157,6 +157,13 @@ static const struct { { "groan=blue", "?groan=yellow", 0 }, { "groan=blue", "groan!=yellow", 1 }, { "groan=blue", "?groan!=yellow", 1 }, + { "sky='BLUE'", "sky='BLUE'", 1 }, + { "sky=BLUE", "sky=blue", 1 }, + { "sky='BLUE'", "sky=BLUE", -1 }, + { "sky=BlUe", "sky=BLUE", 1 }, + { "sky='BlUe'", "sky='BLUE'", -1 }, + { "sky=\"BLUE\"", "sky=\"BLUE\"", 1 }, + { "sky=BLUE", "sky=\"BLUE\"", -1 }, { "today=monday, tomorrow=3", "today!=2", 1 }, { "today=monday, tomorrow=3", "today!='monday'", -1 }, { "today=monday, tomorrow=3", "tomorrow=3", 1 }, @@ -615,7 +622,7 @@ static int test_query_cache_stochastic(void) for (i = 1; i <= max; i++) { v[i] = 2 * i; - BIO_snprintf(buf, sizeof(buf), "n=%d\n", i); + snprintf(buf, sizeof(buf), "n=%d\n", i); if (!TEST_true(ossl_method_store_add(store, &prov, i, buf, "abc", &up_ref, &down_ref)) || !TEST_true(ossl_method_store_cache_set(store, &prov, i, @@ -629,7 +636,7 @@ static int test_query_cache_stochastic(void) } } for (i = 1; i <= max; i++) { - BIO_snprintf(buf, sizeof(buf), "n=%d\n", i); + snprintf(buf, sizeof(buf), "n=%d\n", i); if (!ossl_method_store_cache_get(store, NULL, i, buf, &result) || result != v + i) errors++; diff --git a/test/prov_config_test.c b/test/prov_config_test.c index d271ae45396e0..a1889a29a759b 100644 --- a/test/prov_config_test.c +++ b/test/prov_config_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -10,6 +10,7 @@ #include #include #include +#include "crypto/dso_conf.h" #include "testutil.h" static char *configfile = NULL; @@ -67,7 +68,7 @@ static int test_recursive_config(void) return testresult; } -#define P_TEST_PATH "/../test/p_test.so" +#define P_TEST_PATH "/../test/p_test" DSO_EXTENSION static int test_path_config(void) { OSSL_LIB_CTX *ctx = NULL; diff --git a/test/provider_internal_test.c b/test/provider_internal_test.c index 65411d322e59b..21e44a70c4ccc 100644 --- a/test/provider_internal_test.c +++ b/test/provider_internal_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -41,7 +41,7 @@ static const char *expected_greeting1(const char *name) { static char expected_greeting[256] = ""; - BIO_snprintf(expected_greeting, sizeof(expected_greeting), + snprintf(expected_greeting, sizeof(expected_greeting), "Hello OpenSSL %.20s, greetings from %s!", OPENSSL_VERSION_STR, name); diff --git a/test/provider_pkey_test.c b/test/provider_pkey_test.c index c7397c33e62c1..fc6856ea6f886 100644 --- a/test/provider_pkey_test.c +++ b/test/provider_pkey_test.c @@ -328,13 +328,12 @@ static int test_pkey_store(int idx) if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) goto end; - if (!TEST_ptr(loader = OSSL_STORE_LOADER_fetch(libctx, "fake_rsa", - propq))) + if (!TEST_ptr(loader = OSSL_STORE_LOADER_fetch(libctx, "fake-rsa", propq))) goto end; OSSL_STORE_LOADER_free(loader); - if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake_rsa:test", libctx, propq, + if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake-rsa:test", libctx, propq, NULL, NULL, NULL, NULL, NULL))) goto end; @@ -378,14 +377,13 @@ static int test_pkey_delete(void) if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) goto end; - if (!TEST_ptr(loader = OSSL_STORE_LOADER_fetch(libctx, "fake_rsa", - propq))) + if (!TEST_ptr(loader = OSSL_STORE_LOADER_fetch(libctx, "fake-rsa", propq))) goto end; OSSL_STORE_LOADER_free(loader); /* First iteration: load key, check it, delete it */ - if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake_rsa:test", libctx, propq, + if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake-rsa:test", libctx, propq, NULL, NULL, NULL, NULL, NULL))) goto end; @@ -403,7 +401,7 @@ static int test_pkey_delete(void) EVP_PKEY_free(pkey); pkey = NULL; - if (!TEST_int_eq(OSSL_STORE_delete("fake_rsa:test", libctx, propq, + if (!TEST_int_eq(OSSL_STORE_delete("fake-rsa:test", libctx, propq, NULL, NULL, NULL), 1)) goto end; @@ -411,7 +409,7 @@ static int test_pkey_delete(void) goto end; /* Second iteration: load key should fail */ - if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake_rsa:test", libctx, propq, + if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake-rsa:test", libctx, propq, NULL, NULL, NULL, NULL, NULL))) goto end; @@ -461,8 +459,7 @@ static int test_pkey_store_open_ex(void) if (!TEST_ptr(fake_rsa = fake_rsa_start(libctx))) goto end; - if (!TEST_ptr(loader = OSSL_STORE_LOADER_fetch(libctx, "fake_rsa", - propq))) + if (!TEST_ptr(loader = OSSL_STORE_LOADER_fetch(libctx, "fake-rsa", propq))) goto end; OSSL_STORE_LOADER_free(loader); @@ -473,15 +470,19 @@ static int test_pkey_store_open_ex(void) if (UI_method_set_reader(ui_method, fake_pw_read_string)) goto end; - if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake_rsa:openpwtest", libctx, propq, + if (!TEST_ptr(ctx = OSSL_STORE_open_ex("fake-rsa:openpwtest", libctx, propq, ui_method, NULL, NULL, NULL, NULL))) goto end; /* retry w/o ui_method to ensure we actually enter pw checks and fail */ OSSL_STORE_close(ctx); + if (!TEST_ptr_null(ctx = OSSL_STORE_open_ex("fake-rsa:openpwtest", libctx, + propq, NULL, NULL, NULL, NULL, NULL))) + goto end; + + /* retrying with invalid scheme name syntax (note the '_') will fail */ if (!TEST_ptr_null(ctx = OSSL_STORE_open_ex("fake_rsa:openpwtest", libctx, - propq, NULL, NULL, NULL, NULL, - NULL))) + propq, ui_method, NULL, NULL, NULL, NULL))) goto end; ret = 1; diff --git a/test/provider_status_test.c b/test/provider_status_test.c index 9f3294a44178b..97641538863db 100644 --- a/test/provider_status_test.c +++ b/test/provider_status_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -141,6 +142,44 @@ static int get_provider_params(const OSSL_PROVIDER *prov) return ret; } +struct group_capability_st { + int num_capabilities; + int num_correct_type; +}; + +static int tls_group_capability_cb(const OSSL_PARAM params[], void *arg) +{ + const OSSL_PARAM *p = OSSL_PARAM_locate_const( + params, OSSL_CAPABILITY_TLS_GROUP_IS_KEM); + struct group_capability_st *gcp = (struct group_capability_st *)arg; + + gcp->num_capabilities++; + + if (!TEST_ptr(p) || !TEST_uint_eq(p->data_type, OSSL_PARAM_UNSIGNED_INTEGER)) + return 0; + + gcp->num_correct_type++; + return 1; +} + +static int test_tls_group_capability_type(void) +{ + OSSL_PROVIDER *prov = NULL; + struct group_capability_st gc = { 0, 0 }; + int ret = 0; + + if (!TEST_ptr(prov = OSSL_PROVIDER_load(libctx, provider_name)) + || !TEST_true(OSSL_PROVIDER_get_capabilities( + prov, "TLS-GROUP", tls_group_capability_cb, &gc)) + || !TEST_int_eq(gc.num_capabilities, gc.num_correct_type)) + goto err; + + ret = 1; +err: + OSSL_PROVIDER_unload(prov); + return ret; +} + static int test_provider_status(void) { int ret = 0; @@ -217,6 +256,7 @@ int setup_tests(void) { OPTION_CHOICE o; char *config_file = NULL; + bool is_fips, is_default; while ((o = opt_next()) != OPT_EOF) { switch (o) { @@ -234,11 +274,17 @@ int setup_tests(void) } } - libctx = OSSL_LIB_CTX_new(); - if (libctx == NULL) + if (!TEST_ptr(libctx = OSSL_LIB_CTX_new())) + return 0; + if (!TEST_ptr(provider_name)) return 0; - if (strcmp(provider_name, "fips") == 0) { + is_fips = strcmp(provider_name, "fips") == 0; + is_default = strcmp(provider_name, "default") == 0; + + if (is_fips) { + if (!TEST_ptr(config_file)) + return 0; self_test_args.count = 0; OSSL_SELF_TEST_set_callback(libctx, self_test_on_load, &self_test_args); if (!OSSL_LIB_CTX_load_config(libctx, config_file)) { @@ -249,6 +295,10 @@ int setup_tests(void) } else { ADD_TEST(test_provider_gettable_params); } + + if (is_default || (is_fips && fips_provider_version_ge(libctx, 4, 1, 0))) + ADD_TEST(test_tls_group_capability_type); + return 1; } diff --git a/test/provider_test.c b/test/provider_test.c index 475f9ba08c7f0..1372a797609d9 100644 --- a/test/provider_test.c +++ b/test/provider_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -45,7 +45,7 @@ static int test_provider(OSSL_LIB_CTX **libctx, const char *name, int dolegacycheck = (legacy != NULL); OSSL_PROVIDER *deflt = NULL, *base = NULL; - BIO_snprintf(expected_greeting, sizeof(expected_greeting), + snprintf(expected_greeting, sizeof(expected_greeting), "Hello OpenSSL %.20s, greetings from %s!", OPENSSL_VERSION_STR, name); diff --git a/test/punycode_test.c b/test/punycode_test.c index 3591f0dc19a09..7911b9d6d8578 100644 --- a/test/punycode_test.c +++ b/test/punycode_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/quic-openssl-docker/hq-interop/quic-hq-interop.c b/test/quic-openssl-docker/hq-interop/quic-hq-interop.c index 7f7347a0df527..27ad63efa045e 100644 --- a/test/quic-openssl-docker/hq-interop/quic-hq-interop.c +++ b/test/quic-openssl-docker/hq-interop/quic-hq-interop.c @@ -589,11 +589,11 @@ static size_t build_request_set(SSL *ssl) outnames[poll_idx] = req; /* Format the http request */ - BIO_snprintf(req_string, REQ_STRING_SZ, "GET /%s\r\n", req); + snprintf(req_string, REQ_STRING_SZ, "GET /%s\r\n", req); /* build the outfile request path */ memset(outfilename, 0, REQ_STRING_SZ); - BIO_snprintf(outfilename, REQ_STRING_SZ, "/downloads/%s", req); + snprintf(outfilename, REQ_STRING_SZ, "/downloads/%s", req); /* open a bio to write the file */ outbiolist[poll_idx] = BIO_new_file(outfilename, "w+"); diff --git a/test/quic_ackm_test.c b/test/quic_ackm_test.c index 8598bf8398610..79fa51b99f513 100644 --- a/test/quic_ackm_test.c +++ b/test/quic_ackm_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/quic_cc_test.c b/test/quic_cc_test.c index b4ce5caa1b15b..4082cac2438af 100644 --- a/test/quic_cc_test.c +++ b/test/quic_cc_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -102,7 +102,7 @@ struct net_sim { uint64_t latency; /* ms */ uint64_t spare_capacity; - PRIORITY_QUEUE_OF(NET_PKT) * pkts; + PRIORITY_QUEUE_OF(NET_PKT) *pkts; uint64_t total_acked, total_lost; /* bytes */ }; diff --git a/test/quic_cfq_test.c b/test/quic_cfq_test.c index b17e298962ee7..746aa5fd9494c 100644 --- a/test/quic_cfq_test.c +++ b/test/quic_cfq_test.c @@ -167,6 +167,8 @@ static int test_cfq(void) testresult = 1; err: ossl_quic_cfq_free(cfq); + if (testresult && (!TEST_ptr(g_free) || !TEST_size_t_ne(g_free_len, 0))) + testresult = 0; return testresult; } diff --git a/test/quic_client_test.c b/test/quic_client_test.c index 90e8498148831..03f02e644e801 100644 --- a/test/quic_client_test.c +++ b/test/quic_client_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/quic_fc_test.c b/test/quic_fc_test.c index 1a36e1421e8e8..6849618e586be 100644 --- a/test/quic_fc_test.c +++ b/test/quic_fc_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/quic_multistream_test.c b/test/quic_multistream_test.c index b9b263fe94d3f..29927336a6dc3 100644 --- a/test/quic_multistream_test.c +++ b/test/quic_multistream_test.c @@ -356,72 +356,12 @@ static OSSL_TIME get_time(void *arg) return t; } -static int skip_time_ms(struct helper *h, struct helper_local *hl) -{ - if (!TEST_true(CRYPTO_THREAD_write_lock(h->time_lock))) - return 0; - - h->time_slip = ossl_time_add(h->time_slip, ossl_ms2time(hl->check_op->arg2)); - - CRYPTO_THREAD_unlock(h->time_lock); - return 1; -} - static QUIC_TSERVER *s_lock(struct helper *h, struct helper_local *hl); static void s_unlock(struct helper *h, struct helper_local *hl); #define ACQUIRE_S() s_lock(h, hl) #define ACQUIRE_S_NOHL() s_lock(h, NULL) -static int override_key_update(struct helper *h, struct helper_local *hl) -{ - QUIC_CHANNEL *ch = ossl_quic_conn_get_channel(h->c_conn); - - ossl_quic_channel_set_txku_threshold_override(ch, hl->check_op->arg2); - return 1; -} - -static int trigger_key_update(struct helper *h, struct helper_local *hl) -{ - if (!TEST_true(SSL_key_update(h->c_conn, SSL_KEY_UPDATE_REQUESTED))) - return 0; - - return 1; -} - -static int check_key_update_ge(struct helper *h, struct helper_local *hl) -{ - QUIC_CHANNEL *ch = ossl_quic_conn_get_channel(h->c_conn); - int64_t txke = (int64_t)ossl_quic_channel_get_tx_key_epoch(ch); - int64_t rxke = (int64_t)ossl_quic_channel_get_rx_key_epoch(ch); - int64_t diff = txke - rxke; - - /* - * TXKE must always be equal to or ahead of RXKE. - * It can be ahead of RXKE by at most 1. - */ - if (!TEST_int64_t_ge(diff, 0) || !TEST_int64_t_le(diff, 1)) - return 0; - - /* Caller specifies a minimum number of RXKEs which must have happened. */ - if (!TEST_uint64_t_ge((uint64_t)rxke, hl->check_op->arg2)) - return 0; - - return 1; -} - -static int check_key_update_lt(struct helper *h, struct helper_local *hl) -{ - QUIC_CHANNEL *ch = ossl_quic_conn_get_channel(h->c_conn); - uint64_t txke = ossl_quic_channel_get_tx_key_epoch(ch); - - /* Caller specifies a maximum number of TXKEs which must have happened. */ - if (!TEST_uint64_t_lt(txke, hl->check_op->arg2)) - return 0; - - return 1; -} - static unsigned long stream_info_hash(const STREAM_INFO *info) { return OPENSSL_LH_strhash(info->name); @@ -762,7 +702,7 @@ static int helper_init(struct helper *h, const char *script_name, goto err; /* Set title for qlog purposes. */ - BIO_snprintf(title, sizeof(title), "quic_multistream_test: %s", script_name); + snprintf(title, sizeof(title), "quic_multistream_test: %s", script_name); if (!TEST_true(ossl_quic_set_diag_title(h->c_ctx, title))) goto err; @@ -1424,7 +1364,7 @@ static int run_script_worker(struct helper *h, const struct script_op *script, goto out; if (allow_fail && c_stream == NULL) { - if (!TEST_size_t_eq(ERR_GET_REASON(ERR_get_error()), + if (!TEST_size_t_eq(ERR_GET_REASON(ERR_peek_last_error()), SSL_R_STREAM_COUNT_LIMITED)) goto out; @@ -2086,362 +2026,50 @@ static const struct script_op script_12[] = { }; /* 13. Many threads accepted on the same client connection (stress test) */ -static const struct script_op script_13_child[] = { - OP_BEGIN_REPEAT(10), - - OP_C_ACCEPT_STREAM_WAIT(a), - OP_C_READ_EXPECT(a, "foo", 3), - OP_C_EXPECT_FIN(a), - OP_C_FREE_STREAM(a), - - OP_END_REPEAT(), - - OP_END -}; - static const struct script_op script_13[] = { - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_NEW_THREAD(5, script_13_child), - - OP_BEGIN_REPEAT(50), - - OP_S_NEW_STREAM_BIDI(a, ANY_ID), - OP_S_WRITE(a, "foo", 3), - OP_S_CONCLUDE(a), - OP_S_UNBIND_STREAM_ID(a), - - OP_END_REPEAT(), - + /* test moved to test/radix/quic_tests.c */ OP_END }; /* 14. Many threads initiating on the same client connection (stress test) */ -static const struct script_op script_14_child[] = { - OP_BEGIN_REPEAT(10), - - OP_C_NEW_STREAM_BIDI(a, ANY_ID), - OP_C_WRITE(a, "foo", 3), - OP_C_CONCLUDE(a), - OP_C_FREE_STREAM(a), - - OP_END_REPEAT(), - - OP_END -}; - static const struct script_op script_14[] = { - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_NEW_THREAD(5, script_14_child), - - OP_BEGIN_REPEAT(50), - - OP_S_ACCEPT_STREAM_WAIT(a), - OP_S_READ_EXPECT(a, "foo", 3), - OP_S_EXPECT_FIN(a), - OP_S_UNBIND_STREAM_ID(a), - - OP_END_REPEAT(), - + /* test moved to test/radix/quic_tests.c */ OP_END }; /* 15. Client sending large number of streams, MAX_STREAMS test */ static const struct script_op script_15[] = { - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - /* - * This will cause a protocol violation to be raised by the server if we are - * not handling the stream limit correctly on the TX side. - */ - OP_BEGIN_REPEAT(200), - - OP_C_NEW_STREAM_BIDI_EX(a, ANY_ID, SSL_STREAM_FLAG_ADVANCE), - OP_C_WRITE(a, "foo", 3), - OP_C_CONCLUDE(a), - OP_C_FREE_STREAM(a), - - OP_END_REPEAT(), - - /* Prove the connection is still good. */ - OP_S_NEW_STREAM_BIDI(a, S_BIDI_ID(0)), - OP_S_WRITE(a, "bar", 3), - OP_S_CONCLUDE(a), - - OP_C_ACCEPT_STREAM_WAIT(a), - OP_C_READ_EXPECT(a, "bar", 3), - OP_C_EXPECT_FIN(a), - - /* - * Drain the queue of incoming streams. We should be able to get all 200 - * even though only 100 can be initiated at a time. - */ - OP_BEGIN_REPEAT(200), - - OP_S_ACCEPT_STREAM_WAIT(b), - OP_S_READ_EXPECT(b, "foo", 3), - OP_S_EXPECT_FIN(b), - OP_S_UNBIND_STREAM_ID(b), - - OP_END_REPEAT(), - + /* test moved to test/radix/quic_tests.c */ OP_END }; /* 16. Server sending large number of streams, MAX_STREAMS test */ static const struct script_op script_16[] = { - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - /* - * This will cause a protocol violation to be raised by the client if we are - * not handling the stream limit correctly on the TX side. - */ - OP_BEGIN_REPEAT(200), - - OP_S_NEW_STREAM_BIDI(a, ANY_ID), - OP_S_WRITE(a, "foo", 3), - OP_S_CONCLUDE(a), - OP_S_UNBIND_STREAM_ID(a), - - OP_END_REPEAT(), - - /* Prove that the connection is still good. */ - OP_C_NEW_STREAM_BIDI(a, ANY_ID), - OP_C_WRITE(a, "bar", 3), - OP_C_CONCLUDE(a), - - OP_S_ACCEPT_STREAM_WAIT(b), - OP_S_READ_EXPECT(b, "bar", 3), - OP_S_EXPECT_FIN(b), - - /* Drain the queue of incoming streams. */ - OP_BEGIN_REPEAT(200), - - OP_C_ACCEPT_STREAM_WAIT(b), - OP_C_READ_EXPECT(b, "foo", 3), - OP_C_EXPECT_FIN(b), - OP_C_FREE_STREAM(b), - - OP_END_REPEAT(), - + /* test moved to test/radix/quic_tests.c */ OP_END }; /* 17. Key update test - unlimited */ static const struct script_op script_17[] = { - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_CHECK(override_key_update, 1), - - OP_BEGIN_REPEAT(200), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_READ_EXPECT(a, "apple", 5), - - /* - * TXKU frequency is bounded by RTT because a previous TXKU needs to be - * acknowledged by the peer first before another one can be begin. By - * waiting this long, we eliminate any such concern and ensure as many key - * updates as possible can occur for the purposes of this test. - */ - OP_CHECK(skip_time_ms, 100), - - OP_END_REPEAT(), - - /* At least 5 RXKUs detected */ - OP_CHECK(check_key_update_ge, 5), - - /* - * Prove the connection is still healthy by sending something in both - * directions. - */ - OP_C_WRITE(DEFAULT, "xyzzy", 5), - OP_S_READ_EXPECT(a, "xyzzy", 5), - - OP_S_WRITE(a, "plugh", 5), - OP_C_READ_EXPECT(DEFAULT, "plugh", 5), - + /* test moved to test/radix/quic_tests.c */ OP_END }; /* 18. Key update test - RTT-bounded */ static const struct script_op script_18[] = { - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_CHECK(override_key_update, 1), - - OP_BEGIN_REPEAT(200), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_READ_EXPECT(a, "apple", 5), - OP_CHECK(skip_time_ms, 8), - - OP_END_REPEAT(), - - /* - * This time we simulate far less time passing between writes, so there are - * fewer opportunities to initiate TXKUs. Note that we ask for a TXKU every - * 1 packet above, which is absurd; thus this ensures we only actually - * generate TXKUs when we are allowed to. - */ - OP_CHECK(check_key_update_lt, 240), - - /* - * Prove the connection is still healthy by sending something in both - * directions. - */ - OP_C_WRITE(DEFAULT, "xyzzy", 5), - OP_S_READ_EXPECT(a, "xyzzy", 5), - - OP_S_WRITE(a, "plugh", 5), - OP_C_READ_EXPECT(DEFAULT, "plugh", 5), - + /* test moved to test/radix/quic_tests.c */ OP_END }; /* 19. Key update test - artificially triggered */ static const struct script_op script_19[] = { - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_C_WRITE(DEFAULT, "orange", 6), - OP_S_READ_EXPECT(a, "orange", 6), - - OP_S_WRITE(a, "strawberry", 10), - OP_C_READ_EXPECT(DEFAULT, "strawberry", 10), - - OP_CHECK(check_key_update_lt, 1), - OP_CHECK(trigger_key_update, 0), - - OP_C_WRITE(DEFAULT, "orange", 6), - OP_S_READ_EXPECT(a, "orange", 6), - OP_S_WRITE(a, "ok", 2), - - OP_C_READ_EXPECT(DEFAULT, "ok", 2), - OP_CHECK(check_key_update_ge, 1), - + /* test moved to test/radix/quic_tests.c */ OP_END }; /* 20. Multiple threads accept stream with socket forcibly closed (error test) */ -static int script_20_trigger(struct helper *h, volatile uint64_t *counter) -{ -#if defined(OPENSSL_THREADS) - ossl_crypto_mutex_lock(h->misc_m); - ++*counter; - ossl_crypto_condvar_broadcast(h->misc_cv); - ossl_crypto_mutex_unlock(h->misc_m); -#endif - return 1; -} - -static int script_20_wait(struct helper *h, volatile uint64_t *counter, uint64_t threshold) -{ -#if defined(OPENSSL_THREADS) - int stop = 0; - - ossl_crypto_mutex_lock(h->misc_m); - while (!stop) { - stop = (*counter >= threshold); - if (stop) - break; - - ossl_crypto_condvar_wait(h->misc_cv, h->misc_m); - } - - ossl_crypto_mutex_unlock(h->misc_m); -#endif - return 1; -} - -static int script_20_trigger1(struct helper *h, struct helper_local *hl) -{ - return script_20_trigger(h, &h->scratch0); -} - -static int script_20_wait1(struct helper *h, struct helper_local *hl) -{ - return script_20_wait(h, &h->scratch0, hl->check_op->arg2); -} - -static int script_20_trigger2(struct helper *h, struct helper_local *hl) -{ - return script_20_trigger(h, &h->scratch1); -} - -static int script_20_wait2(struct helper *h, struct helper_local *hl) -{ - return script_20_wait(h, &h->scratch1, hl->check_op->arg2); -} - -static const struct script_op script_20_child[] = { - OP_C_ACCEPT_STREAM_WAIT(a), - OP_C_READ_EXPECT(a, "foo", 3), - - OP_CHECK(script_20_trigger1, 0), - OP_CHECK(script_20_wait2, 1), - - OP_C_READ_FAIL_WAIT(a), - OP_C_EXPECT_SSL_ERR(a, SSL_ERROR_SYSCALL), - - OP_EXPECT_ERR_LIB(ERR_LIB_SSL), - OP_EXPECT_ERR_REASON(SSL_R_PROTOCOL_IS_SHUTDOWN), - - OP_POP_ERR(), - OP_EXPECT_ERR_LIB(ERR_LIB_SSL), - OP_EXPECT_ERR_REASON(SSL_R_QUIC_NETWORK_ERROR), - - OP_C_FREE_STREAM(a), - - OP_END -}; - static const struct script_op script_20[] = { - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_NEW_THREAD(5, script_20_child), - - OP_BEGIN_REPEAT(5), - - OP_S_NEW_STREAM_BIDI(a, ANY_ID), - OP_S_WRITE(a, "foo", 3), - OP_S_UNBIND_STREAM_ID(a), - - OP_END_REPEAT(), - - OP_CHECK(script_20_wait1, 5), - - OP_C_CLOSE_SOCKET(), - OP_CHECK(script_20_trigger2, 0), - + /* test moved to test/radix/quic_tests.c */ OP_END }; @@ -2568,1610 +2196,48 @@ static int script_21_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, } static const struct script_op script_21[] = { - OP_S_SET_INJECT_PLAIN(script_21_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(QUIC_PKT_TYPE_1RTT, OSSL_QUIC_VLINT_MAX), - - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0), - - OP_END -}; + /* test moved to test/radix/quic_tests.c */ + OP_END +}; /* 22. Fault injection - non-zero packet header reserved bits */ -static int script_22_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, - unsigned char *buf, size_t len) -{ - if (h->inject_word0 == 0) - return 1; - - hdr->reserved = 1; - return 1; -} - static const struct script_op script_22[] = { - OP_S_SET_INJECT_PLAIN(script_22_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(1, 0), - - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_PROTOCOL_VIOLATION, 0, 0), - + /* test moved to test/radix/quic_tests.c */ OP_END }; /* 23. Fault injection - empty NEW_TOKEN */ -static int script_23_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, - unsigned char *buf, size_t len) -{ - int ok = 0; - WPACKET wpkt; - unsigned char frame_buf[16]; - size_t written; - - if (h->inject_word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) - return 1; - - if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, - sizeof(frame_buf), 0))) - return 0; - - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, OSSL_QUIC_FRAME_TYPE_NEW_TOKEN)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, 0))) - goto err; - - if (!TEST_true(WPACKET_get_total_written(&wpkt, &written))) - goto err; - - if (!qtest_fault_prepend_frame(h->qtf, frame_buf, written)) - goto err; - - ok = 1; -err: - if (ok) - WPACKET_finish(&wpkt); - else - WPACKET_cleanup(&wpkt); - return ok; -} - static const struct script_op script_23[] = { - OP_S_SET_INJECT_PLAIN(script_23_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(1, 0), - - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0), - + /* test moved to test/radix/quic_tests.c */ OP_END }; /* 24. Fault injection - excess value of MAX_STREAMS_BIDI */ -static int script_24_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, - unsigned char *buf, size_t len) -{ - int ok = 0; - WPACKET wpkt; - unsigned char frame_buf[16]; - size_t written; - - if (h->inject_word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) - return 1; - - if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, - sizeof(frame_buf), 0))) - return 0; - - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, h->inject_word1)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, (((uint64_t)1) << 60) + 1))) - goto err; - - if (!TEST_true(WPACKET_get_total_written(&wpkt, &written))) - goto err; - - if (!qtest_fault_prepend_frame(h->qtf, frame_buf, written)) - goto err; - - ok = 1; -err: - if (ok) - WPACKET_finish(&wpkt); - else - WPACKET_cleanup(&wpkt); - return ok; -} - -static const struct script_op script_24[] = { - OP_S_SET_INJECT_PLAIN(script_24_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI), - - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0), - - OP_END -}; - -/* 25. Fault injection - excess value of MAX_STREAMS_UNI */ -static const struct script_op script_25[] = { - OP_S_SET_INJECT_PLAIN(script_24_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI), - - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0), - - OP_END -}; - -/* 26. Fault injection - excess value of STREAMS_BLOCKED_BIDI */ -static const struct script_op script_26[] = { - OP_S_SET_INJECT_PLAIN(script_24_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI), - - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_STREAM_LIMIT_ERROR, 0, 0), - - OP_END -}; - -/* 27. Fault injection - excess value of STREAMS_BLOCKED_UNI */ -static const struct script_op script_27[] = { - OP_S_SET_INJECT_PLAIN(script_24_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI), - - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_STREAM_LIMIT_ERROR, 0, 0), - - OP_END -}; - -/* 28. Fault injection - received RESET_STREAM for send-only stream */ -static int script_28_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, - unsigned char *buf, size_t len) -{ - int ok = 0; - WPACKET wpkt; - unsigned char frame_buf[32]; - size_t written; - - if (h->inject_word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) - return 1; - - if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, - sizeof(frame_buf), 0))) - return 0; - - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, h->inject_word1)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, /* stream ID */ - h->inject_word0 - 1)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, 123)) - || (h->inject_word1 == OSSL_QUIC_FRAME_TYPE_RESET_STREAM - && !TEST_true(WPACKET_quic_write_vlint(&wpkt, 5)))) /* final size */ - goto err; - - if (!TEST_true(WPACKET_get_total_written(&wpkt, &written))) - goto err; - - if (!qtest_fault_prepend_frame(h->qtf, frame_buf, written)) - goto err; - - ok = 1; -err: - if (ok) - WPACKET_finish(&wpkt); - else - WPACKET_cleanup(&wpkt); - return ok; -} - -static const struct script_op script_28[] = { - OP_S_SET_INJECT_PLAIN(script_28_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_C_NEW_STREAM_BIDI(a, C_BIDI_ID(0)), - OP_C_WRITE(a, "orange", 6), - - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "orange", 6), - - OP_C_NEW_STREAM_UNI(b, C_UNI_ID(0)), - OP_C_WRITE(b, "apple", 5), - - OP_S_BIND_STREAM_ID(b, C_UNI_ID(0)), - OP_S_READ_EXPECT(b, "apple", 5), - - OP_SET_INJECT_WORD(C_UNI_ID(0) + 1, OSSL_QUIC_FRAME_TYPE_RESET_STREAM), - OP_S_WRITE(a, "fruit", 5), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0), - - OP_END -}; - -/* 29. Fault injection - received RESET_STREAM for nonexistent send-only stream */ -static const struct script_op script_29[] = { - OP_S_SET_INJECT_PLAIN(script_28_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_C_NEW_STREAM_BIDI(a, C_BIDI_ID(0)), - OP_C_WRITE(a, "orange", 6), - - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "orange", 6), - - OP_C_NEW_STREAM_UNI(b, C_UNI_ID(0)), - OP_C_WRITE(b, "apple", 5), - - OP_S_BIND_STREAM_ID(b, C_UNI_ID(0)), - OP_S_READ_EXPECT(b, "apple", 5), - - OP_SET_INJECT_WORD(C_UNI_ID(1) + 1, OSSL_QUIC_FRAME_TYPE_RESET_STREAM), - OP_S_WRITE(a, "fruit", 5), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0), - - OP_END -}; - -/* 30. Fault injection - received STOP_SENDING for receive-only stream */ -static const struct script_op script_30[] = { - OP_S_SET_INJECT_PLAIN(script_28_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_S_NEW_STREAM_UNI(a, S_UNI_ID(0)), - OP_S_WRITE(a, "apple", 5), - - OP_C_ACCEPT_STREAM_WAIT(a), - OP_C_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(S_UNI_ID(0) + 1, OSSL_QUIC_FRAME_TYPE_STOP_SENDING), - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0), - - OP_END -}; - -/* 31. Fault injection - received STOP_SENDING for nonexistent receive-only stream */ -static const struct script_op script_31[] = { - OP_S_SET_INJECT_PLAIN(script_28_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_S_NEW_STREAM_UNI(a, S_UNI_ID(0)), - OP_S_WRITE(a, "apple", 5), - - OP_C_ACCEPT_STREAM_WAIT(a), - OP_C_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(C_UNI_ID(0) + 1, OSSL_QUIC_FRAME_TYPE_STOP_SENDING), - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0), - - OP_END -}; - -/* 32. Fault injection - STREAM frame for nonexistent stream */ -static int script_32_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, - unsigned char *buf, size_t len) -{ - int ok = 0; - WPACKET wpkt; - unsigned char frame_buf[64]; - size_t written; - uint64_t type = OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN, offset, flen, i; - - if (hdr->type != QUIC_PKT_TYPE_1RTT) - return 1; - - switch (h->inject_word1) { - default: - return 0; - case 0: - return 1; - case 1: - offset = 0; - flen = 0; - break; - case 2: - offset = (((uint64_t)1) << 62) - 1; - flen = 5; - break; - case 3: - offset = 1 * 1024 * 1024 * 1024; /* 1G */ - flen = 5; - break; - case 4: - offset = 0; - flen = 1; - break; - } - - if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, - sizeof(frame_buf), 0))) - return 0; - - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, type)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, /* stream ID */ - h->inject_word0 - 1)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, offset)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, flen))) - goto err; - - for (i = 0; i < flen; ++i) - if (!TEST_true(WPACKET_put_bytes_u8(&wpkt, 0x42))) - goto err; - - if (!TEST_true(WPACKET_get_total_written(&wpkt, &written))) - goto err; - - if (!qtest_fault_prepend_frame(h->qtf, frame_buf, written)) - goto err; - - ok = 1; -err: - if (ok) - WPACKET_finish(&wpkt); - else - WPACKET_cleanup(&wpkt); - return ok; -} - -static const struct script_op script_32[] = { - OP_S_SET_INJECT_PLAIN(script_32_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_S_NEW_STREAM_UNI(a, S_UNI_ID(0)), - OP_S_WRITE(a, "apple", 5), - - OP_C_ACCEPT_STREAM_WAIT(a), - OP_C_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(C_UNI_ID(0) + 1, 1), - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0), - - OP_END -}; - -/* 33. Fault injection - STREAM frame with illegal offset */ -static const struct script_op script_33[] = { - OP_S_SET_INJECT_PLAIN(script_32_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_C_NEW_STREAM_BIDI(a, C_BIDI_ID(0)), - OP_C_WRITE(a, "apple", 5), - - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(C_BIDI_ID(0) + 1, 2), - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0), - - OP_END -}; - -/* 34. Fault injection - STREAM frame which exceeds FC */ -static const struct script_op script_34[] = { - OP_S_SET_INJECT_PLAIN(script_32_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_C_NEW_STREAM_BIDI(a, C_BIDI_ID(0)), - OP_C_WRITE(a, "apple", 5), - - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(C_BIDI_ID(0) + 1, 3), - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_FLOW_CONTROL_ERROR, 0, 0), - - OP_END -}; - -/* 35. Fault injection - MAX_STREAM_DATA for receive-only stream */ -static const struct script_op script_35[] = { - OP_S_SET_INJECT_PLAIN(script_28_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_S_NEW_STREAM_UNI(a, S_UNI_ID(0)), - OP_S_WRITE(a, "apple", 5), - - OP_C_ACCEPT_STREAM_WAIT(a), - OP_C_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(S_UNI_ID(0) + 1, OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA), - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0), - - OP_END -}; - -/* 36. Fault injection - MAX_STREAM_DATA for nonexistent stream */ -static const struct script_op script_36[] = { - OP_S_SET_INJECT_PLAIN(script_28_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_S_NEW_STREAM_UNI(a, S_UNI_ID(0)), - OP_S_WRITE(a, "apple", 5), - - OP_C_ACCEPT_STREAM_WAIT(a), - OP_C_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(C_BIDI_ID(0) + 1, OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA), - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0), - - OP_END -}; - -/* 37. Fault injection - STREAM_DATA_BLOCKED for send-only stream */ -static const struct script_op script_37[] = { - OP_S_SET_INJECT_PLAIN(script_28_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_C_NEW_STREAM_UNI(a, C_UNI_ID(0)), - OP_C_WRITE(a, "apple", 5), - - OP_S_BIND_STREAM_ID(a, C_UNI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_S_NEW_STREAM_UNI(b, S_UNI_ID(0)), - OP_SET_INJECT_WORD(C_UNI_ID(0) + 1, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED), - OP_S_WRITE(b, "orange", 5), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0), - - OP_END -}; - -/* 38. Fault injection - STREAM_DATA_BLOCKED for non-existent stream */ -static const struct script_op script_38[] = { - OP_S_SET_INJECT_PLAIN(script_28_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_C_NEW_STREAM_UNI(a, C_UNI_ID(0)), - OP_C_WRITE(a, "apple", 5), - - OP_S_BIND_STREAM_ID(a, C_UNI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(C_BIDI_ID(0) + 1, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED), - - OP_S_NEW_STREAM_UNI(b, S_UNI_ID(0)), - OP_S_WRITE(b, "orange", 5), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0), - - OP_END -}; - -/* 39. Fault injection - NEW_CONN_ID with zero-len CID */ -static int script_39_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, - unsigned char *buf, size_t len) -{ - int ok = 0; - WPACKET wpkt; - unsigned char frame_buf[64]; - size_t i, written; - uint64_t seq_no = 0, retire_prior_to = 0; - QUIC_CONN_ID new_cid = { 0 }; - QUIC_CHANNEL *ch = ossl_quic_tserver_get_channel(h->s_priv); - - if (hdr->type != QUIC_PKT_TYPE_1RTT) - return 1; - - switch (h->inject_word1) { - case 0: - return 1; - case 1: - new_cid.id_len = 0; - break; - case 2: - new_cid.id_len = 21; - break; - case 3: - new_cid.id_len = 1; - new_cid.id[0] = 0x55; - - seq_no = 0; - retire_prior_to = 1; - break; - case 4: - /* Use our actual CID so we don't break connectivity. */ - ossl_quic_channel_get_diag_local_cid(ch, &new_cid); - - seq_no = 2; - retire_prior_to = 2; - break; - case 5: - /* - * Use a bogus CID which will need to be ignored if connectivity is to - * be continued. - */ - new_cid.id_len = 8; - new_cid.id[0] = 0x55; - - seq_no = 1; - retire_prior_to = 1; - break; - } - - if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, - sizeof(frame_buf), 0))) - return 0; - - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, seq_no)) /* seq no */ - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, retire_prior_to)) /* retire prior to */ - || !TEST_true(WPACKET_put_bytes_u8(&wpkt, new_cid.id_len))) /* len */ - goto err; - - for (i = 0; i < new_cid.id_len && i < OSSL_NELEM(new_cid.id); ++i) - if (!TEST_true(WPACKET_put_bytes_u8(&wpkt, new_cid.id[i]))) - goto err; - - for (; i < new_cid.id_len; ++i) - if (!TEST_true(WPACKET_put_bytes_u8(&wpkt, 0x55))) - goto err; - - for (i = 0; i < QUIC_STATELESS_RESET_TOKEN_LEN; ++i) - if (!TEST_true(WPACKET_put_bytes_u8(&wpkt, 0x42))) - goto err; - - if (!TEST_true(WPACKET_get_total_written(&wpkt, &written))) - goto err; - - if (!qtest_fault_prepend_frame(h->qtf, frame_buf, written)) - goto err; - - ok = 1; -err: - if (ok) - WPACKET_finish(&wpkt); - else - WPACKET_cleanup(&wpkt); - return ok; -} - -static const struct script_op script_39[] = { - OP_S_SET_INJECT_PLAIN(script_39_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_C_NEW_STREAM_BIDI(a, C_BIDI_ID(0)), - OP_C_WRITE(a, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(0, 1), - OP_S_WRITE(a, "orange", 5), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0), - - OP_END -}; - -/* 40. Shutdown flush test */ -static const unsigned char script_40_data[1024] = "strawberry"; - -static const struct script_op script_40[] = { - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_C_NEW_STREAM_BIDI(a, C_BIDI_ID(0)), - OP_C_WRITE(a, "apple", 5), - - OP_C_INHIBIT_TICK(1), - OP_C_SET_WRITE_BUF_SIZE(a, 1024 * 100 * 3), - - OP_BEGIN_REPEAT(100), - - OP_C_WRITE(a, script_40_data, sizeof(script_40_data)), - - OP_END_REPEAT(), - - OP_C_CONCLUDE(a), - OP_C_SHUTDOWN_WAIT(NULL, 0), /* disengages tick inhibition */ - - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_BEGIN_REPEAT(100), - - OP_S_READ_EXPECT(a, script_40_data, sizeof(script_40_data)), - - OP_END_REPEAT(), - - OP_S_EXPECT_FIN(a), - - OP_C_EXPECT_CONN_CLOSE_INFO(0, 1, 0), - OP_S_EXPECT_CONN_CLOSE_INFO(0, 1, 1), - - OP_END -}; - -/* 41. Fault injection - PATH_CHALLENGE yields PATH_RESPONSE */ -static const uint64_t path_challenge = UINT64_C(0xbdeb9451169c83aa); - -static int script_41_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, - unsigned char *buf, size_t len) -{ - int ok = 0; - WPACKET wpkt; - unsigned char frame_buf[16]; - size_t written; - - if (h->inject_word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) - return 1; - - if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, - sizeof(frame_buf), 0))) - return 0; - - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, h->inject_word1)) - || !TEST_true(WPACKET_put_bytes_u64(&wpkt, path_challenge))) - goto err; - - if (!TEST_true(WPACKET_get_total_written(&wpkt, &written)) - || !TEST_size_t_eq(written, 9)) - goto err; - - if (!qtest_fault_prepend_frame(h->qtf, frame_buf, written)) - goto err; - - --h->inject_word0; - ok = 1; -err: - if (ok) - WPACKET_finish(&wpkt); - else - WPACKET_cleanup(&wpkt); - return ok; -} - -static void script_41_trace(int write_p, int version, int content_type, - const void *buf, size_t len, SSL *ssl, void *arg) -{ - uint64_t frame_type, frame_data; - int was_minimal; - struct helper *h = arg; - PACKET pkt; - - if (version != OSSL_QUIC1_VERSION - || content_type != SSL3_RT_QUIC_FRAME_FULL - || len < 1) - return; - - if (!TEST_true(PACKET_buf_init(&pkt, buf, len))) { - ++h->scratch1; - return; - } - - if (!TEST_true(ossl_quic_wire_peek_frame_header(&pkt, &frame_type, - &was_minimal))) { - ++h->scratch1; - return; - } - - if (frame_type != OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE) - return; - - if (!TEST_true(ossl_quic_wire_decode_frame_path_response(&pkt, &frame_data)) - || !TEST_uint64_t_eq(frame_data, path_challenge)) { - ++h->scratch1; - return; - } - - ++h->scratch0; -} - -static int script_41_setup(struct helper *h, struct helper_local *hl) -{ - ossl_quic_tserver_set_msg_callback(ACQUIRE_S(), script_41_trace, h); - return 1; -} - -static int script_41_check(struct helper *h, struct helper_local *hl) -{ - /* At least one valid challenge/response echo? */ - if (!TEST_uint64_t_gt(h->scratch0, 0)) - return 0; - - /* No failed tests? */ - if (!TEST_uint64_t_eq(h->scratch1, 0)) - return 0; - - return 1; -} - -static const struct script_op script_41[] = { - OP_S_SET_INJECT_PLAIN(script_41_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_CHECK(script_41_setup, 0), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE), - - OP_S_WRITE(a, "orange", 6), - OP_C_READ_EXPECT(DEFAULT, "orange", 6), - - OP_C_WRITE(DEFAULT, "strawberry", 10), - OP_S_READ_EXPECT(a, "strawberry", 10), - - OP_CHECK(script_41_check, 0), - OP_END -}; - -/* 42. Fault injection - CRYPTO frame with illegal offset */ -static int script_42_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, - unsigned char *buf, size_t len) -{ - int ok = 0; - unsigned char frame_buf[64]; - size_t written; - WPACKET wpkt; - - if (h->inject_word0 == 0) - return 1; - - --h->inject_word0; - - if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, - sizeof(frame_buf), 0))) - return 0; - - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, OSSL_QUIC_FRAME_TYPE_CRYPTO)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, h->inject_word1)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, 1)) - || !TEST_true(WPACKET_put_bytes_u8(&wpkt, 0x42))) - goto err; - - if (!TEST_true(WPACKET_get_total_written(&wpkt, &written))) - goto err; - - if (!qtest_fault_prepend_frame(h->qtf, frame_buf, written)) - goto err; - - ok = 1; -err: - if (ok) - WPACKET_finish(&wpkt); - else - WPACKET_cleanup(&wpkt); - return ok; -} - -static const struct script_op script_42[] = { - OP_S_SET_INJECT_PLAIN(script_42_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_C_NEW_STREAM_BIDI(a, C_BIDI_ID(0)), - OP_C_WRITE(a, "apple", 5), - - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(1, (((uint64_t)1) << 62) - 1), - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0), - - OP_END -}; - -/* 43. Fault injection - CRYPTO frame exceeding FC */ -static const struct script_op script_43[] = { - OP_S_SET_INJECT_PLAIN(script_42_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_C_NEW_STREAM_BIDI(a, C_BIDI_ID(0)), - OP_C_WRITE(a, "apple", 5), - - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(1, 0x100000 /* 1 MiB */), - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_CRYPTO_BUFFER_EXCEEDED, 0, 0), - - OP_END -}; - -/* 44. Fault injection - PADDING */ -static int script_44_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, - unsigned char *buf, size_t len) -{ - int ok = 0; - WPACKET wpkt; - unsigned char frame_buf[16]; - size_t written; - - if (h->inject_word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) - return 1; - - if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, - sizeof(frame_buf), 0))) - return 0; - - if (!TEST_true(ossl_quic_wire_encode_padding(&wpkt, 1))) - goto err; - - if (!TEST_true(WPACKET_get_total_written(&wpkt, &written))) - goto err; - - if (!qtest_fault_prepend_frame(h->qtf, frame_buf, written)) - goto err; - - ok = 1; -err: - if (ok) - WPACKET_finish(&wpkt); - else - WPACKET_cleanup(&wpkt); - return ok; -} - -static const struct script_op script_44[] = { - OP_S_SET_INJECT_PLAIN(script_44_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(1, 0), - - OP_S_WRITE(a, "Strawberry", 10), - OP_C_READ_EXPECT(DEFAULT, "Strawberry", 10), - - OP_END -}; - -/* 45. PING must generate ACK */ -static int force_ping(struct helper *h, struct helper_local *hl) -{ - QUIC_CHANNEL *ch = ossl_quic_tserver_get_channel(ACQUIRE_S()); - - h->scratch0 = ossl_quic_channel_get_diag_num_rx_ack(ch); - - if (!TEST_true(ossl_quic_tserver_ping(ACQUIRE_S()))) - return 0; - - return 1; -} - -static int wait_incoming_acks_increased(struct helper *h, struct helper_local *hl) -{ - QUIC_CHANNEL *ch = ossl_quic_tserver_get_channel(ACQUIRE_S()); - uint16_t count; - - count = ossl_quic_channel_get_diag_num_rx_ack(ch); - - if (count == h->scratch0) { - h->check_spin_again = 1; - return 0; - } - - return 1; -} - -static const struct script_op script_45[] = { - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_BEGIN_REPEAT(2), - - OP_CHECK(force_ping, 0), - OP_CHECK(wait_incoming_acks_increased, 0), - - OP_END_REPEAT(), - - OP_S_WRITE(a, "Strawberry", 10), - OP_C_READ_EXPECT(DEFAULT, "Strawberry", 10), - - OP_END -}; - -/* 46. Fault injection - ACK - malformed initial range */ -static int script_46_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, - unsigned char *buf, size_t len) -{ - int ok = 0; - WPACKET wpkt; - unsigned char frame_buf[16]; - size_t written; - uint64_t type = 0, largest_acked = 0, first_range = 0, range_count = 0; - uint64_t agap = 0, alen = 0; - uint64_t ect0 = 0, ect1 = 0, ecnce = 0; - - if (h->inject_word0 == 0) - return 1; - - if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, - sizeof(frame_buf), 0))) - return 0; - - type = OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN; - - switch (h->inject_word0) { - case 1: - largest_acked = 100; - first_range = 101; - range_count = 0; - break; - case 2: - largest_acked = 100; - first_range = 80; - /* [20..100]; [0..18] */ - range_count = 1; - agap = 0; - alen = 19; - break; - case 3: - largest_acked = 100; - first_range = 80; - range_count = 1; - agap = 18; - alen = 1; - break; - case 4: - type = OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN; - largest_acked = 100; - first_range = 1; - range_count = 0; - break; - case 5: - type = OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN; - largest_acked = 0; - first_range = 0; - range_count = 0; - ect0 = 0; - ect1 = 50; - ecnce = 200; - break; - } - - h->inject_word0 = 0; - - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, type)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, largest_acked)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, /*ack_delay=*/0)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, /*ack_range_count=*/range_count)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, /*first_ack_range=*/first_range))) - goto err; - - if (range_count > 0) - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, /*range[0].gap=*/agap)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, /*range[0].len=*/alen))) - goto err; - - if (type == OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN) - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, ect0)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, ect1)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, ecnce))) - goto err; - - if (!TEST_true(WPACKET_get_total_written(&wpkt, &written))) - goto err; - - if (!qtest_fault_prepend_frame(h->qtf, frame_buf, written)) - goto err; - - ok = 1; -err: - if (ok) - WPACKET_finish(&wpkt); - else - WPACKET_cleanup(&wpkt); - return ok; -} - -static const struct script_op script_46[] = { - OP_S_SET_INJECT_PLAIN(script_46_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(1, 0), - - OP_S_WRITE(a, "Strawberry", 10), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0), - - OP_END -}; - -/* 47. Fault injection - ACK - malformed subsequent range */ -static const struct script_op script_47[] = { - OP_S_SET_INJECT_PLAIN(script_46_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(2, 0), - - OP_S_WRITE(a, "Strawberry", 10), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0), - - OP_END -}; - -/* 48. Fault injection - ACK - malformed subsequent range */ -static const struct script_op script_48[] = { - OP_S_SET_INJECT_PLAIN(script_46_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(3, 0), - - OP_S_WRITE(a, "Strawberry", 10), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0), - - OP_END -}; - -/* 49. Fault injection - ACK - fictional PN */ -static const struct script_op script_49[] = { - OP_S_SET_INJECT_PLAIN(script_46_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(4, 0), - - OP_S_WRITE(a, "Strawberry", 10), - /* - * The injected ACK acknowledges a packet number we have not sent, which the - * peer is expected to treat as a PROTOCOL_VIOLATION, so the connection is - * closed rather than the stream data being delivered. - */ - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_PROTOCOL_VIOLATION, 0, 0), - - OP_END -}; - -/* 50. Fault injection - ACK - duplicate PN */ -static const struct script_op script_50[] = { - OP_S_SET_INJECT_PLAIN(script_46_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_BEGIN_REPEAT(2), - - OP_SET_INJECT_WORD(5, 0), - - OP_S_WRITE(a, "Strawberry", 10), - OP_C_READ_EXPECT(DEFAULT, "Strawberry", 10), - - OP_END_REPEAT(), - - OP_END -}; - -/* 51. Fault injection - PATH_RESPONSE is ignored */ -static const struct script_op script_51[] = { - OP_S_SET_INJECT_PLAIN(script_41_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE), - - OP_S_WRITE(a, "orange", 6), - OP_C_READ_EXPECT(DEFAULT, "orange", 6), - - OP_C_WRITE(DEFAULT, "Strawberry", 10), - OP_S_READ_EXPECT(a, "Strawberry", 10), - - OP_END -}; - -/* 52. Fault injection - ignore BLOCKED frames with bogus values */ -static int script_52_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, - unsigned char *buf, size_t len) -{ - int ok = 0; - unsigned char frame_buf[64]; - size_t written; - WPACKET wpkt; - uint64_t type = h->inject_word1; - - if (h->inject_word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) - return 1; - - --h->inject_word0; - - if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, - sizeof(frame_buf), 0))) - return 0; - - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, type))) - goto err; - - if (type == OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED) - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, C_BIDI_ID(0)))) - goto err; - - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, 0xFFFFFF))) - goto err; - - if (!TEST_true(WPACKET_get_total_written(&wpkt, &written))) - goto err; - - if (!qtest_fault_prepend_frame(h->qtf, frame_buf, written)) - goto err; - - ok = 1; -err: - if (ok) - WPACKET_finish(&wpkt); - else - WPACKET_cleanup(&wpkt); - return ok; -} - -static const struct script_op script_52[] = { - OP_S_SET_INJECT_PLAIN(script_52_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED), - - OP_S_WRITE(a, "orange", 6), - OP_C_READ_EXPECT(DEFAULT, "orange", 6), - - OP_C_WRITE(DEFAULT, "Strawberry", 10), - OP_S_READ_EXPECT(a, "Strawberry", 10), - - OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED), - - OP_S_WRITE(a, "orange", 6), - OP_C_READ_EXPECT(DEFAULT, "orange", 6), - - OP_C_WRITE(DEFAULT, "Strawberry", 10), - OP_S_READ_EXPECT(a, "Strawberry", 10), - - OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI), - - OP_S_WRITE(a, "orange", 6), - OP_C_READ_EXPECT(DEFAULT, "orange", 6), - - OP_C_WRITE(DEFAULT, "Strawberry", 10), - OP_S_READ_EXPECT(a, "Strawberry", 10), - - OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI), - - OP_S_WRITE(a, "orange", 6), - OP_C_READ_EXPECT(DEFAULT, "orange", 6), - - OP_C_WRITE(DEFAULT, "Strawberry", 10), - OP_S_READ_EXPECT(a, "Strawberry", 10), - - OP_END -}; - -/* 53. Fault injection - excess CRYPTO buffer size */ -static int script_53_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, - unsigned char *buf, size_t len) -{ - int ok = 0; - size_t written; - WPACKET wpkt; - uint64_t offset = 0, data_len = 100; - unsigned char *frame_buf = NULL; - size_t frame_len, i; - - if (h->inject_word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) - return 1; - - h->inject_word0 = 0; - - switch (h->inject_word1) { - case 0: - /* - * Far out offset which will not have been reached during handshake. - * This will not be delivered to the QUIC_TLS instance since it will be - * waiting for in-order delivery of previous bytes. This tests our flow - * control on CRYPTO stream buffering. - */ - offset = 100000; - data_len = 1; - break; - } - - frame_len = 1 + 8 + 8 + (size_t)data_len; - if (!TEST_ptr(frame_buf = OPENSSL_malloc(frame_len))) - return 0; - - if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, frame_len, 0))) - goto err; - - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, OSSL_QUIC_FRAME_TYPE_CRYPTO)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, offset)) - || !TEST_true(WPACKET_quic_write_vlint(&wpkt, data_len))) - goto err; - - for (i = 0; i < data_len; ++i) - if (!TEST_true(WPACKET_put_bytes_u8(&wpkt, 0x42))) - goto err; - - if (!TEST_true(WPACKET_get_total_written(&wpkt, &written))) - goto err; - - if (!qtest_fault_prepend_frame(h->qtf, frame_buf, written)) - goto err; - - ok = 1; -err: - if (ok) - WPACKET_finish(&wpkt); - else - WPACKET_cleanup(&wpkt); - OPENSSL_free(frame_buf); - return ok; -} - -static const struct script_op script_53[] = { - OP_S_SET_INJECT_PLAIN(script_53_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(1, 0), - OP_S_WRITE(a, "Strawberry", 10), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_CRYPTO_BUFFER_EXCEEDED, 0, 0), - - OP_END -}; - -/* 54. Fault injection - corrupted crypto stream data */ -static int script_54_inject_handshake(struct helper *h, - unsigned char *buf, size_t buf_len) -{ - size_t i; - - for (i = 0; i < buf_len; ++i) - buf[i] ^= 0xff; - - return 1; -} - -static const struct script_op script_54[] = { - OP_S_SET_INJECT_HANDSHAKE(script_54_inject_handshake), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT_OR_FAIL(), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_CRYPTO_UNEXPECTED_MESSAGE, 0, 0), - - OP_END -}; - -/* 55. Fault injection - NEW_CONN_ID with >20 byte CID */ -static const struct script_op script_55[] = { - OP_S_SET_INJECT_PLAIN(script_39_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_C_NEW_STREAM_BIDI(a, C_BIDI_ID(0)), - OP_C_WRITE(a, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(0, 2), - OP_S_WRITE(a, "orange", 5), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0), - - OP_END -}; - -/* 56. Fault injection - NEW_CONN_ID with seq no < retire prior to */ -static const struct script_op script_56[] = { - OP_S_SET_INJECT_PLAIN(script_39_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_C_NEW_STREAM_BIDI(a, C_BIDI_ID(0)), - OP_C_WRITE(a, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(0, 3), - OP_S_WRITE(a, "orange", 5), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0), - - OP_END -}; - -/* 57. Fault injection - NEW_CONN_ID with lower seq so ignored */ -static const struct script_op script_57[] = { - OP_S_SET_INJECT_PLAIN(script_39_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), - - OP_C_NEW_STREAM_BIDI(a, C_BIDI_ID(0)), - OP_C_WRITE(a, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(0, 4), - OP_S_WRITE(a, "orange", 5), - OP_C_READ_EXPECT(a, "orange", 5), - - OP_C_WRITE(a, "Strawberry", 10), - OP_S_READ_EXPECT(a, "Strawberry", 10), - - /* - * Now we send a NEW_CONN_ID with a bogus CID. However the sequence number - * is old so it should be ignored and we should still be able to - * communicate. - */ - OP_SET_INJECT_WORD(0, 5), - OP_S_WRITE(a, "raspberry", 9), - OP_C_READ_EXPECT(a, "raspberry", 9), - - OP_C_WRITE(a, "peach", 5), - OP_S_READ_EXPECT(a, "peach", 5), - - OP_END -}; - -/* 58. Fault injection - repeated HANDSHAKE_DONE */ -static int script_58_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, - unsigned char *buf, size_t len) -{ - int ok = 0; - unsigned char frame_buf[64]; - size_t written; - WPACKET wpkt; - - if (h->inject_word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) - return 1; - - if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, - sizeof(frame_buf), 0))) - return 0; - - if (h->inject_word0 == 1) { - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE))) - goto err; - } else { - /* Needless multi-byte encoding */ - if (!TEST_true(WPACKET_put_bytes_u8(&wpkt, 0x40)) - || !TEST_true(WPACKET_put_bytes_u8(&wpkt, 0x1E))) - goto err; - } - - if (!TEST_true(WPACKET_get_total_written(&wpkt, &written))) - goto err; - - if (!qtest_fault_prepend_frame(h->qtf, frame_buf, written)) - goto err; - - ok = 1; -err: - if (ok) - WPACKET_finish(&wpkt); - else - WPACKET_cleanup(&wpkt); - return ok; -} - -static const struct script_op script_58[] = { - OP_S_SET_INJECT_PLAIN(script_58_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(1, 0), - - OP_S_WRITE(a, "orange", 6), - OP_C_READ_EXPECT(DEFAULT, "orange", 6), - - OP_C_WRITE(DEFAULT, "Strawberry", 10), - OP_S_READ_EXPECT(a, "Strawberry", 10), - - OP_END -}; - -/* 59. Fault injection - multi-byte frame encoding */ -static const struct script_op script_59[] = { - OP_S_SET_INJECT_PLAIN(script_58_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), - - OP_SET_INJECT_WORD(2, 0), - - OP_S_WRITE(a, "orange", 6), - - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_PROTOCOL_VIOLATION, 0, 0), - - OP_END -}; - -/* 60. Connection close reason truncation */ -static char long_reason[2048]; - -static int init_reason(struct helper *h, struct helper_local *hl) -{ - memset(long_reason, '~', sizeof(long_reason)); - memcpy(long_reason, "This is a long reason string.", 29); - long_reason[OSSL_NELEM(long_reason) - 1] = '\0'; - return 1; -} - -static int check_shutdown_reason(struct helper *h, struct helper_local *hl) -{ - const QUIC_TERMINATE_CAUSE *tc = ossl_quic_tserver_get_terminate_cause(ACQUIRE_S()); - - if (tc == NULL) { - h->check_spin_again = 1; - return 0; - } - - if (!TEST_size_t_ge(tc->reason_len, 50) - || !TEST_mem_eq(long_reason, tc->reason_len, - tc->reason, tc->reason_len)) - return 0; - - return 1; -} - -static const struct script_op script_60[] = { - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), +static const struct script_op script_24[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_C_WRITE(DEFAULT, "apple", 5), - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), +/* 25. Fault injection - excess value of MAX_STREAMS_UNI */ +static const struct script_op script_25[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_CHECK(init_reason, 0), - OP_C_SHUTDOWN_WAIT(long_reason, 0), - OP_CHECK(check_shutdown_reason, 0), +/* 26. Fault injection - excess value of STREAMS_BLOCKED_BIDI */ +static const struct script_op script_26[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; +/* 27. Fault injection - excess value of STREAMS_BLOCKED_UNI */ +static const struct script_op script_27[] = { + /* test moved to test/radix/quic_tests.c */ OP_END }; -/* 61. Fault injection - RESET_STREAM exceeding stream count FC */ -static int script_61_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, +/* 28. Fault injection - received RESET_STREAM for send-only stream */ +static int script_28_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, unsigned char *buf, size_t len) { int ok = 0; @@ -4186,12 +2252,12 @@ static int script_61_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, sizeof(frame_buf), 0))) return 0; - if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, h->inject_word0)) + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, h->inject_word1)) || !TEST_true(WPACKET_quic_write_vlint(&wpkt, /* stream ID */ - h->inject_word1)) + h->inject_word0 - 1)) || !TEST_true(WPACKET_quic_write_vlint(&wpkt, 123)) - || (h->inject_word0 == OSSL_QUIC_FRAME_TYPE_RESET_STREAM - && !TEST_true(WPACKET_quic_write_vlint(&wpkt, 0)))) /* final size */ + || (h->inject_word1 == OSSL_QUIC_FRAME_TYPE_RESET_STREAM + && !TEST_true(WPACKET_quic_write_vlint(&wpkt, 5)))) /* final size */ goto err; if (!TEST_true(WPACKET_get_total_written(&wpkt, &written))) @@ -4209,85 +2275,224 @@ static int script_61_inject_plain(struct helper *h, QUIC_PKT_HDR *hdr, return ok; } -static const struct script_op script_61[] = { - OP_S_SET_INJECT_PLAIN(script_61_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), +static const struct script_op script_28[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_C_NEW_STREAM_BIDI(a, C_BIDI_ID(0)), - OP_C_WRITE(a, "orange", 6), +/* 29. Fault injection - received RESET_STREAM for nonexistent send-only stream */ +static const struct script_op script_29[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "orange", 6), +/* 30. Fault injection - received STOP_SENDING for receive-only stream */ +static const struct script_op script_30[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_SET_INJECT_WORD(OSSL_QUIC_FRAME_TYPE_RESET_STREAM, S_BIDI_ID(OSSL_QUIC_VLINT_MAX / 4)), - OP_S_WRITE(a, "fruit", 5), +/* 31. Fault injection - received STOP_SENDING for nonexistent receive-only stream */ +static const struct script_op script_31[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_STREAM_LIMIT_ERROR, 0, 0), +/* 32. Fault injection - STREAM frame for nonexistent stream */ +static const struct script_op script_32[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; +/* 33. Fault injection - STREAM frame with illegal offset */ +static const struct script_op script_33[] = { + /* test moved to test/radix/quic_tests.c */ OP_END }; -/* 62. Fault injection - STOP_SENDING with high ID */ -static const struct script_op script_62[] = { - OP_S_SET_INJECT_PLAIN(script_61_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), +/* 34. Fault injection - STREAM frame which exceeds FC */ +static const struct script_op script_34[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_C_NEW_STREAM_BIDI(a, C_BIDI_ID(0)), - OP_C_WRITE(a, "orange", 6), +/* 35. Fault injection - MAX_STREAM_DATA for receive-only stream */ +static const struct script_op script_35[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "orange", 6), +/* 36. Fault injection - MAX_STREAM_DATA for nonexistent stream */ +static const struct script_op script_36[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; + +/* 37. Fault injection - STREAM_DATA_BLOCKED for send-only stream */ +static const struct script_op script_37[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_SET_INJECT_WORD(OSSL_QUIC_FRAME_TYPE_STOP_SENDING, C_BIDI_ID(OSSL_QUIC_VLINT_MAX / 4)), - OP_S_WRITE(a, "fruit", 5), +/* 38. Fault injection - STREAM_DATA_BLOCKED for non-existent stream */ +static const struct script_op script_38[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0), +/* 39. Fault injection - NEW_CONN_ID with zero-len CID */ +static const struct script_op script_39[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; +/* 40. Shutdown flush test */ +static const struct script_op script_40[] = { + /* test moved to test/radix/quic_tests.c */ OP_END }; -/* 63. Fault injection - STREAM frame exceeding stream limit */ -static const struct script_op script_63[] = { - OP_S_SET_INJECT_PLAIN(script_32_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), +/* 41. Fault injection - PATH_CHALLENGE yields PATH_RESPONSE */ +static const struct script_op script_41[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_C_NEW_STREAM_BIDI(a, C_BIDI_ID(0)), - OP_C_WRITE(a, "apple", 5), +/* 42. Fault injection - CRYPTO frame with illegal offset */ +static const struct script_op script_42[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_S_BIND_STREAM_ID(a, C_BIDI_ID(0)), - OP_S_READ_EXPECT(a, "apple", 5), +/* 43. Fault injection - CRYPTO frame exceeding FC */ +static const struct script_op script_43[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_SET_INJECT_WORD(S_BIDI_ID(5000) + 1, 4), - OP_S_WRITE(a, "orange", 6), +/* 44. Fault injection - PADDING */ +static const struct script_op script_44[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_C_EXPECT_CONN_CLOSE_INFO(OSSL_QUIC_ERR_STREAM_LIMIT_ERROR, 0, 0), +/* 45. PING must generate ACK */ +static const struct script_op script_45[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; +/* 46. Fault injection - ACK - malformed initial range */ +static const struct script_op script_46[] = { + /* test moved to test/radix/quic_tests.c */ OP_END }; -/* 64. Fault injection - STREAM - zero-length no-FIN is accepted */ -static const struct script_op script_64[] = { - OP_S_SET_INJECT_PLAIN(script_32_inject_plain), - OP_C_SET_ALPN("ossltest"), - OP_C_CONNECT_WAIT(), - OP_C_SET_DEFAULT_STREAM_MODE(SSL_DEFAULT_STREAM_MODE_NONE), +/* 47. Fault injection - ACK - malformed subsequent range */ +static const struct script_op script_47[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_S_NEW_STREAM_UNI(a, S_UNI_ID(0)), - OP_S_WRITE(a, "apple", 5), +/* 48. Fault injection - ACK - malformed subsequent range */ +static const struct script_op script_48[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_C_ACCEPT_STREAM_WAIT(a), - OP_C_READ_EXPECT(a, "apple", 5), +/* 49. Fault injection - ACK - fictional PN */ +static const struct script_op script_49[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; - OP_SET_INJECT_WORD(S_BIDI_ID(20) + 1, 1), - OP_S_WRITE(a, "orange", 6), - OP_C_READ_EXPECT(a, "orange", 6), +/* 50. Fault injection - ACK - duplicate PN */ +static const struct script_op script_50[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; + +/* 51. Fault injection - PATH_RESPONSE is ignored */ +static const struct script_op script_51[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; + +/* 52. Fault injection - ignore BLOCKED frames with bogus values */ +static const struct script_op script_52[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; + +/* 53. Fault injection - excess CRYPTO buffer size */ +static const struct script_op script_53[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; + +/* 54. Fault injection - corrupted crypto stream data */ +static const struct script_op script_54[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; + +/* 55. Fault injection - NEW_CONN_ID with >20 byte CID */ +static const struct script_op script_55[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; + +/* 56. Fault injection - NEW_CONN_ID with seq no < retire prior to */ +static const struct script_op script_56[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; + +/* 57. Fault injection - NEW_CONN_ID with lower seq so ignored */ +static const struct script_op script_57[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; + +/* 58. Fault injection - repeated HANDSHAKE_DONE */ +static const struct script_op script_58[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; + +/* 59. Fault injection - multi-byte frame encoding */ +static const struct script_op script_59[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; + +/* 60. Connection close reason truncation */ +static const struct script_op script_60[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; + +/* 61. Fault injection - RESET_STREAM exceeding stream count FC */ +static const struct script_op script_61[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; + +/* 62. Fault injection - STOP_SENDING with high ID */ +static const struct script_op script_62[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; + +/* 63. Fault injection - STREAM frame exceeding stream limit */ +static const struct script_op script_63[] = { + /* test moved to test/radix/quic_tests.c */ + OP_END +}; +/* 64. Fault injection - STREAM - zero-length no-FIN is accepted */ +static const struct script_op script_64[] = { + /* test moved to test/radix/quic_tests.c */ OP_END }; @@ -4686,15 +2891,15 @@ static int server_gen_version_neg(struct helper *h, BIO_MSG *msg, size_t stride) goto err; if (!TEST_true(qtest_fault_resize_datagram(h->qtf, l))) - return 0; + goto err; memcpy(msg->data, buf->data, l); h->inject_word0 = 0; rc = 1; err: - if (have_wpkt) - WPACKET_finish(&wpkt); + if (have_wpkt && !WPACKET_finish(&wpkt)) + WPACKET_cleanup(&wpkt); BUF_MEM_free(buf); return rc; @@ -6193,7 +4398,7 @@ static int test_script(int idx) } #endif - BIO_snprintf(script_name, sizeof(script_name), "script %d", script_idx + 1); + snprintf(script_name, sizeof(script_name), "script %d", script_idx + 1); TEST_info("Running script %d (order=%d, blocking=%d)", script_idx + 1, free_order, blocking); @@ -6279,7 +4484,7 @@ static ossl_unused int test_dyn_frame_types(int idx) s[i].arg2 = forbidden_frame_types[idx].expected_err; } - BIO_snprintf(script_name, sizeof(script_name), + snprintf(script_name, sizeof(script_name), "dyn script %d", idx); return run_script(dyn_frame_types_script, script_name, 0, 0); diff --git a/test/quic_rcidm_test.c b/test/quic_rcidm_test.c index 1b966c93d35ad..41c9b92f67c99 100644 --- a/test/quic_rcidm_test.c +++ b/test/quic_rcidm_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/quic_record_test.c b/test/quic_record_test.c index 0c9fa3a09822d..3b24dcd86572b 100644 --- a/test/quic_record_test.c +++ b/test/quic_record_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/quic_srt_gen_test.c b/test/quic_srt_gen_test.c index cfcee4a953d67..5c578f9bdd23d 100644 --- a/test/quic_srt_gen_test.c +++ b/test/quic_srt_gen_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/quic_srtm_test.c b/test/quic_srtm_test.c index 6a1d6f36181aa..46f84e5a51c13 100644 --- a/test/quic_srtm_test.c +++ b/test/quic_srtm_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -22,14 +22,17 @@ static int test_srtm(void) QUIC_SRTM *srtm; void *opaque = NULL; uint64_t seq_num = 0; + uint8_t match; if (!TEST_ptr(srtm = ossl_quic_srtm_new(NULL, NULL))) goto err; if (!TEST_true(ossl_quic_srtm_add(srtm, ptrs + 0, 0, &token_1)) || !TEST_false(ossl_quic_srtm_add(srtm, ptrs + 0, 0, &token_1)) - || !TEST_false(ossl_quic_srtm_remove(srtm, ptrs + 0, 1)) - || !TEST_false(ossl_quic_srtm_remove(srtm, ptrs + 3, 0)) + || !TEST_true(ossl_quic_srtm_remove(srtm, ptrs + 0, 1, &match)) + || !TEST_uint_eq(match, 0) + || !TEST_true(ossl_quic_srtm_remove(srtm, ptrs + 3, 0, &match)) + || !TEST_uint_eq(match, 0) || !TEST_true(ossl_quic_srtm_cull(srtm, ptrs + 3)) || !TEST_true(ossl_quic_srtm_cull(srtm, ptrs + 3)) || !TEST_true(ossl_quic_srtm_add(srtm, ptrs + 0, 1, &token_1)) @@ -38,7 +41,8 @@ static int test_srtm(void) || !TEST_true(ossl_quic_srtm_add(srtm, ptrs + 1, 0, &token_1)) || !TEST_true(ossl_quic_srtm_add(srtm, ptrs + 2, 0, &token_2)) || !TEST_true(ossl_quic_srtm_add(srtm, ptrs + 3, 3, &token_2)) - || !TEST_true(ossl_quic_srtm_remove(srtm, ptrs + 3, 3)) + || !TEST_true(ossl_quic_srtm_remove(srtm, ptrs + 3, 3, &match)) + || !TEST_uint_eq(match, 1) || !TEST_true(ossl_quic_srtm_lookup(srtm, &token_1, 0, &opaque, &seq_num)) || !TEST_ptr_eq(opaque, ptrs + 1) || !TEST_uint64_t_eq(seq_num, 0) @@ -62,7 +66,8 @@ static int test_srtm(void) || !TEST_true(ossl_quic_srtm_lookup(srtm, &token_2, 0, &opaque, &seq_num)) || !TEST_ptr_eq(opaque, ptrs + 2) || !TEST_uint64_t_eq(seq_num, 0) - || !TEST_true(ossl_quic_srtm_remove(srtm, ptrs + 2, 0)) + || !TEST_true(ossl_quic_srtm_remove(srtm, ptrs + 2, 0, &match)) + || !TEST_uint_eq(match, 1) || !TEST_false(ossl_quic_srtm_lookup(srtm, &token_2, 0, &opaque, &seq_num))) goto err; @@ -102,11 +107,11 @@ static int test_srtm_ops_mfail(void) || !ossl_quic_srtm_add(srtm, ptrs + 1, 0, &token_1) || !ossl_quic_srtm_add(srtm, ptrs + 2, 0, &token_2) || !ossl_quic_srtm_add(srtm, ptrs + 3, 3, &token_2) - || !ossl_quic_srtm_remove(srtm, ptrs + 3, 3) + || !ossl_quic_srtm_remove(srtm, ptrs + 3, 3, NULL) || !ossl_quic_srtm_lookup(srtm, &token_1, 0, &opaque, &seq_num) || !ossl_quic_srtm_cull(srtm, ptrs + 0) || !ossl_quic_srtm_lookup(srtm, &token_2, 0, &opaque, &seq_num) - || !ossl_quic_srtm_remove(srtm, ptrs + 2, 0)) + || !ossl_quic_srtm_remove(srtm, ptrs + 2, 0, NULL)) goto err; testresult = 1; diff --git a/test/quic_stream_test.c b/test/quic_stream_test.c index 6a646d93636e7..7a3bbf2208669 100644 --- a/test/quic_stream_test.c +++ b/test/quic_stream_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,9 +7,42 @@ * https://www.openssl.org/source/license.html */ #include "internal/packet.h" +#include "internal/quic_record_rx.h" #include "internal/quic_stream.h" +#include "../ssl/quic/quic_record_rx_local.h" #include "testutil.h" +/* + * A received packet as the stream code sees it, without a QRX behind it. + * The reference the caller keeps is never released by the stream code, so + * the reference count never reaches zero and the packet is never recycled + * through the QRX it does not have. It is freed with pkt_test_free() once + * the test is done with it. + */ +static OSSL_QRX_PKT *pkt_test_new(size_t datagram_len) +{ + RXE *rxe = OPENSSL_zalloc(sizeof(*rxe)); + + if (rxe == NULL) + return NULL; + + rxe->refcount = 1; + rxe->datagram_len = datagram_len; + rxe->pkt.datagram_len = datagram_len; + return &rxe->pkt; +} + +/* The number of references held on a packet, including the caller's own. */ +static size_t pkt_test_refcount(const OSSL_QRX_PKT *pkt) +{ + return ((const RXE *)pkt)->refcount; +} + +static void pkt_test_free(OSSL_QRX_PKT *pkt) +{ + OPENSSL_free((RXE *)pkt); +} + static int compare_iov(const unsigned char *ref, size_t ref_len, const OSSL_QTX_IOVEC *iov, size_t iov_len) { @@ -375,23 +408,29 @@ static const unsigned char simple_data[] = "Hello world! And thank you for all t static int test_rstream_simple(int idx) { QUIC_RSTREAM *rstream = NULL; + OSSL_QRX_PKT *pkt[8] = { NULL }; int ret = 0; unsigned char buf[sizeof(simple_data)]; - size_t readbytes = 0, avail = 0; + size_t readbytes = 0, avail = 0, i; int fin = 0; - int use_rbuf = idx > 1; - int use_sc = idx % 2; + int use_sc = (idx & 1) != 0; + int use_rbuf = (idx & 2) != 0; int (*read_fn)(QUIC_RSTREAM *, unsigned char *, size_t, size_t *, int *) = use_sc ? test_single_copy_read : ossl_quic_rstream_read; + /* every frame arrives in a packet, as it does in production */ + for (i = 0; i < OSSL_NELEM(pkt); ++i) + if (!TEST_ptr(pkt[i] = pkt_test_new(1200))) + goto err; + if (!TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, 0))) goto err; - if (!TEST_true(ossl_quic_rstream_queue_data(rstream, NULL, 5, + if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[0], 5, simple_data + 5, 10, 0)) - || !TEST_true(ossl_quic_rstream_queue_data(rstream, NULL, + || !TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[1], sizeof(simple_data) - 1, simple_data + sizeof(simple_data) - 1, 1, 1)) @@ -399,11 +438,11 @@ static int test_rstream_simple(int idx) &readbytes, &fin)) || !TEST_false(fin) || !TEST_size_t_eq(readbytes, 0) - || !TEST_true(ossl_quic_rstream_queue_data(rstream, NULL, + || !TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[2], sizeof(simple_data) - 10, simple_data + sizeof(simple_data) - 10, 10, 1)) - || !TEST_true(ossl_quic_rstream_queue_data(rstream, NULL, 0, + || !TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[3], 0, simple_data, 1, 0)) || !TEST_true(ossl_quic_rstream_peek(rstream, buf, sizeof(buf), &readbytes, &fin)) @@ -415,10 +454,10 @@ static int test_rstream_simple(int idx) && !TEST_true(ossl_quic_rstream_resize_rbuf(rstream, sizeof(simple_data)))) || (use_rbuf && !TEST_true(ossl_quic_rstream_move_to_rbuf(rstream))) - || !TEST_true(ossl_quic_rstream_queue_data(rstream, NULL, + || !TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[4], 0, simple_data, 10, 0)) - || !TEST_true(ossl_quic_rstream_queue_data(rstream, NULL, + || !TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[5], sizeof(simple_data), NULL, 0, 1)) @@ -427,7 +466,7 @@ static int test_rstream_simple(int idx) || !TEST_false(fin) || !TEST_size_t_eq(readbytes, 15) || !TEST_mem_eq(buf, 15, simple_data, 15) - || !TEST_true(ossl_quic_rstream_queue_data(rstream, NULL, + || !TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[6], 15, simple_data + 15, sizeof(simple_data) - 15, 1)) @@ -442,7 +481,7 @@ static int test_rstream_simple(int idx) || !TEST_false(fin) || !TEST_size_t_eq(readbytes, 12) || !TEST_mem_eq(buf + 2, 12, simple_data + 2, 12) - || !TEST_true(ossl_quic_rstream_queue_data(rstream, NULL, + || !TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[7], sizeof(simple_data), NULL, 0, 1)) @@ -469,6 +508,13 @@ static int test_rstream_simple(int idx) err: ossl_quic_rstream_free(rstream); + /* All the references held by the stream must have been released */ + for (i = 0; i < OSSL_NELEM(pkt); ++i) { + if (pkt[i] != NULL + && !TEST_size_t_eq(pkt_test_refcount(pkt[i]), 1)) + ret = 0; + pkt_test_free(pkt[i]); + } return ret; } @@ -477,14 +523,18 @@ static int test_rstream_random(int idx) unsigned char *bulk_data = NULL; unsigned char *read_buf = NULL; QUIC_RSTREAM *rstream = NULL; - size_t i, read_off, queued_min, queued_max; + OSSL_QRX_PKT **pkts = NULL; + size_t i, read_off, queued_min, queued_max, num_pkts = 0; const size_t data_size = 10000; + /* At most two frames are queued per each of the 100 * 10 iterations */ + const size_t max_pkts = 100 * 10 * 2; int r, s, fin = 0, fin_set = 0; int ret = 0; size_t readbytes = 0; if (!TEST_ptr(bulk_data = OPENSSL_malloc(data_size)) || !TEST_ptr(read_buf = OPENSSL_malloc(data_size)) + || !TEST_ptr(pkts = OPENSSL_zalloc(sizeof(*pkts) * max_pkts)) || !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, 0))) goto err; @@ -498,6 +548,7 @@ static int test_rstream_random(int idx) for (r = 0; r < 100; ++r) { for (s = 0; s < 10; ++s) { size_t off = (r * 10 + s) * 10, size = 10; + OSSL_QRX_PKT *pkt = NULL; if (test_random() % 10 == 0) /* drop packet */ @@ -506,7 +557,12 @@ static int test_rstream_random(int idx) if (off <= queued_min && off + size > queued_min) queued_min = off + size; - if (!TEST_true(ossl_quic_rstream_queue_data(rstream, NULL, off, + /* each frame arrives in its own packet */ + if (!TEST_ptr(pkt = pkt_test_new(1200))) + goto err; + pkts[num_pkts++] = pkt; + + if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt, off, bulk_data + off, size, 0))) goto err; @@ -526,7 +582,12 @@ static int test_rstream_random(int idx) if (off <= queued_min && off + size > queued_min) queued_min = off + size; - if (!TEST_true(ossl_quic_rstream_queue_data(rstream, NULL, off, + /* a retransmit arrives in its own packet */ + if (!TEST_ptr(pkt = pkt_test_new(1200))) + goto err; + pkts[num_pkts++] = pkt; + + if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt, off, bulk_data + off, size, 0))) goto err; @@ -590,16 +651,337 @@ static int test_rstream_random(int idx) err: ossl_quic_rstream_free(rstream); + if (pkts != NULL) { + /* All the references held by the stream must have been released */ + for (i = 0; i < num_pkts; ++i) { + if (!TEST_size_t_eq(pkt_test_refcount(pkts[i]), 1)) + ret = 0; + pkt_test_free(pkts[i]); + } + OPENSSL_free(pkts); + } OPENSSL_free(bulk_data); OPENSSL_free(read_buf); return ret; } +/* + * Verify the reference counting of packets pinned by buffered stream + * chunks and the cleansing of packet backed chunks. + */ +static int test_rstream_pkt(void) +{ + QUIC_RSTREAM *rstream = NULL; + OSSL_QRX_PKT *pkt_a = NULL, *pkt_b = NULL, *pkt_c = NULL; + unsigned char pdata[64], cbuf[64], buf[64]; + size_t readbytes = 0, avail = 0, i; + int fin = 0; + int ret = 0; + + for (i = 0; i < sizeof(pdata); ++i) + pdata[i] = (unsigned char)(0x40 + i); + + if (!TEST_ptr(pkt_a = pkt_test_new(1200)) + || !TEST_ptr(pkt_b = pkt_test_new(1200)) + || !TEST_ptr(pkt_c = pkt_test_new(1200)) + || !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, 0))) + goto err; + + /* A buffered frame holds a reference to its packet */ + if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_a, 0, + pdata, 10, 0)) + || !TEST_size_t_eq(pkt_test_refcount(pkt_a), 2)) + goto err; + + /* Two frames from the same packet hold two references */ + if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_a, 20, + pdata + 20, 10, 0)) + || !TEST_size_t_eq(pkt_test_refcount(pkt_a), 3)) + goto err; + + /* A frame contained in already buffered data takes no reference */ + if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_b, 2, + pdata + 2, 6, 0)) + || !TEST_size_t_eq(pkt_test_refcount(pkt_b), 1)) + goto err; + + /* + * An overlapping frame drops the frames it covers and releases + * their references + */ + if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_c, 0, + pdata, 15, 0)) + || !TEST_size_t_eq(pkt_test_refcount(pkt_a), 2) + || !TEST_size_t_eq(pkt_test_refcount(pkt_c), 2)) + goto err; + + /* Reading past a frame releases its reference */ + if (!TEST_true(ossl_quic_rstream_available(rstream, &avail, &fin)) + || !TEST_size_t_eq(avail, 15) + || !TEST_true(ossl_quic_rstream_read(rstream, buf, sizeof(buf), + &readbytes, &fin)) + || !TEST_size_t_eq(readbytes, 15) + || !TEST_mem_eq(buf, 15, pdata, 15) + || !TEST_size_t_eq(pkt_test_refcount(pkt_c), 1) + || !TEST_size_t_eq(pkt_test_refcount(pkt_a), 2)) + goto err; + + /* Moving frames to the ring buffer releases their references */ + if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_b, 15, + pdata + 15, 5, 0)) + || !TEST_size_t_eq(pkt_test_refcount(pkt_b), 2) + || !TEST_true(ossl_quic_rstream_resize_rbuf(rstream, sizeof(pdata))) + || !TEST_true(ossl_quic_rstream_move_to_rbuf(rstream)) + || !TEST_size_t_eq(pkt_test_refcount(pkt_a), 1) + || !TEST_size_t_eq(pkt_test_refcount(pkt_b), 1)) + goto err; + + /* The moved data is still readable from the ring buffer */ + if (!TEST_true(ossl_quic_rstream_read(rstream, buf, sizeof(buf), + &readbytes, &fin)) + || !TEST_size_t_eq(readbytes, 15) + || !TEST_mem_eq(buf, 15, pdata + 15, 15)) + goto err; + + /* Freeing the stream releases the references of buffered frames */ + if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_c, 30, + pdata + 30, 10, 0)) + || !TEST_size_t_eq(pkt_test_refcount(pkt_c), 2)) + goto err; + ossl_quic_rstream_free(rstream); + rstream = NULL; + if (!TEST_size_t_eq(pkt_test_refcount(pkt_c), 1)) + goto err; + + /* + * Cleansing a consumed packet backed chunk wipes exactly the chunk + * data, leaving the surrounding bytes intact. + */ + memset(cbuf, 0xAA, sizeof(cbuf)); + if (!TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, 0))) + goto err; + ossl_quic_rstream_set_cleanse(rstream, 1); + if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt_a, 0, + cbuf + 8, 48, 0)) + || !TEST_size_t_eq(pkt_test_refcount(pkt_a), 2) + || !TEST_true(ossl_quic_rstream_read(rstream, buf, 48, + &readbytes, &fin)) + || !TEST_size_t_eq(readbytes, 48) + || !TEST_size_t_eq(pkt_test_refcount(pkt_a), 1)) + goto err; + for (i = 0; i < sizeof(cbuf); ++i) + if (!TEST_uchar_eq(cbuf[i], i >= 8 && i < 56 ? 0 : 0xAA)) + goto err; + + ret = 1; + +err: + ossl_quic_rstream_free(rstream); + pkt_test_free(pkt_a); + pkt_test_free(pkt_b); + pkt_test_free(pkt_c); + return ret; +} + +/* + * Many small contiguous frames, each pinning its own packet while the reader + * lags behind, so a large number of packets are held at once and released only + * as the data is finally consumed. Every byte must still read back in order and + * every packet reference must end up released. + */ +static int test_rstream_pkt_overhead(void) +{ + QUIC_RSTREAM *rstream = NULL; + OSSL_QRX_PKT **pkt = NULL; + unsigned char *data = NULL, *buf = NULL; + const size_t framesz = 8; + const size_t nframes = 4096; /* far past a 64 KiB overhead limit */ + const size_t total = framesz * nframes; + const size_t read_lag = 200; /* read only after this many arrive */ + size_t i, got = 0, readbytes = 0; + int fin = 0, ret = 0; + + if (!TEST_ptr(data = OPENSSL_malloc(total)) + || !TEST_ptr(buf = OPENSSL_malloc(total)) + || !TEST_ptr(pkt = OPENSSL_zalloc(nframes * sizeof(*pkt))) + || !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, 0))) + goto err; + + for (i = 0; i < total; ++i) + data[i] = (unsigned char)(i & 0xff); + + for (i = 0; i < nframes; ++i) { + if (!TEST_ptr(pkt[i] = pkt_test_new(1200))) + goto err; + + if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt[i], + i * framesz, data + i * framesz, framesz, + i == nframes - 1))) + goto err; + + /* let the reader fall behind, then drain what has become available */ + if (i % read_lag == read_lag - 1) + while (got < total + && TEST_true(ossl_quic_rstream_read(rstream, buf + got, + total - got, &readbytes, &fin)) + && readbytes > 0) + got += readbytes; + } + + /* drain whatever is left and check every byte survived in order */ + while (got < total + && TEST_true(ossl_quic_rstream_read(rstream, buf + got, total - got, + &readbytes, &fin)) + && readbytes > 0) + got += readbytes; + + if (!TEST_size_t_eq(got, total) + || !TEST_true(fin) + || !TEST_mem_eq(buf, got, data, total)) + goto err; + + /* every consumed frame has released the reference it held on its packet */ + for (i = 0; i < nframes; ++i) + if (!TEST_size_t_eq(pkt_test_refcount(pkt[i]), 1)) + goto err; + + ret = 1; + +err: + ossl_quic_rstream_free(rstream); + if (pkt != NULL) + for (i = 0; i < nframes; ++i) + pkt_test_free(pkt[i]); + OPENSSL_free(pkt); + OPENSSL_free(data); + OPENSSL_free(buf); + return ret; +} + +/* + * Reassemble a buffer delivered as small frames in a random order with + * overlapping retransmits, each frame carrying its own copy of its bytes on + * its own packet as a real one would. The random order drives insertion at the + * head, the tail and the middle of the reassembly, and the frame size is swept + * across the boundary where a design may switch how it stores a chunk, so short + * frames and their overlaps are merged in every combination. The read back must + * match what was sent whether or not the data is cleansed, since each frame's + * own copy is what gets wiped, never the reference. + */ +static int test_rstream_reorder(int idx) +{ + unsigned char *data = NULL, *buf = NULL, *arena = NULL, *ap; + QUIC_RSTREAM *rstream = NULL; + OSSL_QRX_PKT **pkts = NULL; + const size_t data_size = 4096; + const size_t framesz = 1 + (size_t)(idx % 17); + const int cleanse = (idx & 1); + const size_t nframes = (data_size + framesz - 1) / framesz; + size_t *order = NULL; + size_t i, num_pkts = 0, got = 0, readbytes = 0; + int fin = 0, ret = 0; + + if (!TEST_ptr(data = OPENSSL_malloc(data_size)) + || !TEST_ptr(buf = OPENSSL_malloc(data_size)) + || !TEST_ptr(arena = OPENSSL_malloc(3 * data_size)) + || !TEST_ptr(order = OPENSSL_malloc(nframes * sizeof(*order))) + || !TEST_ptr(pkts = OPENSSL_zalloc(2 * nframes * sizeof(*pkts))) + || !TEST_ptr(rstream = ossl_quic_rstream_new(NULL, NULL, 0))) + goto err; + + if (cleanse) + ossl_quic_rstream_set_cleanse(rstream, 1); + + for (i = 0; i < data_size; ++i) + data[i] = (unsigned char)(test_random() & 0xFF); + + for (i = 0; i < nframes; ++i) + order[i] = i; + for (i = nframes; i > 1; --i) { + size_t j = (size_t)(test_random() % i); + size_t tmp = order[i - 1]; + + order[i - 1] = order[j]; + order[j] = tmp; + } + + ap = arena; + for (i = 0; i < nframes; ++i) { + size_t off = order[i] * framesz; + size_t size = off + framesz > data_size ? data_size - off : framesz; + OSSL_QRX_PKT *pkt; + + if (!TEST_ptr(pkt = pkt_test_new(1200))) + goto err; + pkts[num_pkts++] = pkt; + memcpy(ap, data + off, size); + if (!TEST_true(ossl_quic_rstream_queue_data(rstream, pkt, off, ap, + size, 0))) + goto err; + ap += size; + + /* an overlapping retransmit straddling this frame and the next */ + if (off + framesz + framesz / 2 <= data_size + && test_random() % 3 == 0) { + size_t roff = off + framesz / 2; + OSSL_QRX_PKT *rpkt; + + if (!TEST_ptr(rpkt = pkt_test_new(1200))) + goto err; + pkts[num_pkts++] = rpkt; + memcpy(ap, data + roff, framesz); + if (!TEST_true(ossl_quic_rstream_queue_data(rstream, rpkt, roff, ap, + framesz, 0))) + goto err; + ap += framesz; + } + } + + /* final empty fin frame past the last byte */ + if (!TEST_true(ossl_quic_rstream_queue_data(rstream, NULL, data_size, NULL, + 0, 1))) + goto err; + + while (got < data_size) { + if (!TEST_true(ossl_quic_rstream_read(rstream, buf + got, + data_size - got, &readbytes, &fin))) + goto err; + if (readbytes == 0) + break; + got += readbytes; + } + + if (!TEST_size_t_eq(got, data_size) + || !TEST_mem_eq(buf, got, data, data_size)) + goto err; + + ret = 1; + +err: + ossl_quic_rstream_free(rstream); + if (pkts != NULL) { + for (i = 0; i < num_pkts; ++i) { + if (!TEST_size_t_eq(pkt_test_refcount(pkts[i]), 1)) + ret = 0; + pkt_test_free(pkts[i]); + } + OPENSSL_free(pkts); + } + OPENSSL_free(order); + OPENSSL_free(arena); + OPENSSL_free(data); + OPENSSL_free(buf); + return ret; +} + int setup_tests(void) { ADD_TEST(test_sstream_simple); ADD_ALL_TESTS(test_sstream_bulk, 100); ADD_ALL_TESTS(test_rstream_simple, 4); ADD_ALL_TESTS(test_rstream_random, 100); + ADD_TEST(test_rstream_pkt); + ADD_TEST(test_rstream_pkt_overhead); + ADD_ALL_TESTS(test_rstream_reorder, 40); return 1; } diff --git a/test/quic_tserver_test.c b/test/quic_tserver_test.c index b4e81f427f8b9..ac3d879e463a9 100644 --- a/test/quic_tserver_test.c +++ b/test/quic_tserver_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -60,7 +60,7 @@ static int do_test(int use_thread_assist, int use_fake_time, int use_inject) BIO *c_pair_own = NULL, *s_pair_own = NULL; QUIC_TSERVER_ARGS tserver_args = { 0 }; QUIC_TSERVER *tserver = NULL; - BIO_ADDR *s_addr_ = NULL; + BIO_ADDR *s_addr_ = NULL, *c_addr_ = NULL; struct in_addr ina = { 0 }; union BIO_sock_info_u s_info = { 0 }; SSL_CTX *c_ctx = NULL; @@ -85,31 +85,57 @@ static int do_test(int use_thread_assist, int use_fake_time, int use_inject) ina.s_addr = htonl(0x7f000001UL); /* Setup test server. */ - s_fd = BIO_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0); - if (!TEST_int_ge(s_fd, 0)) - goto err; - - if (!TEST_true(BIO_socket_nbio(s_fd, 1))) - goto err; - if (!TEST_ptr(s_addr_ = BIO_ADDR_new())) goto err; if (!TEST_true(BIO_ADDR_rawmake(s_addr_, AF_INET, &ina, sizeof(ina), 0))) goto err; - if (!TEST_true(BIO_bind(s_fd, s_addr_, 0))) - goto err; + if (use_fake_time) { + /* + * Keep accelerated fake time independent of OS network scheduling. + * Other iterations retain real UDP socket coverage. + */ + if (!TEST_true(BIO_new_bio_dgram_pair(&c_net_bio_own, 0, + &s_net_bio_own, 0))) + goto err; - s_info.addr = s_addr_; - if (!TEST_true(BIO_sock_info(s_fd, BIO_SOCK_INFO_ADDRESS, &s_info))) - goto err; + c_net_bio = c_net_bio_own; + s_net_bio = s_net_bio_own; - if (!TEST_int_gt(BIO_ADDR_rawport(s_addr_), 0)) - goto err; + if (!TEST_true(BIO_dgram_set_caps(c_net_bio, + BIO_DGRAM_CAP_HANDLES_DST_ADDR)) + || !TEST_true(BIO_dgram_set_caps(s_net_bio, + BIO_DGRAM_CAP_HANDLES_DST_ADDR))) + goto err; - if (!TEST_ptr(s_net_bio = s_net_bio_own = BIO_new_dgram(s_fd, 0))) - goto err; + if (!TEST_ptr(c_addr_ = BIO_ADDR_new()) + || !TEST_true(BIO_ADDR_rawmake(c_addr_, AF_INET, &ina, + sizeof(ina), 0)) + || !TEST_true(BIO_dgram_set0_local_addr(c_net_bio, c_addr_))) + goto err; + c_addr_ = NULL; + } else { + s_fd = BIO_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0); + if (!TEST_int_ge(s_fd, 0)) + goto err; + + if (!TEST_true(BIO_socket_nbio(s_fd, 1))) + goto err; + + if (!TEST_true(BIO_bind(s_fd, s_addr_, 0))) + goto err; + + s_info.addr = s_addr_; + if (!TEST_true(BIO_sock_info(s_fd, BIO_SOCK_INFO_ADDRESS, &s_info))) + goto err; + + if (!TEST_int_gt(BIO_ADDR_rawport(s_addr_), 0)) + goto err; + + if (!TEST_ptr(s_net_bio = s_net_bio_own = BIO_new_dgram(s_fd, 0))) + goto err; + } if (!BIO_up_ref(s_net_bio)) goto err; @@ -144,18 +170,20 @@ static int do_test(int use_thread_assist, int use_fake_time, int use_inject) } /* Setup test client. */ - c_fd = BIO_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0); - if (!TEST_int_ge(c_fd, 0)) - goto err; + if (!use_fake_time) { + c_fd = BIO_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0); + if (!TEST_int_ge(c_fd, 0)) + goto err; - if (!TEST_true(BIO_socket_nbio(c_fd, 1))) - goto err; + if (!TEST_true(BIO_socket_nbio(c_fd, 1))) + goto err; - if (!TEST_ptr(c_net_bio = c_net_bio_own = BIO_new_dgram(c_fd, 0))) - goto err; + if (!TEST_ptr(c_net_bio = c_net_bio_own = BIO_new_dgram(c_fd, 0))) + goto err; - if (!BIO_dgram_set_peer(c_net_bio, s_addr_)) - goto err; + if (!BIO_dgram_set_peer(c_net_bio, s_addr_)) + goto err; + } if (!TEST_ptr(c_ctx = SSL_CTX_new(use_thread_assist ? OSSL_QUIC_client_thread_method() @@ -165,9 +193,12 @@ static int do_test(int use_thread_assist, int use_fake_time, int use_inject) if (!TEST_ptr(c_ssl = SSL_new(c_ctx))) goto err; - if (use_fake_time) + if (use_fake_time) { + if (!TEST_true(SSL_set1_initial_peer_addr(c_ssl, s_addr_))) + goto err; if (!TEST_true(ossl_quic_set_override_now_cb(c_ssl, fake_now, NULL))) goto err; + } /* 0 is a success for SSL_set_alpn_protos() */ if (!TEST_false(SSL_set_alpn_protos(c_ssl, alpn, sizeof(alpn)))) @@ -397,7 +428,7 @@ static int do_test(int use_thread_assist, int use_fake_time, int use_inject) for (;;) { /* - * Manually spoonfeed received datagrams from the real BIO_dgram + * Manually spoonfeed received datagrams from the network BIO * into QUIC via the injection interface, thereby testing the * injection interface. */ @@ -421,6 +452,7 @@ static int do_test(int use_thread_assist, int use_fake_time, int use_inject) SSL_CTX_free(c_ctx); ossl_quic_tserver_free(tserver); BIO_ADDR_free(s_addr_); + BIO_ADDR_free(c_addr_); BIO_free(s_net_bio_own); BIO_free(c_net_bio_own); BIO_free(c_pair_own); diff --git a/test/quic_txp_test.c b/test/quic_txp_test.c index b2a2d79e5e4b5..ee1432129b6f9 100644 --- a/test/quic_txp_test.c +++ b/test/quic_txp_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/quicapitest.c b/test/quicapitest.c index a8de8f9670bdd..ddaed7025c2cd 100644 --- a/test/quicapitest.c +++ b/test/quicapitest.c @@ -22,6 +22,7 @@ #include "../ssl/quic/quic_channel_local.h" #include "internal/quic_error.h" #include "internal/quic_ssl.h" +#include "internal/quic_port.h" static OSSL_LIB_CTX *libctx = NULL; static char *propq = NULL; @@ -43,6 +44,7 @@ static SSL_CTX *create_server_ctx(void); static SSL_CTX *create_client_ctx(void); static int create_quic_ssl_objects(SSL_CTX *sctx, SSL_CTX *cctx, SSL **lssl, SSL **cssl); +static void quic_advance_time(SSL *clientssl, SSL *serverssl); static int qc_init(SSL *qconn, BIO_ADDR *dst_addr); /* The ssltrace test assumes some options are switched on/off */ @@ -62,7 +64,7 @@ static int qc_init(SSL *qconn, BIO_ADDR *dst_addr); */ static int test_quic_write_read(int idx) { - SSL_CTX *cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()); + SSL_CTX *cctx = NULL; SSL_CTX *sctx = NULL; SSL *clientquic = NULL; QUIC_TSERVER *qtserv = NULL; @@ -78,6 +80,7 @@ static int test_quic_write_read(int idx) if (idx >= 1 && !qtest_supports_blocking()) return TEST_skip("Blocking tests not supported in this build"); + cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()); for (k = 0; k < 2; k++) { if (!TEST_ptr(cctx) || !TEST_true(qtest_create_quic_objects(libctx, cctx, sctx, @@ -308,7 +311,7 @@ static int test_ssl_read_key_update_mfail(void) */ static int test_fin_only_blocking(void) { - SSL_CTX *cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()); + SSL_CTX *cctx = NULL; SSL_CTX *sctx = NULL; SSL *clientquic = NULL; QUIC_TSERVER *qtserv = NULL; @@ -322,6 +325,7 @@ static int test_fin_only_blocking(void) if (!qtest_supports_blocking()) return TEST_skip("Blocking tests not supported in this build"); + cctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method()); if (!TEST_ptr(cctx) || !TEST_true(qtest_create_quic_objects(libctx, cctx, sctx, cert, privkey, @@ -2422,7 +2426,9 @@ static int test_domain_flags(void) { int testresult = 0; SSL_CTX *ctx = NULL; - SSL *domain = NULL, *listener = NULL, *other_conn = NULL; + SSL *inherited_domain = NULL, *domain = NULL, *listener = NULL; + SSL *listener_conn = NULL; + SSL *other_conn = NULL; uint64_t domain_flags = 0; if (!TEST_ptr(ctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_client_method())) @@ -2430,15 +2436,19 @@ static int test_domain_flags(void) || !TEST_uint64_t_ne(domain_flags, 0) || !TEST_uint64_t_ne(domain_flags & (SSL_DOMAIN_FLAG_SINGLE_THREAD | SSL_DOMAIN_FLAG_MULTI_THREAD), 0) || !TEST_uint64_t_ne(domain_flags & SSL_DOMAIN_FLAG_LEGACY_BLOCKING, 0) - || !TEST_true(SSL_CTX_set_domain_flags(ctx, SSL_DOMAIN_FLAG_SINGLE_THREAD)) + || !TEST_true(SSL_CTX_set_domain_flags(ctx, SSL_DOMAIN_FLAG_MULTI_THREAD)) || !TEST_true(SSL_CTX_get_domain_flags(ctx, &domain_flags)) - || !TEST_uint64_t_eq(domain_flags, SSL_DOMAIN_FLAG_SINGLE_THREAD) - || !TEST_ptr(domain = SSL_new_domain(ctx, 0)) + || !TEST_uint64_t_eq(domain_flags, SSL_DOMAIN_FLAG_MULTI_THREAD) + || !TEST_ptr(inherited_domain = SSL_new_domain(ctx, 0)) + || !TEST_true(SSL_get_domain_flags(inherited_domain, &domain_flags)) + || !TEST_uint64_t_eq(domain_flags, SSL_DOMAIN_FLAG_MULTI_THREAD) + || !TEST_ptr(domain = SSL_new_domain(ctx, + SSL_DOMAIN_FLAG_SINGLE_THREAD)) || !TEST_true(SSL_get_domain_flags(domain, &domain_flags)) || !TEST_uint64_t_eq(domain_flags, SSL_DOMAIN_FLAG_SINGLE_THREAD) || !TEST_true(other_conn = SSL_new(ctx)) || !TEST_true(SSL_get_domain_flags(other_conn, &domain_flags)) - || !TEST_uint64_t_eq(domain_flags, SSL_DOMAIN_FLAG_SINGLE_THREAD) + || !TEST_uint64_t_eq(domain_flags, SSL_DOMAIN_FLAG_MULTI_THREAD) || !TEST_true(SSL_is_domain(domain)) || !TEST_false(SSL_is_domain(other_conn)) || !TEST_ptr_eq(SSL_get0_domain(domain), domain) @@ -2447,13 +2457,22 @@ static int test_domain_flags(void) || !TEST_true(SSL_is_listener(listener)) || !TEST_false(SSL_is_domain(listener)) || !TEST_ptr_eq(SSL_get0_domain(listener), domain) - || !TEST_ptr_eq(SSL_get0_listener(listener), listener)) + || !TEST_ptr_eq(SSL_get0_listener(listener), listener) + || !TEST_true(SSL_get_domain_flags(listener, &domain_flags)) + || !TEST_uint64_t_eq(domain_flags, SSL_DOMAIN_FLAG_SINGLE_THREAD) + || !TEST_ptr(listener_conn = SSL_new_from_listener(listener, 0)) + || !TEST_ptr_eq(SSL_get0_domain(listener_conn), domain) + || !TEST_ptr_eq(SSL_get0_listener(listener_conn), listener) + || !TEST_true(SSL_get_domain_flags(listener_conn, &domain_flags)) + || !TEST_uint64_t_eq(domain_flags, SSL_DOMAIN_FLAG_SINGLE_THREAD)) goto err; testresult = 1; err: - SSL_free(domain); + SSL_free(listener_conn); SSL_free(listener); + SSL_free(domain); + SSL_free(inherited_domain); SSL_free(other_conn); SSL_CTX_free(ctx); return testresult; @@ -2805,7 +2824,7 @@ static OSSL_TIME fake_now_cb(void *arg) } static int create_quic_ssl_objects_ex(SSL_CTX *sctx, SSL_CTX *cctx, - SSL **lssl, SSL **cssl, int use_fake_time) + SSL *domain, SSL **lssl, SSL **cssl, int use_fake_time) { BIO_ADDR *addr = NULL; struct in_addr ina; @@ -2825,10 +2844,19 @@ static int create_quic_ssl_objects_ex(SSL_CTX *sctx, SSL_CTX *cctx, goto err; addr = NULL; - *lssl = ql_create(sctx, sbio); - sbio = NULL; - if (!TEST_ptr(*lssl)) - goto err; + if (domain == NULL) { + *lssl = ql_create(sctx, sbio); + sbio = NULL; + if (!TEST_ptr(*lssl)) + goto err; + } else { + if (!TEST_ptr(*lssl = SSL_new_listener_from(domain, 0))) + goto err; + SSL_set_bio(*lssl, sbio, sbio); + sbio = NULL; + if (!TEST_true(SSL_listen(*lssl))) + goto err; + } if (!TEST_ptr(*cssl = SSL_new(cctx))) goto err; @@ -2876,7 +2904,70 @@ static int create_quic_ssl_objects_ex(SSL_CTX *sctx, SSL_CTX *cctx, static int create_quic_ssl_objects(SSL_CTX *sctx, SSL_CTX *cctx, SSL **lssl, SSL **cssl) { - return create_quic_ssl_objects_ex(sctx, cctx, lssl, cssl, 0); + return create_quic_ssl_objects_ex(sctx, cctx, NULL, lssl, cssl, 0); +} + +static int queue_incoming_connection(SSL *qlistener, SSL *clientssl) +{ + int i, ret; + + for (i = 0; i < 5; i++) { + ret = SSL_connect(clientssl); + if (!TEST_int_le(ret, 0) + || !TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_WANT_READ)) + return 0; + + SSL_handle_events(qlistener); + if (SSL_get_accept_connection_queue_len(qlistener) == 1) + break; + } + + return TEST_size_t_eq(SSL_get_accept_connection_queue_len(qlistener), 1); +} + +static SSL *listen_ex_msg_cb_ssl; +static char listen_ex_msg_cb_arg; +static unsigned int listen_ex_tls_msg_count; +static unsigned int listen_ex_quic_msg_count; +static int listen_ex_msg_cb_mismatch; + +static void listen_ex_msg_cb(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg) +{ + (void)write_p; + (void)version; + (void)buf; + (void)len; + + if (ssl != listen_ex_msg_cb_ssl || arg != &listen_ex_msg_cb_arg) + listen_ex_msg_cb_mismatch = 1; + + if (content_type == SSL3_RT_HANDSHAKE) + ++listen_ex_tls_msg_count; + + switch (content_type) { + case SSL3_RT_QUIC_DATAGRAM: + case SSL3_RT_QUIC_PACKET: + case SSL3_RT_QUIC_FRAME_FULL: + case SSL3_RT_QUIC_FRAME_HEADER: + case SSL3_RT_QUIC_FRAME_PADDING: + ++listen_ex_quic_msg_count; + break; + default: + break; + } +} + +static int listen_ex_rejects_new_conn(SSL *qlistener, SSL *new_conn) +{ + int ret = SSL_listen_ex(qlistener, new_conn); + unsigned long err = ERR_get_error(); + int ok = TEST_int_eq(ret, -1) + && TEST_int_eq(ERR_GET_REASON(err), ERR_R_PASSED_INVALID_ARGUMENT) + && TEST_size_t_eq(SSL_get_accept_connection_queue_len(qlistener), 1); + + ERR_clear_error(); + return ok; } static int test_ssl_client_as_ossl_quic_method(void) @@ -2947,68 +3038,312 @@ static int test_ssl_client_as_ossl_quic_method(void) static int test_ssl_listen_ex(void) { - SSL_CTX *cctx = NULL, *sctx = NULL, *qmctx = NULL; + SSL_CTX *cctx = NULL, *sctx = NULL, *qmctx = NULL, *threadctx = NULL; SSL *clientssl = NULL, *serverssl = NULL, *qlistener = NULL; + SSL *domain = NULL; + SSL *preconf = NULL, *prestream = NULL, *threadssl = NULL; + SSL *cstream = NULL, *sstream = NULL; + BIO *confbio = NULL; + unsigned char buf[16], msg[] = "Hello, World!"; + size_t readbytes, written; + uint64_t listener_domain_flags, target_domain_flags; + uint64_t connection_domain_flags, stream_domain_flags; + uint64_t event_handling_mode; + long listener_mode, target_mode; int testresult = 0; int ret = 0, i; if (!TEST_ptr(sctx = create_server_ctx()) - || !TEST_ptr(cctx = create_client_ctx())) + || !TEST_ptr(cctx = create_client_ctx()) + || !TEST_true(SSL_CTX_set_domain_flags(sctx, + SSL_DOMAIN_FLAG_MULTI_THREAD))) goto err; - if (!create_quic_ssl_objects(sctx, cctx, &qlistener, &clientssl)) + listener_mode = SSL_CTX_set_mode(sctx, SSL_MODE_ENABLE_PARTIAL_WRITE); + SSL_CTX_set_msg_callback(sctx, listen_ex_msg_cb); + SSL_CTX_set_msg_callback_arg(sctx, &listen_ex_msg_cb_arg); + + if (!TEST_ptr(domain = SSL_new_domain(sctx, + SSL_DOMAIN_FLAG_MULTI_THREAD)) + || !create_quic_ssl_objects_ex(sctx, cctx, domain, + &qlistener, &clientssl, 1)) goto err; qmctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_method()); - if (!TEST_ptr(qmctx)) + if (!TEST_ptr(qmctx) + || !TEST_true(SSL_CTX_set_domain_flags(qmctx, + SSL_DOMAIN_FLAG_SINGLE_THREAD))) goto err; + SSL_CTX_set_mode(qmctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); serverssl = SSL_new(qmctx); if (!TEST_ptr(serverssl)) goto err; - /* Send ClientHello and server retry */ - for (i = 0; i < 5; i++) { + SSL_clear_mode(serverssl, SSL_MODE_ENABLE_PARTIAL_WRITE); + if (!TEST_true(SSL_set_event_handling_mode(serverssl, + SSL_VALUE_EVENT_HANDLING_MODE_EXPLICIT))) + goto err; + target_mode = SSL_get_mode(serverssl); + listen_ex_msg_cb_ssl = serverssl; + listen_ex_tls_msg_count = 0; + listen_ex_quic_msg_count = 0; + listen_ex_msg_cb_mismatch = 0; + + if (!TEST_int_eq(SSL_listen_ex(NULL, serverssl), -1) + || !TEST_true(ERR_GET_REASON(ERR_get_error()) + == ERR_R_PASSED_INVALID_ARGUMENT) + || !TEST_int_eq(SSL_listen_ex(qlistener, serverssl), 0) + || !queue_incoming_connection(qlistener, clientssl) + || !TEST_true(SSL_get_domain_flags(qlistener, + &listener_domain_flags)) + || !TEST_true(SSL_get_domain_flags(serverssl, + &target_domain_flags)) + || !TEST_uint64_t_ne(listener_domain_flags, target_domain_flags) + || !TEST_long_ne(listener_mode, target_mode)) + goto err; + ERR_clear_error(); + +#if defined(OPENSSL_THREADS) && !defined(OPENSSL_NO_THREAD_POOL) \ + && !defined(OPENSSL_NO_QUIC_THREAD_ASSIST) + /* Thread assistance can't be transferred to an accepted connection. */ + threadctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_method()); + if (!TEST_ptr(threadctx) + || !TEST_true(SSL_CTX_set_domain_flags(threadctx, + SSL_DOMAIN_FLAG_THREAD_ASSISTED | SSL_DOMAIN_FLAG_BLOCKING)) + || !TEST_ptr(threadssl = SSL_new(threadctx)) + || !listen_ex_rejects_new_conn(qlistener, threadssl)) + goto err; + + SSL_free(threadssl); + threadssl = NULL; +#endif + + /* A connection which has already been started is not fresh. */ + if (!listen_ex_rejects_new_conn(qlistener, clientssl)) + goto err; + + /* A connection which belongs to this listener isn't standalone. */ + preconf = SSL_new_from_listener(qlistener, 0); + if (!TEST_ptr(preconf) + || !listen_ex_rejects_new_conn(qlistener, preconf)) + goto err; + + SSL_free(preconf); + preconf = NULL; + + /* Network BIOs may not already be attached. */ + preconf = SSL_new(qmctx); + if (!TEST_ptr(preconf) + || !TEST_ptr(confbio = BIO_new(BIO_s_mem()))) + goto err; + SSL_set_bio(preconf, confbio, confbio); + confbio = NULL; + if (!listen_ex_rejects_new_conn(qlistener, preconf)) + goto err; + + SSL_free(preconf); + preconf = NULL; + + /* Streams may not already have been created. */ + preconf = SSL_new(qmctx); + if (!TEST_ptr(preconf) + || !TEST_ptr(prestream = SSL_new_stream(preconf, + SSL_STREAM_FLAG_ADVANCE)) + || !listen_ex_rejects_new_conn(qlistener, preconf)) + goto err; + + SSL_free(prestream); + prestream = NULL; + SSL_free(preconf); + preconf = NULL; + + if (!TEST_int_eq(SSL_listen_ex(qlistener, serverssl), 1) + || !TEST_size_t_eq(SSL_get_accept_connection_queue_len(qlistener), 0) + || !TEST_true(SSL_get_domain_flags(serverssl, + &connection_domain_flags)) + || !TEST_uint64_t_eq(connection_domain_flags, + listener_domain_flags) + || !TEST_ptr_eq(SSL_get0_domain(serverssl), domain) + || !TEST_ptr_eq(SSL_get0_listener(serverssl), qlistener) + || !TEST_long_eq(SSL_get_mode(serverssl), listener_mode) + || !TEST_true(SSL_get_event_handling_mode(serverssl, + &event_handling_mode)) + || !TEST_uint64_t_eq(event_handling_mode, + SSL_VALUE_EVENT_HANDLING_MODE_INHERIT)) + goto err; + + if (!TEST_ptr_null(SSL_accept_connection(qlistener, 0)) + || !TEST_true(ERR_GET_REASON(ERR_get_error()) + == ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED)) + goto err; + ERR_clear_error(); + + /* The adopted connection keeps the listener hierarchy alive. */ + SSL_free(qlistener); + qlistener = NULL; + SSL_free(domain); + domain = NULL; + + for (i = 0; i < 10; i++) { + ret = SSL_do_handshake(serverssl); + if (ret != 1 + && !TEST_int_eq(SSL_get_error(serverssl, ret), SSL_ERROR_WANT_READ)) + goto err; + ret = SSL_connect(clientssl); - if (!TEST_int_le(ret, 0) - || !TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_WANT_READ)) + if (ret != 1 + && !TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_WANT_READ)) goto err; - ret = SSL_listen_ex(qlistener, serverssl); - if (ret == 1) + + if (SSL_is_init_finished(serverssl) && SSL_is_init_finished(clientssl)) break; - SSL_handle_events(qlistener); + quic_advance_time(clientssl, serverssl); } - /* - * Check to make sure we got a good return code from SSL_listen_ex - */ - if (!TEST_int_eq(ret, 1)) + if (!TEST_int_lt(i, 10) + || !TEST_true(SSL_is_init_finished(serverssl)) + || !TEST_true(SSL_is_init_finished(clientssl))) goto err; - /* Call SSL_accept() and SSL_connect() until we are connected */ - if (!TEST_true(create_bare_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE, 0, 0))) + if (!TEST_true(SSL_set_default_stream_mode(serverssl, + SSL_DEFAULT_STREAM_MODE_NONE)) + || !TEST_true(SSL_set_default_stream_mode(clientssl, + SSL_DEFAULT_STREAM_MODE_NONE)) + || !TEST_ptr(cstream = SSL_new_stream(clientssl, 0)) + || !TEST_true(SSL_write_ex(cstream, msg, sizeof(msg), &written)) + || !TEST_size_t_eq(written, sizeof(msg)) + || !TEST_int_eq(SSL_handle_events(serverssl), 1)) + goto err; - /* - * Ensure that, now that we have used SSL_listen_ex, SSL_accept_connection - * produces an error - */ - if (!TEST_ptr_null(SSL_accept_connection(qlistener, 0))) - goto err; + sstream = SSL_accept_stream(serverssl, 0); + if (!TEST_ptr(sstream) + || !TEST_true(SSL_get_domain_flags(sstream, &stream_domain_flags)) + || !TEST_uint64_t_eq(stream_domain_flags, listener_domain_flags) + || !TEST_ptr_eq(SSL_get0_domain(sstream), + SSL_get0_domain(serverssl)) + || !TEST_ptr_eq(SSL_get0_listener(sstream), + SSL_get0_listener(serverssl)) + || !TEST_true(SSL_read_ex(sstream, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(msg)) + || !TEST_mem_eq(buf, readbytes, msg, sizeof(msg)) + || !TEST_true(SSL_write_ex(sstream, msg, sizeof(msg), &written)) + || !TEST_size_t_eq(written, sizeof(msg)) + || !TEST_true(SSL_read_ex(cstream, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, sizeof(msg)) + || !TEST_mem_eq(buf, readbytes, msg, sizeof(msg))) + goto err; - if (!TEST_true((ERR_GET_REASON(ERR_get_error())) == ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED)) + if (!TEST_uint_gt(listen_ex_tls_msg_count, 0) + || !TEST_uint_gt(listen_ex_quic_msg_count, 0) + || !TEST_false(listen_ex_msg_cb_mismatch)) goto err; - ERR_clear_error(); testresult = 1; err: + SSL_free(sstream); + SSL_free(cstream); + SSL_free(prestream); + SSL_free(preconf); + SSL_free(threadssl); + BIO_free(confbio); SSL_free(qlistener); SSL_free(serverssl); SSL_free(clientssl); + SSL_free(domain); SSL_CTX_free(sctx); SSL_CTX_free(cctx); SSL_CTX_free(qmctx); + SSL_CTX_free(threadctx); + listen_ex_msg_cb_ssl = NULL; + + return testresult; +} + +/* Free a listener which still owns a deferred, unpeeled channel. */ +static int test_ssl_listen_ex_teardown(void) +{ + SSL_CTX *cctx = NULL, *sctx = NULL, *qmctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL, *qlistener = NULL; + int testresult = 0; + + if (!TEST_ptr(sctx = create_server_ctx()) + || !TEST_ptr(cctx = create_client_ctx()) + || !create_quic_ssl_objects_ex(sctx, cctx, NULL, + &qlistener, &clientssl, 1) + || !TEST_ptr(qmctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_method())) + || !TEST_ptr(serverssl = SSL_new(qmctx)) + || !TEST_int_eq(SSL_listen_ex(qlistener, serverssl), 0) + || !queue_incoming_connection(qlistener, clientssl)) + goto err; + + SSL_free(qlistener); + qlistener = NULL; + testresult = 1; + +err: + SSL_free(qlistener); + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + SSL_CTX_free(qmctx); + return testresult; +} + +/* Internal failures are errors and must not consume the queued channel. */ +static int test_ssl_listen_ex_mfail(void) +{ + SSL_CTX *cctx = NULL, *sctx = NULL, *qmctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL, *qlistener = NULL; + int testresult = 0, ret; + + if (!TEST_ptr(sctx = create_server_ctx()) + || !TEST_ptr(cctx = create_client_ctx()) + || !create_quic_ssl_objects_ex(sctx, cctx, NULL, + &qlistener, &clientssl, 1) + || !TEST_ptr(qmctx = SSL_CTX_new_ex(libctx, NULL, OSSL_QUIC_method())) + || !TEST_ptr(serverssl = SSL_new(qmctx)) + || !TEST_int_eq(SSL_listen_ex(qlistener, serverssl), 0) + || !queue_incoming_connection(qlistener, clientssl)) + goto err; + + MFAIL_start(); + ret = SSL_listen_ex(qlistener, serverssl); + MFAIL_end(); + ERR_clear_error(); + + if (mfail_was_triggered()) { + if (!TEST_int_eq(ret, -1) + || !TEST_size_t_eq(SSL_get_accept_connection_queue_len(qlistener), 1)) { + /* ADD_MFAIL_NO_CHECK_TEST treats -1 as an unconditional failure. */ + testresult = -1; + goto err; + } + + ERR_clear_error(); + if (!TEST_int_eq(SSL_listen_ex(qlistener, serverssl), 1) + || !TEST_size_t_eq( + SSL_get_accept_connection_queue_len(qlistener), 0)) { + testresult = -1; + goto err; + } + } else if (!TEST_int_eq(ret, 1) + || !TEST_size_t_eq(SSL_get_accept_connection_queue_len(qlistener), 0)) { + goto err; + } + + testresult = 1; +err: + MFAIL_end(); + SSL_free(qlistener); + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + SSL_CTX_free(qmctx); return testresult; } @@ -3278,6 +3613,86 @@ static int test_accept_stream(void) return testresult; } +/* + * Streams rejected by the incoming stream policy are never placed on the accept + * queue. Check that they are still garbage collected and that the peer is + * granted credit for another stream, so that a peer which keeps opening streams + * neither grows the stream map without bound nor exhausts its stream limit. + */ +static int test_reject_stream_gc(void) +{ + /* Comfortably more than the default initial stream limit of 100. */ + static const int num_streams = 250; + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL, *qlistener = NULL; + SSL *streamssl = NULL; + QUIC_CHANNEL *ch; + QUIC_STREAM_MAP *qsm; + size_t written = 0; + int testresult = 0, ret, i; + + if (!TEST_ptr(sctx = create_server_ctx()) + || !TEST_ptr(cctx = create_client_ctx()) + || !create_quic_ssl_objects(sctx, cctx, &qlistener, &clientssl)) + goto err; + + for (i = 0; i < 2; i++) { + ret = SSL_connect(clientssl); + if (!TEST_int_le(ret, 0) + || !TEST_int_eq(SSL_get_error(clientssl, ret), + SSL_ERROR_WANT_READ)) + goto err; + SSL_handle_events(qlistener); + } + + if (!TEST_ptr(serverssl = SSL_accept_connection(qlistener, 0)) + || !TEST_true(create_bare_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE, 0, 0)) + || !TEST_true(SSL_set_incoming_stream_policy(clientssl, + SSL_INCOMING_STREAM_POLICY_REJECT, 42)) + || !TEST_ptr(ch = ossl_quic_conn_get_channel(clientssl))) + goto err; + + qsm = ossl_quic_channel_get_qsm(ch); + + for (i = 0; i < num_streams; i++) { + if (!TEST_ptr(streamssl = SSL_new_stream(serverssl, 0)) + || !TEST_true(SSL_write_ex(streamssl, "x", 1, &written))) + goto err; + SSL_free(streamssl); + streamssl = NULL; + + /* + * Let the client reject the stream and the server pick up both the + * resulting frames and the MAX_STREAMS credit they release. + */ + if (!TEST_int_eq(SSL_handle_events(clientssl), 1) + || !TEST_int_eq(SSL_handle_events(serverssl), 1) + || !TEST_int_eq(SSL_handle_events(clientssl), 1)) + goto err; + } + + /* + * Every rejected stream should have been collected by now, so the map must + * not have grown in proportion to the number of streams opened. + */ + if (!TEST_size_t_lt(OPENSSL_LH_num_items((OPENSSL_LHASH *)qsm->map), + (size_t)num_streams / 10) + || !TEST_size_t_eq(SSL_get_accept_stream_queue_len(clientssl), 0)) + goto err; + + testresult = 1; +err: + SSL_free(streamssl); + SSL_free(serverssl); + SSL_free(clientssl); + SSL_free(qlistener); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} + /* * When the server has a different primary group than the client, the server * should not fail on the client hello retry. @@ -3558,7 +3973,8 @@ static int test_quic_handshake_multipkt_mfail(void) || !TEST_ptr(cctx = create_client_ctx())) goto err; - if (!create_quic_ssl_objects_ex(sctx, cctx, &qlistener, &clientssl, 1)) + if (!create_quic_ssl_objects_ex(sctx, cctx, NULL, + &qlistener, &clientssl, 1)) goto err; if (!TEST_true(SSL_set_tlsext_host_name(clientssl, "localhost"))) @@ -3840,6 +4256,129 @@ static int test_ssl_new_mfail(void) return ret; } +#define PENDING_LIMIT 5 +#define HANDSHAKE_STEPS 10 +static int test_pending_limit(void) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl_listener = NULL, *serverssl = NULL; + SSL *extra_clients[PENDING_LIMIT * 2] = { NULL }; + BIO *bio; + unsigned int i, handshake_step; + int done; + int testresult = 0; + int ok; + QUIC_PORT *port; + size_t pending_connections = 0; + + if (!TEST_true(create_quic_ctx_pair(libctx, &cctx, &sctx, cert, privkey))) + return 0; + + if (!TEST_true(create_quic_conn_objects(cctx, sctx, &clientssl, &serverssl_listener))) + goto end; + + ok = SSL_set_generic_value_uint(serverssl_listener, + SSL_VALUE_QUIC_MAX_PENDING_CONNS, PENDING_LIMIT); + if (!TEST_true(ok)) { + TEST_info("%s call to SSL_set_generic_request_uint" + "(SSL_VALUE_QUIC_MAX_PENDING_CONNS failed", + OPENSSL_FUNC); + goto end; + } + + if (!TEST_true(SSL_listen(serverssl_listener))) { + TEST_info("%s SSL_listen() failed", OPENSSL_FUNC); + goto end; + } + + port = ossl_quic_listener_get_port(serverssl_listener); + if (!TEST_ptr(port)) + goto end; + + bio = SSL_get_rbio(clientssl); + if (!TEST_ptr(bio)) + goto end; + + if (!TEST_ptr_eq(bio, SSL_get_wbio(clientssl))) + goto end; + + for (i = 0; i < OSSL_NELEM(extra_clients); i++) { + extra_clients[i] = create_quic_client(cctx, bio); + if (!TEST_ptr(extra_clients[i])) + goto end; + } + + for (i = 0; i < PENDING_LIMIT; i++) { + handshake_step = 0; + done = 0; + while (!done && handshake_step++ < HANDSHAKE_STEPS) { + /* + * connections are never accepted by the server. The SSL_connect() + * for non-blocking client returns -1 to keep connect retrying + */ + if (!TEST_int_lt(SSL_connect(extra_clients[i]), 0)) + goto end; + SSL_handle_events(serverssl_listener); + pending_connections = ossl_quic_port_get_num_incoming_channels(port); + done = (pending_connections == (i + 1)); + } + } + + if (!TEST_size_t_eq(pending_connections, PENDING_LIMIT)) + goto end; + + /* + * initiate yet another connection. The connection must not be inserted + * to pending queue. The pending_connections must be 5. + */ + for (i = PENDING_LIMIT; i < OSSL_NELEM(extra_clients); i++) { + handshake_step = 0; + done = 0; + while (!done && handshake_step++ < HANDSHAKE_STEPS) { + /* + * connections are never accepted by the server. The SSL_connect() + * for non-blocking client returns -1 to keep connect retrying + */ + if (!TEST_int_le(SSL_connect(extra_clients[i]), 0)) + goto end; + SSL_handle_events(serverssl_listener); + pending_connections = ossl_quic_port_get_num_incoming_channels(port); + done = (pending_connections == (i + 1)); + } + } + pending_connections = ossl_quic_port_get_num_incoming_channels(port); + if (!TEST_size_t_eq(pending_connections, PENDING_LIMIT)) + goto end; + + /* + * accept one connection and check the length of the queue dropped to 4. + */ + done = 0; + handshake_step = 0; + while (!done && handshake_step++ < HANDSHAKE_STEPS) { + if (!TEST_int_lt(SSL_connect(extra_clients[0]), 0)) + goto end; + SSL_handle_events(serverssl_listener); + serverssl = SSL_accept_connection(serverssl_listener, 0); + done = (serverssl != NULL); + } + pending_connections = ossl_quic_port_get_num_incoming_channels(port); + if (!TEST_size_t_eq(pending_connections, PENDING_LIMIT - 1)) + goto end; + + testresult = 1; +end: + for (i = 0; i < OSSL_NELEM(extra_clients); i++) + SSL_free(extra_clients[i]); + SSL_free(clientssl); + SSL_free(serverssl); + SSL_free(serverssl_listener); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} + /***********************************************************************************/ OPT_TEST_DECLARE_USAGE("provider config certsdir datadir\n") @@ -3923,6 +4462,8 @@ int setup_tests(void) ADD_ALL_TESTS(test_quic_set_fd, 3); ADD_TEST(test_bio_ssl); ADD_TEST(test_ssl_listen_ex); + ADD_TEST(test_ssl_listen_ex_teardown); + ADD_MFAIL_NO_CHECK_TEST(test_ssl_listen_ex_mfail); ADD_TEST(test_ssl_client_as_ossl_quic_method); ADD_TEST(test_back_pressure); ADD_TEST(test_multiple_dgrams); @@ -3946,6 +4487,7 @@ int setup_tests(void) ADD_TEST(test_ssl_accept_connection); ADD_TEST(test_ssl_set_verify); ADD_TEST(test_accept_stream); + ADD_TEST(test_reject_stream_gc); ADD_TEST(test_client_hello_retry); #if OPENSSL_USE_IPV6 ADD_TEST(test_quic_peer_addr_v6); @@ -3955,6 +4497,7 @@ int setup_tests(void) ADD_TEST(test_ech); ADD_TEST(test_quic_resize_txe); ADD_MFAIL_TEST(test_ssl_new_mfail); + ADD_TEST(test_pending_limit); return 1; err: diff --git a/test/radix/quic_bindings.c b/test/radix/quic_bindings.c index 02356f48eba7c..21fd5ef0e643b 100644 --- a/test/radix/quic_bindings.c +++ b/test/radix/quic_bindings.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -13,6 +13,7 @@ #include "internal/quic_channel.h" #include "internal/quic_ssl.h" #include "internal/quic_error.h" +#include "internal/quic_thread_assist.h" /* * RADIX 6D QUIC Test Framework @@ -66,9 +67,13 @@ typedef struct radix_process_st { /* Process-global state. */ CRYPTO_MUTEX *gm; /* global mutex */ - LHASH_OF(RADIX_OBJ) *objs; /* protected by gm */ - OSSL_TIME time_slip; /* protected by gm */ + LHASH_OF(RADIX_OBJ) *objs; BIO *keylog_out; /* protected by gm */ + uint64_t counter[2]; /* protected by gm */ + + CRYPTO_MUTEX *time_m; + OSSL_TIME base_time; /* set once at init, constant thereafter */ + OSSL_TIME time_slip; /* protected by time_m */ int done_join_all_threads; @@ -104,7 +109,7 @@ typedef struct radix_thread_st { DEFINE_STACK_OF(RADIX_THREAD) -/* ssl reference is transferred. name is copied and is required. */ +/* name is copied and is required. Created with no SSL object bound yet. */ static RADIX_OBJ *RADIX_OBJ_new_empty(const char *name) { RADIX_OBJ *obj; @@ -132,6 +137,7 @@ static RADIX_OBJ *RADIX_OBJ_new_empty(const char *name) return obj; } +/* ssl reference is transferred. name is copied and is required. */ static RADIX_OBJ *RADIX_OBJ_new(const char *name, SSL *ssl) { RADIX_OBJ *obj; @@ -139,8 +145,7 @@ static RADIX_OBJ *RADIX_OBJ_new(const char *name, SSL *ssl) if (!TEST_ptr(ssl)) return NULL; - obj = RADIX_OBJ_new_empty(name); - if (!TEST_ptr(obj)) + if (!TEST_ptr(obj = RADIX_OBJ_new_empty(name))) return NULL; obj->ssl = ssl; @@ -178,6 +183,8 @@ static int RADIX_PROCESS_init(RADIX_PROCESS *rp, size_t node_idx, size_t process #if defined(OPENSSL_THREADS) if (!TEST_ptr(rp->gm = ossl_crypto_mutex_new())) goto err; + if (!TEST_ptr(rp->time_m = ossl_crypto_mutex_new())) + goto err; #endif if (!TEST_ptr(rp->objs = lh_RADIX_OBJ_new(RADIX_OBJ_hash, RADIX_OBJ_cmp))) @@ -196,12 +203,15 @@ static int RADIX_PROCESS_init(RADIX_PROCESS *rp, size_t node_idx, size_t process rp->process_idx = process_idx; rp->done_join_all_threads = 0; rp->next_thread_idx = 0; + rp->base_time = ossl_time_now(); + rp->time_slip = ossl_time_zero(); return 1; err: lh_RADIX_OBJ_free(rp->objs); rp->objs = NULL; ossl_crypto_mutex_free(&rp->gm); + ossl_crypto_mutex_free(&rp->time_m); return 0; } @@ -378,7 +388,7 @@ static void RADIX_PROCESS_report_thread_results(RADIX_PROCESS *rp, BIO *bio) "Result for child thread with index %zu:\n", rp->node_idx, rp->process_idx, rt->thread_idx, rt->thread_idx); - BIO_snprintf(pfx_buf, sizeof(pfx_buf), "# -T-%2zu:\t# ", rt->thread_idx); + snprintf(pfx_buf, sizeof(pfx_buf), "# -T-%2zu:\t# ", rt->thread_idx); BIO_set_prefix(bio_err, pfx_buf); l = BIO_get_mem_data(rt->debug_bio, &p); @@ -456,6 +466,7 @@ static void RADIX_PROCESS_cleanup(RADIX_PROCESS *rp) BIO_free_all(rp->keylog_out); rp->keylog_out = NULL; ossl_crypto_mutex_free(&rp->gm); + ossl_crypto_mutex_free(&rp->time_m); } static RADIX_OBJ *RADIX_PROCESS_get_obj(RADIX_PROCESS *rp, const char *name) @@ -662,6 +673,9 @@ static int bindings_process_finish(int testresult_main) radix_thread_cleanup(); /* cleanup main thread */ RADIX_PROCESS_cleanup(&radix_process); + if (!TEST_true(CRYPTO_THREAD_cleanup_local(&radix_thread))) + testresult = 0; + if (testresult) BIO_printf(bio_err, "==> OK\n\n"); else @@ -678,38 +692,46 @@ static OSSL_TIME get_time(void *arg) { OSSL_TIME time_slip; - ossl_crypto_mutex_lock(RP()->gm); + ossl_crypto_mutex_lock(RP()->time_m); time_slip = RP()->time_slip; - ossl_crypto_mutex_unlock(RP()->gm); + ossl_crypto_mutex_unlock(RP()->time_m); - return ossl_time_add(ossl_time_now(), time_slip); + return ossl_time_add(RP()->base_time, time_slip); } -ossl_unused static void radix_skip_time(OSSL_TIME t) +static OSSL_TIME terp_now(void *arg) { - ossl_crypto_mutex_lock(RP()->gm); + return ossl_time_now(); +} + +static void radix_skip_time(OSSL_TIME t) +{ + ossl_crypto_mutex_lock(RP()->time_m); RP()->time_slip = ossl_time_add(RP()->time_slip, t); - ossl_crypto_mutex_unlock(RP()->gm); + ossl_crypto_mutex_unlock(RP()->time_m); } static void per_op_tick_obj(RADIX_OBJ *obj) { ossl_crypto_mutex_lock(obj->mx); - if (obj->active && obj->ssl) + if (obj->active && obj->ssl != NULL) SSL_handle_events(obj->ssl); ossl_crypto_mutex_unlock(obj->mx); } static int do_per_op(TERP *terp, void *arg) { + radix_skip_time(ossl_ms2time(1)); lh_RADIX_OBJ_doall(RP()->objs, per_op_tick_obj); return 1; } static int bindings_adjust_terp_config(TERP_CONFIG *cfg) { - cfg->now_cb = get_time; + cfg->now_cb = terp_now; cfg->per_op_cb = do_per_op; + + cfg->max_execution_time = ossl_ms2time(60000); return 1; } @@ -871,8 +893,6 @@ DEF_FUNC(hf_clear) RADIX_THREAD *rt = RT(); size_t i; - ossl_crypto_mutex_lock(RP()->gm); - lh_RADIX_OBJ_doall(RP()->objs, cleanup_one); lh_RADIX_OBJ_flush(RP()->objs); @@ -881,7 +901,6 @@ DEF_FUNC(hf_clear) rt->ssl[i] = NULL; } - ossl_crypto_mutex_unlock(RP()->gm); return 1; } diff --git a/test/radix/quic_ops.c b/test/radix/quic_ops.c index 902dab4aed9e6..b4bd59e9ecae1 100644 --- a/test/radix/quic_ops.c +++ b/test/radix/quic_ops.c @@ -1,5 +1,5 @@ /* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ #include "internal/sockets.h" +#include "internal/statem.h" #include static const unsigned char alpn_ossltest[] = { @@ -29,20 +30,21 @@ DEF_FUNC(hf_unbind) DEF_FUNC(hf_bind) { + int ok = 0; const char *name; RADIX_OBJ *empty_obj; F_POP(name); - empty_obj = RADIX_OBJ_new_empty(name); - if (empty_obj == NULL) - return 0; - - RADIX_PROCESS_set_obj(RP(), name, empty_obj); + if (!TEST_ptr(empty_obj = RADIX_OBJ_new_empty(name)) + || !TEST_true(RADIX_PROCESS_set_obj(RP(), name, empty_obj))) { + RADIX_OBJ_free(empty_obj); + goto err; + } - return 1; + ok = 1; err: - return 0; + return ok; } static int ssl_ctx_select_alpn(SSL *ssl, @@ -137,6 +139,18 @@ static int ssl_create_bound_socket(uint16_t listen_port, return ok; } +/* Attaches bio as both rbio and wbio, consuming the caller's reference. */ +static int ssl_attach_bio(SSL *ssl, BIO *bio) +{ + SSL_set0_rbio(ssl, bio); + if (!TEST_true(BIO_up_ref(bio))) + return 0; + + SSL_set0_wbio(ssl, bio); + + return 1; +} + static int ssl_attach_bio_dgram(SSL *ssl, uint16_t local_port, uint16_t *actual_port) { @@ -151,13 +165,7 @@ static int ssl_attach_bio_dgram(SSL *ssl, return 0; } - SSL_set0_rbio(ssl, bio); - if (!TEST_true(BIO_up_ref(bio))) - return 0; - - SSL_set0_wbio(ssl, bio); - - return 1; + return ssl_attach_bio(ssl, bio); } DEF_FUNC(hf_new_ssl) @@ -168,22 +176,51 @@ DEF_FUNC(hf_new_ssl) const SSL_METHOD *method; SSL *ssl; uint64_t flags; - int is_server, is_domain; + int is_server, is_domain, is_ta, is_no_bio; F_POP2(name, flags); is_domain = ((flags & 2) != 0); is_server = ((flags & 1) != 0); + is_ta = ((flags & 4) != 0); + is_no_bio = ((flags & 8) != 0); + + if (is_server) + method = OSSL_QUIC_server_method(); + else if (is_ta) + method = OSSL_QUIC_client_thread_method(); + else + method = OSSL_QUIC_client_method(); - method = is_server ? OSSL_QUIC_server_method() : OSSL_QUIC_client_method(); if (!TEST_ptr(ctx = SSL_CTX_new(method))) goto err; +#if defined(OPENSSL_NO_QUIC_THREAD_ASSIST) || !defined(OPENSSL_THREADS) + if (is_ta) { + TEST_skip("thread assisted mode not available"); + F_SKIP_REST(); + } +#endif + #if defined(OPENSSL_THREADS) - if (!TEST_true(SSL_CTX_set_domain_flags(ctx, - SSL_DOMAIN_FLAG_MULTI_THREAD - | SSL_DOMAIN_FLAG_BLOCKING))) + if (is_ta) { + uint64_t domain_flags = 0; + + /* + * Rely on the OSSL_QUIC_client_thread_method() domain flag defaults + * rather than setting them so the method's defaulting stays covered. + */ + if (!TEST_true(SSL_CTX_get_domain_flags(ctx, &domain_flags)) + || !TEST_uint64_t_eq(domain_flags, + SSL_DOMAIN_FLAG_MULTI_THREAD + | SSL_DOMAIN_FLAG_THREAD_ASSISTED + | SSL_DOMAIN_FLAG_BLOCKING)) + goto err; + } else if (!TEST_true(SSL_CTX_set_domain_flags(ctx, + SSL_DOMAIN_FLAG_MULTI_THREAD + | SSL_DOMAIN_FLAG_BLOCKING))) { goto err; + } #endif if (!TEST_true(ssl_ctx_configure(ctx, is_server))) @@ -201,9 +238,15 @@ DEF_FUNC(hf_new_ssl) goto err; } - if (!is_domain && !TEST_true(ssl_attach_bio_dgram(ssl, 0, NULL))) + if (!is_domain && !is_no_bio + && !TEST_true(ssl_attach_bio_dgram(ssl, 0, NULL))) goto err; + if (!TEST_true(ossl_quic_set_override_now_cb(ssl, get_time, NULL))) { + SSL_free(ssl); + goto err; + } + if (!TEST_true(RADIX_PROCESS_set_ssl(RP(), name, ssl))) { SSL_free(ssl); goto err; @@ -287,8 +330,9 @@ DEF_FUNC(hf_new_stream) if (replace == 0) { if (!TEST_ptr_null(stream_obj)) goto err; - } else if (TEST_ptr_null(stream_obj)) + } else if (TEST_ptr_null(stream_obj)) { goto err; + } if (do_accept) { stream = SSL_accept_stream(conn, flags & OP_F_MASK); @@ -342,6 +386,7 @@ DEF_FUNC(hf_accept_conn) SSL_free(conn); goto err; } + radix_activate_obj(RADIX_PROCESS_get_obj(RP(), conn_name)); ok = 1; err: @@ -684,11 +729,19 @@ DEF_FUNC(hf_read_fail) return ok; } +/* + * If tolerate_failure is set, tolerates the connection attempt itself failing + * (rather than the connection later closing after a successful handshake), + * for scripts where fault injection is expected to prevent the handshake + * from completing at all. + */ DEF_FUNC(hf_connect_wait) { int ok = 0, ret; SSL *ssl; + uint64_t tolerate_failure; + F_POP(tolerate_failure); REQUIRE_SSL(ssl); /* if not started */ @@ -712,7 +765,7 @@ DEF_FUNC(hf_connect_wait) if (is_want(ssl, ret)) F_SPIN_AGAIN(); - if (!TEST_int_eq(ret, 1)) + if (!tolerate_failure && !TEST_int_eq(ret, 1)) goto err; } @@ -903,6 +956,62 @@ DEF_FUNC(hf_skip_time) return ok; } +/* + * Link a client and a listener with an in-memory datagram BIO pair. Fake-time + * tests need this: a datagram sitting in the OS UDP path while fake time skips + * ahead could arrive only after a deadline it preceded in fake time. + */ +DEF_FUNC(hf_link_dgram_pair) +{ + int ok = 0; + SSL *c_ssl, *l_ssl; + BIO *c_bio = NULL, *l_bio = NULL; + BIO_ADDR *addr = NULL; + struct in_addr ina; + + REQUIRE_SSL_2(c_ssl, l_ssl); + + if (!TEST_true(BIO_new_bio_dgram_pair(&c_bio, 0, &l_bio, 0))) + goto err; + + if (!TEST_true(BIO_dgram_set_caps(c_bio, BIO_DGRAM_CAP_HANDLES_DST_ADDR)) + || !TEST_true(BIO_dgram_set_caps(l_bio, + BIO_DGRAM_CAP_HANDLES_DST_ADDR))) + goto err; + + ina.s_addr = htonl(INADDR_LOOPBACK); + if (!TEST_ptr(addr = BIO_ADDR_new()) + || !TEST_true(BIO_ADDR_rawmake(addr, AF_INET, &ina, sizeof(ina), 0))) + goto err; + + /* There are no real ports; a stable dummy address is all that is needed. */ + if (!TEST_true(SSL_set1_initial_peer_addr(c_ssl, addr))) + goto err; + + if (!TEST_true(BIO_dgram_set0_local_addr(c_bio, addr))) + goto err; + addr = NULL; + + if (!ssl_attach_bio(c_ssl, c_bio)) { + c_bio = NULL; + goto err; + } + c_bio = NULL; + + if (!ssl_attach_bio(l_ssl, l_bio)) { + l_bio = NULL; + goto err; + } + l_bio = NULL; + + ok = 1; +err: + BIO_free(c_bio); + BIO_free(l_bio); + BIO_ADDR_free(addr); + return ok; +} + DEF_FUNC(hf_set_peer_addr_from) { int ok = 0; @@ -958,6 +1067,587 @@ DEF_FUNC(hf_sleep) return ok; } +DEF_FUNC(hf_set_tick_active) +{ + int ok = 0; + uint64_t active; + const char *name; + RADIX_OBJ *obj; + + F_POP2(name, active); + if (!TEST_ptr(obj = RADIX_PROCESS_get_obj(RP(), name))) + goto err; + + obj->active = (active != 0); + ok = 1; +err: + return ok; +} + +/* Inhibit ticking at the QUIC_ENGINE level */ +DEF_FUNC(hf_set_engine_tick_inhibit) +{ + int ok = 0; + uint64_t inhibit; + SSL *ssl; + QUIC_CHANNEL *ch; + + F_POP(inhibit); + REQUIRE_SSL(ssl); + + if (!TEST_ptr(ch = ossl_quic_conn_get_channel(ssl))) + goto err; + + ossl_quic_engine_set_inhibit_tick(ossl_quic_channel_get0_engine(ch), + inhibit != 0); + ok = 1; +err: + return ok; +} + +/* + * Skip fake time and wait for the assist thread to catch up. It waits on real + * time internally, so wake it and spin until the event timeout is back in the + * future, meaning everything due up to now (any keepalive) has been serviced. + */ +DEF_FUNC(hf_skip_time_wait) +{ + int ok = 0; + uint64_t ms; + SSL *ssl; + struct timeval tv; + int is_infinite; + + REQUIRE_SSL(ssl); + F_POP(ms); + + if (RT()->scratch0 == 0) { + /* Skip only once; spin re-entries pass through here. */ + radix_skip_time(ossl_ms2time(ms)); + RT()->scratch0 = 1; + } + + ossl_quic_conn_force_assist_thread_wake(ssl); + + if (!TEST_true(SSL_get_event_timeout(ssl, &tv, &is_infinite))) + goto err; + + /* {0,0} (subtract saturates) means an event is still pending. */ + if (!is_infinite && tv.tv_sec == 0 && tv.tv_usec == 0) { + OSSL_sleep(1); /* Yield so the assist thread can run. */ + F_SPIN_AGAIN(); + } + + RT()->scratch0 = 0; /* done; not reset at err, as spins pass through it */ + ok = 1; +err: + return ok; +} + +DEF_FUNC(hf_expect_connected) +{ + int ok = 0; + SSL *ssl; + QUIC_CHANNEL *ch; + + REQUIRE_SSL(ssl); + if (!TEST_ptr(ch = ossl_quic_conn_get_channel(ssl))) + goto err; + + if (!TEST_true(ossl_quic_channel_is_active(ch))) + goto err; + + ok = 1; +err: + return ok; +} + +DEF_FUNC(hf_override_key_update) +{ + int ok = 0; + SSL *ssl; + uint64_t threshold; + QUIC_CHANNEL *ch; + + F_POP(threshold); + REQUIRE_SSL(ssl); + ch = ossl_quic_conn_get_channel(ssl); + ossl_quic_channel_set_txku_threshold_override(ch, threshold); + ok = 1; +err: + return ok; +} + +DEF_FUNC(hf_check_key_update_ge) +{ + int ok = 0; + SSL *ssl; + uint64_t min_rxke, txke, rxke; + int64_t diff; + QUIC_CHANNEL *ch; + + F_POP(min_rxke); + REQUIRE_SSL(ssl); + ch = ossl_quic_conn_get_channel(ssl); + txke = ossl_quic_channel_get_tx_key_epoch(ch); + rxke = ossl_quic_channel_get_rx_key_epoch(ch); + diff = (int64_t)txke - (int64_t)rxke; + + /* + * TXKE must always be equal to or ahead of RXKE. + * It can be ahead of RXKE by at most 1. + */ + if (!TEST_int64_t_ge(diff, 0) || !TEST_int64_t_le(diff, 1)) + goto err; + + /* Caller specifies a minimum number of RXKEs which must have happened. */ + if (!TEST_uint64_t_ge(rxke, min_rxke)) + goto err; + + ok = 1; +err: + return ok; +} + +DEF_FUNC(hf_check_key_update_lt) +{ + int ok = 0; + SSL *ssl; + uint64_t max_txke, txke; + QUIC_CHANNEL *ch; + + F_POP(max_txke); + REQUIRE_SSL(ssl); + ch = ossl_quic_conn_get_channel(ssl); + txke = ossl_quic_channel_get_tx_key_epoch(ch); + + /* Caller specifies a maximum number of TXKEs which must not be exceeded. */ + if (!TEST_uint64_t_lt(txke, max_txke)) + goto err; + + ok = 1; +err: + return ok; +} + +DEF_FUNC(hf_trigger_key_update) +{ + int ok = 0; + SSL *ssl; + uint64_t update_type; + + F_POP(update_type); + REQUIRE_SSL(ssl); + + if (!TEST_true(SSL_key_update(ssl, (int)update_type))) + goto err; + + ok = 1; +err: + return ok; +} + +DEF_FUNC(hf_close_socket) +{ + int ok = 0; + SSL *ssl; + BIO *bio; + int fd = -1; + + REQUIRE_SSL(ssl); + + bio = SSL_get_rbio(ssl); + if (!TEST_ptr(bio) || !TEST_true(BIO_get_fd(bio, &fd)) || !TEST_int_ge(fd, 0)) + goto err; + + BIO_closesocket(fd); + + ok = 1; +err: + return ok; +} + +/* Process-global counters (RP()->counter[idx]), used for cross-thread sync. */ +DEF_FUNC(hf_trigger_counter) +{ + int ok = 0; + uint64_t idx; + + F_POP(idx); + + ossl_crypto_mutex_lock(RP()->gm); + ++RP()->counter[idx]; + ossl_crypto_mutex_unlock(RP()->gm); + + ok = 1; +err: + return ok; +} + +DEF_FUNC(hf_wait_counter) +{ + int ok = 0; + uint64_t idx, threshold, current; + + F_POP2(idx, threshold); + + ossl_crypto_mutex_lock(RP()->gm); + current = RP()->counter[idx]; + ossl_crypto_mutex_unlock(RP()->gm); + + if (current < threshold) + F_SPIN_AGAIN(); + + ok = 1; +err: + return ok; +} + +/* + * Fault injection: intercepts a QUIC channel's outgoing packet in plaintext, + * before it is encrypted, so a script can tamper with its frames. + */ +typedef struct radix_fault_st RADIX_FAULT; + +typedef int (*radix_fault_plain_cb)(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len); + +static ossl_inline void *radix_fault_plain_cb_to_ptr(radix_fault_plain_cb cb) +{ + union { + radix_fault_plain_cb cb; + void *ptr; + } u; + + u.cb = cb; + return u.ptr; +} + +static ossl_inline radix_fault_plain_cb radix_fault_ptr_to_plain_cb(void *ptr) +{ + union { + radix_fault_plain_cb cb; + void *ptr; + } u; + + u.ptr = ptr; + return u.cb; +} + +/* + * Handshake (crypto stream) message mutator, used to tamper with a QUIC + * connection's outgoing TLS handshake messages before they are queued for + * transmission. + */ +typedef int (*radix_fault_handshake_cb)(RADIX_FAULT *fault, + unsigned char *buf, size_t len); + +static ossl_inline void * +radix_fault_handshake_cb_to_ptr(radix_fault_handshake_cb cb) +{ + union { + radix_fault_handshake_cb cb; + void *ptr; + } u; + + u.cb = cb; + return u.ptr; +} + +static ossl_inline radix_fault_handshake_cb +radix_fault_ptr_to_handshake_cb(void *ptr) +{ + union { + radix_fault_handshake_cb cb; + void *ptr; + } u; + + u.ptr = ptr; + return u.cb; +} + +struct radix_fault_st { + QUIC_PKT_HDR hdr; + OSSL_QTX_IOVEC io; + size_t buf_alloc; + radix_fault_plain_cb cb; + QUIC_CHANNEL *ch; + uint64_t word0, word1; + /* Handshake message mutator state. */ + unsigned char *handbuf; + size_t handbuflen; + radix_fault_handshake_cb hcb; +}; + +/* Fault injection against one channel at a time. */ +static RADIX_FAULT radix_fault; + +static int radix_fault_mutate(const QUIC_PKT_HDR *hdrin, + const OSSL_QTX_IOVEC *iovecin, size_t numin, + QUIC_PKT_HDR **hdrout, + const OSSL_QTX_IOVEC **iovecout, + size_t *numout, + void *arg) +{ + RADIX_FAULT *fault = arg; + size_t i, bufsz = 0; + unsigned char *cur; + int grow_allowance; + + for (i = 0; i < numin; i++) + bufsz += iovecin[i].buf_len; + + fault->io.buf_len = bufsz; + + /* + * 1200 is the length of the QUIC payload used by the record layer, bufsz is + * what we got from the txp, 16 is the AEAD tag length and 14 is the + * long header allowance (assume zero token length). + */ + grow_allowance = 1200 - (int)bufsz - 16 - 14; + grow_allowance -= hdrin->dst_conn_id.id_len; + grow_allowance -= hdrin->src_conn_id.id_len; + if (!TEST_int_ge(grow_allowance, 0)) + return 0; + bufsz += grow_allowance; + + OPENSSL_free((unsigned char *)fault->io.buf); + fault->io.buf = cur = OPENSSL_malloc(bufsz); + if (cur == NULL) { + fault->io.buf_len = 0; + fault->buf_alloc = 0; + return 0; + } + fault->buf_alloc = bufsz; + + for (i = 0; i < numin; i++) { + memcpy(cur, iovecin[i].buf, iovecin[i].buf_len); + cur += iovecin[i].buf_len; + } + + fault->hdr = *hdrin; + + if (fault->cb != NULL + && !fault->cb(fault, &fault->hdr, (unsigned char *)fault->io.buf, + fault->io.buf_len)) + return 0; + + *hdrout = &fault->hdr; + *iovecout = &fault->io; + *numout = 1; + + return 1; +} + +static void radix_fault_finish(void *arg) +{ + RADIX_FAULT *fault = arg; + + OPENSSL_free((unsigned char *)fault->io.buf); + fault->io.buf = NULL; + fault->io.buf_len = 0; + fault->buf_alloc = 0; +} + +/* To be called from a radix_fault_plain_cb callback. */ +static int radix_fault_resize_plain_packet(RADIX_FAULT *fault, size_t newlen) +{ + unsigned char *buf; + size_t oldlen = fault->io.buf_len; + + if (fault->buf_alloc == 0 || newlen > fault->buf_alloc) + return 0; + + buf = (unsigned char *)fault->io.buf; + + if (newlen > oldlen) + memset(buf + oldlen, 0, newlen - oldlen); + + fault->io.buf_len = newlen; + fault->hdr.len = newlen; + + return 1; +} + +/* + * Prepend frame data into a packet. To be called from a + * radix_fault_plain_cb callback. + */ +static int radix_fault_prepend_frame(RADIX_FAULT *fault, + const unsigned char *frame, size_t frame_len) +{ + unsigned char *buf; + size_t old_len; + + if (fault->buf_alloc == 0) + return 0; + + /* Cast below is safe because we allocated the buffer. */ + buf = (unsigned char *)fault->io.buf; + old_len = fault->io.buf_len; + + if (!radix_fault_resize_plain_packet(fault, old_len + frame_len)) + return 0; + + memmove(buf + frame_len, buf, old_len); + memcpy(buf, frame, frame_len); + + return 1; +} + +DEF_FUNC(hf_set_inject_plain) +{ + int ok = 0; + SSL *ssl; + void *cbptr; + QUIC_CHANNEL *ch; + + F_POP(cbptr); + REQUIRE_SSL(ssl); + + if (!TEST_ptr(ch = ossl_quic_conn_get_channel(ssl))) + goto err; + + OPENSSL_free((unsigned char *)radix_fault.io.buf); + memset(&radix_fault, 0, sizeof(radix_fault)); + radix_fault.cb = radix_fault_ptr_to_plain_cb(cbptr); + radix_fault.ch = ch; + + if (!TEST_true(ossl_quic_channel_set_mutator(ch, radix_fault_mutate, + radix_fault_finish, &radix_fault))) + goto err; + + ok = 1; +err: + return ok; +} + +DEF_FUNC(hf_set_inject_word) +{ + int ok = 0; + + F_POP2(radix_fault.word0, radix_fault.word1); + + ok = 1; +err: + return ok; +} + +/* + * ossl_statem_mutate_handshake_cb: intercepts an outgoing TLS handshake + * message on the crypto stream before it is queued for transmission. + */ +static int radix_fault_handshake_mutate(const unsigned char *msgin, + size_t msginlen, + unsigned char **msgout, + size_t *msgoutlen, + void *arg) +{ + RADIX_FAULT *fault = arg; + unsigned char *buf; + + buf = OPENSSL_malloc(msginlen); + if (buf == NULL) + return 0; + + OPENSSL_free(fault->handbuf); + fault->handbuf = buf; + fault->handbuflen = msginlen; + memcpy(buf, msgin, msginlen); + + if (fault->hcb != NULL && !fault->hcb(fault, buf, fault->handbuflen)) + return 0; + + *msgout = buf; + *msgoutlen = fault->handbuflen; + + return 1; +} + +static void radix_fault_handshake_finish(void *arg) +{ + RADIX_FAULT *fault = arg; + + OPENSSL_free(fault->handbuf); + fault->handbuf = NULL; +} + +/* + * Arms the handshake mutator callback without attaching it to any + * connection yet. Used by scripts that need to intercept a server's very + * first handshake flight: the corresponding connection does not exist until + * a client's Initial packet is accepted, by which point that first flight + * has typically already been generated, so the mutator must instead be + * installed from a SSL_CTX client_hello callback (see script_54 for an + * example) armed with this callback beforehand. + */ +DEF_FUNC(hf_set_inject_handshake_cb) +{ + int ok = 0; + void *cbptr; + + F_POP(cbptr); + + OPENSSL_free(radix_fault.handbuf); + radix_fault.handbuf = NULL; + radix_fault.handbuflen = 0; + radix_fault.hcb = radix_fault_ptr_to_handshake_cb(cbptr); + + ok = 1; +err: + return ok; +} + +DEF_FUNC(hf_push_stream_id_plus_one) +{ + int ok = 0; + SSL *ssl; + uint64_t stream_id_plus_one; + + REQUIRE_SSL(ssl); + stream_id_plus_one = SSL_get_stream_id(ssl) + 1; + F_PUSH(stream_id_plus_one); + ok = 1; +err: + return ok; +} + +DEF_FUNC(hf_inhibit_tick) +{ + int ok = 0; + uint64_t inhibit; + SSL *ssl; + QUIC_CHANNEL *ch; + + F_POP(inhibit); + REQUIRE_SSL(ssl); + + ch = ossl_quic_conn_get_channel(ssl); + ossl_quic_engine_set_inhibit_tick(ossl_quic_channel_get0_engine(ch), + (int)inhibit); + + ok = 1; +err: + return ok; +} + +DEF_FUNC(hf_set_write_buf_size) +{ + int ok = 0; + size_t size; + SSL *ssl; + + F_POP(size); + REQUIRE_SSL(ssl); + + if (!TEST_true(ossl_quic_set_write_buffer_size(ssl, size))) + goto err; + + ok = 1; +err: + return ok; +} + #define OP_UNBIND(name) \ (OP_PUSH_PZ(#name), \ OP_FUNC(hf_unbind)) @@ -977,6 +1667,12 @@ DEF_FUNC(hf_sleep) #define OP_CONNECT_WAIT(name) \ (OP_SELECT_SSL(0, name), \ + OP_PUSH_U64(0), \ + OP_FUNC(hf_connect_wait)) + +#define OP_CONNECT_WAIT_OR_FAIL(name) \ + (OP_SELECT_SSL(0, name), \ + OP_PUSH_U64(1), \ OP_FUNC(hf_connect_wait)) #define OP_LISTEN(name) \ @@ -1184,3 +1880,114 @@ DEF_FUNC(hf_sleep) #define OP_SLEEP(ms) \ (OP_PUSH_U64(ms), \ OP_FUNC(hf_sleep)) + +/* Thread-assisted client, no socket (link a BIO pair instead). */ +#define OP_NEW_SSL_C_TA_MEM(name) \ + (OP_PUSH_PZ(#name), \ + OP_PUSH_U64(4 | 8), \ + OP_FUNC(hf_new_ssl)) + +/* Listener, no socket (link a BIO pair instead). */ +#define OP_NEW_SSL_L_MEM(name) \ + (OP_PUSH_PZ(#name), \ + OP_PUSH_U64(1 | 8), \ + OP_FUNC(hf_new_ssl)) + +#define OP_LINK_DGRAM_PAIR(client_name, listener_name) \ + (OP_SELECT_SSL(0, client_name), \ + OP_SELECT_SSL(1, listener_name), \ + OP_FUNC(hf_link_dgram_pair)) + +#define OP_TICK_DISABLE(name) \ + (OP_PUSH_PZ(#name), \ + OP_PUSH_U64(0), \ + OP_FUNC(hf_set_tick_active)) + +#define OP_TICK_ENABLE(name) \ + (OP_PUSH_PZ(#name), \ + OP_PUSH_U64(1), \ + OP_FUNC(hf_set_tick_active)) + +/* + * Inhibits/uninhibits ticking of the QUIC_ENGINE that "name" belongs (see + * see hf_set_engine_tick_inhibit). + */ +#define OP_ENGINE_TICK_DISABLE(name) \ + (OP_SELECT_SSL(0, name), \ + OP_PUSH_U64(1), \ + OP_FUNC(hf_set_engine_tick_inhibit)) + +#define OP_ENGINE_TICK_ENABLE(name) \ + (OP_SELECT_SSL(0, name), \ + OP_PUSH_U64(0), \ + OP_FUNC(hf_set_engine_tick_inhibit)) + +#define OP_SKIP_TIME_WAIT(name, ms) \ + (OP_SELECT_SSL(0, name), \ + OP_PUSH_U64(ms), \ + OP_FUNC(hf_skip_time_wait)) + +#define OP_EXPECT_CONNECTED(name) \ + (OP_SELECT_SSL(0, name), \ + OP_FUNC(hf_expect_connected)) + +#define OP_OVERRIDE_KEY_UPDATE(name, threshold) \ + (OP_SELECT_SSL(0, name), \ + OP_PUSH_U64(threshold), \ + OP_FUNC(hf_override_key_update)) + +#define OP_CHECK_KEY_UPDATE_GE(name, min_rxke) \ + (OP_SELECT_SSL(0, name), \ + OP_PUSH_U64(min_rxke), \ + OP_FUNC(hf_check_key_update_ge)) + +#define OP_CHECK_KEY_UPDATE_LT(name, max_txke) \ + (OP_SELECT_SSL(0, name), \ + OP_PUSH_U64(max_txke), \ + OP_FUNC(hf_check_key_update_lt)) + +#define OP_TRIGGER_KEY_UPDATE(name, update_type) \ + (OP_SELECT_SSL(0, name), \ + OP_PUSH_U64(update_type), \ + OP_FUNC(hf_trigger_key_update)) + +#define OP_CLOSE_SOCKET(name) \ + (OP_SELECT_SSL(0, name), \ + OP_FUNC(hf_close_socket)) + +#define OP_TRIGGER_COUNTER(idx) \ + (OP_PUSH_U64(idx), \ + OP_FUNC(hf_trigger_counter)) + +#define OP_WAIT_COUNTER(idx, threshold) \ + (OP_PUSH_U64(idx), \ + OP_PUSH_U64(threshold), \ + OP_FUNC(hf_wait_counter)) + +#define OP_SET_INJECT_PLAIN(name, cb) \ + (OP_SELECT_SSL(0, name), \ + OP_PUSH_P(radix_fault_plain_cb_to_ptr(cb)), \ + OP_FUNC(hf_set_inject_plain)) + +#define OP_SET_INJECT_WORD(word0, word1) \ + (OP_PUSH_U64(word0), \ + OP_PUSH_U64(word1), \ + OP_FUNC(hf_set_inject_word)) + +#define OP_SET_INJECT_HANDSHAKE_CB(cb) \ + (OP_PUSH_P(radix_fault_handshake_cb_to_ptr(cb)), \ + OP_FUNC(hf_set_inject_handshake_cb)) + +#define OP_PUSH_STREAM_ID_PLUS_ONE(name) \ + (OP_SELECT_SSL(0, name), \ + OP_FUNC(hf_push_stream_id_plus_one)) + +#define OP_INHIBIT_TICK(name, inhibit) \ + (OP_SELECT_SSL(0, name), \ + OP_PUSH_U64(inhibit), \ + OP_FUNC(hf_inhibit_tick)) + +#define OP_SET_WRITE_BUF_SIZE(name, size) \ + (OP_SELECT_SSL(0, name), \ + OP_PUSH_SIZE(size), \ + OP_FUNC(hf_set_write_buf_size)) diff --git a/test/radix/quic_tests.c b/test/radix/quic_tests.c index 3047ef08a1219..848e46004dd52 100644 --- a/test/radix/quic_tests.c +++ b/test/radix/quic_tests.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -8,6 +8,8 @@ */ #include "internal/quic_stream_map.h" +#include "internal/quic_reactor.h" +#include "../../ssl/rio/poll_builder.h" #if defined(_AIX) /* @@ -52,6 +54,21 @@ DEF_FUNC(check_rejected) return ok; } +DEF_FUNC(check_want_read) +{ + int ok = 0; + SSL *ssl; + + REQUIRE_SSL(ssl); + if (!TEST_int_eq(SSL_get_error(ssl, 0), SSL_ERROR_WANT_READ) + || !TEST_int_eq(SSL_want(ssl), SSL_READING)) + goto err; + + ok = 1; +err: + return ok; +} + /* * Multi-stream test */ @@ -146,6 +163,20 @@ DEF_SCRIPT(multi_stream, "multi stream test") OP_FUNC(check_rejected); } +/* + * Reject an incoming stream before a default stream has been established. + */ +DEF_SCRIPT(reject_before_default_stream, "reject before default stream") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + OP_SET_INCOMING_STREAM_POLICY(C, SSL_INCOMING_STREAM_POLICY_REJECT, 42); + OP_WRITE_B(S, "unseen"); + OP_SLEEP(100); + OP_READ_FAIL(C); + OP_FUNC(check_want_read); +} + /* * Simple single-stream test */ @@ -383,6 +414,178 @@ DEF_SCRIPT(ssl_poll, } } +/* + * Test: poll_abort_blocking + * ------------------------- + * + * SSL_poll(), when it has to block, registers each item's QUIC connection + * for cross-thread notification one item at a time (poll_translate() in + * ssl/rio/poll_immediate.c). If an item turns out to already be ready right + * as it is being registered, translation is aborted so the readout loop can + * retry instead of actually blocking. This exercises that abort path and + * checks that: + * + * - SSL_poll() reports success rather than spuriously failing, and + * - any items already registered before the abort have their blocking + * section correctly left (i.e. no leak in the QUIC reactor's blocking + * waiter count). + * + * The race between an item being registered and becoming ready is normally + * vanishingly narrow, so we use ossl_quic_poll_translate_test_step_cb (test + * instrumentation only, see ssl/rio/poll_builder.h) to deterministically + * make the second item ready immediately before poll_translate() processes + * it, while the first item is still mid-registration. + */ +struct poll_abort_test_ctx { + SSL *peer_writer; /* write here to make target ready */ + SSL *target; + uint64_t target_events; + size_t trigger_idx; + int made_ready; /* set by poll_abort_test_step_cb() on success */ +}; + +static void poll_abort_test_step_cb(size_t idx, void *arg) +{ + struct poll_abort_test_ctx *ctx = arg; + uint64_t revents = 0; + int i; + + if (idx != ctx->trigger_idx) + return; + + if (SSL_write(ctx->peer_writer, "x", 1) != 1) + return; + + /* Force the data through synchronously so target is ready by the time we return. */ + for (i = 0; i < 1000; ++i) { + if (!ossl_quic_conn_poll_events(ctx->target, ctx->target_events, + /* do_tick = */ 1, &revents)) + return; + + if (revents != 0) { + ctx->made_ready = 1; + return; + } + + OSSL_sleep(1); + } +} + +DEF_FUNC(check_poll_abort_blocking) +{ + int ok = 0; + SSL *C, *C0, *Cb0, *Lb0; + QUIC_CHANNEL *ch0; + QUIC_REACTOR *rtor0; + SSL_POLL_ITEM items[2] = { 0 }; + size_t result_count = SIZE_MAX, waiters_before, waiters_after; + struct poll_abort_test_ctx ctx; + const struct timeval z_timeout = { 0 }; + + /* + * C0 and Cb0 are streams of two independent client connections, and so + * belong to two independent QUIC_REACTORs. The bug being tested for does + * not actually require this: it reproduces just as well if all items + * share one reactor. What needs two reactors is poll_abort_test_step_cb() + * below, which forces Cb0 ready by ticking its reactor directly, on this + * thread, while C0's blocking section is still open. Doing that on C0's + * own (shared) reactor would deadlock: ossl_quic_reactor_tick() would see + * a nonzero cur_blocking_waiters left over from C0 and call + * rtor_notify_other_threads(), which waits on a condvar for some *other* + * thread to clear the notifier signal - a thread that doesn't exist here. + * Using Cb0's own, still-untouched reactor keeps that tick a no-op. + */ + REQUIRE_SSL_4(C, C0, Cb0, Lb0); + + items[0].desc = SSL_as_poll_descriptor(C0); + items[0].events = SSL_POLL_EVENT_R; + items[1].desc = SSL_as_poll_descriptor(Cb0); + items[1].events = SSL_POLL_EVENT_R; + + /* Sanity check: nothing ready yet, so SSL_poll() will need to block. */ + if (!TEST_true(SSL_poll(items, OSSL_NELEM(items), sizeof(SSL_POLL_ITEM), + &z_timeout, 0, &result_count)) + || !TEST_size_t_eq(result_count, 0)) + goto err; + + if (!TEST_ptr(ch0 = ossl_quic_conn_get_channel(C))) + goto err; + rtor0 = ossl_quic_channel_get_reactor(ch0); + waiters_before = rtor0->cur_blocking_waiters; + + ctx.peer_writer = Lb0; + ctx.target = Cb0; + ctx.target_events = items[1].events; + ctx.trigger_idx = 1; + ctx.made_ready = 0; + + ossl_quic_poll_translate_test_step_cb_arg = &ctx; + ossl_quic_poll_translate_test_step_cb = poll_abort_test_step_cb; + + result_count = SIZE_MAX; + /* + * No timeout: if the abort_blocking case were instead to actually block, + * this call would hang forever rather than fail fast. + */ + ok = TEST_true(SSL_poll(items, OSSL_NELEM(items), sizeof(SSL_POLL_ITEM), + NULL, 0, &result_count)); + + ossl_quic_poll_translate_test_step_cb = NULL; + ossl_quic_poll_translate_test_step_cb_arg = NULL; + + if (!ok) + goto err; + + ok = 0; + if (!TEST_true(ctx.made_ready) + || !TEST_size_t_ge(result_count, 1) + || !TEST_true((items[1].revents & SSL_POLL_EVENT_R) != 0)) + goto err; + + /* The first item's blocking-section entry must have been balanced. */ + waiters_after = rtor0->cur_blocking_waiters; + if (!TEST_size_t_eq(waiters_after, waiters_before)) + goto err; + + ok = 1; +err: + ossl_quic_poll_translate_test_step_cb = NULL; + ossl_quic_poll_translate_test_step_cb_arg = NULL; + return ok; +} + +DEF_SCRIPT(poll_abort_blocking, + "test that SSL_poll() correctly handles an item becoming ready while blocking is being set up") +{ + OP_SIMPLE_PAIR_CONN_ND(); + + OP_NEW_STREAM(C, C0, 0); + OP_WRITE_B(C0, "probe0"); + + OP_ACCEPT_CONN_WAIT1_ND(L, La, 0); + OP_ACCEPT_STREAM_WAIT(La, La0, 0); + OP_READ_EXPECT_B(La0, "probe0"); + + /* A second, independent client connection to the same listener. */ + OP_NEW_SSL_C(Cb); + OP_SET_PEER_ADDR_FROM(Cb, L); + OP_CONNECT_WAIT(Cb); + OP_SET_DEFAULT_STREAM_MODE(Cb, SSL_DEFAULT_STREAM_MODE_NONE); + + OP_NEW_STREAM(Cb, Cb0, 0); + OP_WRITE_B(Cb0, "probe1"); + + OP_ACCEPT_CONN_WAIT1_ND(L, Lb, 0); + OP_ACCEPT_STREAM_WAIT(Lb, Lb0, 0); + OP_READ_EXPECT_B(Lb0, "probe1"); + + OP_SELECT_SSL(0, C); + OP_SELECT_SSL(1, C0); + OP_SELECT_SSL(2, Cb0); + OP_SELECT_SSL(3, Lb0); + OP_FUNC(check_poll_abort_blocking); +} + DEF_FUNC(check_writeable) { int ok = 0; @@ -456,10 +659,23 @@ static int mutcbk_inject_frames(const QUIC_PKT_HDR *hdrin, /* * make injection callback a one shot event, * callback is invoked for every packet we - * want to modify only one packet here. + * want to modify only one packet here. Returning 0 tells the QTX the + * packet send itself failed (tearing down the connection), so once + * we're done mutating we must pass subsequent packets through + * unmodified instead. + * + * PATH_CHALLENGE is only valid in 0-RTT and 1-RTT packets. The client can + * still send a Handshake packet after SSL_connect() returns, e.g. a PTO + * probe while HANDSHAKE_DONE is in flight, which the server drops once the + * handshake is confirmed. So only a 1-RTT packet is mutated and anything + * else passes through without consuming the one shot. */ - if (mutctx->mutctx_done) - return 0; + if (mutctx->mutctx_done || hdrin->type != QUIC_PKT_TYPE_1RTT) { + *hdrout = (QUIC_PKT_HDR *)hdrin; + *iovecout = iovecin; + *numout = numin; + return 1; + } mutctx->mutctx_done = 1; @@ -475,7 +691,7 @@ static int mutcbk_inject_frames(const QUIC_PKT_HDR *hdrin, grow_allowance -= (hdrin->src_conn_id.id_len < grow_allowance) ? hdrin->src_conn_id.id_len : grow_allowance; if (grow_allowance == 0) { - TEST_info("%s not enough space to inject", __func__); + TEST_info("%s not enough space to inject", OPENSSL_FUNC); return 0; } bufsz += grow_allowance; @@ -486,7 +702,7 @@ static int mutcbk_inject_frames(const QUIC_PKT_HDR *hdrin, /* discard const */ buf = (char *)mutctx->mutctx_iov.buf; if (buf == NULL) { - TEST_info("%s OPENSSL_malloc() failed", __func__); + TEST_info("%s OPENSSL_malloc() failed", OPENSSL_FUNC); return 0; } @@ -567,6 +783,7 @@ DEF_FUNC(mount_flood) mutctx.mutctx_inject = inject_frames; mutctx.mutctx_inject_sz = sizeof(PATH_CHALLENGE_FRAMES) - 1; + mutctx.mutctx_done = 0; REQUIRE_SSL(ssl); ch = ossl_quic_conn_get_channel(ssl); if (!TEST_ptr(ch)) @@ -765,6 +982,39 @@ DEF_SCRIPT(check_ctx_cbks, "Check new_pending and client_hello callbacks") OP_FUNC(check_pending); } +/* + * With client ticking disabled only its assist thread can act, so skipping fake + * time past the 30s idle timeout keeps the server up only if the assist thread + * keeps sending keepalives. + */ +DEF_SCRIPT(check_thread_assisted_idle, + "thread-assisted mode keeps an idle connection alive") +{ + size_t i; + + OP_NEW_SSL_L_MEM(L); + OP_NEW_SSL_C_TA_MEM(C); + OP_LINK_DGRAM_PAIR(C, L); + OP_LISTEN(L); + OP_CONNECT_WAIT(C); + + OP_ACCEPT_CONN_WAIT(L, Sa, 0); + OP_ACCEPT_CONN_NONE(L); + + OP_WRITE_B(C, "apple"); + OP_READ_EXPECT_B(Sa, "apple"); + + OP_TICK_DISABLE(C); + + /* Step well below the keepalive interval so due PINGs can be serviced. */ + for (i = 0; i < 40; ++i) { + OP_SKIP_TIME_WAIT(C, 1000); + OP_EXPECT_CONNECTED(Sa); + } + + OP_TICK_ENABLE(C); +} + DEF_FUNC(check_stream_reset_5) { int ok = 0; @@ -1085,212 +1335,2382 @@ DEF_SCRIPT(script_12, "Many threads initiated on the same client connection") OP_SLEEP(10); } -DEF_SCRIPT(script_13, "place holder for multistrem script_13") +/* 13. Many threads accepted on the same client connection (stress test) */ +DEF_SCRIPT(script_13_child_1, + "child: 10x accept stream from C, read, expect FIN, free") { -} + size_t i; -DEF_SCRIPT(script_14, "place holder for multistrem script_14") -{ + for (i = 0; i < 10; i++) { + OP_ACCEPT_STREAM_WAIT(C, C1, OP_F_REPLACE_STREAM); + OP_READ_EXPECT_B(C1, "foo"); + OP_EXPECT_FIN(C1); + } } -DEF_SCRIPT(script_15, "place holder for multistrem script_15") +DEF_SCRIPT(script_13_child_2, + "child: 10x accept stream from C, read, expect FIN, free") { -} + size_t i; -DEF_SCRIPT(script_16, "place holder for multistrem script_16") -{ + for (i = 0; i < 10; i++) { + OP_ACCEPT_STREAM_WAIT(C, C2, OP_F_REPLACE_STREAM); + OP_READ_EXPECT_B(C2, "foo"); + OP_EXPECT_FIN(C2); + } } -DEF_SCRIPT(script_17, "place holder for multistrem script_17") +DEF_SCRIPT(script_13_child_3, + "child: 10x accept stream from C, read, expect FIN, free") { -} + size_t i; -DEF_SCRIPT(script_18, "place holder for multistrem script_18") -{ + for (i = 0; i < 10; i++) { + OP_ACCEPT_STREAM_WAIT(C, C3, OP_F_REPLACE_STREAM); + OP_READ_EXPECT_B(C3, "foo"); + OP_EXPECT_FIN(C3); + } } -DEF_SCRIPT(script_19, "place holder for multistrem script_19") +DEF_SCRIPT(script_13_child_4, + "child: 10x accept stream from C, read, expect FIN, free") { -} + size_t i; -DEF_SCRIPT(script_20, "place holder for multistrem script_20") -{ + for (i = 0; i < 10; i++) { + OP_ACCEPT_STREAM_WAIT(C, C4, OP_F_REPLACE_STREAM); + OP_READ_EXPECT_B(C4, "foo"); + OP_EXPECT_FIN(C4); + } } -DEF_SCRIPT(script_21, "place holder for multistrem script_21") +DEF_SCRIPT(script_13_child_5, + "child: 10x accept stream from C, read, expect FIN, free") { -} + size_t i; -DEF_SCRIPT(script_22, "place holder for multistrem script_22") -{ + for (i = 0; i < 10; i++) { + OP_ACCEPT_STREAM_WAIT(C, C5, OP_F_REPLACE_STREAM); + OP_READ_EXPECT_B(C5, "foo"); + OP_EXPECT_FIN(C5); + } } -DEF_SCRIPT(script_23, "place holder for multistrem script_23") +DEF_SCRIPT(script_13, + "Many threads accepted on same client connection (stress test)") { -} + size_t i; -DEF_SCRIPT(script_24, "place holder for multistrem script_24") -{ -} + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); -DEF_SCRIPT(script_25, "place holder for multistrem script_25") -{ -} + /* + * put empty objects to radix process cache. + * objects C1 - C5 are going to be used for + * SSL streams in _child_1 - _child_5 threads. + */ + OP_BIND(C1); + OP_BIND(C2); + OP_BIND(C3); + OP_BIND(C4); + OP_BIND(C5); + OP_BIND(Sa); -DEF_SCRIPT(script_26, "place holder for multistrem script_26") -{ -} + OP_SPAWN_THREAD(script_13_child_1); + OP_SPAWN_THREAD(script_13_child_2); + OP_SPAWN_THREAD(script_13_child_3); + OP_SPAWN_THREAD(script_13_child_4); + OP_SPAWN_THREAD(script_13_child_5); -DEF_SCRIPT(script_27, "place holder for multistrem script_27") -{ + for (i = 0; i < 50; ++i) { + OP_NEW_STREAM(S, Sa, OP_F_REPLACE_STREAM); + OP_WRITE_B(Sa, "foo"); + OP_CONCLUDE(Sa); + } } -DEF_SCRIPT(script_28, "place holder for multistrem script_28") +/* 14. Many threads initiating on the same client connection (stress test) */ +DEF_SCRIPT(script_14_child_1, + "child: 10x create stream on C, write, conclude, free") { -} + size_t i; -DEF_SCRIPT(script_29, "place holder for multistrem script_29") -{ + for (i = 0; i < 10; i++) { + OP_NEW_STREAM(C, C1, OP_F_REPLACE_STREAM); + OP_WRITE_B(C1, "foo"); + OP_CONCLUDE(C1); + } } -DEF_SCRIPT(script_30, "place holder for multistrem script_30") +DEF_SCRIPT(script_14_child_2, + "child: 10x create stream on C, write, conclude, free") { -} + size_t i; -DEF_SCRIPT(script_31, "place holder for multistrem script_31") -{ + for (i = 0; i < 10; i++) { + OP_NEW_STREAM(C, C2, OP_F_REPLACE_STREAM); + OP_WRITE_B(C2, "foo"); + OP_CONCLUDE(C2); + } } -DEF_SCRIPT(script_32, "place holder for multistrem script_32") +DEF_SCRIPT(script_14_child_3, + "child: 10x create stream on C, write, conclude, free") { -} + size_t i; -DEF_SCRIPT(script_33, "place holder for multistrem script_33") -{ + for (i = 0; i < 10; i++) { + OP_NEW_STREAM(C, C3, OP_F_REPLACE_STREAM); + OP_WRITE_B(C3, "foo"); + OP_CONCLUDE(C3); + } } -DEF_SCRIPT(script_34, "place holder for multistrem script_34") +DEF_SCRIPT(script_14_child_4, + "child: 10x create stream on C, write, conclude, free") { -} + size_t i; -DEF_SCRIPT(script_35, "place holder for multistrem script_35") -{ + for (i = 0; i < 10; i++) { + OP_NEW_STREAM(C, C4, OP_F_REPLACE_STREAM); + OP_WRITE_B(C4, "foo"); + OP_CONCLUDE(C4); + } } -DEF_SCRIPT(script_36, "place holder for multistrem script_36") +DEF_SCRIPT(script_14_child_5, + "child: 10x create stream on C, write, conclude, free") { -} + size_t i; -DEF_SCRIPT(script_37, "place holder for multistrem script_37") -{ + for (i = 0; i < 10; i++) { + OP_NEW_STREAM(C, C5, OP_F_REPLACE_STREAM); + OP_WRITE_B(C5, "foo"); + OP_CONCLUDE(C5); + } } -DEF_SCRIPT(script_38, "place holder for multistrem script_38") +DEF_SCRIPT(script_14, + "Many threads initiating on same client connection (stress test)") { -} + size_t i; -DEF_SCRIPT(script_39, "place holder for multistrem script_39") -{ -} + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); -DEF_SCRIPT(script_40, "place holder for multistrem script_40") -{ -} + OP_BIND(C1); + OP_BIND(C2); + OP_BIND(C3); + OP_BIND(C4); + OP_BIND(C5); + OP_BIND(Sa); -DEF_SCRIPT(script_41, "place holder for multistrem script_41") -{ -} + OP_SPAWN_THREAD(script_14_child_1); + OP_SPAWN_THREAD(script_14_child_2); + OP_SPAWN_THREAD(script_14_child_3); + OP_SPAWN_THREAD(script_14_child_4); + OP_SPAWN_THREAD(script_14_child_5); -DEF_SCRIPT(script_42, "place holder for multistrem script_42") -{ + for (i = 0; i < 50; ++i) { + OP_ACCEPT_STREAM_WAIT(S, Sa, OP_F_REPLACE_STREAM); + OP_READ_EXPECT_B(Sa, "foo"); + OP_EXPECT_FIN(Sa); + } } -DEF_SCRIPT(script_43, "place holder for multistrem script_43") +/* 15. Client sending large number of streams, MAX_STREAMS test */ +DEF_SCRIPT(script_15, "Client sending large number of streams, MAX_STREAMS test") { -} + size_t i; -DEF_SCRIPT(script_44, "place holder for multistrem script_44") -{ -} + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); -DEF_SCRIPT(script_45, "place holder for multistrem script_45") -{ -} + /* + * This will cause a protocol violation to be raised by the server if we are + * not handling the stream limit correctly on the TX side. + */ + for (i = 0; i < 200; ++i) { + OP_NEW_STREAM(C, Ca, SSL_STREAM_FLAG_ADVANCE); + OP_WRITE(Ca, "foo", 3); + OP_CONCLUDE(Ca); + OP_UNBIND(Ca); + } -DEF_SCRIPT(script_46, "place holder for multistrem script_46") -{ -} + /* Prove the connection is still good. */ + OP_NEW_STREAM(S, Sa, 0); + OP_WRITE(Sa, "bar", 3); + OP_CONCLUDE(Sa); -DEF_SCRIPT(script_47, "place holder for multistrem script_47") -{ -} + OP_ACCEPT_STREAM_WAIT(C, Ca, 0); + OP_READ_EXPECT(Ca, "bar", 3); + OP_EXPECT_FIN(Ca); -DEF_SCRIPT(script_48, "place holder for multistrem script_48") -{ + /* + * Drain the queue of incoming streams. We should be able to get all 200 + * even though only 100 can be initiated at a time. + */ + for (i = 0; i < 200; ++i) { + OP_ACCEPT_STREAM_WAIT(S, Sb, 0); + OP_READ_EXPECT(Sb, "foo", 3); + OP_EXPECT_FIN(Sb); + OP_UNBIND(Sb); + } } -DEF_SCRIPT(script_49, "place holder for multistrem script_49") +/* 16. Server sending large number of streams, MAX_STREAMS test */ +DEF_SCRIPT(script_16, "Server sending large number of streams, MAX_STREAMS test") { -} + size_t i; -DEF_SCRIPT(script_50, "place holder for multistrem script_50") -{ -} + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); -DEF_SCRIPT(script_51, "place holder for multistrem script_51") -{ -} + /* + * This will cause a protocol violation to be raised by the client if we are + * not handling the stream limit correctly on the TX side. + */ + for (i = 0; i < 200; ++i) { + OP_NEW_STREAM(S, Sa, SSL_STREAM_FLAG_ADVANCE); + OP_WRITE(Sa, "foo", 3); + OP_CONCLUDE(Sa); + OP_UNBIND(Sa); + } -DEF_SCRIPT(script_52, "place holder for multistrem script_52") -{ -} + /* Prove that the connection is still good. */ + OP_NEW_STREAM(C, Ca, 0); + OP_WRITE(Ca, "bar", 3); + OP_CONCLUDE(Ca); -DEF_SCRIPT(script_53, "place holder for multistrem script_53") -{ -} + OP_ACCEPT_STREAM_WAIT(S, Sb, 0); + OP_READ_EXPECT(Sb, "bar", 3); + OP_EXPECT_FIN(Sb); -DEF_SCRIPT(script_54, "place holder for multistrem script_54") -{ + /* Drain the queue of incoming streams. */ + for (i = 0; i < 200; ++i) { + OP_ACCEPT_STREAM_WAIT(C, Cb, 0); + OP_READ_EXPECT(Cb, "foo", 3); + OP_EXPECT_FIN(Cb); + OP_UNBIND(Cb); + } } -DEF_SCRIPT(script_55, "place holder for multistrem script_55") +/* 17. Key update test - unlimited */ +DEF_SCRIPT(script_17, "Key update test - unlimited") { -} + size_t i; -DEF_SCRIPT(script_56, "place holder for multistrem script_56") -{ -} + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); -DEF_SCRIPT(script_57, "place holder for multistrem script_57") -{ -} + OP_WRITE(C, "apple", 5); + OP_READ_EXPECT(S, "apple", 5); -DEF_SCRIPT(script_58, "place holder for multistrem script_58") -{ -} + OP_OVERRIDE_KEY_UPDATE(C, 1); + + for (i = 0; i < 200; ++i) { + OP_WRITE(C, "apple", 5); + OP_READ_EXPECT(S, "apple", 5); + /* + * TXKU frequency is bounded by RTT because a previous TXKU needs to be + * acknowledged by the peer first before another one can begin. By + * waiting this long, we eliminate any such concern and ensure as many key + * updates as possible can occur for the purposes of this test. + */ + OP_SKIP_TIME(100); + } -DEF_SCRIPT(script_59, "place holder for multistrem script_59") -{ -} + /* At least 5 RXKUs detected */ + OP_CHECK_KEY_UPDATE_GE(C, 5); -DEF_SCRIPT(script_60, "place holder for multistrem script_60") -{ -} + /* + * Prove the connection is still healthy by sending something in both + * directions. + */ + OP_WRITE(C, "xyzzy", 5); + OP_READ_EXPECT(S, "xyzzy", 5); -DEF_SCRIPT(script_61, "place holder for multistrem script_61") -{ + OP_WRITE(S, "plugh", 5); + OP_READ_EXPECT(C, "plugh", 5); } -DEF_SCRIPT(script_62, "place holder for multistrem script_62") +/* 18. Key update test - RTT-bounded */ +DEF_SCRIPT(script_18, "Key update test - RTT-bounded") { -} + size_t i; -DEF_SCRIPT(script_63, "place holder for multistrem script_63") -{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_WRITE(C, "apple", 5); + OP_READ_EXPECT(S, "apple", 5); + + OP_OVERRIDE_KEY_UPDATE(C, 1); + + for (i = 0; i < 200; ++i) { + OP_WRITE(C, "apple", 5); + OP_READ_EXPECT(S, "apple", 5); + OP_SKIP_TIME(8); + } + + /* + * This time we simulate far less time passing between writes, so there are + * fewer opportunities to initiate TXKUs. Note that we ask for a TXKU every + * 1 packet above, which is absurd; thus this ensures we only actually + * generate TXKUs when we are allowed to. + */ + OP_CHECK_KEY_UPDATE_LT(C, 240); + + /* + * Prove the connection is still healthy by sending something in both + * directions. + */ + OP_WRITE(C, "xyzzy", 5); + OP_READ_EXPECT(S, "xyzzy", 5); + + OP_WRITE(S, "plugh", 5); + OP_READ_EXPECT(C, "plugh", 5); } -DEF_SCRIPT(script_64, "place holder for multistrem script_64") +/* 19. Key update test - artificially triggered */ +DEF_SCRIPT(script_19, "Key update test - artificially triggered") { + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_WRITE(C, "apple", 5); + OP_READ_EXPECT(S, "apple", 5); + + OP_WRITE(C, "orange", 6); + OP_READ_EXPECT(S, "orange", 6); + + OP_WRITE(S, "strawberry", 10); + OP_READ_EXPECT(C, "strawberry", 10); + + OP_CHECK_KEY_UPDATE_LT(C, 1); + + OP_TRIGGER_KEY_UPDATE(C, SSL_KEY_UPDATE_REQUESTED); + + OP_WRITE(C, "orange", 6); + OP_READ_EXPECT(S, "orange", 6); + OP_WRITE(S, "ok", 2); + + OP_READ_EXPECT(C, "ok", 2); + OP_CHECK_KEY_UPDATE_GE(C, 1); +} + +/* 20. Multiple threads accept stream with socket forcibly closed (error test) */ +DEF_SCRIPT(script_20_child_0, + "child: accept stream, read, signal ready, wait, expect read failure") +{ + OP_ACCEPT_STREAM_WAIT(C, Ca, OP_F_REPLACE_STREAM /* bidirectional */); + OP_READ_EXPECT_B(Ca, "foo"); + + OP_TRIGGER_COUNTER(0); + OP_WAIT_COUNTER(1, 1); + + OP_READ_FAIL_WAIT(Ca); + OP_EXPECT_SSL_ERR(Ca, SSL_ERROR_SYSCALL); +} + +DEF_SCRIPT(script_20_child_1, + "child: accept stream, read, signal ready, wait, expect read failure") +{ + OP_ACCEPT_STREAM_WAIT(C, Cb, OP_F_REPLACE_STREAM /* bidirectional */); + OP_READ_EXPECT_B(Cb, "foo"); + + OP_TRIGGER_COUNTER(0); + OP_WAIT_COUNTER(1, 1); + + OP_READ_FAIL_WAIT(Cb); + OP_EXPECT_SSL_ERR(Cb, SSL_ERROR_SYSCALL); +} + +DEF_SCRIPT(script_20_child_2, + "child: accept stream, read, signal ready, wait, expect read failure") +{ + OP_ACCEPT_STREAM_WAIT(C, Cc, OP_F_REPLACE_STREAM /* bidirectional */); + OP_READ_EXPECT_B(Cc, "foo"); + + OP_TRIGGER_COUNTER(0); + OP_WAIT_COUNTER(1, 1); + + OP_READ_FAIL_WAIT(Cc); + OP_EXPECT_SSL_ERR(Cc, SSL_ERROR_SYSCALL); +} + +DEF_SCRIPT(script_20_child_3, + "child: accept stream, read, signal ready, wait, expect read failure") +{ + OP_ACCEPT_STREAM_WAIT(C, Cd, OP_F_REPLACE_STREAM /* bidirectional */); + OP_READ_EXPECT_B(Cd, "foo"); + + OP_TRIGGER_COUNTER(0); + OP_WAIT_COUNTER(1, 1); + + OP_READ_FAIL_WAIT(Cd); + OP_EXPECT_SSL_ERR(Cd, SSL_ERROR_SYSCALL); +} + +DEF_SCRIPT(script_20_child_4, + "child: accept stream, read, signal ready, wait, expect read failure") +{ + OP_ACCEPT_STREAM_WAIT(C, Ce, OP_F_REPLACE_STREAM /* bidirectional */); + OP_READ_EXPECT_B(Ce, "foo"); + + OP_TRIGGER_COUNTER(0); + OP_WAIT_COUNTER(1, 1); + + OP_READ_FAIL_WAIT(Ce); + OP_EXPECT_SSL_ERR(Ce, SSL_ERROR_SYSCALL); +} + +DEF_SCRIPT(script_20, "Multiple threads accept stream with socket forcibly closed (error test)") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_BIND(Ca); + OP_BIND(Cb); + OP_BIND(Cc); + OP_BIND(Cd); + OP_BIND(Ce); + OP_BIND(Sa); + OP_BIND(Sb); + OP_BIND(Sc); + OP_BIND(Sd); + OP_BIND(Se); + + OP_SPAWN_THREAD(script_20_child_0); + OP_SPAWN_THREAD(script_20_child_1); + OP_SPAWN_THREAD(script_20_child_2); + OP_SPAWN_THREAD(script_20_child_3); + OP_SPAWN_THREAD(script_20_child_4); + + OP_NEW_STREAM(S, Sa, OP_F_REPLACE_STREAM /* bidirectional */); + OP_WRITE_B(Sa, "foo"); + OP_CONCLUDE(Sa); + + OP_NEW_STREAM(S, Sb, OP_F_REPLACE_STREAM /* bidirectional */); + OP_WRITE_B(Sb, "foo"); + OP_CONCLUDE(Sb); + + OP_NEW_STREAM(S, Sc, OP_F_REPLACE_STREAM /* bidirectional */); + OP_WRITE_B(Sc, "foo"); + OP_CONCLUDE(Sc); + + OP_NEW_STREAM(S, Sd, OP_F_REPLACE_STREAM /* bidirectional */); + OP_WRITE_B(Sd, "foo"); + OP_CONCLUDE(Sd); + + OP_NEW_STREAM(S, Se, OP_F_REPLACE_STREAM /* bidirectional */); + OP_WRITE_B(Se, "foo"); + OP_CONCLUDE(Se); + + OP_WAIT_COUNTER(0, 5); + + OP_CLOSE_SOCKET(C); + + OP_TRIGGER_COUNTER(1); +} + +/* 21. Fault injection - unknown frame in 1-RTT packet */ +static int script_21_inject_plain(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len) +{ + int ok = 0; + WPACKET wpkt; + unsigned char frame_buf[21]; + size_t written; + + if (fault->word0 == 0 || hdr->type != fault->word0) + return 1; + + if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, + sizeof(frame_buf), 0))) + return 0; + + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, fault->word1))) + goto err; + + switch (fault->word1) { + case OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE: + case OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE: + case OSSL_QUIC_FRAME_TYPE_RETIRE_CONN_ID: + if (!TEST_true(WPACKET_put_bytes_u64(&wpkt, (uint64_t)0))) + goto err; + break; + case OSSL_QUIC_FRAME_TYPE_MAX_DATA: + case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI: + case OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI: + case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI: + case OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI: + case OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED: + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, (uint64_t)0))) + goto err; + break; + case OSSL_QUIC_FRAME_TYPE_STOP_SENDING: + case OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA: + case OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED: + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, (uint64_t)0)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, (uint64_t)0))) + goto err; + break; + case OSSL_QUIC_FRAME_TYPE_STREAM: + case OSSL_QUIC_FRAME_TYPE_RESET_STREAM: + case OSSL_QUIC_FRAME_TYPE_CONN_CLOSE_APP: + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, (uint64_t)0)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, (uint64_t)0)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, (uint64_t)0))) + goto err; + break; + case OSSL_QUIC_FRAME_TYPE_NEW_TOKEN: + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, (uint64_t)1)) + || !TEST_true(WPACKET_put_bytes_u8(&wpkt, (uint8_t)0))) + goto err; + break; + case OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID: + /* seq number */ + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, (uint64_t)0)) + /* retire prior to */ + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, (uint64_t)0)) + /* Connection id length, arbitrary at 1 bytes */ + || !TEST_true(WPACKET_put_bytes_u8(&wpkt, (uint8_t)1)) + /* The connection id */ + || !TEST_true(WPACKET_put_bytes_u8(&wpkt, (uint8_t)0)) + /* 16 bytes total for the stateless reset token */ + || !TEST_true(WPACKET_memset(&wpkt, 0, 16))) + goto err; + + break; + } + + if (!TEST_true(WPACKET_get_total_written(&wpkt, &written)) + || !radix_fault_prepend_frame(fault, frame_buf, written)) + goto err; + + ok = 1; +err: + if (ok) + WPACKET_finish(&wpkt); + else + WPACKET_cleanup(&wpkt); + return ok; +} + +DEF_SCRIPT(script_21, "Fault injection - unknown frame in 1-RTT packet") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_21_inject_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(QUIC_PKT_TYPE_1RTT, OSSL_QUIC_VLINT_MAX); + + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0); +} + +/* 22. Fault injection - non-zero packet header reserved bits */ +static int script_22_inject_plain(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len) +{ + if (fault->word0 == 0) + return 1; + + hdr->reserved = 1; + return 1; +} + +DEF_SCRIPT(script_22, "Fault injection - non-zero packet header reserved bits") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_22_inject_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, 0); + + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_PROTOCOL_VIOLATION, 0, 0); +} + +/* 23. Fault injection - empty NEW_TOKEN */ +static int script_23_inject_plain(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len) +{ + int ok = 0; + WPACKET wpkt; + unsigned char frame_buf[16]; + size_t written; + + if (fault->word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) + return 1; + + if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, sizeof(frame_buf), 0))) + return 0; + + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, OSSL_QUIC_FRAME_TYPE_NEW_TOKEN)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, 0)) + || !TEST_true(WPACKET_get_total_written(&wpkt, &written)) + || !radix_fault_prepend_frame(fault, frame_buf, written)) + goto err; + + ok = 1; +err: + if (ok) + WPACKET_finish(&wpkt); + else + WPACKET_cleanup(&wpkt); + return ok; +} + +DEF_SCRIPT(script_23, "Fault injection - empty NEW_TOKEN") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_23_inject_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, 0); + + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0); +} + +/* 24. Fault injection - excess value of MAX_STREAMS_BIDI */ +static int script_24_inject_plain(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len) +{ + int ok = 0; + WPACKET wpkt; + unsigned char frame_buf[16]; + size_t written; + + if (fault->word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) + return 1; + + if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, sizeof(frame_buf), 0))) + return 0; + + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, fault->word1)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, (((uint64_t)1) << 60) + 1)) + || !TEST_true(WPACKET_get_total_written(&wpkt, &written)) + || !radix_fault_prepend_frame(fault, frame_buf, written)) + goto err; + + ok = 1; +err: + if (ok) + WPACKET_finish(&wpkt); + else + WPACKET_cleanup(&wpkt); + return ok; +} + +DEF_SCRIPT(script_24, "Fault injection - excess value of MAX_STREAMS_BIDI") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_24_inject_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_BIDI); + + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0); +} + +/* 25. Fault injection - excess value of MAX_STREAMS_UNI */ +DEF_SCRIPT(script_25, "Fault injection - excess value of MAX_STREAMS_UNI") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_24_inject_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_MAX_STREAMS_UNI); + + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0); +} + +/* 26. Fault injection - excess value of STREAMS_BLOCKED_BIDI */ +DEF_SCRIPT(script_26, "Fault injection - excess value of STREAMS_BLOCKED_BIDI") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_24_inject_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI); + + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_STREAM_LIMIT_ERROR, 0, 0); +} + +/* 27. Fault injection - excess value of STREAMS_BLOCKED_UNI */ +DEF_SCRIPT(script_27, "Fault injection - excess value of STREAMS_BLOCKED_UNI") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_24_inject_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI); + + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_STREAM_LIMIT_ERROR, 0, 0); +} + +/* 28. Fault injection - received RESET_STREAM for send-only stream */ +static int inject_stream_frame_plain(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len) +{ + int ok = 0; + WPACKET wpkt; + unsigned char frame_buf[32]; + size_t written; + + if (fault->word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) + return 1; + + if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, + sizeof(frame_buf), 0))) + return 0; + + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, fault->word1)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, /* stream ID */ + fault->word0 - 1)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, 123)) + || (fault->word1 == OSSL_QUIC_FRAME_TYPE_RESET_STREAM + && !TEST_true(WPACKET_quic_write_vlint(&wpkt, 5))) /* final size */ + || !TEST_true(WPACKET_get_total_written(&wpkt, &written)) + || !radix_fault_prepend_frame(fault, frame_buf, written)) + goto err; + + ok = 1; +err: + if (ok) + WPACKET_finish(&wpkt); + else + WPACKET_cleanup(&wpkt); + return ok; +} + +DEF_SCRIPT(script_28, "Fault injection - received RESET_STREAM for send-only stream") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_stream_frame_plain); + + OP_NEW_STREAM(C, Ca, 0 /* bidirectional */); + OP_WRITE(Ca, "orange", 6); + + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "orange", 6); + + OP_NEW_STREAM(C, Cb, SSL_STREAM_FLAG_UNI); + OP_WRITE(Cb, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(S, Sb, 0); + OP_READ_EXPECT(Sb, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(C_UNI_ID(0) + 1, OSSL_QUIC_FRAME_TYPE_RESET_STREAM); + OP_WRITE(Sa, "fruit", 5); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0); +} + +/* 29. Fault injection - received RESET_STREAM for nonexistent send-only stream */ +DEF_SCRIPT(script_29, "Fault injection - received RESET_STREAM for nonexistent send-only stream") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_stream_frame_plain); + + OP_NEW_STREAM(C, Ca, 0 /* bidirectional */); + OP_WRITE(Ca, "orange", 6); + + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "orange", 6); + + OP_NEW_STREAM(C, Cb, SSL_STREAM_FLAG_UNI); + OP_WRITE(Cb, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(S, Sb, 0); + OP_READ_EXPECT(Sb, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(C_UNI_ID(1) + 1, OSSL_QUIC_FRAME_TYPE_RESET_STREAM); + OP_WRITE(Sa, "fruit", 5); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0); +} + +/* 30. Fault injection - received STOP_SENDING for receive-only stream */ +DEF_SCRIPT(script_30, "Fault injection - received STOP_SENDING for receive-only stream") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_stream_frame_plain); + + OP_NEW_STREAM(S, Sa, SSL_STREAM_FLAG_UNI); + OP_WRITE(Sa, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(C, Ca, 0); + OP_READ_EXPECT(Ca, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(S_UNI_ID(0) + 1, OSSL_QUIC_FRAME_TYPE_STOP_SENDING); + + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0); +} + +/* 31. Fault injection - received STOP_SENDING for nonexistent receive-only stream */ +DEF_SCRIPT(script_31, "Fault injection - received STOP_SENDING for nonexistent receive-only stream") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_stream_frame_plain); + + OP_NEW_STREAM(S, Sa, SSL_STREAM_FLAG_UNI); + OP_WRITE(Sa, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(C, Ca, 0); + OP_READ_EXPECT(Ca, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(C_UNI_ID(0) + 1, OSSL_QUIC_FRAME_TYPE_STOP_SENDING); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0); +} + +/* 32. Fault injection - STREAM frame for nonexistent stream */ +static int inject_stream_data_frame_plain(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len) +{ + int ok = 0; + WPACKET wpkt; + unsigned char frame_buf[64]; + size_t written; + uint64_t type = OSSL_QUIC_FRAME_TYPE_STREAM_OFF_LEN, offset, flen, i; + + if (hdr->type != QUIC_PKT_TYPE_1RTT) + return 1; + + switch (fault->word1) { + default: + return 0; + case 0: + return 1; + case 1: + offset = 0; + flen = 0; + break; + case 2: + offset = (((uint64_t)1) << 62) - 1; + flen = 5; + break; + case 3: + offset = 1 * 1024 * 1024 * 1024; /* 1G */ + flen = 5; + break; + case 4: + offset = 0; + flen = 1; + break; + } + + if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, + sizeof(frame_buf), 0))) + return 0; + + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, type)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, /* stream ID */ + fault->word0 - 1)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, offset)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, flen))) + goto err; + + for (i = 0; i < flen; ++i) + if (!TEST_true(WPACKET_put_bytes_u8(&wpkt, 0x42))) + goto err; + + if (!TEST_true(WPACKET_get_total_written(&wpkt, &written)) + || !radix_fault_prepend_frame(fault, frame_buf, written)) + goto err; + + ok = 1; +err: + if (ok) + WPACKET_finish(&wpkt); + else + WPACKET_cleanup(&wpkt); + return ok; +} + +DEF_SCRIPT(script_32, "Fault injection - STREAM frame for nonexistent stream") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_stream_data_frame_plain); + + OP_NEW_STREAM(S, Sa, SSL_STREAM_FLAG_UNI); + OP_WRITE(Sa, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(C, Ca, 0); + OP_READ_EXPECT(Ca, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(C_UNI_ID(0) + 1, 1); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0); +} + +/* 33. Fault injection - STREAM frame with illegal offset */ +DEF_SCRIPT(script_33, "Fault injection - STREAM frame with illegal offset") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_stream_data_frame_plain); + + OP_NEW_STREAM(C, Ca, 0 /* bidirectional */); + OP_WRITE(Ca, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(C_BIDI_ID(0) + 1, 2); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0); +} + +DEF_SCRIPT(script_34, "Fault injection - STREAM frame which exceeds FC") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_stream_data_frame_plain); + + OP_NEW_STREAM(C, Ca, 0 /* bidirectional */); + OP_WRITE(Ca, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(C_BIDI_ID(0) + 1, 3); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_FLOW_CONTROL_ERROR, 0, 0); +} + +/* 35. Fault injection - MAX_STREAM_DATA for receive-only stream */ +DEF_SCRIPT(script_35, "Fault injection - MAX_STREAM_DATA for receive-only stream") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_stream_frame_plain); + + OP_NEW_STREAM(S, Sa, SSL_STREAM_FLAG_UNI); + OP_WRITE(Sa, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(C, Ca, 0); + OP_READ_EXPECT(Ca, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(S_UNI_ID(0) + 1, OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA); + + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0); +} + +/* 36. Fault injection - MAX_STREAM_DATA for nonexistent stream */ +DEF_SCRIPT(script_36, "Fault injection - MAX_STREAM_DATA for nonexistent stream") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_stream_frame_plain); + + OP_NEW_STREAM(S, Sa, SSL_STREAM_FLAG_UNI); + OP_WRITE(Sa, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(C, Ca, 0); + OP_READ_EXPECT(Ca, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(C_BIDI_ID(0) + 1, OSSL_QUIC_FRAME_TYPE_MAX_STREAM_DATA); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0); +} + +/* 37. Fault injection - STREAM_DATA_BLOCKED for send-only stream */ +DEF_SCRIPT(script_37, "Fault injection - STREAM_DATA_BLOCKED for send-only stream") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_stream_frame_plain); + + OP_NEW_STREAM(C, Ca, SSL_STREAM_FLAG_UNI); + OP_WRITE(Ca, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_NEW_STREAM(S, Sb, SSL_STREAM_FLAG_UNI); + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(C_UNI_ID(0) + 1, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED); + OP_WRITE(Sb, "orange", 5); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0); +} + +/* 38. Fault injection - STREAM_DATA_BLOCKED for non-existent stream */ +DEF_SCRIPT(script_38, "Fault injection - STREAM_DATA_BLOCKED for non-existent stream") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_stream_frame_plain); + + OP_NEW_STREAM(C, Ca, SSL_STREAM_FLAG_UNI); + OP_WRITE(Ca, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(C_BIDI_ID(0) + 1, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED); + + OP_NEW_STREAM(S, Sb, SSL_STREAM_FLAG_UNI); + OP_WRITE(Sb, "orange", 5); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0); +} + +/* 39. Fault injection - NEW_CONN_ID with zero-len CID */ +static int inject_new_conn_id_plain(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len) +{ + int ok = 0; + WPACKET wpkt; + unsigned char frame_buf[64]; + size_t i, written; + uint64_t seq_no = 0, retire_prior_to = 0; + QUIC_CONN_ID new_cid = { 0 }; + + if (hdr->type != QUIC_PKT_TYPE_1RTT) + return 1; + + switch (fault->word1) { + case 0: + return 1; + case 1: + new_cid.id_len = 0; + break; + case 2: + new_cid.id_len = 21; + break; + case 3: + new_cid.id_len = 1; + new_cid.id[0] = 0x55; + + seq_no = 0; + retire_prior_to = 1; + break; + case 4: + /* Use our actual CID so we don't break connectivity. */ + ossl_quic_channel_get_diag_local_cid(fault->ch, &new_cid); + + seq_no = 2; + retire_prior_to = 2; + break; + case 5: + /* + * Use a bogus CID which will need to be ignored if connectivity is to + * be continued. + */ + new_cid.id_len = 8; + new_cid.id[0] = 0x55; + + seq_no = 1; + retire_prior_to = 1; + break; + } + + if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, + sizeof(frame_buf), 0))) + return 0; + + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, OSSL_QUIC_FRAME_TYPE_NEW_CONN_ID)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, seq_no)) /* seq no */ + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, retire_prior_to)) /* retire prior to */ + || !TEST_true(WPACKET_put_bytes_u8(&wpkt, new_cid.id_len))) /* len */ + goto err; + + for (i = 0; i < new_cid.id_len && i < OSSL_NELEM(new_cid.id); ++i) + if (!TEST_true(WPACKET_put_bytes_u8(&wpkt, new_cid.id[i]))) + goto err; + + for (; i < new_cid.id_len; ++i) + if (!TEST_true(WPACKET_put_bytes_u8(&wpkt, 0x55))) + goto err; + + for (i = 0; i < QUIC_STATELESS_RESET_TOKEN_LEN; ++i) + if (!TEST_true(WPACKET_put_bytes_u8(&wpkt, 0x42))) + goto err; + + if (!TEST_true(WPACKET_get_total_written(&wpkt, &written)) + || !radix_fault_prepend_frame(fault, frame_buf, written)) + goto err; + + ok = 1; +err: + if (ok) + WPACKET_finish(&wpkt); + else + WPACKET_cleanup(&wpkt); + return ok; +} + +DEF_SCRIPT(script_39, "Fault injection - NEW_CONN_ID with zero-len CID") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_new_conn_id_plain); + + OP_NEW_STREAM(C, Ca, 0 /* bidirectional */); + OP_WRITE(Ca, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(0, 1); + OP_WRITE(Sa, "orange", 5); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0); +} + +/* 40. Shutdown flush test */ +static unsigned char script_40_data[1024] = "strawberry"; + +DEF_SCRIPT(script_40, "Shutdown flush test") +{ + size_t i; + + OP_SIMPLE_PAIR_CONN_ND(); + + OP_NEW_STREAM(C, Ca, 0 /* bidirectional */); + OP_WRITE(Ca, "apple", 5); + + OP_INHIBIT_TICK(C, 1); + OP_SET_WRITE_BUF_SIZE(Ca, 1024 * 100 * 3); + + for (i = 0; i < 100; ++i) + OP_WRITE(Ca, script_40_data, sizeof(script_40_data)); + + OP_CONCLUDE(Ca); + OP_SHUTDOWN_WAIT(C, 0, 0, NULL); /* disengages tick inhibition */ + + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + for (i = 0; i < 100; ++i) + OP_READ_EXPECT(Sa, script_40_data, sizeof(script_40_data)); + + OP_EXPECT_FIN(Sa); + + OP_EXPECT_CONN_CLOSE_INFO(C, 0, 1, 0); + OP_EXPECT_CONN_CLOSE_INFO(S, 0, 1, 1); +} + +/* 41. Fault injection - PATH_CHALLENGE yields PATH_RESPONSE */ +static const uint64_t script_41_path_challenge = UINT64_C(0xbdeb9451169c83aa); +static uint64_t script_41_valid_responses; +static uint64_t script_41_bad_responses; + +static int inject_path_challenge_plain(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len) +{ + int ok = 0; + WPACKET wpkt; + unsigned char frame_buf[16]; + size_t written; + + if (fault->word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) + return 1; + + if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, + sizeof(frame_buf), 0))) + return 0; + + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, fault->word1)) + || !TEST_true(WPACKET_put_bytes_u64(&wpkt, script_41_path_challenge)) + || !TEST_true(WPACKET_get_total_written(&wpkt, &written)) + || !TEST_size_t_eq(written, 9) + || !radix_fault_prepend_frame(fault, frame_buf, written)) + goto err; + + --fault->word0; + ok = 1; +err: + if (ok) + WPACKET_finish(&wpkt); + else + WPACKET_cleanup(&wpkt); + return ok; +} + +static void script_41_trace(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg) +{ + uint64_t frame_type, frame_data; + int was_minimal; + PACKET pkt; + + if (version != OSSL_QUIC1_VERSION + || content_type != SSL3_RT_QUIC_FRAME_FULL + || len < 1) + return; + + if (!TEST_true(PACKET_buf_init(&pkt, buf, len)) + || !TEST_true(ossl_quic_wire_peek_frame_header(&pkt, &frame_type, + &was_minimal))) { + ++script_41_bad_responses; + return; + } + + if (frame_type != OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE) + return; + + if (!TEST_true(ossl_quic_wire_decode_frame_path_response(&pkt, &frame_data)) + || !TEST_uint64_t_eq(frame_data, script_41_path_challenge)) { + ++script_41_bad_responses; + return; + } + + ++script_41_valid_responses; +} + +DEF_FUNC(install_trace_41) +{ + int ok = 0; + SSL *ssl; + + REQUIRE_SSL(ssl); + SSL_set_msg_callback(ssl, script_41_trace); + + ok = 1; +err: + return ok; +} + +DEF_FUNC(check_path_response_41) +{ + int ok = 0; + + /* At least one valid challenge/response echo? */ + if (script_41_valid_responses == 0) + F_SPIN_AGAIN(); + + /* No failed tests? */ + if (!TEST_uint64_t_eq(script_41_bad_responses, 0)) + goto err; + + ok = 1; +err: + return ok; +} + +DEF_SCRIPT(script_41, "Fault injection - PATH_CHALLENGE yields PATH_RESPONSE") +{ + OP_SIMPLE_PAIR_CONN(); + + OP_WRITE(C, "apple", 5); + + OP_ACCEPT_CONN_WAIT(L, S, 0); + OP_SET_INJECT_PLAIN(S, inject_path_challenge_plain); + OP_SELECT_SSL(0, S); + OP_FUNC(install_trace_41); + + OP_READ_EXPECT(S, "apple", 5); + + OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_PATH_CHALLENGE); + + OP_WRITE(S, "orange", 6); + OP_READ_EXPECT(C, "orange", 6); + + OP_WRITE(C, "strawberry", 10); + OP_READ_EXPECT(S, "strawberry", 10); + + OP_FUNC(check_path_response_41); +} + +/* 42. Fault injection - CRYPTO frame with illegal offset */ +static int script_42_inject_plain(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len) +{ + int ok = 0; + unsigned char frame_buf[64]; + size_t written; + WPACKET wpkt; + + if (fault->word0 == 0) + return 1; + + --fault->word0; + + if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, + sizeof(frame_buf), 0))) + return 0; + + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, OSSL_QUIC_FRAME_TYPE_CRYPTO)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, fault->word1)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, 1)) + || !TEST_true(WPACKET_put_bytes_u8(&wpkt, 0x42)) + || !TEST_true(WPACKET_get_total_written(&wpkt, &written)) + || !radix_fault_prepend_frame(fault, frame_buf, written)) + goto err; + + ok = 1; +err: + if (ok) + WPACKET_finish(&wpkt); + else + WPACKET_cleanup(&wpkt); + return ok; +} + +DEF_SCRIPT(script_42, "Fault injection - CRYPTO frame with illegal offset") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_42_inject_plain); + + OP_NEW_STREAM(C, Ca, 0); + OP_WRITE(Ca, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, (((uint64_t)1) << 62) - 1); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0); +} + +/* 43. Fault injection - CRYPTO frame exceeding FC */ +DEF_SCRIPT(script_43, "Fault injection - CRYPTO frame exceeding FC") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_42_inject_plain); + + OP_NEW_STREAM(C, Ca, 0); + OP_WRITE(Ca, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, 0x100000 /* 1 MiB */); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_CRYPTO_BUFFER_EXCEEDED, 0, 0); +} + +/* 44. Fault injection - PADDING */ +static int script_44_inject_plain(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len) +{ + int ok = 0; + WPACKET wpkt; + unsigned char frame_buf[16]; + size_t written; + + if (fault->word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) + return 1; + + if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, + sizeof(frame_buf), 0))) + return 0; + + if (!TEST_true(ossl_quic_wire_encode_padding(&wpkt, 1)) + || !TEST_true(WPACKET_get_total_written(&wpkt, &written)) + || !radix_fault_prepend_frame(fault, frame_buf, written)) + goto err; + + ok = 1; +err: + if (ok) + WPACKET_finish(&wpkt); + else + WPACKET_cleanup(&wpkt); + return ok; +} + +DEF_SCRIPT(script_44, "Fault injection - PADDING") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_44_inject_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_SET_INJECT_WORD(1, 0); + + OP_WRITE(Sa, "Strawberry", 10); + OP_READ_EXPECT(C, "Strawberry", 10); +} + +static uint16_t script_45_ack_count; + +/* 45. PING must generate ACK */ +DEF_FUNC(force_ping_45) +{ + int ok = 0; + SSL *ssl; + QUIC_CHANNEL *ch; + + REQUIRE_SSL(ssl); + ch = ossl_quic_conn_get_channel(ssl); + if (!TEST_ptr(ch)) + goto err; + + script_45_ack_count = ossl_quic_channel_get_diag_num_rx_ack(ch); + + if (!TEST_true(ossl_quic_channel_ping(ch))) + goto err; + + ok = 1; +err: + return ok; +} + +DEF_FUNC(wait_incoming_acks_increased_45) +{ + int ok = 0; + SSL *ssl; + QUIC_CHANNEL *ch; + uint16_t count; + + REQUIRE_SSL(ssl); + ch = ossl_quic_conn_get_channel(ssl); + if (!TEST_ptr(ch)) + goto err; + + count = ossl_quic_channel_get_diag_num_rx_ack(ch); + + if (count == script_45_ack_count) + F_SPIN_AGAIN(); + + ok = 1; +err: + return ok; +} + +DEF_SCRIPT(script_45, "PING must generate ACK") +{ + size_t i; + + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + for (i = 0; i < 2; ++i) { + OP_SELECT_SSL(0, S); + OP_FUNC(force_ping_45); + OP_SELECT_SSL(0, S); + OP_FUNC(wait_incoming_acks_increased_45); + } + + OP_WRITE(Sa, "Strawberry", 10); + OP_READ_EXPECT(C, "Strawberry", 10); +} + +static int inject_malformed_ack_plain(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len) +{ + int ok = 0; + WPACKET wpkt; + unsigned char frame_buf[16]; + size_t written; + uint64_t type = 0, largest_acked = 0, first_range = 0, range_count = 0; + uint64_t agap = 0, alen = 0; + uint64_t ect0 = 0, ect1 = 0, ecnce = 0; + + if (fault->word0 == 0) + return 1; + + if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, + sizeof(frame_buf), 0))) + return 0; + + type = OSSL_QUIC_FRAME_TYPE_ACK_WITHOUT_ECN; + + switch (fault->word0) { + case 1: + largest_acked = 100; + first_range = 101; + range_count = 0; + break; + case 2: + largest_acked = 100; + first_range = 80; + /* [20..100]; [0..18] */ + range_count = 1; + agap = 0; + alen = 19; + break; + case 3: + largest_acked = 100; + first_range = 80; + range_count = 1; + agap = 18; + alen = 1; + break; + case 4: + type = OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN; + largest_acked = 100; + first_range = 1; + range_count = 0; + break; + case 5: + type = OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN; + largest_acked = 0; + first_range = 0; + range_count = 0; + ect0 = 0; + ect1 = 50; + ecnce = 200; + break; + } + + fault->word0 = 0; + + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, type)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, largest_acked)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, /*ack_delay=*/0)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, /*ack_range_count=*/range_count)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, /*first_ack_range=*/first_range))) + goto err; + + if (range_count > 0) + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, /*range[0].gap=*/agap)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, /*range[0].len=*/alen))) + goto err; + + if (type == OSSL_QUIC_FRAME_TYPE_ACK_WITH_ECN) + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, ect0)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, ect1)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, ecnce))) + goto err; + + if (!TEST_true(WPACKET_get_total_written(&wpkt, &written)) + || !radix_fault_prepend_frame(fault, frame_buf, written)) + goto err; + + ok = 1; +err: + if (ok) + WPACKET_finish(&wpkt); + else + WPACKET_cleanup(&wpkt); + return ok; +} + +/* 46. Fault injection - ACK - malformed initial range */ +DEF_SCRIPT(script_46, "Fault injection - ACK - malformed initial range") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_malformed_ack_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, 0); + OP_WRITE(Sa, "Strawberry", 10); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0); +} + +DEF_SCRIPT(script_47, "Fault injection - ACK - malformed subsequent range") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_malformed_ack_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(2, 0); + OP_WRITE(Sa, "Strawberry", 10); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0); +} + +DEF_SCRIPT(script_48, "Fault injection - ACK - malformed subsequent range") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_malformed_ack_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(3, 0); + OP_WRITE(Sa, "Strawberry", 10); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0); +} + +DEF_SCRIPT(script_49, "Fault injection - ACK - fictional PN") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_malformed_ack_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_SET_INJECT_WORD(4, 0); + + OP_WRITE(Sa, "Strawberry", 10); + /* + * The injected ACK acknowledges a packet number we have not sent, which the + * peer is expected to treat as a PROTOCOL_VIOLATION, so the connection is + * closed rather than the stream data being delivered. + */ + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_PROTOCOL_VIOLATION, 0, 0); +} + +/* 50. Fault injection - ACK - duplicate PN */ +DEF_SCRIPT(script_50, "Fault injection - ACK - duplicate PN") +{ + size_t i; + + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_malformed_ack_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + for (i = 0; i < 2; ++i) { + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(5, 0); + OP_WRITE(Sa, "Strawberry", 10); + OP_ENGINE_TICK_ENABLE(S); + OP_READ_EXPECT(C, "Strawberry", 10); + } +} + +DEF_SCRIPT(script_51, "Fault injection - PATH_RESPONSE is ignored") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + OP_SET_INJECT_PLAIN(S, inject_path_challenge_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_PATH_RESPONSE); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + OP_READ_EXPECT(C, "orange", 6); + + OP_WRITE(C, "Strawberry", 10); + OP_READ_EXPECT(Sa, "Strawberry", 10); +} + +/* 52. Fault injection - ignore BLOCKED frames with bogus values */ +static int script_52_inject_plain(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len) +{ + int ok = 0; + unsigned char frame_buf[64]; + size_t written; + WPACKET wpkt; + uint64_t type = fault->word1; + + if (fault->word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) + return 1; + + --fault->word0; + + if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, + sizeof(frame_buf), 0))) + return 0; + + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, type))) + goto err; + + if (type == OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED) + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, C_BIDI_ID(0)))) + goto err; + + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, 0xFFFFFF)) + || !TEST_true(WPACKET_get_total_written(&wpkt, &written)) + || !radix_fault_prepend_frame(fault, frame_buf, written)) + goto err; + + ok = 1; +err: + if (ok) + WPACKET_finish(&wpkt); + else + WPACKET_cleanup(&wpkt); + return ok; +} + +DEF_SCRIPT(script_52, "Fault injection - ignore BLOCKED frames with bogus values") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_52_inject_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_DATA_BLOCKED); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + OP_READ_EXPECT(C, "orange", 6); + + OP_WRITE(C, "Strawberry", 10); + OP_READ_EXPECT(Sa, "Strawberry", 10); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_STREAM_DATA_BLOCKED); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + OP_READ_EXPECT(C, "orange", 6); + + OP_WRITE(C, "Strawberry", 10); + OP_READ_EXPECT(Sa, "Strawberry", 10); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_UNI); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + OP_READ_EXPECT(C, "orange", 6); + + OP_WRITE(C, "Strawberry", 10); + OP_READ_EXPECT(Sa, "Strawberry", 10); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, OSSL_QUIC_FRAME_TYPE_STREAMS_BLOCKED_BIDI); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + OP_READ_EXPECT(C, "orange", 6); + + OP_WRITE(C, "Strawberry", 10); + OP_READ_EXPECT(Sa, "Strawberry", 10); +} + +/* 53. Fault injection - excess CRYPTO buffer size */ +static int script_53_inject_plain(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len) +{ + int ok = 0; + size_t written; + WPACKET wpkt; + uint64_t offset = 0, data_len = 100; + unsigned char *frame_buf = NULL; + size_t frame_len, i; + + if (fault->word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) + return 1; + + fault->word0 = 0; + + switch (fault->word1) { + case 0: + /* + * Far out offset which will not have been reached during handshake. + * This will not be delivered to the QUIC_TLS instance since it will be + * waiting for in-order delivery of previous bytes. This tests our flow + * control on CRYPTO stream buffering. + */ + offset = 100000; + data_len = 1; + break; + } + + frame_len = 1 + 8 + 8 + (size_t)data_len; + if (!TEST_ptr(frame_buf = OPENSSL_malloc(frame_len))) + return 0; + + if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, frame_len, 0)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, OSSL_QUIC_FRAME_TYPE_CRYPTO)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, offset)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, data_len))) + goto err; + + for (i = 0; i < data_len; ++i) + if (!TEST_true(WPACKET_put_bytes_u8(&wpkt, 0x42))) + goto err; + + if (!TEST_true(WPACKET_get_total_written(&wpkt, &written)) + || !radix_fault_prepend_frame(fault, frame_buf, written)) + goto err; + + ok = 1; +err: + if (ok) + WPACKET_finish(&wpkt); + else + WPACKET_cleanup(&wpkt); + OPENSSL_free(frame_buf); + return ok; +} + +DEF_SCRIPT(script_53, "Fault injection - excess CRYPTO buffer size") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_53_inject_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, 0); + OP_WRITE(Sa, "Strawberry", 10); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_CRYPTO_BUFFER_EXCEEDED, 0, 0); +} + +/* 54. Fault injection - corrupted crypto stream data */ +static int script_54_inject_handshake(RADIX_FAULT *fault, unsigned char *buf, + size_t buf_len) +{ + size_t i; + + for (i = 0; i < buf_len; ++i) + buf[i] ^= 0xff; + + return 1; +} + +/* + * The corrupted connection's channel does not exist until the client's + * Initial packet is accepted, by which point the server's first handshake + * flight has already been generated. So instead of arming the handshake + * mutator on an already-accepted connection (too late for this test), a + * client_hello callback is used to install it as soon as the ClientHello is + * processed, before any response is generated. + */ +static int script_54_client_hello_cb(SSL *s, int *al, void *arg) +{ + return ossl_statem_set_mutator(s, radix_fault_handshake_mutate, + radix_fault_handshake_finish, &radix_fault); +} + +DEF_FUNC(new_listener_54) +{ + int ok = 0; + SSL_CTX *ctx = NULL; + SSL *listener = NULL; + const char *name; + + F_POP(name); + + if (!TEST_ptr(ctx = SSL_CTX_new(OSSL_QUIC_server_method()))) + goto err; + +#if defined(OPENSSL_THREADS) + if (!TEST_true(SSL_CTX_set_domain_flags(ctx, + SSL_DOMAIN_FLAG_MULTI_THREAD + | SSL_DOMAIN_FLAG_BLOCKING))) + goto err; +#endif + + if (!TEST_true(ssl_ctx_configure(ctx, 1))) + goto err; + + SSL_CTX_set_client_hello_cb(ctx, script_54_client_hello_cb, NULL); + + if (!TEST_ptr(listener = SSL_new_listener(ctx, 0)) + || !TEST_true(ssl_attach_bio_dgram(listener, 0, NULL)) + || !TEST_true(RADIX_PROCESS_set_ssl(RP(), name, listener))) { + SSL_free(listener); + goto err; + } + + ok = 1; +err: + /* SSL object will hold ref, we don't need it */ + SSL_CTX_free(ctx); + return ok; +} + +DEF_SCRIPT(script_54, "Fault injection - corrupted crypto stream data") +{ + OP_SET_INJECT_HANDSHAKE_CB(script_54_inject_handshake); + + OP_PUSH_PZ("L"); + OP_FUNC(new_listener_54); + OP_LISTEN(L); + OP_NEW_SSL_C(C); + OP_SET_PEER_ADDR_FROM(C, L); + + OP_CONNECT_WAIT_OR_FAIL(C); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_CRYPTO_UNEXPECTED_MESSAGE, 0, 0); +} + +/* 55. Fault injection - NEW_CONN_ID with >20 byte CID */ +DEF_SCRIPT(script_55, "Fault injection - NEW_CONN_ID with >20 byte CID") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_new_conn_id_plain); + + OP_NEW_STREAM(C, Ca, 0 /* bidirectional */); + OP_WRITE(Ca, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(0, 2); + OP_WRITE(Sa, "orange", 5); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0); +} + +/* 56. Fault injection - NEW_CONN_ID with seq no < retire prior to */ +DEF_SCRIPT(script_56, "Fault injection - NEW_CONN_ID with seq no < retire prior to") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_new_conn_id_plain); + + OP_NEW_STREAM(C, Ca, 0 /* bidirectional */); + OP_WRITE(Ca, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(0, 3); + OP_WRITE(Sa, "orange", 5); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_FRAME_ENCODING_ERROR, 0, 0); +} + +/* 57. Fault injection - NEW_CONN_ID with lower seq so ignored */ +DEF_SCRIPT(script_57, "Fault injection - NEW_CONN_ID with lower seq so ignored") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_new_conn_id_plain); + + OP_NEW_STREAM(C, Ca, 0 /* bidirectional */); + OP_WRITE(Ca, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(0, 4); + OP_WRITE(Sa, "orange", 5); + OP_ENGINE_TICK_ENABLE(S); + OP_READ_EXPECT(Ca, "orange", 5); + + OP_WRITE(Ca, "Strawberry", 10); + OP_READ_EXPECT(Sa, "Strawberry", 10); + + /* + * Now we send a NEW_CONN_ID with a bogus CID. However the sequence number + * is old so it should be ignored and we should still be able to + * communicate. + */ + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(0, 5); + OP_WRITE(Sa, "raspberry", 9); + OP_ENGINE_TICK_ENABLE(S); + OP_READ_EXPECT(Ca, "raspberry", 9); + + OP_WRITE(Ca, "peach", 5); + OP_READ_EXPECT(Sa, "peach", 5); +} + +/* 58. Fault injection - repeated HANDSHAKE_DONE */ +static int script_58_inject_plain(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len) +{ + int ok = 0; + unsigned char frame_buf[64]; + size_t written; + WPACKET wpkt; + + if (fault->word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) + return 1; + + if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, + sizeof(frame_buf), 0))) + return 0; + + if (fault->word0 == 1) { + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, OSSL_QUIC_FRAME_TYPE_HANDSHAKE_DONE))) + goto err; + } else { + /* Needless multi-byte encoding */ + if (!TEST_true(WPACKET_put_bytes_u8(&wpkt, 0x40)) + || !TEST_true(WPACKET_put_bytes_u8(&wpkt, 0x1E))) + goto err; + } + + if (!TEST_true(WPACKET_get_total_written(&wpkt, &written)) + || !radix_fault_prepend_frame(fault, frame_buf, written)) + goto err; + + ok = 1; +err: + if (ok) + WPACKET_finish(&wpkt); + else + WPACKET_cleanup(&wpkt); + return ok; +} + +DEF_SCRIPT(script_58, "Fault injection - repeated HANDSHAKE_DONE") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_58_inject_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(1, 0); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + OP_READ_EXPECT(C, "orange", 6); + + OP_WRITE(C, "Strawberry", 10); + OP_READ_EXPECT(Sa, "Strawberry", 10); +} + +/* 59. Fault injection - multi-byte frame encoding */ +DEF_SCRIPT(script_59, "Fault injection - multi-byte frame encoding") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_58_inject_plain); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(2, 0); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_PROTOCOL_VIOLATION, 0, 0); +} + +/* 60. Connection close reason truncation */ +static char long_reason_60[2048]; + +DEF_FUNC(init_reason_60) +{ + memset(long_reason_60, '~', sizeof(long_reason_60)); + memcpy(long_reason_60, "This is a long reason string.", 29); + long_reason_60[OSSL_NELEM(long_reason_60) - 1] = '\0'; + return 1; +} + +DEF_FUNC(check_shutdown_reason_60) +{ + int ok = 0; + SSL *ssl; + QUIC_CHANNEL *ch; + const QUIC_TERMINATE_CAUSE *tc; + + REQUIRE_SSL(ssl); + ch = ossl_quic_conn_get_channel(ssl); + if (!TEST_ptr(ch)) + goto err; + + tc = ossl_quic_channel_get_terminate_cause(ch); + if (tc == NULL) + F_SPIN_AGAIN(); + + if (!TEST_size_t_ge(tc->reason_len, 50) + || !TEST_mem_eq(long_reason_60, tc->reason_len, + tc->reason, tc->reason_len)) + goto err; + + ok = 1; +err: + return ok; +} + +DEF_SCRIPT(script_60, "Connection close reason truncation") +{ + OP_SIMPLE_PAIR_CONN(); + OP_ACCEPT_CONN_WAIT(L, S, 0); + + OP_WRITE(C, "apple", 5); + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_FUNC(init_reason_60); + OP_SHUTDOWN_WAIT(C, 0, 0, long_reason_60); + OP_SELECT_SSL(0, S); + OP_FUNC(check_shutdown_reason_60); +} + +/* 61. Fault injection - RESET_STREAM exceeding stream count FC */ +static int script_61_inject_plain(RADIX_FAULT *fault, QUIC_PKT_HDR *hdr, + unsigned char *buf, size_t len) +{ + int ok = 0; + WPACKET wpkt; + unsigned char frame_buf[32]; + size_t written; + + if (fault->word0 == 0 || hdr->type != QUIC_PKT_TYPE_1RTT) + return 1; + + if (!TEST_true(WPACKET_init_static_len(&wpkt, frame_buf, + sizeof(frame_buf), 0))) + return 0; + + if (!TEST_true(WPACKET_quic_write_vlint(&wpkt, fault->word0)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, /* stream ID */ + fault->word1)) + || !TEST_true(WPACKET_quic_write_vlint(&wpkt, 123)) + || (fault->word0 == OSSL_QUIC_FRAME_TYPE_RESET_STREAM + && !TEST_true(WPACKET_quic_write_vlint(&wpkt, 0)))) /* final size */ + goto err; + + if (!TEST_true(WPACKET_get_total_written(&wpkt, &written)) + || !radix_fault_prepend_frame(fault, frame_buf, written)) + goto err; + + ok = 1; +err: + if (ok) + WPACKET_finish(&wpkt); + else + WPACKET_cleanup(&wpkt); + return ok; +} + +DEF_SCRIPT(script_61, "Fault injection - RESET_STREAM exceeding stream count FC") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_61_inject_plain); + + OP_NEW_STREAM(C, Ca, 0 /* bidirectional */); + OP_WRITE(Ca, "orange", 6); + + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "orange", 6); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(OSSL_QUIC_FRAME_TYPE_RESET_STREAM, S_BIDI_ID(OSSL_QUIC_VLINT_MAX / 4)); + OP_WRITE(Sa, "fruit", 5); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_STREAM_LIMIT_ERROR, 0, 0); +} + +/* 62. Fault injection - STOP_SENDING with high ID */ +DEF_SCRIPT(script_62, "Fault injection - STOP_SENDING with high ID") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, script_61_inject_plain); + + OP_NEW_STREAM(C, Ca, 0 /* bidirectional */); + OP_WRITE(Ca, "orange", 6); + + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "orange", 6); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(OSSL_QUIC_FRAME_TYPE_STOP_SENDING, C_BIDI_ID(OSSL_QUIC_VLINT_MAX / 4)); + OP_WRITE(Sa, "fruit", 5); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_STREAM_STATE_ERROR, 0, 0); +} + +/* 63. Fault injection - STREAM frame exceeding stream limit */ +DEF_SCRIPT(script_63, "Fault injection - STREAM frame exceeding stream limit") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_stream_data_frame_plain); + + OP_NEW_STREAM(C, Ca, 0 /* bidirectional */); + OP_WRITE(Ca, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(S, Sa, 0); + OP_READ_EXPECT(Sa, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(S_BIDI_ID(5000) + 1, 4); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + + OP_EXPECT_CONN_CLOSE_INFO(C, OSSL_QUIC_ERR_STREAM_LIMIT_ERROR, 0, 0); +} + +/* 64. Fault injection - STREAM - zero-length no-FIN is accepted */ +DEF_SCRIPT(script_64, "Fault injection - STREAM - zero-length no-FIN is accepted") +{ + OP_SIMPLE_PAIR_CONN_ND(); + OP_ACCEPT_CONN_WAIT_ND(L, S, 0); + + OP_SET_INJECT_PLAIN(S, inject_stream_data_frame_plain); + + OP_NEW_STREAM(S, Sa, SSL_STREAM_FLAG_UNI); + OP_WRITE(Sa, "apple", 5); + + OP_ACCEPT_STREAM_WAIT(C, Ca, 0); + OP_READ_EXPECT(Ca, "apple", 5); + + OP_ENGINE_TICK_DISABLE(S); + OP_SET_INJECT_WORD(S_BIDI_ID(20) + 1, 1); + OP_WRITE(Sa, "orange", 6); + OP_ENGINE_TICK_ENABLE(S); + OP_READ_EXPECT(Ca, "orange", 6); } DEF_SCRIPT(script_65, "place holder for multistrem script_65") @@ -1468,12 +3888,15 @@ DEF_SCRIPT(script_106, "place holder for multistrem script_106") static SCRIPT_INFO *const scripts[] = { USE(simple_stream), USE(multi_stream), + USE(reject_before_default_stream), USE(simple_conn), USE(simple_thread), USE(ssl_poll), + USE(poll_abort_blocking), USE(check_cwm), USE(check_pc_flood), USE(check_ctx_cbks), + USE(check_thread_assisted_idle), USE(script_5), USE(script_6), USE(script_7), diff --git a/test/radix/terp.c b/test/radix/terp.c index a89367ce1fc41..ed415fa62928d 100644 --- a/test/radix/terp.c +++ b/test/radix/terp.c @@ -1,5 +1,5 @@ /* - * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/rand_strict.cnf b/test/rand_strict.cnf new file mode 100644 index 0000000000000..4ac3458354540 --- /dev/null +++ b/test/rand_strict.cnf @@ -0,0 +1,8 @@ +openssl_conf = openssl_init + +[openssl_init] +random = random_section + +[random_section] +seed = TEST-RAND +seed_strict = yes diff --git a/test/rand_test.c b/test/rand_test.c index 5b2270cb4e0b9..de46c99906cc1 100644 --- a/test/rand_test.c +++ b/test/rand_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the >License>). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,7 +7,16 @@ * https://www.openssl.org/source/license.html */ +#ifdef _WIN32 +#include +#endif + #include +#include +#include +#include +#include +#include #include #include #include @@ -16,6 +25,7 @@ #include "testutil.h" static char *configfile; +static char *strictconfigfile; static int test_rand(void) { @@ -104,6 +114,50 @@ static int test_rand_uniform(void) return res; } +/* + * Check that creating the primary DRBG creates the seed source and + * stores it in the library context: later users must keep getting the + * same instance and no replacement may be created. + */ +static int test_rand_primary_seed_stored(void) +{ + OSSL_LIB_CTX *ctx = NULL; + EVP_RAND_CTX *seed; + unsigned char buf[16]; + int ok, res = 0; + + if (!TEST_ptr(ctx = OSSL_LIB_CTX_new()) + || !TEST_ptr_null(ossl_rand_get0_seed_noncreating(ctx))) + goto err; + + /* The default seed source may be unavailable in some configurations */ + ERR_set_mark(); + ok = RAND_bytes_ex(ctx, buf, sizeof(buf), 0) > 0; + ERR_pop_to_mark(); + if (!ok) { + TEST_info("skipped: cannot instantiate the primary DRBG"); + res = 1; + goto err; + } + + seed = ossl_rand_get0_seed_noncreating(ctx); + if (seed == NULL) { + /* The seed source silently fell back to operating system entropy */ + TEST_info("skipped: no seed source was created"); + res = 1; + goto err; + } + + if (!TEST_int_gt(RAND_bytes_ex(ctx, buf, sizeof(buf), 0), 0) + || !TEST_ptr_eq(ossl_rand_get0_seed_noncreating(ctx), seed)) + goto err; + + res = 1; +err: + OSSL_LIB_CTX_free(ctx); + return res; +} + /* Test the FIPS health tests */ static int fips_health_test_one(const uint8_t *buf, size_t n, size_t gen) { @@ -275,6 +329,516 @@ static int test_rand_get0_primary(void) return res; } +/* + * Create a parentless DRBG in a provider: instantiating it requests + * seeding material through the core's get_user_entropy and + * get_user_nonce callbacks, the same path the FIPS provider uses. + */ +static EVP_RAND_CTX *provider_side_drbg(OSSL_LIB_CTX *ctx) +{ + EVP_RAND *rand; + EVP_RAND_CTX *rctx; + + if (!TEST_ptr(rand = EVP_RAND_fetch(ctx, "CTR-DRBG", NULL))) + return NULL; + rctx = EVP_RAND_CTX_new(rand, NULL); + EVP_RAND_free(rand); + return rctx; +} + +static int provider_side_drbg_instantiate(EVP_RAND_CTX *rctx) +{ + OSSL_PARAM params[2]; + + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_DRBG_PARAM_CIPHER, + (char *)"AES-256-CTR", 0); + params[1] = OSSL_PARAM_construct_end(); + return EVP_RAND_instantiate(rctx, 0, 0, NULL, 0, params); +} + +/* + * Regression test for #25941: with strict seeding the configured seed + * source must be instantiated on demand and used when a provider + * requests seeding material before anything else created it, instead of + * being silently replaced by the operating system entropy sources. + */ +static int test_rand_seed_source_strict(void) +{ +#ifndef OPENSSL_NO_FIPS_JITTER + TEST_info("skipped: enable-fips-jitter forces the JITTER seed source"); + return 1; +#else + OSSL_LIB_CTX *ctx = NULL; + EVP_RAND_CTX *drbg = NULL, *seed; + unsigned char entropy[64], buf[16]; + OSSL_PARAM params[3]; + int generate = 1, res = 0; + size_t i; + + for (i = 0; i < sizeof(entropy); i++) + entropy[i] = 0xff & (i + 1); + + /* The config configures TEST-RAND as the seed source and seed_strict */ + if (!TEST_ptr(ctx = OSSL_LIB_CTX_new()) + || !TEST_true(OSSL_LIB_CTX_load_config(ctx, strictconfigfile))) + goto err; + + /* + * The first seeding request must fail: the configured TEST-RAND has + * no entropy to hand out yet and falling back to the operating + * system sources would defeat the configuration. + */ + if (!TEST_ptr(drbg = provider_side_drbg(ctx))) + goto err; + ERR_set_mark(); + if (!TEST_false(provider_side_drbg_instantiate(drbg))) { + ERR_clear_last_mark(); + goto err; + } + ERR_pop_to_mark(); + EVP_RAND_CTX_free(drbg); + drbg = NULL; + + /* The request must have instantiated the configured seed source */ + if (!TEST_ptr(seed = ossl_rand_get0_seed_noncreating(ctx)) + || !TEST_str_eq(EVP_RAND_get0_name(EVP_RAND_CTX_get0_rand(seed)), + "TEST-RAND")) + goto err; + + /* Provision the seed source and check that it feeds the DRBG */ + params[0] = OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY, + entropy, sizeof(entropy)); + params[1] = OSSL_PARAM_construct_int(OSSL_RAND_PARAM_GENERATE, &generate); + params[2] = OSSL_PARAM_construct_end(); + if (!TEST_true(EVP_RAND_CTX_set_params(seed, params)) + || !TEST_ptr(drbg = provider_side_drbg(ctx)) + || !TEST_true(provider_side_drbg_instantiate(drbg)) + || !TEST_true(EVP_RAND_generate(drbg, buf, sizeof(buf), 0, 0, + NULL, 0))) + goto err; + + res = 1; +err: + EVP_RAND_CTX_free(drbg); + OSSL_LIB_CTX_free(ctx); + return res; +#endif /* OPENSSL_NO_FIPS_JITTER */ +} + +/* + * Verify that a provider requesting seeding material keeps the fallback + * behaviour without strict seeding: the request falls back to the + * operating system sources without instantiating the seed source, even + * when one was configured, so a later RAND_set_seed_source_type() call + * still succeeds. In enable-fips-jitter builds seeding is always + * strict and the request instantiates the seed source instead. + */ +static int test_rand_seed_source_nonstrict(void) +{ + OSSL_LIB_CTX *ctx = NULL; + EVP_RAND_CTX *drbg = NULL; + int ok, res = 0; + + if (!TEST_ptr(ctx = OSSL_LIB_CTX_new())) + goto err; + + if (ossl_rand_seed_source_strict(ctx)) { + /* enable-fips-jitter build: the JITTER seed source is hard-wired */ + if (!TEST_ptr(drbg = provider_side_drbg(ctx))) + goto err; + ERR_set_mark(); + ok = provider_side_drbg_instantiate(drbg); + ERR_pop_to_mark(); + /* The seed source may be unusable in this configuration */ + if (ok + && (!TEST_ptr(ossl_rand_get0_seed_noncreating(ctx)) + || !TEST_false(RAND_set_seed_source_type(ctx, "TEST-RAND", + NULL)))) + goto err; + } else { +#ifdef OPENSSL_RAND_SEED_NONE + TEST_info("skipped: no operating system entropy sources"); +#else + /* Strict seeding is implied when the JITTER source is selected */ + if (!TEST_true(RAND_set_seed_source_type(ctx, "JITTER", NULL)) + || !TEST_true(ossl_rand_seed_source_strict(ctx)) + || !TEST_true(RAND_set_seed_source_type(ctx, NULL, NULL)) + || !TEST_false(ossl_rand_seed_source_strict(ctx))) + goto err; + + if (!TEST_ptr(drbg = provider_side_drbg(ctx)) + || !TEST_true(provider_side_drbg_instantiate(drbg)) + || !TEST_ptr_null(ossl_rand_get0_seed_noncreating(ctx)) + || !TEST_true(RAND_set_seed_source_type(ctx, "TEST-RAND", NULL))) + goto err; + EVP_RAND_CTX_free(drbg); + drbg = NULL; + + /* A configured but non-strict seed source still falls back */ + if (!TEST_ptr(drbg = provider_side_drbg(ctx)) + || !TEST_true(provider_side_drbg_instantiate(drbg)) + || !TEST_ptr_null(ossl_rand_get0_seed_noncreating(ctx))) + goto err; +#endif /* OPENSSL_RAND_SEED_NONE */ + } + + res = 1; +err: + EVP_RAND_CTX_free(drbg); + OSSL_LIB_CTX_free(ctx); + return res; +} + +#ifdef OPENSSL_NO_FIPS_JITTER +typedef struct { + const OSSL_CORE_HANDLE *handle; + OSSL_LIB_CTX *libctx; + OSSL_FUNC_get_user_entropy_fn *entropy; + OSSL_FUNC_cleanup_user_entropy_fn *clear_entropy; + int pause_instances; + int recurse_instance; + int direct_recurse; + int started; + int completed; + int seed_calls; + int recursive_error; +} ASYNC_SEED_PROBE; + +typedef struct { + ASYNC_SEED_PROBE *probe; + int instance; + int ready; +} ASYNC_SEED; + +static ASYNC_SEED_PROBE *async_seed_probe; + +static size_t async_seed_request_entropy(ASYNC_SEED_PROBE *probe) +{ + unsigned char sentinel, *out = &sentinel; + size_t len; + + len = probe->entropy(probe->handle, &out, 128, 16, 32); + if (len > 0 && out != NULL && out != &sentinel) + probe->clear_entropy(probe->handle, out, len); + return len; +} + +static void *async_seed_newctx(void *vprobe, void *parent, + const OSSL_DISPATCH *dispatch) +{ + ASYNC_SEED *seed = OPENSSL_zalloc(sizeof(*seed)); + + if (seed != NULL) + seed->probe = vprobe; + return seed; +} + +static void async_seed_freectx(void *vseed) +{ + OPENSSL_free(vseed); +} + +static int async_seed_instantiate(void *vseed, unsigned int strength, + int prediction_resistance, const unsigned char *personalisation, + size_t personalisation_len, const OSSL_PARAM params[]) +{ + ASYNC_SEED *seed = vseed; + ASYNC_SEED_PROBE *probe = seed->probe; + size_t len; + + seed->instance = ++probe->started; + if (seed->instance <= probe->pause_instances) { + if (!ASYNC_pause_job()) + return 0; + } + + if (seed->instance == probe->recurse_instance) { + ERR_clear_error(); + if (probe->direct_recurse) { + probe->recursive_error = ossl_rand_get0_seed(probe->libctx) == NULL + && ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_RAND; + } else { + len = async_seed_request_entropy(probe); + probe->recursive_error = len == 0 + && ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_RAND; + } + return 0; + } + + seed->ready = 1; + probe->completed++; + return 1; +} + +static int async_seed_uninstantiate(void *vseed) +{ + ((ASYNC_SEED *)vseed)->ready = 0; + return 1; +} + +static int async_seed_generate(void *vseed, unsigned char *out, size_t len, + unsigned int strength, int prediction_resistance, + const unsigned char *additional_input, size_t additional_input_len) +{ + if (!((ASYNC_SEED *)vseed)->ready) + return 0; + memset(out, 0x5a, len); + return 1; +} + +static int async_seed_get_ctx_params(void *vseed, OSSL_PARAM params[]) +{ + ASYNC_SEED *seed = vseed; + OSSL_PARAM *p; + int state; + + p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STRENGTH); + if (p != NULL && !OSSL_PARAM_set_uint(p, 256)) + return 0; + p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_STATE); + state = seed->ready ? EVP_RAND_STATE_READY : EVP_RAND_STATE_UNINITIALISED; + if (p != NULL && !OSSL_PARAM_set_int(p, state)) + return 0; + p = OSSL_PARAM_locate(params, OSSL_RAND_PARAM_MAX_REQUEST); + if (p != NULL && !OSSL_PARAM_set_size_t(p, 65536)) + return 0; + p = OSSL_PARAM_locate(params, OSSL_DRBG_PARAM_RESEED_COUNTER); + if (p != NULL && !OSSL_PARAM_set_uint(p, 1)) + return 0; + return 1; +} + +static size_t async_seed_get_seed(void *vseed, unsigned char **out, + int entropy, size_t min_len, size_t max_len, + int prediction_resistance, const unsigned char *additional_input, + size_t additional_input_len) +{ + ASYNC_SEED *seed = vseed; + size_t len = (entropy + 7) / 8; + + if (len < min_len) + len = min_len; + if (!seed->ready || len > max_len + || (*out = OPENSSL_malloc(len)) == NULL) + return 0; + seed->probe->seed_calls++; + memset(*out, 0x5a, len); + return len; +} + +static void async_seed_clear_seed(void *vseed, unsigned char *out, size_t len) +{ + OPENSSL_clear_free(out, len); +} + +static const OSSL_DISPATCH async_seed_rand_functions[] = { + { OSSL_FUNC_RAND_NEWCTX, (void (*)(void))async_seed_newctx }, + { OSSL_FUNC_RAND_FREECTX, (void (*)(void))async_seed_freectx }, + { OSSL_FUNC_RAND_INSTANTIATE, (void (*)(void))async_seed_instantiate }, + { OSSL_FUNC_RAND_UNINSTANTIATE, + (void (*)(void))async_seed_uninstantiate }, + { OSSL_FUNC_RAND_GENERATE, (void (*)(void))async_seed_generate }, + { OSSL_FUNC_RAND_GET_CTX_PARAMS, + (void (*)(void))async_seed_get_ctx_params }, + { OSSL_FUNC_RAND_GET_SEED, (void (*)(void))async_seed_get_seed }, + { OSSL_FUNC_RAND_CLEAR_SEED, (void (*)(void))async_seed_clear_seed }, + OSSL_DISPATCH_END +}; + +static const OSSL_ALGORITHM async_seed_algorithms[] = { + { "ASYNC-SEED:JITTER", "provider=async-seed-probe", + async_seed_rand_functions, "ASYNC seed source test" }, + { NULL, NULL, NULL, NULL } +}; + +static const OSSL_ALGORITHM *async_seed_query(void *vprobe, int operation, + int *no_cache) +{ + *no_cache = 0; + return operation == OSSL_OP_RAND ? async_seed_algorithms : NULL; +} + +static const OSSL_DISPATCH async_seed_provider_functions[] = { + { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))async_seed_query }, + OSSL_DISPATCH_END +}; + +static int async_seed_provider_init(const OSSL_CORE_HANDLE *handle, + const OSSL_DISPATCH *in, const OSSL_DISPATCH **out, void **vprobe) +{ + ASYNC_SEED_PROBE *probe = async_seed_probe; + + probe->handle = handle; + for (; in->function_id != 0; in++) { + switch (in->function_id) { + case OSSL_FUNC_GET_USER_ENTROPY: + probe->entropy = OSSL_FUNC_get_user_entropy(in); + break; + case OSSL_FUNC_CLEANUP_USER_ENTROPY: + probe->clear_entropy = OSSL_FUNC_cleanup_user_entropy(in); + break; + } + } + *vprobe = probe; + *out = async_seed_provider_functions; + return probe->entropy != NULL && probe->clear_entropy != NULL; +} + +static int async_seed_rand_job(void *vctx) +{ + OSSL_LIB_CTX *ctx = *(OSSL_LIB_CTX **)vctx; + + return RAND_get0_primary(ctx) != NULL; +} + +/* + * A paused ASYNC job must not make an independent job, or code running + * outside ASYNC on the same thread, look like recursive seed construction. + * If two jobs pause, each construction marker must survive until its own job + * resumes; a real recursive request by either job must still be rejected. + */ +static int test_rand_seed_source_async(int idx) +{ + ASYNC_SEED_PROBE probe = { 0 }; + OSSL_LIB_CTX *ctx = NULL; + OSSL_PROVIDER *custom = NULL, *def = NULL; + ASYNC_JOB *a = NULL, *b = NULL; + ASYNC_WAIT_CTX *wa = NULL, *wb = NULL; + unsigned char out; + int ra = -1, rb = -1, sa = ASYNC_ERR, sb = ASYNC_ERR; + int async_started = 0, res = 0; + + probe.pause_instances = idx == 2 ? 2 : 1; + probe.recurse_instance = idx == 2 ? 1 : 0; + async_seed_probe = &probe; + if (!TEST_ptr(ctx = OSSL_LIB_CTX_new()) + || !TEST_true(OSSL_PROVIDER_add_builtin(ctx, "async-seed-probe", + async_seed_provider_init)) + || !TEST_ptr(custom = OSSL_PROVIDER_load(ctx, "async-seed-probe")) + || !TEST_ptr(def = OSSL_PROVIDER_load(ctx, "default")) + || !TEST_true(RAND_set_seed_source_type(ctx, + idx == 1 ? "ASYNC-SEED" : "JITTER", + "provider=async-seed-probe"))) + goto err; + if (!ASYNC_is_capable()) { + TEST_info("skipped: ASYNC jobs are unavailable"); + res = 1; + goto err; + } + if (!TEST_true(ASYNC_init_thread(2, 2))) + goto err; + async_started = 1; + if (!TEST_ptr(wa = ASYNC_WAIT_CTX_new()) + || !TEST_ptr(wb = ASYNC_WAIT_CTX_new())) + goto err; + + ERR_clear_error(); + sa = ASYNC_start_job(&a, wa, &ra, async_seed_rand_job, &ctx, sizeof(ctx)); + if (!TEST_int_eq(sa, ASYNC_PAUSE) + || !TEST_int_eq(probe.started, 1) + || !TEST_int_eq(probe.completed, 0)) + goto err; + + if (idx == 3) { + if (!TEST_true(RAND_bytes_ex(ctx, &out, sizeof(out), 0)) + || !TEST_int_eq(probe.started, 2) + || !TEST_int_eq(probe.completed, 1) + || !TEST_int_gt(probe.seed_calls, 0)) + goto err; + } else { + sb = ASYNC_start_job(&b, wb, &rb, async_seed_rand_job, &ctx, + sizeof(ctx)); + if (!TEST_int_eq(sb, idx == 2 ? ASYNC_PAUSE : ASYNC_FINISH) + || !TEST_int_eq(probe.started, 2)) + goto err; + if (idx != 2 + && (!TEST_int_eq(rb, 1) + || !TEST_int_eq(probe.completed, 1) + || !TEST_int_gt(probe.seed_calls, 0))) + goto err; + } + + sa = ASYNC_start_job(&a, wa, &ra, async_seed_rand_job, &ctx, sizeof(ctx)); + if (!TEST_int_eq(sa, ASYNC_FINISH)) + goto err; + if (idx == 2) { + if (!TEST_int_eq(ra, 0) + || !TEST_true(probe.recursive_error) + || !TEST_int_eq(probe.started, 2) + || !TEST_int_eq(probe.completed, 0)) + goto err; + ERR_clear_error(); + sb = ASYNC_start_job(&b, wb, &rb, async_seed_rand_job, &ctx, + sizeof(ctx)); + if (!TEST_int_eq(sb, ASYNC_FINISH) + || !TEST_int_eq(rb, 1) + || !TEST_int_eq(probe.started, 2) + || !TEST_int_eq(probe.completed, 1) + || !TEST_int_gt(probe.seed_calls, 0)) + goto err; + } else if (!TEST_int_eq(ra, 1) + || !TEST_int_eq(probe.started, 2) + || !TEST_int_eq(probe.completed, 2)) { + goto err; + } + + res = 1; +err: + if (a != NULL) + ASYNC_start_job(&a, wa, &ra, async_seed_rand_job, &ctx, sizeof(ctx)); + if (b != NULL) + ASYNC_start_job(&b, wb, &rb, async_seed_rand_job, &ctx, sizeof(ctx)); + ASYNC_WAIT_CTX_free(wa); + ASYNC_WAIT_CTX_free(wb); + if (async_started) + ASYNC_cleanup_thread(); + OSSL_PROVIDER_unload(def); + OSSL_PROVIDER_unload(custom); + OSSL_LIB_CTX_free(ctx); + async_seed_probe = NULL; + return res; +} + +static int test_rand_seed_source_recursive_error(void) +{ + ASYNC_SEED_PROBE probe = { 0 }; + OSSL_LIB_CTX *ctx = NULL; + OSSL_PROVIDER *custom = NULL, *def = NULL; + unsigned char out; + int res = 0; + + probe.recurse_instance = 1; + probe.direct_recurse = 1; + async_seed_probe = &probe; + if (!TEST_ptr(ctx = OSSL_LIB_CTX_new())) + goto err; + probe.libctx = ctx; + if (!TEST_true(OSSL_PROVIDER_add_builtin(ctx, "async-seed-probe", + async_seed_provider_init)) + || !TEST_ptr(custom = OSSL_PROVIDER_load(ctx, "async-seed-probe")) + || !TEST_ptr(def = OSSL_PROVIDER_load(ctx, "default")) + || !TEST_true(RAND_set_seed_source_type(ctx, "ASYNC-SEED", + "provider=async-seed-probe"))) + goto err; + + ERR_clear_error(); + if (!TEST_false(RAND_bytes_ex(ctx, &out, sizeof(out), 0)) + || !TEST_true(probe.recursive_error) + || !TEST_int_eq(probe.started, 1) + || !TEST_int_eq(probe.completed, 0) + || !TEST_ulong_ne(ERR_peek_error(), 0)) + goto err; + + res = 1; +err: + OSSL_PROVIDER_unload(def); + OSSL_PROVIDER_unload(custom); + OSSL_LIB_CTX_free(ctx); + async_seed_probe = NULL; + return res; +} +#endif /* OPENSSL_NO_FIPS_JITTER */ + /* Warm up the DRBG cipher fetch caches outside the mfail injection window */ static int rand_drbg_fetch_warmup(EVP_RAND *drbg_alg) { @@ -419,6 +983,7 @@ int setup_tests(void) } if (!TEST_ptr(configfile = test_get_argument(0)) + || !TEST_ptr(strictconfigfile = test_get_argument(1)) || !TEST_true(RAND_set_DRBG_type(NULL, "TEST-RAND", "fips=no", NULL, NULL)) || (fips_provider_version_ge(NULL, 3, 0, 8) @@ -427,6 +992,7 @@ int setup_tests(void) ADD_TEST(test_rand); ADD_TEST(test_rand_uniform); + ADD_TEST(test_rand_primary_seed_stored); if (OSSL_PROVIDER_available(NULL, "fips") && fips_provider_version_ge(NULL, 3, 4, 0)) @@ -438,6 +1004,13 @@ int setup_tests(void) || fips_provider_version_ge(NULL, 3, 5, 1)) ADD_TEST(test_rand_get0_primary); + ADD_TEST(test_rand_seed_source_strict); + ADD_TEST(test_rand_seed_source_nonstrict); +#ifdef OPENSSL_NO_FIPS_JITTER + ADD_ALL_TESTS(test_rand_seed_source_async, 4); + ADD_TEST(test_rand_seed_source_recursive_error); +#endif + ADD_MFAIL_ALL_TESTS(test_rand_bytes_mfail, 2); ADD_MFAIL_TEST(test_rand_seed_src_mfail); ADD_MFAIL_TEST(test_rand_drbg_mfail); diff --git a/test/rdcpu_sanitytest.c b/test/rdcpu_sanitytest.c index 47c2ea71ca67e..086301740484b 100644 --- a/test/rdcpu_sanitytest.c +++ b/test/rdcpu_sanitytest.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/01-test_generated_ignored.t b/test/recipes/01-test_generated_ignored.t new file mode 100644 index 0000000000000..09d2cd050ef96 --- /dev/null +++ b/test/recipes/01-test_generated_ignored.t @@ -0,0 +1,205 @@ +#! /usr/bin/env perl +# -*- mode: Perl -*- +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use File::Spec::Functions qw(catfile splitdir); +use IPC::Cmd; +use OpenSSL::Test qw(:DEFAULT bldtop_dir srctop_dir); + +use constant MAX_REPORTED => 10; # Longer lists are truncated +use constant CANARY => 'configdata.pm'; # Always present, always ignored + +BEGIN { + setup("test_generated_ignored"); +} + +use lib bldtop_dir('.'); +use configdata; + +# Every file the build generates must be absent from the index and covered +# by .gitignore. The generated files that are deliberately committed -- +# doc/build.info, util/libcrypto.num and the like -- come from explicit +# "make update" targets rather than GENERATE directives, so they are not +# among the targets checked here. + +plan skip_all => "This test requires git" + unless IPC::Cmd::can_run('git'); +# Release tarballs are unpacked archives with no repository. .git is a +# directory in an ordinary clone and a file in a linked worktree. +plan skip_all => "This test requires a git checkout" + unless -e catfile(srctop_dir(), '.git'); +# The targets are judged by git's answer to an ignore query, so a query +# whose answer is known is made first. configdata.pm is covered by the +# committed .gitignore, and this recipe has read it out of the build tree +# already. The query goes through ignore_faults(), the same path the +# targets take, and so covers running git, parsing what it prints, and +# finding the matching rule's source tracked. Only an ignored verdict for +# it makes the verdicts on the targets worth anything; short of that the +# recipe skips. +my %canary_fault = eval { ignore_faults(CANARY) }; + +if ($@) { + my $reason = $@; + + chomp $reason; + plan skip_all => "git cannot answer ignore queries: $reason"; +} + +plan skip_all => "git does not report " . CANARY . " as ignored" + if %canary_fault; + +# The targets are native paths relative to the build tree; git speaks only +# in forward slashes. splitdir() knows the local separator, so splitting +# and rejoining converts them without naming it. +my @targets = sort map { join('/', splitdir($_)) } + keys %{ $unified_info{generate} }; + +plan skip_all => "This build configuration generates no files" + unless @targets; + +plan tests => 2; + +note "Checking ", scalar @targets, " generated files"; + +my %tracked = map { $_ => 1 } git_run('ls-files'); +my %why = ignore_faults(@targets); +my @committed = grep { $tracked{$_} } @targets; +my @unignored = grep { exists $why{$_} } @targets; + +ok(!@committed, "no generated file is tracked in git") + or report_tracked(@committed); +ok(!@unignored, "every generated file is in .gitignore") + or report_unignored(\%why, @unignored); + +# Of the given paths, return those .gitignore does not ignore, mapped to an +# explanation, or to the empty string where none is needed. +# +# git draws ignore rules from three places: the .gitignore files in the +# tree, .git/info/exclude, and the file named by core.excludesFile. Only +# the first is committed. A generated file the other two cover is one that +# every other clone is free to commit, so it must fail here. Telling them +# apart needs the rule that matched, which "git check-ignore -v" reports as +# +# ::\t +sub ignore_faults { + my (@paths) = @_; + my %rule_for; + + foreach my $line (git_batched(['check-ignore', '--no-index', '-v'], + \@paths)) { + # A pattern may contain anything but a tab, so the pathname is + # split off from the end. + my ($fields, $path) = $line =~ m|^(.*)\t([^\t]*)$| + or next; + my ($source, $line_no, $pattern) = $fields =~ m|^(.+?):(\d+):(.*)$| + or next; + + $rule_for{$path} = { source => $source, line => $line_no, + pattern => $pattern }; + } + + # An absolute path is core.excludesFile and anything under .git is + # .git/info/exclude. Neither can be tracked, and git rejects them as + # pathspecs, so they are dropped before asking. + my @sources = grep { !m|^([A-Za-z]:)?[\\/]| && !m|^\.git/| } + do { my %seen; + grep { !$seen{$_}++ } map { $_->{source} } + values %rule_for }; + my %tracked_source = map { $_ => 1 } git_batched(['ls-files'], \@sources); + my %why; + + foreach my $path (@paths) { + my $rule = $rule_for{$path}; + + # A path is ignored only if some rule matched it, that rule was not + # a negative one, and the file holding the rule is committed. + next if defined $rule + && $rule->{pattern} !~ m|^!| + && $tracked_source{ $rule->{source} }; + + # Verbose mode reports negative rules too, and those are matches + # that leave the path *not* ignored. They are also the one case + # where the placement of the new entry matters, since an entry + # above the negative rule has no effect. + $why{$path} = defined $rule && $rule->{pattern} =~ m|^!| + ? "because $rule->{source} line $rule->{line}" + . " ($rule->{pattern}) cancels an earlier match - add it to" + . " .gitignore after line $rule->{line}" + : ''; + } + return %why; +} + +# Run a git subcommand in the source tree and return its standard output as +# a list of lines. Both subcommands used here report their answer entirely +# on stdout; git's exit status adds only whether that answer was empty, +# 1 meaning nothing matched, which is an answer and not a failure. Above +# that git is declining to answer -- 129 with a usage message when it is +# too old for the query, 128 for a repository it will not open -- and that +# dies here rather than being read as an empty answer. +sub git_run { + my (@args) = @_; + + open(my $pipe, '-|', 'git', '-c', 'core.quotePath=false', + '-C', srctop_dir(), @args) + or die "Failed to run git @args: $!"; + my @lines = map { s|\R$||; $_ } <$pipe>; + close $pipe; + die "git @args killed by signal " . ($? & 127) . "\n" if $? & 127; + die "git @args exited with status " . ($? >> 8) . "\n" if ($? >> 8) > 1; + return @lines; +} + +# As git_run(), but with a list of paths to act on. They go in batches: +# the full list runs to a couple of thousand entries, enough to exceed the +# command line length limit on some platforms. +sub git_batched { + my ($subcmd, $paths) = @_; + my $batch = 100; + my @lines; + + for (my $first = 0; $first <= $#$paths; $first += $batch) { + my $last = $first + $batch - 1; + + $last = $#$paths if $last > $#$paths; + push @lines, git_run(@$subcmd, '--', @{$paths}[$first .. $last]); + } + return @lines; +} + +sub report_tracked { + my (@paths) = @_; + + diag scalar @paths, " generated file(s) are committed to the repository", + " and need to be removed:"; + diag " git rm --cached ", $_ foreach shown(@paths); + diag " ... and ", @paths - MAX_REPORTED, " more" if @paths > MAX_REPORTED; +} + +# Paths are shown with a leading "/", the anchored form .gitignore uses for +# generated files. +sub report_unignored { + my ($why, @paths) = @_; + + diag scalar @paths, " generated file(s) are not ignored by .gitignore", + " and need to be added:"; + foreach my $path (shown(@paths)) { + diag " /$path"; + diag " ", $why->{$path} if $why->{$path} ne ''; + } + diag " ... and ", @paths - MAX_REPORTED, " more" if @paths > MAX_REPORTED; +} + +sub shown { + my (@paths) = @_; + + return @paths > MAX_REPORTED ? @paths[0 .. MAX_REPORTED - 1] : @paths; +} diff --git a/test/recipes/01-test_symbol_presence.t b/test/recipes/01-test_symbol_presence.t index 6c8de64b0b322..c1d9c8541f5e7 100644 --- a/test/recipes/01-test_symbol_presence.t +++ b/test/recipes/01-test_symbol_presence.t @@ -1,6 +1,6 @@ #! /usr/bin/env perl # -*- mode: Perl -*- -# Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -26,6 +26,8 @@ plan skip_all => "Test is disabled on NonStop" if config('target') =~ m|^nonstop plan skip_all => "Test is disabled on MacOS" if config('target') =~ m|^darwin|; # AIX reports symbol names differently plan skip_all => "Test is disabled on AIX" if config('target') =~ m|^aix|; +plan skip_all => "This is unsupported on native Windows" + if $^O eq 'MSWin32'; plan skip_all => "This is unsupported on platforms that don't have 'nm'" unless IPC::Cmd::can_run('nm'); @@ -65,9 +67,10 @@ plan tests => $testcount; my %stsymbols; # Static library symbols my %shsymbols; # Shared library symbols my %defsymbols; # Symbols taken from ordinals +my $null_device = devnull(); foreach (sort keys %stlibname) { - my $stlib_cmd = "nm -Pg $stlibpath{$_} 2> /dev/null"; - my $shlib_cmd = "nm -DPg $shlibpath{$_} 2> /dev/null"; + my $stlib_cmd = "nm -Pg $stlibpath{$_} 2> $null_device"; + my $shlib_cmd = "nm -DPg $shlibpath{$_} 2> $null_device"; my @stlib_lines; my @shlib_lines; *OSTDERR = *STDERR; @@ -97,7 +100,7 @@ foreach (sort keys %stlibname) { indir $bldtop => sub { my $mkdefpath = srctop_file("util", "mkdef.pl"); my $def_path = srctop_file("util", "lib$_.num"); - my $def_cmd = "$^X $mkdefpath --ordinals $def_path --name $_ --OS linux 2> /dev/null"; + my $def_cmd = "$^X $mkdefpath --ordinals $def_path --name $_ --OS linux 2> $null_device"; @def_lines = map { s|\R$||; $_ } `$def_cmd`; if ($? != 0) { note "running 'cd $bldtop; $def_cmd' => $?"; diff --git a/test/recipes/02-test_rbtree.t b/test/recipes/02-test_rbtree.t new file mode 100644 index 0000000000000..fb92affda138c --- /dev/null +++ b/test/recipes/02-test_rbtree.t @@ -0,0 +1,11 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use OpenSSL::Test::Simple; + +simple_test("ossl_rbtree_test", "ossl_rbtree_test"); diff --git a/test/recipes/04-test_bio_ndef.t b/test/recipes/04-test_bio_ndef.t new file mode 100644 index 0000000000000..3bb112e17761f --- /dev/null +++ b/test/recipes/04-test_bio_ndef.t @@ -0,0 +1,14 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use OpenSSL::Test::Simple; + +simple_test("test_bio_ndef", "bio_ndef_test"); diff --git a/test/recipes/04-test_encoder_decoder.t b/test/recipes/04-test_encoder_decoder.t index 2acc980e901fc..344a221d38621 100644 --- a/test/recipes/04-test_encoder_decoder.t +++ b/test/recipes/04-test_encoder_decoder.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -25,7 +25,7 @@ my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0); my $rsa_key = srctop_file("test", "certs", "ee-key.pem"); my $pss_key = srctop_file("test", "certs", "ca-pss-key.pem"); -plan tests => ($no_fips ? 0 : 5) + 2; # FIPS install test + test +plan tests => ($no_fips ? 0 : 5) + 3; # FIPS install test + test my $conf = srctop_file("test", "default.cnf"); @@ -45,6 +45,8 @@ sub find_line_file { return 0; } +ok(run(test(["endecode_api_test"]))); + ok(run(test(["endecode_test", "-rsa", $rsa_key, "-pss", $pss_key, "-config", $conf, diff --git a/test/recipes/05-test_rand.t b/test/recipes/05-test_rand.t index d70b65c64928e..28de0094efff1 100644 --- a/test/recipes/05-test_rand.t +++ b/test/recipes/05-test_rand.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -16,12 +16,14 @@ use Cwd qw(abs_path); plan tests => 6; setup("test_rand"); -ok(run(test(["rand_test", srctop_file("test", "default.cnf")]))); +ok(run(test(["rand_test", srctop_file("test", "default.cnf"), + srctop_file("test", "rand_strict.cnf")]))); SKIP: { skip "Skipping FIPS test in this build", 1 if disabled('fips'); - ok(run(test(["rand_test", srctop_file("test", "fips.cnf")]))); + ok(run(test(["rand_test", srctop_file("test", "fips.cnf"), + srctop_file("test", "rand_strict.cnf")]))); } ok(run(test(["drbgtest"]))); diff --git a/test/recipes/15-test_dsa.t b/test/recipes/15-test_dsa.t index 2d16ebd02c082..f8c55fe37e9f5 100644 --- a/test/recipes/15-test_dsa.t +++ b/test/recipes/15-test_dsa.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -11,13 +11,13 @@ use strict; use warnings; use File::Spec; -use OpenSSL::Test qw/:DEFAULT srctop_file/; +use OpenSSL::Test qw/:DEFAULT srctop_file app_fails/; use OpenSSL::Test::Utils; setup("test_dsa"); plan skip_all => 'DSA is not supported in this build' if disabled('dsa'); -plan tests => 10; +plan tests => 12; require_ok(srctop_file('test','recipes','tconversion.pl')); @@ -88,6 +88,85 @@ subtest "dsa -modulus prints the DSA public value" => sub { "-modulus prints the expected public value for a public key"); }; +subtest "dsa -text prints the key in text form" => sub { + plan tests => 6; + + # The private (x) and public (y) values of the committed testdsa.pem / + # testdsapub.pem keypair. -text prints them as colon-separated hex; we + # strip the formatting and compare against the known values so the actual + # key material, not just the labels, is verified. + my $priv_hex = "BF71D497B89755D0C5E41285D81F9577CC3DF8C2"; + my $pub_hex = "CC99A07D9817BFF03BB09B183E9B19EB77ABECF192C3A9FBA833DBE" + . "69EDB719A8E9777BB82736CEC6A8E4E2FAD0693ACC3D14565D62710B95B02CC" + . "6A5CF091EEF9C22F20193EBE114C45A0B5E54A645037E8787FE01B3871508A2" + . "5BDBF7C6B81428F89858F133FDB858C390C2EF7BCF7E41D7C66578F792A2488" + . "C787EF7C7D41"; + + my @priv = run(app(['openssl', 'dsa', '-text', '-noout', + '-in', srctop_file("test", "testdsa.pem")], + stderr => undef), + capture => 1); + chomp @priv; + my $priv_blob = uc join('', @priv); + $priv_blob =~ s/[^0-9A-F]//g; + ok(grep(/^Private-Key: \(1024 bit\)$/, @priv), + "-text prints the private key header"); + ok(index($priv_blob, $priv_hex) >= 0, + "-text prints the expected private value"); + ok(index($priv_blob, $pub_hex) >= 0, + "-text prints the expected public value for a private key"); + + my @pub = run(app(['openssl', 'dsa', '-pubin', '-text', '-noout', + '-in', srctop_file("test", "testdsapub.pem")], + stderr => undef), + capture => 1); + chomp @pub; + my $pub_blob = uc join('', @pub); + $pub_blob =~ s/[^0-9A-F]//g; + ok(grep(/^Public-Key: \(1024 bit\)$/, @pub), + "-text prints the public key header"); + ok(index($pub_blob, $pub_hex) >= 0, + "-text prints the expected public value for a public key"); + ok(!grep(/^priv:/, @pub), + "-text does not print a private component for a public key"); +}; + +subtest "dsa error cases" => sub { + plan tests => 16; + + my $privkey = srctop_file("test", "testdsa.pem"); + + app_fails('dsa', "invalid input format should fail", + qr/Invalid format "BAD" for option -inform/, + '-inform', 'BAD', '-in', $privkey); + app_fails('dsa', "invalid output format should fail", + qr/Invalid format "BAD" for option -outform/, + '-outform', 'BAD', '-in', $privkey); + app_fails('dsa', "extra positional argument should fail", + qr/Extra option: "extra"/, + '-in', $privkey, 'extra'); + app_fails('dsa', "unknown cipher option should fail", + qr/Unknown option or cipher: badcipher/, + '-badcipher', '-in', $privkey); + app_fails('dsa', "invalid passin argument should fail", + qr/Error getting passwords/, + '-passin', 'bad:pass', '-in', $privkey); + app_fails('dsa', "unsupported output format should fail", + qr/bad output format specified for outfile/, + '-in', $privkey, '-outform', 'NSS', '-out', 'dsa-nss.out'); + + my $garbage = "garbage.pem"; + open(my $fh, '>', $garbage) or die "Cannot write $garbage: $!"; + print $fh "not a valid DSA key file\n"; + close($fh); + app_fails('dsa', "loading garbage key file should fail", + qr/unable to load Key/, + '-in', $garbage, '-noout'); + app_fails('dsa', "loading a non-DSA key should fail", + qr/Not a DSA key/, + '-in', srctop_file("test", "testrsa.pem"), '-noout'); +}; + subtest "dsa PVK output is rejected for public key input" => sub { plan tests => 1; diff --git a/test/recipes/15-test_dsaparam.t b/test/recipes/15-test_dsaparam.t index fe7a52d8361d2..fb69f3901ab11 100644 --- a/test/recipes/15-test_dsaparam.t +++ b/test/recipes/15-test_dsaparam.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -13,7 +13,7 @@ use File::Spec; use File::Copy; use File::Compare qw/compare_text/; use OpenSSL::Glob; -use OpenSSL::Test qw/:DEFAULT data_file/; +use OpenSSL::Test qw/:DEFAULT data_file app_fails/; use OpenSSL::Test::Utils; setup("test_dsaparam"); @@ -68,7 +68,7 @@ plan skip_all => "DSA isn't supported in this build" my @valid = glob(data_file("valid", "*.pem")); my @invalid = glob(data_file("invalid", "*.pem")); -my $num_tests = scalar @valid + scalar @invalid + 4; +my $num_tests = scalar @valid + scalar @invalid + 5; plan tests => $num_tests; foreach (@valid) { @@ -103,6 +103,37 @@ subtest "dsaparam DER parameter output" => sub { "read the DER DSA parameters back"); }; +subtest "dsaparam error cases" => sub { + plan tests => 14; + + app_fails('dsaparam', "unknown option should fail", + qr/Unknown option: -badopt/, + '-badopt'); + app_fails('dsaparam', "invalid input format should fail", + qr/Invalid format "BAD" for option -inform/, + '-inform', 'BAD', '-in', $srcparams); + app_fails('dsaparam', "invalid output format should fail", + qr/Invalid format "BAD" for option -outform/, + '-outform', 'BAD', '-in', $srcparams); + app_fails('dsaparam', "non-numeric bitsize should fail", + qr/Can't parse "bad" as a number/, + 'bad'); + app_fails('dsaparam', "non-numeric q bitsize should fail", + qr/Can't parse "bad" as a number/, + '512', 'bad'); + app_fails('dsaparam', "extra positional argument should fail", + qr/Extra option/, + '512', '160', '5'); + + my $garbage = "garbage.pem"; + open(my $fh, '>', $garbage) or die "Cannot write $garbage: $!"; + print $fh "not a valid DSA parameter file\n"; + close($fh); + app_fails('dsaparam', "loading garbage DSA parameters file should fail", + qr/Could not find or decode key parameters/, + '-in', $garbage, '-noout'); +}; + subtest "dsaparam DER private key output with -genkey" => sub { plan tests => 2; diff --git a/test/recipes/15-test_ec.t b/test/recipes/15-test_ec.t index e3d18a884986b..894c070edda76 100644 --- a/test/recipes/15-test_ec.t +++ b/test/recipes/15-test_ec.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -19,7 +19,7 @@ setup("test_ec"); plan skip_all => 'EC is not supported in this build' if disabled('ec'); -plan tests => 19; +plan tests => 21; my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0); @@ -152,6 +152,31 @@ subtest 'EC parameter encoding (-param_enc)' => sub { "an invalid parameter encoding is rejected"); }; +subtest 'ec -no_public excludes the public key from the private key' => sub { + plan tests => 5; + + my $key = srctop_file("test", "testec-p256.pem"); + + ok(run(app(['openssl', 'ec', '-in', $key, + '-outform', 'DER', '-out', 'ec-priv-default.der'])), + "writing private key with the public key included by default"); + ok(run(app(['openssl', 'ec', '-in', $key, '-no_public', + '-outform', 'DER', '-out', 'ec-priv-nopub.der'])), + "writing private key with -no_public"); + ok((-s 'ec-priv-nopub.der') < (-s 'ec-priv-default.der'), + "-no_public encoding is smaller than the default one"); + # The encoding is deterministic for a fixed key, so compare it + # against the checked-in reference file. + is(compare('ec-priv-nopub.der', data_file('ec-priv-nopub.der')), 0, + "-no_public encoding matches the reference file"); + # The public key is recomputed from the private scalar on load, so + # it must match the reference public key encoding. + ok(run(app(['openssl', 'ec', '-inform', 'DER', '-in', 'ec-priv-nopub.der', + '-pubout', '-outform', 'DER', '-out', 'ec-nopub-pub.der'])) + && compare('ec-nopub-pub.der', data_file('ec-conv-unc.der')) == 0, + "the public key is recovered from a key written with -no_public"); +}; + subtest 'ec -text prints the key in text form' => sub { plan tests => 7; @@ -201,6 +226,30 @@ subtest 'ec -text prints the key in text form' => sub { "ec -text does not print a private component for a public key"); }; +subtest 'ec -check reports the key consistency' => sub { + plan tests => 4; + + # ec -check prints the verdict on stderr and always exits successfully, + # so check the printed message instead of the exit status. + my $valid_err = 'ec-check-valid.err'; + ok(run(app(['openssl', 'ec', '-check', '-noout', + '-in', srctop_file("test", "testec-p256.pem")], + stderr => $valid_err)), + "ec -check runs on a valid key"); + test_file_contains("ec -check of a valid key", $valid_err, + "EC Key valid"); + + # The invalid key is testec-p256.pem with the group generator as the + # public key, which is on the curve but fails the pairwise check. + my $invalid_err = 'ec-check-invalid.err'; + ok(run(app(['openssl', 'ec', '-check', '-noout', + '-in', data_file('ec-check-invalid.pem')], + stderr => $invalid_err)), + "ec -check runs on an invalid key"); + test_file_contains("ec -check of an invalid key", $invalid_err, + "EC Key Invalid"); +}; + subtest 'Check loading of fips and non-fips keys' => sub { plan skip_all => "FIPS is disabled" if $no_fips; diff --git a/test/recipes/15-test_ec_data/ec-check-invalid.pem b/test/recipes/15-test_ec_data/ec-check-invalid.pem new file mode 100644 index 0000000000000..cc592f5a24d45 --- /dev/null +++ b/test/recipes/15-test_ec_data/ec-check-invalid.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIDYEX2yQlhJXDIwBEwcfyAn2eICEKJxqsAPGChey1a2toAoGCCqGSM49 +AwEHoUQDQgAEaxfR8uEsQkf4vOblY6RA8ncDfYEt6zOg9KE5RdiYwpZP40Li/hp/ +m47n60p8D54WK84zV2sxXs7LtkBoN79R9Q== +-----END EC PRIVATE KEY----- diff --git a/test/recipes/15-test_ec_data/ec-priv-nopub.der b/test/recipes/15-test_ec_data/ec-priv-nopub.der new file mode 100644 index 0000000000000..52be88745ca7d --- /dev/null +++ b/test/recipes/15-test_ec_data/ec-priv-nopub.der @@ -0,0 +1,3 @@ +01 6_l�–W ŒÈ öx€„(œj°Æ +²խ­  +*†HÎ= \ No newline at end of file diff --git a/test/recipes/15-test_ecparam.t b/test/recipes/15-test_ecparam.t index 169814b4e531a..2ac8b7c6ea5b2 100644 --- a/test/recipes/15-test_ecparam.t +++ b/test/recipes/15-test_ecparam.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -10,11 +10,8 @@ use strict; use warnings; -use File::Spec; -use File::Copy; -use File::Compare qw/compare_text compare/; use OpenSSL::Glob; -use OpenSSL::Test qw/:DEFAULT data_file srctop_file bldtop_dir/; +use OpenSSL::Test qw/:DEFAULT data_file/; use OpenSSL::Test::Utils; setup("test_ecparam"); @@ -30,231 +27,27 @@ if (disabled("sm2")) { @valid = grep { !/sm2-.*\.pem/} @valid; } -plan tests => 16; +# The corpus is swept in a single process per set; the ecparam and +# pkeyparam applications themselves are covered by 20-test_app_ecparam.t. +plan tests => 3; -sub checkload { - my $files = shift; # List of files - my $valid = shift; # Check should pass or fail? - my $app = shift; # Which application - my $opt = shift; # Additional option +# The file names are written to a list file and that is passed instead: +# there are more of them than a test can be given arguments. +sub corpus_list { + my $name = shift; - foreach (@$files) { - if ($valid) { - ok(run(app(['openssl', $app, '-noout', $opt, '-in', $_]))); - } else { - ok(!run(app(['openssl', $app, '-noout', $opt, '-in', $_]))); - } - } + open(my $fh, '>', $name) or die "Cannot write $name: $!"; + print $fh "$_\n" foreach (@_); + close($fh); + return $name; } -sub checkcompare { - my $files = shift; # List of files - my $app = shift; # Which application +ok(run(test(["ecparam_test", "valid", corpus_list("valid.lst", @valid)])), + "Load and check valid parameters"); - foreach (@$files) { - my $testout = "$app.tst"; +ok(run(test(["ecparam_test", "noncanon", + corpus_list("noncanon.lst", @noncanon)])), + "Load and check non-canonically encoded parameters"); - ok(run(app(['openssl', $app, '-out', $testout, '-in', $_]))); - ok(!compare_text($_, $testout, sub { - my $in1 = $_[0]; - my $in2 = $_[1]; - $in1 =~ s/\r\n/\n/g; - $in2 =~ s/\r\n/\n/g; - $in1 ne $in2}), "Original file $_ is the same as new one"); - } -} - -sub check_identical { - my $apps = shift; # List of applications - - foreach (@$apps) { - my $inout = "$_.tst"; - my $backup = "backup.tst"; - - copy($inout, $backup); - ok(run(app(['openssl', $_, '-in', $inout, '-out', $inout]))); - ok(!compare($inout, $backup), "converted file $inout did not change"); - } -} - -my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0); - -subtest "Check loading valid parameters by ecparam with -check" => sub { - plan tests => scalar(@valid); - checkload(\@valid, 1, "ecparam", "-check"); -}; - -subtest "Check loading valid parameters by ecparam with -check_named" => sub { - plan tests => scalar(@valid); - checkload(\@valid, 1, "ecparam", "-check_named"); -}; - -subtest "Check loading valid parameters by pkeyparam with -check" => sub { - plan tests => scalar(@valid); - checkload(\@valid, 1, "pkeyparam", "-check"); -}; - -subtest "Check loading non-canonically encoded parameters by ecparam with -check" => sub { - plan tests => scalar(@noncanon); - checkload(\@noncanon, 1, "ecparam", "-check"); -}; - -subtest "Check loading non-canonically encoded parameters by ecparam with -check_named" => sub { - plan tests => scalar(@noncanon); - checkload(\@noncanon, 1, "ecparam", "-check_named"); -}; - -subtest "Check loading non-canonically encoded parameters by pkeyparam with -check" => sub { - plan tests => scalar(@noncanon); - checkload(\@noncanon, 1, "pkeyparam", "-check"); -}; - -subtest "Check loading invalid parameters by ecparam with -check" => sub { - plan tests => scalar(@invalid); - checkload(\@invalid, 0, "ecparam", "-check"); -}; - -subtest "Check loading invalid parameters by ecparam with -check_named" => sub { - plan tests => scalar(@invalid); - checkload(\@invalid, 0, "ecparam", "-check_named"); -}; - -subtest "Check loading invalid parameters by pkeyparam with -check" => sub { - plan tests => scalar(@invalid); - checkload(\@invalid, 0, "pkeyparam", "-check"); -}; - -subtest "Check ecparam does not change the parameter file on output" => sub { - plan tests => 2 * scalar(@valid); - checkcompare(\@valid, "ecparam"); -}; - -subtest "Check pkeyparam does not change the parameter file on output" => sub { - plan tests => 2 * scalar(@valid); - checkcompare(\@valid, "pkeyparam"); -}; - -my @apps = ("ecparam", "pkeyparam"); -subtest "Check param apps do not garble infile identical to outfile" => sub { - plan tests => 2 * scalar(@apps); - check_identical(\@apps); -}; - -subtest "Check loading of fips and non-fips params" => sub { - plan skip_all => "FIPS is disabled" - if $no_fips; - plan tests => 8; - - my $fipsconf = srctop_file("test", "fips-and-base.cnf"); - my $defaultconf = srctop_file("test", "default.cnf"); - - $ENV{OPENSSL_CONF} = $fipsconf; - - ok(run(app(['openssl', 'ecparam', - '-in', data_file('valid', 'secp384r1-explicit.pem'), - '-check'])), - "Loading explicitly encoded valid curve"); - - ok(run(app(['openssl', 'ecparam', - '-in', data_file('valid', 'secp384r1-named.pem'), - '-check'])), - "Loading named valid curve"); - - ok(!run(app(['openssl', 'ecparam', - '-in', data_file('valid', 'secp112r1-named.pem'), - '-check'])), - "Fail loading named non-fips curve"); - - ok(!run(app(['openssl', 'pkeyparam', - '-in', data_file('valid', 'secp112r1-named.pem'), - '-check'])), - "Fail loading named non-fips curve using pkeyparam"); - - ok(run(app(['openssl', 'ecparam', - '-provider', 'default', - '-propquery', '?fips!=yes', - '-in', data_file('valid', 'secp112r1-named.pem'), - '-check'])), - "Loading named non-fips curve in FIPS mode with non-FIPS property". - " query"); - - ok(run(app(['openssl', 'pkeyparam', - '-provider', 'default', - '-propquery', '?fips!=yes', - '-in', data_file('valid', 'secp112r1-named.pem'), - '-check'])), - "Loading named non-fips curve in FIPS mode with non-FIPS property". - " query using pkeyparam"); - - ok(!run(app(['openssl', 'ecparam', - '-genkey', '-name', 'secp112r1'])), - "Fail generating key for named non-fips curve"); - - ok(run(app(['openssl', 'ecparam', - '-provider', 'default', - '-propquery', '?fips!=yes', - '-genkey', '-name', 'secp112r1'])), - "Generating key for named non-fips curve with non-FIPS property query"); - - $ENV{OPENSSL_CONF} = $defaultconf; -}; - -subtest "Check ecparam -param_enc converts between named and explicit" => sub { - plan tests => 3; - - my $named = data_file('valid', 'secp384r1-named.pem'); - my $explicit = data_file('valid', 'secp384r1-explicit.pem'); - - # The encodings are canonical, so re-encoding a named curve as explicit - # (and vice versa) must reproduce the matching reference file byte for byte. - my $to_explicit = 'param-explicit.tst'; - ok(run(app(['openssl', 'ecparam', '-in', $named, '-param_enc', 'explicit', - '-out', $to_explicit])) - && !compare($to_explicit, $explicit), - "named_curve params re-encoded as explicit match the reference file"); - - my $to_named = 'param-named.tst'; - ok(run(app(['openssl', 'ecparam', '-in', $explicit, '-param_enc', - 'named_curve', '-out', $to_named])) - && !compare($to_named, $named), - "explicit params re-encoded as named_curve match the reference file"); - - ok(!run(app(['openssl', 'ecparam', '-in', $named, '-noout', - '-param_enc', 'bogus'])), - "an invalid parameter encoding is rejected"); -}; - -subtest "Check ecparam -text prints the parameters in text form" => sub { - plan tests => 6; - - my $named = data_file('valid', 'secp384r1-named.pem'); - my $explicit = data_file('valid', 'secp384r1-explicit.pem'); - - # Named parameters print the curve identification. - my @named = run(app(['openssl', 'ecparam', '-text', '-noout', '-in', $named], - stderr => undef), - capture => 1); - chomp @named; - ok(grep(/^EC-Parameters: \(384 bit field, 192 bit security level\)$/, @named), - "named parameters print the EC-Parameters header"); - ok(grep(/^ASN1 OID: secp384r1$/, @named), - "named parameters print the expected curve OID"); - ok(grep(/^NIST CURVE: P-384$/, @named), - "named parameters print the expected NIST curve name"); - - # Explicit parameters print the field parameters instead of the curve name. - my @explicit = run(app(['openssl', 'ecparam', '-text', '-noout', - '-in', $explicit], - stderr => undef), - capture => 1); - chomp @explicit; - ok(grep(/^EC-Parameters: \(384 bit field, 192 bit security level\)$/, @explicit), - "explicit parameters print the EC-Parameters header"); - ok(grep(/^Field Type: prime-field$/, @explicit) - && grep(/^Cofactor:/, @explicit), - "explicit parameters print the field parameters"); - ok(!grep(/^ASN1 OID:/, @explicit), - "explicit parameters do not print a curve OID"); -}; - -ok(run(app(['openssl', 'ecparam', '-list_curves'])), "Test -list_curves"); +ok(run(test(["ecparam_test", "invalid", corpus_list("invalid.lst", @invalid)])), + "Reject invalid parameters"); diff --git a/test/recipes/15-test_gendsa.t b/test/recipes/15-test_gendsa.t index cd331c4cfc22f..81f0685822ca5 100644 --- a/test/recipes/15-test_gendsa.t +++ b/test/recipes/15-test_gendsa.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2017-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -11,7 +11,8 @@ use strict; use warnings; use File::Spec; -use OpenSSL::Test qw/:DEFAULT srctop_file srctop_dir bldtop_dir bldtop_file/; +use OpenSSL::Test qw/:DEFAULT srctop_file srctop_dir bldtop_dir bldtop_file + app_fails slurp_file/; use OpenSSL::Test::Utils; BEGIN { @@ -28,7 +29,7 @@ my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0); plan tests => ($no_fips ? 0 : 2) # FIPS related tests - + 18; + + 19; ok(run(app([ 'openssl', 'genpkey', '-genparam', '-algorithm', 'DSA', @@ -107,14 +108,63 @@ ok(!run(app([ 'openssl', 'genpkey', '-algorithm', 'DSA'])), "genpkey DSA with no params should fail"); -ok(run(app(["openssl", "gendsa", "-verbose", - 'dsagen.pem'])), - "gendsa with -verbose option and dsagen parameter"); +subtest "gendsa verbose mode" => sub { + plan tests => 4; + + my $stderr_file = "gendsa_verbose.txt"; + + ok(run(app(['openssl', 'gendsa', '-verbose', + '-out', 'gendsatest-verbose.pem', 'dsagen.pem'], + stderr => $stderr_file)), + "gendsa -verbose generates a key"); + my $err = slurp_file($stderr_file); + ok($err =~ qr/Generating DSA key with \d+ bits/, + "-verbose reports the key generation"); + + ok(run(app(['openssl', 'gendsa', '-quiet', + '-out', 'gendsatest-quiet.pem', 'dsagen.pem'], + stderr => $stderr_file)), + "gendsa -quiet generates a key"); + $err = slurp_file($stderr_file); + ok($err !~ qr/Generating DSA key/, + "-quiet does not report the key generation"); + unlink($stderr_file) if -f $stderr_file; +}; ok(!run(app(["openssl", "gendsa", 'dsagen.pem', "-verbose"])), "gendsa with extra parameter (at end) should fail"); +subtest "gendsa error cases" => sub { + plan tests => 14; + + app_fails('gendsa', "missing params file argument should fail", + qr/Missing argument: params file/); + app_fails('gendsa', "extra positional argument should fail", + qr/Extra argument after params file: "extra"/, + 'dsagen.pem', 'extra'); + app_fails('gendsa', "unknown cipher option should fail", + qr/Unknown option or cipher: badcipher/, + '-badcipher', 'dsagen.pem'); + app_fails('gendsa', "invalid passout argument should fail", + qr/Error getting password/, + '-passout', 'bad:pass', 'dsagen.pem'); + app_fails('gendsa', "nonexistent params file should fail", + qr/Could not open file or uri for loading key parameters/, + 'nonexistent.pem'); + + my $garbage = "garbage.pem"; + open(my $fh, '>', $garbage) or die "Cannot write $garbage: $!"; + print $fh "not a valid DSA params file\n"; + close($fh); + app_fails('gendsa', "garbage params file should fail", + qr/Could not find or decode key parameters/, + $garbage); + app_fails('gendsa', "non-DSA params file should fail", + qr/Could not find or decode key parameters of DSA parameters/, + srctop_file("test", "testrsa.pem")); +}; + # test key generation with dsaparam tool ok(run(app([ 'openssl', 'dsaparam', '-genkey', diff --git a/test/recipes/15-test_genec.t b/test/recipes/15-test_genec.t index 4d5090fa398a8..6df40ccd3daf3 100644 --- a/test/recipes/15-test_genec.t +++ b/test/recipes/15-test_genec.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -7,302 +7,6 @@ # https://www.openssl.org/source/license.html -use strict; -use warnings; +use OpenSSL::Test::Simple; -use File::Spec; -use OpenSSL::Test qw/:DEFAULT srctop_file/; -use OpenSSL::Test::Utils; - -# 'supported' and 'unsupported' reflect the current state of things. In -# Test::More terms, 'supported' works exactly like ok(run(whatever)), while -# 'unsupported' wraps that in a TODO: { } block. -# -# The first argument is the test name (this becomes the last argument to -# 'ok') -# The remaining argument are passed unchecked to 'run'. - -# 1: the result of app() or similar, i.e. something you can pass to -sub supported_pass { - my $str = shift; - - ok(run(@_), $str); -} - -sub supported_fail { - my $str = shift; - - ok(!run(@_), $str); -} - -setup("test_genec"); - -plan skip_all => "This test is unsupported in a no-ec build" - if disabled("ec"); - -my @prime_curves = qw( - secp112r1 - secp112r2 - secp128r1 - secp128r2 - secp160k1 - secp160r1 - secp160r2 - secp192k1 - secp224k1 - secp224r1 - secp256k1 - secp384r1 - secp521r1 - prime192v1 - prime192v2 - prime192v3 - prime239v1 - prime239v2 - prime239v3 - prime256v1 - wap-wsg-idm-ecid-wtls6 - wap-wsg-idm-ecid-wtls7 - wap-wsg-idm-ecid-wtls8 - wap-wsg-idm-ecid-wtls9 - wap-wsg-idm-ecid-wtls12 - brainpoolP160r1 - brainpoolP160t1 - brainpoolP192r1 - brainpoolP192t1 - brainpoolP224r1 - brainpoolP224t1 - brainpoolP256r1 - brainpoolP256t1 - brainpoolP320r1 - brainpoolP320t1 - brainpoolP384r1 - brainpoolP384t1 - brainpoolP512r1 - brainpoolP512t1 -); - -my @binary_curves = qw( - sect113r1 - sect113r2 - sect131r1 - sect131r2 - sect163k1 - sect163r1 - sect163r2 - sect193r1 - sect193r2 - sect233k1 - sect233r1 - sect239k1 - sect283k1 - sect283r1 - sect409k1 - sect409r1 - sect571k1 - sect571r1 - c2pnb163v1 - c2pnb163v2 - c2pnb163v3 - c2pnb176v1 - c2tnb191v1 - c2tnb191v2 - c2tnb191v3 - c2pnb208w1 - c2tnb239v1 - c2tnb239v2 - c2tnb239v3 - c2pnb272w1 - c2pnb304w1 - c2tnb359v1 - c2pnb368w1 - c2tnb431r1 - wap-wsg-idm-ecid-wtls1 - wap-wsg-idm-ecid-wtls3 - wap-wsg-idm-ecid-wtls4 - wap-wsg-idm-ecid-wtls5 - wap-wsg-idm-ecid-wtls10 - wap-wsg-idm-ecid-wtls11 -); - -my @explicit_only_curves = (); -push(@explicit_only_curves, qw( - Oakley-EC2N-3 - Oakley-EC2N-4 - )) if !disabled("ec2m"); - -my @other_curves = (); -push(@other_curves, 'SM2') - if !disabled("sm2"); - -my @curve_aliases = qw( - P-192 - P-224 - P-256 - P-384 - P-521 -); -push(@curve_aliases, qw( - B-163 - B-233 - B-283 - B-409 - B-571 - K-163 - K-233 - K-283 - K-409 - K-571 -)) if !disabled("ec2m"); - -my @curve_list = (); -push(@curve_list, @prime_curves); -push(@curve_list, @binary_curves) - if !disabled("ec2m"); -push(@curve_list, @other_curves); -push(@curve_list, @curve_aliases); - -my %params_encodings = - ( - 'named_curve' => \&supported_pass, - 'explicit' => \&supported_pass - ); - -my @output_formats = ('PEM', 'DER'); - -plan tests => scalar(@curve_list) * scalar(keys %params_encodings) - * (1 + scalar(@output_formats)) # Try listed @output_formats and text output - * 2 # Test generating parameters and keys - + 1 # Checking that with no curve it fails - + 1 # Checking that with unknown curve it fails - + 1 # Subtest for explicit only curves - + 1 # base serializer test - ; - -ok(!run(app([ 'openssl', 'genpkey', - '-algorithm', 'EC'])), - "genpkey EC with no params should fail"); - -ok(!run(app([ 'openssl', 'genpkey', - '-algorithm', 'EC', - '-pkeyopt', 'ec_paramgen_curve:bogus_foobar_curve'])), - "genpkey EC with unknown curve name should fail"); - -ok(run(app([ 'openssl', 'genpkey', - '-provider-path', 'providers', - '-provider', 'base', - '-config', srctop_file("test", "default.cnf"), - '-algorithm', 'EC', - '-pkeyopt', 'ec_paramgen_curve:prime256v1', - '-text'])), - "generate a private key and serialize it using the base provider"); - -foreach my $curvename (@curve_list) { - foreach my $paramenc (sort keys %params_encodings) { - my $fn = $params_encodings{$paramenc}; - - # --- Test generating parameters --- - - $fn->("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (text)", - app([ 'openssl', 'genpkey', '-genparam', - '-algorithm', 'EC', - '-pkeyopt', 'ec_paramgen_curve:'.$curvename, - '-pkeyopt', 'ec_param_enc:'.$paramenc, - '-text'])); - - foreach my $outform (@output_formats) { - my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform; - $fn->("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (${outform})", - app([ 'openssl', 'genpkey', '-genparam', - '-algorithm', 'EC', - '-pkeyopt', 'ec_paramgen_curve:'.$curvename, - '-pkeyopt', 'ec_param_enc:'.$paramenc, - '-outform', $outform, - '-out', $outfile])); - } - - # --- Test generating actual keys --- - - $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (text)", - app([ 'openssl', 'genpkey', - '-algorithm', 'EC', - '-pkeyopt', 'ec_paramgen_curve:'.$curvename, - '-pkeyopt', 'ec_param_enc:'.$paramenc, - '-text'])); - - foreach my $outform (@output_formats) { - my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform; - my $outpubfile = "ecgen.${curvename}.${paramenc}-pub." . lc $outform; - $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (${outform})", - app([ 'openssl', 'genpkey', - '-algorithm', 'EC', - '-pkeyopt', 'ec_paramgen_curve:'.$curvename, - '-pkeyopt', 'ec_param_enc:'.$paramenc, - '-outform', $outform, - '-out', $outfile, - '-outpubkey', $outpubfile])); - } - } -} - -subtest "test curves that only support explicit parameters encoding" => sub { - plan skip_all => "This test is unsupported under current configuration" - if scalar(@explicit_only_curves) <= 0; - - plan tests => scalar(@explicit_only_curves) * scalar(keys %params_encodings) - * (1 + scalar(@output_formats)) # Try listed @output_formats and text output - * 2 # Test generating parameters and keys - ; - - my %params_encodings = - ( - 'named_curve' => \&supported_fail, - 'explicit' => \&supported_pass - ); - - foreach my $curvename (@explicit_only_curves) { - foreach my $paramenc (sort keys %params_encodings) { - my $fn = $params_encodings{$paramenc}; - - # --- Test generating parameters --- - - $fn->("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (text)", - app([ 'openssl', 'genpkey', '-genparam', - '-algorithm', 'EC', - '-pkeyopt', 'ec_paramgen_curve:'.$curvename, - '-pkeyopt', 'ec_param_enc:'.$paramenc, - '-text'])); - - foreach my $outform (@output_formats) { - my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform; - $fn->("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (${outform})", - app([ 'openssl', 'genpkey', '-genparam', - '-algorithm', 'EC', - '-pkeyopt', 'ec_paramgen_curve:'.$curvename, - '-pkeyopt', 'ec_param_enc:'.$paramenc, - '-outform', $outform, - '-out', $outfile])); - } - - # --- Test generating actual keys --- - - $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (text)", - app([ 'openssl', 'genpkey', - '-algorithm', 'EC', - '-pkeyopt', 'ec_paramgen_curve:'.$curvename, - '-pkeyopt', 'ec_param_enc:'.$paramenc, - '-text'])); - - foreach my $outform (@output_formats) { - my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform; - $fn->("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (${outform})", - app([ 'openssl', 'genpkey', - '-algorithm', 'EC', - '-pkeyopt', 'ec_paramgen_curve:'.$curvename, - '-pkeyopt', 'ec_param_enc:'.$paramenc, - '-outform', $outform, - '-out', $outfile])); - } - } - } -}; +simple_test("test_genec", "genec_test", "ec"); diff --git a/test/recipes/15-test_genpkey.t b/test/recipes/15-test_genpkey.t index ddef803ff1fc1..a2fa2cfdff09d 100644 --- a/test/recipes/15-test_genpkey.t +++ b/test/recipes/15-test_genpkey.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -9,7 +9,7 @@ use strict; use warnings; -use OpenSSL::Test qw/:DEFAULT with/; +use OpenSSL::Test qw/:DEFAULT with app_fails slurp_file/; use OpenSSL::Test::Utils; setup("test_genpkey"); @@ -22,7 +22,7 @@ push @algs, qw(EC) unless disabled("ec"); push @algs, qw(X25519 X448) unless disabled("ecx"); push @algs, qw(SM2) unless disabled("sm2"); -plan tests => scalar(@algs) + 2; +plan tests => scalar(@algs) + 4; foreach (@algs) { my $alg = $_; @@ -67,3 +67,67 @@ SKIP: { "Cannot use a cipher with -genparam"); }); } + +subtest "genpkey error cases" => sub { + plan tests => 20; + + app_fails('genpkey', "no algorithm or parameter file should fail", + qr/Use -help for summary/); + app_fails('genpkey', "extra positional argument should fail", + qr/Extra option: "extra"/, + '-algorithm', 'RSA', 'extra'); + app_fails('genpkey', "invalid output format should fail", + qr/Invalid format "BAD" for option -outform/, + '-outform', 'BAD', '-algorithm', 'RSA'); + app_fails('genpkey', "parameter file with -genparam should fail", + qr/Use -help for summary/, + '-genparam', '-paramfile', 'dsagen.pem'); + app_fails('genpkey', "unknown algorithm should fail", + qr/Error initializing FOO context/, + '-algorithm', 'FOO'); + app_fails('genpkey', "unknown key option should fail", + qr/Error setting bad:1 parameter/, + '-algorithm', 'RSA', '-pkeyopt', 'bad:1'); + app_fails('genpkey', "unknown cipher option should fail", + qr/Unknown option or cipher: badcipher/, + '-algorithm', 'RSA', '-badcipher'); + app_fails('genpkey', "invalid pass argument should fail", + qr/Error getting password/, + '-algorithm', 'RSA', '-pass', 'bad:secret'); + app_fails('genpkey', "nonexistent parameter file should fail", + qr/Can't open parameter file/, + '-paramfile', 'nonexistent.pem'); + + my $garbage = "garbage.pem"; + open(my $fh, '>', $garbage) or die "Cannot write $garbage: $!"; + print $fh "not a valid params file\n"; + close($fh); + app_fails('genpkey', "garbage parameter file should fail", + qr/Error reading parameter file/, + '-paramfile', $garbage); +}; + +subtest "genpkey verbose mode" => sub { + plan tests => 4; + + my $stderr_file = "genpkey_verbose.txt"; + + ok(run(app(['openssl', 'genpkey', '-verbose', '-algorithm', 'RSA', + '-pkeyopt', 'rsa_keygen_bits:2048', + '-out', 'genpkey-verbose.pem'], + stderr => $stderr_file)), + "genpkey -verbose generates a key"); + my $err = slurp_file($stderr_file); + ok($err =~ qr/Generating RSA key/, + "-verbose reports the key generation"); + + ok(run(app(['openssl', 'genpkey', '-quiet', '-algorithm', 'RSA', + '-pkeyopt', 'rsa_keygen_bits:2048', + '-out', 'genpkey-quiet.pem'], + stderr => $stderr_file)), + "genpkey -quiet generates a key"); + $err = slurp_file($stderr_file); + ok($err !~ qr/Generating RSA key/, + "-quiet does not report the key generation"); + unlink($stderr_file) if -f $stderr_file; +}; diff --git a/test/recipes/15-test_genrsa.t b/test/recipes/15-test_genrsa.t index 83196031d776a..22bd9b5812e05 100644 --- a/test/recipes/15-test_genrsa.t +++ b/test/recipes/15-test_genrsa.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -11,7 +11,8 @@ use strict; use warnings; use File::Spec; -use OpenSSL::Test qw/:DEFAULT srctop_file srctop_dir bldtop_dir bldtop_file/; +use OpenSSL::Test qw/:DEFAULT srctop_file srctop_dir bldtop_dir bldtop_file + app_fails slurp_file/; use OpenSSL::Test::Utils; BEGIN { @@ -25,7 +26,7 @@ my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0); plan tests => ($no_fips ? 0 : 5) # Extra FIPS related tests - + 16; + + 18; # We want to know that an absurdly small number of bits isn't support is(run(app([ 'openssl', 'genpkey', '-out', 'genrsatest.pem', @@ -116,6 +117,58 @@ ok(run(app(([ 'openssl', 'asn1parse', ok(run(app([ 'openssl', 'rsa', '-in', 'genrsatest-enc.pem', '-passin', 'pass:x' ])), "rsa decrypt"); +subtest "genrsa error cases" => sub { + plan tests => 14; + + app_fails('genrsa', "unknown cipher option should fail", + qr/Unknown option or cipher: badcipher/, + '-badcipher'); + app_fails('genrsa', "non-numeric primes argument should fail", + qr/Can't parse "abc" as a number/, + '-primes', 'abc', $good); + app_fails('genrsa', "too small number of primes should fail", + qr/Error generating RSA key/, + '-primes', '1', $good); + app_fails('genrsa', "too large number of primes should fail", + qr/Error generating RSA key/, + '-primes', '100', $good); + app_fails('genrsa', "invalid passout argument should fail", + qr/Error getting password/, + '-passout', 'bad:pass', $good); + app_fails('genrsa', "non-numeric bits argument should fail", + qr/Can't parse "abc" as a number/, + 'abc'); + app_fails('genrsa', "negative bits argument should fail", + qr/Invalid number of bits: -5/, + '--', '-5'); +}; + +subtest "genrsa verbose mode" => sub { + plan tests => 6; + + my $stderr_file = "genrsa_verbose.txt"; + + ok(run(app(['openssl', 'genrsa', '-verbose', '-f4', + '-out', 'genrsatest-verbose.pem', $good], + stderr => $stderr_file)), + "genrsa -verbose generates a key"); + my $err = slurp_file($stderr_file); + ok($err =~ qr/Generating RSA key with $good bits/, + "-verbose reports the key generation"); + ok($err =~ qr/e is 65537 \(0x010001\)/, + "-verbose reports the public exponent"); + + ok(run(app(['openssl', 'genrsa', '-quiet', '-f4', + '-out', 'genrsatest-quiet.pem', $good], + stderr => $stderr_file)), + "genrsa -quiet generates a key"); + $err = slurp_file($stderr_file); + ok($err !~ qr/Generating RSA key/, + "-quiet does not report the key generation"); + ok($err !~ qr/e is/, "-quiet does not report the public exponent"); + unlink($stderr_file) if -f $stderr_file; +}; + unless ($no_fips) { my $provconf = srctop_file("test", "fips-and-base.cnf"); my $provpath = bldtop_dir("providers"); diff --git a/test/recipes/15-test_ml_dsa_codecs.t b/test/recipes/15-test_ml_dsa_codecs.t index 16fc5c30219ba..908f3a414dc1d 100644 --- a/test/recipes/15-test_ml_dsa_codecs.t +++ b/test/recipes/15-test_ml_dsa_codecs.t @@ -194,10 +194,9 @@ foreach my $alg (@algs) { sprintf("create fake private key: %s", $alg)); my $realfh = IO::File->new($real, "<:raw"); my $fakefh = IO::File->new($fake, "<:raw"); - local $/ = undef; - my $realder = <$realfh>; + my $realder = do { local $/; <$realfh> }; $realfh->close(); - my $fakeder = <$fakefh>; + my $fakeder = do { local $/; <$fakefh> }; $fakefh->close(); # # - 20 bytes PKCS8 fixed overhead, diff --git a/test/recipes/15-test_ml_kem_codecs.t b/test/recipes/15-test_ml_kem_codecs.t index 25d92571c543b..b1fce9e36a31d 100644 --- a/test/recipes/15-test_ml_kem_codecs.t +++ b/test/recipes/15-test_ml_kem_codecs.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -179,9 +179,8 @@ foreach my $alg (@algs) { sprintf("create fake private key: %s", $alg)); my $realfh = IO::File->new($real, "<:raw"); my $fakefh = IO::File->new($fake, "<:raw"); - local $/ = undef; - my $realder = <$realfh>; - my $fakeder = <$fakefh>; + my $realder = do { local $/; <$realfh> }; + my $fakeder = do { local $/; <$fakefh> }; $realfh->close(); $fakefh->close(); # diff --git a/test/recipes/15-test_pkey.t b/test/recipes/15-test_pkey.t index fa4363f057142..56481266e4f78 100644 --- a/test/recipes/15-test_pkey.t +++ b/test/recipes/15-test_pkey.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -16,7 +16,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/; setup("test_pkey"); -plan tests => 7; +plan tests => 9; my @app = ('openssl', 'pkey'); @@ -112,6 +112,65 @@ subtest "=== pkey handling of DER encoding ===" => sub { "Same file contents after converting to DER and back"); }; +subtest "=== pkey -inform and -outform ===" => sub { + plan tests => 10; + + my $priv_der = 'inform_priv.der'; + my $priv_pem = 'inform_priv.pem'; + my $pub_der = 'inform_pub.der'; + my $pub_pem = 'inform_pub.pem'; + my $pub_ref = 'inform_pubref.pem'; + + # Public keys convert between PEM and DER just like private keys do. + ok(run(app([@app, '-in', $in_key, '-pubout', '-outform', 'DER', + '-out', $pub_der])), + "write DER-encoded public key"); + ok(run(app([@app, '-pubin', '-inform', 'DER', '-in', $pub_der, + '-pubout', '-out', $pub_pem])), + "read DER-encoded public key"); + ok(run(app([@app, '-in', $in_key, '-pubout', '-out', $pub_ref])), + "write PEM-encoded public key"); + is(compare_text($pub_ref, $pub_pem), 0, + "Same public key after converting to DER and back"); + + # -inform is unspecified by default, in which case the format is detected. + ok(run(app([@app, '-in', $in_key, '-outform', 'DER', '-out', $priv_der])), + "write DER-encoded private key"); + ok(run(app([@app, '-in', $priv_der, '-out', $priv_pem])), + "DER input is accepted without -inform"); + is(compare_text($in_key, $priv_pem), 0, + "Same private key after converting to DER and back"); + + # A mismatching -inform is not silently ignored. + ok(!run(app([@app, '-inform', 'DER', '-in', $in_key, '-noout'])), + "PEM input read as DER is rejected"); + ok(!run(app([@app, '-inform', 'PEM', '-in', $priv_der, '-noout'])), + "DER input read as PEM is rejected"); + + # Unlike -inform, -outform is limited to PEM and DER. + ok(!run(app([@app, '-in', $in_key, '-outform', 'MSBLOB', + '-out', 'inform_bad.tmp'])), + "-outform MSBLOB is rejected"); +}; + +subtest "=== pkey PKCS#12 input ===" => sub { + plan tests => 3; + + my $p12 = 'key.p12'; + ok(run(app(['openssl', 'pkcs12', '-export', '-inkey', $in_key, + '-in', srctop_file('test', 'certs', 'root-cert.pem'), + '-keypbe', 'AES-256-CBC', '-certpbe', 'AES-256-CBC', + '-macalg', 'sha256', '-passout', $pass, '-out', $p12])), + "create a PKCS#12 file holding the key"); + + my $from_p12 = 'from_p12.pem'; + ok(run(app([@app, '-inform', 'P12', '-in', $p12, '-passin', $pass, + '-out', $from_p12])), + "read the private key from the PKCS#12 file"); + is(compare_text($in_key, $from_p12), 0, + "key read from PKCS#12 is the same as the original key"); +}; + subtest "=== pkey text and text_pub output ===" => sub { plan tests => 6; diff --git a/test/recipes/15-test_rsa.t b/test/recipes/15-test_rsa.t index 3e60b23ef47d5..f3581484fe678 100644 --- a/test/recipes/15-test_rsa.t +++ b/test/recipes/15-test_rsa.t @@ -12,12 +12,12 @@ use warnings; use File::Spec; use File::Compare qw/compare/; -use OpenSSL::Test qw/:DEFAULT srctop_file/; +use OpenSSL::Test qw/:DEFAULT srctop_file app_fails/; use OpenSSL::Test::Utils; setup("test_rsa"); -plan tests => 16; +plan tests => 19; require_ok(srctop_file('test', 'recipes', 'tconversion.pl')); @@ -27,6 +27,134 @@ run_rsa_tests("pkey"); run_rsa_tests("rsa"); +SKIP: { + skip "RSA is not supported in this build", 3 if disabled("rsa"); + + subtest "rsa -modulus prints the RSA modulus" => sub { + plan tests => 2; + + # The modulus (n) of the committed testrsa.pem / testrsapub.pem keypair. + my $expected = "Modulus=AADB7AA92E464F15711996166B4FF8BBE2301DFEE9D8" + . "B3596DC3C1A7DFCE7C87180170509FC84EFD17B5BB02CA5DD0A3228686B38" + . "0CB746F3CAE4CDFC8AE5D3D"; + + my @priv = run(app(['openssl', 'rsa', '-modulus', '-noout', + '-in', srctop_file("test", "testrsa.pem")], + stderr => undef), + capture => 1); + chomp @priv; + ok(grep(/^\Q$expected\E$/, @priv), + "-modulus prints the expected modulus for a private key"); + + my @pub = run(app(['openssl', 'rsa', '-pubin', '-modulus', '-noout', + '-in', srctop_file("test", "testrsapub.pem")], + stderr => undef), + capture => 1); + chomp @pub; + ok(grep(/^\Q$expected\E$/, @pub), + "-modulus prints the expected modulus for a public key"); + }; + + subtest "rsa -text prints the key in text form" => sub { + plan tests => 6; + + # The modulus (n) and private exponent (d) of the committed + # testrsa.pem keypair. -text prints them as colon-separated hex; we + # strip the formatting and compare against the known values so the + # actual key material, not just the labels, is verified. + my $modulus = "AADB7AA92E464F15711996166B4FF8BBE2301DFEE9D8B3596DC3" + . "C1A7DFCE7C87180170509FC84EFD17B5BB02CA5DD0A3228686B380CB746F" + . "3CAE4CDFC8AE5D3D"; + my $priv_exp = "677727CDA1D733F6F119A479091D51AC3D6A1410157E840588E1" + . "FDB8F26031AA00BA84048AC3C755C64329C3AFE30120EBF4C89C02170671" + . "2282DAAF473BB2A1"; + + my @priv = run(app(['openssl', 'rsa', '-text', '-noout', + '-in', srctop_file("test", "testrsa.pem")], + stderr => undef), + capture => 1); + chomp @priv; + my $priv_blob = uc join('', @priv); + $priv_blob =~ s/[^0-9A-F]//g; + ok(grep(/^Private-Key: \(512 bit, 2 primes\)$/, @priv), + "-text prints the private key header"); + ok(index($priv_blob, $modulus) >= 0, + "-text prints the expected modulus for a private key"); + ok(index($priv_blob, $priv_exp) >= 0, + "-text prints the expected private exponent"); + + my @pub = run(app(['openssl', 'rsa', '-pubin', '-text', '-noout', + '-in', srctop_file("test", "testrsapub.pem")], + stderr => undef), + capture => 1); + chomp @pub; + my $pub_blob = uc join('', @pub); + $pub_blob =~ s/[^0-9A-F]//g; + ok(grep(/^Public-Key: \(512 bit\)$/, @pub), + "-text prints the public key header"); + ok(index($pub_blob, $modulus) >= 0, + "-text prints the expected modulus for a public key"); + ok(!grep(/privateExponent/, @pub), + "-text does not print a private exponent for a public key"); + }; + + subtest "rsa error cases" => sub { + plan tests => 20; + + my $privkey = srctop_file("test", "testrsa.pem"); + my $pubkey = srctop_file("test", "testrsapub.pem"); + + app_fails('rsa', "invalid input format should fail", + qr/Invalid format "BAD" for option -inform/, + '-inform', 'BAD', '-in', $privkey); + app_fails('rsa', "invalid output format should fail", + qr/Invalid format "BAD" for option -outform/, + '-outform', 'BAD', '-in', $privkey); + app_fails('rsa', "extra positional argument should fail", + qr/Extra option: "extra"/, + '-in', $privkey, 'extra'); + app_fails('rsa', "unknown cipher option should fail", + qr/Unknown option or cipher: badcipher/, + '-badcipher', '-in', $privkey); + app_fails('rsa', "invalid passin argument should fail", + qr/Error getting passwords/, + '-passin', 'bad:pass', '-in', $privkey); + app_fails('rsa', "checking a public key should fail", + qr/Only private keys can be checked/, + '-check', '-pubin', '-in', $pubkey); + app_fails('rsa', "unsupported output format should fail", + qr/bad output format specified for outfile/, + '-in', $privkey, '-outform', 'NSS', '-out', 'rsa-nss.out'); + app_fails('rsa', "PVK output for public key input should fail", + qr/PVK form impossible with public key input/, + '-pubin', '-in', $pubkey, '-outform', 'PVK', + '-out', 'rsa-pvk.out'); + + my $garbage = "garbage.pem"; + open(my $fh, '>', $garbage) or die "Cannot write $garbage: $!"; + print $fh "not a valid RSA key file\n"; + close($fh); + app_fails('rsa', "loading garbage key file should fail", + qr/Could not find or decode private key/, + '-in', $garbage, '-noout'); + + SKIP: { + my $nonrsa = !disabled("ec") + ? srctop_file("test", "testec-p256.pem") + : !disabled("dsa") + ? srctop_file("test", "testdsa.pem") + : undef; + + skip "No non-RSA key type available in this build", 2 + if !defined $nonrsa; + + app_fails('rsa', "loading a non-RSA key should fail", + qr/Not an RSA key/, + '-in', $nonrsa, '-noout'); + } + }; +} + sub run_rsa_tests { my $cmd = shift; diff --git a/test/recipes/20-test_app_ciphers.t b/test/recipes/20-test_app_ciphers.t new file mode 100644 index 0000000000000..e605c9925d692 --- /dev/null +++ b/test/recipes/20-test_app_ciphers.t @@ -0,0 +1,165 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use OpenSSL::Test qw/:DEFAULT with/; +use OpenSSL::Test::Utils; + +setup("test_app_ciphers"); + +plan skip_all => "The ciphers app is not available in a no-sock build" + if disabled("sock"); +plan skip_all => "No TLS protocols are supported by this OpenSSL build" + if alldisabled(available_protocols("tls")); + +plan tests => 7; + +my $base_status; +my @base = run(app(["openssl", "ciphers"]), + capture => 1, statusvar => \$base_status); +my @names = map { s|\R||; split(/:/, $_) } @base; + +subtest "ciphers lists cipher names in non-verbose mode" => sub { + plan tests => 5; + + ok($base_status, "ciphers with no options runs successfully"); + is(scalar @base, 1, "the whole list is printed on a single line"); + ok(@names > 0, "the list is not empty"); + is(join(" ", grep { !/^[A-Za-z0-9_-]+$/ } @names), "", + "the list holds colon-separated cipher names"); + with({ exit_checker => sub { return shift == 1; } }, + sub { + ok(run(app(["openssl", "ciphers", "NOSUCHCIPHER"])), + "an unknown cipher string is rejected"); + }); +}; + +# Each verbose line is a SSL_CIPHER_description() of one listed cipher. +my $desc = qr/\S+\s+Kx=\S+\s+Au=\S+\s+Enc=\S+\s+Mac=\S+/; + +subtest "ciphers -v describes each cipher" => sub { + plan tests => 3; + + my $status; + my @out = run(app(["openssl", "ciphers", "-v"]), + capture => 1, statusvar => \$status); + chomp @out; + ok($status, "ciphers -v runs successfully"); + is(scalar @out, scalar @names, "one description line per cipher"); + my @got = map { /^(\S+)\s+$desc$/ ? $1 : "BAD LINE: $_" } @out; + is(join(":", @got), join(":", @names), + "each line holds a full description of the listed cipher"); +}; + +subtest "ciphers -V prefixes descriptions with cipher codes" => sub { + plan tests => 3; + + my $status; + my @out = run(app(["openssl", "ciphers", "-V"]), + capture => 1, statusvar => \$status); + chomp @out; + ok($status, "ciphers -V runs successfully"); + is(scalar @out, scalar @names, "one description line per cipher"); + my $code = qr/(?:0x[0-9A-F]{2},){1,3}0x[0-9A-F]{2}/; + my @got = map { /^\s*$code - (\S+)\s+$desc$/ ? $1 : "BAD LINE: $_" } @out; + is(join(":", @got), join(":", @names), + "each line holds the cipher code and a full description"); +}; + +subtest "ciphers -stdname prefixes descriptions with standard names" => sub { + plan tests => 4; + + my $status; + my @out = run(app(["openssl", "ciphers", "-stdname"]), + capture => 1, statusvar => \$status); + chomp @out; + ok($status, "ciphers -stdname runs successfully"); + is(scalar @out, scalar @names, "one description line per cipher"); + my @got = map { /^\S+\s+- (\S+)\s+$desc$/ ? $1 : "BAD LINE: $_" } @out; + is(join(":", @got), join(":", @names), + "each line holds the standard name and a full description"); + my @badstd = grep { !/^(?:TLS_\S+|UNKNOWN)\s/ } @out; + is(join("\n", @badstd), "", "standard names are TLS_* or UNKNOWN"); +}; + +subtest "ciphers -V -stdname combines codes and standard names" => sub { + plan tests => 3; + + my $status; + my @out = run(app(["openssl", "ciphers", "-V", "-stdname"]), + capture => 1, statusvar => \$status); + chomp @out; + ok($status, "ciphers -V -stdname runs successfully"); + my $code = qr/(?:0x[0-9A-F]{2},){1,3}0x[0-9A-F]{2}/; + my @got = map { /^\s*$code - \S+\s+- (\S+)\s+$desc$/ ? $1 : "BAD LINE: $_" } + @out; + is(join(":", @got), join(":", @names), + "each line holds the code, the standard name and a description"); + + SKIP: { + my @all = run(app(["openssl", "ciphers", "ALL"]), capture => 1); + skip "AES128-SHA is not available", 1 + unless grep { /(?:^|:)AES128-SHA(?::|$)/ } map { s|\R||r } @all; + + # The TLSv1.3 ciphersuites are always prepended to the list. + my @line = grep { / - AES128-SHA\s/ } + run(app(["openssl", "ciphers", "-stdname", "AES128-SHA"]), + capture => 1, statusvar => \$status); + ok($status && @line == 1 + && $line[0] =~ /^TLS_RSA_WITH_AES_128_CBC_SHA\s+- AES128-SHA\s/, + "AES128-SHA maps to the TLS_RSA_WITH_AES_128_CBC_SHA standard name"); + } +}; + +subtest "ciphers -psk includes PSK ciphers among the supported ones" => sub { + plan skip_all => "PSK is not supported by this OpenSSL build" + if disabled("psk"); + plan skip_all => "TLSv1.2 is not supported by this OpenSSL build" + if disabled("tls1_2"); + + plan tests => 3; + + my $status; + my @psk = grep { /PSK/ } + map { s|\R||; split(/:/, $_) } + run(app(["openssl", "ciphers", "-s", "-psk", "PSK"]), + capture => 1, statusvar => \$status); + ok($status, "ciphers -s -psk runs successfully"); + ok(@psk > 0, "PSK ciphers are supported with -psk"); + + @psk = grep { /PSK/ } + map { s|\R||; split(/:/, $_) } + run(app(["openssl", "ciphers", "-s", "PSK"]), + capture => 1, statusvar => \$status); + ok($status && @psk == 0, "PSK ciphers are not supported without -psk"); +}; + +subtest "ciphers -ciphersuites configures the TLSv1.3 ciphersuites" => sub { + plan skip_all => "TLSv1.3 is not supported by this OpenSSL build" + if disabled("tls1_3"); + + plan tests => 3; + + my $status; + my @suites = grep { /^TLS_/ } + map { s|\R||; split(/:/, $_) } + run(app(["openssl", "ciphers", "-ciphersuites", + "TLS_AES_128_GCM_SHA256"]), + capture => 1, statusvar => \$status); + ok($status, "ciphers -ciphersuites runs successfully"); + is(join(":", @suites), "TLS_AES_128_GCM_SHA256", + "only the configured TLSv1.3 ciphersuite is listed"); + with({ exit_checker => sub { return shift == 1; } }, + sub { + ok(run(app(["openssl", "ciphers", "-ciphersuites", + "NOSUCHSUITE"])), + "an unknown TLSv1.3 ciphersuite is rejected"); + }); +}; diff --git a/test/recipes/20-test_app_ecparam.t b/test/recipes/20-test_app_ecparam.t new file mode 100644 index 0000000000000..1c03efff1d3b4 --- /dev/null +++ b/test/recipes/20-test_app_ecparam.t @@ -0,0 +1,251 @@ +#! /usr/bin/env perl +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +use strict; +use warnings; + +use File::Copy; +use File::Compare qw/compare_text compare/; +use OpenSSL::Test qw/:DEFAULT srctop_file/; +use OpenSSL::Test::Utils; + +setup("test_app_ecparam"); + +plan skip_all => "EC or EC2M isn't supported in this build" + if disabled("ec") || disabled("ec2m"); + +# The parameter corpus belongs to 15-test_ecparam.t, so it has to be named +# by path rather than through data_file(), which resolves against the data +# directory of the recipe that calls it. +sub param_file { + return srctop_file("test", "recipes", "15-test_ecparam_data", @_); +} + +# The parameter corpus is swept in process by 15-test_ecparam.t. What is +# tested here is the applications: their options, and that they write what +# they read. A representative curve is enough for that; running the whole +# corpus through them buys process startup rather than coverage. +my $named = param_file('valid', 'secp384r1-named.pem'); +my $explicit = param_file('valid', 'secp384r1-explicit.pem'); +my $prime = param_file('valid', 'prime256v1-named.pem'); + +my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0); + +plan tests => 8; + +sub checkcompare { + my $files = shift; # List of files + my $app = shift; # Which application + + foreach (@$files) { + my $testout = "$app.tst"; + + ok(run(app(['openssl', $app, '-out', $testout, '-in', $_]))); + ok(!compare_text($_, $testout, sub { + my $in1 = $_[0]; + my $in2 = $_[1]; + $in1 =~ s/\r\n/\n/g; + $in2 =~ s/\r\n/\n/g; + $in1 ne $in2}), "Original file $_ is the same as new one"); + } +} + +sub check_identical { + my $apps = shift; # List of applications + + foreach (@$apps) { + my $inout = "$_.tst"; + my $backup = "backup.tst"; + + copy($inout, $backup); + ok(run(app(['openssl', $_, '-in', $inout, '-out', $inout]))); + ok(!compare($inout, $backup), "converted file $inout did not change"); + } +} + +my @representative = ($named, $explicit, $prime); + +subtest "Check ecparam does not change the parameter file on output" => sub { + plan tests => 2 * scalar(@representative); + checkcompare(\@representative, "ecparam"); +}; + +subtest "Check pkeyparam does not change the parameter file on output" => sub { + plan tests => 2 * scalar(@representative); + checkcompare(\@representative, "pkeyparam"); +}; + +my @apps = ("ecparam", "pkeyparam"); +subtest "Check param apps do not garble infile identical to outfile" => sub { + plan tests => 2 * scalar(@apps); + check_identical(\@apps); +}; + +subtest "Check loading of fips and non-fips params" => sub { + plan skip_all => "FIPS is disabled" + if $no_fips; + plan tests => 8; + + my $fipsconf = srctop_file("test", "fips-and-base.cnf"); + my $defaultconf = srctop_file("test", "default.cnf"); + + $ENV{OPENSSL_CONF} = $fipsconf; + + ok(run(app(['openssl', 'ecparam', + '-in', param_file('valid', 'secp384r1-explicit.pem'), + '-check'])), + "Loading explicitly encoded valid curve"); + + ok(run(app(['openssl', 'ecparam', + '-in', param_file('valid', 'secp384r1-named.pem'), + '-check'])), + "Loading named valid curve"); + + ok(!run(app(['openssl', 'ecparam', + '-in', param_file('valid', 'secp112r1-named.pem'), + '-check'])), + "Fail loading named non-fips curve"); + + ok(!run(app(['openssl', 'pkeyparam', + '-in', param_file('valid', 'secp112r1-named.pem'), + '-check'])), + "Fail loading named non-fips curve using pkeyparam"); + + ok(run(app(['openssl', 'ecparam', + '-provider', 'default', + '-propquery', '?fips!=yes', + '-in', param_file('valid', 'secp112r1-named.pem'), + '-check'])), + "Loading named non-fips curve in FIPS mode with non-FIPS property". + " query"); + + ok(run(app(['openssl', 'pkeyparam', + '-provider', 'default', + '-propquery', '?fips!=yes', + '-in', param_file('valid', 'secp112r1-named.pem'), + '-check'])), + "Loading named non-fips curve in FIPS mode with non-FIPS property". + " query using pkeyparam"); + + ok(!run(app(['openssl', 'ecparam', + '-genkey', '-name', 'secp112r1'])), + "Fail generating key for named non-fips curve"); + + ok(run(app(['openssl', 'ecparam', + '-provider', 'default', + '-propquery', '?fips!=yes', + '-genkey', '-name', 'secp112r1'])), + "Generating key for named non-fips curve with non-FIPS property query"); + + $ENV{OPENSSL_CONF} = $defaultconf; +}; + +subtest "Check ecparam -param_enc converts between named and explicit" => sub { + plan tests => 3; + + # The encodings are canonical, so re-encoding a named curve as explicit + # (and vice versa) must reproduce the matching reference file byte for byte. + my $to_explicit = 'param-explicit.tst'; + ok(run(app(['openssl', 'ecparam', '-in', $named, '-param_enc', 'explicit', + '-out', $to_explicit])) + && !compare($to_explicit, $explicit), + "named_curve params re-encoded as explicit match the reference file"); + + my $to_named = 'param-named.tst'; + ok(run(app(['openssl', 'ecparam', '-in', $explicit, '-param_enc', + 'named_curve', '-out', $to_named])) + && !compare($to_named, $named), + "explicit params re-encoded as named_curve match the reference file"); + + ok(!run(app(['openssl', 'ecparam', '-in', $named, '-noout', + '-param_enc', 'bogus'])), + "an invalid parameter encoding is rejected"); +}; + +subtest "Check ecparam -inform and -outform handling" => sub { + plan tests => 4; + + my $der = 'param.der'; + ok(run(app(['openssl', 'ecparam', '-in', $named, '-outform', 'DER', + '-out', $der])), + "write DER-encoded parameters"); + my $pem = 'param-der.pem'; + ok(run(app(['openssl', 'ecparam', '-inform', 'DER', '-in', $der, + '-out', $pem])) + && !compare($pem, $named), + "parameters survive a PEM -> DER -> PEM roundtrip"); + + ok(!run(app(['openssl', 'ecparam', '-in', $der, '-noout'])), + "DER input without -inform is rejected as the default is PEM"); + + ok(!run(app(['openssl', 'ecparam', '-in', $named, '-outform', 'MSBLOB', + '-out', 'param.tmp'])), + "-outform is limited to PEM and DER"); +}; + +subtest "Check ecparam -conv_form selects the generator point encoding" => sub { + plan tests => 5; + + # Only explicit parameters encode the generator point; the reference file + # uses the default uncompressed form. + my $comp = 'param-comp.pem'; + ok(run(app(['openssl', 'ecparam', '-in', $explicit, '-conv_form', + 'compressed', '-out', $comp])), + "write explicit parameters with a compressed generator"); + ok((-s $comp) < (-s $explicit), + "compressed generator encoding is smaller than uncompressed"); + + my $back = 'param-unc.pem'; + ok(run(app(['openssl', 'ecparam', '-in', $comp, '-conv_form', + 'uncompressed', '-out', $back])) + && !compare($back, $explicit), + "converting back to uncompressed matches the reference file"); + + my $namedout = 'param-named-conv.pem'; + ok(run(app(['openssl', 'ecparam', '-in', $named, '-conv_form', + 'compressed', '-out', $namedout])) + && !compare($namedout, $named), + "-conv_form does not change named curve parameters"); + + ok(!run(app(['openssl', 'ecparam', '-in', $named, '-noout', + '-conv_form', 'bogus'])), + "an invalid conversion form is rejected"); +}; + +subtest "Check ecparam -text and -list_curves" => sub { + plan tests => 7; + + # Named parameters print the curve identification. + my @named = run(app(['openssl', 'ecparam', '-text', '-noout', '-in', $named], + stderr => undef), + capture => 1); + chomp @named; + ok(grep(/^EC-Parameters: \(384 bit field, 192 bit security level\)$/, @named), + "named parameters print the EC-Parameters header"); + ok(grep(/^ASN1 OID: secp384r1$/, @named), + "named parameters print the expected curve OID"); + ok(grep(/^NIST CURVE: P-384$/, @named), + "named parameters print the expected NIST curve name"); + + # Explicit parameters print the field parameters instead of the curve name. + my @explicit = run(app(['openssl', 'ecparam', '-text', '-noout', + '-in', $explicit], + stderr => undef), + capture => 1); + chomp @explicit; + ok(grep(/^EC-Parameters: \(384 bit field, 192 bit security level\)$/, @explicit), + "explicit parameters print the EC-Parameters header"); + ok(grep(/^Field Type: prime-field$/, @explicit) + && grep(/^Cofactor:/, @explicit), + "explicit parameters print the field parameters"); + ok(!grep(/^ASN1 OID:/, @explicit), + "explicit parameters do not print a curve OID"); + + ok(run(app(['openssl', 'ecparam', '-list_curves'])), "Test -list_curves"); +}; diff --git a/test/recipes/20-test_app_genec.t b/test/recipes/20-test_app_genec.t new file mode 100644 index 0000000000000..9038d2bb9dcf1 --- /dev/null +++ b/test/recipes/20-test_app_genec.t @@ -0,0 +1,158 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +use strict; +use warnings; + +use OpenSSL::Test qw/:DEFAULT srctop_file/; +use OpenSSL::Test::Utils; + +# The genpkey command line surface for EC: the -pkeyopt names, the output +# format and text options, and the negative cases. None of this varies +# from one curve to the next, so only a few representative curves are +# used here. Every curve is covered in this process by genec_test, which +# is driven by test/recipes/15-test_genec.t. + +sub supported_pass { + my $str = shift; + + ok(run(@_), $str); +} + +sub supported_fail { + my $str = shift; + + ok(!run(@_), $str); +} + +setup("test_app_genec"); + +plan skip_all => "This test is unsupported in a no-ec build" + if disabled("ec"); + +my @curve_list = ('prime256v1'); +push(@curve_list, 'sect233k1') + if !disabled("ec2m"); +push(@curve_list, 'P-256'); +push(@curve_list, 'SM2') + if !disabled("sm2"); + +my @explicit_only_curves = (); +push(@explicit_only_curves, qw( + Oakley-EC2N-3 + Oakley-EC2N-4 + )) if !disabled("ec2m"); + +my @param_encodings = ('named_curve', 'explicit'); + +my @output_formats = ('PEM', 'DER'); + +plan tests => scalar(@curve_list) * scalar(@param_encodings) + * (1 + scalar(@output_formats)) # Try listed @output_formats and text output + * 2 # Test generating parameters and keys + + 1 # Checking that with no curve it fails + + 1 # Checking that with unknown curve it fails + + 1 # Checking that a bad encoding fails + + 1 # Subtest for explicit only curves + + 1 # base serializer test + ; + +ok(!run(app([ 'openssl', 'genpkey', + '-algorithm', 'EC'])), + "genpkey EC with no params should fail"); + +ok(!run(app([ 'openssl', 'genpkey', + '-algorithm', 'EC', + '-pkeyopt', 'ec_paramgen_curve:bogus_foobar_curve'])), + "genpkey EC with unknown curve name should fail"); + +ok(!run(app([ 'openssl', 'genpkey', + '-algorithm', 'EC', + '-pkeyopt', 'ec_paramgen_curve:prime256v1', + '-pkeyopt', 'ec_param_enc:bogus_foobar_encoding'])), + "genpkey EC with unknown parameter encoding should fail"); + +ok(run(app([ 'openssl', 'genpkey', + '-provider-path', 'providers', + '-provider', 'base', + '-config', srctop_file("test", "default.cnf"), + '-algorithm', 'EC', + '-pkeyopt', 'ec_paramgen_curve:prime256v1', + '-text'])), + "generate a private key and serialize it using the base provider"); + +foreach my $curvename (@curve_list) { + foreach my $paramenc (@param_encodings) { + + # --- Test generating parameters --- + + supported_pass("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (text)", + app([ 'openssl', 'genpkey', '-genparam', + '-algorithm', 'EC', + '-pkeyopt', 'ec_paramgen_curve:'.$curvename, + '-pkeyopt', 'ec_param_enc:'.$paramenc, + '-text'])); + + foreach my $outform (@output_formats) { + my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform; + supported_pass("genpkey EC params ${curvename} with ec_param_enc:'${paramenc}' (${outform})", + app([ 'openssl', 'genpkey', '-genparam', + '-algorithm', 'EC', + '-pkeyopt', 'ec_paramgen_curve:'.$curvename, + '-pkeyopt', 'ec_param_enc:'.$paramenc, + '-outform', $outform, + '-out', $outfile])); + } + + # --- Test generating actual keys --- + + supported_pass("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (text)", + app([ 'openssl', 'genpkey', + '-algorithm', 'EC', + '-pkeyopt', 'ec_paramgen_curve:'.$curvename, + '-pkeyopt', 'ec_param_enc:'.$paramenc, + '-text'])); + + foreach my $outform (@output_formats) { + my $outfile = "ecgen.${curvename}.${paramenc}." . lc $outform; + my $outpubfile = "ecgen.${curvename}.${paramenc}-pub." . lc $outform; + supported_pass("genpkey EC key on ${curvename} with ec_param_enc:'${paramenc}' (${outform})", + app([ 'openssl', 'genpkey', + '-algorithm', 'EC', + '-pkeyopt', 'ec_paramgen_curve:'.$curvename, + '-pkeyopt', 'ec_param_enc:'.$paramenc, + '-outform', $outform, + '-out', $outfile, + '-outpubkey', $outpubfile])); + } + } +} + +subtest "test curves that only support explicit parameters encoding" => sub { + plan skip_all => "This test is unsupported under current configuration" + if scalar(@explicit_only_curves) <= 0; + + plan tests => scalar(@explicit_only_curves) * 2; + + foreach my $curvename (@explicit_only_curves) { + supported_fail("genpkey EC params ${curvename} with ec_param_enc:'named_curve' should fail", + app([ 'openssl', 'genpkey', '-genparam', + '-algorithm', 'EC', + '-pkeyopt', 'ec_paramgen_curve:'.$curvename, + '-pkeyopt', 'ec_param_enc:named_curve', + '-text'])); + + supported_pass("genpkey EC params ${curvename} with ec_param_enc:'explicit'", + app([ 'openssl', 'genpkey', '-genparam', + '-algorithm', 'EC', + '-pkeyopt', 'ec_paramgen_curve:'.$curvename, + '-pkeyopt', 'ec_param_enc:explicit', + '-text'])); + } +}; diff --git a/test/recipes/20-test_app_s_client_msg.t b/test/recipes/20-test_app_s_client_msg.t new file mode 100644 index 0000000000000..75d388efe8575 --- /dev/null +++ b/test/recipes/20-test_app_s_client_msg.t @@ -0,0 +1,110 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use IPC::Open3; +use OpenSSL::Test qw/:DEFAULT result_dir srctop_file bldtop_file/; +use OpenSSL::Test::Utils; + +my $test_name = "test_app_s_client_msg"; +setup($test_name); + +plan skip_all => "$test_name needs sock enabled" + if disabled("sock"); +plan skip_all => "$test_name is not available on Windows or VMS" + if $^O =~ /^(VMS|MSWin32|msys)$/; + +my $shlib_wrap = bldtop_file("util", "wrap.pl"); +my $apps_openssl = bldtop_file("apps", "openssl"); +my $server_pem = srctop_file("test", "certs", "servercert.pem"); +my $server_key = srctop_file("test", "certs", "serverkey.pem"); +my $resultdir = result_dir(); + +# Each case exercises the s_client message callback (-msg) over a different +# protocol version. Every record must be decoded; before the DTLSv1.2 fix such +# records were logged as "Not TLS data or unknown version". +my @cases = ( + { name => "TLSv1.2", flag => "-tls1_2", disabled => "tls1_2" }, + { name => "TLSv1.3", flag => "-tls1_3", disabled => "tls1_3" }, + { name => "DTLSv1.2", flag => "-dtls1_2", disabled => "dtls1_2" }, +); +@cases = grep { !disabled($_->{disabled}) } @cases; + +plan tests => scalar @cases; + +# Run one s_server/s_client handshake logging protocol messages via -msgfile. +# Returns the number of decoded and undecoded records seen in the log. +sub run_case +{ + my $case = shift; + my $msgfile = "$resultdir/s_client-msg-$case->{disabled}.txt"; + my ($records, $unknown) = (0, 0); + + eval { + local $SIG{ALRM} = sub { die "timeout\n" }; + alarm 60; + + # Start a server speaking just this protocol version + my @s_server_cmd = ("s_server", $case->{flag}, "-accept", "0", + "-naccept", "1", "-cert", $server_pem, + "-key", $server_key); + my $s_server_pid = open3(my $s_server_i, my $s_server_o, my $s_server_e, + $shlib_wrap, $apps_openssl, @s_server_cmd); + + # Figure out what port it is listening on + my $server_port = "0"; + while (<$s_server_o>) { + print($_); + chomp; + if (/^ACCEPT \S+?:(\d+)/) { + $server_port = $1; + last; + } elsif (/^Using default/) { + ; + } else { + last; + } + } + + # Connect a client that logs the protocol messages to a file. -msgfile + # sets the log destination but selects SSL_trace; the trailing -msg + # switches the callback back to msg_cb (the code under test) while + # keeping the file destination. + my @s_client_cmd = ("s_client", $case->{flag}, "-msgfile", $msgfile, + "-msg", "-connect", "localhost:$server_port"); + my $s_client_pid = open3(my $s_client_i, my $s_client_o, my $s_client_e, + $shlib_wrap, $apps_openssl, @s_client_cmd); + + # Quit the client once connected, then reap both processes + print $s_client_i "Q\n"; + waitpid($s_client_pid, 0); + kill 'HUP', $s_server_pid if kill 0, $s_server_pid; + waitpid($s_server_pid, 0); + + alarm 0; + }; + die $@ if $@ && $@ ne "timeout\n"; + print("TIMEOUT: $case->{name} timed out\n") if $@; + + if (open(my $fh, '<', $msgfile)) { + while (<$fh>) { + $records++ if /^(?:>>>|<<<)/; + $unknown++ if /Not TLS data or unknown version/; + } + close($fh); + } + return ($records, $unknown); +} + +foreach my $case (@cases) { + my ($records, $unknown) = run_case($case); + ok($records > 0 && $unknown == 0, + "s_client -msg decodes all $case->{name} records"); +} diff --git a/test/recipes/20-test_cli_fips.t b/test/recipes/20-test_cli_fips.t index 2abc4d243414c..fd8842b867e58 100644 --- a/test/recipes/20-test_cli_fips.t +++ b/test/recipes/20-test_cli_fips.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -26,11 +26,12 @@ use platform; my $no_check = disabled("fips") || disabled('fips-securitychecks'); plan skip_all => "Test only supported in a fips build with security checks" if $no_check; -plan tests => 12; +plan tests => 13; my $fipsmodule = bldtop_file('providers', platform->dso('fips')); my $fipsconf = srctop_file("test", "fips-and-base.cnf"); my $defaultconf = srctop_file("test", "default.cnf"); +my $identityconf = srctop_file("test" ,"fipsidentity.cnf"); my $tbs_data = $fipsmodule; my $bogus_data = $fipsconf; @@ -282,6 +283,43 @@ SKIP: { }; } +SKIP: { + skip "FIPS RSA tests because of no rsa in this build", 1 + if disabled("rsa"); + + subtest RSA_identity => sub { + my $testtext_prefix = 'RSA'; + my $fips_key = $testtext_prefix.'.fips.priv.pem'; + my $fips_pub_key = $testtext_prefix.'.fips.pub.pem'; + my $nonfips_key = $testtext_prefix.'.nonfips.priv.pem'; + my $nonfips_pub_key = $testtext_prefix.'.nonfips.pub.pem'; + my $testtext = ''; + + plan tests => 2; + + my $destfips = bldtop_file("test-runs", "test_cli_fips", platform->dso("fips-identity")); + copy($fipsmodule, $destfips) or die("Couldn't copy file"); + $ENV{OPENSSL_CONF} = $identityconf; + my $oldmodules = $ENV{OPENSSL_MODULES}; + $ENV{OPENSSL_MODULES} = bldtop_dir("test-runs", "test_cli_fips"); + $testtext = $testtext_prefix.': '. + 'Generate a key with a non-FIPS algorithm with the default provider'; + print "Running genpkey"; + ok(run(app(['openssl', 'genpkey', '-algorithm', 'RSA', + '-pkeyopt', 'rsa_keygen_bits:512', + '-out', $nonfips_key])), + $testtext); + + $testtext = $testtext_prefix.': '. + 'Generate a key with a FIPS algorithm'; + ok(run(app(['openssl', 'genpkey', '-algorithm', 'RSA', + '-pkeyopt', 'rsa_keygen_bits:2048', + '-out', $fips_key])), + $testtext); + $ENV{OPENSSL_MODULES} = $oldmodules; + }; +} + SKIP : { skip "FIPS DSA tests because of no dsa in this build", 1 if disabled("dsa") || $dsasignpass == '0'; diff --git a/test/recipes/20-test_cli_list.t b/test/recipes/20-test_cli_list.t index e528dbb4660d2..7dc3a01f729b3 100644 --- a/test/recipes/20-test_cli_list.t +++ b/test/recipes/20-test_cli_list.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -13,7 +13,7 @@ use OpenSSL::Test qw/:DEFAULT bldtop_file srctop_file bldtop_dir with/; use OpenSSL::Test::Utils; setup("test_cli_list"); -plan tests => 4; +plan tests => 14; my $fipsconf = srctop_file("test", "fips-and-base.cnf"); my $defaultconf = srctop_file("test", "default.cnf"); @@ -31,6 +31,47 @@ sub check_skey_manager_list { check_skey_manager_list("default"); +my @match; + +ok(run(app(["openssl", "list", "-commands"], stdout => "commands.txt")), + "List standard commands"); +open DATA, "commands.txt"; +@match = grep /\blist\b/, ; +close DATA; +ok(scalar @match > 0, "The list command is among the standard commands"); + +ok(run(app(["openssl", "list", "-1", "-commands"], stdout => "commands1.txt")), + "List standard commands in one column"); +open DATA, "commands1.txt"; +@match = grep /^list$/, ; +close DATA; +ok(scalar @match == 1, "One-column output has one command per line"); + +SKIP: { + skip "Deprecated functionality is disabled", 1 + if disabled("deprecated"); + + ok(run(app(["openssl", "list", "-digest-commands"])), + "List digest commands"); +} + +ok(run(app(["openssl", "list", "-options", "list"], stdout => "options.txt")), + "List options of the list command"); +open DATA, "options.txt"; +@match = grep /^select s$/, ; +close DATA; +ok(scalar @match == 1, "The select option is listed for the list command"); + +ok(run(app(["openssl", "list", "-disabled"])), + "List disabled features, algorithms, and protocols"); + +ok(run(app(["openssl", "list", "-objects"], stdout => "objects.txt")), + "List built-in objects"); +open DATA, "objects.txt"; +@match = grep /^CN = commonName, 2\.5\.4\.3$/, ; +close DATA; +ok(scalar @match == 1, "The commonName OID mapping is listed"); + SKIP: { my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0); skip "FIPS provider disabled or not installed", 2 diff --git a/test/recipes/20-test_dgst.t b/test/recipes/20-test_dgst.t index 6cabaf3be55e9..cfca1e2e696d7 100644 --- a/test/recipes/20-test_dgst.t +++ b/test/recipes/20-test_dgst.t @@ -12,13 +12,14 @@ use warnings; use File::Spec; use File::Basename; +use File::Copy; use OpenSSL::Test qw/:DEFAULT with srctop_file srctop_dir data_file bldtop_dir/; use OpenSSL::Test::Utils; use Cwd qw(abs_path); setup("test_dgst"); -plan tests => 26; +plan tests => 31; sub tsignverify { my $testtext = shift; @@ -424,6 +425,118 @@ subtest "signing with xoflen is not supported `dgst` CLI" => sub { "Generating signature with xoflen should fail"); }; +subtest "Coreutils format output with `dgst` CLI" => sub { + my $testdata = srctop_file('test', 'data.bin'); + my $expected = + 'd9fd1d3a7dc90526d2853450dcc63e26a311012d337fa4a192276f9824a046da'; + + # A newline in a filename is not possible everywhere, so that part of + # the test is conditional on actually being able to create such a file. + my $nlfile = "dgst_r_newline\nname.bin"; + my $have_nl = $^O ne 'MSWin32' && $^O ne 'VMS' && copy($testdata, $nlfile); + + plan tests => $have_nl ? 3 : 2; + + my @rdata = run(app(['openssl', 'dgst', '-sha256', '-r', $testdata]), + capture => 1); + chomp(@rdata); + ok($rdata[0] eq "$expected *$testdata", + "-r: Check coreutils style output is as expected ($rdata[0])"); + + # Without a file argument the input is stdin, reported as "stdin" + my @stdindata = run(app(['openssl', 'dgst', '-sha256', '-r'], + stdin => $testdata), capture => 1); + chomp(@stdindata); + ok($stdindata[0] eq "$expected *stdin", + "-r: Check coreutils style output for stdin ($stdindata[0])"); + + if ($have_nl) { + # A newline in the filename is escaped as "\n" and the whole line + # is prefixed with a backslash, the way the '*sum' programs do it. + my @nldata = run(app(['openssl', 'dgst', '-sha256', '-r', $nlfile]), + capture => 1); + chomp(@nldata); + ok($nldata[0] eq "\\$expected *dgst_r_newline\\nname.bin", + "-r: Check newline in filename is escaped ($nldata[0])"); + unlink($nlfile); + } +}; + +subtest "Colon separated output with `dgst` CLI" => sub { + plan tests => 1; + + my $testdata = srctop_file('test', 'data.bin'); + my @cdata = run(app(['openssl', 'dgst', '-sha256', '-c', $testdata]), + capture => 1); + chomp(@cdata); + my $hash = 'd9:fd:1d:3a:7d:c9:05:26:d2:85:34:50:dc:c6:3e:26:' + . 'a3:11:01:2d:33:7f:a4:a1:92:27:6f:98:24:a0:46:da'; + my $expected = qr/SHA2-256\(\Q$testdata\E\)= \Q$hash\E/; + ok($cdata[0] =~ $expected, + "-c: Check colon separated output is as expected ($cdata[0])"); +}; + +subtest "Binary output with `dgst` CLI" => sub { + plan tests => 2; + + my $testdata = srctop_file('test', 'data.bin'); + my $outfile = "dgst_binary_out.bin"; + my $expected = + 'd9fd1d3a7dc90526d2853450dcc63e26a311012d337fa4a192276f9824a046da'; + + ok(run(app(['openssl', 'dgst', '-sha256', '-binary', '-out', $outfile, + $testdata])), + "-binary: Generating binary digest"); + + my $binary = ''; + if (open(my $fh, '<', $outfile)) { + binmode($fh); + local $/; + $binary = <$fh>; + close($fh); + } + ok(unpack("H*", $binary) eq $expected, + "-binary: Check raw digest bytes are as expected"); + unlink($outfile); +}; + +subtest "Hex signature output with `dgst` CLI" => sub { + if (disabled("rsa")) { + plan tests => 1; + ok(1, "Skipped (RSA not supported)"); + return; + } + plan tests => 3; + + my $testdata = srctop_file('test', 'data.bin'); + my $privkey = srctop_file("test", "testrsa.pem"); + my $sigfile = "dgst_hex_sign.sig"; + + # Signature output defaults to binary; -hex must override that. + ok(run(app(['openssl', 'dgst', '-sha256', '-sign', $privkey, + '-out', $sigfile, $testdata])), + "-hex: Generating reference binary signature"); + + my $binsig = ''; + if (open(my $fh, '<', $sigfile)) { + binmode($fh); + local $/; + $binsig = <$fh>; + close($fh); + } + unlink($sigfile); + + my @hexdata = run(app(['openssl', 'dgst', '-sha256', '-hex', + '-sign', $privkey, $testdata]), capture => 1); + chomp(@hexdata); + ok($hexdata[0] =~ /^RSA-SHA2-256\(\Q$testdata\E\)= ([0-9a-f]+)$/, + "-hex: Check hex signature output format ($hexdata[0])"); + my $hexsig = $1 // ''; + # RSA PKCS#1 v1.5 signing is deterministic, so both runs must match. + ok($hexsig eq unpack("H*", $binsig), + "-hex: Check hex signature matches the binary signature"); +}; + subtest "Listing supported digests with `dgst` CLI" => sub { plan tests => 3; @@ -437,6 +550,40 @@ subtest "Listing supported digests with `dgst` CLI" => sub { ok($listing =~ /-sha512\b/, "LIST: Check sha512 is listed"); }; +subtest "signing and verifying with DER `-keyform` `dgst` CLI" => sub { + if (disabled("rsa")) { + plan tests => 1; + ok(1, "Skipped (RSA not supported)"); + return; + } + plan tests => 4; + + my $data_to_sign = srctop_file('test', 'data.bin'); + my $privkey_pem = srctop_file("test", "testrsa.pem"); + my $pubkey_pem = srctop_file("test", "testrsapub.pem"); + my $privkey_der = "testrsa-keyform.der"; + my $pubkey_der = "testrsapub-keyform.der"; + my $sigfile = "testrsa-keyform.sig"; + + # Convert the keys to DER so the `-keyform DER` code path can be exercised. + ok(run(app(['openssl', 'pkey', '-in', $privkey_pem, + '-outform', 'DER', '-out', $privkey_der])), + "Convert private key to DER"); + ok(run(app(['openssl', 'pkey', '-in', $pubkey_pem, '-pubin', + '-outform', 'DER', '-pubout', '-out', $pubkey_der])), + "Convert public key to DER"); + + ok(run(app(['openssl', 'dgst', '-sign', $privkey_der, '-keyform', 'DER', + '-out', $sigfile, + $data_to_sign])), + "Generating signature with DER private key via -keyform"); + + ok(run(app(['openssl', 'dgst', '-verify', $pubkey_der, '-keyform', 'DER', + '-signature', $sigfile, + $data_to_sign])), + "Verify signature with DER public key via -keyform"); +}; + subtest "signing using the nonce-type sigopt" => sub { if (disabled("ec")) { plan tests => 1; diff --git a/test/recipes/20-test_dhparam.t b/test/recipes/20-test_dhparam.t index f08e8dd437242..76ea3f84ff62c 100644 --- a/test/recipes/20-test_dhparam.t +++ b/test/recipes/20-test_dhparam.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -21,7 +21,7 @@ setup("test_dhparam"); plan skip_all => "DH is not supported in this build" if disabled("dh"); -plan tests => 23; +plan tests => 26; my $fipsconf = srctop_file("test", "fips-and-base.cnf"); @@ -156,7 +156,7 @@ subtest "Generate: 512 bit PKCS3 params, generator 2, explicit PEM file" => sub checkdhparams("gen-pkcs3-2-512.exp.pem", "PKCS3", 2, "PEM", 512, 125); }; SKIP: { - skip "Skipping tests that require DSA", 4 if disabled("dsa"); + skip "Skipping tests that require DSA", 7 if disabled("dsa"); subtest "Generate: 512 bit X9.42 params, generator 0, PEM file" => sub { plan tests => 5; @@ -182,6 +182,19 @@ SKIP: { '-dsaparam', '-outform', 'DER', '512' ]))); checkdhparams("gen-x942-0-512.der", "X9.42", 0, "DER", 512); }; + subtest "Convert: 1024 bit DSA params to X9.42 params, PEM file" => sub { + plan tests => 5; + ok(run(app([ 'openssl', 'dhparam', '-dsaparam', + '-in', data_file("dsa-1024.pem"), + '-out', 'conv-x942-0-1024.pem' ]))); + checkdhparams("conv-x942-0-1024.pem", "X9.42", 0, "PEM", 1024); + }; + ok(!run(app([ 'openssl', 'dhparam', '-dsaparam', '-noout', + '-in', data_file("pkcs3-2-1024.pem") ])), + "Reading PKCS3 DH params with -dsaparam should fail"); + ok(!run(app([ 'openssl', 'dhparam', '-noout', + '-in', data_file("dsa-1024.pem") ])), + "Reading DSA params without -dsaparam should fail"); } SKIP: { skip "Skipping tests that are only supported in a fips build with security ". diff --git a/test/recipes/20-test_dhparam_data/dsa-1024.pem b/test/recipes/20-test_dhparam_data/dsa-1024.pem new file mode 100644 index 0000000000000..8943961b084ec --- /dev/null +++ b/test/recipes/20-test_dhparam_data/dsa-1024.pem @@ -0,0 +1,9 @@ +-----BEGIN DSA PARAMETERS----- +MIIBJgKBgQCyCgpMap62rzzHrKhlctvB7OT4mQWQgV7M1pkWGA5eCTh1ZmboddAP +olr83vzRBGdWcHc4WfNEeY5qYHs0TfvDZF/RAc/OFJeiWd6+3ezPw5RwBLAklsbo +Xfox5gsQnduwBp+cXt0aHUT5jX64TIp+C1ErFBBgjCDXyamzXDqRVwIdAPW2VkVB +HAMQPUa0H4+dZfFt4Qj2Dks6p1q0vNcCgYA0h5PdB4LFgNKtaKxgH45sWlUwv8IX +YeAW8ESHUDtvyshR8TMtT17SBhUBDLWdYdANv3eqAI7gEDbp/smgNcWkseT9hzfl +gXCM4op79P8FpecP5dxWgjkglCmn5m2g0PDb+pO0tSunX1aJ+Taj8uwHgLKGm8gz +NIPXl2GH69SDnA== +-----END DSA PARAMETERS----- diff --git a/test/recipes/20-test_enc.t b/test/recipes/20-test_enc.t index fe09dfdd4c93a..1bf1750826d33 100644 --- a/test/recipes/20-test_enc.t +++ b/test/recipes/20-test_enc.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -41,7 +41,7 @@ my @ciphers = |rc2|rc4|seed)/x} @ciphers if disabled("legacy"); -plan tests => 6 + (scalar @ciphers)*2; +plan tests => 11 + (scalar @ciphers)*2; SKIP: { skip "Problems getting ciphers...", 1 + scalar(@ciphers) @@ -102,4 +102,119 @@ plan tests => 6 + (scalar @ciphers)*2; "-out", "key_from_uri.enc" ])) && File::Compare::compare("key_from_cmdline.enc", "key_from_uri.enc") == 0, "Check that key from URI gives an equal result comparing to the explicit one"); + + # -P prints the salt/key/iv and exits. With a fixed salt and PBKDF2 the + # derived key and iv are deterministic, so the whole output can be checked. + subtest "-P prints the derived key material" => sub { + plan tests => 5; + + my @pout = run(app([$cmd, "enc", "-aes-128-cbc", "-pbkdf2", + "-S", "0102030405060708", "-P", + "-pass", "pass:password"]), capture => 1); + chomp(@pout); + is($pout[0], "salt=0102030405060708", "-P prints the expected salt"); + is($pout[1], "key=F550F3F36CA07658588CBEA7D3B646C6", + "-P prints the expected key"); + is($pout[2], "iv =4080F8E5384C695DB2F79E46195168B8", + "-P prints the expected iv"); + + # With -nosalt no salt is used, so no salt line is printed and the + # derived key/iv differ from the salted case above. + my @pout_nosalt = run(app([$cmd, "enc", "-aes-128-cbc", "-pbkdf2", + "-nosalt", "-P", + "-pass", "pass:password"]), capture => 1); + chomp(@pout_nosalt); + is($pout_nosalt[0], "key=E11244295150E6713CD76E9A51123470", + "-P with -nosalt prints no salt line"); + is($pout_nosalt[1], "iv =93BDB6ACBF0C8021ABAE29881130B210", + "-P with -nosalt prints the expected iv"); + }; + + subtest "-nosalt encrypt/decrypt round-trip" => sub { + plan tests => 3; + + ok(run(app([$cmd, "enc", "-aes-128-cbc", "-nosalt", "-e", "-k", "test", + "-in", $test, "-out", "nosalt.cipher"])), + "encrypt with -nosalt"); + ok(run(app([$cmd, "enc", "-aes-128-cbc", "-nosalt", "-d", "-k", "test", + "-in", "nosalt.cipher", "-out", "nosalt.clear"])), + "decrypt with -nosalt"); + ok(compare_text($test, "nosalt.clear") == 0, + "decrypted output matches the original"); + }; + + subtest "-md selects the key derivation digest" => sub { + plan tests => 4; + + ok(run(app([$cmd, "enc", "-aes-128-cbc", "-md", "sha1", "-e", "-k", "test", + "-in", $test, "-out", "md.cipher"])), + "encrypt with -md sha1"); + ok(run(app([$cmd, "enc", "-aes-128-cbc", "-md", "sha1", "-d", "-k", "test", + "-in", "md.cipher", "-out", "md.clear"])), + "decrypt with -md sha1"); + ok(compare_text($test, "md.clear") == 0, + "decrypted output matches the original"); + # A mismatching digest derives a different key. The decryption + # usually fails on the padding check, but with a random salt the + # garbage last block occasionally happens to look like valid + # padding, in which case it succeeds and produces garbage instead. + ok(!run(app([$cmd, "enc", "-aes-128-cbc", "-md", "sha256", "-d", "-k", "test", + "-in", "md.cipher", "-out", "md_mismatch.clear"])) + || compare_text($test, "md_mismatch.clear") != 0, + "decrypt does not recover the plaintext when -md does not match"); + }; + + subtest "-iter sets the PBKDF2 iteration count" => sub { + plan tests => 4; + + ok(run(app([$cmd, "enc", "-aes-128-cbc", "-iter", "5", "-e", "-k", "test", + "-in", $test, "-out", "iter.cipher"])), + "encrypt with -iter 5"); + ok(run(app([$cmd, "enc", "-aes-128-cbc", "-iter", "5", "-d", "-k", "test", + "-in", "iter.cipher", "-out", "iter.clear"])), + "decrypt with -iter 5"); + ok(compare_text($test, "iter.clear") == 0, + "decrypted output matches the original"); + # As with -md above, a mismatching iteration count derives a + # different key, so the decryption either fails on the padding check + # or, when the garbage happens to look like valid padding, succeeds + # and yields garbage. + ok(!run(app([$cmd, "enc", "-aes-128-cbc", "-iter", "6", "-d", "-k", "test", + "-in", "iter.cipher", "-out", "iter_mismatch.clear"])) + || compare_text($test, "iter_mismatch.clear") != 0, + "decrypt does not recover the plaintext when -iter does not match"); + }; + + subtest "-kfile reads the passphrase from a file" => sub { + plan tests => 5; + + # The trailing CRLF must be stripped from the passphrase. + open my $fh, ">", "kfile.pass" or die "Cannot write kfile.pass: $!"; + print $fh "secret\r\n"; + close $fh; + + ok(run(app([$cmd, "enc", "-aes-128-cbc", "-e", "-kfile", "kfile.pass", + "-in", $test, "-out", "kfile.cipher"])), + "encrypt with -kfile"); + ok(run(app([$cmd, "enc", "-aes-128-cbc", "-d", "-k", "secret", + "-in", "kfile.cipher", "-out", "kfile.clear"])), + "decrypt with the same passphrase given with -k"); + ok(compare_text($test, "kfile.clear") == 0, + "decrypted output matches the original"); + + open $fh, ">", "kfile_empty.pass" or die "Cannot write file: $!"; + close $fh; + ok(!run(app([$cmd, "enc", "-aes-128-cbc", "-e", + "-kfile", "kfile_empty.pass", + "-in", $test, "-out", "kfile_fail.cipher"])), + "an empty passphrase file is rejected"); + + open $fh, ">", "kfile_newline.pass" or die "Cannot write file: $!"; + print $fh "\n"; + close $fh; + ok(!run(app([$cmd, "enc", "-aes-128-cbc", "-e", + "-kfile", "kfile_newline.pass", + "-in", $test, "-out", "kfile_fail.cipher"])), + "a passphrase file with only a newline is rejected"); + }; } diff --git a/test/recipes/20-test_enc_skey.t b/test/recipes/20-test_enc_skey.t new file mode 100644 index 0000000000000..c5305cbeb3ecb --- /dev/null +++ b/test/recipes/20-test_enc_skey.t @@ -0,0 +1,121 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use File::Compare qw/compare/; +use OpenSSL::Test qw/:DEFAULT bldtop_dir with/; +use OpenSSL::Test::Utils; + +setup("test_enc_skey"); + +# The opaque key roundtrip through a provider-implemented cipher needs the +# loadable fake-cipher provider, which is only built with module support. +my $fake_cipher = !disabled('module'); + +plan tests => 2 + ($fake_cipher ? 1 : 0); + +my $key = "000102030405060708090a0b0c0d0e0f"; +my $iv = "00112233445566778899aabbccddeeff"; +my $plain = "plain.txt"; + +open my $fh, ">", $plain or die "Cannot write $plain: $!"; +print $fh "Opaque symmetric key test payload." x 4, "\n"; +close $fh; + +# Helper: run enc expecting a non-zero (failure) exit code, and check that +# stderr matches a regular expression. +sub enc_fails { + my ($testtext, $re, @args) = @_; + + my $stderr_file = "enc_skey_err.txt"; + my $err = ''; + + with({ exit_checker => sub { return shift != 0; } }, + sub { + ok(run(app(['openssl', 'enc', @args], stderr => $stderr_file)), + $testtext); + }); + + if (open(my $fh, '<', $stderr_file)) { + $err = do { local $/; <$fh> }; + close($fh); + } + ok($err =~ $re, "$testtext: stderr matches"); + unlink($stderr_file) if -f $stderr_file; +} + +subtest "enc with an opaque key matches raw key encryption" => sub { + plan tests => 5; + + ok(run(app(['openssl', 'enc', '-aes-128-cbc', '-e', + '-skeymgmt', 'AES', '-skeyopt', "hexraw-bytes:$key", + '-iv', $iv, '-in', $plain, '-out', 'enc_skey.bin'])), + "encrypt with an opaque key built from -skeyopt raw bytes"); + ok(run(app(['openssl', 'enc', '-aes-128-cbc', '-e', + '-K', $key, '-iv', $iv, + '-in', $plain, '-out', 'enc_raw.bin'])), + "encrypt with the same raw key"); + is(compare('enc_skey.bin', 'enc_raw.bin'), 0, + "opaque and raw key encryption produce the same ciphertext"); + ok(run(app(['openssl', 'enc', '-aes-128-cbc', '-d', + '-skeymgmt', 'AES', '-skeyopt', "hexraw-bytes:$key", + '-iv', $iv, '-in', 'enc_skey.bin', '-out', 'dec_skey.txt'])), + "decrypt with the opaque key"); + is(compare('dec_skey.txt', $plain), 0, + "decryption with the opaque key recovers the plaintext"); +}; + +subtest "enc opaque key error handling" => sub { + plan tests => 8; + + enc_fails("a raw key and -skeyopt together are rejected", + qr/Either a raw key or the skeyopt\/skeyuri args must be used/, + '-aes-128-cbc', '-e', '-K', $key, '-iv', $iv, + '-skeyopt', "hexraw-bytes:$key", '-in', $plain); + enc_fails("an unknown -skeymgmt is rejected", + qr/Error creating opaque key object for skeymgmt NoSuchMgmt/, + '-aes-128-cbc', '-e', '-skeymgmt', 'NoSuchMgmt', + '-skeyopt', "hexraw-bytes:$key", '-iv', $iv, '-in', $plain); + enc_fails("an unknown -skeyopt parameter is rejected", + qr/Parameter unknown 'nosuchopt:1'/, + '-aes-128-cbc', '-e', '-skeymgmt', 'AES', + '-skeyopt', 'nosuchopt:1', '-iv', $iv, '-in', $plain); + enc_fails("a malformed -skeyopt without a value is rejected", + qr/Parameter error 'raw-bytes'/, + '-aes-128-cbc', '-e', '-skeymgmt', 'AES', + '-skeyopt', 'raw-bytes', '-iv', $iv, '-in', $plain); +}; + +# The fake-cipher provider names both its cipher and its skey management +# "fake_cipher", so it also covers defaulting the skeymgmt name to the +# cipher name when -skeymgmt is not given. +if ($fake_cipher) { + subtest "enc with an opaque key from the fake-cipher provider" => sub { + plan tests => 4; + + $ENV{OPENSSL_MODULES} = bldtop_dir("test"); + my @prov = ('-provider-path', bldtop_dir("test"), + '-provider', 'fake-cipher', '-provider', 'default'); + + ok(run(app(['openssl', 'enc', @prov, '-fake_cipher', '-e', + '-skeyopt', 'key_name:testkey', + '-skeyopt', "hexraw-bytes:$key", + '-in', $plain, '-out', 'enc_fake.bin'])), + "encrypt with an opaque key without -skeymgmt"); + isnt(compare('enc_fake.bin', $plain), 0, + "the fake cipher transformed the plaintext"); + ok(run(app(['openssl', 'enc', @prov, '-fake_cipher', '-d', + '-skeyopt', "hexraw-bytes:$key", + '-in', 'enc_fake.bin', '-out', 'dec_fake.txt'])), + "decrypt with the opaque key without -skeymgmt"); + is(compare('dec_fake.txt', $plain), 0, + "decryption with the opaque key recovers the plaintext"); + }; +} diff --git a/test/recipes/20-test_kdf.t b/test/recipes/20-test_kdf.t index 8d926d68b3d6c..3f6a1e7ab84bd 100755 --- a/test/recipes/20-test_kdf.t +++ b/test/recipes/20-test_kdf.t @@ -88,6 +88,13 @@ my @krb5kdf_tests = ( desc => 'KRB5KDF AES-128-CBC'}, ); +my @kdf_bin_tests = ( + { cmd => [qw{openssl kdf -keylen 10 -binary -out hkdf-sha256.bin -kdfopt digest:SHA256 -kdfopt key:secret -kdfopt salt:salt -kdfopt info:label HKDF}], + outfile => 'hkdf-sha256.bin', + expected => '2ac4369f525996f8de13', + desc => 'HKDF SHA256 binary output' }, +); + my @scrypt_tests = ( { cmd => [qw{openssl kdf -keylen 64 -kdfopt pass:password -kdfopt salt:NaCl -kdfopt n:1024 -kdfopt r:8 -kdfopt p:16 -kdfopt maxmem_bytes:10485760 id-scrypt}], expected => 'fd:ba:be:1c:9d:34:72:00:78:56:e7:19:0d:01:e9:fe:7c:6a:d7:cb:c8:23:78:30:e7:73:76:63:4b:37:31:62:2e:af:30:d9:2e:22:a3:88:6f:f1:09:27:9d:98:30:da:c7:27:af:b9:4a:83:ee:6d:83:60:cb:df:a2:cc:06:40', @@ -99,12 +106,16 @@ push @kdf_tests, @scrypt_tests unless disabled("scrypt"); push @kdf_tests, @sshkdf_tests unless disabled("sshkdf"); push @kdf_tests, @sskdf_tests unless disabled("sskdf"); -plan tests => scalar @kdf_tests; +plan tests => scalar @kdf_tests + scalar @kdf_bin_tests; foreach (@kdf_tests) { ok(compareline($_->{cmd}, $_->{expected}), $_->{desc}); } +foreach (@kdf_bin_tests) { + ok(comparebinary($_->{cmd}, $_->{outfile}, $_->{expected}), $_->{desc}); +} + # Check that the stdout output matches the expected value. sub compareline { my ($cmdarray, $expect) = @_; @@ -118,10 +129,28 @@ sub compareline { if ($lines[0] =~ m|^\Q${expect}\E\R$|) { return 1; } else { - print "Got: $lines[0]"; - print "Exp: $expect\n"; + diag("Got: $lines[0]"); + diag("Exp: $expect"); return 0; } } return 0; } + +# Check that the binary output file matches the expected value. +sub comparebinary { + my ($cmdarray, $outfile, $expect) = @_; + + return 0 unless run(app($cmdarray)); + + open(my $fh, '<:raw', $outfile) or return 0; + my $got = unpack('H*', do { local $/; <$fh> }); + close($fh); + + if ($got ne lc $expect) { + diag("Got: $got"); + diag("Exp: $expect"); + return 0; + } + return 1; +} diff --git a/test/recipes/20-test_mac.t b/test/recipes/20-test_mac.t index 84a8899049125..69cbc18ad07d9 100644 --- a/test/recipes/20-test_mac.t +++ b/test/recipes/20-test_mac.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/20-test_pkeyutl.t b/test/recipes/20-test_pkeyutl.t index dec9b4b183943..6becd8eb083c7 100644 --- a/test/recipes/20-test_pkeyutl.t +++ b/test/recipes/20-test_pkeyutl.t @@ -17,7 +17,7 @@ use File::Compare qw/compare_text compare/; setup("test_pkeyutl"); -plan tests => 33; +plan tests => 34; # For the tests below we use the cert itself as the TBS file @@ -99,6 +99,15 @@ SKIP: { "Verify an Ed448 signature against a piece of data, no -rawin"); } +sub slurp { + my $file = shift; + + open(my $fh, '<', $file) or return ''; + my $data = do { local $/; <$fh> }; + close($fh); + return $data; +} + my $sigfile; sub tsignverify { my $testtext = shift; @@ -165,7 +174,7 @@ sub tsignverify { } SKIP: { - skip "RSA is not supported by this OpenSSL build", 3 + skip "RSA is not supported by this OpenSSL build", 5 if disabled("rsa"); subtest "RSA CLI signature generation and verification" => sub { @@ -175,8 +184,12 @@ SKIP: { "-rawin", "-digest", "sha256"); }; + # -verifyrecover outputs the recovered payload (binary, without a + # trailing newline), which would otherwise be echoed into the TAP + # stream by run() and corrupt it, so redirect it to a file. ok(run(app((['openssl', 'pkeyutl', '-verifyrecover', '-in', $sigfile, - '-pubin', '-inkey', srctop_file('test', 'testrsapub.pem')]))), + '-pubin', '-inkey', srctop_file('test', 'testrsapub.pem')], + stdout => 'rsa_verifyrecover.out'))), "RSA: Verify signature with -verifyrecover"); subtest "RSA CLI signature and verification with pkeyopt" => sub { @@ -223,6 +236,43 @@ SKIP: { }); }; + subtest "pkeyutl output formatting with -asn1parse and -hexdump" => sub { + plan tests => 7; + + my $key = srctop_file("test", "testrsa.pem"); + my $pub = srctop_file("test", "testrsapub.pem"); + my $data = srctop_file("test", "data.bin"); + + ok(run(app(['openssl', 'pkeyutl', '-sign', '-inkey', $key, + '-rawin', '-digest', 'sha256', + '-in', $data, '-out', 'fmt.sig'])), + "Sign data for the output formatting tests"); + + # -verifyrecover recovers the DigestInfo blob, which is valid ASN.1 + ok(run(app((['openssl', 'pkeyutl', '-verifyrecover', '-asn1parse', + '-pubin', '-inkey', $pub, '-in', 'fmt.sig'], + stdout => 'fmt_asn1.txt'))), + "Recover the signed DigestInfo with -asn1parse"); + my $asn1 = slurp('fmt_asn1.txt'); + ok($asn1 =~ /SEQUENCE/ && $asn1 =~ /:sha256/ && $asn1 =~ /OCTET STRING/, + "-asn1parse prints the parsed DigestInfo structure"); + + ok(run(app((['openssl', 'pkeyutl', '-verifyrecover', '-hexdump', + '-pubin', '-inkey', $pub, '-in', 'fmt.sig'], + stdout => 'fmt_hex.txt'))), + "Recover the signed DigestInfo with -hexdump"); + ok(slurp('fmt_hex.txt') =~ /^0000 - 30 31 30 0d/, + "-hexdump prints a hex dump of the DigestInfo"); + + # a raw RSA signature is not valid ASN.1, but the parse error + # is only reported and the command still succeeds + ok(run(app((['openssl', 'pkeyutl', '-sign', '-asn1parse', + '-inkey', $key, '-rawin', '-digest', 'sha256', + '-in', $data], stdout => 'fmt_bad_asn1.txt'))), + "-asn1parse on output that is not valid ASN.1 still succeeds"); + ok(slurp('fmt_bad_asn1.txt') =~ /Error in encoding/, + "-asn1parse reports the encoding error"); + }; } SKIP: { @@ -451,7 +501,7 @@ SKIP: { my $ecpub = srctop_file("test", "testecpub-p256.pem"); my $rsapub = srctop_file("test", "testrsapub.pem"); - plan tests => 5; + plan tests => 8; # ECDH derive against a matching peer public key ok(run(app(['openssl', 'pkeyutl', '-derive', @@ -459,6 +509,27 @@ SKIP: { '-out', 'derive_secret.bin'])), "Derive shared secret with matching peer key"); + # -peerform: load the peer public key from a DER file and check the + # derived secret matches the one derived from the PEM peer key. + my $ecpub_der = "peer-p256.der"; + ok(run(app(['openssl', 'pkey', '-pubin', '-in', $ecpub, + '-outform', 'DER', '-out', $ecpub_der])), + "Convert peer public key to DER"); + ok(run(app(['openssl', 'pkeyutl', '-derive', + '-inkey', $eckey, '-peerkey', $ecpub_der, + '-peerform', 'DER', '-out', 'derive_secret_der.bin'])) + && compare('derive_secret.bin', 'derive_secret_der.bin') == 0, + "Derive with DER peer key via -peerform matches the PEM result"); + + # -peerform mismatch: reading a DER peer key as PEM fails. + with({ exit_checker => sub { return shift == 1; } }, + sub { + ok(run(app(['openssl', 'pkeyutl', '-derive', + '-inkey', $eckey, '-peerkey', $ecpub_der, + '-peerform', 'PEM'])), + "Fail when -peerform does not match the peer key encoding"); + }); + # setup_peer: peer key file cannot be loaded with({ exit_checker => sub { return shift == 1; } }, sub { diff --git a/test/recipes/20-test_prime.t b/test/recipes/20-test_prime.t index a44cdf0862a5c..e66f5113ba7ab 100644 --- a/test/recipes/20-test_prime.t +++ b/test/recipes/20-test_prime.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -9,12 +9,14 @@ use strict; use warnings; +use Math::BigInt; + use OpenSSL::Test qw(:DEFAULT data_file); use OpenSSL::Test; setup("test_prime"); -plan tests => 10; +plan tests => 19; my $prime_file = data_file("prime.txt"); my $composite_file = data_file("composite.txt"); @@ -54,4 +56,53 @@ ok(run(app(["openssl", "prime", "-in", $prime_file, $composite_file, $long_numbe "Run openssl prime with multiple -in files"); ok(run(app(["openssl", "prime", "-in", "does_not_exist.txt"])), - "Run openssl prime with -in file that does not exist"); \ No newline at end of file + "Run openssl prime with -in file that does not exist"); + +my @generated = run(app(["openssl", "prime", "-generate", "-bits", "128"]), + capture => 1); +chomp @generated; + +ok(@generated == 1 && $generated[0] =~ /^\d+$/, + "Run openssl prime -generate with decimal output"); + +ok(is_reported_prime($generated[0]), + "Generated decimal number is prime"); + +@generated = run(app(["openssl", "prime", "-generate", "-bits", "128", "-hex"]), + capture => 1); +chomp @generated; + +ok(@generated == 1 && $generated[0] =~ /^[89A-F][0-9A-F]{31}$/, + "Run openssl prime -generate with 128 bit hex output"); + +ok(is_reported_prime($generated[0], "-hex"), + "Generated hex number is prime"); + +@generated = run(app(["openssl", "prime", "-generate", "-bits", "128", "-safe"]), + capture => 1); +chomp @generated; + +ok(@generated == 1 && $generated[0] =~ /^\d+$/, + "Run openssl prime -generate with -safe"); + +ok(is_reported_prime($generated[0]), + "Generated safe prime is prime"); + +my $q = @generated == 1 + ? Math::BigInt->new($generated[0])->bsub(1)->bdiv(2)->bstr() : "0"; +ok(is_reported_prime($q), + "Generated safe prime (p-1)/2 is prime"); + +ok(!run(app(["openssl", "prime", "-generate"])), + "Run openssl prime -generate without -bits fails"); + +ok(!run(app(["openssl", "prime", "-generate", "-bits", "128", "42"])), + "Run openssl prime -generate with a number argument fails"); + +# Check that the app reports the given number as prime. +sub is_reported_prime { + my ($num, @flags) = @_; + my @out = run(app(["openssl", "prime", @flags, $num // "0"]), + capture => 1); + return scalar grep { / is prime$/ } @out; +} diff --git a/test/recipes/20-test_rand_config.t b/test/recipes/20-test_rand_config.t index 1db541ffe09b7..675df8e9ae0aa 100644 --- a/test/recipes/20-test_rand_config.t +++ b/test/recipes/20-test_rand_config.t @@ -10,7 +10,7 @@ use strict; use warnings; -use OpenSSL::Test qw/:DEFAULT result_dir/; +use OpenSSL::Test qw/:DEFAULT result_dir with/; use OpenSSL::Test::Utils; setup("test_rand_config"); @@ -57,7 +57,41 @@ my @aria_tests = ( push @rand_tests, @aria_tests unless disabled("aria"); -plan tests => scalar @rand_tests * 2; +# Configured seed sources must be honoured: an available one is used and +# an unavailable one is an error rather than a silent fallback to the +# operating system entropy sources. Not applicable to enable-fips-jitter +# builds, which hard-wire the JITTER seed source. +my $rand_seed_none = + grep { $_ eq 'OPENSSL_RAND_SEED_NONE' } + @{ config('openssl_feature_defines') // [] }; +my @seed_tests; +if (disabled("fips-jitter")) { + push @seed_tests, + { seed => 'SEED-SRC', + expected_ok => 1, + desc => 'configured SEED-SRC seed source works' } + unless $rand_seed_none; + push @seed_tests, + { seed => 'SEED-SRC', + strict => 'yes', + expected_ok => 1, + desc => 'strictly configured SEED-SRC seed source works' } + unless $rand_seed_none; + push @seed_tests, + { seed => 'NONEXISTENT-SEED-SOURCE', + expected_ok => 0, + desc => 'unavailable configured seed source fails, no fallback' }; + push @seed_tests, + { seed => 'HASH-DRBG', + strict => 'yes', + args => ['-hex', '1'], + expected_exit => 1, + stderr_re => qr/error:1200006E:/, + desc => 'recursive strict seed source fails cleanly' }; +} + +plan tests => scalar @rand_tests * 2 + scalar @seed_tests + + scalar grep { defined $_->{stderr_re} } @seed_tests; my $contents =<<'CONFIGEND'; openssl_conf = openssl_init @@ -91,6 +125,41 @@ foreach (@rand_tests) { ok(run(app(["openssl", "rand", "-writerand", "$result_dir/$tmpfile.bin"]))); } +foreach (@seed_tests) { + my $tmpfile = 'rand_seed_config.cfg'; + open(my $cfg, '>', $tmpfile) or die "Could not open file"; + print $cfg $contents; + print $cfg "seed = $_->{seed}\n"; + print $cfg "seed_strict = $_->{strict}\n" if defined $_->{strict}; + close $cfg; + + $ENV{OPENSSL_CONF} = $tmpfile; + + my @args = @{ $_->{args} // ['-hex', '16'] }; + if (defined $_->{expected_exit}) { + my $expected_exit = $_->{expected_exit}; + my $stderr_file = 'rand_seed_config.err'; + + with({ exit_checker => sub { return shift == $expected_exit; } }, + sub { + ok(run(app(["openssl", "rand", @args], + stderr => $stderr_file)), $_->{desc}); + }); + if (defined $_->{stderr_re}) { + open(my $err, '<', $stderr_file) + or die "Could not open error output"; + my $error = do { local $/; <$err> }; + close($err); + like($error, $_->{stderr_re}, + "$_->{desc} reports a RAND error"); + } + unlink($stderr_file); + } else { + my $ok = run(app(["openssl", "rand", @args])); + ok(!$ok == !$_->{expected_ok}, $_->{desc}); + } +} + # Check that the stdout output contains the expected values. sub comparelines { my @lines = run(app(["openssl", "list", "--random-instances"]), diff --git a/test/recipes/20-test_skeyutl.t b/test/recipes/20-test_skeyutl.t index 1c69935cac38c..f37be39d89ae6 100644 --- a/test/recipes/20-test_skeyutl.t +++ b/test/recipes/20-test_skeyutl.t @@ -18,7 +18,7 @@ setup("test_skeyutl"); # when module support is enabled. my $fake_cipher = !disabled('module'); -plan tests => 14 + ($fake_cipher ? 2 : 0); +plan tests => 14 + ($fake_cipher ? 8 : 0); # Helper: run skeyutl expecting a non-zero (failure) exit code, and optionally # check that stderr matches a regular expression. @@ -96,4 +96,29 @@ if ($fake_cipher) { ok($status, "skeyutl -genkey with fake-cipher provider succeeds"); ok(grep(/opaque key/, @out), "skeyutl -genkey reports the generated opaque key"); + + # -skeyopt values are passed to the key generation. The fake-cipher + # provider names the generated key after its key_name parameter, so the + # option shows up in the reported key id. + my $rawopt = 'hexraw-bytes:00112233445566778899aabbccddeeff'; + @out = run(app(['openssl', 'skeyutl', @prov, '-genkey', + '-skeymgmt', 'fake_cipher', + '-skeyopt', 'key_name:testkey', + '-skeyopt', $rawopt]), + capture => 1, statusvar => \$status); + ok($status, "skeyutl -genkey with -skeyopt succeeds"); + ok(grep(/opaque key identified by testkey/, @out), + "skeyutl -genkey applies the -skeyopt key name"); + + # An option not settable by the key management is rejected + skeyutl_fails("skeyutl -genkey with an unknown -skeyopt fails", + qr/Parameter unknown 'nosuchopt:1'/, + @prov, '-genkey', '-skeymgmt', 'fake_cipher', + '-skeyopt', 'nosuchopt:1'); + + # A -skeyopt without the opt:value separator is rejected + skeyutl_fails("skeyutl -genkey with a malformed -skeyopt fails", + qr/Parameter error 'key_name'/, + @prov, '-genkey', '-skeymgmt', 'fake_cipher', + '-skeyopt', 'key_name'); } diff --git a/test/recipes/25-test_configutl.t b/test/recipes/25-test_configutl.t index 880758b35a0c0..6fe258e234f24 100644 --- a/test/recipes/25-test_configutl.t +++ b/test/recipes/25-test_configutl.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/25-test_crl.t b/test/recipes/25-test_crl.t index a65b2c6ce8704..1537994783f98 100644 --- a/test/recipes/25-test_crl.t +++ b/test/recipes/25-test_crl.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -16,7 +16,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/; setup("test_crl"); -plan tests => 12; +plan tests => 13; require_ok(srctop_file('test','recipes','tconversion.pl')); @@ -45,6 +45,31 @@ ok(compare1stline_stdin([qw{openssl crl -hash -noout}], '106cd822'), "crl piped input test"); +# Cover the -crlnumber and -issuer print options. +subtest 'crl -crlnumber and -issuer' => sub { + plan tests => 4; + + my $crl_num = + srctop_file("test/certs", "delta-crl-as-complete-delta.pem"); + my $crl_nonum = srctop_file("test", "testcrl.pem"); + my $issuer_num = "issuer=CN=Delta CRL as Complete Test CA"; + my $issuer_nonum = "issuer=C=US, O=RSA Data Security, Inc.," + . " OU=Secure Server Certification Authority"; + + ok(compare1stline([qw{openssl crl -noout -crlnumber -in}, $crl_num], + 'crlNumber=0x2000'), + "-crlnumber prints the CRL Number"); + ok(compare1stline([qw{openssl crl -noout -crlnumber -in}, $crl_nonum], + 'crlNumber='), + "-crlnumber prints when the CRL has no CRL Number"); + ok(compare1stline([qw{openssl crl -noout -issuer -in}, $crl_num], + $issuer_num), + "-issuer prints the CRL issuer DN"); + ok(compare1stline([qw{openssl crl -noout -issuer -in}, $crl_nonum], + $issuer_nonum), + "-issuer prints another CRL issuer DN"); +}; + ok(!run(app(["openssl", "crl", "-text", "-in", $pem, "-inform", "DER", "-out", $out, "-nameopt", "utf8"]))); ok(run(app(["openssl", "crl", "-text", "-in", $pem, "-inform", "PEM", diff --git a/test/recipes/25-test_pkcs7.t b/test/recipes/25-test_pkcs7.t index 3801c4b106899..fef722a6aa328 100644 --- a/test/recipes/25-test_pkcs7.t +++ b/test/recipes/25-test_pkcs7.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/25-test_pkcs8.t b/test/recipes/25-test_pkcs8.t index bd7224459bb36..92717c0a27eff 100644 --- a/test/recipes/25-test_pkcs8.t +++ b/test/recipes/25-test_pkcs8.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -16,7 +16,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file ok_nofips is_nofips/; setup("test_pkcs8"); -plan tests => 19; +plan tests => 20; my $pc5_key = srctop_file('test', 'certs', 'pc5-key.pem'); @@ -160,6 +160,23 @@ subtest 'PKCS#8 DER inform/outform round trip' => sub { "read encrypted PKCS#8 from DER form"); }; +subtest 'PKCS#8 -nocrypt reads an unencrypted PKCS#8 PEM' => sub { + plan tests => 3; + + # Write an unencrypted PKCS#8 (PrivateKeyInfo) in PEM form. + my $p8_pem = 'p8-nocrypt-pem.pem'; + ok(run(app(['openssl', 'pkcs8', '-topk8', '-nocrypt', + '-in', $pc5_key, '-out', $p8_pem])), + "write unencrypted PKCS#8 in PEM form"); + # Read it back with -nocrypt from PEM (the default input format). + my $recovered = 'p8-nocrypt-pem-read.pem'; + ok(run(app(['openssl', 'pkcs8', '-nocrypt', + '-in', $p8_pem, '-out', $recovered])), + "read unencrypted PKCS#8 from PEM form"); + is(compare_text($pc5_key, $recovered), 0, + "recovered key matches the original"); +}; + SKIP: { skip "SM2, SM3 or SM4 is not supported by this OpenSSL build", 3 if disabled("sm2") || disabled("sm3") || disabled("sm4"); diff --git a/test/recipes/25-test_req.t b/test/recipes/25-test_req.t index a37686736fac0..723d6d308291c 100644 --- a/test/recipes/25-test_req.t +++ b/test/recipes/25-test_req.t @@ -15,7 +15,7 @@ use OpenSSL::Test qw/:DEFAULT srctop_file/; setup("test_req"); -plan tests => 131; +plan tests => 134; require_ok(srctop_file('test', 'recipes', 'tconversion.pl')); @@ -147,6 +147,28 @@ subtest "generating certificate requests with RSA" => sub { } }; +subtest "RSA requests with truncated SHA-512 digests" => sub { + plan tests => 2; + + SKIP: { + skip "RSA is not supported by this OpenSSL build", 2 + if disabled("rsa"); + + foreach my $digest ("sha512-224", "sha512-256") { + my $request = "testreq-rsa-$digest.pem"; + + ok(run(app(["openssl", "req", + "-config", srctop_file("test", "test.cnf"), + "-new", "-out", $request, + "-key", srctop_file("test", "testrsa.pem"), + "-$digest"])) + && run(app(["openssl", "req", "-verify", + "-in", $request, "-noout"])), + "Generating and verifying request with RSA and $digest"); + } + } +}; + subtest "generating certificate requests with RSA-PSS" => sub { plan tests => 12; @@ -321,6 +343,70 @@ subtest "generating certificate requests" => sub { "Verifying signature on request"); }; +subtest "generating certificate requests with attributes" => sub { + plan tests => 10; + + my $csr = "testreq-attrs.pem"; + my $out = "testreq-attrs.txt"; + + ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"), + "-section", "req_attrs", + "-key", srctop_file(@certs, "ee-key.pem"), + @req_new, "-out", $csr])), + "Generating request with prompted attributes"); + + ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"), + "-verify", "-in", $csr, "-noout"])), + "Verifying signature on request with prompted attributes"); + + ok(run(app(["openssl", "req", "-in", $csr, "-noout", "-text", + "-out", $out])), + "Printing text of request with prompted attributes"); + test_file_contains("request with prompted attributes", $out, + "challengePassword", 1); + test_file_contains("request with prompted attributes", $out, + "An Example Company", 1); + + $csr = "testreq-attrs-noprompt.pem"; + $out = "testreq-attrs-noprompt.txt"; + + ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"), + "-section", "req_attrs_noprompt", + "-key", srctop_file(@certs, "ee-key.pem"), + @req_new, "-out", $csr])), + "Generating request with attributes without prompting"); + + ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"), + "-verify", "-in", $csr, "-noout"])), + "Verifying signature on request with attributes without prompting"); + + ok(run(app(["openssl", "req", "-in", $csr, "-noout", "-text", + "-out", $out])), + "Printing text of request with attributes without prompting"); + test_file_contains("request with attributes without prompting", $out, + "challengePassword", 1); + test_file_contains("request with attributes without prompting", $out, + "NopromptSecret456", 1); +}; + +subtest "modifying the subject of an existing certificate request" => sub { + plan tests => 3; + + my $req_in = srctop_file("test", "testreq2.pem"); + my $req_out = "testreq-modified-subj.pem"; + my $subj_out = "testreq-modified-subj.txt"; + + ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"), + "-in", $req_in, "-subj", "/CN=Modified Subject", + "-out", $req_out])), + "Modifying subject of certificate request"); + + run(app(["openssl", "req", "-in", $req_out, "-noout", "-subject", + "-out", $subj_out])); + test_file_contains("modified request", $subj_out, "CN=Modified Subject", 1); + test_file_contains("modified request", $subj_out, "CN=cn4", 0); +}; + subtest "generating SM2 certificate requests" => sub { plan tests => 4; diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t index 9564e78153018..99757b99be34f 100644 --- a/test/recipes/25-test_verify.t +++ b/test/recipes/25-test_verify.t @@ -19,22 +19,80 @@ use OpenSSL::Test::Utils; setup("test_verify"); my @certspath = qw(test certs); +my $ca_cert = srctop_file(@certspath, "ca-cert.pem"); +my $ca_key = srctop_file(@certspath, "ca-key.pem"); sub verify { my ($cert, $purpose, $trusted, $untrusted, @opts) = @_; + # An option hash at the end of @opts is passed on to app(), + # e.g., to tap stderr via { stderr => $file }. + my %app_opts = @opts > 0 && ref($opts[-1]) eq 'HASH' ? %{pop @opts} : (); my @args = qw(openssl verify -auth_level 1); push(@args, "-purpose", $purpose) if $purpose ne ""; push(@args, @opts); for (@$trusted) { push(@args, "-trusted", srctop_file(@certspath, "$_.pem")) } for (@$untrusted) { push(@args, "-untrusted", srctop_file(@certspath, "$_.pem")) } - push(@args, srctop_file(@certspath, "$cert.pem")); - run(app([@args])); + # A certificate generated by the test recipe itself is used in place + # of one from @certspath. + push(@args, -f "$cert.pem" ? "$cert.pem" : srctop_file(@certspath, "$cert.pem")); + run(app([@args], %app_opts)); } -plan tests => 219; +sub make_empty_crl { + my ($prefix, $ca_cert, $ca_key, $crl, $crlexts) = @_; + my $index = "$prefix-index.txt"; + my $serial = "$prefix-serial.txt"; + my $cnf = "$prefix.cnf"; + my $ca_cert_file = "$prefix-ca-cert.pem"; + my $ca_key_file = "$prefix-ca-key.pem"; + + open my $index_fh, ">", $index or return 0; + close $index_fh; + open my $serial_fh, ">", $serial or return 0; + print $serial_fh "01\n"; + close $serial_fh; + copy($ca_cert, $ca_cert_file) or return 0; + copy($ca_key, $ca_key_file) or return 0; + open my $cnf_fh, ">", $cnf or return 0; + print $cnf_fh <<"EOF"; +[ ca ] +default_ca = test_ca + +[ test_ca ] +database = $index +serial = $serial +new_certs_dir = . +certificate = $ca_cert_file +private_key = $ca_key_file +default_md = sha256 +default_days = 365 +default_crl_days = 365 +policy = policy_any + +[ policy_any ] +commonName = optional +EOF + # Optional CRL extension sections; the section is named "crl_ext". + print $cnf_fh $crlexts if defined $crlexts; + close $cnf_fh; + + run(app(["openssl", "ca", "-batch", "-config", $cnf, "-gencrl", + (defined $crlexts ? ("-crlexts", "crl_ext") : ()), + "-out", $crl])); +} + +plan tests => 230; # Canonical success ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]), "accept compat trust"); +SKIP: { + skip "EC is not supported by this OpenSSL build; mixed RSA/ECC chain unavailable", 1 + if disabled("ec") || !(-f srctop_file(@certspath, "mixed-ca-cert.pem")); + ok(verify("mixed-ee-cert", "sslserver", ["root-cert"], ["mixed-ca-cert"]), + "accept mixed RSA/ECC chain"); +} +ok(verify("ee-cert1", "sslserver", ["root-cert"]), + "accept 2-level chain"); # Root CA variants ok(!verify("ee-cert", "sslserver", [qw(root-nonca)], [qw(ca-cert)]), @@ -142,10 +200,29 @@ ok(!verify("ee-cert", "sslserver", [qw(root-cert)], [qw(ca-name2)]), "fail wrong intermediate CA DN"); ok(!verify("ee-cert", "sslserver", [qw(root-cert)], [qw(ca-root2)]), "fail wrong intermediate CA issuer"); + +# CA key rollover: the self-issued transition certificate is not +# self-signed (regression from 792a760ac2). It must neither break +# chain building to the old root nor act as an anchor on its own, +# while explicit PARTIAL_CHAIN trust in it must keep working. +ok(verify("rollover-ee", "", ["rollover-root"], ["rollover-ca"], + "-attime", "1800000000"), + "accept rollover chain through untrusted transition cert"); +ok(!verify("rollover-ee", "", ["rollover-ca"], [], "-attime", "1800000000"), + "reject rollover chain when only transition cert is trusted"); +ok(verify("rollover-ee", "", ["rollover-ca"], [], + "-partial_chain", "-attime", "1800000000"), + "accept rollover transition with explicit partial-chain trust"); ok(!verify("ee-cert", "sslserver", [], [qw(ca-cert)], "-partial_chain"), "fail untrusted partial chain"); ok(verify("ee-cert", "sslserver", [qw(ca-cert)], [], "-partial_chain"), "accept trusted partial chain"); +ok(make_empty_crl("partial-chain-ca", $ca_cert, $ca_key, + "partial-chain-ca.crl") + && verify("ee-cert", "sslserver", [qw(ca-cert)], [], + "-partial_chain", "-crl_check_all", "-CRLfile", + "partial-chain-ca.crl"), + "accept trusted partial chain with CRL_CHECK_ALL"); ok(!verify("ee-cert", "sslserver", [qw(ca-expired)], [], "-partial_chain"), "reject expired trusted partial chain"); # this check is beyond RFC 5280 ok(!verify("ee-cert", "sslserver", [qw(root-expired)], [qw(ca-cert)]), @@ -362,6 +439,17 @@ SKIP: { ok(verify("ee-cert-ec-sha3-512", "", ["root-cert"], ["ca-cert-ec-named"], ), "accept cert generated with EC and SHA3-512"); } + +# DSA chains using id-dsa-with-sha384 / id-dsa-with-sha512 (GitHub issue #30432) +SKIP: { + skip "DSA is not supported by this OpenSSL build", 2 + if disabled("dsa"); + + ok(verify("ee-cert-dsa-sha384", "", ["root-cert-dsa-sha384"], [], ), + "accept DSA cert chain with SHA-384 signatures"); + ok(verify("ee-cert-dsa-sha512", "", ["root-cert-dsa-sha512"], [], ), + "accept DSA cert chain with SHA-512 signatures"); +} # Same as above but with base provider used for decoding SKIP: { my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0); @@ -434,8 +522,8 @@ ok(verify("goodcn1-cert", "", ["root-cert"], ["ncca1-cert"], ), ok(verify("goodcn2-cert", "", ["root-cert"], ["ncca1-cert"], ), "Name Constraints CNs permitted - no SAN extension"); -ok(!verify("badcn1-cert", "", ["root-cert"], ["ncca1-cert"], ), - "Name Constraints CNs not permitted"); +ok(verify("badcn1-cert", "", ["root-cert"], ["ncca1-cert"], ), + "Name Constraints DNS-like CN not checked by default"); ok(!verify("badalt1-cert", "", ["root-cert"], ["ncca1-cert"], ), "Name Constraints hostname not permitted"); @@ -452,11 +540,11 @@ ok(!verify("badalt4-cert", "", ["root-cert"], ["ncca1-cert"], ), ok(!verify("badalt5-cert", "", ["root-cert"], ["ncca1-cert"], ), "Name Constraints IP address not permitted"); -ok(!verify("badalt6-cert", "", ["root-cert"], ["ncca1-cert"], ), - "Name Constraints CN hostname not permitted"); +ok(verify("badalt6-cert", "", ["root-cert"], ["ncca1-cert"], ), + "Name Constraints CN hostname not checked by default"); -ok(!verify("badalt7-cert", "", ["root-cert"], ["ncca1-cert"], ), - "Name Constraints CN BMPSTRING hostname not permitted"); +ok(verify("badalt7-cert", "", ["root-cert"], ["ncca1-cert"], ), + "Name Constraints CN BMPSTRING hostname not checked by default"); ok(!verify("badalt8-cert", "", ["root-cert"], ["ncca1-cert", "ncca3-cert"], ), "Name constraints nested DNS name not permitted 1"); @@ -628,6 +716,66 @@ run(app(["openssl", "verify", ok(grep(/CRL is not yet valid/, do { open my $fh, '<', $cve_28388_stderr; <$fh> }), "CVE-2026-28388"); +# A certificate without a CRL distribution points extension is checked against +# CRLs issued by its issuer as if it had a distribution point whose fullName +# consists of the certificate issuer name and any issuerAltName entries of the +# certificate (RFC 5280, section 6.3.3, last paragraph). A CRL whose issuing +# distribution point matches one of those names is therefore in scope, while +# one that only names a URI not present in an issuerAltName is not. +my $idp_dirname_exts = <<"EOF"; +[ crl_ext ] +issuingDistributionPoint = critical, \@idp_section + +[ idp_section ] +fullname = dirName:idp_dn + +[ idp_dn ] +CN = CA +EOF +ok(make_empty_crl("idp-dirname", $ca_cert, $ca_key, + "idp-dirname.crl", $idp_dirname_exts) + && verify("ee-cert", "", [qw(root-cert)], [qw(ca-cert)], + "-crl_check", "-CRLfile", "idp-dirname.crl"), + "accept CRL whose IDP names the certificate issuer for a certificate without CDP"); + +my $idp_uri = "http://example.com/ca.crl"; +my $idp_uri_exts = <<"EOF"; +[ crl_ext ] +issuingDistributionPoint = critical, \@idp_section + +[ idp_section ] +fullname = URI:$idp_uri +EOF +my $idp_uri_stderr = "idp-uri.err"; +ok(make_empty_crl("idp-uri", $ca_cert, $ca_key, + "idp-uri.crl", $idp_uri_exts) + && !verify("ee-cert", "", [qw(root-cert)], [qw(ca-cert)], + "-crl_check", "-CRLfile", "idp-uri.crl", + { stderr => $idp_uri_stderr }) + && grep(/different CRL scope/, + do { open my $fh, '<', $idp_uri_stderr; <$fh> }), + "reject CRL whose IDP names only a URI for a certificate without CDP"); + +# The URI-only CRL is in scope for a certificate whose issuerAltName extension +# contains that URI. +my $ian_cnf = "ian-cert.cnf"; +open(my $ian_fh, '>', $ian_cnf) or die "cannot write $ian_cnf: $!"; +print $ian_fh <<"EOF"; +[ ext ] +issuerAltName = URI:$idp_uri +EOF +close($ian_fh); +ok(run(app(["openssl", "req", "-new", + "-key", srctop_file(@certspath, "ee-key.pem"), + "-subj", "/CN=issuerAltName test", "-out", "ian-cert.csr"])) + && run(app(["openssl", "x509", "-req", "-in", "ian-cert.csr", + "-CA", $ca_cert, "-CAkey", $ca_key, "-set_serial", "99", + "-days", "3650", "-extfile", $ian_cnf, "-extensions", "ext", + "-out", "ian-cert.pem"])) + && verify("ian-cert", "", [qw(root-cert)], [qw(ca-cert)], + "-crl_check", "-CRLfile", "idp-uri.crl"), + "accept CRL whose IDP matches an issuerAltName of a certificate without CDP"); + # Delta CRLs must not be accepted as complete CRLs my $delta_crl_as_complete_stderr = "delta-crl-as-complete.err"; ok(!run(app(["openssl", "verify", "-auth_level", "1", diff --git a/test/recipes/25-test_verify_store.t b/test/recipes/25-test_verify_store.t index bfac17c7f4cc1..1ebb6050b4542 100644 --- a/test/recipes/25-test_verify_store.t +++ b/test/recipes/25-test_verify_store.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/25-test_x509.t b/test/recipes/25-test_x509.t index 736d185de49ae..9a75043a1ba8d 100644 --- a/test/recipes/25-test_x509.t +++ b/test/recipes/25-test_x509.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -17,7 +17,7 @@ use File::Compare qw/compare_text/; setup("test_x509"); -plan tests => 153; +plan tests => 157; # Prevent MSys2 filename munging for arguments that look like file paths but # aren't @@ -491,6 +491,18 @@ SKIP: { "error loading unsupported sm2 cert"); } +# Printing info about a plain cert must not emit anything on stderr. +subtest "no spurious errors when printing certificate info" => sub { + plan tests => 2; + + my $errfile = "x509-print.err"; + ok(run(app(["openssl", "x509", "-noout", "-serial", + "-in", srctop_file(@certs, "ca-cert.pem")], + stderr => $errfile)), + "x509 -serial succeeds"); + ok(-z $errfile, "x509 -serial produces no output on stderr"); +}; + # 3 tests for -dateopts formats ok(run(app(["openssl", "x509", "-noout", "-dates", "-dateopt", "rfc_822", "-in", srctop_file("test/certs", "ca-cert.pem")])), @@ -502,6 +514,44 @@ ok(!run(app(["openssl", "x509", "-noout", "-dates", "-dateopt", "invalid_format" "-in", srctop_file("test/certs", "ca-cert.pem")])), "Run with invalid -dateopt format"); +# Cover the informational print options that operate on any certificate: +# -serial, -next_serial, the subject/issuer name hashes and -fingerprint. +# ca-cert.pem is a stable committed cert, so the expected values are fixed. +sub x509_print_contains { + my ($cert, $pattern, @opts) = @_; + my $out = "x509-print.out"; + run(app(["openssl", "x509", "-in", $cert, "-noout", @opts], + stdout => $out)); + return test_file_contains("x509 @opts", $out, $pattern, 1); +} + +subtest "printing certificate identification info" => sub { + plan tests => 9; + + my $idcert = srctop_file(@certs, "ca-cert.pem"); + # SHA-1 and SHA-256 fingerprints are the digests of the DER encoding. + my $sha1_fp = "SHA1 Fingerprint=" + . "1F:BF:59:FA:EA:EE:B2:9C:1E:27:4C:C2:C4:90:42:40:21:0B:16:C3"; + my $sha256_fp = "sha256 Fingerprint=" + . "C8:31:AD:BE:F6:5E:EF:44:71:FE:08:0F:DD:DD:01:4F:9C:7E:9F:0A:" + . "74:DF:CA:E9:D0:06:84:57:79:C2:8F:18"; + + x509_print_contains($idcert, "^serial=02\\b", "-serial"); + x509_print_contains($idcert, "^03\\b", "-next_serial"); # serial + 1 + x509_print_contains($idcert, "^56c899cd\\b", "-subject_hash"); + x509_print_contains($idcert, "^56c899cd\\b", "-hash"); # -hash is an alias + x509_print_contains($idcert, "^8489a545\\b", "-issuer_hash"); + x509_print_contains($idcert, $sha1_fp, "-fingerprint"); + x509_print_contains($idcert, $sha256_fp, "-fingerprint", "-sha256"); + + SKIP: { + skip "MD5 disabled", 2 if disabled("md5"); + + x509_print_contains($idcert, "^d74339c5\\b", "-subject_hash_old"); + x509_print_contains($idcert, "^bec651d6\\b", "-issuer_hash_old"); + } +}; + my $ca_cert = srctop_file(@certs, "ca-cert.pem"); my $goodcn2_chain = srctop_file(@certs, "goodcn2-chain.pem"); @@ -545,9 +595,33 @@ my $in_key = srctop_file('test', 'certs', 'x509-check-key.pem'); my $invextfile = srctop_file('test', 'invalid-x509.cnf'); # Test that invalid extensions settings fail ok(!run(app(["openssl", "x509", "-req", "-in", $in_csr, "-signkey", $in_key, - "-out", "/dev/null", "-days", "3650" , "-extensions", "ext", + "-out", File::Spec->devnull(), "-days", "3650" , "-extensions", "ext", "-extfile", $invextfile]))); +subtest "signing output detection with -key" => sub { + plan tests => 5; + + my $v1_cert = srctop_file("test", "testx509.pem"); + my $with_days_cert = "x509-resigned-with-days.pem"; + my $default_ext_cert = "x509-resigned-with-default-ext.pem"; + my $request = "x509-to-request-with-ext.pem"; + + ok(!run(app(["openssl", "x509", "-in", $v1_cert, "-noout", + "-days", "1"])), + "reject -days when no signed output is requested"); + ok(run(app(["openssl", "x509", "-in", $v1_cert, "-signkey", $in_key, + "-days", "1", "-out", $with_days_cert])), + "accept -days when re-signing with -signkey"); + ok(run(app(["openssl", "x509", "-in", $v1_cert, "-key", $in_key, + "-out", $default_ext_cert])), + "re-sign a certificate with -key"); + has_SKID($default_ext_cert, 1); + ok(run(app(["openssl", "x509", "-in", $v1_cert, "-x509toreq", + "-key", $in_key, "-extfile", $cnf, + "-extensions", "v3_req", "-out", $request])), + "accept extension options when signing a request with -key"); +}; + # Tests for issue #16080 (fixed in 1.1.1o) my $b_key = "b-key.pem"; my $b_csr = "b-cert.csr"; @@ -765,6 +839,22 @@ ok(!run(app(["openssl", "x509", "-multi", "-checkend", ok(!run(app(["openssl", "x509", "-checkend", "60", "-in", $c_key])), "Bad parse with -checkend returns non-zero"); +# Regression test: with -multi, a failure on a later certificate must set +# a failing exit status even after an earlier certificate succeeded, i.e. +# the per-certificate success status must not leak into the final result. +subtest "x509 -multi later failure is not masked by earlier success" => sub { + plan tests => 1; + + # goodcn2-chain.pem holds two certificates without subjectAltName, so + # -checkhost falls back to the CN: "www.good.org" matches the first + # certificate ("CN=www.good.org") but not the second ("CN=Test NC CA 1") + my $chain = srctop_file(@certs, "goodcn2-chain.pem"); + + ok(!run(app(["openssl", "x509", "-multi", "-in", $chain, "-noout", + "-checkhost", "www.good.org"])), + "-multi returns non-zero when a later certificate fails -checkhost"); +}; + # Signing using DER-encoded key and CA cert/key inputs, # exercising -keyform, -CAform and -CAkeyform subtest 'x509 signing with DER -keyform, -CAform and -CAkeyform' => sub { diff --git a/test/recipes/30-test_cipher_dupctx.t b/test/recipes/30-test_cipher_dupctx.t new file mode 100644 index 0000000000000..cf0ed3c7d99fc --- /dev/null +++ b/test/recipes/30-test_cipher_dupctx.t @@ -0,0 +1,16 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use OpenSSL::Test; +use OpenSSL::Test::Utils; + +setup("test_cipher_dupctx"); + +plan tests => 1; + +ok(run(test(["cipher_dupctx_test"])), "cipher dupctx tlsmac deep copy"); diff --git a/test/recipes/30-test_composite_sig.t b/test/recipes/30-test_composite_sig.t new file mode 100644 index 0000000000000..ddafa77127354 --- /dev/null +++ b/test/recipes/30-test_composite_sig.t @@ -0,0 +1,94 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use OpenSSL::Test qw(:DEFAULT srctop_dir bldtop_dir srctop_file bldtop_file); +use OpenSSL::Test::Utils; + +BEGIN { + setup("test_composite_sig"); +} + +use lib srctop_dir('Configurations'); +use lib bldtop_dir('.'); + +plan skip_all => 'Composite signatures are not supported in this build' + if disabled('composite'); + +my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0); +my $no_ec = disabled('ec'); +my $no_ecx = $no_ec || disabled('ecx'); +my $provconf = srctop_file("test", "fips-and-base.cnf"); + +# 1 C test run + 1 FIPS skip + 1 require_ok +# + N × 2 tconversion subtests: +# no-ec removes 7 ECDSA + 3 ECX → 8 RSA remain → 19 +# no-ecx removes 3 ECX → 15 remain → 33 +# default: 18 composites → 39 +plan tests => $no_ec ? 19 : $no_ecx ? 33 : 39; + +# ─── C unit test binary ────────────────────────────────────────────────────── +ok(run(test(["composite_sig_test"])), "running composite_sig_test"); + +# ─── FIPS variant ──────────────────────────────────────────────────────────── +SKIP: { + # Composite algorithms are not present in the FIPS provider, so the test + # binary will fail to load them under a FIPS+base library context. + skip "Composite signatures are not available in the FIPS provider", 1; + + ok(run(test(["composite_sig_test", "-config", $provconf])), + "running composite_sig_test with FIPS"); +} + +# ─── pkey CLI conversion round-trips (PKCS#8 + public key) ────────────────── + +require_ok(srctop_file('test','recipes','tconversion.pl')); + +# Remove ECX-dependent composites when ECX is disabled +my @composite_pems = ( + [ "ML-DSA-44-RSA2048-PSS-SHA256", "testcomposite44-rsa2048pss" ], + [ "ML-DSA-44-RSA2048-PKCS15-SHA256", "testcomposite44-rsa2048pkcs15" ], + [ "ML-DSA-44-Ed25519-SHA512", "testcomposite44-ed25519" ], + [ "ML-DSA-44-ECDSA-P256-SHA256", "testcomposite44-ecdsa-p256" ], + [ "ML-DSA-65-RSA3072-PSS-SHA512", "testcomposite65-rsa3072pss" ], + [ "ML-DSA-65-RSA3072-PKCS15-SHA512", "testcomposite65-rsa3072pkcs15" ], + [ "ML-DSA-65-RSA4096-PSS-SHA512", "testcomposite65-rsa4096pss" ], + [ "ML-DSA-65-RSA4096-PKCS15-SHA512", "testcomposite65-rsa4096pkcs15" ], + [ "ML-DSA-65-ECDSA-P256-SHA512", "testcomposite65-ecdsa-p256" ], + [ "ML-DSA-65-ECDSA-P384-SHA512", "testcomposite65-ecdsa-p384" ], + [ "ML-DSA-65-ECDSA-brainpoolP256r1-SHA512", "testcomposite65-ecdsa-brainpoolp256r1" ], + [ "ML-DSA-65-Ed25519-SHA512", "testcomposite65-ed25519" ], + [ "ML-DSA-87-ECDSA-P384-SHA512", "testcomposite87-ecdsa-p384" ], + [ "ML-DSA-87-ECDSA-brainpoolP384r1-SHA512", "testcomposite87-ecdsa-brainpoolp384r1" ], + [ "ML-DSA-87-Ed448-SHAKE256", "testcomposite87-ed448" ], + [ "ML-DSA-87-RSA3072-PSS-SHA512", "testcomposite87-rsa3072pss" ], + [ "ML-DSA-87-RSA4096-PSS-SHA512", "testcomposite87-rsa4096pss" ], + [ "ML-DSA-87-ECDSA-P521-SHA512", "testcomposite87-ecdsa-p521" ], +); +@composite_pems = grep { $_->[0] !~ /ECDSA/ } @composite_pems if $no_ec; +@composite_pems = grep { $_->[0] !~ /Ed25519|Ed448/ } @composite_pems if $no_ecx; + +foreach my $entry (@composite_pems) { + my ($alg, $base) = @$entry; + + subtest "$alg conversions -- pkcs8" => sub { + tconversion(-type => "pkey", + -in => srctop_file("test", "${base}.pem"), + -args => ["pkey"], + -prefix => "${base}-pkcs8"); + }; + + subtest "$alg conversions -- pub" => sub { + tconversion(-type => "pkey", + -in => srctop_file("test", "${base}pub.pem"), + -args => ["pkey", "-pubin", "-pubout"], + -prefix => "${base}-pub"); + }; +} diff --git a/test/recipes/30-test_evp.t b/test/recipes/30-test_evp.t index d94c76fe796e1..bbdc81fedc1ab 100644 --- a/test/recipes/30-test_evp.t +++ b/test/recipes/30-test_evp.t @@ -32,6 +32,7 @@ my $no_ec2m = disabled("ec2m"); my $no_sm2 = disabled("sm2") || disabled("x963kdf"); my $no_siv = disabled("siv"); my $no_argon2 = disabled("argon2"); +my $no_ascon128 = disabled("ascon128"); my $no_ml_dsa = disabled("ml-dsa"); my $no_ml_kem = disabled("ml-kem"); my $no_lms = disabled("lms"); @@ -126,6 +127,7 @@ push @files, qw( evppkey_ml_dsa_87_wycheproof_sign.txt evppkey_ml_dsa_87_wycheproof_verify.txt ) unless $no_ml_dsa; +my $no_composite = disabled("composite"); push @files, qw( evppkey_ml_kem_512_keygen.txt evppkey_ml_kem_512_encap.txt @@ -187,8 +189,17 @@ push @defltfiles, qw(evppkey_brainpool.txt) unless $no_ec; push @defltfiles, qw(evppkey_ecx_kem.txt) unless $no_ecx; push @defltfiles, qw(evppkey_dsa_rfc6979.txt) unless ($no_dsa || $no_determinstic_nonce); push @defltfiles, qw(evppkey_sm2.txt) unless $no_sm2; +# Composite algorithms are not in the FIPS provider — default provider only. +# Some composite algorithms use ECX (Ed25519/Ed448) components; since the test +# data files mix ECX and non-ECX stanzas, skip all of them in no-ecx builds. +push @defltfiles, qw( + evppkey_composite_keygen.txt + evppkey_composite_siggen.txt + evppkey_composite_sigver.txt + ) unless $no_composite || $no_ecx; push @defltfiles, qw(evpciph_aes_gcm_siv.txt) unless $no_siv; push @defltfiles, qw(evpciph_aes_siv.txt) unless $no_siv; +push @defltfiles, qw(evpciph_ascon_aead128.txt) unless $no_ascon128; push @defltfiles, qw(evpkdf_argon2.txt) unless $no_argon2; push @defltfiles, qw(evpkdf_hmac_drbg.txt) unless $no_determinstic_nonce; diff --git a/test/recipes/30-test_evp_data/evpciph_aes_common.txt b/test/recipes/30-test_evp_data/evpciph_aes_common.txt index 5dcbdd89e4f0a..660a8b5339025 100644 --- a/test/recipes/30-test_evp_data/evpciph_aes_common.txt +++ b/test/recipes/30-test_evp_data/evpciph_aes_common.txt @@ -654,6 +654,33 @@ Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F Ciphertext = A2D459477E6432BD74184B1B5370D2243CDC202BC43583B2A55D288CDBBD1E03 NextIV = 00000000000000008000000000000001 +# AES CTR known-answer vectors from NIST SP800-38A appendix F.5. +# The 64-byte (4-block) payload crosses the 64-byte threshold that selects +# the VAES/AVX-512 code path on capable CPUs, exercising it under a KAT. +Cipher = aes-128-ctr +Key = 2B7E151628AED2A6ABF7158809CF4F3C +IV = F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF +Operation = ENCRYPT +Plaintext = 6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710 +Ciphertext = 874D6191B620E3261BEF6864990DB6CE9806F66B7970FDFF8617187BB9FFFDFF5AE4DF3EDBD5D35E5B4F09020DB03EAB1E031DDA2FBE03D1792170A0F3009CEE +NextIV = F0F1F2F3F4F5F6F7F8F9FAFBFCFDFF03 + +Cipher = aes-192-ctr +Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B +IV = F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF +Operation = ENCRYPT +Plaintext = 6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710 +Ciphertext = 1ABC932417521CA24F2B0459FE7E6E0B090339EC0AA6FAEFD5CCC2C6F4CE8E941E36B26BD1EBC670D1BD1D665620ABF74F78A7F6D29809585A97DAEC58C6B050 +NextIV = F0F1F2F3F4F5F6F7F8F9FAFBFCFDFF03 + +Cipher = aes-256-ctr +Key = 603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4 +IV = F0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF +Operation = ENCRYPT +Plaintext = 6BC1BEE22E409F96E93D7E117393172AAE2D8A571E03AC9C9EB76FAC45AF8E5130C81C46A35CE411E5FBC1191A0A52EFF69F2445DF4F9B17AD2B417BE66C3710 +Ciphertext = 601EC313775789A5B7A7F504BBF3D228F443E3CA4D62B59ACA84E990CACAF5C52B0930DAA23DE94CE87017BA2D84988DDFC9C58DB67AADA613C2DD08457941A6 +NextIV = F0F1F2F3F4F5F6F7F8F9FAFBFCFDFF03 + # AES CCM 256 bit key Cipher = aes-256-ccm Key = 1bde3251d41a8b5ea013c195ae128b218b3e0306376357077ef1c1c78548b92e diff --git a/test/recipes/30-test_evp_data/evpciph_ascon_aead128.txt b/test/recipes/30-test_evp_data/evpciph_ascon_aead128.txt new file mode 100644 index 0000000000000..7443f358d62c3 --- /dev/null +++ b/test/recipes/30-test_evp_data/evpciph_ascon_aead128.txt @@ -0,0 +1,18900 @@ +# +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# Tests start with one of these keywords +# Cipher Decrypt Derive Digest Encoding KDF MAC PBE +# PrivPubKeyPair Sign Verify VerifyRecover +# and continue until a blank line. Lines starting with a pound sign are ignored. + +# 8c48ea50620a6b0c69c32ac7438af7fc49d3dab9c6567caf3cb4f2f5764a7065 +Title = Ascon AEAD 128 Test Vectors sourced from LWC_AEAD_KAT_128_128_random.txt + +Cipher = ascon-aead128 +Key = 68143878109DE6D99EB51700335475DA +IV = 57254555E1B4B4EF38E895E37A88A8A3 +Plaintext = +AAD = +Tag = F341833ACC65733F95A3E5E64B20BB0F +Ciphertext = + +Cipher = ascon-aead128 +Key = 0FB064F2CA971A182E5DB3BF78F3AB9E +IV = E12515ACF6D0AB4BA60F7086D07D9743 +Plaintext = +AAD = 8D +Tag = 871CE66DC7D530DCC6ECA4DEA54C7404 +Ciphertext = + +Cipher = ascon-aead128 +Key = D4D1C8162057D6EE0733111EE3F7B552 +IV = AFB4DEEF2B6F1EFA8CB5D195AE761E8E +Plaintext = +AAD = 58D7 +Tag = 7ED7F97F5789CB37100BEB2F6737A51A +Ciphertext = + +Cipher = ascon-aead128 +Key = 492B8E8401ECBFC531E074F92C08EC40 +IV = 79B3DDE4179B81C5A44D9E3BF2B046ED +Plaintext = +AAD = 2376F6 +Tag = 655B26DFAA5EEC32C0E8C5826E89E0AA +Ciphertext = + +Cipher = ascon-aead128 +Key = 5319ACAB4197ABEEE2C34EC317E88167 +IV = AAFF726D4D2341DE95DBE74191E974EC +Plaintext = +AAD = A7CB0505 +Tag = 9618437CCB9B5DE9348ED8503D7062F3 +Ciphertext = + +Cipher = ascon-aead128 +Key = A29033250E556EEB5031967A408A22F0 +IV = C1A5C57E8F89A1093949449F52562FC9 +Plaintext = +AAD = 340A71ED33 +Tag = 8798AF545AD628B9AE07DD58A5609A91 +Ciphertext = + +Cipher = ascon-aead128 +Key = 9872981F73D7B19BF1EDD6F610215A88 +IV = 6736040D1117B1A6C95F424DF6A96533 +Plaintext = +AAD = 183B52246CA7 +Tag = BF972D8A1AB860A826C0E9EADAD6449E +Ciphertext = + +Cipher = ascon-aead128 +Key = D6CCD1C73177CE47BA05EC2A3B96EE04 +IV = 7186FA0D915368B285A7257F37A3AF74 +Plaintext = +AAD = F32C942A7E2770 +Tag = 4ECA6FB419749B946513643C629114A3 +Ciphertext = + +Cipher = ascon-aead128 +Key = 5E776067C40685E5693A2720AAFE3114 +IV = F36CD653FDBCDF86D431DD384D943273 +Plaintext = +AAD = 87BDEB85662BAEAF +Tag = 9A6ED0BFC3C3517528B71217573EFAFC +Ciphertext = + +Cipher = ascon-aead128 +Key = 20ED1109A3C2E27A0FC88CE1F222F7C7 +IV = 50C30DBAA4858728E5A54D1F0DE5346A +Plaintext = +AAD = EE60369F25487C09F4 +Tag = 1F733D46EAA683EE488D599B489E54A7 +Ciphertext = + +Cipher = ascon-aead128 +Key = E90C1B041C02168F183CD4AC32A207AF +IV = 0A741A6D7B4F1669261B2831069954DD +Plaintext = +AAD = EA654C1A6FE2CA57E28D +Tag = 08337A65A0CD166BDBF98709198BAADE +Ciphertext = + +Cipher = ascon-aead128 +Key = B5F04BAC567143E688665AE1A76104F7 +IV = CD5EB3BA0761AE29FA3A942DA190C992 +Plaintext = +AAD = 61BBAB79F8815099284501 +Tag = 33D178CBAE6F547802F4C576067467C9 +Ciphertext = + +Cipher = ascon-aead128 +Key = CC523A49292908B27D47581F31F4A86F +IV = AE72830D4D13A7B97DEE243E42B11D5A +Plaintext = +AAD = 5B953E70CD45CF55690920A2 +Tag = E524D4B19F134D31F004814600218EAC +Ciphertext = + +Cipher = ascon-aead128 +Key = BE3AF69C6716E6B916A2436681AC1ED2 +IV = BD39F119C722C8C825711CF76F0CB1BC +Plaintext = +AAD = 0D46A7A24FFEF0F2EDB0E3703B +Tag = 8BB638CE35D9FB4C36C83B679F123B53 +Ciphertext = + +Cipher = ascon-aead128 +Key = 09A60FED8FE4E0164A5B24107EFAF740 +IV = 973315370C46A268D39029F3BF85546E +Plaintext = +AAD = E9131546035C605E1CAA0AC37EA3 +Tag = 7D49D50D39019639CEA48B29D38F0BB6 +Ciphertext = + +Cipher = ascon-aead128 +Key = 159EAD976872A37F8BA4E95D06050E35 +IV = 0BEA795C52F57A13C7A76825CA275259 +Plaintext = +AAD = 2FF9715EBB40B40A1101249CEC30A3 +Tag = 7C6EF2C6CA8966BD2FFDA207B58680BF +Ciphertext = + +Cipher = ascon-aead128 +Key = 7D86DFC28825ADA8B411745B12B0FDFB +IV = BA9B2B6BD720666CB18EF4B0936066BB +Plaintext = +AAD = 3B88ED25F7FC53F725EB2813D946E94B +Tag = 39D2202DA8DE50A64F0FDEAC4112E4D9 +Ciphertext = + +Cipher = ascon-aead128 +Key = B7317B226CA247B502C1972041DE1D0D +IV = 4478FD4444BC184D737171F38A868CC5 +Plaintext = +AAD = AD2F31860CCDD0B059396647FB7C8F7DC1 +Tag = BD28B4FA218CADB1021E16588480D62C +Ciphertext = + +Cipher = ascon-aead128 +Key = 6D95CC3F6E9810AE18C59CC6857453F4 +IV = 3C90D9D9759395407347E2622903A95E +Plaintext = +AAD = 86455A11BF5201A900E2D0830D46B5C3C051 +Tag = 952A119FABCA7C8ACFF7804578D54E04 +Ciphertext = + +Cipher = ascon-aead128 +Key = 9F4F8D921670307E6B01DFC7872FB1AC +IV = D0C7017810280CC240528A8B49723C62 +Plaintext = +AAD = 56D7C0200789704737CC69E865EC7B75C38CC6 +Tag = C5E55AE8CBC4E6EE719AC0756A64F11F +Ciphertext = + +Cipher = ascon-aead128 +Key = 23498258655561A92298840EAB85218F +IV = E2312575A72E57143375CC954984BEE7 +Plaintext = +AAD = E7C9C110FA9A91571643F455BE4B8E018E4C4EF3 +Tag = 99C8912C55F8D4E5612739A2EA385580 +Ciphertext = + +Cipher = ascon-aead128 +Key = 85852AFFD5D928001754AC62DAE80562 +IV = 2B9BDD4DACC2293BD6CB05EE31034CBF +Plaintext = +AAD = DBE8CC21C436B10EA10EEB8B193373D307394F8506 +Tag = 2AA6244C4FBAAE1001341BC0427DA87C +Ciphertext = + +Cipher = ascon-aead128 +Key = FA7FE23F2A6F56650BF6ADB96B279E50 +IV = D5868358C25A2B557908C1D8889EA0E2 +Plaintext = +AAD = 923E86861F83A7C265FA1F166B7A96CF1D273F0E81B6 +Tag = C0EDA0E153B27492F592458C5EB7316C +Ciphertext = + +Cipher = ascon-aead128 +Key = 5D7FA3FC35E992D64DB82EE08954513B +IV = EF3591725552C4B199B5A274A2E5CF68 +Plaintext = +AAD = 61FF48AD12D2AC43CE3EDD47F618C2536C62357E85E47B +Tag = E1ADF7C507927C01B29AC06C15229F8A +Ciphertext = + +Cipher = ascon-aead128 +Key = 4EBB6FA70CCF8A197BB705B0FF0AFC6B +IV = 704FC73F709D94521A396F94CEC89B0C +Plaintext = +AAD = B638C5F959BB63EB27D37CDFA0B9FA7AECE8F5A161870ACA +Tag = 927A1E95FB2D3BD2BDA334D1FC0B8214 +Ciphertext = + +Cipher = ascon-aead128 +Key = 5511DC52A94D0E99675753D7563B329F +IV = 6FB1F2441DD71D05F34590178D09E9CB +Plaintext = +AAD = 32A101A2A8B1C38A875CC032DB80571E3D545304BA1AE5BBC1 +Tag = 6EE8F73A956F0B9D84F49B134799373F +Ciphertext = + +Cipher = ascon-aead128 +Key = 7E46664394E1E43A9CE3CA7F2B9D4928 +IV = 619BA511A865FE69F014103E855C5F1D +Plaintext = +AAD = BC0B79BC3A5AEB5FAB039995AD8EC818ED9EAAA288988733D463 +Tag = A704EBBB1948D7E08E13BA3781AACE4C +Ciphertext = + +Cipher = ascon-aead128 +Key = 4F0EEFB05A20F2FCFEFA79B9F4728D62 +IV = 40FB7F5038B5EBC2D54287F844D64B39 +Plaintext = +AAD = 8DDF7D0EA4C50F5A238B7678AAA931ABC01C0963A129A3AA5821FC +Tag = B8B3CE35323C34E8B4B36BD4D183134E +Ciphertext = + +Cipher = ascon-aead128 +Key = 01B9065062B298C3FCF1797EB2AB4DCB +IV = FD8B3FD13097D429EB853CB145D8D944 +Plaintext = +AAD = AA52EC690A8689C837027547B4BDFD627744EECED12F75E1E8C66DD1 +Tag = 74744944D04C35A600CB949E060BD2A2 +Ciphertext = + +Cipher = ascon-aead128 +Key = 334BE04053EAEF71E12755E978793A34 +IV = 3D20EE7E9419E6945AB93D67EF310C6A +Plaintext = +AAD = EAF2FE53A41B3D7D1230435FE3DB79D24B3DEA56492D151FF1DC979129 +Tag = B1D39CD6B5AF44E19D338B6D0DA63CB0 +Ciphertext = + +Cipher = ascon-aead128 +Key = 1C05EC7EEE8BCB72042B28C050542246 +IV = E4CE9B50B99A06D405C2A5C911272EF0 +Plaintext = +AAD = B6637A75ABF8C8F7C48A1ABB3CAC933EB3F9214B92CD2906CA6D2ED2FE00 +Tag = 64BDE9B8E80E54014C297747553D0A4E +Ciphertext = + +Cipher = ascon-aead128 +Key = 326B4151DD5FFF38C2D2CD44258F4EAB +IV = 9414FBDA3A01CE065C97456217F058E8 +Plaintext = +AAD = 28566ACB8650CEB7291BF230EF0762F7245406240B0F0B5B23E2F9B86156BB +Tag = 5C4AAAC0AAC5985C83DDD192F879469D +Ciphertext = + +Cipher = ascon-aead128 +Key = 3E6B5E4A29B874267D442ED68FA2ED9A +IV = 4F45937B291CE46D540184DC72AED064 +Plaintext = +AAD = 65961382388BB0E2B3F050E0B2CBC89D01B652B6C475D0E6F6DB2007204D5DCB +Tag = 1D431279DFDCFF990917370479A20DC8 +Ciphertext = + +Cipher = ascon-aead128 +Key = DA851E9442E87CA4527DF7F58EB3CB97 +IV = E48C7951F862549AF8A93E96303176EE +Plaintext = 2A +AAD = +Tag = 8530EF6B9B28597124CC370F4D795E27 +Ciphertext = 7F + +Cipher = ascon-aead128 +Key = 04F0EDFA6BA28DC546A316A5AFC3A272 +IV = 62354700956E976398E742978EC97F36 +Plaintext = 8C +AAD = 3A +Tag = AD668F0E3A4DEEFE1ADD4CAD51D34FD6 +Ciphertext = F8 + +Cipher = ascon-aead128 +Key = AE0D354507C88B42AA48FDAE2D69C12E +IV = 2C8DBC619CD2B3D6D4DFACD0BA8F8883 +Plaintext = E1 +AAD = E6CB +Tag = 734D7BAC4F6D61508764C2397E714A3F +Ciphertext = A2 + +Cipher = ascon-aead128 +Key = B25355E23B4F4B7D891DA8D94B6D3CED +IV = 354AA699BA5A3F9B46EDB3FEFEA6F135 +Plaintext = 62 +AAD = 476372 +Tag = B251172811747C62F5188D2CD4775221 +Ciphertext = 5D + +Cipher = ascon-aead128 +Key = 95614B8DA8179FE71A029D989E331EC6 +IV = 2F58E5004EF6570706129FA4C7AA5A54 +Plaintext = E3 +AAD = 8CA37850 +Tag = 634BE3AC347B4AE6D9D2819EE73D5D3F +Ciphertext = 8F + +Cipher = ascon-aead128 +Key = 38DB21798E9A5C2631FDE3D86C5855E7 +IV = F1D7AA59517952F5D05A501FF9F5E637 +Plaintext = CB +AAD = E88D605296 +Tag = 0BC69510B34F5CDA8DF220B11E565529 +Ciphertext = E7 + +Cipher = ascon-aead128 +Key = A0EB9154846B2BF2F6A2D3DEFC9D426E +IV = D026E9BD8ADF32413DCADE4454048EFE +Plaintext = FA +AAD = 39802F1A9BD8 +Tag = A6A0535B81BDB29B5EA020BCBD77B0ED +Ciphertext = 1C + +Cipher = ascon-aead128 +Key = FA0BC197A3575C62FBB222CF08ABA2CD +IV = C280CA5E60F6A057A0C4C9FD6763E864 +Plaintext = B7 +AAD = E89B678F9FF711 +Tag = BB077850A13B35B1E3A51316C828232D +Ciphertext = F8 + +Cipher = ascon-aead128 +Key = 73DD529E91DF76AE891279A0C69970D3 +IV = 7F751BDC6BF1C42298729AD19242A465 +Plaintext = B0 +AAD = D8BAED4F0A6AA3DF +Tag = 801E8FA0550410FC6FE33C62B2B934D4 +Ciphertext = F9 + +Cipher = ascon-aead128 +Key = 6058553B812FC1ABDF7FE93B7794A853 +IV = 7535CFE3C8D9325EA1CF835D0D55AEE0 +Plaintext = 32 +AAD = B708CC106C91305506 +Tag = 96E51AB45CB8E7F9FE7F065A1D52745F +Ciphertext = CD + +Cipher = ascon-aead128 +Key = AF34B2240022FA63B84F065D0AA7F6ED +IV = 4198B8BADABA6257BBCEE4C60FAB63DA +Plaintext = 2E +AAD = FCD625366743701E4831 +Tag = 45D8E44AF477F3696393966CE140ADEF +Ciphertext = F1 + +Cipher = ascon-aead128 +Key = 4993EC799F6D71BF84BB75CD49941F13 +IV = E6389B072BADB7F28EDE682609E775CD +Plaintext = F6 +AAD = 0AE615EA27BE337E9392AC +Tag = 5AF6029F1EF370E71C4AA844C1F1C138 +Ciphertext = 77 + +Cipher = ascon-aead128 +Key = 63B70574D96B052F0FE0F47BC69C4689 +IV = 4A83FE4B5793CDEBDEBED443E3BAC422 +Plaintext = 05 +AAD = 32FF09F7A87EE63948577B39 +Tag = F4D7993D368851AA0684C91FAE13D869 +Ciphertext = F1 + +Cipher = ascon-aead128 +Key = 579D965067EF2E623B25ACC60D6DBE1B +IV = 96B55DA4756D028AABF7197E00F2D82E +Plaintext = C2 +AAD = EADA66CDF10E4B9EEF2AAD3509 +Tag = C040C019DA42FC032B4EA165CFD05ADE +Ciphertext = 53 + +Cipher = ascon-aead128 +Key = F7ECBBE6DA1E688F425E37DB29947B44 +IV = D395E81836BFDD775DD3897B7CD6C167 +Plaintext = 90 +AAD = E91996980F106E473E6933D9B03C +Tag = 57B8A6250B6966903621CA2BFA540F43 +Ciphertext = 52 + +Cipher = ascon-aead128 +Key = 2857196999C01A7029FB664B2C60CD11 +IV = 1D39DE41870A87917CD6C7C74AC9E6B5 +Plaintext = FD +AAD = 8992E6016CE97AAC4E18BE94F4B70B +Tag = 26E0525B4EC4B5DB44ADF9B2675621AD +Ciphertext = 20 + +Cipher = ascon-aead128 +Key = 6336EAB9AB3E3B77152B4922B02DFB3E +IV = E4687E4B2092222130DD191694E0F2E2 +Plaintext = 3E +AAD = 444F96493CD99AACA233AABDECE9E434 +Tag = D78BE11D357DD5ECA183692B821726F8 +Ciphertext = 8C + +Cipher = ascon-aead128 +Key = F9B0167FA107651ACB16F37E9C52B177 +IV = 9EC5A3EE716BD046F8D437AA69F7259A +Plaintext = 0A +AAD = 5FC6A3DEEDD4A720452A087EBB827FF189 +Tag = 75A418A5032AAFE9692ABCB784921173 +Ciphertext = F8 + +Cipher = ascon-aead128 +Key = 78C855F942D408833E10A06050E14272 +IV = C6D525BCAC9ADE9D814F0D425F14A78F +Plaintext = E1 +AAD = C9E68E36AF7DEEC1F7E0CF478C38D6410E43 +Tag = 76C1BA07E9771B4EA39EEC00F82949BA +Ciphertext = C9 + +Cipher = ascon-aead128 +Key = C6FB9E122B9F4EF2235384013FB5D5D9 +IV = E1497D510839762A9E14608DADB0B3D1 +Plaintext = B5 +AAD = C806F23A6A341F5BE4D73EDA7C4A4825617ADB +Tag = 8ABDA2D79959F031FAA622C2126869E5 +Ciphertext = 5F + +Cipher = ascon-aead128 +Key = 87EA0CC4DE4E64740DC7F1C3E4D5DFD5 +IV = 2056C2BFC3D0EF29EEEDDE36CD5B6820 +Plaintext = EE +AAD = 0140C1D9F0AB206A9E314A438E95FBC65A152B6C +Tag = CC337228832DEB1DB6CD800D0C7BD467 +Ciphertext = BB + +Cipher = ascon-aead128 +Key = 83E052865FC5985966B1002E6EAB193A +IV = F0B5AF2D1002AEC7224C95414C02CBA4 +Plaintext = 34 +AAD = 846825FAA331BB7D4896350B1A704DFFF14988B130 +Tag = 541758A62145836AFC44DD0B077B7653 +Ciphertext = D1 + +Cipher = ascon-aead128 +Key = F1463FB1FA32858774B2E9A1D08F4B9D +IV = 7FDD74912BC53F809CE1A612D3B77F7C +Plaintext = 15 +AAD = 921BA9FA1A961E9FBBA218C3F00695C3E70403F21AB6 +Tag = 6CFD8E2CDC59BCB6F17E59DF1EAEB62A +Ciphertext = 04 + +Cipher = ascon-aead128 +Key = 23DC4938B45350BCE10F8558F0A9AD4C +IV = 953B968D874BB7F4C278CF1755A16618 +Plaintext = 17 +AAD = BB4896F09DE44B62CA417AB188422EF327F4836A9F1745 +Tag = 0DBA7AC392FE1E7AF0E37C08EF6D1C39 +Ciphertext = 2A + +Cipher = ascon-aead128 +Key = 9874C1D242CF4B7761503D89F343D40D +IV = E8CB6B418B92416B687075DC0FD64B3E +Plaintext = B4 +AAD = 2552347A8AF1AB3E5486A8FC44016D954551EBD2D3FCE76B +Tag = F88DD658B7CC29498BA7650056BAE439 +Ciphertext = 97 + +Cipher = ascon-aead128 +Key = 15E2332CE03EAC4F0F6F521E2527FA7E +IV = A4B426C98C9CEBB9363BFF4181D92EE5 +Plaintext = 0D +AAD = A6352AE786CBE385BF0D0F24762FEF31B6D490730BB6A145A6 +Tag = C1CE42744CAF5CE928E691C3BFBE7105 +Ciphertext = 25 + +Cipher = ascon-aead128 +Key = 822E3C18190291E899BC01B5C576B84A +IV = F1D1C3B23E992C4BD8FD2ECE17862E24 +Plaintext = 99 +AAD = D5BA977A4DECE02F2BC64BDCA2DF036A2C6100B9E6AE5C58890E +Tag = 43A73F1100395C693C09F5538D29B8E1 +Ciphertext = 91 + +Cipher = ascon-aead128 +Key = 588EF357D278DE3911FB05E9D9BFF29B +IV = B44A6B9860908145360802C8F0856CC3 +Plaintext = 01 +AAD = 5A2C0076EBAA52C99EA225B014FBD803ABBD033C74D6EB6BFA7CC9 +Tag = 7D4A2C38CB863431A148CC18B83E115E +Ciphertext = C6 + +Cipher = ascon-aead128 +Key = ADF9DBC40D376D26F7915CBBBE3C2B46 +IV = 1A340B50B0EA1CB44FE617B256AC1511 +Plaintext = B1 +AAD = 90EB3D0156041E7472226AF8C2731274A1249E996BEC53D45B774E58 +Tag = 0F9337DA9BEC3B3E05B9492B492B5AAD +Ciphertext = 7D + +Cipher = ascon-aead128 +Key = 1C9983F8FAFEF5F474E0FF7A70FB4D41 +IV = 850A5E166F0807728F98AAC8A9F80184 +Plaintext = 35 +AAD = 762A524AF03B3BC01FDFB72788901992290757E91A66B7C8676D564417 +Tag = 9D2A798F043E0B83AF095CB75C4AA3D1 +Ciphertext = 65 + +Cipher = ascon-aead128 +Key = BB2C2AD438BA8E2088A279C67ECC2289 +IV = 5E57E72389570A97E825D62EAB4D0F46 +Plaintext = 81 +AAD = 330B0F46A5EE85708304C1BC36C0338267848830FC4D9DC4A81568CB06B6 +Tag = 4511575862798F9A233E83D5589E721E +Ciphertext = D1 + +Cipher = ascon-aead128 +Key = 9915EE9233C6582BB64E27A46BE4F14E +IV = 2457F75DD2D94EBFD7CD7CACB8506AA6 +Plaintext = 87 +AAD = 89F11D5798FA2FE123E0223686A1EEE767A3A48CDB475DD7F903964E39AC86 +Tag = C3B2955966F558C9C79266DB9E35DA4F +Ciphertext = 00 + +Cipher = ascon-aead128 +Key = 09EE87A1B994B3E17DA5293E29745CED +IV = 304E5F895C7955E693563F1E2F310738 +Plaintext = A7 +AAD = 68F13BEF34D1BCBB61F07D483C1BDDD9B698448610AF8DB164DF9738257862AB +Tag = F889C3C6AC76B1C5086D35C509AB45F2 +Ciphertext = E8 + +Cipher = ascon-aead128 +Key = 20523514D1B67B05759AB7AACC66EFEE +IV = F3C47557288E8A563350B9565D068B18 +Plaintext = FAAF +AAD = +Tag = 4FF611D750823EFAF35FD89A56EF8D32 +Ciphertext = 7B4A + +Cipher = ascon-aead128 +Key = A6D03E84C8529CBE2B56F48B521C8FD8 +IV = 184EF678240AB5A5F77DFBD265B54519 +Plaintext = C7F5 +AAD = C8 +Tag = A0129D452AB24DDC9AEE1E260A741EE1 +Ciphertext = 3B1D + +Cipher = ascon-aead128 +Key = E049C01FF9D9E165F76C32BE17734828 +IV = 3AE50A5A160C29C0046C9CBD0ED91D99 +Plaintext = 6BC7 +AAD = 9094 +Tag = A580F929F5A6BD0FDAB6E8ECB2A5EC2D +Ciphertext = BE21 + +Cipher = ascon-aead128 +Key = 1D1A3CDA1FCDEED47C3C51E80D285129 +IV = 8957BD46CA7D9BD21082FACF88687991 +Plaintext = E75C +AAD = 9F6556 +Tag = DBA037C8F55384CAEAAD450751858A4E +Ciphertext = CAB6 + +Cipher = ascon-aead128 +Key = 46A838E9EBD05BEBBA687D3D581C07DB +IV = 19062F16F68D2AD31AC0B9D02DB32D30 +Plaintext = CEE3 +AAD = DA127065 +Tag = 490ACFA34D1A3A2B2F8A08087B9B3C11 +Ciphertext = 7ACE + +Cipher = ascon-aead128 +Key = 5C9782BF20FF66E8C61340B4F6671313 +IV = FBA7CCEAA5F4A70BA628E2D0AFB7CDED +Plaintext = E789 +AAD = C81F29475C +Tag = 95AD9A6976C3D76EE777015DEBE0FDFE +Ciphertext = 71B7 + +Cipher = ascon-aead128 +Key = 0BBE28A29B2B2CFFA54EB548BDE1E2C8 +IV = 7D0C6D1415EE1722C628C77633E7ABE7 +Plaintext = 8A10 +AAD = 0EA4A7A6A07D +Tag = D1CBAEDCA885C977203F585781733FBC +Ciphertext = 182E + +Cipher = ascon-aead128 +Key = 4BFDFCDDF037F44DE0EF66EA01215C18 +IV = 800CA84402202EDF1D0AE6E10CAF21E5 +Plaintext = 2D6E +AAD = 6861A41973A294 +Tag = D05096250868D9D6E0544D61E18C6673 +Ciphertext = BF67 + +Cipher = ascon-aead128 +Key = 46218C9CFA2B627D7353D34F381C95DC +IV = 798528E5B4C65E7C5BD512FD17CFE0D5 +Plaintext = 1D78 +AAD = D4D0E23FDE852F3B +Tag = 2B29D20FA454C470EF7DE05075DD3D71 +Ciphertext = 7D57 + +Cipher = ascon-aead128 +Key = AC85B25A9988AB577E9E6DB57D06FE91 +IV = FE4461BA4514B0C82431176DF99AD4AD +Plaintext = B18C +AAD = 3211FD6FFA0CD64F5D +Tag = 03470D86E20EC2C00842F27DBE54B9C7 +Ciphertext = A2A3 + +Cipher = ascon-aead128 +Key = D697D56FE70B8DF15D662CE250542324 +IV = 2C1F27129E64D7E3CD45E85747E2A258 +Plaintext = 9054 +AAD = 7B5D9845E9CF286D8B0B +Tag = 41CCE8DC75958B077886B0EE22A7256F +Ciphertext = 2D3F + +Cipher = ascon-aead128 +Key = E4F8D6011CDD5EBEB095B0DF88288652 +IV = 885CBB2EE00E9EA5DCAD0C72DA585A31 +Plaintext = 57D6 +AAD = AA0B21465B784E242BE8A0 +Tag = F325AC3CF6B51402A3B99E016D2D1379 +Ciphertext = 6744 + +Cipher = ascon-aead128 +Key = CBAAB905D0B019BDD5F562DCA08C8177 +IV = 663DA020B4E9064E0FC787CFCE1054CB +Plaintext = B568 +AAD = A6A6FC0C7995D1520E70310A +Tag = 8A4DEE97DFB4ECD3DA7A9FC553F5DC33 +Ciphertext = 59F1 + +Cipher = ascon-aead128 +Key = 30495A0ABFC3CF9B0D66DAE7FBCEA8A4 +IV = BFA68A88EDB16BA7D566704143F299D7 +Plaintext = 79E1 +AAD = 7F986647F731C0579567480CBE +Tag = 6B66FB67F84754266960FE5DE9F1785F +Ciphertext = FED9 + +Cipher = ascon-aead128 +Key = 92C339BF3608A897D7618F35EA7C8E7B +IV = 92DDE6CCACC69FDE1926B4505151D564 +Plaintext = E68A +AAD = 60E4506FF101EDE78595CFB9A930 +Tag = 1025D3464E8BA3CE696635C44E0B072F +Ciphertext = C77A + +Cipher = ascon-aead128 +Key = 4804784A8CC172F9192F6A86947A845C +IV = BD9A57E1B4BED17B63C3CE8CD0BA13B6 +Plaintext = FB60 +AAD = F1CF018309F5B253AF2765124AB6BC +Tag = 9F331CB6142A8778CA8B6CC534B08513 +Ciphertext = 09A3 + +Cipher = ascon-aead128 +Key = 5194FD544582ED32ED29658C07658CFF +IV = ACB9576B9B3E860444FB48869C4CAF39 +Plaintext = 44A2 +AAD = FFE3EDD33FF16C6314AD320B70E5133F +Tag = CE9B8D798AAC0ACBEB9444276512DC9E +Ciphertext = 59E2 + +Cipher = ascon-aead128 +Key = A427A6D8371B63E4F7678CE73A7D2E6C +IV = A6D3F1C1B9556977BAF484B2ED3E82E6 +Plaintext = 5DB3 +AAD = 534DF0CF789670262EDEA10C494B4749FE +Tag = A133DFC53F9EC197B1A580AB91F9A52A +Ciphertext = 3E10 + +Cipher = ascon-aead128 +Key = E625B43CAC4BBA63DF5D4135FB076C99 +IV = 5ED798E03C94C246EB8BF1D32EE76A2A +Plaintext = 7DBF +AAD = ABDFA71EC1253785603FDFEFC2AA83930B8E +Tag = 57062D40319F825F7A328C9FBAF9F7A4 +Ciphertext = 0313 + +Cipher = ascon-aead128 +Key = 0C6FCBFF899CB769221D8B711D084ECA +IV = 6F37D02139544E44AFEB47B7890A85F8 +Plaintext = 5802 +AAD = D7AE0370615B802371E144946CEB4D77E65E87 +Tag = 1D9255DB06F5528393E974B147FC3E87 +Ciphertext = 0CFC + +Cipher = ascon-aead128 +Key = 5550DCA0ED0EC4F029709157A85D11CA +IV = 5E74E148063F4CE0CC75509A571A93BB +Plaintext = BFAA +AAD = B9C4930B95BEC37F8AFB828DFC1D1040A75207A8 +Tag = 6D63DCA9094A030EC7994B791D3F1FAC +Ciphertext = 701D + +Cipher = ascon-aead128 +Key = 5FC21E9DD2F817C40DC758ECC7F18DC9 +IV = 594DB3488A7D923FA91AB1A701E794BD +Plaintext = 9CDC +AAD = D687DD46A465F90B2F0DFAC7DB39BEE428BCD4EF43 +Tag = 188EBBE8875FA67AF2B45387EF8D7126 +Ciphertext = 774C + +Cipher = ascon-aead128 +Key = E611490FC18E7C6F4BE87943251DC769 +IV = 4792BA4641F284D58AAA45284C6116AF +Plaintext = 4FFD +AAD = E74C9A29362BFFFDA87AA6E5CF5CB6E6490493E455B0 +Tag = CA4C6E502472AB7FEA800AC80B75951A +Ciphertext = C2D2 + +Cipher = ascon-aead128 +Key = C0D095399776838DFB013094DE611BAC +IV = 3CDDE383415D84BB00BCA4651794146B +Plaintext = 66FF +AAD = D559C7323ECA0E1F2C6CD7FFB457CDF1BB437E60CDA1E5 +Tag = 9671BA08A6E9133E9A6C12DE8A82E358 +Ciphertext = 0133 + +Cipher = ascon-aead128 +Key = 4F83F45215C30B66D74159CD274A8DD9 +IV = 39A778652B6EFC599B7C36A064145786 +Plaintext = A5A5 +AAD = B299ED82514F6ADBA6A187FF63B5C44FA973FBE4A3776BDF +Tag = A4B152B569D6C22C267AC0E506F8E682 +Ciphertext = 1192 + +Cipher = ascon-aead128 +Key = 1C99709E71115500FA4708B94B1798B6 +IV = 5B71683A37D4C12B159BC9058D3B2EDC +Plaintext = 3CFF +AAD = 5DBA99E3CBAA20AB4C54424C5F5210422B676C4134CA104483 +Tag = BDA74C4E20224A0D30A5ED06DA92A1B3 +Ciphertext = E4B5 + +Cipher = ascon-aead128 +Key = 0A2CA3F31C89978600096168AF57A5F4 +IV = E0B9C663404DCF2C1B077712F9C34D6B +Plaintext = A4B7 +AAD = 1F1FEB7254FF7ACCE83BE895BE7FB1FA4CF7AA68B2651D79A900 +Tag = DF2F29A1AD817BAC6608172F92CD163E +Ciphertext = 7583 + +Cipher = ascon-aead128 +Key = 6565020874B8443C2E13E45700C34F27 +IV = 63A98305FA6C30C931507DCB198EED4D +Plaintext = EE96 +AAD = 979A6E6BD703495C865F6DD3AB47ADD7D0AFC5D4BADCDFA33BF685 +Tag = 6272D40FF5CA7F00CE019A15470FA24D +Ciphertext = 2FD8 + +Cipher = ascon-aead128 +Key = 712DFCB64006C81DA4E29BF677E9D7CC +IV = A98BC4AB0FBC475D2119308B28BE3E04 +Plaintext = 815A +AAD = E0367BF7B7300FF27704669C31D76D85EFD5D953020FB6AD327A4C34 +Tag = 2E6A82CCF99D44B72F32F7702D84BD10 +Ciphertext = 0BF9 + +Cipher = ascon-aead128 +Key = FF4DBA2EDD6E0E15A536267EAF088A94 +IV = FDF86D757F2E045098626AA0B28DFEAC +Plaintext = 5889 +AAD = F8EE4A23D677D552A8DEBC28B4F1F66922BE2634AC57DE9AC947014B5B +Tag = 427E10F6E2587F967A02964F858CE59B +Ciphertext = 5879 + +Cipher = ascon-aead128 +Key = FE9573C41EE028C4844A44A6FCDC4C08 +IV = A3193FD3DB61222E72E96D09EE643987 +Plaintext = 7F82 +AAD = E4A99760070D456CA0FE4B66C259D0485089470EEDAE109AC2A175E68CF1 +Tag = B0C83C81C71F31120D8F56BCD606873E +Ciphertext = EEDA + +Cipher = ascon-aead128 +Key = AA382E672CAA9328F3EDEEE1FC47E1B0 +IV = FA72B54FE72A1B667C3ED3D4C9DCBAB2 +Plaintext = 534D +AAD = 49C7EDCF99AB1AB936CF98A7E73D0FCCF4687AE1BF8B3F503EB84F86887BFD +Tag = 30B250D6A5519A138EEF5294637E89B6 +Ciphertext = A306 + +Cipher = ascon-aead128 +Key = 884232F083C4F8ADBFC1B0822179E819 +IV = 9C2A1650173BB8D7C6D5AEE41D610032 +Plaintext = 8B4F +AAD = 636361F694077073DEEDEB634B4DF7CE6F0B9FB70C2CA4DE57E11ECA39605770 +Tag = 2A621D25BA24DCB08E806C2C06DC36C4 +Ciphertext = 4668 + +Cipher = ascon-aead128 +Key = 61A1DFA6C052FD9B2728232DC5EC484B +IV = 8208DCCCA45CE1EE57D859F9611FA978 +Plaintext = ECC82D +AAD = +Tag = 4532B39E9C84637D396EDF08918DB656 +Ciphertext = 86BD1E + +Cipher = ascon-aead128 +Key = C43A350002CBBE1317AE4D398131AB20 +IV = 05332071940E677BFDB302A997FE2F10 +Plaintext = 1A7870 +AAD = 6C +Tag = 21DF576486CC3C4AFC2ECECECCA222F9 +Ciphertext = D16FB1 + +Cipher = ascon-aead128 +Key = 5750AC6790022FEDDD8EB45C41D26B74 +IV = 6590AD86D9F91440CE5802D1BB6BB476 +Plaintext = FF3DA8 +AAD = B817 +Tag = E60E18247BAC9002414CC6A5E3DA2423 +Ciphertext = C6EE42 + +Cipher = ascon-aead128 +Key = 3751E6192F5C76F8E53FE175197B1859 +IV = 1C7A76DEEAD798C62E691DFD16207ED5 +Plaintext = F9EF4A +AAD = 7A7E59 +Tag = 3EDAD48C34B1EA4B773684E363C943F8 +Ciphertext = 26CA82 + +Cipher = ascon-aead128 +Key = 3157F9D4C842B129401241D627BA6ED0 +IV = CC3850BB74F1090D77E5050CB3307363 +Plaintext = 3D6010 +AAD = 0BEB031E +Tag = F8731DFF526058EF8626E2BDCFA5DF27 +Ciphertext = 5702BA + +Cipher = ascon-aead128 +Key = 3A2C880576D124F182CB9B888DDB64B3 +IV = 1845EEF51A1DDF3AF35ACBA1F83B37F7 +Plaintext = C64BB9 +AAD = 268D8F2DEB +Tag = 484751941D985FE1F5A3E61423A62E44 +Ciphertext = 5753AF + +Cipher = ascon-aead128 +Key = 99E0F04648A18D830FF5CBA3A312D604 +IV = BA5BD037F08CBA8DE1B6D99A43DFF035 +Plaintext = B9FA83 +AAD = E55B429A2F0F +Tag = 51EAAAA917EDA46B0384682805BC12CB +Ciphertext = 89DF6C + +Cipher = ascon-aead128 +Key = C328F35C361CE84C9A3C95EF4113587C +IV = CFAA2A1D8E8F864AE94C1AD2945CD3B4 +Plaintext = 2019CA +AAD = 3DAA59318BB1F4 +Tag = AF020DB5252A6B024B4235C46D0AD2BB +Ciphertext = 675438 + +Cipher = ascon-aead128 +Key = 9A320CCE75E6EE8F9B0542689F474132 +IV = A1FE0C9D34A7EA15BA82D7FB6CD0FC6E +Plaintext = 6B50F4 +AAD = 6E8AE4B90CC24BC5 +Tag = A5AD48EF766C61C203196AB8539EC5E6 +Ciphertext = 21FB55 + +Cipher = ascon-aead128 +Key = 2367E5B22CC6D39E2FBC997BF6974598 +IV = 592C31CADB5B6777CF751F77068C2DCC +Plaintext = E73BB9 +AAD = FEA8314C170109465B +Tag = 31BE034D4B520077332A9975D61622F4 +Ciphertext = 1E1A2A + +Cipher = ascon-aead128 +Key = 763BC1357C84E0764627150A99EE996D +IV = 8686FC864E654788B489FF7A680BF7FB +Plaintext = B4FF99 +AAD = B0D3E83A546DDA21AC33 +Tag = 2B9061EB83E9A251035943DA4A09FFC8 +Ciphertext = 0E2C2E + +Cipher = ascon-aead128 +Key = C86739176C1C950F3BCFA0BA684F8A88 +IV = 3D5B6175291C664DB4E6699844A87A01 +Plaintext = 8F6F92 +AAD = 3CA13F8B5AADF65D79E6DE +Tag = 1630A31EA3D86F760DBB34DC1DABF312 +Ciphertext = 709AA9 + +Cipher = ascon-aead128 +Key = B6540A6C7855A6B9F041DC5BEAA34024 +IV = EBA9BA8EA4776C183700573429A9D282 +Plaintext = 2F6C39 +AAD = 882C584CFB2A983828047C7E +Tag = 69567BEBDB934D6B34CDFCAE51487559 +Ciphertext = CD0040 + +Cipher = ascon-aead128 +Key = AEB6DD84FB732147A66E2B2CF2D9391E +IV = F029EE875380C791F58E73583F40B07D +Plaintext = D65DAC +AAD = D991573375EC8777A6BCD5C8EF +Tag = CE066FC9C746E896777C449A9C375595 +Ciphertext = 7306FA + +Cipher = ascon-aead128 +Key = 9E8047D893083AD04808A6ADC405350C +IV = D87B40ECE0F034EC8FAEB24BCE4311E0 +Plaintext = DA0CF3 +AAD = 31CD4B70DCA965714637603357F7 +Tag = 9FF4232893B3C5AFBF9AA89B3BBD35BF +Ciphertext = 1B93F6 + +Cipher = ascon-aead128 +Key = 8493E3D083091C0C1858338BC12F10CD +IV = 4623AFE9477098589387707558FA7C27 +Plaintext = 2C0028 +AAD = D3FE40C59670A3AC366C0C4C728181 +Tag = E4C6196D021027579F615196FD091A05 +Ciphertext = BB9CCA + +Cipher = ascon-aead128 +Key = D54B7746302EAEA068D0B0B685E0F2C2 +IV = 22D9489DE5ADCDCBD0641A981E88411C +Plaintext = 670590 +AAD = 1FB838C89AB43ED217D912856E88172F +Tag = A7930315BE82644A03F847A8444C9885 +Ciphertext = 2BC9A0 + +Cipher = ascon-aead128 +Key = 485F83B1FF4887B96B0FCE73A5A3CC58 +IV = CB07632257809DCB09ADC19D559BBC1B +Plaintext = 3707A6 +AAD = EC813793821B733BEFC08DE18DE35532B8 +Tag = 040EE515E514622B26BE3CF9791510B0 +Ciphertext = 17C6F3 + +Cipher = ascon-aead128 +Key = D2B469C66D172FB0C7A8FFCDB7C789E7 +IV = F6A01589FA3914E313E49EE02186E10E +Plaintext = 0FF5DA +AAD = 3B1AFF27CB1911D0763DADCDC7AA7A029E58 +Tag = 4AC0C0DF65B929D25E2E4034ABB5B1FB +Ciphertext = 45DDA8 + +Cipher = ascon-aead128 +Key = 0B5A9FCC0FE82F3E3BB82CE5586BDF93 +IV = 6C555931B43FF302AA25A575CCBF8C79 +Plaintext = BAB11B +AAD = 025B04BE5DDC3019F7B5B8FBFEFA860218BF15 +Tag = 3C557DFD74A16150F4260AEA201DDDE4 +Ciphertext = 5E7787 + +Cipher = ascon-aead128 +Key = 522E2F7A9FC928F12E082CE4C10F831A +IV = FDC32FB6DB8B89A40AFE5C8E5A2DACA5 +Plaintext = E37A73 +AAD = 76463BC295028C5A60BA99556BC242F646CCCA67 +Tag = C2CB9D31586C4EBA6F0F90CA4BAE8EF4 +Ciphertext = E03FF3 + +Cipher = ascon-aead128 +Key = 3BCAD6E4DF503615CE223BF6BD930EDA +IV = 28D8B9A76E0E98798731E23155D0CFED +Plaintext = E84568 +AAD = D4E2E1349F6930F9D69F4BB6B51EA33BA4C1CE6CB7 +Tag = 9B19D1E5F8638A328351F5691AE47F14 +Ciphertext = 093D0B + +Cipher = ascon-aead128 +Key = D0F4B628B6FB27B4AF683F0CD3D4A3D3 +IV = A44AF5517F05AA9EA1138AA85BEFDBA5 +Plaintext = 02E596 +AAD = 75ADD2B1D00AE7167980D48A4B7971FFF637F5B3C5AB +Tag = 4086733618EA1E54F9B9422DCAD29493 +Ciphertext = DD3B47 + +Cipher = ascon-aead128 +Key = 9BA32F9580B0CDAD1E0F950E1DF20FB5 +IV = 5A2A938D964F305CB7E01975BF754636 +Plaintext = D5D90D +AAD = 0548A6E30082D2D3624DD35185F72DC05F771FC0A9FA31 +Tag = 6F637A0AA8FBD8F4A7FF3DBE72BDC81E +Ciphertext = A155EE + +Cipher = ascon-aead128 +Key = 6832470334390503D8EAEBCA087BEC82 +IV = 07D111439F94BB830758F7355A61BF3A +Plaintext = 0993E1 +AAD = 75FB92E8358E111CB48BDA64EF65F40B291CB192F5CF6B51 +Tag = 93E04BBD99186AC52E5FCC88CC863670 +Ciphertext = D0EE4B + +Cipher = ascon-aead128 +Key = 173288D30DD704BFEF190321A25B11AF +IV = D57B0EEBF756D0C8E4C0F81C6437D101 +Plaintext = 8A8D7E +AAD = CA8D8A944360BDD09B8EC0935DC5A8BA1520BBCBCF93E9C7B1 +Tag = 1FF5CA622FB92BFEA8F854EA944650CD +Ciphertext = 9FAF93 + +Cipher = ascon-aead128 +Key = CFF18BE80F47F4979DCFB2D4BA6117DA +IV = 3DD6FB2F2143A4565C5A5B6A2ECDC4BE +Plaintext = 70902B +AAD = 2497BE57020B632A4E3EBE5223A3C146399633BFF12DE84CBD24 +Tag = FE65D26F6418BBF03B8791AC0E77C23E +Ciphertext = 95DA0F + +Cipher = ascon-aead128 +Key = 6D949D4A43396340AB2708EF69A057DC +IV = 886855BFA971395B698B9248952CFCAA +Plaintext = CAB512 +AAD = D51DC677B3E1EDB299278D37920989A4EB911E9E54A1BA7384A627 +Tag = 0354B960D1460FCD941A88A3572869C4 +Ciphertext = 117222 + +Cipher = ascon-aead128 +Key = 574A473090E9F21C20CCDB6D7A72293C +IV = 743056352261B27D39F40A74FB8D40BB +Plaintext = EA233F +AAD = D60F59A5FA4949F3A40150D8BC45F43B2F3FF51F1F03B3F54A876072 +Tag = B7EF6F5029A919412267B63BEB7B7D71 +Ciphertext = 61319C + +Cipher = ascon-aead128 +Key = 43FECBAA63865B2C392FB8E1DB006D60 +IV = 85AC5AD288A1AB9BB74CB5300261BF71 +Plaintext = 61D258 +AAD = 230489EF1FA615A4476C85D5503F5A86DB906921ACEECA61B2FC898D6C +Tag = BA847E8ECB09E5E7F7889E0B44DD74FC +Ciphertext = 7318C7 + +Cipher = ascon-aead128 +Key = A7CC69115CC5CA9F8F7F47A5DFD6B597 +IV = DC0AD86F1F22EB421B5728492DCDB9EF +Plaintext = A786B7 +AAD = 83DF90E5978C1CFD2355F5E64DAD4345CB8243DC9E05AF772F408B09B686 +Tag = 8943DE4C5B2B78EB7850A13F0D8BF8A2 +Ciphertext = A2F2C8 + +Cipher = ascon-aead128 +Key = F2671C72618129473F20E97F7F062B34 +IV = 0D54936DF3D6E5437EC6A853C735836E +Plaintext = ACA44D +AAD = 86077624066A1D8BF1FF4E1F237A1E6E5443D98E658BFE9FC25714233EB93B +Tag = 883C49AC38A82D588C8AC1F64091475C +Ciphertext = E86799 + +Cipher = ascon-aead128 +Key = 6460B53AC48B3B3E4405C4FA0247A5A1 +IV = 9E5E7D2AD59DA9925C30603C2D912F57 +Plaintext = 1D17FA +AAD = 9FE88B4B2F9B3DD760B192BA37258FABE478296B1461663B56597015FF578A83 +Tag = 1908714C0EFBCDF586C69F183DB50446 +Ciphertext = BD7F05 + +Cipher = ascon-aead128 +Key = E8131E4CE00C21BF7CEBBD089F8D24CB +IV = 4050FBE3B4EED56C4D9C6B14147617A6 +Plaintext = 8F61792A +AAD = +Tag = A3F083859318BBCDB09B4437499A6BB5 +Ciphertext = 6D12E61C + +Cipher = ascon-aead128 +Key = 05C761B9324CA57FD26EA10A38F2E74D +IV = DB81C9C85CE940CA5763575518299B16 +Plaintext = DD682AFD +AAD = D8 +Tag = 5CD333DEB7CBEEF875CEF6AD4D8E314C +Ciphertext = 63D172DC + +Cipher = ascon-aead128 +Key = AD9ECFF5495D4D84D25F59B55A5DB71C +IV = 1617FBDB3485740557E83EADFF18CC32 +Plaintext = 042D519F +AAD = 55DE +Tag = 786D60A198FABEAC4E26DABF85997301 +Ciphertext = 0A0D9C5B + +Cipher = ascon-aead128 +Key = A8996BA3F3BAE37E39B69CF41FEEC8D8 +IV = A8192097B7CA60C908C5883193DD190E +Plaintext = FECE7CA4 +AAD = F2E2BD +Tag = 2137D054AB103140CFC26FAD5952D417 +Ciphertext = AE71D7C1 + +Cipher = ascon-aead128 +Key = 7939590B5771FC313E34D616B2FE6EE2 +IV = AE4D1C5C757AAB76C0293D4EE1ADA6FA +Plaintext = 2C77AFE9 +AAD = F6D78AA1 +Tag = F65AD0FDDB5DB36CA61C222A3F12F787 +Ciphertext = 6B1DEBAB + +Cipher = ascon-aead128 +Key = 5B872A387942F4D198FF2344ACB8216E +IV = FD5FFA5F5B3EB042D17B03A44C38715A +Plaintext = 010BE2A0 +AAD = D57E6C666A +Tag = 768E9D982082DFFEBADB14361E8842C4 +Ciphertext = 2D0EF526 + +Cipher = ascon-aead128 +Key = 79A86C039FFFC52DB58E294DAAEF6F37 +IV = 11D24F3C31F37491394CC9BB1789AFC6 +Plaintext = 62A59D57 +AAD = FDCB90DF0B4C +Tag = 150297E4F6AB7F96C02D40055C88F644 +Ciphertext = 9114D515 + +Cipher = ascon-aead128 +Key = EB1A36DDE02471C0A4C4E3269BEF6D63 +IV = 2D3719C5035F5EE9B755890F73C19BDD +Plaintext = 8FB1899D +AAD = 2DF88ED7ECF706 +Tag = C1B6E549C22DAB490B81D00F96967221 +Ciphertext = FD01C06F + +Cipher = ascon-aead128 +Key = 541581786E7CC93D424E3DF3A02DE10D +IV = F486ADA9FCD00BE415AD5BFFB2741951 +Plaintext = 12A99A49 +AAD = 32E13187D7B3D918 +Tag = 2AA66F43EF30E75C3265FEFC9ADCE62C +Ciphertext = B9E9A2FF + +Cipher = ascon-aead128 +Key = 5BD6B543E433697DE2B3A7C0BDA5F425 +IV = AA5F3E80B926318D48BD2C7BDAE6DCA7 +Plaintext = 98C96EDB +AAD = 657DEFD57F869452C5 +Tag = 607A7100EE0CA236DD91EFC42E50BEE6 +Ciphertext = 74D0B19F + +Cipher = ascon-aead128 +Key = 816DCF1FF590A6FA16D5483EC22C2106 +IV = 5129E857D558C3D7AE29C5ECAE3EAE78 +Plaintext = B6CBB8C1 +AAD = BCDC4F33D79177E43377 +Tag = 4ABB6981ACC364A5DF72FAA4380C541E +Ciphertext = 7A9DE96A + +Cipher = ascon-aead128 +Key = B81EF438A54E35CF8E3F1D730A349718 +IV = 29372DC5BB504F94C13654DD939BC49C +Plaintext = 04B6BC08 +AAD = 9447D641A45FE4FAB779A2 +Tag = D5854CDDB314D60202A93CFA9C631901 +Ciphertext = CD295F24 + +Cipher = ascon-aead128 +Key = A562250BC272A28EA6F36E0644FBB648 +IV = E6392C0B2D8C5B6CD1D1C20B1113499F +Plaintext = 9A4D83DE +AAD = F0E6CD18DDC56A587B446E18 +Tag = 70DF47C8313C91B3A7830D1DF54ED399 +Ciphertext = 267B6BE7 + +Cipher = ascon-aead128 +Key = E97D1191C415BA6E2F10635006FD3D82 +IV = ABA87D7DFA6490D300348266BAE0D2AB +Plaintext = 3D9A9E1F +AAD = 4BCE71A0C77D81B5FD201B889D +Tag = E68F71811EB157254DBD139940DCC099 +Ciphertext = 8BF7CBEE + +Cipher = ascon-aead128 +Key = AC7493E7B353BD65C2FD20EFEA8897B8 +IV = BC00E576E9604B4E0646DA3A53BBF240 +Plaintext = 181F18A5 +AAD = 040BE91DE543234DA99EA2303208 +Tag = 3FCFE84445CF5D265A21BFB337FA1874 +Ciphertext = 4D63384B + +Cipher = ascon-aead128 +Key = 2E2BD53D4DFEC42219F76751345E0884 +IV = 970B02D94C8A80A18FFD50BCFD09802F +Plaintext = BCE850A7 +AAD = 7472DFAD670AF28E59720F295D4F05 +Tag = 4E1E66F185FCEF95D06EA8AE11A2CCA7 +Ciphertext = C849F5F2 + +Cipher = ascon-aead128 +Key = CB69603A6AEE4EFC3AA5DCC37096C8A3 +IV = 71766447703DEBAF84073109F3B45E62 +Plaintext = B628D0E1 +AAD = 590E7A22522F642B7B857BC46A98F676 +Tag = 9D8A3FBC7786E201CE3050F80AF5CE8A +Ciphertext = 3D00055F + +Cipher = ascon-aead128 +Key = 5DBB6D068BDC35B84ADCC740767D83E0 +IV = 7964CC0A38CB2A4402420D615821DF55 +Plaintext = E6067FBB +AAD = 04D18E0AF8DB1229D76C72D6738B5618ED +Tag = A3DCFEA126A29C0A66884D565A313C19 +Ciphertext = 35DA10A8 + +Cipher = ascon-aead128 +Key = A7187B99BC633BFBA03BF6300A3AD1E0 +IV = BC27DE045AACD70694E8DF3D6CA0C6CB +Plaintext = 83035C34 +AAD = C25E2AA69C653581E232540B71C737E7691F +Tag = DC20B8DD9B1609AC4562F9ECA1B88B0B +Ciphertext = BC48DBAE + +Cipher = ascon-aead128 +Key = 89ACB24C1F9CFBF0F2FEF137680ACFBB +IV = 4464B482FDA03617BD345E0E061B6B26 +Plaintext = 1C0B8264 +AAD = FBD2371A7DD3A495A0B450CA12127D88B196CB +Tag = 26F127F96792B6470DC4DEC3CA3591AA +Ciphertext = 1000DDB0 + +Cipher = ascon-aead128 +Key = 0008EEC4F4C68D53CC9AD821BA527893 +IV = 8725E556DAF011C4DB83DAEDF0F2857B +Plaintext = F7B8E26B +AAD = 8A3519D1F7B4E613D2DF0895583ABEFCB9F52BAB +Tag = 9C3582AE1B4422B9246B19D4FECE0B93 +Ciphertext = 8A2BE31F + +Cipher = ascon-aead128 +Key = 957A8EBDC01AE985F5A2235EA225F8CC +IV = D9967C30DB8952AA28E0F8D248EE370C +Plaintext = CE9F3B84 +AAD = 83E9111D398B6C9670BA64752B9ECD2D5C13D61EBC +Tag = 107CF754CF90E1C8C8337DA8D5B20115 +Ciphertext = 1FEF588B + +Cipher = ascon-aead128 +Key = 80BFA9858252A6BA485BC0CE415BD34A +IV = 3FF58D223D837DDE73C539D368C93033 +Plaintext = 579F7649 +AAD = 950A18F5BA8AE58D5DA038E2BEB3EEE9BDB6B050E289 +Tag = EFBFBEC93E13C020627262F567DE9D76 +Ciphertext = C8508F94 + +Cipher = ascon-aead128 +Key = 2EF73B2E24BB72016DFE078587F7AE2F +IV = 65758565FD49B4AF00F69F530C4B3743 +Plaintext = CBB6D443 +AAD = 7F20644830A4E093A59FA90D595A86A2615C2594501E59 +Tag = 687FA60DBEFE31C37C9B7EA23B20731C +Ciphertext = 1BD3CCF1 + +Cipher = ascon-aead128 +Key = 1635403119E4B110A97F53737BECF9DA +IV = 9A003B2268AA04E1DE66D523ADEFF938 +Plaintext = 9DDB7ABA +AAD = ABC9B3D41FB4F5314AB031076C5D77F22E6C5FE235CFBD32 +Tag = 20DAF24D5A03CC3B50189BEF9D781FFF +Ciphertext = 8BBD80DF + +Cipher = ascon-aead128 +Key = FD2CBD12AC015775E581556E5A302289 +IV = 074E8F052C72D739A34C213C84D88030 +Plaintext = BBD6C8BC +AAD = 4B4022E89467A0C8FB37C9E7D72E22C2AD4B89748689D5DD09 +Tag = 568075F65D24B8F72F9EA43541416413 +Ciphertext = DE637970 + +Cipher = ascon-aead128 +Key = 30610B2160E917DEB9D7F9ED88D27E46 +IV = 099278D2B74B5840FAB2B4ED2BB4D84C +Plaintext = 454C2D02 +AAD = C7DC826B85AAAD40F09DA8E8D6472220B3A5E7F69E87313CEC02 +Tag = 227B22C581495620B058B3181854EF5B +Ciphertext = 98537C59 + +Cipher = ascon-aead128 +Key = 8EE17AEDA28034E73F667D8C28B5FDF5 +IV = DF59F4657D13051D08597CAF801C04FD +Plaintext = D304229E +AAD = 573EB1C9167ABE146A4CA3FE8F19D413057EE54832F931A96AB1C5 +Tag = CC7DCC3A59B2AFA34D7E740A3FB86B98 +Ciphertext = 3B57583E + +Cipher = ascon-aead128 +Key = 588EA5928CB92B89589FBA54FCD2BF70 +IV = FF99E50E6379044796E509BAB296B125 +Plaintext = CA85907A +AAD = 7E3DF575BA748569A3CE45A2CC6FF59AD2A0F4577478DC0223F3E8F0 +Tag = B710B1F7BCD4D29B5DA078D4894AE20E +Ciphertext = 3350D9B7 + +Cipher = ascon-aead128 +Key = 28E7A1CD09AFA2F4A0F2DC671D47CF15 +IV = FA7EB4CE8A7984451BDB515165BEFC5A +Plaintext = 1147C994 +AAD = 5FA106124FDFA4592507EC52DD6566FA1994273E4DF8BF269851845B30 +Tag = A2AF123BB130976D00D0F87B30B0A90B +Ciphertext = 71EA5AE8 + +Cipher = ascon-aead128 +Key = 23940C11D8A2E8F84A928C4D26B3D107 +IV = A9AAED5CBD57892CD187822BDDAD01CC +Plaintext = 8D506C74 +AAD = 6CCDD7BA2FFDEC302E3A7D3535B5FDA5FBD63FCBFF9D8FADE16B6AB83DB4 +Tag = AD8F0603FF6DE5734BA9DCBE46F68AD2 +Ciphertext = E74B6B50 + +Cipher = ascon-aead128 +Key = 05DECEE076B8BCA9BDE521B5B78F6FBA +IV = 8C1A0C066CE70A1300EF280C62C3792E +Plaintext = 97D84898 +AAD = 5D4E5C4AABE7FBA877B9583FAC4FA2140AF34874F832ACFC29E14AD01EFDE8 +Tag = 5BCEB4B0F6716D14EE90EE1CC0D08B5F +Ciphertext = A049C8D4 + +Cipher = ascon-aead128 +Key = 0DA1347B6E52F3A274B2112F34628DAD +IV = CF3CCE2C3BCEA30A7815A9E9E5FD1DAE +Plaintext = AFA5467A +AAD = C5DE58810D72B007C035EFA04D29FAF2CFD377A10B260021A5E551A89051B4DD +Tag = 8A257CF20BB0EECD266DEC958C0EB0B9 +Ciphertext = 19D9E90F + +Cipher = ascon-aead128 +Key = 656898E8E9C68624651C7F299B2E9C48 +IV = 6FD616BD11DB3FEF7BB43D289F105269 +Plaintext = A68C5135B2 +AAD = +Tag = D8D888321ED262D7315B4CD9990D0FC5 +Ciphertext = 34CCA57A1C + +Cipher = ascon-aead128 +Key = 817CF3030157C651F6ADCD5586D7DF40 +IV = 89E6C55BBDEC9B09E43B6C57BE6CADDD +Plaintext = 631CDAEBCC +AAD = 26 +Tag = 6E6C9278B63EB4979B89202751DC9F91 +Ciphertext = 08464EE420 + +Cipher = ascon-aead128 +Key = 683B5676BA48693CF8BEAE804B75E126 +IV = 4B0A83935EA6FFBB81B664C3682B9DDD +Plaintext = D3AC2A8542 +AAD = A7F3 +Tag = A2DB3EC7A04CE87CEFCACDAF08BEBA14 +Ciphertext = 360A848D98 + +Cipher = ascon-aead128 +Key = 17FD1FA7930025520DD16CA37B2FF5D3 +IV = 435EC8B1548A59036D9800CB171FB3E8 +Plaintext = B53855DC60 +AAD = E74996 +Tag = 73ED4897238C8491D21105D3339552F8 +Ciphertext = C2179EDC9A + +Cipher = ascon-aead128 +Key = 52951609359018725FB5F62CCAB90B71 +IV = F2AEF83C12334CC915E227A8B8CB5AC5 +Plaintext = 952B5D3F90 +AAD = 3577EAC1 +Tag = 09B69A1F1F26AA9AE24C749115BD32E4 +Ciphertext = 46D8FD724C + +Cipher = ascon-aead128 +Key = 258B84041A71DD4C89EBE80920513F97 +IV = 41A7BBC32491925D2499F14B2A6D1433 +Plaintext = 41A4B460DE +AAD = 2E2DBDECF9 +Tag = A40C2AE144D67C06B7E8B0C972AE844D +Ciphertext = FFDFF24690 + +Cipher = ascon-aead128 +Key = F194F51337EDA5C4A3078CC8CCBEA142 +IV = 7768C116F84531F6C68C95B7C7823B4E +Plaintext = 79CBD78AAE +AAD = FFCA4432353E +Tag = 972BBF98062F885E3F5BE5F50B80CC24 +Ciphertext = FA5AF8AB88 + +Cipher = ascon-aead128 +Key = B9E97FC2B7E16613DA5FD77CB4932A87 +IV = 2C27D6B98EAD8297DAB1101911C5D07C +Plaintext = AEBF4437A6 +AAD = 3B7F7E6A983085 +Tag = 5EF96A3E9862CFDD4ABF1B1C45882DD2 +Ciphertext = A2FBA181BA + +Cipher = ascon-aead128 +Key = D0CA2DEC47B46E438EDD9C59C97B5DC4 +IV = 6129CA8A66E378ED40724E8B6C0CD625 +Plaintext = A1AA429E42 +AAD = A172AA494C55021C +Tag = 4A4DF9752501B219D3E833F5BE79629F +Ciphertext = 1819E89AA4 + +Cipher = ascon-aead128 +Key = 7CA0727185923DA7D4B5F0BE8BBFA2F1 +IV = 2F9E259DECA682C14AEFDE30BB141E0F +Plaintext = 8A435CA5DC +AAD = 9B822C28331064BC54 +Tag = 7158624661062AFFADD0FE1C8EB211DC +Ciphertext = 03AC5DFF70 + +Cipher = ascon-aead128 +Key = 7AD15DA46EDC73FCBF2BFBF58784AA28 +IV = 4AFA2A292E0BAB96B25F1BD2887BD3DE +Plaintext = 12C7B3BE28 +AAD = D6DDA45A62FA6007B4A3 +Tag = 28D0ABDBE1E3E3F5B4112E5C086B19EA +Ciphertext = 31F4A52E40 + +Cipher = ascon-aead128 +Key = 7AD126B819FCBD3DEF444881C4DABB5E +IV = 8FECAD8526D222D6A04DBCE3BA484459 +Plaintext = 34948F51FA +AAD = 130C65210F8A09F233A0EA +Tag = DBAD81126A559BBB92A54DCAB7047D07 +Ciphertext = E96F1BC9A0 + +Cipher = ascon-aead128 +Key = 73D2F298A52CBAACE632F5F2C94CEB20 +IV = 04DABC2BEBECD6154A53492152B097A6 +Plaintext = BB3D57E393 +AAD = 4D29322A104E036A9AA6E8E7 +Tag = 6F3193284022FC31CEC2A4E444982B59 +Ciphertext = 042DB8C9E5 + +Cipher = ascon-aead128 +Key = F00C6A8FE187BE223692F78F3FA4D70A +IV = E61C4CBA55777BCCAFE19815B5C2964F +Plaintext = 24C5B8BC5B +AAD = 13B8A0B544C1938C7C8065589C +Tag = B8BCD64A4A5B028EC356ADF049ECC0F9 +Ciphertext = 1488C9EBA2 + +Cipher = ascon-aead128 +Key = 1DFC024FC50FD0852ACC34E0EF5A3F80 +IV = E8B1CC42695FB0B095E2CA2A74AF8D46 +Plaintext = C44E3F07AA +AAD = 597D954281B6FBCB44B8D98220E2 +Tag = 23F13DA2F42D2EF19A72CD0D429AEB82 +Ciphertext = 480F2679EB + +Cipher = ascon-aead128 +Key = A997B47ED5BE4B25A0A9380C85F0BA4E +IV = 5AAB9572B0B85A538CD5778A292A6DFA +Plaintext = 698CDFF47C +AAD = 675A0D294D05BAF8BB3854BA7F5067 +Tag = D131E3B4161E34F59A81A49C6E04E0CC +Ciphertext = B5964E92D3 + +Cipher = ascon-aead128 +Key = 0A426833B8A7D878F54D9471861C4BFD +IV = A7C918C11F736733AC4068A0377CC283 +Plaintext = B4C45AFC98 +AAD = B2D0BBFCE7F1C032915DCE352781A608 +Tag = D8263FF7D8C3BACF7EC2463F78656C26 +Ciphertext = A1B608593F + +Cipher = ascon-aead128 +Key = 94D5B80315FA185F5440969D514F0AD0 +IV = F31EDC09C62125A7400F7F0499862EC3 +Plaintext = B71C800726 +AAD = FFC3DC56A79B5CEFBB60C2B54EE8AE4710 +Tag = 57700E736D062AE612BD60AA733F4A3A +Ciphertext = 8E9CDE0323 + +Cipher = ascon-aead128 +Key = F1B513416B98450430F468CC5AE97EAD +IV = 8A65EA151BEC9CF8E401F3C67F7A1485 +Plaintext = 4734CFB34A +AAD = DAD87795A98747280EFB4F120736196F5C11 +Tag = CAF96E952DD1C27143ED37823196CFCB +Ciphertext = A8BD0F1796 + +Cipher = ascon-aead128 +Key = BE1C4DDEB9EF585710B68B3C74E051B5 +IV = 27BEBBC3C395E2326CBD6C9539492543 +Plaintext = 7A938EE864 +AAD = 9EB858F4F75BDD2E74BA98C28BE9016523B21F +Tag = A5CC9ED5DACE83D2F2EFFF5B9F0508EC +Ciphertext = 03DCEC3A67 + +Cipher = ascon-aead128 +Key = D819566F7CB2969ECD2EC2EAD5239AF9 +IV = 0CB8AEEBC0889AD1CC5F016550A4D089 +Plaintext = 00A97AC47D +AAD = C01546980563FA74FE3C8DD64A3400322EB34999 +Tag = C06001F680BF8EE4DA558A03E2A60E21 +Ciphertext = 45194D705B + +Cipher = ascon-aead128 +Key = 5B7B6063152D6C7935EC2DF89500DDF1 +IV = 6D9C75FAC28B25F0A84B7BF60E69EFEF +Plaintext = CF8B669796 +AAD = DDEDEFC0A6A705A0856DD5FE1701D20845285A6317 +Tag = 9706AF46BC29A1960923A2724702146C +Ciphertext = 2CB51E8C59 + +Cipher = ascon-aead128 +Key = 057BDD2A24E2BB6AA1C2EC25180A6643 +IV = 590FCA41E63117177C823E91629800B6 +Plaintext = 101BBD009A +AAD = 5A4B01E7ACA309D4918010785933C30591A2735D4989 +Tag = DDFF696CB6E53B676A97EA9843231E96 +Ciphertext = F6627679F1 + +Cipher = ascon-aead128 +Key = B08F5A659CD286A1981E1D43FD36BE1F +IV = 860164AEBAE4CD26E32B47DF2039FBA2 +Plaintext = 152C881DAC +AAD = C20F3C3EA41BCAF92DD0FBC7407405EE662441ACFB79A6 +Tag = BA50B3ABF5109A0F307844FDCA45E6FA +Ciphertext = 4EA108786C + +Cipher = ascon-aead128 +Key = 089578537E26F955988E0A34343FD41D +IV = 0594A8506E8958129F0C1C5968F177AD +Plaintext = 2EDC733CBD +AAD = C5BC405BDD6CAAD2BC93489F9E3A6247E63E955E3367751F +Tag = 09F9AB96CCBDDA20EF31FCD36A5A3011 +Ciphertext = F7DF3B02EC + +Cipher = ascon-aead128 +Key = 65DA7279AC57A1151B0D6606159E836B +IV = 37C866967F1EF052456E784853879DF4 +Plaintext = FDD80AE3F4 +AAD = 814D243B4DD72AD0B23B74D4E70B9D4DAC080F430DF67D356D +Tag = 5F6854F4CBDEE055DE15C70119AF104C +Ciphertext = D1288F7E41 + +Cipher = ascon-aead128 +Key = CC1FF65E7E4D17CF9384757BA47E15E5 +IV = A3350FFB7A18890A94F52EE46C77325A +Plaintext = 5104225EC1 +AAD = 241033B7ED74E1D667168CAF5CCAA7A7F7BDDBE462E32C74AA35 +Tag = 6DFD69ADBF8EF279708C6807FBB078A6 +Ciphertext = 68EB91EB62 + +Cipher = ascon-aead128 +Key = 825ABC4AE820D721CFEA4E9789173606 +IV = 29ADFAD189DAA9EBB9355AFEFC1860AB +Plaintext = 0D8056E049 +AAD = 88CB3318B8C49D673D469D7C9FF23007FE934DCFA332BCBEF438B5 +Tag = B69DD17364494EB7EA9C3333E7A5B43A +Ciphertext = C0C7ED24B3 + +Cipher = ascon-aead128 +Key = 96E96C87E637365403BB6E95A8BEE7A4 +IV = 0161D6DD8955CDA23AF5AD13531FF72A +Plaintext = 4BA7C152C1 +AAD = DFE139869B1EF60E05F10A1E87F555DD91151205CBA2AD1557D5A6B0 +Tag = 6324746ED3C78C2E170D70E9FA1C7FD6 +Ciphertext = 40CA641857 + +Cipher = ascon-aead128 +Key = 64378C50ABB1278060D5A59696F9C810 +IV = 714BAF456294122F16F8B2DC1947E0B6 +Plaintext = C795A3E7EC +AAD = BB2C8B5BFC3EE21F0A2028EA4F67BFC6E3FE33A1ED0571BB65B0A4C435 +Tag = F40C7B6A88CD61C82DB987DF8958DC49 +Ciphertext = 9025F18281 + +Cipher = ascon-aead128 +Key = 6CD9548B66CA85F79CCE38D1BBB31937 +IV = 684A07DB1720CEE1923AC250C9C01691 +Plaintext = C180DAAD31 +AAD = A38E85890B640CFB2A189C0EB57629698ABEDFE65C355490F7B210F96B10 +Tag = 1FFA23C79D21716B7499DF83713C4321 +Ciphertext = 45BAEF894C + +Cipher = ascon-aead128 +Key = 781A3900F666E418D7F2459813AB377B +IV = 40CA5C2F0EFBDB84DD9A8E09EB983FC1 +Plaintext = ECC7D800D6 +AAD = 9DFF50E8CFB95D954105BD476641E3160EE969450BCA343541EBF06D99874F +Tag = C0F8BE0CEAC4CA110786C1F50A6CCD1C +Ciphertext = 7D530D7B65 + +Cipher = ascon-aead128 +Key = 740A80B1B9D4C363FEEFF73B1DA2EB7B +IV = 23FA020D07678495992618922E1F58DB +Plaintext = 76224C96F7 +AAD = 7A39117B3F04CF8230BBA67940B4090CB291B4D8F3B8B690A060D10911266487 +Tag = 7616F85D105945F2239FBF993D5D4CBD +Ciphertext = B3678CF2FB + +Cipher = ascon-aead128 +Key = 88E5F66FFD2BAC4C8C28D3C1502F3BA2 +IV = BFEA3FDFF8568BB4C438F2127996F943 +Plaintext = 79A556C1EB3F +AAD = +Tag = 6244E751D583772AA221B36BDF353F74 +Ciphertext = B507D3348157 + +Cipher = ascon-aead128 +Key = D43B786C004156D24AE8B77DFAC78AA5 +IV = 3A74BF7C0B214A4E244DB4F5203017E1 +Plaintext = 465CBB0CCABB +AAD = 98 +Tag = 535CB8B64D12B83584E588D1BE4F5523 +Ciphertext = 15D223A87B1B + +Cipher = ascon-aead128 +Key = F2D4E180D4E0A5EC5AC040BBF8D16CDD +IV = 6F9708A8E2A08914EFE421528EC9C5CB +Plaintext = 517C11F005D2 +AAD = 28BF +Tag = 243A6B0FEC577324F1F353AD3E191EA8 +Ciphertext = 846CF2F946FA + +Cipher = ascon-aead128 +Key = 1E5F238FB7B25C40FF6696DEA014597B +IV = 6DBBDF57DE3BC1CDB5097812C6C87750 +Plaintext = 925EE801DC30 +AAD = 0D3960 +Tag = 968EE839FB2A806FF843A3F8870CE586 +Ciphertext = 8F570F764DCE + +Cipher = ascon-aead128 +Key = B61FD130A5ABDE7463B6B14AB3EE3DDC +IV = 92A9D60AEA5B926C0F2416A9F1E9DC34 +Plaintext = 5CC657A06053 +AAD = B548C12E +Tag = 808DCBBD53CE1817089EF2C121F10A92 +Ciphertext = 2A84C1DB2B49 + +Cipher = ascon-aead128 +Key = 8D5B796CFDD073BBBE6CD73F4F2AD2FA +IV = C2105A9D7C986985C27CACE6C769ADD2 +Plaintext = D9EDFED6D5DE +AAD = D64FB8565C +Tag = 1B2A0FE7289674155624F42471152124 +Ciphertext = 6F4CAC167CDE + +Cipher = ascon-aead128 +Key = 0C48765D4465642E99BDEA5ED85256A5 +IV = 56D95CDF712DCF755AEDC79C8395BBBC +Plaintext = F1CE746606A4 +AAD = 714F0975247A +Tag = 0696FCE5345DFDA0ED73EF1950B358B7 +Ciphertext = E6A07C5C0C8A + +Cipher = ascon-aead128 +Key = C9FF05EEBB075CC45CE5FA1341F400D6 +IV = 2A958284BF62DEC4D63EB369D0EFA604 +Plaintext = 3B3059A6DA84 +AAD = DC1C9684FBB9B4 +Tag = 57E29AA1A2A5F68206432832D26E7790 +Ciphertext = 860A9FE04014 + +Cipher = ascon-aead128 +Key = EB30C473D788EA63DF5119828810DD97 +IV = 8A0DF99EA068E3B81FDEADCCC0DF2F5C +Plaintext = 88F70E66C91F +AAD = D41E87120B63A03C +Tag = 48DBBADF964CFFB42175647D6634B95E +Ciphertext = 6EEE98A413D0 + +Cipher = ascon-aead128 +Key = 0E7A56E60E7B3047FB6821CF30427320 +IV = D94053480E55ED124B74860EF5C01F75 +Plaintext = 5932D0376EB1 +AAD = E19770BE9D9B35C786 +Tag = 8DE98F994AEA5AAFD553B84D5C5020F9 +Ciphertext = 514F185C67C4 + +Cipher = ascon-aead128 +Key = 128CDD69C9E4A3EBA73D1AEFD7216793 +IV = 34BA7571881EC840BDE42021CF16B584 +Plaintext = B8C8EC6420E8 +AAD = 1F366EA846029FFAE7A5 +Tag = 9E8DB9D66CBEE79BC6D1969F7013914E +Ciphertext = 950C67095D6A + +Cipher = ascon-aead128 +Key = 142731BC29EFED38A16389D925189A9F +IV = 9E3A555575CB992B1BFBB1C9C0706D01 +Plaintext = F9F0C53F20F2 +AAD = A73885D83516022F3622EF +Tag = 4F9FE22E45D1FA3AA2C68B25EE3AD35E +Ciphertext = 8E673106311E + +Cipher = ascon-aead128 +Key = D3325B1D916DE1A9EFCD4510A32ED379 +IV = C23D62C3372322EE833E03BB41C92B32 +Plaintext = A4EAD4AE3F79 +AAD = 9E292263E72B5F6057135624 +Tag = 1EE172D43EB9C99C6028290006C87CDB +Ciphertext = C266E94F120B + +Cipher = ascon-aead128 +Key = 33E273229713381CC010B247AD6D7242 +IV = 0024559FAA0D6739EF25DEFCA9BF6645 +Plaintext = 99190A392C82 +AAD = E30C9168A916F657EB40006574 +Tag = 4AAEC831DFF21271EC282FDDA1C70C81 +Ciphertext = 5694C2FF0882 + +Cipher = ascon-aead128 +Key = 812EA669CB7E3D856ACD0F5D9CF377AF +IV = 6A7F3124D9851B035AEE4DCBD583450D +Plaintext = 0B236F109DFA +AAD = BE9C3B91641A65E1500EC28B41B7 +Tag = 1F7F8AF56833F9973BB19097EAE13D4F +Ciphertext = F8332F475D54 + +Cipher = ascon-aead128 +Key = 7A48546DBAA34E71507B838F60BFD156 +IV = D32E064779494E5B8631A0F19F00934D +Plaintext = 1F1A3BDE6529 +AAD = 4557544B17E1BE24458E388E92D635 +Tag = 37D8ADD9CF9F25F9E81A1F46F61084C5 +Ciphertext = 500D8D0DCF66 + +Cipher = ascon-aead128 +Key = 44D902F1AA080BB3BA1AF3699A949DEF +IV = 153C0A253EA459F0FA5AFDB7AC52EE60 +Plaintext = 891282819392 +AAD = A921AE99F19B31090C77547D5263FE2B +Tag = 3400F18E0B1C3E8803270B4840F7F875 +Ciphertext = 8A4311D3CB13 + +Cipher = ascon-aead128 +Key = D9ED1DD8B4F695262B9AA414A4280ABA +IV = 6F73EA7E457C5DC3969C752E2840003F +Plaintext = 3C062AD6DA2D +AAD = 254AD30C1908632945EA0DBF65FE1D429D +Tag = 29F5D419CB5DD7575C69E2AB5B7057AD +Ciphertext = FA9D57BC8D5C + +Cipher = ascon-aead128 +Key = 4357B08868B3E81E9F8E9D7A0FCA324D +IV = 93665DE10CAD4B25821A67ADCAC89662 +Plaintext = AC178002E4C0 +AAD = 8686BBBBEC8DE5EFF49A2ABAAB398F08B16F +Tag = 6EF2D32571186716AD99B368E69C52F9 +Ciphertext = D37E4E849C74 + +Cipher = ascon-aead128 +Key = 7B36AED3B43EC0814506DF6AAFACE37A +IV = 5BC43AFA49FAC2365E846E35ED17A3C2 +Plaintext = 532F6A22CF42 +AAD = 8D80B40EC5D60852C804D6F7624FA3313D20DD +Tag = F45828440DCC460A749B7166FD3BF347 +Ciphertext = BB47275A89BA + +Cipher = ascon-aead128 +Key = C2F493E706BDA9F7D81EEA5E2D847B1C +IV = 71FBE8B231F41B368DF07CB567671F37 +Plaintext = F112067E530B +AAD = 61DE2EE41D972CE23FD10C19284F6DB0926579FD +Tag = A14D14A92505D8B8B4D3DCC64F600BB8 +Ciphertext = A54DABF4CA33 + +Cipher = ascon-aead128 +Key = 7A0306751F0B80F6834DEFEDA4BA200B +IV = EDF9CF1D501A8678329C24AD8FD0E5A1 +Plaintext = FF1BA58BA285 +AAD = 97A42685DE289B26222A29DAAB5BC561DEA74506BA +Tag = 849A36931536CA2CFD7570B52424D321 +Ciphertext = 4AEA415578AB + +Cipher = ascon-aead128 +Key = 0E89854E74221620E795AC495AE15DC2 +IV = 43595619AC853F229F12D2C5A3939576 +Plaintext = DC946A13F0C7 +AAD = 5E1CAA3A8AD45E14536F8A649A2BE863450F7BF719AC +Tag = 9FBEE774375A4F9C7B55DFF281B53EFC +Ciphertext = 3DCFF16A167C + +Cipher = ascon-aead128 +Key = 95C788511E4344577BD8893B805D5B80 +IV = 918371F05B0084AE356DFBE838649294 +Plaintext = 8BF14E83DBB0 +AAD = 8716688E80CF97DFE0ADB0D324BC3B5D2471B393C27FB4 +Tag = 15EFB66F66164D7C29E508C9F0AEA60A +Ciphertext = 81FEC8B15447 + +Cipher = ascon-aead128 +Key = 2D0AECCAADB7FCA3A6B2EAD969AA9A1F +IV = 4CA3E6E2027727DEFB708C1646B13FBA +Plaintext = 34FF0E647659 +AAD = 23AAB562D5AF2A44A1A43CFD416F429D34FE20779E07AC49 +Tag = D21D96BC631AB132DDAADAF3119332AA +Ciphertext = ADA5E0E7D767 + +Cipher = ascon-aead128 +Key = BF454AD8AC622ED41364655EAF0E3E2D +IV = 319B73BC096C35D835325A0613516682 +Plaintext = 5B99CFD39F5F +AAD = 1412B6423ED90934BAEA8DCF47F8ADEB72A2626CAA3973960B +Tag = 3C7625E8A0130B16B624C432F1882D67 +Ciphertext = 32F381E858F5 + +Cipher = ascon-aead128 +Key = C00E38A9969FB2AA12B003798843455A +IV = 8760E1B5C957BB6ECB5367974BE3C8B1 +Plaintext = 34F752524F05 +AAD = 885567495B03DD1422B9829E26948930C6AAAD7D90676E554AC5 +Tag = 09942F01A7C08650F74E3FFE6EAF0D94 +Ciphertext = 3D39EF86E5D7 + +Cipher = ascon-aead128 +Key = F52061BD967DF17D4383CEA2CB1C60AA +IV = 08E4BD6947DC2847E1D411B8C81389F0 +Plaintext = DEC5C4EC123D +AAD = FD2144A9C1D633C2F4EEABD7901EC5FF786EF06A0DE626593F08B8 +Tag = 85CC54285DDF6776686392FEA6F12FF5 +Ciphertext = 759AE0AC6690 + +Cipher = ascon-aead128 +Key = 8F721786F462F04DCA20FC69D3AF5C52 +IV = 76B3877885C4C8CB1B6881D5A5ECAF69 +Plaintext = E20209346D59 +AAD = 530EE461BC6A8F74619D1BA06ED13D0E06F26BBF206C688AAE1C04A4 +Tag = 8857329C8F28BC0FE7A85FFB4EB5DBC4 +Ciphertext = 37912F008CFB + +Cipher = ascon-aead128 +Key = 4C97D8CB4EDB850DC2AAF227CF66BB42 +IV = 2C81B6AF756150387564799AC1DB0AD0 +Plaintext = 538F0742C1F1 +AAD = 779ACF0CA191BAE1FD371CF2EDAD6A5F01447263C46FDFA11A06290284 +Tag = 31CF8B7BC617B06BACFF75BA353E738F +Ciphertext = 7A55930A8CF3 + +Cipher = ascon-aead128 +Key = B82AC83A0FF70B59D9C962D5AC6CADD3 +IV = 623141501195FCA9AED94570141FC76F +Plaintext = 3EE3384F7A0D +AAD = 408636AAA195D90A5C4A649158192B3F7A543C81C2A4B2F6989E6AAEB7B8 +Tag = F455C098B823E4801F2DC7FB6CF67E4E +Ciphertext = D5CB520D60C5 + +Cipher = ascon-aead128 +Key = 009283FD0F3996F29196A22E9B0FCBBA +IV = 1F7F2CFB3EC96D565C51515AEC995152 +Plaintext = E4FDCD1072E0 +AAD = 40A92752B065AB49B1E37E2AB290803E0F6249FE47EE860263F162F770C6A6 +Tag = 538543FB49DE0F4641787274573FFB82 +Ciphertext = FCC483C34209 + +Cipher = ascon-aead128 +Key = 1C1DC1014CF1B665F193791ECB00731F +IV = 144A2629FB400B52DAEC52DA7DB25EEB +Plaintext = FB0B51710DBE +AAD = 8D22B532BB078ECA122C599C3E6A43FF6792F74BAB21E09F61CBEEA5495F4492 +Tag = 61C8E3043BD7376349BD9EEA06FC5CA6 +Ciphertext = 32FE92AC8D0E + +Cipher = ascon-aead128 +Key = 7F6CA22877E0DD5E46BBB3D87E00CF1E +IV = 9B416C1808355CEB0D0AD1E10BC6EA76 +Plaintext = EF40371DEA3DB4 +AAD = +Tag = 3346C3FDA4617DF62DB932C8230C62C7 +Ciphertext = 5425F5FDFDC166 + +Cipher = ascon-aead128 +Key = BC9779E7F493C9165ACDBDE4EDF703AF +IV = DFF0226B8FEBB84A1FAA1F0843FF6D85 +Plaintext = 7E8B957A695C87 +AAD = 89 +Tag = FC2A492B33C60B088D6CB94C2AAF93B2 +Ciphertext = 113ED160F0878D + +Cipher = ascon-aead128 +Key = A6D012BBBF96E03425C2A1FBD8C836F6 +IV = 7353100983FC0AF340EBDEE57FAB3216 +Plaintext = 59A65025E98C62 +AAD = 730E +Tag = A6AEC79F84DC32C354E72611315C42D5 +Ciphertext = 5473018993FD60 + +Cipher = ascon-aead128 +Key = 96FFDC4FA19327EDD6C89E6B392683D6 +IV = E0976EE8810D6E33E7EBB7B05B0D8AC5 +Plaintext = F87F44CA8F3449 +AAD = EE2DCC +Tag = 2E7336E3EB1A7692CA4169B04FD4F7C4 +Ciphertext = 001252EC47DAFD + +Cipher = ascon-aead128 +Key = E5A398C7FDC7617C800481BA7263BDF3 +IV = 8BCD94A57E3550A40D152486D6BAA143 +Plaintext = C98C3D05AFB162 +AAD = B43DC05F +Tag = B02466B391016578E0416A93A46BAAC4 +Ciphertext = 42A4D77E6683D5 + +Cipher = ascon-aead128 +Key = 9EB0B548C2DD70A56388D0C6FD033307 +IV = BB78051E6B13940E19EC7598288496E4 +Plaintext = DE907E41CCEAD0 +AAD = 7AAFFB66CA +Tag = C8A688DD129BD946726D7C8B5BE6A043 +Ciphertext = B9FF5AA50ED16D + +Cipher = ascon-aead128 +Key = 2F350396992C9E651A027266AA115979 +IV = 841FDC6E621B174B4529A130C72F6701 +Plaintext = C858F66850E675 +AAD = 95783A92520A +Tag = 10E1E806A9D7DD7BB888AEB489668A9F +Ciphertext = D2404F29B48FF4 + +Cipher = ascon-aead128 +Key = 6183594DB8996E944A49E6AABE3BB8A5 +IV = C85A97FF4C3663A5AD6935D108E07802 +Plaintext = 744AF64450D523 +AAD = D5D4CE5ECC26CC +Tag = 387C514260B6982D90708826A964C16C +Ciphertext = 7BEADE3F711C91 + +Cipher = ascon-aead128 +Key = 358DF6E73771D90199C867AC482D3EF6 +IV = DAAB8C45138AAE78978A73C95D5274D3 +Plaintext = 05ACFC5A25E6B6 +AAD = BD35F54667961AB5 +Tag = 06613C016B1AE804F314B52C1A9160AE +Ciphertext = 53E049A907699D + +Cipher = ascon-aead128 +Key = 4F6B1ED317CD5213060134650F6B794A +IV = 065CA3845E1F66DFD78009AF4968AFD7 +Plaintext = 0A5E4EED8126C0 +AAD = 0B4F53F058497D64B5 +Tag = 53C6FB90D8AA37754F01496713F728CD +Ciphertext = A34F23D2F1D1FB + +Cipher = ascon-aead128 +Key = BC73B8F7BE28CAC16F9790DBCBA8C86B +IV = 3980AFB1E7B5D7003AA28E812070115F +Plaintext = 3E72F81878D260 +AAD = 65781C855CFECCCA6185 +Tag = A802386FCF086D74469E83B99DC34590 +Ciphertext = 509DC70072FA55 + +Cipher = ascon-aead128 +Key = 8AAA70EEB052A65948290E7F20596FA3 +IV = 369E926DEE97AB286899D9AE8192E51A +Plaintext = E07A01427D81F0 +AAD = EFB1871B24D622F7DABDA3 +Tag = 4998DAD8CBFB60F91C7D727F446F6B31 +Ciphertext = 4D655116CF9705 + +Cipher = ascon-aead128 +Key = A32428971466167E00F1B33560DD33CA +IV = 45680DE36B4014287980BAEA5A7C9C05 +Plaintext = 25D43AB71099A5 +AAD = 0B53CB1F593498C0CFD59566 +Tag = 1558B348BDFC9D4883EEC5C84FC250FB +Ciphertext = 48254B261314F8 + +Cipher = ascon-aead128 +Key = B03EF55262B1B35EAA46902BB2A6ADF4 +IV = 1DF82755A6082B489123527FA47D00C4 +Plaintext = CB23D82C1B8112 +AAD = 404DFAE5C38A12DCEC22A51863 +Tag = 80350FD33A7BA02DA9FF451D29386231 +Ciphertext = 149ADBC223A939 + +Cipher = ascon-aead128 +Key = 0AB4EE311A574C23F9BDD78B0F279B74 +IV = 1C48FFFD17A3CB7D2AF6D9E686673701 +Plaintext = 8A4570D49F407C +AAD = FA0E3943E9763065A1F9E5111FE6 +Tag = 3F28DC0D4A4F96014C0781F47223915E +Ciphertext = CBA68C587896C0 + +Cipher = ascon-aead128 +Key = 96A98FB6A7E54D332E28499964FCB5F7 +IV = 350E78EA079DDB3444B7ADAF1CF8DB09 +Plaintext = 789C44D1C2A73D +AAD = 4A03FC202F9C3D8A5F93FCAEDF3E0C +Tag = 0DF10E074E5D49A57061AFFE1DD9927D +Ciphertext = E4BA73F250A4FC + +Cipher = ascon-aead128 +Key = CD15446B9062B0EBEAB7474D4C106F51 +IV = BA7E8FBB5B184DC6FEE5E7A176EA10AA +Plaintext = 63A89F207B5C90 +AAD = 4665A1BFD864146A472F12296CFF646A +Tag = 573EB4F5B45FE8482C3898401D611B34 +Ciphertext = 372208196509AA + +Cipher = ascon-aead128 +Key = E5A8CEA4BEFFD6E1C1DFE378784E1BAE +IV = C1AA1D4C79E169C864ACE4E7BFB6C3CD +Plaintext = 48388A7ACECAE4 +AAD = AC49C1139CBB166FCCA1DA00A74A842C2B +Tag = BBAAEB3A9784E731B3B22F6AA02496CA +Ciphertext = F31407F19BDE7D + +Cipher = ascon-aead128 +Key = 5FCFB7E67BC469F29274C15877BBA9E5 +IV = 21158FE596C54AE359C482A29DC40B11 +Plaintext = 6060BF7AA8C8C5 +AAD = 3F8B4FB841031EA0FE93F56BB61120B90FA2 +Tag = 5AB73FAD591D70D183E28AB0930ACD76 +Ciphertext = D57A69F5E271CB + +Cipher = ascon-aead128 +Key = BFF99957CBC4E70D25068C4A8038876C +IV = 4D8881D46AD74FB5E91600F0816EED60 +Plaintext = 213D8A64712483 +AAD = 0B3C7C0DA23AAC680A6EB4E5748ABF129DAC70 +Tag = 0098422A20C8D6B0B35DFF57D525D37C +Ciphertext = 6AC9EE68CE1BC5 + +Cipher = ascon-aead128 +Key = 34597D69DE1A2E9A479E06E459877F68 +IV = E2A028A2082E818AB7D1242A57E8EB19 +Plaintext = 2008B49713F28F +AAD = 60E99005398C706AEC49BBDC194EB1B124410CF9 +Tag = 7734DF6844DBF0A513E1800FAB8128BE +Ciphertext = 4F931399D2BC8C + +Cipher = ascon-aead128 +Key = E0DDB959BCF08D1BEA35F672AAFA088B +IV = F6919FC115FD2AD9711E0C38BE71EF5D +Plaintext = AEFDAE6C2D1451 +AAD = 8A394F5C85D619E43F378BDFBAB638AAC3F3627F1E +Tag = 6B1FC624F00938CE580F0C1B87C8D9ED +Ciphertext = BE0F92D4266A39 + +Cipher = ascon-aead128 +Key = A9B19F9BB66ADD3EF8ACE216B71871DD +IV = 0324BF0E384E429CBB8EDA0DF187B774 +Plaintext = 8258052F9786DA +AAD = 44061FCD11CF06F4F5836C6C7870016998F3D5578676 +Tag = 2A1CB62EAE39FF1C5DE6997A144D05A1 +Ciphertext = 94C71EA2B38212 + +Cipher = ascon-aead128 +Key = 08D8979442627B3F402CCF3EA9AADA67 +IV = B195285A08DB1E80CB6C4A2443ED126C +Plaintext = E9E2025E04A559 +AAD = 7597A262CC44A7E8B54429262300B7DE616367E42C8023 +Tag = 38FCD83CBA981972C24AC78E94E2C7BA +Ciphertext = DD4FDE9E817E01 + +Cipher = ascon-aead128 +Key = D1676F9BE4C6AA6B635FC457B5B8DBF0 +IV = 697850858C858334008DA30A8E2B08D2 +Plaintext = 66A81604491F28 +AAD = 3B2AD0644ED62238CFA407C8691BD040656D963183CFD723 +Tag = CBA00D870EF688846CEAB070270034E2 +Ciphertext = 7FEF3D2B52B5C5 + +Cipher = ascon-aead128 +Key = E671B29FDF90DFF7215E9C540A578032 +IV = BC5883B932D85B60358760B934C90B2D +Plaintext = 79820D2AACB1F5 +AAD = F65161C5F8E08C7843FA333424676B4C8114EA4E111D02BF0E +Tag = 3AFFA93653BD5D0863F2E4ADB763A470 +Ciphertext = E471F67C5B9B82 + +Cipher = ascon-aead128 +Key = 6826B3D5EED4B78B12CE602E1E1C13BF +IV = C7D8CE81CBC8CECABBEBC8AE5F4582C7 +Plaintext = D5C0377FB3D725 +AAD = 4C4E3F52BF7618B29AB2500B2A98D9BEBB634BA3F7A801242670 +Tag = 4172E11C3F7E882D848EBC21F386B168 +Ciphertext = E459D772FFAF09 + +Cipher = ascon-aead128 +Key = A4C225ABB64D8B81DCCE587C98800F40 +IV = 7EC8036A78E06DA9EFB5F7B5730B66FF +Plaintext = 7CD78E306B73C0 +AAD = 3D284447BECDD3F9772DF1433A9C1477D383A5477FE46424E47C61 +Tag = 81E13A5F43089DF462447C3E950CDC5E +Ciphertext = 795FB88AB41325 + +Cipher = ascon-aead128 +Key = 1994A2261F420392CB2921DF6ABD3910 +IV = 7EA04ABC86B7438FE4F0BA390317A8ED +Plaintext = 5B828D0FFEB198 +AAD = ED2CEA300C1A018AA3BC9BB80B529507C9F46E54A18850A265E98181 +Tag = 2B3465DAECF00AA3E12C4F2DEC379E16 +Ciphertext = 148EB51509F1A8 + +Cipher = ascon-aead128 +Key = 3A77856229B505A0C1FBA5683B769203 +IV = 4FFA82D5F62F4F4254BB4609D626F9F8 +Plaintext = B259E6371B0D7F +AAD = 0C3E17A500A578395A78EB12DCE46B77E9D8A52E6A43EE4C9C5B2F6558 +Tag = 090118A1B6B5F7FE289B532459A0BE76 +Ciphertext = FA59274F79D917 + +Cipher = ascon-aead128 +Key = 8397832E2320EB54C7F44B4AF8745670 +IV = 5CF6802B62D20B0AAB60B1DBEC958832 +Plaintext = 70DCDF14D329F2 +AAD = EC4DD5D83D6BDCCDE19C8AED8E15EAB451B88585DE1D4BE9098C2BEE5656 +Tag = E2EFDBC6BCE796A2D4933CAAABD1FD59 +Ciphertext = 8170FE71628D61 + +Cipher = ascon-aead128 +Key = 1453C5962318DFD5AE57383A2E87F7F5 +IV = 1C80D5D9F55013447690A9C743696C02 +Plaintext = 05DD5F89CE59E7 +AAD = 9114153FF10C786939A220F7B83E26C9A7B4259483A3BF69334AF550202651 +Tag = 9CDC5F4311202A188F03D573573CD1DD +Ciphertext = 3E36ED4BFCEFBA + +Cipher = ascon-aead128 +Key = 99881C03053C3A7DBB97758D8FD759C9 +IV = 9AF42D167C97F072EAC5D109198E80FC +Plaintext = 0005CAE3F48FC6 +AAD = 4CD17D5CFB33C7E6A868649BD152D6FC53C4DA1119555062D56E2BBCA7E23060 +Tag = C3CC83AAC937B258AF6218A896887F6C +Ciphertext = C8D69116648335 + +Cipher = ascon-aead128 +Key = 28E2C885691860861CCA45FA080B4953 +IV = C92119C69DBB69F4A25975EB61B4C706 +Plaintext = BB44FE74E66A07F5 +AAD = +Tag = E09047FF418C3006B8BC37EDAF245653 +Ciphertext = BA3A20FA5B947FA3 + +Cipher = ascon-aead128 +Key = 23205C648C2583F17D7D92E8DB62DFB9 +IV = E979F2765C63F427E4BFF2D1D4F4EBFF +Plaintext = 0E042D2A91BB5D2F +AAD = DA +Tag = F423E90EF1F12AD6B62AB6E2BEEA4233 +Ciphertext = 16AAB452FAB1269C + +Cipher = ascon-aead128 +Key = 3FD081947F20BAFF18A3113CEB74E428 +IV = 3D196D03E54D86D3D8C9D4A0851E964D +Plaintext = 25703993AB26F9DE +AAD = 42E8 +Tag = 0B4B3BA1BA0736794C81CD5495C23325 +Ciphertext = FB7E6ACED652EEB6 + +Cipher = ascon-aead128 +Key = 8A4CD24E8AC0CE0DB39DD50110C1B989 +IV = B70C2D643EC77EB24D2E14A560ACFE4E +Plaintext = 76C94BA1177F8C86 +AAD = BFC0CD +Tag = 1FF417287FD21404D3112E1F0919C1D1 +Ciphertext = 866F30049131A275 + +Cipher = ascon-aead128 +Key = 79FE09E0B9B5267F512F5351B8AEBEBB +IV = 1132181D578272B14441C78E8E0AE332 +Plaintext = FC43551DDC69DB0F +AAD = 139A73CB +Tag = 3D0FADD6C15EACC1B3CEAFDBD77A7B4D +Ciphertext = 559D3F684A0CE91A + +Cipher = ascon-aead128 +Key = E286BA4C3EA854E0CD2657CCC7453243 +IV = 87F56D32203A4F6E21F9378B40A78AC0 +Plaintext = 96A7718FC4E5C6F1 +AAD = ADED78510B +Tag = 77E8ED36963ADCD05823533C65629062 +Ciphertext = 6E29EB2CEC54BCCE + +Cipher = ascon-aead128 +Key = 09E080D76E260ED678A043CEE9B3A4B1 +IV = 3F834D19EA4A309D5A95938510984D8D +Plaintext = DF0AEFBA979894C5 +AAD = 8C9D7F00084E +Tag = E3402CC9B7FAAA667B5700741688CD8F +Ciphertext = 4F6D9422C8D58C1E + +Cipher = ascon-aead128 +Key = A6B32DC83AE7DFA038BFBF1339881938 +IV = 621F7F65894E57A53FEC1FF7EC3C5E11 +Plaintext = 173EC92081F1BB69 +AAD = B41BB1B40D7F80 +Tag = 9BC48E4C2FEAF56D21C773438549506B +Ciphertext = A81B91D1D27F5967 + +Cipher = ascon-aead128 +Key = 61EE828FB9F4E117D49E2F0ADF73B64F +IV = 20FD0B25ED351123BA9C84AC096F1D7F +Plaintext = 63FFAF96AF6F6F62 +AAD = B1D17E15CA270C56 +Tag = BB16863EE3FF0EC4F13E70D1FCEA487E +Ciphertext = 7C2AB0F6A4D56452 + +Cipher = ascon-aead128 +Key = C326B15A7F3EB34A4165265C0C554532 +IV = 74AAC6E3301AE0934BC24B7DC7D5AC69 +Plaintext = 0A8011480654A450 +AAD = B7C2B122A52903515C +Tag = 3D43FF9A688BAFB06CD7E77D9FACFF2E +Ciphertext = 16DA1EFF6CE0001C + +Cipher = ascon-aead128 +Key = 16196DB3D0F796C57C1544067D993283 +IV = 43D6793C9BD285501FC34A0461019F0A +Plaintext = 7DD0C3F3E03C4D46 +AAD = 1BC2EBD9816CADBFBF01 +Tag = E7CBCFDC792380C45B38E2CED2C30699 +Ciphertext = D75556806912DADA + +Cipher = ascon-aead128 +Key = AE7190155B7B991AF32C4F670F11DCA5 +IV = F29BAB801037FDFC70D30E8886619102 +Plaintext = 05501C9E960BE739 +AAD = 63FB1AEFB48FF7DB963D82 +Tag = F1FAB123CC48A4C907BA463DD8B38355 +Ciphertext = 4EE0DC8153EEC988 + +Cipher = ascon-aead128 +Key = 118007752226ED6F8DB1095653D4C991 +IV = FE5D2012A88148CFE70BCFB5195EB80C +Plaintext = 9108EE0A5307AEC3 +AAD = ACD8BEE72CEF6766ACCB1D84 +Tag = AB358EF51691487067196D133D8AAA85 +Ciphertext = 29702C9603565147 + +Cipher = ascon-aead128 +Key = 52D902B159E4995EDE70BE186943DD62 +IV = 997F6CB2F50015571B832A54AA888DB4 +Plaintext = 10A3D1CEE6BC54E1 +AAD = CED704C172C02DC1F69DCA6517 +Tag = 620019131751F6B612AEFCA48C577C13 +Ciphertext = 0D50514CE51C32D6 + +Cipher = ascon-aead128 +Key = A3F786A2D26055E5B24729E20B80DD16 +IV = FF09BC3623D66BA5D1E614DA9819D219 +Plaintext = 5A0439067F98090B +AAD = CB94E24193E86E95E68D140F6122 +Tag = FF0DA334ABB14B6EA1C860CB868BEEC3 +Ciphertext = FBF32C5111CC676D + +Cipher = ascon-aead128 +Key = 0B32C0F22588BF202599EA4EFB21627A +IV = CB1BB8138B0F70C7D943966ABFBCF632 +Plaintext = 2D0AD2C1AB5B933E +AAD = 54D73668A16EE8A5A3D5AA1D4DA9AD +Tag = AC8B5965C14615754D856796BD2D1918 +Ciphertext = 6BB598DC9B322715 + +Cipher = ascon-aead128 +Key = A287777453EA98E006D03FF704A43BBF +IV = 64ACE6B20710997532CC9AF8E3844355 +Plaintext = 7982758411CB3BEB +AAD = 408A3C288BA89AC975E808599E0B6AB3 +Tag = 5F0E28B19284E449DDC5442EC99960FA +Ciphertext = 9616366231429DB0 + +Cipher = ascon-aead128 +Key = D89B5F46A660A2E674F00BFA66FC4D02 +IV = E8DBC752C329EB08206BCBDCE9F15BF0 +Plaintext = 9183F2D66B92862F +AAD = 5DDD5CF8AA80787A6DE330335F9ED7C9B1 +Tag = EA8F6444EC02DA630657EC04001BA926 +Ciphertext = E9EEA7339522F2E7 + +Cipher = ascon-aead128 +Key = 3684AD9C8BA6667A763A74A1AF0DA47D +IV = 8EAE66A4430D975B4BE5783B30E94AE9 +Plaintext = 5C57DCC627F625EC +AAD = 2D653287DB7B79D0E927DAD157DAA8F67657 +Tag = 38B53379A2C6F7BC60387AD5CB1F5299 +Ciphertext = 12CA6BF9E77DA0C4 + +Cipher = ascon-aead128 +Key = BAC7C961731D67FDFFD62C4DFC9535A2 +IV = E95B30EEE88D22CC042B9AB8EDACD0C3 +Plaintext = E6A8B0E1944B8AEF +AAD = 14C75D9FC4C0B6311635F0A8026138D2F7DFD7 +Tag = D52D5C4C540320D6E517CCE3AF6FFA69 +Ciphertext = 9E2E6BA4721DFD18 + +Cipher = ascon-aead128 +Key = B9B3E77198A6F25F38EEFF47F01BFE6F +IV = 1B035760B5C02A2FFB2AFBD3EFF5AE17 +Plaintext = 7F48D60FCE37C530 +AAD = 69A38868786BC0F79B20B43FD2A6888CAF1F03D2 +Tag = F3D6A1D1229847A696219060F0C4313A +Ciphertext = F4871F58CE9CE3D9 + +Cipher = ascon-aead128 +Key = 52345B62F1E1077ADF0A0A9D84856D92 +IV = 0CFDF04EDC9DDFF926E9C27A4346B261 +Plaintext = 07FA4268329FA6C5 +AAD = A64F89A371528C0B558700961ED0358F2131A95A38 +Tag = FA64E3019C955DF7057B6C5CBDA95B21 +Ciphertext = 0D90FF5D003C91AF + +Cipher = ascon-aead128 +Key = F341FFE10E27130829248CF8A56F1646 +IV = EF561ED33CE44CC7772B84A8E2B492FA +Plaintext = C2B5349787830E9C +AAD = 28437F61E215B7CC8C75D2ECBCDF415540781782214A +Tag = 044F1325D66641E148CD3144D8D4722C +Ciphertext = 45ACC2877556C4D3 + +Cipher = ascon-aead128 +Key = 44D773952971FAD5E42A34B3DE04432B +IV = 62C684F3C2854E044D8C273C862D8A15 +Plaintext = 902F2ECDC986EBA7 +AAD = 1F4A99B8046C70CC02CA475020CB615751F6AF8CACCC02 +Tag = 4E95E9479282BBC494CD99FE2B3D2AFF +Ciphertext = 7450A4B8C07487F0 + +Cipher = ascon-aead128 +Key = 8B083C20D936A344DDF966F17C19EB5E +IV = CD9AA509B9AD38FAC7D97D8BFBB5E8C6 +Plaintext = 7CA2192EF7E85FCE +AAD = FAEE487C99681B7F3274B805B977869EA198AC24FF6D1EE2 +Tag = 78CC2160435BFA42573C824B77951A2F +Ciphertext = 20367E491689877A + +Cipher = ascon-aead128 +Key = E453183E2A482ED226A8107BC9A037DF +IV = A8A7251A4812D57D145791EA830CB760 +Plaintext = A6911198F79610EE +AAD = FBAEE65663F2885B0681CEE3C460DE443B9E1FF582A0E1B75B +Tag = 5DF4D023293F902A63966279F345D390 +Ciphertext = 2D1957ADE4105F9C + +Cipher = ascon-aead128 +Key = AD1A9603F870259F93441F38DABF9AD0 +IV = B6B1F1D9BB93026EBA7A2E78306B119F +Plaintext = 3E4CDF0674370FDA +AAD = 92FC359AF0B28F8587CDF163F612D5EEF3FFC842C35D244A0642 +Tag = 64D8A864FE1D9841331422D2C21E5405 +Ciphertext = AFE5DBE1DD419607 + +Cipher = ascon-aead128 +Key = 74F693FF42B42EACEC4AD12302F17511 +IV = EA4EDF234428FF12A1D9717457CB6CB2 +Plaintext = BFE46C09567CF09A +AAD = 2E9BD491069D2C9447732417FA00A3AE29B6F09E66A4F985129770 +Tag = 7FDF0A18370C3A8D613D7AE090BAEE1A +Ciphertext = 01CC1D7B9CD16174 + +Cipher = ascon-aead128 +Key = 99B8D0ECED017C011F1FF7B37D570A13 +IV = 76F607AE7BC6DFB078952D933AA8F91E +Plaintext = EC5CCE742F6E1FEE +AAD = 0F3A6E20E2A11009C2153B1E23329885751CF1CFC44295584C26C6EC +Tag = B4C8BEC4882AF68585D629533AF81B98 +Ciphertext = B55C7551812DB506 + +Cipher = ascon-aead128 +Key = 956CD76EC012DF7CE930760598C566A8 +IV = 373C126043150D6745F7215EA551453F +Plaintext = AF4197CC1360F00C +AAD = 6BD3D39F25313880D9C2A691FE010FDC6FA81E7D1297460E18DF0D47D9 +Tag = 4FFEFA81261C3DF657C86D9651F0BE94 +Ciphertext = 75A590EAA40A5699 + +Cipher = ascon-aead128 +Key = A4702615F80D492AA6D834037799FB26 +IV = E202AC5B69D01A78BB57CB40E8BB5972 +Plaintext = D17032B192CABF63 +AAD = 654019D4FE847486995EC09489805CE12617B56F8DA426D94519B71BB629 +Tag = 93481DAC24ED215C62532A4AEB0E6C5E +Ciphertext = D39A0BB49F0570F4 + +Cipher = ascon-aead128 +Key = 942833934527EA9CDDA9B8FA92CCE081 +IV = C321B4E3129E64FA49D53D578BB5FF53 +Plaintext = 1BE3D7D4526B2954 +AAD = 1E08366A5E5910D5D4726F3C114138E57851A5EA282AEC77E26B15B1766B2C +Tag = EBA441158FA1B13F414C4C9E6926C660 +Ciphertext = F5B484B5DCFB80B9 + +Cipher = ascon-aead128 +Key = A2321C564561238683926015851D9409 +IV = 10A47B9C40C1CE406E016F3D18613388 +Plaintext = 8EFD6A99EFF87892 +AAD = F253C698B8038B60A3CF0D5AD45262B9EB96B69D8EFA3C95DA572C275C1AFC9D +Tag = 564DC2D1F2E70A6E14917FBEB238A64D +Ciphertext = 7044EB806EA89766 + +Cipher = ascon-aead128 +Key = C87E781E7F61A8BCE0499CBF7226D8E0 +IV = 316C13E010B6200FDF6BAC474CF10564 +Plaintext = 2B1166694617373B04 +AAD = +Tag = 0744B34AFFA7FB797F002B3284A3077D +Ciphertext = 2D9D61847F9567B324 + +Cipher = ascon-aead128 +Key = C5299A443DC4653954BB50BB1778EE68 +IV = F8660972E8E98193A46E7B894EA2B21A +Plaintext = 07AB7F9615BC630958 +AAD = 18 +Tag = 671CCAC35B569B8E16D2305FEE41D800 +Ciphertext = 9C6BF651ECB5FCAB93 + +Cipher = ascon-aead128 +Key = 0B0158EFB305D86225B500185994356A +IV = 769791CE7DDC89389BBA551B8BFED509 +Plaintext = BCCCF78BA322D72908 +AAD = B883 +Tag = 08AD0265F6D021FD0EC16AE137B9652D +Ciphertext = 9B9A2A31F0FD7054DB + +Cipher = ascon-aead128 +Key = 82148869B94B6D159E41CFFBCB72D408 +IV = 2F32A1BADFA603622FE914AF1687F55B +Plaintext = 30E58F1B76C64A2D82 +AAD = 6EDE29 +Tag = 6279202FE6DC3E2933039E1E1461589C +Ciphertext = E3D9D0A6327E461ECC + +Cipher = ascon-aead128 +Key = F063234311C5096BBDCA6B65DBAE6D17 +IV = EB4A54C6AEEB570F1EFDE7B43281BC7E +Plaintext = B09105A1F7E9CDFA62 +AAD = B90B367A +Tag = 68F703E3EA578BE9742DCD49C13FF20D +Ciphertext = 1C655E93DCCC0E56A0 + +Cipher = ascon-aead128 +Key = B28F260557FB55A90743AA9DC9EC45EA +IV = 1479081B122795ECF4842ABBE4AA8C35 +Plaintext = 8411C3CD0708A4ABC7 +AAD = 826075574B +Tag = 7EB02314C506758D749246696C1ECF83 +Ciphertext = C35EE8DCA0E01D34E5 + +Cipher = ascon-aead128 +Key = EBA55267D64C3305A8310F31E797FD68 +IV = 66F7DE2CB7565F1284B11346AB244F53 +Plaintext = 106D72725A959B6477 +AAD = EEC5A4CA1BF1 +Tag = 52B1B6014BAD5B57527A3906498B8CE2 +Ciphertext = 007A4B5824A8BD9B87 + +Cipher = ascon-aead128 +Key = F8F4291480BEAC170D210E2723F5F77A +IV = C1FBD8DCA15DE849E346FA3AF17616B4 +Plaintext = 230CF9C9FF8D07CF7D +AAD = 7932E4880182DB +Tag = B8421949E9AAA6B8CDB717E2F993EE65 +Ciphertext = 18962495671E8ADCE1 + +Cipher = ascon-aead128 +Key = 77BD24A90BEF30EC1863B18C34885D58 +IV = E208FF92A0FF2753DA81D259CCEE4161 +Plaintext = 5A8D9AF87A53CB7AF2 +AAD = 6DAA24D14D30A3A1 +Tag = 5F045B5B84EAC7C90C16D2D47B6EA8CB +Ciphertext = 3A24BE9F42D2F767B1 + +Cipher = ascon-aead128 +Key = EC8BD602151EEA010FCE97836E4D56AB +IV = A0BCBFB84E0C189A57346A499E15098B +Plaintext = 9412EB4BA03C035781 +AAD = 88721D260332655FBA +Tag = A827F00B0B6517208EE5BCF141AE2793 +Ciphertext = 45CCEB428507774E8E + +Cipher = ascon-aead128 +Key = 6A7BB33289A20F6D6BD6AD42E5269BAE +IV = DD4030C0782260740E5F9579C5F39C9E +Plaintext = 31D1C305BEE0260A1A +AAD = 916B956BB77A80E94828 +Tag = A770908562140F513A37F10F9D1BF6DB +Ciphertext = 3F94A413C1480770D7 + +Cipher = ascon-aead128 +Key = BABC3D469B87E297BAB1D4FFE339C4D2 +IV = 8B70F93D61283C4BC728D7AC27323B0A +Plaintext = 90387474EE58122821 +AAD = 7E2CB93160DAB3D6B48DD4 +Tag = 9CECDF7C64EB592661B2D3672F353D5C +Ciphertext = 4B7D951AA5A657F6C5 + +Cipher = ascon-aead128 +Key = ED17D61B923A61C788CFA7CEA6670393 +IV = ADD2E147F9BC090D549DF613C0025584 +Plaintext = 05531B4EB5D4C384D5 +AAD = 8D5B0041534ED628F09080B6 +Tag = 9F725AF610B03A0633CFC0CB18C4094F +Ciphertext = 4483C2F6BEF1455E18 + +Cipher = ascon-aead128 +Key = 3E59ED0BB0C3745C0848E137134066D6 +IV = 1D0252727310CEF2AE74F628ADE71B9E +Plaintext = 90450BDA7A6447F70E +AAD = 2386A86859D0020EF0EF46CC64 +Tag = F8C4B8CB3272DDEEFB7250C8885C2368 +Ciphertext = 82CBEF00B95973AFE4 + +Cipher = ascon-aead128 +Key = 5CF94F8027CCBE05287E844A0BD599BE +IV = 87C5ED1728AA15E81E4FE6492DC8A473 +Plaintext = AF6C3986A9450FB233 +AAD = C0E5D5E59A5B743842BF8A0B150D +Tag = CB40BD1E94158566A055BC305CFE5498 +Ciphertext = E3D4BD7C5C79841969 + +Cipher = ascon-aead128 +Key = D7148147C49B82649B50A4036BA4E549 +IV = 74DA225DDF080E44708F2F1A7C59C5ED +Plaintext = 1C61549A86ACE80E58 +AAD = 13CC683C19170CC9DFF1F0771732A4 +Tag = 431073224FC30F9EE979391BD8F62722 +Ciphertext = C7C4AE3E52739A1573 + +Cipher = ascon-aead128 +Key = F70D92BB36A78D34673E84673D8E9C63 +IV = FF384FB08046D8EC3AC74D6B541989B3 +Plaintext = 6E6EEA93D54E76A756 +AAD = 45FF8191060F9F8782FEA2B6E6CC3DE9 +Tag = 67ED5F9526FAFE06C3A14F8AE95AFDD8 +Ciphertext = 028AF2691ADF970951 + +Cipher = ascon-aead128 +Key = F8F217FE28A35E727E86981CA566D963 +IV = 0986E07FC86777CE2244786B4268B872 +Plaintext = 6736963BB130FFE2FB +AAD = 2DE00F4DE4F411ECF88E3B90052FF7E75E +Tag = 737BB09D0A111FFB3C98D01C7FA14E71 +Ciphertext = BA91369ABB4E8B6550 + +Cipher = ascon-aead128 +Key = 251505A4595AB6F466DF787C28D6174A +IV = EEAA70CDB30052E726CF1A467D6C83B6 +Plaintext = 23D48E3CC213D52062 +AAD = 7A04DB2ACCF8A154F23A57A8E6AA52ECD20A +Tag = 0D878C85E4CB6ED4A937ADD913D88C0E +Ciphertext = 684AE2A0EEE59A6ED3 + +Cipher = ascon-aead128 +Key = A2FE13025BC85637299245C15D2F96B3 +IV = EC79130BC1F189698C56DEB0F6603D9D +Plaintext = 081D11463A437480B2 +AAD = 82B958FE306114846E716AD652938488794F13 +Tag = 10A14E9510B2FCD86C6FD5AEFEEBAF85 +Ciphertext = 233CF1C3112C943AEF + +Cipher = ascon-aead128 +Key = 7C4EC01BA2F5FAF9445D05193BD32E94 +IV = 751F66A7F0DBCA80028F27EAA1F42A4A +Plaintext = 7E30A7500AAC6021CF +AAD = 977477558B4B76C228C897340B4C791C3E076308 +Tag = DE33D1D7347D7896E3FDABF25183F872 +Ciphertext = CF1F3C66AE3D92CA9A + +Cipher = ascon-aead128 +Key = A55B14448F3935CB850FDCA5E0D63089 +IV = 46984D132ACC4052FEDEFCEF57101497 +Plaintext = C4F4A8489FD72CB287 +AAD = D15663865E2144F9BDB6FEF6E1D6FE673AD34F2AEB +Tag = 33E5F20DCD3A981E42E0C19498663689 +Ciphertext = B9FFC03C378124B3D0 + +Cipher = ascon-aead128 +Key = 8A9A1B2C824D6114A2D52BE8A1596453 +IV = A1892E3F406CF2556374817E7258EC93 +Plaintext = 369686B9EC52D9AC3E +AAD = 4AB1DD9CE91AA36DA5858CF5C65F541E572829BB9C2E +Tag = 40FB2FEF197056704C25A367C96248D2 +Ciphertext = 415DEF656DCE125658 + +Cipher = ascon-aead128 +Key = 9709866DC54A584019FE6FCCFDCE6F5D +IV = 57EF9966E83BF1A2FD3D50289E34F0D7 +Plaintext = 72EA0D95B2B4C06238 +AAD = B673EA205DD131D659666796E72D35BEB3DA77F31C912F +Tag = 509D4271FD4FAFCFAA60FA861AE3FD41 +Ciphertext = FF1546FD2D4028E389 + +Cipher = ascon-aead128 +Key = 7ACE92F01D725C664156B7BBCB298B8B +IV = B2620A8F993BCE177D8015849BB5FBE8 +Plaintext = 820989DCED7EEF776B +AAD = 09DE2609AFB91847229963C1CA9883E43A4D2BA3BF975703 +Tag = 4E5AB5EEBCD36DC06427024961F7796B +Ciphertext = E89E22F6C622A30F45 + +Cipher = ascon-aead128 +Key = 3A2A619ECDED43A37CD8319EF20043DF +IV = 37A2A07B922B11030ACE85E3EDE8853C +Plaintext = D7C0186EF9301386A7 +AAD = B132C00B98344302F866191B805A7E508C4CA7E8CA34A67D95 +Tag = F6761164CF4DB844863558B32491DC1B +Ciphertext = 75BAEC64AA94855FEB + +Cipher = ascon-aead128 +Key = 9E1363C3943424A9CFDB771C76293DAC +IV = B05A6AECAA7E2448997C76EF3020A10F +Plaintext = 240DAF1C127B6F50A0 +AAD = C8388A3D487DB5EB135CFF9752F64C0BD31F79D7B15AAAF9BDF0 +Tag = 9FF24446560BF3129CB4B0A7AB982449 +Ciphertext = C10A3E6F1C49F20F82 + +Cipher = ascon-aead128 +Key = 48F9000A7CB4B1526A1C1479BDC7E07C +IV = A708824532FF3F9F5308CEAD0D5599B4 +Plaintext = 0FB9D0279C773C381B +AAD = C84EFE5410B5CEBAD14A6913CA6B7D2BFA54A4E72799C1354CBABE +Tag = 0453987BB1E5A2EC79A8ECCA571EBFC2 +Ciphertext = 8183EBB31AAD089127 + +Cipher = ascon-aead128 +Key = 90D6A398F908B4A8BB84D0D994CC5848 +IV = 8CCD9E0A26441BBD987648C0745D06A7 +Plaintext = 8E76378A3CFD16734D +AAD = CB9E5785D08835EBB36BA4BFDD854B58676D165A12322E50CBA6C381 +Tag = 5D001077A9488B063F2D4A340F5ADE0D +Ciphertext = B1ADCE86809F1282F3 + +Cipher = ascon-aead128 +Key = 6EC2F8B2A9E5A773D5C9EE2D04F22587 +IV = AB9625ED9D5D1D419D9633FF0623BA95 +Plaintext = 1D07172CED605548E3 +AAD = 51AF939BB82D425CC4E43730471C85B6E73EA341E99206214AE61BDFDD +Tag = 3A83D91E6385D5C97ABAB4EB229E99F9 +Ciphertext = DFD87A210AD4B237FC + +Cipher = ascon-aead128 +Key = 854F3CAB1FDA742B21B2A51B5518AD5C +IV = 6334AACD39AE882B2ECE8FA61D868107 +Plaintext = 89914F79671683D250 +AAD = 3B4C1D69CB663C5D50C8A70F060A85ECC0A8EA15B0434956466ABB613804 +Tag = C9B09330375176F51152CAB451B0152E +Ciphertext = 6BF35287C720319112 + +Cipher = ascon-aead128 +Key = 8A0ADBA255DD4A03AC4B52B9E2DA7F94 +IV = 6C9341090CC2B780EF533E0AECF81C19 +Plaintext = 4F6E24FB15FF781B9F +AAD = CED5A1AB2E9BABA51F23A750AC063B3E5F631A16CFE0522BF3C07B97DEA654 +Tag = B7B0127F9F519C2273ED7E156C6F93AD +Ciphertext = A4A7B5EECC180A593B + +Cipher = ascon-aead128 +Key = BED57792AA592D45A84EBF0DA8760C80 +IV = 56836457C29C649D6A834FD436C9B1C7 +Plaintext = 8C1DD6D6D419A69681 +AAD = 61122922A2A01BD617600CFEDE427CAF6376EA202FDF49161E46A32C04B4A038 +Tag = 4169E98BF370312AD37245E087BB9B35 +Ciphertext = 4E7CAA0E15A5FBEDE9 + +Cipher = ascon-aead128 +Key = 3FB4BDA0024284E140836292EA4958A8 +IV = 816563E8FDF8D22A38134378D149CD9B +Plaintext = 21B7CED8DADC6CDFA93A +AAD = +Tag = 717CACA1ABDE961551D158900F0F99A1 +Ciphertext = 620887C16480BF3AC0B7 + +Cipher = ascon-aead128 +Key = 3A2C343BA8BB4BF196C9B8FE4B943C7C +IV = DA5FDB3B96CB7EB74AFFC1E4C613E923 +Plaintext = 16A4CC6FE5A00A84226B +AAD = 4A +Tag = B6641DB082F6882302730BD56009FD22 +Ciphertext = 919B772DACA563029704 + +Cipher = ascon-aead128 +Key = 6673A2694482C108A5190F5BE4062781 +IV = B80485152C580E7E1DED53C51CB4DAB6 +Plaintext = 309AFCC1223781B0E046 +AAD = E520 +Tag = 9C397A861DF12C5513F36FB6D43F78A1 +Ciphertext = 71D5C81B76642BCF6C9E + +Cipher = ascon-aead128 +Key = 4569BF664C2BBF23EC58DE789E267EE5 +IV = 91ADABCECEC36698BEABAFFB51CDD241 +Plaintext = E08F8FB8F4D5F0EE37D7 +AAD = CE89C6 +Tag = 30A5F9E92A5E23EA72B44356BEA926AC +Ciphertext = DE8EA38D937F1CFB80BD + +Cipher = ascon-aead128 +Key = FEF70B8DC1E6A1B5A24158F912642E4F +IV = A15F79D513E7A2CD415D1CB9D213928C +Plaintext = 1B1D82511CA76992F275 +AAD = 9C0C90C6 +Tag = 354F9146958A6C8A6A4FB999BE771134 +Ciphertext = FB7280F2E5726DEAC19B + +Cipher = ascon-aead128 +Key = A02B78BCE884AB1679A9709F8BE8D5A0 +IV = CE0408970F5E55F16E5B6E618F71F4DF +Plaintext = 7FD9180F2325A6BAC3E3 +AAD = 7B2F067DD4 +Tag = 32823FC179CD4C189E1F85829C995033 +Ciphertext = B1BE0BF194E83DEC8C12 + +Cipher = ascon-aead128 +Key = 377EA96A7A38835712ABA6A36A636B65 +IV = 58DE0C7465AD313D5C447083438E4F1F +Plaintext = 951BCB68D40BCA0DF347 +AAD = AF980BBC7AAC +Tag = B86614E8A01EC5F58F1360752192DE2D +Ciphertext = 2D4BDF2B99F59C8B7977 + +Cipher = ascon-aead128 +Key = 9075594D100104469F59BB09FF17577C +IV = 468D356BCB715FC5E29438722363AC01 +Plaintext = D10ABD8AEB12D2CB75CD +AAD = FCC7C27A4B473C +Tag = CE796B8871821FCA215F7308E540D1E4 +Ciphertext = CD39A073689B48DDB2D8 + +Cipher = ascon-aead128 +Key = D01B159A9F8FB3E3A4514EF49512F406 +IV = 2D094D6E9E3CB3D3C39DFE635E9FBA28 +Plaintext = 8BD881A8168CA64A18B1 +AAD = C6A77AA463970170 +Tag = B14EBBA9AADE5BF49731721F28126578 +Ciphertext = 6CE7D492DB21392E4D86 + +Cipher = ascon-aead128 +Key = 2511917F88942C6CFC8EEA2116D49CE3 +IV = 60C309DAFE05B845A939C9FC96D2E656 +Plaintext = 410A8347C4570C5CD036 +AAD = E0EC4F373BB10FB276 +Tag = BE21CA58CC691591D466630D35D9150C +Ciphertext = 5EF1F3149FB5ECCC794F + +Cipher = ascon-aead128 +Key = 8F349A044D28850478162AAF5AE3A3C8 +IV = 557A888D8F92A3D92C2225CBF8904076 +Plaintext = B8A535D599A9289D4DFB +AAD = DA9FFE230A91C161D632 +Tag = 5B12D6AB1E0E2920FFD177B0A8EC83C5 +Ciphertext = A792B9101D3F4FCDD0A7 + +Cipher = ascon-aead128 +Key = 976A2E7352359EE44244A064FFB61836 +IV = 5D02760FEBBBF8E343006712A4650B91 +Plaintext = 6C65E81A3097BB3DE03C +AAD = 9BAFDB74E33F78298A508D +Tag = BBEFC2EEAD52CBD79B825FA21DE3869A +Ciphertext = A145AAD28A6031436ADA + +Cipher = ascon-aead128 +Key = 5775D683844513AC123EA4DE33BC6362 +IV = F9CBFFD8C60ADDBD1AB6911EE5EFEF8F +Plaintext = 88E08E2BD0DC99EBD636 +AAD = 3C48245B1E882A7B2B5BB922 +Tag = 83CC3D78DCE055ADA34ECF482F7E6086 +Ciphertext = 69D05C5A7F0A3C27F249 + +Cipher = ascon-aead128 +Key = 63A1803EAACA477E14A7250FEEF84600 +IV = 00DC7E1A37672497319AC3BAE814AF2C +Plaintext = A1A24F7E5DB3D291A681 +AAD = 998AAB3BF4C0DFBC63AA6ADED3 +Tag = 0584690B2E2863F7DA3E70F05E36C851 +Ciphertext = 7A28E91CEF67B48A746B + +Cipher = ascon-aead128 +Key = C30EF4BA1D90FB5621BC25C453A3B9F9 +IV = E91C457D6ECAD3DB38DF398444DF71AA +Plaintext = BBE6DC5A4B63507D9B18 +AAD = F2E6D5F00E1DE326D0893D4850B4 +Tag = 1CAE2D2AB752A0FA30E176891C176E27 +Ciphertext = 1B4DABE21FA347E61C8D + +Cipher = ascon-aead128 +Key = 389DB65C326CB9692A9C261EA1289273 +IV = 5B9AC97CE8AC4CE6DB4385AA3D925E25 +Plaintext = A67059001D786C5AFE4E +AAD = E3D873D7AD187A798FF1E7B75FF23A +Tag = C1F798085CEA545F326CB98A9DDF22DB +Ciphertext = 9A4CC659DAEBD94BDA9E + +Cipher = ascon-aead128 +Key = 6D04AE8BC1382F86024C714535CA37D1 +IV = EFC2EDCA693BF5689B414ED72CE475FF +Plaintext = 600113EDC4274E136F4A +AAD = 48FD540A089E2BD01F980047B010F63A +Tag = 8F9FBF25D54557A839E789800AA796DC +Ciphertext = 72C91CA1C87362AC67F2 + +Cipher = ascon-aead128 +Key = EC478398A8216EFD26811DB54E230F6B +IV = 22B2194A952A8FAA6E544936F3B55141 +Plaintext = 325E31A2B0668EB3B4E0 +AAD = DE238E63E195ED88DA56FB62AEBDB25F0A +Tag = C222A8A16CC755F8B676E99A7747256B +Ciphertext = 3D96F5BEE0376FE9FECC + +Cipher = ascon-aead128 +Key = 66B9C9EF77AD5BF1BC849C6DD5A11ECE +IV = 7830B929F3F101499F8B75376EF9F4C0 +Plaintext = 84027EE5081CE020DFBE +AAD = E741DB8C41ED9112DFD9B83458DA5788FE59 +Tag = CE540630B88D7EA6BC485519B99F7FA1 +Ciphertext = BC401CACDB5E1557564B + +Cipher = ascon-aead128 +Key = 8F6A7007A32802BD2CB4C620CA273132 +IV = AEDDBD0E66DD384D1F6F11784D271CDB +Plaintext = 93B1567D269F6B720066 +AAD = 7288A42CF6270E800C5A60234B74E41F40E663 +Tag = 52EC0DEB492F5ECE25331F66176BE859 +Ciphertext = 80D32B21F310C5C44D43 + +Cipher = ascon-aead128 +Key = 89D135726DD7343D318B1B544170A816 +IV = 96D198D19B91D4271D3CB04187C0A3C5 +Plaintext = F5FFB111F38D6E3942B9 +AAD = 41E48F67167FDD2581EC2D21FFF3969F9043A518 +Tag = C4B7A8C496970B7EB832FD6EFF2F510A +Ciphertext = E215D8F1106CBE0FF985 + +Cipher = ascon-aead128 +Key = 3D292CA0CA3D654C9C7829931D952662 +IV = 33C818EBAE2E82B30223827F4359E607 +Plaintext = 3C653158AFDE364CAC2E +AAD = FE3FB42C77B812642DD5B5FC072C8982910357F3D5 +Tag = F18D23CB10511EA49368A4D70C2191B8 +Ciphertext = 891D7747DC09A987B83B + +Cipher = ascon-aead128 +Key = 5F2925EEAC575A2C382CF602D1BA2218 +IV = 62AB5BFEEBEFA75B35E15295A3773F01 +Plaintext = 46F953107B39F166DF93 +AAD = A012967F2FAE4DB0F761B998B98BD2CF615989403E86 +Tag = C45809F1BE21A91CE0B634759C6BBCA7 +Ciphertext = E2A6A043E16A7ED8F410 + +Cipher = ascon-aead128 +Key = BD889C04F6730C26BF155283EC0322CF +IV = 8DF5C3CACE4BDDFA2DD12A71F5F3504D +Plaintext = 9D1DF9B3DD1D0549B12B +AAD = E98E421C232FB001CD88F4D38AC49524A942FAAD7C9557 +Tag = C888C0F86E752D654EBD516228352167 +Ciphertext = B1C143F2353E9FB8352F + +Cipher = ascon-aead128 +Key = 792D3B749D6CC57A53E2663A42EADAFB +IV = FAE8DAE2E123D37B6E62CA282D3EBB07 +Plaintext = AF64AD5FC5B9DC279596 +AAD = B0B93894BB546CB78110EEF34A46D445ACA81A44AEC17709 +Tag = 06841A2D6FD15F99D0D3EDE28FF710F4 +Ciphertext = 978E9845A47BCC6384E2 + +Cipher = ascon-aead128 +Key = F068BAD7ED4981CB2F854AC23933B2CB +IV = 6F45401CF120FB9F143AD208F882FAAD +Plaintext = DA5ED3F934E380E34ACE +AAD = CF1A2B6CE1DE2B7BB7502FA67C53616BCB81A4A503FBC33595 +Tag = 4326A078BBC8BE024AC1BC61609BFCA0 +Ciphertext = F36C929E540FCEA65404 + +Cipher = ascon-aead128 +Key = 11C4F641FEC4129B983EDA1B2CB08AE5 +IV = AFEB7EF2910D20F3C9DDE57E9B7AB2B2 +Plaintext = F92856CB4FD18535D9C6 +AAD = D4D440DE874F44926AB55DA1FF310B43B8C1519F2136A10E7353 +Tag = C9FA9E1A21732B25C4054E8475610EEF +Ciphertext = 5625B6DD5464F44EAF40 + +Cipher = ascon-aead128 +Key = 65F596CEFB1A6FEA8AD1F7C22F585676 +IV = B3C414207A3194B05CCDE5C223918293 +Plaintext = 66691FA281D5AEC945EA +AAD = E0BBF66E3BEA117A521B66E77FE2E035A99BE7B654F38EB51508CF +Tag = A104628C3CBCA3B12B7CCAE81868D8EC +Ciphertext = 9CCB129B7285C22442E2 + +Cipher = ascon-aead128 +Key = 52ADC692A89E681A27464A61B2B98483 +IV = 778F1E298E0D8B9587DD81AAD7B805BC +Plaintext = 061BD57A19AC3B4A8D08 +AAD = 65FB5F02849A0AC7324E2EE35213BBF6CB0BD583C5416334F361253F +Tag = 8CADF65FC8D76DAF0256412E3C7CFD6B +Ciphertext = D848DC3EE720FD99862D + +Cipher = ascon-aead128 +Key = B54E9113E36C277E439436B1A6F0603B +IV = 1D3F55DB0DDD6D9F121670948FFAD128 +Plaintext = E5E34AD4408EF6F8504F +AAD = 68047599E15C845E7A13E168CE336B5E2283DA8F0B170C7EBF3F1B1CD9 +Tag = D2D00A6A586D624AA94CB1741AE470AE +Ciphertext = E245A179AF1DDAD073AD + +Cipher = ascon-aead128 +Key = 0C6FECF553683D6D74F444EC2C25765C +IV = 4A78A5A8D4E76FD3B9303119B22F4E15 +Plaintext = 6D85D8E709B1ECC1ED59 +AAD = 2BDE10AC8B6BAD4FBF4F71286E71F87B144E79F2385308C3253D3E038E0E +Tag = 91F262499DDEAB37A76B2F86F7381E21 +Ciphertext = 40945D8E53B6879AC322 + +Cipher = ascon-aead128 +Key = 3DF1D1410ACD5849FD4367CD2C56BFDA +IV = 43CE48181FADAABE6BDDE5018B4B8033 +Plaintext = A46FB6E4B09CA37F5E5C +AAD = 92EFB03B60470E45CC43CE9D1B2390128C06CF920AA955D741D3DA5C0BA7B2 +Tag = 43962FF4A05AE7DD4F34B76D95D36483 +Ciphertext = 55210E73C7FF57D580B4 + +Cipher = ascon-aead128 +Key = E909BD69ABBC3B00A3D5B8DCF23C6535 +IV = 82A17308D7E3C8AA531B7745302B396D +Plaintext = FFE4E3EBB68D4436987E +AAD = 327F465C9C01FD83C57FE7373D5BEEC74F7AE56C55DBDCDCA6C77AD6588E4D73 +Tag = 5BF3DCF21B5897110EFA65CAA4774CBC +Ciphertext = 6E6F8C09076EEE0D9D78 + +Cipher = ascon-aead128 +Key = 98A7688D4E6F5FC3C0AB57DE8FB6D9D6 +IV = FE3BA26D134BC69BDC3C74476ADC9711 +Plaintext = 0D1CC691428A1A717112BD +AAD = +Tag = 24BF54DC08A644A6402F3675E92FB1F6 +Ciphertext = 85397BA0ECD101F88FC880 + +Cipher = ascon-aead128 +Key = 72C36CD5A24E67DDDD96DE5C8A782305 +IV = 2AE4E97C887296AD2D272C506C517E82 +Plaintext = 9F79F66E7D7C46EF1E4DFE +AAD = 36 +Tag = DEC0E4C0570554A2F49CE7D13C4B50B1 +Ciphertext = 1576F3AA09A24E567C4BA4 + +Cipher = ascon-aead128 +Key = 3A3BE14B881F87CEBCD7B051C729D736 +IV = FE83A834AA35334669E36B50ACE76458 +Plaintext = ECD80E709A6D7C7F5146A7 +AAD = 1B7D +Tag = A4FD78C7986D649C100185B1FF59FF98 +Ciphertext = 90A548A639EC62FE7A2F54 + +Cipher = ascon-aead128 +Key = EB178909547A84CF9FDC08D3833F598E +IV = D2DBF24BB9BCB6E8DCED487F57F5306C +Plaintext = A8D2EFFA805A418C13CFCF +AAD = B90777 +Tag = 300A628AF5EEE791655AAB77C73EF0B4 +Ciphertext = 0A49181926A6D2861322AD + +Cipher = ascon-aead128 +Key = 6AC31C9FDDFC7118E6B8572DFA3AF438 +IV = 89CFC1C12D25B7DD16C6D34B9ACAA016 +Plaintext = 3CD1A07E3A18EE07AE1189 +AAD = 1F00D66F +Tag = DB17939CE65C27DBF08AB10FAFB3CEB6 +Ciphertext = 794FE7380F7A6C805C02D5 + +Cipher = ascon-aead128 +Key = 29E0DCEEFF9DB6B1C016C5F23B1CD599 +IV = D2AFFDC99FC2277BBF7DD18D5BDC42A9 +Plaintext = 9B522DD515C8D80A40FD98 +AAD = 5C20F28BCC +Tag = C0CF50E8C258148D0DEB64C99E041703 +Ciphertext = 96598CA1F1A9B619B026D5 + +Cipher = ascon-aead128 +Key = FAB80D70004879C36837AAE147ECE219 +IV = 2F499BCFC1D4263611CAAFAE2C4455C1 +Plaintext = D777A06ADEF14241DC0766 +AAD = 31D55285F4D0 +Tag = A0D8C41BD336D574EDFA9ABF5842D5EE +Ciphertext = 6235CDFA4E53B883992EC8 + +Cipher = ascon-aead128 +Key = 42780EB2C375C02E85E5175BEB3B7668 +IV = 6588DDAFCCB1C43A75EC740612BE8151 +Plaintext = CD450AA700A1792E0F339E +AAD = D68BFC08207872 +Tag = E7C9A180623AE9FBEE5093DCC16CC98D +Ciphertext = C719480E728F44B519B290 + +Cipher = ascon-aead128 +Key = CEA84B9F5311695A233590C69EFCDEEE +IV = C716868316392FFAFEA799D7119AC94E +Plaintext = 7CAB2DFB7CC294A2B01ECD +AAD = 0160989312E604D3 +Tag = BF8BBDC61ADB663DEB5A9710BB20FD2B +Ciphertext = 2AA1948C6C9C589AE2A228 + +Cipher = ascon-aead128 +Key = 92D3F74356D465D7A9CDD9386E07F639 +IV = 176E3D7F4B7C5BAF6EE95AC16D6AA3B4 +Plaintext = 029EF895DD702B6C548583 +AAD = 1DB596E03102E1B6D2 +Tag = B2C80514F503E49B9C10A6BE9E5E4ECE +Ciphertext = 35D7DA70828A4DF8F09A14 + +Cipher = ascon-aead128 +Key = 38DB31FA00806CA7DC2E384E52C57E91 +IV = D09CBF737AF9F1EC1257F40BF3B70762 +Plaintext = 1C9295F5F8DAA321206091 +AAD = 6F2178210E52285700F7 +Tag = 735FB5B681B79DA0E548875A4EF40E89 +Ciphertext = BBC91502C34D386D520194 + +Cipher = ascon-aead128 +Key = 016B8995EB5F1A0CCBA2FC34F0315A2B +IV = 89674E78CF97C3FCEF823AF7D5FB5BFC +Plaintext = AE5319BEFE71500D231F37 +AAD = 5E4FCBDA3F6440B97D9470 +Tag = F04002772E2226E00858D286FD9DDE20 +Ciphertext = EE6891AB5FB0BACDB6164A + +Cipher = ascon-aead128 +Key = 12E86AD54E71C5D86050B232FD4555B4 +IV = 0CF5F3BCCC30E9A707A4DC7FBF3F1837 +Plaintext = F29B10320484FB41DB00E1 +AAD = AE430935699D8BADA26D2EEB +Tag = 4F2CB5FCA78ABCB0505ED150BFDAE18D +Ciphertext = 0BE436D5120DD82BB40841 + +Cipher = ascon-aead128 +Key = F2197F6998E91EC809315AA4BBF920CD +IV = 2597775D21E47D40D8B8B5D11644FE6C +Plaintext = 2E05BD308C9C0701601EFA +AAD = 1885F19DAE6DE9F28F3C1BA789 +Tag = 5F3DA4D5B035C7A54D9448AAEA0012B2 +Ciphertext = 05E6361D7D0B6933DEB918 + +Cipher = ascon-aead128 +Key = B907419AB843AEC437C6E19F78EB2E47 +IV = 3EF452774159FAE2D8E9CEDBFCE8FCF9 +Plaintext = 710511DA28EECC8118C76A +AAD = B80FED7991BBEC7A08A599656982 +Tag = 342E0BFB2145F3A02EF8C0A8F972E00E +Ciphertext = 9018B03EC7D8E4D7837D59 + +Cipher = ascon-aead128 +Key = CA0CA1046B34E5C6623EC27529A6DDDA +IV = 684CCF904761A446911B5415D28277EE +Plaintext = D3D41B15FC5FDF0A5E04C7 +AAD = 647EABC81F0CCF563430BA0AD6002E +Tag = 55C39E0044A33B29EE525AF97F6A1A23 +Ciphertext = 4EC4BFBADE4B6E35646756 + +Cipher = ascon-aead128 +Key = 18114EA2353009B8F10D3E7F37EF7CA7 +IV = E0DAB689163582B90E792E6754C19BB4 +Plaintext = 38B2CA7C2ADA45B316E4C8 +AAD = D53BBE57A269635889659D4A3A772317 +Tag = 01C5FB665974D41D9306153DD0112BEA +Ciphertext = 8E9FAB916E5417EF6A1128 + +Cipher = ascon-aead128 +Key = DD49E981ABD306BC22FCDCE51BB6C7E7 +IV = B2F58789B2D0D660B3798C5702813C39 +Plaintext = 28B1FF16631233C4971E4B +AAD = FA86AD307281C19D6DDCD0572CF8861EAE +Tag = D22A5E31BE1ECB6B83F0B3FC223FDFC5 +Ciphertext = D34576982BBD1216FB8F74 + +Cipher = ascon-aead128 +Key = 72D289E0DAE0C9D9E15DAAE6DF96D03A +IV = 6AF42AF972BC4D9A16BAC8DE539B86B8 +Plaintext = BF5956C7E918FF6682A53B +AAD = 290649EC2713C772F7918003F5FB676821F7 +Tag = A96A848850AB2054131940A3B1209253 +Ciphertext = F1ABC0E4532F96C9F6F7F3 + +Cipher = ascon-aead128 +Key = FCF5EF9BF2B849C6E2130685B4F3C952 +IV = D070B87CEB981174FCBD43116FC9DE14 +Plaintext = 696917AEC4B75699B4EAF1 +AAD = FC2B1A6EF7723B3EF68D3F49A7FDB5F45BF470 +Tag = 2EB5A427DB704F07A870E70B9D52596A +Ciphertext = FCDDD741122294CC81253C + +Cipher = ascon-aead128 +Key = 63BB38C341800EE3BB4FB62097041775 +IV = CAE55F6DF76E699C8B4B793401BEF5F1 +Plaintext = B880D9DAA51DDCFA8FFCCA +AAD = 853BD0F0B635F92F72497D443920D4C668DC2355 +Tag = 8A91555D7E20A6CE1A361838B308D6EC +Ciphertext = A34FFEB71858F86544CD02 + +Cipher = ascon-aead128 +Key = 7BC80D1CF59F535553DE1E937F0C88DA +IV = F235A37171BC5C45075B82DBAE8049D8 +Plaintext = CDE477DA70EE8D8ED8E14E +AAD = 2DD9DD3F686B3D7FD32C29E7117295921AEB307052 +Tag = 5658FBC475F82F08A1E50505B97A51AE +Ciphertext = 81E489B2A8658B0C8E0741 + +Cipher = ascon-aead128 +Key = 844E37850E5E20088292139C367E8032 +IV = 86E1EC8ED1960BF5F4F51065592E69CB +Plaintext = 9618589D8E8D89BE520BAF +AAD = 44F341C7353BAAB9547406D7725C67DFC236F4B8AFAD +Tag = E58D33BB164AE473B89DAE8B90C8DF8C +Ciphertext = 1F367422DCAD0ACB7500DD + +Cipher = ascon-aead128 +Key = 5632E84F3CE6D3912DCE7556A69F2E43 +IV = 327AEF8603773AEF9521938507C21E4C +Plaintext = ACBDDB265BA5EA1EAB56E5 +AAD = 75DD0B54C0B06631DF8A965A756F850E87031A7BB0D66D +Tag = B1FDAAEF3AA97F7B42FCB97B7333FD81 +Ciphertext = C06DFBCE217D1783B4C428 + +Cipher = ascon-aead128 +Key = FEB38FE5A9BBB7D7F3A014FC91858E29 +IV = 0FDE1753B1511937251263F2CB28E074 +Plaintext = DB9121DCC87489C0CCD163 +AAD = 3020C31C226790DA2044E43478CE750BA98394207ECA4BBB +Tag = 530C718D3D207624055CE726EDE38D96 +Ciphertext = 8345D7D25AA4194EEAE071 + +Cipher = ascon-aead128 +Key = 0CDEA54BEE003E924FB30BC39379E74B +IV = F670F92FA57B5EBD44999149E9A023E6 +Plaintext = 6EB92D2D13F809DED05767 +AAD = F5FFADF6374CBD6418097230A4C6772E6E2131406909A08597 +Tag = 1F3BD78EB8A951C350B636C16F08778F +Ciphertext = 9195390607D1DF1F04DA00 + +Cipher = ascon-aead128 +Key = DF4C76D5703755CD014008894FE28E7F +IV = 8A8B963F5C8EEFEA46C06FD08EF94613 +Plaintext = C2E684512DE6DFCDD39384 +AAD = BC5324437A448C79C6946855F4CADA6769BB98949CCFE89179E6 +Tag = 81D9004552427B48C4F1F02D3BF06E0B +Ciphertext = B5EA093EF274BEDEFB2B3A + +Cipher = ascon-aead128 +Key = A849B45D4054DF8E1A16F38D48EFEF9D +IV = CFAE003D2E8C1821FDA403B2A441836D +Plaintext = EFADE1DF3FE5FFAE064D2F +AAD = 373F97781EBEFA3A709A70DE762CC79DDFF1C3E6A8DA4BBA2F5298 +Tag = 24795C1652C9657C5AE051C921F95E84 +Ciphertext = DF5B31FD5F0C1B4337CEBD + +Cipher = ascon-aead128 +Key = 637C4E5ADD292AB0FE7578B0FC7F4091 +IV = 3627D4C9E46D6E3DBB4813C529504C19 +Plaintext = D9AA5B74B93A9531922FE2 +AAD = 748BA8E1032F9C05C90F7596B67315B161322DAD7A2CBE4B23E103D2 +Tag = 39D7722F4F2850BDB4A8A912624E27D6 +Ciphertext = D004E9FC74AB5B5640F5FB + +Cipher = ascon-aead128 +Key = 7D88F4FF5840FCB002FA5350B95A160F +IV = 6DD0AC8CD7B6B5E0323139DFE490104D +Plaintext = 73BFCCE2BD66EADB094826 +AAD = F4E90E0E9B25718467A1838A9878E53B0EFE990208B6204AAF93253331 +Tag = 2E7F0C213501C01BD65D44C99650008B +Ciphertext = B3C8838661061B657D24B7 + +Cipher = ascon-aead128 +Key = 40BB98BF884AA9A6C21C43C8E9E01EB5 +IV = 71E85FB6E1A1FE3739D81C0FE9E995D8 +Plaintext = 11B71568DACC3639AC5D3A +AAD = 5389AA32FA945EE6341CC9F77CE77DB2EA2293DBBFF2132327BF8D568211 +Tag = E5D5F003401581316143CF305C438D4C +Ciphertext = FBF2605CF291E972651D68 + +Cipher = ascon-aead128 +Key = 49DBCCFB2E24DB15821267D45AF4FAA4 +IV = C4593C7A7D4B2D6E4F304EB7E97ECD4F +Plaintext = BCE602D2A0D5E7ABC2DD79 +AAD = ED0D023064A492AC28961E98BE4D0CC0ED9976CCBCF3970D2BFBFBEE4A0B6F +Tag = 24127B2A65FD48791D5AE6DBFF1339F4 +Ciphertext = C54E6C81A476AB25E9DCF0 + +Cipher = ascon-aead128 +Key = 69377B761D06230362CCBF36B528D279 +IV = E164E7B0CFDF9F883AE9AAEC4BDB8ED1 +Plaintext = 4455BCFCE1C465DCF91A22 +AAD = 2DA0824C75092389BED687CFE1DB907F5FDE4659366901EE8CAE3286A82B95D9 +Tag = 599D07207B563F6C6EE702CB7E1F4794 +Ciphertext = D15A19DE7930F1E848C04B + +Cipher = ascon-aead128 +Key = 947C54E2B6A15AF4BA69DE0D52353C46 +IV = 2377C51DFAD51EC3A2C06723C40BAC84 +Plaintext = 4BD9359EC1FC709E354C719F +AAD = +Tag = 8173BD2DA544431ED1CF15F94FC6CF31 +Ciphertext = C578968153A1F42A507D9E49 + +Cipher = ascon-aead128 +Key = 432CB3ACEE70B7BC71ACFEA728373DCC +IV = E3EDFD295EE90FB18A9F89DB3A820B40 +Plaintext = F23DED810D64B656E4309AFE +AAD = 38 +Tag = 9CF909E0F12082F88941684D02264286 +Ciphertext = B0EFF5EA909BFD0B26176CAA + +Cipher = ascon-aead128 +Key = 5C4FD972A82A86CC5F33A404BC7D7959 +IV = F85CDC45D1D169894F40612C119EEE7C +Plaintext = 9EC790D840B040C4F73D3D36 +AAD = C40E +Tag = 58C021A4561B05ADDECE8EFB743BFB87 +Ciphertext = F3227CC099CE671CB56DF195 + +Cipher = ascon-aead128 +Key = C89C8B207CC118ED8D4B2C02B58779DE +IV = 41DE99322A8ADE3225CE32F86CA77330 +Plaintext = B781F7D2494748D5293A544D +AAD = 929B43 +Tag = 78831C56B29CB56CAA94BBCBDF99CD8E +Ciphertext = 876CB56492EA78D6741A561C + +Cipher = ascon-aead128 +Key = 06B2BDDA0D6764D5684E7D5BC174D96F +IV = DACBD9F06BA2E8A9B11810C15A7D834B +Plaintext = DEE67C89F5189AE688304411 +AAD = 67996F09 +Tag = 2336836942581C3CD308F17B5E16331B +Ciphertext = FB8A0BF20B56FBCFDE505CE3 + +Cipher = ascon-aead128 +Key = 6432CECEAE450AE65B4B3808A6962AE5 +IV = 25C4680C5C7914A1A8CB58F06E7F5F02 +Plaintext = 3B0158E9FE977C8F3EFE27F0 +AAD = DB3BAC633D +Tag = CC1E67B9CCBC30979FA0B8F63CB224AB +Ciphertext = C6C725E8FB63076E5F5BA2B2 + +Cipher = ascon-aead128 +Key = 4F7D179A82866D99658D2F144C836A24 +IV = CA7F2147C26902E2293DDD9A01C92027 +Plaintext = 256B7818772E3F54BF14D1CF +AAD = 20B617EABC55 +Tag = 8E4EC2CCC85153ABF02323F431114631 +Ciphertext = F3C23AEB078AA5AB51000892 + +Cipher = ascon-aead128 +Key = 9956ED44B117EAC68FC4529A155AB1BE +IV = B64B4CF19F971F6301EA31B0F43A7651 +Plaintext = 21359B7A99B8B6C1660DB03B +AAD = 97B22A1819FAE8 +Tag = 9831968439926CDF5CAEF8413C040EEB +Ciphertext = 842F8D7DA3944AB3001FDA29 + +Cipher = ascon-aead128 +Key = 474380FCD006A39A9D3AC809859C081A +IV = 0ED208A55C09439CC4487EBE1341AB75 +Plaintext = 56AE6539B164A149AB1E4720 +AAD = BD8D96DDB7734CC4 +Tag = F9089C4A9B5E94E9A6BFA8E10EDA7E74 +Ciphertext = 98B6A44358FBC98313F21E97 + +Cipher = ascon-aead128 +Key = 27E969B2869B52DCF52665E73EFB9DDC +IV = 9E9130458B1BB9D2BF2AD2889EBD59E4 +Plaintext = CE35EF1A98754796A3392F86 +AAD = 4A21020CA3D2484F18 +Tag = A1330723A9EA717C34AA2C229808546D +Ciphertext = 860FAB0B4C4C3485E0465D40 + +Cipher = ascon-aead128 +Key = 5BF7AF8D4D5E761EDD42603229F3BCC2 +IV = 9B8EBBB914ED730044A780BAE447942D +Plaintext = 1F82ACC36AE84805711BE68B +AAD = 319D2200278FF2CF3A56 +Tag = 72A20C9A202E3C6DB708461D7E42BC26 +Ciphertext = 7E319DD332E89E2454E7244B + +Cipher = ascon-aead128 +Key = E24F6BB5DEB077C90A02D1ED4FC23593 +IV = AFD0C92AB933FC4C61E515FF9BA8AF7D +Plaintext = C9D077DEAB89BB7BF844E10A +AAD = FCD7ADFD0490AECA01FF68 +Tag = 539AF9BD3895D29623591462F71B55DA +Ciphertext = E18761D7D44D9B1DB33F0A80 + +Cipher = ascon-aead128 +Key = 36698AC2303A2FB64C454B579D078592 +IV = DE9F17CBAB08DF8B83941D334DFA1AD2 +Plaintext = ED1A2642C8B8E6EDE75561F9 +AAD = 3939E23D17684B59EE46F553 +Tag = 97DA20C775F675A454D5C3BFA3D0FDEC +Ciphertext = 508FE5E6FBCF6EB41F6E04C6 + +Cipher = ascon-aead128 +Key = EC70BE585D1BD2DFF9B65BC2B24996D9 +IV = 1051960E4610BF09F5D285DB3CCEFF45 +Plaintext = BBD0D683166F682FF6BDE556 +AAD = A4BE44555EF145173A275B9424 +Tag = 8DC8CD083A2B32224513DEEF4E850E8E +Ciphertext = 12D80A4D69856AB54585542B + +Cipher = ascon-aead128 +Key = 283082D9EEF6BFC371E571E29C416D58 +IV = 20A860EADC3CF6ACFDC52D42916BEB44 +Plaintext = 5DAAC17336F0A56E40F81F83 +AAD = E4D27E0D243C1269BCC0B750BB92 +Tag = FE6F6869E330F147E8D2945EFBE5B3B3 +Ciphertext = B2A86E943C8D7E3C1DA8B5FD + +Cipher = ascon-aead128 +Key = EC2DA9816D17E840F0966A7532845ACC +IV = 4E181EA8854062F2C6C7EFE14446ACCC +Plaintext = AAD5A8AFAC6573F15627A21C +AAD = 5EECF4691F4A0E4FAB2C0CEAAECD72 +Tag = F176A91C00A6428BDDAD5FFBC8F07143 +Ciphertext = E5AADACF57A65BF34E6C3C7C + +Cipher = ascon-aead128 +Key = 2A508A1217BF2CF81B63E8483F5943A7 +IV = 1AD0F2E52FA26E8617AEBBF25601A00A +Plaintext = B253BC6F21B78F3EC6DB2FF4 +AAD = ADB0140A4CB3F9553955199544EACFB3 +Tag = 2B2FFA0B4B11BA40F021CD397B2719F8 +Ciphertext = E74FC65A8A5B2DD22C39F97B + +Cipher = ascon-aead128 +Key = 9C1DCD9ED0A978EAC19F923881463503 +IV = B78EB4E6FD9F803B393168FF378461C9 +Plaintext = 9232AEA1D93F41BE774CD098 +AAD = 07BE97C130B00B36E3729A59CBEEA939E6 +Tag = 8AE94A4508FBE1FBF918A78BA5FE96F1 +Ciphertext = 59E09C844F5D909B48168951 + +Cipher = ascon-aead128 +Key = 564A7764C4CC8DDC8B903EFB68A35C10 +IV = 2CE58137199BD7476C3648BAE94C1B16 +Plaintext = CD5F7EC99B61D5A113A32FB6 +AAD = F564A72CFD1FB9ABE0490C535EE6C9530678 +Tag = DC2690051766A795A254E443C89783F3 +Ciphertext = 8C838C4EF427395075973504 + +Cipher = ascon-aead128 +Key = 9F5A32919CDFAA96F467ABDD8DE587FD +IV = 0DD74A7A08CD64B6287E8A2B59ABCD97 +Plaintext = DFE66762B84EEA88C5D84F3D +AAD = 1941DFED021A5287A2C6A60FCD0F3A766CC927 +Tag = 426244490EC8A9DA0AA9B037E7209108 +Ciphertext = F982AAD94A3D3B960FA36C1C + +Cipher = ascon-aead128 +Key = 6C55F880E6A496CF7DC6CEF091A95EAE +IV = 243177A192C5A3AEB582FFE8F05AE7CA +Plaintext = 14B19E9F6BEB34CBCF43C2B8 +AAD = 367C71014B8D17EC45C97DBCA5867E725232D01C +Tag = 508671884FDE903A82DDFF9C45D16A0B +Ciphertext = 7B41C7032D4D38B35322CDBF + +Cipher = ascon-aead128 +Key = B7A105032B75EBD533F40471DCDC0486 +IV = 8C6844B6661885160001C9211A5EE494 +Plaintext = 700E1EFEC77AF0E0F6AFEECD +AAD = 0DF08247FDFDEDDCD95B9035468E17BFA9DD911710 +Tag = 0EA398A063E2A4F50FB4CD1CAAF89057 +Ciphertext = 41D19F877FC718AB17BE9413 + +Cipher = ascon-aead128 +Key = 68305584CBABB972957F00293A210577 +IV = EE626EEA715C0D824BAE05CBCDC694B2 +Plaintext = C208CDA503B70A5DBFA65138 +AAD = 2EE75D4D52484FE76F6628B52FD186F9C1DD420A415B +Tag = 8BD7FB3AA83E664898EDD6AB9695568F +Ciphertext = 4106AC5A937F09611B8D96B6 + +Cipher = ascon-aead128 +Key = E60D65D1A260F40354EA875A27C96D25 +IV = DFB604DB536FF1B980AD6C0763ED935B +Plaintext = 308F8D9D81F39C6A9A252D57 +AAD = B56763829F9DC72E9F67A2236A5F7FEA850EE558208E6D +Tag = A9CF1D4B0421EC96B24BCC845F30DA84 +Ciphertext = 9A3EB47601B77150FE34D3B5 + +Cipher = ascon-aead128 +Key = CAE593DF0F01A9E515C117D30D4FECF2 +IV = 67A51730B9EDCF47DA8303C747168D7C +Plaintext = 1BC886934A5EC8C41F3DFA8D +AAD = 8C53E406E6077095EB6917D4F5109009807DCD89B0FD6BA4 +Tag = 5D83D385E856F6E688F372748D7E1972 +Ciphertext = 07D868248EF19697092499DA + +Cipher = ascon-aead128 +Key = FA9690DD92937B7C3A559E6EFFC7884D +IV = 919E20C8359D19170DE0341E73509E3F +Plaintext = C6F56AA5628D18CD892E1815 +AAD = 95F5A26E82A1D9401E0F89C07457CA2C36B9938B2B5B301D6D +Tag = 8B09D99B0DDB9CCC5E296248EB5951D6 +Ciphertext = D0F649A3505897B32D2D5AD9 + +Cipher = ascon-aead128 +Key = 6D109B32C1E4E0FC8AEC85D96FE71C81 +IV = 408C7B95A0FCF3D3E74D3D124F319888 +Plaintext = 2FF9F0E30DEAFF0B1BF727ED +AAD = 81B4DD6C42850A4A20C0A6A9F5330A0B778AF358375CE8CFD9C5 +Tag = 98758891554C19CA0720CA64136878F4 +Ciphertext = CD618BDDD3666614A13AAC1B + +Cipher = ascon-aead128 +Key = 79FA900F63BBA648E6243C237570C092 +IV = 5EC72424FB0A92BEB2B3FCD49ECEFF60 +Plaintext = DA8B3E6A51E4A8B9A0354662 +AAD = CBF54451DCDC42A2AEF287489F6E9D0F10143BD5CA6652EF361E88 +Tag = FC9191A281293994EB62281981EF113E +Ciphertext = A8342042161B4869A938FB73 + +Cipher = ascon-aead128 +Key = 469A35159AEED567611EB38951D03550 +IV = 6859EDABA8A21E60CB5C2A6C1B905F46 +Plaintext = 4C31E5F3756430189E6FD3C5 +AAD = 81264E9D2FC838D493596320C5B7B5E2B5DA1392B73FCAF81E443594 +Tag = 0C7E03C5D831666A0E96792CECABDACE +Ciphertext = F0558B9CB19806883863721C + +Cipher = ascon-aead128 +Key = B0BB2263665CB8998A2085839E8CDB61 +IV = 02085E0CA6A3FFBEBA4EF403D7D5BF61 +Plaintext = CD3AFFB757F73D5F5E1AEFD9 +AAD = 48D9BCA265EE39E0E6CC8620B7D418E7948C79CA609FD35CDE475617C0 +Tag = 88D9EEF2E17511847358146BC39CBD2E +Ciphertext = 6839749ABED415FCDC35A21D + +Cipher = ascon-aead128 +Key = C373F4DB108A9C72460463BF28CC446F +IV = 83F860DA9D6D984C995106300CE17407 +Plaintext = FBC3CC1E3822B7589D669F54 +AAD = AAB32971775C61D7F172107301394A78523CAAFD87D2114A6E6297731F52 +Tag = BF10B5BA338533BCFF70C8F45FF78766 +Ciphertext = 58A84939EAD4D530DB459069 + +Cipher = ascon-aead128 +Key = F26AAC45ACFAD7448C5DFE063DD7B6B9 +IV = D121975B0A8644654A1B574B7142A4F2 +Plaintext = F3A5AD1C44C0FEF2FC8710E5 +AAD = 8E5197E2535225CD7ECB22973FC6A0091028E9FEA24578BDA7C3052329CF10 +Tag = 25AF37CAFFC7862E3D4E74BEC44FF268 +Ciphertext = FAEF7C87B1A5DBEB5D14DBD3 + +Cipher = ascon-aead128 +Key = 5A4A9CFE9E52F3EA9FE97CBAFE5911BB +IV = E584907042756984D21F0BE092A5E2D4 +Plaintext = 42D3BCBC2318435A8F84728F +AAD = 23293F318643AC47117B81CE1C3FF8B10B4D7DF505F8387813A731DCC66BA83F +Tag = 81ECEE49669A55D64258E515DFBFFB9E +Ciphertext = ED78F0CDDF4604826F72B38B + +Cipher = ascon-aead128 +Key = 1653079151732C6BC40B47B07EA8E020 +IV = F977DF7EDF24D3571FF988891281B848 +Plaintext = 8194E25662CD93B4CE657798CF +AAD = +Tag = 0F084AD03503539CDA358A96D13BCAC5 +Ciphertext = E54CBC136B882AF9123EE8D522 + +Cipher = ascon-aead128 +Key = 064B3DD58388EAD024F5BFB1B2EB70F4 +IV = B1EA5DBD3BCACFF1E0F737101C1F83DB +Plaintext = FC831989942B79F09116E0CFF8 +AAD = 6B +Tag = 35D67B40B0E4697176805C70E43F77AA +Ciphertext = 31933F9CDC82B9F0F30A2CC750 + +Cipher = ascon-aead128 +Key = B1B475497429B812A330067139F43D98 +IV = 5FDAD7F6E052AB5DEC51D2AB6AD3243D +Plaintext = CF37C3850B1392DB2CCD9855F1 +AAD = D5E5 +Tag = 065DDBB77BC04313622180734C2A299D +Ciphertext = 6F9021DB468623DB960852849E + +Cipher = ascon-aead128 +Key = 5FA3F16BA085F3811D134D39C16868B9 +IV = 44711664285B7E2B137576070D6475DA +Plaintext = D60EB5AF216D94C1CAD3D477C1 +AAD = C964D0 +Tag = C96115B875603AEC666AB19193360192 +Ciphertext = 4A1A9ED553871B7C1A69625CFA + +Cipher = ascon-aead128 +Key = 647543FEA3A2B9696E2AADCBF47CAED6 +IV = CFEE2F338A0335B56F8BC42F31A99DCC +Plaintext = BD67BB5A260F743972E5CE5C1E +AAD = 5DF6F4F7 +Tag = 4A7CD213585131B5693F097883DF2AFA +Ciphertext = 55CD2836CE8489B18319338664 + +Cipher = ascon-aead128 +Key = 4423F7992286CBE08039D72F166EEE03 +IV = 904D7E7A40181E1BD9AD3BB978B0FF70 +Plaintext = 2F072E97F83C805B1F1C5A1BF8 +AAD = EA535EF465 +Tag = 2964661B7B9C5C4AC40742EED937D0C9 +Ciphertext = E615E28524D408E4D623358FE7 + +Cipher = ascon-aead128 +Key = A47B02E8E9A2544747BE213228E70230 +IV = A617BA579036F957A2CF964D9BBAAB89 +Plaintext = 7C0E378CAC25BD5A0F31D455D6 +AAD = 4567D1A537D2 +Tag = 591047E892F3CF30A629BCD06FD4DDAE +Ciphertext = 43BC0BE60891B073DF6B5796AE + +Cipher = ascon-aead128 +Key = 3834FDE9459D86E395A60F5FA0ECD358 +IV = A56D6823122B4906F4FD90D5E67D6C97 +Plaintext = 6C176F651E9FC676AE02775145 +AAD = 285154365DAE6D +Tag = 334A8C73E00E3AD9EC14EE668420FC20 +Ciphertext = EAC6E07977A26A211D230350E3 + +Cipher = ascon-aead128 +Key = 9262D67E635E58B829F1943FAAE776AA +IV = 2273D7AEDEDFBC99412F20AC71BB8DB9 +Plaintext = 0BA104073BF446EC6A5F47D90B +AAD = EDBE73BFFEC92909 +Tag = 2D14D847014628FFF837D614ABD6C26B +Ciphertext = 161C76D8CBC95E8330A602EF6D + +Cipher = ascon-aead128 +Key = 12569DD1947491DB6A808E65239ABA92 +IV = C25D97185A5C4CE5E2386DFA798DA9F0 +Plaintext = A83898365D601AE1AA97621925 +AAD = 08B785484239AA44AD +Tag = B4E2F11F510B4D41860AF83381048352 +Ciphertext = 8768DD0AA9BBA013B27634A9EA + +Cipher = ascon-aead128 +Key = D2C4F14B161DAB95671DBA0548CCEA8C +IV = B148242BFF6A36EC735F88D2C9419F4B +Plaintext = 32A0D560C35E42A7DFD20CAEA5 +AAD = 6B2ED689CDF7563C02F1 +Tag = CFF98BE41EA41EFA42774A2F2F3110A0 +Ciphertext = E46B376DE8A2C39790F1729B0A + +Cipher = ascon-aead128 +Key = F26B909B619AA9FC604D17F64345D50C +IV = 0709066BF1C4142E8ED0A8728F4D113D +Plaintext = 5620320D1DB0A4A3FEE553B508 +AAD = F9F316A272F32AE575C7E1 +Tag = AEA0B5FF2BDBE06FDA6E48F5ED0C0BFE +Ciphertext = 1F8D0B240E39819D8F08831613 + +Cipher = ascon-aead128 +Key = 7E42B7CCDFAF0EF19DEE69990A99E759 +IV = 915A7AC6B8A5E417A4183E2FD03FF37D +Plaintext = F603894F1EF5660B0A365E3089 +AAD = D7F3FAFE9E32ACA70669DB4C +Tag = F14B290BDE7C77556E7685329A4FF3C8 +Ciphertext = 22F4130485CBB6F533293DBFF8 + +Cipher = ascon-aead128 +Key = 15ACC8776E27BB2809EDD20B26CC38F3 +IV = F324BD5957B93D3BA745F45C542E1180 +Plaintext = 6FC90B41DA5C3131ED94C8126A +AAD = 26246A9F6A7E149C139841CCF8 +Tag = 3D64B919A7205941CC857B5F3A19A157 +Ciphertext = E42A9AC08DE0C50746F69B8CC2 + +Cipher = ascon-aead128 +Key = 6D3FAEC7144A4DB18158CD5C52A671A7 +IV = CDB063085F015EABFB42948E4DAEF9C5 +Plaintext = 6372819C5873866F66431A3A54 +AAD = 4260FEBD7C7450D0940753D737DD +Tag = 7AB80C80A371836F705BF1F6348FD749 +Ciphertext = E2829AB91BEF66645F75A5532D + +Cipher = ascon-aead128 +Key = 720843542B61ACE5D6BB6E8854D8AA65 +IV = DC3D1B24ECEB290DDC776E7DDFF91DE7 +Plaintext = 4CCE6608C520F7C415C5C44285 +AAD = A45CB5AD0CA879FAFEBCC3ADB7B521 +Tag = 4C84C202145983DE0DF3E11F22AF12E9 +Ciphertext = 5E94A4C085E776E5CF542BFC25 + +Cipher = ascon-aead128 +Key = 298580E28F13FDD3984A7F374606107E +IV = AF144EA01A65AA85D38D9BA993CB9F83 +Plaintext = 1B34CB8FFA6962A269CF68EEEF +AAD = 70311811B46B3C90D8F84D86734FFB7F +Tag = 349C8AFFA7DEAA9EC9A478E52D2D0D65 +Ciphertext = 433048DADCD5C7ECB59BB1F848 + +Cipher = ascon-aead128 +Key = 53EA0CB036050CD77AEC4489F01811A0 +IV = A09FF6218E2448ABB7286FC3ECBFE56B +Plaintext = 7EA42DA25879896E9C09321AE4 +AAD = 577DC0687D727B17B891351A4E9FD3924B +Tag = 396145D284F58ECC7E64F5E7BF6D0054 +Ciphertext = 889439BE0DF85FAED208373EC2 + +Cipher = ascon-aead128 +Key = E112CF3979080EC8867C872750047AD2 +IV = 440621D58A082E5D2F615E539A8AAF41 +Plaintext = E49CC457E3EB24695D67655D16 +AAD = 1EBEFA51AE785FCA60344CC121F1D3F10152 +Tag = F8AF5BC159711F7A700CC9A5471DA7B1 +Ciphertext = 79650009DD87650BDF2E3DC240 + +Cipher = ascon-aead128 +Key = FEB5993D5FB12B5F917F007C15D2DA79 +IV = 03FA0F5EB0FC91833B504123A4E991B1 +Plaintext = BB570E216DB0962CF43AA93091 +AAD = B126491DBECBEA560B60B0ABCDDEFD6D3596EA +Tag = 0BCAF93D7444D92FB5C7E324B4D656AF +Ciphertext = B27A455A6F5AFD2281D147601C + +Cipher = ascon-aead128 +Key = 979D4474234A44D5FFCC9D26A5F42184 +IV = B2F31A45D197C7AD5B651DEDD197D116 +Plaintext = 209D3562B3DF4AB610DE803878 +AAD = 1376BEC6763C8A019188FB696288FD8D92BB95FC +Tag = 0BED795605926CEC72B81CA6F52F51F8 +Ciphertext = 4996C87C94392F1BBE1C98F67A + +Cipher = ascon-aead128 +Key = EE50DBF76738F893ABFBB2C10EADF86B +IV = 52AF623A2C2412348E5F7F3E83195C81 +Plaintext = B0A5B478088FF9E8700087D6E1 +AAD = DF40306C0DD39568559F733EBDFBF46BDABDB9528E +Tag = C7CFF2A80966D1BB7B083705362F8D6D +Ciphertext = 6F98E4F098D0CCD84DFE9F7844 + +Cipher = ascon-aead128 +Key = 45612E06130FF9CE2991E3A51F987677 +IV = 951EF7BC243741E9633D770180389B63 +Plaintext = 6D36CE7F5A2A584555E9C05161 +AAD = F855F54FC8A638FFA9B974008644330E1B22BEC33728 +Tag = CAFCE1BB1D8BB9C6B47B998FE2955ECE +Ciphertext = BCD242F7FDF2FCD8CC69E876EA + +Cipher = ascon-aead128 +Key = 89232202D3AC96C74E1FC5F7DAF1BFD9 +IV = F3BB1DFB18729F54B4935EE08AB8481B +Plaintext = D3C0D544BF48F39466B26796C3 +AAD = 28950E81CF8DB96079A1B74A324DE262603EA1B080FDCC +Tag = 02807D33EA33A8DD964B9630CBAE9F84 +Ciphertext = BA0AD67A51E4D0A2E5F53E8298 + +Cipher = ascon-aead128 +Key = 28AAE1AE157319AF36AF721073B1B77E +IV = 3471CFD09DF005BFED68742C01226D54 +Plaintext = CAC42776B2047DCED679EDBD74 +AAD = 365FEBEE1B600E7F85935DAB8B6616DDED6DCB760A74412F +Tag = 5DB922F6B2BBB6BB3934894B92729381 +Ciphertext = 719EA926ADB7A474A72A55BC6B + +Cipher = ascon-aead128 +Key = 1724AEC8C1A86CE68E8EEB6944A7EAD3 +IV = 8776D372B151364D156B6933DAC5C2FE +Plaintext = 1E2A630F0B23E2267C6B8F9468 +AAD = CDB803D44994FAD2F234BB884B4B5E55DE1155C6BF3F7750FA +Tag = 6F78A0EDFF56A72FD8B95024172CF433 +Ciphertext = 6C4474C62957D4EA4ED31DD53D + +Cipher = ascon-aead128 +Key = 161B53C9F70F7F08984009F4C2E8CE04 +IV = 1427AADDF1FDE135FEDD25A76D9D1645 +Plaintext = 80C58CD9E2BABE3F78CEAFC8FF +AAD = CF3FA48ECA36CDB3FD524375A69C23EFCC9F2EDAC3D79C4AC5C1 +Tag = E7C122145F24396DF69CA3C4B0396BF1 +Ciphertext = 2F6E059780DD36CEDC7CD33C1F + +Cipher = ascon-aead128 +Key = DB85D897C66C2B61A845DBC758A49147 +IV = 98B72E957517CCC730A6CE7776A32177 +Plaintext = 62F507D293BBEEE09BD9814929 +AAD = 3F031BB81C08E6F4DC871EF65F3471ECE6EFF5A7F5F26489FDEC7D +Tag = D70BB8770E82B1EF1BEACE254770AE15 +Ciphertext = 45547177936D8AB9F1DC943D1B + +Cipher = ascon-aead128 +Key = FDD323684CCDC4948D4FB4C65CFEE16D +IV = 7A570D6A555FEA103DB616A495FAA6FA +Plaintext = A7B4F55EAA8260181AF509D31D +AAD = B7B98094CD2246E0B4998988715A6149A8C5E06C17A8B2BD316E9BDD +Tag = EDFEEACD8D39AA97B294917ADD7086B0 +Ciphertext = ECF5AAF0C256C6DD39F767CFC2 + +Cipher = ascon-aead128 +Key = 6A925C9D3075552C560B8BA3F5CBA807 +IV = 598FE6F5E3482EB1D44560A1150C7499 +Plaintext = E36AB627D30448913B11BE6B66 +AAD = 93D3DB207F1065716A360EF401E1ECA5CEA50B8955932A51A805918287 +Tag = FCDBA71971D3CF399A5BA0B948128815 +Ciphertext = C4D512470299F2EE59FAB90083 + +Cipher = ascon-aead128 +Key = 86F00EDACAA02947BF2A6CE065069177 +IV = B8EC80132757C3DA226C51D9C70AA866 +Plaintext = 695FD8BAD213ECE348CCF0C3AE +AAD = 18381003F19397DCB1BA5D289E74B9A43CFD9CAF6BBB9654FF53B48BC005 +Tag = 50551D63FF202AD9BC6FD3D86E5AA055 +Ciphertext = ED33FB8BC28DA6707F467DA100 + +Cipher = ascon-aead128 +Key = 79183E53F9AD0499D31F844032BDADFD +IV = 9E574D5142B5B16E1B4C13628E8D7197 +Plaintext = 0FB25C14E299EAA44C3D7B37DA +AAD = 69A2FC959E68BB684E6553CF8782BBAD63207BBC53F68CB4CDCCD38576865C +Tag = 4BA43912B7DB49BD095BA5186BD4F362 +Ciphertext = 28084C712849C1E56CE773A5DF + +Cipher = ascon-aead128 +Key = B9E06FAB9955228562CF4FFADFC84D59 +IV = EF97830C9A02E44EC9A8A659EAD73231 +Plaintext = 19C9CCFDCE700A4FE10C585642 +AAD = BE5C14A819B6824D87C1C82812EADF9D50625458069590836403A4AD9B3EFAD4 +Tag = 71C714B7BA89C4E42E5B9FCE0BEF84F0 +Ciphertext = 2408915C9FDB9F76792081BA89 + +Cipher = ascon-aead128 +Key = F2E1FBE211EE7A0E30C6B9D709674EC4 +IV = 22BF9F1AC66804C170712F2575761DDE +Plaintext = A7E5C69DB67D036C45E98C5B3C32 +AAD = +Tag = 762FE349BD240A6BCFD85A33A55C0398 +Ciphertext = D6462BE24BF6967813AFB814AF8E + +Cipher = ascon-aead128 +Key = 0BC27D94C82EEFD13114DDE06E4EA87C +IV = 58033A4DD3324DC62E88E80E5824C9B2 +Plaintext = 81FE10BC2F9894DB9A7635F4930E +AAD = F9 +Tag = 5D31B681D6C26D7A2E98178F286DDCF0 +Ciphertext = 965C9C238A7E5C3DE4B2C9ED80F9 + +Cipher = ascon-aead128 +Key = BB029FADA897F4A4A44B65E80E29DCD9 +IV = E29581B88117B4A17C9A8F83797BBB3C +Plaintext = 0B6FD24D618DBD09095B47441593 +AAD = DBB7 +Tag = 7B4C6C2E02546B5915C9310943623CA5 +Ciphertext = 384FD352983B06F7AA669CF4FC66 + +Cipher = ascon-aead128 +Key = 83D29E7D313C77071F8425DB5B8E3057 +IV = B955E8D30DEE9B693C09B537BC9CBCBE +Plaintext = 98A734D45EDAFD4DD1D62FF8A813 +AAD = C48C02 +Tag = 8477F731408568B2EF19F12F24BF5B35 +Ciphertext = A89A1C64CA7EB65AFAB249C3B262 + +Cipher = ascon-aead128 +Key = 37344AD38CC00A6A5B33D92BDA3838DB +IV = 3A763D1D38CFB4D59E063F3F5A8B6D1A +Plaintext = DED15BDB1B376A25D0B1F9984FAC +AAD = 95DCD7A8 +Tag = A42908019EEADFFF51499FEC2901EF1D +Ciphertext = 2003887D76FBA401288172B74F5B + +Cipher = ascon-aead128 +Key = 328167CAA6A9F660D660B37D5ED0185F +IV = A0B22C067C5B9EC3379685CCA1424010 +Plaintext = C267305FAE41C290D694E1916A71 +AAD = A1C4E4C006 +Tag = 24F0574FEE65A8F6DF95EB81BFDAA331 +Ciphertext = 3AAC38FE11FF789D2B528D358F90 + +Cipher = ascon-aead128 +Key = DE68FD176D74F0EE976D90B764DE6B19 +IV = A6604F7082F4294CCAE376CAC15485FD +Plaintext = 4E6385E9ACDF0C29915599AC8D1B +AAD = 251B9B19CBD7 +Tag = D8DE7A84251E49B4F0AE78736F694903 +Ciphertext = B28F907DE98D951DB3C41A7A367A + +Cipher = ascon-aead128 +Key = D7B1A5D1E30EEAEF1F2956E6FCBFF7EE +IV = 5805A0CEFA5DCCC4BC0089F586D497D2 +Plaintext = 014C426EB9EB5108737237D7A7D5 +AAD = DA3C0D2F5B06E2 +Tag = 2A22FA21A49716BD661CDA67671CDB29 +Ciphertext = 68E309C8EF090BEEA8CED48033FA + +Cipher = ascon-aead128 +Key = AF1F5966452D3790E5EB9D5C9C2BE0B2 +IV = 771ECAE36FACAFC06216D64B8F2EF85C +Plaintext = 94436E2B93714DC398274AFD3FA3 +AAD = AB60C2313A4C4FBE +Tag = 317FDF0E0AC337D3DFC2C572A2FFB200 +Ciphertext = 2847AF18BBFA2EBFBFED9C5E1FF6 + +Cipher = ascon-aead128 +Key = 549A31B430A93294177ED98861A16D51 +IV = 4EE582C74779B69ACB8A98F4100384B4 +Plaintext = D8D2D5A8C269918C08F1846A236A +AAD = E1A2209AA60CAB4C5E +Tag = 606F59302C56B4701489A9F0EB86B5DA +Ciphertext = F7F5706AC28B2F3EC6E01BC0E1E7 + +Cipher = ascon-aead128 +Key = E1D601AA0576D225D6BFE4351E2566AB +IV = 7CB5A28D88E49EDA6BB3CF9D796BDCE2 +Plaintext = 0CE62A8A15C9EB6D74536CE91AE8 +AAD = 40EE9ECD6F1F84B1AAA5 +Tag = 2C2344E61A3C91E573B977E468EF1F25 +Ciphertext = 62E2A776A6045D744EAF8F6836E3 + +Cipher = ascon-aead128 +Key = 8FD4F233F626206B9DAD46A8415DC489 +IV = 1CA1D68952FB7D707528FCFFDD59340A +Plaintext = 8B05177A19BDE15DCB8012A5E604 +AAD = F233CB8EB4B3F579847065 +Tag = 3BF0ED1BC467B6648CB093B71597AA87 +Ciphertext = 9F12BF6BC19C8DC45EAB986DD50A + +Cipher = ascon-aead128 +Key = FE13C75D4DC19340DD34FF894BC9BE17 +IV = 7946B6C464D7C35BDD1A9E6CE4C6973C +Plaintext = A5B033FFA1B2D9EF4F860E1ABBCC +AAD = 39271956763737351580A361 +Tag = EE4D17184CCD299B98B462DD8936E748 +Ciphertext = 0E265DFC328AEA4120F7D871E6EA + +Cipher = ascon-aead128 +Key = 1478C2B726A5B8AF04411D2D1149CFEA +IV = E24BE0536FFF7935CDEE4C72A4A7EFBE +Plaintext = F230D337020F9C14A7F3D272266A +AAD = 5CF7179C070F6B8E0BC3891DEF +Tag = FB23D66A055EC401563574E44DD33E49 +Ciphertext = EECAD75468B8DC23C96416615A21 + +Cipher = ascon-aead128 +Key = 0F995B3A63E2F1890E048631FA8DE6A6 +IV = D05BFEBF271925C5A80E2CF0F13B126F +Plaintext = 3E665B18DABF44D3F34527B4D4C4 +AAD = 04385C28400D37718559B48E795D +Tag = 4B00F8C6F7C4C8194F932F909499BD0F +Ciphertext = 5580B9A404FF4C50E2E73822929A + +Cipher = ascon-aead128 +Key = B29ECE620955517DAEFB67E51491D886 +IV = B93F09563C66916468E75AB412ADF99A +Plaintext = D294F9AC0CBF4E02F64AE5DDDEE4 +AAD = A97B854705FC0FFAED4C0CD5B9C126 +Tag = B2382B9C93FCE5F1C05AE424AF64CEAF +Ciphertext = 533D565136C19D281FB917EB2761 + +Cipher = ascon-aead128 +Key = C0EB1833A94ADCEE7309F638B8075D1F +IV = E64F6EBB03322ADA56F65FA56DA8A224 +Plaintext = C45FDB587BCC7F33CD020B18890A +AAD = DC3328C4449872B942CFEE381C48629A +Tag = 2A4B827F71506516D123524F75E0E679 +Ciphertext = AA06257EB83D175D36E899CA2FF6 + +Cipher = ascon-aead128 +Key = 6AC16923D4A998FB8DD8DA25C280C07C +IV = 6537AC62E287413B4D9415EACE6E9F00 +Plaintext = 9BADA78E7DC5BE04BE7B27221B68 +AAD = CF97F0A4B54E3C62C782690AD2C0ADFC37 +Tag = 708BDA915B1312C44F14E856B749895A +Ciphertext = E2D62980D3877384F69D3F6D2A29 + +Cipher = ascon-aead128 +Key = A27C9A04355010E044227F173096EB2A +IV = 02C7CD412E5E2E8C23F1D47370582B2A +Plaintext = BB8F4E88F6E29C98BF007A7C3303 +AAD = 70D6DC9AB1C5431FFA16EC144D1CEFBD4735 +Tag = 4F53F3CB09EAFD84B43A370403A6E007 +Ciphertext = 45546A707431C4D7097E0CB6864C + +Cipher = ascon-aead128 +Key = 1B38EC337E2B9F6FDB10FE6AEEEED6DF +IV = 994ADDF98DEB2045C9ABFAFCD585F880 +Plaintext = 69799A25E972DD33B421EEE276AD +AAD = 7FF776589A2164E478186DFA9C3DDDBA7B65EC +Tag = C52EBD3DD1042024F24E71E3C1757E44 +Ciphertext = 09E2C7D5E7833B750A0BA9CD1240 + +Cipher = ascon-aead128 +Key = 71B5B03BBD09CD75F7CAEAAAFA401A1E +IV = 3DAF304B3484B1E3F98555557DB95A19 +Plaintext = B5F0EC80AF9B57B297E1DF8C278A +AAD = 3F137E26C8E70E33ADF76376D7C259DF473907B7 +Tag = 8A5B9B4FA3839B23386E838167A490A8 +Ciphertext = 16E8846FE6641385DD26359B62E3 + +Cipher = ascon-aead128 +Key = B59B747C566B8EFF29943B0F8BD1894A +IV = E17CB430EBC5AB8F5AEBC9D566F20CA6 +Plaintext = AFCDB86A5476E8F4C8FED2654039 +AAD = 6B537FD019AD3B9AA58FF8808950B303EFB298257F +Tag = 16B44D664850222417227CD3606C6403 +Ciphertext = 05F2C9A5BDB6D5AF6F1D556753D6 + +Cipher = ascon-aead128 +Key = 4137094B2F5FCBD4B2DAE04BCE6626D1 +IV = 3A668140A22096881B5EF518FDF326C1 +Plaintext = A74E72430B714387F3871D24BD3E +AAD = 400DF49A06BC1E1D486984873BE9C0BCC507F3928CF0 +Tag = 425EEF0FB4D233CA23FAAE5E281732F1 +Ciphertext = 363F448D415144FB72C9266A5DF9 + +Cipher = ascon-aead128 +Key = 97A592231732C5EFFC790F5932869ECD +IV = BE7699C4FA67F9D49004C9E3208A41FF +Plaintext = 075C6D8A966153B3CA2B3BB1C046 +AAD = B5C6A93D35BBE7835DEF13174169D5F81107E8D5D26CAF +Tag = 982F5F16FBDB4732E5DAA3C2E98BC00E +Ciphertext = 6E811237798AABB16C2D5B6C8855 + +Cipher = ascon-aead128 +Key = 20385F11DEA185B0617A74693DB625B7 +IV = 9B9F21F3FE27456FF99012642365317F +Plaintext = 0186F8B21525ED64E473C9608936 +AAD = FF2958BDCEDBC2B7DD431F5DF0BCD24C108E2F99C8702F80 +Tag = 4E9DB593023DD9360FA74F93646C569F +Ciphertext = 2B5B456D750E1215628B18EA122D + +Cipher = ascon-aead128 +Key = 60E21DC5D5FC9E39EF53441C3EE93C89 +IV = D007025AA3E64901984227FF79B8BE1A +Plaintext = 10DCB9DEA476BD2B6F1743C5A83C +AAD = 41260119FCFD8BDF10A77D4A8CEA6F6BA133A4A2CE1F455577 +Tag = A21315D23A0436435F7EBC99BDA348DC +Ciphertext = 1423AA85F124807CF313F666309F + +Cipher = ascon-aead128 +Key = 997386E434EA0B3396706A8FF1B38FAD +IV = B5057F271B7258DF171D2F2F621E7C70 +Plaintext = A384198DE080220977F01B4EACF5 +AAD = B1E0D0DC66FE9E07D04AD351EA5AA38BCF3479E57B5773B34C0A +Tag = FDE43B78D54B3B6100784B002A6007EB +Ciphertext = 549EEDEFA482EFC26099F15EE68B + +Cipher = ascon-aead128 +Key = 86E45F7516DFFA4D8135BE62A6E9A0C5 +IV = AEEDF6A5A3E9EFD97175436E9A6E55D8 +Plaintext = 5C9A36546D5DE1BB1B29DEA83C96 +AAD = 553111835C6E6BBCC060A299E2C464A360AD268DA36F29948CDE3A +Tag = 129CE70961D8BD5A703794E7D25F0C83 +Ciphertext = 9B70F52CE45FA9D3D141D8376E25 + +Cipher = ascon-aead128 +Key = 5FF98ABFD4E02DB49F41BA2727680A48 +IV = 38F38D6B0AD48801B46165FC411FA950 +Plaintext = 5F09A73B87EC1CABFF5F77B2F2F6 +AAD = 2D8E5B4F4D28ABB1360C864484D1914220602C4F99F68AC69B78D7F4 +Tag = F76E68B2B76957E8BB616692BDBD2A11 +Ciphertext = 2AE5955470F4A00E35809CFBF3AF + +Cipher = ascon-aead128 +Key = 9CD933C0D6708C65372311EE3AD1C6A5 +IV = F0E06ECAFB6BAA2C652D23E988E7241A +Plaintext = 007FB8E10AB9F6642C18EB719271 +AAD = E75A553C3C00E10C93855897B46E1E28EBC437CEE48500969BBBCDCFED +Tag = 27F2D954BC97DE3A35E58196FF28569F +Ciphertext = 61FFCA021FF9B1A03A81BD12289F + +Cipher = ascon-aead128 +Key = B313CCC42DE16AEC386477967CE46D6A +IV = 5AD06D11C6DECBACB4BB17D7D7797966 +Plaintext = 365BA9D231ED18DDB638305F8F32 +AAD = 18E7E72445DE4434A4562F72EA06EB225244EC45956AE55E59EB09BDCB0A +Tag = C542BA3F4C853A53B9FA417D1D54ACDD +Ciphertext = BD972E1E0B670FAEC7B731254AFE + +Cipher = ascon-aead128 +Key = 6390CF547CCD35EE8FD484A8253DB39B +IV = F34A0B867A26B7186220593E4932F50D +Plaintext = 3D573DDEC8F15A3C7348CF0CC785 +AAD = 9474B7F3AA4522642B2B3C2B55998BFACC2CB4B4E9DF425998E93D4175989D +Tag = 6D397D9073B572635C8BF4F54023DBB3 +Ciphertext = D43EA1712282A381FC6957FBB4A2 + +Cipher = ascon-aead128 +Key = C5ABBE65588A954981A3971683184D03 +IV = 5A2361734987CB861609B45E093024B3 +Plaintext = B5D22B98FA0AE8EFC87092D9146B +AAD = 010CA42233A70E24AD946C55152CD84661C7655BF849F06302B7E0D8B88AB1E3 +Tag = BB4633D6F4ECFCAAA38127119ECF6745 +Ciphertext = 48B29C5DAF6729FAEEFB773F9B6F + +Cipher = ascon-aead128 +Key = 053E1FD09998305ED6810EC69E726516 +IV = CBBE00C808FA69028A982679491005BB +Plaintext = C1FE3AC8B482B06031B9CD3C697D16 +AAD = +Tag = 5F1661697328F9C1A99135760D8E35A7 +Ciphertext = 7B44CC00C8F1A9E47DE82BB1481583 + +Cipher = ascon-aead128 +Key = 189E59EFBA0B23E35D8F05DA1AAEBA48 +IV = C6999D9F3BC3E9A050610AFFE346A315 +Plaintext = 21E6A74AD5F1F88933C1561742C59B +AAD = 55 +Tag = 131C8983DE4EB95AAE7A15C1A58B69C6 +Ciphertext = 6BF4981B018F1A6786D5E1C118F8F1 + +Cipher = ascon-aead128 +Key = E345E7D8B7E0EB5C103A276A5847FA7F +IV = 8F54A0960C7B6D6A6E54749E4B4F6821 +Plaintext = 3A5A5AB726B8F4E37C3AEE7E32EF26 +AAD = C292 +Tag = 23B8F32599F90EF9A0CD9FBC7B264B0B +Ciphertext = 04F2B097BB89930C430693A53C2CA0 + +Cipher = ascon-aead128 +Key = 924227DCE34F5DF5603D995BADA218B2 +IV = 2F1806F2391165EACB352AAAD9ED0E0E +Plaintext = 1A898EF596DAA4848C756370C41DBC +AAD = B711E4 +Tag = BE1BBA38EB622BAEC8408E231E94A853 +Ciphertext = 4B0AE30A0AB90B63A1A78CE9A959DA + +Cipher = ascon-aead128 +Key = 94A7517DBD4AFD1369C4F9B128BB3347 +IV = 7F49695A9B6DCF1C3C243D6518619F93 +Plaintext = E3BD6A04946502A5010BB35D8C6EF0 +AAD = C28001CB +Tag = 273697F5ABC8757994532AEC7C28C135 +Ciphertext = 120ECDE98B6CAF9CDE000143FF5E33 + +Cipher = ascon-aead128 +Key = CBE347389A57BB4A1F53571CAE063E24 +IV = 0A5D5BC1254F96A6CC9C25BF07665EAB +Plaintext = BBDC07C6C62096C3F5572546DA3E23 +AAD = B60B580215 +Tag = 459E18C204391DEF39A1E037130807B2 +Ciphertext = C3F3A7FDA43A68CC0F33481CE53A32 + +Cipher = ascon-aead128 +Key = 849CE5C9CBBFBA7A2F85582687B195EE +IV = DF85A3D727B98B27BDDD886E827B748D +Plaintext = C6DC05A15D261F3BBF78A351306FE5 +AAD = 3AA1CBE3FCAD +Tag = 2A46CC0454B89B05A08F159850016147 +Ciphertext = A8C306197E8B36AF35370B6DF82950 + +Cipher = ascon-aead128 +Key = E1D731C77D148540889F0E43CC23F754 +IV = D1ACC63B74732B916A756DF780778D6E +Plaintext = A3AEDAF94233D8DDA32BBC1B0945FA +AAD = 654E5089476D10 +Tag = 0C354D9E2EE898D8D098613299AF8F61 +Ciphertext = DE69F3A41019D2D4355F955B5A3726 + +Cipher = ascon-aead128 +Key = 6DC8C1FBAEFBECAA879372E8E7CC41EC +IV = 8336F8EA696B28167D4F9F2608D6A4B5 +Plaintext = A2C26AC5773D84F1B8560E9168199B +AAD = 2C3315A9F5E4A74E +Tag = BAFCD574269CAFEA87E73516A64FF794 +Ciphertext = 296409DE5BDC1BEAAB27BF4A7F827A + +Cipher = ascon-aead128 +Key = 5F0662CFE8776F99ED5DD445F0D7BAB5 +IV = 2B033E9A5E9EB44F28E0DCF871D11EA0 +Plaintext = FAF3E66124E113CC7D3779E2CECEAD +AAD = 92887F1EEF41A32D74 +Tag = 77C38B071D5FCD97044A44C1F40CED5B +Ciphertext = 86E4794A76E4BFD54CB877CEEA2A7A + +Cipher = ascon-aead128 +Key = 00A820700A93D6AABCF11BC86BA33E85 +IV = 08C769DCDB8731226144692F9133C5D6 +Plaintext = EC9E780CD09A8D8BE4E73426547D94 +AAD = FB35691ACFFC93DAD1AF +Tag = 339392BE0176EC2D84B9EEAEB51ACB2E +Ciphertext = 910E8E34F6C8606DDAC4997512D0CF + +Cipher = ascon-aead128 +Key = EE59D294E876DB399C6B953CEE0110E7 +IV = AD5E4ED329B8C89AE7553254B6E45A4A +Plaintext = 335BF83D879EDC65CA159126317EC3 +AAD = 5F08A0FB96EACAE8DDCA02 +Tag = DC7AA000E203A6B83A432E4FE0177184 +Ciphertext = BB27D3C867A0539BAF11272EC79D39 + +Cipher = ascon-aead128 +Key = 8B861BE27B41E12E079D30BF208B501D +IV = 12A5AE219171F3464619B2AC1FB083AB +Plaintext = 807505F81649BABA57355AE6FCCC2A +AAD = 8CAAA60A3F2A9DA3AF8EC142 +Tag = 6FA5EBD67311FBF2256C84E830CBEB68 +Ciphertext = CF74F06D94B682DA20445AF04DB4E6 + +Cipher = ascon-aead128 +Key = 682EAE9E889684A4BDE34047AD1333D3 +IV = A4E8076E91952E1E56C757C4C6B02400 +Plaintext = C58731DBC7CDD9BF4CDDCBA7FB483C +AAD = 5E0B24CC5770D086C20E503BEB +Tag = A9A77074EB59190D1818D8DD10515317 +Ciphertext = 67CC9A94219B017C21D651F0A0F43A + +Cipher = ascon-aead128 +Key = FFCBA14D27BDE9479499DC26DEB1D2CC +IV = BA6D4363C464197BA7525F7F8AE050CB +Plaintext = 0CE53ABFC21582223C2FE8D7267670 +AAD = 1F9FA28B83DFF06EA6A212087EC0 +Tag = B55142D075BE85D5C975DF70828348F1 +Ciphertext = D396373E7408651244822F9FDC5D21 + +Cipher = ascon-aead128 +Key = 40D63777EA2AB592073C86E2386799A9 +IV = DB9985D4F8BC0026DAAE60079C30E5CC +Plaintext = 1C466AF24F41E7F0ED993DAB65A150 +AAD = 8DDC316F36A42AD77674FD9B22F0D0 +Tag = 9CE3E0E70110685DC8745BDC5ECA5954 +Ciphertext = A6D750A2EB14E97AD21C6102701992 + +Cipher = ascon-aead128 +Key = 209E4A88A603E63FC526BBFE3196D446 +IV = D21A86490483FD52BEAC900E84938183 +Plaintext = 23FDD9A7B9A1D38DE101EE88EA2355 +AAD = C211414796D90178E0D1E79BBC2F5055 +Tag = CC0C1B3707CF2E68E4EA5E265EE799CF +Ciphertext = 7EEEDCD02DEF6CF5C2EC61AC3DBBB7 + +Cipher = ascon-aead128 +Key = 984E2E80A2AF3031BDC9706BF4115EED +IV = 8D1DB82AD52969C3FE175330653329A4 +Plaintext = FAF3824C4FA0CE78694DD6C5AB140E +AAD = EDA4BAC2995CFB652979CBC727F4FB8BDE +Tag = 7A428B66FA550BC6D21F676B0F9CAA26 +Ciphertext = 437BFA1A5C7EF36369A6A1C24FA657 + +Cipher = ascon-aead128 +Key = 6BA09F0EA353C56A73AB578B7269BD40 +IV = CE1CA673F21146384B31E5F1F003BAF0 +Plaintext = BA412CC3AEDCD8BC8F87C6DC3807C7 +AAD = AA615D130425F8D1C1B546791BCDD7B7BCBC +Tag = 13D508BC33ACCD3DA120DEE3CCA268DD +Ciphertext = 3E8EB7772921529ABFC41AF3095253 + +Cipher = ascon-aead128 +Key = ACE5AE378DE33354584106E865408CE8 +IV = 417E8004B96128F7C4D7AB7D5CACA51D +Plaintext = 111275785BDCE35B00DB9A3B8C00B9 +AAD = 713D4823C06FB13CFBE53E78F4E157F877710B +Tag = B52FE3EC7A001EDFD7BFBABB6D3DEF24 +Ciphertext = 2C56DCC118D18249ED8D83A1517873 + +Cipher = ascon-aead128 +Key = ADE276375C1130B04A8B338EC7A92E59 +IV = 4BEAF56D96D779C5113CB770E9857A20 +Plaintext = DA5502FEFD599C800EB1EDBC72A5CA +AAD = C2D29B06FA66DB757A2AB20FCDC554B559196B25 +Tag = D0CBAF24C61ACB08484D89B1EBAF175F +Ciphertext = 3D21A4529717728F1178A0064DE2C2 + +Cipher = ascon-aead128 +Key = 77BE0426394B1EB1E9943283C8470BF2 +IV = 432413FAB3BF04BDC7FA033A83FBCAB4 +Plaintext = BC60870077196FEA9AC6C03AF8ECF9 +AAD = A02D9EBD6BF755FBE92A2FBE7B07CC68A2EAB6235C +Tag = F89DAFA82219F124B3B48036DB238AB4 +Ciphertext = 4930A63F5AAC2DA9A1B0448E7A9ABD + +Cipher = ascon-aead128 +Key = 46E484D2D0D319661554EF23F72B51E9 +IV = D10433863C46D6FD91E9054B7F2E4AC3 +Plaintext = 3CF704F46895864FE56AC1DEAE47A8 +AAD = 03FB4EEC618C8903B0CE43F0A71B3008C9B80578D873 +Tag = B6D0EB106123606C8057A0F4CA036FFD +Ciphertext = F8FDA5163C11BA62FBC8A7E3166D0F + +Cipher = ascon-aead128 +Key = EB49FE9D6425BE0CCA80D137BA97193E +IV = D671BEAC9342D702654612C87DA988A2 +Plaintext = DD672BFC5CE12C1F58033312CDB850 +AAD = E62CE79F404389214973D2F3B7AB94FE7B24DFDB33B49A +Tag = 131574BAD578A809E0078B8886065F89 +Ciphertext = 57483FBAA09876C89D5D70ADC3F4FB + +Cipher = ascon-aead128 +Key = D53168926CAA2C7ED77CD35E7C476A95 +IV = 6056196AA28E4D05856D0905A50375D0 +Plaintext = F1829E452FE247196031390FB02F96 +AAD = 46237AA269C8823E5716729368C5F5FC854EF457D12D0FE2 +Tag = 2F3641A7006E5852DD9B6D573D12512C +Ciphertext = 68A291C6BCB7A8E34736DF06F010F6 + +Cipher = ascon-aead128 +Key = 15116F9B4B9ED9659AFD4BA981098250 +IV = C00B67417BCA8EDDFC3330945481D0A5 +Plaintext = 8350CB247B896AE8260055B05B6843 +AAD = E8C50500B91E381539697111B0088929DE5EE1CA4E390E718B +Tag = 9A9E08C76C33C7C9C26540E6D63A239E +Ciphertext = 9D21AEB92657055BAB02294DBA9BDB + +Cipher = ascon-aead128 +Key = E4F3B6BE7E54142EA40F33523E92D914 +IV = 7891FF7EDB158BC1C4C8674305178859 +Plaintext = 74FD1D40BA30B13136E276A8C39018 +AAD = B0AE0098ED467658B10BDA19BB382892140CA8C48BEF84AA429C +Tag = 0E200792982D2F74C7771FCA217947FD +Ciphertext = 96E0B67F4220E8E5378F79A49B7885 + +Cipher = ascon-aead128 +Key = A79429064A9C2FEA231C070D7E40C78F +IV = D5ECF5854CFF386B11476BC6F1C0500D +Plaintext = BE5D25AEAC305DCF4CFB6B63C8476F +AAD = E0BE01944C94FCF93F6D780FC3AEACC980BA669A8B3F20C3CA38F8 +Tag = D201B77AB462F7CEBBBE664A379AEFF8 +Ciphertext = A454D9D067F43161780A954B030898 + +Cipher = ascon-aead128 +Key = BC747ECC2D78A95E40193C3E2D7467C7 +IV = 6961A3E11B3E5BA76D6CE59E6B472EE6 +Plaintext = ED169EC817AA70E3FDEFF0CCBD7B82 +AAD = 96402058C2077DBB3FC7E5AADC4DB08D0B35AFDC2E4CE17EBE4E9605 +Tag = 0D84B065F5A5CF42EE7BCF756F583610 +Ciphertext = 7951279578D2413647EE6B6CB2A117 + +Cipher = ascon-aead128 +Key = A0A1E49B981B4C7FB4D5D0C5B00A4D56 +IV = 299AF1EE827D56ECCED2F6F03DF73744 +Plaintext = 64DDDB04BEC2A9A48CBF2C0D9C10B9 +AAD = AC1EA6E8C30B0B9FC6C3F24F151F8AED53B0E1BEF431BC8B7B10E0B5CF +Tag = 10F82B321BCDC297AFDD98759DDE0290 +Ciphertext = AB27E4616B6501848C8BCB44C47668 + +Cipher = ascon-aead128 +Key = 090BBE913D5D9473B324BCCC9CFE12F4 +IV = 784DB38E3280787018FA707D5F70299A +Plaintext = E61CBD47251897E96ABBC2AB3B27BF +AAD = DFBFBAD141E87BF010BFA82D70EC5C36E995C4667B2D26D62A5404EDAD06 +Tag = 8CB468F8155299FCF8BB595F077086F6 +Ciphertext = C7D037C3A5ED3E39149169AFCE63FC + +Cipher = ascon-aead128 +Key = 5F5D998B9051212878031961867B2850 +IV = 901509EB03FCC0EC39DEC22DF90A2ECD +Plaintext = 8DD52653135B6D28FBA73FF5F0FE60 +AAD = D58A57E9327C53173DF234F8B09A8DE95389266956C14C72C0B5A32FD47CF0 +Tag = 6F605CF2AACAFD14C5B825164DC38B25 +Ciphertext = 54DB5B024F4FA5A07ACEBC31D31625 + +Cipher = ascon-aead128 +Key = DB4AF4F7B3DCC92245D25683D583035B +IV = 0C3BB09F043BE8090FC5E095B605BD96 +Plaintext = 3E8CB0EA6C0CE3FBECC1AE3A6E751D +AAD = E9CC2E253572BCCFAD7FF9BAEBA47A8CFA21478F1DF5F8BB8A24C4EC5A9CBD46 +Tag = 2AE36AAD866B38A172F075CD745F1F6A +Ciphertext = EE4C53751F3EF4CA46BFF3E9593409 + +Cipher = ascon-aead128 +Key = 2D84B171DF299FA8388FDA099AE2F4DA +IV = 143E8EA659E6D362285A9ABBEAEB0346 +Plaintext = 8BF3E7ABEC27AA9C20176F71737AE498 +AAD = +Tag = AFB27522398CBC3CED0C8977D08D020F +Ciphertext = 621D5BC95FAC07F27155723892C62430 + +Cipher = ascon-aead128 +Key = 51CC1AFCAA12A99A7CCBF2EBA247720E +IV = 503F15E5783C656DE5432ED0307C29B3 +Plaintext = 9841E33AD92E35F9317D61FBA020C272 +AAD = CB +Tag = EFA80CC52F7742B11D29E046BDFF1189 +Ciphertext = 28250A3048AA6F98FA9ACAF84F23D0AC + +Cipher = ascon-aead128 +Key = 7636446545707354A6AB4284AE3F9A81 +IV = 7CB67F8FA1949600C88D995E41C2152D +Plaintext = AD7775F2738EF2B1AEB7461E34FA2ED1 +AAD = CFEE +Tag = 4B1A0FCDB4FA6C40E548BC89FE472C83 +Ciphertext = 3C81FF7AF4228A6D84DD586D8A7BCF85 + +Cipher = ascon-aead128 +Key = 97296D20E59CC614CCBC97E62648F31A +IV = 30DBF68B6E30C618F5217F90B3CF333F +Plaintext = 72EDE943930BDD41B9AF9813B9B4140E +AAD = 2C67B4 +Tag = 37F767E53B179221377BD913BCF2FFE3 +Ciphertext = F2B89B1226EF0140490DF527BED50FB3 + +Cipher = ascon-aead128 +Key = E8DAF46165CEC6735627B2E0DA7BC4F5 +IV = 34DBB90CD5C882F0E55D6F6E3F2289C3 +Plaintext = 809C78860C77C0D86D9F128305093E8D +AAD = 4A8D7077 +Tag = 0A2A51E8089475329EEEBD00D344E383 +Ciphertext = 256052222D36A52C772214D06F124C3B + +Cipher = ascon-aead128 +Key = 18F4697BED1ED816ED29B2B2012E1AFF +IV = 330CCFAFB6070D5ED1128ABB3902245D +Plaintext = 2C7B11BDDC6A324E10618A8FF41D37A2 +AAD = A104C44795 +Tag = 01A3B9928BF123F297D81259DB1C0F16 +Ciphertext = BD68C265B954301205A17968A3CA1A2A + +Cipher = ascon-aead128 +Key = 1D6228D1F73C227DC291C64EF16659AA +IV = 005C923124D912D664E876050323C389 +Plaintext = 657091D509B83438D89D06A7A895750F +AAD = AE6585D40D5F +Tag = 36BAD6EF0F6C378BDF2E4C2FA4D5999F +Ciphertext = BA4397F71E8C60E350793800EBD1BE4C + +Cipher = ascon-aead128 +Key = A6AD1B7E736BDF6954DAB6E1DDEA839D +IV = EB232A37DBD9DAD2F3E38F9A4BCFCF53 +Plaintext = D8DC9AAD13B767B4F032044AFE9F328D +AAD = 1FF39531A4EAAE +Tag = AA129F84D9710C081F4FFBD1D272976A +Ciphertext = C49456F05BFE69D8B102F5FF45D94E05 + +Cipher = ascon-aead128 +Key = B2B033914F5A2FE1413CC83CEABDB48E +IV = E59CE311726205D5103C8872ABF25B79 +Plaintext = A90AE7F36ECA813538C34756E1629645 +AAD = C571E416CA6C7729 +Tag = B0231824AD8C6F6C48D241CA21362695 +Ciphertext = 16E0831D9734F3F104E989D40848532D + +Cipher = ascon-aead128 +Key = 3EE75C7351FF60EA8403020EDB0BED8F +IV = 8E7A7CA8174C4405EED7759F7EE81156 +Plaintext = 21BDDE7FB67DC2AC426DA528DC3731F0 +AAD = 2CB73670795B36447D +Tag = F4C04AA97556D40AE75B95BC6F3AA2CA +Ciphertext = 86311AC0CAAD92B818033F4A2B3711AF + +Cipher = ascon-aead128 +Key = 4B3C03FDD5A457535DB21A17942E3611 +IV = FC2CEE9F1206F24614E361B7D2A694A1 +Plaintext = EAA1E3F552A27289C705C5D34BCAF7FF +AAD = 2D8586676AF73E699157 +Tag = 8A6DA5759FCA2AA806AF3F59F9A963E1 +Ciphertext = 02B66ADA8A420D7C94284188B1D6C9FF + +Cipher = ascon-aead128 +Key = D0EA8BC5057D2716FA0EC24A83F63F2A +IV = 22D65FA21472462616DE06A0840E7AAD +Plaintext = E057E8A8F6D99959589F47D8D5A77397 +AAD = 66A6501C358827C863AA76 +Tag = 34CD2A5EF03DB4A0A63C818874CB3E4C +Ciphertext = 04DEC3D8DA4140530224CEBBB6722B19 + +Cipher = ascon-aead128 +Key = 9A9B4DCD9937349003565C83A2DD9BD9 +IV = DA1B8C86A7C5136536EA802A9ABDA159 +Plaintext = CF3F035413C6FAE74FCBF92E4D9A619E +AAD = 93A6CEED80E5681EF57A606B +Tag = 14472572799A39E2C6D6347E97446330 +Ciphertext = 69F81686FE148E5F0E367235F2DD3174 + +Cipher = ascon-aead128 +Key = 57E4C81FB9C384137A6B4D45657271B7 +IV = 81976176D4528C9A5908ED4C713849D2 +Plaintext = 88FB2763555F9E2DA23E81BB14142C51 +AAD = 6BDC54A413540C0C8810DDEA1F +Tag = 0A62792824D8D3DD9E47476257202E02 +Ciphertext = 6927E5775AED1069075F4702AF96E634 + +Cipher = ascon-aead128 +Key = 17EEA81B58471E13EAB730B0B41EF82E +IV = 9925F3D19E51389E648EA9FDBB242F52 +Plaintext = 4E86C527123228F54C2AFD7A58936512 +AAD = 93ED2D1498B4A6C896861B578838 +Tag = 66F09E72C934A72136779B253D2CE4FD +Ciphertext = A6B2E98291255F7F63CCFAA2505F99F3 + +Cipher = ascon-aead128 +Key = 4BD1B356039353DF431EDC3E3EAFFD35 +IV = DEF45C1C7D22AB317C8189E2D21CF81C +Plaintext = 2A3337F9509FABE8035D0C8BF4C2476A +AAD = A04828ED42A7842997100FB6F31208 +Tag = 5BE6AB2DE39C80E564FDDEE51B8D4C7E +Ciphertext = F84A9434E4A87AE81CB4865D7C4D1671 + +Cipher = ascon-aead128 +Key = 0265C9E36A9B492D2255CED710372C14 +IV = 9F77155CCEB090CAAFA56D925328BEA1 +Plaintext = BF062E78572CE9F3660D58EFA8C937A4 +AAD = 9541B5B7E0A8FD977DD11E07BE521221 +Tag = 240E1EDBD61DB3ABC421BC8E65C408F0 +Ciphertext = 9518908A6FD3F885A6AC75F1F54D9E29 + +Cipher = ascon-aead128 +Key = D41BB959E68634C75EA242496CBCE011 +IV = F8E4B8FC9AC47688B3BAEBFEB7ED5812 +Plaintext = BE6ABA0D56A9B7921CABD15041531436 +AAD = 76D527E642BAE97DAE77B3C3E24BDA0E84 +Tag = CDCFB138504EE07449618D2BDBF8207A +Ciphertext = D436D965C6EC083ED9997F3AB9D24CA8 + +Cipher = ascon-aead128 +Key = B7CDE617CB1181588A73240EE54F0AAE +IV = 075396C885DCD0367FF9C3BA113D679B +Plaintext = 7E55EBD02359BE38AC517DFA704D8142 +AAD = 30FCD6EBD6AF91059D9DA9711C200095C9DA +Tag = 7403E66F2FDBA7317BA01581BEC9045D +Ciphertext = E543912283763EEBC03F5E30CABDFEA6 + +Cipher = ascon-aead128 +Key = C8B5C56B645110DBD8AA192558AFC85D +IV = 25420089CABB20466E37225607D72DD9 +Plaintext = CA9FC80102F179833039C5AF02B404C8 +AAD = 4B9D4AD96A446FB02071121965F5C051447761 +Tag = 4830C2DB97CB32A3BA109EF871E30862 +Ciphertext = B7697D15FCA068D9D57D89E1B5377E28 + +Cipher = ascon-aead128 +Key = 3FC54517A03D5FBB2A2020D609C3A8EA +IV = DFE88B7A0183E80FB1ED993AF3761DE3 +Plaintext = 8259F3E10BEA08193A8FE50B1469449E +AAD = AC5261BD73F1007ED97B75EA3C385B16C162D2E9 +Tag = 64C7E1B51EC0F5B0C9132CA501541278 +Ciphertext = CA00BC6328A9FE7C4AFC167DA6F1425A + +Cipher = ascon-aead128 +Key = A099E57C331CD88458E38DCAAE509DAD +IV = 17713BC57DA873A0361BA7997412D977 +Plaintext = 6BB8974EDB80E6C149DD727FEC894989 +AAD = D1F7EEF03D92F33EEFE3C9D631CF5D9947C5D48272 +Tag = 834A8F71CFBC7CE2FAC3EA033B341BC3 +Ciphertext = E8EC27A05C33C483AC3B75E54F87849F + +Cipher = ascon-aead128 +Key = 4B6F05B16B51F555D54A3393D8AA158E +IV = AEB62E02BE63E8369BA7EB4C59D620EC +Plaintext = 3B14753BB34EA5D6C3068892A3832039 +AAD = ACA64AA73823DD803B2B616C03C7944AB113D6FE94B6 +Tag = 0FED827F7CBE9B14EBB7A91C81A8CF72 +Ciphertext = 6D305E8C2C2F347A78EB668D5A24D63D + +Cipher = ascon-aead128 +Key = 585465F55F35006976B35DAF2F792F1D +IV = 7CCE868D46980D33D127E9977E925EE2 +Plaintext = 3D82DDAFC6B64E309B5969DDCBD6E1FD +AAD = 6FC6FC57E990B4DC4E528DF26A41FCCE1B04375ECE34C8 +Tag = CFA5F3C035658B7703103A2A1B4BB936 +Ciphertext = 636FBBC92B9B3E3DDFB4B6A41C993441 + +Cipher = ascon-aead128 +Key = 6E66E7F042B61D8A209E56E9DC98C67E +IV = F4CC8B2B6B48DEE1E00AAD5785758DCB +Plaintext = 5C758F79FAE35C8A959936330934628F +AAD = 5AF0B8D5D56B5F367C2823F0BD9193C6FCDA4A9D7097B4E3 +Tag = C476166A7232124B7D5334E89491AD9A +Ciphertext = 29742D8F84E841DBBE7034DEA66FC133 + +Cipher = ascon-aead128 +Key = A821C0D24C76DAAA904CC48214FED265 +IV = 0A8605A55FF4D7E17A04CF0399CB72C0 +Plaintext = 8E6DB82D05FBA2F109C267BD83EA9B56 +AAD = 6BF9C13B94DBD6CCF6475DCAF36D31048E078193ABB8B52E7F +Tag = 3F0D46991488814E46B29D30B9383FC7 +Ciphertext = 50C65EA5CE96FB2AF0D24A0C223C9CB3 + +Cipher = ascon-aead128 +Key = EAD413CAED5103D0A420AAC17E4942E3 +IV = F5D25F1FD4A422C6446E549BDA253F19 +Plaintext = 1DFB4A82173C816D70E70471CFAB5331 +AAD = 0A6395741AB87DE7A41D7774A7B6524C4C0BA265C6F871EDBA75 +Tag = D59A57E3EAFBBAC2C6459EC2F341F969 +Ciphertext = 97B038D49C20343D99E2E6275E8709A8 + +Cipher = ascon-aead128 +Key = 476ABCF783188C2D827FF4D24FCA9C33 +IV = 188126FF0226D401C88F4F45CCB6B4E6 +Plaintext = 216369EDD01791C8F1310D73961F091B +AAD = 23798334123E6BEFB6FE16E16F25206AB4C94C4A809008C92790DE +Tag = 6333E272F4D77268BD82EDE0C10CB5EA +Ciphertext = 25D55C4DBA31BCD4ADB8123BF09F8B41 + +Cipher = ascon-aead128 +Key = 54DD78BCA228A5B6FF64A8F9602E4182 +IV = EAB2FE7BA0CD990A4087FB0A4D3CA7DE +Plaintext = 6152F3F88422DCFD9636CEB1F6CE58B1 +AAD = 3C68DD1CA5BAABD9DBF3FF6C19B2F43B9A1C0D42C57562F4B92CA8F9 +Tag = D6F8F3B6CC90AE1321DE20D07BE2D883 +Ciphertext = 19D0CD3A4B1C3824F27AFF759D686982 + +Cipher = ascon-aead128 +Key = 129957E8AE839164A644E99A9C942A22 +IV = 6830B298E080BE0D1B4EE347C31C06F8 +Plaintext = E7866E03D39A0F44FA19142B06DF4A20 +AAD = A5C0B4060D615507B872D880ACE702361D004FEB5319D7AAEE11B61346 +Tag = D234CEADD6F70D8B2CB69B7F11645631 +Ciphertext = 7B017177271D89C64085160D54CB9A80 + +Cipher = ascon-aead128 +Key = 756797BBEBB3F4C0387955613F930149 +IV = 4791533ADD2A7413A10E1C91AEEE5D18 +Plaintext = 58E36CE97D5DC3296D4FB448770A1FC0 +AAD = A4D99F4B304E74CDA309E2951870FF1A25CAC9F71A61E2D68524D18E4E7B +Tag = CDFEBEF2B082922BBD73AC387EBF7EB5 +Ciphertext = 2BA19CFA81B13119E6547FC3C19989A9 + +Cipher = ascon-aead128 +Key = 89B97294182549D0CE0003BEFCBE6F6E +IV = DD1F90575E52677E5079059E965D5EE1 +Plaintext = 16C1BE032D9DCFB6185D4E185E442016 +AAD = 6D2E51F164A00DF3B01C6A2A19F7B9873D1D87F029030733F719D6F7FCAB80 +Tag = D1115E8A00C74D6645C2E6DB8B70B4CB +Ciphertext = 957A6A85AD5C1186477FA3FC6FC766A8 + +Cipher = ascon-aead128 +Key = C54071DDDD9599EEC64D0C04088AEA4D +IV = 90B04BC39EB5200B3F9F2BE1255696C2 +Plaintext = 58324FD1D73A2632EC590371D5BB2860 +AAD = CC882306EAAECDAD6C271A896A3D4E4301AC26EB9B564800648811B03DB9439B +Tag = 7D7FFEBBFAE8AF21D16402D3FBFBEEC9 +Ciphertext = 1494F50002E1D6F9AA8A6407184660C1 + +Cipher = ascon-aead128 +Key = 30D0CEAF3C2A202226BF6D981DA35E70 +IV = 03C0A6DBDE2116EEC49357D6209F610E +Plaintext = E37491E09FC7F482E200F9ED111DFE21B0 +AAD = +Tag = 1D8922DA6820E38200DBCF80F7F3DB45 +Ciphertext = 0DC7C9955D44EB7F3CB465D78AF159BE26 + +Cipher = ascon-aead128 +Key = 65D92D520B4F139B18A514B76D01712F +IV = 4A5F3D56B2AE6AF2A487FDA8F2BC10AE +Plaintext = 213195E182582E3699E1EBD9072B0C98D4 +AAD = F4 +Tag = 5871E0A7E1847D607C9B664A86F5398A +Ciphertext = 7C4C2B724EEDA17E3805C7DE8CE5A324F0 + +Cipher = ascon-aead128 +Key = 29556EBCAF23AF917C9DC1909AD2630E +IV = F66F5BCDCE6E2B1BEDF8497F0AE7BB33 +Plaintext = 39751563F45DFDF16763C03803068E9A05 +AAD = EDD0 +Tag = 8EC7DE62FFA9F49EE916F1460F9BF233 +Ciphertext = CF322ED6BD7C57D295002BEA9F235C3A14 + +Cipher = ascon-aead128 +Key = 9D6946E31619C30EE8827103AD8991DC +IV = AB81830E1A0932FFA90A73A3ACDEE160 +Plaintext = CD980D48159C2F8D56446E631A36443045 +AAD = 8FCB46 +Tag = AFDDF1D6496729A01550AF4ABEC545CD +Ciphertext = 7613E6A5462BFDB743C115554B5C2A8808 + +Cipher = ascon-aead128 +Key = BD8ACF036D5C1E8F2EF909EED8B890F0 +IV = 19A72B4A58F4B8DFCD2377DE25A5D460 +Plaintext = 73793D20246093A0E971FA2B621F96E965 +AAD = 5B872741 +Tag = 318E2152249FB783DFA4CEEAAB8FD16A +Ciphertext = 0BD520600488FDFCF629629F9FA222B1EA + +Cipher = ascon-aead128 +Key = 8D6A1AAE36C2898E64725BD67DEF6058 +IV = 14915D80052A97C6B39C76690DD74827 +Plaintext = E3A2806CADE2FC3A57A18106D15CA5B711 +AAD = D2FD4D9ED2 +Tag = 92007664F886724471102DC474115E01 +Ciphertext = 53A621F35A4C31428DA937ADC295C0DE3E + +Cipher = ascon-aead128 +Key = 45A4A4F55B0D749B39299386FA4D823B +IV = 0277C1A8B446903D5A9E4212F0930299 +Plaintext = 492590EBA8266FFB4D53F90AED016D0C3C +AAD = BFF7F4DB79FA +Tag = 5E2E8F90D560AF1863017063D4127E3C +Ciphertext = 923C86D3C0D5155F1B431426B5A31AE6E9 + +Cipher = ascon-aead128 +Key = 0D753F9F0DE5C48F084877598D279A3E +IV = CA81B87D509707A443165D2625360B4F +Plaintext = 47B141DDEC5D4BF91747237DBAEC12AE9A +AAD = FFE79A5DDCCA21 +Tag = 786E017A6CEFCA04CAC798BF47825D3B +Ciphertext = A94B3519E072CED5496A13055B0E365047 + +Cipher = ascon-aead128 +Key = 706212AA6B7723D0DDFDCFFDD26DB468 +IV = 0D2D242B1BD6D332E3BC7F086FB86175 +Plaintext = A238A96BC8F48587142FC6E16841FF59B3 +AAD = AB60DEC8B6FB6242 +Tag = ACEDB264E680430D68832173D6C14E74 +Ciphertext = A9EBAD92EE77DD3A5E1BA38896F89EB6E8 + +Cipher = ascon-aead128 +Key = 44BD309FE9E953887603A643E6A5D0C4 +IV = 433681E29F6E71486A27ECA6714916D9 +Plaintext = C3C39BAC1A9A66AD0C18DA5D5B1F30D700 +AAD = 66B68B77B57036119D +Tag = 9C6B713B5449A42F2C2EFD2832E7931E +Ciphertext = EA2190790440D7D084E5D5A0595CDA724F + +Cipher = ascon-aead128 +Key = F83BD0549BB2732F20660C8A0FE83AB7 +IV = 788B9A6785B1429F9DD72B834B2C8D84 +Plaintext = 964F7C4556A15175BD143C6A0F50557643 +AAD = A582CAE357127B6C6AAE +Tag = 4E953C0C0DFC0F8D41D358BB6B8A37FB +Ciphertext = FF22F64B050F51C0BC423E7C1B96F792E3 + +Cipher = ascon-aead128 +Key = 2E4D6A82677DB9C458A997E0DF389071 +IV = 1C5ECB22FA8307B031E4EC499DE3164C +Plaintext = 8665EE986F6AE6E1A9967A26E6FEB56D53 +AAD = 9E99321C788867769D68F8 +Tag = 3B20AFED14F2E283339602F8ABF8FD8B +Ciphertext = 308AB0A6A103C709A48188AE4CBE33940D + +Cipher = ascon-aead128 +Key = 7F6122A220CD4F526F5765F0FFDDC7C6 +IV = 6DA8753A9AD679C5BD1E6465F6371C3B +Plaintext = 5070BF8D44D77713E9315C16FA96EB9F0C +AAD = 73E02DC965854A92D032F5F5 +Tag = 960C8AD943F752ACAC3DC94986D9B6BD +Ciphertext = CB060B3C7003071ED5CEDB758F77E96303 + +Cipher = ascon-aead128 +Key = B3A4DDC8719659A0E7A46EA968A5CE11 +IV = 3F58139C7BE79EBB5EE26D7600B4AC0C +Plaintext = 87FFA9C4CA081EF51CD91D733A27E98945 +AAD = B000BA32E0D8002E60915D128B +Tag = 05045F6A25FC06912135A9F4B66C5DF2 +Ciphertext = 595840819552C57EB531B1152BE27F2DCF + +Cipher = ascon-aead128 +Key = 6A4C26B5EE35E792059D3B889F7EF402 +IV = 9BE187E2B93ABB9CD42E277363367008 +Plaintext = 2A618413380C3054E4D994C1C155FD7394 +AAD = F2869F65DE572CF1A7EE716092C0 +Tag = 5B2327E5A846063E3665172DFD45E209 +Ciphertext = B82277D29E3C1E879C2D73B38C61A7C4A3 + +Cipher = ascon-aead128 +Key = C736407FC1593214007D187FB664BDCA +IV = F47C0999E41E957A3204DFFDE2175110 +Plaintext = 75EE6D5F5FEC4BF8E583E6912EFD580C2C +AAD = 5D42D6025C8937D5D34DB5DBD04DF0 +Tag = 99B282A8037CE9EDAAF4F6F0A51DDD00 +Ciphertext = 74676870FD50782039C92F5B7ECD445E80 + +Cipher = ascon-aead128 +Key = EDA7AAF524EE7872AE45E9075531D859 +IV = 5F0139D7971D4C94A0918AF53B111E2D +Plaintext = 02F04397125FFC64DCB9416F6F94C58362 +AAD = F06E859A77F330428A1B8990A3600A73 +Tag = F58D9A17EB52A8E439F189076AF21C6F +Ciphertext = 842B1C236153E6C4F2136B24981622421D + +Cipher = ascon-aead128 +Key = 8D49C7439329BAF52895036F8978D67A +IV = 1A4B22F72DFD02BD05B9D439EDBA982B +Plaintext = 83EA4E55C20D69993753E512210FCE34BE +AAD = E25B902EDA4D6ECF3AD4B7500289802407 +Tag = 2F9E75E3B53291DB234C797442498829 +Ciphertext = AF4D3B37CB5444ADE695503A9F6BF97325 + +Cipher = ascon-aead128 +Key = F649F5B8C4B3C0143471C203FE4BFFB8 +IV = 3289B8E46DE154BBBA0922327650D17A +Plaintext = C0906E02D24ADA9700250F0A0A3C85D8EA +AAD = 92ED6AEA7066E9605E8DF1D22F73A2839D80 +Tag = 10813E66F4352338225573BD121FD102 +Ciphertext = 5A46B1738DDB16358EBCE52AB8D84B0F00 + +Cipher = ascon-aead128 +Key = E3B945354519FFD479D56280838352F6 +IV = BDB715A73303B214F47D64B80E779E32 +Plaintext = A506488FC08A2803E7F1FBFAC419D45564 +AAD = 03004544E4F2EA6CAA178F632422F30A0829B0 +Tag = 6D30739EC65387EA0832AC7411D06230 +Ciphertext = 0CC307E770D86912334F4ABEB965B86BB4 + +Cipher = ascon-aead128 +Key = 54FE703F9401BB470796179BA63ABAE0 +IV = F67DFBFCAF6ECFD64055A3E533E2DB10 +Plaintext = 87A4ABEC9E184A081844AF23D4DA67B8C5 +AAD = 8E58DAE17AA78919358D87D58C8F29F91125F330 +Tag = 593B7763E1FC9E962BD718D52108F20A +Ciphertext = F25660CEEEF101C829014A56AA4094D60D + +Cipher = ascon-aead128 +Key = 09EB8BBB24E36DC00472AE445A0923FD +IV = 3054DB421398C37EC77696DD8BDAB6A9 +Plaintext = 52F2C3A7FA16029EA3771245F2785B8DC9 +AAD = DDC65867DD338DF5EC5F70CFAFE6909B835B3A827B +Tag = 701DB1BD93F8FE463B62330C4EAD3D86 +Ciphertext = 2475590AD6460CBAA8321031D8C8848D59 + +Cipher = ascon-aead128 +Key = 216B47067C7E2649F41E78874E734715 +IV = 5FE7F07EE5BCDA35406C459EEDEE51CA +Plaintext = CE8AE42D399F9EAA48E8C0931B3B0967C0 +AAD = BC9E765E9DAE2C6F64A7044B26FC0307AED4B6BBA4B5 +Tag = 23CE2A04B4AE780E76E5E4AEAF9A4CDF +Ciphertext = 42F0278CD466AD526FD49B9B4B52953583 + +Cipher = ascon-aead128 +Key = 41BB41A75C7F0AA674B4593F8E606633 +IV = 1C399DB6BAFBFA753B57838C3C6AD292 +Plaintext = 295DB196C538F00C0FDA4C98FAB7A6A6A4 +AAD = 03C1B4E88BE5BD7C8D95ECCD5CC4D6D9E2B0EAAB84AC31 +Tag = 2D97EDC5EC66B9877AAC43D3C24E158E +Ciphertext = 1A9355AC4FD57C97FCFB3C88FC8A23160E + +Cipher = ascon-aead128 +Key = 93FF2480410BAF6AD372A3D610D6C63F +IV = B089EFE1616A785F8092176EB3CB25DC +Plaintext = 404B67A64D081C8C6FC4F8DABF9C27503C +AAD = 37C9EA5EB1AD691752F1FCF4337FD31E43E56D5C310F05A0 +Tag = 7A7F729A61DF9FC8B7E15EB3A93C9940 +Ciphertext = 19E296A2B99DC2150CDFC8F1FDD6604025 + +Cipher = ascon-aead128 +Key = 5FA43C7B6446E74CEEF55ADB87E38926 +IV = 4997F35506B760B85999085C846EB874 +Plaintext = 25A25383BA7E953CB73F133969D9FC4BB6 +AAD = CECEDC53EFC478EF4A9BA57B93A2548ADC0437596D4F067E95 +Tag = 0277990F4A7D613FE1663767ECFE4EEB +Ciphertext = 4DDAD4D5F5CFEA23AC6F7CA31FE42B96C9 + +Cipher = ascon-aead128 +Key = 1C935D5C1CC794F78A7C412BD8FFB165 +IV = BE8DC2F290C3AA4E9DB9637B89F8BE8E +Plaintext = DE5028EFB959ACE605D7577C4A7FCF855E +AAD = FADBCF65FF8CA547B3D4B84A10FEF495782EDA37C2E79A7AD8DD +Tag = DF8EA8496F53765129C8C26CB099CFC4 +Ciphertext = 38855C47A93469D003FED589230DD24074 + +Cipher = ascon-aead128 +Key = E4B435CDB27B679E345760B60890BB68 +IV = 4561B0C1F6A2034C2E3777304E505606 +Plaintext = 58275550B43A601EC520A8465EF2FE0F8B +AAD = 33769F781CC9B8A6F9C8B58D75E44B8C8D9D097396E7B8397376C5 +Tag = 8C69743539AB576CED5F7B615218150D +Ciphertext = 06D9FCA5BBE6DEB27BDC6E481785E7DECD + +Cipher = ascon-aead128 +Key = A1725605E03ACE5B85522E0CCD19AF0B +IV = D6EF1960B7E65520E873BF27CB4A28BE +Plaintext = FCBDD69875CE42858A2575E67B58390244 +AAD = E507E7AAB66B3DB2C0DFAA611A9874D7D45EEDFE50FB3AA571A1B0D2 +Tag = EB5B780B697276EB9EDCDA8242201303 +Ciphertext = 726175357408101F825F58286F41F29234 + +Cipher = ascon-aead128 +Key = C8B7B12F11946354A07A5AF71E902A00 +IV = CC4370B3E5EAFD6F13AB5F18C5DDC490 +Plaintext = CD50A5008F816890F057556DC35E252448 +AAD = D2B424C3B8E87ED9B84AA348CB474D97F3EF652F2C2618417E96DEB4EF +Tag = A0127F88F4784A760E3F52352A0F0E24 +Ciphertext = 493069AD35A13A98853654C5E1F2D24537 + +Cipher = ascon-aead128 +Key = 9853F9AD65522CD5567981120DF68A6B +IV = 7588EE201B5E5C36F234C6E3FB30B6ED +Plaintext = 77E0C623B84927E7B307A2FA011C2CC30B +AAD = 6F5CB83E04F02C47B8912F27BF93D57BD92BDFFBE852B84A830DF92D8D1B +Tag = 23091AAE15F5855A882C3FF4A2A0FBCC +Ciphertext = B43B92E9EC1BD4C35AB284D65CC7C3D3F1 + +Cipher = ascon-aead128 +Key = 3524564CD8140C1B43F1B7914E9F9C5B +IV = 7833EC8363654BF71DDAABC4656A338B +Plaintext = 7D53DBEA82CA4F5C10BA58B4FC7F3EA99F +AAD = 7BB82084319137D780AA301A07751E42D62F580AE7309CBE93E9ED1624FDB9 +Tag = AF9A00F17EAD78500C9145E7094BA35C +Ciphertext = 196350C60CE7703CF6DD9C064E632BCA36 + +Cipher = ascon-aead128 +Key = 3F8A5EBBC057CDFD3BD5D2053D2AA33A +IV = 62C1289628E8EDAD791D9973CC4853EA +Plaintext = CD3A8F65E15CB41EF6BA776B43F5FA2F2B +AAD = CA9400CA95980F787A1DE9431BF44AB6F4B54AAF3728218F5C6AA8378E30F7AD +Tag = 6A40CBDD3DDE0922FFCACDEFCA5ECD6B +Ciphertext = 45777EAA304460E3A0F69D6F073B584A14 + +Cipher = ascon-aead128 +Key = 146835D2B9892C255822227B8EE37F0E +IV = 08386E874FB86F3B1D4C1DAE26B45FE5 +Plaintext = 43F3AA6FCA6084BB65B9AC56CC68ADE0B8B0 +AAD = +Tag = E4E62FE04E2528A0F9FDD6E3DBAA40C3 +Ciphertext = B8ECDB7CA8B771D33E8E79C11D154EDB5F78 + +Cipher = ascon-aead128 +Key = 946C87C41B6893953199866D8EF68002 +IV = 08FF6B0A030B5435F22B3F2F7E88405C +Plaintext = 35CBD81E2329050C0952B8AAAC5CBB47E60B +AAD = 64 +Tag = 9112CCE4068FA6C8406B82917489014F +Ciphertext = 34C05F79ABCD64BBC3B30FD0C4ABA085AFEA + +Cipher = ascon-aead128 +Key = 7A312879401783E280CFDB370DF34E8C +IV = F408ACA13AB6C1C9FB226E5034E7EDD0 +Plaintext = 9FECF85EB5FDE84F5428962AEB908F25F157 +AAD = 8310 +Tag = C53B209956698FE374A0AEFFE88D380B +Ciphertext = 3DB6A6AECE1001D0249595B7B8BCA69EF673 + +Cipher = ascon-aead128 +Key = D40808525B24AE1584CF797708B7EEEE +IV = 090EEC869759E0394D228892C3821DAC +Plaintext = 420A5A6F62A5BEB5F99E2F38E324E8263450 +AAD = 1037E7 +Tag = FF37F4288F8B2816E19DD7FE0F91C6C0 +Ciphertext = F9BA2898075AE48035D3D39EE5EE6769CA02 + +Cipher = ascon-aead128 +Key = 8B15BCD9C2C1B2805B8EBF6DEB1F7B7B +IV = 85A723D16610274960F7761F5646E40E +Plaintext = 1AF1DC3A6FC0AC8ABE2332B2A7B30A3FB7AB +AAD = D1ADF73F +Tag = 03F1F78ACB759C5480DDB87C6E90EC2C +Ciphertext = 4D8153B8911F77D78D7E4B770D2C303A4DE9 + +Cipher = ascon-aead128 +Key = E240D5CECC7A1E55B0F27305696B4F1F +IV = 779AB3B97C5551213FF8E6138208221A +Plaintext = 053CB3D7AE7FB4CDEB33B04D6A649D3405E2 +AAD = C5FF5644E5 +Tag = 3B4B876D05FCC238406610ED2B054FA8 +Ciphertext = 1B7FC7417080A6461E10AFC29CBE39376121 + +Cipher = ascon-aead128 +Key = BE9A7BCC62917AB3557488C62B52E2E7 +IV = F9AE2350E204630EF9D0D34DA5972D71 +Plaintext = 6A958E0DFC38F3766D61B33EA28B888F5AFE +AAD = 76CB80CD8367 +Tag = 264A52C9AC27386A3EFBEE2D137A1843 +Ciphertext = F79368F8770409AD84A741020218012334F9 + +Cipher = ascon-aead128 +Key = A113B7B13498385C170CCBA88B586C14 +IV = 01FA6300145C1FF22CC19F8942993D39 +Plaintext = 7B935E7FA05058714F9C6602641C32603728 +AAD = 1B9742AAA0F1B6 +Tag = 49982CCC9D33D2EB5BEE7D35D386CE42 +Ciphertext = 8C875EC8601B6447087197EC950C4A36D883 + +Cipher = ascon-aead128 +Key = 08CBDFA6E9C2DDE901716A43B21EEDEC +IV = 7F52FBFD65CABA2E328ABB09FFA50399 +Plaintext = D2D5AA0342D164237FE833565AE0137A544C +AAD = 54611D486F4F793C +Tag = 274E77DA816A753210752D84EE612AE3 +Ciphertext = CED923C750F5ED46A9837FCDB38F0D2EDD74 + +Cipher = ascon-aead128 +Key = 68CB59BAE1A4DB631FC194E948F5FFB7 +IV = 57E21C61AA70802245C9DE95C1A732B2 +Plaintext = A50E218A582CFCE85967FB13032AEA5A4E12 +AAD = 0261099F131A00AE90 +Tag = BFBC3A2246D9865DFE9B1316BC78A049 +Ciphertext = A4AFADF6666EBCE91053F49CB90CD2E0D091 + +Cipher = ascon-aead128 +Key = 9450B53EA97F393E9CCF710D640B3AB0 +IV = EA8992790F5941A2E55E0327908A77E6 +Plaintext = CE088B508452285C4BD2E88E1EB749D1467F +AAD = 2654CD85F9DDB5FAB03F +Tag = 57B42E8787DD1E713AF82205AA68CB1B +Ciphertext = AF0254669A96E3BD2008147D7A5D7D63A762 + +Cipher = ascon-aead128 +Key = 77B4E5689EC591A6A242261A7595EE6E +IV = 4B3812B7C45C798807D050C75677FCFA +Plaintext = 1B49E5826E11791BAC336B734A8F90A08488 +AAD = 36894439FA65DC9320F8A7 +Tag = 71B8D5A54BAA22DABA3C200332BB07C4 +Ciphertext = 300BBB3E2909EE665F405EC5A133B3EDA96E + +Cipher = ascon-aead128 +Key = 78507DE2A8CE71184B1AF77A7E8A58D6 +IV = 713B844A42DB5EACC0E8D84EEE1562BB +Plaintext = 6AAC89C2F0AE7E4552C0FE24FBA4E1050581 +AAD = 246296C9B53D833850DFD7A7 +Tag = 99DDD16AA15367A366293743BFC06338 +Ciphertext = 29BD31BD2C72BD78479C7816D3E963DFFB09 + +Cipher = ascon-aead128 +Key = B2C29EED7C234F3690EE73E871473D90 +IV = 764D7923F6DB05CFDCB5CA22F11C7BC3 +Plaintext = DB8480ECAA2BAF5D80602CC84D95A2643879 +AAD = 5A77D20F7F563DE21D8826EDC2 +Tag = 843147ACE4DBB75217AE5B0405B8AD35 +Ciphertext = 50414EED4FAD84A9A29954374DA9C75C2A4F + +Cipher = ascon-aead128 +Key = B6C8DF612D155F5AC93E3DE10C6E742D +IV = F63751A8CFA51D0761D5B2CA0541D046 +Plaintext = A6399D2F5FF601247AF37FE8CBE0DF5E16E8 +AAD = F6EF6576608EBC64CB7B52EB679D +Tag = DBFA8DBF5943421751F246F1D645BF44 +Ciphertext = 46226A491AACD1A258CB23C7B39BB0CF20CF + +Cipher = ascon-aead128 +Key = 1B3B3929274B30BFB3C3F7D8EBD61E94 +IV = 607FB05BF32545003FDAE76EDD27DFFC +Plaintext = 35E71DB9753D61C4CBA079BEA558692F613F +AAD = 1D394687C0D2EC2435B28C4756BDE9 +Tag = 865BB80CBB63E5651E56708ABB2145EE +Ciphertext = 3E3D09371268D9A7F003F7F22C8ACE4E33EE + +Cipher = ascon-aead128 +Key = 76DC644B520EC85B5CFA8750712C3D54 +IV = E4C92065C7F5C862894BE1F3F3E4FB67 +Plaintext = 538CB410B3771A5E18F699FE7DEDD45E64FC +AAD = A076DDAA3C5EA4273D105E42F66D22A3 +Tag = EF43C1B4F8837F0CAD389770EBB712FB +Ciphertext = 6405AC83533E9561A9A3F559511E08CEE660 + +Cipher = ascon-aead128 +Key = C1F3B56B8CF3D01B5C4943634F605797 +IV = 875BF732541859DF908F937A3DB6B05E +Plaintext = 2ED4AFD3CAEDD387AE0AC0C4DAF6463B3068 +AAD = 5E99337B40CD25BBE74ECF27EF7A0246B8 +Tag = A9603FDB9FF428A2587418FB7D691F24 +Ciphertext = 4E113C819045446949C4695A320BFD3E49D5 + +Cipher = ascon-aead128 +Key = 8A4924657E06C69F051904BB0A8F27E2 +IV = A0B3D5C2C7D3668A58AAACA712B797FC +Plaintext = 334F559FC082C14438280EED6C8C22E73240 +AAD = 4C074E6A32A009422CD2CC825DCD11B2C5E2 +Tag = 11F55A25029E11CE46E75A8FF777BF6C +Ciphertext = 54BDDF317B3DFD699ECE25E93B02162A3881 + +Cipher = ascon-aead128 +Key = 9BE71826C464F141CBBD586167D51672 +IV = 52EB946AA95F4CF858BC53CA63F48CC5 +Plaintext = 5E6A6EB49782DB0DE9909AFD95BA9B1560A2 +AAD = 5A1D9E629B837718306B2151EDBB167891B312 +Tag = B656B454E962F9EFC3AA8255D9448916 +Ciphertext = 7829C26985F7251FD4B793C311181DC34C5E + +Cipher = ascon-aead128 +Key = 72BA019B38FCDABB90310BEAA5361643 +IV = C1AB48D280125566A540974695DADDE0 +Plaintext = 6FC26A152C3D17DBED1CBE117AD75FB4DAA7 +AAD = 8D52479DDD69ECA7801E66263D1202EB8F9923E0 +Tag = 9EACED14BDCC515DCF7F143A9E79D2E5 +Ciphertext = F3AC14E88CF51D856E8621324FDFE919BEB6 + +Cipher = ascon-aead128 +Key = 32FDE0161A62495DBBE5561650149966 +IV = 0E21CD0B9772DE6E2E625A7FE95AFB58 +Plaintext = 978A78ECDBD701B45D1C4374D464580B7E78 +AAD = 18F8B0C9611D79766C374649A538D5B5C86302151C +Tag = 6CCE458D2746ADF274583B537A8935C8 +Ciphertext = 22F647EF5B53A879258D45E5D489DFD9401E + +Cipher = ascon-aead128 +Key = 962E8AA47C97EFE3AE6046F11D6DEBD9 +IV = 36DCCB67E95EB21F02D120B7DAAADFD4 +Plaintext = 3BDDDF819FA36F826F0E1632CF0BC0E1A320 +AAD = 9F5884DEA2ED2B093FABBF31B44D5AECA8B0D6DC6A72 +Tag = A0A7B0AB3DBA9D02D4FCFCA96AF3B438 +Ciphertext = 3A7668C9703C180618ABF74102584FEA0737 + +Cipher = ascon-aead128 +Key = 0DE62B11D693A70C48E78A2C0CAC0B67 +IV = 9377F3DA97CF91F34644889D9EA1DCB9 +Plaintext = D33A5400D661CB84D04BE83C80BA5FFA0199 +AAD = EA3036C13468ED314FD14DF8D18A9C2E2D128D62F20AA3 +Tag = 0240D5F54A236E6551885B97329DAB05 +Ciphertext = D51A2709C7B207EAD9772BC4B5693DBE4E1F + +Cipher = ascon-aead128 +Key = E18F71F4AA513BC9BEF16F89E230F974 +IV = 6969BF1B02C1CE500D7B54E584B41AFB +Plaintext = 4F098CAACD443C0A58F44D7C7D234087A3ED +AAD = 1FA36AD4F4EDBA7FAD29BEF7992BA635B9D1F6C4B954FA34 +Tag = 1EE828F6443E227325688839E0EBE032 +Ciphertext = 2DC72AB8C18E613FE2D248C5B4FA37C0199D + +Cipher = ascon-aead128 +Key = B051E7236792249C7F71C8538DE66A33 +IV = F85D43B8334A6DE22F69C99517B46C86 +Plaintext = 2A6BD2339971220E8C5E24C678C92E8E0F79 +AAD = 3C89370686C023607EEB6128C10917B8274F7C2BE361920CEF +Tag = E82CFC47C4AB49337BC2F2BC32BEE1E8 +Ciphertext = 47CC60DF07EA3A0391DDC3FDB7C636A5DEDE + +Cipher = ascon-aead128 +Key = 109D178C9875B429672E6896490BCB05 +IV = FC7B4E26EB3DF5F8D57AFD7D2678E14B +Plaintext = 85D7527E28729DD7C08051971103A3D9E68F +AAD = 123013D4D3C43CF3E50B6DE776BDE6E17483FC049C96144A829D +Tag = F7A13BFFAB90F66C4292F64746BAC25D +Ciphertext = 018567082059476E78F21209E73856BB7DE1 + +Cipher = ascon-aead128 +Key = CE50512D3202D5CAEE9BE093E2F43B0D +IV = AF0CFFCE4D5D55A7ED9534460B71BFD0 +Plaintext = C4AF5BF2AA1B62834D4C0D5620A1D2B11C51 +AAD = 4877C83C40AF8614C022C854AA5BBA0FF0F283945BC2CFE23A4D6B +Tag = 0ECFB799801E97B04F0BBAE30B2650CA +Ciphertext = A77250187C61B01FF759F5B0A9DC8FC420CF + +Cipher = ascon-aead128 +Key = 4B9C562363B2DE474DF4FDAEAF832C10 +IV = 46594B192D342C7216AA8FFE57F19725 +Plaintext = 3C138ECDFA141BEC61CB46067E517438CB3F +AAD = 3EC3FCAB6756DD326806992014E7876883E8C410C6216AE7F829ABE2 +Tag = 94208BC2857ED2028C2FA9D73791AFAD +Ciphertext = F76EA4A4A8C28E8155E421719827A7E3B3B8 + +Cipher = ascon-aead128 +Key = 82F93A559B90698DC510B23665C1E640 +IV = ABFD1AF90410FB5DC3E803AAC14EFAC9 +Plaintext = 8506320F2B5CC35F3A3FCA2E1A338348EE88 +AAD = 2059A453DD35586D582D8F067BCEBE90F8516712D0E2CCED7D547BCFAD +Tag = A5AC2929BC7DDAC2598A58152EECBCEB +Ciphertext = 22F0E2F13D39A86D7AB1283DA4F635046260 + +Cipher = ascon-aead128 +Key = 78C353C1915E65935684AF266EAB46A2 +IV = B7D9DC4014552AE626D2B74A2BEFB8BF +Plaintext = 65EFFAE2863A1B92DF3D465DC2A0E7D730DB +AAD = CBBDCBC94144D9C6D705DF61184DD5EDCEC4FFBA5998F24B622A5E49E106 +Tag = 764B5863B43F8977034357CBDF598DA7 +Ciphertext = 7104EB571E8C81CDB5120A245824C2627A75 + +Cipher = ascon-aead128 +Key = 7B539D8032A9535FE42DC6FD6E03920A +IV = FB3EE819DDC3761D7F83B44545DF20AE +Plaintext = 616B8284CB539CABD7D17436AA207B33F474 +AAD = E5FF2A8E19AF89D6908F3ACFD15B10BE953473EF773B8BD6F80EFE89D34E70 +Tag = 29BA832151253831531E099A0324DEDA +Ciphertext = DB844231FB8416D2488B4BD58C91FD24320E + +Cipher = ascon-aead128 +Key = 64FAB0957B83BF20B632A72B496C66EF +IV = E1562F7A70A27B702EB85AD7AE3A5351 +Plaintext = 0BF5FC17E7B5539FDCB715EBFB279884B52C +AAD = 1290225C0F7BF4FE6140469FF7785CED8134D5D40E4FE1B4F5B0E7C6D55F6263 +Tag = EC937168901018356144594F2E10DC1D +Ciphertext = A5D09437ADBCB0E66A83E95B013696DB54B4 + +Cipher = ascon-aead128 +Key = 2AA4922C768E016F95F042BE2C8B5638 +IV = C943F06C3A6D4E9C9FB23CF2D87D079C +Plaintext = 52666CDA092EE549783F0FCA4F72F0F7833BBD +AAD = +Tag = B6A5347B28BA8F648EDDF0F7D2C3EAD9 +Ciphertext = 6342DAA84D334A6892AFA5D4365DD65EB17510 + +Cipher = ascon-aead128 +Key = 5B203DAC9AD46AB4583C7B7C5B093FB1 +IV = EC4E0066BABB462721D340AF699F8F30 +Plaintext = 0E6496C65766A4AE5E423BDA85532164000B9E +AAD = 5C +Tag = 293C7DEA2F68F62AE679A46ECE790EEA +Ciphertext = 465CC660C097035821D4DC06361B1FD93E5FA7 + +Cipher = ascon-aead128 +Key = 0CCB29CE32BBBAE772DA4FDC4DDDAFDC +IV = 292A5B7E744317D13E5ADFBE1EE8E2BA +Plaintext = BB802047E35E762F9B7D24C872C93D0F083590 +AAD = B34D +Tag = 262A766C2DABECF1B5A04B06EDDC5A97 +Ciphertext = 79852D20D951952E8F9AD3CC0FE2E5FDCA0CEE + +Cipher = ascon-aead128 +Key = E83A3DE8DB68417CF18414950F34A241 +IV = 83DAB6F5EB43FC78D9412EC8EC4928AB +Plaintext = 3BE462B14E33B431F9AFEA50E549E00C924196 +AAD = E3D1F1 +Tag = 8D19CC7651CBF9F8F43C07884254E55C +Ciphertext = 3B404BA762B0C6EB187AFEED64430C386042EE + +Cipher = ascon-aead128 +Key = 2FC956EEC03F7C9A79680CC6AF398261 +IV = EEA9F62B086BE479FFF0E92349085720 +Plaintext = 0614BB0C642602ED6480BA2F7DF0CBB54F746B +AAD = FE88477F +Tag = 4EABA6CB11DC3F38BFD6FDFF5584F953 +Ciphertext = 9985B55CB04B7C2A71ECC541D3157444E4FC42 + +Cipher = ascon-aead128 +Key = 92B683780FA519CE33D37A3073223E26 +IV = 7317E60DCE6F7D1FA08667D082EC856D +Plaintext = 518CB24D86586739D8DC3AD7FD3241B19ED289 +AAD = 4ECD1F3F36 +Tag = 5C49CC37AC4C2D0E5C8D40455043B33A +Ciphertext = B8C02EB3BDBAC84C70CDABE130D7256B6F396A + +Cipher = ascon-aead128 +Key = CE43CBAECF21CE89E28945D6F1F6649E +IV = C7EB4F7D71DC34C10C401407222E03F9 +Plaintext = EB2F59C521DE0E4B6A8BE6EBD45CCC2192BE67 +AAD = 56D15786B514 +Tag = E425ADEB231466CD74779476E25A68E3 +Ciphertext = A718E2028BD5AB0E155DD18B4C145E42B3B173 + +Cipher = ascon-aead128 +Key = 240767E74242D10324C522C5DAC56D90 +IV = 95B8EC2E7360722FCF07F0F76B4BDF7E +Plaintext = 099CCA8F8432D5C12F1F2098142FCDB225E5DE +AAD = 22CBDD7DB3CED6 +Tag = 28D4BF9DC746FEFDCC3523837C52897B +Ciphertext = 94A4998FBDEF958DF8F1FEAD584731C6660448 + +Cipher = ascon-aead128 +Key = 4A54A90707AB6262A35430F19B1934F3 +IV = DF59BF2D9C7C531382778CC0AE34765E +Plaintext = 6F8081D752C5FDB7813D6051644F47E2A8FB56 +AAD = 5D0B7EAAF2623C4A +Tag = 1B65A72B1EE25E895DB5C7D22BC4AA01 +Ciphertext = 7A41B818B94FA5E3D1BB0B27C4ACA8D9D8DE89 + +Cipher = ascon-aead128 +Key = 58557CAE544D1675EBF8C0CE7AEFE0FB +IV = D26A7474B4C20CFBDA59D55DC0448074 +Plaintext = 819BA213151909975C4F01645F3B8BA2FD939E +AAD = D6E9880C88E4C700E8 +Tag = 93932E831433D431FFF687E673E59D83 +Ciphertext = 74839026A2B0BA04A1C7A03FE23DF6BD368096 + +Cipher = ascon-aead128 +Key = E3743F276306DC856E93442E2043CCFF +IV = 787C496385B72C6E99FABF4720C5D5B8 +Plaintext = ED4FD90220E1CE2ABBDDC36F2362F5681E6A65 +AAD = F6DF9042341EE76A2C3F +Tag = F8283F626DD54984B1405C7DB6396382 +Ciphertext = 68748B68664F426A20085614C31DC6CBDE45FB + +Cipher = ascon-aead128 +Key = 5DFEC0CB820BA4B07DFF8EF256826AF8 +IV = C87B835BDE6E9DE3F75B4660B851B01B +Plaintext = 39BD6A036EDC8591A74C60F207161FB0656CB9 +AAD = 7D2357A1ADF71A2ECF69E1 +Tag = 1333BF3EAD8500B1CD7BA9D61CC12229 +Ciphertext = D06F64E931643225DF42A60E51C2A8EED47E95 + +Cipher = ascon-aead128 +Key = C53E822D436B892177E3E96709F8507A +IV = 8C0095B44215CCA4C1DB0F2547862944 +Plaintext = 8B16D68E9FAF2CD891A7987D8589298F909E1B +AAD = B81853FBEC4E1CD6FAD69275 +Tag = 225D493B5D08B42CFB31027F4C2B90A5 +Ciphertext = 9D9B431C95366E8A89F668F7EEC223E83C23B2 + +Cipher = ascon-aead128 +Key = A2907242BE5D2EF308503A084BC1A55A +IV = 894FAF4187D0FD3B61C55C3E2BC6BA87 +Plaintext = D35E41D8C2ADA8F2AF7D5B6CD942F220768912 +AAD = EE8DA3A22DB3423E4F9F48FF5B +Tag = 72F1BA3CCAE6BE6808A7CB8243E62273 +Ciphertext = D9A6CAB3536E824492EA9794616AA7C7754075 + +Cipher = ascon-aead128 +Key = 28F306F151F801D1836681ECE18E39B2 +IV = C4B687D7DC2793772827694F09F06E15 +Plaintext = 2E07EA3293CF59FE99C6B7756415819C861B74 +AAD = 79C679A1E70A5A6AE53E820080D4 +Tag = 640C70A98B26ED643D8D392FD34A57D1 +Ciphertext = DCFDE5222BC76481042512944C749ABBD2C604 + +Cipher = ascon-aead128 +Key = B84CDC71A9FFC160BDFB1604BF3CC5A3 +IV = 61CDE17E59EB163DAA19388FB961A72A +Plaintext = 103AEB2E2236BBBAE3D13D1AC0CEEFC9D55D92 +AAD = 5D34B39D115FA78AAA8C175417E4DC +Tag = 03C5B0510DBE72C20CF24CBC6B9333D5 +Ciphertext = 30B33820B05C0F359FB97DC7E51D34B75798ED + +Cipher = ascon-aead128 +Key = 11FE97D7DBB214EBF8C7887525B64F67 +IV = 3025F9C6F2C00D62F16B5BC3AA7AD6BE +Plaintext = E790555E595DF89863FAEDF076D292DE396A6B +AAD = D6A4FE7BEC0D32896B2EAC6496D92B0D +Tag = BF69AC9067A051C4EE12DB0A6962209C +Ciphertext = 4808544C142B1332CE74C0E9EF65B61AA7914D + +Cipher = ascon-aead128 +Key = 289231A79909EB756BBFB5E04E7C239A +IV = AA7E09C889BC8EC3594D5E02BE3A21E8 +Plaintext = DC14A28FF497FBF2FD7183A4645C403CCF7859 +AAD = 94399BDD9D2B3F57778A8F98B664396D31 +Tag = A739C64235B5EE49A8B3CA9B5CE55458 +Ciphertext = 3ED09415C43F9E34E6B8B64144EA626808D061 + +Cipher = ascon-aead128 +Key = 5E13FCE3888EF3189910C1658E958880 +IV = CD8895CDD1892F81FAAF04632C6C258E +Plaintext = 1C7EDA41CFDC517A4D8F079822C35ED262EB66 +AAD = AB6F6D835324009534F7FF55A5E1F757D114 +Tag = 915C09C8B5B7203017EAA1F0734AC10D +Ciphertext = C912E548771CF05B845BCB69581B6728772333 + +Cipher = ascon-aead128 +Key = 20581D5494D1DA2506AC07947305C081 +IV = CD93E4F469CFD224E3D46D3E36D395E3 +Plaintext = 12535B346F192C747BCA78A51F1D4690B0C895 +AAD = FFEA32CFE49893D13CA6BBFC18C1AA4F4B5A05 +Tag = F35B60CCEE3277D8C51BACC744DF4991 +Ciphertext = 225BEC7ADFB780A54C97DA2CD5548CA19E1C28 + +Cipher = ascon-aead128 +Key = 8D6EE588EC213AE7CA031470EC4D11E1 +IV = BDECB27A5D950E642E04D1CF660C281C +Plaintext = 1F3A1B57C5BC505F850D547EB1CA6BAD3CE695 +AAD = 2E2ABC76E1828D594D082A2D327FBA224138A99A +Tag = 46BB136F6A030995088529D964C6C0C7 +Ciphertext = 4AF35BDF44D58B1B52492972F6E02119A662CE + +Cipher = ascon-aead128 +Key = 278D2980C89F196D494D970187DB8FAA +IV = FDBF3E3549FF8A5296D5BEF931377E20 +Plaintext = A8426444F61DE4EE31C97EC0AE09F1B403431A +AAD = 97D86BC86E43DD25019A7F381683E33A5E08AC8D1F +Tag = 779C39C43A26E0AA92DBD8D064ACF302 +Ciphertext = D7B3529AB7FBD9606EA70F3A7B32D1481D3A91 + +Cipher = ascon-aead128 +Key = 57EB953EB5A18612874063525E80D7A1 +IV = 5A6F543E9A0A86A5077C65A0D7C6B8B3 +Plaintext = ABAD1E580443BBD075CA548ADB9A1C44D819D9 +AAD = 88897BE967F8746B6CA01000484618E4EF28E137C70D +Tag = 172678F7BBBE1F30960BC186014A1E3A +Ciphertext = AFEA8165D1CBE816A6EF7BDDF9CE38422528CA + +Cipher = ascon-aead128 +Key = 422E71007C00AE4B3B9FB088D2AB1511 +IV = 901CAE38F07D4102279BA2E3391A32FB +Plaintext = 429FCD2734B7FBD9E6C7D31DE4FC4AB44C66E6 +AAD = DFCFB6E963B31C186A1AD67446FB93F260C9F1BC31FB13 +Tag = 6298B0D33D480B6478D409E34BF3235D +Ciphertext = EE3A7377004A0CCBD2D8088EE3E259F7142E88 + +Cipher = ascon-aead128 +Key = 860968DBD33D90213CE16ED75DF77D7D +IV = BF912CCB9CFF3CA3168DBCE3A64A8E33 +Plaintext = 21DA047B3358146D2242D83C71F9DB22BFF78B +AAD = 691F9048263B088008B681D15CAE054B0A4A6CF0ECA08FB7 +Tag = 1EF9FB049A1A42B3952FAACC736CAA4B +Ciphertext = DC88ADAD69649F65DC5460BF675680CC6D3BC3 + +Cipher = ascon-aead128 +Key = A94787A6D6FAE053D0CBB40F5CD0E919 +IV = 25D59DBCDFED9F5BB5323588A512DFB8 +Plaintext = 66C9541CB448196B211025879E877233377451 +AAD = 643348A285C506691A6A6FC9B927F7299B42832E27F83F0447 +Tag = F027A4AB529074D592DF0F0DFED056CA +Ciphertext = 9E977A313DB818D0164BEBA51A3BA6A5F1E462 + +Cipher = ascon-aead128 +Key = 4540AE0422125BAFAEBCC4405ED44B96 +IV = 7D19BE6C7122ACEF66114CFACFE33D31 +Plaintext = CBF50C8D8F2D0FEA7E1622B1E5DFFEDE4F03DF +AAD = D90E31E8AB45597DE745F850889376FFCEB93418C8D04D39ECFB +Tag = A99A801F0E1B845C0903A770CAA4FE77 +Ciphertext = 8EF063FDD6813848A77905A75B0BBAECB01B31 + +Cipher = ascon-aead128 +Key = E2EDA646F64012847E3386E5E5787028 +IV = 776CA312354226B2775A83FE618A13DA +Plaintext = C1FADBB5E5AADD18E1E724A74255E0BEE65B06 +AAD = F4605E8564CB793A4984397815654823DE3EA599CC712B69E7E10E +Tag = D5DFE180AE875A0BAAADB7252B473AAA +Ciphertext = F59ECA9BB2732C636B6AB989A45ACBCD85200D + +Cipher = ascon-aead128 +Key = 5FCA4A794C0B49D8DD1F0832581D6B66 +IV = A4B97E34FFDF36C68DC7366A40E22403 +Plaintext = 2DB96EB48738CB6B561E0A022478A483D48FE9 +AAD = 4701329E95AB7A6D684FF06FF4F8D3C92D7AFF0A04932A5324AC7682 +Tag = B199FA082FB9F3D34923330B424EB429 +Ciphertext = 64EA35D8C036137092281CF38B8F87716E3AA2 + +Cipher = ascon-aead128 +Key = 3BFE7B59CED5636914B61F747DE11514 +IV = 3DEA0611DDEB3F5C4EEC1FC6E210E140 +Plaintext = 1A9113C4FB171AF862D3F3F6BCE49FD586453E +AAD = 76B4CBCFCD2FDA44A1BD61E559D7BECA94A6A8D311A2503AD051588AC7 +Tag = 52E9217F228A3B1F63F1445289B9D805 +Ciphertext = F5CE5AF2BBEAD169A0E2FD0F78018EC17C0D6A + +Cipher = ascon-aead128 +Key = 27DA09B14C7DA53EB4B99F3D6D517F4F +IV = 23881BADE00A15944B298D583B4C755E +Plaintext = 6EFE2BD829B4E9C8715A7B242FD309192B9C81 +AAD = 12D7F791949E18299661B5C4357CDE53CBB639CFD609C838F52B4A4796FD +Tag = 88245BAC1A277382F7192E33958179AB +Ciphertext = 2AD7B6CA5FD9D405F6F820D0EAC5409D1B71EB + +Cipher = ascon-aead128 +Key = 5679D92EAFA42C463A4880C37F652385 +IV = C1028BA0E657F7104D61DBAF998251CD +Plaintext = 857CEB40D8CD5475462FD4DC14535968C6393A +AAD = DCA52E4BB5FF0AE0EA09D1C38E99CE44390F478767EEA31EAB3E3CB567C8F3 +Tag = 7AC6D078AE7B1CB6D49301EAC8761CBF +Ciphertext = 143EB240462DB1CEE496203E4AE7827D09E0AC + +Cipher = ascon-aead128 +Key = D8C92AA6C2445A0B7C59156F73502417 +IV = 21FCAD7CDB2CBAE53C4E5E5E2AF9AFB3 +Plaintext = 5DCFD8235C077C537FF293B9E7D4E4A049BECE +AAD = C5D0F74995908A24B748442650CFADEA98530BD962F8ACF26D086E60C442B735 +Tag = E36F57B59EE72AD7F09B122A0CF1B991 +Ciphertext = E4D653743F0897186F7EFE18FCC09D4051CC75 + +Cipher = ascon-aead128 +Key = D9CC262D05891228F52FE13E049A6435 +IV = 6369B51E61A2884EBDD83618EAAFEDE3 +Plaintext = 0A6705C62F292E9AC4A23F5DA2BE5F5D4226EFAE +AAD = +Tag = 60E178C63C162C876B5D6AF1979FAD6B +Ciphertext = 5C85278404D54A8D0A51467E55F7BA21DE2EE13E + +Cipher = ascon-aead128 +Key = D0457AD8E890AB3A628D0C81D9FF3B1D +IV = 1F5A88C5B9C44DB3B2A68638197CF9B6 +Plaintext = A617A95883147E206F0BC962A6071FB5F1F85483 +AAD = AE +Tag = A7C1E30E04917E2A969FF8FAC6CED16C +Ciphertext = 699EFBE3E8355F5ED3C9F7B11347CCD1514996FD + +Cipher = ascon-aead128 +Key = C4D41C5296331524B838A751780A61B9 +IV = 3137D7C3186A6A1FFF751E60D4F2FBD5 +Plaintext = 70ECD2566B942B5AC1CFBD4778A315733802F66B +AAD = 1A20 +Tag = DFE43EEA4D65B7A7582E6E1127D7CACA +Ciphertext = F87B85FCF351A49FC68320DDD9BB618AD60C0D6B + +Cipher = ascon-aead128 +Key = 3262C11AB3F87CD06ED3453FD4633AAD +IV = 4F3ECE5B671340A74F5356098D5735E6 +Plaintext = 5003D68EF40E9D0ED429A2E4858FFDA3E2143BAF +AAD = 790882 +Tag = C6D928847F03ACCD72F790A17E01FD45 +Ciphertext = 652BD4787079BF5C96AAFB41E9148DBA9844C12D + +Cipher = ascon-aead128 +Key = 6BA2D094995D59B3DAC723C60E4D06D0 +IV = 5FA882ED10C08CBCD854935F41917045 +Plaintext = A57D48DE323D50B87FD72C5D463F10B209C2D737 +AAD = C6FF0E10 +Tag = F8E6F4EE12988C3F89C1833759ED5DCB +Ciphertext = 6ABEC06AE591862FAEA599819F9D7287930E35DA + +Cipher = ascon-aead128 +Key = 75918FE52B78E45C4EA50373828DEA69 +IV = 53F4EA80A65BAE3EB3778EB8B94AADB9 +Plaintext = D6EEDC4704B5450E03A1E46FBDC322E4B20FAE0E +AAD = A73A4BEA31 +Tag = B6B00695F388A130EA6A8CED6FD7695F +Ciphertext = 9B541DA601ADAA2E570D1BD07E355C8D0254AE35 + +Cipher = ascon-aead128 +Key = A54E5357EAAD829E9B06617ADE9A5D63 +IV = C6C21E2DF87A87C1ECA3B311E869FCFE +Plaintext = 0629EEC0BC8A6EE9F4C451B1D922DA830624F0BB +AAD = 3188FB4B3873 +Tag = 9AE5FE0E3998DE46BDAB293229407226 +Ciphertext = AE25E7E78A7F4D085D89FB92D797DC07E16C91E4 + +Cipher = ascon-aead128 +Key = 97B39C26FDC11F286E97D039E02BCE37 +IV = AEC15CADEBAE356614996EBBB2ED4C39 +Plaintext = 73B0E6BF38FDD554E0ECF8B230187644F9FF18EE +AAD = 0AA9CC057C0C4E +Tag = FBB28DC3D7584FA7B534CBB301B7A22A +Ciphertext = D8A714B7415CB549C24004901E3FC3871149FE59 + +Cipher = ascon-aead128 +Key = 40D9B3E94AFC5A7FE07248A767FF85F6 +IV = 26579280CF246CF237DBEE9C490A73C7 +Plaintext = CDFAF690CFF985E46FBAAC9B0C66148480F38407 +AAD = 55BEB2A02E291E3E +Tag = 6B29771E92D7F0B5DEA087882253C60D +Ciphertext = 99E05320980FC19FE22C2BAC6D3DEEB386912C24 + +Cipher = ascon-aead128 +Key = 7C07A4222BCF3DA673FB9C453708998F +IV = FB4766E03FD6822513236C888C81A88F +Plaintext = 6DE23A1A3ACFDD77C3137D11F871BFABBCC7FC90 +AAD = 913971CE7FDD2E84D0 +Tag = 3CAFA47FF8BD7BC9AEB3E2E2D26E7CD4 +Ciphertext = 80EBE5BC5BCED0BF21392F777C40E6B81C0D91DF + +Cipher = ascon-aead128 +Key = 53DDC66723F537122F431480FE8A72E9 +IV = BDA30648CBE03A5AD8B2B8C2C4D29D49 +Plaintext = FD86BDEE9FB015B9CCBCDEA95154E91419895299 +AAD = 0DBC90197326167AB040 +Tag = A8A5DE4207D0CE6DC372B396A728D5AB +Ciphertext = F3B6C9810929B06FAF93DAB9B40E483B65CCC121 + +Cipher = ascon-aead128 +Key = 09811CEF1229B154952EA854CBF893D2 +IV = 25E44F835195C2557801692E9BA5FBAA +Plaintext = 9F6E4B95BAB4BC2158AE2BCED08271F41EBA12A4 +AAD = 185CBD7B5D8C00F027D454 +Tag = EB73130F244B7E8981C93BF24758CA5C +Ciphertext = 1FD64C6B1AACB946B75ABC5B0DEA67895CEB3B20 + +Cipher = ascon-aead128 +Key = CACA5073CFFCD905CD730E669C61FBF0 +IV = CA424D5447A6BC903DB96814D6586353 +Plaintext = C4F0821979AB3F8D8AD357E0744139B4FA14FD5E +AAD = 2B6AC3D0A8F9BA59B9775D77 +Tag = 34904FEB983258B47F8170CB37414874 +Ciphertext = 22F44D62D853544F2C0E89DE2CDA2F64D51B277F + +Cipher = ascon-aead128 +Key = 00F95EE93CF3D71599F5D75B28F5E22C +IV = 37F55941B5292130BCE207773B0FCC42 +Plaintext = 5A67F1CC3158A259F955805D23A1747B5E241118 +AAD = 7AE84C780A15BCD995052597D2 +Tag = 0DF6DFE1762E117063C4528C8DFD948D +Ciphertext = 0DD0BE8581BBD59A7DA922F84EDD5DF0F74F0AE5 + +Cipher = ascon-aead128 +Key = CF5710FCE2CA6992A24657DEA4E4FA1E +IV = 4EF62773247A11C50C66D903B7774F7F +Plaintext = 51C035B2050287CDD76A2EE35355B3B99F0CA464 +AAD = B4FCD81BEB1A2D45B21D40C0C034 +Tag = D7929C623FBA9C45A723EFBDB61D496C +Ciphertext = CB12AE1E8301FF92935C32E9BE677E49FEEED65F + +Cipher = ascon-aead128 +Key = F34BDCE54E580FCC4E5F4C4F11B782B6 +IV = 6A9F5B34355E81EBD7BB3B1B32D67951 +Plaintext = 5382E9339C4304960E03547017E9AE3F8AB2FE71 +AAD = EE7DBB3277C6CE514DCEF61061D2C9 +Tag = 3004B06ED8C228AB37CE3ADB961F152F +Ciphertext = F29CB8D73234B0B4C98EFB5299D4142846C30DFD + +Cipher = ascon-aead128 +Key = 8D3027636A4B81AF784689AE82612813 +IV = 78A49A2C97921785887CED66136D2833 +Plaintext = DECB047910A7F9EF974F8D56E4AB89D143CB39FF +AAD = 70D329C5959DEAB006955BE3A3CFF9F7 +Tag = 3503472DADE055C78F802BABB28691D0 +Ciphertext = 326DC82124D5856AE062ABD4A4B6C259467CB6C5 + +Cipher = ascon-aead128 +Key = 4AD3FB13C8D7FBD2C3C5F0BB465483E6 +IV = 6988C28CD70121B4803F6DCC48FB4A95 +Plaintext = E41EC718375BEE662FD780B9F054A31A622B3C23 +AAD = 196C8CA3B6A305A6502076E6578BFAD2E9 +Tag = 639AA7CBBAE5E44DE9E484E47508EC1B +Ciphertext = AFBDD02D2C2DFFAC244E973F14440E84FB0C1FF8 + +Cipher = ascon-aead128 +Key = 6A20F95FBE241AD317D8EB6E4D523843 +IV = FE28AE5F64DF87243F9E61BF4C6AAD5C +Plaintext = 5B958B9E72FC551A5D64A3FAF8369D916BEEAD85 +AAD = FAAC7B82E9166C2281190B07E8CDFA0A58AE +Tag = D2F7C9DB949A27AA5EBCE8F4FB905B84 +Ciphertext = 3D7B99A347E865295C8829EC76AE00794A278A39 + +Cipher = ascon-aead128 +Key = 5ACE93FF649AD675258C8BE128372A52 +IV = 474022AEAB4F69FF407D9561EA7F1408 +Plaintext = D634D5B91131B2444BA59FB6C848035ADE7BE6DA +AAD = 1CAFDC72A9D44EF3FD40BFB13FDCBDF2A39598 +Tag = EF562A6F84310686039E83DD01EFF460 +Ciphertext = 54E367B879E7BF89077B4BDF23F33BB3CF30935F + +Cipher = ascon-aead128 +Key = 58C91D9F94C37C7DD46E7860D52BC1B0 +IV = 49A3DF697F458EC24E725A4C6EC4234D +Plaintext = 9B8A0401F9615EC0814E622766CDA70BD82013B3 +AAD = DB92E3C30E3EDD80E0A36248EA973007333B07F8 +Tag = 6655E5C390814C94A212BDE2506AF8F4 +Ciphertext = A0D39F9953842F81B9116194B202C4A98395F1AC + +Cipher = ascon-aead128 +Key = 7FF050D89CDF2A58C989F9E0A35C41DA +IV = 4E2E7532DB4380AE22EC874A0BE8AFD6 +Plaintext = 1A35E404D6D89F7358082AA314699B436B7FE09D +AAD = 6B4EBF7091775A36EDAC1BB701F9C9E1F8A6E7757B +Tag = DC4B36ED1FE265C8577CCE40978252FE +Ciphertext = 744356752CE3E3632D508A4ED17C5D725242092E + +Cipher = ascon-aead128 +Key = 916CB31A410E9665B4B836B370C10F79 +IV = 3763D69E165AA85CC44B521077273BDF +Plaintext = 1001E10BF2B95E56552F5496D89100B026F8F280 +AAD = CCDFC5E656C804060042850A063515975D760DBC7755 +Tag = BE51C5BE5664E67E497A39C4DDAC6898 +Ciphertext = D5637E0D661DD19CC4585DBC2F8A7346D903715C + +Cipher = ascon-aead128 +Key = EE07FAEB394E84F9A6D18CF183F2AC83 +IV = 219BD40EAC059FA4BC50A35E6B22D324 +Plaintext = D7EAA1DD3E6A5E9506411F9707D2F4727ACADDF6 +AAD = 89722B5BC8AE9D610D1309E64A909AE8C88D76B6BD8488 +Tag = AF5F49A7BE812587DD9C0AAE89EF03A0 +Ciphertext = F2D17067D4A4CC1E030AE3CFE1400149F7F8A5DC + +Cipher = ascon-aead128 +Key = 854EEB5A2EF4EC5E75E0C56FCE77C1ED +IV = F5EFF6F352F57E2E14E0420F62A80352 +Plaintext = F551A3F8D974E3DB76194BD6F775E8347C990F66 +AAD = D6F9285FD231324EFB8C2AFA211F6AB68338531780160B5E +Tag = 992EB150423C1AF3A0C77232818387D8 +Ciphertext = A6FE6E1DCCF119D1A0A03383FBA2F33DFF304FBA + +Cipher = ascon-aead128 +Key = 763F1C8A50089E7CD22CA6E5C41B133E +IV = FB83A3E0B55DAC4ADFA670963F5A0673 +Plaintext = F715F4C94178DFB0F63FD1F3746C3E0756690425 +AAD = A40D87C4025E4E4955E79BBC126C9F4F0370C98CDD901D3971 +Tag = 07589D09DCE62500B25D11FA51CB44BF +Ciphertext = 540173E4151F1C8E1B38D7E037C6604F50BA35D0 + +Cipher = ascon-aead128 +Key = 1B9275277852AE038828EE4F9CC0CF49 +IV = 0F864DA3C6C4C09767CA71E90C2EBD96 +Plaintext = DDFC321972B66B0244A21D755A6C73A0476C4649 +AAD = 8FB53D19DB03C86BD484FACFBC1FE0356C4EDF164231F1C6EB07 +Tag = 7B64BE3E8E7B4F7F7ED520C46C43C57C +Ciphertext = 39BC2FA2B3F13D403B72C5DBD99DA605715F780A + +Cipher = ascon-aead128 +Key = E63C28D72CA629AFAE5B521EE3569F11 +IV = 2371FF492554D95FEF0731F23FF2E617 +Plaintext = 200C8924456089E21E90D37C9648BFA472856D1B +AAD = 3FC748B1A5E2D5864DFC67B2D55E3AE6AC6F1FCCF9E4079B51D591 +Tag = 45E3801B580B3EDFAF255222EEC58BB3 +Ciphertext = 17C96EBE06E042817DBE2FE6194220659D30988E + +Cipher = ascon-aead128 +Key = C5C8ADBE8916E41740F26B7B12B7EA0E +IV = 4672B7BC950AE803EBC3E4F78BC5DC96 +Plaintext = D929854A0C4A203C5340E3AEB419C0B34EF6D917 +AAD = C59E461AD28B3DE91112D75DE24902E7D7290452CD962EE9B1B82990 +Tag = 6B1FB730F0F4D14825819CA0C0CF8064 +Ciphertext = F6E287DA697DBF9683434700E7D839B14C2D62B0 + +Cipher = ascon-aead128 +Key = 9DB2CD23AB2A756DD950BF6A9A5327DE +IV = 65B63025D44691F69275CB11B4168788 +Plaintext = 8E7B99301A5CF58E9979BA9761BCBDAF199D024F +AAD = CF63505DE81038C241EB66FDF0C94183A38C0C0E6F5926E6956A05EDF1 +Tag = 82DB529CA3F880B561C5684D667D3531 +Ciphertext = 3FB4D20636CAE08183CA3B8C87F78695F22BD3BC + +Cipher = ascon-aead128 +Key = EFD461DA41C96F7B9BFA55854411D2E4 +IV = 585B45F6433E70B314770D30961B3C13 +Plaintext = 20C2ED5A6DD70F4840C80212E1A96023E383AABC +AAD = 2350BAC572E9D45E7D65A5F764F10F7E96F20692BA601699773140842A29 +Tag = CEEF818905A9E92F8168BF674B45AB5F +Ciphertext = 9845756B5E7432AC7285F048175E4EE37B519BF6 + +Cipher = ascon-aead128 +Key = B43D76190D8D3B7431AC2501FB98CB4F +IV = B5EAB85C056519BB5636253B164A2DFB +Plaintext = 7A2E3735BFA91CAE928FEF586F968D6477016BB1 +AAD = 080B7695C3F6260D9A0BBFCF1E4E7579A8ED1BE0CEC852865512BD6ED938BF +Tag = E5D8ACEFA7687370857B861B85A7851C +Ciphertext = 37C65861FAAA64C759DC3F3B61A08B704892C8ED + +Cipher = ascon-aead128 +Key = 6108A6CABEF8FAC03B592E9BF7B1A3A3 +IV = C87BF138D0FB90891C1DC59F99BB0B3F +Plaintext = 75A3F358F15F5CE29E723EB2F2C9F9AA244A8E68 +AAD = 58465177E2EB926DEE1773599FDAFAEA82EEB653E00AFF635148BF0A2FE9B56E +Tag = E2CBF4453D12F152F7C36BB16E2F872E +Ciphertext = D68798107299D1B4DC24C2EB5ED2EA2BF540D9D6 + +Cipher = ascon-aead128 +Key = BDB97D8D071D8D735E72CDAD47B37DF8 +IV = 2631B98CBFFED94670D1DFB489C69DC8 +Plaintext = ADFBEDE49164F36F223B45E708D4D15FB80DC93FF8 +AAD = +Tag = 823B6726EC2ADC620E4F88FA197C4A91 +Ciphertext = 0C7726A92A9999D60015E6EC7A0EA881E84F8D18CB + +Cipher = ascon-aead128 +Key = 4D7665FD6FE43968BB87396AF621BE8D +IV = B3A8B353CC01E981093BF21EEC0CB6B4 +Plaintext = E2B087E4363393C280A4296E51645E60A6F73CCEBB +AAD = E9 +Tag = B58AB0FF1C400071F2EC83310F519706 +Ciphertext = 845261663699B8DA6E1C10E1B1739DFF3A3ADD91B7 + +Cipher = ascon-aead128 +Key = D7FD73C906B76D6F25611D8401E6BF94 +IV = A2A11E8A54A23E0CB8A4398E0EEF754C +Plaintext = A90D8B23CA7DAA79FF8BC8DF4170D99DD98E9D44A2 +AAD = CF8D +Tag = ECAE44B51AD3108DA80392865626EC27 +Ciphertext = 383136B05A173628D94F31F76FCBDA68A1C45221C9 + +Cipher = ascon-aead128 +Key = EC624C166AAFFE260DD385ABFF788B4F +IV = 1F69C661B9D06042042665E87A5969CE +Plaintext = 9243BD076CDB0201D73DCFB8A3131595E7C16840EA +AAD = D264FF +Tag = 1AC1FB7723475A395C7F1E33CC46BAF6 +Ciphertext = 8FC28A7C1221843A988D05FC04F979AE28A28C99EF + +Cipher = ascon-aead128 +Key = ED5AD2813DE07CF9DBCC41817A600416 +IV = 9164ADA4CBC46A31ED3287CF9672D275 +Plaintext = 2DDFBF042D81B3FBEB9198F16D2960AFED7EE5B162 +AAD = 7F2A7473 +Tag = 23D59BD3887F9851CC3F3086F3474BD3 +Ciphertext = BF980CBE4D0C625EA85DD43C1086ECB1DE7AC6D8DB + +Cipher = ascon-aead128 +Key = 26F567568403406FB3F7ACF7CEE3F8A3 +IV = 67D317354FB05C69858583AB645FDABD +Plaintext = BDC66945D284F8B860636895C65AAAD1CA0E207715 +AAD = 539ABBFACE +Tag = 847F6F900409715FEFBC0D22E4EC0083 +Ciphertext = A08A64C86931FE660871609189D7314A77DBA8BD4E + +Cipher = ascon-aead128 +Key = 67444F077DC1F8CA144EF848C2F8967C +IV = 7FF32D105F9394B88C3862363D5B333A +Plaintext = E9C45EB51C61C095B89EB63E25F0A64CD1F539D416 +AAD = 5C8974DEC8B2 +Tag = 9A27B334ED33CA0768E7754CC6986296 +Ciphertext = 2108D2AB493BB7E61D0A8761037A63458388B4AD56 + +Cipher = ascon-aead128 +Key = 89F7515AEC8A83E1B64B89AAFE15A53F +IV = FB7C70A265835DCE3E0ED3EACFEE8419 +Plaintext = 8A088DC2705FA6265E565EEC47F270C430FA54D2A5 +AAD = EB586990AEB4A5 +Tag = FAC94554A8B48DE97BD6DC585B652622 +Ciphertext = FE7A74C060C9749DDFE61FACE7CC37386F154B5932 + +Cipher = ascon-aead128 +Key = C48301557A0246EE826670CA9D3D1F81 +IV = B89EEEABE58689E83A979A2B5F574816 +Plaintext = 0760879FC01A4258274AA3AE3BD00C74DBA54B4E8C +AAD = DB4EEC9325BBB521 +Tag = 4309555425E65872D4F380F8F6235F61 +Ciphertext = 15C8B8E3B0D5E745FC06503398CE82893DBF46CC71 + +Cipher = ascon-aead128 +Key = 6EB783E07D227B3852EF7BE3C60FD48E +IV = 1C8A0BB61BEF933B1922D3BAB4FA6FFD +Plaintext = 95D93A0A0710A7E3F8C0EE4E507D9C14B76D1744BE +AAD = 14154AADE59714DFCB +Tag = 5E961BE2783535A304D57D365AB172AE +Ciphertext = CC0CE79D0F67E714E103F027671E6FA1C1EA0C6C66 + +Cipher = ascon-aead128 +Key = 5330B7A3B72BA43B40D61BB6FBFDFB06 +IV = D3E43194963414A29D52E7A4662572DD +Plaintext = 6E1A7DA7060D40C8D1D18883D2B23B4D88CF3B059A +AAD = A85E671A07F43ECB09B3 +Tag = 364A8E011DBF0F3C929B0C3F8139AD70 +Ciphertext = A0EEB6B2F7EA922BDFF8D90B61ABCC29E7E762A23F + +Cipher = ascon-aead128 +Key = E27EC22ABAFE4DED0114D1BF9D370121 +IV = E4C80E5C3778BD8E1AE31C6E6D362FE4 +Plaintext = FDD560172AA6094F1555305BE611D73D8A8FE95BCF +AAD = 3FDCFC08FFD35078CDF723 +Tag = 27AC880FCA39D3CB6F85396E9A778CD5 +Ciphertext = E6D60A9923B14F1F585545E12EFA5647A5B4ED8989 + +Cipher = ascon-aead128 +Key = 21BE1B19F25ED8BE9F2B2C905762BC49 +IV = ABD0F0F5F52C706116A5718D50C24916 +Plaintext = DFF028B3DC7952084FF370D4E10FE0BB1304AE1ECC +AAD = 3ABD29221898BA113103F4CE +Tag = BF844482EE7855AB4B1319B376059E8E +Ciphertext = E15331669CB186C424839D317DDF802307E57286B3 + +Cipher = ascon-aead128 +Key = 37EEC54DD7FD6A3D823C54E9F28A4E6D +IV = 3659A9A3DF0C41BAF132D8E654137CB5 +Plaintext = D416567FF289ACBD638BEE33E481236F461D217D8B +AAD = 0D9E69CB5B5265742C589D180A +Tag = ADDFB6540A17010EE55E7B6132924B16 +Ciphertext = 5ECB38A4C279BBC281EB3533D72B38C3EC3F3F35A2 + +Cipher = ascon-aead128 +Key = F37212F8902C1C6EDCF9BF52F5F6DE14 +IV = 9F9F63CD4B7ADD1639CF1A9140142B1C +Plaintext = 8FAE78BA182EF2DE30B11146D9DB68E7470D1DCB66 +AAD = D08FFD14A618D581741B232D58A0 +Tag = 44CE8FD4E52DB2E2A6DA8C59D0DFE8B9 +Ciphertext = C0146241066CBE5D4ED1458412CBADA5479C8BBF81 + +Cipher = ascon-aead128 +Key = 34CC48335DC8E4A80D7BE42B59847437 +IV = 896284B384FA1B039C7C1D73D1A566A0 +Plaintext = 5053E9048302B07D497CE856C8FE98D03A9BE4099E +AAD = 27880DFDB106A21DB3FEB2A7D1C923 +Tag = E1C3069918FB3D2B2D968D03C7AA1160 +Ciphertext = 67BA8E28D35B078DB6AE10D06AE029E18C3078E6D7 + +Cipher = ascon-aead128 +Key = 5C1369F3079930AF45BEBD31FFF4532A +IV = 7C6D35F21655A85410C8DAEF279A2B48 +Plaintext = 9361BAEDEC05FF89B340880D284DC6A03F31CA41BA +AAD = B53BC2EFDBDC3F01CC85085B9C20C8C8 +Tag = 000FD50BAFFB9A5034BAFC5E879853B8 +Ciphertext = D5B587CB2ABA51A237BE081851914760D0C02BEB42 + +Cipher = ascon-aead128 +Key = A4BCCB7FF078C2E6B3193E1DC5A89854 +IV = 411B590DF379686870ED1E6D559511A7 +Plaintext = 2881AEEB2B6C248192F67FC53295E98C92777C491A +AAD = F78890CEB3A0FA8A7C9389A82449CB9A88 +Tag = 778C3C868C1A0BCACB7C139DD34BB0F1 +Ciphertext = 20FC55F2651287CB021E2B1E386ED9B23C9BEF3F11 + +Cipher = ascon-aead128 +Key = 3E8EFDB0D489006F39846A64D0C816C6 +IV = FC8304C4CB14B371DF3DFA5FD6865932 +Plaintext = 3C3543797A08259B763839491D4F949CC0F13AB9D5 +AAD = EEA80453C2F20BA3E21C2A75ACAD5AB45316 +Tag = 2C5F2E7C62A6231F9C0DCC81CC675A7D +Ciphertext = DA1D9A7CA7C065C41B48C66311B58A77B1F3E176D7 + +Cipher = ascon-aead128 +Key = AF19FCB31C0D4FA762288320AFC14955 +IV = 59A3B5618CF14C9B89B2BE6FD2F0E73B +Plaintext = D756CAAB677BBDF2522950D0A490B16BE2EFD2182A +AAD = 95EBC67628D5B3C3DA182B98405D1304C2ED63 +Tag = 702E823D05367AF4EC9335BACBA3FED9 +Ciphertext = 8E5A6EF1DF8E9E332D5162A6361F2A127AD7ABB1A8 + +Cipher = ascon-aead128 +Key = 2A1E8558B4A27527425E5723FE22065E +IV = F2890CAD6BC5002C5A95C9174E30ADE1 +Plaintext = F5CF14DF98B0DD8B03154D8C9D5C4A621B4D19AE76 +AAD = 9315DBCAA4A96E170AD3AA4EF0C2093CDCEAF0E3 +Tag = D8DB3AD8A4A41BF0CCF40D803E28D4DF +Ciphertext = 4028D07EE61DD432ADD082585CA094027D8E2EFDD8 + +Cipher = ascon-aead128 +Key = 4AC796E75F696AFA36A1212BC9D401E3 +IV = 12F89C3A5B24C3335244129DD6A0BA94 +Plaintext = 0B8CC71186C2C6EBA1363944748E2DC62A1B7136F4 +AAD = 66A35CD61F131FBC8704345DB824C2F58C981BA53C +Tag = BD398AEBF13656CA199F295A51573E71 +Ciphertext = 1457F581DD4EDCD9F07138D684D1028E9C9AA723DC + +Cipher = ascon-aead128 +Key = 4F17684E89C3E5193911A2598900EF0C +IV = 869473C841FBFCFAA2903C9A0C1C24E4 +Plaintext = 3CE702BDD25AE5FD91DDD581E81A78536C66BDBEED +AAD = 96D16E09B4C66F936C68FC946E03405AB269B61D9D52 +Tag = 6D906142D4B0CCACA622C489D5FC7423 +Ciphertext = 908F923B3E9309CF3F8FF5D921598D54A6CD587128 + +Cipher = ascon-aead128 +Key = 5568F57F435DE4D15D9A5601D19CBEAE +IV = 4BF63DAA403E0BF63D3059555394E496 +Plaintext = 48D5AB20FCA95172D99E95EF5EAFAD29EA07B69E09 +AAD = B1B2418C27CD736DB8DB48047CF7F8ACBEBCA195303EB7 +Tag = 4A4F57C689D348ED3A719DAAA7209AE1 +Ciphertext = 02BCE42D793797362EE280C45A83DD851F8F3C8753 + +Cipher = ascon-aead128 +Key = 8D0AEC13DC370EF615C6F43BE476842D +IV = 7DDDCF482F41E4366A2A529DA8D631F9 +Plaintext = F7026305110A784D343747E3F79D0685F1CF7663F5 +AAD = 12B1A6BE03B3B300907677ACE1088409071094CAC7D9B3C3 +Tag = A8313B907E52891522AC3F46C687D485 +Ciphertext = 4F9FA1503A3B0B2459AA07DCD12C3EFDD15335C382 + +Cipher = ascon-aead128 +Key = 67A735A4DF8790C58A5F8AD4530258FB +IV = A45D40E221088200057214D12EC414C2 +Plaintext = F6B4C352E81D35995323A2B6189204AA102AFDBB08 +AAD = D4BF2BC69C4B422384B46E334BCA7E8CB3261452FAAE18EF9C +Tag = 465FDD1F1EA13C6F2241B0769890603D +Ciphertext = AED995F86454B4ECB3C1594ABC78C5573FBF1D3C25 + +Cipher = ascon-aead128 +Key = 47FC58CAF21D5CE8A0A7039F535554B6 +IV = 576246F2A9EA3FC42570EC3F8D381100 +Plaintext = 4CC8588DAFE54C814F2B93EF1198612E9BC0E4B3A8 +AAD = 3C5C2C4728838808AF3B13636CFAB20931A51352875FF17F2539 +Tag = 034124BA62F2B5C74C36EFB15A26B432 +Ciphertext = B2EE3C83BF895FA99EF37758108D7EE28840E3F86C + +Cipher = ascon-aead128 +Key = 43C7733AF06D8486769E46B13842DC90 +IV = 745D682A804A7297B25C44933A02D0ED +Plaintext = EB9553A846904195731C898D7BCC6710BFFC93CC62 +AAD = 72FA3AB89C07CDE0EA34916E5192CDDD1582D1ACCADE8B070F49EF +Tag = 2DE368647D07D2FFE4F8C7625100073F +Ciphertext = 099C47438B94B656DB81B3503470F0EA7ABC155EDF + +Cipher = ascon-aead128 +Key = AFFC94C4C58366C4AFE95293B027DFAA +IV = C92EED9D38DD97C9ED9F15F1994D9F4F +Plaintext = D04225094C41C0E355815D6039B3A70D97B0D9C4B2 +AAD = C08C7B8C52D16EFDE2A61A8BE3928D0248819C17F3EFC94FDA82EC5C +Tag = F72B90A76DF680DE7B094BE5C2B99F2B +Ciphertext = C480A4638DE864A16A16E6494B865F3F329FB18EA2 + +Cipher = ascon-aead128 +Key = 2F9AFB93031E43DEED3DBF0746482D8B +IV = DE59E0830E2A579225970D1596B99AEC +Plaintext = 8190C1E1040A62BE067D95ACEBC83185BEA1B65778 +AAD = 45BAA5482E752D874D80978C9760C2F976CC42B499D0EAF50A1E1CB3FC +Tag = D0E1EF764ECA53FC39A9FA656DFFC168 +Ciphertext = 33B0626BEF6AA8B8205233CCAB228F0BB29E5EF06B + +Cipher = ascon-aead128 +Key = B9DF840391BF6E89F6D3D4E9AA4D1B72 +IV = EF04489E008ADE5A4DC8DF58643670B2 +Plaintext = 36A91832BEEE3F8A63013C8127D0ACC3389BF9012E +AAD = 91BDE38A68E3679D187FE82AC1B49896815EEFE408B025B9B4525DE3DF91 +Tag = CE62BBA0E5E3B420FE8FCD3715AD6172 +Ciphertext = 201A69951A50B43DDC63817FDF848C8BE07861F986 + +Cipher = ascon-aead128 +Key = C08A40115959BDB265D27C057672CA86 +IV = C2D09A5ADCF603D1950CE9EEAEB6717E +Plaintext = B3D703414AD3352C2449DA051B6C01F7C56C9F659B +AAD = 1AB241885DB5B452D0B101823EE98025FF9B036CA389F17FC5980132F6D1BC +Tag = CAD4D34AD9C3897766DB75DF007A5958 +Ciphertext = D8DD51E2E24BB53D89990A7F2792862B5156510B7B + +Cipher = ascon-aead128 +Key = E7B6336804A4C7AA69817800D4146EAD +IV = BC3C4FBBF7D0A5465B93B023226D77C4 +Plaintext = 4A2C7A8995605BF95EED5B27028CA9727B4228AD9A +AAD = F298CFC9253931292AEDC9479CCA59FD88153B9B05AD2F6DADA1C91C2EB9C049 +Tag = BF592C055B210460890A284C6D56734E +Ciphertext = AC0943F3A89D0365DCC360F3BC164344DD83432E11 + +Cipher = ascon-aead128 +Key = 21D541B2FE4B03579361EA21195FC9CD +IV = 5C51942D8D494141D339F279C3BF3688 +Plaintext = 8B639D3C20D0589AAF7687FC9841F9C0562C3CA0B3E7 +AAD = +Tag = 220A433EBDD6D4C2E7F007B82BF6E750 +Ciphertext = 51F2550B30D87812A935BBC23DCF4EE6858AEA5D7EB3 + +Cipher = ascon-aead128 +Key = 2FD724CEB71912517A9E1445C60B60D5 +IV = 4379F5A66FB2798D6DB5232DB48F3C1B +Plaintext = 57D094D093FC0927E30F330098C9A2FCD81DAE73AF41 +AAD = 1F +Tag = 4A6566F0DCB3E74DDB6339CED2F7B68B +Ciphertext = 0D47E1E74F6FD40A10830F0BF22211E968A43794B0A3 + +Cipher = ascon-aead128 +Key = A6FDE965BD8801FFB35A27848E912F5B +IV = 797AE9285D43B750867B0C815ED63277 +Plaintext = 7BE8F41632F432775C84A3BBE9FCE3B1DF3716B61655 +AAD = 5547 +Tag = F575421B225B82A43BA69E6D03F0070D +Ciphertext = 15C2364AC64F1E3ED2DCEFD11665C32FCB9A2E3C4AF1 + +Cipher = ascon-aead128 +Key = BA865BA63301823AA611295213E3CFE1 +IV = 5B61E2477DCED03175D7B6A212F7ADCF +Plaintext = E50283AD7B59048CE640AAA5E3B6A9076C7D3320D0A6 +AAD = 4466F2 +Tag = 02674E6941B2EEFE05197D43E4CC5FF2 +Ciphertext = 4CFA14A9B51B3D0207559D9EAB742760E82E80FDA4A7 + +Cipher = ascon-aead128 +Key = 7E867065E6577B9896FFAF8168BF072F +IV = 8349B6B91B9ECD44B82013305202B8F2 +Plaintext = B100BE049B56962AE4DCCB47639B191819DB95722542 +AAD = F5C7BA88 +Tag = 9235F9849AA9FE31A70221538CC55A30 +Ciphertext = DECE9BEB35CEA999FEE7647A4F210AC40E7C923114D1 + +Cipher = ascon-aead128 +Key = ADE13A72F4DFC8972EDED3C316361B7D +IV = D9F88A1D8DC6D915561D1E952F50D645 +Plaintext = 749225B83EAE929D353CED00E676EDB02A0194F4CCCD +AAD = 01C6A9B058 +Tag = 05A0A5C553AF610F1F78E76CF75A566D +Ciphertext = ABF79DF100338D5FE7E1755AC0397BC2E0690E39864B + +Cipher = ascon-aead128 +Key = AC1673ACB9770B7BED87E7D00BA5781D +IV = CA50502709F89CC85D516CC56D83CAA5 +Plaintext = AE06C485BADA36D57E94E727D2934432040AD15AE95C +AAD = BB78D15F19D5 +Tag = 47C53B4FCF16D9ECB527EADB415C7E06 +Ciphertext = 346D993BAE74F5190882E11FA8405C2AA714654CA4E7 + +Cipher = ascon-aead128 +Key = EA5A478950004C2D44F2127C731E3084 +IV = C7DBB63D9BC9060793F41EC0E58F2A7F +Plaintext = BC7A28333EBAF31C0ED1DE78AA02DA2179D87D277D2E +AAD = 46213B8551BDCC +Tag = 0DA1AEE25ABD938DD0E2E894DF495583 +Ciphertext = B4EA97234487D68E2C5D0DF1171AC03A93B83D1FF7CB + +Cipher = ascon-aead128 +Key = ECD9DEEFCB2BCBA9B9E9DDCF6C18A984 +IV = A85B1FA0F212E8FC716A147F7C3BF52A +Plaintext = AB08A421DD8DCFCEA89F7FADBD309FDB397104B918B2 +AAD = 378FE3CFD3861381 +Tag = 3DA99DD0E92BA51B6E5EB6E834B486B7 +Ciphertext = C0F274DBAA91EB7125896AF90174409F7308508E3B8A + +Cipher = ascon-aead128 +Key = 554BF1FFCC10055FE30A0C0A52D27402 +IV = BD5A1FFD11C800267DBF3D51D5FB977B +Plaintext = 84A2726070F7AB3A9902984C291C9E93C71AE5139F25 +AAD = B90F39A39562709994 +Tag = 129E58BE7EB7D94C83EEAF8DAD295275 +Ciphertext = A5548A8DBC6249BCF10653E2A69DC3F017922F05B22C + +Cipher = ascon-aead128 +Key = 904464D9058B948A02FB43E60878706A +IV = 184359DAC11934722BFADBA3FA6C8C3F +Plaintext = DC759189FA75AF443089D7528576FC61FD5F96C5588D +AAD = 14A0DA69389457598929 +Tag = 20899C6AAFDAE9D452661041CA52B980 +Ciphertext = 95D4A3CA70F1F4CEF6B32DDBC02FD61DF0216195D025 + +Cipher = ascon-aead128 +Key = D2C96FDB378DFC1B8B4245E26E3AF9C5 +IV = 35341980B5DC7C31CB7F173D015CD08E +Plaintext = 9BC8437ED89EA655C14F801559540BFF713D45A82002 +AAD = 063056FB389F8846159C4E +Tag = 6B50616A7782B450A909CB3C41D785C9 +Ciphertext = 17253FD60A6ED63D630DF540B9A01CE5E9135F48D41C + +Cipher = ascon-aead128 +Key = C980BDC07AC20DF19483AD918BBCF3F9 +IV = A6489B489C033FCBEC498D2EC0CEB27B +Plaintext = 39EB25630651235D9C72CFD1E7394B1BCB6BFF4DFE6F +AAD = 274BA15ED8D093F8E60EEEFE +Tag = 0C86198A9E84ED2D69432A31F1E886F8 +Ciphertext = 1E998713C0DCA45C08091E892C741CBA7CA80637321D + +Cipher = ascon-aead128 +Key = 21CEBE6E6D4A0F34312E8389D5741747 +IV = 15B964B61DE734D189CCCE72101F13C4 +Plaintext = 6B1F2C44B94D3920DF42143C34898567525AAFD551B1 +AAD = FEEC4564BC538014C51073BD85 +Tag = 694B88EE0FCC4CF7EB845A064AE6D203 +Ciphertext = B76CDD43143A123631E963CDEA5243697B54A8F3FB65 + +Cipher = ascon-aead128 +Key = 00A86597326A7FDA69BCB86A0B3BC227 +IV = 2C78E414DE00699036A46785FD804269 +Plaintext = 23C82D6B59E566E4D3E3D7B8A92C24874C913B0F2FE1 +AAD = D11975E98891C0EAE1B7DC968013 +Tag = 803A98705EC108CA8D323F72AAD126E4 +Ciphertext = 61E52C6AF2A65A66E8C7E4CDBC989BE1B6EA9DC06D47 + +Cipher = ascon-aead128 +Key = 2112C1002F669D01BE0F64CE8A6E7A72 +IV = 2C2AD956D592C3BBFC35E76BD13AD977 +Plaintext = 4C1B5D12A83F1870290D2019EB85876BBE1CF21FB7AC +AAD = ED3D769FC91AC40B643A3902E192A3 +Tag = 539077177DD8B48B1B8242E329E7A2F6 +Ciphertext = C0C1F9ED883C464AD5CD07C9D6AE60F1F1475B5A71E7 + +Cipher = ascon-aead128 +Key = D6E77F9A64729FBAD4B79372B07C06D9 +IV = 63E98F054917B3D80545E1D69C9D6F04 +Plaintext = C7507B5722A489F0136CC81AB7DAD7EB4FAED151BABD +AAD = A933BA3BA2698003D5B4608F07EA3D53 +Tag = 7D23D14B0644AB75F6D84A310DCDE134 +Ciphertext = 6E9C061F3A3E27FB4DD402A1BA792A38AFD4D67FFB29 + +Cipher = ascon-aead128 +Key = A573C40C738871362424811717E6C744 +IV = D2E297EAD039D91E338674A6296DEBEA +Plaintext = 39BF2C39599A522113DE2501AD1BC6F2179A7CCDDF38 +AAD = DC0AD2066B1DD81B738EE2B82FBD166EEF +Tag = C75AFB16F47E31EEE145414C80ACB0D2 +Ciphertext = 75AB8D5ECFE793F36E46B2F50CFAB9E425F31E9B953D + +Cipher = ascon-aead128 +Key = 27A6500A4178B408B98102805820F56D +IV = 9D6B6DF408DB07E3250F440FC7EDC0FF +Plaintext = B96B7C258BEF3E3D621F722921B341EE9EB750F2656E +AAD = E34FCF95C4B106B14A737EDEDC5B2E080C57 +Tag = 17F9EB20C790044573E616ECC2FC9497 +Ciphertext = F83314F886BD4AA795D7CCE48AC0B20DE0C989CFE8FF + +Cipher = ascon-aead128 +Key = 6395B43F7262C49078A6244D80D5916D +IV = 6B1FC0042D3940DA46B889545829B146 +Plaintext = 383C728D59AF7AA5717F6553F4A868C51119819CA483 +AAD = 882FC2D675876FB62D2AE00D24FCFADE4223D2 +Tag = 464EA2BB62D5FD53E2535B06790A3F2D +Ciphertext = 5E0F7EC197472590D433435422368585E40FFD939A4F + +Cipher = ascon-aead128 +Key = 73FB4309CF876007CDF719B255CA39E0 +IV = 66AD9A0F84B2CAE171F54127DC364A50 +Plaintext = D4AB729814BF2488CD836FBEB4D4D358FA41E837EC30 +AAD = 7964E4CC5253EF333DBFB33275075E5A439C9215 +Tag = C3B4FB1396704AFB4B1DED6C0795552F +Ciphertext = 4C52B42C402E9E240A0D5A58AC37F2FA288501E5DE16 + +Cipher = ascon-aead128 +Key = B4867A7B4918A10A09B65327C2DDBB52 +IV = 3E06189F6A42E298AB2522D249876590 +Plaintext = 0BF7CC0E296D69511E296841F8A4E5A6DBF2A2BFCD81 +AAD = E111920642EAFDF59CB28AD306BE8AAAFEECCEBC93 +Tag = 46F77FBF0FABF361CE97CAEC7F720298 +Ciphertext = 787B0999B01C9F28E017FF45F28D63D41553C189FB33 + +Cipher = ascon-aead128 +Key = 49F0E7A7D514982BBF1D93D116151EE3 +IV = 23C80E060AC18FA7D40776DADAEB7C1C +Plaintext = A75085DED2B717DA0335C44A4ACE55B4CF4865106A1F +AAD = 406FC0E83239BBAF2F3F727625F823C1A5F346F85973 +Tag = BD7506E7DA85D7532B9C562EF4E88789 +Ciphertext = 0999307BF2155B69ADA13955F4C83E47AE1620409D22 + +Cipher = ascon-aead128 +Key = 413B2294D9B116050A13B2158AAB1C95 +IV = AFD9CFE93CE3B4FB37C89ED08E3D95DB +Plaintext = 4767F32FDC64A682E5545446D5897A0F940F68CFCC57 +AAD = A5C395B21A3140E629350A39C5CB6B7170ACA7AE9641B0 +Tag = 1D12A399379F96E7EDCC504031DCDF37 +Ciphertext = 3CAF2C91B60B4033FBCDD1D87757B59D2BF4123BD489 + +Cipher = ascon-aead128 +Key = E6A680185120DFFCE8C0BE422F56C375 +IV = 9688C30D9319F68063FD71F32BBACDB3 +Plaintext = 0F99AA7E2F55E48906570A33113F1B8771A06BB2B31F +AAD = A3140A7E5A99BC4144220F4C18F53BA0B43CF369690A10DD +Tag = 10A3FDEB97C288D33672889D69963D7F +Ciphertext = 19F85C9632920A2B86CBCE215F87B6D0FF609021D473 + +Cipher = ascon-aead128 +Key = 30A0AFB43DBFEEB4DF61AE9B491BC711 +IV = 56C7618A11D9D8E376AC9942B51F93F4 +Plaintext = 6E526BA0D6E4817F444C5D2F76DF890B5AF3B809B2EE +AAD = 32D539A9E5060DCF8BCC783CAFD2573D60D6DBAE24A6BD6B64 +Tag = ECF92E006D8653E30AE94B6E48B34043 +Ciphertext = F0BF36F08EED114797FBAA8A7091AAAE5D82416DFC3C + +Cipher = ascon-aead128 +Key = 5E2B7D1E2F21C3AC653E6CD3717BE111 +IV = 6986EDF0466387797F7B0E941A424CA5 +Plaintext = B188FCAAC521024A8A4C83EE5A9300DCD7D17E06D015 +AAD = 016FA492B17DEDDA28FF348CECBA0E9CC81C58E20CE3D60D5C11 +Tag = 834D10DA4394431F316F5426FBDADDD5 +Ciphertext = 12A2FAB0CB66AFA11841B52D6A2FC0870361D2D5741C + +Cipher = ascon-aead128 +Key = 1FE83EDC0E8806FFC44680BD248DC9BD +IV = 5C09521BF688C99BE8E4A82DE4AAE9B2 +Plaintext = F7579FB911D91720733B41F32FF3DA6E16AEAC559CC1 +AAD = AE296C215DD23884C29E5B1C3A8690DE7C4ED85E7B85CD4DD44E5A +Tag = 85A1A78044018A357C1B3C4862F4EE91 +Ciphertext = EEF542651762EA0448798D91FC5EF77D01F244B9AB99 + +Cipher = ascon-aead128 +Key = 127E6E79143811B31528982A8ACE1F21 +IV = CEF57C4D7EA92B6A8CD0261C1D223383 +Plaintext = BE728E2EF7B22CA2353317E0F3552AD86F671A05B33B +AAD = 432F20B22B9CB6EBD6FA78B5015D54DD81666F284C8E9463DC98E6EE +Tag = 0DFAEA950CE172557EC5629FD9CE7186 +Ciphertext = A1C527DA0D85E399744B8BECA75FAC0A94B1B3457477 + +Cipher = ascon-aead128 +Key = 1334348067CD9393202E190DE3BCC7F2 +IV = EFB7F1A5C2579EE315DBA5F33A5DB5B3 +Plaintext = D0260E8679B12F9DAD999D8A81AD3A6BECEC6D9D1306 +AAD = 866E11CD054A399F289135E33AF8298B7235BB2677D6460146677AE39B +Tag = 2BAF5F1AF31DB89B67A59E51753B6F39 +Ciphertext = B5C258A5035D9E22CE7204F9F186E9051BA876BD5440 + +Cipher = ascon-aead128 +Key = 524121C11BAEF95050130E759E35FE46 +IV = 56D17317C36D7CB1C87198E43F4DD30A +Plaintext = 8B12C6594452719D1C42B3386427311BB62576E2A395 +AAD = B1E8BEF11D652CE3D54F8CDA91A536BA67A7B592C2CDD1F67F546D3D1833 +Tag = 645A218C3F724421D1CF049FFFD27E8B +Ciphertext = 151ECD253CAEA4CD3C1EFC053C34E861C493C578AA01 + +Cipher = ascon-aead128 +Key = E3AD0B68E432887F673065400E9F8C7B +IV = 20603F542FC2317ECFB5D02E4FE634E3 +Plaintext = F95F78E8727A81D590387F2DE5F56913A885D997EE64 +AAD = B8CCF17993F73C9ADE111924577333ACA10AC73CE9597F7EAFE90B2F0D10C5 +Tag = 55217C84C97E032E535C474C1A83092C +Ciphertext = 2541A5B54D8905F0974C03232F2F07541D632B5A68E2 + +Cipher = ascon-aead128 +Key = 5C6162E1D8DF6156EB595A5C1174B74D +IV = D96BB4A3612AD1B77198AB3A8FCF909F +Plaintext = E243289434FAB8D27B5296B5C2A62E3C53C92C7E8CDB +AAD = C51C20EFC03AD5B8EBBDB362555D9FF9135DC518B15E77B8C8B41B8DCB003E27 +Tag = 80E97599AC481EA2A50087130853C138 +Ciphertext = 52C19DF30CFACAD3B47CE8265AF731DDBEE8F0967227 + +Cipher = ascon-aead128 +Key = C10F101778D63B0373FA580A6C1917F6 +IV = 1D863FD2BA5B7E912B852D8A97BDFFF6 +Plaintext = C7EA9B254338C8D9672F5D79EC9D88C703C4175148D4D9 +AAD = +Tag = 2A1BBEFF708D4BCA899E8354215FF8C0 +Ciphertext = 8A90A726044D1332359914CE1AAE21718D6EC72317451A + +Cipher = ascon-aead128 +Key = CEA9D536ADCB6661C2BBDB2D855CB8E9 +IV = AEA0DB6802A50186E179DA7A4BA0BDC6 +Plaintext = 17B4D5FFBF4153AB4478A96A7359B03D7514384BE742CE +AAD = 23 +Tag = D3E44C50376019AA84E52D99A764D3CD +Ciphertext = DA43B8BA91BE6445FD421C75F2BDB130083411AED28803 + +Cipher = ascon-aead128 +Key = CCFCDF02A4A9D5226EAD2BECDB6F601D +IV = 7960CF20C5A15199E34DC9E78FCD2360 +Plaintext = 74AC1EB2D416E6CF06F907E3A74F793C95C55DD427E278 +AAD = BABE +Tag = C607A8612CFAEF1DCD5C621B5DB3758B +Ciphertext = 64D81179F9FB93FBF0CCC884FAB5B3BA327DC91A28C1C9 + +Cipher = ascon-aead128 +Key = 37577FED57490D4D43C5C15483D15F4A +IV = FA5797283EA9ECEA03BEFD50E1CE1A8C +Plaintext = B7AE54FFD98AFAB6681F1A040E187E49051143D1959608 +AAD = DC4B62 +Tag = 2388A07F632CC1DA88122FB2EFFCA0E5 +Ciphertext = 122D6D0AC693F91578F98721EF7781D5617F14130AE84D + +Cipher = ascon-aead128 +Key = D9FF1B7D05C4F6A39A2A6A5200CE9936 +IV = DEF8454D86003FA9C6B23B07BAA95FAC +Plaintext = A857D4FA84BEAB91161EA0BA613DD46712FEC26BC12F50 +AAD = 42B14CC5 +Tag = D656E966F2EDFB5DA015F1425DF37315 +Ciphertext = D3CDD3B117C7AACD2991646060D6A06589C941AE94980D + +Cipher = ascon-aead128 +Key = 69274E55246AA3D0F1F2F88FAC466D13 +IV = 8C2C1C4D25AAF896E0BA18ED3179CDB9 +Plaintext = 4BECB50D63E1BF907F497DE6FFDD73EB9D2B6BFB77C2D2 +AAD = 7BD9B0826C +Tag = DF0729432A1A303ECF363B67C727D53E +Ciphertext = 9BDC75456F49AEE8858AA3478C8433D9DEA22EFF462C76 + +Cipher = ascon-aead128 +Key = 5350C49517012331A94BAB139166B1EE +IV = 787019659AAAE4CF0BD120D96780BDED +Plaintext = 6BBC50B096224BFDCF64AE99F867C0213C51C06B00FA7C +AAD = 35F58ECA95A0 +Tag = EB593808A96781DDE9F850853527ECCC +Ciphertext = D3399B50C3E084C87DB93FF7405FFE9E237773136AC3E3 + +Cipher = ascon-aead128 +Key = A31886B1100BC7688D2A835876A136A6 +IV = ABE35249689F00185823B5BD9F5C7092 +Plaintext = D47964AE6873F35F3DA4E1B6E4AA89D25AB3C0AE3FC625 +AAD = A4FE2AE1C05E14 +Tag = B4EA8F8A4441160739D1A5C59263C35C +Ciphertext = 5404E35D6D0CFCACC2EA18503457D98D3C4554C1ACB7E2 + +Cipher = ascon-aead128 +Key = 42C6A5A7D52AEB3FED8EEB83FDA20C03 +IV = 9ACC9D3CAB2DF67169ACB426FB0BD972 +Plaintext = 765A525862A217E447DD955F9C49DD6E91304AEAB1E740 +AAD = 2DE78082C4E77E41 +Tag = 6A981EEE96E8206C5892CD3FE996444F +Ciphertext = 1E9417F0B72E09519D4DC00FB79123F28F0BE022DEB51D + +Cipher = ascon-aead128 +Key = BC860CC413D1126B4DD2B13CE9175ED0 +IV = 23E302BB67435D24678B681FB19D6808 +Plaintext = B0312C0159EFE228162D394BFDD61763A5F442B0EF3A47 +AAD = 18EC2DA051E93CEAB9 +Tag = 8154AF7367D35860A6D35A4DE427FC8B +Ciphertext = 083015BA15F0CF5EB24FB9460337A91F39A7B74350F908 + +Cipher = ascon-aead128 +Key = F6BDAA84EF7B4F769DDEA671FC7848BD +IV = 7D87BC9FB7DB9B83C7934B6B3EAFB571 +Plaintext = 72039D9D912E43ABA7EA75B30280191C9F3410EC13FA1A +AAD = F6833456358C990C3C77 +Tag = 92392B024AD3F5A8D7042E519CBB5408 +Ciphertext = FA967AB5535A2F4BA349976168B519023E6B1A4D431FB8 + +Cipher = ascon-aead128 +Key = F98443DEE66AB2C335EABC61B9471F19 +IV = 3C5E63EB15ED36844579D0DB3FE53726 +Plaintext = 86DD3A16B85B9DB539B208D3BC21070E7107D05065A565 +AAD = DF021A515CD054A31F7E20 +Tag = E628486396449526FB701A1F21C28757 +Ciphertext = ABBD26EC76F982E097648037443A98D7AEE03A83B6154A + +Cipher = ascon-aead128 +Key = D8F62A29A037C471DA0828BB2C080E80 +IV = 2857CED1E01F72D4E8E5C2DC3EB2B9AD +Plaintext = 81537EBA10D1057F3A3D8E552A2A7B0935E8065634ACC2 +AAD = C12EA7F3E351DD1156063883 +Tag = 21252D930595E35261CEAEF12189593A +Ciphertext = B90F11255D51BA0CA1F3F3F09E79C23B1F0209EFFE66C2 + +Cipher = ascon-aead128 +Key = B8F8FB03B16F2B3E755E5B9AA548F224 +IV = 9E6BFBEF3A59053F586E23D05462CF5C +Plaintext = E82FA64654A06BA94D4D189F348B51121E8F7CB128C343 +AAD = 962E8084CD1A0A660618AE2684 +Tag = 69B7456A37F9D2C2AD7686D4F242C85B +Ciphertext = 100C208EEA396D977936EDA4B5D89491466C5570163BA6 + +Cipher = ascon-aead128 +Key = 51F58461FBB8617DC5D6C748B9028290 +IV = 97BC2AFCE470F1A9E6334D1326D651F3 +Plaintext = 50789945B18A99293E2EF1FA4D32A12DDC9CDDC85B5E39 +AAD = 04EBE97DA98050BB5F8A851DEE6E +Tag = 1E2C5A71FB8DCA315B6C46F0A5C1ACD3 +Ciphertext = 63AC2F8E46AC4DB703D17798571974BE965BB690179F68 + +Cipher = ascon-aead128 +Key = 92A7E8DB8531B6DF983F59850DC886E3 +IV = 16A777CB551D02428A12777F1D2AE0AE +Plaintext = 8584377FB926F987CEA3B341BF55B0E80F6C9C84224C10 +AAD = 8AF65334EAB083FD01259E3DE5781C +Tag = D502FC4EFBE3BFCC37861484F44E101B +Ciphertext = 5E90CA5FB72A6F80B26943B9EC8D7A9253219D8AD2C7C3 + +Cipher = ascon-aead128 +Key = 18F640475E0A7B4F33093DE3F99DFF7B +IV = DE8F6AF17FEE4BD4B89A44D3C8AE8B3C +Plaintext = 0ECABD9A1934E3A1882D24917123BBFC6735E037E6B173 +AAD = 0C44644664D2F9A557F019D3156EBE79 +Tag = 04BFC46536E59AF9855314B4C39BBEB9 +Ciphertext = E3C5FC1D08FECED829B7DA855221F2C01B9CF9C298CB33 + +Cipher = ascon-aead128 +Key = 066D552108E19E0E6C6C8792F1392720 +IV = 046C02F350B0B678DEB91A1241FC84C0 +Plaintext = C71A7F90D1A5BBC34B99806AEBC136773FA3CBC95B24EB +AAD = 4566401C578252C7E4245F66185E7FD57B +Tag = 22C756721AB69386DE8AC1582D748E04 +Ciphertext = 9B970472AE4EC0C57AA6EA73F9266D3451A36FCD075EBB + +Cipher = ascon-aead128 +Key = 7C77FDC670D64536808EDB5814FB0BED +IV = D63EE4ABC3A8B0B6C79130622F472573 +Plaintext = 44A0E7D4842E133E8C1159A06C80E57BD6459F1F699576 +AAD = 4AF5F75BF7C47A20116271E2CCACCC3286C2 +Tag = 45A20422B9C06E9CEC7B95E256D91037 +Ciphertext = 32BC0FD206C8D02B34278577AC87660719448865FCEEF3 + +Cipher = ascon-aead128 +Key = 28C0F4DF1457E0CD734A8058BC8EF84F +IV = 1AC0CF9A651D417EBE49F88A58812FD1 +Plaintext = 268A93714B06057B67AFB76552007DF0C1E169A6BF2F74 +AAD = 6087D13CE91F0D29DA41083817C5DBD93CDA44 +Tag = 893120EF858CD55D5C4C07BFA9CFCE26 +Ciphertext = 342233292D8E203AC73ECAB33B70C867A9E42BEEEB47EA + +Cipher = ascon-aead128 +Key = 95D2E3E9A4E33D710324E545442D371A +IV = F169956F96C8ED94065CA78733EE49B4 +Plaintext = 6E21A10F7ABB6E9CB947A27B4744D6B7BF6D1FC3AE36A3 +AAD = 05727FCE59C2E1709C3C4B2B848FC3FB724AB5A0 +Tag = 601D5FE65EC4B64970BB742AE6A70EF0 +Ciphertext = D7BD17231C8AF42FCD0F4D1C1BF5E9F7374D40BED73D45 + +Cipher = ascon-aead128 +Key = 9EF60037301492C0AE49B18AEF9C5B43 +IV = EA59F4CD702A1C9981B9EDBA9DDE40A9 +Plaintext = 72E3C89CC9D329C0F3495E6A07A1A9AACBCB17E433000A +AAD = 4B073E64EAAB4BADFCFD36236E4C08ABDFED9D28BC +Tag = 86BFA6A9DFEE714C9C434D70FBA44834 +Ciphertext = BEF747B087CC13548091F8324555D6DCA1BBD8C3348AE7 + +Cipher = ascon-aead128 +Key = 64C1E001AC30E152850D216471924437 +IV = E369C4140253D40408E370E3DEB15FF3 +Plaintext = 95F6774F507D61B196F75315F6A32DC2D0BC517B58EB3E +AAD = 7F236C74BC961EC1552DC7B6CF8C6D2A947E4DB68955 +Tag = B3FB85FD3398C5FD4F5DD4874A869021 +Ciphertext = D4AA7EEEAB78C65B2AA681DA9D35D5740EB1D19FD2BDE2 + +Cipher = ascon-aead128 +Key = 157B124CA8AB6198855169FDADDB154C +IV = EBCFE53640866A4E472B86A71364F269 +Plaintext = 4FF17DFEEF8ACD82878DC37F5CA518292446B6CCFC6A0E +AAD = 027873467BAFC1D8FBF3C96C4C44C49A7CE000793FFCC5 +Tag = F6F04AEF415F2FD40F744072E6537BD9 +Ciphertext = B0CDAA271B689AEF14928B233DFB3ACCCE75C210AC5141 + +Cipher = ascon-aead128 +Key = 493AFEBC7CF13575614296651A2E1466 +IV = ABDED9375CE93AFC89529D72A03DED1A +Plaintext = 73223B1EC863A0A0E672D1D37CABC712AD6508B3095AA4 +AAD = 1B2413691142FFA9719F5BDB022B1AA0A830FBEA6C905647 +Tag = 7ADBBFFFBA6CE4D8DC76E98BF902C48E +Ciphertext = C0406E590396D26D00210FB52B8D179E23E2369A665395 + +Cipher = ascon-aead128 +Key = 7BEDF6F1642C63CF42FE2F8CCC23CFA6 +IV = 77A87EDB3499C52BC4EFD5D71B289A2C +Plaintext = 598AFE7051891992AC88D8F851C9005C428F1AF56BF66D +AAD = AA44BEF64B62889905ABC1909F31E2FB1B81E8AF6BED6F0E56 +Tag = 606016478B5453DC7B791D3479847552 +Ciphertext = B76F725674A8E905EDB7C82A80A1AD8C042D4F2A46A1E2 + +Cipher = ascon-aead128 +Key = 5A2FD68C2A272DC497341A6856B2C472 +IV = 8362011D9446CF72B400D8970CD55687 +Plaintext = DE76940055BF3A144EDAA6CC4C312FF84BED544D4E4FAE +AAD = 1DB57739E1B03D95C0580AB846D361DEEA867DB597D383A49892 +Tag = A3D4BB21D2CC0C2AE9984C032F3248AE +Ciphertext = F4A983F1E36D140337B205B326EF4554A08E0863260B89 + +Cipher = ascon-aead128 +Key = 6CAFF8951D33CEE8A318FC22DA12328D +IV = 45580D8828335028CCD57DDE88EC707F +Plaintext = 0E8700DAE1EA4AB6FFA124561043AE395BCF99346C6614 +AAD = 3F10A7B79B36CE7927C3B6F0F559EA761BCB1E3F5AA2507C25DDFB +Tag = 4C8065E182D560C83E8E567D64DEC371 +Ciphertext = B4EF110F8FD1A9EC3820C8E4CEED4D05BAC19C2AC8940A + +Cipher = ascon-aead128 +Key = 09E39D13123CA05CFAFC16727262977D +IV = 3E833E0C9895928FCB942D0EA498DC4E +Plaintext = 893844191AA87A26FB5924DED2667EF50467C2F8D1C4CB +AAD = 65285592B7084303C70798DBCE1F8E358806AF6E04D35D2A166A0B3B +Tag = AE67344926D6A703942FABC5E86ED218 +Ciphertext = 81DFB567ED9C653EA7098DF049C8065ABA80BEE606BACE + +Cipher = ascon-aead128 +Key = 608513A52322366CC82172AB1FFBA882 +IV = BD3A86B929D8A2D19FBEBF9D4011A4D7 +Plaintext = FE96F51E21A6E6023318C83D24609E6AACE429125A95C7 +AAD = 53F6C8AEE68F449B6FB38DA503D05D3A8A48E243F1B81CD9E5B23E49EF +Tag = 7F344B2C56ED563F4E56C2FDE49CC010 +Ciphertext = B2BD684CFD3B52644DFE7295C13835FF6678D2C14EF5B1 + +Cipher = ascon-aead128 +Key = F4DABD16497EAB41AE81F9DCCFDF9878 +IV = 9171C65927F3F8554DE38DCC930FB374 +Plaintext = C4DA882F892D378B882EF5CCFDEA08BC83ABD16D9FAFFE +AAD = 7B3297657964E0E300C2BF8D5E3BFED8C56B264A80C55B00DBBFF348BBBD +Tag = ECC2FA4C1EC85FB69A3D58BD6725D849 +Ciphertext = 822B9F91CFB427518FD5A4B88AAE664EFA06851128EA7E + +Cipher = ascon-aead128 +Key = 8A8855ECB12BBD550438121FECDD59F9 +IV = 1880998182AE519937B5F99DA29FF914 +Plaintext = 7F39A8120B6006496AC65689D5D9639ED05765B4125429 +AAD = 0157DFC07F10C97FAFA18A3A43B8B632A584A7F99BBED1C58AE4694BE1FDEC +Tag = 92E27269BDFBF77F95436C8B6325DB52 +Ciphertext = DA9604680B4A999F4E71B9AED6FF802E408DE33BB5114D + +Cipher = ascon-aead128 +Key = 5E010585032AA643E2609632BFC8D7AE +IV = A8894031776AC2BA1CDECC02B35AEA3A +Plaintext = E86417002C3C1254457F492DF972E3499EDAE9434A3674 +AAD = 421A7F0A9309D9FEE0B37980407718C54AB2F90B629DD944165521C54BFB7A38 +Tag = D16DD28155D34002518F28F79A57CD3C +Ciphertext = 020275B95974ECE26815C28E743D4852F132AB0A6FC8FD + +Cipher = ascon-aead128 +Key = 5441D0F2A74887703972DA34C652C791 +IV = 94C0E9B5A2FBBC1FB7D2998DFF765F91 +Plaintext = 468547FB1CE08ECD418485B062C292585BE648F02A88C196 +AAD = +Tag = 50A6B917501F00417C83B54C45C32B04 +Ciphertext = E5FBE3807C094A3F628828AB5B67538BE2ACBB661162772D + +Cipher = ascon-aead128 +Key = 15ED208679CEB7416F10A74C99DFC76D +IV = A9E2F6B546B7E876B4721F2A98B875B1 +Plaintext = CA3682FEAB4DA7562452525C515C99A6437F92B6265BAA01 +AAD = 8F +Tag = 5ABC7B251E97363E9B9B516B974D4DF7 +Ciphertext = B200B268F53853FD6E92A567810AF836D619A8E4579339FF + +Cipher = ascon-aead128 +Key = A707BA4D563CF46336B29C8A5CFE3A87 +IV = 989E06873C1545BB8708645B237A2AFA +Plaintext = 1C71B36228FD82100B0FDC9E1F26F3472B41153474DACDB2 +AAD = BEAF +Tag = C917FA343EC0FA69EC8F442820C8E930 +Ciphertext = E57B4F364DDAE56463F29CDB159FD4CAF5902C54F9A723B0 + +Cipher = ascon-aead128 +Key = 4A2449B29C31201178D7AE63E9D70DC6 +IV = B4058444B25416353882D0A389EC3057 +Plaintext = E5A22F96D7AE8AF29F6578FAD3F835CA91688FE2D127F6B6 +AAD = 267AD0 +Tag = 4CBB596DBCBB0F3B98A6600D20CB6228 +Ciphertext = 34D0ED1E531F0BAD047E8B4BE5FCE2DADB60A89A217D89CB + +Cipher = ascon-aead128 +Key = 677B779FE2BB8734B5E0EA4A3CAAA4D0 +IV = 4F7BA5AEB066316825D9AD953006A247 +Plaintext = 047C69BCD36CDC326F4C8AAF9461517654C5098B8C4AED67 +AAD = 90273DF9 +Tag = 39B9004D935F4B4A78383CE00B0724EF +Ciphertext = EB9084B97C378B2DDFC9F197D023C11FC640BD76C595A0E1 + +Cipher = ascon-aead128 +Key = C51434C4BAC870FE9DDF2F6C51E856D8 +IV = F7FF8021DFBBA654E2D77787471DABF4 +Plaintext = 98CBD248BA178F75D0D8ADC712E67FF7DF532B539F3EA009 +AAD = 60239EA27D +Tag = 273117023E4F2FAFFB4C55BD8BE6478E +Ciphertext = 6D0BA2791A0AF7D69BC8BA9F91DF7EBD25D622640A888D7C + +Cipher = ascon-aead128 +Key = F40FC39EBEC44BB56C6FABFC260661D0 +IV = F31E133635BF90EBC9D39DD23C90B596 +Plaintext = DB907EB5158481EA8BCA6E8C23C71834D6FE33D7339DD625 +AAD = 7DB9F68D3EAF +Tag = 33F3B042ABB9B1D0C0C49D93A73B8CEC +Ciphertext = E660A6F9F0F2ACDA64A7D7CBD474EA4867AA8BEE8FD0496A + +Cipher = ascon-aead128 +Key = 8F609C48AD809C630519175FA0B8B55E +IV = 99F191432D8BF9AFC96216675D4EAB30 +Plaintext = 97BC396E7B87C8D8F2924EF4F549BD69106183D68FBBE16B +AAD = 2FAEEDC34A594D +Tag = B3A778D39AC84F508BDF75DC888DE969 +Ciphertext = FD6F5B183BB4C04FDEA1815ADD2EAE807A3B76C0718398AD + +Cipher = ascon-aead128 +Key = C01F0EB19F8BA0FD321F321DA9B0CA70 +IV = 00B6F38CA79F48A08E89BFE8A96C677C +Plaintext = 9EF6812EFA60697AC9E41E992F7A3197DACB002ABA06A446 +AAD = 64A77E94CAF4B995 +Tag = 6C58E623254D3DBF3F0DFC3238DD23DA +Ciphertext = 25B8BF0260D360FD1BFCEBD6BD2BBF0845843CB11CA476EF + +Cipher = ascon-aead128 +Key = 4B7DD709DD78EA2F6E98F24B00C3B514 +IV = 2F65BA7029AAE1960FF2E1ADA7E3E1A3 +Plaintext = D9A152D05509D714C9042E9AD2F1F29CF529C809B4F8BEAB +AAD = 412E9610BB4E558440 +Tag = 6F9983BFA848EB4B54A74B78A0C305A0 +Ciphertext = D1A649C26A3BE385A9F85DADD8DE9FE29381324252091923 + +Cipher = ascon-aead128 +Key = B0DFA52010EC21CDEB9C00888664E5A2 +IV = 8D3FDE6DFF4AE90114908581FCF96401 +Plaintext = 0585DC5960ED9695F4507810472224C671F60D451F6A0F1E +AAD = 8844F2094D24709B31EE +Tag = 2FEBE42B59074E2A4A9BC20B0508B04F +Ciphertext = 44EDDCC57DE8193618B29745C2C58B15A8A2BCA9D902F157 + +Cipher = ascon-aead128 +Key = 3862C5AEEA3672516D8A76EEC6A35EAA +IV = 4DFC81C35D258699A3C2E9A5ED2D7930 +Plaintext = CCF7202033DCF491942D493D036D3403223FAB13EB9A2BB1 +AAD = 8A4758428EE6AF6DC9B649 +Tag = B21B829B59979D30412EF5C5D253A965 +Ciphertext = 8AE32CFC22D27084851C25BE5672F60917C92045CEA3BCAA + +Cipher = ascon-aead128 +Key = 2683E869164180E2A273E7E85E8A31FB +IV = EC793B54B6A0EF332402D62F8E66BDD0 +Plaintext = 9744B8A315DDA7E65F1A6038FAB9912BA50591D4435B8716 +AAD = 06FF5321213761D750CF0B86 +Tag = B88AAB57A3118B8A660D38BDF37ABA99 +Ciphertext = E04FA9BB6D47A2D053C2A7C2CDAF389DAB30828262A36996 + +Cipher = ascon-aead128 +Key = 4B4B01AD864B29E57E346A300DDB2AF4 +IV = 91B0525FBE624FC3429F391DCCB0B9CA +Plaintext = B538A6F935D1C788646FACF244C5D92037227011EDB2B66B +AAD = 3F7712B0025B479D173B3D6D37 +Tag = 16A08525CDFA2E811BBE77EC589D709E +Ciphertext = DC9D880524768B7696C6026C4071DE8AB8CED27FA562BD2F + +Cipher = ascon-aead128 +Key = 534C0D1EE68B46FAB7892AA5E8EC5E57 +IV = B7DB72EAD4F17E1A452B8C17BB4A1FEA +Plaintext = 91AF37B704B24A30B801CB90EF07D760D7F47E9D8A24ECC9 +AAD = 3719B5B70BF3050BEBE3716B4058 +Tag = DE1799A212BF3ED5E351688BE95D9E96 +Ciphertext = 097D6CE8957622BF5566E83817B5D0F02524B87570166FA9 + +Cipher = ascon-aead128 +Key = FFD17F8C28790B7CCEACC4DF671FF5CE +IV = AC68FE15B312861999310CB54ECFF1D6 +Plaintext = 3E0976EB2B677A17F269739FEA7E0576F6A9221C07CF635E +AAD = 2D2F75B97C1600BF2E3F67AB5BA79F +Tag = 733B03941FC1E2AE70B2298E9CD74DDF +Ciphertext = 3B1C841FE728342D11658CDB377F5A807009D9601DFC1351 + +Cipher = ascon-aead128 +Key = 97EAA66E0E2A33D9DF0FD88F29B45AE1 +IV = FA9E5F04FCC3E80CC61BC5CF36E51D14 +Plaintext = E0D8A1331936BB437D2F8A9FA0D074A8385D756B2569180F +AAD = C899D7554AF31BCC7C8F095D28D6F093 +Tag = 72BF56853D13C755214B83B570F2D1F4 +Ciphertext = 012C42A507401D6E948D3824671A457FB592AD514B2E3B6F + +Cipher = ascon-aead128 +Key = 2065785D96548EDC32B0F72D18C1EAED +IV = 7E44A20A2AD9E5EDA969211B31B231D6 +Plaintext = 6F4580B50538F0922B69359992B098BFBAD3B46B3C3AD82B +AAD = 61698BA78D086D38786286924B072ECAB1 +Tag = 26915552804D41F062C22E6ED093E6F2 +Ciphertext = 8E741877C8AB128C3DFACDD91B3D3338491D5F88B533625E + +Cipher = ascon-aead128 +Key = 828DCFD5FF20B94682ED2AE69F3E875B +IV = 0C971C6387070919705DCE0B030DF71D +Plaintext = 8797E7C7F8752B3257A484460B4F36010153FA052A4C60D3 +AAD = 355EA3055B7FBB3BDC915F3D849C907648F5 +Tag = E456F622EAE7E7CA65B71DBA801AE47D +Ciphertext = 97B342FCA3C6C13071066AB106547021DEF2556EAC44423C + +Cipher = ascon-aead128 +Key = FA447077A353401CB419EF8EC0C5274A +IV = 31D2677D9E8F24F7A5940C913E7AC7FB +Plaintext = FFCCF4B4364CE99EE59B0BDF49DCD3D335D0B69D2A3DC9CA +AAD = D273788D061A1C8C1320ED791A074F16A3D0F7 +Tag = CAEC4A78420DADD5FCB919B2963166CD +Ciphertext = 646D79F3EAFC79261A22D8E5F49D865A01E2C86A3B0AD884 + +Cipher = ascon-aead128 +Key = 0BE9209FBD2E4C85C823C526E95D3550 +IV = 3AE36276414C73B58CB8C672F0FBE590 +Plaintext = FED6B0C1346B6AA01FF278C03FA5ABB8C66E6B4C6EFDD81A +AAD = C3ACC816211CC58D2F18CC5F50C9CE638AC9DFF2 +Tag = 29A9A22502225C96BB58EBB33D579886 +Ciphertext = 9E2B8EF71527F61932CFC10BCF9CA887C89339AB6943E1E6 + +Cipher = ascon-aead128 +Key = 1DE715223B7AE1C404188A473975E8D3 +IV = C4EA87931B6C25386537B21173148CC3 +Plaintext = A4819E9D6F51F9544A67503AC9C41FF0B0543357E7AEBF27 +AAD = 6D443D952AFE7E7F03C511E28731CCF074FB429CBD +Tag = 3C343FC72FA216FB5307BEE7E6245CFE +Ciphertext = 09575EFA9B4012488A7EDD6B44C85B7DC8B64C52789F6567 + +Cipher = ascon-aead128 +Key = 24C7A64E7399B83187146ED7E8DFA7B6 +IV = 09D2B56692B49B937E9C907A19EC7DFD +Plaintext = 1DD8126B6600727BC54C3D01A75B9DB76517AB8D0B5E00E8 +AAD = 0CA2454155A530CEEB1E47F172B6F0769112F1C60885 +Tag = 01D99A075CB78E4BA851471A9CEBC723 +Ciphertext = B1FD10E491CF9E2B46D8A3F3A58E31C8A601EC74ED42D332 + +Cipher = ascon-aead128 +Key = 9C1EE740E5E58B5BB35C81489644DCD8 +IV = 14B8268B46455B93B19AE1BC01D0C241 +Plaintext = 6A9A8AF282E2A39985D2A7BBAA23A2BB1215A3F6AE692B57 +AAD = 9EBCDAA0B3F0B39378844028284F0788550212EE7013E7 +Tag = 49ADF37BA0C14CD3B6E0742383DCBA7A +Ciphertext = F2EE45D0ABBFF62A9283B002B8E8DEC3606942520B56FD17 + +Cipher = ascon-aead128 +Key = E9E84A014EFBBFA8C75A0A5478C94E10 +IV = A61062FE26CC977C11C36C7E240B6C13 +Plaintext = E40074FE40C6F24FBBD939146BFD77AE43ED48802331097E +AAD = 96DB806DBCD863B90A0D6956CE28C9979FDF848F616E3F3B +Tag = AAEE93F6AFFB66475BF06F11A6B288CF +Ciphertext = CBF422D7C5716C25826F4287020167872D71B1FD1AC6C410 + +Cipher = ascon-aead128 +Key = 87B50DF9E1BCD30597FD6880B655D03E +IV = 38B11ED96C91ED1A214931F73A57CF3C +Plaintext = 76C325A619AD828B922A5A3F41FAB7272E0E0B3BB765B288 +AAD = F588E6DBE5238ACD8EE36DD87B3E672935FC4FEA3479222F56 +Tag = B8E9B840D13EE7E0E57A95E07D13420E +Ciphertext = B4B0090726557605A39C7E1BD69CE7861B5CD675A3903BC0 + +Cipher = ascon-aead128 +Key = FBBE228034E4D6D8DCB0F26DB72D4F91 +IV = DDE850429CE8EB5B08FC9DC32416A073 +Plaintext = 72D92A65AC8EDBA65409FC1403247B18FDA531B99EF733F7 +AAD = 2EE2F6A5EE344D7BAB679F8C55075509911275C4BCB271D78A49 +Tag = 023C36366BD3E50A6484D66FEA7F41F7 +Ciphertext = 5227ED77962FF287EC348C5F5B9DE5954EE01B5B7B4D7AAB + +Cipher = ascon-aead128 +Key = CE6D3B2557C5E2B816C603FF43C8473A +IV = 38E78441B4269812D561F9A346C9338D +Plaintext = 52D6EA3E49EEAB3D16F84604776DB4AEE354111AA345AFB2 +AAD = AD7DFAD87DE2FD0CA14F1F2DCEAA9D05891BFD8BD79AE9688A2734 +Tag = 01F68C68B3A233404D08CCA23DC258F4 +Ciphertext = DB298C80836648F7DD63C3CE35E75270C42D5C36B10C41A2 + +Cipher = ascon-aead128 +Key = 0C1F3B1BE6AB9B1233C13404A9F3BBAA +IV = DFFADDB21773A27A4ACC87A070319898 +Plaintext = 523135E474B4BC4E185BF36AAC37D29DC2FCBB9221BF0F8F +AAD = 00B36356C19DF314576DA6AB7CC5D44E2533EAEC491BED39533C6C6A +Tag = BDB0AE92828F2F06259D6F82ABC66DFA +Ciphertext = 1BEB179944FCF50134FCBC03C4A01CB67C5A43DEA8FD6273 + +Cipher = ascon-aead128 +Key = F3061420AEA9FE46E1AB2525D6A2586E +IV = 28CB8DB9175086777441C6BC371BF561 +Plaintext = 1612D370AE98204D6AE57ED2728AF5AD4EA0CF722A2BA306 +AAD = CC8D9B9184C96C55F8EFFB845A0B55EBBE98D8974CC883B5B319CDF223 +Tag = 6A8651FF448182B6E8F2667699BD20EE +Ciphertext = E7C010C0ECCAD2DE59EE539DB90D9820F72BAF85BF3BACB8 + +Cipher = ascon-aead128 +Key = 88CFC5D49E21DCF2E3B0DD85FE9E4122 +IV = B84B271D0905C0D24B419BBEDEEA81D5 +Plaintext = 623D4894E14C18ECD22C8C3D4D2F99CC60AAFFABCEAD74FE +AAD = D9B372C626A20979D3C307C555A3446B8DCDDD9159EC13C7C547BA7E8E0A +Tag = B1049E0DA79ECC4B6069285003DFA311 +Ciphertext = F0A92AE4F2CC30EE25E3A205AD14781702BA9D0F5023D868 + +Cipher = ascon-aead128 +Key = 1420184BAA9CE26A27BEDA7B254BD72B +IV = 228CADE14EA13ACBE0BB4EF48B098C44 +Plaintext = 3986D5BD5BFBC4734D0DD45DA7B9D03006CCF7971F49646E +AAD = E8B9BDDFDFCD86F052D4FECB9B45A72255F2C969E30EA3129AA0FADE406DA9 +Tag = E11B3F4695C37B8E741C146F9348FE61 +Ciphertext = E3D6F583E217D35B4C63ED14BE8D1E4DD4B60FF76B7D2CBA + +Cipher = ascon-aead128 +Key = 02E6D826E540F9009B7AB8E3D3876F59 +IV = BBB14EFAC516D0EA672651D07658B109 +Plaintext = BB8BC5FDC9CA554B1458973F89B556CD9FAB860D106DA7BF +AAD = 94016B8D4992B819188B08EFF77BABF0E93A678BE75D0C57F9371A17505A733F +Tag = E1A4E553B1130E2DADD0811A2797B242 +Ciphertext = D0AF14F30FF74093B32E4587C83011C2647ADADC0D1A4B2A + +Cipher = ascon-aead128 +Key = 151F38D1B413BE3932ED10027E363DE8 +IV = EF3172544489EFB31C034E56BDC0A947 +Plaintext = 1C676A21671B985B36D654AFA7242AEBADB1436D3AEE60439F +AAD = +Tag = AAB0462CDC848619DDA0C6CDF2D6004F +Ciphertext = 3326192019810CABA8ACA75989136446658A0FE582EA53E57D + +Cipher = ascon-aead128 +Key = 80B9E23A7163855B73799A52A4117A61 +IV = 7CAF9CFCBCB1CD006D903531BD6D7A11 +Plaintext = DEA9EC4BC7690A0876A97031263FD272CFDE870E5CC93B0616 +AAD = EB +Tag = 3A3DC80AC852ABB6DF16E3AE06565BCB +Ciphertext = 3A683EBE9F875A7A8DF4E9271F4DC5A22C279EC3051AD64475 + +Cipher = ascon-aead128 +Key = 947F127970628661211E2C0A04CAF0B7 +IV = 8BBB822EABAAA46524F50F659CD2CDAE +Plaintext = EC4797937F5D43B2E7385612E39F3432493D360B2FC402B46A +AAD = BFF2 +Tag = A45FB6C01998380DE53B4791B78C7D40 +Ciphertext = 6CC9576F7F33C053AFB2F8539D0C73BB7C76F2C95AA7309696 + +Cipher = ascon-aead128 +Key = BBA3DF7A3D5E514B65485A57FB569AC3 +IV = 238409D1A4D950B3E14C47CA257D2718 +Plaintext = 4CF85872B2BC312454D825FAB2C031FF0D1D2D566CB4150CE7 +AAD = 877BE2 +Tag = D6027EA32DF5618AE44F2BCB315F6394 +Ciphertext = B03EECA7DE90317228F3B5BE6234A70B3BDC9B7993C7F9141C + +Cipher = ascon-aead128 +Key = 49FA2C90DD9920C8DBCC17288F78FA0F +IV = 2E36CF1B76D7926F1A3EB9002CE8F496 +Plaintext = ABD9FF510A44736AE619D8791A9276494CED063B8BDC4F0B62 +AAD = 33247F7A +Tag = 670668B3E7AF00C9B0EEC72BB25571D2 +Ciphertext = B1413680FE8037ACC8634340FCB23431E3B0DA1FE48AEF1547 + +Cipher = ascon-aead128 +Key = 2C6AECF750E030920D6776AF82F68987 +IV = 4E0B7750021B48ADA26B12B1987E329D +Plaintext = 02E10C0EED0E6BD54EE933007883A3D93E3572BE4D7A017506 +AAD = 8CCFAEBD6B +Tag = 424711D802020EBBAA4BD59D15C5924F +Ciphertext = 747C6E55B023E4CE51C33F96AC6484AF2E374921472881F03D + +Cipher = ascon-aead128 +Key = EF66F3AC528230C190008AAF4B6ACAEE +IV = 529A57FF723F0BB813A3BD24557B948A +Plaintext = E33249D73ABAFA40F89F2076DEFB7D9F2F9CDBC3DEC518CDE3 +AAD = FE1630E255DA +Tag = 2F338F3616B3DE4E17F630AB05A7EF59 +Ciphertext = 52A42B4ABC117FB1F2198BC0F6EF9DE54FC266732FDC6B0030 + +Cipher = ascon-aead128 +Key = B6A3EB3F4CA48D44FA838AAC9CDF55F1 +IV = 155011C4A0044B2F03223AD44226F78C +Plaintext = F138782BAFF21422CD8B0AD89F381E57FFE013CE25CB75C14B +AAD = A8ABB7A995BFD4 +Tag = EB9B68CF9B8A0761D25F95A253AAE383 +Ciphertext = 2A2737B6D57F526845517338346781E937A71D1A848BF74B51 + +Cipher = ascon-aead128 +Key = 531F32A331E3B506C0AF3E35849D1D1E +IV = D74E40051D7FD6B7FEAD209F1B7DA2C6 +Plaintext = AE2FF2E995BC27C035E4CE1DB9CB7075D50AEE1257CBBEEBB3 +AAD = 09CA9542E183B9B7 +Tag = 3F8AC8F2C5E30D56617B3CF0251A9FCD +Ciphertext = 58E50DFE068A699BBD69C1E449FFC80EA556CF7A88BD072D9A + +Cipher = ascon-aead128 +Key = C9BCCD7270476DA59A6254C66F2EA1D0 +IV = 0715AD182DB602F020D7F66AFC4B7C98 +Plaintext = 9E5AA71F6F2E9BBA0279FA7F8BF9C7BE7982C75A074FC8C04F +AAD = 63ED39F96A759C1AD9 +Tag = 96AEBEC3678D9EE18D8C0BA08528227E +Ciphertext = 83A97E127163B48F80EAD471E7E4BDB1A12237BF0554A3821F + +Cipher = ascon-aead128 +Key = 3C53C1A512330E620DCDFB10FBA9E439 +IV = 00547090051E1373C3AAE851ED4EBEAA +Plaintext = 279780B6494BD05DA0F58EE6D866FE6151D1FE0A813DDD415A +AAD = B4770370D031144D4F22 +Tag = 644DB67FCC2248F8B01144D7C9D82164 +Ciphertext = 23CC2642461796CEB0DA8686F09221AEF0C49704C1EC1099B2 + +Cipher = ascon-aead128 +Key = F9169C185927F1EAE76C233F714306C7 +IV = DB1EFBB61A3C80399CCF25BC23FBC261 +Plaintext = 76944627634955861E16287191B9D1E7BB96667DBA85CB2D34 +AAD = 066EDF7929BFDB14E640AE +Tag = DB4DC28197443EBF4C41CFC95DA57FED +Ciphertext = 320981D3D330595970F4022587C7429F24EBE70C96E48408E1 + +Cipher = ascon-aead128 +Key = B9D92308B497D752A8ECC2F80E11D385 +IV = 1D90602380C81F45ADCAD29A979961CF +Plaintext = AA720334A3E67E826378029E912D70FEFEFD713C374304A400 +AAD = 3C8704E62DF1C9E8C5E5BF8C +Tag = 6BF33E4ADE8DEEDBF4CB74C68EE073A0 +Ciphertext = 25525F6A44112F8EFE41B1DEC3E592D70A6AE1DC0FEBBEF261 + +Cipher = ascon-aead128 +Key = E0ECD93D5445899C7CB43845053A86B1 +IV = A511629059397BA00A5D70B6BBA8FFE0 +Plaintext = F9356C35018D6C556E2908DC6DF3710C53BFE54FED61D578FB +AAD = 09569EB2C9E2C3E478FCDE0F8E +Tag = 352F4F9391EC0478C4416F690991E967 +Ciphertext = 26666E32D66E32DDE9F592F5747183C086D5245D78B808DAAB + +Cipher = ascon-aead128 +Key = C4D986A6C195F4A14FEEC5D746295648 +IV = 3A306BA7BD2F9C3A49A2ABBBB39D32D4 +Plaintext = 74F45804C09934DB95DDE43F7856DC6FB5AC1E862A28621320 +AAD = 87863FDFC09DB631C0F4C48BC0E5 +Tag = EA298625CDC1F303E4D4A082576732F3 +Ciphertext = 04AD58532D7FB5A907BC4C101E9A417BDC1EF4192A2741714B + +Cipher = ascon-aead128 +Key = A9736E92529C93F259945DD2F15A8CF5 +IV = 976148DC1B6E60D14BE32355CFD096F3 +Plaintext = A8E87E25F79749522688527957EC72116E4E561BEEC43B3DAE +AAD = 77FC6C839265367011CC0E19E6AED6 +Tag = 8C9C8138BE743AF774E1980A93EA10C5 +Ciphertext = ABAD0FF7F626A89F1302591219B96DA0F9FD92AA7C5D9FACE0 + +Cipher = ascon-aead128 +Key = 5727979E193DEBC1648AFAFEB0FD7F1A +IV = D2F74902F655B62E43EEA4F9CEA9817B +Plaintext = 23F46435E32E22F4C5B584282CEDA8FCE1CCC788B07C69BF51 +AAD = CC49F0C2154CC9738C14A83A7A92899E +Tag = 4DC0AAF560BC614937197BE15A25EF7B +Ciphertext = 40C41D2C30931762373B18DEFC54639DDC7597776F2B8AAC50 + +Cipher = ascon-aead128 +Key = E30916B0D70179EEC78B301B6E0DEA33 +IV = 38230120BD5AD77EFBD3F89A149FFF1D +Plaintext = 81E5A73A682C267F5B03CEE0A90769536951C31426CD2C0096 +AAD = 8424D5B2B065548A2C6047B8A86A6BE0FC +Tag = 0C661E6C48B71ACADEB4BED69BEB4282 +Ciphertext = C3A34BAE008DDDDB5714BEE570206345A4E7065A07DEE6CD07 + +Cipher = ascon-aead128 +Key = EA9525727968319C583BD4DAE6D30B28 +IV = 63A4E9C8554D56CD6148121E7206DA2A +Plaintext = 0BD30E22F08222CB1D80C4E3DABB381D0EBF44CD4C0A6C06FB +AAD = 67D5AEFF8912D08C9A645B14AE2B52AF6F74 +Tag = 8CF9CCEABA6B5CEC8E87648D640D9A74 +Ciphertext = D06C3840412950C92A40F143B1C5CDF1A705FFFD4C66BFD3A2 + +Cipher = ascon-aead128 +Key = A7F9277B6B612292ACDB729832135B29 +IV = 3FD38ADF9093096CF7D3EC317D8FFBD8 +Plaintext = 7FC71931D2E90AD4A44465D36DDEAFC5FD5D547B056BE519AE +AAD = 778DB0F82251743AFCBD7F71334A14363C8F8D +Tag = E09EB84F58768F8CB3154A44DDECA023 +Ciphertext = C2FA1C7BD827F0E98CDE687495098AAAC949F4AB8162BE890A + +Cipher = ascon-aead128 +Key = 1FF0EA6EF095B790EB5AC08606051A79 +IV = 28417EB2DA454019F1BE041E508CB703 +Plaintext = 5D26110A10AEEB78B796172D67C3FEBF55C762B6B85DAAD27E +AAD = 1AFC1E2DE05E8C564DFE1884515A22DD10E6F446 +Tag = B36DB4ECF21D4657E14DE10407E056A4 +Ciphertext = 06028E15AB514462A67BE8F35771F092D1163D2B75514A3921 + +Cipher = ascon-aead128 +Key = 8C9EC25B21ED53F9162F169518CCFFCC +IV = 21B3234430C95EC5846D97790C6CE58D +Plaintext = 0B9FFD712B0181C7E768B31D1E0A2CE3649E30AC8673D1CC0B +AAD = F41B5B02A5906025534FC109AFBC356B3EA03E7531 +Tag = A9F40B4F4859CF34CA07A778B3314150 +Ciphertext = 6F23621B4CF7F5CFAA23BAAE81DBF6D14E7054530591754F3D + +Cipher = ascon-aead128 +Key = D1276693EC17D15DC824081DD91704BE +IV = B573B0D57B84C1F5FD459628432701D4 +Plaintext = 592C9BA448090F91106C0DFF267B07F749AF056DC810E8F286 +AAD = 03216321CA5067B0EA2C5DB19DC4DFCA6D7E3C568799 +Tag = 840F91ED5643579F114605E257D73243 +Ciphertext = 79048A4977245290CCC76F4D32A2EE6E8D6D85ABE2547A6F91 + +Cipher = ascon-aead128 +Key = 16EE3BDC763020DFC9FD3CE0E99BF298 +IV = CAA499F1B5F163F98FB9F81C7F9B3985 +Plaintext = 097CE8ED019F360BA3601524865852296444449FF3E82DCB7D +AAD = 326F3C8F6B6CAB4B5EF9A15667EFB4690165A5BDA808D5 +Tag = 688872C3BE9D6CFDB522F96A1C9EA692 +Ciphertext = AB9D89757968D0D201477DB75DFD1A846FC91695AAA16F446F + +Cipher = ascon-aead128 +Key = 78E7F6088F2D435B6E75C5A3E833143F +IV = D7DB8BFBFCEF680F8024925FA2A7EC15 +Plaintext = 04745FD77A806AECD29086CC0EB9B8406BAFDC13984DDAA85D +AAD = BC0C03A9726F5E795BEDF8F8999A7F433D0E278FA52F2DCF +Tag = 1B89549582E9D7E4B675788D8B2DB41E +Ciphertext = 4F09E3624E72118808D4AD16B72295964DAAAF014B8BA21B23 + +Cipher = ascon-aead128 +Key = 427DF1962D63CE97BAE459B489F95C72 +IV = 7E919AD360EAA8B110AE6BAD9169C31E +Plaintext = 7F914E4280814AF670ED48F312CBCD710D30DE5811B6266BBA +AAD = D547B4EDD1B4BD9720D875BFFEFA088DE76D5F25815062CBD2 +Tag = CB7874CB8DB212C936E0BF048CDC4A2D +Ciphertext = B13C9007F0A548B495168036A14688AFEDB8597CC5476BA7A9 + +Cipher = ascon-aead128 +Key = 549132EFE0AC8B2F32F7E9EA7FDD24F7 +IV = 31F99C4597E2820E354F8220CDB1454A +Plaintext = 7721A86CF4E89C1E803C6093FEB2D2E54B9DAA00B3A0DD9D69 +AAD = 48BA30CB701ED1EA2D57E3F3C87817EE809953C95F33A3CDEC5A +Tag = BF55DCB69F0982EED7600FDC295F1DDD +Ciphertext = ADF127652311EA0256BD48ECCBEFAC0E8BD1CC01E75E53B953 + +Cipher = ascon-aead128 +Key = 20DA1D099BA244BF5858FFFA92EE61D1 +IV = FA61E02283C9DF9EADA8EA4E8EF8896D +Plaintext = A7627C147AEF077E17442EDF4A37C372CAC1C3C78AFAF6986A +AAD = 0E504BB5391F670075E51A3622570793989A7C4B0EB837D761EEDD +Tag = 128C5F217B4F4622FA97EB7CD2C19E43 +Ciphertext = E5FA1DE8A4B2282DE56E455F560240724A20CAD134149CE2F7 + +Cipher = ascon-aead128 +Key = A4F78FAC788B1999FB1DA937F8E49DF9 +IV = 3590E665F1DABD33E53534D7C7233989 +Plaintext = 44227A3FD563B27FA7EA6BD373DDDE3600A3898C6180ED17F7 +AAD = 7CE96092F85940FBC166DDFA147DD4C4BF0D29C45F503E691B25FC80 +Tag = 406C822E70881DA10780596989687041 +Ciphertext = 25984BA3AFF10279E4C4D2D8D01EC065E3A04111EB6E43C2D6 + +Cipher = ascon-aead128 +Key = A39F872559E65DB2EEA5A8BE68739A45 +IV = C3B73F12F51A7F0C55A06ED4F1721CD4 +Plaintext = BCC72C681D8A8CEC7FDFEB06F65D1A6308AFB2915D05626F3C +AAD = CF1F20B03113EA26EDAB44A7533B1CA11E5AF356D979D1856204003EEB +Tag = 12AB7AD546B993E63BFDC3F6AD65D813 +Ciphertext = DA6B36E28F50316F55C1813E067BCB3F95CA20FE979371DCFE + +Cipher = ascon-aead128 +Key = 2181D6BD92D6C2551D4C934289B8A0D1 +IV = 6F55CAF242F08E5F5D253C78D5009E86 +Plaintext = 70571F81BC3395280A13EBD337336083C9A1CC2142A657C54B +AAD = 428BA551985982C51997AB0C612884183F3AFB1FBDB9920215A7818C2C02 +Tag = D9E4EF858DB1BC517E4A4B1D9BF27FB5 +Ciphertext = 5AE5FF6165215631EC19EB9ACD6ADEC2CF553D7C745171419D + +Cipher = ascon-aead128 +Key = 1F33C10DABC583FF23F9D9BF3F4E1244 +IV = A4E13542940A5E9D9AB37F305E07D502 +Plaintext = 2EB60C7992F80674B4906B509308702F94F8C67AD55F2C2E72 +AAD = A87B2CA0696A4F44A9F8157757CCB313888F9DF1AA656496F99786C6C25F39 +Tag = C3C18F952EED1BC363F16B97E269C13D +Ciphertext = 352DE80604C8E44785221057E465BA2EFE743448B7FF23695B + +Cipher = ascon-aead128 +Key = 4BFD4D9815699C99DC0F44D80185B808 +IV = 1BA8C08625F888F1B37C99B746DF6654 +Plaintext = 68CD4E9C74B2595B05AE914C815DF379A4A6D29F59C05084AA +AAD = 9927E2BFCCD8B5EF28EC479DA870E248A3D8E15124AB088058F5615E0CFD7C39 +Tag = CF28F8AC70C766DEA151191DEB30A177 +Ciphertext = F6AF38E648897001D6EDCC7CC33D4B99490F9409E4A0655CB4 + +Cipher = ascon-aead128 +Key = 8EAD1CBE105D5073EDBBC03126C5FE39 +IV = 5E3E7D497DE844D043AFE6B65D3FDF9B +Plaintext = 7ABC72C8775943E330E3C6612F9C89CDA7DF396E8A5C15FE9161 +AAD = +Tag = F7588E5B23E3B45C59CEF7FA62F4D8DA +Ciphertext = 808C3526E9B97D9D9696357BE9B387CDB78562459C6648892177 + +Cipher = ascon-aead128 +Key = CCAC9431A02675EA30959B2329A0BD87 +IV = 5978A34567E64B54D69D2D07FB8AF955 +Plaintext = 034C50DD73A8E0CAADBAB2433F9359935DE52E4A9216442A6072 +AAD = DC +Tag = 451370F477E36F8CE0C74B8133FC67A4 +Ciphertext = F51F9250DB1C52165D30F8D61204A3C442DFB530C75331E83BDC + +Cipher = ascon-aead128 +Key = 351B8F0BAADC8A05031C4A624BEAE789 +IV = 6B663E2C11826397C5949B63E669F07F +Plaintext = 769B11BC03541F7BF89E6215EB051608B460BCE02347C1C12914 +AAD = 4D6C +Tag = DAD814C57879FFD53DD6641E70864C5C +Ciphertext = 8B4080F77FF61C0D9319EF09CDBC420381970EBF9B40650173FB + +Cipher = ascon-aead128 +Key = 3C4A2CBE92CC6F9C156E2548A1C239FE +IV = 74CC7031A5DEA061362710E30D19C92C +Plaintext = 74175BE429FD6A61D294EC35E9404AF7D9096FF359F6089E6ED0 +AAD = A0F8A2 +Tag = E1654700AA1E7D7A4BB4B9DF220E82E3 +Ciphertext = BCDE603A4D58193A8853FE5C7B962306D90B7EF1F4B255747EDD + +Cipher = ascon-aead128 +Key = 22BC912AD1260081952BD1E3C61A01A2 +IV = FB0A803EBE4266285B04784924EBC425 +Plaintext = 5EAF502033FDFEEC05BA2A0D4D085E82E197F18CC345599DA820 +AAD = D309E076 +Tag = 9668A5C87FBECEA2445C40D8C840A553 +Ciphertext = ECB77B663E3036758FE5E42D43120170C30BAB68F9CA814B2E41 + +Cipher = ascon-aead128 +Key = 4E11205BF4E9B1C83624BFCC6879CCA3 +IV = 068F00715413172C8D2B054D56EB1ACA +Plaintext = F433C9CB9254D27FB1646D084406577AFAC4AFD44326EB5932FA +AAD = 8F5BDFA3B5 +Tag = 1516EB67C2910095806B4EBF3E3EEE3A +Ciphertext = 077FFD72678F7B7E8783969B987E44F0C918086A0EAD0A1092CA + +Cipher = ascon-aead128 +Key = CB02052410F368E23920765CA52FE594 +IV = 2A00A3BFBBE1C81865F4E512B9FA4B6D +Plaintext = 637761464C26F92867197B9225F97BB3B4A6268AC4E77BCF3150 +AAD = 6F42626EAD47 +Tag = 228093446B4C77EFA6EE85AC40B8B8ED +Ciphertext = FB08660ECEA946D792FD36DCB23AC7B9D0BD7EA28017A6CE03C1 + +Cipher = ascon-aead128 +Key = 26FDE36910A34FCCFDCDA4A3FB91B06A +IV = 678D78E22F649EC3AFA4A9D112E22C58 +Plaintext = 69C575BFB8F54357A26453A805DE9E90C944A4CE5F9ED85ABCFD +AAD = E796D0D974E198 +Tag = BC08321AA8854FEE80C2142D3B89F4D6 +Ciphertext = A2B46E836E2ADA42FEAD66E8B0E1080CAC462062B3DE3B7521C0 + +Cipher = ascon-aead128 +Key = 71FDF191EE2386147717508136B04BDB +IV = C4A417095A5A56198A617FFAF3167283 +Plaintext = 5A18459627355C9133794C259A25F9559942DF64475A07259A21 +AAD = 1FC59899C5F0CBF7 +Tag = 7E71921928DD59934FEA5F12B427A4B7 +Ciphertext = 29571449549E1400EA547EA66DE15FA6CC86AE874BAB23FC9BAA + +Cipher = ascon-aead128 +Key = F2FC2A8741D8D1FB5DE4E1322240BEFB +IV = 4C558C7B8E2E278AC7436E0DB5905D49 +Plaintext = 5D1F593BA9D76EB69358AA2DB71C0BF8EDCE6238720BA109551D +AAD = C67543150A18D14F39 +Tag = 8448D38E8B3FD3D7229A7B3C6E46BC75 +Ciphertext = 0E57E4EB3B5998C47F6DF4F2B6F3920100E7D26B79E849E2E213 + +Cipher = ascon-aead128 +Key = E5CBA075061ACDDD13496D7B1A16E3C4 +IV = 5484D1323FB114CC6B78E0112FA89252 +Plaintext = 6DDC5B6D5EB60D7A90A0F09F09C841B983FD86840A085C585759 +AAD = 82EBF55170C84FA230E8 +Tag = A678EF0E4E143A87D864B11F7B2F8672 +Ciphertext = 09E150AD0D0FB309F96D41F954314DAA06D51609E9650A86EA55 + +Cipher = ascon-aead128 +Key = DC6F72056BBE859DAABC4541440A05C4 +IV = 2AABE99A5CBF8E93D0101FB1B84112E2 +Plaintext = C118F855829C5EB8D2C5E5E0B12F23EABDE9CB68FB8303B9CB97 +AAD = B9C361BA6D847766945B22 +Tag = F0415584B5E69709F190A81429C2F5B6 +Ciphertext = 7BF13F68E213B826AB773E482A3FC27688F2D61E9AEFC62AE14D + +Cipher = ascon-aead128 +Key = 3565FEEEE74E1993EE0183060E083CFE +IV = A9ED2B9B6EC3245502434765FA2910D0 +Plaintext = 4B330275796AC5EB23C3777AC823D5FEE7CDF8C863485A62CDD9 +AAD = E58675DF3E693CA4DAE44C16 +Tag = 06DCBD5A34B6D52B1DBAF898115F52DF +Ciphertext = 31D49F17F745E18285FDD8E65730787C4E243E603F46CF1E1DBF + +Cipher = ascon-aead128 +Key = C6C176B35D386EF5EB705FACAC5F1D90 +IV = 55B02F38A0E74E81FF5A44E225CAF7C4 +Plaintext = 8B9854EE587C5479FFC2BEEB4F945288BBF290FB0D8BB7A42B37 +AAD = 433B545E4120E0AEAA15618714 +Tag = CF6A889F77739FB582EAC04A13E237D4 +Ciphertext = 6D4B7645286904BCB3A41712B9BC59EE9C286DAB1EDD357A0E3B + +Cipher = ascon-aead128 +Key = 227455F50F72A71CB06930AF4EBEC282 +IV = A458057B094FCCA181C7BB87EC8EC1A5 +Plaintext = 0C2996D74565958AED0FC541DD5453CB72E7A36E4A7AC127D404 +AAD = A35CD978BDA5F3FAF96E51FADDE0 +Tag = 37065FCB4D1917FD3E9926BF4F07F39E +Ciphertext = 9E45A87E81F7B56DDFE7ED5BCF948C97AB22445170B15E1407F8 + +Cipher = ascon-aead128 +Key = FA84127D942E28EE5A2C712D3F46714C +IV = EAB9A9A1B2E8567773D8AF86F288D4A8 +Plaintext = 213DD32B05EAAF9BEA9C45B339F6A26A11E801F439498EFB51B1 +AAD = C377C62D4F99B250CB3B9955F99F4B +Tag = EEEA8E9511677A60E36D317A60EF5D86 +Ciphertext = C822CD3EF1E77CF8BFBBCDD810862481D70D14631077341324E4 + +Cipher = ascon-aead128 +Key = B70AB150CA647E959E117909D4445C67 +IV = 7AB6287A395D3AA712DBFF9C00EEA894 +Plaintext = C2AA31582755010A7BDC29C53207BF07D3E65300AD269D1088FC +AAD = 2B89B46F1C00BBA2EB3B8007E2954EB6 +Tag = D0A6B598FBC313D5901D7AC4B4BC4B47 +Ciphertext = 8BE505700E294893C6E3B59DFC0150C926F8826A89E4CBE68564 + +Cipher = ascon-aead128 +Key = 63128CB9AC8FAAEDC8B224B7CAAEB2EE +IV = 6814496EA84A3C20F9FC498F2F8867C1 +Plaintext = 9329ADB02BE2CDA6FD9CB1D956C04A5809077EE8D3B9A6CF41D5 +AAD = E47C49D5627F8A7C0372C9759A881FED3B +Tag = 1A2BF1C8FBECB0BECA9538259F15C6EC +Ciphertext = C46B65C8D575AA0C67E54C4BBEBF3BF21741C7846086083ECA27 + +Cipher = ascon-aead128 +Key = B003000EE9FBDBD9013898D94482086B +IV = E350EAA3BF74CB459F55415A765F7D0D +Plaintext = 587DCA20F53802C6EAFF4E8B2C90A8623A069B20F990DF11F9EA +AAD = D4A7F82138521D30C7EBED40B1DE2B877846 +Tag = 202842594A41A79B281D0B4EA86849E9 +Ciphertext = F52D2D164C9E215BBB4A295B86988BF5C2302FE6FDAC37EE0E07 + +Cipher = ascon-aead128 +Key = 1192802117C0C815E6E6856803B6522D +IV = EF269511E6D89712495B705F56390682 +Plaintext = B05CEACCD24DE815B7C5B788B281D27D7122A96DFCCB7554DADD +AAD = E228FD6932A5F28B84224DCF28C992EE1562D3 +Tag = 50AA21B7A02CF56BF843E669737925C4 +Ciphertext = AAB7DFEEC3AF1D3ABFA1D9CF5228D4DAB4B02C0EF8C77136DFCC + +Cipher = ascon-aead128 +Key = 6ACDF5B281AC1A2CD9868368247655E8 +IV = 68AC29DA1607982DA9232D0D1EA32684 +Plaintext = 44B538615E19CE6A34ACC8EB77548BBA7F76FF57C12DDEE8CD0A +AAD = D2C0E149EC83C2BC6729D6E15029570F6D34BCFD +Tag = 7D381CC544DAD2D30B7B78432CDAA591 +Ciphertext = ABD351C90E85640EC9B244800EB1D2A68D13F9FE5EBB8392DC21 + +Cipher = ascon-aead128 +Key = FA51DBD64883AF18C1B80A11F6D0ADEC +IV = 5DA84A1D8FCD8E1ACAC2F391272D50AB +Plaintext = 6D8D5868F436D686ED447E400B73489C77BC636797BFE4645A9D +AAD = CEE84B0C36BB21F4D3F30C1FC7B02277BF9BB741B6 +Tag = 2FC7986EF2446108EABAA6F54E3F3939 +Ciphertext = 349D83C32C8631E25F096910B50E556E17C3DF93FA6CCA437B28 + +Cipher = ascon-aead128 +Key = 786049CF78F72A79F16EC43115D36E2F +IV = D5C44C58432A16E425BEFB02B320745D +Plaintext = 6A9B6FCD1198233DD26D1B61FE7F4C21E83472AB118B5C1FA7D3 +AAD = A82AB0BA58C02DDF2186583F8CF0290EDE7512DABFF6 +Tag = D2239E6E9A62A38CD755D862B3D3BE2F +Ciphertext = 7AC66DBBD1C91A47A9B9508DFEAD088FB2AC6DC608B704625E23 + +Cipher = ascon-aead128 +Key = B313A80FAC3413F70146EE48D8A692D0 +IV = 7FD0CD92D5125B9ABFB06D42487405E9 +Plaintext = E97D50C7EEADE806B649950F2EF34D03311652F56FF1AA1466AC +AAD = CBF9577899F559D02EB6290F13FE562D78D1F1D7C033F4 +Tag = AC01280F82AF4C533D28A64F0B929CE3 +Ciphertext = 33075DE8FC76905CF2D92023310C51D50C038E5A213FA276E43E + +Cipher = ascon-aead128 +Key = F2FA3D3534DEA11C5F4747A51C76BD1D +IV = D79F3102EAD3F6942844C3A8D3120040 +Plaintext = 763B985090E7A4089FD8A4A7B2804180B5670278A5AD5FC933DD +AAD = 234045F562E98D74E2C46A5AF1F0B0031F9A2ECC6CE87FE6 +Tag = 1AE17667C4B54F7BBFB294DFC99082B7 +Ciphertext = 51785D3664AFFDD810F63347BC640A763C98876A1649962328DE + +Cipher = ascon-aead128 +Key = 4504266D3D68283D3EFB1EB91D447CB5 +IV = F5908D4DF1B636F6528B36B1E7A14353 +Plaintext = C4ACAC8CDFB8E53017ABA7476FABFCED74A0C777D513DE26CE39 +AAD = 670B7EFADB5DDA6369EB589B2290CD1150EAFF8A820D2590DF +Tag = 06E1C70A8DD87E90D81E97A3BE50DE2F +Ciphertext = 528CBAB12836EB067B702E24A9BB833855AD9C60E9C33F1BCC0C + +Cipher = ascon-aead128 +Key = 90C1D79DB2D71F70E4DF110F703715AA +IV = C76AA6E6A194DFE68C440BD7E3A82621 +Plaintext = 58A76B703DAB9C77489CF20DA7EAF308D4A4B64860A58D47C2C9 +AAD = 2EF6E98182806A8B027043C2DD9357D93D83AF39646A00C397F0 +Tag = E93320A3AD0B8F11256D1825ED8B30D3 +Ciphertext = A3AADFBC546F3775F7C2E882AFE087BDDED6679FD41D68B834A9 + +Cipher = ascon-aead128 +Key = 4D57E8FB36174E2F352264D5DF9C32AD +IV = 3D5070EB923A4B6B1787DA3B407DE49E +Plaintext = 3FDBE4A001CB8033433656F7BF74777CCF48DF2D79665D502CB8 +AAD = 972674B7AC084E9824DACC2EA2D372BF66F1F1A3CC682DAF8CDA0C +Tag = 1D9D66D4233D47CE07A7CE5D0B488736 +Ciphertext = AA74929496FFFB6855B68805975657A51CA545059DC17A9CACCB + +Cipher = ascon-aead128 +Key = C2D693E16A6B37871E58F78795CB9776 +IV = C42822C33ED4E837A122DBB96182B649 +Plaintext = A21A5D3914B338445516369B7ADD61666D5AB6B96AC891558367 +AAD = E5507218C50CADDAC6485952144C5A065930CD1DEB9650754C4381C5 +Tag = 1571488C54AD823D5E71F0D03C7CF3FD +Ciphertext = 9BFFBDB1300B0C23ED63E96B25D192CB4D8B7508E8FDF1DF1505 + +Cipher = ascon-aead128 +Key = 3DC8EEDB310E5A8D1F301A42AE99D7DA +IV = A38C25EAE84029551D64ACD9F8A175CA +Plaintext = 71B639F49A29A89F8728F637DCA12089116C775EA47E598FB8B8 +AAD = 47A14DD3E107265A565F6279AA1CB4CDEEC90560E7BCCB044318E72AEF +Tag = 967C1B9A5745C6573EEF40928E6F58B9 +Ciphertext = 55A88779B9A6F791AB57F380A495E9C2D230105F7F6F202D6970 + +Cipher = ascon-aead128 +Key = 394BAB5768CCD4F45A713A5AE18AA249 +IV = E980AAA88C9F4B0F9BA9814D707C8AE6 +Plaintext = 7B55BA6E9429E8AD72B04B1F73128B028C94546C1512B06E684B +AAD = AE5371D3D18AEA53E716FA9EB574AFD33C29487966145FF53EC54ABBF273 +Tag = DBA920966C516E470AE9E2755830EAF5 +Ciphertext = 66C43FD4D785B5DA4017EB7DF92EA87355B23AC6B1C2F89E4A97 + +Cipher = ascon-aead128 +Key = BDDD66A650FB9C069E775B8C99A90ED5 +IV = 7F741A45BE83C4A9B3AF2F2D9CA3BC98 +Plaintext = F0489E3D6BD998DF6B04CC05419A28C5608B03EABEFEC2F4A3D2 +AAD = 5D48323B2A3F85148004360C7EEF5A38975069DB8D918FC17C6B5A581E5C91 +Tag = 3B49F5E1DDA3364C125667715A35C5B9 +Ciphertext = 9797F131A8BC06F50B327BE280214CA9DB141292961C80701A36 + +Cipher = ascon-aead128 +Key = C2F90000BE75AAF58BD4513BE18F371A +IV = 9AF062DA20E7DFB2175F616153474778 +Plaintext = 5E61F53ECD81C57016F64E5B09B847BA8924B59DEB986BF01A77 +AAD = B91710C55D9276E050AFB0053B2C1FDC12338E5C62B763D9ADAD27FF24AB22C3 +Tag = BFD17BB56B1DBB264942F28EF581D5D6 +Ciphertext = 680E0D5653611C19522DC1D81953C917AC2347BE6F476DC69178 + +Cipher = ascon-aead128 +Key = 321C2C6C6ABAC567F076CACE235ADD44 +IV = 369810B6BB2771401ECDD8B5954D8FA2 +Plaintext = 8064900DD0566DF291DA0BD399949B320C97933F14F8400894B283 +AAD = +Tag = 34D70788D5C649F410C99546ADCF7F7D +Ciphertext = E4E269754D991C64750D5605C1F1B15E62DF7BE4D80CE9F73B2207 + +Cipher = ascon-aead128 +Key = 1022D9EFC96CA9DEA33C8456D8C23D44 +IV = 402C2C3E2A3EB3283B907DD89E02CBAC +Plaintext = 0823FFFBBFEF7488AE49DECC513616F11E097551A2F6D80F9B359A +AAD = 72 +Tag = 324443817906CA626D3C9FA74A1267B8 +Ciphertext = 0FAA0CF9BE3AF0115085A765642C8049299AF33809A576068614CA + +Cipher = ascon-aead128 +Key = 84EAB65B342578BE38BFACF7141297E7 +IV = 3EA7C04C86389358CFC831A549EFF42E +Plaintext = 2FF47502C8859A918CCCC4D63B776757EE77C28CAF5FF737B80BF7 +AAD = 858A +Tag = 22CBD9641835361F915CE45CF2AD2D87 +Ciphertext = E1C3C71C7340AAF67D3CE8C41D8D9C71829C50E6C3F9AB42125FE8 + +Cipher = ascon-aead128 +Key = F5CB22F72F33F867FF224C873D0E5ED2 +IV = 2A3718D66285559CD83D4E49110CBA8C +Plaintext = 651A6BE2FC961E087C9770D00F7F46781CE716421B59E876E11C77 +AAD = 64EC5B +Tag = D495CF6CDBF9D584B4DA874352905626 +Ciphertext = 01209CEF6FB43F62B0EC1DC1A552216C56060D5E66D7FA4E65A094 + +Cipher = ascon-aead128 +Key = E9DA230B914E71F12752D03528D0159A +IV = F296AFB221DE29E413FB775C55ABCD5D +Plaintext = 0E0DB5FD3E3B66CCD34C7A25235365F0262207B63C6387B384A3B0 +AAD = CFA0F2AB +Tag = A3C9AAB76C6C9BF6549E685B83DAF7C5 +Ciphertext = C611F3B58E4721A645B78AD1B669252CCE78EA9A5CCEFEBF2296E0 + +Cipher = ascon-aead128 +Key = 1699D6166B1D69B027304EC653679CCF +IV = 33E4163FE7ECA30ABF8E94083E54F6F1 +Plaintext = 3442CE90505504C7F907C4A0CF12E063E09F1BAC12AE854DC40A39 +AAD = AF6DC9DD0B +Tag = B482A9DF61FEC4F26B200269A1DE52C7 +Ciphertext = A07C7590EC6D06CC9B02F21C80F57F88E7E66B65873E69EF4A7F8F + +Cipher = ascon-aead128 +Key = 1900E89D1EC047B548F358DDCB0F27A9 +IV = 17195C00F6A4CE320506F5B7EF750AE5 +Plaintext = 66F65BDE5C9245E8FD8007E9E3F26BB219C448D1CC9D702CC91A12 +AAD = 74A3D4D81620 +Tag = D306899DB4CA49E01BFFDD4DFD466556 +Ciphertext = 8AE7693CA519234E66C441007E8316E191E17C9587F2E574C532F8 + +Cipher = ascon-aead128 +Key = 994E62A2EC055537AE06CC1E35E16FB5 +IV = 720768E3694F9F93AD64A0199A0BC329 +Plaintext = 45A7421EEC6BD55C487005DCF27720334020C81341B8C48018B157 +AAD = F500B6AA3EF92C +Tag = F7B033884FF21F5A107B0235155FC246 +Ciphertext = 61D22983A0D050A722BF28BB83C0639916F754378085AAE70B2E54 + +Cipher = ascon-aead128 +Key = 4D8EA19C8B42A0A66295B3F02D0F64BC +IV = 6039B6D8AA9B077583CDEC3244A59129 +Plaintext = E764AE028F5F5EBFCBA13017764BB5AB5F4D071EA85292FB624AB2 +AAD = 9A1756E4F33E08C6 +Tag = E4A3CC06155E99E7795BDD523F75CB6B +Ciphertext = A600670FA094A48EC0FCD8524E179296883F1ACB892E4B26FF4900 + +Cipher = ascon-aead128 +Key = A97EED0454A5242862702FDDBA13225A +IV = 6F2B4C4BE673D4C173DBECCB697149A4 +Plaintext = AA37EECDA4D69809BE0AB64F55C19FD76559E886462EC4B4CD97DB +AAD = 4D602BFEEFCD924C5D +Tag = 4B0E5FE91E98089F8F6D6F22E6F3C132 +Ciphertext = 8EB492C889C3EEABF563097C692DCA64BD90FB2F1623BA58E194EC + +Cipher = ascon-aead128 +Key = 8FE755A98EE0E210EA0B85DD9294EC97 +IV = 793F9D3113520C1BF775E655E8AAC096 +Plaintext = 42F5506542A857722B47BD1429735D50CA80FE7C5B0ECAA9D9C4DF +AAD = 0E8CA26C11FDC3B2BE34 +Tag = 9C1245443C402CC60FFED82CFAD2081C +Ciphertext = B7178295C5079DED35C8909F067D39EF0A297CC0735B8F5A16EE19 + +Cipher = ascon-aead128 +Key = 4A51EC88F80AD30365F5B71DF6DA263A +IV = A80FD4DA92B157F115EE6B853F276616 +Plaintext = 8246A1DBBA456C7751E1E3037362EB3629FCFFF254297D93E61AF9 +AAD = 707897B27DBD3F474FF19D +Tag = D1F9C952165E951CD126CE5B3DBF5063 +Ciphertext = 6C5E9B6F1981F297A697005C09A095AAD6BB841435BD24AEDEB377 + +Cipher = ascon-aead128 +Key = 7700FF6A4A9A2D5992997990CF6308EB +IV = 59AC8AB69661F4736BDF93F285314945 +Plaintext = 20EDD2565ED7B09224466FFAB077AA88636DCC0CDEE8957AED739E +AAD = 9A23CFB6BAAF0662B36713B6 +Tag = B494C09ED72FC048E671941A72021D73 +Ciphertext = E56F630B84E2538B676F18C52398F681FEE2A83FAB3A4FB62C49E9 + +Cipher = ascon-aead128 +Key = FBE3B40BCD1AD57C7980CF0164CCAD85 +IV = F309E1D1146767E9BB82DBCADAF37025 +Plaintext = 61E3B060CADDE54259EC8C8151FD42B196ED0EDE6ECEDFBA520996 +AAD = 6AD76D359F801FE0BD832A722F +Tag = 667E16BD54E29EFA57C634A58EF4FB82 +Ciphertext = 25BC3C5097C90A22D8F37FE89A6A3A6332C5E23A3FDF89F8CAB395 + +Cipher = ascon-aead128 +Key = 6C7D89072D47A96934B0B866C934C2A3 +IV = 02B7B10085B8FBA4E8B478CF19E269D9 +Plaintext = ABC6270B6384716D56EDFB8DFD7CC63D5350A12DFB2E4EC36F385A +AAD = 5F830AEE81E6D4372E896C8A7852 +Tag = 0879EC1C74726A6F3904FD25F4BBEB13 +Ciphertext = 8DAFD2CE106BE6BD05CCDDA07E8F04D003849377CD595D395EC38F + +Cipher = ascon-aead128 +Key = 525EB1CA3230CD353C2DEF657110DE03 +IV = C30F6E1092254972E53AE5EC4FCA01AC +Plaintext = 4305FB77CAFD5C322348B27ECF5A01B13642929CE8ACD9BD4E2BDA +AAD = 43FCDE9A31C2D913FE6DE9F4F87C32 +Tag = AA9DFF8345F49A9E4B65EAE39EA3ABB4 +Ciphertext = 467603A0BDA0D69F960A836CDCDDD5D9E5BBBF569D2887A5E2C6B3 + +Cipher = ascon-aead128 +Key = A23062046010DFA54EAD726638A25A76 +IV = 0E40344FAADFF208DC34A0300A2A6B24 +Plaintext = 9A15FE0451591FBF2FBDE3DAB5A4413A6DF85DB945E35CD680B5D5 +AAD = DAE5F37EE58713DC8253DD2F69151D5E +Tag = 82018188219F3EEBD40C5B1CAE2AAE52 +Ciphertext = 2CA2653C5E71215A0DF651FD9C5F35A4CAD327C38EF8B4AB08D849 + +Cipher = ascon-aead128 +Key = A3A08BF227B56777C61528C68C7E6DEB +IV = FDEE5492D83863E6409D52B95E9E3AA8 +Plaintext = 2A3FA2E2FD87D26D266F59B133635291F6C9E20C59009EBEC00368 +AAD = 2ECF5FB83663DBF5B80991FAD875A207BB +Tag = 667F310ABD020623ED8886DF52247BA7 +Ciphertext = B7E1E4AFB6C557543325D38078E291DC9D832770DA9BFF20A650E6 + +Cipher = ascon-aead128 +Key = 26554F3F8834D1AFB6185E3D837F9F5F +IV = 03759A12BE3435118BCBA3E12045D4B6 +Plaintext = 8CB93094EDE0443B8CEC6A48F0D815866438C586F824ED2DB3FF9A +AAD = 5FC3654D88B79785FD390E4417F468C14999 +Tag = DC16165D6BA56A260C9C06ECFC9647B3 +Ciphertext = 22C5AE18C02D53A42638BFE74AB5E0B535BEF7026F9C8B1C710890 + +Cipher = ascon-aead128 +Key = 96753DA0B767AC1DED3126A015ED2E86 +IV = D8C40D9B7122E0C03716A20B39B6DE91 +Plaintext = 4C1E36ED54305906BCECCF3A9FA8B64E55B93A100130B1CB351FCF +AAD = 4912DBE7F6380C5C3FC8FC35E10A17A9E9D3DC +Tag = F7E06760FCE951C53F173E04548B7B9C +Ciphertext = 76C32FE6418A2145720D1A7133CBDAE22C1ED304AC0CDC1D90D000 + +Cipher = ascon-aead128 +Key = 51A6782DE8804703A9943FBA665315F4 +IV = E42BA154702E1BD999FFAFAB70043B23 +Plaintext = 9564A1AB9E004C22D91F0E29D1B892AC43E1D4B447039A206C4EC0 +AAD = BF2C3F6343CA1505BA62EDFAE0D5DB23AD51A8C1 +Tag = 44D850DA9777F111D57E37D00CC39440 +Ciphertext = 8704167AAB636BAAC5E799D1C1DDFE154C4CEBD43AE369405D8132 + +Cipher = ascon-aead128 +Key = 36F6D00B6FCA75C21B5D44CD0ACEB067 +IV = 1EEA014DE8B683DE179CEACC83FB360A +Plaintext = A24ECE99F8FBE7028AD2E03D510B8023927BF373C7ACF9171BCEFD +AAD = 7D26892D0CDE5C448EE9F6FD54C4D4BE3A6F4E826A +Tag = 01BE1A34AF41C1E8CF10AD886043DCFF +Ciphertext = F1A1BD010C64EA03DAF74C7D506CB37E79A884C73BBB5275EFAD03 + +Cipher = ascon-aead128 +Key = E555218DBF7576F0EC081C3A79D44E93 +IV = 2C6E6D390727AA1AC7CA63C33C14D045 +Plaintext = 18A1024D50378116E410725076EBD9A95D4148C587379FD1C256A5 +AAD = F96D8C00C71B14F9CB4C95C72F2FFCF6A6FB6163E825 +Tag = 3D597258A3C130CFCFFCD86E97FA775C +Ciphertext = FB227BD2293AFF475E3654EE7C0AF81D150EC823A3573B12A9ABBB + +Cipher = ascon-aead128 +Key = 340E22AB933E6ADF306E15B42CF18350 +IV = 3A9EFC79553A92C0FC4EE4220629A46D +Plaintext = 25E111A747131638D53F485E889C929D379E420E1D9AC86E2E3118 +AAD = B04FD1CC0824142A53958674D1C7394FF4BA86800E42F4 +Tag = C9055995DF1AB4C237BF400BD9AE7C78 +Ciphertext = 233919D001973C94EDBA027073695CCCF3C0355C2FBCFE5A14055D + +Cipher = ascon-aead128 +Key = 3F7AF8DBCB4CC58899CC1AAF79FB9EC4 +IV = 98DF8E20B7A6E345719AB41AA7E8B29C +Plaintext = CF88D5E345D064A2DAEAE8ACAAC1E2DA37D2C49BABCE61A3AE6FF4 +AAD = 51A7A88D3FA1FCCD093BC80EB69690F19875B4EF39C46B4C +Tag = 8774F95FD443A2A29C17CCE0781AFB81 +Ciphertext = EA62A130C1B5C7675BA22381BBDC25CB7E65BDBC61BD082A6FF1C7 + +Cipher = ascon-aead128 +Key = 85C083EEBF56447E62DADB93946681DC +IV = 5991FDC2EFB2ACA60D3F09E362FB2A1D +Plaintext = 6F9211B5EB600A0FD318A967CABFF9517B8A11B3261EF30245D51E +AAD = 4DC36F5A91BC284131427A239D1BC3ED01B7ED7BDE414F2345 +Tag = 10264659970E2695FAC3CDCEA64D9B5A +Ciphertext = 3767632A77A380A8EBE3DB12F28D41BBCF5569B20C024868F6328B + +Cipher = ascon-aead128 +Key = F203A57970385F71CA2760C0F389DE2A +IV = 9540BCBC916CE7129EE018F2B932C20F +Plaintext = 05D0B36103618D478446F4885BB70A1BA192FFCBBFB7C354EEC6FF +AAD = 6A32280E2BED4854B325CC49255F85A67BA08024D9DCE8045462 +Tag = 18AEA125F7F4CF656EF67FCBD3CCF276 +Ciphertext = A5CD5AB7AA4638F55A5411E8C1A2E50766CC4BA01960A0B57BC406 + +Cipher = ascon-aead128 +Key = AAABDF4EDAE21EB5A3ECFD136474E763 +IV = 5B79D2721D667E02C2C393470C4000A0 +Plaintext = BDD36544004449FCFFC2EE209B1B86146C8EBC5BE6EF5634F1C71F +AAD = E1C03DC7998288D5E1AE20DF22472DA8EF86EF4096F885DD559FEE +Tag = 948BE8C0152A7174E79353DC6B2B8485 +Ciphertext = 9207332F3A5F1E38E8469D95C11BF9C5BED80485A024BB4CC79ACB + +Cipher = ascon-aead128 +Key = A3CE4C034F5F8E569969C8631929E5D3 +IV = D69D162BE8DDBE9FB846161F49A60D32 +Plaintext = 4F330161B04E23EA620DB3EAC5A5D6724F5805A780A3D4BDD38D48 +AAD = 4416C3047D6C19910178E9CB4520CF8FB4F94C528504967072E4F35A +Tag = AC4030B62824DC8FF8589F1043E8DEA0 +Ciphertext = 0D9251D93226308BD7D083FF5EE528379D29E453E7FD1E7EDCEB1D + +Cipher = ascon-aead128 +Key = 39943DE5C17EECFDA3C53C1ADD2CD8FF +IV = EB856864868513BA35F2DA8F08B90883 +Plaintext = 7C00016D8C4E8958C5157CF06BFB48E658236A41CBBDC81D6C5523 +AAD = C60212F9773DEFF31880F2E19DCBDD991B2CE3DD3C87CF7E846564FC80 +Tag = FF0629CE407D04EB7772F559649E5DFB +Ciphertext = 1C34E948DB79B1C9B7E620CF07DADDF3AC45CE42FBFA6B75F3E4C3 + +Cipher = ascon-aead128 +Key = 380D31C3C7EFD0469920AF111EA6EAC8 +IV = 9ED696973C71D37A58C9A40F93541C07 +Plaintext = 0410E83E298C54C712E43886851BA84F2E64980BED0D580E6095C8 +AAD = D5EA7723DA7E4DF3D5018B86E4631C1CBC04049A9CAB9E392DC5D0A86F5B +Tag = 5A7CBB438B19E33C63EB09BC4B250EAF +Ciphertext = DC0E12C88C140A142CE47A7D0711F13326F6113C8E45FAB20175C6 + +Cipher = ascon-aead128 +Key = CD663FC84A0963213F619CDF918ACC1D +IV = E91F3E3B10A88B88A6453ED1D7404701 +Plaintext = 52D9315CB00C809B3A9BA23CBC715B5E878981547A3095754EF01A +AAD = 83A027834B9E0E31455414662BC53086F4073C82A0FAFCDB4BD64F61935D98 +Tag = 6D89814D2205C9A5FD4FED1A9C4FF955 +Ciphertext = 0492834CB24FF6008ECE0DFFD0E8DAB7024A99A797EBD539900207 + +Cipher = ascon-aead128 +Key = 09006CD1193C6AA9D63195B12EC26E19 +IV = 3D64A2454758684A5C690196BE3051F7 +Plaintext = CEDCE39F99269131F03FAA58D70AB548BDBCB856D01845E61C806B +AAD = B778FB74AC7771DEBFCB8ECA69C7E53BFF9FA0ADA8D85849392D93A8210B424B +Tag = 10C691270459AECBDED34969B9C14574 +Ciphertext = F34D60C669CB6907A2AAD9C153D40F281CE2FCE1ADD40903134B8D + +Cipher = ascon-aead128 +Key = 2D45372F13CD3D282E193B0D8A99A150 +IV = A8D4608CB1CEBF96054E12EF760A9724 +Plaintext = D518F187E1D9A160CB4151FB0271EAD6CDF81AE59D2228285A6D0AC5 +AAD = +Tag = 999D56394BEAA793B352D87CAA90F9D3 +Ciphertext = 376FD467530D310C6D596A8311C5AA4653189EE05826B3EF6FEC214D + +Cipher = ascon-aead128 +Key = 7A5822025354D39AF997CEABC08E2BFF +IV = 795796FC5E691FC7FCAA2976751C9874 +Plaintext = 18F63F905FCA95279E75C2FE0CF056FA8BAD70C1B9D2827F5614EB5E +AAD = 36 +Tag = 3DFFBFB642B7929515403840ED5CC2F7 +Ciphertext = 19E5504BB6AF3AE0F39161AA29BE82B816AC679B2A916A01DAFD6CA3 + +Cipher = ascon-aead128 +Key = DB2902863E8903147B20F985A3AC32CD +IV = 49F22C38C088799109B456D02C549FB6 +Plaintext = EBB78BA1098285EC6081D5713FE4B30540697520EE11914612A19B9D +AAD = 9995 +Tag = E468BFC7F327EECBDE245DB22BAE325C +Ciphertext = BB94D66C25F7634F0842A2FE9B77ABD4A1EAEEBA5C8942B6A0217D30 + +Cipher = ascon-aead128 +Key = C580B6D918A51C82F5C0252FAA3EB365 +IV = 8D678E5F5130E75B5E3DBD1A789936D0 +Plaintext = D4EF07E0534B92B361FB5EAD95F51B69CAF9F0C38FC6C407EE5EDCC5 +AAD = B416E6 +Tag = 723E1A7131622E6A6B647024A81F7C78 +Ciphertext = CEC811F349172A9A19F8051123CAB75F26B4AE08AFEBC1D53653D40C + +Cipher = ascon-aead128 +Key = C4361621067C4AD4594A2636143699DC +IV = AA3CB4E8F16AFA77CDD07B21BAA78202 +Plaintext = B583E4EACCF6B7EDFCA6BF6A835D058024E44EE743691AACC608A2C1 +AAD = BF774911 +Tag = 2B6850AF924433366E151BB3C9EC538E +Ciphertext = B179FB3D7D9E027153A8B9A2BE3A968AC4670FCCBC96CB73D5806335 + +Cipher = ascon-aead128 +Key = 4A30441BD2FCECDC895B42E862632669 +IV = 89CD0978FCCC758417692719046CB8D8 +Plaintext = CCE04A34CCB06D61CF0AFB05F552A4068F5D2222C75B45803628B1D3 +AAD = 3B25B40781 +Tag = B51C2F48A00ABD6BE75649CA789866B5 +Ciphertext = 7B74D7D72F2EF981FAAD74FA2F8502201D7486AC4FA0D2664870E6D0 + +Cipher = ascon-aead128 +Key = D4225AF9E4F370D4BC0B79C4A265FB66 +IV = 4F55B595A68E40668CC2662037D454CE +Plaintext = D3F312290D07BB94D37D2FE6BF42AD0041F4173FA23A14AC402150A2 +AAD = D473FA53713E +Tag = FCE9B73A75DB3E07614027389D840691 +Ciphertext = BDA861F62EC3E20F04796DD477F0DE4B6A99DF6478EBCBC589E85820 + +Cipher = ascon-aead128 +Key = B4D24F065899A131C9E78A0CBFFD99F0 +IV = 021D381B37671BD7CB6878EF1B11C4CA +Plaintext = 4B034B9DBC37AA0598C4C7D6D9F748FF5F0883AABA3A98FA354458D0 +AAD = 24D232E317B928 +Tag = E85CF78DE460035EFFCFDB4F0A310C78 +Ciphertext = 0E9F33BBAE26A344BADB9F0413C55CDD3989B99DF441FF5761DA9A6F + +Cipher = ascon-aead128 +Key = E79628DB85B555A03B1A9D2066E3F445 +IV = 0CB78589A6F799049C3D9EB6B1FF6020 +Plaintext = C9D903CF056BD68FEDBF7CCDC89E6F6F4B40D912CE369E504D92CC65 +AAD = 595E1B133B5971A2 +Tag = 8A175E7DEDBCCA132E3CB4E20D5C958B +Ciphertext = 028C58D9966F21D7785128266B6BF9176FF5DE715DC7726F578EB36E + +Cipher = ascon-aead128 +Key = 2C5DF3655C8513888E85D7B1EFB2B9D0 +IV = C8119E93E1A5FFBAB587802538D16FD4 +Plaintext = 5320641985E1F3E53CC912735D89BB1AAAEDF81E7DD92A8EFB06901E +AAD = 4392E69739B3D67012 +Tag = 9897FB9CC14EA8389599BAA14A8B31C2 +Ciphertext = 7C742A295669277403D6BCFAC0D8BB7DC5F2B8DC4FA708DFF4EED44D + +Cipher = ascon-aead128 +Key = 56D8A6BC8851ECCFC34D2E4C9BE78E22 +IV = AC9F6592B58D154D68AB5C6C49D89DB3 +Plaintext = E1CC8DC6259F0BDF5194D33874981B202AE4EB68686E11D2CAC27E2C +AAD = FF9241A3D718D3C65CC4 +Tag = B5BFBCA4ED877EFA52FBBE85399D0141 +Ciphertext = 00983B106895D04F92F57E1D8C5EA051ACF2234AA6DAFA9252E5B2B2 + +Cipher = ascon-aead128 +Key = 1812FB094679C226B12A2872EC11A4FF +IV = 3260CCAEE9E30E45D5637696DDD94FBA +Plaintext = B0CEDD668064C014F631016E6BE5C04839E0DE33CBBD3A14FE9F61B5 +AAD = 03F08D3CE26E4EDF7A479C +Tag = F18EB8A8268443EDFA08D333ACF6B663 +Ciphertext = F9B0EB128B675F264220E26BC411353359EEF5305D67A05A35733931 + +Cipher = ascon-aead128 +Key = 20BA5A1785FC9E7C301344AC68449432 +IV = F61569AEE673AE14B00E046D7859109E +Plaintext = 334D50D0AF7C780A6BFB84E83F06746616320AA48E968BA59D4C06DF +AAD = FA03410FE9348924A591F966 +Tag = 12ECCADD9BDCF3BA9686685064C17031 +Ciphertext = 57EE3C2439AA24528BB65F680B9ABF4B3538E0FD7F1BB4F72FB5221C + +Cipher = ascon-aead128 +Key = CE62510B33BD70F5FF906366F9CFB409 +IV = 0C05631832F69B7CEEAF0F536EFBE514 +Plaintext = F6F80E727E341D6344EEA4E338157A3273D2276361798BC95B442CA6 +AAD = 7457B3366B4CC7CEDF81AF2A06 +Tag = F793BC835C237C62D03E292B4AC98957 +Ciphertext = CCBB393AB22139C5832E647D31F266246263006C874D3F01636F433B + +Cipher = ascon-aead128 +Key = 49E0D3C56005836F2B4F044A702E91C8 +IV = 565539E5A607CB9BD42AD6EE9DB16FFA +Plaintext = 05FC984269E63B8B399B8D660C8D6F128748B5ABD0ACA74F699C77E0 +AAD = A3C8A4213AE7779B3DF2FDCC5E50 +Tag = 01E2B249ADBB7E6FE5992539CD1A5440 +Ciphertext = 32CAC22448A20F94F911CBF0F2D14757093A776A07FCDD8BBA1C946D + +Cipher = ascon-aead128 +Key = 6E742E016F2F759E10BC3D52821F7678 +IV = 5D535D9C463C0CB851E0E6724738B13D +Plaintext = 024CAA236D6A5D6F55B45A56884CBCD515D6D4229BF81487430AEB5C +AAD = A4CA9C8ABFA16EDE38059192B6ED4B +Tag = E7DCA42B71D18E9B3CB66D8783A685B4 +Ciphertext = 6B22B3F0CF8AF9563200433ED921BAE405C8444F1B3ACE27B16D0DF7 + +Cipher = ascon-aead128 +Key = 334877FCAFB2C564D31CA38B8812B63B +IV = 600CFC52E1EE1B38E6B33D918C60CA84 +Plaintext = A26E0E935B9CC2214017AFFF8552C267D0053313BBB0F03353FFDB28 +AAD = 1A316952277EB32BB41397B453A4CBD0 +Tag = 0D74A853F38C97F53DBAE54EEBD852B0 +Ciphertext = 1F975E084D706BE43DFBA126AA14E6E12445362041C01A8EFE22BCFD + +Cipher = ascon-aead128 +Key = AD1A35E46D2480495C46255359593416 +IV = 4E8C716F0CF6233327DFF7D1994B9219 +Plaintext = 6DDA7EC0069E0DAF2F0181BA3BB8CF5484B54607A9A87B315A0A7790 +AAD = 312D45EA0A06B1FDA88080D4AC66CDFA84 +Tag = E8B4E8B2BBA03E68FA7CE56C72738EF8 +Ciphertext = 606706F5CA32F491763D6EEB8A28FC0BCC1198E3AE7A6B400D606903 + +Cipher = ascon-aead128 +Key = 3870DAD824A38382A6678952215D2489 +IV = 209007854EF7D4791B4B0A39D3EF74ED +Plaintext = 19DCEB1F5C2096BBB6D338290E1C46D36EDA0C4E769C1111E0A68698 +AAD = 9CFDC9EEC889D0BFAF7AE33FEA32F2C773EA +Tag = 4888E937DFE182BA8C436B11888B8ACA +Ciphertext = 0AB2FB52F5465E5046B03AEF2F4F0573213F76DC3645B21A128BE022 + +Cipher = ascon-aead128 +Key = FCD04E43EBA151E6BE54A872242687AB +IV = 331E6E84CD009AEAABD9A6FC612C7E85 +Plaintext = 62E64452D903740A4DB1A94B93D873249523F79B84809701663086F2 +AAD = 5F10E8E4086FB57BC43E34E7279677555D537C +Tag = 36919D4F629B0BB872737413EDD4C680 +Ciphertext = D04C291BF474C1CB706C76CC5800B069CBF8CEC6E1EE8AEF27EA9297 + +Cipher = ascon-aead128 +Key = D20FA9553592CEBF9F862939A4592B33 +IV = 8CC96A5662AB38393CF4B67809C163DC +Plaintext = BEB12C947E5B977F7887D83963A2CF83417B932058E66686F1E8334B +AAD = 82FB084F029AB616C3F8A87DAED369C9310E576D +Tag = 574301F93535FA80A3C8ADAF881DBC66 +Ciphertext = 6FA9D616131633A208599B96CEEDBF57049D8D2E80CD44A540EC09AB + +Cipher = ascon-aead128 +Key = EE30BCF2FEBE3813A78EEEA126763DEE +IV = 7F56F2D65235411E7E6784C568F1960B +Plaintext = 10D1950BC92A8E1882E5E6EB9487BF522EF3C7A7B4AF4CE30533C758 +AAD = CE15AB4C1F9ED313E3204B98514F784052FBC18988 +Tag = 2E7E35563FDC9551450CB3D32A3F6B79 +Ciphertext = 22D06525F01CC8A83B3E3CA2D5F8519096B6806DB5BB078784DFFB40 + +Cipher = ascon-aead128 +Key = EF7D47B4423E182F423106ACF925EB3A +IV = 01EFF0F353EC92523955E302930A089C +Plaintext = DD2053302DB8E5998D69537995B7F29EB743840E00C20AE8167382BE +AAD = 07F60DADFB37A2AD154B20D63BFE2B18F99331466F16 +Tag = 276F37D22606F08265CD5DBA61236582 +Ciphertext = 044645DDC2F9D12C57A401A6E03409DC4A9831D0B8BBBC439EDCCA2B + +Cipher = ascon-aead128 +Key = B078FE5E2E2910F3F0B37244D72B5D73 +IV = 52F38D9D8299BFA2AE32FAE41086A7EA +Plaintext = F0803B48FECBF3EFEDEAAAE9D5D5FFB968849C26D96AA08D3199C0AE +AAD = 9E9E373C6ED66478A950367156304CC070044C9050F949 +Tag = DAB5F033DCA143380BE465C12124292B +Ciphertext = C10D20F1C5273A9ED9521C5E0B297B82A24E1B48EADB2D4F5AB84744 + +Cipher = ascon-aead128 +Key = 40E2ED0EED3B106C5B92EE9B25F15BAA +IV = BADBA5157B3BB8E006DE6033F09C821B +Plaintext = 94D099CA6D61ACE223F7B74B51EF3A46B8E6493E3C3C73BEF03417A1 +AAD = 6A806D323564EF5F5F6A0A748EDA72F80877250EC559743D +Tag = 7ED9B7FE852809D3150683BAF85234F3 +Ciphertext = B0E9DB0B02330E83450DF4D036FDF9CA59E1DC6083B71F527E5B62EA + +Cipher = ascon-aead128 +Key = 64F33E1968CCC6469CC8691A368C817F +IV = A8C30B372BB27C17AEFC64A797C58489 +Plaintext = 8865991CFE7ED779B1C71D284CB05489962C7907D0DFBF54E3D22691 +AAD = 2D1C698C338A01D743657DFCE0A4C49F3993D000E660A8867E +Tag = B5B3A1372C9A60FD03DC99D7AE6F0799 +Ciphertext = BAB302EF513F80A6D8095CDF82F72F4B2BAFB7C299660050F36E4275 + +Cipher = ascon-aead128 +Key = 81EBBDB5DDCBFE5B6B776757639DB410 +IV = 0A6FA0AACC5EF8295C529BE3F5857E67 +Plaintext = D47DC25D5A086F59391F3E09839F241E4B3F14C0C53F99D8AC93DECF +AAD = 299A7226937F3C5C89A7406B393650296DFA38DACB1CD75986A0 +Tag = A9CEDB98F0D0EA16B09483AC2126F051 +Ciphertext = E37833B0EAFDE3AF41F86B4EB8C0D379A03B386B60C2744B50818BA5 + +Cipher = ascon-aead128 +Key = 3D287893FBEE1E1D24B6D55FB4470A6F +IV = 01BDABC6569A5D11BACC3D47077383B4 +Plaintext = 0FFC76955AE03F0C09965E7ABF6E5B91316F15074729D051A93A01D6 +AAD = 4F79A7F3C2A25FD6425378BCB40C5F7C6B641CE18E93EC00DFDC92 +Tag = 5DDFE9E6456E48935B37056438A1B80A +Ciphertext = 399F655D0B3FF4AC4C03DB22CF2EA61233E1EA797651FA1C7284B447 + +Cipher = ascon-aead128 +Key = 2B110FACA346420D7CF8D7F47E93DCEC +IV = 68ED5C9E876EC0A6F2F0CEE03839A791 +Plaintext = EED2644FD7E9F10F65665421FA5784431EA5B41850355A8DF434480D +AAD = 61B44ABC8E21133BED5D64A7248674987928950F9EC611E4F0F9F2DE +Tag = 3C3D8F47A0C201AF8B354A7454CB93DE +Ciphertext = E3D44CF29065B2FE9A39804D3AD500D0D3B33E242868888A8D9C0AFB + +Cipher = ascon-aead128 +Key = 21E88A36B2508675381C55637E632501 +IV = 34DE7D381EF356FA5D9A0FAF1022812C +Plaintext = EF13AF6174460240BDA0D141EDAD0001E079B35BB4A0A28A51205C5D +AAD = 6CF6C1370FBA865F99CD2C739A40F261D9BF9DAC006B3AD849B86B6224 +Tag = 727E2EED8A90443BEDDDBCBF0351ACD4 +Ciphertext = 3C4B3A4281DD91403A1A04F249A7C80B8F4CD101F0730243DC7524CA + +Cipher = ascon-aead128 +Key = 4F838D52706159C72DB627A412B454A9 +IV = A4594B58A44877E94836B6F4714BBEE8 +Plaintext = C2D8A7CCD747736F42EEAD80A112CC18457F5E9B1C502EAC17D0F278 +AAD = B436D66D15973D1937E87DE68C096F0BAB5E8744199F8C1EE8A17A76AD38 +Tag = 53EBC5A22C089B61B6FF18D4D385E7A7 +Ciphertext = 8BCEE2303B4807A996AC29FDED3AAD45774D6FAF1AA86C2D603B82CF + +Cipher = ascon-aead128 +Key = BDC1593B8B40529D2DA6E4638F783D53 +IV = 40FE8931007EC1E4A80953CBFDB4C9CF +Plaintext = FBE4D58E3D133BA770E181E326A78F130A8A13B3C419D1842B1A0853 +AAD = 18F287ECC7C4B76C3FDD89B0682D071BC8BBB39099F7D4E8367FAC0D828298 +Tag = C5D25D8B0E624F01A2AF0ACF52A1C3E2 +Ciphertext = 9C234EDE086599484B7138352D2AAAEBF40093908A88E7600654D06E + +Cipher = ascon-aead128 +Key = 826A4BCAF3D31894BC828F168A98D9B3 +IV = B68584802CECE1AD8D8DB9DF2375B4AA +Plaintext = 0751DE905AF353B0C230024A526ADB3FEFF658A680BF2E5B471ADF79 +AAD = FA97D1D4DD8D324D2BA0215ECE3B77E65224F3D945700E1BD51E2F795A39FD58 +Tag = 335ACF8B6B28F17554FFD8A0FD8F4595 +Ciphertext = 3FECED579CBD4F8F1D8B0DC0CAE99E3AE2FB40C1EEE2E54D1836B5FF + +Cipher = ascon-aead128 +Key = E3B59491A8EDCFC1EC5CD758238F0D98 +IV = 5F6A475F5A28FD9EA3586C2AC4CE37AC +Plaintext = 6D2728FB20BBF53E4C33C2750F19A8536D9BB9DAA5C94703C1EA605C56 +AAD = +Tag = F85F250AED94AE21B68FFFEC567CAB52 +Ciphertext = B60897650A911188934D8E64662289907D7449B84F2DA2FA4BD972E7CF + +Cipher = ascon-aead128 +Key = 6EC4A0613AC4034963FB758ABDA1256B +IV = 60C1C57A683AA5381EA833ADDE6A101D +Plaintext = DFCB5B9003D823B558411B7ECFD2D99498886127B8FD305175DCFFE3CF +AAD = 66 +Tag = 6381E31416C49B779325795B3835DBAE +Ciphertext = B0CE65D1BB2D3ABC97D8B3FF4026EF857CA5A02F9FCF7C6FFD2394255E + +Cipher = ascon-aead128 +Key = 6BFB8CED18AA6EC24FA8426DE4602ACA +IV = 1D6797F10AC7DF7204146A4EB8644345 +Plaintext = E0CF09EA67C21A47F266EA95A20A0C78E3E192C085D1B2BED9EAE8F381 +AAD = 0F4B +Tag = F6946BF3474D9FB5F2B3621C76705151 +Ciphertext = 4F991442EF92FD0DEA264536252AD1483F93088F65C87F98357937D524 + +Cipher = ascon-aead128 +Key = 8480AF7A786728EE94207B2363356119 +IV = A747D9D8CEBFA257C0485CF7C2AFCAA4 +Plaintext = 5DB678A1F699E2B7CB62047D1AB8DA3EDD8C5DAA355FBE921981495E77 +AAD = AB384C +Tag = 099618C30FA55053C0703B8A83E5C8AC +Ciphertext = 5EE6DE25EE98AF4E5094D182B3062BB9DF1061F3E385BB922BCE12F801 + +Cipher = ascon-aead128 +Key = FBE06E7122600B6DCA7FF56F7F5A73D9 +IV = 2225F968DA82B5FD459F96FA2D2D734C +Plaintext = 5954CAB2239415A6F6FDEDE049D803798B1773C81EFC113A3D2BE8D027 +AAD = 4C89FE44 +Tag = 6558133835D67CEE28847198B2707BD3 +Ciphertext = E2944DD1468B769A83FE2893A7CE420CE2A73524299EB3265F85EF5455 + +Cipher = ascon-aead128 +Key = C8B80E0C893E1485C0B2C6757067C879 +IV = 4DE9BC2C7599B237B5D3D740CE7414C3 +Plaintext = A4F4B9E2531A0DAFDEE4294AF7AFBBEE8E542B9EA9C375382A471BF5EA +AAD = 721FF90FB8 +Tag = FD9DACB6FB2A8E8DB3AFEB2B09DB9696 +Ciphertext = BF7FFC6DA3C222E12035FC654872B84A9989DA14F9A03A3A291C080EAE + +Cipher = ascon-aead128 +Key = A739BC0C6C8722D806E31051DDFA29A7 +IV = 75645F9E0D7F239CF2ABE0A3CFA1271F +Plaintext = 0CA5814D6A5C906760DE892466E1F51A13B5CF1DFC3F375850416E5361 +AAD = 7C27267D33B7 +Tag = 71F071EE3AA0C563EB18BA4A80076EEF +Ciphertext = FAE7C2A9A0D516413802E5B0F56DF830EBEC63B15DABE0D906388FF1E0 + +Cipher = ascon-aead128 +Key = CA01529EFDBF8E09AD13CE9C57CF8397 +IV = 0C7986C301B0407CDFC8A8023F8C97E3 +Plaintext = B58F2738ED2B236AD7E09361EBFDA80F4779CB06CC7766EABF39854F4F +AAD = 29E6CB16FA7224 +Tag = 5538C3FBFA9EAE30A800942B6CFB950E +Ciphertext = F02C555D2F1AA77886794F1252BAFEF34E3DD61CD1431ECBAE8CF5A898 + +Cipher = ascon-aead128 +Key = 7ABD32939CAFC2256623F194F4864940 +IV = 13CB4BE90A8C9685DF74A72AD360F160 +Plaintext = A56C99F012E3D40906CE64A8B1B8FE79011844443A1FBB7638017E8A8F +AAD = 732E1FEC076459F4 +Tag = FCCAAB59BD96F34568BA8DB5FBA7F45E +Ciphertext = 8B9E9BD1817E240A57BE5110E45240BD22FF0ACDBC3FD22F0CE40BA9D6 + +Cipher = ascon-aead128 +Key = 81648C79944B86C42F03A0E5A95D7F4B +IV = 82F91C5F0790234CEF410E8BF264D8B9 +Plaintext = 253210D64078CE818207F4767217190A82572CE06031D170818A871637 +AAD = 78FAAF91939F8C72A5 +Tag = 61E25D441B3FAFDDF69C32C67835C80C +Ciphertext = A85BC6AA1B6F280EA63E459ED43334F830B626AEBBD4E21E0E0D0FFA61 + +Cipher = ascon-aead128 +Key = 884A87BD049256153645D09E7E7F5ED2 +IV = 600D6C1A493D21A06F186AEE3CD1BC51 +Plaintext = B748C2010E3061EB2333CD86DD6665D524DF7A88297EB9E9297C82FF88 +AAD = 5118C40895AD8A60D72D +Tag = 72B2A138A8795299C86619938D12A6D8 +Ciphertext = 4143329117FC4859AF9EDC4B952FC9D649EDBA3486E3C1D6A6784E4F25 + +Cipher = ascon-aead128 +Key = 0DE9A36C0C754A4BCCB0CAF8FA6CEA2A +IV = 3AC6EB11F8C3C5937C7D85166BBC8B7D +Plaintext = 5B1E26C4089BD5F8F0BB771443725DEE98F97BE300B32D3E91D4C7D842 +AAD = 95D837B63A4881E1ED79F6 +Tag = D4C12A409005EAE5FFFEA48F3DDC26E7 +Ciphertext = 49813DF2A090E1BDD72449F3F1740BC61967FCE2B03A78DBB418C29B8C + +Cipher = ascon-aead128 +Key = 6B522150069B78826F749EE28967A672 +IV = E75E8A8A1B6921DA826803EE954BBCC7 +Plaintext = D147D55B289940DFB71EA43006587082BA4E88A5BA944B57EF66FFDF9E +AAD = DCE61B0A741BE240F35B964D +Tag = 8B1FE9725E0BBA1371394EEE3885FF56 +Ciphertext = A61AB059C17875FC872CCC16E08D24852C50524ED9205D91ABD4AAD0A1 + +Cipher = ascon-aead128 +Key = CD61E3AABEAB25FB8AF425B74DFD05EB +IV = F46EE5763AEC894246419404FDF4A970 +Plaintext = 18BC24D03468F75A58BF903C4E11ECD2B13724029A9D8806F2E43FE158 +AAD = C38C9C9C4B91E13542E0976C40 +Tag = 8D6D03EAA02299B0A57C38ABFB62696F +Ciphertext = EEFEC0FD911222B395D88BA69AF0AB218F389FBB4A134DE973ED4A59F9 + +Cipher = ascon-aead128 +Key = B87F6BE39FF987106600820B65893D71 +IV = 24720A847B33D6480F428768629F66A4 +Plaintext = DFC61E90832F0E539727ABBF391DE552DCAAAE45B0FF29C0E245DC400E +AAD = 49DA48C29567C0342E4459631690 +Tag = D381D1FC63970C57DC566E74F3BEB1D9 +Ciphertext = D2F01860A46D21A059E83854B9F21E71850E528389E539A31558D23202 + +Cipher = ascon-aead128 +Key = A76DD32FAED329762B114EBE81DAA4AE +IV = BC3E41A3646BECCE5260366C884729EE +Plaintext = 98C5F9A27DF6246EB1EECAA6FF3D297ED488B468D9A521E76BB5CA62E4 +AAD = EB88C1B4A0C6C377CCF8EC13971D80 +Tag = 630B4832BBE1E6189C6DAD86DB0F201A +Ciphertext = D5EF0198CCB7B8AF6A415ECC331F847685B08E086FEC99542D52C2E77E + +Cipher = ascon-aead128 +Key = B20F11CE50576A8FE458FAEF53FD2090 +IV = EF14EEC24F5925F5CB9CC25758700A2D +Plaintext = C1C9807C57DE6DE8E910201C177647B6E8828BB6C2E3BBC08A3E562B05 +AAD = 6453C13E9061C259A93403984D9DED35 +Tag = 3FA65037CD322B9737496A3FB387C854 +Ciphertext = 32FEB2188C75078C0CDEFDBA64467547F0E9BEE12A301093ADA08B893E + +Cipher = ascon-aead128 +Key = 57E3B2998240A08CF789C42F1EA794D1 +IV = B6AFC778BB653FB83CD32691E103B90F +Plaintext = 07F3E354C4F996DF33761F03A6C64B68F1DF1B87C8AD7D4557657A597B +AAD = 83D6D6F8004A1E9EEC35A2B60EB540181E +Tag = 622D90BA9AEEBCAAE51AE887AB54AF40 +Ciphertext = 255C979C3BFDF8DD00B49BB325FBDE704E0D78EA36C9CD3510862E30E0 + +Cipher = ascon-aead128 +Key = AC96470E18EFCD2B75EBBF356DCB2676 +IV = 633753F9F02362C3DD6AE51FB079D6DB +Plaintext = B9A490368BC78FE16A3CE4D40B86516CA7C1CEE24C29AF483C3E4B920D +AAD = 1FAFB7A93B1670DD82CFC043C03C4463FAD4 +Tag = F575B390FFAD942B815C92F533251F03 +Ciphertext = 0E469F45F0B44F34FC4B19F39C3E4636EF52903B57BF41BFDDE2D446BD + +Cipher = ascon-aead128 +Key = FBD66FF6721580A00023F89FEE700AFA +IV = EB2415E76ACFADBED8132C6CD8C2D5D2 +Plaintext = 568F08555643FD9952AA67C87A6E0E66881180285437B9C2CD87A86B3F +AAD = 03BE42B21841199485BB33AE5C7F144DEDEBDE +Tag = 31D2520B688156F2EC1CA9CA0ABEB40F +Ciphertext = 9725CCE16DDCE6243BB605F9AF3B6E3B5958CB79DD09F417E61A215539 + +Cipher = ascon-aead128 +Key = 4C583362F5CE1BC25A519C5B423126BF +IV = 2B9E978EDB76271E6AFE5E139F11BE63 +Plaintext = F5B7B551468D280B3D84126ECF8BABB68F219D3CAFFFAB70D5587BD8E7 +AAD = B0E51927C99746840ED84EC5902D08AD38A05D5A +Tag = 9E638E67CA35354CC6FD3E6C93AF2E9E +Ciphertext = 617ED321E2FE79A5D15F399A9836D1E9556742118191F0977FE18A5BCB + +Cipher = ascon-aead128 +Key = 7F22571C86B47630825CE359EA132B45 +IV = 557233A072F87CEA8008BD98AA7599C6 +Plaintext = BD358BE744A69D2D8367BBF07C845123BB48293F2638847EBB8205079A +AAD = D3BF1BAD2674BFFFCC0079C9E978355AB68271EE2A +Tag = 1D40D5454E30F8B493035BE6B0185001 +Ciphertext = 70A0E582E5825762D9C96B0F8FEE436B1A2D94477B0537A4B2BC7A3C39 + +Cipher = ascon-aead128 +Key = 1D5A5B4E3ED4F2ED4C13E572F81C1BC3 +IV = 166ABB17F711FC8E93FDB55195AECC7C +Plaintext = B433162E952EBBFC6BEA641C51729CFC190DD022C7D005CB6818A53ADF +AAD = D261E9D699E6D4FDA2432F9453D5933E33462FEB4762 +Tag = 632E28D47AAD5E0CE7C9DA3FFFAFAE16 +Ciphertext = 1F6EA8B55E9CEAC07C97913344DF9007050F93DE395823C76ACF3E2E1B + +Cipher = ascon-aead128 +Key = 6DAFA5FAAAC8D4FF59ACD3567A788222 +IV = A19BF62F6EEEC50C267734781405C363 +Plaintext = E262470D1526AFF88AB190C9D24E2E3665BDC0DD80330EFDF775FEF54E +AAD = 64F60B83970DF1EB92E0E4A22A456FD0BE5660549843AA +Tag = DD5A0DAD20FAABFC4CEC0AF484D895D2 +Ciphertext = F78EAF6CD0808E21406103CBD2D71565167E47E832A71B0A317C1C07D7 + +Cipher = ascon-aead128 +Key = 29F3A88B9BBD13238228B16BEFCDD6B9 +IV = 683EC98D0C164E6462B8400F2B892325 +Plaintext = 183116371112EBF8B93CE81BE3E3BB54A020937D629D60F8C30548B675 +AAD = 536C1A28756A93B23A91F78C806DBBFC1370BE07B2FDB8F0 +Tag = 5B04F4B2FE6EF8FDC82BDF8B8897E77C +Ciphertext = 6A533654899918CD5E92EB061BE55C0A8DDC2AFFA257FF9E08B14765FA + +Cipher = ascon-aead128 +Key = 331E7A52240DBB20E1B092164E1078F5 +IV = 38E64B4EDC9AB9F84EBCA727C1D52F46 +Plaintext = 05DA6F81714D8E7861038ED663612D3F58291961EC521AE1EB69724151 +AAD = 8D471C7988550FEE76756BD87FB8AE7837A7F55C06E5868ECF +Tag = 1710A8D7CFE202EE2752CA7C102C2B31 +Ciphertext = C8BFC93DAB50F3121D9E5B050426FF658689AA22E946038203AA10B548 + +Cipher = ascon-aead128 +Key = 48C1502DCEB3179DB6B426799A5A2B54 +IV = 9FE155331623C457F0EF61EA5D8EB382 +Plaintext = 47F05673D49BC01D7F1D94F7E7A0356EC84598ACC5D77B489C3F3DD521 +AAD = 01680618E41A1BE88F30AE59F1F3FD4E61463D5CC48F0CC78531 +Tag = 353F4B062BB5A2D3A00EABAF3ED7E390 +Ciphertext = 2917571EE0B4FADD081A9A6F8FCC444CA56AF0602191F78231AF43ACDA + +Cipher = ascon-aead128 +Key = 8ABE48D9C5246D437F738368117B5458 +IV = 12B8B2008837360F3EEA168DA1AF3935 +Plaintext = 549E3DFBA3C64C5FE0FE20EC4B13E6E4406170DCBC39E7825DBB449C76 +AAD = 7C822CE62A1976608ECCE236EE13452FAB48AF7EC5234D20213B9B +Tag = 9C1148662B38F226D2863441054FA117 +Ciphertext = 4407F635B26CB19AF82302A119074537F156BD6A545ABECFEFAE02E8C0 + +Cipher = ascon-aead128 +Key = 1C11F46A7EB9DFA53D002C95750A63CC +IV = F7B06D5F2B7FC41153D4178116D04F02 +Plaintext = 5AF22E1D5FA3DA0F416BE9F756867201A4DDF7E39EDEFEEC34CBF58D34 +AAD = 890D9DE1B875B52E209BB5C5693D70274E8B5DB4BF86E4FA86919C0E +Tag = 8D30E43DF03C403EA62893159675C982 +Ciphertext = C78767C32616D0CF7C7E81270021AA2006E9F0528080218F713347AA91 + +Cipher = ascon-aead128 +Key = ACE183F9B4B7E08CDE3812A04B110DF7 +IV = 1EFBC3F946E8B77DFB2A89991DBF4995 +Plaintext = D95B816B482B05006E3D53E493E8624267B2AF498A199B7060ED519E04 +AAD = E6148774AB87AB6769DC55EFDCC216DFD0A576123F141F0ACED1DD580E +Tag = 1080B95ACDC79CD177B7093CC7909247 +Ciphertext = 9F95F5B846DECFA7C14946BC96D3B16F0A99BD52E4C873558DFCEF2857 + +Cipher = ascon-aead128 +Key = A332A074F3D393281B12B65A2075E354 +IV = B4B0B53944998D63D176C8043EF0DD20 +Plaintext = 9AE4819EC411CD8178EFAD299C573489FADD7AB1D03BEAE4313E3D5001 +AAD = 28E2DFA5AD2984E97D8A97550190C9DC31F9D35BB3A863F5697BBEA54472 +Tag = D87864B27B004146D24898E0E7D23903 +Ciphertext = B7662CF63241E3ADFA6AA00B7D7B96AD029D23F81936A41EF851FE23AB + +Cipher = ascon-aead128 +Key = 34BB5975D1BD5B0E252A293653737CF0 +IV = 68B93B76F8E1EA4D7A56738C4F29B23C +Plaintext = 903DE0599E3BD3B6E51C19002B04E829D51E6AC22916E5F966487FCE9C +AAD = 687FE8BD4919086F3A014E99DAFE09587A85523DE6D2BD1703F355C04DD6D6 +Tag = 64BA8CAB94FBB983487A89557A1C8F64 +Ciphertext = A4EBC9739CEFA1B772203A1F46A7CDD3D1FF51CE811014432C859D06FA + +Cipher = ascon-aead128 +Key = 3FD9CBC51D3C948F793707BADCF14D73 +IV = B485FC54F8DBF59C863DDFB60ACD3668 +Plaintext = B226CD9EF93F47DD224CF1BB54D894441CE5DC36BD36E893D233D6E205 +AAD = ACDC4C6B54D088A6E495DF23F892D8CCCEC478B97381B1B7CFD8266834DC4211 +Tag = 7B6A0A6B6F8BA19EEE76D4AFB679E5A2 +Ciphertext = CF0B88F42066D728B9FC654BF1A83DC37C3D499DC84FDEE8D1BA8641E4 + +Cipher = ascon-aead128 +Key = 9E030986D256237FB806C0E595E93F4D +IV = 7BC40D50A807C1C4355A56925B017342 +Plaintext = EE0DC6913064705E1ABB5C2F169804062D2F8CF59F56F77FCC7BF2FED611 +AAD = +Tag = AC48A51DBC5BB38A777178BEBE0FC51D +Ciphertext = 9DE726E8B4E3508C733F5CF50DE26539EA9E00FBD21FF12F2EDA49798F72 + +Cipher = ascon-aead128 +Key = 2A6D400FEF8FCB300E4FABBE7307C2DE +IV = CC5E65B38452D670EE41D68E8B6432F1 +Plaintext = 33351C605ACFED8B6D6F0FF7FBC5CC7587C905CCA7EDEE64BAF0A945B449 +AAD = FE +Tag = 15E8E8D70977775EBF43A9801725AA38 +Ciphertext = D47620F679B17B3E5DAEB85A29B1BD3FCC19E4E6C146D897606B867094AE + +Cipher = ascon-aead128 +Key = 20F92D471FB77D2150C44CCB10DF63EA +IV = 84983DAE058CAF6D706B9E13D349F142 +Plaintext = FAE752DD12D2B6938CAEA64BE460BC3FDECFBC66087C75DC30BD32B75043 +AAD = 84B2 +Tag = 1B9C0A266FEFD5EFD645D9BC833CDA77 +Ciphertext = 41491E5061DA2FBBCEA92AD6249A4F5FE66D97E7555588F113399453F02E + +Cipher = ascon-aead128 +Key = E48B2E8268DB39256DC665B2F80CF596 +IV = 1CD4B72C6C8FD38D2575BB28C4F2AB88 +Plaintext = 13C36F403E7A002FE61F52CB777A697ECAC85B4ADFEBCA8ACB312E22B920 +AAD = BFC8DF +Tag = 20895240ADDA9E21496A3209457457BA +Ciphertext = F6F536DB410F740EF51135929AAC4F96F1B1F201B416C8C73127CCC804F3 + +Cipher = ascon-aead128 +Key = A8F5ED1903969AA4946DB18C045427B5 +IV = 917A7CCB7535265EDC1DA7199B9F562F +Plaintext = AE5389AD827D8E5EF113D89EB2C63ABB4F1E65C0A5C4E39DD1255D5B1D98 +AAD = 18821DA9 +Tag = 0F6D41330AF87F3AB710A9E1C8FFD64D +Ciphertext = 8B353D3B5A7560129B35A4B042D4D0C45A985634704C7FA6F3201EF5DC20 + +Cipher = ascon-aead128 +Key = 750749F88C6C2DD76E17D54D4346BA28 +IV = 2AEAE8E7DC33DD52AF7027656B0A4112 +Plaintext = 0F2D78DE5452B196E5BFB8B4CF32DBB86B4C854A7C19793E63BDA0D5DA65 +AAD = 63CFE08F2D +Tag = 1D241D790B00B7FC5FE74558A043D3A4 +Ciphertext = 9B0314A6450BB35D9C69D88EDBFD392524E62E3236894BD0F6276E1B0092 + +Cipher = ascon-aead128 +Key = D5391513C0C5F392FC75D780CF1C7C5A +IV = 928D20ADB9685528B6986CC4498512F9 +Plaintext = 56A5ACF283CBA2D118337DD89673BA6AC83BCD75CB830FE759F369E75715 +AAD = 6FB19988880A +Tag = BE3D7139BB5CD1D43B5E73373B54B730 +Ciphertext = 83D93F595D0101FED39AC95D999810E6367F7E9A5321770955739A0155DC + +Cipher = ascon-aead128 +Key = 158D4DA20C7313DB002CF58509BD045A +IV = 624A685A5DEE7CFFC1EDB75E29D1B5B7 +Plaintext = F2D37B207C61749C05F43357647022CF0EC90E2F6A5CC0C303EE8A25CD32 +AAD = 5DA695D0177DA5 +Tag = 8D5254D10DD57B0E0A82C183DABF0526 +Ciphertext = BC97C44D94CDF3F7239D1B250F54195E3FDC1D8D8FED0ADA35E1628195FB + +Cipher = ascon-aead128 +Key = C7B11CFE22E0CDD01FE4F2823CB98F49 +IV = D688BE8032A2C8426DF68AC242941550 +Plaintext = AA946EE5FEF9D587D2FA3A042995C4525B7F7C1A5C733CCFE5A19B5803CE +AAD = 8C099C5CF9CA4C26 +Tag = 5ADBD05950A5EEDADCE0AF4368E5CB2F +Ciphertext = 431AD348172FC9F742F12685E640C689D56EBFE340231D93BAD0D191E285 + +Cipher = ascon-aead128 +Key = AA7375399541798D3BAE91F6AD3124F6 +IV = E6F955288AE3CBFA237576DC83F42365 +Plaintext = 8F58E26A6EEB3C3A7A284B250C1F337B6272E0CD0E93E5E971CB284D0BEC +AAD = 031B73092DB3597E0C +Tag = A8F6DC8F1D020B8B2FD1AD98E445BFDE +Ciphertext = 7F7FCB6D44CF8C4950600DE8A82CF2A40F1E92D2C9CA2AFB657DE6A6503F + +Cipher = ascon-aead128 +Key = 5A09B292F71D33EDCCC4DEFF5DEC3B32 +IV = BDAA8A3A1FB9C50A8E70D58462C594B8 +Plaintext = 0999094108EFD98C836E0825ADEE6BD55490E1D528582D5530F057165F2A +AAD = 7EA462C2508569277E4F +Tag = DDF08C99FA174398362F942C2B8ADFCE +Ciphertext = 5622F76D43BF721099F13A22B76A6281EDC0D543015019DF7E8BD29655BA + +Cipher = ascon-aead128 +Key = 66BA10AB5908D9E3429AF67399EBD628 +IV = 986335E8B5544B299DDCAF73566E2FA5 +Plaintext = ADD2240CD1293F761BE796EF7C72EFC073EF8A1504F0402A28517D909A1B +AAD = CAFDBFD610134C82E28DC1 +Tag = 0989FA390D66DB01458F542049EB0D6F +Ciphertext = 30CFF381D421BB235D8F3AA69037F3D0065EE4C43FC7DF12632B08EBDB57 + +Cipher = ascon-aead128 +Key = 090D889E188A1AF4B312ACC18772BCEA +IV = B01AE4043569A49F6C21C644BB9F53EE +Plaintext = B9D88E606F6FB2E1F09144C3C683EC0913E2C963133C7653A36072B3CF34 +AAD = 19712305F8FFF75036F934CD +Tag = CA32D9030E01D32ADD57200AC212F6E1 +Ciphertext = 55581A04A51D952B4E9AB24FF36FB3424847DE2FAB90BAA1B7993942DD66 + +Cipher = ascon-aead128 +Key = 687C6D4A26E587881424A2CC9539FC7A +IV = B8CF69483AA1F95459181602A52B1F84 +Plaintext = C8C77D6473E58EF0B8CE6556433799B37E3F31D8FE37F112A2287223767C +AAD = 9EF3E4ADCF0747CAD7853F79B3 +Tag = 9109F754236EEF65270DD27A1B166929 +Ciphertext = C870071D8D4A1EC7AE0327FCFFA461A113E8E1534A28F0027D4974E15CCC + +Cipher = ascon-aead128 +Key = 48DDC126066A5BF91A4A162CDF79F64C +IV = CD79DE7EED4ED00E1A290C87FF56A3B0 +Plaintext = 611E09BA1789F567943B3FF253029C1C3A683154CB8AFD71C7B0D910F95E +AAD = 56D865858365A3DFDC938DED5BE1 +Tag = 95328658EFBC4CB27D451A26DD48A060 +Ciphertext = B791AD3AA88D9F63953A2884DEDEA61CCC9F5FAEB52CB1D9D62648DAD478 + +Cipher = ascon-aead128 +Key = CDAEF7A9CA354CA32B64490C926725F5 +IV = 5CFB6E440F84BD774FD6AC50608B0699 +Plaintext = 3EA9123602FFE19D0807CB80D7CAD47AC2A201CB5B4C87283BA3F2D39AD8 +AAD = 35D805953BEBE25869457189BFD9BC +Tag = 4984BAE5F4A663986AD3F0EF337DFC38 +Ciphertext = B8CFDA8E9FA9A253DBEBC5DD2D632E82E246D1A63587F1F8E31B8476A509 + +Cipher = ascon-aead128 +Key = 0AA0A24D28D2702B3F9E6C5EBBF7DA52 +IV = 8A731E49EB6E2E238FE287ACD01F21BA +Plaintext = 0B07533BD8846A402C864DC5E423F02BD6196A6507E8D80C6DF79DDE342B +AAD = 1D68516FCEA56D9B312676180A534CF6 +Tag = 6D8392536CE66CA583749E0C334244E9 +Ciphertext = D395F0C8C6702F42BA49B2974F18C7F061F8F10E963294941DDAC11A5042 + +Cipher = ascon-aead128 +Key = 9EC21F8DE2C4EEA66928C031E7857D9D +IV = 9A6E03A2B969D835D1EBD93823EAE972 +Plaintext = 3DEEF462CCD098952B5EF3523FB9892C02DA6752E5ED3F8E20AEE977E257 +AAD = 5D4279A6E2F1D7CD054FD03525E1C337D2 +Tag = 7664620174B63FD5414D5BDE50ACE470 +Ciphertext = FDFC09AEF1E3680DD4BFC4DE80145C08BF9DD429E56A1ECED8233DC36689 + +Cipher = ascon-aead128 +Key = 92AFC44E9B5F315F1F09E70FA540D1C3 +IV = 2021E89DDE3828F4B9FEBCFFA10CC03E +Plaintext = 2044B09C8E5269EFCA52161680F3A7F8B9C1F0BE14C8623AE42B7FDB08A8 +AAD = B656F2A02D76A2F43227BEA1A57E144BA0A2 +Tag = 98B80FA14171526A90E2BC0346F522A2 +Ciphertext = 7635D61DC4705C5DC227B440701B4D5AFE9CEEC7C0397C72399D354C85D3 + +Cipher = ascon-aead128 +Key = B68277E94F42CEBC1C4651E25E723539 +IV = CEEA88D8C053C096D1786E2CA53923FA +Plaintext = 7BAE7D72988CDA6562C6956C3A116CAAA8F29777E75215768C842D43D564 +AAD = 502DE1CD3C20409B64727E8E350019391C2295 +Tag = BF7079EA3C634C20DCADD6FDFD8E9BF5 +Ciphertext = 38FAFA45D069B25879D4E7B35897297CB212A58E24914DB4E430B61F57EA + +Cipher = ascon-aead128 +Key = F22B63DA10442D51F78EBE4835E4EA57 +IV = EA98C107139EE022904FA9F51D36FE0B +Plaintext = DC5419E454D665052ADA1BF4D9889A591E2C3595C0215D50730200BEEC0E +AAD = 594E7CE665B85453CAF56CFA053BE17328C8E1E9 +Tag = 75A7E069960D41C24A9226F2B096D577 +Ciphertext = 3483AEBF7CDD261B7997ADB3E1676FB827D8870361194528A37A4086F76F + +Cipher = ascon-aead128 +Key = FBBA816EE6C079BF4B7F23D081F7E32B +IV = 168501F0A11E3A0785400EDAF7F96B5C +Plaintext = 641225F53692DFCF38EB2E9B678170E0A9EBB40DB8AC4AF5791515B2DCB2 +AAD = 3352A0D3F9D46F7C8101413531631A79FCA002384A +Tag = 498DFA782C5CC37B5BCE85EC3F0510A7 +Ciphertext = 8B98387EF603C58874A71E85712BBBBE6475F9169FC1230C0FD8EF3572CB + +Cipher = ascon-aead128 +Key = 82E8D61EDE4D9841E20516F6FD09B779 +IV = 2FE3209C263E89E287317D63426F96FB +Plaintext = C245EEDD33212A97746C29CC76F7F6D427743D8AE88787355D0F9FDF6DEE +AAD = 645BBE7E91DC317C20D4A5C58B56905E4740FC2EB9CF +Tag = A42C711388CA99C49648BF16E9506B7D +Ciphertext = 527AD0C7EA636EDE96244DB855BBC52A010C7A1A5A5157D7C9B0D3782DA9 + +Cipher = ascon-aead128 +Key = FF728A5AD92AE6CAC183C4C88EBC6C9F +IV = D281AB9C7E2475D9E41CD41DC09FFC5F +Plaintext = 44651ED73667536A5F91CDD0FB86005A43B4A43922FB154AAC2128F1193E +AAD = 77A20CDAC23649EBD2451256810B9008B8D93C68FCD438 +Tag = BD85F9A26882A7C8DEE604A179AE901F +Ciphertext = 1A0E37DD78E362610E2607B2D944506D1868F6D411924EA7EC2B3288EA25 + +Cipher = ascon-aead128 +Key = CAC2087EB92E5F4C173A11E49AB5C26B +IV = 89DE4F57A06768329747D7463A15CCA7 +Plaintext = 168B619160480ED5CE88BE6A3D2298B041314E7CE6A0BEABD1FC5AB02E16 +AAD = 36A9FB4BA60C603E4F37E7C0F163E3E96B125756D56D97DA +Tag = A9EECD7F6A3345E7D7431D9AD7B5BE4A +Ciphertext = EBE41F10F29F802A412F430891F9BD40063203D6C182652CAAB8D9BBD270 + +Cipher = ascon-aead128 +Key = 57FF3A9ADF11270EB7D46D579C0F5163 +IV = 7BA41B2C0C75A09F96EC43B5B754AB54 +Plaintext = AE8B552F48DCF8AE98DD4F88A8622033094F7B4557B93D1649C1B0213A04 +AAD = 2C610A92FBD2C3FBFC31E32E4B3CCBC98370D71E361150A836 +Tag = 001E06AF05FC21B89985A4155448EB31 +Ciphertext = 677AA17748515CB298E80F6A16E990E097177F4B5CD3487DFF844A12F110 + +Cipher = ascon-aead128 +Key = 21AE206E541BB493B0608F8D90A7F564 +IV = 6DB0FD80666A55A799BB1850F3925F78 +Plaintext = 07AE65FD96249C77ECB24B06E806E3DCB01D7A0FD417CB1AEC9D3EEBE15F +AAD = 726B689142A0276301EBA871564C4B7B8C1799C4498F8BC5EE79 +Tag = AF7CD9770FD147BCEE02D0814434CCD6 +Ciphertext = DCF786669AFBC016D8C17DA2E075C8EDCC9B2389CAD51DFDA0DF59984790 + +Cipher = ascon-aead128 +Key = 49FC4FB90DEE1EC8DA93E4C78D8C10DB +IV = 23DC4A46D983EC1ABC5AA4C76089C0E0 +Plaintext = B8409876F135784461DF3524FE1EAD3CF0C60FEF78D97A795C480BB95B86 +AAD = 1FD3793DA789104F86F1037D8E8A358A9B96E1852B0FCA85A07272 +Tag = 2DF51515CAC5734F9CC82CD28B055E6E +Ciphertext = 7680CFA99D2B28CB174FD10C53CF3F01B19F97AC6C9509BE68C2CD43DA3E + +Cipher = ascon-aead128 +Key = 7EFA54C34BF46610777091DA26ADAE8B +IV = B1CB6D1FBE7A758BDADC269A6674236E +Plaintext = 878369FE617DA547424300DB5EA56115CC8B2E597EEE75F4B4F0D7402836 +AAD = 95000195950D0979BD2FB115E5C3289D9B40DE884ADCCEEED346309A +Tag = EC26475F2EA03981CA39E4AE45259BDE +Ciphertext = EAFC61293D9456553FFABB8C6CD51A20F7DD5454D51BAEE2E6587F5DA910 + +Cipher = ascon-aead128 +Key = FCF90C50F7995A59741D9D9CECE2AA64 +IV = 42762345120244DEB019CAE29F302AD0 +Plaintext = F8062F982436CFB5F18CBE514FFDC394DADE87BE9361DFC6A37F2912B7AC +AAD = 2AE76AEDD2884820714B5BC78B0CF9A9F48E2D489219F9A1C436A2ECD8 +Tag = 99A1CF5884C7BC5D54A31672BC5ABF44 +Ciphertext = 04AFB00A9183D431961CD18A1165D7F8A34E6DEAD27E4B70DBC7B0CA6404 + +Cipher = ascon-aead128 +Key = A3C6CBB4C0D5F5C8FEB4D52C15F37ACF +IV = 6361766D9A96E9FA945BA4D7061F00BD +Plaintext = 10B457FA6260912A42798B924E0BA30331F9C80CF976E61E3C66188C4878 +AAD = 1C90316E7339BBB860FC0A147618E433A8E2BB8B4E081B38C0707CC0E112 +Tag = 524EC4EB7EAA0933D289957FF5023EBE +Ciphertext = 7DE50B0A0C6F7BDB7CE6099AB1974D8F925EE105D986D8F21B4CE04A15EA + +Cipher = ascon-aead128 +Key = 2EE01A86148B7A89B7C0346CD89AF63E +IV = 950A840F54EC29C4B6075F88F07DDE37 +Plaintext = 7A1EA9B117D4C33CEA1F5384286E0D03089F90A49DE4E4932051592C028D +AAD = B6F8A7F937BD89B5B4D9371DDFC7F4207AAD28DDE10C4C921F463443CFAF57 +Tag = E38A38E568997B397323DA926ACDF3C0 +Ciphertext = 8C5D5B5B7B6BDEF49C057810F88FFD5D392E821B22628E6C624489F21609 + +Cipher = ascon-aead128 +Key = 17445B56B7C7EDCFBA66CB201ADAF34F +IV = 05B19900732AB25545E8ADAF2FDCD7B5 +Plaintext = 5A1170485CA31167BCA19C9B03D786098F9F18D19EC4527E1BC81B145C83 +AAD = 1C38B23076528013D9A55F2A8877529D3C2C430BA3CA0F7DB861DE8094A1FF54 +Tag = 3B0451B0D620D9CCD6F4C20485AC9BF9 +Ciphertext = 5B0C11EC4B34A92743F2BBD4FEAD62136753FEEED9A7D9454B95060E2B76 + +Cipher = ascon-aead128 +Key = 72D10CF2899D1937FF639293D5BF4536 +IV = 724DC33FFEA5C0E6F08B64D8026C70A0 +Plaintext = C2D4D91DEA93E07C1A180834B2E5738EBE0CE18361D9A5F5AF155B8383CBD0 +AAD = +Tag = 06A6D8C825AD82F4504D77C976DE4B5F +Ciphertext = 0E115EA4279A151E24A40775756835BDCFFC8AA599F93AF89F60802A29918A + +Cipher = ascon-aead128 +Key = 468709F4A4991C6FE4551EC8A5296A0C +IV = 74FACEEC1852B6E3C4B8BCEE7B2E4B9B +Plaintext = 44560688E7A8AF04B49D8905E8515B06FEA80F2B6D3F0A2B540650CC9F0919 +AAD = 2A +Tag = BAA8A5A2B5EB98B3A214A75612A1647D +Ciphertext = 238D43FF1F66FA6980EF97E73669233D51BFD86D5B9863E2B688C48FBBF59B + +Cipher = ascon-aead128 +Key = DF6C44BD81EF15E75DA4CDCB53731EBD +IV = ED98E2E8C8279A37E3E2996A498094A8 +Plaintext = A542FA7782B8B7D2A2EF349B2159F282D0B334D9768BBDACCCDE4996B829C2 +AAD = AF71 +Tag = 8BD33D2451EA69CDC2FB102F38C96AA7 +Ciphertext = BA1AC4F8ED3773205A061AC9070055B1677DD35AF00443BBF2949D2ECB93BE + +Cipher = ascon-aead128 +Key = 9E0DCA4DA35B4E249B8B0EC3FD3BFB7A +IV = 2159315011C796C29744E54683EB63F6 +Plaintext = 29716C4979A7458E56ADBC971F67DA0DA62881CE6911F94E78D67C9859818B +AAD = 884DF8 +Tag = FB241024940DAE2A14DC3F32861FC309 +Ciphertext = 56EC80F091A4EEED976D15A88036092B6FD162C5150D95008697FC981A3FCF + +Cipher = ascon-aead128 +Key = 7FD9802C550449F8E6928F54BA039FC0 +IV = FECACD7CA0C9CCAD848C4259DD7AC8AD +Plaintext = 7DEFB09225F447BF626E861A6C5655FFDDC80A268B3D6C13C7C43951687E5C +AAD = 3D5D98B9 +Tag = DF8A1349E2EE7023C736C9204FE852E0 +Ciphertext = 8C43CBE297BCF8F48C54ABB393CADB1A886A2794C71417051690B016A55792 + +Cipher = ascon-aead128 +Key = 3F6CCBDC485BE4AD13ECA5B87796925A +IV = 358C135543C5BFA4F8361AFB1A0FE3F1 +Plaintext = 2CC8238A7E7B3A4D90E0289A7852F348826175FF42C69850D675BD7E241D58 +AAD = A8112C3AED +Tag = D325A87D9396B171930B166115B460FA +Ciphertext = 3451E8CAFCDC04E25A0BF5777CA760E83EEDD0084EB64B6C6860C42F3C4BFC + +Cipher = ascon-aead128 +Key = AAC88C99596E279A5EB04150E70209C0 +IV = C8516DDD99AB695F0D17749CCA603B3D +Plaintext = 0DBB970C03798AA5E576FA28CC24BEB68FDD2A55CC9B1C29E3F715107E2B60 +AAD = 19FF9E756163 +Tag = C1A7591FE9A5FAACCC8A3793F0F4E93F +Ciphertext = 77AFB17025ED49BD71B2398830F6B98CF4F0C5FF5E13008DF79FF2B0CB6DF1 + +Cipher = ascon-aead128 +Key = 931E9826BCC7D3B3A319DD7697BAE30E +IV = 479527B3257738DD4747055B6DC8E27D +Plaintext = F259F18B067974365550DABEBF3F364C15FCA02AA84280C7364006204B8896 +AAD = E698723C19EEB8 +Tag = 58CB1AE8FADC3FFA789EB06443DEB7E4 +Ciphertext = F3070871F8F7B12C40EEB6FE4F9FF6EB3D95A72E96A0642019644F7E50DB37 + +Cipher = ascon-aead128 +Key = 28D3D9D1044A20318321A37A03959AE7 +IV = 211CAD0A9EAD7C5B28ECBE896CF1C78C +Plaintext = EDE867C2490EDE972BD36D67335B0F0DB364708A8BE028AFEB54F1B5DB4D7A +AAD = AB1C38BB8F54C68E +Tag = DFAF56EED3A047EB9B528EE26F8776FE +Ciphertext = 738046E9DD2E1EA105B2B6FD7B6BD6CA5C0CF1268A3DC80AB310B499443FAF + +Cipher = ascon-aead128 +Key = 68870C862DC66F7DC5652ADB7F1BC19E +IV = 07C1428E7637ACF289BEA1B605FFE9FB +Plaintext = A4652D2B4142BEDD25326FAB2B720D15AE9B479011E201583832983F69DDEC +AAD = 2475FB35EED091FB2E +Tag = 2E734F4CD95F4E0BE24F7EB216FEE7CC +Ciphertext = EB71E70511C5B8CCE7DAD06A42E7A1ED4AA9CF42D6E1BE6AA08293131833E3 + +Cipher = ascon-aead128 +Key = 016BAA2C1226E6582ED966B202F026D6 +IV = E2B87F884EAF2F1EA8F1556302E38B84 +Plaintext = A6E52322F450A0AEDED3BC27C843DB4B0EA94AB6ABE59CDCEE753CF5FD0147 +AAD = 785C075479F3DCCAC287 +Tag = 40D0B4732D4961E51C314BCAB2C73D57 +Ciphertext = 1AA4D5D6EDBF5CBFC4D03BC41CD55B9D24C73E4FD29FF3271206EB26744F5A + +Cipher = ascon-aead128 +Key = 5334B5DFA099E35AC26B2A2381ED13F6 +IV = DD5C9228901D188183407A981345BE7B +Plaintext = 614179B69B2A72A5FC47731646B008D07EB784EEFA8321EC56849593818F86 +AAD = FFA4AAF55C561F551056BE +Tag = 3338EE3019ABE6BEC799D813398AA4D2 +Ciphertext = 47F253F20F48DBB325937B9B3A295BA5334DE93A68EE04C7FEA50C419D4694 + +Cipher = ascon-aead128 +Key = 05C303B2A527D41F6DF99CA0AD5E9A05 +IV = 0B29A69B66146BDA733B2FF53800FE49 +Plaintext = 1A32623ACD69CFBE87EB10634A46CCF64F9B835B44FA32C572347AE5B3A97C +AAD = 2AC50926E0F8EF1C9E68959A +Tag = 8E0C7CD6DA51F1097E50D15622A14407 +Ciphertext = CF1F714F336587ECF5EB59F94160C6D0FD817E48030BBB49B2A31D6E46492E + +Cipher = ascon-aead128 +Key = 54D95D9D2B12F42B623DD9A8803DCACE +IV = E7941EF66533D1DABE2743EEA2A922F8 +Plaintext = 833E583255D435E3AD0428C7208286304B9CED392352AEDE726ECA53283539 +AAD = 28B074E1DBAC62A61AE7CA38E6 +Tag = 7B675CEE9F7DD1D0DE651FA9B4C09C03 +Ciphertext = 5DA7E254898C9435818CEFD1541FBA1062013543537AA1D77ECA9DCC4EF0AF + +Cipher = ascon-aead128 +Key = CF5DD61985CBDBA791291A33A20E1450 +IV = 8458DE7BEEEDB2EB4ECB896C61E13F6E +Plaintext = 1F31C0A74BE5548EA25CFEE4E4E1E9722E76408BE0BA1F1352C2AD9E8AA369 +AAD = FDBFF74CCB184264E561C4C8F296 +Tag = A1A6000C1DD91100EC8080245811C8F7 +Ciphertext = 1F9486E6E1656A54AE92514BA2DC8D0495CE7B380A9EFDD4F15CF57CAFE2F6 + +Cipher = ascon-aead128 +Key = 32D376733D2DF112CE5F0A322FCF2021 +IV = E8CAF20069C1E0251E0CEAD9767FF7B5 +Plaintext = A0BEBE6CB771FACEE27890D7076FDC35702874B7AA3630A83A28F8FC54C7AE +AAD = 91DB96AD5F0C5E88CABAA81A7EBD95 +Tag = D9349284BF9144060FD244D0592C1312 +Ciphertext = 26C4AAC9704FAC78AA3ECB2727EBDA1A5B682C2681262579A526FD89FB09E6 + +Cipher = ascon-aead128 +Key = FF827B824D5360E227B385D27EF90C2C +IV = 0D8D1BC325AFCD22AEFE410051D3F418 +Plaintext = 3364AB2D362E0F6EC4F1F3641E3887FC923A9FC81B7AEA6C13078F6C3AFA96 +AAD = E7526451F544F4FFF0E4237AED824068 +Tag = 84919020B5680D84BBF1CE66A0EE8D8B +Ciphertext = F3C90F858FE5BDE25201A6FED27098E47D5A74114F55B9258A5D74EF722DD9 + +Cipher = ascon-aead128 +Key = 52D156C425ED5F734645BFE5533A4F1F +IV = 17212A1063434091AE4ADB4FA1D511D8 +Plaintext = 311B93872FDA592DC3B752B29FC928E8774EFAA215DB9021A61FDCCDCE146F +AAD = DFB12D9824AF0E485ED2D06657882CB399 +Tag = D34D3FD0DBCB85D0531F03D191117B7C +Ciphertext = 9FD1896A3FD7680435207DAB0AB97C2B5D832AEE141EFCC26D743C71433A9E + +Cipher = ascon-aead128 +Key = 9D8A4BC1A3C4D702D57F8C6557D03300 +IV = 6CE29BFA35F44B3ACA34E719286ECD5F +Plaintext = 64F51254E4FBC957758D1EFCC0C0D1A7211164346AD7F5668CBD2DF7E66BF4 +AAD = 7351E62477F23B1B3C35BC25C90791B71DB3 +Tag = 5477D0E47B3C99F12FEB74A9FF55D2A0 +Ciphertext = F19E29E6CA6B1BA0673B55AC942C5F15A3E3F9518686B66E7818C35DED1CB7 + +Cipher = ascon-aead128 +Key = B3DBDB18550A89B5EC211E1FAB6CF619 +IV = 946B4C0D902ED308AECB78A395FF7FDE +Plaintext = 641BE5C5DDCAD9C4679111175B9355CA543C2A6070D9C0DF84860CF63695A4 +AAD = 3A8C8011ADD32638B22C40CFCDAAC8636C9D11 +Tag = 32ECE21FFE95EF7C7C50A20F17102B80 +Ciphertext = 3999F6FDE16281D3978EE7035B1A92D2B44ACC969FA5DE34A2252631A8FA79 + +Cipher = ascon-aead128 +Key = 61555C585F8113F1BDE27C9595629F0A +IV = 812D2A990F812BBB4C30CCFB0EFE38B9 +Plaintext = EE4D536A057B4E5E962F1F42EBE8E316B95B161609DCD73B0131D9E3FF155D +AAD = F37BC1D7EFB8A1A052C15C7D746FB884F5F0A7E9 +Tag = 0C21FFAACD42E93336E58A4E19F3708C +Ciphertext = B6FF759EC9C8D24B6D0308A11185FE344743661C0F4C443E517D2CBB8E2DB1 + +Cipher = ascon-aead128 +Key = E9F285316AD6D8DA1E1D960395606D52 +IV = 58C4274F7D824A7570C0B3D03B8EC59A +Plaintext = 922A0B291945B26F1B24C9B3B82A4430D123E9AF41F9447A48E4BF85D8012F +AAD = 435AA0E2B831EB7BF4996951440A8EAE2443BD544C +Tag = A5365FA31BA27AF8E8F26C7580BA771D +Ciphertext = B56F0AB7A0592ADF4EBDCFC2C8CD951A2EC545BCBBA8574B85184621554059 + +Cipher = ascon-aead128 +Key = BE506DD874F9A26C01F66ED34E27DF43 +IV = 1ED3213B2F7FFB03EC13F94BDB11682A +Plaintext = 05B234E57E7EF96025F59F5B46BCBB5C3064701BE9C433AFCD0644438CB762 +AAD = 952D700C28AF9FC8B81C99FF977EDCB76971D78E1D0C +Tag = 0DD7240DB1FA567A2081E249D705E5E0 +Ciphertext = EDB6D167B030E0D4851B0C00D8723F7EA95A3E79395890CF53120DEAD19F3D + +Cipher = ascon-aead128 +Key = 50778187ECF580E957CBD6C6C0F0B5FF +IV = 52780D11785DF29E51B5B59AC38FF05B +Plaintext = A024704149023204BC8627FDFB240C14996F47D09A250297F116825E69CCD1 +AAD = FEAA25B11C2785DB23BDB361F5EC73904711D0A409F386 +Tag = 1DE084A7E16BCD554E22DF02EEDD45FA +Ciphertext = 83C075AF23A632CBF192BF09BF6B65C206B652EF8BFEAD4566E61AF8B2091E + +Cipher = ascon-aead128 +Key = 4B7DCE16EFA28D0CD14F20E6FDD41E5A +IV = 889318E5E88208D06ECBDE0554565292 +Plaintext = 0CEA9157D4781339D394E493471077351AC2CEA5DFC55F9248A013AC873443 +AAD = B25EE22E1E1E0BE25BA5DE35FA51E74D7BB258CF2809BF7C +Tag = C575E6FC2202743F5AFB36F15F250418 +Ciphertext = D4A01F5CC2DD9A5EF52773FAF937CAE8F57DCC0A8BF224505C121DD90E68D4 + +Cipher = ascon-aead128 +Key = CEAB4A644E0FF97FF92461FF7297F2EB +IV = EFF6B4639E60F6C2EC060545A0DE6AB3 +Plaintext = 7E0A5443DE427D8D328886AC2EF0B6FF4FDF87FE05DD49F225F3F7720B8D32 +AAD = FAF826D51447AF1A8DDD20A2697083A619CF535E57F645B16B +Tag = 7AB2DBDBB0330594CEA257D21DDE6841 +Ciphertext = C54412E5FEDEE33853A94527BBA3AF1284897F04EB4036718ECA39EECB9302 + +Cipher = ascon-aead128 +Key = 6E4FB89D9C81B8828405D978F4A71C42 +IV = E61AA7C11CF3434A4A0B8DAEE127216C +Plaintext = BECF0C70C68F64C2F2352F4C458CFC9087A62263FEE56D8E6C7FD79DC6EC86 +AAD = 33B991E6CB5ADBA902303ADA267B58AC5CF8A7593ED87E5A6015 +Tag = 9E093F35C5F5E05DB2425312B722F933 +Ciphertext = E2CB47C83F1D49BFCB4E9C8E7C5BAFA38AB64E4A4CB9ABDFD9B8B25DC7C2B9 + +Cipher = ascon-aead128 +Key = 6A877102A142F3ABC81E57365BC3C763 +IV = 224D4A5239C0FB3870CD40F81C5A9276 +Plaintext = A2A165170C637C6FCE27A3BF69B7B1C338632BB6C75F8CD5DB85357633DC81 +AAD = 6C599007428159513BEE2277B623293BA6A4D5A0B4DD6CB6F3BCD2 +Tag = BD7DBF8302D8C3CF9B56EDFB94957049 +Ciphertext = 7E1A7D170834FDA5D26ED4DFCDFB3BF4AD6EB715827FFED9A7F3B2D9C06895 + +Cipher = ascon-aead128 +Key = DF9BB5BF2CB0235A58ED372E42FBF5D5 +IV = 39DBDC0FE9D3015CEC03F94D9AFEC0E5 +Plaintext = 25305474AA6A9BD30C3BB828B7CCF77DC599613F44A581771161A8C0B4B0AE +AAD = 60740DA6061472E48D5FC418B88F01B884F6C21B1CF5D9BD3D4AFC2D +Tag = 9DD9BF5546B827E41EC0A04B0920B4C4 +Ciphertext = 6150AD682CA0DB6FCB10A896E115727D729A0484EF006A551F65BBA0D7798E + +Cipher = ascon-aead128 +Key = 00BCBA28F76B5AECF364541691C2E350 +IV = 3B2BA30ABE06217B24AF2BE27768B156 +Plaintext = 1172058252A4BB02AF9BB7B15631F265A4F17296F7100BF9229854B869A563 +AAD = 981974B0CBF402F585AF75E3AD9D283D962D2A8AEFBABF2143A18FE20E +Tag = FC2C654AF2D90E26481A23E207FB6A92 +Ciphertext = 12EC548DC577DA5BEB39C5FC5A3D15D1E57581AA71A802EB9AB909362C42F4 + +Cipher = ascon-aead128 +Key = 869EA7B43FDF97E21804BB7661CD43DB +IV = B12E6F1E431DB2D105866950E8F30DEF +Plaintext = C029557FA0DCD8E362D9BA91CB18E5C87F2938C9F41F6966C3C1A61F26953A +AAD = 41975C045683079E7891EB55EB35FFB34E2D118200FD99DB5CEBE2FB0286 +Tag = 36F738F0F6C2A99666E6194E96E4F7B1 +Ciphertext = 67F2EB95B391528EE1442D1AD4057CB62C8064AC1A5401A39DE78771503732 + +Cipher = ascon-aead128 +Key = 36C0ECE0074172A844542B8EEE510498 +IV = D9F5B2B566A4E471858D969151570ECE +Plaintext = 78DF28A55A0AEB949EA12E2524B0C77215F3F210AA0DAECC6942A4F2B2E482 +AAD = FCBE82F73B0BE13CFB36A5D1C4E54D228925BF6C01CCE4C308AF307A1EBBDA +Tag = DF84C2241D6FEB7EF55B95031FA9BE8B +Ciphertext = 4F803EE232A77901C4C19B199C4C1B2CF1A92655343532EDC48F3579F0014C + +Cipher = ascon-aead128 +Key = 65A1007266F8FD5C5E6F80932528A4A6 +IV = 6B9586A4F12023E87EBC158BDE82835C +Plaintext = C09DDB8B821D902A5736EC0577866EBC48088498E3359B87993FA150E7E799 +AAD = 35223E2BCD9D74E9DC639881E26286BD23AAAC8926BC61382A57A9FF8E5E6CE4 +Tag = 9976CB49C5348D6EC9D5C8B2362AA46A +Ciphertext = CAEC4696A6013566CB8A6710331C70C256C0FFEFCCA95D8D853B0E477FCCD6 + +Cipher = ascon-aead128 +Key = 6325318772DB69F0E2208F1F6BC8D58D +IV = 6AB5D9FD6F37C0B3875DC69BA48FAE22 +Plaintext = 820753D335519EACBBFA39BA43AD9F6AA1CF082987DF52A3760C8B965542E92F +AAD = +Tag = 818485D362583CBF840A76FE660A80BD +Ciphertext = 74D98BCA4586E5D772D04DAB4C00F09B33D6FD6373C608CCBDA34B10BD20C46E + +Cipher = ascon-aead128 +Key = E6925781F3B5B34292DE2C9B867895AC +IV = C89A3AD658E32DE04DAC2658B52C4A79 +Plaintext = 11EE3A1A4BE9FD5B3EAF1C148A3B962EA5C7DAD361317A1C6FB7BCAB40D4E12E +AAD = 92 +Tag = 638AC0DD010A91C9314597A0B8DA73A1 +Ciphertext = 08AF19830417B7EB20AF9C67EC2F7CC91228B97A46684C82FD094B79D561740D + +Cipher = ascon-aead128 +Key = 2FDD71601DC264F3A51461B36696B1FA +IV = E8DAF2E922669E1558CB764834EAAFB0 +Plaintext = A80090A4978D04224071BFF73B20E4E0CC3B7B795664BDA173FDE59AE3F1F3D2 +AAD = B4E1 +Tag = 38AAE8A9DBA2496758B1869A360B9606 +Ciphertext = 1E2FD5BC3DD0DDA86AA9751E230322AF8DB53AF0D124AA27E30372A83E590592 + +Cipher = ascon-aead128 +Key = C60794A024EC16A08EA6A6710BA51C1C +IV = 7529456AA8EB0BD0F1C7A199EE17C746 +Plaintext = 45723EEB0A50A3AD5DDB7A736FDBBA6DB610082097D8485B8561A767F268F2BA +AAD = A259FD +Tag = 2F9C851B64F218A30D8223D292641246 +Ciphertext = 275E46CCE55608D7082687A3102700BFA7174EE3671C9B02BBC8B5987F076572 + +Cipher = ascon-aead128 +Key = 889B38AF6141FA8EBB2FAB153BE86FEB +IV = F231E781731A73661E0E5CCA3C1DC1E1 +Plaintext = 09F83AD862709BB94498397225B08F62DF0DB161C8DA6EC42262A8B70A6E4E99 +AAD = C7C34405 +Tag = 456912107F739132C17A4CEF2312C41E +Ciphertext = 5602DE62DA7A4EAB385EAE934F825FD7EC0A3DE9CCED080F7C98B4A757B36B0D + +Cipher = ascon-aead128 +Key = EB5FC6867AE8A3378739365B873D5B5A +IV = 5D3116A3000373528B3A7188323D5FCE +Plaintext = 2263335A52D0B0664058CFE94E13A84BE1DCF45743518BCA986844D68A04A51E +AAD = D12716C77F +Tag = 2954259B97DCD492BDCEDFB5D6A9C9FC +Ciphertext = 8BB0707DCC9C486459F53E37F5B74EB48FF4373799789C9973A5779C3FC1B848 + +Cipher = ascon-aead128 +Key = B231EF42782497180BCEFA789423FF7E +IV = 1A65D684B16E42200881F81C8C21685A +Plaintext = 6924AAC5965BBF08E5C350E5B359540DFF63F8388B596F84E41371BEC901EE12 +AAD = 59822713657D +Tag = 3AAF05BAECDFCA3737827050E39E54DE +Ciphertext = 340111FB785917E176C537725D7C3F5CA5E1034FA129E29AED81B19151FEDA7A + +Cipher = ascon-aead128 +Key = 65FC636FD36F5214FFC5E43AFEF44538 +IV = 15E54D810551DF4334F7CD6ED90A6DA4 +Plaintext = DD7E2B8CFE3BC5D7EF9076D9E947BAB209E2134680DC2828CCD2882CBACBF277 +AAD = 65E20FADB0ED16 +Tag = 12106EB327C0388AF7A0D6B9DC7EC8A8 +Ciphertext = 72CF9E500EA8E0DC011703C6E704F26FCF434975580C6A4BF50AD7C74B77A6E9 + +Cipher = ascon-aead128 +Key = 75CBFF2732CCC24098EC1F6D1F5D09C0 +IV = D28A270EA82DCCD60A7592714B2129A0 +Plaintext = 8931D041F76D0944FCB704601AAFE4C07FFB4F9FE42CE1C2365531B1A8042BD4 +AAD = 2DF0C9748860EF9E +Tag = C831AFCB91C089D959777664D78A2578 +Ciphertext = 7A1B1DF7A66C50107FE67FACFC298565FCF4DD28CEF20C79241F51E09D5A8222 + +Cipher = ascon-aead128 +Key = D9383003C24DD45E7EB638956FE000FA +IV = 4344A43DD217E0C471C6744AE818440B +Plaintext = 9E6A2AEF95C59F2A1DCC7D400D7EA8C5957A8C44315DDDEC6AB82BDC9F73B874 +AAD = 1047701431CA91DF39 +Tag = A4A82EE9B0B3C999AB7BD07DAE8054A4 +Ciphertext = BEF73602C336AA2D6483F2284C442EA946453FE69D0D18573A5C48F7B5838FC7 + +Cipher = ascon-aead128 +Key = 1AD0B95C657584F5BC5FFB3E8B1CAFF0 +IV = 05E253CA7FEDBFCD57457D149E005486 +Plaintext = 5C229E262E394E5127450825257D53D432AB722C46B0022AA3AE0DBFE2EDF669 +AAD = 123EC5172365337CC352 +Tag = 0C648F3D903CED2F9F878D5FBA961C71 +Ciphertext = CBEB7A44E4D8B3E3DE228F6738B62CE00DA44731E3E82E5102941EDF17A66E60 + +Cipher = ascon-aead128 +Key = 278601D6CD665CB373ADD9A407B44CDB +IV = 6A1193DE69B21FBECC4AFCFC46CF469A +Plaintext = 9E14FBCE839F61195B2022B6FF24D4F4B7CCE05AF4C1A1489978D6CBCD8C9C17 +AAD = F512AF89BA68B7BDDE30D6 +Tag = 0B92F17C162A46EB4EBA0F5F1E094F14 +Ciphertext = E90B369FAB5C819AE93B480E3D8BDBDFBB01C541481B01E6DBB03C0C411DD31E + +Cipher = ascon-aead128 +Key = FFD953B10F4C5E349D0D5DBE41FBEC8D +IV = 014C0696D7202DF9FD1CBBA90BDEB227 +Plaintext = F0829D15CA93D1111A5FE51607986E99B19F95D0294DFECB98236C6942D21C39 +AAD = 702979B1F2DE3688B03E4429 +Tag = A1AB1EF5921309908B2820C8685FC020 +Ciphertext = A9AA84A74944F05BCDEB58AA7A3CA67950CA8E893A1A9733D9DC136689BCAA05 + +Cipher = ascon-aead128 +Key = 8B08EE1E7E5DBC016F716AD9035844FA +IV = 9E0B6871FEF109AD6DA3DC862D9C37C2 +Plaintext = F4E56DBBB851C9EEEF2A640A5103E6020A405938D046103EC7DBCDA5490DC2BE +AAD = 40F8A912918EE28F6875ACE612 +Tag = 3004829740519B3247DBEF7A826382E2 +Ciphertext = 22DB95F2757644C6BBF11D7DE2B325772498A4D9F2587AEB058191F9F432F4E4 + +Cipher = ascon-aead128 +Key = 30C7E1F0A206CF7B68DCBDAC62F957EE +IV = 025E13F4CE2777D29BC44F9A13FFE07D +Plaintext = 3ABD2C7E861D72497E4F78114EF521455DFC35062A64858FC283D37BE9B9F555 +AAD = 3B726002A2618E4BD67199F313FB +Tag = A2F08B56A5238A0F33B64CB70A401308 +Ciphertext = 9B2E034B5117DC0E7EE6DAA6819FCA8DACDC81920E23723F78FFE63AC34FB78E + +Cipher = ascon-aead128 +Key = EE17C1F2768EA9AC3CDDF755BD2A5BB5 +IV = 9A493BCDA0EB5E9AAF3538BF4AF71FF3 +Plaintext = 8CAA7CB2C80A393533A0F10249AC6FFFF286D9E85EE484647A8777F0987B7B51 +AAD = F415F47A7698A79C65D9CFF73BF109 +Tag = 7529226C6FFEE1DC548FCD1753462CCE +Ciphertext = 554850BF785BFA97D34240B1560C79BEAF7D9E66349590CAB71A51C65E93E651 + +Cipher = ascon-aead128 +Key = 0D980D912A639B0279B4691DB9451F16 +IV = A590985A8D990ECCA5ACD794AEAC8377 +Plaintext = F07A4C8A62AF579AB634AD242C0E31FA58E52811690D2CA998024EFC06C01311 +AAD = 46E78BAEB31379A6A4656BF1DB112DB6 +Tag = C47EEA51F081B153AB06E13F618765AC +Ciphertext = 78E4037AD4BB5C54F29E2EFD52468B7C41260D6D1DF0B7FBBB67D5521214B8CD + +Cipher = ascon-aead128 +Key = 3F0033829C865CFC050B9127E6DDD2EF +IV = 3BBBC4E4DFE23B63537ADC53F1F9284E +Plaintext = 56057A89EAF01A064BF2CD55C574B9EB3C6ABC618DB50ADF6DC85B722CBA942D +AAD = C3D125F9263ADE0FEA9C51AE0B1794BEFB +Tag = AB97F33395DB1F4FAB6E65137D355E52 +Ciphertext = 886E375281D385FD107D20183FCDF8E054E5E65F5CA9D47D62D05D823C5411E5 + +Cipher = ascon-aead128 +Key = 44BBB04954F36C21659F0BF2B7CFB5AC +IV = EF416F4075B97C17D0C43DCA6DD63FD4 +Plaintext = 4EFBBD81DF1B60C3EF8D5661B08099614101F6B47875DABEA1CE7BF0E84DE878 +AAD = A7410018F3E127FB84ACCAC7E8EE621B488C +Tag = CCAACDEA9BBCDFD4B2B375B5316DC795 +Ciphertext = 84E5B9710570E59726F99BDB3A3200CAF664C1AEF4D3136339D73392CB4B5DED + +Cipher = ascon-aead128 +Key = 9B5C152491B77612742760EC6E88F164 +IV = F6A7387CF19F727E34B9138F0F1FB25C +Plaintext = 33E0C28818558885BD7ECB59E75D70579AC9BE60EABD6E75FFAD99B2D2478CE5 +AAD = FB83FDB7EB8D4BC444A3E7E2B310557B98D527 +Tag = ABF1EF7D60478793925C87BCA044AF16 +Ciphertext = 8C5743453FF07BD248089F7497E49A8D6C786998EFCC6C555D27E2E5F49DA227 + +Cipher = ascon-aead128 +Key = 61A11A7F8B8B182AF9951B1B1BC1F961 +IV = B6E7E0C951813D5052C7B4DE345A3B15 +Plaintext = 488423D49C21BE500E19E5691DFBFA9C44809A53286A832283D214C70CB1787C +AAD = 5C9010ADC0104C249CEB8161F3A1170A6689136D +Tag = C897189EB669E98672EA6422FAFC6D15 +Ciphertext = 71FF4FC7FEB9E0822518028D3AE75830DB50824136B2D3E657235DAD06978311 + +Cipher = ascon-aead128 +Key = 1223E617F191D752FE216FF65BF23ADF +IV = 60502CAF03EE92A7FAFF897203BBA121 +Plaintext = 319EB1E1F0BC86D38CB61621E0156DAB28433863760F4F976992471676738721 +AAD = E31A26B0E66E20B85602D0DEBE0E4A7140A4153700 +Tag = 35920FDB07F07134E8CBD49C483E628D +Ciphertext = 0ADF27583750E6DE955AFDAA43B3343AEEE91B973C1CC60AD727D5DA2C69E442 + +Cipher = ascon-aead128 +Key = F6323BDE80DA1DA8DA31A43F4FB60735 +IV = 5BF7DB97E8DD734CCB16AFB3C8CDCE42 +Plaintext = 44F6BF0A49B66C1F82018B442C741A70617EE97045699B3D66A961A208A2E74B +AAD = E25C366A85C95BCA74FCDCB94E61346573B3DE2926C7 +Tag = 13990C14CB423B97AEB0D72340AC3CE6 +Ciphertext = CCD261ABBF4A8F83DA7A6B3046945263B77454DD62650E4B61B5DE83B168F662 + +Cipher = ascon-aead128 +Key = 74169317957BB6F78D4C6129FC9DB0F1 +IV = 8365A1A19F9CD30FAA42792730172570 +Plaintext = 101CE613C5DDCBD4C62AD50C02CE78DFB173FA864D4AF7B058BBE0D546293074 +AAD = 4B4B7F83DC8BB8B5FAD1FE50F97A051FF20B8C80F89DDA +Tag = 37F9248B98ECA0FECBBCEB6EFDF9F3BC +Ciphertext = D65686D8FCC6CAB018B5CF8A8B91B637BCE1E653244587BEBDB829821CE145ED + +Cipher = ascon-aead128 +Key = 9DB0888280A86B9BB648F110809AD4B3 +IV = D78207EF26CD881DB6066CE75123FC17 +Plaintext = 6C841A9C740B7C1B330B5D0339086F0B2E648C96EEF0DF0DF35B4E068737D5CC +AAD = 0EFC55591C97246A1945DDF58339CBB82417861204F8B6AF +Tag = DC12A9FE9E6448FA75031C97753FEFB5 +Ciphertext = 8A2BB68E14F970BE7E66DFECF8097B8AD94DE10BF3D72E6C95532FEE32065CD1 + +Cipher = ascon-aead128 +Key = 20F6B4C737230A74C69CC724CF12C447 +IV = 308060E7BDDB0709A0DDBBA8B1D1FE15 +Plaintext = C97FFDA5A768BB144795349B41FA5F1A74C6DAB913D342F88DBCEEBA9DBBCC7E +AAD = C6A6F29CEBEA4D9D22DCC94EA4EDB09A0EA1D46DD7FB1B615B +Tag = BA47350473D89DD91B0FE935860D8323 +Ciphertext = D202E209E7DE143E7DE206A097A5AA743BE2EF556795C8BEBB8BD763E259B006 + +Cipher = ascon-aead128 +Key = BE955B1F15FF53ED3DCACC2ED482E0F2 +IV = 9EE1BCC3EAD987980E379266510A4C51 +Plaintext = 8884ED09033F7D481D49EE7F734AC7D79B1526394AAC055E230AF1F5BC8AE277 +AAD = 6F416706293FE892F53C75277656685433BCF67F2D18B493889E +Tag = FA4A396362ADF0DEA6C05396E6108AF4 +Ciphertext = 636A150E6674946291005AB7A61D38683024DA4D74E3CEB0A65D64899A83AA38 + +Cipher = ascon-aead128 +Key = 68BC8170CE1D78A2CD0B77D741B58981 +IV = 2690C534E0925728628ACA5CF5521D70 +Plaintext = BDCD37D5C190287B2476F2A6BCE381992B66057B7406FE0E7112A2EDD4FF42CB +AAD = F1D4D4CEB776E6D91144A31449D8F351095560C60E9C59166A6AA7 +Tag = D37A76ADF07EEFBE36F9AC7851DD31F6 +Ciphertext = 31C43DDA278F84FE08B60301C29E38AFAC7EA1897B67BF273DADB50589278BA1 + +Cipher = ascon-aead128 +Key = 40BE6A83C047B0759AF5467E651C107E +IV = 3A7905AB9280D5996F668083DC5AB869 +Plaintext = 45D6DA697B9A51F4F939345322C4204E42CE6F23F65D49757FA98E30064E64E6 +AAD = 6149C147F7EA642A71A92C30E88C161B7AD0246C8B1B1B239ECF323C +Tag = 307D832E10298DDFE722DF1DD9292ED5 +Ciphertext = 8C4158371A26F19CE3CDDBF50BA8A011A71930AFDFB6DE8D72BB59DC490D2A83 + +Cipher = ascon-aead128 +Key = 1A14E8D85E7530860F5355F568A89117 +IV = 1146B521ACED0615487CEDA80DDABAF6 +Plaintext = 3324AA4262DB01328E0A91115191646DAF474B0FEB09D8ACD29CDC1493105C6D +AAD = CEA05D5AB47049B1A6048EE94FA5A8292A025B28614F1306B3A0535AE9 +Tag = 1E22AB428F0D38F1BE8D557076EBC233 +Ciphertext = BC6F59CBC378E9C0C87AB4862D3F89265603DBA71C3EB363BDC0692E082495AB + +Cipher = ascon-aead128 +Key = EB5E3FE8D687A532DD8AA37C5850AE58 +IV = B53B402C8010F067AE84582DF23013B5 +Plaintext = A32EC4D7128F1D506144163E4A7C4B4F0B5CC00BF3A14B1408B60EF9358B046F +AAD = 5761F5F7784CB430918CBC4E999E860B9751C6E86A9ABEE1BD23DC6F1C8B +Tag = 353DA2EBF3A789D113E5F909AA99410A +Ciphertext = E3ADEBE757B20E15D6A812666F82D556FF17A17D2058424A406CDC37B322CBC5 + +Cipher = ascon-aead128 +Key = CA861A7597C1367F10572B542AF21FC1 +IV = 4FF5E99D4DCE3CB3066BC2125BDC63AD +Plaintext = 82DCC081A1C5BCC80941415A9CFE1D46397AB5ABD60C0B23F0A6FEC01BB1C77F +AAD = 65D820440CAE151BF2680693AAD0094C971F3DA0470E2E0CDF9208AB015D28 +Tag = 33A4B97A61F0AF5C152BDA1C214D07DC +Ciphertext = 9E390A701FBB616824CA75A44969377CBE2B5B37B6E8EE6FABB3050E294E0ADF + +Cipher = ascon-aead128 +Key = 489AF558A277350DE2A8C9C37F525A6B +IV = 6F12617461AA928D61B6F47ABE605269 +Plaintext = 6C5FB4720A4B10D10FC3A15575BC10D3365EC49FCF91E680DACC59A9B1E664B7 +AAD = 43FD0EF6174A312D6EE59DE6DC0E200A71AC168C70A9CB988F30A02FB78BEB70 +Tag = CAEC1B96A428649A59A6E260AC4D0867 +Ciphertext = 123BA36E66E7656E5C09D5C83015C42282FBEAAD3A971FF29AA91649FAEAFD0D + +# TestCount: 1089 + +# bbbc34692fe05e5fda0a3b025585622ab3e3747495e5e3655b29aae8c2a4bd33 +Title = Ascon AEAD 128 Test Vectors sourced from LWC_AEAD_KAT_128_128.txt + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = +Tag = 4F9C278211BEC9316BF68F46EE8B2EC6 +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 30 +Tag = CCCB674FE18A09A285D6AB11B35675C0 +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 3031 +Tag = F65B191550C4DF9CFDD4460EBBCCA782 +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132 +Tag = D127CF7D2CD4DA8930616C70B3619F42 +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 30313233 +Tag = 000BA92E52B5ED6B97C9D913CC4C82DF +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 3031323334 +Tag = F7CC167F8FED3AEEA99B385B8622157E +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435 +Tag = 51CCBC46D56E93B89B1A3BFDAD0AA4D5 +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 30313233343536 +Tag = B38ABBD573E071C6265EEAC4A68F65AB +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 3031323334353637 +Tag = 865C594093A9EDEE2C1D6384CCB4939E +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738 +Tag = 24F13284A0F90F906B18C7E4061C0896 +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 30313233343536373839 +Tag = 35BB5B5EBB8F21B1694603345397A443 +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A +Tag = B8BF86903450F40432F51096E55898FA +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B +Tag = 4B03B405717243D04CE7D1713728975E +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C +Tag = D2813664BA3D183EF2F9CD7135680F19 +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D +Tag = 84C04A74C7A193755A5B40394E3BA2BA +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E +Tag = 759102A6953861627AAE1836D003A294 +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F +Tag = E4230CDB8330EE9DC0CFD7C7B346E6DC +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = BD8851CD3AF9847844839A791DD70E8C +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 118F0CCED10E0BB559A85F7EDE580836 +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 1C68E3DE2C87B9A3C81AD91E1A083C6E +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = B8097B457642C490908EED5F4E891267 +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 7B59AFD062513B22047EAF7F764CED9B +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = EE064DA0C9A683619FB3C01A79C5AD0B +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 5849469C8B2805242FFB357EDA7FD6BA +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = FAAF823952248AFD0E3FE69834C15D65 +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 0A0BB58CE4513C2CFB950CCDF7C5DBFC +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 4ED362C4407B1D3BE17A51465659DECF +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = A35C52EC6E7C78C051B23D03F691916F +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = F1C946363A21CCFFE291A289202FC64C +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = F1D453E933904578EEC3EA8E85550CE5 +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 82E22C860881C0485EC5F5E8CEA42CEA +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = C6306F1F154C78833984173360AAE874 +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = EFC3E78B02AD9A80A6F0548C5B0BB5BA +Ciphertext = + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = +Tag = DD576ABA1CD3E6FC704DE02AEDB79588 +Ciphertext = E8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 30 +Tag = 2B8016836C75A7D86866588CA245D886 +Ciphertext = 96 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 3031 +Tag = 3A16FBAD0D79C8C40107BC825C7C7905 +Ciphertext = 30 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132 +Tag = 45B6BE39CDFAAB037BC4FE19676FF139 +Ciphertext = 66 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 30313233 +Tag = B8C8B1A8A1E4D95C555DD17EB46AAEFC +Ciphertext = CF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 3031323334 +Tag = F95DD3B6D7A44A9744C8F7AEFE632A4E +Ciphertext = 30 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435 +Tag = 518EAF9B6EB960F7C4528F77CA1DAEF1 +Ciphertext = 93 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 30313233343536 +Tag = A1C5E8B4A7018F479FCD981511BA9AB5 +Ciphertext = 6E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 3031323334353637 +Tag = 7DCE50DFD3D3EACCD615CBC25967202C +Ciphertext = FA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738 +Tag = B3C1E19D1E1EFBC033B197D23FBCA6B0 +Ciphertext = BF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 30313233343536373839 +Tag = B8FDF6038E39058E2E19E0DA7BAFD6AE +Ciphertext = 12 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A +Tag = CF44D29379D786B21DEA02509CA8E730 +Ciphertext = 16 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B +Tag = 7DF146989D0E6F7466A36849E02912A1 +Ciphertext = B8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C +Tag = 41469F54D4E434A7C17B39E900B3340B +Ciphertext = 8C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D +Tag = 7200D24BEA889680827E3629425763CE +Ciphertext = 01 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E +Tag = 89CB1DE2AE7D3E45BA7E9CC293548546 +Ciphertext = 20 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 8BBACE2C82A050832E46B3224A9552A0 +Ciphertext = 63 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = E87E33BA792DF45D597057279A071E6B +Ciphertext = BF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = B9301C313B0C04313AA086F8757A275A +Ciphertext = B3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = B360E82D852DC6810F277213C0F9061D +Ciphertext = A9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = DB137A276D54B14EDB73E533A5A5EB5F +Ciphertext = D7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = BA9027A1FA8400FF1BCFBD744F1A803E +Ciphertext = CC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 520902D8BA4A49CB80A324FD3758E7B4 +Ciphertext = 96 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 09DAE4F15C2040B70B2BE56EB76A060C +Ciphertext = 78 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = DB232D18359F4142ACD841E37D1164F8 +Ciphertext = 9D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 102803A1438F6A01371274DCE4E4EC92 +Ciphertext = 16 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 270E4FE50992432606EA862B4AB08CF1 +Ciphertext = A9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 457DA717874F602B3F64DB80E53BB0F3 +Ciphertext = E4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 55F95314C7652499143E49C06B3B4ECA +Ciphertext = 52 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 4FE0A5293214B15C394A7D8FAABA0990 +Ciphertext = 43 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 2B6237D59A11A29779B00A447B11F9B7 +Ciphertext = 56 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = F7488BC3128A4A17DFE3487E892607EF +Ciphertext = 4B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 9963324ED507234028425D0F64BA269C +Ciphertext = CB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = +Tag = 5A12D2A396E76224F6EE5418F6465197 +Ciphertext = E8C3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 30 +Tag = D39E0CD43E61F7D01A1B636FD60FB19F +Ciphertext = 9610 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 3031 +Tag = AF580A941E04B208804084BC23DB63BD +Ciphertext = 30FC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132 +Tag = AF0EEBDD39302D5298470382D05BEB71 +Ciphertext = 66D0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 30313233 +Tag = 82F450D352A10303A8494EC6ED08405F +Ciphertext = CF53 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 3031323334 +Tag = FD3994BE85C859063A0FA3436B1B27AF +Ciphertext = 3076 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435 +Tag = 6848C186CA92DCC20741A92F7AAFE673 +Ciphertext = 9310 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 30313233343536 +Tag = F821B59862AEC892C64AEFDE050DB4A7 +Ciphertext = 6E02 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 3031323334353637 +Tag = FA678B8FD28E1B265DE2770BBA5E90EB +Ciphertext = FABE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738 +Tag = FBAEF4A54C62C451D6404AD5013ECB73 +Ciphertext = BF79 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 30313233343536373839 +Tag = 3BA621551E91B78E92600A3F900C0272 +Ciphertext = 1204 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A +Tag = F5075468D8F2DB7929D94CD2EE71CD18 +Ciphertext = 16C3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B +Tag = 4FD99D63D0DC755961B787FA3A0DE912 +Ciphertext = B83A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C +Tag = DA7B9CD92B1475BE687800EFA947FD0C +Ciphertext = 8C83 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D +Tag = C74748E350AC26A6F2E84955EB2131B6 +Ciphertext = 018C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E +Tag = F2C1A3C1AB20FBB134B58666EC153FBA +Ciphertext = 20FD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 1564490063338629A5EF780A0025796D +Ciphertext = 6373 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 4D0F94AC9A4EDBC03EAD68418693D0BC +Ciphertext = BF77 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 72A0536EE6DB9B08D7FE43DD8E05C5E2 +Ciphertext = B3B0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = B39F5B2D8096C4195787E2BB901A63F4 +Ciphertext = A967 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = C22F39FCAF9E1C0F7C8422AEB8FAA9F4 +Ciphertext = D7FD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = E33F78CD8408D7DD8FB9EFC20F83033D +Ciphertext = CC26 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = CECEEA1FCFF000E0A0E526586830B8DF +Ciphertext = 96A3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = E9AB1EC06728B5CAE4F272B5DFDA3840 +Ciphertext = 7814 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = AAE224860C8AFE8C29125182BCAE06AC +Ciphertext = 9D29 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = F49F109C2C2F2376427EA193F8CBE127 +Ciphertext = 16CB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = DF3688F905414A1329F8A4284B5C70E8 +Ciphertext = A92E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 0665800E1B1BE00AEE71CA6C9BB19B77 +Ciphertext = E4C1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 5A28D30461956195D208299373D3C7CF +Ciphertext = 5247 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 3C1E397478E7C87B69FA73DE75EA4812 +Ciphertext = 432F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 72CDEA7AD983C26C67182CFF0D8D1074 +Ciphertext = 5659 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = F36134AB487BB5AA58ED1E4B566E3350 +Ciphertext = 4B39 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 9B697A93CF76048A63E80676F605250B +Ciphertext = CB34 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = +Tag = AF8E12816B8EDF39AD1571A9492B7CA2 +Ciphertext = E8C3DE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 30 +Tag = D3E1076A5E5666C5341E929FF172806D +Ciphertext = 96107D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 3031 +Tag = 124C81E9918E04463126BA85452573AF +Ciphertext = 30FCEF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132 +Tag = 790A715044A3E616D441C1790951404A +Ciphertext = 66D0D5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 30313233 +Tag = F5A18D9E7F98FF6B1EBC960BD394BCC9 +Ciphertext = CF5337 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 3031323334 +Tag = B54D0FF007F34FF4D5CC6095366F092C +Ciphertext = 307665 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435 +Tag = D50D94E52A31553833E8F30BE814BE02 +Ciphertext = 9310C6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 30313233343536 +Tag = C2ADCD2EA7E7397C1638B7A775D54225 +Ciphertext = 6E024B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 3031323334353637 +Tag = 9EFA75CB354CD5E83C481FB6E42E94C0 +Ciphertext = FABE2C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738 +Tag = F4CFC0E8D70C3F570F880557BC1D8CA0 +Ciphertext = BF79D7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 30313233343536373839 +Tag = 6869F4B4CA9EFCB87201FFD1BAE79415 +Ciphertext = 120429 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A +Tag = 044533D79DE2EAC4BBE1147B4CD41DB1 +Ciphertext = 16C36E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B +Tag = 906083E5AEE1B974DDCD54B3409BD9C1 +Ciphertext = B83A1C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C +Tag = 3751D5BEFCFCF8B92C8B4C6736FB9FBD +Ciphertext = 8C839B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D +Tag = A697BFED542CF2A7763C098BDEE74261 +Ciphertext = 018C98 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E +Tag = FB947B6928C4F5F4930B4BD8F1ED14B3 +Ciphertext = 20FD19 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 2CD7B2919000A89B1D71B4A2016B6E0A +Ciphertext = 6373EB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 691ADCFB47D7B024092EE2500E35A9F1 +Ciphertext = BF77C7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = D419A8BC5FC53006E86111C525F16A09 +Ciphertext = B3B05F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 0872CF670D5856C022753F367E89099F +Ciphertext = A967C1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = C9A9A80A5AB6C11665DFEAC70D51BC49 +Ciphertext = D7FDDE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 266BA8C885C6FE76F85BDDB2E4CDF019 +Ciphertext = CC261D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 8D41BB62A973286AFFED1512BC82748F +Ciphertext = 96A3AB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 72994BFDE5583AD3BF3C109C7C2520C5 +Ciphertext = 781459 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = D5D1876DE04C364766107C0B0AC38B59 +Ciphertext = 9D29F9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = F9B555F7459E9B14C76C47AB0D4BEDEF +Ciphertext = 16CB13 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 68E83CCD88AB45153E937C70C4F4D170 +Ciphertext = A92EF7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = CBF02957AE28C2B18EA1E308E13FA568 +Ciphertext = E4C1BB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 00FD4DC3A33C1722527524E0C6230C26 +Ciphertext = 52476F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = D980259A5A5CFB7BA10CD03E844B48A1 +Ciphertext = 432F0C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = B49AEF3EDC9AC55BF3CA13738BB70925 +Ciphertext = 565968 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 9AE46A9FAFC14BE36A2196E69D80B5F8 +Ciphertext = 4B392E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 1997FAE2610A881DD5627EC0C5345203 +Ciphertext = CB34D0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = +Tag = 03C0A96A9B09B64CDE66D9AB0796CD04 +Ciphertext = E8C3DEEE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 30 +Tag = C34B518F67870E904B0E15E08A1B084B +Ciphertext = 96107D8A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 3031 +Tag = A35487A8B2B9BB0005806D48A6A82BD3 +Ciphertext = 30FCEFAD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132 +Tag = 81A1BE64DB64E4D3E2C5E690FF507673 +Ciphertext = 66D0D52B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 30313233 +Tag = 8205A29C9F1747CDE8BCE331E3E925FC +Ciphertext = CF5337FC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 3031323334 +Tag = F6C07497B2029279BE7BE3226FA7F606 +Ciphertext = 3076658C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435 +Tag = 7DC77C54AF7AD4AEBE2F29BC1A939D18 +Ciphertext = 9310C6DD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 30313233343536 +Tag = 1A5F5EF8297153B4F69F9B91FF866A6F +Ciphertext = 6E024BD4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 3031323334353637 +Tag = 55E2032D9C598FEE8119C43A882B42B0 +Ciphertext = FABE2CB1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738 +Tag = CCE3AF83A257A0D22F060CE8B83508D3 +Ciphertext = BF79D747 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 30313233343536373839 +Tag = 1A1BDA5D8D62C4FB0B1B262C1A679ED5 +Ciphertext = 12042996 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A +Tag = 865FD0B0001F659C215B7F44BD434D7C +Ciphertext = 16C36E25 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B +Tag = 5945B1A375D3BA40CF435C0834C22FAC +Ciphertext = B83A1C62 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C +Tag = 892F9FC81C479C47AC37BD57D71175F6 +Ciphertext = 8C839BA1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D +Tag = 32E574BB32B467D18ADB2EE8F45E9E40 +Ciphertext = 018C9859 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E +Tag = 623C968486EF1C48AAAC18F8BE82B9F7 +Ciphertext = 20FD19DA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 64A4B314256306FB9A16AF4155C88A20 +Ciphertext = 6373EBB2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 2886FBFF0EDFBCBE382D0179F8FA2E34 +Ciphertext = BF77C71B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = C4259667339CC3E4FE425C6978CEB93E +Ciphertext = B3B05F0A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 260C1A504E8A7CF24CB06C168DCFEE5F +Ciphertext = A967C136 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 9105EB99A0CFF9A05BB29EB0475656E2 +Ciphertext = D7FDDE3B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 5284319F2DC6CF99A3E8037FF6999A68 +Ciphertext = CC261D9F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 10617DFB6AB79C17853BA9A8F4C9C611 +Ciphertext = 96A3AB36 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = D0D56915608ACBF12B895CA19218E067 +Ciphertext = 7814592E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 92480E71FF4FA4B79CED9DBE3E2C64C2 +Ciphertext = 9D29F9D5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 3D93E3F44620FFE3E533F4C346A80E95 +Ciphertext = 16CB13E5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 1BB2BA89908C1A6E1769D270CE06BDAD +Ciphertext = A92EF70D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 8AA75FD63B6C9E318F178E1859F6E0C0 +Ciphertext = E4C1BB6B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = B8F88B3EE4DE8504EBDC2FC5775F8A69 +Ciphertext = 52476FE1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 80D0FE9EF64C7AFC6A290F7BE0F94595 +Ciphertext = 432F0CB6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = E5510E8100D9718F88E73973B7535FEE +Ciphertext = 565968B0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 816B5F58304DAD0544142C7C4DDD0C80 +Ciphertext = 4B392E5F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 0470D4BBF29995051DDFFB1CCE9D5631 +Ciphertext = CB34D046 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = +Tag = 21812A398A8FF074C8B7DA46C82A94A7 +Ciphertext = E8C3DEEE24 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 30 +Tag = 8664E18A6B63695D80C860C8011F9CB0 +Ciphertext = 96107D8A29 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 3031 +Tag = BF7A34E4B7388F2F3E2B8E07EE082B5E +Ciphertext = 30FCEFAD28 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132 +Tag = A8655208176FD6FF6E6DA394A245418C +Ciphertext = 66D0D52BF4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 30313233 +Tag = EE25ABCBBE7BB1AC7B9EFF03D77536C8 +Ciphertext = CF5337FCB7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 3031323334 +Tag = 34018C75D5EB4836D4CD9A49C7537BF1 +Ciphertext = 3076658CBA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435 +Tag = 06F1AB9F4A7C0DDEAA59218CF589B784 +Ciphertext = 9310C6DD8E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 30313233343536 +Tag = 2090DF7F163A9DF032CFDB952F18706F +Ciphertext = 6E024BD403 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 3031323334353637 +Tag = 2E64C7970DC97F8418C0E4063B9F0C89 +Ciphertext = FABE2CB1E7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738 +Tag = 1D239ED22339DF5804210D0012A835AA +Ciphertext = BF79D7476D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 30313233343536373839 +Tag = AD7FFE31C9216C832D91EF0B09312E2C +Ciphertext = 12042996DA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A +Tag = 201778013CAB1B09D225B285940774F9 +Ciphertext = 16C36E25FB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B +Tag = 9DF9B34D49C7F5777FC036558E27EC41 +Ciphertext = B83A1C62AD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C +Tag = AF67C5B7D84521D2F31D7EE04FD286BD +Ciphertext = 8C839BA1B0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D +Tag = BE718CA659491E34FE7F2CCDB3A21609 +Ciphertext = 018C9859DC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E +Tag = 5F60A39C721B90B3523BAC2CF1F3C36E +Ciphertext = 20FD19DABC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = CF2CDCAD554A12C444EAD89DA6CCAD87 +Ciphertext = 6373EBB28B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 52911DB912E31602A77B20576661B84C +Ciphertext = BF77C71B3D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 597A91D4FE861C10EEBF14AFAE99D3BB +Ciphertext = B3B05F0A08 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 0DF8EE2C1145A55D95BAA9AD34F8CEF3 +Ciphertext = A967C136D3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 6FF3FEC70AA1748A3C5E66FCEC304485 +Ciphertext = D7FDDE3BE4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = A058EDC3A61500442C54C519004298E8 +Ciphertext = CC261D9F8F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 394B334128B15CFD71F84681275C8425 +Ciphertext = 96A3AB365E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 526F115BDF2728BC536004F84E90F602 +Ciphertext = 7814592EEA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 2484BF2539D963BB38F1F583FCC2EBEB +Ciphertext = 9D29F9D52A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 4DB30A6F90C98021D528B2F5F4F299B2 +Ciphertext = 16CB13E585 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = FF1551EBFCD659AD211EC0623B0CCAC4 +Ciphertext = A92EF70DF2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 37C9476F22CC47E3281C997ED8A31991 +Ciphertext = E4C1BB6B1B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = E7C222447CD86FE7249B8EA4CD8FB35D +Ciphertext = 52476FE14A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = E276F9E890B765A48F52B3773AD8A218 +Ciphertext = 432F0CB672 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = A421E2A2DD84136BB080461C3BE53C15 +Ciphertext = 565968B056 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 534745A404C076E7794EF83E09101004 +Ciphertext = 4B392E5FA6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 3DC956870A9164D712E734B0E8997DD0 +Ciphertext = CB34D04660 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = +Tag = 05D75242AFC7928D1157C10AB4AEE0F2 +Ciphertext = E8C3DEEE246C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 30 +Tag = 0996AA90E6B88BE7A2865F0AEC5C70F4 +Ciphertext = 96107D8A29A7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 3031 +Tag = 442BB53111FDCD74E0F4622E360B9C5F +Ciphertext = 30FCEFAD2827 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132 +Tag = 0F6A46461573F744B038D904E8E1DA2A +Ciphertext = 66D0D52BF401 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 30313233 +Tag = 6454F749005CA24D6DC56F2BA9A164E5 +Ciphertext = CF5337FCB70E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 3031323334 +Tag = 9345F687F1836A11DF2324EF907FEC28 +Ciphertext = 3076658CBA8B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435 +Tag = 376C1C60A0772518BA981B0DEBE8C1AE +Ciphertext = 9310C6DD8E9C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 30313233343536 +Tag = C5CEE9AAA091DD3D992879ED578611E5 +Ciphertext = 6E024BD403F3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 3031323334353637 +Tag = EE208BFE553C93E06E8A6F0744BFB4C0 +Ciphertext = FABE2CB1E7EB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738 +Tag = 11611DA1356DFCD346C1A1148EF39C98 +Ciphertext = BF79D7476D6F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 30313233343536373839 +Tag = 71000325D34908AEFDE7341C37BC5A4F +Ciphertext = 12042996DA42 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A +Tag = D214CCB7AD7BABDC38B1E25F8548649A +Ciphertext = 16C36E25FBA8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B +Tag = ECD5E1FAFA666730152C615EF7656CDF +Ciphertext = B83A1C62AD05 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C +Tag = FE4855526913E59A9A48F50B173DCF1A +Ciphertext = 8C839BA1B04F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D +Tag = 557C32C4B6A02679EA5029C0A0927D29 +Ciphertext = 018C9859DC39 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E +Tag = C897A91DA0799E355D110C043C313EE3 +Ciphertext = 20FD19DABC1A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 650EC31F07DC059890264ECD3321E0F6 +Ciphertext = 6373EBB28BE9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 352E3162A87A92DB604AB137E001D89B +Ciphertext = BF77C71B3DE9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = E00130E3529B3A179E633F858D86688F +Ciphertext = B3B05F0A08C5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 634FC36E5492CC0E116B64724E1D3437 +Ciphertext = A967C136D389 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = ABDB3D7A68E33C7A0872E32822F7186D +Ciphertext = D7FDDE3BE4E1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 62D584F26DEB1043A65F8562A85FA2D8 +Ciphertext = CC261D9F8FB8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 3F46774FEC10208AC55D72B5B392EA4B +Ciphertext = 96A3AB365E57 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 1C04B38BA86364E4BA8FAF07AB093DDB +Ciphertext = 7814592EEAE4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 240286529CEED53EFEE495645FC7E701 +Ciphertext = 9D29F9D52ADF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = B1A1DCBE837BF0BEDEB9B6A7F992C224 +Ciphertext = 16CB13E58535 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = C206CA40D83ABC6603C41251A152A7D2 +Ciphertext = A92EF70DF2EF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 2A5403095C37BFA0E5C98D44050FD852 +Ciphertext = E4C1BB6B1B26 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = E08E36F53F99024F6BDFD963D9E6C7BC +Ciphertext = 52476FE14A81 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 9ABFCC244C43EB98CDFDD5CF8E684DCA +Ciphertext = 432F0CB672E7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 07664992086E8C0C46DB49E2C08F9841 +Ciphertext = 565968B0563D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = E9A76C6625010A4D141FA41535E92083 +Ciphertext = 4B392E5FA60E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = A0E89218934E756C1E945D9ED61598E6 +Ciphertext = CB34D04660A6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = +Tag = 653B4F72D2456EE9DBDA057677A3F87A +Ciphertext = E8C3DEEE246CC5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 30 +Tag = A3E5B4F8B7A22D7A31C17FC5FCA4D8D3 +Ciphertext = 96107D8A29A752 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 3031 +Tag = 7EC55ACEF7A6590CA407A936F61FA360 +Ciphertext = 30FCEFAD28275D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132 +Tag = 4CFCCEA25BB53CEF292120521D154BF4 +Ciphertext = 66D0D52BF401C6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 30313233 +Tag = 55CBE02D912E1356A30EDC91490DFA5F +Ciphertext = CF5337FCB70EC4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 3031323334 +Tag = 4E7286CACB55627D97C69B0C904C8C19 +Ciphertext = 3076658CBA8BF3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435 +Tag = A66AF2F0132672A9C728DE3B0BDDE3DF +Ciphertext = 9310C6DD8E9CBC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 30313233343536 +Tag = 8AAC3AC98AB105666CDC41B57F182EBF +Ciphertext = 6E024BD403F386 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 3031323334353637 +Tag = 0FFEB94F5A2ACAF15A5B5AFA28DAEF50 +Ciphertext = FABE2CB1E7EBA6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738 +Tag = 85D5803AD41635387C8C97A2094FF8CA +Ciphertext = BF79D7476D6FB0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 30313233343536373839 +Tag = 6232DCFFE1844F1FF338671F1DEC35CC +Ciphertext = 12042996DA42B4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A +Tag = 5D868F1314B39A0356DAE2473C9B8D82 +Ciphertext = 16C36E25FBA893 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B +Tag = 0AB3E0EE5B278E929ACF94B9FF1A9ABF +Ciphertext = B83A1C62AD05C6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C +Tag = 2AB61A6AFBB039117A14D717FEF1D636 +Ciphertext = 8C839BA1B04F19 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D +Tag = 64266E5DD3EAC5DC6A176B1A2156A6B1 +Ciphertext = 018C9859DC3935 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E +Tag = 4B24FED82DD497366A3AB11494B70EE4 +Ciphertext = 20FD19DABC1A5C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 81153837F5A24C224CF022089B62DFA6 +Ciphertext = 6373EBB28BE97C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = E7490974AD705BB7B4ADCAE104D905EA +Ciphertext = BF77C71B3DE9F1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 9CCCC489FA07B844EF5F21E1712844CB +Ciphertext = B3B05F0A08C576 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 4A23045350256E7521E7DFEA6C14E318 +Ciphertext = A967C136D389E0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = AC7E66CFC6F56508E096707989F3B371 +Ciphertext = D7FDDE3BE4E1BB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = E811EFD262A43625169B2435546198D2 +Ciphertext = CC261D9F8FB884 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 116A2BF0E1C787DB7E34F1A73F5BD84B +Ciphertext = 96A3AB365E5774 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = D2ECE8AE282B68EC0E2599A5EC21F829 +Ciphertext = 7814592EEAE415 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = D44F612B14D93D84C49253DB445ED912 +Ciphertext = 9D29F9D52ADF94 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = B615B1CEDE896F619FE188B6C6A8DB67 +Ciphertext = 16CB13E5853541 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 5197D6A244FE7FFCA7682A3B7D12911F +Ciphertext = A92EF70DF2EF0F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = A6AEEC18053781EDF9789F05F87394C4 +Ciphertext = E4C1BB6B1B264F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 95BD28EF48CBDBF9B2906A6EA438BE16 +Ciphertext = 52476FE14A8119 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = F08F97CEB2BCD9F6E301EFCC090AE957 +Ciphertext = 432F0CB672E75F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 88ED0D0B7FE043C9B831FFEC531AEBB3 +Ciphertext = 565968B0563DF9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 3C39C9239951E42312C8B7E772F2552C +Ciphertext = 4B392E5FA60E0C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = D96DC2D3E9060E5F2ACACCA9A8F101E6 +Ciphertext = CB34D04660A66D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = +Tag = E455EF6B33B782A3DD91ED6695373C27 +Ciphertext = E8C3DEEE246CC5EA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 30 +Tag = 6A458FD77624539F22F62AC4498E9023 +Ciphertext = 96107D8A29A7529A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 3031 +Tag = 1186C5B07CBD93F9850592DAD3877019 +Ciphertext = 30FCEFAD28275DF1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132 +Tag = C9320627FB267485C44FAF3CF1DB51C2 +Ciphertext = 66D0D52BF401C6DC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 30313233 +Tag = 3221C954AEC33C48C99E498AFBC75318 +Ciphertext = CF5337FCB70EC45D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 3031323334 +Tag = 094F92EED3027C86C09E0AB8D0399B16 +Ciphertext = 3076658CBA8BF3BB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435 +Tag = B689E42F14283BA04917929A0F746171 +Ciphertext = 9310C6DD8E9CBC3E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 30313233343536 +Tag = 9CF1E38B9CAFC3046924282EC9C3A96E +Ciphertext = 6E024BD403F386EB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 3031323334353637 +Tag = 40524BC3388725341B84C3537042DEC5 +Ciphertext = FABE2CB1E7EBA632 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738 +Tag = 830B7E7D80BB56EC53E5DFFD78F38ADD +Ciphertext = BF79D7476D6FB05B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 30313233343536373839 +Tag = D57182792515A30B054CA302FA97C29D +Ciphertext = 12042996DA42B453 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A +Tag = 3C63BEE8DBF4D2B8CA4B11986901F79B +Ciphertext = 16C36E25FBA893EB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B +Tag = 28E86DDCC7FE78BF8B157424064F5877 +Ciphertext = B83A1C62AD05C670 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C +Tag = EDDDCFD6B9A6FE497D3C5021EBF23990 +Ciphertext = 8C839BA1B04F19FF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D +Tag = 0556C85C230B7EC86A8094D60DA2DB27 +Ciphertext = 018C9859DC3935CD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E +Tag = 6CCB928D9578AB5B256E6EBA95632F34 +Ciphertext = 20FD19DABC1A5CC4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = FF4AD146B3AE40035CE2D47DC825F46A +Ciphertext = 6373EBB28BE97C9B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 1611F5BD26E89FF6D79FB4F17D2F0A90 +Ciphertext = BF77C71B3DE9F1C5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 5F43D6597CA62CE1D15C3D05F86B09DB +Ciphertext = B3B05F0A08C57697 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 7C221BC601A1CDAC0F57D311284766DB +Ciphertext = A967C136D389E007 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 2CF1E82F81E92F7EDA572E554FB7A985 +Ciphertext = D7FDDE3BE4E1BB8A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 810643672710E71FAED36E09975E0DEA +Ciphertext = CC261D9F8FB8842E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = DF42A3E85D6567387E0A791372BE76AF +Ciphertext = 96A3AB365E577466 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 09BA2DAC110D637F52BD26756F56FEAB +Ciphertext = 7814592EEAE415B7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = DE2C0E70358D598EC7FDDC8E3796C670 +Ciphertext = 9D29F9D52ADF9470 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = B38396BE456C486F26932ED701D9ADA8 +Ciphertext = 16CB13E5853541E2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 8D31574309BCA0FD6305CDFF54499960 +Ciphertext = A92EF70DF2EF0FAA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = DDB2C3C620DB32C00E18EF700A35FF7D +Ciphertext = E4C1BB6B1B264F12 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = C5A4F9AB198C26FC42FD0BC9542AC00D +Ciphertext = 52476FE14A8119E7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = E7D31E1371B0E6ACF2BEC9413DB2CB0B +Ciphertext = 432F0CB672E75FE4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = F16939E603C6E040CABEA424BB549226 +Ciphertext = 565968B0563DF95E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = B662A8CEAD07581A723D447A452225A4 +Ciphertext = 4B392E5FA60E0CBB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 2021222324252627 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = A1381376EDA2316C9683DC3F391DC406 +Ciphertext = CB34D04660A66DBF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = +Tag = 329BC950AE101B9247F3605EBEDCBF6C +Ciphertext = E8C3DEEE246CC5EAE3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 30 +Tag = 558544B3E0BFA4E8376EE8DF76A48386 +Ciphertext = 96107D8A29A7529A79 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 3031 +Tag = CFAEEDC161BED25C45CFAE2BA5EDE064 +Ciphertext = 30FCEFAD28275DF1A3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132 +Tag = D53C2882E73404CAACF83950F538B9CE +Ciphertext = 66D0D52BF401C6DC1C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 30313233 +Tag = C2CC82BA76602C2AF3CF23CACF6FBEFE +Ciphertext = CF5337FCB70EC45D17 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 3031323334 +Tag = 4131DE4469C5B637B936A2B60B041BD7 +Ciphertext = 3076658CBA8BF3BB6D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435 +Tag = D90B8789DAFBFFD15EDF4621B406DC39 +Ciphertext = 9310C6DD8E9CBC3E40 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 30313233343536 +Tag = BEAC5026FE771F3375DEBC1D69BB5311 +Ciphertext = 6E024BD403F386EB9D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 3031323334353637 +Tag = 4CC6D5216D0215313E08F384D2D674C4 +Ciphertext = FABE2CB1E7EBA6329A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738 +Tag = 19CCA281C41C56EE49AF66737E2985D1 +Ciphertext = BF79D7476D6FB05B88 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 30313233343536373839 +Tag = C74440FDDFC2264AC55D072E594F4EA4 +Ciphertext = 12042996DA42B4536E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A +Tag = AA0B265A0C5862A5D1C3E32B6738B16A +Ciphertext = 16C36E25FBA893EB46 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B +Tag = B8CA7ABEDD607BAB410117733246E064 +Ciphertext = B83A1C62AD05C670D6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C +Tag = 5A4929216DE8F237BF514A98B7A976D9 +Ciphertext = 8C839BA1B04F19FFE2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D +Tag = ED2734068C7D4AEE8FA5C1A7714F9E4C +Ciphertext = 018C9859DC3935CDEA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E +Tag = CF7089E8C1C27A8BBD286393716751CB +Ciphertext = 20FD19DABC1A5CC449 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = FC9AC21399C069DEED58C9D07D0EFBFA +Ciphertext = 6373EBB28BE97C9BAC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 972116D01CCC9733F4FABDEE5EA0C888 +Ciphertext = BF77C71B3DE9F1C5B3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = B51634A3A91D3437AB565186E92660F6 +Ciphertext = B3B05F0A08C5769749 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = B769576993D2EB4AE6B3D4FDA2D0B466 +Ciphertext = A967C136D389E007BA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 50A75AE70DA6BF8067DB75742C154717 +Ciphertext = D7FDDE3BE4E1BB8A71 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 65A7212A2D39FCEF082C7E83EFC82D43 +Ciphertext = CC261D9F8FB8842E82 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = DE9F038B06585F76B519D611B843DA57 +Ciphertext = 96A3AB365E57746625 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 1F0CFDB96ACE977F17A9551B0E5C6516 +Ciphertext = 7814592EEAE415B75C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = C07F414F69653505D497F0B8299F714A +Ciphertext = 9D29F9D52ADF9470AF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 23FC2D2A85F58DAA70433F6A37AAE40B +Ciphertext = 16CB13E5853541E2F3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 16FF622848C79764C301517B0BD70CE7 +Ciphertext = A92EF70DF2EF0FAA74 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 82C37B1EEC0E908114688368D8FE8186 +Ciphertext = E4C1BB6B1B264F12EE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = E2C3F52B32EE7C722710A8D0724BD460 +Ciphertext = 52476FE14A8119E7CE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = D5AF7580C690A1732A9DC0A5A0F57C50 +Ciphertext = 432F0CB672E75FE412 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 28A99AA90D961BB17AFFE431E0721E29 +Ciphertext = 565968B0563DF95EA9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 5753656333FD6F41D5A5EFB99EF32576 +Ciphertext = 4B392E5FA60E0CBBCA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = B55047438EBE45F11374D66D6E75DDAB +Ciphertext = CB34D04660A66DBFBE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = +Tag = DF96F8B1F5C34F2E8C96D3305D849297 +Ciphertext = E8C3DEEE246CC5EAE3E8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 30 +Tag = D01889CE22E2BA84DC747E0EF775E8B0 +Ciphertext = 96107D8A29A7529A7941 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 3031 +Tag = 58D5D716AE8FFF42F8F1761C91CBE3D8 +Ciphertext = 30FCEFAD28275DF1A31E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132 +Tag = 83CE3E3BD880A21173C38B03C449D313 +Ciphertext = 66D0D52BF401C6DC1C0A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 30313233 +Tag = 8C216619E70A01CA5BA35CDA4691D46E +Ciphertext = CF5337FCB70EC45D179E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 3031323334 +Tag = 303DC870E662189EFFD833181929BA81 +Ciphertext = 3076658CBA8BF3BB6DCC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435 +Tag = 08342785CE20B1B46F559878F12EBAE4 +Ciphertext = 9310C6DD8E9CBC3E406C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 30313233343536 +Tag = C6D690F447FEB2DB1E694F6D27032319 +Ciphertext = 6E024BD403F386EB9D1C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 3031323334353637 +Tag = 2A0F1EB0B5DFCCC7CC34F681209F9509 +Ciphertext = FABE2CB1E7EBA6329A30 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738 +Tag = CEA93E193EA1C88162EEAA4DB2841C11 +Ciphertext = BF79D7476D6FB05B8891 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 30313233343536373839 +Tag = 0E64692CF6041FF8C367E1423253C84C +Ciphertext = 12042996DA42B4536E5A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A +Tag = ACC5A8DA6F097013D5AC9B0971D6A35B +Ciphertext = 16C36E25FBA893EB4673 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B +Tag = ECA227D6BD4075A8AD3218D2D826D01F +Ciphertext = B83A1C62AD05C670D6E9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C +Tag = 2532DE15CEAC89B92FEE06C7894F9E0A +Ciphertext = 8C839BA1B04F19FFE26C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D +Tag = 13F4B1C058E57A869AEC24957A20B3F3 +Ciphertext = 018C9859DC3935CDEAA3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E +Tag = D0E881DAAB9B82A8E0A3BB1E23055357 +Ciphertext = 20FD19DABC1A5CC449A6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 0D242426D5B8D86DB72F35B5543A2655 +Ciphertext = 6373EBB28BE97C9BAC09 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 3A15C6C9D3FF810A53B216A29B7844BE +Ciphertext = BF77C71B3DE9F1C5B372 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = DE34243DE3FDD318F37B785FA6651BC6 +Ciphertext = B3B05F0A08C5769749A3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 88F5AA823357D40CF629CBB136E67852 +Ciphertext = A967C136D389E007BA42 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = B1836437A5F54D28369C9B34FB383D24 +Ciphertext = D7FDDE3BE4E1BB8A7157 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = BC6308CDDE03C255DD57C64D0993DA09 +Ciphertext = CC261D9F8FB8842E82E2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 9C33033CAF3935C3A8E3D7F48E41729C +Ciphertext = 96A3AB365E5774662556 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = B9A9148D71C7249A56F99B35AF774F42 +Ciphertext = 7814592EEAE415B75C50 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = A72A0A6E1B066AFAD8C9A0144F22612E +Ciphertext = 9D29F9D52ADF9470AF4C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = E3900686DD247E7F72645E366751DBB9 +Ciphertext = 16CB13E5853541E2F36B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = A9A58493CB2C1C653AC7CA6F934FB2E8 +Ciphertext = A92EF70DF2EF0FAA74A2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 599123D4393898409A7D413627314515 +Ciphertext = E4C1BB6B1B264F12EEC2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = DB1FD9D438F3B35B5AD69ADDEEEE04FC +Ciphertext = 52476FE14A8119E7CE36 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 8C9D42BF32F634083EA44F95C7FB7B2A +Ciphertext = 432F0CB672E75FE412F9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 5A9392FFEC7D6A7134D09B72E3809528 +Ciphertext = 565968B0563DF95EA912 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = B88691F26054800AC3579B2B815DD262 +Ciphertext = 4B392E5FA60E0CBBCA54 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 20212223242526272829 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = FC8AFEEAF2C3E7D84C2CEDF2AD323735 +Ciphertext = CB34D04660A66DBFBE9C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = +Tag = 4657914B9DE7C78E25D6A482F7EB3CFA +Ciphertext = E8C3DEEE246CC5EAE3E872 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 30 +Tag = B75B9176C5BEC0B1A80E106C0C115FCF +Ciphertext = 96107D8A29A7529A7941BD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 3031 +Tag = 09550B4148BF47E5C21C61319580B144 +Ciphertext = 30FCEFAD28275DF1A31E10 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132 +Tag = 7F7D8F578D8C6E3D4723E78416C1CECE +Ciphertext = 66D0D52BF401C6DC1C0AD4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 30313233 +Tag = 040A99DA47F3C1059FF7F28027F71840 +Ciphertext = CF5337FCB70EC45D179E0C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 3031323334 +Tag = C8AFB6150AC0CF74391B000146917AAD +Ciphertext = 3076658CBA8BF3BB6DCCAA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435 +Tag = 4BC95B3D8F5490B081784CB351DC5872 +Ciphertext = 9310C6DD8E9CBC3E406C0E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 30313233343536 +Tag = 82A4ABAD3E955008F171798D59BA2CEE +Ciphertext = 6E024BD403F386EB9D1C56 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 3031323334353637 +Tag = 990A8A3B3121855E7B42C2C8028AA77D +Ciphertext = FABE2CB1E7EBA6329A3008 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738 +Tag = B4065ECAD8E520E094DC6FCE197B393C +Ciphertext = BF79D7476D6FB05B8891A0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 30313233343536373839 +Tag = CAC91A8655345AFBBD37DD9C787DE80D +Ciphertext = 12042996DA42B4536E5A5F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A +Tag = 78B2DF7BB2A41734786A059FDD9FFB23 +Ciphertext = 16C36E25FBA893EB467330 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B +Tag = 6FDEF8590891CF76B39A8A2082202395 +Ciphertext = B83A1C62AD05C670D6E922 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C +Tag = CA69BBBB6427822E76F60C651BBC50D0 +Ciphertext = 8C839BA1B04F19FFE26C69 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D +Tag = 2DDC617266ADB223CC28B351082ACD53 +Ciphertext = 018C9859DC3935CDEAA338 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E +Tag = B2D19DACF08E95FE78E1BB177FA6E4C2 +Ciphertext = 20FD19DABC1A5CC449A621 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F +Tag = ABD40E375CD362C200F939973AA1237C +Ciphertext = 6373EBB28BE97C9BAC090C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = C5E1E41291DF5AFAECE7298CA53211F9 +Ciphertext = BF77C71B3DE9F1C5B372EF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = F1D0E66E72CC24B6E523140045F7D750 +Ciphertext = B3B05F0A08C5769749A3B5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 5E668C2258BA2711E92422F616113B51 +Ciphertext = A967C136D389E007BA42FB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 8D1E1DB3962E92BAA027868D07B8EBD1 +Ciphertext = D7FDDE3BE4E1BB8A71570B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = D704828CBBF654BD7F6496F7547255F8 +Ciphertext = CC261D9F8FB8842E82E22B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = B7FF6CCC01CF6D2422271BDF294F1BAE +Ciphertext = 96A3AB365E57746625562F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 94305136BE5EAE01BF759D599FF07B2A +Ciphertext = 7814592EEAE415B75C50EB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = E376EEFB9CBB89338C1DF4ADEE1F0F93 +Ciphertext = 9D29F9D52ADF9470AF4CBC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 0802CD049C3850C223F572EB50791177 +Ciphertext = 16CB13E5853541E2F36B38 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 0D93A7B2619FE75ACF6A3EFE9AB34F0B +Ciphertext = A92EF70DF2EF0FAA74A21F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 9B4603D0BC450DB88589CD1D22E32320 +Ciphertext = E4C1BB6B1B264F12EEC2AB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 4485F6F014C03CDA0092418AEDB5AAA9 +Ciphertext = 52476FE14A8119E7CE3696 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = DE9F38E0D43F780918F751AEC2F558D5 +Ciphertext = 432F0CB672E75FE412F94B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 0412D40AF7707B4633D15F95220001CA +Ciphertext = 565968B0563DF95EA9124E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = F18582B0998B948A61DFE150D176990B +Ciphertext = 4B392E5FA60E0CBBCA547D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = F78E4DE7182EEFAB1EC99A93E45F2128 +Ciphertext = CB34D04660A66DBFBE9C85 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = +Tag = 3681E50093528EA0705C07B5D3DC6486 +Ciphertext = E8C3DEEE246CC5EAE3E87231 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 30 +Tag = D2A3F12F54CC8C9929D3596F652D3455 +Ciphertext = 96107D8A29A7529A7941BDC7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 3031 +Tag = 4D3B2B529A1128FE7FE442F253F1F017 +Ciphertext = 30FCEFAD28275DF1A31E10C0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132 +Tag = 5D29DF34FD308C61C71F5CED12F170BE +Ciphertext = 66D0D52BF401C6DC1C0AD4DA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 30313233 +Tag = 4866C3547E2FC9E659C09D56FF266F17 +Ciphertext = CF5337FCB70EC45D179E0C3F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 3031323334 +Tag = 9E4982B0AEEB68020D86E4405A500097 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435 +Tag = 0C1AA3849275BF49196BC7064C2B9964 +Ciphertext = 9310C6DD8E9CBC3E406C0EBF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 30313233343536 +Tag = 9C7CE7562346B9927ABD8B04C5519BDA +Ciphertext = 6E024BD403F386EB9D1C56F4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 3031323334353637 +Tag = 120B13740D49379670E84703EF29F020 +Ciphertext = FABE2CB1E7EBA6329A30080F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738 +Tag = 821ACCDE77B9401B62C58638757D62BD +Ciphertext = BF79D7476D6FB05B8891A079 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 30313233343536373839 +Tag = E96E05B6B889791513199E1FB7271D37 +Ciphertext = 12042996DA42B4536E5A5FBC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A +Tag = DDB1D2A632A3C697C858B48CC4AE3B83 +Ciphertext = 16C36E25FBA893EB467330C2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B +Tag = 10128E8D21684B829D3988F82CA51E68 +Ciphertext = B83A1C62AD05C670D6E9220E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C +Tag = 8CC35ADE888FA74F5C947BFFFB63CB7B +Ciphertext = 8C839BA1B04F19FFE26C69A2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D +Tag = 1156AECB331415B2B2820493A5581374 +Ciphertext = 018C9859DC3935CDEAA33884 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E +Tag = 6115D19E3062AD7797985F16A0A18155 +Ciphertext = 20FD19DABC1A5CC449A621D3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 4266D36C2BF6F26167A53EB84682622D +Ciphertext = 6373EBB28BE97C9BAC090CF3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 467F2B78802590AFAD69A73B3D62A2F6 +Ciphertext = BF77C71B3DE9F1C5B372EF27 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 71982F096057F86BCE93935BE1DA5E2F +Ciphertext = B3B05F0A08C5769749A3B565 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 01BDFB03BC1930BA5FAA46372DB93A2C +Ciphertext = A967C136D389E007BA42FBC6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = D96CD52E090BE9EF4BD417DAF81F2C2B +Ciphertext = D7FDDE3BE4E1BB8A71570BD3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = A923ED56F9DCA3D85D6362A381BFE4E1 +Ciphertext = CC261D9F8FB8842E82E22B10 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 8441B6F3291F42A30509BC844E625C4F +Ciphertext = 96A3AB365E57746625562F5C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 81DA1DC645FB2394B9DBD9C267D94D6B +Ciphertext = 7814592EEAE415B75C50EB97 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = A8FD904178509873F8B4852CD27DF443 +Ciphertext = 9D29F9D52ADF9470AF4CBCE0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = EE621CB279D7B623CB85D8E73036D0CD +Ciphertext = 16CB13E5853541E2F36B3824 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 68C4A44B20C0CD1EFC71DAFE69DA610F +Ciphertext = A92EF70DF2EF0FAA74A21F97 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 391ED0DC1FFD4478DE6548C6C67504D2 +Ciphertext = E4C1BB6B1B264F12EEC2ABB5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 901926CF13F56400E1E8176D94248D06 +Ciphertext = 52476FE14A8119E7CE3696C4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 0719154699A3928520377D0CF82E7177 +Ciphertext = 432F0CB672E75FE412F94B56 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = F6D1D9F3418F33B2E1F058EFF57D4369 +Ciphertext = 565968B0563DF95EA9124E5F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 933C4C9DAFB8A11E6F14408D096DE42D +Ciphertext = 4B392E5FA60E0CBBCA547DB9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 2AC88719A60D5742E568D8290AF8C01C +Ciphertext = CB34D04660A66DBFBE9C8566 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = +Tag = A5C650E11348C7DD427F3977AB9B630E +Ciphertext = E8C3DEEE246CC5EAE3E8723138 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 30 +Tag = 540B2C86C4756D874D4BBC8A1F90D2AF +Ciphertext = 96107D8A29A7529A7941BDC7DF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 3031 +Tag = C316D74E4A015C6A38604E071F1FA24E +Ciphertext = 30FCEFAD28275DF1A31E10C057 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132 +Tag = 4F1C8FF225BDAEAC2DC75AA336BB1091 +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 30313233 +Tag = C4A223E3C7901593013C4F37C9464D8D +Ciphertext = CF5337FCB70EC45D179E0C3F51 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 3031323334 +Tag = 9DD5F6D3DDBE9E57011B4FFBC894A190 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F12 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435 +Tag = B69FAD3EDD6851794BBC2D554404D31D +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 30313233343536 +Tag = 60B5216CA89DF8E1C2489E758A680F44 +Ciphertext = 6E024BD403F386EB9D1C56F459 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 3031323334353637 +Tag = 3A9BFED4EDADD05C4ABE22343280F77B +Ciphertext = FABE2CB1E7EBA6329A30080F26 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738 +Tag = 18A89CA63068E80A3676636B3E0252D0 +Ciphertext = BF79D7476D6FB05B8891A079BE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 30313233343536373839 +Tag = E4F0519C111A9AC8F6685F7F2A9378F1 +Ciphertext = 12042996DA42B4536E5A5FBC1D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A +Tag = 45712FC490301B0C93F47381D6296819 +Ciphertext = 16C36E25FBA893EB467330C2C8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B +Tag = 6280CF0C7A4A6A400506E2826AB7CB69 +Ciphertext = B83A1C62AD05C670D6E9220E0D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C +Tag = 7420BD62481BAF7BAB1D6A38015347B2 +Ciphertext = 8C839BA1B04F19FFE26C69A28F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D +Tag = 5F3F5575F649FB7D9C48EC5B96B55D18 +Ciphertext = 018C9859DC3935CDEAA3388459 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E +Tag = 6B63939755DC7254128A2DCEDB92B946 +Ciphertext = 20FD19DABC1A5CC449A621D34D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 0759D0EBC6A14033A1315C705CF12F81 +Ciphertext = 6373EBB28BE97C9BAC090CF399 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = C09A7C966EFADC7966A420F5DE14E2F9 +Ciphertext = BF77C71B3DE9F1C5B372EF273A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = D542BC7B4FAEB0F8B5C3AE41B85F17B3 +Ciphertext = B3B05F0A08C5769749A3B5658B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 4ED6B9DBBB726BDC2EC95B0671EEAFFE +Ciphertext = A967C136D389E007BA42FBC674 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 9ABB59655893DCC8CF4D40E64ED517E9 +Ciphertext = D7FDDE3BE4E1BB8A71570BD346 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 3EF8C11D9C45856A63A26E2765D1D09D +Ciphertext = CC261D9F8FB8842E82E22B1067 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = DF0DCFC10353630F299EAE10FBD09739 +Ciphertext = 96A3AB365E57746625562F5CE7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 12F27E5704DCFC717765332E44F3A2C9 +Ciphertext = 7814592EEAE415B75C50EB97F5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 6F3487112073DC520A51633DFEA7A3B2 +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 5582308D6F32B70D3E23BE880FBDC6F6 +Ciphertext = 16CB13E5853541E2F36B382403 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 2FCC7A2655B665682976273CA22CCB64 +Ciphertext = A92EF70DF2EF0FAA74A21F9739 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 2E166111C50BAC5781E01B928535C4A5 +Ciphertext = E4C1BB6B1B264F12EEC2ABB542 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 9332CD7367F44B319403F2207EAB5677 +Ciphertext = 52476FE14A8119E7CE3696C489 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 2F78B7B5BDEDE143D1B408B3ADBA0379 +Ciphertext = 432F0CB672E75FE412F94B56CB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 6EECBFBA521B07BEA4E5782C1D7D1BF6 +Ciphertext = 565968B0563DF95EA9124E5F45 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 169145B7C828410D4060E1EE6D3D2B82 +Ciphertext = 4B392E5FA60E0CBBCA547DB96E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = B9F0100EF9F99275B0A5087F234F2A20 +Ciphertext = CB34D04660A66DBFBE9C856601 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = +Tag = D52C675734AD306A5BC54C1422934D5D +Ciphertext = E8C3DEEE246CC5EAE3E872313897 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 30 +Tag = 84B6728EFCC82F5E5F0C6D32E34E7687 +Ciphertext = 96107D8A29A7529A7941BDC7DF1F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 3031 +Tag = 81DD0A19989D418026C24E1382C9522C +Ciphertext = 30FCEFAD28275DF1A31E10C05795 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132 +Tag = D755985F7C57ED72EBFDB5756CDC1DA7 +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 30313233 +Tag = 9CA02085703482573DEB076CCC8C7264 +Ciphertext = CF5337FCB70EC45D179E0C3F51BB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 3031323334 +Tag = BF8E03EA7CC52596887D7C9DEEEA6BCE +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435 +Tag = 85BC4E1A3ED915385A34AEE6423C25C5 +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 30313233343536 +Tag = 75EA44187A78F151147B100DA7492B31 +Ciphertext = 6E024BD403F386EB9D1C56F459CF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 3031323334353637 +Tag = A94F141A7B9949A791C5A3105556F71E +Ciphertext = FABE2CB1E7EBA6329A30080F26E7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738 +Tag = 2AA2995F143AA03F3968F752FB5F2603 +Ciphertext = BF79D7476D6FB05B8891A079BE8A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 30313233343536373839 +Tag = 1B0BD21765FED84BBF8B6D2A2730B790 +Ciphertext = 12042996DA42B4536E5A5FBC1D9B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A +Tag = C6772D336A5869EA15BC6AADD329889C +Ciphertext = 16C36E25FBA893EB467330C2C80B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B +Tag = 5F1BB28A88653BECF5915E05C2557269 +Ciphertext = B83A1C62AD05C670D6E9220E0DD9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C +Tag = A914F89024B41648EAEB65719EFC876B +Ciphertext = 8C839BA1B04F19FFE26C69A28F56 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D +Tag = 296E6F3E54AB27A4947860057BD50BD8 +Ciphertext = 018C9859DC3935CDEAA3388459C8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E +Tag = B61686E7B30F291CF84B35C3CE9D70D8 +Ciphertext = 20FD19DABC1A5CC449A621D34DAC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 8CA523BAF7F942477EEA9C566B251BB5 +Ciphertext = 6373EBB28BE97C9BAC090CF399C1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 6900C97F3F8B2C856031008BCBD2035A +Ciphertext = BF77C71B3DE9F1C5B372EF273A08 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = F4B00F09928AD3FD4D234E3B8105594D +Ciphertext = B3B05F0A08C5769749A3B5658BCB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 56377C404671C5EF8518B1334AD0921A +Ciphertext = A967C136D389E007BA42FBC6747E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 795AE91150B6231F83DE93515BCD3AF4 +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = FEBBF6DBAA6C555796A4C739B510D152 +Ciphertext = CC261D9F8FB8842E82E22B106796 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 869541E6D839B2D595E19264222DCEA9 +Ciphertext = 96A3AB365E57746625562F5CE7C5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 332E231D1A099BAD850EAF086DB5643F +Ciphertext = 7814592EEAE415B75C50EB97F59B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 86B68136DB925F31CD18D197ED5281DE +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A448 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 006099233BEE47F4185BA54EFAB990B3 +Ciphertext = 16CB13E5853541E2F36B38240366 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 91B65B27A817333B4A2510650E9D1C81 +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = A32792BE3E001694F79F7DCDCDA93342 +Ciphertext = E4C1BB6B1B264F12EEC2ABB54276 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 13833906F39FB3C92ABC7F205DB3E6CF +Ciphertext = 52476FE14A8119E7CE3696C48930 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = EEE88DF2698662BFE855A179AFB942D8 +Ciphertext = 432F0CB672E75FE412F94B56CB0A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = ADDE74A51F85431EF43C1EF483492CDB +Ciphertext = 565968B0563DF95EA9124E5F4506 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 998AF346CF0C58F320FEEEF984E031E1 +Ciphertext = 4B392E5FA60E0CBBCA547DB96E32 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 349723CF938F6D468556FF3AB1F76372 +Ciphertext = CB34D04660A66DBFBE9C856601F5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = +Tag = 83AECC1DA0834A52940EC4BFCDDB6404 +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 30 +Tag = 70915182EE42081F9D1622AD33F30BE6 +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 3031 +Tag = A61FA2D1A56EF969B16917BF71B4771E +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132 +Tag = 6A05A976C212C3C1534838EC99A13FCE +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 30313233 +Tag = 6429C3D7D02FCC989BE215B45CA38F36 +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 3031323334 +Tag = 535DE9380C3895D2F561D8A3D58080F6 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435 +Tag = 82DF8B4C4A7E3C3FE9B6339251CCB933 +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 30313233343536 +Tag = 954DEC0C7365F71B8232D8FF460A9691 +Ciphertext = 6E024BD403F386EB9D1C56F459CFDC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 3031323334353637 +Tag = 3035A42578E145B3813FF62F8A94C187 +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738 +Tag = 1CC15730F75A187CAF77A9504AF37DF7 +Ciphertext = BF79D7476D6FB05B8891A079BE8A19 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 30313233343536373839 +Tag = 699A26D7A85A6B66089424F38DAB364D +Ciphertext = 12042996DA42B4536E5A5FBC1D9B23 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A +Tag = 559DAD654E60D8A3B777831D61781AD7 +Ciphertext = 16C36E25FBA893EB467330C2C80B34 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B +Tag = B178731459A4013C05763C6A552E1122 +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C +Tag = FE8CC35DD71742AE395653D3C6C46C20 +Ciphertext = 8C839BA1B04F19FFE26C69A28F5635 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D +Tag = 4786568B2874691221F55EF3227DE262 +Ciphertext = 018C9859DC3935CDEAA3388459C8A7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E +Tag = D7F316F7F9AEE44F263C8D7B7094C199 +Ciphertext = 20FD19DABC1A5CC449A621D34DAC60 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 646BE0C80B0404770341EB48D6178948 +Ciphertext = 6373EBB28BE97C9BAC090CF399C13E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = C1CFCFDC64BB8CAA4433E48A1E50014A +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 9C4C2970AA154B8547C7D0FD2AD455A0 +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 44DC8B4C2264CAA43B7CE7D677FD2871 +Ciphertext = A967C136D389E007BA42FBC6747E55 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 2516BA53D1E10524774FEE9AAF3F5A12 +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C459 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = E3BC50B6EE4FBDDD987CC83549A5C2E5 +Ciphertext = CC261D9F8FB8842E82E22B106796CD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 1B0AE048E9E6530825FCD8712722A906 +Ciphertext = 96A3AB365E57746625562F5CE7C541 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = EACB9385AC5D277F6F75B374A14F8164 +Ciphertext = 7814592EEAE415B75C50EB97F59BA5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = C660005A81628FA166594398AB6CE999 +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 25265ADB1F03521832A6EBA5927611BB +Ciphertext = 16CB13E5853541E2F36B38240366AC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 1C40BC2D77A1B4DBA05B1DCEAC274146 +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = F6D92AAC07A55F97F5FDDDE66B3DD76B +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 1B97080EC1B2C5DD54A27D191D83D3AF +Ciphertext = 52476FE14A8119E7CE3696C4893020 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 8971C3F81E3F78F411A574EFA349B67C +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 59125003191C2B341DFE83368ADE535D +Ciphertext = 565968B0563DF95EA9124E5F4506BC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = D09AFDF9321C587A7FB8FB15A0DFBB72 +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = C79104F5675250A98B8EEADC36B8EBBE +Ciphertext = CB34D04660A66DBFBE9C856601F5B8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = +Tag = 9EAA915C9DD3245D77048F24D46D27A7 +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 30 +Tag = B48691673A22DA04BCC261FEE0FD6A4D +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 3031 +Tag = 262BAB513A2B1149CD8F98E0A8D69CDE +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132 +Tag = FDD427DD8122BF41378574F9997711AD +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 30313233 +Tag = B2EA6460CFAF4023E574D0D2D9DE2C59 +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 3031323334 +Tag = 46F157C79A766F890E75439636E99487 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435 +Tag = 130C5118F88BA70838B7473162F85984 +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA31243 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 30313233343536 +Tag = FCC3A7567D27F75E8C554AB411D9B6EC +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 3031323334353637 +Tag = 053D4B066B939796125BEB583009FE0D +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738 +Tag = 2D7060462FC0BA739C5EB208490C44E5 +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 30313233343536373839 +Tag = A05ED8E6771C2297EF92F8E1F2115B11 +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A +Tag = 4EFD4DCDAD7F528228B59D1360D9C338 +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B +Tag = 56D3B6858BB1B3A1503F6360F82D6022 +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C +Tag = E7D6E00BE9794619B58614A29CD6BC0A +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D +Tag = D7D6235BB2E84EA1039C9D83C63F601C +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E +Tag = 72248BB7D46CC4A7F5F9C1AB782255B6 +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 3ABFC0D209E8F4844C90814D13F32C59 +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 6A67A7A5995C860CE8F00BC0FC2EBAD6 +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 979F12D6EE61B76EB08A192D7E385A11 +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D40 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = CEDE0A5DD5B6DB8AC83FC53FDB29829E +Ciphertext = A967C136D389E007BA42FBC6747E55A6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 556477A5D80D116A12B901CB56011E8D +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C45996 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 61E2C411F70ABAC962BCEBF6CD0EA5FD +Ciphertext = CC261D9F8FB8842E82E22B106796CD70 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = FA955C668AAE924F0EA67E1C7AC396A5 +Ciphertext = 96A3AB365E57746625562F5CE7C54109 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 853FDADB36B8F4AAB88A7B4D90D44D97 +Ciphertext = 7814592EEAE415B75C50EB97F59BA554 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 33767E555C575DFDE3A9CC530140549D +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 3403571B5EDD6D8330BF7584F2AB9026 +Ciphertext = 16CB13E5853541E2F36B38240366ACEE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 0ADDB423696769E6B7AA669DEFB422B1 +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB8923 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = F95F87916643B7F4CE8E2078D077BF64 +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 05BE07F1AF54AD2CB0B32A99CC868BAF +Ciphertext = 52476FE14A8119E7CE3696C48930208F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = F13858B7B827BAF971D539FD9A037BBC +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = F773076D513316A880B97125F4413D38 +Ciphertext = 565968B0563DF95EA9124E5F4506BC64 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = FAE93D97F6134DD7A6F13E19D5A0DAF8 +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 7A81D0A7A37F8A346C0F6FC60093D40B +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = +Tag = 301002539D456275DD0B0CEAB3B23844 +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB60 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 30 +Tag = EA70D7986E7B59CD0D357239F5D25BF5 +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 3031 +Tag = 51682DE2BA2F00EFCA8C1A9F03F3D615 +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132 +Tag = 4845E7276E49BF721C3FC7A2F85F0945 +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 30313233 +Tag = 912D1CD4E668B8CEBD17AA79154A24BF +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC96 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 3031323334 +Tag = 609638CD44C6CD4D5FBF32ED95EFCC14 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435 +Tag = D1BC180AF9989AFFC8C0637EB81D5299 +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 30313233343536 +Tag = 7935A5F1710C754C66A491D361C5FEB1 +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 3031323334353637 +Tag = 69EEB34D52491408DBD86E6ADCE46EF4 +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC7250 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738 +Tag = 3DAB0CA49C0138BB79BD161A0E6403A3 +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 30313233343536373839 +Tag = A2A983CD3C4040B5BDA5EAB0B86C61FF +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A +Tag = F1BE9F1B4E0ED53434E3D9602806210C +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B +Tag = C67D6591BF1DEFFFBE8CF6F42A08D434 +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C +Tag = E27180F575868F27ECCE773213877B10 +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D +Tag = 28F4AA0296A79A7081D4B633D7AEA3E3 +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E +Tag = 182D0B63844365AA804F51124F8F8B8D +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 97E8B4E670B6AF4CB7DB044B2685F85A +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = D507D7B3C2AEE97911E791F7970D6635 +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 54B6B9A440B608B9BA118746100990F1 +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 14A05E4359B74F94F01E8352B2601BD9 +Ciphertext = A967C136D389E007BA42FBC6747E55A689 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = C0A257D671949CE2CF4FF337DEE80D3D +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = C1CF3E6270E9DDB9DDB048820DBA26E6 +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = A1B56137D5D1A880C9D5FE573DB677F1 +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 801FCC7852551F5F665CAA29286B86B4 +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 76CE5513F07F90BCBA97C274EC3AACD6 +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 689A75448A3A27567102F10EB07443EA +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 24F906401867C6F4715ACEDDA4545F4A +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 21BEB61BF6967FC988A88BC453C86713 +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 46831F896A2625CEEA4E93CF2AB663C1 +Ciphertext = 52476FE14A8119E7CE3696C48930208F3D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = F0312AB3DD5DB7A877DC0FB836C123D2 +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 1E03A7F8D719C97FAAB4AC9D4AAAFE61 +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = ECC75C8FF4A85C769508F2BC99FE4221 +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD83 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 0D7CAAB912FC145145DF923A2403A85F +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = +Tag = 22F7517D289D000B4418443947AD52DA +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB6089 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 30 +Tag = 47EE9673FB67D654ABE87717AB875683 +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C721 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 3031 +Tag = 75A2B251BE78B265C54A9F469A5652BD +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC752 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132 +Tag = 7915AB4188784520AACC107FF4A82EC5 +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3F1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 30313233 +Tag = 2E7062EE9BD80DA6C72E3A9B43AED9E0 +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC967A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 3031323334 +Tag = F6493C7698F65F6860A7433A0F561E6C +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7DB6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435 +Tag = 6975FAF3B6B2B17EF1EA2503C3D31EF5 +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F2C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 30313233343536 +Tag = DF8FD8BE2FAF0576C81E8D21C0DD8F8A +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B2F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 3031323334353637 +Tag = FC57F4DE06A334B7EBADCA03B44B73E9 +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72503D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738 +Tag = 5554125721C60DBE94011141B4EB18F9 +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B63F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 30313233343536373839 +Tag = 16BC7C6F4C86C6613D8604B69B677255 +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B301 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A +Tag = 27C8C5B2532B029BF4EB97B161095C85 +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3DF8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B +Tag = 74914E4CB82465BE860A650404D48E7E +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E43D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C +Tag = DA2135C0C71233D3FE94C6ECA22FF215 +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2D7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D +Tag = 0843369936A5DC1727D4157069887B25 +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34BE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E +Tag = 199A73799070D6D17D320761F4BA4BC0 +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF43 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = A4E1B5C836DE17A44BD84889DFFC1901 +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14EA6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = C7F94FF648628B292360E158E55D373D +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE967 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 3E4537125E43A411D2BA637F443219AB +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C75 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = E74AAC319F5B43247B01CFF1AE17FBB5 +Ciphertext = A967C136D389E007BA42FBC6747E55A689FC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 7857F9498C6B4CE6D33E7AE55C53BD90 +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689FC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = CB3AC39EE776EB899A3EBF51FE04E4D7 +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B23 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 16C3D88482F92BC4F419472E6C106EA4 +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF0E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 90D21807FE0607D0FD5782912D6F0E9A +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F7D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 6062C006200D33E84FA192734495D928 +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FCB1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 02857DA2AA2B53EAB9DF0AF75487A416 +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48E0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 7DEEE40909DA6C27EE09BEF1A5CFD992 +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237DF6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 672EB837FBFB85B363C146B07A5D25C6 +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0D8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = D91FAF1E17381091E16320B6FDD295AC +Ciphertext = 52476FE14A8119E7CE3696C48930208F3DAE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = E760797D526391C35408CE9AB55339E1 +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42F3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 8A3CACB2F8D24D0E02B32E74883CCE6B +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F577 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 2411FCA543D54D9F59E2D8490DEE7247 +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD8382 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 37F68EBC123461E64BF65725F6BDEB51 +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51A4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = +Tag = 26E4099A8F7C06AA8CBF6A20A0316D61 +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB6089AA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 30 +Tag = EB586A1A64F68B51AF23595DDDE6D7FA +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C72103 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 3031 +Tag = B17363C35B0727F0D6335F37FD3EC3C1 +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC75236 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132 +Tag = F9CCA6CED6D5DC73BAB548ECAD40C3A5 +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3F130 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 30313233 +Tag = D73B9E5E6FD30A5524EA65ADEE3BF379 +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC967A50 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 3031323334 +Tag = 34908C3D983778A1EED91ACC2081CB28 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7DB6C1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435 +Tag = 439656FD62474EEC12D53CFE6C0FCD6C +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F2C89 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 30313233343536 +Tag = 4CF00628A720AD5A426E73AA8C5C703D +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B2F64 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 3031323334353637 +Tag = AAA47653483652F91B10F965E79DDBA3 +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72503D2E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738 +Tag = 068F92C20085A489305D808ED6562E9C +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B63FFE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 30313233343536373839 +Tag = 553AE5609E9C4A6DB0FDC050A9C55FA9 +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B3016F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A +Tag = 8CDFE5EF32757EEBC85F9DFB0408C3A1 +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3DF86B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B +Tag = 2203B500EFBD8CD558F32C81C650EAEF +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E43D8D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C +Tag = 11D354ED5734247B7B04B2948869BAD5 +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2D70C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D +Tag = 8FF94A7479F0648FED0F1B698CFC5B57 +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34BE7D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E +Tag = DD45CBF728DBCC4EC40A6830A3E69474 +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF43F5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 66862A494492FC435FBD14CFFD894994 +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14EA6C5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = C9A30A53BEC2B1D449E64014CFEB9077 +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE9675A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = A70352C74B75A519BF369DF5CE27854C +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C75AA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 5F3122FDAB8D4D402EFD7F46DB1FB63D +Ciphertext = A967C136D389E007BA42FBC6747E55A689FCFA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 52E44D10016DB49F89EC986574329979 +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689FC9F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 6C4F62102D5945A6C7F57C3C4687AD19 +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B2342 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 2CB9FD8AC527B8E625989D759C1F59A3 +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF0EAB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = E08FDD99494C283D2A781E6E3658BC0F +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F7DA7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 09880E4B987B3C90C14CEDE668984D7D +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FCB1B3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 42A93D56723818B3191C3BDECDF4FF69 +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48E0B2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = C14F153A35CCCF8D744CC0BE3BF0EFAA +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237DF62F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = F7E6D452F618862D504CBE70E49E21E9 +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0D828 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 652BFDC8F7C6A7B8565DE32B196EA55E +Ciphertext = 52476FE14A8119E7CE3696C48930208F3DAEA7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 40D951C6954870223E1A3DB31C7C60AA +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42F3FC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 3914D78DB796478CD38ABF0B5D5A6623 +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F57779 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 42C398D43086168E246B021D985E9A80 +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD8382D6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 5604EDB310677696052FB8FFE7835974 +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51A499 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = +Tag = A2013BE574B7E87EE1FB650AC5F4F93A +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB6089AA3E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 30 +Tag = B7596C26F9CDA7B63D84DF49B0D546F0 +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C7210336 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 3031 +Tag = 03D772315BFC7F32D0D9FEC4A4026F26 +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC7523628 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132 +Tag = 1B47BC1B34A4E95393BD0A0AD4041E7D +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3F13056 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 30313233 +Tag = 56E744997ABDAF28CEB41C8AAC1B2708 +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC967A5094 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 3031323334 +Tag = 39F92F64A6CB185D8685984E75170B11 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7DB6C1FA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435 +Tag = 3F389A3A17549DF28703EDCE91E82967 +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F2C894A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 30313233343536 +Tag = D96B441DA4380049CFE0CB39463FF51E +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B2F6462 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 3031323334353637 +Tag = 4F0FB8A308BAA2CFCDDA43DA206B880F +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72503D2E3C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738 +Tag = FBB86ABE3B3581AFCD18FE28B2F944C9 +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B63FFE31 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 30313233343536373839 +Tag = 1ED9DEACE2BF2E51E6E74BC7FA9DD171 +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B3016F93 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A +Tag = 72F55916AC574FAAB0879FC89E67A5A4 +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3DF86B05 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B +Tag = 20647AF25E726FA1CD4C1340434CC824 +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E43D8D6C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C +Tag = A3D550CBE87460D52DBDE3EFFCEBD335 +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2D70C86 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D +Tag = 02094287F3609213EB27F68851B997EC +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34BE7DF7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E +Tag = B1993492631952627146E8FA68A5F620 +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF43F597 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = F2AF8C369C60B4A248BB5E204A0C82C6 +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14EA6C5E5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 83B88C00A0565AB43EA1C8358C56B8A9 +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE9675ADC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 658CF62A6238D3495428F0FE1424F77B +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C75AAD1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 8CB1DD1AD5B502074DE1D667B140F939 +Ciphertext = A967C136D389E007BA42FBC6747E55A689FCFAC9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 046AFF8239462773DFD5AA5F427F925D +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689FC9F1E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 7EAA1867CA36EA2D806BA33F1B196F3F +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B23422B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 057E2E9C7EA099F63C81600CB8729D5A +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF0EABAF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 6771A1929998D194B8AF855A7AC5D89D +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F7DA7C8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 53F4538661ABB8541AE9E4605EB02359 +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FCB1B329 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 09A656827AD160AD9ACE8DAEB4E1E3B2 +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48E0B21D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 4E22E17E4EFA2C3C3EC938D2EE67C09F +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237DF62F9A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 9C04F5B4C600C9E4F5375EC9E60E38FF +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0D8286F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 004BAD5836964DF74B9ADA01076348AA +Ciphertext = 52476FE14A8119E7CE3696C48930208F3DAEA77D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = AA8396C259BB7EDCBB66AEEA42D89863 +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42F3FC84 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = BAB5640E7461F807B5C75B25904C62A7 +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F57779D6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 79164DBAFF3855F7CC466D2A517EDC33 +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD8382D6C0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = B9DB209CBC869765F3173FBA2F729AEF +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51A499B5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = +Tag = 14B0B35B5C13FB37BA8EA9F73A767092 +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB6089AA3E15 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 30 +Tag = 9FD9A688673386C538D359EAB5B7BD42 +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C7210336AB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 3031 +Tag = 3F5FDC1E00EDB8ECF58DFD94CF0AFCFE +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC752362857 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132 +Tag = 7463B5634AA9F2AAE94C330BEA112864 +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3F13056B0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 30313233 +Tag = 811DC49E28FE0E861B6DC74CD52AC681 +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC967A509415 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 3031323334 +Tag = 2C4696E8A23DAC8E8E4F6C1FB1FE9D67 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7DB6C1FA9B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435 +Tag = AA62AB6C68CA7F8F8D5A00FF8BFC1165 +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F2C894A6E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 30313233343536 +Tag = 4CA07920D7750CC23F2D3D064173711A +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B2F6462F2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 3031323334353637 +Tag = 51240F0ACEA3E33D82EF436A0D587624 +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72503D2E3CCE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738 +Tag = 24B1ED7F9517E94247EF707EDB9D606D +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B63FFE3106 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 30313233343536373839 +Tag = 66D238D8E891F71E849BF9CF9E256A31 +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B3016F9392 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A +Tag = F78073368DB3CA5D357589C5824D1600 +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3DF86B0589 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B +Tag = 8332A5B3BCB9D4D6F999AA1B4F665EA9 +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E43D8D6C06 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C +Tag = D8D4C55E9EAD9D2125F4419D7A4EC68C +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2D70C8649 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D +Tag = 44F751A708F2A016FF3F206FABC6F777 +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34BE7DF768 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E +Tag = 5F4D6C3B7E98A651D7A629B75F3E0F71 +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF43F597DF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = A7A8C6CE505FD9C98D05F99C2EC892AC +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14EA6C5E519 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 6B78026AB38CE9C5541547108325AFFA +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE9675ADC57 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = F985F2396D90E24F3AC6A5FF1A367206 +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C75AAD1E8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 402C1FBC7162856B90A1715B052FE37E +Ciphertext = A967C136D389E007BA42FBC6747E55A689FCFAC94E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 4E9328DADA9E84F1AC6AFEA55C9A00EA +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689FC9F1E68 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 548806C7600E630EF01E5A17C3B00042 +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B23422BE0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 284A19C847730C9B7CCAF54E069E3DFF +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF0EABAF4A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = EB0025BE9FEC0423BEEC29C133E2EB7F +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F7DA7C82F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = FC741903A262E7172D45C50EFEEAD4B2 +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FCB1B32976 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = E9147F4467D6A1B5C55106CA4E1C62A2 +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48E0B21D8A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 57A2503C97374C0B12DC20238FEAF7B3 +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237DF62F9A2B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 875E7339F1DDF0B85B8FC7B242CFC562 +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0D8286FB9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 5A8921070130B028E831A4414107338D +Ciphertext = 52476FE14A8119E7CE3696C48930208F3DAEA77D67 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 979DE5E4E43020FF878BA204C4B63109 +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42F3FC8496 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = A440ED6972000320403705FF8526A36B +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F57779D678 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 1824985478F07FD23A954339FC26565F +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD8382D6C0E6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 7DFD3E9638506577E5711AC6153DD93E +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51A499B55A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = +Tag = 716C6A45716E62379B6C5AC65E11D182 +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB6089AA3E15E8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 30 +Tag = 8B2904B220EF29C1F13E0E511F824CF2 +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C7210336AB5B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 3031 +Tag = 873EA8A79411A282BB58ECF7642905A8 +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC752362857C8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132 +Tag = 6301295D501AF99F8E8954BDD2CD557F +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3F13056B09B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 30313233 +Tag = 4D5570E6BD3B9F8CD873551C9ADE1903 +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC967A5094152F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 3031323334 +Tag = C44115275D15B568CB1C1AE58FD27F84 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7DB6C1FA9B1D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435 +Tag = 5D62EA2644C9552834F3BAECB89E5049 +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F2C894A6E97 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 30313233343536 +Tag = D66EE33EC962EF5DF185404EA4C4B3A9 +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B2F6462F27F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 3031323334353637 +Tag = F758B09F8C3363C1CE78A82B3857087B +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72503D2E3CCE7C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738 +Tag = 4BF9D8E7CF877EA2A09F4A00C60D613B +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B63FFE31062D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 30313233343536373839 +Tag = 632C0CB7504BD09452BE3FAD0FD191A5 +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B3016F9392BA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A +Tag = FB4012DA5C4F48A0144E93E7FA337740 +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3DF86B05892A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B +Tag = 87F35628EEC3A75A60FAF8462C30962D +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E43D8D6C06DA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C +Tag = 66387B75812A5E61C2CF98903842BB0C +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2D70C8649EB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D +Tag = A7331B67E9367010D2D965F04B5191B3 +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34BE7DF768AE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E +Tag = C553B140DB74248BC80947EA32C28B21 +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF43F597DF00 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 0AC50AEF753042881F867252B09409FA +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14EA6C5E519E3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 024788D44C562E9FBBCE9922F6FCB151 +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE9675ADC5777 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = C0D54895F382A2065A7CF6CC796D280B +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C75AAD1E856 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = BD64247BEC31ED95A63A7F0A21B7518B +Ciphertext = A967C136D389E007BA42FBC6747E55A689FCFAC94EE2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = A746451221732D3E42D8CAB34DBFFE7C +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689FC9F1E68DB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 9EBAF2A90D2BD41F5C76490E42451795 +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B23422BE018 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 20D3B2FE931D21F8A452D37293096157 +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF0EABAF4A0D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 3ECBDA9FF583E3436EE309B75A2288F7 +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F7DA7C82FEE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 4280CC9622CB298792A17ABEBB579097 +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FCB1B3297646 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 43AF352024BE973C687F0A4813897B2C +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48E0B21D8A34 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = E9A36AAAD68792D51E7E06D69B60EC2C +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237DF62F9A2B40 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 61EA2D3736D7FE168DBEC8D89D2A7718 +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0D8286FB990 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 4D428C240E057CD3C2055FC22587A185 +Ciphertext = 52476FE14A8119E7CE3696C48930208F3DAEA77D6714 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 5E0A890004F784ED5DEEA9C1B34B557D +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42F3FC8496AD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = BABE98CEFD673FFBCBDB1A7B2AA3AC2B +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F57779D678DB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = EF0E6477259364E74F229E818A52954D +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD8382D6C0E608 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = E314AA320405A437A3FFDE5A601C65DE +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51A499B55AC8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = +Tag = 0C91B33379F1FA4CD0DDD83E72AB54CD +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB6089AA3E15E803 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 30 +Tag = 55D18EE1FD7206710605ECBD2D32663A +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C7210336AB5B1E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 3031 +Tag = 90ADF47F7CEB1A603683F0D952C03F82 +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC752362857C8DB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132 +Tag = DFED88EF49FE493AD8A3D9383FCD2DBF +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3F13056B09B17 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 30313233 +Tag = 64CC817E44D943545BB06B98477D6A7F +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC967A5094152FAF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 3031323334 +Tag = 94271131B6D127FDC87A7F6F826F2663 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7DB6C1FA9B1D1E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435 +Tag = D28CA4EDBEB4B4DE933EE710FD8854C8 +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F2C894A6E978A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 30313233343536 +Tag = 127F1A88644E5D0E79A007ED237CD572 +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B2F6462F27F58 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 3031323334353637 +Tag = A85B372C31719BDDCA826921F9EA11E8 +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72503D2E3CCE7C9F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738 +Tag = D714C7790AEE325EC92FC8D7DB705BB9 +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B63FFE31062DC7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 30313233343536373839 +Tag = E63BC51DD0E7AF728E0EB289B3255B50 +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B3016F9392BA49 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A +Tag = 626C81BC35AB252B1EE257BFC0D50607 +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3DF86B05892ABF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B +Tag = 2AB53AD0AE43DD3FC10B057FAFEDBE21 +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E43D8D6C06DA58 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C +Tag = 639379EF381A77DC75AC76DBB85E9663 +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2D70C8649EBCF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D +Tag = 57E25257414C2A88A7515F2BAB2E53F4 +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34BE7DF768AE95 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E +Tag = ABB5BD2EE43366F85178FE317A3ECEFD +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF43F597DF00A4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = C2305AEB78146858CAFF2DE13A629A6A +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14EA6C5E519E30A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = CA117185EDCEB2F9796526790CDBD0BA +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE9675ADC577734 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 21786BEC376F4472311FD4AD6446CDB6 +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C75AAD1E85649 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 3AD751ADF342E608CB55325CA1AF4D85 +Ciphertext = A967C136D389E007BA42FBC6747E55A689FCFAC94EE2DD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = CE5B219A1D672B615C41A82056FD6F17 +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689FC9F1E68DB2C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 4C1FC3CADD96E2348A97EE575B1AE43D +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B23422BE018E5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 3CE1737242F67745C02247860979D3B9 +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF0EABAF4A0D02 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 458B8D0554CD553959B42C23CB827500 +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F7DA7C82FEED0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 99E52563643D631C513D6EAABA486988 +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FCB1B329764698 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 3F32D75D300778A3BD4BB5BC5CD5812F +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48E0B21D8A3424 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 8F5EE030387FEBC9EF0842290AC02A48 +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237DF62F9A2B4080 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 19462FA303C7638A699C581328417A27 +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0D8286FB990CB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = B81A4C92C5E78DC460340EF2AF988F1B +Ciphertext = 52476FE14A8119E7CE3696C48930208F3DAEA77D67142D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = D1C5A7191898D5B7DFAE40051FE41918 +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42F3FC8496ADD6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = F3BB50ABDE93FE7A0A4517124A4DC70A +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F57779D678DB87 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 1911035AE842EA3D24FF1473774BB345 +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD8382D6C0E608E2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 8EB14253C9EFA3D5065C50BDF1803947 +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51A499B55AC8F7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = +Tag = F2D00B0754CB343B0EA742A196423647 +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB6089AA3E15E80307 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 30 +Tag = D748FB65E57CEC0F1979752B90C190C8 +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C7210336AB5B1EB9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 3031 +Tag = 5436ACC6183D91E7FE07BDC9CDF4C268 +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC752362857C8DBC0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132 +Tag = 6FFF67A83597604FCB05C21132E35A2F +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3F13056B09B1797 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 30313233 +Tag = E08FE76BCA62E3314FCB3443710B7B20 +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC967A5094152FAF73 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 3031323334 +Tag = DC3C520695668F4F7FB34FCF1C93E955 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7DB6C1FA9B1D1E5F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435 +Tag = 211212693A848BB79A669E735342EC63 +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F2C894A6E978A90 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 30313233343536 +Tag = A606F5BA7C506EA9408A4F81C0A6E231 +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B2F6462F27F5876 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 3031323334353637 +Tag = E8BE8680030C5A15A9728E64A3900373 +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72503D2E3CCE7C9F5B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738 +Tag = 1329BC31CEA3264A444B6C11CF607F88 +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B63FFE31062DC7AA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 30313233343536373839 +Tag = 961859FA27EAF703F9ED11FC744773C2 +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B3016F9392BA49BE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A +Tag = 62E3CD6EC573E0E2C087D256E72285E9 +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3DF86B05892ABF59 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B +Tag = 7B0FD7D968000E17BD5B57BD7BC79994 +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E43D8D6C06DA586C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C +Tag = DC18C3BB934B097A677C7354D6D0B42B +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2D70C8649EBCFFA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D +Tag = 2F4433426712F098B592D978E1A24F1C +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34BE7DF768AE95B6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E +Tag = 844B28F3AFDC5ACD07D31F44CF499CA9 +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF43F597DF00A4FC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 392B0B5E10A6A861DE3750A13D4759D4 +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14EA6C5E519E30A5C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = F60B8ABA729D90F51E4559DB4CFCD721 +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE9675ADC5777342F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 259FFF441D58A09329BAA5CFD2EA5DD8 +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C75AAD1E8564974 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 55D5907684B9CFD0FDA36371D0DB55DE +Ciphertext = A967C136D389E007BA42FBC6747E55A689FCFAC94EE2DDE3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 6A3D34DD2B8372055C5E0A659D4EF8C2 +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689FC9F1E68DB2C1E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 6F42038000D00E70522D029B26A1CCD2 +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B23422BE018E553 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = F2E2E6FEEC5F76085AE70FE252980169 +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF0EABAF4A0D0274 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = F0BBE2C727B3CB19F6848E3930FBD6D1 +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F7DA7C82FEED07A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = DFEBAF445205EC9B019D022C7042AE59 +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FCB1B32976469892 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 7947F5E3EBCF878DC972462D67FE35F0 +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48E0B21D8A342473 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 58CA1C68014821A9A92DE2CD2350CF8A +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237DF62F9A2B4080B8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = BD063B9C21575F6E9D934AFBEACA0262 +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0D8286FB990CB04 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = FE35F164E0BE7727C7E97E7D7E7A7C34 +Ciphertext = 52476FE14A8119E7CE3696C48930208F3DAEA77D67142DC9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 0648DF6DCEA92B54865D610128EBD452 +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42F3FC8496ADD69A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = AA3BEC0FEE9B463CAE31BFB9754A7ED3 +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F57779D678DB879E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 0EBB3B7514C3DA2F69226E962A35B628 +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD8382D6C0E608E24F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F3031323334353637 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 3866442532876D7EF88DBCDA974C92B5 +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51A499B55AC8F7FB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = +Tag = 787643EC8F22A0266ECCEF74D326B556 +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB6089AA3E15E8030797 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 30 +Tag = B69F563B9E75D7D6A94810D8FF6AF3D6 +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C7210336AB5B1EB94C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 3031 +Tag = B62F8F0DAF202195EAD1BC095B2EA07D +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC752362857C8DBC0CE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132 +Tag = 087EA0277F08E34A66B349E48740894E +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3F13056B09B1797A1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 30313233 +Tag = CF5DDD1EA78C2EB5E2F26EE67D739F91 +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC967A5094152FAF7382 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 3031323334 +Tag = 73D8DC7F39E058FB464655137B122D2C +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7DB6C1FA9B1D1E5F9E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435 +Tag = A9E665CAA101BE4BA4273D462BD93AEF +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F2C894A6E978A90FD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 30313233343536 +Tag = BD4AAE19F4EF9A9451AF9E1619470A80 +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B2F6462F27F587664 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 3031323334353637 +Tag = 32F4F43E4D3CE2062873A7977F7ED84A +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72503D2E3CCE7C9F5BC5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738 +Tag = AFE35886BFBC1FBC06DF0E1FEA7D22BA +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B63FFE31062DC7AAE2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 30313233343536373839 +Tag = 7F8C9369B8948E15F5A858420325740C +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B3016F9392BA49BE3C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A +Tag = 4B60461E51582E2FD603C05567EE8851 +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3DF86B05892ABF5901 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B +Tag = 00A857094A1AD5ED2F78858633559E9E +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E43D8D6C06DA586CEE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C +Tag = A3854937F6612274A24E5A7BB8876DFB +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2D70C8649EBCFFA24 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D +Tag = 5BB8BC4A4CEBD6C2C4BD4A5A4B8632E4 +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34BE7DF768AE95B633 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E +Tag = 16DB9BB18CB558AFB40572D0A863F9B4 +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF43F597DF00A4FCC9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 39F83A3FCCF168C827E7BBED08ECD1FC +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14EA6C5E519E30A5C6E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 395786F1BF959D3952D7E0B62D3CF156 +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE9675ADC5777342F1D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = EC8C893B06B03F3D34223484983FDA64 +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C75AAD1E8564974C6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 029865A9036DFDF387B27D64CFC3A7EC +Ciphertext = A967C136D389E007BA42FBC6747E55A689FCFAC94EE2DDE396 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 8D0C6269449FFFF6A08903340492787A +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689FC9F1E68DB2C1E6A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 69771C918AD59967BF72641516FFC22D +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B23422BE018E5533C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 6BC58BAEFFF1C200ED6D0D3C2E2D6912 +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF0EABAF4A0D0274F5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = D74AFAC52A28114297F75125A2CBE22B +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F7DA7C82FEED07A82 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 871B40F97E774C2977DB11D2CEFF7C08 +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FCB1B32976469892D5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 36EE62A452576A34F75324A06C981FC5 +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48E0B21D8A3424739F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 089903E3FBADE7DA98DC0CB9A823FB87 +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237DF62F9A2B4080B850 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = D59C7926A37D275345E58F6C89528B1D +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0D8286FB990CB040D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 40395CA8472E03023737FD96014BDF84 +Ciphertext = 52476FE14A8119E7CE3696C48930208F3DAEA77D67142DC97E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 13DA8BDD93C39BF8EBE2BEF61D15CEA4 +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42F3FC8496ADD69ABC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = F7D87EAF837F358B21205747FEBE0B9F +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F57779D678DB879EFF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = DD69B38880A2238A6494FBAF0BBD047B +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD8382D6C0E608E24F44 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 6B699C342D566E64B5B5A0A4BF37C2DA +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51A499B55AC8F7FBEF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = +Tag = 27AF1FFE5269710780A0D91EAB1BD3AF +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB6089AA3E15E80307970F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 30 +Tag = FC026ADBA8ED09EE4DA5336D7308EC50 +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C7210336AB5B1EB94CFC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 3031 +Tag = 039FF7B449838152731BFAE4F2CD892F +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC752362857C8DBC0CE1A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132 +Tag = 48B87353CD26683FCAE1A2C72611F1C0 +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3F13056B09B1797A127 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 30313233 +Tag = A47AB7A5203B0739526BE71D2E278889 +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC967A5094152FAF7382D8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 3031323334 +Tag = B7585BBEBC43F0A3567BD3F9874F7201 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7DB6C1FA9B1D1E5F9E59 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435 +Tag = 217D6CB18BE7D1396FB15CE2ABDDAF0E +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F2C894A6E978A90FDB1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 30313233343536 +Tag = 980D20E58A6549CD4997E86C99BA3DD2 +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B2F6462F27F58766415 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 3031323334353637 +Tag = 33890B57DF3538280E1AB7CB10BDB4B5 +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72503D2E3CCE7C9F5BC5E4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738 +Tag = 5D9CC557B1FA67B6C9D3968939093E87 +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B63FFE31062DC7AAE254 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 30313233343536373839 +Tag = EC02C24ADB22F6C1E1957B7BEB297025 +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B3016F9392BA49BE3CA6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A +Tag = C6F5A0D69F3610AB5A57680552C757B6 +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3DF86B05892ABF59012A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B +Tag = CFFF67344C21D32F6287366EB1E0EE63 +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E43D8D6C06DA586CEED8 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C +Tag = 11EEEA65DDEF8ACB4C3A128AC0AAC004 +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2D70C8649EBCFFA2420 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D +Tag = AC06B34013DA91E3B26E69EECC33B089 +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34BE7DF768AE95B63312 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E +Tag = 28B046618F349F60213B0B5535C4D37C +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF43F597DF00A4FCC957 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 6102821838732A60349FE1AD12B68EE1 +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14EA6C5E519E30A5C6EF4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 485F58C0F09243A203B8F6AE4C576F8C +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE9675ADC5777342F1D1E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 2F0F9628C2FA795536D86E811B64C6BA +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C75AAD1E8564974C66C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 754D9903D02E16BCEF1F94738D5FA8C9 +Ciphertext = A967C136D389E007BA42FBC6747E55A689FCFAC94EE2DDE396F6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 08DD61194DC9D1A12BFBA558F8B699F1 +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689FC9F1E68DB2C1E6AD5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = 9C58F341BBDCA3559726270A0B6E28FE +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B23422BE018E5533C5E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 869CF0D6E0DD1839D2F6FDE600E1225D +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF0EABAF4A0D0274F528 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = E5FEF767664E713BBD1B5B15BC42CF43 +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F7DA7C82FEED07A824B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = B163089F7920FCB55D5359EB093512B0 +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FCB1B32976469892D5BC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 3B2EB92E083B0EFC66D283EAD20C06A0 +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48E0B21D8A3424739FCD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 8CE2FAF6CDE1FBC0752246E5D616E8A6 +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237DF62F9A2B4080B85004 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = F4082B9377C83160750217C81579066D +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0D8286FB990CB040DC1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 26FB1C82D67C13029C5CDC77927A401E +Ciphertext = 52476FE14A8119E7CE3696C48930208F3DAEA77D67142DC97EEB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 801459A34004818FE95CEB2F78B6EA62 +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42F3FC8496ADD69ABC3F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = E8F27F7A4318873E4C06CA55C14EAA3E +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F57779D678DB879EFF69 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 67AD178C9E92E2461E64E48F4AC3A0AA +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD8382D6C0E608E24F441A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F30313233343536373839 +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 75A6EB958DB1DE620CB47F063A491490 +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51A499B55AC8F7FBEFBC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = +Tag = 8FA96A7A8F18A2163D45CC8061DDBE9E +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB6089AA3E15E80307970F2D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 30 +Tag = 1ED0B5C07DD0025C0D69363527E95B84 +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C7210336AB5B1EB94CFC06 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 3031 +Tag = 47D7B2795BD92085A539E0FA6AF26471 +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC752362857C8DBC0CE1AD1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132 +Tag = 5570130144C1F1B1B2CAEC959370BD24 +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3F13056B09B1797A127EE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 30313233 +Tag = 2B69CE1A7C6EC8DE8BBCAF1333E9A381 +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC967A5094152FAF7382D836 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 3031323334 +Tag = 6176D50457D2D7868ED6F6D5C829D308 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7DB6C1FA9B1D1E5F9E590F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435 +Tag = 77B268A5653068EBB83BF38B1F741C7D +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F2C894A6E978A90FDB1BC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 30313233343536 +Tag = E5538B479D6EA830EAA8E7A0F3A9188F +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B2F6462F27F5876641569 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 3031323334353637 +Tag = E7CF079592E03B9B852140D8B31EBBB9 +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72503D2E3CCE7C9F5BC5E4BB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738 +Tag = 81866427935FC63F66D69208A0B04DC7 +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B63FFE31062DC7AAE25451 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 30313233343536373839 +Tag = 9048FD3B25E82A0483D9F3AF29A2959A +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B3016F9392BA49BE3CA6BC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A +Tag = 0F172085D3C17E3F5F4081C9EEC28814 +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3DF86B05892ABF59012A84 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B +Tag = A19D0A8967051D18CCEFC1986751B15D +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E43D8D6C06DA586CEED818 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C +Tag = 16127F7500FF03D098E86B0C2EE673BE +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2D70C8649EBCFFA242029 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D +Tag = 8F9AF9553BF7E54D2882FA865513CCFB +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34BE7DF768AE95B633128F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E +Tag = ABEE4CF13C4565A781565F3F69C4DA29 +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF43F597DF00A4FCC9570F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 5BBF55207054E8EC81952A6D6470A26E +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14EA6C5E519E30A5C6EF44F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = FEFF079110B9DCE6E92A3C01CBF849DC +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE9675ADC5777342F1D1EF3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 36BCCE20293FA20F6C8D742C8D05E286 +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C75AAD1E8564974C66CFC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = D170C531C9CE5FB94309B2E90C59EBA7 +Ciphertext = A967C136D389E007BA42FBC6747E55A689FCFAC94EE2DDE396F6DE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 208019C166CF90156694F88577F3C91F +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689FC9F1E68DB2C1E6AD537 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = FB31BBFF94C3EA7282FDB640674055E4 +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B23422BE018E5533C5EB9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 8C1376911A07A3A7E0FDF0C7A7FF0C10 +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF0EABAF4A0D0274F528DF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = AB476849F1BADFB37B2B9290A0279127 +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F7DA7C82FEED07A824B07 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = FD3CE3F4A8BC3659AC09DE2E027D885D +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FCB1B32976469892D5BC91 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 8D7FE125FE101F106553F75B2372928F +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48E0B21D8A3424739FCD62 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = B59E3F28591F9DD7F95EA4D0F819F20B +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237DF62F9A2B4080B850046D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = ADD34CB2B4CEFB49B2EAAE625701A6DF +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0D8286FB990CB040DC107 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = CC59B5501D514790159F417ABBF009B6 +Ciphertext = 52476FE14A8119E7CE3696C48930208F3DAEA77D67142DC97EEB7C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = DF1595C8F8EEED87BEAF83C90D74D621 +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42F3FC8496ADD69ABC3F8C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = B45E5A34F710BD01DB9990064094F410 +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F57779D678DB879EFF69D9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 8282426C469C8B0503458DA2F720C098 +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD8382D6C0E608E24F441AAA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 8417583AF231A74853F566FFFF917796 +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51A499B55AC8F7FBEFBC33 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = +Tag = E418CEA5853314B05F1F89F229D6770F +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB6089AA3E15E80307970F2D1F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 30 +Tag = E7B7AD272EB2F33645EFEF0FC64D76FA +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C7210336AB5B1EB94CFC067C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 3031 +Tag = 38DF876272104222E6A5935C709E04CA +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC752362857C8DBC0CE1AD14B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132 +Tag = 99CECA52381066F7C4F33556AF0DBB6D +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3F13056B09B1797A127EE7E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 30313233 +Tag = 791F05E165FFDBAE1756FB194FCF45EE +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC967A5094152FAF7382D836E6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 3031323334 +Tag = 05EBF5EEE3FE1260CE8331A28257DC56 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7DB6C1FA9B1D1E5F9E590FA4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435 +Tag = A6DF9726098EDEDB4011BA4D2DE5E54C +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F2C894A6E978A90FDB1BCC6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 30313233343536 +Tag = 6A258BCD9C921F9EE1EF64DC9C25F439 +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B2F6462F27F58766415690B + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 3031323334353637 +Tag = AB0EFB4C59FF50A3A57D1C3179C3F0F0 +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72503D2E3CCE7C9F5BC5E4BBBD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738 +Tag = 0ECDA3C4FC7B2C30484168E5FE76588E +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B63FFE31062DC7AAE254516F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 30313233343536373839 +Tag = 9F5BDB7DD7E0CC4BD73F532D4AC8DD91 +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B3016F9392BA49BE3CA6BC1C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A +Tag = 6ED81F723071DA8096CD4D04D5DF4033 +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3DF86B05892ABF59012A845D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B +Tag = A97C8A1E4D7DD8A746AF038830D5CB09 +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E43D8D6C06DA586CEED818F6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C +Tag = 4B657B1082C3E8FE5521B653B5BB0558 +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2D70C8649EBCFFA242029BB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D +Tag = F75787EA19B23738B6404FDFB54CFBBD +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34BE7DF768AE95B633128F33 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E +Tag = D3EB956EAC4CEDA0191B5ACF478894E8 +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF43F597DF00A4FCC9570F4C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 83541728D2D42D234DF106E17296D743 +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14EA6C5E519E30A5C6EF44F7C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = DB4A004C38FF9B091718EA539304BB65 +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE9675ADC5777342F1D1EF3C5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = B0503190A2CECE4E4311BAB8CA008611 +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C75AAD1E8564974C66CFCE4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = B6FDFA3AE0BE0381D64C6F9C20B03284 +Ciphertext = A967C136D389E007BA42FBC6747E55A689FCFAC94EE2DDE396F6DEDB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 75768176C0DADA49FFBB7E5838372F1C +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689FC9F1E68DB2C1E6AD537C2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = B3F670EC4EE4E8EAEB3D419AA21D8278 +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B23422BE018E5533C5EB98E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = B1D5C6F724B7BC831031C22BE6F5BED8 +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF0EABAF4A0D0274F528DFC7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = A6099F239A43017B89BD279D7537B078 +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F7DA7C82FEED07A824B076C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 4170653354A56E9CE3A7C2E657BCB71E +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FCB1B32976469892D5BC918C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 5205766E44C7BA4A5663DAC1D93FD3CD +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48E0B21D8A3424739FCD62AC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = B9A9FE7BC9269F19A782FC29492B599B +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237DF62F9A2B4080B850046DDD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 309EE2528DAF54FB1F6F58F5B227BD10 +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0D8286FB990CB040DC10759 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = C3C98CB88E68B56E93D95531AE2A8A64 +Ciphertext = 52476FE14A8119E7CE3696C48930208F3DAEA77D67142DC97EEB7C93 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 5056A2C006C20EC776FD3AAD91337667 +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42F3FC8496ADD69ABC3F8C48 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 6CAB8033E888851D5AE4AD1FFB53C0CE +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F57779D678DB879EFF69D9D7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 8C74538EB419A0246CF6B4721BECE1C4 +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD8382D6C0E608E24F441AAAFC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 127FEEF94733F7BBA02B48CAF4E1D669 +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51A499B55AC8F7FBEFBC331A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = +Tag = AC3D038076CB38A7782A2823823AAB66 +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB6089AA3E15E80307970F2D1F00 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 30 +Tag = B05B62F3B7B1139EC2063AB25E82EFAD +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C7210336AB5B1EB94CFC067CE2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 3031 +Tag = FC5AB64B3F0E69CB6EE535DCF9254728 +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC752362857C8DBC0CE1AD14B17 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132 +Tag = 0FE9DA2703C13BC6F6CA4F6B63E6BBB4 +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3F13056B09B1797A127EE7EBD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 30313233 +Tag = 15CD57CE53AB84A03BD94DF6DF7A17A1 +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC967A5094152FAF7382D836E6D5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 3031323334 +Tag = 5D992F55340FE3AF0DE6635DDD868B9B +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7DB6C1FA9B1D1E5F9E590FA4D5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435 +Tag = 555667A5E9CD0C1E0F577E02188CCBCE +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F2C894A6E978A90FDB1BCC680 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 30313233343536 +Tag = DBD36EBFA336740D51ADCAD7FAD8CCA7 +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B2F6462F27F58766415690BCE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 3031323334353637 +Tag = 404BAE240A05B8419758BDC9CBA89DE3 +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72503D2E3CCE7C9F5BC5E4BBBD2D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738 +Tag = 9645866FF8609B47DCF0065E18BC7D8D +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B63FFE31062DC7AAE254516F08 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 30313233343536373839 +Tag = 66D79B478E9BA4B57E4332E9B0A17DBC +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B3016F9392BA49BE3CA6BC1C86 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A +Tag = 154C8EFAD6B08773D84A1BEA61E134F5 +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3DF86B05892ABF59012A845D7D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B +Tag = A6DEA044DB0FAB9F3BFA525AC6B91D59 +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E43D8D6C06DA586CEED818F679 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C +Tag = 6408C70FDCE34D303BBF5B1EDB5BE870 +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2D70C8649EBCFFA242029BB9C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D +Tag = 7D2655B99742E2016976902BFBB2261B +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34BE7DF768AE95B633128F332F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E +Tag = 34DC7A76FDF990DCC2B0F1405189754D +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF43F597DF00A4FCC9570F4C64 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 830C671536E4A38E518BC82EE4A3B737 +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14EA6C5E519E30A5C6EF44F7CEA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = F0D87E7A8EDB08ADE99B56AA58218487 +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE9675ADC5777342F1D1EF3C5D4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 8153BE2426F9B1CCEE5FFBF8182B1787 +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C75AAD1E8564974C66CFCE4D9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = BE24378A8A13808142B6EFE7EC0203A0 +Ciphertext = A967C136D389E007BA42FBC6747E55A689FCFAC94EE2DDE396F6DEDB2E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 95E4C0C40DF291185216C31B1DAD9E65 +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689FC9F1E68DB2C1E6AD537C2DB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = FA390D5F53EC6474CC37BEACE33EF334 +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B23422BE018E5533C5EB98E2E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 546C5240825ADAACB7FD8781BE1F22FC +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF0EABAF4A0D0274F528DFC7C6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 849032F7DA7AAF99A6685B20D4974F3E +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F7DA7C82FEED07A824B076CCE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 7A7DFA934147094D5B71BF8121D1944C +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FCB1B32976469892D5BC918CAC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 621D29061DA0CF1F8980054725C6CEA9 +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48E0B21D8A3424739FCD62AC2D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = A2C4E16CB15A691AD67FDC3BD7F299C5 +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237DF62F9A2B4080B850046DDD38 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = C24F4B476EE0EEA883C8553216C5C7F4 +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0D8286FB990CB040DC107595C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = D695823108A110419F536B9F732E48BB +Ciphertext = 52476FE14A8119E7CE3696C48930208F3DAEA77D67142DC97EEB7C9341 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = AA1F9A8FD3EA88E0CC44DB1219DA1D3B +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42F3FC8496ADD69ABC3F8C48C1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = F698CE1719636F6BEBA0289E0B467C4E +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F57779D678DB879EFF69D9D73F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 8B24B17CABB61D7EDC93031F83B5252F +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD8382D6C0E608E24F441AAAFC47 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = A2E8593C12628FE1ABEF161F392A104A +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51A499B55AC8F7FBEFBC331A61 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = +Tag = FA1EA2B92A5DD1B9D1C9DEB4CBEAABA0 +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB6089AA3E15E80307970F2D1F0066 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 30 +Tag = 7A2DB5F2EF4E5D08271E8794FFCFD6CF +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C7210336AB5B1EB94CFC067CE224 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 3031 +Tag = CE4CB4C7996DA94AA683CE6335C935AC +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC752362857C8DBC0CE1AD14B17E7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132 +Tag = EFA1AB5E9FDE810D007E11185A97C772 +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3F13056B09B1797A127EE7EBD04 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 30313233 +Tag = 7B39CB0A70034AC15F4306B152801EB2 +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC967A5094152FAF7382D836E6D5DE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 3031323334 +Tag = BDC949A9927ABEE7DB72032F90BEF538 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7DB6C1FA9B1D1E5F9E590FA4D5BB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435 +Tag = 01162EFFADEE650799A92E7F34AF5AFB +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F2C894A6E978A90FDB1BCC68020 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 30313233343536 +Tag = C28CD0B64FAF2D163B5E6F4DFF1A5FB3 +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B2F6462F27F58766415690BCEFF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 3031323334353637 +Tag = F047156FA849EFBA43A797A9787C53BC +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72503D2E3CCE7C9F5BC5E4BBBD2D28 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738 +Tag = A895946CDD7001544DBC0F430A3DF552 +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B63FFE31062DC7AAE254516F0860 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 30313233343536373839 +Tag = 0E98B5805DB5B40A89BC445E6EC72C69 +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B3016F9392BA49BE3CA6BC1C8650 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A +Tag = 8AB94B09372CE5CF792148CC9BC9AE2A +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3DF86B05892ABF59012A845D7DAA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B +Tag = 401A603567B721DE38E57CC26014E881 +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E43D8D6C06DA586CEED818F6797D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C +Tag = 144546387AAEA36026E0832A56CDBBF1 +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2D70C8649EBCFFA242029BB9C0F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D +Tag = FC20C5F31505D50D53A2505DEAC1359E +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34BE7DF768AE95B633128F332FFC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E +Tag = A21BF61016B8E605B58C2C9C065E7BBE +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF43F597DF00A4FCC9570F4C64C4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F +Tag = C4F7C620AD546C97097831537AB22E9B +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14EA6C5E519E30A5C6EF44F7CEA88 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 5A28224B9221FCC01061A72AC3DB44DD +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE9675ADC5777342F1D1EF3C5D4BF + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = AED202A3ED692B4C5AEF6AA172E36594 +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C75AAD1E8564974C66CFCE4D9FB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = 4B63DEAA45CF37AC4DA5351A88D745BF +Ciphertext = A967C136D389E007BA42FBC6747E55A689FCFAC94EE2DDE396F6DEDB2E5F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 18E5F8330CCA37C6F58D088DB23CB5E3 +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689FC9F1E68DB2C1E6AD537C2DBC3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = B9C1D5C0A3F3F255397B2A02D32DA03A +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B23422BE018E5533C5EB98E2EB7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = D5C096CDBE9BEF7412AE04FD04884929 +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF0EABAF4A0D0274F528DFC7C689 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = DF16E8CBC7F181BA19806B953744646F +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F7DA7C82FEED07A824B076CCE8F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 97E800B5C7A91CC043BD8E175AD080BA +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FCB1B32976469892D5BC918CAC79 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = B2D36A792BA208D4158CDF4E968FA99F +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48E0B21D8A3424739FCD62AC2DDE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = BAEDA24A1AEDBBDFDDEB681B27812261 +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237DF62F9A2B4080B850046DDD386D + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = F966098856B32B97C868331F6CEF1B27 +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0D8286FB990CB040DC107595C16 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 896861DC4995E34086CB79A4D6ED134A +Ciphertext = 52476FE14A8119E7CE3696C48930208F3DAEA77D67142DC97EEB7C934166 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 81328E98F9E83C920D70596F4354BCAF +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42F3FC8496ADD69ABC3F8C48C106 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 48FC8179F2A09D4E82DA925CFC92FC67 +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F57779D678DB879EFF69D9D73F18 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = E1A76A7A67C2709DFEFE5A56B7C3D062 +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD8382D6C0E608E24F441AAAFC4726 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 1DAC0C917BAC84C02DE8008F939E147A +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51A499B55AC8F7FBEFBC331A613E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = +Tag = 609F5B9C996A223962F5B702DD53C2EB +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB6089AA3E15E80307970F2D1F006654 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 30 +Tag = 89E62F1A99ED4A0EB805B9D19F3117BC +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C7210336AB5B1EB94CFC067CE22487 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 3031 +Tag = CB26E67298C26964A828C933DAD87795 +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC752362857C8DBC0CE1AD14B17E764 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132 +Tag = 412E9E06B6BA1F49E12C117738F0AF3B +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3F13056B09B1797A127EE7EBD0453 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 30313233 +Tag = 21220F77824067EE429B9B3E774B2489 +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC967A5094152FAF7382D836E6D5DE08 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 3031323334 +Tag = 4BDD5E67A4257244E57AB47B406F03D3 +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7DB6C1FA9B1D1E5F9E590FA4D5BBDC + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435 +Tag = F6AB242EEF3442B05BDF3265F4204477 +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F2C894A6E978A90FDB1BCC68020F9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 30313233343536 +Tag = 47D69D34DC0B48B654F595606D586EA7 +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B2F6462F27F58766415690BCEFF35 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 3031323334353637 +Tag = 906459BC5E8E7D9BE631EEA14A354A9E +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72503D2E3CCE7C9F5BC5E4BBBD2D2870 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738 +Tag = BC9CBA109BE2FB1BE9CBADDA0EAA728B +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B63FFE31062DC7AAE254516F08602E + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 30313233343536373839 +Tag = 18931C17CD83BEF52713760EA9257D89 +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B3016F9392BA49BE3CA6BC1C86503A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A +Tag = A17EEF55B4B2FF7B17B0C04174813E3A +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3DF86B05892ABF59012A845D7DAA9F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B +Tag = 50135F2291397AA43FE5D39350B68B20 +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E43D8D6C06DA586CEED818F6797D40 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C +Tag = D0B04A9491CC63F8099EFA949B2859DC +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2D70C8649EBCFFA242029BB9C0FDD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D +Tag = 4DF5FB88DBC5DA6CD5385F8D1AC2D087 +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34BE7DF768AE95B633128F332FFC71 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E +Tag = 161B2C959E1236530A4F375502F05514 +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF43F597DF00A4FCC9570F4C64C4D0 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F +Tag = E47D15156DE9781AD405A566C0577AFF +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14EA6C5E519E30A5C6EF44F7CEA881A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = E5BDC363862A0F72890D8CD522B08964 +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE9675ADC5777342F1D1EF3C5D4BFC7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 2EC63A6A0CE9663920F3220F52D9AC0B +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C75AAD1E8564974C66CFCE4D9FBF6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = D171901B45A3E23E7C9464DFC577744C +Ciphertext = A967C136D389E007BA42FBC6747E55A689FCFAC94EE2DDE396F6DEDB2E5F33 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 55F51C5A247CC4EE0F2E81FCDEB3EF4C +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689FC9F1E68DB2C1E6AD537C2DBC357 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = EB3DDCDA742C3616BB73A6215A937E53 +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B23422BE018E5533C5EB98E2EB7AD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = D198BFE367F3D61A73CB945BE51F2BAA +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF0EABAF4A0D0274F528DFC7C68968 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = CBB9E5B07BAEAD33C53F693FF215C0DD +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F7DA7C82FEED07A824B076CCE8F75 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 36E99B62AB82D2FB91F22266B40D28A8 +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FCB1B32976469892D5BC918CAC7997 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 852C6CDC34006B05B9D5EF0F08A015E6 +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48E0B21D8A3424739FCD62AC2DDEDE + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = 41C515B55987D7F4D57A1959F3EC7578 +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237DF62F9A2B4080B850046DDD386DED + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 595ADC9A457C252ABAABA0285A83A796 +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0D8286FB990CB040DC107595C1638 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = 3608335A36CF3F0EEAAC43B0FEDB3005 +Ciphertext = 52476FE14A8119E7CE3696C48930208F3DAEA77D67142DC97EEB7C934166A3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = 441C229A61A4AEBBA1F809581011F356 +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42F3FC8496ADD69ABC3F8C48C1061A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = C5B84665D7D7FA7C8FB4C6C9B21160D3 +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F57779D678DB879EFF69D9D73F189F + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 7640E8294794DD3C2AA021192B091DE3 +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD8382D6C0E608E24F441AAAFC4726E5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = 0700D5E09881BF1F9A946DE6F3EB9A76 +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51A499B55AC8F7FBEFBC331A613EE9 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = +Tag = AAA5FA172CB9F07D07463CEFC7440BC1 +Ciphertext = E8C3DEEE246CC5EAE3E872313897A2BB6089AA3E15E80307970F2D1F006654C2 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 30 +Tag = B9E5DBBB767A4AD97D1949F09022CD66 +Ciphertext = 96107D8A29A7529A7941BDC7DF1FE3C6C7210336AB5B1EB94CFC067CE2248742 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 3031 +Tag = 860248165402DBD4C41DE6CE06B7A7B9 +Ciphertext = 30FCEFAD28275DF1A31E10C05795C7BAC752362857C8DBC0CE1AD14B17E764D5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132 +Tag = 16AE3A3EE064E511FD9F9585F986D497 +Ciphertext = 66D0D52BF401C6DC1C0AD4DACD1D94C4F3F13056B09B1797A127EE7EBD0453AB + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 30313233 +Tag = 7DF9EB3A01C3E5D4AE56CCBC76A4503C +Ciphertext = CF5337FCB70EC45D179E0C3F51BB25AC967A5094152FAF7382D836E6D5DE08CD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 3031323334 +Tag = 2203BE65733466175151854848B09A3D +Ciphertext = 3076658CBA8BF3BB6DCCAA2F1255EE2E7DB6C1FA9B1D1E5F9E590FA4D5BBDC35 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435 +Tag = 5C315B7CDFC8B75292B1EACAFAAA7CC2 +Ciphertext = 9310C6DD8E9CBC3E406C0EBFBEA312435F2C894A6E978A90FDB1BCC68020F9D4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 30313233343536 +Tag = E161E0D6894B3C1D7F89078C9021F67F +Ciphertext = 6E024BD403F386EB9D1C56F459CFDCDE1B2F6462F27F58766415690BCEFF3577 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 3031323334353637 +Tag = ACD40754D79F1C3A9522A593B9395E84 +Ciphertext = FABE2CB1E7EBA6329A30080F26E7DC72503D2E3CCE7C9F5BC5E4BBBD2D287019 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738 +Tag = 47B9B9589610D74BF6505608F98A8D2C +Ciphertext = BF79D7476D6FB05B8891A079BE8A1992B63FFE31062DC7AAE254516F08602E28 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 30313233343536373839 +Tag = D9D018DE281C400D7DF33A9D426924A4 +Ciphertext = 12042996DA42B4536E5A5FBC1D9B2326B3016F9392BA49BE3CA6BC1C86503AF5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A +Tag = FE7FC2C3E6F098014D705AEFE2B4ABCE +Ciphertext = 16C36E25FBA893EB467330C2C80B34DA3DF86B05892ABF59012A845D7DAA9F26 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B +Tag = 5060261B7372733014B8B000ABA3FA5A +Ciphertext = B83A1C62AD05C670D6E9220E0DD9BE46E43D8D6C06DA586CEED818F6797D40B6 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C +Tag = 7FA5E603A05DEE74DBAAE635AADE497A +Ciphertext = 8C839BA1B04F19FFE26C69A28F56350FF2D70C8649EBCFFA242029BB9C0FDDE1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D +Tag = 6FCDE81D19A3D78A55F0324134404723 +Ciphertext = 018C9859DC3935CDEAA3388459C8A7EB34BE7DF768AE95B633128F332FFC7126 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E +Tag = DBC8504A6EE24BE1DE7F594925D38471 +Ciphertext = 20FD19DABC1A5CC449A621D34DAC6013EF43F597DF00A4FCC9570F4C64C4D006 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F +Tag = ABEF171657D19C6C1138B7577693E439 +Ciphertext = 6373EBB28BE97C9BAC090CF399C13EF14EA6C5E519E30A5C6EF44F7CEA881AB7 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F40 +Tag = 055DD1908BB4C524BC967452FFDAA943 +Ciphertext = BF77C71B3DE9F1C5B372EF273A08E89BE9675ADC5777342F1D1EF3C5D4BFC7AA + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F4041 +Tag = 5284D040756638A1678663C076762C5A +Ciphertext = B3B05F0A08C5769749A3B5658BCB1D409C75AAD1E8564974C66CFCE4D9FBF6C3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F404142 +Tag = E7CE6774824610077DC06DE66F18CC2D +Ciphertext = A967C136D389E007BA42FBC6747E55A689FCFAC94EE2DDE396F6DEDB2E5F334A + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F40414243 +Tag = 2436CF291C85BB0B536678E7CD2E6FC6 +Ciphertext = D7FDDE3BE4E1BB8A71570BD346C4599689FC9F1E68DB2C1E6AD537C2DBC35757 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F4041424344 +Tag = F3D6345FC3BC6FE52F3B97EF291BF2C3 +Ciphertext = CC261D9F8FB8842E82E22B106796CD708B23422BE018E5533C5EB98E2EB7ADF4 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F404142434445 +Tag = 7E9ED33D249E3EABD1BC968B0BE9F000 +Ciphertext = 96A3AB365E57746625562F5CE7C54109BF0EABAF4A0D0274F528DFC7C68968E1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F40414243444546 +Tag = 7FCF3B37C7801BCD99FB02EBA3317319 +Ciphertext = 7814592EEAE415B75C50EB97F59BA5544F7DA7C82FEED07A824B076CCE8F7586 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F4041424344454647 +Tag = 7C2EA1AF570963F07BD64CC5F9EFAE3F +Ciphertext = 9D29F9D52ADF9470AF4CBCE0A4481AC7FCB1B32976469892D5BC918CAC7997F5 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748 +Tag = 827185E74A6D226FD2FA5CBD8A07AE13 +Ciphertext = 16CB13E5853541E2F36B38240366ACEE48E0B21D8A3424739FCD62AC2DDEDE93 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F40414243444546474849 +Tag = E7833CF56F755945AEB70D2BAAAA361C +Ciphertext = A92EF70DF2EF0FAA74A21F9739FB89237DF62F9A2B4080B850046DDD386DED48 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A +Tag = 24C0704A7C552B78E5BFB505271F48FB +Ciphertext = E4C1BB6B1B264F12EEC2ABB542761ABBC0D8286FB990CB040DC107595C16386C + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B +Tag = C57C4E944A374176C7465FFE44C951AC +Ciphertext = 52476FE14A8119E7CE3696C48930208F3DAEA77D67142DC97EEB7C934166A3F3 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C +Tag = B2CF12AFAF08EF5F7C0F84A41AC6E480 +Ciphertext = 432F0CB672E75FE412F94B56CB0A4C2E42F3FC8496ADD69ABC3F8C48C1061A20 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D +Tag = 81C118B24248F7A8B0829BA47A383C05 +Ciphertext = 565968B0563DF95EA9124E5F4506BC64F57779D678DB879EFF69D9D73F189FE1 + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E +Tag = 779233DA0AE25E0BDE856E4805896EC2 +Ciphertext = 4B392E5FA60E0CBBCA547DB96E3262BD8382D6C0E608E24F441AAAFC4726E5AD + +Cipher = ascon-aead128 +Key = 000102030405060708090A0B0C0D0E0F +IV = 101112131415161718191A1B1C1D1E1F +Plaintext = 202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F +AAD = 303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F +Tag = FD191750A47F211C0A15ED28173D7CAA +Ciphertext = CB34D04660A66DBFBE9C856601F5B8AA51A499B55AC8F7FBEFBC331A613EE9CD + +# TestCount: 1089 + +# cdd700675ed750e11ddd2b27a52dcda86b04aad03af9e54d0455b7fab277a606 +Title = Ascon AEAD 128 Test Vectors sourced from LWC_AEAD_KAT_128_128_lwcforum.txt + +# valid message size 1464 +Cipher = ascon-aead128 +Key = 25F036595935EEE372A205AF4E32939B +IV = 78CCE019A744ED402D04F730504FDAF2 +Plaintext = 36A44E4E4A20741F54817C57F2925E87D60096A48E050EC2C0FA580221BC53645F18EE4E8B00050F82E4D8BE70EDB4878244A2055E334931968B8E4FC871FE972E18F8DAA30FFCD6FA8621A92C4F51D246D180DC1A4D052BCFBCB7FF72B64711E6419058F5DAE37248CC0AD7119F05463ABB09F6F0217DE012CC0AE657FC63443E0FC3EABFF9DD6CED0E944E422D1A30B770C5B7AC5120C5C4AF4528D0FD1A4B68C59801DB1A8741DD9D09E28D2E9DE5B2D92FE736AC98EDEFFE2610B3B49BF0F348E57D9518549DE984DA0F483D3795116076F6CD3314BC2DAB12DDF3778D280118EF444820509A8491FDB2D188A5B1C691FE523DA522C033294FE90577A971F6B10D2F4EF24CF010DC713C3562EAA405601762783BEA5CF52F111FD166940DE88CBC207A7563D3440E416133E68AD13EAAE4A46047F8BBC6B13A1EE12C1EAA486453A9A6CA2A90FD431D6AF989280FA540E12781EFADA1930059C83B44F217EF9719CE92E02A748054A71C298EC13D892A79A14BF72858B7B216A5706154B851057A626F597CC4156DA62D479077043F1C3F10CA50CCF86EC117E0C985031FFFEFCA23145FCD2FAEB58BDD50FB10263A1265542144ED003982F3AE429BFA9069872D58C654F0E04E106115C5EEA773B0F0A5B71FAFFDBB01C9EA916B1EEC12BAFB74C8CDB860E621850511E2D83B4ADA7FFE51F64370B98A7256FC6A5E7430234F5AC97ADEA6F890BF9599AAECD9298E9FB7EC209A1C778ABA3E5A61647BC311D5ED927D71D0FCD906C136ADD60F9D992D6ECBA787108832E33EBF9F4B972B44D288D5FE46AB1CCFBA131AD9E6CAB4ABA1C133F6B01B89C464609933105C8D6E95F2DA4E399E528151FBEC74F5AF4C198A14FE8A633593B6FE1099E612E8BF5E85AB43F4EF6571026EB1A4B42F14CFB51480A8FB5D020A605E244F29046C6F683C8DEE4A6C572A24A3FC1BB191DE87E941E4D19140C30183A0E295CB1548FD02423B78A1258448BC56845861E759CF809C65E7209ADD28788C6BAA89C25E0E5AFE196F5566E6C4BC9B153BBB6B9F9B4713152EB060DD676413FF14B9DABFF9F775FD63CDE9791AB6A12A8485A26C0DECD06275AD2F5EFA20B10A4266D10AE2DC1B43466D3CCE5D9AFB780E3559E2C2A6F227E977494CC71602421BDF37B3E49748A7695E269FB00205DBB2B650C4C7CF479B74A9206B93CE7B2F6AFAB27E62479476EDB178647F5277E7726D9A11C63E7A4C979B3E3A77DC149AE2F734B64F87796A22D9D71657E31C213238F925346A682C7F66E6C60859FF109CDD81881DC197EAF42FEEEC6663F4B47F1C083EE3EE66778E0736E9A1B262C9DAC6797961940470A00E31047C7CC61B713147EB50C12CAE7709F9158BAE4942CD25129FEA7A53EB18979DD5BD61FB12411A786F6A7678199ACB02579AEEE5F2C4EE3756692631F6DE5CD2B82357F0150DE6D47136DAD757ACF8051F78FB502AB2AA10CE2AA4A81AE881900DA3BFF542DAEC49B31974BCEA16DFAA7121127EE30CA806794621EB693EB988B449CAB3EC03C2448BB19C103EEE26B84AFA37F9D603AD01FBB97CFBB901E07560EB08A04C2CBD6D5ECEF2316F97C88B2069A06E06BFB2B19BC8B73386C68A89D027B052E6856B1E3CC99B07107C9264F1F1DB4F61726EA038560584748AE79743696047E675A59AFE81323C24AAA01F35534195EB3B275EB80F198F80E6AAB2E203C4A71B4B7D7B4C4051E03F327C8EB6E54E204851AC0841028ED75B151A17D77F5A20E6F904EAD5C548AAE9471E86938BD99A9889699057BC6519BCA62036263A09C0D75BA7BCE1644B8208011EFAE30844CF3C7F7F4D16C9C92994EA2E2FA51283AF3E5EAE37E41CB9333EE787559E6A35B36251F9A7BABBAA0E927E27F6361BDDF67E6EBC84590CEB20C54B0F2E42748B2AB57ACC5418DCF482B4A0A466F4C3FD220991D72FAEB15A5565D9E16FAC7BCB1EF2FD41BC4E89DDA17A39CFB868852B024EEC25B09C5C7C031F77EE3FFA85D639D48673F78141D380B335B474E1A1EDE0AEDF20BF551A8196813D9CD79A9E +AAD = 06F5D7D8 +Tag = 658D40A525E26024DA774D24C3E4021D +Ciphertext = 73A34D3B32E0E40CBC1B8899A3BE8A5B1F1A066835F7AD1F7F29392ACC280041A16B9D5DC09CEDC86D91BB3D0573D40489BD5A5688C9FBA4F09DA806F17B1E04191DD77584ABFC1A971739DD14C51B05C933E03B1F17B72D1D87CBF2A4F38EEDE1FF005BCB4013C971E75CAED2CE0123E24934271896C6BB6E9982E6DC5C35070001F264A78FF767859C712EE6A6AFE52F061B141383788E1AC31319D3967C9F16BCC6F65564B204F9C4FE9C331A65457E473988A9B05E8E485A12B21841FD89ABC58896A64BE922CAA25AC8EFDBF2AD97F28798463607ADC3D0309A5BB352E0503BDCF4C9227CE95D90291C3EFD5E3929C69F7D978705F03B9E4370FBD4D7F9A21F8D3C3C25391FB081774E22AA9D5088A1272994A212FC746EA9C0D0663D731F93194F564AB1D9C4A82BC11910608658EE91E782C2061C7083A4AD24006E14EB49591F83D240EDE6E994A0E256DCBF8E1A8E6C5F273822A3A0F2F5D4921A648C2A08288B87E6A4A56622E304260F447E164DBA6A173FDA6D07EF76F7F5996BAECD33909EE1495094B02CB86DECE7B53420B3DBD5002E432D5DC3C44061B63931E8D9DB65116A4DF25E33E5D21D51830F243A815455D0C00D608AE674D9853FD3F89A30C579A9BB9BAD1382479CAD5B94BDD5DD3D75C2546342EB528070EA0F061DBEB0543A518F71B9FB51A85FBB40573449FB126DA45D29285F3AA12BE7836CAC1639869B279DF8CBBFB36CE3D3C489BCA5D0F2621E8B4D89108491461C4C213154CD88CF27BF59D81E6E56917438FE683559B44BDDC3B16E3B1E804AAFE2BB24069661029D417328425AA40C12485683C3CDDC8B63D095B28FA1EC35A76BC1CAAC9D6C46C8B8D709BE3DE394F4952D6692634A50E4766F66801408AE2A2F5BC5A879A545EB6D86CDA4964ADC553CE0690A03F2DAFBD6F6293F685340789B2FCF23861D86497D7A17EB0CCDEE520429D7F1BB134F920E4AEAEB1FFC6EB890861A09C1267E6F28D13195325F53C3340595A23EF18D29FB9C6F3E4462D417F2DE719DF9E147758E7C64A9333AD6D16E6D69FF5F47BA0A481B20FC9A2E57E78E2FF72275A9BE0C56C18B8AA797B7102A9CD6B5CAB38E711215F87B97E39C9F912D5A39D6ADA0E8694C05CB06ADB5C8927C2FD1E087A119038B8EC5F4C9FF3A6F32D3B6AFDBFFE3682827950F60F7AA9E5C8D03CDB59BB209D219697F8FDBFDD9A7BB04CE2608947CE7942B051379B4F84A0B4EFBA3504AFE86A659EAF47AB0F13D6E5F6F91955B475E2B5CA8FF07B4E9E797381BD3BA0D4D0D977014CA3D04314372239078AAB189BEA45A19B3868E34A119CF9A8C31BD4E9514A742AA3377FC58DC2B891AC1B8910725BF509464317ECDFE038DC6D2B4490FC4AFF177244D2C3E98102518CBD6EE947ED42491A1C19994827DC934012C63E1869F2820219CE06B97A31DDE9A5E73ADBCA1811C1917B33D74B3E34624938D79D777890D4E8734660D447B494A84636998E06470C6FC08D1CA44AB95001DB60ECD533A6D69085D00C32AF13D237283DED6255DF01AB1A65015EDA2650B38C5A6E5A8A9352EAC6848C5F8F84736D46ADD611EBA1CF2EFB1B7EEC22E46F45E5D4CDBBC8B773F3FE3E46704200589B4C2B6E6ED91AC09F7DADCA73A322D4CD434565D8FDD02B43A7B3A725B96FDBB878FCD815341F11946E78C4BC70D8B6B2CF5A5CBE1AD403CBBAB17094D88E66773C58BDCC447793031D6131D780DCFB8C691E5565E3458DC79539EAE5F98EF4D941230EB3C394A99EF0AC25529A4B1C935948DA5FE38A78F2EE5BF16BB85644EE9F0383A8D956441A8F91AF241083B132D55B40D974879EFA39920AD4C15C68CA067D7E01F60B2E75FA1996D70FCADFA01FD1F3B3DC26A7521C53722F7086EB94EF9B6695371F1DD01A8C5E35CDF90C976730DB748F02928034D81824964BD2A618B122971BE23B5FF0A6423866E5FC7CDE6574EB8367638E45F76EC676A4FF9621D445326B1CA9967A4D0543B45F50BD19AA3FFA489E4B7A8C411844CF3E7A838EA254AD35BCFD35FA53120AE44B006F09F + +# valid message size 8 +Cipher = ascon-aead128 +Key = 2ED5EC554182411718E4B3C30CDA2FAB +IV = 8E52D7A2F8438151851ABD1BC20DB45A +Plaintext = 2F67C96A0E528599 +AAD = 16CA0B462B3D618A +Tag = C0A864A79E4C15BB122F6578401BE145 +Ciphertext = F785F7ED37B4BB31 + +# valid message size 0 +Cipher = ascon-aead128 +Key = F3B7BE4BDDD625D5AB4E647EEC51354F +IV = DEE22EDAEF5188E777ECEB84ABF11711 +Plaintext = +AAD = 51 +Tag = DE741C08B24D1461B9B72224A8FCDF1E +Ciphertext = + +# valid message size 1464 +Cipher = ascon-aead128 +Key = 6B6FCAED4F633FBBA6EE47485C994754 +IV = 9F15B214E07FEAC5A237A28601C6D463 +Plaintext = 4407A27EE135D0491401D2E10008496AD94620B110F6975EC70E91092AC396C0BC2F265B31472051D2ED8EC3179EDF0C69AAC6710D5C304E6F44B7D3A3C61F506A1224D1E1ED389126CFDF2268D347282E85A07FFD25B35FFFD8EBED904DAE0BCE3D5904790E2A7B72344B3D7C0DE59CFD8EA41D269F53455FC5D209014A01D821D4542A7A42AF205A240DC8D975E2F2F24FF001A990E42FE913A4B43B217A2833731CA8B8BA22BADF83C301918B6CEAE2DF16B259002F91EF2541669DFAE439AAE49466583A39382D362125CDE29D5EA7BAD25C0BC7CE33438BB89279BB1CE59F8957ADF70591A7A6DE8422DE09C40D88E3BEE328882DE2156022CD82A6BE71193C86438BF067A2282BB52D42AB543AC7AB0A96FD38BD165C749796E3C425FF1F1309A2838181987B1CBBFDD2009F690CE806D79C2873E17E6FE61758D0BE6405B60D2FA2B1B64629711AE17DC0435BD42D89FABE4E63F7A02823139A6A3FAB5D57F71CF270C75A31BFAD2A0D9263BE2C8B422B47C4A5B753168F7A8EA3ACBE326F8426C8276864662FC8FEA038EA0DC464E70E28136499B13FC9DCE14CCC8E13EFF79E0D3DF60522DEC517FBA7171A2C81B629BB9D961F0BEB74895D8C8219623AEAB1404BFF866EE2EC4A4D4C9D0927AEB05F95A3D37658D89222C96CA7965BABB4C1BD66DAE08130BAD9B14CD1BE4D6B61AFDB2284BF66745867B9DDBD023A55EEA197DC4CC1D4D0DE65E8F9C40C07D3D55D0AF8BA3827F55A480D7227A472B79E5B5D2F27711EA0DA0B441ED66DAF4B60E5085FF7429AB679A28103B362A93AF2315B69AFD8AC633F6A1DAFF3091EED99C111419C13C05BC1A6B584EF1BEC78620A2CA511469C8838A4208C25EBC27083946AF250679EDF70FFA808222774247EA54CE9DD78DB52248909F8F33436D5E444015AB0F927FB6C4C35129E9465112FFC0D809ED8930AB917CDC75DA5EC3CC9D223DD261973857D517D9043C9B49023F8C8F626B5370BB1F6A1982C5F9DC660F848CC7087EA158888024C5B03C7EF633CA465DDF516139B182C3077DA581EB4B7304B80E81F9B0DB26E9DB3EAB0AD2FB135EFBA38E86AE23530585BBA9EAD30E398A3D27C6F7B1D09572A87785FB0687E00C6A569637BCEC5684BB7C7405314C06DD0510CDBB342BAD2B1E0BDE36AD580EFDCB9D808C67F1CD50D1324C355C80416C60A8F5F5CA34D83EB96B29B11E1FD7537D764993CB8A6503437CD9F1DF67DE8DBA71D5F452193386B541C30CD81C42B15AE8C7D646ADA0D633F2A25D6AE66F519C9BF69C49E3015442B2EE89C7682B372A1896F69008371CC0FFB05F76E61BDEE261604C15A67777E7739393CF271EDBD76B23424F68C19454E9CB5A22A1ED5C970F975607DF2183A12F0F2C74A35DA9D0E4880BC2D98F79AFCBF73BDB2D45458636FCBF8FC8C3F8499FA11069A52FA18C21794E19E189CD702DB63BE7E5B873E9C9963DA6AE2A18108FC233287F000AAC45AFB9A4072BA4AD3F3F5212981053E72D36A00EF1FAEDF7613D8A1F56A5011DBB8F92460EDFD29DF180776ED805787F6E4BFB386FFBBA4AB1B242D99185568A2E3467087E0DD85D54021D61837F2F5BB51AB10AB9D8ADBFD547944C8D08FC6C39ED4093AE7FF160639DD46DDE48C73282E71486D44BD04586A72336798BC05B05A137963E9BBD452940A71C044FE19C8051C9A5F47597FE1CFB0D074CCAF6D7CD89582D113103F739DF5D83A4B44146C596A617C22A6690094979339EB5F86E59CF4E8AE7B48B5F5DD26C1528145958B9B631A614DF15A322C823D7B7C06873D6EF29D565C65F011B56B9FFBE4167F4E02089D87442498AA9AB582F90B3A79D79E83E38FA73E2E357309ACE2515E4D1502EE78736800F9495AF2BCA6E3F7067AF1C85C6133F0A7C3D967143B78B5593B686CF61CC1066E9E8A9935B48188517B0331F08902ECE21246B49900ECBDD1A499803E7701E9B9EB59BED699BAF3415115983846C5CF397B8AE3D60C6C6DB2CCC8911A014ADA7A1978053044154857537247EA53858ADECA47C2EC1D13AC7FEB0B +AAD = B82D0E40 +Tag = 88DEF4000D9F595609BA2F52968FB6C8 +Ciphertext = 3700508B86C6FBDE5A99F5E7E3D76383E479B54A473D410C11A92581030325055863D3701B0D79ADB706FA57A68C31FAFDD144EF4513708A5AA6ADCC3655A57C9DF723FCE48C72388993F8DF88537E63A149E6229464E91954BFD939F038796F15C90E1F1520B4D7EE11A10803C4D58E91451A5E954D3FE71B142B721821952FE4722F1133BAB0D38EAF240AB4943A8015E8000916C4B6783E053A30E0B73040F4D994C3BDD98AB032781D4A5A39F7A17305D2E24DDDCDC423156AC57B76380E5FE74D86470FB843870068F30EA0315615BBC41BEAAD493404F33E258F7957914E43E11D7840A23C7BEE9052EED902E069246C663A6837E7516A21B8EE302105FB1A800EF453AD45813EDAD3A4248E0C9F347AB88D4E4A0E4DE9E6DC8BB37C0E0EA8FF3EBDB66CA9F339CEF73E5FB9D0320537255D6987FD6F242A787D9C1F563C198742996F823C6D6488E4D3D661C184CB5E67EAF8330DDD4A46A1CB023E87608F7278A68BC232DAC065DBC913A5D517B9092C9F7CE3D470DB27D49A915287489E32CE77543606096CD27CD160E75771E556A723CD828BBE5FE32C63415A623963EC6ECE92A8C5F8CE493A3DBCCF796EAB88EAA78809F026C001D186C29EBE4550F5E567D67C46F8B226719CBA4A10138887A91D324CC86F0DC334FED59AB7E06C62749F16406AE7313A89E6B35EA1B2E9CC52B2E97370B1607112F4A5732805DBB31B9EBB0598FA47BB88E64CD75A5ADD337887F797BDB954B1DC5CD8785291A46DA87E056685656A910AA46B6B7F54C307F046BD072EDA3C2929603DCE88340360A77379E2E40C14D3CB59D57AAB0A486F200BCEEFB1452A3764471607F148FB813E71F7467A338C21979FBB161BC06240FE8C2589F4D306C4B1B56F5F73CA5CB367EC3A688DA2F8450AD53FAC470C4A4FBA6DD839BCF654CD055DD757039896EDDAFF01A1F55484E002E5D6A59A78C5D31C73AC5C8720A72C1C8B596F47CC0BA2FB5755D1CC58DDB417904638BE5662F7844BD044ADCCAA815F9CA7FC04912B7E5BE7013C419B717608D957293B8D433A7E51ECB5C66FA19775F31DF59652AD70EC9249F76BB21EB09318790414ED9C9A4ADD689A4C60A0935CE1067FC47671D619EB7543F2C17CA064F1F890E7644D8B301389E3361975B0FC2E643E2B89910D65053A721A0E9131F0E5575D0DBB5BC1EB1E09CAD17C574BE5B46DB1ECEE1AC4568B79AECA8C037DACA7BDC0349C2D0EB6AAD892AFCBE9B1F1B78316A274E4974FD802DBEB0388BA126D25502758D1470B90088E63462BF5BD6587D52D3EAAC86ED998BCB47B0261351F84677852C22B66325612A3E56A012114D517676093A73579CF7EA4F318F7B2A43A094CD3EFB8875352F95F1A336F910EDFF62236C532FF43A39E8BA05707862B21F2DC278D97E2D2F092A968F1B5738033529BA2B53316E868E4942DFC1C20FB2D2A9522C58539429880C68E069F9D8C5213AE31C5F0BFEFFE6DC5BCFC739FA398186A6432CA0E11289C337EEB913AE416102E3A0C12B5DA1898F40E5635CFF2776009301CC142092EC7866906441974E90148E541A72DDC3D930E68EA871A0D9072F39F8A8DA6226975354AA9FBC7809AFBDFFF82353450B0390489FA0B9B4161BC0E1DEE57A43661DC2FD2BB4E660F11A9C4A3ABA187B3190A167B34A6255F7537BF6C482EACB954DA3F9DE83BF24D8804E6A2A94DAB4899E42DE9C3DB2F55ACFC3383581E9821F63ADCB156E4A453021EE5495383DC054E138C788159ED7C5909B861690AF3EB451C75166A8511B04B2A92BCAD01F3B58629B979D67EEE982FB77001998E3F17BD67BDAAF6A8BB82045252B23D5CC4C559C360379567A02356120DCA7E62980C9CE245BEEC513B284F5A825B139C00A4DD4D9B81DA96D1476B5A91941624DE8C8A6AD530E9EC6A8759BD0070F5CB4A6E2CDA54CF89C0617BE49C75F963098FA139E101A3F751796B5D5E7B161183C7CD64BF3B2FE8076F031EE8D853F06EEF185B74B79F05A198E330896D88F4166C754F9E9494660909ACFECB57F9893486987B4556 + +# valid message size 0 +Cipher = ascon-aead128 +Key = F1B827484301D3544465D144B3F79035 +IV = 2CAEAD773CD9956E752437688A05ACF2 +Plaintext = +AAD = 86289329A818574C +Tag = 79165304ABF60A22CD2BF90896E92FB3 +Ciphertext = + +# valid message size 1464 +Cipher = ascon-aead128 +Key = 4080909FA727D84D2D9C3D342AB67DCD +IV = 5155EE0FCF512BE7823B0F63DFE4DFCF +Plaintext = B3DF4184EF61E1BE41334208EBCD1D5F83D57BD5EAFDC1A37C71AEBE36C8AC953CBD1B30ACD162CAE8E7414AE95A87628779EF00D619A9B51D9E087DB323887887ACCC2EB2ECB2B273B1EC02BC77BA22EA4B36BCD8ABBF221365130EC8E417C55FC8C23C8D58B09BC63D8D242DA7F9A6E3E59367ECCBA0DCEDAA1B4DD9A4E98F9A27A2F4B47D94929B9AF59B1E9AF46B6C6D2AE351AFD89428E64FE23C63C22254FE8A050504F1655001CC52D504BE52B5B0E16B7A063DEA4E0DCCCD2EB15537D8D3471F0FEE65677BC49250E286BF2327FC2D8C8256A74EC09FB7F73823379EAB957901BD9E42C64A79F0B673ED08C84EA8A63184C8B5822CF95F6F376E2F578CF3A44D0DBD6689BA66420865F1DAD297EEA98F7D051AE3DFF7D5C33FD28FDC4A98298049BABB90421D771E85AD1C3A1F8CD848C4A0D987D8C06E15E8A249E8D766BECCC85988DC33184D608EFB5D31DA9AA4B2FA4617AABEA2A7894CA5A89FD38F461FEF4F72C503FB15AC5379F8DD623C3B4DFD97ED914E140D26B2FF908E70AD8DFFB53D428B28DFAEFE306B5645A9CA2610695BA23BA1B5D0DA414B13036B873CA5EBF82724F9B0241EE8EF60E3BDC87CE7D97F24140B515EFF6D6749DDCCAA92A92FB159B1A20116B9368353B154ED1D79CF2B29EB63279A9A9A28B7916647523D5CB7B30C6ECB44D8696ADE87FEACAB7F4AD00DA080A7460816BF167A498453EE3115559D39110B03E75181F848139BED7D38479639B2BDB570ABF5AEB4C98FE517EF55E9570D4539C50AB82F254DBF032428FD103CBCB57F589F2C8E1B5C4E1DC19CE158BDB2966FF20ED12FF98D9023EBF28A8CCC7EA85A3AD691B7E1B71D68BB9B6E886C674571928E1E2EEB8686CA0F09A229D2C25142F3861EE721DF8E3BF068735D1F07B684AC18F93E607A6FB44FC6A7D814F495F94A2B94E6485D50B300E33D821228AB07521E7CBAC812E2791669985A37B526FCD37A13F472D03B4EC8463D7C3DEDA1261A9F85F677DB3037481BCFDEC5F57B4ABC40AF9815B79582E22DF282D5653C29C7713F97302F84F74ADBAB57005C89D2CAF3BFFC3D0911630A02144AE9AE62E3DFA51754B5E4198DBCB74D390C3E8185A41FB7E1A53FECBD5FDC8C2D1B3A0D9C79C8775A45341DE6D9324085BBD757CC818EA6CAF6803D9FB959F5D957EC7182AAB1C043C6263F7002D00872FF66028784C0AC8C9343A5F88AD8A1EC3E438FEDC1BDDB0A1713065A4E36C72678CA9F53576D54973FE4EE660CC7B9EE855331BE401BB1418AF86F71BA523E5D7B7E80C0384D95D1EFF8ADDCCF74FD505A17D4FB0409E55D185DC85FFEE2DCEDA690EA8D46F9B537BE5FCE486DD57215FA1F17A27D4358729923A7DA8536D30D1BBF363F896F0960629C3CA43A9CEF43EBB264DECB3A70623778F42352DAB2888CC12DAE9F338C8A15B63FE006B438FC3363EFD2D1F441E04FD307117BE50E87EAB418786F40A4B826D9C915FA8F5C8340F8F0EEEADFB698804C5FCC2B7A0F2FA7B8F6519BBF8CF2BF37ABF82A2CE5C07684D183F5209C0AFE7FF823E1D88CABC99A6D42980AE7806BFD2EB334BE6D53669F55A7A98C39861BEB531CC76911E7ABFF2E90BEA3276C9C5017F8F1E9D64011A4BC4282E5023D60E727ACB6CBB902EB4708348FDD94C377E90A587441943115130A22ACCE64C6FDF02FD77B7AB5D197150CA9E1A1B03310F9CA99DAA9C81F52F597A3C096561DE342379FAEBC47FC3339C05F34EB507363D712B203CAEB5328108586E3121101BEEFC69E6A118553B1CE66A1E968EA66A4233FE984A3191956E3779D37C1192127BFA14524B1095251BF0135644A6ABF251EE1C0D2287D1BD6AD488699E71BF0B5447929C7A542F219ED97C5A1E3B40B79B77818DF584EFF42856E776982B869A311801FD140F77FDCEEA6E490B879F2F83C0CE26E03105CF67AE74237CA8997352E219062953A39BFF93CF0B16A6E8A0B7C7E2C75D5FA9F0024295659B54811650FAF6296E88F6202D32275C71FAA8B0B5C36BB4C5D215F3382903E6CE3E00AB12A8BA2BB0CF422 +AAD = 2CCAA6827E2B637230A5D973D651EF94 +Tag = A9EEB9B85D1760372C0C98C8335A094E +Ciphertext = CA7C015199C6620FD282D300E1267299CB6700590009796F87E678BC60B0BA09AE7FE2A631B2562B1B3E01886E2034F31DAE5518BCB3201003D4719835D898AFD04F1A38B15E4B02DA90986D25E932B9655AA1ACF87E22BA0BF9EE79E6A82E29C7A99996530005CCC468D4D58AC85646FE7A2B2E92161231C119E507723877ECC0540DED31DD360A9608D822965A60475C20E182D7BCA71B8FB9DFCC36E51C148614565E840E0993ABADC3C7F1E61B4F3BE16D163E99C6F90A5D0B2DDB8A6A4A5336B4D979113BF0A9B17BCC6E6E17A8262D2E2EFB3DA0AE0D0C062971030AEF703A5DEF029E71632FF628CA64D67FF16B3FF2A3260472C39E22671F6244FAA7A40F7D23030A342021B4946DDEAC2A3214664FD14A85DC4C3EA702071B449A9A5757DC7AB40B104A47EA19B3772F04B08ED2287D7E9E867C1017E6B67E30C336A57B548AA044501CCFA48AFC1BD20F3AD13BFB7EA73D22067CBF94C5BD9320AB78E1E3754E293CC143A34E72F0BEAFA30B61C9567C19837C145A71C67B28C4E9B24DE2DE4F0D7439664E30457CF0B98BD8E56611B432C2F1412D360E8234F8030B3C77F84F7C5615D0983504789D2162A8E75689A5E09C661468479C7070F3F93F8552921B5DD185617C5ADF8A85988AE6D6DC326AB5296236D4C9D2F403BEBF9CA81C3872C14CA8F4CC1ACBEC43FFB5DB752A292FB630385AFF00A5AC0362F96B0298F4E87E1722E726290E5E02E7CB04235962FC6DF50674B35449D635B185464D7B7A1BACC56F9FF752B65FD06ED2E9DEB4B7D6A82EEDA24F35DCFCBE87277864EAED2258D256C7451FCFE5B5143F07E36E3B4ECFFE4BDFAAA5781E16517195FC6264B5375D728DD1BB11479E561B628F6868AABFD7A26E9BAE82D99E6DF8675011A941F6641C585A4B62516FC343A3AAFFE35271FBBF5F42AFC5C98BD1452D44FC58D5A85F075858F4F2C98F9793F0F3866A2F987B44AAFC7E546AF599B1499D786B4A913A3CEC2541F68F6B8EE7294027C597BC9794906E4A313B5B4BC6C78156DAA576CBBE4043FDDDAAB8FDDA91AD99EE0F42F0E6F66C767B01C378B935DC9F40CF86D691F9069D5A16C86448E87E59A9FBE467A4B05AB52A826AF9AE0DF33F50D1C5933ECA17460B99F850D5A0808A9199D42D7FBF239C022EF59D0F0E10E7E193DFFC90C98F0AF5BC07153B18FE5037727335A3EA1233B3826B6FF4B109EBBD9C5478274BB6C0B07B24C64058E12036F9551EAE273019D85192A10416D7B50736511EC88D9CE9D0F9AAEA0B1F6D12DC474AFD69AB8B60D7A55822B6E19A1AF91C0EB2CE0A25F8ACB318740332F638B5C965F6AD95EBA61C0355A94A3F4E5CD92DB809108C7EA383CFCFC6F4AE5A08EDF38B916DB32264D05342D47EDA1A0A09E5D60FDE5CCA7398B43D7A898F7FBA309C3012C2E37E2B9223EC2C9CEEE937EC56B21AE0E531CE835EB691F8E0086642B81F77D7CC0FCFB2E7758EC3DEFCA8E451F15A7B1E568334473FCE78680EF7C303C72585BC0E0949C70A65E1E201970EBECF957D04A17E3FB3332233BC9902F1324E4D483D6E315AFAD7262DF00C42115760E1CB85B66BD8B36A735E4C35873004D3FF7776792473EB5D5518BB01FF54A2AF9BFEA6A6551ECA7609257297A8B03672C2AC52382ACCA300A35727CD114FB46B177C4512CA39D0ADCA302C00493298E8FE457BEB78CD4DCF49AC507E14DEA77F81C04FCCE200ADBE6B7BC3C3406CA2DCA2A458AFBF91A5BFF82FBB2F84AA2BAC0733ED0297FD781D159CAC564CCF5473C5E65E5D3603F0E97DF7C4884FBCA76C356ECBDCF1D78AB6DD06EB9D006AE80054C997E5E3DEA7DA92949660FB56CBD5E924556E8341BC10A47E36F029A9E64507EBC5A8CF5CC96FFD39C3AA09F1E7F392D943BC4C6A62E58A6EC83C15851FA2B19910D985F22680CA993243CAB28049909387AD7FA906D18D595EFB17287E67FC33CD9C835535C989839D10939C351DA8DC3D0DA0B89A3F8FFEE87F38A75DCF3ADF1307F20049D48DEEDD78B679FEB1BAEFE16B005515AA15A13E0CCACC7FDEC28C + +# valid message size 1464 +Cipher = ascon-aead128 +Key = 1E8CD913F8A3C084E7BB3A2BF2E47D31 +IV = F34F2DBF04E588CA3C2D24C0C4DDBE25 +Plaintext = 63BB688E8A866BE4DE100A30CBFE287643D046C2D7C50D4FA827A254B6275771AFFFB01E248F9B3772DFE213230BFF89BD8D7C5D0931219DAD18E662E3162EB6B99881CB4E0A52B3340E50F7E3F92B9C27199729ABF9687EDE12700BA938535BB12C5A8A8A343AB23BC828FAE129BAB4ED493BCA7E050ABF3003EC3C99470AFCBAF446B69FA112F3DEE4EEE3D16E9CB558BC1E5FFD89DCAC219B5A8748FE19F3BD2C3FECE303154B3748EB991727EEC16637E4DD29ABFE3118999503468BAAE0CBFA25A42FB0D154A6D228B59E4295FAAC9820111A3BCA122D0DD4496E1105AB9D0BCE1C024992B5658F3656824993D5049B57AD6A99C58F30127621DC88E695CD7C17937478F762066BAC8A057390E47AFF44D2BA574104453EECEFD371D9DCA9A089063100608CA3F4A7FFED3B8ABC8292A6DD4313DB753B134D358B088F9491CFE164E989B2799EB82FC5B041170AB42F6D41CAFC9996C514CA1EB22B009A64126D1D5925D3F8DF2C3E8BE315C5F9FC43805B9B4ECA95364B9FD4BE94C772B794619DD4F9B08F5C74619DBD0DB2B04FD1226EABA4FF1648D7E70E86FE394B65CBD34EB427240293F0FF26EC2CD82898EF85ED7159C712944A55FC12A2095E3A1538F13963FB28AC1FDABAA5D92A1BFFBE7597794CD90C04C1B96AD128F0F1E7A0EBD6F3E6EE34F35C40527E0D6CBB203AFD532C72E5EE3B2CED78A99157842EE9D205ED532719CF41A31C0B878EF654FE4A972B9DC575BBFD9AC7F8758A6205BC23943A67CDCC12E383EACEC9E2B49EF624AB47C05991245D4AF0B85F205AB641164E63F9BBEC317D844719DAA7F21AE6290251DF1A45639170DD1DDC13B2C329348CB29350A43B377AC93B117849B558D6D2361E08D726D1EBD189DDCF5469D183F0A61A3F869585C61965510951192628C506417CA5205D66E0A87E1B5D68265F698E87A39B184F3CB157EF72D5C89AB862B50A4D2855DECF48B45FDE166969B03FF19FC391838CACB604CB4E30EA91180EC6B9A75ED83714B0B85AE7B9712647ED3F33E328D726DE295D97248A909F5D2346CF50B0C15166BA8B12D928A5F344DE8460F1B7ADEF36A0DA7E014113891F19FDC472A1D6962CEDCC299DC44CB684695246062FADA6755798AFD6425025A702F2C02BE081A207ED3404EB8352725323FA98EECC83F06B574E1B0926BFE99CA6829BD18C8BA3E7AF3E18FBA9BAF104265CB248B837DA7F0255D4916699E12E4A674401B7A1C79857B03E8E6AF4C19C5C16E2CA0CA1E46FA71BCE37B61181165CEAB04276EF4D84941AF107F84B140E93383550B61621A982D45A9BD390E1452F283180437F266DC85E35F2B0DD775B07C0A37EDC305F45C907BFA195B1B10438ABD7CF1994CA1311C88758E12EF9A55CFE9313EC6369FEC8ECB73CBF84D716AD31BA0405A74273F5906C14A907649A0D1A44971E9E18D542D9072DDD8E538DF070ABAF74F49FB5BC201D5BF65455C0871C2EA53F40F80E19E4C22CA01495663CDF23385CB526187A8FDAFD80BCDFED8346A6C060AE4DB0779C958F327315A78AB71E16301C64D1F6152AB065FB8E5D05D4A8596DD5068E9273C0C01F96E6077A3372C99DC8BC67E2D4C94A839C4A7C0D388A5DCABB39B5B09084BC5BA3B2602F22363289C4BF3C174177990BBC0BF52844B2E60B883CBEF9BD180D44000B3E22691A606618F349784D468943A0A9F4848F9416F1CB54A7E57738CBABB2F817353976A1A1AA8E1051696EBD42B37B58132488B56CF44D5715737AEEDF279DC6552E540A2A0853DA0083C5875D966532FCE0B8872A42AB40EC1E8C2D2FA03029CBA868135F702E0BD1ADB4E82FC5FA7E0E48F1FF6E169B1282131E0B7B25AB60529BBCB42E51D38CB2ADB57C8EC31127240D1EE7AE31BBB50C55904C52228FAB02549593084550BC74654DC1601F84BF01F6E66E07C4B121E006A8D8C187398F1E0A79392D7D1EDFBC617248E4FA55ECD0D04A5B3C20A43EA374B3029C78FBED2BBDA255A64B9283D807B1A552683CE6B0BC08F03DDE53FD663A95B9CA1B434466841C2657 +AAD = F8 +Tag = D5C5ABC5637056784430BB83883891EC +Ciphertext = 29DEF5AAB3327EA6A440787A5E2206B533C93C02A2796A304F0EA242634083CEFBF2FBC07ABC5F87F6E0456766E6A513040076E8299A42CD52DE4B117DBD674246C106E987DEC0CC6F2FD051C083941EE62852FC33D67488E1F4BACA288A1FF39F5A83F3A8C1C204935F18FD47D85F973B2F97E967CC8B35A024822C50B8E0128B8C4A271BA28CB200F9A7BAC0FC90381CA24E02954FFF273C92B7E7F522D935B043E0E6A8FE1BCCAD4A623F6B3A7DCE4D743BAB3BCD1248AE5805EEB532E03E1FD1724B03DBCB893561AB2A7981AFAE462CB8864A796B88A7E7D4522DE4C301FF60D6079B515E66269882FF2FCD82544CA0D3690D91D152A3B479922447BD99372731EDB956B5750D0402F971711A70C125C71D1A5B44963440A300D2E46F7DD3F2AEDF65A066B7CC7D3FE2F4F3B57CB5EB83198E84C3C79B0DB353BECF80F764F87A1F0E3E4912B762E3DF150134E4DDCC11F2ECC044CAD53090840D2D9C8ADCCB4602BE5F004BDF10AAB19E72FDB986F3D9DA1A3D6C66824FCC24FE749B648C5748F6E53FBA77290C37DDA0F35758072BAD413CF5A2073722AB4C8FA716161DED06A0AF706898AF2DA498DE89A421E52207E6F53898E6037203071A263A18FCA297E71CF24955699D019A58BFDA00878A7716320916865ED37A6649E93625AA92CCBDB503A2F0C3E3D36430C74F51E86FFD3670E75BF7AB2C51D7C96B438E8C0B25DF91B0B0B6F31D551AC03302E2D37A61645CF73C3DBB53BEE136833E37F64274F9BBF25FF01BA742FE4BC472CC7A870C712011570F6C1BAFD05216B1390B5B86E3B52EE92133D7AA4DC6F4A343D117CCDCCF4EFD285E99D25F7A88F1D230F02E463DDA00AD12A68209FB979A8A915D0D436ECD3B6F74013E25E2A8F69107C37B525BCBE1FFF4E35D4E9095F16C398AE444E6BA1B9B6C297225D001B0FAED3E3D4E0C6E6DA7AB0A59CDA4DB4F01048D9D1E45613776A94E4522D9B11AE017B472AEE12D06BF44104FB8AD09CCCE5380FF33A29F29A45B7EB36F4C1970F5F5CFCFBD601D1F40BF7C8DBEFEB126B20037F88907785B8C850CD87221CD7A5EF6381BFE69BA0D1046A7DB5287049519EAA100D4A44771F9F1E458243E79B2534D08638BD8827B97151747DB0E1AB2CC1493E95DF11C324608FCE29F26A7169783B25B5571CE02B7F7A8556E303C215A0A7BD44ECE63D64E4B28FF92B0E441EC5EC22D475CC2E911D2C52D3E70DFC6E3BF7D6396F1892E33463151404979DCAF80DC21429B599171364CFC33AEE4AE17DDF02B79C611C09635D3C0EB1324C2EDD78E0FD18103D36C2998055851F257D21A439A95FFBA0835E41310DDDBB7221E897225C9EC2B51E9993E1D1C89CE5D2D29EE0594A6B152ADE779DC191C15368426D3838C9D419248A7054F31F50AADCAD5AB5AE202B14148F063414A66F64AEBAEFCEE67DA4367D8E2118720DB2EA8423BBB6DBD18E0FA9779D3A3931793AA165B21E71929C084A4473F00F21D69546BFDB928848F60076B040C2706456587D33CD6E53CE2CB10E9FEF4ECF788ABEA66F5C46149E09ADD1764C7728B14DB3AF05B1454FC0FD7A8A7780CFDB980FC5FE3C9DCCC48F46BA9058B7505AA0984286A297E9941598FDEB532580525C045F1DD12D6BC1A15F05A9B72169A8B64E1AB736CD4F4F0EB4FDDC3BA85AA790757EE1FF3BD3E7C18D32AE72D99B35BDA665078723B34F0F7ECD2CB5316BC13ECB67B7814E4C45B77988BCED1A86DCA1DAE3DC58A2E2B89238364F15F13C3115F74165B36627D317ABE5F02FAEBB1DF7A32C1986508E903CE92E2939DEF63231E6EC1D576E3ADC6ACE63AB9C26394486BD2649BA1F8EA1930A7A96F102AD3E6EB504A95D4C44C0746649AE066D97022154333D02757D7CC0B4C01AC1C112058ED9F9E082AA28431C31FBA8099C8ACF72BD34AB1A730E4159640A53EFE32AF22DC0EB80A444BB8479F58D5BFD6E890853DF8559634D979446E31AACE828A99CB88C294CA3FE8056598042BED726DB0D5844F24CA9902A9F24035549FBC6B5E72FA0BB3D745113CF0BE22426B + +# valid message size 8 +Cipher = ascon-aead128 +Key = C727F2F43D3DB01322148BED7CA2689C +IV = E4CDCAF06BE1DF1EDD492DDCA16DC764 +Plaintext = 1F6728B45349836E +AAD = 7C61056F9FA2EDF2D7E6C19A1B9F02A9 +Tag = C889635D5E268E2DDD43B5E5CD60CA83 +Ciphertext = 261016D057AE996E + +# valid message size 0 +Cipher = ascon-aead128 +Key = 5771E291DEC058546BFBB2AD02AD3EF8 +IV = A5626303055105035398078A19CF2BDA +Plaintext = +AAD = 55E699E0 +Tag = 933DF4109AB41A2D68E0CF173A0BB790 +Ciphertext = + +# valid message size 0 +Cipher = ascon-aead128 +Key = FB338D01518A469C8AFEE684A407FC51 +IV = 1F5653AF6F80C48E1BE2A3E77845E339 +Plaintext = +AAD = 1527E192001BC1C6B648B52FFCA24B70 +Tag = F099AFA2BA7CECAEFDFBAF74DE38D157 +Ciphertext = + +# valid message size 16 +Cipher = ascon-aead128 +Key = 6C7F4E3BF57069427CE9F2D8C3FA8BE6 +IV = C4F9D885DB1ED936F2E831280560F0BF +Plaintext = 0EDAF3E9D3258AB79C42C4DB29C08923 +AAD = 972E72FB +Tag = 1B27AAC1F4FE5F9774ABD5DAFB1094C2 +Ciphertext = 7A66E9A678F94A97813B6A11904180DF + +# invalid message size 1 +Cipher = ascon-aead128 +Key = 2C7CAC2664252D4823C73C52C72188BE +IV = AAA1FBA3FCA821AE8AAC89BDF157C0E7 +Plaintext = F2 +AAD = 26 +Tag = D7E1DF2D82F2D65D40E1ABC0574380BE +Ciphertext = 46 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# valid message size 1 +Cipher = ascon-aead128 +Key = A6BEA4AED53BCCD400FF6FA44295BF58 +IV = 7B8C4C7FCA94311997DB35A36C69D1E6 +Plaintext = 34 +AAD = 3E +Tag = 2527412E08CB9DDC1C50025E9EB9A23F +Ciphertext = BC + +# invalid message size 1 +Cipher = ascon-aead128 +Key = AB3C95B802039AB6B5BC0215520A56DE +IV = 43914EF700889BCBEF0BD7263256FFC9 +Plaintext = 78 +AAD = C6 +Tag = 172248997933301CDA71DBA22C39DAFC +Ciphertext = 41 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid message size 484 +Cipher = ascon-aead128 +Key = E693960656161B0A93B0321271C3CD91 +IV = F4654A9CD87F5C8E562217D77199B471 +Plaintext = B6CEF3CCF7DEFEA7634B5670FBCAD0EB5C7D2785601F3B79AA6DE3B5B3D7F7BFB5229F37A3C6EF92B5F10E8BC1B25BC38C937C1E23DF93969279228AFB49F38B5396BAD92A9848958E94D06E11AFB8F8121F291F5BD89CD58E09A52AA464976BFE82382BF78199F34BE6908F0F2484E2C12978DB1FD32F7AFAE54A20F31DF029FC64708F778D00908536D374480CC66A84C2687AECBC4C2A52BD30123779002DF66693AAB3F56B3429E855E9FFBB32ED1EDF9C31B5753D3F18463CBA5CEE580C36A67EE1791CB68E5634510467622A978B42F358DCCE78802953916DB8B0D73B9048B3593C507402280DDA802338D8B61CA52E19FA0030672DFDB7268A49D5A55C16741EAFD05A3ACEF12FCEF4F75CF07ADB511382BE4090184C2C3E984E78DF3834240DC4BA074B4AF44B09D0617235A0C6ABAEF7C2239ED5E30562A31CA280784F96C0D34F2CC0D405C98D7237BFB7D9F79DD1A2C9E876108537E1B4A4A72E52CA9081CAB261519AEBDAF1F8962B9D244E88AC7ED0DDAF6720AF4E184B0C2F5E9B3BA7A73DEC27954C37B7EFF67D7A5999BC651BFBAF81EDE019AA0212384FDEAA935D5A84F6E6626116319926C071A335F57E8EA61462EBB9BAC62442258213E7D844621F1FD5A3D503BAE47DE8C720A806CC1DB9C138963072A0C92FC21F3C941EB1 +AAD = +Tag = FA37ACD3C1D8F1C0723B341E1F7D6F5D +Ciphertext = 0C8CD7D37A379C2B76B6B37F0768B3EE24A9A519E15049AD0B532CB387B70010959CDCEC930788166CBF50A26FD3F41E2C6223B1E2DC64DE16602E0202B574D0BD5F1F5E5A9F6B99CFC0BD7BD8E34C7253D92A57BE953B689EA1BF402FAA6D2AEDF2F435C23C495579B3B8A3640981402390030EF7C93367526081522AC98B9F81A67C3820AAF4A07B362F5481978D8A847D9E54F8C357C79C7B9A6E89896604B8590BA8E673490C80E6F2F187B1898E9DAD95838BC052E39E84CC6E89A3538DB1E2071281A406DE978FBEE1691A5526D62C1D3B55DED246750525705E76DAA960C921288B76338BC414B63E3E1019A285733FD2A36D3E7D5A981B92DA90383274B020406B3B35B1ABB627398F73C142363C0AEFC1A03FD013ABD1AB498772C09F9E7E02BD1EEF57A55EF5E87FA01A166F814F3E4E5B9C741DCB0CD8E4FD824D708B6A034DB6915F1200F13552A538BE93EED757935491320800BF8229C4ECF49920DD761270966FCF24DD69B9794DE3DBAA77FFFED55CC587CCCC29605D3479697CA8DC67930B98B879EB4D327FFCAE3F2DB554AAE53CF3544EF6F83C1696D916DDFA819FCAAEC0363982E44258BF863CC3AEF6C6509EF33FD551D29211EDA27098D2572FA4771CBBA2B85F20B80C46AC1D3C42607FD0FAB7EE28899F704BAA0D1233CF +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# valid message size 2 +Cipher = ascon-aead128 +Key = 1CC57062B8C14E2EA1A8928ACB33C05A +IV = ABF56F6959B0971D6117AE4D2F7F1DBE +Plaintext = 51E1 +AAD = +Tag = C2CDBF38D60E781AE9C26BF35FF26B9F +Ciphertext = 83A3 + +# valid message size 484 +Cipher = ascon-aead128 +Key = 37949CDAAE30BC6AC3681C23B361FF3B +IV = 115D2252197A43254888C44094D28681 +Plaintext = AA88F69C49AA8D0F10B4996B524BFD960AA07F7777188DDFA24E71475E1EC04231C18DF890364A9536783870AA0FC60625C7074D18F35B91FA16F9FA3946B0F2F4573990BD0406D356EA40FEE01D3593886A219716722A3D65FBFD793C4F5CF0C8467C53D5364821C034F72EB35DB1DDE16672CE2419DB812CFC2AC2068D96068D4F369AA0E1BD512100D6E27BFC8A084A2097D5DD8DCCAE6AFA26D90B861A339DF0A06327163DFFA920AD2343F80630712277E6F5C129FF83872FA6BBE4469AE5A3458B5B27E033E2972CBCE0A86B71F4F667E80F343DDCC6A1DF9FE79644C4DA123D9FB37BD5494243035D946D1FDB1CBDB1C57C5D8AB16569C4BA48404C4C5368E2CD6ACBBE79201DA6CC31DF475982038329E47E477C888C3949B61B0101F6B70A2B8B517150FE38A45FB7BE8086216A3844BD2367D4206545DD9175C2051CA5D57AD51CCD3092322AACDAE8C5C90CB3274BE2BC43D34F350A250C93BF89759E4211E906B0059D08B28AF8BAFA38A07BD1DD4D76235F61012A9F11A823FF73A0363CA5B3E0060322AEDA0AB9DA943BD28591C1E13CFE7BE3B0E7DB11F4F5E4B2175884BD92EC9BCADA2AC84854A82795633E22923D916337C0C203F92AF22EB9F657A182107D3F98F5F7071236338E07C046ADB5D2527586F44CFDD0E9A2A0E8FC0E +AAD = EE986AD2 +Tag = E28E9FC252FD561FC98AE9EE514CED41 +Ciphertext = F91B8B6B05A72D8647C97A76F0448D651E7C9A73B1AD4A0376F6522F9A1C31ED80FEA66E3825DC3DA01A05A75F523BBC2571E0616A0D077D7243764DB812E66594887296C34693B3DB5B2BEDD3A2A4BF96BDF7B1A88F8EADA33E5C5C820A2294830F0A998340CD457253C66B72CEA657AC2C39644CA7C815D1343F0A3470DBCC86E9DF8867F0D341C4DE1D166C37ACD41934404CDF2B3C53A9B4F1A56B8E05352E9784E7CBED1C8BEA434221D10B67F74E541FA4D54F0F234AAEE1BF7DF8AF1F47F56F2B2E2EF4723CFAC75F9B98F991945B6DED60C524B62370DD10534363B0F64C9982A4DAF5DD881D68565D72209C4456E13DDF77D64EBD87643155509D8C16AE3D75DCF739B945752D368CEDC597A4C3327A382E1FE41719FE9B011CAB4EDE31B031E2E2FC84351F67E5E3073AE075DE75A9FA08629DAB9C678254799F1BEBA6D2115E14591D40A68B5BB5B90B1E0E55F870C5288DF03D87AF2346F216AB694E5AD026A2A189D4FCA9A8BCC554D4DB9F4665B91D989F0AC4E71D818E658E97DC1639098153B799512536191E89E414E7446CDF926572C30A5732BC7B4BF9ADE180539F5847B2CB61EA9C8B5C760F0DC5FEE45C58756AF5E8F15246C1C843041645043D071272E58EE3CF9DCEFAEBB0DE33BD47AD56F1D2ADBF79EC45E024649F8DC9 + +# TestCount: 17 + +# 6c0809b1e184baee4193125599c63b238c21c138c85dbf73090f838190878764 +Title = Ascon AEAD 128 Test Vectors sourced from LWC_AEAD_KAT_128_128_rooterberg.txt + +# valid basic +Cipher = ascon-aead128 +Key = 00000000000000000000000000000000 +IV = 00000000000000000000000000000000 +Plaintext = +AAD = +Tag = F1E8DA91F9FBF090CAF3E37CCAD91BAE +Ciphertext = + +# valid basic +Cipher = ascon-aead128 +Key = 00000000000000000000000000000000 +IV = 00000000000000000000000000000000 +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = +Tag = 92CE8989E58F4E24C3EC7A98AEDBDF83 +Ciphertext = 2876CFAE5C2C69D95BF97A4907C8023A + +# valid basic +Cipher = ascon-aead128 +Key = 00000000000000000000000000000000 +IV = 00000000000000000000000000000000 +Plaintext = +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 0721E4FFF66E5EDDC394F4D384880713 +Ciphertext = + +# valid basic +Cipher = ascon-aead128 +Key = 00000000000000000000000000000000 +IV = 00000000000000000000000000000000 +Plaintext = 202122232425262728292A2B2C2D2E2F +AAD = 303132333435363738393A3B3C3D3E3F +Tag = 792793B5E3664005E2D7023FD50D0070 +Ciphertext = 2B3A48FE270301D3967FD7BD0570BCF3 + +# valid message size 0 +Cipher = ascon-aead128 +Key = B29D680BA104AAB08194B26B58039EC0 +IV = C53060FFE0D3960C85FE318980032ACC +Plaintext = +AAD = +Tag = 635DA497EEEB62088C7539FFD73D3F37 +Ciphertext = + +# valid message size 0 +Cipher = ascon-aead128 +Key = C7378E54488C36CB62B31EAA64CCE654 +IV = CF067C5C8A4B88E6D6BAE6D11F0263B0 +Plaintext = +AAD = A9D1A64E7BABFC9BF64721EFDBAA60A9 +Tag = 6EE453498885D069A61B6194CF2D3D1A +Ciphertext = + +# valid message size 0 +Cipher = ascon-aead128 +Key = A25109DC66CBCDA19002A515F2C07807 +IV = DF99BFB0B73FBD2C16F3D1B215256333 +Plaintext = +AAD = 412EB4A9ABED5FC46C5B115839B992BFF46398F3FC37D72D80F15D7DCFB5 +Tag = 9B1868FD9031FDFF0005BC47948B5907 +Ciphertext = + +# valid message size 1 +Cipher = ascon-aead128 +Key = B29D680BA104AAB08194B26B58039EC0 +IV = C53060FFE0D3960C85FE318980032ACC +Plaintext = FD +AAD = +Tag = 6F5F578BCCE1450D7EC08CFBC4A58B69 +Ciphertext = 91 + +# valid message size 1 +Cipher = ascon-aead128 +Key = C7378E54488C36CB62B31EAA64CCE654 +IV = CF067C5C8A4B88E6D6BAE6D11F0263B0 +Plaintext = D3 +AAD = A9D1A64E7BABFC9BF64721EFDBAA60A9 +Tag = 5F09506AC92EB5EEB82E5CF7D5C50CB5 +Ciphertext = 36 + +# valid message size 1 +Cipher = ascon-aead128 +Key = A25109DC66CBCDA19002A515F2C07807 +IV = DF99BFB0B73FBD2C16F3D1B215256333 +Plaintext = F2 +AAD = 412EB4A9ABED5FC46C5B115839B992BFF46398F3FC37D72D80F15D7DCFB5 +Tag = DF29238DDC3D1C13AA7A30A15A19E7CB +Ciphertext = A4 + +# valid message size 2 +Cipher = ascon-aead128 +Key = B29D680BA104AAB08194B26B58039EC0 +IV = C53060FFE0D3960C85FE318980032ACC +Plaintext = FD68 +AAD = +Tag = DFA216BED33CC8206F7058599769B0B7 +Ciphertext = 9123 + +# valid message size 2 +Cipher = ascon-aead128 +Key = C7378E54488C36CB62B31EAA64CCE654 +IV = CF067C5C8A4B88E6D6BAE6D11F0263B0 +Plaintext = D311 +AAD = A9D1A64E7BABFC9BF64721EFDBAA60A9 +Tag = 85A9BA4E46B89F3F260AF3AED127118B +Ciphertext = 36BC + +# valid message size 2 +Cipher = ascon-aead128 +Key = A25109DC66CBCDA19002A515F2C07807 +IV = DF99BFB0B73FBD2C16F3D1B215256333 +Plaintext = F2E7 +AAD = 412EB4A9ABED5FC46C5B115839B992BFF46398F3FC37D72D80F15D7DCFB5 +Tag = 915BAB49A89B39E3958617474FB58F52 +Ciphertext = A442 + +# valid message size 3 +Cipher = ascon-aead128 +Key = B29D680BA104AAB08194B26B58039EC0 +IV = C53060FFE0D3960C85FE318980032ACC +Plaintext = FD6878 +AAD = +Tag = D7FB201509225ABB287BC536C8995BBB +Ciphertext = 9123B6 + +# valid message size 3 +Cipher = ascon-aead128 +Key = C7378E54488C36CB62B31EAA64CCE654 +IV = CF067C5C8A4B88E6D6BAE6D11F0263B0 +Plaintext = D31112 +AAD = A9D1A64E7BABFC9BF64721EFDBAA60A9 +Tag = A0C97EFC821BC62280FAB400EFBB41B8 +Ciphertext = 36BCB0 + +# valid message size 3 +Cipher = ascon-aead128 +Key = A25109DC66CBCDA19002A515F2C07807 +IV = DF99BFB0B73FBD2C16F3D1B215256333 +Plaintext = F2E72C +AAD = 412EB4A9ABED5FC46C5B115839B992BFF46398F3FC37D72D80F15D7DCFB5 +Tag = 70DF8DE31D061A2D39B34BF74C6A1BC0 +Ciphertext = A44211 + +# valid message size 7 +Cipher = ascon-aead128 +Key = B29D680BA104AAB08194B26B58039EC0 +IV = C53060FFE0D3960C85FE318980032ACC +Plaintext = FD68784F3F718E +AAD = +Tag = EFBF8188296A37300C21653B1F951B2B +Ciphertext = 9123B684A94A63 + +# valid message size 7 +Cipher = ascon-aead128 +Key = C7378E54488C36CB62B31EAA64CCE654 +IV = CF067C5C8A4B88E6D6BAE6D11F0263B0 +Plaintext = D311123F3332E9 +AAD = A9D1A64E7BABFC9BF64721EFDBAA60A9 +Tag = F3D1F6466A3F35BE6219443600487C5B +Ciphertext = 36BCB051C746AE + +# valid message size 7 +Cipher = ascon-aead128 +Key = A25109DC66CBCDA19002A515F2C07807 +IV = DF99BFB0B73FBD2C16F3D1B215256333 +Plaintext = F2E72C1695ACED +AAD = 412EB4A9ABED5FC46C5B115839B992BFF46398F3FC37D72D80F15D7DCFB5 +Tag = 543CD5CC56EB26AAF3B91EC4BAC26B04 +Ciphertext = A442111377B820 + +# valid message size 8 +Cipher = ascon-aead128 +Key = B29D680BA104AAB08194B26B58039EC0 +IV = C53060FFE0D3960C85FE318980032ACC +Plaintext = FD68784F3F718EFE +AAD = +Tag = 8C09A854478B282BCD05FDA33C35E09F +Ciphertext = 9123B684A94A6314 + +# valid message size 8 +Cipher = ascon-aead128 +Key = C7378E54488C36CB62B31EAA64CCE654 +IV = CF067C5C8A4B88E6D6BAE6D11F0263B0 +Plaintext = D311123F3332E9CF +AAD = A9D1A64E7BABFC9BF64721EFDBAA60A9 +Tag = 14A6256642C9ECFD5F1D5F605020235F +Ciphertext = 36BCB051C746AEA4 + +# valid message size 8 +Cipher = ascon-aead128 +Key = A25109DC66CBCDA19002A515F2C07807 +IV = DF99BFB0B73FBD2C16F3D1B215256333 +Plaintext = F2E72C1695ACED6A +AAD = 412EB4A9ABED5FC46C5B115839B992BFF46398F3FC37D72D80F15D7DCFB5 +Tag = D4ABDF636377445694E8AE947ADFEA22 +Ciphertext = A442111377B82074 + +# valid message size 12 +Cipher = ascon-aead128 +Key = B29D680BA104AAB08194B26B58039EC0 +IV = C53060FFE0D3960C85FE318980032ACC +Plaintext = FD68784F3F718EFE52C346CF +AAD = +Tag = 96AD9EB9E5D526DCA5B51F31129B9928 +Ciphertext = 9123B684A94A6314204138F3 + +# valid message size 12 +Cipher = ascon-aead128 +Key = C7378E54488C36CB62B31EAA64CCE654 +IV = CF067C5C8A4B88E6D6BAE6D11F0263B0 +Plaintext = D311123F3332E9CF1D5D43F0 +AAD = A9D1A64E7BABFC9BF64721EFDBAA60A9 +Tag = 8B542DA1F446A2D8DCB35CC425C094D8 +Ciphertext = 36BCB051C746AEA47F03B7F0 + +# valid message size 12 +Cipher = ascon-aead128 +Key = A25109DC66CBCDA19002A515F2C07807 +IV = DF99BFB0B73FBD2C16F3D1B215256333 +Plaintext = F2E72C1695ACED6A32F70AC7 +AAD = 412EB4A9ABED5FC46C5B115839B992BFF46398F3FC37D72D80F15D7DCFB5 +Tag = D4CC3E3ABF8527C7FE9A10BDF270CB80 +Ciphertext = A442111377B820744659C99F + +# valid message size 15 +Cipher = ascon-aead128 +Key = B29D680BA104AAB08194B26B58039EC0 +IV = C53060FFE0D3960C85FE318980032ACC +Plaintext = FD68784F3F718EFE52C346CF90BED7 +AAD = +Tag = C05A68F70EB4AB9D8354F698BC4B3F57 +Ciphertext = 9123B684A94A6314204138F302FB79 + +# valid message size 15 +Cipher = ascon-aead128 +Key = C7378E54488C36CB62B31EAA64CCE654 +IV = CF067C5C8A4B88E6D6BAE6D11F0263B0 +Plaintext = D311123F3332E9CF1D5D43F095A64A +AAD = A9D1A64E7BABFC9BF64721EFDBAA60A9 +Tag = AD842DB965582ABA405AFEEDC8B009B8 +Ciphertext = 36BCB051C746AEA47F03B7F0D0D39A + +# valid message size 15 +Cipher = ascon-aead128 +Key = A25109DC66CBCDA19002A515F2C07807 +IV = DF99BFB0B73FBD2C16F3D1B215256333 +Plaintext = F2E72C1695ACED6A32F70AC70F3E07 +AAD = 412EB4A9ABED5FC46C5B115839B992BFF46398F3FC37D72D80F15D7DCFB5 +Tag = D3547E2F45D48A9E20529A60119A0511 +Ciphertext = A442111377B820744659C99F565668 + +# valid message size 16 +Cipher = ascon-aead128 +Key = B29D680BA104AAB08194B26B58039EC0 +IV = C53060FFE0D3960C85FE318980032ACC +Plaintext = FD68784F3F718EFE52C346CF90BED747 +AAD = +Tag = 1F2CA5998ABB40FD4A5FA231B3DC38C4 +Ciphertext = 9123B684A94A6314204138F302FB797D + +# valid message size 16 +Cipher = ascon-aead128 +Key = C7378E54488C36CB62B31EAA64CCE654 +IV = CF067C5C8A4B88E6D6BAE6D11F0263B0 +Plaintext = D311123F3332E9CF1D5D43F095A64AEF +AAD = A9D1A64E7BABFC9BF64721EFDBAA60A9 +Tag = 3263B243BA7B09F7718B62BB1F7A6FDB +Ciphertext = 36BCB051C746AEA47F03B7F0D0D39A86 + +# valid message size 16 +Cipher = ascon-aead128 +Key = A25109DC66CBCDA19002A515F2C07807 +IV = DF99BFB0B73FBD2C16F3D1B215256333 +Plaintext = F2E72C1695ACED6A32F70AC70F3E07B0 +AAD = 412EB4A9ABED5FC46C5B115839B992BFF46398F3FC37D72D80F15D7DCFB5 +Tag = 85D1B3D207A9BCD0E278E1802FFBA3B5 +Ciphertext = A442111377B820744659C99F56566851 + +# valid message size 17 +Cipher = ascon-aead128 +Key = B29D680BA104AAB08194B26B58039EC0 +IV = C53060FFE0D3960C85FE318980032ACC +Plaintext = FD68784F3F718EFE52C346CF90BED747D3 +AAD = +Tag = 2CA16178C4427832C4FB8310DA22C067 +Ciphertext = 9123B684A94A6314204138F302FB797D07 + +# valid message size 17 +Cipher = ascon-aead128 +Key = C7378E54488C36CB62B31EAA64CCE654 +IV = CF067C5C8A4B88E6D6BAE6D11F0263B0 +Plaintext = D311123F3332E9CF1D5D43F095A64AEFF3 +AAD = A9D1A64E7BABFC9BF64721EFDBAA60A9 +Tag = 7723F660C263044C9B15770BD96473DE +Ciphertext = 36BCB051C746AEA47F03B7F0D0D39A8697 + +# valid message size 17 +Cipher = ascon-aead128 +Key = A25109DC66CBCDA19002A515F2C07807 +IV = DF99BFB0B73FBD2C16F3D1B215256333 +Plaintext = F2E72C1695ACED6A32F70AC70F3E07B093 +AAD = 412EB4A9ABED5FC46C5B115839B992BFF46398F3FC37D72D80F15D7DCFB5 +Tag = 747AE0D1A372DFA122E12450CB3A7B21 +Ciphertext = A442111377B820744659C99F565668519E + +# valid message size 31 +Cipher = ascon-aead128 +Key = B29D680BA104AAB08194B26B58039EC0 +IV = C53060FFE0D3960C85FE318980032ACC +Plaintext = FD68784F3F718EFE52C346CF90BED747D3D314B3EE90401EB243CA07688F0F +AAD = +Tag = 3D6DBD9BE251C3EA77953CA87414D80A +Ciphertext = 9123B684A94A6314204138F302FB797D070EB71C857CFDD700D19F679CA7C2 + +# valid message size 31 +Cipher = ascon-aead128 +Key = C7378E54488C36CB62B31EAA64CCE654 +IV = CF067C5C8A4B88E6D6BAE6D11F0263B0 +Plaintext = D311123F3332E9CF1D5D43F095A64AEFF3BDBE489722D41E1DF6F7C1F7AB10 +AAD = A9D1A64E7BABFC9BF64721EFDBAA60A9 +Tag = 988AE45CFC7EC85EA4E590B2CDF62EB6 +Ciphertext = 36BCB051C746AEA47F03B7F0D0D39A8697D5D6B8ED2607A10FAE027C029C36 + +# valid message size 31 +Cipher = ascon-aead128 +Key = A25109DC66CBCDA19002A515F2C07807 +IV = DF99BFB0B73FBD2C16F3D1B215256333 +Plaintext = F2E72C1695ACED6A32F70AC70F3E07B0933E0D299916D1F03D63E54A17E6AE +AAD = 412EB4A9ABED5FC46C5B115839B992BFF46398F3FC37D72D80F15D7DCFB5 +Tag = F14072073E9E82AF64948C4F68270EA0 +Ciphertext = A442111377B820744659C99F565668519E1D246FEB2AC7401FD6C5E8C1865B + +# valid message size 32 +Cipher = ascon-aead128 +Key = B29D680BA104AAB08194B26B58039EC0 +IV = C53060FFE0D3960C85FE318980032ACC +Plaintext = FD68784F3F718EFE52C346CF90BED747D3D314B3EE90401EB243CA07688F0FBD +AAD = +Tag = 7A40D69E2D753733F20CFEA7C6A394F0 +Ciphertext = 9123B684A94A6314204138F302FB797D070EB71C857CFDD700D19F679CA7C235 + +# valid message size 32 +Cipher = ascon-aead128 +Key = C7378E54488C36CB62B31EAA64CCE654 +IV = CF067C5C8A4B88E6D6BAE6D11F0263B0 +Plaintext = D311123F3332E9CF1D5D43F095A64AEFF3BDBE489722D41E1DF6F7C1F7AB10A0 +AAD = A9D1A64E7BABFC9BF64721EFDBAA60A9 +Tag = EF060BA68BFD8880105308B28F66007B +Ciphertext = 36BCB051C746AEA47F03B7F0D0D39A8697D5D6B8ED2607A10FAE027C029C36ED + +# valid message size 32 +Cipher = ascon-aead128 +Key = A25109DC66CBCDA19002A515F2C07807 +IV = DF99BFB0B73FBD2C16F3D1B215256333 +Plaintext = F2E72C1695ACED6A32F70AC70F3E07B0933E0D299916D1F03D63E54A17E6AEE3 +AAD = 412EB4A9ABED5FC46C5B115839B992BFF46398F3FC37D72D80F15D7DCFB5 +Tag = 0763079B086DE1C9F36A7A3C24B2F94B +Ciphertext = A442111377B820744659C99F565668519E1D246FEB2AC7401FD6C5E8C1865B17 + +# valid message size 80 +Cipher = ascon-aead128 +Key = B29D680BA104AAB08194B26B58039EC0 +IV = C53060FFE0D3960C85FE318980032ACC +Plaintext = FD68784F3F718EFE52C346CF90BED747D3D314B3EE90401EB243CA07688F0FBD41B4AFF38577AEF9E851BC262AC1389752D6F9680BF97C90E458275CDF713217D7BE21CCA3A39255431AA9E917140F5D +AAD = +Tag = 61AE10B0C7A41F519EDDACEC0FA04D9C +Ciphertext = 9123B684A94A6314204138F302FB797D070EB71C857CFDD700D19F679CA7C23566FB0C3B8B10278FA707453A513C75E570DD8EAD6C31468965B9163B1216BDA98E191F3BF70F2670624C9F594C42D0ED + +# valid message size 80 +Cipher = ascon-aead128 +Key = C7378E54488C36CB62B31EAA64CCE654 +IV = CF067C5C8A4B88E6D6BAE6D11F0263B0 +Plaintext = D311123F3332E9CF1D5D43F095A64AEFF3BDBE489722D41E1DF6F7C1F7AB10A0F5803D12DD46B6C08AD9B307EB16BFC15DF8528CB1888C659AD9707E988C1825527149E6C99A51694219B75D30D48399 +AAD = A9D1A64E7BABFC9BF64721EFDBAA60A9 +Tag = B529C95F4A488A0898ED1AEE3DF4383E +Ciphertext = 36BCB051C746AEA47F03B7F0D0D39A8697D5D6B8ED2607A10FAE027C029C36ED24594519262C4DE076E24D9A6980B600095CFD34E5F8E244AE7532CDAAB123389660DC4385CA12A58CB704A9C8E26AA3 + +# valid message size 80 +Cipher = ascon-aead128 +Key = A25109DC66CBCDA19002A515F2C07807 +IV = DF99BFB0B73FBD2C16F3D1B215256333 +Plaintext = F2E72C1695ACED6A32F70AC70F3E07B0933E0D299916D1F03D63E54A17E6AEE39D1CDB0F73F4225ED3737843518A2513C7FFEF01E76CC4C7532F43D6424480E8B439BE5C66CB2F692446D5EF63E88310 +AAD = 412EB4A9ABED5FC46C5B115839B992BFF46398F3FC37D72D80F15D7DCFB5 +Tag = CCF1675C7157AE9E3798D9033A55A192 +Ciphertext = A442111377B820744659C99F565668519E1D246FEB2AC7401FD6C5E8C1865B178E83823FAADC37506364C6D89DA1AD3C1C332A5B39CED1C99134DADE4AD3CC03DBF5987DAC79600493CDB6C236CFCFA2 + +# valid message size 129 +Cipher = ascon-aead128 +Key = B29D680BA104AAB08194B26B58039EC0 +IV = C53060FFE0D3960C85FE318980032ACC +Plaintext = FD68784F3F718EFE52C346CF90BED747D3D314B3EE90401EB243CA07688F0FBD41B4AFF38577AEF9E851BC262AC1389752D6F9680BF97C90E458275CDF713217D7BE21CCA3A39255431AA9E917140F5D6D7D2C919D5E89CD28A6F28A63B14496EA5AE011E3EA8DA715878D9D4748A16E9296D42D9689C07EC2EEFA898089DDFCEC +AAD = +Tag = 76C8013E9FC231A36E5AA7955394E498 +Ciphertext = 9123B684A94A6314204138F302FB797D070EB71C857CFDD700D19F679CA7C23566FB0C3B8B10278FA707453A513C75E570DD8EAD6C31468965B9163B1216BDA98E191F3BF70F2670624C9F594C42D0ED3F2D19B715351E7918D8808819F8C1DA81D109BAB34E1BF762B18EBFDEB232CF7F5F49963AE1DA3D32952FD5C8B9497657 + +# valid message size 129 +Cipher = ascon-aead128 +Key = C7378E54488C36CB62B31EAA64CCE654 +IV = CF067C5C8A4B88E6D6BAE6D11F0263B0 +Plaintext = D311123F3332E9CF1D5D43F095A64AEFF3BDBE489722D41E1DF6F7C1F7AB10A0F5803D12DD46B6C08AD9B307EB16BFC15DF8528CB1888C659AD9707E988C1825527149E6C99A51694219B75D30D48399DC506E1590EE71FFC6DE355FBF373646FE7C6F2099093ACFE6521A866C435ED74E365341C631FEB21EDF924069E4D8333A +AAD = A9D1A64E7BABFC9BF64721EFDBAA60A9 +Tag = 6DD505A77F4FC8B6392E45AF958D48E4 +Ciphertext = 36BCB051C746AEA47F03B7F0D0D39A8697D5D6B8ED2607A10FAE027C029C36ED24594519262C4DE076E24D9A6980B600095CFD34E5F8E244AE7532CDAAB123389660DC4385CA12A58CB704A9C8E26AA3015AEC5587CC7440F655D8949FCCDAFA70B5FFFB830FF761D09D79765992529C8FE20BB40C131D4852039F1EFC02B2AE44 + +# valid message size 129 +Cipher = ascon-aead128 +Key = A25109DC66CBCDA19002A515F2C07807 +IV = DF99BFB0B73FBD2C16F3D1B215256333 +Plaintext = F2E72C1695ACED6A32F70AC70F3E07B0933E0D299916D1F03D63E54A17E6AEE39D1CDB0F73F4225ED3737843518A2513C7FFEF01E76CC4C7532F43D6424480E8B439BE5C66CB2F692446D5EF63E883105C7A879CE5DD7CD0F178F5AD04B88EF1FD0B635245E934B2DDBB86BF746EB50302EB5E1684932FC976F6DA1D5F388CB428 +AAD = 412EB4A9ABED5FC46C5B115839B992BFF46398F3FC37D72D80F15D7DCFB5 +Tag = E237143F445DB6A6D7FFA4415C3DA3CC +Ciphertext = A442111377B820744659C99F565668519E1D246FEB2AC7401FD6C5E8C1865B178E83823FAADC37506364C6D89DA1AD3C1C332A5B39CED1C99134DADE4AD3CC03DBF5987DAC79600493CDB6C236CFCFA25D8F802B61E041F7ABE4FF430E7E93FA6DE20726CD633F0C596193F1A454E62C1EE20FFDA7E29A3566E1ED54C8D4E0E285 + +# valid aad size 0 +Cipher = ascon-aead128 +Key = 98ECE9B5338985F732B274D02D39BAE1 +IV = 8BDF1718569749D3746EA3B51F4853B8 +Plaintext = 819F7C4958DB8E2F5AD217DF747C1EF4 +AAD = +Tag = 20F517BA1C258A8192BE9415071C7168 +Ciphertext = 7D8564BE8FB66586DCE7B28C2B5D0BAE + +# valid aad size 1 +Cipher = ascon-aead128 +Key = 5F57F58B6150CFE4723F85E39A63D04B +IV = D8705FA0E277FA3772A971DD2C17A630 +Plaintext = 7C42EED95BC06B14350DBD2270C852C4 +AAD = CE +Tag = 15633730DEEA28408D67DB0647EC4E08 +Ciphertext = 1089D7F4BBF99B5B84F4C819A8DDC2B0 + +# valid aad size 15 +Cipher = ascon-aead128 +Key = 63EA82F78C751FF18779C5270E1AFC67 +IV = A46DC0D3F4B6277CF87D8BABEDEDE801 +Plaintext = 0253F2B9CE7D38C6308BD3CD43915304 +AAD = 8E85D4615BC9DF2F6F314810BA09B9 +Tag = 17840428C031D4F088C9081E98E0622B +Ciphertext = 9E22510C85AEB3F1D015B9DE8F88034B + +# valid aad size 16 +Cipher = ascon-aead128 +Key = D80B41CDFEA08BC013486A1980788249 +IV = 63785EA2483AFF006B491FACB45E8155 +Plaintext = 22EC7FB33E708AF401784BC3C4C37141 +AAD = 7FFED61D1E69F41762D6752D14FBF577 +Tag = BE0B11CE87F5B10CFFC8D7F58F51E0FA +Ciphertext = FCF147CFF828EF5D8C18852FDFECEB88 + +# valid aad size 17 +Cipher = ascon-aead128 +Key = 8340F5AA515293C9C89203A65564DCE2 +IV = 29AAD441207F17175B8327975EEE0BCA +Plaintext = 9EDF396959B4E6B81FBDCF58317DE121 +AAD = 7D7C000BA16569E0AEBEC220BF9E54D8F9 +Tag = 01705D5C47C2527BCC45CB6802EF353F +Ciphertext = 95F27EFABC891D41FC0A14094D0B26EF + +# valid aad size 31 +Cipher = ascon-aead128 +Key = C30B840B8BFE3DE657D95682A444541F +IV = 493C4F69D2C35B3ADDCF72D8161E15C1 +Plaintext = D38CA899330206230B30875A5AB24FFB +AAD = 737ECC9F4A2F61DEC324A0370DD3B20BD365B10CB65C17D1F70854AC56138E +Tag = 7FFBFADE5459E5E78FC5F8BC85B66557 +Ciphertext = DA034C260B2307EE72E98C53CE62E5FE + +# valid aad size 32 +Cipher = ascon-aead128 +Key = D89ABF07665CEB5B336F9C14EBF95A34 +IV = E982CE57B2F0169B7954D576EB145DEF +Plaintext = B2F7B6B6EBE9538413E68FD48BC11869 +AAD = 1518A3BABE7BAA906CBD23F63EA7474FF7016BB74CECFA30836E1BD4657AADA2 +Tag = BD3367FB1F0CF33163C6CD668B9EB92C +Ciphertext = 322BEDF516916A0C8BD3F09D8C5AC57F + +# valid aad size 33 +Cipher = ascon-aead128 +Key = 05D67CDD0C3D15AAFA84AF83C76E9D8B +IV = A882B2ABABD1DC0BBA913B0BC6079FB7 +Plaintext = D85B96F142845ED5F58A2F4FE0879655 +AAD = 1FB9140DCF2FA45BE9B744BD1B2DC718577B66D3976651CB366EC286D07EC1928B +Tag = 0F934A6E7D0D800CEA3CBF7BFC777521 +Ciphertext = 86C8DEA6DC41849E27F55301613B34D7 + +# valid aad size 65 +Cipher = ascon-aead128 +Key = 150D0E8EFC290FEABB94997A0FE04175 +IV = B847A1AD1B10E570246097388BA37A66 +Plaintext = B8D36B81681804B1EC47C7E75A751339 +AAD = 31D2B01596230B98F306BA08B6043FDA22ACC90E07B350650EF9E662B69DE5F0EFDC2F64C7FDD20581A30777A1D85076845183CCD46D35231D16918CB5C294D144 +Tag = 3F399C6005C3715E867ED7965AC29FD3 +Ciphertext = 93DBB158BCCD558704EB65E0C59BF3A4 + +# valid aad size 129 +Cipher = ascon-aead128 +Key = C588CF0B0EFCF286D87CE81AC12CE608 +IV = 9A4EAD57AB7BA53359B22F52F5001039 +Plaintext = B753D3BCDEE5966EBB9A14C247FA64BD +AAD = FD27B570C44C1E31AB99FE04FDA49FD14FBF053C45399C3DFEB813D646A20F89C37B362AF2DA3F3C6838F060B50D2A7657C2BED34AF8F5603CFEBE65CE63CD2335C390A2B9F253AA8366C79F32054BC6FA7246B60B1EAA68F85DCA16436EA454743676F6CAF349CED64341E2A74D1444FD437538A11CFB1F8E1AB3417D5D6BB9E7 +Tag = 432539208C48D2CA530970B753A16811 +Ciphertext = 9CC058B6B1751FBEB2C2BAD130ED7F56 + +# valid aad size 257 +Cipher = ascon-aead128 +Key = 9395BA1E2ADC4CE5FFFBCB94E5006CC5 +IV = 3D82F3A82B356578BA3342101B3DF0DE +Plaintext = DB591970FB38F8027E975A902A53D346 +AAD = 757C15409C0755FD10C28B89C754E06985014998A047702D48F204D4EF6342EF6ADC1AB0B562C90B75B4B890A3EDB16A4EE009F09AA2DA132FBE7C059E5A11BFF2362D2A6E47C1864496BBC03BA5E18AD1CD08A46ED2AF61F1E10113E61ADD5E1A650B69070323EA47716C9071774AEA1F8407C1CC64BAB2314FA15F2620285E70BB0119C8BF97CEE4595CD36F64DCFCA5230EC9E8C9061061A3192302BE574DDDD902E423AFAC391105631D35EDD2A892FA8F509BA21A788734041F86AE4F359D76405D432CB5F5404E433FCD7303FB881AB18BA69A27C7D400F8AB821DC4D5384C9DB666812B030FF4DB7D110344DD9743F159F564D67CE67C2C6858456D8196 +Tag = 8C9C7A2769D9CF23C629D399B81C723E +Ciphertext = 85EDFBA791AEEAE7C90EFF733DF7E965 + +# invalid tag changed to all 0 +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = 00000000000000000000000000000000 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid tag changed to all 1 +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid all lsbs changed in tag +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = 7554C8CFBFEC169370C4DBEB3C080699 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid all msbs changed in tag +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = F4D5494E3E6D9712F1455A6ABD898718 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 0 modified in tag +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = 7555C9CEBEED179271C5DAEA3D090798 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 7 modified in tag +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = F455C9CEBEED179271C5DAEA3D090798 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 8 modified in tag +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = 7454C9CEBEED179271C5DAEA3D090798 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 24 modified in tag +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = 7455C9CFBEED179271C5DAEA3D090798 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 31 modified in tag +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = 7455C94EBEED179271C5DAEA3D090798 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 56 modified in tag +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = 7455C9CEBEED179371C5DAEA3D090798 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 63 modified in tag +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = 7455C9CEBEED171271C5DAEA3D090798 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 96 modified in tag +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = 7455C9CEBEED179271C5DAEA3C090798 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 103 modified in tag +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = 7455C9CEBEED179271C5DAEABD090798 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 119 modified in tag +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = 7455C9CEBEED179271C5DAEA3D098798 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 120 modified in tag +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = 7455C9CEBEED179271C5DAEA3D090799 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 127 modified in tag +Cipher = ascon-aead128 +Key = 9BEC514B17A27594018DE567F92BE802 +IV = 771ACBFDB2F45E480BD709AE52A96D58 +Plaintext = +AAD = +Tag = 7455C9CEBEED179271C5DAEA3D090718 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid tag changed to all 0 +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = 00000000000000000000000000000000 +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid tag changed to all 1 +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid all lsbs changed in tag +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = A1ED8B128B313BC3B54A35881EE7576F +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid all msbs changed in tag +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = 206C0A930AB0BA4234CBB4099F66D6EE +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 0 modified in tag +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = A1EC8A138A303AC2B44B34891FE6566E +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 7 modified in tag +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = 20EC8A138A303AC2B44B34891FE6566E +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 8 modified in tag +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = A0ED8A138A303AC2B44B34891FE6566E +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 24 modified in tag +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = A0EC8A128A303AC2B44B34891FE6566E +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 31 modified in tag +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = A0EC8A938A303AC2B44B34891FE6566E +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 56 modified in tag +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = A0EC8A138A303AC3B44B34891FE6566E +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 63 modified in tag +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = A0EC8A138A303A42B44B34891FE6566E +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 96 modified in tag +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = A0EC8A138A303AC2B44B34891EE6566E +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 103 modified in tag +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = A0EC8A138A303AC2B44B34899FE6566E +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 119 modified in tag +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = A0EC8A138A303AC2B44B34891FE6D66E +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 120 modified in tag +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = A0EC8A138A303AC2B44B34891FE6566F +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 127 modified in tag +Cipher = ascon-aead128 +Key = BDA9CEFDD49D07D876C978D00266AB72 +IV = C3F97BC788BCEF3F9CE2E2C0E4F29332 +Plaintext = +AAD = +Tag = A0EC8A138A303AC2B44B34891FE656EE +Ciphertext = 71D964088D05D8006D6DDD2C2D227AC6 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid tag changed to all 0 +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = 00000000000000000000000000000000 +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid tag changed to all 1 +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid all lsbs changed in tag +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = D421CE166A020D66F2B04B58F4E2CEEE +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid all msbs changed in tag +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = 55A04F97EB838CE77331CAD975634F6F +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 0 modified in tag +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = D420CF176B030C67F3B14A59F5E3CFEF +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 7 modified in tag +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = 5520CF176B030C67F3B14A59F5E3CFEF +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 8 modified in tag +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = D521CF176B030C67F3B14A59F5E3CFEF +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 24 modified in tag +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = D520CF166B030C67F3B14A59F5E3CFEF +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 31 modified in tag +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = D520CF976B030C67F3B14A59F5E3CFEF +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 56 modified in tag +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = D520CF176B030C66F3B14A59F5E3CFEF +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 63 modified in tag +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = D520CF176B030CE7F3B14A59F5E3CFEF +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 96 modified in tag +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = D520CF176B030C67F3B14A59F4E3CFEF +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 103 modified in tag +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = D520CF176B030C67F3B14A5975E3CFEF +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 119 modified in tag +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = D520CF176B030C67F3B14A59F5E34FEF +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 120 modified in tag +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = D520CF176B030C67F3B14A59F5E3CFEE +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 127 modified in tag +Cipher = ascon-aead128 +Key = 543B11E1AD8028337EBF32542E048134 +IV = 89B4EA11586B12CF7AF8AE970FDDDC71 +Plaintext = +AAD = 2CD43A0628DFD0EC72B96466B91CD77E +Tag = D520CF176B030C67F3B14A59F5E3CF6F +Ciphertext = +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid tag changed to all 0 +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = 00000000000000000000000000000000 +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid tag changed to all 1 +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid all lsbs changed in tag +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = 3696C06E205055124206C596AB546FD2 +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid all msbs changed in tag +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = B71741EFA1D1D493C38744172AD5EE53 +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 0 modified in tag +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = 3697C16F215154134307C497AA556ED3 +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 7 modified in tag +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = B797C16F215154134307C497AA556ED3 +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 8 modified in tag +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = 3796C16F215154134307C497AA556ED3 +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 24 modified in tag +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = 3797C16E215154134307C497AA556ED3 +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 31 modified in tag +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = 3797C1EF215154134307C497AA556ED3 +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 56 modified in tag +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = 3797C16F215154124307C497AA556ED3 +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 63 modified in tag +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = 3797C16F215154934307C497AA556ED3 +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 96 modified in tag +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = 3797C16F215154134307C497AB556ED3 +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 103 modified in tag +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = 3797C16F215154134307C4972A556ED3 +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 119 modified in tag +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = 3797C16F215154134307C497AA55EED3 +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 120 modified in tag +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = 3797C16F215154134307C497AA556ED2 +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# invalid bit 127 modified in tag +Cipher = ascon-aead128 +Key = A130435CC5AED41FDD21228C6F84A08A +IV = B0A82FA045788F0EDCFD83D4A07B0FAE +Plaintext = +AAD = AC726EDA3EC7F951BB7F6094C5495807 +Tag = 3797C16F215154134307C497AA556E53 +Ciphertext = 6E89105F803A2CB613DC876AB9034099 +Operation = DECRYPT +Result = CIPHERFINAL_ERROR +Reason = bad decrypt + +# TestCount: 121 + diff --git a/test/recipes/30-test_evp_data/evppkey_composite_keygen.txt b/test/recipes/30-test_evp_data/evppkey_composite_keygen.txt new file mode 100644 index 0000000000000..ff4130622d08e --- /dev/null +++ b/test/recipes/30-test_evp_data/evppkey_composite_keygen.txt @@ -0,0 +1,103 @@ +# Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# Composite key generation test vectors. +# Source: https://github.com/lamps-wg/draft-composite-sigs/blob/main/src/testvectors.json +# +# Each stanza derives the composite key pair from the IETF sk bytes +# (mldsaSeed || tradSK) and verifies that the resulting pub/priv match. + +# --- ML-DSA-44-RSA2048-PSS-SHA256 --- +KeyGen = ML-DSA-44-RSA2048-PSS-SHA256 +KeyName = keygen_MLDSA44_RSA2048_PSS_SHA256 +Ctrl = hexpriv:34F9019BD154D935F509A8A3284867B09F7245B3FE3AFFB513E7E33EABE48B1D308204A30201000282010100D458650ECD7AA9A1DC565D8A3F5A947E8CDDFA3ED3C9E5618450E4F51CB4F539AF633C18CFFD9D5A6025FD043C55DF4FBABD37CF49E6F99DC553EDBC1C5E80C82F493166985A07ED2585AA585182020712E42FF504832E5FC6559F3339F0FA6F45BB8D7A0897795952749EAC504F4A6FFB9AC708D2FDC6F7A9B84A3322AA5E7B4CFD6316E8D8075A510D21F8DF4A289213AFDA2D9D3809DDCE40A0DB1ACA06A9AFDAC50261916C8FC9C6F81271E2060267ED60714BA868BAB1C3B4E4FB8D2CAF6940C671F1CAF5B84F536128FD3B084E2D8F77EC2A705EE1337B388F5292D2A28DE3503858FDB18062B02D9F24ACCF1127D40629EAA5640B8EA55CA9ABCB0F97020301000102820100585F8D7772A6E93036EE2EB1D99A0E10F8F96D2B76A320F6CBC58AF444053FC5C92B88985EFF92DC4905A65E7BE9D52D6E6F4F69D2BCF107EB56F9AAFF37896B46DAB457997266B818949F87702CA64161685C59218EA2DF3340F127B5A687E38567000358CE09AFD5F4391147BF2820A0DB1298A68EFD9E9720DEA89775C629D2758F29EAE6F7AFE31DC21A01AD126A6F6A7656BE3A46FFBE667498BC5E5B3A203EDA94B81F1E16C725BF671FF76A598DFD0CF5E3DBF3A6454D6912EBB4D4506D06999214AAB033F92A5056A7ACEC86B0333FC54CF67E4E712FC9FE5F24D4BC2C54C605B27D6BF7CF9132B9C20158306D024205E0D63163997D998F68DEC03102818100F20774299DFD276E3E1AB44531DF28A19FBA5EA0E1391C24A8C6F1FE6B8B79AFCC68926AA9A8C04C3F82FB6FC12837816E5C6691D8484406CBC7A7A9B42F3CA078688EE1DCB1F9C6B2F84ABC5956D952CCA550C7F3BB470F9A30047F8D2B75C90712534E23C55E4B0E2AAB30E5F89227DF8C06ED1338B5ECFF22DFF46C59CA8F02818100E09A4B06B0A2F782A01D304601648A9A004C3114888D3504A955F37630E66BC87A0AF45BDE0DFD3CA13F25E0D7171970E4C7C0A8350201EF71609960E3DC324ACA98CCE795B484D4A94708DCB0527C0B2FDD57686C6586C0495EEBE1F512A0C8E28456E96559872A98D9C5F197F1AF7CA5F490CAED248E90E423EEEA54918E7902818079F08D73265954937390CAC08E06EC16BA3E10CD278C3984B2D0413E38FAF59D3FF473C86FA048FA6189619B058B78A3AA71BD6FBFB3712AA762F93344480458A931ACC35909065A38F365DC0D7AF755832BCB4E629B398B3FD8EF7B4029E4571B4BFD52C22CFF7BFB303E3E0DAFB61B86C2AAFEA90F8A81546E42BD8815993B02818100C63A46F73B9449608751DB961D8A8FED454FF98D46CB61BCA07B5469BED4CED1DC2CA8E81FBE36FF78CCD3F071C55855D4051C5B18959201B30DEFB09CCA6DB4A6C45F2C116B86446EB65BF2F2C789E511B4877D8915BDED1D9462194603CFD61C5D729B813097E4178D346F7A8BFB36C6FD678141F51EC27027EAA7F44596F90281806B45A11136C88C3CAB7169AD7C729023D29E3B7F9F99DAD9C2CE050A040351147C44DC739C37D413826914FD05CAA31EF2394960F81DE6A3285B3315C6E2DBDE69D857582694D72D5BAB60F445CD9D689253234A9221B1CFA6040220574CF394DD2796ED9FB602DB2112846B580F83BCB7A2489F8AC62FD8F4E22EF83B6BCF5B +CtrlOut = hexpub:2E5DB69836B5C20D0A56AD897F7F486DDCD329E09DD60BF8C88467A572EB8F5099B0E042A81726892132022F3AF2C3B073D16CA17CCDCBC48872C3CF87A8F9C9D556F358C32417158A7A5EAB3E33C8DC7A9038D678910B7F69CF1D655A3CB947F9CAC4FA6B00285478498EF13B403EBCF1BF3F5E1E0B27BEE2A64549314AA72EBBA571A39ABC1056651D7857816F7FB65CC3E3AC04AF2AFEDFDE42D9FE3E8D6BFF5B0F65576BE997ECA2FB536CCA3321819F3B46A74C614A790C7F54C282573B108637F2071DA385A53CCBA5E05E044DF6E591E57FD06717063B3D409BF24A047C1A5921DD60E72DB9EE36387C4B9647B72EC473AF7F5113323C0E80708E5D087DE1457630370A67CF0DA69E9AD56287F0EFC95554D3B32E5CC51997EED4B79E2BFAED0B9399DED3262E39A309E10DFB85AD148B5D94364B43274F4FB425FB0729716141591A6F5A72CC99B03F9B461BBE65282D439364E664A37786C1681387AC4D47CBE43DA784353F8B327248FE92E6C29EAFAAE0D3E42CC9A391C7A5966E309D3DBB263EFE0A639EEAFD1D69E613F0054E36025F63846C79D677E64C631B6AC81F488C82FDB858D1AC650376E1BD396E2D07378F1E6BF03FF25F5B7F3E96AB981658F1E8480CEC8A0506B2D8D8D8BB5562EB7551EB09667713B36A4463DDA5DF454BCFC7D9C5551E8E228CA8BBE6AF4A402B1AD5F170D3A022D970AA944DEF76132B78D03B49CEDF2626EE01E1D13F0C0E387166EEBB01482A8A89D333DB5DC7ACB21ECF06125DF31F9D9DBD326D9D4A252ADED2A43E7B4FCE68F9DD3DDFCC24E1F595013A9E23D945BC41F6125D268338DAD314C82F9BB1F4EF9C5442E35B397783F710F13EA3DEB24CD11D88608A09EA49A4A61DF53625550240FA7B7945C7017668EE020135AB8C24448C6E7FCB6409349B6B67FD3C973720BD39AFF92ED40AAEEB16E85902DA4673C71220290B7CEA5D35FF331B69441BFDC23A4F3B33CFB91208AD79F6BF4F7CBB93B766B07386A7E03EFB28C6228E74BB241EC08A13BA4D3CE5CBAF6DD18FF3B5ACD2968801E553FE1A343AE416703399F2B5FC122B7CF0BD59F21F7C4ED0F904C63AC548B1059EABB2B3139B373947A002C2AA2C2DB8FCC44FC0257600663A0FDB44F8F9B64E7D308C216F584F8142A062A9DA687D23387156E0F3EC7C8846D32DB948FD31C8CAB02EB24349EB9ABEF1522C874F8CFFDD75BD68DAF939ED53B405AB6E441FE48E2935B8F2623817DC63B6A0169B0442A97FD7F643D5E3E592FB78B934BFB183E2AC6DBA61C98C318CCCAD022511EA7EEEDE5A3C31ED4402BDD18FCB687E3B539121A087F8EF404D9ACFEA2C17A5C73A8A95EBE548A7CCABE9E9E91C901296EB48496B4C54830E58033310165A31812ED5CEF7958FFB176BF170098D67541DD3A911C26D22E4EE96D8632D3BFD35543B4D8E04F32F4307F23F99690D86AEDBA9263849899B1DC79D21C96AE91ACFDE1D4D67377401801B0F8050B9C3F54114CB606F3FEFB814AF92F72A73008638F6E4C081ABA98CC3C5C8482FAB5C7FA4BCE3A99CB942CCA459E23267CA7978E1675E9DB60FC6F448F5421D3975BCE0CBF7612401E8D09D3A223CF3944E98A0B2F91CB8CD5CDBEF6208AFB3894CD6887F1D0C2B0DDFC5BA126137E9A86FEDD47ED010C71C49C83BF8B4F3C4B10EA291717AD28F96C138D254BAE83C985BD1CE51EC86B80EE4A9BB2257CCD17474914371119D8F18F293972A804A6515E33BC66B4E6C8B8F14AAB7CF8C323783DFC553D20AF2E54D0223443E33FF6F1343A587A716DAC7C55FE3EFCA28F849FD909D9EDC4AB51E111C531FDC6B990654970D94153082010A0282010100D458650ECD7AA9A1DC565D8A3F5A947E8CDDFA3ED3C9E5618450E4F51CB4F539AF633C18CFFD9D5A6025FD043C55DF4FBABD37CF49E6F99DC553EDBC1C5E80C82F493166985A07ED2585AA585182020712E42FF504832E5FC6559F3339F0FA6F45BB8D7A0897795952749EAC504F4A6FFB9AC708D2FDC6F7A9B84A3322AA5E7B4CFD6316E8D8075A510D21F8DF4A289213AFDA2D9D3809DDCE40A0DB1ACA06A9AFDAC50261916C8FC9C6F81271E2060267ED60714BA868BAB1C3B4E4FB8D2CAF6940C671F1CAF5B84F536128FD3B084E2D8F77EC2A705EE1337B388F5292D2A28DE3503858FDB18062B02D9F24ACCF1127D40629EAA5640B8EA55CA9ABCB0F970203010001 +CtrlOut = hexpriv:34F9019BD154D935F509A8A3284867B09F7245B3FE3AFFB513E7E33EABE48B1D308204A30201000282010100D458650ECD7AA9A1DC565D8A3F5A947E8CDDFA3ED3C9E5618450E4F51CB4F539AF633C18CFFD9D5A6025FD043C55DF4FBABD37CF49E6F99DC553EDBC1C5E80C82F493166985A07ED2585AA585182020712E42FF504832E5FC6559F3339F0FA6F45BB8D7A0897795952749EAC504F4A6FFB9AC708D2FDC6F7A9B84A3322AA5E7B4CFD6316E8D8075A510D21F8DF4A289213AFDA2D9D3809DDCE40A0DB1ACA06A9AFDAC50261916C8FC9C6F81271E2060267ED60714BA868BAB1C3B4E4FB8D2CAF6940C671F1CAF5B84F536128FD3B084E2D8F77EC2A705EE1337B388F5292D2A28DE3503858FDB18062B02D9F24ACCF1127D40629EAA5640B8EA55CA9ABCB0F97020301000102820100585F8D7772A6E93036EE2EB1D99A0E10F8F96D2B76A320F6CBC58AF444053FC5C92B88985EFF92DC4905A65E7BE9D52D6E6F4F69D2BCF107EB56F9AAFF37896B46DAB457997266B818949F87702CA64161685C59218EA2DF3340F127B5A687E38567000358CE09AFD5F4391147BF2820A0DB1298A68EFD9E9720DEA89775C629D2758F29EAE6F7AFE31DC21A01AD126A6F6A7656BE3A46FFBE667498BC5E5B3A203EDA94B81F1E16C725BF671FF76A598DFD0CF5E3DBF3A6454D6912EBB4D4506D06999214AAB033F92A5056A7ACEC86B0333FC54CF67E4E712FC9FE5F24D4BC2C54C605B27D6BF7CF9132B9C20158306D024205E0D63163997D998F68DEC03102818100F20774299DFD276E3E1AB44531DF28A19FBA5EA0E1391C24A8C6F1FE6B8B79AFCC68926AA9A8C04C3F82FB6FC12837816E5C6691D8484406CBC7A7A9B42F3CA078688EE1DCB1F9C6B2F84ABC5956D952CCA550C7F3BB470F9A30047F8D2B75C90712534E23C55E4B0E2AAB30E5F89227DF8C06ED1338B5ECFF22DFF46C59CA8F02818100E09A4B06B0A2F782A01D304601648A9A004C3114888D3504A955F37630E66BC87A0AF45BDE0DFD3CA13F25E0D7171970E4C7C0A8350201EF71609960E3DC324ACA98CCE795B484D4A94708DCB0527C0B2FDD57686C6586C0495EEBE1F512A0C8E28456E96559872A98D9C5F197F1AF7CA5F490CAED248E90E423EEEA54918E7902818079F08D73265954937390CAC08E06EC16BA3E10CD278C3984B2D0413E38FAF59D3FF473C86FA048FA6189619B058B78A3AA71BD6FBFB3712AA762F93344480458A931ACC35909065A38F365DC0D7AF755832BCB4E629B398B3FD8EF7B4029E4571B4BFD52C22CFF7BFB303E3E0DAFB61B86C2AAFEA90F8A81546E42BD8815993B02818100C63A46F73B9449608751DB961D8A8FED454FF98D46CB61BCA07B5469BED4CED1DC2CA8E81FBE36FF78CCD3F071C55855D4051C5B18959201B30DEFB09CCA6DB4A6C45F2C116B86446EB65BF2F2C789E511B4877D8915BDED1D9462194603CFD61C5D729B813097E4178D346F7A8BFB36C6FD678141F51EC27027EAA7F44596F90281806B45A11136C88C3CAB7169AD7C729023D29E3B7F9F99DAD9C2CE050A040351147C44DC739C37D413826914FD05CAA31EF2394960F81DE6A3285B3315C6E2DBDE69D857582694D72D5BAB60F445CD9D689253234A9221B1CFA6040220574CF394DD2796ED9FB602DB2112846B580F83BCB7A2489F8AC62FD8F4E22EF83B6BCF5B + +# --- ML-DSA-44-RSA2048-PKCS15-SHA256 --- +KeyGen = ML-DSA-44-RSA2048-PKCS15-SHA256 +KeyName = keygen_MLDSA44_RSA2048_PKCS15_SHA256 +Ctrl = hexpriv:78539BB6D21D060F9CD6D400BA9A9DB7AD1B81E3519591E285F7A242798F8234308204A40201000282010100D36DBE90D91DB27EB643531E032783F85B13135FAD7B8A63C29DFB76FCA2B32B3F3E69E7CCBA5014FA0C5D9FCA83F341502F9BAAD1BA2E6A82DAC32D537BA170B477FEF75E6D07F05EA0E2FA288136DFB5225A2FCEA672F87A98FBA23AD6AE5ADE7953C29DD99909BFC52C97E905B906015DE6991082FACEA5EEC253D539FEEB09CCDD36B81304E70A63F4BF6BC9ED43A8763B4E99CC050F36811230780FF1286787AB181BCF7C0D8683FB9CDB170442875A156BA5DC7920E634B749EECD44C0E35981D51997D89AAF0033C6E92B580E173D664C5A8762191C7953C96C3429B6AE3F6AC31CF9A884B5E9B1F40FB722B09AFD0982FA6054D9306C40F5A0D31BD30203010001028201000B5A697114BF8EA8AAE2859C3C76203F88AB1C64B7079B15A2A08CC81B1124DC2DD00D0178A709357F272FD5D7459647E110400F2AFB90E780F1A753BA97B917B8BBCD7CA75CE52012ACC2A8C533B468772D0A39114DDDD4459D0BBCC3E512F0128C8DA3608A368E0FF6A75F86E5F0455D731736B6976F49591EAF8A59E3A732606C7FE7388750F7E70746CB365F97F17930CEF48663BDD45F284CB99BFDBDAB50B86974304E3916C5E42A51D776ADB687944E5F2E4E03F0839E7B53B0EE253E6F3E51ABA8797C7E22061BFD71C442F1A120D82EED3EB34BAE8622F184830510A7B4540983D04A828533B86CEA53BED3EA79907596D65B1D5463ACBD778C693102818100FAF1B076026D0E21D596FAAA6880BDAAE8E2278469B64A48445ACE4BA96F3FD0B16F5B9108EA2E5DD7BAF450CAD9585F7A064339E49DA189A02311BC20D9F1115D40E97D04660DDBEA929B009A37AFC1C7B23B37B6F6A3D8B1C8874810AC82170D95AC3709F20AA5F5C2CA3E83992944B1051DB7833BBB3AF18B4FE1B09AE3B102818100D7B03E7019FC0874A13CD285A226549516D9F0127EB9FEB6563BC1F458BB5DBE34472B706520AEC9CFC46B0A9BF1FAE58427C720425413F14439F3799649E1535232DCB3894BDC7325EFC5A457A138FB923A5CE4101D7D1AFA850B9FCAD06AFD8B9DEAFB30B624C08BD4C788BB005809CBC4CF8BF018C857CDEE2F150E996CC302818100CFB0F32C688B9BF3B2D477784C6FA90AE81E2D38B149772762B389242402785DA04D1B0AE9C6F043290689A8C88AA452B92AAFBF1D90BD1EABD3FA9CAACFD66E59B11CCE24B2D66B9A346667543C1C921456561EA1A6762B25D162EDE926EDB068C4E4B8D4D967A8BDC3CF2178476E5974ED581007648B6C987785D0B41B2DB102818100BD3A61BD05FF090811C183CD3BF236F8CA20903019C0624864256F474965B09BC3CFC0BB8DED7B8B90DD792FC89B268CA04229C012912321E3C297EA4F41280F6AA936D9C895A6A5DB5D9DDF4E0623310B1C6B0CA75AC7BC98978B1838DE5B4F70632E9A0C2570DF008EC0342423EC19440DBA2CC28B6B912519577338E8BFF30281807BE0CD9D3DF5B13FF298BB24DC8B43CD044D77E9C1FF84FC568E50A311FE95264C6958592D4ED8DCDD0F40858D14E359D9046DE2A0543D9F3998D3DCBCD6D793AE0C5C21EE1BF5CD541E823582479D841601B9E4CC586388A05D4302161DA58EB08BCD71E7BD1059F493287521120F1405BFDDCD77A5EE9A1597CFD466DE2F3A +CtrlOut = hexpub:F6799156D8C2182A9CD1DD67B7744C0DC18B067AA2337597BDF4A887E0BD52469BB27A8A3A02FF67B8D28368C1AF40D7D6DA29AEFB3865661717D77BC0494DFE941C2088C5F8D68EAB4FB246548CEE2B7FAAA4DAE23CDE84DC8A95AAEA7770181B3491A453076CEB446BA7E4A3755BA6611A2480F2F92FEA6FCCCC709C7E276A58FC132D8062D27087B57787124DFB7065ABF6FD12CFE8A0BF57CB39AC99587D1D32CE236F08BF75C149DA8B5D8DE80209033AC350B803BD1EEA4561610BE58FF07CC0DF940830897B4C0AB656E745C9BA2B1741B10ED1EB8B9ED8CDBE25AA173B703B6668332F459BDB00326F523989FE37039E90F52D9A69890708579FC738BFFD9A4A8A431D4932CBFDFEC7AFF083D2085016787AAB937D0C4506F64D5D65B4E7A7352F8A559624E8ADD9B2698E26862C69B7A5C949BDA200116DC709BC0D1E2A3D98788DF2DA2A28E4845DE78300D747B90F06FB4EEB426939451B017C5DDD23637F3FFEC4160D2F50D34EDEC5860565621B84E16EC05B6EA01D2C7B40AE131151EBF9485959257877A2ADC81D725AD79143053C8340468116AADB25800977783C621572A68C98467318222F366DD7C43A812826FBE7FFB1ACEEE16865E46F94892E304C9EA2BCCCD872917FC92D1E6268BB53C04D580088A1051BB98ABDFD5ACC813CC1A9FABED3D8E7F42447411FC9FB0F53EB7398301B817CE75CDCAD11F64448E14428A957C5409CEB47416846A2EADB902AFB7102A263C528C98320E61806FE893B39BE425CE2EB7D858D2ED8B87344FCCA53D64364BC6E6A80F205DEC75AE1C5702FE3307FAEEC8B69035BD77028B4DB82D6F3BC46D00BEDEC9094B958D565D30F31D1365A173A73063213680477CE0EF81E6B4DDB943B5ED04380C20C9F837B6F0C97A7404D9F83979E8B1979F34B4334664140FF83F20814441262D60A79A1FCD3990014457DC7AB8954E702BAB330428F5DC8173A4B316F2AD4FB5AA488052967BBEF5086A78400B8CEDDE46566662AB23290918DC769249AA9CAAE10DDCD68F0ABE9325FC2C0C2D3B487A1167B2626A59CB0D58D342A26A54DA43E9C2DE15AC09DCC6C72F2446BD0DEEC4CEDBB342269F2491E87EDBA812041B7EEEEDAAF8DDC6C8519AB78BF8719E181522D8C1F5A608EEE9903F96C4D17A034A5159BD2A3B61BA3A92729984FE2651F087972DF332CADA5CB9A78CBADCC8A3A8BB1F7061C40C5B1A482B78B69932146548573E386237EE6F631FF506A12F046175CB38DFEF07ABE2A2AD7A7A0D5D8A1563AA4232FE5EC1623BD361F85810FDC31413A4112BE55D82C9DE0383F5EFF9824BF42E919609ABA0E8A9DFFCF0DBDB7011A9A5FC785D5F8E5CA335E2885FCC989AFC8C06B8664F1C9D93BB22A55D5DDD98991FCEF1C4BDCD50C79DE9C49F1CF9487936636555301C6B1D3DA426213F8D0367ED48D8E02CAA9D25DBA87C18F03A7C7D3ACE057C503DB05D8C89A3FDFA62FE872A9D1759ED535D49A7AF4AC248EC578C4F2EF5B0F66EE6DB88040095A68A55FBC3E42EB26DDB6961E8A6CCED4D680D056448FF8C47B602FBBA1ED09C5DA5770F1E2B8C14D99BEB36826C35E3E4F2B45CD7A6E05DEACE18967F9686F5FB52ABD4456D94DAFB3A2CB999DB8161BF23270DEAC796D88B8940281A9EC1670CCE38C7E485A0631180F73F418CDB18BB7CD3EBBAD778FB446F9C5C82BED00BE83DE42228C962D6744F86A92BE4BC2CFAC1E1E067681F4A6776C40CADEE0447F69D5AC76334731D1A8CB8F2AE0F5FA2B995684018F6E0B2D80D8E296E2191B5C0C96C97FBE48CCE408AF86FF59F445E6D1AFBDB48A7E93BC30FA9C032DDB9CB23082010A0282010100D36DBE90D91DB27EB643531E032783F85B13135FAD7B8A63C29DFB76FCA2B32B3F3E69E7CCBA5014FA0C5D9FCA83F341502F9BAAD1BA2E6A82DAC32D537BA170B477FEF75E6D07F05EA0E2FA288136DFB5225A2FCEA672F87A98FBA23AD6AE5ADE7953C29DD99909BFC52C97E905B906015DE6991082FACEA5EEC253D539FEEB09CCDD36B81304E70A63F4BF6BC9ED43A8763B4E99CC050F36811230780FF1286787AB181BCF7C0D8683FB9CDB170442875A156BA5DC7920E634B749EECD44C0E35981D51997D89AAF0033C6E92B580E173D664C5A8762191C7953C96C3429B6AE3F6AC31CF9A884B5E9B1F40FB722B09AFD0982FA6054D9306C40F5A0D31BD30203010001 +CtrlOut = hexpriv:78539BB6D21D060F9CD6D400BA9A9DB7AD1B81E3519591E285F7A242798F8234308204A40201000282010100D36DBE90D91DB27EB643531E032783F85B13135FAD7B8A63C29DFB76FCA2B32B3F3E69E7CCBA5014FA0C5D9FCA83F341502F9BAAD1BA2E6A82DAC32D537BA170B477FEF75E6D07F05EA0E2FA288136DFB5225A2FCEA672F87A98FBA23AD6AE5ADE7953C29DD99909BFC52C97E905B906015DE6991082FACEA5EEC253D539FEEB09CCDD36B81304E70A63F4BF6BC9ED43A8763B4E99CC050F36811230780FF1286787AB181BCF7C0D8683FB9CDB170442875A156BA5DC7920E634B749EECD44C0E35981D51997D89AAF0033C6E92B580E173D664C5A8762191C7953C96C3429B6AE3F6AC31CF9A884B5E9B1F40FB722B09AFD0982FA6054D9306C40F5A0D31BD30203010001028201000B5A697114BF8EA8AAE2859C3C76203F88AB1C64B7079B15A2A08CC81B1124DC2DD00D0178A709357F272FD5D7459647E110400F2AFB90E780F1A753BA97B917B8BBCD7CA75CE52012ACC2A8C533B468772D0A39114DDDD4459D0BBCC3E512F0128C8DA3608A368E0FF6A75F86E5F0455D731736B6976F49591EAF8A59E3A732606C7FE7388750F7E70746CB365F97F17930CEF48663BDD45F284CB99BFDBDAB50B86974304E3916C5E42A51D776ADB687944E5F2E4E03F0839E7B53B0EE253E6F3E51ABA8797C7E22061BFD71C442F1A120D82EED3EB34BAE8622F184830510A7B4540983D04A828533B86CEA53BED3EA79907596D65B1D5463ACBD778C693102818100FAF1B076026D0E21D596FAAA6880BDAAE8E2278469B64A48445ACE4BA96F3FD0B16F5B9108EA2E5DD7BAF450CAD9585F7A064339E49DA189A02311BC20D9F1115D40E97D04660DDBEA929B009A37AFC1C7B23B37B6F6A3D8B1C8874810AC82170D95AC3709F20AA5F5C2CA3E83992944B1051DB7833BBB3AF18B4FE1B09AE3B102818100D7B03E7019FC0874A13CD285A226549516D9F0127EB9FEB6563BC1F458BB5DBE34472B706520AEC9CFC46B0A9BF1FAE58427C720425413F14439F3799649E1535232DCB3894BDC7325EFC5A457A138FB923A5CE4101D7D1AFA850B9FCAD06AFD8B9DEAFB30B624C08BD4C788BB005809CBC4CF8BF018C857CDEE2F150E996CC302818100CFB0F32C688B9BF3B2D477784C6FA90AE81E2D38B149772762B389242402785DA04D1B0AE9C6F043290689A8C88AA452B92AAFBF1D90BD1EABD3FA9CAACFD66E59B11CCE24B2D66B9A346667543C1C921456561EA1A6762B25D162EDE926EDB068C4E4B8D4D967A8BDC3CF2178476E5974ED581007648B6C987785D0B41B2DB102818100BD3A61BD05FF090811C183CD3BF236F8CA20903019C0624864256F474965B09BC3CFC0BB8DED7B8B90DD792FC89B268CA04229C012912321E3C297EA4F41280F6AA936D9C895A6A5DB5D9DDF4E0623310B1C6B0CA75AC7BC98978B1838DE5B4F70632E9A0C2570DF008EC0342423EC19440DBA2CC28B6B912519577338E8BFF30281807BE0CD9D3DF5B13FF298BB24DC8B43CD044D77E9C1FF84FC568E50A311FE95264C6958592D4ED8DCDD0F40858D14E359D9046DE2A0543D9F3998D3DCBCD6D793AE0C5C21EE1BF5CD541E823582479D841601B9E4CC586388A05D4302161DA58EB08BCD71E7BD1059F493287521120F1405BFDDCD77A5EE9A1597CFD466DE2F3A + +# --- ML-DSA-44-Ed25519-SHA512 --- +KeyGen = ML-DSA-44-Ed25519-SHA512 +KeyName = keygen_MLDSA44_Ed25519_SHA512 +Ctrl = hexpriv:01D8DF59152D8A44E39A25E6775EF18A0044B20E58C2C4346AC37C27D152176C5BEA6C2454617BFB48479EB8B13B711A98116B73F7ECAC30FAF1DD9B4FA17D68 +CtrlOut = hexpub:165A6569022056E604034E2737D557C8C58AE170E14619DA19A58EE85AA80AD883AF9ACBF3DA261054887FCD755F16DB1E928127344EA81A8A7DB3E0B2B31166305D1DE467E4E8B8A4AEDBB217630645E6EF20AA3DF302E743E4CCA2390854ECC35DE2900E14989B81BA94B15C3CE111C8472C2C9BA503C176BFBE4EBE0D2A1D1C11A0E2F461650DDCCBB033FFD5DF43875379EEB1CE08F2E2FFBB639AA3D8AC2CC5B291000DB0642817F03603D16A3CCC97C167401F2A41F3332B9B623BA8CA11BF9F7740B9521C0E61EE0D5CB6B3A6A1ADB15F36674202D43AD0BC75CDBDE3F21D3FE138049841028CEC3F0C512B3DE7850564F605AAF42B875272465FBCEDC162A1018E8DF9F7B6DDAE858A4CAB3C91C9E6B2C23C2AF2DC890B86401AE4D37C3A97AFBE9076F4C1E25297E36965832208741C1CE03063BA0598122551FCFC469B3C3220148CF4F8173C05BE8A37C4932A9AC97D1C3D04456AA8BA24AC61834896003193B2C10AF287D9C33E0DEF5D5CA3B2D1352A9F71115BF904FDBF7680412FD566CC724F26CB1CBA40083B2AF6A0C272D7B01C4299A556B33854644D995322CA7F60177D6AF3131562206B14639EE2A268BA4C7A4D07971F4176F49033D6FBCC5948306C35D47041B60FD1DB651F2BEC76CCDA9265E4B764DE9FCA57EE9B66009BB22B3739F871AAFC83AE037D0E803191DE3CAE1EAA5E5DE67F224A1440153460F231AFEA991A40133539A3DC58C6DAD5E0E270DE69C82698830AE1632DB254DDEE4CE178FD9D69C59F174370F1EB3900EFD7F83FB74D86319D6279411F5C009F04DD19E3F87A9937685DE347F2498D1C743317AF2C460A3770EB484E7CD0A59398610C33D51070FCFDB09FFE560364811286457870D34D6AF2F033121AE22FC9859D984168236F1936DC90F4C7E2B8B7A961DB883A73B738EA2A0EFF6E665F950ECDEF2DDE5FCC16499D20D1887D28326AC2C21CEE66A80F6D0BC50442AF6750649F2634E8ECAFE3689C20CF040E2EB29F62D7A594D5B07045BF35A7E2BA316ADAC7EC06FA6D9E067FE7FED917058632D6BD1F05F8938B315063A6E76B41D2CD7A87930C260D8736D191A8EFB244E1B0656A0285435D96EF86D27BB1F03F6F03C6DBD6296E7A22CEA532EA9956483C190316E08CF7857F522817BAFEDC34E8F7A03C36E9FD17C5031CEAF6F71BE4553D92C84C767BD3018E88ECE8E054647C157378899011CD4E7E04141AE106E59310D4CA23CB4A3492017DE82A45A6BBD4BD2F19AB86C1E077628EA9B64BD7D12866BC7E790CAC79A2E30EE179EBD0DAE95D77DCDA9E8F8E823D364DA7AA23C0D4808CF6366A2D43D2167C190A5369E4D146255C154A6CE141D10AC51B0524C2E5124B5681AA8F478E4408626F8C69EC31A529FEECD63F3C647D4E80EC3FAC86C532CC8A490B0A2A6236D81A37156DA254BFD2A0F18E283BA931026FA25922795A8AD038D4C6C7C32DFFD5A64ACCE9F1F71488B0E83CFBBD2CF709F5084348037D08BFC34F165823FBD3A547783C17D6BB1C02F9F609CEBFAB74DB3FD6CC62812F4B4E29E4B3C6787B6F5FF3D5C9FBFD24DA806EB4559ADB9301DD6B42188F3472B9247E5F7B079B97134EB25B8D1F9889DAD1FBD11FF72DC6CBEA38874BD0DFA31CC73E75F76AB5A9545D596786998AF78F00E5FC07D27BCDBC5D861754D5E50D16DFAC12E1B203A56C4EC1DFF1F65E5E96CFC32D4E051326362277C06F95402EE0B933239E1B3B9258EE5A5859D4C96C9C6AE85FBCB9D71DA5EFCAF79EDC225E4A727E93818837B34C73EEF2460C3642DA6567A8E1BCA0474E120FBE469A3C24606017292BCBD9732A4FC8823BCC1046B2A778878182640AA23A258F9110950218A6D0B31E3AB4915568BADE5A +CtrlOut = hexpriv:01D8DF59152D8A44E39A25E6775EF18A0044B20E58C2C4346AC37C27D152176C5BEA6C2454617BFB48479EB8B13B711A98116B73F7ECAC30FAF1DD9B4FA17D68 + +# --- ML-DSA-44-ECDSA-P256-SHA256 --- +KeyGen = ML-DSA-44-ECDSA-P256-SHA256 +KeyName = keygen_MLDSA44_ECDSA_P256_SHA256 +Ctrl = hexpriv:C73679C3FE307C7AA1EA2FBD47E401434005B2D35A5A2734CF641EA2A9CBDEC530310201010420B94E7609A7176ABAFBD4A34FABAE42B091E44D9E46E67FCA566C2A188A63C65FA00A06082A8648CE3D030107 +CtrlOut = hexpub:D2D4B1C579468AF6E97E40F3FEF407CB6C1783F5E38A85F168A112383DD346C7048D4DC5210217ACF9E60B2C6290A7C17AE793F6DA7401D33BBB784FFBD80AF99EF51AEC03E7D860510D3E004BD5D646B2F3D6F6D74E2904FA1B06E92372ACA7E1739E2E200E383A26CC19023DA36E3656699ED0D8E26A98252CCF033B6A94E8F0B12ADF59EAB01C0AAF08D69001FA67BC4FB91B5674704E284150F98DE1937C1681E93740AB75E42291123014E6ED8066C971B7A0BED2B39B233250A0E40F0A5CF66C837E9FCC0CFCC4C8D9BB0595ECFC39603E5282EE4ADB6423B2DF8AC1AC7B8117332941EA2CA2D47F0A62B8A90F7394B6CC0691C22E8DDEC8CACCA4337B1D1FBE35F74964277C019E7A841442167FFBC508F3F19346EEE8870842467FD19387C49ACDEDEB6A8566CBE9A8FB4657589AC08F0CFE3247F5545E4B4AB610F443CEBF187D7B9717B280FFA121ACEF737476EF1ED3D176C1A71B02FE0DC83A39E3D892F74F9E6EC9F8FCC5E6A49FC361D12764D126130AB66F22F12B2FBD9495348855A4CA743B060222CCC713EDEC1F36102244A091BFA95F9FB01A85257E2340388937C1ADD7F396535D9AD2EA9BE6074C8177967CAC5C3573C3586070B5811EF6278A79CA0821C25EC4959F867BB1E73359EB3C79BF9717BB7C0D6343704D00387418D86209E77DB9679C312C2366521E1E4C1B0B2D7141E27478E3D45847FFF9A1A120E10F5130BDB501C140893DE38C5B398636651C453F4C22246B81680D92D40FD5320DC93989B4681F69AE7A971602EC128D6D78DF80BFE7CF8219DAA596703C51C061D43A308B6F287ED9C1E82B86CB597623ACFFA4955A70EB60C08E59454E813211967A06D600A5C374C68C8383087A0FCD2FEE35E49B4D520F90A8085CA0EB39F9B46381751B305105448FF2C4670717FBDBF453C064FDDEC84C0C6DFA1A6AD2B858A35DBC5C8B46170AB3EB1EE6B0CB7390938AA96EBCA7970AAAF0D65429DF948D7B1A860FE3962C5E6ADDC8E2FF22F2F61D5782B9569687214886D207E48253AFE6FAE8C41C902D8B7ACF73B8E3D9B3B3D933772170680A54486A7C984BF61FEDA914937422D2FD20781B82FAE766A8A628A7EEE5F84B1D9BD5D6BCD0FFA1400A592A1B6CE493FE50F8ED206EB76BFC4C187BC2468E4A8E34CEA54796320C6E60FF677B5C805266CEB9844493CEA3C92FB4F3C190415037F9C7DDBEF60694206633EB92508D3FA5564AC01B05506BBC316241FB70D9ADD2CD5EA6B9D3DD9A238B7CD36E737EF910326EC1BE1F0AD2101FCE3AB00D551F215E6098385B17F16789D43A78D1BD198AAA8FC3B6C03604FC26EA925CAD3B3420944C556492B0936974C8E73580430CD09C576013061E2179F6CAEA6735D2CEF17293E1E48BC27EFDD8D1BE031891D1154526551679DDF9FCF322D56421FA28E8F86BE6DABE781499F9DE1DBB905CD1A6FD9BC13BBF2B4711366A1D9AF36757723ECDAFA3B6CC1AC69BAD0E400F4A39DAC50033502D1281B92B3C2C5EC4A24F30B3AD83F4DF028C78CE22999BB5789C726E1EE048619AE2A1FFB517F9D901B90E733274D483BBC069D86DA5F4EC9E8498DC6FAE6B5E86DF48DF2669461EFD867E690AA5DFB27B807CD3C7C2E733E143EF8ABEE7CF75F6F85B640516EF6601E8C9AFD73E4DF913014AAA9938B11B5DE529EB0164E0E5C6FD3DC1F2AE83E9F697E14320078C7FB5EE5F8ADBF515811F0450B10DE1515C8381D4C17DE21738010559441E8BF5C55766B18BE922EE2D8F9030E1948C35F954A21A41E3D86E929B76AFC9AA034A3BC4B805567DD27FC858ABF4A96B161066C2C7D6DF762074341ABE6CD304CAF258B19DB3284BAC11B0407AE7E23C3814981FAFE126E67D1C983251820A58174157A8EDD5AD789D77F750BB1DB055D257619C041F49A9D47CE43A22D48DB4 +CtrlOut = hexpriv:C73679C3FE307C7AA1EA2FBD47E401434005B2D35A5A2734CF641EA2A9CBDEC530310201010420B94E7609A7176ABAFBD4A34FABAE42B091E44D9E46E67FCA566C2A188A63C65FA00A06082A8648CE3D030107 + +# --- ML-DSA-65-RSA3072-PSS-SHA512 --- +KeyGen = ML-DSA-65-RSA3072-PSS-SHA512 +KeyName = keygen_MLDSA65_RSA3072_PSS_SHA512 +Ctrl = hexpriv:01C4D64F4BC0A3956D1D30669B85558D5C197C9191D50DCFC11E5522492E0271308206E20201000282018100B7020EE94951CD84FF89399830948369E0B2AD71F5541F79FFC85A28ED677A9BD3DB063E5EBFAFE391FFAC02D96710C765034398F765872BAA52DEF751698914E350704AAEC20F2DC4F113978E9473CB1D79D4CA567201CA06FC69EC852AA469C229269E6D0673B1F2BE7FBA2B91EEEE5FDBFAEA6410BEFFD20A357CADFAB218E837869C78C785A5DD2EFA23AFFD0BA269C739149C707F19B6E8E6E4BB534932AA1D6BD0AA45A522B9B212B4A7D5ABCBB8BD81922E929A8073BA20C58799F104BE2169B2DE89CD95F138FB7B7284C735E014BD0CB1B30DC2A327DF832F0DBF236F5AA40F5C57F0BEAE4F6C98A86AB8605C970C3D87106493A9059F4B9E862CA1F2E7F4C454FAD6159673665A280BA1E92FF0061AD252FF37A783DE39CBF68EAFC2C92BD34AB35A39F517ADBA3BF38B7269553C683A3B43B8BAF6E1FC82458CEAD42F113F93B140BAAA54C5008B6D719A36DC867D8C8DC9BFAF5A4CD7B0CD59C9FC48508ED86EE359175F4D7B357C9C39767827E9739AF77360940EA422C24B3B02030100010282018025111BA8109BAAFED72B1A29431DB1884E64A250C499E74E348A8608681D5F6E1478F648C7B41792064E3CAECF0DDB0E27DD8361862A60386DE51F1804BB55728FA0093E772B031C0819B4182C5ED11D40B91E6A651BEE54D71964F2ECFDF8131BAA6E12048F1BFBDCE8CCC20E751E69D5AC9EA3BEE4CD6ACF4616134CC1CC34D343FBD5D178C80F123FA3967ADCCBF077704C956A2236FC245A03FA2C1EF0627CA63CE224BABA79D016CB471FFF5D2E841A8E15E7ACF5F2327E6E88D3B0506A87C412D6EF837BA08218421DBC8EDB79EB8F98182BC114A04926DD8E9DBA906593DE4226AD7A0ECB9FA65624895804BFFC87F2D24ECBE94F431639B2DD519FDA00094EBB523E7B9F3DF2257D0B00FF065A3475DED62A0F7D8493AD48773BE9E00EC72F23149D34B5F40774E3150EABB7A9751D866AED1F00F58560F424DB69931B92EAA2511539EF18AD64B39B8BB8B113BDC7A0E77D4C10CCCAA93979D7E4B28679A1341B8E30EC9A883FF51943F3783DD2380086D1595E9A66F75A2E30CEA10281C100E019EB2E335EB3876F2D6FFF68CDE6698E8621CB81E678E8D8B1EF84C72A8F3C4F2B02BFD2F4799DFC9DB252805618035E1E4FD88CA3B02C315731C4A2CE6F278D89DC01FAB4C8F02FDCCFAAC8087630A3DDBC0D1F0B2C09FF647465F05720FB335426345454E9E2F059AA0F6B4494A669B40416D973C757907C8A752E1FEC7E8A1C7A70448BDB9405D653F5BE2EF469610846841477AB581AAB7786FE44E6C00D074A0B79EE12CE35B1C4599AED3714612EA70C67070316A90E88FA56769DC90281C100D10EBBE7A2FBACDC4B06F36589A5226E9BA99CFEB12ED0EB44A22A5CD7CCB28AD194887DB6CFCECEA4C60533B0CE6C999A9C637B5B6D96FD6D29436CB24494CAD1EBE8EB10C2864E1046D5574E7626FD3833759D4D47A3830D94E7C2E05C1981041CC58C602A57705887FF111BB5C6BAED5ED1B9EFE3913EC9D9734F35EA556E00BF58F4A6E7C6CEE159BBBC753C8E4D19953C69A706327FA20A042D585D5ABB0870346B21AB8111D0CE3C27A2CB523DB49E220A3D41FC769074F0E8ADBA52E30281C00A4AE6744EC3B0B72DB2068CD281726DB2B0126948640F75924E49D3ED59D50E4E0C89A9C9C494B95EDAD74FD6B91D8D3A0B665B69CA32D334C8EE6E3B9403A2EB6B43818BC435DE6234600D55F69D870A5FAABD678999D233BAA765EF2DF143D84DAB1B882C0639F814062D831DB93E1368C32F517971D461BC76977F30D429D3AA0F2D8CD867935AD9472DE8383BDD83296023BCD4EA37B7B1DC6184D82148FCD032E4680B392DE36570C134CE6453394B6D3CB296ADDBA2941A52751A29910281C05FF8C99E6F1DE69F42FA2FE69F27E604AD05528341C7E234FF4F0AEF9049F274F3FDA223443766134B6574A1E43AFF740C9C5AB718A3D8BB02CFFC99FBC4AC21E7F8CAF68EBD1E76DBD608BE89D087D99B61544F205910E16AECBEF0A19AE6426A26E331AC3C03E419606561EF3CA5BCCE97C6E3FB12976D21B0E7D4A745AA6E537D8452DC046F2A2E1DC9A79C926E294AE34DD69ACCA7861C5748CFA04F4B05ADBC04F46182A040138179F0203602CD3D0B9348EC124CDA093B06156B1BAC4D0281C04FBB3F04EFD3293EBD8D4FC7B8F446D78ADADA6E7DC735E80CBE61BE1BCCF65CCD6F404C48C8E43F785748EFC689D0ED7492E1BFD14FA9CBF1B2A668CF014AC64087FEC7DC7F5A01999624727F07255AB0B0CB60987B1473DD45814E92BADB0D28008E59E739063052CF16812F7DE3CFF8BC1BA561D83374C18140CF89232EA0F401CBCC502FFD27BB9176D9548BEA152915D9C85510FCDCAD4A1037E35338B8C973A7FBF559A26020D27D20B87B96B2A2266DB751916DC2DD4C52CF43F8A57C +CtrlOut = hexpub:843A239B195FAC960DB9A763AFA1F3E4E4C517862669E21A0827F5993E888DAA063E1D3665E0F3E5CC5798ED57423343F50948E5B6155934E005F179AF335EB1B97A185B65F6375FD12046F3BBBEB9E34EC4D1196ACC65CEA7E97CAF8370B7F771CFF2539A706C86B28BB91A4262F3BC1FF95DFA013E466D60A4BAAA7C237BC48D8F763DCB7F6C917C5DF6D84DAF208DB9B1F7B08D822B68A7465E577247D5A8BBCF5004A136E7E2C7F68D6C79ED8A0B2BA248C1463D00A65251127C7AD4615C4D75D629A56A15ECD90AD73DEFD6F6B01404AD5804E3845DA829FE8DF3B95054607CA22CDCCDEA6FA800DDB57C885525F1FE1100C25404A591CCFCF640C2415527B61940672AD0DF58791E1291EC6332176DAD4A49260F3FA3D47A8139095892922EBFA73EE7DD281E58A4FA236AD530E10AC693DFE383AE22D752546FFB15DD068ED71C5E2C57F371F1BDA9D30DAF83959477B394DC03CE98F054C9C48792ACAE378322179527F2E2C85168A802FCCB5D2277012158B69E792E3CA5E6F3ABD1B427B9A8ADDB50C4C8E3B38408EFD12A04C11A543FE32BABB81867B805EE822A8B4B08B1393B035681C2E45BB841FCDB767D69955080534FBC5AB35E1B0E19F84E46E6365713A7815F27C16BA8EE8884569EEEB3785873488C82D063F20C22C3B54473986E944D50FC1295680335FA30C1304E32B1F29325ED785658F41AD4B5C764B2A734CF3D04A63A45ED370DA7B30293B049695CED8564ED862AD5FEA92B47C50891350F8E477D79ACF3CC125D121E57C5728689FF9532572F13F27F9B220D7D006CBB3CC71E2A1DE6030E03F8653C064B997B7363AAF190F1C2D0487EE07283150BF018582DD582C6F8621EE227FCFD45C43FCB646FEE0D71140A2159EBA4DF59B6F34321E7A06197AB08B51F0FC2B62EF07534C203968DF3D10DF8D6DE81F7F394619A606E025759F4716595FFF3EF8999BAA21C93742A7841900B8AB3CB91BE1885A7A5A353C653BD511833B1927633CA4B5E2A5938F1B0096D63D9EB21959FDFEABD563879EC7087DF1DE38643CFE1D45F0C8A303692196545C271AD42F1D886BA27C87FC8A8F6E5BE006F5440827652600C4F1B0894F2E3BEBFC2C98B0167C582A28F339C4DC0F35CC7AF606C5EE2B819EEB3B9974D42D32FC7065DD51C883F0BC3721D0B31998FF8ED630866DAF64F3687D3F677C32748698B072CFEDDCB8821FDAC1693EC5B7D7898CE45EF18C8DCF84AADA28F84F4187D9F0A47ADCE81031D9E574FB38D726F9546AF58E4AC98B6E72CECF9FEA7FB53619AE91A4BF169834A712F84B062F7E98FADAFEE90B8F6DECA21C9045DC5434D81FB84817C59CBAB1C981348EED073E0B5A57746D86FDA10E62602749ACD025E3D83DF167B4A2A73B67F5A793A07413C261ABBEE36A189C301800C8396CC7D1BF0A85BF0617181ED9C1ABBEECDDA36B9C9EC70E2B4AFAD6F4D2FF6AE1908EF94A478C8BB91B419629A411EE504AFEFCDBE72937657BA49962EAB9F33BA570113811C95B6E625AF7AB90B147C03C96D2583E494BD720DC8B19693383F44CF4D9F24FD50D03DB0E0FB0CF06E54C28F000DDE228BDDEAAF8F6F55CF8DE5636EEEB9714FEB22CE0BC73DFCF5BB94F8B08A1D8F2BF95C1478E8C378716780030960FB3C0B695F7E776207F2976F458F82FFA6E37D2BA973B68DE0008BC8758323F5535B66810DAD474FE7410FAF56833601CC8D017E10A85305822B80A70AFAB726A366482BDE7CCD33C8639A8D45152C98BFE4B8C815B63F86C8C83DB03F37439038BDD49FB8B84CA1B4A232EA71DB74FFF1F7B6B2CFD788472497203F32FDEE8C5B1830A00D7B1CCFCCD9A0FF084CF080E2C141545743A62875C308346BF48F5C4573BB631255A2E124AE80D9D94FF962856FCAB74F5C25916CBE82BA6885495B279B81F36CA5F8B4E8BA8EDCA49296AD5C5E3BDD1C06B46ED7DB0415AE757068D39F85232585D89407F2F962C29F9125DCE36A69D4743D1336A25DBFFDA046086A5B5F0C473EE8A26E790788A6352234BC0E95A3D0862EE29AAAA58B2BA5B584E7CDDDCDE507D044748A7695FBB4ECFA2B0F7A47F385B6E02A68665B7865D034E3F176D8D7864D2E2D502AC6292FDEC415CB8E2A3B5F95C71B66BAF2E5D2FB5A1453E6457A192E0B4B9A68FBAACF592673952E1453596EDED2D4DA6043F6CB3A74171E4F45A7BD040ED9FAF11D27CE00B862E207251364B47D9AB9297792210E96A775917E7A362BEDBA39FFDA5922A9F4FE550B64026179A50411D461FC4B2EA6FED28311DB35896546829A020BC433305D41D78386AC3FEFE535A4661D2961728AAC8A7C5D3783CAA9D47D331FE610C329A02CC26E65AC3B30DEDAB4B8739A0F77D18C1A504C71556013BE4B0844ECE0B5A830DE9254E091ABA8449D29C8F1351022F493A3CF2C6A5386CE0CCA878FC0F9193C4B57C47BC1706C8FE0430632728D2BA101B3DDF01E459E55BA1A437FBB3451C0FF8EB7AE023287EAB688C580F658A588A20B6C1425A66D68B3064348ABE330D6487CEC36604587A49243FA5C6C4F4368D63459C0EDAAFE7633C0F494F595FAB249EFEFCC61B6ECCD714E7C3B58CE39E79741E9E72C2F63514334ED8D1C4194C966A005BBD6A2EE6497FD4B185E0790E84AE6FC99BE0E473DF082F7340D0B5A40C679761CCD1FB570E93E5F4BD9BD8DE7F59A7FEA5E815A26C1E04F7DD1B24D8EB5429184A20D6FAD90123612ED5C585E1D3082018A0282018100B7020EE94951CD84FF89399830948369E0B2AD71F5541F79FFC85A28ED677A9BD3DB063E5EBFAFE391FFAC02D96710C765034398F765872BAA52DEF751698914E350704AAEC20F2DC4F113978E9473CB1D79D4CA567201CA06FC69EC852AA469C229269E6D0673B1F2BE7FBA2B91EEEE5FDBFAEA6410BEFFD20A357CADFAB218E837869C78C785A5DD2EFA23AFFD0BA269C739149C707F19B6E8E6E4BB534932AA1D6BD0AA45A522B9B212B4A7D5ABCBB8BD81922E929A8073BA20C58799F104BE2169B2DE89CD95F138FB7B7284C735E014BD0CB1B30DC2A327DF832F0DBF236F5AA40F5C57F0BEAE4F6C98A86AB8605C970C3D87106493A9059F4B9E862CA1F2E7F4C454FAD6159673665A280BA1E92FF0061AD252FF37A783DE39CBF68EAFC2C92BD34AB35A39F517ADBA3BF38B7269553C683A3B43B8BAF6E1FC82458CEAD42F113F93B140BAAA54C5008B6D719A36DC867D8C8DC9BFAF5A4CD7B0CD59C9FC48508ED86EE359175F4D7B357C9C39767827E9739AF77360940EA422C24B3B0203010001 +CtrlOut = hexpriv:01C4D64F4BC0A3956D1D30669B85558D5C197C9191D50DCFC11E5522492E0271308206E20201000282018100B7020EE94951CD84FF89399830948369E0B2AD71F5541F79FFC85A28ED677A9BD3DB063E5EBFAFE391FFAC02D96710C765034398F765872BAA52DEF751698914E350704AAEC20F2DC4F113978E9473CB1D79D4CA567201CA06FC69EC852AA469C229269E6D0673B1F2BE7FBA2B91EEEE5FDBFAEA6410BEFFD20A357CADFAB218E837869C78C785A5DD2EFA23AFFD0BA269C739149C707F19B6E8E6E4BB534932AA1D6BD0AA45A522B9B212B4A7D5ABCBB8BD81922E929A8073BA20C58799F104BE2169B2DE89CD95F138FB7B7284C735E014BD0CB1B30DC2A327DF832F0DBF236F5AA40F5C57F0BEAE4F6C98A86AB8605C970C3D87106493A9059F4B9E862CA1F2E7F4C454FAD6159673665A280BA1E92FF0061AD252FF37A783DE39CBF68EAFC2C92BD34AB35A39F517ADBA3BF38B7269553C683A3B43B8BAF6E1FC82458CEAD42F113F93B140BAAA54C5008B6D719A36DC867D8C8DC9BFAF5A4CD7B0CD59C9FC48508ED86EE359175F4D7B357C9C39767827E9739AF77360940EA422C24B3B02030100010282018025111BA8109BAAFED72B1A29431DB1884E64A250C499E74E348A8608681D5F6E1478F648C7B41792064E3CAECF0DDB0E27DD8361862A60386DE51F1804BB55728FA0093E772B031C0819B4182C5ED11D40B91E6A651BEE54D71964F2ECFDF8131BAA6E12048F1BFBDCE8CCC20E751E69D5AC9EA3BEE4CD6ACF4616134CC1CC34D343FBD5D178C80F123FA3967ADCCBF077704C956A2236FC245A03FA2C1EF0627CA63CE224BABA79D016CB471FFF5D2E841A8E15E7ACF5F2327E6E88D3B0506A87C412D6EF837BA08218421DBC8EDB79EB8F98182BC114A04926DD8E9DBA906593DE4226AD7A0ECB9FA65624895804BFFC87F2D24ECBE94F431639B2DD519FDA00094EBB523E7B9F3DF2257D0B00FF065A3475DED62A0F7D8493AD48773BE9E00EC72F23149D34B5F40774E3150EABB7A9751D866AED1F00F58560F424DB69931B92EAA2511539EF18AD64B39B8BB8B113BDC7A0E77D4C10CCCAA93979D7E4B28679A1341B8E30EC9A883FF51943F3783DD2380086D1595E9A66F75A2E30CEA10281C100E019EB2E335EB3876F2D6FFF68CDE6698E8621CB81E678E8D8B1EF84C72A8F3C4F2B02BFD2F4799DFC9DB252805618035E1E4FD88CA3B02C315731C4A2CE6F278D89DC01FAB4C8F02FDCCFAAC8087630A3DDBC0D1F0B2C09FF647465F05720FB335426345454E9E2F059AA0F6B4494A669B40416D973C757907C8A752E1FEC7E8A1C7A70448BDB9405D653F5BE2EF469610846841477AB581AAB7786FE44E6C00D074A0B79EE12CE35B1C4599AED3714612EA70C67070316A90E88FA56769DC90281C100D10EBBE7A2FBACDC4B06F36589A5226E9BA99CFEB12ED0EB44A22A5CD7CCB28AD194887DB6CFCECEA4C60533B0CE6C999A9C637B5B6D96FD6D29436CB24494CAD1EBE8EB10C2864E1046D5574E7626FD3833759D4D47A3830D94E7C2E05C1981041CC58C602A57705887FF111BB5C6BAED5ED1B9EFE3913EC9D9734F35EA556E00BF58F4A6E7C6CEE159BBBC753C8E4D19953C69A706327FA20A042D585D5ABB0870346B21AB8111D0CE3C27A2CB523DB49E220A3D41FC769074F0E8ADBA52E30281C00A4AE6744EC3B0B72DB2068CD281726DB2B0126948640F75924E49D3ED59D50E4E0C89A9C9C494B95EDAD74FD6B91D8D3A0B665B69CA32D334C8EE6E3B9403A2EB6B43818BC435DE6234600D55F69D870A5FAABD678999D233BAA765EF2DF143D84DAB1B882C0639F814062D831DB93E1368C32F517971D461BC76977F30D429D3AA0F2D8CD867935AD9472DE8383BDD83296023BCD4EA37B7B1DC6184D82148FCD032E4680B392DE36570C134CE6453394B6D3CB296ADDBA2941A52751A29910281C05FF8C99E6F1DE69F42FA2FE69F27E604AD05528341C7E234FF4F0AEF9049F274F3FDA223443766134B6574A1E43AFF740C9C5AB718A3D8BB02CFFC99FBC4AC21E7F8CAF68EBD1E76DBD608BE89D087D99B61544F205910E16AECBEF0A19AE6426A26E331AC3C03E419606561EF3CA5BCCE97C6E3FB12976D21B0E7D4A745AA6E537D8452DC046F2A2E1DC9A79C926E294AE34DD69ACCA7861C5748CFA04F4B05ADBC04F46182A040138179F0203602CD3D0B9348EC124CDA093B06156B1BAC4D0281C04FBB3F04EFD3293EBD8D4FC7B8F446D78ADADA6E7DC735E80CBE61BE1BCCF65CCD6F404C48C8E43F785748EFC689D0ED7492E1BFD14FA9CBF1B2A668CF014AC64087FEC7DC7F5A01999624727F07255AB0B0CB60987B1473DD45814E92BADB0D28008E59E739063052CF16812F7DE3CFF8BC1BA561D83374C18140CF89232EA0F401CBCC502FFD27BB9176D9548BEA152915D9C85510FCDCAD4A1037E35338B8C973A7FBF559A26020D27D20B87B96B2A2266DB751916DC2DD4C52CF43F8A57C + +# --- ML-DSA-65-RSA3072-PKCS15-SHA512 --- +KeyGen = ML-DSA-65-RSA3072-PKCS15-SHA512 +KeyName = keygen_MLDSA65_RSA3072_PKCS15_SHA512 +Ctrl = hexpriv:B65E5BA11EB7A95AE888D146E2282BBFE2F61C1C0713E3652452E58106D41763308206E402010002820181008E392CE848552ADC9347048BE9F11C049C53288DA1B5180EEDCCA9CA5D4565DF947BB674ABFADAFA03D5E7AF5AA6DC70DCE2C56FFCA60E9DEACE5E9C79304DAA21B53628F2F28E1F184DB6F26AE2ABDEA2F37280B2FA0A082ED6CA9D040154D33FA53F73D85E3C774F748847C59CCA86CB510AC127790E9A296565FC62EFFD06D90D371803B727D0B1E713D977DD9BE125DD6761885FCA48961A63BE0CA80CD42414013756B2E67BCCC4333D1CDA364DCDCC35A864F0F0E3A7E91FF942C34F77B1C53C9F1A3034C20B497E9C32E6398D6D276D6566AA729BD82429890E0859F3F7441600C17C3B45FBC1ABCA31A5B86D5EDBC64BE3EA2CC2703F4E38C53AF5AD467C3BB93219186ECFE0DA31EF5539A25423DA4BA860A6D1E694BEC9D46F640D4ED98AEA9B88DD94A0A7FF25BC88CF3A7EE85F61570015C9F237B5EBA5C10A6DF8DE1170E6EB414AD6FD80EB94DF002E0632C7CC45DB8536C153C33528444D944233F19429F55FC41C9C86002E8B89EDE19311C2A1598DCC03EAE5B96AFBACB902030100010282018021EF2874DFD55A5DB8D248166E2236522F4E742D9EF8CB9DBC4589F99BD9941E0D9A9B052987B839D132778E526DDFC91A1B0D8AD3D877425CA512D3F8E27A956E67835DAFE209E107767B8149D97DB2A864B7DC5757EB8EDA462B9FDD35C81C8362154AB9C47A5EE9595FAEE84AA9D411ACEB88FCB718B1D5D0B8CDC8798480DEC7156F286BCA17346B7343FF22A42FCB4E117DA7015C0D87AB12436557AF7FEA7FCF6E79C443D4241E682F5BB40122FD488D40F99CB78D4A22089BFBBF0835A6E9913C9559758320B4D8E3D8819B95BDB7864C1F8AFD83C058E53F482795688E08D679184CE16D1151F1C947D9E64BB2ECBFC272647D5761F35BC11F5B8A99E03AE5C0522162EFE0D164712806CDDDA0EA0B7ACE3C9C0C479FA7FC0EDF5D1AF005BC353CFB22BC7B41F1F32EA28789763144A813864F67FEEF8852EE41FD3B0F3647B5C92145FE0FC282A9EBF27CB87A9C4BAE9442880365D9AE9E15E13CEA2CF937D712FF0546DA3D1472358497488F65B0F428C5C279906895708B0D33D10281C100BEF37B65EFD7508D0521327BD87A1A7CE7A2AD36B5E8617F461F6EBEFC3A2E53B214AC3C075C766EA411C441131EAC31B8AD0DE788FB32E68C6D3D9AA99ACCBACF415D52371856E0906C84BBF84C162A5915BBED81C07164C6B4BE8364EA079E3875E641F88EB05256DAF6BF69B4659C9A2284BAC0A8656D094C1E7DE644628711BE3A22A8211C378E860ED0204D3D68D8E6A94E51065AFE0197B16E9D0D2BBB302962230C2058EB400E2707E18D43C08C30B68F4A8EF3FFC4D703A7AD6FF6650281C100BEAC3AA19F34AE1B381736531D51173356B122279EE0ED10E229926E4D16A7644B623063415A3C5A7B5809890F4864558FBF0E528A6532CD05176F7B6E7013E72C16BCC162ABEF42A60CBB2F11AC3321091FA12D8C7B66AC5F69DF0BBAE3598C319A992A9B36090D36540B68F324BA5C5CFE200B276B777BCC10AF56FB70BEEF8E5A5A92175130D3141193664FD7716BD0F757D3A9685F50BC3F087F2C30B7CDAD83A57D487E98F6D445F71F094066CD887DDEF1A0EC2CAD4E6A4F71D9593DC50281C100B9F3884EBBA2D5798EEE46285EA681D6F307F3605D0360B6BDC5EC6626604E2F0933A28A8EAC9754A587FBB357783E3DE956F53C6DA41A6C73820A44EC37A8799F4D4B20BE3080A20D62F05BD0AFDFC1FBA0F3B295F19F3B815A10510A5BF1713E106A5C023E8A2C951284C9E099617E80876EF4229B9AB1F524E068C06E05F8FCE95FD9D21AF44C9209B0B13353A4A2CEDEC92F502E3D3C30B6D57E1F88ECF64C2F70B72A9EF1989E7769C0FE00406368E223562548530AD7587FE1B13F60150281C057794804B1B74750B170E4B948AFD506F6749908B838D449749841D75C8252150F0862CE8642D1816928C067229DC17A07524D4DCCB414943E0BBC57521914E86F2F9734D901ABE855A96D8E707B2191BC4FC86FCF0D25D35A8A858B2A17F712FC06C2D1EB16E51C2C9A6E099DD271B4C1ECCBE29219195DB006CF8A061C795C0960A64073760A022C28CC089A046AC25DC1BB871D2706E3511951DA95F95BB97E2AF11702D52173CB7AB59E856E083BAEACA04515E083B6964CEB597DAF15490281C1009122A88128ECFE66B0363C945F89B175AD82E832B3A61EB581D6268B60C06B097635F4487FDE6DEFFF9E15E1721A8B01C6C9823F2C04F654D785A6EDFB0C774769D35AA76DB6A1BAEF8DCE117F210E6381A927BB8469725AAEC0565CBB660D52FF949F38396F9F183DC0C4211A87C3483FA0E16527C8D61AD35861226A4E84926A03627BEF4AC7ED83D8AD60C2ADA8750C0A0CE2B77146712F73DF60E3DD45BE3B97733E8EFADA94BE86291CD8053BD389E1ABDB37B045AF59E27C07A79D9B60 +CtrlOut = hexpub:9D718A15CFB0EDDD7132ACFAA636BE80592305D71D985008C4FE62380354A01A7F3C8368603413F3E4D629B8647C514B0158C1301E514BC07FA57389B6A8AF4F346E6D9C51837ACD3D0043A94B3FDCD3EF35D5F14BAEEB6753CE2A9D3F342889936789BD8D2BC00D0B7F33693E6DCD120BC807018C2F6EDBE57C6E9CA2D9ACEC07177995198EF648A20D68AE97CCBD2D5C654AAEF9AECCD23202E5922AF29411FAA4FDC7270B247B442468E19F14546B614AC724E751126B1DA606D914FE737B9293B0DF1F24FC3593AD9B40B1A695CFD7DAC1234649F399AAF174DF042CDF3FF684FD6675966D03131B3827F83338B0CEEB209FA0BC270BAD7DBB8D344745A357C305E1ED56B4C5FAA67527F2E2EC2D970855CA5E6EDFA5D82393BF80C6704AC16AE19CA24FDFBE686656EE8901635C81362570820623F2DE0EFF60FBC8917809DCED360FD4C44D8C4230EF40F6EFF56FB246256DC0AE394424776FFD532086DC476C3863D15F212741E2244ED9563679A400DF65F4600C0F709F32ED99AE794797B86C965D5F24B457627E589EFC3F68A22A5A2261293727A8F94BF1D0DDD019DB55D0D6D1E2B41F17764042A1FEEA6B16126FC4811C793AF58AA632B9584419482F867B36CACD29E9C5A497BC4B817939627E6E1FEA7CDA210A9763279D64420CDE868D1B30A164CA58E1656C3B1E019BAFB503E2D668132870D421C806108979AC3027C548FCBA71FB742EE0EE4F1D1C9E373886FF498AC1D46995C2F6683FD3B376BD9080C1F3AD0BD53A8E42B85D4CB142D2C384968797D3368D9A92EE9E59475619B8DDA9310CC25DA44A82AEE9E88BFB72E4ABF24BAFAC246A441600DDBA3CF98CADD2863E320BB3C3F0BD7AE1490A38369E332751BCA6194ADEC164F13CBA1AC1EB96039ECB9868F0BE392B32A9B92198A5BA976D9283AC0A5E7F391E464ADD2CCAE36E7C4E1CCCF548A772A7A5095D2F1736E5C5DFC72181F8972C08013A9D37668149BC63039BB607F533CD872568789E936E52B732427FD3AA07DA70927730D23CE2AC038146850507D7AD3ED3C546C000597F7521FAFFEB99111D1C102283033C3C7927E7D6A90B65D048EB6553BF2753FB51B4A37ED0ACC03C9699A54AF9E6363A14597EA2AF04C1900A304B341B6FBA1F57BEAE40B051B35B9194FBC3655758FF08FB57F43141EAF427AB4F691A562F39994241B42887DCD6FEF2FC24A5D48121F88111637B213342A76106223C536A4B0BF683BA9E208B899C2E031D6C24488148BC2B1102943A12832130DF7F064B0A558EBA030DB058D2713B352E4AC1A6ACA99BB24FE3A0A7063517C25F659E6201A7E2858D21C487009F0C611897E82B11280057C603E7569319A172B1D672E4523094D5AB6B0D488C30B3666AD479A945BD4B82433FAEFB82A708618989A3360E191F1C284BF102FCE1CF906C967C19ED9402C388FF78BEE1102B364ED21AC4BB2F16CA2CB418054EAA1DFEFFD2C40E671423C156A6CE82D3AAFFED71DDB5029AB63B3CD059857199E808842EB91273DCC57D0AA0DC9109D4EAF2F796405E718832B28C33378C7893EEBB91B2BC0F1C6464845D4A4C101F3AE5B991BA0F3AC73EA42DD825623C3C1941794611CE61A49DC38B89A99D0609FBC0D9D859E44F7C3AA0CB88DE539516C8328F28D4BE3B7F31BA5C60A1EC4B634E4AC27EA1B7FFD376C143F80BE1D48D5D311B98B57D83D8124F48EA6335091302E9243CC5852CDCD628F8BFA4183D0195BF3C9AAD67DABDA4774397814B7475DC06697582A6E314F16325DA714804006910A922358670F6055C0C1CB7EE4EF5893E22725AD7900BCEDEC13D6AF016407C264B300834D2A5BB8E85A5839DFF103E253DFACCA1598E728E456120BF975EACCEA2D8769C3DAB89B616013655A1FC5477B2BBC8B5BA84AEB485B10BE29CD8EEE29F6197C5DC23F5715E280EBD95B15FE19DEEDF0CB96DE99FBB7114AF7F496FF1741338BCD3797B9C8F6AE9DE3E5309CC33DC95640B86FEB4BA0B769D190D7BD1EF4D087CEA1CD9F175AFCF1D4BAA60A001FED72324A71E1638550C4DD92C7B6B8332A5F3BE0331115CB92B1D9D096C466667517466521152895687FFE592C57E07585371FE2BB334C551AF3DA0653BBA6BCB1D301EB4C269C93227D647739C7F1E66CAB132E800CFE25ED3D9D9A3D90869F8D45F16621D29D13A94B078F86403635FAB995192BBA5E3969B07A662592E8D1495262BF004FC25958547688E92EB6832D92E0931FA92A63AAFAF82B2744AA3B2CD25A6DC2C1914AB4BA4ED36E396E596DD6E6AA4450C801EA86F573E78E1C079D03C52142269325095A9F819E57B572D38D7F8E3B2369FB42DE16D0104FDD1B263470D53F7AC6A76033FA52268546AA208B036B8A80E25BF2EF0ADB3B48E075E7CF58BDCF02F8175E8EE98EEA293AF0750CBEE7B09B2920EFE2F9A5BB299011F40507DFF09309C5EADC2C245107B2CD7A52E58B3E96CF75D08581EA85B62EA2C4F6AFFB9B258775F43ED859516C80CB2D4146EA8E915011A15A540B60716AFAAA1E6E0FBA70334EEE20EF1B14658C211B7B7E4F4CD1DC0C1640FFB097A03973A091FB9550EBE6A077A34F40FE889DE1492A24B58AEC908B08F116B6C133ECD9D88C7B8B9A200AF261266139F4189E94071CC530B79FBDA9417F676668F0F4449032958A35410EB122B8F16E8A6B24279E0B0B784F6323E1E6FE5F4ADD6410AAA23BA5CE6717221BE5A3770D9AA3082018A02820181008E392CE848552ADC9347048BE9F11C049C53288DA1B5180EEDCCA9CA5D4565DF947BB674ABFADAFA03D5E7AF5AA6DC70DCE2C56FFCA60E9DEACE5E9C79304DAA21B53628F2F28E1F184DB6F26AE2ABDEA2F37280B2FA0A082ED6CA9D040154D33FA53F73D85E3C774F748847C59CCA86CB510AC127790E9A296565FC62EFFD06D90D371803B727D0B1E713D977DD9BE125DD6761885FCA48961A63BE0CA80CD42414013756B2E67BCCC4333D1CDA364DCDCC35A864F0F0E3A7E91FF942C34F77B1C53C9F1A3034C20B497E9C32E6398D6D276D6566AA729BD82429890E0859F3F7441600C17C3B45FBC1ABCA31A5B86D5EDBC64BE3EA2CC2703F4E38C53AF5AD467C3BB93219186ECFE0DA31EF5539A25423DA4BA860A6D1E694BEC9D46F640D4ED98AEA9B88DD94A0A7FF25BC88CF3A7EE85F61570015C9F237B5EBA5C10A6DF8DE1170E6EB414AD6FD80EB94DF002E0632C7CC45DB8536C153C33528444D944233F19429F55FC41C9C86002E8B89EDE19311C2A1598DCC03EAE5B96AFBACB90203010001 +CtrlOut = hexpriv:B65E5BA11EB7A95AE888D146E2282BBFE2F61C1C0713E3652452E58106D41763308206E402010002820181008E392CE848552ADC9347048BE9F11C049C53288DA1B5180EEDCCA9CA5D4565DF947BB674ABFADAFA03D5E7AF5AA6DC70DCE2C56FFCA60E9DEACE5E9C79304DAA21B53628F2F28E1F184DB6F26AE2ABDEA2F37280B2FA0A082ED6CA9D040154D33FA53F73D85E3C774F748847C59CCA86CB510AC127790E9A296565FC62EFFD06D90D371803B727D0B1E713D977DD9BE125DD6761885FCA48961A63BE0CA80CD42414013756B2E67BCCC4333D1CDA364DCDCC35A864F0F0E3A7E91FF942C34F77B1C53C9F1A3034C20B497E9C32E6398D6D276D6566AA729BD82429890E0859F3F7441600C17C3B45FBC1ABCA31A5B86D5EDBC64BE3EA2CC2703F4E38C53AF5AD467C3BB93219186ECFE0DA31EF5539A25423DA4BA860A6D1E694BEC9D46F640D4ED98AEA9B88DD94A0A7FF25BC88CF3A7EE85F61570015C9F237B5EBA5C10A6DF8DE1170E6EB414AD6FD80EB94DF002E0632C7CC45DB8536C153C33528444D944233F19429F55FC41C9C86002E8B89EDE19311C2A1598DCC03EAE5B96AFBACB902030100010282018021EF2874DFD55A5DB8D248166E2236522F4E742D9EF8CB9DBC4589F99BD9941E0D9A9B052987B839D132778E526DDFC91A1B0D8AD3D877425CA512D3F8E27A956E67835DAFE209E107767B8149D97DB2A864B7DC5757EB8EDA462B9FDD35C81C8362154AB9C47A5EE9595FAEE84AA9D411ACEB88FCB718B1D5D0B8CDC8798480DEC7156F286BCA17346B7343FF22A42FCB4E117DA7015C0D87AB12436557AF7FEA7FCF6E79C443D4241E682F5BB40122FD488D40F99CB78D4A22089BFBBF0835A6E9913C9559758320B4D8E3D8819B95BDB7864C1F8AFD83C058E53F482795688E08D679184CE16D1151F1C947D9E64BB2ECBFC272647D5761F35BC11F5B8A99E03AE5C0522162EFE0D164712806CDDDA0EA0B7ACE3C9C0C479FA7FC0EDF5D1AF005BC353CFB22BC7B41F1F32EA28789763144A813864F67FEEF8852EE41FD3B0F3647B5C92145FE0FC282A9EBF27CB87A9C4BAE9442880365D9AE9E15E13CEA2CF937D712FF0546DA3D1472358497488F65B0F428C5C279906895708B0D33D10281C100BEF37B65EFD7508D0521327BD87A1A7CE7A2AD36B5E8617F461F6EBEFC3A2E53B214AC3C075C766EA411C441131EAC31B8AD0DE788FB32E68C6D3D9AA99ACCBACF415D52371856E0906C84BBF84C162A5915BBED81C07164C6B4BE8364EA079E3875E641F88EB05256DAF6BF69B4659C9A2284BAC0A8656D094C1E7DE644628711BE3A22A8211C378E860ED0204D3D68D8E6A94E51065AFE0197B16E9D0D2BBB302962230C2058EB400E2707E18D43C08C30B68F4A8EF3FFC4D703A7AD6FF6650281C100BEAC3AA19F34AE1B381736531D51173356B122279EE0ED10E229926E4D16A7644B623063415A3C5A7B5809890F4864558FBF0E528A6532CD05176F7B6E7013E72C16BCC162ABEF42A60CBB2F11AC3321091FA12D8C7B66AC5F69DF0BBAE3598C319A992A9B36090D36540B68F324BA5C5CFE200B276B777BCC10AF56FB70BEEF8E5A5A92175130D3141193664FD7716BD0F757D3A9685F50BC3F087F2C30B7CDAD83A57D487E98F6D445F71F094066CD887DDEF1A0EC2CAD4E6A4F71D9593DC50281C100B9F3884EBBA2D5798EEE46285EA681D6F307F3605D0360B6BDC5EC6626604E2F0933A28A8EAC9754A587FBB357783E3DE956F53C6DA41A6C73820A44EC37A8799F4D4B20BE3080A20D62F05BD0AFDFC1FBA0F3B295F19F3B815A10510A5BF1713E106A5C023E8A2C951284C9E099617E80876EF4229B9AB1F524E068C06E05F8FCE95FD9D21AF44C9209B0B13353A4A2CEDEC92F502E3D3C30B6D57E1F88ECF64C2F70B72A9EF1989E7769C0FE00406368E223562548530AD7587FE1B13F60150281C057794804B1B74750B170E4B948AFD506F6749908B838D449749841D75C8252150F0862CE8642D1816928C067229DC17A07524D4DCCB414943E0BBC57521914E86F2F9734D901ABE855A96D8E707B2191BC4FC86FCF0D25D35A8A858B2A17F712FC06C2D1EB16E51C2C9A6E099DD271B4C1ECCBE29219195DB006CF8A061C795C0960A64073760A022C28CC089A046AC25DC1BB871D2706E3511951DA95F95BB97E2AF11702D52173CB7AB59E856E083BAEACA04515E083B6964CEB597DAF15490281C1009122A88128ECFE66B0363C945F89B175AD82E832B3A61EB581D6268B60C06B097635F4487FDE6DEFFF9E15E1721A8B01C6C9823F2C04F654D785A6EDFB0C774769D35AA76DB6A1BAEF8DCE117F210E6381A927BB8469725AAEC0565CBB660D52FF949F38396F9F183DC0C4211A87C3483FA0E16527C8D61AD35861226A4E84926A03627BEF4AC7ED83D8AD60C2ADA8750C0A0CE2B77146712F73DF60E3DD45BE3B97733E8EFADA94BE86291CD8053BD389E1ABDB37B045AF59E27C07A79D9B60 + +# --- ML-DSA-65-RSA4096-PSS-SHA512 --- +KeyGen = ML-DSA-65-RSA4096-PSS-SHA512 +KeyName = keygen_MLDSA65_RSA4096_PSS_SHA512 +Ctrl = hexpriv:C4795A90094568A7B97CF93D6D2C0F229248EDE4959EFCE2B5D41C7C3F9D2BEC308209280201000282020100C282D5A772D2C739A825536DF6D88F645947501DEEA2AB669C0DC9199BE3071A8461A84854669CDE59C894A1ECDE833E9DF286CB5DEAF55B8FDDF382EB03D307908B2144FE1A2B0F581C6EC8870DB5CC0DCFC67A23E734C497FE71F69473E6B060AA060715386CCC5269E003C2CCCE0018DCE1C87437DFDF20587456EC451C92395EDA4E6C55F3CCFBD7CA96938706F3DF45F7A07F5D1E19900C2CCE381E70969ECA20BD25C2B475CEE9A0ED9F9FFCC58527ADF6000E1099C6797D00A5171D5C2C9FB863C1105F192AEC7C48BC6043C9C5E5FFD4B81B67382860E62E9BA3FCFB59A024368FC73DE2BD6643F016D2BB0CCF013CB13281ED6E6257DD89EC9D5E286D2508C4408EBAF5305DA36DC733816E112FD99B972EEFD1161DF31F9E1C8683C9A331CDB525AA08791AC565B15AD459691C3E08A5F1C2D00E801B7DDA9D1D5440C90D1987FB8ECE8ED0B20C27C2FD0288B9B1C243537F9C6AEBDEC0309151CBB64E55EBA5D7A5FB62AEBFFD86993AFD76A7E00C69FB042D42A684A759D827732E2222CC44C7DB88EE626891A373156E59F1D5C035A60DC8658268B0C65B846CABD97DDB00B3FA9EE3AFC5065BC30394A1CB545AC39D17E1539752EF34297A14F9E5F4A5218C4D7B7A97AFEA587C50BE1032F23F11700A7FAC554BA2CC5AC8F450EAF0BA4203FD014C05D557877C1451B0D250B555B7F8F68287FA3519F1F2CF020301000102820200492DF11509219CDBA7D3B7324173136BA51D2BDABF0BCB6194E7A8D7AE2AF962B4188BB7FEAD066AAF2BC423B19ABB9504D698790DB216B2668B921098BBBD1AF4FA2B3FAA3C0D243E39A0426871338AFC4D45F670E88D1543BBF2835B31C9C264F3C2C5CA698AA14A8653C60675883148295DF6CD26B25EDF6BF80535EA008850F64B3AC30E89657F009E530D58F9382A31C82AC59032815A8D021469CFA5FB3CED7DE8BBBAA7AB44F7E7D84EBC61DCAC2E9407DFD86ACD77FB00190C838843C3F4296ABA599EF5B88CF56B6617EF990B8FEF32C83B6317A13567947470FB7E532769486FCA7D917F4168E0FCAD36BB686C2639E26F387555A18A135886924409A90AE149A915A9CAD2657141CD94148370977841A0CE2B2615A86FE6F98C1DFDED00B66BABA4EA1D1E172478E5F00AA3C8831351D17BEF7E1BA26B32F6DAD7951C288135184AECB816358BDC77CF5776E4F62D2FB9D0FAA17F861A04F00F5CE8669AB3430BF342ADBBD53C7C689B178BD3F3272DE37F79773487BDA30E555E5D27E008F994750C7074486323C706306229B265DCD1382B094E908C6FCEA99EDE0E3DD71AC68459DEAFDB940B17DAFF30434E4C64B66B0FCAA28096F12DA4CCF6FCD139E1B9A85594C268296FFA95957390FE9CEC98B5503E9C17EC41C461E454FA7735AA37747510D63D23CAD6C088DB32F8C70D754A5D286794FD9118C6910282010100F61DCFF7210F3E6F6B117688096095BF0007A1A6EAAD3A0C3C48C9C3FE606C647E05D97CD782B9395484D4D19275BB1F049A4093AD73B272FE9EF14398F31FE00F829058A1ED414E80BE6FDFC83D1EF8743AD9282AA4ABB2DC088427E9F8BCAE79E95151C22A33C0D073F1A65DBD4CAED4218D4038FA936D481A877D16688790A574C3C2239FA315DA9C5F91EC8D5E1B8C3AE69B4F1E34A259AB801F2FC69702BF496AB3F98E7C8D20DC5DD00A8F94DF1AAD0A832476144F731D15F2DDECA9640D557157E9A0C9FC9DE644934CAAA18665F413920E123AB30242A00778A55F5F42A15C145F2C67B311FA6026F49FC28781BE00CE563161FA1790033E6B8381710282010100CA527EE81F6A8FDF3501FFB9E09E2EE278AA79A355C8EE96A9391AD3A5FDA83D5A4BB710496F0AC4AFEF365C1B17320C0A8262D5BE4B638366485F9C9A2CF57B0BA80EA1995E9B71550D986537D15F3BAE46180089B5608A715FB0BBEDED63DD4950D14549F5C76C1F5C6E39929DABD8A05C263691061DB0647882F99CC61F8D9E7BC81D1649842FD824C74F014D8DACA41C46013D31A027D26ACA485068D693A9185BD12C2A20832E48B02814AE735037612AEE5811C9F848BF5A6E75D36E7303B5AF8F9312F8EA6E3E119C09977E8313F10CC93B255A0CDC723215A0A5DB88EE226A525D136EA7EA0DB8AFE42807F9206D0EE174E09AA57C7B4E70EE5A983F0282010100EACD2E671B072C0DA81C14F55BDCE5803F4B0891F23A29B31AA066BDB1A5D4435B67C1423568E5C5283941C05EF62AFB40ACD9070AE7E24B8B579FDD59C2399ACDB1467D089F0D3B13E09B62E7EA47EDC9158BAFA25F4FDF67C44830BC2B2DF7571F9D115F285C0F8BCFD1AF62A702CD985C1A223739F804BE51710989A358124B87C66B25095BD1B1AA9612E597493D06DFFABA19153C29D75AA2F51DE35C96A66028886381E899CBCBF144558EFDFC8BBAA2D8D2A4446437F27BCA24A770439FE4F0296B1E9715869EF4B582E3170EDD9DAA3E21668AD1D54A32DA6DE377C5AE0FBB8543F75D479DD33C806DC92D119259EEF2EB905964FBADCD2A73F01641028201005C74F893A10FB4719F2AABAF48CB60C793B6EBE14D698646894C944AD61725D3EBB8A00EAC50374E8CCBB73EBE0E8A8B601E17866FF0C9A8198CC74CAC5411564A8C612B4E0822E6D6A460D91879F098385AC5CB312316DC0D555A5177383DA3B9465A6BDC9199B17A5F65EB9F69B8474578F6E986BA91C4B315335D585C5DBCFD08B9F938DF1DAE338B131DB28DBB4982B17CF841FBB4A19E11B920F4C60410F47C3231538A68D329CA83DDBD1DBF8A8FD432A73ACDDE4B3D0B5D0B0F83307D14DBE93FA6494C40ED6225EFF59E2A6D4226ACDE24CE3BE996B004DD474DA4165E24920BD386F6D17B2F0C102D26720651E024A5B9208EEB4308A25F0F3D8D47028201001C79A187C6231F0B683813DCBA666B8B15395D93CFB0D1779EC5903700FE30BDAE1BC31648C41E13E62C62FD4F454CCFC8C6D5EA3BB79D1FE4D252657DDFE0A690218D79BE32A0D5D44E9A50DACF2DB19C212B4266073A7C20A68C3C0567ECE44029521E33C4E8A1D18227F784D81924565970D1A61529F447E517304B08DED2536962E9E152C3A20D81097B90D0A21578DC2F76BF21033476DC4990439F1575707155792F3D209AAE8656BB305B1EA7895E7A49F570FC6209B33C77474713CE7BFF4AAC71D5E39C36FF42195A8CDA28D18A538E252601FADF2F373DE676D01656D7A13E743CA084EB1CDB9430BED51C36803066C99E09D86D9939F209CC8C04 +CtrlOut = hexpub:6F2F8658D2212B1267EEB8DEEF074F6A1E7AA9AC249F0FFB1F61D8EE1976ED0732E6413F374D44AA4673E8BA10341A8E2699EDDC18546F0871C6EB91464DA8718DB30DB82D6C74D15E6396397DD0E61D186C0E9893BA4E30CDE4B95C1E5F3CD1EF8CC24E8B74BB4B6F08C4642AD2F48179668115A1DEEA7BC5DCCE479968ACE38DA273E31B87D25173356736A8D9D5D445FA6903E8F002DB3656112ECB3ABF19B08B64ACE9C80B5A5B5C43A748D75EA21551B987D45D9E88B908B2050B4F7E0FA11F0B5DD6F39F4676D6D27689E2D4533282553C4C181AD8D8788C9AF9D15BF5799A613A4CBB7692FB3F905FF30DCA2DE714777EF0ADC4E466AADD6C00847C0585E3540C6329794FC9F11A55DDCA323849455E5B858F224CE1C6ED315B3607E28ABA6937190DDBE90DDE19F45334E2D12EB9A4437D07858D44082C0E4708EECE127989F92341F00D267292134912849BB66B77F5006D977D11BEE2D7EC766A4DE75C18463A6F8AE27855A3A52B6F6273D4A08AD49229B414CC81B74ABEBD33D81921508571F2A17DF4E8EBF13464EA0BB06D2F185CD1A9200FF6C66979EC89644D36914767863589E9EEF76FF51238E781E428C7B6C61FF3E41980E261CC0044CFCA1692869CD272BC913B182C85EB12855BED5BF7604FD052BBF2B3655CFE3C500937CA820B137351092E37DCE075A7AF64B858D44D98AA3FB424F77A29FA16E8A2358EDBF1FA4EAF0ECC1B6C16FE5490EB4A0DB0907D4AAAA2F1BC76C7C2C041BB9C9D6D9D4F935029165419142404E02A89E788ED3991655423626D5A120D335F802A6F5A53E2B3660A414158995D8B3668483A294A83C04FA88DD82610294E6D90E9B91F7C6C98EAD2042E0BDECEF84173E04052D4BC6570CFAD59C8F29D2A021C5CA02B9657DEA39105243E05AB4B03DAC81DC70F92A1A0F4CCC993FA541F9AA3A05EDC55BAD1C2D476200AB112809C830F2B19B396773559A4063F466DD53B9FAE5DEA9BA6A29742FD852C526B1A941945B43DB0F265173203CE5AC49D6769EC46CD9FEB129106915DBC0E48AB921AAA5555C664DAFF6AC9BEFD3B73C1466D0D4820E086F079E47FF75AC77388BB500724D2F9A27355367AD8BCCDA0E9F9C9B928D8B9BE0BC8E5C095BC5707DC57EEDAB1E2571381A0DAC93D3BA0A44197DABA2EF6FB203258CD7BE245E0BFD0ED9458F79ABAD29F5ABF84B7054B0882E15A31AC7CBA75768F3E4AD7743F54DD4036B2A6AAB35B845D85A9C0D7BED5C116F53E8F0D92F79405DE64A08FE4159D106F9A97A0021A6608D1EE380EB8BC4BC65842A53CE0F14F4B37F74C890232B04374771C25790B06DC69A70BA92B4C85D22548063C3E77C2CB5AD81EE9E4971915070354E866AC53C025D5D5007BC66EA4ADF878F2B1B2B5CC811A5CDFC86DB3AA48AB1C5DE89988F0586ED074CDBC7C29228B3442561707065B56675E8A73D180BAF7C6F92FA551DE82C360978E1645BFDB795200E51554001C57DD8C8426DA35056D333E7C34FFBEB03F33204FF667F74C42E2223C0F5B6D3C47E13D626FD04755516566739F5006D6709EBCBE32CD67DA9C23DFD2D3A1946672062C30BC3CBB76FB1A0078D07CE61934599258EFA86B6586A3C5FB09F4F847FA0F43B9159A918830BCEB1A948E4497DE59359E4D2B6F12E301F15BE49633F1977CE512A34AAAD414AF4BF8575850F88286F53ECC7576A18E68BBBFC534445F4A1D2450C43EFE69404C3783B16F45AF2E2682E8186A72AFC990D687C05895BAB1725797B1EF962938991F478DA5199210F72506307E2A84C8F0168AF38D5A979543F643BA6221D5F7FD3C28CCFF25A1D2610804A640AB886EDA2C23E7AF67FC608E6364373222CD6ABA740BFE455EF46E8FF6FEEF76995E15987D667BF048052A3858842F4094DD7D62B3F9EA053981C0351D396C1CFAE6DA711A961F8801A6AB1CFC27EF289A7E25057F742D9005DD2A0A32A499D6D59B6F3069F0BC6C0AD485CC4BA4CCE4EC776BF8D7B9ED88EE7CB1FB3D2F0C0E42A4E0FB6448605CBCAC426DA90B370E29B467692B57970E219AC1856B35C55AF9E2F60B11A67A8C3E3EFABA457825C657604A83F2EF9BB32034A223E8431935A78C89E5B73CEA306DED8B3E069CC6F87C310CB02E0A3AAEE30A480B7AAB58CFB015D4888403BAC5ACFE19073C4A82AAFE48C27378E12893DD970030D3BA89166A5F0C33CB14E46AC0A7E771F90279949182C03346CEDB67F6AD57AF2F961ECE979C7337475952DA9D79BD542D8EE3FBE7847423F806FCA3B4C59BF505A5ABF1EE8728AF6C8CBBCC3C66723A2AFF2306EDD2F94997A710A3DDF3A18D9D0BDCF1570AEA7B2FBC1AE216003D9F744E10D701DB6D9CB89F6FE3E78533588BB1EAF92DB25B5581B00D435D3A0822252326E1BFE5A35DBF245EB6095EBD0B92D2CE96CBBA9EFA12966D8F0D9FDEAF4AF2A6353FBA7C2EABC7E3C6A0F6CD9B2DAD2A47B3D4380852E18AA1611DF6D3B61FD4AC88DBE73A4CD67A8D3E881278B23D32350FBD79C1EC4D9B33214DD77806DE3AB9C240E0B2760AC3F0D0BBDF9B235243FE592D510F39B008E993468D650B6BADBE7CFE003054BB16E75B5A4F752C898A8C5F3D97E14756864D894497CB13EA66368682F1ED63E638E04D4E03D1A3087CAC067E8AC1C52479CDA676AC91E53C86DBB4525110847E7DB9044DC27B36B4DF68E4EBDED32BFC745D32C22E1ECD916F38E45E69F8CC5105FD47DC904444E0B4FE3082020A0282020100C282D5A772D2C739A825536DF6D88F645947501DEEA2AB669C0DC9199BE3071A8461A84854669CDE59C894A1ECDE833E9DF286CB5DEAF55B8FDDF382EB03D307908B2144FE1A2B0F581C6EC8870DB5CC0DCFC67A23E734C497FE71F69473E6B060AA060715386CCC5269E003C2CCCE0018DCE1C87437DFDF20587456EC451C92395EDA4E6C55F3CCFBD7CA96938706F3DF45F7A07F5D1E19900C2CCE381E70969ECA20BD25C2B475CEE9A0ED9F9FFCC58527ADF6000E1099C6797D00A5171D5C2C9FB863C1105F192AEC7C48BC6043C9C5E5FFD4B81B67382860E62E9BA3FCFB59A024368FC73DE2BD6643F016D2BB0CCF013CB13281ED6E6257DD89EC9D5E286D2508C4408EBAF5305DA36DC733816E112FD99B972EEFD1161DF31F9E1C8683C9A331CDB525AA08791AC565B15AD459691C3E08A5F1C2D00E801B7DDA9D1D5440C90D1987FB8ECE8ED0B20C27C2FD0288B9B1C243537F9C6AEBDEC0309151CBB64E55EBA5D7A5FB62AEBFFD86993AFD76A7E00C69FB042D42A684A759D827732E2222CC44C7DB88EE626891A373156E59F1D5C035A60DC8658268B0C65B846CABD97DDB00B3FA9EE3AFC5065BC30394A1CB545AC39D17E1539752EF34297A14F9E5F4A5218C4D7B7A97AFEA587C50BE1032F23F11700A7FAC554BA2CC5AC8F450EAF0BA4203FD014C05D557877C1451B0D250B555B7F8F68287FA3519F1F2CF0203010001 +CtrlOut = hexpriv:C4795A90094568A7B97CF93D6D2C0F229248EDE4959EFCE2B5D41C7C3F9D2BEC308209280201000282020100C282D5A772D2C739A825536DF6D88F645947501DEEA2AB669C0DC9199BE3071A8461A84854669CDE59C894A1ECDE833E9DF286CB5DEAF55B8FDDF382EB03D307908B2144FE1A2B0F581C6EC8870DB5CC0DCFC67A23E734C497FE71F69473E6B060AA060715386CCC5269E003C2CCCE0018DCE1C87437DFDF20587456EC451C92395EDA4E6C55F3CCFBD7CA96938706F3DF45F7A07F5D1E19900C2CCE381E70969ECA20BD25C2B475CEE9A0ED9F9FFCC58527ADF6000E1099C6797D00A5171D5C2C9FB863C1105F192AEC7C48BC6043C9C5E5FFD4B81B67382860E62E9BA3FCFB59A024368FC73DE2BD6643F016D2BB0CCF013CB13281ED6E6257DD89EC9D5E286D2508C4408EBAF5305DA36DC733816E112FD99B972EEFD1161DF31F9E1C8683C9A331CDB525AA08791AC565B15AD459691C3E08A5F1C2D00E801B7DDA9D1D5440C90D1987FB8ECE8ED0B20C27C2FD0288B9B1C243537F9C6AEBDEC0309151CBB64E55EBA5D7A5FB62AEBFFD86993AFD76A7E00C69FB042D42A684A759D827732E2222CC44C7DB88EE626891A373156E59F1D5C035A60DC8658268B0C65B846CABD97DDB00B3FA9EE3AFC5065BC30394A1CB545AC39D17E1539752EF34297A14F9E5F4A5218C4D7B7A97AFEA587C50BE1032F23F11700A7FAC554BA2CC5AC8F450EAF0BA4203FD014C05D557877C1451B0D250B555B7F8F68287FA3519F1F2CF020301000102820200492DF11509219CDBA7D3B7324173136BA51D2BDABF0BCB6194E7A8D7AE2AF962B4188BB7FEAD066AAF2BC423B19ABB9504D698790DB216B2668B921098BBBD1AF4FA2B3FAA3C0D243E39A0426871338AFC4D45F670E88D1543BBF2835B31C9C264F3C2C5CA698AA14A8653C60675883148295DF6CD26B25EDF6BF80535EA008850F64B3AC30E89657F009E530D58F9382A31C82AC59032815A8D021469CFA5FB3CED7DE8BBBAA7AB44F7E7D84EBC61DCAC2E9407DFD86ACD77FB00190C838843C3F4296ABA599EF5B88CF56B6617EF990B8FEF32C83B6317A13567947470FB7E532769486FCA7D917F4168E0FCAD36BB686C2639E26F387555A18A135886924409A90AE149A915A9CAD2657141CD94148370977841A0CE2B2615A86FE6F98C1DFDED00B66BABA4EA1D1E172478E5F00AA3C8831351D17BEF7E1BA26B32F6DAD7951C288135184AECB816358BDC77CF5776E4F62D2FB9D0FAA17F861A04F00F5CE8669AB3430BF342ADBBD53C7C689B178BD3F3272DE37F79773487BDA30E555E5D27E008F994750C7074486323C706306229B265DCD1382B094E908C6FCEA99EDE0E3DD71AC68459DEAFDB940B17DAFF30434E4C64B66B0FCAA28096F12DA4CCF6FCD139E1B9A85594C268296FFA95957390FE9CEC98B5503E9C17EC41C461E454FA7735AA37747510D63D23CAD6C088DB32F8C70D754A5D286794FD9118C6910282010100F61DCFF7210F3E6F6B117688096095BF0007A1A6EAAD3A0C3C48C9C3FE606C647E05D97CD782B9395484D4D19275BB1F049A4093AD73B272FE9EF14398F31FE00F829058A1ED414E80BE6FDFC83D1EF8743AD9282AA4ABB2DC088427E9F8BCAE79E95151C22A33C0D073F1A65DBD4CAED4218D4038FA936D481A877D16688790A574C3C2239FA315DA9C5F91EC8D5E1B8C3AE69B4F1E34A259AB801F2FC69702BF496AB3F98E7C8D20DC5DD00A8F94DF1AAD0A832476144F731D15F2DDECA9640D557157E9A0C9FC9DE644934CAAA18665F413920E123AB30242A00778A55F5F42A15C145F2C67B311FA6026F49FC28781BE00CE563161FA1790033E6B8381710282010100CA527EE81F6A8FDF3501FFB9E09E2EE278AA79A355C8EE96A9391AD3A5FDA83D5A4BB710496F0AC4AFEF365C1B17320C0A8262D5BE4B638366485F9C9A2CF57B0BA80EA1995E9B71550D986537D15F3BAE46180089B5608A715FB0BBEDED63DD4950D14549F5C76C1F5C6E39929DABD8A05C263691061DB0647882F99CC61F8D9E7BC81D1649842FD824C74F014D8DACA41C46013D31A027D26ACA485068D693A9185BD12C2A20832E48B02814AE735037612AEE5811C9F848BF5A6E75D36E7303B5AF8F9312F8EA6E3E119C09977E8313F10CC93B255A0CDC723215A0A5DB88EE226A525D136EA7EA0DB8AFE42807F9206D0EE174E09AA57C7B4E70EE5A983F0282010100EACD2E671B072C0DA81C14F55BDCE5803F4B0891F23A29B31AA066BDB1A5D4435B67C1423568E5C5283941C05EF62AFB40ACD9070AE7E24B8B579FDD59C2399ACDB1467D089F0D3B13E09B62E7EA47EDC9158BAFA25F4FDF67C44830BC2B2DF7571F9D115F285C0F8BCFD1AF62A702CD985C1A223739F804BE51710989A358124B87C66B25095BD1B1AA9612E597493D06DFFABA19153C29D75AA2F51DE35C96A66028886381E899CBCBF144558EFDFC8BBAA2D8D2A4446437F27BCA24A770439FE4F0296B1E9715869EF4B582E3170EDD9DAA3E21668AD1D54A32DA6DE377C5AE0FBB8543F75D479DD33C806DC92D119259EEF2EB905964FBADCD2A73F01641028201005C74F893A10FB4719F2AABAF48CB60C793B6EBE14D698646894C944AD61725D3EBB8A00EAC50374E8CCBB73EBE0E8A8B601E17866FF0C9A8198CC74CAC5411564A8C612B4E0822E6D6A460D91879F098385AC5CB312316DC0D555A5177383DA3B9465A6BDC9199B17A5F65EB9F69B8474578F6E986BA91C4B315335D585C5DBCFD08B9F938DF1DAE338B131DB28DBB4982B17CF841FBB4A19E11B920F4C60410F47C3231538A68D329CA83DDBD1DBF8A8FD432A73ACDDE4B3D0B5D0B0F83307D14DBE93FA6494C40ED6225EFF59E2A6D4226ACDE24CE3BE996B004DD474DA4165E24920BD386F6D17B2F0C102D26720651E024A5B9208EEB4308A25F0F3D8D47028201001C79A187C6231F0B683813DCBA666B8B15395D93CFB0D1779EC5903700FE30BDAE1BC31648C41E13E62C62FD4F454CCFC8C6D5EA3BB79D1FE4D252657DDFE0A690218D79BE32A0D5D44E9A50DACF2DB19C212B4266073A7C20A68C3C0567ECE44029521E33C4E8A1D18227F784D81924565970D1A61529F447E517304B08DED2536962E9E152C3A20D81097B90D0A21578DC2F76BF21033476DC4990439F1575707155792F3D209AAE8656BB305B1EA7895E7A49F570FC6209B33C77474713CE7BFF4AAC71D5E39C36FF42195A8CDA28D18A538E252601FADF2F373DE676D01656D7A13E743CA084EB1CDB9430BED51C36803066C99E09D86D9939F209CC8C04 + +# --- ML-DSA-65-RSA4096-PKCS15-SHA512 --- +KeyGen = ML-DSA-65-RSA4096-PKCS15-SHA512 +KeyName = keygen_MLDSA65_RSA4096_PKCS15_SHA512 +Ctrl = hexpriv:FC6BE06103AC3C4B6638F4BD75A919DF01F70A283EC6749A4EEBCDA34C41B10D308209270201000282020100B5862E597195EA861A86885D21EE5E26443B07ADD4E8EE1813388BAEA8CACB21A608A6E082EC760358AB79AFB3D0F3D610F9D8F6AB3ECA447423DAB9633646C133E9F31A4FA01D30B925B9D48F23982ECB9555F716C18BAF190A8BD31498882DCBFCB173A097DFC6ADEA1B6B54122D9A6ED38BDF9894B20CB46BA41C3D24DD052DC9C3BE1C33C3E50D2C8BF8EB04955DE07C0ABF173A7D1EB5BDEC38BD2EA14023B520003B00C012479292C30E7B5128FF912B78E5BEBCF5E5939B1DAC04CF2216F142296620D2B809B432E3D96BD12629C828016B3D3F4FADE6050C85801043BE19D665A2753F22380954930A6B6E11677D7047533CF4C4A4FF49F53CA4B93A6E4D14655418BE05428F924E4D83D59E9B5F3054A02660AD51773E12BB35A445CC46602B2A07654181CE815A472867D4A14A67BB1CFDC44804D92CF7786D82DC05F6C855726C207288288996CA322A462F7E199265407968826B7EE6665156DD0EE580AA1F96B409372D034AEBE789CFF4077C2469DD36B4EF4082F6F42AE573C9596210477707154058F6ACD0A69D14B9A93BD388177C0DF2BF2D4E12662285ECD2B2AF78DE54AB8C8FD130CAD46BD85A5322AF4698293CB37559F46487E6BE51BED079E70598AAAEF88C129A3D5BD74240808DDE4926E084401EDB145A06F0132C6D84D5894BDFA699F8B3578B10C7AD5948145CE90682923081DE731521230203010001028202003A98AF72910F7F4EBDD64AC3A195E44F7EFBFD2D188AFE7CC80B9B4F8CCE35C74D6502957BBDE01491757D09024743C708E0D6303E343D2FDEBBCA39C8F476DF9C25FBA3352BEEF050FC042240F891021E16BD52CF46381494454AC09F27E3E1C0B4F80566C44FE8BF30509C935D70DA26C76422100B83F444F3705CEB41F094E0E47E2AEAC8AD064DFBE0CD3FF45151260B749E9DDD74114B429D33EDA1D54CB29A1FD3E33809487D512BCE0A693558423376F0865D4D7B251A425AD03217391E65CFE13446092F7E766C6D0FBCD59D77A45481ACBFEF2585F1B814842DC45251D5DE571D9BB27F15CEB13DEC01A4DCBA670C2D020A2DCB22A604164576B911BFDAD99A80F7820EED10344A9F4D3FC249E1235EDF99505E8C02232A0FA51CE6D2CFCC1AF9595F8A99BEAE7DA606AD395804D90BD896A1A800507EDFB1B6756D1E9BE299D8C639DB416238EC34F654E59729E268ACB9D64E2AADFDFEEC8489A123827003415176E73B422A2CFCF477D346D343BB71CBCB18261E4D76AEA5FBFFC3718E8D37D49C2402813B8C7DC1ECF078F9C8189101335BC88340B756D3679789A98203A23B6EAF111B5D79823A765CCE863EF7E657C8C0EAC8961DA4BD926F517EF086DA3241585EA20BD408A81905A47438960F3690C0847C86DF52729C5855BDAB22F8E695E699B72A89368FFA8CDCCFDF3DA8334888752D2DFE3AC7AA2D0282010100DD6C93928A6C22FDC74084A990CD566F6792D0592840726849B2467571627139B9B691B723FCDA23CD279FA4031A581C3FAFFFB1ED35B341FD6BA1552F67875BF5ACC3705CD69705935A95282349D9AD81BFC86639D745654982A2FFFABDAAAD169F5DE6EF8003CDF56DAECE43623DF480910AC70E6120A44FD7382CA1AC568FF36FEBBD0B43F3A5EF480313C6473608AC3945500B5BD775B99416C92C0D399B3D5F8F6572BCAD4916425A8A916816F79EEEFEABF06075D01CF78C23BB2215F8B191E981BB9119697F4363589A09778F34B8C6E2C842F334129BF49900672F710AA81352C215686488AF77B0D59C7F121271A321B586E168712AAA55B478EECF0282010100D1DE9A980E2BCC2BF238F577D2DA5CF1CB772B6F22894E147A21EC8ECFDECC2A938362CB6603DA5BE1EE0FED6109E3BED3FD8933B8368B645B0D101B1E11C8FF0E4950922709EBE273ECA835AEB64AA1B16F3B1FC0A06CD50A1D158FCEDD6E835E0A97DAAD7CC022BD0E787476E3B5C14B0D2261379A4DAB4CAD9FF1C067921E2FCB19E6C220C4847DCE66F3E56E0182887CF0B500B6C624FCFF0CD4CEB1757E46D01E6AB62349D9D6FA2F2D52712BB9C01A945E2C9CD08953B4E810AD53F0BE6A1661D9A926CD8D43CA41E6C63211816C626F99FD6BF0BB075419F2AE23839558A3078E9AD7B47DB16466274343E5A93EE7B75EFFED1A3B8976BA9A21561D6D028201003A16A6EC55C622B3E316E8F6B717376AC8883A82794DD6F5C707AEF6568595E0A7F8DE6766588A3DC42F75F108235C24250D1E0E6685A4FE55E66B8FB67CF984C581CA4FEAFB1CE9888BC5FF9EAA5C21E99D0F8CC9F5D0ADCEC827CCF1D1DA39C86A8CAEEDFBEE8394B46E9C8C0EF4E3F4EA98223A827E96BC9F608C4CE9B257D76C7032CB06CB9FA79383C3274C3D3FAF36E31929B1B167A004DAA97216121BC8D10E0476424B4F9638581A6C251B8960B7A036293C950BC0DDAC751F3DC4F7D655CA258FB8742B3A08CAC24EBED70FC9AC03F930C2679D2C989F65983679BAB529FCCFC43CEB831C5CB410BF296C28A8900954E9937604F953511664DF28FF0282010047AAE8C7FC2EE0AE312D5A45ECEF3CC6256130A7E6F7547E91A67C0DD8D6908A098DD872F50763CDF4BD431B21042B8DC2FED5979FD4A08D48BA914171674968300CC142E7A9EFAF893ECBC269433F013082778244598450CBFF5A999D5EE89A5BC6EA4C76EA1F02BDE4EF2576641471499BD69DB44B3132CA20907A11E64C739A8694F5C45D443EAA678DA8C43468B796BC73C69BD3CE9E5AF70DFEAE06D3C4A791F2912659AEA28153364117E225B86CEDA6B4F22F2AD77A8A50A5414B64EEE1737B3EC510C728F279633FD776C99B94D398A0D175C6E3578154CB16C471EED231FA26ACA1F4B4E79B0D7762F510BC570AF207B305D8EB73E9E39736C31D91028201004067AE8F16440FB321A51429D31D688F9BA6D88FC49B6A04993DC9A8227CA9AB0F8E3ADEEDF04471430A16829CB0FAE7376CFD2F305A2C8E8A5BCF45AD193DDE2AC8F05A84F1A5D2353965654D9A34718CE40F92F55E75CEA4DBF0A1CE7314837141D1CB54C7C2D8AA6533E3332D5A3FE1B0CE94E8EF7D1DEC8425D8D77F168F0ED9BE723211959DF5A51D6927BEFA893FB44577F15B916C24E4B2B7368CA7584D6BE39E8BBC56831B249753F1CAD594952EDE1E664ED819E3E54FB27AC40005C0A23C758FC816F50219450C4079517C2DB5BF90F5005A87349F058DA793E954D76A0A8E696516D38F225C613FFA1795E869143ABBEAC6F88B07ADE55053B0CC +CtrlOut = hexpub:F1B9E9575C48F9DB5F66B88FF6A7B70995B63BDF95F3C0B02C11B603233473FB0E8DBC73CDD7C9CC046B6A813061EA06467C5BAE5100D1A456A5E8CF3619E866E1C563F4C122E6B133853691E918909FD6D7B87A6F29A232945629DC24D14BF9FCDEABF0B8658C1F052FFDCD193EC09FC69979BA3C3061AC287EE33DD6EF915A496B8BD1C11F57D511571BE73EAB3653E92F3083ECF5EBD54AE61659ABA68D6BE46A27610E21BD9CB544EADFA8CEA74D71AE5B2491AFFC33D453B9B26D47A1907978B0DD5076878022E4668709469F25FDA4B1C8085F3D773D8C75ADC4AFB0DEEBEE63B5381DB256B44E967FF5A8DF14A03928F770F6CEE7FDF0BA0E0547F18F6426950124A62B9D0053B870FE991369583E5AB7326F922CE3648D54311CC1AE0F54D64D0C7CA9839FAA3294B632ECBFDDFDBF719F78756579BF021C2DDD90D00896446B5866C622A4470AE88A878C9F869D2D69C67072D5CF763BDBA4E358AB28E2A2BF7E84C1D699A2FE6FF6F877F84ABD4539D49F69411690D7FC8B342140EDDC31CB4998EB953C3CAA90E93C39B459AC4CA487BCD37BE09D28B94509CD48E7FF05ADE85155C83359A488BAF8B679859C5132A7160B7705B5BBE558582ADD600BB199DEF2BEBC23C5A59946C67E8D4A75FC1F4A4304421492A76BE0E2F9BE6234CEF9C201827E63F9175DCA7423FF382EC65DC80F297465A2D0A4E56CA7046CDACB7459BA26D88DFC18C432D4C31BE7B552D8769468D466ECD9E5BED343546866EF849343884494C89F95D635C15136195D406BC653FD79A4A8EA82F4CB3CB2117CA4366FD01E02B2EB61A8F40153F4C9D7815CF9A47B9CFFB2A394B5D7857B8C97111461000ABE3C5CD1C8D8255C7C6B9F5A9574EF4C1946471BC639695E72446631DA28A5EEFDB8E54F1AD7C4DA77CAFA66D8B4B05B83CA6D4A9C519EF4A2037E54E7A94431458E7412B9D4BDF9E4CC6B7FE6F62699C7F503DA365A87079FC8B74A55AFF99BE786F3112C150842BDB43464A6AAF240CAE72B4B6D07C354911854C21759B3ABFDDE7874E0286FF4740F615D84BFCB6FC86E1C7DBC20E6C25DA86E693910CBD7C5F8C3A152F9316E5A22E892F78F5D993D3A2EEA4F6EC37DE4F58A16C9841D7D99B4D9D08E99BD838DCB505A26095A6CA0CAAF966A98849A3A2A0D5F85FDBF9BE6E46CB37B8828A28EEA1DE9522C5B6BCEE40B31618FF3CCCDCC358D92542E95C73C8A616D3AB79F2A68B85ABDA265C537658DB0E4307DBF8EA77CBC89ADAA8DAD5DAE51C0A117D4617550D5EF02F652693F59EA2E9294DA5E76775D98C9E35AEEF7C9BC8981C80E7DE06BB6F2CC6AD37DD6E4F22DBA871E8117BE02983BEC992B7CB94549CE10A21ADCEB6B3DE2E1B2FF5147D0D9CEFAAA39742F35A4A9C4CE6A2EB8D69DE510AC8DD41488BA90ECC2C53E9C25C8340DF371298716692A40E65C7BE574F2FC166DD9A36BDD2D02FBC8E5FFF0E94655401141E0F7CA996DE81C2AB92FD1088827E5A91848A7E05C0228933FE1A1CE96591C4DB9775CB8FE2322AC572A031281012AA3E36E8A7AA0DB1BB4A3A10DE4E547EBDBCD90485166FE51219B6442E78DB6D23AA95AB07CF81BC540C61654F73BBD45489D01049C306F7DBBF764DB8DCA3CF7DF95C10065428DF62F78DD0F26816CD91377D3F8B60EA73999E858FD247A4DD4CCAE665EA3DEEA5AFE5878E9D2000716C84CFDA8CD3F84DE7ADFA1FFB8378BD81CC1B93F7BD957D2B5AA605DB549A021DD5D5D8ADEDBFC7CCA9F30CE0654DC00BEE10E3255B5614B0838247108E4C82B03CD97A4B04F95CBC3879A8A42866A28BCB6204AB0ED26A88CC5BF463BC928CB7AD952314DC097BB91025E7456FABECC899229827D0CA68F573427E3620FAA767CBC65A3F0F0473676099111D5D3747C1AD3174A82DFAB18EE1E14CC963069975DD11CD13B061AE3317DA5B4613AC3EEE25BABE240A9D6A3504CAD1636629AE1DF510BE366D855575AF665C082B469B6A9E457EEC8232C7A2CDEAE54AF738F6C780FE10DFA64D570C679462CDBDF3B7C5366ABE9A049B00FDC53A203C9FCCC7D2307E65217D996FB7C93DEC2B6E922910854810CD35707920FBA032E581CEE1F63B5E4091917D189661976D6CEF6BE93B619D45843EF872D24984D3BCECA170CDDFBC25DA323BA73C1FC9118B7C2A47C14B557083F778C83F02526D44BEFF0DDACE98BF7BE246961923C0B8DB0A4653A3474474AA9ECEF4560D1AC38D6D0B1CE42DD44F58A5AE37628405155AEDCCDD06AFFE4FDB0192298092C4B5586486403D63BEF8FBC81ECE29AA0E4114DCB16DFC1B90AEAF7C3F0A063A80F1AB80376A449AD8A718D3B3445D0B0BE780513BFF81361E12CD1CC2EFA710100149DDF925D95C4B34A5C294EB19E6F8FFEA42592D536262C4DBC9BCC6C2EAAC88CE3504F8441757854896DE06325C3A72A0E8CEEE054FD5CC8DAFE1426A6A6FE820503DA67F7BC01FD1483897E2842F3EC1857BF67D1576E2E475F6FE67065F91A59A4AE525D3B517760C3B45F20C8FC29FCFBD5C941A3FAE1398838EE9DE265160D7865F05AF895645C371967062274B83616EC53181EA0B3434CFB1964500F1A607DDBF78A2C83C9BE3AF2FB6CABB72D491A1DA300726CAB02DE7F3AFE62D2C1969FB475C6B7B5A448B29A4BADB9F5C2C78C9A1F8082686F4CAFAADA219181AFA1FB5451420A8F37D66D15AC5437B53D0B9532953D8209B18CF419E251BECC84B00390193082020A0282020100B5862E597195EA861A86885D21EE5E26443B07ADD4E8EE1813388BAEA8CACB21A608A6E082EC760358AB79AFB3D0F3D610F9D8F6AB3ECA447423DAB9633646C133E9F31A4FA01D30B925B9D48F23982ECB9555F716C18BAF190A8BD31498882DCBFCB173A097DFC6ADEA1B6B54122D9A6ED38BDF9894B20CB46BA41C3D24DD052DC9C3BE1C33C3E50D2C8BF8EB04955DE07C0ABF173A7D1EB5BDEC38BD2EA14023B520003B00C012479292C30E7B5128FF912B78E5BEBCF5E5939B1DAC04CF2216F142296620D2B809B432E3D96BD12629C828016B3D3F4FADE6050C85801043BE19D665A2753F22380954930A6B6E11677D7047533CF4C4A4FF49F53CA4B93A6E4D14655418BE05428F924E4D83D59E9B5F3054A02660AD51773E12BB35A445CC46602B2A07654181CE815A472867D4A14A67BB1CFDC44804D92CF7786D82DC05F6C855726C207288288996CA322A462F7E199265407968826B7EE6665156DD0EE580AA1F96B409372D034AEBE789CFF4077C2469DD36B4EF4082F6F42AE573C9596210477707154058F6ACD0A69D14B9A93BD388177C0DF2BF2D4E12662285ECD2B2AF78DE54AB8C8FD130CAD46BD85A5322AF4698293CB37559F46487E6BE51BED079E70598AAAEF88C129A3D5BD74240808DDE4926E084401EDB145A06F0132C6D84D5894BDFA699F8B3578B10C7AD5948145CE90682923081DE731521230203010001 +CtrlOut = hexpriv:FC6BE06103AC3C4B6638F4BD75A919DF01F70A283EC6749A4EEBCDA34C41B10D308209270201000282020100B5862E597195EA861A86885D21EE5E26443B07ADD4E8EE1813388BAEA8CACB21A608A6E082EC760358AB79AFB3D0F3D610F9D8F6AB3ECA447423DAB9633646C133E9F31A4FA01D30B925B9D48F23982ECB9555F716C18BAF190A8BD31498882DCBFCB173A097DFC6ADEA1B6B54122D9A6ED38BDF9894B20CB46BA41C3D24DD052DC9C3BE1C33C3E50D2C8BF8EB04955DE07C0ABF173A7D1EB5BDEC38BD2EA14023B520003B00C012479292C30E7B5128FF912B78E5BEBCF5E5939B1DAC04CF2216F142296620D2B809B432E3D96BD12629C828016B3D3F4FADE6050C85801043BE19D665A2753F22380954930A6B6E11677D7047533CF4C4A4FF49F53CA4B93A6E4D14655418BE05428F924E4D83D59E9B5F3054A02660AD51773E12BB35A445CC46602B2A07654181CE815A472867D4A14A67BB1CFDC44804D92CF7786D82DC05F6C855726C207288288996CA322A462F7E199265407968826B7EE6665156DD0EE580AA1F96B409372D034AEBE789CFF4077C2469DD36B4EF4082F6F42AE573C9596210477707154058F6ACD0A69D14B9A93BD388177C0DF2BF2D4E12662285ECD2B2AF78DE54AB8C8FD130CAD46BD85A5322AF4698293CB37559F46487E6BE51BED079E70598AAAEF88C129A3D5BD74240808DDE4926E084401EDB145A06F0132C6D84D5894BDFA699F8B3578B10C7AD5948145CE90682923081DE731521230203010001028202003A98AF72910F7F4EBDD64AC3A195E44F7EFBFD2D188AFE7CC80B9B4F8CCE35C74D6502957BBDE01491757D09024743C708E0D6303E343D2FDEBBCA39C8F476DF9C25FBA3352BEEF050FC042240F891021E16BD52CF46381494454AC09F27E3E1C0B4F80566C44FE8BF30509C935D70DA26C76422100B83F444F3705CEB41F094E0E47E2AEAC8AD064DFBE0CD3FF45151260B749E9DDD74114B429D33EDA1D54CB29A1FD3E33809487D512BCE0A693558423376F0865D4D7B251A425AD03217391E65CFE13446092F7E766C6D0FBCD59D77A45481ACBFEF2585F1B814842DC45251D5DE571D9BB27F15CEB13DEC01A4DCBA670C2D020A2DCB22A604164576B911BFDAD99A80F7820EED10344A9F4D3FC249E1235EDF99505E8C02232A0FA51CE6D2CFCC1AF9595F8A99BEAE7DA606AD395804D90BD896A1A800507EDFB1B6756D1E9BE299D8C639DB416238EC34F654E59729E268ACB9D64E2AADFDFEEC8489A123827003415176E73B422A2CFCF477D346D343BB71CBCB18261E4D76AEA5FBFFC3718E8D37D49C2402813B8C7DC1ECF078F9C8189101335BC88340B756D3679789A98203A23B6EAF111B5D79823A765CCE863EF7E657C8C0EAC8961DA4BD926F517EF086DA3241585EA20BD408A81905A47438960F3690C0847C86DF52729C5855BDAB22F8E695E699B72A89368FFA8CDCCFDF3DA8334888752D2DFE3AC7AA2D0282010100DD6C93928A6C22FDC74084A990CD566F6792D0592840726849B2467571627139B9B691B723FCDA23CD279FA4031A581C3FAFFFB1ED35B341FD6BA1552F67875BF5ACC3705CD69705935A95282349D9AD81BFC86639D745654982A2FFFABDAAAD169F5DE6EF8003CDF56DAECE43623DF480910AC70E6120A44FD7382CA1AC568FF36FEBBD0B43F3A5EF480313C6473608AC3945500B5BD775B99416C92C0D399B3D5F8F6572BCAD4916425A8A916816F79EEEFEABF06075D01CF78C23BB2215F8B191E981BB9119697F4363589A09778F34B8C6E2C842F334129BF49900672F710AA81352C215686488AF77B0D59C7F121271A321B586E168712AAA55B478EECF0282010100D1DE9A980E2BCC2BF238F577D2DA5CF1CB772B6F22894E147A21EC8ECFDECC2A938362CB6603DA5BE1EE0FED6109E3BED3FD8933B8368B645B0D101B1E11C8FF0E4950922709EBE273ECA835AEB64AA1B16F3B1FC0A06CD50A1D158FCEDD6E835E0A97DAAD7CC022BD0E787476E3B5C14B0D2261379A4DAB4CAD9FF1C067921E2FCB19E6C220C4847DCE66F3E56E0182887CF0B500B6C624FCFF0CD4CEB1757E46D01E6AB62349D9D6FA2F2D52712BB9C01A945E2C9CD08953B4E810AD53F0BE6A1661D9A926CD8D43CA41E6C63211816C626F99FD6BF0BB075419F2AE23839558A3078E9AD7B47DB16466274343E5A93EE7B75EFFED1A3B8976BA9A21561D6D028201003A16A6EC55C622B3E316E8F6B717376AC8883A82794DD6F5C707AEF6568595E0A7F8DE6766588A3DC42F75F108235C24250D1E0E6685A4FE55E66B8FB67CF984C581CA4FEAFB1CE9888BC5FF9EAA5C21E99D0F8CC9F5D0ADCEC827CCF1D1DA39C86A8CAEEDFBEE8394B46E9C8C0EF4E3F4EA98223A827E96BC9F608C4CE9B257D76C7032CB06CB9FA79383C3274C3D3FAF36E31929B1B167A004DAA97216121BC8D10E0476424B4F9638581A6C251B8960B7A036293C950BC0DDAC751F3DC4F7D655CA258FB8742B3A08CAC24EBED70FC9AC03F930C2679D2C989F65983679BAB529FCCFC43CEB831C5CB410BF296C28A8900954E9937604F953511664DF28FF0282010047AAE8C7FC2EE0AE312D5A45ECEF3CC6256130A7E6F7547E91A67C0DD8D6908A098DD872F50763CDF4BD431B21042B8DC2FED5979FD4A08D48BA914171674968300CC142E7A9EFAF893ECBC269433F013082778244598450CBFF5A999D5EE89A5BC6EA4C76EA1F02BDE4EF2576641471499BD69DB44B3132CA20907A11E64C739A8694F5C45D443EAA678DA8C43468B796BC73C69BD3CE9E5AF70DFEAE06D3C4A791F2912659AEA28153364117E225B86CEDA6B4F22F2AD77A8A50A5414B64EEE1737B3EC510C728F279633FD776C99B94D398A0D175C6E3578154CB16C471EED231FA26ACA1F4B4E79B0D7762F510BC570AF207B305D8EB73E9E39736C31D91028201004067AE8F16440FB321A51429D31D688F9BA6D88FC49B6A04993DC9A8227CA9AB0F8E3ADEEDF04471430A16829CB0FAE7376CFD2F305A2C8E8A5BCF45AD193DDE2AC8F05A84F1A5D2353965654D9A34718CE40F92F55E75CEA4DBF0A1CE7314837141D1CB54C7C2D8AA6533E3332D5A3FE1B0CE94E8EF7D1DEC8425D8D77F168F0ED9BE723211959DF5A51D6927BEFA893FB44577F15B916C24E4B2B7368CA7584D6BE39E8BBC56831B249753F1CAD594952EDE1E664ED819E3E54FB27AC40005C0A23C758FC816F50219450C4079517C2DB5BF90F5005A87349F058DA793E954D76A0A8E696516D38F225C613FFA1795E869143ABBEAC6F88B07ADE55053B0CC + +# --- ML-DSA-65-ECDSA-P256-SHA512 --- +KeyGen = ML-DSA-65-ECDSA-P256-SHA512 +KeyName = keygen_MLDSA65_ECDSA_P256_SHA512 +Ctrl = hexpriv:6EC75C5AEB0B9B214DBA608AAFDE387BC8BE031A465DD760C7D7C7EBD628E3DA30310201010420984397BCC439C060EF5109CCE70B96DD735A33D0EE53A17AB997A9CCE46ACAABA00A06082A8648CE3D030107 +CtrlOut = hexpub:AD94F20981495292C5D759BEF7FAA40BBF030157336926E10DD12095772F14160627D4545486727FAC72D58C3D43AD9D20CC23627DB00F8A7E1DEA2707CF1C04498177FB0564F5BA2DB2BF6116A9E2CE4C948B44BDC4399363921249E3295C06CA414369382B4B982CE62E424B27DD0AB827E5AF3361C56F4CFF91E0A783A6E11DD66E2CE624222DADC0B7307682E53613C28C4445A98FEC56C75D38A592820689867A9175DCC7B646AE6A37B37E6E139FE92412F1634876F9D3A2D118064C6CA412914BCCD94885817031FC72F129422CEB47499D93CB63ACA450149E5DDEC01D7EE5B151310A6BA304789D658F5233A84E5339B39EC29A2D54263913D8313142DF4D44AE6A547A3E04ABE98353F227CA3CA1EA3D62B4B4385A1279C271D880CF4640D217AEACE7A6C9EED1CE3CB03C182AD15048356D8C436268CCA188CBDF0D94192D94B4F0023D3A3ECBB8E688216D4E690C4C167CEF3D9674837D991825F6A0A2B18275EE78912A66526E524932583D0927615F5502F0E600B7D88E60B17E94C8FE1F1B7955888B19CB1D87260E8C274A9FCA8E109366A9A4C171EB1C5B296C90A1E8FDC283E3939E0150BBECF23F72B7813862FD5AEEC59B7A7846C695841E18423A59802C4B3D5EF92499C0E1179EB42190B751E35F67659AC65785D598E5BAE406A9D02F1A3B05777AF9F1688CE61D0D0DCE37203FAD97020911DD2BF6D99282511B81545F90BC062334D212956DB1D3292A9507B7EDF38D019035097FE6D093FC0072422708F37E8D6AD7BE2AFFE2B03A9A48815020249B68F77AD43A4612DC36244C4CAA0CDC51997770498ED0CB8083A9179B7D3A22AD00B62545ED0A9C1DD94DD3E9288E56334737BB405F91DA8FC76C75039A05DFD8EBC3A81F733332ABACAF0F85436D52A98AB14542F4BA1904DA04BB37DA4BDCC132CF21CB76B332AD651B7DA0A1FD1513B6A5A15E627267D4E2F844EA677EFAD5014C8A9EF78805BAE020A4BAA14CE74B23AD34BCD3CA66E03A55A7B38B30F0922410B43581975F76660EA0DE3B3CAAB36FA56B787E9C35BF0455C8A1CE275FC2B571AE81EC9EFF3BBDC063B6D9E595EFBEB6BA8A446AA45E2BD3255604C5D4C023B7B1BA7D6E5D1F33835C1A736D74A6044DA788C65387ED44C363302C4CF98B28B1F06BB82A783FC85BDFBFA6873D2F52D902232A0058A6A20A19EFE1C98B10D579080398C0CDBDEB47CA70F2A29966F35DA784D1A0B89B710D7592E63F3D21C74FB1F62716D7D55E83520343FD6F6B4F7DEF46ADD764E17D40070B8EFEB9C951CD059A6E7A83DBA82399EDF2CDECD5F2414F1EBA55D5CBE8A0E5029205D58D7B19D93A23DE46B36517EE243FC4FFF74922A84EC51F7AAFE1FE61E665C73535F97195A17A28DF52B5018FF9428245F7305B1F6365308DE18AA976BD2229E347F1882126C536E8A454A558E9B768D16A77C6D7552247EE928E7A922BC0F6C2747EFD292759EA2CBF819CC65618586867B6680CD5F542D0278C794B61CE06F9B4556E6EAE4EB0ED79ACB5742AE82044B0E5E5758F4712E3378B75F7CB754E5EBA4C99038EA77CA891ED1C76B571937497D9DCDCA3FC32B44881FFF1FE14A4C62FA9CF91C72D8BFB2EC27E43BC8180B3A7CFCD440D747FB7DB553FF47AA11E94297B436A32B04537701647B7A3C32628AFBEAA607B01E8DE5AB73EBC407904E8DD0C345CFBFE054C878B091AE13B83EB85204E934109A0517B70ACE5890E917BFC8BF55F82D37489FB8F10FE6EF9BAB6053D4A1FE472C8227AC28DFB808474483093A485F9018BF97B3175C8795F259A6ED1B67F590AD8DA3FEB05C46B793B9B1B561A5952B835AD65F7A173148420D1350A32FE91F92BC2662B6BE59452A22230A750CC44987E63BF123A575A11C7E414697C85BB973E20EB83B293F7E5E845974E745805769D8B89E683C445B7FB43AED71506AB897626055E0960E16B878BA7448BE0D7BB7C15E4A26D0D4C39B8E3A9B568641FAC269AF0C93C7AA3571FB404881E541602BCC3E9CC5068D9A74C50E466630ABE9C66A27DA3D12197117452BA69F75A99246FD3CF52281ACA78E7BDBEB8DC1C55CBF4C737DEA2A7885644718E7500481AC49B73FE61A7604A093EE112D2E541934C2334741EC41AC9AAE5A6BC7ED17CEEA2E3EA43A46E7692A75CBA9AFAB4FD2389213F90350F15837A31FCD978BF7A300D762F65A09BFFAD33D1ABB46BFA2BBFC28FA37FE3A270567C6D956BF7D8A0BEC063603C5A887A9C5B73F771889A2CB153C009F395921DB90925991370E06D96771479F14D9A7EA7894E2383AFB8F6E7777F352B0BF9368549BEE25893ED96B19A90DF6ED38B0310E440FBD4DD44F3190EEBCFDF683AC09A449861C6B62B33BB019D47284B5C6D7708E924A1AB9F5FE97C113EBB213A29476591702E3EC1FE54954FB2677DCD7A1FCF6E688E86682465F3A0FAC6F654D9AA8C0153BCED83FFF383D7D53CE88D1DFA295DE3AA005747F1C2A9EE07DD29964F4C26F1EC775FEEA237CBEA6648945E8A9EC455EAAA0DEEB1F9340BBEDDC4D7E4A8E3ED369337F1F75B7A2A79FB0CE1F6CA9D734EB904830650CD4E56BB676AA8ACD49A943DB74766CC4C112439EECDEA283F1E3B414E2D9FBF94D0588954EA92C03ECC00639C9626D6B545D565F57732B038E590454C1A316F061A431E3E1A16BC6A1EC51D3A5AB9AC6853F35B3E4AD32554D25B4ED2D0D734087824A3C4CFB7CACD7C51B66E69E40498824439F3DA0225096AFE049E8E6DB7273C7BE13CFA1DFB1DAEFB7DAD843EE35AEE5BF9E27EFA148821F220442CB49A665326A465A8B806AB58C6FAD546B496 +CtrlOut = hexpriv:6EC75C5AEB0B9B214DBA608AAFDE387BC8BE031A465DD760C7D7C7EBD628E3DA30310201010420984397BCC439C060EF5109CCE70B96DD735A33D0EE53A17AB997A9CCE46ACAABA00A06082A8648CE3D030107 + +# --- ML-DSA-65-Ed25519-SHA512 --- +KeyGen = ML-DSA-65-Ed25519-SHA512 +KeyName = keygen_MLDSA65_Ed25519_SHA512 +Ctrl = hexpriv:23A578205289555E65DDF567601CB4715FB593A7796A8F71D668C3BCA876D93760E9741F5FB8A68B3C490B93E4AA0E5D82206EF3B8E2242E1BCF4729F2E146AA +CtrlOut = hexpub:9491EA15C863E26FA3C4BA30E00446CFF560AF06B486922B3CC813381C7A0E8B8F99D3B43FCF2E9C258C0ED1B864591102482191D5F3B0D4CDA97CCDC2CFCFCA90F8C3CEA5F8A38607F0EB00931964AFD8DE7762E8FF8640F6EC3AEFF2A1A1DB89214F6F5839E0F07D1763F1B4D8F622F0F05E6C7FF7AC1E230A5FFC580ACDB7B94BA000F3019F4BE079E58574FFFF8F976C4F3A21A3B3A7FE5E222BC22D5A2EC9B5B118D3D9952A9D71971B02B709B3850E74F2ADE47865196B095BD3018B6492110C65B0FB34C2FA1E10FA2E9C9101F766F0329CBDA4927A439D7F42883DD04943475FE414B95CEA16DD25334831E611AF0AE01DE3D31F157597480E31FDA971AB789A47E3CAEECC2FCFF944703628624BD8D9459264837919ADB9C13171104C27CCE420B1F7FB14E119BB5951D23E41AC6924481DB71948DDF1073816F99BDD68FEDEF9219CA9D57AF8A4D449994E3249DCDBEFD5A59FAFB8BF000147182909E7B20D33452916A60351C6D2A9B82899C29A127C5D8615DAEBE384EF67ACE94329BC12E873644CB42428CCCCFB917763823D09B826922F4709EC78967A203753D20DA38BFA45228D93757CECD529A27A60B200F4864D03D40F70C33975AF6D3BA770E03E6C26D7A6FE8D6C2B5911221904B6F45C7DD687AC6B8EADBA292131FDC58841A76263B97976B9A6FF7A0516459B9200BD3A18BAC07FD59D7ADC5DF1E830B259751877EAC0FC4BB6064C18D9E70410AA312A537799B7E1D9FCC532538600175D1EBA758ECA110AC7BDDAB5695E0C48A56EA6E02E602F9A1D090B712E0AF3D840811EF698CD3FAFB648A4D24CF4B7166549BE5C704725731624A247D69EDEA6026E2A294C75BBE0B3593CFABB8087BA3D00585C45F83FFF6FEB6018B1DE2E39A41FF3FC54459B846D0C720509CA032870FE1FB996A304828467749045C82B29790505295D4F4E929F0F3C7FF2FB49C0AA249C462B089D8B3EA942D1D805508705CB94FD8CC183B957C9A17D8BD97C081F0FA68526ABDE22940DF16C3AB72E96364F4E870B7E085A3BB50BFBBE8F7664EE4FD6730001D2DE8757FB0FB19FBDE26A04B45F2DF6EBFA3249976C636E3B51FD515C1004456295A257259C0F4EA51AD8F47D4783259AD39870D465C39C58AF0164AC2CEEA9A8E85CD8C16E67E9298C96398D0956D4859E731616B55873C5D2509510598AC04B2B9E7FD0051CE446D67A908D97A382A62E65E3D4FC4D4D4325B672E15C588392A24EEA01DEF6731ECE04A9BDB957842707BAF1037DD937C7CD15FC5E5250EF4243933C9F47F877C0E50004DF11472BD6A2D50711E098F3A7AFBE78A1BD958020C50BC2E78C8B2CCA141ADA70F662F488017F437960A7DD649F4FF9075149B0A83A9F48B8F38A3C7C7C4595C3156F977F37DA9062FBAA655D6A8E332BB358748C1212037C4C98A2AE667532BC95633943A4789DF2B3E4531A39A67EBE025BFE7B14155BBF61551BCDD88EB148F597D6FC5972E306DAB4A4D74F2132BB2DB83093BE9791F20F56410093D591830D8E67D78F18380F0A960B2905692EE66DF1F27E95313C3C4EBEFF33C9078D97BDE63A7510CAF31B1705D81FDB573690516B9D63FFAA1D8F559D6305C75A5BC85F4CB2786DA97FB9FED79A9E6B9B7F4B6EF42955D5D13A40F983F7BEE107BCCAAE9CB10C5E8458B5CFBC42418A1C6035320EE092D73B430662643C5B733A8C9376BB507AF33F5562C7B0676450F1AEA83531CA53C142F4D77D88E3A01C34C9BCA257EDB7F99C562DF2F52FB50ED7E9F53F53887BC373A26260C893AA9A6A1D40764DDDA8CC1F102649E3F520C8DCF439794C23CD047E0C216FA250243552FB73E937555B8E00EF0FC2DDE6710C7F25B55B6C4D9960BDB4DBC4588B93E2C3C2540C0376ABE9C6FB45DDCA1B64327A03531F31573ACF6D0BCD9A1A59E4A962B5AF4EF29F4DE5891567EACD80F575F9FBA578620D2AE54AF0656C3213A2E0312B2A0ED02255CE196CE45BFE88329318389E770951690DB2A5C2AECD38D2A6AB3794C2069559EFDBD7AE3892749D9F20DCA60D12E3D45EDFEDBDE106B5D9F1EC8353DB5601B22EEA34A9D0529ABF980641C51E24E996BEA818A7C1A9FAA3656302C275B208BC89B3296A8E76C746B81F9A9BA34D6220EDDEFBA816811DF54B8BC35BDC2B31330988D7556696BE0FC786985DDB4A9F1690F5E6AB09346FDB8E095F0D0A5EF8B88E5FA8C16A7C0DD2D0DC91407D998DF36A83733D4968E4EB695DAE309166B1F23503A420D76E8BEA55B4A5376323FFFB316B43CD36ADC5B009BD3099AE1184550612CED253D9A2EB51C80E62B98E88E1FA5690CAB676289A76E2246847339E3A1AA3B08E837D53DD60305E9BD8095F923C7EB0FB72332525017263927510DF9509CCCB06C651660DD97957A5057452406545114225082B00E0D65DB826D2BA3ABE2596149C909DFB086B6353C4B0B047B4F42FD29D35C73FAD6E50C81E09F2A16555088D933AD27C32C6AE005F734C5D37A4033FE3E14BEB2B26DFCAE7962A2889F1DC269876A67C52CA90D8DBA008EAD042739727C507AD85EDAB0213D46252999C0066A0F43CEE7FE4E7DF930C8ABFCA4F594C24CAA6C8EE35F2E2FC0E7ACCCEB30E35E4C452A8AF92FF6672F236964F7B0C03430572C2BEAFD3345FCF6718E51AEF30C60F4FAC9F9580CED1429E3FF3F08EB4499BAA86C6CD1413BF183AA8FF83AF3DFE7E221422FB16C255B2C479373FCEA0299242C814EA188183F83627B13C96303AE121C8DC1E1F1BADFCC83FFBD5D8504FDA +CtrlOut = hexpriv:23A578205289555E65DDF567601CB4715FB593A7796A8F71D668C3BCA876D93760E9741F5FB8A68B3C490B93E4AA0E5D82206EF3B8E2242E1BCF4729F2E146AA + +# --- ML-DSA-87-Ed448-SHAKE256 --- +KeyGen = ML-DSA-87-Ed448-SHAKE256 +KeyName = keygen_MLDSA87_Ed448_SHAKE256 +Ctrl = hexpriv:72FA1D691964729C9A94AF91F6BA94483F7908D6CB79D190FE5B3DBB9B15A3D7C9135C4A75AFA6B08928660ED66480121065B529FB9E1F02B1FE2E86DE38889DD721C4E975DADEC088868CBA9684819B6778C1DFB8F2A51606 +CtrlOut = hexpub:E431AFB3371D2CB40B06D0F8F32A6C915A3F5DB6C397887721FDF176E95CF8DA9A3E0A24AF68C535FCBAE2C0C68765F7512AA2DEF8932BA354C8597F6CE996751A65EB2C2E515DF44C6F60010569B706350E0D0AAC0FE8770EA142810BD81763D61FF94C1262DD591261FF938B404D3AFD082AA70D18B7EDFF9A8DA9973F828CE4CDEFEDDA712D429AE4195EAEBEAA4322118DE6907D87701101B247CAB1166DFDE9E2CB74B76ED28C3D8316E9DED1A3A2BA57FF589B31678CAE48EE834BAFFF7A1E91C5350134B75D4F90ADADFF058F84D032B41FA74131FDD07ABCFB1175DD4F5F9AB872CB99BE84D8BAE84909B50AA945E077AE7CE9080F8F33EC47EDAE4FC294C689020167599832BF7DFC473B4F2CB6059073708BED191CD6ED168E56F32154DA47C2AAB92FD9F343D5B69BCA2415FC16A464E002BF843FF86982DD36454DA03AC3C66B7B3F9B55FE68EBFAE83F3608B053840914BA6461BDF67BF3B5272331284DAC721085894AF51A47DCC558A0383806C35CBB1A5D48D922AB40390231C43353C672A15FFE966BC6ADB3A0096013EC2395D72C861BE98D15F7C57DB70D556AAB4FDA5623B23816118A41A8C2DD47E4782F672597271014E8041054B626DA478CF509E3FBCB6DC49351119C91AD26BB5AB49D833068913B4E359324F97410F5388B0B927F55B4C29BD904E6DEA6C754033BB18E7FAC7F92198C39248C4F7F01555175D07879E32B17656DB3E44DCD5ECCEC8D0E2CC2AF59D2C3A5850BABB7AF92005CBD26E86F29EE385C1BE987AA9ED0A5D82B645267F2820E735731F1D75242511CB29153582C0238C4060DAC7A2FC9C201447F27DF7C59CC4A219400A87572318FB863ADBE7146D9AC409CD77D654FEA132A790571D5F4497B3869AB8802D7FD4AA9C48A79C0D6D4AB4572A3088E44BEADA3C1D210B7834FB99C64A7B8F107975922249C6FF5EE7B60DD9EF564BC4C5B1E5C065125CB2735E0732D12F71AF689A24E220C22BF5324E007B4B90F80BAA64FE3FA58C4973CF6CB2321A5BF779B1441092C578FAA7238D4C5140EB79A361F638F4C5A7D5DCE4008C55F242E099DA1802A985F2339E4930EFABDC8265B535A31CB5F7ECA8EE087DD67CFE5FC214F51F2C893F86BF69F1060C1B1D25DFBBCF4BD5F9C192A4B950AD1EC42460633E4AE118E0D4D0094AB3F5188A41D59FEF76B0DDEE805D940B7F6551FE702653FCCF0162958AA8B18208C2FABFF88E0CC15A308CF9F9FF9186174C084B66500FBD3DB6BEC3B8A315EEDE69DFEE11C4C9FA569DBCBF9DD40FF28982FED20DE28F446035707CE1540CFBEFBACE154163F779D4D7A6F39065AC84B6A8580A7E8221340C6E13E42EC9C2545629CAAA1F20A57C3BFD9F45A08B4CEFAC83CCAA37F5BE7BD4780AD7EE2119117D95F4ADCFA44F916FD98772FA706BA99B25A295996BD6C82E82B61B7B97799B2D4EA222F66C58613EB62744FA4D7F573D12B9BF5FC7AABC2CED6BB037AF7CCFECA27333E29F251CE31514AF0173804328BFD51C1C6D2DCD96A7F43A94C223F07E40F5F16C0DB614447B67BF380422206B74001AD4A4FCFF066833922585F5D8E6D34E85E4E290532D3F9CDE217759B01EB6E3E668EC558778C433295FF8A67DCE72996AC893253C4EDAB10594E45600DD8C4266F42D37B3B6B888F7025C832CD22189587F66D7476C42D679CE2E61AFA84C90791FEBDC0C3ACDD08C88E6DC9638F1E55273F6EBD7626A971F24461D2A06E3B9125EE509C9BD7351FF6225FEF61A1A26214BBF7E3F7BF69EB34523317D79B47C46169D867534104E189E5D2B63FFB4F61334571012CF48F5548C8F7B932D1152AF5A995EEA929189D2788C0C92278FF95874A767BA039571CF13C6D784CF97B586E4A572366AA89BBEFBA23B1262F0A9C9A5C81F4DE927F4EEAFA886D9E0EA19A85554BA4512A01C61FA6C1F74E2A2D9D67F5AFBBB4947278EA663809653CFD2D2152D67197CD56F44C69461B7C1BCC420B61E969E78ED8752D223C2E8E9E004597504F80257B6B5BEF0317A60CB9F146FC2B0FE804F92AE82696F2C138D95F2E40B9682B7A70942C4CD98FFF15191D200CDAAC6128B7B26C424D7F735B7B778E6DFF578B1BF38F2647124D038DA623B23FF0A56CFD357878F18E8B30081C42D77B5F54D5D7BCAC0B6FA7C0DAFA3445845B0F3EC7B10CC4FAABD90793AEFCEA8035A41353A1571A20E733FEE860A9A6015FE0516B6611849D8EA3D1759BF98EEE4F22F5487DE81F6E77E727E1CDBDCE69D22D0F1F471CB5391E9AA1BEE43868134CFA6C1D743690C3959A0083E9D560960D64391165F8FB48DB689D7EDAA8DF3BC663A8045E878413913A72AD6F4DDA96D1A0582A97CA2BB4AC88DD9FF57B544556DD19776221662E1B3B499CD3DDA75E52A36E757B6D9EEE6C676D1583CC524668E8CFC1230858952E4843B3BD3B4AF21251DCDB7743CD2843C704C0DEE3AA308220B2BEC91920A90FC6A591CC65B4582CA27E93CFB7B923FB9B1EC1BA60696DC8CF5766154FF3AD71E500FBF9AF0B934ECDBB9C78B8D80E92AFFDAC2D2439D542C19DA47076423905B831D447EA78E5B00C2AC08F3B2F988E31286133A2E68643951F3017B2FEAD95A3C6C844DA00B41CEC20BB1CEF989EAD3E44B524D5A8D5C6359AD6813F778406764441F8F97F69C1F9B13855B7F69B4020DC3586C7B15A387F194DD5311F51AB248C9560938B8F0E7F732B84BF8BE059F47D7DBDF02CAC5992E5E7B0ABAAF4081A1BF6134ECED7B8C82483CABCDB99ABCB8AA7B57A0B30A044A30A0FC5B036133AC04824550EF822EF9CB476FFD85F1584F74538283F7C69CD001910083A79FE767B0A37E7026A076FAF971CFF2E08D0F0452B4C8B42BBAF89E8EA48882CB141BD29B95256A4824620E767ADFA66613DB0136F48D901046D92CF72E7DF09B4A2B2D71B94CA1FC1F409F3ACEAD0783E27F04A23A1CB4C0F25F20AC4469C1480AE1D0DB3A0BB97D3E6C9168A2EDFC2AE5BDA64CD21F110D9648799C030A4A3097C9E9B21453A1645028B3F3A4DEE1A2E9ECB7CCF21D803EC4873420A73995DADC319A22D555B4A7E6664515456A27B2A22240AF68E2E27CB0EFDA4E798B6CD7B17211E82163C5F620B2AB36AF7E625F9E86CB067682C7D1EAFE172DA638B465D3C9DCA6E1971FD44B192993EC328004EC25480EA2C46B3AB7E8E3CF3DC91536938F6600D835847137827A9B50C6FD7AA1365BC1D5BAF7B3013699394E6FB80090F341D1287390E93ADC5B3409A56BA90339D029B17662D19F5AB3FD0EE9B6F0D01F1F5724A1ECA95743953FF63441192A646C50DB9113CF7EFD979602EAD4CA30F6B369B85104FD4C163BE6B3B8EC6D32186A592A62FF6C452A8AB27FC97D641FDCD1746F78E2A0F6E24733C20B89B2AABF13D488B9851755E7962978D08E4C393548762987FCA579B25F1E258EEF688B917A97475B350B1C570D69AA1776123CBC171BAB921F29E0CD82001B58444471158A463F9C834AADA291651451CB9EB0075395784B3D3B1043B9A603ED170ACDA24DDF1C3A7C12C3F1CBB158F7B95EEC29E7A1DC4AB9D49857392711F223AB9AEACDD64F18FEB1793D1F83245A990E576DE87F1AE289048961FF4826DAB22F2F6B91A756FEE4B28A3AA34B6DEACB15223F0AE2C0B761EA20FF6E437A49EC157EB6A778B62BBFEA8B71A18184245DF8336FBF3D6A89465E5DC5DD1D0B61219905100 +CtrlOut = hexpriv:72FA1D691964729C9A94AF91F6BA94483F7908D6CB79D190FE5B3DBB9B15A3D7C9135C4A75AFA6B08928660ED66480121065B529FB9E1F02B1FE2E86DE38889DD721C4E975DADEC088868CBA9684819B6778C1DFB8F2A51606 + +# --- ML-DSA-87-RSA3072-PSS-SHA512 --- +KeyGen = ML-DSA-87-RSA3072-PSS-SHA512 +KeyName = keygen_MLDSA87_RSA3072_PSS_SHA512 +Ctrl = hexpriv:162ACB431E3DEB0D736946540F843DFFBB14BF957D5BC9055DE2F3A812DA0C97308206E30201000282018100E357CD609383CE1B20B72540FD9C5989E4EEABE4CBB8AFF2A750619BE230E9461F26504A18B6D389A0971EA44F6ACEBE396D33ED2BC203C6CC6BB544719690FD6370A862A6831B0B46C20B6F7C332281EDBD74BC2DD59E5A5C43D9197970587923EECF81E4D091536C175D45B9F312A4821926E70DF889328E6D8352836A045EF4B7A0CD9DAD414FB46876A69CD8710A46AA19F88C6AA2F906444846E6A744B1C604BE365C3C1D05C913B8E1693DC49D2680EBC0811262A786E3608D8BC86692B4E85555D73121E6FF1C1F66C15DE24290D152E797E2F391CFA69E2405A185A78A2FCEC616C0E329335E36CE867B3A91EA43367E26E932F85513D2560A5E656038DBA2190B7F1913D6837F70825E6A0939560E7141024E90211958145EC1F94CE18D9E8C009E19DB89FCBD2B9AC76770CD6800EE6AD144A7F164F8A3DB4EDA79D38054F00110F7D7FDD7BFC5298B332167FC556B9A2404C621FC32B3CC5EDE89F1AC17D49D799FE865EB83334545FCD5F986795957FA2DDF5FADD7A4E8FBB81102030100010282018050E6FC053439A16CF1F57AE267DDEDD72E8AE8CCE0DA7672A9ABE7306C0BEFD7AE5A1A14643B1B884C87BAB5CA353E215F9A46F24DB21B59F1811ADEA2756C5F5FB5C596659F1E4EA2FD86C843B086C529EF53CD6B9A2B6208977478A6489E936D801C8423033DD42C111C7625B824983A5BED0628689B9A4C2918A4927375DEBCC3640C07E291ED654C0F7D372FA6FA7B2F2952D3D556EDBB972D095E278440A73124E77F673D04C40BAAAD3CA068896C1C50C90EA59649FBAC8ABD9452DA7D0AFB40F0B0A39C8FC6018F2C6EE28046E07D0B3361B167E8034F5910C8C53BF9D7F00BA51C0FAA1836FFAF1172723595537D0ECF1950B553E2BDB289791E38703848CB7D15472226419C82DCDC3DBFCACC6569A214DE17F99A366BAC705B6BAE3424F47166CE5725218407AF3A4F0698177D680C563A95E68E2E7A64D8FD58E1791C6D02A65EA25AC26F13C145BBA9B29491C17AD15765F7A62ADCE30F9F2EF0C48E3440EE93D34ABD84068CF8464A038718C76D4CFBBB7CB0463B9622FD4BA90281C100F62113948EF5473CBAC4DD7121A3DB15BCDFE93C263EB8855305A4407C0F54DB466EEA3C2D3F8EE3B7937937EFBDB68296300C22F21C862CFB825CD6EF6B117B1F1522860F3D2270B202E5E2B3EA77F107730CF641335510C29AB70EA69A4E205EF7FBCE36259E87EBE8C4324E17112DDDF82BC386F3D6E6087DEED32A0FAA27D8B948CA3E8A59EEE43FB7554B45B85830B29061FACA9C33524EEDD78341DEA2732462C48BA039369394903F8249C70731F7A0472D3EB72CF93094E82EAF21CF0281C100EC75DAA3D33D7CCC713E3D596C8AF269F5C6362F1C7F43ECA4107953DA78361EEBAD5BD24BCDF79B602CF01CE243A12CE356DDE992CE7D74BE137424FD67885648FC7C0A7DEF4AF20BD1730DEA42E6B1D2D35FE2DB19AC55914B7A81A58A37B3D56166DEC5F9160456092882E780940123C1F1A4E1FD20D1DE7C34C9200B4AC3E5817415EA8E12B5BDF6308530D40D52B53B587E3B04F05DD05FAC75C1CFA1166A1A48346A66C2E4A839715981D5D50F821D9B1E046F1AA9C0D7021A1C97601F0281C07F53471CD003A5118E90EEF96A6CA8968B39CE1F56AD95A92AF4BD2EBABEF7A7E3BCD721C04AA3F1BB72E7FF7EDF467E3191B38594781B15441B014A135AF1151F5440A2D75949EAC0BBED0EA502438005D987B810ACAC71DA2A4D4E9FF32D3D63C3A798DABC0551CD4181D5803E409DD8B95C726EEACF9DFA80A33ECC008486CE7FB35F24914FCADC7AF5AD831E132A542EDBB0441BF2483E6924731BACC4AE8720289402A32555CD6CCA5E80590843F99E5F64D2CC21D87B249DB3AB0AE0530281C0234112FEF7E0A3F9AB2C9762FCBEDE9393B420A1F782B5F2D3272D9FA5E3E455C9D787E81BAB32AE74B15E7F3FF0CB57F0F12396CE6F80DEE5F3EA8E1545D95ADBF8E0D9839B28B65BB2B78FAC8C9AEE8A3B3F81881F14C5912B0AB1C7A78AD4820CCA948E39ABE1AB9E23EF186AE0262759A4186C251C3E8E0840AA77DF971F0BD9B820085F7444AA74C91922858B12F8B84762529452EDF9C239E938A327263B5D7DC46AD4B55BF804D07482DA09B10D3A32C54FEDECB0C0728DFAACA6990B0281C1009999C3511238DCF6A94294104E696C97E3AB8E5653010846377195BD3E89864E47B9297465651B6A37E420C51F50FE76F6BA25B36E2968119A2A5BDA5ECE7A25199950E614A44FB83B0C069479BB183E69173FACA51011926E25D502F17542F1EBBEEF08A86EB1AA30DB718D8F577D44E089F37E5B3F0BE43D7ABAAF26EF5B6EB323768215565F72A6EF7F4DD8549647E3FBF914F4CD72C233E9DE4D9CC72B1D11A436A590D5565A88C380303AB392656604D027D147624B9EC22E922635CA7C +CtrlOut = hexpub:C8D67CE17D1B6E2D42A58CDE67CA5559BEDFFD8071C670A59F55BA500403C045BCC7E112C32BEFB2BADAD7C2C5C1165DD1EEE71769BD6F55C445B0F56EAE08BA086F4B33190EE88F1A750BE1D5772884C9492458520206227615A41C390448DE2BABD946E0DAC1FD534C9E828FF595EF6D8B1EA2CFF5761153327B7542A36ADDA0BDFBCC0F025734BC01CC11460BF08FFA1118DAF08D9E63AF8C3505EF0AFC034030DBF27F439EEB154F4093ED6FEB961EE38C1E0E708A2868F9B6FD9D61D362C107DD2B6AE9E0E03FEC2C61C71311F196B03C0EA94576E2EDECAEC9091DCBB72F8521B7284C12FB49BCADD3636996DC76FEE9222B2197807E1161849137F0EF5D2E35EC3544CCBF645C2C3216E5D6F7A68907E91F917045A20E193958A5D555EAEE0E450F66D8B16D36A97B34EE324A6F979CE712FBBB51391A97A340CD7097CC3A0E5461D38583AFF0F6CBB8E93C3137835A5F29F70EF1E91CB4A7A9B10F6A796AE2E0B48556FBF940F536ADFEC55FAACA2532776E43D536DF2DBE2D10F254E4C87FC4263C48C8FE5D684D27402EC18BCD8E11BBB5C1A75CACED4EC11BB4A5C7BD1725F81B46CFA9A49B1E7CC0701F2369986E507C9C8DB22B4700ECA593EE96AAEA7BA7AA503438E1AE8EDEA4B1B02B1BF328A948229CE7732325EFE02743196588E46CA1C53A7958729DEA6BC0E8349C15EF5F79AFCF5D71D05EB56ED6ECCD7B10DC089DCEDB85511757917B5831B88FA719A0E832C9B2B1767F42706711E772766D85AC16F7A542852157C881809DAB72573010EB7241CAF692A4DFC3BCD1B99FA025E582BE90579F31BBE2C44A0DC06583DF38EF4CB9BF43378BE407E07CC75E589E2FA59D1E7BE1C41D73B7A654FFAF701513AABD63AA50D21461F7A54FB7C1BAC72188A0AEDA82B8FB6B2C2711C1653666AEFEC32F455DCBA5C707A79CE2CB2908F6B914FD780EA23CB31BA9FA4ABFA2B0BB0DECCE118267252595E4B81293BFA1F6080D150502AF917F0C70CFC10F260214BE6E76C066489F0F4A8CD6297AFF54BC63339AC55AFDD76B3AE496BE5E7E6E2FB078A4DCAFA0BED4C65474CB539B9315EB1BEF50128C37BC833AC28FDD1D8C30E9BEAD05074994173E65B9A67054AA3C4C32B3F852316A29BD6E716E5222B3252EA9E3A71DF4E04E056DA94554CB201635DD4912C650351020384970635BE17DAFE564C088B80DF6A39B1B27EA5CC25222095DA92B0F3417FF72DEE9F39D950CF532CDAFC93A8E532025DF7B8AA5BF183F99FE384FB42839494CC6FE642250A199079D1A9483A51C1C35F7339864852F61569EBE1CD6F4A3F88C8733A3A400727D93A09B2A6D0F67B8E1F5A88F76876C191D0827C8AB021E56ECDF7D249FE0C35CCC595E237D0661614C92F38CF41694A985F89432C7D66B9F3AB9782849D279737E49D06F4E7E953880E51EDC97D99461640505CC08CC75AF6A6538ACBB30FC8B5230F5DDC0AAA92559327E05353B64FFD0C8EC4C3B6DC3400A9CAD3964E302BDBCB4D5EF1A5C0464AF110D8B56A44B3F9534AB9590F1FC32CC4FC26A908AB63F03EB775F4DE4A3E633AAD89BEA128F6A5B2C46F5EB3CCCF858554EDB6BE7AA029E1059C6EFA11AFE0ACAE4C8B026FE616A66C4B17C508FBA013DBBB0CE09090CAB4F4BE730BCC1F17243CA7C0C8DAAA11F8383251240D954B5A70C3BCC4105CBFA463AC476E987B0553984BA8D1C8BA3295745DD94748DDAE5C7A300C30FD47EFD6C9045CAA12B1722A8129ABCF92BCB5AB8379BEF2E13AB697075FFEFA9AB14767B60048D702C258ECAFC42E20AB0C22E9A67DDF9E938092E0FF80AAD226C7A246B00E28134A590E9CB72BD281D0991803FDB3256EBB8803FE13B6C4681E67362C9EB6CA610DF8D3027F62B877973EBC32AB488BF56D8293D2709438C702364DA3F39C3EC563E04FEC44B880846BCDD21DB30CE0A72880DBF1EA5EF58F3F9A40ECF3838982107F9D1D2D22E0AC14217A6EA6618D3F6FE7A5B73FD823386962665DF54157169CBEE7236A9ED83D0FD6419ABAFF8E92B7644F6B6A019B42554061FD6E1F665BD0CE2686EAD53C98D0CCB56283653E6BAD9D0EBC1591DBE709B123A1B6E9B980346584077AF714AF86F699218F03CA5A22E4CA3C50D41890F86AB5ED30BACEC4CECE8BAECA0CB737B42067110B70D54E6F547CCFCE6EFE84613CD1E332A9104B6AE21E71F7B6875B63F9B2FB5557A5397D1BCD65A126814A34530E14D18E426CA65CD582F2F4AB636D487A2098229415CFE72CB14FC691AE2EB2AB7A63DB7410F15C2EF46A7FE8A1A217E195BF5B2C3C6659AEC9524E195B298FC294A78DADE828424D311FD9DCBE13519E0A3C2C49402255E441B1354856FCC47458B635640A32FD8465C03DCA97FA3808E83AF09D8EAC01838E89387FC8EE99C49AE58F62DF2FCADB83FDA36A41858138B2CE4BE9BDA5D95BAFF17BBA6981D82FC783FE1B3A90DC2B4D2559684CC92CF91CE508FAE1DD556872C0922D74C1A469C593EC2DB170DEB2FC16CFEE2D34D4FF57D2350A5F4DB04CD01BA0B2515C27CAC632ABF168C077B32D04E7561DE9702EF77EF594E98BDCF3504AEE7B0F56C9636C47EE9A9E999EE8B45F67225BD07EE7734BDF487DF71FAEFF73A80881D75641D89237C4334ABA408780B723B26E04215805AD7EE06C6D4B70DEEB19D4CCDDC53CC0FECF9F8025091D3BA96CE1BD2F16C5892F892E28253276591035C390F951ED2CC2753D7E0ACD9E88E0CFDA4534A2D3F500A27627D26695A92CABD79547934957D36A553C9EFBF5072D06E78C0F4CBFD9CC43389C4E739021F8DF9B2F6B468840BDCF7ECC0DBC55B17818C87ABC2481F12A38EB4D7E6AA8ACE43E910FAFFC7896C06FCEA4384F6C3871E44C3E53048A172E2F4197A7B7A3B83CD4F490710DD3C3ED3E00C3D1D77ED2B8305F2837DFE22E32B6FE0E0CA502C53A9B504A0815A51FB6815AC41E01B20D7ABF4E6CCBD6039755F4DB6C31233DC3AA4705452363A4D1C1839054C8A0D75305AE0936D3D0F5C597612705FD5D912805C2F1EB6E46F52224AF090EC214B30314C03050772B591B4AEC6C59D591F3881FAE3BF6CCAAC2FEBEBA1EDE83AAB0DA60AD99D448BDADE0E6CAA54345083808D7385C59C89FDC13767FE36A40D9A657E171018BC4B88063853963FC5F9DA74A3382D66525FFFB8A8A3D6C52C1EF769A43FBD9889E459B04C492A967BFECE670D0ECE1FC0D0C22723430BB90BCE7E5C89508D1B1EA0F32D71F2ACF133999B023128D4FD830C878BAD5FB6B92D2D3435FE8EBB4686184B9236BFDA00A3A553DB092EA9EB290DA6FFA3BBC93249289FCFB0B78C4D4718B86AF1232A02EE4909D966F307E8DBF893C1D3453950D3CA9DB2AF83A2A9A35C4FADFC0DF9F7860CF84CF627F17586AEE38FA69A927157D23EAA132E9DA7B73B45B6AB99E2DAD24A21BE67FDA1679E4C8DDE6742F7348BC0DF981B69DAC17A78FC9242397C3A84DBDDABA51B09F240277615C4B3331D17A21EA44050766C9CFF15DAC1EF6B0FD6B3A01D72B0B2AA081BA9967AB7DBF83ED658CE4F923936734D707C82C684FD3872B770FB54C30D65326D8D0A5890A94F564FAEB6A6F16FBC0379BB99D7397B390E24492F4DEE2F3A636C452277F76F67D8183082018A0282018100E357CD609383CE1B20B72540FD9C5989E4EEABE4CBB8AFF2A750619BE230E9461F26504A18B6D389A0971EA44F6ACEBE396D33ED2BC203C6CC6BB544719690FD6370A862A6831B0B46C20B6F7C332281EDBD74BC2DD59E5A5C43D9197970587923EECF81E4D091536C175D45B9F312A4821926E70DF889328E6D8352836A045EF4B7A0CD9DAD414FB46876A69CD8710A46AA19F88C6AA2F906444846E6A744B1C604BE365C3C1D05C913B8E1693DC49D2680EBC0811262A786E3608D8BC86692B4E85555D73121E6FF1C1F66C15DE24290D152E797E2F391CFA69E2405A185A78A2FCEC616C0E329335E36CE867B3A91EA43367E26E932F85513D2560A5E656038DBA2190B7F1913D6837F70825E6A0939560E7141024E90211958145EC1F94CE18D9E8C009E19DB89FCBD2B9AC76770CD6800EE6AD144A7F164F8A3DB4EDA79D38054F00110F7D7FDD7BFC5298B332167FC556B9A2404C621FC32B3CC5EDE89F1AC17D49D799FE865EB83334545FCD5F986795957FA2DDF5FADD7A4E8FBB8110203010001 +CtrlOut = hexpriv:162ACB431E3DEB0D736946540F843DFFBB14BF957D5BC9055DE2F3A812DA0C97308206E30201000282018100E357CD609383CE1B20B72540FD9C5989E4EEABE4CBB8AFF2A750619BE230E9461F26504A18B6D389A0971EA44F6ACEBE396D33ED2BC203C6CC6BB544719690FD6370A862A6831B0B46C20B6F7C332281EDBD74BC2DD59E5A5C43D9197970587923EECF81E4D091536C175D45B9F312A4821926E70DF889328E6D8352836A045EF4B7A0CD9DAD414FB46876A69CD8710A46AA19F88C6AA2F906444846E6A744B1C604BE365C3C1D05C913B8E1693DC49D2680EBC0811262A786E3608D8BC86692B4E85555D73121E6FF1C1F66C15DE24290D152E797E2F391CFA69E2405A185A78A2FCEC616C0E329335E36CE867B3A91EA43367E26E932F85513D2560A5E656038DBA2190B7F1913D6837F70825E6A0939560E7141024E90211958145EC1F94CE18D9E8C009E19DB89FCBD2B9AC76770CD6800EE6AD144A7F164F8A3DB4EDA79D38054F00110F7D7FDD7BFC5298B332167FC556B9A2404C621FC32B3CC5EDE89F1AC17D49D799FE865EB83334545FCD5F986795957FA2DDF5FADD7A4E8FBB81102030100010282018050E6FC053439A16CF1F57AE267DDEDD72E8AE8CCE0DA7672A9ABE7306C0BEFD7AE5A1A14643B1B884C87BAB5CA353E215F9A46F24DB21B59F1811ADEA2756C5F5FB5C596659F1E4EA2FD86C843B086C529EF53CD6B9A2B6208977478A6489E936D801C8423033DD42C111C7625B824983A5BED0628689B9A4C2918A4927375DEBCC3640C07E291ED654C0F7D372FA6FA7B2F2952D3D556EDBB972D095E278440A73124E77F673D04C40BAAAD3CA068896C1C50C90EA59649FBAC8ABD9452DA7D0AFB40F0B0A39C8FC6018F2C6EE28046E07D0B3361B167E8034F5910C8C53BF9D7F00BA51C0FAA1836FFAF1172723595537D0ECF1950B553E2BDB289791E38703848CB7D15472226419C82DCDC3DBFCACC6569A214DE17F99A366BAC705B6BAE3424F47166CE5725218407AF3A4F0698177D680C563A95E68E2E7A64D8FD58E1791C6D02A65EA25AC26F13C145BBA9B29491C17AD15765F7A62ADCE30F9F2EF0C48E3440EE93D34ABD84068CF8464A038718C76D4CFBBB7CB0463B9622FD4BA90281C100F62113948EF5473CBAC4DD7121A3DB15BCDFE93C263EB8855305A4407C0F54DB466EEA3C2D3F8EE3B7937937EFBDB68296300C22F21C862CFB825CD6EF6B117B1F1522860F3D2270B202E5E2B3EA77F107730CF641335510C29AB70EA69A4E205EF7FBCE36259E87EBE8C4324E17112DDDF82BC386F3D6E6087DEED32A0FAA27D8B948CA3E8A59EEE43FB7554B45B85830B29061FACA9C33524EEDD78341DEA2732462C48BA039369394903F8249C70731F7A0472D3EB72CF93094E82EAF21CF0281C100EC75DAA3D33D7CCC713E3D596C8AF269F5C6362F1C7F43ECA4107953DA78361EEBAD5BD24BCDF79B602CF01CE243A12CE356DDE992CE7D74BE137424FD67885648FC7C0A7DEF4AF20BD1730DEA42E6B1D2D35FE2DB19AC55914B7A81A58A37B3D56166DEC5F9160456092882E780940123C1F1A4E1FD20D1DE7C34C9200B4AC3E5817415EA8E12B5BDF6308530D40D52B53B587E3B04F05DD05FAC75C1CFA1166A1A48346A66C2E4A839715981D5D50F821D9B1E046F1AA9C0D7021A1C97601F0281C07F53471CD003A5118E90EEF96A6CA8968B39CE1F56AD95A92AF4BD2EBABEF7A7E3BCD721C04AA3F1BB72E7FF7EDF467E3191B38594781B15441B014A135AF1151F5440A2D75949EAC0BBED0EA502438005D987B810ACAC71DA2A4D4E9FF32D3D63C3A798DABC0551CD4181D5803E409DD8B95C726EEACF9DFA80A33ECC008486CE7FB35F24914FCADC7AF5AD831E132A542EDBB0441BF2483E6924731BACC4AE8720289402A32555CD6CCA5E80590843F99E5F64D2CC21D87B249DB3AB0AE0530281C0234112FEF7E0A3F9AB2C9762FCBEDE9393B420A1F782B5F2D3272D9FA5E3E455C9D787E81BAB32AE74B15E7F3FF0CB57F0F12396CE6F80DEE5F3EA8E1545D95ADBF8E0D9839B28B65BB2B78FAC8C9AEE8A3B3F81881F14C5912B0AB1C7A78AD4820CCA948E39ABE1AB9E23EF186AE0262759A4186C251C3E8E0840AA77DF971F0BD9B820085F7444AA74C91922858B12F8B84762529452EDF9C239E938A327263B5D7DC46AD4B55BF804D07482DA09B10D3A32C54FEDECB0C0728DFAACA6990B0281C1009999C3511238DCF6A94294104E696C97E3AB8E5653010846377195BD3E89864E47B9297465651B6A37E420C51F50FE76F6BA25B36E2968119A2A5BDA5ECE7A25199950E614A44FB83B0C069479BB183E69173FACA51011926E25D502F17542F1EBBEEF08A86EB1AA30DB718D8F577D44E089F37E5B3F0BE43D7ABAAF26EF5B6EB323768215565F72A6EF7F4DD8549647E3FBF914F4CD72C233E9DE4D9CC72B1D11A436A590D5565A88C380303AB392656604D027D147624B9EC22E922635CA7C + +# --- ML-DSA-87-RSA4096-PSS-SHA512 --- +KeyGen = ML-DSA-87-RSA4096-PSS-SHA512 +KeyName = keygen_MLDSA87_RSA4096_PSS_SHA512 +Ctrl = hexpriv:78313380F340B18D1A17D58579335B6460701206F4F349AEADC32E95FDFAD2FE308209280201000282020100B303407B756BC67861684CE02B80AF8DDF380D24352E4D6401A39B926B98A7675B4ED51F12C4E7D39B576AEAC14850C97BBE046061D86A6453082CB492B09AB062C23E9736AAF3173C343CAF437459551278AF1706A986523B8E987EB3254DC54845DCE1DE000396A69124AAE1581AC722043D7ECC8279ABF90F547811CC1E768A26EE3CE22DD6A6AF0760ED13B2E0E687D833A0AA10F2C07DE6258847AF1B77CED25A09B7647156478DDC2033E27671F263DB6E8CD49F0B506188D4BE869776138C237FAB5F101ED8FDD98F21E2952D2287EBFF5764E040E03178633437B2EBAAE40006FD161EB24BC7D795CDBBB224F100567AAF4F6AB8C0E24752015D69F0A3EAE6BDD34324056D06A1AF8E2DA7AF2C99386134994876756923C797FFF785EA6F267085B2B3D2F55A56BCC2A423A7A4F4C0490C6DE369F832B74E21B0E9EF2D9342B78320391D7B18E130DBEDD41D3F2DED060EF7CD3BE300CE57CE89A9FD5F0D64BD2E06BD4285747110165474BA6A9ECCA92FB246AEB5CC5584340003A10E6B28AC2B43AB595C62AF395439248F3B8CC903B8BAD134D2825C01757FCDB9173B6258264176D520F5D340F946E9404880499884F4C86C379B48FC5F0266AC4576A17091BC797B18C356C4E88FABE02B58684B2E8D11E65DE63A7518598BEC3BE0CD670E64ACA93557F4343FE02DB7AF30E5AE9A7598BA8643ADF3CBAB128D020301000102820200327E20D29200C7D70DB6A33479E0CEE3C80A21DECC2756C9F612655FCBFC9F7F6E4852A1F4A3D8B61DB36F236F484C0D40DB8C957913D7929BBF0B0915F53D74B22E930408F5F8225E2767D491C4C02BD84D75299C05F62EBCC0D06FB06D3DBDFF504168EE3AF7C8270C7A98BE7E20F3793B53F32F913FEB8B9150E49B3485852F1BA308464DE2A55A6A4CE32232CAF00B7226C1D3267BAA62F8A72E84F5B5DC39D8A86FE42C2F31C476159879BA0F69BD928002F33347F72381975C56AF550A87A1F8235B3DB1A8D9D0E46C5484FA49E45B0D6C95048DA28EFA35385A32B9C3728CE41B14890838875A838B2C201CB401CC74181FD9D942EA9908BFEF459F8B3846DA2663E2E0051298E1703A9E75A419878E883E74E67761A1E8F972CD2E7DCC89767F246967E9DD7B77DD5DD9C22E460E933B9C62E16DB7EB8AFD2323C66D029E2D9AB9C9696D6FE41BD8A92FF989A0D6F1960CCD4BABB8A2F88A20C3C87393AE08CE4086660B4F88BC437C4EB9D08B10982F97395BBF4371C59020805FC9863BC51D5AE7CD6C976348152A8DDB2FC2F75BB525960DB2615663678DF60A6F58682D7CC00A5DB65F1CF5199975DE5B388BE586C6EE7593C3DD93B13D340136E1E152BB3AAA9F2E7EA5F540711FE4729EBF77F31F6650E5802E5C83CB75DED6A3AE48AE87946AB4ECA9A1CA254D3DD4955700E3EB5348B3B1F21FEB574ACD6B0282010100F7F3BB2CD2A1CA2C9E64FA3FF3D88AE1366F28BEB47F4D9FB967EEF6FF75FE60BD7E6299A1B9A5AF3AE53DC775BC91F5F335E77A030AA20757D96CDC369DE6C78AECFD675E72B6985434C085CB353E7F6E721BB1461FDCEACCE9A4ADF6501BB4F069262B40B175276CBC62D7760A935B31F049ED9C05434B775FBB5DB8173197E4DE7554B93028EF5A9F9925CA3046DF0A31B13828984703DA6CE5E3EA4D64A21D69659FFCE487EE13D54DC1AB01E4B0C4FAE1E4131B8BF4A21F9596C9A316FC278E20EFD828CF8B03FA62C22CB15AE5E7BEE24B7D067303668333458AD6EE9C1538DCFB4DD4B42D5554393C96F171E92273DABF369AAA07F56061BB80E03EFB0282010100B8D2B198FE1EB7B17B6FA395A16D64815CB2A65DDF944CAAB541A1027B60F4CDCDC3006430A379051FCA64C9FC52FFFA4CBA7228DF19D18013E448D27BC0B569470D3806CD56CEA0B14B5875FB9992F84DEE885B0827AA81583FFC7B11033B36A7D405C952FE8A178B14B1379D3B665D38D179A374249FF208F986BE276CED11E1388270ABB49273CCEE5996E463DE8B94E7CE9E5D1ED85FFFAEDC2908788AAE6BA0E5210EE033932DD8D12191ED863983C4CDAB9DE41D3DFCED9E8B1100CD5163F57F56BCB1E078EC2750079A77B96584FC2DC47C474B1C88C77BD8503323BFC732B2B164C6248BB2F176EE8F5E92E675090371ACF21F25C01B84B3C72C1E1702820101008D2696DB415D10F6AD84D66129B38FFBFD3CF278FDCFAAA4CEAB38022C1343A856B767F2057AE5B3075810FF472AFDFC8163A24E7704CA905B964EBE5DE92DC35276EF1AB54DA05CBF32F89631C431BBE167DC13E2D3A8B391CB401038340A51CABA511C364BCF618E29002B9FEB0D4FD0F1F563EA79A48185875DE6503203ED7040A3928389C303DF1713DBCB6A082E5863497BAAC0654CF03F25EFC52621AF9806B3EF8BCB9D060F0C52A379722E79E2E8DF4733096F76E8040AE838093BC077D41533F45DE728402F7DA104484272B6A697B4598C1E55453A5329B78BFB71A73323B97BE92658D84685FED3FEC6D5ECE2FF17F341C0A19F322AF0CEC0D999028201007960E581B4623801372F7A1F2A84CD1CA7E42B9E3AD70A029247279699B0731535AC7AF5517C0A5E7322584ECE8733D50DCEE46A331AA19B9B74B0DE8AA7647C5F4D2F1E487C59F6EE78ACFFCEDC6CC8E56561E766D3A6068C0E79A1D8EA6658DE9F3FAD97F3D27CE3BA132892FA0F9FE950A8B1CFF4BD96168EC90ED895909BCD6D6F3CCF87272725CEE2C755F6C090AA9A11F7AEF032E9D8E0DD75953A94D93795D2E483007ADE8D9D76BAB53B688B1D1E8273D29D9D16B8A4D51A3F706766AC5EEDE1E8CA68C101565018AE393268998D8401261D2C16F13D10F85EB337271B8B100FB03EF0814E6385D7E6101629837307EFFFC482F027D9EAACA68132C10282010007E555D6183A10D52C726281F08427520985902AAF170B3EF275791AF9D5B9A49388C8DEFC17546418ED74B3FFC6713170CA09873405064157D83903FA6B37FC90CFC2CC64ED54DD5BEC0CF3A35EA2AC9F4857B8044F02AD3CF0B814A858D213D87092DF216F81A52BC72CA138CDBF824CF1421848D34D02EA657568CD13E89B6A3E3D2CC7EBE84D40A5ADAE1C774D5FC6AB2C993DDF426C588600AB162C0B31F552459ACB054198C3DA8CF9AA5D93C9803A8901B30642E60CC1B03D04D02AC8F67FC2244DA70D00A0D6560DC682ADD50B7746304A50F3CC70D57B59E41174B495600899D8310BD407A2F1D95092BF39808DE96B5DCEA33EB61F10DC3F64ACD5 +CtrlOut = hexpub:ACF0712CA13A12FF8B8B249D0EAD8AA974215B67AD2D66736D5F865A0D5EDAE4634B9577CDFACA4C3057D6B845DFD7416FE897DEF380C70993C4E96F2A39C40C4191C9F2AB745640FB661EEB5BEB3F5CFF515A733CC17BE0BE5DF1D4028C7ECEEA91E16A8BD7FF91EA0029CC1BFE3C3D42AA04A8618BDCACD4935BA35BEC471C0196218E2B147D0BA41DBA0EA9AE8656CB6B9C74E24CB428DDC38626BFC010FF20613DCC37F349F2974CA30A3B3E5CD33557B09A58BBE5D632678C720C398BE8C8FE0AE1BC5F728B0C7E3468C5E35882530E82DEF6FD9C195D614A992283D7D96C691ECF682F999BFE7DF8723BC492BE70A0CBED70868772C62B89FD2B4AB97D3EA84D666D80CB849B14B25C2A14D848CDC90E1ACBA92D351407698B454532AE07C4CEED9471BB6B5D61B05A0592B70EC9694A1E0C5251650A65CC55B1D49AC89E58BA83EBC3AB8D6C14B3651D0F14D67FCE7535749431C58F000B23FABCD78C6C5CBA3F66E362EC80868FBA3B4D97D74A9F34EB18345E99238A525C143205AD250D0ADF5D9DA22F564475A809C64D387B7A5CFA4B73E8BB9962BF965E190882A4871B5B0158DC4B32F287B28887359A425FE04C3B34659CDE5993CE3E2B02A97383F7BF590947398E8463E16B74D0305ACB5ED32B72F282EF337DDBC85E5A484EEE8E9B29E79611C975809A6AE8DA77DC5D333DF89CA9221D9FBC5DFF07BC33EED7511EFA960E9BEE999693E83F8FF0925571BCA50E6E8878CAE14164D23D1F79EC45961ABD4B84A537C520EAD2B079EAD127A3C6402C59CB967A71AA16C4A623532A0C8D8076136786D11E83E5567F185E6A86CEB0DC0F878F43B81A1C348E902F0158EED3BCB0D098E19FA479913B0FCF7BB9758FDA6FE28DD2D19C2D5891ED53935D0D1E467F05D74C6DB326889BD0B12088C3EC7FEB633A412A9A3434239060688BF57349FD936C9740A9BFC2D5109734958B23441311FCF9B0C57209923956A87A5127FCD5F1646A86C44197536C05ED3A25E6ACA760373C4719C8B86F4EC0621ECC2C8C274FDD50A08B7BE2D95935E5566526F3C632A96F1330CC7A785FE001CEF7E5C608F2542225231563C00745AF15BEAD4BF5ED46A401514745F91E0A7ED6C52403E7AAEF8D091D44EC40C68531CF6B315740804FD48BCAE0474C7F5E6CA1E3A3ACA3E124B25813E4255EF7D49E09B0CFF382091D69D3F1AD964E04E70DD9353EDBA437B53059DE2BCF6D57FD521A2ABB8288D17EA95AFD61420D4E4251A901B8BD79C7A18B9B5B460E0787D5F583958167EAFA89A82CEB6D5A41388B39B26F37A41883ACF25AC0FB6FB72D2FA2F46735347DF660BE479F535900276B4B5821D9D5D4B2FF7DDF41A540DB565E196BFC81D3842C1119C54855D322D0E486B5076733629D998C72FD7006D3512021EC6DCA9FC8CEB580EAAE534C4A539753DD2CC6FDE5E780D36DA06A0C174B15B2BCA88A0D77C0C1CAA37BB03DFD28787392F9BDA063FE4B1C0DD5DD6254033A3717EC97EC836B9874A131370DBFDF10675D559213C1EB3D9805DA28E73EBAA24CDB984C3CAEBFC54D8EFA7B2443D86B5EE354FA7471F6BD7E33218492AC69419071BD7000A9BD666B46FE6CBBE50C3FDD31A133B3B21B9DE94B1CC19DE07D5586CDF5801E8189E65E64B936A7E08E16B79167B1B5DE6A710174ABD5D644B622DC8AAC70A1C05F2F39B1AF181475D505740A02782445187748BA2CC1C08F3F8B40A1D849546D7DD7A3826F571EEE93026E98B1E9746DC45AA8755590D310B327BC7A9868BD9325E4586B0641E78C0A96A05DAE1FBA700DECEA0BD883A10EE26E3705C31DAC293B6B9DB04F814DEF7C4259EE85DCAC6000E7110885E0625C20FA814F90159923A457904A12EE14A8AF8FD4037AF8E3D1ECBBFB3C7D3AC79FCEBB5BEDF2CBE117BFC5AD51EF6CA497464BD4361005707E572A93678338D449C171DE552EDA126747F87AF24DD3910AF2C492918CEDA0F96B19673824A92BBA75BE421A59D3CBD55460327393C0E42FB00B0E986E946BCE964326AE20DAF2EB000F8EF501CA126BBE5C315B49D17266EB35D2275D923319FFEB15369AFA708AA3DE81C4C93ADA4DF51517F2DADC07DFB11C8B1A3D75A1E42A985F9CBC014143FB3FE65696F75CCEA3A9DCD89E95CA8941373D2860F849490CFF15E4398D02243C8D53B9525BD7AF999D93112CD9091DA7816574E1F3EB4980D31BCA1258BC88CB828F0A29ECA46AADE35EE7C7ED252839B663B5A440E84651524F5D9BAAE86DE12C20FB5E82B0D1186F7424B0966037F15646318B4CBCB9C773EBA507476CF9D8A300E73D57798342965DE743EBD2FABBD3B291843C033858D5768DF02BE002867FEAEF5911DC0A76BC001D49F635D1C749AF51F6E0C90C16D647ECC0B0858D6B408F04FC1DCC68D3C0167BDAC569AE27E917D94CD1DDF4BA13B89C38EA5BCC20C91B3F9077EC98AF1CA8084ECE4A1F625E7948F2D4E2D7CF917741B95002C3E3B08DEC32A6BEC616284532B6C4776D1277EFC941E74D941C887ACA15500B4BECC7DFD88E2E11F98E8F4A4399D54C0BB717844E8B4E91F12B56474EFAAA7CE871ADA080F06D001E6804CF7EFCF3C4B251A5C9BF93F98D2FF3702EDECB377208BEE02A125520FB8E931252101C62BBD0ADB09597BB4A4746B36DA393B9CEE20334B53699C9649CFBAAB8E35D27360A35810DA4FFE805FE7D1969635B0BFE43EA2E77A65889D59D211F66DF5DFBCC630F62BEB421D27A0BC0D72255960A479E05316769553273908D08B1B799C1F228515A1B0A72E6263EBC95DADBFE895046A9D0695B741F144A288ADA988BEA5BED7AA97A2AC354F11873D48F662BD2E220994C9A96C5849A654AF8F0AA8140E275A60BF7273C81D6F58359EC612A41E9D13D156C505F08FA905293347EAD4C8FBEA54CBA2118C3E57D7CE4CFDBF0A669AD281D1451B4B774EFEB53FBFCD4509196B181347065A248175B3A402299F9627FFD805AFF437AFD84BDD15FF2C64F7D86409FD69CC8FD09EDF852C3C67D54F83FAF9F088FDFADFC141E03F3146813D2DD74CC67C28D45B11658FC8588A6C4019CBBDFDA7D3A6669239EB6BDA2943CA6F085D2157C5ED97A1F154C02AEA1CE599928AC7830FAC2D1BA12E72966A4DD99EBA9E188E4BC0EA1196C7C2C12128FCC38FD10D726493CE504A59D06B14EB6CAE341C948C1B17AC965A7F8D38EC465CC7C0354073DD7B54603DFDCA25593F72623637A37CBA0640BDE158A9326B72C854FD8D450C10A2D3640EF1CC863EB3151110D7D827BE4B11491316F379B52477DD24CA547C9A22CE4634292DA2BA195810D069D9764A558A3B6034C9A787A6FA22F7790429FAA33B78F5A62B0E9BA4F1961DC7D177B97B17E1A89FF3AAA4B4B6EEEDF786F55486D873269C2EEFE246BA0A33D90EC8207E6A97908B294CC921EA6C29B38228885DEE6827580D88ADB5EEA0209DCD1C932C504CA815CECC1A1049FB3C66393B9CF83F8DA342C1B9F2193790AC91788E19831D5E19A0CCFF09668A3CB45CBC427E9D49CA75148627622AD3B6B0E614A6858657DD4AFD4860E709DE2815F1C740B69FD8DE98060C6D4F597996FD6514D598A0C8A2F29B3017A4FE59175A53EC0D62319969DAE0C6BBBC76A3A4A363082020A0282020100B303407B756BC67861684CE02B80AF8DDF380D24352E4D6401A39B926B98A7675B4ED51F12C4E7D39B576AEAC14850C97BBE046061D86A6453082CB492B09AB062C23E9736AAF3173C343CAF437459551278AF1706A986523B8E987EB3254DC54845DCE1DE000396A69124AAE1581AC722043D7ECC8279ABF90F547811CC1E768A26EE3CE22DD6A6AF0760ED13B2E0E687D833A0AA10F2C07DE6258847AF1B77CED25A09B7647156478DDC2033E27671F263DB6E8CD49F0B506188D4BE869776138C237FAB5F101ED8FDD98F21E2952D2287EBFF5764E040E03178633437B2EBAAE40006FD161EB24BC7D795CDBBB224F100567AAF4F6AB8C0E24752015D69F0A3EAE6BDD34324056D06A1AF8E2DA7AF2C99386134994876756923C797FFF785EA6F267085B2B3D2F55A56BCC2A423A7A4F4C0490C6DE369F832B74E21B0E9EF2D9342B78320391D7B18E130DBEDD41D3F2DED060EF7CD3BE300CE57CE89A9FD5F0D64BD2E06BD4285747110165474BA6A9ECCA92FB246AEB5CC5584340003A10E6B28AC2B43AB595C62AF395439248F3B8CC903B8BAD134D2825C01757FCDB9173B6258264176D520F5D340F946E9404880499884F4C86C379B48FC5F0266AC4576A17091BC797B18C356C4E88FABE02B58684B2E8D11E65DE63A7518598BEC3BE0CD670E64ACA93557F4343FE02DB7AF30E5AE9A7598BA8643ADF3CBAB128D0203010001 +CtrlOut = hexpriv:78313380F340B18D1A17D58579335B6460701206F4F349AEADC32E95FDFAD2FE308209280201000282020100B303407B756BC67861684CE02B80AF8DDF380D24352E4D6401A39B926B98A7675B4ED51F12C4E7D39B576AEAC14850C97BBE046061D86A6453082CB492B09AB062C23E9736AAF3173C343CAF437459551278AF1706A986523B8E987EB3254DC54845DCE1DE000396A69124AAE1581AC722043D7ECC8279ABF90F547811CC1E768A26EE3CE22DD6A6AF0760ED13B2E0E687D833A0AA10F2C07DE6258847AF1B77CED25A09B7647156478DDC2033E27671F263DB6E8CD49F0B506188D4BE869776138C237FAB5F101ED8FDD98F21E2952D2287EBFF5764E040E03178633437B2EBAAE40006FD161EB24BC7D795CDBBB224F100567AAF4F6AB8C0E24752015D69F0A3EAE6BDD34324056D06A1AF8E2DA7AF2C99386134994876756923C797FFF785EA6F267085B2B3D2F55A56BCC2A423A7A4F4C0490C6DE369F832B74E21B0E9EF2D9342B78320391D7B18E130DBEDD41D3F2DED060EF7CD3BE300CE57CE89A9FD5F0D64BD2E06BD4285747110165474BA6A9ECCA92FB246AEB5CC5584340003A10E6B28AC2B43AB595C62AF395439248F3B8CC903B8BAD134D2825C01757FCDB9173B6258264176D520F5D340F946E9404880499884F4C86C379B48FC5F0266AC4576A17091BC797B18C356C4E88FABE02B58684B2E8D11E65DE63A7518598BEC3BE0CD670E64ACA93557F4343FE02DB7AF30E5AE9A7598BA8643ADF3CBAB128D020301000102820200327E20D29200C7D70DB6A33479E0CEE3C80A21DECC2756C9F612655FCBFC9F7F6E4852A1F4A3D8B61DB36F236F484C0D40DB8C957913D7929BBF0B0915F53D74B22E930408F5F8225E2767D491C4C02BD84D75299C05F62EBCC0D06FB06D3DBDFF504168EE3AF7C8270C7A98BE7E20F3793B53F32F913FEB8B9150E49B3485852F1BA308464DE2A55A6A4CE32232CAF00B7226C1D3267BAA62F8A72E84F5B5DC39D8A86FE42C2F31C476159879BA0F69BD928002F33347F72381975C56AF550A87A1F8235B3DB1A8D9D0E46C5484FA49E45B0D6C95048DA28EFA35385A32B9C3728CE41B14890838875A838B2C201CB401CC74181FD9D942EA9908BFEF459F8B3846DA2663E2E0051298E1703A9E75A419878E883E74E67761A1E8F972CD2E7DCC89767F246967E9DD7B77DD5DD9C22E460E933B9C62E16DB7EB8AFD2323C66D029E2D9AB9C9696D6FE41BD8A92FF989A0D6F1960CCD4BABB8A2F88A20C3C87393AE08CE4086660B4F88BC437C4EB9D08B10982F97395BBF4371C59020805FC9863BC51D5AE7CD6C976348152A8DDB2FC2F75BB525960DB2615663678DF60A6F58682D7CC00A5DB65F1CF5199975DE5B388BE586C6EE7593C3DD93B13D340136E1E152BB3AAA9F2E7EA5F540711FE4729EBF77F31F6650E5802E5C83CB75DED6A3AE48AE87946AB4ECA9A1CA254D3DD4955700E3EB5348B3B1F21FEB574ACD6B0282010100F7F3BB2CD2A1CA2C9E64FA3FF3D88AE1366F28BEB47F4D9FB967EEF6FF75FE60BD7E6299A1B9A5AF3AE53DC775BC91F5F335E77A030AA20757D96CDC369DE6C78AECFD675E72B6985434C085CB353E7F6E721BB1461FDCEACCE9A4ADF6501BB4F069262B40B175276CBC62D7760A935B31F049ED9C05434B775FBB5DB8173197E4DE7554B93028EF5A9F9925CA3046DF0A31B13828984703DA6CE5E3EA4D64A21D69659FFCE487EE13D54DC1AB01E4B0C4FAE1E4131B8BF4A21F9596C9A316FC278E20EFD828CF8B03FA62C22CB15AE5E7BEE24B7D067303668333458AD6EE9C1538DCFB4DD4B42D5554393C96F171E92273DABF369AAA07F56061BB80E03EFB0282010100B8D2B198FE1EB7B17B6FA395A16D64815CB2A65DDF944CAAB541A1027B60F4CDCDC3006430A379051FCA64C9FC52FFFA4CBA7228DF19D18013E448D27BC0B569470D3806CD56CEA0B14B5875FB9992F84DEE885B0827AA81583FFC7B11033B36A7D405C952FE8A178B14B1379D3B665D38D179A374249FF208F986BE276CED11E1388270ABB49273CCEE5996E463DE8B94E7CE9E5D1ED85FFFAEDC2908788AAE6BA0E5210EE033932DD8D12191ED863983C4CDAB9DE41D3DFCED9E8B1100CD5163F57F56BCB1E078EC2750079A77B96584FC2DC47C474B1C88C77BD8503323BFC732B2B164C6248BB2F176EE8F5E92E675090371ACF21F25C01B84B3C72C1E1702820101008D2696DB415D10F6AD84D66129B38FFBFD3CF278FDCFAAA4CEAB38022C1343A856B767F2057AE5B3075810FF472AFDFC8163A24E7704CA905B964EBE5DE92DC35276EF1AB54DA05CBF32F89631C431BBE167DC13E2D3A8B391CB401038340A51CABA511C364BCF618E29002B9FEB0D4FD0F1F563EA79A48185875DE6503203ED7040A3928389C303DF1713DBCB6A082E5863497BAAC0654CF03F25EFC52621AF9806B3EF8BCB9D060F0C52A379722E79E2E8DF4733096F76E8040AE838093BC077D41533F45DE728402F7DA104484272B6A697B4598C1E55453A5329B78BFB71A73323B97BE92658D84685FED3FEC6D5ECE2FF17F341C0A19F322AF0CEC0D999028201007960E581B4623801372F7A1F2A84CD1CA7E42B9E3AD70A029247279699B0731535AC7AF5517C0A5E7322584ECE8733D50DCEE46A331AA19B9B74B0DE8AA7647C5F4D2F1E487C59F6EE78ACFFCEDC6CC8E56561E766D3A6068C0E79A1D8EA6658DE9F3FAD97F3D27CE3BA132892FA0F9FE950A8B1CFF4BD96168EC90ED895909BCD6D6F3CCF87272725CEE2C755F6C090AA9A11F7AEF032E9D8E0DD75953A94D93795D2E483007ADE8D9D76BAB53B688B1D1E8273D29D9D16B8A4D51A3F706766AC5EEDE1E8CA68C101565018AE393268998D8401261D2C16F13D10F85EB337271B8B100FB03EF0814E6385D7E6101629837307EFFFC482F027D9EAACA68132C10282010007E555D6183A10D52C726281F08427520985902AAF170B3EF275791AF9D5B9A49388C8DEFC17546418ED74B3FFC6713170CA09873405064157D83903FA6B37FC90CFC2CC64ED54DD5BEC0CF3A35EA2AC9F4857B8044F02AD3CF0B814A858D213D87092DF216F81A52BC72CA138CDBF824CF1421848D34D02EA657568CD13E89B6A3E3D2CC7EBE84D40A5ADAE1C774D5FC6AB2C993DDF426C588600AB162C0B31F552459ACB054198C3DA8CF9AA5D93C9803A8901B30642E60CC1B03D04D02AC8F67FC2244DA70D00A0D6560DC682ADD50B7746304A50F3CC70D57B59E41174B495600899D8310BD407A2F1D95092BF39808DE96B5DCEA33EB61F10DC3F64ACD5 diff --git a/test/recipes/30-test_evp_data/evppkey_composite_siggen.txt b/test/recipes/30-test_evp_data/evppkey_composite_siggen.txt new file mode 100644 index 0000000000000..77b31fcdeb567 --- /dev/null +++ b/test/recipes/30-test_evp_data/evppkey_composite_siggen.txt @@ -0,0 +1,200 @@ +# Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# Composite signature generation test vectors. +# Generated by this implementation +# +# Message : "The quick brown fox jumps over the lazy dog." +# Context : empty +# TestEntropy: 32 zero bytes (0000000000000000000000000000000000000000000000000000000000000000) +# +# Covered : RSA-PKCS15 and Ed* algorithms only. +# Excluded: RSA-PSS (random salt) and ECDSA (random k — needs RFC 6979 +# nonce passthrough in composite_classic_sign to be testable). + +# --- ML-DSA-44-RSA2048-PKCS15-SHA256 --- +PrivateKey = composite44_rsa2048pkcs15 +-----BEGIN PRIVATE KEY----- +MIIE3AIBADAKBggrBgEFBQcGJgSCBMnffmwkuPHv3MxVXULFHm1o6i0Ej6/N8O4W +0imXaL2kdDCCBKUCAQACggEBAM81VF8Ya2LgzA4M1x4JApfgrIewFZd/eQ+rROgF +zfqMd4kigQLH0wGcaONJaFEINdCWKQCK67FBQDc3EZJWRJDUr+/xcX3XCn0c4RdC +fdqES0LMoWejAbKU32X6vvX6ODdhwS6hSeplZmYtI5IU7lrDo+JtkyEWumFuxgUr +K7h77IP9RFwhMn+rPRCiSkKtH2/Hj9MqerJSUm1jliwvLm3x+fwxgrCbA4CjWVRY +2TcwM1RGFHk2+ugwVMkspdLJrKTSC/tyxK24ehG+lUHXBRzmlXD809sxI3uUosnu +Y1VFT50jJ2IIM2egT5gdVMm6o/wc3e4def6PvTo+2rsTlKUCAwEAAQKCAQASNrkb +odEgsCtnqcPIAVk/wfFQfQ8s0bjxwmeMcKQuO6YvQP/vn2KCH/5NSlDX3J2kX+qr +QEre+iIbqGTMRPaCd5uefw3vlpU2sbDsgzz+VgYqkUO30SmPScxIUc3y38OMxLQ/ +NdDCQJcLcLjReLMJ+ewANYsLC80mzt6rqiON8/gAxy10WBUY7zrfpsGeHaFFH4bg +7MyF3eDWQlJjJPIAOLUJx1bYNgOkbM2lNLYeoJY8pVcY3pHY6yPZmqe1dYLvgCT8 +Mq3qlApRxCE4pqkowp5c/d9Ak6+iLVsIdbL+BLAdVZp7YQYKoOMTY1JNW9d8Zh2y +2Ba3PA0t40Ri2HkBAoGBAP6g6DOOBRUagYp0sO2bHX/dnw3RutcKcMy/Pv7ep5Cu +wHXv6JzTdmrvLFEPW/FuQj3SvK8eiz4e/PNiei91dGsmkArN+sTFDUMQz84WApK/ +cV1zSj/1Ij2cMeZt9kI+Nd57jSkyi7KLiCsGLm1TQlpv+6JeblXq6pIWFsJ8SdsB +AoGBANBTCZcTV/cWml6MLvyEZifxIfbTbE8GryF8uFfS4BklRVicHa0DcbnMyCm+ +FBlaLeECap9ZMmvf8VgDhVq1Ik/EwZav93eD4kSOD6E9z4ARGZSptYtV24R68ZXq +uq8P2m6KqZwQ0suwDDO2HzkFnIuHMU3Ty7wK5q+gboSPOm2lAoGBALXKn72fGdXV +VMNLSL57TnZp/hLZuDGrjJlBuXIx+SR8/3+0RzkgaJ00IUnGU3htpfGJsZi9j+BM +M4B4wI99ph6SK6jrIqy1myBUsmiKok+vSvrTQyGinE2sZJwFyhnFXKR5RXEyWzag +FBnTkfYPyYHUDa4BCXlh/RNLnfhA0GIBAoGBAMzIg8nduv/qWS8N8HZMFDu5PuDq +bjK06F0rw+6ZHa+6QpPbSxSzKQ0y76SQ9CMD0cu5W2RvAzClwBH7zBAhtKvjR0XA +jqwOmdM4LscbAqnqpVHNDef9Kz/styTezEqgc+FsL1R5+S0/To9avRCJopxJ9j6C +L2kW8jO8qkdmoFH9AoGBAN3Mn3aplSxVg/6mIwRk4E/BPuY1GhZx+Zqw/4og0Joj +8zX01LJaJcDxRkWnJVqfQ9WP6NDTUJAqKaOsFIvBkEOCPvny7MLptkAESG352ijf +kkgTe+mWXNtQcYfhnk8LOBAIbnR7dFGEK/UKN3uVKl7mHJTF3a1mFJGqGwA+3TAs +-----END PRIVATE KEY----- + +Sign-Message = ML-DSA-44-RSA2048-PKCS15-SHA256:composite44_rsa2048pkcs15 +Ctrl = hextest-entropy:0000000000000000000000000000000000000000000000000000000000000000 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = A61466A1E5C79EB615D0CCAEAB1BEDB326187B9EF23D18B6F100AB664CAB2F38066ECBA642866F532F26AD5758A5D279979017ECEFDA2400EBEE039CE6A83490A2CB0E2F82FF3E8A15C73F2209B618A8C6043422570410255521BFED4234B007B0064881470AD5B9790C79289752239D9933019B82B8C5C072E13DA87FE047972FE6495AD14382F2A6571D7DAA198A776042ECFE07A97592735A2C5015336193A5E46292F612401169457460CB3F319A9E7B156D56845FDA6A72CD4F93315B3D590495DBCC051F82DEF036C98EFF454404708D8887B7A7D02CE44690E51BA5E9B8999E973D84D079DA28FE54ECAA93F382C6D712F2B41923F96CB57998574B49738BC77D5515101952E7A65F0D9F98A9ECEA304ACBD9A3ECDD4B42B6BABF7DA5D4B9A90131818225C08342BD3A8E6134F2C3FFD8ACFBD4964A270FE1013F084B4452FBA511F8A51765BF51B9EA57881655A2097C337839CA690E0418089907D2E27C21488CCAEDD3CFAA6627BA20C2EBCA15CC7FCA810BC2A78749FDED9A9B6476F4D2465B00D57AA35F581D48D39DFCEB928B8ACCABB52D89EBF40F8D0D7013F5868F0CEBCEE30D098A4CE9992222C4352C26B57C4AC699D2AEED02222971D03E30C795F0761F278425CDBFCE280592A8148D96B692E7EFE28DC5460A6F2FD060BCE865ABDBB4665BF1CE71F4CB63682C63CDBED99C3F1E25345BFC89AECC6B046A4C42629C47E6EF52396582985E09C560BBF4E6E64C5240EAAE1349C37A361D1EF791E12EDB6DC6D9F3631C4F33DFA143C70D66D55829BA2599B89C5636C940DC4143E7451CA2515BB1D7CD646F8D9983943BA5DE6E4059902B21ECA896CE94DB8D814305288737394761F7EE18E042C2D37278E9FBAA0B7BE078A9D4F9453937F894666C6E2B93943560F160DFF94E552A6B5EC351061FC18C9465B06076F4F51F3CC3754CB1ABD5ED34B610C0BEED40EC9D9805098DF693613A1E15AB1DBB213BE914B1B69D0A7F26D8C79702E7942EE0E11B21AB05BF2FE57FE00C06964E9A862BE2221CD561D4D77EFE2B4353A573C9B2448AD9B08F7CEA999452E49FA71739BDA03758AD14DD8CE1E6FC948E6A64733EC23BD0ECE55C783AE37A5A2DCD7550EC2A5C6BF2166A9C5572FB4C2DE174FEA3886D844C3F620EDBDA6236AF5FFBD246524EAB15FCA21A89DB076853A71A02DECE95FE37C06EA9F796703C9B06959A5F4C2B071964A091F6B8F10B1FECF8C02BD62A4E4E09C82057D363605F0BB85A9E20949FE5562BA568A2DF750A513AC4BE959FF84E759A4386D29C8F7DE580C6E7EC5D26FE87BAAD41AAD2DF5102FAB47DB7AF4210FFCB1D653C228EBA53C663170E61893CF6B6DE93C642825C0CB66D6C88235A9D3B50E5D6A3BB730EF516E98BAC811B4D80EEFD3673345E7AF849DFF517896F0FE3A6F3C71D74AD32EF2D9281253E7539621BA9D90D2A269ADF73FD5EEF94593239D435D959E994C45A0B8E0D751288166A4DAC6404F70EF23B43D288CB64CDA0D248EC5CB8ADE89A6A0A143BEFD65471AD9E8C141F07A5B446EF6F6E61F77E7C03482B4ABA57E447570E456FF550B29CE6BA9AF6650743C35D7FBE9534311760D80D03335268B139922CAA537A278F9884AB2BD53DB7096B08AE6B951411D61675B07138C49D184572FE09FD0E40D741780F74E96020676BC112441640CE8DF74C5AA65D2C34C6A159D8F1BA8374CA09E405046CDC3DCEF4327C8C4ED5BEFA93D72E2A41996355E310CBE86DD3E03538A1D718A5B7BACE25F9A5217EA5C4564336DA72E26598F636FE6D3FED5538961075FC2577972DD1E5DC2F94E5B8B679148D4DB300F625F17F5ACA21B79D22402C493F4DD18C029EAB67791282E99F2E3C120189B777EB6B707EE9C28A6DD8B255200FAB7C051D4CAC2B34C72C0E13661EB8107F5A326CB33D040F2E055A942C86543766094CE0E8ABA3C4B816A906DB2823C11C08B1555033367CFB71FA1DE74FB055C2D5072D618EEE50AE96DC3A5E0D47A61B66FF2F105AFC0DF34175E25E187DCD6C3EF413E7D76D83C4E49577D0C6F164377619479EE83DAD542E56BB4FF1F4E1460EA30A7F90B0F873B3280BB1E06F07C11C4184BFB77A82C39F62721A6CFE89C0EE7B3673E4EAB1D87364E70EA65D9EDA0F9281C24F728B00413FF7716588B0FCA738E4044D2562558A0FB8A0A71CFEF80FDD699416A499486261E894CB1C6215A8A89EDD48499DFE100BD76D2CF72DD2A872EFAD18F00315309FFE9B9BA157FE16A4FB6A43FA94D593E65B8DC9C04044B245BEABD7F781D9470A56958BD0D8D010D5F0BABB0431C2A7BF86998ED0695B4D427A01765DA68F16EDCCE26515A5099E76CD0C976EBDE976BB2ED105679DAEE40C64DAF8F3261568ACA0B12ADC1B4DE83D1B940F981051DBA5E5594E3F38F40D4FBD2822EFB8E3670D816A76CCD7747CC9274996DB31E8C43E49FCE4A3A97A90811550566A9FE2AF443BD84D0976BF571BD95E5D64E5AD3B1A519618C96ED7D7A67C00F3CF00306986BFEA690444A31CDFA090FCFBE30AA9423A35430B5D10EA961A9D5885A274DC0DFAF57BE0E1FA378D4C3DAE9ACC22C6AAFDD0D659B627BDA713ED3F330FD2FB641F5307FABF61BF6B9C2A64C75B27E0CADD7786CA28741746C86F714D944265BE8814E5596B492363233ACCC6D1F2C630DD21FE102F3949C48962E8CD17830E6423E6CDA4CE3E15D0F12B90B0F32F218AD3E17182E08530B8E7F062ED7ED5842E7C45899D300364EAF9F9B142C9C949301C48EA8952DD9E7A8930EE8F004767D585670E927651B128671C561D32E2002A1515DC2BD6B1675EB60C3E7C19AE57D4816AEADB9D03037889E247B82900EACA6EDF58346306C3AE2BB9C296F51D0E7C3E3601C392A7443097620E948D69D6D2A979A0C9C0AA572BE8CDFF609A934E539FB676946883E724864FADEE802635A9C1C2FB124EC0D0146ADF9A4E0CA409E48E87B567A5FCD15414C0C261FD520F9693AAF6FDA9010E46A95B3E2CCB412E27867348CEA8D59A9DD208630154ED57DFD4759B9195D9F5C72BE392C247510BDBA782981172C4AD170D5CA3EAF6A371A6DC19D0AFD470DC3991CC96D7335AEF88BD614F4C513C6958DFE8A765DA31A747A4152B00C232782722BF5BF90230D92DEE96540D0575BAEF5B4B1F372A6B9D6F5BA2BEE7D8E3E41BB2DBFE19DEFD67070FC7711DD61139C84AE4BC6FE94CC0ED7A115128A933A6B9A6554F379D70875F3B9C82593B7C4C0F09C6BE876CB73F52F3E1F53E55FF39A73CE84A041250515B94B3BDC2C3DEE4FA091A1D363D697B989CE1E5E9F3FF040D131B2E7E96A4A5AABAC7E8EBEDF30C191A2628343D515A5B6C707F85929399A3A7B8BCD5DBEB000000000000000000000000000D1B2B4354FB9F8BD37CF4A84713DAF30ECEDA8B034234DE33FB9991D4A77BCBBD0CD0F7A207D1F68820C8955C4FE5952D78D212DD3F625C881470159D7DD234D830408B391E0FCD16604EE5262643C692F1047236B44E3F0B928AEC877FAFE3311877DC2C4F9B0702F2131217DA16B0D3C8ACED475211C08BF940FDED40A1C09CA6E4488768F316450A3DAC1DF80DD71A9D909532E3C3D16CB9DF4BEFAE46886EFFD7C2F3A47BA811084382398469D579C55788FD812829488DDE211DECEF310FF42DDD94C5ADF1159993F4DC8A7B5F8481D9D1785F2D0B03E8D11989DB91EA10B8847EC82C133738B7C7C6CA030B35DBB57EF97F45890F9E9336CD25E17E4F9FD1358F + +# --- ML-DSA-44-Ed25519-SHA512 --- +PrivateKey = composite44_ed25519 +-----BEGIN PRIVATE KEY----- +MFECAQAwCgYIKwYBBQUHBicEQImSHevDE0axbaK/T/+iLEp80Ck1QFQsJncl2T6k +nA4HQTSxAdbQbts85c/JR5Tmv2ygQBLSXqjQH/2W150LZLw= +-----END PRIVATE KEY----- + +Sign-Message = ML-DSA-44-Ed25519-SHA512:composite44_ed25519 +Ctrl = hextest-entropy:0000000000000000000000000000000000000000000000000000000000000000 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = A14AD56F37ADB1FACA6E3A875C2B58D2049D1FA8378D6C89A45AF7ECE8C8C9DBEE7E006B2A35AD02EF8F2DB8BAA51869460497C0D18BD2E7256B6DFE73E25C6F5074FC2A913ADB1B39212E99FBF9336E87EB73BEDF10EB4DC2C816A230188C4A1BBA120902FC5C15D6FBA3BFFD21A7A603A8F5A741A2386E8D21B54070D20EBBE2D727FEC25091BE090687981F8F28DC72F2BA2A6CBDD9701CBF6E8F27114DE303BA1AE839A757D64F71F5DEC21D74DF242EFCD44FFAE700795FB95D749547DBD2C302DF2322006A88CCBD69F27911013D58F07D2EC90DE9DFFD54E580969D53379D9AF0A8A95D09404D6776DE1324E7A2FA1ED2B3B20DF3B3B54D1FF7A55FE62B2EF73BFE046E7D7AE1B746D0B12C94125E14E30320D7D7E8DE7875B520001D74EC85C7C71F9D0AEB6F117062A9AA2332844314EA79236AD1E57FB078D320A8F30C314C6E5CFACFFEA765407D8AA45D3748FAFA0F916EB04E0D7D62A9F9EC4495A9130C547A24494DA3C6A2500D1081EF960B7DAAD0970BBBB5A285A662658A85CDD144BB90A9A40B58D6E08871E637EB367A74314F3DEB651630C2BFBE5BF01ACEA4D8E526B368F8AFA213CBE00301BB790621EB822B685B29705AB4B1466D910CCAE659B383032336060C5C334E85F694C39F1C27ECD1D0E24ABC57F4A67C1A8B38B9A9C73EFBDF98FF18E4F38E013E115E698FC3A340BFD3C7D7C4A86262E33092D1C70B14AAA5D42BD3E6F0E7F1CD6F4531A72BBE9967AA2751222474EAA9C5CA7E5BEC94DF34CB58850B0FA44D7F0B970AE06728CC425B303A980858CE5F2AD386A57CFCF50317F881461488D3F420E86498AB28C49B778A3B9C86350482CCA550777E411D5A571506AE462BD60BEA7A7CEFBE8F7FDB0C622B80D34EF89680715BA5D1BF3B2C0815D2B1A8E19879AE37AA5DE422A8E94CCD3CCC9C9D5CB08EF076F4BE06DF7810F9FFA1AAE7CACFF9C9B625774294F1742540E0E1CDE1686BBB6801B603679D1586A2729EDC8A89946985483073DFF69639C9FBF6CF3DB1BF42BC31C1566CCF4985B29738EEDA572150F7570C994DE1F912CC74B5B50EF1FB08B8E331DEAD7D5644B4C41DD8B06E5A1B40EE8EC85207BC4431B8A587EA796FF41B16DF709F907915585ECEAAF1FCCE7D852945808B9C2437BE21276195A65746BF41544E187DE09B72B392C5B5438B275AD6D6FF418409FF4483998EC14EA7A1D1FCF92586989AA62736285CD7CA942771E048EBDE34A9A9E32E3627E3AEA40F2240619DDF0E013F2B7C709CE7C184BBB645929BEA103D909A2B424F7236A031DBFD994A532541538BAD9BDDA7AAF467C193D675A063991075E449A15508F30A1CB2D780AAA5007E91CA15C759358B7371EBD2E573A045533FE0C299DFEA47E614507D7FE89054FA249A42C8390EA08828A8895FDBD9771E2AABF1FB3907C678FF6D2DDFD343CF6B059D5BDA6ABDBE183F7504C5381B1CB4783492369C63F5864AA7CC125F14F138E7753A85F8F43A370335411CE24EB9C58FBAC59C442491757B32186ADDA9AC43EDB37170DAA677F92493A94AF051B865012501A082515E7EE84A3E4BC9455135D6456F8729F3A897FE9A2B1F4C42FC200C12DDC88C70BCA905BBE16AFB97EA5FBA7E3B5207E28861018736AAD6DD4890CA923FD346E7B904836D5FE3F1EEA050E61F7E744065AB3ABD754FA33CDB9D359267487AE3CEA6C3065C0391AFDDC209D291B988AB2EEC201F911C2A96EAE25803E0D054DD4A6410BB1B7CFA243F2B2B7E4CB5B188216FE10827BB3C8087926D38A4943D206E39E29CAF62ADD180ED138FDD36AF8724BCE7125034C1352D437C360CE4796E4623068E5653C944C4E63178A4C06BFF8D36624A320FC88CB3A0ECB9F761BD9A15EB5F0AAD27CA17D7735AA5159815A194716D14535A53EEB9969398ED010E77067CC957A368748D3290CE4546EE02B2310BC3DCFF5B689BEC9C978622C6FCB2CA4BF92F8452306ADE13D5D76D36041504CE2BE260F85B722ADE80B66D7701222DB419E611FD12315E767BED8EB7AFA63BEEC6CB5D6D8D51A500F6A612B6EA9757627B518021D6FF90EFD34463494D7FBCF5A035EA905CB3B941B15D178B4ADB11E60AF64B86E07B78EE11E854AAC08D14678EB47A65FF1E39B21C9E870BB35B803C827AE9C61B6B3C1C85934FF16203101E5FA520FD6B45E24E59819682A944DDCEB6F1D9409EB843313164934C22A9A069D9B95D8EDC8D3E36A2A1AC53B8D4E01F3EA7D1071F3D3BE2B687F75B8980E53D3071D80B27D344DF828E218294CBF8E3AF827CCDF2485059E1A65F434E504170978BF7EF96B6ACD0206D1C10F730AFD9FD83B0DCE84A7F20F9506BCB525E17DCD1F525D80F03F0340B841E01F08399674047A38653318B6D3FA4A273E2EA394CEC8170C556E43BAF41845CB939DA4EA53E1C671B6E86D68E1AE211292A3E47201946753DECD3E4DA49E0530AF809A98C41E4DF5888D28D033321E32428D32000F30D650818FD670AFE06EAC9DC9594BBD280610FEB598175370907DC55048CC5732392409E7A0C0654D045734E0E2DF2A883C4EDE1850A5462B29CEF439A3ADAC74A6EE843BBDE5A0DE0D6268A61B303F762C92816820AC785E5DF5B104377830316000F7717EB8B5C136127C02EF852D2D7236358E2B2692CFA67D39F883A43FEB3F3AF6E5D3232C524A6DD08CA23E22E6177C6B35DB21308B02D502DD7E78AA645A875122F2249E49E58997867EBE8AEB1ED3025154CB889A21D708869FB05351FBDD78A954DCACC909B4F0C026AC6A83EF93BE9986E697D0F080A1D358BB7DBC16FB3E69C2577540C35A0DEAD3B342B576FE802A7969C300D6F76C2D1FDAAAC189CF85D416987717A33EB987090BFDBA02CDD0BAB02189A9642079786141C372BEB7417381E1DF01842A84F144A82E19EFD8FDBBF7F49B739C57701EC27A61F81BB26B30BF725CC26DE54A1A06F5E228306BCCECD80620CBE7776D401FB9127824E236278585E11366C6465B4824993AA449551982720217FE3A83402B963DB487B662875630F8A5A565337160ACDFF75A9A3EEE990066B0F916315322C43FE85A2D15F774F1DCD8A11C340442082CC6BE506B807ED3CFC6D3FDBC2D54E596D26061BBD9832FD0B30F3D4CFDA5CE3C572BEAEC07C63F0C070BDB5A3007E0431C19B8FB3CDA21E87961C2EEE5BF918BD264F5A837C05BD1A0992366EC8984AF6041817816397BF71A00D2AF5AC12AFADCEFD5216DF6F3D59E6E0FD39FA0286BFAC6BA0D714255F87BD42A61EE24142484959778D9EA2A7B3B6B9BAC1C5C8CFD4DBDFE7EBEFFC0D1C252B3747494B54688392A0A2BDDBECFD06106470838A8CBDBFD2DDE4E805132A3A5A878DA4B9C3D6FD000000000000000000000000192B38449878C66E52A3F1880993DD3E140A600BB04840FC08483DF0E1C6628701850AA495428E8B86081732575CE0CEC2B10984D5AC43675E91B8B5CB5C17D12407C706 + +# --- ML-DSA-65-RSA3072-PKCS15-SHA512 --- +PrivateKey = composite65_rsa3072pkcs15 +-----BEGIN PRIVATE KEY----- +MIIHGgIBADAKBggrBgEFBQcGKgSCBwcHukeyOris53W6VTyujtz2kclnPnqU8X09 +dD4LrHiXfzCCBuMCAQACggGBAIu0rV6M30WXiTZrPKI0OhCSjdMtiGXSskQo58mG +GW7+SW/pNNGSc36APK+Yhh5WiYOwf2EJKGXYJfqsUMTAE8qt8cFRNah11+O327Rq +7PIPcwHNZ0oLqvxYnJVLec7AQ1jsWZfWkXb9Q7pKQWNJF+NO+MI1Y07iaMi3LBuf +cHFMsfsfd/+u8taevP9zeklYJ1MebmYW7JdpaL3IAntHLfX5/Ks9lx8CCM4jM7D1 +5vPGe3S2mXosVOjQxjE1KkH0eCclaEsespgA8kZLMA9PCoj7nV2dUxqIYW8sos0R +FinL+hpdqlpS9/Ax9bV//TIuziSc8gptjfxrKXs/ENMkIXkvNWpBOmWTT5xM7R5u +m8E4nqBdeC2RbQhkfhQG1XaBI54qoLC5DY1BOOfmIxEVhsQ29k8bnrysiMjsjfDf +pO14yYClrKxBtUKuNFiC2BdHEDK6VKHfqEIkMKzP26M/R+E96o0FCETpwUgcC8s5 +jk8SWScC5LgnKdHkC/t0dtFBgwIDAQABAoIBgAyD0MdjCY8+OMGiD/Tx28UR89gt +QIY/6SNCTNKYi4e4tNMXH4RUlmRd0Cc6G8L0+phMQ8+UAUVE/HtSW2E8rv6INYYd +TxgPsm7I+3VT4h+kXaeVgxa2092LgeoShaS37sXfqlOimjZVZW9Mk+31JXQskLaJ +D3kzaV1C92sOuIUVxe3ajvvdwWLo0RfLJvMSDWJx8UQo8o8fwg0aMTViQM5DqNby +4KpGRYv9yvV5Gcl7CCKCRwkS6+pNOtaRTin0CyYsjE4axCCXhkokN2aAmybeuFHK +Y6Rl9QIBA5O+BVgRYd47zjiCxF6iNqRWOBuiEJCwj8esf+tOOyX9PtmsanKZlvOc +EbIMdnTesOulHB44/GDt2sSJ4v1NM8Tv8ic6GZ5ZzLWUyVr0/tLwgRNWfcg07AFc +g3EkEzkYc3liD+7QN1KtguKeyP6PnyGCFQDpqd5zEL8WWKoGgkrl8qITG52x+t8M +M2Z3QxHBi/5xH3tMrovkdiOajbh4mNJMSAo0sQKBwQDEuksTjRFg66ZATfbLSPBS +d8rWlDl3hUvpsbh7nxSP4Nx8yYg6aZBX0Gkw+WhMOgczGgoGT2Te/B842J1bLiZi +soJnaSNLujaSEGYI9aYBqsw84MZ8STIcS17xfD8g8pxNURBc5JQu9YFFTZKX9WwO +r1jBxRmR/bOrhZ1uP0kOnN7pYglxJGwiqbDmLnFknoyrW0LZLNCm/TM0mynK1Qyb ++N932Nu9kq6dOP7Zn3ct7/C2dFXvFZ/bPy/Zkiq1mlMCgcEAtcxA2b3SKx05SaKp +JcpdEX4FmKDkuT8YsReDZfM7/gTu0Iu4LcdeXMxEsokTqmQUGW0zDPq0ktH32wYR +faWjzb6R+oWXDkzc1eOU8WjWFz1qlRmQLd0A1sRIw8UqydsXg4QAByKymrXVVVAZ +Sr2qzT/cXE9mNvbhvQqHhAUrBCC91aYh1zi3OIplPKgdoUgPl3bxMIa5calXgu/T +bYU3BxOzbWmFkElk0b3UaOxIV2xa2nWg7gBLGu5/JCPDabYRAoHAK6SUgTrbbx/4 +Gu3w4TpGLlVrB12MvioxJCAMKEirXBvrbjebZDIFFqYin/3EmJyK+lg9fxbf7uQJ +3SeZCSBc3apyaZSWgvdFofPHXxd4A4irlJndDreCSWqjHnmM27dW24QvWBxRj3Vh +f0ltSw7kMQHPc/VQ7eVVlainu0yI3ZgJj8bzB0moP6xblUUaXNMbq+wsEVfy1gj3 +8iS2Ccxn5rY4hTLz1MOUv0Zkq0zIOMWxJhj683Zdp1sGN4NIvE8HAoHAV3rh+eUN +rRFy76wGGNk3z6MErl09sqZaC111LSnORH27LT8OcXjuP1lL9V1gyS0/Prz9Q9Gf +8sZ2rj5NTFjYabi6JgMCnS7/VS0eDsyTuLsk/no+ltMyBCaPnSTTYi67Md3i5Ywc +xbWZ4mOYyA5ckkeYkhLi7LAAECdw7mZOPL5EmvpGbnosMFjoPjfniiRS3F+vz9oE +gl0qbydYZeskf5NLU+rjCntGuGbQP2zzop3RWi4gMmaRvXPmWk2bStMBAoHBALfp +mcc5/xMlDA/td6SAWZsvFPqNEs3PqzAmKlZBSNAadl/55oCKT69NFDM/HTpna1kJ +I1k3ON3PFkxO4mE1MkCiygHNTEoPN5W8a86VKM84Zdmceg3s/qgQE2CImclxZ3K9 +voe5x6ckeYNlpSKUYe9hZdN7NQDmGNI2rXW5vKFQ3OhGI9exfeh5N95zy9UCV/Q6 +CCb+nV+B8f4CahbPl65hh0hLikhOPQHEiCLKyjJxTaomIFa9dc9SetES35PRoQ== +-----END PRIVATE KEY----- + +Sign-Message = ML-DSA-65-RSA3072-PKCS15-SHA512:composite65_rsa3072pkcs15 +Ctrl = hextest-entropy:0000000000000000000000000000000000000000000000000000000000000000 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 33C7AF4389F5FEF2DD0A07F886ED51B14D6E33B8D83754BE6555C60CC7C47F1720D8AE9B6FC4E53DD3FFEB14D13B450CAC16BBB7A46A186B7F9D01655D0E519FEC9651A6AF0DB257FA48BB654ABB145A9DEC765504F666FDE4E5472AED3CBAC6099AB8E4D6FAC3773A491ED740F6BCEA66E62F3559392999ECA186ADED0C2EDA607FE0CDB53B6AEE9BFF59ED2A32912830D34B412F2323B11B5F8FD0B05B9F0DFFE4738FE8F130CE1B0F857F9B9AA38B7D25349788EC8FB8D57999C13ED9C4DD9437CD6B0CA3FCF22398A2C3A16490EF2DE5D138F0CB78209046F2BBB9D02D1DE1F2C7FF8919F41B8F65A7CA0EFDDD64B8214FC48D307059944D21EB3E2DBF11842A167AC03574EDC2866CE2907A520214EC7E4716D14A131EB1C2891A9EB67B1B690E22E7A9FACC147ABB7E6DA217A00DC7B8CF631A781E72A5457316E8F314B9FA19A0BB6DB5174028F410C3D3F83A43E584FAC3231DA1E973AE94456F07BC93DE44C884AA9924277AB8B05E2D396A4B0FD10F86EFD6B883869244B6BEA7324EFA713D87724F5AA50D71A128D29F3703EBA43BEBC9CB2C6172CBEB1BE08D6A179CE71686C9081FB2E200DC3F0D1EF1ABCF3DE8566E7F7D7E230CDED0B7F52038A290E429F85FD016C3EA441F890D559EF57381AD022174CB21861AC0D0A946744C37314BA9759F4805AB1F3A74299F0823226DB90CFBC3DF6F61FF6C4FD0CC652C66624E832249FD2D4064A967F3CF3C8CA4F950189C7EDBE4C9972950CCC8F6D0FD744AA15BB9E18D86E4F32FB74B931C9E3E11C00BF81D2F0FBD5FA2CA06F277F3EBE42D2476893EF92193EA211F90CF27D0CD755E61B09EDCC1CF56D6BCDD30AAAF31E964192AB4B4CA9FD4A2C91A37E4DAB4C621171093867BF9CF75A1015AB3886309C630731CF9A36BAE77D4AE0B1D66EAC62BC5CB4C2718A3E825D4876084A685247A1475471FC502DD98CA336AAB7A19B67FD0EE188D34C0FABE06104D4AA048597F7EC4930D1AD8AD497816803FB25B6D288D69968F95C3205713FE1CB904F4C84DBDF4B39225E62FA6A4AC556D96646FD006ACD101C584A79E58BE3B8E39B65D25840005E27A16D2DCC20EA8D8684622F8726EA338E9E571E1C6C63B5C3B8EBE8B4ED1BA9C32C18D35DA13FF9A9F06F5C69EDC0C681397E07E15A5B8FDB93B33F416DA34FA5330444976ABD3EDD85A48EFCA8D4D6F3525401666890E3B5C1361AE06F8887F45A849A137FA4722913A998CD675D575BC96AD622842F62F904AA447A71593CA9CB1CDCD2986057C075AF6CCCAEEEA8477A5224762F37CB7A81EE046BB7AD3D9AEB355E11E49E5179FBAA1CFFDCB06AD99882FCC7BF68C384BB33DB972E0082CE2B18A26A3C90E49CB20ECBDAADCF62304E23D20D1CAF4F15F33D6134AEB7536B5169AD1CC07909212C56FB34AFBD1D704D197C5DBDBD3A0F67A589B65F336163F2C7E8072323365BD0B0CC778A0FF9874E20266960734DC5B9546721906062AA783D4C805A675E9F15828E86CD10FEC4F0ABB7B1A0825132C40413435CF1C7665A4AA256EE1DDEFB93853B0EC51FF04238CFC3F69E7F246BB28D1440FC5367CFC95CE0BC4FA1E8DE459F7847433D26A466170280F9FAEFBE19B8DA58F44C75AC5290E11C1D82C186EE1A845C8C07E987161CB8ED115479E25DD556C5A0A2B6E2D2DBAED7724F6A550FA4C2354B124BBC9E48BB5294BF8091F2B2F6C04BD044EB2F841C9EB4D5AFDE600F26E1EDA855B042ACBBDE2F7E9392477AF3CDA438D0B3D172A59B22D7D2B60B1E425A88A72ADC185694985838F78C7562BEA84C128038E3841B9FCE3C95C360BA8638FBF971272E4C6BDC8477B44B00EBEAEC800B3BAFC57048785098C07A1CE49B99FF0DFA7C23182608A85BEAF10A620B3B441C52E24D4F78031A19E1E2FFE0C06EA7B1B67B9C73FE9AA93884D9CCD65B5E76C6DEDB2C56167F083473722207AEE5C3AC74C8A3A0BEF570F40A7D73524B538DD5850C19F9F44DA459C815C3AFEB4186EE4B1946670BAC20DD5AC1E4E8F779908081CDF57908911966673E649A81B713301AB8A0BEFDA7B630CE12C4CBA0880CD4A3C354E143E5483864E377F7F62453FBF3351224BA532FC76CDADA8912ED8BC19D00E177218C803F5B0B2C5A1B0AE9E9A14FB19E169BAD6809C74237696EE5544506C7F6323D2566B18EC02B6C51578A1D785A9FEA8CF674890D900B9D1882137B87632BE94659870A9EB16B88D63B293D34FD630B61AB17FFF38C7752D16425982C8D5D58946ADD0A882917AD2DB82DCC4E32CA20DB3CE629470BD3980C7FCBE312EA066915514441454972BC510C1DC4305E490C79F5CD50944CAA1D4DC5B8850210E0C4ACABD97A310A0DC160CA251051C818325D02A13454D9E901965C947B405472DA92CED7737855BF1DE83909C229ECADF01AF8109177439E633C2BBA3A1592EFADFB1AFB5BE5D3783E0BF35425DFF0A9DBB71DB876F1E16AFDC725DF849F708D69219F6177CAF6DF384E479FF2D23F231FFC75E277659EEF306A49BA9E0553F8EE33F714483080DAB82E7281D9EA4EA2DC3E0B8141C7343756261F0D87116EB8FCD62AA322A612F13CA77C99AE1752761305EC6806680AA7E4B5709DD47F58D466D0FB0B5053FDF5445B7FE13000C34040D3FD162368449DDF7AA2F622B78C6EAA4E1C93B98E981D1F831735B28BCD9F8D62A11DAC9236D18280B717B273A46319D2DB09A9A1880A7C5406F8286D37591788F24C63E8877184ABF3B3062CD6B5D349ABD0BECC030A4577EDCE4081C7C91409B1376C7748D969C26C4C3DAF1972600BAAEFCB483F01C86093657B6EE0AA0DADFD5A0342A1C586CF262C6D15B076EAA3907CFAB3E341EE54DFDD8C24C7100F0372815B2DFA2EAD3066407EC83806EC1D8C79858CE36EF2FBD0541B81063A1F02DF413E776B267FDD798F19439FB361532ACDBCCD53192FA3AD60A37296C3C388EEBFDF122F4848FEA55E4851DE2CBD9F5A721D2276C1331E0EC9AF37504601095D32AFE75BC52BAE41D148D007E3AADDEB82FB0A804D353CC2E0042485EB5EEE4AF81C46484FCDC6F8839050E1AA338E5EE4CC1C42493114793FD49A5DE62F59BE4046EE3A9B6DAFC51D03E0BFFBE9B883CBC82D29F3F909361F17DDF1DCA2539FD2AEEB4E2B04CE009DBAC160BDA3FDDDE331C549D6B805723B8FCB6EF496A8E1A44D9E3271A4E5B17C5B418F7613BF84EFF1A42393385201CE865BB96D69CDA8832FE5D8DC06C704C2A8D0327B6EBB6240274DD0C64C912F414BFB78900C9A4A39AAFB70D2952A8B9A6384F419299E7260F35C447010D4E2351278B3129618B492048EBCE44771DDD5898D1B3EA410A0F4E3DCE84601AAE4660DBDA3753D519FF1BD888C5C89F2F9BFE82F60E447E81F2B6976FD26D94084B2E45C0916D05117B0E276E69889B95ED8E7DED69396146F7481B3C65F83920A7E23E56C0677B5FC70A0A3BB59EEB4CDD2A0EB78D4BF185D23B47B7D852ACA02B9DDFD4D02DF33F6E1D264A60D66366C318AB969FB56F8BF97E8AF44B4D1946BBB85BADD49815380613FA945AB110A2008108C93A4D231D92827966B9BE715323142FF555DD58F7BEBDC7660BCC999210F9DC57B1628093005E58AAAEB0A3D0813C34EF10BAF22F249FFFBE6FC9AA2A0C1A6EF72BC9BF99930AE23C020BCBC125C0180F04351AD50E14C1A5B3AF06A850BB6145A279307390665D316117BDFDA037EB58E4146CB84010F04F7219AE5E9E8D5C1B82D45651FE373EF66EA61BCF57B8C95E156CB0E2D9F749C23236FE504516F36E708F9172C8F10DF7F2493759ED0924FC72153AD838DFC99F91A96D3B5AC3702DFA331F2460D46B1CA37B85A30986E0C116C5E1ECF9FDC2ABF3580F98AAA68C3C1B8A4C33D7068B81EE47E3D6F4A8DA37C5D6635180A6BD8074B3BD617FB55ACE51371515BF9130E4568F60232F83B5CFDF914914BB5E9965A66BF88DDEEA6879DA395A8FF995A544BB2DF84B72D25EC61088C6343C541C823992D13D3FA18A4DF6D5D7BDF59F7A891A81A77ACA00B74422E2FF4516023E1E1B919AEBC9B17F7F971DCE8D2EE007411518478B4CCA6CDC7EE600200A3EF9E475CF49901EA032A0C95C03F72938C5FF3F709623F897D4BF305113FA3058A6D5C3F7A0BA926E558CDACF3924D457A55E8B73A088224425910653E8EB219F80B6950728B25B2E47FA454CCEE8030AF91621604A43E80F5BE11AE4CE7480A27EBFCFBCD02C7CB7041AE4983FC22E23C82F49A44B7D31E7E7A6B9D25E9D3055AE5A86B6B0C530A9A739059EAA233EE7B5D03D1B1F7E73C2B520CF732E1BA80C26CA1C6A07E76298550E0572D0ED79C46667156B1D5173FA3231096298421B1754FD29D163116BF26DB345F6E2C4F2B23C1F09B457FB991DF53DA210EC43D0243C1745D39FB1C58ABDBD73EE861E6C1B33CC7B8FFF8093817AE3484769B78E5FF9F958BFBF71DC6F062A3A118D9DA3B27A1B24022700F911772B6ABB896B19382C19C34E75EF62F11E87F76AFEA23A4C93C0E9B06E34FF826C0186B31A6FC30A6A1873690E1FE0B5A12F4030A4140B0E317492BEE0011F283E5B74839BDEFB2E334D8A9295A4CED9E75C606278A1D0F6FE3E56A0C62C52686BB7C2D7E4000000000000000007111B23272F3BD09141231E4E48AACD9E4B15F5E7A2EF1E5E2D632201D4794FED9D0B73CEB76C35AEC724C968D586F3E49DCD0B4CDB9699B71E9F82B592CA42D22933865FD74CFABB0CB54BB1787375D55643E25B692F06AB772631CE36333A0112D4327E4C7EA5FCAE50280E2376518FB2C48A3E8035B03ABF0FC28D3F8E998468DC1A246F7850A72EBAD30A564C3390DF43C58B3D00E1E92BBA0DE61457AED170AC4785F49AB5E58FED25B38D9A082A7EAB3A1EF9EC3EBC2E08D2E7A28DFFB1FCC1AC17B1BAAC7FAED1EDF0C7A1187C5A560FB0646BC49EA5EC9D114120EA0C26CD555ACD293CC54D6E059E4011928B25C15D56A39522A3267DE3054F61782F9AB5C2809FDADFA1CC420FC6313B2D4655773D37230862DA9B681B76936F70F58426A572C38CB1D1CA9753A4512A0C09E4AC82D25961CAD6E64C97EC823A863B2F1A21F43D8FC247DC4BDD6D3F6D5415AED0F1575C529A76C0F2109260AC5D56A5BD47401AC865156E4C7389BCF151BA061808AB239C519427EF7A22B09E4756B0EC64D2A0 + +# --- ML-DSA-65-RSA4096-PKCS15-SHA512 --- +PrivateKey = composite65_rsa4096pkcs15 +-----BEGIN PRIVATE KEY----- +MIIJYAIBADAKBggrBgEFBQcGLASCCU0b67uAIFSaS9o0XAPESK9L5NpYKca5OC+W +gbRADWgeGzCCCSkCAQACggIBALJAIzxbT9rlKU1B8Rx0rswf0p87Qo0AA+z8Fe+q +pEKWu1wkx4Mx8XxAhWII8LOf0Q7d3ii7PBu+u4hh9wfnGbl8/MDNWY0G/mLvyQlw +X4qcAU6+59+9kSdiFJL4ZqC08SyJzcHEFRhJVD450v0XcwS/EEXVCYJ81YCMuG94 +EeEK5SGqY0m0lM/6w4i2uIbBzZ0mdy9zeCVrqBy3P4cvJ+Ul43G2Bo/dyRmy9dY4 +IpI2IN9H50QvC6rkFIh15LcrAj+VdVp4kAlH6/Yp9HxAucut4+OeztAC/cod/Lf4 +TRFzOn7yV7qrxwa61TkIm7p0aQHJoWEfSQZ2YCikJ/FwGSIE5fx3B8Vs8ws0Kppy +aDNlwELf3+mijf4leJ5VCLzlvN0CCiL8H3nEn5DcfmZwbTH37WES8/BIeKJugj3B +e6S2nPATSfuYP6/V8I9KUjXjqw8LZPVVA58SAmDxBEKgUgKH4zp047DeDLLb08V4 +5rPcIz4sXX10cWGc18g5NFpBF8nlgI3KHdZM4xnVdy8miXaLc/5g4bZ5KwrD2RDr +mjEWOJ9+IMTexMPgb1PiQRUXoUZUNcrAnLWW8y3R2wh09zQcAZf7tY5Uv5RzAWsJ +jeqcmDvaFOS01YGHof8gBFRGZfQm1jKfTxJ6mQS5ldInnHEeCUwwJ517485DW2KP +oe3XAgMBAAECggIANOp8a10SKkHwjmpeiRuMjrV9wd6GRbR09ePqITGPvOLhcRvM +DMMFVOUUk8NirXhqyBaObpoS4IuxQW4Pt01gYiPcJuJvTMIAP9++VyqAenYQn09m +J5IvprjjsbPDR78ff6DTL8wllQWj2CszWwYck5Ki4pA5V/72JMjhsdm7uQqSdfmO +qyFMMifX51yTEBI1l4sFQ9VsG/PHPusZlWim18x1JlsqvIfTPOlXOMaGYNBn1tES +MzgiJxO5kr8o7EV8z+JvKbHz1IWA452V4lMWtQQEzJxm+fKBZACd9wFj46PJAEmy +SIzZM0LArMNE88e+KpUwbtQqShxXNIlzACZOlz32+kV3kodbHvLnGDZpD63xoKDv +caGjtyvYkW+RY21ZQ/j5Fa5WQH2yPs8IN8mk1iJt8Rn4suaVHmJOu2xh5xeqKBSp +7no0p2UxQ2ZDbsTHSn05fICmG9E89ToT42/G94yGfE7hJCBlyvp0sJGxsQ5VF7W5 +QuPHmqEnNdbQN6NsxxCzVQoJR/tYg+L8AKHNrszyg8gOAdxc5xkAZSFy7GkQ0K99 +4pRoZ748XT151ZmYg8RRr3E6+DVvNmB94wed3RNn5XibfFCpTUU8pxeCDujqJNLK +jo8Ub8hnEjhqR7ueYJ7PcP9UYWz+9gIz5piDcDn6O8SlmA5U6P0JIVqNWkECggEB +APkZoJBfX4bXW7a5QJ28zwCc59bOyxKCmtKpUrGP3yoVXQn/FY9eV/DWAHB5/OIH +QdfKp6MCmCzAe5x2NJfCnS2/d3f6oa2T4I+JrvhOYJ1MTxFxqwodfBSzMHj+2UQW +fDDJTf5n5g/BERjKpqBfvZU0mRh+orjRQjEqSM6h18Rr21pfEkWtFEM/px1Nq3Zh ++13mufQWRN6K5Mjv2tgU/fl2d2uajYGgwGDGfP0JwMpPm3dvoOZZc/22vrZnmudA +LM8T9WykGJ31cHMzjzQINRYMvGcDdwf9Z2o2F5a48JGQAU7qnTRsU3dOparTDZ89 +b/+EospkHgWl7Lm9zjJ+6UECggEBALcwHXI5ACCgnn7vh78PYWG7kADIZkfQeyb4 +TlPfq+ZRPKKWFj3rJ7xr+5Q1bdqucVlabDnVB4KpmwxSw8w/vLdNx61HAc6ujUTN +EYZ1lepLary0p25su5FbBo80VWkEWsX/lvSxAQfI6b2eadlpdT2U0dFqTctm+/tr +nVMcRT15RdKD+1uekW+gwsLLpFzP+kB5zaGsgNfLc98dQ3JzHZKMRt8qsXfnm9si +V8aaPs1ps+d/qIId66nWEnAMW/YCLeIrV5b7w05iUrQw/RAlltqlIi9OBHkqTaUJ +64euvs8J9b+6X9jHP6fr1f/VgEg2C9TET7nJkVhLRZmdSPHruRcCggEBANykiIaZ +FAJaS9CEMuoFTc4bLXgl39ZbfUvP04GYEHI0Th8GpVBCnt6ij+0RAKAtEXNU/Dv1 +llk9fcBPK7KpHZRiHi5WAFPBwo0hxawHsKhj6T1oU7o396pWNj9WbZhT2llUVhNc +cHnP55bwGbvAUisRVfJOaVAPevQVojv1Oyuu5bMctxCkiGgwv5PDMnc/vumj7153 +QzVkDda2LkBsB7Kp7omPcnw5qW2PIzL3Kp+I+ApJBFpFLeqzriXfi2P+gjJCWYeL +qopv1tUT/Gp4Qp1vVopglVSsbqezlh1ZXy1wQthmFC1VLnFlZnTzUQOV5diM4a0o +FTenixHTQAuWQoECggEAQDjeGe1h3g5xgo73SERcH6diFOQs94BfrIng7Aa+fUB9 +wYJcydhnVeeFi7AvkzsVAf5xctT8jRJpCSj6++BciOb72gPK3mrTnAtI2ZrftAQ8 +p2uuR0hXed4vroTqbKbaLBAvHBnyAoitaYzgDxipwa0q4gAixeyU6tAPl9ORcrvR +frxGoxg0ZK43mZNLTD6dvXz2Wnffs8fgF5hqzPUOqRIExrhw/1hzi5++piHtYpZs +O/zFVtimhiRG0oGCu/yHmYMYchZRomlWFVYXYlHLUVwTYAI6D0CFeBbCPA9HVc5o +GY99isJPzs8fd1GiZ66K90zbpobELfA1tmUt7aJ2gQKCAQEA6rTNMhzP2wMIZq+T +386ODf1pJ+DkW9hc3RE3oIjdUaPREuJQWKBCOViscMxX4lEFujXcAdSxW7zokAkI +AE4d9O9yU3EBi6TfcKeI1x5Ehfqp3nZMFcM304VkcXvHwBBnITTz2ispQiDW6+Bh +51m27RFklm6wmV0B17LG1Ot1ZhH/VTMCIjfq+XuMGTncKyStmehZyYPTKxLi/wMI +QdWY2H0LxOLKJV/5V77BDde3TYY1FqmrkBzG7h/W+tLgS8N/57GEib5FQFZ10CFw +CWTXtaLsXr4DL4wgT4j+vSypcM2FshEk5Fz0X6ptQ6H81Fe4qTfwd2o3m8XDQCeQ +FWsiEQ== +-----END PRIVATE KEY----- + +Sign-Message = ML-DSA-65-RSA4096-PKCS15-SHA512:composite65_rsa4096pkcs15 +Ctrl = hextest-entropy:0000000000000000000000000000000000000000000000000000000000000000 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 4DFC306F5178E687BCAC137DC751109C7FC674A16E77E1D9557B46D6BE9A00796147D4CD879D4D77E7E2ABB042E345B0AA84394C75A7077761B10869C43282E51B0B2F438C10A6033B4351352BF06A9EEA9E4A39E9CC54614682AA6829C83035D92BB3FBB68305F52A410A7E1EC02355DDDD483DBB6D355FEF122928460238401CFEB5FE105BFD0D9E1BB3588C794B497214BE22C9D288089CE9D25322B14803AEF7DC9A295744932352F75E4C8831BA53EF716467B73774564AAE0CD981D6BF942EDB73A88C713E7F36A4393BE16EA3FAA7EBD794DD5D11991C4FDD319A0E0307DBA57D42C341B2E03EC921D818B14204A3B3804705F2640FF1D53CEB0D68A5797FE4F2583D512CCBA7433E6E9B0CC0360C760372E4CA2D26DE1C966E4927E0DD2947D874A3E41C6407DA4660081712B5869E558686A361F9F7FE890B0F1CD4197DE259EC5307D0E36033A83E5128BBD4C86A49F610275898F0B59585195DB978549055E498CB1CE0540877E08E3BBBD0FBB5ECFED158E3ABF8D75829834F3A3B18453421042B9064C0652F7D488B111A0E603342D50D96CFBF1F3B5235A87B16841ED3D8EF5D54196D1F9DE1D65E81CEB43E935423E67FB161D932242BDF3DD06E138A665295469C4200ADF97C6F243166682B9AEE47CDA43F451804A952DA31996E2CAE03B297992A4BFCCABCBFF3428F6339FBEEEA6B64EDCD04EAFB067DD76EF459F1921E59C5F576E59809601364CA80F8AC85A96B9042F982A12AC70EB8D16C1547AD9EBE4374423A74963763D9388A3FC5C1D751E515F8EB86904FD15F5AF03FFFEB3AAA13AD4839B57B4F4F894F5EA08D1DC8E9E0406A05A924EA425EEAC1D0BC25FAA114F73EB95158895320B9437A181F4799638E5073A5482A5281BD18874143F4EC55BE246C5C374EBC400242DE08C83A779B3582201632CFB290A5F35D5463C837E3CB2BC7C7939FFB101490B38B12BB3241373552D0A1B9B198C986D8254EC924DED1F435948F44099EE3A3AEED33FDF94172BA1B5C3931B76754072B4752A3F04425478D8AB9AD7F9E059C690B8CD9BC478EE11C380D3C6FF59844FB6658FCA5398E1E262496413621ACBC4C96EB6472C9C3C0FB07979D2B97ABA1BBCDCED2D9BB4D029EAD207370FCA9907E03E01E50B8568AE79A840AA13E419EAB8A09E609662D01BFBB212D1273B8ADF958904512755932461D8B6A1E9E6FEF6E564C375D895120BCDBBC7C95A133C7804BBA493CD2D27290476B7B05526E8E36F24CF48832B88876B997FFE1EF5B2DD7D9F4EB9C4AEB3C963871959E37C22E4D8BF8196807954AD6DB7D8AD85B635D5EDEE0C0E0A8D79387E419101D987EF94E713F540CB75E0A4A6B1FCBC2479BB430C414E3AECC9053D24453B52BC408D4A08C1F971AC8A20584F1A71A93BFDD372054A9AFD1EA23E6E2BE9008C7ACD0FBEB02CDC7CD5C52BC855D0385EA5AF352B5FDFFCFBE7E92F1A279F0AE65421AC2AE4BB3E885A99E186FE9E3848700A8904AA37349427899D592F0EFAA72334399E68195C5C070F2DBB98B3E3C1E6F85AAC4FDF9B12A652AF8ACD638E56B4681F7013251C3B09F2A99CCB53721720BB6C869B54A9BA111D069EF539076E3B5CD7A1DF9DA9E1DC22356B24FB534E0D105CED616A6827596E549197F328972E5E766EBF63A2B35D2F95A06310EFCA2655A8FA6DB8ABD0E0DDBC425F5764A93FEB5B79CCC7F8A036FF546F43D44CE554A5C7A599ADC78EE981FC51FB5B7C28E3CBE3BB70A899AC29A23EC259E3BFE6B0D15DEB72BBE175F037743D6E91AFAA97BA2C7B02E764540DA689E5E6E32EC7BE635C4F88C3A323A9859637FB9DE9CF05E2546BB9FD7E5F411DD7EE718650596E52694E492B5E42C0E36344F865732DDCF3AC9E3714341B1AD47CA90848B1458F01C26C7C736E9C57B01734F44DE4B352670AD2F7DCD7C1BDAA6F5AF64A45CFDEC19F62112C429781FF4FD3CB6C7259E095209147634DB13BAA1558B57C3248C12C911DD5FE06ADD451A9CB565F7270D88A652E87241952D8B4C7E4D7F06B46B73CCFF8795D3959BB61785F2B21AF71DE90D6527FD41A03ED6FF13F4E6E5CA3BA8C087AF00162E69328769B403F2BE575A93C6A64B83275F08F9B885AF2CBD684664843901BC0060E96EE9BEBEA7C94C2E084239F0DC2108B23C0ACB87166712CF620616ED8219F6F8F66DB3F672317992E0F25753292A7E206D03CDA3EC37980D52AA10A93794AC49D3F6D2EA05BFC4B9FCB3058F2763B0ECE4785D989FFF16648D399AD042747AF419CE9FCEB75778F66E1A859302FE02131C67EAA1CF2AB05468649ED56BCA3D448D39029CFEB3DB2FCE887C7B97D07485FC373CC8B6C988130E1E1C5A82168098C7FD542D7B331739AC8337DE82454155147937771F3BCFE950B30D133566A67C8699AD97B558CF83A5995757D9396DF867698EBF623B247413D07289017B401B339896BE5C4A407F2A1D607C227FD3F45DC52C0F7D8BB6E523BA100F87A2412A7C7CB655877DF1ABC80231CA81241C6D7728CA07C5B98CCDFAC2EC861B89DEBB1A5378F1E8215742BBC13C02F9C6A0F632C23C2140CE45F74B2A2084A107E094EF87A76E27EC798ABD84C3C361CC4508953216049147258B5477F16D606F6DA96A6609D291A4DF144F343064B8316D5865603E6A11C710465631092B4B7B89267D33A8C0F436714D00CD16E6AAC77D7875D60147965DEAAB5FD907E1C23815FB709F4D34F6282371E3C0CC1B4ACB559175CEA3C7C2F149F56EF5C5A489176728996300DE7F55C9AB5BA63CAA9D2EB7CD3A2D7FEA8370098F5018353100BA3160B89CEC67D13EA8D65B5F9FD553327D77CE8D36B23965D1BF3343E9E374D1793DB1F0027FA570E277AE933291DBB8BC69EE07150C19060CC67A9C229C36439B88E112FEA6A5F20B3D358BCF9B9727A96FEE11C3278AE329FF6D43CFA7C78D20EC64F4EDEEF82E693CA0483A74F30FA65723E912F5FC481D18DABDE1AD1EB4E95C2D0C192AF7D57A08EC36832C998170B45999C5F8B5D5BF5346B8189FBAE472FB40994DEC7C7EB6F1605E647195610A3CD198655D188BEAF6FE3B185917C66C8906515B49FEBC3C60D85BA093E5B0F7CC4F105EABE85F1AD033207C204116DE03055C85E491096EBE7143EF5A79472B76EBBF939DBD5E82E9F6EAC11EEB30ACFB693EBABADF7B4CD313587CB3D21961CABEDDF6FE2982D4436181A1F4ABD059ADDEBDAFB3AE29FB8C47E9299C791F6555DD6E6D01D670D453183EA6DB4EFF3F4A6BD39420E76DBB805CCF52D1D807ADEF2FFF19B5290ACB948AC0B200C776AA0BC60CB170B7903571D5576D4BD6A5A377799BD22CB204522A2FD151E11B9DFF697CEFDCF7CA9A67E317FA0A1C07E81D10E12E3DA4823B9E00884CCA4890C4329590A34564142AF99EF66F7B34F8EE6506C337F81380308EA7B2D21C268A21A27CA1D3572012E535599E62F12A642A524267773260C4841888D034FDD572FB63B657BC7ECF426B03711FEB75707F4D232612413FCB87EA80E95DEFFA1B5855DA6F704125C95AA085D55B8245A7CCFE6D22DED29BAD14407A27563DD8C5430EF3287DC21F62C335D30371E386C443A5971228F9FBBA08F625DB6EEEE645EB2C1020C0C49CB6725D9FC8AD8799F84E271684AED4860E61D8DDEAAC614A4FC3BAEE80F1D9ECA1D7DDDFDF6CBD36726F3D3747C6F7E889A569AB83CB1B267EC1783F7F50CBB9C84DC4703FFE5E203638DA8F47D40D47B82AA81CF1607CBA2CF1A9D121FE4B3C3CB789455C343D3344D6471DEB846C526CD5BFCC5F236F0BFE42B56C3C7C3767EF2D560ACD62A8959221D6FD83F1A4897A4C524275B58C0A5A0985B282B365BAB73D08F7ED1095AF17D83DF309EB24055FA10658742AE93DE71E803E3F0FD2D6F090A5EDCB8D6934C8F71FADEBE8DCC0DC804F564E273ED85295B37741507E043CEF6D49C77D6699481F6B610EF19EBB5F99EB8563ACD4C9097952BF582D7C76C84DEF359AC60576AFBE7166A7784192E9916991C482021D45B663DF19533DC1793DB7A507F2247D39AEA4ADFDC7B76C88765183846ABCF23B0F8C8614268A3806C7685B728BCF1474C7D18967F64D77BE5A08AD6026BC2D74AE3D3BE48D699E0FC36C8A8DFF7971456D0E035E259A052C9564303B2847F0C12B728EE12903E2163F05671068B92C6D8F8706D2128294C0216C33383778C75B9E210089DA1343A29A01652938F9C5B63757925E9694149E773F9B77F17798FCDE5BC1839A93534954593EEDA41E3602C2FACF364937DA3AE3BDB498151F37E50D57E7FBEC184ACC144AC13AF2C14ABF07E9A87E4DB47497D998E09FF35150D54F96275C20B04ACB967EE74E0547C1B2601A2FACF5487432F5135AE2364CA8865C36CF330D729BA853D640140D9BF41389CB572601C3193329A96DC69684FFD532EF570DAD8DD551E7248B308F48BDD6C20DB6DC4DB812C98522084409D6D0092F6ACFF5ED6750BEE2F519E8E4C9107B15CF1AA47B03C39035FCEDABACC1ECA56223168B7BD35A920885AB271B4B60BE79314E8BC350AEFEAC206000374C69C1CFD4D6FB06070C2189A3ADC4D6EB2C5D73DF0F274254ADBDC0C1C54E8F9BB6D9E4FF00000000000000000000000000000000090C131720274B8EB984046244E424B5D0408EF1096235881568F4FDFA27CD9A7BA06F254159C1AD2E6708B2927D0728EC5065571218521021521A21A7221891B93B270995C36982B3DC1CDA09E5609009C2BDDAC875DE0DB4619FFB1E89F9B88032C6C060C15C260BDFC062AF0AB571AB7CD9E4EB2CC6ECEE3BD930BAF64C2A6C1B6E9582A1A0465116FFC58000AF6C9C5B65B9CD7B771F59F601BBC1499ADA548A0B342E2FAD954233EED3985E7E0EC772CF6CB64D87D91F6C705D6C2482276B29C857DA5E58A493813357372B720BDB8F993CB954A1700DD1AA766E667F728E1C2A1038B7A2C18A3A95B0C38DB4288C444BE20BA929D5E7ECF0E13CE38505C35F6F417A4917F286638EAD5CE26C26F60429142F30257758F82773598032A6493D4B2C435007BCE4D18D0077A3AD9DFFB7E1493943529A91F1A09DD27BCE92306FDFED7B75C6F542C5F6EC70ADE7CDD20AFEEB54CA3484812163B78D63DA1AF0826D143C90CB245576C68E8FF6E08933B59EEEC2F7CB64B2195DA9CB7661FA7C10BC980D98B560C3184206AB15173BB670FB021E1A23C4FC811C3DFAD022ACF0D851858CE2C90B6EDA575A61426482F7C78B9AD99F05D3C84B12A11015D6466A868E3EFD6245F734CF9728569623DDFE39D49F070E24C363BD1B62CC48B0FFC3CF90059FB747F397D2818D24748AEF2CCA1B0BBCEA0E18D1944A197C1CD75321622D589A0F + +# --- ML-DSA-65-Ed25519-SHA512 --- +PrivateKey = composite65_ed25519 +-----BEGIN PRIVATE KEY----- +MFECAQAwCgYIKwYBBQUHBjAEQCnbTPaiuWTH/EbxKVia8bGahMqjhsMg0nIaVsxa +fLvDF+2lXRegZNW13Z5R9QBsqyKO4p/bpkrCU813+1r3ljo= +-----END PRIVATE KEY----- + +Sign-Message = ML-DSA-65-Ed25519-SHA512:composite65_ed25519 +Ctrl = hextest-entropy:0000000000000000000000000000000000000000000000000000000000000000 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 544FDF45FA7C94FE4DE251EC5141EE6C24A945FF9D300C0C0785817BCD5ABF651A060C21F9CA3058EA59BBB2BCE9EC2036D431FFA43C96E00830981BE56C225EAD8F1AC5B438A1F60DE99BFEBEE83A567AEC50257A920DDB1BDDD8FCDBEED282D61EBB417D8DEE0CF585EF5D6DAECF32A9BC542DDC8FB54B77CA105E0C646067C82107AE525B978590DE3664C7FEE4673361B8CAC1271C783802F4775DF44F2B2376D34E74D7DF6F7869CAE630F19FD4A3FF9644DFF258F4D0546CD41513B904CCF0D4E8AF06BA76DA24E0C02FEEAB0D67C376BB684D9C37383BB1E70EF0A39FA1700B6BD903213C82F0FC659388BA8A2CBED735E88C7540334EEC907D3638B1AAE58ADA432BEB40A13073D6461BB325C53F8F5016F171ED16C8F62C3AC8C9929444527018733ED2BA7A04D6709E7F5253719C660E6392AA849C0BF661139FFDB9F1C0B4C6614728342E15019F1F37E6B5BC6E6991528359758D8A1E74FD206039921D7F8312177951072B484ED870C4828E8FC7DD4B2BB87D0CC8967140B47381FEEFA6C72BDF16E332DE73721B5E140CF8AAAC4C54791B63111409F1CE8E53722C3A609DD4D108F268ED8544603F89ADD8582E28CCFE5119ECD0FF37AB2AC83B6BEB5A565E41ABE1DEF49AD0D2C91CEF88110A01C09FAEED79AA7B7CA20B36FB70C242409AECA80E64B139A9364537F856C743252208E14E554A16E4241FCC58BFCD1F7D4CB0940110874F0127A045F2F03F4DFB88C43FCD22B8219111EEA39EFE5584489509CABC533C0A71EFB1569DD90205180AA473054EF5D5B5AAE9F907AEDC44A1BB863F862E49ED215C0742AE23D195478C5356C9B6CA68BBF408EFF1E5C81126C846EAF7038DD29AE78D8C4D4E61861CDF0DAD125C0B123F97B4261EF4E4EFC1B51FA929C2D082A3CBC0B12DED3780C63FC4386007FFE26FBCF0CFBBA131ECD550F5F0EF44C0EF51A2AAF144876C1ABF6F048BA6A97E09383FA712972AB42BA2432230781149332CA2B7D76CEA903E8C3990C1B856498F6E06D71686A24B391F523AC133647BB9A9629B78D5AFFE5464635BCB7603B69D0A190BFE2F81582BB72F194795B1204D0EB0E700087FA8614D69EFD6FF1BCF555C576750A1018AF608BEF87BE47C9F155929D9DEADFF07F80B5482CCD3C802788ED203770ECD40E4D8BFCB6D66CD4492A71987ADCA830578569FE13B44DB001FB7D792CC316A7C09A6A95A2565D4C1412FBC344D38F46E0267757BEB97DC181209885EC7DFFB5D7880F8B20202EB4EE0AE7EF59C696EE91C64EF2D07B02B8198BA77FE6ACD9B3B84FE5AAB767CA0EF0892C8683B645DE386C51B07874122AA973F9A952555F3D16D42F377EE1B3FAC230F8E068CF81B26507E5E75B7678AE6CF73C817B47A2A73D5C1368071AB47732AA4111C2C5131209582E9B8E421522F131E62F70AF03B5E1F236186F6FCC848646DDB8504BF9F5EFFF10351AC79C98F2E58E5317A79B1470CA65CEBB00DC6B55C45A11FC32BBF1DAC77FD2FF04A28861827E937B25F8B1130D8D864DE86A2A07FAFE99FC05F81BE46D44057DC21AA29FC06B64F6BED485FF0DA927DB91C3D5E83D7635F24282C7E1C25416FCFA1C10AD4C68A0FD0403E98CA6D5F8C7F07A9B010DCA52081628B3C22A867A3AE51220B5FF0BACC631DB2C96C79CC435B0CBA6FE5F6881D43DC24D97CF323EB110C13B0B01E3E59E5EF1631606B24858986B497E74D6F4DA3574973F52E631001AC6311B7CC2BDFED0BFC54CB4274E4B82E6DF9A642E44AA89D4F13EA55D27C5FD902E330CFA5D7072C901DA24CD5769B8195DD8788C6234E1CB5E1E1216A933C1A9BAEB0413F4A322D1B8D90CE1E318F542F6EC8A746CBC9976645A385303ECBA223E82FB41ACE461BFD70EAA3A9419E04B0229B4CA1278BF0E40CCDA15DD586F5061A89040EE63EEE421EF5C7A81400AA74A4A89E147DAC7868E52E318F8D087AF3EB88858ADF1D98ED23E8E7DA85B5DB55E214D6BC0FEB4B216CBBDB010672F6F6EE46376D54107738D3829AD073D92E8DB5EE853FA681D158FC898DC56C0133585722840E27115CC22F647064AAB0970F80E38C9C3DB5B528153EE47725CC978225E18DB4A92C33672F69A2D562601779303E796A0B0CAB27F2920BC08062A1C991B7480EB8F041FAA065627D4AD3F6D40D30592C37EADE77BC193221EB3BD0674AA73287FAB5AF29B8E332BDCEC5C199AC209F60410B22F930B01BBE8FA6D15C00C46A9CB9CB092CC72428614DEE4647A24AD03365388D7EFD52CF0A6B279ED9F987DF1B84A8861C0870D83291473EAF908ADE1CE2243B127C13AA61CA5FE3CD7F1ECB3C7A6A55825B866EA535C55987C3052C5C0D253E95485749EC3DB4EC5C2BC10E861213CDF7A251976EB9799E6FB00292262AD46B58C80260BD2BF6CEF231F923D5BF02E3AAD74C257E8D09D6C7C1820C8E97A0365799BAAD37A70F0C9FD191E6F0A7ECF1508EC368B3847EBE47E6BE85EC9FA9AFEBB39537227271FE978CBA6455D2B2EEF54CEF37B99A238352345E38F1B6E8DB8B6FA0D4D46966249298E3172D7CCCAC1C7710E9088E069F131483E965898DC83C5D4A249FA2770E4B9A8ABD109D412E0BC75F8B402C6BCAE883DB5720DD708D0EF4D5D7F649E207888B243710AAB8718258D28BB38A8D93EA09738C42EF24302BDA92EAB734E2FD90D4E1EDE16880D817761B3BCC695DD31855362DD03F27722A72F004EF1CADBED80CA6062E6BAFA8DA3B9D9B27EB6F7E1F07286076F4E11EF057801B66313855446FDFA2D639F707C65CEBEB5E09702114F0139BBC9395172039103C1B69E1860E239DE932330A5CCE08A4655FF7A7EDAC84C4EBCCFA3D0D968CE91176DC4EF40E8CAD5121968F923402DA9A48B4B1AED1A0E331287C951EB9CE67915CCFE2DD9800521D1796A35762108123BC37F04E399BFAEBD9120004823DAB2715E26F0567BFCF3189CACCC79C19C9AA08AE22A7BE3966A0EA8654A5809DEDEBA0837791477DD0CC0A8D293D85B15F9C13A13921A93698479281A627FEE72EA71518C5279CE6BF68B8937991A71C2357CDB856F6429240713D647DD8512C1C64890C57CC5452534DB6903D08721B9C537AC16786668EB0762F010F8E47BED2323A8C7053302FD7300851AE00CA26FBDE6BA398D8F9DA6AA7C74EF16465DE525A5CC4AB8934C1C1715DBDE0D904978612135BA22B6CF2E5F5457E4654AA5F040E79A2E6C367314F96B8671755AC2171B414469320B6F937798298BDFA4F7EF064A24C4D200CE340320ABAE69C4B561566675FB4F37D7FB8EF8512089923842B3384B3A184EF4B5B83A43845372C6ACB2D5FB7972F22AA1F48F707FECD0DD7D50AFF8A4930C02F60E7EF6232DFB09854DFA21C79C225C62A79F9E9F354AE36AC1B922DBFABA8A8E3E2F9B0A2426233FF5DDB2AC03524D8258F513F8FBF2169165FB258FBC523D9EE2451279F30D72B72CA693C880B98008B3A2A3CE9AC886329B582D104105BA62506CE3C2B4E1341D213340842FFF34AD4E32B5AF582E0B5E16A194A48BF2DC362F793BDCC6324FA2FDC4374E3FA5738CD1EE445DD414FEC39D77DF227C49CD915C05F0DFBAB49023CE2F5F766899B5B9DF6155AA9E2F7065796CCA7D849AEB7CCC0991756C9BA6FB39F60B15DE3568A2F92E4D8C41C9BB61591115D628BF2F789BFE4FFD7D89574ECD9E3E1DBA9BBF77372F682EB68510A520723F96506AAD738531DAB18FF4EDA66DE6F2FF6C53C78E6534466093A7905393E961614E4E5FD7DD506E49EDDD1E64D0EF39EE99416EFEE607FCF982F1245197571A363BEC2349939F1C576E83857F1B7AC0140E994148BE9CA34B54AAAD80B2E9FE30FEDA7720964896331D9F46B4FE31F20B265712D59D1314BAB17F5A40236DAE2FD3E996AF3F5A1A28370D0736F06CE4110A7786004C277A6A39EB768736E8083212A4C0213C375548ACDF378E38CE9340FA98424192EAA0B988E691859BA72D588C47DA6D09F29DD4C392467DCC477E804C5538184C24E57A0BDF108B9153B031E1DB0FFA08632B855C9D19593524F9A083CB487D8C5311952CECDFBF9D963080EEA384E0414FEFA70DB84ACF303C0014E1929CC039CC14A435137C2D5E2CE46041BB62DEA7313AEFC07FD6EFE2D9E625B81F0C282326CAD4924E2593043BE9F16AA89379B86DFFAE9FF4BD2E8E8CB4656288C322EFC8EB0EAC1916D5C5CE4CE9EB6265A5692735FB6568D5B46B0F49D69F74214C40421E5D87C2C71E8AACD32D2B66F0479F1CF669221E4E7C67C07159B326BE2332B09E0335D47081196D1FAA9E97E1C90482773A26A02040A788D4ECFEAAEE65A61753FA3A9C91DCDD4ED397104C6090FF79E8D005E08C659BF91EF5FD5A63420BF1ED7D7F284739EC850B332F47EF42FDF8EE5F703F2A3AAEE6CDD58CBE841E87B467AC14A178BC95B01D8C81F71D268CB09B5ABFB66E3E9A935CFFF093E5868C7563E82214638CC0EABF6619B889BDDD49811FC63521DD5B69AD33D9A2B9045CA4794962C33000A636990D1A8237709D59FFE0055DB1FFD2354B891DA0AD62C757D28E00413445A5C667CB456678A0133F76F718490999BAEAFBCDDFC1670CC00000000000000000000000000000000000000000000000000000006080B0E191C6A5E27CD9B59EF8819488CFE3A7F607ED883FB4711DDFA1D32CB93F04177CB4A1E7459316E699888BD5AD389E13B867EDEC9D12D0FB47EAB1DE001B97059130F + +# --- ML-DSA-87-Ed448-SHAKE256 --- +PrivateKey = composite87_ed448 +-----BEGIN PRIVATE KEY----- +MGoCAQAwCgYIKwYBBQUHBjMEWS3IXgQt1eTh2G1FGERkcjK7Qx7xuYI79HkrZ64r +wLckU5u28onvLD+Yu3367F6vQbQ3QuTTmfMXeIq/D9tWii+LWiew8Zgo/XliPTyi +cCQqRjmx4LsSEtq7 +-----END PRIVATE KEY----- + +Sign-Message = ML-DSA-87-Ed448-SHAKE256:composite87_ed448 +Ctrl = hextest-entropy:0000000000000000000000000000000000000000000000000000000000000000 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 052786ED045B50DA5FA9133F2C80C25250F59B8EC1149BCB6B749760060609881D9C8F4A024FE24716A0424CAE617141F31DB73F808AB49F9FEB18A73122B3986016508CA9D0514E2D3A8FDD0B688BCA5F35158B015C0779DAE4F71D833EBF803012B80BDE41F3DD7D3A316B97710397141CAF57F43C9CFFA99C4F98A9CE29A7094B2A408C3466FC36F053E388AD5C7F4AED1455FBAF806499D52C21AE74A00BE07B304CA19D6C13716B751F1DF4EDC8C9588C57132E99BA2EFE449927B3AC5CE1814442A167A029E5324F3E3DA7ED23917D9F1585442F4D55AEB94F21419E749356A3B6B1BE10D8CA6B3AE5F7F517425E395822CBF6D979CCEF58FA2E618FEF48A23D4AFE83EF022607ABA2BD06803D9E1F8634B59359F59AED412B36CB85B4F7110FB1AC62998BDE7210D92F046E3B62A7E890E2AF312C009FF2A4922B662BBAECFDEEB5B88A9DB4A8E27A2FD25C1B717F8811C3B986A3F440647680ECE000FFB5BBCB1365DE5A804420BE64E626203BAFD0BA1D677A324CC0C6FF441F4358515168F9703CE72D76926FABC638A0228E0CAADA514F7A0762E4ABCC8D58729861A92B93160AFC91F19A917CE0AA785F4644A74358EA1C60F422EF7313D238FD653415C6EB272EF7A9E5C92221E67A4E61BE56A0E79CD23DFE342CA68DC9952002A62F1C1BFCE1338431B528697B7F33D93DB311E7C629CD2F2C85316FEA1108227C7E153E7CB4B65880E330165D19EAE0AD7EED66185B8EB028BC9E9F1F6AF58A9963D9B68A22EF7FA89D738CA7F4B0BF4FCBD7C050392874D5D03CA7491EE665BA802C217640CF6F85F6B5704330BB8AA8A186C76369643ED653B1BE30904960F4298309016ED092CEEE1D968356216D184358347192367FF809BBC9FFEBE048BC6C8881E75A14464834388D019C2DAAD471B46CFD7D544B6237A9D42ED8DD8E74A3A0D788ADFBAEEEA884A948354816A7694F2BBD899879D98746CF99B9732EE4C3AF41E21A8F747FF4663C52A1035BA3E4E7491901DE65A73BA35F9F231B58563736C21D8CD5D2879B0C9DCF19D6FE2A7F30EF75E3749CBE6FBD7DD66C149CDAC36B5104AA9A6FBB3477142467D5725B51F2FF77C8EFB718D2AE4D4A9910AAFF2421B225FE29522241F1828C822C83FD0056345A9466BF1E48ADD62E547C81BE51BF1B4786EF5A76987B70851BA61B7B35567853BD213CF9163280882ED7246D52F238BB7008B0D7F67462C4395CC339997B8BF1C186AC4CD258CBD7C057DCE9FF76C81F8903F0F61D22C4C07EBDE2BD2F63904425366D5322498D5919D1E5269435059DC31F53882FE3C9DA0F8C911A03B03DD398ABD4E719D7F72CEE9FB91C052239304FEBDAC64883C0B6E171A2A0ADAF398D4A026A4FD59E369A072929D3256F8CCC4BD5E4D8A2AB35C758EB7CAEC4D3D537A25C4A2AB0E5B059C37BF69AFBE64C7175B11AAC7BED274EF7086B65F354888DA439C6A04ABAAC4F9A5728D25C91610F7136FC21B833BB743B1A54DE6343EACEAAB64B382A89C91ABAD9B37F3C90011F0CC664AC706D06B402FBDD824BD952425E2E42836A90FA59ACAEEEC0B74BAA294B1E8CFE1AFEBD5B5E8BB3DEAE923145A7B90C5824608078E07B061AE39AC743AAF57AD11CF2E2E7F4CA978463C7535293AE19683BBF26943F65DE9CDDADA2E2630C916D1C20878B471BC8E94123802B4F788DF436C097198BA8AA1068B6D9353F2A0CBEA2B73BA90D54C4EF62BCFFEA1812DB34EAE3B2A5AA46D8FF16ACFE67DE1AC3EC1625CB00B4D40489B038E00B23DE98A742164480E9278955E78A9E7CD5326A48FE7D9AE8327C863C22B749157812F6ACD4FDD6482DFDB7449090ABA18F4EB136B292C07DDD6C2B3B0C20E6583421A545849D77B95E701D072457794B87A902FAD20EE640AD70020D6A337C95C4BC7D122F9DA8AB68D99712FA6A49F79C195C708568DCE3792C44E1F9C6508C5C4ABF6C66C7946B5684C1DCD36FC7021D7675997C85AFE939300E93F909B0B0558CF0F67EDA64C2DFD1E8341789E61655EF20B306AD656D5E4F323CE1DB6051A66AD9CAA695161BF74E42640DB0BADC4F2A56F87790AD2B443EB7E10F44955C87F131644A5339705ABFEE2C9D16A89BAC03CD449C5D513EC3B03970786572113F7B566FB54764BED2719CE758ADEDAC42C66411C367DA566288B5335ADD1473700F8D367E65319A9F1A34EF570CAAA23E84EB7EDD14D7272D57F9E9DA849EFB537DF4EE5C2EF4D9C61400160639EFDDDE807547C381D34D6A729E12278E8A9B509EF5FB394BC875CD64BB70EF00EC9EF3EABDBFDFD024B11F6925FCDFAC897EC977E2A1334ADA36182B01355BE663A0E59F3E5F13A17FF4F5F1B89CFABB01C51FAADC107A81429D11DC9864AED50F6E658DF4AC4CFF0605D00412A14A57ED60C83E5C4586C2420F1270D60553AE3FBB313E66A8F2C3AF90F704E29C829347CEAA4B1D81358A3B9BA34BD7F367E8AB712F8DB87E29EC39988344A5720FE8C662CADAB3D8191408CF36DE08A41E604C58124879E47BAFD593D643E5CB756CF0F61E93863AC04D9920C6A4984D55B8C669A1F37C2032FF70D822D1EC00C37E41A6D91C5B67D9BD49B86E986F7119404D0C86C8778BAE4D3488E23F4FB9A5AAFB99066C8AA1D52FFB0167A2D908CB4EB60BA0010BC590EE3A0C941517ED9B3B7829D3A974AD6C3054E212657271EEC2E21D0EA2F423CF9C1C16994DB12ADDBA8082F6DF93AF04AEF477BDAD3952F788678818D319B7EC69F10994EA9B717A2C1020144B49CC210C6BB4FD56568CD5359870D40DC9D77859B7042D12773BCE3E78D00E01DD0A2A175FE8964B3610969C9AA985F56F9A6E309565C053BC83C0F71C04BFFC1768C494DF14CEF9B0AE22AE661922F01A2F13225B99D2D2B9787E3EB6EBE66E818E47AD6A0FD3F1A5C805858007D12CC1A98005A756CF94EAE35F1AFAF5BD7616560381B2B19D7F785B1B4C96007BEEC8201C4959CA375F63A115AC6F0C4103895E9E411D937587CE79190E7DA769856C494E8509378C409A0237CB452095AA3F58FF8F7A6B3616856D5025E498B91E8B9E194B8E703FFFD4314747481CF89A546B5552E74168B17BB9E36E6C40EF0086F28D7E93F4AB37D4B2268CD77E67AEF09E74C039C7C9BFA65B1B1B49D3002C56CA09D6B2A601B6C4D59130C448302CBE8115A211E7D3E50E046501A10E50AB08F5A1EF6A89DD78974BB568196FFE03337A30BE467BC0679C5819EFD0E12639EC568769E9B8DF745BC9450A35096495904CEA2E39FD111BCAB74E5B1293951AA3AAFBEC4A242290A15EEB03A50FC5EECA63620EA41C4BC7F50AD9F83CA7F364AD8AAFEF421DE61D6BAB6BA6D99E1BD71A8BC53468E358E7B24A70FCDC1F0971D2EC6961EA9A51A80F52B95053EEF6E80260EA863BAA651297BFACAE427496A45C8C07E0D85BAE25436BAFDAA9EB317580DEA2E7B1F27208D00A201B055922435C228D742F871F1D9FF2FDBF7241D19D8A8F1E411353FAC0C29E2C913F5289D1BB325A610C21BD00B1AD5B1BA215CD4AFE9EDC17BB722D5A627E3843D28F6B1878BDAFC462ABEA39FA579287BD7C6144C7ECDF7A2BBD68F2947281F63E7BE2C88431A78BD2AE3215AB19D6DE7804A8FBDF0BABD6AF01876826BC2127B107DD9FE9574020D15DAAD8C9E25A2EE0E80B88A69B10C93D0826C15B0F92217BFDB04DE553B93B71B10C5E6E630E85A5FE7FF0403B174B3AF22F7A2C0D124184C954D9C58D6B66092354956CBFBD3A9FB37481DD1DD9D80D351A779407E63FF4B0AD22C791BF5F1CA1C2CC47E4FFEAC2AF390C6A3D0FA666657DF30A646B5FCA4F66ED919116EA841ADBDE20101E236F849C0F6C3DC77071FFF980EA56C2359825999CC50F44A1C25B7689132D9F668C32185E172C935297C7363479D37CF6A15ADE3A8E4C4B5C7860FBDFF713AFC6483E8D559AC37FDD244CAEDA34BC8DFCF4CEEADABDB3F010D5DBED6E974C255D02B637E4262816C2066E5EEC7FDC97D3C4893EDFDEDEF212A402FD127275D22FB56ED1CE7C9D8F7A853F46A5CA7A42DC9F5602EC5A95B39019C0D7DDAC101B0D454B7F2952CA88AB09D2B8B916D3AB0B55B0581276CB26024AD644DE527F0AEB82C8020C1CE2F639C1F7272F42671B9791015B9941AB2B3D1473EDEBB7EDA28A128C268F0192E0CB9E4F180357DCC7D868CF6E359BADD85B3024C676452C0D0FBD621B3D9AD3D68832428FE1E84C1A33AA6B502B86EC6A2A65A11A5F5D2CD2D3E21E06E723EEB48A854F70E07B7DB6F1C267DFE0D6FAD16D9A682501B1DA5596E3B0B5243D7E0414164E1F7278A485B17904EADE6C2AE1C52EA1E055154BDCB5AE830BA701A61E1950B4305D4CD5EFD8D55CA4EFB92BD437F16F0A8339F99A6DD4C946D4A445E52C76CBE95DBE02ABD2C3E6BDF0CEF99035D8A90B2D2C47EEF140A0C96DE229133AAC6DE27500DEFFC0D59E83D4988B783311C08DC8BC5FEA514BA6CD1CE811809A7BB90D9232FCA1ECC6AE3BB6700AC4626F1BD98CB046E3E8DB0ED0D13276FA5E019952A7FE01C731073C55D6D7BAFC901C219B3197256AF76B8ACC483852C9F206D78CF2860FBF0023A96B902F259B06441D0148F6DF051F3C9A2A00CA4522373049CF2BE36F91B10CF2E338288FC0C1F1B675E0968D6099990B9D040D5948EDA78BDA25C0BEF46D50169A41742A744245AB2A41A0CB64C2B32297BE001573975E932B781B7C8029AE4950EEDCFBBDF586BD0CFF8B373E57193FC065B0B2E52604B693CADF43557868D00788EC92BEFCB78ED2D1417E23B0A632D8F9F8F01A4ADE74D9901050E3A16F62D00B5ED358CEBFBE02D011B01D534E7147B35FAE861E8B6363EADC28C6D8E33F1C965863FA035F24EAB326A28E0F9D760AE21BE22B83E2CAF4B6A7BC5D4384109B628564D3755915CEB85F4EBAB12F88F98B6D455D03C3DA95D9D2E6936F2AAFED357BFFB123771AAC4BDDF8AF9A1C98D6DC38CCEE0673803542E0B6057DD0DFBA59E62DE6CFBA858C9027054B7AF9E1AAB17A3854C7D92BB97F2B69D87BEDA4CB2ABEBF74F9593A9D5BEA8684E052F31AE5A20DEE4566F54E4936FACEB23A95B67810DC26640A70CE63157840B3A795C79FBC6A0D03352372ABE6CB0D240672069A4B8E0CA55994077E5942F2EDD9A240E366D455797AE8D4AEA91B8E3B5EDFC0AB7AF25D8E5CBC516D808CE92D79A615AA9951977BA5CB297874C7E492F0C69F2BEAB93F3EC4A59C248E5D1F2FEFB718D5B1D3AC05068E6EE6A5E43FE8FF007C9D94E2F621B953848C5135844FAB77D6CD75554E17371F476DB0BD64214001E56297D1FA38E774442AFC7A014388DFF447E6F61C272FC6F3AA9977367538E81F04F3FD757C4A68EC09C616BBD291A5099B1B9FF1D1A8061144757CC88BC8ECB3E637E5E5495C79A3FEF34ED03F82C3E5F355E4C87BB5B12CB9FA4E9A8FD18FEEB1D33763E472FA652FA3256B7A1542FEF6657A6148855DF9A76CE4FFD43A6AB7AF22C933A05C0B119441E960DA3A4D338BBF80DBCC5263E353C7AAFEFD5E1B508F6856FE59199A23395149700A5FBB3A7A18F99B2025E168423E3BA721B9F27A29272D7E1F05CCFE755F2A23731F7DB3A59E921E34ABB30210E5212CCC0EDECC45F6FF07740A0F013F23AA2BFD1DB428BF25A47B73392A7319F8E83CB771449CED9493BDF22E5B913169C8C9820F48122CF0DEB90354765DEDB50AB70613F54AE3223B44A085B9C8493391763AD7E63691B65D716FCCAE598DD6485E0197E6A5990308BF65A0EEB857F286FB83556FB9D30371AB4ED24D27F59F0F7120B933F6EE9D4FDE74CD9DCEF964D40D7AF4DC808C5578B1E8948B879396BD358A577EBDAE90102B96E5D26B45BDFA86CB401A2506B6A96B3EC48C34FB8237C334C6BCFD2155D86F5DA5D60C553BF037F196E561C0B6C9572DC0E0B99A2F983D3C19574F7FB485C9ABFB3BE30469FA075ECAD6959571EC6A812E680B2EE7C08017D7223E9ED8FD7D434D27034182A25A8B24BADF7EB4F7740075A9EFFCEB8006E51E6BB9BFBF05FE1AD066AA45130C656A7299F7B1FF1C9832ACBA3215F9CD5E667E737FB3BDC2282FCA18738A4557EEF63D8763B5B8930B35B3FDFB527C5BB9854BD8848796A6B7DDFD7F91B84B986BE2071F28D45912DFFB7B23AB0DAC17A358D6B3562A8421263BEA9700EE48AF2257FA635372748806860620BE0DCF4E48ABC6634F422980704B686128010FBF236487E1699AB6D994662A37B92B341698E729D36F073B40F9DB77FD7E4225C806884EAA94173F5108BF1A42366CF38895F643EA63C7E85CF016E06329D7B2AC76C133619649B9BE025A750E0CFD768ACADE51A28F60E402E9417207D0343122C5808B475317FF7FB3C73B4DA31718345055576DE8061033BAC8E5E7233A3E4E5B5C6D9CC7D7DDE8172838B6B7D4F93E4D6393BAE2E50A748C94B4B707163A3B4A4C6364699FACB8C8EAF7002F416C7B8B9B9FEC0000000000070E1A21282E3D46D15BF4E34A7B4467187F82EDE0928A4EFD1BB435DF3597EEA032CAA93E5E4DBA27F56EDD4A22867F27C0193CB86A3A4F1AD65F219CAA412B80443AF4F58E219E333CD8BC7E667FCD8C9D605E39156FB1E696C0A155DE9DBA7B170A925BE8BE1B800E78AFF196CBBBCA3666E7BA21ADF20500 + diff --git a/test/recipes/30-test_evp_data/evppkey_composite_sigver.txt b/test/recipes/30-test_evp_data/evppkey_composite_sigver.txt new file mode 100644 index 0000000000000..6e8f1aebf9d69 --- /dev/null +++ b/test/recipes/30-test_evp_data/evppkey_composite_sigver.txt @@ -0,0 +1,264 @@ +# Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# Composite signature verification test vectors. +# Source: https://github.com/lamps-wg/draft-composite-sigs/blob/main/src/testvectors.json +# Message: "The quick brown fox jumps over the lazy dog." +# Context: empty (no context string) + +# --- ML-DSA-44-RSA2048-PSS-SHA256 --- +PublicKeyRaw = COMP_ML_DSA_44_RSA2048_PSS_SHA256:ML-DSA-44-RSA2048-PSS-SHA256:2E5DB69836B5C20D0A56AD897F7F486DDCD329E09DD60BF8C88467A572EB8F5099B0E042A81726892132022F3AF2C3B073D16CA17CCDCBC48872C3CF87A8F9C9D556F358C32417158A7A5EAB3E33C8DC7A9038D678910B7F69CF1D655A3CB947F9CAC4FA6B00285478498EF13B403EBCF1BF3F5E1E0B27BEE2A64549314AA72EBBA571A39ABC1056651D7857816F7FB65CC3E3AC04AF2AFEDFDE42D9FE3E8D6BFF5B0F65576BE997ECA2FB536CCA3321819F3B46A74C614A790C7F54C282573B108637F2071DA385A53CCBA5E05E044DF6E591E57FD06717063B3D409BF24A047C1A5921DD60E72DB9EE36387C4B9647B72EC473AF7F5113323C0E80708E5D087DE1457630370A67CF0DA69E9AD56287F0EFC95554D3B32E5CC51997EED4B79E2BFAED0B9399DED3262E39A309E10DFB85AD148B5D94364B43274F4FB425FB0729716141591A6F5A72CC99B03F9B461BBE65282D439364E664A37786C1681387AC4D47CBE43DA784353F8B327248FE92E6C29EAFAAE0D3E42CC9A391C7A5966E309D3DBB263EFE0A639EEAFD1D69E613F0054E36025F63846C79D677E64C631B6AC81F488C82FDB858D1AC650376E1BD396E2D07378F1E6BF03FF25F5B7F3E96AB981658F1E8480CEC8A0506B2D8D8D8BB5562EB7551EB09667713B36A4463DDA5DF454BCFC7D9C5551E8E228CA8BBE6AF4A402B1AD5F170D3A022D970AA944DEF76132B78D03B49CEDF2626EE01E1D13F0C0E387166EEBB01482A8A89D333DB5DC7ACB21ECF06125DF31F9D9DBD326D9D4A252ADED2A43E7B4FCE68F9DD3DDFCC24E1F595013A9E23D945BC41F6125D268338DAD314C82F9BB1F4EF9C5442E35B397783F710F13EA3DEB24CD11D88608A09EA49A4A61DF53625550240FA7B7945C7017668EE020135AB8C24448C6E7FCB6409349B6B67FD3C973720BD39AFF92ED40AAEEB16E85902DA4673C71220290B7CEA5D35FF331B69441BFDC23A4F3B33CFB91208AD79F6BF4F7CBB93B766B07386A7E03EFB28C6228E74BB241EC08A13BA4D3CE5CBAF6DD18FF3B5ACD2968801E553FE1A343AE416703399F2B5FC122B7CF0BD59F21F7C4ED0F904C63AC548B1059EABB2B3139B373947A002C2AA2C2DB8FCC44FC0257600663A0FDB44F8F9B64E7D308C216F584F8142A062A9DA687D23387156E0F3EC7C8846D32DB948FD31C8CAB02EB24349EB9ABEF1522C874F8CFFDD75BD68DAF939ED53B405AB6E441FE48E2935B8F2623817DC63B6A0169B0442A97FD7F643D5E3E592FB78B934BFB183E2AC6DBA61C98C318CCCAD022511EA7EEEDE5A3C31ED4402BDD18FCB687E3B539121A087F8EF404D9ACFEA2C17A5C73A8A95EBE548A7CCABE9E9E91C901296EB48496B4C54830E58033310165A31812ED5CEF7958FFB176BF170098D67541DD3A911C26D22E4EE96D8632D3BFD35543B4D8E04F32F4307F23F99690D86AEDBA9263849899B1DC79D21C96AE91ACFDE1D4D67377401801B0F8050B9C3F54114CB606F3FEFB814AF92F72A73008638F6E4C081ABA98CC3C5C8482FAB5C7FA4BCE3A99CB942CCA459E23267CA7978E1675E9DB60FC6F448F5421D3975BCE0CBF7612401E8D09D3A223CF3944E98A0B2F91CB8CD5CDBEF6208AFB3894CD6887F1D0C2B0DDFC5BA126137E9A86FEDD47ED010C71C49C83BF8B4F3C4B10EA291717AD28F96C138D254BAE83C985BD1CE51EC86B80EE4A9BB2257CCD17474914371119D8F18F293972A804A6515E33BC66B4E6C8B8F14AAB7CF8C323783DFC553D20AF2E54D0223443E33FF6F1343A587A716DAC7C55FE3EFCA28F849FD909D9EDC4AB51E111C531FDC6B990654970D94153082010A0282010100D458650ECD7AA9A1DC565D8A3F5A947E8CDDFA3ED3C9E5618450E4F51CB4F539AF633C18CFFD9D5A6025FD043C55DF4FBABD37CF49E6F99DC553EDBC1C5E80C82F493166985A07ED2585AA585182020712E42FF504832E5FC6559F3339F0FA6F45BB8D7A0897795952749EAC504F4A6FFB9AC708D2FDC6F7A9B84A3322AA5E7B4CFD6316E8D8075A510D21F8DF4A289213AFDA2D9D3809DDCE40A0DB1ACA06A9AFDAC50261916C8FC9C6F81271E2060267ED60714BA868BAB1C3B4E4FB8D2CAF6940C671F1CAF5B84F536128FD3B084E2D8F77EC2A705EE1337B388F5292D2A28DE3503858FDB18062B02D9F24ACCF1127D40629EAA5640B8EA55CA9ABCB0F970203010001 + +# valid signature +Verify-Message-Public = ML-DSA-44-RSA2048-PSS-SHA256:COMP_ML_DSA_44_RSA2048_PSS_SHA256 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 2B7D7AEC97EC176859729C7FE56E1D745896C9D2402A9E2E3581F35334C1FF74252D99D0452918074647C29CAAEC822872AAAB61BDEB2BFB1F51E80C30DC55D9BBA66D4AFC5A304DE768F78DED94719CBD6E79745FF88035697FFA611237D9E702C0DA7B317E4FD2613787AB08D9CDBBF1BA1876F8422EF54B3320FFC2602275162FD8D1D142555C3AFFAF04B7288C328CC44FF78796BC0FE0E81F2141D2F142497D16C83E1972ABE8E90174911ACE9717DF542BA3B3E2601EA4EFE90221A3316800C6316C5E902D72BC2CAA9EA66C556DC6CC2693948C7AEA233E566DF8D9ED011B00D229B41852557FB94CE4E1A1296337E3D8E41B5824E97AE3331F6B902F849BDD601B64A8CFE4BA059D9BF400E3B6A08658E9B149B68A0C36E6FAE8D49F1AD4386755223C7D66FF0FC6143A1FC1F2D55E9208A48A9211AB9DBAC952B044F1DD7E2E7FC4515558C2BAB99AF79A94896584724B5E7B030FFB0A99B0CAA2C789825758523496F41CBE4A7BD309A3CFF64A05F1C59734984DAE2CD5710E97D3564DC27D22EFEA890AF773A93459BBC33FC1AF698DDDE57E08CB6523413395C1665A3C74662438F6D5F2AC0A185E559F8F4262BD7714EEE358A6F92AE2C61B953F0F4804790BF6E13ED7BDCC119BCD3EE6EFFBFBF6004F08B571901015842F7830AC7830033AFEBD9BF69548D0DC3E141E68DA162AA4A74C63410622EEE08D31C99685C23C7379B1CC8A10DC57EE28574394001F91574609FCA25ED19668C35EB326C732D79AD44289E3801FEC5CF75613EF3B2F56A01D62B8B9DDE9E0244BB3B947169B05E8903EC7EC7D07D63F6775FCBB8C4328B1CED92AE143FC7A585171AA526312B0D2806EBF2293CD3A74D8D5A4035829ECEABCCDED2FDEF561FE20CA204D7BBFAD592FCF54E0112917ADE6C4A5EBE902B3C21AE89A2C70B1BFCB67711409E99F35B5D4CC7C08D197475ADEF7146008807FC658A1858576011B131155B4DB57B2E7921F8932E1F65B1A042511530430D7C48BF226942444B988CAE4549415DDD9B64449AC98E8BB2043355CA719613CA42F6C19522CAE8B96D85592A083481FE565027CBFF5B1D68DBB7087E89E4C83BC089CEEFE623287E554F19F28C4B02116587F954B598A71E4E61CBC76B2B0F6D9ABB484CB5199F41208ECBC2DB4C13BD6729BF3661141102E9C48DCDFDFA7A3AE48ECDCC6A3C446FE9D30318403319CD1016B03DDBDE890D734430A4F38DED06A429C6B75A6EA3C22DC69F4E662A5417ED95687BED5297CABC4A6304E8633B14D84DEBE5562ECB4E24AC4724A4E7BD773A36C622937610706928B9DDA4265A27F01F7E204B4DAE546C858CFF105306504547B854E494237A526D3F2AC58C2F7D4CBC273FAE213950B8D20F1DE979D8B6B340F81C56F489C4C63D49315C7D384F6203B4499DFA30D60D5F251D7A3FA26A3A186D0DC4CC46567ECFCE324661C48B3EBA544C0B9A726B47EEA67D86602F39C54DCD883A6705B92338201D27BB88004C7E9B7716986BB3AC272796BA150A391FAA529C98EE473CE15D00A005FABBAEF291D652A2955DD51EBC9F0221B1D01B543B5DFE0732A4AB4EDE89A304FD5FB2DBD50A49FCD8D643042D966FE739C9F18C72E2CF70CF5B4C2B4E12567B5D3EEECF778086A92D04A7B6AA5BC63306CB89E2D834DEE799F9DE468F00A82E624161CB8D0A2390CFCAEE440CF0E4478B2F4C3CD9C1C7629AEB176AA96186EBD19B6448901F2053056D84C374A0758364CB97780EB19ABD25A336F6B485F2B5236C862FD28AED81EAEC25A56AA7BB714FC527521D5475C719509F3AAF98D541EF6839070A792FAEAC432330A0D9C596838244CFD679EFDB38CB58B1D5F986C96F084BE51C3B7E56C5A457436ACD1C9F36F57BAC57B6C2A2E51A81AE17E3E2C3C775FC544C91F2D6F6561E215F113C4F4B8A943C288E44A33C8F1B1BEA6AF0F522AEC3C60281570AFBF20F58175E3B8E66F2F376694B845DA27A88E2601E39CC16E2069A570DED0A5236A8F065D5A8E9D024D4885D86ADA9BEC54D29CCC3AE4D2ECFB25BC8A0F9F58F0A4AE8247606391DE8394D8FB062D8AA1E27478500E9A311D9EFD7569A73EE6CD664255C58E2629368B449405E4A16EC98C7257A13B2BD20A0114F2F64710C3A9BD713B697B40F2C80CE86A7FCB3CD9BF7F84255BE66EFB7AD71B709A2D68C6B55DA5626E9AE708D658A2F5E7045E0218908A6A77FB1687B4FE4A5264C50DAB2D3E25AC5E29DBB098D4D021E05742F69532AF2283FE2D71691977EB9AF13787A4CB85C15189105BC65BBF32BCAD177F5207C839ADE50E4B301F43D1289B23D4E7AE94C554623463163861C1BFB7AEB67823566B48DD7BF32F73DE92B06E249496B986C1042E912AA3C839FCEE9D40969BE5A0C17BC88C70DD8E14D18E13D2D87B8C73708F0BA286A985C4E5A1E155C593871FD1771F7048354B0607C4FE34C8122244782D421AB8248ECF19123252C013807B4FAE907263C9E1C0D4783D78831A24192F6F5714072AF30F80E12C748C61F4907BB8E6BBE656CDC4DECF3B18341A0FCFA6C5D57AA46B2C6D9364C08EFA6349BFEB8B3D515BACAF84D6D0E5D204AB4D48FEFCDC4A09C1B67B83888EE050A5B4BD44EA64C23A3AE2C422ABC7CE044C798AE6F438094573B192B594B2199E9BB5B1024943E908AEF25CB1A9B1C4C2774DA464E5D198E5185481D54072EC4EF480F2C2FEDA1257CC5BA50E2BBF92644877C228351405A48074F75B9C31C13679A993DCA77D5DDC238C227558AFE82A4C8D708C84AE621FD7FD1C096552EE2A47726150C4ABC4E18C84A70A594AC88C93CD8F696D9DE7E499DE795F710353800BD8D9BAAD89F181324A46A3247466812369A7F68F048D085C6712F665E99E6DA2644FA65CC60C8B7C7DD6D5DA1EF26DB827EE07C46B7183788C517729E69CECE098DB66E0861591538F19D74375105BAD1A92D21C92BAE5C0C7FDEC2ADC43D3532F84B23E5B72A2AD3ABBE0D01C5DB8AB3F707A0A352A4462BD807D6A377C16C14CEF9D61B44EE06EF15998CD26496414591C855D85176C28BFF98A5319616E91253E7EA9BF3E057B5A647AFBC3EB9078FAF4AFDE029FCE0731ED29679B0B1BAC40E09915F0A1615F4E9408C23642F11C319DFAF6CB29E0D87E2E96664627942962547BD931AD63D3A5422003A787036678ED7BED020BE9BCC0F8FAF5A8EABB7F0DA75AE5FD3D190D8184BC852FE990517ABB871782144522931BC1605B67BC133BD81A76C8225D4021042BD85021FE2AF7CB67BBC6C37D7E8388A0A1A8AECCD6ED0A162D687172799A9BA2ABC7C8DCE7EC06192C2E666B7BA8C1C9CCE5E6EEF7FBFE102E4A5F738A98A2A5AAB2ECF900000000000000000000000000000000000000000000000B1B2C3922261AE51AB4493F3DA1AB68CC3746F004E438BDC2DCCC8F79D10FC7888AA80DDFF065AF45BBD4E7C1A4215A9A7E9CBABB9B89A54086E5A3DD471E42B547258CF2F47F7BFB67FDC89D52F0C8C126526D0A7919FD013CAA336B929D78C67027490166C6A2C400D4086CB94403CA9ED0FEC33F9A3A0D32EBBC65C06F6DAE6FDE7D5D5A13481B20539E5F4865E1554B7E1C172C58EBEE0064A29813EFEBD66D2192C34E5B369732FAEE9BDB6092258EE56F698FA28272C5A3994E6C9EA055158C66F209FC22DA63F0BC6A2F41B37849C0735163C7BEDB15D78198D319D72EAFCFEC34DAD0596A11799D6DAA09E8FE0A68DC195A18E04196AFC24725957BA3ED7E4D + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-44-RSA2048-PSS-SHA256:COMP_ML_DSA_44_RSA2048_PSS_SHA256 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 2A7D7AEC97EC176859729C7FE56E1D745896C9D2402A9E2E3581F35334C1FF74252D99D0452918074647C29CAAEC822872AAAB61BDEB2BFB1F51E80C30DC55D9BBA66D4AFC5A304DE768F78DED94719CBD6E79745FF88035697FFA611237D9E702C0DA7B317E4FD2613787AB08D9CDBBF1BA1876F8422EF54B3320FFC2602275162FD8D1D142555C3AFFAF04B7288C328CC44FF78796BC0FE0E81F2141D2F142497D16C83E1972ABE8E90174911ACE9717DF542BA3B3E2601EA4EFE90221A3316800C6316C5E902D72BC2CAA9EA66C556DC6CC2693948C7AEA233E566DF8D9ED011B00D229B41852557FB94CE4E1A1296337E3D8E41B5824E97AE3331F6B902F849BDD601B64A8CFE4BA059D9BF400E3B6A08658E9B149B68A0C36E6FAE8D49F1AD4386755223C7D66FF0FC6143A1FC1F2D55E9208A48A9211AB9DBAC952B044F1DD7E2E7FC4515558C2BAB99AF79A94896584724B5E7B030FFB0A99B0CAA2C789825758523496F41CBE4A7BD309A3CFF64A05F1C59734984DAE2CD5710E97D3564DC27D22EFEA890AF773A93459BBC33FC1AF698DDDE57E08CB6523413395C1665A3C74662438F6D5F2AC0A185E559F8F4262BD7714EEE358A6F92AE2C61B953F0F4804790BF6E13ED7BDCC119BCD3EE6EFFBFBF6004F08B571901015842F7830AC7830033AFEBD9BF69548D0DC3E141E68DA162AA4A74C63410622EEE08D31C99685C23C7379B1CC8A10DC57EE28574394001F91574609FCA25ED19668C35EB326C732D79AD44289E3801FEC5CF75613EF3B2F56A01D62B8B9DDE9E0244BB3B947169B05E8903EC7EC7D07D63F6775FCBB8C4328B1CED92AE143FC7A585171AA526312B0D2806EBF2293CD3A74D8D5A4035829ECEABCCDED2FDEF561FE20CA204D7BBFAD592FCF54E0112917ADE6C4A5EBE902B3C21AE89A2C70B1BFCB67711409E99F35B5D4CC7C08D197475ADEF7146008807FC658A1858576011B131155B4DB57B2E7921F8932E1F65B1A042511530430D7C48BF226942444B988CAE4549415DDD9B64449AC98E8BB2043355CA719613CA42F6C19522CAE8B96D85592A083481FE565027CBFF5B1D68DBB7087E89E4C83BC089CEEFE623287E554F19F28C4B02116587F954B598A71E4E61CBC76B2B0F6D9ABB484CB5199F41208ECBC2DB4C13BD6729BF3661141102E9C48DCDFDFA7A3AE48ECDCC6A3C446FE9D30318403319CD1016B03DDBDE890D734430A4F38DED06A429C6B75A6EA3C22DC69F4E662A5417ED95687BED5297CABC4A6304E8633B14D84DEBE5562ECB4E24AC4724A4E7BD773A36C622937610706928B9DDA4265A27F01F7E204B4DAE546C858CFF105306504547B854E494237A526D3F2AC58C2F7D4CBC273FAE213950B8D20F1DE979D8B6B340F81C56F489C4C63D49315C7D384F6203B4499DFA30D60D5F251D7A3FA26A3A186D0DC4CC46567ECFCE324661C48B3EBA544C0B9A726B47EEA67D86602F39C54DCD883A6705B92338201D27BB88004C7E9B7716986BB3AC272796BA150A391FAA529C98EE473CE15D00A005FABBAEF291D652A2955DD51EBC9F0221B1D01B543B5DFE0732A4AB4EDE89A304FD5FB2DBD50A49FCD8D643042D966FE739C9F18C72E2CF70CF5B4C2B4E12567B5D3EEECF778086A92D04A7B6AA5BC63306CB89E2D834DEE799F9DE468F00A82E624161CB8D0A2390CFCAEE440CF0E4478B2F4C3CD9C1C7629AEB176AA96186EBD19B6448901F2053056D84C374A0758364CB97780EB19ABD25A336F6B485F2B5236C862FD28AED81EAEC25A56AA7BB714FC527521D5475C719509F3AAF98D541EF6839070A792FAEAC432330A0D9C596838244CFD679EFDB38CB58B1D5F986C96F084BE51C3B7E56C5A457436ACD1C9F36F57BAC57B6C2A2E51A81AE17E3E2C3C775FC544C91F2D6F6561E215F113C4F4B8A943C288E44A33C8F1B1BEA6AF0F522AEC3C60281570AFBF20F58175E3B8E66F2F376694B845DA27A88E2601E39CC16E2069A570DED0A5236A8F065D5A8E9D024D4885D86ADA9BEC54D29CCC3AE4D2ECFB25BC8A0F9F58F0A4AE8247606391DE8394D8FB062D8AA1E27478500E9A311D9EFD7569A73EE6CD664255C58E2629368B449405E4A16EC98C7257A13B2BD20A0114F2F64710C3A9BD713B697B40F2C80CE86A7FCB3CD9BF7F84255BE66EFB7AD71B709A2D68C6B55DA5626E9AE708D658A2F5E7045E0218908A6A77FB1687B4FE4A5264C50DAB2D3E25AC5E29DBB098D4D021E05742F69532AF2283FE2D71691977EB9AF13787A4CB85C15189105BC65BBF32BCAD177F5207C839ADE50E4B301F43D1289B23D4E7AE94C554623463163861C1BFB7AEB67823566B48DD7BF32F73DE92B06E249496B986C1042E912AA3C839FCEE9D40969BE5A0C17BC88C70DD8E14D18E13D2D87B8C73708F0BA286A985C4E5A1E155C593871FD1771F7048354B0607C4FE34C8122244782D421AB8248ECF19123252C013807B4FAE907263C9E1C0D4783D78831A24192F6F5714072AF30F80E12C748C61F4907BB8E6BBE656CDC4DECF3B18341A0FCFA6C5D57AA46B2C6D9364C08EFA6349BFEB8B3D515BACAF84D6D0E5D204AB4D48FEFCDC4A09C1B67B83888EE050A5B4BD44EA64C23A3AE2C422ABC7CE044C798AE6F438094573B192B594B2199E9BB5B1024943E908AEF25CB1A9B1C4C2774DA464E5D198E5185481D54072EC4EF480F2C2FEDA1257CC5BA50E2BBF92644877C228351405A48074F75B9C31C13679A993DCA77D5DDC238C227558AFE82A4C8D708C84AE621FD7FD1C096552EE2A47726150C4ABC4E18C84A70A594AC88C93CD8F696D9DE7E499DE795F710353800BD8D9BAAD89F181324A46A3247466812369A7F68F048D085C6712F665E99E6DA2644FA65CC60C8B7C7DD6D5DA1EF26DB827EE07C46B7183788C517729E69CECE098DB66E0861591538F19D74375105BAD1A92D21C92BAE5C0C7FDEC2ADC43D3532F84B23E5B72A2AD3ABBE0D01C5DB8AB3F707A0A352A4462BD807D6A377C16C14CEF9D61B44EE06EF15998CD26496414591C855D85176C28BFF98A5319616E91253E7EA9BF3E057B5A647AFBC3EB9078FAF4AFDE029FCE0731ED29679B0B1BAC40E09915F0A1615F4E9408C23642F11C319DFAF6CB29E0D87E2E96664627942962547BD931AD63D3A5422003A787036678ED7BED020BE9BCC0F8FAF5A8EABB7F0DA75AE5FD3D190D8184BC852FE990517ABB871782144522931BC1605B67BC133BD81A76C8225D4021042BD85021FE2AF7CB67BBC6C37D7E8388A0A1A8AECCD6ED0A162D687172799A9BA2ABC7C8DCE7EC06192C2E666B7BA8C1C9CCE5E6EEF7FBFE102E4A5F738A98A2A5AAB2ECF900000000000000000000000000000000000000000000000B1B2C3922261AE51AB4493F3DA1AB68CC3746F004E438BDC2DCCC8F79D10FC7888AA80DDFF065AF45BBD4E7C1A4215A9A7E9CBABB9B89A54086E5A3DD471E42B547258CF2F47F7BFB67FDC89D52F0C8C126526D0A7919FD013CAA336B929D78C67027490166C6A2C400D4086CB94403CA9ED0FEC33F9A3A0D32EBBC65C06F6DAE6FDE7D5D5A13481B20539E5F4865E1554B7E1C172C58EBEE0064A29813EFEBD66D2192C34E5B369732FAEE9BDB6092258EE56F698FA28272C5A3994E6C9EA055158C66F209FC22DA63F0BC6A2F41B37849C0735163C7BEDB15D78198D319D72EAFCFEC34DAD0596A11799D6DAA09E8FE0A68DC195A18E04196AFC24725957BA3ED7E4D +Result = VERIFY_ERROR + +# --- ML-DSA-44-RSA2048-PKCS15-SHA256 --- +PublicKeyRaw = COMP_ML_DSA_44_RSA2048_PKCS15_SHA256:ML-DSA-44-RSA2048-PKCS15-SHA256:F6799156D8C2182A9CD1DD67B7744C0DC18B067AA2337597BDF4A887E0BD52469BB27A8A3A02FF67B8D28368C1AF40D7D6DA29AEFB3865661717D77BC0494DFE941C2088C5F8D68EAB4FB246548CEE2B7FAAA4DAE23CDE84DC8A95AAEA7770181B3491A453076CEB446BA7E4A3755BA6611A2480F2F92FEA6FCCCC709C7E276A58FC132D8062D27087B57787124DFB7065ABF6FD12CFE8A0BF57CB39AC99587D1D32CE236F08BF75C149DA8B5D8DE80209033AC350B803BD1EEA4561610BE58FF07CC0DF940830897B4C0AB656E745C9BA2B1741B10ED1EB8B9ED8CDBE25AA173B703B6668332F459BDB00326F523989FE37039E90F52D9A69890708579FC738BFFD9A4A8A431D4932CBFDFEC7AFF083D2085016787AAB937D0C4506F64D5D65B4E7A7352F8A559624E8ADD9B2698E26862C69B7A5C949BDA200116DC709BC0D1E2A3D98788DF2DA2A28E4845DE78300D747B90F06FB4EEB426939451B017C5DDD23637F3FFEC4160D2F50D34EDEC5860565621B84E16EC05B6EA01D2C7B40AE131151EBF9485959257877A2ADC81D725AD79143053C8340468116AADB25800977783C621572A68C98467318222F366DD7C43A812826FBE7FFB1ACEEE16865E46F94892E304C9EA2BCCCD872917FC92D1E6268BB53C04D580088A1051BB98ABDFD5ACC813CC1A9FABED3D8E7F42447411FC9FB0F53EB7398301B817CE75CDCAD11F64448E14428A957C5409CEB47416846A2EADB902AFB7102A263C528C98320E61806FE893B39BE425CE2EB7D858D2ED8B87344FCCA53D64364BC6E6A80F205DEC75AE1C5702FE3307FAEEC8B69035BD77028B4DB82D6F3BC46D00BEDEC9094B958D565D30F31D1365A173A73063213680477CE0EF81E6B4DDB943B5ED04380C20C9F837B6F0C97A7404D9F83979E8B1979F34B4334664140FF83F20814441262D60A79A1FCD3990014457DC7AB8954E702BAB330428F5DC8173A4B316F2AD4FB5AA488052967BBEF5086A78400B8CEDDE46566662AB23290918DC769249AA9CAAE10DDCD68F0ABE9325FC2C0C2D3B487A1167B2626A59CB0D58D342A26A54DA43E9C2DE15AC09DCC6C72F2446BD0DEEC4CEDBB342269F2491E87EDBA812041B7EEEEDAAF8DDC6C8519AB78BF8719E181522D8C1F5A608EEE9903F96C4D17A034A5159BD2A3B61BA3A92729984FE2651F087972DF332CADA5CB9A78CBADCC8A3A8BB1F7061C40C5B1A482B78B69932146548573E386237EE6F631FF506A12F046175CB38DFEF07ABE2A2AD7A7A0D5D8A1563AA4232FE5EC1623BD361F85810FDC31413A4112BE55D82C9DE0383F5EFF9824BF42E919609ABA0E8A9DFFCF0DBDB7011A9A5FC785D5F8E5CA335E2885FCC989AFC8C06B8664F1C9D93BB22A55D5DDD98991FCEF1C4BDCD50C79DE9C49F1CF9487936636555301C6B1D3DA426213F8D0367ED48D8E02CAA9D25DBA87C18F03A7C7D3ACE057C503DB05D8C89A3FDFA62FE872A9D1759ED535D49A7AF4AC248EC578C4F2EF5B0F66EE6DB88040095A68A55FBC3E42EB26DDB6961E8A6CCED4D680D056448FF8C47B602FBBA1ED09C5DA5770F1E2B8C14D99BEB36826C35E3E4F2B45CD7A6E05DEACE18967F9686F5FB52ABD4456D94DAFB3A2CB999DB8161BF23270DEAC796D88B8940281A9EC1670CCE38C7E485A0631180F73F418CDB18BB7CD3EBBAD778FB446F9C5C82BED00BE83DE42228C962D6744F86A92BE4BC2CFAC1E1E067681F4A6776C40CADEE0447F69D5AC76334731D1A8CB8F2AE0F5FA2B995684018F6E0B2D80D8E296E2191B5C0C96C97FBE48CCE408AF86FF59F445E6D1AFBDB48A7E93BC30FA9C032DDB9CB23082010A0282010100D36DBE90D91DB27EB643531E032783F85B13135FAD7B8A63C29DFB76FCA2B32B3F3E69E7CCBA5014FA0C5D9FCA83F341502F9BAAD1BA2E6A82DAC32D537BA170B477FEF75E6D07F05EA0E2FA288136DFB5225A2FCEA672F87A98FBA23AD6AE5ADE7953C29DD99909BFC52C97E905B906015DE6991082FACEA5EEC253D539FEEB09CCDD36B81304E70A63F4BF6BC9ED43A8763B4E99CC050F36811230780FF1286787AB181BCF7C0D8683FB9CDB170442875A156BA5DC7920E634B749EECD44C0E35981D51997D89AAF0033C6E92B580E173D664C5A8762191C7953C96C3429B6AE3F6AC31CF9A884B5E9B1F40FB722B09AFD0982FA6054D9306C40F5A0D31BD30203010001 + +# valid signature +Verify-Message-Public = ML-DSA-44-RSA2048-PKCS15-SHA256:COMP_ML_DSA_44_RSA2048_PKCS15_SHA256 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 23C59332E93B0B45AC0C1386DF76F3DE7B2EAE285AB4C87DA24957581D158AE325338FBB0DD5AA179CBCC8BC96648433CCA4016F8E16DC3EC02BE16CDF0713943C9A2FF285F603DCE75C9192C7DC402ECFAF43309AE628C4E60F0DAEBF9A6217B24C5D4D00E0294779EF8514C58D40E419FB1A0BE0AECDF9A695406815F08409ADABEA36B539DF4860BF91433A7E8E0C194AF125B667129D6B75FE97EDCB7754400F78BE28F195B76717C41B66397E654443BF3168DC80C10F5E87DD330807FC4EB68F9B1A62612E748E136DFA0B7D5A9B87F69DFA4112F8ED03D3BD10C38F848BB9FAF2C76DF4A3CC27A10A82B4B58697F60BCA8C77CF983536732B7D234C6E42E705874F915E264B2D017792248E1219EAE075318C2049EE84C6EA3DC69B21156ECDCE5A3987DF00A1497C03689FD2896B7D9941F469B2CD13ADB7E5DD528BE35E3AEC4F8FE4D09DCD797062CD863742C998AD065D57EFB2608DE2C25D5191EC298DEE47A0A8F05CD2D2866FF1863FD7172C3EC9DA7320A20E5D8BEB3B7DD497149FECCCBD9695D0BE829C89C4DCD6E201A82DE8669F7CF1F3E996489AD84382BE534A6D6512AE2C178BD77ECD6B003E95B41D8BF9EB5A23813C04C8B086AFE87F985196A6F9F7BBA4A3DD6419FC3D1B49A0B1ADD678C7E89A1FAB68E092E9BF64F9F021D65B69B49F4C51A6C838CBF6DE75CC2A71D2DDD0FB70540BC72E27C991F80069D761C7A872FA2D776EE922542280F69752455E928ABF3FD6A07BC1A6357AF0535B5D871D505A52FA5343C9B92B046AB94A966D850CEA6442E2E8B4FDAA0DB9403B9C54B524928D001E0093E0EC5B4C9DAB99B0D85D0BB2A5B49F921B07D87AF65231CDC4359707D83099B614D8C694164C1E89CB326BD854A15E444182A172ECBB62B1EC0A2A2F68F9AA4A114B5DB2CADA96A82CD2669B65D650BAE04EADD5F809F0E97E187EBF0C4EF418D1025338D249273E8FCFA1C8D22E27831831EC18AC89E59CA1886787337FB220DFF402ABB41B08AC778DBE69869CD3B0FAD805D0DE1B650DEB002E34494C2411A682C8D38ADA12DB45DEED8334060281C2BB1188F791EEE1B2EDB0F65A48701661F0F539638FFA66E24EBBCCBA0F1B5A01EE2964D29B493D9B1E33D1FF555908BAF3D59DB8709A1ED5E07A514E0FA21EC5189759A76BC07942B0163D758CE99D64270C70D9EE56D876E3760B0CFAB746141B0FBA7F23CE7667AA9DB0695C943E432DE92271BBA6D507E5C731908E5FB819BC7FC2A4690BD87FA48802BF7B5B6BDEF737BA3D8615D2FD7C5A7BD8706E173B08B3DD579DA75BA5B7C4805E9488EE96F93024ECFB2D49448AB1AE89738A36C39C2144D9A02D2AECD04C595BDAE045E599543212DB19FEFDC1250D355FA67CC69724ADF66F6B37E198E5556ED9B0F0A9D3C774FF2CAA8BEA4C85E42CFE55BA6F050B1D424199067E7D7E54DA86677073A779C984C0A48E581316E20957AE685BFC880DB08328DAD2EE97725A0AB273BDDA828924ABACB96ECFF92195DC89ABA3BAD7EB6861941A16655F896B4E18BA992FA9326F8F438D01DC214B4F8DE2B768774D17F490A2B7113B3CB3128A054E3C31584E190AE83AB1E131DA2C3CE8CACD4BBA9B96ACFBEACDFE7357DEB5ED7B32EC297FC4FB38CD5077E016209084C3CE9D37C9C080789CF4E8653B9F4B4F407FAEFF50C29459B7B585A561DA6E719DF9D63ED517F7EBEC8BA98304046D4C175786ED0A84BF7068725E54DF4C38C8F6EC93A8ECBC37F336295D749C7A3E8F3E5686D9CF93723E80C39AEE26683CA71FB9E044810ED9DD2ECC65EA533B1022379A58D1404D1D6A798B74BEE8E49E10369D738EAEA2740A2B83CD23E708C02B43BFCA967A336D94AE0973E5D026A19784722DCD5ECCBC0C819D5124AEB7C5209E3302AAB70960FEA4264ED58180C511AA3E00AF108D340890C12427523D970787E0CAF2F4E8F24686DD091C9213187EE690CDF417E8AF8A32DEC91B8762D98C0518B43527E149B4E737356CAE01E23FFB2D8322986F06E56748769FA5B07293BF4FCCD39CCE6C09599D7B164B26F2A98E8053F3852ADD4A64204D90A53A7E0A2D718912476775FF92A99D888E7A4785DAC3B9D70C29639D5C1EB90045B34432719E31EA4282FA2A53FFB91211ED4025A462042D4D5F4E065873BB6B9232692D074A0181B21DA053FD98875F5E8A941475FED7C7F643C37D174FA8E254ED49EC9E2EAE80869CB37A1BEFEC7401394845F16F2847D54D26A6070CB8E88D2DB00E1ACA4E2E3B0BB93F0A4D76CD96219390852970D79C05DCA4440A6E6F5EFBDF691631B96AF7B7813FAFFD0E74874EE4A6FA526E586DED35285CBC297399DD4EA3EE4AC148F09625DEA8D3825257CC399C6AC508416E677408DC1FD737579362A103E2A344E5393D40DD5E4EB2FAE15ED0108D06C7E7A54A171A47AA147D3E127411153A7110854FF75123C0495B05A92262426DF7D92E6BE658901C6B1E600181AC2130B4174B6B8F6244D8D2A375E8C8414170059C25124518CB4B6F186798657D96EB46B5F949F064641A2E1DE5B13CE890DE84465BA26415D5B07A735782F788948952CAC50A55C5398037F830A6ECA86BCD057F2B815E003BAD93569F3890DD5F3F065CAE556F74CC196ED944E0BC63F6BD751A4667C3F7FD338530B2993A4CED95BBA11CC6B385A17B0E50AF373C75B3064850232D62D6C607913300639C0E23AC5413F39D9E115A1C08CFB7F072B7605F56721E0E92A355CF855A49660B55CE442663C8546BA977F25709BCC049F3C55E9AD909BFC82E43AE51A395EF7D8D13E2B13F5B4606A4269327A152A66176BAF0266A9DB85AC0CCF92DAB7EB0267F32F38622272ABE3C7B5736B0192BED3965F43CFB29C303D511B5B9B734DCAFA9A0A9A6C8D4BD6008F793C7745BC3E82333E7FC5F76490761A93DB615B58641022249ED0926F8B323DA6BEE1621D2E0B292449FBCDD25329F635163EFC0D098A0D07BA32C78BC922DF9ED81A39454AD1E81C5C418FFA07413423E27B4483869999031039F103575BAB7E624AA72028137D3814600C104CC37262B5350116480B3C68F2D418096381CD2E4A98E586469F85109AB18D3C07B82235E80EB62DDDC3CFA2D60439C4D070706C1C91819558A9CCE090F528C10BCF63B1CAE750285FAC8FF64D9CE277490230D92C8AD9A18F2E8967E815B3AB9FE65208C70A7468961E13E838105722A04EEDA45A8E22BAF321CFE8C1C9719F174D05241A6D9CE281A858E2AE67C136DF5F65E8600820D4483CC0C1B3D425F61878B8F91CAD9DEEE07080B182F33373C6C7B8792A1B8BDC2D0E7F5111B203F42546D729BE1F229393C4355647378878B8CA0C3DCE50000000000000000000000000000000000000000000E212C3BC8B207F28E331624FA599C6B6D0A9079371641D25538F3018492E6E0C600ECA2B6D0EEA679760B83A8E928889502DC84868C3C4799115AB00C57753930F1424F1804AD39AF69304122C08C2599D18AD8D062521C343471EC4C10FA0F9C3A2CA5B8F637D15B69A25F41547A5C90800A26E579057EEB1369556362E5DFA4F2EE225DD6C781A7A231D9D34E7827B1E90E6FBAE0BCB6A4B2421EACB38E0C88B274B8B7A9131598158D6CC3E7EF539C441F46AE03B016229C6CCFACAB06ACE1D23B77C0ACEA7F2847CAF4734A6E5BB668C0C45EE2F70CB978A9FA2F3EF56EAC6FE5FE4AEB11BC0AB2775CC477AD665A6ADA327C5165560E3D53CB559E05BEED367AF4 + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-44-RSA2048-PKCS15-SHA256:COMP_ML_DSA_44_RSA2048_PKCS15_SHA256 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 22C59332E93B0B45AC0C1386DF76F3DE7B2EAE285AB4C87DA24957581D158AE325338FBB0DD5AA179CBCC8BC96648433CCA4016F8E16DC3EC02BE16CDF0713943C9A2FF285F603DCE75C9192C7DC402ECFAF43309AE628C4E60F0DAEBF9A6217B24C5D4D00E0294779EF8514C58D40E419FB1A0BE0AECDF9A695406815F08409ADABEA36B539DF4860BF91433A7E8E0C194AF125B667129D6B75FE97EDCB7754400F78BE28F195B76717C41B66397E654443BF3168DC80C10F5E87DD330807FC4EB68F9B1A62612E748E136DFA0B7D5A9B87F69DFA4112F8ED03D3BD10C38F848BB9FAF2C76DF4A3CC27A10A82B4B58697F60BCA8C77CF983536732B7D234C6E42E705874F915E264B2D017792248E1219EAE075318C2049EE84C6EA3DC69B21156ECDCE5A3987DF00A1497C03689FD2896B7D9941F469B2CD13ADB7E5DD528BE35E3AEC4F8FE4D09DCD797062CD863742C998AD065D57EFB2608DE2C25D5191EC298DEE47A0A8F05CD2D2866FF1863FD7172C3EC9DA7320A20E5D8BEB3B7DD497149FECCCBD9695D0BE829C89C4DCD6E201A82DE8669F7CF1F3E996489AD84382BE534A6D6512AE2C178BD77ECD6B003E95B41D8BF9EB5A23813C04C8B086AFE87F985196A6F9F7BBA4A3DD6419FC3D1B49A0B1ADD678C7E89A1FAB68E092E9BF64F9F021D65B69B49F4C51A6C838CBF6DE75CC2A71D2DDD0FB70540BC72E27C991F80069D761C7A872FA2D776EE922542280F69752455E928ABF3FD6A07BC1A6357AF0535B5D871D505A52FA5343C9B92B046AB94A966D850CEA6442E2E8B4FDAA0DB9403B9C54B524928D001E0093E0EC5B4C9DAB99B0D85D0BB2A5B49F921B07D87AF65231CDC4359707D83099B614D8C694164C1E89CB326BD854A15E444182A172ECBB62B1EC0A2A2F68F9AA4A114B5DB2CADA96A82CD2669B65D650BAE04EADD5F809F0E97E187EBF0C4EF418D1025338D249273E8FCFA1C8D22E27831831EC18AC89E59CA1886787337FB220DFF402ABB41B08AC778DBE69869CD3B0FAD805D0DE1B650DEB002E34494C2411A682C8D38ADA12DB45DEED8334060281C2BB1188F791EEE1B2EDB0F65A48701661F0F539638FFA66E24EBBCCBA0F1B5A01EE2964D29B493D9B1E33D1FF555908BAF3D59DB8709A1ED5E07A514E0FA21EC5189759A76BC07942B0163D758CE99D64270C70D9EE56D876E3760B0CFAB746141B0FBA7F23CE7667AA9DB0695C943E432DE92271BBA6D507E5C731908E5FB819BC7FC2A4690BD87FA48802BF7B5B6BDEF737BA3D8615D2FD7C5A7BD8706E173B08B3DD579DA75BA5B7C4805E9488EE96F93024ECFB2D49448AB1AE89738A36C39C2144D9A02D2AECD04C595BDAE045E599543212DB19FEFDC1250D355FA67CC69724ADF66F6B37E198E5556ED9B0F0A9D3C774FF2CAA8BEA4C85E42CFE55BA6F050B1D424199067E7D7E54DA86677073A779C984C0A48E581316E20957AE685BFC880DB08328DAD2EE97725A0AB273BDDA828924ABACB96ECFF92195DC89ABA3BAD7EB6861941A16655F896B4E18BA992FA9326F8F438D01DC214B4F8DE2B768774D17F490A2B7113B3CB3128A054E3C31584E190AE83AB1E131DA2C3CE8CACD4BBA9B96ACFBEACDFE7357DEB5ED7B32EC297FC4FB38CD5077E016209084C3CE9D37C9C080789CF4E8653B9F4B4F407FAEFF50C29459B7B585A561DA6E719DF9D63ED517F7EBEC8BA98304046D4C175786ED0A84BF7068725E54DF4C38C8F6EC93A8ECBC37F336295D749C7A3E8F3E5686D9CF93723E80C39AEE26683CA71FB9E044810ED9DD2ECC65EA533B1022379A58D1404D1D6A798B74BEE8E49E10369D738EAEA2740A2B83CD23E708C02B43BFCA967A336D94AE0973E5D026A19784722DCD5ECCBC0C819D5124AEB7C5209E3302AAB70960FEA4264ED58180C511AA3E00AF108D340890C12427523D970787E0CAF2F4E8F24686DD091C9213187EE690CDF417E8AF8A32DEC91B8762D98C0518B43527E149B4E737356CAE01E23FFB2D8322986F06E56748769FA5B07293BF4FCCD39CCE6C09599D7B164B26F2A98E8053F3852ADD4A64204D90A53A7E0A2D718912476775FF92A99D888E7A4785DAC3B9D70C29639D5C1EB90045B34432719E31EA4282FA2A53FFB91211ED4025A462042D4D5F4E065873BB6B9232692D074A0181B21DA053FD98875F5E8A941475FED7C7F643C37D174FA8E254ED49EC9E2EAE80869CB37A1BEFEC7401394845F16F2847D54D26A6070CB8E88D2DB00E1ACA4E2E3B0BB93F0A4D76CD96219390852970D79C05DCA4440A6E6F5EFBDF691631B96AF7B7813FAFFD0E74874EE4A6FA526E586DED35285CBC297399DD4EA3EE4AC148F09625DEA8D3825257CC399C6AC508416E677408DC1FD737579362A103E2A344E5393D40DD5E4EB2FAE15ED0108D06C7E7A54A171A47AA147D3E127411153A7110854FF75123C0495B05A92262426DF7D92E6BE658901C6B1E600181AC2130B4174B6B8F6244D8D2A375E8C8414170059C25124518CB4B6F186798657D96EB46B5F949F064641A2E1DE5B13CE890DE84465BA26415D5B07A735782F788948952CAC50A55C5398037F830A6ECA86BCD057F2B815E003BAD93569F3890DD5F3F065CAE556F74CC196ED944E0BC63F6BD751A4667C3F7FD338530B2993A4CED95BBA11CC6B385A17B0E50AF373C75B3064850232D62D6C607913300639C0E23AC5413F39D9E115A1C08CFB7F072B7605F56721E0E92A355CF855A49660B55CE442663C8546BA977F25709BCC049F3C55E9AD909BFC82E43AE51A395EF7D8D13E2B13F5B4606A4269327A152A66176BAF0266A9DB85AC0CCF92DAB7EB0267F32F38622272ABE3C7B5736B0192BED3965F43CFB29C303D511B5B9B734DCAFA9A0A9A6C8D4BD6008F793C7745BC3E82333E7FC5F76490761A93DB615B58641022249ED0926F8B323DA6BEE1621D2E0B292449FBCDD25329F635163EFC0D098A0D07BA32C78BC922DF9ED81A39454AD1E81C5C418FFA07413423E27B4483869999031039F103575BAB7E624AA72028137D3814600C104CC37262B5350116480B3C68F2D418096381CD2E4A98E586469F85109AB18D3C07B82235E80EB62DDDC3CFA2D60439C4D070706C1C91819558A9CCE090F528C10BCF63B1CAE750285FAC8FF64D9CE277490230D92C8AD9A18F2E8967E815B3AB9FE65208C70A7468961E13E838105722A04EEDA45A8E22BAF321CFE8C1C9719F174D05241A6D9CE281A858E2AE67C136DF5F65E8600820D4483CC0C1B3D425F61878B8F91CAD9DEEE07080B182F33373C6C7B8792A1B8BDC2D0E7F5111B203F42546D729BE1F229393C4355647378878B8CA0C3DCE50000000000000000000000000000000000000000000E212C3BC8B207F28E331624FA599C6B6D0A9079371641D25538F3018492E6E0C600ECA2B6D0EEA679760B83A8E928889502DC84868C3C4799115AB00C57753930F1424F1804AD39AF69304122C08C2599D18AD8D062521C343471EC4C10FA0F9C3A2CA5B8F637D15B69A25F41547A5C90800A26E579057EEB1369556362E5DFA4F2EE225DD6C781A7A231D9D34E7827B1E90E6FBAE0BCB6A4B2421EACB38E0C88B274B8B7A9131598158D6CC3E7EF539C441F46AE03B016229C6CCFACAB06ACE1D23B77C0ACEA7F2847CAF4734A6E5BB668C0C45EE2F70CB978A9FA2F3EF56EAC6FE5FE4AEB11BC0AB2775CC477AD665A6ADA327C5165560E3D53CB559E05BEED367AF4 +Result = VERIFY_ERROR + +# --- ML-DSA-44-Ed25519-SHA512 --- +PublicKeyRaw = COMP_ML_DSA_44_Ed25519_SHA512:ML-DSA-44-Ed25519-SHA512:165A6569022056E604034E2737D557C8C58AE170E14619DA19A58EE85AA80AD883AF9ACBF3DA261054887FCD755F16DB1E928127344EA81A8A7DB3E0B2B31166305D1DE467E4E8B8A4AEDBB217630645E6EF20AA3DF302E743E4CCA2390854ECC35DE2900E14989B81BA94B15C3CE111C8472C2C9BA503C176BFBE4EBE0D2A1D1C11A0E2F461650DDCCBB033FFD5DF43875379EEB1CE08F2E2FFBB639AA3D8AC2CC5B291000DB0642817F03603D16A3CCC97C167401F2A41F3332B9B623BA8CA11BF9F7740B9521C0E61EE0D5CB6B3A6A1ADB15F36674202D43AD0BC75CDBDE3F21D3FE138049841028CEC3F0C512B3DE7850564F605AAF42B875272465FBCEDC162A1018E8DF9F7B6DDAE858A4CAB3C91C9E6B2C23C2AF2DC890B86401AE4D37C3A97AFBE9076F4C1E25297E36965832208741C1CE03063BA0598122551FCFC469B3C3220148CF4F8173C05BE8A37C4932A9AC97D1C3D04456AA8BA24AC61834896003193B2C10AF287D9C33E0DEF5D5CA3B2D1352A9F71115BF904FDBF7680412FD566CC724F26CB1CBA40083B2AF6A0C272D7B01C4299A556B33854644D995322CA7F60177D6AF3131562206B14639EE2A268BA4C7A4D07971F4176F49033D6FBCC5948306C35D47041B60FD1DB651F2BEC76CCDA9265E4B764DE9FCA57EE9B66009BB22B3739F871AAFC83AE037D0E803191DE3CAE1EAA5E5DE67F224A1440153460F231AFEA991A40133539A3DC58C6DAD5E0E270DE69C82698830AE1632DB254DDEE4CE178FD9D69C59F174370F1EB3900EFD7F83FB74D86319D6279411F5C009F04DD19E3F87A9937685DE347F2498D1C743317AF2C460A3770EB484E7CD0A59398610C33D51070FCFDB09FFE560364811286457870D34D6AF2F033121AE22FC9859D984168236F1936DC90F4C7E2B8B7A961DB883A73B738EA2A0EFF6E665F950ECDEF2DDE5FCC16499D20D1887D28326AC2C21CEE66A80F6D0BC50442AF6750649F2634E8ECAFE3689C20CF040E2EB29F62D7A594D5B07045BF35A7E2BA316ADAC7EC06FA6D9E067FE7FED917058632D6BD1F05F8938B315063A6E76B41D2CD7A87930C260D8736D191A8EFB244E1B0656A0285435D96EF86D27BB1F03F6F03C6DBD6296E7A22CEA532EA9956483C190316E08CF7857F522817BAFEDC34E8F7A03C36E9FD17C5031CEAF6F71BE4553D92C84C767BD3018E88ECE8E054647C157378899011CD4E7E04141AE106E59310D4CA23CB4A3492017DE82A45A6BBD4BD2F19AB86C1E077628EA9B64BD7D12866BC7E790CAC79A2E30EE179EBD0DAE95D77DCDA9E8F8E823D364DA7AA23C0D4808CF6366A2D43D2167C190A5369E4D146255C154A6CE141D10AC51B0524C2E5124B5681AA8F478E4408626F8C69EC31A529FEECD63F3C647D4E80EC3FAC86C532CC8A490B0A2A6236D81A37156DA254BFD2A0F18E283BA931026FA25922795A8AD038D4C6C7C32DFFD5A64ACCE9F1F71488B0E83CFBBD2CF709F5084348037D08BFC34F165823FBD3A547783C17D6BB1C02F9F609CEBFAB74DB3FD6CC62812F4B4E29E4B3C6787B6F5FF3D5C9FBFD24DA806EB4559ADB9301DD6B42188F3472B9247E5F7B079B97134EB25B8D1F9889DAD1FBD11FF72DC6CBEA38874BD0DFA31CC73E75F76AB5A9545D596786998AF78F00E5FC07D27BCDBC5D861754D5E50D16DFAC12E1B203A56C4EC1DFF1F65E5E96CFC32D4E051326362277C06F95402EE0B933239E1B3B9258EE5A5859D4C96C9C6AE85FBCB9D71DA5EFCAF79EDC225E4A727E93818837B34C73EEF2460C3642DA6567A8E1BCA0474E120FBE469A3C24606017292BCBD9732A4FC8823BCC1046B2A778878182640AA23A258F9110950218A6D0B31E3AB4915568BADE5A + +# valid signature +Verify-Message-Public = ML-DSA-44-Ed25519-SHA512:COMP_ML_DSA_44_Ed25519_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 8DFDE5769FF0CDFEDA1CD0165CF50B49AED6A2A55B15769CFB3910A4CB45473FDD41DF1B6D7AEDB52F972A8EC5FF36F466E45F1ED78634DA12567914BCF5348B6635AD5B606398FB0E51CA192824F969DCC47FA7BAC5D86F892396D0CF65EE00FF2BC6483E81A1AABFD3D62BFDE744EFD812B356E43722CBED06B7DC18626445004F8777483862D9688FB6FE60922C111AB1ACE0F8919249FD8134CF5470E572DD63A5F8A9D250EDE41597636D78934D7764A2F46BEE799663045E6CAB7524E2E8F74150443AD4E0A28961180DAB5E58A46A6608F4E2A090149E0477203156742437B6CED7E399744E77F6E34336CF67A93A1E824C35004F887B0E961A9983E1AB7C132282E3A3AC1DB09880BCD780D054A90116B8651D6FD2635C9C7A61C8ABE12D5D65571248CA29C8D3DF36836B915710AE35EE084876C1C50DABC61C605F046A90C14D955D706AE419E83BFE405EC4DFFB8C15DB4C17D1D1D5DF5FF12C2CF5D1A16AF88D6F487D33D6CDA5A36628F39DD2576FC31B7FE3F18554001F87CA3F3314617B274952E3818BF8FC422ACC2E02357536CB7CC417ED040551B4B05D0A29FCEE016BD103649FA32E932E8B4FBE3E7BE0CA16A144B29BD16F93AD0C1E6B54BD4A30E000101208C03DD475CE926C9CA76665458AADFD8C001E69A303FB1BDE2ACB094B0E51FDDEBF516AB23DD21195761688A0674453E7BB03E8B9523EB900840919C1C5C5E1C2D6043E8234E5553C89B7A4C59A5080723F1A2E53A94173B84D3AB96378B380066CF76B7636BA71F060722A00BB387606F9A628DD9F8ABC800DC9F877EFB728829F3EB56FD841C85BFF6DA5F7AFEADEC716215880F802954499EB38E61A68BF4F1EB09E1BCD5BFD0502959AE6168CD4894EF2CAFFBE27AA2B6C80D7C39AC66043DA03AD7C926D74AB43E8772CB6599BE574EC91E4C1F6DFCCEA97596ED502062F5F62BC70A7C0916D13D9894096D9FA1524FCE2DF751374DB98EE9C2EA1D573F9DB3543BB811BFECCAB1AEE7DA31E7E27217C73361535085F163583EFE0DBC390547A6BF7DFCF338E0637ABD98E7D97B1660948046BD171C06E35A3E73C3931545F28EB8807815FF277201472AEE420A9947E2EA078E4405ED0A312D2D01039E4C465FF892EE6A2467D9AB6FB4DFCA08AE1BDDFE3CF97136EF4F346EC8497AC614503075908F3B2CA21C853512AB817A15A79AF75C334BEDD01573DF9859AB62E17165BBE3108C56949C53C0B2A496429208FC66D0D4825E73ED97E95FD399DB582524AF6CFD440E99FA0564B621B33041DB54B85F69E12843A016FF095B8F1243356858B9404D77A7D14A26067DEB8783D8F9D9911B08F483111518C0D379246C17F8C5D25D06578DFB86F3F852561A0157DCE744533856AB8051014BDD582C535FA5CAB93CC10283025CE440BF88AE4547611760940CEF18F46B9387FAAB553BEC4D5653094FB01743DEB489EF88C6FA80C87B9109750ACA2D7828E74B147E6218BD15B01F1567546D7D4D709301F22A4AA2A051392DAA19E8C3E860CB4FBD17FEFE739A93D9BA6F0B45E48C6B012D5F4464D326632534ADF1CCCC3042CBABB7928168505D134158395D35034C4CA4DE56A37605A6839E6E7458C571DDC032D96755007E891891FFA64B9DE1F312C8DA6496E09F4B41A0E0FF2FEC0EE64F188A8A4F28E5BDCFD7F3337752F4295DBF250070007DBA375E3E6690659482550306720FDFBF1A9E06CD108CCB65CB8FB1FADF712194D248B8CCCE1A769B71198E4B5FB0E29E543A3DEE053B7F415118E7601AD51FECC542EDB459F2EBC01B618C89DAB0B51452F7417B0FA7D7F8076B10CAA8022F7C1B9B59725D6693EAC13F70B0707070A421AD7C675435DE403DA7D15C70E2D3177372855541282D1C53590955BDE6892B7CD2A3C5D938B4B85AA109A0CC1E3863803239F2E945008D397BC253073AE93054AE633C2AC04CBE3457442F30D3F4F2ECBBE9F3242053A05EF9F552678A135F8F3FA93C897E14895C406E40241D57366C0EE93C7A2DD048A2E90BC4B591AB5C04E920471B37515D4B6166C59FC9C3E2E7FBCB93BE22AEBE57140574ED7B53125AEDA9C3F5761EC9021A8C6CBE8C8620FDEA470A28C44CCFACDEC804B2553A9063EBB773C5FA11C05229181AE5748372415C53F44360C169D30B3AC8FB5C997E14E5367A70EE0BA02264CC9BD4D5845380F6424A4FF84FC6ADC7CA9FD624360FFEA6BE3BB84BF33A1BE94043B828094E85370794D724D9766069E6505E93C325ADF7497A920053A845FB3E86A816C5D4767007B55738042A8C18AF9F0D896B66CECF81A41B78255C50A0A8984314BE0DFB0F6381CA5FA468B51B5930B2BF76A3582EED7803D2453CE2200AC2D9828990792D295B2C9D44162CA0AA5A63645FD3B3B1A1B30C5B4FFB640E1154E7C9D8BF66FDB95AE60F37D4227D9981CF9F6F9BFEEF97CF65A132BD2DE81F1A34A4D14D2C7191839DCEE131829BA3ADE6C227D8636852DBAA9BD1914E8A851F8EB420AA81F376F05C269BC90DA47721E2FDAB2E4B1E05DF5AEFCE8387FB3C08D7E9EDE6A72500D577F1217053F55B2EA6D08D9C9C450731BA57978D3E2E198036B78C45B7658B3D2515196C642D4AE4D18362654BEC5EEFF1CD64FCCFF002F0B1A278CE445D11EE7996A356F6717D5E229A617A17E05BD9204D5AD5EEE7203DAB9CF2013BF85D6A912D68915A79DDDDB9AE849898D60443107E98F0E447337879C4FF36F2A927A551728DEC41FE7839C8A16000E2F063BAB10E59C142ADA4FF18D889F359FBA53EE17ECC544832E139D7C3C72F699ADB5C72C03C6E39386AF3D438F03F67AF91E5584BF564B5573AABF81F6EC3B3DB66B16C82860252629F7068BD866D0D10ABC4367A92F0BCD3620C0436D93B242BD39C14B1D8AC233CBC791EABEF52A09A6DBD51E4EA234FDC27D083867C3D58E10D71DCF0F8662A830161BA8A21B6C172F97D211C92A9BC54957F8E0797019FC2E1C8C8AA2A85E810BB00BD590540A01E8BD07A1CB14F8E0ADB109ED4AB5D0AF9A95F9F72D194CB040EC8BCEF2091B300D3B052AC08623484CC51626E958307D43DA53D9D8328CAAD4D67B81F23EE6C4A814003FA27D30FAC282C0EE2BE1956856820334A3E34DA89FC7B376BD769871370E2B866DD40B5C9FF63CDBB02F6D9D9CB7BEAF606F3DA1456D6FEC70FBB1739F15DA453549058EF2F8DF5AF31D6F122466BF202531DE0C17D2A351C38D2A2D87F907270FAB6F07B58B0C8FBB0CF77D95FF820B0A17AB6A641D607A3C7FBB390C171D244D568E96AFDCDFFD0A454A607895A7AECBCDEDF12D2F3C788FABAEE1F2F8FD04263750A2C8D6DEF20000000000000000000000000000000000000000000000000000000000000000000000000C18232C38A7A66954E1FDA808213A91B1982C12E9D4946866F0C568425C14B04ADCA4A4D2879914E67260F46ACFFB70168AB02BB253A87388B626AAA46C83C4D829940D + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-44-Ed25519-SHA512:COMP_ML_DSA_44_Ed25519_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 8CFDE5769FF0CDFEDA1CD0165CF50B49AED6A2A55B15769CFB3910A4CB45473FDD41DF1B6D7AEDB52F972A8EC5FF36F466E45F1ED78634DA12567914BCF5348B6635AD5B606398FB0E51CA192824F969DCC47FA7BAC5D86F892396D0CF65EE00FF2BC6483E81A1AABFD3D62BFDE744EFD812B356E43722CBED06B7DC18626445004F8777483862D9688FB6FE60922C111AB1ACE0F8919249FD8134CF5470E572DD63A5F8A9D250EDE41597636D78934D7764A2F46BEE799663045E6CAB7524E2E8F74150443AD4E0A28961180DAB5E58A46A6608F4E2A090149E0477203156742437B6CED7E399744E77F6E34336CF67A93A1E824C35004F887B0E961A9983E1AB7C132282E3A3AC1DB09880BCD780D054A90116B8651D6FD2635C9C7A61C8ABE12D5D65571248CA29C8D3DF36836B915710AE35EE084876C1C50DABC61C605F046A90C14D955D706AE419E83BFE405EC4DFFB8C15DB4C17D1D1D5DF5FF12C2CF5D1A16AF88D6F487D33D6CDA5A36628F39DD2576FC31B7FE3F18554001F87CA3F3314617B274952E3818BF8FC422ACC2E02357536CB7CC417ED040551B4B05D0A29FCEE016BD103649FA32E932E8B4FBE3E7BE0CA16A144B29BD16F93AD0C1E6B54BD4A30E000101208C03DD475CE926C9CA76665458AADFD8C001E69A303FB1BDE2ACB094B0E51FDDEBF516AB23DD21195761688A0674453E7BB03E8B9523EB900840919C1C5C5E1C2D6043E8234E5553C89B7A4C59A5080723F1A2E53A94173B84D3AB96378B380066CF76B7636BA71F060722A00BB387606F9A628DD9F8ABC800DC9F877EFB728829F3EB56FD841C85BFF6DA5F7AFEADEC716215880F802954499EB38E61A68BF4F1EB09E1BCD5BFD0502959AE6168CD4894EF2CAFFBE27AA2B6C80D7C39AC66043DA03AD7C926D74AB43E8772CB6599BE574EC91E4C1F6DFCCEA97596ED502062F5F62BC70A7C0916D13D9894096D9FA1524FCE2DF751374DB98EE9C2EA1D573F9DB3543BB811BFECCAB1AEE7DA31E7E27217C73361535085F163583EFE0DBC390547A6BF7DFCF338E0637ABD98E7D97B1660948046BD171C06E35A3E73C3931545F28EB8807815FF277201472AEE420A9947E2EA078E4405ED0A312D2D01039E4C465FF892EE6A2467D9AB6FB4DFCA08AE1BDDFE3CF97136EF4F346EC8497AC614503075908F3B2CA21C853512AB817A15A79AF75C334BEDD01573DF9859AB62E17165BBE3108C56949C53C0B2A496429208FC66D0D4825E73ED97E95FD399DB582524AF6CFD440E99FA0564B621B33041DB54B85F69E12843A016FF095B8F1243356858B9404D77A7D14A26067DEB8783D8F9D9911B08F483111518C0D379246C17F8C5D25D06578DFB86F3F852561A0157DCE744533856AB8051014BDD582C535FA5CAB93CC10283025CE440BF88AE4547611760940CEF18F46B9387FAAB553BEC4D5653094FB01743DEB489EF88C6FA80C87B9109750ACA2D7828E74B147E6218BD15B01F1567546D7D4D709301F22A4AA2A051392DAA19E8C3E860CB4FBD17FEFE739A93D9BA6F0B45E48C6B012D5F4464D326632534ADF1CCCC3042CBABB7928168505D134158395D35034C4CA4DE56A37605A6839E6E7458C571DDC032D96755007E891891FFA64B9DE1F312C8DA6496E09F4B41A0E0FF2FEC0EE64F188A8A4F28E5BDCFD7F3337752F4295DBF250070007DBA375E3E6690659482550306720FDFBF1A9E06CD108CCB65CB8FB1FADF712194D248B8CCCE1A769B71198E4B5FB0E29E543A3DEE053B7F415118E7601AD51FECC542EDB459F2EBC01B618C89DAB0B51452F7417B0FA7D7F8076B10CAA8022F7C1B9B59725D6693EAC13F70B0707070A421AD7C675435DE403DA7D15C70E2D3177372855541282D1C53590955BDE6892B7CD2A3C5D938B4B85AA109A0CC1E3863803239F2E945008D397BC253073AE93054AE633C2AC04CBE3457442F30D3F4F2ECBBE9F3242053A05EF9F552678A135F8F3FA93C897E14895C406E40241D57366C0EE93C7A2DD048A2E90BC4B591AB5C04E920471B37515D4B6166C59FC9C3E2E7FBCB93BE22AEBE57140574ED7B53125AEDA9C3F5761EC9021A8C6CBE8C8620FDEA470A28C44CCFACDEC804B2553A9063EBB773C5FA11C05229181AE5748372415C53F44360C169D30B3AC8FB5C997E14E5367A70EE0BA02264CC9BD4D5845380F6424A4FF84FC6ADC7CA9FD624360FFEA6BE3BB84BF33A1BE94043B828094E85370794D724D9766069E6505E93C325ADF7497A920053A845FB3E86A816C5D4767007B55738042A8C18AF9F0D896B66CECF81A41B78255C50A0A8984314BE0DFB0F6381CA5FA468B51B5930B2BF76A3582EED7803D2453CE2200AC2D9828990792D295B2C9D44162CA0AA5A63645FD3B3B1A1B30C5B4FFB640E1154E7C9D8BF66FDB95AE60F37D4227D9981CF9F6F9BFEEF97CF65A132BD2DE81F1A34A4D14D2C7191839DCEE131829BA3ADE6C227D8636852DBAA9BD1914E8A851F8EB420AA81F376F05C269BC90DA47721E2FDAB2E4B1E05DF5AEFCE8387FB3C08D7E9EDE6A72500D577F1217053F55B2EA6D08D9C9C450731BA57978D3E2E198036B78C45B7658B3D2515196C642D4AE4D18362654BEC5EEFF1CD64FCCFF002F0B1A278CE445D11EE7996A356F6717D5E229A617A17E05BD9204D5AD5EEE7203DAB9CF2013BF85D6A912D68915A79DDDDB9AE849898D60443107E98F0E447337879C4FF36F2A927A551728DEC41FE7839C8A16000E2F063BAB10E59C142ADA4FF18D889F359FBA53EE17ECC544832E139D7C3C72F699ADB5C72C03C6E39386AF3D438F03F67AF91E5584BF564B5573AABF81F6EC3B3DB66B16C82860252629F7068BD866D0D10ABC4367A92F0BCD3620C0436D93B242BD39C14B1D8AC233CBC791EABEF52A09A6DBD51E4EA234FDC27D083867C3D58E10D71DCF0F8662A830161BA8A21B6C172F97D211C92A9BC54957F8E0797019FC2E1C8C8AA2A85E810BB00BD590540A01E8BD07A1CB14F8E0ADB109ED4AB5D0AF9A95F9F72D194CB040EC8BCEF2091B300D3B052AC08623484CC51626E958307D43DA53D9D8328CAAD4D67B81F23EE6C4A814003FA27D30FAC282C0EE2BE1956856820334A3E34DA89FC7B376BD769871370E2B866DD40B5C9FF63CDBB02F6D9D9CB7BEAF606F3DA1456D6FEC70FBB1739F15DA453549058EF2F8DF5AF31D6F122466BF202531DE0C17D2A351C38D2A2D87F907270FAB6F07B58B0C8FBB0CF77D95FF820B0A17AB6A641D607A3C7FBB390C171D244D568E96AFDCDFFD0A454A607895A7AECBCDEDF12D2F3C788FABAEE1F2F8FD04263750A2C8D6DEF20000000000000000000000000000000000000000000000000000000000000000000000000C18232C38A7A66954E1FDA808213A91B1982C12E9D4946866F0C568425C14B04ADCA4A4D2879914E67260F46ACFFB70168AB02BB253A87388B626AAA46C83C4D829940D +Result = VERIFY_ERROR + +# --- ML-DSA-44-ECDSA-P256-SHA256 --- +PublicKeyRaw = COMP_ML_DSA_44_ECDSA_P256_SHA256:ML-DSA-44-ECDSA-P256-SHA256:D2D4B1C579468AF6E97E40F3FEF407CB6C1783F5E38A85F168A112383DD346C7048D4DC5210217ACF9E60B2C6290A7C17AE793F6DA7401D33BBB784FFBD80AF99EF51AEC03E7D860510D3E004BD5D646B2F3D6F6D74E2904FA1B06E92372ACA7E1739E2E200E383A26CC19023DA36E3656699ED0D8E26A98252CCF033B6A94E8F0B12ADF59EAB01C0AAF08D69001FA67BC4FB91B5674704E284150F98DE1937C1681E93740AB75E42291123014E6ED8066C971B7A0BED2B39B233250A0E40F0A5CF66C837E9FCC0CFCC4C8D9BB0595ECFC39603E5282EE4ADB6423B2DF8AC1AC7B8117332941EA2CA2D47F0A62B8A90F7394B6CC0691C22E8DDEC8CACCA4337B1D1FBE35F74964277C019E7A841442167FFBC508F3F19346EEE8870842467FD19387C49ACDEDEB6A8566CBE9A8FB4657589AC08F0CFE3247F5545E4B4AB610F443CEBF187D7B9717B280FFA121ACEF737476EF1ED3D176C1A71B02FE0DC83A39E3D892F74F9E6EC9F8FCC5E6A49FC361D12764D126130AB66F22F12B2FBD9495348855A4CA743B060222CCC713EDEC1F36102244A091BFA95F9FB01A85257E2340388937C1ADD7F396535D9AD2EA9BE6074C8177967CAC5C3573C3586070B5811EF6278A79CA0821C25EC4959F867BB1E73359EB3C79BF9717BB7C0D6343704D00387418D86209E77DB9679C312C2366521E1E4C1B0B2D7141E27478E3D45847FFF9A1A120E10F5130BDB501C140893DE38C5B398636651C453F4C22246B81680D92D40FD5320DC93989B4681F69AE7A971602EC128D6D78DF80BFE7CF8219DAA596703C51C061D43A308B6F287ED9C1E82B86CB597623ACFFA4955A70EB60C08E59454E813211967A06D600A5C374C68C8383087A0FCD2FEE35E49B4D520F90A8085CA0EB39F9B46381751B305105448FF2C4670717FBDBF453C064FDDEC84C0C6DFA1A6AD2B858A35DBC5C8B46170AB3EB1EE6B0CB7390938AA96EBCA7970AAAF0D65429DF948D7B1A860FE3962C5E6ADDC8E2FF22F2F61D5782B9569687214886D207E48253AFE6FAE8C41C902D8B7ACF73B8E3D9B3B3D933772170680A54486A7C984BF61FEDA914937422D2FD20781B82FAE766A8A628A7EEE5F84B1D9BD5D6BCD0FFA1400A592A1B6CE493FE50F8ED206EB76BFC4C187BC2468E4A8E34CEA54796320C6E60FF677B5C805266CEB9844493CEA3C92FB4F3C190415037F9C7DDBEF60694206633EB92508D3FA5564AC01B05506BBC316241FB70D9ADD2CD5EA6B9D3DD9A238B7CD36E737EF910326EC1BE1F0AD2101FCE3AB00D551F215E6098385B17F16789D43A78D1BD198AAA8FC3B6C03604FC26EA925CAD3B3420944C556492B0936974C8E73580430CD09C576013061E2179F6CAEA6735D2CEF17293E1E48BC27EFDD8D1BE031891D1154526551679DDF9FCF322D56421FA28E8F86BE6DABE781499F9DE1DBB905CD1A6FD9BC13BBF2B4711366A1D9AF36757723ECDAFA3B6CC1AC69BAD0E400F4A39DAC50033502D1281B92B3C2C5EC4A24F30B3AD83F4DF028C78CE22999BB5789C726E1EE048619AE2A1FFB517F9D901B90E733274D483BBC069D86DA5F4EC9E8498DC6FAE6B5E86DF48DF2669461EFD867E690AA5DFB27B807CD3C7C2E733E143EF8ABEE7CF75F6F85B640516EF6601E8C9AFD73E4DF913014AAA9938B11B5DE529EB0164E0E5C6FD3DC1F2AE83E9F697E14320078C7FB5EE5F8ADBF515811F0450B10DE1515C8381D4C17DE21738010559441E8BF5C55766B18BE922EE2D8F9030E1948C35F954A21A41E3D86E929B76AFC9AA034A3BC4B805567DD27FC858ABF4A96B161066C2C7D6DF762074341ABE6CD304CAF258B19DB3284BAC11B0407AE7E23C3814981FAFE126E67D1C983251820A58174157A8EDD5AD789D77F750BB1DB055D257619C041F49A9D47CE43A22D48DB4 + +# valid signature +Verify-Message-Public = ML-DSA-44-ECDSA-P256-SHA256:COMP_ML_DSA_44_ECDSA_P256_SHA256 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 2C534DC369F19E41517D27C823A364072029E066699B978029D37FF85D53B56803ADEA45C95272FD6B1572CB455C88B62EE1E5F0734BCCE62AF1732BA9A346529B6C7352F9DD025677A0FB168DE0726A51A6D511E616A574F3209398BFFFEA8D383DFD3964F6127C4EF62230C2FD2652EC3575EDE4B472553623449B4EF0F24991CC9D6C6A61566D359A0871EE10A477A7259F721C911EAE4751CDB399C91887B7F3ECEF43938264D11EEC21C29189074F2A300ED8C930D0372FB71D85E69EBBF888EE4A582C190AF72379888919EF4110FCC4666B4FFBF0690EE65F8B754059B3D03B96F4D881464C98F039FFBF5061B56E2ED2DE05AE70C4003D181445B68081939B4DE8AE330471DB408F33A1210D7168B88BADCF0A36F964556B5ABD87629AF35AEFC81147B4FFA4B2FAD7DC129C429184A28F150674D84C79531C4F81568CD362C30B6F746AA16B0ACFE97CBF4BF5F6ADF011463680861409F9894DFC62375375D321DF3EA40B71CE9123311BFA6149124FBAEF1FF09D4BDBE3C270C69F134A5FF0E5AEA04774B912B3744A0D15736F649B5AF5083FA0B0DE40789779F2CC49D1E30AB829D13974E7E5C23AA84A7E78BDE394925B770F8EC31E9E0116AD43F00DAB37DB2D3B4DA3E11188EF88C000031772EFE2CC70552F9849D552B3E731465A6A5CB2DB1942B7B8B114F0D268BC9963274FB9F8F00742F12658D9E18CBB992A14565DBF4A084263585214F2129A41CE9A625AB174E4FBD6A8F9CDEAA34A2929290115D163F7AB511AA0B2F065EA89E89B37DF6A53639A078A2E9EEFF1FA4261AB3A1E48EA4B8C01F6BEC5D8DFAD3FDBAF9D1B04CFAE26FD32BBB2441EC8095781739568DED72C2CE1F6FD482A68A6E469DB3254213160F0F42865547860D9C33748B1DE750C04C54EA32BD83F62F9ACF1739BB8056C0494C1E708995260769249E23793DB5F5C535D9BB38D88AB66D383631D4BB4FD785BC19FDBB17CF3D5210713EBE7A5A2D898DBCF77B9D94BD41437C18C1A0178AF4A8383ECEBEF1D489D6A9DE188475B0C62457EBE111B3B7AE772FE6D2973671FE7B94CAF1DA9867447910E05C0386A3B034D20C6FB9DB00A47DC6EAC4F089B3E2E52D4D2CA4499171CC7B0F7B7DCEAF19B470C1D6751490BAEB2BB787A28D94379B5D4E8AC9E0B690D61AF55CD6D4FD08D23909EC5E197BAA7DE4B30AABF6019A205E6BE44C6206F2B075370A621118FFEDBEA01818B2841D81BF13B54035CABDC55660ABDAD881587A2B8F0C90B491DD10B5CE5F3671DD56594AC7DD490DF3DEF46F4A240DD643BAD9E85375337D90F73BEC72C6FAF745CE66AD5F1F649B537054103CA88327737B46A76CFBBE342366360ED5718C71F83DAC2919D11917BC93D927342F6C11851B6A1EFBA3DB9BFCF5BF57137C17FDCE3AFDADC8CAE2EFB13DC782E7D08624D32FB7B5FB0A07A7186493B41AFE60980420B2035B9646A0AF01658D5C0C7074484D765B01F31C9EC57E20E0BAF97F86CB979E6E4F8EF7F581FCEE18B3A4BBC8286F243BE70DC11D7E45651B8D9B8F1794B0C91C98D5C40375178B7DE871234031A89747B5B234F2D054400F219061AB9E39361AD13F52B9AC23CC2E073724E139219A341B59705D4901E4BCB34DFDF79BE1258B313F25A2A7CEECA95B0AF00B9868603EA39285D5629B9B99453C8919C9349D833F283EE6AB4E4D2632C2A388D3409C1C42EDAC6F774231DC4CDE7E80D0BB555C8B32F3EB179ACF03AC8C2003893401218CDFA0EC6C407BD531F91C4AE9FA4D5009D2F0ED858DD7F07AD00D094595563080EB75081C9C8F1176A4D8A7A76996BB235177029C2229F47052244109C09C8DEB079FDE5FB5CC76EBE99913B9163C892E16A3A4DB809240CE25FA552E8E17D1E87052DA76BB62151F1DFC59FB6E1827A597DD40A19847157A0299F560ED945CA8F63CC3565997303C505B58AAC6F14C09DE9E943F55F2B5B1128127E8BFDEB1862386B26A6FE8F513B6DFAB610665F7863920380A1111553CB9D1609FACF819833051FA022328B08988521CB06C14B1C4BD30B13A321077139DE826E71AE3571187F05CBD89BA7B57AE7671447D0B2BB9492713B29E4852DD06E8D86A78B0A48C66E2070662B7E8F1690A6C4A527B937B8A3D1801E7627341A7B17BA770EB3DF21537AD37796DA6DC175B48AB98C6EE195678CAA10E24843E13CC2008C7479F05FF867843C9A008F844D0F06AC6F8A8B3636DF746369246484E4A3B7D75BA888F7F38D76A3C218B66BBC95D86791ADEC70ADE91D32E3BF71A76D4A46BD2BD3778B9989BECAFDF0B78ECDC6FF3A8FE5CC2940EE3C72C1221FC9845B82968B82768F6183679F69968CFB765D2A5B3F1F16E426C1A456611FE3A5301DA75457B3DDA22F0B003D9221E8D7BBCFAE43A91187A13AE60882AC9890DA0BC2755F15067E5D5F00AD1C17A20149A483B60C990717635D1DC3C49AD3D03CE60479ADA86F253811C6C01501DC54B603D2063EFABE0C1971C045718B56BBBBFEBFAE978AF7468690EB57EA73643D2E711AFEA96EF44E8B22472B07B25C3EF6B753B1EE8C5D88B0DC99DBB01D33DFC1E898B904090CB5C4C878E6F51720C5CF5BC150065AF2D11E7B17023165E2E185C3AE44C6D045A04DAFD69505AD7C3DEA74F47257AFA46B397DE93197F6169CB82A7ABA3507F6567F469E1459EDE302D8733B5FC42337226BC320AEAD6B32F71B0BA36F5A4F403AC19E2E4C172B0086107E36D1B747C16B17EEC4E6560487C2084CB7C0D7992817865A621B1181532EC4AF690BDB048608FB737E38942D71B406E5E660D63470B7F8F65DB6B4B932E83BC2176A1D89112B3352E787715F2D53A3EF94311216001D5F21770598982DEECA5C66640045F81302630A0D6B62EBE77FBC1AB3FA11E854F526BA32806B31755EC7570481C1CF36BE1F67E0542631966F94AA4F9FD6020B5E6887F83AF29E65ADEE6B5FBB22C7E35A5219FCB83004ED113B2EDD20345F3AB4A414DB200AAA8519F6CCD2BE9FBAE91C1A56D5A0823CA2B1D7D593A31F85C6946372B9CD65EB340D563000011D9AA4210FDD41714B96897517D345D3621F697148714617AE8C278376F7E65ACC3275614015982E4472C1E37E3A4EEED0388AF04F363CF0696EC4A870B51033F0527E2CF4B9C7943588C2931AF4B59614B8DF8C0196B4D52823D8E895AFDC06AE20BFBE90F1C1C7E515D9D7370346384DA8F6394700F8DC7989C797ABF26A7254EB760369313ACA43E9115D52E3A6AC6F13F29EF27E6BF8DC8A1FC124E10A282C333C5A797AADDFF2F41C222C3B45464A6D6F8E919399B1C0F1F4FF1E253464789095A0ACBBBEE6F43C435C5D788892A2B0C6C8C9F2F3FA000000000000000000000000000000000000000000000C1E2B3A3044022060DE1E100E0AE32775BC6715895A2904AA959A043C03340DA1817F844E6505C1022034D567287AFB29F16311919FA48A57C3C7558A4EC542104C69EC35AFD79BBF58 + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-44-ECDSA-P256-SHA256:COMP_ML_DSA_44_ECDSA_P256_SHA256 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 2D534DC369F19E41517D27C823A364072029E066699B978029D37FF85D53B56803ADEA45C95272FD6B1572CB455C88B62EE1E5F0734BCCE62AF1732BA9A346529B6C7352F9DD025677A0FB168DE0726A51A6D511E616A574F3209398BFFFEA8D383DFD3964F6127C4EF62230C2FD2652EC3575EDE4B472553623449B4EF0F24991CC9D6C6A61566D359A0871EE10A477A7259F721C911EAE4751CDB399C91887B7F3ECEF43938264D11EEC21C29189074F2A300ED8C930D0372FB71D85E69EBBF888EE4A582C190AF72379888919EF4110FCC4666B4FFBF0690EE65F8B754059B3D03B96F4D881464C98F039FFBF5061B56E2ED2DE05AE70C4003D181445B68081939B4DE8AE330471DB408F33A1210D7168B88BADCF0A36F964556B5ABD87629AF35AEFC81147B4FFA4B2FAD7DC129C429184A28F150674D84C79531C4F81568CD362C30B6F746AA16B0ACFE97CBF4BF5F6ADF011463680861409F9894DFC62375375D321DF3EA40B71CE9123311BFA6149124FBAEF1FF09D4BDBE3C270C69F134A5FF0E5AEA04774B912B3744A0D15736F649B5AF5083FA0B0DE40789779F2CC49D1E30AB829D13974E7E5C23AA84A7E78BDE394925B770F8EC31E9E0116AD43F00DAB37DB2D3B4DA3E11188EF88C000031772EFE2CC70552F9849D552B3E731465A6A5CB2DB1942B7B8B114F0D268BC9963274FB9F8F00742F12658D9E18CBB992A14565DBF4A084263585214F2129A41CE9A625AB174E4FBD6A8F9CDEAA34A2929290115D163F7AB511AA0B2F065EA89E89B37DF6A53639A078A2E9EEFF1FA4261AB3A1E48EA4B8C01F6BEC5D8DFAD3FDBAF9D1B04CFAE26FD32BBB2441EC8095781739568DED72C2CE1F6FD482A68A6E469DB3254213160F0F42865547860D9C33748B1DE750C04C54EA32BD83F62F9ACF1739BB8056C0494C1E708995260769249E23793DB5F5C535D9BB38D88AB66D383631D4BB4FD785BC19FDBB17CF3D5210713EBE7A5A2D898DBCF77B9D94BD41437C18C1A0178AF4A8383ECEBEF1D489D6A9DE188475B0C62457EBE111B3B7AE772FE6D2973671FE7B94CAF1DA9867447910E05C0386A3B034D20C6FB9DB00A47DC6EAC4F089B3E2E52D4D2CA4499171CC7B0F7B7DCEAF19B470C1D6751490BAEB2BB787A28D94379B5D4E8AC9E0B690D61AF55CD6D4FD08D23909EC5E197BAA7DE4B30AABF6019A205E6BE44C6206F2B075370A621118FFEDBEA01818B2841D81BF13B54035CABDC55660ABDAD881587A2B8F0C90B491DD10B5CE5F3671DD56594AC7DD490DF3DEF46F4A240DD643BAD9E85375337D90F73BEC72C6FAF745CE66AD5F1F649B537054103CA88327737B46A76CFBBE342366360ED5718C71F83DAC2919D11917BC93D927342F6C11851B6A1EFBA3DB9BFCF5BF57137C17FDCE3AFDADC8CAE2EFB13DC782E7D08624D32FB7B5FB0A07A7186493B41AFE60980420B2035B9646A0AF01658D5C0C7074484D765B01F31C9EC57E20E0BAF97F86CB979E6E4F8EF7F581FCEE18B3A4BBC8286F243BE70DC11D7E45651B8D9B8F1794B0C91C98D5C40375178B7DE871234031A89747B5B234F2D054400F219061AB9E39361AD13F52B9AC23CC2E073724E139219A341B59705D4901E4BCB34DFDF79BE1258B313F25A2A7CEECA95B0AF00B9868603EA39285D5629B9B99453C8919C9349D833F283EE6AB4E4D2632C2A388D3409C1C42EDAC6F774231DC4CDE7E80D0BB555C8B32F3EB179ACF03AC8C2003893401218CDFA0EC6C407BD531F91C4AE9FA4D5009D2F0ED858DD7F07AD00D094595563080EB75081C9C8F1176A4D8A7A76996BB235177029C2229F47052244109C09C8DEB079FDE5FB5CC76EBE99913B9163C892E16A3A4DB809240CE25FA552E8E17D1E87052DA76BB62151F1DFC59FB6E1827A597DD40A19847157A0299F560ED945CA8F63CC3565997303C505B58AAC6F14C09DE9E943F55F2B5B1128127E8BFDEB1862386B26A6FE8F513B6DFAB610665F7863920380A1111553CB9D1609FACF819833051FA022328B08988521CB06C14B1C4BD30B13A321077139DE826E71AE3571187F05CBD89BA7B57AE7671447D0B2BB9492713B29E4852DD06E8D86A78B0A48C66E2070662B7E8F1690A6C4A527B937B8A3D1801E7627341A7B17BA770EB3DF21537AD37796DA6DC175B48AB98C6EE195678CAA10E24843E13CC2008C7479F05FF867843C9A008F844D0F06AC6F8A8B3636DF746369246484E4A3B7D75BA888F7F38D76A3C218B66BBC95D86791ADEC70ADE91D32E3BF71A76D4A46BD2BD3778B9989BECAFDF0B78ECDC6FF3A8FE5CC2940EE3C72C1221FC9845B82968B82768F6183679F69968CFB765D2A5B3F1F16E426C1A456611FE3A5301DA75457B3DDA22F0B003D9221E8D7BBCFAE43A91187A13AE60882AC9890DA0BC2755F15067E5D5F00AD1C17A20149A483B60C990717635D1DC3C49AD3D03CE60479ADA86F253811C6C01501DC54B603D2063EFABE0C1971C045718B56BBBBFEBFAE978AF7468690EB57EA73643D2E711AFEA96EF44E8B22472B07B25C3EF6B753B1EE8C5D88B0DC99DBB01D33DFC1E898B904090CB5C4C878E6F51720C5CF5BC150065AF2D11E7B17023165E2E185C3AE44C6D045A04DAFD69505AD7C3DEA74F47257AFA46B397DE93197F6169CB82A7ABA3507F6567F469E1459EDE302D8733B5FC42337226BC320AEAD6B32F71B0BA36F5A4F403AC19E2E4C172B0086107E36D1B747C16B17EEC4E6560487C2084CB7C0D7992817865A621B1181532EC4AF690BDB048608FB737E38942D71B406E5E660D63470B7F8F65DB6B4B932E83BC2176A1D89112B3352E787715F2D53A3EF94311216001D5F21770598982DEECA5C66640045F81302630A0D6B62EBE77FBC1AB3FA11E854F526BA32806B31755EC7570481C1CF36BE1F67E0542631966F94AA4F9FD6020B5E6887F83AF29E65ADEE6B5FBB22C7E35A5219FCB83004ED113B2EDD20345F3AB4A414DB200AAA8519F6CCD2BE9FBAE91C1A56D5A0823CA2B1D7D593A31F85C6946372B9CD65EB340D563000011D9AA4210FDD41714B96897517D345D3621F697148714617AE8C278376F7E65ACC3275614015982E4472C1E37E3A4EEED0388AF04F363CF0696EC4A870B51033F0527E2CF4B9C7943588C2931AF4B59614B8DF8C0196B4D52823D8E895AFDC06AE20BFBE90F1C1C7E515D9D7370346384DA8F6394700F8DC7989C797ABF26A7254EB760369313ACA43E9115D52E3A6AC6F13F29EF27E6BF8DC8A1FC124E10A282C333C5A797AADDFF2F41C222C3B45464A6D6F8E919399B1C0F1F4FF1E253464789095A0ACBBBEE6F43C435C5D788892A2B0C6C8C9F2F3FA000000000000000000000000000000000000000000000C1E2B3A3044022060DE1E100E0AE32775BC6715895A2904AA959A043C03340DA1817F844E6505C1022034D567287AFB29F16311919FA48A57C3C7558A4EC542104C69EC35AFD79BBF58 +Result = VERIFY_ERROR + +# --- ML-DSA-65-RSA3072-PSS-SHA512 --- +PublicKeyRaw = COMP_ML_DSA_65_RSA3072_PSS_SHA512:ML-DSA-65-RSA3072-PSS-SHA512:843A239B195FAC960DB9A763AFA1F3E4E4C517862669E21A0827F5993E888DAA063E1D3665E0F3E5CC5798ED57423343F50948E5B6155934E005F179AF335EB1B97A185B65F6375FD12046F3BBBEB9E34EC4D1196ACC65CEA7E97CAF8370B7F771CFF2539A706C86B28BB91A4262F3BC1FF95DFA013E466D60A4BAAA7C237BC48D8F763DCB7F6C917C5DF6D84DAF208DB9B1F7B08D822B68A7465E577247D5A8BBCF5004A136E7E2C7F68D6C79ED8A0B2BA248C1463D00A65251127C7AD4615C4D75D629A56A15ECD90AD73DEFD6F6B01404AD5804E3845DA829FE8DF3B95054607CA22CDCCDEA6FA800DDB57C885525F1FE1100C25404A591CCFCF640C2415527B61940672AD0DF58791E1291EC6332176DAD4A49260F3FA3D47A8139095892922EBFA73EE7DD281E58A4FA236AD530E10AC693DFE383AE22D752546FFB15DD068ED71C5E2C57F371F1BDA9D30DAF83959477B394DC03CE98F054C9C48792ACAE378322179527F2E2C85168A802FCCB5D2277012158B69E792E3CA5E6F3ABD1B427B9A8ADDB50C4C8E3B38408EFD12A04C11A543FE32BABB81867B805EE822A8B4B08B1393B035681C2E45BB841FCDB767D69955080534FBC5AB35E1B0E19F84E46E6365713A7815F27C16BA8EE8884569EEEB3785873488C82D063F20C22C3B54473986E944D50FC1295680335FA30C1304E32B1F29325ED785658F41AD4B5C764B2A734CF3D04A63A45ED370DA7B30293B049695CED8564ED862AD5FEA92B47C50891350F8E477D79ACF3CC125D121E57C5728689FF9532572F13F27F9B220D7D006CBB3CC71E2A1DE6030E03F8653C064B997B7363AAF190F1C2D0487EE07283150BF018582DD582C6F8621EE227FCFD45C43FCB646FEE0D71140A2159EBA4DF59B6F34321E7A06197AB08B51F0FC2B62EF07534C203968DF3D10DF8D6DE81F7F394619A606E025759F4716595FFF3EF8999BAA21C93742A7841900B8AB3CB91BE1885A7A5A353C653BD511833B1927633CA4B5E2A5938F1B0096D63D9EB21959FDFEABD563879EC7087DF1DE38643CFE1D45F0C8A303692196545C271AD42F1D886BA27C87FC8A8F6E5BE006F5440827652600C4F1B0894F2E3BEBFC2C98B0167C582A28F339C4DC0F35CC7AF606C5EE2B819EEB3B9974D42D32FC7065DD51C883F0BC3721D0B31998FF8ED630866DAF64F3687D3F677C32748698B072CFEDDCB8821FDAC1693EC5B7D7898CE45EF18C8DCF84AADA28F84F4187D9F0A47ADCE81031D9E574FB38D726F9546AF58E4AC98B6E72CECF9FEA7FB53619AE91A4BF169834A712F84B062F7E98FADAFEE90B8F6DECA21C9045DC5434D81FB84817C59CBAB1C981348EED073E0B5A57746D86FDA10E62602749ACD025E3D83DF167B4A2A73B67F5A793A07413C261ABBEE36A189C301800C8396CC7D1BF0A85BF0617181ED9C1ABBEECDDA36B9C9EC70E2B4AFAD6F4D2FF6AE1908EF94A478C8BB91B419629A411EE504AFEFCDBE72937657BA49962EAB9F33BA570113811C95B6E625AF7AB90B147C03C96D2583E494BD720DC8B19693383F44CF4D9F24FD50D03DB0E0FB0CF06E54C28F000DDE228BDDEAAF8F6F55CF8DE5636EEEB9714FEB22CE0BC73DFCF5BB94F8B08A1D8F2BF95C1478E8C378716780030960FB3C0B695F7E776207F2976F458F82FFA6E37D2BA973B68DE0008BC8758323F5535B66810DAD474FE7410FAF56833601CC8D017E10A85305822B80A70AFAB726A366482BDE7CCD33C8639A8D45152C98BFE4B8C815B63F86C8C83DB03F37439038BDD49FB8B84CA1B4A232EA71DB74FFF1F7B6B2CFD788472497203F32FDEE8C5B1830A00D7B1CCFCCD9A0FF084CF080E2C141545743A62875C308346BF48F5C4573BB631255A2E124AE80D9D94FF962856FCAB74F5C25916CBE82BA6885495B279B81F36CA5F8B4E8BA8EDCA49296AD5C5E3BDD1C06B46ED7DB0415AE757068D39F85232585D89407F2F962C29F9125DCE36A69D4743D1336A25DBFFDA046086A5B5F0C473EE8A26E790788A6352234BC0E95A3D0862EE29AAAA58B2BA5B584E7CDDDCDE507D044748A7695FBB4ECFA2B0F7A47F385B6E02A68665B7865D034E3F176D8D7864D2E2D502AC6292FDEC415CB8E2A3B5F95C71B66BAF2E5D2FB5A1453E6457A192E0B4B9A68FBAACF592673952E1453596EDED2D4DA6043F6CB3A74171E4F45A7BD040ED9FAF11D27CE00B862E207251364B47D9AB9297792210E96A775917E7A362BEDBA39FFDA5922A9F4FE550B64026179A50411D461FC4B2EA6FED28311DB35896546829A020BC433305D41D78386AC3FEFE535A4661D2961728AAC8A7C5D3783CAA9D47D331FE610C329A02CC26E65AC3B30DEDAB4B8739A0F77D18C1A504C71556013BE4B0844ECE0B5A830DE9254E091ABA8449D29C8F1351022F493A3CF2C6A5386CE0CCA878FC0F9193C4B57C47BC1706C8FE0430632728D2BA101B3DDF01E459E55BA1A437FBB3451C0FF8EB7AE023287EAB688C580F658A588A20B6C1425A66D68B3064348ABE330D6487CEC36604587A49243FA5C6C4F4368D63459C0EDAAFE7633C0F494F595FAB249EFEFCC61B6ECCD714E7C3B58CE39E79741E9E72C2F63514334ED8D1C4194C966A005BBD6A2EE6497FD4B185E0790E84AE6FC99BE0E473DF082F7340D0B5A40C679761CCD1FB570E93E5F4BD9BD8DE7F59A7FEA5E815A26C1E04F7DD1B24D8EB5429184A20D6FAD90123612ED5C585E1D3082018A0282018100B7020EE94951CD84FF89399830948369E0B2AD71F5541F79FFC85A28ED677A9BD3DB063E5EBFAFE391FFAC02D96710C765034398F765872BAA52DEF751698914E350704AAEC20F2DC4F113978E9473CB1D79D4CA567201CA06FC69EC852AA469C229269E6D0673B1F2BE7FBA2B91EEEE5FDBFAEA6410BEFFD20A357CADFAB218E837869C78C785A5DD2EFA23AFFD0BA269C739149C707F19B6E8E6E4BB534932AA1D6BD0AA45A522B9B212B4A7D5ABCBB8BD81922E929A8073BA20C58799F104BE2169B2DE89CD95F138FB7B7284C735E014BD0CB1B30DC2A327DF832F0DBF236F5AA40F5C57F0BEAE4F6C98A86AB8605C970C3D87106493A9059F4B9E862CA1F2E7F4C454FAD6159673665A280BA1E92FF0061AD252FF37A783DE39CBF68EAFC2C92BD34AB35A39F517ADBA3BF38B7269553C683A3B43B8BAF6E1FC82458CEAD42F113F93B140BAAA54C5008B6D719A36DC867D8C8DC9BFAF5A4CD7B0CD59C9FC48508ED86EE359175F4D7B357C9C39767827E9739AF77360940EA422C24B3B0203010001 + +# valid signature +Verify-Message-Public = ML-DSA-65-RSA3072-PSS-SHA512:COMP_ML_DSA_65_RSA3072_PSS_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = BFFD036DCC6EAFD90A99866ADB32175464B75B092CE6A495AC40438465C956F19D46B3B4ACC18CFC27DFD4147F4110709755BCD9CBBF62F4C62344FCDF91C5E66F5318059A44EE7BA923E087ACF104014FE00CC80292356C0CF7E7349DEF8CD34491141ACD65F07DF0673841EFFE160659D973239D1B6C10130ECD7AB8F1908FDBBF720D19C87BE7ECAEA7AEE409EAE47AB6A89D44AE31B4F028A77A36F5847CECC054193B16707FDABFA6F002A2296AFE9AECAEC9299D4B6D9CE7B2020B9BE4802388AFCFB6A196200235B4382EFDC6195706DBAA7302D3BF7B93DD4E30014047D437258421C21ABC6854EDE06ABF6750AF5FF486CB8AC66B521B220F02A978A11B2EBBC467447B68D4F3190EAF4B04F76258D4722B87E91925DBC33F162B39E673FDDBCE019D82FA4E325533BD66A5FD9416DB79354B9A5A002F889497144004A1579EB6BB84FD82084B00B6092183AC3061D8CABF2C54AABA910B33B70A043094642852E05CEDF9A9428C6FE31ED24F2A2E99677EA38FC1A57E90C7C40789AAA8D11D3D0E13267863336E953F02E9CF544AF305DD4A4FBCF39264FC2156DB09FEB71539785E269253690535B9EA53C14F1EA13E968559C0F9B115547FDB71647038250C97CC7F381D2AEFDC718F17F0F00029FB36F134644C5DA3E030EC04894C3D3450CA68759B2DE4697BD8132CC973A7DCDA55EF9E35BD9DDB810C74DAAA21E6B23D7E5CB75C48F7B0A75CCA83FECBB5BD842962591D3787B20B478FC2F7F338CFFE978BF8E2B760412A2D02E318C92457C4B8F024A8EC0522075E9D7DFF9000EFE3B191F6F08EA3DD08C013A531861B316A5BAF8342C64C333F12CB5D9CFF8859A626730F3B74B18334D585F2260EF9BF7C2D1B2BA7F30E1E6B84FB52DC2DEB6604F7F50192729E03653917D2E61F55AA2A10FBEC27A037531F128D844214B926852672DE85B6F6C6785B3E098CAA74D3EB5736E317E30E245B82B62411F7A7055B9893F7CDA98CDFA6AC4179445DCCC3DECDCC2CFB29CD55D0D213B3B802DB6A016295BA2D9A94591C3237CC801F7B7FBB27D68A2D8B7B84445D83CA2AF5994AD2A2195A40A5C185F54BB95874708AFF7BA7AF84CCEFDA4438D1D43F40898D781F0B7345D0AFA0674AF03BCA31C609D63E783AB4AFFCF2107D6CBD0A794410EE54C416F0E05E2E650AD06FC38F897E4C9F6F5745C5A4E677D9CC91756683B1F6D6D815A1F4D21EB06F8A071C812D513096309EA560410A00EA15923A98C2A7E9A9935CF7F8D6DBFD816429A952C4461E4533C295ED99BCA7EBC709CF1947681D4DDE16601BC32520F52B950C91C71F58AA310DEE3817DFEBB64A6A5C1C1B556A8F2B8D8DC7279DC23A9162697ACAD382F191EF2529D617D0AD29AE5DA7CB39B054052214ED766C4D4E70AA7B854BB9837CBD83D41AD60F74CD353289BEC1307F9CEC3FFC1B65DF6B0CCF9CF98D8ED845428BE211D4F37466A2EAF8ABAC723F856A82A6DEC4F8621EB8A3FB0F40461CEADD705A53A925784FD6495DEAA658CB9E08624137353911CF2F89C795F4CB3DA49F247957925A726F1F07935A252AD2401A374213A92011F40454981DBA931661284122AFB879CE735EDB645A62E3CAC1D6A1A02CF98BB741ADA00A38B0DDF4753F931EEA4751A354DCC47796D495B5D2D4DF6AE351B52261B243359037F0ED6D743993F798CCE05CFED69BE28179C99EF7CC2E7617B1976C03AE6C54C09F2596BFD37F9041464FAC58CBD38CEDAAFEFB4F73DC73556FD03E7C2ADBF47D963248961CA48BB3DC41FC6C2E19D1BE4F6545A6159639A1DCF89DB737E461D325A3F14480F07F9DA3519B044DC71C59D7917D4544E26B69F736AFD1D711035D812985214A68C112541129ADB687B1C27E2AD30A3F50F69998FD6A9E13AF76CE2DBC01F57E8FEF561C1B149AA5C3DA2BA289C6D7F2BF4F9193C525912F4660557AEACB766A6AC0A08C520E92B83032643732AF592C1BB75624D432FB02358172C04F63E8F6D0E68FFFD32927589777C3DC59936D9D0C5E12977C2F52746B23D443D8CC3A770355193834DC70F110D605FBDA07CCEE9471B6BFF6C610A00318189024BB0482A052846559E0AD5D25049A06C3DFE7FC0BFA73E9C93279268434A6822787F04B508326CF6009BD33689A71D50050F91BE38A21AE6E8ACB90ABC114118C28E4B27EB1DE90C5B5081B3ED3798F1F1AD1E3094B882C6A511AAF45151153D5E7106B8584C52C9561B3916B7C0D08BAC0DB000532D13C32CC8F7394E6CBAB1DE85B084F94CE4BDD41D5331C2A4C5961EA73230A01E3B4AA28BEA5DC5B3DA0985AC5570A120BF0997B9C96626F9B31A04914B9B8527EDB8B1A224593B568EB80716D2780BCC64F0D9DCDAF173C0EAE88FB2E9F427193E0A8A04CA7290F06B2BF41AA857E968EAED2612BE928FCB45FBD7C6C712127F0058C1F93F5EEBBC587D91380FC3FAEA333740136304870EFFF8D5D9858BAD263B7B793CA530044F20102400A4AB4ABCA08F47EBE2E70C8F9FDFD6953D33120137169EA136C38CEFE23C5CCD805C020EF959C0147EE48A1DA2BE2AA936D32B89DFD239FC119F86C921F0BCA4BF2901B881CFB13767F8705309F0D740FE1DB842A5746C2137A8190E25C8648B1696A9D6858414D3EC04470C36AF484CE5CBD382B6AB47C90A3E603FBBB467DDEE72F6C35195F3E04445E919B9B463660C772974C0A0A67BECB622D6482B5E2AB69E7128B1BD0A8E7C0C9827BD700E022F3CF54A6EEF3021905EC87E37E7D1EAE39F56DEF925B4AB9B35E43706219A1712AB6CEE516EFC9DA6530B0F35FAA8F26672AAFBB16A2706E46C1E249A7983052138F86A1DD9716C21A0DED94932CE888C124A34BDE765CEC6355D1DC25FB54568CE04CA3F687D93B09DCBA7F27C550A34CEC79C32A7BA76518796191C40F59399695D21334189636E601D0A5ABDA45D0944F892813B73BD07F62767405EAA5AE889CF3ADD74A29B612A4B5534B0FCF1D20900CE0C7488D506BF9B5BF5D2AC32C353FAA5B7D1A10B9B7D8810F0B3887BECA547C042B5154A611ED49879CAEAA1D1A49F9EC22BB85B8F4004F7A8B638B0EE353B537CB4AA2F9082E89DAF9D9938D535B66A187E75A6EDFB6C6AAC3E7B674966B2BF0289733B378EE56CBD1E84C2FFFD5269BDE69FE522D1875583687513227CD1F6207DB1523B881650284E2E87699F96773741C4EF4967707FB1BE07E54E5150455EB36080DDBB82009395A42D9BA601DC62532A83856394A6948744622B4610F648042F39E6E65B5DBAD6DC77660FC0598F5C20F5802B49DD45ED4D425689C3B10175B1A0EB1E670C48B51FA5CF862630F6D37B27CDD4421E6BE690761AD3CBCA7B8358064DA946A821E874E543601D2F1D791F670A47803BFDA2FF8F1717AC195CC0CB012A829E8B7FC1A8FE78DA7FC56CF3155C3E4AD2FF3896634727CE486A7E2E458CC96A49B4D41496FCD69DDB3034590A60F3FE07D1E64C0B36A35DFBC4ABCC12011679013D31E0E96A5A19B4EAB131995AE3D14983D05B6CA4DD72D1FE5CEC574E0F1B4790551D105F32FE51B1CA38243AE36C850D93D9F590E0AE24010E9392F70E0BA1AF3FE091D630C39E20CD3C7386C28D417DEC5B0C6BE7B1B580F24A86083F24AD102D8AD6C7D31CD83DC6EA5878A29C6C42F29A0B7DFA5767E0F49B73B1A6E32E6314BEC25871A4715FC6936D2F30FBBCAF00FCC5305EF0A05DDA294D99E3B0E626167F59678D787F42AF323F70C755BEB86BBC61711742FE2F49D1CC261B05E25450F566D27207B7A302E658E3284F21B7116648E7C587BA85E182ECF47AAD30E699F1D3BA0452BAB70E125E815009EBFB97724728B7B7B304B4B8EC7BAF25489A24B4C90AFB61B40E0BDB24955A80A66C1CE7B21FA6FB920FA1C5C080C786355E0578D93D734BCCAE77569342CA6263AB1C7A4D1C5CE95307A2BA7590494A8CC682237E6D1986C37D9DE0F3338D4F21014E80D34C8C4227EBDC8B7FEBEE1D7ED6E45E20AA50F3F49E20EA97C962BEF4E953BAC2F2C78D96D068D02C2B2EBEE56DD2D5826CE68C04406A1FC57511356CA063DE060604F9E15B1BA54A76DDD987F7923AD14BC16E34474E20A7FA8C1976D202F192660F614217152EBA216732E321EFFB2FB3116D537AD3F77C10CD3F9F50188090B2CC990A7F980B2B6C43051714E14C8D89C47323A38F84CB119AC44D71B8F54C8F8B2AC3771D83A98BFE41844DE7523BA2858727DC305CD33FB8B68F9F797C6FBE78D39C42AA3B7C49E2F44417F052365A7D83800A54479F371126F9F4305B79722F92C3BA14768466964B616CB9CBA608A52F4E3BE0ADAD4C963AA15A121E369D689B75531266B48C4B524E4FE23E15D037876A382F4984F45EE27DA55E9351167132DB2046EB97A333038EF000785541279B92E16713C3C00DC75C0E593F612C62377522AAB09EBF284FD38F474224D7B60EE246D435B3362DAF0F07335ABB1126222F5FCB05DB6E157C4928C3375EA8977938D3CDDAFCCA98FA26695B08D3164155FCE26E50504ADB494BDC47206E799B7B7CC1DCD47DE96C965DF0E2487D3EB222E3769D8162D7A88D5E5F0F138677A8598D9E61028456E9C9EAAB1E2E4E77897E0F1F90000000000000000000000000000050A1219242996A0537DAAFF35ACAFB10DF0E7FB1D4FE3C5C7F247908EB1B918D98491FB76074C825672286238F7481D548A5070EC41984C9F655A1F5FD88D0219916261F351DDFDE9BCC6FB2A38E393D89029C3BA5D65866E4E4A9D814C5A634F2D51FDC3A1C4667C5D139C1FC987BD584448BECA000DAE92DB4A335582FBBE2B19A85426D9B584137FA998EF2FC776000BC33A6D04844462AD86610B465080CA5B9710B5076177C1432987B8BFA71C3786D79B247148F0B4302EA017CBCB4040101723B87AB08FEA5361D2BBD60369674C2D0AC9DC3FF098F4B29343F09FCAEAF9D72E47BA61323B7C2FE001B2DE5FF9BDB77E1326BE977E7BE45633A25770DDAA4F2A566230932396DD5EF3F848FBA561563BC9956DFA11076C3DA7130A9324C6E2E57B7CE13FA2702364F11FB3C576806AF4D62D314C996B6D96DA83B91EBD49D083D9B27ECDEA7B71D865D57F84BF3844DE2F7F8D8D46C5BB72F156497F2307E3590B8E35C4326C46E18A939B6D7C88DAE4B040063258F00BF35BC99A946AACE61651EB + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-65-RSA3072-PSS-SHA512:COMP_ML_DSA_65_RSA3072_PSS_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = BEFD036DCC6EAFD90A99866ADB32175464B75B092CE6A495AC40438465C956F19D46B3B4ACC18CFC27DFD4147F4110709755BCD9CBBF62F4C62344FCDF91C5E66F5318059A44EE7BA923E087ACF104014FE00CC80292356C0CF7E7349DEF8CD34491141ACD65F07DF0673841EFFE160659D973239D1B6C10130ECD7AB8F1908FDBBF720D19C87BE7ECAEA7AEE409EAE47AB6A89D44AE31B4F028A77A36F5847CECC054193B16707FDABFA6F002A2296AFE9AECAEC9299D4B6D9CE7B2020B9BE4802388AFCFB6A196200235B4382EFDC6195706DBAA7302D3BF7B93DD4E30014047D437258421C21ABC6854EDE06ABF6750AF5FF486CB8AC66B521B220F02A978A11B2EBBC467447B68D4F3190EAF4B04F76258D4722B87E91925DBC33F162B39E673FDDBCE019D82FA4E325533BD66A5FD9416DB79354B9A5A002F889497144004A1579EB6BB84FD82084B00B6092183AC3061D8CABF2C54AABA910B33B70A043094642852E05CEDF9A9428C6FE31ED24F2A2E99677EA38FC1A57E90C7C40789AAA8D11D3D0E13267863336E953F02E9CF544AF305DD4A4FBCF39264FC2156DB09FEB71539785E269253690535B9EA53C14F1EA13E968559C0F9B115547FDB71647038250C97CC7F381D2AEFDC718F17F0F00029FB36F134644C5DA3E030EC04894C3D3450CA68759B2DE4697BD8132CC973A7DCDA55EF9E35BD9DDB810C74DAAA21E6B23D7E5CB75C48F7B0A75CCA83FECBB5BD842962591D3787B20B478FC2F7F338CFFE978BF8E2B760412A2D02E318C92457C4B8F024A8EC0522075E9D7DFF9000EFE3B191F6F08EA3DD08C013A531861B316A5BAF8342C64C333F12CB5D9CFF8859A626730F3B74B18334D585F2260EF9BF7C2D1B2BA7F30E1E6B84FB52DC2DEB6604F7F50192729E03653917D2E61F55AA2A10FBEC27A037531F128D844214B926852672DE85B6F6C6785B3E098CAA74D3EB5736E317E30E245B82B62411F7A7055B9893F7CDA98CDFA6AC4179445DCCC3DECDCC2CFB29CD55D0D213B3B802DB6A016295BA2D9A94591C3237CC801F7B7FBB27D68A2D8B7B84445D83CA2AF5994AD2A2195A40A5C185F54BB95874708AFF7BA7AF84CCEFDA4438D1D43F40898D781F0B7345D0AFA0674AF03BCA31C609D63E783AB4AFFCF2107D6CBD0A794410EE54C416F0E05E2E650AD06FC38F897E4C9F6F5745C5A4E677D9CC91756683B1F6D6D815A1F4D21EB06F8A071C812D513096309EA560410A00EA15923A98C2A7E9A9935CF7F8D6DBFD816429A952C4461E4533C295ED99BCA7EBC709CF1947681D4DDE16601BC32520F52B950C91C71F58AA310DEE3817DFEBB64A6A5C1C1B556A8F2B8D8DC7279DC23A9162697ACAD382F191EF2529D617D0AD29AE5DA7CB39B054052214ED766C4D4E70AA7B854BB9837CBD83D41AD60F74CD353289BEC1307F9CEC3FFC1B65DF6B0CCF9CF98D8ED845428BE211D4F37466A2EAF8ABAC723F856A82A6DEC4F8621EB8A3FB0F40461CEADD705A53A925784FD6495DEAA658CB9E08624137353911CF2F89C795F4CB3DA49F247957925A726F1F07935A252AD2401A374213A92011F40454981DBA931661284122AFB879CE735EDB645A62E3CAC1D6A1A02CF98BB741ADA00A38B0DDF4753F931EEA4751A354DCC47796D495B5D2D4DF6AE351B52261B243359037F0ED6D743993F798CCE05CFED69BE28179C99EF7CC2E7617B1976C03AE6C54C09F2596BFD37F9041464FAC58CBD38CEDAAFEFB4F73DC73556FD03E7C2ADBF47D963248961CA48BB3DC41FC6C2E19D1BE4F6545A6159639A1DCF89DB737E461D325A3F14480F07F9DA3519B044DC71C59D7917D4544E26B69F736AFD1D711035D812985214A68C112541129ADB687B1C27E2AD30A3F50F69998FD6A9E13AF76CE2DBC01F57E8FEF561C1B149AA5C3DA2BA289C6D7F2BF4F9193C525912F4660557AEACB766A6AC0A08C520E92B83032643732AF592C1BB75624D432FB02358172C04F63E8F6D0E68FFFD32927589777C3DC59936D9D0C5E12977C2F52746B23D443D8CC3A770355193834DC70F110D605FBDA07CCEE9471B6BFF6C610A00318189024BB0482A052846559E0AD5D25049A06C3DFE7FC0BFA73E9C93279268434A6822787F04B508326CF6009BD33689A71D50050F91BE38A21AE6E8ACB90ABC114118C28E4B27EB1DE90C5B5081B3ED3798F1F1AD1E3094B882C6A511AAF45151153D5E7106B8584C52C9561B3916B7C0D08BAC0DB000532D13C32CC8F7394E6CBAB1DE85B084F94CE4BDD41D5331C2A4C5961EA73230A01E3B4AA28BEA5DC5B3DA0985AC5570A120BF0997B9C96626F9B31A04914B9B8527EDB8B1A224593B568EB80716D2780BCC64F0D9DCDAF173C0EAE88FB2E9F427193E0A8A04CA7290F06B2BF41AA857E968EAED2612BE928FCB45FBD7C6C712127F0058C1F93F5EEBBC587D91380FC3FAEA333740136304870EFFF8D5D9858BAD263B7B793CA530044F20102400A4AB4ABCA08F47EBE2E70C8F9FDFD6953D33120137169EA136C38CEFE23C5CCD805C020EF959C0147EE48A1DA2BE2AA936D32B89DFD239FC119F86C921F0BCA4BF2901B881CFB13767F8705309F0D740FE1DB842A5746C2137A8190E25C8648B1696A9D6858414D3EC04470C36AF484CE5CBD382B6AB47C90A3E603FBBB467DDEE72F6C35195F3E04445E919B9B463660C772974C0A0A67BECB622D6482B5E2AB69E7128B1BD0A8E7C0C9827BD700E022F3CF54A6EEF3021905EC87E37E7D1EAE39F56DEF925B4AB9B35E43706219A1712AB6CEE516EFC9DA6530B0F35FAA8F26672AAFBB16A2706E46C1E249A7983052138F86A1DD9716C21A0DED94932CE888C124A34BDE765CEC6355D1DC25FB54568CE04CA3F687D93B09DCBA7F27C550A34CEC79C32A7BA76518796191C40F59399695D21334189636E601D0A5ABDA45D0944F892813B73BD07F62767405EAA5AE889CF3ADD74A29B612A4B5534B0FCF1D20900CE0C7488D506BF9B5BF5D2AC32C353FAA5B7D1A10B9B7D8810F0B3887BECA547C042B5154A611ED49879CAEAA1D1A49F9EC22BB85B8F4004F7A8B638B0EE353B537CB4AA2F9082E89DAF9D9938D535B66A187E75A6EDFB6C6AAC3E7B674966B2BF0289733B378EE56CBD1E84C2FFFD5269BDE69FE522D1875583687513227CD1F6207DB1523B881650284E2E87699F96773741C4EF4967707FB1BE07E54E5150455EB36080DDBB82009395A42D9BA601DC62532A83856394A6948744622B4610F648042F39E6E65B5DBAD6DC77660FC0598F5C20F5802B49DD45ED4D425689C3B10175B1A0EB1E670C48B51FA5CF862630F6D37B27CDD4421E6BE690761AD3CBCA7B8358064DA946A821E874E543601D2F1D791F670A47803BFDA2FF8F1717AC195CC0CB012A829E8B7FC1A8FE78DA7FC56CF3155C3E4AD2FF3896634727CE486A7E2E458CC96A49B4D41496FCD69DDB3034590A60F3FE07D1E64C0B36A35DFBC4ABCC12011679013D31E0E96A5A19B4EAB131995AE3D14983D05B6CA4DD72D1FE5CEC574E0F1B4790551D105F32FE51B1CA38243AE36C850D93D9F590E0AE24010E9392F70E0BA1AF3FE091D630C39E20CD3C7386C28D417DEC5B0C6BE7B1B580F24A86083F24AD102D8AD6C7D31CD83DC6EA5878A29C6C42F29A0B7DFA5767E0F49B73B1A6E32E6314BEC25871A4715FC6936D2F30FBBCAF00FCC5305EF0A05DDA294D99E3B0E626167F59678D787F42AF323F70C755BEB86BBC61711742FE2F49D1CC261B05E25450F566D27207B7A302E658E3284F21B7116648E7C587BA85E182ECF47AAD30E699F1D3BA0452BAB70E125E815009EBFB97724728B7B7B304B4B8EC7BAF25489A24B4C90AFB61B40E0BDB24955A80A66C1CE7B21FA6FB920FA1C5C080C786355E0578D93D734BCCAE77569342CA6263AB1C7A4D1C5CE95307A2BA7590494A8CC682237E6D1986C37D9DE0F3338D4F21014E80D34C8C4227EBDC8B7FEBEE1D7ED6E45E20AA50F3F49E20EA97C962BEF4E953BAC2F2C78D96D068D02C2B2EBEE56DD2D5826CE68C04406A1FC57511356CA063DE060604F9E15B1BA54A76DDD987F7923AD14BC16E34474E20A7FA8C1976D202F192660F614217152EBA216732E321EFFB2FB3116D537AD3F77C10CD3F9F50188090B2CC990A7F980B2B6C43051714E14C8D89C47323A38F84CB119AC44D71B8F54C8F8B2AC3771D83A98BFE41844DE7523BA2858727DC305CD33FB8B68F9F797C6FBE78D39C42AA3B7C49E2F44417F052365A7D83800A54479F371126F9F4305B79722F92C3BA14768466964B616CB9CBA608A52F4E3BE0ADAD4C963AA15A121E369D689B75531266B48C4B524E4FE23E15D037876A382F4984F45EE27DA55E9351167132DB2046EB97A333038EF000785541279B92E16713C3C00DC75C0E593F612C62377522AAB09EBF284FD38F474224D7B60EE246D435B3362DAF0F07335ABB1126222F5FCB05DB6E157C4928C3375EA8977938D3CDDAFCCA98FA26695B08D3164155FCE26E50504ADB494BDC47206E799B7B7CC1DCD47DE96C965DF0E2487D3EB222E3769D8162D7A88D5E5F0F138677A8598D9E61028456E9C9EAAB1E2E4E77897E0F1F90000000000000000000000000000050A1219242996A0537DAAFF35ACAFB10DF0E7FB1D4FE3C5C7F247908EB1B918D98491FB76074C825672286238F7481D548A5070EC41984C9F655A1F5FD88D0219916261F351DDFDE9BCC6FB2A38E393D89029C3BA5D65866E4E4A9D814C5A634F2D51FDC3A1C4667C5D139C1FC987BD584448BECA000DAE92DB4A335582FBBE2B19A85426D9B584137FA998EF2FC776000BC33A6D04844462AD86610B465080CA5B9710B5076177C1432987B8BFA71C3786D79B247148F0B4302EA017CBCB4040101723B87AB08FEA5361D2BBD60369674C2D0AC9DC3FF098F4B29343F09FCAEAF9D72E47BA61323B7C2FE001B2DE5FF9BDB77E1326BE977E7BE45633A25770DDAA4F2A566230932396DD5EF3F848FBA561563BC9956DFA11076C3DA7130A9324C6E2E57B7CE13FA2702364F11FB3C576806AF4D62D314C996B6D96DA83B91EBD49D083D9B27ECDEA7B71D865D57F84BF3844DE2F7F8D8D46C5BB72F156497F2307E3590B8E35C4326C46E18A939B6D7C88DAE4B040063258F00BF35BC99A946AACE61651EB +Result = VERIFY_ERROR + +# --- ML-DSA-65-RSA3072-PKCS15-SHA512 --- +PublicKeyRaw = COMP_ML_DSA_65_RSA3072_PKCS15_SHA512:ML-DSA-65-RSA3072-PKCS15-SHA512:9D718A15CFB0EDDD7132ACFAA636BE80592305D71D985008C4FE62380354A01A7F3C8368603413F3E4D629B8647C514B0158C1301E514BC07FA57389B6A8AF4F346E6D9C51837ACD3D0043A94B3FDCD3EF35D5F14BAEEB6753CE2A9D3F342889936789BD8D2BC00D0B7F33693E6DCD120BC807018C2F6EDBE57C6E9CA2D9ACEC07177995198EF648A20D68AE97CCBD2D5C654AAEF9AECCD23202E5922AF29411FAA4FDC7270B247B442468E19F14546B614AC724E751126B1DA606D914FE737B9293B0DF1F24FC3593AD9B40B1A695CFD7DAC1234649F399AAF174DF042CDF3FF684FD6675966D03131B3827F83338B0CEEB209FA0BC270BAD7DBB8D344745A357C305E1ED56B4C5FAA67527F2E2EC2D970855CA5E6EDFA5D82393BF80C6704AC16AE19CA24FDFBE686656EE8901635C81362570820623F2DE0EFF60FBC8917809DCED360FD4C44D8C4230EF40F6EFF56FB246256DC0AE394424776FFD532086DC476C3863D15F212741E2244ED9563679A400DF65F4600C0F709F32ED99AE794797B86C965D5F24B457627E589EFC3F68A22A5A2261293727A8F94BF1D0DDD019DB55D0D6D1E2B41F17764042A1FEEA6B16126FC4811C793AF58AA632B9584419482F867B36CACD29E9C5A497BC4B817939627E6E1FEA7CDA210A9763279D64420CDE868D1B30A164CA58E1656C3B1E019BAFB503E2D668132870D421C806108979AC3027C548FCBA71FB742EE0EE4F1D1C9E373886FF498AC1D46995C2F6683FD3B376BD9080C1F3AD0BD53A8E42B85D4CB142D2C384968797D3368D9A92EE9E59475619B8DDA9310CC25DA44A82AEE9E88BFB72E4ABF24BAFAC246A441600DDBA3CF98CADD2863E320BB3C3F0BD7AE1490A38369E332751BCA6194ADEC164F13CBA1AC1EB96039ECB9868F0BE392B32A9B92198A5BA976D9283AC0A5E7F391E464ADD2CCAE36E7C4E1CCCF548A772A7A5095D2F1736E5C5DFC72181F8972C08013A9D37668149BC63039BB607F533CD872568789E936E52B732427FD3AA07DA70927730D23CE2AC038146850507D7AD3ED3C546C000597F7521FAFFEB99111D1C102283033C3C7927E7D6A90B65D048EB6553BF2753FB51B4A37ED0ACC03C9699A54AF9E6363A14597EA2AF04C1900A304B341B6FBA1F57BEAE40B051B35B9194FBC3655758FF08FB57F43141EAF427AB4F691A562F39994241B42887DCD6FEF2FC24A5D48121F88111637B213342A76106223C536A4B0BF683BA9E208B899C2E031D6C24488148BC2B1102943A12832130DF7F064B0A558EBA030DB058D2713B352E4AC1A6ACA99BB24FE3A0A7063517C25F659E6201A7E2858D21C487009F0C611897E82B11280057C603E7569319A172B1D672E4523094D5AB6B0D488C30B3666AD479A945BD4B82433FAEFB82A708618989A3360E191F1C284BF102FCE1CF906C967C19ED9402C388FF78BEE1102B364ED21AC4BB2F16CA2CB418054EAA1DFEFFD2C40E671423C156A6CE82D3AAFFED71DDB5029AB63B3CD059857199E808842EB91273DCC57D0AA0DC9109D4EAF2F796405E718832B28C33378C7893EEBB91B2BC0F1C6464845D4A4C101F3AE5B991BA0F3AC73EA42DD825623C3C1941794611CE61A49DC38B89A99D0609FBC0D9D859E44F7C3AA0CB88DE539516C8328F28D4BE3B7F31BA5C60A1EC4B634E4AC27EA1B7FFD376C143F80BE1D48D5D311B98B57D83D8124F48EA6335091302E9243CC5852CDCD628F8BFA4183D0195BF3C9AAD67DABDA4774397814B7475DC06697582A6E314F16325DA714804006910A922358670F6055C0C1CB7EE4EF5893E22725AD7900BCEDEC13D6AF016407C264B300834D2A5BB8E85A5839DFF103E253DFACCA1598E728E456120BF975EACCEA2D8769C3DAB89B616013655A1FC5477B2BBC8B5BA84AEB485B10BE29CD8EEE29F6197C5DC23F5715E280EBD95B15FE19DEEDF0CB96DE99FBB7114AF7F496FF1741338BCD3797B9C8F6AE9DE3E5309CC33DC95640B86FEB4BA0B769D190D7BD1EF4D087CEA1CD9F175AFCF1D4BAA60A001FED72324A71E1638550C4DD92C7B6B8332A5F3BE0331115CB92B1D9D096C466667517466521152895687FFE592C57E07585371FE2BB334C551AF3DA0653BBA6BCB1D301EB4C269C93227D647739C7F1E66CAB132E800CFE25ED3D9D9A3D90869F8D45F16621D29D13A94B078F86403635FAB995192BBA5E3969B07A662592E8D1495262BF004FC25958547688E92EB6832D92E0931FA92A63AAFAF82B2744AA3B2CD25A6DC2C1914AB4BA4ED36E396E596DD6E6AA4450C801EA86F573E78E1C079D03C52142269325095A9F819E57B572D38D7F8E3B2369FB42DE16D0104FDD1B263470D53F7AC6A76033FA52268546AA208B036B8A80E25BF2EF0ADB3B48E075E7CF58BDCF02F8175E8EE98EEA293AF0750CBEE7B09B2920EFE2F9A5BB299011F40507DFF09309C5EADC2C245107B2CD7A52E58B3E96CF75D08581EA85B62EA2C4F6AFFB9B258775F43ED859516C80CB2D4146EA8E915011A15A540B60716AFAAA1E6E0FBA70334EEE20EF1B14658C211B7B7E4F4CD1DC0C1640FFB097A03973A091FB9550EBE6A077A34F40FE889DE1492A24B58AEC908B08F116B6C133ECD9D88C7B8B9A200AF261266139F4189E94071CC530B79FBDA9417F676668F0F4449032958A35410EB122B8F16E8A6B24279E0B0B784F6323E1E6FE5F4ADD6410AAA23BA5CE6717221BE5A3770D9AA3082018A02820181008E392CE848552ADC9347048BE9F11C049C53288DA1B5180EEDCCA9CA5D4565DF947BB674ABFADAFA03D5E7AF5AA6DC70DCE2C56FFCA60E9DEACE5E9C79304DAA21B53628F2F28E1F184DB6F26AE2ABDEA2F37280B2FA0A082ED6CA9D040154D33FA53F73D85E3C774F748847C59CCA86CB510AC127790E9A296565FC62EFFD06D90D371803B727D0B1E713D977DD9BE125DD6761885FCA48961A63BE0CA80CD42414013756B2E67BCCC4333D1CDA364DCDCC35A864F0F0E3A7E91FF942C34F77B1C53C9F1A3034C20B497E9C32E6398D6D276D6566AA729BD82429890E0859F3F7441600C17C3B45FBC1ABCA31A5B86D5EDBC64BE3EA2CC2703F4E38C53AF5AD467C3BB93219186ECFE0DA31EF5539A25423DA4BA860A6D1E694BEC9D46F640D4ED98AEA9B88DD94A0A7FF25BC88CF3A7EE85F61570015C9F237B5EBA5C10A6DF8DE1170E6EB414AD6FD80EB94DF002E0632C7CC45DB8536C153C33528444D944233F19429F55FC41C9C86002E8B89EDE19311C2A1598DCC03EAE5B96AFBACB90203010001 + +# valid signature +Verify-Message-Public = ML-DSA-65-RSA3072-PKCS15-SHA512:COMP_ML_DSA_65_RSA3072_PKCS15_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 5848EF06B5553AD2BFDC07BE94281983BD4685BB476A541F047B8CC7B88180119AC269EC3A6AD1FCEFA6F8BE5445FC42517DB551E71AFDFBC97007BA673F6F833959FA6152377F9CE78DD0EC51F5DCBD63084695406F4EA056270BC96DB544CB350123A7A244298851DD1FAED555659053552C40DF5F3D4962A31764881389C77043E9E3C4027CD703DE95078B7897B006B9BB340760A5971C95E250955A600969741C984557FF64E7FB1714CF0A5CC11A7E41C318636D7059F0ECA723E5D6A86776F3DDBE49F2AB6E8C52194F6E83CE052201AFA74C878BDB67AD9B1FB1F37FDC9B4CABC73961BD929FCE853135D9A2A6AEDE4FCCAC3080A2F718FEEEACE509BF37847FCAD640A570707F0C499B1A4944A6B6C2667DA5A96AA7ABE5AB04ED3C8823EA334C5CCD6BBB70E6F0717C69611120E56FE4629633338731E2DD42BCE33E8DC62C373A7308BA3279120DC305F9C415AF927F19952B493F6E5300425A0E1FC4C7B34F6A2B1D24D41D5D99D8C30431F1D99FA2B39BC6156C913EC4F57E8A44CA86100E20BC66D64F6ADC51814391DA2B9BBCCCDF5BE2CD441C5798BB10E930E39C316A40F071F93A34A7EEB63874CDBDDE0A5AFA84EC722F3988722AAD2B0D50D681BF49CD7F82537BF7949FCA5CC11F8095C9357F5490C86909F1A202CEBE0AB57A1DF25856B6B5C92D37835EF183C90679BF882B954B4F2D2F9420D92089878E60CA35FB76ED81A4F2A524AFB5C1EC0BFE61354AD39F82876D4FDD3954AE60C92CBCC75D5F9F6FE26DA1B182B9074D0FB7D5263B411EE736282E6D864FB130049A202E7D1321FFE8898EEA1F51C3AD125CACAAA285398A67C5BEB2703A5A32BA6D3F31E84C48A622C372E957821A8950EC72415F6BBCC2313140B238C42E896856043776A0536944313F976AC28769C3269D7062D692EEE502A879CF6BA97FBB34EE4F3D762062A302DBA1F1FFB5DCABAFDC58E9C82D9EDBAAAE54959F5E746648AB7F79072C00D6C8963C3D9EAA04A52763382C5A911B60ABFAE998B89FBA5F5078BADCBC98F68B06BA330E546B467770B9B64E2120C4D6AF7BBA545D96147A585BE7CEE7E07D216C29648D7DC338169D85BE32F2E9503F5076B4C62691F53A839F23F707334A02F11184AFDC38767CB772E053A0D9880C009F68A57305E6E8C43ED2175DC103D1BF615252FE03EFE0094F66FB95E52537610C97B99F6565ADBC711080D958EAD1FF946332D745C48324D123CE7F51066DC02D504470CE162B13D7DF346FCD80CD910A0DAD4F7959E6C5F9184E669BE1F5CA99B32C2192782C4C69AB930BA4E68A0894932B5821065D415CDA2038F725ED2819F5840007CC2C75AA8F1C8B812E1CA104D5F33418A8E991CE4A6BFE4167C915976423238B87DA6E2005EB670F7BAE62D3DCEC680DC811399F5C0B32E5CABBC1131174B8968D952E07F1EDBAE6F78502249F1E3C4C8251FA0FDFA75DBD7B9B47E1C7BF782F43F802AF137CAE524470B6F5D7A95335F270634167567FFC0C871916E51A3877901DF35F888991FD6F80BBD62D9BEE006B10018CB975A5EC1F0E0A97DD5EEF95BBFB2710BD1B3E15C4476467994AF37CB1FE7555973A1FB7026DF18E7438BF0FAEB070870FA183EDD95AF65FA156F34A1D232EF074666BF568F90F20597FBBA293929DF24786CB7A2120CD3F6FD63BBADC53B20C435373FE4F0D2D731BCC92625248EE71FA71F6E171054025662F383EBDAF43FBF242234CFB6E15E97223441A15D67F9FAD4ED9612B085F7EF93BDAA94B7F673765180E4724BC132534DE6C07BA5A0CA406F82451EAA66BEA11488943136803F8C7C3800B9E022064D0240C8A0658824A1F6557939121DF1C880F1F9B302922C6138F7D90387D428679FAD5BFA0E2DE2672D329356BE6D35AEE0576C7D4AA9EE91DE0C12CB4FBC0A0441D79BCC24BBF9306016F622F226D533D3DEDD969926B8FF3DD546CC7872265273497671D36A81E283A1CBDA55E9A68A9B5C3E8F7A6E283D167A9E7CD5984B5B0B89C5FE3C2861F57CF7C12631844EEFED371C4B1F970471F26B79255AB0B896BE4F17D03DE632478F098D85A4088331654E12D128E329D6A57EFCEF8E68376694A367C24046AA111B8B9AD6D2AC4EC07F906EEA97518ACB2278645055BE7F7C88D3F756023D61EAE2B6E2397CB466291D59031A41C8A44E857E5AA7C76DDEC6D854EF89A23D9CC548C1DB8918D348C78DE02122937014ADEFEA2F2407C421EDBC807C375949DBEC492D2A52E9068CAB783CD16DA178A7553F0034EAF7700F27D71093A5AF4EE2D5654A27E9B8B55144C6E365590CE8CC8AA18DBA7FB4AFB4F3D8ABC4A743AA4EB2629EB9F30826878B0BF33A5BD23ADFF87C687E7C0A058B180A292C080CEEBF4D7FD9E2EA095A21701A5162DF1939F33320817842BFDFBAE3EA8A1F559B11EE09A3CB3C95E0F9AD3061BA3D949B0297FC453C1C91D23AE7EEE06FF0F586C331189517F0AEEFDDF1848363B434838AEB6140F31A7BF51737CCB6C51944A6C1FBE843398066C8D6DB170CB07305BC305BCC33C174FDDCAE0F085A829F8F4A72DE57BF72DE90BB666A0C7E3BDA6F161A56C5E0A6F89A1BC35B6E03E1DE7A2F88B7DDD6C5341A4B819801D822DD16145264ED12E80A3F68225B4782C0B8A382ADB35EBC15D9B5C992200806CD3D76CB1DAD241B04482513215F827AFF641EDC41EBFC03B31CDB03CEC0415A934C4ACE801AC1A43145818441347424F35F5839C9CBC4EDCF295120B16A082981751E2EBF96A8683D24CF84592572718CE731D48AD087DD4B425032A162B7504D668DA22540969F2B88271267EA76A528015D4F5983434D5DF4F4A9D15A1994CB56925ABB38CE4C410BB503AF6EF0E1C989F2A0FC62530F3EA2916B69E3C390D2D82CE47BFAFC2D9B61D619C167D72A1099353847DEB77E0887994CCE9AA09A6B0901F1AFB80BAF8315703EC4871C137A2D347734BD8F9FD37F95E025E94EFCE9103DDBC60D3AED083716BCE15C5F2441828AC9C320491EF6B3D55A898A20C37F1E42443D6CB9B41A9BFA6C670F6CFB49C0ED143FF0EE5DB30DA1D580789B34F8BB966025A39A48025AA5AC2A41FACD87C5E6D0DD193D2A91A1D481D49570A2CFE9FEC55C46DE2362979198BDD57D7DCC4E17C4BFB0FD36B55D4C05027F59D8BFFBD501BBF7FF6C36AF87F08474C98C48137DBB6EBBEE14EE15403D1E79F95DD6F63149EA7A775440214142C39427C6622F8429D3457B41045242CB22BBE5FE18EEC2398189C5FC733E0F32F133835D2F10C810C956BD8BA2C1CB2B5D28E4CEBB587C58F33AF816AB0F5B3696E27E55C09AAC62D25D15C816DDDD1B910356CF41C8A7DCA037FA614AD84B23F1395A21DCE6C5F6395463AAF5CB28229FFB0BF8F12460EDED448FFF9B3C2A95BC31A4B24C0B72A4A3F2A792590C9732747A2015CF470059787643486802FB4C6832DEAF50AB5BD72AB154ABA4410DCAC7A06D87C75C15B398C8093F9DF4103E6CC8FF5A0D73B88B30D5A0F160420EDF4A61B22831EB3903F852962884EA120194A56233463C4796F82418627BC3AC3E49091E10FA2FB0E57A3A11A754210E693253F4F8DB2CE46C230F89D5FC278E9E0F5FC4E014E0899F017AC412882E6EF529C35737393695D872C59A53A767057FB61DEDAF16895704285ED7393C6BE09C86FB5B55B9E6A444388D74C8D07D36A97024C467E851E31D51E6A44EE5E549D1ACBCC07C5C32965489E2F15DB3DED8C8D37A6295D073AFC59650A0A17575AB3696405C1D0C1BCA0B76A56DC9E741BFAB688CD95918D77F8B6C44B2831DA87EF7B466088D9B61BD8EC06C7CA71D9805923D1F8522C5B214B915FECCC1927D4BE5470C89B743A0E200E271509E35614FD6B771CA80F0BAB290D2BA9F2B85644F604C5923F9EA5BD0AAEF37AA5294F97F6FB1B3AE262106BF9D0E3A089119489BD1B7E1F5C175618EEAB83655FBB6B5C9638D9F46730C607355AD1605AB62A88582C00BB51087B14F29C722003A0EAF65157BF7800F9DA5566FCE2DF8A7B9C43071D9B46A600239B3DFACB98EA0E0477400328914EFC97A80D63688FC4B731F07B94BA59837DF03D4BE362ECBD74F6DAAB4F208610A8A824449AA0274D83B045D2BC34F01F22BDD58119EEB66AEA51B9BB54B6C878D32466FAD28FB3E3DB4CD0CEC7FBED6CABD5CBD07E8C7A3551D0BF21429500ED0CF74B2C088A5668C0F0AEFA9161C58B9D90595D360B620BB7C232DEBA1A65D829B858F5160CFC0E58A3BFF62F3749F8DCD5EB70F85E6DC38E06390D6429833226626EF509F30AE3B6E436F7A3576EA2819B0E62CC459B625C128F8C926B5B2A04F2988E44C96C0D1B1787ED03F0A87BF03AED175244C5906B3B7077A9446026BA4FF39898CA8C417535F06ADDB3B1A991615FB3A97D3EED4FFBE31E34289D6C3C63B46ACC0D7CF26CCD299535DE02FAC3849150E5A180E3119203292D27F74C4CB7C16176C505C73049E57D063A65AD756744355A0D017D0881E091AE2261BB59A65091910AB2C2005AA2397812899FFE384F899F64B7C787180D29DCA441D85C9A16325F89171A5E648995A6A7B719333A4FE0FB143D4275BABD215978B1C61579A8B5BAC3F0000000000000000000000000000000000000040D13191E25482F2926D966AFE645A44AADA4AE3686C451A184C37E8F689D38C4836C2A9FF642746AA6E5031D15721E85205B6DE909D65E35D46BE971CD4DA0A6F8304EB58D2B0642EDD5BEB529E9FAD4B5887FA1D9DAF8D32220174F77DB4BE3B3D6A25E2269F2EB4650A0A0DA8FE1A4733B8FB93AC3E496A94F46404B76DFB518512C833AD8827DC0998224DB3739145C8B84AC736BA80025BC76A13A654AC44F752EACAB7062DB55A667850D5E897DA6F7C25E8B4F763CA38AD260E46648F3994D3E6F65D42713398DB2FA9F3F118E011E48B166CB1E38B4FB818F8A89964A729DCA1DD241F6DF4547D96F9BE0F438A725945A38901CD3C8F5FFC1AD0F13433ED607E55F0F59DED80259593F1F7952288CB6AFEAC204C3ABD842AAA4155FA96525D7958A5C7188E1812797FE7357DC79625D13F9C833F4876DCDD5E6078A4D1321A0DB425434FDF09245314820164DFCB81D59F58DD7658F93F168C5ED511894A6EF4EC5DD6A35464D7A799C39EF819C4D36E98271E9320505587A25CEDD333FE76C34A7 + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-65-RSA3072-PKCS15-SHA512:COMP_ML_DSA_65_RSA3072_PKCS15_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 5948EF06B5553AD2BFDC07BE94281983BD4685BB476A541F047B8CC7B88180119AC269EC3A6AD1FCEFA6F8BE5445FC42517DB551E71AFDFBC97007BA673F6F833959FA6152377F9CE78DD0EC51F5DCBD63084695406F4EA056270BC96DB544CB350123A7A244298851DD1FAED555659053552C40DF5F3D4962A31764881389C77043E9E3C4027CD703DE95078B7897B006B9BB340760A5971C95E250955A600969741C984557FF64E7FB1714CF0A5CC11A7E41C318636D7059F0ECA723E5D6A86776F3DDBE49F2AB6E8C52194F6E83CE052201AFA74C878BDB67AD9B1FB1F37FDC9B4CABC73961BD929FCE853135D9A2A6AEDE4FCCAC3080A2F718FEEEACE509BF37847FCAD640A570707F0C499B1A4944A6B6C2667DA5A96AA7ABE5AB04ED3C8823EA334C5CCD6BBB70E6F0717C69611120E56FE4629633338731E2DD42BCE33E8DC62C373A7308BA3279120DC305F9C415AF927F19952B493F6E5300425A0E1FC4C7B34F6A2B1D24D41D5D99D8C30431F1D99FA2B39BC6156C913EC4F57E8A44CA86100E20BC66D64F6ADC51814391DA2B9BBCCCDF5BE2CD441C5798BB10E930E39C316A40F071F93A34A7EEB63874CDBDDE0A5AFA84EC722F3988722AAD2B0D50D681BF49CD7F82537BF7949FCA5CC11F8095C9357F5490C86909F1A202CEBE0AB57A1DF25856B6B5C92D37835EF183C90679BF882B954B4F2D2F9420D92089878E60CA35FB76ED81A4F2A524AFB5C1EC0BFE61354AD39F82876D4FDD3954AE60C92CBCC75D5F9F6FE26DA1B182B9074D0FB7D5263B411EE736282E6D864FB130049A202E7D1321FFE8898EEA1F51C3AD125CACAAA285398A67C5BEB2703A5A32BA6D3F31E84C48A622C372E957821A8950EC72415F6BBCC2313140B238C42E896856043776A0536944313F976AC28769C3269D7062D692EEE502A879CF6BA97FBB34EE4F3D762062A302DBA1F1FFB5DCABAFDC58E9C82D9EDBAAAE54959F5E746648AB7F79072C00D6C8963C3D9EAA04A52763382C5A911B60ABFAE998B89FBA5F5078BADCBC98F68B06BA330E546B467770B9B64E2120C4D6AF7BBA545D96147A585BE7CEE7E07D216C29648D7DC338169D85BE32F2E9503F5076B4C62691F53A839F23F707334A02F11184AFDC38767CB772E053A0D9880C009F68A57305E6E8C43ED2175DC103D1BF615252FE03EFE0094F66FB95E52537610C97B99F6565ADBC711080D958EAD1FF946332D745C48324D123CE7F51066DC02D504470CE162B13D7DF346FCD80CD910A0DAD4F7959E6C5F9184E669BE1F5CA99B32C2192782C4C69AB930BA4E68A0894932B5821065D415CDA2038F725ED2819F5840007CC2C75AA8F1C8B812E1CA104D5F33418A8E991CE4A6BFE4167C915976423238B87DA6E2005EB670F7BAE62D3DCEC680DC811399F5C0B32E5CABBC1131174B8968D952E07F1EDBAE6F78502249F1E3C4C8251FA0FDFA75DBD7B9B47E1C7BF782F43F802AF137CAE524470B6F5D7A95335F270634167567FFC0C871916E51A3877901DF35F888991FD6F80BBD62D9BEE006B10018CB975A5EC1F0E0A97DD5EEF95BBFB2710BD1B3E15C4476467994AF37CB1FE7555973A1FB7026DF18E7438BF0FAEB070870FA183EDD95AF65FA156F34A1D232EF074666BF568F90F20597FBBA293929DF24786CB7A2120CD3F6FD63BBADC53B20C435373FE4F0D2D731BCC92625248EE71FA71F6E171054025662F383EBDAF43FBF242234CFB6E15E97223441A15D67F9FAD4ED9612B085F7EF93BDAA94B7F673765180E4724BC132534DE6C07BA5A0CA406F82451EAA66BEA11488943136803F8C7C3800B9E022064D0240C8A0658824A1F6557939121DF1C880F1F9B302922C6138F7D90387D428679FAD5BFA0E2DE2672D329356BE6D35AEE0576C7D4AA9EE91DE0C12CB4FBC0A0441D79BCC24BBF9306016F622F226D533D3DEDD969926B8FF3DD546CC7872265273497671D36A81E283A1CBDA55E9A68A9B5C3E8F7A6E283D167A9E7CD5984B5B0B89C5FE3C2861F57CF7C12631844EEFED371C4B1F970471F26B79255AB0B896BE4F17D03DE632478F098D85A4088331654E12D128E329D6A57EFCEF8E68376694A367C24046AA111B8B9AD6D2AC4EC07F906EEA97518ACB2278645055BE7F7C88D3F756023D61EAE2B6E2397CB466291D59031A41C8A44E857E5AA7C76DDEC6D854EF89A23D9CC548C1DB8918D348C78DE02122937014ADEFEA2F2407C421EDBC807C375949DBEC492D2A52E9068CAB783CD16DA178A7553F0034EAF7700F27D71093A5AF4EE2D5654A27E9B8B55144C6E365590CE8CC8AA18DBA7FB4AFB4F3D8ABC4A743AA4EB2629EB9F30826878B0BF33A5BD23ADFF87C687E7C0A058B180A292C080CEEBF4D7FD9E2EA095A21701A5162DF1939F33320817842BFDFBAE3EA8A1F559B11EE09A3CB3C95E0F9AD3061BA3D949B0297FC453C1C91D23AE7EEE06FF0F586C331189517F0AEEFDDF1848363B434838AEB6140F31A7BF51737CCB6C51944A6C1FBE843398066C8D6DB170CB07305BC305BCC33C174FDDCAE0F085A829F8F4A72DE57BF72DE90BB666A0C7E3BDA6F161A56C5E0A6F89A1BC35B6E03E1DE7A2F88B7DDD6C5341A4B819801D822DD16145264ED12E80A3F68225B4782C0B8A382ADB35EBC15D9B5C992200806CD3D76CB1DAD241B04482513215F827AFF641EDC41EBFC03B31CDB03CEC0415A934C4ACE801AC1A43145818441347424F35F5839C9CBC4EDCF295120B16A082981751E2EBF96A8683D24CF84592572718CE731D48AD087DD4B425032A162B7504D668DA22540969F2B88271267EA76A528015D4F5983434D5DF4F4A9D15A1994CB56925ABB38CE4C410BB503AF6EF0E1C989F2A0FC62530F3EA2916B69E3C390D2D82CE47BFAFC2D9B61D619C167D72A1099353847DEB77E0887994CCE9AA09A6B0901F1AFB80BAF8315703EC4871C137A2D347734BD8F9FD37F95E025E94EFCE9103DDBC60D3AED083716BCE15C5F2441828AC9C320491EF6B3D55A898A20C37F1E42443D6CB9B41A9BFA6C670F6CFB49C0ED143FF0EE5DB30DA1D580789B34F8BB966025A39A48025AA5AC2A41FACD87C5E6D0DD193D2A91A1D481D49570A2CFE9FEC55C46DE2362979198BDD57D7DCC4E17C4BFB0FD36B55D4C05027F59D8BFFBD501BBF7FF6C36AF87F08474C98C48137DBB6EBBEE14EE15403D1E79F95DD6F63149EA7A775440214142C39427C6622F8429D3457B41045242CB22BBE5FE18EEC2398189C5FC733E0F32F133835D2F10C810C956BD8BA2C1CB2B5D28E4CEBB587C58F33AF816AB0F5B3696E27E55C09AAC62D25D15C816DDDD1B910356CF41C8A7DCA037FA614AD84B23F1395A21DCE6C5F6395463AAF5CB28229FFB0BF8F12460EDED448FFF9B3C2A95BC31A4B24C0B72A4A3F2A792590C9732747A2015CF470059787643486802FB4C6832DEAF50AB5BD72AB154ABA4410DCAC7A06D87C75C15B398C8093F9DF4103E6CC8FF5A0D73B88B30D5A0F160420EDF4A61B22831EB3903F852962884EA120194A56233463C4796F82418627BC3AC3E49091E10FA2FB0E57A3A11A754210E693253F4F8DB2CE46C230F89D5FC278E9E0F5FC4E014E0899F017AC412882E6EF529C35737393695D872C59A53A767057FB61DEDAF16895704285ED7393C6BE09C86FB5B55B9E6A444388D74C8D07D36A97024C467E851E31D51E6A44EE5E549D1ACBCC07C5C32965489E2F15DB3DED8C8D37A6295D073AFC59650A0A17575AB3696405C1D0C1BCA0B76A56DC9E741BFAB688CD95918D77F8B6C44B2831DA87EF7B466088D9B61BD8EC06C7CA71D9805923D1F8522C5B214B915FECCC1927D4BE5470C89B743A0E200E271509E35614FD6B771CA80F0BAB290D2BA9F2B85644F604C5923F9EA5BD0AAEF37AA5294F97F6FB1B3AE262106BF9D0E3A089119489BD1B7E1F5C175618EEAB83655FBB6B5C9638D9F46730C607355AD1605AB62A88582C00BB51087B14F29C722003A0EAF65157BF7800F9DA5566FCE2DF8A7B9C43071D9B46A600239B3DFACB98EA0E0477400328914EFC97A80D63688FC4B731F07B94BA59837DF03D4BE362ECBD74F6DAAB4F208610A8A824449AA0274D83B045D2BC34F01F22BDD58119EEB66AEA51B9BB54B6C878D32466FAD28FB3E3DB4CD0CEC7FBED6CABD5CBD07E8C7A3551D0BF21429500ED0CF74B2C088A5668C0F0AEFA9161C58B9D90595D360B620BB7C232DEBA1A65D829B858F5160CFC0E58A3BFF62F3749F8DCD5EB70F85E6DC38E06390D6429833226626EF509F30AE3B6E436F7A3576EA2819B0E62CC459B625C128F8C926B5B2A04F2988E44C96C0D1B1787ED03F0A87BF03AED175244C5906B3B7077A9446026BA4FF39898CA8C417535F06ADDB3B1A991615FB3A97D3EED4FFBE31E34289D6C3C63B46ACC0D7CF26CCD299535DE02FAC3849150E5A180E3119203292D27F74C4CB7C16176C505C73049E57D063A65AD756744355A0D017D0881E091AE2261BB59A65091910AB2C2005AA2397812899FFE384F899F64B7C787180D29DCA441D85C9A16325F89171A5E648995A6A7B719333A4FE0FB143D4275BABD215978B1C61579A8B5BAC3F0000000000000000000000000000000000000040D13191E25482F2926D966AFE645A44AADA4AE3686C451A184C37E8F689D38C4836C2A9FF642746AA6E5031D15721E85205B6DE909D65E35D46BE971CD4DA0A6F8304EB58D2B0642EDD5BEB529E9FAD4B5887FA1D9DAF8D32220174F77DB4BE3B3D6A25E2269F2EB4650A0A0DA8FE1A4733B8FB93AC3E496A94F46404B76DFB518512C833AD8827DC0998224DB3739145C8B84AC736BA80025BC76A13A654AC44F752EACAB7062DB55A667850D5E897DA6F7C25E8B4F763CA38AD260E46648F3994D3E6F65D42713398DB2FA9F3F118E011E48B166CB1E38B4FB818F8A89964A729DCA1DD241F6DF4547D96F9BE0F438A725945A38901CD3C8F5FFC1AD0F13433ED607E55F0F59DED80259593F1F7952288CB6AFEAC204C3ABD842AAA4155FA96525D7958A5C7188E1812797FE7357DC79625D13F9C833F4876DCDD5E6078A4D1321A0DB425434FDF09245314820164DFCB81D59F58DD7658F93F168C5ED511894A6EF4EC5DD6A35464D7A799C39EF819C4D36E98271E9320505587A25CEDD333FE76C34A7 +Result = VERIFY_ERROR + +# --- ML-DSA-65-RSA4096-PSS-SHA512 --- +PublicKeyRaw = COMP_ML_DSA_65_RSA4096_PSS_SHA512:ML-DSA-65-RSA4096-PSS-SHA512:6F2F8658D2212B1267EEB8DEEF074F6A1E7AA9AC249F0FFB1F61D8EE1976ED0732E6413F374D44AA4673E8BA10341A8E2699EDDC18546F0871C6EB91464DA8718DB30DB82D6C74D15E6396397DD0E61D186C0E9893BA4E30CDE4B95C1E5F3CD1EF8CC24E8B74BB4B6F08C4642AD2F48179668115A1DEEA7BC5DCCE479968ACE38DA273E31B87D25173356736A8D9D5D445FA6903E8F002DB3656112ECB3ABF19B08B64ACE9C80B5A5B5C43A748D75EA21551B987D45D9E88B908B2050B4F7E0FA11F0B5DD6F39F4676D6D27689E2D4533282553C4C181AD8D8788C9AF9D15BF5799A613A4CBB7692FB3F905FF30DCA2DE714777EF0ADC4E466AADD6C00847C0585E3540C6329794FC9F11A55DDCA323849455E5B858F224CE1C6ED315B3607E28ABA6937190DDBE90DDE19F45334E2D12EB9A4437D07858D44082C0E4708EECE127989F92341F00D267292134912849BB66B77F5006D977D11BEE2D7EC766A4DE75C18463A6F8AE27855A3A52B6F6273D4A08AD49229B414CC81B74ABEBD33D81921508571F2A17DF4E8EBF13464EA0BB06D2F185CD1A9200FF6C66979EC89644D36914767863589E9EEF76FF51238E781E428C7B6C61FF3E41980E261CC0044CFCA1692869CD272BC913B182C85EB12855BED5BF7604FD052BBF2B3655CFE3C500937CA820B137351092E37DCE075A7AF64B858D44D98AA3FB424F77A29FA16E8A2358EDBF1FA4EAF0ECC1B6C16FE5490EB4A0DB0907D4AAAA2F1BC76C7C2C041BB9C9D6D9D4F935029165419142404E02A89E788ED3991655423626D5A120D335F802A6F5A53E2B3660A414158995D8B3668483A294A83C04FA88DD82610294E6D90E9B91F7C6C98EAD2042E0BDECEF84173E04052D4BC6570CFAD59C8F29D2A021C5CA02B9657DEA39105243E05AB4B03DAC81DC70F92A1A0F4CCC993FA541F9AA3A05EDC55BAD1C2D476200AB112809C830F2B19B396773559A4063F466DD53B9FAE5DEA9BA6A29742FD852C526B1A941945B43DB0F265173203CE5AC49D6769EC46CD9FEB129106915DBC0E48AB921AAA5555C664DAFF6AC9BEFD3B73C1466D0D4820E086F079E47FF75AC77388BB500724D2F9A27355367AD8BCCDA0E9F9C9B928D8B9BE0BC8E5C095BC5707DC57EEDAB1E2571381A0DAC93D3BA0A44197DABA2EF6FB203258CD7BE245E0BFD0ED9458F79ABAD29F5ABF84B7054B0882E15A31AC7CBA75768F3E4AD7743F54DD4036B2A6AAB35B845D85A9C0D7BED5C116F53E8F0D92F79405DE64A08FE4159D106F9A97A0021A6608D1EE380EB8BC4BC65842A53CE0F14F4B37F74C890232B04374771C25790B06DC69A70BA92B4C85D22548063C3E77C2CB5AD81EE9E4971915070354E866AC53C025D5D5007BC66EA4ADF878F2B1B2B5CC811A5CDFC86DB3AA48AB1C5DE89988F0586ED074CDBC7C29228B3442561707065B56675E8A73D180BAF7C6F92FA551DE82C360978E1645BFDB795200E51554001C57DD8C8426DA35056D333E7C34FFBEB03F33204FF667F74C42E2223C0F5B6D3C47E13D626FD04755516566739F5006D6709EBCBE32CD67DA9C23DFD2D3A1946672062C30BC3CBB76FB1A0078D07CE61934599258EFA86B6586A3C5FB09F4F847FA0F43B9159A918830BCEB1A948E4497DE59359E4D2B6F12E301F15BE49633F1977CE512A34AAAD414AF4BF8575850F88286F53ECC7576A18E68BBBFC534445F4A1D2450C43EFE69404C3783B16F45AF2E2682E8186A72AFC990D687C05895BAB1725797B1EF962938991F478DA5199210F72506307E2A84C8F0168AF38D5A979543F643BA6221D5F7FD3C28CCFF25A1D2610804A640AB886EDA2C23E7AF67FC608E6364373222CD6ABA740BFE455EF46E8FF6FEEF76995E15987D667BF048052A3858842F4094DD7D62B3F9EA053981C0351D396C1CFAE6DA711A961F8801A6AB1CFC27EF289A7E25057F742D9005DD2A0A32A499D6D59B6F3069F0BC6C0AD485CC4BA4CCE4EC776BF8D7B9ED88EE7CB1FB3D2F0C0E42A4E0FB6448605CBCAC426DA90B370E29B467692B57970E219AC1856B35C55AF9E2F60B11A67A8C3E3EFABA457825C657604A83F2EF9BB32034A223E8431935A78C89E5B73CEA306DED8B3E069CC6F87C310CB02E0A3AAEE30A480B7AAB58CFB015D4888403BAC5ACFE19073C4A82AAFE48C27378E12893DD970030D3BA89166A5F0C33CB14E46AC0A7E771F90279949182C03346CEDB67F6AD57AF2F961ECE979C7337475952DA9D79BD542D8EE3FBE7847423F806FCA3B4C59BF505A5ABF1EE8728AF6C8CBBCC3C66723A2AFF2306EDD2F94997A710A3DDF3A18D9D0BDCF1570AEA7B2FBC1AE216003D9F744E10D701DB6D9CB89F6FE3E78533588BB1EAF92DB25B5581B00D435D3A0822252326E1BFE5A35DBF245EB6095EBD0B92D2CE96CBBA9EFA12966D8F0D9FDEAF4AF2A6353FBA7C2EABC7E3C6A0F6CD9B2DAD2A47B3D4380852E18AA1611DF6D3B61FD4AC88DBE73A4CD67A8D3E881278B23D32350FBD79C1EC4D9B33214DD77806DE3AB9C240E0B2760AC3F0D0BBDF9B235243FE592D510F39B008E993468D650B6BADBE7CFE003054BB16E75B5A4F752C898A8C5F3D97E14756864D894497CB13EA66368682F1ED63E638E04D4E03D1A3087CAC067E8AC1C52479CDA676AC91E53C86DBB4525110847E7DB9044DC27B36B4DF68E4EBDED32BFC745D32C22E1ECD916F38E45E69F8CC5105FD47DC904444E0B4FE3082020A0282020100C282D5A772D2C739A825536DF6D88F645947501DEEA2AB669C0DC9199BE3071A8461A84854669CDE59C894A1ECDE833E9DF286CB5DEAF55B8FDDF382EB03D307908B2144FE1A2B0F581C6EC8870DB5CC0DCFC67A23E734C497FE71F69473E6B060AA060715386CCC5269E003C2CCCE0018DCE1C87437DFDF20587456EC451C92395EDA4E6C55F3CCFBD7CA96938706F3DF45F7A07F5D1E19900C2CCE381E70969ECA20BD25C2B475CEE9A0ED9F9FFCC58527ADF6000E1099C6797D00A5171D5C2C9FB863C1105F192AEC7C48BC6043C9C5E5FFD4B81B67382860E62E9BA3FCFB59A024368FC73DE2BD6643F016D2BB0CCF013CB13281ED6E6257DD89EC9D5E286D2508C4408EBAF5305DA36DC733816E112FD99B972EEFD1161DF31F9E1C8683C9A331CDB525AA08791AC565B15AD459691C3E08A5F1C2D00E801B7DDA9D1D5440C90D1987FB8ECE8ED0B20C27C2FD0288B9B1C243537F9C6AEBDEC0309151CBB64E55EBA5D7A5FB62AEBFFD86993AFD76A7E00C69FB042D42A684A759D827732E2222CC44C7DB88EE626891A373156E59F1D5C035A60DC8658268B0C65B846CABD97DDB00B3FA9EE3AFC5065BC30394A1CB545AC39D17E1539752EF34297A14F9E5F4A5218C4D7B7A97AFEA587C50BE1032F23F11700A7FAC554BA2CC5AC8F450EAF0BA4203FD014C05D557877C1451B0D250B555B7F8F68287FA3519F1F2CF0203010001 + +# valid signature +Verify-Message-Public = ML-DSA-65-RSA4096-PSS-SHA512:COMP_ML_DSA_65_RSA4096_PSS_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 7AC5BB765D468F803E44F83623974A19792E02013794A1EBDFFD85C8C04811E29814FB2CEAE7209BBCF6A72BF3769797BF1420DEC1AC94DF465B9780DD96C1E2816B9C56FB47BE352E3AB7D2B2F4270CCA2A198C30CEC265CB0F623A796D5BBF2AC2F9EB045B516E2F4E7655303D2B0DDB702DFA1BB26F39DB01D1F6A716F95493D01951F09FB9D0B11D165AA8667E7FAC9231923E552AB278A361EB63ABE8B40C770CF8276497D34CBD53D9E919535F925024F8B9CC43A338A6194F8E1CE553195F1BD8260953E842E4F1878D73A3A5C0255A29B69F30ABD9EACF5D5C0F03DF2AD5CEB16ACA87A0BC8C623EB10DF4A2B75FB5A84D1E1CAB692E8D76C89C15B5BF1CA5B9135F3A02E29FE190A1CA413AD14404C7690FC3E29268C50C4BA1E63960C4AEB8653957353747677DB716D563E12A311DC1D63D6A525B117156AFBD6791713B00643138A2820DB9B3C7FCF30C4D675C32BC0D5105BCE0E5BF82A45A16F265E4B77548F18A589439014D95ED14BE839B456C3B369D76A74C9C8DA35363F769CF7205FE99C90C76F3D20C289CBAC05E573FD49402509CC4386CAF9E3EBAFFE539FB56CDBC13BCFBCEBC8D840B6139BAD8E3E0489CF767A4CA4AE61B03150B9CF6BC2176ADB6D9658DC9E875C12EC4C2F6585E78AE95A901DD696E1D25E5D1DFCD6E14506415B7AB880B069EEAD173BF5FFCFBEB91D41CCC62037F4AF7113C6BDEC7EAD371D2D4FE2C783F8287E617147A2C7CD861EF839BE00C76E08627F377774B0EB101B499575FC2D66529718FDCCD9A3F41A854E83EBF87AAAF054E8EF707EA9D4B3CA628DB63C0DD834C57FCC35C10595B8789264A36FFD5499BADE483409C3C19F3A529791A922C6D20B4794CE4B564E23C359E3B4BB09D179DE77DA0808C97718AB546F0DAF50CD8C74C1D6EDAEBEB8698E2828C730F9C1B9BE00C6EF15C7A8CD297C05781F1E889323092C54B93C7B3EC5E4DDAE7BB20373E991D24A9252026289D52A5FCD65F0EBA846F80F42834E31D922E6EF9367D9AF5DF04C2D8EE903794CB1FCAA86485F25E623C43CB0001E4BCF8F7FE867C98C44BBF8974181DDA6894F44DBDA9819481F46C92722143FCC974011F87A304668188AF655530CB65C7F0C8C9463FBE02FFA23FF642F4F285610529D2E7CDF4052A4E1C0697E6B855E5B33F289B87871F179F07066F9C7BE33BE0756659AC662ECD9EF4C1C8D69127855C8F6D682D7FB13F94D50AB19222B5143E4C33027D5012658B5811F74CE388C351FD0AD72514A92A5993B91A04B42BDFE87EF7C7670BAB39578AF24EBCFA7404E2F926951B54AB4FFBDF7B6A3660CF8C605C1934FB7B671D230D82323F82FA92CF38488A81D74473A63DE88FAE9923ADD3AC6B7AB3650329BA9A5D21F109B96A5B97208AFBDEB5677882BCCCD27A93E77E3FCD62278EB0801D9562EDEB98E9CB21F1BB04B55277D3215B26A417CA3A3D69EF577D8E89598AB1E28FFC5A1F81B725D5EEEAC6D821DD508A0949D51C0F8841B2D8837377379B135DA2CB0B523ED896F6F76D2E1038C041DBE9E42F703D1FCE8CAC8B51B30E2D34B6C806C24902AB310A71B15CE70A834DF0B1B26A02B3CF2195E81EE9393329CF151FAC1CA9C397653995B5C351573E2F00839A1F23966BE11F88A26A4D707C3CB848A6745C740F182CCC250BBC18923AB30A35E5BC8AB12E65241DCC7FAB018F0B71D8D813E0B89F64D0A2723B3F2D2452A8DD7535FAFC592137C2ABDBCB086DF34C002E62660C6834282AC5C2852DE0E755C715A9E3D78AEC595892CC8A0C3FE551B055DB56BFA8B2D583390422FB9B8D54CFF0146522EE9E03C613D0B5F696C0973976CC461EA7C6287F81439FBA863B6C38DBFE9B948E815A3C0D8A56DE3E17D972D7CB3E1867EFCCF6A4ACE6C9BCF01E863951827BD9FE21C86BAB17CD91392334B316D25AAE04B539AA71D275E7FB6E4FCE3C481F3D645A465745F312B913A8E07C7628B9D683CDD404CC02CE356B643AC9D8BB5113C4CB16C8310A1A43D0DB530997B8D76044EE2CEAF2FAE83AA5BEEB1493C8D9E1C6E46D73B0900A7B513E1C83A2A600C7B2F8D2C20F6F415B0D42CF863B080FE708005DC3C90D50CC20D422CB2E52EA21DCEA63EC42211AD2630C5DE583B4147D4855FC75C12C99DF5F5BCDB323CC1A2F89E419AE54EBAF774F3A74E4E5AD4620095C89228B1AC34C8DD71B859D2C11FECC40F3B74E4ECA9DCA5C3A6BC71F068DEF8CB7963B2347422A758EEF798F3ECBE3269FDA8A2EC9CB70487A0351B2ABB80193EFECC0B860E08B38BA8DA7A27FE56C7C1C1F3C1FFE9EFC07A83F3F8E9ADAE6BBD6B6EF60B531901140D84E5F81F75B3F5661C2138C31B404514CCB210AAA18A39F68505327133055B4D2F1E56F799F5E4A4139959948852B16854A6B430383B48E3998FFBD19E49C7FFA77585020E67270E7718103108732CBB96CA394102B833D9A0036D9AD08F7B1F80E96BA6BD20BBB464BB6705FF50FE5850D9182D51738603BC321A150CEE34926C3816D1FA474E868A301730584B9A458C04B447CEE44C2F4EF71F18748BDCC3888D263BB9884472E11921E119983AEF4CF3699F172F44962130A638C416E019DEDE65FF1D36D57E594D7FE0289B62955D26DDEC21894612F915EB6033BFC903CEB285A4420D1C9617439ED75248CB653A40DBBA1CDD026BDEF99CC1FE4D5E6E71AF4C29B36C491C03CEEE96AAA3BE9E4EEEF2DC0F40B185E6BFAA5BD2C23AB0C99AEBCE7BE8908E6F89043F00C47D54048A56608B32B17D3E89B6338AE0C05EE3315360B309BC3B0FAF3C3EE33ED179647960E7EDA8F8D4E6D6AD2ED5B5118E601DD9D9EEE21A27E658905468FE5214C4659BA522D7A2B818C5E7E96597F3039DA94780BF135A6A37D43D61A8AF6994F38CE40925F932AC1E5BDD06A30864D842D9B33AE04EDD692B29C60BCF1138668FFDB955E9541642357A872E06D2C98A5ECF05C8C809EF6C9ADE383FC8C945647671F29F8409BC0D45E8524F7F108A2CB48C4EDBD02FDC5D14A9F6004781D240C881D832E852D3F5A9390D20FE645461C084564D9720681D305ED08F6066D33544529A026367BBAEF610F9A3299BE149DAA94D0833A79C16338AC48CF8158E960685D81CB9229BE20405A0A887C9111D97FA51DB4B3B1B5FB60C80EEB5F9C6F8494C7B8F5D121F5F349853B8DCEE4DCD98094CDA2974D44591931616FA1A86AB7955792F3DF84CED0EAC847BA48E1BDEA91999AE079EDC68AB2EEA48518699629A6C5FD5E25C23107569105A799348FADCC9CEB52DEAA220C458492CC04E72A2856FC7BA7F7B473C81085C92F46D396333A022D6304C47DCA9EB17143B6CB7768FE5DACFB63490F83CCE69A98384D9D8FFDDBEFF500761ECE23A84AEAEEE9D00FC5F74BB35F3A837E23E1CB591EADD9FAB2ACCE614F9F291A87383C0E9F27B0143BD3E753DAABC1162A51E9B030E9DBDB1EDF496C8F5C0EC7A523E5B92F28DDA799C180707DCED957DBC7D7FA9B0EF9FB0CD6E91360D596E878E1ED6080B930FFF6CEC9156FAE1B1A15FE86345D8EC473393BCA28C34AD7FCF2E2D4A6B98EB4D8368D27C3CF18113FFAC0AAA76B161644B549E4F36D3F7BA41441D8AE781B4790FFF04FBD6FC25AC36BFF9923959B9ED0C4326D5DD2FDD1CF9FEA0AD7CFCDBF4E5AB73C0D87E1078D9FD00464304C21E323C426A209FBC24B3FF29D8B37D857DE9226307CA1DE186777BD18D056526E0ADE148928ACE13D9FDE863FB9524883ACF858E808D16A37EA1C8E6F4120ED4D54C3BE74CAE4E9477ED8B172EA98733876DDE41A8460CA197AA271CD2E7CFD4842647E3A7F18848A0823F0F127D3E42C200AA774E9211499D86C23072DF55EB0396C2F126AA3CF386D914604D942B083BC9FB8F75517F914C92F3EBD2873A61EB46757478DDE01FBDBF667B88D88CBAEC3B263325AA3718792DFF4C82B70E7D01B418270A44D8900669A9F8587977FBDAC420BC761A21A38CC1CD67920F67C3FA3F2515A20ED7213BB9D4941D770C3E4289AC9BDEBCC64B39117ED96EC224DCF1DC7F22BACF1F6D42E034985E85D20028313D0A4771801FF184D7A706A597955F15C6C7AD7589D3385C292100BD33D8D81045FCA284DC862C039FBEF0AE1883F99159EBCAD47B0953AC6EA4815EC88B995DAEFCD5196B698EFFD4559FD3250FFD0BACC5BA91B5767F977B096EEE5BB0417EEBD328C517F2D955FF350E82489B6CCB0A0C1F670DA0431D9EC92CB8945DEA4B949C70A58BBB6B8CA5B2B926D967EEC42C305E7017A7E623EABA0E03E2D575F03EE5B086A18D0C67EBD025D3285D12184B0BAF41D03BCCDBFC4CA1669EC7C141AA46026077499DACC4D58CB30ABD594AFE31AC5E16E45F27CF86C8880AE275B171DB6BAF3335E1F2253CBCC5B72D81B4E89C6C2CD258DEF65217838D5D6AF49231E22904D91070A52F6A61C5E4FA672E3DA2835713C6EE75D12A9746480E2CBE4471509F7C1B564948F424949781AF0ACA45BB4CA5B76B758C3BA6E67498F4FCA631F20C1C5E416C5EE03F7DD83F1DF4DAD6C434C7DE9C623060462A30B455277A1BAE3F3020A617083AFBAEB0F233E64A7B5C3D2D9FC12486394C7264C5F62A672EAEF0000000000000000000000000000000008101A1F2427A9CA8FA82D44B2DF8A84B2E98D1F6CD489DA44A43C9DE1FD55280AF9D370DAC49B3A0B1112DB87F018516862AC2940A3B13A721D17EA92306584AACC2BE73B1BBB5919EFEC1867E4F75757833952BE708FAD220502AF0DFE4C0D09152BEC29F4ADE85FCA3A9910F4152AA803B40E39CE22C8ACE02BEB47779E6A013051B441E87A20484B417CB07D172325F1F6A961F348EFD4936B56271F0BD0370D5E51D7C69DBD401F34D4B7E9936A3FE83301CFF4718BF0F910365E16AD9E05027D392375B0EB4435466B87F5A156A543BC76632DCD8086E4CE8B900D2A92A6B58ED4C99D829D310E99A027526506B5417810D0AFAA2E23288A041A8FFAD10A1929179B626E2AAF95747A3A985FFA47646FCB9798610E7E0D9EFAE30E9908046C4A7284B377BB803DCFC267E5D73B42E360FEEC337AC5F3E5BC647A432B9DCD724F4D0091D03ED349628BF419C705B23215D2F813CC11296E584F84599CF6F19D707E16D22F19397EB40AE7262FDC8E4B010083178051F0797F8E3F5388531963E6C0F35C975F1A8FD786A7739E373A6E11F5D503C6FBC2518487C10E7205FFFAAD2F066BA755102EF9C76DE58E9A8318F05CE8B5525D7B94A926D983C478E5A2B455DCB9102BFD115791B225E5DFF8844A740D4838A16D53C2171F8811BC01839C036F30ABBF022CD785E01E7B6FB7E1A040667DB7B3D40684BEF581DDD6B7895E8EC553 + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-65-RSA4096-PSS-SHA512:COMP_ML_DSA_65_RSA4096_PSS_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 7BC5BB765D468F803E44F83623974A19792E02013794A1EBDFFD85C8C04811E29814FB2CEAE7209BBCF6A72BF3769797BF1420DEC1AC94DF465B9780DD96C1E2816B9C56FB47BE352E3AB7D2B2F4270CCA2A198C30CEC265CB0F623A796D5BBF2AC2F9EB045B516E2F4E7655303D2B0DDB702DFA1BB26F39DB01D1F6A716F95493D01951F09FB9D0B11D165AA8667E7FAC9231923E552AB278A361EB63ABE8B40C770CF8276497D34CBD53D9E919535F925024F8B9CC43A338A6194F8E1CE553195F1BD8260953E842E4F1878D73A3A5C0255A29B69F30ABD9EACF5D5C0F03DF2AD5CEB16ACA87A0BC8C623EB10DF4A2B75FB5A84D1E1CAB692E8D76C89C15B5BF1CA5B9135F3A02E29FE190A1CA413AD14404C7690FC3E29268C50C4BA1E63960C4AEB8653957353747677DB716D563E12A311DC1D63D6A525B117156AFBD6791713B00643138A2820DB9B3C7FCF30C4D675C32BC0D5105BCE0E5BF82A45A16F265E4B77548F18A589439014D95ED14BE839B456C3B369D76A74C9C8DA35363F769CF7205FE99C90C76F3D20C289CBAC05E573FD49402509CC4386CAF9E3EBAFFE539FB56CDBC13BCFBCEBC8D840B6139BAD8E3E0489CF767A4CA4AE61B03150B9CF6BC2176ADB6D9658DC9E875C12EC4C2F6585E78AE95A901DD696E1D25E5D1DFCD6E14506415B7AB880B069EEAD173BF5FFCFBEB91D41CCC62037F4AF7113C6BDEC7EAD371D2D4FE2C783F8287E617147A2C7CD861EF839BE00C76E08627F377774B0EB101B499575FC2D66529718FDCCD9A3F41A854E83EBF87AAAF054E8EF707EA9D4B3CA628DB63C0DD834C57FCC35C10595B8789264A36FFD5499BADE483409C3C19F3A529791A922C6D20B4794CE4B564E23C359E3B4BB09D179DE77DA0808C97718AB546F0DAF50CD8C74C1D6EDAEBEB8698E2828C730F9C1B9BE00C6EF15C7A8CD297C05781F1E889323092C54B93C7B3EC5E4DDAE7BB20373E991D24A9252026289D52A5FCD65F0EBA846F80F42834E31D922E6EF9367D9AF5DF04C2D8EE903794CB1FCAA86485F25E623C43CB0001E4BCF8F7FE867C98C44BBF8974181DDA6894F44DBDA9819481F46C92722143FCC974011F87A304668188AF655530CB65C7F0C8C9463FBE02FFA23FF642F4F285610529D2E7CDF4052A4E1C0697E6B855E5B33F289B87871F179F07066F9C7BE33BE0756659AC662ECD9EF4C1C8D69127855C8F6D682D7FB13F94D50AB19222B5143E4C33027D5012658B5811F74CE388C351FD0AD72514A92A5993B91A04B42BDFE87EF7C7670BAB39578AF24EBCFA7404E2F926951B54AB4FFBDF7B6A3660CF8C605C1934FB7B671D230D82323F82FA92CF38488A81D74473A63DE88FAE9923ADD3AC6B7AB3650329BA9A5D21F109B96A5B97208AFBDEB5677882BCCCD27A93E77E3FCD62278EB0801D9562EDEB98E9CB21F1BB04B55277D3215B26A417CA3A3D69EF577D8E89598AB1E28FFC5A1F81B725D5EEEAC6D821DD508A0949D51C0F8841B2D8837377379B135DA2CB0B523ED896F6F76D2E1038C041DBE9E42F703D1FCE8CAC8B51B30E2D34B6C806C24902AB310A71B15CE70A834DF0B1B26A02B3CF2195E81EE9393329CF151FAC1CA9C397653995B5C351573E2F00839A1F23966BE11F88A26A4D707C3CB848A6745C740F182CCC250BBC18923AB30A35E5BC8AB12E65241DCC7FAB018F0B71D8D813E0B89F64D0A2723B3F2D2452A8DD7535FAFC592137C2ABDBCB086DF34C002E62660C6834282AC5C2852DE0E755C715A9E3D78AEC595892CC8A0C3FE551B055DB56BFA8B2D583390422FB9B8D54CFF0146522EE9E03C613D0B5F696C0973976CC461EA7C6287F81439FBA863B6C38DBFE9B948E815A3C0D8A56DE3E17D972D7CB3E1867EFCCF6A4ACE6C9BCF01E863951827BD9FE21C86BAB17CD91392334B316D25AAE04B539AA71D275E7FB6E4FCE3C481F3D645A465745F312B913A8E07C7628B9D683CDD404CC02CE356B643AC9D8BB5113C4CB16C8310A1A43D0DB530997B8D76044EE2CEAF2FAE83AA5BEEB1493C8D9E1C6E46D73B0900A7B513E1C83A2A600C7B2F8D2C20F6F415B0D42CF863B080FE708005DC3C90D50CC20D422CB2E52EA21DCEA63EC42211AD2630C5DE583B4147D4855FC75C12C99DF5F5BCDB323CC1A2F89E419AE54EBAF774F3A74E4E5AD4620095C89228B1AC34C8DD71B859D2C11FECC40F3B74E4ECA9DCA5C3A6BC71F068DEF8CB7963B2347422A758EEF798F3ECBE3269FDA8A2EC9CB70487A0351B2ABB80193EFECC0B860E08B38BA8DA7A27FE56C7C1C1F3C1FFE9EFC07A83F3F8E9ADAE6BBD6B6EF60B531901140D84E5F81F75B3F5661C2138C31B404514CCB210AAA18A39F68505327133055B4D2F1E56F799F5E4A4139959948852B16854A6B430383B48E3998FFBD19E49C7FFA77585020E67270E7718103108732CBB96CA394102B833D9A0036D9AD08F7B1F80E96BA6BD20BBB464BB6705FF50FE5850D9182D51738603BC321A150CEE34926C3816D1FA474E868A301730584B9A458C04B447CEE44C2F4EF71F18748BDCC3888D263BB9884472E11921E119983AEF4CF3699F172F44962130A638C416E019DEDE65FF1D36D57E594D7FE0289B62955D26DDEC21894612F915EB6033BFC903CEB285A4420D1C9617439ED75248CB653A40DBBA1CDD026BDEF99CC1FE4D5E6E71AF4C29B36C491C03CEEE96AAA3BE9E4EEEF2DC0F40B185E6BFAA5BD2C23AB0C99AEBCE7BE8908E6F89043F00C47D54048A56608B32B17D3E89B6338AE0C05EE3315360B309BC3B0FAF3C3EE33ED179647960E7EDA8F8D4E6D6AD2ED5B5118E601DD9D9EEE21A27E658905468FE5214C4659BA522D7A2B818C5E7E96597F3039DA94780BF135A6A37D43D61A8AF6994F38CE40925F932AC1E5BDD06A30864D842D9B33AE04EDD692B29C60BCF1138668FFDB955E9541642357A872E06D2C98A5ECF05C8C809EF6C9ADE383FC8C945647671F29F8409BC0D45E8524F7F108A2CB48C4EDBD02FDC5D14A9F6004781D240C881D832E852D3F5A9390D20FE645461C084564D9720681D305ED08F6066D33544529A026367BBAEF610F9A3299BE149DAA94D0833A79C16338AC48CF8158E960685D81CB9229BE20405A0A887C9111D97FA51DB4B3B1B5FB60C80EEB5F9C6F8494C7B8F5D121F5F349853B8DCEE4DCD98094CDA2974D44591931616FA1A86AB7955792F3DF84CED0EAC847BA48E1BDEA91999AE079EDC68AB2EEA48518699629A6C5FD5E25C23107569105A799348FADCC9CEB52DEAA220C458492CC04E72A2856FC7BA7F7B473C81085C92F46D396333A022D6304C47DCA9EB17143B6CB7768FE5DACFB63490F83CCE69A98384D9D8FFDDBEFF500761ECE23A84AEAEEE9D00FC5F74BB35F3A837E23E1CB591EADD9FAB2ACCE614F9F291A87383C0E9F27B0143BD3E753DAABC1162A51E9B030E9DBDB1EDF496C8F5C0EC7A523E5B92F28DDA799C180707DCED957DBC7D7FA9B0EF9FB0CD6E91360D596E878E1ED6080B930FFF6CEC9156FAE1B1A15FE86345D8EC473393BCA28C34AD7FCF2E2D4A6B98EB4D8368D27C3CF18113FFAC0AAA76B161644B549E4F36D3F7BA41441D8AE781B4790FFF04FBD6FC25AC36BFF9923959B9ED0C4326D5DD2FDD1CF9FEA0AD7CFCDBF4E5AB73C0D87E1078D9FD00464304C21E323C426A209FBC24B3FF29D8B37D857DE9226307CA1DE186777BD18D056526E0ADE148928ACE13D9FDE863FB9524883ACF858E808D16A37EA1C8E6F4120ED4D54C3BE74CAE4E9477ED8B172EA98733876DDE41A8460CA197AA271CD2E7CFD4842647E3A7F18848A0823F0F127D3E42C200AA774E9211499D86C23072DF55EB0396C2F126AA3CF386D914604D942B083BC9FB8F75517F914C92F3EBD2873A61EB46757478DDE01FBDBF667B88D88CBAEC3B263325AA3718792DFF4C82B70E7D01B418270A44D8900669A9F8587977FBDAC420BC761A21A38CC1CD67920F67C3FA3F2515A20ED7213BB9D4941D770C3E4289AC9BDEBCC64B39117ED96EC224DCF1DC7F22BACF1F6D42E034985E85D20028313D0A4771801FF184D7A706A597955F15C6C7AD7589D3385C292100BD33D8D81045FCA284DC862C039FBEF0AE1883F99159EBCAD47B0953AC6EA4815EC88B995DAEFCD5196B698EFFD4559FD3250FFD0BACC5BA91B5767F977B096EEE5BB0417EEBD328C517F2D955FF350E82489B6CCB0A0C1F670DA0431D9EC92CB8945DEA4B949C70A58BBB6B8CA5B2B926D967EEC42C305E7017A7E623EABA0E03E2D575F03EE5B086A18D0C67EBD025D3285D12184B0BAF41D03BCCDBFC4CA1669EC7C141AA46026077499DACC4D58CB30ABD594AFE31AC5E16E45F27CF86C8880AE275B171DB6BAF3335E1F2253CBCC5B72D81B4E89C6C2CD258DEF65217838D5D6AF49231E22904D91070A52F6A61C5E4FA672E3DA2835713C6EE75D12A9746480E2CBE4471509F7C1B564948F424949781AF0ACA45BB4CA5B76B758C3BA6E67498F4FCA631F20C1C5E416C5EE03F7DD83F1DF4DAD6C434C7DE9C623060462A30B455277A1BAE3F3020A617083AFBAEB0F233E64A7B5C3D2D9FC12486394C7264C5F62A672EAEF0000000000000000000000000000000008101A1F2427A9CA8FA82D44B2DF8A84B2E98D1F6CD489DA44A43C9DE1FD55280AF9D370DAC49B3A0B1112DB87F018516862AC2940A3B13A721D17EA92306584AACC2BE73B1BBB5919EFEC1867E4F75757833952BE708FAD220502AF0DFE4C0D09152BEC29F4ADE85FCA3A9910F4152AA803B40E39CE22C8ACE02BEB47779E6A013051B441E87A20484B417CB07D172325F1F6A961F348EFD4936B56271F0BD0370D5E51D7C69DBD401F34D4B7E9936A3FE83301CFF4718BF0F910365E16AD9E05027D392375B0EB4435466B87F5A156A543BC76632DCD8086E4CE8B900D2A92A6B58ED4C99D829D310E99A027526506B5417810D0AFAA2E23288A041A8FFAD10A1929179B626E2AAF95747A3A985FFA47646FCB9798610E7E0D9EFAE30E9908046C4A7284B377BB803DCFC267E5D73B42E360FEEC337AC5F3E5BC647A432B9DCD724F4D0091D03ED349628BF419C705B23215D2F813CC11296E584F84599CF6F19D707E16D22F19397EB40AE7262FDC8E4B010083178051F0797F8E3F5388531963E6C0F35C975F1A8FD786A7739E373A6E11F5D503C6FBC2518487C10E7205FFFAAD2F066BA755102EF9C76DE58E9A8318F05CE8B5525D7B94A926D983C478E5A2B455DCB9102BFD115791B225E5DFF8844A740D4838A16D53C2171F8811BC01839C036F30ABBF022CD785E01E7B6FB7E1A040667DB7B3D40684BEF581DDD6B7895E8EC553 +Result = VERIFY_ERROR + +# --- ML-DSA-65-RSA4096-PKCS15-SHA512 --- +PublicKeyRaw = COMP_ML_DSA_65_RSA4096_PKCS15_SHA512:ML-DSA-65-RSA4096-PKCS15-SHA512:F1B9E9575C48F9DB5F66B88FF6A7B70995B63BDF95F3C0B02C11B603233473FB0E8DBC73CDD7C9CC046B6A813061EA06467C5BAE5100D1A456A5E8CF3619E866E1C563F4C122E6B133853691E918909FD6D7B87A6F29A232945629DC24D14BF9FCDEABF0B8658C1F052FFDCD193EC09FC69979BA3C3061AC287EE33DD6EF915A496B8BD1C11F57D511571BE73EAB3653E92F3083ECF5EBD54AE61659ABA68D6BE46A27610E21BD9CB544EADFA8CEA74D71AE5B2491AFFC33D453B9B26D47A1907978B0DD5076878022E4668709469F25FDA4B1C8085F3D773D8C75ADC4AFB0DEEBEE63B5381DB256B44E967FF5A8DF14A03928F770F6CEE7FDF0BA0E0547F18F6426950124A62B9D0053B870FE991369583E5AB7326F922CE3648D54311CC1AE0F54D64D0C7CA9839FAA3294B632ECBFDDFDBF719F78756579BF021C2DDD90D00896446B5866C622A4470AE88A878C9F869D2D69C67072D5CF763BDBA4E358AB28E2A2BF7E84C1D699A2FE6FF6F877F84ABD4539D49F69411690D7FC8B342140EDDC31CB4998EB953C3CAA90E93C39B459AC4CA487BCD37BE09D28B94509CD48E7FF05ADE85155C83359A488BAF8B679859C5132A7160B7705B5BBE558582ADD600BB199DEF2BEBC23C5A59946C67E8D4A75FC1F4A4304421492A76BE0E2F9BE6234CEF9C201827E63F9175DCA7423FF382EC65DC80F297465A2D0A4E56CA7046CDACB7459BA26D88DFC18C432D4C31BE7B552D8769468D466ECD9E5BED343546866EF849343884494C89F95D635C15136195D406BC653FD79A4A8EA82F4CB3CB2117CA4366FD01E02B2EB61A8F40153F4C9D7815CF9A47B9CFFB2A394B5D7857B8C97111461000ABE3C5CD1C8D8255C7C6B9F5A9574EF4C1946471BC639695E72446631DA28A5EEFDB8E54F1AD7C4DA77CAFA66D8B4B05B83CA6D4A9C519EF4A2037E54E7A94431458E7412B9D4BDF9E4CC6B7FE6F62699C7F503DA365A87079FC8B74A55AFF99BE786F3112C150842BDB43464A6AAF240CAE72B4B6D07C354911854C21759B3ABFDDE7874E0286FF4740F615D84BFCB6FC86E1C7DBC20E6C25DA86E693910CBD7C5F8C3A152F9316E5A22E892F78F5D993D3A2EEA4F6EC37DE4F58A16C9841D7D99B4D9D08E99BD838DCB505A26095A6CA0CAAF966A98849A3A2A0D5F85FDBF9BE6E46CB37B8828A28EEA1DE9522C5B6BCEE40B31618FF3CCCDCC358D92542E95C73C8A616D3AB79F2A68B85ABDA265C537658DB0E4307DBF8EA77CBC89ADAA8DAD5DAE51C0A117D4617550D5EF02F652693F59EA2E9294DA5E76775D98C9E35AEEF7C9BC8981C80E7DE06BB6F2CC6AD37DD6E4F22DBA871E8117BE02983BEC992B7CB94549CE10A21ADCEB6B3DE2E1B2FF5147D0D9CEFAAA39742F35A4A9C4CE6A2EB8D69DE510AC8DD41488BA90ECC2C53E9C25C8340DF371298716692A40E65C7BE574F2FC166DD9A36BDD2D02FBC8E5FFF0E94655401141E0F7CA996DE81C2AB92FD1088827E5A91848A7E05C0228933FE1A1CE96591C4DB9775CB8FE2322AC572A031281012AA3E36E8A7AA0DB1BB4A3A10DE4E547EBDBCD90485166FE51219B6442E78DB6D23AA95AB07CF81BC540C61654F73BBD45489D01049C306F7DBBF764DB8DCA3CF7DF95C10065428DF62F78DD0F26816CD91377D3F8B60EA73999E858FD247A4DD4CCAE665EA3DEEA5AFE5878E9D2000716C84CFDA8CD3F84DE7ADFA1FFB8378BD81CC1B93F7BD957D2B5AA605DB549A021DD5D5D8ADEDBFC7CCA9F30CE0654DC00BEE10E3255B5614B0838247108E4C82B03CD97A4B04F95CBC3879A8A42866A28BCB6204AB0ED26A88CC5BF463BC928CB7AD952314DC097BB91025E7456FABECC899229827D0CA68F573427E3620FAA767CBC65A3F0F0473676099111D5D3747C1AD3174A82DFAB18EE1E14CC963069975DD11CD13B061AE3317DA5B4613AC3EEE25BABE240A9D6A3504CAD1636629AE1DF510BE366D855575AF665C082B469B6A9E457EEC8232C7A2CDEAE54AF738F6C780FE10DFA64D570C679462CDBDF3B7C5366ABE9A049B00FDC53A203C9FCCC7D2307E65217D996FB7C93DEC2B6E922910854810CD35707920FBA032E581CEE1F63B5E4091917D189661976D6CEF6BE93B619D45843EF872D24984D3BCECA170CDDFBC25DA323BA73C1FC9118B7C2A47C14B557083F778C83F02526D44BEFF0DDACE98BF7BE246961923C0B8DB0A4653A3474474AA9ECEF4560D1AC38D6D0B1CE42DD44F58A5AE37628405155AEDCCDD06AFFE4FDB0192298092C4B5586486403D63BEF8FBC81ECE29AA0E4114DCB16DFC1B90AEAF7C3F0A063A80F1AB80376A449AD8A718D3B3445D0B0BE780513BFF81361E12CD1CC2EFA710100149DDF925D95C4B34A5C294EB19E6F8FFEA42592D536262C4DBC9BCC6C2EAAC88CE3504F8441757854896DE06325C3A72A0E8CEEE054FD5CC8DAFE1426A6A6FE820503DA67F7BC01FD1483897E2842F3EC1857BF67D1576E2E475F6FE67065F91A59A4AE525D3B517760C3B45F20C8FC29FCFBD5C941A3FAE1398838EE9DE265160D7865F05AF895645C371967062274B83616EC53181EA0B3434CFB1964500F1A607DDBF78A2C83C9BE3AF2FB6CABB72D491A1DA300726CAB02DE7F3AFE62D2C1969FB475C6B7B5A448B29A4BADB9F5C2C78C9A1F8082686F4CAFAADA219181AFA1FB5451420A8F37D66D15AC5437B53D0B9532953D8209B18CF419E251BECC84B00390193082020A0282020100B5862E597195EA861A86885D21EE5E26443B07ADD4E8EE1813388BAEA8CACB21A608A6E082EC760358AB79AFB3D0F3D610F9D8F6AB3ECA447423DAB9633646C133E9F31A4FA01D30B925B9D48F23982ECB9555F716C18BAF190A8BD31498882DCBFCB173A097DFC6ADEA1B6B54122D9A6ED38BDF9894B20CB46BA41C3D24DD052DC9C3BE1C33C3E50D2C8BF8EB04955DE07C0ABF173A7D1EB5BDEC38BD2EA14023B520003B00C012479292C30E7B5128FF912B78E5BEBCF5E5939B1DAC04CF2216F142296620D2B809B432E3D96BD12629C828016B3D3F4FADE6050C85801043BE19D665A2753F22380954930A6B6E11677D7047533CF4C4A4FF49F53CA4B93A6E4D14655418BE05428F924E4D83D59E9B5F3054A02660AD51773E12BB35A445CC46602B2A07654181CE815A472867D4A14A67BB1CFDC44804D92CF7786D82DC05F6C855726C207288288996CA322A462F7E199265407968826B7EE6665156DD0EE580AA1F96B409372D034AEBE789CFF4077C2469DD36B4EF4082F6F42AE573C9596210477707154058F6ACD0A69D14B9A93BD388177C0DF2BF2D4E12662285ECD2B2AF78DE54AB8C8FD130CAD46BD85A5322AF4698293CB37559F46487E6BE51BED079E70598AAAEF88C129A3D5BD74240808DDE4926E084401EDB145A06F0132C6D84D5894BDFA699F8B3578B10C7AD5948145CE90682923081DE731521230203010001 + +# valid signature +Verify-Message-Public = ML-DSA-65-RSA4096-PKCS15-SHA512:COMP_ML_DSA_65_RSA4096_PKCS15_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = CADB0E5E77EAA1C9570F441CC782D86EADFD39560F2ABD16F7BD1EEB06FDF4FBA3F46940F802154DED30044E3A1745436953A69CC800020F1E22A62F325B7E75268CA98E907E121AC6FABFEFFF4D977248091E2153717D1BF7E7A013EE43EDEF46660C2D8BB0D57203675F2A5E15C9FF535964C4C170072022ACDAF3829119BFB16ED702FBFB66F96DA1FE19343175B290B65FD86A9BC4BD96301EDEC14EC43FA3622F7BBDC61F42901A85F08F55B653EBAB72E7CB6B4A38E07C73000348D9A5F599F7AF50857091310FBFA2171427164CAC07B5757CE9F9C8EAA2B5746358B8FA3E1B7A7FD92826896A8F157BA7CC45723991A2053F01CFC089872DDDD5C232A59022A2968775BB4D9F27F0ACDB361DFAFE1C33AC6124FCB484410544A18B17D7F091FBBA656507EF78220717A4CBC2462F3EBB3D404AC6325AB3BD3ADE5E72B3A39EF6BAAB3D6562C27F96507D902B0E5B740D92862F82A681FD6D398569C32581041C3ECC861654DD8AE45ED5F29BAEB4679329AD885392D01B7037C2CE73BE52CAEA1BEB06EA4BD48FAE84A6A836B37F33DD4FB47AF3D0A0181C2FA4B6692995EDF0BA80042F27AD0652E167A17A51B5B03FA3F505FFF34B95D0E8BBD17F986699F5F4963BA8AF7007D81B46B497D5F1E3E143656DCA342F553D153D8C7270486E416D23D7662188FD98022A2EDC4D2BF1395044FA533416B51FE55CF0940A6177839B08D4C7BA228BDC0E31027340888846A7371932C7BA31A56424B2907AB59DDE15048BB42CF87947F0147737A5E20E3401F8F62DDE119C310A0185F008045607200344B8B328B018EC4BE158D4C287E54A465E2CC8616816488C9B6298631741CED9FE23759F598C79440411F33EFB332D0B8CBAC41DFE5A46C3A585D9E9ED3213F00D013A523B2D23E42DE60DE9F0B24B77717E6EC1522834E6E4B46ABF71DF713923FCBF255C9E3521763603ED5A0F52BB988440107D481E085AEA7A8C5D1576664842ED68A7C05C907B23BCF11CBF3334A8D72E4FC1204CE46088656CC18E5EAC7ABC87DB09EB353D52FA3C7643FE2F5737496987C3BEC2C828E8243BE854D34E9C43D83F2BB93AE7D480D6BDA27B559C2BAC01B0E5E0B2FBCADDA499C8351EEC07E860E9C347DFE817861162E9A0A607C01DAAB595D0EBA5D186E94E4A44F0356F48737F1C89C73FF775A308A3390DC494479901E241CE7B0F673481BD817C5386D94412EA89C81B123E1016A27824C146EA9DCFF4B4E273E9DD6C8F0289B117FD500F9D9C9C84692A7CCE33CC683B2E02B958A0D93F72FF6AE91C4222F447E7D4BC0A7FE61999F1EC318533DAD7E26C4953B660CA16139C3A711E9EADCF99F6C45256498E2B82B1591E2F2471D505E74B60C36283DC5E43A12131F2AF5DF4E72FF42C1E9CC10F17BDF64B2333FE02DED1D9524122A339A6446EA1241E6DDB562607ECB4713FA65FDB1D72194F377C758CA74ED3F2C6F812525938D2FDFDB674CB2DF6ACA21B8C7A27625F2F540ED6582CFB8DEE240CA7F0A7E7B155750AC322489A2A279239AA97DCDDA349D1AF2F1A2F0D2C2B796A84532297BC347BBE3DEA8E7BDAD66E697CB8A700C37CE2C0AD0C5600006329B0817C5207F8E6A64A91594E9D700F9E0FDDF3257650152A80880B03E3FBEC32A0C29C3FA14A4A7043A8A7545221C2E432C0916767560ED709AE3362F3E76E31203A4639025F2A3E244E486D5A329B429CCF9C812199449497C969F7940D2B0AAE182CC545C417B707D4CD2471D34F0AA5C7AD11A779ABE33E096A7D135F04809D01694F70D110B5433AD99E08A982593AAED9943E8D7F67757BE4FE57E990FA5D99B286FA8931862404C463207E30A9BF636BAFE5D7A7DC7E813B67E0F2731203D1C2516140797425BD17E90F35E155FAD40D00875B3042EC019CFBC19C5103B55F57FEEF12405E48BBE74893042797EA8B1B0249D2B21EFBAA87EC56DBE63AA831533A88C7AD9B12D6E01DCAAA1DA14676608393998C4B2D53D0A5B53B106D5346A3288020C2819E2DE5365B2558996391A32574FF566A7D85FB9D4677DDCF06AA5EF42B6B4ACE1867EC9774C0A1899794978B9FF2770180F3C528EAA28AD61C9F8EA0ABDC18D60FA53F8BEEFDF9D59A16204BBBC98B74BC922C3064DC2EC6AB11F8CA2008961BADEEF5EF198FB01DCE6D3B36EB43FD6AD9BEB099A4C5C7C43B7F5D02A0D3341DF4B26A48CA55B59BA0F74E760E675F8372D64B23C656D02A94F626DC353C2CDE33FA511148656D18F1846FBECCA86C1DD9E664A7DEA702C4AF314F79F5FA990D32EDA7DB2CF7A8FD71B219CF525D2F26B2EBC13800118FD5B480B1AB6E06DCAC4313E0D65A9B30C24A6830232AB74B56DCC2DA62603C5E6CA8EB6165B29149DA92F6ED66DE7EFCA70A86551404695262076BFA4AA5953D2F2B32D7599A54A5E7756D83BED661B7E53E24A0E97DA3AA7318985551EF14DC8DD4AD0ED88AE92ACF82AFAD52D97D77E5DF64DF0842BF3344A00BD91EBBAEE81F9206048B204C283D13468D44748C171BEC2FAABEC5D397A5345EC9CE74072CE3EC17A7ACB39C43EDD09E633DB0793151C2A5E5A154D257C8F9B33DBB4FB82E1AE58A761D0809EB88EAAEFBDFDB74AAB45EF47CEDB56B5F3CDFB5FBD018C9594A26CDFD74BA6BDA97DE16F9BF14B3FFCB6F919798DF6A8052AB40F3260E25382247FA96F27E4F47FFFE86F28DDAF8763C1B76AE2E2A231E15A0B4A73857DD8EE3FB99377287BBF1A8FE25E1817C5712FE3D8CD161A03E471D90A73CF91DB3D40423D8D9C34F9CCAF0456FC172E85D2E70058976E96CED37994475C8048A622A21B12944B2E18ECD45893193C2A13DF8161FBF6161D4E4576520C9B10E04ED9BA885D04A05F3B2683C0ACCF1F04F491001D33E982A5EFAE0DE91E3F3409A48306EA317B45988281C7A2625C538C635AF3C3FB101DFD5D443FB3B1C49012AA039F4EC0732392AC7AEEB172148379C561FEECDCA47232B3AA395405B095F06B4BB9808D02A6D359F75C9CE4AC1D8948DF8064646AD3658C2E1EBB93A48C09145FF1219E436FF6ED52D20344DC203FBF03FCB42A7B97E11F7CFF39BE18C4F2E426045DE9198027C16EB2162E7F66230145B061BCA0097D038A1E760F7000AAE1E5AFC87A6BD29218FE456BB8359D29A7658C4CF5FC0A2F0F7B7A7E5FB9FF836FEC4B0B51B6FF8A49D0CE4EE162BE0FC62C93CF4EB01AE38DA657902E08D42AE73DC85215451B548247225BF68D1CB8F5D702DF46E40006F29AA94FE45C1373BC41893EF5E3C77CDF32FA1CDC65002167B68F514C84CC4FF83BA16E75B7D5684AB316D1DD88A3C3901DB31E4F3D3554D9A881657906F93A6403ABA05BCD08BD0980506EB3E4F0CD0FF3008B28E186FF634BBCF6B277A1579E58E5B93C174446D0A3E274B3612D1F3FDAEF6A7F6AEBFF62961BCB26F22FE371FE62EE08CFEC39E3CA42C76B685817D20E5230B26CF822F653B018682A22C3BADD87FACF00AA52D369A0475F73911C026F4CE6113E8F106216FC0E0EB0771308BD74AF1FB27B8D0F86B3B5C2B83D6FB5331EB8099C20E8A569CA120FBCA73D5B1E0E9B43ACEDF874DBBC090A2FEED0D7E31BCE11A18EF006C9D8B7EB1D2D7CC79C9621E9FE5E5949E4B58AC483DB47638EBC326DCFEA282A24113AEA5D66A5121B3A14D0530E2AF9B469417E2846F9174577184790950419E7A0745B6F6F5C59D2607C16A2D28EE34347B09487D4D1D49C077AEF3669490C94DD40195F880D790FC91F4CA11E99B408404E8CAFDB816407A14131AEE01BD4338FA464A33B75DDEE9B524D8CF8DFCE470ECE7494A59D3EFB7C9F73F2238CE6C82EF2CE15310DE0C5279F9F4EAAB10AE2241560A44EDA24A4E5669C76B79CF1B0DB691EA94FFAFC5C3A572C9FF7A42B203605A5272995A8CBC537E3AC1DF82081131E276D37E19D566EFEA03CCB56F6405BC8C0B7D90DA493140D24A80C38445EEB5F81CDE90E96CC86F24B1B691E4E1B30437C2A7A770EBA5623D62A5530CA4DBA231CC50B37C0CAEEC18E727967507D73101C76494F1CDEF3732F3F0CAFC0F252605EF797486F4F7B0267B33BA63EC54AAC2FBEFA62D76509C8B78F9171BBD7780EADF6DA027AB83DF7C9B44B68869E1BC69F65A5656ED8BD9858843164320CF99841965D95BC6B500D4C7B9FC38C3D247DC98D0BBA0DC9C29A593D19268648F0FE3A0A6CCF599AD7731D4717FE5996290D46AB9E92419873A1DF8A2D4C0A6B6F87E93D80F0250D53FAFF6A599BDA260F095CE5D8D109EDBF204048BD4BBABA0874205F894DD3533D3D997DFDD19F2BF48E96CF4AA99290AE2E0C83738F751D424FF886D0AD844590E7B636DFD6107B00D17EEBB5B724AD03DE7EF6C2B0E68A6A4FEEBF756C50BF55CCE8B07FA35E9B7EBC74083F3165077274010B7889307C1987DE12440B2A7FFABE4B3A7D222E82883C24FCE5993D43744B562E56233842539419FBFDAA7FC5783018F382FF05CDA322FD5E6E35B9937712EE937A439D927005AADB3D312BD433082A098D0B27BBDAC53DA3C6CC089190A59DB1DB1EF4CCD5CDDF173055807324E6E74829495C2D6E90C7D94A8B9E8FE1318307896FC696C9BB1DB346B86D6DA3A409CA5FC000000000000000000000000000000000B12181D2227A29C3BD0A4B6C76637B16B98B3B8A0321F7F032D5317290C264FD97DBCD47E28B96F277223721E0ED6982C358D5C8AADC86742FD2999BA1A6625BBA382A48F62B9D30745EB24DDAAFEEA66F7995DA3234DE0E0305646C31712A66D5753E4DC1D83FA727B3621B0E28C185BF599DC7FCDD32F84E1673DB0D3A6D3F99A927B1B7F9B2DA1FFB0741C59E13D461499FB8D23BE2FA640C2EC5937680C8624E845F150EBFFF6C8B64A5142B74B10E78F6CE2B5BA7C49FE9948DEF490AC64AD156244E024FA75CC22621D9F89033CE91D3D95709665714E989C1796A9474D9A97F4D729C467E9CFB57E0CF7C38A78F38B776C806D964E45A54D8739111A81AAF05CA9686A8455A3819627D87B3C020E67727665454F6FB94B9BE085783647035A5A8D405B081B029220BEA91452158BC621B6A38EEDB28538DB75168FB0FEDF81B008DAD8A3E37E5106E0959C8FE3C6BB980DE0B8B144878E401A0C5623ACDED0673D1783E19C81AB4D9D9141C185A169700EF59843759A8A1A6C4058A8670E43B42DF01C35D30A1E056A2DCC3A35894587123EF023DA0C5AE1C6C5B18DABDF2F2E407E047347A475BA77938543EB304AF85DD2B4FB0E2EEB3C076BBFB65966688DC4E355C628FEDDC6DD6A320BD5ABFB2C6006CF2D99E9984B3CCEEBC280F221621C8E9E828B14DFAF4D46B6A65BA6E83FBD0E9E9FD76EEAC5F22143539B5E1279F244 + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-65-RSA4096-PKCS15-SHA512:COMP_ML_DSA_65_RSA4096_PKCS15_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = CBDB0E5E77EAA1C9570F441CC782D86EADFD39560F2ABD16F7BD1EEB06FDF4FBA3F46940F802154DED30044E3A1745436953A69CC800020F1E22A62F325B7E75268CA98E907E121AC6FABFEFFF4D977248091E2153717D1BF7E7A013EE43EDEF46660C2D8BB0D57203675F2A5E15C9FF535964C4C170072022ACDAF3829119BFB16ED702FBFB66F96DA1FE19343175B290B65FD86A9BC4BD96301EDEC14EC43FA3622F7BBDC61F42901A85F08F55B653EBAB72E7CB6B4A38E07C73000348D9A5F599F7AF50857091310FBFA2171427164CAC07B5757CE9F9C8EAA2B5746358B8FA3E1B7A7FD92826896A8F157BA7CC45723991A2053F01CFC089872DDDD5C232A59022A2968775BB4D9F27F0ACDB361DFAFE1C33AC6124FCB484410544A18B17D7F091FBBA656507EF78220717A4CBC2462F3EBB3D404AC6325AB3BD3ADE5E72B3A39EF6BAAB3D6562C27F96507D902B0E5B740D92862F82A681FD6D398569C32581041C3ECC861654DD8AE45ED5F29BAEB4679329AD885392D01B7037C2CE73BE52CAEA1BEB06EA4BD48FAE84A6A836B37F33DD4FB47AF3D0A0181C2FA4B6692995EDF0BA80042F27AD0652E167A17A51B5B03FA3F505FFF34B95D0E8BBD17F986699F5F4963BA8AF7007D81B46B497D5F1E3E143656DCA342F553D153D8C7270486E416D23D7662188FD98022A2EDC4D2BF1395044FA533416B51FE55CF0940A6177839B08D4C7BA228BDC0E31027340888846A7371932C7BA31A56424B2907AB59DDE15048BB42CF87947F0147737A5E20E3401F8F62DDE119C310A0185F008045607200344B8B328B018EC4BE158D4C287E54A465E2CC8616816488C9B6298631741CED9FE23759F598C79440411F33EFB332D0B8CBAC41DFE5A46C3A585D9E9ED3213F00D013A523B2D23E42DE60DE9F0B24B77717E6EC1522834E6E4B46ABF71DF713923FCBF255C9E3521763603ED5A0F52BB988440107D481E085AEA7A8C5D1576664842ED68A7C05C907B23BCF11CBF3334A8D72E4FC1204CE46088656CC18E5EAC7ABC87DB09EB353D52FA3C7643FE2F5737496987C3BEC2C828E8243BE854D34E9C43D83F2BB93AE7D480D6BDA27B559C2BAC01B0E5E0B2FBCADDA499C8351EEC07E860E9C347DFE817861162E9A0A607C01DAAB595D0EBA5D186E94E4A44F0356F48737F1C89C73FF775A308A3390DC494479901E241CE7B0F673481BD817C5386D94412EA89C81B123E1016A27824C146EA9DCFF4B4E273E9DD6C8F0289B117FD500F9D9C9C84692A7CCE33CC683B2E02B958A0D93F72FF6AE91C4222F447E7D4BC0A7FE61999F1EC318533DAD7E26C4953B660CA16139C3A711E9EADCF99F6C45256498E2B82B1591E2F2471D505E74B60C36283DC5E43A12131F2AF5DF4E72FF42C1E9CC10F17BDF64B2333FE02DED1D9524122A339A6446EA1241E6DDB562607ECB4713FA65FDB1D72194F377C758CA74ED3F2C6F812525938D2FDFDB674CB2DF6ACA21B8C7A27625F2F540ED6582CFB8DEE240CA7F0A7E7B155750AC322489A2A279239AA97DCDDA349D1AF2F1A2F0D2C2B796A84532297BC347BBE3DEA8E7BDAD66E697CB8A700C37CE2C0AD0C5600006329B0817C5207F8E6A64A91594E9D700F9E0FDDF3257650152A80880B03E3FBEC32A0C29C3FA14A4A7043A8A7545221C2E432C0916767560ED709AE3362F3E76E31203A4639025F2A3E244E486D5A329B429CCF9C812199449497C969F7940D2B0AAE182CC545C417B707D4CD2471D34F0AA5C7AD11A779ABE33E096A7D135F04809D01694F70D110B5433AD99E08A982593AAED9943E8D7F67757BE4FE57E990FA5D99B286FA8931862404C463207E30A9BF636BAFE5D7A7DC7E813B67E0F2731203D1C2516140797425BD17E90F35E155FAD40D00875B3042EC019CFBC19C5103B55F57FEEF12405E48BBE74893042797EA8B1B0249D2B21EFBAA87EC56DBE63AA831533A88C7AD9B12D6E01DCAAA1DA14676608393998C4B2D53D0A5B53B106D5346A3288020C2819E2DE5365B2558996391A32574FF566A7D85FB9D4677DDCF06AA5EF42B6B4ACE1867EC9774C0A1899794978B9FF2770180F3C528EAA28AD61C9F8EA0ABDC18D60FA53F8BEEFDF9D59A16204BBBC98B74BC922C3064DC2EC6AB11F8CA2008961BADEEF5EF198FB01DCE6D3B36EB43FD6AD9BEB099A4C5C7C43B7F5D02A0D3341DF4B26A48CA55B59BA0F74E760E675F8372D64B23C656D02A94F626DC353C2CDE33FA511148656D18F1846FBECCA86C1DD9E664A7DEA702C4AF314F79F5FA990D32EDA7DB2CF7A8FD71B219CF525D2F26B2EBC13800118FD5B480B1AB6E06DCAC4313E0D65A9B30C24A6830232AB74B56DCC2DA62603C5E6CA8EB6165B29149DA92F6ED66DE7EFCA70A86551404695262076BFA4AA5953D2F2B32D7599A54A5E7756D83BED661B7E53E24A0E97DA3AA7318985551EF14DC8DD4AD0ED88AE92ACF82AFAD52D97D77E5DF64DF0842BF3344A00BD91EBBAEE81F9206048B204C283D13468D44748C171BEC2FAABEC5D397A5345EC9CE74072CE3EC17A7ACB39C43EDD09E633DB0793151C2A5E5A154D257C8F9B33DBB4FB82E1AE58A761D0809EB88EAAEFBDFDB74AAB45EF47CEDB56B5F3CDFB5FBD018C9594A26CDFD74BA6BDA97DE16F9BF14B3FFCB6F919798DF6A8052AB40F3260E25382247FA96F27E4F47FFFE86F28DDAF8763C1B76AE2E2A231E15A0B4A73857DD8EE3FB99377287BBF1A8FE25E1817C5712FE3D8CD161A03E471D90A73CF91DB3D40423D8D9C34F9CCAF0456FC172E85D2E70058976E96CED37994475C8048A622A21B12944B2E18ECD45893193C2A13DF8161FBF6161D4E4576520C9B10E04ED9BA885D04A05F3B2683C0ACCF1F04F491001D33E982A5EFAE0DE91E3F3409A48306EA317B45988281C7A2625C538C635AF3C3FB101DFD5D443FB3B1C49012AA039F4EC0732392AC7AEEB172148379C561FEECDCA47232B3AA395405B095F06B4BB9808D02A6D359F75C9CE4AC1D8948DF8064646AD3658C2E1EBB93A48C09145FF1219E436FF6ED52D20344DC203FBF03FCB42A7B97E11F7CFF39BE18C4F2E426045DE9198027C16EB2162E7F66230145B061BCA0097D038A1E760F7000AAE1E5AFC87A6BD29218FE456BB8359D29A7658C4CF5FC0A2F0F7B7A7E5FB9FF836FEC4B0B51B6FF8A49D0CE4EE162BE0FC62C93CF4EB01AE38DA657902E08D42AE73DC85215451B548247225BF68D1CB8F5D702DF46E40006F29AA94FE45C1373BC41893EF5E3C77CDF32FA1CDC65002167B68F514C84CC4FF83BA16E75B7D5684AB316D1DD88A3C3901DB31E4F3D3554D9A881657906F93A6403ABA05BCD08BD0980506EB3E4F0CD0FF3008B28E186FF634BBCF6B277A1579E58E5B93C174446D0A3E274B3612D1F3FDAEF6A7F6AEBFF62961BCB26F22FE371FE62EE08CFEC39E3CA42C76B685817D20E5230B26CF822F653B018682A22C3BADD87FACF00AA52D369A0475F73911C026F4CE6113E8F106216FC0E0EB0771308BD74AF1FB27B8D0F86B3B5C2B83D6FB5331EB8099C20E8A569CA120FBCA73D5B1E0E9B43ACEDF874DBBC090A2FEED0D7E31BCE11A18EF006C9D8B7EB1D2D7CC79C9621E9FE5E5949E4B58AC483DB47638EBC326DCFEA282A24113AEA5D66A5121B3A14D0530E2AF9B469417E2846F9174577184790950419E7A0745B6F6F5C59D2607C16A2D28EE34347B09487D4D1D49C077AEF3669490C94DD40195F880D790FC91F4CA11E99B408404E8CAFDB816407A14131AEE01BD4338FA464A33B75DDEE9B524D8CF8DFCE470ECE7494A59D3EFB7C9F73F2238CE6C82EF2CE15310DE0C5279F9F4EAAB10AE2241560A44EDA24A4E5669C76B79CF1B0DB691EA94FFAFC5C3A572C9FF7A42B203605A5272995A8CBC537E3AC1DF82081131E276D37E19D566EFEA03CCB56F6405BC8C0B7D90DA493140D24A80C38445EEB5F81CDE90E96CC86F24B1B691E4E1B30437C2A7A770EBA5623D62A5530CA4DBA231CC50B37C0CAEEC18E727967507D73101C76494F1CDEF3732F3F0CAFC0F252605EF797486F4F7B0267B33BA63EC54AAC2FBEFA62D76509C8B78F9171BBD7780EADF6DA027AB83DF7C9B44B68869E1BC69F65A5656ED8BD9858843164320CF99841965D95BC6B500D4C7B9FC38C3D247DC98D0BBA0DC9C29A593D19268648F0FE3A0A6CCF599AD7731D4717FE5996290D46AB9E92419873A1DF8A2D4C0A6B6F87E93D80F0250D53FAFF6A599BDA260F095CE5D8D109EDBF204048BD4BBABA0874205F894DD3533D3D997DFDD19F2BF48E96CF4AA99290AE2E0C83738F751D424FF886D0AD844590E7B636DFD6107B00D17EEBB5B724AD03DE7EF6C2B0E68A6A4FEEBF756C50BF55CCE8B07FA35E9B7EBC74083F3165077274010B7889307C1987DE12440B2A7FFABE4B3A7D222E82883C24FCE5993D43744B562E56233842539419FBFDAA7FC5783018F382FF05CDA322FD5E6E35B9937712EE937A439D927005AADB3D312BD433082A098D0B27BBDAC53DA3C6CC089190A59DB1DB1EF4CCD5CDDF173055807324E6E74829495C2D6E90C7D94A8B9E8FE1318307896FC696C9BB1DB346B86D6DA3A409CA5FC000000000000000000000000000000000B12181D2227A29C3BD0A4B6C76637B16B98B3B8A0321F7F032D5317290C264FD97DBCD47E28B96F277223721E0ED6982C358D5C8AADC86742FD2999BA1A6625BBA382A48F62B9D30745EB24DDAAFEEA66F7995DA3234DE0E0305646C31712A66D5753E4DC1D83FA727B3621B0E28C185BF599DC7FCDD32F84E1673DB0D3A6D3F99A927B1B7F9B2DA1FFB0741C59E13D461499FB8D23BE2FA640C2EC5937680C8624E845F150EBFFF6C8B64A5142B74B10E78F6CE2B5BA7C49FE9948DEF490AC64AD156244E024FA75CC22621D9F89033CE91D3D95709665714E989C1796A9474D9A97F4D729C467E9CFB57E0CF7C38A78F38B776C806D964E45A54D8739111A81AAF05CA9686A8455A3819627D87B3C020E67727665454F6FB94B9BE085783647035A5A8D405B081B029220BEA91452158BC621B6A38EEDB28538DB75168FB0FEDF81B008DAD8A3E37E5106E0959C8FE3C6BB980DE0B8B144878E401A0C5623ACDED0673D1783E19C81AB4D9D9141C185A169700EF59843759A8A1A6C4058A8670E43B42DF01C35D30A1E056A2DCC3A35894587123EF023DA0C5AE1C6C5B18DABDF2F2E407E047347A475BA77938543EB304AF85DD2B4FB0E2EEB3C076BBFB65966688DC4E355C628FEDDC6DD6A320BD5ABFB2C6006CF2D99E9984B3CCEEBC280F221621C8E9E828B14DFAF4D46B6A65BA6E83FBD0E9E9FD76EEAC5F22143539B5E1279F244 +Result = VERIFY_ERROR + +# --- ML-DSA-65-ECDSA-P256-SHA512 --- +PublicKeyRaw = COMP_ML_DSA_65_ECDSA_P256_SHA512:ML-DSA-65-ECDSA-P256-SHA512:AD94F20981495292C5D759BEF7FAA40BBF030157336926E10DD12095772F14160627D4545486727FAC72D58C3D43AD9D20CC23627DB00F8A7E1DEA2707CF1C04498177FB0564F5BA2DB2BF6116A9E2CE4C948B44BDC4399363921249E3295C06CA414369382B4B982CE62E424B27DD0AB827E5AF3361C56F4CFF91E0A783A6E11DD66E2CE624222DADC0B7307682E53613C28C4445A98FEC56C75D38A592820689867A9175DCC7B646AE6A37B37E6E139FE92412F1634876F9D3A2D118064C6CA412914BCCD94885817031FC72F129422CEB47499D93CB63ACA450149E5DDEC01D7EE5B151310A6BA304789D658F5233A84E5339B39EC29A2D54263913D8313142DF4D44AE6A547A3E04ABE98353F227CA3CA1EA3D62B4B4385A1279C271D880CF4640D217AEACE7A6C9EED1CE3CB03C182AD15048356D8C436268CCA188CBDF0D94192D94B4F0023D3A3ECBB8E688216D4E690C4C167CEF3D9674837D991825F6A0A2B18275EE78912A66526E524932583D0927615F5502F0E600B7D88E60B17E94C8FE1F1B7955888B19CB1D87260E8C274A9FCA8E109366A9A4C171EB1C5B296C90A1E8FDC283E3939E0150BBECF23F72B7813862FD5AEEC59B7A7846C695841E18423A59802C4B3D5EF92499C0E1179EB42190B751E35F67659AC65785D598E5BAE406A9D02F1A3B05777AF9F1688CE61D0D0DCE37203FAD97020911DD2BF6D99282511B81545F90BC062334D212956DB1D3292A9507B7EDF38D019035097FE6D093FC0072422708F37E8D6AD7BE2AFFE2B03A9A48815020249B68F77AD43A4612DC36244C4CAA0CDC51997770498ED0CB8083A9179B7D3A22AD00B62545ED0A9C1DD94DD3E9288E56334737BB405F91DA8FC76C75039A05DFD8EBC3A81F733332ABACAF0F85436D52A98AB14542F4BA1904DA04BB37DA4BDCC132CF21CB76B332AD651B7DA0A1FD1513B6A5A15E627267D4E2F844EA677EFAD5014C8A9EF78805BAE020A4BAA14CE74B23AD34BCD3CA66E03A55A7B38B30F0922410B43581975F76660EA0DE3B3CAAB36FA56B787E9C35BF0455C8A1CE275FC2B571AE81EC9EFF3BBDC063B6D9E595EFBEB6BA8A446AA45E2BD3255604C5D4C023B7B1BA7D6E5D1F33835C1A736D74A6044DA788C65387ED44C363302C4CF98B28B1F06BB82A783FC85BDFBFA6873D2F52D902232A0058A6A20A19EFE1C98B10D579080398C0CDBDEB47CA70F2A29966F35DA784D1A0B89B710D7592E63F3D21C74FB1F62716D7D55E83520343FD6F6B4F7DEF46ADD764E17D40070B8EFEB9C951CD059A6E7A83DBA82399EDF2CDECD5F2414F1EBA55D5CBE8A0E5029205D58D7B19D93A23DE46B36517EE243FC4FFF74922A84EC51F7AAFE1FE61E665C73535F97195A17A28DF52B5018FF9428245F7305B1F6365308DE18AA976BD2229E347F1882126C536E8A454A558E9B768D16A77C6D7552247EE928E7A922BC0F6C2747EFD292759EA2CBF819CC65618586867B6680CD5F542D0278C794B61CE06F9B4556E6EAE4EB0ED79ACB5742AE82044B0E5E5758F4712E3378B75F7CB754E5EBA4C99038EA77CA891ED1C76B571937497D9DCDCA3FC32B44881FFF1FE14A4C62FA9CF91C72D8BFB2EC27E43BC8180B3A7CFCD440D747FB7DB553FF47AA11E94297B436A32B04537701647B7A3C32628AFBEAA607B01E8DE5AB73EBC407904E8DD0C345CFBFE054C878B091AE13B83EB85204E934109A0517B70ACE5890E917BFC8BF55F82D37489FB8F10FE6EF9BAB6053D4A1FE472C8227AC28DFB808474483093A485F9018BF97B3175C8795F259A6ED1B67F590AD8DA3FEB05C46B793B9B1B561A5952B835AD65F7A173148420D1350A32FE91F92BC2662B6BE59452A22230A750CC44987E63BF123A575A11C7E414697C85BB973E20EB83B293F7E5E845974E745805769D8B89E683C445B7FB43AED71506AB897626055E0960E16B878BA7448BE0D7BB7C15E4A26D0D4C39B8E3A9B568641FAC269AF0C93C7AA3571FB404881E541602BCC3E9CC5068D9A74C50E466630ABE9C66A27DA3D12197117452BA69F75A99246FD3CF52281ACA78E7BDBEB8DC1C55CBF4C737DEA2A7885644718E7500481AC49B73FE61A7604A093EE112D2E541934C2334741EC41AC9AAE5A6BC7ED17CEEA2E3EA43A46E7692A75CBA9AFAB4FD2389213F90350F15837A31FCD978BF7A300D762F65A09BFFAD33D1ABB46BFA2BBFC28FA37FE3A270567C6D956BF7D8A0BEC063603C5A887A9C5B73F771889A2CB153C009F395921DB90925991370E06D96771479F14D9A7EA7894E2383AFB8F6E7777F352B0BF9368549BEE25893ED96B19A90DF6ED38B0310E440FBD4DD44F3190EEBCFDF683AC09A449861C6B62B33BB019D47284B5C6D7708E924A1AB9F5FE97C113EBB213A29476591702E3EC1FE54954FB2677DCD7A1FCF6E688E86682465F3A0FAC6F654D9AA8C0153BCED83FFF383D7D53CE88D1DFA295DE3AA005747F1C2A9EE07DD29964F4C26F1EC775FEEA237CBEA6648945E8A9EC455EAAA0DEEB1F9340BBEDDC4D7E4A8E3ED369337F1F75B7A2A79FB0CE1F6CA9D734EB904830650CD4E56BB676AA8ACD49A943DB74766CC4C112439EECDEA283F1E3B414E2D9FBF94D0588954EA92C03ECC00639C9626D6B545D565F57732B038E590454C1A316F061A431E3E1A16BC6A1EC51D3A5AB9AC6853F35B3E4AD32554D25B4ED2D0D734087824A3C4CFB7CACD7C51B66E69E40498824439F3DA0225096AFE049E8E6DB7273C7BE13CFA1DFB1DAEFB7DAD843EE35AEE5BF9E27EFA148821F220442CB49A665326A465A8B806AB58C6FAD546B496 + +# valid signature +Verify-Message-Public = ML-DSA-65-ECDSA-P256-SHA512:COMP_ML_DSA_65_ECDSA_P256_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 6767174A6C9E63E2C1EAC618DDF3CA6118E18AC6DDAE33D7A5D5A76CBA41F6F0B2A8D9C70EF39ADBF80BF85A46723E94FE30A68FE49F20D90044CF6AD7DA1BFC03BDFF3C2DE2D197D2BA0AD4D6B87FBB554925C5D196B1E4EB2C048422CC2AC94A295AC386033DD044BF57D50708596E0EA701B9E75E4A3D4496FA280958E370064BA9DDD0B78C4E3887D98F9430EF97776603CC79393DD0250E1C5A8398BD618FE83BE9B13EB6047352A17FF0110C9262BD1819A92FC3B1D281FA7E9AE058A1A592DA58D8ABAC84210288CCD88BFB60B9BE0E2AD0E286E121BC28F71B7BEF99D8195970B0AF8BDBE878B9789D6100A1540F2E177495127643976C6EDA1251936E20B89B04DD8EF8808290BC825384F6F005C3DC15D0255A31A0BEDD0CDE54E988D6F60651144FE0A0899646F1E0B1C038610CF5E8EEF050E8CEB4E5C7D2269CDCE655666D779DF6C848198878C6BFEA15E66BA71AB4D474BA1C808C6384E00C044B2212A3D88B09C2CBC886D0E43F1EB8086891C21D4334C71C804478515665D7C0DEF150E57717394327017BF646F49E88BC1BAC3AA4BC6854FF9FEEB16333DEEBC5CAFB6464DE9A700B7DF274390DEAB4E424D7DC09D328FE55079A9B69CA79125A8DF4433D6F8C494265E4B6B67E8740E8BAF35541D7F200C62BFE5224010523E6AA5731B16D69C35E82ED5CE92D932E2FA9DFB20B49AE3BF099D89B06FBEA3D18C7D36EF238F4A20F5EE9A375A404910CD2A97BBC089CE59D88714A28FD2FF03A562EB5BEACA0486958498FEBA63F8AB7600B06D3D4076F8D38D1C4D415EA11568F99C93247E15826DD002A91A4F629410527F67E8555B713C9DC2BFD16DE0F2CA64EEDAE55CCBC451AB758CCF55543E32E1101B283C12A7C555A6CDE1366E8F46F04AAC53AE7A805A425249BEAAA18224015C08325397720B26C801E663FA6FA780BE75DEB99D57E7513E512EDC44F6C9B53113B062BB814072033CAB2B2B86C97FDE5CC9E3234A246D205443407B276E6EE36B05B34B95B149683CF49043E8CCA0F3B815888E3757932A88A4D6DE14E3C2633F73A24C40EE3C2606C0D6A29B39F412394227429A5729A48615BDEB7389875A1D5B17935D8DF7A48EB309DB0BDBCB097C7071D84F85F61BE11ABAB6346D235675714278DB78F687897B0A4D3D6E959646B438A4E3345335072043006FCBF1986ABB250EF84A833EB84C6A2C939021C579D4807CBE0BBB692847CACFB1BFCD68F60B8F3D38339D1626F5C452627BBDC9F830A62199CCE36F0A29E0261D94DFAA04ACEF0D36817EFEFD49AB6543CBDAE22CA826A5E08A2F9B3DFD39CEF76C6D13EBB80F040AF24DD97F935E7D482613CAF829EBB38B5292938D9FA67BAA7F83593C09A729F295718418D1A6F5F70FED5E26CC0EA719B950A5D21BEC5DFCA74D3F473FD87A53308C3D6797CFC4374EC16B5CAEB9124D1712E6FF03B3B5D6174A9C8142ABA22B3C4AADDCAA645431D0682375CDC76BF9054B5EB208FC576F5B449C9BA4BD0990098A8DE50FA0CF479810589DEAC85114A3EEA322F783CAF8BB259F8F218F0086FC914ECBBFDC75273447DB400FE0D222B41C41E080BE4E34874C1E7D7143DC81A4F03C91A483FAF960952E5BAD53DF4A5E411979AAE0CF6E293CA3CAE080C45643FF16A22A369875BD3B2666979FE3128309687B7E0326CCF3EB139D64FD4E94847282FCF693982879F3E5FBA063B2736738FA2D8B8B9816AAA3AE2F850F6AC399885EE996CBB7F960CBDA8518E6E917D5CF206DFF33608598BA5D68BC128CF5C01C193576082E988A5B5E4BC345351EB73B731B51745BF3B54BE1D5AC5E6FAB318F4334A8F9AC4794288395B203C8058CE28EBF5696FD8BFB30B145F562DE1164CB64467F2973B3B5DF4F810F49156EAEE3FDA8183C64FD81B5F4232EA98EBA437C0643EBA76DC46DAF011CFC077263627B435BD3FA141C03E0C0F65AB85C3C100A1BDF0AA81B4EF32C5FF9575E9387970D84A6BC789CEB71D51D1040BDC16AF07191CDFEC77DA846AA083EB3644B1C815F4B6B4DA4A078C666585B7B7E7933311F4E9BD676018F600D5882449E62359B31CD2B9B1C9762F4EAE5AAC6A6191FD58C93E6CF3104D53F5755A23E3305D917D6FE87E1D8076CACF168AAACB8488656BDD28B53258B466E4AA8ACA2BDCE0B099F938DE59FBE2238418C0D77B8B35B4C1926A347FC2F5E4CBD87E14B1B90D7E875E2438003E860AACE5B92586D6F9C979AC01BA43FEFABB505031E3C9BAB787AE33A18050F538520BBB198D78BD88326DDE36A45D81AFE4DDD10DA80110D872EBB81D427E95A3485EFF2E7BCEA683AA1E34DD544584FBB8FA3E006760CC316C5B9D18C3A742DDBB9AA16BA2BF14B8F6FEB992522500855E427E8A13C25D31B5236EFEFB3A8265548E6DE1CAA400B9AAB6EB42758B9C2B892AA8E34973FFC075867CEADA0B0E98A4AEEC844F808404B09F0D7D63172FBD055DA594A6BD876011EC1624F611315CBCCAABFF31DDE88AC979FDACDBE547E07792B59372725B6E2AA077A905A8BE6A4EEB3DC012D9A87D9BFD9AC61D3B5C89DC7ADF6AB042D294D6C0527E012A3C79270CF6A63EF9BF13A674F555925454055FF16A2C4A1499533376147B805A651EE5AE6BA6A1948E4F329A92C2BF6F260F58CBB7BEDD4456E25EF49357BC94F3A3460EFE79A96CE2EB2E6045246BBBB433669B4CBD9659DF57C09BADC17FFEC2E4CEF921E95F277EEB174027645A0CFBA1CE94943E7AC9A9BA4D7F787457614FBB86B3F7032B9E81B269B098FFBB7EFCBB5DF8752766D534F8AB8E5FA9BC38E22D53C8FF59A11968D24FFC1BA6595B71C9F41234B1B8CEB3F6B529E2A85788A61BFE651D1FADCD3DA42562643A563C5568B9782C9D9105D8B776BBC9E738145D4890D68ACB0FFF07EF9ADE61309EB6F5147B4D5B8F0A6192B96993E1138CB3BB9426EC50A9436D609CED3ED3CADC4833F54C0FF63C1F49DF0E1317F021F0C85CB5AF31F0C229CEF8660418302A76A7B8C776A15D617040E0765363C22124840AF9673D2E4FCEB9C49F08C3C71A2021AF872BF5820FE528464943F034286088BE266A57F8E1926233D272DAC0357CF01A27E97C647958A34E9866BA54482F67110C3F886E0160057D6B47966E2580B844FB49CB05046A92E69BD9FC5071133B57C4311B7A13B25B3D32992AB4FD1B4189C4A9432952C3DDD452368F699D1D0A046E7D1BFF3905CE233F0629846B09CD78A0AD62DDB4FE615298241AC997B2C179E75C55207EE196E84A9B725A02F1412F261261BA99A449E474CA7F6660244225130162348EA15C96DA2042EDA37843979680BD3C21CF8DC17C2578382CDDA820826B5B3E6102C4E1DB42F92B7BC0CA439DA30C1352107A68173251CC21B3651F7ED58C8384BEA3425C710BD0C917EE941E9ADC8B5C294A90FC5B0786A73C1F673D2DD877DB768DC36B49CAACC5FB7389A2859EB6FA7BF5B67397D2DB6601519F1AAEE0CF3228E9C5C456560C0019855B01E504FC7836E7D1EBD82398A591518A04A0BF25777B798A28880577A93577705F6B25D20A781E1EFC1DC12809955A64404BBF169BEABA1226E2B9BBF78FF0A6938D91F8499182903617C30E93E2E0E089EDE517E441AEECC369BF376580E109E606AF7C262D8AC6C5FFB03BE4704D0AC478BCAAFD93A83E0A441A58027CB4DB3F22B4A3F4DB098ED8C0384D12D4CF5CEF768D33569A8919C2243C93AB6B66D845AADFC450990E08C30E6CE337C8EC9078DBBBC6FC73198EC07E65BB9320868BED478DF9870CE703455E0AF3F3B0A7619BA4300D027DCE81EE6614F4BAA99608B21CEDF95E5F739C0AE5254F60EF94E90D60858F4F10A3B47CDF6753A06FCC1B4DA5B03E932B65841AF436920E896CFA13E913A86B20940A3C3DD3A5CE51E3D5432AF5D207FE7E86FBDEAA7C1A02047E0CF7B50E7EBDFCD32471822A76364DF9E7B73C1F696A8BE8630482A03F15062EC7B82C0760C64F512E7C94EE90CB93452F2207D9668A41D506BAB19CEDDA76EE01800464C9036E894CA44DB7E2BAEEE4C804DAE843090742943DDC089830CD2AF76EDDBE2180A5DDDC307C32A9F8EADF40B42CEB0A842F86115751056A7F46AC8CAF930A6BFAE152F536A1B338E4D26D9BC3D4BAF954AF6ED0970B3E16A35C01DF48E5F341D66E096D619450DB8780D95BB85157CDE232AF626ED60F6D7902DEAC2BC93453CF7DFAEF766982E5150478D64C6A1B863D019EF0AAFD30BB482A16522668BEE3A6A794E6E30ED93CB5F9327560A260EF13D727A48939B220AF7C41D20A9F5DC00006654E2812C89783E2EDCF5CB86A1691EF17CDAED82539924D8637332BD04E9AE8B12EB67C8710D3D76FD69E2ED799A38A60D8C9C2A8D4770DED441D45D7D98830162E880A76F097497FB7FF7424F2C1B828A83CF1DD9F198C0F2977D490CBE3C1E23D92310D91A87A6420A7862B7E7F9EB3B3D3BC6C7E02BD3462C78C31E74211F83E369F954ECBA114276710CF08A51C730E7A1796503E20B7F7D2976393F89050236E0A845E9C238948C965141DC6143A28F6B9CB19B7712AC6ECF2333F5EADB0CAEC101720415E81B1B4B5D6E3E6EE21282AA9AEC90D26485E727FED1F292C2F8495E20000000000000000000000040B181E252C3045022100E30C60900AC01C923A9A29FD56E9ADDDE9BF9C5593C607D0D6189E76E891D59402206E4E966DC46593BD60F5ACB47239E7579ED20FD8E516E19ED4B97437F83AA120 + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-65-ECDSA-P256-SHA512:COMP_ML_DSA_65_ECDSA_P256_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 6667174A6C9E63E2C1EAC618DDF3CA6118E18AC6DDAE33D7A5D5A76CBA41F6F0B2A8D9C70EF39ADBF80BF85A46723E94FE30A68FE49F20D90044CF6AD7DA1BFC03BDFF3C2DE2D197D2BA0AD4D6B87FBB554925C5D196B1E4EB2C048422CC2AC94A295AC386033DD044BF57D50708596E0EA701B9E75E4A3D4496FA280958E370064BA9DDD0B78C4E3887D98F9430EF97776603CC79393DD0250E1C5A8398BD618FE83BE9B13EB6047352A17FF0110C9262BD1819A92FC3B1D281FA7E9AE058A1A592DA58D8ABAC84210288CCD88BFB60B9BE0E2AD0E286E121BC28F71B7BEF99D8195970B0AF8BDBE878B9789D6100A1540F2E177495127643976C6EDA1251936E20B89B04DD8EF8808290BC825384F6F005C3DC15D0255A31A0BEDD0CDE54E988D6F60651144FE0A0899646F1E0B1C038610CF5E8EEF050E8CEB4E5C7D2269CDCE655666D779DF6C848198878C6BFEA15E66BA71AB4D474BA1C808C6384E00C044B2212A3D88B09C2CBC886D0E43F1EB8086891C21D4334C71C804478515665D7C0DEF150E57717394327017BF646F49E88BC1BAC3AA4BC6854FF9FEEB16333DEEBC5CAFB6464DE9A700B7DF274390DEAB4E424D7DC09D328FE55079A9B69CA79125A8DF4433D6F8C494265E4B6B67E8740E8BAF35541D7F200C62BFE5224010523E6AA5731B16D69C35E82ED5CE92D932E2FA9DFB20B49AE3BF099D89B06FBEA3D18C7D36EF238F4A20F5EE9A375A404910CD2A97BBC089CE59D88714A28FD2FF03A562EB5BEACA0486958498FEBA63F8AB7600B06D3D4076F8D38D1C4D415EA11568F99C93247E15826DD002A91A4F629410527F67E8555B713C9DC2BFD16DE0F2CA64EEDAE55CCBC451AB758CCF55543E32E1101B283C12A7C555A6CDE1366E8F46F04AAC53AE7A805A425249BEAAA18224015C08325397720B26C801E663FA6FA780BE75DEB99D57E7513E512EDC44F6C9B53113B062BB814072033CAB2B2B86C97FDE5CC9E3234A246D205443407B276E6EE36B05B34B95B149683CF49043E8CCA0F3B815888E3757932A88A4D6DE14E3C2633F73A24C40EE3C2606C0D6A29B39F412394227429A5729A48615BDEB7389875A1D5B17935D8DF7A48EB309DB0BDBCB097C7071D84F85F61BE11ABAB6346D235675714278DB78F687897B0A4D3D6E959646B438A4E3345335072043006FCBF1986ABB250EF84A833EB84C6A2C939021C579D4807CBE0BBB692847CACFB1BFCD68F60B8F3D38339D1626F5C452627BBDC9F830A62199CCE36F0A29E0261D94DFAA04ACEF0D36817EFEFD49AB6543CBDAE22CA826A5E08A2F9B3DFD39CEF76C6D13EBB80F040AF24DD97F935E7D482613CAF829EBB38B5292938D9FA67BAA7F83593C09A729F295718418D1A6F5F70FED5E26CC0EA719B950A5D21BEC5DFCA74D3F473FD87A53308C3D6797CFC4374EC16B5CAEB9124D1712E6FF03B3B5D6174A9C8142ABA22B3C4AADDCAA645431D0682375CDC76BF9054B5EB208FC576F5B449C9BA4BD0990098A8DE50FA0CF479810589DEAC85114A3EEA322F783CAF8BB259F8F218F0086FC914ECBBFDC75273447DB400FE0D222B41C41E080BE4E34874C1E7D7143DC81A4F03C91A483FAF960952E5BAD53DF4A5E411979AAE0CF6E293CA3CAE080C45643FF16A22A369875BD3B2666979FE3128309687B7E0326CCF3EB139D64FD4E94847282FCF693982879F3E5FBA063B2736738FA2D8B8B9816AAA3AE2F850F6AC399885EE996CBB7F960CBDA8518E6E917D5CF206DFF33608598BA5D68BC128CF5C01C193576082E988A5B5E4BC345351EB73B731B51745BF3B54BE1D5AC5E6FAB318F4334A8F9AC4794288395B203C8058CE28EBF5696FD8BFB30B145F562DE1164CB64467F2973B3B5DF4F810F49156EAEE3FDA8183C64FD81B5F4232EA98EBA437C0643EBA76DC46DAF011CFC077263627B435BD3FA141C03E0C0F65AB85C3C100A1BDF0AA81B4EF32C5FF9575E9387970D84A6BC789CEB71D51D1040BDC16AF07191CDFEC77DA846AA083EB3644B1C815F4B6B4DA4A078C666585B7B7E7933311F4E9BD676018F600D5882449E62359B31CD2B9B1C9762F4EAE5AAC6A6191FD58C93E6CF3104D53F5755A23E3305D917D6FE87E1D8076CACF168AAACB8488656BDD28B53258B466E4AA8ACA2BDCE0B099F938DE59FBE2238418C0D77B8B35B4C1926A347FC2F5E4CBD87E14B1B90D7E875E2438003E860AACE5B92586D6F9C979AC01BA43FEFABB505031E3C9BAB787AE33A18050F538520BBB198D78BD88326DDE36A45D81AFE4DDD10DA80110D872EBB81D427E95A3485EFF2E7BCEA683AA1E34DD544584FBB8FA3E006760CC316C5B9D18C3A742DDBB9AA16BA2BF14B8F6FEB992522500855E427E8A13C25D31B5236EFEFB3A8265548E6DE1CAA400B9AAB6EB42758B9C2B892AA8E34973FFC075867CEADA0B0E98A4AEEC844F808404B09F0D7D63172FBD055DA594A6BD876011EC1624F611315CBCCAABFF31DDE88AC979FDACDBE547E07792B59372725B6E2AA077A905A8BE6A4EEB3DC012D9A87D9BFD9AC61D3B5C89DC7ADF6AB042D294D6C0527E012A3C79270CF6A63EF9BF13A674F555925454055FF16A2C4A1499533376147B805A651EE5AE6BA6A1948E4F329A92C2BF6F260F58CBB7BEDD4456E25EF49357BC94F3A3460EFE79A96CE2EB2E6045246BBBB433669B4CBD9659DF57C09BADC17FFEC2E4CEF921E95F277EEB174027645A0CFBA1CE94943E7AC9A9BA4D7F787457614FBB86B3F7032B9E81B269B098FFBB7EFCBB5DF8752766D534F8AB8E5FA9BC38E22D53C8FF59A11968D24FFC1BA6595B71C9F41234B1B8CEB3F6B529E2A85788A61BFE651D1FADCD3DA42562643A563C5568B9782C9D9105D8B776BBC9E738145D4890D68ACB0FFF07EF9ADE61309EB6F5147B4D5B8F0A6192B96993E1138CB3BB9426EC50A9436D609CED3ED3CADC4833F54C0FF63C1F49DF0E1317F021F0C85CB5AF31F0C229CEF8660418302A76A7B8C776A15D617040E0765363C22124840AF9673D2E4FCEB9C49F08C3C71A2021AF872BF5820FE528464943F034286088BE266A57F8E1926233D272DAC0357CF01A27E97C647958A34E9866BA54482F67110C3F886E0160057D6B47966E2580B844FB49CB05046A92E69BD9FC5071133B57C4311B7A13B25B3D32992AB4FD1B4189C4A9432952C3DDD452368F699D1D0A046E7D1BFF3905CE233F0629846B09CD78A0AD62DDB4FE615298241AC997B2C179E75C55207EE196E84A9B725A02F1412F261261BA99A449E474CA7F6660244225130162348EA15C96DA2042EDA37843979680BD3C21CF8DC17C2578382CDDA820826B5B3E6102C4E1DB42F92B7BC0CA439DA30C1352107A68173251CC21B3651F7ED58C8384BEA3425C710BD0C917EE941E9ADC8B5C294A90FC5B0786A73C1F673D2DD877DB768DC36B49CAACC5FB7389A2859EB6FA7BF5B67397D2DB6601519F1AAEE0CF3228E9C5C456560C0019855B01E504FC7836E7D1EBD82398A591518A04A0BF25777B798A28880577A93577705F6B25D20A781E1EFC1DC12809955A64404BBF169BEABA1226E2B9BBF78FF0A6938D91F8499182903617C30E93E2E0E089EDE517E441AEECC369BF376580E109E606AF7C262D8AC6C5FFB03BE4704D0AC478BCAAFD93A83E0A441A58027CB4DB3F22B4A3F4DB098ED8C0384D12D4CF5CEF768D33569A8919C2243C93AB6B66D845AADFC450990E08C30E6CE337C8EC9078DBBBC6FC73198EC07E65BB9320868BED478DF9870CE703455E0AF3F3B0A7619BA4300D027DCE81EE6614F4BAA99608B21CEDF95E5F739C0AE5254F60EF94E90D60858F4F10A3B47CDF6753A06FCC1B4DA5B03E932B65841AF436920E896CFA13E913A86B20940A3C3DD3A5CE51E3D5432AF5D207FE7E86FBDEAA7C1A02047E0CF7B50E7EBDFCD32471822A76364DF9E7B73C1F696A8BE8630482A03F15062EC7B82C0760C64F512E7C94EE90CB93452F2207D9668A41D506BAB19CEDDA76EE01800464C9036E894CA44DB7E2BAEEE4C804DAE843090742943DDC089830CD2AF76EDDBE2180A5DDDC307C32A9F8EADF40B42CEB0A842F86115751056A7F46AC8CAF930A6BFAE152F536A1B338E4D26D9BC3D4BAF954AF6ED0970B3E16A35C01DF48E5F341D66E096D619450DB8780D95BB85157CDE232AF626ED60F6D7902DEAC2BC93453CF7DFAEF766982E5150478D64C6A1B863D019EF0AAFD30BB482A16522668BEE3A6A794E6E30ED93CB5F9327560A260EF13D727A48939B220AF7C41D20A9F5DC00006654E2812C89783E2EDCF5CB86A1691EF17CDAED82539924D8637332BD04E9AE8B12EB67C8710D3D76FD69E2ED799A38A60D8C9C2A8D4770DED441D45D7D98830162E880A76F097497FB7FF7424F2C1B828A83CF1DD9F198C0F2977D490CBE3C1E23D92310D91A87A6420A7862B7E7F9EB3B3D3BC6C7E02BD3462C78C31E74211F83E369F954ECBA114276710CF08A51C730E7A1796503E20B7F7D2976393F89050236E0A845E9C238948C965141DC6143A28F6B9CB19B7712AC6ECF2333F5EADB0CAEC101720415E81B1B4B5D6E3E6EE21282AA9AEC90D26485E727FED1F292C2F8495E20000000000000000000000040B181E252C3045022100E30C60900AC01C923A9A29FD56E9ADDDE9BF9C5593C607D0D6189E76E891D59402206E4E966DC46593BD60F5ACB47239E7579ED20FD8E516E19ED4B97437F83AA120 +Result = VERIFY_ERROR + +# --- ML-DSA-65-ECDSA-P384-SHA512 --- +PublicKeyRaw = COMP_ML_DSA_65_ECDSA_P384_SHA512:ML-DSA-65-ECDSA-P384-SHA512:B5D1B08CE906155049DA99BE0A94D8B36C1E0827D956A14925D0FB5E271EB23D59F9B9EEF9126B892AAB75EE62B4DC2312E3C4D76C26675F2A317CF2DE1FC8B2EA1D878CC2AFB8406DFDF811B10937C0BE9F5A955FA17DE5EB18928608ED1B42DE29A48F23B22A9522921436A41E961E283B24313CEB248C993C3374DAA4F2FCBD4AF7817FAF928CB77B1D699C636306B2B08684C2C77DCDF405879616ECF4F2241C82DE73C3CD20494F2ECB1B67AC475D61BF4690EA5272F1172B9B4738268018EC69E352577A970751EA1D08871695F1DF8EEA0A613069761BC59D1AF0A3744E6902890D996282BF4FEF0F66FAC3C01917AD93B306BEACCA2A60E2D681695C0E8DA2D0CAEE362F98787701F4FD043A5C9A72B41090670341FA875A0578C4B8054DB00E299F9CE31D88A7A743A56FA67426EBC28D5BD0799247AD1F3F2F30369FA5A7D04FE3FD2DF8CCCAD99124071A0D81E061114E523ADD5679052EA1B79BF887BFD6F260DD8C21DAFBB11D11CABDD49BCC2A5EEB38A0098A8C41EBBCEC7256272E10EE0B24C9465AB3120C290CF8EE04415F9B94D458923899BFA0FE0AB7BE40AF241BEA3ACC98F732EE778D9D3580ADA29741C684340B701CBAC9CE576B003C3346F7F7220B7C39ED0F2727DD4C5FA7FBA971E458F0277D217E74E1F3DA06F5F44793B909485ACDD4D96319DD60222F5ED1D4FC713B4F9CCA7E1B429605864D4403FB9D6E5FBE47E719E57ACDCD648C0C3BC3ABA7D46CF8E90444ADEB9C58E263EE44A8EDD5B93BC2D9F8BAB209D3F2E2F2BA7686506CF47AAC108A814EECFEB3A3C13527458ED2D0647E52EB621DBF1827259E0E1807720C9679ED0EF318F48164650FAD1ADA2DD62ECFDC765B1FCBE429A5A67024C7A648B859FE7DB694319B0DA6ECF90E134E06E1383A1E3FBEC01EFD474203E70CEA5B084976010367579F8ABE437049E8A82187601769A78377884EFADB696F238ECECD4FA0CE24CC7975BB0027BC568E2176EA40D51569322588B184F7559052A0A25FCBDD42E386D936D671C8E292074C865AFC5E738A9AC5F450A29C484B5EEA35F926FD3A7DD198D0DE73EB6A2560CEBBA0C80358D973CAA91ACC675A0DE31496641748D9548DDD0B1667284A78FA966D49D47356D639C7117CB0814E1255309CC381A773523423D532A73A3BFE7989884CA7DC8657207EE663F67B13C8F3507FAC091D73E3EBB8CF73A48B14BEE6D54B1F99E47888D5AC41914A5956D262A162533CDA13C553E98AFA9F20062621684767393DB80057A3E611E817BAD9993D6CE9DAAC22D41AD3EFCEFE467D0A750A7415F5006B49D1ACD6CA073952ACFC31FBABC1145CBFBE27A64838EA6C38DA82DBD21D95370AA2087FCD4495EA3C72711E685CD4616DA84B5BEA0B97AECC85356CF2F50547F16186732C6805B40A33CAA664ED2A4E6FB565A6F0219984D95F1B4AF01B8C8F6FF59751ADCD1FDE23ECA7869214D665F09318EBD75E25CFF2E42F12EFEE412B05E8281F52E8AD195BDAA9971BCC34909B1502E325EDCF57F727BD4AD71C77B709807B21A579A10E7548B9F12E9EC02DD675B819FA32DB6ABA631B249B5E9343B1B068A5CEE1F4B9D357A63798A551BEDE53F3AD136DAE4CE2D65533800704390DBBBE4D502DD8A3943ADFE3F548E88FE91394A9E5293BFA7411C85178E9D27836F2795788FC6A0F47CAC6C54D12BD69B3A5A48E2C4727C6B2C185FD5A349CDF85426605EB828066DE8382AAC193D97FA371EFDF62EF61881A3933BEE4050BCBFDBBE167A4EB35E9539AC49AA5B7F67A50787D011B185887FB1374EDC6204B144B740A6CAF0EF47BB780DBB63A46D900C2005180F1B3523D5B3E5FAF1D1A738487EBC84F2B809DC35D4FDB658A7AFF4E27FD16E65384883539390C7A3116B45E4B1FA1B16DD6299D1BA73BC638D441F8A4E206E8AE14B3482AACC1804984459B389EEB38C69353A2BD2D162B57F14C979BBF79388E3DA69FA358EF7DC7C95606C80F346AF5AA710898AE18C9DE6D030579E98329145AE3D88FB2688F1E9CF0C9179AEB0CE5765F7AAF1927BA4013A786F2B12370B026CC3D5DD23B3667E3978AB664B8781FFAA2BD3CF699B6BF39E322A6ED2FF7736E8261F5CC48B8A17A103DC2379CF7EFE2E337D58D681670AC842BB4316DF68BF83F8B05DD1A577C82ECD7B7115A1B54B2E66AEE73F5BB507CDC12BC00938BF83300B787D680837B2D656593646E23730042D35507AAF9FA8664E267BFEF38F6A44146259D31FEAD0585D9754B46EC786756366B7A30F7E3133D0E8CD3C24F1DF8C5DB797D89F13B860F5692AB4421E1EC5CFADCFD8EAC6B27D5D1B7BB4B389700DC37721199B514567F618E7D786A8DB10357CBD99BD12053A89E32C934D93FE72BA97C4EB0606DCDD7CEC9206686451DB5EC6949E9EEC27CDA0997C94B9FA26059E59178303DDC76280781334CDDC55FDA75A00ACE8740456757D02FF8FC292980FFC69222A31B85795083C5BD73EA7E99F641456FF442F1784FCB498ECBBF9B767749E4BCC9DE95F5E12DF9BDF1A5CFB7131E181DD80F14D542E236B7F2A07C398390F66E363112BE8649F731C1892556E4BFAEBB026C20992EED1344246D0D7B8276B81E18EA66EC05E74D7A03E96F23155D435DE1D8D15F7089B375A7C1447BFABCF4FD0DF73A693F5DB6E73D101AE5B6B51C51D93B29099ABD02387CD428820CDF3C06DFD5DBB799B9D6ADB18C7942BCDC2FDAFE0BDF669FA1043B99628699473AB2DA34A38E3761F514CE695C10FEABCD82443F6B326D7B92019CDD70393D86A12F1B8D97BC4FA936835C9EF3E43C864A9167FFAA9324ED0A0898BF31D4567AAC36F8EC1C62F577AEFE4969B2CE56DAEEB5E8DE5B8F31C1244A + +# valid signature +Verify-Message-Public = ML-DSA-65-ECDSA-P384-SHA512:COMP_ML_DSA_65_ECDSA_P384_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 87FD58C8184F842C7F6D65C3636EDC2CDE19448D4CAEEB32424DBBF7D618E5F4ADD4F1FBB172282001B6A5232D9BE9BBCAADD3B72F42CC38C68C78187DCAB2DAEE391BF974D8F413A4D14EB42CAF7DACBA0E4EC45D503C8028FC4E5DC926D31DD6C4C925BC580DDD424F444ABB84830FD521E5F68DBDDB63D3F60C6F5A73455A1F8B3ECBBF05C4CAFE7EF45DC4D1B6FFD7B4B1EB9FEBE1276D66353EA5A701ACDA0E71AAF226F78E9B5519C7FE414BBFF94DEF177C8326B1F3A8B78A1CB7DFF31FB337310C1751F18A007DE4ABA91686FA3A67F9C9CC72A9ED91C0BBC6D4A1FCB6B0BEF2C944C011300373D8B5D679A612D50268BE1BEC1DEA612544BA50D295353B147265F8DA681DAC4E175B30837554FEA3D3F140EFB8D00A4179EEAA96BACA9DF37A4C8B7076F499B5ABBE17C5AE173B3CA93339C50F2C17CD9D06B5965F6B94F4962ECCD17773717ADD029505FD52E887BB095B2C1C70A839EBC46E4D17A5A80A456441556430E9A755DA4D142A36644D5985F0ED9259653E1EE27FA231A68F6AD691FFE11D9CA1DDAF0AAC09E62BA13F77228937768B8D422508B87DF8A4027F1085594F66C91C18455E28917C6F3CD41D40922B95CE7DC4EF2134917801FCF1EA218527493C7D0F4D07DB9633EE53D9358381A7175ABF28F55D7AE8925D457A71E747C105BC840012E7F01698783FA2CA56AB53872D15F95A3D7A27CBE1E5E449CDDC2B550AE9B5636DEC281BCB7B39AF6502E7A5D50B0EFC83EF4A597804A7642201F7E7CF7FB3DD763E5F1EBD7DCF6565DEFBB3AEE203D48ED9A2E1C5ED53A75EBB5DE57FBF45D163A4C30EB06E7A9E9994F26FB1647D929856E1F14D2972259CE4F3BAEA9A3042E414004E01D557CFAF669187083CC5FFE1D250CCCD86BB0F2F109F1700297E5C5820C090B5FEAEDF32CC83EA5904DE0585F5AF5906E3C98F314E0967F8E458D55C6DCC13357C7E88F99621C0311F18EDD62B89888B909FEB9A517902F74A5187EDDEB66597F1ECDA4A3422EF0CB73A594C7DC854A030260CA3EA3222C808FF630BB8BD53B5CD546BB5B1267C2978B85D00DCBE081126137319D517471366EAF1D15C99C45CE151522BABE0D522968859FB8606C725C88A097862C849D95EB4E9A2743418BECAD230041FD36B20A0C0192C1411F5FD861EB3FA77445E69440E36E5BB02E3E1EC50EFD576A810A508E3FBC32946499B4351A96D5950A1DFDF037A9720CD7AE984FEDE567652D9A8D3ECA13CD3E44A6FEB5E22E77E5B2F0FB5A70DA2C3461B2A279B6AA65C20293312F856DC50CFF6137BFC6973F8F3BFD36CECE59CAE4C59B51E1E67F851D27FA8897BF6D9786C9229C17386A925A3EA152FDAFD7AA9BEFC2D9D61911007D06B2EC0ABF5117F9243C0229B811545EE108D20545BE7DACF687D58F1E20CA04626051DE9F0E40BD37519FFB8CA91DECBE7D540CEB0EF76006F0E9D78588AA2D514D31F1A71919212CE09105F863D13D41EA3857B2FDA055DBA4E5EF67CDDC4C6D8B59FFB11F8095E17192F1A3485C88B656F2E387A3F16901278534B5F6AD07EB45CDB412CED1F22BB69480C46A142B9C2EE3F52AD367156E64566A246491F3FBB65B69C70AD275521AB3E6D7E7BC37E75833B0F331A29B4C0B943DB5A26FBBC0F828FDC0837E521CCCA53BCC285F37CA2FA7306FF6EB6B5B250E8A2771456849B49AC2D7F492D676FCC2B17E45E33FB9D4CB2B783243AF1169F6422AD05D0C0524E13E8F7320E1B1BF499150C29862FED2925D78ADA680B141C73CBC29CC56DBA4D10C7163C5D6361157CE2AA2FC821D5D207C6DD41F835C7F4587F17D2EBD8A82A3968AB357DDB8E820538193645F73C6C8BDF266557DCA94CB2A6739596143ED68E6D10618090C54CF12DECA6E70258BBE2F65A62BB4CDFE29B61AFE910CC05C0F5039A4890F8FF4666204E7703E88D4F6FB490E57F49C32638DC302ED6E303D9E77D70D08B2474594B224DEFAFA5A904CB67BD6D7F0FF505CF565605F847498BBD7C9C56976BB54A055060DA6C7E9F2CB7EB4F97D03500D3B289910AD3E7473A6F61C9D35092CE097F0AAFA8F705A56F94B576CD0C0BA22563F963AEC5329E1AD6F2206FF3189EB0891A70A99E388D11E2AA4E309A27DC5BBDB1402E079087ADA7645907CC74BF97F809E854D731933B521B4FAB9FD81E086C020BA929E37C4A139BF71CFC58078AEC2AC04CCDBBDA4550953F11E77AF881752FF55322615499F0470D37DB97CF2681CB9C79C680098DC3C3EAAF05E896C2A50C84443ED42FB0C089DE9F341766D0C8B64D90DB29F3FE5502596BDA64DEF92B4E9792F18B3341D10CB4775CD4426F8145906A869434EEC0B77674941445AB9754CDF7D17720FFB4E55BEE26B092CEFECA8F81D5AE79607CA552948CBFC40E1778A7D480C47BD5E1F1578C1E35B249E8F3B2F08DA56445C052C32040A434DDF02FAC949E4736188CCE6B0CF0AA1A1979931AB4C5434BEE04F9A9F153BAAC524F44F3219938D4B01936A3D52AC94F8B852731A3875739B2E87FF57E5314713EE235CFDDE72F88F13EFF72CCECC17E2BEDB0B1D42B4C19C2179EAD016107B3E8D93952364B56030EA2EDEE223D3AE95DB38440D038F4053E75B4251934C324B01F6B53ECC6F0EE757C0476CC16D8D978150128FD18BF3A7402691474DAE1DBA0EA41EC22EA6CF71D0A5B3F64CD5777B268FC2E95AA5FD3D02BFC3CD8BA861532FF35F07DBFD05A3B7689D2955CFEFA5CC2117E408A20A566ED6AAB37C77FCF8747200FD14EEE64D35D0D24D0BFDA5EF80F13E4B63AF970088D2514EE6AA9388BEC38B1E70A87B5CA1DCA1006750216479280633E549BEC7E199F86D67F9E235A3BE89A2F2CE2C64687A19B2EB661136313444B06228A71F74BC6C4BF32B147146CFDC086A292EBD75A73904628F92E713CF0C700293FD22F443F509CEDB0CB2483753EC89FCD6E8D78A84873F1DA330E9C99CD987F2FE28290C8DD43589B4FEF34AE15C581EC008A4B2D2C2A947A41F766F0B64C8F5CA4E6A615ECA2935B12CAD4D5422C7DB3203DB274ED34015DB736808AA9CAAD394281D3AEADBC32F787FD4070159C676FC10F50AD6E9206624CB1E17B4652D2E9054DCB68D423569279306F9569E02B56186DD7ECB4D5EDB873DEA30E2D4E82BCE841C46A9645FBF3E3CBBD1168D693675953B34031704050D1A0C035553B108D73F15B70D51EDF50AA3FA871BE4BFB2C9386B91BFB1867322DA443AEC00AE518B0FDF6B74057DFDCE29F369FE8B78A42202E94CC5E9452EDA10CFBDEF60E6A82B056C9116A64C1B70232C9B3BA62CF865DC9A706D8FB89EA7A2003159CDD55B84F26585DF5B923BB463E82578D0F85678633771CC15695DC8E84E7F1DA326CF185AEDAD4DCF5E3E19954C4F3DEC035DFDDA1F0937FADF769863EA396FEF1079D56E869DD1CDB79DFB3F539A486AC849293C2AA645EA2680A2E5F67E1916A5AAC76735180C3294A2BAFEF7E7E842317E36F3FC8B52B7C6A0FE5419048475B6E2A39D4E7C6E785838AD1AD66AE39E47DD7D11D31439567215FC748A247BEF065C2F50D98A131C97167AFEFBFF6E044A3EB54D9B421059D1F4ED8D2ED24B94DAA7E1E383422B582ABBCE19DC8B66553FDC8DA09A5587167D08B415152A7D03D869221EC0F1FE66A78844981CA448D7C6C76A003D7944FC9C51A48F713E0EC0A55C3D12B4C71AB39139E7E0FE4CC26EC2BFA59612FE22F6C64B6DB449BDF2CAF46E22634ED3A774A42C90E3C17BDCC031F67DA8573B649DEB08FD77B01FE09584D85F5BC4BE680D761ACE56AD08AEAAD6DE8D81E04B074B75871E0E13CB2A94EE4EE2ADF28CE3D34F6CD6E94FED333B071F6E73C3A8BBE2844B4726A29CA8C5B992F622F14C406D2753954778BBC5A0B21A10B1D2791ACE8C583363CDDB5435E1BF4594AC8C9717391E6E32EB0CCB5817302BE2565C64400F3B385EE392FBFC2A00B9519BAE42AC2D580F4ECA8D8FD5E2EF5FF5363649AE66B9646AF2BFDCF8BCCFA648D31471E59EE735AD57852497696716D9EA83CD5F815CBC0603F9AAF303064E3672FAA571923BE37D12C8889D6F2A016004B5CCC56BA6DC3C384035104F6B2786EC87427D38BFCB9DF403EEA2880DF16B40C2A9767407D9A1F2B4E1FFA86BC953E1A6330C0E8D134959128D471494C1591ECD070B224F7FF92658EB76B964A0F85F4B829D994817D04D70F43A463E9870762C83E97FB9145A0ECB714181249A88F12270A7B2DB45DDE99E6CB60F1BBF2846194B896D226D9CDB16E0C89C2E01835CA4A4463883FAB4B16B4938A1C02254D3DDFC9D8C345D9BDD773706A7D0C46C47FA57F64558B0E8B0C69D4CD81F23DEE87E804DF6CBB066D29D3ADA59FBD95ABBC6F5FE1D6BF99EADFF83A6CDCD5870F60AF60EE7A682352012A7CC7B0E648A42BE54C2077E0EC2D251019D390D7C40DC329228D990E5357C38EACA4012D0C27B6F0F6A83BB406ADA810480A22FA00EC5267FFA9A33EC2E7057219387EAC23A16CC1028C8EB91DB72A5F6F9153775EBCDC923DBCC76A369CB507AB1D085985F5282660FAC9D9A8067DA2E21330C3DCF6355C8695A7A9BCDF05185C7EA9D01B7AA6035AC40000000000000000000000000000000000000000000000000000040911171A1D30640230092532392AEA33A6D3D0EE856CD28173CF742E3B8135BB8BE99B0D25E64371CA9594F6A5946EC839BB94821C2CC8F3AF02307E8F802F604E737E2B9983E0CB6E287AAD0924A479316D41BA66C6C2104AF5F495775CE3146A42809A9B61732FC05AB1 + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-65-ECDSA-P384-SHA512:COMP_ML_DSA_65_ECDSA_P384_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 86FD58C8184F842C7F6D65C3636EDC2CDE19448D4CAEEB32424DBBF7D618E5F4ADD4F1FBB172282001B6A5232D9BE9BBCAADD3B72F42CC38C68C78187DCAB2DAEE391BF974D8F413A4D14EB42CAF7DACBA0E4EC45D503C8028FC4E5DC926D31DD6C4C925BC580DDD424F444ABB84830FD521E5F68DBDDB63D3F60C6F5A73455A1F8B3ECBBF05C4CAFE7EF45DC4D1B6FFD7B4B1EB9FEBE1276D66353EA5A701ACDA0E71AAF226F78E9B5519C7FE414BBFF94DEF177C8326B1F3A8B78A1CB7DFF31FB337310C1751F18A007DE4ABA91686FA3A67F9C9CC72A9ED91C0BBC6D4A1FCB6B0BEF2C944C011300373D8B5D679A612D50268BE1BEC1DEA612544BA50D295353B147265F8DA681DAC4E175B30837554FEA3D3F140EFB8D00A4179EEAA96BACA9DF37A4C8B7076F499B5ABBE17C5AE173B3CA93339C50F2C17CD9D06B5965F6B94F4962ECCD17773717ADD029505FD52E887BB095B2C1C70A839EBC46E4D17A5A80A456441556430E9A755DA4D142A36644D5985F0ED9259653E1EE27FA231A68F6AD691FFE11D9CA1DDAF0AAC09E62BA13F77228937768B8D422508B87DF8A4027F1085594F66C91C18455E28917C6F3CD41D40922B95CE7DC4EF2134917801FCF1EA218527493C7D0F4D07DB9633EE53D9358381A7175ABF28F55D7AE8925D457A71E747C105BC840012E7F01698783FA2CA56AB53872D15F95A3D7A27CBE1E5E449CDDC2B550AE9B5636DEC281BCB7B39AF6502E7A5D50B0EFC83EF4A597804A7642201F7E7CF7FB3DD763E5F1EBD7DCF6565DEFBB3AEE203D48ED9A2E1C5ED53A75EBB5DE57FBF45D163A4C30EB06E7A9E9994F26FB1647D929856E1F14D2972259CE4F3BAEA9A3042E414004E01D557CFAF669187083CC5FFE1D250CCCD86BB0F2F109F1700297E5C5820C090B5FEAEDF32CC83EA5904DE0585F5AF5906E3C98F314E0967F8E458D55C6DCC13357C7E88F99621C0311F18EDD62B89888B909FEB9A517902F74A5187EDDEB66597F1ECDA4A3422EF0CB73A594C7DC854A030260CA3EA3222C808FF630BB8BD53B5CD546BB5B1267C2978B85D00DCBE081126137319D517471366EAF1D15C99C45CE151522BABE0D522968859FB8606C725C88A097862C849D95EB4E9A2743418BECAD230041FD36B20A0C0192C1411F5FD861EB3FA77445E69440E36E5BB02E3E1EC50EFD576A810A508E3FBC32946499B4351A96D5950A1DFDF037A9720CD7AE984FEDE567652D9A8D3ECA13CD3E44A6FEB5E22E77E5B2F0FB5A70DA2C3461B2A279B6AA65C20293312F856DC50CFF6137BFC6973F8F3BFD36CECE59CAE4C59B51E1E67F851D27FA8897BF6D9786C9229C17386A925A3EA152FDAFD7AA9BEFC2D9D61911007D06B2EC0ABF5117F9243C0229B811545EE108D20545BE7DACF687D58F1E20CA04626051DE9F0E40BD37519FFB8CA91DECBE7D540CEB0EF76006F0E9D78588AA2D514D31F1A71919212CE09105F863D13D41EA3857B2FDA055DBA4E5EF67CDDC4C6D8B59FFB11F8095E17192F1A3485C88B656F2E387A3F16901278534B5F6AD07EB45CDB412CED1F22BB69480C46A142B9C2EE3F52AD367156E64566A246491F3FBB65B69C70AD275521AB3E6D7E7BC37E75833B0F331A29B4C0B943DB5A26FBBC0F828FDC0837E521CCCA53BCC285F37CA2FA7306FF6EB6B5B250E8A2771456849B49AC2D7F492D676FCC2B17E45E33FB9D4CB2B783243AF1169F6422AD05D0C0524E13E8F7320E1B1BF499150C29862FED2925D78ADA680B141C73CBC29CC56DBA4D10C7163C5D6361157CE2AA2FC821D5D207C6DD41F835C7F4587F17D2EBD8A82A3968AB357DDB8E820538193645F73C6C8BDF266557DCA94CB2A6739596143ED68E6D10618090C54CF12DECA6E70258BBE2F65A62BB4CDFE29B61AFE910CC05C0F5039A4890F8FF4666204E7703E88D4F6FB490E57F49C32638DC302ED6E303D9E77D70D08B2474594B224DEFAFA5A904CB67BD6D7F0FF505CF565605F847498BBD7C9C56976BB54A055060DA6C7E9F2CB7EB4F97D03500D3B289910AD3E7473A6F61C9D35092CE097F0AAFA8F705A56F94B576CD0C0BA22563F963AEC5329E1AD6F2206FF3189EB0891A70A99E388D11E2AA4E309A27DC5BBDB1402E079087ADA7645907CC74BF97F809E854D731933B521B4FAB9FD81E086C020BA929E37C4A139BF71CFC58078AEC2AC04CCDBBDA4550953F11E77AF881752FF55322615499F0470D37DB97CF2681CB9C79C680098DC3C3EAAF05E896C2A50C84443ED42FB0C089DE9F341766D0C8B64D90DB29F3FE5502596BDA64DEF92B4E9792F18B3341D10CB4775CD4426F8145906A869434EEC0B77674941445AB9754CDF7D17720FFB4E55BEE26B092CEFECA8F81D5AE79607CA552948CBFC40E1778A7D480C47BD5E1F1578C1E35B249E8F3B2F08DA56445C052C32040A434DDF02FAC949E4736188CCE6B0CF0AA1A1979931AB4C5434BEE04F9A9F153BAAC524F44F3219938D4B01936A3D52AC94F8B852731A3875739B2E87FF57E5314713EE235CFDDE72F88F13EFF72CCECC17E2BEDB0B1D42B4C19C2179EAD016107B3E8D93952364B56030EA2EDEE223D3AE95DB38440D038F4053E75B4251934C324B01F6B53ECC6F0EE757C0476CC16D8D978150128FD18BF3A7402691474DAE1DBA0EA41EC22EA6CF71D0A5B3F64CD5777B268FC2E95AA5FD3D02BFC3CD8BA861532FF35F07DBFD05A3B7689D2955CFEFA5CC2117E408A20A566ED6AAB37C77FCF8747200FD14EEE64D35D0D24D0BFDA5EF80F13E4B63AF970088D2514EE6AA9388BEC38B1E70A87B5CA1DCA1006750216479280633E549BEC7E199F86D67F9E235A3BE89A2F2CE2C64687A19B2EB661136313444B06228A71F74BC6C4BF32B147146CFDC086A292EBD75A73904628F92E713CF0C700293FD22F443F509CEDB0CB2483753EC89FCD6E8D78A84873F1DA330E9C99CD987F2FE28290C8DD43589B4FEF34AE15C581EC008A4B2D2C2A947A41F766F0B64C8F5CA4E6A615ECA2935B12CAD4D5422C7DB3203DB274ED34015DB736808AA9CAAD394281D3AEADBC32F787FD4070159C676FC10F50AD6E9206624CB1E17B4652D2E9054DCB68D423569279306F9569E02B56186DD7ECB4D5EDB873DEA30E2D4E82BCE841C46A9645FBF3E3CBBD1168D693675953B34031704050D1A0C035553B108D73F15B70D51EDF50AA3FA871BE4BFB2C9386B91BFB1867322DA443AEC00AE518B0FDF6B74057DFDCE29F369FE8B78A42202E94CC5E9452EDA10CFBDEF60E6A82B056C9116A64C1B70232C9B3BA62CF865DC9A706D8FB89EA7A2003159CDD55B84F26585DF5B923BB463E82578D0F85678633771CC15695DC8E84E7F1DA326CF185AEDAD4DCF5E3E19954C4F3DEC035DFDDA1F0937FADF769863EA396FEF1079D56E869DD1CDB79DFB3F539A486AC849293C2AA645EA2680A2E5F67E1916A5AAC76735180C3294A2BAFEF7E7E842317E36F3FC8B52B7C6A0FE5419048475B6E2A39D4E7C6E785838AD1AD66AE39E47DD7D11D31439567215FC748A247BEF065C2F50D98A131C97167AFEFBFF6E044A3EB54D9B421059D1F4ED8D2ED24B94DAA7E1E383422B582ABBCE19DC8B66553FDC8DA09A5587167D08B415152A7D03D869221EC0F1FE66A78844981CA448D7C6C76A003D7944FC9C51A48F713E0EC0A55C3D12B4C71AB39139E7E0FE4CC26EC2BFA59612FE22F6C64B6DB449BDF2CAF46E22634ED3A774A42C90E3C17BDCC031F67DA8573B649DEB08FD77B01FE09584D85F5BC4BE680D761ACE56AD08AEAAD6DE8D81E04B074B75871E0E13CB2A94EE4EE2ADF28CE3D34F6CD6E94FED333B071F6E73C3A8BBE2844B4726A29CA8C5B992F622F14C406D2753954778BBC5A0B21A10B1D2791ACE8C583363CDDB5435E1BF4594AC8C9717391E6E32EB0CCB5817302BE2565C64400F3B385EE392FBFC2A00B9519BAE42AC2D580F4ECA8D8FD5E2EF5FF5363649AE66B9646AF2BFDCF8BCCFA648D31471E59EE735AD57852497696716D9EA83CD5F815CBC0603F9AAF303064E3672FAA571923BE37D12C8889D6F2A016004B5CCC56BA6DC3C384035104F6B2786EC87427D38BFCB9DF403EEA2880DF16B40C2A9767407D9A1F2B4E1FFA86BC953E1A6330C0E8D134959128D471494C1591ECD070B224F7FF92658EB76B964A0F85F4B829D994817D04D70F43A463E9870762C83E97FB9145A0ECB714181249A88F12270A7B2DB45DDE99E6CB60F1BBF2846194B896D226D9CDB16E0C89C2E01835CA4A4463883FAB4B16B4938A1C02254D3DDFC9D8C345D9BDD773706A7D0C46C47FA57F64558B0E8B0C69D4CD81F23DEE87E804DF6CBB066D29D3ADA59FBD95ABBC6F5FE1D6BF99EADFF83A6CDCD5870F60AF60EE7A682352012A7CC7B0E648A42BE54C2077E0EC2D251019D390D7C40DC329228D990E5357C38EACA4012D0C27B6F0F6A83BB406ADA810480A22FA00EC5267FFA9A33EC2E7057219387EAC23A16CC1028C8EB91DB72A5F6F9153775EBCDC923DBCC76A369CB507AB1D085985F5282660FAC9D9A8067DA2E21330C3DCF6355C8695A7A9BCDF05185C7EA9D01B7AA6035AC40000000000000000000000000000000000000000000000000000040911171A1D30640230092532392AEA33A6D3D0EE856CD28173CF742E3B8135BB8BE99B0D25E64371CA9594F6A5946EC839BB94821C2CC8F3AF02307E8F802F604E737E2B9983E0CB6E287AAD0924A479316D41BA66C6C2104AF5F495775CE3146A42809A9B61732FC05AB1 +Result = VERIFY_ERROR + +# --- ML-DSA-65-ECDSA-brainpoolP256r1-SHA512 --- +PublicKeyRaw = COMP_ML_DSA_65_ECDSA_brainpoolP256r1_SHA512:ML-DSA-65-ECDSA-brainpoolP256r1-SHA512:AB2FB1062A2657EBBACC3C8BCCA8CFAF43373B6945418294D19F6BEE4CD25B6E7C7C1F08FC7417A4FFF87393FF4E4EBDEA3638946B8A266FB73AD2CCAFF49CD16E6696CB2C25355356648136793D036ECC774BC3C3A0DC98E1315A981CD22A839C8DC3DB58E3EDC26EAB6E67FB1D41ED169CEAE2C52D5CB12C4C96CB02824D9C8AB5B3811E27467A0FBA5C4D2EE43411108D458789FEE3553D4B0E28399E09D6CF088159F7430EFC40DBF42BF0B6192E13DC3502B7D2EC9B7A501190D2CFDC2FF14B700AE3F458819065D1A8AB5FB2D95FC50E3D08D8F44347BEA323A2C8ED0420FEA1EFB12782F9DC81163ABCC93150B2CFDF6D8681327DACF99F9CE2F8F6A8452E9CA2912B73DC60C94AB15C8C6ACEC02F4390C8FE7FD62FE1273B22D1ECA2322DA442558706123E75B0A8C0746698A0337D8C8E0B071B17970802768F2AB670204CD75EFB0AFF41EA5912B50872C5553690AFD10DF41A618609AFB5CBB490936CD583100D4F94521EB4CC38F680B5DEDCDCC304E52DD1FCA5C12C807731CEE265375E8EF30274615E400923603D9EEA4C665460F8357E2078C1D226B62B9165CB80D5D42BD1945A6F2C7AEFDE4A5B8803E1AE8195864959E91413A9520ED85B97F61399ED6104C616F8B2353A93808861D7DE215ABDB1B35C11B97ED71DD3D35B3D5CB36C9B6C74B041723DAA2FCC2D529FE8DA33B59C9C55EA92F9BD35C6A39446AE354C5E7C6BF54F0F386312904693D024F7B2A6CA8BA80545DC45345A83C8101E5AA102C14E472CB1A274AFA3B97ED38182F0CE5F17582187E7A46048AE1A791A8067BC6D018A42CCD5008F0BAB3F483CA512B890FAC766B7167D2C78DFB0B1A22D324FDA2429789625C64E94DB31B256879CAB216B43564210A0F01A0BDAEAF75E40B3CFBE79B0CD0C0874CECC0BC05D2CD6F32F88FFA8E2C769F0382F7C54F42F30CA5E0DC183F89AC1744CB32049829CBBEF4117966F54B18AB0C3E3C3737E749EF6399534B8749ACE9AF69E0962F9324669BB832018DA73A61461923453BA3608AFF772DA76D2BE5AF35FABB8E1912CB997760EDAF9CBF74ABB854D9DAA90F261786C3FBB0635B217D165DB52104DE244D1E21DC29BA926493A5B9118E689B90C1824BD7ECA883025344A99B4ED0E27228D8EA3C0968E94DE09A8C56747A960F8BF99F2A920EFA005D4FD5074666397083F437130288A2343FCF99CC04C4ACBF5FFA666A3F4866C764A233BC164F7DD4D32E822F923570C0E8A98C0E0C19968FB89EE4CDC94E9EFA7794868C4B13CBA30318C69DA21377CB1381CCDF543C84839C8AAFBAE5E2E6B3A618745D3163EC410C9FB5E1D2218CE7B0453FFD50985BA9D5649D670FAF7BECC56C543E7C55E2BF6CA0D5616E0D8CE38C8852ECC773F4D1B73A6A935D7A0C45AF4C5C8904D7FEA8477EE7607D92E22B1852E0C11A81513E72E2B87C49F8221A94FF13CCD5B1457A966C08D3DBDC8F074C63684428697EBCF45F676CEBBC6DF7717B9659AC629FA8EA7FE530647F1B9DA69FA84741C13F0C27AD8CDF1BFB23B2E4E798A1D9426C0771EA9AB6EEF118C1BE2B98926F0F6A3A6B7AF9B8CB3D5A6275575371D95D675E8EA1C364B3099BBE114D1029153E69E46386D36F218EA6238F692A783C9D30D80DAB41455D119F20225F5B74E2F705EBFA5B65B1EC15F898F6CAF74F70D379443F860F244CED62709EB4E72B89E08A23C5875ED75BFB684339FAF61B5BDA1678AEBD80C51231523D66EB0CA50216CB089488F986A813A6CC5AABB8D894CB7C951BBE61545B61395364047F6BC1A96A8A91A4D60ABA59D266555CFC4053392CDDF371D78465E413C5E858ECFD18D2E38B49D355383F5389C9DAAF837DBF87DA723CB3A0825AAB3DF1675ECA5DF6F8C749AD7EE5786424254EE491A35E1D0D4F30BAFD934F9A983545C48F678C46311CB3B8884E2A8F89ACB3DD574C029B95265227CF06CB569253BBEA302C88CA162894C0DD86C92405612C1817A1FF421F6D632FF9A61414219C46E536F8F55B2321E8CC56880A072564DC73D9A86E26CC22E2346CE53973F56B176F26EC12EE19EB829E74D8F1FEE77AD05B5FB722A25E7EFA1424549A63E41FE280F3526F306FA2D6181220B8CB7775D39739A44A928E774FC754355D0CC2C35AA74E5BAAEC27B0B9B540F6C36E432F44C634E2B509110EDBB603083BD2DB53B28D10FFA5F83BA2EB69CF0F798812A58DC5051AE2FAAF34DDC46B73DE16A3B829402D7C9354B00CB61FA541F950535F7A630B5204B53F50DB100EEC1CD5AA346BA52CD981FC24872C98CF5CD8CE3212B83D147862D5B3A03F3DD38BEE7A6595197210E4CBC32CA38A2BCA80A5DBFA5707478796065153A6003A79AFFC6C3952113D27F9AF7E35F2A9D3B022590F3DB99785144D8DAD167DBDF5A51A60074594AE654FE9A93571E052A7E5383379491F74FE1EBB95EEDCD179EF0DEA0B289BA88BCFB67402BC2DBCF84C638058B639F5BAD00E6AB02AAC3C8D0AFE8B016D27B2252618F931D33431D73DFDCAE4A96F48B64650DC20762D72D5CCE0293ED2F902D553622D0BB73939E689D7DD470464505A8DBC28FDDB6D4DE93B1D52B6E2B7D9A6F057DBE9FC82C94122C74F45786403480F136E5187071285A99CF7CDF97A07168DAB2E2E996A0CEB7F14FC143FA6BBD1E8E8F5C0C2098CF4642D8609E748D466F067FCC227782220AE9BC620192EA2D83444F2DF7C7E24EBE7AD12956F751CC63AF190473BE1BA065A8FDC2BAAFEC2AD0E82AB9407617BCACA14E43282B5B20CB9492262B95FF044D91002BBCCDBF0002CF88428BA93FE7F2E7FD06557E10DFB7ADC19D + +# valid signature +Verify-Message-Public = ML-DSA-65-ECDSA-brainpoolP256r1-SHA512:COMP_ML_DSA_65_ECDSA_brainpoolP256r1_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 64A23684573595BC43851AF1E7E4D78AC1941E18B77B2DC225D5AABD6CFDC0F2C1F8046A0715F4E0637CB37C826A44F55BF7F9E66CB999D9979BBA638618595F2CB615FA0AEC1CB07DC2A9ABA9FF3D4C2C3B6CA6211C69F3953DD6539F02120CAEC2D132B490AC4481350C655C66EC172AF6DCD6E6B800719A6ADD0C56721046635C700D65EB38F3F553E0F6529C49E6EF48071F422EDB6FC9E07DB45E4E0064C4BCB235661AB0F2BD7B364D80C3F69E8948BA6FD87118E8A1C4A77350AAE98E3B000E11F49205C71C97CE6480121D096FD12E04A512134C1C1D1D475B696CEAD87E9D5E17AC66953C6CCA94AF5A7E9199DB6EB63C282C96478FA9964853A1E13BC8C11C7B83BD4B7EBAE5132972619A5D2A11D524199F014EF89EF87CF8533FB1213832A44378D39139CEC747D504B192C2A2D0A106C6F43A1584DA7F1847ED7F8F5F8CAB3976988C81FD5607305A637392F1EDA5A79E57395A07DDA00E2D43A7477958B9A5E80D518E53CD7C4DEBB56D6880C81CE54EEEBE5A6A7D13209A5FB040D8CDD9634F6A2FAFA35782FA1556DAD4A79B6F1DFF73E8E9EDE08302B60097C7E3888A5EE0218B690405FF89CFC9F06DFCC5657AEA9E9665B9512D9E9AF1CBAB191A55CC5BA66C977678FE14BD6DA1D4147C4F0018E70396EB49FD9A5D62606084ACD7B2ECFD81CCD3B721BDBB0C23342ADC6382426BEEE7473C45F7330B4BC02A98B1E9C6952912DB2DD7466172C12DB909AF1D0D7B7702CE8E4D73978B94C3E52C097BE8F94187ACB7345793B04DACC0183E3EE7136F4B83ABBB82BBEA549CD1D5194A8AE15BA947994A53526B891679EEAC1000A1F421183A9C6883981EFB99052F6EA4B58B031E33649553FB36E30E55B5505BD829B91087CB6F599F8A5DAE95E15862CE6F5A063812819B70DF6A87C6AB11E05EA20FA76C4B62C05DA3AB59EAF29B20F28BF1AAF2C301947999C5D181AA7BEB41A0DD06FCF8037FE5E21A48F9B4B60CC93C9BAF8835901AFE7DE6A3ECED4C893ED28531840BFE7B0EA244BADE26E4E69859E2E159975F8C06023C88C8EDEE1D3346B3244B1968BC590425B3ACAE4B013E942188E396F5E6448FA3A304B11800319577A1E82EDBCFE53AACCAF20600B39763E8DC4E399596C100DAB719BEB45818A1AC7F463C4CACBA4279D71FEA90C7311D503DEE4AFACEACB52B8A391A247357C16088AC7CB3760B526BC1BC6F0936134713FD92B3ED46214BC5E41DA53B553138560E7820E0A31C26DCDF867BBAC636EE7372DE6B7BE27CBA566A260A15451E38467F82A4F918ABB21679CE71F0996FDCEAB955B2957E2DB8B78956FFF78252CCEC7381E53EE74C47CCB01F8EF3BA47A46E8751C5B2C1EF93A1C9A24469A6E3A447A1ED891F8D4EAF288F2F51E258914F049CC024EB7D4458120C9DF1360AE2DF27D695D868097398A1290EDBD8FC5A68E952E37BB7EB92B4A80C1952CDD382E5B48D1CE3A55C0DEF7682065D2E4F934714278C66F0BA7F224D7D8EE1913F4120030A7C4004A1C48938A5DB1F37C65B65AE387B0322682B3AEF896198406C7080E3249F89E3AD2C18B60D7F224F8BB4D78EBFBA931CB4BE98E4A1C1A814CDC44779A5F06DF3D428DDD8B31A2DFF3B232EF63E43F5CEA0E516CD91556686DEC1C4B84A352868017358ED41E09623C9DA213CC325920A0C1F4F4D3B7E53A1DA1FA30EF5F6A591B6FAD4292E670371E4E896C5D0C35892CB7BD10292668155EA56DC41060C23CE615F24EA90125B3490084D19711B940E1E331C7C39D0FD4FFB2751FD8617014E8301A63D86BE7D01F784BA46CDCDBA2DE4F60C046F3219BB0C1F6573D334ADC8E30974F34422C35B85E69D824EDE94B590BE521459315E96A71B02E89C030D4C96DCA561DA618CC277977A1C6D035192FB353F28EAA138596519862940CDF7609BBA93D82FEDAF600E2CCF07BF03388CC8B1D2147F691227D1CB10932FCCD5EEEF7B4EADDA831E582F1417E981BB0FB5A92288470DB0FE4D6A59727E1D780AE7296227F8D49426DB6CBEFD866BB2CEC457BF2F1A8307762147422653D8299B244353BBF7FF852160B6482006D4396327856F573C081D75F83FC80537879A5024E50197821A6A7FF2A7522D4FA81D7F072FD4625D7FE5149F2ADFA32CB827DF93268FFD7E324B01730CFEA50E439E43C89C84CE468B8F691E3117F4E464A0703258017FBDEEA9C494201848D4B184F56B88019899B9CA39471ED9A9509CAE73340965A1D7CF44CD14ECBCC7D20DADF586A255D58FC0B6645016F2650FDD7BF9E8FF4553500429BA4AB7272AB91579F9FE9DFA4C1DFE5D07D4A5A07571CB22B7057575B9EB539657A5CF707777BDF5567B1358BC70ED471D47AF44CE01606ED58893A99595CB82EEDE6F059663403277DC3F2B1AA5F70EAE593C6B771C58ECB15BB09FECB9664FCA9888128EE7DFDA36421C2ED68623EA32C0698C0F8370374EC5F9A351B313C0FC211BB2B796866D8DAD8C5879C684BF15CFC0B01AA17D14858CE8F4E67084CB4895E06CC6FF17998D3427E094621945B85A6F2300368185C83B659A93F7B78ABD5C002B0C88CCEFBEA7E0CED0D2C3FD7DA031B9D784518A0EF80C9318EB6BD2E759EFBF51191F86FB56D0E21EA7D69C93E1D9A3C2FC83971B43DF0481EA7CF61370E3621F30CC001637E12A545DA4BAAE8BFD3323ABB9466A2C7E25E21E801CDCD70BC7F73DD709260C47B1F1A470A87EFE53678328B24500E24CD5C9F15E1AE93E3C6BE945EF0992A5158AD832DA2F1001711FEF5056EBD63C5109C98631E8A17B52D7406376FAAB37C053105CF519F416468B109084ACCF503FA44CE9C44BBEA5EED9455FBE2C50BED5251E341F478851216DB9F09EF887F8B96C80E26CA1974DF17883B1DEC957196324C590DE4D61A2366942F377B674F46B4A54DA027F566B5C98AEA38768B8FA5F0BA382393A60594175BCE985735D022D87B9061657467C0FC8E3B611859910DB30D709FA43C868F5CF8C9A4A22F9F00187644558E24DF8B960924D4DF5F65D9F52BA7777215EB24A534059371AF849A52A0E39A4D397434FEDABDE97C3E6C4D72C825F7E771C38C33B04606CAFA0C9AF7056D016ACA21F30B82303350FC5C13588AF07A0ED789D2668363E338060A079A488C5E9484227A4C369FA74C7764A52F80BBE1ED62B4A2408D879D7D800CC4F7309F1484AE7868BA62740728F430B4D2CF751F03697791148817D456A5105CB342B6D9D049D2FA2F9F55182E0B896E8B633039F4ECEC5D13C132C1BD2DFC86BAE61506E566F936AF2A78AC3E886C6CD4B1BBE1E741C58A951C11F1A1AC132366AE8D96587BFF6977A1CAF4A6C616887FD9A05ED65192B8ACEBD8EAEF0DE87EC999C3BB1E769AC74EC55E1CC0085AF11A5A902577D0E510AB649E4B6FDE199BF247D70DA42C36FDAEB60A1B02BB1CCF0A9451CCF7D1BD8A75956CEC512E4C75AD008B6B9AB1A61C273EADCF5D623EA7FE1D1F33EC3CD9511C3C5E564B222B447FBE86B4047AAA8059824E5608004FA8E12094BCD3BF0B1FCCDAF31D63E17385673F3BB98DCA65FF01893E873C1031D124DECFA1F62ADC4F3BCD579AC99D358DAFD0D310E1E474DF5D043B0AA14B6A2AAE95E3E03CA9AD5FE8127DDD3E477F92D447A0DD5AE7B4365EEDE0F1477B13CCE194662FEAA02D6792FB49F35FD009637314A194E0DEFB4BB18AB9466CC1D362398CEF4FB6EF3347CBA707AD7CFD119F0441BB69B097F83ACAD2B98780265A8C373D3C30F646FC179648B2007818E76C89F8392A9B54294F5B76692BAEFAF1A743DFD8DD9F47A6A398DB10400F5C62E274AE7EF6ED6C377FBF0584B5CD67AB66888D9CCE9484C9E230434720F7EC20D9BE4702470568371A641CFFDC357EB8FC523815FD2CC1CE242D2AC217E4F9985EE39D60FEB88985A4775935B4597ED706265371F35AAC3FBD65DB8EAA791842BEB02D451D3014C17632251E421D4ED198B7FE7EA360CE3542ECDD270735567A83B9CAD3B7056BFA76C432AF0703DAE6FD75165D80B02CD938F9F72A6859456F3682972DD16074C373330865C5DB50592F5E9D0E8890759DA198284AA2B2E1A84B2788DDB044A23E6946EDC12991E5BF1E98B1C3228F7E32E2F7FAA289352CD2553DCB814BCA7BC9C5D665D024D763693A16FB88D88C2E2618BF4E7AB21682A97F5F5020C23968DE756564AA23E60D9CC30EE93CB0F6FD9BCEF29136FFA72EB80550B2B629C0EF91FFBF47BCADDB0FBB72FDD60DCFE7115DC96066CA7BFFB63AA9BD12A590FD81845C9D5D20AB29BBB40BFF96D0881C4226F64D8F08C7C1A9EDAF5EA6E0CF172A0611698789AD1D71BABA5D4ED6E273423333805E14E622440C857FC81CBC8E6947EFABC313882423BFC989BDCA9F6BD315925025486163D24FD976C6883B5200A46B620B71DB8F0DDF299CD9BF160A0A97CF3AAB0DC1BF632E81FF75FDDD2A43113B77852E54757923B97C52FE22A013B876F7D8A0C70A2FA82C1589B626E0CE5C8E3A6767E0857BC64179467833AE87AB8DCF997B6443E4F43C84A00CE9BBA016642F8ABAB92AE8323B6AB0A3E6D7C9097FF59E90D266A90BAD4FD00334E6885978E92CC031E4BA3A40000000000000000000000000000000000000000000000000007091016191E304502200CC0D119C5F9AE1140B9ABE8920FDE77B5B86501FB690FD838354FAD9B9EBC88022100978A5BADC3B13576E2DA9043ED6DEE9600016EA7E60649244CF826A1007492FB + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-65-ECDSA-brainpoolP256r1-SHA512:COMP_ML_DSA_65_ECDSA_brainpoolP256r1_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 65A23684573595BC43851AF1E7E4D78AC1941E18B77B2DC225D5AABD6CFDC0F2C1F8046A0715F4E0637CB37C826A44F55BF7F9E66CB999D9979BBA638618595F2CB615FA0AEC1CB07DC2A9ABA9FF3D4C2C3B6CA6211C69F3953DD6539F02120CAEC2D132B490AC4481350C655C66EC172AF6DCD6E6B800719A6ADD0C56721046635C700D65EB38F3F553E0F6529C49E6EF48071F422EDB6FC9E07DB45E4E0064C4BCB235661AB0F2BD7B364D80C3F69E8948BA6FD87118E8A1C4A77350AAE98E3B000E11F49205C71C97CE6480121D096FD12E04A512134C1C1D1D475B696CEAD87E9D5E17AC66953C6CCA94AF5A7E9199DB6EB63C282C96478FA9964853A1E13BC8C11C7B83BD4B7EBAE5132972619A5D2A11D524199F014EF89EF87CF8533FB1213832A44378D39139CEC747D504B192C2A2D0A106C6F43A1584DA7F1847ED7F8F5F8CAB3976988C81FD5607305A637392F1EDA5A79E57395A07DDA00E2D43A7477958B9A5E80D518E53CD7C4DEBB56D6880C81CE54EEEBE5A6A7D13209A5FB040D8CDD9634F6A2FAFA35782FA1556DAD4A79B6F1DFF73E8E9EDE08302B60097C7E3888A5EE0218B690405FF89CFC9F06DFCC5657AEA9E9665B9512D9E9AF1CBAB191A55CC5BA66C977678FE14BD6DA1D4147C4F0018E70396EB49FD9A5D62606084ACD7B2ECFD81CCD3B721BDBB0C23342ADC6382426BEEE7473C45F7330B4BC02A98B1E9C6952912DB2DD7466172C12DB909AF1D0D7B7702CE8E4D73978B94C3E52C097BE8F94187ACB7345793B04DACC0183E3EE7136F4B83ABBB82BBEA549CD1D5194A8AE15BA947994A53526B891679EEAC1000A1F421183A9C6883981EFB99052F6EA4B58B031E33649553FB36E30E55B5505BD829B91087CB6F599F8A5DAE95E15862CE6F5A063812819B70DF6A87C6AB11E05EA20FA76C4B62C05DA3AB59EAF29B20F28BF1AAF2C301947999C5D181AA7BEB41A0DD06FCF8037FE5E21A48F9B4B60CC93C9BAF8835901AFE7DE6A3ECED4C893ED28531840BFE7B0EA244BADE26E4E69859E2E159975F8C06023C88C8EDEE1D3346B3244B1968BC590425B3ACAE4B013E942188E396F5E6448FA3A304B11800319577A1E82EDBCFE53AACCAF20600B39763E8DC4E399596C100DAB719BEB45818A1AC7F463C4CACBA4279D71FEA90C7311D503DEE4AFACEACB52B8A391A247357C16088AC7CB3760B526BC1BC6F0936134713FD92B3ED46214BC5E41DA53B553138560E7820E0A31C26DCDF867BBAC636EE7372DE6B7BE27CBA566A260A15451E38467F82A4F918ABB21679CE71F0996FDCEAB955B2957E2DB8B78956FFF78252CCEC7381E53EE74C47CCB01F8EF3BA47A46E8751C5B2C1EF93A1C9A24469A6E3A447A1ED891F8D4EAF288F2F51E258914F049CC024EB7D4458120C9DF1360AE2DF27D695D868097398A1290EDBD8FC5A68E952E37BB7EB92B4A80C1952CDD382E5B48D1CE3A55C0DEF7682065D2E4F934714278C66F0BA7F224D7D8EE1913F4120030A7C4004A1C48938A5DB1F37C65B65AE387B0322682B3AEF896198406C7080E3249F89E3AD2C18B60D7F224F8BB4D78EBFBA931CB4BE98E4A1C1A814CDC44779A5F06DF3D428DDD8B31A2DFF3B232EF63E43F5CEA0E516CD91556686DEC1C4B84A352868017358ED41E09623C9DA213CC325920A0C1F4F4D3B7E53A1DA1FA30EF5F6A591B6FAD4292E670371E4E896C5D0C35892CB7BD10292668155EA56DC41060C23CE615F24EA90125B3490084D19711B940E1E331C7C39D0FD4FFB2751FD8617014E8301A63D86BE7D01F784BA46CDCDBA2DE4F60C046F3219BB0C1F6573D334ADC8E30974F34422C35B85E69D824EDE94B590BE521459315E96A71B02E89C030D4C96DCA561DA618CC277977A1C6D035192FB353F28EAA138596519862940CDF7609BBA93D82FEDAF600E2CCF07BF03388CC8B1D2147F691227D1CB10932FCCD5EEEF7B4EADDA831E582F1417E981BB0FB5A92288470DB0FE4D6A59727E1D780AE7296227F8D49426DB6CBEFD866BB2CEC457BF2F1A8307762147422653D8299B244353BBF7FF852160B6482006D4396327856F573C081D75F83FC80537879A5024E50197821A6A7FF2A7522D4FA81D7F072FD4625D7FE5149F2ADFA32CB827DF93268FFD7E324B01730CFEA50E439E43C89C84CE468B8F691E3117F4E464A0703258017FBDEEA9C494201848D4B184F56B88019899B9CA39471ED9A9509CAE73340965A1D7CF44CD14ECBCC7D20DADF586A255D58FC0B6645016F2650FDD7BF9E8FF4553500429BA4AB7272AB91579F9FE9DFA4C1DFE5D07D4A5A07571CB22B7057575B9EB539657A5CF707777BDF5567B1358BC70ED471D47AF44CE01606ED58893A99595CB82EEDE6F059663403277DC3F2B1AA5F70EAE593C6B771C58ECB15BB09FECB9664FCA9888128EE7DFDA36421C2ED68623EA32C0698C0F8370374EC5F9A351B313C0FC211BB2B796866D8DAD8C5879C684BF15CFC0B01AA17D14858CE8F4E67084CB4895E06CC6FF17998D3427E094621945B85A6F2300368185C83B659A93F7B78ABD5C002B0C88CCEFBEA7E0CED0D2C3FD7DA031B9D784518A0EF80C9318EB6BD2E759EFBF51191F86FB56D0E21EA7D69C93E1D9A3C2FC83971B43DF0481EA7CF61370E3621F30CC001637E12A545DA4BAAE8BFD3323ABB9466A2C7E25E21E801CDCD70BC7F73DD709260C47B1F1A470A87EFE53678328B24500E24CD5C9F15E1AE93E3C6BE945EF0992A5158AD832DA2F1001711FEF5056EBD63C5109C98631E8A17B52D7406376FAAB37C053105CF519F416468B109084ACCF503FA44CE9C44BBEA5EED9455FBE2C50BED5251E341F478851216DB9F09EF887F8B96C80E26CA1974DF17883B1DEC957196324C590DE4D61A2366942F377B674F46B4A54DA027F566B5C98AEA38768B8FA5F0BA382393A60594175BCE985735D022D87B9061657467C0FC8E3B611859910DB30D709FA43C868F5CF8C9A4A22F9F00187644558E24DF8B960924D4DF5F65D9F52BA7777215EB24A534059371AF849A52A0E39A4D397434FEDABDE97C3E6C4D72C825F7E771C38C33B04606CAFA0C9AF7056D016ACA21F30B82303350FC5C13588AF07A0ED789D2668363E338060A079A488C5E9484227A4C369FA74C7764A52F80BBE1ED62B4A2408D879D7D800CC4F7309F1484AE7868BA62740728F430B4D2CF751F03697791148817D456A5105CB342B6D9D049D2FA2F9F55182E0B896E8B633039F4ECEC5D13C132C1BD2DFC86BAE61506E566F936AF2A78AC3E886C6CD4B1BBE1E741C58A951C11F1A1AC132366AE8D96587BFF6977A1CAF4A6C616887FD9A05ED65192B8ACEBD8EAEF0DE87EC999C3BB1E769AC74EC55E1CC0085AF11A5A902577D0E510AB649E4B6FDE199BF247D70DA42C36FDAEB60A1B02BB1CCF0A9451CCF7D1BD8A75956CEC512E4C75AD008B6B9AB1A61C273EADCF5D623EA7FE1D1F33EC3CD9511C3C5E564B222B447FBE86B4047AAA8059824E5608004FA8E12094BCD3BF0B1FCCDAF31D63E17385673F3BB98DCA65FF01893E873C1031D124DECFA1F62ADC4F3BCD579AC99D358DAFD0D310E1E474DF5D043B0AA14B6A2AAE95E3E03CA9AD5FE8127DDD3E477F92D447A0DD5AE7B4365EEDE0F1477B13CCE194662FEAA02D6792FB49F35FD009637314A194E0DEFB4BB18AB9466CC1D362398CEF4FB6EF3347CBA707AD7CFD119F0441BB69B097F83ACAD2B98780265A8C373D3C30F646FC179648B2007818E76C89F8392A9B54294F5B76692BAEFAF1A743DFD8DD9F47A6A398DB10400F5C62E274AE7EF6ED6C377FBF0584B5CD67AB66888D9CCE9484C9E230434720F7EC20D9BE4702470568371A641CFFDC357EB8FC523815FD2CC1CE242D2AC217E4F9985EE39D60FEB88985A4775935B4597ED706265371F35AAC3FBD65DB8EAA791842BEB02D451D3014C17632251E421D4ED198B7FE7EA360CE3542ECDD270735567A83B9CAD3B7056BFA76C432AF0703DAE6FD75165D80B02CD938F9F72A6859456F3682972DD16074C373330865C5DB50592F5E9D0E8890759DA198284AA2B2E1A84B2788DDB044A23E6946EDC12991E5BF1E98B1C3228F7E32E2F7FAA289352CD2553DCB814BCA7BC9C5D665D024D763693A16FB88D88C2E2618BF4E7AB21682A97F5F5020C23968DE756564AA23E60D9CC30EE93CB0F6FD9BCEF29136FFA72EB80550B2B629C0EF91FFBF47BCADDB0FBB72FDD60DCFE7115DC96066CA7BFFB63AA9BD12A590FD81845C9D5D20AB29BBB40BFF96D0881C4226F64D8F08C7C1A9EDAF5EA6E0CF172A0611698789AD1D71BABA5D4ED6E273423333805E14E622440C857FC81CBC8E6947EFABC313882423BFC989BDCA9F6BD315925025486163D24FD976C6883B5200A46B620B71DB8F0DDF299CD9BF160A0A97CF3AAB0DC1BF632E81FF75FDDD2A43113B77852E54757923B97C52FE22A013B876F7D8A0C70A2FA82C1589B626E0CE5C8E3A6767E0857BC64179467833AE87AB8DCF997B6443E4F43C84A00CE9BBA016642F8ABAB92AE8323B6AB0A3E6D7C9097FF59E90D266A90BAD4FD00334E6885978E92CC031E4BA3A40000000000000000000000000000000000000000000000000007091016191E304502200CC0D119C5F9AE1140B9ABE8920FDE77B5B86501FB690FD838354FAD9B9EBC88022100978A5BADC3B13576E2DA9043ED6DEE9600016EA7E60649244CF826A1007492FB +Result = VERIFY_ERROR + +# --- ML-DSA-65-Ed25519-SHA512 --- +PublicKeyRaw = COMP_ML_DSA_65_Ed25519_SHA512:ML-DSA-65-Ed25519-SHA512:9491EA15C863E26FA3C4BA30E00446CFF560AF06B486922B3CC813381C7A0E8B8F99D3B43FCF2E9C258C0ED1B864591102482191D5F3B0D4CDA97CCDC2CFCFCA90F8C3CEA5F8A38607F0EB00931964AFD8DE7762E8FF8640F6EC3AEFF2A1A1DB89214F6F5839E0F07D1763F1B4D8F622F0F05E6C7FF7AC1E230A5FFC580ACDB7B94BA000F3019F4BE079E58574FFFF8F976C4F3A21A3B3A7FE5E222BC22D5A2EC9B5B118D3D9952A9D71971B02B709B3850E74F2ADE47865196B095BD3018B6492110C65B0FB34C2FA1E10FA2E9C9101F766F0329CBDA4927A439D7F42883DD04943475FE414B95CEA16DD25334831E611AF0AE01DE3D31F157597480E31FDA971AB789A47E3CAEECC2FCFF944703628624BD8D9459264837919ADB9C13171104C27CCE420B1F7FB14E119BB5951D23E41AC6924481DB71948DDF1073816F99BDD68FEDEF9219CA9D57AF8A4D449994E3249DCDBEFD5A59FAFB8BF000147182909E7B20D33452916A60351C6D2A9B82899C29A127C5D8615DAEBE384EF67ACE94329BC12E873644CB42428CCCCFB917763823D09B826922F4709EC78967A203753D20DA38BFA45228D93757CECD529A27A60B200F4864D03D40F70C33975AF6D3BA770E03E6C26D7A6FE8D6C2B5911221904B6F45C7DD687AC6B8EADBA292131FDC58841A76263B97976B9A6FF7A0516459B9200BD3A18BAC07FD59D7ADC5DF1E830B259751877EAC0FC4BB6064C18D9E70410AA312A537799B7E1D9FCC532538600175D1EBA758ECA110AC7BDDAB5695E0C48A56EA6E02E602F9A1D090B712E0AF3D840811EF698CD3FAFB648A4D24CF4B7166549BE5C704725731624A247D69EDEA6026E2A294C75BBE0B3593CFABB8087BA3D00585C45F83FFF6FEB6018B1DE2E39A41FF3FC54459B846D0C720509CA032870FE1FB996A304828467749045C82B29790505295D4F4E929F0F3C7FF2FB49C0AA249C462B089D8B3EA942D1D805508705CB94FD8CC183B957C9A17D8BD97C081F0FA68526ABDE22940DF16C3AB72E96364F4E870B7E085A3BB50BFBBE8F7664EE4FD6730001D2DE8757FB0FB19FBDE26A04B45F2DF6EBFA3249976C636E3B51FD515C1004456295A257259C0F4EA51AD8F47D4783259AD39870D465C39C58AF0164AC2CEEA9A8E85CD8C16E67E9298C96398D0956D4859E731616B55873C5D2509510598AC04B2B9E7FD0051CE446D67A908D97A382A62E65E3D4FC4D4D4325B672E15C588392A24EEA01DEF6731ECE04A9BDB957842707BAF1037DD937C7CD15FC5E5250EF4243933C9F47F877C0E50004DF11472BD6A2D50711E098F3A7AFBE78A1BD958020C50BC2E78C8B2CCA141ADA70F662F488017F437960A7DD649F4FF9075149B0A83A9F48B8F38A3C7C7C4595C3156F977F37DA9062FBAA655D6A8E332BB358748C1212037C4C98A2AE667532BC95633943A4789DF2B3E4531A39A67EBE025BFE7B14155BBF61551BCDD88EB148F597D6FC5972E306DAB4A4D74F2132BB2DB83093BE9791F20F56410093D591830D8E67D78F18380F0A960B2905692EE66DF1F27E95313C3C4EBEFF33C9078D97BDE63A7510CAF31B1705D81FDB573690516B9D63FFAA1D8F559D6305C75A5BC85F4CB2786DA97FB9FED79A9E6B9B7F4B6EF42955D5D13A40F983F7BEE107BCCAAE9CB10C5E8458B5CFBC42418A1C6035320EE092D73B430662643C5B733A8C9376BB507AF33F5562C7B0676450F1AEA83531CA53C142F4D77D88E3A01C34C9BCA257EDB7F99C562DF2F52FB50ED7E9F53F53887BC373A26260C893AA9A6A1D40764DDDA8CC1F102649E3F520C8DCF439794C23CD047E0C216FA250243552FB73E937555B8E00EF0FC2DDE6710C7F25B55B6C4D9960BDB4DBC4588B93E2C3C2540C0376ABE9C6FB45DDCA1B64327A03531F31573ACF6D0BCD9A1A59E4A962B5AF4EF29F4DE5891567EACD80F575F9FBA578620D2AE54AF0656C3213A2E0312B2A0ED02255CE196CE45BFE88329318389E770951690DB2A5C2AECD38D2A6AB3794C2069559EFDBD7AE3892749D9F20DCA60D12E3D45EDFEDBDE106B5D9F1EC8353DB5601B22EEA34A9D0529ABF980641C51E24E996BEA818A7C1A9FAA3656302C275B208BC89B3296A8E76C746B81F9A9BA34D6220EDDEFBA816811DF54B8BC35BDC2B31330988D7556696BE0FC786985DDB4A9F1690F5E6AB09346FDB8E095F0D0A5EF8B88E5FA8C16A7C0DD2D0DC91407D998DF36A83733D4968E4EB695DAE309166B1F23503A420D76E8BEA55B4A5376323FFFB316B43CD36ADC5B009BD3099AE1184550612CED253D9A2EB51C80E62B98E88E1FA5690CAB676289A76E2246847339E3A1AA3B08E837D53DD60305E9BD8095F923C7EB0FB72332525017263927510DF9509CCCB06C651660DD97957A5057452406545114225082B00E0D65DB826D2BA3ABE2596149C909DFB086B6353C4B0B047B4F42FD29D35C73FAD6E50C81E09F2A16555088D933AD27C32C6AE005F734C5D37A4033FE3E14BEB2B26DFCAE7962A2889F1DC269876A67C52CA90D8DBA008EAD042739727C507AD85EDAB0213D46252999C0066A0F43CEE7FE4E7DF930C8ABFCA4F594C24CAA6C8EE35F2E2FC0E7ACCCEB30E35E4C452A8AF92FF6672F236964F7B0C03430572C2BEAFD3345FCF6718E51AEF30C60F4FAC9F9580CED1429E3FF3F08EB4499BAA86C6CD1413BF183AA8FF83AF3DFE7E221422FB16C255B2C479373FCEA0299242C814EA188183F83627B13C96303AE121C8DC1E1F1BADFCC83FFBD5D8504FDA + +# valid signature +Verify-Message-Public = ML-DSA-65-Ed25519-SHA512:COMP_ML_DSA_65_Ed25519_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 17187F0325BEBC35043816918D982F85C801256C591BB177B2B93E3101409FCE9ADA23721386A8E15A2B74376779E91B21645639994BEE8453746F8BCCE8DA11A8C3218C81A5B9E839645F26E7A2CEA71F6BD27486CF44F98CBCDC93D10E5C8B866E75D8F805F8DF6783C6F5DD3846A9DDB8C5168C560E09ECCDAC65E3C77CBB14468EFA310C32CCC2374AE0736A7D704327F11E3C5C74F1A8F3B8174019A4598A5BC7895B4AE7E07F68D27E5F76608B5B94A03237A0E4E5A53F54EC1BDDCA7BE5E33E4D2EC9A4A5FC1C88346E4523D8EAB0CA66EBD5AF0931B93B5BBC4C53E39C00545C023F9EEC9BB5F9380F1A6EC87C32AB8CB0FA0D5B3D3306787E7AF9467A3221558143EBDB3462FA1164631897356BB58705501B1C3ACDBF5A3A45BE9CC2718CBFEC015018761A7E1AD3F8E0201671EDB795585FB51303917ACC30B984478BABE6B489179268BB3DAF53713703CA34C0D45809C61A647B408C598E241DCB38FB6A0531CB27869C761F4724FFC5D34E0D2668CEFB4101E19A47794557403069DB8DA4D240F34EA35A2D1D234BFA4A7C4C82E23A809EA112B3CA94D17C9F3033DAE78AA033CDA616F587DD8CA381B7969C3240AF4B1D1B52E179DD5F672202E000E645C76055D8C04940E882F794A726927C48C485B90264E8E48BCB472B9FC996E360F8D4A486CE8C534A140CBB74B4BFE2D8DE2B788B182015052141DD6EAD5A4A0F422EE2EEC06698361BF1BD27D7230E9DA67ADF05E818C428A65B55983562E8673E22C845CF578531C0B6911A8E3C263A24A1963ADC0EEE73624F9307FDE76C20B3EA6FE0CB4044C382C2BA2A2D2AA06B491E049EB8234D27C14435C4B92172FA4AC9EAD1F19C72A4C1BC6A2C079790F38FECA5FC3A7CE8B6EC9EB61B6D5F8254834E947D2F535464BD8F2EDD4CB241CB456F6594839F27CAD65C9F838A4570F1861E5C87E227BCBE5AF22295DB3A3B0CD8275A2436211B420F39226049025451622C2FAC05BFBBDC2E901D3E538AA3C3EC06AA7A74EAF62441F7C479000C2537690B626EE4F6E4A64D9982DA6A76FCFEFC028E015C2DADA585E09A29E1F03D1C2A28B53D6C96D7F663C967FDFF315934A1CC996FF225D691102F4A0A9297295FFFF11A08096ACD42B6F4054493ED24D0DEFECB2784643BC9F1F303517D4DCF6309F847337C45C17C32A68795D516E93F15DDC1051F2F360D55F5651DB95FB504D88DF0409AD42F9E7015131C0F51C3E13FA242AC87330D4E2558FE79C497FD6E935DE37FFEFFAB9BA7DB6FD984D07AFDF5C4CF77EE7559A810CE3E8CC915265A1A7BAAF69F9620589832D8DF84AD89D1A4D6416A4322922AF2BD6E1B39E44A323F361526BA954DCC6E5E941C52AD37C9221CDE9765CD299B75C839255FC19A0C396B2BDC91AEEE9D4A66C736798F3B5AA07CD8DECBADEF7FE79DA169AB0B35150EDEF8AC1033921544BCCC2F79DFDCD67D0154A2BA4CB960CC52355340F0236F7062206ABA53087804CE447002EA8151344E02424FDF816C49728FAB00A3C59BFD7A4B9793FA235252113043B0D172B16E118F80A3C9DE815271AB93CC5E188A235314D36805A183049908BE0EB88730B0107AB2A5509D8FEDE711C8E0B2F93113940B326891F0943AE541B00456720789DCC82C73234475BAAA310F676C806229ECD25DA7FEC86C4306700FCB13F87F326B826278EB68D0AA48D671E7B6F33DBB846025A4019C87AE3D66D031809763FE9A874FCBE3E82722B9BAC8CE06EA5DEFA2FBA9A949EB58EF6DDCC2170130E8698BBE89215DD6260D132ECF3CB5655E8B6DE73B3D4CC4DD94C2598679F012BDA38AEC2F5E83D5E86AF8FC22D45F3C343764A8E271F005B0DE4967AAF430952772A7ADFFE6321BA738D2BCD4D663D379C148AB84B703D92A1B5156E81328D4A1F3C14C5E7CA673E6F134DC9D8465BAE9F070F9D00550E3C387D1D8008052A4BB8F1C13B1B0777EE5E00B95E7778239D21E1F7DD2D4E57DCE1E046D2771C90E4232A7F4C59E8D4E112F275CD275A1B0ACC9FF3162722C79987FDC8D4A1AB3A7A38543CFFDEE7AB32EC54E7A8AE95FE767F97D6DF09DA668E49FA8A2D625E92D5CC394F8D48C11B066A1B834EE3E844CEA3BD0A63E4EA612B8CBBFF0F0C4B00E20ADA00EBF70EC4780B78DA433CA68A0B2BF1701A24F9B3CE9DE503704B7817B081A3CE49181B7B8F35A3B20FF9941F65E72E8D1623E656E98C0853067DD17204FDCBE8253F88F9BFAF4650B3E6EB9B1120140EFD8DF4B4ABC599112BE90F2491972682CCFEF27A7997CD507D34136FEDF3FC13857961E13F9678C3B9413A3849BD350975B3A54A57466C31C4B9BBD9DB992D5A367B00E552E95AD4804C53850E3C8CE0849435638D653D7D276DD9B8C42FE965501832DE56BEB1D62FDB00FC0E8427B444A50F1EF16351673F34E140EBF6875E705D8EEB92D22994D3D37EB652A89B570B039006B6A5AC67EB696E480B82DA389C2C27570606B92B3D871A371C6685308B4B00334C2D61EFF9704BA5CCE400BB562BBCDA09A48EC0948218BA411EB3246FCA46C61BD88BE51AB495CB56934D09F08FEEEF03A7C496D0C233E7472360F7CF02D9F1042D1F2E017776294D3E277CCAEEDAB1350B3500DF62A8626E39B1168FD1F4151739A50DEC96863E1C1BCA11CCB7B33FF60A0330A6AB7F9B93689CBBD022E89B6CABADDB147E9A86B862824EE78A8A9C15633D71D9CB682581548B3096DC31F0DFC8DFA924A5A5EB86FDC79175F43FF05022F416EC10D35B8B0ABB37760EE371F3173B3C7AF06573037BC1071A1AB69B026671D53479DAF873E19A89CD6990F5EAE9EC259A90E4A17974A7AA272B38782FB0B0430FD3EC34BFB1F64DAD176CB2BA827E7A14D7815CD0810281D59909344399CB98FE59BFBC6623220C4BB2EABE9DB26FA1872B69F642FDBEB4A61B2047EAFA5E0520CA7CFF6C7BB5C682A010D9E8D00C69E96B934D13A640D551721AB8D550135A26CB3B7FE30135EA7F3A6278EE0A1BC2FAC2E4127B6C68012728700DA88CCF0FF59E33FF4B01227371E765B9FA9B180DA280ADFCB701C9D6F0701ED68A098C7A0B3A10BCE87A4B2757C510F884C1E9AD294152DBFBEA6C6D07111E06483C8812CD561984553AA3EF406BB32BE8281A7B0CC8AF8169FFF2F1B916267494B009C11FF8F4CA4C14A183C9F826B3BC566C19AE9A16079702032931FEC10D0353E455732276E044CC6EB3CBF010E313AFFB663FF16B7991B9604E624929779EBD7EE13F9545A8862650FB7500835E0994CB05BCD2D301DD4364F851FC6EA5A8DCBF7DEE8D6277D41CCFAA6C97386990ABBEC6738BDFFBE75CADCE6C4A084A9ABA37885420E398A83A0597ECF110164340156216F8D8C0009D3B768AA82BB52531963BAE6856479E3B4CB9BA243B9109BD0CC64E0D920F68581161BA5D156730558A3330C70D540B6C3BE7F75CE7BCC34005764CA74596C3851AC7005AD2EDC07881E7960EACC6814D8B3F5671A180BB6B6B1C382374ED70B029B1BA5BA7C7398E90120EDD56AB73B72DBD3B48D74C9609F80C2474D71F86824DBBAD508801C3D8C5DBE49932EAF3BEBCA03968E109A7B0F0FA29549DF6D175333AB29882217D431FC5859474F7BD9AB4EAB9D8774E0E5FD65F2DAD936AF33F52CD1D6872D0AE7D17089436E6D66B7ABB653674B1A180F5CD1ED906D818073D32030A5C1F66B61B8B75AED5DF912133F3001C467EF1093BE4660FBB711FF3F9C9CC461D2462A588DB5A158FA2519BAD58B36E30441C21CB919814611479C8FFBE5A9024AA236BFA2717B59F887F4F336AA6C0BCB2167B7B0B0954D0D0F31B9CCAC50F8EA56143AA4D321C9D7544A8F9A8C99BD64E5C75D39A018E4B876D15A8C8EF94001F1CB310C3C283B00C4D0D49395D923AD82A04ED4C844289202D86E3A6425B431392545D43E5607037B965DE33BF2DEA607BFF27970ACBC3A22D9FFDD01351F3F7A1D73C9C446F412C40F99CD273A5765998A81B4EB7C83DD1ED8E8E149EFDE75EF9F9EFFC7E14A7A071B94C3E55197A6426C52174398EAFF7DF875D0EC8FAC618D2D2BD8FC2F5BF35245289F050109AD3E850C7A7A583B38C27684B4C114FF2449D23ECBBA8DD139D8D122FA7909B56B230190AFE0789A4CC8A007A5430CF161D1D302605B3DA4B8114D6D3E860ED1777FDBEA53BF9AF4D9AECDC522C620C8CC49C503229E37448520391E8C891AA6301CAC5B9644DF250ACD928F3C21E8B4394DDBF702174EE5B80D87D69150B5988D7AA4D399152D9C6FE8E36E5A13585918551B6C310667BD905DAEE8F2B16C5F328E67E44DD9FFA55CB240A811CE50A654F5F442ED1B1408D79A181CD65CD0601902316AEF225379E3E6B617137BD6C3042EA7FACFD70954F29242DE49CE04C8387CA06250AD42A675C329EC0BF06CC276244F5E65259B0F6B3E8C431889C26391E17B97843AC8D690FA056924D4501FCC19C84B4B0F560134CAAAA1C682F65A5550A9FD3569AE3790DA191F01C4D1F4899F29E4E2045C06C8A75879B0FC0822D36972B4D75D3FA3D42AC35138679165AABEF805C92EBC1A3B6D8DADD904072D3132353D4F9EB9142C4A76161B58E00102131F72B9BECBCFD1D9FD0E3965798EB4D1D9EE0000000000000000000006101418242D4BE430A76BB7184A93BE676EC1F2A2A7AAAC46DC75087C90F4CAD5ED5DCE888DE46FB37DF48A861072DE770367CE90A16EEFC48CB5B580D7A19B46D21AF94A05 + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-65-Ed25519-SHA512:COMP_ML_DSA_65_Ed25519_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 16187F0325BEBC35043816918D982F85C801256C591BB177B2B93E3101409FCE9ADA23721386A8E15A2B74376779E91B21645639994BEE8453746F8BCCE8DA11A8C3218C81A5B9E839645F26E7A2CEA71F6BD27486CF44F98CBCDC93D10E5C8B866E75D8F805F8DF6783C6F5DD3846A9DDB8C5168C560E09ECCDAC65E3C77CBB14468EFA310C32CCC2374AE0736A7D704327F11E3C5C74F1A8F3B8174019A4598A5BC7895B4AE7E07F68D27E5F76608B5B94A03237A0E4E5A53F54EC1BDDCA7BE5E33E4D2EC9A4A5FC1C88346E4523D8EAB0CA66EBD5AF0931B93B5BBC4C53E39C00545C023F9EEC9BB5F9380F1A6EC87C32AB8CB0FA0D5B3D3306787E7AF9467A3221558143EBDB3462FA1164631897356BB58705501B1C3ACDBF5A3A45BE9CC2718CBFEC015018761A7E1AD3F8E0201671EDB795585FB51303917ACC30B984478BABE6B489179268BB3DAF53713703CA34C0D45809C61A647B408C598E241DCB38FB6A0531CB27869C761F4724FFC5D34E0D2668CEFB4101E19A47794557403069DB8DA4D240F34EA35A2D1D234BFA4A7C4C82E23A809EA112B3CA94D17C9F3033DAE78AA033CDA616F587DD8CA381B7969C3240AF4B1D1B52E179DD5F672202E000E645C76055D8C04940E882F794A726927C48C485B90264E8E48BCB472B9FC996E360F8D4A486CE8C534A140CBB74B4BFE2D8DE2B788B182015052141DD6EAD5A4A0F422EE2EEC06698361BF1BD27D7230E9DA67ADF05E818C428A65B55983562E8673E22C845CF578531C0B6911A8E3C263A24A1963ADC0EEE73624F9307FDE76C20B3EA6FE0CB4044C382C2BA2A2D2AA06B491E049EB8234D27C14435C4B92172FA4AC9EAD1F19C72A4C1BC6A2C079790F38FECA5FC3A7CE8B6EC9EB61B6D5F8254834E947D2F535464BD8F2EDD4CB241CB456F6594839F27CAD65C9F838A4570F1861E5C87E227BCBE5AF22295DB3A3B0CD8275A2436211B420F39226049025451622C2FAC05BFBBDC2E901D3E538AA3C3EC06AA7A74EAF62441F7C479000C2537690B626EE4F6E4A64D9982DA6A76FCFEFC028E015C2DADA585E09A29E1F03D1C2A28B53D6C96D7F663C967FDFF315934A1CC996FF225D691102F4A0A9297295FFFF11A08096ACD42B6F4054493ED24D0DEFECB2784643BC9F1F303517D4DCF6309F847337C45C17C32A68795D516E93F15DDC1051F2F360D55F5651DB95FB504D88DF0409AD42F9E7015131C0F51C3E13FA242AC87330D4E2558FE79C497FD6E935DE37FFEFFAB9BA7DB6FD984D07AFDF5C4CF77EE7559A810CE3E8CC915265A1A7BAAF69F9620589832D8DF84AD89D1A4D6416A4322922AF2BD6E1B39E44A323F361526BA954DCC6E5E941C52AD37C9221CDE9765CD299B75C839255FC19A0C396B2BDC91AEEE9D4A66C736798F3B5AA07CD8DECBADEF7FE79DA169AB0B35150EDEF8AC1033921544BCCC2F79DFDCD67D0154A2BA4CB960CC52355340F0236F7062206ABA53087804CE447002EA8151344E02424FDF816C49728FAB00A3C59BFD7A4B9793FA235252113043B0D172B16E118F80A3C9DE815271AB93CC5E188A235314D36805A183049908BE0EB88730B0107AB2A5509D8FEDE711C8E0B2F93113940B326891F0943AE541B00456720789DCC82C73234475BAAA310F676C806229ECD25DA7FEC86C4306700FCB13F87F326B826278EB68D0AA48D671E7B6F33DBB846025A4019C87AE3D66D031809763FE9A874FCBE3E82722B9BAC8CE06EA5DEFA2FBA9A949EB58EF6DDCC2170130E8698BBE89215DD6260D132ECF3CB5655E8B6DE73B3D4CC4DD94C2598679F012BDA38AEC2F5E83D5E86AF8FC22D45F3C343764A8E271F005B0DE4967AAF430952772A7ADFFE6321BA738D2BCD4D663D379C148AB84B703D92A1B5156E81328D4A1F3C14C5E7CA673E6F134DC9D8465BAE9F070F9D00550E3C387D1D8008052A4BB8F1C13B1B0777EE5E00B95E7778239D21E1F7DD2D4E57DCE1E046D2771C90E4232A7F4C59E8D4E112F275CD275A1B0ACC9FF3162722C79987FDC8D4A1AB3A7A38543CFFDEE7AB32EC54E7A8AE95FE767F97D6DF09DA668E49FA8A2D625E92D5CC394F8D48C11B066A1B834EE3E844CEA3BD0A63E4EA612B8CBBFF0F0C4B00E20ADA00EBF70EC4780B78DA433CA68A0B2BF1701A24F9B3CE9DE503704B7817B081A3CE49181B7B8F35A3B20FF9941F65E72E8D1623E656E98C0853067DD17204FDCBE8253F88F9BFAF4650B3E6EB9B1120140EFD8DF4B4ABC599112BE90F2491972682CCFEF27A7997CD507D34136FEDF3FC13857961E13F9678C3B9413A3849BD350975B3A54A57466C31C4B9BBD9DB992D5A367B00E552E95AD4804C53850E3C8CE0849435638D653D7D276DD9B8C42FE965501832DE56BEB1D62FDB00FC0E8427B444A50F1EF16351673F34E140EBF6875E705D8EEB92D22994D3D37EB652A89B570B039006B6A5AC67EB696E480B82DA389C2C27570606B92B3D871A371C6685308B4B00334C2D61EFF9704BA5CCE400BB562BBCDA09A48EC0948218BA411EB3246FCA46C61BD88BE51AB495CB56934D09F08FEEEF03A7C496D0C233E7472360F7CF02D9F1042D1F2E017776294D3E277CCAEEDAB1350B3500DF62A8626E39B1168FD1F4151739A50DEC96863E1C1BCA11CCB7B33FF60A0330A6AB7F9B93689CBBD022E89B6CABADDB147E9A86B862824EE78A8A9C15633D71D9CB682581548B3096DC31F0DFC8DFA924A5A5EB86FDC79175F43FF05022F416EC10D35B8B0ABB37760EE371F3173B3C7AF06573037BC1071A1AB69B026671D53479DAF873E19A89CD6990F5EAE9EC259A90E4A17974A7AA272B38782FB0B0430FD3EC34BFB1F64DAD176CB2BA827E7A14D7815CD0810281D59909344399CB98FE59BFBC6623220C4BB2EABE9DB26FA1872B69F642FDBEB4A61B2047EAFA5E0520CA7CFF6C7BB5C682A010D9E8D00C69E96B934D13A640D551721AB8D550135A26CB3B7FE30135EA7F3A6278EE0A1BC2FAC2E4127B6C68012728700DA88CCF0FF59E33FF4B01227371E765B9FA9B180DA280ADFCB701C9D6F0701ED68A098C7A0B3A10BCE87A4B2757C510F884C1E9AD294152DBFBEA6C6D07111E06483C8812CD561984553AA3EF406BB32BE8281A7B0CC8AF8169FFF2F1B916267494B009C11FF8F4CA4C14A183C9F826B3BC566C19AE9A16079702032931FEC10D0353E455732276E044CC6EB3CBF010E313AFFB663FF16B7991B9604E624929779EBD7EE13F9545A8862650FB7500835E0994CB05BCD2D301DD4364F851FC6EA5A8DCBF7DEE8D6277D41CCFAA6C97386990ABBEC6738BDFFBE75CADCE6C4A084A9ABA37885420E398A83A0597ECF110164340156216F8D8C0009D3B768AA82BB52531963BAE6856479E3B4CB9BA243B9109BD0CC64E0D920F68581161BA5D156730558A3330C70D540B6C3BE7F75CE7BCC34005764CA74596C3851AC7005AD2EDC07881E7960EACC6814D8B3F5671A180BB6B6B1C382374ED70B029B1BA5BA7C7398E90120EDD56AB73B72DBD3B48D74C9609F80C2474D71F86824DBBAD508801C3D8C5DBE49932EAF3BEBCA03968E109A7B0F0FA29549DF6D175333AB29882217D431FC5859474F7BD9AB4EAB9D8774E0E5FD65F2DAD936AF33F52CD1D6872D0AE7D17089436E6D66B7ABB653674B1A180F5CD1ED906D818073D32030A5C1F66B61B8B75AED5DF912133F3001C467EF1093BE4660FBB711FF3F9C9CC461D2462A588DB5A158FA2519BAD58B36E30441C21CB919814611479C8FFBE5A9024AA236BFA2717B59F887F4F336AA6C0BCB2167B7B0B0954D0D0F31B9CCAC50F8EA56143AA4D321C9D7544A8F9A8C99BD64E5C75D39A018E4B876D15A8C8EF94001F1CB310C3C283B00C4D0D49395D923AD82A04ED4C844289202D86E3A6425B431392545D43E5607037B965DE33BF2DEA607BFF27970ACBC3A22D9FFDD01351F3F7A1D73C9C446F412C40F99CD273A5765998A81B4EB7C83DD1ED8E8E149EFDE75EF9F9EFFC7E14A7A071B94C3E55197A6426C52174398EAFF7DF875D0EC8FAC618D2D2BD8FC2F5BF35245289F050109AD3E850C7A7A583B38C27684B4C114FF2449D23ECBBA8DD139D8D122FA7909B56B230190AFE0789A4CC8A007A5430CF161D1D302605B3DA4B8114D6D3E860ED1777FDBEA53BF9AF4D9AECDC522C620C8CC49C503229E37448520391E8C891AA6301CAC5B9644DF250ACD928F3C21E8B4394DDBF702174EE5B80D87D69150B5988D7AA4D399152D9C6FE8E36E5A13585918551B6C310667BD905DAEE8F2B16C5F328E67E44DD9FFA55CB240A811CE50A654F5F442ED1B1408D79A181CD65CD0601902316AEF225379E3E6B617137BD6C3042EA7FACFD70954F29242DE49CE04C8387CA06250AD42A675C329EC0BF06CC276244F5E65259B0F6B3E8C431889C26391E17B97843AC8D690FA056924D4501FCC19C84B4B0F560134CAAAA1C682F65A5550A9FD3569AE3790DA191F01C4D1F4899F29E4E2045C06C8A75879B0FC0822D36972B4D75D3FA3D42AC35138679165AABEF805C92EBC1A3B6D8DADD904072D3132353D4F9EB9142C4A76161B58E00102131F72B9BECBCFD1D9FD0E3965798EB4D1D9EE0000000000000000000006101418242D4BE430A76BB7184A93BE676EC1F2A2A7AAAC46DC75087C90F4CAD5ED5DCE888DE46FB37DF48A861072DE770367CE90A16EEFC48CB5B580D7A19B46D21AF94A05 +Result = VERIFY_ERROR + +# --- ML-DSA-87-ECDSA-P384-SHA512 --- +PublicKeyRaw = COMP_ML_DSA_87_ECDSA_P384_SHA512:ML-DSA-87-ECDSA-P384-SHA512:549DE643B930A7355321FF63321DE9448D72F9B69430555F9BD7331C327FCAA57D9BBF7B1BF011BCD5C315FFACD6C66BE6F10C85A6387CF6D55C4AF0A9486FC24810DBAB0AE7ED2BEAFDB52B3E7F0AF5F8A74D27B533D8CF371B876911D3C6A8C7902F342DA753FCCD8A6D8627B772EB2EF9CC5C970CA5E6CF48113A66165AEA68D428D362F596029BF6B513F9782D316F5DA15248C934588F43315CFF7385146A31DA68A0EFD352C07B1DF7C9C76665D366CD48A13C959D6446F2AD6A9976AAFFA45F856386FB6F981C4015503385519057A4CE203239AECC1C75D4B894E8CB945C3EDBE66CA3813BD4E7998288769EF28069C236F3CDCFC9D364A30B09F50792A8EE6AF3130B6124C2803A043A0F42D73CE12DFB545E9E1A91743B777EFA756EE1DD566530863F4841F674C89131BA0178C3839194D5ABCCCC203B75E1C126D3833928FF78DEA9E8E755F8BF3810522C712AD68856EECD78C3B256A20FF4DE78ED2052EF3B71ECA03DCB4590F30269E984FEE237A348DAAEA8BECD0AB61C5AA862C0F1BDF4DE5AB9440E580E5A801BBFF64FEC9150564290C4051AE862A5D13E541E98DC10C0122EAFC1DAC5230CFED72F329353E668934E73363EFF2978321DA2A2C4696E33C4A106C1646E0A80225BE31A48C3542456DD6CB422CB7FB766106BA07724D3AC24CB5A14479C0336AED78D1A37BCB135B30DE3BA8C42D168149C6581DA1F6801A3500662F77402525159A3598812A2509652CE3B910D23FB139A6ABC42C02AE1720217BD140DEBC2DB3507F03E70F923D6E5EF462D53223E195F4B84380CEC79869F45F59265B73E8B973B86A720C05C53A074F53DDC6DA471927950C0144938B53610AC16A20DABE5D61B7B36B9644C05AC91F6A5105DE892ED35A1DDF98DFAADD30280AC638B20B077FE9C39EC1FE1616B242486A44CF2D0FA19F08B228BB24E50D9FD3537730E1FF31CD8F35EC3C12786530E732F43E1A768037249D8EB0B1D8BD10AAAD089437845B03ADF53F7249367F53C361A813B0545F504A954706DF5018A219D9A82731D2F77E3A0CB60295F6C6753825E22316DEEF05342CD55446A488D977349519CC5D7D95C82E3D9384D7B3CDE747F1B8B48466CACEC00E62592E9270B0268AA3C70F3F4130B336D338BF1C4197DA92B3A88EDAD2F0BA4E731B84DBAC11652E35166687D96D6F2B7BBD9AA612F75BC59CA1B93FE55DA6B7B0794006FA68BC8C6F3BE77BCA4F68B2EFB4EDE3E1E693A58DBBFF319E91E2B2331B53B7C162C2879F0088791EC782ACD728D9ED39F83BB5A2CD2AE448E9832303EEDF027AC9F97014545DC72A763EBDF8FDE8532D7D196675A0E6187D095B0CC9DFBDBC6C456F7DDE6A72B5A564A51E0E0E21C7D10B62936A243516FB12847675840B4429D3AA64E518B94740752E56688CC637A7C99EFE7F60D6D039B51041B3CC8F101028BF6E8BC15FC456B0CAD1D764E77351E4C5F85880691A9F22738026C4566FFC4C892F8EC1CC1D07CBB140A6D4D5EBC0FDF26458525A15EB09D9D13EA0371BDE6BCFE17F85FC2A2FBD48DD406EA5CBCFC746AC3E72A17A7F9D2DD25588F5367B02E54CDBAFEA0430817CB94ECEBFE559DFB788E4F84C43D5BA50FD36AA2E16ABBBD21773A2DCD1CD168F3384590142764B51423C3BEC27D9E1721B8BE97A766DC66D7422F4D48FED10D4730FE514276B1E2205848884EBC1D8B6D655BA3E73620E9E935FE415D8130E428E4C428747537571CF3D598A9B226C12C62AE4047848C66DAA21920731AEE6AC93244C6D85B0D6DD632BF011E7E5ED768DA9EB1A63A09A066681561E8182D250AAF8C6ABA2E08BCBED3BA50976E57DB4B22A8CA88D7D80C29A55598EE4206E56D25B5DC712412ABBC05CEFB2EE1EDF63C2ECC6227A2F4DC060A0ECEAD185CCBEDD55DE9DD785F36EA736C4A4418F1691D4E9C02EDBF5FD9650EA345F20D4C98A80E96958EEC59894A19B4C5146E5405C5BF90FD0ABF582637F9E0448B555F8BA4C67270FE594439B001DC0AB98236A117D90B3B60F193A74A90B15F2556AB3344130A103F0032148B7785743986B8D38924CD42FA26E395821F7965CC225A8661155CB88A9703B72BACC3CB7B2A9468D54F457607D6D4E5E402FC8EA2FA66331B8DC888A5D91BCF7BEFEB9791B3AFFCB45B748430BC28A8222F6A9822ECA2080149F02BCB8A0BF923AA3A98231EABE744665ECBA21264EFB0528922F9076B1E1D7D98757EAE550440D2923792A8B0B560CE937B0FC954C342062416784473D566111CF4711DE0AC277BFAEA3FCC3C8F8E8C995BFB98FE08754ECAA016E4C0630A877C19FF432AC0445F4729C06921BD1D025054F73BA064287D3E85CA987C0C86E0C98A715C7DF5D3F5A6744250B5DB1CFD0E480EDF5203D4AE098CDB5A9FBED394879BBCEEF4C2D09BA0EF573867E8AB3091DE3595E336A61A7A866C948082130B23BD3564E0A57350FC020EF389F48F274B40E6FFA5600FD5C1C0382DCA4FBB8AEFD5AB08DAC11E122B0CAE79C335C0AE27CB7EB128AB9B9E02F36BAFC255A37156A9F995472FEC5F1596F4BCB70D305B65CAE196889FDA0D8F5D4D1FD80EF7B19F23D20C7008956E7F0400E9CF8E394C2F99333B8FD14AD983CC983EDD78BF6640617373C2023F6CEB8522B28B798C3770E8FE4598802CB7BDE0826251251AE4CBA31D28C50ABF9E39CF87E8C76BBB12CD161E88DB17E4AB5F79E7134AC51FAE2FDFF7201B57B9D9638435714D81A68B465A84A5B6950C0C29BE2A9AB92187F1EF4849A4E4AD81E2D5E8E87170E476C23401A7862F725D6B54120260287B2D3D1FA1283F247B47408B18BD3D7D65127D5EDEA7AA5A97E11FA8AE1ED23A542C31D94BEFB41B0ADB57A8F7DC3FB18AFB5E3F9E97D37C1566826F1395A76B22CD760D6402F25A92595F965B210EF531FF11959E3AE04D6C9E26A3D600EEAF5F92AFB1589A9EE51F1F41AA955F80072D048F2DD2C6218DC241EE48308AEC643EF0604B65C12A77A8EFAB3D5C01A20BF3FB049A6E42F71E7FDB0698E86A150BD5675E43F0185C59A41EA4F745D8D20EEFCA9824921E2A8BFE5F8CBE7A651CC25FCCD22346285F5990C4E5690E2067BD5F4DCA20EBBCEE70F7F89D66B6AD8E678209029E8303D05C997E79886D45CACA84B42F2A112525CDF97B1BFC463FC587CD9DE6F5BD1880929120229C665C62989980A543C8C1A3248019793F289ACBE8DCD0A1E4F262DD4306DB4A4F97AC01CF03960FF48A32294937FA7368540877340202A4EBB72A303BDC37A9A48C402A36E48CD37141628FAC32376E28198B56550B18D0EE06CE8718901D4B30693D73D0FB7A5621A25D41FBA9FE10F4BEA7F4E4B6C3904B6679618AEF1B8D7B2250871AF6BE3D659D8DF314B77A9BFD25929205E6ACDE9FBAD8EFA5414CBC6520830B57F1CCED53E05994A187ADA4ABB464BB079DD9B7C57479EABD8C0118D4436DAD6211112BFDAF2B609FC3DCB49C17FFD0F2D5421C68339933AEBC8C8666120EE244D4EDDBF4C82060F1C475AC624AEE6F1B91E7E46B5381B9DB64D95D7A2C9DB34F017121DA8CFB12387BD7850E359E4DF5D8D7177B9229B4BABBEC85A77DAFD23F2274041004443F27CAD72F33DC9E305A94AAB491E5CE57532EF07B14F304F2CF94FB86CF326B32BA08096B20E49C4224E5407A6A3EEDC326C4A1CAF80A830B183AA86FA6FA0A4351210A470EA013950D89061EF6B235E21320AC266DD348A4131F80CCE502F756C3FEA40B7B4DA118544FA98509793FD3F14E40ADC6A9EB + +# valid signature +Verify-Message-Public = ML-DSA-87-ECDSA-P384-SHA512:COMP_ML_DSA_87_ECDSA_P384_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = C7CB5AF53216EFE01BC23F0E2295BA73624283B69DFE80583038A66AECBFD2FD10BBD55940C5960BD5C818CAD4D90F6B7CD9674D78141F1AC93C1C92CF66134C1A6B0B51B09F6E675D2C0F503D881E115E2A8FC018E70D8B1504ACF7391AC77BDA2960E294F85974736081497CB7930108D8EF78CBC3AED9DAD222C49D7327807A558E26AF6E507DFF734E08579EDB8621C23F1D4889B5830DA857C4A1C79E5CB80B568DD97D6FC92B733FAD9BD92F1A622BE12112E2D3F6D94CD74278F55DD27A41BB907D46E7A4F69393CDEC036F79058044E85EE6357D8D39D7A398C104486912688DF2B2EFC295893F77C01DB11C424A3F265BF805AB17114C6AC3B2AC8DAD4F545CCC46B7B328E4BC77AECC5788C8950833A666DBE16CBB2B3A7A086FC4C2E364621C5B834D8518E6BC7390B3DF4C20D094E87593D308E93569B2D44FCDED577B17B66FE9B9AFAC99E57B035C4BA32C79351BA50234668339DEBC67A6A7C0F980847797D7A22F47660FDBEA0D9771A2BF2579411728D20B1713E9B51D55BC3DFA1F36122A3B4A755E1EBC83EB0537684FF561E81A2ED06EDCF4E8004DBB0DA940AF79E1BCDE4A0C180030CA28E5FD026D1201B5A6C8A1A0E0213AE53D2F9D93FBE2BB45E342850CA83649293981E8F02AFFAC0B15FD379352F22536167943FB180CF05A4B4DDFB08642AE9F678405CC4C1138DDBADA07B168BD6C92ED76E37998BDE78026C302F7F073BB8789A4ED36F95C369089CF779E884138BAD4C33668FC660D0440CDC0DC61EAC77BD5657DF9D48C810263E713D402C850D68ADDAF2644DB0B3259E80838B7FA8726D9AC9EE3613B81560F847B65D407C232470F2F5E7ED1F43F9F3F592552CAF3E6B4077F656F5EFA422903E23F0241976F6264B4267B341403CE501BE74C86DF24076FF73DB3B7A3F9EAA96FC841041F54D62CCBCCF3619761B93DABC18E60AE6210491FFA07917AD9D4363BF08B1B1F510B43A94332CF771A960A6FEE35FA1F1F747BC266E6BBC10522B2DE89C64C039349ED87DA661A57AB114D52710A439143C154C82CF07EE112F601A34F05196D6F64D66908C86028FB09B08FC123A1268285F9FFE19CE48948B23E2A050B1296E7902CB714546A661633111095BA3AD11E27387EA951DC3F6A18FB9FD9B870ABEC2834023B84084AE3600A84CC7F0427B00BD1B5D9ABF84942A24F8217E58C12DEBD2C1BFECAA6FBA722146EB92B856908DD7C09E04776CBEAB7BA74C7549CCD1B66BB04FBED8FF8C5375BE929CC46B7CE3B3660274F69AE1D474F13DE4CBAE2C1E4613335A945751C1A0E23E8055701A057D80FB22501C06F31965ED571BC1C49E5DC0BFFD77F6A422C42452F2263BF25329DEB4993FCFA8FA208F867B4625F13E5D41AC4AEEAC88402D4D00D629613FC7B79F2E4CED0C1071DA1167016530FCB8736E4EF21587B5DEF26D4619022E18BB4A1C22EB96DAD2CEF76E4F486B64FDCA6887F0BA0989959E1B30ED0E9E93780E45D05347B9811303B5FD4AE7B7613D75BDDFFFEA908E43277EC8EABDF1C126FF81940FD16B074468D4F6922003665610CCD5E16268D118DD473466A6DCEF8AD1674C71279CBCD4BBEEB01AD0974B8CD2B83F92495B7987BE610369A5D312CB246D9C95B7000C4331A4564AA2FE7137369DFDEA7BD454BE6B1B4CF21464B6E74D4B01FF9D09137F334263B0852E9B833EA2A62D2A9BF1A8ED246B533444A153884E0E622AE762181C15D06D512F1430DBF5D5DD57B18A333998956B8517F2EBC38DD1F92EE53BCDBCB6ECEF8897C3E23D2DDCCA82A1F3F2AABDD98F5273862E4097BE0E82A51F8994EC40E8F58DD1256887D21D146BA3423C10BA55B2E32974CFADFFE09742ADB5F3E74EAD3FE54E008AA53A706A53E745314BA4616DE8BCC6DC79807A4A47D395812A7F60576A77C3A4E61E75041303FA181323F4DB05213C5059CD98DB68C5BF76F51BF5903659991DF4FD1D877666993C3B4866CBE2D037C6D6A87BAB96CBD954F8CD7772B6FD01C73AA7997B577368BCD5C1EEFB1EA1C4C031DC80A08134D7EF29CC79C09B934FC2F239B050D0D04990F837400C76FC62ED1E928B34F96758D7B00912F030C5AAB353636BDC258D6ED1290CEB77FED67B07D6AC4E0B02A94DBA60040FEA5B9972DFD9111EA4850B0BEF808EC602F46EC058E9F33D07EB418C20C18724A04CBA46878965EBF0FB88AD2578332994CFD162E7D1AD58FDCC4C7B34495E8421ED5FE860FEAD21BEEDD94DA53258A52479C0C06AB29334ECCC4897DA8D3630057B76E9E3A1640E0EFCC35EB46053CA3C099C1C729F1214FF8F30DE3362BC9E218F326FC837EA5F150BC33D901A0D75CFA384620603348C8D106AAD73C04084E3450F796244307565E26F170A9FB665F4C409F863B34594AA65830A6010950866C953A28CCCC64C9C27D8DFBFD3E1AE2FFEC3872380AA04B50752E6F8DED80C96C75881B4045482FB8F07367D2EDD5F71ABD7B9922E8004C62F43DFB77D34E0C9128CD5AE1561A594651DC704A45AD10AB208CC3CD7ACAE8F591A5E64AD3E6A88FBEC5EBF95C964EE61243D5291204AAC1A9FE6B696CAC6938AFEFFE6355C2C37E95431EBE324B070AA8A060175BD5E558D62EA1DF7F2D84A4EB1E0D95871F15696A435F90A6B6402F06E91A7A89640A97AB5A867860E87BD538D4F1F3E2DDC9C9C6D90054C60380CD3BC7C361E7109CFE2CB98B55262FC480E0D9B9314731DF9169A7545EF5EC957067E3A96585E843505E798F306EFCD7FDDEC2BC5AC170DEAD7E25F7B3C2CA70330C1C461A57455AA1DE20C332508DBC8E5A97E5688B275392CF4171AC4BCD101EE82DAE3758DEC9EBEBFB7211B2D341945986F8C4FC314459201C64C59EFA230C8A5C0DB92297A4B0CC69ED75A1F4FD8E9EC2F6FBF3EC9A7D4716F8F796B85F45791D99E61FDBB38FC5422CF6C1AD1EFE8BD94BB050E102F348282352D4AB1D57209BCB539A33FCBCF26D7B93DBB40D1F7683A38638001198EE8D62DC00C78F791A306A93359273D8D7A1746DFBD99D394321232DC3FEC584A4A888514C5C28223409E2C853C6F7492CA7DCECA90DB051F00F730DEE82C486543DF2F0128E8C1869CC82BAB2DB09C1768875A434BB2EE1F141B320785E93B26F70C9699A8C68ECE9DAA0A4900393DF6CA2BBEEA6E4D3EC94A4E68EAA87717FBC109D2FB9E402FC21D6D5DB41CD8D78590491167D669BFF1E272DC4933A3B6DD26025E3B85F8290A60599DE84B27A4DCA1AB749352CF925401E611E9CD1EDDDE65E71D8EEBD1AB5BB9D9825703934DB02AA39A2546A7E93CBA357A0E939421AB5FF48D03E5F7A901314FDA167906512976704483B4773F14910BC41344958C2A78E5FBEB32810797FFFC3B6FBCE8753BFC8A317617F4B3BD783DF114D32CB43FE9C6BE434278F16D87871F03DCF4C7F2BE141C7D7B397237A97A16DD2EAED6C602EA121A79ED92CF1384106E3422A8D208DA31E1F95AFBC72709D6261A22BB70AD8DB84CCF1DF5A5DB22EF0E2D1460A7ADF02DA8300EAB102D1423D2782859D36E36648CD203B2D9BD2CFD11121F91FE0807FB725D715E88EEBA96F9B701FABE40E4E0BD2B2C2168ADB795C142ACDB8178936663966B505F5DD636C460903BEFA0E2A58F03A2B678E85CD9395E13D0A09D372D326F4D17BE4276FA5412AC08A1DF8B21C35FB01FAD02C8E6F29510F734A8270E0BB7B733092849D5F4B69ECD0DF374B5F94C2677F8EA3FCFE81104822208734E6BFA8D1C0EE6D7C544BC53DAF304C2E508822F9F614A2079D14325874C9E4F4D7D199EC27B34FAD30C9465F54A458CA1C72D03BD44788B33FB038BDE045B143CC798B6B0FDB5737A2021DD20CC3C00EDE83ECD7746AF05D1CAFC60E8203F0AA8413207328DD4FE318F1300638B6B76258A51DC61A43D01BFCDD67F380D8864984D2111110DC4222B3CD648AC8CE831F87D67D05D856F13E3A3A8CC5390CE7F87EDD80F6306217C58CE4852F6CA9798BBB570D882FC306E094CC4E0EDBD5BD7E1E51A33AB62D6924A2F63A9174AC389D081E51D87B7141820164F34E80C97F128F0A04AAE0CA3E8551790D8ADD622241B936079137A938D075026EFA487ABC0FCEF34896DD8EA0927F7A61F6CED3A8E4848E072F641BC9EEC9AC97880D63922F6B3A7731A82E27F06FEC67EBE225CE17530363977FF402DCDD23C383D948B3ED8F2AB5831C507F51FF89939FC4712F27AE40A685A2681A239412A1974E6DDED772A26A7FB1013F2E33938F1A390ABA5CC8C1627B9AD077A31ADDA04FDC9DF7EFF3510926F4803EE1A556F7E367FC26D04FF62799DDF159EE5D0B34B9A3CB65681CE67AE4FDB0E410FFBF2034F1086CCC403E6152D70B98CEC53A37820A2961F4B5516CCADD0B5AC2A69026192C76ECD087FE3770727166600E97591329046DA1B14879103DF5D4C71CCCE37EA6130FF083CDF09C5B86935084E375FF77962C851AE97CF035C8844B8E7C7B5BDA2D39953D2C64E52241C7C74AB55A4D51FDA17F8E73A13B11FCB1B42933D49E3B615388BD23631C98B84CA802A4E3FA82898ACDA12CBC7EDF797C6368B7CCFC3B9C7DE4F636ED866CA0BB690E5C09E6B16B3E7AA3F16DDB65A72C788ED5E64B7A4B1BF69BE813861E9B9354D769F9014B5BE64F868BCA085B6FDE6F82136E9DED0BFE3876F6FC08C88AEEF3E327E9D42FAEF7666403F46AB637B6A6D1D968AE0AD953F2DB5E6895B04FE331086352AAE19F7F26334E8583CD578A44A0E1030B76E19828E93FAA351AFBB2AD2F9D86CE06485C9FB4FFAAF35F792761EFF0D42B65CFE559E4D8D4C6179D40D48714F91EE5C7421A59BA86303B7A06AE8675C0BB8B23F90312E654E10C860B8783F50E0C75249A3E957D1D405C76DE3C6CA24A25A0B100F8E5ACED3C29B81286305150B5775902B2EF7CA45F9382F8B12B354DFE93F9C3A63944DFF780EEAFB8E883A16E5767739C4D59D83C5D58F0EE13C4E94D8BFFA54CD648EA0DA1BF7EF245899553E3879B03CF067344E177A3B97CD8DB8A7B27DEBDC283355145A23416F30DDF3B8291F9BE78AD5FB36086AF2C2C2E24DAD3DE0721F324D0245417E0341722538B8BE7778BEB6FBF528E6C6BC9AF853788F1DA364F147E312E0EF6968B69B963E139A6B364287A4B6C6A2B9643C493462A83F132B5703928AEE8DA954DF1F7CB027B4DE1ACC0AE7A1FC46AC12E91C7FD3AB0BA9846DEF8490BA884CB3E171F00A28E34D4BD71487D1C5BFF65CEE9C6761BFFCB180667C068676C75ADAEABE6C03AE077653F62F0F5B4488A4B5375BD637104EB20A407D998A3C882D5690C0F1CA59C22BDC73C23E44F4B7251DB71425E00027831976C6032A08657782B43CA98F147820C9E0E308CB05EF8C3408224DD3133B73F2178CFCE16A9251DC4FE202BA6C69C1C0F38830AD3ACD7A9D821E1C2D10782D7A1C617DB855922FDE34D69D2644D7E09A9872A687AE21C946543EF9020DE3911D985B211A4492B96D321CB69D2548275170DDB3A2AAF4BF3A7F6C95696570C1F27693EC153E7C9157DF2E69C32255DAC6411139000E02506AE0BED9E472A7A48685E54785EE41F94713047C54508F062F9B81342C6AA8B81EF7C1B21FF8D1D4AF5C1FE950E3A32EB132D0B4C5531649DCAF7EA8FA57BA6FA83A5F2D561BB60F910AC0B034AD3FFA319A67B8E59BE9D0E801CA09C6AC20AC32BF032FCA973FDD4C56DB7DE13AB6A13AB73D1FE2ED87E9E7665AD0836EDEC1B4F01C032E66C117E9DC983340C27C04175B91CC41474DF5AE3E016181B7D6B170745C26C34E8C4DE9961F52AFB62E0D102BF0B0B67C8095378C5CEC9A74770CFF7AD9260A5DDCA58053B5B80B310819DC24826E19FFDBF48B6FEC9E740C89EFCBEEE2B8B5045A8E49B697463541782C35070C7B9439B256E1F50FE857BB709A17FD769949362C71EB4CF132E7C7B51532CD25CADD5531B659FB095FA55FD3A259BF7A1775D6589ACC0D3F8626F0153B4FD13B21E7F4B869025A8908CDDB3EEA6E4E35A256D6133186F1069B40CCABF932FED14828BF9230F114AB825A3F42EB2DD2D845738ECB35F290986C13DCEB26E4823C6B038D0C65AB0EEDBCF5FB0AE475F6D34C222B504A373AB53DA64BDF7F98C9F540558C57B274FBA094BED588E38CD6F28936FFCE145B415C8E4C47202122C02AD135FFAD79CBBDC289154B61151D5AF859B6BD5F2D93F837B641BF17B52C59645F1451CE6C976DFC6B7E9A6618E649671030EC3FAD2D4B6ED7821EF616D17E945EDFB3DE504A5CD2A3DB3232320150CD306107B22B2A37CE45DD952D54E2AD62D08BCB67384C75938EF9A0DD2A752F5A3E63B48BFE2586B641C574715C6C020E56239EBA10F9945C7FEFCDBFE7C1B3E98A87EB7CB36576FBA404548A9E61128365D65CEEBEEF6FC2577C2C57795BCCCD7F22084A60A255E959B9CC7C9D5DB4242484C739096B8E900000000000000000000000000000000000000000000000000000000050F13191C26272F3065023069CA292B1EAB5F7C5A851FB22AF923980F3CB8F6A19066F2776D4D7EE346F0963140BB0669D97624D4F967466739DA38023100C9C81B728A27B7341D9355D9C6B03D88B395AFC736488E9A73DC963B8CA882258DE45EF74ADBC44958676A5189A14F8E + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-87-ECDSA-P384-SHA512:COMP_ML_DSA_87_ECDSA_P384_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = C6CB5AF53216EFE01BC23F0E2295BA73624283B69DFE80583038A66AECBFD2FD10BBD55940C5960BD5C818CAD4D90F6B7CD9674D78141F1AC93C1C92CF66134C1A6B0B51B09F6E675D2C0F503D881E115E2A8FC018E70D8B1504ACF7391AC77BDA2960E294F85974736081497CB7930108D8EF78CBC3AED9DAD222C49D7327807A558E26AF6E507DFF734E08579EDB8621C23F1D4889B5830DA857C4A1C79E5CB80B568DD97D6FC92B733FAD9BD92F1A622BE12112E2D3F6D94CD74278F55DD27A41BB907D46E7A4F69393CDEC036F79058044E85EE6357D8D39D7A398C104486912688DF2B2EFC295893F77C01DB11C424A3F265BF805AB17114C6AC3B2AC8DAD4F545CCC46B7B328E4BC77AECC5788C8950833A666DBE16CBB2B3A7A086FC4C2E364621C5B834D8518E6BC7390B3DF4C20D094E87593D308E93569B2D44FCDED577B17B66FE9B9AFAC99E57B035C4BA32C79351BA50234668339DEBC67A6A7C0F980847797D7A22F47660FDBEA0D9771A2BF2579411728D20B1713E9B51D55BC3DFA1F36122A3B4A755E1EBC83EB0537684FF561E81A2ED06EDCF4E8004DBB0DA940AF79E1BCDE4A0C180030CA28E5FD026D1201B5A6C8A1A0E0213AE53D2F9D93FBE2BB45E342850CA83649293981E8F02AFFAC0B15FD379352F22536167943FB180CF05A4B4DDFB08642AE9F678405CC4C1138DDBADA07B168BD6C92ED76E37998BDE78026C302F7F073BB8789A4ED36F95C369089CF779E884138BAD4C33668FC660D0440CDC0DC61EAC77BD5657DF9D48C810263E713D402C850D68ADDAF2644DB0B3259E80838B7FA8726D9AC9EE3613B81560F847B65D407C232470F2F5E7ED1F43F9F3F592552CAF3E6B4077F656F5EFA422903E23F0241976F6264B4267B341403CE501BE74C86DF24076FF73DB3B7A3F9EAA96FC841041F54D62CCBCCF3619761B93DABC18E60AE6210491FFA07917AD9D4363BF08B1B1F510B43A94332CF771A960A6FEE35FA1F1F747BC266E6BBC10522B2DE89C64C039349ED87DA661A57AB114D52710A439143C154C82CF07EE112F601A34F05196D6F64D66908C86028FB09B08FC123A1268285F9FFE19CE48948B23E2A050B1296E7902CB714546A661633111095BA3AD11E27387EA951DC3F6A18FB9FD9B870ABEC2834023B84084AE3600A84CC7F0427B00BD1B5D9ABF84942A24F8217E58C12DEBD2C1BFECAA6FBA722146EB92B856908DD7C09E04776CBEAB7BA74C7549CCD1B66BB04FBED8FF8C5375BE929CC46B7CE3B3660274F69AE1D474F13DE4CBAE2C1E4613335A945751C1A0E23E8055701A057D80FB22501C06F31965ED571BC1C49E5DC0BFFD77F6A422C42452F2263BF25329DEB4993FCFA8FA208F867B4625F13E5D41AC4AEEAC88402D4D00D629613FC7B79F2E4CED0C1071DA1167016530FCB8736E4EF21587B5DEF26D4619022E18BB4A1C22EB96DAD2CEF76E4F486B64FDCA6887F0BA0989959E1B30ED0E9E93780E45D05347B9811303B5FD4AE7B7613D75BDDFFFEA908E43277EC8EABDF1C126FF81940FD16B074468D4F6922003665610CCD5E16268D118DD473466A6DCEF8AD1674C71279CBCD4BBEEB01AD0974B8CD2B83F92495B7987BE610369A5D312CB246D9C95B7000C4331A4564AA2FE7137369DFDEA7BD454BE6B1B4CF21464B6E74D4B01FF9D09137F334263B0852E9B833EA2A62D2A9BF1A8ED246B533444A153884E0E622AE762181C15D06D512F1430DBF5D5DD57B18A333998956B8517F2EBC38DD1F92EE53BCDBCB6ECEF8897C3E23D2DDCCA82A1F3F2AABDD98F5273862E4097BE0E82A51F8994EC40E8F58DD1256887D21D146BA3423C10BA55B2E32974CFADFFE09742ADB5F3E74EAD3FE54E008AA53A706A53E745314BA4616DE8BCC6DC79807A4A47D395812A7F60576A77C3A4E61E75041303FA181323F4DB05213C5059CD98DB68C5BF76F51BF5903659991DF4FD1D877666993C3B4866CBE2D037C6D6A87BAB96CBD954F8CD7772B6FD01C73AA7997B577368BCD5C1EEFB1EA1C4C031DC80A08134D7EF29CC79C09B934FC2F239B050D0D04990F837400C76FC62ED1E928B34F96758D7B00912F030C5AAB353636BDC258D6ED1290CEB77FED67B07D6AC4E0B02A94DBA60040FEA5B9972DFD9111EA4850B0BEF808EC602F46EC058E9F33D07EB418C20C18724A04CBA46878965EBF0FB88AD2578332994CFD162E7D1AD58FDCC4C7B34495E8421ED5FE860FEAD21BEEDD94DA53258A52479C0C06AB29334ECCC4897DA8D3630057B76E9E3A1640E0EFCC35EB46053CA3C099C1C729F1214FF8F30DE3362BC9E218F326FC837EA5F150BC33D901A0D75CFA384620603348C8D106AAD73C04084E3450F796244307565E26F170A9FB665F4C409F863B34594AA65830A6010950866C953A28CCCC64C9C27D8DFBFD3E1AE2FFEC3872380AA04B50752E6F8DED80C96C75881B4045482FB8F07367D2EDD5F71ABD7B9922E8004C62F43DFB77D34E0C9128CD5AE1561A594651DC704A45AD10AB208CC3CD7ACAE8F591A5E64AD3E6A88FBEC5EBF95C964EE61243D5291204AAC1A9FE6B696CAC6938AFEFFE6355C2C37E95431EBE324B070AA8A060175BD5E558D62EA1DF7F2D84A4EB1E0D95871F15696A435F90A6B6402F06E91A7A89640A97AB5A867860E87BD538D4F1F3E2DDC9C9C6D90054C60380CD3BC7C361E7109CFE2CB98B55262FC480E0D9B9314731DF9169A7545EF5EC957067E3A96585E843505E798F306EFCD7FDDEC2BC5AC170DEAD7E25F7B3C2CA70330C1C461A57455AA1DE20C332508DBC8E5A97E5688B275392CF4171AC4BCD101EE82DAE3758DEC9EBEBFB7211B2D341945986F8C4FC314459201C64C59EFA230C8A5C0DB92297A4B0CC69ED75A1F4FD8E9EC2F6FBF3EC9A7D4716F8F796B85F45791D99E61FDBB38FC5422CF6C1AD1EFE8BD94BB050E102F348282352D4AB1D57209BCB539A33FCBCF26D7B93DBB40D1F7683A38638001198EE8D62DC00C78F791A306A93359273D8D7A1746DFBD99D394321232DC3FEC584A4A888514C5C28223409E2C853C6F7492CA7DCECA90DB051F00F730DEE82C486543DF2F0128E8C1869CC82BAB2DB09C1768875A434BB2EE1F141B320785E93B26F70C9699A8C68ECE9DAA0A4900393DF6CA2BBEEA6E4D3EC94A4E68EAA87717FBC109D2FB9E402FC21D6D5DB41CD8D78590491167D669BFF1E272DC4933A3B6DD26025E3B85F8290A60599DE84B27A4DCA1AB749352CF925401E611E9CD1EDDDE65E71D8EEBD1AB5BB9D9825703934DB02AA39A2546A7E93CBA357A0E939421AB5FF48D03E5F7A901314FDA167906512976704483B4773F14910BC41344958C2A78E5FBEB32810797FFFC3B6FBCE8753BFC8A317617F4B3BD783DF114D32CB43FE9C6BE434278F16D87871F03DCF4C7F2BE141C7D7B397237A97A16DD2EAED6C602EA121A79ED92CF1384106E3422A8D208DA31E1F95AFBC72709D6261A22BB70AD8DB84CCF1DF5A5DB22EF0E2D1460A7ADF02DA8300EAB102D1423D2782859D36E36648CD203B2D9BD2CFD11121F91FE0807FB725D715E88EEBA96F9B701FABE40E4E0BD2B2C2168ADB795C142ACDB8178936663966B505F5DD636C460903BEFA0E2A58F03A2B678E85CD9395E13D0A09D372D326F4D17BE4276FA5412AC08A1DF8B21C35FB01FAD02C8E6F29510F734A8270E0BB7B733092849D5F4B69ECD0DF374B5F94C2677F8EA3FCFE81104822208734E6BFA8D1C0EE6D7C544BC53DAF304C2E508822F9F614A2079D14325874C9E4F4D7D199EC27B34FAD30C9465F54A458CA1C72D03BD44788B33FB038BDE045B143CC798B6B0FDB5737A2021DD20CC3C00EDE83ECD7746AF05D1CAFC60E8203F0AA8413207328DD4FE318F1300638B6B76258A51DC61A43D01BFCDD67F380D8864984D2111110DC4222B3CD648AC8CE831F87D67D05D856F13E3A3A8CC5390CE7F87EDD80F6306217C58CE4852F6CA9798BBB570D882FC306E094CC4E0EDBD5BD7E1E51A33AB62D6924A2F63A9174AC389D081E51D87B7141820164F34E80C97F128F0A04AAE0CA3E8551790D8ADD622241B936079137A938D075026EFA487ABC0FCEF34896DD8EA0927F7A61F6CED3A8E4848E072F641BC9EEC9AC97880D63922F6B3A7731A82E27F06FEC67EBE225CE17530363977FF402DCDD23C383D948B3ED8F2AB5831C507F51FF89939FC4712F27AE40A685A2681A239412A1974E6DDED772A26A7FB1013F2E33938F1A390ABA5CC8C1627B9AD077A31ADDA04FDC9DF7EFF3510926F4803EE1A556F7E367FC26D04FF62799DDF159EE5D0B34B9A3CB65681CE67AE4FDB0E410FFBF2034F1086CCC403E6152D70B98CEC53A37820A2961F4B5516CCADD0B5AC2A69026192C76ECD087FE3770727166600E97591329046DA1B14879103DF5D4C71CCCE37EA6130FF083CDF09C5B86935084E375FF77962C851AE97CF035C8844B8E7C7B5BDA2D39953D2C64E52241C7C74AB55A4D51FDA17F8E73A13B11FCB1B42933D49E3B615388BD23631C98B84CA802A4E3FA82898ACDA12CBC7EDF797C6368B7CCFC3B9C7DE4F636ED866CA0BB690E5C09E6B16B3E7AA3F16DDB65A72C788ED5E64B7A4B1BF69BE813861E9B9354D769F9014B5BE64F868BCA085B6FDE6F82136E9DED0BFE3876F6FC08C88AEEF3E327E9D42FAEF7666403F46AB637B6A6D1D968AE0AD953F2DB5E6895B04FE331086352AAE19F7F26334E8583CD578A44A0E1030B76E19828E93FAA351AFBB2AD2F9D86CE06485C9FB4FFAAF35F792761EFF0D42B65CFE559E4D8D4C6179D40D48714F91EE5C7421A59BA86303B7A06AE8675C0BB8B23F90312E654E10C860B8783F50E0C75249A3E957D1D405C76DE3C6CA24A25A0B100F8E5ACED3C29B81286305150B5775902B2EF7CA45F9382F8B12B354DFE93F9C3A63944DFF780EEAFB8E883A16E5767739C4D59D83C5D58F0EE13C4E94D8BFFA54CD648EA0DA1BF7EF245899553E3879B03CF067344E177A3B97CD8DB8A7B27DEBDC283355145A23416F30DDF3B8291F9BE78AD5FB36086AF2C2C2E24DAD3DE0721F324D0245417E0341722538B8BE7778BEB6FBF528E6C6BC9AF853788F1DA364F147E312E0EF6968B69B963E139A6B364287A4B6C6A2B9643C493462A83F132B5703928AEE8DA954DF1F7CB027B4DE1ACC0AE7A1FC46AC12E91C7FD3AB0BA9846DEF8490BA884CB3E171F00A28E34D4BD71487D1C5BFF65CEE9C6761BFFCB180667C068676C75ADAEABE6C03AE077653F62F0F5B4488A4B5375BD637104EB20A407D998A3C882D5690C0F1CA59C22BDC73C23E44F4B7251DB71425E00027831976C6032A08657782B43CA98F147820C9E0E308CB05EF8C3408224DD3133B73F2178CFCE16A9251DC4FE202BA6C69C1C0F38830AD3ACD7A9D821E1C2D10782D7A1C617DB855922FDE34D69D2644D7E09A9872A687AE21C946543EF9020DE3911D985B211A4492B96D321CB69D2548275170DDB3A2AAF4BF3A7F6C95696570C1F27693EC153E7C9157DF2E69C32255DAC6411139000E02506AE0BED9E472A7A48685E54785EE41F94713047C54508F062F9B81342C6AA8B81EF7C1B21FF8D1D4AF5C1FE950E3A32EB132D0B4C5531649DCAF7EA8FA57BA6FA83A5F2D561BB60F910AC0B034AD3FFA319A67B8E59BE9D0E801CA09C6AC20AC32BF032FCA973FDD4C56DB7DE13AB6A13AB73D1FE2ED87E9E7665AD0836EDEC1B4F01C032E66C117E9DC983340C27C04175B91CC41474DF5AE3E016181B7D6B170745C26C34E8C4DE9961F52AFB62E0D102BF0B0B67C8095378C5CEC9A74770CFF7AD9260A5DDCA58053B5B80B310819DC24826E19FFDBF48B6FEC9E740C89EFCBEEE2B8B5045A8E49B697463541782C35070C7B9439B256E1F50FE857BB709A17FD769949362C71EB4CF132E7C7B51532CD25CADD5531B659FB095FA55FD3A259BF7A1775D6589ACC0D3F8626F0153B4FD13B21E7F4B869025A8908CDDB3EEA6E4E35A256D6133186F1069B40CCABF932FED14828BF9230F114AB825A3F42EB2DD2D845738ECB35F290986C13DCEB26E4823C6B038D0C65AB0EEDBCF5FB0AE475F6D34C222B504A373AB53DA64BDF7F98C9F540558C57B274FBA094BED588E38CD6F28936FFCE145B415C8E4C47202122C02AD135FFAD79CBBDC289154B61151D5AF859B6BD5F2D93F837B641BF17B52C59645F1451CE6C976DFC6B7E9A6618E649671030EC3FAD2D4B6ED7821EF616D17E945EDFB3DE504A5CD2A3DB3232320150CD306107B22B2A37CE45DD952D54E2AD62D08BCB67384C75938EF9A0DD2A752F5A3E63B48BFE2586B641C574715C6C020E56239EBA10F9945C7FEFCDBFE7C1B3E98A87EB7CB36576FBA404548A9E61128365D65CEEBEEF6FC2577C2C57795BCCCD7F22084A60A255E959B9CC7C9D5DB4242484C739096B8E900000000000000000000000000000000000000000000000000000000050F13191C26272F3065023069CA292B1EAB5F7C5A851FB22AF923980F3CB8F6A19066F2776D4D7EE346F0963140BB0669D97624D4F967466739DA38023100C9C81B728A27B7341D9355D9C6B03D88B395AFC736488E9A73DC963B8CA882258DE45EF74ADBC44958676A5189A14F8E +Result = VERIFY_ERROR + +# --- ML-DSA-87-ECDSA-brainpoolP384r1-SHA512 --- +PublicKeyRaw = COMP_ML_DSA_87_ECDSA_brainpoolP384r1_SHA512:ML-DSA-87-ECDSA-brainpoolP384r1-SHA512:1C0376CD72C5D2BF57C57B84B0F63B4FC0FC7D793E4B7CAE48CD691D6D4BE210467D68131CC1B19633F3B033B4B054E4216330E004829B589D4963B9BF2A6656AD058DC7669D97513F397777BDDA2F2BC84C813AA8D884C796EC4F2F03202A50653A9E322E1427CA0516F936159AC60F93D25423F35A4536B3BD4AC15F42704C6F4EF24E70243A48F0E03FC65653CD008463FC6D16231A92E2F42F25F782AE675C5C4C7047374A77064277F5E072D76C5C684A61C436B34BF614730E9881469AE88AEEB052B195EB16C3F645C8C37A0A7AC7A57BFD326C641E08E270021F7B4322E2C39B22B82A44D9A0D3B8114D0FFF06DE5C7C7F468508E53FF3CD8681F8DB553E0637B692CD9510642D583AF2910E8CCA70D2922ADEC73E606982192AD56652A12616166F811878125B973EFF42ABDB43C46A9801EDF26E8EB0D7862410C3CC64A23B4BE1472D83908782125192DE1DB1640CC99979F89F050060999CCA04F8865D53D0DF8DEDE9CD45181C1EA12911FA98E72C7FD3B4DE4C1BE1E3AE5456CB6ED6C0A02F8A2390FCA38E74CB3327D8AB8400902E8AF22F1EDF6E04D3059C72CA43B3C0D0076E7BD8543EA11889FA7DF5021CA6C711EA80723C3CC630DD4A29409E17FC28C0CC6E1B8E23E8E1F7A025A092D0354BDE6138E8A71C1F427606962F59BF966F423E4F7F16AD22C6C4B1E17D8E9D00F52BF86E52A7C3F8F01ACD79F98783D05E401974ECA1F9057887C48F4D4E6468DA0C4A69857815CD15E5B9F3F79C3F8C1F40FBE8B3BA05973D9F5704A8E82CAA7850CB8EB2766885DA194C85EC183B6F5DEF5AA147C60E90F9C60B87399482E69DEADCBF768E9AC6A144A60DE78718E134A3ED53B8005D459F191050ED910D440B2269727B9C8ECBC2477F782C0B56E8985CBEF4EB8379A38DF9C1BA7B086DA6878ED95348F17525D89AAF0CCC7E8E309FA2AC23D798A247BEC1286A7690A1491CBF5B3FCA9B6B614251A0D4FB821A8E61A9661970ED0453862035070C9D887E4A4725F43EE889BFCCA9B250FE581B7225C14D4C3D070FA5DBA1308D8B84385706C7E30D4439A5FC5F42C89FC297787F9023DD1D19A5C6DBDE32FA9B8E48E96C6991726426056288190E45ACABD550A81EEC030EDB7CF695F53DDFE1597704C46346706ECBCE8636186A1254A4087061B7CCBFA52E496C931E7B77457E08918DF083E4FEE514FD79CC1C6AE3BE2EC9306483C378843A755818625585F414066022FBFAEB3DDE6C4AFB3CAC5198AD2AFB07BCABBC738891008884F7350FED4DC9ED1397AFD00F6E0CF3BF438AFFE4C8A377BC54AC90D0ADF5C8FEBD2E2C161E23EEFC317BF2A05DC2545C82F65C6736516A15E7375D5D23F45727578E5DFA427C90353E6169E64E6C821A4784650B4302B61BA5A88B75870D9C5852D9AA508DE8E18C0AEB07A478596AE3ACDF54FB9BD071CC23BA9A480CB64EB3E0D7CD3A19F95F26464F234BE762DCB1761DF1CC8C6EDF753B015B84BBE431B2E011F244104B4A308599202A2EA618CA40C85116958415160B064E5D3929139D3A3FC9525BA1E5B59C5E8948C86EB0AF9602BD93D5338B69EAF5A4ED92D41BAC1CF395A08B2602AB174458209E167049ECF22C0BF3052704F9610A7CE6AB27852417433004A30C8A67AF444B70094F66D61D5826B0225050BEB2E55D72981F52FA6A66E7B58B6CEE20F6B6A156231496E55BA1BB2ED97E2FA83D208996B186C69298904770DFB7CB7FF9FD5CD279A7A370F64D6295648E57FE44E5AC7878A5C005CCC822660247CA804F8EDFDA6DCCEA3E47FB9BAB18B797D5E11A483CD7246E2DFA24B6620D52CB8EB4BF53A9D0BD35B64633192C189470541AB79AFFD968DB222490288414684F9E96030FC72DBA08CC01AD67B9C70A000861E5EE1C3BE1B917A42A67193E0B1331E862DA8A6B2440892647FCD6C7DBD534DF1131A8FD4BF6964EE1E0017086711C2C15E5773E3D72102FBF406719D08D633F152EEA628B1E22D86C6B5CFD0DB6AD8B58876A8C43EFDA9302681520C03F9456B8B15011D2B4FE07CE67AE06CB4173343178EDBE3F778EE91E509AA2D0DC0563EB97BA746EA22480A684C858B107557E91F70834DB2204D47FF33578D4240F3CE0D605A644699D3D47802CCEC091C084D3BEF79C95C0100B7B661C85E9D59CF2251B0D5DAF5D47C80A52CA050AAF5BCDB2750A844A2A230E4BAE0C2E930549C71AD6AF0E88780B9C87B49B1ACEE2E7A6DDE0080CDD828C290268D71DA0B3DD47EFF8895719C2EB152B4A28061A2B67F78E29C5487104C6E02FF15DAB88B877213BE2FC101103C33250F519173531926E34ED3180DC706089122F4656D3AACF254FE07123970FDDC588415D10A73B9FDB651B118C6652DC597E0AE28AA6EA18D96038D242D01F92591747FA48B84ED91C8E86A8CF5F3874681368B54CC752E364169BCA722E979C279C1844662C2225833CB37979CE7F4518498AFA26395C563F88FBB198879F60B6C672A2C035FA21D9D287C478DB598AE710C0FAB966FE7D22BAA7B020B916B39A02137789CC02D0F7DB096CBD4880170D26918D5E1F922363C6E772E8F1F3818239372FCFE6197C51E9677ECCCD1EFCB3743EF11A047424780D53D23EEE48CE6AC32CD638F9CC9DDD674C1E710E32CBC56C0323605832F1E77C19CFC168080D7923BFB257725CEEA127C3D02754512AFA983637EC10209CD3AB97957949A8897043B959BFEB602B01EC7560EB12A1A36D931198EB7AD63A9C1F7F0DE015DEE8B499E78C1976DF721308A4F70B84A9BF12B476A6F634E789CB59810B590744E69CB65D6B7BD7C07FF6E6162F4013A04E771B24CBCED318427E76FDF1671749FF4FBE2D2A0DEED039F871E99EBF15178164F52E41ABF6419DF62500C3ED6E34A556A42DD6049C6922B39B35F2A9736368F4B205B5538831E2D665047D153A9808E5BAC5F2A2A9828F4C05E85710AE26ADCA37B79FAFF9B99C6FC4F884965E36B465631D0D4A724798A986751C31705798856A619D35AC2F4E0850F8161432B514602808CC351A3565EC108AF54ECDA143B18F5392A800FF0C14E4B808CBB48D7B164FCB43B87ED851F50222545447141DD18A09143C6FEB509CA7EFC4E618E284E56317215A425A44595FA5E004A0541946C50CECF3F2594991DCCF1E1F0B3FE175EA14281F1C37CB9951791093E06124ECE60415CCDF452ED24D947A5C77F6A9CFE77E398D02A7EB3B7DC91F46BED14221CF620206015243F2F2B818AD6C6BF793CEF2367D9BCC38D7645451B4A6B8510A32238B66675990CC88B7C0DAF3117C2811CDB40A7ADCBA6F0106616106F0559A58020D369CA2984E9E4327FD30F5078DC5B2CC14E233A88A595AE4732E21ECCA1EA465A7D255BD3B2BA9BADC5F860E44D6786750A1738CA59027224E808F9864262F068F7A4E9F26EDCC5F2F4A6A87EB722F461DE34A6DE548746AC92634F1487DF3CAD4AB795D636336A64AC9E8F1C9FD0033E6D2E6ED9EA94ACAFB37A55279800938D2F9CF66613964C573F24A816644D96C084E19EEDE3E450907DFAB63F6355E133BD1A810B1F8EA4EC8BEE3AAE5036E838B9FB77E9744B3323C37C5BD2E7C576E6D9E5FA3B921E071590BE8CA3BA6FB7F6576D17E1815BDDD77A3D7C20463142D527E1321232B8DB7C4480EBED6EC78EA3E4A5BA310FF49E75B7CFC170E53095AD3BF85FBB8826AAE2E60ACBA1B6872F36CA2CC8BDC0C260DE03B97FAAEA1AE9B3A37EBACD942ABDF99FD80FD9434AA8DC6B4AF75D261A5B51A560ED1CA + +# valid signature +Verify-Message-Public = ML-DSA-87-ECDSA-brainpoolP384r1-SHA512:COMP_ML_DSA_87_ECDSA_brainpoolP384r1_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 8FC14DCADDD6FF3C6AADCA241AAD0CC4393C96CD0DCA8D9A3FE7B2CA26CD3419E23D157740538CDE1EA4A1D385A365E4567333CE19D118BB20D91BD39846B14CB74A3FF77DCA5B00A60415168CB1EDEE73E7F7623EE5D13C502793F53CA2B581DF778C3CA369FC4164B7E4ED479BB6986411D3D24EEA9BFE1ABE7599A2755FE06399A1017F9FC09A926BF26F10238B14E20FFA54A209619B48BDC299D87F9D9FA888513B80F600DB4D26EC73EE3D0252F751DF19E2A12C5505C7E66C4CAFE29F9EA6CE8523023008BB63E20380489631C87B37621CF0DB42F31F8FE9204EB42AF254DB0770CCF0419DC879E4B26F32123A1ECBD59909251A83C3394413BDD160BBAC2DB1EF8A8FC98ADCB00894C1029916F0464A2399E23480B99F3073BF041FBBA6273AFE01172D4DFA9064DC8C81AE2F488E7D761158D1F0903B6FCDB82E90284937D48504DA1F92EB7E437BD52E462077ECFD9F30B93AC42BD7263744B83F6FD3FAE7D513C717F61D9B3330833A6009D01FC48B99E00F893FEDE5EB47E5466D90BB9A95AD0CBE0F700013F0F14590EC31800C2AFF57556B86162E8BEA9F46C5D1D8BA60412176AE7A29E9F3CA6E134552FD1211D13B07B926454D9C600156819F3E8A0175924249E8FC931608439E7C58DD4A9B832552A1EEC3DCFD8975D2D63A4DC94947A3200EFCCB5BAE5C6DDE47173617D82F0462D57051CF251CC53F3D84DAE8E029F154223E6B629A9422AC76B6B2C69950EBA6904F198DF406474D6CB8FAD425D055C915C531097EB41D3003867FFCEAEEF91ABA000EED5126EF471DB39DF6938CF89E19115FC36DBCAAF873C8E94F12A725B030242A24C0AF3350E4373289619F4AE4E4625DF3E39AD7D060952CDC491FA2EE649CC24B69AE5EBB8E033D793609A80CAC49CF1EFF44D2994FC5324F0FE90E3CB68492496FA61EBBEA65EA84F577347FFE8D560ADF3ABB801D26851D94EFDCAA53462BB4CCA9272BBB9308011EE2DA551E63AEE0085B012AD7455945D8A82FE231F85366A8E1B15428AA2959B6EEF320144028431A59C575B83EB693160D8D0D675198E90ACB28E784552E1691498DEF6662337AA1F9EF4C82E2AF4A73C3B7B95D44D2DC4EA403F3F747A944FFF5831EFD539A23CB9C5BDAA4EDE489883F832DB17AF04B334F0EF16BF199ABAFC881FB87509AB6ED07689BF17BFE5459F56EE0149BE29DA6CD9B5BA7BF87C8FD71283A010E20B0D45341884F2FFDB24EF9CA1AC50B78D532FA611B0D2F370E96D1064BBF832238363C04A880D963AA86015E37E5F65ED53119671D82B76E75877B7D084909A7DFBDCAED087E07262EC5273E84A60A0EE4372E8BB1CAD17666D79226A505A56243E0536F95D834739F702EBE5ADA0AC6276AD744795170B1FCDE8BF5A69E08B13C53604F6FCB5F305663D098BFE0F830EC55AD757123C3E5D8975689E18B46242FA5A408BA1382C060B784EEBDB611AE408BD6C357E1E1F3717B4BFC74B0ED2C32AB334E19C090D93C36CD8F1CEF493DB293EC67278F24C202F37AB47585302A7C5B267C2262D931A8DC17AFDC11EB6D1C51355C546A54E707051250F5C08BFDFB994C5160825CA6B3BACFD0328D5071FF648A5DBA14F8FD73299B80C0620EE6390C5B3ABAB40ED3486462889D501CB17C593DA0DD332C2CD8F12F4BBA10EDADF8159C30AA8722BC456F5BF8C9ED22DB1C2F54E6EAF1190163C5B651C15E9CFA1AD8F5576769EDB0E9AFB26B7B6930F11E7A84398E1E954C25654D95E1D8BE1903DBBA7CFCC888EADA155F27F84FDA80875D0FFD6F78C0FA1DA6B78A416711E39CEDF8B5118FED2163EBBCF2B1B7944127DE0FEA8D21CF1A33C0557D8B1B76A0D6CA6C3B60EB8412A2EB00223D6121E3F99180238A4CEFC7177DB4397AE84C6F1FB4B116FCA0E3485AB025820E92C091274EBE2B9BF1484AABC196BF2667BB131150F6D8F5A1E6E2669FC13FE2841075D76EBCD9599DFCA825ED1BA5F0572AAE02F93D3CFA74083BF143D9AC725928D698BB4C3112EA85E6FFAE3899E3AF339B2F394560FBE2DFC84CA5B63B3745112514C47F0F47DFE1E74CECD6081170416DAF67CB221A62DF2C7A3A7390CD67D1ECFF824FC102AD80E753C07671419FB61CD4DB43FD4FA6EE2463A1821EA283FD9DFB9B68602492FE043E26D3565E089820131DD107B51B24FEBCA09432AD5C811AE583A0B788604A5AA1C5EC0387CB768203052FBA47FC40C0E43726D6B6332B642336DF5D0F227B4C75CD9D2DAE2B62BD3F00E72AED1E7F02BE2A209CD69C66D61762586B98C1EDAB2D0F187DF49F2679B321C9EAF3FACB6BE3AFB5293315B238A3AAFC9E070443995E7891B561926F1E960A20D23E2821AF0505C4B98331F9CCB973B5F72EDA1B2C1A7C3EEE9A57FA58BC987CCFA0BC6ED7F42292B187115FEB21A087E327148007A0963654C70F99169290B4EAD313AF618AEF37F8EDF685D7ADDB45E73B3E1BE6973FA427FA79BFE66FB35A471BD297983D3CE1FBFDF283830CB97EB05F99AFC0DF4AEA1523D1CE1DC0934F940DB7B86CF16B5D76BD5145028F161A8A268570AD8718679C18A7F0E9D0DE38CDD03C4C69E8D8ADE6F0E443F6AF76779761488796885B47E387532E282A17D1D3E82F1CE2081DE18C0E124F52B0B02FD3324E03DF00FAEB79DAD529E303AF475FA6D7B345C0C0291C7A46F243890D3D8B44915F5A1C01F5AEF80D92016BCF505D54A76B8A3129844A098768FB6B9393784177FAE9B1845F03B0659566E80F18AE9588BB05ADBC347E3EE8BD26ECE0270E9B3A5EF279B1030985CAB4F382C10B6ECADDE514E7AA4C4AB9A8F07F4943FF9FE674537610B687A3F71B9ABFD21B09F068C19002BDB1874E1C616F6B39922ECEC94E39C0ED13FBFD6665C511C5931D846BA3835BBA127309AD4F6BDD2ED51004EBB07DA76EBF7A1D0895C4314BDFFF3EBF9B77D06FDABAF24EBF705BBC79CFA73B9A6ABAB17627550469A88D74CD5602123F79E5F307FFA6034659E2DB51053ABA9554786DDE31BC19C475505BD34E342DA74B9A2CBF8EF9DEAACEDD56B6200A1F493274711A0BA87217128833EFE43A4999F1235F43AFCCA4E2A2039ACBD918E6E7314E238D7071F16604B23C820DD340AF873ABB113BFF0AA0B68FE295636977DA64A71452441F068B5B34EA572B403049846B455ED88AC149A0621AA040E214657C5665D5DB325F373B2CD226EA255A676CC2C82B15FD8797AB92656145462D5946680D77594CCBDB0AD87F41ADE107F5C1B288A261EF474599D2B46966280D95899D61ABFD79DC7F8C27E412B47366B8EA2951173A43CC39E72335EA9675B097CB2A436EEFBDEA740FE3058ED88E3C4E093A373FE75434CEF783FBC00E98C61EC2DA904D2DDF69651C54C30775FAB66E5F9331E335E765060651028183128165129495A9CD199CB53F4FDAF7926C7D0FE15B8A91689A280091A4AAEB0C5F53A357409BDF6A998EA56DAF2C14C12996BB9455A675325C243D68429EF41F82136C98D384AA96A07BEB6862F54DEB383C8BABE09F61EFFE6BB7A829528A2EC1915EBC144B51F67C5D03D746BE83A65AA043A10F50A9BC7BC02841CB9C42E779D3BE4580953403CA0FCE6CF72B485B84046528E6810B35A8A25D48E8AA3A119A653C413CC2BA5FF54D840C0EF1EB31E10F4933717D34D943188A88929EAFC179745F0638301EEB73774E63DCFF44B2C7A05C25BE537A07215710FCF5EBFBA5C177D450CF1C7712677666DC77BCA68D37462A07CE265C6B7C6EB9F77EACDBA12CDE9739D10161AE89AABBD0ABDD4D3503BC0EBB8169F7417C95AED4AD45D45883D4797813A2F5E58915C4A76D6736F18058965A08C948AE079ADBFC489A8D5A8DCB6BC487F4492DBEE93C6210654375A057C178EAC015B4078395E4C77DA1B096DEB11AE1A03A9B82F5140AE5922CC98A7881190E0593488C6E2259D7E6B772F51EFFA12008F504F61C0119D8719215FA706DDA9E9C8E23623C0A13E4FD0CD7419043F66C948B7ACB756235CB9DB3CDCEAF46DDF393B69453BA04651E5872B079F5D70CC3BFAB274CC12135D7CC1BF13EE6FDED1995F1DBF9C6E05D28A0D9574E50BFCB1B2F9920682D719EC5A82AB7B2E10F3DD48F361427DD546CDA22A6D57472FEBB7FF2DF4FFF08343004ECE9B54BA62F70B78F5483A67FD810C3D6789832056DC8EEFBB45EF43A1468F324EBEABE5795DCB178133A75F0500537B15A0BC4DDEA408DBE8D7FD6121B05AC4313C57C7DB7D66B7268A0A62A9691DE62E1791506A3580CD61A33FBFE8A8733F6D8E5B3848D30223CB5DC76B731A69A0C1230E92E43A88A49AD3ABB5612D4B28974A226AFAE6919CA9B74E48AE2292A4E4765E18D3D22195454C50C2836124DD47D4E6E80834EF4B9001295B039E531382EA5B900E67280F7B40AEA30E69A3B02847299CA0ACBD98FE42FB0D71C558FA3C85C5DBF1DF15FEAA9094BBBFCE8695D477C2777D9EF402B37DABE80BD94E0C051A88A7266919B349BC35B36F14EC0EA12AAEB4AAE10A0F9F58EDCC391C6C45BBA41801F37A1176739FEA35547880C85F9AC2EA3C0D5559201E5F07B5FD41D542EAC6C60013D52C0AC1659DF83507F96ACC8AF00051C7AFAD8FB6DBCC5F79FEA7561BD2FA257C2C7CC9B18DDC2F3CF379D69CC49CA825BDBD54EA15DD38215736BB4411BD2C6C2EB519D41EB57B6585A8F40C17486CEF28E20062162CB7988CECC0B2D742698F81B6D5EB5305DCD89023C4585E0C1DEEC4B3A108325CEE4B5FFEEFF52B06225FB69C63AF461ACE6FADC77573497ED50A9943BCD7FE97293E639DFAD1E38550100E873A3A1FF4692BE31B952F600278F305A523EB234380B9E272327BE5DBB708ECCE078A3C19079D3147D9B22164BC8EB7C11EE5D82CA89301DDFB2D017857CAE23DC4E216002540CB6A9C3E11F3125C5A8B947C677B0846BF4AC7CF40902295AA70723D874A6FD9EE6F55DC024CEFBE85733340046F9E4CDE744B7593AA4802F40C106998BB5B6893E9EC38BC3126FDDA3820F5EBD19325599433FD3276B4DF2C723EED1B4260A670A57D14329D766D7A045FD29E9416362087FD5D5D8F4BD31D9BD59B03862B8144C5034783A65656FCF8F2814FFECBB738522EFBE4B47AC46C6B3AF10F496CD16910FB1AB0D909AFE2957C611A2875DF02299D373F54A8024E925B353D2D9C68E086C6BB410493E9C793913E782153D8142F17A684B9A6CDB4648686C33CA13DD5CE8003B7D03D8B8C1F1BE2CCAE66B761BE182280F0F89C952C0C4D80742F3E6CCE5FF05A63CE2FA1796EFF2B5C4CDC423CE578019CEB91AE9B100971275883B328AACDA16146AFFD15DF33B04EB55CE094738B8A77772266B63595BE4DC28098F12CCE86B112FC2AE866AC29278ACE10DEB2183E0555E5661D47EFC52A4442030684EBA71D4370688A70E9379EE869CAD3AE55972E59C03D5F253A3F3B3C7937F66C7A256853B9ACD707EE854244C8B2AA6D4E6E486C6A7EC77A7A8C5082D11BFE3629942E554B5CD36F300CE324F704F03FB388720D569A683CC30608449D1106D7C3A941C4AE4BC31470F25CE0319E8E75135C2E76EC039EEF5EE9766FEBCBDE1085B4545143252194941F78AA0AAFCA74C4FE46B4CA58A32237ECB717327FAC80758D733DCB11239658C68DD85F6A32B5601AE8B2DC26441BCF30FC76054229D30CB0ABB81596459FDD8BEB47A38A0EA4ADCA3350FD943F051A4222CF36E0E08EDBFABA37F4EEE5F11F7BEAB540A3420AC2A744D23D5C329CA210D2DB6ED3DC3627E89818B937B4439B0F0CC926F689DD5F6A02E8CF2EA13040E3518FA2E6BC278758D69048C7C5AEAADD19CDC40C8652D44F89E763C5EF6EF80F12BCB9D548B7D482735751001D7D5AEF5CB8D89C0C4428A6AC465EE0CFE797AA5CD7A1A0A9ADECCDB93F2967FDA2B6C20A9628FF21EFF9312B4C70E0228726CB755929C99993BFEB0C2F51E78C770FA3B4B03B68C9FE177979EC5BEBF2F1C217D87BB39F1341011AE9F8C02BE00BC879DB9AECD5CC64EBDBB45E5274ADEDED91E282889C271D9C66BE4BB40B3CA2DDD133E432A461185BCED5E733EC6089716CFB9B11F23A265E19703E2F78107B3D5D5AD067BE039CD7AA7CCAAF7E96E5D65FF1EE5D448A3A5090B2BDCF2CFDBCD0E74533167211047D9233532A46E70CEE5842BBB54A982B87923F529305ADA734AA71AF33BB47FB6017B3E8AB498B03B0262DF3B3CB83BBF26DD1AD5EFB25081584D5E70640ACF0311B2AC309EBA8A5A31F1F2866A7119598E78F642ACF2ED38450DE04885BED58022C77143DA31E3EF903468992EE3196EEB4886A471D9B44748FA1CE22AFB97A47596347CC76130B0B351E0C2CA88241AA8541EA66C816E6DF0C572BAE1BE543E687E30717379BCEC1E3540A5A6AFBEC3CDD3005769BDEAEF507196ADDFF61797EDF4F61B43A5C4F9253135F0F81B292E35414748546BA2EC0000000000000000000000000000000000000000000610161C21262B363064023036FFF06D26588D8593297243B4652395F4E75E4C8C4911EDC1D44DC344D35896F925B371ECE9495DA8B7CDB161D516A202302931D09625483B360FAD0FB0C3A9C7D30E4AB60428862CF32BC736C84E53183BDD02A5AA7C114EA69DCCFC6D62C518B5 + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-87-ECDSA-brainpoolP384r1-SHA512:COMP_ML_DSA_87_ECDSA_brainpoolP384r1_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 8EC14DCADDD6FF3C6AADCA241AAD0CC4393C96CD0DCA8D9A3FE7B2CA26CD3419E23D157740538CDE1EA4A1D385A365E4567333CE19D118BB20D91BD39846B14CB74A3FF77DCA5B00A60415168CB1EDEE73E7F7623EE5D13C502793F53CA2B581DF778C3CA369FC4164B7E4ED479BB6986411D3D24EEA9BFE1ABE7599A2755FE06399A1017F9FC09A926BF26F10238B14E20FFA54A209619B48BDC299D87F9D9FA888513B80F600DB4D26EC73EE3D0252F751DF19E2A12C5505C7E66C4CAFE29F9EA6CE8523023008BB63E20380489631C87B37621CF0DB42F31F8FE9204EB42AF254DB0770CCF0419DC879E4B26F32123A1ECBD59909251A83C3394413BDD160BBAC2DB1EF8A8FC98ADCB00894C1029916F0464A2399E23480B99F3073BF041FBBA6273AFE01172D4DFA9064DC8C81AE2F488E7D761158D1F0903B6FCDB82E90284937D48504DA1F92EB7E437BD52E462077ECFD9F30B93AC42BD7263744B83F6FD3FAE7D513C717F61D9B3330833A6009D01FC48B99E00F893FEDE5EB47E5466D90BB9A95AD0CBE0F700013F0F14590EC31800C2AFF57556B86162E8BEA9F46C5D1D8BA60412176AE7A29E9F3CA6E134552FD1211D13B07B926454D9C600156819F3E8A0175924249E8FC931608439E7C58DD4A9B832552A1EEC3DCFD8975D2D63A4DC94947A3200EFCCB5BAE5C6DDE47173617D82F0462D57051CF251CC53F3D84DAE8E029F154223E6B629A9422AC76B6B2C69950EBA6904F198DF406474D6CB8FAD425D055C915C531097EB41D3003867FFCEAEEF91ABA000EED5126EF471DB39DF6938CF89E19115FC36DBCAAF873C8E94F12A725B030242A24C0AF3350E4373289619F4AE4E4625DF3E39AD7D060952CDC491FA2EE649CC24B69AE5EBB8E033D793609A80CAC49CF1EFF44D2994FC5324F0FE90E3CB68492496FA61EBBEA65EA84F577347FFE8D560ADF3ABB801D26851D94EFDCAA53462BB4CCA9272BBB9308011EE2DA551E63AEE0085B012AD7455945D8A82FE231F85366A8E1B15428AA2959B6EEF320144028431A59C575B83EB693160D8D0D675198E90ACB28E784552E1691498DEF6662337AA1F9EF4C82E2AF4A73C3B7B95D44D2DC4EA403F3F747A944FFF5831EFD539A23CB9C5BDAA4EDE489883F832DB17AF04B334F0EF16BF199ABAFC881FB87509AB6ED07689BF17BFE5459F56EE0149BE29DA6CD9B5BA7BF87C8FD71283A010E20B0D45341884F2FFDB24EF9CA1AC50B78D532FA611B0D2F370E96D1064BBF832238363C04A880D963AA86015E37E5F65ED53119671D82B76E75877B7D084909A7DFBDCAED087E07262EC5273E84A60A0EE4372E8BB1CAD17666D79226A505A56243E0536F95D834739F702EBE5ADA0AC6276AD744795170B1FCDE8BF5A69E08B13C53604F6FCB5F305663D098BFE0F830EC55AD757123C3E5D8975689E18B46242FA5A408BA1382C060B784EEBDB611AE408BD6C357E1E1F3717B4BFC74B0ED2C32AB334E19C090D93C36CD8F1CEF493DB293EC67278F24C202F37AB47585302A7C5B267C2262D931A8DC17AFDC11EB6D1C51355C546A54E707051250F5C08BFDFB994C5160825CA6B3BACFD0328D5071FF648A5DBA14F8FD73299B80C0620EE6390C5B3ABAB40ED3486462889D501CB17C593DA0DD332C2CD8F12F4BBA10EDADF8159C30AA8722BC456F5BF8C9ED22DB1C2F54E6EAF1190163C5B651C15E9CFA1AD8F5576769EDB0E9AFB26B7B6930F11E7A84398E1E954C25654D95E1D8BE1903DBBA7CFCC888EADA155F27F84FDA80875D0FFD6F78C0FA1DA6B78A416711E39CEDF8B5118FED2163EBBCF2B1B7944127DE0FEA8D21CF1A33C0557D8B1B76A0D6CA6C3B60EB8412A2EB00223D6121E3F99180238A4CEFC7177DB4397AE84C6F1FB4B116FCA0E3485AB025820E92C091274EBE2B9BF1484AABC196BF2667BB131150F6D8F5A1E6E2669FC13FE2841075D76EBCD9599DFCA825ED1BA5F0572AAE02F93D3CFA74083BF143D9AC725928D698BB4C3112EA85E6FFAE3899E3AF339B2F394560FBE2DFC84CA5B63B3745112514C47F0F47DFE1E74CECD6081170416DAF67CB221A62DF2C7A3A7390CD67D1ECFF824FC102AD80E753C07671419FB61CD4DB43FD4FA6EE2463A1821EA283FD9DFB9B68602492FE043E26D3565E089820131DD107B51B24FEBCA09432AD5C811AE583A0B788604A5AA1C5EC0387CB768203052FBA47FC40C0E43726D6B6332B642336DF5D0F227B4C75CD9D2DAE2B62BD3F00E72AED1E7F02BE2A209CD69C66D61762586B98C1EDAB2D0F187DF49F2679B321C9EAF3FACB6BE3AFB5293315B238A3AAFC9E070443995E7891B561926F1E960A20D23E2821AF0505C4B98331F9CCB973B5F72EDA1B2C1A7C3EEE9A57FA58BC987CCFA0BC6ED7F42292B187115FEB21A087E327148007A0963654C70F99169290B4EAD313AF618AEF37F8EDF685D7ADDB45E73B3E1BE6973FA427FA79BFE66FB35A471BD297983D3CE1FBFDF283830CB97EB05F99AFC0DF4AEA1523D1CE1DC0934F940DB7B86CF16B5D76BD5145028F161A8A268570AD8718679C18A7F0E9D0DE38CDD03C4C69E8D8ADE6F0E443F6AF76779761488796885B47E387532E282A17D1D3E82F1CE2081DE18C0E124F52B0B02FD3324E03DF00FAEB79DAD529E303AF475FA6D7B345C0C0291C7A46F243890D3D8B44915F5A1C01F5AEF80D92016BCF505D54A76B8A3129844A098768FB6B9393784177FAE9B1845F03B0659566E80F18AE9588BB05ADBC347E3EE8BD26ECE0270E9B3A5EF279B1030985CAB4F382C10B6ECADDE514E7AA4C4AB9A8F07F4943FF9FE674537610B687A3F71B9ABFD21B09F068C19002BDB1874E1C616F6B39922ECEC94E39C0ED13FBFD6665C511C5931D846BA3835BBA127309AD4F6BDD2ED51004EBB07DA76EBF7A1D0895C4314BDFFF3EBF9B77D06FDABAF24EBF705BBC79CFA73B9A6ABAB17627550469A88D74CD5602123F79E5F307FFA6034659E2DB51053ABA9554786DDE31BC19C475505BD34E342DA74B9A2CBF8EF9DEAACEDD56B6200A1F493274711A0BA87217128833EFE43A4999F1235F43AFCCA4E2A2039ACBD918E6E7314E238D7071F16604B23C820DD340AF873ABB113BFF0AA0B68FE295636977DA64A71452441F068B5B34EA572B403049846B455ED88AC149A0621AA040E214657C5665D5DB325F373B2CD226EA255A676CC2C82B15FD8797AB92656145462D5946680D77594CCBDB0AD87F41ADE107F5C1B288A261EF474599D2B46966280D95899D61ABFD79DC7F8C27E412B47366B8EA2951173A43CC39E72335EA9675B097CB2A436EEFBDEA740FE3058ED88E3C4E093A373FE75434CEF783FBC00E98C61EC2DA904D2DDF69651C54C30775FAB66E5F9331E335E765060651028183128165129495A9CD199CB53F4FDAF7926C7D0FE15B8A91689A280091A4AAEB0C5F53A357409BDF6A998EA56DAF2C14C12996BB9455A675325C243D68429EF41F82136C98D384AA96A07BEB6862F54DEB383C8BABE09F61EFFE6BB7A829528A2EC1915EBC144B51F67C5D03D746BE83A65AA043A10F50A9BC7BC02841CB9C42E779D3BE4580953403CA0FCE6CF72B485B84046528E6810B35A8A25D48E8AA3A119A653C413CC2BA5FF54D840C0EF1EB31E10F4933717D34D943188A88929EAFC179745F0638301EEB73774E63DCFF44B2C7A05C25BE537A07215710FCF5EBFBA5C177D450CF1C7712677666DC77BCA68D37462A07CE265C6B7C6EB9F77EACDBA12CDE9739D10161AE89AABBD0ABDD4D3503BC0EBB8169F7417C95AED4AD45D45883D4797813A2F5E58915C4A76D6736F18058965A08C948AE079ADBFC489A8D5A8DCB6BC487F4492DBEE93C6210654375A057C178EAC015B4078395E4C77DA1B096DEB11AE1A03A9B82F5140AE5922CC98A7881190E0593488C6E2259D7E6B772F51EFFA12008F504F61C0119D8719215FA706DDA9E9C8E23623C0A13E4FD0CD7419043F66C948B7ACB756235CB9DB3CDCEAF46DDF393B69453BA04651E5872B079F5D70CC3BFAB274CC12135D7CC1BF13EE6FDED1995F1DBF9C6E05D28A0D9574E50BFCB1B2F9920682D719EC5A82AB7B2E10F3DD48F361427DD546CDA22A6D57472FEBB7FF2DF4FFF08343004ECE9B54BA62F70B78F5483A67FD810C3D6789832056DC8EEFBB45EF43A1468F324EBEABE5795DCB178133A75F0500537B15A0BC4DDEA408DBE8D7FD6121B05AC4313C57C7DB7D66B7268A0A62A9691DE62E1791506A3580CD61A33FBFE8A8733F6D8E5B3848D30223CB5DC76B731A69A0C1230E92E43A88A49AD3ABB5612D4B28974A226AFAE6919CA9B74E48AE2292A4E4765E18D3D22195454C50C2836124DD47D4E6E80834EF4B9001295B039E531382EA5B900E67280F7B40AEA30E69A3B02847299CA0ACBD98FE42FB0D71C558FA3C85C5DBF1DF15FEAA9094BBBFCE8695D477C2777D9EF402B37DABE80BD94E0C051A88A7266919B349BC35B36F14EC0EA12AAEB4AAE10A0F9F58EDCC391C6C45BBA41801F37A1176739FEA35547880C85F9AC2EA3C0D5559201E5F07B5FD41D542EAC6C60013D52C0AC1659DF83507F96ACC8AF00051C7AFAD8FB6DBCC5F79FEA7561BD2FA257C2C7CC9B18DDC2F3CF379D69CC49CA825BDBD54EA15DD38215736BB4411BD2C6C2EB519D41EB57B6585A8F40C17486CEF28E20062162CB7988CECC0B2D742698F81B6D5EB5305DCD89023C4585E0C1DEEC4B3A108325CEE4B5FFEEFF52B06225FB69C63AF461ACE6FADC77573497ED50A9943BCD7FE97293E639DFAD1E38550100E873A3A1FF4692BE31B952F600278F305A523EB234380B9E272327BE5DBB708ECCE078A3C19079D3147D9B22164BC8EB7C11EE5D82CA89301DDFB2D017857CAE23DC4E216002540CB6A9C3E11F3125C5A8B947C677B0846BF4AC7CF40902295AA70723D874A6FD9EE6F55DC024CEFBE85733340046F9E4CDE744B7593AA4802F40C106998BB5B6893E9EC38BC3126FDDA3820F5EBD19325599433FD3276B4DF2C723EED1B4260A670A57D14329D766D7A045FD29E9416362087FD5D5D8F4BD31D9BD59B03862B8144C5034783A65656FCF8F2814FFECBB738522EFBE4B47AC46C6B3AF10F496CD16910FB1AB0D909AFE2957C611A2875DF02299D373F54A8024E925B353D2D9C68E086C6BB410493E9C793913E782153D8142F17A684B9A6CDB4648686C33CA13DD5CE8003B7D03D8B8C1F1BE2CCAE66B761BE182280F0F89C952C0C4D80742F3E6CCE5FF05A63CE2FA1796EFF2B5C4CDC423CE578019CEB91AE9B100971275883B328AACDA16146AFFD15DF33B04EB55CE094738B8A77772266B63595BE4DC28098F12CCE86B112FC2AE866AC29278ACE10DEB2183E0555E5661D47EFC52A4442030684EBA71D4370688A70E9379EE869CAD3AE55972E59C03D5F253A3F3B3C7937F66C7A256853B9ACD707EE854244C8B2AA6D4E6E486C6A7EC77A7A8C5082D11BFE3629942E554B5CD36F300CE324F704F03FB388720D569A683CC30608449D1106D7C3A941C4AE4BC31470F25CE0319E8E75135C2E76EC039EEF5EE9766FEBCBDE1085B4545143252194941F78AA0AAFCA74C4FE46B4CA58A32237ECB717327FAC80758D733DCB11239658C68DD85F6A32B5601AE8B2DC26441BCF30FC76054229D30CB0ABB81596459FDD8BEB47A38A0EA4ADCA3350FD943F051A4222CF36E0E08EDBFABA37F4EEE5F11F7BEAB540A3420AC2A744D23D5C329CA210D2DB6ED3DC3627E89818B937B4439B0F0CC926F689DD5F6A02E8CF2EA13040E3518FA2E6BC278758D69048C7C5AEAADD19CDC40C8652D44F89E763C5EF6EF80F12BCB9D548B7D482735751001D7D5AEF5CB8D89C0C4428A6AC465EE0CFE797AA5CD7A1A0A9ADECCDB93F2967FDA2B6C20A9628FF21EFF9312B4C70E0228726CB755929C99993BFEB0C2F51E78C770FA3B4B03B68C9FE177979EC5BEBF2F1C217D87BB39F1341011AE9F8C02BE00BC879DB9AECD5CC64EBDBB45E5274ADEDED91E282889C271D9C66BE4BB40B3CA2DDD133E432A461185BCED5E733EC6089716CFB9B11F23A265E19703E2F78107B3D5D5AD067BE039CD7AA7CCAAF7E96E5D65FF1EE5D448A3A5090B2BDCF2CFDBCD0E74533167211047D9233532A46E70CEE5842BBB54A982B87923F529305ADA734AA71AF33BB47FB6017B3E8AB498B03B0262DF3B3CB83BBF26DD1AD5EFB25081584D5E70640ACF0311B2AC309EBA8A5A31F1F2866A7119598E78F642ACF2ED38450DE04885BED58022C77143DA31E3EF903468992EE3196EEB4886A471D9B44748FA1CE22AFB97A47596347CC76130B0B351E0C2CA88241AA8541EA66C816E6DF0C572BAE1BE543E687E30717379BCEC1E3540A5A6AFBEC3CDD3005769BDEAEF507196ADDFF61797EDF4F61B43A5C4F9253135F0F81B292E35414748546BA2EC0000000000000000000000000000000000000000000610161C21262B363064023036FFF06D26588D8593297243B4652395F4E75E4C8C4911EDC1D44DC344D35896F925B371ECE9495DA8B7CDB161D516A202302931D09625483B360FAD0FB0C3A9C7D30E4AB60428862CF32BC736C84E53183BDD02A5AA7C114EA69DCCFC6D62C518B5 +Result = VERIFY_ERROR + +# --- ML-DSA-87-Ed448-SHAKE256 --- +PublicKeyRaw = COMP_ML_DSA_87_Ed448_SHAKE256:ML-DSA-87-Ed448-SHAKE256:E431AFB3371D2CB40B06D0F8F32A6C915A3F5DB6C397887721FDF176E95CF8DA9A3E0A24AF68C535FCBAE2C0C68765F7512AA2DEF8932BA354C8597F6CE996751A65EB2C2E515DF44C6F60010569B706350E0D0AAC0FE8770EA142810BD81763D61FF94C1262DD591261FF938B404D3AFD082AA70D18B7EDFF9A8DA9973F828CE4CDEFEDDA712D429AE4195EAEBEAA4322118DE6907D87701101B247CAB1166DFDE9E2CB74B76ED28C3D8316E9DED1A3A2BA57FF589B31678CAE48EE834BAFFF7A1E91C5350134B75D4F90ADADFF058F84D032B41FA74131FDD07ABCFB1175DD4F5F9AB872CB99BE84D8BAE84909B50AA945E077AE7CE9080F8F33EC47EDAE4FC294C689020167599832BF7DFC473B4F2CB6059073708BED191CD6ED168E56F32154DA47C2AAB92FD9F343D5B69BCA2415FC16A464E002BF843FF86982DD36454DA03AC3C66B7B3F9B55FE68EBFAE83F3608B053840914BA6461BDF67BF3B5272331284DAC721085894AF51A47DCC558A0383806C35CBB1A5D48D922AB40390231C43353C672A15FFE966BC6ADB3A0096013EC2395D72C861BE98D15F7C57DB70D556AAB4FDA5623B23816118A41A8C2DD47E4782F672597271014E8041054B626DA478CF509E3FBCB6DC49351119C91AD26BB5AB49D833068913B4E359324F97410F5388B0B927F55B4C29BD904E6DEA6C754033BB18E7FAC7F92198C39248C4F7F01555175D07879E32B17656DB3E44DCD5ECCEC8D0E2CC2AF59D2C3A5850BABB7AF92005CBD26E86F29EE385C1BE987AA9ED0A5D82B645267F2820E735731F1D75242511CB29153582C0238C4060DAC7A2FC9C201447F27DF7C59CC4A219400A87572318FB863ADBE7146D9AC409CD77D654FEA132A790571D5F4497B3869AB8802D7FD4AA9C48A79C0D6D4AB4572A3088E44BEADA3C1D210B7834FB99C64A7B8F107975922249C6FF5EE7B60DD9EF564BC4C5B1E5C065125CB2735E0732D12F71AF689A24E220C22BF5324E007B4B90F80BAA64FE3FA58C4973CF6CB2321A5BF779B1441092C578FAA7238D4C5140EB79A361F638F4C5A7D5DCE4008C55F242E099DA1802A985F2339E4930EFABDC8265B535A31CB5F7ECA8EE087DD67CFE5FC214F51F2C893F86BF69F1060C1B1D25DFBBCF4BD5F9C192A4B950AD1EC42460633E4AE118E0D4D0094AB3F5188A41D59FEF76B0DDEE805D940B7F6551FE702653FCCF0162958AA8B18208C2FABFF88E0CC15A308CF9F9FF9186174C084B66500FBD3DB6BEC3B8A315EEDE69DFEE11C4C9FA569DBCBF9DD40FF28982FED20DE28F446035707CE1540CFBEFBACE154163F779D4D7A6F39065AC84B6A8580A7E8221340C6E13E42EC9C2545629CAAA1F20A57C3BFD9F45A08B4CEFAC83CCAA37F5BE7BD4780AD7EE2119117D95F4ADCFA44F916FD98772FA706BA99B25A295996BD6C82E82B61B7B97799B2D4EA222F66C58613EB62744FA4D7F573D12B9BF5FC7AABC2CED6BB037AF7CCFECA27333E29F251CE31514AF0173804328BFD51C1C6D2DCD96A7F43A94C223F07E40F5F16C0DB614447B67BF380422206B74001AD4A4FCFF066833922585F5D8E6D34E85E4E290532D3F9CDE217759B01EB6E3E668EC558778C433295FF8A67DCE72996AC893253C4EDAB10594E45600DD8C4266F42D37B3B6B888F7025C832CD22189587F66D7476C42D679CE2E61AFA84C90791FEBDC0C3ACDD08C88E6DC9638F1E55273F6EBD7626A971F24461D2A06E3B9125EE509C9BD7351FF6225FEF61A1A26214BBF7E3F7BF69EB34523317D79B47C46169D867534104E189E5D2B63FFB4F61334571012CF48F5548C8F7B932D1152AF5A995EEA929189D2788C0C92278FF95874A767BA039571CF13C6D784CF97B586E4A572366AA89BBEFBA23B1262F0A9C9A5C81F4DE927F4EEAFA886D9E0EA19A85554BA4512A01C61FA6C1F74E2A2D9D67F5AFBBB4947278EA663809653CFD2D2152D67197CD56F44C69461B7C1BCC420B61E969E78ED8752D223C2E8E9E004597504F80257B6B5BEF0317A60CB9F146FC2B0FE804F92AE82696F2C138D95F2E40B9682B7A70942C4CD98FFF15191D200CDAAC6128B7B26C424D7F735B7B778E6DFF578B1BF38F2647124D038DA623B23FF0A56CFD357878F18E8B30081C42D77B5F54D5D7BCAC0B6FA7C0DAFA3445845B0F3EC7B10CC4FAABD90793AEFCEA8035A41353A1571A20E733FEE860A9A6015FE0516B6611849D8EA3D1759BF98EEE4F22F5487DE81F6E77E727E1CDBDCE69D22D0F1F471CB5391E9AA1BEE43868134CFA6C1D743690C3959A0083E9D560960D64391165F8FB48DB689D7EDAA8DF3BC663A8045E878413913A72AD6F4DDA96D1A0582A97CA2BB4AC88DD9FF57B544556DD19776221662E1B3B499CD3DDA75E52A36E757B6D9EEE6C676D1583CC524668E8CFC1230858952E4843B3BD3B4AF21251DCDB7743CD2843C704C0DEE3AA308220B2BEC91920A90FC6A591CC65B4582CA27E93CFB7B923FB9B1EC1BA60696DC8CF5766154FF3AD71E500FBF9AF0B934ECDBB9C78B8D80E92AFFDAC2D2439D542C19DA47076423905B831D447EA78E5B00C2AC08F3B2F988E31286133A2E68643951F3017B2FEAD95A3C6C844DA00B41CEC20BB1CEF989EAD3E44B524D5A8D5C6359AD6813F778406764441F8F97F69C1F9B13855B7F69B4020DC3586C7B15A387F194DD5311F51AB248C9560938B8F0E7F732B84BF8BE059F47D7DBDF02CAC5992E5E7B0ABAAF4081A1BF6134ECED7B8C82483CABCDB99ABCB8AA7B57A0B30A044A30A0FC5B036133AC04824550EF822EF9CB476FFD85F1584F74538283F7C69CD001910083A79FE767B0A37E7026A076FAF971CFF2E08D0F0452B4C8B42BBAF89E8EA48882CB141BD29B95256A4824620E767ADFA66613DB0136F48D901046D92CF72E7DF09B4A2B2D71B94CA1FC1F409F3ACEAD0783E27F04A23A1CB4C0F25F20AC4469C1480AE1D0DB3A0BB97D3E6C9168A2EDFC2AE5BDA64CD21F110D9648799C030A4A3097C9E9B21453A1645028B3F3A4DEE1A2E9ECB7CCF21D803EC4873420A73995DADC319A22D555B4A7E6664515456A27B2A22240AF68E2E27CB0EFDA4E798B6CD7B17211E82163C5F620B2AB36AF7E625F9E86CB067682C7D1EAFE172DA638B465D3C9DCA6E1971FD44B192993EC328004EC25480EA2C46B3AB7E8E3CF3DC91536938F6600D835847137827A9B50C6FD7AA1365BC1D5BAF7B3013699394E6FB80090F341D1287390E93ADC5B3409A56BA90339D029B17662D19F5AB3FD0EE9B6F0D01F1F5724A1ECA95743953FF63441192A646C50DB9113CF7EFD979602EAD4CA30F6B369B85104FD4C163BE6B3B8EC6D32186A592A62FF6C452A8AB27FC97D641FDCD1746F78E2A0F6E24733C20B89B2AABF13D488B9851755E7962978D08E4C393548762987FCA579B25F1E258EEF688B917A97475B350B1C570D69AA1776123CBC171BAB921F29E0CD82001B58444471158A463F9C834AADA291651451CB9EB0075395784B3D3B1043B9A603ED170ACDA24DDF1C3A7C12C3F1CBB158F7B95EEC29E7A1DC4AB9D49857392711F223AB9AEACDD64F18FEB1793D1F83245A990E576DE87F1AE289048961FF4826DAB22F2F6B91A756FEE4B28A3AA34B6DEACB15223F0AE2C0B761EA20FF6E437A49EC157EB6A778B62BBFEA8B71A18184245DF8336FBF3D6A89465E5DC5DD1D0B61219905100 + +# valid signature +Verify-Message-Public = ML-DSA-87-Ed448-SHAKE256:COMP_ML_DSA_87_Ed448_SHAKE256 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = E847B66862BEF1979B029A7EC22468B336AD33634E1BC8733810107888BC7DD204D7968FE0FB8EFBE26F58D28CD3E6672A9E46C101E95678FA27071B615183379F140431133C192C7D8BFCB264DAAAF300CA51A0635D5ABF0D4F91C0DCD7C1031B9F556FC67BA2F81A6FB975E3702CE5E435FA03EC8D9AAFAE604284BE4F9B0CA98F507BD992D73AB2D3A4B9F0A485FE0EE8A16A1CC7027BD9D3C60CD003C47D6CBA3A7D7F500FEE6CEB1A0FF4EE800BDF1C736C2F5F4AE93A8C7ADFF13987685DFD4B9B40EDAD9346844D90F12A11C8235CDE310FC90F5E09E8656F1253C4C76ED8F8A05509DD46AACC0618DF1B8A38D3431E0A5962528A63CF935C570BA14B59D272E74F0D45ABA00D186392162F59BD34660A1B195741EFF1DC1395DF28D9877F3C0EEC9137B55B0B7A1CDB99A2392F27A77268C26722FB8FFC96B808BD2408B33BF52BFA68C1B44D11E37614020770E7774865B486FF7DAB1A3114FADA24701EA6C58421FC5B1246CB47DFAF4585C9E0BD0B1015EBB2F911AC6820288AEE4D98C962846A414386552241E73BA088E6FAC989E45256A8404B65700FA5AD05A3D961507FD7054F1AAD3108166315441340C7BD807A242AFDA5C630B7CAAFF3B0C593E4F91DD7CD53596991B040943E0F675671D5BA23A2997086A4558AB4127FA6FD10B00A68AE728C31C74D115647E6C22E7863FE5E1E4B87F3325D8CDDA9CA6B1522173C13CA3FF0DA9E9C199ECC574C40B18955EADC7A1139F19ECCB4434CC529270276434BBFDB0FE2E6D9520D41855726E881528B8E1611398C1BAA6D1120D3AD0CD6B9EE523370F531D66F64DB79B3F53CDF708350FE8C627E076957CEE004E818E1BB730C3025F952C0A47D230FA151A3A4D151E023C99956ED75A0A90E10E42D0EF6924066A41E7BC33568FB05FCC0C3A667C5A7F427055B0A246791E99041538378B0B452D918E908BDC940FDC88DDE1EF22DBC6697A4DF2C82937AE6E9021DB73BF906DF622FFD47F0B019AB4EADD25AD5DAC3756C0CF6B8FB7A3F8443C1E97EBD43E544D18A8B781F8070DDF29BAD511FFC066F931AA40B973D833B1CB67209CE0C88C9C80D8A59CC3DE24B0D2F163ED3641399D6CA4134EDDE2EE3A602C44AF678E2B3A59C1E806447064547B4E0A94FDE7CC9C55FB9911B756A192AA0B40E11F1E5CB52FE4EB47996F59B0BAB0E748E4C16CAF0A02E05AE9BB59785A199F1EBFE5EE6FE2712A1050AFE1B1C8CF8FFB37985A54792887040C4E2F765164498BE6017EB3BE72689EFCFD88F4A5ECA902F745218BACC2C404FDAEB5D703A25B581A0E8B3EF79005570A83EF964BFFBDE53A5214B8C6941D6BDD35773F620F386B6CEC18D1DA0BA4072061605D8D8C5A05C9869722CE4498C31857A12D17B9A38E46CC46B19F43A4E076153CF8B398D9C20CDB96956CA36DB83AECDFDA720B8462A914C9743F2349EC4694FB86CE30795C62B5DD01AE0CA91D37A27AE61BEADDDDA8A3A18BCB2969F56332D87739E760621408A044E30BB2B8664633FBD873244167DA9883F646EE6F6CCF2FE587B60446C18C65903000830D5B3349EBE50263D66FDCFF816B1E684F5F500B29909796F2828F52E18FFD64D91093057E4F2759323FCB0499F78A1230EBD9F6DEB2092D09C08C7546E672ECAF0B32ED934A88A8D8EC189DE8F13DD4CF748DB9229A5997E340988528D5AA8C5B7479C7461E94A8DB9447BC4D330CCF3BA706031D8469D28CEAFEB6A94F6014D701C8DE424244C1554ADC9AB119E07FDD06FE64302301160C11D58A57380A8E7C2DCDA18BE87C68AA283ED89FBB057BD3E38FD5B40FBE98FC9B5F5AD9B32AB0666103B98997884758819F81F61C1531016CD4BC33DEF967CED8A0225FBC392FE39C81EAEBE54306DE1417794DF645A5EED5E25A4523E332989D39865A31B2C39509C35F3B74CE4A9FBE64EB44A0B35AA396A01B671E22FC0A070F1D1EB354CC5DC82731AC2E0607E5328227146445DD8D551D4F369AE0AF47868C8CCDD6BA2FB41D0CF5627B7A6B249C4656E3D751F230C069ADFE39CA6F7A762D6297928DF17DAAEADF2065275E218DB274358DA396B2AA483A988793A32476051DBB20F03AFE727B6D908B9BA5DAC1652BB985D42ED94C64AC81E5380E103AEC9D5153040A02D50F9FF1259D3E9D4761B483FA9B7F984543411452F34EFCBF736764B4BBDD9BAEBE9583B125A11B91031690AD5370F263B10C7DBF2E77D2576DEFB6D8682B6878A096573CA67482EC7AA51706EA0BA6E5E2C9A129316FB1B225A1A2DF3860BF7167356F8BE34F7C6A8A7001741216BDBBA353A8E130904DBA6BA915A6AE992B34DB35BB34C622AEDB508230C58A404CCCD508B229B38D1C775F17DEA87EE58B51B13B58295A1864895FF899B661AF9023A5A83FEAD89267804E89C3E3E153165F67FEE1BE1D0A68E83C308DB2EB5B9507A8A7B48A2116278B516FA53F780D3D3B6E57D67C966CF116469EE54308266DDE588FD7B097D784B61B48BCED518146C544E74B6D60C6B3C85E6AB25A8E2EBF7BD38B8F13799A355A873ACE1187B41950B89CE98F686A57A7FEA910F7E8BB578DA0FE041601A232209DAD6B8313F801A71DD569FB3C25678B0DDC6ED4E0B5F7480B359FD168EE16AA16450149FFC12302AC4C74C933D6C218F60D32FEFD741787D48B1F20504B911462ACFCAD07DE4F3A1D9AF3F2305F8E5097962BDE4EAF7605C2C8D3AD81134F679CB1D9A74D8169BD3122BCE004CAEA28FDDBEE7BD211DF7A4FCF59B8314DD09032DCA5155458385E8D22D4EEFCD5F714B62917C16BE935FE078A21E3F281948582659126EC9E6B70A766A067291B8CA77F19EDAABA41B87805AA3E4654779D375CA869887E871CA5BAE1BFBD9FC3BEA4D9F0B0ADA6F8468537B1F264D1AE34F71BD68894B7D4533FAB99BBFD2888E41DF85330137021267D623882E00DBD42A2EAA93EA4DE4FE2D88DEDB3BC23C677DC02D25BDECDEAE9E1112C15098BD837F76ADA34945EE0F86BB7D4B7522266BC24DAB3F03E2C4B524A25F977B5B68AA5A72986655623658DD36D92A9B5424523A88C0FE39BA54D4926F6AD802418F553B1DAEB3BE6E25C90F95CE313D91E6EA3CDAD5BEEEBA74C306333BA28927B1C3B82C16E45686113A672CF09D986855C0C0CC7EAB9C31E2E351882D8E00111470ED2B67EE2211E65E12271CFB12AB819DCD662AB262AA0AB702A269832C3E79724F16EE58BA9AF1A28DCAA49DD514740FED7071F4248933D9252198CD9239F773ED21933D4CCE7700883A7021E77A8D8D8329AB1A325548C8A5568FE3DD38AB54004840DD32D9DE56A1B4207AFAF4D0BA8A49173E1F13552B57A6CAB43D4BDD691AB1C6554B0971E9681FE8241B19EBC31AA2C8847FF6ADC980249B5540F1576410587791AF230E13557B1B40B1921B6FC7B206017D9FA7A4F36797AF41048F5767E55C1B2E5D749304720EF9B7A6201B19F9CA4930FA6D5388D85504930AEADF59C49D24CEEF9AE454B0A3BD4EDF658FEA455A901C08B84086FCE9E7D2B005AB16EEE1EDC724C74E3CC8F80300857F17539318D9AA951B555C84E70FABECC6788B14833FA7C9942E5109FFB998BC6D9D101FAF357823491674BA8BECB7A6355E8ADD9B1F213D749CE560159942483DA1F59507252EFC1ECF5CB084FFDDC4384FBBDF8C35FAC801F5606A6686761A8DA207D640B53C63B6FB4FB17C10B529E5AA11CCB40266A8BA1F92E8A9AC45DF2D60F28D52F5B7F69E0F4FF62DA7121BF23A6FF5A750A92E475E7E53AE98C29C80D60AA9F29250DD178F26892FC4B4996F157ED470BA45667863E1FC4B2A784BE2F1596FBA429334B5D9393A447E3F05B2FEF0B6BFA6B050FB764816188FC018271C25967C6C7E9CC420A08E270ECDC72A976890624E94FE607323E71AF582A48DB0C41B3B491B5EC64E506EF5AA62698D0CA6DBBA1270D2AFD033F18DE3A52FBA95072D7F2CD638F68DBE737CB880A43981BC3AB594143D29A49441BC58A9882EB7DD1B843608ECF6E1ABA4C2F1891BE8FC5D5A4898D326DCF008AE3035D14507E1C2930DDC3BFD47DB9BC4751F43188090B3E954FD90286E23DA20E926FC7B9075E06CFF65C8F47C388DC11E2C94C45652818D5BC1DB9CA3FD51B89C261F2A6044CD4D1C298E134DA821B8A118E3AC47E6F65826E2CDD7E5F289CB44503936F8C478C153C86EB2681FF8FF2669BA7345C22FF6F9C9D86281C0E8F621C7B22D93572BC96A03DFE3FEA6B8ED2BD972C17A796CF426BAD1A52413519251C498C4D85851F8B575831DD6E9D3AC8281A97AD4796A979D5D64D820A2CD808BE7EB58EBDEA5ECB0BFFE2C5778E63EA5941188C61810B10CC97EB5286EA25AD0540EFF0E67F4B287A539E00D3E56BFEC959A5AE1D97F8AB13D8FE058E76FE2CB4E97930D3CB1E1DBB1F1F000A94DAD2070BD687431C8335A027753362C4D52142A1C4A267B6B996F9A4555EAA4006EC37F22AA470869B059C22A6654B58ECE4760B261B9EF3A506DDE027AE9B63CA62C757E249C51EE1C9EF4EE6DAE282CF9E6FEB111A9D811D4266330231B74672CDCAA81C1E795D37F0C14FF6DEE79E4D0BF9F6F8D654B8AB103CCCCB2D7F34015DD039C47464A09E8DD29206D6F68B07CF5B1024660E18B3B013032CB5B3D1FB811D264919B841407C653D2A2A5801B4705A40B1FDBB374D66BEDE81BF241BFE0E8AD63429D87490C9ADF6948DBC62E0BBDE0DF7EC1D2DEF79B65957139947E3C049666AA05D7E89336EE3F577822C6E6F62E88ADD5C731F5213B78A31C9C06AED5072F25971ED9E25E93E63B8571C47494285ACD54FCADFBA66B9D8C7805A304C1F325DB2DF83F0D6096695C0ECFD031DB6D8A495B497A7DB51D78B7539C386518234495EF71182273197A5F22701CCB2C32FEE83E3CF0A2278969BF4368235BA85EB9E98C7647B356129AA7A5703CF1D64EA92A89612FDB7A87F7889F24D9437C0855A9A3F9C71596B35B7B689D723FE145D30FD7F8BA95543D3DE42681E60B17F6E221C049901E502ED23052A10ACB9EBF230C58C3D6FECF769E61C8A9BC2E1754839403D65CB399B986A3E645DEF3F76D8B4F29675DF6C60607C7EB8F9E1B4C4D240638D649553D55C048FF9F66801D75B4F111F57F1A71AEC54BB3A6B45A73B79828F83A2B7193A3FD2985AE1BF2AB461833B82B03A354CDD3CF85EA76B0AE77E9EF32FEA68BA7A256A2EA477216C1331630B7FB2CE45675D373ED5542EF59B733B419D8995A21BD94DE6566D8B47302273B580BCAB3B67DD7C6E18277506F069ADF7DF49F6BE51E92D18F0E1D8AF9219BD6D8654355088BF57C00179BF6C621C92C415FE19C2913E70E7B8ED78172ACF9D148CD0AC5D60E501DB3DBA860C10D8972B1015C26DCB295283A60BC4DA0E080BF3C8EEE78CF4A1CCC7DA8899CD9F4E1FD8CFD6EE53200D239EA9F6E9F604CAD195909C4040BC4CE487D355CC85E545F5C971B34B54D229D43687FCC795DB4D4378704F5D95C58B67AF7738EBBA5518227A0E18BD4068D0AE6C9BDF02A7BB8402DBB9DFA3E4F3386BE9F56EEA856178DD4FCB49F6C0F79DA74B132428F2E29DD10DBF2C159429719EA7A2479357B346F3F8D014EA98E5BA44E40686C031C484E96680524B2CB49FF6B21E67094202904D99C4FC0C46BD079B9EE77B922B5B94E17CE013B40334560578A22A85D5F7C6C4370ED391BF37292A5B01A7E4207949968A9F373B3BEC14F895E82752EEA1ECE764729ED181BE6B5FF705ECBF7540C2B603C92C500EAD4A70EB6F6F98560F6961238A66F30B9EB5220A835EA1ADE281BBE4887935F381094CB75178220A864B321488D4B25B41A55C42752800576F5F1516E8A203A22FBEE078946D1846D056B3311D89B7BF0FDE9A7AE87D26CA33D2626E5089BDF53A4AC16730F77837E50BEC3B1E0C570B233F0199822C1B9C455D15DE701CE161F1613924A51B6D180127F7AE59CE5B6B4BE92B22AD5654FD5CC06AFBA576653DE32D5F9940B9FA2CB20FAAF23B36E90F2898E8751A28144C630E29C50665D9C1E57CF6271B436FA3231CE1E6D8DF3C63184439587CBAFA672BE6F2037AC1C58ABCD4ADE1748F26E7FBCB360DAA783201186B2E5C5ED9BF1C51E3C20C1595B7995E96D5EAD632D5427C0449D34767F4BD73573C77FF12354921DF2DFF13F6A1B5C479C544F4AA74801284F409FC2DD8C20149F4D84138B69733A09F49BC00EAA4B1305A232E869710097BCCA1F29F5F7F94C931592D73790224EB4B18241AD667A129CB11B660FAA5B542E702BC9AED58EC71D5C0763E516A43408F3D29069A20AD0BF0DF9787E4CFC57A592FE610317680B7C9594B499FD5E8A60512A8BEB0C4A6A2BDDABA0F6BD13DD8E2EF2B14C0AD045407E5C37ED16205E64698CD9DBDFFB01042E30C5F317213A3F5480FA0E1B1C9DA0BAEAEB3F889ABEE4F61C272B9AD2E62F41454B5D7A929BE85681C4EBFE00000000000000000000000000000000000000090F161E242A3338E321E8EC09CD3F3F317C0E62011E614BB921B7613BD2F0960041CFB136882B6A634AFEEE6780DD058B6B0ECBD3921EC1BB10B8FF387422A9809AD1308AAEB4F6C172BD3D1B227C899BC5DFF33E7EC6DA42D1692ED5B3674998C4901EAC44251A7FCF6FFE00B931CDE48A144386B7B7020100 + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-87-Ed448-SHAKE256:COMP_ML_DSA_87_Ed448_SHAKE256 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = E947B66862BEF1979B029A7EC22468B336AD33634E1BC8733810107888BC7DD204D7968FE0FB8EFBE26F58D28CD3E6672A9E46C101E95678FA27071B615183379F140431133C192C7D8BFCB264DAAAF300CA51A0635D5ABF0D4F91C0DCD7C1031B9F556FC67BA2F81A6FB975E3702CE5E435FA03EC8D9AAFAE604284BE4F9B0CA98F507BD992D73AB2D3A4B9F0A485FE0EE8A16A1CC7027BD9D3C60CD003C47D6CBA3A7D7F500FEE6CEB1A0FF4EE800BDF1C736C2F5F4AE93A8C7ADFF13987685DFD4B9B40EDAD9346844D90F12A11C8235CDE310FC90F5E09E8656F1253C4C76ED8F8A05509DD46AACC0618DF1B8A38D3431E0A5962528A63CF935C570BA14B59D272E74F0D45ABA00D186392162F59BD34660A1B195741EFF1DC1395DF28D9877F3C0EEC9137B55B0B7A1CDB99A2392F27A77268C26722FB8FFC96B808BD2408B33BF52BFA68C1B44D11E37614020770E7774865B486FF7DAB1A3114FADA24701EA6C58421FC5B1246CB47DFAF4585C9E0BD0B1015EBB2F911AC6820288AEE4D98C962846A414386552241E73BA088E6FAC989E45256A8404B65700FA5AD05A3D961507FD7054F1AAD3108166315441340C7BD807A242AFDA5C630B7CAAFF3B0C593E4F91DD7CD53596991B040943E0F675671D5BA23A2997086A4558AB4127FA6FD10B00A68AE728C31C74D115647E6C22E7863FE5E1E4B87F3325D8CDDA9CA6B1522173C13CA3FF0DA9E9C199ECC574C40B18955EADC7A1139F19ECCB4434CC529270276434BBFDB0FE2E6D9520D41855726E881528B8E1611398C1BAA6D1120D3AD0CD6B9EE523370F531D66F64DB79B3F53CDF708350FE8C627E076957CEE004E818E1BB730C3025F952C0A47D230FA151A3A4D151E023C99956ED75A0A90E10E42D0EF6924066A41E7BC33568FB05FCC0C3A667C5A7F427055B0A246791E99041538378B0B452D918E908BDC940FDC88DDE1EF22DBC6697A4DF2C82937AE6E9021DB73BF906DF622FFD47F0B019AB4EADD25AD5DAC3756C0CF6B8FB7A3F8443C1E97EBD43E544D18A8B781F8070DDF29BAD511FFC066F931AA40B973D833B1CB67209CE0C88C9C80D8A59CC3DE24B0D2F163ED3641399D6CA4134EDDE2EE3A602C44AF678E2B3A59C1E806447064547B4E0A94FDE7CC9C55FB9911B756A192AA0B40E11F1E5CB52FE4EB47996F59B0BAB0E748E4C16CAF0A02E05AE9BB59785A199F1EBFE5EE6FE2712A1050AFE1B1C8CF8FFB37985A54792887040C4E2F765164498BE6017EB3BE72689EFCFD88F4A5ECA902F745218BACC2C404FDAEB5D703A25B581A0E8B3EF79005570A83EF964BFFBDE53A5214B8C6941D6BDD35773F620F386B6CEC18D1DA0BA4072061605D8D8C5A05C9869722CE4498C31857A12D17B9A38E46CC46B19F43A4E076153CF8B398D9C20CDB96956CA36DB83AECDFDA720B8462A914C9743F2349EC4694FB86CE30795C62B5DD01AE0CA91D37A27AE61BEADDDDA8A3A18BCB2969F56332D87739E760621408A044E30BB2B8664633FBD873244167DA9883F646EE6F6CCF2FE587B60446C18C65903000830D5B3349EBE50263D66FDCFF816B1E684F5F500B29909796F2828F52E18FFD64D91093057E4F2759323FCB0499F78A1230EBD9F6DEB2092D09C08C7546E672ECAF0B32ED934A88A8D8EC189DE8F13DD4CF748DB9229A5997E340988528D5AA8C5B7479C7461E94A8DB9447BC4D330CCF3BA706031D8469D28CEAFEB6A94F6014D701C8DE424244C1554ADC9AB119E07FDD06FE64302301160C11D58A57380A8E7C2DCDA18BE87C68AA283ED89FBB057BD3E38FD5B40FBE98FC9B5F5AD9B32AB0666103B98997884758819F81F61C1531016CD4BC33DEF967CED8A0225FBC392FE39C81EAEBE54306DE1417794DF645A5EED5E25A4523E332989D39865A31B2C39509C35F3B74CE4A9FBE64EB44A0B35AA396A01B671E22FC0A070F1D1EB354CC5DC82731AC2E0607E5328227146445DD8D551D4F369AE0AF47868C8CCDD6BA2FB41D0CF5627B7A6B249C4656E3D751F230C069ADFE39CA6F7A762D6297928DF17DAAEADF2065275E218DB274358DA396B2AA483A988793A32476051DBB20F03AFE727B6D908B9BA5DAC1652BB985D42ED94C64AC81E5380E103AEC9D5153040A02D50F9FF1259D3E9D4761B483FA9B7F984543411452F34EFCBF736764B4BBDD9BAEBE9583B125A11B91031690AD5370F263B10C7DBF2E77D2576DEFB6D8682B6878A096573CA67482EC7AA51706EA0BA6E5E2C9A129316FB1B225A1A2DF3860BF7167356F8BE34F7C6A8A7001741216BDBBA353A8E130904DBA6BA915A6AE992B34DB35BB34C622AEDB508230C58A404CCCD508B229B38D1C775F17DEA87EE58B51B13B58295A1864895FF899B661AF9023A5A83FEAD89267804E89C3E3E153165F67FEE1BE1D0A68E83C308DB2EB5B9507A8A7B48A2116278B516FA53F780D3D3B6E57D67C966CF116469EE54308266DDE588FD7B097D784B61B48BCED518146C544E74B6D60C6B3C85E6AB25A8E2EBF7BD38B8F13799A355A873ACE1187B41950B89CE98F686A57A7FEA910F7E8BB578DA0FE041601A232209DAD6B8313F801A71DD569FB3C25678B0DDC6ED4E0B5F7480B359FD168EE16AA16450149FFC12302AC4C74C933D6C218F60D32FEFD741787D48B1F20504B911462ACFCAD07DE4F3A1D9AF3F2305F8E5097962BDE4EAF7605C2C8D3AD81134F679CB1D9A74D8169BD3122BCE004CAEA28FDDBEE7BD211DF7A4FCF59B8314DD09032DCA5155458385E8D22D4EEFCD5F714B62917C16BE935FE078A21E3F281948582659126EC9E6B70A766A067291B8CA77F19EDAABA41B87805AA3E4654779D375CA869887E871CA5BAE1BFBD9FC3BEA4D9F0B0ADA6F8468537B1F264D1AE34F71BD68894B7D4533FAB99BBFD2888E41DF85330137021267D623882E00DBD42A2EAA93EA4DE4FE2D88DEDB3BC23C677DC02D25BDECDEAE9E1112C15098BD837F76ADA34945EE0F86BB7D4B7522266BC24DAB3F03E2C4B524A25F977B5B68AA5A72986655623658DD36D92A9B5424523A88C0FE39BA54D4926F6AD802418F553B1DAEB3BE6E25C90F95CE313D91E6EA3CDAD5BEEEBA74C306333BA28927B1C3B82C16E45686113A672CF09D986855C0C0CC7EAB9C31E2E351882D8E00111470ED2B67EE2211E65E12271CFB12AB819DCD662AB262AA0AB702A269832C3E79724F16EE58BA9AF1A28DCAA49DD514740FED7071F4248933D9252198CD9239F773ED21933D4CCE7700883A7021E77A8D8D8329AB1A325548C8A5568FE3DD38AB54004840DD32D9DE56A1B4207AFAF4D0BA8A49173E1F13552B57A6CAB43D4BDD691AB1C6554B0971E9681FE8241B19EBC31AA2C8847FF6ADC980249B5540F1576410587791AF230E13557B1B40B1921B6FC7B206017D9FA7A4F36797AF41048F5767E55C1B2E5D749304720EF9B7A6201B19F9CA4930FA6D5388D85504930AEADF59C49D24CEEF9AE454B0A3BD4EDF658FEA455A901C08B84086FCE9E7D2B005AB16EEE1EDC724C74E3CC8F80300857F17539318D9AA951B555C84E70FABECC6788B14833FA7C9942E5109FFB998BC6D9D101FAF357823491674BA8BECB7A6355E8ADD9B1F213D749CE560159942483DA1F59507252EFC1ECF5CB084FFDDC4384FBBDF8C35FAC801F5606A6686761A8DA207D640B53C63B6FB4FB17C10B529E5AA11CCB40266A8BA1F92E8A9AC45DF2D60F28D52F5B7F69E0F4FF62DA7121BF23A6FF5A750A92E475E7E53AE98C29C80D60AA9F29250DD178F26892FC4B4996F157ED470BA45667863E1FC4B2A784BE2F1596FBA429334B5D9393A447E3F05B2FEF0B6BFA6B050FB764816188FC018271C25967C6C7E9CC420A08E270ECDC72A976890624E94FE607323E71AF582A48DB0C41B3B491B5EC64E506EF5AA62698D0CA6DBBA1270D2AFD033F18DE3A52FBA95072D7F2CD638F68DBE737CB880A43981BC3AB594143D29A49441BC58A9882EB7DD1B843608ECF6E1ABA4C2F1891BE8FC5D5A4898D326DCF008AE3035D14507E1C2930DDC3BFD47DB9BC4751F43188090B3E954FD90286E23DA20E926FC7B9075E06CFF65C8F47C388DC11E2C94C45652818D5BC1DB9CA3FD51B89C261F2A6044CD4D1C298E134DA821B8A118E3AC47E6F65826E2CDD7E5F289CB44503936F8C478C153C86EB2681FF8FF2669BA7345C22FF6F9C9D86281C0E8F621C7B22D93572BC96A03DFE3FEA6B8ED2BD972C17A796CF426BAD1A52413519251C498C4D85851F8B575831DD6E9D3AC8281A97AD4796A979D5D64D820A2CD808BE7EB58EBDEA5ECB0BFFE2C5778E63EA5941188C61810B10CC97EB5286EA25AD0540EFF0E67F4B287A539E00D3E56BFEC959A5AE1D97F8AB13D8FE058E76FE2CB4E97930D3CB1E1DBB1F1F000A94DAD2070BD687431C8335A027753362C4D52142A1C4A267B6B996F9A4555EAA4006EC37F22AA470869B059C22A6654B58ECE4760B261B9EF3A506DDE027AE9B63CA62C757E249C51EE1C9EF4EE6DAE282CF9E6FEB111A9D811D4266330231B74672CDCAA81C1E795D37F0C14FF6DEE79E4D0BF9F6F8D654B8AB103CCCCB2D7F34015DD039C47464A09E8DD29206D6F68B07CF5B1024660E18B3B013032CB5B3D1FB811D264919B841407C653D2A2A5801B4705A40B1FDBB374D66BEDE81BF241BFE0E8AD63429D87490C9ADF6948DBC62E0BBDE0DF7EC1D2DEF79B65957139947E3C049666AA05D7E89336EE3F577822C6E6F62E88ADD5C731F5213B78A31C9C06AED5072F25971ED9E25E93E63B8571C47494285ACD54FCADFBA66B9D8C7805A304C1F325DB2DF83F0D6096695C0ECFD031DB6D8A495B497A7DB51D78B7539C386518234495EF71182273197A5F22701CCB2C32FEE83E3CF0A2278969BF4368235BA85EB9E98C7647B356129AA7A5703CF1D64EA92A89612FDB7A87F7889F24D9437C0855A9A3F9C71596B35B7B689D723FE145D30FD7F8BA95543D3DE42681E60B17F6E221C049901E502ED23052A10ACB9EBF230C58C3D6FECF769E61C8A9BC2E1754839403D65CB399B986A3E645DEF3F76D8B4F29675DF6C60607C7EB8F9E1B4C4D240638D649553D55C048FF9F66801D75B4F111F57F1A71AEC54BB3A6B45A73B79828F83A2B7193A3FD2985AE1BF2AB461833B82B03A354CDD3CF85EA76B0AE77E9EF32FEA68BA7A256A2EA477216C1331630B7FB2CE45675D373ED5542EF59B733B419D8995A21BD94DE6566D8B47302273B580BCAB3B67DD7C6E18277506F069ADF7DF49F6BE51E92D18F0E1D8AF9219BD6D8654355088BF57C00179BF6C621C92C415FE19C2913E70E7B8ED78172ACF9D148CD0AC5D60E501DB3DBA860C10D8972B1015C26DCB295283A60BC4DA0E080BF3C8EEE78CF4A1CCC7DA8899CD9F4E1FD8CFD6EE53200D239EA9F6E9F604CAD195909C4040BC4CE487D355CC85E545F5C971B34B54D229D43687FCC795DB4D4378704F5D95C58B67AF7738EBBA5518227A0E18BD4068D0AE6C9BDF02A7BB8402DBB9DFA3E4F3386BE9F56EEA856178DD4FCB49F6C0F79DA74B132428F2E29DD10DBF2C159429719EA7A2479357B346F3F8D014EA98E5BA44E40686C031C484E96680524B2CB49FF6B21E67094202904D99C4FC0C46BD079B9EE77B922B5B94E17CE013B40334560578A22A85D5F7C6C4370ED391BF37292A5B01A7E4207949968A9F373B3BEC14F895E82752EEA1ECE764729ED181BE6B5FF705ECBF7540C2B603C92C500EAD4A70EB6F6F98560F6961238A66F30B9EB5220A835EA1ADE281BBE4887935F381094CB75178220A864B321488D4B25B41A55C42752800576F5F1516E8A203A22FBEE078946D1846D056B3311D89B7BF0FDE9A7AE87D26CA33D2626E5089BDF53A4AC16730F77837E50BEC3B1E0C570B233F0199822C1B9C455D15DE701CE161F1613924A51B6D180127F7AE59CE5B6B4BE92B22AD5654FD5CC06AFBA576653DE32D5F9940B9FA2CB20FAAF23B36E90F2898E8751A28144C630E29C50665D9C1E57CF6271B436FA3231CE1E6D8DF3C63184439587CBAFA672BE6F2037AC1C58ABCD4ADE1748F26E7FBCB360DAA783201186B2E5C5ED9BF1C51E3C20C1595B7995E96D5EAD632D5427C0449D34767F4BD73573C77FF12354921DF2DFF13F6A1B5C479C544F4AA74801284F409FC2DD8C20149F4D84138B69733A09F49BC00EAA4B1305A232E869710097BCCA1F29F5F7F94C931592D73790224EB4B18241AD667A129CB11B660FAA5B542E702BC9AED58EC71D5C0763E516A43408F3D29069A20AD0BF0DF9787E4CFC57A592FE610317680B7C9594B499FD5E8A60512A8BEB0C4A6A2BDDABA0F6BD13DD8E2EF2B14C0AD045407E5C37ED16205E64698CD9DBDFFB01042E30C5F317213A3F5480FA0E1B1C9DA0BAEAEB3F889ABEE4F61C272B9AD2E62F41454B5D7A929BE85681C4EBFE00000000000000000000000000000000000000090F161E242A3338E321E8EC09CD3F3F317C0E62011E614BB921B7613BD2F0960041CFB136882B6A634AFEEE6780DD058B6B0ECBD3921EC1BB10B8FF387422A9809AD1308AAEB4F6C172BD3D1B227C899BC5DFF33E7EC6DA42D1692ED5B3674998C4901EAC44251A7FCF6FFE00B931CDE48A144386B7B7020100 +Result = VERIFY_ERROR + +# --- ML-DSA-87-RSA3072-PSS-SHA512 --- +PublicKeyRaw = COMP_ML_DSA_87_RSA3072_PSS_SHA512:ML-DSA-87-RSA3072-PSS-SHA512:C8D67CE17D1B6E2D42A58CDE67CA5559BEDFFD8071C670A59F55BA500403C045BCC7E112C32BEFB2BADAD7C2C5C1165DD1EEE71769BD6F55C445B0F56EAE08BA086F4B33190EE88F1A750BE1D5772884C9492458520206227615A41C390448DE2BABD946E0DAC1FD534C9E828FF595EF6D8B1EA2CFF5761153327B7542A36ADDA0BDFBCC0F025734BC01CC11460BF08FFA1118DAF08D9E63AF8C3505EF0AFC034030DBF27F439EEB154F4093ED6FEB961EE38C1E0E708A2868F9B6FD9D61D362C107DD2B6AE9E0E03FEC2C61C71311F196B03C0EA94576E2EDECAEC9091DCBB72F8521B7284C12FB49BCADD3636996DC76FEE9222B2197807E1161849137F0EF5D2E35EC3544CCBF645C2C3216E5D6F7A68907E91F917045A20E193958A5D555EAEE0E450F66D8B16D36A97B34EE324A6F979CE712FBBB51391A97A340CD7097CC3A0E5461D38583AFF0F6CBB8E93C3137835A5F29F70EF1E91CB4A7A9B10F6A796AE2E0B48556FBF940F536ADFEC55FAACA2532776E43D536DF2DBE2D10F254E4C87FC4263C48C8FE5D684D27402EC18BCD8E11BBB5C1A75CACED4EC11BB4A5C7BD1725F81B46CFA9A49B1E7CC0701F2369986E507C9C8DB22B4700ECA593EE96AAEA7BA7AA503438E1AE8EDEA4B1B02B1BF328A948229CE7732325EFE02743196588E46CA1C53A7958729DEA6BC0E8349C15EF5F79AFCF5D71D05EB56ED6ECCD7B10DC089DCEDB85511757917B5831B88FA719A0E832C9B2B1767F42706711E772766D85AC16F7A542852157C881809DAB72573010EB7241CAF692A4DFC3BCD1B99FA025E582BE90579F31BBE2C44A0DC06583DF38EF4CB9BF43378BE407E07CC75E589E2FA59D1E7BE1C41D73B7A654FFAF701513AABD63AA50D21461F7A54FB7C1BAC72188A0AEDA82B8FB6B2C2711C1653666AEFEC32F455DCBA5C707A79CE2CB2908F6B914FD780EA23CB31BA9FA4ABFA2B0BB0DECCE118267252595E4B81293BFA1F6080D150502AF917F0C70CFC10F260214BE6E76C066489F0F4A8CD6297AFF54BC63339AC55AFDD76B3AE496BE5E7E6E2FB078A4DCAFA0BED4C65474CB539B9315EB1BEF50128C37BC833AC28FDD1D8C30E9BEAD05074994173E65B9A67054AA3C4C32B3F852316A29BD6E716E5222B3252EA9E3A71DF4E04E056DA94554CB201635DD4912C650351020384970635BE17DAFE564C088B80DF6A39B1B27EA5CC25222095DA92B0F3417FF72DEE9F39D950CF532CDAFC93A8E532025DF7B8AA5BF183F99FE384FB42839494CC6FE642250A199079D1A9483A51C1C35F7339864852F61569EBE1CD6F4A3F88C8733A3A400727D93A09B2A6D0F67B8E1F5A88F76876C191D0827C8AB021E56ECDF7D249FE0C35CCC595E237D0661614C92F38CF41694A985F89432C7D66B9F3AB9782849D279737E49D06F4E7E953880E51EDC97D99461640505CC08CC75AF6A6538ACBB30FC8B5230F5DDC0AAA92559327E05353B64FFD0C8EC4C3B6DC3400A9CAD3964E302BDBCB4D5EF1A5C0464AF110D8B56A44B3F9534AB9590F1FC32CC4FC26A908AB63F03EB775F4DE4A3E633AAD89BEA128F6A5B2C46F5EB3CCCF858554EDB6BE7AA029E1059C6EFA11AFE0ACAE4C8B026FE616A66C4B17C508FBA013DBBB0CE09090CAB4F4BE730BCC1F17243CA7C0C8DAAA11F8383251240D954B5A70C3BCC4105CBFA463AC476E987B0553984BA8D1C8BA3295745DD94748DDAE5C7A300C30FD47EFD6C9045CAA12B1722A8129ABCF92BCB5AB8379BEF2E13AB697075FFEFA9AB14767B60048D702C258ECAFC42E20AB0C22E9A67DDF9E938092E0FF80AAD226C7A246B00E28134A590E9CB72BD281D0991803FDB3256EBB8803FE13B6C4681E67362C9EB6CA610DF8D3027F62B877973EBC32AB488BF56D8293D2709438C702364DA3F39C3EC563E04FEC44B880846BCDD21DB30CE0A72880DBF1EA5EF58F3F9A40ECF3838982107F9D1D2D22E0AC14217A6EA6618D3F6FE7A5B73FD823386962665DF54157169CBEE7236A9ED83D0FD6419ABAFF8E92B7644F6B6A019B42554061FD6E1F665BD0CE2686EAD53C98D0CCB56283653E6BAD9D0EBC1591DBE709B123A1B6E9B980346584077AF714AF86F699218F03CA5A22E4CA3C50D41890F86AB5ED30BACEC4CECE8BAECA0CB737B42067110B70D54E6F547CCFCE6EFE84613CD1E332A9104B6AE21E71F7B6875B63F9B2FB5557A5397D1BCD65A126814A34530E14D18E426CA65CD582F2F4AB636D487A2098229415CFE72CB14FC691AE2EB2AB7A63DB7410F15C2EF46A7FE8A1A217E195BF5B2C3C6659AEC9524E195B298FC294A78DADE828424D311FD9DCBE13519E0A3C2C49402255E441B1354856FCC47458B635640A32FD8465C03DCA97FA3808E83AF09D8EAC01838E89387FC8EE99C49AE58F62DF2FCADB83FDA36A41858138B2CE4BE9BDA5D95BAFF17BBA6981D82FC783FE1B3A90DC2B4D2559684CC92CF91CE508FAE1DD556872C0922D74C1A469C593EC2DB170DEB2FC16CFEE2D34D4FF57D2350A5F4DB04CD01BA0B2515C27CAC632ABF168C077B32D04E7561DE9702EF77EF594E98BDCF3504AEE7B0F56C9636C47EE9A9E999EE8B45F67225BD07EE7734BDF487DF71FAEFF73A80881D75641D89237C4334ABA408780B723B26E04215805AD7EE06C6D4B70DEEB19D4CCDDC53CC0FECF9F8025091D3BA96CE1BD2F16C5892F892E28253276591035C390F951ED2CC2753D7E0ACD9E88E0CFDA4534A2D3F500A27627D26695A92CABD79547934957D36A553C9EFBF5072D06E78C0F4CBFD9CC43389C4E739021F8DF9B2F6B468840BDCF7ECC0DBC55B17818C87ABC2481F12A38EB4D7E6AA8ACE43E910FAFFC7896C06FCEA4384F6C3871E44C3E53048A172E2F4197A7B7A3B83CD4F490710DD3C3ED3E00C3D1D77ED2B8305F2837DFE22E32B6FE0E0CA502C53A9B504A0815A51FB6815AC41E01B20D7ABF4E6CCBD6039755F4DB6C31233DC3AA4705452363A4D1C1839054C8A0D75305AE0936D3D0F5C597612705FD5D912805C2F1EB6E46F52224AF090EC214B30314C03050772B591B4AEC6C59D591F3881FAE3BF6CCAAC2FEBEBA1EDE83AAB0DA60AD99D448BDADE0E6CAA54345083808D7385C59C89FDC13767FE36A40D9A657E171018BC4B88063853963FC5F9DA74A3382D66525FFFB8A8A3D6C52C1EF769A43FBD9889E459B04C492A967BFECE670D0ECE1FC0D0C22723430BB90BCE7E5C89508D1B1EA0F32D71F2ACF133999B023128D4FD830C878BAD5FB6B92D2D3435FE8EBB4686184B9236BFDA00A3A553DB092EA9EB290DA6FFA3BBC93249289FCFB0B78C4D4718B86AF1232A02EE4909D966F307E8DBF893C1D3453950D3CA9DB2AF83A2A9A35C4FADFC0DF9F7860CF84CF627F17586AEE38FA69A927157D23EAA132E9DA7B73B45B6AB99E2DAD24A21BE67FDA1679E4C8DDE6742F7348BC0DF981B69DAC17A78FC9242397C3A84DBDDABA51B09F240277615C4B3331D17A21EA44050766C9CFF15DAC1EF6B0FD6B3A01D72B0B2AA081BA9967AB7DBF83ED658CE4F923936734D707C82C684FD3872B770FB54C30D65326D8D0A5890A94F564FAEB6A6F16FBC0379BB99D7397B390E24492F4DEE2F3A636C452277F76F67D8183082018A0282018100E357CD609383CE1B20B72540FD9C5989E4EEABE4CBB8AFF2A750619BE230E9461F26504A18B6D389A0971EA44F6ACEBE396D33ED2BC203C6CC6BB544719690FD6370A862A6831B0B46C20B6F7C332281EDBD74BC2DD59E5A5C43D9197970587923EECF81E4D091536C175D45B9F312A4821926E70DF889328E6D8352836A045EF4B7A0CD9DAD414FB46876A69CD8710A46AA19F88C6AA2F906444846E6A744B1C604BE365C3C1D05C913B8E1693DC49D2680EBC0811262A786E3608D8BC86692B4E85555D73121E6FF1C1F66C15DE24290D152E797E2F391CFA69E2405A185A78A2FCEC616C0E329335E36CE867B3A91EA43367E26E932F85513D2560A5E656038DBA2190B7F1913D6837F70825E6A0939560E7141024E90211958145EC1F94CE18D9E8C009E19DB89FCBD2B9AC76770CD6800EE6AD144A7F164F8A3DB4EDA79D38054F00110F7D7FDD7BFC5298B332167FC556B9A2404C621FC32B3CC5EDE89F1AC17D49D799FE865EB83334545FCD5F986795957FA2DDF5FADD7A4E8FBB8110203010001 + +# valid signature +Verify-Message-Public = ML-DSA-87-RSA3072-PSS-SHA512:COMP_ML_DSA_87_RSA3072_PSS_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = F455DABC38C6A71417BD19530761102D2FC0D140C159E40E2C068E56908D5E1F1FE0776F379A07DA0AA3CB841860FFFFB4332D065692797ABC36226AE18EC7BC46423625BA23ADD3D238CD1A0912FFB3CC8369B6C70E28941C7FDACEBD6282031A6456B07462D0A0B9898EF02D1025E1AF3171620CD0AB0C0828E83F34144CE2EFBF063CE3D6A0533C2E9413D39899E23C75F21CE7B262BA9BF6C9304812A39A31276ADF4DF8337C48C5ABF3E76065CF12C86BB278C8E98AC55DB12B63F5CC638EE438CC6D4F47F1316CE26B1859A3A68E9E4E3E4215C84DE2C6638962BC232FCC0095830DCAE9612016BB0C0627B39509DED04C9514CA659BB23E2EE8D07F587FDF8D977B3C565FE568EB41546EC18CFC923930680F252D36B8D892BD4ABB723C3B39CD1CBF97D94D54804C53338F1608A5F90A15AC688A46EC290D213230DF997C6BBCDACF49CDA3376B0768D1BDF128EDB9DAFD494BF29FA4F461F893F8F5619AE6AD65E31A9617B922BC7E96E7E4874F9DE27243497E22080ED11446AA218CE3D7446BF2E42A1A5EB23FA9342BDFAD11D4836B5ED854A6E718FB165DE2FC4B8D2389A54E62C971D53E9B916DCFB3FB99B61F1E87E5F5E4DDA03374A9BBC7EBD23F292AE6EA8071C103DB73B1A5B3D0D39A6CA273831D7C602AE9BF70B79D2F33FCCBF8F49FF4152C17AF0DDCFBEBF1507F9061B177C4461EF64C1051D63E26FD426ABA9E577719A2E46CD40D91828CA7EA32E0C0D4AB74186C2057CAFB16B1695DC1E8164BDC106C16AA8EA42561A528D735CBC73584B55A484C4AC00D09F6288FFBAB37BD24B61A94254D155B9CB93E8045B4E0D2F2364AD05E0F9F53F9802CAE498557D1E75C11901B48DE23DA3B2F9ED10C354518C73982E41A021343E2639816DF54CFB52F9680D57AB5ECF1691E28FA3568EED816A83AADCACA12974A5F9B1A45B9CAEFDE1C57BB8EB4675D3FDCF5F03A69837436DB3D990EAD83AEC7451A0BC416A5ABF4456B0995E05D91DF9E68C8102B1AA35AC68423EFDC617FD6F5760D371E92FB5893D27601E31712B45FC2BCF3CAD6BBFF528C4E3E9C9C3D8CB875E344E809237873A8621F482273ED4F5CBEF41BF044F8B86A88191580DD9F28552E768B875F4A918322844A46507C50E5170F15FD0D74A46D5F492D4159BCE96100D974F4749079F7BB4F41C7961AF48B80030A6D001F448B08BC3F84595C981A9CD8CF4B539170589A55709F27ED0D5DAF60C61754BC3BDAB2B96688D6424337F5F6A8039F923C329A8AFC2FEB6E4BCE591593FF72F864A2D14E7FEBABC30941DE50665E9B6D143FFC80C6FBF491B866964A60F8CECA216F7F64C428E698383F745D26F56D332C47418301D6DE91246F04C4F37BACFC6646C807AEB65C1332590C40B6E2F31FE6E46CCF77A87E1C4FF7A200A23A64E16EC9F05A1AFDA51296E9B9891FDC33B4BB8EF8FB177CAABB0078F4BD91FE6180F7A4E14EC66789106EBA744815D6326B990B4421D4798ACF4958C050DBCC86F17D76E16429523A6BA15EA67DFD2119CCB0A69B7CEA7535D5EA41784E0944F00925CEB712F34B04DAE31D928487C5859904BA347E8FE000071B5E0CEADB3553645650EF44F20C32B87C63C7C4F98F862D18368ACAB2CEADA47B98A699E7C3810C2CDCA71F1C67C5D45976DDBC49C95DEABA07CAD8D88AC1C629F09A731BC7A4371416B3672E2A634F08D6854015E40120B5F58D47BF92A7652860EB75BB8BD47632BB04157C789BC70B6FE2064846C8EC95F671A9D902D53B58BC766496E638C566F8219D98B10C044D5AF980E7D7493145D4DE9732A0E2BC81FE6600CA015C04DABE0F54B622B80211ECE4AA610A37A56B2257F36D44D69718EA02F1BF84AE14B4AEE000D2F1F4E110ACB3C4EA2B599FC6167CD181FE8DE683F9A00C4342D364314926E3C1A2D24E428A08D6886953A162635043EDE1E65269CB3CA11C69E620E22111DECD3C6308B3B693531EBABA34A0BB3AC5AF392312912E02DD37C0F7F339DF3FEAC5F6B2686CCFDED082531ADEA1A98A21E4C926DB666A7C207068BF6DADD834F960361110CDB08ED43ED0FD6DA997B0EEEB3772AC005580233336BFFD872BBD4972B8DD7A97D277B0E2D4F556459AEA85694D30A629750158CEC6E92A08D900853A57D3083005512846EC437EDF148DE5125586BC1DD705F3E1BCEFE6D8F13C0D7254F0D2CFD385710273123B3EF8369CD94FE539671C5DF3225FB3CE32771FCEB8F44F4924F92676EE5B6C51CC5C10504E57BE2896C7F22E4A3E618DC97E1DCAFFA8EA63986C7077C4D2193BF27757BD59976473DEDB1C16124867C10D10A1700ABBB873EA9D0590B4E64FD0629E180A19D42B40BA7ABE97FC0736CC8DF1C71A1B578F70EBE97E1377D8384B5D871C89FAF71C0176244149BCE67F1B213803AD7B4658F778959289D914E6FABD9A9797F655AC6920149902237998CAA78131B5D6D961D87B1931B751269F04B18CBC7004C413B89472260BB765DFA23EFB6E8EF63197DA5C1FCFC9640A0F64E90725B727E03B718C08CBC0CCC1A84A2617A827047A495465625284A6CC38E51FB8B62BC091EBC80018702035ACEDF2DA5EC32BA731DDB44B376D9DD79BE5AC1A6184CE336054299554B05F67AC3C4C85A9DDC5A33B7B4AF0ACCBF8C91F58DB4A005CB1933006C14F8127F4CC7188999F130423BFE58394D57FB20139114A28DE5853993178A36B10ACC7E5644AB60FAAE54F9B0AC17FF463F55C3D0D883C493B2E0B31579E14ECFEF41C2659021540AA30FA32B6960ED4FC2FB86F5F34C3878D1CB779DF8A148C1A9F54B025F36F5617E38887096A7901413E6CB451B4BABBCFF06C2D5CD8A6972DB3D4A75FE3B3413B89C9E1E6D28CDF13606DC0D26B117AB6778E264E42510BD2C3B8D8F01B68C42232D3D64E1AB6BE387D894B5966B09E9CFF7EB06FA96C3AE5B6BD5A55DAEC6C59B65C7C2CAF673F64D59190156204179F563B1DC9A1D46B74EFD789F2E148BE26AD93B000CD4A4C144F8815079C2D8A1EC5734E875A73DC3E0873B3D298668F2635088429609E3EAA043D78B2497D66617E0890A95F1D5ABD8E4DAB40830BE1A7D5EE5DA4F2A8AF170F752436881BF29ADEB2897E20982907B915AC11DF038A42AEE15153624BA68536E4959CE4DF65BABA56E9D9EF25EF37271EC8DDADD426A5996DA5FB336A1CAB853C30C49206918172B13AAA9F202699FCE82A41948B89098DD57F44821EE0EFB36BD8EF5B35FAB9B04F3B171463E8D3712277717C6F3F6AA346E7A701F96B108053E295CBB96B264A820992D996BD387ACC6DC44DD9AA6FB9E3B00DE4E21EA0DD9D864A76F385FDD30D58F884E744E69F6C3C2268DA9ED2FDF95E69BD0A30FA234488651F43D0F24ADF67F4AA1FE4CB94A738BB825F19BD402CDDACBEFDFD21239671A421417291EBC641FCF200B78B201B8B525AC452C9CBCDF241A8A6642794CD10B79460879E49A42A04C6F28B96179F2ABC18BBE4A0B72880280A331FA4BEC46DD2CF4864605E89A25B2A7640662142910C91225DFED478633BA27B419949F8D0B30BAFFD30768E8C4C239DE9AFADEAA23D707DCCC83BCF9C0CAFE2530D632D9BB567538EBE493C34EA55750128CCF9203DCA8F161082F3A4828FF47133A0EB81E0F760479D29F14492DDF4E8AEABF8AA33DBB105220D4985FC678CD617BD0ACF4927F9ED9704C327B8FDF7CE24E578F98BEBA74D75D0D3CC44DC4325F71EF8FDA746FF4C74AD9E44FE7A8199BA3F2C7836D4AA996837AA0106282F960D9729151DE94B91C1F31DDBBC43E9E7F1A113AC6463546426A37E8430C97B0D8155B15B6CC09A302B0AEF9DD96A4358DAE81384FA3C7C328EC605E59D65F78E54A3EFD0A389AC582C991A315A7871ADA701A68ABC763AF33A820DEF8861CEDB7FE71E51F3DED0C5673FCB5B097DD5FE55E02D2B89564292EBA477F1FEC654A479C6BC0E01DC0A3EECD8BC7226162C2C56B114DBAE2585751F6E1148010C24E9D334BBCC80FA73BF2632FCFE5AD08F75ABC5D92370DE3FA4307F274E7BD1DFDFCA3B3123826833AF031940BE742B49CB7664ACB88A84BA9D3667F47504AE4766CC576FB313B3B3E29E17FAD689B2543041D0445E8F5CF686B46407504EF8ABA32F6A9E8C278D69AC92170F7AA6033090528F09B5D4C142B3510700B1A67D77BB8AE9FB093D71088967681E630E2938AE7DD28939F5C4634E88A5995055B2BECF5D0CFBC3C2A7094A378744C2C304366ECFE7D3B3415368F03821B8649C2C463162384389480488D9F0A4F50142FE7456BA660837DF0F5FCEA1FC4DD86E5D3D39411020B391A36B0187A3CD938EFDEE246B73A2360E79272EEC44AFE3EF103C3277F8AD70F3BCC9EF4282F668CD75FF61CE88E55C437037A95D16F14E473DBB5BC840200B0C85BAD8C60A03ACC70E6971D6E4AE6D88A68B1B8A889C8EB65C0FB4FB92DAE66B44783EBF64353160238791D14A6C518DA61ED513D86DC7BF9FF06A7714776D1D47CBC4048AFA17E8A724C9112E1818CDA39F023E8BCEB6BAC1B2ED16AD0D0C77A211CCE176BE42461F5730730787D47AFE638A2493AB44933F1F01432B911CEA3BA5D84693DAA5954E2E4F73734E69E56FC5C69467906B2B986C20D085F9CD6DF2285C2E8CC251A72DD9C9D3C77AB812EA6393B66838FB9E6B71557A4912F46D614F4B8CA3C3334F8BBB85796872BE60DF43A9AE416115B92E381707E34D72BF8435D72C374E54A8DC12DAADE89EFFCA439BCBA0ABCAC89ACA8F3738DA4A8332421E528A924807E2E3E0EF33823F247BA924509952A138DEE2FF1698FFF99CB6D20E5EDC109DCFADDC16B70824CA05382EA7D463C57500B219DDBDBFE8183DB182BCA5D0E6A1B3CE9A5926C3060D7069CCD62EB49D53FB05E01F8FC4F0675E342BEA9A56AA823D4B9C4FE99194BD57B5CF5E616602AB853BED737214A10D4B590D73A8363607E0DEBF05CE6EEFBCF2DF11F540C23A5B1370D84C8BB1585CD143046A57E84F515712B6D2B8D634F06518EA9EA54D76F3B0B12B779E3C5332B811B32E6532DF02678A95684017CC4C112618F4976E1A7A8EF671F85C882161CDDF97DBD6F69532813E4F60AF8A650D1D164BECFED85490B453A8431D13DB96B533B808A91195810577A2961B0F5643BB8FE72613F8F9BA69BB2238B96D997DCF5D6A85425DA622C00738B0883583C7BE3585C76D740A7E6BB58F6D213500D476B17A56FDBB4469F54E2986AF02B43EFA2D448EE84F282AE31E825331CBC822D13FD9810C5CA8AD1D10FE6529949D4A9DE05A0AF84B81C5113D3593B3C209A6928797537B433EFEF284B6D5A963E696A3313DD0512FF26EC6D0FA4D7117C83D212A3ED346F8BF87A39EEECAA41412F664BC496F594E963F5A8B081AD232DECA45962C487F476668A5370279AD90102CBCB75B4992D87ECF985EB54C78A8DFADA9F825BEA3E6A5B6CD8D28D0A22E9C45BA43DC6922F122255C64BE92345A881DC78F1E26636023E46404B1F56D00C0437C09328ECA5E09B1A942DE896C7E993FB5BE29754E2BECA2C33DC7FC49BDC00EF3778464E5A7951E50D6BA25CD2D529CC3CBFEE1CDC19E8B8EAE4E4E54F2671874DC46E886515CB5AD389A22822D8CC014A83409F1314EB6CB2FBE59B209A6F43767ED34BD6A7FB629ECD8C15057B8EF78A21BDDDDCC06F413EE10A483E0BC9D2569D6A93BD0A17E68F4C679D9C17FC9604943BC1F305CC558C3746CD6CD248FE42155048FF6F163B423191A39781F4AE7864B03D1CCF31280CD5550B481DDC9084DA2F91349B05F6D4061F8070EE11E21858FAA68ABB34DE6514ACE73F492EE387E97FA9F1A9FFB60950C118B495D69DC6FBB6442CC38510B832AA91832B36285ECF5B8BD602C1E0FC4B24137D45109E7D87006099123DFBBD7BE5FE12324C6A3AC37D727CDC5FDC884187C0E13AF884834D59C60735D62DA7F1B00995D5F0632E5185790CB8C0F1C0F6349912C1A52CAEF6339EA244AD87F577139006C653CA834AD31DA5BE85D694D57670DE62B58A397598A842E09DB83C6C4F0186575FFAF346F52E3A3EF0C4F7B71011E36B68C4A7D35E410C2CE8BD581A3C63D4019F0CDC70EA81E3B2A71CC67A2FB2F9722BD69A76AB9AEA13329572B337377F47ADAA29DAFB07F2F87C7035E1C351EA6F3C4267BC09BE7BADE9C38B5131E11CE9D6AF4029BC0B388418F5DBB401A21786CD1C86B381D839D1E49C7932A5411A88D04B29416CAA6691AC5310BBCE5078DF11093A3E9F267C4FB2AA05412313719C3C2C29CC5052251E7BAE547EA2BD5F44E84F9AC6AE6148D0D26E5BDACC88000961AE6BDC5EE7FA20C6C14A579777CBA898FEFBB1F630D165B8AA1C28B60B99FB256A7DE198E0E8F4F53E33D3F110A2B85C0DCDDFA0A1983FD0715295E6478A6C8CED2FC0A7C7E8BC0E1FD325379E1F65F8193DEF32E344256D3E6051D68999CA9B3BFC2C40000000000000000000000000000000000000000070B161D22272D37B88F61B316E0B8A3F695D071BFA1DA2DA8BB772BB9523D41ECF04ED8767D5E4EF8C0DB815C477CB8871FCB818F6E03707C292C5A0D112FCA57ACE93C1A298B524A70226A23DE80DA1701C76000979E877E573E5B623998BDBC8B57E637F6AD3D51574DB75B2CCE4F0A8C365462091AFF18B25ACA008D36764F8B80A1FD02121ABDD3F35740DB421B4B38E0C6E7EC131CEAE3C93A8C15274ED53CE8990502CDFB7AE2F64CBF14D67CE0F705B9FA9344B1D6B6ADEE56C8D9556E74A001D7AD44D38B50F085CAEC9617A44623B64102DD9B56820A62267834C883B58BB8C225E4DD6BDD16D971B4A010B78D8D70DD32E14510D758939C81478BA24F72B2DAB980378579D23BCB37CAD56609566E020F950286B7BE33F509F058B0C28FBBB8D49ACFD6D51A09E6E053785546EA19A9221C62177BB78119B3FE53FF02945CC43B9267BB1C3FCA6C57D6F291303F8C0410673FFD00A6D5E224FABAA16278231EC476B6A687B18A0B68ED05773B867EEB6DEE5FE370EA7D3D3CE15A7DC60DC4A65FA4B2 + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-87-RSA3072-PSS-SHA512:COMP_ML_DSA_87_RSA3072_PSS_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = F555DABC38C6A71417BD19530761102D2FC0D140C159E40E2C068E56908D5E1F1FE0776F379A07DA0AA3CB841860FFFFB4332D065692797ABC36226AE18EC7BC46423625BA23ADD3D238CD1A0912FFB3CC8369B6C70E28941C7FDACEBD6282031A6456B07462D0A0B9898EF02D1025E1AF3171620CD0AB0C0828E83F34144CE2EFBF063CE3D6A0533C2E9413D39899E23C75F21CE7B262BA9BF6C9304812A39A31276ADF4DF8337C48C5ABF3E76065CF12C86BB278C8E98AC55DB12B63F5CC638EE438CC6D4F47F1316CE26B1859A3A68E9E4E3E4215C84DE2C6638962BC232FCC0095830DCAE9612016BB0C0627B39509DED04C9514CA659BB23E2EE8D07F587FDF8D977B3C565FE568EB41546EC18CFC923930680F252D36B8D892BD4ABB723C3B39CD1CBF97D94D54804C53338F1608A5F90A15AC688A46EC290D213230DF997C6BBCDACF49CDA3376B0768D1BDF128EDB9DAFD494BF29FA4F461F893F8F5619AE6AD65E31A9617B922BC7E96E7E4874F9DE27243497E22080ED11446AA218CE3D7446BF2E42A1A5EB23FA9342BDFAD11D4836B5ED854A6E718FB165DE2FC4B8D2389A54E62C971D53E9B916DCFB3FB99B61F1E87E5F5E4DDA03374A9BBC7EBD23F292AE6EA8071C103DB73B1A5B3D0D39A6CA273831D7C602AE9BF70B79D2F33FCCBF8F49FF4152C17AF0DDCFBEBF1507F9061B177C4461EF64C1051D63E26FD426ABA9E577719A2E46CD40D91828CA7EA32E0C0D4AB74186C2057CAFB16B1695DC1E8164BDC106C16AA8EA42561A528D735CBC73584B55A484C4AC00D09F6288FFBAB37BD24B61A94254D155B9CB93E8045B4E0D2F2364AD05E0F9F53F9802CAE498557D1E75C11901B48DE23DA3B2F9ED10C354518C73982E41A021343E2639816DF54CFB52F9680D57AB5ECF1691E28FA3568EED816A83AADCACA12974A5F9B1A45B9CAEFDE1C57BB8EB4675D3FDCF5F03A69837436DB3D990EAD83AEC7451A0BC416A5ABF4456B0995E05D91DF9E68C8102B1AA35AC68423EFDC617FD6F5760D371E92FB5893D27601E31712B45FC2BCF3CAD6BBFF528C4E3E9C9C3D8CB875E344E809237873A8621F482273ED4F5CBEF41BF044F8B86A88191580DD9F28552E768B875F4A918322844A46507C50E5170F15FD0D74A46D5F492D4159BCE96100D974F4749079F7BB4F41C7961AF48B80030A6D001F448B08BC3F84595C981A9CD8CF4B539170589A55709F27ED0D5DAF60C61754BC3BDAB2B96688D6424337F5F6A8039F923C329A8AFC2FEB6E4BCE591593FF72F864A2D14E7FEBABC30941DE50665E9B6D143FFC80C6FBF491B866964A60F8CECA216F7F64C428E698383F745D26F56D332C47418301D6DE91246F04C4F37BACFC6646C807AEB65C1332590C40B6E2F31FE6E46CCF77A87E1C4FF7A200A23A64E16EC9F05A1AFDA51296E9B9891FDC33B4BB8EF8FB177CAABB0078F4BD91FE6180F7A4E14EC66789106EBA744815D6326B990B4421D4798ACF4958C050DBCC86F17D76E16429523A6BA15EA67DFD2119CCB0A69B7CEA7535D5EA41784E0944F00925CEB712F34B04DAE31D928487C5859904BA347E8FE000071B5E0CEADB3553645650EF44F20C32B87C63C7C4F98F862D18368ACAB2CEADA47B98A699E7C3810C2CDCA71F1C67C5D45976DDBC49C95DEABA07CAD8D88AC1C629F09A731BC7A4371416B3672E2A634F08D6854015E40120B5F58D47BF92A7652860EB75BB8BD47632BB04157C789BC70B6FE2064846C8EC95F671A9D902D53B58BC766496E638C566F8219D98B10C044D5AF980E7D7493145D4DE9732A0E2BC81FE6600CA015C04DABE0F54B622B80211ECE4AA610A37A56B2257F36D44D69718EA02F1BF84AE14B4AEE000D2F1F4E110ACB3C4EA2B599FC6167CD181FE8DE683F9A00C4342D364314926E3C1A2D24E428A08D6886953A162635043EDE1E65269CB3CA11C69E620E22111DECD3C6308B3B693531EBABA34A0BB3AC5AF392312912E02DD37C0F7F339DF3FEAC5F6B2686CCFDED082531ADEA1A98A21E4C926DB666A7C207068BF6DADD834F960361110CDB08ED43ED0FD6DA997B0EEEB3772AC005580233336BFFD872BBD4972B8DD7A97D277B0E2D4F556459AEA85694D30A629750158CEC6E92A08D900853A57D3083005512846EC437EDF148DE5125586BC1DD705F3E1BCEFE6D8F13C0D7254F0D2CFD385710273123B3EF8369CD94FE539671C5DF3225FB3CE32771FCEB8F44F4924F92676EE5B6C51CC5C10504E57BE2896C7F22E4A3E618DC97E1DCAFFA8EA63986C7077C4D2193BF27757BD59976473DEDB1C16124867C10D10A1700ABBB873EA9D0590B4E64FD0629E180A19D42B40BA7ABE97FC0736CC8DF1C71A1B578F70EBE97E1377D8384B5D871C89FAF71C0176244149BCE67F1B213803AD7B4658F778959289D914E6FABD9A9797F655AC6920149902237998CAA78131B5D6D961D87B1931B751269F04B18CBC7004C413B89472260BB765DFA23EFB6E8EF63197DA5C1FCFC9640A0F64E90725B727E03B718C08CBC0CCC1A84A2617A827047A495465625284A6CC38E51FB8B62BC091EBC80018702035ACEDF2DA5EC32BA731DDB44B376D9DD79BE5AC1A6184CE336054299554B05F67AC3C4C85A9DDC5A33B7B4AF0ACCBF8C91F58DB4A005CB1933006C14F8127F4CC7188999F130423BFE58394D57FB20139114A28DE5853993178A36B10ACC7E5644AB60FAAE54F9B0AC17FF463F55C3D0D883C493B2E0B31579E14ECFEF41C2659021540AA30FA32B6960ED4FC2FB86F5F34C3878D1CB779DF8A148C1A9F54B025F36F5617E38887096A7901413E6CB451B4BABBCFF06C2D5CD8A6972DB3D4A75FE3B3413B89C9E1E6D28CDF13606DC0D26B117AB6778E264E42510BD2C3B8D8F01B68C42232D3D64E1AB6BE387D894B5966B09E9CFF7EB06FA96C3AE5B6BD5A55DAEC6C59B65C7C2CAF673F64D59190156204179F563B1DC9A1D46B74EFD789F2E148BE26AD93B000CD4A4C144F8815079C2D8A1EC5734E875A73DC3E0873B3D298668F2635088429609E3EAA043D78B2497D66617E0890A95F1D5ABD8E4DAB40830BE1A7D5EE5DA4F2A8AF170F752436881BF29ADEB2897E20982907B915AC11DF038A42AEE15153624BA68536E4959CE4DF65BABA56E9D9EF25EF37271EC8DDADD426A5996DA5FB336A1CAB853C30C49206918172B13AAA9F202699FCE82A41948B89098DD57F44821EE0EFB36BD8EF5B35FAB9B04F3B171463E8D3712277717C6F3F6AA346E7A701F96B108053E295CBB96B264A820992D996BD387ACC6DC44DD9AA6FB9E3B00DE4E21EA0DD9D864A76F385FDD30D58F884E744E69F6C3C2268DA9ED2FDF95E69BD0A30FA234488651F43D0F24ADF67F4AA1FE4CB94A738BB825F19BD402CDDACBEFDFD21239671A421417291EBC641FCF200B78B201B8B525AC452C9CBCDF241A8A6642794CD10B79460879E49A42A04C6F28B96179F2ABC18BBE4A0B72880280A331FA4BEC46DD2CF4864605E89A25B2A7640662142910C91225DFED478633BA27B419949F8D0B30BAFFD30768E8C4C239DE9AFADEAA23D707DCCC83BCF9C0CAFE2530D632D9BB567538EBE493C34EA55750128CCF9203DCA8F161082F3A4828FF47133A0EB81E0F760479D29F14492DDF4E8AEABF8AA33DBB105220D4985FC678CD617BD0ACF4927F9ED9704C327B8FDF7CE24E578F98BEBA74D75D0D3CC44DC4325F71EF8FDA746FF4C74AD9E44FE7A8199BA3F2C7836D4AA996837AA0106282F960D9729151DE94B91C1F31DDBBC43E9E7F1A113AC6463546426A37E8430C97B0D8155B15B6CC09A302B0AEF9DD96A4358DAE81384FA3C7C328EC605E59D65F78E54A3EFD0A389AC582C991A315A7871ADA701A68ABC763AF33A820DEF8861CEDB7FE71E51F3DED0C5673FCB5B097DD5FE55E02D2B89564292EBA477F1FEC654A479C6BC0E01DC0A3EECD8BC7226162C2C56B114DBAE2585751F6E1148010C24E9D334BBCC80FA73BF2632FCFE5AD08F75ABC5D92370DE3FA4307F274E7BD1DFDFCA3B3123826833AF031940BE742B49CB7664ACB88A84BA9D3667F47504AE4766CC576FB313B3B3E29E17FAD689B2543041D0445E8F5CF686B46407504EF8ABA32F6A9E8C278D69AC92170F7AA6033090528F09B5D4C142B3510700B1A67D77BB8AE9FB093D71088967681E630E2938AE7DD28939F5C4634E88A5995055B2BECF5D0CFBC3C2A7094A378744C2C304366ECFE7D3B3415368F03821B8649C2C463162384389480488D9F0A4F50142FE7456BA660837DF0F5FCEA1FC4DD86E5D3D39411020B391A36B0187A3CD938EFDEE246B73A2360E79272EEC44AFE3EF103C3277F8AD70F3BCC9EF4282F668CD75FF61CE88E55C437037A95D16F14E473DBB5BC840200B0C85BAD8C60A03ACC70E6971D6E4AE6D88A68B1B8A889C8EB65C0FB4FB92DAE66B44783EBF64353160238791D14A6C518DA61ED513D86DC7BF9FF06A7714776D1D47CBC4048AFA17E8A724C9112E1818CDA39F023E8BCEB6BAC1B2ED16AD0D0C77A211CCE176BE42461F5730730787D47AFE638A2493AB44933F1F01432B911CEA3BA5D84693DAA5954E2E4F73734E69E56FC5C69467906B2B986C20D085F9CD6DF2285C2E8CC251A72DD9C9D3C77AB812EA6393B66838FB9E6B71557A4912F46D614F4B8CA3C3334F8BBB85796872BE60DF43A9AE416115B92E381707E34D72BF8435D72C374E54A8DC12DAADE89EFFCA439BCBA0ABCAC89ACA8F3738DA4A8332421E528A924807E2E3E0EF33823F247BA924509952A138DEE2FF1698FFF99CB6D20E5EDC109DCFADDC16B70824CA05382EA7D463C57500B219DDBDBFE8183DB182BCA5D0E6A1B3CE9A5926C3060D7069CCD62EB49D53FB05E01F8FC4F0675E342BEA9A56AA823D4B9C4FE99194BD57B5CF5E616602AB853BED737214A10D4B590D73A8363607E0DEBF05CE6EEFBCF2DF11F540C23A5B1370D84C8BB1585CD143046A57E84F515712B6D2B8D634F06518EA9EA54D76F3B0B12B779E3C5332B811B32E6532DF02678A95684017CC4C112618F4976E1A7A8EF671F85C882161CDDF97DBD6F69532813E4F60AF8A650D1D164BECFED85490B453A8431D13DB96B533B808A91195810577A2961B0F5643BB8FE72613F8F9BA69BB2238B96D997DCF5D6A85425DA622C00738B0883583C7BE3585C76D740A7E6BB58F6D213500D476B17A56FDBB4469F54E2986AF02B43EFA2D448EE84F282AE31E825331CBC822D13FD9810C5CA8AD1D10FE6529949D4A9DE05A0AF84B81C5113D3593B3C209A6928797537B433EFEF284B6D5A963E696A3313DD0512FF26EC6D0FA4D7117C83D212A3ED346F8BF87A39EEECAA41412F664BC496F594E963F5A8B081AD232DECA45962C487F476668A5370279AD90102CBCB75B4992D87ECF985EB54C78A8DFADA9F825BEA3E6A5B6CD8D28D0A22E9C45BA43DC6922F122255C64BE92345A881DC78F1E26636023E46404B1F56D00C0437C09328ECA5E09B1A942DE896C7E993FB5BE29754E2BECA2C33DC7FC49BDC00EF3778464E5A7951E50D6BA25CD2D529CC3CBFEE1CDC19E8B8EAE4E4E54F2671874DC46E886515CB5AD389A22822D8CC014A83409F1314EB6CB2FBE59B209A6F43767ED34BD6A7FB629ECD8C15057B8EF78A21BDDDDCC06F413EE10A483E0BC9D2569D6A93BD0A17E68F4C679D9C17FC9604943BC1F305CC558C3746CD6CD248FE42155048FF6F163B423191A39781F4AE7864B03D1CCF31280CD5550B481DDC9084DA2F91349B05F6D4061F8070EE11E21858FAA68ABB34DE6514ACE73F492EE387E97FA9F1A9FFB60950C118B495D69DC6FBB6442CC38510B832AA91832B36285ECF5B8BD602C1E0FC4B24137D45109E7D87006099123DFBBD7BE5FE12324C6A3AC37D727CDC5FDC884187C0E13AF884834D59C60735D62DA7F1B00995D5F0632E5185790CB8C0F1C0F6349912C1A52CAEF6339EA244AD87F577139006C653CA834AD31DA5BE85D694D57670DE62B58A397598A842E09DB83C6C4F0186575FFAF346F52E3A3EF0C4F7B71011E36B68C4A7D35E410C2CE8BD581A3C63D4019F0CDC70EA81E3B2A71CC67A2FB2F9722BD69A76AB9AEA13329572B337377F47ADAA29DAFB07F2F87C7035E1C351EA6F3C4267BC09BE7BADE9C38B5131E11CE9D6AF4029BC0B388418F5DBB401A21786CD1C86B381D839D1E49C7932A5411A88D04B29416CAA6691AC5310BBCE5078DF11093A3E9F267C4FB2AA05412313719C3C2C29CC5052251E7BAE547EA2BD5F44E84F9AC6AE6148D0D26E5BDACC88000961AE6BDC5EE7FA20C6C14A579777CBA898FEFBB1F630D165B8AA1C28B60B99FB256A7DE198E0E8F4F53E33D3F110A2B85C0DCDDFA0A1983FD0715295E6478A6C8CED2FC0A7C7E8BC0E1FD325379E1F65F8193DEF32E344256D3E6051D68999CA9B3BFC2C40000000000000000000000000000000000000000070B161D22272D37B88F61B316E0B8A3F695D071BFA1DA2DA8BB772BB9523D41ECF04ED8767D5E4EF8C0DB815C477CB8871FCB818F6E03707C292C5A0D112FCA57ACE93C1A298B524A70226A23DE80DA1701C76000979E877E573E5B623998BDBC8B57E637F6AD3D51574DB75B2CCE4F0A8C365462091AFF18B25ACA008D36764F8B80A1FD02121ABDD3F35740DB421B4B38E0C6E7EC131CEAE3C93A8C15274ED53CE8990502CDFB7AE2F64CBF14D67CE0F705B9FA9344B1D6B6ADEE56C8D9556E74A001D7AD44D38B50F085CAEC9617A44623B64102DD9B56820A62267834C883B58BB8C225E4DD6BDD16D971B4A010B78D8D70DD32E14510D758939C81478BA24F72B2DAB980378579D23BCB37CAD56609566E020F950286B7BE33F509F058B0C28FBBB8D49ACFD6D51A09E6E053785546EA19A9221C62177BB78119B3FE53FF02945CC43B9267BB1C3FCA6C57D6F291303F8C0410673FFD00A6D5E224FABAA16278231EC476B6A687B18A0B68ED05773B867EEB6DEE5FE370EA7D3D3CE15A7DC60DC4A65FA4B2 +Result = VERIFY_ERROR + +# --- ML-DSA-87-RSA4096-PSS-SHA512 --- +PublicKeyRaw = COMP_ML_DSA_87_RSA4096_PSS_SHA512:ML-DSA-87-RSA4096-PSS-SHA512:ACF0712CA13A12FF8B8B249D0EAD8AA974215B67AD2D66736D5F865A0D5EDAE4634B9577CDFACA4C3057D6B845DFD7416FE897DEF380C70993C4E96F2A39C40C4191C9F2AB745640FB661EEB5BEB3F5CFF515A733CC17BE0BE5DF1D4028C7ECEEA91E16A8BD7FF91EA0029CC1BFE3C3D42AA04A8618BDCACD4935BA35BEC471C0196218E2B147D0BA41DBA0EA9AE8656CB6B9C74E24CB428DDC38626BFC010FF20613DCC37F349F2974CA30A3B3E5CD33557B09A58BBE5D632678C720C398BE8C8FE0AE1BC5F728B0C7E3468C5E35882530E82DEF6FD9C195D614A992283D7D96C691ECF682F999BFE7DF8723BC492BE70A0CBED70868772C62B89FD2B4AB97D3EA84D666D80CB849B14B25C2A14D848CDC90E1ACBA92D351407698B454532AE07C4CEED9471BB6B5D61B05A0592B70EC9694A1E0C5251650A65CC55B1D49AC89E58BA83EBC3AB8D6C14B3651D0F14D67FCE7535749431C58F000B23FABCD78C6C5CBA3F66E362EC80868FBA3B4D97D74A9F34EB18345E99238A525C143205AD250D0ADF5D9DA22F564475A809C64D387B7A5CFA4B73E8BB9962BF965E190882A4871B5B0158DC4B32F287B28887359A425FE04C3B34659CDE5993CE3E2B02A97383F7BF590947398E8463E16B74D0305ACB5ED32B72F282EF337DDBC85E5A484EEE8E9B29E79611C975809A6AE8DA77DC5D333DF89CA9221D9FBC5DFF07BC33EED7511EFA960E9BEE999693E83F8FF0925571BCA50E6E8878CAE14164D23D1F79EC45961ABD4B84A537C520EAD2B079EAD127A3C6402C59CB967A71AA16C4A623532A0C8D8076136786D11E83E5567F185E6A86CEB0DC0F878F43B81A1C348E902F0158EED3BCB0D098E19FA479913B0FCF7BB9758FDA6FE28DD2D19C2D5891ED53935D0D1E467F05D74C6DB326889BD0B12088C3EC7FEB633A412A9A3434239060688BF57349FD936C9740A9BFC2D5109734958B23441311FCF9B0C57209923956A87A5127FCD5F1646A86C44197536C05ED3A25E6ACA760373C4719C8B86F4EC0621ECC2C8C274FDD50A08B7BE2D95935E5566526F3C632A96F1330CC7A785FE001CEF7E5C608F2542225231563C00745AF15BEAD4BF5ED46A401514745F91E0A7ED6C52403E7AAEF8D091D44EC40C68531CF6B315740804FD48BCAE0474C7F5E6CA1E3A3ACA3E124B25813E4255EF7D49E09B0CFF382091D69D3F1AD964E04E70DD9353EDBA437B53059DE2BCF6D57FD521A2ABB8288D17EA95AFD61420D4E4251A901B8BD79C7A18B9B5B460E0787D5F583958167EAFA89A82CEB6D5A41388B39B26F37A41883ACF25AC0FB6FB72D2FA2F46735347DF660BE479F535900276B4B5821D9D5D4B2FF7DDF41A540DB565E196BFC81D3842C1119C54855D322D0E486B5076733629D998C72FD7006D3512021EC6DCA9FC8CEB580EAAE534C4A539753DD2CC6FDE5E780D36DA06A0C174B15B2BCA88A0D77C0C1CAA37BB03DFD28787392F9BDA063FE4B1C0DD5DD6254033A3717EC97EC836B9874A131370DBFDF10675D559213C1EB3D9805DA28E73EBAA24CDB984C3CAEBFC54D8EFA7B2443D86B5EE354FA7471F6BD7E33218492AC69419071BD7000A9BD666B46FE6CBBE50C3FDD31A133B3B21B9DE94B1CC19DE07D5586CDF5801E8189E65E64B936A7E08E16B79167B1B5DE6A710174ABD5D644B622DC8AAC70A1C05F2F39B1AF181475D505740A02782445187748BA2CC1C08F3F8B40A1D849546D7DD7A3826F571EEE93026E98B1E9746DC45AA8755590D310B327BC7A9868BD9325E4586B0641E78C0A96A05DAE1FBA700DECEA0BD883A10EE26E3705C31DAC293B6B9DB04F814DEF7C4259EE85DCAC6000E7110885E0625C20FA814F90159923A457904A12EE14A8AF8FD4037AF8E3D1ECBBFB3C7D3AC79FCEBB5BEDF2CBE117BFC5AD51EF6CA497464BD4361005707E572A93678338D449C171DE552EDA126747F87AF24DD3910AF2C492918CEDA0F96B19673824A92BBA75BE421A59D3CBD55460327393C0E42FB00B0E986E946BCE964326AE20DAF2EB000F8EF501CA126BBE5C315B49D17266EB35D2275D923319FFEB15369AFA708AA3DE81C4C93ADA4DF51517F2DADC07DFB11C8B1A3D75A1E42A985F9CBC014143FB3FE65696F75CCEA3A9DCD89E95CA8941373D2860F849490CFF15E4398D02243C8D53B9525BD7AF999D93112CD9091DA7816574E1F3EB4980D31BCA1258BC88CB828F0A29ECA46AADE35EE7C7ED252839B663B5A440E84651524F5D9BAAE86DE12C20FB5E82B0D1186F7424B0966037F15646318B4CBCB9C773EBA507476CF9D8A300E73D57798342965DE743EBD2FABBD3B291843C033858D5768DF02BE002867FEAEF5911DC0A76BC001D49F635D1C749AF51F6E0C90C16D647ECC0B0858D6B408F04FC1DCC68D3C0167BDAC569AE27E917D94CD1DDF4BA13B89C38EA5BCC20C91B3F9077EC98AF1CA8084ECE4A1F625E7948F2D4E2D7CF917741B95002C3E3B08DEC32A6BEC616284532B6C4776D1277EFC941E74D941C887ACA15500B4BECC7DFD88E2E11F98E8F4A4399D54C0BB717844E8B4E91F12B56474EFAAA7CE871ADA080F06D001E6804CF7EFCF3C4B251A5C9BF93F98D2FF3702EDECB377208BEE02A125520FB8E931252101C62BBD0ADB09597BB4A4746B36DA393B9CEE20334B53699C9649CFBAAB8E35D27360A35810DA4FFE805FE7D1969635B0BFE43EA2E77A65889D59D211F66DF5DFBCC630F62BEB421D27A0BC0D72255960A479E05316769553273908D08B1B799C1F228515A1B0A72E6263EBC95DADBFE895046A9D0695B741F144A288ADA988BEA5BED7AA97A2AC354F11873D48F662BD2E220994C9A96C5849A654AF8F0AA8140E275A60BF7273C81D6F58359EC612A41E9D13D156C505F08FA905293347EAD4C8FBEA54CBA2118C3E57D7CE4CFDBF0A669AD281D1451B4B774EFEB53FBFCD4509196B181347065A248175B3A402299F9627FFD805AFF437AFD84BDD15FF2C64F7D86409FD69CC8FD09EDF852C3C67D54F83FAF9F088FDFADFC141E03F3146813D2DD74CC67C28D45B11658FC8588A6C4019CBBDFDA7D3A6669239EB6BDA2943CA6F085D2157C5ED97A1F154C02AEA1CE599928AC7830FAC2D1BA12E72966A4DD99EBA9E188E4BC0EA1196C7C2C12128FCC38FD10D726493CE504A59D06B14EB6CAE341C948C1B17AC965A7F8D38EC465CC7C0354073DD7B54603DFDCA25593F72623637A37CBA0640BDE158A9326B72C854FD8D450C10A2D3640EF1CC863EB3151110D7D827BE4B11491316F379B52477DD24CA547C9A22CE4634292DA2BA195810D069D9764A558A3B6034C9A787A6FA22F7790429FAA33B78F5A62B0E9BA4F1961DC7D177B97B17E1A89FF3AAA4B4B6EEEDF786F55486D873269C2EEFE246BA0A33D90EC8207E6A97908B294CC921EA6C29B38228885DEE6827580D88ADB5EEA0209DCD1C932C504CA815CECC1A1049FB3C66393B9CF83F8DA342C1B9F2193790AC91788E19831D5E19A0CCFF09668A3CB45CBC427E9D49CA75148627622AD3B6B0E614A6858657DD4AFD4860E709DE2815F1C740B69FD8DE98060C6D4F597996FD6514D598A0C8A2F29B3017A4FE59175A53EC0D62319969DAE0C6BBBC76A3A4A363082020A0282020100B303407B756BC67861684CE02B80AF8DDF380D24352E4D6401A39B926B98A7675B4ED51F12C4E7D39B576AEAC14850C97BBE046061D86A6453082CB492B09AB062C23E9736AAF3173C343CAF437459551278AF1706A986523B8E987EB3254DC54845DCE1DE000396A69124AAE1581AC722043D7ECC8279ABF90F547811CC1E768A26EE3CE22DD6A6AF0760ED13B2E0E687D833A0AA10F2C07DE6258847AF1B77CED25A09B7647156478DDC2033E27671F263DB6E8CD49F0B506188D4BE869776138C237FAB5F101ED8FDD98F21E2952D2287EBFF5764E040E03178633437B2EBAAE40006FD161EB24BC7D795CDBBB224F100567AAF4F6AB8C0E24752015D69F0A3EAE6BDD34324056D06A1AF8E2DA7AF2C99386134994876756923C797FFF785EA6F267085B2B3D2F55A56BCC2A423A7A4F4C0490C6DE369F832B74E21B0E9EF2D9342B78320391D7B18E130DBEDD41D3F2DED060EF7CD3BE300CE57CE89A9FD5F0D64BD2E06BD4285747110165474BA6A9ECCA92FB246AEB5CC5584340003A10E6B28AC2B43AB595C62AF395439248F3B8CC903B8BAD134D2825C01757FCDB9173B6258264176D520F5D340F946E9404880499884F4C86C379B48FC5F0266AC4576A17091BC797B18C356C4E88FABE02B58684B2E8D11E65DE63A7518598BEC3BE0CD670E64ACA93557F4343FE02DB7AF30E5AE9A7598BA8643ADF3CBAB128D0203010001 + +# valid signature +Verify-Message-Public = ML-DSA-87-RSA4096-PSS-SHA512:COMP_ML_DSA_87_RSA4096_PSS_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = DCE794D81727D475190B70D6B6C2443B1E55F2AD14A230FB255C6F1EA219BB3010FB3134D06B264B4BD744BF922983B0F5F5673BC240AFE1CEAF2D75BDCD91456BC07180340122219198FE1275027FBEE23DF54AAD9B148EFBB0B23213F52DBFF5E92E012BBD176B082B4133B5050C0EDBA460982B0A4E88E56EE54823B8A7517D5D3D5A0EE388083DB4E6A3D6A3DEC4A657F0CD86710DB3A04D37EE693D14E538BADFB5F9F883865BDCF7F686898C36E23BDBC5402146FB57366A91138EE0FAA89A956BF110FAFAB6DD170CF4A679E1CAC157B21A88AC1584437A5B5F256272D49A24239D3978E312F3F219BC4FB50BB8D10F4F67F54FE2CAD1B24DB5BDA37957BB799C7C61174D09EA2972F7A901616DF97E586C8F5C8541727E447B2E2E1F0E2DF0C25827A637978FC85646A72C8023C2340339723027EFC1A30DEF3B564460372B7C850DF9707F6B74540BD9338F190DA87B6B1D51B26D8AE0505F83874910A328DCACEAC9D25B3BE2F335102D263831DDA7C3E66E1BE0D0F39FDE69B522697FB979503ECA14F255BEB5CBC69385BFA35088A794240FDA2C36C4479293EED5CC5EBDE058877681C6DC2DDF3548ECF27DC3E749F42544DC876D27C4CD826FFD8CC03AB958602F433648893CBAB4282A1FEE38E873C91B53D07BFB03844D661160D293CE772C279CDEAE393AB4990495FB02426224A1B2929625FEE77641618584E1FD4A700E467CFEF2B540F752BE1F7A2C7B3788C6F3A4E00E8E29EB2AB850C855A78B1402329F5F6440E55715EF3BB660436BBB8BDCEE68A3A764860174B23E776E03AAE5C06A314BB6C9E21EFB9B49286623B100C92DA87E1B84582E87D9A25FB742FB11316C605972653C0C6D893388E4FDE35D056C9404A669C6B489246C5570D0216D892CB821BEE99CD1C1009BC961F04DB538DBCBA45B7A4683F2E98B39DEA8F1577AD3EEBE05B654B43E391C8F083713C19CFBBD24323CBAF850E845D49789788036E4DA38B439FE90E5B6CC387E7AFE6B111F1A04C36AC066BFAFA35B71BDE0FF783C9C4F03BC711214CE5A352E02791F350DD5005EE0FD5D302181D74F04BEBDA63EF37E2074447D5D05EE1F71DD5F539142330707E42C6E98444FB82405B1EFEFCA8911505210583066CD2D1EE7C444FDB9099F82923CA7A44FE1C950C2D120F4380EB22C9ED597DEC412AA206DF463346E4D820079D708882F8CB7D08D74CC951E6104ABE2243DA203EEA0E516BA14F4F1B62E19D776C6ED7C3386806FEDC7CD77979A8DFC3CA8400DFB2C6D75A8A01624C87E25CA08570AA6559D5F5238E0EC792487C421CE9D85C7B5370F8F4E15A2BCF7E1CF8448F3BC4048E07BB737FE50171FB91C4A9C2832508EA2798EB7A6EF3248CBAB40BE60772CFD237A794793928CB1313969264546BC593C0C3AE8CE9444B4879FAE69E59C26731D4EBE492FAD810FEDF2FEEEFE3C750909650738F646AAFB446B1B421DA9B3E7C2794DA42E43B51D8EABBBCEE79E3B84DF9E1947B9A0F265483090F7D7C00E6B68B1226F0F7549734BB9C3C48BEFF355F9FF40A3FD8AD676534E50769BFCF992DB12995F87AB723A0CAD640A85EF6AD817D8AB1F355CCF730BBDB7F15CA3418181DD1F9E66EFDA432B1E99B77A9BB2DC2BAF77A28963B1BFECFFB27F3EBA61B1AF30BE6525ED291F6306E0409D6F8DBFA0A535198E265BF7430C48D4403AB6A16047D2488CF7F3FCF4AB557B3A6BF4556166E5EC36E836517BDC98E2B7317A8FCE10795ECD4B6979926CC7AAF24962D3072B6ADBAF0B7C2330D9543FAA7B49FEB6FAC3FB0D8944CD05ABDCB958282C3BD436BD2A94CD400D3A287119603F64572AAD790D084058C74CD5B0532E302A0C9BC39AB41701957DC94FD26393EEEA61D195CC32F2CE70B1203891D89B408C00725DDF524EE958B777088772FAC479305F4B48E24E58F203BFE6577A2F21AA24B31307C16302EB5DBF9B0888FD8D4C6AB94421EE4862FEECB3CA6D7A93DBADC67ABB0C317EBF8D2C2D5BA979C620F0E8815CCA80F71A36B4187E1C03B087AFB1869D1ABA2D5B83412E15B137A27E8CE85D0E5324849C0CF5BA10A029DC9FF63761C1FD599779B93CB68D9C91CED21C4317C0C58771C595707DF8DE9B475EBB74E2D4E309E38D91C7BAE26E6DF6F2651D5D208561964F1001AAD9CDD183D4A565D5F3E249023AD09AC686C9FECCE556BFE5189C5B41DE07220283956E165468EC6C89CC8CD76045B040CF083C42D43D10D7974809606CE5F7A264700CEC0F0519FF757F0F965ACDC7413EAC741E47D5718DDA785DA2B17E21261105EFAF06E70F87B26081D2D2F24C5CB181852D1DF60D72E154238802F0A59D4A74F8217EBFA966EEEEB533622459131B54CF551A8778F56ED52EA2B0697D364B5B1264659C5B131A24C92BD723B84696C6FCD5C40A27D228E1E10631263CCB6BF41AD208BBC2E3BCF1863BE4DC60BF3A335A8D2A97EF269BA44216234C8182934EF97AC4ED2D529EEA51F5B9F94D309ABF6A3E55C1C8399197D711227295FCEE9A1465717E7083F4B808521D7E1C227D6805C23D35995FE84843894472B9C17D4B8B45EA1805DDEC904C0B0DA5E4ED0BAF7391449B353EFBABF3355B0E8798ABB2B5AA707F56FA281C7713BEB5329BC4C710BC798EB122548D2BE47BBE938D96A4BFA079F043485B8C9032BA51FAD884EB0F1A3FDDC6B3671FCCF83C41A4E1C8B2F137B8CDE2F7D79E7BB2194B2B07BB615FFEEDBFC96700C3B1C86EDF55E1A8B5281CCBF9EC95F76B8B68502DCC39540CC213BD56F245AEF3EE5BD2341A312C0D469E060D0B44F2AF74FB129E826046D7083C3D381D8828C81847192D609C273F1A70537B02A4E3EE4E7BA3C34A41C372A8510B9A744C492D90613024504361756A17698C760668B03D9198B58DE8721ADE7C33E47F16F0638C7AE1C4259484286A64677A07E7AA7A0A21DEC320D2007C4D16890FC063E09F9EE45318539D8A7ADEE6E93A28A71A8E2874E8D7F384015DDC188941F794954E863538BBF51ADEF9A221E62A30EEF860AF95E02E1B763C05E46ED85C00FE220ADBC6F2470F4C8300936699828F212990EAAA9F9A4562BFA0A82996B9F5AE8A023E033B6D3F6E767B1B7B606829452822174E0BA900EF8818BA5104F8E6248D65C0762D071877F354DE2BE2E89FF83EC6466B4A9F3EDDC398C76926AF6FC235F5A29CA3F7DD41FBADA38482D0C186CD1B1678BDBEEA47410C733800EF6F3C3A49474F10180B37108375CAF9B7EF4EA568FB8F72DD2F8E44AC913D8D735DCC46A41210F954A0BB38C7341E0ECDE9B06A9E919A3A477B9C5E1A6BF7B00E7C3CFB93914856A24A9A2992F011F09A2CBE89370C36D829EF4F930BEE04F3EBD1BEFA6330BB0644BAFD5B2F764C35AF19BA98ABE4D8E48B90816326F06EF8AED81F0D6E24971B0B6A41F205122A32E23005C68FA3D9CEE529E3448B85319C573AC1E12C137205FAC38911B76A0638C12527E9E1A75A59E779C681C9ECC4F26E05BD651F55B96F1CB3660EB43B5F8A08435FEF76C68D20B43E9BECAD563CFBB3F0A6C394099F33F8524BD0A6FB4D8029000A998CB24E5D226C28D6BD19C69292E8B62BB39AE7D107CCF5772F9C751F5BA07634970BFA416D8917658484E0BE3B09956E1CFCA46B59E73EAB2894135441A756457D2CF98B5FC5885E1E7AEE18AFBEB465AAA9689CF1EDEF42B8F6B227FD84E0D369997F9CD74DF8B0B7FB5BEA2F62E13088771C49CF31DDA70FB5FF85AEF3CD0199002CA00540FA96A6406BE58D0387FB5A28192BCD2AB3E9D7E28F026FED872511EBB3B3224499AE1E854FB678A86F972080DAEBEF9905592DD3AA82B71E1A5E27207B38BA78BE36702DFF8690E007747F6B88640A5FF03D81913B68E19B3B5E6510653208DDF3BB64EC2A3097EC3C958708519D9C31B038FC1E49C459E927FA71B372CFB90D18CAE18F629D5772717E3BF80C3F876C194840C131EA5FF141FACDA5216C7D80558F12B4B73B4C4D606870ABFCC835E62C1D5E64B31A6C426018D5FE1598C3C3ED2E64EA634A555D63658FF6D1523F7B7C5E5E8F553FC4ECF17969AE7128279CEBF9430F93FA10791D9F89FD00E60A94171BD794593C849F9914B66D692AD2AC6D338FCA34C64D8A2C448CB8E0DF7F18E5804B1F0B8D28E113BDB049E79492207F005718F1E408F2B94EAFE8F2AEA80DB65BC8D96278030D9A29CB3069B9AD8CC431C64B7D750DBC0E72FAA430DCA979923F6D7B89C2C08AEC204626BC6D76E19475BAC6DEA2C90289BCE8AF2007CCC3C8E208CF9FD59336D93C87CB2457BC0A95A581BC86596CC47A7A4EC9D96587E1A730AA11A3BE88FE21BE2F40B32D5AC30F2DF99422B2A39772C87904C7E9EA00CA07C4AB6DC9E8B65930C36B895731AE2E614B74DFA0A1A812F7A6E9D0B2019FFA7D00C8D22AE5450A4D9BB3465EB41FA4BC7389D9B4E02CEBDAFB3F0677C7BD0408839557F2EFD77A508D2AEE21CCBE4C7B6C5A2330EE26951AC4B94616DB9F001FE3DDC6627C581BEC61F7A3DCF29E82779741230DF5CAC5536902211C391890BC80DBAF6FB7DFAC301B36C87CDF5137A2F2623B792528CE1CD5698DC7ABB3113BC4E706E902E658B790A8AB9762F0D1B4D8FD9C20EC84F22D99E6370AC2EF655300078BE69F9D1DD76F845F689ECD4CC09EF4425F7A861486B4A12536A4AB29C3D3E8D011C1B0A132B38F466616E4388A86A61BD765B1A80F98A80F30EBBF7C78C4BFB81D95553CCADB3CBE716D33CBB0C37D74A4D8BDCA8DAE0D7E30769EEB5361AFC1181741206AD1F031A8CA6248BE65F0A01F44CAB69E4E6A10B7404A8E0933278C869CBAE833210EB9E89C977D2CC20F2FC2E4FF58CD1B5C7F8565F8DE864126FC1029B4C16601CD6B4B2388F2B4D2A960594BA7770067E6521B3F3142668135240EABA622BDD324B1DBEADD05369E7C0AD2CFF8E103220403B3C015689D77F3044F6A327A2CFAD5EF1CAF60A25C2A827CC70D2B8B25652A77885C67FD31C199D9A1BB0D09B2D24322B94045AE76975F56890C1D92050FA842F93A6B6E82928379BDE75803E47FFE4C4447FB50A42E6A4A2D5A53453B9D61BE762BC26C6CD84DF3D993C62093E75696D183CA5DEDC881E32B40893BDFF08C4D8B5AC5B995D869B989F9CC4F8DDC3BA7FD765C08438F809956744134011CEA184D42A657AA805101C3DDC37A0DC61CABB6775FE640FC981D8D6D258713E0066C8B9ACE2D3FB12952A0A8F4DB3ED918D6F871601816C1BDD03D8D6FAEF21322C3BFE78019E443AF9F54AAF46EF83566822C6CF09A6D8D01058023DB082CB0D80984579BE66EDAEA3045BC6E240CE9BEAAA973019F9DAD370E22B356086BAB155BCB8DA8A3EDD26ABF090A4747590A1972B00DA7638044AF5E8BFB5B8D58CF12EC9D8170F5094067920E51FA675760D5F98FD2D80ED6EA751E56A862BCF1130ED0093D56A071FB414A3B7F1BC443838ED285BA606C4652AC79DBBB60775EC2EADA413BF186754441C3551616F8CA2513BD18D02A1FD056FA462A527538E96184C274A95F4FE2FDB43D765BCB471135DD6A0262EDBEB7A8202DBF6B20F120A88671CEA18C7B6B3A19CD59BF33D7786AD34E185B1E27211C0886A6E0A8D5AE08B2EF8EF57F023E4F8FF9BF76C74C53800307F6D65972D7BEF818EC76B16BDB798F90EDB26B67F67724E3EAA62EDFAD46BCC08B7CCA4D250AC0D8EF0BC30CA19340A249F71A9053E19DF219D0F56E40CB5AECD9E1FEBC702E57AC826CA15B622BDD23020864033CF7E74ECB121B781C59CFC7F838B9D52BA15F64EC10183B18D49A83514DA022E6AA516B49E1F0549404D809A392C37E920D1020EE4D56266C0A275F8137DD4F9C0DF8BCF42343CCB943712482346E92B0E1E165C5B4CBEF98C2DB2BC51EF274A8412BA3C4C2C8C65FFC79D8DF08B47CA2FBDEF06C3FD903873C0BC3EAAA9A3E4BBC0EC0FE5B5D748FB5AA5F23A3DB0F1CFB5E69BB24CFBD95E88DF573C8E356E5F1F658BC5A5171FC19700BDF157CB7F31C3FA04A37C92DAD13EB641E52D77B1DABBACEE4B2801CEAAB0FE9EED971DEC2F8682B4FA8B3BCF3D77CA7A8B804E3C99AE2F4861E7A1FF960D2B860DE0B2348B2FCE05FD2A65CAD112C462C22E40F9D8E5EBABA3D9AC14D2B04A8B04731370840DCA9E98560960B29CE8FEFD059413F5B7CD8BBE243F2BC08731D6B4A2E0EA9254F6D1D0EA9C0D4C81D91F4A453E9368EF88CA1E173AF8AF612DA929C0AFA63C5FF9A22C990B3F3AAA7C9A4C2FF17A422C541C5BF495B45C29590D08FDACD369F9DFEC67107F26F2D47E9A42D1F367362FB2D12CF9792E0166282A4146A5B5066F05A8AE45F32BB6E12D7F5D345B704B9853FA69EE14B2D6B80021CB7EC003B70ADAD58080A5BE00809122E39616F85A6F622555E989B636E94A4ACADC8F81B3C97A9BDD3E5FD0A686FA2C6DB203F4D7A81CA000A16181D273F404E5D70E700000000000000000000000000000000040E131B23292F3B8AA10963B3BD11BE6B964006385081E937B9CAAA18E96357A24562ACD2AFBE79C109A3ACE312DC46FEC0C807CF76286E6C25EDB5F37A8463BB3A2B62F3FA8C4086007F4674F454BC27640F5D38126139173D307144DCCE0A0CF5290852AD84102BA8B39C2661FC9940455A61B56EF55AD15D7B9BDFF0E79172F7F2F69E78A488A828EF7F7F82A77A1C61BBD3AFA71AB4B6FDD345EAC0C6CFDDE3798581BE147AAC39E0D258645A86B12ACC4823CFEA7E4DF1CB9F8B6A644BF21D4AE95C9E8A1D3176656F69CD62E84037E7D2E64096FD618CEF82182A40F5602FBB1ED91FA7301A590DA40F9481A847EE4C4B0C20BB1548A5526BCED7747760D7503CCCCD047760199D47A2DDC3F7D53C0B45F62C395FFB5E0CB3254295A297E8670D9293E518225DAACA3C0E7BB1B79A532CFED8DBA08E75D0A532ED1F3EC96CFB0DC382808652911CE752A0672CFA8CFE4A1298576DDE752A3CC178B9ADAE0AFD00FF08B897805ADCC5456245656C09422991BE1847A658E4ACC3FE7820CAF2C273EFC5A378C6EDE79336CBB8AD1E8903C437FFC195EFF00C97A34DC449A361120E6B09586BE4FB3DF68EE699D858DC026DB4DE873A02456782CA2999ED568238C08DFBC1CAFA6C9407818678BF04D0AFA3D7246ECE71D9B2761DF4F86AC0333A1665D3CF8EE059BB302EA829C48771326BE4395B2E9529A234F3E21EB09E137192F13AA8E0 + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-87-RSA4096-PSS-SHA512:COMP_ML_DSA_87_RSA4096_PSS_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = DDE794D81727D475190B70D6B6C2443B1E55F2AD14A230FB255C6F1EA219BB3010FB3134D06B264B4BD744BF922983B0F5F5673BC240AFE1CEAF2D75BDCD91456BC07180340122219198FE1275027FBEE23DF54AAD9B148EFBB0B23213F52DBFF5E92E012BBD176B082B4133B5050C0EDBA460982B0A4E88E56EE54823B8A7517D5D3D5A0EE388083DB4E6A3D6A3DEC4A657F0CD86710DB3A04D37EE693D14E538BADFB5F9F883865BDCF7F686898C36E23BDBC5402146FB57366A91138EE0FAA89A956BF110FAFAB6DD170CF4A679E1CAC157B21A88AC1584437A5B5F256272D49A24239D3978E312F3F219BC4FB50BB8D10F4F67F54FE2CAD1B24DB5BDA37957BB799C7C61174D09EA2972F7A901616DF97E586C8F5C8541727E447B2E2E1F0E2DF0C25827A637978FC85646A72C8023C2340339723027EFC1A30DEF3B564460372B7C850DF9707F6B74540BD9338F190DA87B6B1D51B26D8AE0505F83874910A328DCACEAC9D25B3BE2F335102D263831DDA7C3E66E1BE0D0F39FDE69B522697FB979503ECA14F255BEB5CBC69385BFA35088A794240FDA2C36C4479293EED5CC5EBDE058877681C6DC2DDF3548ECF27DC3E749F42544DC876D27C4CD826FFD8CC03AB958602F433648893CBAB4282A1FEE38E873C91B53D07BFB03844D661160D293CE772C279CDEAE393AB4990495FB02426224A1B2929625FEE77641618584E1FD4A700E467CFEF2B540F752BE1F7A2C7B3788C6F3A4E00E8E29EB2AB850C855A78B1402329F5F6440E55715EF3BB660436BBB8BDCEE68A3A764860174B23E776E03AAE5C06A314BB6C9E21EFB9B49286623B100C92DA87E1B84582E87D9A25FB742FB11316C605972653C0C6D893388E4FDE35D056C9404A669C6B489246C5570D0216D892CB821BEE99CD1C1009BC961F04DB538DBCBA45B7A4683F2E98B39DEA8F1577AD3EEBE05B654B43E391C8F083713C19CFBBD24323CBAF850E845D49789788036E4DA38B439FE90E5B6CC387E7AFE6B111F1A04C36AC066BFAFA35B71BDE0FF783C9C4F03BC711214CE5A352E02791F350DD5005EE0FD5D302181D74F04BEBDA63EF37E2074447D5D05EE1F71DD5F539142330707E42C6E98444FB82405B1EFEFCA8911505210583066CD2D1EE7C444FDB9099F82923CA7A44FE1C950C2D120F4380EB22C9ED597DEC412AA206DF463346E4D820079D708882F8CB7D08D74CC951E6104ABE2243DA203EEA0E516BA14F4F1B62E19D776C6ED7C3386806FEDC7CD77979A8DFC3CA8400DFB2C6D75A8A01624C87E25CA08570AA6559D5F5238E0EC792487C421CE9D85C7B5370F8F4E15A2BCF7E1CF8448F3BC4048E07BB737FE50171FB91C4A9C2832508EA2798EB7A6EF3248CBAB40BE60772CFD237A794793928CB1313969264546BC593C0C3AE8CE9444B4879FAE69E59C26731D4EBE492FAD810FEDF2FEEEFE3C750909650738F646AAFB446B1B421DA9B3E7C2794DA42E43B51D8EABBBCEE79E3B84DF9E1947B9A0F265483090F7D7C00E6B68B1226F0F7549734BB9C3C48BEFF355F9FF40A3FD8AD676534E50769BFCF992DB12995F87AB723A0CAD640A85EF6AD817D8AB1F355CCF730BBDB7F15CA3418181DD1F9E66EFDA432B1E99B77A9BB2DC2BAF77A28963B1BFECFFB27F3EBA61B1AF30BE6525ED291F6306E0409D6F8DBFA0A535198E265BF7430C48D4403AB6A16047D2488CF7F3FCF4AB557B3A6BF4556166E5EC36E836517BDC98E2B7317A8FCE10795ECD4B6979926CC7AAF24962D3072B6ADBAF0B7C2330D9543FAA7B49FEB6FAC3FB0D8944CD05ABDCB958282C3BD436BD2A94CD400D3A287119603F64572AAD790D084058C74CD5B0532E302A0C9BC39AB41701957DC94FD26393EEEA61D195CC32F2CE70B1203891D89B408C00725DDF524EE958B777088772FAC479305F4B48E24E58F203BFE6577A2F21AA24B31307C16302EB5DBF9B0888FD8D4C6AB94421EE4862FEECB3CA6D7A93DBADC67ABB0C317EBF8D2C2D5BA979C620F0E8815CCA80F71A36B4187E1C03B087AFB1869D1ABA2D5B83412E15B137A27E8CE85D0E5324849C0CF5BA10A029DC9FF63761C1FD599779B93CB68D9C91CED21C4317C0C58771C595707DF8DE9B475EBB74E2D4E309E38D91C7BAE26E6DF6F2651D5D208561964F1001AAD9CDD183D4A565D5F3E249023AD09AC686C9FECCE556BFE5189C5B41DE07220283956E165468EC6C89CC8CD76045B040CF083C42D43D10D7974809606CE5F7A264700CEC0F0519FF757F0F965ACDC7413EAC741E47D5718DDA785DA2B17E21261105EFAF06E70F87B26081D2D2F24C5CB181852D1DF60D72E154238802F0A59D4A74F8217EBFA966EEEEB533622459131B54CF551A8778F56ED52EA2B0697D364B5B1264659C5B131A24C92BD723B84696C6FCD5C40A27D228E1E10631263CCB6BF41AD208BBC2E3BCF1863BE4DC60BF3A335A8D2A97EF269BA44216234C8182934EF97AC4ED2D529EEA51F5B9F94D309ABF6A3E55C1C8399197D711227295FCEE9A1465717E7083F4B808521D7E1C227D6805C23D35995FE84843894472B9C17D4B8B45EA1805DDEC904C0B0DA5E4ED0BAF7391449B353EFBABF3355B0E8798ABB2B5AA707F56FA281C7713BEB5329BC4C710BC798EB122548D2BE47BBE938D96A4BFA079F043485B8C9032BA51FAD884EB0F1A3FDDC6B3671FCCF83C41A4E1C8B2F137B8CDE2F7D79E7BB2194B2B07BB615FFEEDBFC96700C3B1C86EDF55E1A8B5281CCBF9EC95F76B8B68502DCC39540CC213BD56F245AEF3EE5BD2341A312C0D469E060D0B44F2AF74FB129E826046D7083C3D381D8828C81847192D609C273F1A70537B02A4E3EE4E7BA3C34A41C372A8510B9A744C492D90613024504361756A17698C760668B03D9198B58DE8721ADE7C33E47F16F0638C7AE1C4259484286A64677A07E7AA7A0A21DEC320D2007C4D16890FC063E09F9EE45318539D8A7ADEE6E93A28A71A8E2874E8D7F384015DDC188941F794954E863538BBF51ADEF9A221E62A30EEF860AF95E02E1B763C05E46ED85C00FE220ADBC6F2470F4C8300936699828F212990EAAA9F9A4562BFA0A82996B9F5AE8A023E033B6D3F6E767B1B7B606829452822174E0BA900EF8818BA5104F8E6248D65C0762D071877F354DE2BE2E89FF83EC6466B4A9F3EDDC398C76926AF6FC235F5A29CA3F7DD41FBADA38482D0C186CD1B1678BDBEEA47410C733800EF6F3C3A49474F10180B37108375CAF9B7EF4EA568FB8F72DD2F8E44AC913D8D735DCC46A41210F954A0BB38C7341E0ECDE9B06A9E919A3A477B9C5E1A6BF7B00E7C3CFB93914856A24A9A2992F011F09A2CBE89370C36D829EF4F930BEE04F3EBD1BEFA6330BB0644BAFD5B2F764C35AF19BA98ABE4D8E48B90816326F06EF8AED81F0D6E24971B0B6A41F205122A32E23005C68FA3D9CEE529E3448B85319C573AC1E12C137205FAC38911B76A0638C12527E9E1A75A59E779C681C9ECC4F26E05BD651F55B96F1CB3660EB43B5F8A08435FEF76C68D20B43E9BECAD563CFBB3F0A6C394099F33F8524BD0A6FB4D8029000A998CB24E5D226C28D6BD19C69292E8B62BB39AE7D107CCF5772F9C751F5BA07634970BFA416D8917658484E0BE3B09956E1CFCA46B59E73EAB2894135441A756457D2CF98B5FC5885E1E7AEE18AFBEB465AAA9689CF1EDEF42B8F6B227FD84E0D369997F9CD74DF8B0B7FB5BEA2F62E13088771C49CF31DDA70FB5FF85AEF3CD0199002CA00540FA96A6406BE58D0387FB5A28192BCD2AB3E9D7E28F026FED872511EBB3B3224499AE1E854FB678A86F972080DAEBEF9905592DD3AA82B71E1A5E27207B38BA78BE36702DFF8690E007747F6B88640A5FF03D81913B68E19B3B5E6510653208DDF3BB64EC2A3097EC3C958708519D9C31B038FC1E49C459E927FA71B372CFB90D18CAE18F629D5772717E3BF80C3F876C194840C131EA5FF141FACDA5216C7D80558F12B4B73B4C4D606870ABFCC835E62C1D5E64B31A6C426018D5FE1598C3C3ED2E64EA634A555D63658FF6D1523F7B7C5E5E8F553FC4ECF17969AE7128279CEBF9430F93FA10791D9F89FD00E60A94171BD794593C849F9914B66D692AD2AC6D338FCA34C64D8A2C448CB8E0DF7F18E5804B1F0B8D28E113BDB049E79492207F005718F1E408F2B94EAFE8F2AEA80DB65BC8D96278030D9A29CB3069B9AD8CC431C64B7D750DBC0E72FAA430DCA979923F6D7B89C2C08AEC204626BC6D76E19475BAC6DEA2C90289BCE8AF2007CCC3C8E208CF9FD59336D93C87CB2457BC0A95A581BC86596CC47A7A4EC9D96587E1A730AA11A3BE88FE21BE2F40B32D5AC30F2DF99422B2A39772C87904C7E9EA00CA07C4AB6DC9E8B65930C36B895731AE2E614B74DFA0A1A812F7A6E9D0B2019FFA7D00C8D22AE5450A4D9BB3465EB41FA4BC7389D9B4E02CEBDAFB3F0677C7BD0408839557F2EFD77A508D2AEE21CCBE4C7B6C5A2330EE26951AC4B94616DB9F001FE3DDC6627C581BEC61F7A3DCF29E82779741230DF5CAC5536902211C391890BC80DBAF6FB7DFAC301B36C87CDF5137A2F2623B792528CE1CD5698DC7ABB3113BC4E706E902E658B790A8AB9762F0D1B4D8FD9C20EC84F22D99E6370AC2EF655300078BE69F9D1DD76F845F689ECD4CC09EF4425F7A861486B4A12536A4AB29C3D3E8D011C1B0A132B38F466616E4388A86A61BD765B1A80F98A80F30EBBF7C78C4BFB81D95553CCADB3CBE716D33CBB0C37D74A4D8BDCA8DAE0D7E30769EEB5361AFC1181741206AD1F031A8CA6248BE65F0A01F44CAB69E4E6A10B7404A8E0933278C869CBAE833210EB9E89C977D2CC20F2FC2E4FF58CD1B5C7F8565F8DE864126FC1029B4C16601CD6B4B2388F2B4D2A960594BA7770067E6521B3F3142668135240EABA622BDD324B1DBEADD05369E7C0AD2CFF8E103220403B3C015689D77F3044F6A327A2CFAD5EF1CAF60A25C2A827CC70D2B8B25652A77885C67FD31C199D9A1BB0D09B2D24322B94045AE76975F56890C1D92050FA842F93A6B6E82928379BDE75803E47FFE4C4447FB50A42E6A4A2D5A53453B9D61BE762BC26C6CD84DF3D993C62093E75696D183CA5DEDC881E32B40893BDFF08C4D8B5AC5B995D869B989F9CC4F8DDC3BA7FD765C08438F809956744134011CEA184D42A657AA805101C3DDC37A0DC61CABB6775FE640FC981D8D6D258713E0066C8B9ACE2D3FB12952A0A8F4DB3ED918D6F871601816C1BDD03D8D6FAEF21322C3BFE78019E443AF9F54AAF46EF83566822C6CF09A6D8D01058023DB082CB0D80984579BE66EDAEA3045BC6E240CE9BEAAA973019F9DAD370E22B356086BAB155BCB8DA8A3EDD26ABF090A4747590A1972B00DA7638044AF5E8BFB5B8D58CF12EC9D8170F5094067920E51FA675760D5F98FD2D80ED6EA751E56A862BCF1130ED0093D56A071FB414A3B7F1BC443838ED285BA606C4652AC79DBBB60775EC2EADA413BF186754441C3551616F8CA2513BD18D02A1FD056FA462A527538E96184C274A95F4FE2FDB43D765BCB471135DD6A0262EDBEB7A8202DBF6B20F120A88671CEA18C7B6B3A19CD59BF33D7786AD34E185B1E27211C0886A6E0A8D5AE08B2EF8EF57F023E4F8FF9BF76C74C53800307F6D65972D7BEF818EC76B16BDB798F90EDB26B67F67724E3EAA62EDFAD46BCC08B7CCA4D250AC0D8EF0BC30CA19340A249F71A9053E19DF219D0F56E40CB5AECD9E1FEBC702E57AC826CA15B622BDD23020864033CF7E74ECB121B781C59CFC7F838B9D52BA15F64EC10183B18D49A83514DA022E6AA516B49E1F0549404D809A392C37E920D1020EE4D56266C0A275F8137DD4F9C0DF8BCF42343CCB943712482346E92B0E1E165C5B4CBEF98C2DB2BC51EF274A8412BA3C4C2C8C65FFC79D8DF08B47CA2FBDEF06C3FD903873C0BC3EAAA9A3E4BBC0EC0FE5B5D748FB5AA5F23A3DB0F1CFB5E69BB24CFBD95E88DF573C8E356E5F1F658BC5A5171FC19700BDF157CB7F31C3FA04A37C92DAD13EB641E52D77B1DABBACEE4B2801CEAAB0FE9EED971DEC2F8682B4FA8B3BCF3D77CA7A8B804E3C99AE2F4861E7A1FF960D2B860DE0B2348B2FCE05FD2A65CAD112C462C22E40F9D8E5EBABA3D9AC14D2B04A8B04731370840DCA9E98560960B29CE8FEFD059413F5B7CD8BBE243F2BC08731D6B4A2E0EA9254F6D1D0EA9C0D4C81D91F4A453E9368EF88CA1E173AF8AF612DA929C0AFA63C5FF9A22C990B3F3AAA7C9A4C2FF17A422C541C5BF495B45C29590D08FDACD369F9DFEC67107F26F2D47E9A42D1F367362FB2D12CF9792E0166282A4146A5B5066F05A8AE45F32BB6E12D7F5D345B704B9853FA69EE14B2D6B80021CB7EC003B70ADAD58080A5BE00809122E39616F85A6F622555E989B636E94A4ACADC8F81B3C97A9BDD3E5FD0A686FA2C6DB203F4D7A81CA000A16181D273F404E5D70E700000000000000000000000000000000040E131B23292F3B8AA10963B3BD11BE6B964006385081E937B9CAAA18E96357A24562ACD2AFBE79C109A3ACE312DC46FEC0C807CF76286E6C25EDB5F37A8463BB3A2B62F3FA8C4086007F4674F454BC27640F5D38126139173D307144DCCE0A0CF5290852AD84102BA8B39C2661FC9940455A61B56EF55AD15D7B9BDFF0E79172F7F2F69E78A488A828EF7F7F82A77A1C61BBD3AFA71AB4B6FDD345EAC0C6CFDDE3798581BE147AAC39E0D258645A86B12ACC4823CFEA7E4DF1CB9F8B6A644BF21D4AE95C9E8A1D3176656F69CD62E84037E7D2E64096FD618CEF82182A40F5602FBB1ED91FA7301A590DA40F9481A847EE4C4B0C20BB1548A5526BCED7747760D7503CCCCD047760199D47A2DDC3F7D53C0B45F62C395FFB5E0CB3254295A297E8670D9293E518225DAACA3C0E7BB1B79A532CFED8DBA08E75D0A532ED1F3EC96CFB0DC382808652911CE752A0672CFA8CFE4A1298576DDE752A3CC178B9ADAE0AFD00FF08B897805ADCC5456245656C09422991BE1847A658E4ACC3FE7820CAF2C273EFC5A378C6EDE79336CBB8AD1E8903C437FFC195EFF00C97A34DC449A361120E6B09586BE4FB3DF68EE699D858DC026DB4DE873A02456782CA2999ED568238C08DFBC1CAFA6C9407818678BF04D0AFA3D7246ECE71D9B2761DF4F86AC0333A1665D3CF8EE059BB302EA829C48771326BE4395B2E9529A234F3E21EB09E137192F13AA8E0 +Result = VERIFY_ERROR + +# --- ML-DSA-87-ECDSA-P521-SHA512 --- +PublicKeyRaw = COMP_ML_DSA_87_ECDSA_P521_SHA512:ML-DSA-87-ECDSA-P521-SHA512:46ADE57DD9C7CD72099968295AA531CC55027CEEC79AB5C6FC464E383EAABCAA585A64F34BC35623F42D91897216814FC63D3F5B16D06EFFE91620648A3B9FE8EBBA5E933B1D9B54CF2C9B35F51AD51F5A3741CD5642CD3DB6FC33A4627297B7F08070F9DB7EE4322B806AB93D4F3A6C2C75093743B8D5D3CFF5B15F14CC3A3A3B8363C3C0BC9A182565FFCCDDECBCAEF596479C9397E149E66E0A592A978B89774A3E14EA23CEFFD16C4A34B16AFEFE21AF3626DFC6DD354E6A1AED7084473A285E951BB5B24C12864665F0B72CAA826452928509BDA8927730D725536309DCE3557187034FE548899C9FADC6A1086965FA5054993639F66A27A9E712F99C0DF0ADF9EA95CDDC950E5521F62DB6CADB54F326CC6F98E0EC3672FC15CEBF22A1C23AA38209617FD0346A83C389149C6A36CC82CD90563DB1D0549EBA4B8A47E23DEFA4188CC21B0AF8DC86FD6A9A43C92A29D398E5F7481E7395D93156D5A27EF668DB58563424FB1FB3F8AFE9F259011D3F02446B2A6C3349D1F16036CF7FB0CEA59E00C7432F8205598E701706BBBE90C4B0005E83FB5405FD85483C92A5EDBCE88897FAF2A7465A7153ED03D3235B998A530CB0EF5F1DACA147CC54B29DADB3B7E377653692ABFB5A9F00173BE3EEB79154C18F89074AD625A89A9210A5AC813458DAB589A50C88282CF72384D538FE7C5CCC07D60A46C369ABD1572675A53E4B71E97796C88AD98E7FC324BC49BE45EA347D4A3D895B12D87FD504CE20F304010FFD707672CF5E0E5FA47D8CDA06F37A224A8B4AEB76389FFF551C4CA74D90B712F7F7C7ECF3744C3E1A59011B89456BA4AE11BB390C49ED7A5E22FC04DE200FA120E34D922CB68E02830D4E63E93A8D1BFE994FC83C7A31276F17D60A96A2B1C365F9AD15EACC7488D9D087C481CDAAE12836DA5A35FD57F3FBBC0FE42708040509414DE2E4242ADF406E08B50165AB5EA50B1C957E691F85B74DE6D7C31E6B075DB95660764006B86C289060AB63D8FCD4CE1E8E8B3AB2D511BC1F1C7BC6CC8688E4FA9432788E159F72F8278B0D264198CD31DF07462DD700B21474B75EE52A339E39CF1829C14954E3ABE79ACAD18C6E24A2C953A5939725FF8C15D317336273A9A57CA53596AF1860C71FC1C73ABA8B94BA6015DC492811CE2D125A80A7EAEF9F8508D351603D4D132F4D3099744315E88AF354ED4CED8DE0EC5D1D006451E48F5FC5871DBBDF46AA503F08ABF63AACD41ECDF15F693938AA6BAA526944F3AE1D6FCBF28A151BE116A699BDF7636DFA43FCD7EF1B7BD9C3D0F338B1E77E0FB249A72E7810D06ACEDA493BA92BFE10A7BC82549DD976B054F3B44B9C0C952B4663A6E83525D0B22D2B437A7C44274C255BA0414DD4A465F8F520328204072112A989AA9CDC7A5BA81DBEB02E82293B7B3411D92B3D1EDA5D9657B2045DF80B171A8F02B646AB13122A0B4D2BA526AA0B6743B753B0FF92E65F6AC6EE87A0F2E60B4F7831A9984ED90D31818DDA447E22647973E3700CCC3F01DA4D61442191DA6B89D9DCACC4B7755B4A44F3E7C776DBC5D9E691271E543A216CA246EC2344FF9065AD1A258FDD5E9620C2AE710055F1EEFA90AFC41ECAE98BBED3B6E7BD62E5C703D193997076E7C8ED010CDD8D84CE0E4B91B9271C30A067CA8D7FB38B777F677421443F40518056EB17A522A37F2EC128A70EF54AB9EE64D21928427FF1695A4D80DC0AEADD76680932F1B6025CAD575CB7120C8D0A6EF4766AA552CA0C489FBF86BAF9A75C9A1C5A4C88B0A8E2F2E2ABD605A8C8A87F0E853AB83363C4DD2D040E168C4E48D0B01A314DBDBE249F72FB6EB846CF9E1F23AF289FF8E5B442D25670948479774FCED65E32E8EE29B04FE1966F43B9BC764EC0DDC4051B41407E2AD5455DFC5A5757B1DD4816950B53E97773C05A3A672775A3037AF909202C8878609E7E44FD56F2557425F224111099042A4CC0FDB6738C2BF5A937CC46EF38C68AC078946A019088D6E91F10B83FC77FC1EC616FAACD91EE680A8AAFD9EE9F153BDCAE52DE32CA9BC59B6E0B8EED17E0D12150FF48C9D72D9BFFB53D15A8A094E76160F44758CF2214EB6C2B39DA12582060849878852756D7B531CBB53CEF50C83B2574BFAE5A31B3581FB8D2711667F2BD6490ED4250967DE1833D8B4CE482C89DEFBBCBA26775C1759B59660333079DE62BF41F433FD5099BDADDA1EE73F92359A0DC5A98B7E454233051AD244D2418CADE9BCD3935882A840DC5506EA9E5D89EB8566F4E009989126A3BD83A22EB2411EF08C34731D566B9B8991CF09E4C3947FDF44AAAA8A0FE13FCAFEE5A89E8F7550A01982D50DA982E8567562374EDC880A1B83C4C7918249B0520CC539C44154ACFF8399098DD2B344E0B32779AFB966C864659D9CA49C755648EDDB37ED1995E972496E445771485098D47945046ABE06125EC5B1865D2CA2B201C5664B714192C0FE40DD17252FFB5DF7869BC597B1D537306A5ACA9CEA54D5923499E03804989EB8D475A7F32517869E08D3B379B85EBE863E7B0F77F755EAAFF83F9A3AD2D55C65EA3560D116F1F9433F7A7B2CE347C747D5BDC1E2FDB1A2EC3993B58760145CEFA2C9B2FE44083B4AB6AFE53BF4AE9A30F7FDED4772EE95FA47339D6F712CB8D50BBC8FB68887E654C0DB891F170B9F31DCE262226F91EB9CAB691150FA4FD96D9F8901E7529EB656119FA4762017BC87E393EBC6D425A7C7C766E0048E0B445DA2A6CABE47EE332D4AAAD8DD95F9C55E0C5B9E16DD4FAF5CEBBDBB968C3AA22B9B3C3B47E5CE57062BFED1279A0E8C22971842AC5F0EEE33AF415582E1C76318EB6EDDACE5481D766A32AC85C2034E271B4794AE14F9B7F567DEDAE27E6D1DCA3FE2D5712AA73E4704314B67C7307D0929CEB3BB4F329B2AB57D3735D519B2EF67D6045CFEF4086514ABC5E8FB71350EAB85F68A2EEBABFD6A1595FF1D67C3EAF337B15F7190236DCFF53E0CFDA1143649C167477A9C49DB6A698DEE802194D3F6BD1AC0F78B2493F94008D802B5B2A9C6F9A3BF2CB66C919DD2E7647679A49BFAF529AA7CBCB28C24A109D7692E94ADB890005C55081C67064EFA52BA06BE2E298D9CA192609CCA9554367FE6C32505C7CC5C55670BCD46F6BDF470E34BBD7F079E0C7FC22A75933473F0D77F7445D4A98C4DBF085D51463094A63909A6511C2A5E99E6DE3E6F4BBCE1CDB4C190F7A1B97253A2A0A41C08DF4F2930DE92B6ADE7A870811396304A16844854E9CC2E06450B253437FD9E373694515A6E70985C08D188E5323EAA42191B728277CC675B9740F9F7AC03536DA071FFD41BA2023DEE5D12646ABEED431572BDFFA185A7ADDFEB1D93300390588AAA484FAB7A6400E4606EF58DA822B464BFFFF8DC4BD7AD829DC000E5EEE5F9A17E16F3ED4FFCF6513F33FB735080AA892BC9CE252CB5A3176FD9AAAF191C2C045591591A3D3A6914C4C4870D8BD4FA60AEED8B036CE0E92C653991D32748641F79C342033B3D30333E61B2E5B6B4914A39A61FA41AA45392738C997AC0678F262F45DB02731257C8939B96F420212F182CA33EB175ECBDFEE22FD882C838FFDC2620641147BFC4782FC7036961FDB4D34895E30CA654B1DE5776D88300157EDE76BF3CBAB5AA87BB5629BDB290400BD3BF6D2A36A0EC63B2D95BA42D7638CBA1167FD1437186C0C92C8737C94683A62604AA5A73C7DDFB59AC2258F923D39B322184D6D856FAAACEFD0BE473E8C223801846DFC74DF3FBC1E81CD3C76785E1879C5821048E5B5DB07FDFFE407E107E200B605A850FE1E2250600C87CE282F085523E770333DA38228CB953B6A5FC5448499 + +# valid signature +Verify-Message-Public = ML-DSA-87-ECDSA-P521-SHA512:COMP_ML_DSA_87_ECDSA_P521_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 1AB3B068A06A054BE404A946D2A96EF9F1D7BFC2194A8B251CC44A81479423127DB47943B798670F89E37E24B61ECAD73918553F288558A00286C560066C93FE386B03EFF82EA87325336CE8E27146753BD9FC42F79A26C6397E1467766DB9D2D7AFB255215D03179F62C2F33C415265BFDC617DAD69117647E4117CDED8285EEC5529DEDC856C3E2A309D3C61430CC1A8AD85B1F422A11CD820D1E2E9E33D8F32EA429C86B548971C54AD81519608EF435E8A4C78968E18E37BDE4F42A55596A3DC658AF0D6E6578B22E8CE2AB7EC51646F14CED1E66B0DE815F47AB3A5F34AB9C705B5C98FD49DC8E6C6F3E7EF0812EB6647BDD34CCB01A54F515E0E0B1DA16B53B0E26CF5E19A9B753C3EC356C6B2BE899D2D03D5FA09827427FB00230D89CD11EC89CC959951DBFF362E82A4B6A32AED3DE7C203776C2C63F8A4222576E348D330FC6BE48E19A618873274AB0649CF8AB1AB65BD70C914208766A10131C4E33966086029B2AE24BBF4C19DB127980CD528D0A02A35CBA7AECEB3883DB61C2453C973BF536545ABCC89543B8D294D9912A9DEB69F55D73793B14FE09CF54D647DFB35CFF60B1225B49E8937713F00C99ADDBD17BF8223482965A7AC221D8B4AC7AD9CD5028C72901A51A9DD260DD1F618D268A004D3488D2591F216AD3287C065C4687F7CA202A979080575FB8B6934CE70F2B001D7EED274C1F1DA65C00F04C1A49CDA8204C10B44F8AF939DDF87722E53E4B150FE9A37ADABFF576C1A724318869B745D26AE433D668F109CEA59325EF6BF372AA170614FBA79E181D728DAEE0B789B062C693723A4C5932B479A7EE7556D3BF6D2A2267DE4AA1DE9FE68750E4B788E05A47A0AD4D510AF0483E0418F41346D1F5FA0A7B14966967051BFD7994784076659B595EFF646460F03DC8887F7B7F166FC1FED6826FBC283567FB97176C425CD9F81D9D4C1E3D7471DCC170D824904253BEF57C0306058C66069413D5DE734CDC00FF8EC14DF0BA555A48CDA0FE91A19E4531287227F9F99974D903211F3E396230ABE9E6993FB151F39D05B3E46FA32F01DD46BFC058555028B0694E8A4FE4114E01AC2EE558927211EB967BDF40C7CA96AF037DC173C50F6B785A079567BCE17493A9DEF0CB7EDF74C259AAEFC926F568EE0B935F8599DB7AD191DF0D24277CBC49FF5608A0647C847FA301315BA8BA5AD3FDD6A5F1217BC99A3EC0575AEFF6B624E3DFCB064C0257572D43F2AF063C51C823C6A197693A471B28A4493BAD7623BF7244127AC2163EAC720A27E0A05E6282709D1E7862AD939FCDF936F7E3AB99D1F8655AAAC6E82994177F0F306818201C85E58002DAA27CBA3E8879C9B2E4DE8070754D6103F26397092C1DE6F8FA79F87894F79FF010F6CF858B2355423205B4F045829E3A73C4D3A3765840B9ECB30EDA2EA32D78EB776CDCBBE78AAA686F81491CDCDC529C5B5EE34C58B85045126D695B14CCE48D681CD880C00DC648D247AB598143AAFE3729D0673FE236F6451C017AEBD12E9D6AF27050446F649BFB74827F4078BFFEBA0F50860E24290CD2F7699B3B2CF8049A09A27670B94A6DD3E76989D61BA0A5578E7EBABFEC37B2035A1E13D8976803A75845D7248338DA0F05BDF66521A5AC019B476BBDD4917DB03D316664686869BE14EEFC253481CE081ACAEE064D32A626C756184B03FD553D2F4A3AB8680CC711ACFE4676C217831931E6CA8CDC5E657722DEA55D241ED7C4561A2BCDBD8B1F96B7C02CB428CCDEA1D4BC1753BB1CA309E14EED168D3EC503BF0924B389502705750B28C67F4D33C9FC241B1F19A2E5E28779E137DB720D08F46D8A8CFF6883AFC2766902EAB30295D6E5E72626F5374BA988548D88E235F9E60753B84A644748522ECD1F6687F7D53005F1B00C21E2A260C94C31A2276929C09F7CCC98F8B21753D2EC919CC6595F1F5ECD650DD9B08F5417A104146DDDEAB998BFE98C03C0704D7D848FAFB16CD37C2F279BF6EFF901EB33075970E82EAF69D248F530AEDF31C65EC6BA8A3CE3485949AA704FAB1EB7A80D226D7D7AD1CB268CBCBF0B8C8C159799AA6BA7C16269B7E155D3099A22E0E79D72B8DCEE192CC797C2B44E844D52DA58F14BDE34ECD47A26D82D4EF6235AECC91A0A54CB5F69A134B634363C512A947A5FDE905033CE0FD6737D33675FEF37E41AC6CEC5ED3EDA0AAF7EA7DDD2296BB2E6B2CAF7FD881EBD82F15D158B592E1CA88D8245069A572C2EC316FD2C81A5592363098B20B311B091D6BA3369BCD42A2554970E2FD507BF6112EA665C9465860D83E7CCB8AF30113DDB096862F4B7C41DE90E40813EE437DBDD9E16E02BF7E5165BFB4A2BCF4B30C7F5116103A3108C6AB50481367FDECAD41C5CC36A29238DCEF1F8704D4739083CB31125B6F3B432953FBC5746EEABD6D87F6C7E9EABBA665CCDAC07BD0B0D5647D3C64606F972A8953BA29CCD46953BFF31C874780C8578BB43AF68EB817D7AD5ACA65210595BB9CFE237C172F7D60D4279689C8BBB33FCD0962281914BA6CB504B3E44EBBC1D386573F9415A4AA37437B42056AFB14FAF59E113BF5CE15F763BB3CB3C811BBEEE355B1EFD2E5789FC2368549F4AC5CC76864879C3167B98B9B6E9E1E9AD984FCE9E812500BAD2A593DDD121D393A299948A1C9B4661BC187D0FC570F9A2148FB9E1E4E52CE58607AFE2BD7068B46BE109E7744F28FD8B84BA751D8C42AC6F7E262B39DDAEBF2799B02CB70F5A344C58222ACA5115D39C748E8DECF9ADD20505875F742CF627C1BA9277B489DB844AF39FAD2C36C1F0D9580F5C4E49C69F1D6D6D660C0A48D7C7BB03637E8AC52137751B5C5722C7E16235D17AA4D4204AF0312711723441047EB0AC1BD371BFEFB91696858D9970D2943875D9C1BFCEF341E5A82E3209FE4DA9D7532D62CEB8EAB69C85BF0BC3FCB56DE02BF5855E02B93DC6CC301261C8CE5A2C32A67BCD72428AEF6A60637F090E9EF513EC274C73EF9B24EE26A45C714A62CB7E0DFC719B5F3E850F3C93B2A548D8323C4DF42D0FA71678DB8218F432B047BDF3FBAB10E87D1D8FBE1A03D38D7F02462D85EED76183CCF87123D2889DA30EFA44B8AA923FF20D32CF3430AA36B8FAAB290F8AEDC91AC4E93860ADD1FC7DFF64128E6D2B6B46F8E395F7013190CA0B3FC2B73C3C231CD5E731839366767547FDE835E0AE130577783EA9DE94A6D59FA6F972EB2840F4C9E42BDFFB582F339FAA4946958F18D2289AD22457E1E65BAD7A1A496AC4733E1304E374ED803B7DBC41FD68544ABDD343AA678E2222F14E9C8593D5E115A8B3E63A2CB4C27BAAFE7FA1F492574E0671DB20B1204C236AC7CAD1CB19D28D0D59DA53097ADD805EFE164EF1944B9F9DA87A8F201D7EEE9106EC01F0C3330107C7E4AA94FA819282920C95EC1C7CC47D71DB98825EEBCED85F38AFA862B3328656C94EB4402BF2C2DE3270771CA10E8E3235F27360B973D4BE43BB137EB976C464308ABEACF84911F429F60FBB0EC4E45CAD848AEF0C37FBE864276D1D6D6D40B9AE47268D7783FA1E43C830F089F5BDB6DCD2646184C258440989F379C529E7CB374196A7FE8B506243A274A4676121E09CAC23C02DEE82E28000630F4000638758B67361763DB886632BCA33736306E8E45FE7A425037684A4B892AD47B9CF2D9FFC24BDD87BC065009C9820111A738B5A3D60F39CB6017997A1BFFF14C8821AB4D93FAD21CD7703E7D351F06E401588622486561EBF46F528D08BC3505F06E17253961D255097E8186B6D2AA5AB91DFFCA71848DC392899322E85A0170572910BDC564602930A624B92CC2AF6B018B0500D1E59D3564E7F6D768E57B2F37A045109D8DDA77CC2ECBAFB66640E10F878A2D9CD46E70ECA694D863A55BFD98E17FEE4C67C47D68629CEC7CC479E456A63A1D0BD8161A763551455EEFEBA0AF44D1DD72E91631865C47E1A21A40FE7258BE14C5882E9BBC4F7E94FA4F75CB48E17D46DC5959B60BA39FD9540828584FB584E63D31FE3053C4424CA39067FFDBD74564E1ED99CB5A80FC82CEF4B41E4903EDAC1CA44A425CCA32EAC5BB44DB23221B55DE4139C78985A5AE48B1190BDABC4C246050E79E7231EB870BBA0B46D91EFFBDAA18DE21750CF0DE7F8EF748673E594FE065D7774A63F144B890CBF7DC1074FFC4EB376BA416609616F7E451DAC2359848A6CEFA408548823DE096DAA34645B0829020D28D14A6603C29270C3847FA4260D0C869F50E2CDDE8381457C120D467C7B0947A23BB53AE75F8E7C8994E0CB8C3930D341D3B2EA33129EF38A9A66DBD7CEA64FA962072000FEBB631E99DF7DDB10E3A7B4E3D9A25AAB968D7895AB68E6EE1DCA2BC4BE9C241D79F43C5E058E82D491E66CE66159FF3425F7BDA5C9346B0BD668461789AF5DF34909AC97B0353298167F77424CEC9F294098D5C1080AFC4228954D0E835311737C1F0CB9C1537388DC67AEBA6ACC8000D0502CB6A344E86D63FBF0BC7B08AF23B20D609117801F8CD267BCA66B2A34A1F272E4608B107A14F40D0F451915D41B731DFF52A6EEE316144B4D64692C2B68129AA80D60D76262FB0DF23C2E2A10AE2F5322D9DECBFE271D5C4964E84C30B68D4C142E622D571709E83284C8D3CA44D17C86E43787D5C3D5289F239CA39CC20D7E79EB606C89BF46EC1C51059D0C1DC07A509C312BA3FA0D9A2810FBFF38BC8E0778ED342C59B8F45EFD8690D4DD00847295A77EAA820A8CB6EB662C0EA6CD8A05ACBFA89E84FA5AF212A50D6C1804A3859318214082545846D4B76913B5FB92A2073C255F0B142BC899D6F372A83FF6F9C231DD55A2F06EFB7F7921C78997EDFBB04094FB0FEC94F92663FBA4F31C110F8DD0E5393CCBDF6C7360509668733C0A911F61970DD4C4ABFC7222B130FC390C6DB07862F5CF433CA3A5A698B1E03867C66A3024DF797D84DE6C37B8301FBD0C8B0C6BCE504F037167F6526490C1C16174B8173D852327624547BF1AF76FB9111D072BF1338E0A56FB45775FB558D19740E3FC0F8B5BCB50FD8D7592B06FE49B0AF8FDE5C075C840FBC73A29612D398AF1B977E5D91B78B11A81644F0DCD3B85A215EEC03826E58AF9FDB0C2BC3BCB874437B152D2D35A63F875C8B4559E11BD52B89625B72E56BC084FF9E90968BA2158708FD7EC4322F2DF8DFCCFC15DEB6573D28564D25BBBB0A7F46A31D66C941C9E344630445F31E9BAB101920EB3D2FC5D04551758B0E4F5C2725D68B6A89EC02BFC9786AEA5777CF829B4C31D23292CEF6FA2F1B0B8FD908FA842DBCB2A32F418AE27551D68D322A2C16B66E2DA8DAB963C97483945C9665FB996B34689B931D9F6A44670D9CE1C94222AE6F7BF5F2DCD008D8D73622464048D58ED93FFC8E57C1B36C4A92761A7D9634E3F5CB6F305E7A2D103D0D53698D73819FD5BBE2C008CA021843CC27B5049C3ACFB77B653598908F056BE5DBC38FCEE3B21B510B0D3264E9A9CD078553AC6398924DAFF6A1698F92099FE3853FA5A0F86B6F15C32C1C3E45AA5754A3219CD893E51A6409A404163E5BB0EF6BF5EDC9A791E9C4E745A93453E2382A7A6F934CBCF77AD660462263CDED97E143368FF42C97A4E1A340AF7F1C9319462A4ACDE84E6F46A711C967E858B0AA326483625D1FF0B29C1E0BFFA79832BDCDD51C9910CC5E549230196B65598C95CCEBE35FE7582F37A240129B577901BCCF04F7BCBE29D346180A8C0511822FBDD7E1DE9BBCB4BC49C18CB52836F95528B805DE001C13CBE8FF8514E8FB62E39B5AA47A73CC21944359EE4939D33822467EAC6E02AB31167C601BC7ECC04BD00EF78DFA28637990A007B98717E4EEE2FFAA72A1268690765AFC226460E64FFD5863394B5B53A41C9A44FA8F3F59A4B8E1187BC6303655644FE430838873BA34537AE0416A3BF045F521619235F95998344F005518308F847F47917C9D7692911942886F55B8E40AD5A91729B6E96425626F73A98B17BC868D88DD8A52011AB837672A7D9AF06EBD6A9FB3BB60EF8C804609D14EAFD19DBE7E6E59211DE8DAE427B00AA0052CB399967079B7F4A8C0488D2B531DC13B0DA644115808B87980474950679C579D5191B2D2A0B1C0E1CBB4F3925F83C35D208F4F0B288118867DA0A8E7934A072F23B56A795AC4AE9C387BF65C318A469AA6513FF7C1A46FB2B676A1CB61F2CD88F3DA21F16F7321092FA81232291CF7E835F830B33558F3BD025DEF4DBDF626397995447D03CD6B867EFC98BAEF9D5F2C6F66F3FF83CCDABA0A1E45FBE0A3AA87E6C996213A618526BD8539BB4839CDE018FD05F926FADA2B42D2FF0B5E177FC9F8CF07EB8B3A782A448147CC9D527BDA9C964CDF3B9A52A4F0EDA2F6EDC9A0FD1BF05E3A57E65005671D97EB83E2A5AAAFC0485CA844B0A292BA4243CFE20C232A3A6BB0D0E247A9ACFF0A101D5DA9D3E6808D97DBED161F646576BBD12543565C8198E1F7042B3EA4D9F6FB0000000000000000000000000000000000000000000000000000030B0F161B222A313081870241710E6DDF1A34DAAD4DD04826A0EC9CEB9AEC0C6B869DDF65D0B979D4BFB0C711A32918447572802A10CA619FF9AE16DE84E037E0231428E13C8A37C804CD6300AB02420145D39D0E280CA4DB32D616F26DE22F2EE427876448D6177AEEFEE12AC19B354AD81C7D6982503D19CF1D581A46216E85D99146D4AE244C942329F5C5B02117349F + +# tampered signature (first byte bit-flipped) +Verify-Message-Public = ML-DSA-87-ECDSA-P521-SHA512:COMP_ML_DSA_87_ECDSA_P521_SHA512 +Input = 54686520717569636B2062726F776E20666F78206A756D7073206F76657220746865206C617A7920646F672E +Output = 1BB3B068A06A054BE404A946D2A96EF9F1D7BFC2194A8B251CC44A81479423127DB47943B798670F89E37E24B61ECAD73918553F288558A00286C560066C93FE386B03EFF82EA87325336CE8E27146753BD9FC42F79A26C6397E1467766DB9D2D7AFB255215D03179F62C2F33C415265BFDC617DAD69117647E4117CDED8285EEC5529DEDC856C3E2A309D3C61430CC1A8AD85B1F422A11CD820D1E2E9E33D8F32EA429C86B548971C54AD81519608EF435E8A4C78968E18E37BDE4F42A55596A3DC658AF0D6E6578B22E8CE2AB7EC51646F14CED1E66B0DE815F47AB3A5F34AB9C705B5C98FD49DC8E6C6F3E7EF0812EB6647BDD34CCB01A54F515E0E0B1DA16B53B0E26CF5E19A9B753C3EC356C6B2BE899D2D03D5FA09827427FB00230D89CD11EC89CC959951DBFF362E82A4B6A32AED3DE7C203776C2C63F8A4222576E348D330FC6BE48E19A618873274AB0649CF8AB1AB65BD70C914208766A10131C4E33966086029B2AE24BBF4C19DB127980CD528D0A02A35CBA7AECEB3883DB61C2453C973BF536545ABCC89543B8D294D9912A9DEB69F55D73793B14FE09CF54D647DFB35CFF60B1225B49E8937713F00C99ADDBD17BF8223482965A7AC221D8B4AC7AD9CD5028C72901A51A9DD260DD1F618D268A004D3488D2591F216AD3287C065C4687F7CA202A979080575FB8B6934CE70F2B001D7EED274C1F1DA65C00F04C1A49CDA8204C10B44F8AF939DDF87722E53E4B150FE9A37ADABFF576C1A724318869B745D26AE433D668F109CEA59325EF6BF372AA170614FBA79E181D728DAEE0B789B062C693723A4C5932B479A7EE7556D3BF6D2A2267DE4AA1DE9FE68750E4B788E05A47A0AD4D510AF0483E0418F41346D1F5FA0A7B14966967051BFD7994784076659B595EFF646460F03DC8887F7B7F166FC1FED6826FBC283567FB97176C425CD9F81D9D4C1E3D7471DCC170D824904253BEF57C0306058C66069413D5DE734CDC00FF8EC14DF0BA555A48CDA0FE91A19E4531287227F9F99974D903211F3E396230ABE9E6993FB151F39D05B3E46FA32F01DD46BFC058555028B0694E8A4FE4114E01AC2EE558927211EB967BDF40C7CA96AF037DC173C50F6B785A079567BCE17493A9DEF0CB7EDF74C259AAEFC926F568EE0B935F8599DB7AD191DF0D24277CBC49FF5608A0647C847FA301315BA8BA5AD3FDD6A5F1217BC99A3EC0575AEFF6B624E3DFCB064C0257572D43F2AF063C51C823C6A197693A471B28A4493BAD7623BF7244127AC2163EAC720A27E0A05E6282709D1E7862AD939FCDF936F7E3AB99D1F8655AAAC6E82994177F0F306818201C85E58002DAA27CBA3E8879C9B2E4DE8070754D6103F26397092C1DE6F8FA79F87894F79FF010F6CF858B2355423205B4F045829E3A73C4D3A3765840B9ECB30EDA2EA32D78EB776CDCBBE78AAA686F81491CDCDC529C5B5EE34C58B85045126D695B14CCE48D681CD880C00DC648D247AB598143AAFE3729D0673FE236F6451C017AEBD12E9D6AF27050446F649BFB74827F4078BFFEBA0F50860E24290CD2F7699B3B2CF8049A09A27670B94A6DD3E76989D61BA0A5578E7EBABFEC37B2035A1E13D8976803A75845D7248338DA0F05BDF66521A5AC019B476BBDD4917DB03D316664686869BE14EEFC253481CE081ACAEE064D32A626C756184B03FD553D2F4A3AB8680CC711ACFE4676C217831931E6CA8CDC5E657722DEA55D241ED7C4561A2BCDBD8B1F96B7C02CB428CCDEA1D4BC1753BB1CA309E14EED168D3EC503BF0924B389502705750B28C67F4D33C9FC241B1F19A2E5E28779E137DB720D08F46D8A8CFF6883AFC2766902EAB30295D6E5E72626F5374BA988548D88E235F9E60753B84A644748522ECD1F6687F7D53005F1B00C21E2A260C94C31A2276929C09F7CCC98F8B21753D2EC919CC6595F1F5ECD650DD9B08F5417A104146DDDEAB998BFE98C03C0704D7D848FAFB16CD37C2F279BF6EFF901EB33075970E82EAF69D248F530AEDF31C65EC6BA8A3CE3485949AA704FAB1EB7A80D226D7D7AD1CB268CBCBF0B8C8C159799AA6BA7C16269B7E155D3099A22E0E79D72B8DCEE192CC797C2B44E844D52DA58F14BDE34ECD47A26D82D4EF6235AECC91A0A54CB5F69A134B634363C512A947A5FDE905033CE0FD6737D33675FEF37E41AC6CEC5ED3EDA0AAF7EA7DDD2296BB2E6B2CAF7FD881EBD82F15D158B592E1CA88D8245069A572C2EC316FD2C81A5592363098B20B311B091D6BA3369BCD42A2554970E2FD507BF6112EA665C9465860D83E7CCB8AF30113DDB096862F4B7C41DE90E40813EE437DBDD9E16E02BF7E5165BFB4A2BCF4B30C7F5116103A3108C6AB50481367FDECAD41C5CC36A29238DCEF1F8704D4739083CB31125B6F3B432953FBC5746EEABD6D87F6C7E9EABBA665CCDAC07BD0B0D5647D3C64606F972A8953BA29CCD46953BFF31C874780C8578BB43AF68EB817D7AD5ACA65210595BB9CFE237C172F7D60D4279689C8BBB33FCD0962281914BA6CB504B3E44EBBC1D386573F9415A4AA37437B42056AFB14FAF59E113BF5CE15F763BB3CB3C811BBEEE355B1EFD2E5789FC2368549F4AC5CC76864879C3167B98B9B6E9E1E9AD984FCE9E812500BAD2A593DDD121D393A299948A1C9B4661BC187D0FC570F9A2148FB9E1E4E52CE58607AFE2BD7068B46BE109E7744F28FD8B84BA751D8C42AC6F7E262B39DDAEBF2799B02CB70F5A344C58222ACA5115D39C748E8DECF9ADD20505875F742CF627C1BA9277B489DB844AF39FAD2C36C1F0D9580F5C4E49C69F1D6D6D660C0A48D7C7BB03637E8AC52137751B5C5722C7E16235D17AA4D4204AF0312711723441047EB0AC1BD371BFEFB91696858D9970D2943875D9C1BFCEF341E5A82E3209FE4DA9D7532D62CEB8EAB69C85BF0BC3FCB56DE02BF5855E02B93DC6CC301261C8CE5A2C32A67BCD72428AEF6A60637F090E9EF513EC274C73EF9B24EE26A45C714A62CB7E0DFC719B5F3E850F3C93B2A548D8323C4DF42D0FA71678DB8218F432B047BDF3FBAB10E87D1D8FBE1A03D38D7F02462D85EED76183CCF87123D2889DA30EFA44B8AA923FF20D32CF3430AA36B8FAAB290F8AEDC91AC4E93860ADD1FC7DFF64128E6D2B6B46F8E395F7013190CA0B3FC2B73C3C231CD5E731839366767547FDE835E0AE130577783EA9DE94A6D59FA6F972EB2840F4C9E42BDFFB582F339FAA4946958F18D2289AD22457E1E65BAD7A1A496AC4733E1304E374ED803B7DBC41FD68544ABDD343AA678E2222F14E9C8593D5E115A8B3E63A2CB4C27BAAFE7FA1F492574E0671DB20B1204C236AC7CAD1CB19D28D0D59DA53097ADD805EFE164EF1944B9F9DA87A8F201D7EEE9106EC01F0C3330107C7E4AA94FA819282920C95EC1C7CC47D71DB98825EEBCED85F38AFA862B3328656C94EB4402BF2C2DE3270771CA10E8E3235F27360B973D4BE43BB137EB976C464308ABEACF84911F429F60FBB0EC4E45CAD848AEF0C37FBE864276D1D6D6D40B9AE47268D7783FA1E43C830F089F5BDB6DCD2646184C258440989F379C529E7CB374196A7FE8B506243A274A4676121E09CAC23C02DEE82E28000630F4000638758B67361763DB886632BCA33736306E8E45FE7A425037684A4B892AD47B9CF2D9FFC24BDD87BC065009C9820111A738B5A3D60F39CB6017997A1BFFF14C8821AB4D93FAD21CD7703E7D351F06E401588622486561EBF46F528D08BC3505F06E17253961D255097E8186B6D2AA5AB91DFFCA71848DC392899322E85A0170572910BDC564602930A624B92CC2AF6B018B0500D1E59D3564E7F6D768E57B2F37A045109D8DDA77CC2ECBAFB66640E10F878A2D9CD46E70ECA694D863A55BFD98E17FEE4C67C47D68629CEC7CC479E456A63A1D0BD8161A763551455EEFEBA0AF44D1DD72E91631865C47E1A21A40FE7258BE14C5882E9BBC4F7E94FA4F75CB48E17D46DC5959B60BA39FD9540828584FB584E63D31FE3053C4424CA39067FFDBD74564E1ED99CB5A80FC82CEF4B41E4903EDAC1CA44A425CCA32EAC5BB44DB23221B55DE4139C78985A5AE48B1190BDABC4C246050E79E7231EB870BBA0B46D91EFFBDAA18DE21750CF0DE7F8EF748673E594FE065D7774A63F144B890CBF7DC1074FFC4EB376BA416609616F7E451DAC2359848A6CEFA408548823DE096DAA34645B0829020D28D14A6603C29270C3847FA4260D0C869F50E2CDDE8381457C120D467C7B0947A23BB53AE75F8E7C8994E0CB8C3930D341D3B2EA33129EF38A9A66DBD7CEA64FA962072000FEBB631E99DF7DDB10E3A7B4E3D9A25AAB968D7895AB68E6EE1DCA2BC4BE9C241D79F43C5E058E82D491E66CE66159FF3425F7BDA5C9346B0BD668461789AF5DF34909AC97B0353298167F77424CEC9F294098D5C1080AFC4228954D0E835311737C1F0CB9C1537388DC67AEBA6ACC8000D0502CB6A344E86D63FBF0BC7B08AF23B20D609117801F8CD267BCA66B2A34A1F272E4608B107A14F40D0F451915D41B731DFF52A6EEE316144B4D64692C2B68129AA80D60D76262FB0DF23C2E2A10AE2F5322D9DECBFE271D5C4964E84C30B68D4C142E622D571709E83284C8D3CA44D17C86E43787D5C3D5289F239CA39CC20D7E79EB606C89BF46EC1C51059D0C1DC07A509C312BA3FA0D9A2810FBFF38BC8E0778ED342C59B8F45EFD8690D4DD00847295A77EAA820A8CB6EB662C0EA6CD8A05ACBFA89E84FA5AF212A50D6C1804A3859318214082545846D4B76913B5FB92A2073C255F0B142BC899D6F372A83FF6F9C231DD55A2F06EFB7F7921C78997EDFBB04094FB0FEC94F92663FBA4F31C110F8DD0E5393CCBDF6C7360509668733C0A911F61970DD4C4ABFC7222B130FC390C6DB07862F5CF433CA3A5A698B1E03867C66A3024DF797D84DE6C37B8301FBD0C8B0C6BCE504F037167F6526490C1C16174B8173D852327624547BF1AF76FB9111D072BF1338E0A56FB45775FB558D19740E3FC0F8B5BCB50FD8D7592B06FE49B0AF8FDE5C075C840FBC73A29612D398AF1B977E5D91B78B11A81644F0DCD3B85A215EEC03826E58AF9FDB0C2BC3BCB874437B152D2D35A63F875C8B4559E11BD52B89625B72E56BC084FF9E90968BA2158708FD7EC4322F2DF8DFCCFC15DEB6573D28564D25BBBB0A7F46A31D66C941C9E344630445F31E9BAB101920EB3D2FC5D04551758B0E4F5C2725D68B6A89EC02BFC9786AEA5777CF829B4C31D23292CEF6FA2F1B0B8FD908FA842DBCB2A32F418AE27551D68D322A2C16B66E2DA8DAB963C97483945C9665FB996B34689B931D9F6A44670D9CE1C94222AE6F7BF5F2DCD008D8D73622464048D58ED93FFC8E57C1B36C4A92761A7D9634E3F5CB6F305E7A2D103D0D53698D73819FD5BBE2C008CA021843CC27B5049C3ACFB77B653598908F056BE5DBC38FCEE3B21B510B0D3264E9A9CD078553AC6398924DAFF6A1698F92099FE3853FA5A0F86B6F15C32C1C3E45AA5754A3219CD893E51A6409A404163E5BB0EF6BF5EDC9A791E9C4E745A93453E2382A7A6F934CBCF77AD660462263CDED97E143368FF42C97A4E1A340AF7F1C9319462A4ACDE84E6F46A711C967E858B0AA326483625D1FF0B29C1E0BFFA79832BDCDD51C9910CC5E549230196B65598C95CCEBE35FE7582F37A240129B577901BCCF04F7BCBE29D346180A8C0511822FBDD7E1DE9BBCB4BC49C18CB52836F95528B805DE001C13CBE8FF8514E8FB62E39B5AA47A73CC21944359EE4939D33822467EAC6E02AB31167C601BC7ECC04BD00EF78DFA28637990A007B98717E4EEE2FFAA72A1268690765AFC226460E64FFD5863394B5B53A41C9A44FA8F3F59A4B8E1187BC6303655644FE430838873BA34537AE0416A3BF045F521619235F95998344F005518308F847F47917C9D7692911942886F55B8E40AD5A91729B6E96425626F73A98B17BC868D88DD8A52011AB837672A7D9AF06EBD6A9FB3BB60EF8C804609D14EAFD19DBE7E6E59211DE8DAE427B00AA0052CB399967079B7F4A8C0488D2B531DC13B0DA644115808B87980474950679C579D5191B2D2A0B1C0E1CBB4F3925F83C35D208F4F0B288118867DA0A8E7934A072F23B56A795AC4AE9C387BF65C318A469AA6513FF7C1A46FB2B676A1CB61F2CD88F3DA21F16F7321092FA81232291CF7E835F830B33558F3BD025DEF4DBDF626397995447D03CD6B867EFC98BAEF9D5F2C6F66F3FF83CCDABA0A1E45FBE0A3AA87E6C996213A618526BD8539BB4839CDE018FD05F926FADA2B42D2FF0B5E177FC9F8CF07EB8B3A782A448147CC9D527BDA9C964CDF3B9A52A4F0EDA2F6EDC9A0FD1BF05E3A57E65005671D97EB83E2A5AAAFC0485CA844B0A292BA4243CFE20C232A3A6BB0D0E247A9ACFF0A101D5DA9D3E6808D97DBED161F646576BBD12543565C8198E1F7042B3EA4D9F6FB0000000000000000000000000000000000000000000000000000030B0F161B222A313081870241710E6DDF1A34DAAD4DD04826A0EC9CEB9AEC0C6B869DDF65D0B979D4BFB0C711A32918447572802A10CA619FF9AE16DE84E037E0231428E13C8A37C804CD6300AB02420145D39D0E280CA4DB32D616F26DE22F2EE427876448D6177AEEFEE12AC19B354AD81C7D6982503D19CF1D581A46216E85D99146D4AE244C942329F5C5B02117349F +Result = VERIFY_ERROR + diff --git a/test/recipes/30-test_evp_data/evppkey_rsa_common.txt b/test/recipes/30-test_evp_data/evppkey_rsa_common.txt index e97ff64c0954c..0df146becc970 100644 --- a/test/recipes/30-test_evp_data/evppkey_rsa_common.txt +++ b/test/recipes/30-test_evp_data/evppkey_rsa_common.txt @@ -1,5 +1,5 @@ # -# Copyright 2001-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2001-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -966,6 +966,15 @@ Input="0123456789ABCDEF0123456789ABCDEF" Output=4DE433D5844043EF08D354DA03CB29068780D52706D7D1E4D50EFB7D58C9D547D83A747DDD0635A96B28F854E50145518482CB49E963054621B53C60C498D07C16E9C2789C893CF38D4D86900DE71BDE463BD2761D1271E358C7480A1AC0BAB930DDF39602AD1BC165B5D7436B516B7A7858E8EB7AB1C420EEB482F4D207F0E462B1724959320A084E13848D11D10FB593E66BF680BF6D3F345FC3E9C3DE60ABBAC37E1C6EC80A268C8D9FC49626C679097AA690BC1AA662B95EB8DB70390861AA0898229F9349B4B5FDD030D4928C47084708A933144BE23BD3C6E661B85B2C0EF9ED36D498D5B7320E8194D363D4AD478C059BAE804181965E0B81B663158A Result = VERIFY_ERROR +# Invalid numeric salt length string. "1x" reaches the provider verbatim as +# the OSSL_SIGNATURE_PARAM_PSS_SALTLEN UTF8 string and is rejected there, so +# older FIPS providers, which converted it with atoi(), accept it as 1. +FIPSversion = >=4.1.0 +Verify = RSA-2048-PUBLIC +Ctrl = rsa_padding_mode:pss +Ctrl = rsa_pss_saltlen:1x +Result = PKEY_CTRL_ERROR + # Verify using default parameters, explicitly setting parameters Verify = RSA-PSS-DEFAULT Ctrl = rsa_padding_mode:pss diff --git a/test/recipes/30-test_evp_data/evprand.txt b/test/recipes/30-test_evp_data/evprand.txt index 9756859c0e80e..6f12c73c26942 100644 --- a/test/recipes/30-test_evp_data/evprand.txt +++ b/test/recipes/30-test_evp_data/evprand.txt @@ -1,5 +1,5 @@ # -# Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -27,7 +27,6 @@ EntropyPredictionResistanceA.0 = C0535ACD3D715A0B1453AB3447D53D9131C939AEE1D9CA2 EntropyPredictionResistanceB.0 = 9FBC48890273FCAFCA1904B6486D1877CAD91EB601E979259506F93BA462AC17D8676C570B2231D4D98EC617C4826573 Output.0 = 19CED57563D065B606DA27DD5E8DE83B93BB7C8F8B02D0288F475550C3F44B77 - # Test vectors come from: # https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/drbg/drbgtestvectors.zip @@ -3561,6 +3560,7 @@ AdditionalInputA.14 = 84922c0335a0ead609e5a92cfc4a225bd3c7c01ab4580b786338e1caa3 AdditionalInputB.14 = 34b034ca643bbfd2fcc57c9b53e0f9b3fd6a73454f1823dfe7b7076ec73fd956 Output.14 = 6caa4475189ee00ddc54910f8723b0e5b8d3d0c321ce7f2ac7194d134a0a31d96b102dd58e092e08f8a008f05c4f2afb2901c6e29549d3a720aa2b1d1f461bb9 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -3596,6 +3596,7 @@ Output.13 = e2b531ea43c513a1564fa65e9a68d43c875137773102941d0ef544c84e3689b82eac Entropy.14 = 727c0ac75a99bb1a318e4fe2fe0f2e312b3b61d82b2e5071acfb4a36bc8258c1 Output.14 = f595ee1af437fe1bed8d451088b788f1cd599f2b0c47feac1fb5c6efbf7a14a8ab0ea11a3569a3c23b2a9702b415bda355c15afd275c0d67b38bcfb54ab13f70 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -3661,6 +3662,7 @@ AdditionalInputA.14 = 170a92d093d30f939b3eac628a18bab5faf86b3a5d91f30cfd0beafdec AdditionalInputB.14 = fd0349af015037cdbb52983155c89fc59f37d512543559c3ee6589f7b93861f6 Output.14 = 0273a1317f3dd36877a505ca2e440445094d3c702c4ff5f4a07daa3f810d8d7a4f4b9c54dce169a1307fbdc5d197e6a3edc3ea737bedc1c9857aa0e9f87943e2 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -3711,6 +3713,7 @@ Entropy.14 = 22d1d8c8bde76a239d032804717face16d77b51170d0f53ccbcca4eaff4fb315 PersonalisationString.14 = 5d3a7d40fdf95b98454bca03c6fcbf6abf3807de75171b55bab2db5a3f5f12f2 Output.14 = 1007e11f48e3c4813fddd67310db56d67a49fe93e45e61b37ba81485df6a62ee57ca41fa1d987f467c2939790a20421c2b4f70b28fb0b90bbeab1ac0ae884f1a +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -3791,6 +3794,7 @@ AdditionalInputA.14 = 1eed7463c004c94b600245f4967af955919d0f325a2baf2e9c5f6e1504 AdditionalInputB.14 = 6eace0fdabf1bc84d08eaa4afcbebd502f1d83847d2e86a1e68147b3b15a76cf Output.14 = da59c09259ecc1d61e05d3198f349904df1468ffaf85f5d6cc57489e2785e54e710413674bd2ac41896ce9010d9588446e7540b35519c4689a5818ace7dbe0a8 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -3826,6 +3830,7 @@ Output.13 = 78b32d396f5a919f5ccb9be2afaf5f6212d75bf084e99357e28ccc98d433696455b1 Entropy.14 = 42cb183d2a04c89c69efbcec08bee2003b9a1cd56878a774f0162bf70f2c708f Output.14 = cb4afdec033b42949ebbb27245fd33c1503c1278027e11a1f050e04080abe4850821b71ed5a6bd83da6bde8e56c5faed49da26887028bab807d1ad055e2a8a27 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -3891,6 +3896,7 @@ AdditionalInputA.14 = eb2888119b0020cff3ac53cbb81d8576457a863fb087f91c795c297f68 AdditionalInputB.14 = ad80f4ecff758da0a5beed20a9d851fcca2ad4ea0d54af619470e3cf3033a04a Output.14 = e2105e60f2f2fceb27c882caebb0c1eca543c359947c4319c503efa82ed5cb63640f627c82217260f0203220435c842d7993623a2b05e26e1ed1d03f68ab3cb1 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -3941,6 +3947,7 @@ Entropy.14 = 3acd2c23bbae4d02cc9e4bb548e264f43e35764b446595bfe1e45165d42c770a PersonalisationString.14 = afb8203d4f7900c35d7bb454a83c5f2667ab506a68b710011c0be67055dfc3eb Output.14 = 02664c0570c4d3c468d16cc7c8b99da7a7f1752249e30f2833b1b7cd32a4df3c23454621d79119a9aaccc52d3f9055dbde98e773c26d4dace09ce9be1f1f61b2 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -4021,6 +4028,7 @@ AdditionalInputA.14 = f57cf314188b397797caa30733cdabd5ab2a90562cab9be5f812bbd482 AdditionalInputB.14 = 93839acaa271af55ec6c8464ac2ba8bc1c61584008b5d908b200d8048edc0562 Output.14 = 38a3dd584a68bd037c5d5be4a103083e1d4bbd8a845ac1832e4c545e942bb5232ccec9df2abaaf0870d1f75d3bf85aa9323b5eedc26a73ade2ddade69fcaf6d4 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -4056,6 +4064,7 @@ Output.13 = e6e345a50ced3cc68ae24ed9ad8cdb482815284e66f9b0151fdd75d13c9758663c4d Entropy.14 = ab875886827197b784b137726f1f5862c016e2c8780452fe98f4eeb68f71aca5 Output.14 = b6634452661b019afbf2e9b6e20b8be7d9cab739383de8636404c275dc495f54fbf23205dbf843afebbc4e88c6ee126f729cc407ccbbe792e3319230f23023d1 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -4121,6 +4130,7 @@ AdditionalInputA.14 = dacdc1a5c9b4215da6b1520c227724ffc888945a3cf1db2d2ff5c48266 AdditionalInputB.14 = f291eac0295f5e0936542010df7ca9c417cd78f7a109655e9050fd502ad91d4c Output.14 = 70b881acd434f90da8788bfe77226132c8a3f2544293b0ef7408559575ff0e52a17aff11b9601a4765e2ab0cc90f19f69fb4485554ec0b17ceabde960a56655d +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -4171,6 +4181,7 @@ Entropy.14 = 0c4564ba254455b6557aec1cfee2b2b726d2c4f45379267f0e27d11c6f1edc7f PersonalisationString.14 = 46aefb024c6acdc9297d5019109310de558f6afcca730c8414c54f4e574fab1e Output.14 = c94894d56985d73ac516c1249cea3d8e79b67dcdb2bf24b830d52f9e1fbdd8bdb37a546c4ffe13186ceb0a230a14ee1be0e409eb19eef018e54f79c3ddd4fbd4 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -4251,6 +4262,7 @@ AdditionalInputA.14 = 959a1aed8c1b0af637b8c0d0dfd600b0d5dcbcac12bc8cb160a2a0ee7f AdditionalInputB.14 = fdbb472c9f368a44f92bab4bd993c7f39d4e61c6503f69c205191d86bc1b2944 Output.14 = fa2f2a566b99ae810b2b95092da67bb16fa185013ad0c83a845b48cf4fa55f7017ed944d08b57d6813700fb60a30a2a2f976f8b9761516ef137e3e3a078312f9 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -4286,6 +4298,7 @@ Output.13 = 9ab8f2730cd5039a1c78f837ccaf7747b27ca425b07728933e61bc39b5c09fd63a0f Entropy.14 = 397427acb3683af13636a70fa2d9ff5b6d032f9fc6197d62ce1027517cb66268 Output.14 = 2c6b5c5682187740fb566ca60644052b2e0bc3285a399e8127ae53fafa3d5286680416772e552a2cbce4a523f26e7e7e45827a291b61a8b6fc7836e3a14e694a +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -4351,6 +4364,7 @@ AdditionalInputA.14 = 534589895777f502aa3712aeed8013d343a824584774d92f9b0668201d AdditionalInputB.14 = a97742c1e0c816626e67ebc81ba3987378499b75212b194bb56a6746029866b0 Output.14 = 8057f97b49700edc8ebf7bbc798e6eae639a443e4c8e935cd06ebf9e9bdb803cd3121a0602b32f088e7906abaa68b28b942e84bb09d13d565490d20295c520a6 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -4401,6 +4415,7 @@ Entropy.14 = 315bbe530ecfa44eb27250f6d20f4b6c648e42c61f6faed6fe483f26f6f8427f PersonalisationString.14 = efa10fa5bc1e445c031620ebb37e7552c2dfa08307dfe53c1b8e74ec55050356 Output.14 = c592d9e7b67415d09dfc46d3039b3afc1ce66afa98e8793437cfcb5ab3a122c636f0a84edc04099d3819d7fa30d196880d9199de17f7170de725f3650ef34b19 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -4481,6 +4496,7 @@ AdditionalInputA.14 = 36551ef09232d2199547aaefecaaad217443d616433d9d169bd8cd3eae AdditionalInputB.14 = 9e57a4e96ace483dbc3c226d2723c9258063278140d220c4fd023c77fb20b84c Output.14 = ca43dcecdab689549bc4493a38a6a017f6048270e5d70d0d7576a2ab764d922bc346e30f42dc5a73ea6a210d2eba9bee5b5afe3c66867a68ab3fe0d08f511101 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -4516,6 +4532,7 @@ Output.13 = 20d734ab5611a39d6ccaf8941d254804c36ba8bf206bf10d82f721ba9548b9f7cc10 Entropy.14 = 8dc5a9e8e9458f841dae788d24bb5fb192ef1ffaccd991f89f2b5d3ba57c1471612496c7d9cdd174 Output.14 = fd74a7b15c9af2ea140a2d0e353c3387b389144dda5779c69f299917dfb19de6ad60dd440c14c010ca161436243bf9d33a6649339a3543b8e71789621da7ab7b +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -4581,6 +4598,7 @@ AdditionalInputA.14 = 79b75fe104f0d7c86bbe311585198f82350a13c4a7e450cfb86e440c00 AdditionalInputB.14 = 6f20134564e79c7eb530727f5b649996c89d7bd54ebac095c19a162348fce468782f0324f2138c84 Output.14 = d00f784a9613677023d27a4350efc4cc28f95a3928c4c8da67063ee59de5d2da13a3090f580e61fff1af27a8f4ba9418e07d856a996e836a89062064bac7a9cc +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -4631,6 +4649,7 @@ Entropy.14 = 0ac627692b28d31e347179c8ee9e508e2b3ffbedae4009414b3b72e76a3739f0292 PersonalisationString.14 = 946fb7e5c3cbf3d198f19135b1a71a241ee892ac5a0316f57eae7076a4d99bf0e77fe23e81258cca Output.14 = 00007f407f75335a351d31d2754366f8f220ef2f9688a87e9d6aac59fa9f36be824b9bc7409ea991d3e0a7c411854b3701c84abdd7a696406dd13331e2785455 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -4711,6 +4730,7 @@ AdditionalInputA.14 = 1564d70c91a7f72151a4483b9eba35b52c196656ff96875d7c59c6d116 AdditionalInputB.14 = c2731fd38e65f8e724378ad4e01359512cb473dd9854fc2303e61c2d197caad69b12fde14aed66b6 Output.14 = c68d3e5697f36c9db2535b05226aa118e00fdab95ca2cdbd37421298d46d2054e900b82ccb63227a23380e4a2e93327718cca3b9f5fc9c3949adabd723bd4313 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -4746,6 +4766,7 @@ Output.13 = ba6649f527ef2d09cacf926d81abd456d4b43800dbf77de69bb9e2229cb6e3ac29c7 Entropy.14 = 62efa359ebd31d3c499353a5ab5f3b70a34c5f39c508231eae5f3ee20e17834b88fb804a32a268a1 Output.14 = 20dbd757317220a9a5b2394b495efe5e12cc7b759c877bfeed6425cd64146ee90c455c50b2243972b43015f69a015f1a4953e84a089d38171f9a6fd47b8d4870 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -4811,6 +4832,7 @@ AdditionalInputA.14 = 612b0fa86e20fcfaafb14424d1ea3092c9be131efaddff1bd9bf0c9f53 AdditionalInputB.14 = afc244f8c93dd4578bd193226d7ed321f96dfeafe8b491684e53a0fa7d5cfb95dc3cb7739df80279 Output.14 = 64806feb8e212b2b5def3375d83075a0cccecf2a8f0fd38a8ff4700a3152d2044b65e555f5a6171b10d72b6b6139ecd29309dd09e132ae88fa9a6adb500a03db +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -4861,6 +4883,7 @@ Entropy.14 = a59c31d7354eec799ecaba8193466aaa928025b162ff442ad2a4e0f9b65409f105d PersonalisationString.14 = 7b56fc016f55fe0ba21f9cc53b962e215e4ecd3dff487af67b275a19cde4afa74724a747358fd1fb Output.14 = aacfaf0360c415de87b92d74381be991f4a41bdd61175bccdd7c8dd19cd3f7076b485e95b1e9ae60ffb9b778f6470e5fe3a54092c6db3b909a4d9e5a8cb96ef5 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -4941,6 +4964,7 @@ AdditionalInputA.14 = 6cff7528b843b2efb40336bdcaa9629be2720bfa509a330430c36d5935 AdditionalInputB.14 = e0843ca3385ed55f56d51343dd718dbd1a3705d7b8a3a5cb7b955c9070ef1faf74382a9130a6803c Output.14 = 9052a75eb225ac7522cb141245e0592a334cdc8e194f5249a5843e6efb6398db1b8ae97a15829efa4685cb4f1435d022424cc7854d34743bb2d861866fff51c1 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -4976,6 +5000,7 @@ Output.13 = 2cb651524a6b094c93e8d1caf33bef269d267eaae0849c359b52d34640f14ad4a7fe Entropy.14 = 689f2f61670360472b24f8ad360fe08e249b59ec0cc4675b08ac0793dae6956db8f63108574ef0c2 Output.14 = 0897856129a42d785b60d770836a68198bc76e29840abb0802ba9d471acf8b8bff3f02e1a1c34015ad51ce85969b12ea65236bc12d349c03f2031fde19cb22c2 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -5041,6 +5066,7 @@ AdditionalInputA.14 = a0c8fb5bc632cec6f7f7a385587f27ee3ef3dfeb5aa13d978049c3d4a8 AdditionalInputB.14 = d2c1ec49b1b0f810ae9a71fe5d93ffa4004e05cf8ffb1e1eacc146c37b3af5258b4e46222cf33914 Output.14 = f3ef4c192e85dccd2df5b1c5f791daca65363d5f79bd490b7d9232b19c6059aaebc494dea3615295f407aec1af3b867a6d94abdcc41f68d2d9afbee19647f748 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -5091,6 +5117,7 @@ Entropy.14 = 2d0c45bdccac3a972fe401601379d5e5f6173edea823d53186829f343c0d1c843a6 PersonalisationString.14 = 9345dc1ee7c428a961f2b787e6f9487f938062afd5fe3b3ceb04ba8445b1118a8e2e30b3f0bcc299 Output.14 = 3d6f9140fdb46cc1a04ae987dda91a18a7eb59240c6b4292f64c8445f27f1f72a2d80e8463da01409cbf28416986ed8a85e8b9c4caa4541688aede1b6905b384 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -5171,6 +5198,7 @@ AdditionalInputA.14 = 28cb3cecec5705c020d8a3edb8079e004050d480efee70faec7e1b00e2 AdditionalInputB.14 = bf2d138b18cd6f6c698901db8b605b598b0c3ec9fb0b14f9b586b791ab6976717fcdda68e42e083c Output.14 = febe358e4daf7e1938d8c0756ae39531b1bc497e603f91c7aa2203327604144eb442ad2efee1fe9b1bbcf33a5eafa94c3c04d583631b91fe550daf227d5cc05d +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -5206,6 +5234,7 @@ Output.13 = 0ad3c8e5ad0cd1f3308f882f9aa0aa5f290d93b4a2045ceb867991f2640c5276156b Entropy.14 = 1f5f78458959b3cabd57a556a8e70c364bab260ad5572fca41fc2bb64335fb888a31cdb37deef5d1 Output.14 = 0c4436f75415d0eec411f5ba0d96fe333161c2d6faa30f6d806dc457b4123b7b2b65cf7bd8f4e699c563ec0c6f45ee37c31b3c6c11c28927b77d53053b0057a7 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -5271,6 +5300,7 @@ AdditionalInputA.14 = 320c3202d710d62b04bed6cc1d45b6a3fa306522b94cb7037ae7ed6609 AdditionalInputB.14 = bf6b78f3552fab90333117fd2fcfac3af10c5e4dc0dedc581b0b15b6aa579e576fd8b10a099d05e1 Output.14 = e9690cf3a6a69e92e56b8f793c2a27d2ed3c321e61c2e59b99b8aebae74aeb9f810348529386037ff4f1a9f525aff494f8817b087d67817c9a7547e56109224a +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -5321,6 +5351,7 @@ Entropy.14 = cf9477ba033c5d2324dd97b69cfe59d66ae7f7327aa928ed1ad36c2d9d63be731ff PersonalisationString.14 = 215a3e638fa6a74d91592b07fa08f8d4983c6ad0820a908ba735ac5bcee68c3f670f6fcf4d05b25c Output.14 = acade190508f25724a3c7dd4d960bee088cb6152f31a537295a8ff4b85af94a0ff006be9ce2f541b8237f6a7fc62a4bb8e41ac6979a6f112b57158aa6eca347f +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -5401,6 +5432,7 @@ AdditionalInputA.14 = 8b981ec9ca88b1493e7ff3b90c02da6f478bfa573f5a0354941dfedb86 AdditionalInputB.14 = 829e75a58edd00d86269ef332e6744723b289f7df8f1c0bbf70222b542b9014e2d0cdd6aaec8c194 Output.14 = 8c4aa794af3d7d4d684006808c98c11d8146b11fd062c69cac019f1913c457b49d423b5ec683f19143eab372079a6df551fc686d9d6f9ce5f64ef619186f816b +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -5436,6 +5468,7 @@ Output.13 = a0ea3af0cc95103ba3e89e5e4a6b792bfb19eef9580255ed76e71ed0e5325848497d Entropy.14 = b7f7e4e68356b2ac2c2c0075c0ef5ec6f5a6f225a18db00830261a95765771eba739a7cf8a1126c58994c43b2d28024a Output.14 = a15e8cc437a600a51dcfb778afa23d577d0e56b004f56eeb286e6c949d982bdb9353cbc63d33d7d397ceb4fea51a6df0b4d6d4cd32b9065bc4110d790c610e44 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -5501,6 +5534,7 @@ AdditionalInputA.14 = 67cd37e14222e5966d243bb44aabb32b0750220f75546953981631b948 AdditionalInputB.14 = 1c0f67ce459099f3993bc8ee4a4550d3e7dec1a5225280ecdb00ac68e17c7cf40afc5e6794208e5742c0012e87d5711c Output.14 = 26167ff9820aa23ab61f7872e007dd25d58c7f82eacb9474280731a550c8b899e08074d910d576939f87e90018987e0bff48da03aaabaa9b7faeaddd65fdf5e2 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -5551,6 +5585,7 @@ Entropy.14 = 4e37ee8649a86dd0bab8785a1e3acbd2c3a57ca346d0e31476490e49b588b928232 PersonalisationString.14 = 61334cdc8735332925221a6318987403a4c1c936c0a8066cbfbb1a84510bac2bb37ea52d6ba9f4e1a93269473f4566cb Output.14 = 8bf9c263c12a19c50525fb70cfe56980b26957e5c295f7546244ce6b7b1b90b24ce3cffc5536e96d973b192a77f878eb5e6987e1055475a0abd00312d7a65dd3 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -5631,6 +5666,7 @@ AdditionalInputA.14 = 781c2441577ac05fc069f0f988e150d7e983bbb49810eeac8b5d98fc5d AdditionalInputB.14 = 7598eabea8e516eb2d111441e94a98bb37916f291e3107dd991e7798ed896dc99b1a405443f7c781b98adc8ba9750696 Output.14 = eae935bf9ea3174c0d7da0359c175cc6bbb91ecf9357e7748011fba02fd52205df0a87a44eb4ccb6015b266ed3bb9be4d0d403838bacd42757cd34216d71989f +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -5666,6 +5702,7 @@ Output.13 = d39cb66ae64219a8de99b4f63daa8536defeaa53a055a66ec3de18c41673fc926b1a Entropy.14 = 100e176574bd55438477f0153ed04b6cf221bf6c1fcd7141aba10c80d71eb2e16bc8213aed689f44ef57807334dc3d12 Output.14 = b4315cc4470d4c50a15836f218b21c96668d32eafc1649cf6c92b96f0716aa54582a31a1c5f597b80f62102622369e422d98c34d1498cb9bc01d418a4d232074 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -5731,6 +5768,7 @@ AdditionalInputA.14 = cd4cb3a8e0f1f8a67577d71339e6c4f40a291cdd22d5a19aafe0f7c99e AdditionalInputB.14 = 0203e75cce2d2e81ec441ba73b3129c6ae5067733bc0031614cbc8fc92d599523ad30da2ea253c06c48293befb14ab71 Output.14 = 927c1e64d9f3acfdd74e7afeb9ab2280f37ce9c1839f8cec8c32db7676fab057620144d34c8382bcb904e85af45d348e10bb2e5708268343595ffc08dd258c00 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -5781,6 +5819,7 @@ Entropy.14 = 4e6768b663b1838fbd56c78b002c08c28121662238456ea93c4b286f4a1d6aa2a1f PersonalisationString.14 = 47c24038732c32baf7e1e71fb0b74b74ec055adb88f8cf111fc27598ea74872fde608266a8f49105282c2ca7093acea2 Output.14 = b1ce96d86e77a251c4fffe5de31e9199a19fa242b03b005cf0b6a23ea3a0c5b87edcbc77d0019f24d8c0594a4edba054b32d2c9e5e2f0893c424b11887b0be48 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -5861,6 +5900,7 @@ AdditionalInputA.14 = 0e2ec484d8866adc065b4f11d3760b4d276e2cf9c066b226311e7c7806 AdditionalInputB.14 = 9fdfcb7460ce5b9913ffb9889696df7abe28aad40eba3b675d7508cca1c98faaa27dd5f52997dd6f251a68e86f966fb1 Output.14 = 66d6b1693a3ca1cb6169858390741bae3285e0c28604d064b57f3aa2ef9a569bec22884ccc5cd315d3f3847c680c3481bcae423cb105ea47956f62cf8c2c5d29 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -5896,6 +5936,7 @@ Output.13 = 47b6dc1f9fc7ba68973e15b489e46b94b4ba58e23d6691a6e8311dd82a6187252e10 Entropy.14 = 80ffeccaddab35221cba00ff374728dab8f91f3e5498622704c050e3e13a2b0bdd2f913672e896a979974c52067e2a05 Output.14 = 0292bdaf725f469307e76e3ef5bed03470f6bdfc22e4d7f0661bd1b87696c9da201bbbdca6a22344ea88ffc7325370863b4cfb105740165eaed9c6e73b06a4e8 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -5961,6 +6002,7 @@ AdditionalInputA.14 = 8ca625e0daf65ecb70ccc63bbe88720ece7a415b12542c59db488bd056 AdditionalInputB.14 = e511e77b98df72d3e4c175b58b7182fa729a61649659ff117d9b4c514cf694fea2731b170d0babbf6b6bf8198be6d932 Output.14 = d9d3ac1480323439e9f8f09a54b3668684890fad51ad314c8e14bf0fdb429738b8955e3d2d928f2403f20caca2065795c0adaa30a5c4683a08d83074633be8f2 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -6011,6 +6053,7 @@ Entropy.14 = 409bc372b8738c80ac35721bbb8e806ddc93e816c8fab98d1d0f2a053f959601667 PersonalisationString.14 = 975da7439df9a5b76f8ae5201da35692fd46d277787f8a73b08201e6547ba72de26ba7725ad44a11f742e6c2b57c0e9f Output.14 = 01fe7c18b85ede519740ed4068af24b4baaaa7d727b05241af481ec843c20bfce41e4bb131cf03a504aecd5409d03f6b5b84d22f0e1042b66e5d99d4339742fd +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -6091,6 +6134,7 @@ AdditionalInputA.14 = b0bf3ae2cfe4d3fae5573781456b3725a59598d52ffdd081b412106481 AdditionalInputB.14 = b94a9134257079c16192066b6e3e50d63d58dec6632524114e6bce3415db5abfe0c89108cf2fd6478a97079f5190f1c5 Output.14 = ac7c1a00228f6a7a0620d00dca7dd38e53c71d31aace470703e4d8911b071b5ae517af60ff9f2aa570b18d35b2dcf8af0ee14ba646f2be35571c7cec44ec88d4 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -6126,6 +6170,7 @@ Output.13 = dbeb1de34b0e6f1c96cf4afd1e1230e434bcb1a5497f797871e16aa3f60f8dbcb4b3 Entropy.14 = c1fdb2167e6db331a3e796c83c8b10352650c20cdcc41b859f8b0059f2638bdceca6120928c3311b6b8d764a67b47192 Output.14 = b9ec753ca46bdc1058f5b77a9d1d9d7090d0b70f8b9995658b8d5abcb68462a09c59cf404bc4a625037b52ba10e336c2bbd049a507fdb95e32d09904a2482f97 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -6191,6 +6236,7 @@ AdditionalInputA.14 = c839973b79c3eea5db7107ca7cae1c012cdd59a50e58b7461ed7921178 AdditionalInputB.14 = 3cde5a2f6e19fb4a4493830016cd86afcb7a8db49a2abf6077ebb5314dd12a2d1fe9d3601c125c41c3e9af4603ee8f8b Output.14 = e61a4d439b4bb1ccdc810ef7a0019e5e88321ab6687f6564d5f70c0afb1633d50da63d6d1b1919b724b57ee926d63a80ac20f1ff06c4932456c70e8b64db43f8 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -6241,6 +6287,7 @@ Entropy.14 = 7ce9977cb80634f0503deee2afb8230c57408c83bf5bf41d2d62d4daa4c492fa60b PersonalisationString.14 = d862039cc2c297d63529a33f38a6e5660a06919a044c7e746ff238b65321d2a233a9a9c7b3534c932a8881ad38d31f65 Output.14 = f17b61f1c3caae331160b714504b9c058ac345f07a5a26034dbfd7fef5013b52cae3e2cd357095b623065ec5cb557001887b17f9b6f9476d5449ac7d81d5abd3 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -27303,6 +27350,7 @@ AdditionalInputA.14 = 639824768081b8f8d09b9b4eb51c0bd1ea5666067ade2628d45e727213 AdditionalInputB.14 = 7492ada1c96f7b2de329cd54651bde17b4fc69471280931180bbdecaa2889435 Output.14 = 5c37c829eee0a9acf2ec0af816c7974a09994e744c070f58d4fcc216491a35be0d32854cc4bf6956ea5c43370c02084dd30a66fda089f5c47b4975d59a01a022 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -27353,6 +27401,7 @@ Entropy.14 = 8ecdbf1cba26eae45f70ccfec0e42d6139be57f131ff60898a3b63968acf28ac ReseedEntropy.14 = 8d860dcf67fbee47f33ed5273ff81956335d9152085f184f8427ad4234f95661 Output.14 = 8049f3fe2e62883f71cc43873b9775bf60a97c070370f9757c51488b050c00959d085ddd8f8e3702aa4cd6ff19b6c62685afb7792eb003c07bbcc9f4a026d138 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -27448,6 +27497,7 @@ AdditionalInputA.14 = 9e0abd6fee611320de52bc48e56f5f17bf180e596d258031e3666066bc AdditionalInputB.14 = 5612694e4260dc91ba87ee97656f1436cec1f711536bdbf61064026673bb398b Output.14 = 02bb0c1e3abb2993383cc9cf2f32c148d785dde27df3a8dbd3ecc73ea4e884cd427061423e0736a95dd3202e6336cfac40311b8f08aaa88a90baa2f93999694b +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -27513,6 +27563,7 @@ PersonalisationString.14 = 48882b0a263582f0c6bb8288ba894d7141e665aa0c084c7d99eaa ReseedEntropy.14 = 34cc10a3d71398efec3c5854ef82a77a0b6bfcaf841ad9a1d5c7bf05aeed9082 Output.14 = cac26b07204eea9a41e4289302d0da8f36ea200dacd2435f1bb1c1235cb362497eeb87aea2889aa1093d13d2cee25eb11e28229c39acdf894122425b5948cae2 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -27623,6 +27674,7 @@ AdditionalInputA.14 = 1550ac6da1742834c705b4dad61c37fc33e7d786f76b553ab324bf543f AdditionalInputB.14 = 77ef7c3f819de78c243351a71bbb460936064738fcb75acfc214c884ff172311 Output.14 = 1030bfc7cc645d6e2d6b2a3f2e97979ab999d70252c15504d71d02c5842c34cf63b94c512e162726acfb1492ccb525ea56e4ca1b54daaac2284e558cb4936931 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -27673,6 +27725,7 @@ Entropy.14 = ac5668ac054f732d2bcd88561642c5a7ca98c68e341cf0cf18873fea93ef33fe ReseedEntropy.14 = 4a4d088beb9843e4622cdb0c5a6851587f2b472dc5d734211409bacec7b2ac06 Output.14 = b2013a363f3ee01ab8573f3e3eed32285108c3ed3bf231c066176ed901e4d6ffaaf0cfd12d63d7c19f6c460baf434a1d6a552c62274bcb7469f7009c0beab972 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -27768,6 +27821,7 @@ AdditionalInputA.14 = cc92f09a3b12f29d9e73253c261e828196fa540a9024632665c6c25a41 AdditionalInputB.14 = 53113703a3362b3eefb0c12587fa25a620e09e0cb63acb3f7b74471618cc0d05 Output.14 = eef4850d91b63508bdf3257c4b66c8c022a6869cc8d9473e5f579d103c67225c04e3994f14c31ff0e328c1adddc8d8f6b1f2e70409325a353eec19c420352b7c +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -27833,6 +27887,7 @@ PersonalisationString.14 = a48f64c672f37649b12630157e15b9364ee7548984d94171b2a29 ReseedEntropy.14 = c4933f8a2af99389732cbd0120b697b9ad99e4821f4610b66c18d9da0e28bd00 Output.14 = 77dc9c1b636acd5b76a3453b168479ce947f4fc1401ccad4dc61d4630370ce21d29017244cee50644e3654e702b623e20ff49861890781a6bdb68e5cf3a7216b +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -27943,6 +27998,7 @@ AdditionalInputA.14 = 2537ee73b566f7febc51963ea96691994fdb150d42db58204f95be45b4 AdditionalInputB.14 = 2f4dd1698f26af2a921d4f4aceda1c15ac71fff62ff7bb5ea6a993a29a8dc199 Output.14 = f1b46b0276bbd75eec0792e9998ce83022c8ff2f00ee9947760c6b2bed3f6a19bff58a0a92093a57b5ac949cc4028fe31e2a6262125994e6e30dbb4b7faa6d4a +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -27993,6 +28049,7 @@ Entropy.14 = d083e222d8159740044707c76bd9ec4436202ac778f63646e5b1e88f21ddc13f ReseedEntropy.14 = b7b714550798c888a5026b0b7801c0923ae60a2858cabb6d6972d66115f40eda Output.14 = 227a88583bb137f082967af04c27cb464a6332720b759b435d4a7e26349f56f4bb447695c06295e838a6c86fc3867006217c94bb5cc99b3c44bfe541fc77503c +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -28088,6 +28145,7 @@ AdditionalInputA.14 = ee0d3e9c178d53f9957ec0877ac719694197e8bdffedf8fe59c57a0cf6 AdditionalInputB.14 = 2545d30f8b974a21fa54146a14a566bc0156a015bdde60f3f2b9e186f6181f5d Output.14 = 7cd2003034f235e209cb0d73ab442234016a04c830752721998146c2f6f27d92300b47fa3ee72b46378092feb175583894b6f7004362f724ef145fe03c941d42 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -28153,6 +28211,7 @@ PersonalisationString.14 = 41b9b8e2d9a7945ffcf2631bf7d668648993c0f4859ea22de4279 ReseedEntropy.14 = cecd9d0ac5cb7ea4cda4566b873bcefc2db068ee41774a6861a21bc69cbe1814 Output.14 = 9d7209b625d5df31a949fbf15bf6e4515e42e6eb03909dd6d7ff4e001a8408c704901ca2b2121c079e36c28aed7a786aa356b6f3c75b87d4c78a2d06371de356 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -28263,6 +28322,7 @@ AdditionalInputA.14 = adc0707f3a06e767ea80f0882ebc015b79f0228547d22eb5a635b244a7 AdditionalInputB.14 = 8372a1277f0eb84cadd53df4a6cc619cfca029f84d9bea48beca8cc8060528cc Output.14 = 86cde22dae3a1af947d76cd15e4df0c83a11769d34610d1991945350acd4f0aaef9ef70b5bbd57fab74fac6be8cbc028b9bab63aa5de62d9f1f95d949e9d093e +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -28313,6 +28373,7 @@ Entropy.14 = e3d8fcb8c049e442d2bd07104c46f0602a1f60f87bdc02dbecdcfcf4006b5b0a ReseedEntropy.14 = e25327867ff27456eff9f4ae4375c7a85788b400dcae03ae8c892472c8a05221 Output.14 = 754063c679269931fdab8f90deaa967969f20b1805d93fe5b1928512cd2fe98984974b0bb1d7494d81f53e073f1a3a9378ea27307a154dc8a1fb1d3e17998f85 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -28408,6 +28469,7 @@ AdditionalInputA.14 = ff296cd83f439529d436254c490013f26fac4ab407e158a06b3c9d4e9e AdditionalInputB.14 = 63dee758f80f00738dee68e5f8a361cbbb371bcfa1b67ffb073c45e3c84b85fb Output.14 = 295446b08f879c3e46f0c57dac85767d94805fcdf7beb1eee75d40f643254691adef0e8300cf27deb90a72805cce91a4433d263ecacee0583b222b81c0bbe401 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -28473,6 +28535,7 @@ PersonalisationString.14 = 345b74cf00947dc1eedbbacd5e4030d5639f5e3c0b9fb986fdc0c ReseedEntropy.14 = 3150b6ab1fb005ceb8323c6982fc3af3092077241dcf4993fe91696bd5b8b747 Output.14 = bff83f45e0a4223489b08409497471427e7b82f834082137497bc552127446a8a3f52a730914650cd753098162f7d253bbd625983430d1f16fcdb0f78a1348a8 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 0 @@ -28583,6 +28646,7 @@ AdditionalInputA.14 = b643013474a37b208a6f6c44cc56b1caea69e1289d8897d53f40423d9a AdditionalInputB.14 = b1e07a0f9740c49335ab5244e3b7aa567c7234e01253fa1c31372ac43b1d6519 Output.14 = 6e5fb213d4bef40b3f274f956960a1e0d28e5399bfcf2709fe98de2b54ff26766835b6ed538b887cc617529d057f6005db0227dae7627728504cb8cf3530eb2e +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -28633,6 +28697,7 @@ Entropy.14 = ac8e24b8704e2011076ff9175fa1c12d9beeed66c9a975037ef6f1f519efa2230ca ReseedEntropy.14 = cbe05b235ab45735f0fa0ed945ec38ec3801f2caed0bd8f96dfb34cc75ef1a6a4122f5a8305f915e Output.14 = 91c49803af71477a06a6a493b75aa36817aa15b58afe7598750b2fe4d663f05ecf0b8c1b5737cd611e2d56ce95a029bc4fbc307f5478f0b796b259e01a48920b +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -28728,6 +28793,7 @@ AdditionalInputA.14 = a491fa45d161efa71ccdb405d6ef3153700b28966582e1052cea992218 AdditionalInputB.14 = 4a0cd52d005056df60803fb353728f3b3fd27964e5c96965ac472ff8bb4dedc4dd7d1ca04b124f0a Output.14 = 0f78e45be38a6a46c2914449beb9df52394067b720f390225f930c3313916f00293c7f7f173cd89d2c30c72bc07482f066708bda7a29af420490821c98c995f4 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -28793,6 +28859,7 @@ PersonalisationString.14 = a35f706fe78dab179bdb83495408764805175744bc020388a8a60 ReseedEntropy.14 = 4d632ef30482e6d5949cf52407d42caea7cd745e70d76d3449852a7ddb3f92e19840cd0217e1112f Output.14 = 3340cd5e74c52918b391156702851b25327072f075e16b8c9378972b081b2ca8cfa7665b7052cc44f480f0c188342357cc6c8cb616a0dadefc4e1ed40ba42b0a +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -28903,6 +28970,7 @@ AdditionalInputA.14 = 5f7205d87d0a9868234eeb8c4ae42cd47c03983b77dfaa84637b4080df AdditionalInputB.14 = fb6d486fd7586036003ffce8865e479498fe530f9ae29e01f98d4a2f7b665b6a9329450b0fb6ffb1 Output.14 = 0d3d8c9ff86fb56bf362787f474f838066fa7483a958c23f752be6e21cb42fee11d8dc53396508f9fd5122d04e41d0e0c949d50c46d51d0ac824b6f46b5df088 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -28953,6 +29021,7 @@ Entropy.14 = 0e681f881afa243f5de75a046205f733a32a1bb39e2abd057c07d8d5e81589d537e ReseedEntropy.14 = cb16a4907b39f647eec2b388704d6a2b89836cdd8d1c0c7ff27cddbbb0d01e306dbd01ec58334700 Output.14 = e48aab2c01335ba4f6d377c3c993932d4fe2ef60254eff315491b81acd1c22b3a33c59b8b78c479b7cd4fdd31f7d15864a48ac706e32174de36f9239aba4b6ad +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -29048,6 +29117,7 @@ AdditionalInputA.14 = 37ab678301ab45deca791b4c5b1a792c5422f2e3be57bcf77d92468e25 AdditionalInputB.14 = cb7a6611c7fd8ffb884ab41766bf4a57878f187dbb09d7b0e77db4ed2ccfbcf3c640a9348dec4e1f Output.14 = b194fd786cfab66885cfe7b03daf642dc60efd7399f6c48d3df50337b40c40349b94ca509053451c34d6b838ce1905b5cddbcf5df1be2a9783404bd0b72b523d +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -29113,6 +29183,7 @@ PersonalisationString.14 = 003b5e534bb565f4e1eacb22f2a2a65093dd0c782a27805f0c4c4 ReseedEntropy.14 = f2c16713da96ef435d96c63fbbc57d49c44d99c679c1af53a12cadea98d31981a7d06991efeec73f Output.14 = 67c409157d60f8703da237c4c8b4f124298bc95f68cd5510304c2167145fb7c4beeadbc6d7ff9b261b420e93cf9fb135d9946d5f4c4829557e7dcd713143115b +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -29223,6 +29294,7 @@ AdditionalInputA.14 = 6f6d6ab0d0c02ecfbaa3ba6d8f38a8acb08699d08f3035ce7fd03343b7 AdditionalInputB.14 = fba0d6f6ca8f1a587782c5319766209059a23cb3e7476b2d060ad06f2db9e09728cdbe0f8a86c14c Output.14 = 9e88544b8486d3445c0bf47d0f55bb8d3f2abf5d5b2816df7abcf3f419dc37ca332bc00fb8c40152750b4c46054e8a281190f6e3007b844c63f6cbd1dd9acb01 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -29273,6 +29345,7 @@ Entropy.14 = 8f5235da708cb15781db85ddc141eacc654d93f8c211ae718df22ed7bae7ba5f2d5 ReseedEntropy.14 = e6cf01b0cf9931ded0ae50bd0e1092cf79221397f2850d31390db33ae05072ad0e67cde6f3c438ba Output.14 = 7a00675e1a9b524dadc1b356b22c46c6747147ed736639739bbf761ed9b917670238ec001387b7cf3c91a58a81ec09c1487313058b6c26ce61d5785269a1d8e3 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -29368,6 +29441,7 @@ AdditionalInputA.14 = 18a09894ed824809e66ee447f9413505035c8e85db5b9c6e597bf6a2e3 AdditionalInputB.14 = 75ec329e54639306dc853b73498dbc002abceadb355e12ae69fea16cc3ae892272544990d2938be9 Output.14 = 4c08126a7fe978f25982672ee2044a9dfe31919a2003853a74d9132b46a2278547af5980d037401275ff86528bff41fa80180e823bb88cda6029e06d2b009e81 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -29433,6 +29507,7 @@ PersonalisationString.14 = d811d476960f2d5032cc3fb7002be155c6314e03ae7788dc886d0 ReseedEntropy.14 = 8fad4aec11507a394be8bf8cf24c4f2442c45948b5ddf28ebe33f9643ae5d21337ec8dedc9b23e1a Output.14 = 6d353a66b4cd16ffc5469b1c16951ba00b075db4f1282df1cba7267b9e191e21f604dda9eb48921f927f1d7b4548d5bcc580829c422ef0d5b2127d5eff4b020c +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -29543,6 +29618,7 @@ AdditionalInputA.14 = eb4fa0ae2bd5ff9ab19545d30350fab09719db12f428ccc3fea36da4a0 AdditionalInputB.14 = f1d0853fc6fecca6730079b5e64840bdcbc2ccf4a9e20aa08e8ee2e48c785838b154c66845e2423b Output.14 = a29949eb92716b0682cd27f62ca00cfbad717fc976c55dddd854ded44a53ea2cd0dc0a97db8b6011d583f8fcb522b7f8c3d2fdd68ebdc083e23d5f5737dfb572 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -29593,6 +29669,7 @@ Entropy.14 = 963fe575c96b319a3418cc7548484ab827df1f7ba56b0da8131fd19f7712add1d29 ReseedEntropy.14 = e1470ee367e55bd8dd82dea6f7fbd905b98d596306807f8aae529807b36aa0655bd260e1e2bab75c Output.14 = a1e6286529fab40e3db9b57741bf6e5b4904590d05569a7d571baf77842065be742e2c26c14e8599e46a520fa39b81ebe32dd857556d9f55e4bd37c1952afc0d +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -29688,6 +29765,7 @@ AdditionalInputA.14 = bf76973791b52d9387e2a36f3ab3620bb983dcd2399fef3cc6bf4cf86c AdditionalInputB.14 = 2089acf7aca43a77d8459d4f384919575ed88c7c4759b9dd7033a132a85c2ec6c71025c166083bc7 Output.14 = 81309a10ac3f02d3fee049a5ddb9f02f64dff3d6b75259d561921a8349b30054059b2af81c6f7d50189a0bb6d360da06bcbdc944997d6f8b051f23998c8c36ae +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -29753,6 +29831,7 @@ PersonalisationString.14 = a477a42a221cd2cbcf790ca70fb6a5f18a91c297617561acd1bc5 ReseedEntropy.14 = 108f6f37621ace418e2155f70dda4c2b5d6aafa9269f6aa98a5455e3a1d188e64ec022c454c68620 Output.14 = 05e4896494b02861a51357463f705e812a14f57eb8630cf1fb025c42ec9dd54de3f5fa1b38d1f3d890aad74d5ad1683d0b5981da4d3a939d05fd5435b1d50f38 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 0 @@ -29863,6 +29942,7 @@ AdditionalInputA.14 = 6aec5f8c3dc54924104e04635ab80b1f782869bc5c1557f7d89daa1e1b AdditionalInputB.14 = 668d732a98f7ae8cdc9235d63e705955c09600a490021a19a34c1befba8cb613ee7d8e4c5774aba4 Output.14 = 1dfb0a6bf411580aa55044f26c598d2620965fc94a769001f10b1909228616146bc9d02f749d094786805e3db859da9e6a572833af5cefdb147873ec6023b028 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -29913,6 +29993,7 @@ Entropy.14 = 1accff5a19861164c5d2cf542cf41a789f143c7956518ae158d4449ff0c257a0096 ReseedEntropy.14 = f2fa58209759d84bf38a1656bae655669767a902ade22a830df56b32ef9e1c992335eb4cb27eeb142bfd21b5d31451de Output.14 = f214b4055d182cb258d9e9b61251bebc9bf090db662c4e36023cc156964fbbe1cedf691cd0c3d7db4262fb65a5d34b942f909b0f31fc18009766413523dcaf40 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -30008,6 +30089,7 @@ AdditionalInputA.14 = e33d181f3159fb0874eff5ef8ddd2b51a60b13ccf046f7e637ed27bed8 AdditionalInputB.14 = 3ecf6233820e6cceddac7b024c490c5ee14c73d5b598c92cda30940471b6ed450019120689aaf157fd87b71b13afea25 Output.14 = 9d793dd96b870dfa0267623bd1c2d8bd3e2c63e9f211340f630fea01358011394154145a10659c4d98274a525c48a90da0126a99b85ed5b4b903195f0dddc762 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -30073,6 +30155,7 @@ PersonalisationString.14 = 8c40c5317f29b64da7f4025cda90ae3e99ba1ed350482048f8411 ReseedEntropy.14 = cb7933c3c803644d4ab7c35b941319bebf6784f98c04754c69359e10c9693b57ae12e38b08ca8a9f0f15142c4476f0bc Output.14 = e95d375c7b3354190721d598e8fde7aef16fb2a9dc963ed76eef6a12abe2001622725a8e1545c73c9a85995e6b07806e2ac39b179b595bcfd96b2189b5d10497 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -30183,6 +30266,7 @@ AdditionalInputA.14 = 588eb722d4066ce1e9148d2e7a6d43d1d8b4886bd97f36f24599dcdedb AdditionalInputB.14 = 1b4e904a6b861201028506075d7d7fecb81158ea3749421d4d4710ba0fcb157b5019dbca199c8302d34745cb0c2330b1 Output.14 = d155941b54ab48dc1866641c034b117d6dd8a7d068d29201105d845315dbc747afd8fb1f9ba5c976c75ff8c7052aff7b342c1489bc0c9f8a7d898b88ed0d5746 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -30233,6 +30317,7 @@ Entropy.14 = 68e91e73623fa6a3ce22f424e9db971459dfbe06601ccff96f1726fa18e61d5cdc1 ReseedEntropy.14 = 249b56dcdc4c5c8eaf796c8685a740fd4ea2455c135e0d7b8e50532fd87c95b781c8f3775c213c2714eecef140125b78 Output.14 = a15d3d61408ddea3b9753c854c693ca1a91cf49d172160bf15f512f345bb1bda9aa7bc4fcce177fdfebb3fea4cc6404c6024527ea662669a5eb78753822bfdd3 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -30328,6 +30413,7 @@ AdditionalInputA.14 = ed3f47e59a12b36a42616b338c7a77a18e333d38abb9da4e36914b69f3 AdditionalInputB.14 = 6e39b249f1b8111ff12fa24f9f2320df2dc8752e1541f556b5cedfff409b6a858490c27e052a63504c7131b438f44356 Output.14 = 650bee69393d5d7793c8a5a40cae79bd470d15fdacab7b51b251f51dc5d3e383d28d808c7f9e018c71eccc80371a9e0267ba4053ec0e4c071d110942c43149c0 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -30393,6 +30479,7 @@ PersonalisationString.14 = 531b64be5d25937f30bed886f2021855db1b63777febe6695eb4f ReseedEntropy.14 = 350112071b8315afa26fa3d9be6b6dec59ba7fed2387556cdec43ab8def92050d2f0fd34ef0c837c022c337f227b2169 Output.14 = 47ad3d7ef4e7bc4696d039b6e424669200b5f6c687f813c270483793518adf6698aa40a781208878017bf77afeb2f98794d21578623888eb98135ef0e5121c57 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -30503,6 +30590,7 @@ AdditionalInputA.14 = 02a4bfd4a825e4d811770127c6f5a568deff4d7989300a0bd23220a586 AdditionalInputB.14 = f9775f8fb1b767c4639e2c3fe9f0820e03e28780641ecbf832451baea5e1ef83cf9e078cc325b1fc7a8a14bf07cc4ff5 Output.14 = ba473979f23358b95ff49610a7b91936b7d1da44bf8891cc19ac6ceb9f0241a8c3771a2efb403275bf599aad30b9e4604e90729241763801387ab239ae543625 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -30553,6 +30641,7 @@ Entropy.14 = e23a7f95c3cf3fddddec66cb16e1fbc38495ebe98b3e14d8f351e58bc457cd38b79 ReseedEntropy.14 = 36410abe456d7a51948098897ec205f75f22ee09cfcc94ca88fbaff8d159fc779a8e420d11fc1ac09518237bfdb74462 Output.14 = 3c14a63a9c74dd02051c0147637401649a68452c28af90e9628f1ac87df1d27671397ba34f493997ef634284b74b3b28b2e7d4171eb025e470f39dfd12636a5f +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -30648,6 +30737,7 @@ AdditionalInputA.14 = aff406d3d514ec118c9a8f470db34922b8bb262f78c1ee6ecbc647eaa2 AdditionalInputB.14 = 50d8e7887df0785c331a381b6f11057ed720abaece80b7f8358386fabf5da24a912b8f1563301fbcd7ad240c03a5e444 Output.14 = be0045c0bee70daf5a57e5b449fde2e9320a0e0d429950ec3b8ec14ca2acdd7ca2a365bebf11f45f356c34f7e52a8c39ac2e141815134bab3b79ce3dc1d2a44f +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -30713,6 +30803,7 @@ PersonalisationString.14 = cfbbe01cda290c89b2841f37952cfc1d9a4222fb425e9453de307 ReseedEntropy.14 = dc9c22b1006462af08615eca5998ea81a81411be226a241c38d480e7ae0ab5bb34721f0ab9226633d655675ffd953420 Output.14 = e544668dbca5b35bb59ab04945649cead8d822a1d8ce125e3ae5db8b23e3bcc05bf6921ce95b85766b92c13c59ae83d908471e03e020fdeb59e5cea817a48802 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -30823,6 +30914,7 @@ AdditionalInputA.14 = bd203cdd94307bab1a53734a3a451f0b038614892186b26877b2c1c849 AdditionalInputB.14 = 631cf0317b713d07ce74f7b05ff4e7a158c769993d357325f8e9d16b25076bc9b0febbbd66bf23fbc9c27286dc1663e7 Output.14 = 401176185d33ef08d0b65a5b853d57583250dd2efaf44ca0f987b45f89eafeb52d2f4346bf9b9d0b7dd4f7126e7d89dd32f53b737cef79ab5dd0794fb8a4c89d +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -30873,6 +30965,7 @@ Entropy.14 = 91fa80b727040295b850119e9fb7e4cce4551ae234f29616af15572557d1555de04 ReseedEntropy.14 = 9937f776ddae1dd4a6ed76cc1795d450e14d1e462c30a9e1a85334b3ca148451b94e00055b3ed227f0a2fc247db4db6d Output.14 = e659a7de7a1b1b15a56170a1d6334dec91b6fffc47fb7ae1f2b3af03cbc25f7bec0cb6afadb76af9d36216825ee0e13aa3915bc515325c27270858654175a81d +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -30968,6 +31061,7 @@ AdditionalInputA.14 = 54dd28543c859fd4dc1e4f0a44ec9aa2b758d51379c0a9c75805356793 AdditionalInputB.14 = 3803a58e41fb766847b9f568ecd7f1993091c4689fcf70f754d345ec7a3f45d1fecbfcc52cd60b47b5a486acb155e213 Output.14 = 3cfb2eda22c4f01893b4760b785d330cb771938ed6f2f929030fe625780fb91fc2f9952409b99f011cb5e7e0b4a7d461be80e94e91111ace0604a7a41719f3b3 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -31033,6 +31127,7 @@ PersonalisationString.14 = e7a492e06f2079eb6428f4d39fb18aa0ece5d1edc5f2e1403737b ReseedEntropy.14 = 17837fdc7d5600fa487fa07331c4db6e3d65d522537aae0715a5936f5cb81953965fdda82e5f2b0a1f20dc8beb76beca Output.14 = 2cf0d9cfb60234b23086dc1649e6fa99c4104de9853d19508105535c960468777a936543f6b31ed0d3c52d135671a23d3ea08fb7f29c9dcb3f151163587c39db +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 0 @@ -52485,6 +52580,7 @@ AdditionalInputB.14 = 373b7d3c6e3c07907a45e6292da02991c252b4f368ac894e44fe2741d6 EntropyPredictionResistanceB.14 = 72901d3c6324cb6eea7e62879721c4ab437fcac453cc43f179388851b6d160f3 Output.14 = effddd2d7c39df20550e03ad21ccba6f6775a92726af567a80bcc91523f3646ec156cbaabd4fdb13c63105f2b771f94fbdec6a2670f8fb263cdec3ac1b775774 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -52550,6 +52646,7 @@ EntropyPredictionResistanceA.14 = 43d53e48de3c247857132224a448147672dec7cffe1016 EntropyPredictionResistanceB.14 = de28c574f0d771f2211acb54b43a60ef79973081f06da6819219612c67bd94b7 Output.14 = 3e6e82f2edb3fcd74559b46d319b09cfc3441c06bac7a1260647ed7f9327485d553873d8b58c08410574161e0ff9d5bb2ed4cfea533bdbcd47ec627ac405d3f6 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -52645,6 +52742,7 @@ AdditionalInputB.14 = f298b8789db7c5b8e0354764d0b30013453c3c5c77bfec04264203d767 EntropyPredictionResistanceB.14 = 9a4dfac99270a67b45256a4da4ac0df15693a4a19fb68d08c0a2061a9e190749 Output.14 = a7746e689fbe9eeed34b0ba524851742a5fefe1ff5ab84c6b9a118da64a8ad8fc9ff601ccbe6a5b7e90c5da8cdc8d9fba741d22a0aa1d8ce4fb9cd6148eb06da +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -52725,6 +52823,7 @@ EntropyPredictionResistanceA.14 = 9dfd31e3adc822b675c0a9c8702df12de4c3354ccdb538 EntropyPredictionResistanceB.14 = 2a1b1519d22d40ef4ec23c6d97dc148cfe171fb5f8b1c305ec6d8e83a1ef9064 Output.14 = ac054570b081cf53b39b0a2faa21ee9b554c05ff9055843ac0eb9031d1de324701ad4cf2875623e0bf4184de4aea20070be1cb586880ac87fbb7e414b4b128d0 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -52835,6 +52934,7 @@ AdditionalInputB.14 = 6fd46ca18d10326f5734d0160163bc42d3daa55e3c74a2e0fc7380fd84 EntropyPredictionResistanceB.14 = 16f3bd62634368535da170a7f117bbf8b896ba1bfac5ab682247b1b55452e844 Output.14 = f84c05b144b114fbd2f80a21862a44f3641fbe980957e3fab736976db37b8bca823d7f848f32f4aca60268c020a2e85a5ee0f31fb746f0dff066b83d32563df9 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -52900,6 +53000,7 @@ EntropyPredictionResistanceA.14 = 8090391380ed44d3423fdf8d47891a2027110da4c2334e EntropyPredictionResistanceB.14 = 8288a190ae9118c57b033808bb3f895d4dfbf2dc7ce9b9016e339548fee10a6f Output.14 = 73d122b8854f2610a833a78af28baf4a2dae48dd1ed685e4f98947092e3aaa56a65fdc9acd8a875c16b2a91c757ff7cd6ee777292fbcb0220795c9519cf44052 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -52995,6 +53096,7 @@ AdditionalInputB.14 = 440e9b55a68dd27df4ef8d0dfeb8c2156c2250cc1ab574432c2b62baca EntropyPredictionResistanceB.14 = 3cd2f704ace560337fcbcc07d2b027c37380b35b26b26e40b9d62dd654e44193 Output.14 = e55b536cca2b2148af20e887ad6b1c6ab5c285fe5271e188c5fe5f7f037bab8d6d2502ab71d768d4f05b1bef7f27440ce8f64311ff7147dbb55719bf7371bbd4 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -53075,6 +53177,7 @@ EntropyPredictionResistanceA.14 = d0caa71a0c2e2f218bdded7a08864addea822aaab598b5 EntropyPredictionResistanceB.14 = 31fcf2f4f7580ea3b79e738830d42a218935ac5c6583febabc14bb5463fe4609 Output.14 = ae6cbc3e108ba64b18244ac14eefb670caa16784e175ffc1f41126cdbe791e0e3de26d58123aae6843613b478b9ed94173fa27c7400bb071e0a9829b9a8fca19 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -53185,6 +53288,7 @@ AdditionalInputB.14 = 55156a604966212f7cf20379b79cdfee41a9fe462c9f7e17e5a082c5dc EntropyPredictionResistanceB.14 = c64dc7f4e7fc14ada0905e271e0de491a7b8e4931d26823e572132329e00652a Output.14 = 7d96dfe0f6fe3eac2de3a3a8729d36afb1767aeae2ac3c79db0c523226cacac3cac6d5a87d4f152e8e7274069cc9f12bb7edb293f04e9bbd5a8f0ab142fc373b +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -53250,6 +53354,7 @@ EntropyPredictionResistanceA.14 = 25aeb73bc04139a647b60a0e506db2109581f58b704f00 EntropyPredictionResistanceB.14 = a2e5839c59fc255576a2fd462c719895314a033823f11f419446d02702bf004f Output.14 = fb833a40a658217ad75391aa8311b3e872bbc2e1cb150da87cc6e3494423c5a992593b68f609d30387a0384f64079236a1038969d011bea6f8adb052c5b57eec +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -53345,6 +53450,7 @@ AdditionalInputB.14 = 4e6c1d082917ac9eda7f032c61867736b5be7b3045555f6ef10c584875 EntropyPredictionResistanceB.14 = bcad225d779bd3653a616a8d667030c556117b2adb88e4a6a4e0d0561ae94f42 Output.14 = 14cf6fa5cfb8f9c74add5b2dca5e30395a1045ed1e1cf4e91ccbdf8ab80d1c0f1d93481651535e4089638b04fdf95f52aec1fff6565b21d8a2a32ea814952411 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -53425,6 +53531,7 @@ EntropyPredictionResistanceA.14 = 24e9ce22a727e4540d7d85e056bf6448063d5f13dae559 EntropyPredictionResistanceB.14 = 9a5f15c36078cfa0c768868816d5bd0b1d33c492fa9554498b6625639a293dcc Output.14 = 54c02aa8e6ccc1f109a5f215f488fe9ca7c7ceb3d1b0d9e9256ac4f5d4195cc8c36f8d8ddff55ea10f86d0eb5bdb5b116339b9c0229eb7e96814012a2ed5eb0a +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -53535,6 +53642,7 @@ AdditionalInputB.14 = 34e517ff4f40e3c0c699710134cdeed029baea8e142db0bac9c5aba6a0 EntropyPredictionResistanceB.14 = 09d8b16346fbf20ca073688ab3e917602686e07dff338142841410068e640296 Output.14 = c1d0095376ac846921d2bba5f4d50d231851311792c66d125d5701d6cc466e181c893dfc9999c21063f69f0cdb9850c3a34755926c67e3af75e801e7c21f3da9 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -53600,6 +53708,7 @@ EntropyPredictionResistanceA.14 = c52074e8343f57c0f56c9aa4bc3a6bcc9dff30b21905ae EntropyPredictionResistanceB.14 = f09a47309a1ddfeb54eea6dfa7b15ab0e6f183e2478a3889de89091c2bac0c25 Output.14 = efd931fe77e202d2aba86f6407126a859c881abc86c8f8342deeabf527ed6dc679e5dfcdd212ddc3f2e779d043f058893d7b23c6b69334ba0132db6ce82a167c +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -53695,6 +53804,7 @@ AdditionalInputB.14 = 0bf212302b4d20c6d2b799c9fd692b14b5672897fc45b416addaf55501 EntropyPredictionResistanceB.14 = d0b9c12bd6b178f89a238afb0fce43d45dfd2467b3a1cf9b1aa31960179f125c Output.14 = 7e5720126ce4ef83b785d9649915cf76ed6ef318422950b6540cef9a0ca90c40203b3a365b8a5c40d63475f7b37f5366b7f2ed6e18885e361ba89d46350028e4 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -53775,6 +53885,7 @@ EntropyPredictionResistanceA.14 = 3695bd2e5b30b1d3957dd0a116bddba53a24dbe647dea6 EntropyPredictionResistanceB.14 = 4079d6610bbc715e62777ab699e3ac6b6c4d097aad4debf668a54d15744d9ec1 Output.14 = d0aaa51fb084825f8bf0476c703f1133829a93dee1f8061222f3502ff1bdfd550edfdc275f3aec8a8fc5f9e5f71246362fdbcc65a00e7cc52ff353cfa3b3759a +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-128-CTR PredictionResistance = 1 @@ -53885,6 +53996,7 @@ AdditionalInputB.14 = b44a499fdf9330170ebede64cf8fb19f4a8317596d80d8f9c9d1009322 EntropyPredictionResistanceB.14 = a4341ae5155601af7ccfd9bc573968f99ff82ae2605a462af7e6ed6fd5f2cab6 Output.14 = de6541dae09137dfe17fa3bc785c8f45d3d36cb621d76c53f9031b2853ee0657a1edba0f6f06dade6a5a62faec54cf69bbf15db2244909114b0486f75da3cf16 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -53950,6 +54062,7 @@ EntropyPredictionResistanceA.14 = ddcd35394681d6f0170aa6bd8932b602745f41117eecb8 EntropyPredictionResistanceB.14 = 09a5d5925616379b5221b347659afa11da4326b630b57f3b78db9812e667ed3fbad25fcce6307486 Output.14 = e04e5432f671015350f0cc912f5e83e969e00584c6178cc82394cf85ce3dee6ca87b6cb02e27a21e03f83c24c761f521830645fefd4474c634e1124a4d93da30 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -54045,6 +54158,7 @@ AdditionalInputB.14 = cc7df42c7f93a63b8a8389c66a336519cf27cc6e61a06a67c33077c954 EntropyPredictionResistanceB.14 = 1c59550710b2efa9f009e44c0aa724ad3451da29323f60d68d025693510fc01670c282b38bff3249 Output.14 = de2abced63a11a9c7c034fae31d8fd57239a76a8d8382d9a507e5230c1b0c5bf063a99f00cd4428db196597427900f56ac2ff8d556d3af3d119a590b594c2e90 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -54125,6 +54239,7 @@ EntropyPredictionResistanceA.14 = 756f29305af9f4d3ceca4399594d07636df0b2ecfaa064 EntropyPredictionResistanceB.14 = 1880252ad93c994dff31fb2a10fab8c265cf6f6a36f010fc35e4d858bbb783e3a682afc3fb98fe6d Output.14 = 2f7872a704eb276afad3efb131e67c4b9508fffdbb704e8c85c07e6132745941a8889ffc37baa637a1b7b7b0b84fbfdb8fbc00e7f1eff50baf2d062d8434bba2 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -54235,6 +54350,7 @@ AdditionalInputB.14 = 3d91e9e7ca5683312545bdb4613dba83182b0c906f3a1d65a2610709e8 EntropyPredictionResistanceB.14 = c9255e2fabf84b9edd45737f5de13e5661acc03623a3f9268efcaf7f5562cf839bcceda229e06f11 Output.14 = 28ac3acb17dfdba1d5abb3e2515dc16b42bd207d2743c51b3a2e5edceb0021d964fadd50d499e2df1623c2832a9e552331e915395d65e95f3d523d40d1d8a15c +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -54300,6 +54416,7 @@ EntropyPredictionResistanceA.14 = ea4ffce516fba5a28325206d639d1b3a0f7c61798947a5 EntropyPredictionResistanceB.14 = d7e649cdf563e960640b50927a92abcaa306d4e1315eadb0316bb65d7f9166577bab34bf012a6f9c Output.14 = e92c34e544c5342445228ae6740616889856eda4ce82fb7f1c15d1951953f5509ae754624ad9f159dd5e1908da3c97d2a66945b8a8746634dc70b7f31718c4ab +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -54395,6 +54512,7 @@ AdditionalInputB.14 = 16d262848510e407c7680cfcd3fcc27b8647fcc0155426b3e7b54bc473 EntropyPredictionResistanceB.14 = f6d98f69302da7ad42b8e580a9d755e929fe39fb0436140388fc7160d94f6167c0e150566fe5310f Output.14 = 9c7766b3ebb27f65539f3dd6001ae45c85bba6d6c09e600f0b9cf5e02f30b0f8584e696c2fee0239d5e4d5b623700ca98c94e7ca82fbb8b4643549f29d2df244 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -54475,6 +54593,7 @@ EntropyPredictionResistanceA.14 = 828357ad5c99f114394f578f56cd7e9a5da671636bce00 EntropyPredictionResistanceB.14 = 6f256e9f5f7a84ba4fd6eb19b6ae20b27c26660e51982bc4cf8e28a2dc43cdb723cc8a727c2ea91d Output.14 = c176910a6a7c96982841c0b603b423b2fa67c267b5388d858a4d8dcd69d6b67cb96816892162147e38cc602afa459fc5623da0862b74f1e8f569bf3b1024d881 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -54585,6 +54704,7 @@ AdditionalInputB.14 = 205f0f79d140c6ffef742bf3cda512a3fb84af66d058e5a34752cfd0e4 EntropyPredictionResistanceB.14 = 1989becc20da39682e67b961dc4a2f10a73b037b21cf055f1f12e8f59f047200dab4907e5e8b96aa Output.14 = fa20e0054f9edef75b34aa4e76b16dd6d9d54de5e350c879e16541cb80a4e64c3f392a0108c792ec8fcec84721cd71ccae15de31f3eff57e09f024506857c3e9 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -54650,6 +54770,7 @@ EntropyPredictionResistanceA.14 = fcab2000ecec66a23af1381d36e1df97a4341c329f375b EntropyPredictionResistanceB.14 = d75022692bbe5beeca5d81942443cf0dd78b770b7542cb8fd1be65e4908816ea43fa903a7a66fe0b Output.14 = d5f91235a90cafc96e39e2a1e636d9a2386c5214d8616941bb9f4c2fd375da49d33fabec2faca971d6520bab482e33f6f2752b2d054f9c3bb1f50d072978ea2f +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -54745,6 +54866,7 @@ AdditionalInputB.14 = 1a72cab51be3633be268e4533fe4ad482e5178cb3b15c6d8090ae9e888 EntropyPredictionResistanceB.14 = 6587fd55057566c3fcdbd85aa2b693d885234144a6ac9000b8640c8530da8e2e72abfca6980d7119 Output.14 = a0496a05e5238f171f18870973c9e7b9b3fff44df1fc1ccfa398ef73aeb41829a39339fd032591abcce4cd9402297f7c2e38fd2486eaa8c20134fc0122af978f +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -54825,6 +54947,7 @@ EntropyPredictionResistanceA.14 = b459eeb404a1480b64e7d572bced365bf822878085363d EntropyPredictionResistanceB.14 = a057871a394e93e58ba191c239e21858a3127a6b748a4505eda487dc6a5293304aad36d52da132b6 Output.14 = 96b24ef7b19370cb3ec40a4763de926977ecbe6af2fba201e983e7bbd71b23fa95bd315933ce2fb5a10f4a121cc56b125233f09ff920cc380df7ab5513403457 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -54935,6 +55058,7 @@ AdditionalInputB.14 = 02a318a1579714ddac239f968564fa2768d5099c237237ac15aba9bddc EntropyPredictionResistanceB.14 = 0d18ee1fdb9dc23c66aea587fa59cc9c65da7690a7a780bc64727fa3fb22602301911ed3f99fd712 Output.14 = 992397ec168448c4521560085f3956d2fc583bda1924b29fddd081dfcc056a0dcaaf3edd1a84158b6b7e5737d37535fbbd6258319b7458c5524cd0061a8850e8 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -55000,6 +55124,7 @@ EntropyPredictionResistanceA.14 = ad927a71c6390c5613a7c14780abe6d266b2d126aa49f2 EntropyPredictionResistanceB.14 = 152ec7c0d26eab6de29d3d2ef321281297bd2591be887318712ccdbbd3ecfc1c9250f99a226fc9b8 Output.14 = 0ad1101454cfe091f1456383eeb1e7a968328da150f1166b89e7c202daf5e42324314c43fd1da6de3feb9ffcf82cf217bbcdf5c96864c227246306f0c975c4c8 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -55095,6 +55220,7 @@ AdditionalInputB.14 = 3f5221732e417fe4234626d8b4fe5dce8d0974a7551c4e7b9eb827f32c EntropyPredictionResistanceB.14 = 1d81b5e14e9f995cf19771d54877e97b2d4f551c36033874fcf3a4814312d7064acc2556ea5e0fdc Output.14 = c6d9cb21922398c6a63e4d17f0f69f1d4c1b4998d73828d43ea1f69acad5b1d94800a6976c09a8b5befa2b0c82877874eaed15027f9f7dad3bffa005e49758a0 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -55175,6 +55301,7 @@ EntropyPredictionResistanceA.14 = 21db28b5cb9724d93c58f787b155f0131c39b5606e6a96 EntropyPredictionResistanceB.14 = 4aa587edcb940c3a9328a0ef2f195effc1cf027b549ff1ec5d5cac0e996196eacd16108498b27366 Output.14 = 69dc6c36459e005275e344886624ca61a42cba3387dcee79392ae96a311313dc7e33283605fb46aa1d881bccaec6336a61545dac52166cbf8174b8dca3ebfbc6 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-192-CTR PredictionResistance = 1 @@ -55285,6 +55412,7 @@ AdditionalInputB.14 = 3dc3ef9447ffddf64c3ca0569afcf8e5d491a9571b9a1fa251e0684d3a EntropyPredictionResistanceB.14 = 140636342e9ebb2bae8a87b5d8193a59b75b12318e7094975bed5ce2d23a58b4a021496e820a1b35 Output.14 = b72e486984d1273fa7865a2a43a830b625e394cccf169610ad2714b5b64ef6473f53e62aaffc85bfa2b155bf81830abfc528a80c17f2e325bb7ac9197e5a1099 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 @@ -55350,6 +55478,7 @@ EntropyPredictionResistanceA.14 = 6f16ff94cb8ade7a928b9a59af32ea79944e6890a003b0 EntropyPredictionResistanceB.14 = c73fe23a8ba2bb780178342598252e9ce3de907c4fc1cd632b353cf959ff610f23a8a2b0424ad137aec7da42f8c9f2da Output.14 = 8f7261edf6d10824218ad0b10881e3c1251637bbb71d0f35280caec7de254e07147f33288b5c60794060b59e6f5cc2938e4c29de1e4d5d4d3bde3f27c3fab92d +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 @@ -55445,6 +55574,7 @@ AdditionalInputB.14 = da29846d4d48e3eeac71ab07fae9b9dbb6c5d83cffb75c67be10bb15e6 EntropyPredictionResistanceB.14 = 0d9037cf745b3cf41628eb1538bb71b59116da1049ecd36d12d344c5a17e471c8c4e72cfdc7ca0538c81085952241d68 Output.14 = 7a7ed6e632630ffcf32f0373deb2c67c6dcb77f04f1991f89d5d25a3a8c390ac8ac373b66c5da990c3fe28cd93f3a4f8e5594cae25498ed73f5f001b83179b0c +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 @@ -55525,6 +55655,7 @@ EntropyPredictionResistanceA.14 = 2b3877ed4d1b3174d36e784ad7b6b7991dd52979ca5b1c EntropyPredictionResistanceB.14 = 91d421c3eb04de94099a7467254bad70e236d5c27616f766e85b4de3965001db854e61a80bfec2eacb4ff93ecafb8b83 Output.14 = ed703d9273bb9462ac400ee8d587ea3c4d6c27aa014defcb6ca6fe885272bcb4b6ba0822f42941071bf635b41d997c631b680d91b23ee48351041dc274900821 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 @@ -55635,6 +55766,7 @@ AdditionalInputB.14 = 4f23641093342d946d3a956c456dba18bd42de21cb2494f6310da7d20a EntropyPredictionResistanceB.14 = 843e7cac38b659a611dc4af4bd228ebc0cd9073ee98350d04da61f77db66c0c70872153d9fa2af4bc583ac2cf79d506e Output.14 = 6754a72f7fe23ea607ef0ae61a61eb3afc562c5227670572b7ff2dcecf3dcb4194829d29fcf9b100412aa0ee87611ab534896f80f47cff40b7f76e0ea46b3d41 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 @@ -55700,6 +55832,7 @@ EntropyPredictionResistanceA.14 = b8ef0d478028f0c55dd13861281489e6c124870f0f28c8 EntropyPredictionResistanceB.14 = c12649a0f249c7f5ddb550eb527a0f720e5eaf04e6e3b96dc24881eba10ce466f67e3fe51a0342cb1a2192a555798169 Output.14 = d8c63ecb23f16ee925282b7744e8cc2c2c1deb56581cf27152118b5790cdbe682a34d91523bf0c7be4ff263aba2ffdda35e4d36a5122461b89b43069932b30a9 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 @@ -55795,6 +55928,7 @@ AdditionalInputB.14 = e97f7fc9e287ae947d3e937d60ece684f0c8dd9e133cbd7265b2b3e073 EntropyPredictionResistanceB.14 = 94904fbdfaf6b1d8931c15a37277814dcacc6343d48b80a1c624f8aa3733e05a52bf1f1266e2b90da5d562d7ffcbc274 Output.14 = ef2fcb4a9113e062d6cd37f51a9944645c3cce0b06e2d11a2c778bdb559a2f627c8a0e7f419660f461456064c3508df1db945af6085abaf7719e868a912df8dd +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 @@ -55875,6 +56009,7 @@ EntropyPredictionResistanceA.14 = c436b73aae532ffb950c6ed83753aa6df0571f11fd8e0a EntropyPredictionResistanceB.14 = d3ed7671eb3c2e0c115ec9d6d684964d39533d767413b63e0bf7c956b47205f8d5001a9650e7a1c7381f110c9ecfe92c Output.14 = f99b7d88ccfe1c84c9949c3548630ea2a9ec033543c693c5bf72a82f404c5eec5b2a09afb6c95f10b48fe4608092e7213285af83ba1304acfef846060a1cf860 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 @@ -55985,6 +56120,7 @@ AdditionalInputB.14 = 58a98d14625f59f7adf6a703b2e1ee21fb83f22f3694f7f06548c85804 EntropyPredictionResistanceB.14 = aec90f26f7c7853f3917de516f1ee0f85a0f3d0eb4967f6d2694552a93a25ca7fbdb4554de8acc0e60af0c5b0829cb9a Output.14 = 18d3f2396fa92b0b9e6bc7a5c0f9f8e10857c0063b4fdd8ee76d12e1205eb5e4fbe1b07ffc0ec5045eaaad608a558d1107f931c0290392166bed2d09849880a5 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 @@ -56050,6 +56186,7 @@ EntropyPredictionResistanceA.14 = 1e5191f18e3c049b3aa304604a42b13e87b61ab808a1f2 EntropyPredictionResistanceB.14 = a04435fab8cffaaef34f6738f2682adef4790e8e2655d5943bd5370009ede99a6da3c9ca4dc7105a1352f9bd295be419 Output.14 = 31b0234431f4ff22f0c1f5c220a5890c7efabc06974357a1ab8a79d1caa66b46b62f0b5a5b0d8010923dd86ced2f039effa2031619aafbb3d7dc9362ef04bdf3 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 @@ -56145,6 +56282,7 @@ AdditionalInputB.14 = b1e3c770adbc772d94edef6188d0f07ea1c25fb41dd20eefb552dead33 EntropyPredictionResistanceB.14 = ffd6fd3031397d33e382f40b6338e7e3640b9b35800d890581fad4784366a1533f38398f255dc316bde222850794e46a Output.14 = 826dc7b1c39fb4955f614fab27697ed5fa1ed8686c701ef5e03776a814bbcdf9afe49343cb53944241c30b201be6d181edd20d55fe0374a43d68205d8ef758ff +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 @@ -56225,6 +56363,7 @@ EntropyPredictionResistanceA.14 = 83acc7bc2f89de95c84a4450d509e7de3512ad839f832b EntropyPredictionResistanceB.14 = 95a26a2f946c03f51012bc6cda0797af89a8500394cc7f11866a861608eb97fcd2e37df3f681dc3c1b3f48bdeae119cd Output.14 = a7b6c0c8bebd7eca9357a2be02063a603c103d68a793e792497ecf66592835f1f9607dae7b98be1049514ec5ea4cdd0b41d5cbf986a3a04314515b341f0924ab +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 @@ -56335,6 +56474,7 @@ AdditionalInputB.14 = c0e16d4fc85cfb1c3a4f69806041c5a270d4af742292dcebeccba75e1b EntropyPredictionResistanceB.14 = a52c99a12f63c6ae4bc101ff221d7fd1b4dd79df76e38992ba3fdf380bdbad5e6aa15d0ab638e90874d81bdb2e983aba Output.14 = e728957b292565f906de0cee5bf91fbe2e189857ca5d5efefb5953a8e9f46630756ea01abf8e6fc499bc8e2e5c29c62669bc07ccfbdc7951215f8ba7f1bc815e +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 @@ -56400,6 +56540,7 @@ EntropyPredictionResistanceA.14 = cd66ebf08c99f9c04c1effc078717b4f24422f111591a0 EntropyPredictionResistanceB.14 = 60c6f9f07f75f1a80188b32d07c2895872c4e8b92a19ac6c2a29bc807f99fb4af75b6aed8e6f75c9a6b1559b48f128e9 Output.14 = 2d20709ea0ff7a624ea1e37d80c65c25eaed85af45ef1a092ea7b97c49c912a0f0fc62d29ff4e4182c6bb12676cab3711c2b8db265cd9f81569a300b99fac43e +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 @@ -56495,6 +56636,7 @@ AdditionalInputB.14 = dbe91ffe3bfb719bebbb0e3bb60aa907ca6e0411c05a7ded766674cd4d EntropyPredictionResistanceB.14 = ca5099749aa7f195e0fde5262c56ad35c1d52069001fbb6580d478f50d1d69f6941d7ea4fa66e4741cad701a67f92933 Output.14 = a135641f33e2aa5975a3be70b05e0b8c48372ef7c6768eed8e6c2b4e91d9153eead217ea47bf96b1412af4e08c3114d2c85f2e29fbe93c26014677bd14266ecf +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 @@ -56575,6 +56717,7 @@ EntropyPredictionResistanceA.14 = c3444261962386b57d6c5f125dc3043678afe1962d55d9 EntropyPredictionResistanceB.14 = 1fd895068aec8df2684784007949e0370578676c6537a09dd90567b95f6138809e70bcc9fc9efc03dfd83f0367784bde Output.14 = 894f3bc0fcbdb76b01df80f05d0ca636bd51438f5ee28250f27e8e47968c9c86a847970090d51b0a60984ebb5079017a5c5bac394e9644befc566edd4768d919 +FIPSversion = <3.5.8 RAND = CTR-DRBG Cipher = AES-256-CTR PredictionResistance = 1 diff --git a/test/recipes/30-test_ml_dsa.t b/test/recipes/30-test_ml_dsa.t old mode 100644 new mode 100755 index 142258cfe906a..8b7b00ba92cbf --- a/test/recipes/30-test_ml_dsa.t +++ b/test/recipes/30-test_ml_dsa.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -92,6 +92,6 @@ SKIP: { skip "FIPS provider version is too old for ML-DSA test", 1 if !$exit; - ok(run(test(["ml_dsa_test", "-config", $provconf])), + ok(run(test(["ml_dsa_test", "-fips", "-config", $provconf])), "running ml_dsa_test with FIPS"); } diff --git a/test/recipes/30-test_pairwise_fail.t b/test/recipes/30-test_pairwise_fail.t index ca2d1f96e497c..1b3269a9824b6 100644 --- a/test/recipes/30-test_pairwise_fail.t +++ b/test/recipes/30-test_pairwise_fail.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/30-test_prov_config.t b/test/recipes/30-test_prov_config.t index 1ef8736209c6f..958acb2b6ff34 100644 --- a/test/recipes/30-test_prov_config.t +++ b/test/recipes/30-test_prov_config.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2021-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -8,7 +8,7 @@ use OpenSSL::Test::Simple; -use OpenSSL::Test qw/:DEFAULT srctop_file srctop_dir bldtop_dir/; +use OpenSSL::Test qw/:DEFAULT srctop_file srctop_dir bldtop_dir bldtop_file/; use OpenSSL::Test::Utils; BEGIN { @@ -24,7 +24,7 @@ plan tests => 2; ok(run(test(["prov_config_test", srctop_file("test", "default.cnf"), srctop_file("test", "recursive.cnf"), - srctop_file("test", "pathed.cnf")])), + bldtop_file("test", "pathed.cnf")])), "running prov_config_test default.cnf"); SKIP: { @@ -32,6 +32,6 @@ SKIP: { ok(run(test(["prov_config_test", srctop_file("test", "fips.cnf"), srctop_file("test", "recursive.cnf"), - srctop_file("test", "pathed.cnf")])), + bldtop_file("test", "pathed.cnf")])), "running prov_config_test fips.cnf"); } diff --git a/test/recipes/60-test_dtls13_internal.t b/test/recipes/60-test_dtls13_internal.t new file mode 100644 index 0000000000000..4d2f080ea82bf --- /dev/null +++ b/test/recipes/60-test_dtls13_internal.t @@ -0,0 +1,17 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +use OpenSSL::Test qw/:DEFAULT srctop_file/; + +setup("test_dtls13_internal"); + +plan tests => 1; + +ok(run(test(["dtls13_internal_test", srctop_file("apps", "server.pem"), + srctop_file("apps", "server.pem")])), "running dtls13_internal_test"); diff --git a/test/recipes/61-test_bio_readbuffer.t b/test/recipes/61-test_bio_readbuffer.t index 72027f722f690..cd3db6a6ec54c 100644 --- a/test/recipes/61-test_bio_readbuffer.t +++ b/test/recipes/61-test_bio_readbuffer.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/65-test_cmp_msg.t b/test/recipes/65-test_cmp_msg.t index d104576a9d60e..ac6648296749d 100644 --- a/test/recipes/65-test_cmp_msg.t +++ b/test/recipes/65-test_cmp_msg.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright Nokia 2007-2019 # Copyright Siemens AG 2015-2019 # @@ -20,17 +20,22 @@ use lib srctop_dir('Configurations'); use lib bldtop_dir('.'); my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0); +my $no_ec = disabled('ec'); plan skip_all => "This test is not supported in a no-cmp build" if disabled("cmp"); -plan tests => 2 + ($no_fips ? 0 : 1); #fips test +plan tests => 2 + ($no_fips ? 0 : 1) + ($no_ec ? 0 : 1); #fips test and ec test my @basic_cmd = ("cmp_msg_test", data_file("new.key"), data_file("server.crt"), data_file("pkcs10.der")); +unless ($no_ec) { + ok(run(test(["cmp_extracerts_dos_test"]))); +} + ok(run(test([@basic_cmd, "none"]))); ok(run(test([@basic_cmd, "default", srctop_file("test", "default.cnf")]))); diff --git a/test/recipes/65-test_cmp_vfy.t b/test/recipes/65-test_cmp_vfy.t index 7cfeb4cc05cbd..8895482ab4a50 100644 --- a/test/recipes/65-test_cmp_vfy.t +++ b/test/recipes/65-test_cmp_vfy.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2007-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2007-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright Nokia 2007-2019 # Copyright Siemens AG 2015-2019 # @@ -29,10 +29,19 @@ plan skip_all => "This test is not supported in a no-ec build" plan tests => 2 + ($no_fips ? 0 : 1); #fips test +# The cert hierarchy should be like this: +# 1 - Root CA (self-signed) +# 1.1 - EndEntity1 (directly issued by root, so 2-level chain) +# 1.2 - Intermediate CA (here with different signature algorithm than root) +# 1.2.1 - EndEntity2 (issued by intermediate CA, so 3-level chain) +sub test_cert { srctop_file("test/certs", $_[0]); } my @basic_cmd = ("cmp_vfy_test", - data_file("server.crt"), data_file("client.crt"), - data_file("EndEntity1.crt"), data_file("EndEntity2.crt"), - data_file("Root_CA.crt"), data_file("Intermediate_CA.crt"), + data_file("server.crt"), + data_file("client.crt"), + test_cert("ee-cert1.pem"), + test_cert("mixed-ee-cert.pem"), + test_cert("root-cert.pem"), + test_cert("mixed-ca-cert.pem"), data_file("IR_protected.der"), data_file("IR_unprotected.der"), data_file("IP_waitingStatus_PBM.der"), diff --git a/test/recipes/65-test_cmp_vfy_data/EndEntity1.crt b/test/recipes/65-test_cmp_vfy_data/EndEntity1.crt deleted file mode 100644 index 4e05449889122..0000000000000 --- a/test/recipes/65-test_cmp_vfy_data/EndEntity1.crt +++ /dev/null @@ -1,16 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICnDCCAYSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdSb290 -IENBMB4XDTE3MTEwODE1NDgwMFoXDTE4MTEwODExMTkwMFowETEPMA0GA1UEAxMG -Q2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtNiWJufEotHe -p6E/4b0laX7K1NRamNoUokLIsq78RoBieBXaGxIdbT6zmhLnLmZdb0UN3v7FUP75 -rqPN2yyj3TbS4o5ilh5El8bDDAPhW5lthCddvH/uBziRAM5oIB4xxOumNbgHpLUT -Clh49sdXd4ydYpCTWld5emRouBmMUeP/0EkyWMBIrHGSBxrqtFVRXhxvVHImQv6Z -hIKql7dCVCZbhUtxw6sLxIGL4xlhKoM2o31k4I/9tjZrWSZZ7KAIOlOLrjxZc/bQ -MwvxVUgS+C+iXzhCY8v+N/K37jwtAAk4C1aOGv/VygNcN0C/ynfKSzFmtnfei4+3 -6GC7HtFzewIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQB3GYpPSCCYsJM5owKcODr/ -I1aJ8jQ+u5jCKjvYLp6Cnbr4AbRXzvKuMyV6UfIAQbrGOxAClvX++5/ZQbhY+TxN -iiUM3yr5yYCLqj4MeYHhJ3gOzcppAO9LQ9V7eA8C830giZMm3cpApFSLP8CpwNUD -W/fgoQfaOae5IYPZdea88Gmt5RVNbtHgVqtm4ifTQo577kfxTeh20s+M6pgYW3/R -vftXy2ITEtk/j3NcRvOyZ7Bu1mAg7wNeUjL+gDWAaxs16LsWsCsUGwfr/Z2Rq1CF -zB0XwIyigkVLDLqDzUShcw0Eb/zYy2KXsxNWA2tb27mw+T+tmmOszpn7JjLrlVks ------END CERTIFICATE----- diff --git a/test/recipes/65-test_cmp_vfy_data/EndEntity2.crt b/test/recipes/65-test_cmp_vfy_data/EndEntity2.crt deleted file mode 100644 index ba062107941bc..0000000000000 --- a/test/recipes/65-test_cmp_vfy_data/EndEntity2.crt +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIB3zCCAZSgAwIBAgIBBjAKBggqhkjOPQQDAzAVMRMwEQYDVQQDEwpad2lzY2hl -bkNBMB4XDTE3MTEwODE2MDUwMFoXDTE4MTEwODExMTkwMFowEjEQMA4GA1UEAxMH -Q2xpZW50MjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALTYlibnxKLR -3qehP+G9JWl+ytTUWpjaFKJCyLKu/EaAYngV2hsSHW0+s5oS5y5mXW9FDd7+xVD+ -+a6jzdsso9020uKOYpYeRJfGwwwD4VuZbYQnXbx/7gc4kQDOaCAeMcTrpjW4B6S1 -EwpYePbHV3eMnWKQk1pXeXpkaLgZjFHj/9BJMljASKxxkgca6rRVUV4cb1RyJkL+ -mYSCqpe3QlQmW4VLccOrC8SBi+MZYSqDNqN9ZOCP/bY2a1kmWeygCDpTi648WXP2 -0DML8VVIEvgvol84QmPL/jfyt+48LQAJOAtWjhr/1coDXDdAv8p3yksxZrZ33ouP -t+hgux7Rc3sCAwEAAaMNMAswCQYDVR0TBAIwADAKBggqhkjOPQQDAwM5ADA2AhkA -qASBLwTauET6FGp/EBe7b/99jTyGB861AhkA5ILGkLX4KmjRkTcNxJ3JKB1Sumya -cbqF ------END CERTIFICATE----- diff --git a/test/recipes/65-test_cmp_vfy_data/Intermediate_CA.crt b/test/recipes/65-test_cmp_vfy_data/Intermediate_CA.crt deleted file mode 100644 index 3416cdb9593e0..0000000000000 --- a/test/recipes/65-test_cmp_vfy_data/Intermediate_CA.crt +++ /dev/null @@ -1,12 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIB1jCBv6ADAgECAgEFMA0GCSqGSIb3DQEBDQUAMBIxEDAOBgNVBAMTB1Jvb3Qg -Q0EwHhcNMTcxMTA4MTYwNDAwWhcNMTgxMTA4MTExOTAwWjAVMRMwEQYDVQQDEwpa -d2lzY2hlbkNBMEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAE9bJcmZWj2CmO6aW8 -9Qylkj1WgPREf9/s4Z1VYqFODeJnebPXFBLVH/aoGxnds9E9oxAwDjAMBgNVHRME -BTADAQH/MA0GCSqGSIb3DQEBDQUAA4IBAQBwQD4NTIWMMevEsSrBpKjjQEWc81Ct -eXoyAXr/d8wgVyuIZe9C7ekxPQCwowcmONUyeYQv9N2eYpdhkAQuk6DS4+aDR4s7 -I6rg5R5CUGGla5NUxM0BKIS3ZIezvEGlP1NFN+HBgJI7ZIIYQ3zDr0EYgo4J7Xvm -5p58pcCZSsbVyKwKs6T+rTzOVVmJ2L1bWzywZEDmzxMkPmA6fP9XtB4Kx/b4oviw -TEQl3Jf9EkBvBkKX2rRJs7aMJo4MwOnE4HHOV5GAQqhGrXltsuXmVfIQPtRN4xlK -oNf/FukI1NcBh4A/iY4PmbyxHYmKy6qjFjng2u2VFtH15HDT4XlLP5gq ------END CERTIFICATE----- diff --git a/test/recipes/65-test_cmp_vfy_data/Root_CA.crt b/test/recipes/65-test_cmp_vfy_data/Root_CA.crt deleted file mode 100644 index 6ccf362546ad9..0000000000000 --- a/test/recipes/65-test_cmp_vfy_data/Root_CA.crt +++ /dev/null @@ -1,17 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICrzCCAZegAwIBAgIBATANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdSb290 -IENBMB4XDTE3MTEwODE1NDUwMFoXDTE4MTEwODExMTkwMFowEjEQMA4GA1UEAxMH -Um9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALiHdLAD2Wu+ -C5UDMK6WCL53Wz0CeU61RRRlGEVSqHrQOWnffgVutgftzsddxxgJJyGsqKo1B+nQ -vapyJyugYJWYNQLN5+iffe4y1UBPnHMQFHiZ4cNR6PB0eHja2wpcN3QmJzOcpRYE -xf+QQwJNFqhRi0cZGfd/JfFi/ybJalqClbnYMPcJo7g6S7M3lWbOnEOUWnbM2EBp -h849mC+kd80vXcRcb7U/3MJKK3Ee72TDye5/kWFf9zcxj2ac0oCiS66JKYobiVJr -NmbGM0I9U6T6ejXVUu2J3pGUFlcf3RCUYf1aWhkmzEzbm/FGMRJ7vVyCXm/OWIh9 -bqtwH5YfljsCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC -AQEAF7tSa9oVan7kPR5/TXB330Ca1xQt5C38afaJbacR9mM8ZkL0HceQTuJGrnAR -4kK7CaB5iraU6Lxyql7drq8aixz/7TXna6c172J6HxDeFhQMeSt1LAh7XN5Ir6Y6 -iO7XD5I5lw3Xv6qvhoD0ktkNk/WtF7aBw2ZAi+RcDMgWzWjoS4WqMbvWEHw10j9b -s8R0YG4yi6wb89UNIMfQtC2XviHKcRS9MzIJQHw73r2EY2t6o9TO+5ukHYDB6/Zo -/CLXu21MzsFvhupHgX6zdptU324tq2za1+4LvmOHSW+D36jEPT22SndXmHo5VmAn -6bQ52MhBI0rrWwju9aBpVzsUUg== ------END CERTIFICATE----- diff --git a/test/recipes/65-test_cmp_vfy_data/chain.txt b/test/recipes/65-test_cmp_vfy_data/chain.txt deleted file mode 100644 index 1b55c25abb4f1..0000000000000 --- a/test/recipes/65-test_cmp_vfy_data/chain.txt +++ /dev/null @@ -1,4 +0,0 @@ -1 - Root_CA (self-signed) -1.1 - EndEntity1 -1.2 Intermediate_CA -1.2.1 EndEntity2 diff --git a/test/recipes/70-test_certtypeext.t b/test/recipes/70-test_certtypeext.t index a310524ee89b1..f436b93e3efde 100644 --- a/test/recipes/70-test_certtypeext.t +++ b/test/recipes/70-test_certtypeext.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/70-test_clienthello.t b/test/recipes/70-test_clienthello.t index 662b31dc4ada8..4813f370c4def 100644 --- a/test/recipes/70-test_clienthello.t +++ b/test/recipes/70-test_clienthello.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -15,10 +15,6 @@ setup("test_clienthello"); plan skip_all => "No TLS/SSL protocols are supported by this OpenSSL build" if alldisabled(available_protocols("tls")); -#No EC with TLSv1.3 confuses the padding calculations in this test -plan skip_all => "No EC with TLSv1.3 is not supported by this test" - if disabled("ec") && !disabled("tls1_3"); - plan tests => 1; ok(run(test(["clienthellotest"])), diff --git a/test/recipes/70-test_comp.t b/test/recipes/70-test_comp.t index c8e37f4cc32c6..c3e545e207192 100644 --- a/test/recipes/70-test_comp.t +++ b/test/recipes/70-test_comp.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2017-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/70-test_dtls13ack.t b/test/recipes/70-test_dtls13ack.t new file mode 100644 index 0000000000000..8649fa866a685 --- /dev/null +++ b/test/recipes/70-test_dtls13ack.t @@ -0,0 +1,279 @@ +#! /usr/bin/env perl +# Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use feature 'state'; + +use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/; +use OpenSSL::Test::Utils; +use File::Temp qw(tempfile); +use TLSProxy::Proxy; +use TLSProxy::Message; +use Cwd qw(abs_path); + +my $test_name = "test_dtls13ack"; +setup($test_name); + +plan skip_all => "TLSProxy isn't usable on $^O" + if $^O =~ /^(VMS)$/ || $^O =~ /^(MSWin32)$/; + +plan skip_all => "$test_name needs the module feature enabled" + if disabled("module"); + +plan skip_all => "$test_name needs the sock feature enabled" + if disabled("sock"); + +plan skip_all => "DTLSProxy does not support partial messages" + if disabled("ec"); + +plan skip_all => "$test_name needs DTLSv1.3 enabled" + if disabled("dtls1_3"); + +$ENV{OPENSSL_MODULES} = abs_path(bldtop_dir("test")); + +my $proxy = TLSProxy::Proxy->new_dtls( + undef, + cmdstr(app(["openssl"]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() +); + +my $testcount = 4; + +plan tests => $testcount; +(undef, my $session) = tempfile(); +my $found_first_client_finish_msg = 0; +my $truncated_ack = 0; + +#Test 1: Check that records are acked during an uninterrupted handshake +$proxy->serverflags("-min_protocol DTLSv1.3 -max_protocol DTLSv1.3"); +$proxy->clientflags("-min_protocol DTLSv1.3 -max_protocol DTLSv1.3 -groups ?X25519:?P-256"); +$proxy->sessionfile($session); +TLSProxy::Message->successondata(1); + +SKIP: { + skip "TLSProxy could not start", $testcount if !$proxy->start(); + + my @expected = get_expected_ack_record_numbers(); + my @actual = get_actual_acked_record_numbers(); + my @missing = record_numbers_missing(\@expected, \@actual); + my $expected_count = @expected; + my $missing_count = @missing; + + ok($missing_count == 0 && $expected_count == 3, + "Check that all record numbers are acked"); + + # Test 2: Check that records that are missing are not acked during a handshake + $proxy->clear(); + $found_first_client_finish_msg = 0; + $proxy->serverflags("-min_protocol DTLSv1.3 -max_protocol DTLSv1.3"); + $proxy->clientflags("-min_protocol DTLSv1.3 -max_protocol DTLSv1.3 -groups ?X25519:?P-256"); + $proxy->sessionfile($session); + $proxy->filter(\&drop_first_client_finish_filter); + TLSProxy::Message->successondata(1); + $proxy->start(); + + @expected = get_expected_ack_record_numbers(); + @actual = get_actual_acked_record_numbers(); + @missing = record_numbers_missing(\@expected, \@actual); + $expected_count = @expected; + $missing_count = @missing; + + ok($missing_count == 1 && $expected_count == 4, + "Check that all record numbers except one are acked"); + + # Test 3: Check that client cert and verify messages are also acked + $proxy->clear(); + $proxy->filter(undef); + $found_first_client_finish_msg = 0; + $proxy->serverflags("-min_protocol DTLSv1.3 -max_protocol DTLSv1.3 -Verify 1"); + $proxy->clientflags("-mtu 2000 -min_protocol DTLSv1.3 -max_protocol DTLSv1.3 -groups ?X25519:?P-256" + ." -cert ".srctop_file("apps", "server.pem")); + $proxy->sessionfile($session); + TLSProxy::Message->successondata(1); + $proxy->start(); + + @expected = get_expected_ack_record_numbers(); + @actual = get_actual_acked_record_numbers(); + @missing = record_numbers_missing(\@expected, \@actual); + $expected_count = @expected; + $missing_count = @missing; + + ok($missing_count == 0 && $expected_count == 5, + "Check that all record numbers are acked"); + + # Test 4: An ACK body of exactly DTLS1_HM_HEADER_LENGTH bytes fills the + # read that looks for a message header and exhausts its record doing so. + # The record that follows it in the same datagram must not then be read + # as the rest of the ACK. + $proxy->clear(); + $proxy->filter(\&short_ack_filter); + $proxy->serverflags("-min_protocol DTLSv1.3 -max_protocol DTLSv1.3"); + $proxy->clientflags("-min_protocol DTLSv1.3 -max_protocol DTLSv1.3 -groups ?X25519:?P-256"); + TLSProxy::Message->successondata(1); + $proxy->start(); + + ok(TLSProxy::Message->fail() + && defined(TLSProxy::Message->alert()) + && TLSProxy::Message->alert()->description() + == TLSProxy::Message::AL_DESC_ILLEGAL_PARAMETER, + "Check a short ACK does not consume the record after it"); +} + +unlink $session; + +sub get_expected_ack_record_numbers +{ + my $records = $proxy->record_list; + my @record_numbers = (); + + foreach (@{$records}) { + my $record = $_; + + if ($record->content_type == TLSProxy::Record::RT_HANDSHAKE + && $record->{sent}) { + my $epoch = $record->epoch; + my $seqnum = $record->seq; + my $serverissender = $record->serverissender; + my $recnum = TLSProxy::RecordNumber->new($epoch, $seqnum); + + my @messages = TLSProxy::Message->get_messages($record); + + my $record_should_be_acked = 0; + + foreach (@messages) { + my $message = $_; + if (!$serverissender + && ($message->mt == TLSProxy::Message::MT_FINISHED + || $message->mt == TLSProxy::Message::MT_CERTIFICATE + || $message->mt == TLSProxy::Message::MT_COMPRESSED_CERTIFICATE + || $message->mt == TLSProxy::Message::MT_CERTIFICATE_VERIFY) + || $message->mt == TLSProxy::Message::MT_KEY_UPDATE + || $message->mt == TLSProxy::Message::MT_NEW_SESSION_TICKET + ) { + $record_should_be_acked = 1; + } + } + + push(@record_numbers, $recnum) if ($record_should_be_acked == 1); + } + } + + return @record_numbers; +} + +sub get_actual_acked_record_numbers +{ + my @records = @{$proxy->record_list}; + my @record_numbers = (); + + foreach (@records) { + my $record = $_; + + $record->get_actual_acked_record_numbers(\@record_numbers); + } + return @record_numbers; +} + +sub record_numbers_missing +{ + my @expected_record_numbers = @{$_[0]}; + my @actual_record_numbers = @{$_[1]}; + my @missing_record_numbers = (); + + foreach (@expected_record_numbers) + { + my $found = 0; + my $expected = $_; + + foreach (@actual_record_numbers) { + my $actual = $_; + if ($actual->epoch() == $expected->epoch() + && $actual->seqnum() == $expected->seqnum()) { + $found = 1 + } + } + + if ($found == 0) { + push(@missing_record_numbers, $expected); + } + } + + return @missing_record_numbers; +} + +sub drop_first_client_finish_filter +{ + my $inproxy = shift; + + foreach my $record (@{$inproxy->record_list}) { + next if ($record->{sent} == 1 || $record->serverissender || $found_first_client_finish_msg == 1); + + my @messages = TLSProxy::Message->get_messages($record); + foreach my $message (@messages) { + if ($message->mt == TLSProxy::Message::MT_FINISHED) { + $record->{sent} = 1; + $found_first_client_finish_msg = 1; + last; + } + } + } +} + +# Truncate the server's ACK to a 12 byte body and follow it with a copy of the +# original in the same datagram. The truncated body claims a record number list +# of 16 bytes but carries 10, so it fills the initial DTLS1_HM_HEADER_LENGTH +# read, leaves its record empty, and cannot be parsed from that record alone. A +# peer that reads the rest of the body from the record behind it gets a list it +# can parse, and loses that record. +sub short_ack_filter +{ + my $inproxy = shift; + my $records = $inproxy->record_list; + my $idx = 0; + + return if $truncated_ack; + + foreach my $record (@{$records}) { + if (!$record->{sent} && $record->serverissender && $record->encrypted + && $record->content_type == TLSProxy::Record::RT_ACK) { + # The copy needs a sequence number of its own, or it is a replay + my $copy = TLSProxy::Record->new_dtls( + 1, + $record->flight, + $record->outer_content_type, + $record->version, + $record->epoch, + $record->seq + 5, + $record->len, + $record->len_real, + $record->decrypt_len, + $record->data, + $record->decrypt_data); + + $copy->encrypted(1); + $copy->content_type(TLSProxy::Record::RT_ACK); + + # The p_ossltest cipher is a no-op, so the record body is the + # inner plaintext, its content type, and a zero tag + my $body = pack("n", 16).("\0" x 10); + my $data = $body.pack("C", TLSProxy::Record::RT_ACK).("\0" x 16); + + $record->data($data); + $record->len(length $data); + $record->decrypt_data($body); + $record->decrypt_len(length $body); + + splice @{$records}, $idx + 1, 0, $copy; + $truncated_ack = 1; + return; + } + $idx++; + } +} diff --git a/test/recipes/70-test_dtls13epoch.t b/test/recipes/70-test_dtls13epoch.t new file mode 100644 index 0000000000000..577b8b414c62e --- /dev/null +++ b/test/recipes/70-test_dtls13epoch.t @@ -0,0 +1,144 @@ +#! /usr/bin/env perl +# Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use feature 'state'; + +use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/; +use OpenSSL::Test::Utils; +use TLSProxy::Proxy; +use TLSProxy::Message; +use Cwd qw(abs_path); + +my $test_name = "test_dtls13epoch"; +setup($test_name); + +plan skip_all => "DTLSProxy isn't usable on $^O" + if ($^O =~ /^(VMS)$/) || ($^O =~ /^(MSWin32)$/); + +plan skip_all => "$test_name needs the module feature enabled" + if disabled("module"); + +plan skip_all => "$test_name needs the sock feature enabled" + if disabled("sock"); + +plan skip_all => "$test_name needs DTLSv1.3 enabled" + if disabled("dtls1_3"); + +plan skip_all => "DTLSProxy does not support partial messages" + if disabled("ec"); + +$ENV{OPENSSL_MODULES} = abs_path(bldtop_dir("test")); + +my $proxy = TLSProxy::Proxy->new_dtls( + undef, + cmdstr(app(["openssl"]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() +); + +plan tests => 2; + +my $epoch_check_failed; +my $latest_epoch; +my $nst_seq_check_failed; +my $nst_msgseq; + +#Test 1: Check that epoch is incremented as expected during a handshake +$epoch_check_failed = 0; +$latest_epoch = 0; +$proxy->serverflags("-min_protocol DTLSv1.3 -max_protocol DTLSv1.3"); +$proxy->clientflags("-min_protocol DTLSv1.3 -max_protocol DTLSv1.3 -groups ?X25519:?P-256"); +$proxy->filter(\¤t_record_epoch_filter); +TLSProxy::Message->successondata(1); +SKIP: { + skip "TLS Proxy did not start", 2 if !$proxy->start(); + ok(!$epoch_check_failed + && $latest_epoch == 3, "Epoch changes correctly during handshake"); + + #Test 2: Check that NewSessionTicket has the correct handshake sequence number + # In DTLS 1.3, post-handshake messages like NewSessionTicket should continue + # the handshake sequence numbering (not reset to 0) + $nst_seq_check_failed = 0; + $nst_msgseq = -1; + foreach my $message (@{$proxy->message_list}) { + if ($message->mt == TLSProxy::Message::MT_NEW_SESSION_TICKET) { + $nst_msgseq = $message->msgseq; + # The NewSessionTicket should have a sequence number > 0 + if ($nst_msgseq == 0) { + print "NewSessionTicket has incorrect sequence number 0 (should be > 0)\n"; + $nst_seq_check_failed = 1; + } + last; + } + } + ok(!$nst_seq_check_failed && $nst_msgseq > 0, + "NewSessionTicket has correct handshake sequence number ($nst_msgseq)"); +} + +sub current_record_epoch_filter +{ + my $records = $proxy->record_list; + my $latest_record = @{$records}[-1]; + my $epoch = $latest_record->epoch; + my @badmessagetypes = undef; + + $latest_epoch = $epoch; + + if ($epoch == 0) { + @badmessagetypes = ( + TLSProxy::Message::MT_NEW_SESSION_TICKET, + TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, + TLSProxy::Message::MT_CERTIFICATE, + TLSProxy::Message::MT_SERVER_KEY_EXCHANGE, + TLSProxy::Message::MT_CERTIFICATE_REQUEST, + TLSProxy::Message::MT_SERVER_HELLO_DONE, + TLSProxy::Message::MT_CERTIFICATE_VERIFY, + TLSProxy::Message::MT_CLIENT_KEY_EXCHANGE, + TLSProxy::Message::MT_FINISHED, + TLSProxy::Message::MT_CERTIFICATE_STATUS, + TLSProxy::Message::MT_COMPRESSED_CERTIFICATE, + TLSProxy::Message::MT_NEXT_PROTO + ); + } elsif ($epoch == 1) { + @badmessagetypes = ( + TLSProxy::Message::MT_NEW_SESSION_TICKET, + TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, + TLSProxy::Message::MT_CERTIFICATE, + TLSProxy::Message::MT_SERVER_KEY_EXCHANGE, + TLSProxy::Message::MT_CERTIFICATE_REQUEST, + TLSProxy::Message::MT_SERVER_HELLO_DONE, + TLSProxy::Message::MT_CERTIFICATE_VERIFY, + TLSProxy::Message::MT_CLIENT_KEY_EXCHANGE, + TLSProxy::Message::MT_FINISHED, + TLSProxy::Message::MT_CERTIFICATE_STATUS, + TLSProxy::Message::MT_COMPRESSED_CERTIFICATE, + TLSProxy::Message::MT_NEXT_PROTO + ); + + } elsif ($epoch == 2) { + @badmessagetypes = ( + TLSProxy::Message::MT_NEW_SESSION_TICKET, + TLSProxy::Message::MT_CERTIFICATE_STATUS, + TLSProxy::Message::MT_COMPRESSED_CERTIFICATE, + TLSProxy::Message::MT_NEXT_PROTO + ); + } + + # Check that message types are acceptable + foreach (@{$proxy->message_list}) + { + my $mt = $_->mt; + + if (grep(/^$mt$/, @badmessagetypes)) { + print "Did not expect $mt in epoch $latest_epoch\n"; + $epoch_check_failed = 1; + } + } +} diff --git a/test/recipes/70-test_dtls13sessionid.t b/test/recipes/70-test_dtls13sessionid.t new file mode 100644 index 0000000000000..2ee53489de749 --- /dev/null +++ b/test/recipes/70-test_dtls13sessionid.t @@ -0,0 +1,117 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# In DTLS 1.3 OpenSSL client always sends an empty legacy_session_id. Other +# implementations (e.g. wolfSSL) instead send a non-empty legacy_session_id on +# the resumption ClientHello. The server must ignore that field for (D)TLS 1.3 +# and resume regardless. +# +# This test drives an OpenSSL <-> OpenSSL DTLS 1.3 resumption through TLSProxy +# and injects a non-empty, mismatching legacy_session_id into the resumption +# ClientHello to reproduce that peer behaviour, then checks the server still +# resumes. Resumption is detected by the absence of a server Certificate +# message (a full handshake would send one, a resumed handshake would not). + +use strict; +use OpenSSL::Test qw/:DEFAULT cmdstr srctop_file bldtop_dir/; +use OpenSSL::Test::Utils; +use File::Temp qw(tempfile); +use TLSProxy::Proxy; +use TLSProxy::Message; +use Cwd qw(abs_path); + +my $test_name = "test_dtls13sessionid"; +setup($test_name); + +plan skip_all => "TLSProxy isn't usable on $^O" + if $^O =~ /^(VMS|MSWin32)$/; + +plan skip_all => "$test_name needs the module feature enabled" + if disabled("module"); + +plan skip_all => "$test_name needs the sock feature enabled" + if disabled("sock"); + +plan skip_all => "DTLSProxy does not support partial messages" + if disabled("ec"); + +plan skip_all => "$test_name needs DTLSv1.3 enabled" + if disabled("dtls1_3"); + +$ENV{OPENSSL_MODULES} = abs_path(bldtop_dir("test")); + +my $proxy = TLSProxy::Proxy->new_dtls( + undef, + cmdstr(app(["openssl"]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() +); + +plan tests => 2; + +# P-256 only: keeps the ClientHello small enough to avoid DTLS fragmentation. +my $clientflags = "-min_protocol DTLSv1.3 -max_protocol DTLSv1.3 -groups ?P-256"; +my $serverflags = "-min_protocol DTLSv1.3 -max_protocol DTLSv1.3"; +(undef, my $session) = tempfile(); + +# Connection 1: full handshake that establishes and saves a resumable session. +$proxy->clientflags("$clientflags -sess_out $session"); +$proxy->serverflags($serverflags); +$proxy->sessionfile($session); +TLSProxy::Message->successondata(1); +my $started = $proxy->start(); +ok($started && server_sent_certificate(), + "Initial DTLS 1.3 handshake completes and establishes a session"); + +# Connection 2: resume, but rewrite the resumption ClientHello to carry a +# non-empty, mismatching legacy_session_id (as a non-OpenSSL peer would). +$proxy->clear(); +$proxy->clientflags("$clientflags -sess_in $session"); +$proxy->serverflags($serverflags); +$proxy->sessionfile($session); +$proxy->filter(\&inject_session_id_filter); +# The server sends at most one NewSessionTicket after a resumption, so the +# proxy must not wait for the default two to be acked. +$proxy->expected_tickets(1); +TLSProxy::Message->successondata(1); +$proxy->start(); +ok(TLSProxy::Message->success() && !server_sent_certificate(), + "Server resumes despite a non-empty mismatching legacy_session_id"); + +unlink $session; + +# Returns 1 if the server sent a Certificate message, i.e. a full (non-resumed) +# handshake took place. +sub server_sent_certificate +{ + foreach my $message (@{$proxy->message_list}) { + return 1 if defined $message + && $message->server + && $message->mt == TLSProxy::Message::MT_CERTIFICATE; + } + return 0; +} + +# Give every empty client ClientHello a non-empty legacy_session_id. This grows +# the message by 32 bytes; the value deliberately does not match the cached +# session id, which is exactly the case ssl_get_prev_session() must tolerate for +# DTLS 1.3. +sub inject_session_id_filter +{ + my $proxy = shift; + + foreach my $message (@{$proxy->message_list}) { + next if !defined $message + || $message->mt != TLSProxy::Message::MT_CLIENT_HELLO; + next if $message->session_id_len != 0; + $message->session_id_len(32); + $message->session(pack("C*", (0xAB) x 32)); + $message->repack(); + } +} diff --git a/test/recipes/70-test_npn.t b/test/recipes/70-test_npn.t index 13ac6fc48d8cc..0ad4cfc8de31d 100644 --- a/test/recipes/70-test_npn.t +++ b/test/recipes/70-test_npn.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/70-test_quic_multistream.t b/test/recipes/70-test_quic_multistream.t index 320d095d94f4e..a13693ee7100d 100644 --- a/test/recipes/70-test_quic_multistream.t +++ b/test/recipes/70-test_quic_multistream.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2022-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2022-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -37,8 +37,12 @@ SKIP: { skip "no qlog", 1 if disabled('qlog'); skip "not running CI tests", 1 unless $ENV{OSSL_RUN_CI_TESTS}; - subtest "check qlog output" => sub { - plan tests => 1; + subtest "generate and check qlog output" => sub { + plan tests => 2; + ok(run(test(["quic_radix_test", + srctop_file("test", "certs", "servercert.pem"), + srctop_file("test", "certs", "serverkey.pem")])), + "running quic_radix_test to contribute qlog output"); ok(run(cmd([data_file("verify-qlog.py")], exe_shell => "python3")), "running qlog verification script"); diff --git a/test/recipes/70-test_quic_radix.t b/test/recipes/70-test_quic_radix.t index f32d2f692023d..9250a2b0df00d 100644 --- a/test/recipes/70-test_quic_radix.t +++ b/test/recipes/70-test_quic_radix.t @@ -1,14 +1,50 @@ #! /usr/bin/env perl -# Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy # in the file LICENSE in the source distribution or at # https://www.openssl.org/source/license.html -use OpenSSL::Test qw/:DEFAULT srctop_file/; +use OpenSSL::Test qw/:DEFAULT result_file srctop_file/; use OpenSSL::Test::Utils; +sub diagnose_failure { + my ($log, $max_bytes) = @_; + my $fh; + + diag("Full stderr: $log"); + if (!open($fh, "<", $log)) { + diag("Could not open stderr log: $!"); + return; + } + + binmode($fh); + my $size = -s $fh; + if (!defined($size)) { + diag("Could not determine stderr log size: $!"); + close($fh); + return; + } + + my $offset = $size > $max_bytes ? $size - $max_bytes : 0; + if (!seek($fh, $offset, 0)) { + diag("Could not seek in stderr log: $!"); + close($fh); + return; + } + + # Do not start the diagnostic output with a truncated line. + scalar <$fh> if $offset > 0; + + diag("Stderr tail (up to " . ($max_bytes / 1024) . " KiB):"); + while (my $line = <$fh>) { + $line =~ s/\r?\n\z//; + diag($line); + } + close($fh); +} + setup("test_quic_radix"); plan skip_all => "QUIC protocol is not supported by this OpenSSL build" @@ -16,6 +52,13 @@ plan skip_all => "QUIC protocol is not supported by this OpenSSL build" plan tests => 1; -ok(run(test(["quic_radix_test", - srctop_file("test", "certs", "servercert.pem"), - srctop_file("test", "certs", "serverkey.pem")]))); +# Keep the test's multi-megabyte diagnostics out of the TAP pipe. +my $redirect = $ENV{HARNESS_ACTIVE} && !$ENV{HARNESS_VERBOSE}; +my $stderr_log = result_file("quic_radix_test.log"); +my $result = run(test(["quic_radix_test", + srctop_file("test", "certs", "servercert.pem"), + srctop_file("test", "certs", "serverkey.pem")], + $redirect ? (stderr => $stderr_log) : ())); + +diagnose_failure($stderr_log, 32 * 1024) if !$result && $redirect; +ok($result, "running QUIC RADIX tests"); diff --git a/test/recipes/70-test_rio_poll_builder.t b/test/recipes/70-test_rio_poll_builder.t new file mode 100644 index 0000000000000..e76c2f280a781 --- /dev/null +++ b/test/recipes/70-test_rio_poll_builder.t @@ -0,0 +1,19 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use OpenSSL::Test; +use OpenSSL::Test::Utils; + +setup("test_rio_poll_builder"); + +plan skip_all => "RIO poll builder tests require QUIC" + if disabled("quic"); + +plan tests => 1; + +ok(run(test(["rio_poll_builder_test"]))); diff --git a/test/recipes/70-test_sslcbcpadding.t b/test/recipes/70-test_sslcbcpadding.t index 7c614fe6a027d..7e272cdd4267d 100644 --- a/test/recipes/70-test_sslcbcpadding.t +++ b/test/recipes/70-test_sslcbcpadding.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -115,6 +115,7 @@ sub add_maximal_padding_filter } my $record = TLSProxy::Record->new( + $last_message->server, $proxy->flight, TLSProxy::Record::RT_APPLICATION_DATA, TLSProxy::Record::VERS_TLS_1_2, diff --git a/test/recipes/70-test_sslcertstatus.t b/test/recipes/70-test_sslcertstatus.t index 4c384ff49efed..1d1bf9ab4cb60 100644 --- a/test/recipes/70-test_sslcertstatus.t +++ b/test/recipes/70-test_sslcertstatus.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/70-test_sslextension.t b/test/recipes/70-test_sslextension.t index 3327df474e1be..cc7111a97883e 100644 --- a/test/recipes/70-test_sslextension.t +++ b/test/recipes/70-test_sslextension.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -38,7 +38,8 @@ use constant { UNSOLICITED_SERVER_NAME => 0, UNSOLICITED_SERVER_NAME_TLS13 => 1, UNSOLICITED_SCT => 2, - NONCOMPLIANT_SUPPORTED_GROUPS => 3 + NONCOMPLIANT_SUPPORTED_GROUPS => 3, + UNKNOWN_SERVER_HELLO_TLS13 => 4 }; my $testtype; @@ -146,7 +147,8 @@ sub inject_unsolicited_extension if ($proxy->flight != 1) { if ($sent_unsolisited_extension) { my $last_record = @{$proxy->record_list}[-1]; - $fatal_alert = 1 if $last_record->is_fatal_alert(0); + my $alert = $last_record->is_fatal_alert(0); + $fatal_alert = $alert if $alert; } return; } @@ -172,6 +174,8 @@ sub inject_unsolicited_extension $type = TLSProxy::Message::EXT_SCT; } elsif ($testtype == NONCOMPLIANT_SUPPORTED_GROUPS) { $type = TLSProxy::Message::EXT_SUPPORTED_GROUPS; + } elsif ($testtype == UNKNOWN_SERVER_HELLO_TLS13) { + $type = TLSProxy::Message::EXT_UNKNOWN; } $message->set_extension($type, $ext); $message->repack(); @@ -194,7 +198,7 @@ sub inject_cryptopro_extension # Test 1-2: Sending a duplicate extension should fail. $proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 8; +plan tests => 9; ok($fatal_alert, "Duplicate ClientHello extension"); SKIP: { @@ -261,7 +265,7 @@ SKIP: { } SKIP: { - skip "TLS 1.3 disabled", 1 + skip "TLS 1.3 disabled", 2 if disabled("tls1_3") || (disabled("ec") && disabled("dh")); #Test 8: Inject an unsolicited extension (TLSv1.3) $fatal_alert = 0; @@ -271,4 +275,14 @@ SKIP: { $proxy->clientflags("-noservername"); $proxy->start(); ok($fatal_alert, "Unsolicited server name extension (TLSv1.3)"); + + #Test 9: Inject an unknown extension in ServerHello (TLSv1.3) + $fatal_alert = 0; + $proxy->clear(); + $proxy->filter(\&inject_unsolicited_extension); + $testtype = UNKNOWN_SERVER_HELLO_TLS13; + $proxy->clientflags(""); + $proxy->start(); + ok($fatal_alert == TLSProxy::Message::AL_DESC_UNSUPPORTED_EXTENSION, + "Unknown ServerHello extension (TLSv1.3)"); } diff --git a/test/recipes/70-test_sslrecords.t b/test/recipes/70-test_sslrecords.t index a09a818efeff0..c66093ac9a736 100644 --- a/test/recipes/70-test_sslrecords.t +++ b/test/recipes/70-test_sslrecords.t @@ -137,7 +137,7 @@ sub run_tests $proxy->clear(); if ($run_test_as_dtls == 1) { $proxy->serverflags("-min_protocol DTLSv1.2 -max_protocol DTLSv1.2"); - $proxy->clientflags("-max_protocol DTLSv1.2"); + $proxy->clientflags("-max_protocol DTLSv1.2 -msg"); } else { $proxy->serverflags("-tls1_2"); $proxy->clientflags("-no_tls1_3"); @@ -146,7 +146,15 @@ sub run_tests $proxy_start_success = $proxy->start(); if ($run_test_as_dtls == 1) { - ok($proxy_start_success == 0, "Unrecognised record type in DTLS1.2"); + # DTLS alerts are best-effort (RFC 6347 section 4.2.7) so we cannot + # rely on the peer observing the client's fatal alert. Instead check + # that s_client itself generated the expected unexpected_message alert + # and then exited cleanly with a failure (rather than crashing). + ok($proxy->client_sent_fatal_alert("unexpected_message") + && $proxy->client_failed(), + "Unrecognised record type in DTLS1.2") + or diag("client exit status: ".$proxy->clientexit. + "\nclient output:\n".$proxy->clientoutput); } else { ok($fatal_alert, "Unrecognised record type in TLS1.2"); } @@ -159,14 +167,18 @@ sub run_tests $fatal_alert = 0; $proxy->clear(); if ($run_test_as_dtls == 1) { - $proxy->clientflags("-min_protocol DTLSv1 -max_protocol DTLSv1 -cipher DEFAULT:\@SECLEVEL=0"); + $proxy->clientflags("-min_protocol DTLSv1 -max_protocol DTLSv1 -msg -cipher DEFAULT:\@SECLEVEL=0"); } else { $proxy->clientflags("-tls1_1 -cipher DEFAULT:\@SECLEVEL=0"); } $proxy->ciphers("AES128-SHA:\@SECLEVEL=0"); $proxy_start_success = $proxy->start(); if ($run_test_as_dtls == 1) { - ok($proxy_start_success == 0, "Unrecognised record type in DTLSv1"); + ok($proxy->client_sent_fatal_alert("unexpected_message") + && $proxy->client_failed(), + "Unrecognised record type in DTLSv1") + or diag("client exit status: ".$proxy->clientexit. + "\nclient output:\n".$proxy->clientoutput); } else { ok($fatal_alert, "Unrecognised record type in TLSv1.1"); } @@ -277,12 +289,13 @@ sub run_tests SKIP: { skip "DTLS only record tests", 1 if $run_test_as_dtls != 1; + skip "EC and DH disabled", 1 if disabled("ec") || disabled("dh"); #Test 17: We should ignore empty app data records $proxy->clear(); + $proxy->clientflags("-groups ?X25519:?P-256:?ffdh2048"); $proxy->filter(\&empty_app_data); $proxy->start(); ok(TLSProxy::Message->success(), "Empty app data in DTLS"); - } } @@ -302,6 +315,7 @@ sub add_empty_recs_filter my $record; if ($isdtls == 1) { $record = TLSProxy::Record->new_dtls( + 0, 0, $content_type, TLSProxy::Record::VERS_DTLS_1_2, @@ -315,6 +329,7 @@ sub add_empty_recs_filter ); } else { $record = TLSProxy::Record->new( + 0, 0, $content_type, TLSProxy::Record::VERS_TLS_1_2, @@ -344,6 +359,7 @@ sub add_frag_alert_filter # Now add the alert level (Fatal) as a separate record $byte = pack('C', TLSProxy::Message::AL_LEVEL_FATAL); my $record = TLSProxy::Record->new( + 0, 0, TLSProxy::Record::RT_ALERT, TLSProxy::Record::VERS_TLS_1_2, @@ -358,6 +374,7 @@ sub add_frag_alert_filter # And finally the description (Unexpected message) in a third record $byte = pack('C', TLSProxy::Message::AL_DESC_UNEXPECTED_MESSAGE); $record = TLSProxy::Record->new( + 0, 0, TLSProxy::Record::RT_ALERT, TLSProxy::Record::VERS_TLS_1_2, @@ -374,6 +391,8 @@ sub add_unknown_record_type { my $proxy = shift; my $records = $proxy->record_list; + my $lastmessage = @{$proxy->message_list}[-1]; + my $isserver = $lastmessage->server; my $isdtls = $proxy->isdtls; state $added_record; @@ -390,6 +409,7 @@ sub add_unknown_record_type if ($isdtls) { $record = TLSProxy::Record->new_dtls( + $isserver, 1, TLSProxy::Record::RT_UNKNOWN, @{$records}[-1]->version(), @@ -403,6 +423,7 @@ sub add_unknown_record_type ); } else { $record = TLSProxy::Record->new( + $isserver, 1, TLSProxy::Record::RT_UNKNOWN, @{$records}[-1]->version(), @@ -544,6 +565,7 @@ sub not_on_record_boundary #KeyUpdates must end on a record boundary my $record = TLSProxy::Record->new( + @{$proxy->{message_list}}[-1]->server, 1, TLSProxy::Record::RT_APPLICATION_DATA, TLSProxy::Record::VERS_TLS_1_2, @@ -571,8 +593,10 @@ sub not_on_record_boundary } else { return if @{$proxy->{message_list}}[-1]->{mt} != TLSProxy::Message::MT_FINISHED; + my $isserver = @{$proxy->{message_list}}[-1]->server; my $record = TLSProxy::Record->new( + $isserver, 1, TLSProxy::Record::RT_APPLICATION_DATA, TLSProxy::Record::VERS_TLS_1_2, @@ -597,6 +621,7 @@ sub not_on_record_boundary if ($boundary_test_type == DATA_BETWEEN_KEY_UPDATE) { #Now add an app data record $record = TLSProxy::Record->new( + $isserver, 1, TLSProxy::Record::RT_APPLICATION_DATA, TLSProxy::Record::VERS_TLS_1_2, @@ -617,6 +642,7 @@ sub not_on_record_boundary #Now add the rest of the KeyUpdate message $record = TLSProxy::Record->new( + $isserver, 1, TLSProxy::Record::RT_APPLICATION_DATA, TLSProxy::Record::VERS_TLS_1_2, @@ -651,30 +677,20 @@ sub empty_app_data return; } - my $data = pack "C52", - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, #IV - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, - 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, #One block of empty padded data - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13; #MAC, assume to be 20 bytes - - # Add a zero length app data record at the end - # This will have the same sequence number as the subsequent app data record - # that s_client will send - which will cause that second record to be - # dropped. But that isn't important for this test. - my $record = TLSProxy::Record->new_dtls( - 4, - TLSProxy::Record::RT_APPLICATION_DATA, - TLSProxy::Record::VERS_DTLS_1_2, - 1, - 1, - length($data), - length($data), - 0, - $data, - "" - ); - push @{$proxy->record_list}, $record; + # Find the client application record + my $client_application_record; + for (my $i = @{$proxy->record_list} - 1; $i >= 0; $i--) { + if ($proxy->record_list->[$i]->serverissender() == 0 + && $proxy->record_list->[$i]->content_type() == TLSProxy::Record::RT_APPLICATION_DATA) { + $client_application_record = $proxy->record_list->[$i]; + last; + } + } + # If we didn't find the Client Application Data record, just return + if (!defined $client_application_record) { + return; + } + + $client_application_record->decrypt_data(""); + $client_application_record->decrypt_len(0); } diff --git a/test/recipes/70-test_sslsessiontick.t b/test/recipes/70-test_sslsessiontick.t index 8ebbbf2cb92c8..e6ec0f61d73d5 100644 --- a/test/recipes/70-test_sslsessiontick.t +++ b/test/recipes/70-test_sslsessiontick.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/70-test_sslsignature.t b/test/recipes/70-test_sslsignature.t index 27a1ad5f7f582..c1d34e5e91b03 100644 --- a/test/recipes/70-test_sslsignature.t +++ b/test/recipes/70-test_sslsignature.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/70-test_sslskewith0p.t b/test/recipes/70-test_sslskewith0p.t index 8b6569a5f4e7c..59ea11225d8a2 100644 --- a/test/recipes/70-test_sslskewith0p.t +++ b/test/recipes/70-test_sslskewith0p.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/70-test_sslversions.t b/test/recipes/70-test_sslversions.t index 6ec62ab4af414..b4976e02a624c 100644 --- a/test/recipes/70-test_sslversions.t +++ b/test/recipes/70-test_sslversions.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/70-test_sslvertol.t b/test/recipes/70-test_sslvertol.t index 8462818ac225f..73b81e362e78a 100644 --- a/test/recipes/70-test_sslvertol.t +++ b/test/recipes/70-test_sslvertol.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/70-test_stime.t b/test/recipes/70-test_stime.t index 0717224266ab1..a7f1f6c90dda9 100644 --- a/test/recipes/70-test_stime.t +++ b/test/recipes/70-test_stime.t @@ -74,5 +74,8 @@ SKIP: { } close $srv_in; -kill 'HUP', $srv_pid; +# SIGKILL rather than SIGHUP: this s_server has no -naccept, so it runs +# until it is stopped, and an ignored SIGHUP inherited from an ancestor +# (SIG_IGN survives exec) would leave the waitpid() below hanging. +kill 'KILL', $srv_pid; waitpid($srv_pid, 0); diff --git a/test/recipes/70-test_tls13alerts.t b/test/recipes/70-test_tls13alerts.t index a3849ccc3675c..c191a4f3209ab 100644 --- a/test/recipes/70-test_tls13alerts.t +++ b/test/recipes/70-test_tls13alerts.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -26,24 +26,67 @@ plan skip_all => "$test_name needs the module feature enabled" plan skip_all => "$test_name needs the sock feature enabled" if disabled("sock"); -plan skip_all => "$test_name needs TLS1.3 enabled" - if disabled("tls1_3") || (disabled("ec") && disabled("dh")); - -my $proxy = TLSProxy::Proxy->new( - undef, - cmdstr(app(["openssl"]), display => 1), - srctop_file("apps", "server.pem"), - (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), - have_IPv6() -); - -#Test 1: We test that a server can handle an unencrypted alert when normally the -# next message is encrypted -$proxy->filter(\&alert_filter); -$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 1; -my $alert = TLSProxy::Message->alert(); -ok(TLSProxy::Message->fail() && !$alert->server() && !$alert->encrypted(), "Client sends an unencrypted alert"); +plan skip_all => "$test_name needs elliptic curves or diffie-hellman enabled" + if disabled("ec") && disabled("dh"); + +my $testcount = 1; + +plan tests => 2 * $testcount; + +SKIP: { + skip "TLS 1.3 is disabled", $testcount if disabled("tls1_3"); + # Run tests with TLS + run_tests(0); +} + +SKIP: { + skip "DTLS 1.3 is disabled", $testcount if disabled("dtls1_3"); + skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/; + run_tests(1); +} + +sub run_tests +{ + my $run_test_as_dtls = shift; + my $proxy_start_success = 0; + + my $proxy; + if ($run_test_as_dtls == 1) { + $proxy = TLSProxy::Proxy->new_dtls( + undef, + cmdstr(app([ "openssl" ]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } + else { + $proxy = TLSProxy::Proxy->new( + undef, + cmdstr(app(["openssl"]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } + + #Test 1: We test that a server can handle an unencrypted alert when normally the + # next message is encrypted + $proxy->clear(); + $proxy->filter(\&alert_filter); + if ($run_test_as_dtls == 1) { + if (disabled("ec")) { + $proxy->clientflags("-groups ffdhe2048:ffdhe3072"); + } else { + $proxy->clientflags("-groups P-256:P-384"); + } + } + $proxy_start_success = $proxy->start(); + skip "TLSProxy did not start correctly", $testcount if $proxy_start_success == 0; + + my $alert = TLSProxy::Message->alert(); + ok(TLSProxy::Message->fail() && !$alert->server() && !$alert->encrypted(), "Client sends an unencrypted alert"); +} sub alert_filter { diff --git a/test/recipes/70-test_tls13certcomp.t b/test/recipes/70-test_tls13certcomp.t index f58c285281fb0..241512fc795a4 100644 --- a/test/recipes/70-test_tls13certcomp.t +++ b/test/recipes/70-test_tls13certcomp.t @@ -210,105 +210,144 @@ plan skip_all => "$test_name needs compression and algorithms enabled" [0,0,0,0] ); -my $proxy = TLSProxy::Proxy->new( - undef, - cmdstr(app(["openssl"]), display => 1), - srctop_file("apps", "server.pem"), - (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), - have_IPv6() -); +my $testcount = 9; + +plan tests => 2 * $testcount; + +SKIP: { + skip "TLS 1.3 is disabled", $testcount if disabled("tls1_3"); + # Run tests with TLS + run_tests(0); +} +SKIP: { + skip "DTLS 1.3 is disabled", $testcount if disabled("dtls1_3"); + skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/; + run_tests(1); +} -#Test 1: Client sends cert comp, but no client auth -$proxy->serverconnects(2); -$proxy->clear(); -$proxy->serverflags("-no_tx_cert_comp -no_rx_cert_comp"); -# One final skip check -$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 9; -checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::CERT_COMP_CLI_EXTENSION, - "Client supports certificate compression"); - -#Test 2: Server sends cert comp, no client auth -$proxy->clear(); -$proxy->clientflags("-no_tx_cert_comp -no_rx_cert_comp"); -$proxy->serverflags("-cert_comp"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::CERT_COMP_SRV_EXTENSION, - "Server supports certificate compression, but no client auth"); - -#Test 3: Both send cert comp, no client auth -$proxy->clear(); -$proxy->serverflags("-cert_comp"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::CERT_COMP_SRV_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::CERT_COMP_CLI_EXTENSION - | checkhandshake::CERT_COMP_SRV_EXTENSION, - "Both support certificate compression, but no client auth"); - -#Test 4: Both send cert comp, with client auth -$proxy->clear(); -$proxy->clientflags("-cert ".srctop_file("apps", "server.pem")); -$proxy->serverflags("-Verify 5 -cert_comp"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::CERT_COMP_BOTH_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::CERT_COMP_CLI_EXTENSION - | checkhandshake::CERT_COMP_SRV_EXTENSION, - "Both support certificate compression, with client auth"); - -#Test 5: Client-to-server-only certificate compression, with client auth -$proxy->clear(); -$proxy->clientflags("-no_rx_cert_comp -cert ".srctop_file("apps", "server.pem")); -$proxy->serverflags("-no_tx_cert_comp -Verify 5 -cert_comp"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::CERT_COMP_CLI_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::CERT_COMP_SRV_EXTENSION, - "Client-to-server-only certificate compression, with client auth"); - -#Test 6: Server-to-client-only certificate compression -$proxy->clear(); -$proxy->clientflags("-no_tx_cert_comp"); -$proxy->serverflags("-no_rx_cert_comp -cert_comp"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::CERT_COMP_SRV_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::CERT_COMP_CLI_EXTENSION, - "Server-to-client-only certificate compression"); - -#Test 7: Neither side wants to send a compressed cert, but will accept one -$proxy->clear(); -$proxy->clientflags("-no_tx_cert_comp"); -$proxy->serverflags("-no_tx_cert_comp -cert_comp"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::CERT_COMP_CLI_EXTENSION - | checkhandshake::CERT_COMP_SRV_EXTENSION, - "Accept but not send compressed certificates"); - -#Test 8: Neither side wants to receive a compressed cert, but will send one -$proxy->clear(); -$proxy->clientflags("-no_rx_cert_comp"); -$proxy->serverflags("-no_rx_cert_comp -cert_comp"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS, - "Send but not accept compressed certificates"); - -#Test 9: Excessive uncompressed certificate length in CompressedCertificate -$proxy->clear(); -$proxy->filter(\&excessive_uncompressed_len_filter); -$proxy->serverflags("-cert_comp"); -$proxy->start(); -ok(is_alert_message(TLSProxy::Message::AL_DESC_BAD_CERTIFICATE), - "Excessive uncompressed certificate length rejected"); +sub run_tests +{ + my $run_test_as_dtls = shift; + my $proxy_start_success = 0; + + my $proxy; + if ($run_test_as_dtls == 1) { + $proxy = TLSProxy::Proxy->new_dtls( + undef, + cmdstr(app([ "openssl" ]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } + else { + $proxy = TLSProxy::Proxy->new( + undef, + cmdstr(app([ "openssl" ]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } + + $proxy->clear(); + + #Test 1: Client sends cert comp, but no client auth + $proxy->serverconnects(2); + $proxy->clear(); + $proxy->serverflags("-no_tx_cert_comp -no_rx_cert_comp"); + # One final skip check + $proxy_start_success = $proxy->start(); + skip "TLSProxy did not start correctly", $testcount if $proxy_start_success == 0; + checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::CERT_COMP_CLI_EXTENSION, + "Client supports certificate compression"); + + #Test 2: Server sends cert comp, no client auth + $proxy->clear(); + $proxy->clientflags("-no_tx_cert_comp -no_rx_cert_comp"); + $proxy->serverflags("-cert_comp"); + $proxy->start(); + checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::CERT_COMP_SRV_EXTENSION, + "Server supports certificate compression, but no client auth"); + + #Test 3: Both send cert comp, no client auth + $proxy->clear(); + $proxy->serverflags("-cert_comp"); + $proxy->start(); + checkhandshake($proxy, checkhandshake::CERT_COMP_SRV_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::CERT_COMP_CLI_EXTENSION + | checkhandshake::CERT_COMP_SRV_EXTENSION, + "Both support certificate compression, but no client auth"); + + #Test 4: Both send cert comp, with client auth + $proxy->clear(); + $proxy->clientflags("-cert " . srctop_file("apps", "server.pem")); + $proxy->serverflags("-Verify 5 -cert_comp"); + $proxy->start(); + checkhandshake($proxy, checkhandshake::CERT_COMP_BOTH_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::CERT_COMP_CLI_EXTENSION + | checkhandshake::CERT_COMP_SRV_EXTENSION, + "Both support certificate compression, with client auth"); + + #Test 5: Client-to-server-only certificate compression, with client auth + $proxy->clear(); + $proxy->clientflags("-no_rx_cert_comp -cert " . srctop_file("apps", "server.pem")); + $proxy->serverflags("-no_tx_cert_comp -Verify 5 -cert_comp"); + $proxy->start(); + checkhandshake($proxy, checkhandshake::CERT_COMP_CLI_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::CERT_COMP_SRV_EXTENSION, + "Client-to-server-only certificate compression, with client auth"); + + #Test 6: Server-to-client-only certificate compression + $proxy->clear(); + $proxy->clientflags("-no_tx_cert_comp"); + $proxy->serverflags("-no_rx_cert_comp -cert_comp"); + $proxy->start(); + checkhandshake($proxy, checkhandshake::CERT_COMP_SRV_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::CERT_COMP_CLI_EXTENSION, + "Server-to-client-only certificate compression"); + + #Test 7: Neither side wants to send a compressed cert, but will accept one + $proxy->clear(); + $proxy->clientflags("-no_tx_cert_comp"); + $proxy->serverflags("-no_tx_cert_comp -cert_comp"); + $proxy->start(); + checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::CERT_COMP_CLI_EXTENSION + | checkhandshake::CERT_COMP_SRV_EXTENSION, + "Accept but not send compressed certificates"); + + #Test 8: Neither side wants to receive a compressed cert, but will send one + $proxy->clear(); + $proxy->clientflags("-no_rx_cert_comp"); + $proxy->serverflags("-no_rx_cert_comp -cert_comp"); + $proxy->start(); + checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS, + "Send but not accept compressed certificates"); + + #Test 9: Excessive uncompressed certificate length in CompressedCertificate + SKIP: { + skip "TLSProxy does not support modifying fragmented encrypted messages for dtls", 1 + if $run_test_as_dtls == 1; + $proxy->clear(); + $proxy->filter(\&excessive_uncompressed_len_filter); + $proxy->serverflags("-cert_comp"); + $proxy->start(); + ok(is_alert_message(TLSProxy::Message::AL_DESC_BAD_CERTIFICATE), + "Excessive uncompressed certificate length rejected"); + } +} my $done = 0; diff --git a/test/recipes/70-test_tls13cookie.t b/test/recipes/70-test_tls13cookie.t index 994f2945db349..9943afc61e36b 100644 --- a/test/recipes/70-test_tls13cookie.t +++ b/test/recipes/70-test_tls13cookie.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -26,8 +26,24 @@ plan skip_all => "$test_name needs the module feature enabled" plan skip_all => "$test_name needs the sock feature enabled" if disabled("sock"); -plan skip_all => "$test_name needs TLS1.3 enabled" - if disabled("tls1_3") || (disabled("ec") && disabled("dh")); +plan skip_all => "$test_name needs EC or DH enabled" + if disabled("ec") && disabled("dh"); + +my $testcount = 3; + +plan tests => 2 * $testcount; + +SKIP: { + skip "TLS 1.3 is disabled", $testcount if disabled("tls1_3"); + # Run tests with TLS + run_tests(0); +} + +SKIP: { + skip "DTLS 1.3 is disabled", $testcount if disabled("dtls1_3"); + skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/; + run_tests(1); +} use constant { COOKIE_ONLY => 0, @@ -35,58 +51,76 @@ use constant { EMPTY_COOKIE => 2 }; -my $proxy = TLSProxy::Proxy->new( - undef, - cmdstr(app(["openssl"]), display => 1), - srctop_file("apps", "server.pem"), - (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), - have_IPv6() -); - my $cookieseen = 0; my $fatal_alert = 0; my $testtype; -#Test 1: Inserting a cookie into an HRR should see it echoed in the ClientHello -# (when a key share is required) -$testtype = COOKIE_AND_KEY_SHARE; -$proxy->filter(\&cookie_filter); -if (disabled("ecx")) { - $proxy->clientflags("-curves ffdhe3072:ffdhe2048"); - $proxy->serverflags("-curves ffdhe2048"); -} else { - $proxy->clientflags("-curves P-256:X25519"); - $proxy->serverflags("-curves X25519"); -} -$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 3; -ok(TLSProxy::Message->success() && $cookieseen == 1, "Cookie seen"); +sub run_tests +{ + my $run_test_as_dtls = shift; + my $proxy_start_success = 0; + my $proxy; + if ($run_test_as_dtls == 1) { + $proxy = TLSProxy::Proxy->new_dtls( + undef, + cmdstr(app([ "openssl" ]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } + else { + $proxy = TLSProxy::Proxy->new( + undef, + cmdstr(app([ "openssl" ]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } -#Test 2: Inserting a cookie into an HRR should see it echoed in the ClientHello -# (without a key share required) -SKIP: { - skip "ECX disabled", 1, if (disabled("ecx")); - $testtype = COOKIE_ONLY; + #Test 1: Inserting a cookie into an HRR should see it echoed in the ClientHello + # (when a key share is required) $proxy->clear(); - $proxy->serverflags("-curves X25519"); - $proxy->clientflags("-curves X25519:secp256r1"); - $proxy->start(); + $testtype = COOKIE_AND_KEY_SHARE; + $proxy->filter(\&cookie_filter); + if (disabled("ecx")) { + $proxy->clientflags("-curves ffdhe3072:ffdhe2048"); + $proxy->serverflags("-curves ffdhe2048"); + } else { + $proxy->clientflags("-curves P-256:X25519"); + $proxy->serverflags("-curves X25519"); + } + $proxy_start_success = $proxy->start(); + skip "TLSProxy did not start correctly", $testcount if $proxy_start_success == 0; ok(TLSProxy::Message->success() && $cookieseen == 1, "Cookie seen"); -} -#Test 3: A client should reject an empty cookie in an HRR -$testtype = EMPTY_COOKIE; -$fatal_alert = 0; -$proxy->clear(); -if (disabled("ecx")) { - $proxy->clientflags("-curves ffdhe3072:ffdhe2048"); - $proxy->serverflags("-curves ffdhe2048"); -} else { - $proxy->clientflags("-curves P-256:X25519"); - $proxy->serverflags("-curves X25519"); + #Test 2: Inserting a cookie into an HRR should see it echoed in the ClientHello + # (without a key share required) + SKIP: { + skip "ECX disabled", 1, if (disabled("ecx")); + $testtype = COOKIE_ONLY; + $proxy->clear(); + $proxy->serverflags("-curves X25519"); + $proxy->clientflags("-curves X25519:secp256r1"); + $proxy->start(); + ok(TLSProxy::Message->success() && $cookieseen == 1, "Cookie seen"); + } + + #Test 3: A client should reject an empty cookie in an HRR + $testtype = EMPTY_COOKIE; + $fatal_alert = 0; + $proxy->clear(); + if (disabled("ecx")) { + $proxy->clientflags("-curves ffdhe3072:ffdhe2048"); + $proxy->serverflags("-curves ffdhe2048"); + } else { + $proxy->clientflags("-curves P-256:X25519"); + $proxy->serverflags("-curves X25519"); + } + $proxy->start(); + ok($fatal_alert, "Empty cookie rejected"); } -$proxy->start(); -ok($fatal_alert, "Empty cookie rejected"); sub cookie_filter { diff --git a/test/recipes/70-test_tls13downgrade.t b/test/recipes/70-test_tls13downgrade.t index 7d750a292bc2f..036027e8a5b91 100644 --- a/test/recipes/70-test_tls13downgrade.t +++ b/test/recipes/70-test_tls13downgrade.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -24,20 +24,11 @@ plan skip_all => "$test_name needs the module feature enabled" plan skip_all => "$test_name needs the sock feature enabled" if disabled("sock"); -plan skip_all => "$test_name needs TLS1.3 and TLS1.2 enabled" - if disabled("tls1_3") || disabled("tls1_2") - || (disabled("ec") && disabled("dh")); +plan skip_all => "$test_name needs EC or DH enabled" + if disabled("ec") && disabled("dh"); $ENV{OPENSSL_MODULES} = abs_path(bldtop_dir("test")); -my $proxy = TLSProxy::Proxy->new( - undef, - cmdstr(app(["openssl"]), display => 1), - srctop_file("apps", "server.pem"), - (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), - have_IPv6() -); - use constant { DOWNGRADE_TO_TLS_1_2 => 0, DOWNGRADE_TO_TLS_1_1 => 1, @@ -46,80 +37,156 @@ use constant { DOWNGRADE_TO_TLS_1_1_WITH_TLS_1_2_SIGNAL => 4, }; -#Test 1: Downgrade from TLSv1.3 to TLSv1.2 -$proxy->filter(\&downgrade_filter); -my $testtype = DOWNGRADE_TO_TLS_1_2; -$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 8; -ok(is_illegal_parameter_client_alert(), "Downgrade TLSv1.3 to TLSv1.2"); - -#Test 2: Downgrade from TLSv1.3 to TLSv1.2 (server sends TLSv1.1 signal) -$proxy->clear(); -$testtype = DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL; -$proxy->start(); -ok(is_illegal_parameter_client_alert(), - "Downgrade from TLSv1.3 to TLSv1.2 (server sends TLSv1.1 signal)"); - -#Test 3: Client falls back from TLSv1.3 (server does not support the fallback -# SCSV) -$proxy->clear(); -$testtype = FALLBACK_FROM_TLS_1_3; -$proxy->clientflags("-fallback_scsv -no_tls1_3"); -$proxy->start(); -ok(is_illegal_parameter_client_alert(), "Fallback from TLSv1.3"); +my $testcount = 8; +plan tests => 2 * $testcount; + +my $testtype; SKIP: { - skip "TLSv1.1 disabled", 5 if disabled("tls1_1"); + skip "TLS 1.2 or 1.3 is disabled", $testcount if disabled("tls1_3") + || disabled("tls1_2"); + # Run tests with TLS + run_tests(0); +} - my $client_flags = "-min_protocol TLSv1.1 -cipher DEFAULT:\@SECLEVEL=0"; - my $server_flags = "-min_protocol TLSv1.1"; - my $ciphers = "AES128-SHA:\@SECLEVEL=0"; +SKIP: { + skip "DTLS 1.2 or 1.3 is disabled", $testcount if disabled("dtls1_3") + || disabled("dtls1_2"); + skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/; + run_tests(1); +} + +sub run_tests +{ + my $run_test_as_dtls = shift; + my $proto1_1 = $run_test_as_dtls == 1 ? "DTLSv1" : "TLSv1.1"; + my $proto1_2 = $run_test_as_dtls == 1 ? "DTLSv1.2" : "TLSv1.2"; + my $proto1_3 = $run_test_as_dtls == 1 ? "DTLSv1.3" : "TLSv1.3"; - #Test 4: Downgrade from TLSv1.3 to TLSv1.1 + my $proxy; + if ($run_test_as_dtls == 1) { + $proxy = TLSProxy::Proxy->new_dtls( + undef, + cmdstr(app([ "openssl" ]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } else { + $proxy = TLSProxy::Proxy->new( + undef, + cmdstr(app([ "openssl" ]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } + + my $client_flags = ""; + + if ($run_test_as_dtls == 1) { + # TLSProxy does not handle partial messages for DTLS. + if (disabled("ec")) { + $client_flags = $client_flags." -groups ffdhe2048:ffdhe3072"; + } else { + $client_flags = $client_flags." -groups P-256:P-384"; + } + } + + #Test 1: Downgrade from (D)TLSv1.3 to (D)TLSv1.2 $proxy->clear(); - $testtype = DOWNGRADE_TO_TLS_1_1; + $proxy->filter(\&downgrade_filter); $proxy->clientflags($client_flags); - $proxy->serverflags($server_flags); - $proxy->ciphers($ciphers); - $proxy->start(); - ok(is_illegal_parameter_client_alert(), "Downgrade TLSv1.3 to TLSv1.1"); + $testtype = DOWNGRADE_TO_TLS_1_2; + skip "Unable to start up Proxy for tests", $testcount if !$proxy->start() && !$run_test_as_dtls; + ok(is_illegal_parameter_client_alert(), "Downgrade ".$proto1_3." to ".$proto1_2); - #Test 5: Downgrade from TLSv1.3 to TLSv1.1 (server sends TLSv1.2 signal) + #Test 2: Downgrade from (D)TLSv1.3 to (D)TLSv1.2 (server sends (D)TLSv1.1 signal) $proxy->clear(); - $testtype = DOWNGRADE_TO_TLS_1_1_WITH_TLS_1_2_SIGNAL; + $testtype = DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL; $proxy->clientflags($client_flags); - $proxy->serverflags($server_flags); - $proxy->ciphers($ciphers); $proxy->start(); ok(is_illegal_parameter_client_alert(), - "Downgrade TLSv1.3 to TLSv1.1 (server sends TLSv1.2 signal)"); + "Downgrade from ".$proto1_3." to ".$proto1_2." (server sends ".$proto1_1." signal)"); - #Test 6: Downgrade from TLSv1.2 to TLSv1.1 + #Test 3: Client falls back from (D)TLSv1.3 (server does not support the + # fallback SCSV) $proxy->clear(); - $testtype = DOWNGRADE_TO_TLS_1_1; - $proxy->clientflags($client_flags." -max_protocol TLSv1.2"); - $proxy->serverflags($server_flags." -max_protocol TLSv1.2"); - $proxy->ciphers($ciphers); + $proxy->filter(\&downgrade_filter); + $testtype = FALLBACK_FROM_TLS_1_3; + $proxy->clientflags("-fallback_scsv -max_protocol ".$proto1_2); $proxy->start(); - ok(is_illegal_parameter_client_alert(), "Downgrade TLSv1.2 to TLSv1.1"); + ok(is_illegal_parameter_client_alert(), "Fallback from ".$proto1_3); - #Test 7: A client side protocol "hole" should not be detected as a downgrade - $proxy->clear(); - $proxy->filter(undef); - $proxy->clientflags($client_flags." -no_tls1_2"); - $proxy->serverflags($server_flags); - $proxy->ciphers($ciphers); - $proxy->start(); - ok(TLSProxy::Message->success(), "TLSv1.2 client-side protocol hole"); + $client_flags = "-min_protocol ".$proto1_1." -cipher DEFAULT:\@SECLEVEL=0"; + if ($run_test_as_dtls == 1) { + # TLSProxy does not handle partial messages for DTLS. + if (disabled("ec")) { + $client_flags = $client_flags." -groups ffdhe2048:ffdhe3072"; + } else { + $client_flags = $client_flags." -groups P-256:P-384"; + } + } + my $server_flags = "-min_protocol ".$proto1_1; + my $ciphers = "AES128-SHA:\@SECLEVEL=0"; - #Test 8: A server side protocol "hole" should not be detected as a downgrade - $proxy->clear(); - $proxy->filter(undef); - $proxy->clientflags($client_flags); - $proxy->serverflags($server_flags." -no_tls1_2"); - $proxy->ciphers($ciphers); - $proxy->start(); - ok(TLSProxy::Message->success(), "TLSv1.2 server-side protocol hole"); + SKIP: { + skip "TLSv1.1 disabled", 3 + if !$run_test_as_dtls && disabled("tls1_1"); + skip "DTLSv1 disabled", 3 + if $run_test_as_dtls == 1 && disabled("dtls1"); + + #Test 4: Downgrade from (D)TLSv1.3 to TLSv1.1/DTLSv1 + $proxy->clear(); + $testtype = DOWNGRADE_TO_TLS_1_1; + $proxy->clientflags($client_flags); + $proxy->serverflags($server_flags); + $proxy->ciphers($ciphers); + $proxy->start(); + ok(is_illegal_parameter_client_alert(), "Downgrade ".$proto1_3." to ".$proto1_1); + + #Test 5: Downgrade from (D)TLSv1.3 to TLSv1.1/DTLSv1 (server sends (D)TLSv1.2 signal) + $proxy->clear(); + $testtype = DOWNGRADE_TO_TLS_1_1_WITH_TLS_1_2_SIGNAL; + $proxy->clientflags($client_flags); + $proxy->serverflags($server_flags); + $proxy->ciphers($ciphers); + $proxy->start(); + ok(is_illegal_parameter_client_alert(), + "Downgrade ".$proto1_3." to ".$proto1_1." (server sends ".$proto1_2." signal)"); + + #Test 6: Downgrade from (D)TLSv1.2 to TLSv1.1/DTLSv1 + $proxy->clear(); + $testtype = DOWNGRADE_TO_TLS_1_1; + $proxy->clientflags($client_flags." -max_protocol ".$proto1_2); + $proxy->serverflags($server_flags." -max_protocol ".$proto1_2); + $proxy->ciphers($ciphers); + $proxy->start(); + ok(is_illegal_parameter_client_alert(), "Downgrade ".$proto1_2." to ".$proto1_1); + } + + SKIP: { + skip "TLSv1.1 disabled", 2 + if !$run_test_as_dtls && disabled("tls1_1"); + skip "Missing support for no_dtls1_2", 2 if $run_test_as_dtls == 1; + #Test 7: A client side protocol "hole" should not be detected as a downgrade + $proxy->clear(); + $proxy->filter(undef); + $proxy->clientflags($client_flags." -no_tls1_2"); + $proxy->serverflags($server_flags); + $proxy->ciphers($ciphers); + $proxy->start(); + ok(TLSProxy::Message->success(), $proto1_2." client-side protocol hole"); + + #Test 8: A server side protocol "hole" should not be detected as a downgrade + $proxy->clear(); + $proxy->filter(undef); + $proxy->clientflags($client_flags); + $proxy->serverflags($server_flags." -no_tls1_2"); + $proxy->ciphers($ciphers); + $proxy->start(); + ok(TLSProxy::Message->success(), $proto1_2." server-side protocol hole"); + } } # Validate that the exchange fails with an illegal parameter alert from @@ -138,15 +205,24 @@ sub downgrade_filter { my $proxy = shift; - # We're only interested in the initial ClientHello and ServerHello - if ($proxy->flight > 1) { + # We're only interested in the initial ClientHello except if we are expecting + # DTLS1.2 handshake in which case the client will send a second ClientHello + my $dtls12hs = $proxy->isdtls && ($testtype == FALLBACK_FROM_TLS_1_3 + || $testtype == DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL + || $testtype == DOWNGRADE_TO_TLS_1_1_WITH_TLS_1_2_SIGNAL + || $testtype == DOWNGRADE_TO_TLS_1_1 + || $testtype == DOWNGRADE_TO_TLS_1_2); + my $client_hello = $proxy->flight == 0 || ($dtls12hs && $proxy->flight == 2); + my $server_hello = ($dtls12hs && $proxy->flight == 3) + || (!$dtls12hs && $proxy->flight == 1); + + if (!$server_hello && !$client_hello) { return; } my $message = ${$proxy->message_list}[$proxy->flight]; - # ServerHello - if ($proxy->flight == 1 && defined($message)) { + if ($server_hello == 1 && defined($message)) { # Update the last byte of the downgrade signal if ($testtype == DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL) { $message->random(substr($message->random, 0, 31) . "\0"); @@ -160,25 +236,28 @@ sub downgrade_filter } # ClientHello - if ($proxy->flight == 0) { - my $ext; + if ($client_hello == 1) { if ($testtype == FALLBACK_FROM_TLS_1_3) { #The default ciphersuite we use for TLSv1.2 without any SCSV my @ciphersuites = (TLSProxy::Message::CIPHER_RSA_WITH_AES_128_CBC_SHA); $message->ciphersuite_len(2 * scalar @ciphersuites); $message->ciphersuites(\@ciphersuites); - } - else { + } else { + my $ext; + my $version12hi = $proxy->isdtls == 1 ? 0xFE : 0x03; + my $version12lo = $proxy->isdtls == 1 ? 0xFD : 0x03; + my $version11hi = $proxy->isdtls == 1 ? 0xFE : 0x03; + my $version11lo = $proxy->isdtls == 1 ? 0xFF : 0x02; + if ($testtype == DOWNGRADE_TO_TLS_1_2 || $testtype == DOWNGRADE_TO_TLS_1_2_WITH_TLS_1_1_SIGNAL) { $ext = pack "C3", - 0x02, # Length - 0x03, 0x03; #TLSv1.2 - } - else { + 0x02, # Length + $version12hi, $version12lo; + } else { $ext = pack "C3", - 0x02, # Length - 0x03, 0x02; #TLSv1.1 + 0x02, # Length + $version11hi, $version11lo; } $message->set_extension(TLSProxy::Message::EXT_SUPPORTED_VERSIONS, diff --git a/test/recipes/70-test_tls13hrr.t b/test/recipes/70-test_tls13hrr.t index c6138b6d299c1..d5c7d734fec5f 100644 --- a/test/recipes/70-test_tls13hrr.t +++ b/test/recipes/70-test_tls13hrr.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2017-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -25,18 +25,14 @@ plan skip_all => "$test_name needs the module feature enabled" plan skip_all => "$test_name needs the sock feature enabled" if disabled("sock"); -plan skip_all => "$test_name needs TLS1.3 enabled" - if disabled("tls1_3") || (disabled("ec") && disabled("dh")); +plan skip_all => "$test_name needs elliptic curves or diffie-hellman enabled" + if disabled("ec") && disabled("dh"); $ENV{OPENSSL_MODULES} = abs_path(bldtop_dir("test")); -my $proxy = TLSProxy::Proxy->new( - undef, - cmdstr(app(["openssl"]), display => 1), - srctop_file("apps", "server.pem"), - (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), - have_IPv6() -); +my $testcount = 5; + +plan tests => 2 * $testcount; use constant { CHANGE_HRR_CIPHERSUITE => 0, @@ -46,75 +42,142 @@ use constant { NO_SUPPORTED_VERSIONS => 4 }; -#Test 1: A client should fail if the server changes the ciphersuite between the -# HRR and the SH -$proxy->filter(\&hrr_filter); -if (disabled("ec")) { - $proxy->serverflags("-curves ffdhe3072"); -} else { - $proxy->serverflags("-curves P-256"); -} -my $testtype = CHANGE_HRR_CIPHERSUITE; -$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 5; -ok(TLSProxy::Message->fail(), "Server ciphersuite changes"); - -#Test 2: It is an error if the client changes the offered ciphersuites so that -# we end up selecting a different ciphersuite between HRR and the SH -$proxy->clear(); -if (disabled("ec")) { - $proxy->serverflags("-curves ffdhe3072"); -} else { - $proxy->serverflags("-curves P-384"); -} -$proxy->ciphersuitess("TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384"); -$testtype = CHANGE_CH1_CIPHERSUITE; -$proxy->start(); -ok(TLSProxy::Message->fail(), "Client ciphersuite changes"); - -#Test 3: A client should fail with unexpected_message alert if the server -# sends more than 1 HRR my $fatal_alert = 0; -$proxy->clear(); -if (disabled("ec")) { - $proxy->serverflags("-curves ffdhe3072"); -} else { - $proxy->serverflags("-curves P-384"); +my $testtype = -1; + +SKIP: { + skip "TLS 1.3 is disabled", $testcount if disabled("tls1_3"); + # Run tests with TLS + run_tests(0); } -$testtype = DUPLICATE_HRR; -$proxy->start(); -ok($fatal_alert, "Server duplicated HRR"); - -#Test 4: If the client sends a group that is in the supported_groups list but -# otherwise not valid (e.g. not suitable for TLSv1.3) we should reject it -# and not consider it when sending the HRR. We send brainpoolP512r1 in -# the ClientHello, which is acceptable to the server but is not valid in -# TLSv1.3. We expect the server to select P-521 in the HRR and the -# handshake to complete successfully + SKIP: { - skip "EC/TLSv1.2 is disabled in this build", 1 - if disabled("ec") || disabled("tls1_2"); + skip "DTLS 1.3 is disabled", $testcount if disabled("dtls1_3"); + skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/; + run_tests(1); +} + +sub run_tests +{ + my $run_test_as_dtls = shift; + my $proxy; + if ($run_test_as_dtls == 1) { + $proxy = TLSProxy::Proxy->new_dtls( + \&hrr_filter, + cmdstr(app([ "openssl" ]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } else { + $proxy = TLSProxy::Proxy->new( + \&hrr_filter, + cmdstr(app([ "openssl" ]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } + + #Test 1: A client should fail if the server changes the ciphersuite between the + # HRR and the SH + $proxy->clear(); + if (disabled("ec")) { + $proxy->serverflags("-curves ffdhe3072"); + if ($run_test_as_dtls == 1) { + $proxy->clientflags("-groups ffdhe2048:ffdhe3072"); + } + } else { + $proxy->serverflags("-curves P-256"); + if ($run_test_as_dtls == 1) { + $proxy->clientflags("-groups P-384:P-256"); + } + } + $testtype = CHANGE_HRR_CIPHERSUITE; + # Skip tests if TLSProxy if it fails to start. + skip "TLSProxy did not start correctly", $testcount if $proxy->start() == 0; + ok(TLSProxy::Message->fail(), "Server ciphersuite changes"); + + #Test 2: It is an error if the client changes the offered ciphersuites so that + # we end up selecting a different ciphersuite between HRR and the SH $proxy->clear(); - $proxy->clientflags("-groups P-256:brainpoolP512r1:P-521"); - $proxy->serverflags("-groups brainpoolP512r1:P-521"); - $testtype = INVALID_GROUP; + if (disabled("ec")) { + $proxy->serverflags("-curves ffdhe3072"); + if ($run_test_as_dtls == 1) { + $proxy->clientflags("-groups ffdhe2048:ffdhe3072"); + } + } else { + $proxy->serverflags("-curves P-384"); + if ($run_test_as_dtls == 1) { + $proxy->clientflags("-groups P-256:P-384"); + } + } + $proxy->ciphersuitess("TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384"); + $testtype = CHANGE_CH1_CIPHERSUITE; $proxy->start(); - ok(TLSProxy::Message->success(), "Invalid group with HRR"); -} + ok(TLSProxy::Message->fail(), "Client ciphersuite changes"); + + #Test 3: A client should fail with unexpected_message alert if the server + # sends more than 1 HRR + $fatal_alert = 0; + $proxy->clear(); + if (disabled("ec")) { + $proxy->serverflags("-curves ffdhe3072"); + if ($run_test_as_dtls == 1) { + $proxy->clientflags("-groups ffdhe2048:ffdhe3072"); + } + } else { + $proxy->serverflags("-curves P-384"); + if ($run_test_as_dtls == 1) { + $proxy->clientflags("-groups P-256:P-384"); + } + } + $testtype = DUPLICATE_HRR; + $proxy->start(); + + # DTLS 1.3 will silent drop a duplicate HRR Record + # This happens in dtls_get_more_records() in dtls_meth.c + # after the call to dtls_record_replay_check() + if ($run_test_as_dtls == 1) { + ok(TLSProxy::Message->success(), "DTLS ignores duplicate HRR"); + } else { + ok($fatal_alert, "Server duplicated HRR"); + } + -#Test 5: A failure should occur if an HRR is sent without the supported_versions -# extension -$fatal_alert = 0; -$proxy->clear(); -if (disabled("ec")) { - $proxy->serverflags("-curves ffdhe3072"); -} else { - $proxy->serverflags("-curves P-384"); + #Test 4: If the client sends a group that is in the supported_groups list but + # otherwise not valid (e.g. not suitable for TLSv1.3) we should reject it + # and not consider it when sending the HRR. We send brainpoolP512r1 in + # the ClientHello, which is acceptable to the server but is not valid in + # TLSv1.3. We expect the server to select P-521 in the HRR and the + # handshake to complete successfully + SKIP: { + skip "EC/(D)TLSv1.2 is disabled in this build", 1 + if disabled("ec") || ($run_test_as_dtls == 0 && disabled("tls1_2")) + || ($run_test_as_dtls == 1 && disabled("dtls1_2")); + + $proxy->clear(); + $proxy->clientflags("-groups P-256:brainpoolP512r1:P-521"); + $proxy->serverflags("-groups brainpoolP512r1:P-521"); + $testtype = INVALID_GROUP; + $proxy->start(); + ok(TLSProxy::Message->success(), "Invalid group with HRR"); + } + + #Test 5: A failure should occur if an HRR is sent without the supported_versions + # extension + $fatal_alert = 0; + $proxy->clear(); + if (disabled("ec")) { + $proxy->serverflags("-curves ffdhe3072"); + } else { + $proxy->serverflags("-curves P-384"); + } + $testtype = NO_SUPPORTED_VERSIONS; + $proxy->start(); + ok($fatal_alert, "supported_versions missing from HRR"); } -$testtype = NO_SUPPORTED_VERSIONS; -$proxy->start(); -ok($fatal_alert, "supported_versions missing from HRR"); sub hrr_filter { @@ -173,14 +236,36 @@ sub hrr_filter next; } my $hrr_record = ${$proxy->record_list}[$i]; - my $dup_hrr = TLSProxy::Record->new(3, - $hrr_record->content_type(), - $hrr_record->version(), - $hrr_record->len(), - $hrr_record->len_real(), - $hrr_record->decrypt_len(), - $hrr_record->data(), - $hrr_record->decrypt_data()); + + my $dup_hrr; + + if ($proxy->isdtls()) { + $dup_hrr = TLSProxy::Record->new_dtls( + 1, + 3, + $hrr_record->content_type(), + $hrr_record->version(), + $hrr_record->epoch(), + $hrr_record->seq(), + $hrr_record->len(), + $hrr_record->len_real(), + $hrr_record->decrypt_len(), + $hrr_record->data(), + $hrr_record->decrypt_data()); + $dup_hrr->encrypted($hrr_record->encrypted()); + $dup_hrr->outer_content_type($hrr_record->outer_content_type()); + } else { + $dup_hrr = TLSProxy::Record->new( + 1, + 3, + $hrr_record->content_type(), + $hrr_record->version(), + $hrr_record->len(), + $hrr_record->len_real(), + $hrr_record->decrypt_len(), + $hrr_record->data(), + $hrr_record->decrypt_data()); + } $i++; splice @{$proxy->record_list}, $i, 0, $dup_hrr; diff --git a/test/recipes/70-test_tls13kexmodes.t b/test/recipes/70-test_tls13kexmodes.t index 685adcd5a966b..fab2505ad44a8 100644 --- a/test/recipes/70-test_tls13kexmodes.t +++ b/test/recipes/70-test_tls13kexmodes.t @@ -32,6 +32,9 @@ plan skip_all => "$test_name needs TLSv1.3 enabled" plan skip_all => "$test_name needs EC enabled" if disabled("ec"); +plan skip_all => "$test_name needs ECX enabled" + if disabled("ecx"); + @handmessages = ( [TLSProxy::Message::MT_CLIENT_HELLO, checkhandshake::ALL_HANDSHAKES], @@ -60,123 +63,130 @@ plan skip_all => "$test_name needs EC enabled" [0, 0] ); -@extensions = ( - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME, - TLSProxy::Message::CLIENT, - checkhandshake::SERVER_NAME_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST, - TLSProxy::Message::CLIENT, - checkhandshake::STATUS_REQUEST_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - (disabled("tls1_2") ? () : - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS, +sub setup_extensions +{ + my $run_test_as_dtls = shift; + my $v12_enabled = ($run_test_as_dtls == 0 && !disabled("tls1_2")) + || ($run_test_as_dtls == 1 && !disabled("dtls1_2")); + + @extensions = ( + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME, TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS]), - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN, - TLSProxy::Message::CLIENT, - checkhandshake::ALPN_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT, - TLSProxy::Message::CLIENT, - checkhandshake::SCT_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES, - TLSProxy::Message::CLIENT, - checkhandshake::PSK_KEX_MODES_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK, - TLSProxy::Message::CLIENT, - checkhandshake::PSK_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_RENEGOTIATE, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - - [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, - TLSProxy::Message::SERVER, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE, - TLSProxy::Message::SERVER, - checkhandshake::KEY_SHARE_HRR_EXTENSION], - - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME, - TLSProxy::Message::CLIENT, - checkhandshake::SERVER_NAME_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST, - TLSProxy::Message::CLIENT, - checkhandshake::STATUS_REQUEST_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - (disabled("tls1_2") ? () : - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS, + checkhandshake::SERVER_NAME_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST, TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS]), - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN, - TLSProxy::Message::CLIENT, - checkhandshake::ALPN_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT, - TLSProxy::Message::CLIENT, - checkhandshake::SCT_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES, - TLSProxy::Message::CLIENT, - checkhandshake::PSK_KEX_MODES_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK, - TLSProxy::Message::CLIENT, - checkhandshake::PSK_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_RENEGOTIATE, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - - [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, - TLSProxy::Message::SERVER, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE, - TLSProxy::Message::SERVER, - checkhandshake::KEY_SHARE_SRV_EXTENSION], - [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_PSK, - TLSProxy::Message::SERVER, - checkhandshake::PSK_SRV_EXTENSION], - - [TLSProxy::Message::MT_CERTIFICATE, TLSProxy::Message::EXT_STATUS_REQUEST, - TLSProxy::Message::SERVER, - checkhandshake::STATUS_REQUEST_SRV_EXTENSION], - [0,0,0,0] -); + checkhandshake::STATUS_REQUEST_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + ($v12_enabled ? + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS] : ()), + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN, + TLSProxy::Message::CLIENT, + checkhandshake::ALPN_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT, + TLSProxy::Message::CLIENT, + checkhandshake::SCT_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES, + TLSProxy::Message::CLIENT, + checkhandshake::PSK_KEX_MODES_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK, + TLSProxy::Message::CLIENT, + checkhandshake::PSK_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_RENEGOTIATE, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + + [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, + TLSProxy::Message::SERVER, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE, + TLSProxy::Message::SERVER, + checkhandshake::KEY_SHARE_HRR_EXTENSION], + + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME, + TLSProxy::Message::CLIENT, + checkhandshake::SERVER_NAME_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST, + TLSProxy::Message::CLIENT, + checkhandshake::STATUS_REQUEST_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + ($v12_enabled ? + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS] : ()), + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN, + TLSProxy::Message::CLIENT, + checkhandshake::ALPN_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT, + TLSProxy::Message::CLIENT, + checkhandshake::SCT_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES, + TLSProxy::Message::CLIENT, + checkhandshake::PSK_KEX_MODES_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK, + TLSProxy::Message::CLIENT, + checkhandshake::PSK_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_RENEGOTIATE, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + + [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, + TLSProxy::Message::SERVER, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE, + TLSProxy::Message::SERVER, + checkhandshake::KEY_SHARE_SRV_EXTENSION], + [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_PSK, + TLSProxy::Message::SERVER, + checkhandshake::PSK_SRV_EXTENSION], + + [TLSProxy::Message::MT_CERTIFICATE, TLSProxy::Message::EXT_STATUS_REQUEST, + TLSProxy::Message::SERVER, + checkhandshake::STATUS_REQUEST_SRV_EXTENSION], + [0,0,0,0] + ); +} use constant { DELETE_EXTENSION => 0, @@ -186,197 +196,241 @@ use constant { UNKNOWN_KEX_MODES => 4, BOTH_KEX_MODES => 5 }; +my $testcount = 13; $ENV{OPENSSL_MODULES} = abs_path(bldtop_dir("test")); -my $proxy = TLSProxy::Proxy->new( - undef, - cmdstr(app(["openssl"]), display => 1), - srctop_file("apps", "server.pem"), - (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), - have_IPv6() -); +plan tests => 2 * $testcount; + +SKIP: { + skip "TLS 1.3 is disabled", $testcount if disabled("tls1_3"); + # Run tests with TLS + run_tests(0); +} + +SKIP: { + skip "DTLS 1.3 is disabled", $testcount if disabled("dtls1_3"); + skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/; + run_tests(1); +} + +my $testtype = -1; -#Test 1: First get a session -(undef, my $session) = tempfile(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -sess_out ".$session); -$proxy->serverflags("-no_rx_cert_comp -servername localhost"); -$proxy->sessionfile($session); -$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 13; -ok(TLSProxy::Message->success(), "Initial connection"); - -#Test 2: Attempt a resume with no kex modes extension. Should fail (server -# MUST abort handshake with pre_shared key and no psk_kex_modes) -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session); -my $testtype = DELETE_EXTENSION; -$proxy->filter(\&modify_kex_modes_filter); -$proxy->start(); -ok(TLSProxy::Message->fail(), "Resume with no kex modes"); - -#Test 3: Attempt a resume with empty kex modes extension. Should fail (empty -# extension is invalid) -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session); -$testtype = EMPTY_EXTENSION; -$proxy->start(); -ok(TLSProxy::Message->fail(), "Resume with empty kex modes"); - -#Test 4: Attempt a resume with non-dhe kex mode only. Should resume without a -# key_share -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in ".$session); -$proxy->serverflags("-no_rx_cert_comp -allow_no_dhe_kex"); -$testtype = NON_DHE_KEX_MODE_ONLY; -$proxy->start(); -checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::PSK_KEX_MODES_EXTENSION - | checkhandshake::PSK_CLI_EXTENSION - | checkhandshake::PSK_SRV_EXTENSION, - "Resume with non-dhe kex mode"); - -#Test 5: Attempt a resume with dhe kex mode only. Should resume with a key_share -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session); -$testtype = DHE_KEX_MODE_ONLY; -$proxy->start(); -checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::PSK_KEX_MODES_EXTENSION - | checkhandshake::KEY_SHARE_SRV_EXTENSION - | checkhandshake::PSK_CLI_EXTENSION - | checkhandshake::PSK_SRV_EXTENSION, - "Resume with non-dhe kex mode"); - -#Test 6: Attempt a resume with only unrecognised kex modes. Should not resume -# but rather fall back to full handshake -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session); -$testtype = UNKNOWN_KEX_MODES; -$proxy->start(); -checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::PSK_KEX_MODES_EXTENSION - | checkhandshake::KEY_SHARE_SRV_EXTENSION - | checkhandshake::PSK_CLI_EXTENSION, - "Resume with unrecognized kex mode"); - -#Test 7: Attempt a resume with both, non-dhe and dhe kex mode. Should resume with -# a key_share, even though non-dhe is allowed, but not explicitly preferred. -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in ".$session); -$proxy->serverflags("-allow_no_dhe_kex"); -$testtype = BOTH_KEX_MODES; -$proxy->start(); -checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::PSK_KEX_MODES_EXTENSION - | checkhandshake::KEY_SHARE_SRV_EXTENSION - | checkhandshake::PSK_CLI_EXTENSION - | checkhandshake::PSK_SRV_EXTENSION, - "Resume with both kex modes"); - -#Test 8: Attempt a resume with both, non-dhe and dhe kex mode, but with server-side -# preference for non-dhe. Should resume without a key_share. -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in ".$session); -$proxy->serverflags("-allow_no_dhe_kex -prefer_no_dhe_kex"); -$testtype = BOTH_KEX_MODES; -$proxy->start(); -checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::PSK_KEX_MODES_EXTENSION - | checkhandshake::PSK_CLI_EXTENSION - | checkhandshake::PSK_SRV_EXTENSION, - "Resume with both kex modes, preference for non-dhe"); - -#Test 9: Attempt a resume with both, non-dhe and dhe kex mode, with server-side -# preference for non-dhe, but non-dhe not allowed. Should resume with a key_share. -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -sess_in ".$session); -$proxy->serverflags("-prefer_no_dhe_kex"); -$testtype = BOTH_KEX_MODES; -$proxy->start(); -checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::PSK_KEX_MODES_EXTENSION - | checkhandshake::KEY_SHARE_SRV_EXTENSION - | checkhandshake::PSK_CLI_EXTENSION - | checkhandshake::PSK_SRV_EXTENSION, - "Resume with both kex modes, preference for but disabled non-dhe"); - -#Test 10: Attempt a resume with both non-dhe and dhe kex mode, but unacceptable -# initial key_share. Should resume with a key_share following an HRR -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session); -$proxy->serverflags("-no_rx_cert_comp -curves P-384"); -$testtype = BOTH_KEX_MODES; -$proxy->start(); -checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::PSK_KEX_MODES_EXTENSION - | checkhandshake::KEY_SHARE_SRV_EXTENSION - | checkhandshake::KEY_SHARE_HRR_EXTENSION - | checkhandshake::PSK_CLI_EXTENSION - | checkhandshake::PSK_SRV_EXTENSION, - "Resume with both kex modes and HRR"); - -#Test 11: Attempt a resume with dhe kex mode only and an unacceptable initial -# key_share. Should resume with a key_share following an HRR -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session); -$proxy->serverflags("-no_rx_cert_comp -curves P-384"); -$testtype = DHE_KEX_MODE_ONLY; -$proxy->start(); -checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::PSK_KEX_MODES_EXTENSION - | checkhandshake::KEY_SHARE_SRV_EXTENSION - | checkhandshake::KEY_SHARE_HRR_EXTENSION - | checkhandshake::PSK_CLI_EXTENSION - | checkhandshake::PSK_SRV_EXTENSION, - "Resume with dhe kex mode and HRR"); - -#Test 12: Attempt a resume with both non-dhe and dhe kex mode, unacceptable -# initial key_share and no overlapping groups. Should resume without a -# key_share -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -curves P-384 -sess_in ".$session); -$proxy->serverflags("-no_rx_cert_comp -allow_no_dhe_kex -curves P-256"); -$testtype = BOTH_KEX_MODES; -$proxy->start(); -checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::PSK_KEX_MODES_EXTENSION - | checkhandshake::PSK_CLI_EXTENSION - | checkhandshake::PSK_SRV_EXTENSION, - "Resume with both kex modes, no overlapping groups"); - -#Test 13: Attempt a resume with dhe kex mode only, unacceptable -# initial key_share and no overlapping groups. Should fail -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -curves P-384 -sess_in ".$session); -$proxy->serverflags("-no_rx_cert_comp -curves P-256"); -$testtype = DHE_KEX_MODE_ONLY; -$proxy->start(); -ok(TLSProxy::Message->fail(), "Resume with dhe kex mode, no overlapping groups"); - -unlink $session; +sub run_tests +{ + my $run_test_as_dtls = shift; + my $proxy_start_success = 0; + + # Setup extensions based on whether we're testing TLS or DTLS + setup_extensions($run_test_as_dtls); + + (undef, my $session) = tempfile(); + my $proxy; + if ($run_test_as_dtls == 1) { + $proxy = TLSProxy::Proxy->new_dtls( + undef, + cmdstr(app([ "openssl" ]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } + else { + $proxy = TLSProxy::Proxy->new( + undef, + cmdstr(app([ "openssl" ]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } + + $proxy->clear(); + + #Test 1: First get a session + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-curves P-256:P-384:X25519:X448 -no_rx_cert_comp -sess_out " . $session); + $proxy->serverflags("-curves P-256:P-384:X25519:X448 -no_rx_cert_comp -servername localhost"); + $proxy->sessionfile($session); + $proxy_start_success = $proxy->start(); + skip "TLSProxy did not start correctly", $testcount if $proxy_start_success == 0; + ok(TLSProxy::Message->success(), "Initial connection"); + + #Test 2: Attempt a resume with no kex modes extension. Should fail (server + # MUST abort handshake with pre_shared key and no psk_kex_modes) + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-curves P-256:P-384:X25519:X448 -no_rx_cert_comp -sess_in " . $session); + $proxy->serverflags("-curves P-256:P-384:X25519:X448"); + $testtype = DELETE_EXTENSION; + $proxy->filter(\&modify_kex_modes_filter); + $proxy->start(); + ok(TLSProxy::Message->fail(), "Resume with no kex modes"); + + #Test 3: Attempt a resume with empty kex modes extension. Should fail (empty + # extension is invalid) + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-curves P-256:P-384:X25519:X448 -no_rx_cert_comp -sess_in " . $session); + $proxy->serverflags("-curves P-256:P-384:X25519:X448"); + $testtype = EMPTY_EXTENSION; + $proxy->start(); + ok(TLSProxy::Message->fail(), "Resume with empty kex modes"); + + #Test 4: Attempt a resume with non-dhe kex mode only. Should resume without a + # key_share + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-curves P-256:P-384:X25519:X448 -no_rx_cert_comp -allow_no_dhe_kex -sess_in " . $session); + $proxy->serverflags("-curves P-256:P-384:X25519:X448 -no_rx_cert_comp -allow_no_dhe_kex"); + $testtype = NON_DHE_KEX_MODE_ONLY; + $proxy->start(); + checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::PSK_KEX_MODES_EXTENSION + | checkhandshake::PSK_CLI_EXTENSION + | checkhandshake::PSK_SRV_EXTENSION, + "Resume with non-dhe kex mode"); + + #Test 5: Attempt a resume with dhe kex mode only. Should resume with a key_share + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-curves P-256:P-384:X25519:X448 -no_rx_cert_comp -sess_in " . $session); + $proxy->serverflags("-curves P-256:P-384:X25519:X448"); + $testtype = DHE_KEX_MODE_ONLY; + $proxy->start(); + checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::PSK_KEX_MODES_EXTENSION + | checkhandshake::KEY_SHARE_SRV_EXTENSION + | checkhandshake::PSK_CLI_EXTENSION + | checkhandshake::PSK_SRV_EXTENSION, + "Resume with non-dhe kex mode"); + + #Test 6: Attempt a resume with only unrecognised kex modes. Should not resume + # but rather fall back to full handshake + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-curves P-256:P-384:X25519:X448 -no_rx_cert_comp -sess_in " . $session); + $proxy->serverflags("-curves P-256:P-384:X25519:X448"); + $testtype = UNKNOWN_KEX_MODES; + $proxy->start(); + checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::PSK_KEX_MODES_EXTENSION + | checkhandshake::KEY_SHARE_SRV_EXTENSION + | checkhandshake::PSK_CLI_EXTENSION, + "Resume with unrecognized kex mode"); + + #Test 7: Attempt a resume with both, non-dhe and dhe kex mode. Should resume with + # a key_share, even though non-dhe is allowed, but not explicitly preferred. + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-curves P-256:P-384:X25519:X448 -no_rx_cert_comp -allow_no_dhe_kex -sess_in " . $session); + $proxy->serverflags("-curves P-256:P-384:X25519:X448 -allow_no_dhe_kex"); + $testtype = BOTH_KEX_MODES; + $proxy->start(); + checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::PSK_KEX_MODES_EXTENSION + | checkhandshake::KEY_SHARE_SRV_EXTENSION + | checkhandshake::PSK_CLI_EXTENSION + | checkhandshake::PSK_SRV_EXTENSION, + "Resume with both kex modes"); + + #Test 8: Attempt a resume with both, non-dhe and dhe kex mode, but with server-side + # preference for non-dhe. Should resume without a key_share. + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-curves P-256:P-384:X25519:X448 -no_rx_cert_comp -allow_no_dhe_kex -sess_in " . $session); + $proxy->serverflags("-curves P-256:P-384:X25519:X448 -allow_no_dhe_kex -prefer_no_dhe_kex"); + $testtype = BOTH_KEX_MODES; + $proxy->start(); + checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::PSK_KEX_MODES_EXTENSION + | checkhandshake::PSK_CLI_EXTENSION + | checkhandshake::PSK_SRV_EXTENSION, + "Resume with both kex modes, preference for non-dhe"); + + #Test 9: Attempt a resume with both, non-dhe and dhe kex mode, with server-side + # preference for non-dhe, but non-dhe not allowed. Should resume with a key_share. + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-curves P-256:P-384:X25519:X448 -no_rx_cert_comp -allow_no_dhe_kex -sess_in " . $session); + $proxy->serverflags("-curves P-256:P-384:X25519:X448 -prefer_no_dhe_kex"); + $testtype = BOTH_KEX_MODES; + $proxy->start(); + checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::PSK_KEX_MODES_EXTENSION + | checkhandshake::KEY_SHARE_SRV_EXTENSION + | checkhandshake::PSK_CLI_EXTENSION + | checkhandshake::PSK_SRV_EXTENSION, + "Resume with both kex modes, preference for but disabled non-dhe"); + + #Test 10: Attempt a resume with both non-dhe and dhe kex mode, but unacceptable + # initial key_share. Should resume with a key_share following an HRR + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-curves P-256:P-384:X25519:X448 -no_rx_cert_comp -sess_in " . $session); + $proxy->serverflags("-no_rx_cert_comp -curves P-384"); + $testtype = BOTH_KEX_MODES; + $proxy->start(); + checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::PSK_KEX_MODES_EXTENSION + | checkhandshake::KEY_SHARE_SRV_EXTENSION + | checkhandshake::KEY_SHARE_HRR_EXTENSION + | checkhandshake::PSK_CLI_EXTENSION + | checkhandshake::PSK_SRV_EXTENSION, + "Resume with both kex modes and HRR"); + + #Test 11: Attempt a resume with dhe kex mode only and an unacceptable initial + # key_share. Should resume with a key_share following an HRR + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-curves P-256:P-384:X25519:X448 -no_rx_cert_comp -sess_in " . $session); + $proxy->serverflags("-no_rx_cert_comp -curves P-384"); + $testtype = DHE_KEX_MODE_ONLY; + $proxy->start(); + checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::PSK_KEX_MODES_EXTENSION + | checkhandshake::KEY_SHARE_SRV_EXTENSION + | checkhandshake::KEY_SHARE_HRR_EXTENSION + | checkhandshake::PSK_CLI_EXTENSION + | checkhandshake::PSK_SRV_EXTENSION, + "Resume with dhe kex mode and HRR"); + + #Test 12: Attempt a resume with both non-dhe and dhe kex mode, unacceptable + # initial key_share and no overlapping groups. Should resume without a + # key_share + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-no_rx_cert_comp -allow_no_dhe_kex -curves P-384 -sess_in " . $session); + $proxy->serverflags("-no_rx_cert_comp -allow_no_dhe_kex -curves P-256"); + $testtype = BOTH_KEX_MODES; + $proxy->start(); + checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::PSK_KEX_MODES_EXTENSION + | checkhandshake::PSK_CLI_EXTENSION + | checkhandshake::PSK_SRV_EXTENSION, + "Resume with both kex modes, no overlapping groups"); + + #Test 13: Attempt a resume with dhe kex mode only, unacceptable + # initial key_share and no overlapping groups. Should fail + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-no_rx_cert_comp -curves P-384 -sess_in " . $session); + $proxy->serverflags("-no_rx_cert_comp -curves P-256"); + $testtype = DHE_KEX_MODE_ONLY; + $proxy->start(); + ok(TLSProxy::Message->fail(), "Resume with dhe kex mode, no overlapping groups"); + + unlink $session; +} sub modify_kex_modes_filter { diff --git a/test/recipes/70-test_tls13messages.t b/test/recipes/70-test_tls13messages.t index b2e356763c0ab..df47080eb8489 100644 --- a/test/recipes/70-test_tls13messages.t +++ b/test/recipes/70-test_tls13messages.t @@ -26,9 +26,6 @@ plan skip_all => "$test_name needs the module feature enabled" plan skip_all => "$test_name needs the sock feature enabled" if disabled("sock"); -plan skip_all => "$test_name needs TLSv1.3 enabled" - if disabled("tls1_3"); - plan skip_all => "$test_name needs EC enabled" if disabled("ec"); @@ -60,399 +57,472 @@ plan skip_all => "$test_name needs EC enabled" [0, 0] ); -@extensions = ( - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME, - TLSProxy::Message::CLIENT, - checkhandshake::SERVER_NAME_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST, - TLSProxy::Message::CLIENT, - checkhandshake::STATUS_REQUEST_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - (disabled("tls1_2") ? () : - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS, +sub setup_extensions +{ + my $run_test_as_dtls = shift; + my $v12_enabled = ($run_test_as_dtls == 0 && !disabled("tls1_2")) + || ($run_test_as_dtls == 1 && !disabled("dtls1_2")); + + @extensions = ( + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME, TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS]), - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN, - TLSProxy::Message::CLIENT, - checkhandshake::ALPN_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT, - TLSProxy::Message::CLIENT, - checkhandshake::SCT_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK, - TLSProxy::Message::CLIENT, - checkhandshake::PSK_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_POST_HANDSHAKE_AUTH, - TLSProxy::Message::CLIENT, - checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_RENEGOTIATE, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - - [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, - TLSProxy::Message::SERVER, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE, - TLSProxy::Message::SERVER, - checkhandshake::KEY_SHARE_HRR_EXTENSION], - - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME, - TLSProxy::Message::CLIENT, - checkhandshake::SERVER_NAME_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST, - TLSProxy::Message::CLIENT, - checkhandshake::STATUS_REQUEST_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - (disabled("tls1_2") ? () : - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS, + checkhandshake::SERVER_NAME_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST, TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS]), - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN, - TLSProxy::Message::CLIENT, - checkhandshake::ALPN_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT, - TLSProxy::Message::CLIENT, - checkhandshake::SCT_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK, - TLSProxy::Message::CLIENT, - checkhandshake::PSK_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_POST_HANDSHAKE_AUTH, - TLSProxy::Message::CLIENT, - checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION], - [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_RENEGOTIATE, - TLSProxy::Message::CLIENT, - checkhandshake::DEFAULT_EXTENSIONS], - - [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, - TLSProxy::Message::SERVER, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE, - TLSProxy::Message::SERVER, - checkhandshake::DEFAULT_EXTENSIONS], - [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_PSK, - TLSProxy::Message::SERVER, - checkhandshake::PSK_SRV_EXTENSION], - - [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_SERVER_NAME, - TLSProxy::Message::SERVER, - checkhandshake::SERVER_NAME_SRV_EXTENSION], - [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_ALPN, - TLSProxy::Message::SERVER, - checkhandshake::ALPN_SRV_EXTENSION], - [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_SUPPORTED_GROUPS, - TLSProxy::Message::SERVER, - checkhandshake::SUPPORTED_GROUPS_SRV_EXTENSION], - - [TLSProxy::Message::MT_CERTIFICATE_REQUEST, TLSProxy::Message::EXT_SIG_ALGS, - TLSProxy::Message::SERVER, - checkhandshake::DEFAULT_EXTENSIONS], - - [TLSProxy::Message::MT_CERTIFICATE, TLSProxy::Message::EXT_STATUS_REQUEST, - TLSProxy::Message::SERVER, - checkhandshake::STATUS_REQUEST_SRV_EXTENSION], - [TLSProxy::Message::MT_CERTIFICATE, TLSProxy::Message::EXT_SCT, - TLSProxy::Message::SERVER, - checkhandshake::SCT_SRV_EXTENSION], - - [0,0,0,0] -); + checkhandshake::STATUS_REQUEST_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + ($v12_enabled ? + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS] : ()), + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN, + TLSProxy::Message::CLIENT, + checkhandshake::ALPN_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT, + TLSProxy::Message::CLIENT, + checkhandshake::SCT_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK, + TLSProxy::Message::CLIENT, + checkhandshake::PSK_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_POST_HANDSHAKE_AUTH, + TLSProxy::Message::CLIENT, + checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_RENEGOTIATE, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + + [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, + TLSProxy::Message::SERVER, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE, + TLSProxy::Message::SERVER, + checkhandshake::KEY_SHARE_HRR_EXTENSION], + + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SERVER_NAME, + TLSProxy::Message::CLIENT, + checkhandshake::SERVER_NAME_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_STATUS_REQUEST, + TLSProxy::Message::CLIENT, + checkhandshake::STATUS_REQUEST_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_GROUPS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + ($v12_enabled ? + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EC_POINT_FORMATS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS] : ()), + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SIG_ALGS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ALPN, + TLSProxy::Message::CLIENT, + checkhandshake::ALPN_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SCT, + TLSProxy::Message::CLIENT, + checkhandshake::SCT_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_ENCRYPT_THEN_MAC, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_EXTENDED_MASTER_SECRET, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SESSION_TICKET, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_KEY_SHARE, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK_KEX_MODES, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_PSK, + TLSProxy::Message::CLIENT, + checkhandshake::PSK_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_POST_HANDSHAKE_AUTH, + TLSProxy::Message::CLIENT, + checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION], + [TLSProxy::Message::MT_CLIENT_HELLO, TLSProxy::Message::EXT_RENEGOTIATE, + TLSProxy::Message::CLIENT, + checkhandshake::DEFAULT_EXTENSIONS], + + [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_SUPPORTED_VERSIONS, + TLSProxy::Message::SERVER, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_KEY_SHARE, + TLSProxy::Message::SERVER, + checkhandshake::DEFAULT_EXTENSIONS], + [TLSProxy::Message::MT_SERVER_HELLO, TLSProxy::Message::EXT_PSK, + TLSProxy::Message::SERVER, + checkhandshake::PSK_SRV_EXTENSION], + + [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_SERVER_NAME, + TLSProxy::Message::SERVER, + checkhandshake::SERVER_NAME_SRV_EXTENSION], + [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_ALPN, + TLSProxy::Message::SERVER, + checkhandshake::ALPN_SRV_EXTENSION], + [TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS, TLSProxy::Message::EXT_SUPPORTED_GROUPS, + TLSProxy::Message::SERVER, + checkhandshake::SUPPORTED_GROUPS_SRV_EXTENSION], + + [TLSProxy::Message::MT_CERTIFICATE_REQUEST, TLSProxy::Message::EXT_SIG_ALGS, + TLSProxy::Message::SERVER, + checkhandshake::DEFAULT_EXTENSIONS], + + [TLSProxy::Message::MT_CERTIFICATE, TLSProxy::Message::EXT_STATUS_REQUEST, + TLSProxy::Message::SERVER, + checkhandshake::STATUS_REQUEST_SRV_EXTENSION], + [TLSProxy::Message::MT_CERTIFICATE, TLSProxy::Message::EXT_SCT, + TLSProxy::Message::SERVER, + checkhandshake::SCT_SRV_EXTENSION], + + [0,0,0,0] + ); +} $ENV{OPENSSL_MODULES} = abs_path(bldtop_dir("test")); -my $proxy = TLSProxy::Proxy->new( - undef, - cmdstr(app(["openssl"]), display => 1), - srctop_file("apps", "server.pem"), - (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), - have_IPv6() -); +my $testcount = 19; my $fatal_alert = 0; my $hello_request_added = 0; my $hello_request_after_server_hello = 0; +my $hello_request_record_epoch = -1; +my $hello_request_record_seq = -1; -#Test 1: Check we get all the right messages for a default handshake -(undef, my $session) = tempfile(); -$proxy->serverconnects(2); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -sess_out ".$session); -$proxy->sessionfile($session); -$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 19; -checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS, - "Default handshake test"); - -#Test 2: Resumption handshake -$proxy->clearClient(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session); -$proxy->clientstart(); -checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, - (checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::PSK_CLI_EXTENSION - | checkhandshake::PSK_SRV_EXTENSION), - "Resumption handshake test"); +plan tests => 2 * $testcount; SKIP: { - skip "No OCSP support in this OpenSSL build", 4 - if disabled("ct") || disabled("ec") || disabled("ocsp"); - #Test 3: A status_request handshake (client request only) + skip "TLS 1.3 is disabled", $testcount if disabled("tls1_3"); + # Run tests with TLS + run_tests(0); +} + +SKIP: { + skip "DTLS 1.3 is disabled", $testcount if disabled("dtls1_3"); + skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/; + run_tests(1); +} + +sub run_tests +{ + my $run_test_as_dtls = shift; + my $proxy_start_success = 0; + + # Setup extensions based on whether we're testing TLS or DTLS + setup_extensions($run_test_as_dtls); + + (undef, my $session) = tempfile(); + my $proxy; + if ($run_test_as_dtls == 1) { + $proxy = TLSProxy::Proxy->new_dtls( + undef, + cmdstr(app([ "openssl" ]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } + else { + $proxy = TLSProxy::Proxy->new( + undef, + cmdstr(app([ "openssl" ]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } + $proxy->clear(); + + #Test 1: Check we get all the right messages for a default handshake + $proxy->serverconnects(2); $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); - $proxy->clientflags("-no_rx_cert_comp -status"); - $proxy->start(); + $proxy->clientflags("-no_rx_cert_comp -sess_out " . $session); + $proxy->sessionfile($session); + $proxy_start_success = $proxy->start(); + skip "TLSProxy did not start correctly", $testcount if $proxy_start_success == 0; checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS, + "Default handshake test"); + + #Test 2: Resumption handshake + $proxy->clearClient(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-no_rx_cert_comp -sess_in " . $session); + $proxy->clientstart(); + checkhandshake($proxy, checkhandshake::RESUME_HANDSHAKE, + (checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::PSK_CLI_EXTENSION + | checkhandshake::PSK_SRV_EXTENSION), + "Resumption handshake test"); + + + SKIP: { + skip "No OCSP support in this OpenSSL build", 4 + if disabled("ct") || disabled("ec") || disabled("ocsp"); + #Test 3: A status_request handshake (client request only) + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-no_rx_cert_comp -status"); + $proxy_start_success = $proxy->start(); + skip "TLSProxy did not start correctly", 4 if $proxy_start_success == 0; + checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::STATUS_REQUEST_CLI_EXTENSION, + "status_request handshake test (client)"); + + #Test 4: A status_request handshake (server support only) + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-no_rx_cert_comp"); + $proxy->serverflags("-no_rx_cert_comp -status_file " + . srctop_file("test", "recipes", "ocsp-response.der")); + $proxy->start(); + checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS, + "status_request handshake test (server)"); + + #Test 5: A status_request handshake (client and server) + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-no_rx_cert_comp -status"); + $proxy->serverflags("-no_rx_cert_comp -status_file " + . srctop_file("test", "recipes", "ocsp-response.der")); + $proxy->start(); + checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::STATUS_REQUEST_CLI_EXTENSION + | checkhandshake::STATUS_REQUEST_SRV_EXTENSION, + "status_request handshake test"); + + #Test 6: A status_request handshake (client and server) with client auth + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-no_rx_cert_comp -status -enable_pha -cert " + . srctop_file("apps", "server.pem")); + $proxy->serverflags("-no_rx_cert_comp -Verify 5 -status_file " + . srctop_file("test", "recipes", "ocsp-response.der")); + $proxy->start(); + checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::STATUS_REQUEST_CLI_EXTENSION + | checkhandshake::STATUS_REQUEST_SRV_EXTENSION + | checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION, + "status_request handshake with client auth test"); + } + + #Test 7: A client auth handshake + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-no_rx_cert_comp -enable_pha" + ." -cert ".srctop_file("apps", "server.pem")); + $proxy->serverflags("-no_rx_cert_comp -Verify 5"); + $proxy_start_success = $proxy->start(); + skip "TLSProxy did not start correctly", $testcount - 6 if $proxy_start_success == 0; + checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE, checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::STATUS_REQUEST_CLI_EXTENSION, - "status_request handshake test (client)"); + | checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION, + "Client auth handshake test"); - #Test 4: A status_request handshake (server support only) + #Test 8: Server name handshake (no client request) $proxy->clear(); $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); - $proxy->clientflags("-no_rx_cert_comp"); - $proxy->serverflags("-no_rx_cert_comp -status_file " - .srctop_file("test", "recipes", "ocsp-response.der")); + $proxy->clientflags("-no_rx_cert_comp -noservername"); $proxy->start(); checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS, - "status_request handshake test (server)"); + checkhandshake::DEFAULT_EXTENSIONS + & ~checkhandshake::SERVER_NAME_CLI_EXTENSION, + "Server name handshake test (client)"); - #Test 5: A status_request handshake (client and server) + #Test 9: Server name handshake (server support only) $proxy->clear(); $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); - $proxy->clientflags("-no_rx_cert_comp -status"); - $proxy->serverflags("-no_rx_cert_comp -status_file " - .srctop_file("test", "recipes", "ocsp-response.der")); + $proxy->clientflags("-no_rx_cert_comp -noservername"); + $proxy->serverflags("-no_rx_cert_comp -servername testhost"); $proxy->start(); checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::STATUS_REQUEST_CLI_EXTENSION - | checkhandshake::STATUS_REQUEST_SRV_EXTENSION, - "status_request handshake test"); + checkhandshake::DEFAULT_EXTENSIONS + & ~checkhandshake::SERVER_NAME_CLI_EXTENSION, + "Server name handshake test (server)"); - #Test 6: A status_request handshake (client and server) with client auth + #Test 10: Server name handshake (client and server) $proxy->clear(); $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); - $proxy->clientflags("-no_rx_cert_comp -status -enable_pha -cert " - .srctop_file("apps", "server.pem")); - $proxy->serverflags("-no_rx_cert_comp -Verify 5 -status_file " - .srctop_file("test", "recipes", "ocsp-response.der")); + $proxy->clientflags("-no_rx_cert_comp -servername testhost"); + $proxy->serverflags("-no_rx_cert_comp -servername testhost"); $proxy->start(); - checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::STATUS_REQUEST_CLI_EXTENSION - | checkhandshake::STATUS_REQUEST_SRV_EXTENSION - | checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION, - "status_request handshake with client auth test"); -} + checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::SERVER_NAME_SRV_EXTENSION, + "Server name handshake test"); + + #Test 11: ALPN handshake (client request only) + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-no_rx_cert_comp -alpn test"); + $proxy->start(); + checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::ALPN_CLI_EXTENSION, + "ALPN handshake test (client)"); -#Test 7: A client auth handshake -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -enable_pha -cert ".srctop_file("apps", "server.pem")); -$proxy->serverflags("-no_rx_cert_comp -Verify 5"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::CLIENT_AUTH_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS | - checkhandshake::POST_HANDSHAKE_AUTH_CLI_EXTENSION, - "Client auth handshake test"); - -#Test 8: Server name handshake (no client request) -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -noservername"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - & ~checkhandshake::SERVER_NAME_CLI_EXTENSION, - "Server name handshake test (client)"); - -#Test 9: Server name handshake (server support only) -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -noservername"); -$proxy->serverflags("-no_rx_cert_comp -servername testhost"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - & ~checkhandshake::SERVER_NAME_CLI_EXTENSION, - "Server name handshake test (server)"); - -#Test 10: Server name handshake (client and server) -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -servername testhost"); -$proxy->serverflags("-no_rx_cert_comp -servername testhost"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::SERVER_NAME_SRV_EXTENSION, - "Server name handshake test"); - -#Test 11: ALPN handshake (client request only) -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -alpn test"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::ALPN_CLI_EXTENSION, - "ALPN handshake test (client)"); - -#Test 12: ALPN handshake (server support only) -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp"); -$proxy->serverflags("-no_rx_cert_comp -alpn test"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS, - "ALPN handshake test (server)"); - -#Test 13: ALPN handshake (client and server) -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -alpn test"); -$proxy->serverflags("-no_rx_cert_comp -alpn test"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::ALPN_CLI_EXTENSION - | checkhandshake::ALPN_SRV_EXTENSION, - "ALPN handshake test"); + #Test 12: ALPN handshake (server support only) + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-no_rx_cert_comp"); + $proxy->serverflags("-no_rx_cert_comp -alpn test"); + $proxy->start(); + checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS, + "ALPN handshake test (server)"); -SKIP: { - skip "No CT, EC or OCSP support in this OpenSSL build", 1 - if disabled("ct") || disabled("ec") || disabled("ocsp"); + #Test 13: ALPN handshake (client and server) + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-no_rx_cert_comp -alpn test"); + $proxy->serverflags("-no_rx_cert_comp -alpn test"); + $proxy->start(); + checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::ALPN_CLI_EXTENSION + | checkhandshake::ALPN_SRV_EXTENSION, + "ALPN handshake test"); + + SKIP: { + skip "No CT, EC or OCSP support in this OpenSSL build", 1 + if disabled("ct") || disabled("ec") || disabled("ocsp"); + + #Test 14: SCT handshake (client request only) + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + #Note: -ct also sends status_request + $proxy->clientflags("-no_rx_cert_comp -ct"); + $proxy->serverflags("-no_rx_cert_comp -status_file " + . srctop_file("test", "recipes", "ocsp-response.der") + . " -serverinfo " . srctop_file("test", "serverinfo2.pem")); + $proxy->start(); + checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::SCT_CLI_EXTENSION + | checkhandshake::SCT_SRV_EXTENSION + | checkhandshake::STATUS_REQUEST_CLI_EXTENSION + | checkhandshake::STATUS_REQUEST_SRV_EXTENSION, + "SCT handshake test"); + } - #Test 14: SCT handshake (client request only) + #Test 15: HRR Handshake $proxy->clear(); $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); - #Note: -ct also sends status_request - $proxy->clientflags("-no_rx_cert_comp -ct"); - $proxy->serverflags("-no_rx_cert_comp -status_file " - .srctop_file("test", "recipes", "ocsp-response.der") - ." -serverinfo ".srctop_file("test", "serverinfo2.pem")); + $proxy->clientflags("-no_rx_cert_comp"); + $proxy->serverflags("-no_rx_cert_comp -curves P-384"); + $proxy->start(); + checkhandshake($proxy, checkhandshake::HRR_HANDSHAKE, + checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::KEY_SHARE_HRR_EXTENSION, + "HRR handshake test"); + + + #Test 16: Resumption handshake with HRR + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-no_rx_cert_comp -sess_in " . $session); + $proxy->serverflags("-no_rx_cert_comp -curves P-384"); + $proxy->start(); + checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE, + (checkhandshake::DEFAULT_EXTENSIONS + | checkhandshake::KEY_SHARE_HRR_EXTENSION + | checkhandshake::PSK_CLI_EXTENSION + | checkhandshake::PSK_SRV_EXTENSION), + "Resumption handshake with HRR test"); + + #Test 17: Acceptable but non preferred key_share + $proxy->clear(); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + $proxy->clientflags("-no_rx_cert_comp -curves P-384"); $proxy->start(); checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::SCT_CLI_EXTENSION - | checkhandshake::SCT_SRV_EXTENSION - | checkhandshake::STATUS_REQUEST_CLI_EXTENSION - | checkhandshake::STATUS_REQUEST_SRV_EXTENSION, - "SCT handshake test"); -} - -#Test 15: HRR Handshake -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp"); -$proxy->serverflags("-no_rx_cert_comp -curves P-384"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::HRR_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::KEY_SHARE_HRR_EXTENSION, - "HRR handshake test"); - -#Test 16: Resumption handshake with HRR -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -sess_in ".$session); -$proxy->serverflags("-no_rx_cert_comp -curves P-384"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::HRR_RESUME_HANDSHAKE, - (checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::KEY_SHARE_HRR_EXTENSION - | checkhandshake::PSK_CLI_EXTENSION - | checkhandshake::PSK_SRV_EXTENSION), - "Resumption handshake with HRR test"); - -#Test 17: Acceptable but non preferred key_share -$proxy->clear(); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp -curves P-384"); -$proxy->start(); -checkhandshake($proxy, checkhandshake::DEFAULT_HANDSHAKE, - checkhandshake::DEFAULT_EXTENSIONS - | checkhandshake::SUPPORTED_GROUPS_SRV_EXTENSION, - "Acceptable but non preferred key_share"); - -#Test 18: HelloRequest is reserved in TLSv1.3 -$proxy->clear(); -$fatal_alert = 0; -$hello_request_added = 0; -$hello_request_after_server_hello = 0; -$proxy->filter(\&inject_hello_request); -$proxy->cipherc("DEFAULT:\@SECLEVEL=2"); -$proxy->clientflags("-no_rx_cert_comp"); -$proxy->start(); -ok($fatal_alert, "HelloRequest rejected in TLSv1.3"); - -#Test 19: A HelloRequest received after selecting TLSv1.2 in the initial -# handshake is still ignored, confirming the legacy skip path is -# preserved even when TLSv1.3 was initially enabled. -SKIP: { - skip "TLSv1.2 disabled", 1 if disabled("tls1_2"); + | checkhandshake::SUPPORTED_GROUPS_SRV_EXTENSION, + "Acceptable but non preferred key_share"); + #Test 18: HelloRequest is reserved in (D)TLSv1.3 $proxy->clear(); $fatal_alert = 0; $hello_request_added = 0; - $hello_request_after_server_hello = 1; + $hello_request_after_server_hello = 0; + $hello_request_record_epoch = -1; + $hello_request_record_seq = -1; $proxy->filter(\&inject_hello_request); $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); - $proxy->clientflags("-no_rx_cert_comp"); - $proxy->serverflags("-no_tls1_3"); + if ($run_test_as_dtls) { + $proxy->clientflags("-no_rx_cert_comp -mtu 16384"); + $proxy->serverflags("-timeout -mtu 16384"); + } else { + $proxy->clientflags("-no_rx_cert_comp"); + } $proxy->start(); - ok(TLSProxy::Message->success() && !$fatal_alert, - "HelloRequest ignored in TLSv1.2"); -} + ok($fatal_alert, "HelloRequest rejected in " + . ($run_test_as_dtls ? "DTLSv1.3" : "TLSv1.3")); + + #Test 19: A HelloRequest received after selecting (D)TLSv1.2 in the initial + # handshake is still ignored, confirming the legacy skip path is + # preserved even when (D)TLSv1.3 was initially enabled. + SKIP: { + my $legacy_version = $run_test_as_dtls ? "DTLSv1.2" : "TLSv1.2"; + my $legacy_version_disabled = $run_test_as_dtls + ? disabled("dtls1_2") + : disabled("tls1_2"); + + skip "$legacy_version disabled", 1 if $legacy_version_disabled; + + $proxy->clear(); + $fatal_alert = 0; + $hello_request_added = 0; + $hello_request_after_server_hello = 1; + $hello_request_record_epoch = -1; + $hello_request_record_seq = -1; + $proxy->filter(\&inject_hello_request); + $proxy->cipherc("DEFAULT:\@SECLEVEL=2"); + if ($run_test_as_dtls) { + $proxy->clientflags("-no_rx_cert_comp -mtu 16384"); + $proxy->serverflags("-max_protocol DTLSv1.2 -mtu 16384"); + } else { + $proxy->clientflags("-no_rx_cert_comp"); + $proxy->serverflags("-no_tls1_3"); + } + $proxy->start(); + ok(TLSProxy::Message->success() && !$fatal_alert, + "HelloRequest ignored in $legacy_version"); + } -unlink $session; + unlink $session; +} sub inject_hello_request { @@ -460,36 +530,95 @@ sub inject_hello_request my $records = $proxy->record_list; my $hello_request; my $record; + my $server_hello; my $server_hello_record; + my $record_epoch; + my $record_seq; + my $record_version; + my $target_message; + my $target_record; + my $msgseq; my $i; if ($hello_request_added) { - $fatal_alert = 1 - if @{$records}[-1]->is_fatal_alert(0) - == TLSProxy::Message::AL_DESC_UNEXPECTED_MESSAGE; + if ($proxy->isdtls()) { + foreach my $existing_record (@{$records}) { + next if $existing_record->{sent}; + next if !$existing_record->serverissender; + next if $existing_record->epoch != $hello_request_record_epoch; + next if $existing_record->seq < $hello_request_record_seq; + + $existing_record->seq($existing_record->seq + 1); + } + + foreach my $existing_record (reverse @{$records}) { + if ($existing_record->is_fatal_alert(0) + == TLSProxy::Message::AL_DESC_UNEXPECTED_MESSAGE) { + $fatal_alert = 1; + last; + } + } + } elsif (@{$records}[-1]->is_fatal_alert(0) + == TLSProxy::Message::AL_DESC_UNEXPECTED_MESSAGE) { + $fatal_alert = 1; + } return; } - return if $proxy->flight != 1; + if (!$proxy->isdtls()) { + return if $proxy->flight != 1; + + $hello_request = pack("C4", TLSProxy::Message::MT_HELLO_REQUEST, + 0, 0, 0); + $record = TLSProxy::Record->new( + 1, + $proxy->flight, + TLSProxy::Record::RT_HANDSHAKE, + TLSProxy::Record::VERS_TLS_1_2, + length($hello_request), + length($hello_request), + length($hello_request), + $hello_request, + $hello_request + ); + + if ($hello_request_after_server_hello) { + foreach my $message (@{$proxy->message_list}) { + next if $message->mt != TLSProxy::Message::MT_SERVER_HELLO + || ${$message->records}[0]->flight != 1; + + $server_hello_record = @{$message->records}[-1]; + last; + } + + return if !defined $server_hello_record; + + for ($i = 0; $i < @{$records}; $i++) { + last if ${$records}[$i] == $server_hello_record; + } + $i++; + } else { + for ($i = 0; ${$records}[$i]->flight() < 1; $i++) { + next; + } + } - $hello_request = pack("C4", TLSProxy::Message::MT_HELLO_REQUEST, - 0, 0, 0); - $record = TLSProxy::Record->new( - 1, - TLSProxy::Record::RT_HANDSHAKE, - TLSProxy::Record::VERS_TLS_1_2, - length($hello_request), - length($hello_request), - length($hello_request), - $hello_request, - $hello_request - ); + splice @{$records}, $i, 0, $record; + $hello_request_added = 1; + return; + } + # Insert a standalone server record into an existing DTLS flight, bumping + # later same-epoch record sequence numbers while preserving handshake message + # sequences for the expected DTLSv1.3 reject and DTLSv1.2 skip paths. if ($hello_request_after_server_hello) { + return if ($proxy->flight & 1) == 0; + foreach my $message (@{$proxy->message_list}) { next if $message->mt != TLSProxy::Message::MT_SERVER_HELLO - || ${$message->records}[0]->flight != 1; + || !$message->server; + $server_hello = $message; $server_hello_record = @{$message->records}[-1]; last; } @@ -500,12 +629,63 @@ sub inject_hello_request last if ${$records}[$i] == $server_hello_record; } $i++; + $record_epoch = $server_hello_record->epoch; + $record_seq = $server_hello_record->seq + 1; + $record_version = $server_hello_record->version; + $msgseq = $server_hello->msgseq + 1; } else { - for ($i = 0; ${$records}[$i]->flight() < 1; $i++) { - next; + return if $proxy->flight != 1; + + foreach my $message (@{$proxy->message_list}) { + next if !$message->server + || ${$message->records}[0]->flight != $proxy->flight; + + $target_message = $message; + $target_record = ${$message->records}[0]; + last; } + + return if !defined $target_record; + + for ($i = 0; $i < @{$records}; $i++) { + last if ${$records}[$i] == $target_record; + } + + $record_epoch = $target_record->epoch; + $record_seq = $target_record->seq; + $record_version = $target_record->version; + $msgseq = $target_message->msgseq; } + foreach my $existing_record (@{$records}) { + next if !$existing_record->serverissender; + next if $existing_record->epoch != $record_epoch; + next if $existing_record->seq < $record_seq; + + $existing_record->seq($existing_record->seq + 1); + } + + $hello_request = pack("C", TLSProxy::Message::MT_HELLO_REQUEST) + . pack("C3", 0, 0, 0) + . pack("n", $msgseq) + . pack("C3", 0, 0, 0) + . pack("C3", 0, 0, 0); + $record = TLSProxy::Record->new_dtls( + 1, + $proxy->flight, + TLSProxy::Record::RT_HANDSHAKE, + $record_version, + $record_epoch, + $record_seq, + length($hello_request), + length($hello_request), + length($hello_request), + $hello_request, + $hello_request + ); + splice @{$records}, $i, 0, $record; $hello_request_added = 1; + $hello_request_record_epoch = $record_epoch; + $hello_request_record_seq = $record_seq; } diff --git a/test/recipes/70-test_tls13psk.t b/test/recipes/70-test_tls13psk.t index d15f838e9d376..c6ca3f6702660 100644 --- a/test/recipes/70-test_tls13psk.t +++ b/test/recipes/70-test_tls13psk.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -25,18 +25,14 @@ plan skip_all => "$test_name needs the module feature enabled" plan skip_all => "$test_name needs the sock feature enabled" if disabled("sock"); -plan skip_all => "$test_name needs TLSv1.3 enabled" - if disabled("tls1_3") || (disabled("ec") && disabled("dh")); +plan skip_all => "$test_name needs elliptic curves or diffie-hellman enabled" + if disabled("ec") && disabled("dh"); $ENV{OPENSSL_MODULES} = abs_path(bldtop_dir("test")); -my $proxy = TLSProxy::Proxy->new( - undef, - cmdstr(app(["openssl"]), display => 1), - srctop_file("apps", "server.pem"), - (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), - have_IPv6() -); +my $testcount = 7; + +plan tests => 2 * $testcount; use constant { PSK_LAST_FIRST_CH => 0, @@ -44,102 +40,173 @@ use constant { TOO_MANY_PSKS => 2 }; -#Most PSK tests are done in test_ssl_new. This tests various failure scenarios -#around PSK - -#Test 1: First get a session -(undef, my $session) = tempfile(); -$proxy->clientflags("-sess_out ".$session); -$proxy->serverflags("-servername localhost"); -$proxy->sessionfile($session); -$proxy->start() or plan skip_all => "Unable to start up Proxy for tests"; -plan tests => 7; -ok(TLSProxy::Message->success(), "Initial connection"); - -#Test 2: Attempt a resume with PSK not in last place. Should fail -$proxy->clear(); -$proxy->clientflags("-sess_in ".$session); -$proxy->filter(\&modify_psk_filter); -my $testtype = PSK_LAST_FIRST_CH; -$proxy->start(); -ok(TLSProxy::Message->fail(), "PSK not last"); - -#Test 3: Attempt a resume after an HRR where PSK hash matches selected -# ciphersuite. Should see PSK on second ClientHello -$proxy->clear(); -$proxy->clientflags("-sess_in ".$session); -if (disabled("ec")) { - $proxy->serverflags("-curves ffdhe3072"); -} else { - $proxy->serverflags("-curves P-384"); +SKIP: { + skip "TLS 1.3 is disabled", $testcount if disabled("tls1_3"); + # Run tests with TLS + run_tests(0); +} + +SKIP: { + skip "DTLS 1.3 is disabled", $testcount if disabled("dtls1_3"); + skip "DTLSProxy does not work on Windows", $testcount if $^O =~ /^(MSWin32)$/; + run_tests(1); } -$proxy->filter(undef); -$proxy->start(); -#Check if the PSK is present in the second ClientHello -my $ch2 = ${$proxy->message_list}[2]; -my $ch2seen = defined $ch2 && $ch2->mt() == TLSProxy::Message::MT_CLIENT_HELLO; -my $pskseen = $ch2seen - && defined ${$ch2->{extension_data}}{TLSProxy::Message::EXT_PSK}; -ok($pskseen, "PSK hash matches"); - -#Test 4: Attempt a resume after an HRR where PSK hash does not match selected -# ciphersuite. Should not see PSK on second ClientHello -$proxy->clear(); -$proxy->clientflags("-sess_in ".$session); -$proxy->filter(\&modify_psk_filter); -if (disabled("ec")) { - $proxy->serverflags("-curves ffdhe3072"); -} else { - $proxy->serverflags("-curves P-384"); + +my $testtype = -1; + +sub run_tests +{ + my $run_test_as_dtls = shift; + my $proxy_start_success = 0; + + my $proxy; + if ($run_test_as_dtls == 1) { + $proxy = TLSProxy::Proxy->new_dtls( + undef, + cmdstr(app([ "openssl" ]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } + else { + $proxy = TLSProxy::Proxy->new( + undef, + cmdstr(app([ "openssl" ]), display => 1), + srctop_file("apps", "server.pem"), + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } + + my $groups_list = "-groups " . + (!disabled("ec") ? "P-256:P-384:" : "") . + (!disabled("ecx") ? "X25519:X448:" : "") . + (!disabled("dh") ? "ffdhe2048:ffdhe3072" : ""); + # Remove trailing colon if present + $groups_list =~ s/:$//; + + #Most PSK tests are done in test_ssl_new. This tests various failure scenarios + #around PSK + + #Test 1: First get a session + $proxy->clear(); + (undef, my $session) = tempfile(); + $proxy->clientflags($groups_list . " -sess_out " . $session); + $proxy->serverflags($groups_list . " -servername localhost"); + $proxy->sessionfile($session); + $proxy_start_success = $proxy->start(); + skip "TLSProxy did not start correctly", $testcount if $proxy_start_success == 0; + ok(TLSProxy::Message->success(), "Initial connection"); + + #Test 2: Attempt a resume with PSK not in last place. Should fail + $proxy->clear(); + $proxy->clientflags($groups_list . " -sess_in " . $session); + $proxy->serverflags($groups_list); + $proxy->filter(\&modify_psk_filter); + $testtype = PSK_LAST_FIRST_CH; + $proxy->start(); + ok(TLSProxy::Message->fail(), "PSK not last"); + + #Test 3: Attempt a resume after an HRR where PSK hash matches selected + # ciphersuite. Should see PSK on second ClientHello + $proxy->clear(); + $proxy->clientflags($groups_list . " -sess_in " . $session); + if (disabled("ec")) { + $proxy->serverflags("-curves ffdhe3072"); + } + else { + $proxy->serverflags("-curves P-384"); + } + $proxy->filter(undef); + $proxy->start(); + #Check if the PSK is present in the second ClientHello + my $ch2 = ${$proxy->message_list}[2]; + my $ch2seen = defined $ch2 && $ch2->mt() == TLSProxy::Message::MT_CLIENT_HELLO; + my $pskseen = $ch2seen + && defined ${$ch2->{extension_data}}{TLSProxy::Message::EXT_PSK}; + ok($pskseen, "PSK hash matches"); + + #Test 4: Attempt a resume after an HRR where PSK hash does not match selected + # ciphersuite. Should not see PSK on second ClientHello + $proxy->clear(); + $proxy->clientflags($groups_list . " -sess_in " . $session); + $proxy->filter(\&modify_psk_filter); + if (disabled("ec")) { + $proxy->serverflags("-curves ffdhe3072"); + } + else { + $proxy->serverflags("-curves P-384"); + } + $proxy->ciphersuitesc("TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384"); + $proxy->ciphersuitess("TLS_AES_256_GCM_SHA384"); + #We force an early failure because TLS Proxy doesn't actually support + #TLS_AES_256_GCM_SHA384. That doesn't matter for this test though. + $testtype = ILLEGAL_EXT_SECOND_CH; + $proxy->start(); + #Check if the PSK is present in the second ClientHello + $ch2 = ${$proxy->message_list}[2]; + $ch2seen = defined $ch2 && $ch2->mt() == TLSProxy::Message::MT_CLIENT_HELLO; + $pskseen = $ch2seen + && defined ${$ch2->extension_data}{TLSProxy::Message::EXT_PSK}; + ok($ch2seen && !$pskseen, "PSK hash does not match"); + + #Test 5: Attempt a resume without a sig agls extension. Should succeed because + # sig algs is not needed in a resumption. + $proxy->clear(); + $proxy->clientflags($groups_list . " -sess_in " . $session); + $proxy->serverflags($groups_list); + $proxy->filter(\&remove_sig_algs_filter); + $proxy->start(); + ok(TLSProxy::Message->success(), "Remove sig algs"); + + #Test 6: Attempt a resume with too many PSKs. Handshake should still succeed. + # It will just ignore the PSKs. + $proxy->clear(); + $proxy->clientflags("-sess_in ".$session); + $proxy->filter(\&modify_psk_filter); + $testtype = TOO_MANY_PSKS; + $proxy->start(); + ok(TLSProxy::Message->success(), "Too many PSKs"); + + my $proxy2; + if ($run_test_as_dtls == 1) { + $proxy2 = TLSProxy::Proxy->new_dtls( + undef, + cmdstr(app(["openssl"]), display => 1), + undef, # Deliberately set to no_cert to force a PSK-only server + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } + else { + $proxy2 = TLSProxy::Proxy->new( + undef, + cmdstr(app(["openssl"]), display => 1), + undef, # Deliberately set to no_cert to force a PSK-only server + (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), + have_IPv6() + ); + } + + #Test 7: Attempt an invalid resume, with a server that can only do PSK. + # Should be treated the same as an invalid binder (decrypt_error) + # as per RFC8446 Appendix E.6 + $proxy2->clear(); + $proxy2->clientflags("-sess_in ".$session); + $proxy2->serverflags("-psk ffeeddccbbaa99887766554433221100 -no_ticket"); + if ($run_test_as_dtls) { + $proxy2->start(); + # For DTLS, the proxy may return 0 even when we got the expected alert, + # because UDP doesn't have connection close semantics and the proxy times out. + # The actual validation happens in is_decode_error_server_alert() below. + } else { + $proxy2->start() or die "Failed to start proxy2"; + } + ok(is_decode_error_server_alert(), "Bad PSK with no handshake fallback"); + + unlink $session; } -$proxy->ciphersuitesc("TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384"); -$proxy->ciphersuitess("TLS_AES_256_GCM_SHA384"); -#We force an early failure because TLS Proxy doesn't actually support -#TLS_AES_256_GCM_SHA384. That doesn't matter for this test though. -$testtype = ILLEGAL_EXT_SECOND_CH; -$proxy->start(); -#Check if the PSK is present in the second ClientHello -$ch2 = ${$proxy->message_list}[2]; -$ch2seen = defined $ch2 && $ch2->mt() == TLSProxy::Message::MT_CLIENT_HELLO; -$pskseen = $ch2seen - && defined ${$ch2->extension_data}{TLSProxy::Message::EXT_PSK}; -ok($ch2seen && !$pskseen, "PSK hash does not match"); - -#Test 5: Attempt a resume without a sig agls extension. Should succeed because -# sig algs is not needed in a resumption. -$proxy->clear(); -$proxy->clientflags("-sess_in ".$session); -$proxy->filter(\&remove_sig_algs_filter); -$proxy->start(); -ok(TLSProxy::Message->success(), "Remove sig algs"); - -#Test 6: Attempt a resume with too many PSKs. Handshake should still succeed. -# It will just ignore the PSKs. -$proxy->clear(); -$proxy->clientflags("-sess_in ".$session); -$proxy->filter(\&modify_psk_filter); -$testtype = TOO_MANY_PSKS; -$proxy->start(); -ok(TLSProxy::Message->success(), "Too many PSKs"); - -my $proxy2 = TLSProxy::Proxy->new( - undef, - cmdstr(app(["openssl"]), display => 1), - undef, # Deliberately set to no_cert to force a PSK-only server - (!$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}), - have_IPv6() -); - -#Test 7: Attempt an invalid resume, with a server that can only do PSK. -# Should be treated the same as an invalid binder (decrypt_error) -# as per RFC8446 Appendix E.6 -$proxy2->clear(); -$proxy2->clientflags("-sess_in ".$session); -$proxy2->serverflags("-psk ffeeddccbbaa99887766554433221100 -no_ticket"); -$proxy2->start() or die "Failed to start proxy2"; -ok(is_decode_error_server_alert(), "Bad PSK with no handshake fallback"); - -unlink $session; sub is_decode_error_server_alert { diff --git a/test/recipes/70-test_tls_groups_list.t b/test/recipes/70-test_tls_groups_list.t new file mode 100644 index 0000000000000..e200a63d0c029 --- /dev/null +++ b/test/recipes/70-test_tls_groups_list.t @@ -0,0 +1,17 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use OpenSSL::Test::Simple; +use OpenSSL::Test qw/:DEFAULT/; +use OpenSSL::Test::Utils qw(disabled); + +setup("test_tls_groups_list"); + +plan skip_all => "needs EC and ECX enabled" if disabled("ecx"); + +simple_test("test_tls_groups_list", "tls_groups_list_test"); diff --git a/test/recipes/70-test_tlsextms.t b/test/recipes/70-test_tlsextms.t index 0e5f5d44b86d2..a3ecbc387c98d 100644 --- a/test/recipes/70-test_tlsextms.t +++ b/test/recipes/70-test_tlsextms.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/70-test_tlspskext.t b/test/recipes/70-test_tlspskext.t index 9c909e5e8022a..d4ad67c2415ee 100644 --- a/test/recipes/70-test_tlspskext.t +++ b/test/recipes/70-test_tlspskext.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/recipes/80-test_ca.t b/test/recipes/80-test_ca.t index 95e21b92abd07..6d00bb351cd5a 100644 --- a/test/recipes/80-test_ca.t +++ b/test/recipes/80-test_ca.t @@ -29,7 +29,7 @@ sub src_file { rmtree("demoCA", { safe => 0 }); -plan tests => 20; +plan tests => 31; require_ok(srctop_file("test", "recipes", "tconversion.pl")); @@ -87,6 +87,22 @@ has_version($v3_cert, 3); has_SKID($v3_cert, 1); has_AKID($v3_cert, 1); +# Sign with X509v3 extensions from a separate -extfile, once using its +# default section and once with a section selected via -extensions. +test_extfile('extfile_default', [], qr/Digital Signature/); +test_extfile('extfile_section', ['-extensions', 'alt_ext'], + qr/Key Encipherment/); + +# Generate a CRL with extensions from the config section named by -crlexts +ok(run(app(['openssl', 'ca', '-config', $cnf, '-gencrl', '-crlsec', '60', + '-crlexts', 'crl_ext', '-out', 'crlexts-crl.pem'])), + 'Generate CRL with -crlexts'); +my $crlexts_text = join('', + run(app(['openssl', 'crl', '-in', 'crlexts-crl.pem', + '-noout', '-text']), capture => 1)); +ok($crlexts_text =~ qr/Version 2/, 'CRL with extensions is version 2'); +ok($crlexts_text =~ qr/Authority Key Identifier/, 'CRL contains AKID'); + test_revoke('notimes', { should_succeed => 1, }); @@ -125,6 +141,45 @@ test_revoke('both_generalizedtime', { should_succeed => 1, }); +sub test_extfile { + my ($filename, $ca_opts, $keyusage_re) = @_; + + $ENV{CN2} = $filename; + ok( + run(app(['openssl', + 'req', + '-config', $cnf, + '-new', + '-key', data_file('revoked.key'), + '-out', "$filename-req.pem", + '-section', 'userreq', + ])), + "Generate CSR: $filename" + ); + delete $ENV{CN2}; + + ok( + run(app(['openssl', + 'ca', + '-batch', + '-config', $cnf, + '-extfile', data_file('extensions.cnf'), + @$ca_opts, + '-in', "$filename-req.pem", + '-out', "$filename-cert.pem", + ])), + "Sign CSR with -extfile: $filename" + ); + + has_version("$filename-cert.pem", 3); + + my $keyusage = join('', + run(app(['openssl', 'x509', '-in', "$filename-cert.pem", + '-noout', '-ext', 'keyUsage']), capture => 1)); + ok($keyusage =~ $keyusage_re, + "keyUsage taken from the extfile: $filename"); +} + sub test_revoke { my ($filename, $opts) = @_; diff --git a/test/recipes/80-test_ca_data/extensions.cnf b/test/recipes/80-test_ca_data/extensions.cnf new file mode 100644 index 0000000000000..ebfd15019cbca --- /dev/null +++ b/test/recipes/80-test_ca_data/extensions.cnf @@ -0,0 +1,10 @@ +extensions = default_ext + +[ default_ext ] +basicConstraints = CA:false +subjectKeyIdentifier = hash +keyUsage = digitalSignature + +[ alt_ext ] +basicConstraints = CA:false +keyUsage = keyEncipherment diff --git a/test/recipes/80-test_cmp_http.t b/test/recipes/80-test_cmp_http.t index 24ec6cd7569fe..1444141598740 100644 --- a/test/recipes/80-test_cmp_http.t +++ b/test/recipes/80-test_cmp_http.t @@ -257,12 +257,44 @@ sub load_tests { my $file = data_file("test_$aspect.csv"); my $result_dir = result_dir(); my @result; + my ($cert_issuer, $cert_serial) = ("", ""); + if ($server_name eq "Mock" && $aspect eq "commands") { + my $cert_file; + if (open(my $cnf, '<', 'server.cnf')) { + while (<$cnf>) { + if (/^\s*rsp_cert\s*=\s*(\S+)/) { + $cert_file = $1; + last; + } + } + close($cnf); + } + if (defined $cert_file && -f $cert_file) { + my @issuer_out = run(app([qw(openssl x509 -noout -issuer -nameopt compat -in), + $cert_file]), capture => 1); + if (@issuer_out) { + ($cert_issuer = $issuer_out[0]) =~ s/^issuer=//; + chomp $cert_issuer; + } + my @serial_out = run(app([qw(openssl x509 -noout -serial -in), $cert_file]), + capture => 1); + if (@serial_out) { + ($cert_serial = $serial_out[0]) =~ s/^serial=/0x/; + chomp $cert_serial; + } + } + die "Cannot extract cert issuer or serial" + . (defined $cert_file ? " from '$cert_file'" : " (rsp_cert not found in server.cnf)") + if $cert_issuer eq "" || $cert_serial eq ""; + } open(my $data, '<', $file) || die "Cannot open '$file' for reading: $!"; LOOP: while (my $line = <$data>) { chomp $line; $line =~ s{\r\n}{\n}g; # adjust line endings + $line =~ s{_CERT_ISSUER}{$cert_issuer}g; + $line =~ s{_CERT_SERIAL}{$cert_serial}g; $line =~ s{_CA_DN}{$ca_dn}g; $line =~ s{_SERVER_DN}{$server_dn}g; $line =~ s{_SERVER_HOST}{$server_host}g; diff --git a/test/recipes/80-test_cmp_http_data/Mock/big_issuing.crt b/test/recipes/80-test_cmp_http_data/Mock/big_issuing.crt index e96f3cf788021..cf5ee5b81cf23 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/big_issuing.crt +++ b/test/recipes/80-test_cmp_http_data/Mock/big_issuing.crt @@ -44,1534 +44,361 @@ e4jmcYiyZev22KXQudeHc4w6crWiEFkVspomn5PqDmza3rkdB3baXFVZ6sd23ufU wjkiKKtwRBwU+5tCCagQZoeQ5dZXQThkiH2XEIOCOLxyD/tb -----END CERTIFICATE----- - - +Subject: C = US, O = Google Trust Services LLC, CN = GTS CA 1C3 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw +MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFDMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAPWI3+dijB43+DdCkH9sh9D7ZYIl/ejLa6T/belaI+KZ9hzp +kgOZE3wJCor6QtZeViSqejOEH9Hpabu5dOxXTGZok3c3VVP+ORBNtzS7XyV3NzsX +lOo85Z3VvMO0Q+sup0fvsEQRY9i0QYXdQTBIkxu/t/bgRQIh4JZCF8/ZK2VWNAcm +BA2o/X3KLu/qSHw3TT8An4Pf73WELnlXXPxXbhqW//yMmqaZviXZf5YsBvcRKgKA +gOtjGDxQSYflispfGStZloEAoPtR28p3CwvJlk/vcEnHXG0g/Zm0tOLKLnf9LdwL +tmsTDIwZKxeWmLnwi/agJ7u2441Rj72ux5uxiZ0CAwEAAaOCAYAwggF8MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T +AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUinR/r4XN7pXNPZzQ4kYU83E1HScwHwYD +VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG +CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw +AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt +MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsMFcG +A1UdIARQME4wOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br +aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcN +AQELBQADggIBAIl9rCBcDDy+mqhXlRu0rvqrpXJxtDaV/d9AEQNMwkYUuxQkq/BQ +cSLbrcRuf8/xam/IgxvYzolfh2yHuKkMo5uhYpSTld9brmYZCwKWnvy15xBpPnrL +RklfRuFBsdeYTWU0AIAaP0+fbH9JAIFTQaSSIYKCGvGjRFsqUBITTcFTNvNCCK9U ++o53UxtkOCcXCb1YyRt8OS1b887U7ZfbFAO/CVMkH8IMBHmYJvJh8VNS/UKMG2Yr +PxWhu//2m+OBmgEGcYk1KCTd4b3rGS3hSMs9WYNRtHTGnXzGsYZbr8w0xNPM1IER +lQCh9BIiAfq0g3GvjLeMcySsN1PCAJA/Ef5c7TaUEDu9Ka7ixzpiO2xj2YC/WXGs +Yye5TBeg2vZzFb8q3o/zpWwygTMD0IZRcZk0upONXbVRWPeyk+gB9lm+cZv9TSjO +z23HFtz30dZGm6fKa+l3D/2gthsjgx0QGtkJAITgRNOidSOzNIb2ILCkXhAd4FJG +AJ2xDx8hcFH1mt0G/FX0Kw4zd8NLQsLxdxP8c4CU6x+7Nz/OAipmsHMdMqUybDKw +juDEI/9bfU1lcKwrmz3O2+BtjjKAvpafkmO8l7tdufThcV4q5O8DIrGKZTqPwJNl +1IXNDw9bg1kWRxYtnCQ6yICmJhSFm/Y3m6xv+cXDBlHz4n/FsRC6UfTd -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS CA 1C3 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw +MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFDMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAPWI3+dijB43+DdCkH9sh9D7ZYIl/ejLa6T/belaI+KZ9hzp +kgOZE3wJCor6QtZeViSqejOEH9Hpabu5dOxXTGZok3c3VVP+ORBNtzS7XyV3NzsX +lOo85Z3VvMO0Q+sup0fvsEQRY9i0QYXdQTBIkxu/t/bgRQIh4JZCF8/ZK2VWNAcm +BA2o/X3KLu/qSHw3TT8An4Pf73WELnlXXPxXbhqW//yMmqaZviXZf5YsBvcRKgKA +gOtjGDxQSYflispfGStZloEAoPtR28p3CwvJlk/vcEnHXG0g/Zm0tOLKLnf9LdwL +tmsTDIwZKxeWmLnwi/agJ7u2441Rj72ux5uxiZ0CAwEAAaOCAYAwggF8MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T +AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUinR/r4XN7pXNPZzQ4kYU83E1HScwHwYD +VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG +CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw +AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt +MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsMFcG +A1UdIARQME4wOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br +aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcN +AQELBQADggIBAIl9rCBcDDy+mqhXlRu0rvqrpXJxtDaV/d9AEQNMwkYUuxQkq/BQ +cSLbrcRuf8/xam/IgxvYzolfh2yHuKkMo5uhYpSTld9brmYZCwKWnvy15xBpPnrL +RklfRuFBsdeYTWU0AIAaP0+fbH9JAIFTQaSSIYKCGvGjRFsqUBITTcFTNvNCCK9U ++o53UxtkOCcXCb1YyRt8OS1b887U7ZfbFAO/CVMkH8IMBHmYJvJh8VNS/UKMG2Yr +PxWhu//2m+OBmgEGcYk1KCTd4b3rGS3hSMs9WYNRtHTGnXzGsYZbr8w0xNPM1IER +lQCh9BIiAfq0g3GvjLeMcySsN1PCAJA/Ef5c7TaUEDu9Ka7ixzpiO2xj2YC/WXGs +Yye5TBeg2vZzFb8q3o/zpWwygTMD0IZRcZk0upONXbVRWPeyk+gB9lm+cZv9TSjO +z23HFtz30dZGm6fKa+l3D/2gthsjgx0QGtkJAITgRNOidSOzNIb2ILCkXhAd4FJG +AJ2xDx8hcFH1mt0G/FX0Kw4zd8NLQsLxdxP8c4CU6x+7Nz/OAipmsHMdMqUybDKw +juDEI/9bfU1lcKwrmz3O2+BtjjKAvpafkmO8l7tdufThcV4q5O8DIrGKZTqPwJNl +1IXNDw9bg1kWRxYtnCQ6yICmJhSFm/Y3m6xv+cXDBlHz4n/FsRC6UfTd -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS CA 1C3 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw +MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFDMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAPWI3+dijB43+DdCkH9sh9D7ZYIl/ejLa6T/belaI+KZ9hzp +kgOZE3wJCor6QtZeViSqejOEH9Hpabu5dOxXTGZok3c3VVP+ORBNtzS7XyV3NzsX +lOo85Z3VvMO0Q+sup0fvsEQRY9i0QYXdQTBIkxu/t/bgRQIh4JZCF8/ZK2VWNAcm +BA2o/X3KLu/qSHw3TT8An4Pf73WELnlXXPxXbhqW//yMmqaZviXZf5YsBvcRKgKA +gOtjGDxQSYflispfGStZloEAoPtR28p3CwvJlk/vcEnHXG0g/Zm0tOLKLnf9LdwL +tmsTDIwZKxeWmLnwi/agJ7u2441Rj72ux5uxiZ0CAwEAAaOCAYAwggF8MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T +AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUinR/r4XN7pXNPZzQ4kYU83E1HScwHwYD +VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG +CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw +AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt +MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsMFcG +A1UdIARQME4wOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br +aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcN +AQELBQADggIBAIl9rCBcDDy+mqhXlRu0rvqrpXJxtDaV/d9AEQNMwkYUuxQkq/BQ +cSLbrcRuf8/xam/IgxvYzolfh2yHuKkMo5uhYpSTld9brmYZCwKWnvy15xBpPnrL +RklfRuFBsdeYTWU0AIAaP0+fbH9JAIFTQaSSIYKCGvGjRFsqUBITTcFTNvNCCK9U ++o53UxtkOCcXCb1YyRt8OS1b887U7ZfbFAO/CVMkH8IMBHmYJvJh8VNS/UKMG2Yr +PxWhu//2m+OBmgEGcYk1KCTd4b3rGS3hSMs9WYNRtHTGnXzGsYZbr8w0xNPM1IER +lQCh9BIiAfq0g3GvjLeMcySsN1PCAJA/Ef5c7TaUEDu9Ka7ixzpiO2xj2YC/WXGs +Yye5TBeg2vZzFb8q3o/zpWwygTMD0IZRcZk0upONXbVRWPeyk+gB9lm+cZv9TSjO +z23HFtz30dZGm6fKa+l3D/2gthsjgx0QGtkJAITgRNOidSOzNIb2ILCkXhAd4FJG +AJ2xDx8hcFH1mt0G/FX0Kw4zd8NLQsLxdxP8c4CU6x+7Nz/OAipmsHMdMqUybDKw +juDEI/9bfU1lcKwrmz3O2+BtjjKAvpafkmO8l7tdufThcV4q5O8DIrGKZTqPwJNl +1IXNDw9bg1kWRxYtnCQ6yICmJhSFm/Y3m6xv+cXDBlHz4n/FsRC6UfTd -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS CA 1C3 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw +MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFDMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAPWI3+dijB43+DdCkH9sh9D7ZYIl/ejLa6T/belaI+KZ9hzp +kgOZE3wJCor6QtZeViSqejOEH9Hpabu5dOxXTGZok3c3VVP+ORBNtzS7XyV3NzsX +lOo85Z3VvMO0Q+sup0fvsEQRY9i0QYXdQTBIkxu/t/bgRQIh4JZCF8/ZK2VWNAcm +BA2o/X3KLu/qSHw3TT8An4Pf73WELnlXXPxXbhqW//yMmqaZviXZf5YsBvcRKgKA +gOtjGDxQSYflispfGStZloEAoPtR28p3CwvJlk/vcEnHXG0g/Zm0tOLKLnf9LdwL +tmsTDIwZKxeWmLnwi/agJ7u2441Rj72ux5uxiZ0CAwEAAaOCAYAwggF8MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T +AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUinR/r4XN7pXNPZzQ4kYU83E1HScwHwYD +VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG +CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw +AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt +MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsMFcG +A1UdIARQME4wOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br +aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcN +AQELBQADggIBAIl9rCBcDDy+mqhXlRu0rvqrpXJxtDaV/d9AEQNMwkYUuxQkq/BQ +cSLbrcRuf8/xam/IgxvYzolfh2yHuKkMo5uhYpSTld9brmYZCwKWnvy15xBpPnrL +RklfRuFBsdeYTWU0AIAaP0+fbH9JAIFTQaSSIYKCGvGjRFsqUBITTcFTNvNCCK9U ++o53UxtkOCcXCb1YyRt8OS1b887U7ZfbFAO/CVMkH8IMBHmYJvJh8VNS/UKMG2Yr +PxWhu//2m+OBmgEGcYk1KCTd4b3rGS3hSMs9WYNRtHTGnXzGsYZbr8w0xNPM1IER +lQCh9BIiAfq0g3GvjLeMcySsN1PCAJA/Ef5c7TaUEDu9Ka7ixzpiO2xj2YC/WXGs +Yye5TBeg2vZzFb8q3o/zpWwygTMD0IZRcZk0upONXbVRWPeyk+gB9lm+cZv9TSjO +z23HFtz30dZGm6fKa+l3D/2gthsjgx0QGtkJAITgRNOidSOzNIb2ILCkXhAd4FJG +AJ2xDx8hcFH1mt0G/FX0Kw4zd8NLQsLxdxP8c4CU6x+7Nz/OAipmsHMdMqUybDKw +juDEI/9bfU1lcKwrmz3O2+BtjjKAvpafkmO8l7tdufThcV4q5O8DIrGKZTqPwJNl +1IXNDw9bg1kWRxYtnCQ6yICmJhSFm/Y3m6xv+cXDBlHz4n/FsRC6UfTd -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS CA 1C3 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw +MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFDMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAPWI3+dijB43+DdCkH9sh9D7ZYIl/ejLa6T/belaI+KZ9hzp +kgOZE3wJCor6QtZeViSqejOEH9Hpabu5dOxXTGZok3c3VVP+ORBNtzS7XyV3NzsX +lOo85Z3VvMO0Q+sup0fvsEQRY9i0QYXdQTBIkxu/t/bgRQIh4JZCF8/ZK2VWNAcm +BA2o/X3KLu/qSHw3TT8An4Pf73WELnlXXPxXbhqW//yMmqaZviXZf5YsBvcRKgKA +gOtjGDxQSYflispfGStZloEAoPtR28p3CwvJlk/vcEnHXG0g/Zm0tOLKLnf9LdwL +tmsTDIwZKxeWmLnwi/agJ7u2441Rj72ux5uxiZ0CAwEAAaOCAYAwggF8MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T +AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUinR/r4XN7pXNPZzQ4kYU83E1HScwHwYD +VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG +CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw +AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt +MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsMFcG +A1UdIARQME4wOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br +aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcN +AQELBQADggIBAIl9rCBcDDy+mqhXlRu0rvqrpXJxtDaV/d9AEQNMwkYUuxQkq/BQ +cSLbrcRuf8/xam/IgxvYzolfh2yHuKkMo5uhYpSTld9brmYZCwKWnvy15xBpPnrL +RklfRuFBsdeYTWU0AIAaP0+fbH9JAIFTQaSSIYKCGvGjRFsqUBITTcFTNvNCCK9U ++o53UxtkOCcXCb1YyRt8OS1b887U7ZfbFAO/CVMkH8IMBHmYJvJh8VNS/UKMG2Yr +PxWhu//2m+OBmgEGcYk1KCTd4b3rGS3hSMs9WYNRtHTGnXzGsYZbr8w0xNPM1IER +lQCh9BIiAfq0g3GvjLeMcySsN1PCAJA/Ef5c7TaUEDu9Ka7ixzpiO2xj2YC/WXGs +Yye5TBeg2vZzFb8q3o/zpWwygTMD0IZRcZk0upONXbVRWPeyk+gB9lm+cZv9TSjO +z23HFtz30dZGm6fKa+l3D/2gthsjgx0QGtkJAITgRNOidSOzNIb2ILCkXhAd4FJG +AJ2xDx8hcFH1mt0G/FX0Kw4zd8NLQsLxdxP8c4CU6x+7Nz/OAipmsHMdMqUybDKw +juDEI/9bfU1lcKwrmz3O2+BtjjKAvpafkmO8l7tdufThcV4q5O8DIrGKZTqPwJNl +1IXNDw9bg1kWRxYtnCQ6yICmJhSFm/Y3m6xv+cXDBlHz4n/FsRC6UfTd -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS CA 1C3 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw +MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFDMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAPWI3+dijB43+DdCkH9sh9D7ZYIl/ejLa6T/belaI+KZ9hzp +kgOZE3wJCor6QtZeViSqejOEH9Hpabu5dOxXTGZok3c3VVP+ORBNtzS7XyV3NzsX +lOo85Z3VvMO0Q+sup0fvsEQRY9i0QYXdQTBIkxu/t/bgRQIh4JZCF8/ZK2VWNAcm +BA2o/X3KLu/qSHw3TT8An4Pf73WELnlXXPxXbhqW//yMmqaZviXZf5YsBvcRKgKA +gOtjGDxQSYflispfGStZloEAoPtR28p3CwvJlk/vcEnHXG0g/Zm0tOLKLnf9LdwL +tmsTDIwZKxeWmLnwi/agJ7u2441Rj72ux5uxiZ0CAwEAAaOCAYAwggF8MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T +AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUinR/r4XN7pXNPZzQ4kYU83E1HScwHwYD +VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG +CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw +AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt +MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsMFcG +A1UdIARQME4wOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br +aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcN +AQELBQADggIBAIl9rCBcDDy+mqhXlRu0rvqrpXJxtDaV/d9AEQNMwkYUuxQkq/BQ +cSLbrcRuf8/xam/IgxvYzolfh2yHuKkMo5uhYpSTld9brmYZCwKWnvy15xBpPnrL +RklfRuFBsdeYTWU0AIAaP0+fbH9JAIFTQaSSIYKCGvGjRFsqUBITTcFTNvNCCK9U ++o53UxtkOCcXCb1YyRt8OS1b887U7ZfbFAO/CVMkH8IMBHmYJvJh8VNS/UKMG2Yr +PxWhu//2m+OBmgEGcYk1KCTd4b3rGS3hSMs9WYNRtHTGnXzGsYZbr8w0xNPM1IER +lQCh9BIiAfq0g3GvjLeMcySsN1PCAJA/Ef5c7TaUEDu9Ka7ixzpiO2xj2YC/WXGs +Yye5TBeg2vZzFb8q3o/zpWwygTMD0IZRcZk0upONXbVRWPeyk+gB9lm+cZv9TSjO +z23HFtz30dZGm6fKa+l3D/2gthsjgx0QGtkJAITgRNOidSOzNIb2ILCkXhAd4FJG +AJ2xDx8hcFH1mt0G/FX0Kw4zd8NLQsLxdxP8c4CU6x+7Nz/OAipmsHMdMqUybDKw +juDEI/9bfU1lcKwrmz3O2+BtjjKAvpafkmO8l7tdufThcV4q5O8DIrGKZTqPwJNl +1IXNDw9bg1kWRxYtnCQ6yICmJhSFm/Y3m6xv+cXDBlHz4n/FsRC6UfTd -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS CA 1C3 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw +MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFDMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAPWI3+dijB43+DdCkH9sh9D7ZYIl/ejLa6T/belaI+KZ9hzp +kgOZE3wJCor6QtZeViSqejOEH9Hpabu5dOxXTGZok3c3VVP+ORBNtzS7XyV3NzsX +lOo85Z3VvMO0Q+sup0fvsEQRY9i0QYXdQTBIkxu/t/bgRQIh4JZCF8/ZK2VWNAcm +BA2o/X3KLu/qSHw3TT8An4Pf73WELnlXXPxXbhqW//yMmqaZviXZf5YsBvcRKgKA +gOtjGDxQSYflispfGStZloEAoPtR28p3CwvJlk/vcEnHXG0g/Zm0tOLKLnf9LdwL +tmsTDIwZKxeWmLnwi/agJ7u2441Rj72ux5uxiZ0CAwEAAaOCAYAwggF8MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T +AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUinR/r4XN7pXNPZzQ4kYU83E1HScwHwYD +VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG +CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw +AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt +MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsMFcG +A1UdIARQME4wOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br +aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcN +AQELBQADggIBAIl9rCBcDDy+mqhXlRu0rvqrpXJxtDaV/d9AEQNMwkYUuxQkq/BQ +cSLbrcRuf8/xam/IgxvYzolfh2yHuKkMo5uhYpSTld9brmYZCwKWnvy15xBpPnrL +RklfRuFBsdeYTWU0AIAaP0+fbH9JAIFTQaSSIYKCGvGjRFsqUBITTcFTNvNCCK9U ++o53UxtkOCcXCb1YyRt8OS1b887U7ZfbFAO/CVMkH8IMBHmYJvJh8VNS/UKMG2Yr +PxWhu//2m+OBmgEGcYk1KCTd4b3rGS3hSMs9WYNRtHTGnXzGsYZbr8w0xNPM1IER +lQCh9BIiAfq0g3GvjLeMcySsN1PCAJA/Ef5c7TaUEDu9Ka7ixzpiO2xj2YC/WXGs +Yye5TBeg2vZzFb8q3o/zpWwygTMD0IZRcZk0upONXbVRWPeyk+gB9lm+cZv9TSjO +z23HFtz30dZGm6fKa+l3D/2gthsjgx0QGtkJAITgRNOidSOzNIb2ILCkXhAd4FJG +AJ2xDx8hcFH1mt0G/FX0Kw4zd8NLQsLxdxP8c4CU6x+7Nz/OAipmsHMdMqUybDKw +juDEI/9bfU1lcKwrmz3O2+BtjjKAvpafkmO8l7tdufThcV4q5O8DIrGKZTqPwJNl +1IXNDw9bg1kWRxYtnCQ6yICmJhSFm/Y3m6xv+cXDBlHz4n/FsRC6UfTd -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS CA 1C3 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw +MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFDMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAPWI3+dijB43+DdCkH9sh9D7ZYIl/ejLa6T/belaI+KZ9hzp +kgOZE3wJCor6QtZeViSqejOEH9Hpabu5dOxXTGZok3c3VVP+ORBNtzS7XyV3NzsX +lOo85Z3VvMO0Q+sup0fvsEQRY9i0QYXdQTBIkxu/t/bgRQIh4JZCF8/ZK2VWNAcm +BA2o/X3KLu/qSHw3TT8An4Pf73WELnlXXPxXbhqW//yMmqaZviXZf5YsBvcRKgKA +gOtjGDxQSYflispfGStZloEAoPtR28p3CwvJlk/vcEnHXG0g/Zm0tOLKLnf9LdwL +tmsTDIwZKxeWmLnwi/agJ7u2441Rj72ux5uxiZ0CAwEAAaOCAYAwggF8MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T +AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUinR/r4XN7pXNPZzQ4kYU83E1HScwHwYD +VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG +CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw +AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt +MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsMFcG +A1UdIARQME4wOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br +aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcN +AQELBQADggIBAIl9rCBcDDy+mqhXlRu0rvqrpXJxtDaV/d9AEQNMwkYUuxQkq/BQ +cSLbrcRuf8/xam/IgxvYzolfh2yHuKkMo5uhYpSTld9brmYZCwKWnvy15xBpPnrL +RklfRuFBsdeYTWU0AIAaP0+fbH9JAIFTQaSSIYKCGvGjRFsqUBITTcFTNvNCCK9U ++o53UxtkOCcXCb1YyRt8OS1b887U7ZfbFAO/CVMkH8IMBHmYJvJh8VNS/UKMG2Yr +PxWhu//2m+OBmgEGcYk1KCTd4b3rGS3hSMs9WYNRtHTGnXzGsYZbr8w0xNPM1IER +lQCh9BIiAfq0g3GvjLeMcySsN1PCAJA/Ef5c7TaUEDu9Ka7ixzpiO2xj2YC/WXGs +Yye5TBeg2vZzFb8q3o/zpWwygTMD0IZRcZk0upONXbVRWPeyk+gB9lm+cZv9TSjO +z23HFtz30dZGm6fKa+l3D/2gthsjgx0QGtkJAITgRNOidSOzNIb2ILCkXhAd4FJG +AJ2xDx8hcFH1mt0G/FX0Kw4zd8NLQsLxdxP8c4CU6x+7Nz/OAipmsHMdMqUybDKw +juDEI/9bfU1lcKwrmz3O2+BtjjKAvpafkmO8l7tdufThcV4q5O8DIrGKZTqPwJNl +1IXNDw9bg1kWRxYtnCQ6yICmJhSFm/Y3m6xv+cXDBlHz4n/FsRC6UfTd -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS CA 1C3 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw +MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFDMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAPWI3+dijB43+DdCkH9sh9D7ZYIl/ejLa6T/belaI+KZ9hzp +kgOZE3wJCor6QtZeViSqejOEH9Hpabu5dOxXTGZok3c3VVP+ORBNtzS7XyV3NzsX +lOo85Z3VvMO0Q+sup0fvsEQRY9i0QYXdQTBIkxu/t/bgRQIh4JZCF8/ZK2VWNAcm +BA2o/X3KLu/qSHw3TT8An4Pf73WELnlXXPxXbhqW//yMmqaZviXZf5YsBvcRKgKA +gOtjGDxQSYflispfGStZloEAoPtR28p3CwvJlk/vcEnHXG0g/Zm0tOLKLnf9LdwL +tmsTDIwZKxeWmLnwi/agJ7u2441Rj72ux5uxiZ0CAwEAAaOCAYAwggF8MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T +AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUinR/r4XN7pXNPZzQ4kYU83E1HScwHwYD +VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG +CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw +AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt +MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsMFcG +A1UdIARQME4wOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br +aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcN +AQELBQADggIBAIl9rCBcDDy+mqhXlRu0rvqrpXJxtDaV/d9AEQNMwkYUuxQkq/BQ +cSLbrcRuf8/xam/IgxvYzolfh2yHuKkMo5uhYpSTld9brmYZCwKWnvy15xBpPnrL +RklfRuFBsdeYTWU0AIAaP0+fbH9JAIFTQaSSIYKCGvGjRFsqUBITTcFTNvNCCK9U ++o53UxtkOCcXCb1YyRt8OS1b887U7ZfbFAO/CVMkH8IMBHmYJvJh8VNS/UKMG2Yr +PxWhu//2m+OBmgEGcYk1KCTd4b3rGS3hSMs9WYNRtHTGnXzGsYZbr8w0xNPM1IER +lQCh9BIiAfq0g3GvjLeMcySsN1PCAJA/Ef5c7TaUEDu9Ka7ixzpiO2xj2YC/WXGs +Yye5TBeg2vZzFb8q3o/zpWwygTMD0IZRcZk0upONXbVRWPeyk+gB9lm+cZv9TSjO +z23HFtz30dZGm6fKa+l3D/2gthsjgx0QGtkJAITgRNOidSOzNIb2ILCkXhAd4FJG +AJ2xDx8hcFH1mt0G/FX0Kw4zd8NLQsLxdxP8c4CU6x+7Nz/OAipmsHMdMqUybDKw +juDEI/9bfU1lcKwrmz3O2+BtjjKAvpafkmO8l7tdufThcV4q5O8DIrGKZTqPwJNl +1IXNDw9bg1kWRxYtnCQ6yICmJhSFm/Y3m6xv+cXDBlHz4n/FsRC6UfTd -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS CA 1C3 +-----BEGIN CERTIFICATE----- +MIIFljCCA36gAwIBAgINAgO8U1lrNMcY9QFQZjANBgkqhkiG9w0BAQsFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMjAwODEzMDAwMDQyWhcNMjcwOTMwMDAw +MDQyWjBGMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzETMBEGA1UEAxMKR1RTIENBIDFDMzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAPWI3+dijB43+DdCkH9sh9D7ZYIl/ejLa6T/belaI+KZ9hzp +kgOZE3wJCor6QtZeViSqejOEH9Hpabu5dOxXTGZok3c3VVP+ORBNtzS7XyV3NzsX +lOo85Z3VvMO0Q+sup0fvsEQRY9i0QYXdQTBIkxu/t/bgRQIh4JZCF8/ZK2VWNAcm +BA2o/X3KLu/qSHw3TT8An4Pf73WELnlXXPxXbhqW//yMmqaZviXZf5YsBvcRKgKA +gOtjGDxQSYflispfGStZloEAoPtR28p3CwvJlk/vcEnHXG0g/Zm0tOLKLnf9LdwL +tmsTDIwZKxeWmLnwi/agJ7u2441Rj72ux5uxiZ0CAwEAAaOCAYAwggF8MA4GA1Ud +DwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0T +AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUinR/r4XN7pXNPZzQ4kYU83E1HScwHwYD +VR0jBBgwFoAU5K8rJnEaK0gnhS9SZizv8IkTcT4waAYIKwYBBQUHAQEEXDBaMCYG +CCsGAQUFBzABhhpodHRwOi8vb2NzcC5wa2kuZ29vZy9ndHNyMTAwBggrBgEFBQcw +AoYkaHR0cDovL3BraS5nb29nL3JlcG8vY2VydHMvZ3RzcjEuZGVyMDQGA1UdHwQt +MCswKaAnoCWGI2h0dHA6Ly9jcmwucGtpLmdvb2cvZ3RzcjEvZ3RzcjEuY3JsMFcG +A1UdIARQME4wOAYKKwYBBAHWeQIFAzAqMCgGCCsGAQUFBwIBFhxodHRwczovL3Br +aS5nb29nL3JlcG9zaXRvcnkvMAgGBmeBDAECATAIBgZngQwBAgIwDQYJKoZIhvcN +AQELBQADggIBAIl9rCBcDDy+mqhXlRu0rvqrpXJxtDaV/d9AEQNMwkYUuxQkq/BQ +cSLbrcRuf8/xam/IgxvYzolfh2yHuKkMo5uhYpSTld9brmYZCwKWnvy15xBpPnrL +RklfRuFBsdeYTWU0AIAaP0+fbH9JAIFTQaSSIYKCGvGjRFsqUBITTcFTNvNCCK9U ++o53UxtkOCcXCb1YyRt8OS1b887U7ZfbFAO/CVMkH8IMBHmYJvJh8VNS/UKMG2Yr +PxWhu//2m+OBmgEGcYk1KCTd4b3rGS3hSMs9WYNRtHTGnXzGsYZbr8w0xNPM1IER +lQCh9BIiAfq0g3GvjLeMcySsN1PCAJA/Ef5c7TaUEDu9Ka7ixzpiO2xj2YC/WXGs +Yye5TBeg2vZzFb8q3o/zpWwygTMD0IZRcZk0upONXbVRWPeyk+gB9lm+cZv9TSjO +z23HFtz30dZGm6fKa+l3D/2gthsjgx0QGtkJAITgRNOidSOzNIb2ILCkXhAd4FJG +AJ2xDx8hcFH1mt0G/FX0Kw4zd8NLQsLxdxP8c4CU6x+7Nz/OAipmsHMdMqUybDKw +juDEI/9bfU1lcKwrmz3O2+BtjjKAvpafkmO8l7tdufThcV4q5O8DIrGKZTqPwJNl +1IXNDw9bg1kWRxYtnCQ6yICmJhSFm/Y3m6xv+cXDBlHz4n/FsRC6UfTd +-----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIDEjCCAfqgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDDA5zaWdu +ZXItaW50ZXJDQTAgFw0yNjA5MDgxMTU1NTlaGA8yMTI2MDkwOTExNTU1OVowHDEa +MBgGA1UEAwwRc2lnbmVyLXN1YmludGVyQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQCml/ziis7d2NLVHWH4/HRH+qDQUOJjhXzCzCGRwSTTEyaydUk+ +S/EMuNqjUhVI1LIV9FjBfG8vq3HMDSVu8B2OCXC/UlD2EA6nmR4IL5vbFfCavyzW +QXGhnG/FWb8kIV0u85oV1367rfIb3H0WGbYFKYmskALgEHYd0ftM6UafLEdtnbp5 +6Jh3HFAoXkHuT7npTZAWUgZvyJRlUPbm+U9BdZGLXCCc1VTD/RvZJGzcaUE2CKXD +ro+O8fHk0WIA7xhmW37TwDbQZof0RQ/DJNVFyAzCG5ohbTkRmGkbcBLMu6/dmkA0 +SeeoeRNFrUxiZclNeiqWwGxAMsnSKv+C2FbzAgMBAAGjYDBeMA8GA1UdEwEB/wQF +MAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQYajKJT+8bjGjCloph8kxjve8v +0zAfBgNVHSMEGDAWgBRAOl9pcSJ32ViEkypt/7yv/EQJ/zANBgkqhkiG9w0BAQsF +AAOCAQEAhOZZJd3ZZTDC2ARKtW79mt1XKB6wxnUobxxbOsjDFJKMfYI3f6vMpz4V +W+qVA+7CEoKyJN6XsRGpb3NQOSh3rIXrTp2JzCxPC5zy/GuGuJQusTUN1bECLRQB +jxHPQgDeLdycZgCgRxJFI/qe3J+VkPfQ0QWYUUE9Zhn1wlf/38z7jli2NaYH5vyL +O0FGXCvbsf/h29ElCkZEL1sU/d1okW6dJoAPrSAqhbJRYPIPf/YeANqHUG7qpCXo +tthD7XQsjbqPEAdlkV03tK0Jczfe7Yp6fVaa60VwAE73Jms6lYb73AtbN8Z7EBR8 +2RwDHLRnS43GXOGLa+5NtZTqrrV53A== -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/big_root.crt b/test/recipes/80-test_cmp_http_data/Mock/big_root.crt index 6f0124cc2f3ca..cecdb6a5b379c 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/big_root.crt +++ b/test/recipes/80-test_cmp_http_data/Mock/big_root.crt @@ -21,1534 +21,368 @@ GbK2mQxrogX4UWjtl+DfYvl+ejpEcYNXKEmIabUUHtpG42544cuPtZizLW5bt/aT JBQfpPZpvf9MUlACxUONFOLQdZ8SXpSJ0e93iX2J2Z52mSQ= -----END CERTIFICATE----- - - +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 +-----BEGIN CERTIFICATE----- +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIC7DCCAdSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1zaWdu +ZXItcm9vdENBMCAXDTI2MDkwODExNTU1OVoYDzIxMjYwOTA5MTE1NTU5WjAYMRYw +FAYDVQQDDA1zaWduZXItcm9vdENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAzDpXk0io89seBlAZkNotOxPZsjJv3voSWOnFN1OoOJq3uBtbqNKzr0b1 +Z60vBj/IatZFLAueX7MpJMAcDzN41fFiLJo735Jj8TqQtaOwrVxOQuQbfdc6Xu1v +LTY2Sulj18QszjVwv+bwILvfkDwikcuecJBIilEX8DaBbASOJiMMYbzJb8pkvzL9 +HG4y00lFVGcwh6ZsKLKo/8GtuIOLHYz0PEHMFgoBvvARmenrldVouZJ3pYodMhKt +DFGxvC2EYExocZQhsdsiNx8xMbbhVaJznKy/Fj8DoLIg8kpx4sXUyLiBkkIrinLd +/3NZ2MNJPKKRkHJpLhgysZ/sOgkPGQIDAQABoz8wPTAPBgNVHRMBAf8EBTADAQH/ +MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUp9K6S3HDOzTH7erY63Kn3xAinvMwDQYJ +KoZIhvcNAQELBQADggEBADqyP4m8tKX5BZ+op07cm9I816nZf41ikPVa7RCdsHdF +te/zGIis+svt/541XVW/5y5PDfeBx8r9dUzcUYezqCiHcEeH6FoDzOoHq4yJp1FN +614MgTF5K3Dab2JpmWWdtyyQJjgjhGYGE6vwMf5UoDSl1kLu6OyzY4fz02QAulhx +todAw+xbWP6xh4OGq3VqeT6MrxhdnAystnIUjwZUPfnITO77MbhsTi5R9RlEUhEA +YvGixH38Qd5bDG1Xf2xPGXvvLK5BwlAKrlw2kOrZZXKMZh24r+Pz5iZ5KV7UiGZD +SDFUoJVjp02owRDOA56tv3PRrLGwvKLzrTgsQdqOTts= +-----END CERTIFICATE----- -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIC7DCCAdSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1zaWdu +ZXItcm9vdENBMCAXDTI2MDgyNzEzMDIxOFoYDzIxMjYwODI4MTMwMjE4WjAYMRYw +FAYDVQQDDA1zaWduZXItcm9vdENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEArdsEEsPAXwKehceBZcTN0zd8+Qhv+HWqNHOXNlKX4Rwm5/Ph42ICuzVO +K0KbJSwPNLb5zttGw3rZ/r+oKHCXAiepKtAcou1W7UFRbFPDmmWPJB4WwHVv6I1Z +Fu/wFid4Dx1LXwOQ7QWENc/OwJbtnvN9X5/kiKkhEaqIbElQqeelA+Gw8uPdRg9s +5pTKN82knc86GgRxniS7ofqxhy3sDDCQJ9sC86fPYsqVZ21OH/adAkJ48TexgLIh +L1zdK+hfj09etmCVPbb9iLhP/z4x1glqOitIdnxkOmoe3ZigSKZwZyZsRlPd6msD +ZCS/EPkxOZyQRoRms1ilfe0i8U5xZwIDAQABoz8wPTAPBgNVHRMBAf8EBTADAQH/ +MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUoA1TXcKeefqbSnvsMKFWbkqQFsYwDQYJ +KoZIhvcNAQELBQADggEBAEuK74uzhJtAPJM31CKMZjBgfkxHheudb2jcPBiHQha7 +q+t3riQehGozWPwhMRBNaGTiJG7FTGjCp5lqrkQ9lUBkUqCy5mlTq9jR2ETK18Sf +N7vwaZ3rhnK99N/gL0SdRpuG/ed7WKTvveFSLhBwkHqijtY28uWvhanwboI3gObd +CU2OSd3umKuC/svf1S7p6py/t55dkljK2tcaLSDHVn+9ytqEGGOE96wJe35c5848 ++TWUqyMmvnvgiySq9zzu5XsHSTxHBwJUMds8Uu134MAhqkgY+xMSgqlq48uY0Ac0 +cDXn7ep55qVhu+ktX2JMuZsvXq2rrZbXyuRIy4GkJwM= -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/big_server.crt b/test/recipes/80-test_cmp_http_data/Mock/big_server.crt index 82e46310fcd56..8317d3003c923 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/big_server.crt +++ b/test/recipes/80-test_cmp_http_data/Mock/big_server.crt @@ -1,1550 +1,229 @@ - Subject: O = openssl_cmp - Issuer: O = openssl_cmp +Subject: CN = www.google.com -----BEGIN CERTIFICATE----- -MIICpTCCAY2gAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQKDAtvcGVu -c3NsX2NtcDAeFw0xNzEyMjAxMzA0MDBaFw0xODEyMjAxMzA0MDBaMBYxFDASBgNV -BAoMC29wZW5zc2xfY21wMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA -4ckRrH0UWmIJFj99kBqvCipGjJRAaPkdvWjdDQLglTpI3eZAJHnq0ypW/PZccrWj -o7mxuvAStEYWF+5Jx6ZFmAsC1K0NNebSAZQoLWYZqiOzkfVVpLicMnItNFElfCoh -BzPCYmF5UlC5yp9PSUEfNwPJqDIRMtw+IlVUV3AJw9TJ3uuWq/vWW9r96/gBKKdd -mj/q2gGT8RC6LxEaolTbhfPbHaA1DFpv1WQFb3oAV3Wq14SOZf9bH1olBVsmBMsU -shFEw5MXVrNCv2moM4HtITMyjvZe7eIwHzSzf6dvQjERG6GvZ/i5KOhaqgJCnRKd -HHzijz9cLec5p9NSOuC1OwIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQDGUXpFCBkV -WgPrBfZyBwt6VCjWB/e67q4IdcKMfDa4hwSquah1AyXHI0PlC/qitnoSx2+7f7pY -TEOay/3eEPUl1J5tdPF2Vg56Dw8jdhSkMwO7bXKDEE3R6o6jaa4ECgxwQtdGHmNU -A41PgKX76yEXku803ptO39/UR7i7Ye3MbyAmWE+PvixJYUbxd3fqz5fsaJqTCzAy -AT9hrr4uu8J7m3LYaYXo4LVL4jw5UsP5bIYtpmmEBfy9GhpUqH5/LzBNij7y3ziE -T59wHkzawAQDHsBPuCe07DFtlzqWWvaih0TQAw9MZ2tbyK9jt7P80Rqt9CwpM/i9 -jQYqSl/ix5hn ------END CERTIFICATE----- - - ------BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIDcjCCAxigAwIBAgIRAOyTTxWAETgwEke6OezpQ7swCgYIKoZIzj0EAwIwOzEL +MAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczEMMAoG +A1UEAxMDV0UyMB4XDTI2MDgxMDA4Mzk1NVoXDTI2MTEwMjA4Mzk1NFowGTEXMBUG +A1UEAxMOd3d3Lmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARg +C9/bNoIcmvbhO7bTZ/FXrD+6s97nhfcFHjMpPcqgOCRUbw6MR2xgFEs9A9CrIwo5 +v5RrTESgfwFPxD7LLyxTo4ICHTCCAhkwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBT2bqJKQ5xLkWb3 +pXEToMkqBbtAMB8GA1UdIwQYMBaAFHW+xHeuifZEN33PsWgfHRrr3DRZMDUGCCsG +AQUFBwEBBCkwJzAlBggrBgEFBQcwAoYZaHR0cDovL2kucGtpLmdvb2cvd2UyLmNy +dDAZBgNVHREEEjAQgg53d3cuZ29vZ2xlLmNvbTATBgNVHSAEDDAKMAgGBmeBDAEC +ATA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vYy5wa2kuZ29vZy93ZTIveUs1blBo +dEhLUXMuY3JsMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYA1219ENGn9XfCx+lf +1wC/+YLJM1pl4dCzAXMXwMjFaXcAAAGf6wsIhAAABAMARzBFAiEAmmiCMRImTYHS +/KIYV9ZaqpKhWUtu1UdIviilq/yJ3IMCIDuLhadpjL6i2fwVV9subl0EMFL+vBYn +NVbaPRoNpA4TAHUAlE5Dh/rswe+B8xkkJqgYZQHH0184AgE/cmd9VTcuGdgAAAGf +6wsIxQAABAMARjBEAiBDXhYxTl3qxR7Ejosoth7sEkoYhU7x60oSbL1xNueCJAIg +dYO9qu84YGfpgjMxxSH+UtHcpUro6Ksa9ydt4ARiIFcwCgYIKoZIzj0EAwIDSAAw +RQIgF6y5F53jOdS2vO6tAFpvoF86nkj2COxIQWm+e+DoMUACIQClpDVYozCX2Rhn +Bi6HTkP3iq0LIdbL+ZewNdtY6eG3KQ== -----END CERTIFICATE----- +Subject: CN = www.google.com -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIDcjCCAxigAwIBAgIRAOyTTxWAETgwEke6OezpQ7swCgYIKoZIzj0EAwIwOzEL +MAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczEMMAoG +A1UEAxMDV0UyMB4XDTI2MDgxMDA4Mzk1NVoXDTI2MTEwMjA4Mzk1NFowGTEXMBUG +A1UEAxMOd3d3Lmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARg +C9/bNoIcmvbhO7bTZ/FXrD+6s97nhfcFHjMpPcqgOCRUbw6MR2xgFEs9A9CrIwo5 +v5RrTESgfwFPxD7LLyxTo4ICHTCCAhkwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBT2bqJKQ5xLkWb3 +pXEToMkqBbtAMB8GA1UdIwQYMBaAFHW+xHeuifZEN33PsWgfHRrr3DRZMDUGCCsG +AQUFBwEBBCkwJzAlBggrBgEFBQcwAoYZaHR0cDovL2kucGtpLmdvb2cvd2UyLmNy +dDAZBgNVHREEEjAQgg53d3cuZ29vZ2xlLmNvbTATBgNVHSAEDDAKMAgGBmeBDAEC +ATA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vYy5wa2kuZ29vZy93ZTIveUs1blBo +dEhLUXMuY3JsMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYA1219ENGn9XfCx+lf +1wC/+YLJM1pl4dCzAXMXwMjFaXcAAAGf6wsIhAAABAMARzBFAiEAmmiCMRImTYHS +/KIYV9ZaqpKhWUtu1UdIviilq/yJ3IMCIDuLhadpjL6i2fwVV9subl0EMFL+vBYn +NVbaPRoNpA4TAHUAlE5Dh/rswe+B8xkkJqgYZQHH0184AgE/cmd9VTcuGdgAAAGf +6wsIxQAABAMARjBEAiBDXhYxTl3qxR7Ejosoth7sEkoYhU7x60oSbL1xNueCJAIg +dYO9qu84YGfpgjMxxSH+UtHcpUro6Ksa9ydt4ARiIFcwCgYIKoZIzj0EAwIDSAAw +RQIgF6y5F53jOdS2vO6tAFpvoF86nkj2COxIQWm+e+DoMUACIQClpDVYozCX2Rhn +Bi6HTkP3iq0LIdbL+ZewNdtY6eG3KQ== -----END CERTIFICATE----- +Subject: CN = www.google.com -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIDcjCCAxigAwIBAgIRAOyTTxWAETgwEke6OezpQ7swCgYIKoZIzj0EAwIwOzEL +MAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczEMMAoG +A1UEAxMDV0UyMB4XDTI2MDgxMDA4Mzk1NVoXDTI2MTEwMjA4Mzk1NFowGTEXMBUG +A1UEAxMOd3d3Lmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARg +C9/bNoIcmvbhO7bTZ/FXrD+6s97nhfcFHjMpPcqgOCRUbw6MR2xgFEs9A9CrIwo5 +v5RrTESgfwFPxD7LLyxTo4ICHTCCAhkwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBT2bqJKQ5xLkWb3 +pXEToMkqBbtAMB8GA1UdIwQYMBaAFHW+xHeuifZEN33PsWgfHRrr3DRZMDUGCCsG +AQUFBwEBBCkwJzAlBggrBgEFBQcwAoYZaHR0cDovL2kucGtpLmdvb2cvd2UyLmNy +dDAZBgNVHREEEjAQgg53d3cuZ29vZ2xlLmNvbTATBgNVHSAEDDAKMAgGBmeBDAEC +ATA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vYy5wa2kuZ29vZy93ZTIveUs1blBo +dEhLUXMuY3JsMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYA1219ENGn9XfCx+lf +1wC/+YLJM1pl4dCzAXMXwMjFaXcAAAGf6wsIhAAABAMARzBFAiEAmmiCMRImTYHS +/KIYV9ZaqpKhWUtu1UdIviilq/yJ3IMCIDuLhadpjL6i2fwVV9subl0EMFL+vBYn +NVbaPRoNpA4TAHUAlE5Dh/rswe+B8xkkJqgYZQHH0184AgE/cmd9VTcuGdgAAAGf +6wsIxQAABAMARjBEAiBDXhYxTl3qxR7Ejosoth7sEkoYhU7x60oSbL1xNueCJAIg +dYO9qu84YGfpgjMxxSH+UtHcpUro6Ksa9ydt4ARiIFcwCgYIKoZIzj0EAwIDSAAw +RQIgF6y5F53jOdS2vO6tAFpvoF86nkj2COxIQWm+e+DoMUACIQClpDVYozCX2Rhn +Bi6HTkP3iq0LIdbL+ZewNdtY6eG3KQ== -----END CERTIFICATE----- +Subject: CN = www.google.com -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIDcjCCAxigAwIBAgIRAOyTTxWAETgwEke6OezpQ7swCgYIKoZIzj0EAwIwOzEL +MAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczEMMAoG +A1UEAxMDV0UyMB4XDTI2MDgxMDA4Mzk1NVoXDTI2MTEwMjA4Mzk1NFowGTEXMBUG +A1UEAxMOd3d3Lmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARg +C9/bNoIcmvbhO7bTZ/FXrD+6s97nhfcFHjMpPcqgOCRUbw6MR2xgFEs9A9CrIwo5 +v5RrTESgfwFPxD7LLyxTo4ICHTCCAhkwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBT2bqJKQ5xLkWb3 +pXEToMkqBbtAMB8GA1UdIwQYMBaAFHW+xHeuifZEN33PsWgfHRrr3DRZMDUGCCsG +AQUFBwEBBCkwJzAlBggrBgEFBQcwAoYZaHR0cDovL2kucGtpLmdvb2cvd2UyLmNy +dDAZBgNVHREEEjAQgg53d3cuZ29vZ2xlLmNvbTATBgNVHSAEDDAKMAgGBmeBDAEC +ATA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vYy5wa2kuZ29vZy93ZTIveUs1blBo +dEhLUXMuY3JsMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYA1219ENGn9XfCx+lf +1wC/+YLJM1pl4dCzAXMXwMjFaXcAAAGf6wsIhAAABAMARzBFAiEAmmiCMRImTYHS +/KIYV9ZaqpKhWUtu1UdIviilq/yJ3IMCIDuLhadpjL6i2fwVV9subl0EMFL+vBYn +NVbaPRoNpA4TAHUAlE5Dh/rswe+B8xkkJqgYZQHH0184AgE/cmd9VTcuGdgAAAGf +6wsIxQAABAMARjBEAiBDXhYxTl3qxR7Ejosoth7sEkoYhU7x60oSbL1xNueCJAIg +dYO9qu84YGfpgjMxxSH+UtHcpUro6Ksa9ydt4ARiIFcwCgYIKoZIzj0EAwIDSAAw +RQIgF6y5F53jOdS2vO6tAFpvoF86nkj2COxIQWm+e+DoMUACIQClpDVYozCX2Rhn +Bi6HTkP3iq0LIdbL+ZewNdtY6eG3KQ== -----END CERTIFICATE----- +Subject: CN = www.google.com -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIDcjCCAxigAwIBAgIRAOyTTxWAETgwEke6OezpQ7swCgYIKoZIzj0EAwIwOzEL +MAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczEMMAoG +A1UEAxMDV0UyMB4XDTI2MDgxMDA4Mzk1NVoXDTI2MTEwMjA4Mzk1NFowGTEXMBUG +A1UEAxMOd3d3Lmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARg +C9/bNoIcmvbhO7bTZ/FXrD+6s97nhfcFHjMpPcqgOCRUbw6MR2xgFEs9A9CrIwo5 +v5RrTESgfwFPxD7LLyxTo4ICHTCCAhkwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBT2bqJKQ5xLkWb3 +pXEToMkqBbtAMB8GA1UdIwQYMBaAFHW+xHeuifZEN33PsWgfHRrr3DRZMDUGCCsG +AQUFBwEBBCkwJzAlBggrBgEFBQcwAoYZaHR0cDovL2kucGtpLmdvb2cvd2UyLmNy +dDAZBgNVHREEEjAQgg53d3cuZ29vZ2xlLmNvbTATBgNVHSAEDDAKMAgGBmeBDAEC +ATA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vYy5wa2kuZ29vZy93ZTIveUs1blBo +dEhLUXMuY3JsMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYA1219ENGn9XfCx+lf +1wC/+YLJM1pl4dCzAXMXwMjFaXcAAAGf6wsIhAAABAMARzBFAiEAmmiCMRImTYHS +/KIYV9ZaqpKhWUtu1UdIviilq/yJ3IMCIDuLhadpjL6i2fwVV9subl0EMFL+vBYn +NVbaPRoNpA4TAHUAlE5Dh/rswe+B8xkkJqgYZQHH0184AgE/cmd9VTcuGdgAAAGf +6wsIxQAABAMARjBEAiBDXhYxTl3qxR7Ejosoth7sEkoYhU7x60oSbL1xNueCJAIg +dYO9qu84YGfpgjMxxSH+UtHcpUro6Ksa9ydt4ARiIFcwCgYIKoZIzj0EAwIDSAAw +RQIgF6y5F53jOdS2vO6tAFpvoF86nkj2COxIQWm+e+DoMUACIQClpDVYozCX2Rhn +Bi6HTkP3iq0LIdbL+ZewNdtY6eG3KQ== -----END CERTIFICATE----- +Subject: CN = www.google.com -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIDcjCCAxigAwIBAgIRAOyTTxWAETgwEke6OezpQ7swCgYIKoZIzj0EAwIwOzEL +MAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczEMMAoG +A1UEAxMDV0UyMB4XDTI2MDgxMDA4Mzk1NVoXDTI2MTEwMjA4Mzk1NFowGTEXMBUG +A1UEAxMOd3d3Lmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARg +C9/bNoIcmvbhO7bTZ/FXrD+6s97nhfcFHjMpPcqgOCRUbw6MR2xgFEs9A9CrIwo5 +v5RrTESgfwFPxD7LLyxTo4ICHTCCAhkwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBT2bqJKQ5xLkWb3 +pXEToMkqBbtAMB8GA1UdIwQYMBaAFHW+xHeuifZEN33PsWgfHRrr3DRZMDUGCCsG +AQUFBwEBBCkwJzAlBggrBgEFBQcwAoYZaHR0cDovL2kucGtpLmdvb2cvd2UyLmNy +dDAZBgNVHREEEjAQgg53d3cuZ29vZ2xlLmNvbTATBgNVHSAEDDAKMAgGBmeBDAEC +ATA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vYy5wa2kuZ29vZy93ZTIveUs1blBo +dEhLUXMuY3JsMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYA1219ENGn9XfCx+lf +1wC/+YLJM1pl4dCzAXMXwMjFaXcAAAGf6wsIhAAABAMARzBFAiEAmmiCMRImTYHS +/KIYV9ZaqpKhWUtu1UdIviilq/yJ3IMCIDuLhadpjL6i2fwVV9subl0EMFL+vBYn +NVbaPRoNpA4TAHUAlE5Dh/rswe+B8xkkJqgYZQHH0184AgE/cmd9VTcuGdgAAAGf +6wsIxQAABAMARjBEAiBDXhYxTl3qxR7Ejosoth7sEkoYhU7x60oSbL1xNueCJAIg +dYO9qu84YGfpgjMxxSH+UtHcpUro6Ksa9ydt4ARiIFcwCgYIKoZIzj0EAwIDSAAw +RQIgF6y5F53jOdS2vO6tAFpvoF86nkj2COxIQWm+e+DoMUACIQClpDVYozCX2Rhn +Bi6HTkP3iq0LIdbL+ZewNdtY6eG3KQ== -----END CERTIFICATE----- +Subject: CN = www.google.com -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIDcjCCAxigAwIBAgIRAOyTTxWAETgwEke6OezpQ7swCgYIKoZIzj0EAwIwOzEL +MAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczEMMAoG +A1UEAxMDV0UyMB4XDTI2MDgxMDA4Mzk1NVoXDTI2MTEwMjA4Mzk1NFowGTEXMBUG +A1UEAxMOd3d3Lmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARg +C9/bNoIcmvbhO7bTZ/FXrD+6s97nhfcFHjMpPcqgOCRUbw6MR2xgFEs9A9CrIwo5 +v5RrTESgfwFPxD7LLyxTo4ICHTCCAhkwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBT2bqJKQ5xLkWb3 +pXEToMkqBbtAMB8GA1UdIwQYMBaAFHW+xHeuifZEN33PsWgfHRrr3DRZMDUGCCsG +AQUFBwEBBCkwJzAlBggrBgEFBQcwAoYZaHR0cDovL2kucGtpLmdvb2cvd2UyLmNy +dDAZBgNVHREEEjAQgg53d3cuZ29vZ2xlLmNvbTATBgNVHSAEDDAKMAgGBmeBDAEC +ATA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vYy5wa2kuZ29vZy93ZTIveUs1blBo +dEhLUXMuY3JsMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYA1219ENGn9XfCx+lf +1wC/+YLJM1pl4dCzAXMXwMjFaXcAAAGf6wsIhAAABAMARzBFAiEAmmiCMRImTYHS +/KIYV9ZaqpKhWUtu1UdIviilq/yJ3IMCIDuLhadpjL6i2fwVV9subl0EMFL+vBYn +NVbaPRoNpA4TAHUAlE5Dh/rswe+B8xkkJqgYZQHH0184AgE/cmd9VTcuGdgAAAGf +6wsIxQAABAMARjBEAiBDXhYxTl3qxR7Ejosoth7sEkoYhU7x60oSbL1xNueCJAIg +dYO9qu84YGfpgjMxxSH+UtHcpUro6Ksa9ydt4ARiIFcwCgYIKoZIzj0EAwIDSAAw +RQIgF6y5F53jOdS2vO6tAFpvoF86nkj2COxIQWm+e+DoMUACIQClpDVYozCX2Rhn +Bi6HTkP3iq0LIdbL+ZewNdtY6eG3KQ== -----END CERTIFICATE----- +Subject: CN = www.google.com -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIDcjCCAxigAwIBAgIRAOyTTxWAETgwEke6OezpQ7swCgYIKoZIzj0EAwIwOzEL +MAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczEMMAoG +A1UEAxMDV0UyMB4XDTI2MDgxMDA4Mzk1NVoXDTI2MTEwMjA4Mzk1NFowGTEXMBUG +A1UEAxMOd3d3Lmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARg +C9/bNoIcmvbhO7bTZ/FXrD+6s97nhfcFHjMpPcqgOCRUbw6MR2xgFEs9A9CrIwo5 +v5RrTESgfwFPxD7LLyxTo4ICHTCCAhkwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBT2bqJKQ5xLkWb3 +pXEToMkqBbtAMB8GA1UdIwQYMBaAFHW+xHeuifZEN33PsWgfHRrr3DRZMDUGCCsG +AQUFBwEBBCkwJzAlBggrBgEFBQcwAoYZaHR0cDovL2kucGtpLmdvb2cvd2UyLmNy +dDAZBgNVHREEEjAQgg53d3cuZ29vZ2xlLmNvbTATBgNVHSAEDDAKMAgGBmeBDAEC +ATA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vYy5wa2kuZ29vZy93ZTIveUs1blBo +dEhLUXMuY3JsMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYA1219ENGn9XfCx+lf +1wC/+YLJM1pl4dCzAXMXwMjFaXcAAAGf6wsIhAAABAMARzBFAiEAmmiCMRImTYHS +/KIYV9ZaqpKhWUtu1UdIviilq/yJ3IMCIDuLhadpjL6i2fwVV9subl0EMFL+vBYn +NVbaPRoNpA4TAHUAlE5Dh/rswe+B8xkkJqgYZQHH0184AgE/cmd9VTcuGdgAAAGf +6wsIxQAABAMARjBEAiBDXhYxTl3qxR7Ejosoth7sEkoYhU7x60oSbL1xNueCJAIg +dYO9qu84YGfpgjMxxSH+UtHcpUro6Ksa9ydt4ARiIFcwCgYIKoZIzj0EAwIDSAAw +RQIgF6y5F53jOdS2vO6tAFpvoF86nkj2COxIQWm+e+DoMUACIQClpDVYozCX2Rhn +Bi6HTkP3iq0LIdbL+ZewNdtY6eG3KQ== -----END CERTIFICATE----- +Subject: CN = www.google.com -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIDcjCCAxigAwIBAgIRAOyTTxWAETgwEke6OezpQ7swCgYIKoZIzj0EAwIwOzEL +MAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczEMMAoG +A1UEAxMDV0UyMB4XDTI2MDgxMDA4Mzk1NVoXDTI2MTEwMjA4Mzk1NFowGTEXMBUG +A1UEAxMOd3d3Lmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARg +C9/bNoIcmvbhO7bTZ/FXrD+6s97nhfcFHjMpPcqgOCRUbw6MR2xgFEs9A9CrIwo5 +v5RrTESgfwFPxD7LLyxTo4ICHTCCAhkwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBT2bqJKQ5xLkWb3 +pXEToMkqBbtAMB8GA1UdIwQYMBaAFHW+xHeuifZEN33PsWgfHRrr3DRZMDUGCCsG +AQUFBwEBBCkwJzAlBggrBgEFBQcwAoYZaHR0cDovL2kucGtpLmdvb2cvd2UyLmNy +dDAZBgNVHREEEjAQgg53d3cuZ29vZ2xlLmNvbTATBgNVHSAEDDAKMAgGBmeBDAEC +ATA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vYy5wa2kuZ29vZy93ZTIveUs1blBo +dEhLUXMuY3JsMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYA1219ENGn9XfCx+lf +1wC/+YLJM1pl4dCzAXMXwMjFaXcAAAGf6wsIhAAABAMARzBFAiEAmmiCMRImTYHS +/KIYV9ZaqpKhWUtu1UdIviilq/yJ3IMCIDuLhadpjL6i2fwVV9subl0EMFL+vBYn +NVbaPRoNpA4TAHUAlE5Dh/rswe+B8xkkJqgYZQHH0184AgE/cmd9VTcuGdgAAAGf +6wsIxQAABAMARjBEAiBDXhYxTl3qxR7Ejosoth7sEkoYhU7x60oSbL1xNueCJAIg +dYO9qu84YGfpgjMxxSH+UtHcpUro6Ksa9ydt4ARiIFcwCgYIKoZIzj0EAwIDSAAw +RQIgF6y5F53jOdS2vO6tAFpvoF86nkj2COxIQWm+e+DoMUACIQClpDVYozCX2Rhn +Bi6HTkP3iq0LIdbL+ZewNdtY6eG3KQ== -----END CERTIFICATE----- +Subject: CN = www.google.com -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIDcjCCAxigAwIBAgIRAOyTTxWAETgwEke6OezpQ7swCgYIKoZIzj0EAwIwOzEL +MAkGA1UEBhMCVVMxHjAcBgNVBAoTFUdvb2dsZSBUcnVzdCBTZXJ2aWNlczEMMAoG +A1UEAxMDV0UyMB4XDTI2MDgxMDA4Mzk1NVoXDTI2MTEwMjA4Mzk1NFowGTEXMBUG +A1UEAxMOd3d3Lmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARg +C9/bNoIcmvbhO7bTZ/FXrD+6s97nhfcFHjMpPcqgOCRUbw6MR2xgFEs9A9CrIwo5 +v5RrTESgfwFPxD7LLyxTo4ICHTCCAhkwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQM +MAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFBT2bqJKQ5xLkWb3 +pXEToMkqBbtAMB8GA1UdIwQYMBaAFHW+xHeuifZEN33PsWgfHRrr3DRZMDUGCCsG +AQUFBwEBBCkwJzAlBggrBgEFBQcwAoYZaHR0cDovL2kucGtpLmdvb2cvd2UyLmNy +dDAZBgNVHREEEjAQgg53d3cuZ29vZ2xlLmNvbTATBgNVHSAEDDAKMAgGBmeBDAEC +ATA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vYy5wa2kuZ29vZy93ZTIveUs1blBo +dEhLUXMuY3JsMIIBAwYKKwYBBAHWeQIEAgSB9ASB8QDvAHYA1219ENGn9XfCx+lf +1wC/+YLJM1pl4dCzAXMXwMjFaXcAAAGf6wsIhAAABAMARzBFAiEAmmiCMRImTYHS +/KIYV9ZaqpKhWUtu1UdIviilq/yJ3IMCIDuLhadpjL6i2fwVV9subl0EMFL+vBYn +NVbaPRoNpA4TAHUAlE5Dh/rswe+B8xkkJqgYZQHH0184AgE/cmd9VTcuGdgAAAGf +6wsIxQAABAMARjBEAiBDXhYxTl3qxR7Ejosoth7sEkoYhU7x60oSbL1xNueCJAIg +dYO9qu84YGfpgjMxxSH+UtHcpUro6Ksa9ydt4ARiIFcwCgYIKoZIzj0EAwIDSAAw +RQIgF6y5F53jOdS2vO6tAFpvoF86nkj2COxIQWm+e+DoMUACIQClpDVYozCX2Rhn +Bi6HTkP3iq0LIdbL+ZewNdtY6eG3KQ== -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/big_trusted.crt b/test/recipes/80-test_cmp_http_data/Mock/big_trusted.crt index 3bd3458e10e87..667921589b74f 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/big_trusted.crt +++ b/test/recipes/80-test_cmp_http_data/Mock/big_trusted.crt @@ -1,1552 +1,347 @@ - Subject: O = openssl_cmp - Issuer: O = openssl_cmp +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIICpTCCAY2gAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQKDAtvcGVu -c3NsX2NtcDAeFw0xNzEyMjAxMzA0MDBaFw0xODEyMjAxMzA0MDBaMBYxFDASBgNV -BAoMC29wZW5zc2xfY21wMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA -4ckRrH0UWmIJFj99kBqvCipGjJRAaPkdvWjdDQLglTpI3eZAJHnq0ypW/PZccrWj -o7mxuvAStEYWF+5Jx6ZFmAsC1K0NNebSAZQoLWYZqiOzkfVVpLicMnItNFElfCoh -BzPCYmF5UlC5yp9PSUEfNwPJqDIRMtw+IlVUV3AJw9TJ3uuWq/vWW9r96/gBKKdd -mj/q2gGT8RC6LxEaolTbhfPbHaA1DFpv1WQFb3oAV3Wq14SOZf9bH1olBVsmBMsU -shFEw5MXVrNCv2moM4HtITMyjvZe7eIwHzSzf6dvQjERG6GvZ/i5KOhaqgJCnRKd -HHzijz9cLec5p9NSOuC1OwIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQDGUXpFCBkV -WgPrBfZyBwt6VCjWB/e67q4IdcKMfDa4hwSquah1AyXHI0PlC/qitnoSx2+7f7pY -TEOay/3eEPUl1J5tdPF2Vg56Dw8jdhSkMwO7bXKDEE3R6o6jaa4ECgxwQtdGHmNU -A41PgKX76yEXku803ptO39/UR7i7Ye3MbyAmWE+PvixJYUbxd3fqz5fsaJqTCzAy -AT9hrr4uu8J7m3LYaYXo4LVL4jw5UsP5bIYtpmmEBfy9GhpUqH5/LzBNij7y3ziE -T59wHkzawAQDHsBPuCe07DFtlzqWWvaih0TQAw9MZ2tbyK9jt7P80Rqt9CwpM/i9 -jQYqSl/ix5hn +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- - - - +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- +Subject: C = US, O = Google Trust Services LLC, CN = GTS Root R1 -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAw +MDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZp +Y2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0GCSqGSIb3DQEBAQUA +A4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaMf/vo +27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7w +Cl7raKb0xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjw +TcLCeoiKu7rPWRnWr4+wB7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0Pfybl +qAj+lug8aJRT7oM6iCsVlgmy4HqMLnXWnOunVmSPlk9orj2XwoSPwLxAwAtcvfaH +szVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk9+aCEI3oncKKiPo4Zor8 +Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zqkUspzBmk +MiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92 +wO1AK/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70p +aDPvOmbsB4om3xPXV2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrN +VjzRlwW5y0vtOUucxD/SVRNuJLDWcfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQID +AQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E +FgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQADggIBAJ+qQibb +C5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe +QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuy +h6f88/qBVRRiClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM4 +7HLwEXWdyzRSjeZ2axfG34arJ45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8J +ZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYciNuaCp+0KueIHoI17eko8cdLiA6Ef +MgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5meLMFrUKTX5hgUvYU/ +Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJFfbdT +6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ +0E6yove+7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm +2tIMPNuzjsmhDYAPexZ3FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bb +bP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3gm3c -----END CERTIFICATE----- - -----BEGIN CERTIFICATE----- -MIIcFzCCG4CgAwIBAgIGR09PUAFxMA0GCSqGSIb3DQEBBQUAMEYxCzAJBgNVBAYT -AlVTMRMwEQYDVQQKEwpHb29nbGUgSW5jMSIwIAYDVQQDExlHb29nbGUgSW50ZXJu -ZXQgQXV0aG9yaXR5MB4XDTEyMTAyNDEzNTczOVoXDTEzMDYwNzE5NDMyN1owZDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDU1vdW50 -YWluIFZpZXcxEzARBgNVBAoTCkdvb2dsZSBJbmMxEzARBgNVBAMTCmdvb2dsZS5j -b20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMNn/Rw5irMPscWpYsExcGQT -wqdxT/U9Pfybt9ttPYlXVbCd6yux0jWGNBHN+f4kCc5pwrbjmA4QSRY2uVa4T8f2 -g3NucDDveUi29WVN+FJcyhj+V38lEkYbdhpIZL149dK5fAN1zzwCo10Nk+lhebcY -fCtMHLmuCX2D6mJ2CnPVAgMBAAGjghnwMIIZ7DAMBgNVHRMBAf8EAjAAMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAdBgNVHQ4EFgQU0Qp1w0hi4nhbaJEB -h/wuZwO4OyIwHwYDVR0jBBgwFoAUv8Aw6/VDET5nup6R+/xq2uNrEiQwWwYDVR0f -BFQwUjBQoE6gTIZKaHR0cDovL3d3dy5nc3RhdGljLmNvbS9Hb29nbGVJbnRlcm5l -dEF1dGhvcml0eS9Hb29nbGVJbnRlcm5ldEF1dGhvcml0eS5jcmwwZgYIKwYBBQUH -AQEEWjBYMFYGCCsGAQUFBzAChkpodHRwOi8vd3d3LmdzdGF0aWMuY29tL0dvb2ds -ZUludGVybmV0QXV0aG9yaXR5L0dvb2dsZUludGVybmV0QXV0aG9yaXR5LmNydDCC -GLYGA1UdEQSCGK0wghipggpnb29nbGUuY29tggwqLmdvb2dsZS5jb22CDSoueW91 -dHViZS5jb22CC3lvdXR1YmUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggh5 -b3V0dS5iZYILKi55dGltZy5jb22CDSouYW5kcm9pZC5jb22CC2FuZHJvaWQuY29t -ghQqLmdvb2dsZWNvbW1lcmNlLmNvbYISZ29vZ2xlY29tbWVyY2UuY29tghAqLnVy -bC5nb29nbGUuY29tggwqLnVyY2hpbi5jb22CCnVyY2hpbi5jb22CFiouZ29vZ2xl -LWFuYWx5dGljcy5jb22CFGdvb2dsZS1hbmFseXRpY3MuY29tghIqLmNsb3VkLmdv -b2dsZS5jb22CBmdvby5nbIIEZy5jb4INKi5nc3RhdGljLmNvbYIPKi5nb29nbGVh -cGlzLmNughYqLmFwcGVuZ2luZS5nb29nbGUuY29tggsqLmdvb2dsZS5hY4ILKi5n -b29nbGUuYWSCCyouZ29vZ2xlLmFlggsqLmdvb2dsZS5hZoILKi5nb29nbGUuYWeC -CyouZ29vZ2xlLmFsggsqLmdvb2dsZS5hbYILKi5nb29nbGUuYXOCCyouZ29vZ2xl -LmF0ggsqLmdvb2dsZS5heoILKi5nb29nbGUuYmGCCyouZ29vZ2xlLmJlggsqLmdv -b2dsZS5iZoILKi5nb29nbGUuYmeCCyouZ29vZ2xlLmJpggsqLmdvb2dsZS5iaoIL -Ki5nb29nbGUuYnOCCyouZ29vZ2xlLmJ5ggsqLmdvb2dsZS5jYYIMKi5nb29nbGUu -Y2F0ggsqLmdvb2dsZS5jY4ILKi5nb29nbGUuY2SCCyouZ29vZ2xlLmNmggsqLmdv -b2dsZS5jZ4ILKi5nb29nbGUuY2iCCyouZ29vZ2xlLmNpggsqLmdvb2dsZS5jbIIL -Ki5nb29nbGUuY22CCyouZ29vZ2xlLmNugg4qLmdvb2dsZS5jby5hb4IOKi5nb29n -bGUuY28uYneCDiouZ29vZ2xlLmNvLmNrgg4qLmdvb2dsZS5jby5jcoIOKi5nb29n -bGUuY28uaHWCDiouZ29vZ2xlLmNvLmlkgg4qLmdvb2dsZS5jby5pbIIOKi5nb29n -bGUuY28uaW2CDiouZ29vZ2xlLmNvLmlugg4qLmdvb2dsZS5jby5qZYIOKi5nb29n -bGUuY28uanCCDiouZ29vZ2xlLmNvLmtlgg4qLmdvb2dsZS5jby5rcoIOKi5nb29n -bGUuY28ubHOCDiouZ29vZ2xlLmNvLm1hgg4qLmdvb2dsZS5jby5teoIOKi5nb29n -bGUuY28ubnqCDiouZ29vZ2xlLmNvLnRogg4qLmdvb2dsZS5jby50eoIOKi5nb29n -bGUuY28udWeCDiouZ29vZ2xlLmNvLnVrgg4qLmdvb2dsZS5jby51eoIOKi5nb29n -bGUuY28udmWCDiouZ29vZ2xlLmNvLnZpgg4qLmdvb2dsZS5jby56YYIOKi5nb29n -bGUuY28uem2CDiouZ29vZ2xlLmNvLnp3gg8qLmdvb2dsZS5jb20uYWaCDyouZ29v -Z2xlLmNvbS5hZ4IPKi5nb29nbGUuY29tLmFpgg8qLmdvb2dsZS5jb20uYXKCDyou -Z29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJkgg8qLmdvb2dsZS5jb20uYmiC -DyouZ29vZ2xlLmNvbS5iboIPKi5nb29nbGUuY29tLmJvgg8qLmdvb2dsZS5jb20u -YnKCDyouZ29vZ2xlLmNvbS5ieYIPKi5nb29nbGUuY29tLmJ6gg8qLmdvb2dsZS5j -b20uY26CDyouZ29vZ2xlLmNvbS5jb4IPKi5nb29nbGUuY29tLmN1gg8qLmdvb2ds -ZS5jb20uY3mCDyouZ29vZ2xlLmNvbS5kb4IPKi5nb29nbGUuY29tLmVjgg8qLmdv -b2dsZS5jb20uZWeCDyouZ29vZ2xlLmNvbS5ldIIPKi5nb29nbGUuY29tLmZqgg8q -Lmdvb2dsZS5jb20uZ2WCDyouZ29vZ2xlLmNvbS5naIIPKi5nb29nbGUuY29tLmdp -gg8qLmdvb2dsZS5jb20uZ3KCDyouZ29vZ2xlLmNvbS5ndIIPKi5nb29nbGUuY29t -Lmhrgg8qLmdvb2dsZS5jb20uaXGCDyouZ29vZ2xlLmNvbS5qbYIPKi5nb29nbGUu -Y29tLmpvgg8qLmdvb2dsZS5jb20ua2iCDyouZ29vZ2xlLmNvbS5rd4IPKi5nb29n -bGUuY29tLmxigg8qLmdvb2dsZS5jb20ubHmCDyouZ29vZ2xlLmNvbS5tdIIPKi5n -b29nbGUuY29tLm14gg8qLmdvb2dsZS5jb20ubXmCDyouZ29vZ2xlLmNvbS5uYYIP -Ki5nb29nbGUuY29tLm5mgg8qLmdvb2dsZS5jb20ubmeCDyouZ29vZ2xlLmNvbS5u -aYIPKi5nb29nbGUuY29tLm5wgg8qLmdvb2dsZS5jb20ubnKCDyouZ29vZ2xlLmNv -bS5vbYIPKi5nb29nbGUuY29tLnBhgg8qLmdvb2dsZS5jb20ucGWCDyouZ29vZ2xl -LmNvbS5waIIPKi5nb29nbGUuY29tLnBrgg8qLmdvb2dsZS5jb20ucGyCDyouZ29v -Z2xlLmNvbS5wcoIPKi5nb29nbGUuY29tLnB5gg8qLmdvb2dsZS5jb20ucWGCDyou -Z29vZ2xlLmNvbS5ydYIPKi5nb29nbGUuY29tLnNhgg8qLmdvb2dsZS5jb20uc2KC -DyouZ29vZ2xlLmNvbS5zZ4IPKi5nb29nbGUuY29tLnNsgg8qLmdvb2dsZS5jb20u -c3aCDyouZ29vZ2xlLmNvbS50aoIPKi5nb29nbGUuY29tLnRugg8qLmdvb2dsZS5j -b20udHKCDyouZ29vZ2xlLmNvbS50d4IPKi5nb29nbGUuY29tLnVhgg8qLmdvb2ds -ZS5jb20udXmCDyouZ29vZ2xlLmNvbS52Y4IPKi5nb29nbGUuY29tLnZlgg8qLmdv -b2dsZS5jb20udm6CCyouZ29vZ2xlLmN2ggsqLmdvb2dsZS5jeoILKi5nb29nbGUu -ZGWCCyouZ29vZ2xlLmRqggsqLmdvb2dsZS5ka4ILKi5nb29nbGUuZG2CCyouZ29v -Z2xlLmR6ggsqLmdvb2dsZS5lZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZpggsq -Lmdvb2dsZS5mbYILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmdhggsqLmdvb2dsZS5n -ZYILKi5nb29nbGUuZ2eCCyouZ29vZ2xlLmdsggsqLmdvb2dsZS5nbYILKi5nb29n -bGUuZ3CCCyouZ29vZ2xlLmdyggsqLmdvb2dsZS5neYILKi5nb29nbGUuaGuCCyou -Z29vZ2xlLmhuggsqLmdvb2dsZS5ocoILKi5nb29nbGUuaHSCCyouZ29vZ2xlLmh1 -ggsqLmdvb2dsZS5pZYILKi5nb29nbGUuaW2CDSouZ29vZ2xlLmluZm+CCyouZ29v -Z2xlLmlxggsqLmdvb2dsZS5pc4ILKi5nb29nbGUuaXSCDiouZ29vZ2xlLml0LmFv -ggsqLmdvb2dsZS5qZYILKi5nb29nbGUuam+CDSouZ29vZ2xlLmpvYnOCCyouZ29v -Z2xlLmpwggsqLmdvb2dsZS5rZ4ILKi5nb29nbGUua2mCCyouZ29vZ2xlLmt6ggsq -Lmdvb2dsZS5sYYILKi5nb29nbGUubGmCCyouZ29vZ2xlLmxrggsqLmdvb2dsZS5s -dIILKi5nb29nbGUubHWCCyouZ29vZ2xlLmx2ggsqLmdvb2dsZS5tZIILKi5nb29n -bGUubWWCCyouZ29vZ2xlLm1nggsqLmdvb2dsZS5ta4ILKi5nb29nbGUubWyCCyou -Z29vZ2xlLm1uggsqLmdvb2dsZS5tc4ILKi5nb29nbGUubXWCCyouZ29vZ2xlLm12 -ggsqLmdvb2dsZS5td4ILKi5nb29nbGUubmWCDiouZ29vZ2xlLm5lLmpwggwqLmdv -b2dsZS5uZXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5ub4ILKi5nb29nbGUubnKC -CyouZ29vZ2xlLm51gg8qLmdvb2dsZS5vZmYuYWmCCyouZ29vZ2xlLnBrggsqLmdv -b2dsZS5wbIILKi5nb29nbGUucG6CCyouZ29vZ2xlLnBzggsqLmdvb2dsZS5wdIIL -Ki5nb29nbGUucm+CCyouZ29vZ2xlLnJzggsqLmdvb2dsZS5ydYILKi5nb29nbGUu -cneCCyouZ29vZ2xlLnNjggsqLmdvb2dsZS5zZYILKi5nb29nbGUuc2iCCyouZ29v -Z2xlLnNpggsqLmdvb2dsZS5za4ILKi5nb29nbGUuc22CCyouZ29vZ2xlLnNuggsq -Lmdvb2dsZS5zb4ILKi5nb29nbGUuc3SCCyouZ29vZ2xlLnRkggsqLmdvb2dsZS50 -Z4ILKi5nb29nbGUudGuCCyouZ29vZ2xlLnRsggsqLmdvb2dsZS50bYILKi5nb29n -bGUudG6CCyouZ29vZ2xlLnRvggsqLmdvb2dsZS50cIILKi5nb29nbGUudHSCCyou -Z29vZ2xlLnVzggsqLmdvb2dsZS51eoILKi5nb29nbGUudmeCCyouZ29vZ2xlLnZ1 -ggsqLmdvb2dsZS53c4IJZ29vZ2xlLmFjgglnb29nbGUuYWSCCWdvb2dsZS5hZYIJ -Z29vZ2xlLmFmgglnb29nbGUuYWeCCWdvb2dsZS5hbIIJZ29vZ2xlLmFtgglnb29n -bGUuYXOCCWdvb2dsZS5hdIIJZ29vZ2xlLmF6gglnb29nbGUuYmGCCWdvb2dsZS5i -ZYIJZ29vZ2xlLmJmgglnb29nbGUuYmeCCWdvb2dsZS5iaYIJZ29vZ2xlLmJqggln -b29nbGUuYnOCCWdvb2dsZS5ieYIJZ29vZ2xlLmNhggpnb29nbGUuY2F0gglnb29n -bGUuY2OCCWdvb2dsZS5jZIIJZ29vZ2xlLmNmgglnb29nbGUuY2eCCWdvb2dsZS5j -aIIJZ29vZ2xlLmNpgglnb29nbGUuY2yCCWdvb2dsZS5jbYIJZ29vZ2xlLmNuggxn -b29nbGUuY28uYW+CDGdvb2dsZS5jby5id4IMZ29vZ2xlLmNvLmNrggxnb29nbGUu -Y28uY3KCDGdvb2dsZS5jby5odYIMZ29vZ2xlLmNvLmlkggxnb29nbGUuY28uaWyC -DGdvb2dsZS5jby5pbYIMZ29vZ2xlLmNvLmluggxnb29nbGUuY28uamWCDGdvb2ds -ZS5jby5qcIIMZ29vZ2xlLmNvLmtlggxnb29nbGUuY28ua3KCDGdvb2dsZS5jby5s -c4IMZ29vZ2xlLmNvLm1hggxnb29nbGUuY28ubXqCDGdvb2dsZS5jby5ueoIMZ29v -Z2xlLmNvLnRoggxnb29nbGUuY28udHqCDGdvb2dsZS5jby51Z4IMZ29vZ2xlLmNv -LnVrggxnb29nbGUuY28udXqCDGdvb2dsZS5jby52ZYIMZ29vZ2xlLmNvLnZpggxn -b29nbGUuY28uemGCDGdvb2dsZS5jby56bYIMZ29vZ2xlLmNvLnp3gg1nb29nbGUu -Y29tLmFmgg1nb29nbGUuY29tLmFngg1nb29nbGUuY29tLmFpgg1nb29nbGUuY29t -LmFygg1nb29nbGUuY29tLmF1gg1nb29nbGUuY29tLmJkgg1nb29nbGUuY29tLmJo -gg1nb29nbGUuY29tLmJugg1nb29nbGUuY29tLmJvgg1nb29nbGUuY29tLmJygg1n -b29nbGUuY29tLmJ5gg1nb29nbGUuY29tLmJ6gg1nb29nbGUuY29tLmNugg1nb29n -bGUuY29tLmNvgg1nb29nbGUuY29tLmN1gg1nb29nbGUuY29tLmN5gg1nb29nbGUu -Y29tLmRvgg1nb29nbGUuY29tLmVjgg1nb29nbGUuY29tLmVngg1nb29nbGUuY29t -LmV0gg1nb29nbGUuY29tLmZqgg1nb29nbGUuY29tLmdlgg1nb29nbGUuY29tLmdo -gg1nb29nbGUuY29tLmdpgg1nb29nbGUuY29tLmdygg1nb29nbGUuY29tLmd0gg1n -b29nbGUuY29tLmhrgg1nb29nbGUuY29tLmlxgg1nb29nbGUuY29tLmptgg1nb29n -bGUuY29tLmpvgg1nb29nbGUuY29tLmtogg1nb29nbGUuY29tLmt3gg1nb29nbGUu -Y29tLmxigg1nb29nbGUuY29tLmx5gg1nb29nbGUuY29tLm10gg1nb29nbGUuY29t -Lm14gg1nb29nbGUuY29tLm15gg1nb29nbGUuY29tLm5hgg1nb29nbGUuY29tLm5m -gg1nb29nbGUuY29tLm5ngg1nb29nbGUuY29tLm5pgg1nb29nbGUuY29tLm5wgg1n -b29nbGUuY29tLm5ygg1nb29nbGUuY29tLm9tgg1nb29nbGUuY29tLnBhgg1nb29n -bGUuY29tLnBlgg1nb29nbGUuY29tLnBogg1nb29nbGUuY29tLnBrgg1nb29nbGUu -Y29tLnBsgg1nb29nbGUuY29tLnBygg1nb29nbGUuY29tLnB5gg1nb29nbGUuY29t -LnFhgg1nb29nbGUuY29tLnJ1gg1nb29nbGUuY29tLnNhgg1nb29nbGUuY29tLnNi -gg1nb29nbGUuY29tLnNngg1nb29nbGUuY29tLnNsgg1nb29nbGUuY29tLnN2gg1n -b29nbGUuY29tLnRqgg1nb29nbGUuY29tLnRugg1nb29nbGUuY29tLnRygg1nb29n -bGUuY29tLnR3gg1nb29nbGUuY29tLnVhgg1nb29nbGUuY29tLnV5gg1nb29nbGUu -Y29tLnZjgg1nb29nbGUuY29tLnZlgg1nb29nbGUuY29tLnZugglnb29nbGUuY3aC -CWdvb2dsZS5jeoIJZ29vZ2xlLmRlgglnb29nbGUuZGqCCWdvb2dsZS5ka4IJZ29v -Z2xlLmRtgglnb29nbGUuZHqCCWdvb2dsZS5lZYIJZ29vZ2xlLmVzgglnb29nbGUu -ZmmCCWdvb2dsZS5mbYIJZ29vZ2xlLmZygglnb29nbGUuZ2GCCWdvb2dsZS5nZYIJ -Z29vZ2xlLmdngglnb29nbGUuZ2yCCWdvb2dsZS5nbYIJZ29vZ2xlLmdwgglnb29n -bGUuZ3KCCWdvb2dsZS5neYIJZ29vZ2xlLmhrgglnb29nbGUuaG6CCWdvb2dsZS5o -coIJZ29vZ2xlLmh0gglnb29nbGUuaHWCCWdvb2dsZS5pZYIJZ29vZ2xlLmltggtn -b29nbGUuaW5mb4IJZ29vZ2xlLmlxgglnb29nbGUuaXOCCWdvb2dsZS5pdIIMZ29v -Z2xlLml0LmFvgglnb29nbGUuamWCCWdvb2dsZS5qb4ILZ29vZ2xlLmpvYnOCCWdv -b2dsZS5qcIIJZ29vZ2xlLmtngglnb29nbGUua2mCCWdvb2dsZS5reoIJZ29vZ2xl -Lmxhgglnb29nbGUubGmCCWdvb2dsZS5sa4IJZ29vZ2xlLmx0gglnb29nbGUubHWC -CWdvb2dsZS5sdoIJZ29vZ2xlLm1kgglnb29nbGUubWWCCWdvb2dsZS5tZ4IJZ29v -Z2xlLm1rgglnb29nbGUubWyCCWdvb2dsZS5tboIJZ29vZ2xlLm1zgglnb29nbGUu -bXWCCWdvb2dsZS5tdoIJZ29vZ2xlLm13gglnb29nbGUubmWCDGdvb2dsZS5uZS5q -cIIKZ29vZ2xlLm5ldIIJZ29vZ2xlLm5sgglnb29nbGUubm+CCWdvb2dsZS5ucoIJ -Z29vZ2xlLm51gg1nb29nbGUub2ZmLmFpgglnb29nbGUucGuCCWdvb2dsZS5wbIIJ -Z29vZ2xlLnBugglnb29nbGUucHOCCWdvb2dsZS5wdIIJZ29vZ2xlLnJvgglnb29n -bGUucnOCCWdvb2dsZS5ydYIJZ29vZ2xlLnJ3gglnb29nbGUuc2OCCWdvb2dsZS5z -ZYIJZ29vZ2xlLnNogglnb29nbGUuc2mCCWdvb2dsZS5za4IJZ29vZ2xlLnNtggln -b29nbGUuc26CCWdvb2dsZS5zb4IJZ29vZ2xlLnN0gglnb29nbGUudGSCCWdvb2ds -ZS50Z4IJZ29vZ2xlLnRrgglnb29nbGUudGyCCWdvb2dsZS50bYIJZ29vZ2xlLnRu -gglnb29nbGUudG+CCWdvb2dsZS50cIIJZ29vZ2xlLnR0gglnb29nbGUudXOCCWdv -b2dsZS51eoIJZ29vZ2xlLnZngglnb29nbGUudnWCCWdvb2dsZS53czANBgkqhkiG -9w0BAQUFAAOBgQCROJdKT00d96BpNG4j3Xf5Kz7kJENMTYtgsGQW5E6y2yjRaguD -LPO+y4IH9KiVXD+qO8koye9yOMNawN9r/DFQd+t2nDmvlpcwJBNguiuqxl+rJaU8 -KKgswikGaaM4z+i4vHuXcCKZtM/ELAaJlSaBPip4GBAkgv7D9hwh+sWvYA== +MIIC4DCCAcigAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290 +IENBMCAXDTI2MDkwODExNTU1M1oYDzIxMjYwOTA5MTE1NTUzWjASMRAwDgYDVQQD +DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv3vCufPG +QbBiyfjMIqahkuqnpx3Z5xjHJZ5UFn6IttloxK6bKTI4LRcRoQhNxHKlSnMDx01X +e/G7OBC/FOKUY/2sfPm2D5sE2J23XFaM43PtA5IMIzGdEWHCKLAlB53IMHNAIl2x +26AQjfL3XTme4/5zCpZxJB2hxixV0pxLe/acDiQw+ScWARmmzouslh0NxSEkvA0e +ItK1KedIRgzeIcPbRCjf3UpqTq9TkWBdLcOPdXIEqORt1hv6Hv6yXOnBoooGGKTN +2erKxDjwTucdDckszq6FVqVFtoEZkgLjknkyTrZFl5nhSUU6rMRcUrhRiaPseGoY +w/r1z1YqMg7sBwIDAQABoz8wPTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB +BjAdBgNVHQ4EFgQUhVbCRtkiBKZPPyLPY9Vb2OPbEEgwDQYJKoZIhvcNAQELBQAD +ggEBACda3WuIy+UfXqLxeKYNDyrGlxEIPmSGFqKqzJzXiq2B5lCfWtdKzcbgOREc +TvtNhM03bNqppymdEpHAkZVwmgaSA9+e7yvgAHhpd9Y8GZwY/J1FjM4B8WOV4FyM +9bzq5PbiBvlO149GmL+DXp4ZrOkkUyRDo2CkWB6Zh7Nr20oeWPC9IlmWfnpdOrhj +pbihSvgVHB1ejCAhgRtVgTifMNrylZyePvuE97l0tLEbuu6Ad2ygNsNUZhJopolL +lCwDhnGUaeVhKd3dqE5eAGQHrlisgL/M2Pg3zoSisu9mXzVtnSsrkgecDbHjiqMX +aLqx8WYUZB+lHp9nJcX5RiA/hZI= -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/csr.pem b/test/recipes/80-test_cmp_http_data/Mock/csr.pem index f8591522b0f5e..b499b11666f7a 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/csr.pem +++ b/test/recipes/80-test_cmp_http_data/Mock/csr.pem @@ -1,17 +1,15 @@ -----BEGIN CERTIFICATE REQUEST----- -MIICszCCAZ0CAQAwVDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUx -ITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDENMAsGA1UEAxMEbGVh -ZjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9EKPVgvwSgO9C7UCXc -FRkl6q/Xbrd3EJohc02/0mlpXYzk9bETQxcUs3UyY1P/HCAxGb2kyMEcT/3bVUC4 -3PuI861MM/dzbmWJbBFlBFIOC6537NDc+dMh5OKyYVcVo2/CIv8EQVYlhxRMT+ws -E5F4k3JQtWwqk7lpI8Rd7YU307LbUcmO6jZM9iaTcdILg/L+KLUKGIwOQBGbyuCF -y8DsMaJecQUzLyK77339pJIfnOzgtkFW1E6MP6KaY6iCgsdpmjRwrSxUyRC3938L -USSybMuHyhj9P+pKWXPEqfPFiuAeBWrhfSFdQpqACVAtbycYWoByCn1bRY1FrPBj -6G0CAwEAAaAcMBoGCSqGSIb3DQEJDjENMAswCQYDVR0TBAIwADALBgkqhkiG9w0B -AQsDggEBAK7GB08OLpPGY2QWJ++vZhqbFZAO4Y3/PsfnzKjM7OFyA6lJafqGXjmO -U+R63oHAJYhThKrpo4X91YTUgL8HI8eicM+vn3HQDRw2DKgoQcpTk9y3Hqj4YEhA -gRLzvd4Pe7kowVtNKzqjQA2WcerZC+5XEYd88JisB1Vxijm7KmYsmili3MbR3row -idelrt6UfyH23ytfurZvOOvawpm3Z8bilh6SY1WNSlRKwSntY9DOw8izTiimGlru -A+TwtQ5zObWfxB5oLQib13ttCh+0rZ7zAy35txFkiOAmUUYIyng6A8zsE4RO2RCa -BYjeQvaCjBl0fn24JCWKxuT7xtkCzXc= +MIICXzCCAUcCAQAwGjEYMBYGA1UEAwwPc2lnbmVyLWxlYWYtY3NyMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArQXEaGT43i/1H4P1k2qi6fCQLXOXf/lR +3qUzzFrogUTx351XLhSMPM14OVTBoGEKxjkX8xhKmFBYnyYD9QhQO0EG3cfq2DMH +i4/B/zNvPN/LTNp4d0ksSdvEhHDdIR6gQ+QLG9I6oZSrw6ESwNFpYfgLkk8vakoB +mQwqQjoRB0zO/05YH6NZaWp/tiPx7Kb5Z30j8DrVS0yNBU5lXqk0mi4xLmxYSVx2 +3Hws1OFKOvTeazZ1hzZ/gag9MUEk2TDOroozdJu+WecfvuOlfXjxU6ipwKWW/qgx +NO/8sJwvskNHSHJlJ1pyhP6gf0xHvNKzm3MZMMjC9AIsRAs28YNjGwIDAQABoAAw +DQYJKoZIhvcNAQELBQADggEBAERbgLZPsH3EMYrL2hbYTgeZS/d8Ah8x42Khn3ew +TSBz2nT6Esi7juQOUu4UhXOzkgS42GeEauSWxIPM/+Tbc0xEuu9+Hode2jYPw2/u +EbVh0uP6zjHw5Tr6fN/f0IxAz6yyj28+r+ZBeWoDEUJGrMLj5LrBptB8QGqHJIaY +Q1PgjZkILpR+vSZbzUrx/sAfPOawMcJrQnn66SJ8+SOi7Sl4uq1FKcAkcSHDubIK +Ho4yYosEu4EyLM/DA8GhfSzSA7ttkYZXoVzFim8VCcvyNC9jd3PLh2Yl3MxPC5Ee +7cBQcqeRA+U35WmR+pV2LTYiyhntNrT+VETdkaFL5p2qW5A= -----END CERTIFICATE REQUEST----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/issuing.crt b/test/recipes/80-test_cmp_http_data/Mock/issuing.crt index 7329f852bc83b..3bbbcd5e180a4 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/issuing.crt +++ b/test/recipes/80-test_cmp_http_data/Mock/issuing.crt @@ -1,44 +1,19 @@ -Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = interCA -----BEGIN CERTIFICATE----- -MIIDgDCCAmigAwIBAgIJANnoWlLlEsTgMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnJvb3RDQTAeFw0xNTA3MDIxMzE3MDVa -Fw0zNTA3MDIxMzE3MDVaMFcxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 -YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMT -B2ludGVyQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7s0ejvpQO -nvfwD+e4R+9WQovtrsqOTw8khiREqi5JlmAFbpDEFam18npRkt6gOcGMnjuFzuz6 -iEuQmeeyh0BqWAwpMgWMMteEzLOAaqkEl//J2+WgRbA/8pmwHfbPW/d+f3bp64Fo -D1hQAenBzXmLxVohEQ9BA+xEDRkL/cA3Y+k/O1C9ORhSQrJNsB9aE3zKbFHd9mOm -H4aNSsF8On3SqlRVOCQine5c6ACSd0HUEjYy9aObqY47ySNULbzVq5y6VOjMs0W+ -2G/XqrcVkxzf9bVqyVBrrAJrnb35/y/iK0zWgJBP+HXhwr5mMTvNuEirBeVYuz+6 -hUerUbuJhr0FAgMBAAGjUDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFBj61iO5 -j11dE30+j6iRx9lhwBcuMB8GA1UdIwQYMBaAFIVWiTXinwAa4YYDC0uvdhJrM239 -MA0GCSqGSIb3DQEBCwUAA4IBAQDAU0MvL/yZpmibhxUsoSsa97UJbejn5IbxpPzZ -4WHw8lsoUGs12ZHzQJ9LxkZVeuccFXy9yFEHW56GTlkBmD2qrddlmQCfQ3m8jtZ9 -Hh5feKAyrqfmfsWF5QPjAmdj/MFdq+yMJVosDftkmUmaBHjzbvbcq1sWh/6drH8U -7pdYRpfeEY8dHSU6FHwVN/H8VaBB7vYYc2wXwtk8On7z2ocIVHn9RPkcLwmwJjb/ -e4jmcYiyZev22KXQudeHc4w6crWiEFkVspomn5PqDmza3rkdB3baXFVZ6sd23ufU -wjkiKKtwRBwU+5tCCagQZoeQ5dZXQThkiH2XEIOCOLxyD/tb ------END CERTIFICATE----- -Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = subinterCA ------BEGIN CERTIFICATE----- -MIIDhDCCAmygAwIBAgIJAJkv2OGshkmUMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMTB2ludGVyQ0EwHhcNMTUwNzAyMTMxODIz -WhcNMzUwNzAyMTMxODIzWjBaMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1T -dGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRMwEQYDVQQD -EwpzdWJpbnRlckNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/zQj -vhbU7RWDsRaEkVUBZWR/PqZ49GoE9p3OyRN4pkt1c1yb2ARVkYZP5e9gHb04wPVz -2+FYy+2mNkl+uAZbcK5w5fWO3WJIEn57he4MkWu3ew1nJeSv3na8gyOoCheG64kW -VbA2YL92mR7QoSCo4SP7RmykLrwj6TlDxqgH6DxKSD/CpdCHE3DKAzAiri3GVc90 -OJAszYHlje4/maVIOayGROVET3xa5cbtRJl8IBgmqhMywtz4hhY/XZTvdEn290aL -857Hk7JjogA7mLKi07yKzknMxHV+k6JX7xJEttkcNQRFHONWZG1T4mRY1Drh6VbJ -Gb+0GNIldNLQqigkfwIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBTp -Z30QdMGarrhMPwk+HHAV3R8aTzAfBgNVHSMEGDAWgBQY+tYjuY9dXRN9Po+okcfZ -YcAXLjANBgkqhkiG9w0BAQsFAAOCAQEAgVUsOf9rdHlQDw4clP8GMY7QahfXbvd8 -8o++P18KeInQXH6+sCg0axZXzhOmKwn+Ina3EsOP7xk4aKIYwJ4A1xBuT7fKxquQ -pbJyjkEBsNRVLC9t4gOA0FC791v5bOCZjyff5uN+hy8r0828nVxha6CKLqwrPd+E -mC7DtilSZIgO2vwbTBL6ifmw9n1dd/Bl8Wdjnl7YJqTIf0Ozc2SZSMRUq9ryn4Wq -YrjRl8NwioGb1LfjEJ0wJi2ngL3IgaN94qmDn10OJs8hlsufwP1n+Bca3fsl0m5U -gUMG+CXxbF0kdCKZ9kQb1MJE4vOk6zfyBGQndmQnxHjt5botI/xpXg== +MIIDEjCCAfqgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDDA5zaWdu +ZXItaW50ZXJDQTAgFw0yNjA4MjcxMzAyMThaGA8yMTI2MDgyODEzMDIxOFowHDEa +MBgGA1UEAwwRc2lnbmVyLXN1YmludGVyQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDVtUxlSXhn0YEKL1kcHdGWxhZfrFfKc9/bc/h+gX9DLjUviYgy +WfKPVPMDwek9FyaPhwuevDHnbhJ998PZwPhZGUVooE7E/0Ws9gdrkwiCekYDwrkV ++FcF7Z8y42kem4epConTKez9zsK9kks1gO/c0UYG8p4IW4IP0dCPG+hWx5TdxAOC +gBUEft9DY93Hw5sZCzkNHBgdCg9CtDfxKhlSmsomZUj0WRVnMlz7KxnOmcnOLYex +OaWQbaxGVPj88jnFCprDwcl41wod/FCQ2FBi5EgU6i+OS+kXua3Yf0BqzBa6Bt39 +T6n+SoJSKxj4MJtanXcZ42VnztFuvc9zbRs7AgMBAAGjYDBeMA8GA1UdEwEB/wQF +MAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTBLcMazlMMaD5Qi0604+IDUwOc +dTAfBgNVHSMEGDAWgBTsiAttQK5AyZloxjLpJLX3YYxcDDANBgkqhkiG9w0BAQsF +AAOCAQEASRQKe65V4miLNvyU0jK2UoHCoguA3faWKEyQfnD61nEQ6f5/w35c5AVP +nVZRgk+ADt0bRCpQpstAw8fl1IMGgjrtMReHr70ToLtKEpRbwBgNPa9fDCl27zG7 +pfAY+RTcZMp2eJDfOY0VAKAP4kO/of6Mg18hClJ6JONTyGNP5M7hHlKbwJDhVEUI ++T7C7QzlvS0WdiI/aaSm5hrTpz7W7gRhU/PNIssxj++72eNlyLxMSLLSXLbi2SnL +v9gb7traRUMXuI/qCWkFxMP6xm3kMg+++hqlWpqtrSK+4jbwbvnlSO75KYgxR8Qm +B8/0Fc0HcrlPxqKcz7XOHfNtbAWOcg== -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/new.key b/test/recipes/80-test_cmp_http_data/Mock/new.key index a1b1721245b7f..9af28408fe0ee 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/new.key +++ b/test/recipes/80-test_cmp_http_data/Mock/new.key @@ -1,27 +1,28 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAv0Qo9WC/BKA70LtQJdwVGSXqr9dut3cQmiFzTb/SaWldjOT1 -sRNDFxSzdTJjU/8cIDEZvaTIwRxP/dtVQLjc+4jzrUwz93NuZYlsEWUEUg4Lrnfs -0Nz50yHk4rJhVxWjb8Ii/wRBViWHFExP7CwTkXiTclC1bCqTuWkjxF3thTfTsttR -yY7qNkz2JpNx0guD8v4otQoYjA5AEZvK4IXLwOwxol5xBTMvIrvvff2kkh+c7OC2 -QVbUTow/oppjqIKCx2maNHCtLFTJELf3fwtRJLJsy4fKGP0/6kpZc8Sp88WK4B4F -auF9IV1CmoAJUC1vJxhagHIKfVtFjUWs8GPobQIDAQABAoIBAB1fCiskQDElqgnT -uesWcOb7u55lJstlrVb97Ab0fgtR8tvADTq0Colw1F4a7sXnVxpab+l/dJSzFFWX -aPAXc1ftH/5sxU4qm7lb8Qx6xr8TCRgxslwgkvypJ8zoN6p32DFBTr56mM3x1Vx4 -m41Y92hPa9USL8n8f9LpImT1R5Q9ShI/RUCowPyzhC6OGkFSBJu72nyA3WK0znXn -q5TNsTRdJLOug7eoJJvhOPfy3neNQV0f2jQ+2wDKCYvn6i4j9FSLgYC/vorqofEd -vFBHxl374117F6DXdBChyD4CD5vsplB0zcExRUCT5+iBqf5uc8CbLHeyNk6vSaf5 -BljHWsECgYEA93QnlKsVycgCQqHt2q8EIZ5p7ksGYRVfBEzgetsNdpxvSwrLyLQE -L5AKG3upndOofCeJnLuQF1j954FjCs5Y+8Sy2H1D1EPrHSBp4ig2F5aOxT3vYROd -v+/mF4ZUzlIlv3jNDz5IoLaxm9vhXTtLLUtQyTueGDmqwlht0Kr3/gcCgYEAxd86 -Q23jT4DmJqUl+g0lWdc2dgej0jwFfJ2BEw/Q55vHjqj96oAX5QQZFOUhZU8Otd/D -lLzlsFn0pOaSW/RB4l5Kv8ab+ZpxfAV6Gq47nlfzmEGGx4wcoL0xkHufiXg0sqaG -UtEMSKFhxPQZhWojUimK/+YIF69molxA6G9miOsCgYEA8mICSytxwh55qE74rtXz -1AJZfKJcc0f9tDahQ3XBsEb29Kh0h/lciEIsxFLTB9dFF6easb0/HL98pQElxHXu -z14SWOAKSqbka7lOPcppgZ1l52oNSiduw4z28mAQPbBVbUGkiqPVfCa3vhUYoLvt -nUZCsXoGF3CVBJydpGFzXI0CgYEAtt3Jg72PoM8YZEimI0R462F4xHXlEYtE6tjJ -C+vG/fU65P4Kw+ijrJQv9d6YEX+RscXdg51bjLJl5OvuAStopCLOZBPR3Ei+bobF -RNkW4gyYZHLSc6JqZqbSopuNYkeENEKvyuPFvW3f5FxPJbxkbi9UdZCKlBEXAh/O -IMGregcCgYBC8bS7zk6KNDy8q2uC/m/g6LRMxpb8G4jsrcLoyuJs3zDckBjQuLJQ -IOMXcQBWN1h+DKekF2ecr3fJAJyEv4pU4Ct2r/ZTYFMdJTyAbjw0mqOjUR4nsdOh -t/vCbt0QW3HXYTcVdCnFqBtelKnI12KoC0jAO9EAJGZ6kE/NwG6dQg== ------END RSA PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtBcRoZPjeL/Uf +g/WTaqLp8JAtc5d/+VHepTPMWuiBRPHfnVcuFIw8zXg5VMGgYQrGORfzGEqYUFif +JgP1CFA7QQbdx+rYMweLj8H/M28838tM2nh3SSxJ28SEcN0hHqBD5Asb0jqhlKvD +oRLA0Wlh+AuSTy9qSgGZDCpCOhEHTM7/Tlgfo1lpan+2I/HspvlnfSPwOtVLTI0F +TmVeqTSaLjEubFhJXHbcfCzU4Uo69N5rNnWHNn+BqD0xQSTZMM6uijN0m75Z5x++ +46V9ePFTqKnApZb+qDE07/ywnC+yQ0dIcmUnWnKE/qB/TEe80rObcxkwyML0AixE +Czbxg2MbAgMBAAECggEAAzGtOlzMJ/82+rcgaZwZLXwROqLneTzR2+wtJHN0ga0T +UVShvzTbkTnHzjh4Kezwr8/DrJYBC9vGhGBFcsNjBnJWXUdrWJoPOcPUdHtvbRkX +3dorSXnH1Vs3FFd9tYv6WxZ9dVeFrpBEis7RPk7/WjLOiou8rS0i52o36NNn7Lxg +o0znk04af13Hn3Yu83lIi8CLLEe92xmWzrJKMNpWCQTPA02IeemrkYOFJ/TJ6Y2b +oh+X2XIk0bg/4dxM4w1FMq977OrYLBDnpDfJG9d0WPtMh/Q0UGAjuzCFnhuLHmm7 +VZPTU89MV9FS5emzdldqnmH6RCLg+EazrvQWMZiq5QKBgQDfARre0J8A3HkwxHCK +HQ+PQEvAlUneg/bL8CygT9M0eeZUVO+gtkAPP8Anr56venzVslf1ae4m0tvfd1wz +c57cs4Y58DquBAaN7VWPIOIKoJ9UMwAHssVYitW78KN7HG/AlqSPRKJz4jNG9lip +6pUDmL3bjtdsZQ3PTGWouc8UZwKBgQDGn3dRV7ChK7l70pn2JhYEeNnxYC3FHyAH +D8A2BZck1YNr1PacHQrzpvFpuxWPyDkmTA8jiAkyzNSz5POPvVm/fPg1GmqjK0tQ +F0re5U33E5m/gtcxk4W4U28uLBmYstjVl0j4oTzGtsFS2tHSgCF7k5AJzUo5Aewn +k4DG0SSrLQKBgQC4M/t0DTMpzPO2Gq0zCGov09Y+z5Hi4XJcZpkWGpnFAOQGyNnf +EGu9rNUWcvRK0oyHH/eT2dpD62x/G+LnBRw2BXxcI1j1IJIhbed8gJb2XFL/g9kE +guCMELIXud/v8z9D/6sSRIlD25ariRUX1ZMdE2/QCh9bg+VyVBKs2j55BQKBgQCK +24c2FeEE/CWDXFuIi13PKJHtPrkg2z6v0SImYkglVyO2qj7yKxex+V9C9KkBSRAz +Ju9afss3eZ2mWoSwU8c/qOV5cotkoWrYhkAwjgywlEJjcdxx61mL4MCUff4zE62l +vUsljsuHfNKw0wvnZu6Bj0senyeprR9lF6jq1eIVzQKBgENiD4HzP9nvMmtWM4x1 +dKVfSzmwuJaqPmThQJN4qeme007VpYtdEuFRvYdwMVQUlmWd69xyiTtBTIAHWqU5 +76i9P62RJBWTziTUSBsD+fyMQYqldnlufyPFQVqSsG2/XfBhHMlHSftqKMHQHgZY +ZFbspUmdTyd9URkmOEJLiUwU +-----END PRIVATE KEY----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/newWithNew.pem b/test/recipes/80-test_cmp_http_data/Mock/newWithNew.pem index 1a02d1997f3c8..ce6c5674b3ee6 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/newWithNew.pem +++ b/test/recipes/80-test_cmp_http_data/Mock/newWithNew.pem @@ -1,11 +1,18 @@ ------BEGIN PRIVATE KEY----- -MC4CAQAwBQYDK2VwBCIEINTuctv5E1hK1bbY8fdp+K06/nwoy/HU++CXqI9EdVhC ------END PRIVATE KEY----- -----BEGIN CERTIFICATE----- -MIIBAzCBtqADAgECAgH+MAUGAytlcDASMRAwDgYDVQQDDAdSb290IENBMCAXDTIz -MDYwNTIwMjMwMFoYDzIxMjMwNjA1MjAyMzAwWjASMRAwDgYDVQQDDAdSb290IENB -MCowBQYDK2VwAyEAGb9ECWmEzf6FQbrBZ9w7lshQhqowtrbLDFw4rXAxZuGjLzAt -MAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFKKMwfhuWWDT4DrnXJYsl6jUSCk8MAUG -AytlcANBAEG62N+3Go9h1ekWyQMf1hYFQMPQF/XVP2EH1euP7mVxJt0mquGpVsm+ -qLt/W4xBKiu08Jfcv4Gxi6CjgOekGww= +MIIC4DCCAcigAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290 +IENBMCAXDTI2MDgyNzEzMDIxMloYDzIxMjYwODI4MTMwMjEyWjASMRAwDgYDVQQD +DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5w9TxEfD +dVnSll5Dv1lcgAmsxVXUHMYTnExTA6UkbmjJkhXxWldeYidWvXtl5BB1L6DXuyx4 +Zh14WfbiE0qYBG5UCN25B+oVgKbbFhZr0vSKJ4+wIl1XiFMpS9vTogZRSIccIQ9K +wgKz/L9xoS9Vd5FOKnXydRILTAEwZ95ZT2A8Io0TTQclWvaq9cE7miUmty3bQ6Ob +Fe7/+DfebSULecHip1+Zw2u9Vv5iAIGOdfStbYRRrrKSzkwLiaki9ZYTkMFIV9r+ +druBQ1UdM4rdu9MqFKpokrIenrbWnGRdklNrcNOldX923ZdR+HW+5MmjylTzEL2G +1EKUflcoUmT8EQIDAQABoz8wPTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB +BjAdBgNVHQ4EFgQUMQKXiGGCOFK2HECOu1/TJeoe9lcwDQYJKoZIhvcNAQELBQAD +ggEBAMUFrSAb6ZXQbQ3pWTNn2P28iHgqh3kZsQd9SbjFTOaeTabl7rRDMpkxSra2 +WRgzLwJvPn/YxQCtPUSVpiNmc5bClTc+NxkeA7+EgdR/9reUET0H7y8LuUNdcBuV +epwNhmue9iQnB4Gc60wzjQYJ5gjcyKCGXNKkQJaCIPk+cDmp/oAPc63Kt6NsVxW/ +50Texql7bV/h35HVm17m8YZDl+or9GLf18fzpxErDry2cfyaTQVrUzHMwor5sJw+ +VZEXKYccgg33TpUac/qCt4w7e7tJjdtEVpKpYSuT937m4+dZEmwtshjjw0yXamXY +McsqsweWQbtx8C7I27Lb35S1ChI= -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/newWithOld.pem b/test/recipes/80-test_cmp_http_data/Mock/newWithOld.pem index 988496cd35081..342a7e2e91281 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/newWithOld.pem +++ b/test/recipes/80-test_cmp_http_data/Mock/newWithOld.pem @@ -1,13 +1,19 @@ -----BEGIN CERTIFICATE----- -MIICCTCB8qADAgECAhR+y2i70DQe9ryvJ8uPJO8qOMfX+zANBgkqhkiG9w0BAQsF -ADASMRAwDgYDVQQDDAdSb290IENBMCAXDTIzMDYwNTIwMjg1N1oYDzIxMjMwNjA1 -MjAyODU3WjASMRAwDgYDVQQDDAdSb290IENBMCowBQYDK2VwAyEAGb9ECWmEzf6F -QbrBZ9w7lshQhqowtrbLDFw4rXAxZuGjUDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0O -BBYEFKKMwfhuWWDT4DrnXJYsl6jUSCk8MB8GA1UdIwQYMBaAFHB/Lq6DaFmYBCMq -zes+F80k3QFJMA0GCSqGSIb3DQEBCwUAA4IBAQB6Eg6lRxiUUXMGO8l7XYJ3d49x -YDqwt+fvaQcnwVN3kJ1GAb/0lcB6k4mt8jHizT2HKw1ZMHK7CGbHYAMKvtxML3px -GXqeEQO2IlWU23kEyPhX/yoOG0cp9QWm4tdTvr3xCr4E4rNZJUNbSqyOCdcAs39H -4dDBHBQrL530/XquKdXmq4fAwyKIGxNW1WTohKq9Yzd3NK+0Ku11Ny86FIzB3iks -a8NdsE88xfBQcQMo9omZZbPQBg7YMId4zRyDFplrLWZjhoNmStmTHTX/nOYUMGm3 -75iikSsNRJl4A/ZvnZrDA2am3ihvMghVIN4IVfXrk5tHiZ/XHZuu3vetK2jp +MIIDBTCCAe2gAwIBAgIUXpL1fyjTebfAPfk+H0txgotBIUUwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHUm9vdCBDQTAeFw0yNjA4MjcxMzAyMTJaFw0yNjA5MjYx +MzAyMTJaMBIxEDAOBgNVBAMMB1Jvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDnD1PER8N1WdKWXkO/WVyACazFVdQcxhOcTFMDpSRuaMmSFfFa +V15iJ1a9e2XkEHUvoNe7LHhmHXhZ9uITSpgEblQI3bkH6hWAptsWFmvS9Ionj7Ai +XVeIUylL29OiBlFIhxwhD0rCArP8v3GhL1V3kU4qdfJ1EgtMATBn3llPYDwijRNN +ByVa9qr1wTuaJSa3LdtDo5sV7v/4N95tJQt5weKnX5nDa71W/mIAgY519K1thFGu +spLOTAuJqSL1lhOQwUhX2v52u4FDVR0zit270yoUqmiSsh6ettacZF2SU2tw06V1 +f3bdl1H4db7kyaPKVPMQvYbUQpR+VyhSZPwRAgMBAAGjUzBRMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFDECl4hhgjhSthxAjrtf0yXqHvZXMB8GA1UdIwQYMBaA +FK6Bq3xWRlpsnsrY0m5hQB7CIMfBMA0GCSqGSIb3DQEBCwUAA4IBAQBHg5CtnsyW +nowtTPaermxY1XzwNmfOVZpItW1Hc5CEGNg2SIJ2syI9g8jvZWOQYKw9XKyaWtey +eLA51mX1lb2/6+rmO+Usg3yghr1zZhJkP57zpnZZ3UGNo+vKdwkhPUKb+880oNRu +2uLj4rFkiaBRfmqgmF8hT6KXApqfTpQtQMVGEfOPMpzAvG0cA9fnZP267tXXqKDs +SimkERvxfV7tT99p9jSfT6ycVK+Ma7IDmWf2saKHhvPuBsyu7LfeaFDGtrE8zTjH +VUkd5rniKKYD3pWuGZyMQr0xXxn7UiJWRZAxZ0SbaKUAdmnIGINrIZWXvObNNcVI +mk0mbHTqgCIz -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/new_pass_12345.key b/test/recipes/80-test_cmp_http_data/Mock/new_pass_12345.key index e1aabfeb79a5f..2d5921ece076f 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/new_pass_12345.key +++ b/test/recipes/80-test_cmp_http_data/Mock/new_pass_12345.key @@ -1,30 +1,30 @@ -----BEGIN ENCRYPTED PRIVATE KEY----- -MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIuH8X1xWl9ygCAggA -MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBCw27UHDuBtxWa928AXEEb1BIIE -0A/aH/nMGoifA4TKpLg1SobskugzWV7+N2qh3j9LZrz6GxB9jR64JBx8+eKBu5lv -VeMp/cIuGZscJ56QFZ01tTEyIiP1eeD68eQol2n7KEwk9DKkR2QbQuLDOaR4voqM -rm02uehLnNPJ7d81CrgfqIRi5OF4cWVV20jN7pQMxn8KqW4OYPdOrV1i6mTnsbNz -M5hL9YMud4wppWwA93MLD4TGvQBQSTvreYtLNy1atq1uK4k2KZh2tw/CTNiCo47R -N6Ft+CDJblikodpj/a6ZPJ84qBMonTbc7IMvkeWP0mnzA25ohOW7RfhgWzz/mfx3 -/ypX8xqLd8JzmdRFOcc5MFdVcYPmgFzFVtEJ0bBZx6WCW+6OszLkt/7p7raRKirA -/zJJSBmEvQKvwtZ6I/rG6SqMFiTseRuWq0sXa1NX2zlH9y+g68K+7Bt5816l93WD -p0GQgWxXV2J+QJ3fGvxMdQG7qmGWx6dc6yZkFw9e94sTHH74fShTv53OekCgWg2B -58pFBTK9NGtiG5LawtDKMqlYcSKvfqjvKwDokQS104DwM+om0QBLTH+RRxh05jYv -2hx1uwSXoo8oO+AYaYsEQE8z7mYxQr5Ea1gKbtyYPE0Eo5rrH9fYzXN8A1LH7wbL -ywQIZq/lthuJGarTPCFjoHrPW9O+FiQBLsn5Ej2VVm2MQpS3v6m7SnHTWBaPZvkq -GEGw/MZiwkzyULsg7zRKfnNhYBfxdg+gmwIR6x1e4vT6hAFjZbvn1eOlFTLqIBpE -XQCqxaITtW6bCEhvl/c0AKkAWM39XEs/ff1giYza+6SLgLQObHApp+Q/Hk3PaUDq -Wnm/5w8IyQcGDAik0f6JqbQ+licBk5lHlOifO0GFKqePlKLY/Mvx9al2UflzOydG -u9BpXx8sLooLuyycXFhgpZZLp19+79KgPm+ZrXKlKKwTDQwuB+eGxr2wKWCbJb2y -gmnBCtml5apTQx+l630GldMjkhwxOSZJoXy6XKQew85L/J9Jknta3bjGbyL2lEeW -/gfT+L6WrmG3Hf4xGhpkkx6UITzujJbE2/YyxJ+sXlRuYd4ld0Hfn6Ihsajknj8G -jvLb77FvgNndf5SXlqU3sMGcOPizQkMr/AmtHPzBLT8O6OxpeAOWzG3jOvznRsmZ -27nmW4cM/6t/86PvnAssPETFcrC3GqFYWnzdVaWunCz5zn4xIot3633VGR1lbxX4 -kTQLBzgBjKuajgVim5Q4obfaqnJEvHkbJaAFJg0y6uId2RIzYo5/onHrVOQR5ulB -qyR8YJjWu3pyq8t5q9Iw3L+pWDOh4AH7/ay0IBu/qxapvybqEXyol3kAJIsY0AKZ -Y5dPA4duWjW0MHNDgliAssKr2t3CTALU9nrBVX1fEPR4Y05JZ9f4OIueu/IGdDIE -snLdqtkY0sOTma9FhKDv1RwsumT/UfOqUJ3ZSJCaKgE/RnzS3YN+j5BYv788micZ -S9nl5KX+q/VSVXxial0nxkGiqs73mASF5JP4iarRihSntGMvn4PPB7Oid5SVLrqk -JFFy7pjL8xuERx0hlShUl2q8/C3DSi0u+QkIhNrUBKZRADzNDkJcfWmKwbhq7HPp -ghzvaDrFtH/4o8t7kd+TVdKjnS0cna43Sj94w3J5/y5Y +MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQILd1EQllper4CAggA +MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBCmeMHbU0YMjWfup6s2MBQ+BIIE +0K5dPet1yKiCh391iLz1QcuaYNuPP1JyGmYRbSl0Fzddr2xWWfp01Jqf3XcCSL0o +koriMva/QR4Vcq4x2EBNmgx0D+VPsYzW07qerfjsOXPTTD4wab63s3a1QtBw1ssu +qAa6tqhzxN8QE7MttT4P+sprkxIL6kQO1pVVP/l/r3ol8J5UXh2FKUMlKjwYtCSL +wpuGt/QTTnT52APVFFQKpVOvBJPlNzXmypT6S3WULyihU3ljaisroJiiJmFwfSqi ++HcKDG0BYsnLyWE3y2jsa1cvxE7jWE2sUydcp80Zt1ElSomP2UAV5MDbOqi2OUlp +wUNCcUdnDHLQTdou4NeJ7x0TyXMzUPXKVUPYthW203cYKgSYE5RBHOfvLyGo0kcy +UjHlGmbXUaK3pX/G/iXArIAPT1HL9DBuFt+fYZQ5DoD9Rd7//4bL26Poo0PgNU+r +VoyE46Ox4sogXN6rx731KFdh3Ud2C0vhlgwKo5qvbeIRjW4rs/tdFguhAthaaEIY +CUDymdRKHGsJ1vBaJqAu2t2kOzUhYfrAAgZD0boiPRzQKa6veT25Dy5HdZukO1Of +6d5/5+dXam+Z0WPou/bNswQRO2stgFmvyTszLaCofQQdP16XR6AdxYsNbcVQy/Up +YozOdYxXuk6cjRRFaA2QFJC61u3et6qqZoxl6nAXJsblUqV1q84PcCThuISu4d99 +qKYBhxbuE+MTVwrvEuTiFPgH4kXWMdizNb/LgbbZLyl16QT+W2Fv4Ghl3oehGR5z +MdcE5YspfOeFghl8wL63B5VyYd8o3mZzJY7gHoBj/iCb9+VtKi8+bXexmkELbXVi +poAmQLmAw1lwQFIoAcZSgSmKBQRaoUuzGoE5VpficN4cAElsVk8q54jjOzTsFih3 +REeAL49YQEvW1fLPyVeQGWa82w8NTtnAjPKsN1XqHQcmnXF4uBbTBDxt1yPRFoYG +jd8NxubXz0PaKHl3v2FMKKZf+FVXb2SjYCgN6a3PlSyr9N7+wNg0Ky+wWAIJIQZ3 +Pk11rWUlabXhvokXpj813GVUDhwU7V+u9XbQSg8IrPwvuM2/8ee3St5Apbnpfs/O +nsucuDPE7qLRX1JQde0OctCgvsJkWpP96IvbDzQq6qDFh+xYON98hyZAMLanfGIo +61Inmjji3QsvwWLjKqsdJWqRD4AGDCs0pvkTolIcizFz9isynjMdUfbvtYuxXutu +emQvmQuCNmHYgT9vZkc2R1uT7CjRRN2Be5DNwoy4DtuwzcMyEISqNxw58+wu4glP +EOubdk4kLP5jkrdred9nzb6VAOvhbTPsLROjEraKgpBdi4dK927yuVwe5IPgi874 +sHs1iGwruB48ByGj+eSO3wiwXvQUKvWxthKcZHA0/szBqZzuruapg4sOmicFsqbM +KU43tmiovXIgyXtuzCHZ0amJ6Bc+ggsgiKrjwDnLJajAZKubWdsoHxLFyeywOypW +aAZVzN+zNeNZPGSksqKaRccMiMnHSCCJSSHpqnB0SDs+SWn5LnIUYPy2H2qbWFuk +wVcqKYxnBtHava/DT7AzfgUB7TRIKY9J5sePjZpe19xWqi0juTl3sPgJ0EwHNszj +wP5CdLVPLlJgNvmbM06KEBvMC1K1l/mr7VaYT55ms9Zj -----END ENCRYPTED PRIVATE KEY----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/newcrl.pem b/test/recipes/80-test_cmp_http_data/Mock/newcrl.pem index 101d7cd67c518..431a6e819640d 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/newcrl.pem +++ b/test/recipes/80-test_cmp_http_data/Mock/newcrl.pem @@ -1,12 +1,10 @@ -----BEGIN X509 CRL----- -MIIBtDCBnQIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJBVTETMBEGA1UE -CBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRk -MRMwEQYDVQQDEwpzdWJpbnRlckNBFw0yNDAyMjMxNTQ3NTFaFw0zNzA5MTIxNTQ3 -NTFaoA8wDTALBgNVHRQEBAICEAcwDQYJKoZIhvcNAQELBQADggEBAFyUvxWlxjLA -DjTq/N26EXH6GZxmDyr5tjPk1KQBRY/jPNWvxloXFIH7PAtzInJmEoF2PCDw290Z -BRuftPaxVW1tcHAsZzL5QFSGa2wWSLGCHpZCg9twcLQbGrOq7+S2M2ZjOVxSMN1u -ok/QLhuqniPieOUetzafqUNknYJahILnomLhPoQBzko9EdtBJkygOGdj/3T07iLy -hicW0QlBA5B9oCIUmknnx4kCh6VlsSq9FJTs2HXZhJHF0VVFbAlbjHMFkwjTh31r -Bc8u1D35T0kqwbTbVmtPghdpW2uJ+9LsWXdrlTGGlRJXA+3d13hKlFMFcQEavf4h -wVlABZ6eEPo= +MIIBdzBhAgEBMA0GCSqGSIb3DQEBCwUAMBwxGjAYBgNVBAMMEXNpZ25lci1zdWJp +bnRlckNBFw0yNjA4MjcxMzAyMjRaGA8yMTI2MDgyNzEzMDIyNFqgDzANMAsGA1Ud +FAQEAgIQCDANBgkqhkiG9w0BAQsFAAOCAQEAbCFkWsDbA+CtlUADSqxQzyNQW3VF +EoASiRd6da3L99LVwUjBZ4U1GwlDCCjT8xPpZwX3qrcYwU2gWenx1jqj4IB9kSd5 +3tcC/GKkWGLqYeuXDmr0wfSEDS/BwRfl66+64MKsp0yT3asbJ1seuTwymr/9EPuX +qUiJcoytkW0B6wTxPVptjp9rqfNtixdUdvFpDqUUcXtquGWEImVxRpW+GtQow4KU +ZDSM1Xxp2vKwaVqONdf8pgutvvTE1joDJVRilnBxbeIvrlFmD/lIStePI/oUaLlZ +DXf33SPEtqnbkED6z5oYxtHPbEUunMhsvBMH80mR9kmKs3rlJVTW+9VTCA== -----END X509 CRL----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/oldWithNew.pem b/test/recipes/80-test_cmp_http_data/Mock/oldWithNew.pem index 8fa15f8999826..7d4ef32501333 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/oldWithNew.pem +++ b/test/recipes/80-test_cmp_http_data/Mock/oldWithNew.pem @@ -1,14 +1,19 @@ -----BEGIN CERTIFICATE----- -MIICMjCCAeSgAwIBAgIUcaAacl/D9rcbM5ytumMvdL3J+HIwBQYDK2VwMBIxEDAO -BgNVBAMMB1Jvb3QgQ0EwIBcNMjMwNjA1MjAyOTI0WhgPMjEyMzA2MDUyMDI5MjRa -MBIxEDAOBgNVBAMMB1Jvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQC/mhXWzc26ztIg2Duia7kDG54SAr3uaHk9TeGBmmWJIVoRKYvaosZ4/rT2 -hez/rxcNdVbi61QsI6MuHSen7lfLeLcZENeAFnvZAN7bdaqpCqpoGVBVWbVbEb5q -ZG1kkRZ1IiyIUG2T7x0ESUeHZZAOEM5aocYdBqtCAk/EYH3sxGExKVtPArVPkoBY -6WqLmYlbkvq82tDtOtr9hx4fvR9TR8lg5eEHEz3Y3APVttV30Y9gVKqt2tWPX1u+ -jrdezFl257HlAetGRapPnDmaAAdoSAKpatL/rir1NH1QTCsHySJlmDeT3+Kb7MHA -RQtNm7SvygwSSmNtOVcua3wQwGrHAgMBAAGjUDBOMAwGA1UdEwQFMAMBAf8wHQYD -VR0OBBYEFHB/Lq6DaFmYBCMqzes+F80k3QFJMB8GA1UdIwQYMBaAFKKMwfhuWWDT -4DrnXJYsl6jUSCk8MAUGAytlcANBAHFKIp57/EisMF84ZvOFzxnS2o8/qKsRrrh5 -w1nBOmOvavZxbtFyO9batLEWikNV0LDFIHw9g3uYmgB1VUzhcw4= +MIIDBTCCAe2gAwIBAgIUV8Er52Kc37kB4LMVNXy/vi8A4CUwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHUm9vdCBDQTAeFw0yNjA4MjcxMzAyMTJaFw0yNjA5MjYx +MzAyMTJaMBIxEDAOBgNVBAMMB1Jvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQCuU56h761StwVmWzZ3HyiEAgghB7kUfrzJgiKyLm3O/s2wMlgv +AK7f+vYEuBcqP8T0i+vOr2mtYbAhLUk7gqv89XiVv6P1U5HN3NUw3wXDz+4qYrpG +9CQhAslEi8Le7NORAGcPzd9DxeVxhc5fbCJCP/rN7R4ttO7BZvd2igt3JwAYtaDY +R2ooHXkp+uymuRF+G/EFJcreaQtdcfxYHb25BA+hl4BHIIMkjH0NIrN54e251/Ba +cjikKz0czNXOcRGPh+b3A9eIRH97GAmMSKHs2J/dIlNwhPjzKl/rsPTBqnvPt7JS +ugEHbaXTxt6LMvRe5hMeUwOzrP+2xeqWKrgxAgMBAAGjUzBRMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK6Bq3xWRlpsnsrY0m5hQB7CIMfBMB8GA1UdIwQYMBaA +FDECl4hhgjhSthxAjrtf0yXqHvZXMA0GCSqGSIb3DQEBCwUAA4IBAQDCT80khCV2 ++B1UE8z77MGD7C65aIs/uS2s8oheP8RI4d8dSGYwIt5C+16tJ7EB2fqVDd+McHx6 +xxCSY75/s4b5M0k/IMHMtfRuMAz9Q7VVrz0H/g3XrhKbdcPoahn8OopqRsWYa1YZ +88CZU1imsH/dEurW3B7uzmojcF7t5SyldayU0P43rQxEsiZ4gAoC2kehaqAE9mJw +LIZXm2F9a4YvWu4PTNWUV2OHQHPN291jzAu5O8NdWLoRncdIU+Scvyiyh5FR3PgO +xZW4Zpn2MEocT7oJS49sfPJGgeyKwOo2bXZG1zGDgRSpPaU46unmVklnWIsI3eUQ +t4KFJGwzzFv5 -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/oldWithOld.pem b/test/recipes/80-test_cmp_http_data/Mock/oldWithOld.pem index 7c6db11c445f9..067daf21e8e41 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/oldWithOld.pem +++ b/test/recipes/80-test_cmp_http_data/Mock/oldWithOld.pem @@ -1,46 +1,18 @@ ------BEGIN PRIVATE KEY----- -MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC/mhXWzc26ztIg -2Duia7kDG54SAr3uaHk9TeGBmmWJIVoRKYvaosZ4/rT2hez/rxcNdVbi61QsI6Mu -HSen7lfLeLcZENeAFnvZAN7bdaqpCqpoGVBVWbVbEb5qZG1kkRZ1IiyIUG2T7x0E -SUeHZZAOEM5aocYdBqtCAk/EYH3sxGExKVtPArVPkoBY6WqLmYlbkvq82tDtOtr9 -hx4fvR9TR8lg5eEHEz3Y3APVttV30Y9gVKqt2tWPX1u+jrdezFl257HlAetGRapP -nDmaAAdoSAKpatL/rir1NH1QTCsHySJlmDeT3+Kb7MHARQtNm7SvygwSSmNtOVcu -a3wQwGrHAgMBAAECggEBAL4rWle8JuCuHGNbGz1nO9d41tg7fnYdnZAaN6OiMfr8 -bl+wY84aV3GKJOS2InfYOcIy340UU5QHvxOq/kwwRVV/uAOZ8rqAFmZY9djOnhdv -rZjq3xAHnPgJ0XvZt7XkR2z1AUw+v7Pf1WYGsYcSZ/t99MKB5Je0odA/aRqZRwLy -YflbsnAJtxdJ6fsiVCSJcU76V8sxfiCimw6ppLMEp3zCjveQ5Lv0eVoL2zNYeh+l -GiSwqTqaR+WJekkDiXRd9KYI19drf7OkTII1DtOd6bgvKX3zv2lNiere4J4k7cAP -rW6fBFgtSq2oklTpWUlXRH7XQAgDtDvldXdlKaj96dkCgYEA8KPSu5ywg8pjCofE -nLtJTfVyD2g9tgNLj9dI3kuSniZU51kOtk5rZZwL0S8piGczL908aV9DIWdXWsND -5hlXquKUTSjxPYEzZvaN+tvf9e0AcY/D/UaK0mKPjEbh7vg6pS77aZZz2EL2inOs -dam8famOOC9RUkxH5JWa3UV4UhsCgYEAy9T0wPQctjuvDkZQTqKEKsHrmrgY2PXT -Re8DDGI8hxjYb8l+NoFQ7eiwTHir/DULupxQoBBUQtS+idQzUu02tzLMnGcjHNwh -Tu+vZ4xlVnXxfgIRjDKkfQjiAC5SLzoNO9Jn8g4eS/1mEPXhQ0TXIsFonZDypp/n -RMp21DkvdMUCgYAIMgwjR5rbYjEtUqJnlBlTBmD0FWDEqigQpgxdRcWgjT2nA2l0 -3AbcVwwv+6M2eg1MPASqsgvfP13CQZQ2afaKY10Zo6NTrOrLPupm+MYP4hp5w6Ox -JI3lzGWHKYLYWKvmpEr7tZwMaXtsC7R77WP2A6hMUZA7dU2dg1ra3lrSsQKBgQDA -sPIsUtmtwOBtqzUSEXrGfQqA+larDEGNVDVaiKfVwzwg+aeyWS+rqRS5Rj64L2GG -KW3i020EvN/fplZap9vY9lIN7UZ5avSmDdqRFl1ajiccy1HRarKrbTFRoHibItMN -4YvYfVZQ2h2aHQe2Myb6OULv6e4qbPIRyyDo4aKmTQKBgQCadq2JfICFIP9Q1aQn -93oD7Z4WcYs+KsLYO+/uJxWMrn0/gv90cGrSfstJqDOHnRq4WKUcgK9ErxaE4LkW -sD0mBhRM3SMxnRJZRO+6roRdehtjHkvzKu75KjcsuwefoMs2sFa4CLQ1YU2vO3Tx -dgzpnKS2bH/i5yLwhelRfddZ6Q== ------END PRIVATE KEY----- -----BEGIN CERTIFICATE----- -MIIC8TCCAdmgAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290 -IENBMCAXDTE2MDExNDIyMjkwNVoYDzIxMTYwMTE1MjIyOTA1WjASMRAwDgYDVQQD -DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv5oV1s3N -us7SINg7omu5AxueEgK97mh5PU3hgZpliSFaESmL2qLGeP609oXs/68XDXVW4utU -LCOjLh0np+5Xy3i3GRDXgBZ72QDe23WqqQqqaBlQVVm1WxG+amRtZJEWdSIsiFBt -k+8dBElHh2WQDhDOWqHGHQarQgJPxGB97MRhMSlbTwK1T5KAWOlqi5mJW5L6vNrQ -7Tra/YceH70fU0fJYOXhBxM92NwD1bbVd9GPYFSqrdrVj19bvo63XsxZduex5QHr -RkWqT5w5mgAHaEgCqWrS/64q9TR9UEwrB8kiZZg3k9/im+zBwEULTZu0r8oMEkpj -bTlXLmt8EMBqxwIDAQABo1AwTjAdBgNVHQ4EFgQUcH8uroNoWZgEIyrN6z4XzSTd -AUkwHwYDVR0jBBgwFoAUcH8uroNoWZgEIyrN6z4XzSTdAUkwDAYDVR0TBAUwAwEB -/zANBgkqhkiG9w0BAQsFAAOCAQEAuiLq2lhcOJHrwUP0txbHk2vy6rmGTPxqmcCo -CUQFZ3KrvUQM+rtRqqQ0+LzU4wSTFogBz9KSMfT03gPegY3b/7L2TOaMmUFRzTdd -c9PNT0lP8V3pNQrxp0IjKir791QkGe2Ux45iMKf/SXpeTWASp4zeMiD6/LXFzzaK -BfNS5IrIWRDev41lFasDzudK5/kmVaMvDOFyW51KkKkqb64VS4UA81JIEzClvz+3 -Vp3k1AXup5+XnTvhqu2nRhrLpJR5w8OXQpcn6qjKlVc2BXtb3xwci1/ibHlZy3CZ -n70e2NYihU5yYKccReP+fjLgVFsuhsDs/0hRML1u9bLp9nUbYA== +MIIC4DCCAcigAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290 +IENBMCAXDTI2MDgyNzEzMDIxMloYDzIxMjYwODI4MTMwMjEyWjASMRAwDgYDVQQD +DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArlOeoe+t +UrcFZls2dx8ohAIIIQe5FH68yYIisi5tzv7NsDJYLwCu3/r2BLgXKj/E9Ivrzq9p +rWGwIS1JO4Kr/PV4lb+j9VORzdzVMN8Fw8/uKmK6RvQkIQLJRIvC3uzTkQBnD83f +Q8XlcYXOX2wiQj/6ze0eLbTuwWb3dooLdycAGLWg2EdqKB15KfrsprkRfhvxBSXK +3mkLXXH8WB29uQQPoZeARyCDJIx9DSKzeeHtudfwWnI4pCs9HMzVznERj4fm9wPX +iER/exgJjEih7Nif3SJTcIT48ypf67D0wap7z7eyUroBB22l08beizL0XuYTHlMD +s6z/tsXqliq4MQIDAQABoz8wPTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB +BjAdBgNVHQ4EFgQUroGrfFZGWmyeytjSbmFAHsIgx8EwDQYJKoZIhvcNAQELBQAD +ggEBAEzx/3RhfaGHKZvitVY+gTuRrcIjxp5oyNAXwThSrAf5M/h7C3VN9calDBwf +NBdjruQjf+0UotoAf5vo/xgQO3mI5H4vkb7UlvQ5xVb4KGL4O9xNgZisTv/kgpGv +L09bOQOSIQtb/bUF90jZBnH++L40ZzOeDCPkYFTpDvoE7sB3vyaDDjD8s9PzH5Iu +yK+KvlrKJ+Y8ptFhgQmkhgIfNCG6E6laeVgmokbEDdBGUrsjq1S/pTuY6FxFdHS4 +Ifn1L9YTlqiaVzJaH3jgVk1komVmKgw20CQZl+tcSxzpez1R1h35r+kDj6F4Lj38 +1aRHVCZrZP6mq/YntYou/m7eXGo= -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/oldcrl.pem b/test/recipes/80-test_cmp_http_data/Mock/oldcrl.pem index f596289d1db6f..4ca91cbc5a3c2 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/oldcrl.pem +++ b/test/recipes/80-test_cmp_http_data/Mock/oldcrl.pem @@ -1,12 +1,10 @@ -----BEGIN X509 CRL----- -MIIBtDCBnQIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJBVTETMBEGA1UE -CBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRk -MRMwEQYDVQQDEwpzdWJpbnRlckNBFw0yNDAyMjMxNTQ3MzhaFw0zNDEyMTcxNTQ3 -MzhaoA8wDTALBgNVHRQEBAICEAYwDQYJKoZIhvcNAQELBQADggEBANfH339j7LXB -9X+Vpk1xjTSRwoIQ7C/LZbOJ4tiVaNsBd+3rlOgJEnYPuB883ylAy3TOPn9taMXe -kmPebHC4WDhESNbwm8kdFNz6Ghvvn4TuDcSgWV8xxtw5AHVfnCs8801KI8pcn7K6 -MwGdJ7CPvB38SFn5ssKQueLySRfL+bRWXpgB79hjFE7J1ukaUr2xg3q4YFQwexld -xuaIR0AiFyTVKWTWLEdAKRzPiYTmx1ZMyYEdwh17l6nWh/UgfUEqmK9ub2Mqh20h -g7/Nwf0iaQS7bui7DgzkW76dbXcmAmTkU8VLznOLIheus8uj6Kl2TewO5PvjVGeu -Fgt7CED5epw= +MIIBdzBhAgEBMA0GCSqGSIb3DQEBCwUAMBwxGjAYBgNVBAMMEXNpZ25lci1zdWJp +bnRlckNBFw0yNjA4MjcxMzAyMTlaGA8yMTI2MDgyNzEzMDIxOVqgDzANMAsGA1Ud +FAQEAgIQBzANBgkqhkiG9w0BAQsFAAOCAQEAQHKy+cGe8hY+lZD1xzOoLNLp1/wt +t1n49pgrSCqDPI4VZc3cDrm8AzyDdmI1gGRQyGvMFOeWF4w5mBa+r9+M0FmomEkx +9Nz30ZGCAPeF5o02g4Bu/n7KvcY2gOVj+C9YTCSrMbFY1ITLK0L1t+QGF4e878ZI +NoMfNAgh5oiy8v1zeB91jeGCDjW4LzF1Dzcw9zN6Rdot9ReSeC23wsy7J2/6f25+ +di0jQHuGtsAVgSxjkRNtkUV9vbS4pWiC+LR7HK48RtsU8KTRn2dHkhsfkBoRJznX +cVfXyLBiS6O/oXW0PAjK7jxfXD8FqRpa9lStOxWZKRdpYjOaZvBribxjog== -----END X509 CRL----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/root.crt b/test/recipes/80-test_cmp_http_data/Mock/root.crt index 30fb8317e4b4e..37eb5dc4fbbc2 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/root.crt +++ b/test/recipes/80-test_cmp_http_data/Mock/root.crt @@ -1,22 +1,18 @@ -Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = rootCA -----BEGIN CERTIFICATE----- -MIIDfzCCAmegAwIBAgIJAIhDKcvC6xWaMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnJvb3RDQTAeFw0xNTA3MDIxMzE1MTFa -Fw0zNTA3MDIxMzE1MTFaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0 -YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMM -BnJvb3RDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMDxa3eIrDXf -+3NTL5KAL3QWMk31ECBvbDqO0dxr4S4+wwQPv5vEyRLR5AtFl+UGzWY64eDiK9+i -xOx70z08iv9edKCrpwNqFlteksR+W3mKadS8g16uQpJ0pSvnAMGp3NWxUwcPc/eO -rRQ+JZ7lHubMkc2VDIBEIMP9F8+RPWMQHBRb+8OowYiyd/+c2/xqRERE94XsCCzU -34Gjecn+HpuTFlO3l6u+Txql4vpGBeQNnCqkzLkeIaBsxKtZsEA5u/mIrf3fjbQL -r35B4CE8yDNFSYQvkwbu/U/tT/O8m978JV5V1XXUxXs6QDUGn8SEtGyTDK83Wq+2 -QU0mIxy4ArMCAwEAAaNQME4wDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUhVaJNeKf -ABrhhgMLS692Emszbf0wHwYDVR0jBBgwFoAUhVaJNeKfABrhhgMLS692Emszbf0w -DQYJKoZIhvcNAQELBQADggEBADIKvyoK4rtPQ86I2lo5EDeAuzctXi2I3SZpnOe0 -mCCxJeZhWW0S7JuHvlfhEgXFBPEXzhS4HJLUlZUsWyiJ+3KcINMygaiF7MgIe6hZ -WzpsMatS4mbNFElc89M+YryRFrQc9d1Uqjxhl3ms5MhDNcMP/PNwHa/wnIoqkpNI -qtDoR741wcZ7bdr6XVdF8+pBjzbBPPRSf24x3bqavHBWcTjcSVcM/ZEXxeqH5SN0 -GbK2mQxrogX4UWjtl+DfYvl+ejpEcYNXKEmIabUUHtpG42544cuPtZizLW5bt/aT -JBQfpPZpvf9MUlACxUONFOLQdZ8SXpSJ0e93iX2J2Z52mSQ= +MIIC7DCCAdSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1zaWdu +ZXItcm9vdENBMCAXDTI2MDgyNzEzMDIxOFoYDzIxMjYwODI4MTMwMjE4WjAYMRYw +FAYDVQQDDA1zaWduZXItcm9vdENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEArdsEEsPAXwKehceBZcTN0zd8+Qhv+HWqNHOXNlKX4Rwm5/Ph42ICuzVO +K0KbJSwPNLb5zttGw3rZ/r+oKHCXAiepKtAcou1W7UFRbFPDmmWPJB4WwHVv6I1Z +Fu/wFid4Dx1LXwOQ7QWENc/OwJbtnvN9X5/kiKkhEaqIbElQqeelA+Gw8uPdRg9s +5pTKN82knc86GgRxniS7ofqxhy3sDDCQJ9sC86fPYsqVZ21OH/adAkJ48TexgLIh +L1zdK+hfj09etmCVPbb9iLhP/z4x1glqOitIdnxkOmoe3ZigSKZwZyZsRlPd6msD +ZCS/EPkxOZyQRoRms1ilfe0i8U5xZwIDAQABoz8wPTAPBgNVHRMBAf8EBTADAQH/ +MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUoA1TXcKeefqbSnvsMKFWbkqQFsYwDQYJ +KoZIhvcNAQELBQADggEBAEuK74uzhJtAPJM31CKMZjBgfkxHheudb2jcPBiHQha7 +q+t3riQehGozWPwhMRBNaGTiJG7FTGjCp5lqrkQ9lUBkUqCy5mlTq9jR2ETK18Sf +N7vwaZ3rhnK99N/gL0SdRpuG/ed7WKTvveFSLhBwkHqijtY28uWvhanwboI3gObd +CU2OSd3umKuC/svf1S7p6py/t55dkljK2tcaLSDHVn+9ytqEGGOE96wJe35c5848 ++TWUqyMmvnvgiySq9zzu5XsHSTxHBwJUMds8Uu134MAhqkgY+xMSgqlq48uY0Ac0 +cDXn7ep55qVhu+ktX2JMuZsvXq2rrZbXyuRIy4GkJwM= -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/server.crt b/test/recipes/80-test_cmp_http_data/Mock/server.crt index d49b846995f24..7d0f28f103b83 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/server.crt +++ b/test/recipes/80-test_cmp_http_data/Mock/server.crt @@ -1,25 +1,20 @@ - Issuer: CN=Root CA - Validity - Not Before: Aug 8 13:28:36 2024 GMT - Not After : Apr 11 13:28:36 2127 GMT - Subject: CN=server.example -----BEGIN CERTIFICATE----- -MIIDVDCCAjygAwIBAgIUMoDahWpYk1B1WIjOwkom4s27V/EwDQYJKoZIhvcNAQEL -BQAwEjEQMA4GA1UEAwwHUm9vdCBDQTAgFw0yNDA4MDgxMzI4MzZaGA8yMTI3MDQx -MTEzMjgzNlowGTEXMBUGA1UEAwwOc2VydmVyLmV4YW1wbGUwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQDVXWBq3/xh7kiqjBFIQ6VttlJdqphJsWGSNbH8 -OgQlDG15/7TVyelcHDvgq7O4faPebb3g3ddavxRHEUJepoLQYcF/3RNG5gmFBw7y -1PwaZNIKrSCrIGuW8K3MxBlTVdwBHaSz74q0SVNdigUc8dzhRL/F1+J3GVdclwt1 -7ohDcQ/KbMG0slCnd0ZsWA8Rv/F2JFquOUK3UWcp4dBVMG8X5JHqrfgowkNvomSp -+52YkmJIPusNT4JKiv8/cu6Wta6hwZi6732QdW3/WlKeq/XAftCHQ9uFBwcPfTh6 -/dHT7mUd0+o5aoc37krT4A1u9XCswr3xbvOSlV6p8KFllZONAgMBAAGjgZgwgZUw -CQYDVR0TBAIwADAdBgNVHQ4EFgQUwOeEv+hZJzMQsFJPUVIvBtbAes0wHwYDVR0j -BBgwFoAUcH8uroNoWZgEIyrN6z4XzSTdAUkwDgYDVR0PAQH/BAQDAgWgMB0GA1Ud -JQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDIDAZBgNVHREEEjAQgg5zZXJ2ZXIuZXhh -bXBsZTANBgkqhkiG9w0BAQsFAAOCAQEAPRQ87zMFGrcQau8h8wDULU2PPgo1nifQ -1Vs+4WD7bPzk5GHl3M3OE2ZwhzYfO+ACcJa29Ahu7GRC660lXKlwONnQYuTTLqPD -KylY9ZJQUyP+CA5oZsDtnOcfrTy837jKq18NQ3ZxbRDpoVIATNHf9J2qe9yIkxYe -9p+aXGdvfDsNrhkz/m76V+KmioventOEKsRg64FfGKEZP8EfoBiNJipBdmN1I+GE -VTW91jjpgBTdCmyncmVn/CaV1d5S4ed4oQMLlLc+KsqDe97bF2TssFxcMmnyxgqb -bKDZOfzPI1HTs22tj6eLcZTIkcAuFET+uxcmFQcDsjYEf0G+iZLGWw== +MIIDMTCCAhmgAwIBAgIBAjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290 +IENBMCAXDTI2MDgyNzEzMDIxMloYDzIxMjYwODI4MTMwMjEyWjAZMRcwFQYDVQQD +DA5zZXJ2ZXIuZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AOgIpwWaDCfxfaFgAeMzu/eYbxcyY3YHAmuxAuw7+qt/qG+uGZlGM92s5VkZ9JVP +PGODADn1VyUTV0TXtwhMTdg/M4hGq8OrI6XHq9slNVXGuETWMTh/eJBWK81I7pC3 +Qseogi0VZnnmJWJLzUFLN31/UljHlLUj9RrSC0SU6nmChUcYRBEwH/mZ2vS8Meu1 +WwmKHami8FDjVd9SEhVvrYcjnu0mejDfcQtB7aktpnVO9gCkPkHtavD47rMrenBL +8KlY0njheAq0nfQ5TfU4Cfc6DZ7nUCbVmLfgAyetyDy9Z/qaQL6dXp5xdxZTE9+v +P5/pk5gnGjAuacj2BukSDqkCAwEAAaOBiDCBhTAdBgNVHQ4EFgQUD9JSfQYLumzt ++qlvpnSwhL4dtkMwHwYDVR0jBBgwFoAUroGrfFZGWmyeytjSbmFAHsIgx8EwCQYD +VR0TBAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAyAwGQYDVR0RBBIw +EIIOc2VydmVyLmV4YW1wbGUwDQYJKoZIhvcNAQELBQADggEBAA4W5qoM36Y+4U84 +i6wMo0q1mBxUpRUZQY26FYY6IPLoKve/CkgrdudiSU9fvVGQ5RIo4hgwWF/yBM2K +XJBRiaAw6ELz84p6UiNWDWqn2PCewomq2hc0IfR5pDBOsf5smHydAC0dA8xXCPJx +VnIjfmrFp7JeOp7VV0Qo9Lo0e3aOCQIE/IbCF2lWV0STps0Jv+m6qiDfuN8bC3/J +Q2ItxT/udhSZ74a8QbVSpJQt0m2Gcc+I4LQPu0jMZFPi2LT1QIwgoIo0d+0rarUg +rdg58V8tT6QpcYh9y9FJ8pVM57v/HYN6b7InTcybrg2jqPZVp+0tIB1HeBWdBQay +MDu4SRs= -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/server.key b/test/recipes/80-test_cmp_http_data/Mock/server.key index 0d7e4049fdc9f..3f54b0a3d4a6a 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/server.key +++ b/test/recipes/80-test_cmp_http_data/Mock/server.key @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDVXWBq3/xh7kiq -jBFIQ6VttlJdqphJsWGSNbH8OgQlDG15/7TVyelcHDvgq7O4faPebb3g3ddavxRH -EUJepoLQYcF/3RNG5gmFBw7y1PwaZNIKrSCrIGuW8K3MxBlTVdwBHaSz74q0SVNd -igUc8dzhRL/F1+J3GVdclwt17ohDcQ/KbMG0slCnd0ZsWA8Rv/F2JFquOUK3UWcp -4dBVMG8X5JHqrfgowkNvomSp+52YkmJIPusNT4JKiv8/cu6Wta6hwZi6732QdW3/ -WlKeq/XAftCHQ9uFBwcPfTh6/dHT7mUd0+o5aoc37krT4A1u9XCswr3xbvOSlV6p -8KFllZONAgMBAAECggEADLTt7A+A2Vg2jamf0dztejY0e42QWjstI2b9PZc67fXq -gyx+WYkX07t+uWegYWliG/oPJ9guXiIpE/5sJHToL37S5kmFP2CtynVcJ4wVo4DD -nY0n9+kLX0bgIuS+2V6wpoRcbbbjXM9NHrH8kfe5ftT4UtEDlLI2qLX6IcDd7p4u -OYjILChR8GSGTw96yIy2Ws/1Uq9PMw64JoT4RcK5QqnkcPMDFRH1SeLOL+zXP2c4 -nEl9yOy3HauZKxwl/Ry/XK1s3DdjopIAU29ut+hAuMiTb06kzZnumL9NoplKoZtU -otw/gVcCKhT+Ep+p6i8InLF0XEME8A0qUR0niWebgQKBgQD6vkxR49B8ZZQrzjw4 -XKs1lI9cP7cgPiuWlDHMNjYou3WbOaGrMeScvbB1Ldh9A8pjAhxlw8AaV/xs4qcA -trmVmSISVMVyc1wSGlJXWi2nUzTNs9OE3vj22SyStihf8UUZtWwX2b5Y4JrYhA/V -+ThGGqHR03oLNLShNLtJc2c7YQKBgQDZ1nkibEyrepexw/fnwkw61IJKq9wRIh1G -PREakhbe9wU5ie0knuf9razt7awzQiwFmlixmWqsM7UEtLuXNnNPciwdrKhhbvrd -vD/rkbIEHEPllIhFlDtOzn3hRBWTzWmXFjpou/2LvHTSbVis4IYVZymTp2jb1ZLs -7VbiG9JTrQKBgQDc6n75g1szzpdehQT/r33U5j/syeJBUSU8NPMu9fB/sLHsgjlT -SNEf2+y1QSBE/Or6kmiMrIv7advn30W+Vj9qc5HWTsPrk4HiHTjA553jl2alebN5 -lK4LZspjtIQcC8mS3goPdXPEgJdM/gWpwzr2YQ6DfOxBJT2j7n64NyoT4QKBgH7/ -yx+GhCx1DHtXBPDZFhg2TL+78lEK0oZgk9gp06up2CHzh44SFq6O0oLkTcCUk5Ww -poTkLIy4mJBlzfgahp+KsK2cO46SZS9g0ONFzcMXt33hWpE2Gl2XhUwPpYTF/QlY -rDTjZK5S8Mi9dzVSsNlJi7PJphiEK2R1+nFYRwcBAoGBANWoIG85jpXAOnq/Kcgx -Rl3YivR0Ke6r1tFlP58rT7X3EkiboXyQl5vLIFCAwUte6RGrLl1dy3Qyh80B9ySL -Jx6vj42CK7vgv6A96TuVYhnXTnEI6ZvwAQ2VGaw4BizhjALs/kdSE/og9aSCs3ws -KQypwAFz0tbHxaNag/bSAN0J +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDoCKcFmgwn8X2h +YAHjM7v3mG8XMmN2BwJrsQLsO/qrf6hvrhmZRjPdrOVZGfSVTzxjgwA59VclE1dE +17cITE3YPzOIRqvDqyOlx6vbJTVVxrhE1jE4f3iQVivNSO6Qt0LHqIItFWZ55iVi +S81BSzd9f1JYx5S1I/Ua0gtElOp5goVHGEQRMB/5mdr0vDHrtVsJih2povBQ41Xf +UhIVb62HI57tJnow33ELQe2pLaZ1TvYApD5B7Wrw+O6zK3pwS/CpWNJ44XgKtJ30 +OU31OAn3Og2e51Am1Zi34AMnrcg8vWf6mkC+nV6ecXcWUxPfrz+f6ZOYJxowLmnI +9gbpEg6pAgMBAAECggEAONTLsdXMBemCU4j8FV25u3hIt1YGYeVwHJffpyQ+rown +IWlzSCUXdYNQLk1q6DoeyKHQp6F1fXV6AbjTEfN8eotqUAW9MsDjS4q3B0cbA94X +Cncq2ZNxIGsWseJb2jKkptnZPnkYHyG1RNjbllM5rWGGtgt2GxLKSQ4qp9rQfj94 +CD2cWX9CH6Qiv/tYPOxFICv6j4YDvUSuCiJpDXUeQXqhsN5PRGHbW/7K4gPbV9Bg +VMQDuBbr0NK333HLMxioWf+GbOWqhFYfbk33RPe6owaL/raHkJgsgClFKbTIWERY +z6dbBhyiC2+7Fite4XyYHTLqabfCiEDqJujiaI9THQKBgQD1bTQhePlu4dBEvIbn +wv+1O861cYKbiE2QB+E5pPnoV/Mho6Pxuoc+oNf7ksxy9Y1icSIK5wytVgcMJdu9 +O72PQKmWInD7W0IPBdkup0mkJvI4AyBcgKw7uWjfA8Krr9Xn775Z1Y+34wOEKCRj +toZtV6XUzYZ6vHoHGh6kBLAPDQKBgQDyB72WHHnjdKSZpIIkP9Wq1hdiyezu547j +4R9OY07PERrByRz4rBrKq2rL/mOzCSsPl9gXTtvIPjE7oh4V2zgrDeJY/HoW4OrR +LI9cPYpPzwaVym8RS5IdbBk1MpBcOD0zpDpv+Llgmxj/1IzKfGUHcRBu9qyYnCF3 +V8xdZxu3DQKBgDK4ZtWkEqh/snMCIz8yZXYm7glBdCSAfscNWdZ36c3Cn1SMZQ1H +5ztiMkCjje0UIiv+BXMLXOtVpA82o7rv5bT9QA7u/zpzGavRIZkqqWVrRxOcUcvM +K8wL/UhZlpm0tRhBy6z1HcZ6+/cL9LlGt3FRc8wOzYP//5gIJdzvuxLhAoGBAMoQ +clTwA0dF6+ImOU0ASmftg+rDQN+YTXCtU9DDElnIIvmk6V4nedq40FntUdl4jw3e +rNeQy+dbHQl3aPzAYB154v5+E4QkVYc7V5kf++hzpEDMmHvtBtkvlcAXLfUAMwB5 +XRx8oHAqLO3xy3WF82cKGzk5EpH6z+nuUD2uxrHFAoGAB9/Vbw2hpc+mqSmDAVGx +1fGDzp1V7gx81UiSadkJAYcIEnQRYjitD4uJ3ZhnXlOzHeyJXsPy/c99DUGONod6 +XD4j2cI40fI/hbFDIL+RdZ+q6WC22iKJ1IA7i49cSgYs37URTn5RqKnMhkmAthga +8TbBhVvZLWrcBa/eFNt9YXU= -----END PRIVATE KEY----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/setup-mock.sh b/test/recipes/80-test_cmp_http_data/Mock/setup-mock.sh new file mode 100755 index 0000000000000..c1b3239a37da4 --- /dev/null +++ b/test/recipes/80-test_cmp_http_data/Mock/setup-mock.sh @@ -0,0 +1,197 @@ +#! /bin/bash +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You can obtain a copy in the file LICENSE in the source distribution +# or at https://www.openssl.org/source/license.html +# +# Script to set up credentials for CMP mock server and tested client (signer) +# Usage: ./setup-mock.sh [PQC] +# Using the optional parameter "PQC" will generate certificates using PQC algorithms, +# otherwise classic algorithms are used. +# Using PQC algorithms makes testing take longer as it is more computationally intensive. +################################################################### +set -e +#set -x # for debug + +mkcert_sh="../../../certs/mkcert.sh" +OPENSSL=openssl +# Specify whether PQC or Classic algorithms are used +# Possible values: "PQC" or "Classic" +# Check if first parameter is PQC, then set USE_PQC accordingly + +if [[ "$(printf '%s' "$1" | tr '[:upper:]' '[:lower:]')" == "pqc" ]]; then + OPENSSL_VER=$($OPENSSL version | awk '{print $2}') + if ! awk -v ver="$OPENSSL_VER" 'BEGIN { + split(ver, a, /[.\-]/); split("3.5.0", b, /[.\-]/); + for (i=1; i<=3; i++) if (a[i]+0 != b[i]+0) { exit (a[i]+0 > b[i]+0) ? 0 : 1 }; exit 0 }'; then + echo "Error: OpenSSL version 3.5 or higher is required for PQC algorithms. Current version: $OPENSSL_VER" + exit 1 + fi + USE_PQC=1 +fi + +if [ -z "$DAYS" ]; then + DAYS=36524 # 100 years, with 24 leap years per 100 years until 2400 +fi + +if [[ ${USE_PQC+set} ]]; then + alg="MLDSA65" + # Central key generation test(s) will fail as leaf cert is required + # for encryption + alg2="SLH-DSA-SHAKE-192s" +else + alg="rsa" + alg2=$alg +fi + # algorithms for server certificate chain + server_rootca_keyalg=$alg2 + server_leaf_keyalg=$alg + # rootCACert update test case + new_rootca_keyalg=$alg + + # algorithms for client certificate chain + signer_rootca_keyalg=$alg + signer_interca_keyalg=$alg + signer_subinterca_keyalg=$alg + # signer leaf uses alg2 to exercise algorithm diversity in the chain; + # for PQC mode, alg2 is SLH-DSA which is a signature-only algorithm + signer_leaf_keyalg=$alg2 + +# CMP server certificate +rename_serverfiles() { + echo "Removing intermediate files and renaming mock server files" + # removing unneeded files + rm server_root-key.pem server_root-pubkey.pem newWithNew-key.pem newWithNew-pubkey.pem + mv server_root-cert.pem server_root.crt + cp server_root.crt trusted.crt + cat trusted.crt >> big_trusted.crt # works also if not yet existing + mv server_root.crt oldWithOld.pem + mv server-key.pem server.key + mv server-cert.pem server.crt + mv newWithNew-cert.pem newWithNew.pem +} + +remove_serverfiles() { + echo "Removing server files" + rm -f server_root.crt trusted.crt server.key server.crt + rm -f oldWithOld.pem newWithNew.pem oldWithNew.pem newWithOld.pem +} + +gen_server_credentials() { + remove_serverfiles + # allow time to sync file system after deletions + sleep 5 + OPENSSL_KEYALG=${server_rootca_keyalg} \ + $mkcert_sh genroot "Root CA" server_root-key server_root-cert + OPENSSL_KEYALG=${server_leaf_keyalg} \ + $mkcert_sh genee -p serverAuth,cmKGA server.example server-key server-cert server_root-key server_root-cert + + OPENSSL_KEYALG=${new_rootca_keyalg} \ + $mkcert_sh genroot "Root CA" newWithNew-key newWithNew-cert + + $OPENSSL pkey -in newWithNew-key.pem -out newWithNew-pubkey.pem -outform PEM -pubout + $OPENSSL x509 -new -subj "/CN=Root CA" -CA server_root-cert.pem -CAkey server_root-key.pem \ + -out newWithOld.pem -force_pubkey newWithNew-pubkey.pem \ + -extfile <(printf "basicConstraints=critical,CA:true") + + $OPENSSL pkey -in server_root-key.pem -out server_root-pubkey.pem -outform PEM -pubout + $OPENSSL x509 -new -subj "/CN=Root CA" -CA newWithNew-cert.pem -CAkey newWithNew-key.pem \ + -out oldWithNew.pem -force_pubkey server_root-pubkey.pem \ + -extfile <(printf "basicConstraints=critical,CA:true") + + rename_serverfiles +} + +rename_signerfiles() { + echo "Renaming signer files" + mv signer_root-cert.pem root.crt + cat root.crt >> big_root.crt + cp root.crt signer_root.crt + # $OPENSSL crl -in signer_subinterCA-crl0.pem -out crl.der -outform DER + mv signer_subinterCA-crl0.pem oldcrl.pem + mv signer_subinterCA-crl1.pem newcrl.pem + rm -f signer_root-key.pem signer_interCA-key.pem signer_interCA-cert.pem \ + signer_subinterCA-key.pem + mv signer_subinterCA-cert.pem issuing.crt + cat issuing.crt >> big_issuing.crt + mv signer_leaf-key.pem new.key + $OPENSSL pkey -in new.key -out new_pass_12345.key -aes256 -passout file:12345.txt + mv signer_leaf-csr.pem csr.pem + cp new.key signer.key + mv signer_leaf-cert.pem signer_only.crt + mv signer_issuing-cert.pem signer_issuing.crt + mv signer_chain.pem signer.crt +} +remove_signerfiles() { + echo "Removing signer files" + rm -f root.crt signer_root.crt newcrl.pem oldcrl.pem new.key signer.key signer_only.crt \ + signer_no_SKID.crt signer_issuing.crt signer.crt issuing.crt csr.pem +} + +# cannot use genee() because this uses a self-signature for the POP in a PKCS#10 CSR +genee_kem() { + local cn=$1; shift + local key=$1; shift + local cert=$1; shift + local cakey=$1; shift + local ca=$1; shift + echo "Generating KEM certificate" + $OPENSSL genpkey -algorithm "$OPENSSL_KEYALG" -out ${key}.pem -outpubkey ${cn}-pubkey.pem + $OPENSSL x509 -new -subj "/CN=${cn}" -CA ${ca}.pem -CAkey ${cakey}.pem \ + -out ${cert}.pem -force_pubkey ${cn}-pubkey.pem \ + -extfile <(printf "basicConstraints=critical,CA:false\nkeyUsage=critical,keyEncipherment") + $OPENSSL x509 -new -subj "/CN=${cn}-noSKID" -CA ${ca}.pem -CAkey ${cakey}.pem \ + -out ${cert}-noSKID.pem -force_pubkey ${cn}-pubkey.pem \ + -extfile <(printf "basicConstraints=critical,CA:false\nkeyUsage=critical,keyEncipherment\nsubjectKeyIdentifier=none") + rm -f ${cn}-pubkey.pem +} + +gen_client_chain() { + echo "Generating signer certificates" + remove_signerfiles + # allow time to sync file system after deletions + sleep 5 + OPENSSL_KEYALG=${signer_rootca_keyalg} \ + $mkcert_sh genroot "signer-rootCA" signer_root-key signer_root-cert + OPENSSL_KEYALG=${signer_interca_keyalg} \ + $mkcert_sh genca "signer-interCA" signer_interCA-key signer_interCA-cert signer_root-key signer_root-cert + OPENSSL_KEYALG=${signer_subinterca_keyalg} \ + $mkcert_sh genca "signer-subinterCA" signer_subinterCA-key signer_subinterCA-cert signer_interCA-key signer_interCA-cert + + if [[ "$signer_leaf_keyalg" == *KEM* ]]; then + OPENSSL_KEYALG=${signer_leaf_keyalg} genee_kem "signer-leaf" signer_leaf-key signer_leaf-cert signer_subinterCA-key signer_subinterCA-cert + # cannot use KEM signer_leaf-key.pem for PKCS#10 CSR generation, using signer_subinterCA-key instead + $OPENSSL req -new -subj "/CN=signer-leaf-csr" -key signer_subinterCA-key.pem -out signer_leaf-csr.pem + else + OPENSSL_KEYALG=${signer_leaf_keyalg} \ + $mkcert_sh genee -p clientAuth "signer-leaf" signer_leaf-key signer_leaf-cert signer_subinterCA-key signer_subinterCA-cert + # create signer certificate without subjectKeyIdentifier + # $OPENSSL req -new -subj "/CN=signer-leaf-noSKID" -key signer_leaf-key.pem \ + # | $OPENSSL x509 -req -days $DAYS -extfile <(printf "subjectKeyIdentifier=none") -out signer_leaf-cert-noSKID.crt -CA signer_subinterCA-cert.pem -CAkey signer_subinterCA-key.pem + $OPENSSL req -new -subj "/CN=signer-leaf-csr" -key signer_leaf-key.pem -out signer_leaf-csr.pem + fi + + echo "Generating demoCA folder" + mkdir -p demoCA + touch demoCA/index.txt + echo 1007 > demoCA/crlnumber + $OPENSSL ca -gencrl -keyfile signer_subinterCA-key.pem -cert signer_subinterCA-cert.pem -out signer_subinterCA-crl0.pem -crldays $DAYS \ + -config <(printf "[ca]\ndefault_ca= CA_default\n[CA_default]\n%s\n%s\n%s\n" \ + "database = ./demoCA/index.txt" "crlnumber = ./demoCA/crlnumber" "default_md = default") + cat signer_leaf-cert.pem signer_subinterCA-cert.pem signer_interCA-cert.pem > signer_chain.pem + cat signer_subinterCA-cert.pem signer_interCA-cert.pem signer_root-cert.pem > signer_fullchain.pem + $OPENSSL pkcs12 -export -out signer.p12 -inkey signer_leaf-key.pem -in signer_leaf-cert.pem -certfile signer_fullchain.pem -password file:12345.txt + rm -f signer_fullchain.pem + cat signer_subinterCA-cert.pem signer_interCA-cert.pem > signer_issuing-cert.pem + sleep 5 # Wait for 5 seconds before generating the next CRL + $OPENSSL ca -gencrl -keyfile signer_subinterCA-key.pem -cert signer_subinterCA-cert.pem -out signer_subinterCA-crl1.pem -crldays $DAYS \ + -config <(printf "[ca]\ndefault_ca= CA_default\n[CA_default]\n%s\n%s\n%s\n" \ + "database = ./demoCA/index.txt" "crlnumber = ./demoCA/crlnumber" "default_md = default") + rename_signerfiles + rm -rf demoCA +} + +gen_server_credentials +gen_client_chain diff --git a/test/recipes/80-test_cmp_http_data/Mock/signer.crt b/test/recipes/80-test_cmp_http_data/Mock/signer.crt index cb72e33bff768..5abd7b7faa5c9 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/signer.crt +++ b/test/recipes/80-test_cmp_http_data/Mock/signer.crt @@ -1,68 +1,57 @@ -Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = leaf -----BEGIN CERTIFICATE----- -MIIDfjCCAmagAwIBAgIJAKRNsDKacUqNMA0GCSqGSIb3DQEBCwUAMFoxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxEzARBgNVBAMTCnN1YmludGVyQ0EwHhcNMTUwNzAyMTMx -OTQ5WhcNMzUwNzAyMTMxOTQ5WjBUMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29t -ZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQ0wCwYD -VQQDEwRsZWFmMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv0Qo9WC/ -BKA70LtQJdwVGSXqr9dut3cQmiFzTb/SaWldjOT1sRNDFxSzdTJjU/8cIDEZvaTI -wRxP/dtVQLjc+4jzrUwz93NuZYlsEWUEUg4Lrnfs0Nz50yHk4rJhVxWjb8Ii/wRB -ViWHFExP7CwTkXiTclC1bCqTuWkjxF3thTfTsttRyY7qNkz2JpNx0guD8v4otQoY -jA5AEZvK4IXLwOwxol5xBTMvIrvvff2kkh+c7OC2QVbUTow/oppjqIKCx2maNHCt -LFTJELf3fwtRJLJsy4fKGP0/6kpZc8Sp88WK4B4FauF9IV1CmoAJUC1vJxhagHIK -fVtFjUWs8GPobQIDAQABo00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBQcHcT+8SVG -IRlN9YTuM9rlz7UZfzAfBgNVHSMEGDAWgBTpZ30QdMGarrhMPwk+HHAV3R8aTzAN -BgkqhkiG9w0BAQsFAAOCAQEAGjmSkF8is+v0/RLcnSRiCXENz+yNi4pFCAt6dOtT -6Gtpqa1tY5It9lVppfWb26JrygMIzOr/fB0r1Q7FtZ/7Ft3P6IXVdk3GDO0QsORD -2dRAejhYpc5c7joHxAw9oRfKrEqE+ihVPUTcfcIuBaalvuhkpQRmKP71ws5DVzOw -QhnMd0TtIrbKHaNQ4kNsmSY5fQolwB0LtNfTus7OEFdcZWhOXrWImKXN9jewPKdV -mSG34NfXOnA6qx0eQg06z+TkdrptH6j1Va2vS1/bL+h1GxjpTHlvTGaZYxaloIjw -y/EzY5jygRoABnR3eBm15CYZwwKL9izIq1H3OhymEi/Ycg== +MIIDKTCCAhGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFzaWdu +ZXItc3ViaW50ZXJDQTAgFw0yNjA4MjcxMzAyMTlaGA8yMTI2MDgyODEzMDIxOVow +FjEUMBIGA1UEAwwLc2lnbmVyLWxlYWYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCtBcRoZPjeL/Ufg/WTaqLp8JAtc5d/+VHepTPMWuiBRPHfnVcuFIw8 +zXg5VMGgYQrGORfzGEqYUFifJgP1CFA7QQbdx+rYMweLj8H/M28838tM2nh3SSxJ +28SEcN0hHqBD5Asb0jqhlKvDoRLA0Wlh+AuSTy9qSgGZDCpCOhEHTM7/Tlgfo1lp +an+2I/HspvlnfSPwOtVLTI0FTmVeqTSaLjEubFhJXHbcfCzU4Uo69N5rNnWHNn+B +qD0xQSTZMM6uijN0m75Z5x++46V9ePFTqKnApZb+qDE07/ywnC+yQ0dIcmUnWnKE +/qB/TEe80rObcxkwyML0AixECzbxg2MbAgMBAAGjejB4MB0GA1UdDgQWBBTfXRko +n4RzVx7JubTWpN0NsB1Y9jAfBgNVHSMEGDAWgBTBLcMazlMMaD5Qi0604+IDUwOc +dTAJBgNVHRMEAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMCMBYGA1UdEQQPMA2CC3Np +Z25lci1sZWFmMA0GCSqGSIb3DQEBCwUAA4IBAQC4gRs9nILUGjNciLmY6+iyhoEy +pjDXAsNqKfCmtQXbh7lVZN1fgXlcVIjZp1DWaR/ie6h5+jt5fc2rIbocQQV8xcDd +LN1IsculUoe9ipyZz8miWyPfYRT5fclko7RH2ndkimJg3r2gF8szeoq87QjTyfez +T/Um3RRfniTlaEGVuy2628q9VbN+ZBvKkPhIXbDMzUW7rcZDSBX5qmrmcusJDrRr +fTCVwXdrCJjI6ozyDc459Zi7s6aGiZWexgNu85Nai8udujdy9dHWtcCbqLcEMD0l +IfIeKIyu7QmVvuO/GO1op0v4i4Betd+sRJSzasvpapi9cdLfDIDiLrZ+f9SC -----END CERTIFICATE----- - -Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = subinterCA -----BEGIN CERTIFICATE----- -MIIDhDCCAmygAwIBAgIJAJkv2OGshkmUMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMTB2ludGVyQ0EwHhcNMTUwNzAyMTMxODIz -WhcNMzUwNzAyMTMxODIzWjBaMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1T -dGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRMwEQYDVQQD -EwpzdWJpbnRlckNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/zQj -vhbU7RWDsRaEkVUBZWR/PqZ49GoE9p3OyRN4pkt1c1yb2ARVkYZP5e9gHb04wPVz -2+FYy+2mNkl+uAZbcK5w5fWO3WJIEn57he4MkWu3ew1nJeSv3na8gyOoCheG64kW -VbA2YL92mR7QoSCo4SP7RmykLrwj6TlDxqgH6DxKSD/CpdCHE3DKAzAiri3GVc90 -OJAszYHlje4/maVIOayGROVET3xa5cbtRJl8IBgmqhMywtz4hhY/XZTvdEn290aL -857Hk7JjogA7mLKi07yKzknMxHV+k6JX7xJEttkcNQRFHONWZG1T4mRY1Drh6VbJ -Gb+0GNIldNLQqigkfwIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBTp -Z30QdMGarrhMPwk+HHAV3R8aTzAfBgNVHSMEGDAWgBQY+tYjuY9dXRN9Po+okcfZ -YcAXLjANBgkqhkiG9w0BAQsFAAOCAQEAgVUsOf9rdHlQDw4clP8GMY7QahfXbvd8 -8o++P18KeInQXH6+sCg0axZXzhOmKwn+Ina3EsOP7xk4aKIYwJ4A1xBuT7fKxquQ -pbJyjkEBsNRVLC9t4gOA0FC791v5bOCZjyff5uN+hy8r0828nVxha6CKLqwrPd+E -mC7DtilSZIgO2vwbTBL6ifmw9n1dd/Bl8Wdjnl7YJqTIf0Ozc2SZSMRUq9ryn4Wq -YrjRl8NwioGb1LfjEJ0wJi2ngL3IgaN94qmDn10OJs8hlsufwP1n+Bca3fsl0m5U -gUMG+CXxbF0kdCKZ9kQb1MJE4vOk6zfyBGQndmQnxHjt5botI/xpXg== +MIIDEjCCAfqgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDDA5zaWdu +ZXItaW50ZXJDQTAgFw0yNjA4MjcxMzAyMThaGA8yMTI2MDgyODEzMDIxOFowHDEa +MBgGA1UEAwwRc2lnbmVyLXN1YmludGVyQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDVtUxlSXhn0YEKL1kcHdGWxhZfrFfKc9/bc/h+gX9DLjUviYgy +WfKPVPMDwek9FyaPhwuevDHnbhJ998PZwPhZGUVooE7E/0Ws9gdrkwiCekYDwrkV ++FcF7Z8y42kem4epConTKez9zsK9kks1gO/c0UYG8p4IW4IP0dCPG+hWx5TdxAOC +gBUEft9DY93Hw5sZCzkNHBgdCg9CtDfxKhlSmsomZUj0WRVnMlz7KxnOmcnOLYex +OaWQbaxGVPj88jnFCprDwcl41wod/FCQ2FBi5EgU6i+OS+kXua3Yf0BqzBa6Bt39 +T6n+SoJSKxj4MJtanXcZ42VnztFuvc9zbRs7AgMBAAGjYDBeMA8GA1UdEwEB/wQF +MAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTBLcMazlMMaD5Qi0604+IDUwOc +dTAfBgNVHSMEGDAWgBTsiAttQK5AyZloxjLpJLX3YYxcDDANBgkqhkiG9w0BAQsF +AAOCAQEASRQKe65V4miLNvyU0jK2UoHCoguA3faWKEyQfnD61nEQ6f5/w35c5AVP +nVZRgk+ADt0bRCpQpstAw8fl1IMGgjrtMReHr70ToLtKEpRbwBgNPa9fDCl27zG7 +pfAY+RTcZMp2eJDfOY0VAKAP4kO/of6Mg18hClJ6JONTyGNP5M7hHlKbwJDhVEUI ++T7C7QzlvS0WdiI/aaSm5hrTpz7W7gRhU/PNIssxj++72eNlyLxMSLLSXLbi2SnL +v9gb7traRUMXuI/qCWkFxMP6xm3kMg+++hqlWpqtrSK+4jbwbvnlSO75KYgxR8Qm +B8/0Fc0HcrlPxqKcz7XOHfNtbAWOcg== -----END CERTIFICATE----- - -Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = interCA -----BEGIN CERTIFICATE----- -MIIDgDCCAmigAwIBAgIJANnoWlLlEsTgMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnJvb3RDQTAeFw0xNTA3MDIxMzE3MDVa -Fw0zNTA3MDIxMzE3MDVaMFcxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 -YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMT -B2ludGVyQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7s0ejvpQO -nvfwD+e4R+9WQovtrsqOTw8khiREqi5JlmAFbpDEFam18npRkt6gOcGMnjuFzuz6 -iEuQmeeyh0BqWAwpMgWMMteEzLOAaqkEl//J2+WgRbA/8pmwHfbPW/d+f3bp64Fo -D1hQAenBzXmLxVohEQ9BA+xEDRkL/cA3Y+k/O1C9ORhSQrJNsB9aE3zKbFHd9mOm -H4aNSsF8On3SqlRVOCQine5c6ACSd0HUEjYy9aObqY47ySNULbzVq5y6VOjMs0W+ -2G/XqrcVkxzf9bVqyVBrrAJrnb35/y/iK0zWgJBP+HXhwr5mMTvNuEirBeVYuz+6 -hUerUbuJhr0FAgMBAAGjUDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFBj61iO5 -j11dE30+j6iRx9lhwBcuMB8GA1UdIwQYMBaAFIVWiTXinwAa4YYDC0uvdhJrM239 -MA0GCSqGSIb3DQEBCwUAA4IBAQDAU0MvL/yZpmibhxUsoSsa97UJbejn5IbxpPzZ -4WHw8lsoUGs12ZHzQJ9LxkZVeuccFXy9yFEHW56GTlkBmD2qrddlmQCfQ3m8jtZ9 -Hh5feKAyrqfmfsWF5QPjAmdj/MFdq+yMJVosDftkmUmaBHjzbvbcq1sWh/6drH8U -7pdYRpfeEY8dHSU6FHwVN/H8VaBB7vYYc2wXwtk8On7z2ocIVHn9RPkcLwmwJjb/ -e4jmcYiyZev22KXQudeHc4w6crWiEFkVspomn5PqDmza3rkdB3baXFVZ6sd23ufU -wjkiKKtwRBwU+5tCCagQZoeQ5dZXQThkiH2XEIOCOLxyD/tb +MIIDDjCCAfagAwIBAgIBAjANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1zaWdu +ZXItcm9vdENBMCAXDTI2MDgyNzEzMDIxOFoYDzIxMjYwODI4MTMwMjE4WjAZMRcw +FQYDVQQDDA5zaWduZXItaW50ZXJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALfzO3Ys1oIQJNE2fZZjgiIZO3v2FbvxDt28ggZUaIpjttrxSaWM4bDV +PC0v8oz1pCrrQf9q6bztT+4BYR+hqNw7o1E6SY5dFdz/RweO320QfjExJzAu2K6K +5vC+NH6P2plkT90do3Zri0M6tBDGg8pBzPNyXvBrlLwzwRETLhvf10qiMkzrdnYe +GOW/lVRMfvxlHsuu+CTdPwOTz6qdnShBBdACr6xee8rjK67Gv/R4yzyS16ncDjR3 +ziMjYxn6+4qS/zptS0TUQfPUQ6RXvfK81cVQetyC3MU8QNB5kIT5cEoW35GV9+o5 +tZSnOcdkZR51lXEhAJtqgJsIQ1B+f8cCAwEAAaNgMF4wDwYDVR0TAQH/BAUwAwEB +/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFOyIC21ArkDJmWjGMukktfdhjFwMMB8G +A1UdIwQYMBaAFKANU13Cnnn6m0p77DChVm5KkBbGMA0GCSqGSIb3DQEBCwUAA4IB +AQBCjFFpMSfNBAU9QppyYGoWwjixegxmHOE8EzKVocxLXDee23EX1ANX1l5EkcgR +bhYuL7Kr2SrMFbdGnSDuUpuSKP+KiYZsGyP/RAz7ST8FrlzQI4WZ+TzbLj5hYojk +Oh4Z/yQcfrIjO740p5MUDLQThHO2cnK9f+aYZSb4b+Ehu4MPlmTsgV2WfD9lgOhE ++zrCST26a59M3kdkDvsfJqJADVDSN9EqhAGKJ19SC/grGfEzcT3ABZFa4r0ssixu +PIhUwlTW78gXt6Yg0XuvuoafI6W2x2zogqKN9QNgx31VJHXV+SNbz2toXHLPXKb9 +TPbbQ7/he/c0/zxKZ6WeiSEW -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/signer.key b/test/recipes/80-test_cmp_http_data/Mock/signer.key index a1b1721245b7f..9af28408fe0ee 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/signer.key +++ b/test/recipes/80-test_cmp_http_data/Mock/signer.key @@ -1,27 +1,28 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAv0Qo9WC/BKA70LtQJdwVGSXqr9dut3cQmiFzTb/SaWldjOT1 -sRNDFxSzdTJjU/8cIDEZvaTIwRxP/dtVQLjc+4jzrUwz93NuZYlsEWUEUg4Lrnfs -0Nz50yHk4rJhVxWjb8Ii/wRBViWHFExP7CwTkXiTclC1bCqTuWkjxF3thTfTsttR -yY7qNkz2JpNx0guD8v4otQoYjA5AEZvK4IXLwOwxol5xBTMvIrvvff2kkh+c7OC2 -QVbUTow/oppjqIKCx2maNHCtLFTJELf3fwtRJLJsy4fKGP0/6kpZc8Sp88WK4B4F -auF9IV1CmoAJUC1vJxhagHIKfVtFjUWs8GPobQIDAQABAoIBAB1fCiskQDElqgnT -uesWcOb7u55lJstlrVb97Ab0fgtR8tvADTq0Colw1F4a7sXnVxpab+l/dJSzFFWX -aPAXc1ftH/5sxU4qm7lb8Qx6xr8TCRgxslwgkvypJ8zoN6p32DFBTr56mM3x1Vx4 -m41Y92hPa9USL8n8f9LpImT1R5Q9ShI/RUCowPyzhC6OGkFSBJu72nyA3WK0znXn -q5TNsTRdJLOug7eoJJvhOPfy3neNQV0f2jQ+2wDKCYvn6i4j9FSLgYC/vorqofEd -vFBHxl374117F6DXdBChyD4CD5vsplB0zcExRUCT5+iBqf5uc8CbLHeyNk6vSaf5 -BljHWsECgYEA93QnlKsVycgCQqHt2q8EIZ5p7ksGYRVfBEzgetsNdpxvSwrLyLQE -L5AKG3upndOofCeJnLuQF1j954FjCs5Y+8Sy2H1D1EPrHSBp4ig2F5aOxT3vYROd -v+/mF4ZUzlIlv3jNDz5IoLaxm9vhXTtLLUtQyTueGDmqwlht0Kr3/gcCgYEAxd86 -Q23jT4DmJqUl+g0lWdc2dgej0jwFfJ2BEw/Q55vHjqj96oAX5QQZFOUhZU8Otd/D -lLzlsFn0pOaSW/RB4l5Kv8ab+ZpxfAV6Gq47nlfzmEGGx4wcoL0xkHufiXg0sqaG -UtEMSKFhxPQZhWojUimK/+YIF69molxA6G9miOsCgYEA8mICSytxwh55qE74rtXz -1AJZfKJcc0f9tDahQ3XBsEb29Kh0h/lciEIsxFLTB9dFF6easb0/HL98pQElxHXu -z14SWOAKSqbka7lOPcppgZ1l52oNSiduw4z28mAQPbBVbUGkiqPVfCa3vhUYoLvt -nUZCsXoGF3CVBJydpGFzXI0CgYEAtt3Jg72PoM8YZEimI0R462F4xHXlEYtE6tjJ -C+vG/fU65P4Kw+ijrJQv9d6YEX+RscXdg51bjLJl5OvuAStopCLOZBPR3Ei+bobF -RNkW4gyYZHLSc6JqZqbSopuNYkeENEKvyuPFvW3f5FxPJbxkbi9UdZCKlBEXAh/O -IMGregcCgYBC8bS7zk6KNDy8q2uC/m/g6LRMxpb8G4jsrcLoyuJs3zDckBjQuLJQ -IOMXcQBWN1h+DKekF2ecr3fJAJyEv4pU4Ct2r/ZTYFMdJTyAbjw0mqOjUR4nsdOh -t/vCbt0QW3HXYTcVdCnFqBtelKnI12KoC0jAO9EAJGZ6kE/NwG6dQg== ------END RSA PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtBcRoZPjeL/Uf +g/WTaqLp8JAtc5d/+VHepTPMWuiBRPHfnVcuFIw8zXg5VMGgYQrGORfzGEqYUFif +JgP1CFA7QQbdx+rYMweLj8H/M28838tM2nh3SSxJ28SEcN0hHqBD5Asb0jqhlKvD +oRLA0Wlh+AuSTy9qSgGZDCpCOhEHTM7/Tlgfo1lpan+2I/HspvlnfSPwOtVLTI0F +TmVeqTSaLjEubFhJXHbcfCzU4Uo69N5rNnWHNn+BqD0xQSTZMM6uijN0m75Z5x++ +46V9ePFTqKnApZb+qDE07/ywnC+yQ0dIcmUnWnKE/qB/TEe80rObcxkwyML0AixE +Czbxg2MbAgMBAAECggEAAzGtOlzMJ/82+rcgaZwZLXwROqLneTzR2+wtJHN0ga0T +UVShvzTbkTnHzjh4Kezwr8/DrJYBC9vGhGBFcsNjBnJWXUdrWJoPOcPUdHtvbRkX +3dorSXnH1Vs3FFd9tYv6WxZ9dVeFrpBEis7RPk7/WjLOiou8rS0i52o36NNn7Lxg +o0znk04af13Hn3Yu83lIi8CLLEe92xmWzrJKMNpWCQTPA02IeemrkYOFJ/TJ6Y2b +oh+X2XIk0bg/4dxM4w1FMq977OrYLBDnpDfJG9d0WPtMh/Q0UGAjuzCFnhuLHmm7 +VZPTU89MV9FS5emzdldqnmH6RCLg+EazrvQWMZiq5QKBgQDfARre0J8A3HkwxHCK +HQ+PQEvAlUneg/bL8CygT9M0eeZUVO+gtkAPP8Anr56venzVslf1ae4m0tvfd1wz +c57cs4Y58DquBAaN7VWPIOIKoJ9UMwAHssVYitW78KN7HG/AlqSPRKJz4jNG9lip +6pUDmL3bjtdsZQ3PTGWouc8UZwKBgQDGn3dRV7ChK7l70pn2JhYEeNnxYC3FHyAH +D8A2BZck1YNr1PacHQrzpvFpuxWPyDkmTA8jiAkyzNSz5POPvVm/fPg1GmqjK0tQ +F0re5U33E5m/gtcxk4W4U28uLBmYstjVl0j4oTzGtsFS2tHSgCF7k5AJzUo5Aewn +k4DG0SSrLQKBgQC4M/t0DTMpzPO2Gq0zCGov09Y+z5Hi4XJcZpkWGpnFAOQGyNnf +EGu9rNUWcvRK0oyHH/eT2dpD62x/G+LnBRw2BXxcI1j1IJIhbed8gJb2XFL/g9kE +guCMELIXud/v8z9D/6sSRIlD25ariRUX1ZMdE2/QCh9bg+VyVBKs2j55BQKBgQCK +24c2FeEE/CWDXFuIi13PKJHtPrkg2z6v0SImYkglVyO2qj7yKxex+V9C9KkBSRAz +Ju9afss3eZ2mWoSwU8c/qOV5cotkoWrYhkAwjgywlEJjcdxx61mL4MCUff4zE62l +vUsljsuHfNKw0wvnZu6Bj0senyeprR9lF6jq1eIVzQKBgENiD4HzP9nvMmtWM4x1 +dKVfSzmwuJaqPmThQJN4qeme007VpYtdEuFRvYdwMVQUlmWd69xyiTtBTIAHWqU5 +76i9P62RJBWTziTUSBsD+fyMQYqldnlufyPFQVqSsG2/XfBhHMlHSftqKMHQHgZY +ZFbspUmdTyd9URkmOEJLiUwU +-----END PRIVATE KEY----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/signer.p12 b/test/recipes/80-test_cmp_http_data/Mock/signer.p12 index 5bbb1e205f73f..1129062a62088 100644 Binary files a/test/recipes/80-test_cmp_http_data/Mock/signer.p12 and b/test/recipes/80-test_cmp_http_data/Mock/signer.p12 differ diff --git a/test/recipes/80-test_cmp_http_data/Mock/signer_issuing.crt b/test/recipes/80-test_cmp_http_data/Mock/signer_issuing.crt index 7734439f8c47c..d447cf62f1d22 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/signer_issuing.crt +++ b/test/recipes/80-test_cmp_http_data/Mock/signer_issuing.crt @@ -1,65 +1,38 @@ - Subject: O = openssl_cmp - Issuer: O = openssl_cmp -----BEGIN CERTIFICATE----- -MIICpTCCAY2gAwIBAgIBATANBgkqhkiG9w0BAQUFADAWMRQwEgYDVQQKDAtvcGVu -c3NsX2NtcDAeFw0xNzEyMjAxMzA0MDBaFw0xODEyMjAxMzA0MDBaMBYxFDASBgNV -BAoMC29wZW5zc2xfY21wMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA -4ckRrH0UWmIJFj99kBqvCipGjJRAaPkdvWjdDQLglTpI3eZAJHnq0ypW/PZccrWj -o7mxuvAStEYWF+5Jx6ZFmAsC1K0NNebSAZQoLWYZqiOzkfVVpLicMnItNFElfCoh -BzPCYmF5UlC5yp9PSUEfNwPJqDIRMtw+IlVUV3AJw9TJ3uuWq/vWW9r96/gBKKdd -mj/q2gGT8RC6LxEaolTbhfPbHaA1DFpv1WQFb3oAV3Wq14SOZf9bH1olBVsmBMsU -shFEw5MXVrNCv2moM4HtITMyjvZe7eIwHzSzf6dvQjERG6GvZ/i5KOhaqgJCnRKd -HHzijz9cLec5p9NSOuC1OwIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQDGUXpFCBkV -WgPrBfZyBwt6VCjWB/e67q4IdcKMfDa4hwSquah1AyXHI0PlC/qitnoSx2+7f7pY -TEOay/3eEPUl1J5tdPF2Vg56Dw8jdhSkMwO7bXKDEE3R6o6jaa4ECgxwQtdGHmNU -A41PgKX76yEXku803ptO39/UR7i7Ye3MbyAmWE+PvixJYUbxd3fqz5fsaJqTCzAy -AT9hrr4uu8J7m3LYaYXo4LVL4jw5UsP5bIYtpmmEBfy9GhpUqH5/LzBNij7y3ziE -T59wHkzawAQDHsBPuCe07DFtlzqWWvaih0TQAw9MZ2tbyK9jt7P80Rqt9CwpM/i9 -jQYqSl/ix5hn +MIIDEjCCAfqgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAZMRcwFQYDVQQDDA5zaWdu +ZXItaW50ZXJDQTAgFw0yNjA4MjcxMzAyMThaGA8yMTI2MDgyODEzMDIxOFowHDEa +MBgGA1UEAwwRc2lnbmVyLXN1YmludGVyQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDVtUxlSXhn0YEKL1kcHdGWxhZfrFfKc9/bc/h+gX9DLjUviYgy +WfKPVPMDwek9FyaPhwuevDHnbhJ998PZwPhZGUVooE7E/0Ws9gdrkwiCekYDwrkV ++FcF7Z8y42kem4epConTKez9zsK9kks1gO/c0UYG8p4IW4IP0dCPG+hWx5TdxAOC +gBUEft9DY93Hw5sZCzkNHBgdCg9CtDfxKhlSmsomZUj0WRVnMlz7KxnOmcnOLYex +OaWQbaxGVPj88jnFCprDwcl41wod/FCQ2FBi5EgU6i+OS+kXua3Yf0BqzBa6Bt39 +T6n+SoJSKxj4MJtanXcZ42VnztFuvc9zbRs7AgMBAAGjYDBeMA8GA1UdEwEB/wQF +MAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTBLcMazlMMaD5Qi0604+IDUwOc +dTAfBgNVHSMEGDAWgBTsiAttQK5AyZloxjLpJLX3YYxcDDANBgkqhkiG9w0BAQsF +AAOCAQEASRQKe65V4miLNvyU0jK2UoHCoguA3faWKEyQfnD61nEQ6f5/w35c5AVP +nVZRgk+ADt0bRCpQpstAw8fl1IMGgjrtMReHr70ToLtKEpRbwBgNPa9fDCl27zG7 +pfAY+RTcZMp2eJDfOY0VAKAP4kO/of6Mg18hClJ6JONTyGNP5M7hHlKbwJDhVEUI ++T7C7QzlvS0WdiI/aaSm5hrTpz7W7gRhU/PNIssxj++72eNlyLxMSLLSXLbi2SnL +v9gb7traRUMXuI/qCWkFxMP6xm3kMg+++hqlWpqtrSK+4jbwbvnlSO75KYgxR8Qm +B8/0Fc0HcrlPxqKcz7XOHfNtbAWOcg== -----END CERTIFICATE----- - -Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = subinterCA -----BEGIN CERTIFICATE----- -MIIDhDCCAmygAwIBAgIJAJkv2OGshkmUMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMTB2ludGVyQ0EwHhcNMTUwNzAyMTMxODIz -WhcNMzUwNzAyMTMxODIzWjBaMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1T -dGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRMwEQYDVQQD -EwpzdWJpbnRlckNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/zQj -vhbU7RWDsRaEkVUBZWR/PqZ49GoE9p3OyRN4pkt1c1yb2ARVkYZP5e9gHb04wPVz -2+FYy+2mNkl+uAZbcK5w5fWO3WJIEn57he4MkWu3ew1nJeSv3na8gyOoCheG64kW -VbA2YL92mR7QoSCo4SP7RmykLrwj6TlDxqgH6DxKSD/CpdCHE3DKAzAiri3GVc90 -OJAszYHlje4/maVIOayGROVET3xa5cbtRJl8IBgmqhMywtz4hhY/XZTvdEn290aL -857Hk7JjogA7mLKi07yKzknMxHV+k6JX7xJEttkcNQRFHONWZG1T4mRY1Drh6VbJ -Gb+0GNIldNLQqigkfwIDAQABo1AwTjAMBgNVHRMEBTADAQH/MB0GA1UdDgQWBBTp -Z30QdMGarrhMPwk+HHAV3R8aTzAfBgNVHSMEGDAWgBQY+tYjuY9dXRN9Po+okcfZ -YcAXLjANBgkqhkiG9w0BAQsFAAOCAQEAgVUsOf9rdHlQDw4clP8GMY7QahfXbvd8 -8o++P18KeInQXH6+sCg0axZXzhOmKwn+Ina3EsOP7xk4aKIYwJ4A1xBuT7fKxquQ -pbJyjkEBsNRVLC9t4gOA0FC791v5bOCZjyff5uN+hy8r0828nVxha6CKLqwrPd+E -mC7DtilSZIgO2vwbTBL6ifmw9n1dd/Bl8Wdjnl7YJqTIf0Ozc2SZSMRUq9ryn4Wq -YrjRl8NwioGb1LfjEJ0wJi2ngL3IgaN94qmDn10OJs8hlsufwP1n+Bca3fsl0m5U -gUMG+CXxbF0kdCKZ9kQb1MJE4vOk6zfyBGQndmQnxHjt5botI/xpXg== ------END CERTIFICATE----- - -Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = interCA ------BEGIN CERTIFICATE----- -MIIDgDCCAmigAwIBAgIJANnoWlLlEsTgMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnJvb3RDQTAeFw0xNTA3MDIxMzE3MDVa -Fw0zNTA3MDIxMzE3MDVaMFcxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 -YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxEDAOBgNVBAMT -B2ludGVyQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC7s0ejvpQO -nvfwD+e4R+9WQovtrsqOTw8khiREqi5JlmAFbpDEFam18npRkt6gOcGMnjuFzuz6 -iEuQmeeyh0BqWAwpMgWMMteEzLOAaqkEl//J2+WgRbA/8pmwHfbPW/d+f3bp64Fo -D1hQAenBzXmLxVohEQ9BA+xEDRkL/cA3Y+k/O1C9ORhSQrJNsB9aE3zKbFHd9mOm -H4aNSsF8On3SqlRVOCQine5c6ACSd0HUEjYy9aObqY47ySNULbzVq5y6VOjMs0W+ -2G/XqrcVkxzf9bVqyVBrrAJrnb35/y/iK0zWgJBP+HXhwr5mMTvNuEirBeVYuz+6 -hUerUbuJhr0FAgMBAAGjUDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFBj61iO5 -j11dE30+j6iRx9lhwBcuMB8GA1UdIwQYMBaAFIVWiTXinwAa4YYDC0uvdhJrM239 -MA0GCSqGSIb3DQEBCwUAA4IBAQDAU0MvL/yZpmibhxUsoSsa97UJbejn5IbxpPzZ -4WHw8lsoUGs12ZHzQJ9LxkZVeuccFXy9yFEHW56GTlkBmD2qrddlmQCfQ3m8jtZ9 -Hh5feKAyrqfmfsWF5QPjAmdj/MFdq+yMJVosDftkmUmaBHjzbvbcq1sWh/6drH8U -7pdYRpfeEY8dHSU6FHwVN/H8VaBB7vYYc2wXwtk8On7z2ocIVHn9RPkcLwmwJjb/ -e4jmcYiyZev22KXQudeHc4w6crWiEFkVspomn5PqDmza3rkdB3baXFVZ6sd23ufU -wjkiKKtwRBwU+5tCCagQZoeQ5dZXQThkiH2XEIOCOLxyD/tb +MIIDDjCCAfagAwIBAgIBAjANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1zaWdu +ZXItcm9vdENBMCAXDTI2MDgyNzEzMDIxOFoYDzIxMjYwODI4MTMwMjE4WjAZMRcw +FQYDVQQDDA5zaWduZXItaW50ZXJDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALfzO3Ys1oIQJNE2fZZjgiIZO3v2FbvxDt28ggZUaIpjttrxSaWM4bDV +PC0v8oz1pCrrQf9q6bztT+4BYR+hqNw7o1E6SY5dFdz/RweO320QfjExJzAu2K6K +5vC+NH6P2plkT90do3Zri0M6tBDGg8pBzPNyXvBrlLwzwRETLhvf10qiMkzrdnYe +GOW/lVRMfvxlHsuu+CTdPwOTz6qdnShBBdACr6xee8rjK67Gv/R4yzyS16ncDjR3 +ziMjYxn6+4qS/zptS0TUQfPUQ6RXvfK81cVQetyC3MU8QNB5kIT5cEoW35GV9+o5 +tZSnOcdkZR51lXEhAJtqgJsIQ1B+f8cCAwEAAaNgMF4wDwYDVR0TAQH/BAUwAwEB +/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFOyIC21ArkDJmWjGMukktfdhjFwMMB8G +A1UdIwQYMBaAFKANU13Cnnn6m0p77DChVm5KkBbGMA0GCSqGSIb3DQEBCwUAA4IB +AQBCjFFpMSfNBAU9QppyYGoWwjixegxmHOE8EzKVocxLXDee23EX1ANX1l5EkcgR +bhYuL7Kr2SrMFbdGnSDuUpuSKP+KiYZsGyP/RAz7ST8FrlzQI4WZ+TzbLj5hYojk +Oh4Z/yQcfrIjO740p5MUDLQThHO2cnK9f+aYZSb4b+Ehu4MPlmTsgV2WfD9lgOhE ++zrCST26a59M3kdkDvsfJqJADVDSN9EqhAGKJ19SC/grGfEzcT3ABZFa4r0ssixu +PIhUwlTW78gXt6Yg0XuvuoafI6W2x2zogqKN9QNgx31VJHXV+SNbz2toXHLPXKb9 +TPbbQ7/he/c0/zxKZ6WeiSEW -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/signer_only.crt b/test/recipes/80-test_cmp_http_data/Mock/signer_only.crt index bb94d126e93f5..7d1185500e23e 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/signer_only.crt +++ b/test/recipes/80-test_cmp_http_data/Mock/signer_only.crt @@ -1,21 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDfjCCAmagAwIBAgIJAKRNsDKacUqNMA0GCSqGSIb3DQEBCwUAMFoxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxEzARBgNVBAMTCnN1YmludGVyQ0EwHhcNMTUwNzAyMTMx -OTQ5WhcNMzUwNzAyMTMxOTQ5WjBUMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29t -ZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQ0wCwYD -VQQDEwRsZWFmMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv0Qo9WC/ -BKA70LtQJdwVGSXqr9dut3cQmiFzTb/SaWldjOT1sRNDFxSzdTJjU/8cIDEZvaTI -wRxP/dtVQLjc+4jzrUwz93NuZYlsEWUEUg4Lrnfs0Nz50yHk4rJhVxWjb8Ii/wRB -ViWHFExP7CwTkXiTclC1bCqTuWkjxF3thTfTsttRyY7qNkz2JpNx0guD8v4otQoY -jA5AEZvK4IXLwOwxol5xBTMvIrvvff2kkh+c7OC2QVbUTow/oppjqIKCx2maNHCt -LFTJELf3fwtRJLJsy4fKGP0/6kpZc8Sp88WK4B4FauF9IV1CmoAJUC1vJxhagHIK -fVtFjUWs8GPobQIDAQABo00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBQcHcT+8SVG -IRlN9YTuM9rlz7UZfzAfBgNVHSMEGDAWgBTpZ30QdMGarrhMPwk+HHAV3R8aTzAN -BgkqhkiG9w0BAQsFAAOCAQEAGjmSkF8is+v0/RLcnSRiCXENz+yNi4pFCAt6dOtT -6Gtpqa1tY5It9lVppfWb26JrygMIzOr/fB0r1Q7FtZ/7Ft3P6IXVdk3GDO0QsORD -2dRAejhYpc5c7joHxAw9oRfKrEqE+ihVPUTcfcIuBaalvuhkpQRmKP71ws5DVzOw -QhnMd0TtIrbKHaNQ4kNsmSY5fQolwB0LtNfTus7OEFdcZWhOXrWImKXN9jewPKdV -mSG34NfXOnA6qx0eQg06z+TkdrptH6j1Va2vS1/bL+h1GxjpTHlvTGaZYxaloIjw -y/EzY5jygRoABnR3eBm15CYZwwKL9izIq1H3OhymEi/Ycg== +MIIDKTCCAhGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFzaWdu +ZXItc3ViaW50ZXJDQTAgFw0yNjA4MjcxMzAyMTlaGA8yMTI2MDgyODEzMDIxOVow +FjEUMBIGA1UEAwwLc2lnbmVyLWxlYWYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQCtBcRoZPjeL/Ufg/WTaqLp8JAtc5d/+VHepTPMWuiBRPHfnVcuFIw8 +zXg5VMGgYQrGORfzGEqYUFifJgP1CFA7QQbdx+rYMweLj8H/M28838tM2nh3SSxJ +28SEcN0hHqBD5Asb0jqhlKvDoRLA0Wlh+AuSTy9qSgGZDCpCOhEHTM7/Tlgfo1lp +an+2I/HspvlnfSPwOtVLTI0FTmVeqTSaLjEubFhJXHbcfCzU4Uo69N5rNnWHNn+B +qD0xQSTZMM6uijN0m75Z5x++46V9ePFTqKnApZb+qDE07/ywnC+yQ0dIcmUnWnKE +/qB/TEe80rObcxkwyML0AixECzbxg2MbAgMBAAGjejB4MB0GA1UdDgQWBBTfXRko +n4RzVx7JubTWpN0NsB1Y9jAfBgNVHSMEGDAWgBTBLcMazlMMaD5Qi0604+IDUwOc +dTAJBgNVHRMEAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMCMBYGA1UdEQQPMA2CC3Np +Z25lci1sZWFmMA0GCSqGSIb3DQEBCwUAA4IBAQC4gRs9nILUGjNciLmY6+iyhoEy +pjDXAsNqKfCmtQXbh7lVZN1fgXlcVIjZp1DWaR/ie6h5+jt5fc2rIbocQQV8xcDd +LN1IsculUoe9ipyZz8miWyPfYRT5fclko7RH2ndkimJg3r2gF8szeoq87QjTyfez +T/Um3RRfniTlaEGVuy2628q9VbN+ZBvKkPhIXbDMzUW7rcZDSBX5qmrmcusJDrRr +fTCVwXdrCJjI6ozyDc459Zi7s6aGiZWexgNu85Nai8udujdy9dHWtcCbqLcEMD0l +IfIeKIyu7QmVvuO/GO1op0v4i4Betd+sRJSzasvpapi9cdLfDIDiLrZ+f9SC -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/signer_root.crt b/test/recipes/80-test_cmp_http_data/Mock/signer_root.crt index 30fb8317e4b4e..37eb5dc4fbbc2 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/signer_root.crt +++ b/test/recipes/80-test_cmp_http_data/Mock/signer_root.crt @@ -1,22 +1,18 @@ -Subject: C = AU, ST = Some-State, O = Internet Widgits Pty Ltd, CN = rootCA -----BEGIN CERTIFICATE----- -MIIDfzCCAmegAwIBAgIJAIhDKcvC6xWaMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX -aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMMBnJvb3RDQTAeFw0xNTA3MDIxMzE1MTFa -Fw0zNTA3MDIxMzE1MTFaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0 -YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMM -BnJvb3RDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMDxa3eIrDXf -+3NTL5KAL3QWMk31ECBvbDqO0dxr4S4+wwQPv5vEyRLR5AtFl+UGzWY64eDiK9+i -xOx70z08iv9edKCrpwNqFlteksR+W3mKadS8g16uQpJ0pSvnAMGp3NWxUwcPc/eO -rRQ+JZ7lHubMkc2VDIBEIMP9F8+RPWMQHBRb+8OowYiyd/+c2/xqRERE94XsCCzU -34Gjecn+HpuTFlO3l6u+Txql4vpGBeQNnCqkzLkeIaBsxKtZsEA5u/mIrf3fjbQL -r35B4CE8yDNFSYQvkwbu/U/tT/O8m978JV5V1XXUxXs6QDUGn8SEtGyTDK83Wq+2 -QU0mIxy4ArMCAwEAAaNQME4wDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUhVaJNeKf -ABrhhgMLS692Emszbf0wHwYDVR0jBBgwFoAUhVaJNeKfABrhhgMLS692Emszbf0w -DQYJKoZIhvcNAQELBQADggEBADIKvyoK4rtPQ86I2lo5EDeAuzctXi2I3SZpnOe0 -mCCxJeZhWW0S7JuHvlfhEgXFBPEXzhS4HJLUlZUsWyiJ+3KcINMygaiF7MgIe6hZ -WzpsMatS4mbNFElc89M+YryRFrQc9d1Uqjxhl3ms5MhDNcMP/PNwHa/wnIoqkpNI -qtDoR741wcZ7bdr6XVdF8+pBjzbBPPRSf24x3bqavHBWcTjcSVcM/ZEXxeqH5SN0 -GbK2mQxrogX4UWjtl+DfYvl+ejpEcYNXKEmIabUUHtpG42544cuPtZizLW5bt/aT -JBQfpPZpvf9MUlACxUONFOLQdZ8SXpSJ0e93iX2J2Z52mSQ= +MIIC7DCCAdSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1zaWdu +ZXItcm9vdENBMCAXDTI2MDgyNzEzMDIxOFoYDzIxMjYwODI4MTMwMjE4WjAYMRYw +FAYDVQQDDA1zaWduZXItcm9vdENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEArdsEEsPAXwKehceBZcTN0zd8+Qhv+HWqNHOXNlKX4Rwm5/Ph42ICuzVO +K0KbJSwPNLb5zttGw3rZ/r+oKHCXAiepKtAcou1W7UFRbFPDmmWPJB4WwHVv6I1Z +Fu/wFid4Dx1LXwOQ7QWENc/OwJbtnvN9X5/kiKkhEaqIbElQqeelA+Gw8uPdRg9s +5pTKN82knc86GgRxniS7ofqxhy3sDDCQJ9sC86fPYsqVZ21OH/adAkJ48TexgLIh +L1zdK+hfj09etmCVPbb9iLhP/z4x1glqOitIdnxkOmoe3ZigSKZwZyZsRlPd6msD +ZCS/EPkxOZyQRoRms1ilfe0i8U5xZwIDAQABoz8wPTAPBgNVHRMBAf8EBTADAQH/ +MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUoA1TXcKeefqbSnvsMKFWbkqQFsYwDQYJ +KoZIhvcNAQELBQADggEBAEuK74uzhJtAPJM31CKMZjBgfkxHheudb2jcPBiHQha7 +q+t3riQehGozWPwhMRBNaGTiJG7FTGjCp5lqrkQ9lUBkUqCy5mlTq9jR2ETK18Sf +N7vwaZ3rhnK99N/gL0SdRpuG/ed7WKTvveFSLhBwkHqijtY28uWvhanwboI3gObd +CU2OSd3umKuC/svf1S7p6py/t55dkljK2tcaLSDHVn+9ytqEGGOE96wJe35c5848 ++TWUqyMmvnvgiySq9zzu5XsHSTxHBwJUMds8Uu134MAhqkgY+xMSgqlq48uY0Ac0 +cDXn7ep55qVhu+ktX2JMuZsvXq2rrZbXyuRIy4GkJwM= -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/Mock/trusted.crt b/test/recipes/80-test_cmp_http_data/Mock/trusted.crt index 23406e998d8c4..067daf21e8e41 100644 --- a/test/recipes/80-test_cmp_http_data/Mock/trusted.crt +++ b/test/recipes/80-test_cmp_http_data/Mock/trusted.crt @@ -1,23 +1,18 @@ - Issuer: CN=Root CA - Validity - Not Before: Jan 14 22:29:05 2016 GMT - Not After : Jan 15 22:29:05 2116 GMT - Subject: CN=Root CA -----BEGIN CERTIFICATE----- -MIIC8TCCAdmgAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290 -IENBMCAXDTE2MDExNDIyMjkwNVoYDzIxMTYwMTE1MjIyOTA1WjASMRAwDgYDVQQD -DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv5oV1s3N -us7SINg7omu5AxueEgK97mh5PU3hgZpliSFaESmL2qLGeP609oXs/68XDXVW4utU -LCOjLh0np+5Xy3i3GRDXgBZ72QDe23WqqQqqaBlQVVm1WxG+amRtZJEWdSIsiFBt -k+8dBElHh2WQDhDOWqHGHQarQgJPxGB97MRhMSlbTwK1T5KAWOlqi5mJW5L6vNrQ -7Tra/YceH70fU0fJYOXhBxM92NwD1bbVd9GPYFSqrdrVj19bvo63XsxZduex5QHr -RkWqT5w5mgAHaEgCqWrS/64q9TR9UEwrB8kiZZg3k9/im+zBwEULTZu0r8oMEkpj -bTlXLmt8EMBqxwIDAQABo1AwTjAdBgNVHQ4EFgQUcH8uroNoWZgEIyrN6z4XzSTd -AUkwHwYDVR0jBBgwFoAUcH8uroNoWZgEIyrN6z4XzSTdAUkwDAYDVR0TBAUwAwEB -/zANBgkqhkiG9w0BAQsFAAOCAQEAuiLq2lhcOJHrwUP0txbHk2vy6rmGTPxqmcCo -CUQFZ3KrvUQM+rtRqqQ0+LzU4wSTFogBz9KSMfT03gPegY3b/7L2TOaMmUFRzTdd -c9PNT0lP8V3pNQrxp0IjKir791QkGe2Ux45iMKf/SXpeTWASp4zeMiD6/LXFzzaK -BfNS5IrIWRDev41lFasDzudK5/kmVaMvDOFyW51KkKkqb64VS4UA81JIEzClvz+3 -Vp3k1AXup5+XnTvhqu2nRhrLpJR5w8OXQpcn6qjKlVc2BXtb3xwci1/ibHlZy3CZ -n70e2NYihU5yYKccReP+fjLgVFsuhsDs/0hRML1u9bLp9nUbYA== +MIIC4DCCAcigAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290 +IENBMCAXDTI2MDgyNzEzMDIxMloYDzIxMjYwODI4MTMwMjEyWjASMRAwDgYDVQQD +DAdSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArlOeoe+t +UrcFZls2dx8ohAIIIQe5FH68yYIisi5tzv7NsDJYLwCu3/r2BLgXKj/E9Ivrzq9p +rWGwIS1JO4Kr/PV4lb+j9VORzdzVMN8Fw8/uKmK6RvQkIQLJRIvC3uzTkQBnD83f +Q8XlcYXOX2wiQj/6ze0eLbTuwWb3dooLdycAGLWg2EdqKB15KfrsprkRfhvxBSXK +3mkLXXH8WB29uQQPoZeARyCDJIx9DSKzeeHtudfwWnI4pCs9HMzVznERj4fm9wPX +iER/exgJjEih7Nif3SJTcIT48ypf67D0wap7z7eyUroBB22l08beizL0XuYTHlMD +s6z/tsXqliq4MQIDAQABoz8wPTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIB +BjAdBgNVHQ4EFgQUroGrfFZGWmyeytjSbmFAHsIgx8EwDQYJKoZIhvcNAQELBQAD +ggEBAEzx/3RhfaGHKZvitVY+gTuRrcIjxp5oyNAXwThSrAf5M/h7C3VN9calDBwf +NBdjruQjf+0UotoAf5vo/xgQO3mI5H4vkb7UlvQ5xVb4KGL4O9xNgZisTv/kgpGv +L09bOQOSIQtb/bUF90jZBnH++L40ZzOeDCPkYFTpDvoE7sB3vyaDDjD8s9PzH5Iu +yK+KvlrKJ+Y8ptFhgQmkhgIfNCG6E6laeVgmokbEDdBGUrsjq1S/pTuY6FxFdHS4 +Ifn1L9YTlqiaVzJaH3jgVk1komVmKgw20CQZl+tcSxzpez1R1h35r+kDj6F4Lj38 +1aRHVCZrZP6mq/YntYou/m7eXGo= -----END CERTIFICATE----- diff --git a/test/recipes/80-test_cmp_http_data/test_commands.csv b/test/recipes/80-test_cmp_http_data/test_commands.csv index 9e77baa4b127b..785d5d7da6e95 100644 --- a/test/recipes/80-test_cmp_http_data/test_commands.csv +++ b/test/recipes/80-test_cmp_http_data/test_commands.csv @@ -45,14 +45,14 @@ expected,description, -section,val, -cmd,val,val2, -cacertsout,val,val2, -infoty 0,revreason out of integer range, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,_RESULT_DIR/test.cert.pem, -revreason,010000000000000000000 1,use csr for revocation, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,, -revreason,0, -csr,csr.pem 1, --- get certificate for revocation ----, -section,, -cmd,cr,,BLANK,,,BLANK,,,BLANK,,BLANK, -1,use issuer and serial for revocation, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,, -revreason,-1,BLANK,,, -expect_sender,"""",-issuer,/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=subinterCA,-serial,0xA44DB0329A714A8D +1,use issuer and serial for revocation, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,, -revreason,-1,BLANK,,, -expect_sender,"""",-issuer, _CERT_ISSUER, -serial, _CERT_SERIAL 1, --- get certificate for revocation ----, -section,, -cmd,cr,,BLANK,,,BLANK,,,BLANK,,BLANK, -0,use issuer but no serial for revocation, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,, -revreason,-1,BLANK,,, -expect_sender,"""",-issuer,/C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=subinterCA,BLANK, -0,use serial but no issuer for revocation, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,, -revreason,-1,BLANK,,, -expect_sender,"""", -issuer, """", -serial, 0xA44DB0329A714A8D -0,wrong issuer for revocation, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,, -revreason,-1,BLANK,,, -expect_sender,"""", -issuer, /C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=wrongCA, -serial, 0xA44DB0329A714A8D -0,bad issuer DN for revocation, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,, -revreason,-1,BLANK,,, -expect_sender,"""", -issuer, "'XYZ'", -serial, 0xA44DB0329A714A8D -0,wrong serial for revocation, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,, -revreason,-1,BLANK,,, -expect_sender,"""", -issuer, /C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=subinterCA, -serial, 0xA44DB0329A714A00 -0,bad serial for revocation, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,, -revreason,-1,BLANK,,, -expect_sender,"""", -issuer, /C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=subinterCA, -serial, xyz +0,use issuer but no serial for revocation, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,, -revreason,-1,BLANK,,, -expect_sender,"""",-issuer, _CERT_ISSUER,BLANK, +0,use serial but no issuer for revocation, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,, -revreason,-1,BLANK,,, -expect_sender,"""", -issuer, """", -serial, _CERT_SERIAL +0,wrong issuer for revocation, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,, -revreason,-1,BLANK,,, -expect_sender,"""", -issuer, /C=AU/ST=Some-State/O=Internet Widgits Pty Ltd/CN=wrongCA, -serial, _CERT_SERIAL +0,bad issuer DN for revocation, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,, -revreason,-1,BLANK,,, -expect_sender,"""", -issuer, "'XYZ'", -serial, _CERT_SERIAL +0,wrong serial for revocation, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,, -revreason,-1,BLANK,,, -expect_sender,"""", -issuer, _CERT_ISSUER, -serial, 0xA44DB0329A714A00 +0,bad serial for revocation, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,, -revreason,-1,BLANK,,, -expect_sender,"""", -issuer, _CERT_ISSUER, -serial, xyz 0,rr without oldcert/csr/issuer/serial, -section,, -cmd,rr,,BLANK,,,BLANK,,,BLANK,,BLANK, 0,rr with oldcert file nonexistent, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,idontexist,BLANK, 0,rr with empty oldcert file, -section,, -cmd,rr,,BLANK,,,BLANK,,, -oldcert,empty.txt,BLANK, diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t index 7516cf024ef6a..634ddbb6e3f74 100644 --- a/test/recipes/80-test_cms.t +++ b/test/recipes/80-test_cms.t @@ -13,7 +13,7 @@ use warnings; use POSIX; use File::Spec::Functions qw/catfile/; use File::Compare qw/compare_text compare/; -use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir bldtop_file with data_file/; +use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir bldtop_file with data_file slurp_file/; use OpenSSL::Test::Utils; @@ -56,9 +56,10 @@ my ($no_des, $no_dh, $no_dsa, $no_ec, $no_ec2m, $no_rc2, $no_zlib) $no_rc2 = 1 if disabled("legacy"); -plan tests => 40; +plan tests => 43; -ok(run(test(["pkcs7_test"])), "test pkcs7"); +ok(run(test(["pkcs7_test", srctop_file("test", "certs", "servercert.pem"), + srctop_file("test", "certs", "serverkey.pem")])), "test pkcs7"); unless ($no_fips) { my $provconf = srctop_file("test", "fips-and-base.cnf"); @@ -1069,6 +1070,67 @@ subtest "CMS decrypt authEnvelopedData with authenticated attributes\n" => sub { "tampered authEnvelopedData leaks no plaintext to -out"); }; +subtest "CMS parse authenticatedData authAttrs and unauthAttrs\n" => sub { + plan tests => 3; + + # BouncyCastle authenticatedData (HMAC-SHA256, KEK) carrying both an + # authenticated and an unauthenticated attribute. Per RFC 5652 these are + # SET OF Attribute, so with the CMS_AuthenticatedData template fixed to use + # X509_ATTRIBUTE they are rendered as attributes (object:/set:) rather than + # as an X509_ALGOR (algorithm:/parameter:) they were misparsed into before. + my $exit = 0; + my $dump = join "\n", + run(app(["openssl", "cms", @defaultprov, "-cmsout", "-noout", + "-print", "-inform", "PEM", + "-in", catfile($datadir, "authenticated_attrs.pem")]), + capture => 1, + statusvar => $exit); + + is($exit, 0, "parse authenticatedData with attributes"); + ok($dump =~ /authAttrs:.*?object:.*?1\.3\.6\.1\.4\.1\.5949\.99\.1.*?UTF8STRING:auth-attr-value/s, + "authAttrs parsed as SET OF Attribute"); + ok($dump =~ /unauthAttrs:.*?object:.*?1\.3\.6\.1\.4\.1\.5949\.99\.2.*?UTF8STRING:unauth-attr-value/s, + "unauthAttrs parsed as SET OF Attribute"); +}; + +# Replace all occurrences of a DER encoded OID in a file +sub replace_der_oid { + my ($file, $from_hex, $to_hex) = @_; + my $from = pack("H*", $from_hex); + my $to = pack("H*", $to_hex); + my $der = slurp_file($file, binary => 1); + + $der =~ s/\Q$from\E/$to/g; + open(my $fh, ">", $file) or die "Cannot write $file: $!"; + binmode $fh; + print $fh $der; + close($fh); +} + +subtest "reject signature algorithm OID as digestAlgorithm\n" => sub { + plan tests => 8; + + foreach my $app ("cms", "smime") { + foreach my $attrs ("attrs", "noattr") { + my @noattr = $attrs eq "noattr" ? ("-noattr") : (); + my $sig = "digalg-$app-$attrs.der"; + + ok(run(app(["openssl", $app, @defaultprov, "-sign", "-in", $smcont, + "-outform", "DER", "-nodetach", "-md", "sha256", + @noattr, "-signer", $smrsa1, "-out", $sig])), + "sign ($app, $attrs)"); + + # Replace the sha256 OID with sha256WithRSAEncryption + replace_der_oid($sig, "608648016503040201", "2a864886f70d01010b"); + + ok(!run(app(["openssl", $app, @defaultprov, "-verify", "-noverify", + "-in", $sig, "-inform", "DER", + "-out", "$sig.txt"])), + "must not verify with signature algorithm OID ($app, $attrs)"); + } + } +}; + subtest "CAdES <=> CAdES consistency tests\n" => sub { plan tests => (scalar @smime_cms_cades_tests); @@ -1787,3 +1849,79 @@ subtest "PWRI missing keyDerivationAlgorithm regression" => sub { }); }; +subtest "sign and verify with multiple keys and -verify_partial" => sub { + plan tests => 9; + + my $smrsa2 = catfile($smdir, "smrsa2.pem"); + my $sig1 = "sig1.cms"; + my $out1 = "out1.txt"; + my $sig2 = "sig2.cms"; + my $out2 = "out2.txt"; + + ok(run(app(['openssl', 'cms', + @defaultprov, + '-sign', '-in', $smcont, + '-nodetach', + '-signer', $smrsa1, + '-out', $sig1, '-outform', 'DER', + ])), + "sign with first key"); + ok(run(app(['openssl', 'cms', + @defaultprov, + '-verify', '-in', $sig1, '-inform', 'DER', + '-CAfile', $smrsa1, '-partial_chain', + '-verify_partial', + '-out', $out1, + ])), + "verify single signature"); + is(compare($smcont, $out1), 0, "compare original message with verified message"); + + # because the smrsa2 signature cannot be verified, overall verification fails + ok(!run(app(['openssl', 'cms', + @defaultprov, + '-verify', '-in', $sig1, '-inform', 'DER', + '-CAfile', $smrsa2, '-partial_chain', + '-verify_partial', + '-out', $out2, + ])), + "try to verify rsa1 signature with only rsa2"); + + ok(run(app(['openssl', 'cms', + @defaultprov, + '-resign', '-in', $sig1, '-inform', 'DER', + '-signer', $smrsa2, + '-out', $sig2, '-outform', 'DER', + ])), + "resign with second key"); + + # because the smrsa1 signature can be verified, overall verification succeeds + ok(run(app(['openssl', 'cms', + @defaultprov, + '-verify', '-in', $sig2, '-inform', 'DER', + '-CAfile', $smrsa1, '-partial_chain', + '-verify_partial', + '-out', $out2, + ])), + "verify two signatures with only rsa1"); + + # because the smrsa2 signature can be verified, overall verification succeeds + ok(run(app(['openssl', 'cms', + @defaultprov, + '-verify', '-in', $sig2, '-inform', 'DER', + '-CAfile', $smrsa2, '-partial_chain', + '-verify_partial', + '-out', $out2, + ])), + "verify two signatures with only rsa2"); + + # because both signatures can be verified, overall verification succeeds + ok(run(app(['openssl', 'cms', + @defaultprov, + '-verify', '-in', $sig2, '-inform', 'DER', + '-CAfile', $smroot, + '-verify_partial', + '-out', $out2, + ])), + "verify both signature signatures with root"); + is(compare($smcont, $out2), 0, "compare original message with verified message"); +}; diff --git a/test/recipes/80-test_cms_data/authenticated_attrs.pem b/test/recipes/80-test_cms_data/authenticated_attrs.pem new file mode 100644 index 0000000000000..4f3d212698011 --- /dev/null +++ b/test/recipes/80-test_cms_data/authenticated_attrs.pem @@ -0,0 +1,8 @@ +-----BEGIN CMS----- +MIAGCyqGSIb3DQEJEAECoIAwgAIBADFDokECAQQwBQQDwP7gMAsGCWCGSAFlAwQB +BQQoWM396pUOzWW6mFsNvr+XXTLufCrvzG3jiTOX+l3LpSXbXHhhpadw5DAMBggq +hkiG9w0CCQUAoQsGCWCGSAFlAwQCATCABgkqhkiG9w0BBwGggCSABB5IZWxsbyBB +dXRoZW50aWNhdGVkRGF0YSB3b3JsZAoAAAAAAACiIDAeBgkrBgEEAa49YwExEQwP +YXV0aC1hdHRyLXZhbHVlBCB9kCl8ic3e5461oodeDSyR7heZxtdN7G/N+oqerDIj +PqMiMCAGCSsGAQQBrj1jAjETDBF1bmF1dGgtYXR0ci12YWx1ZQAAAAAAAA== +-----END CMS----- diff --git a/test/recipes/80-test_cmsapi.t b/test/recipes/80-test_cmsapi.t index 3d1dae8464646..adfa8d51f5862 100644 --- a/test/recipes/80-test_cmsapi.t +++ b/test/recipes/80-test_cmsapi.t @@ -16,9 +16,18 @@ plan skip_all => "CMS is disabled in this build" if disabled("cms"); plan tests => 1; +my @ed448_args = disabled("ecx") ? () : ( + srctop_file("test", "certs", "server-ed448-cert.pem"), + srctop_file("test", "certs", "server-ed448-key.pem")); + ok(run(test(["cmsapitest", srctop_file("test", "certs", "servercert.pem"), srctop_file("test", "certs", "serverkey.pem"), srctop_file("test", "recipes", "80-test_cmsapi_data", "encryptedData.der"), srctop_file("test", "recipes", "80-test_cmsapi_data", "encDataWithTooLongIV.pem"), - srctop_file("test", "recipes", "80-test_cmsapi_data", "cms_pwri_kek_oob.der")])), + srctop_file("test", "recipes", "80-test_cmsapi_data", "cms_pwri_kek_oob.der"), + srctop_file("test", "recipes", "80-test_cmsapi_data", "cms_pwri_kek_NoIV.der"), + srctop_file("test", "smime-certs", "smec1.pem"), + srctop_file("test", "certs", "alt1-cert.pem"), + srctop_file("test", "certs", "alt1-key.pem"), + @ed448_args])), "running cmsapitest"); diff --git a/test/recipes/80-test_cmsapi_data/cms_pwri_kek_NoIV.der b/test/recipes/80-test_cmsapi_data/cms_pwri_kek_NoIV.der new file mode 100644 index 0000000000000..c3ef3abd10e6b Binary files /dev/null and b/test/recipes/80-test_cmsapi_data/cms_pwri_kek_NoIV.der differ diff --git a/test/recipes/80-test_cmsapi_data/cms_pwri_kek_oob.der b/test/recipes/80-test_cmsapi_data/cms_pwri_kek_oob.der index c3ef3abd10e6b..5e7302d0fad70 100644 Binary files a/test/recipes/80-test_cmsapi_data/cms_pwri_kek_oob.der and b/test/recipes/80-test_cmsapi_data/cms_pwri_kek_oob.der differ diff --git a/test/recipes/80-test_dtls_ccs_reorder.t b/test/recipes/80-test_dtls_ccs_reorder.t index 3c703afc34a39..b6ac263286558 100755 --- a/test/recipes/80-test_dtls_ccs_reorder.t +++ b/test/recipes/80-test_dtls_ccs_reorder.t @@ -18,6 +18,9 @@ setup("test_dtls_ccs_reorder"); plan skip_all => "No DTLS protocols are supported" if alldisabled(available_protocols("dtls")); +plan skip_all => "No DTLS 1.2 or 1.0 support in this OpenSSL build" + if disabled("dtls1_2") && disabled("dtls1"); + plan tests => 1; ok(run(test(["dtls_ccs_reorder_test", diff --git a/test/recipes/80-test_dtls_mtu.t b/test/recipes/80-test_dtls_mtu.t index 501c42c8a1473..da82e45d340ea 100644 --- a/test/recipes/80-test_dtls_mtu.t +++ b/test/recipes/80-test_dtls_mtu.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -7,7 +7,7 @@ # https://www.openssl.org/source/license.html -use OpenSSL::Test; +use OpenSSL::Test qw/:DEFAULT srctop_file/; use OpenSSL::Test::Utils; my $test_name = "test_dtls_mtu"; @@ -18,4 +18,7 @@ plan skip_all => "$test_name needs DTLS and PSK support enabled" plan tests => 1; -ok(run(test(["dtls_mtu_test"])), "running dtls_mtu_test"); +ok(run(test(["dtls_mtu_test", + srctop_file("test/certs/servercert.pem"), + srctop_file("test/certs/serverkey.pem")])), + "running dtls_mtu_test"); diff --git a/test/recipes/80-test_dtls_multithread.t b/test/recipes/80-test_dtls_multithread.t new file mode 100644 index 0000000000000..748dfcf33663b --- /dev/null +++ b/test/recipes/80-test_dtls_multithread.t @@ -0,0 +1,26 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use OpenSSL::Test::Utils; +use OpenSSL::Test qw/:DEFAULT srctop_file/; + +setup("test_dtls_multithread"); + +plan skip_all => "test_dtls_multithread needs the sock feature enabled" + if disabled("sock"); + +plan skip_all => "test_dtls_multithread needs DTLS enabled" + if disabled("dtls"); + +plan skip_all => "test_dtls_multithread needs the threads feature enabled" + if disabled("threads"); + +plan tests => 1; + +ok(run(test(["dtls_multithread_test", srctop_file("apps", "server.pem"), + srctop_file("apps", "server.pem")])), "running dtls_multithread_test"); diff --git a/test/recipes/80-test_dtlsssllistener.t b/test/recipes/80-test_dtlsssllistener.t new file mode 100644 index 0000000000000..dd2636558e219 --- /dev/null +++ b/test/recipes/80-test_dtlsssllistener.t @@ -0,0 +1,23 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use OpenSSL::Test::Utils; +use OpenSSL::Test qw/:DEFAULT srctop_file/; + +setup("test_dtlsssllistener"); + +plan skip_all => "test_dtlsssllistener needs the sock feature enabled" + if disabled("sock"); + +plan skip_all => "test_dtlsssllistener needs DTLS enabled" + if disabled("dtls"); + +plan tests => 1; + +ok(run(test(["dtlsssllistenertest", srctop_file("apps", "server.pem"), + srctop_file("apps", "server.pem")])), "running dtlsssllistenertest"); diff --git a/test/recipes/80-test_dtlsv1listen.t b/test/recipes/80-test_dtlsv1listen.t index e40b120ef1ac0..f423de306985a 100644 --- a/test/recipes/80-test_dtlsv1listen.t +++ b/test/recipes/80-test_dtlsv1listen.t @@ -1,12 +1,23 @@ #! /usr/bin/env perl -# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy # in the file LICENSE in the source distribution or at # https://www.openssl.org/source/license.html +use OpenSSL::Test::Utils; +use OpenSSL::Test qw/:DEFAULT srctop_file/; -use OpenSSL::Test::Simple; +setup("test_dtlsv1listen"); -simple_test("test_dtlsv1listen", "dtlsv1listentest", "dh"); +plan skip_all => "No DTLS protocols are supported by this OpenSSL build" + if alldisabled(available_protocols("dtls")); + +plan skip_all => "No DTLS 1.2 support in this OpenSSL build" + if disabled("dtls1_2"); + +plan tests => 1; + +ok(run(test(["dtlsv1listentest", srctop_file("apps", "server.pem"), + srctop_file("apps", "server.pem")])), "running dtlsv1listentest"); diff --git a/test/recipes/80-test_ocsp.t b/test/recipes/80-test_ocsp.t index 62ee9f13cae87..cec3d7d64a317 100644 --- a/test/recipes/80-test_ocsp.t +++ b/test/recipes/80-test_ocsp.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -54,7 +54,7 @@ sub test_ocsp { $title); }); } -plan tests => 14; +plan tests => 15; subtest "=== VALID OCSP RESPONSES ===" => sub { plan tests => 7; @@ -263,3 +263,44 @@ subtest "=== OCSP handling of identical input and output files ===" => sub { ok(run(app(['openssl', 'ocsp', '-respin', $inout2, '-respout', $inout2, '-noverify']))); ok(!compare($inout2, $backup2), "copied response $inout2 did not change"); }; + +subtest "=== OCSP offline request/responder/verify round-trip ===" => sub { + plan tests => 6; + + # Offline round-trip: build a request, answer it with the built-in + # responder using a static index, then verify the response. + my $issuer = catfile($ocspdir, "intermediate-cert.pem"); + my $ee = catfile($ocspdir, "server-cert.pem"); + my $index = catfile($ocspdir, "index.txt"); + my $rsigner = catfile($ocspdir, "ocsp.pem"); + my $root = catfile($ocspdir, "root-cert.pem"); + + # The serial of server-cert.pem is listed as valid in index.txt, so its + # status is "good"; a serial absent from the index yields "unknown". + my $roundtrip = sub { + my ($title, $reqargs, $status) = @_; + my $req = "rt-req.der"; + my $resp = "rt-resp.der"; + + ok(run(app(['openssl', 'ocsp', '-issuer', $issuer, @$reqargs, + '-reqout', $req])), + "$title: produce request"); + ok(run(app(['openssl', 'ocsp', '-index', $index, '-rsigner', $rsigner, + '-CA', $issuer, '-reqin', $req, '-respout', $resp])), + "$title: responder produces response"); + # Passing the request again lets print_ocsp_summary report the status. + ok(run(app(['openssl', 'ocsp', '-issuer', $issuer, @$reqargs, + '-no_nonce', '-respin', $resp, '-CAfile', $root, + '-verify_other', $rsigner, + '-no-CApath', '-no-CAstore'])), + "$title: verify self-generated response ($status)"); + }; + + SKIP: { + # The responder certificates use EC keys. + skip "EC is not supported by this OpenSSL build", 6 if disabled("ec"); + + $roundtrip->("GOOD (by cert)", ['-cert', $ee], "good"); + $roundtrip->("UNKNOWN (by serial)", ['-serial', '0x1234'], "unknown"); + } +}; diff --git a/test/recipes/80-test_pkcs12.t b/test/recipes/80-test_pkcs12.t index 5e9838d107d8a..a9015c69ee666 100644 --- a/test/recipes/80-test_pkcs12.t +++ b/test/recipes/80-test_pkcs12.t @@ -55,8 +55,9 @@ if (eval { require Win32::API; 1; }) { $ENV{OPENSSL_WIN32_UTF8}=1; my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0); +my $no_err = disabled('err') || disabled('autoerrinit'); -plan tests => 64 + ($no_fips ? 0 : 5); +plan tests => 77 + ($no_fips ? 0 : 5); # Test different PKCS#12 formats ok(run(test(["pkcs12_format_test"])), "test pkcs12 formats"); @@ -84,6 +85,7 @@ my $outfile4 = "out4.p12"; my $outfile5 = "out5.p12"; my $outfile6 = "out6.p12"; my $outfile7 = "out7.p12"; +my $outfile8 = "out8.p12"; # Test the -chain option with -untrusted ok(run(app(["openssl", "pkcs12", "-export", "-chain", @@ -176,11 +178,20 @@ ok(grep(/Trusted key usage (Oracle)/, @pkcs12info) == 0, ok(scalar @match > 0 ? 0 : 1, "test_export_pkcs12_outerr6_empty"); } +# Export key + cert + distinct CA cert for combination tests +ok(run(app(["openssl", "pkcs12", "-export", + "-inkey", srctop_file(@path, "ee-key.pem"), + "-in", srctop_file(@path, "ee-cert.pem"), + "-certfile", srctop_file(@path, "ca-cert.pem"), + "-passout", "pass:", + "-nomac", "-out", $outfile8])), + "test_export_pkcs12_key_cert_ca"); + # Test dumping a PKCS#12 file whose private key is stored in an unencrypted # keyBag (created with -keypbe NONE) rather than a shrouded keyBag. { my $keybag = "keybag.p12"; - ok(run(app(["openssl", "pkcs12", "-export", "-keypbe", "NONE", + ok(run(app(["openssl", "pkcs12", "-export", "-keyex", "-keypbe", "NONE", "-certpbe", "NONE", "-nomac", "-inkey", srctop_file(@path, "cert-key-cert.pem"), "-in", srctop_file(@path, "cert-key-cert.pem"), @@ -322,6 +333,60 @@ with({ exit_checker => sub { return shift == 1; } }, delete $ENV{OPENSSL_CONF} } +# Test -clcerts/-cacerts cert filtering and the -name friendly name. +subtest "pkcs12 -clcerts/-cacerts filtering and -name" => sub { + plan tests => 7; + + # A PKCS#12 with a key + matching EE cert (gets a localKeyID) and a CA + # cert added via -certfile (no localKeyID), plus a friendly name. + my $mixed = "mixed.p12"; + ok(run(app(["openssl", "pkcs12", "-export", + "-inkey", srctop_file(@path, "ee-key.pem"), + "-in", srctop_file(@path, "ee-cert.pem"), + "-certfile", srctop_file(@path, "ca-cert.pem"), + "-name", "Friendly Client", + "-passout", "pass:", "-out", $mixed])), + "export a PKCS#12 with a client cert, a CA cert and a friendly name"); + + # -name sets the friendly name, visible in -info output. + my @info = run(app(["openssl", "pkcs12", "-in", $mixed, "-info", "-nokeys", + "-passin", "pass:"]), capture => 1); + ok(grep(/friendlyName: Friendly Client/, @info) == 1, + "the -name friendly name is present in the output"); + + # Without filtering both certificates are dumped. + my @all = run(app(["openssl", "pkcs12", "-in", $mixed, "-nokeys", + "-passin", "pass:"]), capture => 1); + ok(grep(/BEGIN CERTIFICATE/, @all) == 2, + "both certificates are output without filtering"); + + # -clcerts outputs only the client (leaf) certificate. + my @cl = run(app(["openssl", "pkcs12", "-in", $mixed, "-nokeys", "-clcerts", + "-passin", "pass:"]), capture => 1); + ok(grep(/BEGIN CERTIFICATE/, @cl) == 1, + "-clcerts outputs a single certificate"); + ok(grep(/subject=CN\s*=\s*server\.example/, @cl) == 1, + "-clcerts outputs the client certificate"); + + # -cacerts outputs only the CA certificate. + my @ca = run(app(["openssl", "pkcs12", "-in", $mixed, "-nokeys", "-cacerts", + "-passin", "pass:"]), capture => 1); + ok(grep(/BEGIN CERTIFICATE/, @ca) == 1, + "-cacerts outputs a single certificate"); + ok(grep(/subject=CN\s*=\s*CA\b/, @ca) == 1, + "-cacerts outputs the CA certificate"); +}; + +# Test PKCS12_parse_ex libctx propagation (PR #30937) +# mixed.p12 uses AES-encrypted cert safe, exercising PKCS7 context propagation +ok(run(test(["pkcs12_api_test", + "-in", "mixed.p12", + "-pass", "", + "-has-key", 1, + "-has-cert", 1, + "-has-ca", 1, + ])), "Test PKCS12_parse_ex libctx propagation (PR #30937)"); + # Tests for pkcs12_parse ok(run(test(["pkcs12_api_test", "-in", $outfile1, @@ -354,6 +419,7 @@ ok(run(test(["pkcs12_api_test", "-has-ca", 1, "-has-key", 1, "-has-cert", 1, + "-ca-count", 1, ])), "Test pkcs12_parse()"); ok(run(test(["pkcs12_api_test", @@ -367,120 +433,242 @@ ok(run(test(["pkcs12_api_test", "-has-ca", 1, "-has-key", 1, "-has-cert", 1, + "-ca-count", 1, ])), "Test pkcs12_parse()"); +# Test PKCS12_parse cert placement: two certs sharing a key + unrelated cert. +# The cert from -in should be returned as the main cert; the other cert +# matching the key (from -certfile) should go to the CA stack. +{ + my $extra_certs = "extra_certs.pem"; + open(my $out, '>', $extra_certs) or die "Cannot create $extra_certs: $!"; + for my $f (srctop_file(@path, "ee-cert2.pem"), + srctop_file(@path, "ca-cert.pem")) { + open(my $in, '<', $f) or die "Cannot read $f: $!"; + print $out $_ while <$in>; + close $in; + } + close $out; + + my $twocert_p12 = "twocert.p12"; + ok(run(app(["openssl", "pkcs12", "-export", + "-inkey", srctop_file(@path, "ee-key.pem"), + "-in", srctop_file(@path, "ee-cert.pem"), + "-certfile", $extra_certs, + "-passout", "pass:", "-nomac", "-out", $twocert_p12])), + "export PKCS#12 with two certs sharing a key and unrelated cert"); + + ok(run(test(["pkcs12_api_test", + "-in", $twocert_p12, + "-has-key", 1, + "-has-cert", 1, + "-has-ca", 1, + "-ca-count", 2, + "-expected-cert", srctop_file(@path, "ee-cert.pem"), + "-expected-key", srctop_file(@path, "ee-key.pem"), + "-expected-ca", $extra_certs, + ])), "Test PKCS12_parse cert placement with shared key"); +} + +# Test PKCS12_parse with a key encrypted using a different password than the MAC. +# Omitting the key succeeds; requesting it fails. +ok(run(test(["pkcs12_api_test", + "-in", srctop_file("test", "recipes", "80-test_pkcs12_data", + "mismatched_key_pass.p12"), + "-mismatched-key-pass", + ])), "Test PKCS12_parse with mismatched key password"); +ok(run(test(["pkcs12_api_test", + "-in", $outfile8, + "-pass", "", + "-has-ca", 1, + "-has-key", 1, + "-has-cert", 1, + ])), "Test pkcs12_parse() key+cert+ca combinations"); + # Test against CVE-2025-69421, octet parameter is expected, but # NULL is being received and dereferenced unless ($no_fips) { - my $file = "sha256mac_cert.oct-is-null.p12"; - my $path = srctop_file("test", "recipes", "80-test_pkcs12_data", $file); - with({ exit_checker => sub { return shift == 1; } }, - sub { - my @output = run(app(["openssl", "storeutl", "-certs", "-text", - "-passin", "pass:RedHatEnterpriseLinux10.0", $path]), - capture => 1, stderr => "outerr.txt"); - open DATA, "outerr.txt"; - my @match = grep /PKCS12_item_decrypt_d2i_ex:passed a null parameter/, ; - close DATA; - ok(scalar @match > 0 ? 0 : 1, "Test against CVE-2025-69421 - null parameter, sha256mac"); - } - ); + SKIP: { + skip "Error messages are not compiled in", 1 if $no_err; + { + my $file = "sha256mac_cert.oct-is-null.p12"; + my $path = srctop_file("test", "recipes", "80-test_pkcs12_data", $file); + with({ exit_checker => sub { return shift == 1; } }, + sub { + my @output = run(app(["openssl", "storeutl", "-certs", "-text", + "-passin", "pass:RedHatEnterpriseLinux10.0", $path], + stderr => "outerr.txt"), + capture => 1); + open DATA, "outerr.txt"; + my @match = grep /PKCS12_item_decrypt_d2i_ex:passed a null parameter/, ; + close DATA; + ok(scalar @match > 0, "Test against CVE-2025-69421 - null parameter, sha256mac"); + } + ); + } + } } -{ - my $file = "pbmac1_cert.oct-is-null.p12"; - my $path = srctop_file("test", "recipes", "80-test_pkcs12_data", $file); - with({ exit_checker => sub { return shift == 1; } }, - sub { - my @output = run(app(["openssl", "storeutl", "-certs", "-text", - "-passin", "pass:RedHatEnterpriseLinux10.0", $path]), - capture => 1, stderr => "outerr.txt"); - open DATA, "outerr.txt"; - my @match = grep /PKCS12_item_decrypt_d2i_ex:passed a null parameter/, ; - close DATA; - ok(scalar @match > 0 ? 0 : 1, "Test against CVE-2025-69421 - null parameter, pbmac1"); - } - ); + SKIP: { + skip "Error messages are not compiled in", 1 if $no_err; + { + my $file = "pbmac1_cert.oct-is-null.p12"; + my $path = srctop_file("test", "recipes", "80-test_pkcs12_data", $file); + with({ exit_checker => sub { return shift == 1; } }, + sub { + my @output = run(app(["openssl", "storeutl", "-certs", "-text", + "-passin", "pass:RedHatEnterpriseLinux10.0", $path], + stderr => "outerr.txt"), + capture => 1); + open DATA, "outerr.txt"; + my @match = grep /PKCS12_item_decrypt_d2i_ex:passed a null parameter/, ; + close DATA; + ok(scalar @match > 0, "Test against CVE-2025-69421 - null parameter, pbmac1"); + } + ); + } } # Test against CVE-2026-22795 , missing ASN1_TYPE validation in cert unless ($no_fips) { - for my $file ("BOOLEAN-in-friendlyName-of-cert-pkcs12-sha256mac.p12", - "BOOLEAN-in-localKeyID-of-cert-pkcs12-sha256mac.p12" + SKIP: { + skip "Error messages are not compiled in", 2 if $no_err; + { + for my $file ("BOOLEAN-in-friendlyName-of-cert-pkcs12-sha256mac.p12", + "BOOLEAN-in-localKeyID-of-cert-pkcs12-sha256mac.p12" + ) + { + my $path = srctop_file("test", "recipes", "80-test_pkcs12_data", $file); + with({ exit_checker => sub { return shift == 1; } }, + sub { + my @output = run(app(["openssl", "storeutl", "-certs", "-text", + "-passin", "pass:RedHatEnterpriseLinux10.0", $path], + stderr => "outerr.txt"), + capture => 1); + open DATA, "outerr.txt"; + my @match = grep /:PKCS12_parse_ex:parse error:/, ; + close DATA; + ok(scalar @match > 0, "Test against CVE-2026-22795 , missing ASN1_TYPE validation in cert, sha256mac"); + } + ); + } + } + } +} + + SKIP: { + skip "Error messages are not compiled in", 2 if $no_err; + for my $file ("BOOLEAN-in-friendlyName-of-cert-pbmac1.p12", + "BOOLEAN-in-localKeyID-of-cert-pbmac1.p12" ) { my $path = srctop_file("test", "recipes", "80-test_pkcs12_data", $file); with({ exit_checker => sub { return shift == 1; } }, - sub { - my @output = run(app(["openssl", "storeutl", "-certs", "-text", - "-passin", "pass:RedHatEnterpriseLinux10.0", $path]), - capture => 1, stderr => "outerr.txt"); - open DATA, "outerr.txt"; - my @match = grep /:PKCS12_parse:parse error:/, ; - close DATA; - ok(scalar @match > 0 ? 0 : 1, "Test against CVE-2026-22795 , missing ASN1_TYPE validation in cert, sha256mac"); + sub { + my @output = run(app(["openssl", "storeutl", "-certs", "-text", + "-passin", "pass:RedHatEnterpriseLinux10.0", $path], + stderr => "outerr.txt"), + capture => 1); + open DATA, "outerr.txt"; + my @match = grep /:PKCS12_parse_ex:parse error:/, ; + close DATA; + ok(scalar @match > 0, "Test against CVE-2026-22795 , missing ASN1_TYPE validation in cert, pbmac1"); } ); } } -for my $file ("BOOLEAN-in-friendlyName-of-cert-pbmac1.p12", - "BOOLEAN-in-localKeyID-of-cert-pbmac1.p12" - ) -{ - my $path = srctop_file("test", "recipes", "80-test_pkcs12_data", $file); - with({ exit_checker => sub { return shift == 1; } }, - sub { - my @output = run(app(["openssl", "storeutl", "-certs", "-text", - "-passin", "pass:RedHatEnterpriseLinux10.0", $path]), - capture => 1, stderr => "outerr.txt"); - open DATA, "outerr.txt"; - my @match = grep /:PKCS12_parse:parse error:/, ; - close DATA; - ok(scalar @match > 0 ? 0 : 1, "Test against CVE-2026-22795 , missing ASN1_TYPE validation in cert, pbmac1"); +# Test against CVE-2026-22795, missing ASN1_TYPE validation in keys +unless ($no_fips) { + SKIP: { + skip "Error messages are not compiled in", 2 if $no_err; + { + for my $file ("BOOLEAN-in-friendlyName-of-key-pkcs12-sha256mac.p12", + "BOOLEAN-in-localKeyID-of-key-pkcs12-sha256mac.p12" + ) + { + my $path = srctop_file("test", "recipes", "80-test_pkcs12_data", $file); + with({ exit_checker => sub { return shift == 1; } }, + sub { + my @output = run(app(["openssl", "storeutl", "-keys", "-text", + "-passin", "pass:RedHatEnterpriseLinux10.0", $path], + stderr => "outerr.txt"), + capture => 1); + open DATA, "outerr.txt"; + my @match = grep /:PKCS12_parse_ex:parse error:/, ; + close DATA; + ok(scalar @match > 0, "Test against CVE-2026-22795 , missing ASN1_TYPE validation in keys, sha256mac"); + } + ); + } } - ); + } } -# Test against CVE-2026-22795, missing ASN1_TYPE validation in keys -unless ($no_fips) { - for my $file ("BOOLEAN-in-friendlyName-of-key-pkcs12-sha256mac.p12", - "BOOLEAN-in-localKeyID-of-key-pkcs12-sha256mac.p12" - ) + SKIP: { + skip "Error messages are not compiled in", 2 if $no_err; { + for my $file ("BOOLEAN-in-friendlyName-of-key-pbmac1.p12", + "BOOLEAN-in-localKeyID-of-key-pbmac1.p12" + ) + { my $path = srctop_file("test", "recipes", "80-test_pkcs12_data", $file); with({ exit_checker => sub { return shift == 1; } }, sub { - my @output = run(app(["openssl", "storeutl", "-keys", "-text", - "-passin", "pass:RedHatEnterpriseLinux10.0", $path]), - capture => 1, stderr => "outerr.txt"); + "-passin", "pass:RedHatEnterpriseLinux10.0", $path], + stderr => "outerr.txt"), + capture => 1); open DATA, "outerr.txt"; - my @match = grep /:PKCS12_parse:parse error:/, ; + my @match = grep /:PKCS12_parse_ex:parse error:/, ; close DATA; - ok(scalar @match > 0 ? 0 : 1, "Test against CVE-2026-22795 , missing ASN1_TYPE validation in keys, sha256mac"); + ok(scalar @match > 0, "Test against CVE-2026-22795 , missing ASN1_TYPE validation in keys, pbmac1"); } ); + } } } -for my $file ("BOOLEAN-in-friendlyName-of-key-pbmac1.p12", - "BOOLEAN-in-localKeyID-of-key-pbmac1.p12" - ) + +# Test PKCS12_parse_ex() with Java symmetric key file +ok(run(test(["pkcs12_api_test", + "-in", srctop_file("test", "recipes", "80-test_pkcs12_data", "java-skey.p12"), + "-pass", "password", + "-num-skeys", "1", + ])), "Test PKCS12_parse_ex() with symmetric key"); + +# Test OSSL_STORE with Java symmetric key file { - my $path = srctop_file("test", "recipes", "80-test_pkcs12_data", $file); - with({ exit_checker => sub { return shift == 1; } }, - sub { - my @output = run(app(["openssl", "storeutl", "-keys", "-text", - "-passin", "pass:RedHatEnterpriseLinux10.0", $path]), - capture => 1, stderr => "outerr.txt"); - open DATA, "outerr.txt"; - my @match = grep /:PKCS12_parse:parse error:/, ; - close DATA; - ok(scalar @match > 0 ? 0 : 1, "Test against CVE-2026-22795 , missing ASN1_TYPE validation in keys, pbmac1"); - } - ); + my @output = run(app(["openssl", "storeutl", + "-passin", "pass:password", + srctop_file("test", "recipes", "80-test_pkcs12_data", "java-skey.p12")]), + capture => 1); + ok(@output > 0, "Test OSSL_STORE loads symmetric key from PKCS#12"); + + my $output_text = join("", @output); + like($output_text, qr/Symmetric key/, "OSSL_STORE output shows symmetric key"); +} + + +# Test PKCS12_parse_ex() with multiple symmetric keys +ok(run(test(["pkcs12_api_test", + "-in", srctop_file("test", "recipes", "80-test_pkcs12_data", "multi-skey.p12"), + "-pass", "password", + "-num-skeys", "2", + ])), "Test PKCS12_parse_ex() with multiple symmetric keys"); + +# Test OSSL_STORE with multiple symmetric keys +{ + my @output = run(app(["openssl", "storeutl", + "-passin", "pass:password", + srctop_file("test", "recipes", "80-test_pkcs12_data", "multi-skey.p12")]), + capture => 1); + ok(@output > 0, "Test OSSL_STORE loads multiple symmetric keys from PKCS#12"); + + my $output_text = join("", @output); + my @skey_matches = ($output_text =~ /Symmetric key/g); + ok(scalar @skey_matches == 2, "OSSL_STORE output shows two symmetric keys"); } SetConsoleOutputCP($savedcp) if (defined($savedcp)); diff --git a/test/recipes/80-test_pkcs12_data/java-skey.p12 b/test/recipes/80-test_pkcs12_data/java-skey.p12 new file mode 100644 index 0000000000000..46c347bef656f Binary files /dev/null and b/test/recipes/80-test_pkcs12_data/java-skey.p12 differ diff --git a/test/recipes/80-test_pkcs12_data/mismatched_key_pass.p12 b/test/recipes/80-test_pkcs12_data/mismatched_key_pass.p12 new file mode 100644 index 0000000000000..d5fb51ae40061 Binary files /dev/null and b/test/recipes/80-test_pkcs12_data/mismatched_key_pass.p12 differ diff --git a/test/recipes/80-test_pkcs12_data/multi-skey.p12 b/test/recipes/80-test_pkcs12_data/multi-skey.p12 new file mode 100644 index 0000000000000..8db996c1d161e Binary files /dev/null and b/test/recipes/80-test_pkcs12_data/multi-skey.p12 differ diff --git a/test/recipes/80-test_ssl_new.t b/test/recipes/80-test_ssl_new.t index 8516652f97292..43a0bdf15baee 100644 --- a/test/recipes/80-test_ssl_new.t +++ b/test/recipes/80-test_ssl_new.t @@ -54,7 +54,8 @@ my $is_default_tls = (!disabled("tls1") && !disabled("tls1_1") && !disabled("tls1_2") && !disabled("tls1_3") && (!disabled("ec") || !disabled("dh"))); -my $is_default_dtls = (!disabled("dtls1") && !disabled("dtls1_2")); +my $is_default_dtls = (!disabled("dtls1") && !disabled("dtls1_2") && + !disabled("dtls1_3")); my @all_pre_tls1_3 = ("tls1", "tls1_1", "tls1_2"); my $no_tls = alldisabled(available_protocols("tls")); @@ -85,7 +86,7 @@ my %conf_dependent_tests = ( "05-sni.cnf" => disabled("tls1_1"), "07-dtls-protocol-version.cnf" => !$is_default_dtls || !disabled("sctp"), "10-resumption.cnf" => !$is_default_tls || $no_ec, - "11-dtls_resumption.cnf" => !$is_default_dtls || !disabled("sctp"), + "11-dtls_resumption.cnf" => !$is_default_dtls || $no_ec || !disabled("sctp"), "14-curves.cnf" => disabled("tls-deprecated-ec") || $no_ecx || $no_sm2 || $no_ml_kem, "16-dtls-certstatus.cnf" => !$is_default_dtls || !disabled("sctp"), "17-renegotiate.cnf" => disabled("tls1_2"), @@ -119,8 +120,7 @@ my %skip = ( # special-casing for. # TODO(TLS 1.3): We should review this once we have TLS 1.3. "13-fragmentation.cnf" => disabled("tls1_2"), - "14-curves.cnf" => disabled("tls1_2") || disabled("tls1_3") - || $no_ec2m || $no_ecx || $no_dh, + "14-curves.cnf" => disabled("tls1_2") || disabled("tls1_3") || ($no_ec && $no_dh), "15-certstatus.cnf" => $no_tls || $no_ocsp, "16-dtls-certstatus.cnf" => $no_dtls || $no_ocsp, "17-renegotiate.cnf" => $no_tls_below1_3, diff --git a/test/recipes/80-test_tsget.t b/test/recipes/80-test_tsget.t new file mode 100644 index 0000000000000..cc69db65fe5d8 --- /dev/null +++ b/test/recipes/80-test_tsget.t @@ -0,0 +1,379 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use File::Copy qw/copy/; +use IO::Socket::INET; +use OpenSSL::Test qw/:DEFAULT srctop_file bldtop_file/; +use OpenSSL::Test::Utils; + +setup("test_tsget"); + +plan skip_all => "TS is not supported by this OpenSSL build" + if disabled("ts"); + +plan skip_all => "fork() is not available on this platform" + if $^O =~ /^(MSWin32|VMS)$/; + +plan skip_all => "tsget is not available (not built)" + unless -f bldtop_file("apps", "tsget.pl"); + +eval { require Net::Curl::Easy }; +plan skip_all => "Net::Curl::Easy is not available" + if $@; + +plan skip_all => "test_tsget needs IPv4" + unless have_IPv4(); + +plan tests => 12; + +indir "tsget" => sub { + my $openssl_conf = srctop_file("test", "CAtsa.cnf"); + my $tsacakey = srctop_file("test", "certs", "ca-key.pem"); + my $alt1_key = srctop_file("test", "certs", "alt1-key.pem"); + my ($normal_pid, $normal_port); + + # These two tests exercise tsget argument validation before any network + # or TSA infrastructure is needed. + + subtest "missing -h flag" => sub { + plan tests => 1; + ok(!run(perlapp(["tsget.pl", "test.tsq"])), + "tsget exits non-zero without -h"); + }; + + subtest "multiple files combined with -o" => sub { + plan tests => 1; + ok(!run(perlapp(["tsget.pl", "-h", "http://127.0.0.1:1", + "-o", "combined.tsr", "test.tsq", "test2.tsq"])), + "tsget exits non-zero with -o and multiple input files"); + }; + + SKIP: { + skip "TSA infrastructure setup failed", 10 + unless setup_tsa_infrastructure($openssl_conf, $tsacakey, $alt1_key); + + ($normal_pid, $normal_port) = start_mock_tsa_server( + mode => 'normal', + response_file => 'canned.tsr', + ); + + SKIP: { + skip "could not start normal mock server", 8 unless defined $normal_pid; + + my $url = "http://127.0.0.1:$normal_port"; + + subtest "default output extension (.tsr)" => sub { + plan tests => 3; + ok(run(perlapp(["tsget.pl", "-v", "-h", $url, "test.tsq"])), + "tsget runs successfully"); + ok(-f "test.tsr", "output file test.tsr created"); + ok(run(app(["openssl", "ts", "-verify", + "-queryfile", "test.tsq", + "-in", "test.tsr", + "-CAfile", "tsaca.pem", + "-untrusted", "tsa_cert.pem"])), + "timestamp reply is cryptographically valid"); + }; + + subtest "custom extension (-e .reply)" => sub { + plan tests => 3; + ok(run(perlapp(["tsget.pl", "-v", "-e", ".reply", "-h", $url, "test.tsq"])), + "tsget runs with -e .reply"); + ok(-f "test.reply", "output file test.reply created"); + ok(run(app(["openssl", "ts", "-verify", + "-queryfile", "test.tsq", + "-in", "test.reply", + "-CAfile", "tsaca.pem", + "-untrusted", "tsa_cert.pem"])), + "timestamp reply is cryptographically valid"); + }; + + subtest "custom output file (-o)" => sub { + plan tests => 3; + ok(run(perlapp(["tsget.pl", "-v", "-o", "custom.tsr", "-h", $url, "test.tsq"])), + "tsget runs with -o"); + ok(-f "custom.tsr", "custom output file created"); + ok(run(app(["openssl", "ts", "-verify", + "-queryfile", "test.tsq", + "-in", "custom.tsr", + "-CAfile", "tsaca.pem", + "-untrusted", "tsa_cert.pem"])), + "timestamp reply is cryptographically valid"); + }; + + subtest "stdin input" => sub { + plan tests => 3; + ok(run(perlapp(["tsget.pl", "-v", "-o", "stdin.tsr", "-h", $url], + stdin => "test.tsq")), + "tsget runs with stdin input"); + ok(-f "stdin.tsr", "output file stdin.tsr created"); + ok(run(app(["openssl", "ts", "-verify", + "-queryfile", "test.tsq", + "-in", "stdin.tsr", + "-CAfile", "tsaca.pem", + "-untrusted", "tsa_cert.pem"])), + "timestamp reply is cryptographically valid"); + }; + + subtest "debug mode (-d)" => sub { + plan tests => 1; + ok(run(perlapp(["tsget.pl", "-d", "-o", "debug.tsr", "-h", $url, "test.tsq"])), + "tsget runs with -d flag"); + }; + + subtest "TSGET environment variable" => sub { + plan tests => 3; + local $ENV{TSGET} = "-v -e .envtsr -h $url"; + ok(run(perlapp(["tsget.pl", "test.tsq"])), + "tsget uses TSGET environment variable"); + ok(-f "test.envtsr", "output file test.envtsr created"); + ok(run(app(["openssl", "ts", "-verify", + "-queryfile", "test.tsq", + "-in", "test.envtsr", + "-CAfile", "tsaca.pem", + "-untrusted", "tsa_cert.pem"])), + "timestamp reply is cryptographically valid"); + }; + + subtest "multiple input files" => sub { + plan tests => 4; + SKIP: { + skip "could not copy test.tsq to test2.tsq", 4 + unless copy("test.tsq", "test2.tsq"); + ok(run(perlapp(["tsget.pl", "-v", "-h", $url, "test.tsq", "test2.tsq"])), + "tsget processes two input files"); + ok(-f "test.tsr", "output test.tsr created for first file"); + ok(-f "test2.tsr", "output test2.tsr created for second file"); + ok(run(app(["openssl", "ts", "-verify", + "-queryfile", "test.tsq", + "-in", "test.tsr", + "-CAfile", "tsaca.pem", + "-untrusted", "tsa_cert.pem"])), + "first timestamp reply is cryptographically valid"); + } + }; + + subtest "input file in subdirectory" => sub { + plan tests => 3; + SKIP: { + mkdir "subdir" unless -d "subdir"; + skip "could not set up subdir/test.tsq", 3 + unless -d "subdir" && copy("test.tsq", "subdir/test.tsq"); + ok(run(perlapp(["tsget.pl", "-v", "-h", $url, "subdir/test.tsq"])), + "tsget derives output path from input path"); + ok(-f "subdir/test.tsr", + "output placed in same directory as input"); + ok(run(app(["openssl", "ts", "-verify", + "-queryfile", "subdir/test.tsq", + "-in", "subdir/test.tsr", + "-CAfile", "tsaca.pem", + "-untrusted", "tsa_cert.pem"])), + "timestamp reply is cryptographically valid"); + } + }; + } + + subtest "HTTP server error response" => sub { + plan tests => 2; + my ($pid, $port) = start_mock_tsa_server( + mode => 'error', + http_code => 500, + max_requests => 1, + ); + SKIP: { + skip "could not start error server", 2 unless defined $pid; + ok(!run(perlapp(["tsget.pl", "-h", "http://127.0.0.1:$port", + "-o", "err_http.tsr", "test.tsq"])), + "tsget exits non-zero on HTTP 500"); + ok(!-f "err_http.tsr", + "partial output file removed after HTTP error"); + } + waitpid($pid, 0) if defined $pid; + }; + + subtest "empty server response" => sub { + plan tests => 2; + my ($pid, $port) = start_mock_tsa_server( + mode => 'empty', + max_requests => 1, + ); + SKIP: { + skip "could not start empty server", 2 unless defined $pid; + ok(!run(perlapp(["tsget.pl", "-h", "http://127.0.0.1:$port", + "-o", "err_empty.tsr", "test.tsq"])), + "tsget exits non-zero on empty response"); + ok(!-f "err_empty.tsr", + "partial output file removed after empty response"); + } + waitpid($pid, 0) if defined $pid; + }; + } + + if (defined $normal_pid) { + kill 'TERM', $normal_pid; + waitpid($normal_pid, 0); + } + +}, create => 1, cleanup => 1; + + +# Set up a local TSA: CA cert, signing cert/key, TSA config, and a +# pre-generated timestamp response that the mock server will return for +# every request. +sub setup_tsa_infrastructure { + my ($conf, $cakey, $signerkey) = @_; + + local $ENV{TSDNSECT} = "ts_ca_dn"; + + run(app(["openssl", "req", + "-config", $conf, "-new", "-x509", "-noenc", + "-out", "tsaca.pem", "-key", $cakey])) + or do { diag "Failed to create TSA CA cert"; return 0; }; + + local $ENV{TSDNSECT} = "ts_cert_dn"; + local $ENV{INDEX} = "1"; + + run(app(["openssl", "req", + "-config", $conf, "-new", + "-out", "tsa_req.pem", + "-key", $signerkey, + "-keyout", "tsa_key.pem"])) + or do { diag "Failed to create TSA cert request"; return 0; }; + + run(app(["openssl", "x509", "-req", + "-in", "tsa_req.pem", + "-out", "tsa_cert.pem", + "-CA", "tsaca.pem", "-CAkey", $cakey, + "-CAcreateserial", + "-extfile", $conf, "-extensions", "tsa_cert"])) + or do { diag "Failed to sign TSA cert"; return 0; }; + + open(my $cfh, ">", "local_tsa.cnf") + or do { diag "Failed to write local_tsa.cnf: $!"; return 0; }; + print $cfh <<'END_CNF'; +[ tsa ] +default_tsa = tsa_config1 + +[ tsa_config1 ] +dir = . +serial = $dir/tsa_serial +signer_cert = $dir/tsa_cert.pem +certs = $dir/tsaca.pem +signer_key = $dir/tsa_key.pem +signer_digest = sha256 +default_policy = 1.2.3.4.1 +digests = sha1, sha256, sha384, sha512 +ordering = yes +tsa_name = yes +ess_cert_id_chain = yes +ess_cert_id_alg = sha256 +END_CNF + close $cfh; + + open(my $sfh, ">", "tsa_serial") + or do { diag "Failed to write tsa_serial: $!"; return 0; }; + print $sfh "01\n"; + close $sfh; + + run(app(["openssl", "ts", "-query", + "-data", $conf, "-sha256", "-cert", + "-out", "test.tsq"])) + or do { diag "Failed to create timestamp query"; return 0; }; + + run(app(["openssl", "ts", "-reply", + "-config", "local_tsa.cnf", + "-queryfile", "test.tsq", + "-chain", "tsaca.pem", + "-out", "canned.tsr"])) + or do { diag "Failed to generate canned timestamp response"; return 0; }; + + return 1; +} + + +# Fork a minimal HTTP server. Behaviour is controlled by %opts: +# mode => 'normal' (default): serve $response_file for every POST +# => 'error': return HTTP $http_code with an empty body +# => 'empty': return HTTP 200 with Content-Length: 0 +# response_file => path to the canned response (used by 'normal' mode) +# http_code => HTTP status for 'error' mode (default 500) +# max_requests => stop after this many requests; 0 means unlimited (default) +sub start_mock_tsa_server { + my %opts = @_; + my $mode = $opts{mode} // 'normal'; + my $response_file = $opts{response_file}; + my $http_code = $opts{http_code} // 500; + my $max_requests = $opts{max_requests} // 0; + + my $sock = IO::Socket::INET->new( + LocalAddr => '127.0.0.1', + LocalPort => 0, + Type => SOCK_STREAM, + Listen => 5, + ReuseAddr => 1, + ) or do { diag "Failed to create server socket: $!"; return (undef, undef); }; + + my $port = $sock->sockport(); + + my $pid = fork(); + if (!defined $pid) { + $sock->close(); + diag "fork() failed: $!"; + return (undef, undef); + } + + if ($pid == 0) { + my $n = 0; + while (my $client = $sock->accept()) { + my $content_length = 0; + while (my $line = <$client>) { + $line =~ s/\r?\n$//; + last if $line eq ''; + $content_length = $1 + if $line =~ /^Content-Length:\s*(\d+)/i; + } + my $body = ''; + read($client, $body, $content_length) if $content_length > 0; + + if ($mode eq 'normal' && defined $response_file + && open(my $fh, '<', $response_file)) { + binmode $fh; + local $/; + my $reply = <$fh>; + close $fh; + my $len = length($reply); + print $client + "HTTP/1.0 200 OK\r\n", + "Content-Type: application/timestamp-reply\r\n", + "Content-Length: $len\r\n", + "\r\n", + $reply; + } elsif ($mode eq 'empty') { + print $client + "HTTP/1.0 200 OK\r\n", + "Content-Type: application/timestamp-reply\r\n", + "Content-Length: 0\r\n", + "\r\n"; + } else { + print $client "HTTP/1.0 $http_code Server Error\r\n\r\n"; + } + $client->close(); + ++$n; + last if $max_requests > 0 && $n >= $max_requests; + } + exit 0; + } + + $sock->close(); + select(undef, undef, undef, 0.1); + + return ($pid, $port); +} diff --git a/test/recipes/90-test_asn1_string_poison.t b/test/recipes/90-test_asn1_string_poison.t new file mode 100644 index 0000000000000..e6a584384fd20 --- /dev/null +++ b/test/recipes/90-test_asn1_string_poison.t @@ -0,0 +1,19 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + + +use OpenSSL::Test; +use OpenSSL::Test::Utils; + +setup("test_asn1_string_poison"); + +plan tests => 2; +ok(!run(test(["asn1_string_poison_test"])), + "strlen() on ASN1_STRING data is reported"); +ok(run(test(["asn1_string_poison_test", "counted"])), + "counted access to ASN1_STRING data is clean"); diff --git a/test/recipes/90-test_ct_validation_helpers.t b/test/recipes/90-test_ct_validation_helpers.t new file mode 100644 index 0000000000000..bd795c34ac64b --- /dev/null +++ b/test/recipes/90-test_ct_validation_helpers.t @@ -0,0 +1,104 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +# Tests for the constant-time validation helpers in constant_time.h: +# - CONSTTIME_SECRET +# - CONSTTIME_DECLASSIFY +# - constant_time_declassify_u32() +# +# Most of the modes below check whether Valgrind flags code that is +# deliberately NOT constant-time. The accompanying recipe asserts that the +# harness flags it. Each such mode is a separate process because Valgrind's +# verdict is delivered as a process exit code via Valgrind's --error-exitcode. +# +# The "identity" mode is different: It ensures constant_time_declassify_u32() +# still exists and functions correctly when used OUTSIDE enable-ct-validation. +# Thus this mode uses the ordinary test framework pass/fail signal +# and does not require Valgrind. + +use strict; +use warnings; + +use OpenSSL::Test qw(:DEFAULT result_file); +use OpenSSL::Test::Utils; + +setup("test_ct_validation_helpers"); + +my $NUM_VALGRIND_TESTS = 6; +my $NUM_ALWAYS_TESTS = 1; + +plan tests => $NUM_VALGRIND_TESTS + $NUM_ALWAYS_TESTS; + +SKIP: { + # Ensure test binary is wrapped in Valgrind + skip "This test requires a build with enable-ct-validation", $NUM_VALGRIND_TESTS + if disabled("ct-validation"); + skip "This test requires the test suite to be run with OSSL_VALGRIND_CT=yes", $NUM_VALGRIND_TESTS + unless defined $ENV{OSSL_VALGRIND_CT}; + + # Run one mode of ct_validation_helpers_test, capturing Valgrind's report + # (which it writes to stderr). Returns the run's success flag and report text. + my $ct_run = sub { + my ($mode) = @_; + my $errfile = result_file("ct_validation_helpers_$mode.txt"); + my $ok = run(test(["ct_validation_helpers_test", $mode], stderr => $errfile)); + my $report = ""; + + if (open(my $fh, '<', $errfile)) { + local $/ = undef; + $report = <$fh>; + close($fh); + } + return ($ok, $report); + }; + + my ($ok, $report); + + # "branch" mode: Ensure Valgrind flags a branch (a loop iteration count) on a + # secret marked with CONSTTIME_SECRET. + # + # Valgrind should report: + # "Conditional jump or move depends on uninitialised value(s)". + ($ok, $report) = $ct_run->("branch"); + ok(!$ok, "secret-dependent branch is rejected"); + like($report, qr/uninitiali[sz]ed/i, + "secret-dependent branch is reported as an uninitialised-value error"); + + # "index" mode: Ensure Valgrind flags a lookup table index derived from a + # secret marked with CONSTTIME_SECRET. + # + # Valgrind should report: + # "Use of uninitialised value". + ($ok, $report) = $ct_run->("index"); + ok(!$ok, "secret-dependent table index is rejected"); + like($report, qr/uninitiali[sz]ed/i, + "secret-dependent table index is reported as an uninitialised-value error"); + + # "control" mode: Ensure Valgrind does NOT flag a branch on a secret that has + # been declassified by CONSTTIME_DECLASSIFY. + ($ok, $report) = $ct_run->("control"); + ok($ok, "constant-time code with a declassified output is accepted"); + + # "mask" mode: Ensure Valgrind does NOT flag a branch on the result of + # constant_time_declassify_u32(). + # + # Uses the same calling pattern as constant_time_declassify_u32's current + # unique caller: + # - A constant_time_ge()/constant_time_lt() mask (0 or all-ones) computed from + # secret data is declassified and immediately branched on. The boolean + # outcome of a rejection-sampling check is safe to leak even though the data + # behind it is not. + ($ok, $report) = $ct_run->("mask"); + ok($ok, "a declassified comparison mask can be branched on"); +} + +# "identity" mode: Ensure constant_time_declassify_u32() returns its input +# unmodified, independent of whether Valgrind or enable-ct-validation are +# enabled. +ok(run(test(["ct_validation_helpers_test", "identity"])), + "constant_time_declassify_u32() is an identity function"); diff --git a/test/recipes/90-test_memfail.t b/test/recipes/90-test_memfail.t index fefc2771b65cc..bb8f369bc1efa 100644 --- a/test/recipes/90-test_memfail.t +++ b/test/recipes/90-test_memfail.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2025-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -31,8 +31,6 @@ $ENV{OPENSSL_TEST_MFAIL_DISABLE} = "1"; run(test(["handshake-memfail", "count", srctop_dir("test", "certs")], stderr => "$resultdir/hscountinfo.txt")); -run(test(["x509-memfail", "count", srctop_file("test", "certs", "servercert.pem")], stderr => "$resultdir/x509countinfo.txt")); - run(test(["load_key_certs_crls_memfail", "count", srctop_file("test", "certs", "servercert.pem")], stderr => "$resultdir/load_key_certs_crls_countinfo.txt")); sub get_count_info { @@ -57,11 +55,9 @@ sub get_count_info { my ($hsskipcount, $hsmalloccount) = get_count_info("$resultdir/hscountinfo.txt"); -my ($x509skipcount, $x509malloccount) = get_count_info("$resultdir/x509countinfo.txt"); - my ($load_key_certs_crls_skipcount, $load_key_certs_crls_malloccount) = get_count_info("$resultdir/load_key_certs_crls_countinfo.txt"); -my $total_malloccount = $hsmalloccount + $x509malloccount +my $total_malloccount = $hsmalloccount + $load_key_certs_crls_malloccount; plan skip_all => "could not get malloc counts (one or more count runs failed or output format changed)" if $total_malloccount == 0; @@ -94,6 +90,4 @@ sub run_memfail_test { run_memfail_test($hsskipcount, $hsmalloccount, ["handshake-memfail", "run", srctop_dir("test", "certs")]); -run_memfail_test($x509skipcount, $x509malloccount, ["x509-memfail", "run", srctop_file("test", "certs", "servercert.pem")]); - run_memfail_test($load_key_certs_crls_skipcount, $load_key_certs_crls_malloccount, ["load_key_certs_crls_memfail", "run", srctop_file("test", "certs", "servercert.pem")]); diff --git a/test/recipes/90-test_store.t b/test/recipes/90-test_store.t index cb3289d07733e..ea9e7fa321fee 100644 --- a/test/recipes/90-test_store.t +++ b/test/recipes/90-test_store.t @@ -519,8 +519,8 @@ sub runall { return 1; } -# According to RFC8089, a relative file: path is invalid. We still produce -# them for testing purposes. +# According to RFC8089, a relative file: path is invalid. +# We still support them and produce them here for testing purposes. sub to_file_uri { my ($file, $isdir, $authority) = @_; my $vol; diff --git a/test/recipes/95-test_external_krb5_data/patches/0001-Use-Accessors-for-ASN1_STRING-values-from-OpenSSL.patch b/test/recipes/95-test_external_krb5_data/patches/0001-Use-Accessors-for-ASN1_STRING-values-from-OpenSSL.patch index c571f0ea3ab34..7ce8b8689a2ae 100644 --- a/test/recipes/95-test_external_krb5_data/patches/0001-Use-Accessors-for-ASN1_STRING-values-from-OpenSSL.patch +++ b/test/recipes/95-test_external_krb5_data/patches/0001-Use-Accessors-for-ASN1_STRING-values-from-OpenSSL.patch @@ -10,8 +10,8 @@ structure. https://github.com/openssl/openssl/issues/29117 --- - .../preauth/pkinit/pkinit_crypto_openssl.c | 16 +++++++++------- - 1 file changed, 9 insertions(+), 7 deletions(-) + .../preauth/pkinit/pkinit_crypto_openssl.c | 18 +++++++++++------- + 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c index d1fe18e5a..14e060de8 100644 @@ -47,20 +47,25 @@ index d1fe18e5a..14e060de8 100644 if (princs != NULL && OBJ_cmp(plgctx->id_pkinit_san, gen->d.otherName->type_id) == 0) { -@@ -2414,12 +2415,13 @@ crypto_retrieve_X509_sans(krb5_context context, +@@ -2414,12 +2415,17 @@ crypto_retrieve_X509_sans(krb5_context context, case GEN_DNS: if (dnss != NULL) { ++ if (ASN1_STRING_length(gen->d.dNSName) == 0) ++ break; /* Prevent abuse of embedded null characters. */ - if (memchr(gen->d.dNSName->data, '\0', gen->d.dNSName->length)) + if (memchr(ASN1_STRING_get0_data(gen->d.dNSName), '\0', + ASN1_STRING_length(gen->d.dNSName))) break; - pkiDebug("%s: found dns name = %s\n", __FUNCTION__, +- pkiDebug("%s: found dns name = %s\n", __FUNCTION__, - gen->d.dNSName->data); ++ pkiDebug("%s: found dns name = %.*s\n", __FUNCTION__, ++ (int)ASN1_STRING_length(gen->d.dNSName), + ASN1_STRING_get0_data(gen->d.dNSName)); dnss[d] = (unsigned char *) - strdup((char *)gen->d.dNSName->data); -+ strdup((char *)ASN1_STRING_get0_data(gen->d.dNSName)); ++ strndup((char *)ASN1_STRING_get0_data(gen->d.dNSName), ++ ASN1_STRING_length(gen->d.dNSName)); if (dnss[d] == NULL) { pkiDebug("%s: failed to duplicate dns name\n", __FUNCTION__); diff --git a/test/recipes/95-test_external_pkcs11_provider_data/pkcs11-provider.sh b/test/recipes/95-test_external_pkcs11_provider_data/pkcs11-provider.sh index 1b49ca933fec4..f75f1260a039a 100755 --- a/test/recipes/95-test_external_pkcs11_provider_data/pkcs11-provider.sh +++ b/test/recipes/95-test_external_pkcs11_provider_data/pkcs11-provider.sh @@ -85,13 +85,10 @@ echo "Running tests" echo "------------------------------------------------------------------" # For maintenance reasons and simplicity we only run test with kryoptic token -meson test -C $PKCS11_PROVIDER_BUILDDIR --suite=kryoptic +meson test -C $PKCS11_PROVIDER_BUILDDIR --print-errorlogs --suite=kryoptic -if [ $? -ne 0 ]; then - cat $PKCS11_PROVIDER_BUILDDIR/meson-logs/testlog.txt - exit 1 -fi +RESULT=$? rm -rf $PKCS11_PROVIDER_BUILDDIR -exit 0 +exit $RESULT diff --git a/test/recipes/95-test_external_pyca.t b/test/recipes/95-test_external_pyca.t index fe1d3f127a122..c93645a106adf 100644 --- a/test/recipes/95-test_external_pyca.t +++ b/test/recipes/95-test_external_pyca.t @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -22,9 +22,6 @@ plan skip_all => "PYCA Cryptography not available" plan skip_all => "PYCA tests only available in a shared build" if disabled("shared"); -# Temporariy disable this test until PYCA Cryptography works with 4.0 -plan skip_all => "PYCA Cryptography needs updating"; - plan tests => 1; ok(run(cmd(["sh", data_file("cryptography.sh")])), diff --git a/test/recipes/95-test_external_pyca_data/cryptography.sh b/test/recipes/95-test_external_pyca_data/cryptography.sh index 18d93f539442f..ee2da3bc02bef 100755 --- a/test/recipes/95-test_external_pyca_data/cryptography.sh +++ b/test/recipes/95-test_external_pyca_data/cryptography.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. # Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use @@ -19,6 +19,10 @@ O_BINC=`pwd`/$BLDTOP/include O_SINC=`pwd`/$SRCTOP/include O_LIB=`pwd`/$BLDTOP +: "${PYTHON_CMD=python3}" +: "${VENV_CMD=${PYTHON_CMD} -m venv}" +: "${INSTALLTOP=$(pwd)/${BLDTOP}/venv-cryptography/.local}" + export PATH=$O_EXE:$PATH export LD_LIBRARY_PATH=$O_LIB:$LD_LIBRARY_PATH @@ -30,14 +34,26 @@ echo "Testing OpenSSL using Python Cryptography:" echo " CWD: $PWD" echo " SRCTOP: $SRCTOP" echo " BLDTOP: $BLDTOP" +echo " INSTALLTOP: $INSTALLTOP" +echo " Python command: $PYTHON_CMD" +echo " venv command: $VENV_CMD" echo " OpenSSL version: $OPENSSL_VERSION" echo "------------------------------------------------------------------" -cd $SRCTOP +cd $BLDTOP -# Create a python virtual env and activate +# Create a python virtual env rm -rf venv-cryptography -python -m venv venv-cryptography +${VENV_CMD} venv-cryptography + +# Construct "installed" header directory +find "$O_SINC" "$O_BINC" -name '*.h' -printf '%p %P\n' \ + | while read -r from to; do + mkdir -p "$(dirname "$INSTALLTOP/include/$to")" + ln -sf "$from" "$INSTALLTOP/include/$to" + done + +# Activate the python virtual env . ./venv-cryptography/bin/activate # Upgrade pip to always have latest pip install -U pip @@ -47,8 +63,10 @@ cd pyca-cryptography echo "------------------------------------------------------------------" echo "Building cryptography and installing test requirements" echo "------------------------------------------------------------------" -LDFLAGS="-L$O_LIB" CFLAGS="-I$O_BINC -I$O_SINC " pip install .[test] -pip install -e vectors +OPENSSL_LIB_DIR="$O_LIB" OPENSSL_INCLUDE_DIR="$INSTALLTOP/include/" pip install . --group test +# Replace the PyPI cryptography_vectors with the in-tree one so the +# versions match when the submodule is not pinned at a PyPI release +pip install ./vectors echo "------------------------------------------------------------------" echo "Print linked libraries" diff --git a/test/recipes/99-test_fuzz_cms_verify.t b/test/recipes/99-test_fuzz_cms_verify.t new file mode 100644 index 0000000000000..c29f33e7a9dd6 --- /dev/null +++ b/test/recipes/99-test_fuzz_cms_verify.t @@ -0,0 +1,25 @@ +#!/usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use OpenSSL::Test qw/:DEFAULT srctop_file/; +use OpenSSL::Test::Utils; + +my $fuzzer = "cms_verify"; +setup("test_fuzz_${fuzzer}"); + +plan skip_all => "This test requires cms support" + if disabled("cms"); + +plan tests => 2; # one more due to below require_ok(...) + +require_ok(srctop_file('test','recipes','fuzz.pl')); + +fuzz_ok($fuzzer); diff --git a/test/recipes/99-test_fuzz_echconfiglist_parser.t b/test/recipes/99-test_fuzz_echconfiglist_parser.t new file mode 100644 index 0000000000000..09e115caa6585 --- /dev/null +++ b/test/recipes/99-test_fuzz_echconfiglist_parser.t @@ -0,0 +1,25 @@ +#!/usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use OpenSSL::Test qw/:DEFAULT srctop_file/; +use OpenSSL::Test::Utils; + +my $fuzzer = "echconfiglist_parser"; +setup("test_fuzz_${fuzzer}"); + +plan skip_all => "This test requires ech support" + if disabled("ech"); + +plan tests => 2; # one more due to below require_ok(...) + +require_ok(srctop_file('test','recipes','fuzz.pl')); + +fuzz_ok($fuzzer); diff --git a/test/recipes/99-test_fuzz_pkcs7_verify.t b/test/recipes/99-test_fuzz_pkcs7_verify.t new file mode 100644 index 0000000000000..cbd50399f59cd --- /dev/null +++ b/test/recipes/99-test_fuzz_pkcs7_verify.t @@ -0,0 +1,22 @@ +#!/usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use OpenSSL::Test qw/:DEFAULT srctop_file/; +use OpenSSL::Test::Utils; + +my $fuzzer = "pkcs7_verify"; +setup("test_fuzz_${fuzzer}"); + +plan tests => 2; # one more due to below require_ok(...) + +require_ok(srctop_file('test','recipes','fuzz.pl')); + +fuzz_ok($fuzzer); diff --git a/test/recipes/99-test_fuzz_x509v3.t b/test/recipes/99-test_fuzz_x509v3.t new file mode 100755 index 0000000000000..08e8a179ba39f --- /dev/null +++ b/test/recipes/99-test_fuzz_x509v3.t @@ -0,0 +1,22 @@ +#!/usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use OpenSSL::Test qw/:DEFAULT srctop_file/; +use OpenSSL::Test::Utils; + +my $fuzzer = "x509v3"; +setup("test_fuzz_${fuzzer}"); + +plan tests => 2; # one more due to below require_ok(...) + +require_ok(srctop_file('test','recipes','fuzz.pl')); + +fuzz_ok($fuzzer); diff --git a/test/rio_poll_builder_test.c b/test/rio_poll_builder_test.c new file mode 100644 index 0000000000000..f4acb7b9c20ba --- /dev/null +++ b/test/rio_poll_builder_test.c @@ -0,0 +1,45 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "../ssl/rio/poll_builder.h" +#include "testutil.h" + +static int test_duplicate_fd(void) +{ +#if RIO_POLL_METHOD == RIO_POLL_METHOD_POLL + RIO_POLL_BUILDER rpb; + struct pollfd *pfds; + int ret = 0; + + if (!TEST_true(ossl_rio_poll_builder_init(&rpb))) + return 0; + + if (!TEST_true(ossl_rio_poll_builder_add_fd(&rpb, 0, 1, 0)) + || !TEST_true(ossl_rio_poll_builder_add_fd(&rpb, 0, 0, 1))) + goto out; + + pfds = rpb.pfd_heap != NULL ? rpb.pfd_heap : rpb.pfds; + if (!TEST_size_t_eq(rpb.pfd_num, 1) + || !TEST_int_eq(pfds[0].events, POLLIN | POLLOUT)) + goto out; + + ret = 1; +out: + ossl_rio_poll_builder_cleanup(&rpb); + return ret; +#else + return TEST_skip("poll() backend is not in use"); +#endif +} + +int setup_tests(void) +{ + ADD_TEST(test_duplicate_fd); + return 1; +} diff --git a/test/rpktest.c b/test/rpktest.c index 98be18b3a6f79..a4d94b1c45601 100644 --- a/test/rpktest.c +++ b/test/rpktest.c @@ -1,5 +1,5 @@ /* - * Copyright 2023-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2023-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -38,6 +38,37 @@ static OSSL_PROVIDER *defctxnull = NULL; static const unsigned char cert_type_rpk[] = { TLSEXT_cert_type_rpk, TLSEXT_cert_type_x509 }; static const unsigned char SID_CTX[] = { 'r', 'p', 'k' }; +/* + * Wire form of a SignatureSchemeList that lists rsa_pkcs1_sha256 + * and ed448 -- between them they cover the issuer signature on + * every cert this file loads from test/certs + * (sha256WithRSAEncryption for the RSA/ECDSA/Ed25519 leaves and + * ED448 for the Ed448 leaf), so the extension is harmless when + * the handshake is non-RPK and the server's check_cert_usable() + * has to walk the list against a real cert. When RPK is + * negotiated check_cert_usable() returns early without inspecting + * the list, and when the slot is an RPK-listed key-only slot but + * X509 was negotiated check_cert_usable() returns 0 on the x == + * NULL path -- the inevitable outcome, now discovered earlier. + * + * Payload: length, rsa_pkcs1_sha256, ed448 + */ +static const unsigned char sigalgs_cert_payload[] = { + 0x00, 0x04, + 0x04, 0x01, + 0x08, 0x08 +}; + +static int sigalgs_cert_add_cb(SSL *s, unsigned int ext_type, + unsigned int context, + const unsigned char **out, size_t *outlen, + X509 *x, size_t chainidx, int *al, void *add_arg) +{ + *out = sigalgs_cert_payload; + *outlen = sizeof(sigalgs_cert_payload); + return 1; +} + static int rpk_verify_client_cb(int ok, X509_STORE_CTX *ctx) { int err = X509_STORE_CTX_get_error(ctx); @@ -255,18 +286,43 @@ static int test_rpk(int idx) /* NEW */ SSL_CTX_set_verify(cctx, SSL_VERIFY_PEER, rpk_verify_client_cb); - if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, - NULL, NULL))) + /* + * Send signature_algorithms_cert in every ClientHello, and in + * every TLS 1.3 CertificateRequest. The OpenSSL stack doesn't + * construct this extension by default in either direction, so + * register a custom add hook on both ends. This exercises the + * three distinct paths through check_cert_usable() on whichever + * side receives the extension: + * - RPK was negotiated for this side's cert -- early return 1, + * list contents ignored. + * - RPK was offered but X509 was negotiated and this side's + * slot holds only a private key -- x == NULL, return 0 + * (any peer-sent signature_algorithms_cert against a key-only + * slot would otherwise trigger a crash). + * - X509 negotiated with a real cert -- walk the list, find + * a match against the issuer's signature algorithm. + * The server's registration only fires on TLS 1.3 connections + * where the server requests a client certificate (case 2, 9, + * 10 etc.); on TLS 1.2 the sigalgs travel inside the + * CertificateRequest body, not as a separate extension. + */ + if (!TEST_true(SSL_CTX_add_custom_ext(cctx, + TLSEXT_TYPE_signature_algorithms_cert, + SSL_EXT_CLIENT_HELLO, + sigalgs_cert_add_cb, NULL, NULL, + NULL, NULL)) + || !TEST_true(SSL_CTX_add_custom_ext(sctx, + TLSEXT_TYPE_signature_algorithms_cert, + SSL_EXT_TLS1_3_CERTIFICATE_REQUEST, + sigalgs_cert_add_cb, NULL, NULL, + NULL, NULL)) + || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + || !TEST_int_gt(SSL_dane_enable(serverssl, NULL), 0) + || !TEST_int_gt(SSL_dane_enable(clientssl, "example.com"), 0) + || !TEST_int_eq(SSL_use_PrivateKey_file(serverssl, privkey_file, SSL_FILETYPE_PEM), 1)) goto end; - if (!TEST_int_gt(SSL_dane_enable(serverssl, NULL), 0)) - goto end; - if (!TEST_int_gt(SSL_dane_enable(clientssl, "example.com"), 0)) - goto end; - - /* Set private key and certificate */ - if (!TEST_int_eq(SSL_use_PrivateKey_file(serverssl, privkey_file, SSL_FILETYPE_PEM), 1)) - goto end; /* Only a private key */ if (idx == 1) { if (idx_server_server_rpk == 0 || idx_client_server_rpk == 0) { diff --git a/test/rsa_test.c b/test/rsa_test.c index de2966b2a22b0..46bed1ae68aae 100644 --- a/test/rsa_test.c +++ b/test/rsa_test.c @@ -1,5 +1,5 @@ /* - * Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/run_tests.pl b/test/run_tests.pl index f31c181a3da0f..4ba3553c8281f 100644 --- a/test/run_tests.pl +++ b/test/run_tests.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/test/secmemtest.c b/test/secmemtest.c index b0ac91a38f6a1..8bac1be2eca0b 100644 --- a/test/secmemtest.c +++ b/test/secmemtest.c @@ -1,5 +1,5 @@ /* - * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2015-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/simpledynamic.c b/test/simpledynamic.c index 5918797cd6a15..530577d0526e3 100644 --- a/test/simpledynamic.c +++ b/test/simpledynamic.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/siphash_internal_test.c b/test/siphash_internal_test.c index 6ea87d9b9cc6b..b00b94a2c312f 100644 --- a/test/siphash_internal_test.c +++ b/test/siphash_internal_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/sparse_array_test.c b/test/sparse_array_test.c index b41b50902c191..4fe1fef7aa88e 100644 --- a/test/sparse_array_test.c +++ b/test/sparse_array_test.c @@ -36,7 +36,7 @@ static int test_sparse_array(void) { INT_MAX, "m" }, { 6666666, "d" }, { (ossl_uintmax_t)-1, "H" }, { 99, "e" } }; - SPARSE_ARRAY_OF(char) * sa; + SPARSE_ARRAY_OF(char) *sa; size_t i, j; int res = 0; @@ -101,7 +101,7 @@ struct index_cases_st { }; struct doall_st { - SPARSE_ARRAY_OF(char) * sa; + SPARSE_ARRAY_OF(char) *sa; size_t num_cases; const struct index_cases_st *cases; int res; diff --git a/test/srptest.c b/test/srptest.c index 0fceadd24b3a6..0954ae35e126b 100644 --- a/test/srptest.c +++ b/test/srptest.c @@ -1,5 +1,5 @@ /* - * Copyright 2011-2021 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2011-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -149,11 +149,10 @@ static int run_srp_kat(void) /* use builtin 1024-bit params */ const SRP_gN *GN; - if (!TEST_ptr(GN = SRP_get_default_gN("1024"))) - goto err; - BN_hex2bn(&s, "BEB25379D1A8581EB5A727673A2441EE"); - /* Set up server's password entry */ - if (!TEST_true(SRP_create_verifier_BN("alice", "password123", &s, &v, GN->N, + if (!TEST_ptr(GN = SRP_get_default_gN("1024")) + || !TEST_true(BN_hex2bn(&s, "BEB25379D1A8581EB5A727673A2441EE")) + /* Set up server's password entry */ + || !TEST_true(SRP_create_verifier_BN("alice", "password123", &s, &v, GN->N, GN->g))) goto err; @@ -168,8 +167,9 @@ static int run_srp_kat(void) TEST_note(" okay"); /* Server random */ - BN_hex2bn(&b, "E487CB59D31AC550471E81F00F6928E01DDA08E974A004F49E61F5D1" - "05284D20"); + if (!TEST_true(BN_hex2bn(&b, "E487CB59D31AC550471E81F00F6928E01DDA08E974A004F49E61F5D1" + "05284D20"))) + goto err; /* Server's first message */ Bpub = SRP_Calc_B(b, GN->N, GN->g, v); @@ -187,8 +187,9 @@ static int run_srp_kat(void) TEST_note(" okay"); /* Client random */ - BN_hex2bn(&a, "60975527035CF2AD1989806F0407210BC81EDC04E2762A56AFD529DD" - "DA2D4393"); + if (!TEST_true(BN_hex2bn(&a, "60975527035CF2AD1989806F0407210BC81EDC04E2762A56AFD529DD" + "DA2D4393"))) + goto err; /* Client's response */ Apub = SRP_Calc_A(a, GN->N, GN->g); diff --git a/test/ssl-tests/02-protocol-version.cnf b/test/ssl-tests/02-protocol-version.cnf index 8fc30f90877b7..ec29e8bc1727d 100644 --- a/test/ssl-tests/02-protocol-version.cnf +++ b/test/ssl-tests/02-protocol-version.cnf @@ -363,8 +363,8 @@ test-357 = 357-version-negotiation test-358 = 358-version-negotiation test-359 = 359-version-negotiation test-360 = 360-version-negotiation -test-361 = 361-ciphersuite-sanity-check-client -test-362 = 362-ciphersuite-sanity-check-server +test-361 = 361-ciphersuite-sanity-check-tls-client +test-362 = 362-ciphersuite-sanity-check-tls-server # =========================================================== [0-version-negotiation] @@ -10013,20 +10013,20 @@ ExpectedResult = Success # =========================================================== -[361-ciphersuite-sanity-check-client] -ssl_conf = 361-ciphersuite-sanity-check-client-ssl +[361-ciphersuite-sanity-check-tls-client] +ssl_conf = 361-ciphersuite-sanity-check-tls-client-ssl -[361-ciphersuite-sanity-check-client-ssl] -server = 361-ciphersuite-sanity-check-client-server -client = 361-ciphersuite-sanity-check-client-client +[361-ciphersuite-sanity-check-tls-client-ssl] +server = 361-ciphersuite-sanity-check-tls-client-server +client = 361-ciphersuite-sanity-check-tls-client-client -[361-ciphersuite-sanity-check-client-server] +[361-ciphersuite-sanity-check-tls-client-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[361-ciphersuite-sanity-check-client-client] +[361-ciphersuite-sanity-check-tls-client-client] CipherString = AES128-SHA Ciphersuites = VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem @@ -10034,24 +10034,25 @@ VerifyMode = Peer [test-361] ExpectedResult = ClientFail +Method = TLS # =========================================================== -[362-ciphersuite-sanity-check-server] -ssl_conf = 362-ciphersuite-sanity-check-server-ssl +[362-ciphersuite-sanity-check-tls-server] +ssl_conf = 362-ciphersuite-sanity-check-tls-server-ssl -[362-ciphersuite-sanity-check-server-ssl] -server = 362-ciphersuite-sanity-check-server-server -client = 362-ciphersuite-sanity-check-server-client +[362-ciphersuite-sanity-check-tls-server-ssl] +server = 362-ciphersuite-sanity-check-tls-server-server +client = 362-ciphersuite-sanity-check-tls-server-client -[362-ciphersuite-sanity-check-server-server] +[362-ciphersuite-sanity-check-tls-server-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = AES128-SHA Ciphersuites = PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[362-ciphersuite-sanity-check-server-client] +[362-ciphersuite-sanity-check-tls-server-client] CipherString = AES128-SHA MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem @@ -10059,5 +10060,6 @@ VerifyMode = Peer [test-362] ExpectedResult = ServerFail +Method = TLS diff --git a/test/ssl-tests/07-dtls-protocol-version.cnf b/test/ssl-tests/07-dtls-protocol-version.cnf index 100036b3d1fc8..2980db64e98e8 100644 --- a/test/ssl-tests/07-dtls-protocol-version.cnf +++ b/test/ssl-tests/07-dtls-protocol-version.cnf @@ -1,6 +1,6 @@ # Generated with generate_ssl_tests.pl -num_tests = 64 +num_tests = 171 test-0 = 0-version-negotiation test-1 = 1-version-negotiation @@ -66,6 +66,113 @@ test-60 = 60-version-negotiation test-61 = 61-version-negotiation test-62 = 62-version-negotiation test-63 = 63-version-negotiation +test-64 = 64-version-negotiation +test-65 = 65-version-negotiation +test-66 = 66-version-negotiation +test-67 = 67-version-negotiation +test-68 = 68-version-negotiation +test-69 = 69-version-negotiation +test-70 = 70-version-negotiation +test-71 = 71-version-negotiation +test-72 = 72-version-negotiation +test-73 = 73-version-negotiation +test-74 = 74-version-negotiation +test-75 = 75-version-negotiation +test-76 = 76-version-negotiation +test-77 = 77-version-negotiation +test-78 = 78-version-negotiation +test-79 = 79-version-negotiation +test-80 = 80-version-negotiation +test-81 = 81-version-negotiation +test-82 = 82-version-negotiation +test-83 = 83-version-negotiation +test-84 = 84-version-negotiation +test-85 = 85-version-negotiation +test-86 = 86-version-negotiation +test-87 = 87-version-negotiation +test-88 = 88-version-negotiation +test-89 = 89-version-negotiation +test-90 = 90-version-negotiation +test-91 = 91-version-negotiation +test-92 = 92-version-negotiation +test-93 = 93-version-negotiation +test-94 = 94-version-negotiation +test-95 = 95-version-negotiation +test-96 = 96-version-negotiation +test-97 = 97-version-negotiation +test-98 = 98-version-negotiation +test-99 = 99-version-negotiation +test-100 = 100-version-negotiation +test-101 = 101-version-negotiation +test-102 = 102-version-negotiation +test-103 = 103-version-negotiation +test-104 = 104-version-negotiation +test-105 = 105-version-negotiation +test-106 = 106-version-negotiation +test-107 = 107-version-negotiation +test-108 = 108-version-negotiation +test-109 = 109-version-negotiation +test-110 = 110-version-negotiation +test-111 = 111-version-negotiation +test-112 = 112-version-negotiation +test-113 = 113-version-negotiation +test-114 = 114-version-negotiation +test-115 = 115-version-negotiation +test-116 = 116-version-negotiation +test-117 = 117-version-negotiation +test-118 = 118-version-negotiation +test-119 = 119-version-negotiation +test-120 = 120-version-negotiation +test-121 = 121-version-negotiation +test-122 = 122-version-negotiation +test-123 = 123-version-negotiation +test-124 = 124-version-negotiation +test-125 = 125-version-negotiation +test-126 = 126-version-negotiation +test-127 = 127-version-negotiation +test-128 = 128-version-negotiation +test-129 = 129-version-negotiation +test-130 = 130-version-negotiation +test-131 = 131-version-negotiation +test-132 = 132-version-negotiation +test-133 = 133-version-negotiation +test-134 = 134-version-negotiation +test-135 = 135-version-negotiation +test-136 = 136-version-negotiation +test-137 = 137-version-negotiation +test-138 = 138-version-negotiation +test-139 = 139-version-negotiation +test-140 = 140-version-negotiation +test-141 = 141-version-negotiation +test-142 = 142-version-negotiation +test-143 = 143-version-negotiation +test-144 = 144-version-negotiation +test-145 = 145-version-negotiation +test-146 = 146-version-negotiation +test-147 = 147-version-negotiation +test-148 = 148-version-negotiation +test-149 = 149-version-negotiation +test-150 = 150-version-negotiation +test-151 = 151-version-negotiation +test-152 = 152-version-negotiation +test-153 = 153-version-negotiation +test-154 = 154-version-negotiation +test-155 = 155-version-negotiation +test-156 = 156-version-negotiation +test-157 = 157-version-negotiation +test-158 = 158-version-negotiation +test-159 = 159-version-negotiation +test-160 = 160-version-negotiation +test-161 = 161-version-negotiation +test-162 = 162-version-negotiation +test-163 = 163-version-negotiation +test-164 = 164-version-negotiation +test-165 = 165-version-negotiation +test-166 = 166-version-negotiation +test-167 = 167-version-negotiation +test-168 = 168-version-negotiation +test-169 = 169-ciphersuite-sanity-check-dtls-client +test-170 = 170-ciphersuite-sanity-check-dtls-server # =========================================================== [0-version-negotiation] @@ -132,6 +239,7 @@ client = 2-version-negotiation-client [2-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [2-version-negotiation-client] @@ -158,8 +266,6 @@ client = 3-version-negotiation-client [3-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [3-version-negotiation-client] @@ -186,7 +292,7 @@ client = 4-version-negotiation-client [4-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem @@ -214,6 +320,7 @@ client = 5-version-negotiation-client [5-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem @@ -241,8 +348,8 @@ client = 6-version-negotiation-client [6-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [6-version-negotiation-client] @@ -252,7 +359,8 @@ VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-6] -ExpectedResult = ServerFail +ExpectedProtocol = DTLSv1 +ExpectedResult = Success Method = DTLS @@ -268,7 +376,7 @@ client = 7-version-negotiation-client [7-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1.2 +MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [7-version-negotiation-client] @@ -278,7 +386,8 @@ VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-7] -ExpectedResult = ServerFail +ExpectedProtocol = DTLSv1 +ExpectedResult = Success Method = DTLS @@ -294,18 +403,18 @@ client = 8-version-negotiation-client [8-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [8-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-8] -ExpectedProtocol = DTLSv1 -ExpectedResult = Success +ExpectedResult = ServerFail Method = DTLS @@ -321,18 +430,18 @@ client = 9-version-negotiation-client [9-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [9-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-9] -ExpectedProtocol = DTLSv1.2 -ExpectedResult = Success +ExpectedResult = ServerFail Method = DTLS @@ -348,17 +457,17 @@ client = 10-version-negotiation-client [10-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [10-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-10] -ExpectedProtocol = DTLSv1.2 -ExpectedResult = Success +ExpectedResult = ServerFail Method = DTLS @@ -374,19 +483,18 @@ client = 11-version-negotiation-client [11-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [11-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-11] -ExpectedProtocol = DTLSv1 -ExpectedResult = Success +ExpectedResult = ServerFail Method = DTLS @@ -402,19 +510,17 @@ client = 12-version-negotiation-client [12-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1 +MinProtocol = DTLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [12-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-12] -ExpectedProtocol = DTLSv1.2 -ExpectedResult = Success +ExpectedResult = ServerFail Method = DTLS @@ -430,7 +536,7 @@ client = 13-version-negotiation-client [13-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [13-version-negotiation-client] @@ -440,7 +546,7 @@ VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-13] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1 ExpectedResult = Success Method = DTLS @@ -458,7 +564,6 @@ client = 14-version-negotiation-client Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [14-version-negotiation-client] @@ -485,7 +590,7 @@ client = 15-version-negotiation-client [15-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [15-version-negotiation-client] @@ -512,16 +617,16 @@ client = 16-version-negotiation-client [16-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [16-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-16] -ExpectedProtocol = DTLSv1 +ExpectedProtocol = DTLSv1.2 ExpectedResult = Success Method = DTLS @@ -538,16 +643,18 @@ client = 17-version-negotiation-client [17-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [17-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-17] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1 ExpectedResult = Success Method = DTLS @@ -564,10 +671,13 @@ client = 18-version-negotiation-client [18-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [18-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer @@ -589,17 +699,18 @@ client = 19-version-negotiation-client [19-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [19-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-19] -ExpectedProtocol = DTLSv1 +ExpectedProtocol = DTLSv1.2 ExpectedResult = Success Method = DTLS @@ -616,12 +727,12 @@ client = 20-version-negotiation-client [20-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [20-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer @@ -643,11 +754,13 @@ client = 21-version-negotiation-client [21-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [21-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer @@ -669,12 +782,13 @@ client = 22-version-negotiation-client [22-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 +MaxProtocol = DTLSv1.3 MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [22-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer @@ -701,6 +815,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [23-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer @@ -722,19 +837,18 @@ client = 24-version-negotiation-client [24-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [24-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-24] -ExpectedProtocol = DTLSv1 -ExpectedResult = Success +ExpectedResult = ServerFail Method = DTLS @@ -750,19 +864,17 @@ client = 25-version-negotiation-client [25-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [25-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-25] -ExpectedProtocol = DTLSv1 -ExpectedResult = Success +ExpectedResult = ServerFail Method = DTLS @@ -778,12 +890,12 @@ client = 26-version-negotiation-client [26-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [26-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer @@ -805,19 +917,17 @@ client = 27-version-negotiation-client [27-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [27-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-27] -ExpectedProtocol = DTLSv1 +ExpectedProtocol = DTLSv1.2 ExpectedResult = Success Method = DTLS @@ -834,19 +944,17 @@ client = 28-version-negotiation-client [28-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [28-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-28] -ExpectedProtocol = DTLSv1 +ExpectedProtocol = DTLSv1.3 ExpectedResult = Success Method = DTLS @@ -863,18 +971,16 @@ client = 29-version-negotiation-client [29-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [29-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-29] -ExpectedProtocol = DTLSv1 +ExpectedProtocol = DTLSv1.3 ExpectedResult = Success Method = DTLS @@ -891,19 +997,19 @@ client = 30-version-negotiation-client [30-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [30-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-30] -ExpectedResult = ServerFail +ExpectedProtocol = DTLSv1 +ExpectedResult = Success Method = DTLS @@ -919,18 +1025,19 @@ client = 31-version-negotiation-client [31-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [31-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-31] -ExpectedResult = ServerFail +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success Method = DTLS @@ -946,18 +1053,18 @@ client = 32-version-negotiation-client [32-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [32-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-32] -ExpectedProtocol = DTLSv1 +ExpectedProtocol = DTLSv1.3 ExpectedResult = Success Method = DTLS @@ -974,18 +1081,17 @@ client = 33-version-negotiation-client [33-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [33-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-33] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1.3 ExpectedResult = Success Method = DTLS @@ -1002,12 +1108,13 @@ client = 34-version-negotiation-client [34-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [34-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer @@ -1029,19 +1136,18 @@ client = 35-version-negotiation-client [35-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [35-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-35] -ExpectedProtocol = DTLSv1 +ExpectedProtocol = DTLSv1.3 ExpectedResult = Success Method = DTLS @@ -1058,19 +1164,17 @@ client = 36-version-negotiation-client [36-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1 +MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [36-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-36] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1.3 ExpectedResult = Success Method = DTLS @@ -1087,18 +1191,18 @@ client = 37-version-negotiation-client [37-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [37-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-37] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1.3 ExpectedResult = Success Method = DTLS @@ -1115,19 +1219,17 @@ client = 38-version-negotiation-client [38-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 +MinProtocol = DTLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [38-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-38] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1.3 ExpectedResult = Success Method = DTLS @@ -1144,18 +1246,16 @@ client = 39-version-negotiation-client [39-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [39-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-39] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1 ExpectedResult = Success Method = DTLS @@ -1172,17 +1272,16 @@ client = 40-version-negotiation-client [40-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 +MaxProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [40-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-40] -ExpectedProtocol = DTLSv1 +ExpectedProtocol = DTLSv1.2 ExpectedResult = Success Method = DTLS @@ -1199,17 +1298,16 @@ client = 41-version-negotiation-client [41-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 +MaxProtocol = DTLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [41-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-41] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1.3 ExpectedResult = Success Method = DTLS @@ -1230,12 +1328,11 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [42-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-42] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1.3 ExpectedResult = Success Method = DTLS @@ -1258,7 +1355,6 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [43-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer @@ -1286,7 +1382,6 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [44-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer @@ -1308,17 +1403,17 @@ client = 45-version-negotiation-client [45-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [45-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-45] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1.3 ExpectedResult = Success Method = DTLS @@ -1335,18 +1430,16 @@ client = 46-version-negotiation-client [46-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 +MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [46-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-46] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1.3 ExpectedResult = Success Method = DTLS @@ -1363,12 +1456,12 @@ client = 47-version-negotiation-client [47-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [47-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer @@ -1390,18 +1483,18 @@ client = 48-version-negotiation-client [48-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [48-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-48] -ExpectedResult = ClientFail +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success Method = DTLS @@ -1417,18 +1510,16 @@ client = 49-version-negotiation-client [49-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [49-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-49] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1.3 ExpectedResult = Success Method = DTLS @@ -1445,17 +1536,17 @@ client = 50-version-negotiation-client [50-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [50-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-50] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1.3 ExpectedResult = Success Method = DTLS @@ -1472,19 +1563,17 @@ client = 51-version-negotiation-client [51-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 +MinProtocol = DTLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [51-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-51] -ExpectedResult = ClientFail +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success Method = DTLS @@ -1500,19 +1589,18 @@ client = 52-version-negotiation-client [52-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [52-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-52] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1 ExpectedResult = Success Method = DTLS @@ -1529,18 +1617,18 @@ client = 53-version-negotiation-client [53-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [53-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-53] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1 ExpectedResult = Success Method = DTLS @@ -1557,19 +1645,18 @@ client = 54-version-negotiation-client [54-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [54-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-54] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1 ExpectedResult = Success Method = DTLS @@ -1586,18 +1673,17 @@ client = 55-version-negotiation-client [55-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [55-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-55] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1 ExpectedResult = Success Method = DTLS @@ -1615,16 +1701,19 @@ client = 56-version-negotiation-client Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [56-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-56] -ExpectedResult = ClientFail +ExpectedProtocol = DTLSv1 +ExpectedResult = Success Method = DTLS @@ -1641,16 +1730,18 @@ client = 57-version-negotiation-client Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [57-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-57] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1 ExpectedResult = Success Method = DTLS @@ -1667,16 +1758,19 @@ client = 58-version-negotiation-client [58-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [58-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-58] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1 ExpectedResult = Success Method = DTLS @@ -1693,18 +1787,19 @@ client = 59-version-negotiation-client [59-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 MinProtocol = DTLSv1 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [59-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-59] -ExpectedResult = ClientFail +ExpectedProtocol = DTLSv1 +ExpectedResult = Success Method = DTLS @@ -1721,18 +1816,18 @@ client = 60-version-negotiation-client Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1 +MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [60-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-60] -ExpectedProtocol = DTLSv1.2 -ExpectedResult = Success +ExpectedResult = ServerFail Method = DTLS @@ -1748,18 +1843,19 @@ client = 61-version-negotiation-client [61-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [61-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-61] -ExpectedProtocol = DTLSv1.2 -ExpectedResult = Success +ExpectedResult = ServerFail Method = DTLS @@ -1775,19 +1871,18 @@ client = 62-version-negotiation-client [62-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 MinProtocol = DTLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [62-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-62] -ExpectedProtocol = DTLSv1.2 -ExpectedResult = Success +ExpectedResult = ServerFail Method = DTLS @@ -1803,18 +1898,2991 @@ client = 63-version-negotiation-client [63-version-negotiation-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [63-version-negotiation-client] CipherString = DEFAULT:@SECLEVEL=0 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-63] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[64-version-negotiation] +ssl_conf = 64-version-negotiation-ssl + +[64-version-negotiation-ssl] +server = 64-version-negotiation-server +client = 64-version-negotiation-client + +[64-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[64-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-64] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[65-version-negotiation] +ssl_conf = 65-version-negotiation-ssl + +[65-version-negotiation-ssl] +server = 65-version-negotiation-server +client = 65-version-negotiation-client + +[65-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[65-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-65] +ExpectedProtocol = DTLSv1 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[66-version-negotiation] +ssl_conf = 66-version-negotiation-ssl + +[66-version-negotiation-ssl] +server = 66-version-negotiation-server +client = 66-version-negotiation-client + +[66-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[66-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-66] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[67-version-negotiation] +ssl_conf = 67-version-negotiation-ssl + +[67-version-negotiation-ssl] +server = 67-version-negotiation-server +client = 67-version-negotiation-client + +[67-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[67-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-67] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[68-version-negotiation] +ssl_conf = 68-version-negotiation-ssl + +[68-version-negotiation-ssl] +server = 68-version-negotiation-server +client = 68-version-negotiation-client + +[68-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[68-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-68] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[69-version-negotiation] +ssl_conf = 69-version-negotiation-ssl + +[69-version-negotiation-ssl] +server = 69-version-negotiation-server +client = 69-version-negotiation-client + +[69-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[69-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-69] +ExpectedProtocol = DTLSv1 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[70-version-negotiation] +ssl_conf = 70-version-negotiation-ssl + +[70-version-negotiation-ssl] +server = 70-version-negotiation-server +client = 70-version-negotiation-client + +[70-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[70-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-70] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[71-version-negotiation] +ssl_conf = 71-version-negotiation-ssl + +[71-version-negotiation-ssl] +server = 71-version-negotiation-server +client = 71-version-negotiation-client + +[71-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[71-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-71] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[72-version-negotiation] +ssl_conf = 72-version-negotiation-ssl + +[72-version-negotiation-ssl] +server = 72-version-negotiation-server +client = 72-version-negotiation-client + +[72-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[72-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-72] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[73-version-negotiation] +ssl_conf = 73-version-negotiation-ssl + +[73-version-negotiation-ssl] +server = 73-version-negotiation-server +client = 73-version-negotiation-client + +[73-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[73-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-73] ExpectedProtocol = DTLSv1.2 ExpectedResult = Success Method = DTLS +# =========================================================== + +[74-version-negotiation] +ssl_conf = 74-version-negotiation-ssl + +[74-version-negotiation-ssl] +server = 74-version-negotiation-server +client = 74-version-negotiation-client + +[74-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[74-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-74] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[75-version-negotiation] +ssl_conf = 75-version-negotiation-ssl + +[75-version-negotiation-ssl] +server = 75-version-negotiation-server +client = 75-version-negotiation-client + +[75-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[75-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-75] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[76-version-negotiation] +ssl_conf = 76-version-negotiation-ssl + +[76-version-negotiation-ssl] +server = 76-version-negotiation-server +client = 76-version-negotiation-client + +[76-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[76-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-76] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[77-version-negotiation] +ssl_conf = 77-version-negotiation-ssl + +[77-version-negotiation-ssl] +server = 77-version-negotiation-server +client = 77-version-negotiation-client + +[77-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[77-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-77] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[78-version-negotiation] +ssl_conf = 78-version-negotiation-ssl + +[78-version-negotiation-ssl] +server = 78-version-negotiation-server +client = 78-version-negotiation-client + +[78-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[78-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-78] +ExpectedProtocol = DTLSv1 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[79-version-negotiation] +ssl_conf = 79-version-negotiation-ssl + +[79-version-negotiation-ssl] +server = 79-version-negotiation-server +client = 79-version-negotiation-client + +[79-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[79-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-79] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[80-version-negotiation] +ssl_conf = 80-version-negotiation-ssl + +[80-version-negotiation-ssl] +server = 80-version-negotiation-server +client = 80-version-negotiation-client + +[80-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[80-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-80] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[81-version-negotiation] +ssl_conf = 81-version-negotiation-ssl + +[81-version-negotiation-ssl] +server = 81-version-negotiation-server +client = 81-version-negotiation-client + +[81-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[81-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-81] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[82-version-negotiation] +ssl_conf = 82-version-negotiation-ssl + +[82-version-negotiation-ssl] +server = 82-version-negotiation-server +client = 82-version-negotiation-client + +[82-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[82-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-82] +ExpectedProtocol = DTLSv1 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[83-version-negotiation] +ssl_conf = 83-version-negotiation-ssl + +[83-version-negotiation-ssl] +server = 83-version-negotiation-server +client = 83-version-negotiation-client + +[83-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[83-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-83] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[84-version-negotiation] +ssl_conf = 84-version-negotiation-ssl + +[84-version-negotiation-ssl] +server = 84-version-negotiation-server +client = 84-version-negotiation-client + +[84-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[84-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-84] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[85-version-negotiation] +ssl_conf = 85-version-negotiation-ssl + +[85-version-negotiation-ssl] +server = 85-version-negotiation-server +client = 85-version-negotiation-client + +[85-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[85-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-85] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[86-version-negotiation] +ssl_conf = 86-version-negotiation-ssl + +[86-version-negotiation-ssl] +server = 86-version-negotiation-server +client = 86-version-negotiation-client + +[86-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[86-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-86] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[87-version-negotiation] +ssl_conf = 87-version-negotiation-ssl + +[87-version-negotiation-ssl] +server = 87-version-negotiation-server +client = 87-version-negotiation-client + +[87-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[87-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-87] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[88-version-negotiation] +ssl_conf = 88-version-negotiation-ssl + +[88-version-negotiation-ssl] +server = 88-version-negotiation-server +client = 88-version-negotiation-client + +[88-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[88-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-88] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[89-version-negotiation] +ssl_conf = 89-version-negotiation-ssl + +[89-version-negotiation-ssl] +server = 89-version-negotiation-server +client = 89-version-negotiation-client + +[89-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[89-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-89] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[90-version-negotiation] +ssl_conf = 90-version-negotiation-ssl + +[90-version-negotiation-ssl] +server = 90-version-negotiation-server +client = 90-version-negotiation-client + +[90-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[90-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-90] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[91-version-negotiation] +ssl_conf = 91-version-negotiation-ssl + +[91-version-negotiation-ssl] +server = 91-version-negotiation-server +client = 91-version-negotiation-client + +[91-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[91-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-91] +ExpectedProtocol = DTLSv1 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[92-version-negotiation] +ssl_conf = 92-version-negotiation-ssl + +[92-version-negotiation-ssl] +server = 92-version-negotiation-server +client = 92-version-negotiation-client + +[92-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[92-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-92] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[93-version-negotiation] +ssl_conf = 93-version-negotiation-ssl + +[93-version-negotiation-ssl] +server = 93-version-negotiation-server +client = 93-version-negotiation-client + +[93-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[93-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-93] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[94-version-negotiation] +ssl_conf = 94-version-negotiation-ssl + +[94-version-negotiation-ssl] +server = 94-version-negotiation-server +client = 94-version-negotiation-client + +[94-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[94-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-94] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[95-version-negotiation] +ssl_conf = 95-version-negotiation-ssl + +[95-version-negotiation-ssl] +server = 95-version-negotiation-server +client = 95-version-negotiation-client + +[95-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[95-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-95] +ExpectedProtocol = DTLSv1 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[96-version-negotiation] +ssl_conf = 96-version-negotiation-ssl + +[96-version-negotiation-ssl] +server = 96-version-negotiation-server +client = 96-version-negotiation-client + +[96-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[96-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-96] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[97-version-negotiation] +ssl_conf = 97-version-negotiation-ssl + +[97-version-negotiation-ssl] +server = 97-version-negotiation-server +client = 97-version-negotiation-client + +[97-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[97-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-97] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[98-version-negotiation] +ssl_conf = 98-version-negotiation-ssl + +[98-version-negotiation-ssl] +server = 98-version-negotiation-server +client = 98-version-negotiation-client + +[98-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[98-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-98] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[99-version-negotiation] +ssl_conf = 99-version-negotiation-ssl + +[99-version-negotiation-ssl] +server = 99-version-negotiation-server +client = 99-version-negotiation-client + +[99-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[99-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-99] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[100-version-negotiation] +ssl_conf = 100-version-negotiation-ssl + +[100-version-negotiation-ssl] +server = 100-version-negotiation-server +client = 100-version-negotiation-client + +[100-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[100-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-100] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[101-version-negotiation] +ssl_conf = 101-version-negotiation-ssl + +[101-version-negotiation-ssl] +server = 101-version-negotiation-server +client = 101-version-negotiation-client + +[101-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[101-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-101] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[102-version-negotiation] +ssl_conf = 102-version-negotiation-ssl + +[102-version-negotiation-ssl] +server = 102-version-negotiation-server +client = 102-version-negotiation-client + +[102-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[102-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-102] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[103-version-negotiation] +ssl_conf = 103-version-negotiation-ssl + +[103-version-negotiation-ssl] +server = 103-version-negotiation-server +client = 103-version-negotiation-client + +[103-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[103-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-103] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[104-version-negotiation] +ssl_conf = 104-version-negotiation-ssl + +[104-version-negotiation-ssl] +server = 104-version-negotiation-server +client = 104-version-negotiation-client + +[104-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[104-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-104] +ExpectedResult = ClientFail +Method = DTLS + + +# =========================================================== + +[105-version-negotiation] +ssl_conf = 105-version-negotiation-ssl + +[105-version-negotiation-ssl] +server = 105-version-negotiation-server +client = 105-version-negotiation-client + +[105-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[105-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-105] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[106-version-negotiation] +ssl_conf = 106-version-negotiation-ssl + +[106-version-negotiation-ssl] +server = 106-version-negotiation-server +client = 106-version-negotiation-client + +[106-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[106-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-106] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[107-version-negotiation] +ssl_conf = 107-version-negotiation-ssl + +[107-version-negotiation-ssl] +server = 107-version-negotiation-server +client = 107-version-negotiation-client + +[107-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[107-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-107] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[108-version-negotiation] +ssl_conf = 108-version-negotiation-ssl + +[108-version-negotiation-ssl] +server = 108-version-negotiation-server +client = 108-version-negotiation-client + +[108-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[108-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-108] +ExpectedResult = ClientFail +Method = DTLS + + +# =========================================================== + +[109-version-negotiation] +ssl_conf = 109-version-negotiation-ssl + +[109-version-negotiation-ssl] +server = 109-version-negotiation-server +client = 109-version-negotiation-client + +[109-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[109-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-109] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[110-version-negotiation] +ssl_conf = 110-version-negotiation-ssl + +[110-version-negotiation-ssl] +server = 110-version-negotiation-server +client = 110-version-negotiation-client + +[110-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[110-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-110] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[111-version-negotiation] +ssl_conf = 111-version-negotiation-ssl + +[111-version-negotiation-ssl] +server = 111-version-negotiation-server +client = 111-version-negotiation-client + +[111-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[111-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-111] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[112-version-negotiation] +ssl_conf = 112-version-negotiation-ssl + +[112-version-negotiation-ssl] +server = 112-version-negotiation-server +client = 112-version-negotiation-client + +[112-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[112-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-112] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[113-version-negotiation] +ssl_conf = 113-version-negotiation-ssl + +[113-version-negotiation-ssl] +server = 113-version-negotiation-server +client = 113-version-negotiation-client + +[113-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[113-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-113] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[114-version-negotiation] +ssl_conf = 114-version-negotiation-ssl + +[114-version-negotiation-ssl] +server = 114-version-negotiation-server +client = 114-version-negotiation-client + +[114-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[114-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-114] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[115-version-negotiation] +ssl_conf = 115-version-negotiation-ssl + +[115-version-negotiation-ssl] +server = 115-version-negotiation-server +client = 115-version-negotiation-client + +[115-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[115-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-115] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[116-version-negotiation] +ssl_conf = 116-version-negotiation-ssl + +[116-version-negotiation-ssl] +server = 116-version-negotiation-server +client = 116-version-negotiation-client + +[116-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[116-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-116] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[117-version-negotiation] +ssl_conf = 117-version-negotiation-ssl + +[117-version-negotiation-ssl] +server = 117-version-negotiation-server +client = 117-version-negotiation-client + +[117-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[117-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-117] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[118-version-negotiation] +ssl_conf = 118-version-negotiation-ssl + +[118-version-negotiation-ssl] +server = 118-version-negotiation-server +client = 118-version-negotiation-client + +[118-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[118-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-118] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[119-version-negotiation] +ssl_conf = 119-version-negotiation-ssl + +[119-version-negotiation-ssl] +server = 119-version-negotiation-server +client = 119-version-negotiation-client + +[119-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[119-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-119] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[120-version-negotiation] +ssl_conf = 120-version-negotiation-ssl + +[120-version-negotiation-ssl] +server = 120-version-negotiation-server +client = 120-version-negotiation-client + +[120-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[120-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-120] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[121-version-negotiation] +ssl_conf = 121-version-negotiation-ssl + +[121-version-negotiation-ssl] +server = 121-version-negotiation-server +client = 121-version-negotiation-client + +[121-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[121-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-121] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[122-version-negotiation] +ssl_conf = 122-version-negotiation-ssl + +[122-version-negotiation-ssl] +server = 122-version-negotiation-server +client = 122-version-negotiation-client + +[122-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[122-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-122] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[123-version-negotiation] +ssl_conf = 123-version-negotiation-ssl + +[123-version-negotiation-ssl] +server = 123-version-negotiation-server +client = 123-version-negotiation-client + +[123-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[123-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-123] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[124-version-negotiation] +ssl_conf = 124-version-negotiation-ssl + +[124-version-negotiation-ssl] +server = 124-version-negotiation-server +client = 124-version-negotiation-client + +[124-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[124-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-124] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[125-version-negotiation] +ssl_conf = 125-version-negotiation-ssl + +[125-version-negotiation-ssl] +server = 125-version-negotiation-server +client = 125-version-negotiation-client + +[125-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[125-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-125] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[126-version-negotiation] +ssl_conf = 126-version-negotiation-ssl + +[126-version-negotiation-ssl] +server = 126-version-negotiation-server +client = 126-version-negotiation-client + +[126-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[126-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-126] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[127-version-negotiation] +ssl_conf = 127-version-negotiation-ssl + +[127-version-negotiation-ssl] +server = 127-version-negotiation-server +client = 127-version-negotiation-client + +[127-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[127-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-127] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[128-version-negotiation] +ssl_conf = 128-version-negotiation-ssl + +[128-version-negotiation-ssl] +server = 128-version-negotiation-server +client = 128-version-negotiation-client + +[128-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[128-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-128] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[129-version-negotiation] +ssl_conf = 129-version-negotiation-ssl + +[129-version-negotiation-ssl] +server = 129-version-negotiation-server +client = 129-version-negotiation-client + +[129-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[129-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-129] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[130-version-negotiation] +ssl_conf = 130-version-negotiation-ssl + +[130-version-negotiation-ssl] +server = 130-version-negotiation-server +client = 130-version-negotiation-client + +[130-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[130-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-130] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[131-version-negotiation] +ssl_conf = 131-version-negotiation-ssl + +[131-version-negotiation-ssl] +server = 131-version-negotiation-server +client = 131-version-negotiation-client + +[131-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[131-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-131] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[132-version-negotiation] +ssl_conf = 132-version-negotiation-ssl + +[132-version-negotiation-ssl] +server = 132-version-negotiation-server +client = 132-version-negotiation-client + +[132-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[132-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-132] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[133-version-negotiation] +ssl_conf = 133-version-negotiation-ssl + +[133-version-negotiation-ssl] +server = 133-version-negotiation-server +client = 133-version-negotiation-client + +[133-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[133-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-133] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[134-version-negotiation] +ssl_conf = 134-version-negotiation-ssl + +[134-version-negotiation-ssl] +server = 134-version-negotiation-server +client = 134-version-negotiation-client + +[134-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[134-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-134] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[135-version-negotiation] +ssl_conf = 135-version-negotiation-ssl + +[135-version-negotiation-ssl] +server = 135-version-negotiation-server +client = 135-version-negotiation-client + +[135-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[135-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-135] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[136-version-negotiation] +ssl_conf = 136-version-negotiation-ssl + +[136-version-negotiation-ssl] +server = 136-version-negotiation-server +client = 136-version-negotiation-client + +[136-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[136-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-136] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[137-version-negotiation] +ssl_conf = 137-version-negotiation-ssl + +[137-version-negotiation-ssl] +server = 137-version-negotiation-server +client = 137-version-negotiation-client + +[137-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[137-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-137] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[138-version-negotiation] +ssl_conf = 138-version-negotiation-ssl + +[138-version-negotiation-ssl] +server = 138-version-negotiation-server +client = 138-version-negotiation-client + +[138-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[138-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-138] +ExpectedProtocol = DTLSv1.2 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[139-version-negotiation] +ssl_conf = 139-version-negotiation-ssl + +[139-version-negotiation-ssl] +server = 139-version-negotiation-server +client = 139-version-negotiation-client + +[139-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[139-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-139] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[140-version-negotiation] +ssl_conf = 140-version-negotiation-ssl + +[140-version-negotiation-ssl] +server = 140-version-negotiation-server +client = 140-version-negotiation-client + +[140-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[140-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-140] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[141-version-negotiation] +ssl_conf = 141-version-negotiation-ssl + +[141-version-negotiation-ssl] +server = 141-version-negotiation-server +client = 141-version-negotiation-client + +[141-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[141-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-141] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[142-version-negotiation] +ssl_conf = 142-version-negotiation-ssl + +[142-version-negotiation-ssl] +server = 142-version-negotiation-server +client = 142-version-negotiation-client + +[142-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[142-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-142] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[143-version-negotiation] +ssl_conf = 143-version-negotiation-ssl + +[143-version-negotiation-ssl] +server = 143-version-negotiation-server +client = 143-version-negotiation-client + +[143-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[143-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-143] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[144-version-negotiation] +ssl_conf = 144-version-negotiation-ssl + +[144-version-negotiation-ssl] +server = 144-version-negotiation-server +client = 144-version-negotiation-client + +[144-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[144-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-144] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[145-version-negotiation] +ssl_conf = 145-version-negotiation-ssl + +[145-version-negotiation-ssl] +server = 145-version-negotiation-server +client = 145-version-negotiation-client + +[145-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[145-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-145] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[146-version-negotiation] +ssl_conf = 146-version-negotiation-ssl + +[146-version-negotiation-ssl] +server = 146-version-negotiation-server +client = 146-version-negotiation-client + +[146-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[146-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-146] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[147-version-negotiation] +ssl_conf = 147-version-negotiation-ssl + +[147-version-negotiation-ssl] +server = 147-version-negotiation-server +client = 147-version-negotiation-client + +[147-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[147-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-147] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[148-version-negotiation] +ssl_conf = 148-version-negotiation-ssl + +[148-version-negotiation-ssl] +server = 148-version-negotiation-server +client = 148-version-negotiation-client + +[148-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[148-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-148] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[149-version-negotiation] +ssl_conf = 149-version-negotiation-ssl + +[149-version-negotiation-ssl] +server = 149-version-negotiation-server +client = 149-version-negotiation-client + +[149-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[149-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-149] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[150-version-negotiation] +ssl_conf = 150-version-negotiation-ssl + +[150-version-negotiation-ssl] +server = 150-version-negotiation-server +client = 150-version-negotiation-client + +[150-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[150-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-150] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[151-version-negotiation] +ssl_conf = 151-version-negotiation-ssl + +[151-version-negotiation-ssl] +server = 151-version-negotiation-server +client = 151-version-negotiation-client + +[151-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[151-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-151] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[152-version-negotiation] +ssl_conf = 152-version-negotiation-ssl + +[152-version-negotiation-ssl] +server = 152-version-negotiation-server +client = 152-version-negotiation-client + +[152-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[152-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-152] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[153-version-negotiation] +ssl_conf = 153-version-negotiation-ssl + +[153-version-negotiation-ssl] +server = 153-version-negotiation-server +client = 153-version-negotiation-client + +[153-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[153-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-153] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[154-version-negotiation] +ssl_conf = 154-version-negotiation-ssl + +[154-version-negotiation-ssl] +server = 154-version-negotiation-server +client = 154-version-negotiation-client + +[154-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[154-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-154] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[155-version-negotiation] +ssl_conf = 155-version-negotiation-ssl + +[155-version-negotiation-ssl] +server = 155-version-negotiation-server +client = 155-version-negotiation-client + +[155-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[155-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-155] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[156-version-negotiation] +ssl_conf = 156-version-negotiation-ssl + +[156-version-negotiation-ssl] +server = 156-version-negotiation-server +client = 156-version-negotiation-client + +[156-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[156-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-156] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[157-version-negotiation] +ssl_conf = 157-version-negotiation-ssl + +[157-version-negotiation-ssl] +server = 157-version-negotiation-server +client = 157-version-negotiation-client + +[157-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[157-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-157] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[158-version-negotiation] +ssl_conf = 158-version-negotiation-ssl + +[158-version-negotiation-ssl] +server = 158-version-negotiation-server +client = 158-version-negotiation-client + +[158-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[158-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-158] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[159-version-negotiation] +ssl_conf = 159-version-negotiation-ssl + +[159-version-negotiation-ssl] +server = 159-version-negotiation-server +client = 159-version-negotiation-client + +[159-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[159-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-159] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[160-version-negotiation] +ssl_conf = 160-version-negotiation-ssl + +[160-version-negotiation-ssl] +server = 160-version-negotiation-server +client = 160-version-negotiation-client + +[160-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[160-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-160] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[161-version-negotiation] +ssl_conf = 161-version-negotiation-ssl + +[161-version-negotiation-ssl] +server = 161-version-negotiation-server +client = 161-version-negotiation-client + +[161-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[161-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-161] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[162-version-negotiation] +ssl_conf = 162-version-negotiation-ssl + +[162-version-negotiation-ssl] +server = 162-version-negotiation-server +client = 162-version-negotiation-client + +[162-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[162-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-162] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[163-version-negotiation] +ssl_conf = 163-version-negotiation-ssl + +[163-version-negotiation-ssl] +server = 163-version-negotiation-server +client = 163-version-negotiation-client + +[163-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[163-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-163] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[164-version-negotiation] +ssl_conf = 164-version-negotiation-ssl + +[164-version-negotiation-ssl] +server = 164-version-negotiation-server +client = 164-version-negotiation-client + +[164-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[164-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-164] +ExpectedResult = ServerFail +Method = DTLS + + +# =========================================================== + +[165-version-negotiation] +ssl_conf = 165-version-negotiation-ssl + +[165-version-negotiation-ssl] +server = 165-version-negotiation-server +client = 165-version-negotiation-client + +[165-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[165-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-165] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[166-version-negotiation] +ssl_conf = 166-version-negotiation-ssl + +[166-version-negotiation-ssl] +server = 166-version-negotiation-server +client = 166-version-negotiation-client + +[166-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[166-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-166] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[167-version-negotiation] +ssl_conf = 167-version-negotiation-ssl + +[167-version-negotiation-ssl] +server = 167-version-negotiation-server +client = 167-version-negotiation-client + +[167-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[167-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-167] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[168-version-negotiation] +ssl_conf = 168-version-negotiation-ssl + +[168-version-negotiation-ssl] +server = 168-version-negotiation-server +client = 168-version-negotiation-client + +[168-version-negotiation-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[168-version-negotiation-client] +CipherString = DEFAULT:@SECLEVEL=0 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-168] +ExpectedProtocol = DTLSv1.3 +ExpectedResult = Success +Method = DTLS + + +# =========================================================== + +[169-ciphersuite-sanity-check-dtls-client] +ssl_conf = 169-ciphersuite-sanity-check-dtls-client-ssl + +[169-ciphersuite-sanity-check-dtls-client-ssl] +server = 169-ciphersuite-sanity-check-dtls-client-server +client = 169-ciphersuite-sanity-check-dtls-client-client + +[169-ciphersuite-sanity-check-dtls-client-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +MaxProtocol = DTLSv1.2 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[169-ciphersuite-sanity-check-dtls-client-client] +CipherString = AES128-SHA +Ciphersuites = +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-169] +ExpectedResult = ClientFail +Method = DTLS + + +# =========================================================== + +[170-ciphersuite-sanity-check-dtls-server] +ssl_conf = 170-ciphersuite-sanity-check-dtls-server-ssl + +[170-ciphersuite-sanity-check-dtls-server-ssl] +server = 170-ciphersuite-sanity-check-dtls-server-server +client = 170-ciphersuite-sanity-check-dtls-server-client + +[170-ciphersuite-sanity-check-dtls-server-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = AES128-SHA +Ciphersuites = +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[170-ciphersuite-sanity-check-dtls-server-client] +CipherString = AES128-SHA +MaxProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-170] +ExpectedResult = ServerFail +Method = DTLS + + diff --git a/test/ssl-tests/10-resumption.cnf b/test/ssl-tests/10-resumption.cnf index ca1f39a139da2..e016f498d8109 100644 --- a/test/ssl-tests/10-resumption.cnf +++ b/test/ssl-tests/10-resumption.cnf @@ -66,7 +66,7 @@ test-60 = 60-resumption test-61 = 61-resumption test-62 = 62-resumption test-63 = 63-resumption -test-64 = 64-resumption-with-hrr +test-64 = 64-tls13-resumption-with-hrr # =========================================================== [0-resumption] @@ -2405,27 +2405,27 @@ ResumptionExpected = Yes # =========================================================== -[64-resumption-with-hrr] -ssl_conf = 64-resumption-with-hrr-ssl +[64-tls13-resumption-with-hrr] +ssl_conf = 64-tls13-resumption-with-hrr-ssl -[64-resumption-with-hrr-ssl] -server = 64-resumption-with-hrr-server -client = 64-resumption-with-hrr-client -resume-server = 64-resumption-with-hrr-server -resume-client = 64-resumption-with-hrr-resume-client +[64-tls13-resumption-with-hrr-ssl] +server = 64-tls13-resumption-with-hrr-server +client = 64-tls13-resumption-with-hrr-client +resume-server = 64-tls13-resumption-with-hrr-server +resume-client = 64-tls13-resumption-with-hrr-resume-client -[64-resumption-with-hrr-server] +[64-tls13-resumption-with-hrr-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT Curves = P-256 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[64-resumption-with-hrr-client] +[64-tls13-resumption-with-hrr-client] CipherString = DEFAULT VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[64-resumption-with-hrr-resume-client] +[64-tls13-resumption-with-hrr-resume-client] CipherString = DEFAULT VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer diff --git a/test/ssl-tests/11-dtls_resumption.cnf b/test/ssl-tests/11-dtls_resumption.cnf index 424e3d425b0ee..9b29dd2f195d0 100644 --- a/test/ssl-tests/11-dtls_resumption.cnf +++ b/test/ssl-tests/11-dtls_resumption.cnf @@ -1,6 +1,6 @@ # Generated with generate_ssl_tests.pl -num_tests = 16 +num_tests = 37 test-0 = 0-resumption test-1 = 1-resumption @@ -18,6 +18,27 @@ test-12 = 12-resumption test-13 = 13-resumption test-14 = 14-resumption test-15 = 15-resumption +test-16 = 16-resumption +test-17 = 17-resumption +test-18 = 18-resumption +test-19 = 19-resumption +test-20 = 20-resumption +test-21 = 21-resumption +test-22 = 22-resumption +test-23 = 23-resumption +test-24 = 24-resumption +test-25 = 25-resumption +test-26 = 26-resumption +test-27 = 27-resumption +test-28 = 28-resumption +test-29 = 29-resumption +test-30 = 30-resumption +test-31 = 31-resumption +test-32 = 32-resumption +test-33 = 33-resumption +test-34 = 34-resumption +test-35 = 35-resumption +test-36 = 36-dtls13-resumption-with-hrr # =========================================================== [0-resumption] @@ -184,15 +205,15 @@ resume-client = 4-resumption-client [4-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [4-resumption-resume-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem @@ -202,7 +223,7 @@ VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-4] -ExpectedProtocol = DTLSv1 +ExpectedProtocol = DTLSv1.3 HandshakeMode = Resume Method = DTLS ResumptionExpected = No @@ -222,15 +243,15 @@ resume-client = 5-resumption-client [5-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [5-resumption-resume-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 +MaxProtocol = DTLSv1.3 Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem @@ -240,7 +261,7 @@ VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-5] -ExpectedProtocol = DTLSv1 +ExpectedProtocol = DTLSv1.3 HandshakeMode = Resume Method = DTLS ResumptionExpected = No @@ -268,7 +289,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [6-resumption-resume-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem @@ -278,10 +299,10 @@ VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-6] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1 HandshakeMode = Resume Method = DTLS -ResumptionExpected = Yes +ResumptionExpected = No # =========================================================== @@ -306,7 +327,7 @@ PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [7-resumption-resume-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 +MaxProtocol = DTLSv1 Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem @@ -316,10 +337,10 @@ VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-7] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1 HandshakeMode = Resume Method = DTLS -ResumptionExpected = Yes +ResumptionExpected = No # =========================================================== @@ -330,30 +351,31 @@ ssl_conf = 8-resumption-ssl [8-resumption-ssl] server = 8-resumption-server client = 8-resumption-client -resume-server = 8-resumption-server -resume-client = 8-resumption-resume-client +resume-server = 8-resumption-resume-server +resume-client = 8-resumption-client [8-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[8-resumption-client] +[8-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 -VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem -VerifyMode = Peer +MaxProtocol = DTLSv1.2 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[8-resumption-resume-client] +[8-resumption-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-8] -ExpectedProtocol = DTLSv1 +ExpectedProtocol = DTLSv1.2 HandshakeMode = Resume Method = DTLS ResumptionExpected = Yes @@ -367,30 +389,31 @@ ssl_conf = 9-resumption-ssl [9-resumption-ssl] server = 9-resumption-server client = 9-resumption-client -resume-server = 9-resumption-server -resume-client = 9-resumption-resume-client +resume-server = 9-resumption-resume-server +resume-client = 9-resumption-client [9-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[9-resumption-client] +[9-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 -VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem -VerifyMode = Peer +MaxProtocol = DTLSv1.2 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[9-resumption-resume-client] +[9-resumption-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-9] -ExpectedProtocol = DTLSv1 +ExpectedProtocol = DTLSv1.2 HandshakeMode = Resume Method = DTLS ResumptionExpected = Yes @@ -404,30 +427,31 @@ ssl_conf = 10-resumption-ssl [10-resumption-ssl] server = 10-resumption-server client = 10-resumption-client -resume-server = 10-resumption-server -resume-client = 10-resumption-resume-client +resume-server = 10-resumption-resume-server +resume-client = 10-resumption-client [10-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[10-resumption-client] +[10-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 -VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem -VerifyMode = Peer +MaxProtocol = DTLSv1.3 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[10-resumption-resume-client] +[10-resumption-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-10] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1.3 HandshakeMode = Resume Method = DTLS ResumptionExpected = No @@ -441,30 +465,31 @@ ssl_conf = 11-resumption-ssl [11-resumption-ssl] server = 11-resumption-server client = 11-resumption-client -resume-server = 11-resumption-server -resume-client = 11-resumption-resume-client +resume-server = 11-resumption-resume-server +resume-client = 11-resumption-client [11-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[11-resumption-client] +[11-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 -MinProtocol = DTLSv1 -VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem -VerifyMode = Peer +MaxProtocol = DTLSv1.3 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[11-resumption-resume-client] +[11-resumption-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer [test-11] -ExpectedProtocol = DTLSv1.2 +ExpectedProtocol = DTLSv1.3 HandshakeMode = Resume Method = DTLS ResumptionExpected = No @@ -478,25 +503,26 @@ ssl_conf = 12-resumption-ssl [12-resumption-ssl] server = 12-resumption-server client = 12-resumption-client -resume-server = 12-resumption-server -resume-client = 12-resumption-resume-client +resume-server = 12-resumption-resume-server +resume-client = 12-resumption-client [12-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[12-resumption-client] +[12-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 -VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem -VerifyMode = Peer +MaxProtocol = DTLSv1 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[12-resumption-resume-client] +[12-resumption-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer @@ -515,25 +541,26 @@ ssl_conf = 13-resumption-ssl [13-resumption-ssl] server = 13-resumption-server client = 13-resumption-client -resume-server = 13-resumption-server -resume-client = 13-resumption-resume-client +resume-server = 13-resumption-resume-server +resume-client = 13-resumption-client [13-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[13-resumption-client] +[13-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 -VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem -VerifyMode = Peer +MaxProtocol = DTLSv1 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[13-resumption-resume-client] +[13-resumption-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer @@ -552,25 +579,26 @@ ssl_conf = 14-resumption-ssl [14-resumption-ssl] server = 14-resumption-server client = 14-resumption-client -resume-server = 14-resumption-server -resume-client = 14-resumption-resume-client +resume-server = 14-resumption-resume-server +resume-client = 14-resumption-client [14-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 Options = SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[14-resumption-client] +[14-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 -VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem -VerifyMode = Peer +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[14-resumption-resume-client] +[14-resumption-client] CipherString = DEFAULT:@SECLEVEL=0 -MaxProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer @@ -578,7 +606,7 @@ VerifyMode = Peer ExpectedProtocol = DTLSv1.2 HandshakeMode = Resume Method = DTLS -ResumptionExpected = Yes +ResumptionExpected = No # =========================================================== @@ -589,32 +617,809 @@ ssl_conf = 15-resumption-ssl [15-resumption-ssl] server = 15-resumption-server client = 15-resumption-client -resume-server = 15-resumption-server -resume-client = 15-resumption-resume-client +resume-server = 15-resumption-resume-server +resume-client = 15-resumption-client [15-resumption-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 Options = -SessionTicket PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[15-resumption-client] +[15-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT:@SECLEVEL=0 MaxProtocol = DTLSv1.2 -MinProtocol = DTLSv1.2 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[15-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-15] +ExpectedProtocol = DTLSv1.2 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = No + + +# =========================================================== + +[16-resumption] +ssl_conf = 16-resumption-ssl + +[16-resumption-ssl] +server = 16-resumption-server +client = 16-resumption-client +resume-server = 16-resumption-resume-server +resume-client = 16-resumption-client + +[16-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[16-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[16-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-16] +ExpectedProtocol = DTLSv1.3 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = Yes + + +# =========================================================== + +[17-resumption] +ssl_conf = 17-resumption-ssl + +[17-resumption-ssl] +server = 17-resumption-server +client = 17-resumption-client +resume-server = 17-resumption-resume-server +resume-client = 17-resumption-client + +[17-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[17-resumption-resume-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[17-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-17] +ExpectedProtocol = DTLSv1.3 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = Yes + + +# =========================================================== + +[18-resumption] +ssl_conf = 18-resumption-ssl + +[18-resumption-ssl] +server = 18-resumption-server +client = 18-resumption-client +resume-server = 18-resumption-server +resume-client = 18-resumption-resume-client + +[18-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[18-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[18-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-18] +ExpectedProtocol = DTLSv1 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = Yes + + +# =========================================================== + +[19-resumption] +ssl_conf = 19-resumption-ssl + +[19-resumption-ssl] +server = 19-resumption-server +client = 19-resumption-client +resume-server = 19-resumption-server +resume-client = 19-resumption-resume-client + +[19-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[19-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[19-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-19] +ExpectedProtocol = DTLSv1 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = Yes + + +# =========================================================== + +[20-resumption] +ssl_conf = 20-resumption-ssl + +[20-resumption-ssl] +server = 20-resumption-server +client = 20-resumption-client +resume-server = 20-resumption-server +resume-client = 20-resumption-resume-client + +[20-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[20-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[15-resumption-resume-client] +[20-resumption-resume-client] CipherString = DEFAULT:@SECLEVEL=0 MaxProtocol = DTLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-15] +[test-20] ExpectedProtocol = DTLSv1.2 HandshakeMode = Resume Method = DTLS +ResumptionExpected = No + + +# =========================================================== + +[21-resumption] +ssl_conf = 21-resumption-ssl + +[21-resumption-ssl] +server = 21-resumption-server +client = 21-resumption-client +resume-server = 21-resumption-server +resume-client = 21-resumption-resume-client + +[21-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[21-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[21-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-21] +ExpectedProtocol = DTLSv1.2 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = No + + +# =========================================================== + +[22-resumption] +ssl_conf = 22-resumption-ssl + +[22-resumption-ssl] +server = 22-resumption-server +client = 22-resumption-client +resume-server = 22-resumption-server +resume-client = 22-resumption-resume-client + +[22-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[22-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[22-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-22] +ExpectedProtocol = DTLSv1.3 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = No + + +# =========================================================== + +[23-resumption] +ssl_conf = 23-resumption-ssl + +[23-resumption-ssl] +server = 23-resumption-server +client = 23-resumption-client +resume-server = 23-resumption-server +resume-client = 23-resumption-resume-client + +[23-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[23-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +MinProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[23-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-23] +ExpectedProtocol = DTLSv1.3 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = No + + +# =========================================================== + +[24-resumption] +ssl_conf = 24-resumption-ssl + +[24-resumption-ssl] +server = 24-resumption-server +client = 24-resumption-client +resume-server = 24-resumption-server +resume-client = 24-resumption-resume-client + +[24-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[24-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[24-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-24] +ExpectedProtocol = DTLSv1 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = No + + +# =========================================================== + +[25-resumption] +ssl_conf = 25-resumption-ssl + +[25-resumption-ssl] +server = 25-resumption-server +client = 25-resumption-client +resume-server = 25-resumption-server +resume-client = 25-resumption-resume-client + +[25-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[25-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[25-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-25] +ExpectedProtocol = DTLSv1 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = No + + +# =========================================================== + +[26-resumption] +ssl_conf = 26-resumption-ssl + +[26-resumption-ssl] +server = 26-resumption-server +client = 26-resumption-client +resume-server = 26-resumption-server +resume-client = 26-resumption-resume-client + +[26-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[26-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[26-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-26] +ExpectedProtocol = DTLSv1.2 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = Yes + + +# =========================================================== + +[27-resumption] +ssl_conf = 27-resumption-ssl + +[27-resumption-ssl] +server = 27-resumption-server +client = 27-resumption-client +resume-server = 27-resumption-server +resume-client = 27-resumption-resume-client + +[27-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[27-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[27-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-27] +ExpectedProtocol = DTLSv1.2 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = Yes + + +# =========================================================== + +[28-resumption] +ssl_conf = 28-resumption-ssl + +[28-resumption-ssl] +server = 28-resumption-server +client = 28-resumption-client +resume-server = 28-resumption-server +resume-client = 28-resumption-resume-client + +[28-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[28-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[28-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-28] +ExpectedProtocol = DTLSv1.3 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = No + + +# =========================================================== + +[29-resumption] +ssl_conf = 29-resumption-ssl + +[29-resumption-ssl] +server = 29-resumption-server +client = 29-resumption-client +resume-server = 29-resumption-server +resume-client = 29-resumption-resume-client + +[29-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[29-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +MinProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[29-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-29] +ExpectedProtocol = DTLSv1.3 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = No + + +# =========================================================== + +[30-resumption] +ssl_conf = 30-resumption-ssl + +[30-resumption-ssl] +server = 30-resumption-server +client = 30-resumption-client +resume-server = 30-resumption-server +resume-client = 30-resumption-resume-client + +[30-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[30-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[30-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-30] +ExpectedProtocol = DTLSv1 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = No + + +# =========================================================== + +[31-resumption] +ssl_conf = 31-resumption-ssl + +[31-resumption-ssl] +server = 31-resumption-server +client = 31-resumption-client +resume-server = 31-resumption-server +resume-client = 31-resumption-resume-client + +[31-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[31-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[31-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-31] +ExpectedProtocol = DTLSv1 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = No + + +# =========================================================== + +[32-resumption] +ssl_conf = 32-resumption-ssl + +[32-resumption-ssl] +server = 32-resumption-server +client = 32-resumption-client +resume-server = 32-resumption-server +resume-client = 32-resumption-resume-client + +[32-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[32-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[32-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-32] +ExpectedProtocol = DTLSv1.2 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = No + + +# =========================================================== + +[33-resumption] +ssl_conf = 33-resumption-ssl + +[33-resumption-ssl] +server = 33-resumption-server +client = 33-resumption-client +resume-server = 33-resumption-server +resume-client = 33-resumption-resume-client + +[33-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[33-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[33-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-33] +ExpectedProtocol = DTLSv1.2 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = No + + +# =========================================================== + +[34-resumption] +ssl_conf = 34-resumption-ssl + +[34-resumption-ssl] +server = 34-resumption-server +client = 34-resumption-client +resume-server = 34-resumption-server +resume-client = 34-resumption-resume-client + +[34-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[34-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[34-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-34] +ExpectedProtocol = DTLSv1.3 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = Yes + + +# =========================================================== + +[35-resumption] +ssl_conf = 35-resumption-ssl + +[35-resumption-ssl] +server = 35-resumption-server +client = 35-resumption-client +resume-server = 35-resumption-server +resume-client = 35-resumption-resume-client + +[35-resumption-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT:@SECLEVEL=0 +Options = -SessionTicket +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[35-resumption-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +MinProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[35-resumption-resume-client] +CipherString = DEFAULT:@SECLEVEL=0 +MaxProtocol = DTLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-35] +ExpectedProtocol = DTLSv1.3 +HandshakeMode = Resume +Method = DTLS +ResumptionExpected = Yes + + +# =========================================================== + +[36-dtls13-resumption-with-hrr] +ssl_conf = 36-dtls13-resumption-with-hrr-ssl + +[36-dtls13-resumption-with-hrr-ssl] +server = 36-dtls13-resumption-with-hrr-server +client = 36-dtls13-resumption-with-hrr-client +resume-server = 36-dtls13-resumption-with-hrr-server +resume-client = 36-dtls13-resumption-with-hrr-resume-client + +[36-dtls13-resumption-with-hrr-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT +Curves = P-256 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[36-dtls13-resumption-with-hrr-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[36-dtls13-resumption-with-hrr-resume-client] +CipherString = DEFAULT +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-36] +ExpectedProtocol = DTLSv1.3 +HandshakeMode = Resume +Method = DTLS ResumptionExpected = Yes diff --git a/test/ssl-tests/14-curves.cnf b/test/ssl-tests/14-curves.cnf index 5a215d5b4e355..1abfd62503746 100644 --- a/test/ssl-tests/14-curves.cnf +++ b/test/ssl-tests/14-curves.cnf @@ -1,6 +1,6 @@ # Generated with generate_ssl_tests.pl -num_tests = 119 +num_tests = 125 test-0 = 0-curve-prime256v1 test-1 = 1-curve-secp384r1 @@ -20,107 +20,113 @@ test-14 = 14-curve-SecP256r1MLKEM768 test-15 = 15-curve-SecP384r1MLKEM1024 test-16 = 16-curve-curveSM2 test-17 = 17-curve-curveSM2MLKEM768 -test-18 = 18-curve-sect233k1 -test-19 = 19-curve-sect233r1 -test-20 = 20-curve-sect283k1 -test-21 = 21-curve-sect283r1 -test-22 = 22-curve-sect409k1 -test-23 = 23-curve-sect409r1 -test-24 = 24-curve-sect571k1 -test-25 = 25-curve-sect571r1 -test-26 = 26-curve-secp224r1 -test-27 = 27-curve-sect163k1 -test-28 = 28-curve-sect163r2 -test-29 = 29-curve-prime192v1 -test-30 = 30-curve-sect163r1 -test-31 = 31-curve-sect193r1 -test-32 = 32-curve-sect193r2 -test-33 = 33-curve-sect239k1 -test-34 = 34-curve-secp160k1 -test-35 = 35-curve-secp160r1 -test-36 = 36-curve-secp160r2 -test-37 = 37-curve-secp192k1 -test-38 = 38-curve-secp224k1 -test-39 = 39-curve-secp256k1 -test-40 = 40-curve-brainpoolP256r1 -test-41 = 41-curve-brainpoolP384r1 -test-42 = 42-curve-brainpoolP512r1 -test-43 = 43-curve-sect233k1-tls12-in-tls13 -test-44 = 44-curve-sect233r1-tls12-in-tls13 -test-45 = 45-curve-sect283k1-tls12-in-tls13 -test-46 = 46-curve-sect283r1-tls12-in-tls13 -test-47 = 47-curve-sect409k1-tls12-in-tls13 -test-48 = 48-curve-sect409r1-tls12-in-tls13 -test-49 = 49-curve-sect571k1-tls12-in-tls13 -test-50 = 50-curve-sect571r1-tls12-in-tls13 -test-51 = 51-curve-secp224r1-tls12-in-tls13 -test-52 = 52-curve-sect163k1-tls12-in-tls13 -test-53 = 53-curve-sect163r2-tls12-in-tls13 -test-54 = 54-curve-prime192v1-tls12-in-tls13 -test-55 = 55-curve-sect163r1-tls12-in-tls13 -test-56 = 56-curve-sect193r1-tls12-in-tls13 -test-57 = 57-curve-sect193r2-tls12-in-tls13 -test-58 = 58-curve-sect239k1-tls12-in-tls13 -test-59 = 59-curve-secp160k1-tls12-in-tls13 -test-60 = 60-curve-secp160r1-tls12-in-tls13 -test-61 = 61-curve-secp160r2-tls12-in-tls13 -test-62 = 62-curve-secp192k1-tls12-in-tls13 -test-63 = 63-curve-secp224k1-tls12-in-tls13 -test-64 = 64-curve-secp256k1-tls12-in-tls13 -test-65 = 65-curve-brainpoolP256r1-tls12-in-tls13 -test-66 = 66-curve-brainpoolP384r1-tls12-in-tls13 -test-67 = 67-curve-brainpoolP512r1-tls12-in-tls13 -test-68 = 68-curve-sect233k1-tls13 -test-69 = 69-curve-sect233r1-tls13 -test-70 = 70-curve-sect283k1-tls13 -test-71 = 71-curve-sect283r1-tls13 -test-72 = 72-curve-sect409k1-tls13 -test-73 = 73-curve-sect409r1-tls13 -test-74 = 74-curve-sect571k1-tls13 -test-75 = 75-curve-sect571r1-tls13 -test-76 = 76-curve-secp224r1-tls13 -test-77 = 77-curve-sect163k1-tls13 -test-78 = 78-curve-sect163r2-tls13 -test-79 = 79-curve-prime192v1-tls13 -test-80 = 80-curve-sect163r1-tls13 -test-81 = 81-curve-sect193r1-tls13 -test-82 = 82-curve-sect193r2-tls13 -test-83 = 83-curve-sect239k1-tls13 -test-84 = 84-curve-secp160k1-tls13 -test-85 = 85-curve-secp160r1-tls13 -test-86 = 86-curve-secp160r2-tls13 -test-87 = 87-curve-secp192k1-tls13 -test-88 = 88-curve-secp224k1-tls13 -test-89 = 89-curve-secp256k1-tls13 -test-90 = 90-curve-brainpoolP256r1-tls13 -test-91 = 91-curve-brainpoolP384r1-tls13 -test-92 = 92-curve-brainpoolP512r1-tls13 -test-93 = 93-curve-ffdhe2048-tls13-in-tls12 -test-94 = 94-curve-ffdhe2048-tls13-in-tls12-2 -test-95 = 95-curve-ffdhe3072-tls13-in-tls12 -test-96 = 96-curve-ffdhe3072-tls13-in-tls12-2 -test-97 = 97-curve-ffdhe4096-tls13-in-tls12 -test-98 = 98-curve-ffdhe4096-tls13-in-tls12-2 -test-99 = 99-curve-ffdhe6144-tls13-in-tls12 -test-100 = 100-curve-ffdhe6144-tls13-in-tls12-2 -test-101 = 101-curve-ffdhe8192-tls13-in-tls12 -test-102 = 102-curve-ffdhe8192-tls13-in-tls12-2 -test-103 = 103-curve-brainpoolP256r1tls13-tls13-in-tls12 -test-104 = 104-curve-brainpoolP256r1tls13-tls13-in-tls12-2 -test-105 = 105-curve-brainpoolP384r1tls13-tls13-in-tls12 -test-106 = 106-curve-brainpoolP384r1tls13-tls13-in-tls12-2 -test-107 = 107-curve-brainpoolP512r1tls13-tls13-in-tls12 -test-108 = 108-curve-brainpoolP512r1tls13-tls13-in-tls12-2 -test-109 = 109-curve-X25519MLKEM768-tls13-in-tls12 -test-110 = 110-curve-X25519MLKEM768-tls13-in-tls12-2 -test-111 = 111-curve-SecP256r1MLKEM768-tls13-in-tls12 -test-112 = 112-curve-SecP256r1MLKEM768-tls13-in-tls12-2 -test-113 = 113-curve-SecP384r1MLKEM1024-tls13-in-tls12 -test-114 = 114-curve-SecP384r1MLKEM1024-tls13-in-tls12-2 -test-115 = 115-curve-curveSM2-tls13-in-tls12 -test-116 = 116-curve-curveSM2-tls13-in-tls12-2 -test-117 = 117-curve-curveSM2MLKEM768-tls13-in-tls12 -test-118 = 118-curve-curveSM2MLKEM768-tls13-in-tls12-2 +test-18 = 18-curve-MLKEM512X25519 +test-19 = 19-curve-SecP256r1MLKEM512 +test-20 = 20-curve-ffdhe2048 +test-21 = 21-curve-ffdhe3072 +test-22 = 22-curve-ffdhe4096 +test-23 = 23-curve-ffdhe6144 +test-24 = 24-curve-ffdhe8192 +test-25 = 25-curve-sect233k1 +test-26 = 26-curve-sect233r1 +test-27 = 27-curve-sect283k1 +test-28 = 28-curve-sect283r1 +test-29 = 29-curve-sect409k1 +test-30 = 30-curve-sect409r1 +test-31 = 31-curve-sect571k1 +test-32 = 32-curve-sect571r1 +test-33 = 33-curve-secp224r1 +test-34 = 34-curve-sect163k1 +test-35 = 35-curve-sect163r2 +test-36 = 36-curve-prime192v1 +test-37 = 37-curve-sect163r1 +test-38 = 38-curve-sect193r1 +test-39 = 39-curve-sect193r2 +test-40 = 40-curve-sect239k1 +test-41 = 41-curve-secp160k1 +test-42 = 42-curve-secp160r1 +test-43 = 43-curve-secp160r2 +test-44 = 44-curve-secp192k1 +test-45 = 45-curve-secp224k1 +test-46 = 46-curve-secp256k1 +test-47 = 47-curve-brainpoolP256r1 +test-48 = 48-curve-brainpoolP384r1 +test-49 = 49-curve-brainpoolP512r1 +test-50 = 50-curve-sect233k1-tls12-in-tls13 +test-51 = 51-curve-sect233r1-tls12-in-tls13 +test-52 = 52-curve-sect283k1-tls12-in-tls13 +test-53 = 53-curve-sect283r1-tls12-in-tls13 +test-54 = 54-curve-sect409k1-tls12-in-tls13 +test-55 = 55-curve-sect409r1-tls12-in-tls13 +test-56 = 56-curve-sect571k1-tls12-in-tls13 +test-57 = 57-curve-sect571r1-tls12-in-tls13 +test-58 = 58-curve-secp224r1-tls12-in-tls13 +test-59 = 59-curve-sect163k1-tls12-in-tls13 +test-60 = 60-curve-sect163r2-tls12-in-tls13 +test-61 = 61-curve-prime192v1-tls12-in-tls13 +test-62 = 62-curve-sect163r1-tls12-in-tls13 +test-63 = 63-curve-sect193r1-tls12-in-tls13 +test-64 = 64-curve-sect193r2-tls12-in-tls13 +test-65 = 65-curve-sect239k1-tls12-in-tls13 +test-66 = 66-curve-secp160k1-tls12-in-tls13 +test-67 = 67-curve-secp160r1-tls12-in-tls13 +test-68 = 68-curve-secp160r2-tls12-in-tls13 +test-69 = 69-curve-secp192k1-tls12-in-tls13 +test-70 = 70-curve-secp224k1-tls12-in-tls13 +test-71 = 71-curve-secp256k1-tls12-in-tls13 +test-72 = 72-curve-brainpoolP256r1-tls12-in-tls13 +test-73 = 73-curve-brainpoolP384r1-tls12-in-tls13 +test-74 = 74-curve-brainpoolP512r1-tls12-in-tls13 +test-75 = 75-curve-sect233k1-tls13 +test-76 = 76-curve-sect233r1-tls13 +test-77 = 77-curve-sect283k1-tls13 +test-78 = 78-curve-sect283r1-tls13 +test-79 = 79-curve-sect409k1-tls13 +test-80 = 80-curve-sect409r1-tls13 +test-81 = 81-curve-sect571k1-tls13 +test-82 = 82-curve-sect571r1-tls13 +test-83 = 83-curve-secp224r1-tls13 +test-84 = 84-curve-sect163k1-tls13 +test-85 = 85-curve-sect163r2-tls13 +test-86 = 86-curve-prime192v1-tls13 +test-87 = 87-curve-sect163r1-tls13 +test-88 = 88-curve-sect193r1-tls13 +test-89 = 89-curve-sect193r2-tls13 +test-90 = 90-curve-sect239k1-tls13 +test-91 = 91-curve-secp160k1-tls13 +test-92 = 92-curve-secp160r1-tls13 +test-93 = 93-curve-secp160r2-tls13 +test-94 = 94-curve-secp192k1-tls13 +test-95 = 95-curve-secp224k1-tls13 +test-96 = 96-curve-secp256k1-tls13 +test-97 = 97-curve-brainpoolP256r1-tls13 +test-98 = 98-curve-brainpoolP384r1-tls13 +test-99 = 99-curve-brainpoolP512r1-tls13 +test-100 = 100-curve-ffdhe2048-tls13-in-tls12-2 +test-101 = 101-curve-ffdhe3072-tls13-in-tls12-2 +test-102 = 102-curve-ffdhe4096-tls13-in-tls12-2 +test-103 = 103-curve-ffdhe6144-tls13-in-tls12-2 +test-104 = 104-curve-ffdhe8192-tls13-in-tls12-2 +test-105 = 105-curve-brainpoolP256r1tls13-tls13-in-tls12 +test-106 = 106-curve-brainpoolP256r1tls13-tls13-in-tls12-2 +test-107 = 107-curve-brainpoolP384r1tls13-tls13-in-tls12 +test-108 = 108-curve-brainpoolP384r1tls13-tls13-in-tls12-2 +test-109 = 109-curve-brainpoolP512r1tls13-tls13-in-tls12 +test-110 = 110-curve-brainpoolP512r1tls13-tls13-in-tls12-2 +test-111 = 111-curve-X25519MLKEM768-tls13-in-tls12 +test-112 = 112-curve-X25519MLKEM768-tls13-in-tls12-2 +test-113 = 113-curve-SecP256r1MLKEM768-tls13-in-tls12 +test-114 = 114-curve-SecP256r1MLKEM768-tls13-in-tls12-2 +test-115 = 115-curve-SecP384r1MLKEM1024-tls13-in-tls12 +test-116 = 116-curve-SecP384r1MLKEM1024-tls13-in-tls12-2 +test-117 = 117-curve-curveSM2-tls13-in-tls12 +test-118 = 118-curve-curveSM2-tls13-in-tls12-2 +test-119 = 119-curve-curveSM2MLKEM768-tls13-in-tls12 +test-120 = 120-curve-curveSM2MLKEM768-tls13-in-tls12-2 +test-121 = 121-curve-MLKEM512X25519-tls13-in-tls12 +test-122 = 122-curve-MLKEM512X25519-tls13-in-tls12-2 +test-123 = 123-curve-SecP256r1MLKEM512-tls13-in-tls12 +test-124 = 124-curve-SecP256r1MLKEM512-tls13-in-tls12-2 # =========================================================== [0-curve-prime256v1] @@ -283,7 +289,7 @@ MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [5-curve-ffdhe2048-client] -CipherString = ECDHE@SECLEVEL=1 +CipherString = DHE@SECLEVEL=1 Curves = ffdhe2048 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem @@ -292,7 +298,7 @@ VerifyMode = Peer [test-5] ExpectedProtocol = TLSv1.3 ExpectedResult = Success -ExpectedTmpKeyType = dhKeyAgreement +ExpectedTmpKeyType = ffdhe2048 # =========================================================== @@ -312,7 +318,7 @@ MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [6-curve-ffdhe3072-client] -CipherString = ECDHE@SECLEVEL=1 +CipherString = DHE@SECLEVEL=1 Curves = ffdhe3072 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem @@ -321,7 +327,7 @@ VerifyMode = Peer [test-6] ExpectedProtocol = TLSv1.3 ExpectedResult = Success -ExpectedTmpKeyType = dhKeyAgreement +ExpectedTmpKeyType = ffdhe3072 # =========================================================== @@ -341,7 +347,7 @@ MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [7-curve-ffdhe4096-client] -CipherString = ECDHE@SECLEVEL=1 +CipherString = DHE@SECLEVEL=1 Curves = ffdhe4096 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem @@ -350,7 +356,7 @@ VerifyMode = Peer [test-7] ExpectedProtocol = TLSv1.3 ExpectedResult = Success -ExpectedTmpKeyType = dhKeyAgreement +ExpectedTmpKeyType = ffdhe4096 # =========================================================== @@ -370,7 +376,7 @@ MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [8-curve-ffdhe6144-client] -CipherString = ECDHE@SECLEVEL=1 +CipherString = DHE@SECLEVEL=1 Curves = ffdhe6144 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem @@ -379,7 +385,7 @@ VerifyMode = Peer [test-8] ExpectedProtocol = TLSv1.3 ExpectedResult = Success -ExpectedTmpKeyType = dhKeyAgreement +ExpectedTmpKeyType = ffdhe6144 # =========================================================== @@ -399,7 +405,7 @@ MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem [9-curve-ffdhe8192-client] -CipherString = ECDHE@SECLEVEL=1 +CipherString = DHE@SECLEVEL=1 Curves = ffdhe8192 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem @@ -408,7 +414,7 @@ VerifyMode = Peer [test-9] ExpectedProtocol = TLSv1.3 ExpectedResult = Success -ExpectedTmpKeyType = dhKeyAgreement +ExpectedTmpKeyType = ffdhe8192 # =========================================================== @@ -645,28 +651,231 @@ ExpectedTmpKeyType = curveSM2MLKEM768 # =========================================================== -[18-curve-sect233k1] -ssl_conf = 18-curve-sect233k1-ssl +[18-curve-MLKEM512X25519] +ssl_conf = 18-curve-MLKEM512X25519-ssl + +[18-curve-MLKEM512X25519-ssl] +server = 18-curve-MLKEM512X25519-server +client = 18-curve-MLKEM512X25519-client + +[18-curve-MLKEM512X25519-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = MLKEM512X25519 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[18-curve-MLKEM512X25519-client] +CipherString = ECDHE@SECLEVEL=1 +Curves = MLKEM512X25519 +MaxProtocol = TLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-18] +ExpectedProtocol = TLSv1.3 +ExpectedResult = Success +ExpectedTmpKeyType = MLKEM512X25519 + + +# =========================================================== + +[19-curve-SecP256r1MLKEM512] +ssl_conf = 19-curve-SecP256r1MLKEM512-ssl + +[19-curve-SecP256r1MLKEM512-ssl] +server = 19-curve-SecP256r1MLKEM512-server +client = 19-curve-SecP256r1MLKEM512-client + +[19-curve-SecP256r1MLKEM512-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = SecP256r1MLKEM512 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[19-curve-SecP256r1MLKEM512-client] +CipherString = ECDHE@SECLEVEL=1 +Curves = SecP256r1MLKEM512 +MaxProtocol = TLSv1.3 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-19] +ExpectedProtocol = TLSv1.3 +ExpectedResult = Success +ExpectedTmpKeyType = SecP256r1MLKEM512 + + +# =========================================================== + +[20-curve-ffdhe2048] +ssl_conf = 20-curve-ffdhe2048-ssl + +[20-curve-ffdhe2048-ssl] +server = 20-curve-ffdhe2048-server +client = 20-curve-ffdhe2048-client + +[20-curve-ffdhe2048-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe2048 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[20-curve-ffdhe2048-client] +CipherString = DHE@SECLEVEL=1 +Curves = ffdhe2048 +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-20] +ExpectedProtocol = TLSv1.2 +ExpectedResult = Success +ExpectedTmpKeyType = dhKeyAgreement + + +# =========================================================== + +[21-curve-ffdhe3072] +ssl_conf = 21-curve-ffdhe3072-ssl + +[21-curve-ffdhe3072-ssl] +server = 21-curve-ffdhe3072-server +client = 21-curve-ffdhe3072-client + +[21-curve-ffdhe3072-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe3072 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[21-curve-ffdhe3072-client] +CipherString = DHE@SECLEVEL=1 +Curves = ffdhe3072 +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-21] +ExpectedProtocol = TLSv1.2 +ExpectedResult = Success +ExpectedTmpKeyType = dhKeyAgreement + + +# =========================================================== + +[22-curve-ffdhe4096] +ssl_conf = 22-curve-ffdhe4096-ssl + +[22-curve-ffdhe4096-ssl] +server = 22-curve-ffdhe4096-server +client = 22-curve-ffdhe4096-client + +[22-curve-ffdhe4096-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe4096 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[22-curve-ffdhe4096-client] +CipherString = DHE@SECLEVEL=1 +Curves = ffdhe4096 +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-22] +ExpectedProtocol = TLSv1.2 +ExpectedResult = Success +ExpectedTmpKeyType = dhKeyAgreement + + +# =========================================================== + +[23-curve-ffdhe6144] +ssl_conf = 23-curve-ffdhe6144-ssl + +[23-curve-ffdhe6144-ssl] +server = 23-curve-ffdhe6144-server +client = 23-curve-ffdhe6144-client + +[23-curve-ffdhe6144-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe6144 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[23-curve-ffdhe6144-client] +CipherString = DHE@SECLEVEL=1 +Curves = ffdhe6144 +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-23] +ExpectedProtocol = TLSv1.2 +ExpectedResult = Success +ExpectedTmpKeyType = dhKeyAgreement + + +# =========================================================== + +[24-curve-ffdhe8192] +ssl_conf = 24-curve-ffdhe8192-ssl -[18-curve-sect233k1-ssl] -server = 18-curve-sect233k1-server -client = 18-curve-sect233k1-client +[24-curve-ffdhe8192-ssl] +server = 24-curve-ffdhe8192-server +client = 24-curve-ffdhe8192-client -[18-curve-sect233k1-server] +[24-curve-ffdhe8192-server] +Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe8192 +MaxProtocol = TLSv1.3 +PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem + +[24-curve-ffdhe8192-client] +CipherString = DHE@SECLEVEL=1 +Curves = ffdhe8192 +MaxProtocol = TLSv1.2 +VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem +VerifyMode = Peer + +[test-24] +ExpectedProtocol = TLSv1.2 +ExpectedResult = Success +ExpectedTmpKeyType = dhKeyAgreement + + +# =========================================================== + +[25-curve-sect233k1] +ssl_conf = 25-curve-sect233k1-ssl + +[25-curve-sect233k1-ssl] +server = 25-curve-sect233k1-server +client = 25-curve-sect233k1-client + +[25-curve-sect233k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect233k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[18-curve-sect233k1-client] +[25-curve-sect233k1-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect233k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-18] +[test-25] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect233k1 @@ -674,28 +883,28 @@ ExpectedTmpKeyType = sect233k1 # =========================================================== -[19-curve-sect233r1] -ssl_conf = 19-curve-sect233r1-ssl +[26-curve-sect233r1] +ssl_conf = 26-curve-sect233r1-ssl -[19-curve-sect233r1-ssl] -server = 19-curve-sect233r1-server -client = 19-curve-sect233r1-client +[26-curve-sect233r1-ssl] +server = 26-curve-sect233r1-server +client = 26-curve-sect233r1-client -[19-curve-sect233r1-server] +[26-curve-sect233r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect233r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[19-curve-sect233r1-client] +[26-curve-sect233r1-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect233r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-19] +[test-26] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect233r1 @@ -703,28 +912,28 @@ ExpectedTmpKeyType = sect233r1 # =========================================================== -[20-curve-sect283k1] -ssl_conf = 20-curve-sect283k1-ssl +[27-curve-sect283k1] +ssl_conf = 27-curve-sect283k1-ssl -[20-curve-sect283k1-ssl] -server = 20-curve-sect283k1-server -client = 20-curve-sect283k1-client +[27-curve-sect283k1-ssl] +server = 27-curve-sect283k1-server +client = 27-curve-sect283k1-client -[20-curve-sect283k1-server] +[27-curve-sect283k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect283k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[20-curve-sect283k1-client] +[27-curve-sect283k1-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect283k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-20] +[test-27] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect283k1 @@ -732,28 +941,28 @@ ExpectedTmpKeyType = sect283k1 # =========================================================== -[21-curve-sect283r1] -ssl_conf = 21-curve-sect283r1-ssl +[28-curve-sect283r1] +ssl_conf = 28-curve-sect283r1-ssl -[21-curve-sect283r1-ssl] -server = 21-curve-sect283r1-server -client = 21-curve-sect283r1-client +[28-curve-sect283r1-ssl] +server = 28-curve-sect283r1-server +client = 28-curve-sect283r1-client -[21-curve-sect283r1-server] +[28-curve-sect283r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect283r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[21-curve-sect283r1-client] +[28-curve-sect283r1-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect283r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-21] +[test-28] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect283r1 @@ -761,28 +970,28 @@ ExpectedTmpKeyType = sect283r1 # =========================================================== -[22-curve-sect409k1] -ssl_conf = 22-curve-sect409k1-ssl +[29-curve-sect409k1] +ssl_conf = 29-curve-sect409k1-ssl -[22-curve-sect409k1-ssl] -server = 22-curve-sect409k1-server -client = 22-curve-sect409k1-client +[29-curve-sect409k1-ssl] +server = 29-curve-sect409k1-server +client = 29-curve-sect409k1-client -[22-curve-sect409k1-server] +[29-curve-sect409k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect409k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[22-curve-sect409k1-client] +[29-curve-sect409k1-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect409k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-22] +[test-29] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect409k1 @@ -790,28 +999,28 @@ ExpectedTmpKeyType = sect409k1 # =========================================================== -[23-curve-sect409r1] -ssl_conf = 23-curve-sect409r1-ssl +[30-curve-sect409r1] +ssl_conf = 30-curve-sect409r1-ssl -[23-curve-sect409r1-ssl] -server = 23-curve-sect409r1-server -client = 23-curve-sect409r1-client +[30-curve-sect409r1-ssl] +server = 30-curve-sect409r1-server +client = 30-curve-sect409r1-client -[23-curve-sect409r1-server] +[30-curve-sect409r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect409r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[23-curve-sect409r1-client] +[30-curve-sect409r1-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect409r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-23] +[test-30] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect409r1 @@ -819,28 +1028,28 @@ ExpectedTmpKeyType = sect409r1 # =========================================================== -[24-curve-sect571k1] -ssl_conf = 24-curve-sect571k1-ssl +[31-curve-sect571k1] +ssl_conf = 31-curve-sect571k1-ssl -[24-curve-sect571k1-ssl] -server = 24-curve-sect571k1-server -client = 24-curve-sect571k1-client +[31-curve-sect571k1-ssl] +server = 31-curve-sect571k1-server +client = 31-curve-sect571k1-client -[24-curve-sect571k1-server] +[31-curve-sect571k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect571k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[24-curve-sect571k1-client] +[31-curve-sect571k1-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect571k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-24] +[test-31] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect571k1 @@ -848,28 +1057,28 @@ ExpectedTmpKeyType = sect571k1 # =========================================================== -[25-curve-sect571r1] -ssl_conf = 25-curve-sect571r1-ssl +[32-curve-sect571r1] +ssl_conf = 32-curve-sect571r1-ssl -[25-curve-sect571r1-ssl] -server = 25-curve-sect571r1-server -client = 25-curve-sect571r1-client +[32-curve-sect571r1-ssl] +server = 32-curve-sect571r1-server +client = 32-curve-sect571r1-client -[25-curve-sect571r1-server] +[32-curve-sect571r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect571r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[25-curve-sect571r1-client] +[32-curve-sect571r1-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect571r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-25] +[test-32] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect571r1 @@ -877,28 +1086,28 @@ ExpectedTmpKeyType = sect571r1 # =========================================================== -[26-curve-secp224r1] -ssl_conf = 26-curve-secp224r1-ssl +[33-curve-secp224r1] +ssl_conf = 33-curve-secp224r1-ssl -[26-curve-secp224r1-ssl] -server = 26-curve-secp224r1-server -client = 26-curve-secp224r1-client +[33-curve-secp224r1-ssl] +server = 33-curve-secp224r1-server +client = 33-curve-secp224r1-client -[26-curve-secp224r1-server] +[33-curve-secp224r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp224r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[26-curve-secp224r1-client] +[33-curve-secp224r1-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp224r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-26] +[test-33] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = secp224r1 @@ -906,28 +1115,28 @@ ExpectedTmpKeyType = secp224r1 # =========================================================== -[27-curve-sect163k1] -ssl_conf = 27-curve-sect163k1-ssl +[34-curve-sect163k1] +ssl_conf = 34-curve-sect163k1-ssl -[27-curve-sect163k1-ssl] -server = 27-curve-sect163k1-server -client = 27-curve-sect163k1-client +[34-curve-sect163k1-ssl] +server = 34-curve-sect163k1-server +client = 34-curve-sect163k1-client -[27-curve-sect163k1-server] +[34-curve-sect163k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect163k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[27-curve-sect163k1-client] +[34-curve-sect163k1-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect163k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-27] +[test-34] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect163k1 @@ -935,28 +1144,28 @@ ExpectedTmpKeyType = sect163k1 # =========================================================== -[28-curve-sect163r2] -ssl_conf = 28-curve-sect163r2-ssl +[35-curve-sect163r2] +ssl_conf = 35-curve-sect163r2-ssl -[28-curve-sect163r2-ssl] -server = 28-curve-sect163r2-server -client = 28-curve-sect163r2-client +[35-curve-sect163r2-ssl] +server = 35-curve-sect163r2-server +client = 35-curve-sect163r2-client -[28-curve-sect163r2-server] +[35-curve-sect163r2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect163r2 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[28-curve-sect163r2-client] +[35-curve-sect163r2-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect163r2 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-28] +[test-35] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect163r2 @@ -964,28 +1173,28 @@ ExpectedTmpKeyType = sect163r2 # =========================================================== -[29-curve-prime192v1] -ssl_conf = 29-curve-prime192v1-ssl +[36-curve-prime192v1] +ssl_conf = 36-curve-prime192v1-ssl -[29-curve-prime192v1-ssl] -server = 29-curve-prime192v1-server -client = 29-curve-prime192v1-client +[36-curve-prime192v1-ssl] +server = 36-curve-prime192v1-server +client = 36-curve-prime192v1-client -[29-curve-prime192v1-server] +[36-curve-prime192v1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = prime192v1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[29-curve-prime192v1-client] +[36-curve-prime192v1-client] CipherString = ECDHE@SECLEVEL=1 Curves = prime192v1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-29] +[test-36] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = prime192v1 @@ -993,28 +1202,28 @@ ExpectedTmpKeyType = prime192v1 # =========================================================== -[30-curve-sect163r1] -ssl_conf = 30-curve-sect163r1-ssl +[37-curve-sect163r1] +ssl_conf = 37-curve-sect163r1-ssl -[30-curve-sect163r1-ssl] -server = 30-curve-sect163r1-server -client = 30-curve-sect163r1-client +[37-curve-sect163r1-ssl] +server = 37-curve-sect163r1-server +client = 37-curve-sect163r1-client -[30-curve-sect163r1-server] +[37-curve-sect163r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect163r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[30-curve-sect163r1-client] +[37-curve-sect163r1-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect163r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-30] +[test-37] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect163r1 @@ -1022,28 +1231,28 @@ ExpectedTmpKeyType = sect163r1 # =========================================================== -[31-curve-sect193r1] -ssl_conf = 31-curve-sect193r1-ssl +[38-curve-sect193r1] +ssl_conf = 38-curve-sect193r1-ssl -[31-curve-sect193r1-ssl] -server = 31-curve-sect193r1-server -client = 31-curve-sect193r1-client +[38-curve-sect193r1-ssl] +server = 38-curve-sect193r1-server +client = 38-curve-sect193r1-client -[31-curve-sect193r1-server] +[38-curve-sect193r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect193r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[31-curve-sect193r1-client] +[38-curve-sect193r1-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect193r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-31] +[test-38] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect193r1 @@ -1051,28 +1260,28 @@ ExpectedTmpKeyType = sect193r1 # =========================================================== -[32-curve-sect193r2] -ssl_conf = 32-curve-sect193r2-ssl +[39-curve-sect193r2] +ssl_conf = 39-curve-sect193r2-ssl -[32-curve-sect193r2-ssl] -server = 32-curve-sect193r2-server -client = 32-curve-sect193r2-client +[39-curve-sect193r2-ssl] +server = 39-curve-sect193r2-server +client = 39-curve-sect193r2-client -[32-curve-sect193r2-server] +[39-curve-sect193r2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect193r2 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[32-curve-sect193r2-client] +[39-curve-sect193r2-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect193r2 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-32] +[test-39] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect193r2 @@ -1080,28 +1289,28 @@ ExpectedTmpKeyType = sect193r2 # =========================================================== -[33-curve-sect239k1] -ssl_conf = 33-curve-sect239k1-ssl +[40-curve-sect239k1] +ssl_conf = 40-curve-sect239k1-ssl -[33-curve-sect239k1-ssl] -server = 33-curve-sect239k1-server -client = 33-curve-sect239k1-client +[40-curve-sect239k1-ssl] +server = 40-curve-sect239k1-server +client = 40-curve-sect239k1-client -[33-curve-sect239k1-server] +[40-curve-sect239k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect239k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[33-curve-sect239k1-client] +[40-curve-sect239k1-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect239k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-33] +[test-40] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = sect239k1 @@ -1109,28 +1318,28 @@ ExpectedTmpKeyType = sect239k1 # =========================================================== -[34-curve-secp160k1] -ssl_conf = 34-curve-secp160k1-ssl +[41-curve-secp160k1] +ssl_conf = 41-curve-secp160k1-ssl -[34-curve-secp160k1-ssl] -server = 34-curve-secp160k1-server -client = 34-curve-secp160k1-client +[41-curve-secp160k1-ssl] +server = 41-curve-secp160k1-server +client = 41-curve-secp160k1-client -[34-curve-secp160k1-server] +[41-curve-secp160k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp160k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[34-curve-secp160k1-client] +[41-curve-secp160k1-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp160k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-34] +[test-41] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = secp160k1 @@ -1138,28 +1347,28 @@ ExpectedTmpKeyType = secp160k1 # =========================================================== -[35-curve-secp160r1] -ssl_conf = 35-curve-secp160r1-ssl +[42-curve-secp160r1] +ssl_conf = 42-curve-secp160r1-ssl -[35-curve-secp160r1-ssl] -server = 35-curve-secp160r1-server -client = 35-curve-secp160r1-client +[42-curve-secp160r1-ssl] +server = 42-curve-secp160r1-server +client = 42-curve-secp160r1-client -[35-curve-secp160r1-server] +[42-curve-secp160r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp160r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[35-curve-secp160r1-client] +[42-curve-secp160r1-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp160r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-35] +[test-42] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = secp160r1 @@ -1167,28 +1376,28 @@ ExpectedTmpKeyType = secp160r1 # =========================================================== -[36-curve-secp160r2] -ssl_conf = 36-curve-secp160r2-ssl +[43-curve-secp160r2] +ssl_conf = 43-curve-secp160r2-ssl -[36-curve-secp160r2-ssl] -server = 36-curve-secp160r2-server -client = 36-curve-secp160r2-client +[43-curve-secp160r2-ssl] +server = 43-curve-secp160r2-server +client = 43-curve-secp160r2-client -[36-curve-secp160r2-server] +[43-curve-secp160r2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp160r2 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[36-curve-secp160r2-client] +[43-curve-secp160r2-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp160r2 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-36] +[test-43] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = secp160r2 @@ -1196,28 +1405,28 @@ ExpectedTmpKeyType = secp160r2 # =========================================================== -[37-curve-secp192k1] -ssl_conf = 37-curve-secp192k1-ssl +[44-curve-secp192k1] +ssl_conf = 44-curve-secp192k1-ssl -[37-curve-secp192k1-ssl] -server = 37-curve-secp192k1-server -client = 37-curve-secp192k1-client +[44-curve-secp192k1-ssl] +server = 44-curve-secp192k1-server +client = 44-curve-secp192k1-client -[37-curve-secp192k1-server] +[44-curve-secp192k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp192k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[37-curve-secp192k1-client] +[44-curve-secp192k1-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp192k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-37] +[test-44] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = secp192k1 @@ -1225,28 +1434,28 @@ ExpectedTmpKeyType = secp192k1 # =========================================================== -[38-curve-secp224k1] -ssl_conf = 38-curve-secp224k1-ssl +[45-curve-secp224k1] +ssl_conf = 45-curve-secp224k1-ssl -[38-curve-secp224k1-ssl] -server = 38-curve-secp224k1-server -client = 38-curve-secp224k1-client +[45-curve-secp224k1-ssl] +server = 45-curve-secp224k1-server +client = 45-curve-secp224k1-client -[38-curve-secp224k1-server] +[45-curve-secp224k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp224k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[38-curve-secp224k1-client] +[45-curve-secp224k1-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp224k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-38] +[test-45] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = secp224k1 @@ -1254,28 +1463,28 @@ ExpectedTmpKeyType = secp224k1 # =========================================================== -[39-curve-secp256k1] -ssl_conf = 39-curve-secp256k1-ssl +[46-curve-secp256k1] +ssl_conf = 46-curve-secp256k1-ssl -[39-curve-secp256k1-ssl] -server = 39-curve-secp256k1-server -client = 39-curve-secp256k1-client +[46-curve-secp256k1-ssl] +server = 46-curve-secp256k1-server +client = 46-curve-secp256k1-client -[39-curve-secp256k1-server] +[46-curve-secp256k1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp256k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[39-curve-secp256k1-client] +[46-curve-secp256k1-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp256k1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-39] +[test-46] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = secp256k1 @@ -1283,28 +1492,28 @@ ExpectedTmpKeyType = secp256k1 # =========================================================== -[40-curve-brainpoolP256r1] -ssl_conf = 40-curve-brainpoolP256r1-ssl +[47-curve-brainpoolP256r1] +ssl_conf = 47-curve-brainpoolP256r1-ssl -[40-curve-brainpoolP256r1-ssl] -server = 40-curve-brainpoolP256r1-server -client = 40-curve-brainpoolP256r1-client +[47-curve-brainpoolP256r1-ssl] +server = 47-curve-brainpoolP256r1-server +client = 47-curve-brainpoolP256r1-client -[40-curve-brainpoolP256r1-server] +[47-curve-brainpoolP256r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = brainpoolP256r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[40-curve-brainpoolP256r1-client] +[47-curve-brainpoolP256r1-client] CipherString = ECDHE@SECLEVEL=1 Curves = brainpoolP256r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-40] +[test-47] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = brainpoolP256r1 @@ -1312,28 +1521,28 @@ ExpectedTmpKeyType = brainpoolP256r1 # =========================================================== -[41-curve-brainpoolP384r1] -ssl_conf = 41-curve-brainpoolP384r1-ssl +[48-curve-brainpoolP384r1] +ssl_conf = 48-curve-brainpoolP384r1-ssl -[41-curve-brainpoolP384r1-ssl] -server = 41-curve-brainpoolP384r1-server -client = 41-curve-brainpoolP384r1-client +[48-curve-brainpoolP384r1-ssl] +server = 48-curve-brainpoolP384r1-server +client = 48-curve-brainpoolP384r1-client -[41-curve-brainpoolP384r1-server] +[48-curve-brainpoolP384r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = brainpoolP384r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[41-curve-brainpoolP384r1-client] +[48-curve-brainpoolP384r1-client] CipherString = ECDHE@SECLEVEL=1 Curves = brainpoolP384r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-41] +[test-48] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = brainpoolP384r1 @@ -1341,28 +1550,28 @@ ExpectedTmpKeyType = brainpoolP384r1 # =========================================================== -[42-curve-brainpoolP512r1] -ssl_conf = 42-curve-brainpoolP512r1-ssl +[49-curve-brainpoolP512r1] +ssl_conf = 49-curve-brainpoolP512r1-ssl -[42-curve-brainpoolP512r1-ssl] -server = 42-curve-brainpoolP512r1-server -client = 42-curve-brainpoolP512r1-client +[49-curve-brainpoolP512r1-ssl] +server = 49-curve-brainpoolP512r1-server +client = 49-curve-brainpoolP512r1-client -[42-curve-brainpoolP512r1-server] +[49-curve-brainpoolP512r1-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = brainpoolP512r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[42-curve-brainpoolP512r1-client] +[49-curve-brainpoolP512r1-client] CipherString = ECDHE@SECLEVEL=1 Curves = brainpoolP512r1 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-42] +[test-49] ExpectedProtocol = TLSv1.2 ExpectedResult = Success ExpectedTmpKeyType = brainpoolP512r1 @@ -1370,21 +1579,21 @@ ExpectedTmpKeyType = brainpoolP512r1 # =========================================================== -[43-curve-sect233k1-tls12-in-tls13] -ssl_conf = 43-curve-sect233k1-tls12-in-tls13-ssl +[50-curve-sect233k1-tls12-in-tls13] +ssl_conf = 50-curve-sect233k1-tls12-in-tls13-ssl -[43-curve-sect233k1-tls12-in-tls13-ssl] -server = 43-curve-sect233k1-tls12-in-tls13-server -client = 43-curve-sect233k1-tls12-in-tls13-client +[50-curve-sect233k1-tls12-in-tls13-ssl] +server = 50-curve-sect233k1-tls12-in-tls13-server +client = 50-curve-sect233k1-tls12-in-tls13-client -[43-curve-sect233k1-tls12-in-tls13-server] +[50-curve-sect233k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect233k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[43-curve-sect233k1-tls12-in-tls13-client] +[50-curve-sect233k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect233k1:P-256 MaxProtocol = TLSv1.3 @@ -1392,7 +1601,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-43] +[test-50] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1400,21 +1609,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[44-curve-sect233r1-tls12-in-tls13] -ssl_conf = 44-curve-sect233r1-tls12-in-tls13-ssl +[51-curve-sect233r1-tls12-in-tls13] +ssl_conf = 51-curve-sect233r1-tls12-in-tls13-ssl -[44-curve-sect233r1-tls12-in-tls13-ssl] -server = 44-curve-sect233r1-tls12-in-tls13-server -client = 44-curve-sect233r1-tls12-in-tls13-client +[51-curve-sect233r1-tls12-in-tls13-ssl] +server = 51-curve-sect233r1-tls12-in-tls13-server +client = 51-curve-sect233r1-tls12-in-tls13-client -[44-curve-sect233r1-tls12-in-tls13-server] +[51-curve-sect233r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect233r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[44-curve-sect233r1-tls12-in-tls13-client] +[51-curve-sect233r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect233r1:P-256 MaxProtocol = TLSv1.3 @@ -1422,7 +1631,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-44] +[test-51] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1430,21 +1639,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[45-curve-sect283k1-tls12-in-tls13] -ssl_conf = 45-curve-sect283k1-tls12-in-tls13-ssl +[52-curve-sect283k1-tls12-in-tls13] +ssl_conf = 52-curve-sect283k1-tls12-in-tls13-ssl -[45-curve-sect283k1-tls12-in-tls13-ssl] -server = 45-curve-sect283k1-tls12-in-tls13-server -client = 45-curve-sect283k1-tls12-in-tls13-client +[52-curve-sect283k1-tls12-in-tls13-ssl] +server = 52-curve-sect283k1-tls12-in-tls13-server +client = 52-curve-sect283k1-tls12-in-tls13-client -[45-curve-sect283k1-tls12-in-tls13-server] +[52-curve-sect283k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect283k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[45-curve-sect283k1-tls12-in-tls13-client] +[52-curve-sect283k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect283k1:P-256 MaxProtocol = TLSv1.3 @@ -1452,7 +1661,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-45] +[test-52] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1460,21 +1669,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[46-curve-sect283r1-tls12-in-tls13] -ssl_conf = 46-curve-sect283r1-tls12-in-tls13-ssl +[53-curve-sect283r1-tls12-in-tls13] +ssl_conf = 53-curve-sect283r1-tls12-in-tls13-ssl -[46-curve-sect283r1-tls12-in-tls13-ssl] -server = 46-curve-sect283r1-tls12-in-tls13-server -client = 46-curve-sect283r1-tls12-in-tls13-client +[53-curve-sect283r1-tls12-in-tls13-ssl] +server = 53-curve-sect283r1-tls12-in-tls13-server +client = 53-curve-sect283r1-tls12-in-tls13-client -[46-curve-sect283r1-tls12-in-tls13-server] +[53-curve-sect283r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect283r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[46-curve-sect283r1-tls12-in-tls13-client] +[53-curve-sect283r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect283r1:P-256 MaxProtocol = TLSv1.3 @@ -1482,7 +1691,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-46] +[test-53] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1490,21 +1699,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[47-curve-sect409k1-tls12-in-tls13] -ssl_conf = 47-curve-sect409k1-tls12-in-tls13-ssl +[54-curve-sect409k1-tls12-in-tls13] +ssl_conf = 54-curve-sect409k1-tls12-in-tls13-ssl -[47-curve-sect409k1-tls12-in-tls13-ssl] -server = 47-curve-sect409k1-tls12-in-tls13-server -client = 47-curve-sect409k1-tls12-in-tls13-client +[54-curve-sect409k1-tls12-in-tls13-ssl] +server = 54-curve-sect409k1-tls12-in-tls13-server +client = 54-curve-sect409k1-tls12-in-tls13-client -[47-curve-sect409k1-tls12-in-tls13-server] +[54-curve-sect409k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect409k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[47-curve-sect409k1-tls12-in-tls13-client] +[54-curve-sect409k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect409k1:P-256 MaxProtocol = TLSv1.3 @@ -1512,7 +1721,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-47] +[test-54] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1520,21 +1729,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[48-curve-sect409r1-tls12-in-tls13] -ssl_conf = 48-curve-sect409r1-tls12-in-tls13-ssl +[55-curve-sect409r1-tls12-in-tls13] +ssl_conf = 55-curve-sect409r1-tls12-in-tls13-ssl -[48-curve-sect409r1-tls12-in-tls13-ssl] -server = 48-curve-sect409r1-tls12-in-tls13-server -client = 48-curve-sect409r1-tls12-in-tls13-client +[55-curve-sect409r1-tls12-in-tls13-ssl] +server = 55-curve-sect409r1-tls12-in-tls13-server +client = 55-curve-sect409r1-tls12-in-tls13-client -[48-curve-sect409r1-tls12-in-tls13-server] +[55-curve-sect409r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect409r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[48-curve-sect409r1-tls12-in-tls13-client] +[55-curve-sect409r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect409r1:P-256 MaxProtocol = TLSv1.3 @@ -1542,7 +1751,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-48] +[test-55] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1550,21 +1759,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[49-curve-sect571k1-tls12-in-tls13] -ssl_conf = 49-curve-sect571k1-tls12-in-tls13-ssl +[56-curve-sect571k1-tls12-in-tls13] +ssl_conf = 56-curve-sect571k1-tls12-in-tls13-ssl -[49-curve-sect571k1-tls12-in-tls13-ssl] -server = 49-curve-sect571k1-tls12-in-tls13-server -client = 49-curve-sect571k1-tls12-in-tls13-client +[56-curve-sect571k1-tls12-in-tls13-ssl] +server = 56-curve-sect571k1-tls12-in-tls13-server +client = 56-curve-sect571k1-tls12-in-tls13-client -[49-curve-sect571k1-tls12-in-tls13-server] +[56-curve-sect571k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect571k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[49-curve-sect571k1-tls12-in-tls13-client] +[56-curve-sect571k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect571k1:P-256 MaxProtocol = TLSv1.3 @@ -1572,7 +1781,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-49] +[test-56] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1580,21 +1789,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[50-curve-sect571r1-tls12-in-tls13] -ssl_conf = 50-curve-sect571r1-tls12-in-tls13-ssl +[57-curve-sect571r1-tls12-in-tls13] +ssl_conf = 57-curve-sect571r1-tls12-in-tls13-ssl -[50-curve-sect571r1-tls12-in-tls13-ssl] -server = 50-curve-sect571r1-tls12-in-tls13-server -client = 50-curve-sect571r1-tls12-in-tls13-client +[57-curve-sect571r1-tls12-in-tls13-ssl] +server = 57-curve-sect571r1-tls12-in-tls13-server +client = 57-curve-sect571r1-tls12-in-tls13-client -[50-curve-sect571r1-tls12-in-tls13-server] +[57-curve-sect571r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect571r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[50-curve-sect571r1-tls12-in-tls13-client] +[57-curve-sect571r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect571r1:P-256 MaxProtocol = TLSv1.3 @@ -1602,7 +1811,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-50] +[test-57] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1610,21 +1819,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[51-curve-secp224r1-tls12-in-tls13] -ssl_conf = 51-curve-secp224r1-tls12-in-tls13-ssl +[58-curve-secp224r1-tls12-in-tls13] +ssl_conf = 58-curve-secp224r1-tls12-in-tls13-ssl -[51-curve-secp224r1-tls12-in-tls13-ssl] -server = 51-curve-secp224r1-tls12-in-tls13-server -client = 51-curve-secp224r1-tls12-in-tls13-client +[58-curve-secp224r1-tls12-in-tls13-ssl] +server = 58-curve-secp224r1-tls12-in-tls13-server +client = 58-curve-secp224r1-tls12-in-tls13-client -[51-curve-secp224r1-tls12-in-tls13-server] +[58-curve-secp224r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp224r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[51-curve-secp224r1-tls12-in-tls13-client] +[58-curve-secp224r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp224r1:P-256 MaxProtocol = TLSv1.3 @@ -1632,7 +1841,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-51] +[test-58] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1640,21 +1849,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[52-curve-sect163k1-tls12-in-tls13] -ssl_conf = 52-curve-sect163k1-tls12-in-tls13-ssl +[59-curve-sect163k1-tls12-in-tls13] +ssl_conf = 59-curve-sect163k1-tls12-in-tls13-ssl -[52-curve-sect163k1-tls12-in-tls13-ssl] -server = 52-curve-sect163k1-tls12-in-tls13-server -client = 52-curve-sect163k1-tls12-in-tls13-client +[59-curve-sect163k1-tls12-in-tls13-ssl] +server = 59-curve-sect163k1-tls12-in-tls13-server +client = 59-curve-sect163k1-tls12-in-tls13-client -[52-curve-sect163k1-tls12-in-tls13-server] +[59-curve-sect163k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect163k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[52-curve-sect163k1-tls12-in-tls13-client] +[59-curve-sect163k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect163k1:P-256 MaxProtocol = TLSv1.3 @@ -1662,7 +1871,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-52] +[test-59] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1670,21 +1879,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[53-curve-sect163r2-tls12-in-tls13] -ssl_conf = 53-curve-sect163r2-tls12-in-tls13-ssl +[60-curve-sect163r2-tls12-in-tls13] +ssl_conf = 60-curve-sect163r2-tls12-in-tls13-ssl -[53-curve-sect163r2-tls12-in-tls13-ssl] -server = 53-curve-sect163r2-tls12-in-tls13-server -client = 53-curve-sect163r2-tls12-in-tls13-client +[60-curve-sect163r2-tls12-in-tls13-ssl] +server = 60-curve-sect163r2-tls12-in-tls13-server +client = 60-curve-sect163r2-tls12-in-tls13-client -[53-curve-sect163r2-tls12-in-tls13-server] +[60-curve-sect163r2-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect163r2:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[53-curve-sect163r2-tls12-in-tls13-client] +[60-curve-sect163r2-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect163r2:P-256 MaxProtocol = TLSv1.3 @@ -1692,7 +1901,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-53] +[test-60] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1700,21 +1909,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[54-curve-prime192v1-tls12-in-tls13] -ssl_conf = 54-curve-prime192v1-tls12-in-tls13-ssl +[61-curve-prime192v1-tls12-in-tls13] +ssl_conf = 61-curve-prime192v1-tls12-in-tls13-ssl -[54-curve-prime192v1-tls12-in-tls13-ssl] -server = 54-curve-prime192v1-tls12-in-tls13-server -client = 54-curve-prime192v1-tls12-in-tls13-client +[61-curve-prime192v1-tls12-in-tls13-ssl] +server = 61-curve-prime192v1-tls12-in-tls13-server +client = 61-curve-prime192v1-tls12-in-tls13-client -[54-curve-prime192v1-tls12-in-tls13-server] +[61-curve-prime192v1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = prime192v1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[54-curve-prime192v1-tls12-in-tls13-client] +[61-curve-prime192v1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = prime192v1:P-256 MaxProtocol = TLSv1.3 @@ -1722,7 +1931,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-54] +[test-61] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1730,21 +1939,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[55-curve-sect163r1-tls12-in-tls13] -ssl_conf = 55-curve-sect163r1-tls12-in-tls13-ssl +[62-curve-sect163r1-tls12-in-tls13] +ssl_conf = 62-curve-sect163r1-tls12-in-tls13-ssl -[55-curve-sect163r1-tls12-in-tls13-ssl] -server = 55-curve-sect163r1-tls12-in-tls13-server -client = 55-curve-sect163r1-tls12-in-tls13-client +[62-curve-sect163r1-tls12-in-tls13-ssl] +server = 62-curve-sect163r1-tls12-in-tls13-server +client = 62-curve-sect163r1-tls12-in-tls13-client -[55-curve-sect163r1-tls12-in-tls13-server] +[62-curve-sect163r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect163r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[55-curve-sect163r1-tls12-in-tls13-client] +[62-curve-sect163r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect163r1:P-256 MaxProtocol = TLSv1.3 @@ -1752,7 +1961,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-55] +[test-62] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1760,21 +1969,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[56-curve-sect193r1-tls12-in-tls13] -ssl_conf = 56-curve-sect193r1-tls12-in-tls13-ssl +[63-curve-sect193r1-tls12-in-tls13] +ssl_conf = 63-curve-sect193r1-tls12-in-tls13-ssl -[56-curve-sect193r1-tls12-in-tls13-ssl] -server = 56-curve-sect193r1-tls12-in-tls13-server -client = 56-curve-sect193r1-tls12-in-tls13-client +[63-curve-sect193r1-tls12-in-tls13-ssl] +server = 63-curve-sect193r1-tls12-in-tls13-server +client = 63-curve-sect193r1-tls12-in-tls13-client -[56-curve-sect193r1-tls12-in-tls13-server] +[63-curve-sect193r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect193r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[56-curve-sect193r1-tls12-in-tls13-client] +[63-curve-sect193r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect193r1:P-256 MaxProtocol = TLSv1.3 @@ -1782,7 +1991,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-56] +[test-63] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1790,21 +1999,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[57-curve-sect193r2-tls12-in-tls13] -ssl_conf = 57-curve-sect193r2-tls12-in-tls13-ssl +[64-curve-sect193r2-tls12-in-tls13] +ssl_conf = 64-curve-sect193r2-tls12-in-tls13-ssl -[57-curve-sect193r2-tls12-in-tls13-ssl] -server = 57-curve-sect193r2-tls12-in-tls13-server -client = 57-curve-sect193r2-tls12-in-tls13-client +[64-curve-sect193r2-tls12-in-tls13-ssl] +server = 64-curve-sect193r2-tls12-in-tls13-server +client = 64-curve-sect193r2-tls12-in-tls13-client -[57-curve-sect193r2-tls12-in-tls13-server] +[64-curve-sect193r2-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect193r2:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[57-curve-sect193r2-tls12-in-tls13-client] +[64-curve-sect193r2-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect193r2:P-256 MaxProtocol = TLSv1.3 @@ -1812,7 +2021,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-57] +[test-64] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1820,21 +2029,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[58-curve-sect239k1-tls12-in-tls13] -ssl_conf = 58-curve-sect239k1-tls12-in-tls13-ssl +[65-curve-sect239k1-tls12-in-tls13] +ssl_conf = 65-curve-sect239k1-tls12-in-tls13-ssl -[58-curve-sect239k1-tls12-in-tls13-ssl] -server = 58-curve-sect239k1-tls12-in-tls13-server -client = 58-curve-sect239k1-tls12-in-tls13-client +[65-curve-sect239k1-tls12-in-tls13-ssl] +server = 65-curve-sect239k1-tls12-in-tls13-server +client = 65-curve-sect239k1-tls12-in-tls13-client -[58-curve-sect239k1-tls12-in-tls13-server] +[65-curve-sect239k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect239k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[58-curve-sect239k1-tls12-in-tls13-client] +[65-curve-sect239k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect239k1:P-256 MaxProtocol = TLSv1.3 @@ -1842,7 +2051,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-58] +[test-65] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1850,21 +2059,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[59-curve-secp160k1-tls12-in-tls13] -ssl_conf = 59-curve-secp160k1-tls12-in-tls13-ssl +[66-curve-secp160k1-tls12-in-tls13] +ssl_conf = 66-curve-secp160k1-tls12-in-tls13-ssl -[59-curve-secp160k1-tls12-in-tls13-ssl] -server = 59-curve-secp160k1-tls12-in-tls13-server -client = 59-curve-secp160k1-tls12-in-tls13-client +[66-curve-secp160k1-tls12-in-tls13-ssl] +server = 66-curve-secp160k1-tls12-in-tls13-server +client = 66-curve-secp160k1-tls12-in-tls13-client -[59-curve-secp160k1-tls12-in-tls13-server] +[66-curve-secp160k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp160k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[59-curve-secp160k1-tls12-in-tls13-client] +[66-curve-secp160k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp160k1:P-256 MaxProtocol = TLSv1.3 @@ -1872,7 +2081,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-59] +[test-66] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1880,21 +2089,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[60-curve-secp160r1-tls12-in-tls13] -ssl_conf = 60-curve-secp160r1-tls12-in-tls13-ssl +[67-curve-secp160r1-tls12-in-tls13] +ssl_conf = 67-curve-secp160r1-tls12-in-tls13-ssl -[60-curve-secp160r1-tls12-in-tls13-ssl] -server = 60-curve-secp160r1-tls12-in-tls13-server -client = 60-curve-secp160r1-tls12-in-tls13-client +[67-curve-secp160r1-tls12-in-tls13-ssl] +server = 67-curve-secp160r1-tls12-in-tls13-server +client = 67-curve-secp160r1-tls12-in-tls13-client -[60-curve-secp160r1-tls12-in-tls13-server] +[67-curve-secp160r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp160r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[60-curve-secp160r1-tls12-in-tls13-client] +[67-curve-secp160r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp160r1:P-256 MaxProtocol = TLSv1.3 @@ -1902,7 +2111,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-60] +[test-67] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1910,21 +2119,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[61-curve-secp160r2-tls12-in-tls13] -ssl_conf = 61-curve-secp160r2-tls12-in-tls13-ssl +[68-curve-secp160r2-tls12-in-tls13] +ssl_conf = 68-curve-secp160r2-tls12-in-tls13-ssl -[61-curve-secp160r2-tls12-in-tls13-ssl] -server = 61-curve-secp160r2-tls12-in-tls13-server -client = 61-curve-secp160r2-tls12-in-tls13-client +[68-curve-secp160r2-tls12-in-tls13-ssl] +server = 68-curve-secp160r2-tls12-in-tls13-server +client = 68-curve-secp160r2-tls12-in-tls13-client -[61-curve-secp160r2-tls12-in-tls13-server] +[68-curve-secp160r2-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp160r2:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[61-curve-secp160r2-tls12-in-tls13-client] +[68-curve-secp160r2-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp160r2:P-256 MaxProtocol = TLSv1.3 @@ -1932,7 +2141,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-61] +[test-68] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1940,21 +2149,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[62-curve-secp192k1-tls12-in-tls13] -ssl_conf = 62-curve-secp192k1-tls12-in-tls13-ssl +[69-curve-secp192k1-tls12-in-tls13] +ssl_conf = 69-curve-secp192k1-tls12-in-tls13-ssl -[62-curve-secp192k1-tls12-in-tls13-ssl] -server = 62-curve-secp192k1-tls12-in-tls13-server -client = 62-curve-secp192k1-tls12-in-tls13-client +[69-curve-secp192k1-tls12-in-tls13-ssl] +server = 69-curve-secp192k1-tls12-in-tls13-server +client = 69-curve-secp192k1-tls12-in-tls13-client -[62-curve-secp192k1-tls12-in-tls13-server] +[69-curve-secp192k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp192k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[62-curve-secp192k1-tls12-in-tls13-client] +[69-curve-secp192k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp192k1:P-256 MaxProtocol = TLSv1.3 @@ -1962,7 +2171,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-62] +[test-69] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -1970,21 +2179,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[63-curve-secp224k1-tls12-in-tls13] -ssl_conf = 63-curve-secp224k1-tls12-in-tls13-ssl +[70-curve-secp224k1-tls12-in-tls13] +ssl_conf = 70-curve-secp224k1-tls12-in-tls13-ssl -[63-curve-secp224k1-tls12-in-tls13-ssl] -server = 63-curve-secp224k1-tls12-in-tls13-server -client = 63-curve-secp224k1-tls12-in-tls13-client +[70-curve-secp224k1-tls12-in-tls13-ssl] +server = 70-curve-secp224k1-tls12-in-tls13-server +client = 70-curve-secp224k1-tls12-in-tls13-client -[63-curve-secp224k1-tls12-in-tls13-server] +[70-curve-secp224k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp224k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[63-curve-secp224k1-tls12-in-tls13-client] +[70-curve-secp224k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp224k1:P-256 MaxProtocol = TLSv1.3 @@ -1992,7 +2201,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-63] +[test-70] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -2000,21 +2209,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[64-curve-secp256k1-tls12-in-tls13] -ssl_conf = 64-curve-secp256k1-tls12-in-tls13-ssl +[71-curve-secp256k1-tls12-in-tls13] +ssl_conf = 71-curve-secp256k1-tls12-in-tls13-ssl -[64-curve-secp256k1-tls12-in-tls13-ssl] -server = 64-curve-secp256k1-tls12-in-tls13-server -client = 64-curve-secp256k1-tls12-in-tls13-client +[71-curve-secp256k1-tls12-in-tls13-ssl] +server = 71-curve-secp256k1-tls12-in-tls13-server +client = 71-curve-secp256k1-tls12-in-tls13-client -[64-curve-secp256k1-tls12-in-tls13-server] +[71-curve-secp256k1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp256k1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[64-curve-secp256k1-tls12-in-tls13-client] +[71-curve-secp256k1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp256k1:P-256 MaxProtocol = TLSv1.3 @@ -2022,7 +2231,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-64] +[test-71] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -2030,21 +2239,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[65-curve-brainpoolP256r1-tls12-in-tls13] -ssl_conf = 65-curve-brainpoolP256r1-tls12-in-tls13-ssl +[72-curve-brainpoolP256r1-tls12-in-tls13] +ssl_conf = 72-curve-brainpoolP256r1-tls12-in-tls13-ssl -[65-curve-brainpoolP256r1-tls12-in-tls13-ssl] -server = 65-curve-brainpoolP256r1-tls12-in-tls13-server -client = 65-curve-brainpoolP256r1-tls12-in-tls13-client +[72-curve-brainpoolP256r1-tls12-in-tls13-ssl] +server = 72-curve-brainpoolP256r1-tls12-in-tls13-server +client = 72-curve-brainpoolP256r1-tls12-in-tls13-client -[65-curve-brainpoolP256r1-tls12-in-tls13-server] +[72-curve-brainpoolP256r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = brainpoolP256r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[65-curve-brainpoolP256r1-tls12-in-tls13-client] +[72-curve-brainpoolP256r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = brainpoolP256r1:P-256 MaxProtocol = TLSv1.3 @@ -2052,7 +2261,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-65] +[test-72] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -2060,21 +2269,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[66-curve-brainpoolP384r1-tls12-in-tls13] -ssl_conf = 66-curve-brainpoolP384r1-tls12-in-tls13-ssl +[73-curve-brainpoolP384r1-tls12-in-tls13] +ssl_conf = 73-curve-brainpoolP384r1-tls12-in-tls13-ssl -[66-curve-brainpoolP384r1-tls12-in-tls13-ssl] -server = 66-curve-brainpoolP384r1-tls12-in-tls13-server -client = 66-curve-brainpoolP384r1-tls12-in-tls13-client +[73-curve-brainpoolP384r1-tls12-in-tls13-ssl] +server = 73-curve-brainpoolP384r1-tls12-in-tls13-server +client = 73-curve-brainpoolP384r1-tls12-in-tls13-client -[66-curve-brainpoolP384r1-tls12-in-tls13-server] +[73-curve-brainpoolP384r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = brainpoolP384r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[66-curve-brainpoolP384r1-tls12-in-tls13-client] +[73-curve-brainpoolP384r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = brainpoolP384r1:P-256 MaxProtocol = TLSv1.3 @@ -2082,7 +2291,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-66] +[test-73] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -2090,21 +2299,21 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[67-curve-brainpoolP512r1-tls12-in-tls13] -ssl_conf = 67-curve-brainpoolP512r1-tls12-in-tls13-ssl +[74-curve-brainpoolP512r1-tls12-in-tls13] +ssl_conf = 74-curve-brainpoolP512r1-tls12-in-tls13-ssl -[67-curve-brainpoolP512r1-tls12-in-tls13-ssl] -server = 67-curve-brainpoolP512r1-tls12-in-tls13-server -client = 67-curve-brainpoolP512r1-tls12-in-tls13-client +[74-curve-brainpoolP512r1-tls12-in-tls13-ssl] +server = 74-curve-brainpoolP512r1-tls12-in-tls13-server +client = 74-curve-brainpoolP512r1-tls12-in-tls13-client -[67-curve-brainpoolP512r1-tls12-in-tls13-server] +[74-curve-brainpoolP512r1-tls12-in-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = brainpoolP512r1:P-256 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[67-curve-brainpoolP512r1-tls12-in-tls13-client] +[74-curve-brainpoolP512r1-tls12-in-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = brainpoolP512r1:P-256 MaxProtocol = TLSv1.3 @@ -2112,7 +2321,7 @@ MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-67] +[test-74] ExpectedProtocol = TLSv1.3 ExpectedResult = Success ExpectedTmpKeyType = P-256 @@ -2120,1378 +2329,1351 @@ ExpectedTmpKeyType = P-256 # =========================================================== -[68-curve-sect233k1-tls13] -ssl_conf = 68-curve-sect233k1-tls13-ssl +[75-curve-sect233k1-tls13] +ssl_conf = 75-curve-sect233k1-tls13-ssl -[68-curve-sect233k1-tls13-ssl] -server = 68-curve-sect233k1-tls13-server -client = 68-curve-sect233k1-tls13-client +[75-curve-sect233k1-tls13-ssl] +server = 75-curve-sect233k1-tls13-server +client = 75-curve-sect233k1-tls13-client -[68-curve-sect233k1-tls13-server] +[75-curve-sect233k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect233k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[68-curve-sect233k1-tls13-client] +[75-curve-sect233k1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect233k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-68] +[test-75] ExpectedResult = ClientFail # =========================================================== -[69-curve-sect233r1-tls13] -ssl_conf = 69-curve-sect233r1-tls13-ssl +[76-curve-sect233r1-tls13] +ssl_conf = 76-curve-sect233r1-tls13-ssl -[69-curve-sect233r1-tls13-ssl] -server = 69-curve-sect233r1-tls13-server -client = 69-curve-sect233r1-tls13-client +[76-curve-sect233r1-tls13-ssl] +server = 76-curve-sect233r1-tls13-server +client = 76-curve-sect233r1-tls13-client -[69-curve-sect233r1-tls13-server] +[76-curve-sect233r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect233r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[69-curve-sect233r1-tls13-client] +[76-curve-sect233r1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect233r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-69] +[test-76] ExpectedResult = ClientFail # =========================================================== -[70-curve-sect283k1-tls13] -ssl_conf = 70-curve-sect283k1-tls13-ssl +[77-curve-sect283k1-tls13] +ssl_conf = 77-curve-sect283k1-tls13-ssl -[70-curve-sect283k1-tls13-ssl] -server = 70-curve-sect283k1-tls13-server -client = 70-curve-sect283k1-tls13-client +[77-curve-sect283k1-tls13-ssl] +server = 77-curve-sect283k1-tls13-server +client = 77-curve-sect283k1-tls13-client -[70-curve-sect283k1-tls13-server] +[77-curve-sect283k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect283k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[70-curve-sect283k1-tls13-client] +[77-curve-sect283k1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect283k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-70] +[test-77] ExpectedResult = ClientFail # =========================================================== -[71-curve-sect283r1-tls13] -ssl_conf = 71-curve-sect283r1-tls13-ssl +[78-curve-sect283r1-tls13] +ssl_conf = 78-curve-sect283r1-tls13-ssl -[71-curve-sect283r1-tls13-ssl] -server = 71-curve-sect283r1-tls13-server -client = 71-curve-sect283r1-tls13-client +[78-curve-sect283r1-tls13-ssl] +server = 78-curve-sect283r1-tls13-server +client = 78-curve-sect283r1-tls13-client -[71-curve-sect283r1-tls13-server] +[78-curve-sect283r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect283r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[71-curve-sect283r1-tls13-client] +[78-curve-sect283r1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect283r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-71] +[test-78] ExpectedResult = ClientFail # =========================================================== -[72-curve-sect409k1-tls13] -ssl_conf = 72-curve-sect409k1-tls13-ssl +[79-curve-sect409k1-tls13] +ssl_conf = 79-curve-sect409k1-tls13-ssl -[72-curve-sect409k1-tls13-ssl] -server = 72-curve-sect409k1-tls13-server -client = 72-curve-sect409k1-tls13-client +[79-curve-sect409k1-tls13-ssl] +server = 79-curve-sect409k1-tls13-server +client = 79-curve-sect409k1-tls13-client -[72-curve-sect409k1-tls13-server] +[79-curve-sect409k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect409k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[72-curve-sect409k1-tls13-client] +[79-curve-sect409k1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect409k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-72] +[test-79] ExpectedResult = ClientFail # =========================================================== -[73-curve-sect409r1-tls13] -ssl_conf = 73-curve-sect409r1-tls13-ssl +[80-curve-sect409r1-tls13] +ssl_conf = 80-curve-sect409r1-tls13-ssl -[73-curve-sect409r1-tls13-ssl] -server = 73-curve-sect409r1-tls13-server -client = 73-curve-sect409r1-tls13-client +[80-curve-sect409r1-tls13-ssl] +server = 80-curve-sect409r1-tls13-server +client = 80-curve-sect409r1-tls13-client -[73-curve-sect409r1-tls13-server] +[80-curve-sect409r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect409r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[73-curve-sect409r1-tls13-client] +[80-curve-sect409r1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect409r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-73] +[test-80] ExpectedResult = ClientFail # =========================================================== -[74-curve-sect571k1-tls13] -ssl_conf = 74-curve-sect571k1-tls13-ssl +[81-curve-sect571k1-tls13] +ssl_conf = 81-curve-sect571k1-tls13-ssl -[74-curve-sect571k1-tls13-ssl] -server = 74-curve-sect571k1-tls13-server -client = 74-curve-sect571k1-tls13-client +[81-curve-sect571k1-tls13-ssl] +server = 81-curve-sect571k1-tls13-server +client = 81-curve-sect571k1-tls13-client -[74-curve-sect571k1-tls13-server] +[81-curve-sect571k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect571k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[74-curve-sect571k1-tls13-client] +[81-curve-sect571k1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect571k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-74] +[test-81] ExpectedResult = ClientFail # =========================================================== -[75-curve-sect571r1-tls13] -ssl_conf = 75-curve-sect571r1-tls13-ssl +[82-curve-sect571r1-tls13] +ssl_conf = 82-curve-sect571r1-tls13-ssl -[75-curve-sect571r1-tls13-ssl] -server = 75-curve-sect571r1-tls13-server -client = 75-curve-sect571r1-tls13-client +[82-curve-sect571r1-tls13-ssl] +server = 82-curve-sect571r1-tls13-server +client = 82-curve-sect571r1-tls13-client -[75-curve-sect571r1-tls13-server] +[82-curve-sect571r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect571r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[75-curve-sect571r1-tls13-client] +[82-curve-sect571r1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect571r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-75] +[test-82] ExpectedResult = ClientFail # =========================================================== -[76-curve-secp224r1-tls13] -ssl_conf = 76-curve-secp224r1-tls13-ssl +[83-curve-secp224r1-tls13] +ssl_conf = 83-curve-secp224r1-tls13-ssl -[76-curve-secp224r1-tls13-ssl] -server = 76-curve-secp224r1-tls13-server -client = 76-curve-secp224r1-tls13-client +[83-curve-secp224r1-tls13-ssl] +server = 83-curve-secp224r1-tls13-server +client = 83-curve-secp224r1-tls13-client -[76-curve-secp224r1-tls13-server] +[83-curve-secp224r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp224r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[76-curve-secp224r1-tls13-client] +[83-curve-secp224r1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp224r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-76] +[test-83] ExpectedResult = ClientFail # =========================================================== -[77-curve-sect163k1-tls13] -ssl_conf = 77-curve-sect163k1-tls13-ssl +[84-curve-sect163k1-tls13] +ssl_conf = 84-curve-sect163k1-tls13-ssl -[77-curve-sect163k1-tls13-ssl] -server = 77-curve-sect163k1-tls13-server -client = 77-curve-sect163k1-tls13-client +[84-curve-sect163k1-tls13-ssl] +server = 84-curve-sect163k1-tls13-server +client = 84-curve-sect163k1-tls13-client -[77-curve-sect163k1-tls13-server] +[84-curve-sect163k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect163k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[77-curve-sect163k1-tls13-client] +[84-curve-sect163k1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect163k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-77] +[test-84] ExpectedResult = ClientFail # =========================================================== -[78-curve-sect163r2-tls13] -ssl_conf = 78-curve-sect163r2-tls13-ssl +[85-curve-sect163r2-tls13] +ssl_conf = 85-curve-sect163r2-tls13-ssl -[78-curve-sect163r2-tls13-ssl] -server = 78-curve-sect163r2-tls13-server -client = 78-curve-sect163r2-tls13-client +[85-curve-sect163r2-tls13-ssl] +server = 85-curve-sect163r2-tls13-server +client = 85-curve-sect163r2-tls13-client -[78-curve-sect163r2-tls13-server] +[85-curve-sect163r2-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect163r2 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[78-curve-sect163r2-tls13-client] +[85-curve-sect163r2-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect163r2 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-78] +[test-85] ExpectedResult = ClientFail # =========================================================== -[79-curve-prime192v1-tls13] -ssl_conf = 79-curve-prime192v1-tls13-ssl +[86-curve-prime192v1-tls13] +ssl_conf = 86-curve-prime192v1-tls13-ssl -[79-curve-prime192v1-tls13-ssl] -server = 79-curve-prime192v1-tls13-server -client = 79-curve-prime192v1-tls13-client +[86-curve-prime192v1-tls13-ssl] +server = 86-curve-prime192v1-tls13-server +client = 86-curve-prime192v1-tls13-client -[79-curve-prime192v1-tls13-server] +[86-curve-prime192v1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = prime192v1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[79-curve-prime192v1-tls13-client] +[86-curve-prime192v1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = prime192v1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-79] +[test-86] ExpectedResult = ClientFail # =========================================================== -[80-curve-sect163r1-tls13] -ssl_conf = 80-curve-sect163r1-tls13-ssl +[87-curve-sect163r1-tls13] +ssl_conf = 87-curve-sect163r1-tls13-ssl -[80-curve-sect163r1-tls13-ssl] -server = 80-curve-sect163r1-tls13-server -client = 80-curve-sect163r1-tls13-client +[87-curve-sect163r1-tls13-ssl] +server = 87-curve-sect163r1-tls13-server +client = 87-curve-sect163r1-tls13-client -[80-curve-sect163r1-tls13-server] +[87-curve-sect163r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect163r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[80-curve-sect163r1-tls13-client] +[87-curve-sect163r1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect163r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-80] +[test-87] ExpectedResult = ClientFail # =========================================================== -[81-curve-sect193r1-tls13] -ssl_conf = 81-curve-sect193r1-tls13-ssl +[88-curve-sect193r1-tls13] +ssl_conf = 88-curve-sect193r1-tls13-ssl -[81-curve-sect193r1-tls13-ssl] -server = 81-curve-sect193r1-tls13-server -client = 81-curve-sect193r1-tls13-client +[88-curve-sect193r1-tls13-ssl] +server = 88-curve-sect193r1-tls13-server +client = 88-curve-sect193r1-tls13-client -[81-curve-sect193r1-tls13-server] +[88-curve-sect193r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect193r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[81-curve-sect193r1-tls13-client] +[88-curve-sect193r1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect193r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-81] +[test-88] ExpectedResult = ClientFail # =========================================================== -[82-curve-sect193r2-tls13] -ssl_conf = 82-curve-sect193r2-tls13-ssl +[89-curve-sect193r2-tls13] +ssl_conf = 89-curve-sect193r2-tls13-ssl -[82-curve-sect193r2-tls13-ssl] -server = 82-curve-sect193r2-tls13-server -client = 82-curve-sect193r2-tls13-client +[89-curve-sect193r2-tls13-ssl] +server = 89-curve-sect193r2-tls13-server +client = 89-curve-sect193r2-tls13-client -[82-curve-sect193r2-tls13-server] +[89-curve-sect193r2-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect193r2 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[82-curve-sect193r2-tls13-client] +[89-curve-sect193r2-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect193r2 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-82] +[test-89] ExpectedResult = ClientFail # =========================================================== -[83-curve-sect239k1-tls13] -ssl_conf = 83-curve-sect239k1-tls13-ssl +[90-curve-sect239k1-tls13] +ssl_conf = 90-curve-sect239k1-tls13-ssl -[83-curve-sect239k1-tls13-ssl] -server = 83-curve-sect239k1-tls13-server -client = 83-curve-sect239k1-tls13-client +[90-curve-sect239k1-tls13-ssl] +server = 90-curve-sect239k1-tls13-server +client = 90-curve-sect239k1-tls13-client -[83-curve-sect239k1-tls13-server] +[90-curve-sect239k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = sect239k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[83-curve-sect239k1-tls13-client] +[90-curve-sect239k1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = sect239k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-83] +[test-90] ExpectedResult = ClientFail # =========================================================== -[84-curve-secp160k1-tls13] -ssl_conf = 84-curve-secp160k1-tls13-ssl +[91-curve-secp160k1-tls13] +ssl_conf = 91-curve-secp160k1-tls13-ssl -[84-curve-secp160k1-tls13-ssl] -server = 84-curve-secp160k1-tls13-server -client = 84-curve-secp160k1-tls13-client +[91-curve-secp160k1-tls13-ssl] +server = 91-curve-secp160k1-tls13-server +client = 91-curve-secp160k1-tls13-client -[84-curve-secp160k1-tls13-server] +[91-curve-secp160k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp160k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[84-curve-secp160k1-tls13-client] +[91-curve-secp160k1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp160k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-84] +[test-91] ExpectedResult = ClientFail # =========================================================== -[85-curve-secp160r1-tls13] -ssl_conf = 85-curve-secp160r1-tls13-ssl +[92-curve-secp160r1-tls13] +ssl_conf = 92-curve-secp160r1-tls13-ssl -[85-curve-secp160r1-tls13-ssl] -server = 85-curve-secp160r1-tls13-server -client = 85-curve-secp160r1-tls13-client +[92-curve-secp160r1-tls13-ssl] +server = 92-curve-secp160r1-tls13-server +client = 92-curve-secp160r1-tls13-client -[85-curve-secp160r1-tls13-server] +[92-curve-secp160r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp160r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[85-curve-secp160r1-tls13-client] +[92-curve-secp160r1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp160r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-85] +[test-92] ExpectedResult = ClientFail # =========================================================== -[86-curve-secp160r2-tls13] -ssl_conf = 86-curve-secp160r2-tls13-ssl +[93-curve-secp160r2-tls13] +ssl_conf = 93-curve-secp160r2-tls13-ssl -[86-curve-secp160r2-tls13-ssl] -server = 86-curve-secp160r2-tls13-server -client = 86-curve-secp160r2-tls13-client +[93-curve-secp160r2-tls13-ssl] +server = 93-curve-secp160r2-tls13-server +client = 93-curve-secp160r2-tls13-client -[86-curve-secp160r2-tls13-server] +[93-curve-secp160r2-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp160r2 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[86-curve-secp160r2-tls13-client] +[93-curve-secp160r2-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp160r2 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-86] +[test-93] ExpectedResult = ClientFail # =========================================================== -[87-curve-secp192k1-tls13] -ssl_conf = 87-curve-secp192k1-tls13-ssl +[94-curve-secp192k1-tls13] +ssl_conf = 94-curve-secp192k1-tls13-ssl -[87-curve-secp192k1-tls13-ssl] -server = 87-curve-secp192k1-tls13-server -client = 87-curve-secp192k1-tls13-client +[94-curve-secp192k1-tls13-ssl] +server = 94-curve-secp192k1-tls13-server +client = 94-curve-secp192k1-tls13-client -[87-curve-secp192k1-tls13-server] +[94-curve-secp192k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp192k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[87-curve-secp192k1-tls13-client] +[94-curve-secp192k1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp192k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-87] +[test-94] ExpectedResult = ClientFail # =========================================================== -[88-curve-secp224k1-tls13] -ssl_conf = 88-curve-secp224k1-tls13-ssl +[95-curve-secp224k1-tls13] +ssl_conf = 95-curve-secp224k1-tls13-ssl -[88-curve-secp224k1-tls13-ssl] -server = 88-curve-secp224k1-tls13-server -client = 88-curve-secp224k1-tls13-client +[95-curve-secp224k1-tls13-ssl] +server = 95-curve-secp224k1-tls13-server +client = 95-curve-secp224k1-tls13-client -[88-curve-secp224k1-tls13-server] +[95-curve-secp224k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp224k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[88-curve-secp224k1-tls13-client] +[95-curve-secp224k1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp224k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-88] +[test-95] ExpectedResult = ClientFail # =========================================================== -[89-curve-secp256k1-tls13] -ssl_conf = 89-curve-secp256k1-tls13-ssl +[96-curve-secp256k1-tls13] +ssl_conf = 96-curve-secp256k1-tls13-ssl -[89-curve-secp256k1-tls13-ssl] -server = 89-curve-secp256k1-tls13-server -client = 89-curve-secp256k1-tls13-client +[96-curve-secp256k1-tls13-ssl] +server = 96-curve-secp256k1-tls13-server +client = 96-curve-secp256k1-tls13-client -[89-curve-secp256k1-tls13-server] +[96-curve-secp256k1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = secp256k1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[89-curve-secp256k1-tls13-client] +[96-curve-secp256k1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = secp256k1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-89] +[test-96] ExpectedResult = ClientFail # =========================================================== -[90-curve-brainpoolP256r1-tls13] -ssl_conf = 90-curve-brainpoolP256r1-tls13-ssl +[97-curve-brainpoolP256r1-tls13] +ssl_conf = 97-curve-brainpoolP256r1-tls13-ssl -[90-curve-brainpoolP256r1-tls13-ssl] -server = 90-curve-brainpoolP256r1-tls13-server -client = 90-curve-brainpoolP256r1-tls13-client +[97-curve-brainpoolP256r1-tls13-ssl] +server = 97-curve-brainpoolP256r1-tls13-server +client = 97-curve-brainpoolP256r1-tls13-client -[90-curve-brainpoolP256r1-tls13-server] +[97-curve-brainpoolP256r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = brainpoolP256r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[90-curve-brainpoolP256r1-tls13-client] +[97-curve-brainpoolP256r1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = brainpoolP256r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-90] +[test-97] ExpectedResult = ClientFail # =========================================================== -[91-curve-brainpoolP384r1-tls13] -ssl_conf = 91-curve-brainpoolP384r1-tls13-ssl +[98-curve-brainpoolP384r1-tls13] +ssl_conf = 98-curve-brainpoolP384r1-tls13-ssl -[91-curve-brainpoolP384r1-tls13-ssl] -server = 91-curve-brainpoolP384r1-tls13-server -client = 91-curve-brainpoolP384r1-tls13-client +[98-curve-brainpoolP384r1-tls13-ssl] +server = 98-curve-brainpoolP384r1-tls13-server +client = 98-curve-brainpoolP384r1-tls13-client -[91-curve-brainpoolP384r1-tls13-server] +[98-curve-brainpoolP384r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = brainpoolP384r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[91-curve-brainpoolP384r1-tls13-client] +[98-curve-brainpoolP384r1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = brainpoolP384r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-91] +[test-98] ExpectedResult = ClientFail # =========================================================== -[92-curve-brainpoolP512r1-tls13] -ssl_conf = 92-curve-brainpoolP512r1-tls13-ssl +[99-curve-brainpoolP512r1-tls13] +ssl_conf = 99-curve-brainpoolP512r1-tls13-ssl -[92-curve-brainpoolP512r1-tls13-ssl] -server = 92-curve-brainpoolP512r1-tls13-server -client = 92-curve-brainpoolP512r1-tls13-client +[99-curve-brainpoolP512r1-tls13-ssl] +server = 99-curve-brainpoolP512r1-tls13-server +client = 99-curve-brainpoolP512r1-tls13-client -[92-curve-brainpoolP512r1-tls13-server] +[99-curve-brainpoolP512r1-tls13-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = brainpoolP512r1 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[92-curve-brainpoolP512r1-tls13-client] +[99-curve-brainpoolP512r1-tls13-client] CipherString = ECDHE@SECLEVEL=1 Curves = brainpoolP512r1 MinProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-92] +[test-99] ExpectedResult = ClientFail # =========================================================== -[93-curve-ffdhe2048-tls13-in-tls12] -ssl_conf = 93-curve-ffdhe2048-tls13-in-tls12-ssl - -[93-curve-ffdhe2048-tls13-in-tls12-ssl] -server = 93-curve-ffdhe2048-tls13-in-tls12-server -client = 93-curve-ffdhe2048-tls13-in-tls12-client - -[93-curve-ffdhe2048-tls13-in-tls12-server] -Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem -CipherString = DEFAULT@SECLEVEL=1 -Curves = ffdhe2048 -MaxProtocol = TLSv1.3 -PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem - -[93-curve-ffdhe2048-tls13-in-tls12-client] -CipherString = ECDHE@SECLEVEL=1 -Curves = ffdhe2048 -MaxProtocol = TLSv1.2 -VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem -VerifyMode = Peer - -[test-93] -ExpectedResult = ServerFail - - -# =========================================================== - -[94-curve-ffdhe2048-tls13-in-tls12-2] -ssl_conf = 94-curve-ffdhe2048-tls13-in-tls12-2-ssl +[100-curve-ffdhe2048-tls13-in-tls12-2] +ssl_conf = 100-curve-ffdhe2048-tls13-in-tls12-2-ssl -[94-curve-ffdhe2048-tls13-in-tls12-2-ssl] -server = 94-curve-ffdhe2048-tls13-in-tls12-2-server -client = 94-curve-ffdhe2048-tls13-in-tls12-2-client +[100-curve-ffdhe2048-tls13-in-tls12-2-ssl] +server = 100-curve-ffdhe2048-tls13-in-tls12-2-server +client = 100-curve-ffdhe2048-tls13-in-tls12-2-client -[94-curve-ffdhe2048-tls13-in-tls12-2-server] +[100-curve-ffdhe2048-tls13-in-tls12-2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = ffdhe2048 MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[94-curve-ffdhe2048-tls13-in-tls12-2-client] +[100-curve-ffdhe2048-tls13-in-tls12-2-client] CipherString = DEFAULT@SECLEVEL=1 Curves = ffdhe2048 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-94] +[test-100] ExpectedResult = Success # =========================================================== -[95-curve-ffdhe3072-tls13-in-tls12] -ssl_conf = 95-curve-ffdhe3072-tls13-in-tls12-ssl +[101-curve-ffdhe3072-tls13-in-tls12-2] +ssl_conf = 101-curve-ffdhe3072-tls13-in-tls12-2-ssl -[95-curve-ffdhe3072-tls13-in-tls12-ssl] -server = 95-curve-ffdhe3072-tls13-in-tls12-server -client = 95-curve-ffdhe3072-tls13-in-tls12-client +[101-curve-ffdhe3072-tls13-in-tls12-2-ssl] +server = 101-curve-ffdhe3072-tls13-in-tls12-2-server +client = 101-curve-ffdhe3072-tls13-in-tls12-2-client -[95-curve-ffdhe3072-tls13-in-tls12-server] +[101-curve-ffdhe3072-tls13-in-tls12-2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 Curves = ffdhe3072 -MaxProtocol = TLSv1.3 +MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[95-curve-ffdhe3072-tls13-in-tls12-client] -CipherString = ECDHE@SECLEVEL=1 +[101-curve-ffdhe3072-tls13-in-tls12-2-client] +CipherString = DEFAULT@SECLEVEL=1 Curves = ffdhe3072 -MaxProtocol = TLSv1.2 +MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-95] -ExpectedResult = ServerFail +[test-101] +ExpectedResult = Success # =========================================================== -[96-curve-ffdhe3072-tls13-in-tls12-2] -ssl_conf = 96-curve-ffdhe3072-tls13-in-tls12-2-ssl +[102-curve-ffdhe4096-tls13-in-tls12-2] +ssl_conf = 102-curve-ffdhe4096-tls13-in-tls12-2-ssl -[96-curve-ffdhe3072-tls13-in-tls12-2-ssl] -server = 96-curve-ffdhe3072-tls13-in-tls12-2-server -client = 96-curve-ffdhe3072-tls13-in-tls12-2-client +[102-curve-ffdhe4096-tls13-in-tls12-2-ssl] +server = 102-curve-ffdhe4096-tls13-in-tls12-2-server +client = 102-curve-ffdhe4096-tls13-in-tls12-2-client -[96-curve-ffdhe3072-tls13-in-tls12-2-server] +[102-curve-ffdhe4096-tls13-in-tls12-2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = ffdhe3072 +Curves = ffdhe4096 MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[96-curve-ffdhe3072-tls13-in-tls12-2-client] +[102-curve-ffdhe4096-tls13-in-tls12-2-client] CipherString = DEFAULT@SECLEVEL=1 -Curves = ffdhe3072 +Curves = ffdhe4096 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-96] +[test-102] ExpectedResult = Success # =========================================================== -[97-curve-ffdhe4096-tls13-in-tls12] -ssl_conf = 97-curve-ffdhe4096-tls13-in-tls12-ssl +[103-curve-ffdhe6144-tls13-in-tls12-2] +ssl_conf = 103-curve-ffdhe6144-tls13-in-tls12-2-ssl -[97-curve-ffdhe4096-tls13-in-tls12-ssl] -server = 97-curve-ffdhe4096-tls13-in-tls12-server -client = 97-curve-ffdhe4096-tls13-in-tls12-client +[103-curve-ffdhe6144-tls13-in-tls12-2-ssl] +server = 103-curve-ffdhe6144-tls13-in-tls12-2-server +client = 103-curve-ffdhe6144-tls13-in-tls12-2-client -[97-curve-ffdhe4096-tls13-in-tls12-server] +[103-curve-ffdhe6144-tls13-in-tls12-2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = ffdhe4096 -MaxProtocol = TLSv1.3 +Curves = ffdhe6144 +MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[97-curve-ffdhe4096-tls13-in-tls12-client] -CipherString = ECDHE@SECLEVEL=1 -Curves = ffdhe4096 -MaxProtocol = TLSv1.2 +[103-curve-ffdhe6144-tls13-in-tls12-2-client] +CipherString = DEFAULT@SECLEVEL=1 +Curves = ffdhe6144 +MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-97] -ExpectedResult = ServerFail +[test-103] +ExpectedResult = Success # =========================================================== -[98-curve-ffdhe4096-tls13-in-tls12-2] -ssl_conf = 98-curve-ffdhe4096-tls13-in-tls12-2-ssl +[104-curve-ffdhe8192-tls13-in-tls12-2] +ssl_conf = 104-curve-ffdhe8192-tls13-in-tls12-2-ssl -[98-curve-ffdhe4096-tls13-in-tls12-2-ssl] -server = 98-curve-ffdhe4096-tls13-in-tls12-2-server -client = 98-curve-ffdhe4096-tls13-in-tls12-2-client +[104-curve-ffdhe8192-tls13-in-tls12-2-ssl] +server = 104-curve-ffdhe8192-tls13-in-tls12-2-server +client = 104-curve-ffdhe8192-tls13-in-tls12-2-client -[98-curve-ffdhe4096-tls13-in-tls12-2-server] +[104-curve-ffdhe8192-tls13-in-tls12-2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = ffdhe4096 +Curves = ffdhe8192 MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[98-curve-ffdhe4096-tls13-in-tls12-2-client] +[104-curve-ffdhe8192-tls13-in-tls12-2-client] CipherString = DEFAULT@SECLEVEL=1 -Curves = ffdhe4096 +Curves = ffdhe8192 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-98] +[test-104] ExpectedResult = Success # =========================================================== -[99-curve-ffdhe6144-tls13-in-tls12] -ssl_conf = 99-curve-ffdhe6144-tls13-in-tls12-ssl +[105-curve-brainpoolP256r1tls13-tls13-in-tls12] +ssl_conf = 105-curve-brainpoolP256r1tls13-tls13-in-tls12-ssl -[99-curve-ffdhe6144-tls13-in-tls12-ssl] -server = 99-curve-ffdhe6144-tls13-in-tls12-server -client = 99-curve-ffdhe6144-tls13-in-tls12-client +[105-curve-brainpoolP256r1tls13-tls13-in-tls12-ssl] +server = 105-curve-brainpoolP256r1tls13-tls13-in-tls12-server +client = 105-curve-brainpoolP256r1tls13-tls13-in-tls12-client -[99-curve-ffdhe6144-tls13-in-tls12-server] +[105-curve-brainpoolP256r1tls13-tls13-in-tls12-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = ffdhe6144 +Curves = brainpoolP256r1tls13 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[99-curve-ffdhe6144-tls13-in-tls12-client] +[105-curve-brainpoolP256r1tls13-tls13-in-tls12-client] CipherString = ECDHE@SECLEVEL=1 -Curves = ffdhe6144 +Curves = brainpoolP256r1tls13 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-99] +[test-105] ExpectedResult = ServerFail # =========================================================== -[100-curve-ffdhe6144-tls13-in-tls12-2] -ssl_conf = 100-curve-ffdhe6144-tls13-in-tls12-2-ssl +[106-curve-brainpoolP256r1tls13-tls13-in-tls12-2] +ssl_conf = 106-curve-brainpoolP256r1tls13-tls13-in-tls12-2-ssl -[100-curve-ffdhe6144-tls13-in-tls12-2-ssl] -server = 100-curve-ffdhe6144-tls13-in-tls12-2-server -client = 100-curve-ffdhe6144-tls13-in-tls12-2-client +[106-curve-brainpoolP256r1tls13-tls13-in-tls12-2-ssl] +server = 106-curve-brainpoolP256r1tls13-tls13-in-tls12-2-server +client = 106-curve-brainpoolP256r1tls13-tls13-in-tls12-2-client -[100-curve-ffdhe6144-tls13-in-tls12-2-server] +[106-curve-brainpoolP256r1tls13-tls13-in-tls12-2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = ffdhe6144 +Curves = brainpoolP256r1tls13 MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[100-curve-ffdhe6144-tls13-in-tls12-2-client] +[106-curve-brainpoolP256r1tls13-tls13-in-tls12-2-client] CipherString = DEFAULT@SECLEVEL=1 -Curves = ffdhe6144 +Curves = brainpoolP256r1tls13 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-100] +[test-106] ExpectedResult = Success # =========================================================== -[101-curve-ffdhe8192-tls13-in-tls12] -ssl_conf = 101-curve-ffdhe8192-tls13-in-tls12-ssl +[107-curve-brainpoolP384r1tls13-tls13-in-tls12] +ssl_conf = 107-curve-brainpoolP384r1tls13-tls13-in-tls12-ssl -[101-curve-ffdhe8192-tls13-in-tls12-ssl] -server = 101-curve-ffdhe8192-tls13-in-tls12-server -client = 101-curve-ffdhe8192-tls13-in-tls12-client +[107-curve-brainpoolP384r1tls13-tls13-in-tls12-ssl] +server = 107-curve-brainpoolP384r1tls13-tls13-in-tls12-server +client = 107-curve-brainpoolP384r1tls13-tls13-in-tls12-client -[101-curve-ffdhe8192-tls13-in-tls12-server] +[107-curve-brainpoolP384r1tls13-tls13-in-tls12-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = ffdhe8192 +Curves = brainpoolP384r1tls13 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[101-curve-ffdhe8192-tls13-in-tls12-client] +[107-curve-brainpoolP384r1tls13-tls13-in-tls12-client] CipherString = ECDHE@SECLEVEL=1 -Curves = ffdhe8192 +Curves = brainpoolP384r1tls13 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-101] +[test-107] ExpectedResult = ServerFail # =========================================================== -[102-curve-ffdhe8192-tls13-in-tls12-2] -ssl_conf = 102-curve-ffdhe8192-tls13-in-tls12-2-ssl +[108-curve-brainpoolP384r1tls13-tls13-in-tls12-2] +ssl_conf = 108-curve-brainpoolP384r1tls13-tls13-in-tls12-2-ssl -[102-curve-ffdhe8192-tls13-in-tls12-2-ssl] -server = 102-curve-ffdhe8192-tls13-in-tls12-2-server -client = 102-curve-ffdhe8192-tls13-in-tls12-2-client +[108-curve-brainpoolP384r1tls13-tls13-in-tls12-2-ssl] +server = 108-curve-brainpoolP384r1tls13-tls13-in-tls12-2-server +client = 108-curve-brainpoolP384r1tls13-tls13-in-tls12-2-client -[102-curve-ffdhe8192-tls13-in-tls12-2-server] +[108-curve-brainpoolP384r1tls13-tls13-in-tls12-2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = ffdhe8192 +Curves = brainpoolP384r1tls13 MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[102-curve-ffdhe8192-tls13-in-tls12-2-client] +[108-curve-brainpoolP384r1tls13-tls13-in-tls12-2-client] CipherString = DEFAULT@SECLEVEL=1 -Curves = ffdhe8192 +Curves = brainpoolP384r1tls13 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-102] +[test-108] ExpectedResult = Success # =========================================================== -[103-curve-brainpoolP256r1tls13-tls13-in-tls12] -ssl_conf = 103-curve-brainpoolP256r1tls13-tls13-in-tls12-ssl +[109-curve-brainpoolP512r1tls13-tls13-in-tls12] +ssl_conf = 109-curve-brainpoolP512r1tls13-tls13-in-tls12-ssl -[103-curve-brainpoolP256r1tls13-tls13-in-tls12-ssl] -server = 103-curve-brainpoolP256r1tls13-tls13-in-tls12-server -client = 103-curve-brainpoolP256r1tls13-tls13-in-tls12-client +[109-curve-brainpoolP512r1tls13-tls13-in-tls12-ssl] +server = 109-curve-brainpoolP512r1tls13-tls13-in-tls12-server +client = 109-curve-brainpoolP512r1tls13-tls13-in-tls12-client -[103-curve-brainpoolP256r1tls13-tls13-in-tls12-server] +[109-curve-brainpoolP512r1tls13-tls13-in-tls12-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = brainpoolP256r1tls13 +Curves = brainpoolP512r1tls13 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[103-curve-brainpoolP256r1tls13-tls13-in-tls12-client] +[109-curve-brainpoolP512r1tls13-tls13-in-tls12-client] CipherString = ECDHE@SECLEVEL=1 -Curves = brainpoolP256r1tls13 +Curves = brainpoolP512r1tls13 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-103] +[test-109] ExpectedResult = ServerFail # =========================================================== -[104-curve-brainpoolP256r1tls13-tls13-in-tls12-2] -ssl_conf = 104-curve-brainpoolP256r1tls13-tls13-in-tls12-2-ssl +[110-curve-brainpoolP512r1tls13-tls13-in-tls12-2] +ssl_conf = 110-curve-brainpoolP512r1tls13-tls13-in-tls12-2-ssl -[104-curve-brainpoolP256r1tls13-tls13-in-tls12-2-ssl] -server = 104-curve-brainpoolP256r1tls13-tls13-in-tls12-2-server -client = 104-curve-brainpoolP256r1tls13-tls13-in-tls12-2-client +[110-curve-brainpoolP512r1tls13-tls13-in-tls12-2-ssl] +server = 110-curve-brainpoolP512r1tls13-tls13-in-tls12-2-server +client = 110-curve-brainpoolP512r1tls13-tls13-in-tls12-2-client -[104-curve-brainpoolP256r1tls13-tls13-in-tls12-2-server] +[110-curve-brainpoolP512r1tls13-tls13-in-tls12-2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = brainpoolP256r1tls13 +Curves = brainpoolP512r1tls13 MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[104-curve-brainpoolP256r1tls13-tls13-in-tls12-2-client] +[110-curve-brainpoolP512r1tls13-tls13-in-tls12-2-client] CipherString = DEFAULT@SECLEVEL=1 -Curves = brainpoolP256r1tls13 +Curves = brainpoolP512r1tls13 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-104] +[test-110] ExpectedResult = Success # =========================================================== -[105-curve-brainpoolP384r1tls13-tls13-in-tls12] -ssl_conf = 105-curve-brainpoolP384r1tls13-tls13-in-tls12-ssl +[111-curve-X25519MLKEM768-tls13-in-tls12] +ssl_conf = 111-curve-X25519MLKEM768-tls13-in-tls12-ssl -[105-curve-brainpoolP384r1tls13-tls13-in-tls12-ssl] -server = 105-curve-brainpoolP384r1tls13-tls13-in-tls12-server -client = 105-curve-brainpoolP384r1tls13-tls13-in-tls12-client +[111-curve-X25519MLKEM768-tls13-in-tls12-ssl] +server = 111-curve-X25519MLKEM768-tls13-in-tls12-server +client = 111-curve-X25519MLKEM768-tls13-in-tls12-client -[105-curve-brainpoolP384r1tls13-tls13-in-tls12-server] +[111-curve-X25519MLKEM768-tls13-in-tls12-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = brainpoolP384r1tls13 +Curves = X25519MLKEM768 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[105-curve-brainpoolP384r1tls13-tls13-in-tls12-client] +[111-curve-X25519MLKEM768-tls13-in-tls12-client] CipherString = ECDHE@SECLEVEL=1 -Curves = brainpoolP384r1tls13 +Curves = X25519MLKEM768 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-105] +[test-111] ExpectedResult = ServerFail # =========================================================== -[106-curve-brainpoolP384r1tls13-tls13-in-tls12-2] -ssl_conf = 106-curve-brainpoolP384r1tls13-tls13-in-tls12-2-ssl +[112-curve-X25519MLKEM768-tls13-in-tls12-2] +ssl_conf = 112-curve-X25519MLKEM768-tls13-in-tls12-2-ssl -[106-curve-brainpoolP384r1tls13-tls13-in-tls12-2-ssl] -server = 106-curve-brainpoolP384r1tls13-tls13-in-tls12-2-server -client = 106-curve-brainpoolP384r1tls13-tls13-in-tls12-2-client +[112-curve-X25519MLKEM768-tls13-in-tls12-2-ssl] +server = 112-curve-X25519MLKEM768-tls13-in-tls12-2-server +client = 112-curve-X25519MLKEM768-tls13-in-tls12-2-client -[106-curve-brainpoolP384r1tls13-tls13-in-tls12-2-server] +[112-curve-X25519MLKEM768-tls13-in-tls12-2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = brainpoolP384r1tls13 +Curves = X25519MLKEM768 MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[106-curve-brainpoolP384r1tls13-tls13-in-tls12-2-client] +[112-curve-X25519MLKEM768-tls13-in-tls12-2-client] CipherString = DEFAULT@SECLEVEL=1 -Curves = brainpoolP384r1tls13 +Curves = X25519MLKEM768 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-106] +[test-112] ExpectedResult = Success # =========================================================== -[107-curve-brainpoolP512r1tls13-tls13-in-tls12] -ssl_conf = 107-curve-brainpoolP512r1tls13-tls13-in-tls12-ssl +[113-curve-SecP256r1MLKEM768-tls13-in-tls12] +ssl_conf = 113-curve-SecP256r1MLKEM768-tls13-in-tls12-ssl -[107-curve-brainpoolP512r1tls13-tls13-in-tls12-ssl] -server = 107-curve-brainpoolP512r1tls13-tls13-in-tls12-server -client = 107-curve-brainpoolP512r1tls13-tls13-in-tls12-client +[113-curve-SecP256r1MLKEM768-tls13-in-tls12-ssl] +server = 113-curve-SecP256r1MLKEM768-tls13-in-tls12-server +client = 113-curve-SecP256r1MLKEM768-tls13-in-tls12-client -[107-curve-brainpoolP512r1tls13-tls13-in-tls12-server] +[113-curve-SecP256r1MLKEM768-tls13-in-tls12-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = brainpoolP512r1tls13 +Curves = SecP256r1MLKEM768 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[107-curve-brainpoolP512r1tls13-tls13-in-tls12-client] +[113-curve-SecP256r1MLKEM768-tls13-in-tls12-client] CipherString = ECDHE@SECLEVEL=1 -Curves = brainpoolP512r1tls13 +Curves = SecP256r1MLKEM768 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-107] +[test-113] ExpectedResult = ServerFail # =========================================================== -[108-curve-brainpoolP512r1tls13-tls13-in-tls12-2] -ssl_conf = 108-curve-brainpoolP512r1tls13-tls13-in-tls12-2-ssl +[114-curve-SecP256r1MLKEM768-tls13-in-tls12-2] +ssl_conf = 114-curve-SecP256r1MLKEM768-tls13-in-tls12-2-ssl -[108-curve-brainpoolP512r1tls13-tls13-in-tls12-2-ssl] -server = 108-curve-brainpoolP512r1tls13-tls13-in-tls12-2-server -client = 108-curve-brainpoolP512r1tls13-tls13-in-tls12-2-client +[114-curve-SecP256r1MLKEM768-tls13-in-tls12-2-ssl] +server = 114-curve-SecP256r1MLKEM768-tls13-in-tls12-2-server +client = 114-curve-SecP256r1MLKEM768-tls13-in-tls12-2-client -[108-curve-brainpoolP512r1tls13-tls13-in-tls12-2-server] +[114-curve-SecP256r1MLKEM768-tls13-in-tls12-2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = brainpoolP512r1tls13 +Curves = SecP256r1MLKEM768 MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[108-curve-brainpoolP512r1tls13-tls13-in-tls12-2-client] +[114-curve-SecP256r1MLKEM768-tls13-in-tls12-2-client] CipherString = DEFAULT@SECLEVEL=1 -Curves = brainpoolP512r1tls13 +Curves = SecP256r1MLKEM768 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-108] +[test-114] ExpectedResult = Success # =========================================================== -[109-curve-X25519MLKEM768-tls13-in-tls12] -ssl_conf = 109-curve-X25519MLKEM768-tls13-in-tls12-ssl +[115-curve-SecP384r1MLKEM1024-tls13-in-tls12] +ssl_conf = 115-curve-SecP384r1MLKEM1024-tls13-in-tls12-ssl -[109-curve-X25519MLKEM768-tls13-in-tls12-ssl] -server = 109-curve-X25519MLKEM768-tls13-in-tls12-server -client = 109-curve-X25519MLKEM768-tls13-in-tls12-client +[115-curve-SecP384r1MLKEM1024-tls13-in-tls12-ssl] +server = 115-curve-SecP384r1MLKEM1024-tls13-in-tls12-server +client = 115-curve-SecP384r1MLKEM1024-tls13-in-tls12-client -[109-curve-X25519MLKEM768-tls13-in-tls12-server] +[115-curve-SecP384r1MLKEM1024-tls13-in-tls12-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = X25519MLKEM768 +Curves = SecP384r1MLKEM1024 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[109-curve-X25519MLKEM768-tls13-in-tls12-client] +[115-curve-SecP384r1MLKEM1024-tls13-in-tls12-client] CipherString = ECDHE@SECLEVEL=1 -Curves = X25519MLKEM768 +Curves = SecP384r1MLKEM1024 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-109] +[test-115] ExpectedResult = ServerFail # =========================================================== -[110-curve-X25519MLKEM768-tls13-in-tls12-2] -ssl_conf = 110-curve-X25519MLKEM768-tls13-in-tls12-2-ssl +[116-curve-SecP384r1MLKEM1024-tls13-in-tls12-2] +ssl_conf = 116-curve-SecP384r1MLKEM1024-tls13-in-tls12-2-ssl -[110-curve-X25519MLKEM768-tls13-in-tls12-2-ssl] -server = 110-curve-X25519MLKEM768-tls13-in-tls12-2-server -client = 110-curve-X25519MLKEM768-tls13-in-tls12-2-client +[116-curve-SecP384r1MLKEM1024-tls13-in-tls12-2-ssl] +server = 116-curve-SecP384r1MLKEM1024-tls13-in-tls12-2-server +client = 116-curve-SecP384r1MLKEM1024-tls13-in-tls12-2-client -[110-curve-X25519MLKEM768-tls13-in-tls12-2-server] +[116-curve-SecP384r1MLKEM1024-tls13-in-tls12-2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = X25519MLKEM768 +Curves = SecP384r1MLKEM1024 MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[110-curve-X25519MLKEM768-tls13-in-tls12-2-client] +[116-curve-SecP384r1MLKEM1024-tls13-in-tls12-2-client] CipherString = DEFAULT@SECLEVEL=1 -Curves = X25519MLKEM768 +Curves = SecP384r1MLKEM1024 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-110] +[test-116] ExpectedResult = Success # =========================================================== -[111-curve-SecP256r1MLKEM768-tls13-in-tls12] -ssl_conf = 111-curve-SecP256r1MLKEM768-tls13-in-tls12-ssl +[117-curve-curveSM2-tls13-in-tls12] +ssl_conf = 117-curve-curveSM2-tls13-in-tls12-ssl -[111-curve-SecP256r1MLKEM768-tls13-in-tls12-ssl] -server = 111-curve-SecP256r1MLKEM768-tls13-in-tls12-server -client = 111-curve-SecP256r1MLKEM768-tls13-in-tls12-client +[117-curve-curveSM2-tls13-in-tls12-ssl] +server = 117-curve-curveSM2-tls13-in-tls12-server +client = 117-curve-curveSM2-tls13-in-tls12-client -[111-curve-SecP256r1MLKEM768-tls13-in-tls12-server] +[117-curve-curveSM2-tls13-in-tls12-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = SecP256r1MLKEM768 +Curves = curveSM2 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[111-curve-SecP256r1MLKEM768-tls13-in-tls12-client] +[117-curve-curveSM2-tls13-in-tls12-client] CipherString = ECDHE@SECLEVEL=1 -Curves = SecP256r1MLKEM768 +Curves = curveSM2 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-111] +[test-117] ExpectedResult = ServerFail # =========================================================== -[112-curve-SecP256r1MLKEM768-tls13-in-tls12-2] -ssl_conf = 112-curve-SecP256r1MLKEM768-tls13-in-tls12-2-ssl +[118-curve-curveSM2-tls13-in-tls12-2] +ssl_conf = 118-curve-curveSM2-tls13-in-tls12-2-ssl -[112-curve-SecP256r1MLKEM768-tls13-in-tls12-2-ssl] -server = 112-curve-SecP256r1MLKEM768-tls13-in-tls12-2-server -client = 112-curve-SecP256r1MLKEM768-tls13-in-tls12-2-client +[118-curve-curveSM2-tls13-in-tls12-2-ssl] +server = 118-curve-curveSM2-tls13-in-tls12-2-server +client = 118-curve-curveSM2-tls13-in-tls12-2-client -[112-curve-SecP256r1MLKEM768-tls13-in-tls12-2-server] +[118-curve-curveSM2-tls13-in-tls12-2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = SecP256r1MLKEM768 +Curves = curveSM2 MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[112-curve-SecP256r1MLKEM768-tls13-in-tls12-2-client] +[118-curve-curveSM2-tls13-in-tls12-2-client] CipherString = DEFAULT@SECLEVEL=1 -Curves = SecP256r1MLKEM768 +Curves = curveSM2 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-112] +[test-118] ExpectedResult = Success # =========================================================== -[113-curve-SecP384r1MLKEM1024-tls13-in-tls12] -ssl_conf = 113-curve-SecP384r1MLKEM1024-tls13-in-tls12-ssl +[119-curve-curveSM2MLKEM768-tls13-in-tls12] +ssl_conf = 119-curve-curveSM2MLKEM768-tls13-in-tls12-ssl -[113-curve-SecP384r1MLKEM1024-tls13-in-tls12-ssl] -server = 113-curve-SecP384r1MLKEM1024-tls13-in-tls12-server -client = 113-curve-SecP384r1MLKEM1024-tls13-in-tls12-client +[119-curve-curveSM2MLKEM768-tls13-in-tls12-ssl] +server = 119-curve-curveSM2MLKEM768-tls13-in-tls12-server +client = 119-curve-curveSM2MLKEM768-tls13-in-tls12-client -[113-curve-SecP384r1MLKEM1024-tls13-in-tls12-server] +[119-curve-curveSM2MLKEM768-tls13-in-tls12-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = SecP384r1MLKEM1024 +Curves = curveSM2MLKEM768 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[113-curve-SecP384r1MLKEM1024-tls13-in-tls12-client] +[119-curve-curveSM2MLKEM768-tls13-in-tls12-client] CipherString = ECDHE@SECLEVEL=1 -Curves = SecP384r1MLKEM1024 +Curves = curveSM2MLKEM768 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-113] +[test-119] ExpectedResult = ServerFail # =========================================================== -[114-curve-SecP384r1MLKEM1024-tls13-in-tls12-2] -ssl_conf = 114-curve-SecP384r1MLKEM1024-tls13-in-tls12-2-ssl +[120-curve-curveSM2MLKEM768-tls13-in-tls12-2] +ssl_conf = 120-curve-curveSM2MLKEM768-tls13-in-tls12-2-ssl -[114-curve-SecP384r1MLKEM1024-tls13-in-tls12-2-ssl] -server = 114-curve-SecP384r1MLKEM1024-tls13-in-tls12-2-server -client = 114-curve-SecP384r1MLKEM1024-tls13-in-tls12-2-client +[120-curve-curveSM2MLKEM768-tls13-in-tls12-2-ssl] +server = 120-curve-curveSM2MLKEM768-tls13-in-tls12-2-server +client = 120-curve-curveSM2MLKEM768-tls13-in-tls12-2-client -[114-curve-SecP384r1MLKEM1024-tls13-in-tls12-2-server] +[120-curve-curveSM2MLKEM768-tls13-in-tls12-2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = SecP384r1MLKEM1024 +Curves = curveSM2MLKEM768 MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[114-curve-SecP384r1MLKEM1024-tls13-in-tls12-2-client] +[120-curve-curveSM2MLKEM768-tls13-in-tls12-2-client] CipherString = DEFAULT@SECLEVEL=1 -Curves = SecP384r1MLKEM1024 +Curves = curveSM2MLKEM768 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-114] +[test-120] ExpectedResult = Success # =========================================================== -[115-curve-curveSM2-tls13-in-tls12] -ssl_conf = 115-curve-curveSM2-tls13-in-tls12-ssl +[121-curve-MLKEM512X25519-tls13-in-tls12] +ssl_conf = 121-curve-MLKEM512X25519-tls13-in-tls12-ssl -[115-curve-curveSM2-tls13-in-tls12-ssl] -server = 115-curve-curveSM2-tls13-in-tls12-server -client = 115-curve-curveSM2-tls13-in-tls12-client +[121-curve-MLKEM512X25519-tls13-in-tls12-ssl] +server = 121-curve-MLKEM512X25519-tls13-in-tls12-server +client = 121-curve-MLKEM512X25519-tls13-in-tls12-client -[115-curve-curveSM2-tls13-in-tls12-server] +[121-curve-MLKEM512X25519-tls13-in-tls12-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = curveSM2 +Curves = MLKEM512X25519 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[115-curve-curveSM2-tls13-in-tls12-client] +[121-curve-MLKEM512X25519-tls13-in-tls12-client] CipherString = ECDHE@SECLEVEL=1 -Curves = curveSM2 +Curves = MLKEM512X25519 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-115] +[test-121] ExpectedResult = ServerFail # =========================================================== -[116-curve-curveSM2-tls13-in-tls12-2] -ssl_conf = 116-curve-curveSM2-tls13-in-tls12-2-ssl +[122-curve-MLKEM512X25519-tls13-in-tls12-2] +ssl_conf = 122-curve-MLKEM512X25519-tls13-in-tls12-2-ssl -[116-curve-curveSM2-tls13-in-tls12-2-ssl] -server = 116-curve-curveSM2-tls13-in-tls12-2-server -client = 116-curve-curveSM2-tls13-in-tls12-2-client +[122-curve-MLKEM512X25519-tls13-in-tls12-2-ssl] +server = 122-curve-MLKEM512X25519-tls13-in-tls12-2-server +client = 122-curve-MLKEM512X25519-tls13-in-tls12-2-client -[116-curve-curveSM2-tls13-in-tls12-2-server] +[122-curve-MLKEM512X25519-tls13-in-tls12-2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = curveSM2 +Curves = MLKEM512X25519 MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[116-curve-curveSM2-tls13-in-tls12-2-client] +[122-curve-MLKEM512X25519-tls13-in-tls12-2-client] CipherString = DEFAULT@SECLEVEL=1 -Curves = curveSM2 +Curves = MLKEM512X25519 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-116] +[test-122] ExpectedResult = Success # =========================================================== -[117-curve-curveSM2MLKEM768-tls13-in-tls12] -ssl_conf = 117-curve-curveSM2MLKEM768-tls13-in-tls12-ssl +[123-curve-SecP256r1MLKEM512-tls13-in-tls12] +ssl_conf = 123-curve-SecP256r1MLKEM512-tls13-in-tls12-ssl -[117-curve-curveSM2MLKEM768-tls13-in-tls12-ssl] -server = 117-curve-curveSM2MLKEM768-tls13-in-tls12-server -client = 117-curve-curveSM2MLKEM768-tls13-in-tls12-client +[123-curve-SecP256r1MLKEM512-tls13-in-tls12-ssl] +server = 123-curve-SecP256r1MLKEM512-tls13-in-tls12-server +client = 123-curve-SecP256r1MLKEM512-tls13-in-tls12-client -[117-curve-curveSM2MLKEM768-tls13-in-tls12-server] +[123-curve-SecP256r1MLKEM512-tls13-in-tls12-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = curveSM2MLKEM768 +Curves = SecP256r1MLKEM512 MaxProtocol = TLSv1.3 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[117-curve-curveSM2MLKEM768-tls13-in-tls12-client] +[123-curve-SecP256r1MLKEM512-tls13-in-tls12-client] CipherString = ECDHE@SECLEVEL=1 -Curves = curveSM2MLKEM768 +Curves = SecP256r1MLKEM512 MaxProtocol = TLSv1.2 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-117] +[test-123] ExpectedResult = ServerFail # =========================================================== -[118-curve-curveSM2MLKEM768-tls13-in-tls12-2] -ssl_conf = 118-curve-curveSM2MLKEM768-tls13-in-tls12-2-ssl +[124-curve-SecP256r1MLKEM512-tls13-in-tls12-2] +ssl_conf = 124-curve-SecP256r1MLKEM512-tls13-in-tls12-2-ssl -[118-curve-curveSM2MLKEM768-tls13-in-tls12-2-ssl] -server = 118-curve-curveSM2MLKEM768-tls13-in-tls12-2-server -client = 118-curve-curveSM2MLKEM768-tls13-in-tls12-2-client +[124-curve-SecP256r1MLKEM512-tls13-in-tls12-2-ssl] +server = 124-curve-SecP256r1MLKEM512-tls13-in-tls12-2-server +client = 124-curve-SecP256r1MLKEM512-tls13-in-tls12-2-client -[118-curve-curveSM2MLKEM768-tls13-in-tls12-2-server] +[124-curve-SecP256r1MLKEM512-tls13-in-tls12-2-server] Certificate = ${ENV::TEST_CERTS_DIR}/servercert.pem CipherString = DEFAULT@SECLEVEL=1 -Curves = curveSM2MLKEM768 +Curves = SecP256r1MLKEM512 MaxProtocol = TLSv1.2 PrivateKey = ${ENV::TEST_CERTS_DIR}/serverkey.pem -[118-curve-curveSM2MLKEM768-tls13-in-tls12-2-client] +[124-curve-SecP256r1MLKEM512-tls13-in-tls12-2-client] CipherString = DEFAULT@SECLEVEL=1 -Curves = curveSM2MLKEM768 +Curves = SecP256r1MLKEM512 MaxProtocol = TLSv1.3 VerifyCAFile = ${ENV::TEST_CERTS_DIR}/rootcert.pem VerifyMode = Peer -[test-118] +[test-124] ExpectedResult = Success diff --git a/test/ssl-tests/14-curves.cnf.in b/test/ssl-tests/14-curves.cnf.in index abcdb5dc0f7c6..c3cbbecd5a5c2 100644 --- a/test/ssl-tests/14-curves.cnf.in +++ b/test/ssl-tests/14-curves.cnf.in @@ -10,39 +10,82 @@ use warnings; use OpenSSL::Test; use OpenSSL::Test::Utils; +# Set in test/generate_ssl_tests.pl:read_config() our $fips_mode; our $fips_3_4; our $fips_3_5; +our $fips_4_2; -my @curves = ("prime256v1", "secp384r1", "secp521r1"); +my @curves = qw( + prime256v1 + secp384r1 + secp521r1 + ) unless (disabled("ec")); -my @curves_no_fips = ("X25519", "X448"); +my @curves_no_fips; +push @curves_no_fips, qw( + X25519 + X448 + ) unless (disabled("ecx")); push @curves, @curves_no_fips if !$fips_mode; +#Curves suitable for for both TLS 1.2 and TLS 1.3 +my @curves_tls = qw( + ffdhe2048 + ffdhe3072 + ffdhe4096 + ffdhe6144 + ffdhe8192 + ) unless (disabled("dh")); + #Curves *only* suitable for use in TLSv1.3 -my @curves_tls_1_3 = ("ffdhe2048", "ffdhe3072", "ffdhe4096", "ffdhe6144", - "ffdhe8192"); -my @curves_tls_1_3_no_fips = ("brainpoolP256r1tls13", "brainpoolP384r1tls13", - "brainpoolP512r1tls13"); +my @curves_tls_1_3 = @curves_tls; + +my @curves_tls_1_3_no_fips; +push @curves_tls_1_3_no_fips, qw( + brainpoolP256r1tls13 + brainpoolP384r1tls13 + brainpoolP512r1tls13 + ) unless (disabled("ec")); push @curves_tls_1_3, @curves_tls_1_3_no_fips if !$fips_mode; push @curves, @curves_tls_1_3; -my @curves_tls_1_2 = (); -push @curves_tls_1_2, - "sect233k1", "sect233r1", "sect283k1", "sect283r1", "sect409k1", - "sect409r1", "sect571k1", "sect571r1", "secp224r1" - unless ($fips_3_4 || disabled("tls-deprecated-ec")); +my @curves_tls_1_2 = @curves_tls; +push @curves_tls_1_2, qw( + sect233k1 + sect233r1 + sect283k1 + sect283r1 + sect409k1 + sect409r1 + sect571k1 + sect571r1 + secp224r1 + ) unless ($fips_3_4 || disabled("tls-deprecated-ec")); my @curves_non_fips = (); -push @curves_non_fips, - "sect163k1", "sect163r2", "prime192v1", "sect163r1", "sect193r1", - "sect193r2", "sect239k1", "secp160k1", "secp160r1", "secp160r2", - "secp192k1", "secp224k1", "secp256k1" - unless disabled("tls-deprecated-ec"); -push @curves_non_fips, - "brainpoolP256r1", "brainpoolP384r1", "brainpoolP512r1"; +push @curves_non_fips, qw( + sect163k1 + sect163r2 + prime192v1 + sect163r1 + sect193r1 + sect193r2 + sect239k1 + secp160k1 + secp160r1 + secp160r2 + secp192k1 + secp224k1 + secp256k1 + ) unless disabled("tls-deprecated-ec"); +push @curves_non_fips, qw( + brainpoolP256r1 + brainpoolP384r1 + brainpoolP512r1 + ) unless (disabled("ec")); push @curves_tls_1_2, @curves_non_fips if !$fips_mode; @@ -50,11 +93,15 @@ my @curves_no_nid = (); push @curves_no_nid, qw(X25519MLKEM768) unless (disabled("ml-kem") || disabled("ecx") || ($fips_mode && !$fips_3_5)); push @curves_no_nid, qw(SecP256r1MLKEM768 SecP384r1MLKEM1024) - unless (disabled("ml-kem") || ($fips_mode && !$fips_3_5)); + unless (disabled("ml-kem") || disabled("ec") || ($fips_mode && !$fips_3_5)); push @curves_no_nid, qw(curveSM2) - unless ($fips_mode || disabled("sm2")); + unless (disabled("sm2") || $fips_mode); push @curves_no_nid, qw(curveSM2MLKEM768) - unless ($fips_mode || disabled("sm2") || disabled("ml-kem")); + unless (disabled("ml-kem") || disabled("sm2") || $fips_mode); +push @curves_no_nid, qw(MLKEM512X25519) + unless (disabled("ml-kem") || disabled("ecx") || ($fips_mode && !$fips_4_2)); +push @curves_no_nid, qw(SecP256r1MLKEM512) + unless (disabled("ml-kem") || disabled("ec") || ($fips_mode && !$fips_4_2)); push @curves_tls_1_3, @curves_no_nid; push @curves, @curves_no_nid; @@ -77,6 +124,7 @@ sub get_key_type { sub generate_tests() { foreach (0..$#curves) { my $curve = $curves[$_]; + my $cipher = $curve =~ m{^ffdhe\d+$} ? "DHE" : "ECDHE"; push @tests, { name => "curve-${curve}", server => { @@ -85,12 +133,12 @@ sub generate_tests() { "MaxProtocol" => "TLSv1.3" }, client => { - "CipherString" => 'ECDHE@SECLEVEL=1', + "CipherString" => $cipher . '@SECLEVEL=1', "MaxProtocol" => "TLSv1.3", "Curves" => $curve }, test => { - "ExpectedTmpKeyType" => get_key_type($curve), + "ExpectedTmpKeyType" => $curve, "ExpectedProtocol" => "TLSv1.3", "ExpectedResult" => "Success" }, @@ -98,6 +146,7 @@ sub generate_tests() { } foreach (0..$#curves_tls_1_2) { my $curve = $curves_tls_1_2[$_]; + my $cipher = ($curve =~ m{^ffdhe}) ? "DHE" : "ECDHE"; push @tests, { name => "curve-${curve}", server => { @@ -106,7 +155,7 @@ sub generate_tests() { "MaxProtocol" => "TLSv1.3" }, client => { - "CipherString" => 'ECDHE@SECLEVEL=1', + "CipherString" => $cipher . '@SECLEVEL=1', "MaxProtocol" => "TLSv1.2", "Curves" => $curve }, @@ -139,7 +188,7 @@ sub generate_tests() { "ExpectedProtocol" => "TLSv1.3", "ExpectedResult" => "Success" }, - }; + } unless $curve =~ m{^ffdhe\d+$}; # Valid in both protocols } foreach (0..$#curves_tls_1_2) { my $curve = $curves_tls_1_2[$_]; @@ -158,7 +207,7 @@ sub generate_tests() { test => { "ExpectedResult" => "ClientFail" }, - }; + } unless $curve =~ m{^ffdhe\d+$}; # Valid in both protocols } if (!$fips_3_4) { foreach (0..$#curves_tls_1_3) { @@ -181,7 +230,7 @@ sub generate_tests() { #ECDHE key exchange "ExpectedResult" => "ServerFail" }, - }; + } unless $curve =~ m{^ffdhe\d+$}; # Valid in both protocols push @tests, { name => "curve-${curve}-tls13-in-tls12-2", server => { diff --git a/test/ssl-tests/18-dtls-renegotiate.cnf.in b/test/ssl-tests/18-dtls-renegotiate.cnf.in index 8996849a2c725..2c99d8b1ffda8 100644 --- a/test/ssl-tests/18-dtls-renegotiate.cnf.in +++ b/test/ssl-tests/18-dtls-renegotiate.cnf.in @@ -1,5 +1,5 @@ # -*- mode: perl; -*- -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -23,7 +23,7 @@ our @tests = (); foreach my $sctp ("No", "Yes") { next if disabled("sctp") && $sctp eq "Yes"; - next if disabled("dtls1_2") && $fips_mode; + next if disabled("dtls1_2"); my $suffix = ($sctp eq "No") ? "" : "-sctp"; our @tests_basic = ( diff --git a/test/ssl-tests/29-dtls-sctp-label-bug.cnf b/test/ssl-tests/29-dtls-sctp-label-bug.cnf index 24f9e04f16d93..157045dfaf74c 100644 --- a/test/ssl-tests/29-dtls-sctp-label-bug.cnf +++ b/test/ssl-tests/29-dtls-sctp-label-bug.cnf @@ -28,6 +28,7 @@ VerifyMode = Peer [test-0] EnableClientSCTPLabelBug = No EnableServerSCTPLabelBug = No +ExpectedProtocol = DTLSv1.2 ExpectedResult = Success Method = DTLS UseSCTP = Yes @@ -55,6 +56,7 @@ VerifyMode = Peer [test-1] EnableClientSCTPLabelBug = Yes EnableServerSCTPLabelBug = Yes +ExpectedProtocol = DTLSv1.2 ExpectedResult = Success Method = DTLS UseSCTP = Yes diff --git a/test/ssl-tests/29-dtls-sctp-label-bug.cnf.in b/test/ssl-tests/29-dtls-sctp-label-bug.cnf.in index f14e68139d3eb..8801e5b1920de 100644 --- a/test/ssl-tests/29-dtls-sctp-label-bug.cnf.in +++ b/test/ssl-tests/29-dtls-sctp-label-bug.cnf.in @@ -1,5 +1,5 @@ # -*- mode: perl; -*- -# Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2019-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -25,7 +25,8 @@ our @tests = ( "UseSCTP" => "Yes", "EnableClientSCTPLabelBug" => "No", "EnableServerSCTPLabelBug" => "No", - "ExpectedResult" => "Success" + "ExpectedResult" => "Success", + "ExpectedProtocol" => "DTLSv1.2" } }, { @@ -37,7 +38,8 @@ our @tests = ( "UseSCTP" => "Yes", "EnableClientSCTPLabelBug" => "Yes", "EnableServerSCTPLabelBug" => "Yes", - "ExpectedResult" => "Success" + "ExpectedResult" => "Success", + "ExpectedProtocol" => "DTLSv1.2" } }, { diff --git a/test/ssl-tests/protocol_version.pm b/test/ssl-tests/protocol_version.pm index 4a5522fc4c337..cbe42e9182232 100644 --- a/test/ssl-tests/protocol_version.pm +++ b/test/ssl-tests/protocol_version.pm @@ -1,5 +1,5 @@ # -*- mode: perl; -*- -# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -66,6 +66,9 @@ sub max_prot_enabled { foreach my $i (0..$#protocols) { if (!$is_disabled[$i] && ($protocols[$i] ne "TLSv1.3" + || !disabled("ec") + || !disabled("dh")) + && ($protocols[$i] ne "DTLSv1.3" || !disabled("ec") || !disabled("dh"))) { $max_enabled = $i; @@ -80,16 +83,16 @@ $min_tls_enabled_fips = min_prot_enabled(\@tls_protocols_fips, \@is_tls_disabled $max_tls_enabled_fips = max_prot_enabled(\@tls_protocols_fips, \@is_tls_disabled_fips); -my @dtls_protocols = ("DTLSv1", "DTLSv1.2"); -my @dtls_protocols_fips = ("DTLSv1.2"); +my @dtls_protocols = ("DTLSv1", "DTLSv1.2", "DTLSv1.3"); +my @dtls_protocols_fips = ("DTLSv1.2", "DTLSv1.3"); # undef stands for "no limit". -my @min_dtls_protocols = (undef, "DTLSv1", "DTLSv1.2"); -my @min_dtls_protocols_fips = (undef, "DTLSv1.2"); -my @max_dtls_protocols = ("DTLSv1", "DTLSv1.2", undef); -my @max_dtls_protocols_fips = ("DTLSv1.2", undef); +my @min_dtls_protocols = (undef, "DTLSv1", "DTLSv1.2", "DTLSv1.3"); +my @min_dtls_protocols_fips = (undef, "DTLSv1.2", "DTLSv1.3"); +my @max_dtls_protocols = ("DTLSv1", "DTLSv1.2", "DTLSv1.3", undef); +my @max_dtls_protocols_fips = ("DTLSv1.2", "DTLSv1.3", undef); -my @is_dtls_disabled = anydisabled("dtls1", "dtls1_2"); -my @is_dtls_disabled_fips = anydisabled("dtls1_2"); +my @is_dtls_disabled = anydisabled("dtls1", "dtls1_2", "dtls1_3"); +my @is_dtls_disabled_fips = anydisabled("dtls1_2", "dtls1_3"); my $min_dtls_enabled; my $max_dtls_enabled; my $min_dtls_enabled_fips; my $max_dtls_enabled_fips; @@ -104,9 +107,9 @@ $max_dtls_enabled_fips = max_prot_enabled(\@dtls_protocols_fips, \@is_dtls_disab sub no_tests { my ($dtls, $fips) = @_; if ($dtls && $fips) { - return disabled("dtls1_2"); + return alldisabled("dtls1_2", "dtls1_3"); } - return $dtls ? alldisabled("dtls1", "dtls1_2") : + return $dtls ? alldisabled("dtls1", "dtls1_2", "dtls1_3") : alldisabled("tls1", "tls1_1", "tls1_2", "tls1_3"); } @@ -152,7 +155,7 @@ sub generate_version_tests { foreach my $s_max ($s_max_min..$#max_protocols) { my ($result, $protocol) = expected_result($c_min, $c_max, $s_min, $s_max, - $min_enabled, $max_enabled, + $min_enabled, $max_enabled, $sctp, \@protocols); push @tests, { "name" => "version-negotiation", @@ -178,42 +181,82 @@ sub generate_version_tests { } } } - return @tests - if disabled("tls1_3") - || disabled("tls1_2") - || (disabled("ec") && disabled("dh")) - || $dtls; - - #Add some version/ciphersuite sanity check tests - push @tests, { - "name" => "ciphersuite-sanity-check-client", - "client" => { - #Offering only <=TLSv1.2 ciphersuites with TLSv1.3 should fail - "CipherString" => "AES128-SHA", - "Ciphersuites" => "", - }, - "server" => { - "MaxProtocol" => "TLSv1.2" - }, - "test" => { - "ExpectedResult" => "ClientFail", - } - }; - push @tests, { - "name" => "ciphersuite-sanity-check-server", - "client" => { - "CipherString" => "AES128-SHA", - "MaxProtocol" => "TLSv1.2" - }, - "server" => { - #Allowing only <=TLSv1.2 ciphersuites with TLSv1.3 should fail - "CipherString" => "AES128-SHA", - "Ciphersuites" => "", - }, - "test" => { - "ExpectedResult" => "ServerFail", - } - }; + + if (!$dtls && !(disabled("tls1_3") + || disabled("tls1_2") + || (disabled("ec") && disabled("dh")))) + { + #Add some version/ciphersuite sanity check tests + push @tests, { + "name" => "ciphersuite-sanity-check-tls-client", + "client" => { + #Offering only <=TLSv1.2 ciphersuites with TLSv1.3 should fail + "CipherString" => "AES128-SHA", + "Ciphersuites" => "", + }, + "server" => { + "MaxProtocol" => "TLSv1.2" + }, + "test" => { + "Method" => "TLS", + "ExpectedResult" => "ClientFail", + } + }; + push @tests, { + "name" => "ciphersuite-sanity-check-tls-server", + "client" => { + "CipherString" => "AES128-SHA", + "MaxProtocol" => "TLSv1.2" + }, + "server" => { + #Allowing only <=TLSv1.2 ciphersuites with TLSv1.3 should fail + "CipherString" => "AES128-SHA", + "Ciphersuites" => "", + }, + "test" => { + "Method" => "TLS", + "ExpectedResult" => "ServerFail", + } + }; + } + + if ($dtls && !(disabled("dtls1_3") + || disabled("dtls1_2") + || (disabled("ec") && disabled("dh")))) + { + #Add some version/ciphersuite sanity check tests + push @tests, { + "name" => "ciphersuite-sanity-check-dtls-client", + "client" => { + #Offering only <=DTLSv1.2 ciphersuites with DTLSv1.3 should fail + "CipherString" => "AES128-SHA", + "Ciphersuites" => "", + }, + "server" => { + "MaxProtocol" => "DTLSv1.2" + }, + "test" => { + "Method" => "DTLS", + "ExpectedResult" => "ClientFail", + } + }; + push @tests, { + "name" => "ciphersuite-sanity-check-dtls-server", + "client" => { + "CipherString" => "AES128-SHA", + "MaxProtocol" => "DTLSv1.2" + }, + "server" => { + #Allowing only <=DTLSv1.2 ciphersuites with DTLSv1.3 should fail + "CipherString" => "AES128-SHA", + "Ciphersuites" => "", + }, + "test" => { + "Method" => "DTLS", + "ExpectedResult" => "ServerFail", + } + }; + } return @tests; } @@ -252,16 +295,10 @@ sub generate_resumption_tests { # Upgrade or downgrade the server/client max version support and test # that it upgrades, downgrades or resumes the session as well. foreach my $resume_protocol($min_enabled..$max_enabled) { - my $resumption_expected; - # We should only resume on exact version match. - if ($original_protocol eq $resume_protocol) { - $resumption_expected = "Yes"; - } else { - $resumption_expected = "No"; - } - for (my $sctp = 0; $sctp < ($dtls && !disabled("sctp") ? 2 : 1); $sctp++) { + my ($expected_resume_protocol, $expected_result, $resumption_expected) = expected_resume_result($original_protocol, $resume_protocol, $sctp, \@protocols); + foreach my $ticket ("SessionTicket", "-SessionTicket") { # Client is flexible, server upgrades/downgrades. push @server_tests, { @@ -281,13 +318,16 @@ sub generate_resumption_tests { "Options" => $ticket, }, "test" => { - "ExpectedProtocol" => $protocols[$resume_protocol], + "ExpectedProtocol" => $protocols[$expected_resume_protocol], "Method" => $method, "HandshakeMode" => "Resume", "ResumptionExpected" => $resumption_expected, } }; - $server_tests[-1]{"test"}{"UseSCTP"} = "Yes" if $sctp; + if ($sctp) { + $server_tests[-1]{"test"}{"ExpectedResult"} = $expected_result; + $server_tests[-1]{"test"}{"UseSCTP"} = "Yes"; + } # Server is flexible, client upgrades/downgrades. push @client_tests, { "name" => "resumption", @@ -305,13 +345,16 @@ sub generate_resumption_tests { "MaxProtocol" => $protocols[$resume_protocol], }, "test" => { - "ExpectedProtocol" => $protocols[$resume_protocol], + "ExpectedProtocol" => $protocols[$expected_resume_protocol], "Method" => $method, "HandshakeMode" => "Resume", "ResumptionExpected" => $resumption_expected, } }; - $client_tests[-1]{"test"}{"UseSCTP"} = "Yes" if $sctp; + if ($sctp) { + $client_tests[-1]{"test"}{"ExpectedResult"} = $expected_result; + $client_tests[-1]{"test"}{"UseSCTP"} = "Yes"; + } } } } @@ -319,7 +362,7 @@ sub generate_resumption_tests { if (!disabled("tls1_3") && (!disabled("ec") || !disabled("dh")) && !$dtls) { push @client_tests, { - "name" => "resumption-with-hrr", + "name" => "tls13-resumption-with-hrr", "client" => { }, "server" => { @@ -336,14 +379,47 @@ sub generate_resumption_tests { }; } + if (!disabled("dtls1_3") && (!disabled("ec") || !disabled("dh")) && $dtls) { + push @client_tests, { + "name" => "dtls13-resumption-with-hrr", + "client" => { + }, + "server" => { + "Curves" => disabled("ec") ? "ffdhe3072" : "P-256" + }, + "resume_client" => { + }, + "test" => { + "ExpectedProtocol" => "DTLSv1.3", + "Method" => "DTLS", + "HandshakeMode" => "Resume", + "ResumptionExpected" => "Yes", + } + }; + } + return (@server_tests, @client_tests); } sub expected_result { - my ($c_min, $c_max, $s_min, $s_max, $min_enabled, $max_enabled, + my ($c_min, $c_max, $s_min, $s_max, $min_enabled, $max_enabled, $sctp, $protocols) = @_; my @prots = @$protocols; + # For DTLS over SCTP, DTLSv1.3 is not supported. Cap max_enabled to the + # highest SCTP-compatible protocol (DTLSv1.2 or below). + if ($sctp) { + my $sctp_max_enabled = $max_enabled; + for (my $i = $max_enabled; $i >= 0; $i--) { + if ($prots[$i] ne "DTLSv1.3") { + $sctp_max_enabled = $i; + last; + } + } + $c_max = min $c_max, $sctp_max_enabled; + $s_max = min $s_max, $sctp_max_enabled; + } + my $orig_c_max = $c_max; # Adjust for "undef" (no limit). $c_min = $c_min == 0 ? 0 : $c_min - 1; @@ -362,7 +438,11 @@ sub expected_result { || ($orig_c_max != scalar @$protocols && $prots[$orig_c_max] eq "TLSv1.3" && $c_max != $orig_c_max - && !disabled("tls1_3"))) { + && !disabled("tls1_3")) + || ($orig_c_max != scalar @$protocols + && $prots[$orig_c_max] eq "DTLSv1.3" + && $c_max != $orig_c_max + && !disabled("dtls1_3"))) { # Client should fail to even send a hello. return ("ClientFail", undef); } elsif ($s_min > $s_max) { @@ -372,7 +452,8 @@ sub expected_result { # Server doesn't support the client range. return ("ServerFail", undef); } elsif ($c_min > $s_max) { - if ($prots[$c_max] eq "TLSv1.3") { + if ($prots[$c_max] eq "TLSv1.3" + || $prots[$c_max] eq "DTLSv1.3") { # Client will have sent supported_versions, so server will know # that there are no overlapping versions. return ("ServerFail", undef); @@ -388,4 +469,35 @@ sub expected_result { } } +sub expected_resume_result { + my ($original_protocol, $max_resume_enabled, $sctp, $protocols) = @_; + my @prots = @$protocols; + my $expected_max_enabled = $max_resume_enabled; + my $resumption_expected; + my $expected_result = "Success"; + + # For DTLS over SCTP, DTLSv1.3 is not supported. Cap max_enabled to the + # highest SCTP-compatible protocol (DTLSv1.2 or below). + if ($sctp) { + for (my $i = $max_resume_enabled; $i >= 0; $i--) { + if ($prots[$i] ne "DTLSv1.3") { + $expected_max_enabled = $i; + last; + } + } + if ($prots[$original_protocol] eq "DTLSv1.3") { + $expected_result = "FirstHandshakeFailed"; + } + } + + # We should only resume on exact version match. + if ($original_protocol eq $expected_max_enabled) { + $resumption_expected = "Yes"; + } else { + $resumption_expected = "No"; + } + + return ($expected_max_enabled, $expected_result, $resumption_expected); +} + 1; diff --git a/test/ssl_ctx_test.c b/test/ssl_ctx_test.c index 796472f0cbdbe..8369fab96557e 100644 --- a/test/ssl_ctx_test.c +++ b/test/ssl_ctx_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -39,13 +39,20 @@ static const version_test version_testdata[] = { { PROTO_TLS, TLS1_2_VERSION, TLS1_1_VERSION, 1, 1, TLS1_2_VERSION, TLS1_1_VERSION }, { PROTO_TLS, SSL3_VERSION, TLS1_3_VERSION, 0, 1, 0, TLS1_3_VERSION }, { PROTO_TLS, TLS1_VERSION, TLS1_3_VERSION + 1, 1, 0, TLS1_VERSION, 0 }, -#ifndef OPENSSL_NO_DTLS +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_DTLS1_2) { PROTO_TLS, DTLS1_VERSION, DTLS1_2_VERSION, 1, 1, 0, 0 }, #endif { PROTO_TLS, OSSL_QUIC1_VERSION, OSSL_QUIC1_VERSION, 0, 0, 0, 0 }, { PROTO_TLS, 7, 42, 0, 0, 0, 0 }, { PROTO_DTLS, 0, 0, 1, 1, 0, 0 }, +#ifndef OPENSSL_NO_DTLS1_2 { PROTO_DTLS, DTLS1_VERSION, DTLS1_2_VERSION, 1, 1, DTLS1_VERSION, DTLS1_2_VERSION }, +#endif + { PROTO_DTLS, DTLS1_VERSION, DTLS1_3_VERSION, 1, 1, DTLS1_VERSION, DTLS1_3_VERSION }, + { PROTO_DTLS, DTLS1_2_VERSION, DTLS1_3_VERSION, 1, 1, DTLS1_2_VERSION, DTLS1_3_VERSION }, +#ifndef OPENSSL_NO_DTLS1_3 + { PROTO_DTLS, DTLS1_3_VERSION, DTLS1_3_VERSION, 1, 1, DTLS1_3_VERSION, DTLS1_3_VERSION }, +#endif #ifndef OPENSSL_NO_DTLS1_2 { PROTO_DTLS, DTLS1_2_VERSION, DTLS1_2_VERSION, 1, 1, DTLS1_2_VERSION, DTLS1_2_VERSION }, #endif @@ -55,8 +62,8 @@ static const version_test version_testdata[] = { #if !defined(OPENSSL_NO_DTLS1) && !defined(OPENSSL_NO_DTLS1_2) { PROTO_DTLS, DTLS1_2_VERSION, DTLS1_VERSION, 1, 1, DTLS1_2_VERSION, DTLS1_VERSION }, #endif - { PROTO_DTLS, DTLS1_VERSION + 1, DTLS1_2_VERSION, 0, 1, 0, DTLS1_2_VERSION }, - { PROTO_DTLS, DTLS1_VERSION, DTLS1_2_VERSION - 1, 1, 0, DTLS1_VERSION, 0 }, + { PROTO_DTLS, DTLS1_VERSION + 1, DTLS1_3_VERSION, 0, 1, 0, DTLS1_3_VERSION }, + { PROTO_DTLS, DTLS1_VERSION, DTLS1_3_VERSION - 1, 1, 0, DTLS1_VERSION, 0 }, { PROTO_DTLS, TLS1_VERSION, TLS1_3_VERSION, 1, 1, 0, 0 }, { PROTO_DTLS, OSSL_QUIC1_VERSION, OSSL_QUIC1_VERSION, 0, 0, 0, 0 }, /* These functions never have an effect when called on a QUIC object */ @@ -65,7 +72,7 @@ static const version_test version_testdata[] = { { PROTO_QUIC, OSSL_QUIC1_VERSION, OSSL_QUIC1_VERSION + 1, 0, 0, 0, 0 }, { PROTO_QUIC, TLS1_VERSION, TLS1_3_VERSION, 1, 1, 0, 0 }, #ifndef OPENSSL_NO_DTLS - { PROTO_QUIC, DTLS1_VERSION, DTLS1_2_VERSION, 1, 1, 0, 0 }, + { PROTO_QUIC, DTLS1_VERSION, DTLS1_3_VERSION, 1, 1, 0, 0 }, #endif }; diff --git a/test/ssl_old_test.c b/test/ssl_old_test.c index 40df6536e359e..dbfb020931e21 100644 --- a/test/ssl_old_test.c +++ b/test/ssl_old_test.c @@ -819,7 +819,8 @@ static int protocol_from_string(const char *value) { "tls1.2", TLS1_2_VERSION }, { "tls1.3", TLS1_3_VERSION }, { "dtls1", DTLS1_VERSION }, - { "dtls1.2", DTLS1_2_VERSION } + { "dtls1.2", DTLS1_2_VERSION }, + { "dtls1.3", DTLS1_3_VERSION } }; size_t i; size_t n = OSSL_NELEM(versions); @@ -1043,13 +1044,16 @@ int main(int argc, char *argv[]) } else if (HAS_PREFIX(*argv, "-num")) { if (--argc < 1) goto bad; - number = atoi(*(++argv)); + (void)test_strtoint(*(++argv), &number); if (number == 0) number = 1; } else if (strcmp(*argv, "-bytes") == 0) { + unsigned long ul = 0; + if (--argc < 1) goto bad; - bytes = atol(*(++argv)); + if (OPENSSL_strtoul(*(++argv), NULL, 10, &ul) && ul <= LONG_MAX) + bytes = (long)ul; if (bytes == 0L) bytes = 1L; i = (int)strlen(argv[0]); @@ -1191,9 +1195,12 @@ int main(int argc, char *argv[]) goto bad; client_sess_in = *(++argv); } else if (strcmp(*argv, "-should_reuse") == 0) { + int reuse_arg = 0; + if (--argc < 1) goto bad; - should_reuse = !!atoi(*(++argv)); + (void)test_strtoint(*(++argv), &reuse_arg); + should_reuse = reuse_arg != 0; } else if (strcmp(*argv, "-no_ticket") == 0) { no_ticket = 1; } else if (strcmp(*argv, "-client_ktls") == 0) { @@ -1938,7 +1945,7 @@ int doit_localhost(SSL *s_ssl, SSL *c_ssl, int family, long count, if (BIO_do_accept(acpt) <= 0) goto err; - BIO_snprintf(addr_str, sizeof(addr_str), ":%s", BIO_get_accept_port(acpt)); + snprintf(addr_str, sizeof(addr_str), ":%s", BIO_get_accept_port(acpt)); client = BIO_new_connect(addr_str); if (!client) @@ -2967,8 +2974,8 @@ static unsigned int psk_client_callback(SSL *ssl, const char *hint, int ret; unsigned int psk_len = 0; - ret = BIO_snprintf(identity, max_identity_len, "Client_identity"); - if (ret < 0) + ret = snprintf(identity, max_identity_len, "Client_identity"); + if (ret < 0 || (unsigned int)ret >= max_identity_len) goto out_err; if (debug) fprintf(stderr, "client: created identity '%s' len=%d\n", identity, diff --git a/test/ssl_test.c b/test/ssl_test.c index 27b44156b3a30..e2ca841c755be 100644 --- a/test/ssl_test.c +++ b/test/ssl_test.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -400,7 +400,7 @@ static int test_handshake(int idx) HANDSHAKE_RESULT *result = NULL; char test_app[MAX_TESTCASE_NAME_LENGTH]; - BIO_snprintf(test_app, sizeof(test_app), "test-%d", idx); + snprintf(test_app, sizeof(test_app), "test-%d", idx); test_ctx = SSL_TEST_CTX_create(conf, test_app, libctx); if (!TEST_ptr(test_ctx)) @@ -415,10 +415,18 @@ static int test_handshake(int idx) #ifndef OPENSSL_NO_DTLS if (test_ctx->method == SSL_TEST_METHOD_DTLS) { +#if !defined(OPENSSL_NO_DTLS1_3) \ + && defined(OPENSSL_NO_EC) \ + && defined(OPENSSL_NO_DH) + /* Without ec or dh there are no built-in groups for DTLSv1.3 */ + int maxversion = DTLS1_2_VERSION; +#else + int maxversion = 0; +#endif server_ctx = SSL_CTX_new_ex(libctx, NULL, DTLS_server_method()); if (!TEST_true(SSL_CTX_set_options(server_ctx, SSL_OP_ALLOW_CLIENT_RENEGOTIATION)) - || !TEST_true(SSL_CTX_set_max_proto_version(server_ctx, 0))) + || !TEST_true(SSL_CTX_set_max_proto_version(server_ctx, maxversion))) goto err; if (test_ctx->extra.server.servername_callback != SSL_TEST_SERVERNAME_CB_NONE) { if (!TEST_ptr(server2_ctx = SSL_CTX_new_ex(libctx, NULL, DTLS_server_method())) @@ -427,18 +435,18 @@ static int test_handshake(int idx) goto err; } client_ctx = SSL_CTX_new_ex(libctx, NULL, DTLS_client_method()); - if (!TEST_true(SSL_CTX_set_max_proto_version(client_ctx, 0))) + if (!TEST_true(SSL_CTX_set_max_proto_version(client_ctx, maxversion))) goto err; if (test_ctx->handshake_mode == SSL_TEST_HANDSHAKE_RESUME) { resume_server_ctx = SSL_CTX_new_ex(libctx, NULL, DTLS_server_method()); - if (!TEST_true(SSL_CTX_set_max_proto_version(resume_server_ctx, 0)) + if (!TEST_true(SSL_CTX_set_max_proto_version(resume_server_ctx, maxversion)) || !TEST_true(SSL_CTX_set_options(resume_server_ctx, SSL_OP_ALLOW_CLIENT_RENEGOTIATION))) goto err; resume_client_ctx = SSL_CTX_new_ex(libctx, NULL, DTLS_client_method()); - if (!TEST_true(SSL_CTX_set_max_proto_version(resume_client_ctx, 0))) + if (!TEST_true(SSL_CTX_set_max_proto_version(resume_client_ctx, maxversion))) goto err; if (!TEST_ptr(resume_server_ctx) || !TEST_ptr(resume_client_ctx)) diff --git a/test/sslapitest.c b/test/sslapitest.c index d751385fd2320..b07bc3b95509f 100644 --- a/test/sslapitest.c +++ b/test/sslapitest.c @@ -55,6 +55,16 @@ #define OSSL_NO_USABLE_TLS1_3 #endif +#undef OSSL_NO_USABLE_DTLS1_3 +#if defined(OPENSSL_NO_DTLS1_3) \ + || (defined(OPENSSL_NO_EC) && defined(OPENSSL_NO_DH)) +/* + * If we don't have ec or dh then there are no built-in groups that are usable + * with DTLSv1.3 + */ +#define OSSL_NO_USABLE_DTLS1_3 +#endif + /* Defined in tls-provider.c */ int tls_provider_init(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH *in, @@ -64,7 +74,7 @@ int tls_provider_init(const OSSL_CORE_HANDLE *handle, static OSSL_LIB_CTX *libctx = NULL; static OSSL_PROVIDER *defctxnull = NULL; -#ifndef OSSL_NO_USABLE_TLS1_3 +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) static SSL_SESSION *clientpsk = NULL; static SSL_SESSION *serverpsk = NULL; @@ -78,6 +88,9 @@ static int find_session_cb(SSL *ssl, const unsigned char *identity, static int use_session_cb_cnt = 0; static int find_session_cb_cnt = 0; +#endif + +#if !defined(OSSL_NO_USABLE_TLS1_3) static int end_of_early_data = 0; #endif @@ -211,7 +224,7 @@ static int compare_hex_encoded_buffer(const char *hex_encoded, return 1; for (i = j = 0; i < raw_length && j + 1 < hex_length; i++, j += 2) { - BIO_snprintf(hexed, sizeof(hexed), "%02x", raw[i]); + snprintf(hexed, sizeof(hexed), "%02x", raw[i]); if (!TEST_int_eq(hexed[0], hex_encoded[j]) || !TEST_int_eq(hexed[1], hex_encoded[j + 1])) return 1; @@ -446,12 +459,14 @@ static int test_keylog(void) } #endif -#ifndef OSSL_NO_USABLE_TLS1_3 -static int test_keylog_no_master_key(void) +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) +static int test_keylog_no_master_key(int idx) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; SSL_SESSION *sess = NULL; + const SSL_METHOD *smeth, *cmeth; + int vermin; int testresult = 0; struct sslapitest_log_counts expected; unsigned char buf[1]; @@ -465,8 +480,27 @@ static int test_keylog_no_master_key(void) server_log_buffer_index = 0; error_writing_log = 0; - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), TLS1_VERSION, 0, + if (idx == 0) { + /* Testing TLS */ + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_VERSION; +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("No usable TLSv1.3"); + goto end; +#endif + } else { + /* Testing DTLS */ + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_VERSION; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("No usable DTLSv1.3"); + goto end; +#endif + } + + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, 0, &sctx, &cctx, cert, privkey)) || !TEST_true(SSL_CTX_set_max_early_data(sctx, SSL3_RT_MAX_PLAIN_LENGTH))) @@ -661,6 +695,393 @@ static int test_client_cert_verify_cb(void) return testresult; } +static int server_retry_state; + +static int server_verify_retry_cb(X509_STORE_CTX *ctx, void *arg) +{ + int idx = SSL_get_ex_data_X509_STORE_CTX_idx(); + SSL *ssl; + + (void)arg; + + if (idx < 0 || (ssl = X509_STORE_CTX_get_ex_data(ctx, idx)) == NULL) + return 0; + + if (server_retry_state == 0) { + /* First call: ask the state machine to pause and retry. */ + server_retry_state = 1; + return SSL_set_retry_verify(ssl); + } + + /* Second call (after the app supplied a verdict): accept. */ + server_retry_state = 2; + return 1; +} + +static int test_server_cert_verify_cb(void) +{ + char *skey = test_mk_file_path(certsdir, "leaf.key"); + char *leaf = test_mk_file_path(certsdir, "leaf.pem"); + char *leaf_chain = test_mk_file_path(certsdir, "leaf-chain.pem"); + char *root = test_mk_file_path(certsdir, "rootCA.pem"); + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + + server_retry_state = 0; + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), TLS1_VERSION, 0, + &sctx, &cctx, NULL, NULL))) + goto end; + + /* Server needs its own cert/key for the TLS handshake. */ + if (!TEST_int_eq(SSL_CTX_use_certificate_chain_file(sctx, leaf_chain), 1) + || !TEST_int_eq(SSL_CTX_use_PrivateKey_file(sctx, skey, + SSL_FILETYPE_PEM), + 1) + || !TEST_int_eq(SSL_CTX_check_private_key(sctx), 1)) + goto end; + + /* Server requests and verifies a client certificate via the retry cb. */ + SSL_CTX_set_verify(sctx, + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + NULL); + SSL_CTX_set_cert_verify_callback(sctx, server_verify_retry_cb, NULL); + + /* Client presents its cert (leaf signed by interCA/rootCA). */ + if (!TEST_int_eq(SSL_CTX_use_certificate_file(cctx, leaf, + SSL_FILETYPE_PEM), + 1) + || !TEST_int_eq(SSL_CTX_use_PrivateKey_file(cctx, skey, + SSL_FILETYPE_PEM), + 1) + || !TEST_int_eq(SSL_CTX_check_private_key(cctx), 1)) + goto end; + /* Client trusts the server's root so it accepts the server cert. */ + if (!TEST_true(SSL_CTX_load_verify_locations(cctx, root, NULL))) + goto end; + SSL_CTX_set_verify(cctx, SSL_VERIFY_PEER, NULL); + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, + &clientssl, NULL, NULL))) + goto end; + + /* + * Driving the handshake the first time must surface + * SSL_ERROR_WANT_RETRY_VERIFY (proving the server state machine actually + * honored the callback's pause request rather than silently accepting -1). + */ + if (!TEST_false(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_WANT_RETRY_VERIFY))) + goto end; + if (!TEST_int_eq(server_retry_state, 1)) + goto end; + + /* Resuming the handshake must now complete cleanly. */ + if (!TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + if (!TEST_int_eq(server_retry_state, 2)) + goto end; + + testresult = 1; + +end: + if (clientssl != NULL) { + SSL_shutdown(clientssl); + SSL_free(clientssl); + } + if (serverssl != NULL) { + SSL_shutdown(serverssl); + SSL_free(serverssl); + } + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + OPENSSL_free(skey); + OPENSSL_free(leaf); + OPENSSL_free(leaf_chain); + OPENSSL_free(root); + return testresult; +} + +/* + * Same as test_server_cert_verify_cb() but with the client sending its + * credentials as an RPK. Exercises tls_post_process_client_rpk() and the + * SSL_set_retry_verify() pause on the server-side RPK code path. + */ +static int test_server_rpk_verify_cb(void) +{ + static const unsigned char cert_type_rpk[] = { TLSEXT_cert_type_rpk }; + char *skey = test_mk_file_path(certsdir, "leaf.key"); + char *leaf = test_mk_file_path(certsdir, "leaf.pem"); + char *leaf_chain = test_mk_file_path(certsdir, "leaf-chain.pem"); + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + + server_retry_state = 0; + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), TLS1_VERSION, 0, + &sctx, &cctx, NULL, NULL))) + goto end; + + /* Server needs its own cert/key for the TLS handshake. */ + if (!TEST_int_eq(SSL_CTX_use_certificate_chain_file(sctx, leaf_chain), 1) + || !TEST_int_eq(SSL_CTX_use_PrivateKey_file(sctx, skey, + SSL_FILETYPE_PEM), + 1) + || !TEST_int_eq(SSL_CTX_check_private_key(sctx), 1)) + goto end; + + /* Server: require client auth as RPK, verify via retry callback. */ + if (!TEST_true(SSL_CTX_set1_client_cert_type(sctx, cert_type_rpk, + sizeof(cert_type_rpk)))) + goto end; + SSL_CTX_set_verify(sctx, + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + NULL); + SSL_CTX_set_cert_verify_callback(sctx, server_verify_retry_cb, NULL); + + /* Client presents its cert as RPK. */ + if (!TEST_true(SSL_CTX_set1_client_cert_type(cctx, cert_type_rpk, + sizeof(cert_type_rpk)))) + goto end; + if (!TEST_int_eq(SSL_CTX_use_certificate_file(cctx, leaf, + SSL_FILETYPE_PEM), + 1) + || !TEST_int_eq(SSL_CTX_use_PrivateKey_file(cctx, skey, + SSL_FILETYPE_PEM), + 1) + || !TEST_int_eq(SSL_CTX_check_private_key(cctx), 1)) + goto end; + SSL_CTX_set_verify(cctx, SSL_VERIFY_NONE, NULL); + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, + &clientssl, NULL, NULL))) + goto end; + + /* First drive: callback returns retry, handshake must surface it. */ + if (!TEST_false(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_WANT_RETRY_VERIFY))) + goto end; + if (!TEST_int_eq(server_retry_state, 1)) + goto end; + + /* Resume: callback accepts, handshake completes. */ + if (!TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + if (!TEST_int_eq(server_retry_state, 2)) + goto end; + + /* Confirm the connection actually used raw public keys. */ + if (!TEST_ptr(SSL_get0_peer_rpk(serverssl))) + goto end; + + testresult = 1; + +end: + if (clientssl != NULL) { + SSL_shutdown(clientssl); + SSL_free(clientssl); + } + if (serverssl != NULL) { + SSL_shutdown(serverssl); + SSL_free(serverssl); + } + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + OPENSSL_free(skey); + OPENSSL_free(leaf); + OPENSSL_free(leaf_chain); + return testresult; +} + +#ifndef OPENSSL_NO_TLS1_2 +static void cert_request_msg_cb(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg) +{ + const unsigned char *msg = buf; + int *seen = arg; + + (void)version; + (void)ssl; + + if (seen != NULL && write_p == 1 && content_type == SSL3_RT_HANDSHAKE + && len >= SSL3_HM_HEADER_LENGTH + && msg[0] == SSL3_MT_CERTIFICATE_REQUEST) + *seen = 1; +} + +/* + * TLS 1.2 server that requests a client cert: after CertificateRequest, + * inject a Certificate whose certificate_list is one valid entry plus + * trailing garbage (tst 0: stray byte; tst 1: truncated entry header). + * The server must reject with decode_error / SSL_R_CERT_LENGTH_MISMATCH. + * That is the double-free path from 95dcb1b719 dropping "x = NULL;" after + * sk_X509_push(). The protocol checks do not distinguish a configuration in + * which the UAF remains silent; memory-safety tooling and enabled refcount + * assertions catch it. + */ +static int test_malformed_client_cert_tail(int tst) +{ + char *skey = test_mk_file_path(certsdir, "leaf.key"); + char *leaf_chain = test_mk_file_path(certsdir, "leaf-chain.pem"); + char *leaf = test_mk_file_path(certsdir, "leaf.pem"); + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + X509 *crt = NULL; + unsigned char *der = NULL, *body, *cp; + unsigned char flight[16384]; + unsigned char rec[4096]; + static const unsigned char expected_alert[] = { + SSL3_RT_ALERT, TLS1_2_VERSION_MAJOR, TLS1_2_VERSION_MINOR, + 0, 2, SSL3_AL_FATAL, TLS1_AD_DECODE_ERROR + }; + size_t taillen = tst == 0 ? 1 : 3; + size_t listlen, msglen, reclen, written = 0; + int cert_request_seen = 0, derlen, ret, testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), TLS1_2_VERSION, TLS1_2_VERSION, + &sctx, &cctx, NULL, NULL))) + goto end; + + /* The server needs its own credentials and must request a client cert */ + if (!TEST_int_eq(SSL_CTX_use_certificate_chain_file(sctx, leaf_chain), 1) + || !TEST_int_eq(SSL_CTX_use_PrivateKey_file(sctx, skey, + SSL_FILETYPE_PEM), + 1) + || !TEST_int_eq(SSL_CTX_check_private_key(sctx), 1)) + goto end; + SSL_CTX_set_verify(sctx, SSL_VERIFY_PEER, NULL); + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, + &clientssl, NULL, NULL))) + goto end; + + SSL_set_msg_callback(serverssl, cert_request_msg_cb); + SSL_set_msg_callback_arg(serverssl, &cert_request_seen); + + /* The client emits ClientHello; the server consumes it and replies */ + ret = SSL_connect(clientssl); + if (!TEST_int_eq(SSL_get_error(clientssl, ret), SSL_ERROR_WANT_READ)) + goto end; + ret = SSL_accept(serverssl); + if (!TEST_int_eq(SSL_get_error(serverssl, ret), SSL_ERROR_WANT_READ)) + goto end; + + /* + * Discard the server flight. The message callback must have observed a + * CertificateRequest, i.e. the server is now waiting for the client + * Certificate that we are going to forge. The client is never advanced + * again. + */ + while ((ret = BIO_read(SSL_get_rbio(clientssl), flight, + (int)sizeof(flight))) + > 0) + continue; + if (!TEST_true(cert_request_seen)) + goto end; + + /* Use a real, parseable certificate as the first (valid) list entry */ + if (!TEST_ptr(crt = load_cert_pem(leaf, libctx))) + goto end; + if (!TEST_int_gt(derlen = i2d_X509(crt, NULL), 0) + || !TEST_ptr(der = OPENSSL_malloc(derlen))) + goto end; + cp = der; + if (!TEST_int_eq(i2d_X509(crt, &cp), derlen)) + goto end; + + listlen = 3 + (size_t)derlen + taillen; + if (!TEST_size_t_le(SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH + + 3 + listlen, + sizeof(rec))) + goto end; + + /* + * Craft the Certificate body: + * certificate_list<3> = [ len<3> DER(cert) ] [ trailing garbage ] + * The garbage is inside the declared list length, so the parse loop + * starts a second iteration and fails its loop-top length checks. + */ + /* handshake message body starts after record and handshake headers */ + body = rec + SSL3_RT_HEADER_LENGTH + SSL3_HM_HEADER_LENGTH; + cp = body; + *cp++ = (unsigned char)(listlen >> 16); + *cp++ = (unsigned char)(listlen >> 8); + *cp++ = (unsigned char)listlen; + *cp++ = (unsigned char)(derlen >> 16); + *cp++ = (unsigned char)(derlen >> 8); + *cp++ = (unsigned char)derlen; + memcpy(cp, der, derlen); + cp += derlen; + if (tst == 0) { + *cp++ = 0; /* one stray byte: PACKET_get_net_3() fails */ + } else { + /* truncated entry header: declares 42 bytes, provides none */ + *cp++ = 0; + *cp++ = 0; + *cp++ = 42; /* PACKET_get_bytes() fails */ + } + msglen = (size_t)(cp - body); + + /* handshake header: type 11 (certificate) + uint24 length */ + rec[SSL3_RT_HEADER_LENGTH] = SSL3_MT_CERTIFICATE; + rec[SSL3_RT_HEADER_LENGTH + 1] = (unsigned char)(msglen >> 16); + rec[SSL3_RT_HEADER_LENGTH + 2] = (unsigned char)(msglen >> 8); + rec[SSL3_RT_HEADER_LENGTH + 3] = (unsigned char)msglen; + + /* TLSPlaintext header */ + reclen = msglen + SSL3_HM_HEADER_LENGTH; + rec[0] = SSL3_RT_HANDSHAKE; + rec[1] = TLS1_2_VERSION_MAJOR; + rec[2] = TLS1_2_VERSION_MINOR; + rec[3] = (unsigned char)(reclen >> 8); + rec[4] = (unsigned char)reclen; + reclen += SSL3_RT_HEADER_LENGTH; + + if (!TEST_true(BIO_write_ex(SSL_get_rbio(serverssl), rec, reclen, + &written)) + || !TEST_size_t_eq(written, reclen)) + goto end; + + /* The protocol rejection is the same if the memory error remains silent. */ + ERR_clear_error(); + ret = SSL_accept(serverssl); + if (!TEST_int_le(ret, 0) + || !TEST_int_eq(SSL_get_error(serverssl, ret), SSL_ERROR_SSL) + || !TEST_int_eq(ERR_GET_REASON(ERR_peek_last_error()), + SSL_R_CERT_LENGTH_MISMATCH)) + goto end; + ERR_clear_error(); + + /* The server must have sent us a fatal decode_error alert */ + ret = BIO_read(SSL_get_rbio(clientssl), flight, (int)sizeof(flight)); + if (!TEST_int_eq(ret, (int)sizeof(expected_alert)) + || !TEST_mem_eq(flight, ret, expected_alert, + sizeof(expected_alert))) + goto end; + + testresult = 1; + +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + X509_free(crt); + OPENSSL_free(der); + OPENSSL_free(skey); + OPENSSL_free(leaf_chain); + OPENSSL_free(leaf); + return testresult; +} +#endif /* OPENSSL_NO_TLS1_2 */ + static int test_ssl_build_cert_chain(void) { int ret = 0; @@ -984,12 +1405,18 @@ static int execute_test_large_message(const SSL_METHOD *smeth, SSL *clientssl = NULL, *serverssl = NULL; int testresult = 0; +#ifdef OSSL_NO_USABLE_DTLS1_3 + if (smeth == DTLS_server_method() + && (max_version == 0 || max_version == DTLS1_3_VERSION)) + max_version = DTLS1_2_VERSION; +#endif + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, min_version, max_version, &sctx, &cctx, cert, privkey))) goto end; -#ifdef OPENSSL_NO_DTLS1_2 +#if defined(OPENSSL_NO_DTLS1_2) && defined(OPENSSL_NO_DTLS1_3) if (smeth == DTLS_server_method()) { /* * Default sigalgs are SHA1 based in rlayer.wrl->sequence, SEQ_NUM_SIZE); - memcpy(srec_wseq_before, &serversc->rlayer.wrl->sequence, SEQ_NUM_SIZE); - memcpy(crec_rseq_before, &clientsc->rlayer.rrl->sequence, SEQ_NUM_SIZE); - memcpy(srec_rseq_before, &serversc->rlayer.rrl->sequence, SEQ_NUM_SIZE); + crec_wseq_before = clientsc->rlayer.wrl->sequence; + srec_wseq_before = serversc->rlayer.wrl->sequence; + crec_rseq_before = clientsc->rlayer.rrl->sequence; + srec_rseq_before = serversc->rlayer.rrl->sequence; if (!TEST_true(SSL_write(clientssl, cbuf, sizeof(cbuf)) == sizeof(cbuf))) goto end; @@ -1089,10 +1512,10 @@ static int ping_pong_query(SSL *clientssl, SSL *serverssl) } } - memcpy(crec_wseq_after, &clientsc->rlayer.wrl->sequence, SEQ_NUM_SIZE); - memcpy(srec_wseq_after, &serversc->rlayer.wrl->sequence, SEQ_NUM_SIZE); - memcpy(crec_rseq_after, &clientsc->rlayer.rrl->sequence, SEQ_NUM_SIZE); - memcpy(srec_rseq_after, &serversc->rlayer.rrl->sequence, SEQ_NUM_SIZE); + crec_wseq_after = clientsc->rlayer.wrl->sequence; + srec_wseq_after = serversc->rlayer.wrl->sequence; + crec_rseq_after = clientsc->rlayer.rrl->sequence; + srec_rseq_after = serversc->rlayer.rrl->sequence; /* verify the payload */ if (!TEST_mem_eq(cbuf, sizeof(cbuf), sbuf, sizeof(sbuf))) @@ -1103,42 +1526,34 @@ static int ping_pong_query(SSL *clientssl, SSL *serverssl) * OpenSSL sequences */ if (!BIO_get_ktls_send(clientsc->wbio)) { - if (!TEST_mem_ne(crec_wseq_before, SEQ_NUM_SIZE, - crec_wseq_after, SEQ_NUM_SIZE)) + if (!TEST_uint64_t_ne(crec_wseq_before, crec_wseq_after)) goto end; } else { - if (!TEST_mem_eq(crec_wseq_before, SEQ_NUM_SIZE, - crec_wseq_after, SEQ_NUM_SIZE)) + if (!TEST_uint64_t_eq(crec_wseq_before, crec_wseq_after)) goto end; } if (!BIO_get_ktls_send(serversc->wbio)) { - if (!TEST_mem_ne(srec_wseq_before, SEQ_NUM_SIZE, - srec_wseq_after, SEQ_NUM_SIZE)) + if (!TEST_uint64_t_ne(srec_wseq_before, srec_wseq_after)) goto end; } else { - if (!TEST_mem_eq(srec_wseq_before, SEQ_NUM_SIZE, - srec_wseq_after, SEQ_NUM_SIZE)) + if (!TEST_uint64_t_eq(srec_wseq_before, srec_wseq_after)) goto end; } if (!BIO_get_ktls_recv(clientsc->wbio)) { - if (!TEST_mem_ne(crec_rseq_before, SEQ_NUM_SIZE, - crec_rseq_after, SEQ_NUM_SIZE)) + if (!TEST_uint64_t_ne(crec_rseq_before, crec_rseq_after)) goto end; } else { - if (!TEST_mem_eq(crec_rseq_before, SEQ_NUM_SIZE, - crec_rseq_after, SEQ_NUM_SIZE)) + if (!TEST_uint64_t_eq(crec_rseq_before, crec_rseq_after)) goto end; } if (!BIO_get_ktls_recv(serversc->wbio)) { - if (!TEST_mem_ne(srec_rseq_before, SEQ_NUM_SIZE, - srec_rseq_after, SEQ_NUM_SIZE)) + if (!TEST_uint64_t_ne(srec_rseq_before, srec_rseq_after)) goto end; } else { - if (!TEST_mem_eq(srec_rseq_before, SEQ_NUM_SIZE, - srec_rseq_after, SEQ_NUM_SIZE)) + if (!TEST_uint64_t_eq(srec_rseq_before, srec_rseq_after)) goto end; } @@ -1985,15 +2400,22 @@ static int test_cleanse_plaintext(void) return 0; #endif -#if !defined(OPENSSL_NO_DTLS) - +#if !defined(OPENSSL_NO_DTLS1_2) if (!TEST_true(execute_cleanse_plaintext(DTLS_server_method(), DTLS_client_method(), - DTLS1_VERSION, - 0))) + DTLS1_2_VERSION, + DTLS1_2_VERSION))) return 0; #endif - return 1; + +#if !defined(OSSL_NO_USABLE_DTLS1_3) + if (!TEST_true(execute_cleanse_plaintext(DTLS_server_method(), + DTLS_client_method(), + DTLS1_3_VERSION, + DTLS1_3_VERSION))) + return 0; +#endif + return 1; } #ifndef OPENSSL_NO_OCSP @@ -2642,8 +3064,9 @@ static int test_tlsext_status_type_multi(void) #endif #endif -#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) -static int new_called, remove_called, get_called; +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) \ + || !defined(OSSL_NO_USABLE_DTLS1_3) +static int new_called, get_called; static int new_session_cb(SSL *ssl, SSL_SESSION *sess) { @@ -2656,11 +3079,6 @@ static int new_session_cb(SSL *ssl, SSL_SESSION *sess) return 1; } -static void remove_session_cb(SSL_CTX *ctx, SSL_SESSION *sess) -{ - remove_called++; -} - static SSL_SESSION *get_sess_val = NULL; static SSL_SESSION *get_session_cb(SSL *ssl, const unsigned char *id, int len, @@ -2670,6 +3088,15 @@ static SSL_SESSION *get_session_cb(SSL *ssl, const unsigned char *id, int len, *copy = 1; return get_sess_val; } +#endif + +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) +static int remove_called; + +static void remove_session_cb(SSL_CTX *ctx, SSL_SESSION *sess) +{ + remove_called++; +} static int execute_test_session(int maxprot, int use_int_cache, int use_ext_cache, long s_options) @@ -3096,7 +3523,7 @@ static int test_session_wo_ca_names(void) #endif } -#ifndef OSSL_NO_USABLE_TLS1_3 +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) static SSL_SESSION *sesscache[6]; static int do_cache; @@ -3130,13 +3557,24 @@ static int post_handshake_verify(SSL *sssl, SSL *cssl) return 1; } -static int setup_ticket_test(int stateful, int idx, SSL_CTX **sctx, +static int setup_ticket_test(int testdtls, int stateful, int idx, SSL_CTX **sctx, SSL_CTX **cctx) { int sess_id_ctx = 1; + const SSL_METHOD *smeth, *cmeth; + int vermin; - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), TLS1_VERSION, 0, + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_VERSION; + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_VERSION; + } + + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, 0, sctx, cctx, cert, privkey)) || !TEST_true(SSL_CTX_set_num_tickets(*sctx, idx)) || !TEST_true(SSL_CTX_set_session_id_context(*sctx, @@ -3216,17 +3654,33 @@ static int test_tickets(int stateful, int idx) SSL *serverssl = NULL, *clientssl = NULL; int testresult = 0; size_t j; + int testdtls = idx >= 3; + +#if defined(OSSL_NO_USABLE_TLS1_3) + if (!testdtls) { + testresult = TEST_skip("TLSv1.3 is not usable"); + goto end; + } +#endif +#if defined(OSSL_NO_USABLE_DTLS1_3) + if (testdtls) { + testresult = TEST_skip("DTLSv1.3 is not usable"); + goto end; + } +#endif /* idx is the test number, but also the number of tickets we want */ + if (testdtls) + idx -= 3; new_called = 0; do_cache = 1; - if (!setup_ticket_test(stateful, idx, &sctx, &cctx)) + if (!setup_ticket_test(testdtls, stateful, idx, &sctx, &cctx)) goto end; - if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, - &clientssl, NULL, NULL))) + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL))) goto end; if (!TEST_true(create_ssl_connection(serverssl, clientssl, @@ -3253,7 +3707,7 @@ static int test_tickets(int stateful, int idx) /* Stop caching sessions - just count them */ do_cache = 0; - if (!setup_ticket_test(stateful, idx, &sctx, &cctx)) + if (!setup_ticket_test(testdtls, stateful, idx, &sctx, &cctx)) goto end; if (!check_resumption(idx, sctx, cctx, 0)) @@ -3266,7 +3720,7 @@ static int test_tickets(int stateful, int idx) SSL_CTX_free(cctx); sctx = cctx = NULL; - if (!setup_ticket_test(stateful, idx, &sctx, &cctx)) + if (!setup_ticket_test(testdtls, stateful, idx, &sctx, &cctx)) goto end; if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, @@ -3327,15 +3781,37 @@ static int test_stateful_tickets(int idx) return test_tickets(1, idx); } -static int test_psk_tickets(void) +static int test_psk_tickets(int idx) { SSL_CTX *sctx = NULL, *cctx = NULL; SSL *serverssl = NULL, *clientssl = NULL; int testresult = 0; int sess_id_ctx = 1; + const SSL_METHOD *smeth, *cmeth; + int vermin, vermax = 0; + int testdtls = idx > 0; + int clientpskver = TLS1_3_VERSION; - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), TLS1_VERSION, 0, + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + clientpskver = DTLS1_3_VERSION; + vermin = DTLS1_VERSION; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("DTLSv1.3 is not usable"); + goto end; +#endif + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_VERSION; +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("TLSv1.3 is not usable"); + goto end; +#endif + } + + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, NULL, NULL)) || !TEST_true(SSL_CTX_set_session_id_context(sctx, (void *)&sess_id_ctx, @@ -3355,7 +3831,9 @@ static int test_psk_tickets(void) NULL, NULL))) goto end; clientpsk = serverpsk = create_a_psk(clientssl, SHA384_DIGEST_LENGTH); - if (!TEST_ptr(clientpsk) || !TEST_true(SSL_SESSION_up_ref(clientpsk))) + if (!TEST_ptr(clientpsk) + || !TEST_true(SSL_SESSION_up_ref(clientpsk)) + || !TEST_true(SSL_SESSION_set_protocol_version(clientpsk, clientpskver))) goto end; if (!TEST_true(create_ssl_connection(serverssl, clientssl, @@ -3390,16 +3868,32 @@ static int test_extra_tickets(int idx) int stateful = 0; size_t nbytes; unsigned char c, buf[1]; + int testdtls = (idx >= 6); + int expected_new_called = 0; new_called = 0; do_cache = 1; + if (testdtls) { + idx -= 6; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("DTLSv1.3 is not usable"); + goto end; +#endif + } else { +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("TLSv1.3 is not usable"); + goto end; +#endif + } + if (idx >= 3) { idx -= 3; stateful = 1; } - if (!TEST_ptr(bretry) || !setup_ticket_test(stateful, idx, &sctx, &cctx)) + if (!TEST_ptr(bretry) + || !setup_ticket_test(testdtls, stateful, idx, &sctx, &cctx)) goto end; SSL_CTX_sess_set_new_cb(sctx, new_session_cb); /* setup_ticket_test() uses new_cachesession_cb which we don't need. */ @@ -3490,6 +3984,14 @@ static int test_extra_tickets(int idx) /* Restore a BIO that will let the write succeed */ SSL_set0_wbio(serverssl, tmp); tmp = NULL; + + /* + * When the DTLS 1.3 write fails it doesn't get queued up and thus + * New Session Tickets can be issued. + */ + if (testdtls) + expected_new_called = 2; + /* * These calls should just queue the request and not send anything * even if we explicitly try to hit the state machine. @@ -3498,27 +4000,40 @@ static int test_extra_tickets(int idx) || !TEST_true(SSL_new_session_ticket(serverssl)) || !TEST_int_eq(0, new_called) || !TEST_true(SSL_do_handshake(serverssl)) - || !TEST_int_eq(0, new_called)) + || !TEST_int_eq(expected_new_called, new_called)) goto end; /* Re-do the write; still no tickets sent */ if (!TEST_true(SSL_write_ex(serverssl, &c, 1, &nbytes)) || !TEST_size_t_eq(1, nbytes) - || !TEST_int_eq(0, new_called) - || !TEST_true(SSL_read_ex(clientssl, buf, sizeof(buf), &nbytes)) - || !TEST_int_eq(0, new_called) + || !TEST_int_eq(expected_new_called, new_called)) + goto end; + + /* + * When the DTLS 1.3 write fails it doesn't get queued up and thus + * New Session Tickets can be issued. + */ + if (testdtls) + expected_new_called = 4; + + if (!TEST_true(SSL_read_ex(clientssl, buf, sizeof(buf), &nbytes)) + || !TEST_int_eq(expected_new_called, new_called) || !TEST_size_t_eq(sizeof(buf), nbytes) || !TEST_int_eq(c, buf[0]) || !TEST_false(SSL_read_ex(clientssl, buf, sizeof(buf), &nbytes))) goto end; /* Even trying to hit the state machine now will still not send tickets */ if (!TEST_true(SSL_do_handshake(serverssl)) - || !TEST_int_eq(0, new_called)) + || !TEST_int_eq(expected_new_called, new_called)) goto end; /* Now the *next* write should send the tickets */ c = '6'; + + if (!testdtls) + expected_new_called = 2; + if (!TEST_true(SSL_write_ex(serverssl, &c, 1, &nbytes)) || !TEST_size_t_eq(1, nbytes) - || !TEST_int_eq(2, new_called) + || !TEST_int_eq(expected_new_called, new_called) || !TEST_true(SSL_read_ex(clientssl, buf, sizeof(buf), &nbytes)) || !TEST_int_eq(4, new_called) || !TEST_size_t_eq(sizeof(buf), nbytes) @@ -3969,7 +4484,7 @@ static int test_set_sigalgs(int idx) } #endif -#ifndef OSSL_NO_USABLE_TLS1_3 +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) static int psk_client_cb_cnt = 0; static int psk_server_cb_cnt = 0; @@ -4135,14 +4650,26 @@ static int ed_gen_cb(SSL *s, void *arg) */ static int setupearly_data_test(SSL_CTX **cctx, SSL_CTX **sctx, SSL **clientssl, SSL **serverssl, SSL_SESSION **sess, int idx, - size_t mdsize) + size_t mdsize, int testdtls) { int artificial = (artificial_ticket_time > 0); + const SSL_METHOD *cmeth, *smeth; + int vermin, vermax = 0; + int pskver = TLS1_3_VERSION; + + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_VERSION; + pskver = DTLS1_3_VERSION; + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_VERSION; + } if (*sctx == NULL - && !TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), - TLS1_VERSION, 0, + && !TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, sctx, cctx, cert, privkey))) return 0; @@ -4188,7 +4715,8 @@ static int setupearly_data_test(SSL_CTX **cctx, SSL_CTX **sctx, SSL **clientssl, */ || !TEST_true(SSL_SESSION_set_max_early_data(clientpsk, 0x100)) - || !TEST_true(SSL_SESSION_up_ref(clientpsk))) { + || !TEST_true(SSL_SESSION_up_ref(clientpsk)) + || !TEST_true(SSL_SESSION_set_protocol_version(clientpsk, pskver))) { SSL_SESSION_free(clientpsk); clientpsk = NULL; return 0; @@ -4266,13 +4794,27 @@ static int test_early_data_read_write(int idx) size_t readbytes, written, eoedlen, rawread, rawwritten; BIO *rbio; OSSL_TIME timer; + int testdtls = idx >= 6; + + if (testdtls) { + idx -= 6; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("DTLSv1.3 is not usable"); + goto end; +#endif + } else { +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("TLSv1.3 is not usable"); + goto end; +#endif + } /* Artificially give the next 2 tickets some age for non PSK sessions */ if (idx != 2) artificial_ticket_time = 2; if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, &serverssl, &sess, idx, - SHA384_DIGEST_LENGTH))) { + SHA384_DIGEST_LENGTH, testdtls))) { artificial_ticket_time = 0; goto end; } @@ -4330,59 +4872,108 @@ static int test_early_data_read_write(int idx) goto end; /* - * If client writes normal data it should mean writing early data is no - * longer possible. + * DTLS 1.3 Client will finish the handshake when the SSL_write_ex is called. + * This is the same as TLS 1.3, but for DTLS 1.3 the client doesn't exit the + * state machine. Instead it waits to read a DTLS 1.3 ACK from the server. + * This cannot happen with how this test is written. + * + * Therefore the call to SSL_write_ex will return false. */ - if (!TEST_true(SSL_write_ex(clientssl, MSG5, strlen(MSG5), &written)) - || !TEST_size_t_eq(written, strlen(MSG5)) - || !TEST_int_eq(SSL_get_early_data_status(clientssl), - SSL_EARLY_DATA_ACCEPTED)) - goto end; + if (testdtls) { + /* + * If client writes normal data it should mean writing early data is no + * longer possible. + */ + written = 0; + if (!TEST_false(SSL_write_ex(clientssl, MSG5, strlen(MSG5), &written)) + || !TEST_size_t_eq(written, 0) + || !TEST_int_eq(SSL_get_early_data_status(clientssl), + SSL_EARLY_DATA_ACCEPTED)) + goto end; - /* - * At this point the client has written EndOfEarlyData, ClientFinished and - * normal (fully protected) data. We are going to cause a delay between the - * arrival of EndOfEarlyData and ClientFinished. We read out all the data - * in the read BIO, and then just put back the EndOfEarlyData message. - */ - rbio = SSL_get_rbio(serverssl); - if (!TEST_true(BIO_read_ex(rbio, data, sizeof(data), &rawread)) - || !TEST_size_t_lt(rawread, sizeof(data)) - || !TEST_size_t_gt(rawread, SSL3_RT_HEADER_LENGTH)) - goto end; + /* + * Server should be told he can still read early data since + * the server hasn't read the Client Finish message + */ + readbytes = 0; + if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf), + &readbytes), + SSL_READ_EARLY_DATA_FINISH) + || !TEST_size_t_eq(readbytes, 0)) + goto end; - /* Record length is in the 4th and 5th bytes of the record header */ - eoedlen = SSL3_RT_HEADER_LENGTH + (data[3] << 8 | data[4]); - if (!TEST_true(BIO_write_ex(rbio, data, eoedlen, &rawwritten)) - || !TEST_size_t_eq(rawwritten, eoedlen)) - goto end; + /* + * Server has not finished init yet, so should still be able to write early + * data. + */ + if (!TEST_true(SSL_write_early_data(serverssl, MSG6, strlen(MSG6), + &written)) + || !TEST_size_t_eq(written, strlen(MSG6))) + goto end; - /* Server should be told that there is no more early data */ - if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf), - &readbytes), - SSL_READ_EARLY_DATA_FINISH) - || !TEST_size_t_eq(readbytes, 0)) - goto end; + /* + * Server should not receive anything here since the data was not sent + * by the client in the call above. The reason for that is the client + * is waiting for the ACK to the Client Finish message. + */ + if (!TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes))) + goto end; + } else { + /* + * If client writes normal data it should mean writing early data is no + * longer possible. + */ + if (!TEST_true(SSL_write_ex(clientssl, MSG5, strlen(MSG5), &written)) + || !TEST_size_t_eq(written, strlen(MSG5)) + || !TEST_int_eq(SSL_get_early_data_status(clientssl), + SSL_EARLY_DATA_ACCEPTED)) + goto end; - /* - * Server has not finished init yet, so should still be able to write early - * data. - */ - if (!TEST_true(SSL_write_early_data(serverssl, MSG6, strlen(MSG6), - &written)) - || !TEST_size_t_eq(written, strlen(MSG6))) - goto end; + /* + * At this point the client has written EndOfEarlyData, ClientFinished and + * normal (fully protected) data. We are going to cause a delay between the + * arrival of EndOfEarlyData and ClientFinished. We read out all the data + * in the read BIO, and then just put back the EndOfEarlyData message. + */ + rbio = SSL_get_rbio(serverssl); + if (!TEST_true(BIO_read_ex(rbio, data, sizeof(data), &rawread)) + || !TEST_size_t_lt(rawread, sizeof(data)) + || !TEST_size_t_gt(rawread, SSL3_RT_HEADER_LENGTH)) + goto end; - /* Push the ClientFinished and the normal data back into the server rbio */ - if (!TEST_true(BIO_write_ex(rbio, data + eoedlen, rawread - eoedlen, - &rawwritten)) - || !TEST_size_t_eq(rawwritten, rawread - eoedlen)) - goto end; + /* Record length is in the 4th and 5th bytes of the record header */ + eoedlen = SSL3_RT_HEADER_LENGTH + (data[3] << 8 | data[4]); + if (!TEST_true(BIO_write_ex(rbio, data, eoedlen, &rawwritten)) + || !TEST_size_t_eq(rawwritten, eoedlen)) + goto end; - /* Server should be able to read normal data */ - if (!TEST_true(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes)) - || !TEST_size_t_eq(readbytes, strlen(MSG5))) - goto end; + /* Server should be told that there is no more early data */ + if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf), + &readbytes), + SSL_READ_EARLY_DATA_FINISH) + || !TEST_size_t_eq(readbytes, 0)) + goto end; + + /* + * Server has not finished init yet, so should still be able to write early + * data. + */ + if (!TEST_true(SSL_write_early_data(serverssl, MSG6, strlen(MSG6), + &written)) + || !TEST_size_t_eq(written, strlen(MSG6))) + goto end; + + /* Push the ClientFinished and the normal data back into the server rbio */ + if (!TEST_true(BIO_write_ex(rbio, data + eoedlen, rawread - eoedlen, + &rawwritten)) + || !TEST_size_t_eq(rawwritten, rawread - eoedlen)) + goto end; + + /* Server should be able to read normal data */ + if (!TEST_true(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes)) + || !TEST_size_t_eq(readbytes, strlen(MSG5))) + goto end; + } /* Client and server should not be able to write/read early data now */ if (!TEST_false(SSL_write_early_data(clientssl, MSG6, strlen(MSG6), @@ -4442,9 +5033,21 @@ static int test_early_data_read_write(int idx) || !TEST_mem_eq(buf, readbytes, MSG1, strlen(MSG1))) goto end; - if (!TEST_int_gt(SSL_connect(clientssl), 0) - || !TEST_int_gt(SSL_accept(serverssl), 0)) - goto end; + if (testdtls) { + /* + * Since DTLS1.3 requires the Client to receive an + * ACK so the first call to SSL_connect will fail + * since it is waiting for the ACK from the server + */ + if (!TEST_int_lt(SSL_connect(clientssl), 0) + || !TEST_int_gt(SSL_accept(serverssl), 0) + || !TEST_int_gt(SSL_connect(clientssl), 0)) + goto end; + } else { + if (!TEST_int_gt(SSL_connect(clientssl), 0) + || !TEST_int_gt(SSL_accept(serverssl), 0)) + goto end; + } /* Client and server should not be able to write/read early data now */ if (!TEST_false(SSL_write_early_data(clientssl, MSG6, strlen(MSG6), @@ -4510,11 +5113,32 @@ static int test_early_data_replay_int(int idx, int usecb, int confopt) size_t readbytes, written; unsigned char buf[20]; OSSL_TIME timer; + const SSL_METHOD *smeth, *cmeth; + int vermin, vermax = 0; + int testdtls = idx >= 2; + + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_VERSION; + idx -= 2; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("DTLSv1.3 is not usable"); + goto end; +#endif + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_VERSION; +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("TLSv1.3 is not usable"); + goto end; +#endif + } allow_ed_cb_called = 0; - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), TLS1_VERSION, 0, + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, cert, privkey))) return 0; @@ -4540,7 +5164,7 @@ static int test_early_data_replay_int(int idx, int usecb, int confopt) if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, &serverssl, &sess, idx, - SHA384_DIGEST_LENGTH))) + SHA384_DIGEST_LENGTH, testdtls))) goto end; /* @@ -4588,14 +5212,29 @@ static int test_early_data_replay_int(int idx, int usecb, int confopt) testresult = check_early_data_timeout(timer); goto end; } - if (!TEST_mem_eq(MSG1, strlen(MSG1), buf, readbytes) + if (!TEST_mem_eq(MSG1, strlen(MSG1), buf, readbytes)) + goto end; + + if (testdtls) { /* * Server will have sent its flight so client can now send * end of early data and complete its half of the handshake + * DTLS1.3 will return an error for the client is waiting + * for an ACK from the server */ - || !TEST_int_gt(SSL_connect(clientssl), 0) - || !TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf), - &readbytes), + if (!TEST_int_lt(SSL_connect(clientssl), 0)) + goto end; + } else { + /* + * Server will have sent its flight so client can now send + * end of early data and complete its half of the handshake + */ + if (!TEST_int_gt(SSL_connect(clientssl), 0)) + goto end; + } + + if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf), + &readbytes), SSL_READ_EARLY_DATA_FINISH) || !TEST_int_eq(SSL_get_early_data_status(serverssl), SSL_EARLY_DATA_ACCEPTED)) @@ -4658,7 +5297,7 @@ static const char *ciphersuites[] = { * testtype: 2 == HRR, invalid early_data sent after HRR * testtype: 3 == recv_max_early_data set to 0 */ -static int early_data_skip_helper(int testtype, int cipher, int idx) +static int early_data_skip_helper(int testdtls, int testtype, int cipher, int idx) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; @@ -4666,16 +5305,34 @@ static int early_data_skip_helper(int testtype, int cipher, int idx) SSL_SESSION *sess = NULL; unsigned char buf[20]; size_t readbytes, written; + const SSL_METHOD *smeth, *cmeth; + int vermin, vermax = 0; + + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_VERSION; + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_VERSION; + } if (is_fips && cipher >= 4) return 1; + /* + * RFC 9147 (DTLS 1.3): TLS_AES_128_CCM_8_SHA256 MUST NOT be used in + * DTLS without additional safeguards against forgery, which we do not + * implement, so this cipher is not offered under DTLS. + */ + if (testdtls && cipher == 0) + return 1; + if (ciphersuites[cipher] == NULL) return TEST_skip("Cipher not supported"); - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), - TLS1_VERSION, 0, + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, cert, privkey))) goto end; @@ -4684,15 +5341,36 @@ static int early_data_skip_helper(int testtype, int cipher, int idx) SSL_CTX_set_security_level(cctx, 0); } - if (!TEST_true(SSL_CTX_set_ciphersuites(sctx, ciphersuites[cipher])) - || !TEST_true(SSL_CTX_set_ciphersuites(cctx, ciphersuites[cipher]))) + if (!TEST_true(SSL_CTX_set_ciphersuites(sctx, ciphersuites[cipher]))) + goto end; + if (idx == 2) { + /* + * The external PSK (see create_a_psk) is stamped with a fixed + * ciphersuite that need not be the one under test. For the client to + * offer 0-RTT that ciphersuite must be among those it offers, so offer + * it alongside the ciphersuite under test. The server offers only the + * ciphersuite under test, so the one it selects differs from the PSK's + * whenever the two are not the same. + */ + char clientsuites[128]; + + snprintf(clientsuites, sizeof(clientsuites), "%s:%s", + ciphersuites[cipher], + (cipher == 2 || cipher == 6) + ? "TLS_AES_256_GCM_SHA384" + : "TLS_AES_128_GCM_SHA256"); + if (!TEST_true(SSL_CTX_set_ciphersuites(cctx, clientsuites))) + goto end; + } else if (!TEST_true(SSL_CTX_set_ciphersuites(cctx, ciphersuites[cipher]))) { goto end; + } if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, &serverssl, &sess, idx, (cipher == 2 || cipher == 6) ? SHA384_DIGEST_LENGTH - : SHA256_DIGEST_LENGTH))) + : SHA256_DIGEST_LENGTH, + testdtls))) goto end; if (testtype == 1 || testtype == 2) { @@ -4763,6 +5441,11 @@ static int early_data_skip_helper(int testtype, int cipher, int idx) 0x17, 0x03, 0x03, 0x00, 0x01, 0x00 }; + /* A record with the DTLS1.3 Unified Header */ + const unsigned char bad_early_data_dtls[] = { + 0x2D, 0x00, 0x00, 0x00, 0x01, 0x00 + }; + /* * We force the client to attempt a write. This will fail because * we're still in the handshake. It will cause the second @@ -4776,31 +5459,62 @@ static int early_data_skip_helper(int testtype, int cipher, int idx) * Inject some early_data after the second ClientHello. This should * cause the server to fail */ - if (!TEST_true(BIO_write_ex(wbio, bad_early_data, - sizeof(bad_early_data), &written))) - goto end; + if (testdtls) { + /* + * Injecting bad DTLS data, but since the sequence number needs + * to be encrypted the SSL_read() below will result in a different + * error message. + */ + if (!TEST_true(BIO_write_ex(wbio, bad_early_data_dtls, + sizeof(bad_early_data_dtls), &written))) + goto end; + + } else { + if (!TEST_true(BIO_write_ex(wbio, bad_early_data, + sizeof(bad_early_data), &written))) + goto end; + } } /* FALLTHROUGH */ - case 3: + case 3: { /* * This client has sent more early_data than we are willing to skip * (case 3) or sent invalid early_data (case 2) so the connection should * abort. */ + int sslerr = testdtls ? SSL_ERROR_WANT_READ : SSL_ERROR_SSL; + if (!TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf), &readbytes)) - || !TEST_int_eq(SSL_get_error(serverssl, 0), SSL_ERROR_SSL)) + || !TEST_int_eq(SSL_get_error(serverssl, 0), sslerr)) goto end; /* Connection has failed - nothing more to do */ testresult = 1; goto end; - + } default: TEST_error("Invalid test type"); goto end; } + /* + * To finish the DTLS1.3 handshake the client needs to + * process the ack message from the server before it + * can write data. + * + * The SSL_write_ex from the client will fail since + * the client needs to send a finish message and will + * wait for the server to send the ACK response. + */ + if (testdtls) { + if (!TEST_true(SSL_connect(clientssl))) + goto end; + + if (!TEST_true(SSL_accept(serverssl))) + goto end; + } + ERR_clear_error(); /* * Should be able to send normal data despite rejection of early data. The @@ -4841,7 +5555,20 @@ static int early_data_skip_helper(int testtype, int cipher, int idx) */ static int test_early_data_skip(int idx) { - return early_data_skip_helper(0, + int testdtls = ((size_t)idx) >= OSSL_NELEM(ciphersuites) * 3; + + if (testdtls) { + idx -= OSSL_NELEM(ciphersuites) * 3; +#if defined(OSSL_NO_USABLE_DTLS1_3) + return TEST_skip("No usable DTLSv1.3"); +#endif + } else { +#if defined(OSSL_NO_USABLE_TLS1_3) + return TEST_skip("No usable TLSv1.3"); +#endif + } + + return early_data_skip_helper(testdtls, 0, idx % OSSL_NELEM(ciphersuites), idx / OSSL_NELEM(ciphersuites)); } @@ -4852,7 +5579,20 @@ static int test_early_data_skip(int idx) */ static int test_early_data_skip_hrr(int idx) { - return early_data_skip_helper(1, + int testdtls = ((size_t)idx) >= OSSL_NELEM(ciphersuites) * 3; + + if (testdtls) { + idx -= OSSL_NELEM(ciphersuites) * 3; +#if defined(OSSL_NO_USABLE_DTLS1_3) + return TEST_skip("No usable DTLSv1.3"); +#endif + } else { +#if defined(OSSL_NO_USABLE_TLS1_3) + return TEST_skip("No usable TLSv1.3"); +#endif + } + + return early_data_skip_helper(testdtls, 1, idx % OSSL_NELEM(ciphersuites), idx / OSSL_NELEM(ciphersuites)); } @@ -4864,7 +5604,20 @@ static int test_early_data_skip_hrr(int idx) */ static int test_early_data_skip_hrr_fail(int idx) { - return early_data_skip_helper(2, + int testdtls = ((size_t)idx) >= OSSL_NELEM(ciphersuites) * 3; + + if (testdtls) { + idx -= OSSL_NELEM(ciphersuites) * 3; +#if defined(OSSL_NO_USABLE_DTLS1_3) + return TEST_skip("No usable DTLSv1.3"); +#endif + } else { +#if defined(OSSL_NO_USABLE_TLS1_3) + return TEST_skip("No usable TLSv1.3"); +#endif + } + + return early_data_skip_helper(testdtls, 2, idx % OSSL_NELEM(ciphersuites), idx / OSSL_NELEM(ciphersuites)); } @@ -4875,10 +5628,23 @@ static int test_early_data_skip_hrr_fail(int idx) */ static int test_early_data_skip_abort(int idx) { - return early_data_skip_helper(3, - idx % OSSL_NELEM(ciphersuites), - idx / OSSL_NELEM(ciphersuites)); -} + int testdtls = ((size_t)idx) >= OSSL_NELEM(ciphersuites) * 3; + + if (testdtls) { + idx -= OSSL_NELEM(ciphersuites) * 3; +#if defined(OSSL_NO_USABLE_DTLS1_3) + return TEST_skip("No usable DTLSv1.3"); +#endif + } else { +#if defined(OSSL_NO_USABLE_TLS1_3) + return TEST_skip("No usable TLSv1.3"); +#endif + } + + return early_data_skip_helper(testdtls, 3, + idx % OSSL_NELEM(ciphersuites), + idx / OSSL_NELEM(ciphersuites)); +} /* * Test that a server attempting to read early data can handle a connection @@ -4892,10 +5658,24 @@ static int test_early_data_not_sent(int idx) SSL_SESSION *sess = NULL; unsigned char buf[20]; size_t readbytes, written; + int testdtls = idx >= 3; + + if (testdtls) { + idx -= 3; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("No usable DTLSv1.3"); + goto end; +#endif + } else { +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("No usable TLSv1.3"); + goto end; +#endif + } if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, &serverssl, &sess, idx, - SHA384_DIGEST_LENGTH))) + SHA384_DIGEST_LENGTH, testdtls))) goto end; /* Write some data - should block due to handshake with server */ @@ -4914,6 +5694,20 @@ static int test_early_data_not_sent(int idx) SSL_EARLY_DATA_NOT_SENT)) goto end; + if (testdtls) { + /* + * We need to move the state machine along for DTLS1.3 + * The client needs to read the server hello and send its + * finish message and the server needs to ACK the finish + * message + */ + if (!TEST_true(SSL_connect(clientssl))) + goto end; + + if (!TEST_true(SSL_accept(serverssl))) + goto end; + } + /* Continue writing the message we started earlier */ if (!TEST_true(SSL_write_ex(clientssl, MSG1, strlen(MSG1), &written)) || !TEST_size_t_eq(written, strlen(MSG1)) @@ -4981,16 +5775,32 @@ static int test_early_data_psk(int idx) #define BADALPNLEN 8 #define GOODALPN (alpnlist) #define BADALPN (alpnlist + GOODALPNLEN) - int err = 0; + int err = 0, suppressed = 0; unsigned char buf[20]; size_t readbytes, written; int readearlyres = SSL_READ_EARLY_DATA_SUCCESS, connectres = 1; int edstatus = SSL_EARLY_DATA_ACCEPTED; + int testdtls = idx >= 8; + int version1_2 = testdtls ? DTLS1_2_VERSION : TLS1_2_VERSION; + + if (testdtls) { + idx -= 8; + version1_2 = DTLS1_2_VERSION; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("No usable DTLSv1.3"); + goto end; +#endif + } else { +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("No usable TLSv1.3"); + goto end; +#endif + } /* We always set this up with a final parameter of "2" for PSK */ if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, &serverssl, &sess, 2, - SHA384_DIGEST_LENGTH))) + SHA384_DIGEST_LENGTH, testdtls))) goto end; servalpn = "goodalpn"; @@ -5011,8 +5821,12 @@ static int test_early_data_psk(int idx) break; case 1: - /* Set inconsistent ALPN (early client detection) */ - err = SSL_R_INCONSISTENT_EARLY_DATA_ALPN; + /* + * Inconsistent ALPN, detected by the client before it sends: the + * offered ALPN cannot include the session's, so the client suppresses + * 0-RTT and completes a full handshake instead of failing. + */ + suppressed = 1; /* SSL_set_alpn_protos returns 0 for success and 1 for failure */ if (!TEST_true(SSL_SESSION_set1_alpn_selected(sess, GOODALPN, GOODALPNLEN)) @@ -5028,7 +5842,7 @@ static int test_early_data_psk(int idx) * SNI/ALPN consistency tests. */ err = SSL_R_BAD_PSK; - if (!TEST_true(SSL_SESSION_set_protocol_version(sess, TLS1_2_VERSION))) + if (!TEST_true(SSL_SESSION_set_protocol_version(sess, version1_2))) goto end; break; @@ -5113,6 +5927,25 @@ static int test_early_data_psk(int idx) || !TEST_int_eq(SSL_get_error(clientssl, 0), SSL_ERROR_SSL) || !TEST_int_eq(ERR_GET_REASON(ERR_get_error()), err)) goto end; + } else if (suppressed) { + /* + * The client suppresses 0-RTT: the first SSL_write_early_data() writes + * the ClientHello (without early data) and reports "retry". The server + * sees no early data, and both ends complete a full handshake with the + * early data reported as rejected on the client. + */ + if (!TEST_false(SSL_write_early_data(clientssl, MSG1, strlen(MSG1), + &written)) + || !TEST_int_eq(SSL_get_error(clientssl, 0), SSL_ERROR_WANT_READ) + || !TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf), + &readbytes), + SSL_READ_EARLY_DATA_FINISH) + || !TEST_size_t_eq(readbytes, 0) + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE)) + || !TEST_int_eq(SSL_get_early_data_status(clientssl), + SSL_EARLY_DATA_REJECTED)) + goto end; } else { OSSL_TIME timer = ossl_time_now(); @@ -5127,6 +5960,20 @@ static int test_early_data_psk(int idx) goto end; } + if (testdtls) { + /* + * We need to move the state machine along for DTLS1.3 + * The client needs to read the server hello and send its + * finish message and the server needs to ACK the finish + * message + */ + if (!TEST_true(SSL_connect(clientssl))) + goto end; + + if (!TEST_true(SSL_accept(serverssl))) + goto end; + } + if ((readearlyres == SSL_READ_EARLY_DATA_SUCCESS && !TEST_mem_eq(buf, readbytes, MSG1, strlen(MSG1))) || !TEST_int_eq(SSL_get_early_data_status(serverssl), edstatus) @@ -5157,6 +6004,8 @@ static int test_early_data_psk(int idx) * idx == 4: Test with TLS1_3_RFC_AES_128_CCM_8_SHA256 * idx == 5: Test with TLS1_3_RFC_SHA256_SHA256 * idx == 6: Test with TLS1_3_RFC_SHA384_SHA384 + * + * idx > 6: Tests are repeated with DTLS. */ static int test_early_data_psk_with_all_ciphers(int idx) { @@ -5204,6 +6053,20 @@ static int test_early_data_psk_with_all_ciphers(int idx) NULL #endif }; + int testdtls = idx >= 7; + + if (testdtls) { + idx -= 7; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("No usable DTLSv1.3"); + goto end; +#endif + } else { +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("No usable TLSv1.3"); + goto end; +#endif + } if (cipher_str[idx] == NULL) return 1; @@ -5213,11 +6076,18 @@ static int test_early_data_psk_with_all_ciphers(int idx) */ if ((idx == 2 || idx == 5 || idx == 6) && is_fips == 1) return 1; + /* + * RFC 9147 (DTLS 1.3): TLS_AES_128_CCM_8_SHA256 MUST NOT be used in + * DTLS without additional safeguards against forgery, which we do not + * implement, so this cipher is not offered under DTLS. + */ + if (idx == 4 && testdtls) + return 1; /* We always set this up with a final parameter of "2" for PSK */ if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, &serverssl, &sess, 2, - SHA384_DIGEST_LENGTH))) + SHA384_DIGEST_LENGTH, testdtls))) goto end; if (idx == 4 || idx == 5 || idx == 6) { @@ -5257,6 +6127,20 @@ static int test_early_data_psk_with_all_ciphers(int idx) goto end; } + if (testdtls) { + /* + * We need to move the state machine along for DTLS1.3 + * The client needs to read the server hello and send its + * finish message and the server needs to ACK the finish + * message + */ + if (!TEST_true(SSL_connect(clientssl))) + goto end; + + if (!TEST_true(SSL_accept(serverssl))) + goto end; + } + if (!TEST_mem_eq(buf, readbytes, MSG1, strlen(MSG1)) || !TEST_int_eq(SSL_get_early_data_status(serverssl), SSL_EARLY_DATA_ACCEPTED) @@ -5302,10 +6186,24 @@ static int test_early_data_not_expected(int idx) SSL_SESSION *sess = NULL; unsigned char buf[20]; size_t readbytes, written; + int testdtls = idx >= 3; + + if (testdtls) { + idx -= 3; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("No usable DTLSv1.3"); + goto end; +#endif + } else { +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("No usable TLSv1.3"); + goto end; +#endif + } if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, &serverssl, &sess, idx, - SHA384_DIGEST_LENGTH))) + SHA384_DIGEST_LENGTH, testdtls))) goto end; /* Write some early data */ @@ -5313,13 +6211,21 @@ static int test_early_data_not_expected(int idx) &written))) goto end; + if (!TEST_int_le(SSL_accept(serverssl), 0)) + goto end; + /* - * Server should skip over early data and then block waiting for client to - * continue handshake + * For DTLS1.3 the call to SSL_connect here still fails since + * it is waiting on the server to send an ACK to its Finished message. */ - if (!TEST_int_le(SSL_accept(serverssl), 0) - || !TEST_int_gt(SSL_connect(clientssl), 0) - || !TEST_int_eq(SSL_get_early_data_status(serverssl), + if (testdtls) { + if (!TEST_int_lt(SSL_connect(clientssl), 0)) + goto end; + } else { + if (!TEST_int_gt(SSL_connect(clientssl), 0)) + goto end; + } + if (!TEST_int_eq(SSL_get_early_data_status(serverssl), SSL_EARLY_DATA_REJECTED) || !TEST_int_gt(SSL_accept(serverssl), 0) || !TEST_int_eq(SSL_get_early_data_status(clientssl), @@ -5348,8 +6254,292 @@ static int test_early_data_not_expected(int idx) SSL_CTX_free(cctx); return testresult; } +#endif -#ifndef OPENSSL_NO_TLS1_2 +#if !defined(OSSL_NO_USABLE_TLS1_3) +/* + * Locks in the requirement that a resumed PSK's exact ciphersuite, not + * merely a shared digest, must match the negotiated one before 0-RTT data + * is accepted: the client encrypts its early data with the AEAD bound to + * its own PSK session before it can know what cipher the server will + * negotiate, so a same-digest-but-different-cipher negotiation must fall + * back to an ordinary connection rather than attempt decryption with the + * wrong cipher. + */ +static int test_early_data_psk_cipher_mismatch(void) +{ +#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + SSL_SESSION *sess = NULL; + unsigned char buf[20]; + size_t readbytes, written; + + if (is_fips) { + testresult = TEST_skip("CHACHA is not supported in FIPS"); + return 1; + } + + if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, + &serverssl, &sess, 2, SHA256_DIGEST_LENGTH, 0))) + goto end; + + /* + * The PSK is bound to AES-128-GCM (SHA256 digest). The client offers + * both AES-128-GCM and ChaCha20-Poly1305, so it can (and does) send 0-RTT + * keyed with the PSK's cipher; the server offers only ChaCha20-Poly1305. + * The server therefore selects a different cipher than the one that keyed + * the early data -- same digest -- and rejects the early data. + */ + if (!TEST_true(SSL_set_ciphersuites(clientssl, + "TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256")) + || !TEST_true(SSL_set_ciphersuites(serverssl, + "TLS_CHACHA20_POLY1305_SHA256"))) + goto end; + + SSL_set_connect_state(clientssl); + if (!TEST_true(SSL_write_early_data(clientssl, MSG1, strlen(MSG1), + &written))) + goto end; + + if (!TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf), + &readbytes), + SSL_READ_EARLY_DATA_FINISH) + || !TEST_int_eq(SSL_get_early_data_status(serverssl), + SSL_EARLY_DATA_REJECTED)) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + + testresult = 1; +end: + SSL_SESSION_free(sess); + SSL_SESSION_free(clientpsk); + SSL_SESSION_free(serverpsk); + clientpsk = serverpsk = NULL; + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +#else + return 1; +#endif +} + +#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) +/* + * A security callback that keeps TLS_AES_128_GCM_SHA256 off the wire, while + * leaving it in the configured ciphersuite list. + */ +static int no_aes128gcm_supported_cb(const SSL *ssl, const SSL_CTX *ctx, + int op, int bits, int nid, void *other, void *ex) +{ + if (op == SSL_SECOP_CIPHER_SUPPORTED && other != NULL + && strcmp(SSL_CIPHER_get_name((const SSL_CIPHER *)other), + "TLS_AES_128_GCM_SHA256") + == 0) + return 0; + return 1; +} + +/* + * A PSK bound to a SHA-256 cipher is offered, but a security callback drops + * that exact cipher from the ClientHello (leaving ChaCha20-Poly1305, same + * digest). Per RFC 9846 4.3.10 0-RTT needs the PSK's exact cipher on the wire, + * so early_data must be suppressed -- yet the PSK is still digest-compatible + * and resumes at 1-RTT. Regression guard for tls13_early_cipher_offered() / + * tls13_digest_offered() testing SSL_SECOP_CIPHER_SUPPORTED (what is actually + * serialised) rather than the configured list under SSL_SECOP_CIPHER_CHECK. + */ +static int test_early_data_psk_cipher_off_wire(void) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + SSL_SESSION *sess = NULL; + unsigned char buf[20]; + unsigned char edexp[32]; + size_t readbytes, written; + + if (is_fips) + return TEST_skip("CHACHA is not supported in FIPS"); + + if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, + &serverssl, &sess, 2, SHA256_DIGEST_LENGTH, 0))) + goto end; + + if (!TEST_true(SSL_set_ciphersuites(clientssl, + "TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256")) + || !TEST_true(SSL_set_ciphersuites(serverssl, + "TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256"))) + goto end; + + /* Drop the PSK's exact cipher from the client's wire offer. */ + SSL_set_security_level(clientssl, 0); + SSL_set_security_callback(clientssl, no_aes128gcm_supported_cb); + + SSL_set_connect_state(clientssl); + + /* + * The client suppresses 0-RTT (the PSK cipher is not on the wire): the + * first SSL_write_early_data() sends the ClientHello without early data and + * reports "retry"; the server sees no early data; the connection completes + * at 1-RTT with early data rejected on the client. + */ + if (!TEST_false(SSL_write_early_data(clientssl, MSG1, strlen(MSG1), + &written)) + || !TEST_int_eq(SSL_get_error(clientssl, 0), SSL_ERROR_WANT_READ) + /* + * Suppressing 0-RTT derives no early secrets, so the early exporter + * must be unavailable, both before the handshake completes -- where + * there is not even a negotiated cipher to take a digest from -- and + * after, where the status reads REJECTED as it would for a server + * rejection. + */ + || !TEST_false(SSL_export_keying_material_early(clientssl, edexp, + sizeof(edexp), "label", 5, NULL, 0)) + || !TEST_int_eq(SSL_read_early_data(serverssl, buf, sizeof(buf), + &readbytes), + SSL_READ_EARLY_DATA_FINISH) + || !TEST_size_t_eq(readbytes, 0) + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE)) + || !TEST_int_eq(SSL_get_early_data_status(clientssl), + SSL_EARLY_DATA_REJECTED) + || !TEST_false(SSL_export_keying_material_early(clientssl, edexp, + sizeof(edexp), "label", 5, NULL, 0))) + goto end; + + /* But the PSK still resumed, on the digest-compatible cipher. */ + if (!TEST_true(SSL_session_reused(clientssl)) + || !TEST_str_eq(SSL_CIPHER_get_name(SSL_get_current_cipher(clientssl)), + "TLS_CHACHA20_POLY1305_SHA256")) + goto end; + + testresult = 1; +end: + SSL_SESSION_free(sess); + SSL_SESSION_free(clientpsk); + SSL_SESSION_free(serverpsk); + clientpsk = serverpsk = NULL; + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} +#endif + +#ifndef OPENSSL_NO_EC +/* A raw external PSK bound to |suite_id|'s ciphersuite, master key all 0x01. */ +static SSL_SESSION *make_hrr_psk(SSL *ssl, const unsigned char *suite_id) +{ + static const unsigned char key[32] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + }; + const SSL_CIPHER *cipher = SSL_CIPHER_find(ssl, suite_id); + SSL_SESSION *s = SSL_SESSION_new(); + + if (s == NULL || cipher == NULL + || !SSL_SESSION_set1_master_key(s, key, sizeof(key)) + || !SSL_SESSION_set_cipher(s, cipher) + || !SSL_SESSION_set_protocol_version(s, TLS1_3_VERSION)) { + SSL_SESSION_free(s); + return NULL; + } + return s; +} + +static const unsigned char hrr_psk_id[] = "hrrpskid"; + +/* + * A poorly-behaved callback that yields a PSK bound to a SHA-384 cipher on the + * first (md == NULL) call and a SHA-256 one once the digest is known. + */ +static int hrr_use_session_cb(SSL *ssl, const EVP_MD *md, + const unsigned char **id, size_t *idlen, SSL_SESSION **sess) +{ + static const unsigned char sha384_id[] = { 0x13, 0x02 }; + static const unsigned char sha256_id[] = { 0x13, 0x01 }; + + *id = hrr_psk_id; + *idlen = sizeof(hrr_psk_id) - 1; + if (md == NULL) + *sess = make_hrr_psk(ssl, sha384_id); + else if (EVP_MD_is_a(md, "SHA256")) + *sess = make_hrr_psk(ssl, sha256_id); + else + *sess = NULL; + return *sess != NULL; +} + +static int hrr_find_session_cb(SSL *ssl, const unsigned char *identity, + size_t identity_len, SSL_SESSION **sess) +{ + static const unsigned char sha256_id[] = { 0x13, 0x01 }; + + if (identity_len != sizeof(hrr_psk_id) - 1 + || memcmp(identity, hrr_psk_id, identity_len) != 0) { + *sess = NULL; + return 1; + } + *sess = make_hrr_psk(ssl, sha256_id); + return *sess != NULL; +} + +/* + * After a HelloRetryRequest the second ClientHello must not introduce a + * pre_shared_key extension the first lacked (RFC 9846 4.2.2). Here the client + * offers only TLS_AES_128_GCM_SHA256, so the callback's first (SHA-384) PSK is + * dropped and CH1 carries no PSK; the retry then makes the callback yield a + * digest-compatible SHA-256 PSK. Check that no PSK extension is added in CH2. + */ +static int test_hrr_psk_no_ch2_add(void) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + int testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), TLS1_3_VERSION, TLS1_3_VERSION, + &sctx, &cctx, cert, privkey)) + || !TEST_true(SSL_CTX_set_ciphersuites(cctx, "TLS_AES_128_GCM_SHA256")) + || !TEST_true(SSL_CTX_set_ciphersuites(sctx, "TLS_AES_128_GCM_SHA256"))) + goto end; + SSL_CTX_set_psk_use_session_callback(cctx, hrr_use_session_cb); + SSL_CTX_set_psk_find_session_callback(sctx, hrr_find_session_cb); + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + /* Client sends a P-256 key_share; server forces a retry to P-384. */ + || !TEST_true(SSL_set1_groups_list(clientssl, "P-256:P-384")) + || !TEST_true(SSL_set1_groups_list(serverssl, "P-384"))) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + /* CH2 must not have added a PSK, so no resumption happened. */ + if (!TEST_false(SSL_session_reused(clientssl))) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} +#endif /* OPENSSL_NO_EC */ +#endif /* !defined(OSSL_NO_USABLE_TLS1_3) */ + +#if !defined(OSSL_NO_USABLE_TLS1_3) && !defined(OPENSSL_NO_TLS1_2) /* * Test that a server attempting to read early data can handle a connection * from a TLSv1.2 client. @@ -5364,7 +6554,7 @@ static int test_early_data_tls1_2(int idx) if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, &serverssl, NULL, idx, - SHA384_DIGEST_LENGTH))) + SHA384_DIGEST_LENGTH, 0))) goto end; /* Write some data - should block due to handshake with server */ @@ -5422,8 +6612,9 @@ static int test_early_data_tls1_2(int idx) return testresult; } -#endif /* OPENSSL_NO_TLS1_2 */ +#endif /* OSSL_NO_USABLE_TLS1_3 || OPENSSL_NO_TLS1_2 */ +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) /* * Test configuring the TLSv1.3 ciphersuites * @@ -5437,15 +6628,38 @@ static int test_early_data_tls1_2(int idx) * Test 7: Set a non-default ciphersuite in the SSL (SSL_CTX cipher_list) * Test 8: Set a default ciphersuite in the SSL (SSL cipher_list) * Test 9: Set a non-default ciphersuite in the SSL (SSL cipher_list) + * + * Test >9: Test are repeated for DTLS. */ static int test_set_ciphersuite(int idx) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; int testresult = 0; + const SSL_METHOD *smeth, *cmeth; + int vermin, vermax = 0; + int testdtls = idx >= 10; - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), TLS1_VERSION, 0, + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_VERSION; + idx -= 10; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("DTLSv1.3 is disabled"); + goto end; +#endif + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_VERSION; +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("TLSv1.3 is disabled"); + goto end; +#endif + } + + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, cert, privkey)) || !TEST_true(SSL_CTX_set_ciphersuites(sctx, "tls_aes_128_gcm_sha256:tls_aes_128_ccm_sha256"))) @@ -5505,17 +6719,37 @@ static int test_set_ciphersuite(int idx) return testresult; } -static int test_ciphersuite_change(void) +static int test_ciphersuite_change(int idx) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; SSL_SESSION *clntsess = NULL; int testresult = 0; const SSL_CIPHER *aes_128_gcm_sha256 = NULL; + const SSL_METHOD *smeth, *cmeth; + int vermin, vermax = 0; + int testdtls = idx >= 1; + + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_VERSION; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("DTLSv1.3 is not usable"); + goto end; +#endif + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_VERSION; +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("TLSv1.3 is not usable"); + goto end; +#endif + } /* Create a session based on SHA-256 */ - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), TLS1_VERSION, 0, + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, cert, privkey)) || !TEST_true(SSL_CTX_set_ciphersuites(sctx, "tls_aes_128_gcm_sha256:" @@ -5638,6 +6872,7 @@ static int test_ciphersuite_change(void) return testresult; } +#if !defined(OSSL_NO_USABLE_TLS1_3) /* * Test TLSv1.3 Key exchange * Test 0 = Test all ECDHE Key exchange with TLSv1.3 client and server @@ -5656,14 +6891,16 @@ static int test_ciphersuite_change(void) * Test 13 = Test MLKEM512 * Test 14 = Test MLKEM768 * Test 15 = Test MLKEM1024 - * Test 16 = Test X25519MLKEM768 - * Test 17 = Test SecP256r1MLKEM768 - * Test 18 = Test SecP384r1MLKEM1024 - * Test 19 = Test curveSM2 with TLSv1.3 client and server - * Test 20 = Test curveSM2MLKEM768 with TLSv1.3 client and server - * Test 21 = Test all ML-KEM with TLSv1.2 client and server - * Test 22 = Test all FFDHE with TLSv1.2 client and server - * Test 23 = Test all ECDHE with TLSv1.2 client and server + * Test 16 = Test MLKEM512X25519 + * Test 17 = Test X25519MLKEM768 + * Test 18 = Test SecP256r1MLKEM512 + * Test 19 = Test SecP256r1MLKEM768 + * Test 20 = Test SecP384r1MLKEM1024 + * Test 21 = Test curveSM2 with TLSv1.3 client and server + * Test 22 = Test curveSM2MLKEM768 with TLSv1.3 client and server + * Test 23 = Test all ML-KEM with TLSv1.2 client and server + * Test 24 = Test all FFDHE with TLSv1.2 client and server + * Test 25 = Test all ECDHE with TLSv1.2 client and server */ #ifndef OPENSSL_NO_EC static int ecdhe_kexch_groups[] = { NID_X9_62_prime256v1, NID_secp384r1, @@ -5694,7 +6931,7 @@ static int test_key_exchange(int idx) switch (idx) { #ifndef OPENSSL_NO_EC #ifndef OPENSSL_NO_TLS1_2 - case 23: + case 25: max_version = TLS1_2_VERSION; #endif /* OPENSSL_NO_TLS1_2 */ /* Fall through */ @@ -5732,7 +6969,7 @@ static int test_key_exchange(int idx) #endif /* OPENSSL_NO_EC */ #ifndef OPENSSL_NO_DH #ifndef OPENSSL_NO_TLS1_2 - case 22: + case 24: max_version = TLS1_2_VERSION; #endif /* OPENSSL_NO_TLS1_2 */ /* Fall through */ @@ -5764,7 +7001,7 @@ static int test_key_exchange(int idx) #endif /* OPENSSL_NO_DH */ #ifndef OPENSSL_NO_ML_KEM #if !defined(OPENSSL_NO_TLS1_2) - case 21: + case 23: max_version = TLS1_2_VERSION; kexch_groups = NULL; #if !defined(OPENSSL_NO_EC) @@ -5805,17 +7042,27 @@ static int test_key_exchange(int idx) #ifndef OPENSSL_NO_EC #ifndef OPENSSL_NO_ECX case 16: + kexch_groups = NULL; + kexch_name0 = "MLKEM512X25519"; + kexch_names = kexch_name0; + break; + case 17: kexch_groups = NULL; kexch_name0 = "X25519MLKEM768"; kexch_names = kexch_name0; break; #endif /* OPENSSL_NO_ECX */ - case 17: + case 18: + kexch_groups = NULL; + kexch_name0 = "SecP256r1MLKEM512"; + kexch_names = kexch_name0; + break; + case 19: kexch_groups = NULL; kexch_name0 = "SecP256r1MLKEM768"; kexch_names = kexch_name0; break; - case 18: + case 20: kexch_groups = NULL; kexch_name0 = "SecP384r1MLKEM1024"; kexch_names = kexch_name0; @@ -5825,7 +7072,7 @@ static int test_key_exchange(int idx) #ifndef OPENSSL_NO_EC #ifndef OPENSSL_NO_SM2 - case 19: + case 21: if (is_fips) return TEST_skip("curveSM2 is not supported by the fips provider."); kexch_groups = NULL; @@ -5833,7 +7080,7 @@ static int test_key_exchange(int idx) kexch_names = kexch_name0; break; #ifndef OPENSSL_NO_ML_KEM - case 20: + case 22: if (is_fips) return TEST_skip("curveSM2MLKEM768 is not supported by the fips provider."); kexch_groups = NULL; @@ -5850,9 +7097,13 @@ static int test_key_exchange(int idx) } if (is_fips && fips_provider_version_lt(libctx, 3, 5, 0) - && ((idx >= 12 && idx <= 18) || idx == 21)) + && ((idx >= 12 && idx <= 20) || idx == 23)) return TEST_skip("ML-KEM not supported in this version of fips provider"); + if (is_fips && fips_provider_version_lt(libctx, 4, 2, 0) + && (idx == 16 || idx == 18)) + return TEST_skip("ML-KEM-512 hybrids not supported in this version of fips provider"); + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), TLS_client_method(), TLS1_VERSION, max_version, &sctx, &cctx, cert, @@ -6150,14 +7401,20 @@ static int test_negotiated_group(int idx) SSL_SESSION_free(origsess); return testresult; } -#endif /* !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_DH) */ +#endif /* !defined(OSSL_NO_USABLE_TLS1_3) */ +#endif +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) /* - * Test TLSv1.3 Cipher Suite + * Test (D)TLSv1.3 Cipher Suite * Test 0 = Set TLS1.3 cipher on context * Test 1 = Set TLS1.3 cipher on SSL * Test 2 = Set TLS1.3 and TLS1.2 cipher on context * Test 3 = Set TLS1.3 and TLS1.2 cipher on SSL + * Test 4 = Set DTLS1.3 cipher on context + * Test 5 = Set DTLS1.3 cipher on SSL + * Test 6 = Set DTLS1.3 and DTLS1.2 cipher on context + * Test 7 = Set DTLS1.3 and DTLS1.2 cipher on SSL */ static int test_tls13_ciphersuite(int idx) { @@ -6196,6 +7453,33 @@ static int test_tls13_ciphersuite(int idx) int testresult = 0; int max_ver; size_t i; + const SSL_METHOD *smeth, *cmeth; + int vermin; + int version1_3, version1_2; + int testdtls = idx >= 4; + + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_VERSION; + version1_2 = DTLS1_2_VERSION; + version1_3 = DTLS1_3_VERSION; + idx -= 4; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("DTLSv1.3 is not usable"); + goto end; +#endif + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_VERSION; + version1_2 = TLS1_2_VERSION; + version1_3 = TLS1_3_VERSION; +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("TLSv1.3 is not usable"); + goto end; +#endif + } switch (idx) { case 0: @@ -6214,18 +7498,28 @@ static int test_tls13_ciphersuite(int idx) break; } - for (max_ver = TLS1_2_VERSION; max_ver <= TLS1_3_VERSION; max_ver++) { + for (max_ver = version1_2; max_ver <= version1_3; testdtls ? max_ver-- : max_ver++) { #ifdef OPENSSL_NO_TLS1_2 if (max_ver == TLS1_2_VERSION) continue; +#endif +#ifdef OPENSSL_NO_USABLE_TLS1_3 + if (max_ver == TLS1_3_VERSION) + continue; +#endif +#ifdef OPENSSL_NO_DTLS1_2 + if (max_ver == DTLS1_2_VERSION) + continue; +#endif +#ifdef OPENSSL_NO_USABLE_DTLS1_3 + if (max_ver == DTLS1_3_VERSION) + continue; #endif for (i = 0; i < OSSL_NELEM(t13_ciphers); i++) { if (is_fips && !t13_ciphers[i].fipscapable) continue; t13_cipher = t13_ciphers[i].ciphername; - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), - TLS1_VERSION, max_ver, + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, max_ver, &sctx, &cctx, cert, privkey))) goto end; @@ -6277,10 +7571,26 @@ static int test_tls13_ciphersuite(int idx) * TEST_strn_eq is used below because t13_cipher can contain * multiple ciphersuites */ - if (max_ver == TLS1_3_VERSION - && !TEST_strn_eq(t13_cipher, negotiated_scipher, - strlen(negotiated_scipher))) - goto end; + if (max_ver == version1_3) { + const char *expected = t13_cipher; + + /* + * TLS_AES_128_CCM_8_SHA256 is not offered under DTLS (RFC + * 9147 forbids it without additional forgery safeguards we + * do not implement). When an entry lists it first for a + * DTLS1.3 run, the next cipher in the list is what actually + * gets negotiated instead. + */ + if (testdtls + && strncmp(t13_cipher, TLS1_3_RFC_AES_128_CCM_8_SHA256, + strlen(TLS1_3_RFC_AES_128_CCM_8_SHA256)) + == 0) + expected = TLS1_3_RFC_AES_128_CCM_SHA256; + + if (!TEST_strn_eq(expected, negotiated_scipher, + strlen(negotiated_scipher))) + goto end; + } #ifndef OPENSSL_NO_TLS1_2 /* Below validation is not done when t12_cipher is NULL */ @@ -6288,6 +7598,12 @@ static int test_tls13_ciphersuite(int idx) && !TEST_str_eq(t12_cipher, negotiated_scipher)) goto end; #endif +#ifndef OPENSSL_NO_DTLS1_2 + /* Below validation is not done when t12_cipher is NULL */ + if (max_ver == DTLS1_2_VERSION && t12_cipher != NULL + && !TEST_str_eq(t12_cipher, negotiated_scipher)) + goto end; +#endif SSL_free(serverssl); serverssl = NULL; @@ -6315,6 +7631,8 @@ static int test_tls13_ciphersuite(int idx) * Test 1 = Test both new and old style callbacks * Test 2 = Test old style callbacks * Test 3 = Test old style callbacks with no certificate + * + * Test >3: Test are repeated for DTLS. */ static int test_tls13_psk(int idx) { @@ -6328,9 +7646,32 @@ static int test_tls13_psk(int idx) 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f }; int testresult = 0; + const SSL_METHOD *smeth, *cmeth; + int vermin, vermax = 0; + int testdtls = idx >= 4; + int clientpskver = TLS1_3_VERSION; - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), TLS1_VERSION, 0, + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_VERSION; + clientpskver = DTLS1_3_VERSION; + idx -= 4; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("No usable DTLSv1.3"); + goto end; +#endif + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_VERSION; +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("No usable TLSv1.3"); + goto end; +#endif + } + + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, idx == 3 ? NULL : cert, idx == 3 ? NULL : privkey))) goto end; @@ -6427,7 +7768,7 @@ static int test_tls13_psk(int idx) sizeof(key))) || !TEST_true(SSL_SESSION_set_cipher(clientpsk, cipher)) || !TEST_true(SSL_SESSION_set_protocol_version(clientpsk, - TLS1_3_VERSION)) + clientpskver)) || !TEST_true(SSL_SESSION_up_ref(clientpsk))) goto end; serverpsk = clientpsk; @@ -6546,41 +7887,67 @@ static int test_tls13_psk(int idx) return testresult; } -#ifndef OSSL_NO_USABLE_TLS1_3 /* - * Test TLS1.3 connection establishment succeeds with various configurations of - * the options `SSL_OP_ALLOW_NO_DHE_KEX` and `SSL_OP_PREFER_NO_DHE_KEX`. + * Test (D)TLS1.3 connection establishment succeeds with various configurations + * of the options `SSL_OP_ALLOW_NO_DHE_KEX` and `SSL_OP_PREFER_NO_DHE_KEX`. * The verification of whether the right KEX mode is chosen is not covered by * this test but by `test_tls13kexmodes`. * * Tests (idx & 1): Server has `SSL_OP_ALLOW_NO_DHE_KEX` set. * Tests (idx & 2): Server has `SSL_OP_PREFER_NO_DHE_KEX` set. * Tests (idx & 4): Client has `SSL_OP_ALLOW_NO_DHE_KEX` set. + * Tests (idx < 8): Tests are run with TLS. + * Tests (idx >= 8): Tests are run with DTLS. */ -static int test_tls13_no_dhe_kex(const int idx) +static int test_tls13_no_dhe_kex(int idx) { SSL_CTX *sctx = NULL, *cctx = NULL; + const SSL_METHOD *smeth, *cmeth; SSL *serverssl = NULL, *clientssl = NULL; int testresult = 0; + int vermin; size_t j; SSL_SESSION *saved_session; + int testdtls = idx >= 8; + int server_allow_no_dhe, server_prefer_no_dhe, client_allow_no_dhe; + uint64_t server_options, client_options; + + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_3_VERSION; + idx -= 8; - int server_allow_no_dhe = (idx & 1) != 0; - int server_prefer_no_dhe = (idx & 2) != 0; - int client_allow_no_dhe = (idx & 4) != 0; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("No usable DTLSv1.3"); + goto end; +#endif + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_3_VERSION; - uint64_t server_options = 0 +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("No usable TLSv1.3"); + goto end; +#endif + } + + server_allow_no_dhe = (idx & 1) != 0; + server_prefer_no_dhe = (idx & 2) != 0; + client_allow_no_dhe = (idx & 4) != 0; + + server_options = 0 | (server_allow_no_dhe ? SSL_OP_ALLOW_NO_DHE_KEX : 0) | (server_prefer_no_dhe ? SSL_OP_PREFER_NO_DHE_KEX : 0); - uint64_t client_options = 0 + client_options = 0 | (client_allow_no_dhe ? SSL_OP_ALLOW_NO_DHE_KEX : 0); new_called = 0; do_cache = 1; - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), TLS1_3_VERSION, 0, + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, 0, &sctx, &cctx, cert, privkey))) goto end; @@ -6617,8 +7984,7 @@ static int test_tls13_no_dhe_kex(const int idx) */ /* The server context already exists, so we only create the client. */ - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), TLS1_3_VERSION, 0, + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, 0, NULL, &cctx, cert, privkey))) goto end; @@ -6639,24 +8005,186 @@ static int test_tls13_no_dhe_kex(const int idx) if (!TEST_true(SSL_session_reused(clientssl))) goto end; - SSL_shutdown(clientssl); - SSL_shutdown(serverssl); - + SSL_shutdown(clientssl); + SSL_shutdown(serverssl); + + testresult = 1; + +end: + SSL_free(serverssl); + SSL_free(clientssl); + for (j = 0; j < OSSL_NELEM(sesscache); j++) { + SSL_SESSION_free(sesscache[j]); + sesscache[j] = NULL; + } + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + + return testresult; +} +#endif /* !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) */ +#ifndef OSSL_NO_USABLE_TLS1_3 + +#if !defined(OSSL_NO_USABLE_TLS1_3) +/* + * A server with SSL_VERIFY_PEER set but no session ID context configured + * must still accept a TLS 1.3 external PSK connection: the session was + * just resolved via the application's own callback for this identity, not + * read back out of a shared cache, so the sid_ctx check that guards + * against cross-context cache reuse does not apply to it. + */ +static int test_tls13_psk_verify_peer_no_sid_ctx(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + int testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), TLS1_VERSION, 0, &sctx, &cctx, NULL, NULL)) + || !TEST_true(SSL_CTX_set_ciphersuites(cctx, "TLS_AES_128_GCM_SHA256"))) + goto end; + + SSL_CTX_set_verify(sctx, SSL_VERIFY_PEER, NULL); + + SSL_CTX_set_psk_use_session_callback(cctx, use_session_cb); + SSL_CTX_set_psk_find_session_callback(sctx, find_session_cb); + srvid = pskid; + use_session_cb_cnt = 0; + find_session_cb_cnt = 0; + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL))) + goto end; + + clientpsk = create_a_psk(clientssl, SHA256_DIGEST_LENGTH); + if (!TEST_ptr(clientpsk) || !TEST_true(SSL_SESSION_up_ref(clientpsk))) + goto end; + serverpsk = clientpsk; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)) + || !TEST_true(SSL_session_reused(clientssl)) + || !TEST_true(SSL_session_reused(serverssl))) + goto end; + + testresult = 1; +end: + SSL_SESSION_free(clientpsk); + SSL_SESSION_free(serverpsk); + clientpsk = serverpsk = NULL; + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * A server with SSL_VERIFY_PEER set but no session ID context configured + * must not issue a session ticket after a full (non-PSK) handshake: any + * such ticket would be a poison pill, since resuming it would hit exactly + * the sid_ctx check that a fresh external PSK is exempted from above. + */ +static int test_tls13_psk_verify_peer_no_ticket(void) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + SSL_SESSION *sess = NULL; + int testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), TLS1_VERSION, 0, &sctx, &cctx, cert, privkey))) + goto end; + + SSL_CTX_set_verify(sctx, SSL_VERIFY_PEER, NULL); + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL)) + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE))) + goto end; + + sess = SSL_get1_session(clientssl); + if (!TEST_ptr(sess) || !TEST_false(SSL_SESSION_has_ticket(sess))) + goto end; + + testresult = 1; +end: + SSL_SESSION_free(sess); + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + return testresult; +} + +/* + * A client with its own session ID context configured must still be able + * to resume a TLS 1.3 external PSK obtained via the legacy + * psk_use_session_cb()/psk_client_callback() callbacks. s->psksession is + * never routed through ssl_get_new_session(), so, unlike an ordinary + * session, it was never stamped with the client's own sid_ctx; without + * that stamp tls_process_server_hello()'s own sid_ctx self-consistency + * check fatally rejects marking it reused. + * + * Test 0: new style callback (psk_use_session_cb()/psk_find_session_cb()). + * Test 1: old style callback (psk_client_callback()/psk_server_callback()). + */ +static int test_tls13_psk_client_sid_ctx(int idx) +{ + SSL_CTX *sctx = NULL, *cctx = NULL; + SSL *serverssl = NULL, *clientssl = NULL; + int sess_id_ctx = 1; + int testresult = 0; + + if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), + TLS_client_method(), TLS1_VERSION, 0, &sctx, &cctx, NULL, NULL)) + || !TEST_true(SSL_CTX_set_ciphersuites(cctx, "TLS_AES_128_GCM_SHA256")) + || !TEST_true(SSL_CTX_set_session_id_context(cctx, + (void *)&sess_id_ctx, sizeof(sess_id_ctx)))) + goto end; + + srvid = pskid; + if (idx == 0) { + SSL_CTX_set_psk_use_session_callback(cctx, use_session_cb); + SSL_CTX_set_psk_find_session_callback(sctx, find_session_cb); + use_session_cb_cnt = 0; + find_session_cb_cnt = 0; + } +#ifndef OPENSSL_NO_PSK + else { + SSL_CTX_set_psk_client_callback(cctx, psk_client_cb); + SSL_CTX_set_psk_server_callback(sctx, psk_server_cb); + psk_client_cb_cnt = 0; + psk_server_cb_cnt = 0; + } +#endif + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, + NULL, NULL))) + goto end; + + clientpsk = create_a_psk(clientssl, SHA256_DIGEST_LENGTH); + if (!TEST_ptr(clientpsk) || !TEST_true(SSL_SESSION_up_ref(clientpsk))) + goto end; + serverpsk = clientpsk; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)) + || !TEST_true(SSL_session_reused(clientssl)) + || !TEST_true(SSL_session_reused(serverssl))) + goto end; + testresult = 1; - end: + SSL_SESSION_free(clientpsk); + SSL_SESSION_free(serverpsk); + clientpsk = serverpsk = NULL; SSL_free(serverssl); SSL_free(clientssl); - for (j = 0; j < OSSL_NELEM(sesscache); j++) { - SSL_SESSION_free(sesscache[j]); - sesscache[j] = NULL; - } SSL_CTX_free(sctx); SSL_CTX_free(cctx); - return testresult; } -#endif /* OSSL_NO_USABLE_TLS1_3 */ +#endif /* !defined(OSSL_NO_USABLE_TLS1_3) */ static unsigned char cookie_magic_value[] = "cookie magic"; @@ -6782,6 +8310,7 @@ static int test_stateless(void) return testresult; } #endif /* OSSL_NO_USABLE_TLS1_3 */ +#endif /* !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) */ static int clntaddoldcb = 0; static int clntparseoldcb = 0; @@ -7138,7 +8667,8 @@ static int test_custom_exts(int tst) return testresult; } -#if !defined(OPENSSL_NO_TLS1_2) && !defined(OSSL_NO_USABLE_TLS1_3) +#if (!defined(OPENSSL_NO_TLS1_2) && !defined(OSSL_NO_USABLE_TLS1_3)) \ + || (!defined(OPENSSL_NO_DTLS1_2) && !defined(OSSL_NO_USABLE_DTLS1_3)) #define SYNTHV1CONTEXT (SSL_EXT_TLS1_2_AND_BELOW_ONLY \ | SSL_EXT_CLIENT_HELLO \ @@ -7183,7 +8713,7 @@ static int serverinfo_custom_parse_cb(SSL *s, unsigned int ext_type, return 1; } -static int test_serverinfo_custom(const int idx) +static int test_serverinfo_custom(int idx) { SSL_CTX *sctx = NULL, *cctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; @@ -7202,34 +8732,54 @@ static int test_serverinfo_custom(const int idx) size_t si_len = 0; const int call_use_serverinfo_ex = idx > 0; + const SSL_METHOD *smeth, *cmeth; + int testdtls = idx >= 4; + + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + idx -= 4; + +#if defined(OPENSSL_NO_DTLS1_2) || defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("DTLSv1.2 or DTLSv1.3 are disabled"); + goto end; +#endif + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + +#if defined(OPENSSL_NO_TLS1_2) || defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("TLSv1.2 or TLSv1.3 are disabled"); + goto end; +#endif + } + switch (idx) { case 0: /* FALLTHROUGH */ case 1: serverinfo_version = SSL_SERVERINFOV1; - protocol_version = TLS1_2_VERSION; + protocol_version = testdtls ? DTLS1_2_VERSION : TLS1_2_VERSION; extension_context = SYNTHV1CONTEXT; si = serverinfo_custom_v1; si_len = serverinfo_custom_v1_len; break; case 2: serverinfo_version = SSL_SERVERINFOV2; - protocol_version = TLS1_2_VERSION; + protocol_version = testdtls ? DTLS1_2_VERSION : TLS1_2_VERSION; extension_context = SYNTHV1CONTEXT; si = serverinfo_custom_v2; si_len = serverinfo_custom_v2_len; break; case 3: serverinfo_version = SSL_SERVERINFOV2; - protocol_version = TLS1_3_VERSION; + protocol_version = testdtls ? DTLS1_3_VERSION : TLS1_3_VERSION; extension_context = TLS13CONTEXT; si = serverinfo_custom_tls13; si_len = serverinfo_custom_tls13_len; break; } - if (!TEST_true(create_ssl_ctx_pair(libctx, - TLS_method(), - TLS_method(), + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, protocol_version, protocol_version, &sctx, &cctx, cert, privkey))) @@ -7469,7 +9019,7 @@ static int test_export_key_mat(int tst) return testresult; } -#ifndef OSSL_NO_USABLE_TLS1_3 +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) /* * Test that SSL_export_keying_material_early() produces expected * results. There are no test vectors so all we do is test that both @@ -7489,9 +9039,23 @@ static int test_export_key_mat_early(int idx) unsigned char skeymat1[80], skeymat2[80]; unsigned char buf[1]; size_t readbytes, written; + int testdtls = idx >= 3; + + if (testdtls) { + idx -= 3; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("No usable DTLSv1.3"); + goto end; +#endif + } else { +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("No usable TLSv1.3"); + goto end; +#endif + } if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, &serverssl, - &sess, idx, SHA384_DIGEST_LENGTH))) + &sess, idx, SHA384_DIGEST_LENGTH, testdtls))) goto end; /* Here writing 0 length early data is enough. */ @@ -7555,18 +9119,36 @@ static int test_export_key_mat_early(int idx) /* * Test KeyUpdate. */ -static int test_key_update(void) +static int test_key_update(int idx) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; int testresult = 0, i, j; char buf[20]; static char *mess = "A test message"; + const SSL_METHOD *smeth, *cmeth; + int vermin, vermax = 0; + int testdtls = idx >= 1; - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), - TLS1_3_VERSION, - 0, + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_3_VERSION; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("No usable DTLSv1.3"); + goto end; +#endif + } else { +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("No usable TLSv1.3"); + goto end; +#endif + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_3_VERSION; + } + + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, cert, privkey)) || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) @@ -7583,6 +9165,54 @@ static int test_key_update(void) : SSL_KEY_UPDATE_REQUESTED)) || !TEST_true(SSL_do_handshake(clientssl))) goto end; + + if (testdtls) { + /* + * For DTLS1.3 we need to call the server side too since + * he needs to send an ACK and client has to process that ACK + * + * For SSL_KEY_UPDATE_REQUESTED after loop 0 + * the server read will result in sending the prior + * key update. So, unlike the TLS test, for DTLS + * we cannot wait until all 40 messages have been + * queued. Therefore for DTLS we will clean things + * up before the write/reads below. + * If we do not let the server send its key update + * then it will not be able to send the ACK from + * the client update and then the client will + * not be able to send the next key update because it + * is waiting on an ACK. + */ + if (!TEST_int_eq(SSL_read(serverssl, buf, sizeof(buf)), -1)) + goto end; + + /* + * DTLS 1.3 Client will read the ACK message + */ + if (!TEST_int_eq(SSL_read(clientssl, buf, sizeof(buf)), -1)) + goto end; + + /* + * If DTLS1.3 Server needs to send a Key Update back + * it needs to make a do_handshake call too + */ + if (j == 1) { + if (!TEST_int_eq(SSL_write(serverssl, mess, (int)strlen(mess)), -1)) + goto end; + + /* + * Client needs to read the servers key update and send an ACK + */ + if (!TEST_int_eq(SSL_read(clientssl, buf, sizeof(buf)), -1)) + goto end; + + /* + * The server needs to read the ACK + */ + if (!TEST_int_eq(SSL_read(serverssl, buf, sizeof(buf)), -1)) + goto end; + } + } } /* Check that sending and receiving app data is ok */ @@ -7614,7 +9244,7 @@ static int test_key_update(void) * Test 0: Client sends KeyUpdate while Server is writing * Test 1: Server sends KeyUpdate while Client is writing */ -static int test_key_update_peer_in_write(int tst) +static int test_key_update_peer_in_write(int idx) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; @@ -7624,12 +9254,33 @@ static int test_key_update_peer_in_write(int tst) BIO *bretry = BIO_new(bio_s_always_retry()); BIO *tmp = NULL; SSL *peerupdate = NULL, *peerwrite = NULL; + const SSL_METHOD *smeth, *cmeth; + int vermin, vermax = 0; + int testdtls = idx >= 2; + int expected_update_result = 1; + + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_3_VERSION; + idx -= 2; + +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("No usable DTLSv1.3"); + goto end; +#endif + } else { +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("No usable TLSv1.3"); + goto end; +#endif + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_3_VERSION; + } if (!TEST_ptr(bretry) - || !TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), - TLS1_3_VERSION, - 0, + || !TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, cert, privkey)) || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) @@ -7637,11 +9288,35 @@ static int test_key_update_peer_in_write(int tst) SSL_ERROR_NONE))) goto end; - peerupdate = tst == 0 ? clientssl : serverssl; - peerwrite = tst == 0 ? serverssl : clientssl; + peerupdate = idx == 0 ? clientssl : serverssl; + peerwrite = idx == 0 ? serverssl : clientssl; + + /* + * DTLS 1.3 if the client sends the key update it will return -1 + * since it is waiting for an ACK from the server. + */ + if (testdtls) { + size_t bytes_read = 0; + + /* + * For DTLS1.3 the server needs to read the NewSessionTicket + * ack from the client before it can process the KeyUpdate + * message from down below. + */ + if (idx == 1) + if (!TEST_false(SSL_read_ex(serverssl, buf, sizeof(buf), &bytes_read)) + || !TEST_size_t_eq(bytes_read, 0)) + goto end; + + /* + * Expected update result is -1 for the peerupdate will be + * waiting for an ACK from the other side. + */ + expected_update_result = -1; + } if (!TEST_true(SSL_key_update(peerupdate, SSL_KEY_UPDATE_REQUESTED)) - || !TEST_int_eq(SSL_do_handshake(peerupdate), 1)) + || !TEST_int_eq(SSL_do_handshake(peerupdate), expected_update_result)) goto end; /* Swap the writing endpoint's write BIO to force a retry */ @@ -7671,6 +9346,32 @@ static int test_key_update_peer_in_write(int tst) || !TEST_true(SSL_net_read_desired(peerwrite))) goto end; + if (testdtls) { + /* + * The peer write just sent an Key Update message + * it is waiting to get an ACK and cannot write + * until it receives an ACK. + */ + if (!TEST_int_eq(SSL_read(peerupdate, buf, sizeof(buf)), -1)) + goto end; + + /* + * The peerwrite needs to construct its key update + */ + if (!TEST_int_eq(SSL_write(peerwrite, mess, (int)strlen(mess)), -1)) + goto end; + + /* + * The peerupdate needs to ack the key update sent by + * the peerwrite. + * + * If this doesn't happen in the SSL_write below it will + * fail for the peerwrite is waiting on an ACK. + */ + if (!TEST_int_eq(SSL_read(peerupdate, buf, sizeof(buf)), -1)) + goto end; + } + /* * Complete the write we started previously and read it from the other * endpoint @@ -7709,7 +9410,7 @@ static int test_key_update_peer_in_write(int tst) * Test 0: Client sends KeyUpdate while Server is reading * Test 1: Server sends KeyUpdate while Client is reading */ -static int test_key_update_peer_in_read(int tst) +static int test_key_update_peer_in_read(int idx) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; @@ -7718,11 +9419,32 @@ static int test_key_update_peer_in_read(int tst) static char *mess = "A test message"; BIO *lbio = NULL, *pbio = NULL; SSL *local = NULL, *peer = NULL; + const SSL_METHOD *smeth, *cmeth; + int vermin, vermax = 0; + int testdtls = idx >= 2; + int bio_size = 512; + int dtls_max_size = 495; /* bio_size - DTLS1.3 Header (5 bytes) - DTLS1.3 ACK - buffer */ - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), - TLS1_3_VERSION, - 0, + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_3_VERSION; + idx -= 2; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("No usable DTLSv1.3"); + goto end; +#endif + } else { +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("No usable TLSv1.3"); + goto end; +#endif + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_3_VERSION; + } + + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, cert, privkey)) || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) @@ -7730,50 +9452,110 @@ static int test_key_update_peer_in_read(int tst) SSL_ERROR_NONE))) goto end; - local = tst == 0 ? clientssl : serverssl; - peer = tst == 0 ? serverssl : clientssl; - - if (!TEST_int_eq(BIO_new_bio_pair(&lbio, 512, &pbio, 512), 1)) + /* Process the session ticket ACKs before starting a KeyUpdate. */ + if (testdtls + && !TEST_int_eq(SSL_read(serverssl, prbuf, sizeof(prbuf)), -1)) goto end; + local = idx == 0 ? clientssl : serverssl; + peer = idx == 0 ? serverssl : clientssl; + + if (!testdtls) { + if (!TEST_int_eq(BIO_new_bio_pair(&lbio, bio_size, &pbio, bio_size), 1)) + goto end; + } else { +#if !defined(OSSL_NO_USABLE_DTLS1_3) + if (!TEST_int_eq(BIO_new_bio_dgram_pair(&lbio, bio_size, &pbio, bio_size), 1)) + goto end; +#endif + } + SSL_set_bio(local, lbio, lbio); SSL_set_bio(peer, pbio, pbio); - /* - * we first write keyupdate msg then appdata in local - * write data in local will fail with SSL_ERROR_WANT_WRITE,because - * lwbuf app data msg size + key updata msg size > 512(the size of - * the bio pair buffer) - */ - if (!TEST_true(SSL_key_update(local, SSL_KEY_UPDATE_REQUESTED)) - || !TEST_int_eq(SSL_write(local, lwbuf, sizeof(lwbuf)), -1) - || !TEST_int_eq(SSL_get_error(local, -1), SSL_ERROR_WANT_WRITE)) - goto end; + if (testdtls) { + /* + * DTLS 1.3 will return a SSL_ERROR_WANT_READ for the client wants + * to read an ACK to its KeyUpdate message. + */ + if (!TEST_true(SSL_key_update(local, SSL_KEY_UPDATE_REQUESTED)) + || !TEST_int_eq(SSL_write(local, lwbuf, sizeof(lwbuf)), -1) + || !TEST_int_eq(SSL_get_error(local, -1), SSL_ERROR_WANT_READ)) + goto end; - /* - * first read keyupdate msg in peer in peer - * then read appdata that we know will fail with SSL_ERROR_WANT_READ - */ - if (!TEST_int_eq(SSL_read(peer, prbuf, sizeof(prbuf)), -1) - || !TEST_int_eq(SSL_get_error(peer, -1), SSL_ERROR_WANT_READ)) - goto end; + /* + * first read keyupdate msg in peer + * then read appdata that we know will fail with SSL_ERROR_WANT_READ + */ + if (!TEST_int_eq(SSL_read(peer, prbuf, sizeof(prbuf)), -1) + || !TEST_int_eq(SSL_get_error(peer, -1), SSL_ERROR_WANT_READ)) + goto end; - /* Now write some data in peer - we will write the key update */ - if (!TEST_int_eq(SSL_write(peer, mess, (int)strlen(mess)), (int)strlen(mess))) - goto end; + /* + * For DTLS1.3 the peer now needs to write to send out + * its key update message. + * + * It will send an SSL_ERROR_WANT_READ since it is waiting + * for an ACK from the other side. + */ + /* Now write some data in peer - we will write the key update */ + if (!TEST_int_eq(SSL_write(peer, mess, (int)strlen(mess)), -1) + || !TEST_int_eq(SSL_get_error(peer, -1), SSL_ERROR_WANT_READ)) + goto end; - /* - * write data in local previously that we will complete - * read data in peer previously that we will complete - */ - if (!TEST_int_eq(SSL_write(local, lwbuf, sizeof(lwbuf)), sizeof(lwbuf)) - || !TEST_int_eq(SSL_read(peer, prbuf, sizeof(prbuf)), sizeof(prbuf))) - goto end; + /* + * Local needs to read the ACK and respond to the Key Update and + * it will send out the ACK to the key update. + */ + if (!TEST_int_eq(SSL_read(local, prbuf, sizeof(prbuf)), -1) + || !TEST_int_eq(SSL_get_error(local, -1), SSL_ERROR_WANT_READ)) + goto end; - /* check that sending and receiving appdata ok */ - if (!TEST_int_eq(SSL_write(local, mess, (int)strlen(mess)), (int)strlen(mess)) - || !TEST_int_eq(SSL_read(peer, prbuf, sizeof(prbuf)), (int)strlen(mess))) - goto end; + if (!TEST_int_eq(SSL_write(local, lwbuf, dtls_max_size), dtls_max_size) + || !TEST_int_eq(SSL_read(peer, prbuf, sizeof(prbuf)), dtls_max_size)) + goto end; + + /* check that sending and receiving appdata ok */ + if (!TEST_int_eq(SSL_write(local, mess, (int)strlen(mess)), (int)strlen(mess)) + || !TEST_int_eq(SSL_read(peer, prbuf, sizeof(prbuf)), (int)strlen(mess))) + goto end; + } else { + /* + * we first write keyupdate msg then appdata in local + * write data in local will fail with SSL_ERROR_WANT_WRITE,because + * lwbuf app data msg size + key updata msg size > 512(the size of + * the bio pair buffer) + */ + if (!TEST_true(SSL_key_update(local, SSL_KEY_UPDATE_REQUESTED)) + || !TEST_int_eq(SSL_write(local, lwbuf, sizeof(lwbuf)), -1) + || !TEST_int_eq(SSL_get_error(local, -1), SSL_ERROR_WANT_WRITE)) + goto end; + + /* + * first read keyupdate msg in peer in peer + * then read appdata that we know will fail with SSL_ERROR_WANT_READ + */ + if (!TEST_int_eq(SSL_read(peer, prbuf, sizeof(prbuf)), -1) + || !TEST_int_eq(SSL_get_error(peer, -1), SSL_ERROR_WANT_READ)) + goto end; + + /* Now write some data in peer - we will write the key update */ + if (!TEST_int_eq(SSL_write(peer, mess, (int)strlen(mess)), (int)strlen(mess))) + goto end; + + /* + * write data in local previously that we will complete + * read data in peer previously that we will complete + */ + if (!TEST_int_eq(SSL_write(local, lwbuf, sizeof(lwbuf)), sizeof(lwbuf)) + || !TEST_int_eq(SSL_read(peer, prbuf, sizeof(prbuf)), sizeof(prbuf))) + goto end; + + /* check that sending and receiving appdata ok */ + if (!TEST_int_eq(SSL_write(local, mess, (int)strlen(mess)), (int)strlen(mess)) + || !TEST_int_eq(SSL_read(peer, prbuf, sizeof(prbuf)), (int)strlen(mess))) + goto end; + } testresult = 1; @@ -7792,7 +9574,7 @@ static int test_key_update_peer_in_read(int tst) * Test 0: Client sends KeyUpdate while Client is writing * Test 1: Server sends KeyUpdate while Server is writing */ -static int test_key_update_local_in_write(int tst) +static int test_key_update_local_in_write(int idx) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; @@ -7802,12 +9584,32 @@ static int test_key_update_local_in_write(int tst) BIO *bretry = BIO_new(bio_s_always_retry()); BIO *tmp = NULL; SSL *local = NULL, *peer = NULL; + const SSL_METHOD *smeth, *cmeth; + int vermin, vermax = 0; + int testdtls = idx >= 2; + int expected_do_handshake_result = testdtls ? -1 : 1; + + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = TLS1_3_VERSION; + idx -= 2; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("No usable DTLSv1.3"); + goto end; +#endif + } else { +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("No usable TLSv1.3"); + goto end; +#endif + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_3_VERSION; + } if (!TEST_ptr(bretry) - || !TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), - TLS1_3_VERSION, - 0, + || !TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, cert, privkey)) || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) @@ -7815,8 +9617,8 @@ static int test_key_update_local_in_write(int tst) SSL_ERROR_NONE))) goto end; - local = tst == 0 ? clientssl : serverssl; - peer = tst == 0 ? serverssl : clientssl; + local = idx == 0 ? clientssl : serverssl; + peer = idx == 0 ? serverssl : clientssl; /* Swap the writing endpoint's write BIO to force a retry */ tmp = SSL_get_wbio(local); @@ -7836,10 +9638,15 @@ static int test_key_update_local_in_write(int tst) SSL_set0_wbio(local, tmp); tmp = NULL; - /* SSL_key_update will fail, because writing in local*/ - if (!TEST_false(SSL_key_update(local, SSL_KEY_UPDATE_REQUESTED)) - || !TEST_int_eq(ERR_GET_REASON(ERR_peek_error()), SSL_R_BAD_WRITE_RETRY)) - goto end; + /* + * For DTLS1.3 the key update will succeed for it would + * have just dropped the packet above + */ + if (!testdtls) + /* SSL_key_update will fail, because writing in local */ + if (!TEST_false(SSL_key_update(local, SSL_KEY_UPDATE_REQUESTED)) + || !TEST_int_eq(ERR_GET_REASON(ERR_peek_error()), SSL_R_BAD_WRITE_RETRY)) + goto end; ERR_clear_error(); /* write data in local previously that we will complete */ @@ -7848,9 +9655,29 @@ static int test_key_update_local_in_write(int tst) /* SSL_key_update will succeed because there is no pending write data */ if (!TEST_true(SSL_key_update(local, SSL_KEY_UPDATE_REQUESTED)) - || !TEST_int_eq(SSL_do_handshake(local), 1)) + || !TEST_int_eq(SSL_do_handshake(local), expected_do_handshake_result) + || (testdtls && !TEST_int_eq(SSL_get_error(local, -1), SSL_ERROR_WANT_READ))) goto end; + if (testdtls) { + /* + * So the local can write again down below the + * peer needs to read the data and the Key Update + * and send an ACK back to the local. Though + * first we must read the right above and the + * ACKS from the new session ticket. + */ + if (!TEST_int_eq(SSL_read(peer, buf, sizeof(buf)), (int)strlen(mess))) + goto end; + + /* + * For DTLS1.3 the peer needs to read the key update + * and send an ACK + */ + if (!TEST_int_eq(SSL_read(peer, buf, sizeof(buf)), -1)) + goto end; + } + /* * we write some appdata in local * read data in peer - we will read the keyupdate msg @@ -7859,6 +9686,21 @@ static int test_key_update_local_in_write(int tst) || !TEST_int_eq(SSL_read(peer, buf, sizeof(buf)), (int)strlen(mess))) goto end; + if (testdtls) { + /* + * DTLS1.3 the peer needs to write to send out + * its key update + */ + if (!TEST_int_eq(SSL_write(peer, mess, (int)strlen(mess)), -1)) + goto end; + + /* + * The local side needs to read the ACK + */ + if (!TEST_int_eq(SSL_read(local, buf, sizeof(buf)), -1)) + goto end; + } + /* Write more peer more data to ensure we send the keyupdate message back */ if (!TEST_int_eq(SSL_write(peer, mess, (int)strlen(mess)), (int)strlen(mess)) || !TEST_int_eq(SSL_read(local, buf, sizeof(buf)), (int)strlen(mess))) @@ -7876,7 +9718,9 @@ static int test_key_update_local_in_write(int tst) return testresult; } +#endif /* OSSL_NO_USABLE_TLS1_3 | OSSL_NO_USABLE_DTLS1_3 */ +#if !defined(OSSL_NO_USABLE_TLS1_3) /* * Test we can handle a KeyUpdate (update requested) message while * local read data is pending(the msg header had been read 5 bytes). @@ -8851,7 +10695,7 @@ static int test_info_callback(int tst) /* early_data tests */ if (!TEST_true(setupearly_data_test(&cctx, &sctx, &clientssl, &serverssl, &sess, 0, - SHA384_DIGEST_LENGTH))) + SHA384_DIGEST_LENGTH, 0))) goto end; /* We don't actually need this reference */ @@ -8959,9 +10803,15 @@ static int test_ssl_pending(int tst) goto end; } else { #ifndef OPENSSL_NO_DTLS + int maxversion = 0; + +#ifdef OSSL_NO_USABLE_DTLS1_3 + maxversion = DTLS1_2_VERSION; +#endif + if (!TEST_true(create_ssl_ctx_pair(libctx, DTLS_server_method(), DTLS_client_method(), - DTLS1_VERSION, 0, + DTLS1_VERSION, maxversion, &sctx, &cctx, cert, privkey))) goto end; @@ -10645,32 +12495,78 @@ static int test_session_timeout(int test) * Test 1: TLSv1.2, timeout on new session later than old session * Test 2: TLSv1.3, timeout on new session earlier than old session * Test 3: TLSv1.2, timeout on new session earlier than old session + * Test 4: DTLSv1.3, timeout on new session later than old session + * Test 5: DTLSv1.2, timeout on new session later than old session + * Test 6: DTLSv1.3, timeout on new session earlier than old session + * Test 7: DTLSv1.2, timeout on new session earlier than old session */ -#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) \ + || !defined(OSSL_NO_USABLE_DTLS1_3) || !defined(OPENSSL_NO_DTLS1_2) static int test_session_cache_overflow(int idx) { SSL_CTX *sctx = NULL, *cctx = NULL; SSL *serverssl = NULL, *clientssl = NULL; int testresult = 0; SSL_SESSION *sess = NULL; + const SSL_METHOD *smeth, *cmeth; + int vermin, vermax = 0; + int testdtls = idx >= 4; + + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_VERSION; + idx -= 4; + vermax = (idx % 2 == 0) ? DTLS1_3_VERSION : DTLS1_2_VERSION; + +#if defined(OSSL_NO_USABLE_DTLS1_3) && defined(OPENSSL_NO_DTLS1_2) + testresult = TEST_skip("DTLSv1.3 and DTLSv1.2 are disabled"); + goto end; +#endif + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_VERSION; + vermax = (idx % 2 == 0) ? TLS1_3_VERSION : TLS1_2_VERSION; + +#if defined(OSSL_NO_USABLE_TLS1_3) && defined(OPENSSL_NO_TLS1_2) + testresult = TEST_skip("TLSv1.3 and TLSv1.2 are disabled"); + goto end; +#endif + } get_sess_val = NULL; #ifdef OSSL_NO_USABLE_TLS1_3 /* If no TLSv1.3 available then do nothing in this case */ - if (idx % 2 == 0) - return TEST_skip("No TLSv1.3 available"); + if (idx % 2 == 0 && !testdtls) { + testresult = TEST_skip("No TLSv1.3 available"); + goto end; + } #endif #ifdef OPENSSL_NO_TLS1_2 /* If no TLSv1.2 available then do nothing in this case */ - if (idx % 2 == 1) - return TEST_skip("No TLSv1.2 available"); + if (idx % 2 == 1 && !testdtls) { + testresult = TEST_skip("No TLSv1.2 available"); + goto end; + } +#endif +#ifdef OSSL_NO_USABLE_DTLS1_3 + /* If no DTLSv1.3 available then do nothing in this case */ + if (idx % 2 == 0 && testdtls) { + testresult = TEST_skip("No DTLSv1.3 available"); + goto end; + } +#endif +#ifdef OPENSSL_NO_DTLS1_2 + /* If no DTLSv1.2 available then do nothing in this case */ + if (idx % 2 == 1 && testdtls) { + testresult = TEST_skip("No DTLSv1.2 available"); + goto end; + } #endif - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), TLS1_VERSION, - (idx % 2 == 0) ? TLS1_3_VERSION - : TLS1_2_VERSION, + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, cert, privkey)) || !TEST_true(SSL_CTX_set_options(sctx, SSL_OP_NO_TICKET))) goto end; @@ -10761,7 +12657,10 @@ static int test_session_cache_overflow(int idx) return testresult; } -#endif /* !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) */ +#endif /* \ + * !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) \ + * || !defined(OSSL_NO_USABLE_DTLS1_3) || !defined(OPENSSL_NO_DTLS1_2) \ + */ /* * Test 0: Client sets servername and server acknowledges it (TLSv1.2) @@ -11015,8 +12914,9 @@ static int test_configuration_of_groups(void) } #endif -#if !defined(OPENSSL_NO_EC) \ - && (!defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2)) +#if !defined(OPENSSL_NO_EC) \ + && (!defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) \ + || !defined(OSSL_NO_USABLE_DTLS1_3) || !defined(OPENSSL_NO_DTLS1_2)) /* * Test that if signature algorithms are not available, then we do not offer or * accept them. @@ -11026,6 +12926,7 @@ static int test_configuration_of_groups(void) * Test 3: An RSA and an ECDSA sig alg available: both sig algs shared * Test 4: The client only has an ECDSA sig alg: only ECDSA algorithms shared * Test 5: The server only has an ECDSA sig alg: only ECDSA algorithms shared + * Test >5: Tests are repeated for DTLS */ static int test_sigalgs_available(int idx) { @@ -11039,6 +12940,30 @@ static int test_sigalgs_available(int idx) unsigned char rsig, rhash; unsigned int sigalg, csigalg_expected; const char *sigalg_name, *signame_expected, *csigname_expected; + const SSL_METHOD *smeth, *cmeth; + int vermin, vermax = 0; + int testdtls = idx >= 6; + + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_VERSION; + idx -= 6; + +#if defined(OSSL_NO_USABLE_DTLS1_3) && defined(OPENSSL_NO_DTLS1_2) + testresult = TEST_skip("EC or DTLSv1.3 and DTLSv1.2 are disabled"); + goto end; +#endif + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_VERSION; + +#if defined(OSSL_NO_USABLE_TLS1_3) && defined(OPENSSL_NO_TLS1_2) + testresult = TEST_skip("EC or TLSv1.3 and TLSv1.2 are disabled"); + goto end; +#endif + } if (!TEST_ptr(tmpctx)) goto end; @@ -11081,8 +13006,8 @@ static int test_sigalgs_available(int idx) serverctx = tmpctx; } - cctx = SSL_CTX_new_ex(clientctx, NULL, TLS_client_method()); - sctx = SSL_CTX_new_ex(serverctx, NULL, TLS_server_method()); + cctx = SSL_CTX_new_ex(clientctx, NULL, cmeth); + sctx = SSL_CTX_new_ex(serverctx, NULL, smeth); if (!TEST_ptr(cctx) || !TEST_ptr(sctx)) goto end; @@ -11095,23 +13020,17 @@ static int test_sigalgs_available(int idx) if (idx != 5) { /* RSA first server key */ - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), - TLS1_VERSION, - 0, + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, cert, privkey))) goto end; } else { /* ECDSA P-256 first server key */ - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), - TLS1_VERSION, - 0, + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, cert2, privkey2))) goto end; } - /* Ensure we only use TLSv1.2 ciphersuites based on SHA256 */ + /* Ensure we only use (D)TLSv1.2 ciphersuites based on SHA256 */ if (idx < 4) { if (!TEST_true(SSL_CTX_set_cipher_list(cctx, "ECDHE-RSA-AES128-GCM-SHA256"))) @@ -11213,37 +13132,70 @@ static int test_sigalgs_available(int idx) return testresult; } -#endif /* \ - * !defined(OPENSSL_NO_EC) \ - * && (!defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2)) \ - */ +#endif -#ifndef OPENSSL_NO_TLS1_3 -/* This test can run in TLSv1.3 even if ec and dh are disabled */ +#if !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_DTLS1_3) static int test_pluggable_group(int idx) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; + const SSL_METHOD *smeth, *cmeth; int testresult = 0; OSSL_PROVIDER *tlsprov = OSSL_PROVIDER_load(libctx, "tls-provider"); /* Check that we are not impacted by a provider without any groups */ OSSL_PROVIDER *legacyprov = OSSL_PROVIDER_load(libctx, "legacy"); - const char *group_name = idx == 0 ? "xorkemgroup" : "xorgroup"; + char *group_name; + int vermin, vermax; + int testdtls = idx >= 2; + + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = vermax = DTLS1_3_VERSION; + idx -= 2; + +/* This test can run in DTLSv1.3 even if ec and dh are disabled */ +#if defined(OPENSSL_NO_DTLS1_3) + testresult = TEST_skip("DTLSv1.3 is disabled"); + goto end; +#endif + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = vermax = TLS1_3_VERSION; + +/* This test can run in TLSv1.3 even if ec and dh are disabled */ +#if defined(OPENSSL_NO_TLS1_3) + testresult = TEST_skip("TLSv1.3 is disabled"); + goto end; +#endif + } + + if (idx == 0) + group_name = "xorkemgroup"; + else + group_name = "xorgroup"; if (!TEST_ptr(tlsprov)) goto end; - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), - TLS1_3_VERSION, - TLS1_3_VERSION, + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, cert, privkey)) || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL))) goto end; /* ensure GROUPLIST_INCREMENT (=40) logic triggers: */ - if (!TEST_true(SSL_set1_groups_list(serverssl, "xorgroup:xorkemgroup:dummy1:dummy2:dummy3:dummy4:dummy5:dummy6:dummy7:dummy8:dummy9:dummy10:dummy11:dummy12:dummy13:dummy14:dummy15:dummy16:dummy17:dummy18:dummy19:dummy20:dummy21:dummy22:dummy23:dummy24:dummy25:dummy26:dummy27:dummy28:dummy29:dummy30:dummy31:dummy32:dummy33:dummy34:dummy35:dummy36:dummy37:dummy38:dummy39:dummy40:dummy41:dummy42:dummy43")) + if (!TEST_true(SSL_set1_groups_list(serverssl, + "xorgroup:xorkemgroup:dummy1:dummy2:dummy3" + ":dummy4:dummy5:dummy6:dummy7:dummy8:dummy9" + ":dummy10:dummy11:dummy12:dummy13:dummy14" + ":dummy15:dummy16:dummy17:dummy18:dummy19" + ":dummy20:dummy21:dummy22:dummy23:dummy24" + ":dummy25:dummy26:dummy27:dummy28:dummy29" + ":dummy30:dummy31:dummy32:dummy33:dummy34" + ":dummy35:dummy36:dummy37:dummy38:dummy39" + ":dummy40:dummy41:dummy42:dummy43")) /* removing a single algorithm from the list makes the test pass */ || !TEST_true(SSL_set1_groups_list(clientssl, group_name))) goto end; @@ -11323,19 +13275,21 @@ static int create_cert_key(int idx, char *certfilename, char *privkeyfilename) /* * Test that signature algorithms loaded via the provider interface can - * correctly establish a TLS (1.3) connection. + * correctly establish a (D)TLSv1.3 connection. * Test 0: Signature algorithm with built-in hashing functionality: "xorhmacsig" * Test 1: Signature algorithm using external SHA2 hashing: "xorhmacsha2sig" * Test 2: Signature algorithm with built-in hashing configured via SSL_CONF_cmd * Test 3: Test 0 using RPK * Test 4: Test 1 using RPK * Test 5: Test 2 using RPK + * Test >5: Tests repeated for DTLS */ static int test_pluggable_signature(int idx) { static const unsigned char cert_type_rpk[] = { TLSEXT_cert_type_rpk, TLSEXT_cert_type_x509 }; SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; + const SSL_METHOD *smeth, *cmeth; int testresult = 0; OSSL_PROVIDER *tlsprov = OSSL_PROVIDER_load(libctx, "tls-provider"); OSSL_PROVIDER *defaultprov = OSSL_PROVIDER_load(libctx, "default"); @@ -11345,12 +13299,33 @@ static int test_pluggable_signature(int idx) int sigidx = idx % 3; int rpkidx = idx / 3; int do_conf_cmd = 0; + int vermin, vermax; if (sigidx == 2) { sigidx = 0; do_conf_cmd = 1; } + if (idx < 4) { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = vermax = TLS1_3_VERSION; + +#ifdef OSSL_NO_USABLE_TLS1_3 + testresult = TEST_skip("TLS1.3 is disabled"); + goto end; +#endif + } else { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = vermax = DTLS1_3_VERSION; + +#ifdef OSSL_NO_USABLE_DTLS1_3 + testresult = TEST_skip("DTLS1.3 is disabled"); + goto end; +#endif + } + /* See create_cert_key() above */ expected_sigalg_name = (sigidx == 0) ? "xorhmacsig" : "xorhmacsha2sig"; @@ -11359,10 +13334,7 @@ static int test_pluggable_signature(int idx) || !TEST_true(create_cert_key(sigidx, certfilename, privkeyfilename))) goto end; - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), - TLS1_3_VERSION, - TLS1_3_VERSION, + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, NULL, NULL))) goto end; @@ -11441,12 +13413,29 @@ static int test_pluggable_signature(int idx) #endif #ifndef OPENSSL_NO_TLS1_2 + +#define CERT_TYPE_C "\x0" /* TLSEXT_cert_type_x509 */ +#define CERT_TYPE_S "\x2" /* TLSEXT_cert_type_rpk */ + +#ifndef OPENSSL_NO_CT +#define CB_ARG "callback arg" + +/* ARGSUSED */ +static int validation_cbk(const CT_POLICY_EVAL_CTX *ctx, + const STACK_OF(SCT) *scts, void *arg) +{ + return 1; +} +#endif + static int test_ssl_dup(void) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL, *client2ssl = NULL; int testresult = 0; BIO *rbio = NULL, *wbio = NULL; + unsigned char *ctype; + size_t ctype_len; if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), TLS_client_method(), @@ -11463,6 +13452,27 @@ static int test_ssl_dup(void) || !TEST_true(SSL_set_max_proto_version(clientssl, TLS1_2_VERSION))) goto end; + if (!TEST_true( + SSL_set1_client_cert_type(clientssl, + (const unsigned char *)CERT_TYPE_C, sizeof(CERT_TYPE_C) - 1))) + goto end; + + if (!TEST_true( + SSL_set1_server_cert_type(clientssl, + (const unsigned char *)CERT_TYPE_S, sizeof(CERT_TYPE_S) - 1))) + goto end; + +#ifndef OPENSSL_NO_CT + if (!TEST_true(SSL_set_ct_validation_callback(clientssl, validation_cbk, CB_ARG))) + goto end; +#endif + +#ifndef OPENSSL_NO_OCSP + if (!TEST_true( + SSL_set_tlsext_status_type(clientssl, TLSEXT_STATUSTYPE_ocsp))) + goto end; +#endif + client2ssl = SSL_dup(clientssl); rbio = SSL_get_rbio(clientssl); if (!TEST_ptr(rbio) @@ -11490,6 +13500,28 @@ static int test_ssl_dup(void) if (!TEST_true(create_ssl_connection(serverssl, client2ssl, SSL_ERROR_NONE))) goto end; + if (!TEST_true(SSL_get0_client_cert_type(client2ssl, &ctype, &ctype_len))) + goto end; + + if (!TEST_mem_eq(ctype, ctype_len, CERT_TYPE_C, sizeof(CERT_TYPE_C) - 1)) + goto end; + + if (!TEST_true(SSL_get0_server_cert_type(client2ssl, &ctype, &ctype_len))) + goto end; + + if (!TEST_mem_eq(ctype, ctype_len, CERT_TYPE_S, sizeof(CERT_TYPE_S) - 1)) + goto end; + +#ifndef OPENSSL_NO_CT + if (!TEST_true(SSL_ct_is_enabled(client2ssl))) + goto end; +#endif + +#ifndef OPENSSL_NO_OCSP + if (!TEST_long_eq(SSL_get_tlsext_status_type(client2ssl), TLSEXT_STATUSTYPE_ocsp)) + goto end; +#endif + SSL_free(clientssl); clientssl = SSL_dup(client2ssl); if (!TEST_ptr(clientssl) @@ -12191,28 +14223,50 @@ static int test_shared_ffdhe_group(int idx) #endif /* OPENSSL_NO_DH */ #endif /* OPENSSL_NO_TLS1_2 */ -#ifndef OSSL_NO_USABLE_TLS1_3 +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) /* - * Test that setting an SNI callback works with TLSv1.3. Specifically we check + * Test that setting an SNI callback works with (D)TLSv1.3. Specifically we check * that it works even without a certificate configured for the original * SSL_CTX + * Test 0: Test with TLS + * Test 1: Test with DTLS */ -static int test_sni_tls13(void) +static int test_sni_tls13(int idx) { SSL_CTX *cctx = NULL, *sctx = NULL, *sctx2 = NULL; SSL *clientssl = NULL, *serverssl = NULL; int testresult = 0; + const SSL_METHOD *smeth, *cmeth; + int vermin, vermax = 0; + int testdtls = idx >= 1; + + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_3_VERSION; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("DTLS 1.3 is disabled."); + goto end; +#endif + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_3_VERSION; +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("TLS 1.3 is disabled."); + goto end; +#endif + } /* Reset callback counter */ snicb = 0; /* Create an initial SSL_CTX with no certificate configured */ - sctx = SSL_CTX_new_ex(libctx, NULL, TLS_server_method()); + sctx = SSL_CTX_new_ex(libctx, NULL, smeth); if (!TEST_ptr(sctx)) goto end; /* Require TLSv1.3 as a minimum */ - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), TLS1_3_VERSION, 0, + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx2, &cctx, cert, privkey))) goto end; @@ -12250,27 +14304,61 @@ static int test_sni_tls13(void) * Test that the lifetime hint of a TLSv1.3 ticket is no more than 1 week * 0 = TLSv1.2 * 1 = TLSv1.3 + * 2 = DTLSv1.2 + * 3 = DTLSv1.3 */ static int test_ticket_lifetime(int idx) { SSL_CTX *cctx = NULL, *sctx = NULL; SSL *clientssl = NULL, *serverssl = NULL; int testresult = 0; - int version = TLS1_3_VERSION; + int version; + const SSL_METHOD *smeth, *cmeth; + int testdtls = idx >= 2; + + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + idx -= 2; + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + } #define ONE_WEEK_SEC (7 * 24 * 60 * 60) #define TWO_WEEK_SEC (2 * ONE_WEEK_SEC) if (idx == 0) { #ifdef OPENSSL_NO_TLS1_2 - return TEST_skip("TLS 1.2 is disabled."); -#else - version = TLS1_2_VERSION; + if (!testdtls) { + testresult = TEST_skip("TLS 1.2 is disabled."); + goto end; + } +#endif +#ifdef OPENSSL_NO_DTLS1_2 + if (testdtls) { + testresult = TEST_skip("DTLS 1.2 is disabled."); + goto end; + } #endif + version = testdtls ? DTLS1_2_VERSION : TLS1_2_VERSION; + } else { +#ifdef OSSL_NO_USABLE_TLS1_3 + if (!testdtls) { + testresult = TEST_skip("TLS 1.3 is disabled."); + goto end; + } +#endif +#ifdef OSSL_NO_USABLE_DTLS1_3 + if (testdtls) { + testresult = TEST_skip("DTLS 1.3 is disabled."); + goto end; + } +#endif + version = testdtls ? DTLS1_3_VERSION : TLS1_3_VERSION; } - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), version, version, + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, version, version, &sctx, &cctx, cert, privkey))) goto end; @@ -12719,8 +14807,12 @@ static int test_load_dhfile(void) #endif } -#ifndef OSSL_NO_USABLE_TLS1_3 -/* Test that read_ahead works across a key change */ +#if !defined(OSSL_NO_USABLE_TLS1_3) +/* + * Test that read_ahead works across a key change + * Test 0: Test with TLS + * Test 1: Test with DTLS + */ static int test_read_ahead_key_change(void) { SSL_CTX *cctx = NULL, *sctx = NULL; @@ -12783,7 +14875,9 @@ static int test_read_ahead_key_change(void) SSL_CTX_free(cctx); return testresult; } +#endif +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) static size_t record_pad_cb(SSL *s, int type, size_t len, void *arg) { int *called = arg; @@ -12820,6 +14914,7 @@ static size_t record_pad_cb(SSL *s, int type, size_t len, void *arg) * Test 3: Record block padding on the SSL * Test 4: Extended record block padding on the SSL_CTX * Test 5: Extended record block padding on the SSL + * Test >5: Tests are repeated for DTLS */ static int test_tls13_record_padding(int idx) { @@ -12831,9 +14926,30 @@ static int test_tls13_record_padding(int idx) char buf[80]; int i; int called = 0; + const SSL_METHOD *smeth, *cmeth; + int vermin, vermax = 0; + int testdtls = idx >= 6; - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), - TLS_client_method(), TLS1_3_VERSION, 0, + if (testdtls) { + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + vermin = DTLS1_3_VERSION; + idx -= 6; +#if defined(OSSL_NO_USABLE_DTLS1_3) + testresult = TEST_skip("No usable DTLS 1.3"); + goto end; +#endif + } else { + smeth = TLS_server_method(); + cmeth = TLS_client_method(); + vermin = TLS1_3_VERSION; +#if defined(OSSL_NO_USABLE_TLS1_3) + testresult = TEST_skip("No usable TLS 1.3"); + goto end; +#endif + } + + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, vermin, vermax, &sctx, &cctx, cert, privkey))) goto end; @@ -12920,7 +15036,9 @@ static int test_tls13_record_padding(int idx) SSL_CTX_free(cctx); return testresult; } +#endif /* defined(OSSL_NO_USABLE_TLS1_3) && defined(OSSL_NO_USABLE_TLS1_3) */ +#if !defined(OSSL_NO_USABLE_TLS1_3) static int un_ext_add_cb(SSL *s, unsigned int ext_type, unsigned int context, const unsigned char **out, size_t *outlen, X509 *x, size_t chainidx, int *al, void *add_arg) @@ -12989,6 +15107,9 @@ static int check_version_string(SSL *s, int version) break; case DTLS1_2_VERSION: verstr = "DTLSv1.2"; + break; + case DTLS1_3_VERSION: + verstr = "DTLSv1.3"; } return TEST_str_eq(verstr, SSL_get_version(s)); @@ -13397,6 +15518,70 @@ static int test_data_retry(void) return testresult; } +/* + * Test that a BIO returning 0 without a retry flag for a write with a positive + * length is not treated as a successful write. + */ +static int test_data_write_zero_no_retry(int tst) +{ + SSL_CTX *cctx = NULL, *sctx = NULL; + SSL *clientssl = NULL, *serverssl = NULL; + BIO *bzero = BIO_new(bio_s_no_retry_zero()); + const SSL_METHOD *smeth = TLS_server_method(); + const SSL_METHOD *cmeth = TLS_client_method(); + unsigned char inbuf[1] = { 0 }; + size_t written; + unsigned long errcode; + int err, min_version = 0, max_version = 0, testresult = 0; + + if (tst == 1) { +#if !defined(OPENSSL_NO_DTLS) && !defined(OPENSSL_NO_DTLS1_2) + smeth = DTLS_server_method(); + cmeth = DTLS_client_method(); + min_version = max_version = DTLS1_2_VERSION; +#else + BIO_free(bzero); + return TEST_skip("DTLS 1.2 not supported"); +#endif + } + + if (!TEST_ptr(bzero)) + goto end; + + if (!TEST_true(create_ssl_ctx_pair(libctx, smeth, cmeth, min_version, + max_version, &sctx, &cctx, cert, privkey))) + goto end; + + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, + NULL))) + goto end; + + if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) + goto end; + + SSL_set0_wbio(clientssl, bzero); + bzero = NULL; + + ERR_clear_error(); + if (!TEST_false(SSL_write_ex(clientssl, inbuf, sizeof(inbuf), &written))) + goto end; + + err = SSL_get_error(clientssl, 0); + errcode = ERR_get_error(); + if (!TEST_int_eq(err, SSL_ERROR_SYSCALL) + || !TEST_ulong_eq(errcode, 0)) + goto end; + + testresult = 1; +end: + SSL_free(serverssl); + SSL_free(clientssl); + SSL_CTX_free(sctx); + SSL_CTX_free(cctx); + BIO_free_all(bzero); + return testresult; +} + struct resume_servername_cb_data { int i; SSL_CTX *cctx; @@ -14721,8 +16906,22 @@ static int test_ssl_trace(void) * PACKET functions to confirm that GREASE values (matching 0x?A?A) are * present in the expected fields. */ -static unsigned char *grease_ch_buf; -static size_t grease_ch_len; +#define MAX_GREASE_CLIENT_HELLOS 2 + +typedef struct grease_capture_st { + unsigned char *buf[MAX_GREASE_CLIENT_HELLOS]; + size_t len[MAX_GREASE_CLIENT_HELLOS]; + size_t count; +} GREASE_CAPTURE; + +static void grease_capture_reset(GREASE_CAPTURE *capture) +{ + size_t i; + + for (i = 0; i < OSSL_NELEM(capture->buf); i++) + OPENSSL_free(capture->buf[i]); + memset(capture, 0, sizeof(*capture)); +} static int is_grease(unsigned int v) { @@ -14732,6 +16931,7 @@ static int is_grease(unsigned int v) static void grease_msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) { + GREASE_CAPTURE *capture = arg; const unsigned char *p = buf; /* @@ -14744,12 +16944,14 @@ static void grease_msg_cb(int write_p, int version, int content_type, || p[0] != SSL3_MT_CLIENT_HELLO) return; - /* Only capture the first ClientHello (not HRR retry) */ - if (grease_ch_buf != NULL) + if (capture == NULL || capture->count >= OSSL_NELEM(capture->buf)) return; - grease_ch_buf = OPENSSL_memdup(buf, len); - grease_ch_len = len; + capture->buf[capture->count] = OPENSSL_memdup(buf, len); + if (capture->buf[capture->count] == NULL) + return; + capture->len[capture->count] = len; + capture->count++; } /* @@ -14758,11 +16960,13 @@ static void grease_msg_cb(int write_p, int version, int content_type, * groups, key shares, and signature algorithms. * Returns 1 on success, 0 on failure. */ -static int check_grease_in_client_hello(void) +static int check_grease_in_client_hello(const unsigned char *buf, size_t len, + int expect_grease_keyshare) { PACKET pkt, ciphers, session, compression, exts, ext_data; PACKET inner; unsigned int ext_type = 0, val = 0; + size_t keyshare_count = 0; int found_grease_cipher = 0; int found_grease_ext = 0; int found_grease_group = 0; @@ -14778,9 +16982,8 @@ static int check_grease_in_client_hello(void) memset(&ext_data, 0, sizeof(ext_data)); memset(&inner, 0, sizeof(inner)); - if (!TEST_ptr(grease_ch_buf) - || !TEST_true(PACKET_buf_init(&pkt, grease_ch_buf, - grease_ch_len)) + if (!TEST_ptr(buf) + || !TEST_true(PACKET_buf_init(&pkt, buf, len)) /* Skip handshake message header */ || !TEST_true(PACKET_forward(&pkt, SSL3_HM_HEADER_LENGTH)) /* Skip client_version + random */ @@ -14853,6 +17056,7 @@ static int check_grease_in_client_hello(void) || !TEST_true(PACKET_get_length_prefixed_2( &inner, &ks_entry))) return 0; + keyshare_count++; if (is_grease(val)) found_grease_kshare = 1; } @@ -14880,10 +17084,12 @@ static int check_grease_in_client_hello(void) return 0; if (!TEST_true(found_grease_group)) return 0; - if (!TEST_true(found_grease_kshare)) + if (!TEST_int_eq(found_grease_kshare, expect_grease_keyshare)) return 0; if (!TEST_true(found_grease_sigalg)) return 0; + if (!expect_grease_keyshare && !TEST_size_t_eq(keyshare_count, 1)) + return 0; return 1; } @@ -14892,11 +17098,9 @@ static int test_grease(void) { SSL_CTX *sctx = NULL, *cctx = NULL; SSL *serverssl = NULL, *clientssl = NULL; + GREASE_CAPTURE capture = { 0 }; int testresult = 0; - grease_ch_buf = NULL; - grease_ch_len = 0; - if (!TEST_true(create_ssl_ctx_pair(libctx, TLS_server_method(), TLS_client_method(), TLS1_3_VERSION, TLS1_3_VERSION, @@ -14909,23 +17113,65 @@ static int test_grease(void) &clientssl, NULL, NULL))) goto end; + /* Force the server to request a new key share. */ +#if defined(OPENSSL_NO_EC) + if (!TEST_true(SSL_set1_groups_list(serverssl, "ffdhe3072"))) + goto end; +#else + if (!TEST_true(SSL_set1_groups_list(serverssl, "P-384"))) + goto end; +#endif + SSL_set_msg_callback(clientssl, grease_msg_cb); + SSL_set_msg_callback_arg(clientssl, &capture); - /* A full handshake should succeed - server must tolerate GREASE */ + /* A full handshake should succeed - server must tolerate GREASE. */ if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE))) goto end; - /* Now verify the captured ClientHello contains GREASE values */ - if (!TEST_true(check_grease_in_client_hello())) + if (!TEST_size_t_eq(capture.count, 2) + || !TEST_true(check_grease_in_client_hello(capture.buf[0], + capture.len[0], 1)) + || !TEST_true(check_grease_in_client_hello(capture.buf[1], + capture.len[1], 0))) + goto end; + + shutdown_ssl_connection(serverssl, clientssl); + serverssl = clientssl = NULL; + grease_capture_reset(&capture); + + /* A cookie-only retry must retain the original GREASE key share. */ + SSL_CTX_clear_options(cctx, SSL_OP_ENABLE_MIDDLEBOX_COMPAT); + SSL_CTX_set_stateless_cookie_generate_cb(sctx, + generate_stateless_cookie_callback); + SSL_CTX_set_stateless_cookie_verify_cb(sctx, + verify_stateless_cookie_callback); + if (!TEST_true(create_ssl_objects(sctx, cctx, &serverssl, + &clientssl, NULL, NULL))) + goto end; + + SSL_set_msg_callback(clientssl, grease_msg_cb); + SSL_set_msg_callback_arg(clientssl, &capture); + if (!TEST_false(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_WANT_READ)) + || !TEST_int_eq(SSL_stateless(serverssl), 0) + || !TEST_false(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_WANT_READ)) + || !TEST_int_eq(SSL_stateless(serverssl), 1) + || !TEST_true(create_ssl_connection(serverssl, clientssl, + SSL_ERROR_NONE)) + || !TEST_size_t_eq(capture.count, 2) + || !TEST_true(check_grease_in_client_hello(capture.buf[0], + capture.len[0], 1)) + || !TEST_true(check_grease_in_client_hello(capture.buf[1], + capture.len[1], 1))) goto end; testresult = 1; end: - OPENSSL_free(grease_ch_buf); - grease_ch_buf = NULL; - grease_ch_len = 0; + grease_capture_reset(&capture); SSL_free(serverssl); SSL_free(clientssl); SSL_CTX_free(sctx); @@ -15273,11 +17519,11 @@ int setup_tests(void) ADD_TEST(test_session_with_both_cache); ADD_TEST(test_remove_session_cb_not_under_lock); ADD_TEST(test_session_wo_ca_names); -#ifndef OSSL_NO_USABLE_TLS1_3 - ADD_ALL_TESTS(test_stateful_tickets, 3); - ADD_ALL_TESTS(test_stateless_tickets, 3); - ADD_TEST(test_psk_tickets); - ADD_ALL_TESTS(test_extra_tickets, 6); +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) + ADD_ALL_TESTS(test_stateful_tickets, 6); + ADD_ALL_TESTS(test_stateless_tickets, 6); + ADD_ALL_TESTS(test_psk_tickets, 2); + ADD_ALL_TESTS(test_extra_tickets, 12); #endif ADD_ALL_TESTS(test_ssl_set_bio, TOTAL_SSL_SET_BIO_TESTS); ADD_TEST(test_ssl_bio_pop_next_bio); @@ -15289,10 +17535,15 @@ int setup_tests(void) ADD_ALL_TESTS(test_set_sigalgs, OSSL_NELEM(testsigalgs) * 2); ADD_TEST(test_keylog); #endif -#ifndef OSSL_NO_USABLE_TLS1_3 - ADD_TEST(test_keylog_no_master_key); +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) + ADD_ALL_TESTS(test_keylog_no_master_key, 2); #endif ADD_TEST(test_client_cert_verify_cb); + ADD_TEST(test_server_cert_verify_cb); + ADD_TEST(test_server_rpk_verify_cb); +#ifndef OPENSSL_NO_TLS1_2 + ADD_ALL_TESTS(test_malformed_client_cert_tail, 2); +#endif ADD_TEST(test_ssl_build_cert_chain); ADD_TEST(test_ssl_ctx_build_cert_chain); #ifndef OPENSSL_NO_TLS1_2 @@ -15300,61 +17551,83 @@ int setup_tests(void) ADD_TEST(test_no_ems); ADD_TEST(test_ccs_change_cipher); #endif -#ifndef OSSL_NO_USABLE_TLS1_3 - ADD_ALL_TESTS(test_early_data_read_write, 6); +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) + ADD_ALL_TESTS(test_early_data_read_write, 12); /* * We don't do replay tests for external PSK. Replay protection isn't used * in that scenario. */ - ADD_ALL_TESTS(test_early_data_replay, 2); - ADD_ALL_TESTS(test_early_data_skip, OSSL_NELEM(ciphersuites) * 3); - ADD_ALL_TESTS(test_early_data_skip_hrr, OSSL_NELEM(ciphersuites) * 3); - ADD_ALL_TESTS(test_early_data_skip_hrr_fail, OSSL_NELEM(ciphersuites) * 3); - ADD_ALL_TESTS(test_early_data_skip_abort, OSSL_NELEM(ciphersuites) * 3); - ADD_ALL_TESTS(test_early_data_not_sent, 3); - ADD_ALL_TESTS(test_early_data_psk, 8); - ADD_ALL_TESTS(test_early_data_psk_with_all_ciphers, 7); - ADD_ALL_TESTS(test_early_data_not_expected, 3); -#ifndef OPENSSL_NO_TLS1_2 - ADD_ALL_TESTS(test_early_data_tls1_2, 3); + ADD_ALL_TESTS(test_early_data_replay, 4); + ADD_ALL_TESTS(test_early_data_skip, 2 * OSSL_NELEM(ciphersuites) * 3); + ADD_ALL_TESTS(test_early_data_skip_hrr, 2 * OSSL_NELEM(ciphersuites) * 3); + ADD_ALL_TESTS(test_early_data_skip_hrr_fail, 2 * OSSL_NELEM(ciphersuites) * 3); + ADD_ALL_TESTS(test_early_data_skip_abort, 2 * OSSL_NELEM(ciphersuites) * 3); + ADD_ALL_TESTS(test_early_data_not_sent, 6); + ADD_ALL_TESTS(test_early_data_psk, 16); + ADD_ALL_TESTS(test_early_data_psk_with_all_ciphers, 14); + ADD_ALL_TESTS(test_early_data_not_expected, 6); +#if !defined(OSSL_NO_USABLE_TLS1_3) + ADD_TEST(test_early_data_psk_cipher_mismatch); +#if !defined(OPENSSL_NO_CHACHA) && !defined(OPENSSL_NO_POLY1305) + ADD_TEST(test_early_data_psk_cipher_off_wire); #endif +#ifndef OPENSSL_NO_EC + ADD_TEST(test_hrr_psk_no_ch2_add); #endif -#ifndef OSSL_NO_USABLE_TLS1_3 - ADD_ALL_TESTS(test_set_ciphersuite, 10); - ADD_TEST(test_ciphersuite_change); - ADD_ALL_TESTS(test_tls13_ciphersuite, 4); +#endif +#endif /* !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) */ +#if !defined(OSSL_NO_USABLE_TLS1_3) && !defined(OPENSSL_NO_TLS1_2) + ADD_ALL_TESTS(test_early_data_tls1_2, 3); +#endif +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) + ADD_ALL_TESTS(test_set_ciphersuite, 20); + ADD_ALL_TESTS(test_ciphersuite_change, 2); + ADD_ALL_TESTS(test_tls13_ciphersuite, 8); #ifdef OPENSSL_NO_PSK ADD_ALL_TESTS(test_tls13_psk, 1); #else - ADD_ALL_TESTS(test_tls13_psk, 4); + ADD_ALL_TESTS(test_tls13_psk, 8); #endif /* OPENSSL_NO_PSK */ -#ifndef OSSL_NO_USABLE_TLS1_3 - ADD_ALL_TESTS(test_tls13_no_dhe_kex, 8); -#endif /* OSSL_NO_USABLE_TLS1_3 */ + ADD_ALL_TESTS(test_tls13_no_dhe_kex, 16); +#endif /* !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) */ +#if !defined(OSSL_NO_USABLE_TLS1_3) +#ifdef OPENSSL_NO_PSK + ADD_ALL_TESTS(test_tls13_psk_client_sid_ctx, 1); +#else + ADD_ALL_TESTS(test_tls13_psk_client_sid_ctx, 2); +#endif /* OPENSSL_NO_PSK */ + ADD_TEST(test_tls13_psk_verify_peer_no_sid_ctx); + ADD_TEST(test_tls13_psk_verify_peer_no_ticket); +#endif /* !defined(OSSL_NO_USABLE_TLS1_3) */ +#if !defined(OSSL_NO_USABLE_TLS1_3) #ifndef OPENSSL_NO_TLS1_2 /* Test with both TLSv1.3 and 1.2 versions */ - ADD_ALL_TESTS(test_key_exchange, 23); + ADD_ALL_TESTS(test_key_exchange, 26); #if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_DH) ADD_ALL_TESTS(test_negotiated_group, 4 * (OSSL_NELEM(ecdhe_kexch_groups) + OSSL_NELEM(ffdhe_kexch_groups))); #endif #else /* Test with only TLSv1.3 versions */ - ADD_ALL_TESTS(test_key_exchange, 20); + ADD_ALL_TESTS(test_key_exchange, 23); #endif ADD_ALL_TESTS(test_custom_exts, 6); - ADD_TEST(test_stateless); ADD_TEST(test_pha_key_update); #else ADD_ALL_TESTS(test_custom_exts, 3); #endif - ADD_ALL_TESTS(test_export_key_mat, 6); #ifndef OSSL_NO_USABLE_TLS1_3 - ADD_ALL_TESTS(test_export_key_mat_early, 3); - ADD_TEST(test_key_update); - ADD_ALL_TESTS(test_key_update_peer_in_write, 2); - ADD_ALL_TESTS(test_key_update_peer_in_read, 2); - ADD_ALL_TESTS(test_key_update_local_in_write, 2); + ADD_TEST(test_stateless); +#endif + ADD_ALL_TESTS(test_export_key_mat, 6); +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) + ADD_ALL_TESTS(test_export_key_mat_early, 6); + ADD_ALL_TESTS(test_key_update, 2); + ADD_ALL_TESTS(test_key_update_peer_in_write, 4); + ADD_ALL_TESTS(test_key_update_peer_in_read, 4); + ADD_ALL_TESTS(test_key_update_local_in_write, 4); +#endif +#if !defined(OSSL_NO_USABLE_TLS1_3) ADD_ALL_TESTS(test_key_update_local_in_read, 2); #endif ADD_ALL_TESTS(test_ssl_clear, 8); @@ -15387,13 +17660,14 @@ int setup_tests(void) #if (!defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)) || !defined(OPENSSL_NO_ML_KEM) ADD_TEST(test_configuration_of_groups); #endif -#if !defined(OPENSSL_NO_EC) \ - && (!defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2)) - ADD_ALL_TESTS(test_sigalgs_available, 6); +#if !defined(OPENSSL_NO_EC) \ + && (!defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) \ + || !defined(OSSL_NO_USABLE_DTLS1_3) || !defined(OPENSSL_NO_DTLS1_2)) + ADD_ALL_TESTS(test_sigalgs_available, 12); #endif -#ifndef OPENSSL_NO_TLS1_3 - ADD_ALL_TESTS(test_pluggable_group, 2); - ADD_ALL_TESTS(test_pluggable_signature, 6); +#if !defined(OPENSSL_NO_TLS1_3) || !defined(OPENSSL_NO_DTLS1_3) + ADD_ALL_TESTS(test_pluggable_group, 4); + ADD_ALL_TESTS(test_pluggable_signature, 12); #endif #ifndef OPENSSL_NO_TLS1_2 ADD_TEST(test_ssl_dup); @@ -15405,9 +17679,9 @@ int setup_tests(void) ADD_ALL_TESTS(test_shared_ffdhe_group, 5); #endif #endif -#ifndef OSSL_NO_USABLE_TLS1_3 - ADD_TEST(test_sni_tls13); - ADD_ALL_TESTS(test_ticket_lifetime, 2); +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) + ADD_ALL_TESTS(test_sni_tls13, 2); + ADD_ALL_TESTS(test_ticket_lifetime, 4); #endif ADD_TEST(test_inherit_verify_param); ADD_TEST(test_set_alpn); @@ -15418,23 +17692,28 @@ int setup_tests(void) ADD_TEST(test_set_verify_cert_store_ssl_ctx); ADD_TEST(test_set_verify_cert_store_ssl); ADD_ALL_TESTS(test_session_timeout, 1); -#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) - ADD_ALL_TESTS(test_session_cache_overflow, 4); +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) \ + || !defined(OSSL_NO_USABLE_DTLS1_3) || !defined(OPENSSL_NO_DTLS1_2) + ADD_ALL_TESTS(test_session_cache_overflow, 8); #endif ADD_TEST(test_load_dhfile); +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OSSL_NO_USABLE_DTLS1_3) + ADD_ALL_TESTS(test_tls13_record_padding, 12); +#endif #ifndef OSSL_NO_USABLE_TLS1_3 - ADD_TEST(test_read_ahead_key_change); - ADD_ALL_TESTS(test_tls13_record_padding, 6); ADD_TEST(test_tls13_unknown_extension); + ADD_TEST(test_read_ahead_key_change); #endif -#if !defined(OPENSSL_NO_TLS1_2) && !defined(OSSL_NO_USABLE_TLS1_3) - ADD_ALL_TESTS(test_serverinfo_custom, 4); +#if (!defined(OPENSSL_NO_TLS1_2) && !defined(OSSL_NO_USABLE_TLS1_3)) \ + || (!defined(OPENSSL_NO_DTLS1_2) && !defined(OSSL_NO_USABLE_DTLS1_3)) + ADD_ALL_TESTS(test_serverinfo_custom, 8); #endif ADD_ALL_TESTS(test_version, 6); ADD_TEST(test_ssl_ctx_is_server); ADD_TEST(test_rstate_string); ADD_ALL_TESTS(test_handshake_retry, 16); ADD_TEST(test_data_retry); + ADD_ALL_TESTS(test_data_write_zero_no_retry, 2); ADD_ALL_TESTS(test_multi_resume, 5); ADD_ALL_TESTS(test_select_next_proto, OSSL_NELEM(next_proto_tests)); #if !defined(OPENSSL_NO_TLS1_2) && !defined(OPENSSL_NO_NEXTPROTONEG) @@ -15486,6 +17765,7 @@ void cleanup_tests(void) bio_s_mempacket_test_free(); bio_s_always_retry_free(); bio_s_maybe_retry_free(); + bio_s_no_retry_zero_free(); OSSL_PROVIDER_unload(defctxnull); OSSL_LIB_CTX_free(libctx); } diff --git a/test/sslbuffertest.c b/test/sslbuffertest.c index 13b6f6b40401f..ebaf97a7a19c0 100644 --- a/test/sslbuffertest.c +++ b/test/sslbuffertest.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/test/statem_clnt_construct_test.c b/test/statem_clnt_construct_test.c index 459c7ffe3e360..da2fd39f88318 100644 --- a/test/statem_clnt_construct_test.c +++ b/test/statem_clnt_construct_test.c @@ -8,13 +8,16 @@ */ /* - * Direct tests for tls_construct_client_hello(): prime a client SSL_CONNECTION - * enough to call the construct function without a full handshake, then check - * the result structurally and by round-tripping it through the server parser. - * OOM branches are covered with mfail tests. + * Direct tests for the client state-machine construct functions in + * statem_clnt.c: prime a client SSL_CONNECTION enough to call a construct + * function without a full handshake, then check the result structurally and, + * where useful, by round-tripping it through the server parser. OOM branches + * are covered with mfail tests. */ +#include #include +#include #ifndef OPENSSL_NO_ECH #include #include @@ -41,8 +44,8 @@ #endif /* - * Helpers down to prime_ssl() are generic and reusable by tests for any - * statem_clnt construct function; the ClientHello-specific code follows. + * Helpers down to finish_msg() are generic and reusable by tests for any + * statem_clnt construct function; the per-message code follows. */ /* Connection configuration shared by the construct tests. */ @@ -88,10 +91,11 @@ static SSL_CTX *new_ctx(const CH_CONFIG *cfg, const SSL_METHOD *meth) /* * Set up the init_buf and handshake state the write state machine would have * established before calling a construct function. For the client a WPACKET - * with the handshake header is emitted into init_buf. initbuf_len of 0 means - * full size; a small value exercises WPACKET failures. + * with the handshake header for message type mt is emitted into init_buf. + * initbuf_len of 0 means full size; a small value exercises WPACKET failures. */ -static int prime_ssl(SSL *ssl, int is_client, size_t initbuf_len, WPACKET *pkt) +static int prime_ssl(SSL *ssl, int is_client, size_t initbuf_len, WPACKET *pkt, + int mt) { SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL(ssl); @@ -115,26 +119,20 @@ static int prime_ssl(SSL *ssl, int is_client, size_t initbuf_len, WPACKET *pkt) if (pkt != NULL && (!TEST_true(WPACKET_init(pkt, s->init_buf)) - || !TEST_true(ssl_set_handshake_header(s, pkt, - SSL3_MT_CLIENT_HELLO)))) + || !TEST_true(ssl_set_handshake_header(s, pkt, mt)))) return 0; return 1; } -/* - * =========================================================================== - * tls_construct_client_hello - * =========================================================================== - */ - -/* Finalize the constructed message and return its bytes (header + body). */ -static int finish_ch(SSL *ssl, WPACKET *pkt, unsigned char **msg, +/* Finalize a constructed message and return its bytes (header + body). */ +static int finish_msg(SSL *ssl, WPACKET *pkt, int mt, unsigned char **msg, size_t *msglen) { SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL(ssl); - if (!TEST_true(ssl_close_construct_packet(s, pkt, SSL3_MT_CLIENT_HELLO)) + if (!TEST_ptr(s) + || !TEST_true(ssl_close_construct_packet(s, pkt, mt)) || !TEST_true(WPACKET_get_total_written(pkt, msglen)) || !TEST_true(WPACKET_finish(pkt))) return 0; @@ -143,6 +141,12 @@ static int finish_ch(SSL *ssl, WPACKET *pkt, unsigned char **msg, return 1; } +/* + * =========================================================================== + * tls_construct_client_hello + * =========================================================================== + */ + /* Recover the session_id length, the main branching difference in construct. */ static int get_ch_sessid_len(const CH_CONFIG *cfg, const unsigned char *msg, size_t msglen, size_t *sidlen) @@ -190,7 +194,7 @@ static int roundtrip_process_ch(const CH_CONFIG *cfg, const unsigned char *msg, || !TEST_ptr(ssl = SSL_new(sctx))) goto err; - if (!prime_ssl(ssl, 0, 0, NULL)) + if (!prime_ssl(ssl, 0, 0, NULL, SSL3_MT_CLIENT_HELLO)) goto err; s = SSL_CONNECTION_FROM_SSL(ssl); @@ -233,7 +237,7 @@ static int do_construct_ch(const CH_CONFIG *cfg, if (cfg->clear_midbox) SSL_clear_options(ssl, SSL_OP_ENABLE_MIDDLEBOX_COMPAT); - if (!prime_ssl(ssl, 1, 0, &pkt)) + if (!prime_ssl(ssl, 1, 0, &pkt, SSL3_MT_CLIENT_HELLO)) goto err; s = SSL_CONNECTION_FROM_SSL(ssl); @@ -246,7 +250,7 @@ static int do_construct_ch(const CH_CONFIG *cfg, WPACKET_cleanup(&pkt); goto err; } - if (!finish_ch(ssl, &pkt, &msg, &msglen)) + if (!finish_msg(ssl, &pkt, SSL3_MT_CLIENT_HELLO, &msg, &msglen)) goto err; if (!get_ch_sessid_len(cfg, msg, msglen, &sidlen) @@ -294,7 +298,7 @@ static int do_construct_ch_expect_fail(const CH_CONFIG *cfg, (void)r2; } - if (!prime_ssl(ssl, 1, initbuf_len, &pkt)) + if (!prime_ssl(ssl, 1, initbuf_len, &pkt, SSL3_MT_CLIENT_HELLO)) goto err; have_pkt = 1; s = SSL_CONNECTION_FROM_SSL(ssl); @@ -534,7 +538,7 @@ static int mfail_construct_ch_common(const CH_CONFIG *cfg, if (cfg->clear_midbox) SSL_clear_options(ssl, SSL_OP_ENABLE_MIDDLEBOX_COMPAT); - if (!prime_ssl(ssl, 1, 0, &pkt)) + if (!prime_ssl(ssl, 1, 0, &pkt, SSL3_MT_CLIENT_HELLO)) goto err; s = SSL_CONNECTION_FROM_SSL(ssl); @@ -625,14 +629,14 @@ static int test_construct_ch_ech(void) if (!TEST_ptr(cctx = new_ctx(&cfg, client_method(&cfg))) || !TEST_ptr(cssl = SSL_new(cctx)) || !TEST_true(SSL_set1_echstore(cssl, es)) - || !prime_ssl(cssl, 1, 0, &pkt)) + || !prime_ssl(cssl, 1, 0, &pkt, SSL3_MT_CLIENT_HELLO)) goto err; cs = SSL_CONNECTION_FROM_SSL(cssl); if (!TEST_int_eq(tls_construct_client_hello(cs, &pkt), CON_FUNC_SUCCESS)) { WPACKET_cleanup(&pkt); goto err; } - if (!finish_ch(cssl, &pkt, &msg, &msglen) + if (!finish_msg(cssl, &pkt, SSL3_MT_CLIENT_HELLO, &msg, &msglen) || !get_ch_sessid_len(&cfg, msg, msglen, &sidlen) || !TEST_size_t_eq(sidlen, SSL_MAX_SSL_SESSION_ID_LENGTH)) goto err; @@ -641,7 +645,7 @@ static int test_construct_ch_ech(void) if (!TEST_ptr(sctx = new_ctx(&cfg, server_method(&cfg))) || !TEST_ptr(sssl = SSL_new(sctx)) || !TEST_true(SSL_set1_echstore(sssl, es)) - || !prime_ssl(sssl, 0, 0, NULL)) + || !prime_ssl(sssl, 0, 0, NULL, SSL3_MT_CLIENT_HELLO)) goto err; ss = SSL_CONNECTION_FROM_SSL(sssl); if (!TEST_true(PACKET_buf_init(&rpkt, msg + hdr_len(&cfg), @@ -678,6 +682,848 @@ static int mfail_construct_ch_ech(void) } #endif /* OSSL_NO_USABLE_ECH */ +/* + * =========================================================================== + * tls_construct_end_of_early_data + * =========================================================================== + */ + +#ifndef OSSL_NO_USABLE_TLS1_3 +/* + * EndOfEarlyData carries no body and only advances early_data_state; it is + * valid only from the WRITE_RETRY/FINISHED_WRITING states. + */ +static int do_construct_eoed(int state, CON_FUNC_RETURN expect) +{ + CH_CONFIG cfg = { 0, TLS1_3_VERSION, TLS1_3_VERSION, 0 }; + SSL_CTX *cctx = NULL; + SSL *ssl = NULL; + SSL_CONNECTION *s; + WPACKET pkt; + unsigned char *msg = NULL; + size_t msglen = 0; + int have_pkt = 0; + int ret = 0; + + if (!TEST_ptr(cctx = new_ctx(&cfg, client_method(&cfg))) + || !TEST_ptr(ssl = SSL_new(cctx)) + || !prime_ssl(ssl, 1, 0, &pkt, SSL3_MT_END_OF_EARLY_DATA)) + goto err; + have_pkt = 1; + s = SSL_CONNECTION_FROM_SSL(ssl); + s->early_data_state = state; + + if (!TEST_int_eq(tls_construct_end_of_early_data(s, &pkt), expect)) + goto err; + + if (expect == CON_FUNC_SUCCESS) { + /* State advances and the body is empty (only the header is written). */ + if (!TEST_int_eq(s->early_data_state, SSL_EARLY_DATA_FINISHED_WRITING) + || !finish_msg(ssl, &pkt, SSL3_MT_END_OF_EARLY_DATA, &msg, &msglen)) + goto err; + have_pkt = 0; + if (!TEST_size_t_eq(msglen, hdr_len(&cfg))) + goto err; + } + + ret = 1; +err: + if (have_pkt) + WPACKET_cleanup(&pkt); + SSL_free(ssl); + SSL_CTX_free(cctx); + return ret; +} + +static int test_construct_eoed(void) +{ + return do_construct_eoed(SSL_EARLY_DATA_WRITE_RETRY, CON_FUNC_SUCCESS); +} + +static int test_construct_eoed_bad_state(void) +{ + /* Called from an unexpected state: CON_FUNC_ERROR, nothing written. */ + return do_construct_eoed(SSL_EARLY_DATA_NONE, CON_FUNC_ERROR); +} +#endif /* OSSL_NO_USABLE_TLS1_3 */ + +/* + * =========================================================================== + * tls_construct_client_certificate + * =========================================================================== + */ + +#if !defined(OSSL_NO_USABLE_TLS1_3) || !defined(OPENSSL_NO_TLS1_2) +/* Self-signed client cert + signing-capable key; regenerate with the + * statem_clnt_construct_test ossl-test-tools subcommand. */ +static const char *kClientCert[] = { + "-----BEGIN CERTIFICATE-----\n", + "MIIDvzCCAqegAwIBAgICAQAwDQYJKoZIhvcNAQELBQAwgYExCzAJBgNVBAYTAlVT\n", + "MRAwDgYDVQQIDAdXeW9taW5nMREwDwYDVQQHDAhDaGV5ZW5uZTEVMBMGA1UECgwM\n", + "T3BlblNTTCBUZXN0MRQwEgYDVQQLDAtzdGF0ZW1fY2xudDEgMB4GA1UEAwwXc3Rh\n", + "dGVtX2NsbnQgdGVzdCBjbGllbnQwHhcNMjYwMTAxMDAwMDAwWhcNNDYwMTAxMDAw\n", + "MDAwWjCBgTELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB1d5b21pbmcxETAPBgNVBAcM\n", + "CENoZXllbm5lMRUwEwYDVQQKDAxPcGVuU1NMIFRlc3QxFDASBgNVBAsMC3N0YXRl\n", + "bV9jbG50MSAwHgYDVQQDDBdzdGF0ZW1fY2xudCB0ZXN0IGNsaWVudDCCASIwDQYJ\n", + "KoZIhvcNAQEBBQADggEPADCCAQoCggEBAMnUvJvluB2ZUoQNQlW4wgv0qceITB5X\n", + "cHQe60H1CMTapaRi32dpwEzoEMnMjULcrZshcTAkdke6J1ubJ6qviGp7n1kVYH18\n", + "rGYYk6VT+GPb/SZnjMX3+e5WEpH+53UEGVvBPHl/med0AzklOOf/0hDlMFzMBejA\n", + "z+T++88QIT19BoIwfilcMDZxE0uXbq3QLpugADGd93zLSCwM1vxd9Vi0EwyMpy7Q\n", + "Ot9eIR/+ML0HESXZ1AvVcLjvuhqm+xkNiR9qil68zqgJk+dUpK5hCpLBi7cfBpk7\n", + "jLultF09up6G3Y5KiXd8wS9upwJZXA9+9OKHTf05w4xWAA/kpp9gt0MCAwEAAaM/\n", + "MD0wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFM9Nespo\n", + "NSyfQO8jPjRl4JfH5kOsMA0GCSqGSIb3DQEBCwUAA4IBAQBtTgy5ePCHR+iu3Ign\n", + "wlJzL5+zkWOkQsbAzJsbWrvzqwx2shXr1adM7OJy7tCkmDgwHsXjTTO2qAZrlmYQ\n", + "ktGA/UAtttIqgiiYcyGdrZas2vXUWLUps5YzMm4YdY8YNTvqQl3LCziUhO5YREDP\n", + "teXy4FF6ijGUDe84CYsmKvtbIn34LtZ2Vo3gsiRHvdiaxHavH30UqED9k4NjKnFx\n", + "XM6eMw+bs0Yl1vi/Dz5tHPRaAnsGvnKcEveSAdAoSWmodw8n8W5t8ZvPoPCoKz88\n", + "DOGzUvLma/kVL+3HLiSn6XFiQ2NLfO9ceUgDsSzcRo76XZHJnfGsK6Iewgje3NrB\n", + "WnZs\n", + "-----END CERTIFICATE-----\n", + NULL +}; + +static const char *kClientKey[] = { + "-----BEGIN RSA PRIVATE KEY-----\n", + "MIIEowIBAAKCAQEAydS8m+W4HZlShA1CVbjCC/Spx4hMHldwdB7rQfUIxNqlpGLf\n", + "Z2nATOgQycyNQtytmyFxMCR2R7onW5snqq+IanufWRVgfXysZhiTpVP4Y9v9JmeM\n", + "xff57lYSkf7ndQQZW8E8eX+Z53QDOSU45//SEOUwXMwF6MDP5P77zxAhPX0GgjB+\n", + "KVwwNnETS5durdAum6AAMZ33fMtILAzW/F31WLQTDIynLtA6314hH/4wvQcRJdnU\n", + "C9VwuO+6Gqb7GQ2JH2qKXrzOqAmT51SkrmEKksGLtx8GmTuMu6W0XT26nobdjkqJ\n", + "d3zBL26nAllcD3704odN/TnDjFYAD+Smn2C3QwIDAQABAoIBAGAjkzIJczG6MmmP\n", + "bU0q5FfQk7zlaii7yuetQK/a2fH3GpbauALpBz46/qA5bQJv3sw52lIt1B+nhw7m\n", + "MbdmxKrANy+2dI9hvzckttO2U2exxvyvr4kvbWB/pHnhu3vsV23y9m0DgJqVEuH6\n", + "Hoi4PWZp3aceUiRED+NLKERCMSs5lPSSWR7sUkzHku4x5fZXZppcQW4leo+Z/kNC\n", + "I36CGF4pI9FJXwcuRhbv3NsFMVl/Ng4hWgzgu7zwJEPw2OSKyhdwHV53qGQWyMnJ\n", + "7SawyQfyspKlMZnjWxplFZ5tgaV6O63zZZPEOC2mZNeiZKWC9Lut/wyriLs+W4w7\n", + "9BBX3q0CgYEA94sgemr3rGY2R+9kiPV/TC08IUflMJ7kt0epDDRnojWqobinJzQG\n", + "Nq25i5vZHbjn9g7l2hNmOcHVZZmCYZitmjwWr4ibthftU7+H6WkvcBvH6b6EmHQm\n", + "5IGtOxYPmtf2Ghnj1uQmsBe9vRYcqx7B8/anqRi3lQhebykkII0MLR8CgYEA0LnV\n", + "vXaFAwLOta4Kn43mXC6sVRRMt316d70zRpVRsSQ64TdhtwArmKq3RUmLH2r3ysRL\n", + "6+mxEGJriL7JERH3Jlm0YGsUUQvQWxCddccuTQRc16+UVt7+xzfhzJZNTD4+t0aA\n", + "jsVLpPQHzXI8Yqzh1p83oC4XV4hCYZNLlfleTV0CgYBWIG/yZ9k4gG+OY7pk9JWP\n", + "2YU8Rxl06zPEmQg2GN2d0HJHxklSGIW47ITMEDNgZf8+2zwZvfopSkmHCfwVHNv5\n", + "98Ik3LDgkD6gjtko2tIIfYH2z7SunmsRwhSVpD1VsKINvshI8iSLzBbV/SWIXDE7\n", + "Qqxe5xyom7rPjk7ljG2aHQKBgB36oxV8YWxmSdRUdBgopG6XEY+Cw+YS8rUiCqxX\n", + "pA0iXAafErzbHGfoFTyxbHcNwRtxiEoRHapxyGoypOR7xRjQB5VVq+xcGwgJYeRZ\n", + "wG+1cbRU9qRnkQaCIz9kUyPhSNbAHJTlB5Fgr4I1pzCxDhrqcW3jUNz0qDwlkNSw\n", + "pXfNAoGBAKlFbbPEzFonlkHVtdUuk6Chsi5k/ddrWsGxwUw5F5BSu0UaseolVls5\n", + "TyDVa8FEfDnUZRxl8HSfC/Qp/kAdveGKyhNaex22L5G8m20rXjsQBMFHMOy2Mho1\n", + "hgs0/emKuVyCs+wnYOqJlWZ8Vf/qGcUtDF3r4aEZ1JUDhUBAVEpo\n", + "-----END RSA PRIVATE KEY-----\n", + NULL +}; + +static int load_cert_and_key(SSL *ssl) +{ + X509 *cert = NULL; + EVP_PKEY *pkey = NULL; + int ret = 0; + + if (!TEST_ptr(cert = X509_from_strings(kClientCert)) + || !TEST_ptr(pkey = PKEY_from_strings(kClientKey)) + || !TEST_int_eq(SSL_use_certificate(ssl, cert), 1) + || !TEST_int_eq(SSL_use_PrivateKey(ssl, pkey), 1)) + goto err; + ret = 1; +err: + X509_free(cert); + EVP_PKEY_free(pkey); + return ret; +} + +/* + * Run tls_construct_client_certificate() under mfail; prep installs the cert + * material. For TLS 1.3 the method is swapped in (IS_TLS13 keys off it) and + * middlebox compat cleared to skip the write-key change. + */ +static int mfail_construct_cert(int is_tls13, int (*prep)(SSL_CONNECTION *s)) +{ + CH_CONFIG cfg = { 0, 0, 0, 0 }; + SSL_CTX *cctx = NULL; + SSL *ssl = NULL; + SSL_CONNECTION *s; + WPACKET pkt; + int ok = 0; + int ret = 0; + + if (!TEST_ptr(cctx = new_ctx(&cfg, client_method(&cfg))) + || !TEST_ptr(ssl = SSL_new(cctx))) + goto err; + if (is_tls13) + SSL_clear_options(ssl, SSL_OP_ENABLE_MIDDLEBOX_COMPAT); + if (!prime_ssl(ssl, 1, 0, &pkt, SSL3_MT_CERTIFICATE)) + goto err; + s = SSL_CONNECTION_FROM_SSL(ssl); +#ifndef OSSL_NO_USABLE_TLS1_3 + if (is_tls13) + ssl->method = tlsv1_3_client_method(); +#endif + + if (prep != NULL && !prep(s)) { + WPACKET_cleanup(&pkt); + goto err; + } + + MFAIL_start(); + ok = (tls_construct_client_certificate(s, &pkt) == CON_FUNC_SUCCESS); + MFAIL_end(); + + WPACKET_cleanup(&pkt); + + ret = ok ? 1 : 0; +err: + SSL_free(ssl); + SSL_CTX_free(cctx); + return ret; +} +#endif /* TLS 1.2 or usable TLS 1.3 */ + +#ifndef OSSL_NO_USABLE_TLS1_3 +/* x509 over TLS 1.3; NO_AUTO_CHAIN avoids best-effort verify swallowing OOM. */ +static int prep_cert_x509(SSL_CONNECTION *s) +{ + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + + SSL_set_mode(ssl, SSL_MODE_NO_AUTO_CHAIN); + return load_cert_and_key(ssl); +} + +static int mfail_construct_cert_x509(void) +{ + return mfail_construct_cert(1, prep_cert_x509); +} +#endif /* OSSL_NO_USABLE_TLS1_3 */ + +#ifndef OPENSSL_NO_TLS1_2 +/* RPK derived from the certificate public key over TLS 1.2 (tls_output_rpk). */ +static int prep_cert_rpk(SSL_CONNECTION *s) +{ + if (!load_cert_and_key(SSL_CONNECTION_GET_SSL(s))) + return 0; + s->ext.client_cert_type = TLSEXT_cert_type_rpk; + return 1; +} + +static int mfail_construct_cert_rpk(void) +{ + return mfail_construct_cert(0, prep_cert_rpk); +} +#endif /* OPENSSL_NO_TLS1_2 */ + +/* Deterministic error branches that mfail (allocation-only) cannot reach. */ + +/* An unrecognized certificate type is rejected. */ +static int test_construct_cert_bad_type(void) +{ + CH_CONFIG cfg = { 0, 0, 0, 0 }; + SSL_CTX *cctx = NULL; + SSL *ssl = NULL; + SSL_CONNECTION *s; + WPACKET pkt; + int have_pkt = 0; + int ret = 0; + + if (!TEST_ptr(cctx = new_ctx(&cfg, client_method(&cfg))) + || !TEST_ptr(ssl = SSL_new(cctx)) + || !prime_ssl(ssl, 1, 0, &pkt, SSL3_MT_CERTIFICATE)) + goto err; + have_pkt = 1; + s = SSL_CONNECTION_FROM_SSL(ssl); + s->ext.client_cert_type = 0xff; + + if (!TEST_int_eq(tls_construct_client_certificate(s, &pkt), CON_FUNC_ERROR)) + goto err; + + ret = 1; +err: + if (have_pkt) + WPACKET_cleanup(&pkt); + SSL_free(ssl); + SSL_CTX_free(cctx); + return ret; +} + +#ifndef OSSL_NO_USABLE_TLS1_3 +/* + * With middlebox compat on, the TLS 1.3 path changes the write keys; without a + * negotiated cipher that fails rather than succeeding. + */ +static int test_construct_cert_change_cipher_fail(void) +{ + CH_CONFIG cfg = { 0, 0, 0, 0 }; + SSL_CTX *cctx = NULL; + SSL *ssl = NULL; + SSL_CONNECTION *s; + WPACKET pkt; + int have_pkt = 0; + int ret = 0; + + if (!TEST_ptr(cctx = new_ctx(&cfg, client_method(&cfg))) + || !TEST_ptr(ssl = SSL_new(cctx)) + || !prime_ssl(ssl, 1, 0, &pkt, SSL3_MT_CERTIFICATE)) + goto err; + have_pkt = 1; + s = SSL_CONNECTION_FROM_SSL(ssl); + ssl->method = tlsv1_3_client_method(); + + if (!TEST_int_eq(tls_construct_client_certificate(s, &pkt), CON_FUNC_ERROR)) + goto err; + + ret = 1; +err: + if (have_pkt) + WPACKET_cleanup(&pkt); + SSL_free(ssl); + SSL_CTX_free(cctx); + return ret; +} + +/* + * A WPACKET failure while writing the TLS 1.3 certificate_request_context + * yields CON_FUNC_ERROR. with_pha exercises the non-empty-context branch. + */ +static int do_construct_cert_ctx_small_buf(int with_pha) +{ + CH_CONFIG cfg = { 0, 0, 0, 0 }; + SSL_CTX *cctx = NULL; + SSL *ssl = NULL; + SSL_CONNECTION *s; + WPACKET pkt; + unsigned char buf[16]; + int have_pkt = 0; + int ret = 0; + + if (!TEST_ptr(cctx = new_ctx(&cfg, client_method(&cfg))) + || !TEST_ptr(ssl = SSL_new(cctx))) + goto err; + SSL_set_connect_state(ssl); + s = SSL_CONNECTION_FROM_SSL(ssl); + if (!TEST_ptr(s) + || !TEST_ptr(s->init_buf = BUF_MEM_new()) + || !TEST_true(BUF_MEM_grow(s->init_buf, SSL3_RT_MAX_PLAIN_LENGTH)) + || !TEST_true(tls_setup_handshake(s))) + goto err; + ssl->method = tlsv1_3_client_method(); + + if (with_pha) { + if (!TEST_ptr(s->pha_context = OPENSSL_malloc(4))) + goto err; + s->pha_context_len = 4; + } + + /* Only the handshake header fits, so the context write overflows. */ + if (!TEST_true(WPACKET_init_static_len(&pkt, buf, hdr_len(&cfg), 0))) + goto err; + have_pkt = 1; + if (!TEST_true(ssl_set_handshake_header(s, &pkt, SSL3_MT_CERTIFICATE))) + goto err; + + if (!TEST_int_eq(tls_construct_client_certificate(s, &pkt), CON_FUNC_ERROR)) + goto err; + + ret = 1; +err: + if (have_pkt) + WPACKET_cleanup(&pkt); + SSL_free(ssl); + SSL_CTX_free(cctx); + return ret; +} + +static int test_construct_cert_ctx_small_buf(void) +{ + return do_construct_cert_ctx_small_buf(0); +} + +static int test_construct_cert_pha_ctx_small_buf(void) +{ + return do_construct_cert_ctx_small_buf(1); +} +#endif /* OSSL_NO_USABLE_TLS1_3 */ + +/* + * =========================================================================== + * tls_construct_client_key_exchange + * =========================================================================== + */ + +#ifndef OPENSSL_NO_TLS1_2 +/* + * The CKE constructors read s->session (peer certificate, PSK identity hint, + * SRP username), which the real state machine creates while processing the + * ServerHello; install a minimal TLS 1.2 session in its place. + */ +static SSL_SESSION *install_session(SSL_CONNECTION *s) +{ + SSL *ssl = SSL_CONNECTION_GET_SSL(s); + SSL_SESSION *sess = SSL_SESSION_new(); + + if (!TEST_ptr(sess)) + return NULL; + sess->ssl_version = TLS1_2_VERSION; + if (!TEST_true(SSL_set_session(ssl, sess))) { + SSL_SESSION_free(sess); + return NULL; + } + SSL_SESSION_free(sess); + return s->session; +} + +/* + * Set the negotiated cipher: the configured list still has the TLS 1.3 + * ciphersuites in front, so find the named TLS 1.2 cipher rather than + * taking the head of the list. + */ +static int set_new_cipher(SSL *ssl, const char *name) +{ + SSL_CONNECTION *s = SSL_CONNECTION_FROM_SSL(ssl); + STACK_OF(SSL_CIPHER) *ciphers = SSL_get_ciphers(ssl); + int i; + + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i); + + if (strcmp(SSL_CIPHER_get_name(c), name) == 0) { + s->s3.tmp.new_cipher = c; + return 1; + } + } + TEST_error("cipher %s not found", name); + return 0; +} + +/* + * Construct a ClientKeyExchange for the cipher named by cipher (NULL + * leaves s->s3.tmp.new_cipher for prep to set). prep injects the state the + * chosen key exchange needs; on success check() inspects the message body. + */ +static int do_construct_cke(const char *cipher, + int (*prep)(SSL_CONNECTION *s), CON_FUNC_RETURN expect, + int (*check)(SSL_CONNECTION *s, const unsigned char *body, size_t bodylen)) +{ + CH_CONFIG cfg = { 0, TLS1_2_VERSION, TLS1_2_VERSION, 0 }; + SSL_CTX *cctx = NULL; + SSL *ssl = NULL; + SSL_CONNECTION *s; + WPACKET pkt; + unsigned char *msg = NULL; + size_t msglen = 0; + int have_pkt = 0; + int ret = 0; + + if (!TEST_ptr(cctx = new_ctx(&cfg, client_method(&cfg))) + || !TEST_ptr(ssl = SSL_new(cctx))) + goto err; + if (cipher != NULL && !TEST_true(SSL_set_cipher_list(ssl, cipher))) + goto err; + if (!prime_ssl(ssl, 1, 0, &pkt, SSL3_MT_CLIENT_KEY_EXCHANGE)) + goto err; + have_pkt = 1; + s = SSL_CONNECTION_FROM_SSL(ssl); + if (cipher != NULL && !set_new_cipher(ssl, cipher)) + goto err; + + if (prep != NULL && !prep(s)) + goto err; + + if (!TEST_int_eq(tls_construct_client_key_exchange(s, &pkt), expect)) + goto err; + + if (expect == CON_FUNC_SUCCESS) { + if (!finish_msg(ssl, &pkt, SSL3_MT_CLIENT_KEY_EXCHANGE, &msg, &msglen)) + goto err; + have_pkt = 0; + if (check != NULL + && !check(s, msg + hdr_len(&cfg), msglen - hdr_len(&cfg))) + goto err; + } + + ret = 1; +err: + if (have_pkt) + WPACKET_cleanup(&pkt); + SSL_free(ssl); + SSL_CTX_free(cctx); + return ret; +} + +/* Run tls_construct_client_key_exchange() under mfail; prep as above. */ +static int mfail_construct_cke_common(const char *cipher, + int (*prep)(SSL_CONNECTION *s)) +{ + CH_CONFIG cfg = { 0, TLS1_2_VERSION, TLS1_2_VERSION, 0 }; + SSL_CTX *cctx = NULL; + SSL *ssl = NULL; + SSL_CONNECTION *s; + WPACKET pkt; + int ok = 0; + int ret = 0; + + if (!TEST_ptr(cctx = new_ctx(&cfg, client_method(&cfg))) + || !TEST_ptr(ssl = SSL_new(cctx)) + || !TEST_true(SSL_set_cipher_list(ssl, cipher)) + || !prime_ssl(ssl, 1, 0, &pkt, SSL3_MT_CLIENT_KEY_EXCHANGE)) + goto err; + s = SSL_CONNECTION_FROM_SSL(ssl); + if (!set_new_cipher(ssl, cipher) || (prep != NULL && !prep(s))) { + WPACKET_cleanup(&pkt); + goto err; + } + + MFAIL_start(); + ok = (tls_construct_client_key_exchange(s, &pkt) == CON_FUNC_SUCCESS); + MFAIL_end(); + + WPACKET_cleanup(&pkt); + + /* 1 on clean success, 0 on an injected allocation failure. */ + ret = ok ? 1 : 0; +err: + SSL_free(ssl); + SSL_CTX_free(cctx); + return ret; +} + +/* kRSA: reuse the test certificate as the received server certificate. */ +static int prep_cke_rsa(SSL_CONNECTION *s) +{ + SSL_SESSION *sess = install_session(s); + + if (sess == NULL) + return 0; + return TEST_ptr(sess->peer = X509_from_strings(kClientCert)); +} + +static int check_cke_rsa(SSL_CONNECTION *s, const unsigned char *body, + size_t bodylen) +{ + PACKET pkt = { 0 }, enc = { 0 }; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *pctx = NULL; + unsigned char pms[256]; + size_t pmslen = sizeof(pms); + int ret = 0; + + /* The 2048-bit server key gives a 256-byte encrypted premaster secret. */ + if (!TEST_true(PACKET_buf_init(&pkt, body, bodylen)) + || !TEST_true(PACKET_get_length_prefixed_2(&pkt, &enc)) + || !TEST_size_t_eq(PACKET_remaining(&pkt), 0) + || !TEST_size_t_eq(PACKET_remaining(&enc), 256)) + return 0; + + /* Decrypt with the server key: must match the saved premaster secret. */ + if (!TEST_ptr(pkey = PKEY_from_strings(kClientKey)) + || !TEST_ptr(pctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL)) + || !TEST_int_gt(EVP_PKEY_decrypt_init(pctx), 0) + || !TEST_int_gt(EVP_PKEY_decrypt(pctx, pms, &pmslen, + PACKET_data(&enc), PACKET_remaining(&enc)), + 0) + || !TEST_ptr(s->s3.tmp.pms) + || !TEST_mem_eq(pms, pmslen, s->s3.tmp.pms, s->s3.tmp.pmslen)) + goto err; + + /* The premaster secret starts with the client version. */ + if (!TEST_size_t_eq(pmslen, SSL_MAX_MASTER_KEY_LENGTH) + || !TEST_int_eq(pms[0], (s->client_version >> 8) & 0xff) + || !TEST_int_eq(pms[1], s->client_version & 0xff)) + goto err; + + ret = 1; +err: + EVP_PKEY_CTX_free(pctx); + EVP_PKEY_free(pkey); + return ret; +} + +static int test_construct_cke_rsa(void) +{ + return do_construct_cke("AES128-GCM-SHA256", prep_cke_rsa, + CON_FUNC_SUCCESS, check_cke_rsa); +} + +/* kRSA without a received server certificate fails. */ +static int prep_cke_rsa_no_cert(SSL_CONNECTION *s) +{ + return install_session(s) != NULL; +} + +static int test_construct_cke_rsa_no_cert(void) +{ + return do_construct_cke("AES128-GCM-SHA256", prep_cke_rsa_no_cert, + CON_FUNC_ERROR, NULL); +} + +static int mfail_construct_cke_rsa(void) +{ + return mfail_construct_cke_common("AES128-GCM-SHA256", prep_cke_rsa); +} + +#ifndef OPENSSL_NO_EC +/* kECDHE: the server's ephemeral key would come from ServerKeyExchange. */ +static int prep_cke_ecdhe(SSL_CONNECTION *s) +{ + return TEST_ptr(s->s3.peer_tmp = EVP_PKEY_Q_keygen(NULL, NULL, "EC", + "P-256")); +} + +static int check_cke_ecdhe(SSL_CONNECTION *s, const unsigned char *body, + size_t bodylen) +{ + PACKET pkt = { 0 }, point = { 0 }; + + /* An uncompressed P-256 point: format byte plus two 32-byte coords. */ + if (!TEST_true(PACKET_buf_init(&pkt, body, bodylen)) + || !TEST_true(PACKET_get_length_prefixed_1(&pkt, &point)) + || !TEST_size_t_eq(PACKET_remaining(&pkt), 0) + || !TEST_size_t_eq(PACKET_remaining(&point), 65) + || !TEST_int_eq(PACKET_data(&point)[0], POINT_CONVERSION_UNCOMPRESSED)) + return 0; + /* ssl_derive saved the x-coordinate as the premaster secret. */ + return TEST_ptr(s->s3.tmp.pms) && TEST_size_t_eq(s->s3.tmp.pmslen, 32); +} + +static int test_construct_cke_ecdhe(void) +{ + return do_construct_cke("ECDHE-RSA-AES128-GCM-SHA256", prep_cke_ecdhe, + CON_FUNC_SUCCESS, check_cke_ecdhe); +} + +/* Without the server's ephemeral key (s->s3.peer_tmp) the construct fails. */ +static int test_construct_cke_ecdhe_no_key(void) +{ + return do_construct_cke("ECDHE-RSA-AES128-GCM-SHA256", NULL, + CON_FUNC_ERROR, NULL); +} + +/* A WPACKET overflow while writing the key share yields CON_FUNC_ERROR. */ +static int test_construct_cke_small_buf(void) +{ + CH_CONFIG cfg = { 0, TLS1_2_VERSION, TLS1_2_VERSION, 0 }; + SSL_CTX *cctx = NULL; + SSL *ssl = NULL; + SSL_CONNECTION *s; + WPACKET pkt; + unsigned char buf[16]; + int have_pkt = 0; + int ret = 0; + + if (!TEST_ptr(cctx = new_ctx(&cfg, client_method(&cfg))) + || !TEST_ptr(ssl = SSL_new(cctx)) + || !TEST_true(SSL_set_cipher_list(ssl, "ECDHE-RSA-AES128-GCM-SHA256")) + || !prime_ssl(ssl, 1, 0, NULL, SSL3_MT_CLIENT_KEY_EXCHANGE)) + goto err; + s = SSL_CONNECTION_FROM_SSL(ssl); + if (!set_new_cipher(ssl, "ECDHE-RSA-AES128-GCM-SHA256") + || !prep_cke_ecdhe(s)) + goto err; + + /* Too small for the 65-byte P-256 point: the point write overflows. */ + if (!TEST_true(WPACKET_init_static_len(&pkt, buf, sizeof(buf), 0))) + goto err; + have_pkt = 1; + if (!TEST_true(ssl_set_handshake_header(s, &pkt, + SSL3_MT_CLIENT_KEY_EXCHANGE))) + goto err; + + if (!TEST_int_eq(tls_construct_client_key_exchange(s, &pkt), + CON_FUNC_ERROR)) + goto err; + + ret = 1; +err: + if (have_pkt) + WPACKET_cleanup(&pkt); + SSL_free(ssl); + SSL_CTX_free(cctx); + return ret; +} + +/* + * X25519 keygen when possible: without ECX we fall back to EC keygen, which + * makes a best-effort param-cache allocation whose failure does not propagate + * (as for mfail_construct_ch_tls13), so only crash/leak checking applies. + */ +static int prep_cke_ecdhe_mfail(SSL_CONNECTION *s) +{ +#ifndef OPENSSL_NO_ECX + return TEST_ptr(s->s3.peer_tmp = EVP_PKEY_Q_keygen(NULL, NULL, "X25519")); +#else + return prep_cke_ecdhe(s); +#endif +} + +static int mfail_construct_cke_ecdhe(void) +{ + return mfail_construct_cke_common("ECDHE-RSA-AES128-GCM-SHA256", + prep_cke_ecdhe_mfail); +} +#endif /* OPENSSL_NO_EC */ + +#ifndef OPENSSL_NO_DH +/* kDHE: the server's ephemeral key would come from ServerKeyExchange. */ +static int prep_cke_dhe(SSL_CONNECTION *s) +{ + EVP_PKEY_CTX *pctx = NULL; + int ret = 0; + + if (!TEST_ptr(pctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL)) + || !TEST_int_gt(EVP_PKEY_keygen_init(pctx), 0) + || !TEST_int_gt(EVP_PKEY_CTX_set_group_name(pctx, "ffdhe2048"), 0) + || !TEST_int_gt(EVP_PKEY_keygen(pctx, &s->s3.peer_tmp), 0)) + goto err; + ret = 1; +err: + EVP_PKEY_CTX_free(pctx); + return ret; +} + +/* The public key is zero-padded to the prime length (256 for ffdhe2048). */ +static int check_cke_dhe(SSL_CONNECTION *s, const unsigned char *body, + size_t bodylen) +{ + PACKET pkt = { 0 }, pub = { 0 }; + + if (!TEST_true(PACKET_buf_init(&pkt, body, bodylen)) + || !TEST_true(PACKET_get_length_prefixed_2(&pkt, &pub)) + || !TEST_size_t_eq(PACKET_remaining(&pkt), 0) + || !TEST_size_t_eq(PACKET_remaining(&pub), 256)) + return 0; + /* ssl_derive saved the premaster secret. */ + return TEST_ptr(s->s3.tmp.pms) && TEST_size_t_gt(s->s3.tmp.pmslen, 0); +} + +static int test_construct_cke_dhe(void) +{ + return do_construct_cke("DHE-RSA-AES128-GCM-SHA256", prep_cke_dhe, + CON_FUNC_SUCCESS, check_cke_dhe); +} +#endif /* OPENSSL_NO_DH */ + +#ifndef OPENSSL_NO_PSK +#define CKE_PSK_IDENTITY "statem-clnt-psk-identity" + +static const unsigned char cke_psk[16] = { + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf +}; + +static unsigned int psk_client_cb(SSL *ssl, const char *hint, char *identity, + unsigned int max_identity_len, unsigned char *psk, + unsigned int max_psk_len) +{ + if (snprintf(identity, max_identity_len, "%s", CKE_PSK_IDENTITY) <= 0 + || max_psk_len < sizeof(cke_psk)) + return 0; + memcpy(psk, cke_psk, sizeof(cke_psk)); + return sizeof(cke_psk); +} + +static int prep_cke_psk(SSL_CONNECTION *s) +{ + if (install_session(s) == NULL) + return 0; + SSL_set_psk_client_callback(SSL_CONNECTION_GET_SSL(s), psk_client_cb); + return 1; +} + +/* kPSK sends only the identity; the PSK itself is stashed for the secret. */ +static int check_cke_psk(SSL_CONNECTION *s, const unsigned char *body, + size_t bodylen) +{ + PACKET pkt = { 0 }, identity = { 0 }; + + if (!TEST_true(PACKET_buf_init(&pkt, body, bodylen)) + || !TEST_true(PACKET_get_length_prefixed_2(&pkt, &identity)) + || !TEST_size_t_eq(PACKET_remaining(&pkt), 0) + || !TEST_mem_eq(PACKET_data(&identity), PACKET_remaining(&identity), + CKE_PSK_IDENTITY, strlen(CKE_PSK_IDENTITY))) + return 0; + return TEST_mem_eq(s->s3.tmp.psk, s->s3.tmp.psklen, cke_psk, + sizeof(cke_psk)) + && TEST_str_eq(s->session->psk_identity, CKE_PSK_IDENTITY); +} + +static int test_construct_cke_psk(void) +{ + return do_construct_cke("PSK-AES128-GCM-SHA256", prep_cke_psk, + CON_FUNC_SUCCESS, check_cke_psk); +} + +/* No PSK client callback set: fails before the session is even looked at. */ +static int test_construct_cke_psk_no_cb(void) +{ + return do_construct_cke("PSK-AES128-GCM-SHA256", NULL, CON_FUNC_ERROR, + NULL); +} + +/* A callback returning no PSK is treated as identity-not-found. */ +static unsigned int psk_client_cb_empty(SSL *ssl, const char *hint, + char *identity, unsigned int max_identity_len, unsigned char *psk, + unsigned int max_psk_len) +{ + return 0; +} + +static int prep_cke_psk_not_found(SSL_CONNECTION *s) +{ + if (install_session(s) == NULL) + return 0; + SSL_set_psk_client_callback(SSL_CONNECTION_GET_SSL(s), + psk_client_cb_empty); + return 1; +} + +static int test_construct_cke_psk_not_found(void) +{ + return do_construct_cke("PSK-AES128-GCM-SHA256", prep_cke_psk_not_found, + CON_FUNC_ERROR, NULL); +} + +/* A callback claiming more than PSK_MAX_PSK_LEN is rejected. */ +static unsigned int psk_client_cb_oversize(SSL *ssl, const char *hint, + char *identity, unsigned int max_identity_len, unsigned char *psk, + unsigned int max_psk_len) +{ + return PSK_MAX_PSK_LEN + 1; +} + +static int prep_cke_psk_oversize(SSL_CONNECTION *s) +{ + if (install_session(s) == NULL) + return 0; + SSL_set_psk_client_callback(SSL_CONNECTION_GET_SSL(s), + psk_client_cb_oversize); + return 1; +} + +static int test_construct_cke_psk_oversize(void) +{ + return do_construct_cke("PSK-AES128-GCM-SHA256", prep_cke_psk_oversize, + CON_FUNC_ERROR, NULL); +} + +static int mfail_construct_cke_psk(void) +{ + return mfail_construct_cke_common("PSK-AES128-GCM-SHA256", prep_cke_psk); +} +#endif /* OPENSSL_NO_PSK */ + +/* A cipher whose key exchange matches no branch hits the final SSLfatal. */ +static int prep_cke_bad_kex(SSL_CONNECTION *s) +{ + static const SSL_CIPHER no_kex_cipher = { 0 }; + + s->s3.tmp.new_cipher = &no_kex_cipher; + return 1; +} + +static int test_construct_cke_bad_kex(void) +{ + return do_construct_cke(NULL, prep_cke_bad_kex, CON_FUNC_ERROR, NULL); +} +#endif /* OPENSSL_NO_TLS1_2 */ + int setup_tests(void) { ADD_TEST(test_construct_ch_small_buf); @@ -693,10 +1539,8 @@ int setup_tests(void) ADD_TEST(test_construct_ch_tls13); ADD_TEST(test_construct_ch_tls13_no_middlebox); ADD_TEST(test_construct_ch_hrr); - /* - * The non-cached mfail run takes too long and does not test too much extra - * so better to skip it. - */ + ADD_TEST(test_construct_eoed); + ADD_TEST(test_construct_eoed_bad_state); #if defined(OPENSSL_NO_ECX) /* * Without ECX the key_share falls back to EC keygen, which makes a @@ -724,5 +1568,48 @@ int setup_tests(void) #endif ADD_MFAIL_TEST(mfail_construct_ch_ech); #endif /* OSSL_NO_USABLE_ECH */ + + /* tls_construct_client_certificate: OOM coverage of the output functions. */ +#ifndef OSSL_NO_USABLE_TLS1_3 + ADD_MFAIL_TEST(mfail_construct_cert_x509); +#endif +#ifndef OPENSSL_NO_TLS1_2 + ADD_MFAIL_TEST(mfail_construct_cert_rpk); +#endif + ADD_TEST(test_construct_cert_bad_type); +#ifndef OSSL_NO_USABLE_TLS1_3 + ADD_TEST(test_construct_cert_change_cipher_fail); + ADD_TEST(test_construct_cert_ctx_small_buf); + ADD_TEST(test_construct_cert_pha_ctx_small_buf); +#endif + + /* tls_construct_client_key_exchange */ +#ifndef OPENSSL_NO_TLS1_2 + ADD_TEST(test_construct_cke_rsa); + ADD_TEST(test_construct_cke_rsa_no_cert); + ADD_TEST(test_construct_cke_bad_kex); + ADD_MFAIL_TEST(mfail_construct_cke_rsa); +#ifndef OPENSSL_NO_EC + ADD_TEST(test_construct_cke_ecdhe); + ADD_TEST(test_construct_cke_ecdhe_no_key); + ADD_TEST(test_construct_cke_small_buf); +#if defined(OPENSSL_NO_ECX) + /* EC keygen: see the mfail_construct_ch_tls13 comment above. */ + ADD_MFAIL_NO_CHECK_TEST(mfail_construct_cke_ecdhe); +#else + ADD_MFAIL_TEST(mfail_construct_cke_ecdhe); +#endif +#endif /* OPENSSL_NO_EC */ +#ifndef OPENSSL_NO_DH + ADD_TEST(test_construct_cke_dhe); +#endif +#ifndef OPENSSL_NO_PSK + ADD_TEST(test_construct_cke_psk); + ADD_TEST(test_construct_cke_psk_no_cb); + ADD_TEST(test_construct_cke_psk_not_found); + ADD_TEST(test_construct_cke_psk_oversize); + ADD_MFAIL_TEST(mfail_construct_cke_psk); +#endif +#endif /* OPENSSL_NO_TLS1_2 */ return 1; } diff --git a/test/strtoultest.c b/test/strtoultest.c index fbeee4845ab3c..d99fec3133812 100644 --- a/test/strtoultest.c +++ b/test/strtoultest.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,7 +7,11 @@ * https://www.openssl.org/source/license.html */ +#include +#include + #include +#include #include #include "testutil.h" @@ -87,8 +91,295 @@ static int test_strtoul(int idx) return 1; } +struct strtol_test_entry { + char *input; /* the input string */ + int base; /* the base we are converting in */ + long expect_val; /* the expected value we should get */ + int expect_err; /* the expected error we expect to receive */ + size_t expect_endptr_offset; /* expected endptr offset (index into input) */ +}; + +static struct strtol_test_entry strtol_tests[] = { + /* pass on conv "0" to 0 */ + { + "0", 0, 0, 1, 1 }, + /* pass on conv "12345" to 12345 */ + { + "12345", 0, 12345, 1, 5 }, + /* pass on conv "0x12345" to 0x12345, base 16 */ + { + "0x12345", 0, 0x12345, 1, 7 }, + /* pass on base 10 translation, endptr points to 'x' */ + { + "0x12345", 10, 0, 1, 1 }, + /* pass on conv " 123" to 123 (leading whitespace) */ + { + " 123", 0, 123, 1, 4 }, + /* pass on conv "-1" to -1 (signed negative) */ + { + "-1", 0, -1, 1, 2 }, + /* pass on conv "-12345" to -12345 */ + { + "-12345", 0, -12345, 1, 6 }, + /* pass on conv " -1" to -1 (whitespace + negative) */ + { + " -1", 0, -1, 1, 3 }, +#if LONG_MAX == 2147483647 + /* pass on LONG_MAX translation */ + { + "2147483647", 0, LONG_MAX, 1, 10 }, + /* pass on LONG_MIN translation */ + { + "-2147483648", 0, LONG_MIN, 1, 11 }, +#else + /* pass on LONG_MAX translation */ + { + "9223372036854775807", 0, LONG_MAX, 1, 19 }, + /* pass on LONG_MIN translation */ + { + "-9223372036854775808", 0, LONG_MIN, 1, 20 }, +#endif + /* fail on non-numerical input */ + { + "abcd", 0, 0, 0, 0 }, + /* pass on decimal input */ + { + "1.0", 0, 1, 1, 1 }, + /* Fail on decimal input without leading number */ + { + ".1", 0, 0, 0, 0 } +}; + +static int test_strtol(int idx) +{ + long val; + char *endptr = NULL; + int err; + struct strtol_test_entry *test = &strtol_tests[idx]; + + err = ossl_strtol(test->input, &endptr, test->base, &val); + + if (!TEST_int_eq(err, test->expect_err)) + return 0; + if (!TEST_ptr_eq(endptr, &test->input[test->expect_endptr_offset])) + return 0; + if (test->expect_err == 1) { + if (!TEST_long_eq(val, test->expect_val)) + return 0; + } + return 1; +} + +/* Overflow/underflow must fail and leave errno set to ERANGE */ +static int test_strtol_overflow(void) +{ + long l; + int ret, saved_errno; + + ret = ossl_strtol("99999999999999999999999", NULL, 0, &l); + saved_errno = errno; + if (!TEST_int_eq(ret, 0) || !TEST_int_eq(saved_errno, ERANGE)) + return 0; + + ret = ossl_strtol("-99999999999999999999999", NULL, 0, &l); + saved_errno = errno; + if (!TEST_int_eq(ret, 0) || !TEST_int_eq(saved_errno, ERANGE)) + return 0; + + return 1; +} + +/* + * A NULL endptr requires the whole string to be consumed. Pre-setting errno + * also verifies the internal errno = 0 reset. + */ +static int test_strtol_null_endptr(void) +{ + long l; + int ret; + + /* full consumption succeeds */ + ret = ossl_strtol("123", NULL, 0, &l); + if (!TEST_int_eq(ret, 1) || !TEST_long_eq(l, 123)) + return 0; + + /* leading whitespace + negative, full consumption succeeds */ + ret = ossl_strtol(" -456", NULL, 0, &l); + if (!TEST_int_eq(ret, 1) || !TEST_long_eq(l, -456)) + return 0; + + /* trailing garbage with NULL endptr must fail */ + ret = ossl_strtol("123abc", NULL, 0, &l); + if (!TEST_int_eq(ret, 0)) + return 0; + + /* pre-set errno; the internal reset must let a clean parse succeed */ + errno = ERANGE; + ret = ossl_strtol("789", NULL, 0, &l); + if (!TEST_int_eq(ret, 1) || !TEST_long_eq(l, 789) || !TEST_int_eq(errno, 0)) + return 0; + + return 1; +} + +/* NULL result / NULL str short-circuit to failure */ +static int test_strtol_null_args(void) +{ + long l; + int i; + + /* ossl_strtol: result == NULL */ + if (!TEST_int_eq(ossl_strtol("123", NULL, 0, NULL), 0)) + return 0; + /* ossl_strtol: str == NULL */ + if (!TEST_int_eq(ossl_strtol(NULL, NULL, 0, &l), 0)) + return 0; + /* ossl_strtoint: result == NULL (short-circuits before ossl_strtol) */ + if (!TEST_int_eq(ossl_strtoint("123", NULL, 0, NULL), 0)) + return 0; + /* ossl_strtoint: str == NULL (rejected by ossl_strtol) */ + if (!TEST_int_eq(ossl_strtoint(NULL, NULL, 0, &i), 0)) + return 0; + return 1; +} + +static struct strtol_test_entry strtoint_tests[] = { + /* pass on conv "0" to 0 */ + { + "0", 0, 0, 1, 1 }, + /* pass on conv "123" to 123 */ + { + "123", 0, 123, 1, 3 }, + /* pass on conv "-456" to -456 (signed, within int range) */ + { + "-456", 0, -456, 1, 4 }, +#if INT_MAX == 2147483647 + /* pass on INT_MAX translation */ + { + "2147483647", 0, INT_MAX, 1, 10 }, + /* pass on INT_MIN translation */ + { + "-2147483648", 0, INT_MIN, 1, 11 }, +#endif + /* fail on non-numerical input */ + { + "abcd", 0, 0, 0, 0 }, + /* pass on decimal input */ + { + "1.0", 0, 1, 1, 1 }, + /* Fail on decimal input without leading number */ + { + ".1", 0, 0, 0, 0 } +}; + +/* + * Driver named test_strtoint_arr so it does not clash with the test_strtoint() + * symbol under test. + */ +static int test_strtoint_arr(int idx) +{ + int val; + char *endptr = NULL; + int err; + struct strtol_test_entry *test = &strtoint_tests[idx]; + + err = ossl_strtoint(test->input, &endptr, test->base, &val); + + if (!TEST_int_eq(err, test->expect_err)) + return 0; + if (!TEST_ptr_eq(endptr, &test->input[test->expect_endptr_offset])) + return 0; + if (test->expect_err == 1) { + if (!TEST_int_eq(val, (int)test->expect_val)) + return 0; + } + return 1; +} + +/* Values outside [INT_MIN, INT_MAX] and long overflow all fail */ +static int test_strtoint_overflow(void) +{ + int i; + + /* INT_MAX + 1 (narrowing failure, or long overflow on ILP32) */ + if (!TEST_int_eq(ossl_strtoint("2147483648", NULL, 10, &i), 0)) + return 0; + /* INT_MIN - 1 (narrowing failure, or long underflow on ILP32) */ + if (!TEST_int_eq(ossl_strtoint("-2147483649", NULL, 10, &i), 0)) + return 0; + /* long overflow: ossl_strtol fails */ + if (!TEST_int_eq(ossl_strtoint("99999999999999999999999", NULL, 10, &i), 0)) + return 0; + return 1; +} + +struct strtoint_util_entry { + char *input; /* the input string */ + int expect_val; /* the expected value we should get */ + int expect_err; /* the expected error we expect to receive */ +}; + +static struct strtoint_util_entry util_strtoint_tests[] = { + /* pass on conv "0" to 0 */ + { + "0", 0, 1 }, + /* pass on conv "123" to 123 */ + { + "123", 123, 1 }, + /* pass on conv " 45" to 45 (leading whitespace) */ + { + " 45", 45, 1 }, +#if INT_MAX == 2147483647 + /* pass on INT_MAX translation */ + { + "2147483647", INT_MAX, 1 }, +#endif + /* fail on negative input */ + { + "-1", 0, 0 }, + /* fail on value > INT_MAX */ + { + "2147483648", 0, 0 }, + /* fail on unsigned overflow */ + { + "99999999999999999999999", 0, 0 }, + /* fail on non-numerical input */ + { + "abcd", 0, 0 }, + /* fail on trailing garbage (NULL-endptr full-consumption rule) */ + { + "12abc", 0, 0 }, + /* fail on empty input */ + { + "", 0, 0 } +}; + +static int test_util_strtoint(int idx) +{ + int val; + int err; + struct strtoint_util_entry *test = &util_strtoint_tests[idx]; + + err = test_strtoint(test->input, &val); + + if (!TEST_int_eq(err, test->expect_err)) + return 0; + if (test->expect_err == 1) { + if (!TEST_int_eq(val, test->expect_val)) + return 0; + } + return 1; +} + int setup_tests(void) { ADD_ALL_TESTS(test_strtoul, OSSL_NELEM(strtoul_tests)); + ADD_ALL_TESTS(test_strtol, OSSL_NELEM(strtol_tests)); + ADD_ALL_TESTS(test_strtoint_arr, OSSL_NELEM(strtoint_tests)); + ADD_ALL_TESTS(test_util_strtoint, OSSL_NELEM(util_strtoint_tests)); + ADD_TEST(test_strtol_overflow); + ADD_TEST(test_strtol_null_endptr); + ADD_TEST(test_strtol_null_args); + ADD_TEST(test_strtoint_overflow); return 1; } diff --git a/test/sysdefaulttest.c b/test/sysdefaulttest.c index 6e3b53e3b912e..f9c0a5857492e 100644 --- a/test/sysdefaulttest.c +++ b/test/sysdefaulttest.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/test/test.cnf b/test/test.cnf index a4d8355c5b37e..f7ca49c7bc127 100644 --- a/test/test.cnf +++ b/test/test.cnf @@ -71,6 +71,28 @@ commonName_value = Eric Young emailAddress = email field emailAddress_value = eay@mincom.oz.au +# Request section with prompt-style attributes +[ req_attrs ] +distinguished_name = req_distinguished_name +attributes = req_attributes + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_value = SecretPass123 +challengePassword_min = 4 +challengePassword_max = 20 +unstructuredName = An unstructured name +unstructuredName_value = An Example Company + +# Request section with attributes without prompting +[ req_attrs_noprompt ] +prompt = no +distinguished_name = dirname_sec +attributes = req_attributes_noprompt + +[ req_attributes_noprompt ] +challengePassword = NopromptSecret456 + [ dirname_sec ] C = UK O = My Organization diff --git a/test/testcomposite44-ecdsa-p256.pem b/test/testcomposite44-ecdsa-p256.pem new file mode 100644 index 0000000000000..02f02f9a16e97 --- /dev/null +++ b/test/testcomposite44-ecdsa-p256.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MGQCAQAwCgYIKwYBBQUHBigEU6FUg+RX8FgGg3vc5+vdfehBvUTkQ8K6iYJGOA3O +LCyTMDECAQEEILXW6/tyKRaiYhSoogzNpTucnaMvgjCpxRiMRu9eOHxXoAoGCCqG +SM49AwEH +-----END PRIVATE KEY----- diff --git a/test/testcomposite44-ecdsa-p256pub.pem b/test/testcomposite44-ecdsa-p256pub.pem new file mode 100644 index 0000000000000..309ba1537ae53 --- /dev/null +++ b/test/testcomposite44-ecdsa-p256pub.pem @@ -0,0 +1,32 @@ +-----BEGIN PUBLIC KEY----- +MIIFcjAKBggrBgEFBQcGKAOCBWIAR+O+X5MG5ALgnvs+t99P3JrpARWm0ywszpJ/ +g+38VxahAjeEWsq7ZutIkp+yaDiROtndTSTQjYr+vYpLJ274HaELtAHnAerE827V +3Daj64bBAI6BEhrxjZMADHd6SiIIgUEuGAwJqZIK8qmhzUg+tt5L35ccw8vbjoC6 +tFmm1n26ORvLI+lWEOONQpRffFmaAhgEq6rU/CXGVTAuSS+Bc0gNEjlhGU51Zpwb +AYSJeWZvn9I/qB+QNZFWZKPfDO9hKZ59XvqgpD0NhJr0YHgou5ABhDJHRjKKbzs5 +U5wxRKH3LxaHBVr0JQ6bUeHPrbTCiBFYm72yd2+sf+wT1edppWToCury0YnxvRLL +Nl6+DnhMNkOkDUZhL+ABqxpia4qF1s0tdQT71WuREjUx7agt9UAnAkIoH5k3GzHJ +Yh138TiJWy89Yof0TxdZ9g642Og18TcM2yzhNLv86/et1Ve1ZIegZAzKWsZUEv+6 +b9YsmHROYBHM4uIfGxxkgl6woC4T/IE8pmhkGmQeVz+x0d54ipYaFfnpOnTkMgEi +ndhGJuC41PmZcCEX0rZ9KjzSvcJcIt5fL708yoRqZm2GZRANy4i5+nOdnK8y+JgR +zOH2l/1xBxt7JxVqEf/7SmtHZfEvKPHaMMXQIlpSs/U7NJv6T7J0cDGNh7BsnEHH +KobdYqXqQyNPqIKflk3TN+8VcSOATA/EhykTZiDSuzDKE70N5ufgi2/VmW3+xmY1 +5cg+cnSjgKqnp3O39coT2BUwLXxGHGRW7PkEaPZrqLkYn2fRe4Uj5lfJFmAohqTG +LhDFAeDjaQjKnXgqmMinUEc6TtZ+NRpJ0PpT33dOc+sJYZNVOcOFe/Q0GIxs4gAg +l0cLQhhbNcgf1I674ni6kabuyY5BgSyyt+rX6r/WUu2pRmcfbiOWjTVyE6DpNS5N +dR8ILnLkATdhfm7LR3ZO9+FywjmkBLu6lrMQ/CAflfnySbwI7GyYhfaW4dPChOqq +iGdZvm2/u+trO3b+0kD/MAp5JC91iKnQGuhnhXwTjksMpOhNSAGFSJuZw2QzNrlO +IWXZW5wHWfl5XeSPJjd63bOGhf07GtXUfEPEXCjyQ27t5XLKgxCOotJH0COiTX3x +0LOtzAkx0x333SJjS2m6rLmlAnC3XrIRWZiDDgaTW0nVY7eaCbP1uSfhKFcUEWGJ +l+aaFgwbbBF2n8RBEF5XFxQsOqK2Ii2Tavf616LIdrBmWpLVFJsjIKWa5Nj/o9/L +MIvFUbpOCFcpuWMhupXxe7gx5y+NTDyKfuEYd5iLFBL8uJl+WhHYoBWG6OtyywHa +XLwbIPYjWkGXoaGxTmFVl1QS/odA94GNGFhtT2zR0PCOhuuxK7uNId/jMJNDPfEq +SYn4T1LjrEKFP4xDX9MxjhOM2Y9lTmOPvk1hBhECXILgZc27eB+splF5XGM1RqSR +NoAwXiY2SmwG6NglGxnw2jMN2GIjcYRxKFwY9QOJWjsBguMptA4bzl4OHuDEfIMH +A0mjw0anTzzfdagSMp2cXXCM8NMXCsV0fT9s3l9ChVmfd7Ar6/zbOYn6tVo9TkL5 +8oHLdSJqT8La2SZWvRRLgn7pOtemq5KGqDW7bG/ob2sfY9BR6A5ZnahplCTWdn2K +6d+MRdmOR7pWt6I2NyubHM6GZTSXWcz7T4JK3CtAklIN3hOQP8fRjvmzU3rNIjal +VXD6geizr4jMqTQ9y5dd60OP1a8++pRuyF7lYLuX2zABZWTb3gQ97aAmOhFO9x1s +mIl6fRP00dtQ5nVQvIn9AcRdad528Gb4dIlaXIdIoY4saIb1QwjNFQe0f83WQg3J +uayaA9GB +-----END PUBLIC KEY----- diff --git a/test/testcomposite44-ed25519.pem b/test/testcomposite44-ed25519.pem new file mode 100644 index 0000000000000..03a940952a0f8 --- /dev/null +++ b/test/testcomposite44-ed25519.pem @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY----- +MFECAQAwCgYIKwYBBQUHBicEQImSHevDE0axbaK/T/+iLEp80Ck1QFQsJncl2T6k +nA4HQTSxAdbQbts85c/JR5Tmv2ygQBLSXqjQH/2W150LZLw= +-----END PRIVATE KEY----- diff --git a/test/testcomposite44-ed25519pub.pem b/test/testcomposite44-ed25519pub.pem new file mode 100644 index 0000000000000..9d9835525ca5a --- /dev/null +++ b/test/testcomposite44-ed25519pub.pem @@ -0,0 +1,31 @@ +-----BEGIN PUBLIC KEY----- +MIIFUTAKBggrBgEFBQcGJwOCBUEAaFWRPwCGtjtt8iA1Y1qcDaTHPrCofSsFQyXI +Mrl+Jk86Z1hIAdcPvaeKp4zrvQM9zsx8Ci3lEITEC79JyMbGJA+y1HwYBVKk97WG +y4rQbm727x/N84Z2A3kXPV8L27WsV+9vIUSLam9IoF8e8mOk6zjV7YiN5XW/YYxL +irW/G+LlNPJ3fIClH1iy90f+ySPOKjb1tScCdBBNMxuOlxOZzFOMrexAv0TYpWYm +fGN2ycn3TC3gIUvQHCgTanEadhVs4lbgp4PXEuJjGuMjWpvVAGmnsChY++MU/mzr +cLP6fQrb384IqT/6IGzTLhKoE/IoiJqwZK+eHEtSyRmoMZyVmGKrbIeH8dBK3U+x +IdtQL4HZ6uRS3SxySD3hdDCJWOCN4Ib5B1SaDu/5SOabk8Gg2YwnfbT2Iyr4JMFA +8XrEDBca+pXfvR1AIvCCT8396ol7B7uemjC7sadiWsTbDZdfxyHWPnquYf1Q6+V4 +IllIAkO9LsorHmdGfKvRFisxcR8ipyx6m7sPZxxi8btDDkwPdOs1LiciRbOuz88m +IK0f+ZBpv01MHe7Zk45YWOgLFoZwl5/gHdkrDYVilBMpUYwDGN9tAaNDUxeFENTN +IAXS2pmE1za61SWVLqfS8P6IzoHWDolTqyvXPnvnNIR8yJymAygTr0E1yLuNeP9p +OiDJzznsUdHOQ04CBsoasmTZtEDIsl4sJn7q2W3zBqdTikmBi2vs5esH3/tmwkeY +L9VudWoHstzA+j/XPMSSqlPZKEUGzwFq6/lvAw6AiUawLejXh6TZBNnP0qngN02w +e5nbomDApx5xujf2bsXdUkQOIQrs2wAo8xwuD4tnIOvyfm4BW3MzsNcHjvJXR2UX ++CqVRWtm93Fob3ouTKpAFJKq42mzvzu0sEEu0NC0F4e3gvDwUgvypVjzRS9i4T7i +42WazwU3GrXHCKxSuhLIfM5Frp3iDNOV29AM2GyCDL/nwGDEIR6RVVl5DwV4/W4L +Waq4hp7JquEc0s8x0EtJ5pM94x0AevU1N1H0EcvoMyEmPOLFN8uUv/CWUNU1LYY7 +N5DqOHKN7NxwK4DVbT+FNeVMtZcMSlFGiWDAYztAAf7sJiM08ag2DEJJ2woe0Pen +xl/0iztxApYXJJYoltYAoxzZLOuZUaPSdcZVqrKpW+7fljjo4Hu9OTzZbVWu+SwA +XhrU0c5LXP4bN6ijJ1KR+XlihQmk5vN9oW9/7wo+KbirLO+7WeiYUaKud5qcR3Yw +OO24gpvuS2eC7HTuUYSZd6BQE7h1UR/OBh0/WmVymo8a/C1oCWaaxLJnLhmNPSOE +e9QZKxp8cOYhLQKM9fmLT5C0tFF/EDzj50TSnTGp9IPiaQiEKaZtiH7RunUsQpO4 +1mb/nEp0y3Ggn15JZy+TTxyjhzQac8KOjpleOmANgof1OCzUiiOImHbTT+c5Xg6X +jHGZZ5tFdb8RKmwIOWpSdCHOttNCRpFdmED97Qm74s53ofJWEDN7wjqV/fNJQk6a +e85m5Lo7LWNCtKV0YaDgSPyhLaL3aUi4zDgEVAoS+OXoiX18M6HOxE1xLWVD5Y+4 +SU+Vdkw2uUr7HCEh2B9FLZmrUMrCbuVqztEMGdw7YWprfbggCBaQN3K23/Cv87wK +xKX+UuJYZhyqDvrVzoYHiWusSaOKor1JGpmPsLOEX+dpZ/jTyCdgLWiRt/SMAfnL +6CYo32/HilUqig8jLDxRA8u3gm2S7F30Z3Kct8F4m48xYR1tDv0AoTRWi+Buuv0D +RYI2sYibM9XZ66aVvNy/225Mv1Y/ +-----END PUBLIC KEY----- diff --git a/test/testcomposite44-rsa2048pkcs15.pem b/test/testcomposite44-rsa2048pkcs15.pem new file mode 100644 index 0000000000000..3d43d50458972 --- /dev/null +++ b/test/testcomposite44-rsa2048pkcs15.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIE3AIBADAKBggrBgEFBQcGJgSCBMnffmwkuPHv3MxVXULFHm1o6i0Ej6/N8O4W +0imXaL2kdDCCBKUCAQACggEBAM81VF8Ya2LgzA4M1x4JApfgrIewFZd/eQ+rROgF +zfqMd4kigQLH0wGcaONJaFEINdCWKQCK67FBQDc3EZJWRJDUr+/xcX3XCn0c4RdC +fdqES0LMoWejAbKU32X6vvX6ODdhwS6hSeplZmYtI5IU7lrDo+JtkyEWumFuxgUr +K7h77IP9RFwhMn+rPRCiSkKtH2/Hj9MqerJSUm1jliwvLm3x+fwxgrCbA4CjWVRY +2TcwM1RGFHk2+ugwVMkspdLJrKTSC/tyxK24ehG+lUHXBRzmlXD809sxI3uUosnu +Y1VFT50jJ2IIM2egT5gdVMm6o/wc3e4def6PvTo+2rsTlKUCAwEAAQKCAQASNrkb +odEgsCtnqcPIAVk/wfFQfQ8s0bjxwmeMcKQuO6YvQP/vn2KCH/5NSlDX3J2kX+qr +QEre+iIbqGTMRPaCd5uefw3vlpU2sbDsgzz+VgYqkUO30SmPScxIUc3y38OMxLQ/ +NdDCQJcLcLjReLMJ+ewANYsLC80mzt6rqiON8/gAxy10WBUY7zrfpsGeHaFFH4bg +7MyF3eDWQlJjJPIAOLUJx1bYNgOkbM2lNLYeoJY8pVcY3pHY6yPZmqe1dYLvgCT8 +Mq3qlApRxCE4pqkowp5c/d9Ak6+iLVsIdbL+BLAdVZp7YQYKoOMTY1JNW9d8Zh2y +2Ba3PA0t40Ri2HkBAoGBAP6g6DOOBRUagYp0sO2bHX/dnw3RutcKcMy/Pv7ep5Cu +wHXv6JzTdmrvLFEPW/FuQj3SvK8eiz4e/PNiei91dGsmkArN+sTFDUMQz84WApK/ +cV1zSj/1Ij2cMeZt9kI+Nd57jSkyi7KLiCsGLm1TQlpv+6JeblXq6pIWFsJ8SdsB +AoGBANBTCZcTV/cWml6MLvyEZifxIfbTbE8GryF8uFfS4BklRVicHa0DcbnMyCm+ +FBlaLeECap9ZMmvf8VgDhVq1Ik/EwZav93eD4kSOD6E9z4ARGZSptYtV24R68ZXq +uq8P2m6KqZwQ0suwDDO2HzkFnIuHMU3Ty7wK5q+gboSPOm2lAoGBALXKn72fGdXV +VMNLSL57TnZp/hLZuDGrjJlBuXIx+SR8/3+0RzkgaJ00IUnGU3htpfGJsZi9j+BM +M4B4wI99ph6SK6jrIqy1myBUsmiKok+vSvrTQyGinE2sZJwFyhnFXKR5RXEyWzag +FBnTkfYPyYHUDa4BCXlh/RNLnfhA0GIBAoGBAMzIg8nduv/qWS8N8HZMFDu5PuDq +bjK06F0rw+6ZHa+6QpPbSxSzKQ0y76SQ9CMD0cu5W2RvAzClwBH7zBAhtKvjR0XA +jqwOmdM4LscbAqnqpVHNDef9Kz/styTezEqgc+FsL1R5+S0/To9avRCJopxJ9j6C +L2kW8jO8qkdmoFH9AoGBAN3Mn3aplSxVg/6mIwRk4E/BPuY1GhZx+Zqw/4og0Joj +8zX01LJaJcDxRkWnJVqfQ9WP6NDTUJAqKaOsFIvBkEOCPvny7MLptkAESG352ijf +kkgTe+mWXNtQcYfhnk8LOBAIbnR7dFGEK/UKN3uVKl7mHJTF3a1mFJGqGwA+3TAs +-----END PRIVATE KEY----- diff --git a/test/testcomposite44-rsa2048pkcs15pub.pem b/test/testcomposite44-rsa2048pkcs15pub.pem new file mode 100644 index 0000000000000..f0fb3b455f8c6 --- /dev/null +++ b/test/testcomposite44-rsa2048pkcs15pub.pem @@ -0,0 +1,36 @@ +-----BEGIN PUBLIC KEY----- +MIIGPzAKBggrBgEFBQcGJgOCBi8A3SXogEbRa8cfYa7y/CYz1+E2sjv9jTZQw3PC +9Su8TtRsdivD/ZK/EFwBeDuGSBztOpbQAwOxlZDhXU+ZDmKcMk1GgUOHS/345pqc +0Qg/ncrvmFQ7d4ZJ3Beho8dQnZ6T8XenOtHJJZwHNH3kzUhw2zXBQmeg8gPNSiWt +TSQwZug8cdpN9AET0+HidQpS315UUMXUE8jsIfWb44I33oepd07dWKVxscG+yxCK +nRyOFKtrdJfr06EU1WAuOdfu3s0qGv2gOcbpZaWOMhNBrXA3/C2y3k1QsoPcBPxt +SDtkfTHDL+DpIC8lLVxQUjOxEmrpBqztTpJcxVOajPM7XOO0dJCNP5JfyP+hAtSd +MRAJ8ICtp8jBVzzifgI/HUeZI+ZVRGrdq5qeJaDP/7kV8j05v6ZLsgvj0f22GLCK +CPiTix2hAbZ3Jxs3eqwhUC7nBTU38nNkokeMtKUCex8uuelRYzrNB9TwihUAl1yL +VAGKTqEwPyp5BdO+2y9+UyYWVLRlpxWRFLphOvNDYa+NBwuKgjohHzVVm4GW/NEN +0z1ckhHwIK4+NNktzHdCVgcj9pvn8EvA6tkt3lJxdxW5QQNMM9sudgPTaSyW8vYd +TvzTsnyY0NqXWO2K2OdCoWTpsQJyz+iFAqE6PdbNtyVj3HJczTS2zO8fGpXp8A/B +eK1YmvUUGKBHFOTn3I1KB++IfZttv0l/TOD18WqefC73mZ9kBqGd9vsu6MB2J7Cz +ASFG9pENCU88JWV2AcGUeVMdau23Gz09qYr1P4xsUE80usjXU3bxGHCW98Pvbbod +nw70aq4UJ9xu/5BjvS2slw4EfyLxKpTVHSUkU5jWAWijnyWrjrKUsFZDmHa3/VCi +ykfIObtOa2PCvmocZRQlC20vq3SkUpOw0Wfqpj00OG1PeGrmWy+et4S2okSeWIGy +yLyDPQtz0LyI9be2AHI/IWBKtfRmKpkxnySDHEgvp/mavbHFX/ceUYHDR156C4fJ +KuWKtDoEvZLb1l1FBzT+RofaUWovsiUBgWCRsWNhUCPqdhAnu+Q3XjffWQ5fqYxE +Y2h4KnWlCLrxPLWQ20Ov8KIjrRgE7ap/6RUSShMJ17i6cBLn4OPqBtZ1t9WJLYJ3 +GBqDKoc5fXIz3cGUAhtmf86kEy9EE0y5efRfOvlqpHuhcumKqcYwhHblmsyzmOng +5d41zTfR15YFs0skGe5yN6sIkwCK7SeQVc7u+P5SPk3yd8S7soxQ1GsK7U8GGTA/ +O7SxtlWIWvkHSWS1XCMisCwxmIUaQgwa5q9iOskXLMDyL2JKQaaChZlRbAqiJaoi +zjcpEj/NhtcCFgWnZmDdo5R7hFS5vYLgd3HGdl4B7Q0/ZocBi6EZQViC7fmrSlPO +kzXY9sRJ3o963iQbZDrpSMpojnLNxMiMb1qt1FttrWV4D+7wvyqBtKh5rBEUUx5u +iJVxrlysZhEJNjGphOM75GIfwkJEZt8JQg1TIGZ0BmXD4Fe+QYQnNVD3eMvGuX8X +R38BtyDF3NuPc0eHuGnZ1wkPdudgE36LjLxPYtHAauI5eQuiIw9YzmgJCGa/4EXh +jQlOC493IEv8NK7XCuT611KsGEFhTV/0u2hK+w0hdnSCaeKdtHuZ6zoyuTXvTqWo +8R6LcbtY26dnoETe/kfJr0d4UXffuUEJm/I6PIkkoJjn+j8n6y4TF5HDrBlpDmqE +PxxRxDL1fK3naXy2JmaER2eAl5IuZ+XwvBQmJYDdlObkQeMu6zCCAQoCggEBAM81 +VF8Ya2LgzA4M1x4JApfgrIewFZd/eQ+rROgFzfqMd4kigQLH0wGcaONJaFEINdCW +KQCK67FBQDc3EZJWRJDUr+/xcX3XCn0c4RdCfdqES0LMoWejAbKU32X6vvX6ODdh +wS6hSeplZmYtI5IU7lrDo+JtkyEWumFuxgUrK7h77IP9RFwhMn+rPRCiSkKtH2/H +j9MqerJSUm1jliwvLm3x+fwxgrCbA4CjWVRY2TcwM1RGFHk2+ugwVMkspdLJrKTS +C/tyxK24ehG+lUHXBRzmlXD809sxI3uUosnuY1VFT50jJ2IIM2egT5gdVMm6o/wc +3e4def6PvTo+2rsTlKUCAwEAAQ== +-----END PUBLIC KEY----- diff --git a/test/testcomposite44-rsa2048pss.pem b/test/testcomposite44-rsa2048pss.pem new file mode 100644 index 0000000000000..9ab7f12b0faa9 --- /dev/null +++ b/test/testcomposite44-rsa2048pss.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIE2wIBADAKBggrBgEFBQcGJQSCBMjOXgvZIi/HU4oTpwPVNcRs591xxvpvl/T8 +HBg9dUMNWDCCBKQCAQACggEBAO3IyFSTUCF1FaKeBOGzosGseFblxEQz/bNcycc5 +FtCbV04yoL23HUVUNh0YOZ8sVPC+VN/I7Sp3WBTX5UnWl4Qz5LWf5ixsaZ70qooq +lALmzuyduVx7JEYmtCspj80wfcgiyaNguFq8lGkY1Fbi7VdIwqzSed1jXaW8J4Y6 +9eREcHT1vgEsk/ORqwZ92Au6xaas9BdWi81BIQxF4etVm/qTWcgt5RNe9OGusuLB +slHXWTKIN6nOHxFxJ/QogY+l+A06tnN31B6hBizsRn9XD+FqWq48WkcYdYlt7GUX +x/Tfs9HrXZpnObRg3fIkaIST8dWKuIKzbeHB4lje2TGJKTUCAwEAAQKCAQAaio1L +MhrryR5jmuDE8qCe8+nbb+Udjxy+hFkPcDYK4zP2X1yldcbXd2QHkQMphbDAzcs6 +eWUjltOm6/GaHCZTFC8Z/iGajB/+pU+ogW0o+mtWv5oyPO/abAqIliiIyOSuo1dq +HEB8/Eyn2HonF/L8XvuVKnR+JiUMpqOrbhxb4KKtvVanTpb3dzb9CtMc3d3gS4cV +dfVAE/XChWJWNI64FebpVL/C2/oIkqXzqLvelWj119+YWlVC3/iqKGciNqW+b5zl +Bu7YWASb58YqwOL91ZTIZbiFEv95JPZtY5xkbgYdOHnFmhrxJrx+ADG0ez0hXCDq +8onPx53uRPs/JyW3AoGBAPsaAVg3MHe7tKVdfghazSRfYK5W8iSVC1Pn1Xd8y2AD +86eolOrvj+vCtp1SVvUSQd2JTfOEamffMQMY6RNAHDZ19eKd96XWHvKduLIPEzVy +f7wLJVJGedqGARPgwKWt2KFYAra6LsC4ZWEKXrrurhwLP1VinHdd8EM5wPD1YsI7 +AoGBAPJsRWql+LHD0pnOSbkJTJUimLgbQ1wbbjDo/+RLsBizOrcvD2HSoK/9pZA1 +MCfCM6UcSzHUWnwBW/DfG0sbUIcmndncKugH+w16h2XmJX9cVMf3xJoBlNETrtbo +ELrjBjaW0Wi5+XkKG80u6ABxjn/NV3rudhz+SgFqweiUiRtPAoGAJqXXBSPhctxS +Lo2YQ2LuZiXD9LFvLZA/IRfytCRiDRIuo2SAHzTmGuxqPQaaWbgIqTdj5xI/amNg +4NApt4vLi9pWER4tKrotIzyBW+6UD0rjPCcfBG3SfX7YlZ2nKRj72cF5EXTQk1sO +R4RYFj98TtawVc0KthigTUiLWMr7+1cCgYEA64rxo57h1e8bqF+8V/JGG72Cv5eV +yl/In/Mz9uDnmAhFK4mpG3YotPbxr/1N7cOOpIWqNh9LT6OObqqIfWBrzPVjeDOo +6MwgTUdZWVPV6TqQEb+WocCZlM/YGG1hHATLm6zMiUHxuH5u5t0FhLDRMTIWJpad +4qvcwiW1hMMVuJcCgYEAg4jjqOxOIZYYA1JQK7Z5IQGIPSm8JPlQl/a6OcYw1aQ/ +4zli618syIvSkvmdfU4FskEEWd0k4JNrb1QyMpjufcnzHNgq8M+QzOmBdehMsrlD +P/GTFkbjhMiOogl6fUZ6Zpgj7N5Ou7TKOTtzZYpdw4mnQuIIPQjKlW3aRcZB2EA= +-----END PRIVATE KEY----- diff --git a/test/testcomposite44-rsa2048psspub.pem b/test/testcomposite44-rsa2048psspub.pem new file mode 100644 index 0000000000000..856e5a465d557 --- /dev/null +++ b/test/testcomposite44-rsa2048psspub.pem @@ -0,0 +1,36 @@ +-----BEGIN PUBLIC KEY----- +MIIGPzAKBggrBgEFBQcGJQOCBi8A2ehI0HnB63KVOyApHtLw7PNkq/xjiVyoSREQ +L1Zj959QZFvzde+VY1PWt9do/jcPnUpat6gJn7ngPKnYb4a9UR8q5e0u4O0qe3KE +aqa8cKReH8ym7bHwViq83XDRHAIBI3wYHJOxvixA7xKvbsQbTWtSIKqtd39aFJKK +eiEm8OOMjv5Y45lIQPcK2EWanwh7vxBgca6+whz3AGgax0yDHl4e2HcD0EHMh0Ot +uLZOMEMCJnQd3wEcn6xcLy9Q4ZGKPv0B+xuNKGcUrga6dE4YTdLXNzSCwxR1/bph +34k/De2ot7YpbBMTFrLIl2PCWIg8slf+aqjEiIepgyS8tvf+6+ucv8mXT/4sbSqq +CA2OUFkvIBtIWh/b+HsBczDPMEKVREmk80E0KyI5DLoJnrEG27EZL8UcY959CA/5 +ustr+xED/O/3I/GHmk+ELW3o3fMDselyCE4tOmLdSk9jdMgZqD9nww93+kBZOqO/ +OAHwbxC+ce3c1NWiLoxZlWkiatkZAM4jw4DvW2dYY6lyHKRgc4TgNwP6JjFbJ/Yi +QcNtVsyRM20cOVULzK6SqBnveiAFzOT5Ss11e3z1WJs/aAVihdryoD/SYm+0nMqO +eS2ElKwvHzifMPjKmrM+zep58nKFuEA3jO291sVTjl4sVYccxXixg5GpFyNG5kpz +81GUPJdz8ZVBgzje0SSlmtEvv2sMagpsqb9WfBK6gdC6sWTHAz+6iKKTq7A2Odnc +DdARLuw/zJkfZFhuAajCDz5t8u7GcZ7wX9FTlvOkIGoOm6FoK0N0h2Ko/TUv+dIm +rJLnb3un2L7pcr3z1vvS3yoDm9ZoYC5Z1JxQHuYCAy72mTLDjBFflvOEG63bVpik +i+CN2V2BJrnT39h9TPYEZSbAnsCB+tk497OEbS9RjOL/mtKRvXig58LBeV1EbXOL +OcvKku4CpgORfzpyFvRKwhDoIztoSPNkmO7zE4rjNwM4Gaxuf4o66USAZ/Z8PKwA +8XmWq8+ybzm/O1VLZ1rgyo1lQstkgcTFO/IpFj6Pb67UN6BQLC9N4NyubhGHnUpA +A7GxjJhoGkK/EgOdBH6rZnATFuflbckimaETyjyLeE6yOjZJosWsEvYvuIUSJEDR +7G9gpvhBVV5lsg5dh2Dey56KzIanG1uFeAFSAv/BQKyMrWLMW++qWYpp+AQbyLNv +34f2X7QpPJh2oHIpVuLXP2dPdXM39JXoRk0DbXL2DY12B3u+ZCUjzL79GwjiAgw3 +p+pb63ligrhgj0sAd/YuhroPJxmR0z6vTPowbqaG0HLMsS7Kl55UHKMKdsrOrJkY +3osWfpE/txjpTZbJTBsVDAENlDcEf9HgwEbYCWemwpnZJvb1csMuqL1YAUOIuxbY +rt2kpyEuWktF2nrzrOAcQj5h7s5I0qfaoyHBPI4RgF5QxeL0eC+0SYhlP+cM+pZ9 +fMfJFzKWo8jZOPKBpNTnGhK/P4opbm3C7UERxJU/cESGlK+Ta9l3e1EqQa5q7dlD +ilvQrn54DA17LboDEd0o7yecsKz+riV1UK8iP8I3UBqlL2Gyxfgq8+uYQccpTbqC +M5zHu/rziVtuY0YyCxVe9XgA0WPgAEF3dizVvQ53YPmDLEmNrY2mRN8hvMoSD5Jj +8iI7fOwdgxW6TLTLAm/6inXAD0iUN8oVuIAGzdoOmKm/aACh52Vh23GuWqfpJepa +TNoVlUJTwRwvj6y1nu23VnBwXUXHxz412izlIfwNgZIed0fDsDCCAQoCggEBAO3I +yFSTUCF1FaKeBOGzosGseFblxEQz/bNcycc5FtCbV04yoL23HUVUNh0YOZ8sVPC+ +VN/I7Sp3WBTX5UnWl4Qz5LWf5ixsaZ70qooqlALmzuyduVx7JEYmtCspj80wfcgi +yaNguFq8lGkY1Fbi7VdIwqzSed1jXaW8J4Y69eREcHT1vgEsk/ORqwZ92Au6xaas +9BdWi81BIQxF4etVm/qTWcgt5RNe9OGusuLBslHXWTKIN6nOHxFxJ/QogY+l+A06 +tnN31B6hBizsRn9XD+FqWq48WkcYdYlt7GUXx/Tfs9HrXZpnObRg3fIkaIST8dWK +uIKzbeHB4lje2TGJKTUCAwEAAQ== +-----END PUBLIC KEY----- diff --git a/test/testcomposite65-ecdsa-brainpoolp256r1.pem b/test/testcomposite65-ecdsa-brainpoolp256r1.pem new file mode 100644 index 0000000000000..13e3ee3f57b22 --- /dev/null +++ b/test/testcomposite65-ecdsa-brainpoolp256r1.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MGUCAQAwCgYIKwYBBQUHBi8EVNG1XuOM17P3S9idjhPr7pu94KcIs7sFNNjwwkOK +wCPgMDICAQEEIEJXNcix5Dz4WK4G3BdKU2miRY5vc/TMq8lq4oVIljhboAsGCSsk +AwMCCAEBBw== +-----END PRIVATE KEY----- diff --git a/test/testcomposite65-ecdsa-brainpoolp256r1pub.pem b/test/testcomposite65-ecdsa-brainpoolp256r1pub.pem new file mode 100644 index 0000000000000..c799b30cdf0ad --- /dev/null +++ b/test/testcomposite65-ecdsa-brainpoolp256r1pub.pem @@ -0,0 +1,45 @@ +-----BEGIN PUBLIC KEY----- +MIIH8jAKBggrBgEFBQcGLwOCB+IAwssdW/Ua4ajgEra1JPrdotfDrehokrxUjqqD +i01uQiOdGKM0b6O5QU3IVnn7EVCg5q/1mdNInPzBBp/paODPA63VKS/5XRkeV9Nm +upzf83RHP2Pvi0Q9pef/bgP3YJnnvPj8mLcYqUlR89Q23Ef8XP2X+EHWOQuMG0A5 +9mCuaRLHxXrrO+ABr9Z8Dcaqkvtf7mv0d7G6oDcJo0yJ3Re5q85PT8pndCJQFPjW +9Q9i0Ow7GzThWgPKE7tHh8XfCGbmC5YWqFplXwA1pKODF6h9dpwHbMPkfb15Vobw +Rz2bHeNujVuwsvrMN6AN3lbbvzwHq47uQvKdDLpCHkFBq+cg0hgMKKVidNVE+1jX +79eX9DTSPtg9jFELOiq72zccv37/EAj197FHi5jErUScscFThQ+9mI+mHTLkvu7l +Cvno5dFiH9H3nqpkk2pXrN1i9hLDJchpu1TTgCjzjQZKZN3aaPvEynD8wjNBFZnk +R9vz2nyj+reeFN+M+IY/BNeT1VnPaBUEAzBP9v0iKyHVITkIHSxAcLvNGqLG4i/e +l6EGdXeaFRg28EhIlKFIYyWWH1HkmcvZAkdBaz6k28P33haMxv0XT/8OHopEX6SR ++RV/xVNE9/FboN6tNJTKBXum3fpO84EIL/dkgO9nGRB5aF1X2czBK0sbZZjlZ02Q +4k5O+Ud0NCw9VL/4kB+S5zBGICw2HGhS8HporLavrluosaBrStCJYipxyvQ/GjTI +zRfi0PE6Uax4Ttfkxk/8zyPGz5FwIjSEEjUZuaLfF4xtgEQK8geGO7gIa6hrmMxt +rxQLsjVZmOKVZSYwpmfKqwTuO5XeQ3uTRfnK6XYz3a7zveUtDb2HWywlKBhGCjln +L9xNU83kpHilggqSfOtW7MkyXLvpb443dMdF0UkkNNfGF4hE3ckFS2rJTdxy0Hq4 +w2dsWDG8WZWuhLsG43Xr/XCdKSQ0RUAZh9CDn48+651KLeLlt1HRyr2Oaa+UfQAr +7nelLI94eHktRS1qjxN/4T87a43oJku5kTXPYOVlHtCR+/o+GM7JlTSUgsgXDUPD +S2ese5qdmJgU2OANmkVvwIOnaonmSrPwGh9mg1Lyum8GT+05zAgDzppyzmtZ6fMX +vGuEIU0zz531D3MyKKO64p3G8u/u0eRnvMS3+x4OUSiX+g9wST/2CoC1RUE6yQ// +pEVlKNEzF5o/5K+cxLndsl9wIHicfSLMlG9fj8ZC+9fWIexsRTYQgmeKN6UDitkq +oI4VPLf6RKyEq008X79hAL+WXt/Gl+Djtj24Qr3DlIreI6fBJhyi6nAhAyecyTd2 +VAiqq6RULC2bc35zWI1dU6Q1jdN+v+9+wLIEa+Jg/QhyeKYDjcvF6JeJRMsQsQs+ +UPJYdg1rc/BwuJqPawbkASHrHpK24qxMJrU8+UGXkzq5JCv4xFkSKqdEohMGjR7n +j2YWZ2kSF4XbK9tU/QyACteGf6CYZNgYDt1o0E5s2PV9Yyss94+WAk/u8O9ZtU3Q +o1VFDf9rEdnzIXX9gTpKvyc/tCq0gfgCEpVKciAnZzmGsN0GjCK9C9k3XcQ6cIB5 +z3rDvcQLOUFjxpujax3s4zLcYOeosxDbAZWRccgBL5OK+pfoyg81lZnHVj3LyP2j +gnO6imwu6zRVohoWkKHdkNXtXT8rCB+70f3SsM0PH0Q6aErpgzrLXkOBX0TVkJHf +INtoyHryhJRW+LdpJzONcg/xL2eJvXmi+XF1rF4l9Mlyb5DguuYhvlHvutAgNbe5 +xKmOpiFXHdRgqjsaN21kcpbw579WjVROCXa/iUXw+JPuXgd5BSJmSrMkLTu2JzSN +T3jYRFYWLYicMb8StwJpNJH2DZ0j+GSdOdVjiVluNO9xkBtncY2U+QqmZmpIDHBo +uMx/Xi/T50ApQMRLA+0VEHn+qTvmBO1h7GNhWYf7sQA5HSkOZgLUgu0+owrBygpe +qv5AtcrOqMJUrzv5JkFIUMwUfhu+MqE1ny0ndikRAL4ihOg1gp4+R/7ikqIK6fMQ +8Fmc5j6Ev9YFl5PLGY/yk+YQ6Q6fY8jAs1geyygTcd6qRWxi2NoKxliez2X0F3m+ +CDhhfocGW3Udrijl9bNg0YVZ2OWUnvP0vP00tXyaYVBuo3Y1tacBc1F/HDEm6msU +l+TcGTAoocDrcGCih1sf5Xr8r9bMOQhQRZVFmTlDT9fKm+Hwq54DPHMz014fv373 +3XjmIdjzjDar5BQEWrlEPVCC6/yibJuwvOkt2UF076v298QfF3B25Yvo1oNZfvGY +2lhbH89r1e0XcWEbEB4/OM4Kh10BNOfZ9wPHaaIuwUFh4zZpvb/Unfpcp3VCCTK1 +K2qF7SR0hvZJCPjGjMl0uTMlKF6tKRMCsPAjuOuDAPY/yzVrPXC+xHgPdgS9oQs6 +FZhzauCsGIA5KCYBSpCZQbs11rMkIYI3+L52Wqb2SsN93YG5zkwWdL0/+gxtLI9K +PTH/d3HwlSx3XuYb32vs+wdtwb7bmopfSIaIQdpdtmEhwiiMyk93s3yifX0nyFsi +xv4QjuAZTlN3/X758PQHw9GTw+aEIyk/cIi1P52s+B3FQkTkUuFbQNJMFcUlGtdy +AZTXHsEEUA91jY64eGFmTOgFADgByzYxMSzUqSoPaPfA2rvvymZzSVT6fCPA1T1t +n33BD1FeP2Em84Vl7QBy0P5GAfOfDQ== +-----END PUBLIC KEY----- diff --git a/test/testcomposite65-ecdsa-p256.pem b/test/testcomposite65-ecdsa-p256.pem new file mode 100644 index 0000000000000..24bba78717156 --- /dev/null +++ b/test/testcomposite65-ecdsa-p256.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MGQCAQAwCgYIKwYBBQUHBi0EU/nDBrVgv/y5KJKgd+e+EGN2Zmdz3WEc3yb5DLqL +++2DMDECAQEEIMDetfQjXSFxs1cKNDm+paQ93MYJbGaKeaEt2JerKlhKoAoGCCqG +SM49AwEH +-----END PRIVATE KEY----- diff --git a/test/testcomposite65-ecdsa-p256pub.pem b/test/testcomposite65-ecdsa-p256pub.pem new file mode 100644 index 0000000000000..bd23a86a94486 --- /dev/null +++ b/test/testcomposite65-ecdsa-p256pub.pem @@ -0,0 +1,45 @@ +-----BEGIN PUBLIC KEY----- +MIIH8jAKBggrBgEFBQcGLQOCB+IA57Kibw4Q73lz7xnauW3I1/nEg/teTrHrFgby +TZx/VwqlMlCL+gPYQ+uXsVcyxYBVVME/l+iH/44fijGp3Z6pOdJB3OfJ49KJ07xE +tT52cWy1y2mlGNhmhYdXbzKNIBKVg5QvcU0xNn4I/iSoo+Sx2NiY7X5Q/i2jeD02 +PGvttwBmVITsqYXj3pAmpRWgwO2RFAsXx50ni2SAxiWr8ogGpwWe5WCFdLuWPlu6 +R8LjpxWjOdjLwkfsZsS7+A4KBc+wJQdLJa1Q8x75CCvJ0511we0Vq9JW6fIEJGY2 +2ZL0FwmyMjt58HSfOfanlSkAvUG1atsp6cmp6gN+ntwnoqIYA3xIUbYzWbVBbzx7 +RgdQ8pn5MTJB4xG+Tzy2S3OwYjCFF4giTmmunVsOFn99KWHhi1zyHuCVTUKmZ3+Q +GaYBIbAJkdNyNZ/f29g9du5QZUp22RtSK/p7tPs7aH1EYuTj9DvcRUO86AYWqFuJ +husW1MFvhOI/HXKcd5VQvYinrkn6wF2u7I70WHsq4Hn7kBJnZqylG7goLWxAOPtA +lVGg24NOhlrVGEUezdDGqMAMVJpNRmaC7rD2EXHNMbljW9V+HGVSP4XdpsiOuqic ++DxzgqPqmgWf7Q6hdIC8s5mLO1wP2fw9OYTSKXG52qwmAAUzpnK2zTVNVA2KTFkV +B1N8Dv15NnYZmzbSKkiA+rF6RW6buJifYQ2cd+6o6hg0EkyAADaJQYgpfbgyoV4O +nMsQ7RKZy1nCEEyc2YKMQXQqQ93uVqA8KSxfz149rkpo0YLZ4X0wL17C41dNNB7c +p86ysoWxdDwWrAcX4oU5YQGwmtv89bN4JmfXKhuTr6MxgvvukLCiDx6gEgGMS4Zi +2EVI+ZsGbtBEkt5qr6ajkqqz7i5bMu4hOSkiwsIaLrfd0eprjmhRgP45WxYmGS0r +MbFYUWsHcNmtJO5i0oFJkdQ0ASlUCsUgtsnBLZcXDumqI9ku2Btv1Md8NZWfQNas +CUQoh46NX9aNAqokuDDHxsg+7iSdxBue0y/Onf1t00twdXDTAzMmSuCLUav7gT4L +xj4xAFe9i6aAnIwlSOYUb/uocqY3DZMqg5rJzef45sOg+BwnQmNdqr9J9hCGqtnM +U9cZXMiK0r9TOcSBgAGYISwh68QPCNvu+8Uk1dIgC58BLbqWFGNsjq1OWr1ES/I6 +c2lxNYHLrxnvyHvrZ5yUL+rZEdGcXYX1FC7tWluAntIe7UhJN3X7J6mtnN45cpqh +guwBvH4i/VxxCwRQxbCq4FeX/1RxgifHGx7p2tsfD5mc51tX4vhVVaVQ1sWdOfu3 +W4hQNOaefC8Z/Z5r8vJ2Qm+od5d83H/LkqKf/crLPrpC6931sOpBzpM3fT1mWlSs +P4nahCZ2eiZDZToVAF65iXYnZnEe2Iz6Fz7oOGZTX1SbAq5/zH8R5uVp+F22E5Ov +tVUh6ikyHR4ryzM14HXY0rpfxX9WuEZmL0KMB2XT7o2y0/h+X9Tg1fG6SIQ1zfgE +UTTJyCjJgAz1SikOy1HJlqerg2YBkrugkyFtE9v5qxMeB1Ppaxejtrr35dvTXDJ7 +kBWbAfJItGT6zxogpgqUnGFaCxXNs7UkdNDuVppwd2NJBGtsJhd2rct1hE3Hzvy6 +4u11qeVYkvIcV9piXzTxhSeO3TN15/T+wswMuguWK+gLME/H00fYTIosoUMlxOAt +dos4cO1nJcMT8skTqBvXH0T0F0J5KTUjhkeN4WEdljV0MO31i/KL7KOqRyeJI8Px +xrbZIfmTFdd7WQDcMDCkZnaOYGFSTyG+nspdmGiaDAJ/Ru58S6BotC+agj6wZvnN +D4CBNikYILtgBvmGHdYXyNI1xTG54kKeudIcUTm7NRxJOkFgka+kzAl6IwLVMPmi ++WXbC0mo5t4SukhnszFo2ubDrR77TABNuslQ1eZ8b6UA75/w6toQ4KeGb3+gwjO1 +Yzm3G86E+fYo3OkYCF8Qs3miQftZJSVLTCx6Wef0VR9ACY4LhlEUvE0iY1Vjmx1e +dUsOaITslPJl57IBohNdJyp66uqT6syZLjS7glmWF0lNk8gclzP62H0tPLO5jC2l +7MkEej6gZTtmu2yc11nDTwcD6On4NknHsBiSBLCObdXfkMeoQ18X3sYvdjbR6omF +aKwxzqrwTDynaP60cj/05qX5lERnCfU0dgWBu2f65TdXc9J0dLw1skDM4XKrxbTq +tYGiFfh3V8DfJbVE1wnnMM4xV23m/TbSX8lSWY4OGLsITuuk2RG8pV26ib3uOueQ +cqIv90tEGP6JytqD1mtRYjcFUwWnMf2zHtdNYSBlxNypq2fPlJiWIUz3bH+fQ76r +Wij4gyvczFriK/oEHEU2U98QerEJWNqy0+2LhJL4BslOP1T3FqNIAcKqIhmY42az ++Wtu/FH8QMaAZxBPLwXHg2sfaWvACMLpVWi3EDn7S6QCg5OFiY2nFmmsrIOQ4o2n +OxsyDZmSQy0BfhbSC4jcmniVF3v+DYQg0xzKyba3H+LSFOsmP7cD014hWiRmzAyI +lvnzIulqkK8Czatdtq2PmayRPPi59uxgloQ+kSw3tOWUYcxjI7rRM5Ecp55xiXKD +Z9PZRXIEel5AwD/hhW8cMF7rMVMZt3l3jSQEk1qjfI894eQuezWeDR6VunA/8lML +0GVH5/ePr5CnLF54TjyITQc/oorR+g== +-----END PUBLIC KEY----- diff --git a/test/testcomposite65-ecdsa-p384.pem b/test/testcomposite65-ecdsa-p384.pem new file mode 100644 index 0000000000000..5373b45b96c7d --- /dev/null +++ b/test/testcomposite65-ecdsa-p384.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MHECAQAwCgYIKwYBBQUHBi4EYBQUS0FHbZOVosG59H+ptBUVooth4pX2wyRETtFZ +NPWjMD4CAQEEMOp8tWTGoVcSmcdmCv5x99odUPn5BkB0UGAlomJeNYBv5vOuVj6b +wtXKdz7lHRZjOaAHBgUrgQQAIg== +-----END PRIVATE KEY----- diff --git a/test/testcomposite65-ecdsa-p384pub.pem b/test/testcomposite65-ecdsa-p384pub.pem new file mode 100644 index 0000000000000..37b80b5786bd0 --- /dev/null +++ b/test/testcomposite65-ecdsa-p384pub.pem @@ -0,0 +1,46 @@ +-----BEGIN PUBLIC KEY----- +MIIIEjAKBggrBgEFBQcGLgOCCAIA2OMGI8CocRsHi4DLp2+MJj7nm9XSKnuPPLdw +WJkf4LxLTRn+FSyL9vZD2HEVOmFLWyjPJGDXRREdq1p/cOco5HzXsEAnz4C2MmF3 +OH/l+xpk1/n7ExpVfixM/AAxb8q/r/uVJbAUowIdMyjZCo9d2YrkvYlD5Rl7Mfi1 +3yt8az+ELFbbu3wOSb2cNzoEwO24D9jy+6oxR6rbW9SZt2bPv5rHKeDas6gGM1S7 +69Yg73vzcRBwTUj+HqWpS77RPf11SWdXpQF3PNiRO4NqyBkl0NGW1N1tq1vK/Qzc +A0qCgXQuBNl2OHOPbECBM9B/Z3f7urb18MxBy6cScMB17b3yRztYzQAHE32/KBOw +KVU/zDsAont77hGuP/IedEkGyXiRfPwL0lWL+khblxMpexEo/S4zZsYY4du/K59q +UtgXk6bPA2cLEBMVnvgsMYHyas39uDzJIPx1/wnFRpYWK9Y0nmEmUrJx1ml+tDRp +fQBgVVe95IMLlDgMSPyVFJPKx8sUsILHDj4amVXcvDHwK3/LtK8zxmPPoAx+ZsND +oSL5R1fER/wTHzLMRR/ih6by64rQY1lK0dw6b801w8BObVIk3Ife2stcttA59suw +ld2iwMrhLsGKgqivjQkQGvQ9nczH1quOQM5RdOPJzpxVnnaeGUCRjAN9a68+hgWX +00oFNmHIkZ/kQCJ2IIPJRgBWkYfJwXPGjDfKz6t1Xms0pGWrYG8g09oD1dXGkIIr +iFn/0lEv+6KcUmAN4ZKWIbPa/6CLFgyhC0kR1tzZEKU3Qwp6bQ31yKcfznHWK1cv +lnxrDTjndrua0nEyMGiZ99faX3PzJXVRWubHWrO4V6m0+0vWxyywkdBkMhvuY5/Z +6Qpe8nMjrRQvS0STgU7fIC92H6cxmj1WFHolkqpdCYHZEFSd+LHJosZD9ky95SDL +K8B0m+rLjH9IRg7Eme5QbUSbJNGuub37OM3Ydm4d+tzVB0XcSv0ie0DoH6+lpfGe +dQcL6+hWm4SHciQIvi+qLw92f+XRlruDWU+krAscIvnbGcVL4+/iZ6j5Oe1UVuNH +Y0MnFCxNtY7m2DZfrHdRFCXnWMKX/1gPPS7YZy0LXSj1vi6YLwKuXqOxA2rIIr9z +ZwviBlAr6ZBSZHscLe/cUcqgZl7RUEMKvSTGAjGadzkIEuBYEoCDfznq13GPu10m +1KLnb/qTDO6DsisNOCsM3a6azs7MC2UIdL7HTKlgtcRx2I9nfyQQeMHMUKvjDk8U +WXP3Jb0yxlc/f6wgWP5Qp6WV7drmHP5WbYHWXgSUY4s8o8TunS/6s3nmSWaXbSSo +OaoM+10kN2ImhBug+hOxnTmlvgFJc8MrXpQZdgJ/38YXsv1LX8Y/FRNdiScx7Zn0 +sTKABktUfpGYY5mf1jIXaMvlW5bvSsIcNZNsfKueNYeK8JV9Nt/XKE6Q10nQKBSL +eJcUqESseh+RcLtf9awgR9kogsfVP9vLDydCzXAiVDN+F8LwfZQlyIUaJWmLAqnD +Io5niK91n4g2kRUnswiGg0tgA0rs35K7s9Hkom57dLrySGYcmudH4JCGUx2ejHA4 +zm5OND+gUYh7xw8vRE1OudLA7wdRdfQm4IUZ1CI2+Kk8sRPEnd2hqhiZj7UB9fXK +6roe56eK/tp3woQzYoaEcTf3jvJZWpqXiJxShZu75ZOtcyDZf6wj/I8QAO6czzzb +nfWGn/iCNNTX7dUCHOc65hHmZSkpYlqiARo5aSLehcuOqUolrievy2W7cvEhsUem +rZFeaOoC8YBezYg8jZGZxMb7ziuWeP2kJMTqfCw+zRC+dFVRrHk/xH5cmnnf5cRk +ak5c9Oyy4ba+pA8YE/nZqZze5uqbkQqOxuhZe5y0NUKmcgJLNGqBrVnISkeN6RH1 +XZTQ95wuwxzyHFF51cNuBwOoqm1fuSRDx7ea8HAmHhlkSjCMLBy+DGpITnUOuv59 +B6N9W6Miq//EmiQPfEimCcrxqL9YDpz7mRorJVWhIAc4xtVOGxrOI2IBbCpGKcdT +cODpEYZqPvV95/BZB1R/JlmHQP5pyHhgvAUSLep5aX5oUvAH8RcDM13AKqRSBWnH +VhFk06MoQrXMGyGkv+o8sAWR1VkIacVeaNLpDbi59VExv0I5XKF34ja/EVBrAoam +bM812rL7iq7PO4EfTOKAxOdnRcXiVkPvF8bL9mb28aODeXdy7KJozq3CkiKQyadb +xRRxGWDy4s+6UeeyeHb3aQ+FhZW+WSsY+7X4UqUhYp/DytXZXBQhMA6q/nhBNwFJ +EIYlZq9twO8j+sGmQ9UyDgWnNPWB4j8p1x4SLYidwX5hsAQBWtC1sXExQV3rGPvc +APhhtDgEkP1/s/Cswjvso5ZI9V+RFPiyrJd3XAgjtfcMukA7n27wQjYDwqEr4g8h +WbC7wEkNkrFmuJTzprHSbvZErjRS3ugmzGAzAiDw1NP7PW0ogFo9mD7jpCQqqGqe +oML1BCaV5nUET2veNJ6H9bVsdUHUNGc9QZELo7Tv98dsBubu+KKuLzvAXpzyhL5s +1ycNpmgxQpXlxowr5sM6zGKb30a7k59zIA/X4+MI9IK5T9A8vL54QBzOZAA7TYRc +mWRXdUUEXeOTI2jAuRWmIovZygcG60G0Zi8+GSir3agqg7bNxLe40FTTVHVmFYoA +EIDTq47uHEB6uQ+JYTXh607QaI70SrsSLS/fFM6gmznPnKgaVKcuyGHNcbapy9rt +L/0TmsMn +-----END PUBLIC KEY----- diff --git a/test/testcomposite65-ed25519.pem b/test/testcomposite65-ed25519.pem new file mode 100644 index 0000000000000..b0fa025f68bd5 --- /dev/null +++ b/test/testcomposite65-ed25519.pem @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY----- +MFECAQAwCgYIKwYBBQUHBjAEQCnbTPaiuWTH/EbxKVia8bGahMqjhsMg0nIaVsxa +fLvDF+2lXRegZNW13Z5R9QBsqyKO4p/bpkrCU813+1r3ljo= +-----END PRIVATE KEY----- diff --git a/test/testcomposite65-ed25519pub.pem b/test/testcomposite65-ed25519pub.pem new file mode 100644 index 0000000000000..5602e1d317c38 --- /dev/null +++ b/test/testcomposite65-ed25519pub.pem @@ -0,0 +1,44 @@ +-----BEGIN PUBLIC KEY----- +MIIH0TAKBggrBgEFBQcGMAOCB8EA+l80e8PHgRv+GcG9xk9c5EvDu+h3t0+tMwms +LeJVuLDPJDCh5MnPcqa0MsVegR2E3Y3YJrytASK/F7YMWEkrU037mkIYHXAk88rs +UDjumMGiZlPqBnlW/7ksPjzDXbpkmlWFSD0JIdkfpYLudpieUvuOtK59Jxfa8CKJ +oC5hQfUYwiN4/m3XZVzOkrCi8urQKhV7TOvZgGh1WgSJgi3WLspYqTkCOaBRd+Fx +0S6yD44/MX7VGB8Njo2rwSC+w0waOx6zAPmQlPyQ9cc2ToyuDD8P15wjCWiNgxh3 +Bsplipw/rbyYw00wl93BlBrz7tBTR3Lyfz8Pcs4lfc9D0vXa70HiRAzOiNZqbf1C +dJNpKIp1zX6/fOxVf2/44QGZXajopra/u/nOWIgCvGV9F5KCr5xk+ekaUppqK7fy +3umslRMCLm0b6yuByyxdPqsZIeJdHSROhCUlhzFWJBEbtHtGm/VS6HX0byxETVfy +dnlSOuRT1OJXPlst3yBB3ONyVG0w7Xdhcgm3UTbuc7POSt5CFcNpbgA1Ve6q0+AK +WWpCvXT5gqh/0edIWEp6+LCXvL6/tUcYam5ak8R6+4eWXRL2ZMzQjreTbWBuDJHR +PbxxFwTlmeC2RNdrg9Ou4ywy2KHaCguhGpnOZfGxaGT3p9+Ww6bYWPEqitBcVSoE +YptcGvBG832MRj9+GRkoPcwclkJHF7CZu0e8PfH7QqZfSxKnCpxiirudwib50es4 +M54tWWGTtRC31I6kb8ircFWBa9mhkFylxs8tKlDq/+NU/SkUVie4zYIFrm52kD4y +iLmWv6p5P87tRNwvWTtw69M4VdnsKbtNA/NC2kpXr450pQ+T9+arfjiBxJ1ozWiK +1lqeenWxdf6vPXNRZHNrx7ZwQTv23nRqztVgSgWdLCM5zr/sskBD8r79RhCXiiPi +7LPrxvqYBn5zlTnrnsvC6nGWy2SxlUYjyUeEddns7EMj8hRnNrzv1GS9AxAsEOBW +R3M6YfEL6s40ib2rCwPoCoNnwzlWP0VrgEHybDHZFSG7eKplp6IMyKpE/jceS1iZ +FAznp0J2lIUljG6aUT98lDls4XxdDDmjgUZNYFzmWody7m5N12SbkpmrQvSJ0qxx +wgSdTNtyGytYlfuTHghEtbH3BKboVh8mWTnDLJEED/40/PIK5TRYTlCx+lvViYhb +57AX3Q7uSw7mQxsjAH3MG607GPPEayU5/DIJupy4XgdK+Ek3QuL+RTq2E7Tq8tgG +dGFFyEbphlmHMnHSo+86d17ocwzTgjUb/MvHMtWuFcyZb1Y/tuIaFD/wmuhsScx+ +wZD57t9YQNzZQ5dVL0Ji+akY+aBKF1k1zSom2j8nX9VZZ8Bejpe3iytOcPtDxwMP +3Q9x3ymgIXGH/ubSn5mQaEsrN4wu/uhDVO2dKZZwfPqaJJlU2n+L99lmj5AFm5Ee +K1m2mkMAfP0i8IWkmBe0gE6aQPkRaQw5rvLrsDwWp4oR8GxPMyYGmQJK7GyuhZ60 +/Wi2CT8nVXwHOnewFxOrZZUtMZIRYqPi1Ib59EZsU2NykT84/EqWqJUz/+BmXlH8 +vonuwHumER0jnCVi9iNWlqMJtESEu9L1XZq3Q6SWJ4K48fv+hADX1tP2V0o+hi8o +cBeKWpYugxNzynpHNd8R0YpYnCyq57UAzS8LXM0E1zOH9DhrhkOhc61O782AWS0n +xBw16fnCgmz/YyEgFf8//WL4ENzs+jXAqD5q5n/U0A+7sO35N4lmHKiWodCRLUwN +bcQq+WmmZwHwIKmt7gGsdpE8o5cfCjJo0/5ov7ScTUZLltEDeW2NoqMMp/q88DDL +/QhQ2IbiLCTEU/PDCmGEhyUTY+d+1zdNLq9PAnGn6ADhl6IldamM4h+qd1BqfdIu +V91806CvUS6cVvrSrqPM2I8wB/VotnMLRO8eeeeOWWiefAuTLukJbsMpdOQslJYk +O39l6fgZqsjOx8rilsNe3J9lPJzR9oIb1xAWt7LaTxbGBMjw7A7Ibw85HlfTvb45 +LeNs8pw8gt9JcoxXmxOl3KluVD2sNeJJLHsqjUkfKdNYOM8RhFoets8L4/cOF6My +MRdd2uFPUb7JJDhg8IkHwDxQnjdoM01HKXRWmuAzfXZm9Y7OL9AEPUbuttYOvyFk +PL+q3KEaSjlFAb0YU6SDWrOirQuc0okGLCLlKaHJysbSQMCatnPGtptS5EEkbn/U +IZ2xjoeFFftY2/TifqK0hUooC0y4HUkrgzOpoPwRyscmyjpDwGREFu7LLwBv98fP +2uxDPykj2h1p3teOZ2fJWanmjy/81djhit05Jbn6VThk2AUcukOHTYJcu16CtGSL +JWXB7XTGBuq6dW087PqG66GEBqZCYhCkxdxr3UccGoZ2tKG0hm3TtPhMBjbWim5p +SQYob08vxD8vc0+gaRApI/FyLzzzaIraZ8aA4+GbVbMMgRP5uNiFwbMYZWCwPqOB +tRhKxr25l+JEHXIS7j67+myPRJG0i6pvxwtyMDuVDM8qXCFo2cIuow1p9GyB4n88 +x5ZFdLDHnEEO+ukQSoQgBYNZCYerAq7eNmXEVWciW/Cbm/3NHM12VQCUPhJ7BvFA +36pH+FjxUjY5FkN5+iQmcUAV1URVxIe5obSAgg6o0Gu5ojWGEQ== +-----END PUBLIC KEY----- diff --git a/test/testcomposite65-rsa3072pkcs15.pem b/test/testcomposite65-rsa3072pkcs15.pem new file mode 100644 index 0000000000000..3fa117c5a58b6 --- /dev/null +++ b/test/testcomposite65-rsa3072pkcs15.pem @@ -0,0 +1,40 @@ +-----BEGIN PRIVATE KEY----- +MIIHGgIBADAKBggrBgEFBQcGKgSCBwcHukeyOris53W6VTyujtz2kclnPnqU8X09 +dD4LrHiXfzCCBuMCAQACggGBAIu0rV6M30WXiTZrPKI0OhCSjdMtiGXSskQo58mG +GW7+SW/pNNGSc36APK+Yhh5WiYOwf2EJKGXYJfqsUMTAE8qt8cFRNah11+O327Rq +7PIPcwHNZ0oLqvxYnJVLec7AQ1jsWZfWkXb9Q7pKQWNJF+NO+MI1Y07iaMi3LBuf +cHFMsfsfd/+u8taevP9zeklYJ1MebmYW7JdpaL3IAntHLfX5/Ks9lx8CCM4jM7D1 +5vPGe3S2mXosVOjQxjE1KkH0eCclaEsespgA8kZLMA9PCoj7nV2dUxqIYW8sos0R +FinL+hpdqlpS9/Ax9bV//TIuziSc8gptjfxrKXs/ENMkIXkvNWpBOmWTT5xM7R5u +m8E4nqBdeC2RbQhkfhQG1XaBI54qoLC5DY1BOOfmIxEVhsQ29k8bnrysiMjsjfDf +pO14yYClrKxBtUKuNFiC2BdHEDK6VKHfqEIkMKzP26M/R+E96o0FCETpwUgcC8s5 +jk8SWScC5LgnKdHkC/t0dtFBgwIDAQABAoIBgAyD0MdjCY8+OMGiD/Tx28UR89gt +QIY/6SNCTNKYi4e4tNMXH4RUlmRd0Cc6G8L0+phMQ8+UAUVE/HtSW2E8rv6INYYd +TxgPsm7I+3VT4h+kXaeVgxa2092LgeoShaS37sXfqlOimjZVZW9Mk+31JXQskLaJ +D3kzaV1C92sOuIUVxe3ajvvdwWLo0RfLJvMSDWJx8UQo8o8fwg0aMTViQM5DqNby +4KpGRYv9yvV5Gcl7CCKCRwkS6+pNOtaRTin0CyYsjE4axCCXhkokN2aAmybeuFHK +Y6Rl9QIBA5O+BVgRYd47zjiCxF6iNqRWOBuiEJCwj8esf+tOOyX9PtmsanKZlvOc +EbIMdnTesOulHB44/GDt2sSJ4v1NM8Tv8ic6GZ5ZzLWUyVr0/tLwgRNWfcg07AFc +g3EkEzkYc3liD+7QN1KtguKeyP6PnyGCFQDpqd5zEL8WWKoGgkrl8qITG52x+t8M +M2Z3QxHBi/5xH3tMrovkdiOajbh4mNJMSAo0sQKBwQDEuksTjRFg66ZATfbLSPBS +d8rWlDl3hUvpsbh7nxSP4Nx8yYg6aZBX0Gkw+WhMOgczGgoGT2Te/B842J1bLiZi +soJnaSNLujaSEGYI9aYBqsw84MZ8STIcS17xfD8g8pxNURBc5JQu9YFFTZKX9WwO +r1jBxRmR/bOrhZ1uP0kOnN7pYglxJGwiqbDmLnFknoyrW0LZLNCm/TM0mynK1Qyb ++N932Nu9kq6dOP7Zn3ct7/C2dFXvFZ/bPy/Zkiq1mlMCgcEAtcxA2b3SKx05SaKp +JcpdEX4FmKDkuT8YsReDZfM7/gTu0Iu4LcdeXMxEsokTqmQUGW0zDPq0ktH32wYR +faWjzb6R+oWXDkzc1eOU8WjWFz1qlRmQLd0A1sRIw8UqydsXg4QAByKymrXVVVAZ +Sr2qzT/cXE9mNvbhvQqHhAUrBCC91aYh1zi3OIplPKgdoUgPl3bxMIa5calXgu/T +bYU3BxOzbWmFkElk0b3UaOxIV2xa2nWg7gBLGu5/JCPDabYRAoHAK6SUgTrbbx/4 +Gu3w4TpGLlVrB12MvioxJCAMKEirXBvrbjebZDIFFqYin/3EmJyK+lg9fxbf7uQJ +3SeZCSBc3apyaZSWgvdFofPHXxd4A4irlJndDreCSWqjHnmM27dW24QvWBxRj3Vh +f0ltSw7kMQHPc/VQ7eVVlainu0yI3ZgJj8bzB0moP6xblUUaXNMbq+wsEVfy1gj3 +8iS2Ccxn5rY4hTLz1MOUv0Zkq0zIOMWxJhj683Zdp1sGN4NIvE8HAoHAV3rh+eUN +rRFy76wGGNk3z6MErl09sqZaC111LSnORH27LT8OcXjuP1lL9V1gyS0/Prz9Q9Gf +8sZ2rj5NTFjYabi6JgMCnS7/VS0eDsyTuLsk/no+ltMyBCaPnSTTYi67Md3i5Ywc +xbWZ4mOYyA5ckkeYkhLi7LAAECdw7mZOPL5EmvpGbnosMFjoPjfniiRS3F+vz9oE +gl0qbydYZeskf5NLU+rjCntGuGbQP2zzop3RWi4gMmaRvXPmWk2bStMBAoHBALfp +mcc5/xMlDA/td6SAWZsvFPqNEs3PqzAmKlZBSNAadl/55oCKT69NFDM/HTpna1kJ +I1k3ON3PFkxO4mE1MkCiygHNTEoPN5W8a86VKM84Zdmceg3s/qgQE2CImclxZ3K9 +voe5x6ckeYNlpSKUYe9hZdN7NQDmGNI2rXW5vKFQ3OhGI9exfeh5N95zy9UCV/Q6 +CCb+nV+B8f4CahbPl65hh0hLikhOPQHEiCLKyjJxTaomIFa9dc9SetES35PRoQ== +-----END PRIVATE KEY----- diff --git a/test/testcomposite65-rsa3072pkcs15pub.pem b/test/testcomposite65-rsa3072pkcs15pub.pem new file mode 100644 index 0000000000000..5dbd52a44f7c5 --- /dev/null +++ b/test/testcomposite65-rsa3072pkcs15pub.pem @@ -0,0 +1,52 @@ +-----BEGIN PUBLIC KEY----- +MIIJPzAKBggrBgEFBQcGKgOCCS8AmEkDL9MI9k/T/5fELkF2nvPYf/4ydOZ0NNGA +dEe+AgXYi52x7b+u29Eei6ve/1axp0r/RDuzj9TQ4DH3JSez7VOQYcODfVHUMwZ2 +ELMWx0y3O+0W1goQmnYfmEdUZKWcNpt6nhHWZrAbPosdzylbiCRfy65o97nLe6RW +ldtgJdmX1hfhxdSHSk/eOwIkHb+TzUiOvMxWvNXlk63U6ZRA/2MC3GQsuPa9eNWp +py8ukW6ZoNdGqZRYP0DJdXbP0pf3FjPq5IdUzSNtycIcWdfJDf4jyK5im6u/bn85 +4LIqMDOa75Te1dmLO+L6jJiswcVaXQq2AX8wHcNrBklLKgj4zHGYyDqyMNqTE8b7 +DnFSwcpOK3LvH/KG4+oLPjkycHSgdDLT55LEM/NOMzoJ5hgvrdFIrnqR/6yaKP4r ++Ei3WGBCf+gWhZDTnNEhQORsnJjef2IZjaATtg474f/Z2ru/edFi9/zcv5+bnAwF +ZcQmNjyTBWJNW9huTYGeD+LiQ8PRnnt1+4SQzRDNcTGBj4SrGpxq3926hbbkm4Pc +z6yvLIhJ5dQAhBNiZZ/JbiJY+EZ/EofhiCnNVG2nXkm8BpaHluYrj9i3Vu//j3OJ +GXPh2qySMx15bTPoxlzEZ0gwtE8EylAW55eZ3UuSXOnXwpYYQztskLTMLpQoZqYn ++kKUqraNURxYsxeXS6vAWDFR7Z+kGfXb+VcJLmhyLuwyi/mLWnI24I1ixzO4k/nG +KumMD1qmsc0G+ukk8WRm6+noXGpe/so+MkK/Mi0eedU5ewDvoxJUeNiFtoHeXjzR +K0jXuA8f9s/79dpvqwzEo0yjSrfsghZ1zaXdhZEnNwUEy5fU62VzMh7oA5tThJWa +yQ9uAQCRNghlq/+BqWwTLTKpsHcQbQZMJKLCaCIJDNUqjWAV9r+8xVO87ImBEfy7 +CPtMt9DuULjXhALgPEcFFnHPEkRdSTurBco+MZbdbYi+JZ1u54BQxMJUvwQrLYMG +0V5oddkTCCl5WKP7KIR4hzWfBGo3dZBoTMaFwBZ5H3MVl9PXXXPwVumT7stixtls +xc71Wh5fglPxK01Q+LiPbAkv334UKdln5u9h6Mh24jEG11VRGnaKYy+TR1pzUppd ++1tg3qVXQ6OsMI6UAiUPAmXEBmFLDwHS4WpIzpD3bsvA/K9Yf/RckKvbPiATVj7r +rC2Azp7UTV7R2PnZuEbXGAo89WHDnaQSIvaSrGux2RJZeyAq1vK0jB/IRz+67Hvr +U98xq5hgY2IorUjvY7MkqNXgJVfjmpEFCOVl81EwM4Rb2ek6UCbkd1qKKfhoiXF5 +VbjA1J3PXpwflWmBhGlhTFCTJWS+WVO3w9EW7viB/eylfoK9Z795AKnksWctmI/f +M5nW8FMPAuQQuPbBB8suVc5YQlBtt1FtOgRJZhXVCSrW2+ThwLjR8JvBjxc/XZeO +G5hgmCkBUtc6GrJfZxeOL8FRimfufD3XqrykPpToXrgKcGWqXPtJl2vw1D8QBQJd +0vLyQtVf5FytiZhlN4HtR4baENLJvUfL6K5t/UsF3FSLquPfxPven3ZEtdZYrv7U +Mjk3R6sjc1VkEi4nWRpYQT4LggviJA89bRRI0Bn+A3IyBdqXL6dsCmSgujVqiUT5 +FsDYLWaI/Vp/KMmVFfJJtqJR5KHU1YghJnhQ0U3GrSkx6qqjWGrjviVA8zdUgoiK +lz6hIuzHBksxT/jRE6ULyjaiKHKBxRCY0ck2p1kXkN1Mm2SI/RR8ZmI8gJ2lqMbA +x/9VlQloLSsyYXtfIo4bO2strRikPrsedIdFMwt6POd2WozV5yHK3k5kHwb4W1xS +jNHs7U0QQW2M11V5mleEmu78ty3omMk3w4BdgDZophKSNGnCGA6TSropODAF6RF5 +TA7nPLXoUz5QGk7Nb0PVuaJx9Y9+lQRTguD+bVnuMFXAg/eBy7Nd+7dxSFMXuN66 +4hj1Wz+dCgr3NYNWdHchLPXAjI8Tacaz2yR8v5J8Lq6RW2FOUoAtC/HUDMkxurJ6 +Fmq1npsx+Uuf9k3TKYKb0xECt87F/xG0bsE6LqSzDqNa5gliNhQWxjjbLl8Wct5g +ENCQP9NTxwq3XvRmMn0FjiNUwfsxH2DflvyNTIJuFUwvRaGW+ygteEQHfHgD6AEo +RHPUrBUVIMKifQz4G/vMWwqFgdZ54c1FEtjUQVrQPzVsVk5TDahi/ftwOLk5MJng +SvdqzkC7fXUR0NRbU80yEK8MA8h+19a48KtjafKLtyeGwsZYRhkpObYmYKGCJY9s +DDMv2KBmX9mRLslEhOOYBqM8L3twJlltej8YzvVE1AwWZoeylBQ7YN+3klaEFfio +mkXUpKgPwOjY/YRKXbS/bnxc06GrBk1u9MmKOiNwABQhCO3ffNnlcPa4xmMMDXfh +DyeMzN9K7lxzo2cU63+0N/XkBMp/RACqMyOhkMSs3QGJo1azfMbhZnMzKez2Q1vH +9LXD3JZthVAXxMFTA6flIXYSp3/mjwp93bbeCmOP8u7pMkMn/NruFbo+oEWT6yKV +r/xvLUmKABYCF+u1fdzJ9s6Dpc+O8W7TAA9upFbp13a1oyMpXyOeyr5PAczv+Tyx +W8ezqC8wggGKAoIBgQCLtK1ejN9Fl4k2azyiNDoQko3TLYhl0rJEKOfJhhlu/klv +6TTRknN+gDyvmIYeVomDsH9hCShl2CX6rFDEwBPKrfHBUTWoddfjt9u0auzyD3MB +zWdKC6r8WJyVS3nOwENY7FmX1pF2/UO6SkFjSRfjTvjCNWNO4mjItywbn3BxTLH7 +H3f/rvLWnrz/c3pJWCdTHm5mFuyXaWi9yAJ7Ry31+fyrPZcfAgjOIzOw9ebzxnt0 +tpl6LFTo0MYxNSpB9HgnJWhLHrKYAPJGSzAPTwqI+51dnVMaiGFvLKLNERYpy/oa +XapaUvfwMfW1f/0yLs4knPIKbY38ayl7PxDTJCF5LzVqQTplk0+cTO0ebpvBOJ6g +XXgtkW0IZH4UBtV2gSOeKqCwuQ2NQTjn5iMRFYbENvZPG568rIjI7I3w36TteMmA +paysQbVCrjRYgtgXRxAyulSh36hCJDCsz9ujP0fhPeqNBQhE6cFIHAvLOY5PElkn +AuS4JynR5Av7dHbRQYMCAwEAAQ== +-----END PUBLIC KEY----- diff --git a/test/testcomposite65-rsa3072pss.pem b/test/testcomposite65-rsa3072pss.pem new file mode 100644 index 0000000000000..88d3835d657fa --- /dev/null +++ b/test/testcomposite65-rsa3072pss.pem @@ -0,0 +1,40 @@ +-----BEGIN PRIVATE KEY----- +MIIHHAIBADAKBggrBgEFBQcGKQSCBwnFnTU3QU6Eo1HBA3vZpnZS71EKXFalQcbm +nixgMqGJMzCCBuUCAQACggGBAMwwvT4nUfB3q6M0LYONzomUkTL6GcUXh6rIE2fU +Hr5+brzFyUg7Q2mFv6ZuRI6MjfLW/NDxDOclCXFEED//RRbkCa1j0UFn+kq1d/iE +NPtGv9H9zS0n5ft+B6Ve04o/co/LZQ6v9yfucrAmnqBLMFi5IO9jaT3HSelgMLkt +0SNUu6X32/lvukdkBYrBUWsrm7RwhhQxpY8X6SNSwHOmDK9t4JdbJuRw9qXTbK1H +4bnmQ9hjhvxPUMyCsM3SJpaoZ7LOPVxndzx97TT/Pmh8zjT3gIytbaOdnteDtxsf +c0wZhZIt8Yugvnnx7Yf8A1O6/Cyd8YbogtX/O5ZvEZI7tRJidesC4YxilcCf0ciH +m/Lz1rfjDLqbKf/5KECLy0Y+9QJACoe/615aUEIH6gwj+z5wuIvn39LwWRL9HMnB +RKlJ6M2FoNKcYZsDFxdsZLNqExLjhWVbzdRaMWMgt3F1w242DAF4yeKEDr49t6GL +NosXqYE6PUSM2xNGGO0+DgFh9QIDAQABAoIBgDlwrIvDe+VthLcQgo0zYxqI1J/G +g2FSUTPVvL/EiDGGV5h6+zh6k2gn29Xxxw9isrvRhqUwajTL0nAueXPHV6Qs2hwQ +rFj96wcBLZKXfmABcwybnRBK3QN2XKhEmLWXS57v1KnhDmIJTfIHqy/kduE+kulE +yeI7IaupB4vQO7j4qSDzLMpqh7h1hqmV4FWJmu+Th+Q+Yxhx3X+2U7U0zPS8sCVj +2vkAXiIf676DLhihkgxZUyu/FDezvBDqQTi4fpLF5LSLNUrv1+3iM3olRB7E9lx7 +4xJPWaZQiK7VuLoVaRMQQuxBV/mXXSaNKHfbU2l9HK4Fea5mMJ99ChiFEArYYIC5 +jn6fzuHsR9X9EUavxvZH2REvjd0sARBSrNVOrKSRRukZLI3h1H4aDXzdksaeFMkl +Da0Gfxn5/l1TkJwyijgPfwIojaNg4MNz6UM5yfZGHe0d88zqqL7Lt/7f6NwTJhpx +c1xaiwwWOezBegLMP6lpP+R7bWifQTaJX582MQKBwQDnP9A1iPJMbjEMjqSqz4j6 +jW0mNPv8rETuesSrNaRc2eSjKcnNm7FyJL5aS1z9gJlOwiBqyJFtDTTiloZn00Mc +3ZBDM2HCn/eEuKqzDXnw2hBVp6ZPCND/gXSQRZYdieZ884ygA0efAH4XcY5Aoce9 +GAn9J59h/dvdwAkJsEavrD+5aH7NUsscP/RNwrexOve+deDCjfeNJtYZQRRrwCD/ +rNkvIdqBHA0bJqL+Gpa2gq/unRPSjbBls3PFPQVQSPMCgcEA4guEgHZLTzETq6jY +45pMcsamrnqr/3ILywLZ5UyD5eM3SIinimqGkw7o46yNmxrY/xD/VYbehuKZQi5H +4X2149m4mCyZ1eRsVPb1SRB/0xikI+3CYsmD+3+O29LwV0Jxgn613C7CMsruGw4r +7nVgKNqNBSTptXxKb0QullOP1enG7MPjLZAFFU5FOFoEOUvcnszJTihN/XXRr+aK +fdn2sQV5gaQdkVBaaiPwU75KkTtZXLlcIemW7n51FhVHAON3AoHBAMe2FcPWRKN7 +WsLkghO+bicscsJXafRadqGaxzSxfARwbYP4N/9o4cOZNgfXJDUOldgt0T9Hfki2 +6iByLRuHmWNZehh/TIOAEYy+yzUdg11dhlPjGL8S9yRikd9zKWTTTopE8ALVMkqA +a2UlvdvVnCGTnDTUvlIronGNQoDqivF2igY+15vNT/pSxVNOwcO/EGydcwGzB8MQ +ckCXMuKnqBgHF/4bd5CfQDZdlNBs+BIhJX2mjJL/qQL8CxShUXB3vwKBwQCJVWgO +SFCe73k8/NuxBIjX3ttb/EnNa/PARp4t0tv76p0m42evD+NtK0zRLn/mMVyPMzt+ +Me+20as9azLey+qbYSbmxYo9SoeK43PJDU4r6ben4IcOT9JxFWGtKq48xbCDEQra +mEoCZApfw69rNELU71toObIIQlhS24DWcjRcSalDJgw7HVoJRMGHaCFS0kVa8Z6I +brJbgJ6CGTYhGjDoAiR9YEFajRAxll4n8uAI9p7nV/Ki4/GAOrJWVV0LLCcCgcEA +5V+LGGjZxESn21oShCNsYHz2EDrpm47I62DA0xMHqy1DkpTdineqOkwBjarNtF// +WVY8rzobvx0iDoLP2KJy3asSE9ThDZ5bD87LRsAgqi9bT3Uhv9AwOA6wA8St5P30 +Gc4Mij8LnlXYeKmPad58zJfBfrLpRoNcnyKGvlgGe1fU1Lg1/1e2cbcHucMq6ttj +n2bgCj8ghOtqmjjuuTh3bV6FrIFvNTBtnzrGdQHSdq+wvyLkt702+82CmK/WSvLc +-----END PRIVATE KEY----- diff --git a/test/testcomposite65-rsa3072psspub.pem b/test/testcomposite65-rsa3072psspub.pem new file mode 100644 index 0000000000000..5be1caad41241 --- /dev/null +++ b/test/testcomposite65-rsa3072psspub.pem @@ -0,0 +1,52 @@ +-----BEGIN PUBLIC KEY----- +MIIJPzAKBggrBgEFBQcGKQOCCS8AAVKETkMMYwUYw+37IEeEhqt07jK6NNSZ7BdK +qrsF1mJQTmVYq/vTs/BjH8ilHYZQ7t9L7GB/rSArH6xKMWo29Aff3CypqqBhz4lO +H3M7qDphzdmd0daGfrByZNibvZVP0zjs/0Wv0UVZKMK+9ktzk7mq2lPKAlJkxbAT +bIl/4loie2H++dsLyLIIUUqRttpZ9UH6Q+PVW+27DhObfuOcJib8gecaihHbCNSu +/HvNtnFvZZ6/9Kse6Rkh5OGqJIx32jW6KO4suRxiGxY4dtbtiH5hY7ZIgk+JJN3Z +SAxG3CadT/KMHFnp6rUe2gZbtE9jGbjC29rZLeshU1N5ls4QqWeFK50K71JED7gk +YO8mMrjcqIWhB2sRpuNswuEVWMjN1drfVO/who8SFCXzsoLzIZMGhAoXggrBfq17 +5VxPhgZQMNKFYAiq9fu58NltuYtwuFdLp48n67ZUZ9DjOud5K9oXRtQU7gZaezFw +CcoZxWqUsTIjzwxV44qCSu2qJlsjK9s4EKr+WdpjcHXxxZ3qECiKJlMH3qK4rG2E +tq15SU99bAr4CWMoZG1qsDtoj7kMoSWjxyew9UM1Dg2uQg0dacNAV5AztGhrrXum +ixDNustd5x/q5+Qjk5qt5T1mozr1/AnLe8VR1tfO0L7fMvtHJXGYkqxOiahgHpXT +FVhUXpE/5ODzgTV7NLxeWa5C1sX6rcUp3r7dBcJHTP+Q0NBj5TFP4y9BHCwG1XGL +myUxbFfDQEQz7DM532H/eXcvg3Xey51ZrrtTCpWDW68sIdXBJLtuyoO6IobkDblw +nPZ2XNBCmgPMK2vO5aRYhj3TSFC56ai2PdAVe0YMTrVpQTJamDUrIWIA/VlpQJP/ +vWWKGGchgZLWWCDYAX9V93tu8BrmNRnzO3B+oZHpe4mC2kELi3iLodsTvz0+CcIu +I2CxfdIEcjWGtCgn+y6cHzfcSvVTGNoL2sUU1JUbZTiLcBLIFOJRStLZqfqKDG0V +FGv9XuyYhgrEeQ9UoKM3h6boySRc4ARfoA+cMa18votYaTSqdaf2DIjEj0WD0fC7 +owyqYGGYOq1ihZwM4IR1NQnnGjDN6uLzzVZcdTzPYGmRQPiMiCOiwISt3uOW7yLN +xpv3TqCfVTgk6xlVyDNpBqw0hC8BKzBv0k+T4msruBJbF7+IvR6rtFQKS5FbJI1M +WyLEYVAJVSx2RdNTngk755KnBLZ0pvJKAGfeiyHBmy2yrXd/l9f+/5plXUINwx+s +peBBHkfr6wKJ31DjqwkJXZntF4Squh75nWN+vVJ2uo/W2NLF/Y/0C9ax5tgTqqHn +tgswBVlNgCD3d7DC1mJQxHvZvXiUDwEOgoDWah/PV5O4ibzRjB4hDS1BWmi35Yot +cBRjZgSU2a5JOL1F4XiwhWYn5xW6kCKW7Zd7ORN8+LLpmMuV4HKw0uB/jnb3xl6v +rJk+8SyearcROzQcsnm08lWOdFwDvvAmn5OibWAA/7sGw+SpIWVdKsCdKrebEVNC +zR7d20Q4jzECRTNmVkoTYpRNEonTGbSv2OUCdVfWkOPlXFHz9FAjZJPNwKvjRK2d +ScLw+8nTPto2LU7jOy4kTRtjL9m7H+s24ft47EeFNehFgnLZ95kgxNTnIchGWkLs +KJQ3K1WRBN5SnvxyjzpRJtyFqV4MqnNWclG63ahnySRJMjA2Dj+0po5aMx4+ZFcG +GbWldLiG2/hGg3g5d+gnopfTwI9BLbLuq2HiKjvDkv3EiG4QNijMaQWfo6v5GqBI +ZZO9hbPtVZFuLUjkZrmBdA2joTTRt5Jqfr9xA0XBAXY5LgWnmeMeFUNxc+9ub5V4 +PMa1UATgGu03dPreJLd9Q97z54CDaW/CdwDU2cH9Qy0+NtlrRJsb2IzkFBcNG23b +pfjwX4mcXzzgfTdjpzQreHEbh0jNj+eqxoBD94vSSHVz4IHeqKRp9ggKK8OrDu6r +sMQpuhRHOKPyAW32cipIoktp+hIgYGpuMyF/YHu/gSg9Oa2nWE/9gGW0UVm0cGtW +yNvdMpfHBMVmxqiV1z6i5PVxv7yC7KGSR6+aIXXq4kT9RQaHBHDxDtbzAjIgIwWA +CJNspcw2vszX1BHoTwu8UE0HGQGyCW4TE2T57R83ftospG1ivkl3bqA83l5ULbHX +4kjhEd85GnsnYLvdfRlxANnDU+9p6gL+9IbvwcUD/of6mS/TTYxQWPBCxtPKFLYA +g1mLiMkQtKx2ESZTjFO7e0IyNPX9tvX7qO3a4kiO+zJ4m1xyhJXwftEPSPTe6R44 +1JBWKNGiwpkPF2dZ/M9vfimq55Vko1HgRy2dhyJ9d12TUU1xjV5EMNR/qmRyi6NM +PO1fjeDdueNMxzgcQiynveGQSncXYhh/KT/5fLAI3XHE8pY4rTkxOUlcUWmeuVny +nWBlKE4Y5HXNgqQbx85Z/Zm1aB3Da6uHi+tBEPSy/jKmHCOnHhDCRvzGevHO3Why +Hd+L1VB2c0BpIM3ArnYfrVzVQ4M5AXo0waxxT6LHbdSBkcSlqcQqisc34h/2tXTJ +H6DeeG5/ht4fCJ000rA/OrmS64hK7lkT3N5in58EP9uhdG0iqG4EeYK1d69indRy +PZ7rJL8wggGKAoIBgQDMML0+J1Hwd6ujNC2Djc6JlJEy+hnFF4eqyBNn1B6+fm68 +xclIO0Nphb+mbkSOjI3y1vzQ8QznJQlxRBA//0UW5AmtY9FBZ/pKtXf4hDT7Rr/R +/c0tJ+X7fgelXtOKP3KPy2UOr/cn7nKwJp6gSzBYuSDvY2k9x0npYDC5LdEjVLul +99v5b7pHZAWKwVFrK5u0cIYUMaWPF+kjUsBzpgyvbeCXWybkcPal02ytR+G55kPY +Y4b8T1DMgrDN0iaWqGeyzj1cZ3c8fe00/z5ofM4094CMrW2jnZ7Xg7cbH3NMGYWS +LfGLoL558e2H/ANTuvwsnfGG6ILV/zuWbxGSO7USYnXrAuGMYpXAn9HIh5vy89a3 +4wy6myn/+ShAi8tGPvUCQAqHv+teWlBCB+oMI/s+cLiL59/S8FkS/RzJwUSpSejN +haDSnGGbAxcXbGSzahMS44VlW83UWjFjILdxdcNuNgwBeMnihA6+PbehizaLF6mB +Oj1EjNsTRhjtPg4BYfUCAwEAAQ== +-----END PUBLIC KEY----- diff --git a/test/testcomposite65-rsa4096pkcs15.pem b/test/testcomposite65-rsa4096pkcs15.pem new file mode 100644 index 0000000000000..0b604e4b13945 --- /dev/null +++ b/test/testcomposite65-rsa4096pkcs15.pem @@ -0,0 +1,53 @@ +-----BEGIN PRIVATE KEY----- +MIIJYAIBADAKBggrBgEFBQcGLASCCU0b67uAIFSaS9o0XAPESK9L5NpYKca5OC+W +gbRADWgeGzCCCSkCAQACggIBALJAIzxbT9rlKU1B8Rx0rswf0p87Qo0AA+z8Fe+q +pEKWu1wkx4Mx8XxAhWII8LOf0Q7d3ii7PBu+u4hh9wfnGbl8/MDNWY0G/mLvyQlw +X4qcAU6+59+9kSdiFJL4ZqC08SyJzcHEFRhJVD450v0XcwS/EEXVCYJ81YCMuG94 +EeEK5SGqY0m0lM/6w4i2uIbBzZ0mdy9zeCVrqBy3P4cvJ+Ul43G2Bo/dyRmy9dY4 +IpI2IN9H50QvC6rkFIh15LcrAj+VdVp4kAlH6/Yp9HxAucut4+OeztAC/cod/Lf4 +TRFzOn7yV7qrxwa61TkIm7p0aQHJoWEfSQZ2YCikJ/FwGSIE5fx3B8Vs8ws0Kppy +aDNlwELf3+mijf4leJ5VCLzlvN0CCiL8H3nEn5DcfmZwbTH37WES8/BIeKJugj3B +e6S2nPATSfuYP6/V8I9KUjXjqw8LZPVVA58SAmDxBEKgUgKH4zp047DeDLLb08V4 +5rPcIz4sXX10cWGc18g5NFpBF8nlgI3KHdZM4xnVdy8miXaLc/5g4bZ5KwrD2RDr +mjEWOJ9+IMTexMPgb1PiQRUXoUZUNcrAnLWW8y3R2wh09zQcAZf7tY5Uv5RzAWsJ +jeqcmDvaFOS01YGHof8gBFRGZfQm1jKfTxJ6mQS5ldInnHEeCUwwJ517485DW2KP +oe3XAgMBAAECggIANOp8a10SKkHwjmpeiRuMjrV9wd6GRbR09ePqITGPvOLhcRvM +DMMFVOUUk8NirXhqyBaObpoS4IuxQW4Pt01gYiPcJuJvTMIAP9++VyqAenYQn09m +J5IvprjjsbPDR78ff6DTL8wllQWj2CszWwYck5Ki4pA5V/72JMjhsdm7uQqSdfmO +qyFMMifX51yTEBI1l4sFQ9VsG/PHPusZlWim18x1JlsqvIfTPOlXOMaGYNBn1tES +MzgiJxO5kr8o7EV8z+JvKbHz1IWA452V4lMWtQQEzJxm+fKBZACd9wFj46PJAEmy +SIzZM0LArMNE88e+KpUwbtQqShxXNIlzACZOlz32+kV3kodbHvLnGDZpD63xoKDv +caGjtyvYkW+RY21ZQ/j5Fa5WQH2yPs8IN8mk1iJt8Rn4suaVHmJOu2xh5xeqKBSp +7no0p2UxQ2ZDbsTHSn05fICmG9E89ToT42/G94yGfE7hJCBlyvp0sJGxsQ5VF7W5 +QuPHmqEnNdbQN6NsxxCzVQoJR/tYg+L8AKHNrszyg8gOAdxc5xkAZSFy7GkQ0K99 +4pRoZ748XT151ZmYg8RRr3E6+DVvNmB94wed3RNn5XibfFCpTUU8pxeCDujqJNLK +jo8Ub8hnEjhqR7ueYJ7PcP9UYWz+9gIz5piDcDn6O8SlmA5U6P0JIVqNWkECggEB +APkZoJBfX4bXW7a5QJ28zwCc59bOyxKCmtKpUrGP3yoVXQn/FY9eV/DWAHB5/OIH +QdfKp6MCmCzAe5x2NJfCnS2/d3f6oa2T4I+JrvhOYJ1MTxFxqwodfBSzMHj+2UQW +fDDJTf5n5g/BERjKpqBfvZU0mRh+orjRQjEqSM6h18Rr21pfEkWtFEM/px1Nq3Zh ++13mufQWRN6K5Mjv2tgU/fl2d2uajYGgwGDGfP0JwMpPm3dvoOZZc/22vrZnmudA +LM8T9WykGJ31cHMzjzQINRYMvGcDdwf9Z2o2F5a48JGQAU7qnTRsU3dOparTDZ89 +b/+EospkHgWl7Lm9zjJ+6UECggEBALcwHXI5ACCgnn7vh78PYWG7kADIZkfQeyb4 +TlPfq+ZRPKKWFj3rJ7xr+5Q1bdqucVlabDnVB4KpmwxSw8w/vLdNx61HAc6ujUTN +EYZ1lepLary0p25su5FbBo80VWkEWsX/lvSxAQfI6b2eadlpdT2U0dFqTctm+/tr +nVMcRT15RdKD+1uekW+gwsLLpFzP+kB5zaGsgNfLc98dQ3JzHZKMRt8qsXfnm9si +V8aaPs1ps+d/qIId66nWEnAMW/YCLeIrV5b7w05iUrQw/RAlltqlIi9OBHkqTaUJ +64euvs8J9b+6X9jHP6fr1f/VgEg2C9TET7nJkVhLRZmdSPHruRcCggEBANykiIaZ +FAJaS9CEMuoFTc4bLXgl39ZbfUvP04GYEHI0Th8GpVBCnt6ij+0RAKAtEXNU/Dv1 +llk9fcBPK7KpHZRiHi5WAFPBwo0hxawHsKhj6T1oU7o396pWNj9WbZhT2llUVhNc +cHnP55bwGbvAUisRVfJOaVAPevQVojv1Oyuu5bMctxCkiGgwv5PDMnc/vumj7153 +QzVkDda2LkBsB7Kp7omPcnw5qW2PIzL3Kp+I+ApJBFpFLeqzriXfi2P+gjJCWYeL +qopv1tUT/Gp4Qp1vVopglVSsbqezlh1ZXy1wQthmFC1VLnFlZnTzUQOV5diM4a0o +FTenixHTQAuWQoECggEAQDjeGe1h3g5xgo73SERcH6diFOQs94BfrIng7Aa+fUB9 +wYJcydhnVeeFi7AvkzsVAf5xctT8jRJpCSj6++BciOb72gPK3mrTnAtI2ZrftAQ8 +p2uuR0hXed4vroTqbKbaLBAvHBnyAoitaYzgDxipwa0q4gAixeyU6tAPl9ORcrvR +frxGoxg0ZK43mZNLTD6dvXz2Wnffs8fgF5hqzPUOqRIExrhw/1hzi5++piHtYpZs +O/zFVtimhiRG0oGCu/yHmYMYchZRomlWFVYXYlHLUVwTYAI6D0CFeBbCPA9HVc5o +GY99isJPzs8fd1GiZ66K90zbpobELfA1tmUt7aJ2gQKCAQEA6rTNMhzP2wMIZq+T +386ODf1pJ+DkW9hc3RE3oIjdUaPREuJQWKBCOViscMxX4lEFujXcAdSxW7zokAkI +AE4d9O9yU3EBi6TfcKeI1x5Ehfqp3nZMFcM304VkcXvHwBBnITTz2ispQiDW6+Bh +51m27RFklm6wmV0B17LG1Ot1ZhH/VTMCIjfq+XuMGTncKyStmehZyYPTKxLi/wMI +QdWY2H0LxOLKJV/5V77BDde3TYY1FqmrkBzG7h/W+tLgS8N/57GEib5FQFZ10CFw +CWTXtaLsXr4DL4wgT4j+vSypcM2FshEk5Fz0X6ptQ6H81Fe4qTfwd2o3m8XDQCeQ +FWsiEQ== +-----END PRIVATE KEY----- diff --git a/test/testcomposite65-rsa4096pkcs15pub.pem b/test/testcomposite65-rsa4096pkcs15pub.pem new file mode 100644 index 0000000000000..f5eacdd82be1f --- /dev/null +++ b/test/testcomposite65-rsa4096pkcs15pub.pem @@ -0,0 +1,55 @@ +-----BEGIN PUBLIC KEY----- +MIIJvzAKBggrBgEFBQcGLAOCCa8AB6WucPW3Km4D27s/MoPt43dTqC5lZDykkpck +yCLp3uHEJ4K5WiE8uC9lSEkgJ2eibCgCMkpxeV+TkJjekIQpDJkj0ui/bM1Eu+Iw +UGU4DE896bwRKP0VqLh6NxbFa3SYxpQTtJRd3zj4iReYHQ18xhAShm4PtfPQBtfL +oemx4LjtDGE3Hj8JPokZ1QWSDCvXhvKo4ttz8cvxOrEUTxzwqdZTyRppntUzyOx6 +sMQgp8HfFvDw1dCve0YqXUjGepDsUu/6wlWHr4v/pCDxQv34Kel7qCrviCS8nyHz +/uthEaWDEUDGwtorGbllBlnnWCn3AnvJElKAFZVkLjw9sGg+0CTj7yDmYvytrIZI +rQRIxiFnIqyPXSHnZo+UgulC1vKDaM59GmcL8i8lwsc42tk5C6/hVqcqsH1Uczc4 +JidVayLhEUP3vaVnBYEtHn4njludjuIZiRRF3++iRibSBsddMMXF7v+uV8RVvlI3 +nZyVaqHeqPicneh5MEx20fWF9rENQZt7oI1zdWvVIBVp2yrYZygcP0M+gNkWvxTe +zFauPA2ZbCz6wpg5ZhfXGuUjuIB+jmUTKoDo2rfUy0EY5+kWQRGSLSw8HcvJFjMS +DG9KIQ6p9t+ir4VB6g/hivIT0SxsEw1/0ILNz2fqgxPYaNLGKT1WVRL0i0D8BNFS +0Os+ie+G7OtlHHfrNis7aJE+Y65s6Nyh2ChtIdSM4d+Tu8nVjn2bIAsRmr2EIDbj +hTUn+y1PwrU1rSjzUjExkBQQiy1hKx4GLjKhN6/CmFdZuSsakwOMLOOQ+y6b9FqR +es2cCGRSrW8kq5koD3Cn3N1Ds90qVVoQ20F5ouNBNZDv1K2qJsXKILFauIYWH4cI +hb18lV0wDLCmet1c69y/BnVGEbDSTg8lDP+5vN/OX2c9STS7BsYo3HA8soUSdlUi +eDMmUgkutcBw8mReZlNVNy3s1tALTMwrMy59m8EIYLdz7tv91z6qdIv15lH4ogGg +/m7X7Ywy/2EmmLjRMWJRnk1MM8MYfF/ojXFLJW1cp9di7iSNoCau0X3moOOlyZeI +5mBTj9OtcsgW46OYoWa6nLPmE1nsfoM/PMr6aqXhWGWVkjyMM7nWp73iuPSei8cw +b/CczuGndpdzoLJYBS3QvRMkV5pLpTUzI0yvz1Jhcl/OCL3eKdg/0ECE69mdePo8 +pYgIbT0Wf4tHvuwVhXm6MhCg1/Mv1KCcaFpzhkrO30UzMV63BIiPUDtAxkjuzZ3z +b/uQfWs2GIpTrRQsmDFu9FVH0do/jhsD2UGFFtOtC0egRv/WgRj/1hojHv/O1Kd0 +z08Q9RCtz0GxubN+pwlDqANL/GnoJ7XkJ0UvX59/MGUkNslpp434xvEX/IpAcg7H +gybYWzDD5/+OCEKzYe0ex1jD9K1eKFaA5iH1uaNsKH1S5SazGsqG8eoNd2W4DuMf +Zm5nXLspkurjOa0UADbc/wR9aP8m8WMZ3DqQYKFCjM+iHMqVaS5BlJJY/QUHPe+e +Dp6nToGIFkvfXSoOMHQrOmT9xzZOXYc8yipjYOt3iPx/4ZEuBysjbRDheh4Wxwof +j60Gy/l96KH6fL8Hbn/1rn5awfLjyWMl9i093RI5UTAmdAgOmGdXpo/v1kaTo411 +uwP0JaJzX45ixPdfRJVvdE8+gxfHHkDQELHhFtdz57pwk3BGnqMC97+7xLaytccs +h9YSERtXNDE21/2MrICs8839J0ET7icvIzSH+t3VPAQ5qUjqHetda53NBlAltUta +JGAsl/e0CjokmHN9qxRfMsw9ZqQ+SMTByxmkYyX2k9ntsXdYUyx2rYQFhB6HRqEc +N4l2zcnPOHJsGn0BbMlJN/LoAzWBJ0sZUNAZBhTN3H0I3Wg5+MuvNhTzmEP/YhQa +rDI36w3V4mQFL9Q6DYUxC7LeZOQ08oF7k+DJpYcp7dq5isReaiddqgDtl20kOKLu +BptnGPudFntb2xbsCbTT26KG9UPuGI1NZ/EEEzbvml2Y9HfNOpsb69XJu2X/3+kB +dxOskX2SJl7dGvB3X3XDiyvKq7Ut72GY05xKQb9HqFyitwjDw295kXkctR0fiCdI +2kwFRKg2trTFxJ2jB2mtJqugAgPaM6aFk+6/WYlwPtxJbfFVXeo8jeTpKZulX6U3 +5qQyTRzDSmNn2lhB5mGOyWYghmcBloY2i8oMRFvL/8yIRwVoYNMGrZbZ289Jb4UE +Dzy8y6fLH8e/rRL5cpmdNvTeKIH8+7Di+ubwxXDknPw8Lqs7Iw6xNRNmtPQ64xHQ +IWoQUHE98v6wetH6JTZCr02VfKyl6UWhDIuH8sVmbmYtmnheV7vaKNQejICzYDSz +nVF4rrNNpcxU5rMxkurl1EzkbdXYx2cjUQIp0fP1YxSdpYG07ubfGCbvYHqR62jB +/CRMAcZCiUeuuoJcnV6ekN9yw6IV33VWJMMDEAxayv6vxX1vEQS5LDD0ybMMKXDS +c7LMbtgXl+LYVidxMq2/Jja6JGr1Io+CRXgv35WYLSdUTrscCY4D4chKrXDoXTDj +PmaykeOxRpdU7gfr9drBFuJ0th6t08M+LMr2TmigWkz6qViqXMoFcsgwQWp5LBeM +1gFTJZAwggIKAoICAQCyQCM8W0/a5SlNQfEcdK7MH9KfO0KNAAPs/BXvqqRClrtc +JMeDMfF8QIViCPCzn9EO3d4ouzwbvruIYfcH5xm5fPzAzVmNBv5i78kJcF+KnAFO +vuffvZEnYhSS+GagtPEsic3BxBUYSVQ+OdL9F3MEvxBF1QmCfNWAjLhveBHhCuUh +qmNJtJTP+sOItriGwc2dJncvc3gla6gctz+HLyflJeNxtgaP3ckZsvXWOCKSNiDf +R+dELwuq5BSIdeS3KwI/lXVaeJAJR+v2KfR8QLnLrePjns7QAv3KHfy3+E0Rczp+ +8le6q8cGutU5CJu6dGkByaFhH0kGdmAopCfxcBkiBOX8dwfFbPMLNCqacmgzZcBC +39/poo3+JXieVQi85bzdAgoi/B95xJ+Q3H5mcG0x9+1hEvPwSHiiboI9wXuktpzw +E0n7mD+v1fCPSlI146sPC2T1VQOfEgJg8QRCoFICh+M6dOOw3gyy29PFeOaz3CM+ +LF19dHFhnNfIOTRaQRfJ5YCNyh3WTOMZ1XcvJol2i3P+YOG2eSsKw9kQ65oxFjif +fiDE3sTD4G9T4kEVF6FGVDXKwJy1lvMt0dsIdPc0HAGX+7WOVL+UcwFrCY3qnJg7 +2hTktNWBh6H/IARURmX0JtYyn08SepkEuZXSJ5xxHglMMCede+POQ1tij6Ht1wID +AQAB +-----END PUBLIC KEY----- diff --git a/test/testcomposite65-rsa4096pss.pem b/test/testcomposite65-rsa4096pss.pem new file mode 100644 index 0000000000000..6aaa764134dae --- /dev/null +++ b/test/testcomposite65-rsa4096pss.pem @@ -0,0 +1,53 @@ +-----BEGIN PRIVATE KEY----- +MIIJYAIBADAKBggrBgEFBQcGKwSCCU38fvn32ZrP3LyAaRxi2SCx4DwUKwlsStg5 +Cht+Btet8jCCCSkCAQACggIBAMBEBYbSiwxZnJhsLqI11auJeAN29QgmYCZ7n9tk +rywjKbWA3ZW98a86XIE0E0a6hkXXdUgDEc6C6+5uuan0ZaleDl/LAklhcXN5ocIH +fZpzDFNbfYY459lI8sph0gxgN00fIA6kYNNfGAOA9bq+3nsP/nP8FzBlso+7ZPyF +CuGo1reuHdWRtT+AGFQjw7CNeT19QDhrBM2/ReEEUUm+o4kWtt9Y6STj//6vwckA +eSznUl224AFs9h0Mx8g44HsLhc/IiypbyoJNH5DVpJcH0nZpjuLCrdsVR2VVZQF3 +fELawWbj++zcfMC7eFvHmWv3hbxYAzd6edZrrgLKGltQEOHbj4n7xZ6fdm6zYL/J +RjkJYBClQ4WnjJdhVX/2b0MvZH8zKimpWiMo+jK3JU64XDSUd5Hd1l0tj7PHMkG4 +iYhZAg+Q1To0YjQ+IghVtSp0Cnmm4W1R304yB3wxE5KFUYjuGrG95wDWCVua9i1W +FHyezvkMXb77fu2gvi6nHBoZvWsOQ+zCrviJYWPpd8WN3Qhx0s6q4Q5D7FYFr9HJ +RrL6CHebh0y/CzLVUCMZ1x0zQUfZBkZHwszDJnuH/w3nJR9OoJV/B7kX8ep2wf7I +JfhxXP861ggxfN4z9EREncgaHcDoBVOGI6yzfMd/g14XH0+q4byZzU6gZAs53VQn +qm3DAgMBAAECggIAAIQuP55xISdcdExWE7lxSXSlDd1T6yGvQGs0krJChivSANrH +vY81BvNxLCenpZj6o1Vgy0C224ceexVxCjPN0haek0NITkoks9qvxIWgoLmOXurv ++1xLwxmfDUwV9FKN03cx7tgiKm8m8Vt3TXkVv97bIBSdO1QKlrg6HTN+Q/zgFr4w +9lHd2r3NUuyFqgO3P6MGeSBQcv0Agwov7bLFXajh9NeYSLEUDusJ6jBGIwi7/+Rt +1ZMlVg6iurbsY2g0g8pWFVcJxC/Q1eK8/mrW9dpyt8kuDliQSIViMA7SFpvfyRbz +pj8xVpMqT5TJpLCVe1wBJjT9/sVrQjaou3YLlY5+jv46X0LLTkvy0BbT9ROeGm47 +FdbxI7/uKkvyBeYZ+zjwThqHwyn+NmqbwDGDyn3D40dP7cRXajETaYw43icDhPK1 +Dw/aUNlFY1NxHiSFVer2mH4Myu7LEpIv7Wn2sS6pHLh1Z2wagMNk87WuDsU6J6fO +7nBIb5H6bn51G7a387fAwg2vZyVX5pMwAlXwC3gf4viT06dBy6rNwar4QI1Vfqxs +JjC8FWOoVo8ogbbsHZWgp3r5bBbxvwnu88O9Wdb4ZDT7P5jjQMQeKPibVFRwNh0O +4gx1nkQIKiOC8z8qBTOQlgRDnc2BXmsg5EfLKnPnbyZPBgF+NhgE7e02yIECggEB +APco1YVRB9B3pAjevqzSi8Di4w0QTGJw9BA6bHRhyL1bM8YO75NMyMc5lZlbokT1 +bfKqu8DmohefFdG3b2IRI/SK2GmSDksSo8IPDA+9fg/iN/NlD4eVU+xQLeXt0Z1R +kj+o7vnpsjFrzn39bmko03nsl8NA3hSBF9oo8faq3falnyeQ2OMdJo3cTcDkZdKx +tf3kOy1v1Ldzqnroqe0axxqiJvQjoaKi9OL4RMbJVLZfD3bYku+9ueimFrWk0zkf +bHwwm4tk3kp2WL1gWE7J0ybzBm1hVbqJgk2dQl4qQu7HPR4TSLqKfBkyeD/YTDMh +HMRXxpPLpQw7TUpYnBqRywUCggEBAMckipdg+AVxkZGfClxiXHJovpAtTZgMFh/G +YeR/KM9NL+f5tfY/QI5Lp47/x7NsldK0C6PoV8iVqOGxL/XdqmIIubudsGdOi0R1 +BrPeGI2ktaFIy2WCut/j3epsJuIHBisbY2PO71v/MxSomDArAXT+L+Jw4guJr1rx +pB+Q/GOUQLGk0FHQnIiLBge54re06Xqv5EUCV/jox8Ljj4fsne3gfGkaDLwCPlK9 +Xw6YJmjEZGS9iygpWCN3sOyMH33arIlft/Rtpj2zWHUgEP69sUPO/MYwLZpYH1FZ +qxk7JQDEh00p7HfEupt+yLUJBUHjqJ354gip7qVMQIJkzDTKgCcCggEBAMZ9rLzc +ToJFEx9sg4UXsdS+YcnkBPQp8lf2E5OD1Er+K54r8ItDZxtYS6RVywPGdv4jz5Uj +o5mE0WkTAAip605BE3v1KDVySsFWhEE/1TW8X2LBDq+8ZSGrYrD9RRIqqGEnsoRS +AiFeiv7zwPADMZMBRwAv4CpnYlh5+Zg3sPqcGC0WTphWmNfkzSzUQFHtFlNIL55V +6WdLJOaAY7dfgfcJsm7vDqgmZrTA3bsnhTjRLwIq/BY9MEh+2k4WiOufKOizwLc5 +0qvKT4oHDeR4gXMOSWMegFLGjDb4zIwDNK2+pH66zfXBsdgqiBf+BXQqa4fjVj7r +lSk1luTWNMfBvmECggEAEVBqBFNX/REsuN59Bh8/LmtQ9jQaJPgYDFcxN66em7d4 +TND3Mxu4vyZwwQwYDs+IDzO8N1oCF9x7PHQtWVEWeUOM8nT5W2IG1cLe/FB5Dgee +CxHLLV46ZTDooHMaxlgZ/zF4aLsbMIJ1rHwkDzwN+mAHRcbOwHYOGvgbbusqJnZD +Ua6kthhPI8gClDVjMtm12wbj7+QORgPnKliiqAy4hnAYIQM0zDvds0/nrdsoq783 +g1K/gJRnp13GsipUqpqSmbcKxWOrKn4nWLebAqr3eI/Mhma18E9tGaOULrNnujNc +GCdm+drO5qoVRTgtjtb+WA3byykLKLACg9PDtWtNzQKCAQEAu4YzKqXr9Ve2V1Kv +RbrmZv/cYO1e3QYqr7a4Z0gm04/lSc6q4sQ0orF6i2YIPz0CiuognztLPlsbm+nb +oYZsj9RbuKa0fhCIUNMVV+wtivtvMjLq5EsQHhhVbMS9rF1a+DClvO0O2ve35ebo +Mu0CkWlhlRuuNx2Kli6yqpwSLGdHwm982Ys0+7tjcKLlNkD154TUfMK+K2UGUqzy +uChqYX/M849EnMIhVD6UcSdU3o8oWMCe1elLiAtc/YCWaZgHs6DduW0nd1ZkrY3i +ekgCcWqAVo7om63tfc+VcJY80DKXDDgBULms2vZyebdByXWIeNUnHNvmmlMXWr4R +sZ7M4Q== +-----END PRIVATE KEY----- diff --git a/test/testcomposite65-rsa4096psspub.pem b/test/testcomposite65-rsa4096psspub.pem new file mode 100644 index 0000000000000..2e0c43e78493a --- /dev/null +++ b/test/testcomposite65-rsa4096psspub.pem @@ -0,0 +1,55 @@ +-----BEGIN PUBLIC KEY----- +MIIJvzAKBggrBgEFBQcGKwOCCa8AD4uxYk4vV2IovZyPBzOKEbLoTtsF+3t3YDtl +mz8Nw+UL0d4SWdhhHJA75A85hueFpI00hvujV3KCeey28rkxGEtM4Avqn/p3dfI7 +aWnHFUZpboXLcCiLyX8ty2m+aIrC/uymRelXL+B2h2qxuJOsKkpBUqd5y8BTgnkC +BS05Ia8YJuW+5OtsC+LTtQWsLhaqfC/pZuK75wM7X/pYr7+A6CZOAEFV1FmV9eML +xgxHZ2p0yX8tNkctfXm0yqP0u7C/G/Byh9f67b+nUH+EP2PHpcc/XIXP7fu7qhqO +DEwNUPNTy8alIiuCy9+jln7fJ4v1Nn7huoFF6h1kkPN04m0PawT7tcVC7tZkIyBF +u7Y+310EqIiWO6VgWbgd+AHptZxe42tlOxmWO+TY/HHEtgIEEqi7L552UR0UpfYd +JFthfKEugAb4ilIqc1WzLaGMp9Aw36Gb7hvGtrN2GWOycQMtattfvwFg0cuI6ZYy +cjASCxZE3EgiX+WhonMBb83ZIIYU1FX6YsWnNDoU0Z1gW5LuVIIbAmhRSu6BqNy7 +Pq0QASVWV086iUQSm4B1p65HNS+O/VK35U5tApaG++4KHjf4j2oc3d3OEAhLsc5f +hQPxz6yTaHTol62cFlxUcXpPN5BdepQq13zRseVBIpOTLa1z485WtsiutlHWx4hA +iebFInGHMMHQBhznDuTDEY2pP6uJ14tZfLZ2HSn5rtEgcQs2bgrwU140pkbRx63a +HfO732SgHDWvtWMpO7/BJLE3AnhDCrgTv148ImTkH39wKMzWhq3Gdxjw6ZJ+Rjj9 +3tw1eAS1KeNOngQYP1r5tO8coW3BKDuvHOhq4ZQYWGmAUDIVEubfh2e/J4Wyg6P0 +XzCptc9sSFm+TOusD/0H8YxNh5BEPF/ovr3cxhVJ5zezMfm5WHx0dBqKOhdgbL7l +cae4zZShRsTlhmI5vc1Qfv4lLXYs2XhG+Zv0NFRkHsU+mydZxYuRzr2KuOt3mENO +Gb8ggvemYag7nlfBq5oIET3sdP+suTdpR5tXKK6m3DDu41PrwmKyfewafcm+wVbF +8JhyBFpr4M488A6wp8kDCSMPlCOFMVPXSmWSR78LI2ldE9sqFIuqESEcKFvo6/Uu +9fGmWoe3+XaxpZqPK/zKGtVztClJHut2N7ECgL4TCN5OXIddiTaebzgdRb9Z8O5G +Ar4+RxwU7p8542AMi0TZEBUJ2zBdox+wjdcRlNpIpIV6p338W6Y/KqBoEs2OAkQS +cKv/WM0SIHkPftjK79rpPsqDPrOXs2U1yo92msMjDqPTVgxSF8M+HuGPujzzlccv +eT9i16FAL6voBmv04tNbOmPcpGI3LSu65oW+dyonILOpgTmK8o+kFIkMrBUqqcQX +1vfJ7nNI8sh7iTGePqcI0MMQfSt7+J5QV39HHVRL9WK0YemXw9h8cB8ScT2GOf8c +mtxJgFB3UpjvLmLcxyDASqMfLqLEARHQRWKuzaCz0NpaTMJza/c6GgeVVEjKQkgX +k+HuLGFRoqffsMe30Op8//5pDM9hq/j3pdDFRleDmbvcdjUG/6g22g7wAaTRZN5l +NEW/j+ikmyYHh9qK+ZoFZuK/hr2KJ/9oDlduTXD6exD3lMHZ4AjrnjTCweKqZPlY +TP3hsmME+CXvmbQuflkuS8Gk9C/43JJUn3zM0PZXK8+tTi91qLSRgTYoBaICVKIz +rcMKL+yzIq/9tWg44TFLzGE42NlOlj5wmNZHkZmxEGNjpOG+ExElGiHgCgn/0SHw +GziwOKTaxA65NOXBHbYzhJRg8lTCbqg9bJ50SmEBP22O+GrYR3anZresOPWjhInH +9ToPA9vbx3u2/CJ/TIULOzR+6I8rouiey+r7h94IkWizZaINBDH02kmxlX7TBuZS +OWtKPqy4kZ23NuNCRZ9hff5/CC7IlDARu6HkYC2HGWx8EcgRXnalTw56meYJEmkJ +ZyX7R5eDvIgXOqmwTCiXTX2Fn/nDqiWNxpV6tJSI0XWlAF7tbM1vQf5Cb54hlkrd +65VqLB6pHtMPX7flV0QsPXpfrDx81PqySF9y+MN6T1Wr4ujyRID4pvRLRPSLT/v7 +Pq02UqRth0PzQFpKDGhR/FLQWRPI0uWbxxMeN0Pb8iTycqG8duFDx3SwaCpLxcV8 +K8zwI0oU60eeTW77BUoGTs8KWczVz0yMDJ5GTRPnY8lavGkY7zS8fkNPYzFDGb/h +FUyKjcNnoZutH6S2QXMYLIPnPEtPPnkZF3PjbBqssW51fkhUxybljQgimWEy2NI0 +Sn1vbkQv1I0V20B283o7AqGjsil03llYdtzUU9ztgltB+8AQWFlnHxqjsb5uMTtO +Htl2Cp7Yj4528n5478s1bQcLMp1mydidNC+xSEW+hsapPzD6/ah64rB1oR7e24Ou +z/Fq81MYVuC/chls3fwPWOHg+h8NeP4qx4OJJO0I0TqtEMVEb/GDZ1EuspH/Cate +sWoCUdDxL9q+XQy0UsZHajyTgb2V1SUtLPhbYSjfPSYCpiXCrghrmmMOqMQkTo2J +Fbvs3FkrI+OIvba+oBMiQUrBm0LzfLGjcRBzOKwrjmTy5wxzKt9xM/9gGNW6BRbr +miIwM4AwggIKAoICAQDARAWG0osMWZyYbC6iNdWriXgDdvUIJmAme5/bZK8sIym1 +gN2VvfGvOlyBNBNGuoZF13VIAxHOguvubrmp9GWpXg5fywJJYXFzeaHCB32acwxT +W32GOOfZSPLKYdIMYDdNHyAOpGDTXxgDgPW6vt57D/5z/BcwZbKPu2T8hQrhqNa3 +rh3VkbU/gBhUI8OwjXk9fUA4awTNv0XhBFFJvqOJFrbfWOkk4//+r8HJAHks51Jd +tuABbPYdDMfIOOB7C4XPyIsqW8qCTR+Q1aSXB9J2aY7iwq3bFUdlVWUBd3xC2sFm +4/vs3HzAu3hbx5lr94W8WAM3ennWa64CyhpbUBDh24+J+8Wen3Zus2C/yUY5CWAQ +pUOFp4yXYVV/9m9DL2R/MyopqVojKPoytyVOuFw0lHeR3dZdLY+zxzJBuImIWQIP +kNU6NGI0PiIIVbUqdAp5puFtUd9OMgd8MROShVGI7hqxvecA1glbmvYtVhR8ns75 +DF2++37toL4upxwaGb1rDkPswq74iWFj6XfFjd0IcdLOquEOQ+xWBa/RyUay+gh3 +m4dMvwsy1VAjGdcdM0FH2QZGR8LMwyZ7h/8N5yUfTqCVfwe5F/HqdsH+yCX4cVz/ +OtYIMXzeM/RERJ3IGh3A6AVThiOss3zHf4NeFx9PquG8mc1OoGQLOd1UJ6ptwwID +AQAB +-----END PUBLIC KEY----- diff --git a/test/testcomposite87-ecdsa-brainpoolp384r1.pem b/test/testcomposite87-ecdsa-brainpoolp384r1.pem new file mode 100644 index 0000000000000..7602a0fbff9c9 --- /dev/null +++ b/test/testcomposite87-ecdsa-brainpoolp384r1.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MHUCAQAwCgYIKwYBBQUHBjIEZO7ooU/nP/0CaCbKSmBM0G6wZ7lxgoOF6HBT6H0m +1irsMEICAQEEMDiJyP1dZedYY2nCXsSzM+tUiWUuAssU7psOJoOPtTO1I338nEyw +Jv2eY2a4q1xnYaALBgkrJAMDAggBAQs= +-----END PRIVATE KEY----- diff --git a/test/testcomposite87-ecdsa-brainpoolp384r1pub.pem b/test/testcomposite87-ecdsa-brainpoolp384r1pub.pem new file mode 100644 index 0000000000000..fca70f9840587 --- /dev/null +++ b/test/testcomposite87-ecdsa-brainpoolp384r1pub.pem @@ -0,0 +1,59 @@ +-----BEGIN PUBLIC KEY----- +MIIKkjAKBggrBgEFBQcGMgOCCoIAHP/oSI/1Tq11mCa369+3WVOuxZM52ehdC7yh +FUqEQwqdyC5T0Fbuf7P5NGALbWhK1IgwMz7YtuR36Ia89K3PHHOKAooKnUBuiiCl +gjh7eIlsU8wUEZoOOOGRfT7hd4ApBOUMkCsf8Zy9UHdKTtOdM+i1/Ktv+jcTtCp3 +zqfdFbNPinWDOMOhNloSd2beGqT8jqAM2HqwzY9b39Ac2eo4ezM50TAH+czWC4Gu +rsWJJGLy4tlC4dfUCGb0971n3mGQh/Xno109iTlNoCPcrA3y7GMSd8nTzZTsZ2u5 +/rDgHvXKVtKRYPL2iOC9+4KLDcitcR6Bv362ieIvTKYdz8vle6M7a4CIqt/BJDcE +PUvr5T+s5ibcOHBdupXa2gjrnYjGasCYaYREktkIt4F6Kz8EUxC8ZhebCuTGFHxv +At5JT3nCQO72SQrgqeTr/FenvjgPMpftTdiJlTdYpR0oTzd4mXvTzyTEz/xkAGmO +9h5Nw5qhWUIhzhd7bKaSvGA5CEj+UAuT33GoTj+2ha2mQLgfzmy6NSQKeCNdD+g4 ++jZ9c/ode8KaZdT00arA77FdBoRDpDNpnaIzNsuc+waZFOx1PcnExhEOO+L2LkMz +g2H+dM8zp37nM2mXO4GMnEAYb9QQsCavhG0yiu4aytgNBtW7A7TIiTWYWoxjNadv +uK5VkVNBV8bSOZEgUxCWmkp852FvPLmSauNpY7hBt9E8pBDvrbwFE56Xv6OBmh2+ +Q8TDWqIRRDds9JV/irpnKj0rJs9Jus9YbR9bAMYTPiIfgfBbZq1F+eLda5y3eJ3G +0CKxL+n1A2KPjVOYG5mk3tiNgZFdX3AV7r2Y0q3SIaZQrAu3rFIbVj3E38JttMzT +OMTplEcimtOuwYexTEvgmLQ/XZf0aDBURtUKtJugjIyVKFjpriPr0gsLpnRpbvav +yacfo9nNIJcSvaWxYbksa7521gUAO3rZtcFoFH/vUQdRn+TDpx9dOzOxQfKFS4eb +lBmMDRdpg3tChAYR/WkRUCemQ0wjKbvi6Iyr5nPRad8ZmziDp2WEa/84tP/kRaC4 +/cj0EzjchA6TAcdZp5KZVNlr56DrhKe36pKgckllxbbfH7TAkaKTmi5FyWtC9VGz +YNKc7/MKKl4cADWwMdomzvSz0Qdtkn2iJel/YGkoTVeiq3ZcSvG80grlvdmKlra/ +Vbwt2oS9jAj4yoR8F715MfqhpZmTaoVGI0n3KF5gz8I+Kc8SI4ANfhgoabJxpljT +LMh77VjunI7qRxGJe9crCZ6JSLW+RxVa6H5u0VK0J6KNVUwB05B27uK9b9OQwsGf +Ie4nWHs8L03mo1T4PZ/W8k5jTMDAgle7dx4Z1m3otjzkRKzTkcxa0HUxNwHXVlQ/ +8iBJIOVwMrIj7aF3IUUpMYupJ35BY5ELMNP2IoLXQJlemwQ0XORYXHToBV2h0U7f +e5U1eEvN6K/scvsB5d9lBL9mCc+XppF8Cveisur4t0MA2bIBT+LcK4GFkbJeF6px +Z0i8lKswrXUS+Wn9qR5LbIBbKmUfoAM4UVAQHCD9C08fqLI/sOO+W2vN6gONJFyK +EfUa7k6tqdSZHeVzoilYllRZdO68c7rUuETBsyT5Oov7Cn5E/RBC4zS2SyJ+7fuw +Q0YcyOmAQNnTh25pIOC+HSn/R+EAF0otPnsqaWmeyXBNWqVq0tT4aAz1GIxJW/r+ +CPI0IW/KLSVjO7bnrzT4NYGzKYWYsWqAKwWdDhNIHRoUAQvxHRzQxj9gHv2h3n9s +U+mIA2KNM8vvNcPNYwrzeGJetxvkjme6NQWytQrRMEdEJ6Q9OjBK0Y06dfF5ceYs +IsEzrN4fvo+UQnv6HQVT+PQjj2wEcWQjMrafpNzG7YOiB+r2GADYv6b5HwnUSRfQ +y8OdIp4RclRgmlP62qbN7zGBinuMNBCiFY7c+rErbPpeMJxRcNhUkpXy54dCIM03 +ObOfX2vUjiYWjH0sIduzspDLAXgMTmfjTBj3PdzcgHSwdjmlhnzj31iQc8r1R2sR +oc0frXVXsLlEW3IdvdJoP0Q3HpXUCc5/LsiB99gCtrWBbZFaU9TqzvbEV90jZ3el +d4/AZlQ8gYmb2QLX2t9JueLqTbS6IfJGaPhxk9iK39FYZZUrHGiBH4x7cNvI4hmW +WiBIzXlBuxJOApqlq44Uxb9YelT45C2hqcqgtlKNq4SBmtljqDAW4jIUBmbSEux+ +2v/6gNfcO/1UpVJ5yz9Yip796tnYk1A+oBS0nIwyGCWWyAn0m3ZRuuQf9bt1wvKu +me2lHeku+Cp1ai+uh2pIRRjuJ8Gvhw+1/JOzdPDeyD+vzpNVKdwopn4aKJ1ICy5z +Hk42YZ23I+ksxeZ9sIo1F3h+7zmGqA0mPO0pBEjMiUfPG2SoZQq3ft/sxEpbFTTW +w2FbGF+hJnpECqzs7FkhRHo8n9HIYW2FmC7pYe4fDXo4fV1j791ufm7BmDRCASxw +L5hfx2t191mzHHWxQqYsOmrJ4EEsDS6EEqNQ2PXxtZSAhS8NKGqf+WG6TGj59jzx ++HfXYl/IAvsjzzfVsG8ZbP+dT2ltIakNjt14/KmziSI5MDbb7Puur3joScJjhILR +wU0prZqX141dqyVXHnuj72VxS4lthQY4uA4N9GAH/pJuc6WQaxkrqa+j8bbVTNQ+ +PSIPGCysmypB1OrYxGgu25a1+E7pPLpFuPhf6MkkMcMp5CBM8v23z79YoKuJm/wJ +RNPZlS2xkKyiwXDMcpf2h2mgbIa+kvf0Qfhuf1ef4RFOfPmpsicqyLZ0P4UrDwmN +AoHp5Pp0zD8u0BN21KUuTgmyggbmjQhjKke3SNNOvg4Vbz6AhgFCqvwZwf3iBtRi +Qe7rMWONLc9gmTvMRX9ngp6WzYLCRUXYjRM/BHBvFWoMWlJx4ZAiplTFYye2Mc/I +i68SVtS45mb+zs8KLnCg2Fgp5ejTC2rVVi97uRPIxCK9nV1m3Uv99E1CaiQZMD9i +pSGfJyEYJuhsWyudgY41UANyDURozbNfENYXrGPVFIpjvhtk6N5xxZ7pIECETrbk +K0hRBDMnAeUlbU6vnylfXudI6Ju9KBT0PnM1nE7fyVtGIMNUxCXTxMdwSG9WQBQe +fBzdJWGSTxA2b1Io9BJ7qeeThVgN16VSmxHpe5jnRLorhy6VxiI+gNIqAD6KRvto +rTrZQGXNwOHQJsJGHEztytptV/lUNCH/0dAQZB5mdD7exYVnumXYRjdT1tqyK6Y0 +pRoDkmUq81wRjJ7sU2iFcnkVNzJz7oQqKPCPm1x4b74asAa7v7kRRELgUZKuBOmq +JwuMhWPegKgIDpQ6tY20XOTtRBc9aX8RNhNIeOtvUc61DWvlagswt22YjqUc8jdp +EAWYIbQvRSQnWaA+tkBsCeEe88mLLpNI6Xd0F8WonokOnK7RTXpE38Nvs6vO7pGK +vpEnoJ2Qr0Azee6c2J65bh+rntl0BFaLHqsWXT+kv01cQGVM4cmJKuQL8SEVaNsg +rSWHE/Gw8cpUjikmrqUgvCxZTJ/eBTtCK7VI0NT7FGHTLDLOlHvVMgMRJhsGt2KP +QU5OIsGUnaEMIifiAb3UmuYusPBLIg== +-----END PUBLIC KEY----- diff --git a/test/testcomposite87-ecdsa-p384.pem b/test/testcomposite87-ecdsa-p384.pem new file mode 100644 index 0000000000000..54d6176f23dc8 --- /dev/null +++ b/test/testcomposite87-ecdsa-p384.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MHECAQAwCgYIKwYBBQUHBjEEYHQStAeOFFikSGjYWbblcZIPUaIeC/DGdUsgmAfJ +//KPMD4CAQEEMNQKeMSd/+3Dpxt1DUkDSOGveTzXNNl+z+yAjh0RcMa5nrCOxPiP +S8ydso+hi/KbwaAHBgUrgQQAIg== +-----END PRIVATE KEY----- diff --git a/test/testcomposite87-ecdsa-p384pub.pem b/test/testcomposite87-ecdsa-p384pub.pem new file mode 100644 index 0000000000000..d4e4cdad4b24b --- /dev/null +++ b/test/testcomposite87-ecdsa-p384pub.pem @@ -0,0 +1,59 @@ +-----BEGIN PUBLIC KEY----- +MIIKkjAKBggrBgEFBQcGMQOCCoIAy09Wpq+3PnnX7PCP8p5hY3MDEJhGbqcktrVi +1Ib8D3P3CO75JWX5XU1P/qvWonZ3PHHH0T1rRTXiskEObRa5H8s/42BfhhjFeN9X +89Yy3VG2YSH5LnFlm+b0q3JOh95DAEvqFk4dYe0Hzj5zubxNXJ3ZDumzjCgyyWXp +xyzlBI+Gwa7HoWMPiQMWnR3IgV9ojtVsUxT8q58e0xVS1GRAuZDt7dolj8gtrY39 +l23dtJEMBiS/lAt9Ug7+fUjC0MNrzBN/X2820v/rPTFRs0dQg8q6YxwEc47LL6QB +GBwc3ZCfKkbM55aLs3DBQZe7OEp6cNeHApGtQPzUR7RYkPh4IKbaPeOzk5qFWSjc +kvkAwiBzbc+yfUlRRExjCTL6l1/ihvJo90zzlJVto1256Fg8mjo5MUkdbYwB8Pp6 +apWpHbtTW7hUjB9T5JvGyaG0FOHhhX+J3Ocl0VWwGgswttvvtpWAiXDC16X35gcD +WV3eNKYkdZHU38ZPXPuD+0ao/knIaU+dhKAxULWb3wvB5bGxwwlY3FSCJe9cmUy3 +y6SXPLZFhc8RRQJ/QCe56iaCCiDLawSFrDM9ZB+nPWfPxb1pDyC5R7LYSSqmmgjG +Xw7wfqqx0x4KNe/R88qVUHQpTHB26zuoehaIKxUnSHNCTkrqXVzJRLuANWX2OdUQ +18nc0TfK+7j2mjJD2QjWU/gL6Yn37IWIETRJSLGlufBnuJpzLIob9edDbjsh/Q78 +y1gL2+DmMWzT+iedq2vFour8EId1mzW+p5YuT/svUJFddCHvPugqU/sbtRlRvwD8 +DaTCOl73QCSYdOdyQMAeohD+JIrXvs9ftRg8AO14pJ8hIL4KEk5tcNJeKopDHSaR +PaAozV8XFp2gVnSQ3zLhvitNqJY2rpvfKkHESQTnIA0yAHEDTMqFJ+v5PXO78oWu +OKtnK27r3eLIZm0wwbzcNI51jicetC6896JqA9j8RMgIoHHJKAXtJWYMFgQSorY2 +lnKVFfbypRvxK578V8B7p9DNZ+ztPD0CCKRM/Rkt4L2Ekcp2CuQlyMVVpr1kyo+o +PXPcb11cdbiLWwNNFID8TLopOgg4YDjHgAZ+Zjka3IGBre17ahCyqyLawFfqgYYI +jzp9XjailjPrTTSOgYIrQw46naE7Tm1PmXDJlOQEoP7YTSJ7FMBLMp9Wa6aIRMEr +1zLhRj6pjTFCUVbL6fuRuvmgxrnrdIgn/5D9I3l6uZ3cNKSGu9X+CnVzdvUlbGgA +uv9RMvTNZ6W19VYnQa/GePr+gJFSoLt4zAt7vsT6TcaT+p0zR/aUQHg6XD4y/qW1 +fqEZDlxDyuZWbtVkco6aG5fnsPzM6DTTZm74zy0gIAyyyDcmZIG9N4QNhYn8q3qV +89/1zE5HVBvXBBPvwHbF7laXUJ4za7doxgvfM/asB0M0+Qc5MzavMEjXNjBvt+t2 +VTsD8G4N4FPnGMItl5iYvP29b5tnykOb4PJIusQzi8FZHw5PxOpZ/IpDHmd6zVF+ +df3vPfWCj93cUyL1prWLvFB7E45Fj+Ns5e5f64flaIpSh/Vcq2Iei4EEfRBBYUyT +s6sRSCg16D/o61y7+sCj3LGCCfC0nsB2vLeEFQpG7pS0eP+ZKscwr406aKy5QgWT +Cy/WB3iISWIyxSMaZtmFRUWeeGPK17TiBPRN4Rc+iUqUcw+JMSjCtOmC6lJpGIsk +gd7H40u5q+ElfPXOYJb1keE84eQ1z/Xv03woJcwuGz5H7ggsgIePL5cGCzAownZZ +SsDPPnCJindfQjQkBRAM5GeY98Ch0MWTZtC+Xcc//+DZIHTNnRyENwh4w6bIQQSL +fC141DQkYxAhvToB7NWoNVxDBjjuy4JY59+CKXEFhhTMsN0OcSYU1JPFoDPVWlh4 +EQaXYa6Ub4zIE0zR4yEVxYFPvtY68X6gk1P2zP6Pxu4678PVLLuS9u3/sAdHDW4J +sJdAYkhpksWfybsX5BUSlWwbQAWEdlpe15tlcHxu7b09QZNlRqe6xBRcCDm2WAsn +ioChIDN5zXqmO3PPjIh5q0LB+wlcD8Syzga2l89Gax/J4Eg+nPg17PvyBPmq3Npl +3ZXv3IzxnNUBsuZap1olqo+JoyRXvBSpCh0oyDP5M5euodbYwBxcazaCjbgGw0ur +n4Z9Ufj2jS5j9lb6O1bP80yoY05D0/g7Yjg45R+e3GRhaM8rhsyZQEM2OV9ukDCp +Ln4WIMCPT1tIUDRu3nzDxO8JS/JQyamZlbqSl175MYJK4qWCLpIgOo0ue/A+JSLh +Kbbbue6UPBG3HiqjhjYVUOGTkwBWsk+mf1tbm5Fj58Ek8+GtgMbotq5A8vW4nG5R +SaBBw6RimMIUizIrwwoM5F89GuKbdjJjUf4poEZnhvdgTupP0orgX+sk7XG1ULIS +Api0aDdYPRLpexWQYW5bPQpLq64ZyXUROIGov3XJ7xksGAcrw5Z61kqAnc8IsPEm +H9excyQ670lUQ2RnmPmpEsfPOODbQYkgDPhg9DrFVbXLUcgg9EMNF19O+omk/MXf +TakU9kzP6KHlj02ON2BUOe+ilbZ5/VI0s8bUsuItbDQmU3lC1yjiXc3682CM013j +yypxnRQb4H7uv8iWeNT27gl5BZpxHCa1mEtbfXLgQ+TSnaEECHnW+Y5zJsl9Q6Fj +UZMic5UMzp/DJfXTgStdA7Gqc72ay9dUPHA963121d8PoOtAFIrxzXFCvyaWw6BK +ieu3Z1PJf3DdTHhMq+iDCgtsFneV30zoNervTRri8YMGAvzhZxCOQyCQeGzGDaza +t1gU1wEw2KRKb3xfsMwZfaVr7IrJx9Hycl8LWXEjZJqzcdCW9UqGgcltvXyPfp/V +lpZz0hV/a2ZipajkOGQ7QdQpXQRVggceT/iiJjUkbhMhUJ4zqZhj0p9KPUIEPf8h +IvAODOGC253n1JB65vL2zZ4SY8+WYnlU+gH02LBdURdGuog2hg+mDItlsstVe5W0 +OsCvhYQa/EIGdPEgRz9He1QLecDk+BqMCiEamlObMqNIQarDUtxONi72jjmgDVZx +0BoM3e5BJ8Ywi3BwsX9Wb7ckzW4wV+8xOgWqX1Ht6AIbHk6o7KLWvUZaezBSwd2H +yBctDY7NSKda0oyc25jeNKuyAMLO3oEqwHNA4jgb2Hb4PQOe9zus4M+jlD4flyYb +9Hp8RiSglNX2n8Ut7wWSLds21QLZcvzBGzXKQCHkI59pjlFkWD3HcSSMo30mDd3p +1JSRljMUVB9/Pvf90P5fhPLEpH+l9faczgpT1AKq32B8nffSJh1mdEEUDvn8aAF9 +RQmHjLGFTpgmRY8n2DYcUBxRFWJR8vvrKbZULXCj4SjXxrIo+dj+4ojihnJum0gS +SQEp828urWEwBSBUJQ62GwxRlVTO8eP3U7R9APHSQ239AuYg1irRgS2jA3ueV9xO +j7Bv+NAUv5rPnujcI2BuaWFtt2cmBLysvZyj5ypcnbTZXt63g8wGy/n6sRmhJMLX +N3fgMzCJkqxYZ9owk96uWe4KVEMfUBL3kuQNYd0ePAkr9hDtwY5BeaD7oPEhL6Yt +6ztQCe7biT43zYZwFS8xZFYbadE1QQ== +-----END PUBLIC KEY----- diff --git a/test/testcomposite87-ecdsa-p521.pem b/test/testcomposite87-ecdsa-p521.pem new file mode 100644 index 0000000000000..af0b191ce1d99 --- /dev/null +++ b/test/testcomposite87-ecdsa-p521.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MIGDAgEAMAoGCCsGAQUFBwY2BHKa6AEIeqwYQm/xp1ApWngcHGycph4Oxi+R0bkN +jzLMWDBQAgEBBEIAov9uDs9DyoX1Lc8+Ym2gUi9W3QZYUprguNlwZ27/E+tR8GAt +QHs8zxZyasE/VWOoGl2IY/ZvmygWLQW+GMLKc+agBwYFK4EEACM= +-----END PRIVATE KEY----- diff --git a/test/testcomposite87-ecdsa-p521pub.pem b/test/testcomposite87-ecdsa-p521pub.pem new file mode 100644 index 0000000000000..39714ae7b0049 --- /dev/null +++ b/test/testcomposite87-ecdsa-p521pub.pem @@ -0,0 +1,60 @@ +-----BEGIN PUBLIC KEY----- +MIIKtjAKBggrBgEFBQcGNgOCCqYAYAJltcaQC4Xod4mMDVCTzT14d5/C+dM052LO +jeUg88tICd4w9Zr8n0Nu/DyH2IXHV7nDUZmNZitCHjvi1kX7e1QZvpihdEJ/Cxk3 +vvI/eaZvMXlRdz5VWH9Eg+n60+79PimgfSIwCK11/SYROzOtOpwxAoOH8dqiP3t+ +j1V1/AO8YrYIv5nvx4h5CHk4kNprpjJzuRTVuAbEDRgiYaRHoFMyDH/2zolExuw8 +PwoDnBlpHlOMZXVZ75FVzvmcISLWTEyplZcKPGoZTOttd0jkXhH/Ka3UdXGJ5qRs +RQL8DxrWasTIbCSTJEcmUz4SUP9VuVr9RFLT7M0w1D9uSoBjg4kNDnOCZcDh0Yix +RMwExwp/STLuPPIlXD8FHW7OagJa/K7usep4zijSCXkBaVwyKqv3M8Ka2ziD46N6 +3szQLJzFco6z/tWqNGgxLdOiiIRcJ5ebJZhTDCFH8gHY5NeiTRcaB4+EDILX8wO+ +CDVPgXNlkmoIMzuEett/W5Vs61KIDwS8p/J3/qUFAj0ma0C62sF8dCiTdgGUQq9E +lxJvXrwuT24WBDBe4B6TKg/paP73bDR1+vwKf42SUFovXFzukcCK/B1ODcDSHHLt +lsXp13zJYDrvc2n8ROmDmeHtj6ctmlGXK8eLhBdjuJDOYYFu8Kur/8GvN98bH7oX +GyF5rdX+a+nfWw0q0FafyfJeMXiGHh16nJdFEe+KtIxiSO5+DO2wM9/U274jzoBx +GdnvpfH66sBzKKAXlxIUP785zcPmukwc8xgc2gMaP6FHMnNMDMm5lGMu14MgBbKp +L8ws3AW+vb957Mhsuoy/1rJ5zesm5Ev0uv8q5djM48EE3Nqq669aLS24MsVWX4DP +acf/HCGhOuAKefmOU3dA7/hp7R2lgJ0lzDrGhQLK0A5BNlW1Pt+DhAnIpBfpVFlL +0jLX0lh/FqXVDw/PXWFM8hQwfhamNlOd6rbKsI5o3t0YGjPInHe5UtF1NwGh4jd6 +j1oOJrrYIrsuIec3M0XaIm9YExLnxfpRpwab7khUfaa4LwKUvF4jLlDEE/ZMh4fT +FJr1/tc1scb5UXmZjq03V6Nwaxrjazl3szqBDOZDM0MozEALx3LnYsErXoRBoK2b +wgvyhU7X44upuTQx40k/2uPUtRthraeMQZbWNUGvYhheaVuRvqi3a43fLaW+hdEA +bYLnuT+JeECwSGiGkhJRrPash583833HGHasGbppGOx10zPXaO1eTxAMwCsOVKl/ +OwZu/sikw9Aq2B6nTPun+ZF8UaOuiLgbYLCiOqMY4yPl2TtM//Mdm7iAgqkmhkA9 +8npXx2UsVpTKvsGni7WRC8N2cFpF43EzVFsDePwvXe76SPZjKBN+BmesqfKfAjOU +yI12JYLECQfUQqEjEan4Cr0s79MEvLEb0NC6dWNXIe8Q6JxHm4XoNnHevGMuKa+Q +QTTvpa/xYYn4bRIr9g5+1xXsvrNlxof1eLDh0govt8iWGzV00hdXRsIqfQG6lCnP +DlO0JWwpLLK0H75SLvXNv5BdP/PFmW+CMPitxw8dI4gbqck8qtTEjUcckZeedXrW +47vuWJlytEK2wmyZxWW4GaR1VV3IFCOE2Q3DI8YTWqjOJDHnX5H5DtF+oFXTObkj +KCaXYo0/wrO6k1ZsmDDIEShDehJa/kqFJc9Rc8Xan3Be7gLSA2WVXVhp90UmdY3Q +q/KaxyjDTotPXNWfN02Yeqvv0OMsYZlCavCU8v8bjsBS6Q2EzU1x4qkNeoPgaCTB +e8Hru78/gz6qbagHU4S5a4JkPGvwUnbaksjl2zCdhMalyxHdNo3oS9+MYo0TX8Wg +PJVJe9XH8LTcj+5lAyY2e5AfTL1tn+KBJy/vOXeMZCWDKh5jPbeEISSEJ1tlVEaF +Yy6c/GnWNJ6NkGZlPemiI2LWtsNXpVo7+Xi0iGGGAxGwiAoWAQWhcWoEKirzkRra ++PbV1w0lmQQugF/+aC0eWgbGmAenzWtq9sSN1mP1wkrk1BgRnBCqZ5xSEGtzOagk +SUNw3bLWGvn0mxUxQ4A4qG9rDCDu/LAUFnCCjnHeWC3GjZ0YtcA7tQnmmmOF5Vjd +vsKobnKbwhRxsgeE0T38sSSkLa73UnFNyXzd6mLF94QQQ871b3mg2RJntupyETdG +e7y+gLtqpBaJisR5+/hC5+HmM/Cb3iae1utGWIKnwWG4DT83vAD4scOMNBwbqZxI +vUgE9K9fBe6eAbKrWoNwPOOBlg85dkQ6d8U3D/Q8vl3C3gI+xzGWjddtpMC2wu8r +u6xljwg0TbytQCjM281V55PMr5e7O/U4QbYr3WieMA82JX5srxzAA2/lcXoN2WAe +wuSmdvVPor9/Pqe/9Oi1rpJ8QZS2vlFI3dMNhM6n/kEPPihnlTlmyfbdUajlZFsh +VIPUUmXx9YWOKov8qC6Dhz6OCBc+HdHPqRQJFV/9k0dSbY5IsgDFIpZHwiSMPHj4 +BSKgkEEWQ1VpnVagtBsPqeI5mm4ReLn26i7ftOIzQD2+qSmp3t+nztEuG8yS1pn4 +A8XJxcPp1x0ufUMAe1zmqyInS/haKXCUAXklXcJeMZjtABi5MMmrNeGndG3FKE6r +3uLImZPGQHcDgLclr9fPaIuXf6cyPmqAM30zS4L9ejsDKlsUt/XLPEhzvx0hh3as +L8T17bv7z2IlqmNYx6et3Eu29qBHZP+YF0Fc6i3GadX8IIq9sBSaUDzLtZUm3GDr +bLoSwx/g1uC1BZAt36AVPHO8kPPv0ZB87Zt7Tc8HBhBrfiKpET/ZhRw/6vkYnjnc +M11jCPSlJugQK1yl3/W0Rhj0SazAG40wMrJBn8FoVkGwM3t9S0KOBe8vb5gkjyrS +iqmIzrsnA5O+ysCQxkWMgxD/5FPcugK1k+Vh6I7TWWAJi7y1xUadstTt5G6nFyqS +Iqr5t8ZdLhFOyQQVfAIcGiHyyDkTuAY+UYi5oJUOWU/6D1pC1zcrhIjVhgl/lBUz +GhZs8TUh8AfcTAxi2PW1ErGDAYpQG6jQB/cQoS6URBg4hq76e5Oke/HEygIYKtMo +3UdnxLpi27N3SH0ma/ZANQcLtjF3C6aHvrJqjKd/AaXtaSt2W8CoGG4TuexN8GRh +hQo5NifZ8meOc03FGhzZ60OGsuCOV8swU+9wSfgnad8LXhJVr9fYKX1yeF9hsZL3 +F9kPiOgURWa8rYKUmVyAFNWmomlFUJHV6uPUARf6LxbO1/45xKeQKNZPP4izIdwJ +EoFTvonrOaBwf2khZlUrWe/xj89EgsxOjPobl1/dZNd2eOxej+q/nnLKxyNzFWWj +oGcRPJtPZTRz3VkGgRkUqatRrUGuHtIS0+8ET8fdv6nRX9VEAwXJQWmluveIKLWo +C2q+c0ZGe7+Kg4+kK3adwfjG8XC+YSr9po/g0VGmnFAj7yZ/PdQjIpXSCKlAQZEt +Sz7zxuAl82UfltXNolCS89WKHEjlBABfmYwdjWh68wPAETWR/zb3irF7scN8ENv9 +I+CDO/hWaETRNPw7paEb4/QGNQmSKLb2dhvC0ryrCkWZzEKqRCIHNAEHhrRqNGMp +cPsKGgJAKgFXzP9c9szC2YYywUtyumWEwGN0mYXfQGzIKWscXHSpGov8WFlEulRm +M81Z7ekibfsQ5w== +-----END PUBLIC KEY----- diff --git a/test/testcomposite87-ed448.pem b/test/testcomposite87-ed448.pem new file mode 100644 index 0000000000000..b12c8be25567a --- /dev/null +++ b/test/testcomposite87-ed448.pem @@ -0,0 +1,5 @@ +-----BEGIN PRIVATE KEY----- +MGoCAQAwCgYIKwYBBQUHBjMEWS3IXgQt1eTh2G1FGERkcjK7Qx7xuYI79HkrZ64r +wLckU5u28onvLD+Yu3367F6vQbQ3QuTTmfMXeIq/D9tWii+LWiew8Zgo/XliPTyi +cCQqRjmx4LsSEtq7 +-----END PRIVATE KEY----- diff --git a/test/testcomposite87-ed448pub.pem b/test/testcomposite87-ed448pub.pem new file mode 100644 index 0000000000000..130ebac4c7d0d --- /dev/null +++ b/test/testcomposite87-ed448pub.pem @@ -0,0 +1,58 @@ +-----BEGIN PUBLIC KEY----- +MIIKajAKBggrBgEFBQcGMwOCCloAh+JGKj5g5wcPvhDREfqXD9bG7ZoqgSjVR4VA +rHMBU8popVlLblSGaeHmtjsjKynS+Vfm9ItA/ia4tFHYNcxg0M4JRjS13ZPgXVGJ +ZaRAPejL5uRkjv0xbDs0O3rBTC8QSf7ATmG9qPtjlGG/HqLCUpHjsJlyeSkSEq5G +U+ScLeW5Q/NtJsH4CQv/WbGtnRH+jNiWyC4uOF+QzNKtlUNzulUngjEbgILlrDvx +AfkhgICZifirj+xyOpklf1sKbCZ5b4nyvd/GWRSG0I+OgULPN6RVD13+jmY+LIk/ +bjbpH1IyHlhhcxTADb5xODnXUcjOtHEozDgM4I8LMxlZk8xvgLcEAPacxvwRynNw +ENwVqgb3CiZNFhBs35GjX5C5EiTvx8ES5fMnb7XsJW8dHbRC5V5ZXi+zhOkDJqQh +o8KpbnYZXOPvVXNr2DX6P7CAixtBxevGYizTulehyBuWlMouddt5G1mQJinTxbg1 +S4VfsuNPXmRsPdv6iZQotFvWi4P1B4uEVjZ4sMby17NMzlyBTx2C5SlT83xh/uEF +yxssCVUHnGif4Q8YfAmbb76Etwzm6/tLCTETGn1d0fezI99mG33A6YTZWDYXNp4+ +93H8p6U5JrxPD9pRvInJdixDG30p+B7WuecHcoOOOIr9E+nbfp9VrCBHp2hPrWdM +fyqPGfOuBuqjiop+2O0Qqr62zRAtgjgICS8ZPYXPxonIqDUUeD8EduWs8PTwcHGY +lFsssM3yUzonT8GVOiIPps5RvDyX+7p61ff1xfDx70lP89Q5Bx8wcgT0kUx1f4ry +BH3VsUWT9EQuk8kz2odiSJ5TNK/p4GbXMOKzuP5/cfEH9sjdsQ9FsD32ZE33aCfs +wA4NejBx3/Jh0eIixux+LlG1cVPASodZw5lKZgxiMmGUCUdkSEb1Hv2+EkR6Bzfh +Z5UNSKADep8m/Kn5HZN2Z5EcG6dmaMQ9Xg+3nrwJA25yJ7l3rGJwbYzmastAXOFD +ByjQ2Un28esVqnYklJxOsrq2WHhoJU7Ev5jXJPnAolvE7dnjsjGr4U5ThhEiKL2d +WoP6HAsPIFcwwL0gxESRwRyVQ1Q1qcYzptiseLVl/+Ra1AmCCvLVsNUGF25SWDB8 +Rtl+nCNqclzxemVgsj5XxldTMMO6W94BxrsElNGhzPevwdqRcIsPHvXDYuiBYQ4E +boLc17rJpz0MmTmKLfIPuIx85KHH3uIleZ4gLe/L3t/FTbhIBI8UpzpZxMknwbKL +tI7okvHMZVnhZkSl0VkKzOWA574CGIKBgkJd9YOApS+9Yv/KFOEu2kLYEcFEIj7I +bT2R/sSyGQWA79hXOsZlKkotRWzflqowgvry3slNyn/MZtV8YXoeFAojHm7nlAGR +Jv1WiObd+Q1ftYDLM+J2x7Qco7hW4N4h7bwsxfwOHyH4G1sNZc9Lkgv2Wjop4UM7 +QAHSKPl5x1g0owwGnt4/+5w1xk5HPCsvIp1NCi0CoL9aylHIijD5vGnENoPn8Lm4 +SX4NG6+Z+lNJuueLN/08QDT3bi8wp3Aep+PvlASZ8hZxZqOwkkGGpoqtGr5EwLSO +iplTLmzXthVKVPBMvl2EmzdY1p0zIe0zBhh1ioXaCOpRqGl8jZ8fpMTKoGbzItkL +tdlkfuf51R1ZOjVEH3Fv6uAtOH9qmi5Lm0rRyA/IM7c/Nm7nnBhnA4i/33wJmcMP +neFWxMLEHP3UyJZ+ke26oL1d0u0WCpKprJFwR4sZR4Hq5U6c7t6fSVoHq6gvbUau +CAY00b/cPWEXkJU5C42mTYztdF8bq6ByduZfSLCweOC5skVXTiPRrdSccUQ4O9le +gM8oRapjmA7PuTexMuwf+qHBgC3FppPLAremu3vMgeAhQtlowx/3met42SsbeE/1 +7Elalj2aRsCN4LylMv9sNMF5CuHcVaiBY2tlCM3Cl6MaYgIZugzEdNjEL8q7/d2o +ZpNc89DglCfvmJO3XYspOLuj88XAqyZk8ZcryjdoKEa7wLzrfJ59Sy9j/kuQ4GTI +gUjSavFKWc6lPbCRGd6sewmnqZbq66ou1ok+cawoLPTio7j033f51X+yLqS5LtNb +gO6iY5JhgWJAIQT0IaM4hCfDLhWUJp24io3PkTQyxXPc0hgWsMYy2ctvqriYE/lj +ccfztpyNkYyyiqvaoCUQbd90KXx/kmYvuxxBpqDs1ML1PT+SGuqyh6CNC1x8LMFB +tQD/2WJfnfCGzqY8b2r3Hm1zUWm8z+T1+LdR5dkBms7rDxi+0zrG8Jw69LI6nSKc +BhPv3UrMsZLPj/9UQdpjvZSzJ7D6ZNrKdslH4XQVG2Uqoc2EC95rOmcuHvCvYTVh +rDU25wOTxtEDLVsDLyxO6S6nilGLIVRmOENwdAHanpFrl2BVY1g1zLDf1Z2CbFlX +RBW72hXLb8B49yF7uaFEx9BJ5gwqga27CpKTC11Lq+P/+Zx+016oq6QQPigm+lB3 +i1y+km1cLw+NrHJF/cDaAJ8KKFvwkEKODzAsQEYmz5WxOnvj8pfPVUvkpgLWpkOR +c3ido8GLWGoryb/ePnHruNr+re/sR/TPky5r5bQ15IAzYc7/mxioD+FEKLvXBZlm +kmjZXsM56gr9pqQuT+5+zANR+6j8DfIsqzfhFXARWJz/y/WbxNU4XdZWF0MU+YQ+ +3TR+rq95lPbStowbX0ILAhqs2h9nSOHXs8wLg8gKsxz2CbRmW7X71yBVB+n2V+x8 +aE4mC5zDtiAx5YfBSJC2FrJxr7HvLidtkVnvDqq5bq52yn3qZjqo9QhWHAwSZmgj +iO+GyW4TOz4JdeumgtJuLVkPfmCrPLKRYVDNOakHqsOqiRU67e0F/j2A1/g3R2DW +O7VNlivJsLR9wJ1LGGpVR9I7BjwPRrovNiDEb7poQ2tUv+PPU+ocAlT/MY4hgW5P +fbvs9BmwwDPBRtiWxmsHDL+BRqy7RXRkTmLhRO7NneTM1FZLv4BVIaenKhsRUi65 +LFY4UytpEHk8h4iHVONSOGhUd3/HuDLJ+3QL7kxP5hy5/mGLowfcHWLmy6gCjyHu +x57k0LvaMd2UFmv2ZQQm0dZQ+tqZnDiqkcVHwkqDualDPSDz7ZNmvBqJmfXlg0v5 +HjSg28tx0Ok0hYU0sw4jkm2v4jBwBLu4Ksp/OMP+QVimZsye7+JORHx2Z8+aCUN/ +pthHH1VPoSQiRyfsXKHPKWNnTlq+Jr3Gzl1hzqtWdiz3zD2ylX/ift9QsC6DISFw +H1HGZUuxaMnnx4Cu/xxf7ix/dlt5zD4EBwABhGLIstG6saQkXo6M9IT77wD9EzSz +FuFk8SXud3+p2iKucvKBVZhnBOYVNK9/nUnp6p8xYKiCFg66eHR2NhOwZrDzpgKv +yPQeOGFhAIrKo+QNuYp03Brz+JmFIoiQHux6d/yNghhBgaufJyWEeSKxkcVBpSAF +DHJI2XeLXTLMrJ2TuEQZ+jA2yDFMouehGxzE544qlPkaJLx8HQjWKdD5esZPrBEE +FTyuJYXt86MnZgGYVoOpRJyLW/njPpCFUd0bGTMA +-----END PUBLIC KEY----- diff --git a/test/testcomposite87-rsa3072pss.pem b/test/testcomposite87-rsa3072pss.pem new file mode 100644 index 0000000000000..7f249d1dfbd99 --- /dev/null +++ b/test/testcomposite87-rsa3072pss.pem @@ -0,0 +1,40 @@ +-----BEGIN PRIVATE KEY----- +MIIHGwIBADAKBggrBgEFBQcGNASCBwjFxbelHUAUG8dGshZtiymXFXywzTsMh7NW +Kyet+X6LWTCCBuQCAQACggGBALp/8Jos+tMo8OcwzbDJgV7Mq1mGadOooJAZ+9Mr +D2IxLrvZQD16y61KQYop7ryXN6JleoLH4e+dDZ0fSIbwehXbt3u6t/cLci3RRZgt +oQ26W4O8sDqEwIUu2hmUXWGhwrVzl34qjxkgK9gtoM8bnI7jT4r2lbjHmDCYoGKX +9+cfSZQmeSzG1ZHzpbN1UVFU9X9anv42k4p2YK9QN5CBEIz+CPUMGsg+mkRr08h3 +8l7nK/t4wtbRA0oD0uiRugEVDtuxO7uHXhycLWhQIydGNn/apZ5E+tPEelgYaNf1 +eYywx17+D1NyGkNl5D1h1/AqFQwBoxPZEMdpxCt5sqM1iBGj5JppT4Jv3atbi0KK +orK5b7KxisR8dQZUCSZE36Wj6HEuV2bX8nfqTB7dBUUAeCuhWHhCWXCYvXEHD9Zx +ajCa17RHfqCXy/RBdfoN4vWTgEFljY0lipvbGgeBfEvxjDmH4gaOWjv7kCha+8qR +Yny10Gg6jRuY/14ks50FQE3qowIDAQABAoIBgAVo4qTGOzxWyq4aF01SewMx8qJ1 +KKqwEIA9kLVuYVLa1F00jw15e2D6b24/iyJDTKTURrp2a9JUfumY17S6UwBBUFAx +eVacKWK02EzyveI1DqSCm6YG5cK3OjJVwGOtmoVC5hkNyPrUmRD7OdfoGCF47Hy+ +bFdgysRWGQjjGZjFqo+2kfs/hUBnjd3nwEUYrspT6Zq8IIl6p5FORV5WsBE26TGa +eUhnsHfdnNYKzKf+EqOHvDcY9vx1oe+HEpsnbis6F3naXtSRKZzw2Gz282UcrfGx +CzzrEyUmTU9xpYckwr6q4itt64cQVtVzT/1D9dyKp+Q6tYiF0oY/yCBhiFGvMZgK +Sc9WZ/TR4CvIankz3nIP3boCgsO3iwAQhZNuxdvlgzDx04n4Um0Picw0Qz3JkgeY +t17VsFoxGebPheHNVoaXplCD6MZb4A7b/E8b4qUrG/a+y0fN6LhKz4AhMw1Kivn3 +bkpzqP7fownCri8X3CpQmyfZvQiALUCaSrRBaQKBwQDayS+08lrKXwlvKGTtv4el +37K/o7h9zxYgO5MnyUIarF/aC3ShN9WO2TdWw/37XlxNt20twCDJgNKNzlPR0SwE +3lnbwIXQUxzeSu0ZduxZyXH4m7zvg0+MBCiEmtnlxwlhKSBF3pCOpkdUZFOivozw +nYJaX5mKYMF2GBv6fsTmO233sns0MQ32JG6sbL+mL/ire2JlRIg5qynUVmc9JGso +SMmHAebt7zPprwxT1NNMwacN/5A1+nVGaH8AIJ4bfD0CgcEA2jji9cT/J69ymrFS +hHv++CKq6HZPZ0nRiWj1xdwYGLHegaGOqzaA5zOsy2T2j/AQelk8G+IGlaFuCaFa +wYwgXRkhzvhCz5M4OCWgfuozXmmkUWhh+y+3bM3UBpfkFs9djvXaA1hkOlp0YKD6 +Y1xA3xBAE4z4ye5L/ORvoQqoWBQ5q5cuOZolPszYnCJCijYuKQDGT4Datg8CWkjf +EJekb267PaRi5DUalzJYC7cLpi8+vaUKkkZ7yTJXQHBgIxBfAoHAdf2qTNunOxyl +6dzPEakJbtuFevTAupjERf3bDsnrbJcp2l3zOD70XWWoApMQlk/9V6xkpRfIluNy +qidr7Ovx4W5I58qcYA1ytC+UTvdj38hUPs8+xaz7aXeUom8gtFrzJAMZ9JRjQYtL +TKgOsuYw/FL1yedk1sv3icjWzfEwHzpNxBfteeg6r1RWm4bKlMWqRlD0b8jV7sPw +eyNd6guJ/t/CT50m/YrTZGOTMmLE0dBeV55MF9BLDv2sAFWW7xvBAoHBAKtHgSRk +Nd0BQVOXoGvqIwrBsyF4UwSAFR3kKxvcj3E6kqluk9tgkTZnAdY27au2Qki1p48/ +Den95a9bXS+S+4f3BOk9RLtGExdGuT1EN4OAKX/YDSepoS+eMi/mohkhM47U+wQr +Kaf/fV6mm0DHlQc/6vstZ8ye5DefWNqu0ckoPsemhpqhmWA8SjvqTA3NTtfSCtU2 +DvRcvXz9u097po3r/Lz6PMBfyfoogqDXUCZk6LrTQoPjHJ+jioZCbcK3wwKBwQC9 +kzsC5QOcigtlSpW4VCfaJCUX/czKzQmqu3ELLg5HC47oXRxmgbGmQon9BflOOSRl +NGa4YEoFvJboyWzIpQgCdURl9JxfPP1eb4NP7RdqpyZKJm/QHPuzkVVL11nAzctI +Yh7Uv7pF/NDCKRMBLQtFIed/mJ/k3a7lqWpEKz0G7V+1KlgXlW9/cuSq+O3svQKi +r+B6OMTaqqLpG7giDl7+D5BFkmlYhEfqZkc4wPiKitgUNc0Y5f/dLsxXkLef6J4= +-----END PRIVATE KEY----- diff --git a/test/testcomposite87-rsa3072psspub.pem b/test/testcomposite87-rsa3072psspub.pem new file mode 100644 index 0000000000000..0c83bb437ec83 --- /dev/null +++ b/test/testcomposite87-rsa3072psspub.pem @@ -0,0 +1,65 @@ +-----BEGIN PUBLIC KEY----- +MIILvzAKBggrBgEFBQcGNAOCC68A1gnPnS8pFKdjgGRERjUoQIJvId509iKRaVRq +ugY7Wb4juolskKYJOaIDoaty0RnH/OwKtOliKDK44Y+z5bCTuWOPJzp9IHgZelVh +XrL0MbKZKsgaXttIix+kuQpJZw9LdEaI7hI16e9jm2CPDnMk23F/O3++4JR14au9 +kNcEbonuinq7lzKKx68SmOQDHa2DXAfkz7dSGMM7HkRVH69K7/rAawmQl7/sx8Jv +Z9fYBpD8KU31jYahFHRhTtyi86ANWHqu+0AsbHAEnQVqsW7oKs0Ojtx5sSdB8RVP +IXKAAZTpx/DPuDLdrxj68jEyQudb9DVYU1jNkyouuztKDmnrwNwojAOsEy13Boik +EccKXyh06nsCCOT7qeEa87jRrS2f3sPIkYusNb3wwc4MMHqb7IEyHHUJTdLr0Twt +cQCaaro5O+vUnirOoRlzCZegenGnfopj6fdgDPhhhwT/KaDRJ2xQeKaM9sxJIcSh +HpDCCQMvRCXgSKwCvFQJV9ZK0DjdbGSENhPDjrqc84XVTowIQMfWtj/VWyZ4FOij +36NYaXHLky/bxWZRXP+bb+2TZpp+uijN3GQsbrAoJKGuEd2OmHsYdzypr8oZoE9w +hXZPDyfHmtitxUqR2qFMd455f5ZN9OuRC8crO7vVaWW4n70GxzWHNNe+sJoDxCiI ++vJ8JC9QgRLkkMSTqiPR1V8PFe2pEhM1qjzprsqNmzqsl/yIqFygON7bsn4dH3BS +fYIRe5EUo1kPCoiy1Hv7tDedmPlFqBJq7hnmdrMdRofFCXk5l1FhIuALAmQP42Ei +7GzXWyqGT056dgFCmglg18Kk5U5NUH9FisdAvUhv0ZMfQzY6LdS5mzP8G99HQ7sX +hUrxOitwflMX3GT7pds9Pyy+HTeLLDg36kbP9NFjYJ+ofy9vBVwWQPEhSC1yLI+z +0gLOrtup5OWv20eejdW+5ea1Uo0p67YXRGmgYrax8eK3m4CoaTrwYafprRQNu/aM +DpCFaoXmSJ52nMf8NUMkfOA4y+APxZsKP+IfOeoJfLY4tUOzPI+PDc764uQAaZqI +2xhkqkuFGJll0v3QEtLKKggG7CHvW5FI8sjQ2SM6H5Q2LzcD8mUJFOzUgzQYfqWl +3rSG55MkwWc7X6Tijkrmq/y8SaOI7+D2d+FbKUWW/V62+30kwTEF2UblIUvrR9GL +93le/CvyqBMrLioA0V8SRzvBbvD45ImcdtMtJYJuOibEjM6xnMUVzYw8zpBX8Kmf +PpskaK6Ks6ZKP68fEByi0+YGlqUZjS9Gs7v1kqzdFpufaHmME9QBDofccEV0oijb +juDPENpmwBFx2u7m7m9MsumTdQmzytQvieVbNunJ5DwkgA+QEe9q0jeRUEvZdcrb +nmc+N9orqZXfGj3a2N6wYEnFFIQZ+dmX6Wz8i2hpBKIg5YdOX4D5KjIC3pQybXQq +5QKdnaO5bnbKi0tqcXh1mKGq4/Otl51JQzSxHRGKpyt8agICf9KxD/ABbczssCbK +ZQYP/suuuV74Ja5nR8Xa1QLTPlkR1fsqogx+fOMjp4qlwOFIVmXXV3WDcLQJYf3q +zP+Um1UhlFXGpLJjpVBbpFGaaBP2t8RDZ8wgXQQkLfp2aQ6qMCFJfV1+ZzGlidPv +oNJCXP8120DONONs/0Wm4z8T0sEytQPwi90BjJ470xEWdepSJSLaUyW71h1j2lRS +fXKHM1r3561KqjVk30bcwpGT1hME8SPmRNp4HCo3ynJqK7JOFN6YAnnGuri87dtk +uF06gMbhG847tCDpdyt9Q3f20w/j48N1oU6QlK8ikQQnWpraMSxNvEPcE3tuj+hg +Vg02ffPufqQsw7rkj+aDdxNQlIRwPG/U3OYNTszMliWnsII6/s5UDSD88j1Zc43n +y9fURACK23NaPnjbIxCXpYWpoctfMx2Ix9z9jVJIG/pFDWV8LUWdloHEBQXNlIRH +Ff84kPiaH3bNrkb3JfNQ484ig5GELVQM9TzmvzuEmzIALByfEtYL0xqweve2JfZp +xuzsZcCSzM/EkmgUWmU5g8Xd5mhYtMeFeHvc/xS9FL2L8q0iWpSucaPOS7N5RQS6 +Sv52TUS7UpjKjxTEAS5mEtvM4mGPjjYh0zqT/mYNn2DOpWr9KOWpn3NvXC1bXVYp +6Qhv3rEJ+Z8YGJhqOjuAGD+GsNmr4S7fqu3Uh8/IbacID0IQFAgnLc31oIwxJ/I2 +4YShdMhUag4TwiToS+NFfUsBuxSyaZasrY+8amgUz2GSNtYJnuU42PSgqSL6+orT +IK12XShPgMhpJPRV0sdQb5eFlrH6laVkWZquj4nbeDIl2wmg8jXQ7ljgAcN5bG7Q +OyZQOZrw1VSLJcpPW1EwKxuMUnjcTZwl0HFV1h9C3XNdTeJWapPzQvB1zAeT9Duf +u/R6aQNuBZrvM+bHY3wHrRAFBxwB1QZ7Osa2txipluB/06BlJwbhK7GRLulayHra +I3Gbj/zpdSG4E8prMXhqrrRyrmfryStjBvFjXl51a2SPscbey7Hvh+LRSj5HURA+ +eG/kOOrKCKloBv8WUcV5+Gh2QkzHkVTBC4LAI3FPkNOhzC6CFFB7CzkhsZqBUeEZ +A63Dim/wZGJpn3IcSut/u1cMKjwaKMkXFf/PAMz2xTAEl7FOwvp/serYtXtQ82Vy ++nC06ARVOSRt5gmha+TFCu55X7AvnkosbP0NrFxYqSyzII5Ts2ciVNwtwAgezgnC +WAArh8SUCKCE36EVLv5kT+7soMQB7LpvqpakvzBg84H7syq5YxuQobpiC049rEQI +WkDAPEF8scC5/jM0mBmHTPaZZlm3po2vxBTc1Axn0sFfMfibTdVHYRYNbWEfs8Ru +nhVYTFrwfecMmvuJFBZXORHaP2vyJjPwRr9wcuLOq45w0Rs+qh+7uZavP7O+vByg +H7XpCoK1npxDJ9TzRh+IDBaY8Tx/OmKw1plVgdWWc7k+wO/xrTrgu2q/QFenYqJH +m00KCQ/l2qVxwtSF8WQFRSUL5v2FVlb1v1HS/Kf9dYMxOblCCbblCACOPK3ugg8c +dydye3cT00v2e1EQoI3MN2hhXpXJnA3C+XJ/52uUk2mctXXRKhZWGsh3jtuOIZ/k +I9ZPorALFP2B5NUgbrtYrw6Qsk/cYotL6SpgU65zoCufMSYelQZdqXaVAA/ZgRU4 +cggq64taQU2QF1HSkBSolK6BRQ7A6hhjDNFFg8/Hce1FGFVOpmscdZ2D/e8tsicG +SApTYDRDRjbMhbLiqTDYkhWjulq9FucyBO75SY/OSSzxD/dtllwaBTRYo/2EW7Ji +f3RWI9I9xtbs8IJ1CkcOsrzKYtmm7Qmvil4IjhClmPvTVg4Kuvo6BCcvahP5yehz +BwXYZ/GJZ6HNPRx+dx2ue+jItI6TaD4jOHnKg5WNDFap4qoLLi4eFf0ro7v5VR6c +M8/g/sz1fbJjC0Orl6I1aDlYbY+GMIIBigKCAYEAun/wmiz60yjw5zDNsMmBXsyr +WYZp06igkBn70ysPYjEuu9lAPXrLrUpBiinuvJc3omV6gsfh750NnR9IhvB6Fdu3 +e7q39wtyLdFFmC2hDbpbg7ywOoTAhS7aGZRdYaHCtXOXfiqPGSAr2C2gzxucjuNP +ivaVuMeYMJigYpf35x9JlCZ5LMbVkfOls3VRUVT1f1qe/jaTinZgr1A3kIEQjP4I +9QwayD6aRGvTyHfyXucr+3jC1tEDSgPS6JG6ARUO27E7u4deHJwtaFAjJ0Y2f9ql +nkT608R6WBho1/V5jLDHXv4PU3IaQ2XkPWHX8CoVDAGjE9kQx2nEK3myozWIEaPk +mmlPgm/dq1uLQoqisrlvsrGKxHx1BlQJJkTfpaPocS5XZtfyd+pMHt0FRQB4K6FY +eEJZcJi9cQcP1nFqMJrXtEd+oJfL9EF1+g3i9ZOAQWWNjSWKm9saB4F8S/GMOYfi +Bo5aO/uQKFr7ypFifLXQaDqNG5j/XiSznQVATeqjAgMBAAE= +-----END PUBLIC KEY----- diff --git a/test/testcomposite87-rsa4096pss.pem b/test/testcomposite87-rsa4096pss.pem new file mode 100644 index 0000000000000..f7ae9b6b3e6fa --- /dev/null +++ b/test/testcomposite87-rsa4096pss.pem @@ -0,0 +1,53 @@ +-----BEGIN PRIVATE KEY----- +MIIJYQIBADAKBggrBgEFBQcGNQSCCU7Pevyn8S+s6aAVqnE+lg5wlxYmgNeDH0wE +XRVsKk8nmDCCCSoCAQACggIBALiVpztwGWjusk39pyjBD/mFzImH8qzFsUhvdeAc +fjEOmOBSxicipU3ufV2BBvpm3RIsCvqO2deyL1BrQtrcxZ2FR2cTRcrLJt706Kkm +HRJFmnhA+9+J6lClsvDrh5msjiOhc590oQ2HNi66X3uxAeBTKxj3HXJuv71NVyi/ +G02/MDOFyrUWts+AsaErfQEYNf3Ddb5fXEBIFwuLtgUYd6m3kSHx+uqkA0MBJuvF +2Yb8MR6WhVg75Qm07KmKPOPmpgoqgtMd/QjSE/JSdgZuwrUZtTWXvFiHi4JxErYS +hnrJGxpKQzMdwWHOQaNB8KiztCRS6iCBCa/sgo7US1iB8Iei28mcV6CB4zmyBc7V +8KAaHGcGIs0v/Dcf4OM7RyTCbK4EFZf+5lNNKCxdeQDMmWuQwld2pA8Ew5f43mk7 +RaXQtAn3QcEod1iGKB7EOl2l1waEWnMie5e6n2ZKW1NXwP42WbWenPDQ7ps4LuRS +Agc8sAgeQbLqZkxJUQxXNhjdNsRnP1Odv3MheOZzNxejHvkOBWyBL1R+2kBSrBQO +uOmHXefQtamS4ysA/HjL4k7+5a+7XWQtSrzNFzjBVLUZ+aAtW8JjQsmbV52m/BFr +OCVgr7jYIfuauNwbvxb3T0tfqV9rNWiaCrKXIPizHmxdejZIfX2Ps93rmL41WxYS +BD27AgMBAAECggIAV0ZTMvRW31l1LxEO12MpdXaA9ko0QOKcZz5kQpnWRMW9HNum +W1yzQjzQQ8S9EupN/siaTEv8zlKuslx02NzoBwm8cA0Zw7/4WhT8aPXfawND/TXk +oZYpFwaxq94BWHTRJCGzdKKFf8r9oGx4txhDZdiNGRnGb5PTzuLhoh9x/nm2hbXt +2V+rAkO8ORNB4KGc7aZcZq3aBX7QfqIJZzFhavqjgaRTWlxAOo8x4urCZmOZqffL +hqOTMNq9x4/YKH2m5kmhX8bfHCuQSNQagAIgx9Ym6vcak9VK7lseWL47nZS23uBc +E7Au/lqyiEmmS23kcARQNRwuA2NVe8j+8xNFMV5q6QzLm6+q83se5TTYcssPRyMH +DkQnfJM81JzFbLs05g1NKy0gNewVSOQVjkH8jlkPf/OIjXdpW8ZKiEbWI4CHhD4T +2Qg567tsqcNUyTiH4tEv19nSNu0eGJQXfiHQ9z8kFUv6MFlKeUaeTl6MjGGOBr8S +ANLV+Kiwgt+uBDcqLoY8xvnBs1ACIUdSmnTyqQEF9eIKrK/YSFczI2rmabhZ6tql +hofrKXjdXQdaxaBkMUvXPuTiNLOtKZsVBhbutxKPEOKk4qcWxHr4901SnYAKCe7t +JRhZ4Xs2U/uDS/J+MGKP6ab0jbhP1s26l0/kaRiT1p8aCsvjbk0fKZPB5rECggEB +AOsSbx2veYwMkyDWtfBRO8e4/FAKPQI3m3rvDGwOmpVsOny3PKQWNg1lg/kbfjju +hdWQ0ZkHkuvibdrNpC/0rFz2ERaJ/O2IC37C0zPXegIOU5wha2Dl+UupVf9XPm68 +aoRL8R6OI2X5nuKyweu1A9HxjW/qMqh8TrA6v5HC29csY3r6c0QlOnW+kaeBZFti +XJgPRzeWH2d24xIOE/CTFa6F0MnbkaW3JyzBmnm5egqmmviNM/lEuI7aFBFks7q2 +QBXQIdSMyTGJp0+OSBlEb3M7HgsCq7ht95cDy7+WZdM2a1nHV/mVjRQyoU1bB9qG +9vQG5Mn461cGLtdoE7yf3IkCggEBAMkEjT9tCXbg2BpH66JaEodLalyfO2F2Yb3V +VG3mVViqwJc2Xfq+pAZ06sD9Zp+j2xXU+ieY7I2smmcchWtLmgSGdOL/TVzbZBV+ +rmnKyjdoikBkgqptRYt/Dw99tMBx1+j7Yc64V8LrP7jy6zKAcSMyI103NSMARrDH +nuXHRof3YTEtDGEqFknqfD2lPsNpL8hx5Vfeqg/jDYypHYlombAVr6ud4cj0t6H5 +93zl5ahVLM1AVzrH1eFhYERzJ9zqFa+2n/Cz7O7NrTqolNlI565sgBeO2+mrmGEk +fHuDmQYZUzfaEwxq5YsliSTMsdw34l8OGnIidyMdc4eCWWCwnyMCggEBANVliKWk +NG0kxTOcdtHQjLpEfhiTEss+e9DfzaESqNZYx8eL+GrlFvCWZXXwtWctcSVtMDkB +nSiyBxQIdrJqJUbGwsB5R7jCNd0/M8fuJn5TTyd/VyFB5EwBT2ZbZvvT48ZxwlQA +qLXcI5acvFojm3ItHD6qlo5JOo3U5y+Fe1kcnLp5PcZxHV7iPwuW9OnYo0IPLJGT +oLKmRICRcxyECbzDEcUNpGyRleiVYIx8CgQ9NpXIaZQyBHD6HBmmF1q6M/cZWHzB +yatE0TPxcBYwABTVZ/KK3CSy/36CHaaw+4L/9fgsdPrH/qiFRdUZfEmvF+RzlaKc +a9g2brNxcelcHjECggEBAMgzr1WHDBEIuFHcZVMJsEBtHN5ofCSCWbBOIkteRowL +a8puDEVpz0Ta9t8EwUunTtC8j/QV+yrSx+h/4GVPI3L0Ur+tk2gy3MgHpj+ZB7MN +e/vL3tNMByJ6hg5gnT+5YlcY3n2a3VU1JP7XeOWQRJ3QFqaFEHfuk3kHJzskMBvE +hlkKy7SNzSsKzXg79nl6bmuM++R60BcIhHseB1vOAJr9zjr3AGM7TxSUNyd+dC8l +vXwiY34Yfux8JfumUQJVZQnesgZxvDzOPYQZWD3bvVrblutfjah5DUdaplwBYctQ +N7B9kdEhOcJOvPsYnt98DQmsqywXJV6ku2YvrUJ+Rc8CggEBAM9nwiRi1ik5tLad +VbvzSQwnDZ0/DBbU2SOX9zWYBKV/4ryFOHdGUpuoiJ8PX+h0334TF/F80PWYXcQz +CKguEQM2PxjcoCjaUtsITngxcZ0VAA7GvHcvNVQ/lL0kiayLgWT7wuu9OzX/v/+3 +YF+4Kw6auRop3+4OThnaaNILOx3eTgoE0MkA/VzptYpL6z6TAWcElZ5xtiAWiD8R +x7BILBawH+BVDBnS6W2ksYK7tkW9owmG3RNOQUlFXBxQQf6xLoZRyW52DP301xTL +eQK1mPuDWJLewhxFcHq+gq9h2fJrH697jL8+GJfsK1Kl1EP3ZdLaaBDm4ptyVU80 +1Ds+JIc= +-----END PRIVATE KEY----- diff --git a/test/testcomposite87-rsa4096psspub.pem b/test/testcomposite87-rsa4096psspub.pem new file mode 100644 index 0000000000000..cd4a31eb2f5b8 --- /dev/null +++ b/test/testcomposite87-rsa4096psspub.pem @@ -0,0 +1,68 @@ +-----BEGIN PUBLIC KEY----- +MIIMPzAKBggrBgEFBQcGNQOCDC8AwuN/TPuEGgFfpF22jsHiul5cKyqv/uIjfbKI +3ma4i92+rUjB/noJv4D1+Aa1FnqRVo0gAyd6mc4p4PJ5/BCjLQ37yLfuxVOK5Qev +ztNxLsm9TjTozv1Z3KWbZLQd3Aq32ETtGUWecRbztNlJlawflTHwkm5+Sbkec+x/ +Fy9iLC+lVB3YGX8nH9RtrSwsR6StwbRfYoC14vcUc3GrEYHQX6SrIlaDy9jiN20h +XNhEhE1pNy0wUZ/1/tqxj/9sf8ogk6IjwCBCG6VRBEzyuHfcNi88vWA9umNvAkG7 +1P8fyy7riiQiorf3JA8fY5Hlul7STu3lercnBsnDqGC5FROsPkXU8DJEEhixSCdP +nUWVvaoAajr52lgF46JULHJ+iowxMQU9qX6P2RagYkfdLX5f6twa1NhuSATAtWKz +BmwB4hNUXo2nj4fRdVdF1wqlHGWbAD6n5ctibNBub0jfycV2g/hmkG3/v81h2UKl +MuN90yHIACDvAvrRYyKUKvv9Pm+DDcpnK1l+iNv4jYvh2et+5Yrke/+WySP/jRbj +4rNprXGADre6RnXO8hSvf6+YQmKDSS2e3dbmdg+He6tEUi4sooakyfxkN3NWqBHT +uR4DvhpnTn4Wz/aExJgTrt3HoanKXNdzNWKMy67Hb17oWeK8WJX2P+JdWK5n/9sw +b4QPaBA2TCCkgeTn9BangwPP29PeHDcgQ+pReztEvNzbFvbqdBfH+0ymEgyahDGA +2wP23Jb1+U6e+Sy5PCv1Met8R5JY/MuAkHRtUMEbiVAtXsxEmqFfKnQiKXpwiB8K +nbOrbPyovYqWKxLunQyAjG8qK5J2cgLEQJhlDNUXNokq87ZR7BMlsHNDCuoiHN7v +5MWCG1zMNAJ5uMycEtIVmsgsxhmyuA90wbAMOPBN9k4o50qszQ/d/o6U491ngT7Y +ZgqQkHf0ThwvoGrKEaLYJC/XoM+I8Wv1SZbpxsoSfBuR6V6vSJiMMhNMBJFNf6UT +KLNVT/Iwtssn2BmiFe40d8gk7WWbSfr37eAsLiqBsfwYZqkO+Od9Rw6W4puvaNPt +Vk3oaywXeqmimkfI/CEq/zVLJQhVsS1O7zh47IZk4RzUmgVqZnuCngHl9B1YqWoD +pt9sbn3Q4ZF7VToWbRnFyg24KlUP/NasfuU4xiDrzIa7CQBvR2h8+R60VOZl8PQs +4qqCjPxJEQmKgl25UIrzrWaDeGXQQ6eQ214EOwyW1iJ5shy9TC/G2nzEpR0rqoCY +YfqvV+5yDrZEfggQxlIoBGKZ6RVjUcxEiG5PdhRTCuK/smlNgNcSsErnmuvHtVbd +wvpPVMfB4DXJrE3o9SlqDsJsOkwGjXb0VOOMnLm53RNBVRQ/QNlZewVUceNjvflj +T+aQEnnEOQMopAQHAKT6mnuPK5oa4gdzcUieK4No8UMiaRO3zlvDSlWUytIr5j3f +Tf0ni8R0eM3xIpPj2l1LCbyRXpcUjKPZqEHKZPKG/uBiBM8y/uyPleHtPfXi31Zp ++sfika+qXBcoq2ws16XA48TZLeDbjqi+vAzptOmQQ9HSaYFH46dPV+dta4WcY81n +BM7PHV2/8RJpTPpapGaFhOdx0F7WPePvk9jI2zVHK5YIkOpQOwUAdRt7EVtVSv6q +56LWahkPyU8bfMsqtserj0WeAciw7U1+zR6HSLX8Vik1pZk8GePjBi//uBSGzVaQ +8IHn7T5J90o6l9diA66kl1mla5ZH+g9jl5BX/fwZ30DBGdRNV606ktBHTBt17wte +UCkC21xTYiUJUGF0j49NwdcXylUgRh99huoNN1J7Zr5IFJNyUrrGh/dew6FrRQv8 +Nyxd8X2d9LujdrNjoJ72elU4wIudMhnxN9vfB4va6h97GWyjtp9k0BqKnuJ1Y88w +zCaHsZAySSrdU1CC6VkqMyBFBHIoA92EVjR4VmwmJDOzYHMPiu06/NxPEfeiI98m +J8o6BlIRamBiV0siEe9dxKehGiU3Z1fV2JrleACRvg8kpmbMI9oUyWrx6YlKugDp +v0nv3q+ErYmdLKOJTcdUm2/sgn/nasNuX0nOzunR82gjXXzAkKc5FrYUkLajzXKj +YG8lhW02i8DdYPmFk0tPydW4RD7RnU2AaGnZnFsPxCpDvv0AGNMR07CPkLL/yAJS +stisJvFlrs5cSAfDkEQf+szbZr0oZUE++CSWHKWfOGlJTFeND5UG8qfWi/pQ3L5I +WtgeDJpn8UJraRXZDSrXcwzAuOL2xcHj8ZeRT9k3/c4V4lQA+YakRLLnDmSqyc7B +cnHUbGLWrsVbFmjt0/P+O36hi+eDD8Nwh8i0KA/NLKM9XqAqZF6yV73BzTQxM7KY +2IWSNXgsXgBo+TwDcqXhmJ0VjzDRoZjJaz6FWDFPVzcKqdzyi03Dp1KPuK8wP7Ym +q3fS0pKGgQA8ZvfMz/bUhYqgWF4Q0yn/UgReoRZIt1aI/VoX2xJoCokBN/BIu1Wv +sVvlTrhq3/wVok6Qd6MYYLxASWL5SE2/tOaCK37yYo6GFOTS5nGxGHzXL7z8l+Kr +dERWnN1/QFgDWaOWhmb60KQelRivTtIYP3askuKIO7WAnIAIQl6a6VSlZChVM59b +eJU76IPZ/ObBLesR7OEPOiHJ+TQXWJGbXXN/51qX0NeXwYxq/HikmIYllVeQ5dSN +6tPhBeopPvc4IYxdyqxVVTvGMHUvCYooCtEF2dnR43oVnim8WoatyMUfkue6UhLN +Ge2HnCs+oCO0XL9M3y6Q2CPHO/0/ZtSszH9Il6vN1YPc2BZCJDn3SbLsqPqepVnh +S2ECx0Q8Tm+9GF9d5iLiai+1p8Q+dhHKL4+7ckeerDg/bVsuYVqxZvf6Pl0RJJW+ +gEBW3kFTMdzDoYGBFPJxYzv0uDuBuUZUB99VlCxetoYmBH0/HGVYAbe9tmXNpB56 +lYlQwOVCd2Y2oNYLwf25XQeICi6xP7pHMFWwxlSTZReaT/N758Eq/2GF/8zSxfhg +aQrfsbm1NSV6LQ4+Q5WJ1WIZefSDyQm1LjTv9SGAmBKPpmFIMvh8k1y9V98KvZTE +WI5hHYF7IRoRP94Cm6xdR0ESw1luiQRrvFAayuI91lCa2dNvOycgiKZ1AbDNrsZ7 +PAO7f9XBFtyiyz+WOEZs7d8+JPzeODw2XNnM0JMzDySd08iGINnguNoEdurGuF/y +vYx2RL4fdeYsFH1/8JQ7scL8QlAPYTd9Ywfm7uiBXHxfLiDfHL8j2Troa01R4f11 +7ohbVzISDZHb2dnrB/+9it4tJzB+Oke7ZV7kjAYJK9Pf9PbWId0AeqK0LSIJV7Z6 +7UfvTUxHRLaHyDfJ2oxZ8IfNkPogIJN4fs+u5ihSUCIyjMBvrrT30wXoC+tnLkk8 +4KhCXaEPONPY2MdPdLuB7Bg8iZl/mDL4nTw/tHKBWqWW7xC0f1LBaGAgBfvfENfr +C/geaAsftzQlbnSh0aUCDXv6PSg1MIICCgKCAgEAuJWnO3AZaO6yTf2nKMEP+YXM +iYfyrMWxSG914Bx+MQ6Y4FLGJyKlTe59XYEG+mbdEiwK+o7Z17IvUGtC2tzFnYVH +ZxNFyssm3vToqSYdEkWaeED734nqUKWy8OuHmayOI6Fzn3ShDYc2Lrpfe7EB4FMr +GPcdcm6/vU1XKL8bTb8wM4XKtRa2z4CxoSt9ARg1/cN1vl9cQEgXC4u2BRh3qbeR +IfH66qQDQwEm68XZhvwxHpaFWDvlCbTsqYo84+amCiqC0x39CNIT8lJ2Bm7CtRm1 +NZe8WIeLgnESthKGeskbGkpDMx3BYc5Bo0HwqLO0JFLqIIEJr+yCjtRLWIHwh6Lb +yZxXoIHjObIFztXwoBocZwYizS/8Nx/g4ztHJMJsrgQVl/7mU00oLF15AMyZa5DC +V3akDwTDl/jeaTtFpdC0CfdBwSh3WIYoHsQ6XaXXBoRacyJ7l7qfZkpbU1fA/jZZ +tZ6c8NDumzgu5FICBzywCB5BsupmTElRDFc2GN02xGc/U52/cyF45nM3F6Me+Q4F +bIEvVH7aQFKsFA646Ydd59C1qZLjKwD8eMviTv7lr7tdZC1KvM0XOMFUtRn5oC1b +wmNCyZtXnab8EWs4JWCvuNgh+5q43Bu/FvdPS1+pX2s1aJoKspcg+LMebF16Nkh9 +fY+z3euYvjVbFhIEPbsCAwEAAQ== +-----END PUBLIC KEY----- diff --git a/test/testutil.h b/test/testutil.h index 7e23f538278b5..cda7716cdf441 100644 --- a/test/testutil.h +++ b/test/testutil.h @@ -712,6 +712,14 @@ STACK_OF(X509) *load_certs_pem(const char *file); X509_REQ *load_csr_der(const char *file, OSSL_LIB_CTX *libctx); int test_asn1_string_to_time_t(const char *asn1_string, time_t *out_time_t); int compare_with_reference_file(BIO *membio, const char *reffile); + +/* + * Parse a non-negative decimal integer from |value| into |*result|. Returns 1 + * on success, 0 on failure (NULL/empty/non-numeric/negative/overflowing input, + * or trailing garbage). Test binaries link only against the public ABI, so + * this wraps OPENSSL_strtoul() rather than the libcrypto-internal helpers. + */ +int test_strtoint(const char *value, int *result); /* * Create an X509 from an array of strings. */ diff --git a/test/testutil/basic_output.c b/test/testutil/basic_output.c index 110cc252d4e84..23e3fef10cf70 100644 --- a/test/testutil/basic_output.c +++ b/test/testutil/basic_output.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -24,6 +24,7 @@ static BIO *tap_err = NULL; typedef struct local_test_data_st { BIO *override_bio_out, *override_bio_err; + int io_lock_depth; /**< Recursion depth of this thread's io_lock hold */ } LOCAL_TEST_DATA; #if defined(OPENSSL_THREADS) @@ -185,9 +186,20 @@ void test_close_streams(void) #endif } +/*- + * The lock is taken recursively, tracked by a per-thread depth count, so + * that a caller may hold it across a whole output record while the + * individual writes making up that record continue to take it. A thread + * with no thread-local data available cannot track the depth, and so + * falls back to taking the lock for each write. + */ static ossl_inline void test_io_lock(void) { #if defined(OPENSSL_THREADS) + LOCAL_TEST_DATA *data = get_local_test_data(); + + if (data != NULL && data->io_lock_depth++ > 0) + return; OPENSSL_assert(CRYPTO_THREAD_write_lock(io_lock) > 0); #endif } @@ -195,10 +207,44 @@ static ossl_inline void test_io_lock(void) static ossl_inline void test_io_unlock(void) { #if defined(OPENSSL_THREADS) + LOCAL_TEST_DATA *data = get_local_test_data(); + + if (data != NULL && --data->io_lock_depth > 0) + return; CRYPTO_THREAD_unlock(io_lock); #endif } +/*- + * A thread with no thread-local data has nowhere to record the depth, so + * it must not hold the lock across the record: the writes within would + * deadlock against it. Such a thread falls back to the per-write + * locking, and its records may interleave as they did before. + * + * The depth is tested rather than assumed on the way out, so that a + * begin which found no thread-local data is not matched by an end which + * finds some and releases a lock this thread never took. + */ +void test_output_record_begin(void) +{ +#if defined(OPENSSL_THREADS) + if (get_local_test_data() == NULL) + return; + test_io_lock(); +#endif +} + +void test_output_record_end(void) +{ +#if defined(OPENSSL_THREADS) + LOCAL_TEST_DATA *data = get_local_test_data(); + + if (data == NULL || data->io_lock_depth == 0) + return; + test_io_unlock(); +#endif +} + int test_vprintf_stdout(const char *fmt, va_list ap) { int r; diff --git a/test/testutil/driver.c b/test/testutil/driver.c index bfcb65b7bc62f..8e3637acfeb88 100644 --- a/test/testutil/driver.c +++ b/test/testutil/driver.c @@ -13,6 +13,7 @@ #include #include +#include #include "internal/nelem.h" #include @@ -138,14 +139,22 @@ int setup_test_framework(int argc, char *argv[]) char *test_rand_seed = getenv("OPENSSL_TEST_RAND_SEED"); char *TAP_levels = getenv("HARNESS_OSSL_LEVEL"); - if (TAP_levels != NULL) - level = 4 * atoi(TAP_levels); + if (TAP_levels != NULL) { + int n; + + if (test_strtoint(TAP_levels, &n) && n <= INT_MAX / 4) + level = 4 * n; + } test_adjust_streams_tap_level(level); if (test_rand_order != NULL) { + int n; + rand_order = 1; - set_seed(atoi(test_rand_order)); + set_seed(test_strtoint(test_rand_order, &n) ? n : 0); } else if (test_rand_seed != NULL) { - set_seed(atoi(test_rand_seed)); + int n; + + set_seed(test_strtoint(test_rand_seed, &n) ? n : 0); } else { set_seed(0); } @@ -178,8 +187,12 @@ static int check_single_test_params(char *name, char *testname, char *itname) break; } } - if (i >= num_tests) - single_test = atoi(name); + if (i >= num_tests) { + int n; + + if (test_strtoint(name, &n)) + single_test = n; + } } /* if only iteration is specified, assume we want the first test */ diff --git a/test/testutil/format_output.c b/test/testutil/format_output.c index 5bb530298939d..7a7a1d7fcf14f 100644 --- a/test/testutil/format_output.c +++ b/test/testutil/format_output.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -129,15 +129,19 @@ void test_fail_string_message(const char *prefix, const char *file, const char *op, const char *m1, size_t l1, const char *m2, size_t l2) { + test_output_record_begin(); test_fail_string_common(prefix, file, line, type, left, right, op, m1, l1, m2, l2); test_printf_stderr("\n"); + test_output_record_end(); } void test_output_string(const char *name, const char *m, size_t l) { + test_output_record_begin(); test_fail_string_common("string", NULL, 0, NULL, NULL, NULL, name, m, l, m, l); + test_output_record_end(); } /* BIGNUM formatted output routines */ @@ -369,8 +373,10 @@ void test_fail_bignum_message(const char *prefix, const char *file, const char *op, const BIGNUM *bn1, const BIGNUM *bn2) { + test_output_record_begin(); test_fail_bignum_common(prefix, file, line, type, left, right, op, bn1, bn2); test_printf_stderr("\n"); + test_output_record_end(); } void test_fail_bignum_mono_message(const char *prefix, const char *file, @@ -378,12 +384,15 @@ void test_fail_bignum_mono_message(const char *prefix, const char *file, const char *left, const char *right, const char *op, const BIGNUM *bn) { + test_output_record_begin(); test_fail_bignum_common(prefix, file, line, type, left, right, op, bn, bn); test_printf_stderr("\n"); + test_output_record_end(); } void test_output_bignum(const char *name, const BIGNUM *bn) { + test_output_record_begin(); if (bn == NULL || BN_is_zero(bn)) { test_printf_stderr("bignum: '%s' = %s\n", name == NULL ? "" : name, @@ -404,6 +413,7 @@ void test_output_bignum(const char *name, const BIGNUM *bn) test_fail_bignum_common("bignum", NULL, 0, NULL, NULL, NULL, name, bn, bn); } + test_output_record_end(); } /* Memory output routines */ @@ -524,13 +534,17 @@ void test_fail_memory_message(const char *prefix, const char *file, const unsigned char *m1, size_t l1, const unsigned char *m2, size_t l2) { + test_output_record_begin(); test_fail_memory_common(prefix, file, line, type, left, right, op, m1, l1, m2, l2); test_printf_stderr("\n"); + test_output_record_end(); } void test_output_memory(const char *name, const unsigned char *m, size_t l) { + test_output_record_begin(); test_fail_memory_common("memory", NULL, 0, NULL, NULL, NULL, name, m, l, m, l); + test_output_record_end(); } diff --git a/test/testutil/helper.c b/test/testutil/helper.c index 551b9a200bc3c..16af95eaa8a8e 100644 --- a/test/testutil/helper.c +++ b/test/testutil/helper.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -7,12 +7,24 @@ * https://www.openssl.org/source/license.html */ #include +#include #include #include +#include #include "../testutil.h" +int test_strtoint(const char *value, int *result) +{ + unsigned long ul; + + if (!OPENSSL_strtoul(value, NULL, 10, &ul) || ul > INT_MAX) + return 0; + *result = (int)ul; + return 1; +} + int test_asn1_string_to_time_t(const char *asn1_string, time_t *out_time_t) { int ret = 0; diff --git a/test/testutil/main.c b/test/testutil/main.c index 940d25f7071e5..65b3284892b5e 100644 --- a/test/testutil/main.c +++ b/test/testutil/main.c @@ -7,6 +7,9 @@ * https://www.openssl.org/source/license.html */ +#include +#include +#include #include #include "../testutil.h" #include "output.h" @@ -20,6 +23,94 @@ #endif #endif /* defined(__has_include) */ +/* + * Watchdog: abort a test program that runs longer than a fixed time limit. + * A hung test otherwise consumes the entire CI job budget (e.g. 6 hours); the + * watchdog turns that into a prompt failure that names the test and, where the + * environment enables core dumps, leaves a core with every thread's stack for + * diagnosis. The limit is TEST_WATCHDOG_TIMEOUT seconds, overridable with the + * OPENSSL_TEST_TIMEOUT environment variable; a value of 0 or less disables it. + * + * The default must exceed the slowest legitimate testutil program on the + * slowest supported target (app-based recipes have their own main() and are + * not covered here). Under emulated hppa the slowest such program runs well + * under ten minutes, so thirty minutes leaves ample margin. + */ +#define TEST_WATCHDOG_TIMEOUT 1800 + +#if !defined(OPENSSL_SYS_WINDOWS) +#include +#include + +/* + * The message is prepared at arm time (with the actual limit) so that the + * signal handler only has to call write(), which is async-signal-safe; + * snprintf() is not. + */ +static char watchdog_msg[128]; +static size_t watchdog_msg_len; + +static void test_watchdog_expired(int sig) +{ + (void)sig; + if (write(STDERR_FILENO, watchdog_msg, watchdog_msg_len) < 0) { + } + abort(); +} + +static void test_watchdog_start(unsigned int timeout) +{ + int n = snprintf(watchdog_msg, sizeof(watchdog_msg), + "\n# test watchdog: exceeded time limit of %u seconds, aborting\n", + timeout); + + if (n < 0) + n = 0; + else if ((size_t)n >= sizeof(watchdog_msg)) + n = sizeof(watchdog_msg) - 1; + watchdog_msg_len = (size_t)n; + + signal(SIGALRM, test_watchdog_expired); + alarm(timeout); +} +#else +#include +#include + +static DWORD WINAPI test_watchdog_thread(LPVOID arg) +{ + unsigned int timeout = (unsigned int)(uintptr_t)arg; + + Sleep((DWORD)timeout * 1000); + fprintf(stderr, + "\n# test watchdog: exceeded time limit of %u seconds, aborting\n", + timeout); + fflush(stderr); + abort(); + return 0; +} + +static void test_watchdog_start(unsigned int timeout) +{ + CreateThread(NULL, 0, test_watchdog_thread, + (LPVOID)(uintptr_t)timeout, 0, NULL); +} +#endif /* !defined(OPENSSL_SYS_WINDOWS) */ + +static void setup_test_watchdog(void) +{ + long timeout = TEST_WATCHDOG_TIMEOUT; + const char *e = getenv("OPENSSL_TEST_TIMEOUT"); + + if (e != NULL && *e != '\0') + timeout = strtol(e, NULL, 10); + if (timeout <= 0) + return; + if ((unsigned long)timeout > UINT_MAX) + timeout = UINT_MAX; + test_watchdog_start((unsigned int)timeout); +} + /* * At some point we should consider looking at this function with a view to * moving most/all of this into onfree handlers in OSSL_LIB_CTX. @@ -40,6 +131,8 @@ int main(int argc, char *argv[]) test_open_streams(); + setup_test_watchdog(); + if (!gi_ret) { test_printf_stderr("Global init failed - aborting\n"); return ret; diff --git a/test/testutil/options.c b/test/testutil/options.c index 37be4facac33d..a2b7bb8bed00f 100644 --- a/test/testutil/options.c +++ b/test/testutil/options.c @@ -1,5 +1,5 @@ /* - * Copyright 2018-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -39,7 +39,7 @@ char *test_get_argument(size_t n) { char **argv = opt_rest(); - OPENSSL_assert(n < sizeof(used)); + OPENSSL_assert(n < OSSL_NELEM(used)); if ((int)n >= opt_num_rest() || argv == NULL) return NULL; used[n] = 1; diff --git a/test/testutil/output.h b/test/testutil/output.h index e4f6058ac79b9..8914e6c4fc09f 100644 --- a/test/testutil/output.h +++ b/test/testutil/output.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2014-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -40,6 +40,21 @@ int test_flush_tapout(void); int test_flush_stderr(void); int test_flush_taperr(void); +/** + * @brief Begin a logical output record. + * Writes made by this thread until the matching test_output_record_end() + * are emitted as a unit, so that a record composed of several writes is + * not interleaved with output from another thread. Calls nest; only the + * outermost pair has an effect. Has no effect in a build without + * threads. + */ +void test_output_record_begin(void); + +/** + * @brief End a logical output record begun by test_output_record_begin(). + */ +void test_output_record_end(void); + /* Commodity functions. There's no need to override these */ int test_printf_stdout(const char *fmt, ...) ossl_test__attr__((__format__(__printf__, 1, 2))); diff --git a/test/testutil/tests.c b/test/testutil/tests.c index ccc4727bac720..88e87892259ec 100644 --- a/test/testutil/tests.c +++ b/test/testutil/tests.c @@ -76,12 +76,14 @@ static void test_fail_message_va(const char *prefix, const char *file, const char *left, const char *right, const char *op, const char *fmt, va_list ap) { + test_output_record_begin(); test_fail_message_prefix(prefix, file, line, type, left, right, op); if (fmt != NULL) { test_vprintf_stderr(fmt, ap); test_printf_stderr("\n"); } test_flush_stderr(); + test_output_record_end(); } static void test_fail_message(const char *prefix, const char *file, @@ -118,20 +120,24 @@ void test_error_c90(const char *desc, ...) { va_list ap; + test_output_record_begin(); va_start(ap, desc); test_fail_message_va(NULL, NULL, -1, NULL, NULL, NULL, NULL, desc, ap); va_end(ap); test_printf_stderr("\n"); + test_output_record_end(); } void test_error(const char *file, int line, const char *desc, ...) { va_list ap; + test_output_record_begin(); va_start(ap, desc); test_fail_message_va(NULL, file, line, NULL, NULL, NULL, NULL, desc, ap); va_end(ap); test_printf_stderr("\n"); + test_output_record_end(); } void test_perror(const char *s) @@ -145,6 +151,7 @@ void test_perror(const char *s) void test_note(const char *fmt, ...) { + test_output_record_begin(); test_flush_stdout(); if (fmt != NULL) { va_list ap; @@ -155,6 +162,7 @@ void test_note(const char *fmt, ...) test_printf_stderr("\n"); } test_flush_stderr(); + test_output_record_end(); } int test_skip(const char *file, int line, const char *desc, ...) @@ -171,16 +179,20 @@ int test_skip_c90(const char *desc, ...) { va_list ap; + test_output_record_begin(); va_start(ap, desc); test_fail_message_va("SKIP", NULL, -1, NULL, NULL, NULL, NULL, desc, ap); va_end(ap); test_printf_stderr("\n"); + test_output_record_end(); return TEST_SKIP_CODE; } void test_openssl_errors(void) { + test_output_record_begin(); ERR_print_errors_cb(openssl_error_cb, NULL); + test_output_record_end(); ERR_clear_error(); } @@ -533,11 +545,6 @@ int test_BN_abs_eq_word(const char *file, int line, const char *bns, return 0; } -static const char *print_time(const ASN1_TIME *t) -{ - return t == NULL ? "" : (const char *)ASN1_STRING_get0_data(t); -} - #define DEFINE_TIME_T_COMPARISON(opname, op) \ int test_time_t_##opname(const char *file, int line, \ const char *s1, const char *s2, \ @@ -547,10 +554,21 @@ static const char *print_time(const ASN1_TIME *t) ASN1_TIME *at2 = ASN1_TIME_set(NULL, t2); \ int r = at1 != NULL && at2 != NULL \ && ASN1_TIME_compare(at1, at2) op 0; \ - if (!r) \ + if (!r) { \ + const char *d1 = "", *d2 = ""; \ + int n1 = (int)(sizeof("") - 1), n2 = n1; \ + \ + if (at1 != NULL) { \ + d1 = (const char *)ASN1_STRING_get0_data(at1); \ + n1 = (int)ASN1_STRING_get_length(at1); \ + } \ + if (at2 != NULL) { \ + d2 = (const char *)ASN1_STRING_get0_data(at2); \ + n2 = (int)ASN1_STRING_get_length(at2); \ + } \ test_fail_message(NULL, file, line, "time_t", s1, s2, #op, \ - "[%s] compared to [%s]", \ - print_time(at1), print_time(at2)); \ + "[%.*s] compared to [%.*s]", n1, d1, n2, d2); \ + } \ ASN1_STRING_free(at1); \ ASN1_STRING_free(at2); \ return r; \ diff --git a/test/testutil/testutil_init.c b/test/testutil/testutil_init.c index e4ca6e3a4235e..3331f32dcc213 100644 --- a/test/testutil/testutil_init.c +++ b/test/testutil/testutil_init.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -33,7 +33,7 @@ static size_t internal_trace_cb(const char *buf, size_t cnt, tid = CRYPTO_THREAD_get_current_id(); hex = OPENSSL_buf2hexstr((const unsigned char *)&tid, sizeof(tid)); - BIO_snprintf(buffer, sizeof(buffer), "TRACE[%s]:%s: ", + snprintf(buffer, sizeof(buffer), "TRACE[%s]:%s: ", hex, OSSL_trace_get_category_name(category)); OPENSSL_free(hex); BIO_set_prefix(trace_data->bio, buffer); diff --git a/test/threadstest.c b/test/threadstest.c index 50a5d903403f9..1e7841ce2de9a 100644 --- a/test/threadstest.c +++ b/test/threadstest.c @@ -117,18 +117,42 @@ static int rw_torture_result = 1; static CRYPTO_RWLOCK *rwtorturelock = NULL; static CRYPTO_RWLOCK *atomiclock = NULL; +/*- + * Every write is a race for the readers to catch, and the readers read + * continuously for as long as the writers run. The number of writes is + * therefore what decides the smallest fault the test reliably catches: + * one showing on a fraction p of write races is caught with probability + * 1 - (1 - p) ^ writes, so 100000 writes cover anything at or above 5e-5. + * There is no point at which the sampling is complete -- a rarer fault + * just needs more writes -- so this is a floor for the default run rather + * than a derived figure. + * + * The low contention writers sleep a millisecond between writes, which + * holds them near 1600 writes a second, so they are given fewer. + * + * These counts are per writer and there are two writers, so the races + * sampled are twice the figures below. + * + * The elapsed time check remains as a backstop, so that a machine too + * slow to reach the target stops where it would have stopped before. + */ +#define TORTURE_WRITES 50000 +#define TORTURE_WRITES_LOW 1000 +#define TORTURE_SECONDS 4 + static void rwwriter_fn(int id, int *iterations) { int count; int *old, *new; + int writes = contention == 0 ? TORTURE_WRITES_LOW : TORTURE_WRITES; OSSL_TIME t1, t2; t1 = ossl_time_now(); - for (count = 0;; count++) { + for (count = 0; count < writes; count++) { new = OPENSSL_zalloc(sizeof(int)); OPENSSL_assert(new != NULL); if (contention == 0) - OSSL_sleep(1000); + OSSL_sleep(1); if (!CRYPTO_THREAD_write_lock(rwtorturelock)) abort(); if (rwwriter_ptr != NULL) { @@ -143,7 +167,7 @@ static void rwwriter_fn(int id, int *iterations) if (old != NULL) CRYPTO_free(old, __FILE__, __LINE__); t2 = ossl_time_now(); - if ((ossl_time2seconds(t2) - ossl_time2seconds(t1)) >= 4) + if ((ossl_time2seconds(t2) - ossl_time2seconds(t1)) >= TORTURE_SECONDS) break; } *iterations = count; @@ -318,13 +342,14 @@ static void free_old_rcu_data(void *data) static void writer_fn(int id, int *iterations) { int count; + int writes = contention == 0 ? TORTURE_WRITES_LOW : TORTURE_WRITES; OSSL_TIME t1, t2; uint64_t *old, *new; CRYPTO_RCU_CB_ITEM *cbi = NULL; t1 = ossl_time_now(); - for (count = 0;; count++) { + for (count = 0; count < writes; count++) { new = OPENSSL_zalloc(sizeof(uint64_t)); OPENSSL_assert(new != NULL); *new = (uint64_t)0xBAD; @@ -335,7 +360,7 @@ static void writer_fn(int id, int *iterations) } if (contention == 0) - OSSL_sleep(1000); + OSSL_sleep(1); ossl_rcu_write_lock(rcu_lock); old = ossl_rcu_deref(&writer_ptr); TSAN_ACQUIRE(&writer_ptr); @@ -349,7 +374,7 @@ static void writer_fn(int id, int *iterations) CRYPTO_free(old, NULL, 0); } t2 = ossl_time_now(); - if ((ossl_time2seconds(t2) - ossl_time2seconds(t1)) >= 4) + if ((ossl_time2seconds(t2) - ossl_time2seconds(t1)) >= TORTURE_SECONDS) break; } *iterations = count; @@ -1190,10 +1215,10 @@ static void test_obj_create_one(void) char tids[12], oid[40], sn[30], ln[30]; int id = get_new_uid(); - BIO_snprintf(tids, sizeof(tids), "%d", id); - BIO_snprintf(oid, sizeof(oid), "1.3.6.1.4.1.16604.%s", tids); - BIO_snprintf(sn, sizeof(sn), "short-name-%s", tids); - BIO_snprintf(ln, sizeof(ln), "long-name-%s", tids); + snprintf(tids, sizeof(tids), "%d", id); + snprintf(oid, sizeof(oid), "1.3.6.1.4.1.16604.%s", tids); + snprintf(sn, sizeof(sn), "short-name-%s", tids); + snprintf(ln, sizeof(ln), "long-name-%s", tids); if (!TEST_int_ne(id, 0) || !TEST_true(id = OBJ_create(oid, sn, ln)) || !TEST_true(OBJ_add_sigid(id, NID_sha3_256, NID_rsa))) @@ -1379,7 +1404,7 @@ static void test_obj_create_worker(void) for (i = 0; i < 4; i++) { now = time(NULL); - BIO_snprintf(name, sizeof(name), "Time in Seconds = %ld", (long)now); + snprintf(name, sizeof(name), "Time in Seconds = %ld", (long)now); while (now == time(NULL)) /* no-op */; nid = OBJ_create(NULL, NULL, name); diff --git a/test/timing_load_creds.c b/test/timing_load_creds.c index 5e9e2bf6c0a2a..43996a726174c 100644 --- a/test/timing_load_creds.c +++ b/test/timing_load_creds.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -9,8 +9,10 @@ #include #include +#include #include +#include #ifdef OPENSSL_SYS_UNIX #include @@ -120,10 +122,14 @@ int main(int ac, char **av) default: usage(); break; - case 'c': - if ((count = atoi(optarg)) < 0) + case 'c': { + unsigned long ul; + + if (!OPENSSL_strtoul(optarg, NULL, 10, &ul) || ul > INT_MAX) usage(); + count = (int)ul; break; + } case 'd': debug = 1; break; diff --git a/test/tls-provider.c b/test/tls-provider.c index 6652034936c12..537ee8efb58d3 100644 --- a/test/tls-provider.c +++ b/test/tls-provider.c @@ -218,8 +218,8 @@ static struct tls_group_st xor_group = { 128, /* secbits */ TLS1_2_VERSION, /* mintls */ 0, /* maxtls */ - -1, /* mindtls */ - -1, /* maxdtls */ + DTLS1_3_VERSION, /* mindtls */ + 0, /* maxdtls */ 0 /* is_kem */ }; @@ -230,8 +230,8 @@ static struct tls_group_st xor_kemgroup = { 128, /* secbits */ TLS1_3_VERSION, /* mintls */ 0, /* maxtls */ - -1, /* mindtls */ - -1, /* maxdtls */ + DTLS1_3_VERSION, /* mindtls */ + 0, /* maxdtls */ 1 /* is_kem */ }; @@ -286,6 +286,8 @@ struct tls_sigalg_st { unsigned int secbits; unsigned int mintls; unsigned int maxtls; + unsigned int mindtls; + unsigned int maxdtls; }; #define XORSIGALG_NAME "xorhmacsig" @@ -301,6 +303,8 @@ static struct tls_sigalg_st xor_sigalg = { 128, /* secbits */ TLS1_3_VERSION, /* mintls */ 0, /* maxtls */ + DTLS1_3_VERSION, /* mindtls */ + 0, /* maxdtls */ }; static struct tls_sigalg_st xor_sigalg_hash = { @@ -308,6 +312,8 @@ static struct tls_sigalg_st xor_sigalg_hash = { 128, /* secbits */ TLS1_3_VERSION, /* mintls */ 0, /* maxtls */ + DTLS1_3_VERSION, /* mindtls */ + 0, /* maxdtls */ }; static struct tls_sigalg_st xor_sigalg12 = { @@ -315,6 +321,8 @@ static struct tls_sigalg_st xor_sigalg12 = { 128, /* secbits */ TLS1_2_VERSION, /* mintls */ TLS1_2_VERSION, /* maxtls */ + DTLS1_2_VERSION, /* mindtls */ + DTLS1_2_VERSION, /* maxdtls */ }; static const OSSL_PARAM xor_sig_nohash_params[] = { @@ -333,6 +341,10 @@ static const OSSL_PARAM xor_sig_nohash_params[] = { &xor_sigalg.mintls), OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS, &xor_sigalg.maxtls), + OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MIN_DTLS, + &xor_sigalg.mindtls), + OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MAX_DTLS, + &xor_sigalg.maxdtls), OSSL_PARAM_END }; @@ -354,6 +366,10 @@ static const OSSL_PARAM xor_sig_hash_params[] = { &xor_sigalg_hash.mintls), OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS, &xor_sigalg_hash.maxtls), + OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MIN_DTLS, + &xor_sigalg_hash.mindtls), + OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MAX_DTLS, + &xor_sigalg_hash.maxdtls), OSSL_PARAM_END }; @@ -373,6 +389,10 @@ static const OSSL_PARAM xor_sig_12_params[] = { &xor_sigalg12.mintls), OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MAX_TLS, &xor_sigalg12.maxtls), + OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MIN_DTLS, + &xor_sigalg12.mindtls), + OSSL_PARAM_int(OSSL_CAPABILITY_TLS_SIGALG_MAX_DTLS, + &xor_sigalg12.maxdtls), OSSL_PARAM_END }; @@ -408,7 +428,7 @@ static int tls_prov_get_capabilities(void *provctx, const char *capability, dummy_group_names[i] = OPENSSL_zalloc(dummy_name_max_size); if (dummy_group_names[i] == NULL) return 0; - BIO_snprintf(dummy_group_names[i], + snprintf(dummy_group_names[i], dummy_name_max_size, "%s%d", dummy_base, i); } @@ -725,7 +745,7 @@ static int xor_key_up_ref(XORKEY *key) { int refcnt; - if (CRYPTO_UP_REF(&key->references, &refcnt) <= 0) + if (!CRYPTO_UP_REF(&key->references, &refcnt)) return 0; assert(refcnt > 1); @@ -1282,7 +1302,7 @@ static XORKEY *xor_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, plen = 0; } else { p = ASN1_STRING_get0_data(oct); - plen = ASN1_STRING_length(oct); + plen = (int)ASN1_STRING_get_length(oct); } xork = xor_key_op(palg, p, plen, KEY_OP_PRIVATE, diff --git a/test/tls13encryptiontest.c b/test/tls13encryptiontest.c index 1bb940ae875bc..033d8d20c24e4 100644 --- a/test/tls13encryptiontest.c +++ b/test/tls13encryptiontest.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2023 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -214,9 +214,9 @@ static unsigned char *multihexstr2buf(const char *str[3], size_t *len) static int load_record(TLS_RL_RECORD *rec, RECORD_DATA *recd, unsigned char **key, unsigned char *iv, size_t ivlen, - unsigned char *seq) + uint64_t *seq) { - unsigned char *pt = NULL, *sq = NULL, *ivtmp = NULL; + unsigned char *pt = NULL, *sq = NULL, *p_sq, *ivtmp = NULL; size_t ptlen; *key = OPENSSL_hexstr2buf(recd->key, NULL); @@ -235,7 +235,8 @@ static int load_record(TLS_RL_RECORD *rec, RECORD_DATA *recd, rec->length = ptlen; memcpy(rec->data, pt, ptlen); OPENSSL_free(pt); - memcpy(seq, sq, SEQ_NUM_SIZE); + p_sq = sq; + n2l8(p_sq, *seq); OPENSSL_free(sq); memcpy(iv, ivtmp, ivlen); OPENSSL_free(ivtmp); @@ -285,7 +286,7 @@ static int test_tls13_encryption(void) const EVP_CIPHER *ciph = EVP_aes_128_gcm(); int ret = 0; size_t ivlen, ctr; - unsigned char seqbuf[SEQ_NUM_SIZE]; + uint64_t recseq; unsigned char iv[EVP_MAX_IV_LENGTH]; OSSL_RECORD_LAYER *rrl = NULL, *wrl = NULL; @@ -300,7 +301,7 @@ static int test_tls13_encryption(void) for (ctr = 0; ctr < OSSL_NELEM(refdata); ctr++) { /* Load the record */ ivlen = EVP_CIPHER_get_iv_length(ciph); - if (!load_record(&rec, &refdata[ctr], &key, iv, ivlen, seqbuf)) { + if (!load_record(&rec, &refdata[ctr], &key, iv, ivlen, &recseq)) { TEST_error("Failed loading key into EVP_CIPHER_CTX"); goto err; } @@ -310,12 +311,14 @@ static int test_tls13_encryption(void) NULL, NULL, TLS1_3_VERSION, OSSL_RECORD_ROLE_SERVER, OSSL_RECORD_DIRECTION_WRITE, OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, 0, NULL, 0, - key, 16, iv, ivlen, NULL, 0, EVP_aes_128_gcm(), + NULL, key, 16, iv, ivlen, NULL, 0, NULL, + EVP_aes_128_gcm(), EVP_GCM_TLS_TAG_LEN, 0, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, + NULL, 0, NULL, NULL, NULL, NULL, NULL, &wrl))) goto err; - memcpy(wrl->sequence, seqbuf, sizeof(seqbuf)); + + wrl->sequence = recseq; /* Encrypt it */ if (!TEST_size_t_eq(wrl->funcs->cipher(wrl, &rec, 1, 1, NULL, 0), 1)) { @@ -333,12 +336,14 @@ static int test_tls13_encryption(void) NULL, NULL, TLS1_3_VERSION, OSSL_RECORD_ROLE_SERVER, OSSL_RECORD_DIRECTION_READ, OSSL_RECORD_PROTECTION_LEVEL_APPLICATION, 0, NULL, 0, - key, 16, iv, ivlen, NULL, 0, EVP_aes_128_gcm(), + NULL, key, 16, iv, ivlen, NULL, 0, NULL, + EVP_aes_128_gcm(), EVP_GCM_TLS_TAG_LEN, 0, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, + NULL, 0, NULL, NULL, NULL, NULL, NULL, &rrl))) goto err; - memcpy(rrl->sequence, seqbuf, sizeof(seqbuf)); + + rrl->sequence = recseq; /* Decrypt it */ if (!TEST_int_eq(rrl->funcs->cipher(rrl, &rec, 1, 0, NULL, 0), 1)) { diff --git a/test/tls13secretstest.c b/test/tls13secretstest.c index d5622f7cdfe6a..098e80c5c17b2 100644 --- a/test/tls13secretstest.c +++ b/test/tls13secretstest.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -158,6 +158,12 @@ const EVP_MD *ssl_handshake_md(SSL_CONNECTION *s) return EVP_sha256(); } +int ssl_cipher_get_evp_cipher_sn(SSL_CTX *ctx, const SSL_CIPHER *sslc, + const EVP_CIPHER **enc) +{ + return 0; +} + int ssl_cipher_get_evp_cipher(SSL_CTX *ctx, const SSL_CIPHER *sslc, const EVP_CIPHER **enc) { @@ -172,7 +178,9 @@ int ssl_cipher_get_evp_md_mac(SSL_CTX *ctx, const SSL_CIPHER *sslc, } int ssl_cipher_get_evp(SSL_CTX *ctx, const SSL_SESSION *s, - const EVP_CIPHER **enc, const EVP_MD **md, + const EVP_CIPHER **snenc, + const EVP_CIPHER **enc, + const EVP_MD **md, int *mac_pkey_type, size_t *mac_secret_size, SSL_COMP **comp, int use_etm) @@ -227,9 +235,11 @@ void ssl_evp_md_free(const EVP_MD *md) int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, int direction, int level, unsigned char *secret, size_t secretlen, + unsigned char *snkey, unsigned char *key, size_t keylen, unsigned char *iv, size_t ivlen, unsigned char *mackey, size_t mackeylen, + const EVP_CIPHER *snciph, const EVP_CIPHER *ciph, size_t taglen, int mactype, const EVP_MD *md, const SSL_COMP *comp, const EVP_MD *kdfdigest) @@ -237,6 +247,28 @@ int ssl_set_new_record_layer(SSL_CONNECTION *s, int version, int direction, return 0; } +void dtls1_clear_received_buffer(SSL_CONNECTION *s) +{ +} + +void dtls1_clear_sent_buffer(SSL_CONNECTION *s, int keep_unacked_msgs) +{ +} + +void dtls1_acknowledge_sent_buffer(SSL_CONNECTION *s, uint64_t before_epoch) +{ +} + +uint64_t dtls1_get_epoch(SSL_CONNECTION *s, int rw) +{ + return 0; +} + +int dtls1_increment_epoch(SSL_CONNECTION *s, int rw) +{ + return 0; +} + /* End of mocked out code */ static int test_secret(SSL_CONNECTION *s, unsigned char *prk, @@ -415,8 +447,94 @@ static int test_handshake_secrets(void) return ret; } +/* Full DTLS 1.3 ClientHello as stored in the handshake buffer (393 bytes) */ +/* clang-format off */ +static const unsigned char dtls_raw_transcript[] = { + 0x01, 0x00, 0x01, 0x7d, /* type=ClientHello, length=381 (kept) */ + 0x00, 0x00, /* msg_seq=0 (stripped) */ + 0x00, 0x00, 0x00, /* fragment_offset=0 (stripped) */ + 0x00, 0x01, 0x7d, /* fragment_length=381 (stripped) */ + /* ClientHello body (381 bytes, kept) */ + 0xfe, 0xfd, 0x12, 0x1e, 0xc1, 0x2d, 0x3a, 0xe2, 0x3d, 0xcf, 0x4e, 0x83, + 0x0d, 0xf4, 0x5b, 0x6a, 0x38, 0xd9, 0x4c, 0xcc, 0x8f, 0x4c, 0x53, 0xef, + 0xd4, 0xca, 0xaa, 0x4d, 0x5d, 0x2f, 0x03, 0x71, 0x4d, 0x50, 0x00, 0x00, + 0x00, 0x06, 0x13, 0x02, 0x13, 0x03, 0x13, 0x01, 0x01, 0x00, 0x01, 0x4d, + 0x00, 0x0a, 0x00, 0x04, 0x00, 0x02, 0x00, 0x17, 0x00, 0x23, 0x00, 0x00, + 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x08, + 0x00, 0x06, 0x04, 0x03, 0x08, 0x04, 0x04, 0x01, 0x00, 0x2b, 0x00, 0x03, + 0x02, 0xfe, 0xfc, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x33, 0x00, + 0x47, 0x00, 0x45, 0x00, 0x17, 0x00, 0x41, 0x04, 0x11, 0xdf, 0x6e, 0x16, + 0xe8, 0xb4, 0xc8, 0xf3, 0x9c, 0x74, 0x09, 0x2e, 0xe5, 0xc2, 0xc7, 0x6f, + 0x1b, 0x26, 0xf0, 0x9e, 0x5f, 0xb1, 0x9e, 0x2e, 0xe4, 0xcd, 0x4f, 0xbb, + 0xe9, 0x5e, 0x7c, 0x1e, 0x12, 0x84, 0xd7, 0xee, 0x69, 0xa8, 0x16, 0x2f, + 0x99, 0xdf, 0x65, 0xad, 0x2b, 0x6f, 0xed, 0x74, 0x04, 0xb3, 0xe2, 0xed, + 0xfa, 0x54, 0xd0, 0x62, 0xde, 0xc7, 0x20, 0xb7, 0x4d, 0x17, 0x9d, 0xf9, + 0x00, 0x2a, 0x00, 0x00, 0x00, 0x29, 0x00, 0xcd, 0x00, 0xa8, 0x00, 0xa2, + 0xa2, 0x8c, 0x83, 0x80, 0xd2, 0x1a, 0x39, 0xf1, 0x9a, 0xb9, 0xa9, 0x9e, + 0x00, 0x00, 0x00, 0x00, 0xb5, 0x69, 0x30, 0x63, 0xdd, 0xe8, 0x13, 0xa0, + 0x4a, 0x33, 0x9d, 0xbf, 0x53, 0x5c, 0x5c, 0x2e, 0x00, 0x60, 0x5b, 0xd8, + 0xc2, 0x31, 0xb8, 0xb7, 0x1c, 0xaf, 0x6e, 0xa5, 0x98, 0xc4, 0x84, 0xa8, + 0x4e, 0x75, 0xf5, 0x71, 0xa8, 0x34, 0xcb, 0x9e, 0x65, 0xe9, 0x7e, 0x3e, + 0x3e, 0xf2, 0xd3, 0x00, 0x69, 0x4b, 0x6a, 0x45, 0xd1, 0xb3, 0xad, 0xc3, + 0x7e, 0x41, 0xe5, 0x8f, 0xde, 0xae, 0x36, 0xfc, 0x38, 0x74, 0x08, 0x66, + 0x10, 0xfb, 0x27, 0x46, 0x0c, 0x6c, 0x2a, 0xd8, 0xc7, 0x42, 0x51, 0xce, + 0x0e, 0x61, 0x47, 0x7f, 0xc2, 0xeb, 0x11, 0x47, 0x9e, 0xb9, 0x04, 0xd0, + 0x4e, 0x57, 0xf0, 0x45, 0x1b, 0x29, 0xca, 0x9e, 0x4e, 0x12, 0x2b, 0xc4, + 0x02, 0x66, 0x50, 0x09, 0xd2, 0x50, 0x3c, 0x66, 0xc3, 0x15, 0x25, 0xbb, + 0x9b, 0x0d, 0x52, 0x1b, 0x5d, 0x6d, 0x2f, 0x2c, 0x0d, 0xde, 0xfa, 0xfd, + 0x9a, 0x65, 0xdd, 0xe0, 0x50, 0xfe, 0x4d, 0x9f, 0x39, 0x51, 0x70, 0x87, + 0x3e, 0xbb, 0x47, 0x3e, 0x26, 0xfe, 0x00, 0xfe, 0x74, 0x87, 0x00, 0x21, + 0x20, 0xe7, 0x09, 0x56, 0x88, 0xcd, 0xfb, 0xd4, 0xfe, 0x0f, 0x99, 0x96, + 0xaf, 0x24, 0x7d, 0xb1, 0xed, 0x14, 0x38, 0x25, 0x98, 0xde, 0xf8, 0x37, + 0x02, 0x6c, 0xe7, 0xb7, 0x6e, 0x6e, 0x56, 0xf5, 0xb5, +}; +/* clang-format on */ + +/* + * SHA-256 of the stripped transcript: 4-byte TLS header + 381-byte body, + * with msg_seq, fragment_offset, fragment_length omitted per RFC 9147 §5.2. + * Captured from a live OpenSSL-to-NSS DTLS 1.3 early data handshake. + */ +static const unsigned char dtls_transcript_hash[] = { + 0x5b, 0x8c, 0x4d, 0x67, 0x08, 0xa6, 0x82, 0xa3, 0xb9, 0x62, 0xa5, 0x3a, + 0x96, 0x6c, 0x13, 0x81, 0xa9, 0xbc, 0xf4, 0x77, 0xe0, 0xa5, 0x82, 0x30, + 0x39, 0x01, 0x13, 0x51, 0x3c, 0xf6, 0x97, 0x3c +}; + +/* + * Known-answer test for dtls13_transcript_hash_update (RFC 9147 §5.2). + * Wraps the helper with EVP_DigestInit/Final to verify the stripped hash + * matches a value captured from a live handshake. + */ +static int test_dtls13_transcript_hash(void) +{ + EVP_MD_CTX *ctx = NULL; + unsigned char hash[EVP_MAX_MD_SIZE]; + unsigned int hashlen = 0; + int ret = 0; + + ctx = EVP_MD_CTX_new(); + if (!TEST_ptr(ctx)) + goto err; + if (!TEST_true(EVP_DigestInit_ex(ctx, EVP_sha256(), NULL))) + goto err; + if (!TEST_true(dtls13_transcript_hash_update(ctx, dtls_raw_transcript, + sizeof(dtls_raw_transcript)))) + goto err; + if (!TEST_true(EVP_DigestFinal_ex(ctx, hash, &hashlen))) + goto err; + if (!TEST_mem_eq(hash, hashlen, + dtls_transcript_hash, sizeof(dtls_transcript_hash))) + goto err; + ret = 1; +err: + EVP_MD_CTX_free(ctx); + return ret; +} + int setup_tests(void) { ADD_TEST(test_handshake_secrets); + ADD_TEST(test_dtls13_transcript_hash); return 1; } diff --git a/test/tls13tickettest.c b/test/tls13tickettest.c index f761419a564bc..300c6b2dbc261 100644 --- a/test/tls13tickettest.c +++ b/test/tls13tickettest.c @@ -7,6 +7,7 @@ * https://www.openssl.org/source/license.html */ +#include #include #include #include @@ -27,7 +28,7 @@ * such as new_session_count = 0 or resumption_count = 0, is effectively * signaling no interest in session tickets or resumption. * - * RFC 8446 section 4.2.9: Servers MUST NOT select a key exchange mode that is + * RFC 9846 section 4.3.9: Servers MUST NOT select a key exchange mode that is * not listed by the client. This extension also restricts the modes for use * with PSK resumption. Servers SHOULD NOT send NewSessionTicket with tickets * that are not compatible with the advertised modes; however, if a server does @@ -57,8 +58,11 @@ struct stats { unsigned int ch_has_psk; unsigned int ch_has_psk_kex_modes; unsigned int ch_has_session_ticket; + unsigned int ch_has_early_data; unsigned int sh_has_psk; unsigned int sh_has_supported_versions; + unsigned int ee_has_early_data; + unsigned int ee_has_alpn; }; struct tls13_endpoint { @@ -137,10 +141,15 @@ static void parse_ch_exts(const unsigned char *buf, size_t len, struct stats *x) case TLSEXT_TYPE_session_ticket: x->ch_has_session_ticket = 1; break; + case TLSEXT_TYPE_early_data: + x->ch_has_early_data = 1; + break; } } - TEST_info("ch extensions: psk=%d psk_kex_modes=%d session_ticket=%d", - x->ch_has_psk, x->ch_has_psk_kex_modes, x->ch_has_session_ticket); + TEST_info("ch extensions: psk=%d psk_kex_modes=%d session_ticket=%d" + " early_data=%d", + x->ch_has_psk, x->ch_has_psk_kex_modes, x->ch_has_session_ticket, + x->ch_has_early_data); } static void parse_sh_exts(const unsigned char *buf, size_t len, struct stats *x) @@ -171,6 +180,32 @@ static void parse_sh_exts(const unsigned char *buf, size_t len, struct stats *x) x->sh_has_psk, x->sh_has_supported_versions); } +static void parse_ee_exts(const unsigned char *buf, size_t len, struct stats *x) +{ + PACKET pkt, e, ex; + unsigned int v; + + if (!PACKET_buf_init(&pkt, buf, len) + || !PACKET_forward(&pkt, 4) + || !PACKET_as_length_prefixed_2(&pkt, &e)) + return; + + while (PACKET_remaining(&e) > 0) { + if (!PACKET_get_net_2(&e, &v) || !PACKET_get_length_prefixed_2(&e, &ex)) + return; + switch (v) { + case TLSEXT_TYPE_early_data: + x->ee_has_early_data = 1; + break; + case TLSEXT_TYPE_application_layer_protocol_negotiation: + x->ee_has_alpn = 1; + break; + } + } + TEST_info("ee extensions: early_data=%d alpn=%d", + x->ee_has_early_data, x->ee_has_alpn); +} + static void msg_cb(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg) { @@ -185,6 +220,8 @@ static void msg_cb(int write_p, int version, int content_type, parse_ch_exts(buf, len, stats); if (mt == SSL3_MT_SERVER_HELLO && stats != NULL) parse_sh_exts(buf, len, stats); + if (mt == SSL3_MT_ENCRYPTED_EXTENSIONS && stats != NULL) + parse_ee_exts(buf, len, stats); } } @@ -250,6 +287,236 @@ static int ticket_disable(SSL_CTX *ctx) return 1; } +/* + * A fixed, 0-RTT-capable external PSK (RFC 9846), offered via the + * psk_use_session (client) and psk_find_session (server) callbacks. Used to + * exercise 0-RTT keyed off an external PSK while a retired resumption ticket is + * also present: the external PSK is the first offered identity. + */ +static const unsigned char ext_psk_id[] = { + 'e', 'x', 't', '-', 'p', 's', 'k' +}; +static const unsigned char ext_psk_key[32] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20 +}; + +static SSL_SESSION *ext_psk_session(SSL *ssl) +{ + static const unsigned char tls13_aes128gcmsha256_id[] = { 0x13, 0x01 }; + SSL_SESSION *sess = SSL_SESSION_new(); + const SSL_CIPHER *cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id); + + if (sess == NULL + || cipher == NULL + || !SSL_SESSION_set1_master_key(sess, ext_psk_key, sizeof(ext_psk_key)) + || !SSL_SESSION_set_cipher(sess, cipher) + || !SSL_SESSION_set_protocol_version(sess, TLS1_3_VERSION) + || !SSL_SESSION_set_max_early_data(sess, SSL3_RT_MAX_PLAIN_LENGTH)) { + SSL_SESSION_free(sess); + return NULL; + } + return sess; +} + +static int ext_psk_use_cb(SSL *ssl, const EVP_MD *md, const unsigned char **id, + size_t *idlen, SSL_SESSION **sess) +{ + (void)md; + if ((*sess = ext_psk_session(ssl)) == NULL) + return 0; + *id = ext_psk_id; + *idlen = sizeof(ext_psk_id); + return 1; +} + +static int ext_psk_find_cb(SSL *ssl, const unsigned char *id, size_t idlen, + SSL_SESSION **sess) +{ + if (idlen != sizeof(ext_psk_id) || memcmp(id, ext_psk_id, idlen) != 0) { + *sess = NULL; + return 1; + } + return (*sess = ext_psk_session(ssl)) != NULL; +} + +static int enable_external_psk(SSL *cssl, SSL *sssl) +{ + SSL_set_psk_use_session_callback(cssl, ext_psk_use_cb); + SSL_set_psk_find_session_callback(sssl, ext_psk_find_cb); + return 1; +} + +/* + * A client psk_use_session callback that hands back a single shared + * SSL_SESSION on every call (up-ref'd, as the API permits) so we can check + * that connection-local sid_ctx provenance is not written into it. + */ +static SSL_SESSION *shared_psk_sess = NULL; + +static int shared_psk_use_cb(SSL *ssl, const EVP_MD *md, const unsigned char **id, + size_t *idlen, SSL_SESSION **sess) +{ + (void)ssl; + (void)md; + if (shared_psk_sess == NULL || !SSL_SESSION_up_ref(shared_psk_sess)) + return 0; + *sess = shared_psk_sess; + *id = ext_psk_id; + *idlen = sizeof(ext_psk_id); + return 1; +} + +static int enable_shared_psk(SSL *cssl, SSL *sssl) +{ + SSL_set_psk_use_session_callback(cssl, shared_psk_use_cb); + SSL_set_psk_find_session_callback(sssl, ext_psk_find_cb); + return 1; +} + +/* + * A malformed client psk_use_session callback: a TLS 1.3 session with a cipher + * but no master key set. The client must reject it rather than derive a binder + * from an empty secret. + */ +static int nomasterkey_psk_use_cb(SSL *ssl, const EVP_MD *md, + const unsigned char **id, size_t *idlen, SSL_SESSION **sess) +{ + static const unsigned char tls13_aes128gcmsha256_id[] = { 0x13, 0x01 }; + SSL_SESSION *ns = SSL_SESSION_new(); + const SSL_CIPHER *cipher = SSL_CIPHER_find(ssl, tls13_aes128gcmsha256_id); + + (void)md; + if (ns == NULL + || cipher == NULL + || !SSL_SESSION_set_cipher(ns, cipher) + || !SSL_SESSION_set_protocol_version(ns, TLS1_3_VERSION)) { + SSL_SESSION_free(ns); + return 0; + } + /* Deliberately leave the master key unset. */ + *sess = ns; + *id = ext_psk_id; + *idlen = sizeof(ext_psk_id); + return 1; +} + +/* + * The server offers a single protocol via server_alpn and selects it when the + * client advertises it. The client advertises a protocol using the + * length-prefixed wire form expected by SSL_set_alpn_protos(). + */ +static const char *server_alpn = NULL; + +static int alpn_select_cb(SSL *ssl, const unsigned char **out, + unsigned char *outlen, const unsigned char *in, + unsigned int inlen, void *arg) +{ + unsigned int protlen = 0; + const unsigned char *prot; + + if (server_alpn == NULL) + return SSL_TLSEXT_ERR_NOACK; + + for (prot = in; prot < in + inlen; prot += protlen) { + protlen = *prot++; + if (in + inlen < prot + protlen) + return SSL_TLSEXT_ERR_NOACK; + if (protlen == strlen(server_alpn) + && memcmp(prot, server_alpn, protlen) == 0) { + *out = prot; + *outlen = protlen; + return SSL_TLSEXT_ERR_OK; + } + } + return SSL_TLSEXT_ERR_NOACK; +} + +static int alpn_server_enable(SSL_CTX *ctx, const char *proto) +{ + server_alpn = proto; + SSL_CTX_set_alpn_select_cb(ctx, alpn_select_cb, NULL); + return 1; +} + +/* Change which protocol the server selects for the next handshake. */ +static int alpn_server_select(const char *proto) +{ + server_alpn = proto; + return 1; +} + +/* Append protocol proto (length-prefixed) to the wire buffer at *n. */ +static int alpn_wire_add(unsigned char *wire, size_t cap, unsigned int *n, + const char *proto) +{ + unsigned int plen = (unsigned int)strlen(proto); + + if (plen == 0 || plen > 255 || *n + 1 + plen > cap) + return 0; + wire[(*n)++] = (unsigned char)plen; + memcpy(wire + *n, proto, plen); + *n += plen; + return 1; +} + +static int alpn_client_offer(SSL *ssl, const char *proto) +{ + unsigned char wire[256]; + unsigned int n = 0; + + if (!alpn_wire_add(wire, sizeof(wire), &n, proto)) + return 0; + /* SSL_set_alpn_protos() returns 0 on success. */ + return SSL_set_alpn_protos(ssl, wire, n) == 0; +} + +static int alpn_client_offer2(SSL *ssl, const char *p1, const char *p2) +{ + unsigned char wire[256]; + unsigned int n = 0; + + if (!alpn_wire_add(wire, sizeof(wire), &n, p1) + || !alpn_wire_add(wire, sizeof(wire), &n, p2)) + return 0; + /* SSL_set_alpn_protos() returns 0 on success. */ + return SSL_set_alpn_protos(ssl, wire, n) == 0; +} + +/* Returns 1 if the connection negotiated exactly the given ALPN protocol. */ +static int alpn_conn_selected_is(SSL *ssl, const char *proto) +{ + const unsigned char *alpn = NULL; + unsigned int alpnlen = 0; + + SSL_get0_alpn_selected(ssl, &alpn, &alpnlen); + return alpn != NULL + && alpnlen == strlen(proto) + && memcmp(alpn, proto, alpnlen) == 0; +} + +/* Returns 1 if the connection negotiated no ALPN protocol. */ +static int alpn_conn_selected_none(SSL *ssl) +{ + const unsigned char *alpn = NULL; + unsigned int alpnlen = 0; + + SSL_get0_alpn_selected(ssl, &alpn, &alpnlen); + return alpn == NULL && alpnlen == 0; +} + +/* Returns 1 if the session stores no ALPN protocol. */ +static int alpn_sess_selected_none(SSL *ssl) +{ + const unsigned char *alpn = NULL; + size_t alpnlen = 0; + + SSL_SESSION_get0_alpn_selected(SSL_get_session(ssl), &alpn, &alpnlen); + return alpn == NULL && alpnlen == 0; +} + /* * RFC 5077 3.1: The server sends an empty SessionTicket extension to indicate * that it will send a new session ticket using the NewSessionTicket handshake @@ -652,7 +919,1191 @@ static int test_tls13_ticket_no_decrypt(void) return test; } -OPT_TEST_DECLARE_USAGE("\n") +/* + * TLS 1.3 0-RTT early_data accepted + * + * Complements the suppression/rejection tests above: with a fresh resumption + * ticket the client advertises both pre_shared_key and early_data, the server + * accepts 0-RTT. + */ +static int test_tls13_ticket_early_data_accepted(void) +{ + const unsigned char m[] = "message"; + unsigned char buf[256]; + SSL_CTX *c = NULL, *s = NULL; + struct tls13_channel initial = { .c.ssl = NULL, .s.ssl = NULL }; + struct tls13_channel resumed = { .c.ssl = NULL, .s.ssl = NULL }; + SSL_SESSION *sess = NULL; + size_t w = 0, r = 0; + int test; + + test = TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, &s, &c, cert, pkey)) + && TEST_true(set_ctx_callbacks(c, s)) + && TEST_true(ticket_enable(s)) + && TEST_true(ticket_enable(c)) + && TEST_true(SSL_CTX_set_max_early_data(s, SSL3_RT_MAX_PLAIN_LENGTH)) + && TEST_true(SSL_CTX_set_options(s, SSL_OP_NO_ANTI_REPLAY) != 0) + && TEST_true(tls_channel_init(c, s, &initial)) + && TEST_true(create_ssl_connection(initial.s.ssl, initial.c.ssl, 0)) + && TEST_true(tls_shutdown(&initial)) + && TEST_uint_eq(initial.c.stats.nst_msgs, 2) + && TEST_uint_eq(initial.s.stats.nst_msgs, 2) + && TEST_uint_eq(initial.c.stats.tickets, 2) + && TEST_uint_eq(initial.s.stats.tickets, 2) + && TEST_uint_eq(initial.c.stats.ch_has_psk, 0) + && TEST_uint_eq(initial.s.stats.ch_has_psk, 0) + && TEST_uint_eq(initial.c.stats.ch_has_early_data, 0) + && TEST_uint_eq(initial.s.stats.ch_has_early_data, 0) + && TEST_uint_eq(initial.c.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(initial.s.stats.ch_has_psk_kex_modes, 1) + && TEST_ptr(sess = SSL_get1_session(initial.c.ssl)) + && TEST_true(tls_channel_init(c, s, &resumed)) + && TEST_true(SSL_set_session(resumed.c.ssl, sess)) + && TEST_true(SSL_write_early_data(resumed.c.ssl, m, sizeof(m), &w)) + && TEST_size_t_eq(w, sizeof(m)) + && TEST_int_eq(SSL_read_early_data(resumed.s.ssl, buf, sizeof(buf), &r), + SSL_READ_EARLY_DATA_SUCCESS) + && TEST_mem_eq(buf, r, m, sizeof(m)) + && TEST_int_gt(SSL_connect(resumed.c.ssl), 0) + && TEST_int_eq(SSL_read_early_data(resumed.s.ssl, buf, sizeof(buf), &r), + SSL_READ_EARLY_DATA_FINISH) + && TEST_size_t_eq(r, 0) + && TEST_int_eq(SSL_get_early_data_status(resumed.s.ssl), SSL_EARLY_DATA_ACCEPTED) + && TEST_true(create_ssl_connection(resumed.s.ssl, resumed.c.ssl, 0)) + && TEST_int_eq(SSL_get_early_data_status(resumed.c.ssl), SSL_EARLY_DATA_ACCEPTED) + && TEST_true(SSL_session_reused(resumed.c.ssl)) + && TEST_uint_eq(resumed.c.stats.nst_msgs, 1) + && TEST_uint_eq(resumed.s.stats.nst_msgs, 1) + && TEST_uint_eq(resumed.c.stats.tickets, 1) + && TEST_uint_eq(resumed.s.stats.tickets, 1) + && TEST_uint_eq(resumed.c.stats.ch_has_psk, 1) + && TEST_uint_eq(resumed.s.stats.ch_has_psk, 1) + && TEST_uint_eq(resumed.c.stats.ch_has_early_data, 1) + && TEST_uint_eq(resumed.s.stats.ch_has_early_data, 1) + && TEST_uint_eq(resumed.c.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(resumed.s.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(resumed.s.stats.ee_has_early_data, 1) + && TEST_uint_eq(resumed.c.stats.ee_has_early_data, 1); + + SSL_SESSION_free(sess); + tls_channel_fini(&initial); + tls_channel_fini(&resumed); + SSL_CTX_free(c); + SSL_CTX_free(s); + return test; +} + +/* + * TLS 1.3 stale ALPN cleared from a resumption ticket + * + * A session that negotiated ALPN is resumed on a connection that negotiates no + * ALPN at all (the client advertises none). The NewSessionTicket issued for the + * resumed session must not retain the ALPN protocol from the original session; + * otherwise a later 0-RTT attempt using that ticket would incorrectly assume + * that protocol had been negotiated. + * + * Regression test for GitHub issue #11197: tls_construct_new_session_ticket() + * copied s->s3.alpn_selected into the session only when an ALPN protocol was + * negotiated, but failed to clear s->session->ext.alpn_selected when it wasn't. + * + * A third connection then resumes the now-ALPN-cleared ticket and negotiates + * "goodalpn" again -- the same, non-empty protocol as the original session, + * coincidentally. Since the ticket being resumed carries no ALPN, 0-RTT must + * still be rejected: the client's SSL_write_early_data() appears to succeed + * (the data is sent before the server's response is known), but a post hoc + * SSL_get_early_data_status() check confirms the server never accepted it. + * + * A fourth connection resumes that same ALPN-cleared ticket a second time -- + * anti-replay is disabled for this test, so reusing it twice is not itself a + * reason for rejection -- but this time advertises no ALPN, consistent with + * what the ticket actually recorded. 0-RTT must now be accepted. Without this + * case, the rejection asserted for connection 3 would be unfalsifiable: it + * would look identical if early data were simply never being accepted here + * for any reason at all. + * + * The fourth connection resumes from an independent SSL_SESSION_dup() copy + * of the ticket (taken before connection 3 uses the original), rather than + * the original SSL_SESSION object itself: completing a handshake from a + * resumed session marks that SSL_SESSION object not-resumable on the client + * side as a single-use safeguard, independent of (and in addition to) the + * server's SSL_OP_NO_ANTI_REPLAY setting. Resuming the literal object a + * second time would therefore quietly fall back to a full, non-PSK + * handshake instead of testing the intended 0-RTT path. + */ +static int test_tls13_ticket_alpn_cleared(void) +{ + const unsigned char m[] = "message"; + unsigned char buf[256]; + SSL_CTX *c = NULL, *s = NULL; + struct tls13_channel initial = { .c.ssl = NULL, .s.ssl = NULL }; + struct tls13_channel resumed = { .c.ssl = NULL, .s.ssl = NULL }; + struct tls13_channel resumed2 = { .c.ssl = NULL, .s.ssl = NULL }; + struct tls13_channel resumed3 = { .c.ssl = NULL, .s.ssl = NULL }; + SSL_SESSION *sess = NULL, *sess2 = NULL, *sess2b = NULL; + size_t w = 0, r = 0; + int test; + + test = TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, &s, &c, cert, pkey)) + && TEST_true(set_ctx_callbacks(c, s)) + && TEST_true(ticket_enable(s)) + && TEST_true(ticket_enable(c)) + && TEST_true(SSL_CTX_set_max_early_data(s, SSL3_RT_MAX_PLAIN_LENGTH)) + && TEST_true(SSL_CTX_set_options(s, SSL_OP_NO_ANTI_REPLAY) != 0) + && TEST_true(alpn_server_enable(s, "goodalpn")) + /* + * Connection 1: the client advertises "goodalpn", the server selects + * it, and the negotiated protocol is stored in the session. + */ + && TEST_true(tls_channel_init(c, s, &initial)) + && TEST_true(alpn_client_offer(initial.c.ssl, "goodalpn")) + && TEST_true(create_ssl_connection(initial.s.ssl, initial.c.ssl, SSL_ERROR_NONE)) + && TEST_true(alpn_conn_selected_is(initial.s.ssl, "goodalpn")) + && TEST_true(alpn_conn_selected_is(initial.c.ssl, "goodalpn")) + && TEST_uint_eq(initial.c.stats.nst_msgs, 2) + && TEST_uint_eq(initial.s.stats.nst_msgs, 2) + && TEST_uint_eq(initial.c.stats.tickets, 2) + && TEST_uint_eq(initial.s.stats.tickets, 2) + && TEST_uint_eq(initial.c.stats.ch_has_psk, 0) + && TEST_uint_eq(initial.s.stats.ch_has_psk, 0) + && TEST_uint_eq(initial.c.stats.ch_has_early_data, 0) + && TEST_uint_eq(initial.s.stats.ch_has_early_data, 0) + && TEST_uint_eq(initial.c.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(initial.s.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(initial.s.stats.ee_has_alpn, 1) + && TEST_uint_eq(initial.c.stats.ee_has_alpn, 1) + && TEST_true(tls_shutdown(&initial)) + && TEST_ptr(sess = SSL_get1_session(initial.c.ssl)) + /* + * Connection 2: resume the session, but the client advertises no ALPN + * this time so nothing is negotiated. The server issues a fresh + * NewSessionTicket for the resumed session; its stored ALPN must be + * cleared rather than inheriting "goodalpn" from the original session. + */ + && TEST_true(tls_channel_init(c, s, &resumed)) + && TEST_true(SSL_set_session(resumed.c.ssl, sess)) + && TEST_true(create_ssl_connection(resumed.s.ssl, resumed.c.ssl, SSL_ERROR_NONE)) + && TEST_true(SSL_session_reused(resumed.c.ssl)) + && TEST_uint_eq(resumed.c.stats.nst_msgs, 1) + && TEST_uint_eq(resumed.s.stats.nst_msgs, 1) + && TEST_uint_eq(resumed.c.stats.tickets, 1) + && TEST_uint_eq(resumed.s.stats.tickets, 1) + && TEST_uint_eq(resumed.c.stats.ch_has_psk, 1) + && TEST_uint_eq(resumed.s.stats.ch_has_psk, 1) + && TEST_uint_eq(resumed.c.stats.ch_has_early_data, 0) + && TEST_uint_eq(resumed.s.stats.ch_has_early_data, 0) + && TEST_uint_eq(resumed.c.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(resumed.s.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(resumed.s.stats.ee_has_early_data, 0) + && TEST_uint_eq(resumed.c.stats.ee_has_early_data, 0) + && TEST_uint_eq(resumed.s.stats.ee_has_alpn, 0) + && TEST_uint_eq(resumed.c.stats.ee_has_alpn, 0) + /* No ALPN was negotiated on the resumption handshake ... */ + && TEST_true(alpn_conn_selected_none(resumed.s.ssl)) + && TEST_true(alpn_conn_selected_none(resumed.c.ssl)) + /* ... so the session written into the new ticket must carry none. */ + && TEST_true(alpn_sess_selected_none(resumed.s.ssl)) + && TEST_true(tls_shutdown(&resumed)) + && TEST_ptr(sess2 = SSL_get1_session(resumed.c.ssl)) + /* + * Connection 3 is about to resume sess2 and, since 0-RTT is attempted + * on it, the client will mark sess2 not-resumable once that attempt + * completes (this happens on any full handshake completed from a + * resumed session, independent of the server's anti-replay setting -- + * it is a client-side single-use restriction on the SSL_SESSION + * object itself). Take an independent copy now, while sess2 is still + * untouched, so connection 4 below has its own unconsumed ticket to + * resume from. + */ + && TEST_ptr(sess2b = SSL_SESSION_dup(sess2)) + /* + * Connection 3: resume the ALPN-cleared ticket from connection 2, but + * this time negotiate "goodalpn" again -- the same protocol as the + * original session, purely by coincidence. The ticket being resumed + * has no ALPN of its own, so 0-RTT must be rejected regardless of + * this match. + */ + && TEST_true(tls_channel_init(c, s, &resumed2)) + && TEST_true(alpn_client_offer(resumed2.c.ssl, "goodalpn")) + && TEST_true(SSL_set_session(resumed2.c.ssl, sess2)) + && TEST_true(SSL_write_early_data(resumed2.c.ssl, m, sizeof(m), &w)) + && TEST_size_t_eq(w, sizeof(m)) + /* The server skips the early data: nothing is delivered to the app. */ + && TEST_int_eq(SSL_read_early_data(resumed2.s.ssl, buf, sizeof(buf), &r), + SSL_READ_EARLY_DATA_FINISH) + && TEST_size_t_eq(r, 0) + && TEST_true(create_ssl_connection(resumed2.s.ssl, resumed2.c.ssl, 0)) + && TEST_true(SSL_session_reused(resumed2.c.ssl)) + && TEST_true(alpn_conn_selected_is(resumed2.s.ssl, "goodalpn")) + && TEST_true(alpn_conn_selected_is(resumed2.c.ssl, "goodalpn")) + && TEST_uint_eq(resumed2.s.stats.ee_has_alpn, 1) + && TEST_uint_eq(resumed2.c.stats.ee_has_alpn, 1) + && TEST_uint_eq(resumed2.s.stats.ee_has_early_data, 0) + && TEST_uint_eq(resumed2.c.stats.ee_has_early_data, 0) + /* Post hoc: the write appeared to succeed, but nothing was accepted. */ + && TEST_int_eq(SSL_get_early_data_status(resumed2.c.ssl), + SSL_EARLY_DATA_REJECTED) + && TEST_true(tls_shutdown(&resumed2)) + /* + * Connection 4: resume the same ticket from connection 2 again, via + * the untouched copy (sess2b) taken before connection 3 consumed + * sess2 -- anti-replay is off, so a second use of that ticket is not + * itself rejected -- but this time advertise no ALPN, matching what + * the ticket recorded. 0-RTT must be accepted, proving connection 3 + * was rejected for the ALPN mismatch specifically, not because early + * data never works. + */ + && TEST_true(tls_channel_init(c, s, &resumed3)) + && TEST_true(SSL_set_session(resumed3.c.ssl, sess2b)) + && TEST_true(SSL_write_early_data(resumed3.c.ssl, m, sizeof(m), &w)) + && TEST_size_t_eq(w, sizeof(m)) + && TEST_int_eq(SSL_read_early_data(resumed3.s.ssl, buf, sizeof(buf), &r), + SSL_READ_EARLY_DATA_SUCCESS) + && TEST_mem_eq(buf, r, m, sizeof(m)) + && TEST_int_gt(SSL_connect(resumed3.c.ssl), 0) + && TEST_int_eq(SSL_read_early_data(resumed3.s.ssl, buf, sizeof(buf), &r), + SSL_READ_EARLY_DATA_FINISH) + && TEST_size_t_eq(r, 0) + && TEST_int_eq(SSL_get_early_data_status(resumed3.s.ssl), SSL_EARLY_DATA_ACCEPTED) + && TEST_true(create_ssl_connection(resumed3.s.ssl, resumed3.c.ssl, 0)) + && TEST_int_eq(SSL_get_early_data_status(resumed3.c.ssl), SSL_EARLY_DATA_ACCEPTED) + && TEST_true(SSL_session_reused(resumed3.c.ssl)) + && TEST_true(alpn_conn_selected_none(resumed3.s.ssl)) + && TEST_true(alpn_conn_selected_none(resumed3.c.ssl)) + && TEST_uint_eq(resumed3.s.stats.ee_has_alpn, 0) + && TEST_uint_eq(resumed3.c.stats.ee_has_alpn, 0); + + SSL_SESSION_free(sess); + SSL_SESSION_free(sess2); + SSL_SESSION_free(sess2b); + tls_channel_fini(&initial); + tls_channel_fini(&resumed); + tls_channel_fini(&resumed2); + tls_channel_fini(&resumed3); + SSL_CTX_free(c); + SSL_CTX_free(s); + server_alpn = NULL; + return test; +} + +/* + * TLS 1.3 ALPN mismatch 0-RTT rejection + * + * The session negotiated ALPN "goodalpn". On resumption the client still offers + * "goodalpn" (so it is willing to send early data) alongside "otheralpn", and + * the server selects "otheralpn" instead. Because the ALPN selected for the + * resumption handshake differs from the one associated with the ticket, the + * server must reject 0-RTT while still completing the (resumed) handshake. + * + * RFC 9846 4.3.10: In order to accept early data, the server MUST have accepted + * a PSK cipher suite and selected the first key offered in the client's + * "pre_shared_key" extension. In addition, it MUST verify that the following + * values are the same as those associated with the selected PSK: TLS version + * number, selected cipher suite, and selected ALPN (RFC 7301) protocol, if any. + */ +static int test_tls13_ticket_alpn_mismatch_reject_early_data(void) +{ + const unsigned char m[] = "message"; + unsigned char buf[256]; + SSL_CTX *c = NULL, *s = NULL; + struct tls13_channel initial = { .c.ssl = NULL, .s.ssl = NULL }; + struct tls13_channel resumed = { .c.ssl = NULL, .s.ssl = NULL }; + SSL_SESSION *sess = NULL; + size_t w = 0, r = 0; + int test; + + test = TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, &s, &c, cert, pkey)) + && TEST_true(set_ctx_callbacks(c, s)) + && TEST_true(ticket_enable(s)) + && TEST_true(ticket_enable(c)) + && TEST_true(SSL_CTX_set_max_early_data(s, SSL3_RT_MAX_PLAIN_LENGTH)) + && TEST_true(SSL_CTX_set_options(s, SSL_OP_NO_ANTI_REPLAY) != 0) + && TEST_true(alpn_server_enable(s, "goodalpn")) + /* Connection 1: negotiate ALPN "goodalpn" and store it in the ticket. */ + && TEST_true(tls_channel_init(c, s, &initial)) + && TEST_true(alpn_client_offer(initial.c.ssl, "goodalpn")) + && TEST_true(create_ssl_connection(initial.s.ssl, initial.c.ssl, 0)) + && TEST_true(alpn_conn_selected_is(initial.s.ssl, "goodalpn")) + && TEST_true(alpn_conn_selected_is(initial.c.ssl, "goodalpn")) + && TEST_true(tls_shutdown(&initial)) + && TEST_uint_eq(initial.c.stats.nst_msgs, 2) + && TEST_uint_eq(initial.s.stats.nst_msgs, 2) + && TEST_ptr(sess = SSL_get1_session(initial.c.ssl)) + /* + * Connection 2: attempt 0-RTT. The client offers "goodalpn" (matching + * the ticket, so it is willing to send early data) plus "otheralpn"; + * the server selects "otheralpn", which mismatches the ticket's ALPN. + */ + && TEST_true(tls_channel_init(c, s, &resumed)) + && TEST_true(alpn_client_offer2(resumed.c.ssl, "goodalpn", "otheralpn")) + && TEST_true(alpn_server_select("otheralpn")) + && TEST_true(SSL_set_session(resumed.c.ssl, sess)) + && TEST_true(SSL_write_early_data(resumed.c.ssl, m, sizeof(m), &w)) + && TEST_size_t_eq(w, sizeof(m)) + /* The server skips the early data: nothing is delivered to the app. */ + && TEST_int_eq(SSL_read_early_data(resumed.s.ssl, buf, sizeof(buf), &r), + SSL_READ_EARLY_DATA_FINISH) + && TEST_size_t_eq(r, 0) + && TEST_true(create_ssl_connection(resumed.s.ssl, resumed.c.ssl, 0)) + && TEST_int_eq(SSL_get_early_data_status(resumed.c.ssl), + SSL_EARLY_DATA_REJECTED) + /* PSK resumption still succeeds, only 0-RTT is refused. */ + && TEST_true(SSL_session_reused(resumed.c.ssl)) + && TEST_true(alpn_conn_selected_is(resumed.s.ssl, "otheralpn")) + && TEST_true(alpn_conn_selected_is(resumed.c.ssl, "otheralpn")) + /* ALPN was negotiated, but the server did not accept early_data. */ + && TEST_uint_eq(resumed.s.stats.ee_has_alpn, 1) + && TEST_uint_eq(resumed.c.stats.ee_has_alpn, 1) + && TEST_uint_eq(resumed.s.stats.ee_has_early_data, 0) + && TEST_uint_eq(resumed.c.stats.ee_has_early_data, 0); + + SSL_SESSION_free(sess); + tls_channel_fini(&initial); + tls_channel_fini(&resumed); + SSL_CTX_free(c); + SSL_CTX_free(s); + server_alpn = NULL; + return test; +} + +/* + * TLS 1.3 server-side 0-RTT rejection on a cipher mismatch. + * + * The early data is protected with the cipher recorded in the PSK, so the + * server can only accept 0-RTT if it selects that same cipher. Here the client + * offers the ticket's cipher (so it is willing to send early data, keyed with + * it) alongside a second cipher of the same digest; the server offers only the + * second cipher. PSK resumption still succeeds (the digest matches, so the + * binder validates), but the server negotiates a cipher other than the one that + * keyed the early data and therefore refuses the early data. + * + * This is the server-side counterpart to the client-side cipher suppression in + * test_tls13_ticket_cipher_mismatch_suppress_early_data(): there the ticket's + * cipher is not offered at all, so the client declines 0-RTT before sending; + * here it is offered, so the client sends and the server refuses. + */ +static int test_tls13_ticket_cipher_mismatch_reject_early_data(void) +{ + const unsigned char m[] = "message"; + unsigned char buf[256]; + SSL_CTX *c = NULL, *s = NULL; + struct tls13_channel initial = { .c.ssl = NULL, .s.ssl = NULL }; + struct tls13_channel resumed = { .c.ssl = NULL, .s.ssl = NULL }; + SSL_SESSION *sess = NULL; + unsigned char edexp[32]; + size_t w = 0, r = 0; + int test; + + test = TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, &s, &c, cert, pkey)) + && TEST_true(set_ctx_callbacks(c, s)) + && TEST_true(ticket_enable(s)) + && TEST_true(ticket_enable(c)) + && TEST_true(SSL_CTX_set_max_early_data(s, SSL3_RT_MAX_PLAIN_LENGTH)) + && TEST_true(SSL_CTX_set_options(s, SSL_OP_NO_ANTI_REPLAY) != 0) + /* Connection 1: negotiate AES-128-GCM and store it in the ticket. */ + && TEST_true(SSL_CTX_set_ciphersuites(s, "TLS_AES_128_GCM_SHA256")) + && TEST_true(SSL_CTX_set_ciphersuites(c, "TLS_AES_128_GCM_SHA256")) + && TEST_true(tls_channel_init(c, s, &initial)) + && TEST_true(create_ssl_connection(initial.s.ssl, initial.c.ssl, 0)) + && TEST_true(tls_shutdown(&initial)) + && TEST_uint_eq(initial.c.stats.nst_msgs, 2) + && TEST_uint_eq(initial.s.stats.nst_msgs, 2) + && TEST_ptr(sess = SSL_get1_session(initial.c.ssl)) + /* + * Connection 2: attempt 0-RTT. The client offers AES-128-GCM (matching + * the ticket, so it is willing to send early data keyed with it) plus + * AES-128-CCM; the server offers only AES-128-CCM. Both share the + * SHA256 digest. + */ + && TEST_true(SSL_CTX_set_ciphersuites(s, "TLS_AES_128_CCM_SHA256")) + && TEST_true(SSL_CTX_set_ciphersuites(c, + "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_SHA256")) + && TEST_true(tls_channel_init(c, s, &resumed)) + && TEST_true(SSL_set_session(resumed.c.ssl, sess)) + && TEST_true(SSL_write_early_data(resumed.c.ssl, m, sizeof(m), &w)) + && TEST_size_t_eq(w, sizeof(m)) + /* The server skips the early data: nothing is delivered to the app. */ + && TEST_int_eq(SSL_read_early_data(resumed.s.ssl, buf, sizeof(buf), &r), + SSL_READ_EARLY_DATA_FINISH) + && TEST_size_t_eq(r, 0) + && TEST_true(create_ssl_connection(resumed.s.ssl, resumed.c.ssl, 0)) + && TEST_int_eq(SSL_get_early_data_status(resumed.c.ssl), + SSL_EARLY_DATA_REJECTED) + /* + * Here the client really did send 0-RTT and so derived the early + * secrets, only for the server to decline it. Unlike a client that + * suppressed 0-RTT of its own accord -- which reports the same + * REJECTED status -- the early exporter therefore stays available. + */ + && TEST_int_eq(SSL_export_keying_material_early(resumed.c.ssl, edexp, + sizeof(edexp), "label", 5, NULL, 0), + 1) + /* PSK resumption still succeeds, only 0-RTT is refused. */ + && TEST_true(SSL_session_reused(resumed.c.ssl)) + && TEST_uint_eq(resumed.s.stats.ee_has_early_data, 0) + && TEST_uint_eq(resumed.c.stats.ee_has_early_data, 0); + + SSL_SESSION_free(sess); + tls_channel_fini(&initial); + tls_channel_fini(&resumed); + SSL_CTX_free(c); + SSL_CTX_free(s); + return test; +} + +enum endpoint_state { + ENDPOINT_WRITE_EARLY_DATA, + ENDPOINT_READ_EARLY_DATA, + ENDPOINT_HANDSHAKE, + ENDPOINT_READ_APP_DATA, + ENDPOINT_DONE, + ENDPOINT_ERROR +}; + +/* Retry logic switch extracted from s_client. */ +static int is_retryable(SSL *ssl, int ret) +{ + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_WANT_ASYNC: + case SSL_ERROR_WANT_READ: + return 1; + default: + return 0; + } +} + +/* + * The client follows the s_client retry loop; the server skips early data and + * completes the handshake. + * + * SSL_write_early_data() states the call behaves like SSL_write_ex(): if it + * fails, the caller must consult SSL_get_error() and, while it reports a + * retryable WANT_READ/WANT_WRITE condition, keep calling SSL_write_early_data() + * with the same arguments until it succeeds. This helper encodes that decision. + */ +static int tls_early_data_retry(struct tls13_channel *x) +{ + const unsigned char m[] = "message"; + unsigned char buf[256]; + enum endpoint_state c = ENDPOINT_WRITE_EARLY_DATA; + enum endpoint_state s = ENDPOINT_READ_EARLY_DATA; + size_t w = SIZE_MAX, r = SIZE_MAX; + + for (int i = 0; i < 100 && (c != ENDPOINT_DONE || s != ENDPOINT_DONE); i++) { + if (c == ENDPOINT_WRITE_EARLY_DATA) { + if (SSL_write_early_data(x->c.ssl, m, sizeof(m), &w) > 0) + c = ENDPOINT_DONE; + else if (!is_retryable(x->c.ssl, 0)) + c = ENDPOINT_ERROR; + } + if (s == ENDPOINT_READ_EARLY_DATA) { + switch (SSL_read_early_data(x->s.ssl, buf, sizeof(buf), &r)) { + case SSL_READ_EARLY_DATA_FINISH: + s = ENDPOINT_HANDSHAKE; + break; + default: + s = ENDPOINT_ERROR; + } + } + if (s == ENDPOINT_HANDSHAKE) { + if (SSL_is_init_finished(x->s.ssl)) + s = ENDPOINT_DONE; + else if (SSL_accept(x->s.ssl) <= 0 && !is_retryable(x->s.ssl, 0)) + s = ENDPOINT_ERROR; + } + if (c == ENDPOINT_ERROR || s == ENDPOINT_ERROR) + break; + } + + return TEST_int_eq(c, ENDPOINT_DONE) + && TEST_int_eq(s, ENDPOINT_DONE) + && TEST_size_t_eq(w, sizeof(m)) + && TEST_size_t_eq(r, 0); +} + +/* + * TLS 1.3 Client-side Ticket Age Mismatch 0-RTT Rejection (API retry test) + * + * This test exercises the case where the client does not send a PSK due to a + * ticket age mismatch, and verifies that the client suppresses the early_data + * as a result. + * + * RFC 9846 4.3.10: When a PSK is used and early data is allowed for that PSK, + * the client can send Application Data in its first flight of messages. If the + * client opts to do so, it MUST supply both the "pre_shared_key" and + * "early_data" extensions. The PSK used to encrypt the early data MUST be the + * first PSK listed in the client's "pre_shared_key" extension. + * + * RFC 9846 4.3.11.1: Clients MUST NOT attempt to use tickets which have ages + * greater than the "ticket_lifetime" value which was provided with the ticket. + */ +static int test_tls13_ticket_client_age_mismatch_reject_early_data_retry(void) +{ + SSL_CTX *c = NULL, *s = NULL; + struct tls13_channel initial = { .c.ssl = NULL, .s.ssl = NULL }; + struct tls13_channel resumed = { .c.ssl = NULL, .s.ssl = NULL }; + SSL_SESSION *sess = NULL; + int test; + + test = TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, &s, &c, cert, pkey)) + && TEST_true(set_ctx_callbacks(c, s)) + && TEST_true(ticket_enable(s)) + && TEST_true(ticket_enable(c)) + && TEST_true(SSL_CTX_set_max_early_data(s, SSL3_RT_MAX_PLAIN_LENGTH)) + && TEST_true(SSL_CTX_set_timeout(s, 1) > 0) + && TEST_true(tls_channel_init(c, s, &initial)) + && TEST_true(create_ssl_connection(initial.s.ssl, initial.c.ssl, 0)) + && TEST_true(tls_shutdown(&initial)) + && TEST_uint_eq(initial.c.stats.nst_msgs, 2) + && TEST_uint_eq(initial.s.stats.nst_msgs, 2) + && TEST_uint_eq(initial.c.stats.tickets, 2) + && TEST_uint_eq(initial.s.stats.tickets, 2) + && TEST_uint_eq(initial.c.stats.ch_has_psk, 0) + && TEST_uint_eq(initial.s.stats.ch_has_psk, 0) + && TEST_uint_eq(initial.c.stats.ch_has_early_data, 0) + && TEST_uint_eq(initial.s.stats.ch_has_early_data, 0) + && TEST_uint_eq(initial.c.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(initial.s.stats.ch_has_psk_kex_modes, 1) + && TEST_ptr(sess = SSL_get1_session(initial.c.ssl)) + && TEST_time_t_gt(SSL_SESSION_set_time_ex(sess, time(NULL) - 10), 0) + && TEST_true(tls_channel_init(c, s, &resumed)) + && TEST_true(SSL_set_session(resumed.c.ssl, sess)) + && TEST_true(tls_early_data_retry(&resumed)) + && TEST_int_eq(SSL_get_early_data_status(resumed.c.ssl), SSL_EARLY_DATA_REJECTED) + && TEST_false(SSL_session_reused(resumed.c.ssl)) + && TEST_uint_eq(resumed.c.stats.nst_msgs, 0) + && TEST_uint_eq(resumed.s.stats.nst_msgs, 2) + && TEST_uint_eq(resumed.c.stats.tickets, 0) + && TEST_uint_eq(resumed.s.stats.tickets, 2) + && TEST_uint_eq(resumed.c.stats.ch_has_psk, 0) + && TEST_uint_eq(resumed.s.stats.ch_has_psk, 0) + && TEST_uint_eq(resumed.c.stats.ch_has_early_data, 0) + && TEST_uint_eq(resumed.s.stats.ch_has_early_data, 0) + && TEST_uint_eq(resumed.c.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(resumed.s.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(resumed.s.stats.ee_has_early_data, 0) + && TEST_uint_eq(resumed.c.stats.ee_has_early_data, 0); + + SSL_SESSION_free(sess); + tls_channel_fini(&initial); + tls_channel_fini(&resumed); + SSL_CTX_free(c); + SSL_CTX_free(s); + return test; +} + +/* + * TLS 1.3 Server-side Ticket Age Mismatch 0-RTT Rejection + * + * Exercises the server-side ticket age validation. The client considers the + * ticket fresh and proceeds with PSK + 0-RTT, but the transmitted + * obfuscated_ticket_age indicates a ticket roughly 10s old. Since the apparent + * ticket age exceeds TICKET_AGE_ALLOWANCE, the server rejects early data. + * + * RFC 9846 4.3.10: For PSKs provisioned via NewSessionTicket, a server MUST + * validate that the ticket age for the selected PSK identity is within a small + * tolerance of the time since the ticket was issued. If it is not, the server + * SHOULD proceed with the handshake but reject 0-RTT. + */ +static int test_tls13_ticket_server_age_mismatch_reject_early_data(void) +{ + const unsigned char m[] = "message"; + unsigned char buf[256]; + SSL_CTX *c = NULL, *s = NULL; + struct tls13_channel initial = { .c.ssl = NULL, .s.ssl = NULL }; + struct tls13_channel resumed = { .c.ssl = NULL, .s.ssl = NULL }; + SSL_SESSION *sess = NULL; + size_t w = 0, r = 0; + int test; + + test = TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, &s, &c, cert, pkey)) + && TEST_true(set_ctx_callbacks(c, s)) + && TEST_true(ticket_enable(s)) + && TEST_true(ticket_enable(c)) + && TEST_true(SSL_CTX_set_max_early_data(s, SSL3_RT_MAX_PLAIN_LENGTH)) + && TEST_true(SSL_CTX_set_options(s, SSL_OP_NO_ANTI_REPLAY) != 0) + && TEST_true(tls_channel_init(c, s, &initial)) + && TEST_true(create_ssl_connection(initial.s.ssl, initial.c.ssl, 0)) + && TEST_true(tls_shutdown(&initial)) + && TEST_uint_eq(initial.c.stats.nst_msgs, 2) + && TEST_uint_eq(initial.s.stats.nst_msgs, 2) + && TEST_uint_eq(initial.c.stats.tickets, 2) + && TEST_uint_eq(initial.s.stats.tickets, 2) + && TEST_uint_eq(initial.c.stats.ch_has_psk, 0) + && TEST_uint_eq(initial.s.stats.ch_has_psk, 0) + && TEST_uint_eq(initial.c.stats.ch_has_early_data, 0) + && TEST_uint_eq(initial.s.stats.ch_has_early_data, 0) + && TEST_uint_eq(initial.c.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(initial.s.stats.ch_has_psk_kex_modes, 1) + && TEST_ptr(sess = SSL_get1_session(initial.c.ssl)) + && TEST_time_t_gt(SSL_SESSION_set_time_ex(sess, time(NULL) - 10), 0) + && TEST_true(tls_channel_init(c, s, &resumed)) + && TEST_true(SSL_set_session(resumed.c.ssl, sess)) + && TEST_true(SSL_write_early_data(resumed.c.ssl, m, sizeof(m), &w)) + && TEST_size_t_eq(w, sizeof(m)) + && TEST_int_eq(SSL_read_early_data(resumed.s.ssl, buf, sizeof(buf), &r), + SSL_READ_EARLY_DATA_FINISH) + && TEST_size_t_eq(r, 0) + && TEST_true(create_ssl_connection(resumed.s.ssl, resumed.c.ssl, 0)) + && TEST_int_eq(SSL_get_early_data_status(resumed.c.ssl), SSL_EARLY_DATA_REJECTED) + && TEST_true(SSL_session_reused(resumed.c.ssl)) + && TEST_uint_eq(resumed.c.stats.nst_msgs, 1) + && TEST_uint_eq(resumed.s.stats.nst_msgs, 1) + && TEST_uint_eq(resumed.c.stats.tickets, 1) + && TEST_uint_eq(resumed.s.stats.tickets, 1) + && TEST_uint_eq(resumed.c.stats.ch_has_psk, 1) + && TEST_uint_eq(resumed.s.stats.ch_has_psk, 1) + && TEST_uint_eq(resumed.c.stats.ch_has_early_data, 1) + && TEST_uint_eq(resumed.s.stats.ch_has_early_data, 1) + && TEST_uint_eq(resumed.c.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(resumed.s.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(resumed.s.stats.ee_has_early_data, 0) + && TEST_uint_eq(resumed.c.stats.ee_has_early_data, 0); + + SSL_SESSION_free(sess); + tls_channel_fini(&initial); + tls_channel_fini(&resumed); + SSL_CTX_free(c); + SSL_CTX_free(s); + return test; +} + +/* + * TLS 1.3 Client-side Ticket Age Mismatch 0-RTT Rejection (outer test) + */ +static int test_tls13_ticket_client_age_mismatch_reject_early_data_outer(void) +{ + const unsigned char m[] = "message"; + unsigned char buf[256]; + SSL_CTX *c = NULL, *s = NULL; + struct tls13_channel initial = { .c.ssl = NULL, .s.ssl = NULL }; + struct tls13_channel resumed = { .c.ssl = NULL, .s.ssl = NULL }; + SSL_SESSION *sess = NULL; + size_t r = 0, w = 0; + int test; + + test = TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, &s, &c, cert, pkey)) + && TEST_true(set_ctx_callbacks(c, s)) + && TEST_true(ticket_enable(s)) + && TEST_true(ticket_enable(c)) + && TEST_true(SSL_CTX_set_max_early_data(s, SSL3_RT_MAX_PLAIN_LENGTH)) + && TEST_true(SSL_CTX_set_timeout(s, 1) > 0) + && TEST_true(tls_channel_init(c, s, &initial)) + && TEST_true(create_ssl_connection(initial.s.ssl, initial.c.ssl, 0)) + && TEST_true(tls_shutdown(&initial)) + && TEST_uint_eq(initial.c.stats.nst_msgs, 2) + && TEST_uint_eq(initial.s.stats.nst_msgs, 2) + && TEST_uint_eq(initial.c.stats.tickets, 2) + && TEST_uint_eq(initial.s.stats.tickets, 2) + && TEST_uint_eq(initial.c.stats.ch_has_psk, 0) + && TEST_uint_eq(initial.s.stats.ch_has_psk, 0) + && TEST_uint_eq(initial.c.stats.ch_has_early_data, 0) + && TEST_uint_eq(initial.s.stats.ch_has_early_data, 0) + && TEST_uint_eq(initial.c.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(initial.s.stats.ch_has_psk_kex_modes, 1) + && TEST_ptr(sess = SSL_get1_session(initial.c.ssl)) + && TEST_time_t_gt(SSL_SESSION_set_time_ex(sess, time(NULL) - 10), 0) + && TEST_true(tls_channel_init(c, s, &resumed)) + && TEST_true(SSL_set_session(resumed.c.ssl, sess)) + && TEST_true(tls_early_data_retry(&resumed)) + && TEST_int_eq(SSL_get_early_data_status(resumed.c.ssl), SSL_EARLY_DATA_REJECTED) + && TEST_false(SSL_session_reused(resumed.c.ssl)) + && TEST_uint_eq(resumed.c.stats.nst_msgs, 0) + && TEST_uint_eq(resumed.s.stats.nst_msgs, 2) + && TEST_uint_eq(resumed.c.stats.tickets, 0) + && TEST_uint_eq(resumed.s.stats.tickets, 2) + && TEST_uint_eq(resumed.c.stats.ch_has_psk, 0) + && TEST_uint_eq(resumed.s.stats.ch_has_psk, 0) + && TEST_uint_eq(resumed.c.stats.ch_has_early_data, 0) + && TEST_uint_eq(resumed.s.stats.ch_has_early_data, 0) + && TEST_uint_eq(resumed.c.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(resumed.s.stats.ch_has_psk_kex_modes, 1) + && TEST_uint_eq(resumed.s.stats.ee_has_early_data, 0) + && TEST_uint_eq(resumed.c.stats.ee_has_early_data, 0) + /* + * While the application is still in the early data write sequence, + * further suppressed SSL_write_early_data() calls keep succeeding. + */ + && TEST_size_t_eq((w = SIZE_MAX), SIZE_MAX) + && TEST_true(SSL_write_early_data(resumed.c.ssl, m, sizeof(m), &w)) + && TEST_size_t_eq(w, sizeof(m)) + /* Ordinary application I/O ends that sequence. */ + && TEST_size_t_eq((w = SIZE_MAX), SIZE_MAX) + && TEST_int_gt(SSL_write_ex(resumed.c.ssl, m, sizeof(m), &w), 0) + && TEST_size_t_eq(w, sizeof(m)) + && TEST_size_t_eq((r = SIZE_MAX), SIZE_MAX) + && TEST_int_gt(SSL_read_ex(resumed.s.ssl, buf, sizeof(buf), &r), 0) + && TEST_size_t_eq(r, sizeof(m)) + && TEST_mem_eq(buf, r, m, sizeof(m)) + && TEST_size_t_eq((w = SIZE_MAX), SIZE_MAX) + && TEST_int_gt(SSL_write_ex(resumed.s.ssl, m, sizeof(m), &w), 0) + && TEST_size_t_eq(w, sizeof(m)) + && TEST_size_t_eq((r = SIZE_MAX), SIZE_MAX) + && TEST_int_gt(SSL_read_ex(resumed.c.ssl, buf, sizeof(buf), &r), 0) + && TEST_size_t_eq(r, sizeof(m)) + && TEST_mem_eq(buf, r, m, sizeof(m)) + /* + * Having left the early data write sequence, a further + * SSL_write_early_data() reports the normal error rather than masking + * the application's state-machine mistake as success. + */ + && TEST_size_t_eq((w = SIZE_MAX), SIZE_MAX) + && TEST_false(SSL_write_early_data(resumed.c.ssl, m, sizeof(m), &w)) + && TEST_int_eq(SSL_get_error(resumed.c.ssl, 0), SSL_ERROR_SSL) + && TEST_int_eq(ERR_GET_REASON(ERR_get_error()), + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED) + && TEST_size_t_eq(w, SIZE_MAX); + + SSL_SESSION_free(sess); + tls_channel_fini(&initial); + tls_channel_fini(&resumed); + SSL_CTX_free(c); + SSL_CTX_free(s); + return test; +} + +OPT_TEST_DECLARE_USAGE("\n") + +/* + * TLS 1.3 0-RTT keyed off an external PSK past a retired resumption ticket. + * + * The client holds a 0-RTT-capable resumption ticket that has aged past its + * lifetime, so tls_construct_ctos_psk() does not offer it; an external PSK + * from the psk_use_session callback therefore occupies identity 0 and keys the + * early data. The keying sites must follow that first-offered PSK, not the retired + * ticket (whose max_early_data is still non-zero) -- otherwise client and + * server derive different CLIENT_EARLY_TRAFFIC_SECRET values and the server + * fails with a bad record MAC. Regression test for the mixed aged-ticket + + * external-PSK 0-RTT keying bug. + */ +static int test_tls13_aged_ticket_external_psk_early_data(void) +{ + const unsigned char m[] = "message"; + unsigned char buf[256]; + SSL_CTX *c = NULL, *s = NULL; + struct tls13_channel initial = { .c.ssl = NULL, .s.ssl = NULL }; + struct tls13_channel resumed = { .c.ssl = NULL, .s.ssl = NULL }; + SSL_SESSION *sess = NULL; + size_t w = 0, r = 0; + unsigned char ceed[32], seed[32]; + int test; + + test = TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, &s, &c, cert, pkey)) + && TEST_true(set_ctx_callbacks(c, s)) + && TEST_true(ticket_enable(s)) + && TEST_true(ticket_enable(c)) + /* + * Pin the ciphersuite to the external PSK's committed cipher so the + * negotiated cipher matches it; 0-RTT on an external PSK requires that + * (RFC 9846 4.3.10). Orthogonal to the bug under test, which is about + * which PSK's secret keys the early data, not the cipher. + */ + && TEST_true(SSL_CTX_set_ciphersuites(s, "TLS_AES_128_GCM_SHA256")) + && TEST_true(SSL_CTX_set_ciphersuites(c, "TLS_AES_128_GCM_SHA256")) + && TEST_true(SSL_CTX_set_max_early_data(s, SSL3_RT_MAX_PLAIN_LENGTH)) + && TEST_true(SSL_CTX_set_options(s, SSL_OP_NO_ANTI_REPLAY) != 0) + /* Short ticket lifetime so the backdated ticket ages out client-side + * and is not offered, leaving the external PSK first. */ + && TEST_true(SSL_CTX_set_timeout(s, 1) > 0) + && TEST_true(tls_channel_init(c, s, &initial)) + && TEST_true(create_ssl_connection(initial.s.ssl, initial.c.ssl, 0)) + && TEST_true(tls_shutdown(&initial)) + && TEST_ptr(sess = SSL_get1_session(initial.c.ssl)) + /* Retire the (0-RTT-capable) ticket so it is not offered first. */ + && TEST_time_t_gt(SSL_SESSION_set_time_ex(sess, time(NULL) - 10), 0) + && TEST_true(tls_channel_init(c, s, &resumed)) + && TEST_true(SSL_set_session(resumed.c.ssl, sess)) + && TEST_true(enable_external_psk(resumed.c.ssl, resumed.s.ssl)) + && TEST_true(SSL_write_early_data(resumed.c.ssl, m, sizeof(m), &w)) + && TEST_size_t_eq(w, sizeof(m)) + && TEST_int_eq(SSL_read_early_data(resumed.s.ssl, buf, sizeof(buf), &r), + SSL_READ_EARLY_DATA_SUCCESS) + && TEST_mem_eq(buf, r, m, sizeof(m)) + && TEST_int_gt(SSL_connect(resumed.c.ssl), 0) + && TEST_int_eq(SSL_read_early_data(resumed.s.ssl, buf, sizeof(buf), &r), + SSL_READ_EARLY_DATA_FINISH) + && TEST_size_t_eq(r, 0) + && TEST_int_eq(SSL_get_early_data_status(resumed.s.ssl), + SSL_EARLY_DATA_ACCEPTED) + && TEST_true(create_ssl_connection(resumed.s.ssl, resumed.c.ssl, 0)) + && TEST_int_eq(SSL_get_early_data_status(resumed.c.ssl), + SSL_EARLY_DATA_ACCEPTED) + /* + * The early exporter secret must match on both ends -- an independent + * check (separate from the decrypted early data) that both sides keyed + * 0-RTT from the same first-offered PSK. + */ + && TEST_int_eq(SSL_export_keying_material_early(resumed.c.ssl, ceed, + sizeof(ceed), "label", 5, (const unsigned char *)"ctx", 3), + 1) + && TEST_int_eq(SSL_export_keying_material_early(resumed.s.ssl, seed, + sizeof(seed), "label", 5, (const unsigned char *)"ctx", 3), + 1) + && TEST_mem_eq(ceed, sizeof(ceed), seed, sizeof(seed)) + /* The external PSK (offered first) keyed 0-RTT, not the retired ticket. */ + && TEST_uint_eq(resumed.c.stats.ch_has_psk, 1) + && TEST_uint_eq(resumed.s.stats.ch_has_psk, 1) + && TEST_uint_eq(resumed.c.stats.ch_has_early_data, 1) + && TEST_uint_eq(resumed.s.stats.ch_has_early_data, 1) + && TEST_uint_eq(resumed.s.stats.ee_has_early_data, 1) + && TEST_uint_eq(resumed.c.stats.ee_has_early_data, 1); + + SSL_SESSION_free(sess); + tls_channel_fini(&initial); + tls_channel_fini(&resumed); + SSL_CTX_free(c); + SSL_CTX_free(s); + return test; +} + +/* + * TLS 1.3 external-PSK sid_ctx must not mutate a callback-shared session. + * + * The psk_use_session callback is entitled to return the same SSL_SESSION on + * every call (up-ref'd). When the client resumes via that PSK it stamps its + * connection-local sid_ctx onto the session; it must do so on a private + * duplicate, never on the shared object, or the sid_ctx bleeds across + * connections (and races under concurrency). After a handshake with a + * non-empty client sid_ctx, the shared session's sid_ctx must be untouched. + */ +static int test_tls13_external_psk_sid_ctx_not_shared(void) +{ + SSL_CTX *c = NULL, *s = NULL; + struct tls13_channel conn = { .c.ssl = NULL, .s.ssl = NULL }; + static const unsigned char sidctx[] = { 'S', 'I', 'D' }; + int test; + + test = TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, &s, &c, cert, pkey)) + && TEST_true(set_ctx_callbacks(c, s)) + && TEST_true(SSL_CTX_set_ciphersuites(s, "TLS_AES_128_GCM_SHA256")) + && TEST_true(SSL_CTX_set_ciphersuites(c, "TLS_AES_128_GCM_SHA256")) + && TEST_true(tls_channel_init(c, s, &conn)) + && TEST_ptr(shared_psk_sess = ext_psk_session(conn.c.ssl)) + && TEST_true(SSL_set_session_id_context(conn.c.ssl, sidctx, sizeof(sidctx))) + && TEST_true(enable_shared_psk(conn.c.ssl, conn.s.ssl)) + && TEST_true(create_ssl_connection(conn.s.ssl, conn.c.ssl, 0)) + && TEST_true(SSL_session_reused(conn.c.ssl)) + /* Our sid_ctx must not have been written into the shared session. */ + && TEST_size_t_eq(shared_psk_sess->sid_ctx_length, 0); + + SSL_SESSION_free(shared_psk_sess); + shared_psk_sess = NULL; + tls_channel_fini(&conn); + SSL_CTX_free(c); + SSL_CTX_free(s); + return test; +} + +/* + * TLS 1.3 0-RTT suppressed when the ticket's exact cipher is no longer offered. + * + * The 0-RTT-capable ticket was issued under TLS_AES_128_GCM_SHA256; the + * resumption offers only TLS_AES_128_CCM_SHA256 -- same digest, different + * cipher. Resumption stays viable (digest-compatible), so the ticket is still + * offered and 1-RTT resumption succeeds, but 0-RTT is suppressed because the + * server can only accept it under the ticket's exact cipher (RFC 9846 4.3.10). + */ +static int test_tls13_ticket_cipher_mismatch_suppress_early_data(void) +{ + SSL_CTX *c = NULL, *s = NULL; + struct tls13_channel initial = { .c.ssl = NULL, .s.ssl = NULL }; + struct tls13_channel resumed = { .c.ssl = NULL, .s.ssl = NULL }; + SSL_SESSION *sess = NULL; + unsigned char edexp[32]; + int test; + + test = TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, &s, &c, cert, pkey)) + && TEST_true(set_ctx_callbacks(c, s)) + && TEST_true(ticket_enable(s)) + && TEST_true(ticket_enable(c)) + && TEST_true(SSL_CTX_set_max_early_data(s, SSL3_RT_MAX_PLAIN_LENGTH)) + && TEST_true(SSL_CTX_set_options(s, SSL_OP_NO_ANTI_REPLAY) != 0) + && TEST_true(SSL_CTX_set_ciphersuites(s, "TLS_AES_128_GCM_SHA256")) + && TEST_true(SSL_CTX_set_ciphersuites(c, "TLS_AES_128_GCM_SHA256")) + && TEST_true(tls_channel_init(c, s, &initial)) + && TEST_true(create_ssl_connection(initial.s.ssl, initial.c.ssl, 0)) + && TEST_true(tls_shutdown(&initial)) + && TEST_ptr(sess = SSL_get1_session(initial.c.ssl)) + /* Same digest, different cipher: resume-viable but not 0-RTT-viable. */ + && TEST_true(SSL_CTX_set_ciphersuites(s, "TLS_AES_128_CCM_SHA256")) + && TEST_true(SSL_CTX_set_ciphersuites(c, "TLS_AES_128_CCM_SHA256")) + && TEST_true(tls_channel_init(c, s, &resumed)) + && TEST_true(SSL_set_session(resumed.c.ssl, sess)) + && TEST_true(tls_early_data_retry(&resumed)) + && TEST_int_eq(SSL_get_early_data_status(resumed.c.ssl), + SSL_EARLY_DATA_REJECTED) + /* + * 0-RTT was suppressed here rather than sent and declined, so no early + * secrets were derived and the early exporter is unavailable -- even + * though the status matches that of a server rejection. + */ + && TEST_false(SSL_export_keying_material_early(resumed.c.ssl, edexp, + sizeof(edexp), "label", 5, NULL, 0)) + /* Ticket offered and resumed at 1-RTT; only 0-RTT was suppressed. */ + && TEST_true(SSL_session_reused(resumed.c.ssl)) + && TEST_uint_eq(resumed.c.stats.ch_has_psk, 1) + && TEST_uint_eq(resumed.c.stats.ch_has_early_data, 0) + && TEST_uint_eq(resumed.s.stats.ch_has_early_data, 0) + && TEST_uint_eq(resumed.s.stats.ee_has_early_data, 0); + + SSL_SESSION_free(sess); + tls_channel_fini(&initial); + tls_channel_fini(&resumed); + SSL_CTX_free(c); + SSL_CTX_free(s); + return test; +} + +/* + * TLS 1.3 0-RTT suppressed when the ticket's ALPN is no longer offered. + * + * The ticket recorded ALPN "goodalpn"; the resumption offers only "otheralpn". + * The ticket's ALPN can never be negotiated, so 0-RTT is impossible and must be + * suppressed -- but resumption itself proceeds (ALPN may change across a + * resumption, taking effect after the transition), so 1-RTT resumption + * succeeds with "otheralpn". Previously the client aborted this with a fatal + * alert instead of suppressing. + */ +static int test_tls13_ticket_alpn_mismatch_suppress_early_data(void) +{ + SSL_CTX *c = NULL, *s = NULL; + struct tls13_channel initial = { .c.ssl = NULL, .s.ssl = NULL }; + struct tls13_channel resumed = { .c.ssl = NULL, .s.ssl = NULL }; + SSL_SESSION *sess = NULL; + unsigned char edexp[32]; + int test; + + test = TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, &s, &c, cert, pkey)) + && TEST_true(set_ctx_callbacks(c, s)) + && TEST_true(ticket_enable(s)) + && TEST_true(ticket_enable(c)) + && TEST_true(SSL_CTX_set_max_early_data(s, SSL3_RT_MAX_PLAIN_LENGTH)) + && TEST_true(SSL_CTX_set_options(s, SSL_OP_NO_ANTI_REPLAY) != 0) + && TEST_true(alpn_server_enable(s, "goodalpn")) + /* Connection 1: record "goodalpn" in the 0-RTT-capable ticket. */ + && TEST_true(tls_channel_init(c, s, &initial)) + && TEST_true(alpn_client_offer(initial.c.ssl, "goodalpn")) + && TEST_true(create_ssl_connection(initial.s.ssl, initial.c.ssl, 0)) + && TEST_true(alpn_conn_selected_is(initial.c.ssl, "goodalpn")) + && TEST_true(tls_shutdown(&initial)) + && TEST_ptr(sess = SSL_get1_session(initial.c.ssl)) + /* Connection 2: offer only "otheralpn" -- the ticket's ALPN isn't on + * offer, so 0-RTT is suppressed but 1-RTT resumption still succeeds. */ + && TEST_true(tls_channel_init(c, s, &resumed)) + && TEST_true(SSL_set_session(resumed.c.ssl, sess)) + && TEST_true(alpn_client_offer(resumed.c.ssl, "otheralpn")) + && TEST_true(alpn_server_select("otheralpn")) + && TEST_true(tls_early_data_retry(&resumed)) + && TEST_int_eq(SSL_get_early_data_status(resumed.c.ssl), + SSL_EARLY_DATA_REJECTED) + /* Suppressed 0-RTT derives no early secrets: no early exporter. */ + && TEST_false(SSL_export_keying_material_early(resumed.c.ssl, edexp, + sizeof(edexp), "label", 5, NULL, 0)) + && TEST_true(SSL_session_reused(resumed.c.ssl)) + && TEST_true(alpn_conn_selected_is(resumed.c.ssl, "otheralpn")) + && TEST_uint_eq(resumed.c.stats.ch_has_psk, 1) + && TEST_uint_eq(resumed.c.stats.ch_has_early_data, 0) + && TEST_uint_eq(resumed.s.stats.ee_has_early_data, 0); + + SSL_SESSION_free(sess); + tls_channel_fini(&initial); + tls_channel_fini(&resumed); + SSL_CTX_free(c); + SSL_CTX_free(s); + server_alpn = NULL; + return test; +} + +/* + * TLS 1.3 0-RTT via an external PSK after the resumption ticket is retired for + * lacking an offered digest-compatible cipher. + * + * The ticket is issued under TLS_AES_256_GCM_SHA384; the resumption offers only + * TLS_AES_128_GCM_SHA256, so no offered ciphersuite carries the ticket's SHA384 + * digest and the ticket is retired (not offered). The external PSK (SHA256) + * therefore occupies the first identity and keys 0-RTT -- the cipher analogue + * of the aged-ticket cascade. + */ +static int test_tls13_ticket_cipher_retire_external_psk_early_data(void) +{ + const unsigned char m[] = "message"; + unsigned char buf[256]; + SSL_CTX *c = NULL, *s = NULL; + struct tls13_channel initial = { .c.ssl = NULL, .s.ssl = NULL }; + struct tls13_channel resumed = { .c.ssl = NULL, .s.ssl = NULL }; + SSL_SESSION *sess = NULL; + size_t w = 0, r = 0; + int test; + + test = TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, &s, &c, cert, pkey)) + && TEST_true(set_ctx_callbacks(c, s)) + && TEST_true(ticket_enable(s)) + && TEST_true(ticket_enable(c)) + && TEST_true(SSL_CTX_set_max_early_data(s, SSL3_RT_MAX_PLAIN_LENGTH)) + && TEST_true(SSL_CTX_set_options(s, SSL_OP_NO_ANTI_REPLAY) != 0) + /* Issue the 0-RTT-capable ticket under SHA384. */ + && TEST_true(SSL_CTX_set_ciphersuites(s, "TLS_AES_256_GCM_SHA384")) + && TEST_true(SSL_CTX_set_ciphersuites(c, "TLS_AES_256_GCM_SHA384")) + && TEST_true(tls_channel_init(c, s, &initial)) + && TEST_true(create_ssl_connection(initial.s.ssl, initial.c.ssl, 0)) + && TEST_true(tls_shutdown(&initial)) + && TEST_ptr(sess = SSL_get1_session(initial.c.ssl)) + /* Resume offering only SHA256: the SHA384 ticket has no offered + * digest-compatible cipher, so it is retired and the external PSK + * (SHA256) takes the first identity. */ + && TEST_true(SSL_CTX_set_ciphersuites(s, "TLS_AES_128_GCM_SHA256")) + && TEST_true(SSL_CTX_set_ciphersuites(c, "TLS_AES_128_GCM_SHA256")) + && TEST_true(tls_channel_init(c, s, &resumed)) + && TEST_true(SSL_set_session(resumed.c.ssl, sess)) + && TEST_true(enable_external_psk(resumed.c.ssl, resumed.s.ssl)) + && TEST_true(SSL_write_early_data(resumed.c.ssl, m, sizeof(m), &w)) + && TEST_size_t_eq(w, sizeof(m)) + && TEST_int_eq(SSL_read_early_data(resumed.s.ssl, buf, sizeof(buf), &r), + SSL_READ_EARLY_DATA_SUCCESS) + && TEST_mem_eq(buf, r, m, sizeof(m)) + && TEST_int_gt(SSL_connect(resumed.c.ssl), 0) + && TEST_int_eq(SSL_read_early_data(resumed.s.ssl, buf, sizeof(buf), &r), + SSL_READ_EARLY_DATA_FINISH) + && TEST_size_t_eq(r, 0) + && TEST_int_eq(SSL_get_early_data_status(resumed.s.ssl), + SSL_EARLY_DATA_ACCEPTED) + && TEST_true(create_ssl_connection(resumed.s.ssl, resumed.c.ssl, 0)) + && TEST_int_eq(SSL_get_early_data_status(resumed.c.ssl), + SSL_EARLY_DATA_ACCEPTED) + && TEST_uint_eq(resumed.c.stats.ch_has_psk, 1) + && TEST_uint_eq(resumed.c.stats.ch_has_early_data, 1) + && TEST_uint_eq(resumed.s.stats.ee_has_early_data, 1) + && TEST_uint_eq(resumed.c.stats.ee_has_early_data, 1); + + SSL_SESSION_free(sess); + tls_channel_fini(&initial); + tls_channel_fini(&resumed); + SSL_CTX_free(c); + SSL_CTX_free(s); + return test; +} + +/* + * TLS 1.3 ticket retired for lack of a digest-compatible cipher, no external + * PSK to fall back on: no PSK is offered at all and a full handshake results. + */ +static int test_tls13_ticket_cipher_retire_full_handshake(void) +{ + SSL_CTX *c = NULL, *s = NULL; + struct tls13_channel initial = { .c.ssl = NULL, .s.ssl = NULL }; + struct tls13_channel resumed = { .c.ssl = NULL, .s.ssl = NULL }; + SSL_SESSION *sess = NULL; + int test; + + test = TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, &s, &c, cert, pkey)) + && TEST_true(set_ctx_callbacks(c, s)) + && TEST_true(ticket_enable(s)) + && TEST_true(ticket_enable(c)) + && TEST_true(SSL_CTX_set_max_early_data(s, SSL3_RT_MAX_PLAIN_LENGTH)) + && TEST_true(SSL_CTX_set_options(s, SSL_OP_NO_ANTI_REPLAY) != 0) + && TEST_true(SSL_CTX_set_ciphersuites(s, "TLS_AES_256_GCM_SHA384")) + && TEST_true(SSL_CTX_set_ciphersuites(c, "TLS_AES_256_GCM_SHA384")) + && TEST_true(tls_channel_init(c, s, &initial)) + && TEST_true(create_ssl_connection(initial.s.ssl, initial.c.ssl, 0)) + && TEST_true(tls_shutdown(&initial)) + && TEST_ptr(sess = SSL_get1_session(initial.c.ssl)) + && TEST_true(SSL_CTX_set_ciphersuites(s, "TLS_AES_128_GCM_SHA256")) + && TEST_true(SSL_CTX_set_ciphersuites(c, "TLS_AES_128_GCM_SHA256")) + && TEST_true(tls_channel_init(c, s, &resumed)) + && TEST_true(SSL_set_session(resumed.c.ssl, sess)) + && TEST_true(tls_early_data_retry(&resumed)) + && TEST_int_eq(SSL_get_early_data_status(resumed.c.ssl), + SSL_EARLY_DATA_REJECTED) + && TEST_false(SSL_session_reused(resumed.c.ssl)) + && TEST_uint_eq(resumed.c.stats.ch_has_psk, 0) + && TEST_uint_eq(resumed.c.stats.ch_has_early_data, 0); + + SSL_SESSION_free(sess); + tls_channel_fini(&initial); + tls_channel_fini(&resumed); + SSL_CTX_free(c); + SSL_CTX_free(s); + return test; +} + +/* + * TLS 1.3 external PSK from the callback dropped when no offered ciphersuite + * carries its digest: it is treated as if the callback returned nothing, so no + * PSK is offered and a full handshake results. + */ +static int test_tls13_external_psk_digest_not_offered(void) +{ + SSL_CTX *c = NULL, *s = NULL; + struct tls13_channel conn = { .c.ssl = NULL, .s.ssl = NULL }; + int test; + + test = TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, &s, &c, cert, pkey)) + && TEST_true(set_ctx_callbacks(c, s)) + && TEST_true(SSL_CTX_set_max_early_data(s, SSL3_RT_MAX_PLAIN_LENGTH)) + && TEST_true(SSL_CTX_set_options(s, SSL_OP_NO_ANTI_REPLAY) != 0) + /* External PSK is AES_128_GCM_SHA256, but we offer only SHA384. */ + && TEST_true(SSL_CTX_set_ciphersuites(s, "TLS_AES_256_GCM_SHA384")) + && TEST_true(SSL_CTX_set_ciphersuites(c, "TLS_AES_256_GCM_SHA384")) + && TEST_true(tls_channel_init(c, s, &conn)) + && TEST_true(enable_external_psk(conn.c.ssl, conn.s.ssl)) + && TEST_true(tls_early_data_retry(&conn)) + && TEST_int_eq(SSL_get_early_data_status(conn.c.ssl), + SSL_EARLY_DATA_REJECTED) + && TEST_false(SSL_session_reused(conn.c.ssl)) + && TEST_uint_eq(conn.c.stats.ch_has_psk, 0) + && TEST_uint_eq(conn.c.stats.ch_has_early_data, 0); + + tls_channel_fini(&conn); + SSL_CTX_free(c); + SSL_CTX_free(s); + return test; +} + +/* + * A client psk_use_session callback that returns a session with no master key + * must be rejected (SSL_ERROR_SSL), not used to build a binder from an empty + * secret. + */ +static int test_tls13_external_psk_no_master_key(void) +{ + const unsigned char m[] = "message"; + size_t w = 0; + SSL_CTX *c = NULL, *s = NULL; + struct tls13_channel conn = { .c.ssl = NULL, .s.ssl = NULL }; + int test; + + test = TEST_true(create_ssl_ctx_pair(NULL, TLS_server_method(), TLS_client_method(), + TLS1_3_VERSION, TLS1_3_VERSION, &s, &c, cert, pkey)) + && TEST_true(set_ctx_callbacks(c, s)) + && TEST_true(SSL_CTX_set_max_early_data(s, SSL3_RT_MAX_PLAIN_LENGTH)) + && TEST_true(SSL_CTX_set_ciphersuites(s, "TLS_AES_128_GCM_SHA256")) + && TEST_true(SSL_CTX_set_ciphersuites(c, "TLS_AES_128_GCM_SHA256")) + && TEST_true(tls_channel_init(c, s, &conn)) + && TEST_true((SSL_set_psk_use_session_callback(conn.c.ssl, + nomasterkey_psk_use_cb), + 1)) + && TEST_false(SSL_write_early_data(conn.c.ssl, m, sizeof(m), &w)) + && TEST_int_eq(SSL_get_error(conn.c.ssl, 0), SSL_ERROR_SSL); + + tls_channel_fini(&conn); + SSL_CTX_free(c); + SSL_CTX_free(s); + return test; +} int setup_tests(void) { @@ -674,6 +2125,21 @@ int setup_tests(void) ADD_TEST(test_tls13_ticket_resumed_set_num_tickets_zero); ADD_TEST(test_tls13_ticket_disable_server); ADD_TEST(test_tls13_ticket_no_decrypt); + ADD_TEST(test_tls13_ticket_alpn_cleared); + ADD_TEST(test_tls13_ticket_alpn_mismatch_reject_early_data); + ADD_TEST(test_tls13_ticket_cipher_mismatch_reject_early_data); + ADD_TEST(test_tls13_ticket_early_data_accepted); + ADD_TEST(test_tls13_ticket_client_age_mismatch_reject_early_data_retry); + ADD_TEST(test_tls13_ticket_client_age_mismatch_reject_early_data_outer); + ADD_TEST(test_tls13_ticket_server_age_mismatch_reject_early_data); + ADD_TEST(test_tls13_aged_ticket_external_psk_early_data); + ADD_TEST(test_tls13_external_psk_sid_ctx_not_shared); + ADD_TEST(test_tls13_ticket_cipher_mismatch_suppress_early_data); + ADD_TEST(test_tls13_ticket_alpn_mismatch_suppress_early_data); + ADD_TEST(test_tls13_ticket_cipher_retire_external_psk_early_data); + ADD_TEST(test_tls13_ticket_cipher_retire_full_handshake); + ADD_TEST(test_tls13_external_psk_digest_not_offered); + ADD_TEST(test_tls13_external_psk_no_master_key); return 1; } diff --git a/test/tls_groups_list_test.c b/test/tls_groups_list_test.c new file mode 100644 index 0000000000000..977039363475f --- /dev/null +++ b/test/tls_groups_list_test.c @@ -0,0 +1,411 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Tests for the TLS supported-groups list parser (tls1_set_groups_list()), + * driven through the public SSL_CTX_set1_groups_list() entry point. + * + * The parser maintains three flat arrays and their bookkeeping in SSL_CTX: + * ctx->ext.supportedgroups[0..supportedgroups_len) - groups, in order + * ctx->ext.tuples[0..tuples_len) - group count per tuple + * ctx->ext.keyshares[0..keyshares_len) - keyshare group IDs + * with the governing invariant that the per-tuple counts sum to the group + * count: sum(tuples) == supportedgroups_len. Those fields are not visible + * through the public API, so we include ssl_local.h and check them directly. + * + * Several of the cases below are regressions for GitHub #31315, where the + * remove-group path could leave tuples/keyshares out of step with the group + * array (manifesting as an out-of-bounds read under a sanitizer). + */ + +#include +#include "internal/nelem.h" +#include "internal/tlsgroups.h" +#include "../ssl/ssl_local.h" +#include "testutil.h" + +#define MAX_GROUPS 8 +#define MAX_TUPLES 8 +#define MAX_KS 8 + +/* + * Sentinel used in ctx->ext.keyshares to mean "a single keyshare from the + * first supported group" (set when no '*' prefix appears anywhere). + */ +#define KS_FIRST 0 + +typedef struct { + const char *desc; + const char *list; /* input passed to set1_groups_list */ + uint16_t groups[MAX_GROUPS]; /* expected groups, in order */ + size_t ngroups; + size_t tuples[MAX_TUPLES]; /* expected per-tuple group counts */ + size_t ntuples; + uint16_t keyshares[MAX_KS]; /* expected keyshares (KS_FIRST == 0) */ + size_t nkeyshares; +} TESTCASE; + +static const TESTCASE cases[] = { + /* --- Well-formed baselines --------------------------------------- */ + { + "single tuple, two groups, implicit keyshare", + "X25519:prime256v1", + { OSSL_TLS_GROUP_ID_x25519, OSSL_TLS_GROUP_ID_secp256r1 }, + 2, + { 2 }, + 1, + { KS_FIRST }, + 1, + }, + { + "two tuples, implicit keyshare", + "X25519/prime256v1", + { OSSL_TLS_GROUP_ID_x25519, OSSL_TLS_GROUP_ID_secp256r1 }, + 2, + { 1, 1 }, + 2, + { KS_FIRST }, + 1, + }, + { + "explicit keyshare prefix", + "*X25519:prime256v1", + { OSSL_TLS_GROUP_ID_x25519, OSSL_TLS_GROUP_ID_secp256r1 }, + 2, + { 2 }, + 1, + { OSSL_TLS_GROUP_ID_x25519 }, + 1, + }, + + /* --- #31315: removal that empties a *closed* tuple --------------- */ + { + /* + * -X25519 empties closed tuple 0; it must be excised and the + * active-tuple counter shifted down (was: "1 group, 0 tuples"). + */ + "remove empties closed tuple (excision)", + "X25519/prime256v1:-X25519", + { OSSL_TLS_GROUP_ID_secp256r1 }, + 1, + { 1 }, + 1, + { KS_FIRST }, + 1, + }, + { + /* + * Removed group carried the keyshare and its tuple empties: the + * keyshare must be dropped, not floated onto another tuple's group + * (was: "1 group, tuples {1,1}", keyshare pointing at prime256v1). + */ + "remove keyshared group empties tuple (drop, not float)", + "*X25519/prime256v1/-X25519", + { OSSL_TLS_GROUP_ID_secp256r1 }, + 1, + { 1 }, + 1, + { KS_FIRST }, + 1, + }, + { + /* + * Two removals, each emptying a distinct closed tuple (was: + * "3 groups but tuple counts summing to 5"). + */ + "two removals empty two closed tuples", + "X25519/secp256r1:secp384r1:secp521r1/*X448:-X25519/-X448", + { OSSL_TLS_GROUP_ID_secp256r1, OSSL_TLS_GROUP_ID_secp384r1, + OSSL_TLS_GROUP_ID_secp521r1 }, + 3, + { 3 }, + 1, + { KS_FIRST }, + 1, + }, + + /* --- Removal from the *active* tuple (no excision) --------------- */ + { + "remove empties the active tuple only", + "X25519:-X25519", + { 0 }, + 0, + { 0 }, + 0, + { 0 }, + 0, + }, + { + "closed tuple intact, active tuple emptied and discarded", + "X25519/prime256v1:-prime256v1", + { OSSL_TLS_GROUP_ID_x25519 }, + 1, + { 1 }, + 1, + { KS_FIRST }, + 1, + }, + { + "keyshared group removed from active tuple", + "X25519/secp384r1/*X448:-X448", + { OSSL_TLS_GROUP_ID_x25519, OSSL_TLS_GROUP_ID_secp384r1 }, + 2, + { 1, 1 }, + 2, + { KS_FIRST }, + 1, + }, + + /* --- Legitimate keyshare retention (tuple not emptied) ----------- */ + { + /* + * Removing the keyshared X25519 from a tuple that still has + * prime256v1: prime256v1's own keyshare is retained. + */ + "remove one of two keyshares, tuple survives", + "*X25519:*prime256v1:-X25519", + { OSSL_TLS_GROUP_ID_secp256r1 }, + 1, + { 1 }, + 1, + { OSSL_TLS_GROUP_ID_secp256r1 }, + 1, + }, + + /* --- Keyshare floats *within* its own (surviving, closed) tuple --- */ + { + /* + * X25519 carried the keyshare in closed tuple 0 {X25519,secp384r1}; + * removing it must float the keyshare to secp384r1 (the remaining + * group of tuple 0), NOT to secp256r1 which is in tuple 1. + */ + "keyshare floats to remaining group of same tuple", + "*X25519:secp384r1/secp256r1:-X25519", + { OSSL_TLS_GROUP_ID_secp384r1, OSSL_TLS_GROUP_ID_secp256r1 }, + 2, + { 1, 1 }, + 2, + { OSSL_TLS_GROUP_ID_secp384r1 }, + 1, + }, + { + /* + * Removed keyshared group is in the middle of tuple 0; its keyshare + * floats to the tuple's first group (X25519), and tuple 1's own + * keyshare (secp256r1) is untouched. A float that escaped tuple 0 + * would corrupt this to a different keyshare set. + */ + "mid-tuple keyshare floats to tuple head, not across tuples", + "X25519:*X448:secp384r1 / *secp256r1:-X448", + { OSSL_TLS_GROUP_ID_x25519, OSSL_TLS_GROUP_ID_secp384r1, + OSSL_TLS_GROUP_ID_secp256r1 }, + 3, + { 2, 1 }, + 2, + { OSSL_TLS_GROUP_ID_x25519, OSSL_TLS_GROUP_ID_secp256r1 }, + 2, + }, +}; + +/* + * Assert every structural invariant the parser must maintain, from the parsed + * state alone (independent of the specific input): + * + * 1. Partition: sum(tuples[0..tuples_len)) == supportedgroups_len. + * 2. No empty tuples survive the final compaction (every count > 0). + * 3. Groups are distinct. + * 4. Keyshares are either the lone "first group" sentinel {0}, or a set of + * distinct non-zero group IDs that appear as an ordered subsequence of + * the supported groups (never the sentinel mixed with real IDs). + * + * These are exactly the properties that were violated by GitHub #31315 (a + * broken partition led to an out-of-bounds read in the remove path). + */ +static int check_invariants(SSL_CTX *ctx) +{ + size_t i, j, sum; + int ok = 1; + + /* 1 + 2: partition, with no zero-count tuple left behind. */ + for (i = 0, sum = 0; i < ctx->ext.tuples_len; i++) { + if (!TEST_size_t_gt(ctx->ext.tuples[i], 0)) { + TEST_error("zero-count tuple at index %zu survived", i); + ok = 0; + } + sum += ctx->ext.tuples[i]; + } + if (!TEST_size_t_eq(sum, ctx->ext.supportedgroups_len)) + ok = 0; + + /* 3: groups distinct. */ + for (i = 0; i < ctx->ext.supportedgroups_len; i++) + for (j = 0; j < i; j++) + if (!TEST_uint_ne(ctx->ext.supportedgroups[i], + ctx->ext.supportedgroups[j])) + ok = 0; + + /* 4: keyshare shape. */ + if (ctx->ext.keyshares_len == 1 && ctx->ext.keyshares[0] == KS_FIRST) { + /* Sentinel form: a single implicit keyshare from the first group. */ + } else { + size_t g = 0; + + for (i = 0; i < ctx->ext.keyshares_len; i++) { + uint16_t ks = ctx->ext.keyshares[i]; + + if (!TEST_uint_ne(ks, KS_FIRST)) { /* sentinel must be alone */ + ok = 0; + continue; + } + for (j = 0; j < i; j++) /* distinct */ + if (!TEST_uint_ne(ks, ctx->ext.keyshares[j])) + ok = 0; + while (g < ctx->ext.supportedgroups_len + && ctx->ext.supportedgroups[g] != ks) + g++; /* ordered subsequence */ + if (!TEST_size_t_lt(g, ctx->ext.supportedgroups_len)) { + TEST_error("keyshare 0x%04X not an in-order group", ks); + ok = 0; + break; + } + g++; + } + } + + return ok; +} + +static int run_case(int idx) +{ + const TESTCASE *tc = &cases[idx]; + SSL_CTX *ctx = NULL; + int ret = 0; + size_t i; + + TEST_info("case %d: %s [\"%s\"]", idx, tc->desc, tc->list); + + if (!TEST_ptr(ctx = SSL_CTX_new(TLS_method()))) + goto end; + + if (!TEST_int_eq(SSL_CTX_set1_groups_list(ctx, tc->list), 1)) + goto end; + + /* Groups: exact contents and order. */ + if (!TEST_size_t_eq(ctx->ext.supportedgroups_len, tc->ngroups)) + goto end; + for (i = 0; i < tc->ngroups; i++) + if (!TEST_uint_eq(ctx->ext.supportedgroups[i], tc->groups[i])) + goto end; + + /* Tuples: exact per-tuple counts. */ + if (!TEST_size_t_eq(ctx->ext.tuples_len, tc->ntuples)) + goto end; + for (i = 0; i < tc->ntuples; i++) + if (!TEST_size_t_eq(ctx->ext.tuples[i], tc->tuples[i])) + goto end; + + /* Keyshares: exact contents (KS_FIRST == 0 sentinel). */ + if (!TEST_size_t_eq(ctx->ext.keyshares_len, tc->nkeyshares)) + goto end; + for (i = 0; i < tc->nkeyshares; i++) + if (!TEST_uint_eq(ctx->ext.keyshares[i], tc->keyshares[i])) + goto end; + + if (!check_invariants(ctx)) + goto end; + + ret = 1; +end: + SSL_CTX_free(ctx); + return ret; +} + +/* + * Synthetic edge-case forms. We do not spell out the exact parsed result for + * these (that would just re-derive the parser); instead we assert the parse + * succeeds or fails as expected and, on success, that all invariants hold. + * These deliberately stress the corners of the remove/dedup/keyshare paths. + */ +typedef struct { + const char *list; + int expect_ok; /* 1: parse succeeds; 0: syntax/parse error */ +} EDGECASE; + +static const EDGECASE edgecases[] = { + /* --- valid, invariant-preserving corner cases --- */ + { "X25519", 1 }, + { "X25519:secp256r1:secp384r1:secp521r1:X448", 1 }, /* one full tuple */ + { "X25519/secp256r1/secp384r1/secp521r1/X448", 1 }, /* many tuples */ + { "*X25519:secp256r1", 1 }, + { "X25519:X25519", 1 }, /* dup within tuple */ + { "X25519/X25519", 1 }, /* dup across tuples */ + { "X25519:-secp384r1", 1 }, /* remove absent: no-op */ + { "X25519:-X25519", 1 }, /* empty the active tuple */ + { "X25519/secp256r1:-X25519", 1 }, /* excise closed tuple */ + { "X25519/secp256r1/secp384r1:-secp256r1", 1 }, /* excise middle tuple */ + { "X25519:secp256r1/secp384r1:-secp384r1", 1 }, /* empty active, discard */ + { "*X25519/prime256v1/-X25519", 1 }, /* #31315: drop, not float */ + { "X25519/secp256r1:secp384r1:secp521r1/*X448:-X25519/-X448", 1 }, /* #31315 */ + { "*X25519:*secp256r1:-X25519", 1 }, /* keyshare survives sibling */ + { "X25519/secp256r1:-X25519:secp384r1", 1 }, /* excise then refill */ + { "X25519:secp256r1:X448:-X25519:-X448", 1 }, /* multiple removals */ + { "?*BOGUS:X25519 / *secp256r1", 1 }, /* stacked prefix, unknown */ + { "X25519:?BOGUS:secp256r1", 1 }, /* ignore unknown mid-tuple */ + { "*X25519:DEFAULT:-secp256r1:-X448", 1 }, /* DEFAULT + removals */ + { "DEFAULT:-X25519:-?curveSM2:-?ffdhe2048:-?ffdhe3072", 1 }, + { "secp256r1:DEFAULT", 1 }, /* prepend then DEFAULT */ + + /* --- expected syntax / parse errors --- */ + { "X25519//secp256r1", 0 }, /* empty tuple */ + { "X25519::secp256r1", 0 }, /* empty group */ + { ":X25519", 0 }, + { "X25519:", 0 }, + { "/X25519", 0 }, + { "X25519/", 0 }, + { "**X25519", 0 }, /* double keyshare prefix */ + { "??X25519", 0 }, + { "--X25519", 0 }, + { "X25519:NOTAREALGROUP", 0 }, /* unknown w/o '?' */ + { "-DEFAULT", 0 }, /* prefix on pseudo-group */ + { "?DEFAULT", 0 }, +}; + +static int run_edge(int idx) +{ + const EDGECASE *tc = &edgecases[idx]; + SSL_CTX *ctx = NULL; + int ret = 0, r; + + TEST_info("edge %d: [\"%s\"] expect %s", idx, tc->list, + tc->expect_ok ? "ok" : "error"); + + if (!TEST_ptr(ctx = SSL_CTX_new(TLS_method()))) + goto end; + + r = SSL_CTX_set1_groups_list(ctx, tc->list); + if (tc->expect_ok) { + if (!TEST_int_eq(r, 1) || !check_invariants(ctx)) + goto end; + } else { + if (!TEST_int_eq(r, 0)) + goto end; + } + + ret = 1; +end: + SSL_CTX_free(ctx); + return ret; +} + +int setup_tests(void) +{ + ADD_ALL_TESTS(run_case, (int)OSSL_NELEM(cases)); + ADD_ALL_TESTS(run_edge, (int)OSSL_NELEM(edgecases)); + return 1; +} diff --git a/test/unit/README.md b/test/unit/README.md index 42fd1873d54d1..b945b438ab7ab 100644 --- a/test/unit/README.md +++ b/test/unit/README.md @@ -513,7 +513,9 @@ list is tedious and error-prone, so the helper script `util/mkwraps.pl` generates a first draft from the `build.info` declaration. It reads the `WRAP[]` list, searches the headers under the target's `INCLUDE[]` directories for each function's prototype, and emits matching wrap functions -and expectation helpers. +and expectation helpers. Functions not found there (typically libc/POSIX +functions such as `read` or `socket`) are looked up under the compiler's +default system include paths, and emitted with angle-bracket includes. ```console $ ./util/mkwraps.pl --build-info test/unit/build.info \ @@ -526,6 +528,10 @@ Useful options: `expect_*` helpers, or both (the default). * `--include DIR`: add an extra header search directory beyond those in `INCLUDE[]`. Cumulative. + * `--cc NAME`: C compiler queried for the system include paths (default + `$CC` or `cc`). + * `--no-system`: do not fall back to the compiler's system include + directories for functions missing from the project headers. * `--output FILE`: write to a file instead of standard output. * `--verbose`: report progress and where each prototype was found. diff --git a/test/unit/build.info b/test/unit/build.info index ac04787457ec8..f9e6cbdef9f28 100644 --- a/test/unit/build.info +++ b/test/unit/build.info @@ -50,6 +50,13 @@ IF[{- $config{target} =~ /^(?:linux|BSD)/ -}] DEPEND[crypto/bio/test_bss_fd]=../../libcrypto.a WRAP[crypto/bio/test_bss_fd]=read write lseek close + PROGRAMS{noinst}=crypto/bio/test_bss_file + SOURCE[crypto/bio/test_bss_file]=crypto/bio/test_bss_file.c + INCLUDE[crypto/bio/test_bss_file]=../../include ../../crypto/bio + DEPEND[crypto/bio/test_bss_file]=../../libcrypto.a + WRAP[crypto/bio/test_bss_file]=openssl_fopen fread fwrite fseek ftell feof \ + ferror fclose fflush fgets + PROGRAMS{noinst}=crypto/bio/test_bss_sock SOURCE[crypto/bio/test_bss_sock]=crypto/bio/test_bss_sock.c WRAP[crypto/bio/test_bss_sock]=read write BIO_closesocket @@ -64,4 +71,20 @@ IF[{- $config{target} =~ /^VC-/ -}] INCLUDE[crypto/bio/test_bss_dgram_win]=../../include ../../include/internal \ ../../crypto/bio DEPEND[crypto/bio/test_bss_dgram_win]=../../libcrypto + + # On uplink builds the test must see the same BIO_FLAGS_UPLINK_INTERNAL + # value as libcrypto, and needs applink so UP_* calls dispatch into the + # test executable, where the detours intercept them. + IF[{- !$disabled{uplink} -}] + $INITSRC=../../ms/applink.c + $UPLINKDEF=OPENSSL_USE_APPLINK + ENDIF + + PROGRAMS{noinst}=crypto/bio/test_bss_file_win + SOURCE[crypto/bio/test_bss_file_win]=crypto/bio/test_bss_file_win.c $INITSRC + DEFINE[crypto/bio/test_bss_file_win]=$UPLINKDEF + UNIT_TEST[crypto/bio/test_bss_file_win]=cmocka detours + INCLUDE[crypto/bio/test_bss_file_win]=../../include ../../include/internal \ + ../../crypto/bio ../.. + DEPEND[crypto/bio/test_bss_file_win]=../../libcrypto ENDIF diff --git a/test/unit/crypto/bio/test_bss_file.c b/test/unit/crypto/bio/test_bss_file.c new file mode 100644 index 0000000000000..ccfa88d68703f --- /dev/null +++ b/test/unit/crypto/bio/test_bss_file.c @@ -0,0 +1,898 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifdef OPENSSL_NO_STDIO + +int main(void) +{ + return 0; +} + +#else + +#include +#include +#include +#include +#include +#include + +#include "bio_local.h" + +#include +#include + +static char fake_file_a; +static char fake_file_b; +#define FAKE_FP ((FILE *)&fake_file_a) +#define FAKE_FP2 ((FILE *)&fake_file_b) + +/* wraps */ + +FILE *__wrap_openssl_fopen(const char *filename, const char *mode); +size_t __wrap_fread(void *ptr, size_t size, size_t nmemb, FILE *stream); +size_t __wrap_fwrite(const void *ptr, size_t size, size_t nmemb, + FILE *stream); +int __wrap_fseek(FILE *stream, long offset, int whence); +long __wrap_ftell(FILE *stream); +int __wrap_feof(FILE *stream); +int __wrap_ferror(FILE *stream); +int __wrap_fclose(FILE *stream); +int __wrap_fflush(FILE *stream); +char *__wrap_fgets(char *s, int size, FILE *stream); + +size_t __real_fread(void *ptr, size_t size, size_t nmemb, FILE *stream); +size_t __real_fwrite(const void *ptr, size_t size, size_t nmemb, + FILE *stream); +int __real_fseek(FILE *stream, long offset, int whence); +long __real_ftell(FILE *stream); +int __real_feof(FILE *stream); +int __real_ferror(FILE *stream); +int __real_fclose(FILE *stream); +int __real_fflush(FILE *stream); +char *__real_fgets(char *s, int size, FILE *stream); + +/* + * The --wrap link option rewrites the stdio calls of everything linked + * into the binary, not just of bss_file.c. In particular libgcov in + * --coverage builds reads and writes the .gcda files at process exit + * through fread/fwrite/fseek/ftell/fclose, which must not hit the mocks. + * The tests only ever operate on the two fake FILE pointers, so calls on + * any other stream are forwarded to the real functions. + */ +static int is_mocked_fp(FILE *stream) +{ + return stream == FAKE_FP || stream == FAKE_FP2; +} + +FILE *__wrap_openssl_fopen(const char *filename, const char *mode) +{ + FILE *fp; + + function_called(); + check_expected(filename); + check_expected(mode); + fp = mock_ptr_type(FILE *); + if (fp == NULL) + errno = mock_type(int); + return fp; +} + +size_t __wrap_fread(void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + if (!is_mocked_fp(stream)) + return __real_fread(ptr, size, nmemb, stream); + function_called(); + check_expected_ptr(ptr); + check_expected(size); + check_expected(nmemb); + check_expected_ptr(stream); + return mock_type(size_t); +} + +size_t __wrap_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) +{ + if (!is_mocked_fp(stream)) + return __real_fwrite(ptr, size, nmemb, stream); + function_called(); + check_expected_ptr(ptr); + check_expected(size); + check_expected(nmemb); + check_expected_ptr(stream); + return mock_type(size_t); +} + +int __wrap_fseek(FILE *stream, long offset, int whence) +{ + if (!is_mocked_fp(stream)) + return __real_fseek(stream, offset, whence); + function_called(); + check_expected_ptr(stream); + check_expected(offset); + check_expected(whence); + return mock_type(int); +} + +long __wrap_ftell(FILE *stream) +{ + if (!is_mocked_fp(stream)) + return __real_ftell(stream); + function_called(); + check_expected_ptr(stream); + return mock_type(long); +} + +int __wrap_feof(FILE *stream) +{ + if (!is_mocked_fp(stream)) + return __real_feof(stream); + function_called(); + check_expected_ptr(stream); + return mock_type(int); +} + +int __wrap_ferror(FILE *stream) +{ + if (!is_mocked_fp(stream)) + return __real_ferror(stream); + function_called(); + check_expected_ptr(stream); + return mock_type(int); +} + +int __wrap_fclose(FILE *stream) +{ + if (!is_mocked_fp(stream)) + return __real_fclose(stream); + function_called(); + check_expected_ptr(stream); + return mock_type(int); +} + +int __wrap_fflush(FILE *stream) +{ + if (!is_mocked_fp(stream)) + return __real_fflush(stream); + function_called(); + check_expected_ptr(stream); + return mock_type(int); +} + +char *__wrap_fgets(char *s, int size, FILE *stream) +{ + const char *data; + + if (!is_mocked_fp(stream)) + return __real_fgets(s, size, stream); + function_called(); + check_expected_ptr(s); + check_expected(size); + check_expected_ptr(stream); + data = mock_ptr_type(const char *); + if (data == NULL) + return NULL; + assert_true(strlen(data) < (size_t)size); + strcpy(s, data); + return s; +} + +/* expectations */ + +/* errnoval is consumed by __wrap_openssl_fopen only when rc == NULL */ +static void expect_openssl_fopen(const char *filename, const char *mode, + FILE *rc, int errnoval) +{ + expect_function_call(__wrap_openssl_fopen); + expect_string(__wrap_openssl_fopen, filename, filename); + expect_string(__wrap_openssl_fopen, mode, mode); + will_return(__wrap_openssl_fopen, rc); + if (rc == NULL) + will_return(__wrap_openssl_fopen, errnoval); +} + +static void expect_fread(void *ptr, size_t nmemb, FILE *stream, size_t rc) +{ + expect_function_call(__wrap_fread); + expect_value(__wrap_fread, ptr, ptr); + expect_value(__wrap_fread, size, 1); + expect_value(__wrap_fread, nmemb, nmemb); + expect_value(__wrap_fread, stream, stream); + will_return(__wrap_fread, rc); +} + +static void expect_fwrite(const void *ptr, size_t nmemb, FILE *stream, + size_t rc) +{ + expect_function_call(__wrap_fwrite); + expect_value(__wrap_fwrite, ptr, ptr); + expect_value(__wrap_fwrite, size, 1); + expect_value(__wrap_fwrite, nmemb, nmemb); + expect_value(__wrap_fwrite, stream, stream); + will_return(__wrap_fwrite, rc); +} + +static void expect_fseek(FILE *stream, long offset, int whence, int rc) +{ + expect_function_call(__wrap_fseek); + expect_value(__wrap_fseek, stream, stream); + expect_value(__wrap_fseek, offset, offset); + expect_value(__wrap_fseek, whence, whence); + will_return(__wrap_fseek, rc); +} + +static void expect_ftell(FILE *stream, long rc) +{ + expect_function_call(__wrap_ftell); + expect_value(__wrap_ftell, stream, stream); + will_return(__wrap_ftell, rc); +} + +static void expect_feof(FILE *stream, int rc) +{ + expect_function_call(__wrap_feof); + expect_value(__wrap_feof, stream, stream); + will_return(__wrap_feof, rc); +} + +static void expect_ferror(FILE *stream, int rc) +{ + expect_function_call(__wrap_ferror); + expect_value(__wrap_ferror, stream, stream); + will_return(__wrap_ferror, rc); +} + +static void expect_fclose(FILE *stream, int rc) +{ + expect_function_call(__wrap_fclose); + expect_value(__wrap_fclose, stream, stream); + will_return(__wrap_fclose, rc); +} + +static void expect_fflush(FILE *stream, int rc) +{ + expect_function_call(__wrap_fflush); + expect_value(__wrap_fflush, stream, stream); + will_return(__wrap_fflush, rc); +} + +/* data is copied into the caller's buffer by __wrap_fgets; NULL means EOF */ +static void expect_fgets(char *s, int size, FILE *stream, const char *data) +{ + expect_function_call(__wrap_fgets); + expect_value(__wrap_fgets, s, s); + expect_value(__wrap_fgets, size, size); + expect_value(__wrap_fgets, stream, stream); + will_return(__wrap_fgets, data); +} + +/* setup / teardown */ + +static int setup(void **state) +{ + BIO *bio = BIO_new(BIO_s_file()); + + assert_non_null(bio); + BIO_set_fp(bio, FAKE_FP, BIO_NOCLOSE); + *state = bio; + return 0; +} + +static int teardown(void **state) +{ + if (*state != NULL) + BIO_free(*state); + return 0; +} + +/* BIO_new_file */ + +static void test_new_file_success(void **state) +{ + BIO *bio; + FILE *fp = NULL; + + (void)state; + expect_openssl_fopen("test.txt", "r", FAKE_FP, 0); + bio = BIO_new_file("test.txt", "r"); + assert_non_null(bio); + assert_int_equal(BIO_get_fp(bio, &fp), 1); + assert_ptr_equal(fp, FAKE_FP); + assert_int_equal(BIO_get_close(bio), BIO_CLOSE); + + expect_fclose(FAKE_FP, 0); + BIO_free(bio); +} + +static void test_new_file_binary_mode(void **state) +{ + BIO *bio; + + (void)state; + expect_openssl_fopen("test.bin", "rb", FAKE_FP, 0); + bio = BIO_new_file("test.bin", "rb"); + assert_non_null(bio); + + expect_fclose(FAKE_FP, 0); + BIO_free(bio); +} + +static void test_new_file_no_such_file(void **state) +{ + (void)state; + ERR_clear_error(); + expect_openssl_fopen("missing.txt", "r", NULL, ENOENT); + assert_null(BIO_new_file("missing.txt", "r")); + assert_int_equal(ERR_GET_REASON(ERR_peek_last_error()), + BIO_R_NO_SUCH_FILE); +} + +static void test_new_file_sys_error(void **state) +{ + (void)state; + ERR_clear_error(); + expect_openssl_fopen("secret.txt", "r", NULL, EACCES); + assert_null(BIO_new_file("secret.txt", "r")); + assert_int_equal(ERR_GET_REASON(ERR_peek_last_error()), ERR_R_SYS_LIB); +} + +static void test_new_file_null_filename(void **state) +{ + (void)state; + ERR_clear_error(); + assert_null(BIO_new_file(NULL, "r")); + assert_int_equal(ERR_GET_REASON(ERR_peek_last_error()), + ERR_R_PASSED_NULL_PARAMETER); +} + +/* BIO_new_fp */ + +static void test_new_fp_noclose(void **state) +{ + BIO *bio; + FILE *fp = NULL; + + (void)state; + bio = BIO_new_fp(FAKE_FP, BIO_NOCLOSE); + assert_non_null(bio); + assert_int_equal(BIO_get_fp(bio, &fp), 1); + assert_ptr_equal(fp, FAKE_FP); + assert_int_equal(BIO_get_close(bio), BIO_NOCLOSE); + BIO_free(bio); +} + +static void test_new_fp_close(void **state) +{ + BIO *bio; + + (void)state; + bio = BIO_new_fp(FAKE_FP, BIO_CLOSE); + assert_non_null(bio); + assert_int_equal(BIO_get_close(bio), BIO_CLOSE); + + expect_fclose(FAKE_FP, 0); + BIO_free(bio); +} + +/* file_read (via BIO_read) */ + +static void test_file_read_success(void **state) +{ + BIO *bio = *state; + char buf[8] = { 0 }; + + expect_fread(buf, 8, FAKE_FP, 8); + assert_int_equal(BIO_read(bio, buf, 8), 8); +} + +static void test_file_read_short(void **state) +{ + BIO *bio = *state; + char buf[8] = { 0 }; + + expect_fread(buf, 8, FAKE_FP, 3); + assert_int_equal(BIO_read(bio, buf, 8), 3); +} + +static void test_file_read_eof(void **state) +{ + /* + * fread returns 0 without ferror: plain EOF, no error is raised. + * The two trailing feof calls come from outside bss_file.c: one from + * bread_conv and one from bio_read_intern, which both query + * BIO_CTRL_EOF when the method's read reports 0 bytes. + */ + BIO *bio = *state; + char buf[8] = { 0 }; + + expect_fread(buf, 8, FAKE_FP, 0); + expect_ferror(FAKE_FP, 0); + expect_feof(FAKE_FP, 1); + expect_feof(FAKE_FP, 1); + assert_int_equal(BIO_read(bio, buf, 8), 0); +} + +static void test_file_read_error(void **state) +{ + /* fread returns 0 with ferror set: -1 and ERR_R_SYS_LIB is raised */ + BIO *bio = *state; + char buf[8] = { 0 }; + + ERR_clear_error(); + expect_fread(buf, 8, FAKE_FP, 0); + expect_ferror(FAKE_FP, 1); + assert_int_equal(BIO_read(bio, buf, 8), -1); + assert_int_equal(ERR_GET_REASON(ERR_peek_last_error()), ERR_R_SYS_LIB); +} + +static void test_file_read_zero_length(void **state) +{ + /* outl == 0 never reaches fread */ + BIO *bio = *state; + char buf[8] = { 0 }; + + assert_true(BIO_read(bio, buf, 0) <= 0); +} + +/* file_write (via BIO_write) */ + +static void test_file_write_success(void **state) +{ + BIO *bio = *state; + const char buf[] = "hello"; + + expect_fwrite(buf, 5, FAKE_FP, 5); + assert_int_equal(BIO_write(bio, buf, 5), 5); +} + +static void test_file_write_partial(void **state) +{ + BIO *bio = *state; + const char buf[] = "hello"; + + expect_fwrite(buf, 5, FAKE_FP, 3); + assert_int_equal(BIO_write(bio, buf, 5), 3); +} + +static void test_file_write_fails(void **state) +{ + BIO *bio = *state; + const char buf[] = "hello"; + + expect_fwrite(buf, 5, FAKE_FP, 0); + assert_true(BIO_write(bio, buf, 5) <= 0); +} + +/* file_ctrl (via BIO_ctrl) */ + +static void test_file_ctrl_reset(void **state) +{ + BIO *bio = *state; + + expect_fseek(FAKE_FP, 0, 0, 0); + assert_int_equal(BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL), 0); +} + +static void test_file_ctrl_seek(void **state) +{ + BIO *bio = *state; + + expect_fseek(FAKE_FP, 512, 0, 0); + assert_int_equal(BIO_ctrl(bio, BIO_C_FILE_SEEK, 512, NULL), 0); +} + +static void test_file_ctrl_seek_fails(void **state) +{ + BIO *bio = *state; + + expect_fseek(FAKE_FP, 512, 0, -1); + assert_int_equal(BIO_ctrl(bio, BIO_C_FILE_SEEK, 512, NULL), -1); +} + +static void test_file_ctrl_tell(void **state) +{ + BIO *bio = *state; + + expect_ftell(FAKE_FP, 256); + assert_int_equal(BIO_ctrl(bio, BIO_C_FILE_TELL, 0, NULL), 256); +} + +static void test_file_ctrl_info(void **state) +{ + BIO *bio = *state; + + /* BIO_CTRL_INFO shares the ftell branch with FILE_TELL */ + expect_ftell(FAKE_FP, 128); + assert_int_equal(BIO_ctrl(bio, BIO_CTRL_INFO, 0, NULL), 128); +} + +static void test_file_ctrl_eof_clear(void **state) +{ + BIO *bio = *state; + + expect_feof(FAKE_FP, 0); + assert_int_equal(BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL), 0); +} + +static void test_file_ctrl_eof_set(void **state) +{ + /* any non-zero feof result is mapped to 1 by double negation */ + BIO *bio = *state; + + expect_feof(FAKE_FP, 7); + assert_int_equal(BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL), 1); +} + +static void test_file_ctrl_set_fp_replaces(void **state) +{ + /* shutdown=BIO_NOCLOSE: the old fp is dropped without fclose */ + BIO *bio = *state; + FILE *fp = NULL; + + BIO_set_fp(bio, FAKE_FP2, BIO_NOCLOSE); + assert_int_equal(BIO_get_fp(bio, &fp), 1); + assert_ptr_equal(fp, FAKE_FP2); + assert_int_equal(bio->init, 1); +} + +static void test_file_ctrl_set_fp_closes_old(void **state) +{ + /* shutdown=BIO_CLOSE: the old fp is fclosed before the replacement */ + BIO *bio = *state; + FILE *fp = NULL; + + BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, BIO_CLOSE, NULL); + expect_fclose(FAKE_FP, 0); + BIO_set_fp(bio, FAKE_FP2, BIO_NOCLOSE); + assert_int_equal(BIO_get_fp(bio, &fp), 1); + assert_ptr_equal(fp, FAKE_FP2); + assert_int_equal(BIO_get_close(bio), BIO_NOCLOSE); +} + +static void test_file_ctrl_get_fp(void **state) +{ + BIO *bio = *state; + FILE *fp = NULL; + + assert_int_equal(BIO_get_fp(bio, &fp), 1); + assert_ptr_equal(fp, FAKE_FP); +} + +static void set_filename_test(BIO *bio, long flags, const char *mode) +{ + FILE *fp = NULL; + + expect_openssl_fopen("file.txt", mode, FAKE_FP2, 0); + assert_int_equal( + BIO_ctrl(bio, BIO_C_SET_FILENAME, flags, (void *)"file.txt"), 1); + assert_int_equal(BIO_get_fp(bio, &fp), 1); + assert_ptr_equal(fp, FAKE_FP2); +} + +static void test_file_ctrl_set_filename_read(void **state) +{ + set_filename_test(*state, BIO_FP_READ, "r"); +} + +static void test_file_ctrl_set_filename_write(void **state) +{ + set_filename_test(*state, BIO_FP_WRITE, "w"); +} + +static void test_file_ctrl_set_filename_read_write(void **state) +{ + set_filename_test(*state, BIO_FP_READ | BIO_FP_WRITE, "r+"); +} + +static void test_file_ctrl_set_filename_append(void **state) +{ + set_filename_test(*state, BIO_FP_APPEND, "a"); +} + +static void test_file_ctrl_set_filename_append_read(void **state) +{ + set_filename_test(*state, BIO_FP_APPEND | BIO_FP_READ, "a+"); +} + +static void test_file_ctrl_set_filename_close_flag(void **state) +{ + BIO *bio = *state; + + expect_openssl_fopen("file.txt", "r", FAKE_FP2, 0); + assert_int_equal(BIO_ctrl(bio, BIO_C_SET_FILENAME, + BIO_CLOSE | BIO_FP_READ, (void *)"file.txt"), + 1); + assert_int_equal(BIO_get_close(bio), BIO_CLOSE); + /* Restore before teardown to avoid an unexpected fclose call. */ + BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, BIO_NOCLOSE, NULL); +} + +static void test_file_ctrl_set_filename_bad_mode(void **state) +{ + /* no BIO_FP_* mode flag at all: BIO_R_BAD_FOPEN_MODE, no fopen call */ + BIO *bio = *state; + + ERR_clear_error(); + assert_int_equal( + BIO_ctrl(bio, BIO_C_SET_FILENAME, 0, (void *)"file.txt"), 0); + assert_int_equal(ERR_GET_REASON(ERR_peek_last_error()), + BIO_R_BAD_FOPEN_MODE); +} + +static void test_file_ctrl_set_filename_null(void **state) +{ + BIO *bio = *state; + + ERR_clear_error(); + assert_int_equal(BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_FP_READ, NULL), 0); + assert_int_equal(ERR_GET_REASON(ERR_peek_last_error()), + ERR_R_PASSED_NULL_PARAMETER); +} + +static void test_file_ctrl_set_filename_fopen_fails(void **state) +{ + BIO *bio = *state; + + ERR_clear_error(); + expect_openssl_fopen("file.txt", "r", NULL, EACCES); + assert_int_equal( + BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_FP_READ, (void *)"file.txt"), + 0); + assert_int_equal(ERR_GET_REASON(ERR_peek_last_error()), ERR_R_SYS_LIB); +} + +static void test_file_ctrl_get_close(void **state) +{ + BIO *bio = *state; + + assert_int_equal(BIO_ctrl(bio, BIO_CTRL_GET_CLOSE, 0, NULL), + BIO_NOCLOSE); + bio->shutdown = BIO_CLOSE; + assert_int_equal(BIO_ctrl(bio, BIO_CTRL_GET_CLOSE, 0, NULL), BIO_CLOSE); + bio->shutdown = BIO_NOCLOSE; +} + +static void test_file_ctrl_set_close(void **state) +{ + BIO *bio = *state; + + BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, BIO_CLOSE, NULL); + assert_int_equal(bio->shutdown, BIO_CLOSE); + /* Restore before teardown to avoid an unexpected fclose call. */ + BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, BIO_NOCLOSE, NULL); +} + +static void test_file_ctrl_flush(void **state) +{ + BIO *bio = *state; + + expect_fflush(FAKE_FP, 0); + assert_int_equal(BIO_ctrl(bio, BIO_CTRL_FLUSH, 0, NULL), 1); +} + +static void test_file_ctrl_flush_fails(void **state) +{ + BIO *bio = *state; + + ERR_clear_error(); + expect_fflush(FAKE_FP, EOF); + assert_int_equal(BIO_ctrl(bio, BIO_CTRL_FLUSH, 0, NULL), 0); + assert_int_equal(ERR_GET_REASON(ERR_peek_last_error()), ERR_R_SYS_LIB); +} + +static void test_file_ctrl_dup(void **state) +{ + assert_int_equal(BIO_ctrl(*state, BIO_CTRL_DUP, 0, NULL), 1); +} + +static void test_file_ctrl_pending(void **state) +{ + assert_int_equal(BIO_ctrl(*state, BIO_CTRL_PENDING, 0, NULL), 0); +} + +static void test_file_ctrl_wpending(void **state) +{ + assert_int_equal(BIO_ctrl(*state, BIO_CTRL_WPENDING, 0, NULL), 0); +} + +static void test_file_ctrl_default(void **state) +{ + assert_int_equal(BIO_ctrl(*state, 9999, 0, NULL), 0); +} + +/* file_gets (via BIO_gets) */ + +static void test_file_gets_success(void **state) +{ + BIO *bio = *state; + char buf[16] = { 0 }; + + expect_fgets(buf, (int)sizeof(buf), FAKE_FP, "hi\n"); + assert_int_equal(BIO_gets(bio, buf, (int)sizeof(buf)), 3); + assert_string_equal(buf, "hi\n"); +} + +static void test_file_gets_empty(void **state) +{ + /* fgets succeeds but stores an empty string: 0 is returned */ + BIO *bio = *state; + char buf[16] = { 'x' }; + + expect_fgets(buf, (int)sizeof(buf), FAKE_FP, ""); + assert_int_equal(BIO_gets(bio, buf, (int)sizeof(buf)), 0); + assert_int_equal(buf[0], '\0'); +} + +static void test_file_gets_eof(void **state) +{ + /* fgets returns NULL: 0 is returned and the buffer is cleared */ + BIO *bio = *state; + char buf[16] = { 'x' }; + + expect_fgets(buf, (int)sizeof(buf), FAKE_FP, NULL); + assert_int_equal(BIO_gets(bio, buf, (int)sizeof(buf)), 0); + assert_int_equal(buf[0], '\0'); +} + +/* file_puts (via BIO_puts) */ + +static void test_file_puts_success(void **state) +{ + BIO *bio = *state; + const char *str = "hello"; + + expect_fwrite(str, 5, FAKE_FP, 5); + assert_int_equal(BIO_puts(bio, str), 5); +} + +static void test_file_puts_write_fails(void **state) +{ + BIO *bio = *state; + const char *str = "hello"; + + expect_fwrite(str, 5, FAKE_FP, 0); + assert_true(BIO_puts(bio, str) <= 0); +} + +/* file_free (via BIO_free) */ + +static void test_file_free_shutdown_closes(void **state) +{ + /* shutdown=1, init=1 and ptr set: fclose must be called */ + BIO *bio = BIO_new(BIO_s_file()); + + (void)state; + assert_non_null(bio); + bio->ptr = FAKE_FP; + bio->init = 1; + bio->shutdown = BIO_CLOSE; + + expect_fclose(FAKE_FP, 0); + BIO_free(bio); +} + +static void test_file_free_no_shutdown(void **state) +{ + /* shutdown=0: fclose must NOT be called regardless of init */ + BIO *bio = BIO_new(BIO_s_file()); + + (void)state; + assert_non_null(bio); + bio->ptr = FAKE_FP; + bio->init = 1; + bio->shutdown = BIO_NOCLOSE; + + BIO_free(bio); +} + +static void test_file_free_shutdown_no_init(void **state) +{ + /* shutdown=1 but init=0: fclose must NOT be called */ + BIO *bio = BIO_new(BIO_s_file()); + + (void)state; + assert_non_null(bio); + bio->ptr = FAKE_FP; + bio->init = 0; + bio->shutdown = BIO_CLOSE; + + BIO_free(bio); +} + +static void test_file_free_shutdown_null_ptr(void **state) +{ + /* shutdown=1, init=1 but ptr=NULL: fclose must NOT be called */ + BIO *bio = BIO_new(BIO_s_file()); + + (void)state; + assert_non_null(bio); + bio->ptr = NULL; + bio->init = 1; + bio->shutdown = BIO_CLOSE; + + BIO_free(bio); +} + +/* main */ + +#define FILE_TEST(name) \ + cmocka_unit_test_setup_teardown(name, setup, teardown) + +#define FILE_TEST_PLAIN(name) \ + cmocka_unit_test(name) + +int main(void) +{ + const struct CMUnitTest tests[] = { + /* BIO_new_file */ + FILE_TEST_PLAIN(test_new_file_success), + FILE_TEST_PLAIN(test_new_file_binary_mode), + FILE_TEST_PLAIN(test_new_file_no_such_file), + FILE_TEST_PLAIN(test_new_file_sys_error), + FILE_TEST_PLAIN(test_new_file_null_filename), + /* BIO_new_fp */ + FILE_TEST_PLAIN(test_new_fp_noclose), + FILE_TEST_PLAIN(test_new_fp_close), + /* file_read */ + FILE_TEST(test_file_read_success), + FILE_TEST(test_file_read_short), + FILE_TEST(test_file_read_eof), + FILE_TEST(test_file_read_error), + FILE_TEST(test_file_read_zero_length), + /* file_write */ + FILE_TEST(test_file_write_success), + FILE_TEST(test_file_write_partial), + FILE_TEST(test_file_write_fails), + /* file_ctrl */ + FILE_TEST(test_file_ctrl_reset), + FILE_TEST(test_file_ctrl_seek), + FILE_TEST(test_file_ctrl_seek_fails), + FILE_TEST(test_file_ctrl_tell), + FILE_TEST(test_file_ctrl_info), + FILE_TEST(test_file_ctrl_eof_clear), + FILE_TEST(test_file_ctrl_eof_set), + FILE_TEST(test_file_ctrl_set_fp_replaces), + FILE_TEST(test_file_ctrl_set_fp_closes_old), + FILE_TEST(test_file_ctrl_get_fp), + FILE_TEST(test_file_ctrl_set_filename_read), + FILE_TEST(test_file_ctrl_set_filename_write), + FILE_TEST(test_file_ctrl_set_filename_read_write), + FILE_TEST(test_file_ctrl_set_filename_append), + FILE_TEST(test_file_ctrl_set_filename_append_read), + FILE_TEST(test_file_ctrl_set_filename_close_flag), + FILE_TEST(test_file_ctrl_set_filename_bad_mode), + FILE_TEST(test_file_ctrl_set_filename_null), + FILE_TEST(test_file_ctrl_set_filename_fopen_fails), + FILE_TEST(test_file_ctrl_get_close), + FILE_TEST(test_file_ctrl_set_close), + FILE_TEST(test_file_ctrl_flush), + FILE_TEST(test_file_ctrl_flush_fails), + FILE_TEST(test_file_ctrl_dup), + FILE_TEST(test_file_ctrl_pending), + FILE_TEST(test_file_ctrl_wpending), + FILE_TEST(test_file_ctrl_default), + /* file_gets */ + FILE_TEST(test_file_gets_success), + FILE_TEST(test_file_gets_empty), + FILE_TEST(test_file_gets_eof), + /* file_puts */ + FILE_TEST(test_file_puts_success), + FILE_TEST(test_file_puts_write_fails), + /* file_free */ + FILE_TEST_PLAIN(test_file_free_shutdown_closes), + FILE_TEST_PLAIN(test_file_free_no_shutdown), + FILE_TEST_PLAIN(test_file_free_shutdown_no_init), + FILE_TEST_PLAIN(test_file_free_shutdown_null_ptr), + }; + + cmocka_set_message_output(CM_OUTPUT_TAP); + + return cmocka_run_group_tests(tests, NULL, NULL); +} + +#endif /* OPENSSL_NO_STDIO */ diff --git a/test/unit/crypto/bio/test_bss_file_win.c b/test/unit/crypto/bio/test_bss_file_win.c new file mode 100644 index 0000000000000..3d77512fb9961 --- /dev/null +++ b/test/unit/crypto/bio/test_bss_file_win.c @@ -0,0 +1,753 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +/* + * Windows-only side test for bss_file.c Windows-specific paths. + * Uses Microsoft Detours to intercept CRT stdio calls at runtime. + * Does NOT replace the normal --wrap-based bss_file test; it only + * covers branches that differ under OPENSSL_SYS_WINDOWS: the feof + * EINVAL quirk, the GetFileType guard around ftell, the _setmode + * text/binary handling, the "b"/"t" fopen mode suffix, and (on + * uplink builds) the UP_* applink dispatch. + * + * The CRT interception relies on the test executable and libcrypto + * resolving stdio to the same CRT (the /MD default, where both use + * ucrtbase.dll); Detours patches the function bodies there, so calls + * from either module land in the mocks, and errno set by a mock is + * visible to libcrypto since the per-thread errno lives in the shared + * CRT. On uplink builds the applink table is populated with this + * executable's CRT functions (ms/applink.c is linked in), which the + * same detours intercept. + * + * NOTE: not compiled/verified by the author's toolchain. The first + * test (detour_probe) is a hard gate: if Detours does not intercept + * cross-module CRT calls, every other result is meaningless. + */ + +#include "openssl/e_os2.h" + +#if defined(OPENSSL_NO_STDIO) || !defined(OPENSSL_SYS_WINDOWS) +int main(void) +{ + return 0; +} +#else + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "internal/sockets.h" +#include "bio_local.h" + +#include +#include + +static char fake_file_a; +static char fake_file_b; +#define FAKE_FP ((FILE *)&fake_file_a) +#define FAKE_FP2 ((FILE *)&fake_file_b) +#define FAKE_FD 7 +#define FAKE_OSFHANDLE ((intptr_t)0x1234) + +/* + * Real function pointers. After DetourAttach commits, Detours rewrites + * these to trampolines pointing at the original code. + */ +static int(__cdecl *real_feof)(FILE *) = feof; +static long(__cdecl *real_ftell)(FILE *) = ftell; +static size_t(__cdecl *real_fread)(void *, size_t, size_t, FILE *) = fread; +static size_t(__cdecl *real_fwrite)(const void *, size_t, size_t, FILE *) + = fwrite; +static int(__cdecl *real_fclose)(FILE *) = fclose; +static int(__cdecl *real_fileno)(FILE *) = _fileno; +static int(__cdecl *real_setmode)(int, int) = _setmode; +static intptr_t(__cdecl *real_get_osfhandle)(int) = _get_osfhandle; +static FILE *(__cdecl *real_wfopen)(const wchar_t *, const wchar_t *) + = _wfopen; +static DWORD(WINAPI *real_GetFileType)(HANDLE) = GetFileType; + +/* + * The detours are installed process-wide for the whole run, but the CRT + * (and cmocka itself) call some of these functions internally -- most + * importantly _fileno, which the stdio write path invokes on every + * printf/fwrite used to emit the TAP output. If a mock enforced cmocka + * expectations on those internal calls it would recurse (an unexpected + * call makes cmocka print an error, which calls _fileno again, ...) and + * blow the stack. So a mock only enforces expectations while a test has + * explicitly armed it via g_mocks_armed; otherwise it forwards to the + * real function through the Detours trampoline. Each mock also disarms + * around its own cmocka calls so that a failing expectation can report + * cleanly (its error output would otherwise re-enter the mock). + */ +static int g_mocks_armed; + +static void mocks_arm(void) +{ + g_mocks_armed = 1; +} + +static void mocks_disarm(void) +{ + g_mocks_armed = 0; +} + +/* + * detour_probe uses this to confirm the mock actually fired. It is the + * only place a mock is allowed to run outside a cmocka expectation, so + * mock_feof special-cases it. + */ +static int g_probe_active; +static int g_probe_feof_hits; + +/* mocks */ + +static int __cdecl mock_feof(FILE *stream) +{ + int rc; + + /* Probe path: no expectations queued, just record and answer. */ + if (g_probe_active) { + g_probe_feof_hits++; + return 0; + } + if (!g_mocks_armed) + return real_feof(stream); + + g_mocks_armed = 0; + function_called(); + check_expected_ptr(stream); + rc = mock_type(int); + /* + * bss_file.c inspects errno after feof to detect the invalid-stream + * case, so the mock always programs it (0 for the normal case). + */ + errno = mock_type(int); + g_mocks_armed = 1; + return rc; +} + +static long __cdecl mock_ftell(FILE *stream) +{ + long rc; + + if (!g_mocks_armed) + return real_ftell(stream); + + g_mocks_armed = 0; + function_called(); + check_expected_ptr(stream); + rc = mock_type(long); + g_mocks_armed = 1; + return rc; +} + +static size_t __cdecl mock_fread(void *ptr, size_t size, size_t nmemb, + FILE *stream) +{ + size_t rc; + + if (!g_mocks_armed) + return real_fread(ptr, size, nmemb, stream); + + g_mocks_armed = 0; + function_called(); + check_expected_ptr(ptr); + check_expected(size); + check_expected(nmemb); + check_expected_ptr(stream); + rc = mock_type(size_t); + g_mocks_armed = 1; + return rc; +} + +static size_t __cdecl mock_fwrite(const void *ptr, size_t size, size_t nmemb, + FILE *stream) +{ + size_t rc; + + if (!g_mocks_armed) + return real_fwrite(ptr, size, nmemb, stream); + + g_mocks_armed = 0; + function_called(); + check_expected_ptr(ptr); + check_expected(size); + check_expected(nmemb); + check_expected_ptr(stream); + rc = mock_type(size_t); + g_mocks_armed = 1; + return rc; +} + +static int __cdecl mock_fclose(FILE *stream) +{ + int rc; + + if (!g_mocks_armed) + return real_fclose(stream); + + g_mocks_armed = 0; + function_called(); + check_expected_ptr(stream); + rc = mock_type(int); + g_mocks_armed = 1; + return rc; +} + +static int __cdecl mock_fileno(FILE *stream) +{ + int rc; + + if (!g_mocks_armed) + return real_fileno(stream); + + g_mocks_armed = 0; + function_called(); + check_expected_ptr(stream); + rc = mock_type(int); + g_mocks_armed = 1; + return rc; +} + +static int __cdecl mock_setmode(int fd, int mode) +{ + int rc; + + if (!g_mocks_armed) + return real_setmode(fd, mode); + + g_mocks_armed = 0; + function_called(); + check_expected(fd); + check_expected(mode); + rc = mock_type(int); + g_mocks_armed = 1; + return rc; +} + +static intptr_t __cdecl mock_get_osfhandle(int fd) +{ + intptr_t rc; + + if (!g_mocks_armed) + return real_get_osfhandle(fd); + + g_mocks_armed = 0; + function_called(); + check_expected(fd); + rc = mock_type(intptr_t); + g_mocks_armed = 1; + return rc; +} + +static FILE *__cdecl mock_wfopen(const wchar_t *filename, + const wchar_t *mode) +{ + const wchar_t *exp_filename; + const wchar_t *exp_mode; + FILE *rc; + + if (!g_mocks_armed) + return real_wfopen(filename, mode); + + g_mocks_armed = 0; + function_called(); + exp_filename = mock_ptr_type(const wchar_t *); + exp_mode = mock_ptr_type(const wchar_t *); + assert_int_equal(wcscmp(filename, exp_filename), 0); + assert_int_equal(wcscmp(mode, exp_mode), 0); + rc = mock_ptr_type(FILE *); + if (rc == NULL) + errno = mock_type(int); + g_mocks_armed = 1; + return rc; +} + +static DWORD WINAPI mock_GetFileType(HANDLE h) +{ + DWORD rc; + + if (!g_mocks_armed) + return real_GetFileType(h); + + g_mocks_armed = 0; + function_called(); + check_expected_ptr(h); + rc = mock_type(DWORD); + g_mocks_armed = 1; + return rc; +} + +/* expectations */ + +/* + * errnoval is always consumed by mock_feof; pass 0 unless the test + * exercises the invalid-stream (EINVAL) quirk. + */ +static void expect_feof(FILE *stream, int rc, int errnoval) +{ + expect_function_call(mock_feof); + expect_value(mock_feof, stream, stream); + will_return(mock_feof, rc); + will_return(mock_feof, errnoval); +} + +static void expect_ftell(FILE *stream, long rc) +{ + expect_function_call(mock_ftell); + expect_value(mock_ftell, stream, stream); + will_return(mock_ftell, rc); +} + +static void expect_fread(void *ptr, size_t nmemb, FILE *stream, size_t rc) +{ + expect_function_call(mock_fread); + expect_value(mock_fread, ptr, ptr); + expect_value(mock_fread, size, 1); + expect_value(mock_fread, nmemb, nmemb); + expect_value(mock_fread, stream, stream); + will_return(mock_fread, rc); +} + +static void expect_fwrite(const void *ptr, size_t nmemb, FILE *stream, + size_t rc) +{ + expect_function_call(mock_fwrite); + expect_value(mock_fwrite, ptr, ptr); + expect_value(mock_fwrite, size, 1); + expect_value(mock_fwrite, nmemb, nmemb); + expect_value(mock_fwrite, stream, stream); + will_return(mock_fwrite, rc); +} + +static void expect_fclose(FILE *stream, int rc) +{ + expect_function_call(mock_fclose); + expect_value(mock_fclose, stream, stream); + will_return(mock_fclose, rc); +} + +static void expect_fileno(FILE *stream, int rc) +{ + expect_function_call(mock_fileno); + expect_value(mock_fileno, stream, stream); + will_return(mock_fileno, rc); +} + +static void expect_setmode(int fd, int mode, int rc) +{ + expect_function_call(mock_setmode); + expect_value(mock_setmode, fd, fd); + expect_value(mock_setmode, mode, mode); + will_return(mock_setmode, rc); +} + +static void expect_get_osfhandle(int fd, intptr_t rc) +{ + expect_function_call(mock_get_osfhandle); + expect_value(mock_get_osfhandle, fd, fd); + will_return(mock_get_osfhandle, rc); +} + +static void expect_wfopen(const wchar_t *filename, const wchar_t *mode, + FILE *rc, int errnoval) +{ + expect_function_call(mock_wfopen); + will_return(mock_wfopen, filename); + will_return(mock_wfopen, mode); + will_return(mock_wfopen, rc); + if (rc == NULL) + will_return(mock_wfopen, errnoval); +} + +static void expect_GetFileType(intptr_t h, DWORD rc) +{ + expect_function_call(mock_GetFileType); + expect_value(mock_GetFileType, h, (HANDLE)h); + will_return(mock_GetFileType, rc); +} + +/* + * Setting a FILE pointer always routes through the text/binary mode + * setup: _setmode on the non-uplink path, UP_fsetmod -> applink -> + * _setmode on the uplink path. Either way the same two CRT calls are + * observed. + */ +static void expect_set_fp_mode(FILE *fp, int fd, int mode) +{ + expect_fileno(fp, fd); + expect_setmode(fd, mode, 0); +} + +/* detours */ + +static int attach_detours(void) +{ + if (DetourTransactionBegin() != NO_ERROR) + return 0; + if (DetourUpdateThread(GetCurrentThread()) != NO_ERROR) + return 0; + if (DetourAttach((PVOID *)&real_feof, mock_feof) != NO_ERROR) + return 0; + if (DetourAttach((PVOID *)&real_ftell, mock_ftell) != NO_ERROR) + return 0; + if (DetourAttach((PVOID *)&real_fread, mock_fread) != NO_ERROR) + return 0; + if (DetourAttach((PVOID *)&real_fwrite, mock_fwrite) != NO_ERROR) + return 0; + if (DetourAttach((PVOID *)&real_fclose, mock_fclose) != NO_ERROR) + return 0; + if (DetourAttach((PVOID *)&real_fileno, mock_fileno) != NO_ERROR) + return 0; + if (DetourAttach((PVOID *)&real_setmode, mock_setmode) != NO_ERROR) + return 0; + if (DetourAttach((PVOID *)&real_get_osfhandle, mock_get_osfhandle) + != NO_ERROR) + return 0; + if (DetourAttach((PVOID *)&real_wfopen, mock_wfopen) != NO_ERROR) + return 0; + if (DetourAttach((PVOID *)&real_GetFileType, mock_GetFileType) + != NO_ERROR) + return 0; + return DetourTransactionCommit() == NO_ERROR; +} + +static int detach_detours(void) +{ + if (DetourTransactionBegin() != NO_ERROR) + return 0; + if (DetourUpdateThread(GetCurrentThread()) != NO_ERROR) + return 0; + DetourDetach((PVOID *)&real_feof, mock_feof); + DetourDetach((PVOID *)&real_ftell, mock_ftell); + DetourDetach((PVOID *)&real_fread, mock_fread); + DetourDetach((PVOID *)&real_fwrite, mock_fwrite); + DetourDetach((PVOID *)&real_fclose, mock_fclose); + DetourDetach((PVOID *)&real_fileno, mock_fileno); + DetourDetach((PVOID *)&real_setmode, mock_setmode); + DetourDetach((PVOID *)&real_get_osfhandle, mock_get_osfhandle); + DetourDetach((PVOID *)&real_wfopen, mock_wfopen); + DetourDetach((PVOID *)&real_GetFileType, mock_GetFileType); + return DetourTransactionCommit() == NO_ERROR; +} + +/* setup / teardown */ + +/* + * A BIO in the state BIO_new_file leaves it in: the UPLINK flag is + * cleared, so all Windows-specific non-uplink branches are reachable. + */ +static int setup_internal(void **state) +{ + BIO *bio = BIO_new(BIO_s_file()); + + assert_non_null(bio); + BIO_clear_flags(bio, BIO_FLAGS_UPLINK_INTERNAL); + mocks_arm(); + expect_set_fp_mode(FAKE_FP, FAKE_FD, _O_BINARY); + BIO_set_fp(bio, FAKE_FP, BIO_NOCLOSE); + *state = bio; + return 0; +} + +static int teardown(void **state) +{ + /* + * Disarm before BIO_free (and before cmocka prints the test result): + * once disarmed the mocks forward to the real CRT, so neither the + * NOCLOSE teardown nor the TAP output re-enters an expectation. + */ + mocks_disarm(); + if (*state != NULL) + BIO_free(*state); + return 0; +} + +static int group_setup(void **state) +{ + (void)state; + assert_true(attach_detours()); + return 0; +} + +static int group_teardown(void **state) +{ + (void)state; + assert_true(detach_detours()); + return 0; +} + +/* + * GATE: prove Detours intercepts a CRT call. If this fails, fix the + * linkage (e.g. the test and libcrypto using different CRTs) before + * trusting any other test below. + */ +static void detour_probe(void **state) +{ + (void)state; + g_probe_feof_hits = 0; + g_probe_active = 1; + feof(stdin); + g_probe_active = 0; + + assert_int_equal(g_probe_feof_hits, 1); +} + +/* + * BIO_CTRL_EOF: feof returning 0 on an invalid stream sets errno to + * EINVAL, which bss_file.c maps to -EINVAL (Windows only). + */ + +static void test_win_eof_invalid_stream(void **state) +{ + BIO *bio = *state; + + expect_feof(FAKE_FP, 0, EINVAL); + assert_int_equal(BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL), -EINVAL); +} + +static void test_win_eof_not_eof(void **state) +{ + BIO *bio = *state; + + expect_feof(FAKE_FP, 0, 0); + assert_int_equal(BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL), 0); +} + +static void test_win_eof_at_eof(void **state) +{ + /* any non-zero feof result is mapped to 1 by double negation */ + BIO *bio = *state; + + expect_feof(FAKE_FP, 7, 0); + assert_int_equal(BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL), 1); +} + +/* + * BIO_C_FILE_TELL: on Windows the non-uplink path refuses to ftell + * non-seekable files (GetFileType != FILE_TYPE_DISK), e.g. stdin. + */ + +static void test_win_tell_non_disk(void **state) +{ + BIO *bio = *state; + + expect_fileno(FAKE_FP, FAKE_FD); + expect_get_osfhandle(FAKE_FD, FAKE_OSFHANDLE); + expect_GetFileType(FAKE_OSFHANDLE, FILE_TYPE_PIPE); + assert_int_equal(BIO_ctrl(bio, BIO_C_FILE_TELL, 0, NULL), -1); +} + +static void test_win_tell_disk(void **state) +{ + BIO *bio = *state; + + expect_fileno(FAKE_FP, FAKE_FD); + expect_get_osfhandle(FAKE_FD, FAKE_OSFHANDLE); + expect_GetFileType(FAKE_OSFHANDLE, FILE_TYPE_DISK); + expect_ftell(FAKE_FP, 12345); + assert_int_equal(BIO_ctrl(bio, BIO_C_FILE_TELL, 0, NULL), 12345); +} + +/* BIO_C_SET_FILE_PTR: text/binary mode is applied with _setmode */ + +static void test_win_set_fp_text_mode(void **state) +{ + BIO *bio = *state; + + expect_set_fp_mode(FAKE_FP2, FAKE_FD, _O_TEXT); + BIO_set_fp(bio, FAKE_FP2, BIO_NOCLOSE | BIO_FP_TEXT); +} + +static void test_win_set_fp_binary_mode(void **state) +{ + BIO *bio = *state; + + expect_set_fp_mode(FAKE_FP2, FAKE_FD, _O_BINARY); + BIO_set_fp(bio, FAKE_FP2, BIO_NOCLOSE); +} + +/* + * BIO_C_SET_FILENAME: on Windows an explicit "b" or "t" is appended to + * the fopen mode. The filename and mode are checked in mock_wfopen, + * where openssl_fopen's UTF-8 conversion of plain ASCII input lands. + */ + +static void test_win_set_filename_appends_b(void **state) +{ + BIO *bio = *state; + + expect_wfopen(L"file.txt", L"rb", FAKE_FP2, 0); + assert_int_equal(BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_FP_READ, + (void *)"file.txt"), + 1); +} + +static void test_win_set_filename_appends_t(void **state) +{ + BIO *bio = *state; + + expect_wfopen(L"file.txt", L"rt", FAKE_FP2, 0); + assert_int_equal(BIO_ctrl(bio, BIO_C_SET_FILENAME, + BIO_FP_READ | BIO_FP_TEXT, (void *)"file.txt"), + 1); +} + +#if BIO_FLAGS_UPLINK_INTERNAL != 0 + +/* + * Uplink-only behaviour (requires an applink-enabled build; this test + * links ms/applink.c, so UP_* calls resolve to this executable's CRT). + */ + +static int setup_uplink(void **state) +{ + BIO *bio; + + mocks_arm(); + /* BIO_new_fp keeps the UPLINK flag, so UP_fsetmod is dispatched */ + expect_set_fp_mode(FAKE_FP, FAKE_FD, _O_BINARY); + bio = BIO_new_fp(FAKE_FP, BIO_NOCLOSE); + assert_non_null(bio); + assert_true(BIO_test_flags(bio, BIO_FLAGS_UPLINK_INTERNAL)); + *state = bio; + return 0; +} + +static void test_win_uplink_read(void **state) +{ + BIO *bio = *state; + char buf[8] = { 0 }; + + expect_fread(buf, 8, FAKE_FP, 8); + assert_int_equal(BIO_read(bio, buf, 8), 8); +} + +static void test_win_uplink_write(void **state) +{ + BIO *bio = *state; + const char buf[] = "hello"; + + expect_fwrite(buf, 5, FAKE_FP, 5); + assert_int_equal(BIO_write(bio, buf, 5), 5); +} + +static void test_win_uplink_free_closes(void **state) +{ + BIO *bio = *state; + + BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, BIO_CLOSE, NULL); + expect_fclose(FAKE_FP, 0); + BIO_free(bio); + *state = NULL; +} + +static void test_win_uplink_get_fp_visible(void **state) +{ + /* an application-owned FILE (UPLINK set) is returned to the app */ + BIO *bio = *state; + FILE *fp = NULL; + + assert_int_equal(BIO_get_fp(bio, &fp), 1); + assert_ptr_equal(fp, FAKE_FP); +} + +static void test_win_get_fp_internal_hidden(void **state) +{ + /* + * A FILE opened inside libcrypto (UPLINK cleared) belongs to the + * library CRT and must not be handed back to the application. + */ + BIO *bio = *state; + FILE *fp = FAKE_FP; + + assert_int_equal(BIO_get_fp(bio, &fp), 0); + assert_null(fp); +} + +#if defined(_MSC_VER) && _MSC_VER >= 1900 + +static void test_win_set_fp_stdio_clears_uplink(void **state) +{ + /* + * Safety net: passing one of the standard streams to BIO_set_fp + * clears the UPLINK flag, after which the mode is set with a plain + * _setmode call. + */ + BIO *bio = BIO_new(BIO_s_file()); + + (void)state; + assert_non_null(bio); + assert_true(BIO_test_flags(bio, BIO_FLAGS_UPLINK_INTERNAL)); + mocks_arm(); + expect_set_fp_mode(stdout, 1, _O_BINARY); + BIO_set_fp(bio, stdout, BIO_NOCLOSE); + mocks_disarm(); + assert_false(BIO_test_flags(bio, BIO_FLAGS_UPLINK_INTERNAL)); + BIO_free(bio); +} + +#endif /* _MSC_VER >= 1900 */ + +#endif /* BIO_FLAGS_UPLINK_INTERNAL != 0 */ + +/* main */ + +#define FILE_WIN(name) \ + cmocka_unit_test_setup_teardown(name, setup_internal, teardown) + +#if BIO_FLAGS_UPLINK_INTERNAL != 0 +#define FILE_WIN_UPLINK(name) \ + cmocka_unit_test_setup_teardown(name, setup_uplink, teardown) +#endif + +int main(void) +{ + const struct CMUnitTest tests[] = { + /* no fixture: the gate must not touch the CRT with a fake FILE */ + cmocka_unit_test(detour_probe), + FILE_WIN(test_win_eof_invalid_stream), + FILE_WIN(test_win_eof_not_eof), + FILE_WIN(test_win_eof_at_eof), + FILE_WIN(test_win_tell_non_disk), + FILE_WIN(test_win_tell_disk), + FILE_WIN(test_win_set_fp_text_mode), + FILE_WIN(test_win_set_fp_binary_mode), + FILE_WIN(test_win_set_filename_appends_b), + FILE_WIN(test_win_set_filename_appends_t), +#if BIO_FLAGS_UPLINK_INTERNAL != 0 + FILE_WIN_UPLINK(test_win_uplink_read), + FILE_WIN_UPLINK(test_win_uplink_write), + FILE_WIN_UPLINK(test_win_uplink_free_closes), + FILE_WIN_UPLINK(test_win_uplink_get_fp_visible), + FILE_WIN(test_win_get_fp_internal_hidden), +#if defined(_MSC_VER) && _MSC_VER >= 1900 + cmocka_unit_test(test_win_set_fp_stdio_clears_uplink), +#endif +#endif + }; + + cmocka_set_message_output(CM_OUTPUT_TAP); + return cmocka_run_group_tests(tests, group_setup, group_teardown); +} + +#endif diff --git a/test/v3ext.c b/test/v3ext.c index e2b64411977a3..aa55b367029f7 100644 --- a/test/v3ext.c +++ b/test/v3ext.c @@ -21,6 +21,98 @@ static const char *infile; +static const struct { + const char *single; /* Valid */ + const char *duplicate; /* Invalid */ +} duplicate_field_configs[] = { + { "[default]\nbasicConstraints=CA:true\n", + "[default]\nbasicConstraints=CA:true,CA:false\n" }, + { "[default]\nbasicConstraints=pathlen:0\n", + "[default]\nbasicConstraints=pathlen:0,pathlen:1\n" }, + { "[default]\nbasicAttConstraints=authority:true\n", + "[default]\nbasicAttConstraints=authority:true,authority:false\n" }, + { "[default]\nbasicAttConstraints=pathlen:0\n", + "[default]\nbasicAttConstraints=pathlen:0,pathlen:1\n" }, + { "[default]\npolicyConstraints=requireExplicitPolicy:0\n", + "[default]\npolicyConstraints=requireExplicitPolicy:0,requireExplicitPolicy:1\n" }, + { "[default]\npolicyConstraints=inhibitPolicyMapping:0\n", + "[default]\npolicyConstraints=inhibitPolicyMapping:0,inhibitPolicyMapping:1\n" }, +}; + +static int test_field_config(const char *config, int should_pass) +{ + size_t config_len = strlen(config); + BIO *in = NULL; + CONF *conf = NULL; + X509 *cert = NULL; + X509V3_CTX ctx; + int conf_res, ret = 0; + + if (!TEST_ptr(in = BIO_new(BIO_s_mem())) + || !TEST_int_eq(BIO_write(in, config, (int)config_len), + (int)config_len) + || !TEST_ptr(conf = NCONF_new(NULL)) + || !TEST_int_gt(NCONF_load_bio(conf, in, NULL), 0) + || !TEST_ptr(cert = X509_new())) + goto end; + + X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0); + X509V3_set_nconf(&ctx, conf); + + ERR_clear_error(); + conf_res = X509V3_EXT_add_nconf(conf, &ctx, "default", cert); + if (!TEST_int_eq(conf_res, should_pass) + || (!should_pass && !TEST_err_r(ERR_LIB_X509V3, X509V3_R_DUPLICATE_FIELD))) + goto end; + + ret = 1; +end: + X509_free(cert); + NCONF_free(conf); + BIO_free(in); + ERR_clear_error(); + return ret; +} + +static int test_duplicate_field(int idx) +{ + return test_field_config(duplicate_field_configs[idx].single, 1) + && test_field_config(duplicate_field_configs[idx].duplicate, 0); +} + +static int test_asn1_multi_mfail(void) +{ + static const char config[] = "[default]\n" + "1.2.3.4 = ASN1:SEQUENCE:items\n" + "[items]\n" + "value = INTEGER:1\n"; + size_t config_len = strlen(config); + BIO *in = NULL; + CONF *conf = NULL; + X509 *cert = NULL; + X509V3_CTX ctx; + int ret = 0; + + if (!TEST_ptr(in = BIO_new_mem_buf(config, (int)config_len)) + || !TEST_ptr(conf = NCONF_new(NULL)) + || !TEST_int_gt(NCONF_load_bio(conf, in, NULL), 0) + || !TEST_ptr(cert = X509_new())) + goto end; + + X509V3_set_ctx(&ctx, NULL, NULL, NULL, NULL, 0); + X509V3_set_nconf(&ctx, conf); + + MFAIL_start(); + ret = X509V3_EXT_add_nconf(conf, &ctx, "default", cert); + MFAIL_end(); + +end: + X509_free(cert); + NCONF_free(conf); + BIO_free(in); + return ret; +} + static int test_pathlen(void) { X509 *x = NULL; @@ -753,12 +845,11 @@ static int test_addr_interleaved_canonize(void) * Trigger an overlap-detection error partway through the linear * merge. The first V3EXT_TEST_LARGE_N / 2 entries are adjacent and * mergeable; entry K is a duplicate of entry K-1 (overlap). The - * canonize call must return 0, and the caller's normal teardown of - * the choice must safely free the stack -- some slots hold merged - * results, some hold NULL (from earlier merges), and some hold - * originals that the loop never reached. ASan / UBSan-instrumented - * builds will catch any double-free or use-after-free in the - * teardown that the mixed-state-on-error invariant claims to avoid. + * canonize call must return 0, and the resulting object must remain + * valid: the failed canonize must leave the stack partially + * canonicalized but hole-free, so that inspecting it, retrying + * canonize, and freeing it are all safe. ASan / UBSan-instrumented + * builds will catch any double-free or use-after-free in those walks. */ static int test_asid_canonize_error_midsweep(void) { @@ -801,9 +892,18 @@ static int test_asid_canonize_error_midsweep(void) goto err; /* - * Successful return below relies on ASIdentifiers_free walking - * the partially-compacted stack without UAF or double-free. - * Under ASan / UBSan that walk is the actual test. + * The object must also be safe to inspect and to retry, not only + * to free: both calls walk (and the second re-sorts) the stack, + * so they would crash on any NULL slot left by the mid-sweep merge. + */ + if (!TEST_int_eq(X509v3_asid_is_canonical(asid), 0) + || !TEST_int_eq(X509v3_asid_canonize(asid), 0)) + goto err; + + /* + * Successful return below relies on ASIdentifiers_free walking the + * partially-canonicalized, hole-free stack without UAF or + * double-free. Under ASan / UBSan that walk is the actual test. */ testresult = 1; err: @@ -817,13 +917,11 @@ static int test_asid_canonize_error_midsweep(void) * in IPAddressOrRanges_canonize. Construct a list whose first half is * adjacent and mergeable, with a duplicate at position k that hits the * overlap check after a series of merges has driven write < read. - * The canonize call must return 0, and the family's normal teardown - * (sk_IPAddressFamily_pop_free) must safely walk the partially - * compacted stack -- ASan / UBSan catches any double-free or UAF the - * mixed-state-on-error invariant would otherwise miss. Because the - * v3_addr.c canonize uses direct `return 0` rather than a `done:` - * cleanup label, the teardown invariant for this file is different - * from the asid path and warrants its own coverage. + * The canonize call must return 0, and the resulting object must + * remain valid: the failed canonize must leave the stack partially + * canonicalized but hole-free, so that inspecting it, retrying + * canonize, and freeing it are all safe. ASan / UBSan catches any + * double-free or UAF in those walks. */ static int test_addr_canonize_error_midsweep(void) { @@ -860,10 +958,20 @@ static int test_addr_canonize_error_midsweep(void) if (!TEST_int_eq(X509v3_addr_canonize(addr), 0)) goto end; + /* + * The object must also be safe to inspect and to retry, not only + * to free: both calls walk (and the second re-sorts) the stack, + * so they would crash on any NULL slot left by the mid-sweep merge. + */ + if (!TEST_int_eq(X509v3_addr_is_canonical(addr), 0) + || !TEST_int_eq(X509v3_addr_canonize(addr), 0)) + goto end; + /* * Successful return below relies on sk_IPAddressFamily_pop_free - * walking the partially-compacted aors stack without UAF or - * double-free. Under ASan / UBSan that walk is the actual test. + * walking the partially-canonicalized, hole-free aors stack + * without UAF or double-free. Under ASan / UBSan that walk is + * the actual test. */ testresult = 1; end: @@ -871,6 +979,102 @@ static int test_addr_canonize_error_midsweep(void) return testresult; } +/* + * Verify that an ASIdentifiers object remains safe to inspect and to + * retry after a canonize() call fails. The input [1, 2, 2] fails + * because 2 overlaps the merged [1, 2] range; the merge of 1 and 2 + * runs first, so the failure happens mid-sweep. canonize() must + * return 0 and leave the object in a state where is_canonical() and + * a second canonize() both run without crashing and return 0. + */ +static int test_asid_canonize_failure_then_inspect(void) +{ + ASIdentifiers *asid = NULL; + ASN1_INTEGER *val = NULL; + int testresult = 0; + + if (!TEST_ptr(asid = ASIdentifiers_new())) + goto err; + + if (!TEST_ptr(val = ASN1_INTEGER_new()) + || !TEST_true(ASN1_INTEGER_set_int64(val, 1)) + || !TEST_true(X509v3_asid_add_id_or_range(asid, V3_ASID_ASNUM, + val, NULL))) + goto err; + val = NULL; + if (!TEST_ptr(val = ASN1_INTEGER_new()) + || !TEST_true(ASN1_INTEGER_set_int64(val, 2)) + || !TEST_true(X509v3_asid_add_id_or_range(asid, V3_ASID_ASNUM, + val, NULL))) + goto err; + val = NULL; + if (!TEST_ptr(val = ASN1_INTEGER_new()) + || !TEST_true(ASN1_INTEGER_set_int64(val, 2)) + || !TEST_true(X509v3_asid_add_id_or_range(asid, V3_ASID_ASNUM, + val, NULL))) + goto err; + val = NULL; + + /* canonize must reject the overlap. */ + if (!TEST_int_eq(X509v3_asid_canonize(asid), 0)) + goto err; + + /* The object must be safe to inspect and to retry after the failure. */ + if (!TEST_int_eq(X509v3_asid_is_canonical(asid), 0)) + goto err; + if (!TEST_int_eq(X509v3_asid_canonize(asid), 0)) + goto err; + + testresult = 1; +err: + ASN1_INTEGER_free(val); + ASIdentifiers_free(asid); + return testresult; +} + +/* + * Verify that an IPAddrBlocks object remains safe to inspect and to + * retry after a canonize() call fails. The input + * [1.0.0.0/32, 1.0.0.1/32, 1.0.0.1/32] fails because the third + * prefix overlaps the merged range of the first two; that merge runs + * first, so the failure happens mid-sweep. canonize() must return 0 + * and leave the object in a state where is_canonical() and a second + * canonize() both run without crashing and return 0. + */ +static int test_addr_canonize_failure_then_inspect(void) +{ + IPAddrBlocks *addr = NULL; + unsigned char ip0[4] = { 1, 0, 0, 0 }; + unsigned char ip1[4] = { 1, 0, 0, 1 }; + int testresult = 0; + + if (!TEST_ptr(addr = sk_IPAddressFamily_new_null())) + goto end; + + if (!TEST_true(X509v3_addr_add_prefix(addr, IANA_AFI_IPV4, NULL, + ip0, 32)) + || !TEST_true(X509v3_addr_add_prefix(addr, IANA_AFI_IPV4, NULL, + ip1, 32)) + || !TEST_true(X509v3_addr_add_prefix(addr, IANA_AFI_IPV4, NULL, + ip1, 32))) + goto end; + + /* canonize must reject the overlap. */ + if (!TEST_int_eq(X509v3_addr_canonize(addr), 0)) + goto end; + + /* The object must be safe to inspect and to retry after the failure. */ + if (!TEST_int_eq(X509v3_addr_is_canonical(addr), 0)) + goto end; + if (!TEST_int_eq(X509v3_addr_canonize(addr), 0)) + goto end; + + testresult = 1; +end: + sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); + return testresult; +} + /* * Exercise the merge arm where `cur` is itself a range (rather than a * single integer), hitting the `case ASIdOrRange_range` detach branch @@ -943,9 +1147,10 @@ static int test_asid_range_merge_canonize(void) * well-formed adjacent integers; entry k is an explicitly inverted * range (min = 1000, max = 100). X509v3_asid_add_id_or_range does * not validate min <= max for ranges, so the bad entry is admitted - * into the list, and canonize must detect it on the sweep. The - * teardown under ASan / UBSan verifies that the early-exit path - * leaves the asIdsOrRanges stack in a freeable state. + * into the list, and canonize must detect it on the sweep. Like the + * overlap case, the failure happens after earlier merges have run, so + * canonize must return 0 and leave the object safe to inspect, retry, + * and free. * * The addr-side counterpart of this branch (v3_addr.c:849) is not * reachable through the public API: make_addressRange refuses to @@ -997,6 +1202,15 @@ static int test_asid_canonize_inverted_midsweep(void) if (!TEST_int_eq(X509v3_asid_canonize(asid), 0)) goto err; + /* + * The object must also be safe to inspect and to retry, not only + * to free: both calls walk (and the second re-sorts) the stack, + * so they would crash on any NULL slot left by the mid-sweep merge. + */ + if (!TEST_int_eq(X509v3_asid_is_canonical(asid), 0) + || !TEST_int_eq(X509v3_asid_canonize(asid), 0)) + goto err; + testresult = 1; err: ASN1_INTEGER_free(val); @@ -1048,6 +1262,70 @@ static int test_addr_subset(void) return ret; } +/* + * Regression test for IPAddrBlocks_new/free and d2i/i2d_IPAddrBlocks (issue #18528). + * Ensures empty and non-empty IPAddrBlocks round-trip correctly. + */ +static int test_ipaddrblocks_api(void) +{ + IPAddrBlocks *addr = NULL, *decoded = NULL; + ASN1_OCTET_STRING *ip1 = NULL, *ip2 = NULL; + unsigned char *der = NULL, *derp; + int len; + int ret = 0; + + /* Round-trip empty IPAddrBlocks */ + addr = IPAddrBlocks_new(); + if (!TEST_ptr(addr)) + goto end; + len = i2d_IPAddrBlocks(addr, &der); + if (!TEST_int_ge(len, 0) || !TEST_ptr(der)) + goto end; + derp = der; + decoded = d2i_IPAddrBlocks(NULL, (const unsigned char **)&derp, len); + if (!TEST_ptr(decoded) || !TEST_int_eq(sk_IPAddressFamily_num(decoded), 0)) + goto end; + IPAddrBlocks_free(addr); + IPAddrBlocks_free(decoded); + OPENSSL_free(der); + addr = decoded = NULL; + der = NULL; + + /* Round-trip non-empty IPAddrBlocks and verify structure */ + addr = IPAddrBlocks_new(); + if (!TEST_ptr(addr)) + goto end; + if (!TEST_true(X509v3_addr_canonize(addr))) + goto end; + ip1 = a2i_IPADDRESS(ranges[0].ip1); + ip2 = a2i_IPADDRESS(ranges[0].ip2); + if (!TEST_ptr(ip1) || !TEST_ptr(ip2)) + goto end; + if (!TEST_true(X509v3_addr_add_range(addr, ranges[0].afi, NULL, ip1->data, ip2->data))) + goto end; + if (!TEST_true(X509v3_addr_is_canonical(addr))) + goto end; + + len = i2d_IPAddrBlocks(addr, &der); + if (!TEST_int_ge(len, 0) || !TEST_ptr(der)) + goto end; + derp = der; + decoded = d2i_IPAddrBlocks(NULL, (const unsigned char **)&derp, len); + if (!TEST_ptr(decoded)) + goto end; + if (!check_addr(decoded, ranges[0].rorp)) + goto end; + + ret = 1; +end: + IPAddrBlocks_free(addr); + IPAddrBlocks_free(decoded); + OPENSSL_free(der); + ASN1_OCTET_STRING_free(ip1); + ASN1_OCTET_STRING_free(ip2); + return ret; +} + #endif /* OPENSSL_NO_RFC3779 */ OPT_TEST_DECLARE_USAGE("cert.pem\n") @@ -1063,6 +1341,8 @@ int setup_tests(void) return 0; ADD_TEST(test_pathlen); + ADD_ALL_TESTS(test_duplicate_field, OSSL_NELEM(duplicate_field_configs)); + ADD_MFAIL_TEST(test_asn1_multi_mfail); #ifndef OPENSSL_NO_RFC3779 ADD_TEST(test_asid); ADD_TEST(test_addr_ranges); @@ -1076,8 +1356,11 @@ int setup_tests(void) ADD_TEST(test_addr_interleaved_canonize); ADD_TEST(test_asid_canonize_error_midsweep); ADD_TEST(test_addr_canonize_error_midsweep); + ADD_TEST(test_asid_canonize_failure_then_inspect); + ADD_TEST(test_addr_canonize_failure_then_inspect); ADD_TEST(test_asid_range_merge_canonize); ADD_TEST(test_asid_canonize_inverted_midsweep); + ADD_TEST(test_ipaddrblocks_api); #endif /* OPENSSL_NO_RFC3779 */ return 1; } diff --git a/test/v3nametest.c b/test/v3nametest.c index 8ae7a9e54f339..20029aa163562 100644 --- a/test/v3nametest.c +++ b/test/v3nametest.c @@ -1,5 +1,5 @@ /* - * Copyright 2012-2025 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2012-2026 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -149,7 +149,7 @@ static int set_altname(X509 *crt, ...) ia5 = ASN1_IA5STRING_new(); if (ia5 == NULL) goto out; - if (!ASN1_STRING_set(ia5, name, -1)) + if (!ASN1_STRING_set1_string(ia5, name)) goto out; switch (type) { case GEN_EMAIL: @@ -180,55 +180,29 @@ static int set_cn1(X509 *crt, const char *name) return set_cn(crt, NID_commonName, name, 0); } -static int set_cn_and_email(X509 *crt, const char *name) -{ - return set_cn(crt, NID_commonName, name, - NID_pkcs9_emailAddress, "dummy@example.com", 0); -} - -static int set_cn2(X509 *crt, const char *name) -{ - return set_cn(crt, NID_commonName, "dummy value", - NID_commonName, name, 0); -} - -static int set_cn3(X509 *crt, const char *name) -{ - return set_cn(crt, NID_commonName, name, - NID_commonName, "dummy value", 0); -} - static int set_email1(X509 *crt, const char *name) { return set_cn(crt, NID_pkcs9_emailAddress, name, 0); } -static int set_email2(X509 *crt, const char *name) -{ - return set_cn(crt, NID_pkcs9_emailAddress, "dummy@example.com", - NID_pkcs9_emailAddress, name, 0); -} - -static int set_email3(X509 *crt, const char *name) +static int set_altname_dns(X509 *crt, const char *name) { - return set_cn(crt, NID_pkcs9_emailAddress, name, - NID_pkcs9_emailAddress, "dummy@example.com", 0); + return set_altname(crt, GEN_DNS, name, 0); } -static int set_email_and_cn(X509 *crt, const char *name) +static int set_altname_dns2(X509 *crt, const char *name) { - return set_cn(crt, NID_pkcs9_emailAddress, name, - NID_commonName, "www.example.org", 0); + return set_altname(crt, GEN_DNS, "dummy.example.org", GEN_DNS, name, 0); } -static int set_altname_dns(X509 *crt, const char *name) +static int set_altname_email(X509 *crt, const char *name) { - return set_altname(crt, GEN_DNS, name, 0); + return set_altname(crt, GEN_EMAIL, name, 0); } -static int set_altname_email(X509 *crt, const char *name) +static int set_altname_email2(X509 *crt, const char *name) { - return set_altname(crt, GEN_EMAIL, name, 0); + return set_altname(crt, GEN_EMAIL, "dummy@example.com", GEN_EMAIL, name, 0); } OSSL_END_ALLOW_DEPRECATED #endif /* !defined(OPENSSL_NO_DEPRECATED_4_1) */ @@ -238,21 +212,18 @@ struct set_name_fn { const char *name; int host; int email; + int subject; /* name is in the subject DN, so needs ALWAYS_CHECK_SUBJECT */ }; #if !defined(OPENSSL_NO_DEPRECATED_4_1) OSSL_BEGIN_ALLOW_DEPRECATED static const struct set_name_fn name_fns[] = { - { set_cn1, "set CN", 1, 0 }, - { set_cn2, "set CN", 1, 0 }, - { set_cn3, "set CN", 1, 0 }, - { set_cn_and_email, "set CN", 1, 0 }, - { set_email1, "set emailAddress", 0, 1 }, - { set_email2, "set emailAddress", 0, 1 }, - { set_email3, "set emailAddress", 0, 1 }, - { set_email_and_cn, "set emailAddress", 0, 1 }, - { set_altname_dns, "set dnsName", 1, 0 }, - { set_altname_email, "set rfc822Name", 0, 1 }, + { set_cn1, "set CN", 1, 0, 1 }, + { set_email1, "set emailAddress", 0, 1, 1 }, + { set_altname_dns, "set dnsName", 1, 0, 0 }, + { set_altname_dns2, "set dnsName", 1, 0, 0 }, + { set_altname_email, "set rfc822Name", 0, 1, 0 }, + { set_altname_email2, "set rfc822Name", 0, 1, 0 }, }; static X509 *make_cert(void) @@ -275,7 +246,7 @@ static int check_message(const struct set_name_fn *fn, const char *op, if (match < 0) return 1; - BIO_snprintf(msg, sizeof(msg), "%s: %s: [%s] %s [%s]", + snprintf(msg, sizeof(msg), "%s: %s: [%s] %s [%s]", fn->name, op, nameincert, match ? "matches" : "does not match", name); if (is_exception(msg)) @@ -289,6 +260,7 @@ static int run_cert(X509 *crt, const char *nameincert, { const char *const *pname = names; int failed = 0; + unsigned int subj = fn->subject ? X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT : 0; for (; *pname != NULL; ++pname) { int samename = OPENSSL_strcasecmp(nameincert, *pname) == 0; @@ -301,7 +273,7 @@ static int run_cert(X509 *crt, const char *nameincert, memcpy(name, *pname, namelen + 1); match = -1; - if (!TEST_int_ge(ret = X509_check_host(crt, name, namelen, 0, NULL), + if (!TEST_int_ge(ret = X509_check_host(crt, name, namelen, subj, NULL), 0)) { failed = 1; } else if (fn->host) { @@ -316,7 +288,7 @@ static int run_cert(X509 *crt, const char *nameincert, match = -1; if (!TEST_int_ge(ret = X509_check_host(crt, name, namelen, - X509_CHECK_FLAG_NO_WILDCARDS, + X509_CHECK_FLAG_NO_WILDCARDS | subj, NULL), 0)) { failed = 1; @@ -332,7 +304,7 @@ static int run_cert(X509 *crt, const char *nameincert, failed = 1; match = -1; - ret = X509_check_email(crt, name, namelen, 0); + ret = X509_check_email(crt, name, namelen, subj); if (fn->email) { if (ret && !samename) match = 1; @@ -365,6 +337,141 @@ static int call_run_cert(int i) } return failed == 0; } + +/* + * name64 is a well-formed dNSName exactly 64 bytes long; name68 is the same + * 64 bytes followed by a further label, so it too is a well-formed dNSName + * but 68 bytes long. The 64-byte prefix of name68 is thus a valid, distinct + * name -- a check that only compared the first 64 bytes would wrongly treat + * the two as equal. + */ +static const char name64[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com"; +static const char name68[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com.net"; + +static int test_long_names(void) +{ + X509 *crt = NULL; + int failed = 0; + + /* + * A dNSName may exceed 64 bytes. Each name matches itself but not the + * other: the 64-byte name must not match the 68-byte certificate, nor + * vice versa (no truncation to 64 bytes). + */ + if (!TEST_ptr(crt = make_cert()) + || !TEST_true(set_altname_dns(crt, name68)) + || !TEST_int_eq(X509_check_host(crt, name68, 0, 0, NULL), 1) + || !TEST_int_eq(X509_check_host(crt, name64, 0, 0, NULL), 0)) + failed = 1; + X509_free(crt); + crt = NULL; + + if (!TEST_ptr(crt = make_cert()) + || !TEST_true(set_altname_dns(crt, name64)) + || !TEST_int_eq(X509_check_host(crt, name64, 0, 0, NULL), 1) + || !TEST_int_eq(X509_check_host(crt, name68, 0, 0, NULL), 0)) + failed = 1; + X509_free(crt); + crt = NULL; + + /* + * The 64-byte name can be a commonName and is matched when subject + * checking is requested; the 68-byte name, which shares its first 64 + * bytes, must not match it. + */ + if (!TEST_ptr(crt = make_cert()) + || !TEST_true(set_cn1(crt, name64)) + || !TEST_int_eq(X509_check_host(crt, name64, 0, + X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT, NULL), + 1) + || !TEST_int_eq(X509_check_host(crt, name68, 0, + X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT, NULL), + 0)) + failed = 1; + X509_free(crt); + + return failed == 0; +} + +/* + * The subject commonName / emailAddress is consulted during verification + * only when X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT is set, and never when + * X509_CHECK_FLAG_NEVER_CHECK_SUBJECT is set -- whether or not a subject + * alternative name of the corresponding type is present. In particular the + * default, flags == 0, matches neither, even when the certificate has no + * subject alternative name at all. + */ +static int test_check_subject_flags(void) +{ + X509 *crt = NULL; + int failed = 0; + + /* Subject commonName, no SAN. */ + if (!TEST_ptr(crt = make_cert()) + || !TEST_true(set_cn1(crt, "example.com")) + || !TEST_int_eq(X509_check_host(crt, "example.com", 0, 0, NULL), 0) + || !TEST_int_eq(X509_check_host(crt, "example.com", 0, + X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT, NULL), + 1) + || !TEST_int_eq(X509_check_host(crt, "example.com", 0, + X509_CHECK_FLAG_NEVER_CHECK_SUBJECT, NULL), + 0)) + failed = 1; + X509_free(crt); + crt = NULL; + + /* + * A non-matching dNSName SAN alongside a matching commonName: the SAN + * matches its own name, the requested name does not match the SAN, and + * the commonName is consulted only under ALWAYS_CHECK_SUBJECT -- never + * by default, despite a SAN being present. + */ + if (!TEST_ptr(crt = make_cert()) + || !TEST_true(set_cn1(crt, "example.com")) + || !TEST_true(set_altname_dns(crt, "san.example.net")) + || !TEST_int_eq(X509_check_host(crt, "san.example.net", 0, 0, NULL), 1) + || !TEST_int_eq(X509_check_host(crt, "example.com", 0, 0, NULL), 0) + || !TEST_int_eq(X509_check_host(crt, "example.com", 0, + X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT, NULL), + 1) + || !TEST_int_eq(X509_check_host(crt, "example.com", 0, + X509_CHECK_FLAG_NEVER_CHECK_SUBJECT, NULL), + 0)) + failed = 1; + X509_free(crt); + crt = NULL; + + /* Subject emailAddress, no SAN. */ + if (!TEST_ptr(crt = make_cert()) + || !TEST_true(set_email1(crt, "user@example.com")) + || !TEST_int_eq(X509_check_email(crt, "user@example.com", 0, 0), 0) + || !TEST_int_eq(X509_check_email(crt, "user@example.com", 0, + X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT), + 1) + || !TEST_int_eq(X509_check_email(crt, "user@example.com", 0, + X509_CHECK_FLAG_NEVER_CHECK_SUBJECT), + 0)) + failed = 1; + X509_free(crt); + crt = NULL; + + /* A non-matching rfc822Name SAN alongside a matching subject emailAddress. */ + if (!TEST_ptr(crt = make_cert()) + || !TEST_true(set_email1(crt, "user@example.com")) + || !TEST_true(set_altname_email(crt, "san@example.net")) + || !TEST_int_eq(X509_check_email(crt, "san@example.net", 0, 0), 1) + || !TEST_int_eq(X509_check_email(crt, "user@example.com", 0, 0), 0) + || !TEST_int_eq(X509_check_email(crt, "user@example.com", 0, + X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT), + 1) + || !TEST_int_eq(X509_check_email(crt, "user@example.com", 0, + X509_CHECK_FLAG_NEVER_CHECK_SUBJECT), + 0)) + failed = 1; + X509_free(crt); + + return failed == 0; +} OSSL_END_ALLOW_DEPRECATED #endif /* !defined(OPENSSL_NO_DEPRECATED_4_1) */ @@ -668,6 +775,8 @@ int setup_tests(void) { #if !defined(OPENSSL_NO_DEPRECATED_4_1) ADD_ALL_TESTS(call_run_cert, OSSL_NELEM(name_fns)); + ADD_TEST(test_long_names); + ADD_TEST(test_check_subject_flags); #endif /* !defined(OPENSSL_NO_DEPRECATED_4_1) */ ADD_TEST(test_GENERAL_NAME_cmp); return 1; diff --git a/test/x509_internal_test.c b/test/x509_internal_test.c index 19a7c2469d210..b8c613a493e95 100644 --- a/test/x509_internal_test.c +++ b/test/x509_internal_test.c @@ -16,8 +16,11 @@ #include #include #include "testutil.h" +#include "internal/cryptlib.h" #include "internal/nelem.h" #include "crypto/x509.h" +#include "crypto/evp.h" +#include "../crypto/asn1/asn1_local.h" /********************************************************************** * @@ -152,7 +155,7 @@ static int test_a2i_ipaddress(int idx) { int good = 1; ASN1_OCTET_STRING *ip; - int len = a2i_ipaddress_tests[idx].length; + size_t len = a2i_ipaddress_tests[idx].length; ip = a2i_IPADDRESS(a2i_ipaddress_tests[idx].ipasc); if (len == 0) { @@ -162,7 +165,7 @@ static int test_a2i_ipaddress(int idx) } } else { if (!TEST_ptr(ip) - || !TEST_int_eq(ASN1_STRING_length(ip), len) + || !TEST_size_t_eq(ASN1_STRING_get_length(ip), len) || !TEST_mem_eq(ASN1_STRING_get0_data(ip), len, a2i_ipaddress_tests[idx].data, len)) { good = 0; @@ -172,6 +175,172 @@ static int test_a2i_ipaddress(int idx) return good; } +/** + * @struct ip_asc_testdata_st + * @brief One ossl_ipaddr_to_asc() case: input bytes and expected output. + */ +typedef struct ip_asc_testdata_st { + const char *data; /**< The address bytes to convert */ + int length; /**< The number of bytes at data */ + const char *expected; /**< The string the conversion should produce */ +} IP_ASC_TESTDATA; + +/*- + * ossl_ipaddr_to_asc() is not the inverse of a2i_IPADDRESS(): it neither + * elides a run of zero groups as "::" nor emits lowercase hex, so the + * expected strings below are not the RFC 5952 canonical presentation + * forms of these addresses. + */ +static IP_ASC_TESTDATA ipaddr_to_asc_tests[] = { + { "\x7f\x00\x00\x01", 4, "127.0.0.1" }, + { "\x01\x02\x03\x04", 4, "1.2.3.4" }, + { "\xff\xff\xff\xff", 4, "255.255.255.255" }, + + { "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16, + "0:0:0:0:0:0:0:0" }, + { "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", 16, + "0:0:0:0:0:0:0:1" }, + { "\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\xff\x00\x00\x42\x83\x29", 16, + "2001:DB8:0:0:0:FF00:42:8329" }, + + /* + * The longest output ossl_ipaddr_to_asc() can produce: 39 characters + * and a nul exactly fill its 40-byte buffer, so the last group is + * written with no room to spare. A truncation guard that is off by + * one drops that group. + */ + { "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff", 16, + "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF" }, + + /* Only 4 and 16 are addresses; every other length is reported back. */ + { "", 0, "" }, + { "\x01\x02\x03", 3, "" }, + { "\x01\x02\x03\x04\x05", 5, "" }, +}; + +/** + * @brief Check ossl_ipaddr_to_asc() against one ipaddr_to_asc_tests entry. + * @param idx index into ipaddr_to_asc_tests of the case to run + * @returns 1 if the conversion produced the expected string, 0 otherwise + */ +static int test_ipaddr_to_asc(int idx) +{ + const IP_ASC_TESTDATA *t = &ipaddr_to_asc_tests[idx]; + char *asc = ossl_ipaddr_to_asc((const unsigned char *)t->data, t->length); + int good = TEST_ptr(asc) && TEST_str_eq(asc, t->expected); + + OPENSSL_free(asc); + return good; +} + +/* Adding an extension to a CRL marks its cached encoding stale */ +static int test_crl_add_ext_modifies(void) +{ + EVP_PKEY *pkey = NULL; + X509_NAME *name = NULL; + X509_CRL *crl = NULL, *copy = NULL; + ASN1_TIME *tm = NULL; + ASN1_INTEGER *num = NULL; + X509_EXTENSION *ext = NULL; + int ret = 0; + + if (!TEST_ptr(pkey = EVP_PKEY_Q_keygen(NULL, NULL, "RSA", (size_t)2048)) + || !TEST_ptr(name = X509_NAME_new()) + || !TEST_true(X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, + (const unsigned char *)"crl ext test", -1, -1, 0)) + || !TEST_ptr(tm = ASN1_TIME_set(NULL, 0)) + || !TEST_ptr(num = ASN1_INTEGER_new()) + || !TEST_true(ASN1_INTEGER_set(num, 1)) + || !TEST_ptr(crl = X509_CRL_new()) + || !TEST_true(X509_CRL_set_issuer_name(crl, name)) + || !TEST_true(X509_CRL_set1_lastUpdate(crl, tm)) + || !TEST_int_gt(X509_CRL_sign(crl, pkey, EVP_sha256()), 0)) + goto err; + + /* X509_CRL_add1_ext_i2d() on a decoded copy */ + if (!TEST_ptr(copy = X509_CRL_dup(crl)) + || !TEST_false(copy->crl.enc.modified) + || !TEST_true(X509_CRL_add1_ext_i2d(copy, NID_crl_number, num, 0, 0)) + || !TEST_true(copy->crl.enc.modified)) + goto err; + X509_CRL_free(copy); + copy = NULL; + + /* X509_CRL_add_ext() on a decoded copy */ + if (!TEST_ptr(ext = X509V3_EXT_i2d(NID_crl_number, 0, num)) + || !TEST_ptr(copy = X509_CRL_dup(crl)) + || !TEST_false(copy->crl.enc.modified) + || !TEST_true(X509_CRL_add_ext(copy, ext, -1)) + || !TEST_true(copy->crl.enc.modified)) + goto err; + + ret = 1; +err: + X509_EXTENSION_free(ext); + X509_CRL_free(copy); + X509_CRL_free(crl); + ASN1_INTEGER_free(num); + ASN1_TIME_free(tm); + X509_NAME_free(name); + EVP_PKEY_free(pkey); + return ret; +} + +/* + * A failed encoding save discards the cached encoding, and the item is + * encoded from its fields afterwards. + */ +static int test_enc_save_failure(void) +{ + EVP_PKEY *pkey = NULL; + X509_NAME *name = NULL; + X509_CRL *crl = NULL, *copy = NULL; + X509_CRL_INFO *info = NULL; + ASN1_TIME *tm = NULL; + unsigned char *der = NULL, *der_copy = NULL; + unsigned char buf[1] = { 0 }; + int len, len_copy, ret = 0; + + if (!TEST_ptr(pkey = EVP_PKEY_Q_keygen(NULL, NULL, "RSA", (size_t)2048)) + || !TEST_ptr(name = X509_NAME_new()) + || !TEST_true(X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, + (const unsigned char *)"enc save test", -1, -1, 0)) + || !TEST_ptr(tm = ASN1_TIME_set(NULL, 0)) + || !TEST_ptr(crl = X509_CRL_new()) + || !TEST_true(X509_CRL_set_issuer_name(crl, name)) + || !TEST_true(X509_CRL_set1_lastUpdate(crl, tm)) + || !TEST_int_gt(X509_CRL_sign(crl, pkey, EVP_sha256()), 0) + || !TEST_ptr(copy = X509_CRL_dup(crl)) + || !TEST_false(copy->crl.enc.modified) + || !TEST_ptr(copy->crl.enc.enc)) + goto err; + + /* A zero input length is a failure */ + info = ©->crl; + if (!TEST_false(ossl_asn1_enc_save((ASN1_VALUE **)&info, buf, 0, + ASN1_ITEM_rptr(X509_CRL_INFO))) + || !TEST_ptr_null(copy->crl.enc.enc) + || !TEST_int_eq(copy->crl.enc.len, 0) + || !TEST_true(copy->crl.enc.modified)) + goto err; + + if (!TEST_int_gt(len = i2d_X509_CRL(crl, &der), 0) + || !TEST_int_gt(len_copy = i2d_X509_CRL(copy, &der_copy), 0) + || !TEST_mem_eq(der, (size_t)len, der_copy, (size_t)len_copy)) + goto err; + + ret = 1; +err: + OPENSSL_free(der_copy); + OPENSSL_free(der); + X509_CRL_free(copy); + X509_CRL_free(crl); + ASN1_TIME_free(tm); + X509_NAME_free(name); + EVP_PKEY_free(pkey); + return ret; +} + static int ck_purp(ossl_unused const X509_PURPOSE *purpose, ossl_unused const X509 *x, int ca) { @@ -688,6 +857,142 @@ static int tests_x509_check_akid(void) return test; } +static int test_X509_ALGOR_set_md_null(void) +{ + X509_ALGOR *alg = NULL; + int ret = 0; + + if (!TEST_ptr(alg = X509_ALGOR_new())) + goto err; + + if (!TEST_false(X509_ALGOR_set_md(alg, NULL))) + goto err; + + ret = 1; + +err: + X509_ALGOR_free(alg); + return ret; +} + +/********************************************************************** + * + * Tests for X509_ALGOR_set_md null pointer fix + * (see crypto/asn1/x_algor.c) + * + ***/ + +static int test_X509_ALGOR_set_md_sha1(void) +{ + X509_ALGOR *alg = NULL; + const ASN1_OBJECT *aobj = NULL; + int ptype = V_ASN1_EOC; + int ret = 0; + + if (!TEST_ptr(alg = X509_ALGOR_new())) + goto err; + /* SHA-1 has EVP_MD_FLAG_DIGALGID_ABSENT, so parameter type is V_ASN1_UNDEF */ + if (!TEST_true(X509_ALGOR_set_md(alg, EVP_sha1()))) + goto err; + X509_ALGOR_get0(&aobj, &ptype, NULL, alg); + if (!TEST_int_eq(OBJ_obj2nid(aobj), NID_sha1)) + goto err; + if (!TEST_int_eq(ptype, V_ASN1_UNDEF)) + goto err; + ret = 1; +err: + X509_ALGOR_free(alg); + return ret; +} + +#ifndef OPENSSL_NO_MD5 +static int test_X509_ALGOR_set_md_md5(void) +{ + X509_ALGOR *alg = NULL; + const ASN1_OBJECT *aobj = NULL; + int ptype = V_ASN1_EOC; + int ret = 0; + + if (!TEST_ptr(alg = X509_ALGOR_new())) + goto err; + /* MD5 does not have EVP_MD_FLAG_DIGALGID_ABSENT, so parameter type is V_ASN1_NULL */ + if (!TEST_true(X509_ALGOR_set_md(alg, EVP_md5()))) + goto err; + X509_ALGOR_get0(&aobj, &ptype, NULL, alg); + if (!TEST_int_eq(OBJ_obj2nid(aobj), NID_md5)) + goto err; + if (!TEST_int_eq(ptype, V_ASN1_NULL)) + goto err; + ret = 1; +err: + X509_ALGOR_free(alg); + return ret; +} +#endif /* OPENSSL_NO_MD5 */ + +/* + * An EVP_MD with NID_undef type but a name that OBJ_txt2obj() can resolve. + * This exercises the OBJ_txt2obj() branch in X509_ALGOR_set_md. + */ +static const EVP_MD custom_md_known_oid = { + .type = NID_undef, + .pkey_type = NID_undef, + .type_name = "SHA256", /* OBJ_txt2obj() resolves this via OBJ_sn2nid() */ +}; + +static int test_X509_ALGOR_set_md_nid_undef_known_name(void) +{ + X509_ALGOR *alg = NULL; + const ASN1_OBJECT *aobj = NULL; + int ret = 0; + + if (!TEST_ptr(alg = X509_ALGOR_new())) + goto err; + /* + * NID_undef forces the OBJ_txt2obj() path; name "SHA256" resolves + * to the SHA-256 OID so the call must succeed and set the algorithm. + */ + if (!TEST_true(X509_ALGOR_set_md(alg, &custom_md_known_oid))) + goto err; + X509_ALGOR_get0(&aobj, NULL, NULL, alg); + if (!TEST_int_eq(OBJ_obj2nid(aobj), NID_sha256)) + goto err; + ret = 1; +err: + X509_ALGOR_free(alg); + return ret; +} + +/* + * An EVP_MD with NID_undef type and a name that OBJ_txt2obj() cannot resolve. + * Before the null-pointer fix, X509_ALGOR_set0 was called with a NULL obj, + * causing undefined behaviour. After the fix, X509_ALGOR_set_md returns 0. + */ +static const EVP_MD custom_md_unknown_oid = { + .type = NID_undef, + .pkey_type = NID_undef, + .type_name = "not-a-known-oid-name", +}; + +static int test_X509_ALGOR_set_md_null_obj(void) +{ + X509_ALGOR *alg = NULL; + int ret = 0; + + if (!TEST_ptr(alg = X509_ALGOR_new())) + goto err; + /* + * OBJ_txt2obj("not-a-known-oid-name", 0) returns NULL, so + * X509_ALGOR_set_md must return 0 rather than crash. + */ + if (!TEST_false(X509_ALGOR_set_md(alg, &custom_md_unknown_oid))) + goto err; + ret = 1; +err: + X509_ALGOR_free(alg); + return ret; +} + /* https://github.com/openssl/openssl/issues/26325 */ static const char *kRootExtensionDuplicity[] = { "-----BEGIN CERTIFICATE-----\n", @@ -939,18 +1244,208 @@ static int tests_x509_check_ext_duplicity_nid_dynamic(void) return test; } +/* + * X509_ATTRIBUTE_create_by_NID() must accept a BIT STRING value supplied as + * raw bytes plus an explicit length, as PKCS8_add_keyusage() does for + * 'openssl pkcs12 -export -keyex' (0x10) and '-keysig' (0x80). + * Regression test for https://github.com/openssl/openssl/issues/32234 + */ +static int test_x509_attribute_bit_string(int idx) +{ + unsigned char usage = idx == 0 ? 0x10 : 0x80; + X509_ATTRIBUTE *attr = NULL; + const ASN1_BIT_STRING *bs; + size_t length = 0; + int unused_bits = -1, ret = 0; + + if (!TEST_ptr(attr = X509_ATTRIBUTE_create_by_NID(NULL, NID_key_usage, + V_ASN1_BIT_STRING, &usage, 1)) + || !TEST_ptr(bs = X509_ATTRIBUTE_get0_data(attr, 0, V_ASN1_BIT_STRING, + NULL)) + || !TEST_true(ASN1_BIT_STRING_get_length(bs, &length, &unused_bits)) + || !TEST_size_t_eq(length, 1) + || !TEST_int_eq(unused_bits, 0) + || !TEST_mem_eq(ASN1_STRING_get0_data(bs), 1, &usage, 1)) + goto err; + ret = 1; +err: + X509_ATTRIBUTE_free(attr); + return ret; +} + +/* + * Signing leaves the cached encoding of the signed part current and equal + * to the decoded one; modifying the object afterwards marks it stale. + */ +static int test_sign_caches_encoding(void) +{ + EVP_PKEY *pkey = NULL; + X509_NAME *name = NULL; + X509 *cert = NULL, *cert_copy = NULL; + X509_CRL *crl = NULL, *crl_copy = NULL; + X509_REQ *req = NULL, *req_copy = NULL; + int ret = 0; + + if (!TEST_ptr(pkey = EVP_PKEY_Q_keygen(NULL, NULL, "RSA", (size_t)2048)) + || !TEST_ptr(name = X509_NAME_new()) + || !TEST_true(X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, + (const unsigned char *)"sign test", -1, -1, 0))) + goto err; + + /* Certificate */ + if (!TEST_ptr(cert = X509_new()) + || !TEST_true(cert->cert_info.enc.modified) + || !TEST_true(X509_set_subject_name(cert, name)) + || !TEST_true(X509_set_issuer_name(cert, name)) + || !TEST_ptr(X509_gmtime_adj(X509_getm_notBefore(cert), 0)) + || !TEST_ptr(X509_gmtime_adj(X509_getm_notAfter(cert), 3600)) + || !TEST_true(X509_set_pubkey(cert, pkey)) + || !TEST_int_gt(X509_sign(cert, pkey, EVP_sha256()), 0) + || !TEST_false(cert->cert_info.enc.modified) + || !TEST_ptr(cert_copy = X509_dup(cert)) + || !TEST_false(cert_copy->cert_info.enc.modified) + || !TEST_mem_eq(cert->cert_info.enc.enc, + (size_t)cert->cert_info.enc.len, + cert_copy->cert_info.enc.enc, + (size_t)cert_copy->cert_info.enc.len) + || !TEST_int_eq(X509_cmp(cert, cert_copy), 0) + || !TEST_true(X509_set_version(cert, X509_VERSION_2)) + || !TEST_true(cert->cert_info.enc.modified) + || !TEST_int_gt(X509_sign(cert, pkey, EVP_sha256()), 0) + || !TEST_false(cert->cert_info.enc.modified) + || !TEST_int_ne(X509_cmp(cert, cert_copy), 0)) + goto err; + + /* CRL */ + if (!TEST_ptr(crl = X509_CRL_new()) + || !TEST_true(crl->crl.enc.modified) + || !TEST_true(X509_CRL_set_issuer_name(crl, name)) + || !TEST_true(X509_CRL_set1_lastUpdate(crl, X509_getm_notBefore(cert))) + || !TEST_int_gt(X509_CRL_sign(crl, pkey, EVP_sha256()), 0) + || !TEST_false(crl->crl.enc.modified) + || !TEST_ptr(crl_copy = X509_CRL_dup(crl)) + || !TEST_false(crl_copy->crl.enc.modified) + || !TEST_mem_eq(crl->crl.enc.enc, (size_t)crl->crl.enc.len, + crl_copy->crl.enc.enc, (size_t)crl_copy->crl.enc.len)) + goto err; + + /* Request */ + if (!TEST_ptr(req = X509_REQ_new()) + || !TEST_true(req->req_info.enc.modified) + || !TEST_true(X509_REQ_set_subject_name(req, name)) + || !TEST_true(X509_REQ_set_pubkey(req, pkey)) + || !TEST_int_gt(X509_REQ_sign(req, pkey, EVP_sha256()), 0) + || !TEST_false(req->req_info.enc.modified) + || !TEST_ptr(req_copy = X509_REQ_dup(req)) + || !TEST_false(req_copy->req_info.enc.modified) + || !TEST_mem_eq(req->req_info.enc.enc, (size_t)req->req_info.enc.len, + req_copy->req_info.enc.enc, (size_t)req_copy->req_info.enc.len)) + goto err; + + ret = 1; +err: + X509_REQ_free(req_copy); + X509_REQ_free(req); + X509_CRL_free(crl_copy); + X509_CRL_free(crl); + X509_free(cert_copy); + X509_free(cert); + X509_NAME_free(name); + EVP_PKEY_free(pkey); + return ret; +} + +/* A modified, unsigned certificate or CRL is equal only to itself */ +static int test_cmp_modified(void) +{ + EVP_PKEY *pkey = NULL; + X509_NAME *name = NULL; + X509 *cert = NULL, *copy = NULL; + X509_CRL *crl = NULL, *crl_copy = NULL; + ASN1_INTEGER *serial = NULL; + int ret = 0; + + if (!TEST_ptr(pkey = EVP_PKEY_Q_keygen(NULL, NULL, "RSA", (size_t)2048)) + || !TEST_ptr(name = X509_NAME_new()) + || !TEST_true(X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, + (const unsigned char *)"cmp test", -1, -1, 0)) + || !TEST_ptr(serial = ASN1_INTEGER_new()) + || !TEST_true(ASN1_INTEGER_set(serial, 2))) + goto err; + + if (!TEST_ptr(cert = X509_new()) + || !TEST_true(X509_set_subject_name(cert, name)) + || !TEST_true(X509_set_issuer_name(cert, name)) + || !TEST_ptr(X509_gmtime_adj(X509_getm_notBefore(cert), 0)) + || !TEST_ptr(X509_gmtime_adj(X509_getm_notAfter(cert), 3600)) + || !TEST_true(X509_set_pubkey(cert, pkey)) + || !TEST_int_gt(X509_sign(cert, pkey, EVP_sha256()), 0) + || !TEST_ptr(copy = X509_dup(cert)) + || !TEST_int_eq(X509_cmp(cert, copy), 0) + || !TEST_int_eq(X509_cmp(cert, cert), 0) + /* The copy is modified but still equal to itself */ + || !TEST_true(X509_set_serialNumber(copy, serial)) + || !TEST_int_eq(X509_cmp(copy, copy), 0) + || !TEST_int_eq(X509_cmp(cert, copy), -1) + || !TEST_int_eq(X509_cmp(copy, cert), 1) + /* Both modified: unequal */ + || !TEST_true(X509_set_serialNumber(cert, serial)) + || !TEST_int_ne(X509_cmp(cert, copy), 0) + /* Signing again makes them comparable and equal */ + || !TEST_int_gt(X509_sign(cert, pkey, EVP_sha256()), 0) + || !TEST_int_gt(X509_sign(copy, pkey, EVP_sha256()), 0) + || !TEST_int_eq(X509_cmp(cert, copy), 0)) + goto err; + + if (!TEST_ptr(crl = X509_CRL_new()) + || !TEST_true(X509_CRL_set_issuer_name(crl, name)) + || !TEST_true(X509_CRL_set1_lastUpdate(crl, X509_getm_notBefore(cert))) + || !TEST_int_gt(X509_CRL_sign(crl, pkey, EVP_sha256()), 0) + || !TEST_ptr(crl_copy = X509_CRL_dup(crl)) + || !TEST_int_eq(X509_CRL_match(crl, crl), 0) + || !TEST_true(X509_CRL_set_version(crl_copy, X509_CRL_VERSION_2)) + || !TEST_int_eq(X509_CRL_match(crl_copy, crl_copy), 0) + || !TEST_int_eq(X509_CRL_match(crl, crl_copy), -1) + || !TEST_int_eq(X509_CRL_match(crl_copy, crl), 1)) + goto err; + + ret = 1; +err: + X509_CRL_free(crl_copy); + X509_CRL_free(crl); + X509_free(copy); + X509_free(cert); + ASN1_INTEGER_free(serial); + X509_NAME_free(name); + EVP_PKEY_free(pkey); + return ret; +} + int setup_tests(void) { + ADD_TEST(test_sign_caches_encoding); + ADD_TEST(test_cmp_modified); ADD_TEST(test_standard_exts); ADD_ALL_TESTS(test_a2i_ipaddress, OSSL_NELEM(a2i_ipaddress_tests)); + ADD_ALL_TESTS(test_ipaddr_to_asc, OSSL_NELEM(ipaddr_to_asc_tests)); + ADD_TEST(test_crl_add_ext_modifies); + ADD_TEST(test_enc_save_failure); ADD_TEST(tests_X509_PURPOSE); ADD_TEST(tests_X509_check_time); ADD_TEST(tests_X509_check_crypto); ADD_TEST(tests_x509_check_dpn); ADD_TEST(tests_x509_check_akid); + ADD_TEST(test_X509_ALGOR_set_md_null); ADD_TEST(tests_x509_check_ext_duplicity); ADD_TEST(tests_x509_check_ext_duplicity_nid_undef); ADD_TEST(tests_x509_check_ext_duplicity_nid_dynamic); - + ADD_ALL_TESTS(test_x509_attribute_bit_string, 2); + + ADD_TEST(test_X509_ALGOR_set_md_sha1); +#ifndef OPENSSL_NO_MD5 + ADD_TEST(test_X509_ALGOR_set_md_md5); +#endif + ADD_TEST(test_X509_ALGOR_set_md_nid_undef_known_name); + ADD_TEST(test_X509_ALGOR_set_md_null_obj); return 1; } diff --git a/test/x509_load_cert_file_test.c b/test/x509_load_cert_file_test.c index f9656aaa31c58..bfcd3521f548d 100644 --- a/test/x509_load_cert_file_test.c +++ b/test/x509_load_cert_file_test.c @@ -230,6 +230,19 @@ static int test_x509_get1_objects_mfail(void) return ret; } +/* Trigger memory failures while parsing a PEM certificate. */ +static int test_x509_pem_read_mfail(void) +{ + X509 *cert; + + MFAIL_start(); + cert = X509_from_strings(cn_cert1); + MFAIL_end(); + + X509_free(cert); + return 1; +} + OPT_TEST_DECLARE_USAGE("cert.pem [crl.pem]\n") int setup_tests(void) @@ -247,6 +260,7 @@ int setup_tests(void) ADD_TEST(test_load_cert_file); ADD_TEST(test_load_same_cn_certs); + ADD_MFAIL_NO_CHECK_TEST(test_x509_pem_read_mfail); ADD_MFAIL_TEST(test_x509_store_add_mfail); ADD_MFAIL_TEST(test_x509_get1_objects_mfail); diff --git a/test/x509_memfail.c b/test/x509_memfail.c deleted file mode 100644 index 41b2c098dc04d..0000000000000 --- a/test/x509_memfail.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. - * - * Licensed under the Apache License 2.0 (the "License"). You may not use - * this file except in compliance with the License. You can obtain a copy - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include - -#define OPENSSL_SUPPRESS_DEPRECATED /* EVP_PKEY_get1/set1_RSA */ - -#include -#include -#include -#include -#include -#include "crypto/x509.h" /* x509_st definition */ -#include "testutil.h" - -static char *certfile = NULL; -static int mcount, rcount, fcount, scount, srcount; - -static int do_x509(int allow_failure) -{ - int ret = (allow_failure == 1) ? 0 : 1; - BIO *bio = NULL; - X509 *x509 = NULL; - const ASN1_BIT_STRING *sig = NULL; - const X509_ALGOR *alg = NULL; - EVP_PKEY *pkey; -#ifndef OPENSSL_NO_DEPRECATED_3_0 - RSA *rsa = NULL; -#endif - - if (!TEST_ptr(bio = BIO_new_file(certfile, "r")) - || !TEST_ptr(x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) - || !TEST_ptr(pkey = X509_get0_pubkey(x509))) - goto err; - -#ifndef OPENSSL_NO_DEPRECATED_3_0 - /* Issue #24575 requires legacy key but the test is useful anyway */ - if (!TEST_ptr(rsa = EVP_PKEY_get1_RSA(pkey))) - goto err; - - if (!TEST_int_gt(EVP_PKEY_set1_RSA(pkey, rsa), 0)) - goto err; -#endif - - X509_get0_signature(&sig, &alg, x509); - - if (!TEST_int_gt(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), - (X509_ALGOR *)alg, (ASN1_BIT_STRING *)sig, - &x509->cert_info, pkey), - 0)) - goto err; - - if (!TEST_int_lt(ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), - (X509_ALGOR *)alg, (ASN1_BIT_STRING *)sig, - NULL, pkey), - 0)) - goto err; - - X509_issuer_name_hash(x509); - - ret = 1; - -err: -#ifndef OPENSSL_NO_DEPRECATED_3_0 - RSA_free(rsa); -#endif - X509_free(x509); - BIO_free(bio); - return ret; -} - -static int test_record_alloc_counts(void) -{ - return do_x509(1); -} - -static int test_alloc_failures(void) -{ - return do_x509(0); -} - -static int test_report_alloc_counts(void) -{ - CRYPTO_get_alloc_counts(&mcount, &rcount, &fcount); - /* - * Report our memory allocations from the count run - * NOTE: We report a number of (re)allocations to skip here - * (the scount + srcount value). These are the allocations - * that took place while the test harness itself was getting - * setup (i.e. calling OPENSSL_init_crypto/etc). We can't fail - * those allocations as they will cause the test to fail before - * we have even run the workload. So report them so we can - * allow them to function before we start doing any real testing - */ - TEST_info("skip: %d count %d\n", - scount + srcount, mcount + rcount - scount - srcount); - return 1; -} - -int setup_tests(void) -{ - int ret = 0; - char *opmode = NULL; - - if (!TEST_ptr(opmode = test_get_argument(0))) - goto err; - - if (!TEST_ptr(certfile = test_get_argument(1))) - goto err; - - if (strcmp(opmode, "count") == 0) { - CRYPTO_get_alloc_counts(&scount, &srcount, &fcount); - ADD_TEST(test_record_alloc_counts); - ADD_TEST(test_report_alloc_counts); - } else { - ADD_TEST(test_alloc_failures); - } - ret = 1; -err: - return ret; -} - -void cleanup_tests(void) -{ -} diff --git a/test/x509_req_test.c b/test/x509_req_test.c index b37fd0599adab..1ac626732fd56 100644 --- a/test/x509_req_test.c +++ b/test/x509_req_test.c @@ -7,8 +7,10 @@ * https://www.openssl.org/source/license.html */ +#include #include #include +#include #include "testutil.h" @@ -53,6 +55,83 @@ static int test_x509_req_detect_invalid_version(void) return ret; } +static int add_ext(STACK_OF(X509_EXTENSION) *sk, int nid, char *value) +{ + X509_EXTENSION *ex; + ex = X509V3_EXT_conf_nid(NULL, NULL, nid, value); + if (!ex) + return 0; + if (sk_X509_EXTENSION_push(sk, ex) <= 0) { + X509_EXTENSION_free(ex); + return 0; + } + + return 1; +} + +static int test_x509_req_add_exts(void) +{ + X509_REQ *x = NULL; + STACK_OF(X509_EXTENSION) *exts = NULL; + EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY *pkey = NULL; + int ret = 0; + int nid = NID_undef; + OSSL_PARAM params[2]; + size_t bits = 2048; + + params[0] = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS, &bits); + params[1] = OSSL_PARAM_construct_end(); + + ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); + if (ctx == NULL + || EVP_PKEY_keygen_init(ctx) <= 0 + || EVP_PKEY_CTX_set_params(ctx, params) <= 0 + || EVP_PKEY_keygen(ctx, &pkey) <= 0 + || (x = X509_REQ_new()) == NULL + || X509_REQ_set_pubkey(x, pkey) <= 0) + goto err; + + exts = sk_X509_EXTENSION_new_null(); + if (!TEST_ptr(exts)) + goto err; + + /* + * For request extensions they are all packed in a single attribute. We + * save them in a STACK and add them all at once later... + */ + + if (!TEST_int_eq(add_ext(exts, NID_netscape_cert_type, "client,email"), 1) + || !TEST_int_eq(add_ext(exts, NID_subject_alt_name, "email:steve@openssl.org"), 1) + || !TEST_int_eq(add_ext(exts, NID_crl_distribution_points, "URI:http://example.org"), 1) + /* These tests require some underlying config but we just check that we don't crash */ + || !TEST_int_eq(add_ext(exts, NID_proxyCertInfo, "text:xxx"), 0) + || !TEST_int_eq(add_ext(exts, NID_certificate_policies, "xxx:yyy"), 0) + /* Some Netscape specific extensions */ + || !TEST_int_eq(add_ext(exts, NID_netscape_cert_type, "client,email"), 1)) + goto err; + + /* Maybe even add our own extension based on existing */ + nid = OBJ_create("1.2.3.4", "MyAlias", "My Test Alias Extension"); + if (!TEST_int_ne(nid, NID_undef) + || !TEST_int_gt(X509V3_EXT_add_alias(nid, NID_netscape_comment), 0) + || !TEST_int_eq(add_ext(exts, nid, "example comment alias"), 1) + || !TEST_int_eq(X509_REQ_add_extensions(x, exts), 1)) + goto err; + + if (!X509_REQ_sign(x, pkey, EVP_sha256())) + goto err; + + ret = 1; +err: + EVP_PKEY_CTX_free(ctx); + + X509_REQ_free(x); + EVP_PKEY_free(pkey); + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + + return ret; +} OPT_TEST_DECLARE_USAGE("certdir\n") int setup_tests(void) @@ -65,6 +144,7 @@ int setup_tests(void) return 0; ADD_TEST(test_x509_req_detect_invalid_version); + ADD_TEST(test_x509_req_add_exts); return 1; } diff --git a/test/x509_test.c b/test/x509_test.c index a5beb7ca2fcc2..0eb3f7060bd3a 100644 --- a/test/x509_test.c +++ b/test/x509_test.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include "crypto/x509.h" /* x509_st definition */ @@ -194,6 +195,62 @@ static int test_asn1_item_verify(void) return ret; } +/* Load the self-signed certificate passed on the command line. */ +static X509 *load_arg_cert(void) +{ + const char *certfile; + BIO *bio; + X509 *x509; + + if ((certfile = test_get_argument(0)) == NULL + || (bio = BIO_new_file(certfile, "r")) == NULL) + return NULL; + x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL); + BIO_free(bio); + return x509; +} + +/* Trigger memory failures during certificate self-signature verification. */ +static int test_x509_asn1_item_verify_mfail(void) +{ + X509 *x509; + EVP_PKEY *pkey; + const ASN1_BIT_STRING *sig = NULL; + const X509_ALGOR *alg = NULL; + + if (!TEST_ptr(x509 = load_arg_cert()) + || !TEST_ptr(pkey = X509_get0_pubkey(x509))) { + X509_free(x509); + return -1; + } + X509_get0_signature(&sig, &alg, x509); + + MFAIL_start(); + (void)ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), alg, sig, + &x509->cert_info, pkey); + MFAIL_end(); + + X509_free(x509); + return 1; +} + +/* Trigger memory failures while hashing the issuer name. */ +static int test_x509_issuer_name_hash_mfail(void) +{ + X509 *x509; + int ret = -1; + + if (!TEST_ptr(x509 = load_arg_cert())) + return -1; + + MFAIL_start(); + ret = X509_issuer_name_hash(x509) != 0 ? 1 : 0; + MFAIL_end(); + + X509_free(x509); + return ret; +} + static int test_x509_delete_last_extension(void) { int ret = 0; @@ -645,6 +702,202 @@ static int test_nc_empty_dirname_permitted(void) sizeof(nc_permitted_empty_dirname), X509_V_OK); } +static int test_x509_name_canon_failure_cache(void) +{ + static const unsigned char invalid_utf8[] = { 0xc0, 0xaf }; + int ret = 0, hash_ok = 1; + X509 *cert = NULL; + X509_NAME *empty = NULL; + X509_STORE *store = NULL; + + if (!TEST_ptr(cert = X509_new()) + || !TEST_ptr(empty = X509_NAME_new()) + || !TEST_ptr(store = X509_STORE_new()) + || !TEST_true(X509_NAME_add_entry_by_txt(cert->cert_info.subject, + "CN", V_ASN1_UTF8STRING, invalid_utf8, sizeof(invalid_utf8), -1, + 0)) + /* + * The first attempt populates DER before canonicalization fails. A + * retry must not reuse that partial cache. + */ + || !TEST_int_lt(i2d_X509_NAME(cert->cert_info.subject, NULL), 0) + || !TEST_int_lt(i2d_X509_NAME(cert->cert_info.subject, NULL), 0) + || !TEST_int_eq(X509_NAME_cmp(cert->cert_info.subject, empty), -2) + || !TEST_ulong_eq(X509_NAME_hash_ex(cert->cert_info.subject, NULL, + NULL, &hash_ok), + 0) + || !TEST_false(hash_ok) + || !TEST_false(X509_STORE_add_cert(store, cert))) + goto end; + + ret = 1; + +end: + ERR_clear_error(); + X509_STORE_free(store); + X509_NAME_free(empty); + X509_free(cert); + return ret; +} + +static int test_x509_name_multivalued_rdn_mfail(void) +{ + X509_NAME *name = NULL; + int ret = 0; + + if (!TEST_ptr(name = X509_NAME_new()) + || !TEST_true(X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, + (unsigned char *)"Alice", -1, -1, 0)) + || !TEST_true(X509_NAME_add_entry_by_txt(name, "OU", MBSTRING_ASC, + (unsigned char *)"Engineering", -1, -1, -1))) + goto end; + + MFAIL_start(); + ret = i2d_X509_NAME(name, NULL) > 0; + MFAIL_end(); + +end: + X509_NAME_free(name); + return ret; +} + +static int test_x509_attribute_i2d_mfail(void) +{ + static const unsigned char value1[] = "first"; + static const unsigned char value2[] = "second"; + X509_ATTRIBUTE *attr = NULL; + unsigned char *der = NULL; + int len, ret = -1; + + if (!TEST_ptr(attr = X509_ATTRIBUTE_create_by_NID(NULL, NID_commonName, + V_ASN1_UTF8STRING, value1, sizeof(value1) - 1)) + || !TEST_true(X509_ATTRIBUTE_set1_data(attr, V_ASN1_UTF8STRING, + value2, sizeof(value2) - 1))) + goto end; + + MFAIL_start(); + len = i2d_X509_ATTRIBUTE(attr, &der); + MFAIL_end(); + + if (len <= 0) + ret = der == NULL ? 0 : -1; + else + ret = der != NULL ? 1 : -1; + +end: + OPENSSL_free(der); + X509_ATTRIBUTE_free(attr); + return ret; +} + +static PKCS7 *make_two_digest_pkcs7(void) +{ + PKCS7 *p7 = NULL; + X509_ALGOR *alg = NULL; + + if (!TEST_ptr(p7 = PKCS7_new()) + || !TEST_true(PKCS7_set_type(p7, NID_pkcs7_signed)) + || !TEST_true(PKCS7_content_new(p7, NID_pkcs7_data)) + || !TEST_ptr(alg = X509_ALGOR_new()) + || !TEST_true(X509_ALGOR_set_md(alg, EVP_sha256())) + || !TEST_int_gt(sk_X509_ALGOR_push(p7->d.sign->md_algs, alg), 0)) + goto end; + alg = NULL; + + if (!TEST_ptr(alg = X509_ALGOR_new()) + || !TEST_true(X509_ALGOR_set_md(alg, EVP_sha384())) + || !TEST_int_gt(sk_X509_ALGOR_push(p7->d.sign->md_algs, alg), 0)) + goto end; + alg = NULL; + + return p7; + +end: + X509_ALGOR_free(alg); + PKCS7_free(p7); + return NULL; +} + +static int test_pkcs7_digest_set_i2d_mfail(void) +{ + PKCS7 *p7 = NULL; + unsigned char *der = NULL, *p; + int len, outlen, ret = -1; + + if (!TEST_ptr(p7 = make_two_digest_pkcs7())) + goto end; + + len = i2d_PKCS7(p7, NULL); + if (!TEST_int_gt(len, 0) || !TEST_ptr(der = OPENSSL_malloc(len))) + goto end; + p = der; + + MFAIL_start(); + outlen = i2d_PKCS7(p7, &p); + MFAIL_end(); + + if (outlen <= 0) + ret = 0; + else + ret = outlen == len && p == der + len ? 1 : -1; + +end: + OPENSSL_free(der); + PKCS7_free(p7); + return ret; +} + +static int test_pkcs7_digest_set_stream_mfail(void) +{ + static const unsigned char content[] = "stream content"; + PKCS7 *p7 = NULL, *expected_p7 = NULL; + BIO *in = NULL, *out = NULL; + BIO *expected_in = NULL, *expected_out = NULL; + char *data = NULL, *expected_data = NULL; + long len, expected_len; + int outlen, ret = -1; + + if (!TEST_ptr(expected_p7 = make_two_digest_pkcs7()) + || !TEST_ptr(expected_in = BIO_new_mem_buf(content, + sizeof(content) - 1)) + || !TEST_ptr(expected_out = BIO_new(BIO_s_mem())) + || !TEST_true(i2d_PKCS7_bio_stream(expected_out, expected_p7, + expected_in, + SMIME_STREAM | PKCS7_BINARY)) + || !TEST_long_gt(expected_len = BIO_get_mem_data(expected_out, + &expected_data), + 0) + || !TEST_ptr(p7 = make_two_digest_pkcs7()) + || !TEST_ptr(in = BIO_new_mem_buf(content, sizeof(content) - 1)) + || !TEST_ptr(out = BIO_new(BIO_s_mem()))) + goto end; + + MFAIL_start(); + outlen = i2d_PKCS7_bio_stream(out, p7, in, + SMIME_STREAM | PKCS7_BINARY); + MFAIL_end(); + + if (outlen <= 0) { + ret = 0; + } else { + len = BIO_get_mem_data(out, &data); + if (!TEST_long_eq(len, expected_len) + || !TEST_mem_eq(data, len, expected_data, expected_len)) + ret = -1; + else + ret = 1; + } + +end: + BIO_free(out); + BIO_free(in); + PKCS7_free(p7); + BIO_free(expected_out); + BIO_free(expected_in); + PKCS7_free(expected_p7); + return ret; +} + OPT_TEST_DECLARE_USAGE("\n") int setup_tests(void) @@ -679,6 +932,8 @@ int setup_tests(void) ADD_TEST(test_x509_tbs_cache); ADD_TEST(test_x509_crl_tbs_cache); ADD_TEST(test_asn1_item_verify); + ADD_MFAIL_NO_CHECK_TEST(test_x509_asn1_item_verify_mfail); + ADD_MFAIL_TEST(test_x509_issuer_name_hash_mfail); ADD_TEST(test_x509_delete_last_extension); ADD_TEST(test_x509_crl_delete_last_extension); ADD_TEST(test_x509_revoked_delete_last_extension); @@ -688,6 +943,11 @@ int setup_tests(void) ADD_TEST(test_x509_verify_with_new); ADD_TEST(test_nc_empty_dirname_excluded); ADD_TEST(test_nc_empty_dirname_permitted); + ADD_TEST(test_x509_name_canon_failure_cache); + ADD_MFAIL_TEST(test_x509_name_multivalued_rdn_mfail); + ADD_MFAIL_TEST(test_x509_attribute_i2d_mfail); + ADD_MFAIL_TEST(test_pkcs7_digest_set_i2d_mfail); + ADD_MFAIL_NO_CHECK_TEST(test_pkcs7_digest_set_stream_mfail); return 1; } diff --git a/test/x509_time_test.c b/test/x509_time_test.c index 59dad294ef0a5..2347fc69b4b7c 100644 --- a/test/x509_time_test.c +++ b/test/x509_time_test.c @@ -628,7 +628,7 @@ static int test_days(int n) struct tm t; int r; - BIO_snprintf(d, sizeof(d), "%04d%02d%02d050505Z", + snprintf(d, sizeof(d), "%04d%02d%02d050505Z", day_of_week_tests[n].y, day_of_week_tests[n].m, day_of_week_tests[n].d); diff --git a/util/checkplatformsyms.pl b/util/checkplatformsyms.pl index 991c74bac99e9..73f2a1b62184a 100755 --- a/util/checkplatformsyms.pl +++ b/util/checkplatformsyms.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2006-2023 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2006-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/util/ck_errf.pl b/util/ck_errf.pl index 681535e7200ce..a77eac56d70cd 100755 --- a/util/ck_errf.pl +++ b/util/ck_errf.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -80,6 +80,33 @@ sub help @source = @ARGV; } +# util/mkerr.pl keeps a stamp file next to its statefile recording the +# last completed error-code pass over the tree. While the stamp is +# newer than the config file, the statefile and every source file, +# this check has already run against the current tree; skip the scan. +# (If the config file names its statefile with an S line, this +# derivation misses it and the check simply never skips.) +if ( !$debug ) { + my $statefile = $config; + + $statefile =~ s/\.ec$/.txt/; + my $stamp = (stat "$statefile.stamp")[9]; + + if ( defined $stamp ) { + my $uptodate = 1; + + foreach my $file ( $config, $statefile, @source ) { + my $mtime = (stat $file)[9]; + + if ( !defined $mtime || $mtime >= $stamp ) { + $uptodate = 0; + last; + } + } + exit 0 if $uptodate; + } +} + # To detect if there is any error generation for a libcrypto/libssl libs # we don't know, we need to find out what libs we do know. That list is # readily available in crypto/err/openssl.ec, in form of lines starting diff --git a/util/file-from-stdout.pl b/util/file-from-stdout.pl new file mode 100644 index 0000000000000..8c4946e568873 --- /dev/null +++ b/util/file-from-stdout.pl @@ -0,0 +1,74 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +# Run a command and make its standard output into a file, in place of the +# shell's ">". The output is collected in a temporary file and renamed over +# the target once the command has succeeded, so a failing command leaves the +# previous target rather than a truncated one with a fresh timestamp. +# +# The target is left read-only. Renaming onto a read-only file needs no +# permission on the file itself, so it can still be replaced. +# +# Usage: file-from-stdout.pl [-x] FILE command [args...] + +my $executable = 0; + +if (@ARGV && $ARGV[0] eq "-x") { + $executable = 1; + shift @ARGV; +} + +my $target = shift @ARGV; + +die "Usage: $0 [-x] FILE command [args...]\n" + unless defined $target && @ARGV; + +my $temp = "$target.tmp$$"; + +unlink $temp; + +open my $out, ">", $temp + or die "Can't write $temp, $!\n"; + +END { + unlink $temp if defined $temp && -e $temp; +} + +my $exec = shift @ARGV; +open my $saved, ">&", \*STDOUT + or die "Can't save stdout, $!\n"; +open STDOUT, ">&", $out + or die "Can't redirect stdout to $temp, $!\n"; + +my $status = system($exec, @ARGV); +my $why = $!; + +open STDOUT, ">&", $saved + or die "Can't restore stdout, $!\n"; +close $saved; +close $out + or die "Can't finish writing $temp, $!\n"; + +if ($status != 0) { + my $how = $status == -1 ? "could not be run, $why" + : $status & 127 ? "died with signal " . ($status & 127) + : "exited with " . ($status >> 8); + my $code = $status == -1 || ($status & 127) ? 1 : $status >> 8; + + print STDERR "$exec $how\n"; + exit $code; +} + +chmod $executable ? 0555 : 0444, $temp + or die "Can't set the mode of $temp, $!\n"; + +rename $temp, $target + or die "Can't rename $temp to $target, $!\n"; diff --git a/util/find-doc-nits b/util/find-doc-nits index 2ec0939faa12f..8c1a26cba5f10 100755 --- a/util/find-doc-nits +++ b/util/find-doc-nits @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2002-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2002-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy diff --git a/util/indent.pro b/util/indent.pro index 52f7a60e37f7d..16ff4afb96875 100644 --- a/util/indent.pro +++ b/util/indent.pro @@ -583,6 +583,8 @@ -T clock_t -T custom_ext_methods -T hm_fragment +-T dtls_msg_info +-T dtls_sent_msg -T ssl_ctx_st -T ssl_flag_tbl -T ssl_st diff --git a/util/install-files.pl b/util/install-files.pl new file mode 100644 index 0000000000000..5028fe38e5609 --- /dev/null +++ b/util/install-files.pl @@ -0,0 +1,40 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +require 5.10.0; +use warnings; +use strict; + +use File::Basename; +use File::Compare; +use File::Copy; + +# Install a set of files into one directory in a single process, +# replacing only the files whose content changed; an installed file +# that is already identical keeps its timestamp, so consumers that +# build against the installed tree do not see it as modified. + +if ($#ARGV + 1 < 2) { + print STDERR "Usage: install-files.pl mode target-dir [file...]\n"; + exit 1; +} + +my ($mode, $targetdir, @files) = @ARGV; + +$mode = oct($mode); + +foreach my $file (@files) { + my $target = "$targetdir/" . basename($file); + + next if -f $target && compare($file, $target) == 0; + print "install $file -> $target\n"; + copy($file, $target) + || die "Can't install $file to $target, $!\n"; + chmod $mode, $target + || die "Can't chmod $target, $!\n"; +} diff --git a/util/install-man-pages.pl b/util/install-man-pages.pl new file mode 100644 index 0000000000000..ef7d712eafcce --- /dev/null +++ b/util/install-man-pages.pl @@ -0,0 +1,88 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +require 5.10.0; +use warnings; +use strict; + +use File::Basename; +use File::Compare; +use File::Copy; +use FindBin; +use lib "$FindBin::Bin/perl"; + +use OpenSSL::Util::Pod; + +# Install or uninstall a whole man section's pages and their NAME +# symlinks in a single process; one process per page does not scale +# to the number of pages OpenSSL installs. + +if ($#ARGV + 1 < 5 || $ARGV[0] !~ /^(un)?install$/) { + print STDERR + "Usage: install-man-pages.pl [install|uninstall] src-dir build-dir target-dir man-suffix [man-page-file...]\n"; + exit 1; +} + +my ($action, $srcdir, $builddir, $targetdir, $suffix, @files) = @ARGV; + +foreach my $file (@files) { + my $manname = basename($file); + + $manname =~ m|(.+)\.(.+)|; + my $mainf = $1; + my $section = $2; + die "Bad man page name $file\n" if !defined $mainf; + + my $target = "$targetdir/$manname$suffix"; + + if ($action eq "install") { + # A page is a regular file; a symlink here is a leftover alias, + # and copying would write this page over the one it points to. + unlink $target if -l $target; + + next if -f $target && compare($file, $target) == 0; + + print "install $file -> $target\n"; + copy($file, $target) + || die "Can't install $file to $target, $!\n"; + chmod 0644, $target + || die "Can't chmod $target, $!\n"; + } else { + print "rm -f $target\n"; + unlink $target; + } + + my $podfile = "$srcdir/$mainf.pod"; + # Some pod files are generated and are in the build dir + unless (-e $podfile) { + $podfile = "$builddir/$mainf.pod"; + } + my %podinfo = extract_pod_info($podfile); + + for my $name (@{$podinfo{names}}) { + next if $name eq $mainf; + my $link = "$targetdir/$name.$section$suffix"; + my $linktarget = "$manname$suffix"; + + next if $action eq "install" + && -l $link && readlink($link) eq $linktarget; + + # An alias can collide with an installed page on a + # case-insensitive file system (OSSL_TRACE_ENABLED alongside + # OSSL_trace_enabled), where unlinking the alias would remove + # the page and the symlink would point to itself. Never + # remove anything that is not a symlink, and skip an alias + # whose name is already occupied. + unlink $link if -l $link; + if ($action eq "install") { + symlink $linktarget, $link + || warn "Can't symlink $link to $linktarget, $!\n" + unless -e $link; + } + } +} diff --git a/util/libcrypto.num b/util/libcrypto.num index a51b72cf939bf..eebc52128d376 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -2571,9 +2571,9 @@ ASN1_STRING_copy 2569 4_0_0 EXIST::FUNCTION: ASN1_STRING_dup 2570 4_0_0 EXIST::FUNCTION: ASN1_STRING_type_new 2571 4_0_0 EXIST::FUNCTION: ASN1_STRING_cmp 2572 4_0_0 EXIST::FUNCTION: -ASN1_STRING_set 2573 4_0_0 EXIST::FUNCTION: +ASN1_STRING_set 2573 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_4_1 ASN1_STRING_set0 2574 4_0_0 EXIST::FUNCTION: -ASN1_STRING_length 2575 4_0_0 EXIST::FUNCTION: +ASN1_STRING_length 2575 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_4_1 ASN1_STRING_length_set 2576 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_3_0 ASN1_STRING_type 2577 4_0_0 EXIST::FUNCTION: ASN1_STRING_get0_data 2578 4_0_0 EXIST::FUNCTION: @@ -3017,8 +3017,8 @@ BIO_new_bio_dgram_pair 3015 4_0_0 EXIST::FUNCTION:DGRAM BIO_copy_next_retry 3016 4_0_0 EXIST::FUNCTION: BIO_printf 3017 4_0_0 EXIST::FUNCTION: BIO_vprintf 3018 4_0_0 EXIST::FUNCTION: -BIO_snprintf 3019 4_0_0 EXIST::FUNCTION: -BIO_vsnprintf 3020 4_0_0 EXIST::FUNCTION: +BIO_snprintf 3019 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_4_1 +BIO_vsnprintf 3020 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_4_1 BIO_meth_new 3021 4_0_0 EXIST::FUNCTION: BIO_meth_free 3022 4_0_0 EXIST::FUNCTION: BIO_meth_set_write 3023 4_0_0 EXIST::FUNCTION: @@ -3228,7 +3228,7 @@ PEM_read_CMS 3226 4_0_0 EXIST::FUNCTION:CMS,STDIO PEM_write_CMS 3227 4_0_0 EXIST::FUNCTION:CMS,STDIO PEM_read_bio_CMS 3228 4_0_0 EXIST::FUNCTION:CMS PEM_write_bio_CMS 3229 4_0_0 EXIST::FUNCTION:CMS -CMS_stream 3230 4_0_0 EXIST::FUNCTION:CMS +CMS_stream 3230 4_0_0 EXIST::FUNCTION:CMS,DEPRECATEDIN_4_1 d2i_CMS_bio 3231 4_0_0 EXIST::FUNCTION:CMS i2d_CMS_bio 3232 4_0_0 EXIST::FUNCTION:CMS BIO_new_CMS 3233 4_0_0 EXIST::FUNCTION:CMS @@ -4164,7 +4164,7 @@ PKCS7_RECIP_INFO_get0_alg 4161 4_0_0 EXIST::FUNCTION: PKCS7_add_recipient_info 4162 4_0_0 EXIST::FUNCTION: PKCS7_RECIP_INFO_set 4163 4_0_0 EXIST::FUNCTION: PKCS7_set_cipher 4164 4_0_0 EXIST::FUNCTION: -PKCS7_stream 4165 4_0_0 EXIST::FUNCTION: +PKCS7_stream 4165 4_0_0 EXIST::FUNCTION:DEPRECATEDIN_4_1 PKCS7_get_issuer_and_serial 4166 4_0_0 EXIST::FUNCTION: PKCS7_get_octet_string 4167 4_0_0 EXIST::FUNCTION: PKCS7_digest_from_attributes 4168 4_0_0 EXIST::FUNCTION: @@ -5715,6 +5715,10 @@ OPENSSL_sk_set_cmp_thunks 5712 4_0_0 EXIST::FUNCTION: ASN1_BIT_STRING_set1 5713 4_0_0 EXIST::FUNCTION: OSSL_ESS_check_signing_certs_ex 5714 4_0_0 EXIST::FUNCTION: X509v3_delete_extension 5715 4_0_0 EXIST::FUNCTION: +CMS_SignerInfo_get0_signer_cert ? 4_1_0 EXIST::FUNCTION:CMS +CMS_SignerInfo_get_verification_result ? 4_1_0 EXIST::FUNCTION:CMS +EVP_SKEY_get0_local_keyid ? 4_1_0 EXIST::FUNCTION: +EVP_SKEY_get0_algorithm_id ? 4_1_0 EXIST::FUNCTION: CTLOG_STORE_add0_log ? 4_1_0 EXIST::FUNCTION:CT CRYPTO_atomic_load_ptr ? 4_1_0 EXIST::FUNCTION: CRYPTO_atomic_store_ptr ? 4_1_0 EXIST::FUNCTION: @@ -5724,3 +5728,22 @@ OPENSSL_sk_set_copy_thunks ? 4_1_0 EXIST::FUNCTION: ASN1_STRING_new_not_owned ? 4_1_0 EXIST::FUNCTION: EVP_KDF_CTX_get0_kdf ? 4_1_0 EXIST::FUNCTION: EVP_KDF_CTX_get1_kdf ? 4_1_0 EXIST::FUNCTION: +ASN1_STRING_set1_data ? 4_1_0 EXIST::FUNCTION: +ASN1_STRING_set1_string ? 4_1_0 EXIST::FUNCTION: +ASN1_STRING_get_length ? 4_1_0 EXIST::FUNCTION: +CMS_add_standard_smimecap_ex ? 4_1_0 EXIST::FUNCTION:CMS +BIO_socket_ready ? 4_1_0 EXIST::FUNCTION:SOCK +d2i_IPAddrBlocks ? 4_1_0 EXIST::FUNCTION:RFC3779 +i2d_IPAddrBlocks ? 4_1_0 EXIST::FUNCTION:RFC3779 +IPAddrBlocks_free ? 4_1_0 EXIST::FUNCTION:RFC3779 +IPAddrBlocks_new ? 4_1_0 EXIST::FUNCTION:RFC3779 +IPAddrBlocks_it ? 4_1_0 EXIST::FUNCTION:RFC3779 +PKCS8_PRIV_KEY_INFO_get1_skey ? 4_2_0 EXIST::FUNCTION: +PKCS12_decrypt_secretbag ? 4_2_0 EXIST::FUNCTION: +PKCS12_PARSE_CTX_new ? 4_2_0 EXIST::FUNCTION: +PKCS12_PARSE_CTX_free ? 4_2_0 EXIST::FUNCTION: +PKCS12_PARSE_CTX_set_pkey ? 4_2_0 EXIST::FUNCTION: +PKCS12_PARSE_CTX_set_cert ? 4_2_0 EXIST::FUNCTION: +PKCS12_PARSE_CTX_set_ca ? 4_2_0 EXIST::FUNCTION: +PKCS12_PARSE_CTX_set_skeys ? 4_2_0 EXIST::FUNCTION: +PKCS12_parse_ex ? 4_2_0 EXIST::FUNCTION: diff --git a/util/missingcrypto-internal.txt b/util/missingcrypto-internal.txt index 54e1bc9ba7dd0..41115bbec3b10 100644 --- a/util/missingcrypto-internal.txt +++ b/util/missingcrypto-internal.txt @@ -6,3 +6,4 @@ ossl_do_PVK_header(3) ossl_do_blob_header(3) ossl_b2i(3) ossl_b2i_bio(3) +ossl_rbtree(3) diff --git a/util/missingcrypto.txt b/util/missingcrypto.txt index 5e8126d12ce76..7a489a1b6a6fb 100644 --- a/util/missingcrypto.txt +++ b/util/missingcrypto.txt @@ -285,9 +285,6 @@ CMS_SignerInfo_get0_pkey_ctx(3) CMS_add0_CertificateChoices(3) CMS_add0_RevocationInfoChoice(3) CMS_add0_recipient_password(3) -CMS_add_simple_smimecap(3) -CMS_add_smimecap(3) -CMS_add_standard_smimecap(3) CMS_data(3) CMS_dataInit(3) CMS_decrypt_set1_key(3) @@ -1014,8 +1011,6 @@ X509V3_EXT_conf(3) X509V3_EXT_conf_nid(3) X509V3_EXT_get(3) X509V3_EXT_get_nid(3) -X509V3_EXT_nconf(3) -X509V3_EXT_nconf_nid(3) X509V3_EXT_val_prn(3) X509V3_NAME_from_section(3) X509V3_add_standard_extensions(3) diff --git a/util/mkerr.pl b/util/mkerr.pl index e2479e727b74d..16555d4a604c1 100755 --- a/util/mkerr.pl +++ b/util/mkerr.pl @@ -13,7 +13,6 @@ use File::Spec::Functions qw(abs2rel rel2abs); use lib "."; -use configdata; my $config = "crypto/err/openssl.ec"; my $debug = 0; @@ -21,8 +20,10 @@ my $nowrite = 0; my $rebuild = 0; my $reindex = 0; +my $stateonly = 0; my $static = 0; my $unref = 0; +my $emit; # file to write on stdout instead of doing a full run my %modules = (); my $errors = 0; @@ -64,6 +65,13 @@ sub help -reindex Ignore previously assigned values (except for R records in the config file) and renumber everything starting at 100. + -state Scan the sources and update the state file, but do not + write any header or C files. Only useful with -internal. + + -emit FILE Write the named generated header or C file to standard + output and exit; no scan, no state update. FILE must be + a file the config file names. Only useful with -internal. + -static Make the load/unload functions static. -unref List all unreferenced function and reason codes on stderr; @@ -95,6 +103,11 @@ sub help $rebuild = 1; } elsif ( $arg eq "-reindex" ) { $reindex = 1; + } elsif ( $arg eq "-state" ) { + $stateonly = 1; + } elsif ( $arg eq "-emit" ) { + $emit = $ARGV[1]; + shift @ARGV; } elsif ( $arg eq "-static" ) { $static = 1; } elsif ( $arg eq "-unref" ) { @@ -113,7 +126,10 @@ sub help } my @source; -if ( $internal ) { +if ( defined $emit ) { + die "-emit is only useful with -internal\n" unless $internal; + die "Extra parameters given.\n" if @ARGV; +} elsif ( $internal ) { die "Cannot mix -internal and -static\n" if $static; die "Extra parameters given.\n" if @ARGV; @source = ( glob('crypto/*.c'), glob('crypto/*/*.c'), @@ -143,8 +159,10 @@ sub help # Read and parse the config file open(IN, "$config") || die "Can't open config file $config, $!,"; while ( ) { + s|\R$||; # Better chomp; this may run on a + # checkout with CRLF line endings next if /^#/ || /^$/; - if ( /^L\s+(\S+)\s+(\S+)\s+(\S+)(?:\s+(\S+))?\s+$/ ) { + if ( /^L\s+(\S+)\s+(\S+)\s+(\S+)(?:\s+(\S+))?\s*$/ ) { my $lib = $1; my $pubhdr = $2; my $err = $3; @@ -181,6 +199,34 @@ sub help $statefile =~ s/.ec/.txt/; } +# Unless a rewrite or a report was explicitly requested, skip the run +# entirely if nothing relevant changed since the last one. The stamp +# file records when a run last completed against the current sources; +# it is a separate file rather than the statefile's own timestamp +# because the statefile is a build input, and freshening it would +# spuriously regenerate every emitted error file. While the stamp is +# newer than the config file, the statefile and every source file, a +# new run would find no new reason codes and write nothing. +if ( !defined $emit + && !$rebuild && !$reindex && !$nowrite && !$unref && !$debug + && scalar keys %modules == 0 ) { + my $stamp = (stat "$statefile.stamp")[9]; + + if ( defined $stamp ) { + my $uptodate = 1; + + foreach my $file ( $config, $statefile, @source ) { + my $mtime = (stat $file)[9]; + + if ( !defined $mtime || $mtime >= $stamp ) { + $uptodate = 0; + last; + } + } + exit if $uptodate; + } +} + # The statefile has all the previous assignments. &phase("Reading state"); my $skippedstate = 0; @@ -190,6 +236,7 @@ sub help # Scan function and reason codes and store them: keep a note of the # maximum code used. while ( ) { + s|\R$||; # Better chomp, as above next if /^#/ || /^$/; my $name; my $code; @@ -197,6 +244,9 @@ sub help $name = $1; $code = $2; my $next = ; + + $next =~ s|\R$||; # Better chomp, as above; the greedy + # trim below would keep a \r $next =~ s/^\s*(.*)\s*$/$1/; die "Duplicate define $name" if exists $strings{$name}; $strings{$name} = $next; @@ -286,6 +336,43 @@ sub help } print STDERR "\n" if $debug; +# Resolve the values of the new reason codes before anything is +# written; the state file and the emitted headers all need them. +# Codes are assigned per library, in sorted reason order, into the +# lowest free slot, exactly as the header emission historically did. +&phase("Assigning codes"); +foreach my $lib ( keys %errorfile ) { + next if ! $rnew{$lib}; + foreach my $i ( sort grep( /^${lib}_/, keys %rcodes ) ) { + next if $rcodes{$i} ne "X"; + $rassigned{$lib} =~ m/^:([^:]*):/; + my $findcode = $1; + + $findcode = $rmax{$lib} if !defined $findcode; + while ( $rassigned{$lib} =~ m/:$findcode:/ ) { + $findcode++; + } + $rcodes{$i} = $findcode; + $rassigned{$lib} .= "$findcode:"; + print STDERR "New Reason code $i\n" if $debug; + } +} + +# In -emit mode the state is the single source of truth: write the one +# requested file to standard output and do nothing else. +if ( defined $emit ) { + if ( defined $libprivinc{$emit} && $emit ne 'NONE' ) { + write_internal_header($libprivinc{$emit}, \*STDOUT); + } elsif ( defined $libpubinc{$emit} ) { + write_public_header($libpubinc{$emit}, \*STDOUT); + } elsif ( defined $cskip{$emit} ) { + write_c_source($cskip{$emit}, \*STDOUT); + } else { + die "$emit is not a file the config file $config knows about\n"; + } + exit; +} + # Now process each library in turn. &phase("Writing files"); my $newstate = 0; @@ -295,39 +382,133 @@ sub help next if $nowrite; print STDERR "$lib: $rnew{$lib} new reasons\n" if $rnew{$lib}; $newstate = 1; + next if $stateonly; - # If we get here then we have some new error codes so we - # need to rebuild the header file and C file. + if ($hprivinc{$lib} ne 'NONE') { + my $hfile = $hprivinc{$lib}; - # Make a sorted list of error and reason codes for later use. - my @reasons = sort grep( /^${lib}_/, keys %rcodes ); + open( OUT, ">$hfile" ) || die "Can't write to $hfile, $!,"; + write_internal_header($lib, \*OUT); + close OUT; + } + if ($hpubinc{$lib} ne 'NONE') { + my $hfile = $hpubinc{$lib}; - # indent level for innermost preprocessor lines - my $indent = " "; + open( OUT, ">$hfile" ) || die "Can't write to $hfile, $!,"; + write_public_header($lib, \*OUT); + close OUT; + } + if ($errorfile{$lib} ne 'NONE') { + my $cfile = $errorfile{$lib}; - # Flag if the sub-library is disablable - # There are a few exceptions, where disabling the sub-library - # doesn't actually remove the whole sub-library, but rather implements - # it with a NULL backend. - my $disablable = - ($lib ne "SSL" && $lib ne "ASYNC" && $lib ne "DSO" - && (grep { $lib eq uc $_ } @disablables, @disablables_int)); + open( OUT, ">$cfile" ) + || die "Can't open $cfile for writing, $!, stopped"; + write_c_source($lib, \*OUT); + close OUT; + } +} - # Rewrite the internal header file if there is one ($internal only!) +&phase("Ending"); +# Make a list of unreferenced reason codes +if ( $unref ) { + my @runref; + foreach ( keys %rcodes ) { + push( @runref, $_ ) unless exists $usedreasons{$_}; + } + if ( @runref ) { + print STDERR "The following reason codes were not referenced:\n"; + foreach ( sort @runref ) { + print STDERR " $_\n"; + } + } +} - if ($hprivinc{$lib} ne 'NONE') { - my $hfile = $hprivinc{$lib}; - my $guard = $hfile; +die "Found $errors errors, quitting" if $errors; - if ($guard =~ m|^include/|) { - $guard = $'; - } else { - $guard = basename($guard); - } - $guard = "OSSL_" . join('_', split(m|[./]|, uc $guard)); +# Update the state file +if ( $newstate ) { + open(OUT, ">$statefile.new") + || die "Can't write $statefile.new, $!"; + print OUT <<"EOF"; +# Copyright 1999-$YEAR The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html +EOF + print OUT "\n#Reason codes\n"; + foreach my $i ( sort keys %rcodes ) { + my $short = "$i:$rcodes{$i}:"; + my $t = exists $strings{$i} ? "$strings{$i}" : ""; + $t = "\\\n\t" . $t if length($short) + length($t) > 80; + print OUT "$short$t\n"; + } + close(OUT); + if ( $skippedstate ) { + print "Skipped state, leaving update in $statefile.new"; + } else { + rename "$statefile", "$statefile.old" + || die "Can't backup $statefile to $statefile.old, $!"; + rename "$statefile.new", "$statefile" + || die "Can't rename $statefile to $statefile.new, $!"; + } +} - open( OUT, ">$hfile" ) || die "Can't write to $hfile, $!,"; - print OUT <<"EOF"; +# Record that the sources have been scanned against the current state; +# the up-to-date check at the top keys on the stamp file. The stamp +# is touched on every completed run, not just null ones, so it is +# always newer than the statefile it vouches for. +if ( !$nowrite && !$reindex && scalar keys %modules == 0 ) { + open(STAMP, ">$statefile.stamp") + || warn "Can't write $statefile.stamp, $!"; + close(STAMP); +} + +exit; + +sub lib_disablable +{ + my $lib = shift; + + # configdata is large and only needed when a file is actually + # written, so it is loaded lazily here rather than at startup. + require configdata; + + # Flag if the sub-library is disablable. + # There are a few exceptions, where disabling the sub-library + # doesn't actually remove the whole sub-library, but rather + # implements it with a NULL backend or keeps part of it: no-http + # still builds http_lib.c for URL parsing, so the HTTP reason + # codes must remain visible. + return do { + # The 'once' warning does not know that require defines these. + no warnings 'once'; + + ($lib ne "SSL" && $lib ne "ASYNC" && $lib ne "DSO" + && $lib ne "HTTP" + && (grep { $lib eq uc $_ } @configdata::disablables, + @configdata::disablables_int)); + }; +} + +# Write the internal header file for $lib ($internal only!) +sub write_internal_header +{ + my ( $lib, $fh ) = @_; + my @reasons = sort grep( /^${lib}_/, keys %rcodes ); + my $disablable = lib_disablable($lib); + my $hfile = $hprivinc{$lib}; + my $guard = $hfile; + + if ($guard =~ m|^include/|) { + $guard = $'; + } else { + $guard = basename($guard); + } + $guard = "OSSL_" . join('_', split(m|[./]|, uc $guard)); + + print $fh <<"EOF"; /* * Generated by util/mkerr.pl DO NOT EDIT * Copyright 2020-$YEAR The OpenSSL Project Authors. All Rights Reserved. @@ -350,75 +531,64 @@ sub help #endif EOF - $indent = ' '; - if ($disablable) { - print OUT <<"EOF"; + my $indent = ' '; + if ($disablable) { + print $fh <<"EOF"; #ifndef OPENSSL_NO_${lib} EOF - $indent = " "; - } - print OUT <<"EOF"; + $indent = " "; + } + print $fh <<"EOF"; int ossl_err_load_${lib}_strings(void); EOF - # If this library doesn't have a public header file, we write all - # definitions that would end up there here instead - if ($hpubinc{$lib} eq 'NONE') { - print OUT "\n/*\n * $lib reason codes.\n */\n"; - foreach my $i ( @reasons ) { - my $z = 48 - length($i); - $z = 0 if $z < 0; - if ( $rcodes{$i} eq "X" ) { - $rassigned{$lib} =~ m/^:([^:]*):/; - my $findcode = $1; - $findcode = $rmax{$lib} if !defined $findcode; - while ( $rassigned{$lib} =~ m/:$findcode:/ ) { - $findcode++; - } - $rcodes{$i} = $findcode; - $rassigned{$lib} .= "$findcode:"; - print STDERR "New Reason code $i\n" if $debug; - } - printf OUT "#define $i $rcodes{$i}\n"; - } - print OUT "\n"; + # If this library doesn't have a public header file, we write all + # definitions that would end up there here instead + if ($hpubinc{$lib} eq 'NONE') { + print $fh "\n/*\n * $lib reason codes.\n */\n"; + foreach my $i ( @reasons ) { + print $fh "#define $i $rcodes{$i}\n"; } + print $fh "\n"; + } - # This doesn't go all the way down to zero, to allow for the ending - # brace for 'extern "C" {'. - while (length($indent) > 1) { - $indent = substr $indent, 0, -1; - print OUT "#endif\n"; - } + # This doesn't go all the way down to zero, to allow for the ending + # brace for 'extern "C" {'. + while (length($indent) > 1) { + $indent = substr $indent, 0, -1; + print $fh "#endif\n"; + } - print OUT <<"EOF"; + print $fh <<"EOF"; #ifdef __cplusplus } #endif #endif EOF - close OUT; - } - - # Rewrite the public header file - - if ($hpubinc{$lib} ne 'NONE') { - my $extra_include = - $internal - ? ($lib ne 'SSL' - ? "#include \n" - : "#include \n") - : ''; - my $hfile = $hpubinc{$lib}; - my $guard = $hfile; - $guard =~ s|^include/||; - $guard = join('_', split(m|[./]|, uc $guard)); - $guard = "OSSL_" . $guard unless $internal; +} - open( OUT, ">$hfile" ) || die "Can't write to $hfile, $!,"; - print OUT <<"EOF"; +# Write the public header file for $lib +sub write_public_header +{ + my ( $lib, $fh ) = @_; + my @reasons = sort grep( /^${lib}_/, keys %rcodes ); + my $disablable = lib_disablable($lib); + my $extra_include = + $internal + ? ($lib ne 'SSL' + ? "#include \n" + : "#include \n") + : ''; + my $hfile = $hpubinc{$lib}; + my $guard = $hfile; + + $guard =~ s|^include/||; + $guard = join('_', split(m|[./]|, uc $guard)); + $guard = "OSSL_" . $guard unless $internal; + + print $fh <<"EOF"; /* * Generated by util/mkerr.pl DO NOT EDIT * Copyright 1995-$YEAR The OpenSSL Project Authors. All Rights Reserved. @@ -437,21 +607,21 @@ sub help #include $extra_include EOF - $indent = ' '; - if ( $internal ) { - if ($disablable) { - print OUT <<"EOF"; + my $indent = ' '; + if ( $internal ) { + if ($disablable) { + print $fh <<"EOF"; #ifndef OPENSSL_NO_${lib} EOF - $indent .= ' '; - } - } else { - print OUT <<"EOF"; + $indent .= ' '; + } + } else { + print $fh <<"EOF"; #define ${lib}err(f, r) ERR_${lib}_error(0, (r), OPENSSL_FILE, OPENSSL_LINE) #define ERR_R_${lib}_LIB ERR_${lib}_lib() EOF - if ( ! $static ) { - print OUT <<"EOF"; + if ( ! $static ) { + print $fh <<"EOF"; #ifdef __cplusplus extern \"C\" { @@ -463,66 +633,52 @@ sub help } #endif EOF - } } + } - print OUT "/*\n * $lib reason codes.\n */\n"; - foreach my $i ( @reasons ) { - my $z = 48 - length($i); - $z = 0 if $z < 0; - if ( $rcodes{$i} eq "X" ) { - $rassigned{$lib} =~ m/^:([^:]*):/; - my $findcode = $1; - $findcode = $rmax{$lib} if !defined $findcode; - while ( $rassigned{$lib} =~ m/:$findcode:/ ) { - $findcode++; - } - $rcodes{$i} = $findcode; - $rassigned{$lib} .= "$findcode:"; - print STDERR "New Reason code $i\n" if $debug; - } - printf OUT "#define $i $rcodes{$i}\n"; - } - print OUT "\n"; - - while (length($indent) > 0) { - $indent = substr $indent, 0, -1; - print OUT "#endif\n"; - } - close OUT; + print $fh "/*\n * $lib reason codes.\n */\n"; + foreach my $i ( @reasons ) { + print $fh "#define $i $rcodes{$i}\n"; } + print $fh "\n"; - # Rewrite the C source file containing the error details. + while (length($indent) > 0) { + $indent = substr $indent, 0, -1; + print $fh "#endif\n"; + } +} - if ($errorfile{$lib} ne 'NONE') { - # First, read any existing reason string definitions: - my $cfile = $errorfile{$lib}; - my $pack_lib = $internal ? "ERR_LIB_${lib}" : "0"; - my $hpubincf = $hpubinc{$lib}; - my $hprivincf = $hprivinc{$lib}; - my $includes = ''; - if ($internal) { - if ($hpubincf ne 'NONE') { - $hpubincf =~ s|^include/||; - $includes .= "#include <${hpubincf}>\n"; - } - if ($hprivincf =~ m|^include/|) { - $hprivincf = $'; - } else { - $hprivincf = abs2rel(rel2abs($hprivincf), - rel2abs(dirname($cfile))); - } - $includes .= "#include \"${hprivincf}\"\n"; +# Write the C source file containing the error details for $lib +sub write_c_source +{ + my ( $lib, $fh ) = @_; + my @reasons = sort grep( /^${lib}_/, keys %rcodes ); + my $disablable = lib_disablable($lib); + my $cfile = $errorfile{$lib}; + my $pack_lib = $internal ? "ERR_LIB_${lib}" : "0"; + my $hpubincf = $hpubinc{$lib}; + my $hprivincf = $hprivinc{$lib}; + my $includes = ''; + + if ($internal) { + if ($hpubincf ne 'NONE') { + $hpubincf =~ s|^include/||; + $includes .= "#include <${hpubincf}>\n"; + } + if ($hprivincf =~ m|^include/|) { + $hprivincf = $'; } else { - $includes .= "#include \"${hpubincf}\"\n"; + $hprivincf = abs2rel(rel2abs($hprivincf), + rel2abs(dirname($cfile))); } + $includes .= "#include \"${hprivincf}\"\n"; + } else { + $includes .= "#include \"${hpubincf}\"\n"; + } - open( OUT, ">$cfile" ) - || die "Can't open $cfile for writing, $!, stopped"; - - my $const = $internal ? 'const ' : ''; + my $const = $internal ? 'const ' : ''; - print OUT <<"EOF"; + print $fh <<"EOF"; /* * Generated by util/mkerr.pl DO NOT EDIT * Copyright 1995-$YEAR The OpenSSL Project Authors. All Rights Reserved. @@ -536,48 +692,50 @@ sub help #include $includes EOF - $indent = ''; - if ( $internal ) { - if ($disablable) { - print OUT <<"EOF"; + my $indent = ''; + if ( $internal ) { + if ($disablable) { + print $fh <<"EOF"; #ifndef OPENSSL_NO_${lib} EOF - $indent .= ' '; - } + $indent .= ' '; } - print OUT <<"EOF"; + } + print $fh <<"EOF"; #ifndef OPENSSL_NO_ERR static ${const}ERR_STRING_DATA ${lib}_str_reasons[] = { EOF - # Add each reason code. - foreach my $i ( @reasons ) { - my $rn; - if ( exists $strings{$i} ) { - $rn = $strings{$i}; - $rn = "" if $rn eq '*'; - } else { - $i =~ /^${lib}_R_(\S+)$/; - $rn = $1; - $rn =~ tr/_[A-Z]/ [a-z]/; - $strings{$i} = $rn; - } - my $lines; - $lines = " { ERR_PACK($pack_lib, 0, $i), \"$rn\" },"; - $lines = " { ERR_PACK($pack_lib, 0, $i),\n \"$rn\" }," - if length($lines) > 82; - print OUT "$lines\n"; + # Add each reason code. + foreach my $i ( @reasons ) { + my $rn; + + if ( exists $strings{$i} ) { + $rn = $strings{$i}; + $rn = "" if $rn eq '*'; + } else { + $i =~ /^${lib}_R_(\S+)$/; + $rn = $1; + $rn =~ tr/_[A-Z]/ [a-z]/; + $strings{$i} = $rn; } - print OUT <<"EOF"; + my $lines; + + $lines = " { ERR_PACK($pack_lib, 0, $i), \"$rn\" },"; + $lines = " { ERR_PACK($pack_lib, 0, $i),\n \"$rn\" }," + if length($lines) > 82; + print $fh "$lines\n"; + } + print $fh <<"EOF"; { 0, NULL } }; #endif EOF - if ( $internal ) { - print OUT <<"EOF"; + if ( $internal ) { + print $fh <<"EOF"; int ossl_err_load_${lib}_strings(void) { @@ -588,9 +746,10 @@ sub help return 1; } EOF - } else { - my $st = $static ? "static " : ""; - print OUT <<"EOF"; + } else { + my $st = $static ? "static " : ""; + + print $fh <<"EOF"; static int lib_code = 0; static int error_loaded = 0; @@ -635,68 +794,17 @@ sub help } EOF - } + } - while (length($indent) > 1) { - $indent = substr $indent, 0, -1; - print OUT "#endif\n"; - } - if ($internal && $disablable) { - print OUT <<"EOF"; + while (length($indent) > 1) { + $indent = substr $indent, 0, -1; + print $fh "#endif\n"; + } + if ($internal && $disablable) { + print $fh <<"EOF"; #else NON_EMPTY_TRANSLATION_UNIT #endif EOF - } - close OUT; } } - -&phase("Ending"); -# Make a list of unreferenced reason codes -if ( $unref ) { - my @runref; - foreach ( keys %rcodes ) { - push( @runref, $_ ) unless exists $usedreasons{$_}; - } - if ( @runref ) { - print STDERR "The following reason codes were not referenced:\n"; - foreach ( sort @runref ) { - print STDERR " $_\n"; - } - } -} - -die "Found $errors errors, quitting" if $errors; - -# Update the state file -if ( $newstate ) { - open(OUT, ">$statefile.new") - || die "Can't write $statefile.new, $!"; - print OUT <<"EOF"; -# Copyright 1999-$YEAR The OpenSSL Project Authors. All Rights Reserved. -# -# Licensed under the Apache License 2.0 (the "License"). You may not use -# this file except in compliance with the License. You can obtain a copy -# in the file LICENSE in the source distribution or at -# https://www.openssl.org/source/license.html -EOF - print OUT "\n#Reason codes\n"; - foreach my $i ( sort keys %rcodes ) { - my $short = "$i:$rcodes{$i}:"; - my $t = exists $strings{$i} ? "$strings{$i}" : ""; - $t = "\\\n\t" . $t if length($short) + length($t) > 80; - print OUT "$short$t\n"; - } - close(OUT); - if ( $skippedstate ) { - print "Skipped state, leaving update in $statefile.new"; - } else { - rename "$statefile", "$statefile.old" - || die "Can't backup $statefile to $statefile.old, $!"; - rename "$statefile.new", "$statefile" - || die "Can't rename $statefile to $statefile.new, $!"; - } -} - -exit; diff --git a/util/mknum.pl b/util/mknum.pl index 8c978dfe2dc52..7d821e2075656 100644 --- a/util/mknum.pl +++ b/util/mknum.pl @@ -1,6 +1,6 @@ #! /usr/bin/env perl -# Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2018-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -39,6 +39,29 @@ die "Please supply ordinals file\n" unless $ordinals_file; +# The ordinals file is rewritten on every run, so its timestamp +# records the last completed run. While it is newer than the symbol +# hacking file and every header given, the last run saw the tree in +# its current state and re-parsing would change nothing; skip it. +# Modes that exist to report or to renumber always run. +unless ($checkexist || $renumber || $verbose || $debug) { + my $stamp = (stat $ordinals_file)[9]; + + if (defined $stamp) { + my $uptodate = 1; + + foreach my $f (($symhacks_file // (), @ARGV)) { + my $mtime = (stat $f)[9]; + + if (!defined $mtime || $mtime >= $stamp) { + $uptodate = 0; + last; + } + } + exit 0 if $uptodate; + } +} + my $ordinals = OpenSSL::Ordinals->new(from => $ordinals_file, warnings => $warnings, verbose => $verbose, diff --git a/util/mkpod2html.pl b/util/mkpod2html.pl index ea1164d597c9e..d23ee4b2eaac7 100755 --- a/util/mkpod2html.pl +++ b/util/mkpod2html.pl @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2020-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -11,51 +11,169 @@ use lib "."; use Getopt::Std; +use File::Basename; use Pod::Html; use File::Spec::Functions qw(:DEFAULT rel2abs); +# With -i, convert the one named pod, which is what the per-page rules and +# the other build systems do. Without it, convert every pod named on the +# command line, deriving each output from the pod's own path. Pod::Html is +# expensive to compile and OpenSSL has over nine hundred pages, so loading +# it once and dividing the pages between a few forked workers is far +# cheaper than starting this program once per page. + # Options. -our($opt_i); # -i INFILE -our($opt_o); # -o OUTFILE -our($opt_t); # -t TITLE -our($opt_r); # -r PODROOT +our ($opt_i); # -i INFILE, one page; without it, pods are read from @ARGV +our ($opt_o); # -o OUTFILE with -i, otherwise the directory to write into +our ($opt_t); # -t TITLE, only with -i +our ($opt_r); # -r PODROOT +our ($opt_j); # -j JOBS, only without -i -getopts('i:o:t:r:'); -die "-i flag missing" unless $opt_i; +getopts('i:o:t:r:j:'); die "-o flag missing" unless $opt_o; -die "-t flag missing" unless $opt_t; die "-r flag missing" unless $opt_r; # We originally used realpath() here, but the Windows implementation appears # to require that the directory or file exist to be able to process the input, # so we use rel2abs() instead, which only processes the string without # looking further. -$opt_i = rel2abs($opt_i) or die "Can't convert to real path: $!"; -$opt_o = rel2abs($opt_o) or die "Can't convert to real path: $!"; -$opt_r = rel2abs($opt_r) or die "Can't convert to real path: $!"; - -pod2html - "--infile=$opt_i", - "--outfile=$opt_o", - "--title=$opt_t", - "--podroot=$opt_r", - "--podpath=man1:man3:man5:man7", - "--htmldir=.."; - -# Read in contents. -open F, "<$opt_o" - or die "Can't read $opt_o, $!"; -my $contents = ''; +my $podroot = rel2abs($opt_r) or die "Can't convert to real path: $!"; + +sub cpu_count +{ + my $cpus = $ENV{"NUMBER_OF_PROCESSORS"}; # Windows sets this. + + if (!defined($cpus) && $^O =~ /linux/) { + my $tmp = qx(nproc 2>/dev/null); + + $cpus = $tmp if $? == 0 && $tmp > 0; + } + if (!defined($cpus) && -r "/proc/cpuinfo") { + my $tmp = qx(grep -c ^processor /proc/cpuinfo 2>/dev/null); + + $cpus = $tmp if $? == 0 && $tmp > 0; + } + if (!defined($cpus)) { + my $tmp = qx(sysctl -n hw.ncpu 2>/dev/null); # BSDs, macOS + + $cpus = $tmp if $? == 0 && $tmp > 0; + } + + return defined($cpus) && $cpus > 0 ? int($cpus) : 1; +} + +# Turn one pod into one HTML page. +sub format_page +{ + my ($pod, $out, $title) = @_; + + $pod = rel2abs($pod) or die "Can't convert to real path: $!"; + $out = rel2abs($out) or die "Can't convert to real path: $!"; + + unlink $out; + + pod2html "--infile=$pod", + "--outfile=$out", + "--title=$title", + "--podroot=$podroot", + "--podpath=man1:man3:man5:man7", + "--htmldir=.."; + + # Read in contents. + open my $fh, "<", $out + or die "Can't read $out, $!"; + my $contents = do { local $/ = undef; <$fh> }; + close $fh; + unlink $out; + + $contents =~ + s|href="http://man\.he\.net/(man\d/[^"]+)(?:\.html)?"|href="../$1.html"|g; + open $fh, ">", $out + or die "Can't write $out, $!"; + print $fh $contents; + close $fh; + + chmod 0444, $out + or die "Can't set the mode of $out, $!\n"; +} + +# One named page: the output file and title are given. +if (defined $opt_i) { + die "-t flag missing" unless $opt_t; + format_page($opt_i, $opt_o, $opt_t); + exit 0; +} + +# Otherwise every pod named on the command line, with $opt_o the directory +# holding the man1..man7 subdirectories: doc/man3/BIO_s_mem.pod becomes +# $opt_o/man3/BIO_s_mem.html, titled BIO_s_mem. +sub page_of +{ + my $pod = shift; + my $name = basename($pod, ".pod"); + my ($section) = basename(dirname($pod)) =~ m|^man(\d)$|; + + die "Can't tell the section of $pod from its directory\n" + unless defined $section; + + return ("$opt_o/man$section/$name.html", $name); +} + +my @pods = @ARGV; + +exit 0 unless @pods; + +# Only ask how many processors there are when the answer can matter; the +# count is found by running a command. +my $jobs = @pods > 1 + ? (defined $opt_j && $opt_j > 0 ? int($opt_j) : cpu_count()) + : 1; + +$jobs = scalar @pods if $jobs > @pods; + +sub format_pods { - local $/ = undef; - $contents = ; -} -close F; -unlink $opt_o; - -$contents =~ - s|href="http://man\.he\.net/(man\d/[^"]+)(?:\.html)?"|href="../$1.html"|g; -open F, ">$opt_o" - or die "Can't write $opt_o, $!"; -print F $contents; -close F; + foreach my $pod (@_) { + my ($out, $title) = page_of($pod); + + # The page is current when it is newer than the pod it comes from. + next if -e $out && -M $out < -M $pod; + + format_page($pod, $out, $title); + } +} + +if ($jobs <= 1) { + format_pods(@pods); + exit 0; +} + +my @pids; + +foreach my $worker (0 .. $jobs - 1) { + my $pid = fork(); + + die "Can't fork, $!\n" unless defined $pid; + if (!$pid) { + # Deal every $jobs'th page to this worker. The pages differ a lot + # in size, and dealing them out interleaves the large ones instead + # of handing one worker a contiguous run of them. + my @mine; + + for (my $i = $worker; $i <= $#pods; $i += $jobs) { + push @mine, $pods[$i]; + } + format_pods(@mine); + exit 0; + } + push @pids, $pid; +} + +my $failed = 0; + +foreach my $pid (@pids) { + waitpid($pid, 0); + $failed = 1 if $?; +} + +die "Failed to convert the manual pages to HTML\n" if $failed; diff --git a/util/mkpod2man.pl b/util/mkpod2man.pl new file mode 100644 index 0000000000000..778dc2b091808 --- /dev/null +++ b/util/mkpod2man.pl @@ -0,0 +1,136 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; +use warnings; + +use Getopt::Std; +use File::Basename; +use Pod::Man; + +# Format man pages without loading Pod::Man once per page. pod2man is a +# perl program that compiles Pod::Man before it reads a single pod, and +# OpenSSL has over nine hundred pages, so running it once per page spends +# most of that time compiling the same module again and again. Here the +# module is loaded once and the pages are then divided between a few +# forked workers, which inherit it already compiled. + +# Options. The whole manual is formatted in one run, so the section of +# each page is taken from the directory its pod lives in rather than +# given on the command line: doc/man3/BIO_s_mem.pod is section 3 and +# becomes OUTDIR/man3/BIO_s_mem.3. +our ($opt_o); # -o OUTDIR, the directory holding the man1..man7 dirs +our ($opt_m); # -m MANSUFFIX, appended to the section inside the page +our ($opt_d); # -d DATE +our ($opt_r); # -r RELEASE +our ($opt_j); # -j JOBS + +getopts('o:m:d:r:j:'); +die "-o flag missing" unless defined $opt_o; +$opt_m = '' unless defined $opt_m; +$opt_d = '' unless defined $opt_d; +$opt_r = '' unless defined $opt_r; + +sub cpu_count +{ + my $cpus = $ENV{"NUMBER_OF_PROCESSORS"}; # Windows sets this. + + if (!defined($cpus) && $^O =~ /linux/) { + my $tmp = qx(nproc 2>/dev/null); + + $cpus = $tmp if $? == 0 && $tmp > 0; + } + if (!defined($cpus) && -r "/proc/cpuinfo") { + my $tmp = qx(grep -c ^processor /proc/cpuinfo 2>/dev/null); + + $cpus = $tmp if $? == 0 && $tmp > 0; + } + if (!defined($cpus)) { + my $tmp = qx(sysctl -n hw.ncpu 2>/dev/null); # BSDs, macOS + + $cpus = $tmp if $? == 0 && $tmp > 0; + } + + return defined($cpus) && $cpus > 0 ? int($cpus) : 1; +} + +# Turn one pod into one man page. +sub format_page +{ + my $pod = shift; + my $name = basename($pod, ".pod"); + my $dir = basename(dirname($pod)); + my ($section) = $dir =~ m|^man(\d)$|; + + die "Can't tell the section of $pod from its directory\n" + unless defined $section; + + my $out = "$opt_o/man$section/$name.$section"; + + # The page is current when it is newer than the pod it comes from. + return if -e $out && -M $out < -M $pod; + + unlink $out; + + Pod::Man->new(name => uc $name, + section => "$section$opt_m", + center => "OpenSSL", + date => $opt_d, + release => $opt_r) + ->parse_from_file($pod, $out); + + chmod 0444, $out + or die "Can't set the mode of $out, $!\n"; +} + +my @pods = @ARGV; + +exit 0 unless @pods; + +# Only ask how many processors there are when the answer can matter; +# the count is found by running a command, and the per-page rules call +# this script with a single pod. +my $jobs = @pods > 1 + ? (defined $opt_j && $opt_j > 0 ? int($opt_j) : cpu_count()) + : 1; + +$jobs = scalar @pods if $jobs > @pods; + +# One page, or no reason to fork: do the work here. This is also the path +# taken where fork() is emulated and would cost more than it saves. +if ($jobs <= 1) { + format_page($_) foreach @pods; + exit 0; +} + +my @pids; + +foreach my $worker (0 .. $jobs - 1) { + my $pid = fork(); + + die "Can't fork, $!\n" unless defined $pid; + if (!$pid) { + # Deal every $jobs'th page to this worker. The pages differ a lot + # in size, and dealing them out interleaves the large ones instead + # of handing one worker a contiguous run of them. + for (my $i = $worker; $i <= $#pods; $i += $jobs) { + format_page($pods[$i]); + } + exit 0; + } + push @pids, $pid; +} + +my $failed = 0; + +foreach my $pid (@pids) { + waitpid($pid, 0); + $failed = 1 if $?; +} + +die "Failed to format the manual pages\n" if $failed; diff --git a/util/mkwraps.pl b/util/mkwraps.pl index d7e8bcb7dbfdd..91a44cbb3fd1e 100755 --- a/util/mkwraps.pl +++ b/util/mkwraps.pl @@ -18,6 +18,8 @@ my @extra_includes; my $output_file; my $mode = 'both'; +my $cc; +my $use_system = 1; my $verbose = 0; my $help = 0; @@ -26,10 +28,14 @@ 'include=s' => \@extra_includes, 'output=s' => \$output_file, 'mode=s' => \$mode, + 'cc=s' => \$cc, + 'system!' => \$use_system, 'verbose' => \$verbose, 'help' => \$help) or die "Error in command line arguments\n"; +$cc = $ENV{CC} || 'cc' unless defined $cc; + sub help { print STDERR <<"EOF"; @@ -48,6 +54,14 @@ sub help --mode MODE What to emit: 'wraps', 'expects' or 'both'. Defaults to 'both'. + --cc NAME C compiler used to discover the default system + include search paths. Defaults to \$CC or 'cc'. + + --no-system Do not fall back to the compiler's default system + include directories. By default, functions not + found in the project headers (typically libc/POSIX + functions) are looked up there. + --verbose Print progress to stderr. --help Show this help text. @@ -60,6 +74,12 @@ sub help The first header containing a matching declaration provides the prototype. +Functions not found in those directories (typically system functions +such as read() or socket()) are then looked up under the compiler's +default include search paths, as reported by the C compiler. System +prototypes are emitted with angle-bracket #include directives. Use +--no-system to disable this fallback. + The output is meant as a stub for further editing. Custom logic (out-parameters, variadic forwarding, side effects on globals) still needs to be written manually, and the emitted #include directives may @@ -120,18 +140,20 @@ sub help # Walk all search directories and get them in the order that level ones are # first followed by subdirs so if there are nested includes, we get the -# shortest ones first searched. +# shortest ones first searched. Each base is a [dir, is_system] pair and the +# is_system flag is carried onto every header found beneath it, so that system +# prototypes can later be emitted with angle-bracket includes. sub find_headers { my (@bases) = @_; my @found; - my @queue = map { [$_, ''] } @bases; + my @queue = map { [$_->[0], '', $_->[1]] } @bases; while (@queue) { my @next; my @level_files; foreach my $entry (@queue) { - my ($dir, $rel) = @$entry; + my ($dir, $rel, $sys) = @$entry; next unless -d $dir; opendir(my $dh, $dir) or next; foreach my $name (readdir $dh) { @@ -139,9 +161,9 @@ sub find_headers my $full = catfile($dir, $name); my $newrel = $rel eq '' ? $name : "$rel/$name"; if (-d $full) { - push @next, [$full, $newrel]; + push @next, [$full, $newrel, $sys]; } elsif (-f $full && $name =~ /\.h$/) { - push @level_files, [$full, $newrel]; + push @level_files, [$full, $newrel, $sys]; } } closedir $dh; @@ -153,7 +175,45 @@ sub find_headers return @found; } -my @search_files = find_headers(@search_dirs); +# Ask the C compiler for its default "#include <...>" search paths. Returns +# the list of existing directories, in search order. Empty on failure. +sub system_include_dirs +{ + my ($compiler) = @_; + my $out = `$compiler -xc -E -v /dev/null 2>&1`; + return () unless defined $out + && $out =~ /search starts here:(.*?)End of search list\./s; + my @dirs; + foreach my $line (split /\n/, $1) { + $line =~ s/^\s+//; + $line =~ s/\s+$//; + # clang annotates framework directories; skip those. + next if $line eq '' || $line =~ /\(framework directory\)$/; + push @dirs, $line if -d $line; + } + return @dirs; +} + +# Project headers are searched first (with is_system = 0) so that a project +# declaration always wins over a colliding system one. The system headers are +# appended lazily, only if some function is not found in the project headers. +my @search_files = find_headers(map { [$_, 0] } @search_dirs); +my $system_loaded = 0; + +sub load_system_headers +{ + return if $system_loaded; + $system_loaded = 1; + return unless $use_system; + my @sys_dirs = system_include_dirs($cc); + unless (@sys_dirs) { + warn "WARNING: could not determine system include dirs from '$cc'\n"; + return; + } + print STDERR "System include dirs:\n ", join("\n ", @sys_dirs), "\n" + if $verbose; + push @search_files, find_headers(map { [$_, 1] } @sys_dirs); +} my %file_cache; @@ -184,12 +244,41 @@ sub strip_attribute_macros return $s; } +# Consume reserved-namespace decorations between a declaration's closing +# parenthesis and its semicolon, e.g. glibc's __THROW, __wur or +# __attr_access ((...)). Only __-prefixed tokens (with an optional balanced +# argument list) are eaten, so a genuine following declaration is left alone. +sub skip_trailing_attributes +{ + my $s = shift; + while (1) { + $s =~ s/^\s+//; + last unless $s =~ /^(__\w+)/; + $s = substr($s, length($1)); + $s =~ s/^\s+//; + if ($s =~ /^\(/) { + my $depth = 0; + my $i = 0; + while ($i < length($s)) { + my $c = substr($s, $i, 1); + $depth++ if $c eq '('; + $depth-- if $c eq ')'; + $i++; + last if $depth == 0; + } + return $s if $depth != 0; + $s = substr($s, $i); + } + } + return $s; +} + sub find_function_decl { my ($funcname) = @_; foreach my $entry (@search_files) { - my ($file, $relpath) = @$entry; + my ($file, $relpath, $is_system) = @$entry; unless (exists $file_cache{$file}) { my $text = ''; if (open(my $fh, '<', $file)) { @@ -218,9 +307,10 @@ sub find_function_decl my $params_str = substr($text, $paren_start, $cursor - $paren_start - 1); - # What follows must be ; for this to be a declaration. + # What follows must be ; for this to be a declaration, possibly + # after trailing attribute macros (__THROW, __wur, ...). my $after = substr($text, $cursor); - $after =~ s/^\s+//; + $after = skip_trailing_attributes($after); next unless $after =~ /^;/; # Anything since the previous statement terminator is the return @@ -239,7 +329,8 @@ sub find_function_decl rettype => $rettype, params => $params_str, file => $file, - include_path => $include_path }; + include_path => $include_path, + system => $is_system }; } } return undef; @@ -282,6 +373,9 @@ sub parse_param return { type => '', name => '', is_variadic => 1, is_ptr => 0 } if $param eq '...'; + # Drop the restrict qualifier; it plays no role in a mock signature. + $param =~ s/\b(?:__restrict(?:__)?|restrict)\b//g; + # Reduce TYPE NAME[size] to TYPE * NAME for our purposes. my $is_array = 0; $is_array = 1 if $param =~ s/\[\s*[^\]]*\s*\]\s*$//; @@ -296,6 +390,10 @@ sub parse_param $name = ''; } + # System headers name parameters in the reserved __ namespace; strip the + # leading underscores so the generated wrap uses ordinary local names. + $name =~ s/^_+//; + return { type => $type, name => $name, is_ptr => (($type =~ /\*/) || $is_array) ? 1 : 0, @@ -320,6 +418,11 @@ sub is_void_type my %seen_include; foreach my $func (@wraps) { my $info = find_function_decl($func); + if (!defined $info && !$system_loaded) { + # Not in the project headers: pull in the system ones and retry. + load_system_headers(); + $info = find_function_decl($func); + } unless (defined $info) { warn "WARNING: $func: declaration not found in any include dir\n"; next; @@ -340,7 +443,8 @@ sub is_void_type unless ($seen_include{$info->{include_path}}) { $seen_include{$info->{include_path}} = 1; - push @found_includes, $info->{include_path}; + push @found_includes, { path => $info->{include_path}, + system => $info->{system} }; } print STDERR " found $func in $info->{file}\n" if $verbose; } @@ -369,19 +473,19 @@ sub is_void_type print $out_fh "#include \n"; print $out_fh "\n"; if (@found_includes) { - my @system; + my @angle; my @local; - foreach my $inc (sort @found_includes) { - if ($inc =~ m|^openssl/|) { - push @system, $inc; + foreach my $inc (sort { $a->{path} cmp $b->{path} } @found_includes) { + if ($inc->{system} || $inc->{path} =~ m|^openssl/|) { + push @angle, $inc->{path}; } else { - push @local, $inc; + push @local, $inc->{path}; } } - foreach my $inc (@system) { + foreach my $inc (@angle) { print $out_fh "#include <$inc>\n"; } - print $out_fh "\n" if @system && @local; + print $out_fh "\n" if @angle && @local; foreach my $inc (@local) { print $out_fh "#include \"$inc\"\n"; } diff --git a/util/other.syms b/util/other.syms index 114e25a34850b..9b36384dd807d 100644 --- a/util/other.syms +++ b/util/other.syms @@ -807,6 +807,7 @@ SSL_VALUE_QUIC_WINDOWBSTR define SSL_VALUE_QUIC_WINDOWUSTR define SSL_VALUE_QUIC_ACK_DELAY_EXPONENT define SSL_VALUE_QUIC_ACK_DELAY_MAX define +SSL_VALUE_QUIC_MAX_PENDING_CONNS define SSL_VALUE_QUIC_STREAM_BIDI_LOCAL_AVAIL define SSL_VALUE_QUIC_STREAM_BIDI_REMOTE_AVAIL define SSL_VALUE_QUIC_STREAM_UNI_LOCAL_AVAIL define @@ -818,8 +819,14 @@ SSL_VALUE_EVENT_HANDLING_MODE_EXPLICIT define SSL_VALUE_STREAM_WRITE_BUF_SIZE define SSL_VALUE_STREAM_WRITE_BUF_USED define SSL_VALUE_STREAM_WRITE_BUF_AVAIL define +SSL_VALUE_DTLS_LISTENER_MAX_PENDING_CONNS define +SSL_VALUE_DTLS_LISTENER_PENDING_TIMEOUT define +SSL_VALUE_DTLS_LISTENER_MAX_DGRAM_SIZE define SSL_WRITE_FLAG_CONCLUDE define SSL_LISTENER_FLAG_NO_ACCEPT define +SSL_LISTENER_FLAG_NO_VALIDATE define +SSL_LISTENER_FLAG_SINGLE_THREAD define +SSL_LISTENER_FLAG_ADDRESS_VALIDATION define TLS_DEFAULT_CIPHERSUITES define deprecated 3.0.0 X509_CRL_http_nbio define deprecated 3.0.0 X509_http_nbio define deprecated 3.0.0 diff --git a/util/perl/OpenSSL/Test.pm b/util/perl/OpenSSL/Test.pm index 0cdb41259c90d..9fb0f16e8370a 100644 --- a/util/perl/OpenSSL/Test.pm +++ b/util/perl/OpenSSL/Test.pm @@ -23,7 +23,8 @@ $VERSION = "1.0"; srctop_dir srctop_file data_file data_dir result_file result_dir - pipe with cmdstr + pipe with cmdstr app_fails + slurp_file openssl_versions ok_nofips is_nofips isnt_nofips)); @@ -333,7 +334,7 @@ sub app { $idx=$idx+1; my $resultdir = result_dir(); my $srcdir = srctop_dir(); - return cmd([ "valgrind", "--leak-check=full", "--show-leak-kinds=all", "--gen-suppressions=all", "--suppressions=$srcdir/util/valgrind.suppression", "--log-file=$resultdir/valgrind.log.$idx", "--suppressions=$srcdir/util/valgrind.suppression", @prog, @cmdargs ], + return cmd([ "valgrind", "--leak-check=full", "--show-leak-kinds=all", "--gen-suppressions=all", "--suppressions=$srcdir/util/valgrind.suppression", "--log-file=$resultdir/valgrind.log.$idx.%p", "--suppressions=$srcdir/util/valgrind.suppression", @prog, @cmdargs ], exe_shell => $ENV{EXE_SHELL}, %opts) -> (shift); } else { return cmd([ @prog, @cmdargs ], @@ -363,7 +364,7 @@ sub test { $idx=$idx+1; my $resultdir = result_dir(); my $srcdir = srctop_dir(); - return cmd([ "valgrind", "--leak-check=full", "--show-leak-kinds=all", "--gen-suppressions=all", "--suppressions=$srcdir/util/valgrind.suppression", "--log-file=$resultdir/valgrind.log.$idx", "--suppressions=$srcdir/util/valgrind.suppression", @prog, @cmdargs ], + return cmd([ "valgrind", "--leak-check=full", "--show-leak-kinds=all", "--gen-suppressions=all", "--suppressions=$srcdir/util/valgrind.suppression", "--log-file=$resultdir/valgrind.log.$idx.%p", "--suppressions=$srcdir/util/valgrind.suppression", @prog, @cmdargs ], exe_shell => $ENV{EXE_SHELL}, %opts) -> (shift); } elsif (defined $ENV{OSSL_VALGRIND_CT}) { # Constant-time validation mode: mark secret data as undefined and @@ -510,6 +511,10 @@ sub run { local $_; open($pipe, '-|', "$prefix$cmd") or die "Can't start command: $!"; + # Read line by line, even if a recipe played with $/ (slurp or + # paragraph mode). Otherwise, a bare prefix (or only the first + # line of a multi-line read) would hit the TAP stream unguarded. + local $/ = "\n"; while(<$pipe>) { my $l = ($opts{prefix} // $default_prefix) . $_; if ($opts{capture}) { @@ -833,6 +838,72 @@ sub with { =over 4 +=item B + +C reads back the whole file FILENAME, usually an output +captured with the C or C option of C and its +derivatives, and returns its content as a single string. If the file +cannot be opened, an empty string is returned. + +The following options OPTS are available: + +=over 4 + +=item B 0|1> + +When set to 1, the file is read in binary mode, for example to read +back a DER encoded output. The default is 0, reading in text mode. + +=back + +=back + +=cut + +sub slurp_file { + my ($file, %opts) = @_; + my $content = ''; + + if (open(my $fh, '<', $file)) { + binmode $fh if $opts{binary}; + $content = do { local $/; <$fh> }; + close($fh); + } + return $content; +} + +=over 4 + +=item B + +C runs the C sub-command B with the command +line arguments in LIST, expecting a non-zero (failure) exit status, as a +test named B. If REGEXP is defined, it additionally checks, as +a second test, that the stderr output of the command matches it. + +=back + +=cut + +sub app_fails { + my ($appname, $testtext, $re, @args) = @_; + + my $stderr_file = "app_fails_stderr.txt"; + + with({ exit_checker => sub { return shift != 0; } }, + sub { + ok(run(app(['openssl', $appname, @args], stderr => $stderr_file)), + $testtext); + }); + + if (defined $re) { + ok(slurp_file($stderr_file) =~ $re, "$testtext: stderr matches"); + } + unlink($stderr_file) if -f $stderr_file; +} + +=over 4 + =item B C takes a CODEREF from C or C and simply returns the @@ -1325,11 +1396,13 @@ sub __decorate_cmd { my $display_cmd = "$cmdstr$stdin$stdout$stderr"; - # VMS program output escapes TAP::Parser - if ($^O eq 'VMS') { - $stderr=" 2> ".$null - unless $stderr || !$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}; - } + # Under a non-verbose harness nothing drains the command's stderr, so a + # chatty command can fill the pipe buffer and then block forever waiting + # for a reader that never comes. Send it to the null device unless the + # recipe asked for a specific redirection. On VMS this also keeps + # program output from escaping TAP::Parser. + $stderr=" 2> ".$null + unless $stderr || !$ENV{HARNESS_ACTIVE} || $ENV{HARNESS_VERBOSE}; $cmdstr .= "$stdin$stdout$stderr"; diff --git a/util/perl/OpenSSL/copyright.pm b/util/perl/OpenSSL/copyright.pm index 87567c088945e..61c7ddc0eec3d 100644 --- a/util/perl/OpenSSL/copyright.pm +++ b/util/perl/OpenSSL/copyright.pm @@ -1,5 +1,5 @@ #! /usr/bin/env perl -# Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2021-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -8,12 +8,18 @@ use strict; use warnings; +use File::Spec; package OpenSSL::copyright; sub year_of { my $file = shift; + # A generated file is staged as FILE.new before it is compared to, + # and possibly replaces, FILE; the year that belongs to it is the + # year of the file it is staged to replace. + $file =~ s/\.new$//; + return $ENV{'OSSL_COPYRIGHT_YEAR'} if defined $ENV{'OSSL_COPYRIGHT_YEAR'}; # Get the current year. We use that as the default because the other @@ -22,10 +28,11 @@ sub year_of { my $YEAR = [localtime()]->[5] + 1900; # See if git's available + my $devnull = File::Spec->devnull(); open my $FH, - "git log -1 --date=short --format=format:%cd $file 2>/dev/null|" + "git log -1 --date=short --format=format:%cd $file 2>$devnull|" or return $YEAR; - my $LINE = <$FH>; + my $LINE = <$FH> // ''; close $FH; $LINE =~ s/^([0-9]*)-.*/$1/; $YEAR = $LINE if $LINE; diff --git a/util/perl/OpenSSL/paramnames.pm b/util/perl/OpenSSL/paramnames.pm index 328189c7b3abe..749892144a8d7 100644 --- a/util/perl/OpenSSL/paramnames.pm +++ b/util/perl/OpenSSL/paramnames.pm @@ -17,6 +17,7 @@ our @EXPORT_OK = qw(generate_public_macros produce_param_decoder produce_param_decoder_with_count); +our $headers_included = 0; my $case_sensitive = 1; my $need_break = 0; my $invalid_param = "invalid param"; @@ -515,6 +516,7 @@ my %params = ( 'OSSL_SIGNATURE_PARAM_MESSAGE_ENCODING' => "message-encoding", 'OSSL_SIGNATURE_PARAM_DETERMINISTIC' => "deterministic", 'OSSL_SIGNATURE_PARAM_MU' => "mu", # int + 'OSSL_SIGNATURE_PARAM_COMPOSITE_PREHASH' => "composite-prehash", # int 'OSSL_SIGNATURE_PARAM_TEST_ENTROPY' => "test-entropy", 'OSSL_SIGNATURE_PARAM_ADD_RANDOM' => "additional-random", 'OSSL_SIGNATURE_PARAM_TLS_VERSION' => "tls-version", @@ -646,8 +648,12 @@ my %params = ( 'OSSL_LIBSSL_RECORD_LAYER_PARAM_HS_PADDING' => "hs_padding", # Symmetric Key parameters - 'OSSL_SKEY_PARAM_RAW_BYTES' => "raw-bytes", + 'OSSL_SKEY_PARAM_ALIAS' => "skey-alias", + 'OSSL_SKEY_PARAM_ALGORITHM_OID' => "skey-algorithm-oid", + 'OSSL_SKEY_PARAM_ALGORITHM_PARAMS' => "skey-algorithm-params", 'OSSL_SKEY_PARAM_KEY_LENGTH' => "key-length", + 'OSSL_SKEY_PARAM_LOCAL_KEYID' => "skey-local-keyid", + 'OSSL_SKEY_PARAM_RAW_BYTES' => "raw-bytes", ); sub output_ifdef { @@ -699,6 +705,7 @@ sub trie_matched { my $with_count = shift; my $field = shift; my $num = shift; + my $dup = shift; my $indent1 = shift; my $indent2 = shift; @@ -716,9 +723,13 @@ sub trie_matched { printf "%sr->%s[r->num_%s++] = (OSSL_PARAM *)p;\n", $indent1, $field, $field; } else { printf "%sif (ossl_unlikely(r->%s != NULL)) {\n", $indent1, $field; - printf "%sERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,\n", $indent2; - printf "%s \"param %%s is repeated\", s);\n", $indent2; - printf "%sreturn 0;\n", $indent2; + if (defined $dup && $dup eq 'first') { + printf "%sbreak;\n", $indent2; + } else { + printf "%sERR_raise_data(ERR_LIB_PROV, PROV_R_REPEATED_PARAMETER,\n", $indent2; + printf "%s \"param %%s is repeated\", s);\n", $indent2; + printf "%sreturn 0;\n", $indent2; + } printf "%s}\n", $indent1; printf "%s++*count;\n", $indent1 if $with_count; printf "%sr->%s = (OSSL_PARAM *)p;\n", $indent1, $field; @@ -731,6 +742,7 @@ sub generate_decoder_from_trie { my $trieref = shift; my $identmap = shift; my $concat_num = shift; + my $process_dup = shift; my $ifdefs = shift; my $idt = " "; my $indent0 = $idt x ($n + 3); @@ -744,6 +756,7 @@ sub generate_decoder_from_trie { $field = $identmap->{$trieref->{'name'}}; my $num = $concat_num->{$field}; + my $dup = $process_dup->{$field}; output_ifdef($ifdefs->{$field}); printf "%sif (ossl_likely($strcmp(\"$suf\", s + $n) == 0", $indent0; if (not $case_sensitive) { @@ -753,7 +766,7 @@ sub generate_decoder_from_trie { } print ")) {\n"; printf "%s/* %s */\n", $indent1, $trieref->{'name'}; - trie_matched($with_count, $field, $num, $indent1, $indent2); + trie_matched($with_count, $field, $num, $dup, $indent1, $indent2); printf "%s}\n", $indent0; # If this is at the top level and it's conditional, we have to @@ -772,10 +785,11 @@ sub generate_decoder_from_trie { if ($l eq 'val') { $field = $identmap->{$trieref->{'val'}}; my $num = $concat_num->{$field}; + my $dup = $process_dup->{$field}; printf "%sbreak;\n", $indent1; printf "%scase '\\0':\n", $indent0; output_ifdef($ifdefs->{$field}); - trie_matched($with_count, $field, $num, $indent1, $indent2); + trie_matched($with_count, $field, $num, $dup, $indent1, $indent2); output_endifdef($ifdefs->{$field}); } else { printf "%sbreak;\n", $indent1; @@ -785,7 +799,7 @@ sub generate_decoder_from_trie { printf " case '%s':", uc $l if ($l =~ /[a-z]/); } print "\n"; - generate_decoder_from_trie($with_count, $n + 1, $trieref->{$l}, $identmap, $concat_num, $ifdefs); + generate_decoder_from_trie($with_count, $n + 1, $trieref->{$l}, $identmap, $concat_num, $process_dup, $ifdefs); } } if ($need_break) { @@ -862,18 +876,24 @@ sub output_param_decoder { my @keys = (); my %prms = (); my %concat_num = (); + my %process_dup = (); my %ifdefs = (); - print "/* Machine generated by util/perl/OpenSSL/paramnames.pm */\n"; - # IWYU - print "#include \n"; - print "#include \n"; - print "#include \"internal/common.h\"\n"; - print "#include \"prov/proverr.h\"\n"; - print "\n"; + if (!$headers_included) { + $headers_included = 1; + print "/* Machine generated by util/perl/OpenSSL/paramnames.pm */\n"; + # IWYU + print "#include \n"; + print "#include \n"; + print "#include \n"; + print "#include \"internal/common.h\"\n"; + print "#include \"prov/proverr.h\"\n"; + print "\n"; + } + print "/* Machine generated */\n"; # Output gettable param array printf "#ifndef %s_list\n", $decoder_name_base; - printf "static const OSSL_PARAM %s_list[] = {\n", $decoder_name_base; + printf "static ossl_unused const OSSL_PARAM %s_list[] = {\n", $decoder_name_base; for (my $i = 0; $i <= $#params; $i++) { my $pname = $params[$i][0]; my $pident = $params[$i][1]; @@ -897,6 +917,10 @@ sub output_param_decoder { } elsif (substr($pnum, 0, 3) eq '#if') { # Trim the `#if' from the front $ifdefs{$pident} = substr($pnum, 3); + } elsif ($pnum =~ '^duplicate: *(first)') { + # This provides a provision for other duplicate resolution methods + # even though they aren't implemented yet + $process_dup{$pident} = $1; } elsif (not defined $concat_num{$pident}) { $concat_num{$pident} = $pnum; } @@ -944,7 +968,7 @@ sub output_param_decoder { locate_long_endings(\%t); printf "#ifndef %s_decoder\n", $decoder_name_base; - printf "static int %s_decoder\n", $decoder_name_base; + printf "static ossl_unused int %s_decoder\n", $decoder_name_base; printf " (const OSSL_PARAM *p, struct %s_st *r", $decoder_name_base; printf "%s)\n", ($with_count ? ", int *count" : ""); print "{\n"; @@ -953,7 +977,7 @@ sub output_param_decoder { print " memset(r, 0, sizeof(*r));\n"; print " if (p != NULL)\n"; print " for (; (s = p->key) != NULL; p++)\n"; - generate_decoder_from_trie($with_count, 0, \%t, \%prms, \%concat_num, \%ifdefs); + generate_decoder_from_trie($with_count, 0, \%t, \%prms, \%concat_num, \%process_dup, \%ifdefs); print " return 1;\n"; print "}\n#endif\n"; print "/* End of machine generated */"; diff --git a/util/perl/TLSProxy/Certificate.pm b/util/perl/TLSProxy/Certificate.pm index 6d4fe0f326a3f..356674b878059 100644 --- a/util/perl/TLSProxy/Certificate.pm +++ b/util/perl/TLSProxy/Certificate.pm @@ -26,7 +26,7 @@ sub new my ($isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, @@ -38,7 +38,7 @@ sub new $server, TLSProxy::Message::MT_CERTIFICATE(), $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, diff --git a/util/perl/TLSProxy/CertificateRequest.pm b/util/perl/TLSProxy/CertificateRequest.pm index adb98dc523984..87d360c03cf6e 100644 --- a/util/perl/TLSProxy/CertificateRequest.pm +++ b/util/perl/TLSProxy/CertificateRequest.pm @@ -1,4 +1,4 @@ -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -18,7 +18,7 @@ sub new my ($isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, @@ -30,7 +30,7 @@ sub new $server, TLSProxy::Message::MT_CERTIFICATE_REQUEST(), $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, diff --git a/util/perl/TLSProxy/CertificateVerify.pm b/util/perl/TLSProxy/CertificateVerify.pm index 8940a240cb6a1..5a9ca86098be4 100644 --- a/util/perl/TLSProxy/CertificateVerify.pm +++ b/util/perl/TLSProxy/CertificateVerify.pm @@ -1,4 +1,4 @@ -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -18,7 +18,7 @@ sub new my ($isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, @@ -30,7 +30,7 @@ sub new $server, TLSProxy::Message::MT_CERTIFICATE_VERIFY(), $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, diff --git a/util/perl/TLSProxy/ClientHello.pm b/util/perl/TLSProxy/ClientHello.pm index c24065f2b9107..3d1f3652ed3a1 100644 --- a/util/perl/TLSProxy/ClientHello.pm +++ b/util/perl/TLSProxy/ClientHello.pm @@ -1,4 +1,4 @@ -# Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -20,7 +20,7 @@ sub new my ($isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, @@ -32,7 +32,7 @@ sub new $server, TLSProxy::Message::MT_CLIENT_HELLO, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, diff --git a/util/perl/TLSProxy/EncryptedExtensions.pm b/util/perl/TLSProxy/EncryptedExtensions.pm index 9eb73dd3324f4..ac6f42c44d917 100644 --- a/util/perl/TLSProxy/EncryptedExtensions.pm +++ b/util/perl/TLSProxy/EncryptedExtensions.pm @@ -18,7 +18,7 @@ sub new my ($isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, @@ -30,7 +30,7 @@ sub new $server, TLSProxy::Message::MT_ENCRYPTED_EXTENSIONS(), $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, diff --git a/util/perl/TLSProxy/HelloVerifyRequest.pm b/util/perl/TLSProxy/HelloVerifyRequest.pm index 6fa7f1ac617d2..41cabd8441d3e 100644 --- a/util/perl/TLSProxy/HelloVerifyRequest.pm +++ b/util/perl/TLSProxy/HelloVerifyRequest.pm @@ -1,4 +1,4 @@ -# Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -21,7 +21,7 @@ sub new my ($isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, @@ -33,7 +33,7 @@ sub new $server, TLSProxy::Message::MT_HELLO_VERIFY_REQUEST, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, diff --git a/util/perl/TLSProxy/Message.pm b/util/perl/TLSProxy/Message.pm index 4c1ba50de4831..45c4d9872b740 100644 --- a/util/perl/TLSProxy/Message.pm +++ b/util/perl/TLSProxy/Message.pm @@ -9,6 +9,7 @@ use strict; package TLSProxy::Message; +use TLSProxy::RecordNumber; use TLSProxy::Alert; use constant DTLS_MESSAGE_HEADER_LENGTH => 12; @@ -21,6 +22,7 @@ use constant { MT_SERVER_HELLO => 2, MT_HELLO_VERIFY_REQUEST => 3, MT_NEW_SESSION_TICKET => 4, + MT_END_OF_EARLY_DATA => 5, MT_ENCRYPTED_EXTENSIONS => 8, MT_CERTIFICATE => 11, MT_SERVER_KEY_EXCHANGE => 12, @@ -29,7 +31,10 @@ use constant { MT_CERTIFICATE_VERIFY => 15, MT_CLIENT_KEY_EXCHANGE => 16, MT_FINISHED => 20, + MT_CERTIFICATE_URL => 21, MT_CERTIFICATE_STATUS => 22, + MT_SUPPLEMENTAL_DATA => 23, + MT_KEY_UPDATE => 24, MT_COMPRESSED_CERTIFICATE => 25, MT_NEXT_PROTO => 67 }; @@ -50,8 +55,10 @@ use constant { AL_DESC_DECODE_ERROR => 50, AL_DESC_DECRYPT_ERROR => 51, AL_DESC_PROTOCOL_VERSION => 70, + AL_DESC_INAPPROPRIATE_FALLBACK => 86, AL_DESC_NO_RENEGOTIATION => 100, - AL_DESC_MISSING_EXTENSION => 109 + AL_DESC_MISSING_EXTENSION => 109, + AL_DESC_UNSUPPORTED_EXTENSION => 110 }; my %message_type = ( @@ -151,30 +158,41 @@ use constant { SERVER => 1 }; -my $payload = ""; -my $messlen = -1; -my $mt; -my $startoffset = -1; +# Handshake message reassembly is tracked separately per sender +# (CLIENT/SERVER). The two peers can each have their own in-flight, +# independently fragmented message at the same time, so a fragment that is +# still incomplete for one sender must never be touched by traffic that +# arrives from the other sender. +my @payload = ("", ""); +my @messlen = (-1, -1); +my @messseq = (-1, -1); +my @messfraglen = (-1, -1); +my @messfragoffs = (-1, -1); +my @mt = (undef, undef); +my @startoffset = (-1, -1); my $server = 0; my $success = 0; my $end = 0; -my @message_rec_list = (); -my @message_frag_lens = (); +my @message_rec_list = ([], []); +my @message_frag_lens = ([], []); my $ciphersuite = 0; my $successondata = 0; my $alert; sub clear { - $payload = ""; - $messlen = -1; - $startoffset = -1; + @payload = ("", ""); + @messlen = (-1, -1); + @messseq = (-1, -1); + @messfraglen = (-1, -1); + @messfragoffs = (-1, -1); + @startoffset = (-1, -1); $server = 0; $success = 0; $end = 0; $successondata = 0; - @message_rec_list = (); - @message_frag_lens = (); + @message_rec_list = ([], []); + @message_frag_lens = ([], []); $alert = undef; } @@ -182,21 +200,18 @@ sub clear sub get_messages { my $class = shift; - my $serverin = shift; my $record = shift; - my $isdtls = shift; + my $serverin = $record->serverissender; + my $isdtls = $record->isdtls; my @messages = (); my $message; - @message_frag_lens = (); + $message_frag_lens[$serverin] = []; - if ($serverin != $server && length($payload) != 0) { - die "Changed peer, but we still have fragment data\n"; - } $server = $serverin; if ($record->content_type == TLSProxy::Record::RT_CCS()) { - if ($payload ne "") { + if ($payload[$server] ne "") { #We can't handle this yet die "CCS received before message data complete\n"; } @@ -213,38 +228,55 @@ sub get_messages } else { my $recoffset = 0; - if (length $payload > 0) { + if (length $payload[$server] > 0) { #We are continuing processing a message started in a previous - #record. Add this record to the list associated with this - #message - push @message_rec_list, $record; + #record from this same sender. Add this record to the list + #associated with this message + push @{$message_rec_list[$server]}, $record; - if ($messlen <= length($payload)) { + if ($messlen[$server] <= length($payload[$server])) { #Shouldn't happen - die "Internal error: invalid messlen: ".$messlen - ." payload length:".length($payload)."\n"; + die "Internal error: invalid messlen: ".$messlen[$server] + ." payload length:".length($payload[$server])."\n"; } - if (length($payload) + $record->decrypt_len >= $messlen) { + if (length($payload[$server]) + $record->decrypt_len >= $messlen[$server]) { #We can complete the message with this record - $recoffset = $messlen - length($payload); - $payload .= substr($record->decrypt_data, 0, $recoffset); - push @message_frag_lens, $recoffset; + $recoffset = $messlen[$server] - length($payload[$server]); + if ($isdtls) { - # We must set $msgseq, $msgfrag, $msgfragoffs - die "Internal error: cannot handle partial dtls messages\n" + # For fragmented messages to be parsed correctly we need to + # skip the handshake header + $payload[$server] .= substr($record->decrypt_data, DTLS_MESSAGE_HEADER_LENGTH, $recoffset); + push @{$message_frag_lens[$server]}, $recoffset; + + # We skipped the handshake header above and we need to + # update recoffset accordingly + $recoffset += DTLS_MESSAGE_HEADER_LENGTH; + } else { + $payload[$server] .= substr($record->decrypt_data, 0, $recoffset); + push @{$message_frag_lens[$server]}, $recoffset; } - $message = create_message($server, $mt, - #$msgseq, $msgfrag, $msgfragoffs, - 0, 0, 0, - $payload, $startoffset, $isdtls); + + + $message = create_message($server, $mt[$server], + $messseq[$server], $messfraglen[$server], $messfragoffs[$server], + $payload[$server], $startoffset[$server], $isdtls); push @messages, $message; - $payload = ""; + $payload[$server] = ""; } else { #This is just part of the total message - $payload .= $record->decrypt_data; - $recoffset = $record->decrypt_len; - push @message_frag_lens, $record->decrypt_len; + if ($isdtls) { + # DTLS 1.3 has a unified header before the handshake header. + # We have processed the unified header and need to skip the + # handshake header. + $payload[$server] .= substr($record->decrypt_data, DTLS_MESSAGE_HEADER_LENGTH, length($record->decrypt_data) - DTLS_MESSAGE_HEADER_LENGTH); + $recoffset = $record->decrypt_len; + } else { + $payload[$server] .= $record->decrypt_data; + $recoffset = $record->decrypt_len; + } + push @{$message_frag_lens[$server]}, $record->decrypt_len; } print " Partial message data read: ".$recoffset." bytes\n"; } @@ -257,52 +289,53 @@ sub get_messages #Whilst technically probably valid we can't cope with this die "End of record in the middle of a message header\n"; } - @message_rec_list = ($record); + $message_rec_list[$server] = [$record]; my $lenhi; my $lenlo; - my $msgseq; - my $msgfrag; - my $msgfragoffs; if ($isdtls) { - my $msgfraghi; - my $msgfraglo; + my $msgfraglenhi; + my $msgfraglenlo; my $msgfragoffshi; my $msgfragoffslo; - ($mt, $lenhi, $lenlo, $msgseq, $msgfraghi, $msgfraglo, $msgfragoffshi, $msgfragoffslo) = + ($mt[$server], $lenhi, $lenlo, $messseq[$server], $msgfragoffshi, $msgfragoffslo, $msgfraglenhi, $msgfraglenlo) = unpack('CnCnnCnC', substr($record->decrypt_data, $recoffset)); - $msgfrag = ($msgfraghi << 8) | $msgfraglo; - $msgfragoffs = ($msgfragoffshi << 8) | $msgfragoffslo; + $messfraglen[$server] = ($msgfraglenhi << 8) | $msgfraglenlo; + $messfragoffs[$server] = ($msgfragoffshi << 8) | $msgfragoffslo; } else { - ($mt, $lenhi, $lenlo) = + ($mt[$server], $lenhi, $lenlo) = unpack('CnC', substr($record->decrypt_data, $recoffset)); } - $messlen = ($lenhi << 8) | $lenlo; - print " Message type: $message_type{$mt}($mt)\n"; - print " Message Length: $messlen\n"; - $startoffset = $recoffset; + $messlen[$server] = ($lenhi << 8) | $lenlo; + print " Message type: $message_type{$mt[$server]}($mt[$server])\n"; + print " Message Length: $messlen[$server]\n"; + if ($isdtls) { + print " Message fragment length: $messfraglen[$server]\n"; + print " Message fragment offset: $messfragoffs[$server]\n"; + } + $startoffset[$server] = $recoffset; $recoffset += $msgheaderlen; - $payload = ""; + $payload[$server] = ""; if ($recoffset <= $record->decrypt_len) { #Some payload data is present in this record - if ($record->decrypt_len - $recoffset >= $messlen) { + if ($record->decrypt_len - $recoffset >= $messlen[$server]) { #We can complete the message with this record - $payload .= substr($record->decrypt_data, $recoffset, - $messlen); - $recoffset += $messlen; - push @message_frag_lens, $messlen; - $message = create_message($server, $mt, $msgseq, - $msgfrag, $msgfragoffs, - $payload, $startoffset, $isdtls); + $payload[$server] .= substr($record->decrypt_data, $recoffset, + $messlen[$server]); + $recoffset += $messlen[$server]; + push @{$message_frag_lens[$server]}, $messlen[$server]; + $message = create_message($server, $mt[$server], $messseq[$server], + $messfraglen[$server], $messfragoffs[$server], + $payload[$server], $startoffset[$server], $isdtls); push @messages, $message; - $payload = ""; + $payload[$server] = ""; } else { #This is just part of the total message - $payload .= substr($record->decrypt_data, $recoffset, + $payload[$server] .= substr($record->decrypt_data, $recoffset, $record->decrypt_len - $recoffset); $recoffset = $record->decrypt_len; - push @message_frag_lens, $recoffset; + push @{$message_frag_lens[$server]}, $recoffset; } } } @@ -342,7 +375,7 @@ sub get_messages #construct it sub create_message { - my ($server, $mt, $msgseq, $msgfrag, $msgfragoffs, $data, $startoffset, $isdtls) = @_; + my ($server, $mt, $msgseq, $msgfraglen, $msgfragoffs, $data, $startoffset, $isdtls) = @_; my $message; if ($mt == MT_CLIENT_HELLO) { @@ -350,12 +383,12 @@ sub create_message $isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, - [@message_rec_list], + [@{$message_rec_list[$server]}], $startoffset, - [@message_frag_lens] + [@{$message_frag_lens[$server]}] ); $message->parse(); } elsif ($mt == MT_SERVER_HELLO) { @@ -363,12 +396,12 @@ sub create_message $isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, - [@message_rec_list], + [@{$message_rec_list[$server]}], $startoffset, - [@message_frag_lens] + [@{$message_frag_lens[$server]}] ); $message->parse(); } elsif ($mt == MT_HELLO_VERIFY_REQUEST) { @@ -376,12 +409,12 @@ sub create_message $isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, - [@message_rec_list], + [@{$message_rec_list[$server]}], $startoffset, - [@message_frag_lens] + [@{$message_frag_lens[$server]}] ); $message->parse(); } elsif ($mt == MT_ENCRYPTED_EXTENSIONS) { @@ -389,12 +422,12 @@ sub create_message $isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, - [@message_rec_list], + [@{$message_rec_list[$server]}], $startoffset, - [@message_frag_lens] + [@{$message_frag_lens[$server]}] ); $message->parse(); } elsif ($mt == MT_CERTIFICATE) { @@ -402,12 +435,12 @@ sub create_message $isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, - [@message_rec_list], + [@{$message_rec_list[$server]}], $startoffset, - [@message_frag_lens] + [@{$message_frag_lens[$server]}] ); $message->parse(); } elsif ($mt == MT_CERTIFICATE_REQUEST) { @@ -415,12 +448,12 @@ sub create_message $isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, - [@message_rec_list], + [@{$message_rec_list[$server]}], $startoffset, - [@message_frag_lens] + [@{$message_frag_lens[$server]}] ); $message->parse(); } elsif ($mt == MT_CERTIFICATE_VERIFY) { @@ -428,12 +461,12 @@ sub create_message $isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, - [@message_rec_list], + [@{$message_rec_list[$server]}], $startoffset, - [@message_frag_lens] + [@{$message_frag_lens[$server]}] ); $message->parse(); } elsif ($mt == MT_SERVER_KEY_EXCHANGE) { @@ -441,12 +474,12 @@ sub create_message $isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, - [@message_rec_list], + [@{$message_rec_list[$server]}], $startoffset, - [@message_frag_lens] + [@{$message_frag_lens[$server]}] ); $message->parse(); } elsif ($mt == MT_NEW_SESSION_TICKET) { @@ -454,20 +487,20 @@ sub create_message $message = TLSProxy::NewSessionTicket->new_dtls( $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, - [@message_rec_list], + [@{$message_rec_list[$server]}], $startoffset, - [@message_frag_lens] + [@{$message_frag_lens[$server]}] ); } else { $message = TLSProxy::NewSessionTicket->new( $server, $data, - [@message_rec_list], + [@{$message_rec_list[$server]}], $startoffset, - [@message_frag_lens] + [@{$message_frag_lens[$server]}] ); } $message->parse(); @@ -476,12 +509,12 @@ sub create_message $isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, - [@message_rec_list], + [@{$message_rec_list[$server]}], $startoffset, - [@message_frag_lens] + [@{$message_frag_lens[$server]}] ); $message->parse(); } else { @@ -491,12 +524,12 @@ sub create_message $server, $mt, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, - [@message_rec_list], + [@{$message_rec_list[$server]}], $startoffset, - [@message_frag_lens] + [@{$message_frag_lens[$server]}] ); } @@ -531,7 +564,7 @@ sub new $server, $mt, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, @@ -545,7 +578,7 @@ sub new records => $records, mt => $mt, msgseq => $msgseq, - msgfrag => $msgfrag, + msgfraglen => $msgfraglen, msgfragoffs => $msgfragoffs, startoffset => $startoffset, message_frag_lens => $message_frag_lens, @@ -579,14 +612,21 @@ sub repack my $lenhi = length($self->data) >> 8; if ($self->{isdtls}) { - my $msgfraghi = $self->msgfrag >> 8; - my $msgfraglo = $self->msgfrag & 0xff; + my $msgfraglenhi = $self->msgfraglen >> 8; + my $msgfraglenlo = $self->msgfraglen & 0xff; my $msgfragoffshi = $self->msgfragoffs >> 8; my $msgfragoffslo = $self->msgfragoffs & 0xff; + if (length($self->data) != $self->msgfraglen) { + # TLSProxy does not support message fragmentation hence we can just + # overwrite the fragment lengths + $msgfraglenhi = $lenhi; + $msgfraglenlo = $lenlo; + print "DTLS Message Fragment Length overwritten with actual message size.\n" + } $msgdata = pack('CnCnnCnC', $self->mt, $lenhi, $lenlo, $self->msgseq, - $msgfraghi, $msgfraglo, - $msgfragoffshi, $msgfragoffslo).$self->data; + $msgfragoffshi, $msgfragoffslo, + $msgfraglenhi, $msgfraglenlo).$self->data; } else { $msgdata = pack('CnC', $self->mt, $lenhi, $lenlo).$self->data; } @@ -637,7 +677,8 @@ sub repack $data .= pack("C", $macval); } - if ($rec->version() >= TLSProxy::Record::VERS_TLS_1_1()) { + if ((!$self->{isdtls} && $rec->version() >= TLSProxy::Record::VERS_TLS_1_1()) + || ($self->{isdtls} && $rec->version() <= TLSProxy::Record::VERS_DTLS_1())) { #Explicit IV $data = ("\0"x16).$data; } @@ -707,13 +748,13 @@ sub msgseq } return $self->{msgseq}; } -sub msgfrag +sub msgfraglen { my $self = shift; if (@_) { - $self->{msgfrag} = shift; + $self->{msgfraglen} = shift; } - return $self->{msgfrag}; + return $self->{msgfraglen}; } sub msgfragoffs { diff --git a/util/perl/TLSProxy/NewSessionTicket.pm b/util/perl/TLSProxy/NewSessionTicket.pm index 801a9f63a2b17..071c86953708d 100644 --- a/util/perl/TLSProxy/NewSessionTicket.pm +++ b/util/perl/TLSProxy/NewSessionTicket.pm @@ -1,4 +1,4 @@ -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -18,7 +18,7 @@ sub new_dtls my ($server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, @@ -29,7 +29,7 @@ sub new_dtls 1, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, @@ -66,7 +66,7 @@ sub init{ my ($isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, @@ -78,7 +78,7 @@ sub init{ $server, TLSProxy::Message::MT_NEW_SESSION_TICKET(), $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, diff --git a/util/perl/TLSProxy/Proxy.pm b/util/perl/TLSProxy/Proxy.pm index 5ba6579ed3d8d..bcd8fd5e7bb79 100644 --- a/util/perl/TLSProxy/Proxy.pm +++ b/util/perl/TLSProxy/Proxy.pm @@ -11,6 +11,7 @@ use POSIX ":sys_wait_h"; package TLSProxy::Proxy; use File::Spec; +use File::Temp qw/tempfile/; use IO::Socket; use IO::Select; use TLSProxy::Record; @@ -99,23 +100,6 @@ sub new_dtls { sub init { - my $useSockInet = 0; - eval { - require IO::Socket::IP; - my $s = IO::Socket::IP->new( - LocalAddr => "::1", - LocalPort => 0, - Listen=>1, - ); - $s or die "\n"; - $s->close(); - }; - if ($@ eq "") { - require IO::Socket::IP; - } else { - $useSockInet = 1; - } - my $class = shift; my ($filter, $execute, @@ -125,62 +109,26 @@ sub init $use_IPv6) = @_; $use_IPv6 //= $have_IPv6; - my $test_client_port; - - # Sometimes, our random selection of client ports gets unlucky - # And we randomly select a port that's already in use. This causes - # this test to fail, so lets harden ourselves against that by doing - # a test bind to the randomly selected port, and only continue once we - # find a port that's available. - my $test_client_addr = $use_IPv6 ? "[::1]" : "127.0.0.1"; - my $found_port = 0; - for (my $i = 0; $i <= 10; $i++) { - $test_client_port = 49152 + int(rand(65535 - 49152)); - my $test_sock; - if ($use_IPv6 == 0 || $useINET6 == 0) { - if ($useSockInet == 0) { - $test_sock = IO::Socket::IP->new(LocalPort => $test_client_port, - LocalAddr => $test_client_addr); - } else { - $test_sock = IO::Socket::INET->new(LocalAddr => $test_client_addr, - LocalPort => $test_client_port); - } - } else { - $test_sock = IO::Socket::INET6->new(LocalAddr => $test_client_addr, - LocalPort => $test_client_port, - Domain => AF_INET6); - } - if ($test_sock) { - $found_port = 1; - $test_sock->close(); - print "Found available client port ${test_client_port}\n"; - last; - } - print "Port ${test_client_port} in use - $@\n"; - } - - if ($found_port == 0) { - die "Unable to find usable port for TLSProxy"; - } - my $self = { #Public read/write - proxy_addr => $test_client_addr, - client_addr => $test_client_addr, + proxy_addr => $use_IPv6 ? "[::1]" : "127.0.0.1", filter => $filter, serverflags => "", clientflags => "", serverconnects => 1, reneg => 0, sessionfile => undef, + expected_tickets => 2, #Public read isdtls => $isdtls, proxy_port => 0, - client_port => $test_client_port, server_port => 0, serverpid => 0, clientpid => 0, + clientexit => 0, + clientoutput => "", + client_alerts => [], execute => $execute, cert => $cert, debug => $debug, @@ -193,6 +141,7 @@ sub init partial => ["", ""], record_list => [], message_list => [], + seen_msgseq => {}, }; return bless $self, $class; @@ -216,9 +165,14 @@ sub clearClient $self->{partial} = ["", ""]; $self->{record_list} = []; $self->{message_list} = []; + $self->{seen_msgseq} = {}; $self->{clientflags} = ""; $self->{sessionfile} = undef; + $self->{expected_tickets} = 2; $self->{clientpid} = 0; + $self->{clientexit} = 0; + $self->{clientoutput} = ""; + $self->{client_alerts} = []; $is_tls13 = 0; $ciphersuite = undef; @@ -292,17 +246,17 @@ sub start # Create the Proxy socket my $proxaddr = $self->{proxy_addr}; $proxaddr =~ s/[\[\]]//g; # Remove [ and ] - my $clientaddr = $self->{client_addr}; - $clientaddr =~ s/[\[\]]//g; # Remove [ and ] my @proxyargs; if ($self->{isdtls}) { + # The socket is left unconnected: the client's address and port are + # learned from the first datagram it sends and remembered for + # sending back the server's flights. That way the client's port is + # picked (race free) by the kernel rather than by us. @proxyargs = ( LocalHost => $proxaddr, LocalPort => 0, - PeerHost => $clientaddr, - PeerPort => $self->{client_port}, Proto => "udp", ); } else { @@ -348,7 +302,7 @@ sub start } if ($self->{isdtls}) { - $execcmd .= " -dtls -max_protocol DTLSv1.2" + $execcmd .= " -dtls -max_protocol DTLSv1.3" # TLSProxy does not support message fragmentation. So # set a high mtu and fingers crossed. ." -mtu 1500"; @@ -370,10 +324,23 @@ sub start open(my $savedin, "<&STDIN"); - # Temporarily replace STDIN so that sink process can inherit it... - open(STDIN, "$^X -e 'sleep(10)' |") if $self->{isdtls}; + # DTLS s_server exits when its stdin reaches EOF, so it needs one that + # stays open for as long as the test does. Give it the read end of a + # pipe and keep the write end here; closing that in clientstart() is + # what lets it finish. + my $stdin_holder; + if ($self->{isdtls}) { + my $rd; + + # A previous run that died before its teardown may have left one. + close($self->{stdin_holder}) if defined($self->{stdin_holder}); + pipe($rd, $stdin_holder) or die "Failed to create stdin pipe: $!\n"; + open(STDIN, "<&", $rd) or die "Failed to replace STDIN: $!\n"; + close($rd); + } $pid = open(STDIN, "$execcmd 2>&1 |") or die "Failed to $execcmd: $!\n"; $self->{real_serverpid} = $pid; + $self->{stdin_holder} = $stdin_holder; # Process the output from s_server until we find the ACCEPT line, which # tells us what the accepting address and port are. @@ -443,15 +410,12 @@ sub clientstart my $pid; my $execcmd = $self->execute ." s_client -provider=p_ossltest -provider=default -propquery ?provider=p_ossltest" - ." -connect $self->{proxy_addr}:$self->{proxy_port}"; + ." -state -connect $self->{proxy_addr}:$self->{proxy_port}"; if ($self->{isdtls}) { - $execcmd .= " -dtls -max_protocol DTLSv1.2" + $execcmd .= " -dtls -max_protocol DTLSv1.3" # TLSProxy does not support message fragmentation. So # set a high mtu and fingers crossed. - ." -mtu 1500" - # UDP has no "accept" for sockets which means we need to - # know were to send data back to. - ." -bind $self->{client_addr}:$self->{client_port}"; + ." -mtu 1500"; } else { $execcmd .= " -max_protocol TLSv1.3"; } @@ -474,11 +438,20 @@ sub clientstart print STDERR "Client command: $execcmd\n"; } + # Capture s_client's stdout+stderr so it can be inspected after exit + # (see clientoutput/client_alerts). The open() below only wires the + # client's stdin. The file is created in the test results directory + # (the current working directory during a test run). + my (undef, $capturefile) = tempfile("client-XXXXXX", + DIR => File::Spec->curdir, + SUFFIX => ".out", OPEN => 0); + $self->{clientcapture} = $capturefile; + open(my $savedout, ">&STDOUT"); # If we open pipe with new descriptor, attempt to close it, # explicitly or implicitly, would incur waitpid and effectively # dead-lock... - if (!($pid = open(STDOUT, "| $execcmd"))) { + if (!($pid = open(STDOUT, "| $execcmd >\"$capturefile\" 2>&1"))) { my $err = $!; kill(3, $self->{real_serverpid}); die "Failed to $execcmd: $err\n"; @@ -502,7 +475,12 @@ sub clientstart my $client_sock; if($self->{isdtls}) { - $client_sock = $self->{proxy_sock} + # The proxy socket is unconnected; the client's address is learned + # from the datagrams it sends (see client_sockaddr below). A new + # s_client (with a fresh kernel-assigned port) may connect on each + # clientstart(), so forget any previous peer. + $client_sock = $self->{proxy_sock}; + $self->{client_sockaddr} = undef; } elsif (!($client_sock = $self->{proxy_sock}->accept())) { warn "Failed accepting incoming connection: $!\n"; return 0; @@ -519,17 +497,41 @@ sub clientstart my $ctr = 0; local $SIG{PIPE} = "IGNORE"; $self->{saw_session_ticket} = undef; - while($fdset->count && $ctr < 10) { + $self->{session_ticket_seq} = []; + $self->{saw_session_ticket_ack} = {}; + $self->{server_epoch} = 0; + $self->{server_sequence_number} = 0; + $self->{client_epoch} = 0; + $self->{client_sequence_number} = 0; + + while($fdset->count && $ctr < 50) { if (defined($self->{sessionfile})) { # s_client got -ign_eof and won't be exiting voluntarily, so we # look for data *and* session ticket... last if TLSProxy::Message->success() - && $self->{saw_session_ticket}; + && $self->handshake_complete() == 1; } - if (!(@ready = $fdset->can_read(1))) { - last if TLSProxy::Message->success() - && $self->{saw_session_ticket}; + # For DTLS, check exit conditions BEFORE calling can_read/sysread + # to avoid blocking on a socket where the peer has closed. + # Once we have the session ticket and have seen the end of the + # message stream (close_notify), we're done. + if ($self->{isdtls}) { + my $success_flag = TLSProxy::Message->success(); + my $handshake_done = $self->handshake_complete(); + my $msg_end = TLSProxy::Message->end(); + if (($success_flag && $handshake_done == 1) || ($handshake_done == 1 && $msg_end)) { + last; + } + } + + if (!(@ready = $fdset->can_read(0.1))) { + my $success_flag = TLSProxy::Message->success(); + my $handshake_done = $self->handshake_complete(); + my $msg_end = TLSProxy::Message->end(); + if ($success_flag && $handshake_done == 1) { + last; + } $ctr++; next; } @@ -537,22 +539,52 @@ sub clientstart if ($hand == $server_sock) { if ($server_sock->sysread($indata, 16384)) { if ($indata = $self->process_packet(1, $indata)) { - $client_sock->syswrite($indata) or goto END; + if (!$self->client_syswrite($client_sock, $indata)) { + # For DTLS/UDP, syswrite failure after handshake completion + # is not necessarily an error - the client may have already + # sent close_notify and exited. Unlike TCP, UDP is + # connectionless so we can't rely on socket state. + if (!$self->{isdtls} || $self->handshake_complete() != 1) { + goto END; + } + } } $ctr = 0; } else { - $fdset->remove($server_sock); - $client_sock->shutdown(SHUT_WR); + # For DTLS/UDP, sysread returning 0 doesn't mean the connection + # is closed like it does for TCP. For TCP, 0 means EOF/FIN + # received. For UDP, it may just mean no data available. + # Skip the shutdown logic for DTLS to avoid prematurely + # closing the connection. + if (!$self->{isdtls}) { + $fdset->remove($server_sock); + $client_sock->shutdown(SHUT_WR); + } } } elsif ($hand == $client_sock) { - if ($client_sock->sysread($indata, 16384)) { + if ($self->client_sysread($client_sock, \$indata)) { if ($indata = $self->process_packet(0, $indata)) { - $server_sock->syswrite($indata) or goto END; + if (!$server_sock->syswrite($indata)) { + # For DTLS/UDP, syswrite failure after handshake completion + # is not necessarily an error - the server may have already + # sent close_notify and exited. Unlike TCP, UDP is + # connectionless so we can't rely on socket state. + if (!$self->{isdtls} || $self->handshake_complete() != 1) { + goto END; + } + } } $ctr = 0; } else { - $fdset->remove($client_sock); - $server_sock->shutdown(SHUT_WR); + # For DTLS/UDP, sysread returning 0 doesn't mean the connection + # is closed like it does for TCP. For TCP, 0 means EOF/FIN + # received. For UDP, it may just mean no data available. + # Skip the shutdown logic for DTLS to avoid prematurely + # closing the connection. + if (!$self->{isdtls}) { + $fdset->remove($client_sock); + $server_sock->shutdown(SHUT_WR); + } } } else { kill(3, $self->{real_serverpid}); @@ -561,7 +593,7 @@ sub clientstart } } - if ($ctr >= 10) { + if ($ctr >= 50) { kill(3, $self->{real_serverpid}); print "No progress made\n"; $success = 0; @@ -570,16 +602,37 @@ sub clientstart END: print "Connection closed\n"; if($server_sock) { + if ($self->{isdtls} && $self->is_tls13()) { + my $alert_message = $self->construct_alert_message($self->{client_epoch}, $self->{client_sequence_number} + 1); + $server_sock->syswrite($alert_message) or warn "Failed to send close_notify alert: $!\n"; + } $server_sock->close(); $self->{server_sock} = undef; } if($client_sock) { + # For DTLSv1.3 tests that are using sessionfile we need to send a close_notify + # this is because closing the socket does not result in a FIN being sent as in TCP. + if ($self->{isdtls} && $self->is_tls13() && defined($self->{sessionfile})) { + my $alert_message = $self->construct_alert_message($self->{server_epoch}, $self->{server_sequence_number} + 1); + $self->client_syswrite($client_sock, $alert_message) + or warn "Failed to send close_notify alert: $!\n"; + } + #Closing this also kills the child process - $client_sock->close(); + if (!$self->{isdtls}) { + $client_sock->close(); + } } my $pid; if (--$self->{serverconnects} == 0) { + # Let a DTLS s_server see EOF on its stdin, so that it exits and the + # sink process reading its output finishes too. This has to happen + # before either is waited for. + if (defined($self->{stdin_holder})) { + close($self->{stdin_holder}); + $self->{stdin_holder} = undef; + } $pid = $self->{serverpid}; print "Waiting for 'perl -ne print' process to close: $pid...\n"; $pid = waitpid($pid, 0); @@ -593,6 +646,7 @@ sub clientstart print "Waiting for s_server process to close: $pid...\n"; # it's done already, just collect the exit code [and reap]... waitpid($pid, 0); + die "exit code $? from s_server process\n" if $? != 0; } else { # It's a bit counter-intuitive spot to make next connection to @@ -604,27 +658,133 @@ sub clientstart $pid = $self->{clientpid}; print "Waiting for s_client process to close: $pid...\n"; waitpid($pid, 0); + $self->{clientexit} = $?; + + # Slurp and parse the captured s_client output + if (defined $self->{clientcapture}) { + if (open(my $fh, '<', $self->{clientcapture})) { + local $/; + $self->{clientoutput} = <$fh>; + close($fh); + } + unlink $self->{clientcapture}; + $self->{clientcapture} = undef; + print STDERR $self->{clientoutput} if $self->debug; + $self->{client_alerts} = _parse_alerts($self->{clientoutput}); + } return $success; } +# Read data sent by the client. For DTLS the proxy socket is unconnected, +# so recv() is used and the sender's address is remembered as the +# destination for datagrams sent back to the client. +sub client_sysread +{ + my ($self, $client_sock, $dataref) = @_; + + if (!$self->{isdtls}) { + return $client_sock->sysread($$dataref, 16384); + } + + my $peer = $client_sock->recv($$dataref, 16384, 0); + return undef if !defined $peer; + $self->{client_sockaddr} = $peer; + return length($$dataref); +} + +# Send data to the client, using the address it last sent from in the DTLS +# case. +sub client_syswrite +{ + my ($self, $client_sock, $data) = @_; + + if (!$self->{isdtls}) { + return $client_sock->syswrite($data); + } + + if (!defined $self->{client_sockaddr}) { + warn "Cannot send to client: no datagram received from it yet\n"; + return undef; + } + + return $client_sock->send($data, 0, $self->{client_sockaddr}); +} + +sub construct_alert_message +{ + my ($self, $epoch, $sequence_number) = @_; + + die "construct_alert_message only valid for DTLSv1.3 tests\n" + if !$self->{isdtls} || !$self->is_tls13(); + + my $alert_level = pack("C", 1); # Warning (1) + my $alert_description = pack("C", 0); # close_notify (0) + my $alert_payload = $alert_level.$alert_description; + + if ($epoch == 0) { + # Epoch 0 uses DTLSPlaintext. + my $seqhi = ($sequence_number >> 32) & 0xffff; + my $seqmi = ($sequence_number >> 16) & 0xffff; + my $seqlo = ($sequence_number >> 0) & 0xffff; + + return pack("C", 21). # Alert (21) + pack("n", 0xFEFD). # legacy version DTLS 1.2 + pack("n", $epoch). + pack('nnn', $seqhi, $seqmi, $seqlo). + pack("n", length($alert_payload)). + $alert_payload; + } + + # Keyed epochs use DTLSCiphertext. The p_ossltest cipher leaves the + # payload unchanged and does not verify the tag. The inner plaintext + # holds close_notify and its content type; a zero tag follows. + # The header uses a 16 bit sequence number and a length field. Mask the + # sequence number with the first two payload bytes, as in Record.pm. + my $payload = $alert_payload.pack("C", 21).("\x00" x 16); + my $maskhi = unpack("n", substr($payload, 0, 2)); + my $seqlo = ($sequence_number & 0xffff) ^ $maskhi; + my $first = 0x20 | 0x08 | 0x04 | ($epoch & 0x03); + + return pack("C", $first). + pack("n", $seqlo). + pack("n", length($payload)). + $payload; +} + +# Parse alerts logged by s_client's -msg message callback, e.g. +# >>> DTLS 1.2, Alert [length 0002], fatal unexpected_message +# ">>>" is an alert we sent, "<<<" one we received. Returns a list of +# { direction => 'sent'|'recv', level, name } hashrefs. +sub _parse_alerts +{ + my $output = shift; + my @alerts; + + foreach my $line (split /\n/, $output) { + next unless $line =~ /^(>>>|<<<) .+, Alert \[length [0-9a-f]+\], (warning|fatal) (\S+)$/; + push @alerts, { + direction => ($1 eq '>>>') ? 'sent' : 'recv', + level => $2, + name => $3, + }; + } + return \@alerts; +} + sub process_packet { - my ($self, $server, $packet) = @_; - my $len_real; - my $decrypt_len; - my $data; - my $recnum; + my ($self, $serverissender, $packet) = @_; - if ($server) { + if ($serverissender) { print "Received server packet\n"; } else { print "Received client packet\n"; } - if ($self->{direction} != $server) { + if ($self->{direction} != $serverissender) { $self->{flight} = $self->{flight} + 1; - $self->{direction} = $server; + $self->{direction} = $serverissender; } print "Packet length = ".length($packet)."\n"; @@ -632,13 +792,21 @@ sub process_packet #Return contains the list of record found in the packet followed by the #list of messages in those records and any partial message - my @ret = TLSProxy::Record->get_records($server, $self->flight, - $self->{partial}[$server].$packet, + my @ret = TLSProxy::Record->get_records($serverissender, $self->flight, + $self->{partial}[$serverissender].$packet, $self->{isdtls}); - $self->{partial}[$server] = $ret[2]; + $self->{partial}[$serverissender] = $ret[2]; push @{$self->{record_list}}, @{$ret[0]}; - push @{$self->{message_list}}, @{$ret[1]}; + if ($self->{isdtls}) { + foreach my $msg (@{$ret[1]}) { + my $key = $msg->server . ":" . $msg->msgseq; + push @{$self->{message_list}}, $msg + unless $self->{seen_msgseq}{$key}++; + } + } else { + push @{$self->{message_list}}, @{$ret[1]}; + } print "\n"; @@ -655,6 +823,20 @@ sub process_packet foreach my $message (reverse @{$self->{message_list}}) { if ($message->{mt} == TLSProxy::Message::MT_NEW_SESSION_TICKET) { $self->{saw_session_ticket} = 1; + # Obtain the most recent sequence number of the record + # that contained the NewSessionTicket message + if ($self->{isdtls} && $self->is_tls13()) { + foreach my $record (@{$message->{records}}) { + if (@{$self->{session_ticket_seq}} == 0) { + push @{$self->{session_ticket_seq}}, TLSProxy::RecordNumber->new($record->epoch, $record->seq); + } elsif (scalar(@{$self->{session_ticket_seq}}) != $self->{expected_tickets}) { + my $match = $self->find_session_ticket_ack($record->epoch, $record->seq); + if ($match == -1) { + push @{$self->{session_ticket_seq}}, TLSProxy::RecordNumber->new($record->epoch, $record->seq); + } + } + } + } last; } } @@ -662,7 +844,25 @@ sub process_packet #Reconstruct the packet $packet = ""; foreach my $record (@{$self->record_list}) { - $packet .= $record->reconstruct_record($server); + $packet .= $record->reconstruct_record($serverissender); + + # After we have set the saw_session_ticket flag, we can check if we have + # seen a session ticket ack. This is only relevant for DTLSv1.3 + if ($self->{isdtls} && $self->is_tls13()) { + $self->seen_session_ticket_ack($record); + + my $epoch_key = $serverissender ? 'server_epoch' : 'client_epoch'; + my $seq_key = $serverissender ? 'server_sequence_number' : 'client_sequence_number'; + my $rec_epoch = $record->epoch(); + my $rec_seq = $record->seq(); + + if ($rec_epoch > $self->{$epoch_key}) { + $self->{$epoch_key} = $rec_epoch; + $self->{$seq_key} = $rec_seq; + } elsif ($rec_epoch == $self->{$epoch_key} && $rec_seq > $self->{$seq_key}) { + $self->{$seq_key} = $rec_seq; + } + } } print "Forwarded packet length = ".length($packet)."\n\n"; @@ -670,6 +870,74 @@ sub process_packet return $packet; } +sub seen_session_ticket_ack +{ + my $self = shift; + my $record = shift; + + my $ack_hash = $self->{saw_session_ticket_ack}; + return if !$self->{saw_session_ticket} + || scalar(keys %{$ack_hash}) == $self->{expected_tickets}; + return if $record->content_type() != TLSProxy::Record::RT_ACK; + + my @record_numbers = (); + $record->get_actual_acked_record_numbers(\@record_numbers); + my $ticket_seq = $self->{session_ticket_seq}; + + foreach my $record_number (@record_numbers) { + my $epoch = $record_number->epoch(); + my $seqnum = $record_number->seqnum(); + my $key = "$epoch:$seqnum"; + next if exists $ack_hash->{$key}; + + my $match = $self->find_session_ticket_ack($epoch, $seqnum); + + if ($match != -1) { + my $session_ticket = splice(@{$ticket_seq}, $match, 1); + $ack_hash->{$key} = $session_ticket; + last if scalar(keys %{$ack_hash}) == $self->{expected_tickets}; + } + } +} + +sub find_session_ticket_ack +{ + my $self = shift; + my $record_number_epoch = shift; + my $record_number_seqnum = shift; + + my $tickets = $self->{session_ticket_seq}; + for (my $i = 0; $i < @{$tickets}; $i++) { + my $ticket = $tickets->[$i]; + if ($record_number_epoch == $ticket->epoch() && + $record_number_seqnum == $ticket->seqnum()) { + return $i; + } + } + + return -1; +} + +sub handshake_complete +{ + my $self = shift; + my $res = 0; + + if ($self->{isdtls} && $self->is_tls13() && defined($self->{sessionfile})) { + # The handshake is complete once every expected NewSessionTicket + # (2 by default, but only 1 follows a resumption) has been acked + if (scalar(keys %{$self->{saw_session_ticket_ack}}) == $self->{expected_tickets}) { + $res = 1; + } + } else { + if ($self->{saw_session_ticket}) { + $res = 1; + } + } + + return $res; +} + #Read accessors sub execute { @@ -741,6 +1009,45 @@ sub clientpid my $self = shift; return $self->{clientpid}; } +sub clientexit +{ + my $self = shift; + return $self->{clientexit}; +} +# True only if s_client exited cleanly (i.e. was not killed by a signal) with +# a non-zero status, meaning it rejected the connection rather than crashing. +sub client_failed +{ + my $self = shift; + my $status = $self->{clientexit}; + return 0 if ($status & 127) != 0; + return ($status >> 8) != 0; +} +# Raw captured s_client stdout+stderr from the last run. +sub clientoutput +{ + my $self = shift; + return $self->{clientoutput}; +} +# Arrayref of all alerts parsed from the s_client -msg output. +sub client_alerts +{ + my $self = shift; + return $self->{client_alerts}; +} +# True if s_client locally generated the named fatal alert (e.g. +# "unexpected_message"). Requires -msg in clientflags. Reflects the alert +# s_client generated regardless of whether the peer ever received it. +sub client_sent_fatal_alert +{ + my ($self, $name) = @_; + foreach my $alert (@{$self->{client_alerts}}) { + return 1 if $alert->{direction} eq 'sent' + && $alert->{level} eq 'fatal' + && $alert->{name} eq $name; + } + return 0; +} #Read/write accessors sub filter @@ -863,6 +1170,14 @@ sub sessionfile } return $self->{sessionfile}; } +sub expected_tickets +{ + my $self = shift; + if (@_) { + $self->{expected_tickets} = shift; + } + return $self->{expected_tickets}; +} sub ciphersuite { diff --git a/util/perl/TLSProxy/Record.pm b/util/perl/TLSProxy/Record.pm index b0560fa0e5b04..e99edcbd1f423 100644 --- a/util/perl/TLSProxy/Record.pm +++ b/util/perl/TLSProxy/Record.pm @@ -1,4 +1,4 @@ -# Copyright 2016-2024 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -20,11 +20,16 @@ use constant TLS_RECORD_HEADER_LENGTH => 5; #Record types use constant { - RT_APPLICATION_DATA => 23, - RT_HANDSHAKE => 22, - RT_ALERT => 21, - RT_CCS => 20, - RT_UNKNOWN => 100 + RT_APPLICATION_DATA => 23, + RT_HANDSHAKE => 22, + RT_ALERT => 21, + RT_CCS => 20, + RT_ACK => 26, + RT_UNKNOWN => 100, + RT_DTLS_UNIHDR_EPOCH4 => 0x2c, + RT_DTLS_UNIHDR_EPOCH1 => 0x2d, + RT_DTLS_UNIHDR_EPOCH2 => 0x2e, + RT_DTLS_UNIHDR_EPOCH3 => 0x2f, }; my %record_type = ( @@ -32,10 +37,16 @@ my %record_type = ( RT_HANDSHAKE, "HANDSHAKE", RT_ALERT, "ALERT", RT_CCS, "CCS", - RT_UNKNOWN, "UNKNOWN" + RT_ACK, "ACK", + RT_UNKNOWN, "UNKNOWN", + RT_DTLS_UNIHDR_EPOCH4, "DTLS UNIFIED HEADER (EPOCH 4)", + RT_DTLS_UNIHDR_EPOCH1, "DTLS UNIFIED HEADER (EPOCH 1)", + RT_DTLS_UNIHDR_EPOCH2, "DTLS UNIFIED HEADER (EPOCH 2)", + RT_DTLS_UNIHDR_EPOCH3, "DTLS UNIFIED HEADER (EPOCH 3)", ); use constant { + VERS_DTLS_1_3 => 0xfefc, VERS_DTLS_1_2 => 0xfefd, VERS_DTLS_1 => 0xfeff, VERS_TLS_1_4 => 0x0305, @@ -48,6 +59,7 @@ use constant { }; our %tls_version = ( + VERS_DTLS_1_3, "DTLS1.3", VERS_DTLS_1_2, "DTLS1.2", VERS_DTLS_1, "DTLS1", VERS_TLS_1_3, "TLS1.3", @@ -62,38 +74,83 @@ our %tls_version = ( sub get_records { my $class = shift; - my $server = shift; + my $serverissender = shift; my $flight = shift; my $packet = shift; my $isdtls = shift; my $partial = ""; my @record_list = (); my @message_list = (); - my $record_hdr_len = $isdtls ? DTLS_RECORD_HEADER_LENGTH - : TLS_RECORD_HEADER_LENGTH; my $recnum = 1; while (length ($packet) > 0) { - print " Record $recnum ", $server ? "(server -> client)\n" - : "(client -> server)\n"; - + print " Record $recnum ", $serverissender ? "(server -> client)\n" + : "(client -> server)\n"; + my $record_hdr_len; my $content_type; my $version; my $len; my $epoch; my $seq; - if ($isdtls) { - my $seqhi; - my $seqmi; - my $seqlo; - #Get the record header (unpack can't fail if $packet is too short) - ($content_type, $version, $epoch, - $seqhi, $seqmi, $seqlo, $len) = unpack('Cnnnnnn', $packet); - $seq = ($seqhi << 32) | ($seqmi << 16) | $seqlo + if ($isdtls == 1) { + my $isunifiedhdr; + + $content_type = unpack('B[8]', $packet); + $isunifiedhdr = substr($content_type, 0, 3) == "001"; + + if ($isunifiedhdr == 1) { + my $cbit = substr($content_type, 3, 1); + my $sbit = substr($content_type, 4, 1); + my $lbit = substr($content_type, 5, 1); + my $eebits = substr($content_type, 6, 2); + + if ($cbit == "1" || $lbit == "0") { + die("TLSProxy does not support variable DTLSv1.3 unified header bits"); + } + + # This is a unified header + if ($sbit == "1") { + ($content_type, $seq, $len) = unpack('Cnn', $packet); + $record_hdr_len = 5; + } else { + ($content_type, $seq, $len) = unpack('CCn', $packet); + $record_hdr_len = 4; + } + # Encrypted DTLS 1.3 records have encrypted sequence numbers. + # ossltest engine overrides ecb encryption to be a no-op. + # This effectively means that the sequence number encryption mask + # is just the 16 first bytes of the record body. + my $recordbody = substr($packet, $record_hdr_len, $len); + (my $maskhi, my $maskmi, my $masklo) = unpack('nnn', $recordbody); + $version = VERS_DTLS_1_2; # DTLSv1.3 headers has DTLSv1.2 in its legacy_version field + + if ($eebits == "00") { + $epoch = 4; # must be at least 4 since 0 epoch are not sent with unified hdr + } elsif ($eebits == "01") { + $epoch = 1; + } elsif ($eebits == "10") { + $epoch = 2; + } elsif ($eebits == "11") { + $epoch = 3; + } else { + die("Epoch bits is not 0's or 1's: should not happen") + } + $seq ^= $maskhi; + } else { + my $seqhi; + my $seqmi; + my $seqlo; + #Get the record header (unpack can't fail if $packet is too short) + ($content_type, $version, $epoch, + $seqhi, $seqmi, $seqlo, $len) = unpack('Cnnnnnn', $packet); + $seq = ($seqhi << 32) | ($seqmi << 16) | $seqlo; + $record_hdr_len = DTLS_RECORD_HEADER_LENGTH; + } } else { #Get the record header (unpack can't fail if $packet is too short) ($content_type, $version, $len) = unpack('Cnn', $packet); + $record_hdr_len = TLS_RECORD_HEADER_LENGTH; } if (length($packet) < $record_hdr_len + ($len // 0)) { @@ -106,7 +163,7 @@ sub get_records print " Content type: ".$record_type{$content_type}."\n"; print " Version: $tls_version{$version}\n"; - if($isdtls) { + if($isdtls == 1) { print " Epoch: $epoch\n"; print " Sequence: $seq\n"; } @@ -115,6 +172,7 @@ sub get_records my $record; if ($isdtls) { $record = TLSProxy::Record->new_dtls( + $serverissender, $flight, $content_type, $version, @@ -128,6 +186,7 @@ sub get_records ); } else { $record = TLSProxy::Record->new( + $serverissender, $flight, $content_type, $version, @@ -142,8 +201,8 @@ sub get_records if ($content_type != RT_CCS && (!TLSProxy::Proxy->is_tls13() || $content_type != RT_ALERT)) { - if (($server && $server_encrypting) - || (!$server && $client_encrypting)) { + if (($serverissender && $server_encrypting) + || (!$serverissender && $client_encrypting)) { if (!TLSProxy::Proxy->is_tls13() && $etm) { $record->decryptETM(); } else { @@ -154,6 +213,7 @@ sub get_records if (TLSProxy::Proxy->is_tls13()) { print " Inner content type: " .$record_type{$record->content_type()}."\n"; + print " Data: ".unpack("n",$record->decrypt_data)."\n"; } } } @@ -161,7 +221,7 @@ sub get_records push @record_list, $record; #Now figure out what messages are contained within this record - my @messages = TLSProxy::Message->get_messages($server, $record, $isdtls); + my @messages = TLSProxy::Message->get_messages($record); push @message_list, @messages; $packet = substr($packet, $record_hdr_len + $len); @@ -207,7 +267,8 @@ sub etm sub new_dtls { my $class = shift; - my ($flight, + my ($serverissender, + $flight, $content_type, $version, $epoch, @@ -217,7 +278,8 @@ sub new_dtls $decrypt_len, $data, $decrypt_data) = @_; - return $class->init(1, + return $class->init($serverissender, + 1, $flight, $content_type, $version, @@ -233,7 +295,8 @@ sub new_dtls sub new { my $class = shift; - my ($flight, + my ($serverissender, + $flight, $content_type, $version, $len, @@ -242,6 +305,7 @@ sub new $data, $decrypt_data) = @_; return $class->init( + $serverissender, 0, $flight, $content_type, @@ -258,7 +322,8 @@ sub new sub init { my $class = shift; - my ($isdtls, + my ($serverissender, + $isdtls, $flight, $content_type, $version, @@ -271,6 +336,7 @@ sub init $decrypt_data) = @_; my $self = { + serverissender => $serverissender, isdtls => $isdtls, flight => $flight, content_type => $content_type, @@ -285,7 +351,7 @@ sub init orig_decrypt_data => $decrypt_data, sent => 0, encrypted => 0, - outer_content_type => RT_APPLICATION_DATA + outer_content_type => $content_type, }; return bless $self, $class; @@ -298,7 +364,8 @@ sub decryptETM my $data = $self->data; - if($self->version >= VERS_TLS_1_1()) { + if((!$self->{isdtls} && $self->version >= VERS_TLS_1_1) + || ($self->{isdtls} && $self->version <= VERS_DTLS_1)) { #TLS1.1+ has an explicit IV. Throw it away $data = substr($data, 16); } @@ -340,7 +407,8 @@ sub decrypt() return $data if (length($data) == 2); } $mactaglen = 16; - } elsif ($self->version >= VERS_TLS_1_1()) { + } elsif ((!$self->{isdtls} && $self->version() >= VERS_TLS_1_1) + || ($self->{isdtls} && $self->version() <= VERS_DTLS_1)) { #16 bytes for a standard IV $data = substr($data, 16); @@ -380,21 +448,26 @@ sub reconstruct_record } $self->{sent} = 1; + my $content_type = (TLSProxy::Proxy->is_tls13() && $self->encrypted) + ? $self->outer_content_type : $self->content_type; if($self->{isdtls}) { my $seqhi = ($self->seq >> 32) & 0xffff; my $seqmi = ($self->seq >> 16) & 0xffff; my $seqlo = ($self->seq >> 0) & 0xffff; - $data = pack('Cnnnnnn', $self->content_type, $self->version, - $self->epoch, $seqhi, $seqmi, $seqlo, $self->len); - } else { + if (TLSProxy::Proxy->is_tls13() && $self->encrypted) { - $data = pack('Cnn', $self->outer_content_type, $self->version, - $self->len); - } - else { - $data = pack('Cnn', $self->content_type, $self->version, - $self->len); + # Mask sequence number with record body bytes. Explanation + # given in get_records. + (my $maskhi, my $maskmi, my $masklo) = unpack("nnn", $self->data); + $seqlo ^= $maskhi; + # Prepare a unified header + $data = pack('Cnn', $content_type, $seqlo, $self->len); + } else { + $data = pack('Cnnnnnn', $content_type, $self->version, + $self->epoch, $seqhi, $seqmi, $seqlo, $self->len); } + } else { + $data = pack('Cnn', $content_type, $self->version, $self->len); } $data .= $self->data; @@ -402,7 +475,45 @@ sub reconstruct_record return $data; } +sub get_actual_acked_record_numbers +{ + my $self = shift; + my $record_numbers = shift; + + if ($self->content_type == TLSProxy::Record::RT_ACK) { + my $recnum_count = unpack('n', $self->decrypt_data) / 16; + my $ptr = 2; + + for (my $idx = 0; $idx < $recnum_count; $idx++) { + my $epoch_lo; + my $epoch_hi; + my $msgseq_lo; + my $msgseq_hi; + + ($epoch_hi, $epoch_lo, $msgseq_hi, $msgseq_lo) + = unpack('NNNN', substr($self->decrypt_data, $ptr)); + $ptr = $ptr + 16; + + my $epoch = ($epoch_hi << 32) | $epoch_lo; + my $msgseq = ($msgseq_hi << 32) | $msgseq_lo; + my $recnum = TLSProxy::RecordNumber->new($epoch, $msgseq); + + push(@$record_numbers, $recnum); + } + } +} + #Read only accessors +sub serverissender +{ + my $self = shift; + return $self->{serverissender}; +} +sub isdtls +{ + my $self = shift; + return $self->{isdtls}; +} sub flight { my $self = shift; diff --git a/util/perl/TLSProxy/RecordNumber.pm b/util/perl/TLSProxy/RecordNumber.pm new file mode 100644 index 0000000000000..d497df9570e82 --- /dev/null +++ b/util/perl/TLSProxy/RecordNumber.pm @@ -0,0 +1,37 @@ +# Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved. +# +# Licensed under the Apache License 2.0 (the "License"). You may not use +# this file except in compliance with the License. You can obtain a copy +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html + +use strict; + +package TLSProxy::RecordNumber; + +sub new +{ + my $class = shift; + my ($epoch, + $seqnum) = @_; + + my $self = { + epoch => $epoch, + seqnum => $seqnum + }; + + return bless $self, $class; +} + +# Read only accessors +sub epoch +{ + my $self = shift; + return $self->{epoch}; +} +sub seqnum +{ + my $self = shift; + return $self->{seqnum}; +} +1; diff --git a/util/perl/TLSProxy/ServerHello.pm b/util/perl/TLSProxy/ServerHello.pm index 2d35105d75d3b..034b15d013ff2 100644 --- a/util/perl/TLSProxy/ServerHello.pm +++ b/util/perl/TLSProxy/ServerHello.pm @@ -26,7 +26,7 @@ sub new my ($isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, @@ -38,7 +38,7 @@ sub new $server, TLSProxy::Message::MT_SERVER_HELLO, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, @@ -112,7 +112,8 @@ sub parse if ($random eq $hrrrandom) { TLSProxy::Proxy->is_tls13(1); - } elsif ($neg_version == TLSProxy::Record::VERS_TLS_1_3()) { + } elsif ($neg_version == TLSProxy::Record::VERS_TLS_1_3() + || $neg_version == TLSProxy::Record::VERS_DTLS_1_3()) { TLSProxy::Proxy->is_tls13(1); TLSProxy::Record->server_encrypting(1); diff --git a/util/perl/TLSProxy/ServerKeyExchange.pm b/util/perl/TLSProxy/ServerKeyExchange.pm index 6af7e238262f0..df8214ce9e727 100644 --- a/util/perl/TLSProxy/ServerKeyExchange.pm +++ b/util/perl/TLSProxy/ServerKeyExchange.pm @@ -1,4 +1,4 @@ -# Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved. +# Copyright 2016-2026 The OpenSSL Project Authors. All Rights Reserved. # # Licensed under the Apache License 2.0 (the "License"). You may not use # this file except in compliance with the License. You can obtain a copy @@ -18,7 +18,7 @@ sub new my ($isdtls, $server, $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, @@ -30,7 +30,7 @@ sub new $server, TLSProxy::Message::MT_SERVER_KEY_EXCHANGE(), $msgseq, - $msgfrag, + $msgfraglen, $msgfragoffs, $data, $records, @@ -77,7 +77,8 @@ sub parse my $record = ${$self->records}[0]; if (TLSProxy::Proxy->is_tls13() - || $record->version() == TLSProxy::Record::VERS_TLS_1_2()) { + || $record->version() == TLSProxy::Record::VERS_TLS_1_2() + || $record->version() == TLSProxy::Record::VERS_DTLS_1_2()) { $sigalg = unpack('n', substr($self->data, $ptr)); $ptr += 2; } diff --git a/util/platform_symbols/unix-symbols.txt b/util/platform_symbols/unix-symbols.txt index 62720f35fd3ab..bfd60a51b7e83 100644 --- a/util/platform_symbols/unix-symbols.txt +++ b/util/platform_symbols/unix-symbols.txt @@ -1,7 +1,6 @@ abort accept aligned_alloc -atoi bcmp bind calloc diff --git a/util/platform_symbols/windows-symbols.txt b/util/platform_symbols/windows-symbols.txt index 7ae58a3f182a1..cd41c7ec02893 100644 --- a/util/platform_symbols/windows-symbols.txt +++ b/util/platform_symbols/windows-symbols.txt @@ -125,7 +125,6 @@ _stat64i32 _strdup _time64 _wfopen -atoi calloc clearerr fclose diff --git a/util/valgrind.suppression b/util/valgrind.suppression index 4514e702b0300..cb38471a3ff88 100644 --- a/util/valgrind.suppression +++ b/util/valgrind.suppression @@ -121,6 +121,17 @@ fun:malloc ... fun:OSSL_provider_init + fun:provider_init + fun:provider_activate + ... +} +{ + provider_activate_strdup_without_provider_init + Memcheck:Leak + match-leak-kinds: reachable + fun:malloc + ... + fun:OSSL_provider_init fun:provider_activate ... } @@ -143,3 +154,9 @@ fun:gcm_cipher_internal ... } +{ + asn1_string_poison_test_intentional_terminator_read + Memcheck:Addr1 + fun:strlen + obj:*/asn1_string_poison_test +} diff --git a/util/wrap.pl.in b/util/wrap.pl.in index 4bb13189d38ff..c26500ee8bb93 100644 --- a/util/wrap.pl.in +++ b/util/wrap.pl.in @@ -118,8 +118,16 @@ if ($^O eq 'VMS') { @cmd = ( @ARGV ); } -# The exec() statement on MSWin32 doesn't seem to give back the exit code -# from the call, so we resort to using system() instead. +# exec() keeps this script's pid, which matters to callers that signal the +# command they started: a test recipe using open3() is handed this pid, not +# the command's, so with a subprocess the signal never reaches the command. +# MSWin32 can't use exec() because it doesn't give back the exit code, and +# VMS needs the exit code translated below, so both keep the subprocess. +if ($^O ne 'MSWin32' && $^O ne 'VMS') { + exec @cmd + or die "wrap.pl: Failed to execute '", join(' ', @cmd), "': $!\n"; +} + my $waitcode; if ($^O eq 'MSWin32') { $waitcode = system(quote_cmd_win32(@cmd)); diff --git a/util/write-man-symlinks b/util/write-man-symlinks deleted file mode 100755 index 7db7d2cbe2cbb..0000000000000 --- a/util/write-man-symlinks +++ /dev/null @@ -1,48 +0,0 @@ -#! /usr/bin/env perl -# Copyright 2021 The OpenSSL Project Authors. All Rights Reserved. -# -# Licensed under the Apache License 2.0 (the "License"). You may not use -# this file except in compliance with the License. You can obtain a copy -# in the file LICENSE in the source distribution or at -# https://www.openssl.org/source/license.html - - -require 5.10.0; -use warnings; -use strict; - -use FindBin; -use lib "$FindBin::Bin/perl"; - -use OpenSSL::Util::Pod; - -if ($#ARGV + 1 != 5 || $ARGV[0] !~ /^(un)?install$/) { - print "Usage: write-man-symlinks [install|uninstall] src-dir build-dir man-page-name target-dir\n"; - exit; -} - -my $action = $ARGV[0]; -my $srcdir = $ARGV[1]; -my $builddir = $ARGV[2]; -my $manname = $ARGV[3]; -my $targetdir = $ARGV[4]; - -$manname =~ m|(.+)\.(.+)|; -my $mainf = $1; -my $section = $2; -die "Bad src file" if !defined $mainf; -my $podfile = "$srcdir/$mainf.pod"; -#Some pod files are generated and are in the build dir -unless (-e $podfile) { - $podfile = "$builddir/$mainf.pod"; -} -my %podinfo = extract_pod_info($podfile); - -for my $name (@{$podinfo{names}}) { - next if $name eq $mainf; - if ($action eq "install") { - symlink "$manname", "$targetdir/$name.$section"; - } else { - unlink "$targetdir/$name.$section"; - } -} diff --git a/wycheproof b/wycheproof index aca47066256c1..3fa63dd0344ab 160000 --- a/wycheproof +++ b/wycheproof @@ -1 +1 @@ -Subproject commit aca47066256c167f0ce04d611d718cc85654341e +Subproject commit 3fa63dd0344abb611f1fb1d77e119938603ea230
Security CategoryAttack Type
Security CategoryAttack Type
0Weak
1Key search on a block cipher with a 128-bit key
2Collision search on a 256-bit hash function