diff --git a/.github/workflows/aarch64-more-cross-compiles.yml b/.github/workflows/aarch64-more-cross-compiles.yml deleted file mode 100644 index 13fdef3925a8e..0000000000000 --- a/.github/workflows/aarch64-more-cross-compiles.yml +++ /dev/null @@ -1,202 +0,0 @@ -# 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: Cross Compile for AArch64 Extensions - -on: - pull_request: - types: [opened, reopened, edited, synchronize] - push: - schedule: - - cron: '05 03 * * *' - workflow_dispatch: - -permissions: - contents: read - -jobs: - cross-compilation-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 - 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' - strategy: - fail-fast: false - matrix: - # The platform matrix specifies: - # arch: the architecture to build for, this defines the tool-chain - # prefix {arch}- and the Debian compiler package gcc-{arch} - # name. - # libs: the Debian package for the necessary link/runtime libraries. - # target: the OpenSSL configuration target to use, this is passed - # directly to the config command line. - # fips: set to "no" to disable building FIPS, leave unset to - # build the FIPS provider. - # tests: omit this to run all the tests using QEMU, set it to "none" - # to never run the tests, otherwise its value is passed to - # the "make test" command to allow selective disabling of - # tests. - # qemucpu: optional; string that describes CPU properties. - # The string will be used to set the QEMU_CPU variable. - # opensslcapsname: optional; string that describes the postfix of the - # OpenSSL environment variable that defines CPU - # capabilities. E.g. "foo" will result in an - # environment variable with the name OPENSSL_foo. - # opensslcaps: optional; if opensslcapsname (see above) is set, then - # this string will be used as content for the OpenSSL - # capabilities variable. - # capslabel: label used for artifacts. - platform: [ - { - # Baseline Armv8 crypto extensions: - # include/crypto/aes_platform.h - # providers/implementations/ciphers/cipher_aes_hw_armv8.inc - # crypto/sha/asm/sha1-armv8.pl - # crypto/aes/asm/aes-sha256-armv8.pl - arch: aarch64-linux-gnu, - libs: libc6-dev-arm64-cross, - target: linux-aarch64, - fips: no, - qemucpu: max, - opensslcapsname: armcap, # OPENSSL_armcap - opensslcaps: "0x1d", - capslabel: armv8-crypto - }, { - # PMULL-enabled AES-GCM / GHASH: - # include/crypto/aes_platform.h - # crypto/modes/asm/aes-gcm-armv8_64.pl - # crypto/modes/asm/ghashv8-armx.pl - arch: aarch64-linux-gnu, - libs: libc6-dev-arm64-cross, - target: linux-aarch64, - fips: no, - qemucpu: max, - opensslcapsname: armcap, # OPENSSL_armcap - opensslcaps: "0x3d", - capslabel: armv8-pmull - }, { - # SHA512 extension: - # crypto/aes/asm/aes-sha512-armv8.pl - arch: aarch64-linux-gnu, - libs: libc6-dev-arm64-cross, - target: linux-aarch64, - fips: no, - qemucpu: max, - opensslcapsname: armcap, # OPENSSL_armcap - opensslcaps: "0x7d", - capslabel: armv8-sha512 - }, { - # SHA3-accelerated path. Since OPENSSL_armcap short-circuits runtime - # detection, include the derived "worth using" and unroll bits too: - # crypto/sha/sha3.c - # providers/implementations/digests/sha3_prov.c - # providers/implementations/ciphers/cipher_aes_gcm_hw_armv8.inc - # providers/implementations/ciphers/cipher_aes_hw_armv8.inc - arch: aarch64-linux-gnu, - libs: libc6-dev-arm64-cross, - target: linux-aarch64, - fips: no, - qemucpu: max, - opensslcapsname: armcap, # OPENSSL_armcap - opensslcaps: "0x1987d", - capslabel: armv8-sha3 - }, { - # SVE2 Poly1305 path. OPENSSL_armcap requires the derived - # ARMV9_SVE2_POLY1305 bit to be set explicitly when capability - # probing is overridden: - # crypto/poly1305/asm/poly1305-armv8.pl - # crypto/chacha/asm/chacha-armv8-sve.pl - arch: aarch64-linux-gnu, - libs: libc6-dev-arm64-cross, - target: linux-aarch64, - fips: no, - qemucpu: max, - opensslcapsname: armcap, # OPENSSL_armcap - opensslcaps: "0x2601d", - capslabel: armv9-sve2-poly1305 - } - ] - runs-on: ubuntu-latest - steps: - - name: install packages - run: | - sudo apt-get update - sudo apt-get -yq --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install \ - gcc-${{ matrix.platform.arch }} \ - ${{ matrix.platform.libs }} - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - - name: config with FIPS - if: matrix.platform.fips != 'no' - run: | - ./config --banner=Configured --strict-warnings enable-fips enable-lms \ - --cross-compile-prefix=${{ matrix.platform.arch }}- \ - ${{ matrix.platform.target }} - - name: config without FIPS - if: matrix.platform.fips == 'no' - run: | - ./config --banner=Configured --strict-warnings enable-lms \ - --cross-compile-prefix=${{ matrix.platform.arch }}- \ - ${{ matrix.platform.target }} - - name: config dump - run: ./configdata.pm --dump - - - name: make - run: make -s -j4 - - - name: install qemu - if: matrix.platform.tests != 'none' - run: sudo apt-get -yq --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install qemu-user - - - name: Set QEMU environment - if: matrix.platform.qemucpu != '' - run: echo "QEMU_CPU=${{ matrix.platform.qemucpu }}" >> $GITHUB_ENV - - - name: Set OpenSSL caps environment - if: matrix.platform.opensslcapsname != '' - run: echo "OPENSSL_${{ matrix.platform.opensslcapsname }}=\ - ${{ matrix.platform.opensslcaps }}" >> $GITHUB_ENV - - - name: get cpu info - run: cat /proc/cpuinfo - - - name: get openssl cpu info - if: matrix.platform.tests != 'none' - run: QEMU_LD_PREFIX=/usr/${{ matrix.platform.arch }} ./util/opensslwrap.sh info -cpusettings - - - name: make all tests - if: github.event_name == 'push' && 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 != '' - 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' - run: | - .github/workflows/make-test \ - TESTS="test_evp*" \ - QEMU_LD_PREFIX=/usr/${{ matrix.platform.arch }} - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "cross-compiles-aarch64@${{ matrix.platform.capslabel }}" - path: artifacts.tar.gz - if-no-files-found: ignore diff --git a/.github/workflows/avx512-sde.yml b/.github/workflows/avx512-sde.yml new file mode 100644 index 0000000000000..4c47ed1aaf451 --- /dev/null +++ b/.github/workflows/avx512-sde.yml @@ -0,0 +1,137 @@ +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# Copyright (c) 2026 Intel Corporation. All Rights Reserved. +# +# Licensed under 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 + +# Run AVX512VL-specific tests under Intel SDE. +# +# GitHub Actions runners currently do not have AVX512 hardware. +# Intel SDE emulates AVX512 instructions and spoofs CPUID, +# so AVX512 code paths are exercised. +# +# To update Intel SDE: find the new mirror ID and file date from +# https://www.intel.com/content/www/us/en/download/684897 +# and update the three env vars below. + +name: AVX512 tests via Intel SDE + +on: [pull_request, push] + +permissions: + contents: read + +env: + SDE_VERSION: 10.8.0 + SDE_DATE: 2026-03-15 + SDE_MIRROR_ID: 915934 + +jobs: + linux: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + + - name: install NASM + run: sudo apt-get install -y nasm + + - name: install Intel SDE + run: | + SDE_URL="https://downloadmirror.intel.com/${SDE_MIRROR_ID}/sde-external-${SDE_VERSION}-${SDE_DATE}-lin.tar.xz" + SDE_SHA256="50b320cd226acef7a491f5b321fc1be3c3c7984f9e27a456e64894b5b0979dd3" + curl -fsSL -o /tmp/sde.tar.xz "$SDE_URL" + echo "$SDE_SHA256 /tmp/sde.tar.xz" | sha256sum -c - + mkdir /tmp/sde + tar -xf /tmp/sde.tar.xz -C /tmp/sde/ + sudo mv /tmp/sde/sde-external-${SDE_VERSION}-${SDE_DATE}-lin /opt/sde + echo "/opt/sde" >> "$GITHUB_PATH" + + - name: config + run: | + ./config --banner=Configured --strict-warnings no-shared enable-fips + + - name: build + run: make -j4 + + - name: show CPU and OpenSSL build info + run: | + cat /proc/cpuinfo | grep -m1 "model name" + sde64 -skx -- ./apps/openssl version -c + + - name: ml_dsa_internal_test (AVX512VL via SDE) + run: sde64 -skx -- ./test/ml_dsa_internal_test + + - name: sha3_x4_internal_test (AVX512VL via SDE) + run: sde64 -skx -- ./test/sha3_x4_internal_test + + - name: fipsinstall (FIPS KAT via SDE) + run: sde64 -skx -- ./apps/openssl fipsinstall -module ./providers/fips.so -out /tmp/fipsmodule.cnf -provider_name fips + + windows: + runs-on: windows-2022 + env: + VCVARS: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + + - name: install NASM + run: | + choco install nasm + "C:\Program Files\NASM" | Out-File -FilePath "$env:GITHUB_PATH" -Append + + - name: install JOM + run: choco install jom + + - name: install Intel SDE + run: | + $url = "https://downloadmirror.intel.com/$env:SDE_MIRROR_ID/sde-external-$env:SDE_VERSION-$env:SDE_DATE-win.tar.xz" + $expected = "176F87C80EB42BB91B73E1428F4A0FD067DF322F901F9B4359B20B86B92C2BAE" + curl.exe -fsSL -o sde-win.tar.xz $url + $actual = (Get-FileHash sde-win.tar.xz -Algorithm SHA256).Hash + if ($actual -ne $expected) { throw "SDE SHA256 mismatch: got $actual" } + & "C:\Program Files\7-Zip\7z.exe" x sde-win.tar.xz -so | & "C:\Program Files\7-Zip\7z.exe" x -si -ttar -o"C:\sde" + $sdeRoot = "C:\sde\sde-external-$env:SDE_VERSION-$env:SDE_DATE-win" + if (-not (Test-Path "$sdeRoot\sde.exe")) { throw "sde.exe not found in $sdeRoot" } + "$sdeRoot" | Out-File -FilePath $env:GITHUB_PATH -Append + + - name: prepare build directory + run: mkdir _build + + - name: config + working-directory: _build + shell: cmd + run: | + call "%VCVARS%" + perl ..\Configure --banner=Configured --strict-warnings no-shared enable-fips no-makedepend + + - name: build + working-directory: _build + shell: cmd + run: | + call "%VCVARS%" + jom /j4 /S + + - name: show CPU and OpenSSL build info + working-directory: _build + run: sde -skx -- apps\openssl.exe version -c + + - name: ml_dsa_internal_test (AVX512VL via SDE) + working-directory: _build + shell: cmd + run: sde -skx -- test\ml_dsa_internal_test.exe + + - name: sha3_x4_internal_test (AVX512VL via SDE) + working-directory: _build + shell: cmd + run: sde -skx -- test\sha3_x4_internal_test.exe + + - name: fipsinstall (FIPS KAT via SDE) + working-directory: _build + shell: cmd + run: sde -skx -- apps\openssl.exe fipsinstall -module providers\fips.dll -out fipsmodule.cnf -provider_name fips diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml deleted file mode 100644 index 658a3ef7cbef0..0000000000000 --- a/.github/workflows/backport.yml +++ /dev/null @@ -1,64 +0,0 @@ -# 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: Backports CI - -on: [pull_request] - -permissions: - contents: read - -jobs: - check_backports: - strategy: - fail-fast: false - matrix: - release: [ - { - branch: '4.0', - cppflags: '' - }, { - branch: '3.6', - cppflags: '' - }, { - branch: '3.5', - cppflags: 'CPPFLAGS=-ansi' - }, { - branch: '3.4', - cppflags: 'CPPFLAGS=-ansi' - }, { - branch: '3.0', - cppflags: 'CPPFLAGS=-ansi' - } - ] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - if: ${{ contains(join(github.event.pull_request.labels.*.name,','),matrix.release.branch) }} - with: - ref: ${{ github.event.pull_request.head.sha }} - fetch-depth: 0 - persist-credentials: false - - name: cherry-pick - if: ${{ contains(join(github.event.pull_request.labels.*.name,','),matrix.release.branch) }} - run: | - REFEND=$(git rev-parse HEAD) - REFSTART=$(git rev-parse $REFEND~${{ github.event.pull_request.commits }}) - git checkout ${{ format('openssl-{0}', matrix.release.branch) }} - git config user.name "OpenSSL Machine" - git config user.email "openssl-machine@openssl.org" - echo Cherry-picking $REFSTART..$REFEND - git cherry-pick $REFSTART..$REFEND - - name: config - if: ${{ contains(join(github.event.pull_request.labels.*.name,','),matrix.release.branch) }} - run: ${{ matrix.release.cppflags }} ./config --strict-warnings --banner=Configured no-asm enable-fips --strict-warnings -D_DEFAULT_SOURCE && perl configdata.pm --dump - - name: make - if: ${{ contains(join(github.event.pull_request.labels.*.name,','),matrix.release.branch) }} - run: make -s -j4 - - name: make test - if: ${{ contains(join(github.event.pull_request.labels.*.name,','),matrix.release.branch) }} - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} diff --git a/.github/workflows/check-news-changes.yml b/.github/workflows/check-news-changes.yml deleted file mode 100644 index 484b3ee522faf..0000000000000 --- a/.github/workflows/check-news-changes.yml +++ /dev/null @@ -1,105 +0,0 @@ -# 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 - -name: "Scan to check for NEWS/CHANGES suggestions" - -on: pull_request -env: - NEED_NEWS_CHANGES: "no" - SKIP_NEWS_CHECK: "no" - PR_NUMBER: ${{ github.event.number }} - GH_TOKEN: ${{ github.token }} -permissions: {} - -jobs: - scan_for_news_changes: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - fetch-depth: 0 - - name: "Check if we have the label to skip this test" - run: | - SKIP_TEST=$(gh pr view $PR_NUMBER --json labels --jq '.labels[] | select(.name == "no_news_changes_needed") | .name') - if [ -n "$SKIP_TEST" ]; then - echo "SKIP_NEWS_CHECK=yes" >> $GITHUB_ENV - fi - - - name: "Check if we already have a NEWS/CHANGES entry" - if: ${{ env.SKIP_NEWS_CHECK == 'no' }} - run: | - git diff --name-only ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} > ./names.txt - echo "changed files between ${{ github.event.pull_request.base.sha }} and ${{ github.event.pull_request.head.sha }}" - cat ./names.txt - set +e - grep -q "NEWS\.md" names.txt - if [ $? -eq 0 ]; then - echo "FOUND_NEWS_CHANGES_ADDITION=yes" >> $GITHUB_ENV - else - grep -q "CHANGES\.md" names.txt - if [ $? -eq 0 ]; then - echo "FOUND_NEWS_CHANGES_ADDITION=yes" >> $GITHUB_ENV - else - echo "FOUND_NEWS_CHANGES_ADDITION=no" >> $GITHUB_ENV - fi - fi - - name: "Check if this PR affects a CVE" - if: ${{ env.FOUND_NEWS_CHANGES_ADDITION == 'no' && env.SKIP_NEWS_CHECK == 'no' }} - run: | - git log ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} > ./log.txt - set +e - grep -q "CVE-" ./log.txt - if [ $? -eq 0 ]; then - echo "Changes in this PR reference a CVE" - echo "NEED_NEWS_CHANGES=yes" >> $GITHUB_ENV - fi - - name: "Check if this PR impacts a public API" - if: ${{ env.FOUND_NEWS_CHANGES_ADDITION == 'no' && env.SKIP_NEWS_CHECK == 'no' }} - run: | - set +e - git diff --name-only ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} > ./names.txt - echo "changed files between ${{ github.event.pull_request.base.sha }} and ${{ github.event.pull_request.head.sha }}" - cat ./names.txt - grep -q "include/openssl" ./names.txt - if [ $? -eq 0 ]; then - echo "Changes in this PR may impact public APIS's" - echo "NEED_NEWS_CHANGES=yes" >> $GITHUB_ENV - fi - - name: "Check if this is a feature branch merge" - if: ${{ env.FOUND_NEWS_CHANGES_ADDITION == 'no' && env.SKIP_NEWS_CHECK == 'no' }} - run: | - set +e - echo ${{ github.head_ref }} | grep -q "feature" - if [ $? -eq 0 ]; then - echo "Feature branch found" - echo "NEED_NEWS_CHANGES=yes" >> $GITHUB_ENV - fi - - name: "Check if configuration options have changed" - if: ${{ env.FOUND_NEWS_CHANGES_ADDITION == 'no' && env.SKIP_NEWS_CHECK == 'no' }} - run: | - git checkout ${{ github.event.pull_request.base.sha }} - set +e - ./Configure --help > ./before.txt 2>&1 - git checkout ${{ github.event.pull_request.head.sha }} - ./Configure --help > ./after.txt 2>&1 - set -e - CONF_CHANGE=$(diff ./before.txt ./after.txt | wc -l) - if [ $CONF_CHANGE -ne 0 ]; then - echo "Configuration options changes" - echo "NEED_NEWS_CHANGES=yes" >> $GITHUB_ENV - fi - - name: "Report Results" - if: ${{ env.SKIP_NEWS_CHECK == 'no' }} - run: | - if [ "${{ env.NEED_NEWS_CHANGES }}" == "yes" ]; then - echo "Suggest that you add a NEWS/CHANGES entry for this PR" - echo "Alternatively, quiet this suggestion by applying the no_news_changes_needed label" - exit 1 - fi - - diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index e28a8a1abdddd..0000000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,892 +0,0 @@ -# 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: GitHub CI - -on: [pull_request, push] - -# for some reason, this does not work: -# variables: -# BUILDOPTS: "-j4" -# HARNESS_JOBS: "${HARNESS_JOBS:-4}" - -# for some reason, this does not work: -# before_script: -# - make="make -s" - -permissions: - contents: read - -env: - OSSL_RUN_CI_TESTS: 1 - -jobs: - check_update: - runs-on: ubuntu-latest - steps: - - name: install unifdef - run: | - sudo apt-get update - sudo apt-get -yq --no-install-suggests --no-install-recommends --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install unifdef - - uses: actions/checkout@v6 - with: - fetch-depth: 0 - 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 update - run: make update - - 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. - check-c99: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: config - run: CPPFLAGS='-std=c99 -D_XOPEN_SOURCE=1 -D_POSIX_C_SOURCE=200809L' ./config --strict-warnings --banner=Configured enable-sslkeylog no-asm no-secure-memory no-makedepend enable-buildtest-c++ enable-fips enable-lms && perl configdata.pm --dump - - name: make - run: make -s -j4 - - basic_gcc: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: localegen - run: sudo locale-gen tr_TR.UTF-8 - - name: fipsvendor - # Make one fips build use a customized FIPS vendor - run: echo "FIPS_VENDOR=CI" >> VERSION.dat - - name: config - # enable-quic is on by default, but we leave it here to check we're testing the explicit enable somewhere - run: CC=gcc ./config --strict-warnings --banner=Configured enable-demos enable-h3demo enable-ec_explicit_curves enable-sslkeylog enable-fips enable-quic enable-lms && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test - - name: check fipsvendor - run: | - util/wrap.pl -fips apps/openssl list -providers | grep 'name: CI FIPS Provider for OpenSSL$' - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@basic-gcc" - path: artifacts.tar.gz - - basic_clang: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: CC=clang ./config --strict-warnings --banner=Configured enable-demos enable-h3demo no-fips && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@basic-clang" - path: artifacts.tar.gz - - linux-arm64: - runs-on: ubuntu-24.04-arm - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: config - run: ./config --strict-warnings enable-demos enable-fips enable-lms enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-trace - - name: config dump - run: ./configdata.pm --dump - - name: make - run: make -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@linux-arm64" - path: artifacts.tar.gz - - gcc-min-version: - runs-on: ubuntu-latest - container: - image: docker.io/gcc:9 - timeout-minutes: 90 - strategy: - fail-fast: false - 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 - run: make -s -j4 - - name: print gcc version - run: | - gcc --version - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test - - linux-x86: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: run container - run: | - CONTAINER_ID=$(podman run -d -v $(pwd):/mnt -w /mnt --platform=linux/i386 docker.io/i386/debian:13 sleep infinity) - echo "CONTAINER_ID=$CONTAINER_ID" >> "$GITHUB_ENV" - - name: install dependencies - run: - podman exec -t $CONTAINER_ID sh -c "apt-get update && apt-get install -y gcc perl make" - - name: config - run: | - podman exec -t $CONTAINER_ID sh -c \ - "./config --strict-warnings linux-x86 enable-demos enable-fips enable-lms enable-md2 enable-rc5 enable-trace" - - name: config dump - run: | - podman exec -t $CONTAINER_ID sh -c \ - "./configdata.pm --dump" - - name: make - run: | - podman exec -t $CONTAINER_ID sh -c \ - "make -j" - - name: get cpu info - run: | - cat /proc/cpuinfo - podman exec -t $CONTAINER_ID sh -c \ - "./util/opensslwrap.sh version -c" - - name: make test - run: | - podman exec -t $CONTAINER_ID sh -c \ - ".github/workflows/make-test" - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@linux-x86" - path: artifacts.tar.gz - - freebsd-x86_64: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: config - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 - with: - operating_system: freebsd - version: "13.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 - with: - operating_system: freebsd - version: "13.4" - shutdown_vm: false - run: ./configdata.pm --dump - - name: make - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 - with: - operating_system: freebsd - version: "13.4" - shutdown_vm: false - run: make -j4 - - name: make test - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 - with: - operating_system: freebsd - version: "13.4" - run: | - ./util/opensslwrap.sh version -c - .github/workflows/make-test - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@BSD-x86_64" - path: artifacts.tar.gz - - minimal: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: ./config --strict-warnings --banner=Configured enable-demos enable-h3demo no-bulk no-pic no-asm no-lms -DOPENSSL_NO_SECURE_MEMORY -DOPENSSL_SMALL_FOOTPRINT && perl configdata.pm --dump - - name: make - run: make -j4 # verbose, so no -s here - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@minimal" - path: artifacts.tar.gz - - no-deprecated: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: ./config --strict-warnings --banner=Configured enable-demos enable-h3demo no-deprecated enable-fips && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@no-deprecated" - path: artifacts.tar.gz - - no-shared-ubuntu: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: ./config --strict-warnings --banner=Configured enable-demos enable-h3demo no-shared no-fips && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@no-shared-ubuntu" - path: artifacts.tar.gz - - no-shared-macos: - runs-on: macos-14 - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: ./config --strict-warnings --banner=Configured enable-demos enable-h3demo no-shared no-fips && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - sysctl machdep.cpu - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@no-shared-macos-14" - path: artifacts.tar.gz - - non-caching: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: Adjust ASLR for sanitizer - run: | - sudo cat /proc/sys/vm/mmap_rnd_bits - sudo sysctl -w vm.mmap_rnd_bits=28 - - name: config - run: ./config --strict-warnings --banner=Configured --debug enable-demos enable-h3demo enable-asan enable-ubsan no-cached-fetch no-fips no-dtls no-tls1 no-tls1-method no-tls1_1 no-tls1_1-method no-async && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test OPENSSL_TEST_RAND_ORDER=0 TESTS="-test_fuzz* -test_ssl_* -test_sslapi -test_evp -test_cmp_http -test_verify -test_cms -test_store -test_enc -[01][0-9]" - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@non-caching" - path: artifacts.tar.gz - - address_ub_sanitizer: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: Adjust ASLR for sanitizer - run: | - sudo cat /proc/sys/vm/mmap_rnd_bits - sudo sysctl -w vm.mmap_rnd_bits=28 - - name: config - run: ./config --strict-warnings --banner=Configured --debug enable-demos enable-h3demo enable-asan enable-ec_explicit_curves enable-ubsan enable-rc5 enable-md2 enable-ec_nistp_64_gcc_128 enable-fips enable-lms && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test OPENSSL_TEST_RAND_ORDER=0 - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@address_ub_sanitizer" - path: artifacts.tar.gz - - fuzz_tests: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: Adjust ASLR for sanitizer - run: | - sudo cat /proc/sys/vm/mmap_rnd_bits - sudo sysctl -w vm.mmap_rnd_bits=28 - - name: config - run: ./config --strict-warnings --banner=Configured --debug -DPEDANTIC -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION enable-asan enable-ec_explicit_curves enable-ubsan enable-rc5 enable-md2 enable-ec_nistp_64_gcc_128 enable-weak-ssl-ciphers enable-nextprotoneg && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test OPENSSL_TEST_RAND_ORDER=0 TESTS="test_fuzz*" - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@fuzz_tests" - path: artifacts.tar.gz - if-no-files-found: ignore - - memory_sanitizer: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: Adjust ASLR for sanitizer - run: | - sudo cat /proc/sys/vm/mmap_rnd_bits - sudo sysctl -w vm.mmap_rnd_bits=28 - - name: config - # --debug -O1 is to produce a debug build that runs in a reasonable amount of time - run: CC=clang ./config --strict-warnings --banner=Configured --debug no-shared -O1 -fsanitize=memory -DOSSL_SANITIZE_MEMORY -fno-optimize-sibling-calls enable-rc5 enable-md2 enable-ec_nistp_64_gcc_128 enable-ec_explicit_curves enable-fips enable-lms no-slh-dsa && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test OPENSSL_TEST_RAND_ORDER=0 - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@memory_sanitizer" - path: artifacts.tar.gz - - threads_sanitizer: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: Adjust ASLR for sanitizer - run: | - sudo cat /proc/sys/vm/mmap_rnd_bits - sudo sysctl -w vm.mmap_rnd_bits=28 - - name: config - run: CC=clang ./config --strict-warnings --banner=Configured no-shared no-fips -g -fsanitize=thread && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test V=1 TESTS="test_lhash test_threads test_internal_provider test_provfetch test_provider test_pbe test_evp_kdf test_pkcs12 test_store test_evp test_quic*" - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@threads_sanitizer" - path: artifacts.tar.gz - - enable_non-default_options: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: modprobe tls - run: sudo modprobe tls - - name: config - run: ./config --strict-warnings --banner=Configured enable-demos enable-h3demo no-ec enable-ssl-trace enable-zlib enable-zlib-dynamic enable-crypto-mdebug enable-egd enable-ktls enable-fips enable-lms no-threads && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@enable_non-default_options" - path: artifacts.tar.gz - - full_featured: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: modprobe tls - run: sudo modprobe tls - - name: Enable sctp - run: sudo modprobe sctp - - name: Enable auth in sctp - run: sudo sysctl -w net.sctp.auth_enable=1 - - name: install extra config support - run: sudo apt-get -y install libsctp-dev abigail-tools libzstd-dev zstd - - name: config - run: ./config --strict-warnings --banner=Configured enable-demos enable-h3demo enable-ec_explicit_curves enable-ktls enable-fips enable-lms enable-egd enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-sctp enable-weak-ssl-ciphers enable-trace enable-zlib enable-zstd && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@full_featured" - path: artifacts.tar.gz - - no-legacy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: ./config --strict-warnings --banner=Configured enable-demos enable-h3demo no-legacy enable-fips enable-lms && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@no-legacy" - path: artifacts.tar.gz - - legacy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: ./config --strict-warnings --banner=Configured --debug enable-demos enable-h3demo no-shared enable-crypto-mdebug enable-rc5 enable-md2 enable-weak-ssl-ciphers enable-zlib enable-ec_nistp_64_gcc_128 enable-ec_explicit_curves no-fips && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - 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: - - uses: actions/checkout@v6 - with: - submodules: recursive - persist-credentials: false - - name: package installs - run: | - sudo apt-get update - sudo apt-get -yq install bison gettext keyutils ldap-utils libldap2-dev libkeyutils-dev python3 python3-paste python3-pyrad slapd tcsh python3-virtualenv virtualenv python3-kdcproxy gdb libtls-dev wget gpg - - name: install cpanm and Test2::V0 for gost_engine testing - uses: perl-actions/install-with-cpanm@10d60f00b4073f484fc29d45bfbe2f776397ab3d # v1.7 - with: - install: Test2::V0 - - name: setup hostname workaround - run: sudo hostname localhost - - name: config - run: ./config --strict-warnings --banner=Configured --debug enable-rc5 enable-md2 enable-weak-ssl-ciphers enable-zlib enable-ec_nistp_64_gcc_128 enable-external-tests no-fips && perl configdata.pm --dump - - name: make - run: make -s -j4 - - uses: dtolnay/rust-toolchain@0f44b27771c32bda9f458f75a1e241b09791b331 - with: - toolchain: stable - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: test external gost-engine - run: make test TESTS="test_external_gost_engine" - - name: test external krb5 - run: make test TESTS="test_external_krb5" - - name: test external tlsfuzzer - run: make test TESTS="test_external_tlsfuzzer" - - name: test external Cloudflare quiche - run: make test TESTS="test_external_cf_quiche" VERBOSE=1 - - name: test external rpki client - run: make test TESTS="test_external_rpki-client-portable" - - name: test ability to produce debuginfo files - run: | - make debuginfo - gdb < <(echo -e "file ./libcrypto.so.4\nquit") > ./results - grep -q "Reading symbols from.*libcrypto\.so\.4\.debug" results - - external-tests-oqs-provider: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - persist-credentials: false - - name: config - run: ./config --strict-warnings --banner=Configured --debug enable-external-tests && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: test external oqs-provider - run: make test TESTS="test_external_oqsprovider" - - external-tests-pkcs11-provider: - runs-on: ubuntu-latest - container: fedora:latest - steps: - - name: package installs - run: | - dnf install -y perl-FindBin perl-IPC-Cmd perl-File-Compare perl-File-Copy perl-Test-Simple perl-Test-Harness python3 make g++ perl git meson opensc expect kryoptic - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora and pkcs11-provider submodule - run: | - git config --global --add safe.directory "$GITHUB_WORKSPACE" - git submodule update --init --depth 1 fuzz/corpora - git submodule update --init --depth 1 pkcs11-provider - - name: config - run: ./config --strict-warnings --banner=Configured --debug enable-external-tests no-fips && perl configdata.pm --dump - - name: make - run: make -s -j4 - # Run all tests except external tests to make sure they work fine on Fedora because - # this is the only job running on Fedora, only then execute pkcs11-provider external - # test. - - name: test (except external tests) - run: make test TESTS="-test_external_*" - - name: test external pkcs11-provider - run: make test TESTS="test_external_pkcs11_provider" VERBOSE=1 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - external-tests-pyca: - runs-on: ubuntu-latest - strategy: - matrix: - PYTHON: - - 3.9 - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - persist-credentials: false - - name: package installs - run: | - sudo apt-get update - sudo apt-get -yq install pkgconf libssl-dev - - name: Configure OpenSSL - run: ./config --strict-warnings --banner=Configured --debug enable-external-tests && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: Setup Python - uses: actions/setup-python@v6.0.0 - with: - python-version: ${{ matrix.PYTHON }} - - uses: dtolnay/rust-toolchain@0f44b27771c32bda9f458f75a1e241b09791b331 - with: - toolchain: stable - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: test external pyca - run: make test TESTS="test_external_pyca" VERBOSE=1 - - external-test-bssl: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: Configure OpenSSL - run: ./config enable-external-tests - - name: Build OpenSSL - run: make -s -j4 - - name: Clone BoringSSL 0.20260211.0 - run: git clone --depth 1 --branch 0.20260211.0 https://boringssl.googlesource.com/boringssl - - name: Configure and Build BoringSSL - run: | - cd boringssl - mkdir build - cd build - cmake -DCMAKE_INSTALL_PREFIX=../../boringssl/.local .. - make -s -j4 - make install - cd ../.. - - name: Test ECH with BoringSSL - run: make test TESTS='test_external_ech_bssl' V=1 - - external-test-nss: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: Configure OpenSSL - run: ./config enable-external-tests - - name: Build OpenSSL - run: make -s -j4 - - name: Clone and Build NSS - run: | - mkdir nss - cd nss - git clone --depth 1 --branch NSS_3_112_3_RTM https://github.com/nss-dev/nss.git - hg clone https://hg.mozilla.org/projects/nspr -r NSPR_4_36_BRANCH - cd nss - USE_64=1 make nss_build_all - USE_64=1 make install - cd ../.. - - name: Test ECH with NSS - run: make test TESTS='test_external_ech_nss' V=1 diff --git a/.github/workflows/compiler-zoo.yml b/.github/workflows/compiler-zoo.yml deleted file mode 100644 index 3a0289a10dadf..0000000000000 --- a/.github/workflows/compiler-zoo.yml +++ /dev/null @@ -1,82 +0,0 @@ -# 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: Compiler Zoo CI - -on: [push] - -permissions: - contents: read - -jobs: - gcc: - strategy: - fail-fast: false - matrix: - gcc: [gcc-9, gcc-10, gcc-11, gcc-12, gcc-13, gcc-14] - runs-on: ubuntu-24.04 - steps: - - name: install packages - run: | - sudo apt-get update - sudo apt-get -y install ${{ matrix.gcc }} - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - env: - CC: ${{ matrix.gcc }} - run: | - ./config --strict-warnings --banner=Configured no-shared enable-fips - - name: config dump - run: ./configdata.pm --dump - - name: make - run: make -s -j - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} - - clang: - strategy: - fail-fast: false - matrix: - clang: [clang-11, clang-12, clang-13, clang-14, clang-15, clang-16, clang-17, clang-18, clang-19, clang-20, clang-21] - runs-on: ubuntu-22.04 - steps: - - name: install packages - run: | - set -euo pipefail - VERSION=$(awk -F- '{print $NF}' <<< ${{ matrix.clang }}) - wget -qO- https://apt.llvm.org/llvm-snapshot.gpg.key | sudo tee /etc/apt/trusted.gpg.d/apt.llvm.org.asc - echo "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-$VERSION main" | sudo tee -a /etc/apt/sources.list - sudo apt-get update || true - sudo apt-get -y install ${{ matrix.clang }} - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - env: - CC: ${{ matrix.clang }} - run: | - ./config --strict-warnings --banner=Configured no-shared enable-fips - - name: config dump - run: ./configdata.pm --dump - - name: make - run: make -s -j - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} diff --git a/.github/workflows/coveralls.yml b/.github/workflows/coveralls.yml deleted file mode 100644 index 4c873babc8f96..0000000000000 --- a/.github/workflows/coveralls.yml +++ /dev/null @@ -1,129 +0,0 @@ -# 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: Coverage - -on: - schedule: - - cron: '15 02 * * *' - workflow_dispatch: - inputs: - branch: - description: Branch to measure coverage - required: true - default: master - extra_config: - description: Extra options for configuration script - default: "" - -permissions: - contents: read - -jobs: - define-matrix: - runs-on: ubuntu-latest - outputs: - branches: ${{ steps.branches.outputs.branches }} - steps: - - name: Define branches - id: branches - env: - GITHUB_EVENT_INPUTS_BRANCH: ${{ github.event.inputs.branch }} - GITHUB_EVENT_INPUTS_EXTRA_CONFIG: ${{ github.event.inputs.extra_config }} - run: | - if [ "${{ github.event_name}}" = "workflow_dispatch" ]; then - MATRIX=$(cat << EOF - [{ - "branch": "${GITHUB_EVENT_INPUTS_BRANCH}", - "extra_config": "${GITHUB_EVENT_INPUTS_EXTRA_CONFIG}" - }] - EOF - ) - else - MATRIX=$(cat << EOF - [{ - "branch": "master", - "extra_config": "enable-fips enable-tfo enable-lms enable-crypto-mdebug enable-allocfail-tests" - }, { - "branch": "openssl-4.0", - "extra_config": "enable-fips enable-tfo enable-lms enable-crypto-mdebug enable-allocfail-tests" - },{ - "branch": "openssl-3.6", - "extra_config": "no-afalgeng enable-fips enable-tfo enable-lms" - },{ - "branch": "openssl-3.5", - "extra_config": "no-afalgeng enable-fips enable-tfo" - },{ - "branch": "openssl-3.4", - "extra_config": "no-afalgeng enable-fips enable-tfo" - }, { - "branch": "openssl-3.0", - "extra_config": "no-afalgeng enable-fips" - }] - EOF - ) - fi - echo "branches<> "$GITHUB_OUTPUT" - - coverage: - if: github.repository == 'openssl/openssl' - needs: define-matrix - permissions: - checks: write # for coverallsapp/github-action to create new checks - contents: read # for actions/checkout to fetch code - strategy: - fail-fast: false - matrix: - branches: ${{ fromJSON(needs.define-matrix.outputs.branches) }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - submodules: recursive - ref: ${{ matrix.branches.branch }} - persist-credentials: false - - name: cache commit id - run: | - echo "githubid=`/usr/bin/git log -1 --format='%H'`" >>$GITHUB_ENV - - name: package installs - run: | - sudo apt-get update - sudo apt-get -yq install lcov - sudo apt-get -yq install bison gettext keyutils ldap-utils libldap2-dev libkeyutils-dev python3 python3-paste python3-pyrad slapd tcsh python3-virtualenv virtualenv python3-kdcproxy - - name: install Test2::V0 for gost_engine testing - uses: perl-actions/install-with-cpanm@10d60f00b4073f484fc29d45bfbe2f776397ab3d #v1.7 - with: - install: Test2::V0 - - name: setup hostname workaround - run: sudo hostname localhost - - name: config - run: CC=gcc ./config --debug --coverage ${{ matrix.branches.extra_config }} no-asm enable-rc5 enable-md2 enable-nextprotoneg enable-weak-ssl-ciphers enable-zlib enable-ec_nistp_64_gcc_128 enable-buildtest-c++ enable-ssl-trace enable-trace - - name: config dump - run: ./configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: make test TESTS='-test_external_krb5' EVP_TEST_EXTENDED=1 - - name: generate coverage info - run: lcov -d . -c - --exclude "${PWD}/test/*" - --exclude "${PWD}/fuzz/*" - --exclude "/usr/include/*" - --ignore-errors mismatch - --branch-coverage - -o ./lcov.info - - name: Coveralls upload - uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b #v2.3.6 - with: - github-token: ${{ secrets.github_token }} - git-branch: ${{ matrix.branches.branch }} - git-commit: ${{ env.githubid }} - path-to-lcov: ./lcov.info diff --git a/.github/workflows/cross-compiles.yml b/.github/workflows/cross-compiles.yml deleted file mode 100644 index efc498edf141a..0000000000000 --- a/.github/workflows/cross-compiles.yml +++ /dev/null @@ -1,237 +0,0 @@ -# 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: Cross Compile - -on: [pull_request, push] - -permissions: - contents: read - -jobs: - cross-compilation: - strategy: - fail-fast: false - matrix: - # The platform matrix specifies: - # arch: the architecture to build for, this defines the tool-chain - # prefix {arch}- and the Debian compiler package gcc-{arch} - # name. - # libs: the Debian package for the necessary link/runtime libraries. - # target: the OpenSSL configuration target to use, this is passed - # directly to the config command line. - # fips: set to "no" to disable building FIPS, leave unset to - # build the FIPS provider. - # tests: omit this to run all the tests using QEMU, set it to "none" - # to never run the tests, otherwise its value is passed to - # the "make test" command to allow selective disabling of - # tests. - # qemucpu: optional; string that describes CPU properties. - # The string will be used to set the QEMU_CPU variable. - # opensslcapsname: optional; string that describes the postfix of the - # OpenSSL environment variable that defines CPU - # capabilities. E.g. "foo" will result in an - # environment variable with the name OPENSSL_foo. - # opensslcaps: optional; if opensslcapsname (see above) is set, then - # this string will be used as content for the OpenSSL - # capabilities variable. - # ppa: Launchpad PPA repository to download packages from. - platform: [ - { - arch: i386-pc-msdosdjgpp, - libs: libc-djgpp-dev libwatt-djgpp-dev djgpp-utils, - target: no-threads 386 DJGPP, - tests: none, - ppa: jwt27/djgpp-toolchain - }, { - arch: aarch64-linux-gnu, - libs: libc6-dev-arm64-cross, - target: linux-aarch64, - fips: no - }, { - arch: alpha-linux-gnu, - libs: libc6.1-dev-alpha-cross, - target: linux-alpha-gcc, - fips: no - }, { - arch: arm-linux-gnueabi, - libs: libc6-dev-armel-cross, - target: linux-armv4, - fips: no, - tests: -test_includes -test_store -test_x509_store - }, { - arch: arm-linux-gnueabihf, - libs: libc6-dev-armhf-cross, - target: linux-armv4, - fips: no, - tests: -test_includes -test_store -test_x509_store - }, { - # gcc hppa seems to have some potential compiler issues - # with -O2 on this platform, reduce optimization to -01 - arch: hppa-linux-gnu, - libs: libc6-dev-hppa-cross, - target: -static -O1 linux-generic32, - fips: no, - tests: -test_includes -test_store -test_x509_store - }, { - arch: m68k-linux-gnu, - libs: libc6-dev-m68k-cross, - target: -static -m68040 linux-latomic -Wno-stringop-overflow, - fips: no, - tests: -test_includes -test_store -test_x509_store - }, { - arch: mips-linux-gnu, - libs: libc6-dev-mips-cross, - target: -static linux-mips32, - fips: no, - tests: -test_includes -test_store -test_x509_store - }, { - arch: mips64-linux-gnuabi64, - libs: libc6-dev-mips64-cross, - target: -static linux64-mips64, - fips: no - }, { - arch: mipsel-linux-gnu, - libs: libc6-dev-mipsel-cross, - target: linux-mips32, - fips: no, - tests: -test_includes -test_store -test_x509_store - }, { - arch: powerpc64le-linux-gnu, - libs: libc6-dev-ppc64el-cross, - target: linux-ppc64le, - fips: no - }, { - arch: riscv64-linux-gnu, - libs: libc6-dev-riscv64-cross, - target: linux64-riscv64, - fips: no - }, { - arch: s390x-linux-gnu, - libs: libc6-dev-s390x-cross, - target: linux64-s390x, - fips: no - }, { - arch: sh4-linux-gnu, - libs: libc6-dev-sh4-cross, - target: no-async linux-latomic, - fips: no, - tests: -test_includes -test_store -test_x509_store - }, - - # These build with shared libraries but they crash when run - # They mirror static builds above in order to cover more of the - # code base. - { - arch: hppa-linux-gnu, - libs: libc6-dev-hppa-cross, - target: linux-generic32, - tests: none - }, { - arch: m68k-linux-gnu, - libs: libc6-dev-m68k-cross, - target: -mcfv4e -mxgot linux-latomic -Wno-stringop-overflow no-quic, - tests: none - }, { - arch: mips-linux-gnu, - libs: libc6-dev-mips-cross, - target: linux-mips32, - tests: none - }, { - arch: mips64-linux-gnuabi64, - libs: libc6-dev-mips64-cross, - target: linux64-mips64, - tests: none - }, - - # This build doesn't execute either with or without shared libraries. - { - arch: sparc64-linux-gnu, - libs: libc6-dev-sparc64-cross, - target: linux64-sparcv9, - tests: none - } - ] - runs-on: ubuntu-latest - steps: - - name: install package repository - if: matrix.platform.ppa != '' - run: | - sudo add-apt-repository ppa:${{ matrix.platform.ppa }} - - name: install packages - run: | - sudo apt-get update - sudo apt-get -yq --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install \ - gcc-${{ matrix.platform.arch }} \ - ${{ matrix.platform.libs }} - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - - name: config with FIPS - if: matrix.platform.fips != 'no' - run: | - ./config --banner=Configured --strict-warnings enable-fips enable-lms \ - --cross-compile-prefix=${{ matrix.platform.arch }}- \ - ${{ matrix.platform.target }} - - name: config without FIPS - if: matrix.platform.fips == 'no' - run: | - ./config --banner=Configured --strict-warnings enable-lms \ - --cross-compile-prefix=${{ matrix.platform.arch }}- \ - ${{ matrix.platform.target }} - - name: config dump - run: ./configdata.pm --dump - - - name: make - run: make -s -j4 - - - name: install qemu - if: matrix.platform.tests != 'none' - run: sudo apt-get -yq --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install qemu-user - - - name: Set QEMU environment - if: matrix.platform.qemucpu != '' - run: echo "QEMU_CPU=${{ matrix.platform.qemucpu }}" >> $GITHUB_ENV - - - name: Set OpenSSL caps environment - if: matrix.platform.opensslcapsname != '' - run: echo "OPENSSL_${{ matrix.platform.opensslcapsname }}=\ - ${{ matrix.platform.opensslcaps }}" >> $GITHUB_ENV - - - name: get cpu info - if: matrix.platform.tests != 'none' - run: | - cat /proc/cpuinfo - QEMU_LD_PREFIX=/usr/${{ matrix.platform.arch }} ./util/opensslwrap.sh version -c - - name: make all tests - if: github.event_name == 'push' && 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 != '' - 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' - run: | - .github/workflows/make-test \ - TESTS="test_evp*" \ - QEMU_LD_PREFIX=/usr/${{ matrix.platform.arch }} - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "cross-compiles@${{ matrix.platform.arch }}" - path: artifacts.tar.gz - if-no-files-found: ignore diff --git a/.github/workflows/ct-validation-daily.yml b/.github/workflows/ct-validation-daily.yml deleted file mode 100644 index 5ae384e5a5770..0000000000000 --- a/.github/workflows/ct-validation-daily.yml +++ /dev/null @@ -1,89 +0,0 @@ -# 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 - -name: Constant-time validation (daily) -# Verifies that ML-KEM and ML-DSA signing do not branch on secret data. -# -# The library is built with enable-ct-validation, which defines -# OPENSSL_CONSTANT_TIME_VALIDATION and causes secret regions to be marked -# as "uninitialised" from Valgrind memcheck's perspective. The tests are -# then run via "make test" with OSSL_VALGRIND_CT=yes, which makes -# OpenSSL::Test::test() wrap every test binary with: -# -# valgrind --tool=memcheck --track-origins=yes --error-exitcode=1 -# -# The wrapper chain (util/wrap.pl -> util/shlib_wrap.sh) is preserved, so -# LD_LIBRARY_PATH is set correctly for shared-library builds. Any -# control-flow branch or memory index that depends on secret data causes -# valgrind to exit with code 1, which propagates back through the test -# harness and fails the job. -# -# See include/internal/constant_time.h for the CONSTTIME_SECRET / -# CONSTTIME_DECLASSIFY macro documentation. -# -# Architecture note: Valgrind's memcheck supports x86_64, aarch64, s390x, -# and ppc64 well. GitHub Actions provides hosted runners for x86_64 -# (ubuntu-latest) and aarch64 (ubuntu-24.04-arm); we test both here. -# s390x and ppc64 runners are not available in the public GitHub Actions -# fleet, so they are not included. -# -# Package note: on Debian/Ubuntu the valgrind package bundles the C headers -# (valgrind/memcheck.h) — no separate -dev package is required. On Fedora -# the headers are in valgrind-devel; see Configure for the full list. - -on: - schedule: - - cron: '45 03 * * *' - workflow_dispatch: - -permissions: - contents: read - -jobs: - ct-validation: - if: github.repository == 'openssl/openssl' - strategy: - fail-fast: false - matrix: - include: - - name: linux-x86_64 - runs-on: ubuntu-latest - - name: linux-aarch64 - runs-on: ubuntu-24.04-arm - - name: CT validation (${{ matrix.name }}) - runs-on: ${{ matrix.runs-on }} - - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - - name: Install valgrind - # On Debian/Ubuntu the main 'valgrind' package includes - # /usr/include/valgrind/memcheck.h — no separate -dev package needed. - run: | - sudo apt-get -y update - sudo apt-get -y install valgrind - - - name: Configure with CT validation enabled - run: | - ./Configure enable-ct-validation - ./configdata.pm --dump - - - name: Build - run: make -j$(nproc) - - - name: Run ML-KEM and ML-DSA CT validation under Valgrind - # OSSL_VALGRIND_CT=yes causes OpenSSL::Test::test() to wrap each - # test binary with valgrind --track-origins=yes --error-exitcode=1. - # util/wrap.pl -> util/shlib_wrap.sh sets LD_LIBRARY_PATH first, so - # the shared libraries are found correctly. - run: | - make TESTS="test_internal_ml_kem test_internal_ml_dsa" \ - OSSL_VALGRIND_CT=yes \ - test diff --git a/.github/workflows/deploy-docs-openssl-org.yml b/.github/workflows/deploy-docs-openssl-org.yml deleted file mode 100644 index e3fd909bc6c09..0000000000000 --- a/.github/workflows/deploy-docs-openssl-org.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: "Trigger docs.openssl.org deployment" - -on: - push: - branches: - - "openssl-3.[0-9]+" - - "master" - paths: - - "doc/man*/**" - -permissions: {} - -jobs: - trigger: - if: github.repository == 'openssl/openssl' - runs-on: ubuntu-latest - steps: - - name: "Trigger deployment workflow" - run: | - gh workflow run -f branch=${GITHUB_REF_NAME} deploy-site.yaml - sleep 3 - RUN_ID=$(gh run list -w deploy-site.yaml -L 1 --json databaseId -q ".[0].databaseId") - gh run watch ${RUN_ID} --exit-status - env: - GH_REPO: "openssl/openssl-docs" - GH_TOKEN: ${{ secrets.OPENSSL_MACHINE_TOKEN }} diff --git a/.github/workflows/fips-checksums.yml b/.github/workflows/fips-checksums.yml deleted file mode 100644 index f82a604ab74ed..0000000000000 --- a/.github/workflows/fips-checksums.yml +++ /dev/null @@ -1,123 +0,0 @@ -# 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: FIPS Check and ABIDIFF -on: [pull_request] - -permissions: - contents: read - -jobs: - compute-checksums: - runs-on: ubuntu-latest - steps: - - name: install unifdef - run: | - sudo apt-get update - sudo apt-get -yq --no-install-suggests --no-install-recommends --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install unifdef - - name: create build dirs - run: | - mkdir ./build-pristine - mkdir ./source-pristine - mkdir ./build - mkdir ./source - mkdir ./artifact - - uses: actions/checkout@v6 - with: - repository: ${{ github.event.pull_request.base.repo.full_name }} - ref: ${{ github.event.pull_request.base.ref }} - path: source-pristine - persist-credentials: false - - name: config pristine - run: ../source-pristine/config enable-fips - working-directory: ./build-pristine - - name: config pristine dump - run: ./configdata.pm --dump - working-directory: ./build-pristine - - name: make build_generated pristine - run: make -s build_generated - working-directory: ./build-pristine - - name: make fips-checksums pristine - run: make fips-checksums - working-directory: ./build-pristine - - uses: actions/checkout@v6 - with: - path: source - persist-credentials: false - - name: config - run: ../source/config enable-fips - working-directory: ./build - - name: config dump - run: ./configdata.pm --dump - working-directory: ./build - - name: make build_generated - run: make -s build_generated - working-directory: ./build - - name: make fips-checksums - run: make fips-checksums - working-directory: ./build - - name: update checksums - run: | - cp -a build-pristine/providers/fips.module.sources.new source/providers/fips.module.sources - cp -a build-pristine/providers/fips-sources.checksums.new source/providers/fips-sources.checksums - cp -a build-pristine/providers/fips.checksum.new source/providers/fips.checksum - - name: make diff-fips-checksums - run: make diff-fips-checksums && touch ../artifact/fips_unchanged || ( touch ../artifact/fips_changed ; echo FIPS CHANGED ) - working-directory: ./build - - name: save PR number - run: echo ${{ github.event.number }} > ./artifact/pr_num - - name: save artifact - uses: actions/upload-artifact@v4 - with: - name: fips_checksum - path: artifact/ - - compute-abidiff: - runs-on: ubuntu-latest - env: - BUILD_OPTS: -g --strict-warnings enable-ktls enable-fips enable-egd enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-sctp enable-trace enable-zlib enable-zstd - steps: - - name: create build dirs - run: | - mkdir ./build-pristine - mkdir ./source-pristine - mkdir ./build - mkdir ./source - mkdir ./artifact - - name: install extra config support - run: sudo apt-get -y install libsctp-dev abigail-tools libzstd-dev zstd - - uses: actions/checkout@v6 - with: - repository: ${{ github.event.pull_request.base.repo.full_name }} - ref: ${{ github.event.pull_request.base.ref }} - path: source-pristine - persist-credentials: false - - name: config pristine - run: ../source-pristine/config --banner=Configured $BUILD_OPTS && perl configdata.pm --dump - working-directory: ./build-pristine - - name: make pristine - run: make -s -j4 - working-directory: ./build-pristine - - uses: actions/checkout@v6 - with: - path: source - persist-credentials: false - - name: config - run: ../source/config --banner=Configured $BUILD_OPTS && perl configdata.pm --dump - working-directory: ./build - - name: make - run: make -s -j4 - working-directory: ./build - - name: abidiff - run: abidiff --headers-dir1 build-pristine/include/openssl --headers-dir2 build/include/openssl --drop-private-types ./build-pristine/libcrypto.so ./build/libcrypto.so && abidiff --headers-dir1 build-pristine/include/openssl --headers-dir2 build/include/openssl --drop-private-types ./build-pristine/libssl.so ./build/libssl.so && touch ./artifact/abi_unchanged || ( touch ./artifact/abi_changed ; echo ABI CHANGED ) - - name: save PR number - run: echo ${{ github.event.number }} > ./artifact/pr_num - - name: save artifact - uses: actions/upload-artifact@v5 - with: - name: abidiff - path: artifact/ diff --git a/.github/workflows/fips-label.yml b/.github/workflows/fips-label.yml deleted file mode 100644 index 0dc8f576a0b26..0000000000000 --- a/.github/workflows/fips-label.yml +++ /dev/null @@ -1,141 +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 - -name: FIPS and ABI Changed Label -on: - workflow_run: - workflows: ["FIPS Check and ABIDIFF"] - types: - - completed - -permissions: - contents: read - -jobs: - apply-label: - permissions: - actions: read - pull-requests: write - runs-on: ubuntu-latest - if: ${{ github.event.workflow_run.event == 'pull_request' }} - steps: - - name: 'Download fipscheck artifact' - if: ${{ github.event.workflow_run.conclusion == 'success' }} - uses: actions/github-script@v8 - with: - script: | - var artifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: ${{github.event.workflow_run.id }}, - }); - var matchArtifact = artifacts.data.artifacts.filter((artifact) => { - return artifact.name == "fips_checksum" - })[0]; - var download = await github.rest.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: matchArtifact.id, - archive_format: 'zip', - }); - var fs = require('fs'); - fs.writeFileSync('${{github.workspace}}/artifact.zip', Buffer.from(download.data)); - - run: unzip artifact.zip - if: ${{ github.event.workflow_run.conclusion == 'success' }} - - name: 'Check artifact and apply' - if: ${{ github.event.workflow_run.conclusion == 'success' }} - uses: actions/github-script@v8 - with: - github-token: ${{secrets.GITHUB_TOKEN}} - script: | - var fs = require('fs'); - var pr_num = Number(fs.readFileSync('./pr_num')); - if ( fs.existsSync('./fips_changed') ) { - github.rest.issues.addLabels({ - issue_number: pr_num, - owner: context.repo.owner, - repo: context.repo.repo, - labels: ['severity: fips change'] - }); - } else if ( fs.existsSync('./fips_unchanged') ) { - var labels = await github.rest.issues.listLabelsOnIssue({ - issue_number: pr_num, - owner: context.repo.owner, - repo: context.repo.repo - }); - - for ( var label in labels.data ) { - if (labels.data[label].name == 'severity: fips change') { - github.rest.issues.removeLabel({ - issue_number: pr_num, - owner: context.repo.owner, - repo: context.repo.repo, - name: 'severity: fips change' - }); - } - } - } - - name: 'Cleanup artifact' - if: ${{ github.event.workflow_run.conclusion == 'success' }} - run: rm artifact.zip pr_num - - - name: 'Download abidiff artifact' - if: ${{ github.event.workflow_run.conclusion == 'success' }} - uses: actions/github-script@v8 - with: - script: | - var artifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: ${{github.event.workflow_run.id }}, - }); - var matchArtifact = artifacts.data.artifacts.filter((artifact) => { - return artifact.name == "abidiff" - })[0]; - var download = await github.rest.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: matchArtifact.id, - archive_format: 'zip', - }); - var fs = require('fs'); - fs.writeFileSync('${{github.workspace}}/artifact.zip', Buffer.from(download.data)); - - run: unzip artifact.zip - if: ${{ github.event.workflow_run.conclusion == 'success' }} - - name: 'Check artifact and apply' - if: ${{ github.event.workflow_run.conclusion == 'success' }} - uses: actions/github-script@v8 - with: - github-token: ${{secrets.GITHUB_TOKEN}} - script: | - var fs = require('fs'); - var pr_num = Number(fs.readFileSync('./pr_num')); - if ( fs.existsSync('./abi_changed') ) { - github.rest.issues.addLabels({ - issue_number: pr_num, - owner: context.repo.owner, - repo: context.repo.repo, - labels: ['severity: ABI change'] - }); - } else if ( fs.existsSync('./abi_unchanged') ) { - var labels = await github.rest.issues.listLabelsOnIssue({ - issue_number: pr_num, - owner: context.repo.owner, - repo: context.repo.repo - }); - - for ( var label in labels.data ) { - if (labels.data[label].name == 'severity: ABI change') { - github.rest.issues.removeLabel({ - issue_number: pr_num, - owner: context.repo.owner, - repo: context.repo.repo, - name: 'severity: ABI change' - }); - } - } - } diff --git a/.github/workflows/fuzz-checker.yml b/.github/workflows/fuzz-checker.yml deleted file mode 100644 index 3f7f864976174..0000000000000 --- a/.github/workflows/fuzz-checker.yml +++ /dev/null @@ -1,81 +0,0 @@ -# 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: Fuzz-checker CI - -on: [push] - -permissions: - contents: read - -jobs: - fuzz-checker: - strategy: - fail-fast: false - matrix: - fuzzy: [ - { - name: AFL, - config: enable-fuzz-afl no-module, - install: afl++, - cc: afl-clang-fast - }, { - name: libFuzzer, - config: enable-fuzz-libfuzzer enable-asan enable-ubsan -fno-sanitize=function, - libs: --with-fuzzer-lib=/usr/lib/llvm-18/lib/libFuzzer.a --with-fuzzer-include=/usr/include/clang/18/include/fuzzer, - install: libfuzzer-18-dev, - cc: clang-18, - linker: clang++-18, - tests: -test_memleak - }, { - name: libFuzzer+, - config: enable-fuzz-libfuzzer enable-asan enable-ubsan -fno-sanitize=function -fsanitize-coverage=trace-cmp -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION, - libs: --with-fuzzer-lib=/usr/lib/llvm-18/lib/libFuzzer.a --with-fuzzer-include=/usr/include/clang/18/include/fuzzer, - extra: enable-fips enable-lms enable-ec_nistp_64_gcc_128 -fno-sanitize=alignment enable-tls1_3 enable-weak-ssl-ciphers enable-rc5 enable-md2 enable-nextprotoneg, - install: libfuzzer-18-dev, - cc: clang-18, - linker: clang++-18, - tests: -test_memleak - } - ] - runs-on: ubuntu-24.04 - steps: - - name: install packages - run: | - sudo apt-get update - sudo apt-get -yq --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install ${{ matrix.fuzzy.install }} - - name: Adjust ASLR for sanitizer - run: | - sudo cat /proc/sys/vm/mmap_rnd_bits - sudo sysctl -w vm.mmap_rnd_bits=28 - - uses: actions/checkout@v6 - with: - persist-credentials: false - - - name: config - run: | - CC=${{ matrix.fuzzy.cc }} ./config --banner=Configured no-shared \ - ${{ matrix.fuzzy.config }} ${{ matrix.fuzzy.libs }} ${{ matrix.fuzzy.extra }} - - - name: config dump - run: ./configdata.pm --dump - - name: make with explicit linker - if: matrix.fuzzy.linker != '' - run: LDCMD=${{ matrix.fuzzy.linker }} make -s -j4 - - name: make sans explicit linker - if: matrix.fuzzy.linker == '' - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test restricted - if: matrix.fuzzy.tests != '' - run: AFL_MAP_SIZE=300000 make test HARNESS_JOBS=${HARNESS_JOBS:-4} TESTS="${{ matrix.fuzzy.tests }}" - - name: make test all - if: matrix.fuzzy.tests == '' - run: AFL_MAP_SIZE=300000 make test HARNESS_JOBS=${HARNESS_JOBS:-4} diff --git a/.github/workflows/interop-tests.yml b/.github/workflows/interop-tests.yml deleted file mode 100644 index 65e273f0e08c0..0000000000000 --- a/.github/workflows/interop-tests.yml +++ /dev/null @@ -1,103 +0,0 @@ -# Notes: -# /__w/openssl is the path that github bind-mounts into the container so the ci -# filesystem for this job can be reached. Please note that any changes made to -# this job involving file system paths should be made prefixed with, or relative -# to that directory -name: Interoperability tests with GnuTLS, NSS and OpenSSH -on: - schedule: - - cron: '55 02 * * *' - workflow_dispatch: - -permissions: {} - -jobs: - test: - if: github.repository == 'openssl/openssl' - runs-on: ubuntu-22.04 - container: - image: docker.io/fedora:43 - options: --sysctl net.ipv6.conf.lo.disable_ipv6=0 - timeout-minutes: 90 - strategy: - fail-fast: false - matrix: - COMPONENT: [gnutls, nss] - env: - COMPONENT: ${{ matrix.COMPONENT }} - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: Display environment - run: export - - name : Install needed tools - run: | - dnf -y install perl gcc make \ - rpmdevtools dnf-utils \ - tmt-all beakerlib \ - crypto-policies-scripts - - name: install interop tests - run: | - cd ${GITHUB_WORKSPACE} - git clone --branch=openssl-v0.2 --depth=1 https://gitlab.com/redhat-crypto/tests/interop.git - - name: build openssl as an rpm - run: | - mkdir -p /build/SPECS && cd /build && echo -e "%_topdir /build\n%_lto_cflags %{nil}" >~/.rpmmacros && rpmdev-setuptree - cd /build && cp ${GITHUB_WORKSPACE}/interop/openssl/openssl.spec SPECS/ && \ - cd SPECS/ && source ${GITHUB_WORKSPACE}/VERSION.dat && \ - sed -i "s/SOVERSION/$SHLIB_VERSION/" openssl.spec && \ - sed -i "s/^Version: .*\$/Version: $MAJOR.$MINOR.$PATCH/" openssl.spec - yum-builddep -y /build/SPECS/openssl.spec # just for sure nothing is missing - mkdir -p /build/SOURCES - tar --transform "s/^__w\/openssl\/openssl/openssl-$MAJOR.$MINOR.$PATCH/" -czf /build/SOURCES/openssl-$MAJOR.$MINOR.$PATCH.tar.gz "$GITHUB_WORKSPACE" - rpmbuild -bb /build/SPECS/openssl.spec - rpm -i --force /build/RPMS/x86_64/openssl-* - cp ${GITHUB_WORKSPACE}/interop/openssl/openssl.cnf /etc/pki/tls/openssl.cnf - - 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 - openssl version - echo "Finished - important to prevent unwanted output truncating" - openssh_interop: - if: github.repository == 'openssl/openssl' - name: "openssh interop ${{ matrix.branch.openssl }}" - strategy: - fail-fast: false - matrix: - branch: [ - { openssl: 'master', openssh: 'openssl-master', 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: ''} - ] - runs-on: ubuntu-latest - env: - EPHEMERAL_VM: yes - TEST_SSH_UNSAFE_PERMISSIONS: 1 - TEST_SSH_HOSTBASED_AUTH: yes - steps: - - name: install dependencies - run: | - sudo apt-get update - sudo apt-get -yq install autoconf zlib1g-dev - - uses: actions/checkout@v6 - with: - persist-credentials: false - repository: openssh/openssh-portable - fetch-depth: 1 - - name: setup ci - run: sh ./.github/setup_ci.sh ${{ matrix.branch.openssh }} ubuntu-latest - - name: autoreconf - run: autoreconf - - name: configure - run: sh ./.github/configure.sh ${{ matrix.branch.openssh }} - - name: make - run: | - make clean - make -s -j4 - - name: run tests - run: sh ./.github/run_test.sh diff --git a/.github/workflows/make-release.yml b/.github/workflows/make-release.yml deleted file mode 100644 index 746da6e0591e2..0000000000000 --- a/.github/workflows/make-release.yml +++ /dev/null @@ -1,48 +0,0 @@ -# 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: "Make release" - -on: - push: - tags: - - "openssl-*" - -permissions: {} - -jobs: - release: - runs-on: "releaser" - steps: - - name: "Checkout" - uses: "actions/checkout@v6" - with: - fetch-depth: 1 - ref: ${{ github.ref_name }} - github-server-url: "https://github.openssl.org/" - repository: "openssl/openssl" - token: ${{ secrets.GHE_TOKEN }} - path: ${{ github.ref_name }} - persist-credentials: false - - name: "Prepare assets" - env: - SIGNING_KEY_UID: ${{ vars.signing_key_uid }} - run: | - cd "$GITHUB_REF_NAME" - ./util/mktar.sh - mkdir -p assets && mv "$GITHUB_REF_NAME.tar.gz" assets/ && cd assets - openssl sha1 -r "$GITHUB_REF_NAME.tar.gz" > "$GITHUB_REF_NAME.tar.gz.sha1" - openssl sha256 -r "$GITHUB_REF_NAME.tar.gz" > "$GITHUB_REF_NAME.tar.gz.sha256" - gpg -u "$SIGNING_KEY_UID" -o "$GITHUB_REF_NAME.tar.gz.asc" -sba "$GITHUB_REF_NAME.tar.gz" - - name: "Create release" - env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - run: | - VERSION=$(echo "$GITHUB_REF_NAME" | cut -d "-" -f 2-) - PRE_RELEASE=$([[ "$GITHUB_REF_NAME" =~ alpha|beta ]] && echo "-p" || echo "") - NOTES=$(curl -s "https://api.openssl.org/release-metadata/news/?version=$VERSION&capture_title=False") - gh release create "$GITHUB_REF_NAME" $PRE_RELEASE -t "OpenSSL $VERSION" -d --notes "$NOTES" -R "$GITHUB_REPOSITORY" "$GITHUB_REF_NAME/assets/"* diff --git a/.github/workflows/make-test b/.github/workflows/make-test deleted file mode 100755 index c38d0de3439b9..0000000000000 --- a/.github/workflows/make-test +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env bash -set -eo pipefail - -cleanup() { - # Remove if nothing was generated. - [ -d artifacts ] && find artifacts -type d -empty -delete -} -trap cleanup EXIT - -# Make a central directory to store all output artifacts of our test run to -# avoid having to configure multiple upload-artifacts steps in the workflow -# file. -OSSL_CI_ARTIFACTS_PATH="artifacts/" -if [ -n "${GITHUB_RUN_NUMBER}" ]; then - OSSL_CI_ARTIFACTS_PATH="artifacts/github-${GITHUB_JOB}-${GITHUB_RUN_NUMBER}-${GITHUB_RUN_ID}/" -fi -mkdir -p "$OSSL_CI_ARTIFACTS_PATH" -export OSSL_CI_ARTIFACTS_PATH="$(cd "$OSSL_CI_ARTIFACTS_PATH"; pwd)" - -# 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} "$@" -RESULT=$? -set -e - -# Move an interesting subset of the test-runs data we want into the artifacts -# staging directory. -for test_name in quic_multistream; do - if [ -d "test-runs/test_${test_name}" ]; then - mv "test-runs/test_${test_name}" "$OSSL_CI_ARTIFACTS_PATH/" - fi -done - -# Log the artifact tree. -echo "::group::List of artifact files generated" -echo "Test suite exited with $RESULT, artifacts path is $OSSL_CI_ARTIFACTS_PATH" -(cd "$OSSL_CI_ARTIFACTS_PATH"; find . -type f | sort) -echo "::endgroup::" - -echo "Archive artifacts" -tar -czf artifacts.tar.gz $OSSL_CI_ARTIFACTS_PATH - -exit $RESULT diff --git a/.github/workflows/os-zoo.yml b/.github/workflows/os-zoo.yml deleted file mode 100644 index 66c8c2c2e85bb..0000000000000 --- a/.github/workflows/os-zoo.yml +++ /dev/null @@ -1,345 +0,0 @@ -# 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: OS Zoo CI - -on: - schedule: - - cron: '50 02 * * *' - workflow_dispatch: - -permissions: - contents: read - -jobs: - alpine: - if: github.repository == 'openssl/openssl' - strategy: - fail-fast: false - matrix: - tag: [edge, latest] - 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' || matrix.tag == 'edge' && '-Wno-stringop-overflow' || '' }} - CC: ${{ matrix.cc }} - steps: - - name: install packages - run: apk --no-cache add build-base perl linux-headers ${{ matrix.cc }} - - uses: actions/checkout@v6 - with: - persist-credentials: false - - 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 - - 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:11 - install: apt-get 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 - 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 - - image: docker.io/library/ubuntu:22.04 - 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/fedora:42 - 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 - install: dnf install -y gcc make perl-core - - image: docker.io/library/rockylinux:9 - 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 - - name: install packages - run: ${{ matrix.zoo.install }} - - name: config - run: ./config - - name: config dump - run: ./configdata.pm --dump - - name: make - run: make -j4 - - 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} - - macos: - if: github.repository == 'openssl/openssl' - strategy: - fail-fast: false - matrix: - os: [macos-14, macos-15, macos-15-intel] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: ./config --strict-warnings --banner=Configured enable-fips enable-demos enable-h3demo - - name: config dump - run: ./configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - sysctl machdep.cpu - ./util/opensslwrap.sh version -c - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} LHASH_WORKERS=${LHASH_WORKERS:-16} - - windows: - if: github.repository == 'openssl/openssl' - strategy: - fail-fast: false - matrix: - platform: - - os: windows-2022 - vcvars: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat - - os: windows-2025 - vcvars: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat - runs-on: ${{ matrix.platform.os }} - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: install nasm - run: | - choco install nasm - "C:\Program Files\NASM" | Out-File -FilePath "$env:GITHUB_PATH" -Append - - name: install jom - run: choco install jom - - name: prepare the build directory - run: mkdir _build - - name: config - working-directory: _build - shell: cmd - run: | - call "${{ matrix.platform.vcvars }}" - perl ..\Configure --banner=Configured --strict-warnings no-makedepend enable-fips - perl configdata.pm --dump - - name: build - working-directory: _build - shell: cmd - run: | - call "${{ matrix.platform.vcvars }}" - jom /j4 /S - - name: download coreinfo - run: | - mkdir _build\coreinfo - Invoke-WebRequest -Uri "https://download.sysinternals.com/files/Coreinfo.zip" -outfile "_build\coreinfo\Coreinfo.zip" - - name: get cpu info - working-directory: _build - run: | - 7z.exe x coreinfo/Coreinfo.zip - ./Coreinfo64.exe -accepteula -f - apps/openssl.exe version -c - - name: test - working-directory: _build - shell: cmd - run: | - call "${{ matrix.platform.vcvars }}" - jom test VERBOSE_FAILURE=yes HARNESS_JOBS=4 LHASH_WORKERS=16 - - linux-arm64: - runs-on: ubuntu-24.04-arm - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: config - run: ./config --strict-warnings enable-fips enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-trace - - name: config dump - run: ./configdata.pm --dump - - name: make - run: make -j4 - - name: get cpu info - run: ./util/opensslwrap.sh version -c - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} LHASH_WORKERS=${LHASH_WORKERS:-16} - - linux-x86: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: run container - run: | - CONTAINER_ID=$(podman run -d -v $(pwd):/mnt -w /mnt --platform=linux/i386 docker.io/i386/debian:13 sleep infinity) - echo "CONTAINER_ID=$CONTAINER_ID" >> "$GITHUB_ENV" - - name: install dependencies - run: - podman exec -t $CONTAINER_ID sh -c "apt-get update && apt-get install -y gcc perl make" - - name: config - run: | - podman exec -t $CONTAINER_ID sh -c \ - "./config --strict-warnings linux-x86 enable-demos enable-fips enable-lms enable-md2 enable-rc5 enable-trace" - - name: config dump - run: | - podman exec -t $CONTAINER_ID sh -c \ - "./configdata.pm --dump" - - name: make - run: | - podman exec -t $CONTAINER_ID sh -c \ - "make -j" - - name: get cpu info - run: | - cat /proc/cpuinfo - podman exec -t $CONTAINER_ID sh -c \ - "./util/opensslwrap.sh version -c" - - name: make test - run: | - podman exec -t $CONTAINER_ID sh -c \ - ".github/workflows/make-test" - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@linux-x86" - path: artifacts.tar.gz - - linux-ppc64le: - runs-on: linux-ppc64le - if: github.repository == 'openssl/openssl' - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: config - run: ./config --strict-warnings enable-fips enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-trace - - name: config dump - run: ./configdata.pm --dump - - name: make - run: make -j4 - - 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-s390x: - runs-on: linux-s390x - if: github.repository == 'openssl/openssl' - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: config - run: ./config --strict-warnings enable-fips enable-md2 enable-rc5 enable-trace - - name: config dump - run: ./configdata.pm --dump - - name: make - run: make -j4 - - 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-riscv64: - runs-on: linux-riscv64 - if: github.repository == 'openssl/openssl' - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: config - run: ./config enable-fips enable-ec_nistp_64_gcc_128 enable-md2 enable-rc5 enable-trace - - name: config dump - run: ./configdata.pm --dump - - name: make - run: make -j8 - - name: get cpu info - run: ./util/opensslwrap.sh version -c - - name: make test - env: - OPENSSL_riscvcap: RV64GC_ZBA_ZBB_ZBC_ZBS_ZKT_V - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} LHASH_WORKERS=${LHASH_WORKERS:-16} - - freebsd-x86_64: - runs-on: ubuntu-latest - if: github.repository == 'openssl/openssl' - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: config - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 - with: - operating_system: freebsd - version: "13.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 - with: - operating_system: freebsd - version: "13.4" - shutdown_vm: false - run: ./configdata.pm --dump - - name: make - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 - with: - operating_system: freebsd - version: "13.4" - shutdown_vm: false - run: make -j4 - - name: make test - uses: cross-platform-actions/action@46e8d7fb25520a8d6c64fd2b7a1192611da98eda #v0.30.0 - with: - operating_system: freebsd - version: "13.4" - run: | - ./util/opensslwrap.sh version -c - .github/workflows/make-test diff --git a/.github/workflows/oss-fuzz.yml b/.github/workflows/oss-fuzz.yml deleted file mode 100644 index 33af299a84b81..0000000000000 --- a/.github/workflows/oss-fuzz.yml +++ /dev/null @@ -1,42 +0,0 @@ -# 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: CIFuzz -on: - schedule: - - cron: '50 01 * * *' - workflow_dispatch: -permissions: - contents: read - -jobs: - Fuzzing: - if: github.event_name != 'schedule' || github.repository == 'openssl/openssl' - runs-on: ubuntu-latest - steps: - - name: Clear unnecessary files - run: | - 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 - - name: Build Fuzzers - uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master - with: - oss-fuzz-project-name: 'openssl' - dry-run: false - - name: Run Fuzzers - uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master - with: - oss-fuzz-project-name: 'openssl' - fuzz-seconds: 600 - dry-run: false - - name: Upload Crash - uses: actions/upload-artifact@v5 - if: failure() - with: - name: artifacts - path: ./out/artifacts diff --git a/.github/workflows/perl-minimal-checker.yml b/.github/workflows/perl-minimal-checker.yml deleted file mode 100644 index 9ca4e9b5092ec..0000000000000 --- a/.github/workflows/perl-minimal-checker.yml +++ /dev/null @@ -1,53 +0,0 @@ -# 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 -# in the file LICENSE in the source distribution or at -# https://www.openssl.org/source/license.html - -# Jobs run per pull request submission -name: Perl-minimal-checker CI -on: [pull_request, push] -permissions: - contents: read - -jobs: - perl-minimal-checker: - runs-on: ubuntu-latest - steps: - - name: Install perl 5.10 - run: | - pushd /tmp - mkdir perl - wget https://www.cpan.org/src/5.0/perl-5.10.1.tar.bz2 - 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 install - popd - - name: Install Test::More 0.96 - run: | - pushd /tmp - wget https://cpan.metacpan.org/authors/id/M/MS/MSCHWERN/Test-Simple-0.96.tar.gz - tar xf Test-Simple-0.96.tar.gz - cd Test-Simple-0.96 - PATH="/tmp/perl/bin:$PATH" - perl Makefile.PL - make -j$(nproc) && make install - perl -MTest::More -e 'print "$Test::More::VERSION\n"' - popd - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: Build openssl - run: ./config && make -j $(nproc) - - name: Install sed - run: sudo apt update && sudo apt install sed - - name: Check minimal version compliance - run: | - PM_FILES=($(find . -name "*.pm")) - perl -v - status=0 - for p in "${PM_FILES[@]}"; do perl -I"$(pwd)/util/perl" -I"$(pwd)" -I"$(pwd)/external/perl/Text-Template-1.56/lib" -c "$p" | sed -n '/@INC/{p; q1}' || status=1; done; - exit $status diff --git a/.github/workflows/prov-compat-label.yml b/.github/workflows/prov-compat-label.yml deleted file mode 100644 index cf2b44e169e50..0000000000000 --- a/.github/workflows/prov-compat-label.yml +++ /dev/null @@ -1,285 +0,0 @@ -# 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 -# in the file LICENSE in the source distribution or at -# https://www.openssl.org/source/license.html - -# This verifies that FIPS and legacy providers built against some earlier -# released versions continue to run against the current branch. - -name: Provider compatibility for PRs - -on: [pull_request] - -permissions: - contents: read - -env: - opts: enable-rc5 enable-md2 enable-weak-ssl-ciphers enable-zlib - -jobs: - fips-releases: - if: ${{ contains(github.event.pull_request.labels.*.name,'extended tests') }} - strategy: - matrix: - release: [ - # Formally released versions should be added here. - # `dir' it the directory inside the tarball. - # `tgz' is the name of the tarball. - # `url' is the download URL. - { - dir: openssl-3.0.0, - tgz: openssl-3.0.0.tar.gz, - url: "https://www.openssl.org/source/old/3.0/openssl-3.0.0.tar.gz", - }, - { - dir: openssl-3.0.8, - tgz: openssl-3.0.8.tar.gz, - url: "https://www.openssl.org/source/openssl-3.0.8.tar.gz", - }, - { - dir: openssl-3.0.9, - tgz: openssl-3.0.9.tar.gz, - url: "https://www.openssl.org/source/openssl-3.0.9.tar.gz", - }, - { - dir: openssl-3.1.2, - tgz: openssl-3.1.2.tar.gz, - url: "https://www.openssl.org/source/openssl-3.1.2.tar.gz", - }, - ] - - runs-on: ubuntu-latest - steps: - - name: create download directory - run: mkdir downloads - - name: download release source - run: wget --no-verbose ${{ matrix.release.url }} - working-directory: downloads - - name: unpack release source - run: tar xzf downloads/${{ matrix.release.tgz }} - - - name: localegen - run: sudo locale-gen tr_TR.UTF-8 - - - name: config release - run: | - ./config --banner=Configured enable-shared enable-fips ${{ env.opts }} - working-directory: ${{ matrix.release.dir }} - - name: config dump release - run: ./configdata.pm --dump - working-directory: ${{ matrix.release.dir }} - - - name: make release - run: make -s -j4 - working-directory: ${{ matrix.release.dir }} - - - name: create release artifacts - run: | - tar cz -H posix -f ${{ matrix.release.tgz }} ${{ matrix.release.dir }} - - - name: show module versions from release - run: | - ./util/wrap.pl -fips apps/openssl list -provider-path providers \ - -provider base \ - -provider default \ - -provider fips \ - -provider legacy \ - -providers - working-directory: ${{ matrix.release.dir }} - - - uses: actions/upload-artifact@v5 - with: - name: ${{ matrix.release.tgz }} - path: ${{ matrix.release.tgz }} - retention-days: 7 - - development-branches: - if: ${{ contains(github.event.pull_request.labels.*.name,'extended tests') }} - strategy: - matrix: - branch: [ - # Currently supported FIPS capable branches should be added here. - # `name' is the branch name used to checkout out. - # `dir' directory that will be used to build and test in. - # `tgz' is the name of the tarball use to keep the artifacts of - # the build. - { - name: '', - 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, - tgz: branch-3.4.tar.gz, - extra_config: "", - }, { - name: openssl-3.5, - dir: branch-3.5, - tgz: branch-3.5.tar.gz, - extra_config: "", - }, { - name: openssl-3.6, - dir: branch-3.6, - tgz: branch-3.6.tar.gz, - extra_config: "enable-lms", - }, { - name: openssl-4.0, - dir: branch-4.0, - tgz: branch-4.0.tar.gz, - extra_config: "enable-lms enable-tls-deprecated-ec", - }, { - name: master, - dir: branch-master, - tgz: branch-master.tar.gz, - extra_config: "enable-lms enable-tls-deprecated-ec", - }, - ] - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - path: ${{ matrix.branch.dir }} - repository: openssl/openssl - ref: ${{ matrix.branch.name }} - persist-credentials: false - - name: localegen - run: sudo locale-gen tr_TR.UTF-8 - - - name: config branch - run: | - ./config --banner=Configured enable-shared enable-fips ${{ env.opts }} ${{ matrix.branch.extra_config }} - working-directory: ${{ matrix.branch.dir }} - - name: config dump current - run: ./configdata.pm --dump - working-directory: ${{ matrix.branch.dir }} - - - name: make branch - run: make -s -j4 - working-directory: ${{ matrix.branch.dir }} - - - name: create branch artifacts - run: | - tar cz -H posix -f ${{ matrix.branch.tgz }} ${{ matrix.branch.dir }} - - - name: show module versions from branch - run: | - ./util/wrap.pl -fips apps/openssl list -provider-path providers \ - -provider base \ - -provider default \ - -provider fips \ - -provider legacy \ - -providers - working-directory: ${{ matrix.branch.dir }} - - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - working-directory: ${{ matrix.branch.dir }} - - - uses: actions/upload-artifact@v5 - with: - name: ${{ matrix.branch.tgz }} - path: ${{ matrix.branch.tgz }} - retention-days: 7 - - cross-testing: - if: ${{ contains(github.event.pull_request.labels.*.name,'extended tests') }} - needs: [fips-releases, development-branches] - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - # These can't be figured out earlier and included here as a variable - # substitution. - # - # 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, - 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.0 - - tree_a: PR - tree_b: branch-3.6 - - tree_a: PR - 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 - env: - B_BRANCH: ${{ matrix.tree_b }} - PR_LABELS: ${{ toJson(github.event.pull_request.labels.*.name) }} - run: | - b_ver=${B_BRANCH#branch-} - b_label="branch: $b_ver" - if [[ "$PR_LABELS" == *"$b_label"* ]]; then - echo "Skipping branches modified by the PR" - echo "skip=true" >> "$GITHUB_OUTPUT" - else - echo "skip=false" >> "$GITHUB_OUTPUT" - fi - - - uses: actions/download-artifact@v6.0.0 - if: steps.early_exit.outputs.skip != 'true' - with: - name: ${{ matrix.tree_a }}.tar.gz - - name: unpack first build - if: steps.early_exit.outputs.skip != 'true' - run: tar xzf "${{ matrix.tree_a }}.tar.gz" - - - uses: actions/download-artifact@v6.0.0 - if: steps.early_exit.outputs.skip != 'true' - with: - name: ${{ matrix.tree_b }}.tar.gz - - name: unpack second build - if: steps.early_exit.outputs.skip != 'true' - run: tar xzf "${{ matrix.tree_b }}.tar.gz" - - - 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/ - working-directory: ${{ matrix.tree_a }} - - - name: show module versions from cross validation - if: steps.early_exit.outputs.skip != 'true' - run: | - ./util/wrap.pl -fips apps/openssl list -provider-path providers \ - -provider base \ - -provider default \ - -provider fips \ - -provider legacy \ - -providers - working-directory: ${{ matrix.tree_b }} - - - name: get cpu info - if: steps.early_exit.outputs.skip != 'true' - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - working-directory: ${{ matrix.tree_b }} - - - name: run cross validation tests of FIPS from A with tree from B - if: steps.early_exit.outputs.skip != 'true' - run: | - make test HARNESS_JOBS=${HARNESS_JOBS:-4} - working-directory: ${{ matrix.tree_b }} diff --git a/.github/workflows/provider-compatibility.yml b/.github/workflows/provider-compatibility.yml deleted file mode 100644 index 806a61ad616e0..0000000000000 --- a/.github/workflows/provider-compatibility.yml +++ /dev/null @@ -1,277 +0,0 @@ -# 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 -# in the file LICENSE in the source distribution or at -# https://www.openssl.org/source/license.html - -# This verifies that FIPS and legacy providers built against some earlier -# released versions continue to run against the current branch. - -name: Provider compatibility across versions - -# Please note there is no point in running this job on PR as the tests -# will always run against the tips of the branches in the main repository -# and not the branch from the PR. -# Use the `extended tests` label to run provider compatibility checks -# on PRs. -on: - schedule: - - cron: '10 02 * * *' - workflow_dispatch: - -permissions: - contents: read - -env: - opts: enable-rc5 enable-md2 enable-weak-ssl-ciphers enable-zlib - -jobs: - fips-releases: - if: github.repository == 'openssl/openssl' - strategy: - matrix: - release: [ - # Formally released versions should be added here. - # `dir' it the directory inside the tarball. - # `tgz' is the name of the tarball. - # `url' is the download URL. - { - dir: openssl-3.0.0, - tgz: openssl-3.0.0.tar.gz, - url: "https://www.openssl.org/source/old/3.0/openssl-3.0.0.tar.gz", - }, - { - dir: openssl-3.0.8, - tgz: openssl-3.0.8.tar.gz, - url: "https://www.openssl.org/source/openssl-3.0.8.tar.gz", - }, - { - dir: openssl-3.0.9, - tgz: openssl-3.0.9.tar.gz, - url: "https://www.openssl.org/source/openssl-3.0.9.tar.gz", - }, - { - dir: openssl-3.1.2, - tgz: openssl-3.1.2.tar.gz, - url: "https://www.openssl.org/source/openssl-3.1.2.tar.gz", - }, - ] - - runs-on: ubuntu-latest - steps: - - name: create download directory - run: mkdir downloads - - name: download release source - run: wget --no-verbose ${{ matrix.release.url }} - working-directory: downloads - - name: unpack release source - run: tar xzf downloads/${{ matrix.release.tgz }} - - - name: localegen - run: sudo locale-gen tr_TR.UTF-8 - - - name: config release - run: | - ./config --banner=Configured enable-shared enable-fips ${{ env.opts }} - working-directory: ${{ matrix.release.dir }} - - name: config dump release - run: ./configdata.pm --dump - working-directory: ${{ matrix.release.dir }} - - - name: make release - run: make -s -j4 - working-directory: ${{ matrix.release.dir }} - - - name: create release artifacts - run: | - tar cz -H posix -f ${{ matrix.release.tgz }} ${{ matrix.release.dir }} - - - name: show module versions from release - run: | - ./util/wrap.pl -fips apps/openssl list -provider-path providers \ - -provider base \ - -provider default \ - -provider fips \ - -provider legacy \ - -providers - working-directory: ${{ matrix.release.dir }} - - - uses: actions/upload-artifact@v5 - with: - name: ${{ matrix.release.tgz }} - path: ${{ matrix.release.tgz }} - retention-days: 7 - - development-branches: - if: github.repository == 'openssl/openssl' - strategy: - matrix: - branch: [ - # Currently supported FIPS capable branches should be added here. - # `name' is the branch name used to checkout out. - # `dir' directory that will be used to build and test in. - # `tgz' is the name of the tarball use to keep the artifacts of - # 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, - extra_config: "", - }, { - name: openssl-3.5, - dir: branch-3.5, - tgz: branch-3.5.tar.gz, - extra_config: "", - }, { - name: openssl-3.6, - dir: branch-3.6, - tgz: branch-3.6.tar.gz, - extra_config: "enable-lms", - }, { - name: openssl-4.0, - dir: branch-4.0, - tgz: branch-4.0.tar.gz, - extra_config: "enable-lms enable-tls-deprecated-ec", - }, { - name: master, - dir: branch-master, - tgz: branch-master.tar.gz, - extra_config: "enable-lms enable-tls-deprecated-ec", - }, - ] - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - path: ${{ matrix.branch.dir }} - repository: openssl/openssl - ref: ${{ matrix.branch.name }} - persist-credentials: false - - name: localegen - run: sudo locale-gen tr_TR.UTF-8 - - - name: config branch - run: | - ./config --banner=Configured enable-shared enable-fips ${{ env.opts }} ${{ matrix.branch.extra_config }} - working-directory: ${{ matrix.branch.dir }} - - name: config dump current - run: ./configdata.pm --dump - working-directory: ${{ matrix.branch.dir }} - - - name: make branch - run: make -s -j4 - working-directory: ${{ matrix.branch.dir }} - - - name: create branch artifacts - run: | - tar cz -H posix -f ${{ matrix.branch.tgz }} ${{ matrix.branch.dir }} - - - name: show module versions from branch - run: | - ./util/wrap.pl -fips apps/openssl list -provider-path providers \ - -provider base \ - -provider default \ - -provider fips \ - -provider legacy \ - -providers - working-directory: ${{ matrix.branch.dir }} - - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - working-directory: ${{ matrix.branch.dir }} - - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} - working-directory: ${{ matrix.branch.dir }} - - - uses: actions/upload-artifact@v5 - with: - name: ${{ matrix.branch.tgz }} - path: ${{ matrix.branch.tgz }} - retention-days: 7 - - cross-testing: - if: github.repository == 'openssl/openssl' - needs: [fips-releases, development-branches] - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - # These can't be figured out earlier and included here as a variable - # substitution. - # - # 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, - 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 ] - steps: - - name: early exit checks - id: early_exit - run: | - if [ "${{ matrix.tree_a }}" = "${{ matrix.tree_b }}" ]; then - echo "Skipping because both are the same version" - echo "skip=true" >> "$GITHUB_OUTPUT" - else - echo "skip=false" >> "$GITHUB_OUTPUT" - fi - - - uses: actions/download-artifact@v6.0.0 - if: steps.early_exit.outputs.skip != 'true' - with: - name: ${{ matrix.tree_a }}.tar.gz - - name: unpack first build - if: steps.early_exit.outputs.skip != 'true' - run: tar xzf "${{ matrix.tree_a }}.tar.gz" - - - uses: actions/download-artifact@v6.0.0 - if: steps.early_exit.outputs.skip != 'true' - with: - name: ${{ matrix.tree_b }}.tar.gz - - name: unpack second build - if: steps.early_exit.outputs.skip != 'true' - run: tar xzf "${{ matrix.tree_b }}.tar.gz" - - - 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/ - working-directory: ${{ matrix.tree_a }} - - - name: show module versions from cross validation - if: steps.early_exit.outputs.skip != 'true' - run: | - ./util/wrap.pl -fips apps/openssl list -provider-path providers \ - -provider base \ - -provider default \ - -provider fips \ - -provider legacy \ - -providers - working-directory: ${{ matrix.tree_b }} - - - name: get cpu info - if: steps.early_exit.outputs.skip != 'true' - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - working-directory: ${{ matrix.tree_b }} - - - name: run cross validation tests of FIPS from A with tree from B - if: steps.early_exit.outputs.skip != 'true' - run: | - make test HARNESS_JOBS=${HARNESS_JOBS:-4} - working-directory: ${{ matrix.tree_b }} diff --git a/.github/workflows/riscv-more-cross-compiles.yml b/.github/workflows/riscv-more-cross-compiles.yml deleted file mode 100644 index cac662b8d34fc..0000000000000 --- a/.github/workflows/riscv-more-cross-compiles.yml +++ /dev/null @@ -1,326 +0,0 @@ -# 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: Cross Compile for RISC-V Extensions - -on: - pull_request: - types: [opened, reopened, edited, synchronize] - push: - schedule: - - cron: '35 02 * * *' - workflow_dispatch: - -permissions: - contents: read - -jobs: - cross-compilation-riscv: - # pull request title contains 'riscv' - # pull request title contains 'RISC-V' - # pull request body contains '[riscv ci]' - # 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' - strategy: - fail-fast: false - matrix: - # The platform matrix specifies: - # arch: the architecture to build for, this defines the tool-chain - # prefix {arch}- and the Debian compiler package gcc-{arch} - # name. - # libs: the Debian package for the necessary link/runtime libraries. - # target: the OpenSSL configuration target to use, this is passed - # directly to the config command line. - # fips: set to "no" to disable building FIPS, leave unset to - # build the FIPS provider. - # tests: omit this to run all the tests using QEMU, set it to "none" - # to never run the tests, otherwise its value is passed to - # the "make test" command to allow selective disabling of - # tests. - # qemucpu: optional; string that describes CPU properties. - # The string will be used to set the QEMU_CPU variable. - # opensslcapsname: optional; string that describes the postfix of the - # OpenSSL environment variable that defines CPU - # capabilities. E.g. "foo" will result in an - # environment variable with the name OPENSSL_foo. - # opensslcaps: optional; if opensslcapsname (see above) is set, then - # this string will be used as content for the OpenSSL - # capabilities variable. - # capscheck: optional; ERE pattern passed to grep -E to assert that - # "openssl info -cpusettings" output contains expected - # capabilities when using the hwprobe detection path. - # ppa: Launchpad PPA repository to download packages from. - platform: [ - # Scalar Crypto - { - # RV64GC with bitmanip and scalar crypto extensions - # crypto/aes/asm/aes-riscv64-zkn.pl - # crypto/modes/gcm128.c - # The following paths only use ZBB - # crypto/sha/asm/sha256-riscv64-zbb.pl - # crypto/sha/asm/sha512-riscv64-zbb.pl - # crypto/sm3/asm/sm3-riscv64-zbb.pl - arch: riscv64-linux-gnu, - libs: libc6-dev-riscv64-cross, - target: linux64-riscv64, - fips: no, - qemucpu: "rv64,zbb=true,zbc=true,zbkb=true,zknd=true,zkne=true", - opensslcapsname: riscvcap, # OPENSSL_riscvcap - opensslcaps: "rv64gc_zbb_zbc_zbkb_zknd_zkne" - }, { - # RV64GC ZBC ZBB, but without ZBKB - # crypto/modes/gcm128.c - arch: riscv64-linux-gnu, - libs: libc6-dev-riscv64-cross, - target: linux64-riscv64, - fips: no, - qemucpu: "rv64,zbc=true,zbb=true,zbkb=false", - opensslcapsname: riscvcap, # OPENSSL_riscvcap - opensslcaps: "rv64gc_zbc_zbb" - }, { - # RV64GC ZBC, but without ZBB/ZBKB - # crypto/modes/gcm128.c - arch: riscv64-linux-gnu, - libs: libc6-dev-riscv64-cross, - target: linux64-riscv64, - fips: no, - qemucpu: "rv64,zbc=true,zbb=false,zbkb=false", - opensslcapsname: riscvcap, # OPENSSL_riscvcap - opensslcaps: "rv64gc_zbc" - }, { - # Vector Crypto - # RV64GC V ZBB, but without ZVKB - # For chacha20 vector-only path from #24069 - # crypto/chacha/asm/chacha-riscv64-v-zbb.pl - arch: riscv64-linux-gnu, - libs: libc6-dev-riscv64-cross, - target: linux64-riscv64, - fips: no, - qemucpu: "rv64,v=true,vlen=128,zbb=true,zvbb=false,zvkb=false", - opensslcapsname: riscvcap, # OPENSSL_riscvcap - opensslcaps: "rv64gc_v_zbb" - }, { - # RV64GC V ZVKG, but without ZVKB - # crypto/modes/gcm128.c - arch: riscv64-linux-gnu, - libs: libc6-dev-riscv64-cross, - target: linux64-riscv64, - fips: no, - # 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", - opensslcapsname: riscvcap, # OPENSSL_riscvcap - opensslcaps: "rv64gc_v_zvkg" - }, { - # RV64GC V ZVKB ZVBC, but without ZVKG - # crypto/modes/gcm128.c - arch: riscv64-linux-gnu, - libs: libc6-dev-riscv64-cross, - target: linux64-riscv64, - fips: no, - # 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", - opensslcapsname: riscvcap, # OPENSSL_riscvcap - opensslcaps: "rv64gc_v_zvkb_zvbc" - }, { - # RV64GC V ZVKNED, but without ZVBB/ZVKB/ZVKG - # crypto/aes/asm/aes-riscv64-zvkned.pl - # providers/implementations/ciphers/cipher_aes_xts_hw.c - # providers/implementations/ciphers/cipher_aes_hw_rv64i.inc - # providers/implementations/ciphers/cipher_aes_gcm_hw_rv64i.inc - arch: riscv64-linux-gnu, - libs: libc6-dev-riscv64-cross, - target: linux64-riscv64, - fips: no, - qemucpu: "rv64,v=true,vlen=128,zvkned=true,zvbb=false,zvkb=false,zvkg=false", - opensslcapsname: riscvcap, # OPENSSL_riscvcap - opensslcaps: "rv64gc_v_zvkned" - }, { - # RV64GC with all currently OpenSSL-supported extensions - # crypto/chacha/chacha_riscv.c (with ZVKB) - # crypto/modes/gcm128.c (with ZVKG/ZVKB) - # crypto/sm3/asm/sm3-riscv64-zvksh.pl - # crypto/sm4/asm/sm4-riscv64-zvksed.pl - # crypto/aes/asm/aes-riscv64-zvbb-zvkg-zvkned.pl - # crypto/aes/asm/aes-riscv64-zvkb-zvkned.pl - # crypto/modes/asm/ghash-riscv64-zvkg.pl - # crypto/modes/asm/aes-gcm-riscv64-zvkb-zvkg-zvkned.pl - # crypto/modes/asm/ghash-riscv64-zvkb-zvbc.pl - # crypto/sha/asm/sha256-riscv64-zvkb-zvknha_or_zvknhb.pl - # crypto/sha/asm/sha512-riscv64-zvkb-zvknhb.pl - arch: riscv64-linux-gnu, - 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", - 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" - }, { - # RV64GC with all currently OpenSSL-supported extensions, with zvl256 - # crypto/sha/asm/sha512-riscv64-zvkb-zvknhb.pl - # crypto/sm3/asm/sm3-riscv64-zvksh.pl - arch: riscv64-linux-gnu, - 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", - 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" - }, { - # RV64GC with all currently OpenSSL-supported extensions, with zvl512 - # crypto/sha/asm/sha512-riscv64-zvkb-zvknhb.pl - # crypto/sm3/asm/sm3-riscv64-zvksh.pl - arch: riscv64-linux-gnu, - 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", - 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" - }, { - # Inline asm - # zbb/zbkb: - # include/crypto/md32_common.h - # include/crypto/modes.h - # crypto/chacha/chacha_enc.c - # crypto/des/des_local.h - # zknh (zbt/zpn not available in QEMU): - # crypto/sha/sha512.c - # crypto/sha/sha256.c - # zksh: - # crypto/sm3/sm3_local.h - arch: riscv64-linux-gnu, - libs: libc6-dev-riscv64-cross, - target: -march=rv64gc_zbb_zbkb_zknh_zksh linux64-riscv64, - fips: no, - qemucpu: "rv64,zbb=true,zbkb=true,zknh=true,zksh=true", - opensslcapsname: riscvcap, # OPENSSL_riscvcap - opensslcaps: "rv64gc_inlineasm" # for uploading artifact - }, { - # hwprobe path: RV64GC without V, no OPENSSL_riscvcap override. - # Forces the hwprobe_to_cap() code path (skipped when OPENSSL_riscvcap is set). - # V is absent so AT_HWCAP V bit is clear (VECTOR_CAPABLE=false). - # The rv64 CPU model includes ZBB/ZBC/ZBS/ZBKB by default. - arch: riscv64-linux-gnu, - libs: libc6-dev-riscv64-cross, - target: linux64-riscv64, - fips: no, - qemucpu: "rv64,zbb=true,zbc=true,zbs=true,zbkb=true,v=false", - # No opensslcapsname: hwprobe is used for capability detection. - opensslcaps: "rv64gc_novector_hwprobe", - # ZBB must be detected - capscheck: "_ZBB", - }, { - # hwprobe path: RV64GC + V + ZVKNED (vlen=128), no OPENSSL_riscvcap override. - # Forces the hwprobe_to_cap() code path (skipped when OPENSSL_riscvcap is set). - # V is present so AT_HWCAP V bit is set (VECTOR_CAPABLE=true). - arch: riscv64-linux-gnu, - libs: libc6-dev-riscv64-cross, - target: linux64-riscv64, - fips: no, - qemucpu: "rv64,v=true,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) - # via hwprobe despite being set in QEMU_CPU; tighten once CI moves to a - # newer QEMU that reports all Zvk* extensions via hwprobe. - capscheck: "_V", - } - ] - runs-on: ubuntu-latest - steps: - - name: install package repository - if: matrix.platform.ppa != '' - run: | - sudo add-apt-repository ppa:${{ matrix.platform.ppa }} - - name: install packages - run: | - sudo apt-get update - sudo apt-get -yq --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install \ - gcc-${{ matrix.platform.arch }} \ - ${{ matrix.platform.libs }} - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - - name: config with FIPS - if: matrix.platform.fips != 'no' - run: | - ./config --banner=Configured --strict-warnings enable-fips enable-lms \ - --cross-compile-prefix=${{ matrix.platform.arch }}- \ - ${{ matrix.platform.target }} - - name: config without FIPS - if: matrix.platform.fips == 'no' - run: | - ./config --banner=Configured --strict-warnings enable-lms \ - --cross-compile-prefix=${{ matrix.platform.arch }}- \ - ${{ matrix.platform.target }} - - name: config dump - run: ./configdata.pm --dump - - - name: make - run: make -s -j4 - - - name: install qemu - if: matrix.platform.tests != 'none' - run: sudo apt-get -yq --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install qemu-user - - - name: Set QEMU environment - if: matrix.platform.qemucpu != '' - run: echo "QEMU_CPU=${{ matrix.platform.qemucpu }}" >> $GITHUB_ENV - - - name: Set OpenSSL caps environment - if: matrix.platform.opensslcapsname != '' - run: echo "OPENSSL_${{ matrix.platform.opensslcapsname }}=\ - ${{ matrix.platform.opensslcaps }}" >> $GITHUB_ENV - - - name: get cpu info - run: cat /proc/cpuinfo - - - name: get openssl cpu info - if: matrix.platform.tests != 'none' - run: QEMU_LD_PREFIX=/usr/${{ matrix.platform.arch }} ./util/opensslwrap.sh info -cpusettings - - - name: check detected capabilities - if: matrix.platform.capscheck != '' - run: | - QEMU_LD_PREFIX=/usr/${{ matrix.platform.arch }} \ - ./util/opensslwrap.sh info -cpusettings | \ - grep -qE "${{ matrix.platform.capscheck }}" - - - name: make all tests - if: github.event_name == 'push' && 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 != '' - 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' - run: | - .github/workflows/make-test \ - TESTS="test_evp*" \ - QEMU_LD_PREFIX=/usr/${{ matrix.platform.arch }} - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "cross-compiles-riscv@${{ matrix.platform.opensslcaps }}" - path: artifacts.tar.gz - if-no-files-found: ignore diff --git a/.github/workflows/run-checker-ci.yml b/.github/workflows/run-checker-ci.yml deleted file mode 100644 index 70d105e3f2c00..0000000000000 --- a/.github/workflows/run-checker-ci.yml +++ /dev/null @@ -1,67 +0,0 @@ -# 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 - -# Jobs run per pull request submission -name: Run-checker CI -on: [pull_request, push] -permissions: - contents: read - -env: - OSSL_RUN_CI_TESTS: 1 - -jobs: - run-checker: - strategy: - fail-fast: false - matrix: - opt: [ - no-cmp, - no-cms, - no-dgram, - no-dh, - no-dtls, - no-ec, - no-ecx, - no-ml-dsa, - no-ml-kem, - no-http, - no-legacy, - no-sock, - no-sm2, - no-stdio, - no-threads, - no-thread-pool, - no-default-thread-pool, - no-tls, - no-tls1_2, - no-tls1_3, - enable-trace enable-fips, - no-quic, - -DOPENSSL_USE_IPV6=0 - ] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: CC=clang ./config --banner=Configured --strict-warnings ${{ matrix.opt }} - - name: config dump - run: ./configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - if [ -x apps/openssl ] ; then ./util/opensslwrap.sh version -c ; fi - - name: Check platform symbol usage - run: ./util/checkplatformsyms.pl ./util/platform_symbols/unix-symbols.txt ./libcrypto.so ./libssl.so - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} diff --git a/.github/workflows/run-checker-daily.yml b/.github/workflows/run-checker-daily.yml deleted file mode 100644 index 5a50f1627b8cd..0000000000000 --- a/.github/workflows/run-checker-daily.yml +++ /dev/null @@ -1,446 +0,0 @@ -# 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: Run-checker daily -# Jobs run daily - -on: - schedule: - - cron: '30 02 * * *' - workflow_dispatch: - -permissions: - contents: read - -jobs: - run-checker: - if: github.repository == 'openssl/openssl' - strategy: - fail-fast: false - matrix: - opt: [ - 386, - no-apps, - no-argon2, - no-aria, - no-asan, - no-asm, - no-async, - no-atexit, - no-autoalginit, - no-autoerrinit, - no-autoload-config, - no-bf, - no-blake2, - no-buildtest-c++, - no-bulk, - no-cached-fetch, - no-camellia, - no-cast, - no-chacha, - no-cmac, - no-comp, - enable-crypto-mdebug, - no-ct, - enable-demos, - no-deprecated, - no-des, - no-docs, - no-dsa, - no-dtls1, - no-dtls1_2, - no-dtls1_2-method, - no-dtls1-method, - enable-ec_nistp_64_gcc_128, - enable-egd, -# enable-external-tests, # Requires extra setup - enable-fips, - enable-fips enable-acvp-tests, - enable-fips no-tls1_3, - enable-fips no-des no-dsa no-ec2m, -# enable-fuzz-afl, # Requires extra setup -# enable-fuzz-libfuzzer, # Requires extra setup - no-gost, - enable-h3demo, - enable-hqinterop, - no-hmac-drbg-kdf, - no-hw, - no-idea, - no-ikev2kdf, - no-kbkdf, - no-krb5kdf, - enable-lms, - no-makedepend, - enable-md2, - no-md4, - no-mdc2, - no-msan, - no-multiblock, - no-nextprotoneg, - no-ocb, - no-pic, - no-poly1305, - no-posix-io, - no-psk, - no-pvkkdf, - no-rc2, - enable-rc5, - no-rdrand, - no-rfc3779, - no-ripemd, - no-rmd160, - no-scrypt, - no-secure-memory, - no-seed, - no-shared, - no-siphash, - no-siv, - no-sm2-precomp, - no-sm3, - no-sm4, - no-snmpkdf, - no-sock, - no-srtpkdf, - no-sse2, - no-sshkdf, - no-sskdf, - no-ssl, - no-ssl-trace, - enable-sslkeylog, - no-shared, - no-tests, - enable-tfo, - no-tls1, - no-tls1_1, - no-tls1_1-method, - no-tls1_2-method, - no-tls1-method, - enable-trace, - no-ubsan, - no-ui-console, - enable-unit-test, - no-uplink, - no-weak-ssl-ciphers, - no-whirlpool, - no-x942kdf, - no-x963kdf, - enable-zlib-dynamic, - -DOPENSSL_PEDANTIC_ZEROIZATION, - -DOPENSSL_PEDANTIC_ZEROIZATION enable-fips, - -DOPENSSL_NO_BUILTIN_OVERFLOW_CHECKING, - -DSSL3_ALIGN_PAYLOAD=4, - -DOPENSSL_TLS_SECURITY_LEVEL=0 - ] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: CC=clang ./config --strict-warnings --banner=Configured --strict-warnings ${{ matrix.opt }} - - name: config dump - run: ./configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - if [ -x apps/openssl ] ; then ./util/opensslwrap.sh version -c ; fi - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} - - run-checker-sctp: - if: github.repository == 'openssl/openssl' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: Install Dependencies for sctp option - run: | - sudo apt-get update - sudo apt-get -yq install lksctp-tools libsctp-dev - - - name: Check SCTP and enable auth - id: sctp_auth - continue-on-error: true - run: | - checksctp - sudo sysctl -w net.sctp.auth_enable=1 - - - name: config - if: steps.sctp_auth.outcome == 'success' && steps.sctp_auth.conclusion == 'success' - run: CC=clang ./config --strict-warnings --banner=Configured enable-sctp - - - name: config dump - if: steps.sctp_auth.outcome == 'success' && steps.sctp_auth.conclusion == 'success' - run: ./configdata.pm --dump - - - name: make - if: steps.sctp_auth.outcome == 'success' && steps.sctp_auth.conclusion == 'success' - run: make -s -j4 - - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - - name: make test - if: steps.sctp_auth.outcome == 'success' && steps.sctp_auth.conclusion == 'success' - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} - - enable_brotli_dynamic: - if: github.repository == 'openssl/openssl' - runs-on: ubuntu-latest - steps: - - name: install brotli - run: | - sudo apt-get update - sudo apt-get -yq --no-install-suggests --no-install-recommends --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install brotli libbrotli1 libbrotli-dev - - name: checkout openssl - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: ./config --strict-warnings enable-comp enable-brotli enable-brotli-dynamic && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} - - enable_zstd_dynamic: - if: github.repository == 'openssl/openssl' - runs-on: ubuntu-latest - steps: - - name: install zstd - run: | - sudo apt-get update - sudo apt-get -yq --no-install-suggests --no-install-recommends --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install zstd libzstd1 libzstd-dev - - name: checkout openssl - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: ./config --strict-warnings enable-comp enable-zstd enable-zstd-dynamic && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} - - enable_brotli_and_zstd_dynamic: - if: github.repository == 'openssl/openssl' - runs-on: ubuntu-latest - steps: - - name: install brotli and zstd - run: | - sudo apt-get update - sudo apt-get -yq --no-install-suggests --no-install-recommends --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install brotli libbrotli1 libbrotli-dev - sudo apt-get -yq --no-install-suggests --no-install-recommends --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install zstd libzstd1 libzstd-dev - - name: checkout openssl - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: ./config --strict-warnings enable-comp enable-brotli enable-brotli-dynamic enable-zstd enable-zstd-dynamic && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} - - malloc_failure_testing: - if: github.repository == 'openssl/openssl' - runs-on: ubuntu-latest - steps: - - name: checkout openssl - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: Adjust ASLR for sanitizer - run: | - sudo cat /proc/sys/vm/mmap_rnd_bits - sudo sysctl -w vm.mmap_rnd_bits=28 - - name: config - run: ./config --strict-warnings --banner=Configured --debug enable-asan enable-crypto-mdebug enable-allocfail-tests && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - continue-on-error: true - run: | - make TESTS="test_memfail" test - - enable_brotli_and_asan_ubsan: - if: github.repository == 'openssl/openssl' - runs-on: ubuntu-latest - steps: - - name: install brotli - run: | - sudo apt-get update - sudo apt-get -yq --no-install-suggests --no-install-recommends --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install brotli libbrotli1 libbrotli-dev - - name: checkout openssl - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: Adjust ASLR for sanitizer - run: | - sudo cat /proc/sys/vm/mmap_rnd_bits - sudo sysctl -w vm.mmap_rnd_bits=28 - - name: config - run: ./config --strict-warnings --banner=Configured --debug enable-asan enable-ubsan enable-comp enable-brotli -DPEDANTIC && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} OPENSSL_TEST_RAND_ORDER=0 - - enable_zstd_and_asan_ubsan: - if: github.repository == 'openssl/openssl' - runs-on: ubuntu-latest - steps: - - name: install zstd - run: | - sudo apt-get update - sudo apt-get -yq --no-install-suggests --no-install-recommends --allow-unauthenticated --allow-downgrades --allow-remove-essential --allow-change-held-packages install zstd libzstd1 libzstd-dev - - name: checkout openssl - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: Adjust ASLR for sanitizer - run: | - sudo cat /proc/sys/vm/mmap_rnd_bits - sudo sysctl -w vm.mmap_rnd_bits=28 - - name: config - run: ./config --strict-warnings --banner=Configured --debug enable-asan enable-ubsan enable-comp enable-zstd -DPEDANTIC && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} OPENSSL_TEST_RAND_ORDER=0 - - enable_tfo: - if: github.repository == 'openssl/openssl' - strategy: - matrix: - os: [ubuntu-latest, macos-15, macos-15-intel] - runs-on: ${{matrix.os}} - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: CC=gcc ./config --strict-warnings --banner=Configured enable-tfo && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: ./util/opensslwrap.sh version -c - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} - - enable_buildtest: - if: github.repository == 'openssl/openssl' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: ./config --strict-warnings --banner=Configured no-asm no-makedepend enable-buildtest-c++ enable-fips -D_DEFAULT_SOURCE && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} - - memory_sanitizer_slh_dsa: - if: github.repository == 'openssl/openssl' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: Adjust ASLR for sanitizer - run: | - sudo cat /proc/sys/vm/mmap_rnd_bits - sudo sysctl -w vm.mmap_rnd_bits=28 - - name: config - # --debug -O1 is to produce a debug build that runs in a reasonable amount of time - run: CC=clang ./config --strict-warnings --banner=Configured --debug no-shared -O1 -fsanitize=memory -DOSSL_SANITIZE_MEMORY -fno-optimize-sibling-calls enable-rc5 enable-md2 enable-ec_nistp_64_gcc_128 enable-fips && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} OPENSSL_TEST_RAND_ORDER=0 - - bn_debug: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: config - run: ./config --debug --strict-warnings -DBN_DEBUG --banner=Configured -DOPENSSL_NO_SECURE_MEMORY && perl configdata.pm --dump - - name: make - run: make -j4 # verbose, so no -s here - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: .github/workflows/make-test - - name: save artifacts - if: success() || failure() - uses: actions/upload-artifact@v5 - with: - name: "ci@bn_debug" - path: artifacts.tar.gz diff --git a/.github/workflows/run-checker-merge.yml b/.github/workflows/run-checker-merge.yml deleted file mode 100644 index 4342d97bb62c4..0000000000000 --- a/.github/workflows/run-checker-merge.yml +++ /dev/null @@ -1,114 +0,0 @@ -# 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: Run-checker merge -# Jobs run per merge to master - -on: [push] -permissions: - contents: read - -jobs: - run-checker: - strategy: - fail-fast: false - matrix: - opt: [ - enable-asan enable-ubsan no-shared no-asm -DOPENSSL_SMALL_FOOTPRINT -fno-sanitize=function, - no-dso, - no-ec2m enable-fips, - no-shared, - no-err, - no-filenames, - enable-ubsan no-asm -DOPENSSL_SMALL_FOOTPRINT -fno-sanitize=function, - no-module, - no-ocsp, - no-pinshared, - no-srp, - no-srtp, - no-ts, - no-ui, - no-integrity-only-ciphers, - enable-weak-ssl-ciphers, - enable-zlib, - enable-pie, - ] - runs-on: ubuntu-latest - steps: - - name: Adjust ASLR for sanitizer - run: | - sudo cat /proc/sys/vm/mmap_rnd_bits - sudo sysctl -w vm.mmap_rnd_bits=28 - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: CC=clang ./config --strict-warnings --banner=Configured ${{ matrix.opt }} - - name: config dump - run: ./configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - if [ -x apps/openssl ] ; then ./util/opensslwrap.sh version -c ; fi - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} - - jitter: - runs-on: ubuntu-latest - steps: - - name: checkout openssl - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout jitter - uses: actions/checkout@v6 - with: - repository: smuellerDD/jitterentropy-library - ref: v3.5.0 - path: jitter - persist-credentials: false - - name: build jitter - run: make -C jitter/ - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: config - run: ./config --with-rand-seed=none enable-jitter enable-fips-jitter --with-jitter-include=jitter/ --with-jitter-lib=jitter/ -DOPENSSL_DEFAULT_SEED_SRC=JITTER && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: make test HARNESS_JOBS=${HARNESS_JOBS:-4} - - threads_sanitizer_atomic_fallback: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: Adjust ASLR for sanitizer - run: | - sudo cat /proc/sys/vm/mmap_rnd_bits - sudo sysctl -w vm.mmap_rnd_bits=28 - - name: config - run: CC=clang ./config --strict-warnings --banner=Configured no-shared no-fips -g -fsanitize=thread -DBROKEN_CLANG_ATOMICS && perl configdata.pm --dump - - name: make - run: make -s -j4 - - name: get cpu info - run: | - cat /proc/cpuinfo - ./util/opensslwrap.sh version -c - - name: make test - run: make test V=1 TESTS="test_lhash test_threads test_internal_provider test_provfetch test_provider test_pbe test_evp_kdf test_pkcs12 test_store test_evp test_quic*" diff --git a/.github/workflows/run_quic_interop.yml b/.github/workflows/run_quic_interop.yml deleted file mode 100644 index f7fca6f373d51..0000000000000 --- a/.github/workflows/run_quic_interop.yml +++ /dev/null @@ -1,203 +0,0 @@ -name: "Run openssl quic interop testing" - -on: - schedule: - - cron: '40 02 * * *' - workflow_dispatch: - inputs: - only_interop: - type: boolean - required: false - default: false - description: "Run only interop jobs (skip building/pushing containers)" - -permissions: {} - -jobs: - update_quay_container: - if: ${{ github.repository == 'openssl/openssl' && !inputs.only_interop }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: "log in to quay.io" - run: | - docker login -u openssl-ci+machine -p ${{ secrets.QUAY_IO_PASSWORD }} quay.io - - name: "Build container" - run: | - cd test/quic-openssl-docker/ - docker build -t quay.io/openssl-ci/openssl-quic-interop:latest . - - name: "Push to quay" - run: | - docker push quay.io/openssl-ci/openssl-quic-interop:latest - - update_msquic_quay_container: - if: ${{ github.repository == 'openssl/openssl' && !inputs.only_interop }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - repository: microsoft/msquic - ref: main - submodules: recursive - persist-credentials: false - - name: "log in to quay.io" - run: | - docker login -u openssl-ci+machine -p ${{ secrets.QUAY_IO_PASSWORD }} quay.io - - name: Patch qns.Dockerfile - run: | - sed -i 's/RUN cmake -DQUIC_BUILD_TOOLS=on -DQUIC_ENABLE_LOGGING=on ../RUN cmake -DQUIC_BUILD_TOOLS=on -DQUIC_ENABLE_LOGGING=on -DQUIC_TLS_LIB=openssl ../' ./scripts/qns.Dockerfile - if grep -q "RUN cmake -DQUIC_BUILD_TOOLS=on -DQUIC_ENABLE_LOGGING=on -DQUIC_TLS_LIB=openssl .." ./scripts/qns.Dockerfile; then echo "Patched successfully"; else exit 1; fi - - name: "Build container" - run: | - docker build -f ./scripts/qns.Dockerfile -t quay.io/openssl-ci/msquic-openssl:latest . - - name: "Push to quay" - run: | - docker push quay.io/openssl-ci/msquic-openssl:latest - - run_quic_interop_openssl_client: - if: ${{ !inputs.only_interop }} - needs: [update_quay_container, update_msquic_quay_container] - runs-on: ubuntu-latest - strategy: - matrix: - tests: [http3, transfer, handshake, retry, chacha20, resumption, multiplexing, ipv6] - servers: [quic-go, ngtcp2, mvfst, quiche, nginx, msquic, haproxy, msquic-openssl] - exclude: - - servers: msquic - tests: retry - - servers: msquic-openssl - tests: retry - fail-fast: false - steps: &client_steps - - uses: actions/checkout@v6 - with: - repository: 'quic-interop/quic-interop-runner' - fetch-depth: 0 - persist-credentials: false - - name: Install python requirements - run: | - for i in {1..3}; do pip install -r requirements.txt && break; sleep 10; done - - name: Add tshark repo - run: | - for i in {1..3}; do sudo add-apt-repository ppa:wireshark-dev/stable && break; sleep 10; done - - name: Update apt repos - run: | - for i in {1..3}; do sudo apt-get update && break; sleep 10; done - - name: Install tshark - run: | - for i in {1..3}; do sudo apt-get install -y tshark && break; sleep 10; done - - name: Patch implementations file - run: | - jq '. + { - "openssl": { image: "quay.io/openssl-ci/openssl-quic-interop" - , url: "https://github.com/openssl/openssl" - , role: "both" - }, - "msquic-openssl": { image: "quay.io/openssl-ci/msquic-openssl" - , url: "https://github.com/microsoft/msquic" - , role: "both" - }}' ./implementations_quic.json > ./implementations.tmp - mv ./implementations.tmp implementations_quic.json - - name: Set up docker - uses: docker/setup-docker-action@efe9e3891a4f7307e689f2100b33a155b900a608 # v4.5.0 - with: - version: "28.1.1" - - name: Set up docker compose - uses: docker/setup-compose-action@364cc21a5de5b1ee4a7f5f9d3fa374ce0ccde746 # v1.2.0 - with: - version: "v2.36.2" - - name: Check docker version - run: | - docker version - docker compose version - - name: "Run interop with openssl client" - run: | - python3 ./run.py -c openssl -t ${{ matrix.tests }} -s ${{ matrix.servers }} --log-dir ./logs-client -d - - run_quic_interop_openssl_server: - if: ${{ !inputs.only_interop }} - needs: [update_quay_container, update_msquic_quay_container] - runs-on: ubuntu-latest - strategy: - matrix: - tests: [http3, transfer, handshake, retry, chacha20, resumption, amplificationlimit, ipv6] - clients: [quic-go, ngtcp2, mvfst, quiche, msquic, openssl, chrome, msquic-openssl] - exclude: - - clients: mvfst - tests: amplificationlimit - fail-fast: false - steps: &server_steps - - uses: actions/checkout@v6 - with: - repository: 'quic-interop/quic-interop-runner' - fetch-depth: 0 - persist-credentials: false - - name: Install python requirements - run: | - for i in {1..3}; do pip install -r requirements.txt && break; done - - name: Add tshark repo - run: | - for i in {1..3}; do sudo add-apt-repository ppa:wireshark-dev/stable && break; done - - name: Update apt repos - run: | - for i in {1..3}; do sudo apt-get update && break; done - - name: Install tshark - run: | - for i in {1..3}; do sudo apt-get install -y tshark && break; done - - name: Patch implementations file - run: | - jq '. + { - "openssl": { image: "quay.io/openssl-ci/openssl-quic-interop" - , url: "https://github.com/openssl/openssl" - , role: "both" - }, - "msquic-openssl": { image: "quay.io/openssl-ci/msquic-openssl" - , url: "https://github.com/microsoft/msquic" - , role: "both" - }}' ./implementations_quic.json > ./implementations.tmp - mv ./implementations.tmp implementations_quic.json - - name: Set up docker - uses: docker/setup-docker-action@efe9e3891a4f7307e689f2100b33a155b900a608 # v4.5.0 - with: - version: "28.1.1" - - name: Set up docker compose - uses: docker/setup-compose-action@364cc21a5de5b1ee4a7f5f9d3fa374ce0ccde746 # v1.2.0 - with: - version: "v2.36.2" - - name: Check docker version - run: | - docker version - docker compose version - - name: "Run interop with openssl server" - run: | - python3 ./run.py -s openssl -t "${{ matrix.tests }}" -c "${{ matrix.clients }}" --log-dir ./logs-server -d - - run_quic_interop_openssl_client_only: - if: ${{ inputs.only_interop }} - runs-on: ubuntu-latest - strategy: - matrix: - tests: [http3, transfer, handshake, retry, chacha20, resumption, multiplexing, ipv6] - servers: [quic-go, ngtcp2, mvfst, quiche, nginx, msquic, haproxy, msquic-openssl] - exclude: - - servers: msquic - tests: retry - - servers: msquic-openssl - tests: retry - fail-fast: false - steps: *client_steps - - run_quic_interop_openssl_server_only: - if: ${{ inputs.only_interop }} - runs-on: ubuntu-latest - strategy: - matrix: - tests: [http3, transfer, handshake, retry, chacha20, resumption, amplificationlimit, ipv6] - clients: [quic-go, ngtcp2, mvfst, quiche, msquic, openssl, chrome, msquic-openssl] - exclude: - - clients: mvfst - tests: amplificationlimit - fail-fast: false - steps: *server_steps diff --git a/.github/workflows/static-analysis-on-prem.yml b/.github/workflows/static-analysis-on-prem.yml deleted file mode 100644 index 46781b66b650f..0000000000000 --- a/.github/workflows/static-analysis-on-prem.yml +++ /dev/null @@ -1,42 +0,0 @@ -# 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: Static Analysis On Prem - -on: - schedule: - - cron: '25 02 * * *' - workflow_dispatch: - -permissions: - contents: read - -jobs: - coverity-analysis: - if: github.repository == 'openssl/openssl' - runs-on: ubuntu-latest - container: quay.io/openssl-ci/coverity-analysis:2024.3.1 - steps: - - name: Put license - run: echo ${{ secrets.COVERITY_LICENSE }} | base64 -d > /opt/coverity-analysis/bin/license.dat - - name: Put auth key file - run: | - echo ${{ secrets.COVERITY_AUTH_KEY }} | base64 -d > /auth_key_file.txt - chmod 0600 /auth_key_file.txt - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: Config - run: CC=gcc ./config --strict-warnings --banner=Configured --debug enable-lms enable-fips enable-rc5 enable-md2 enable-nextprotoneg enable-weak-ssl-ciphers enable-zlib enable-ec_nistp_64_gcc_128 no-shared enable-buildtest-c++ enable-external-tests -DPEDANTIC - - name: Config dump - run: ./configdata.pm --dump - - name: Make - run: cov-build --dir cov-int make -s -j4 - - name: Analyze - run: cov-analyze --dir cov-int --strip-path $(pwd) - - name: Commit defects - run: cov-commit-defects --url https://coverity.openssl.org:443 --stream OpenSSL --dir cov-int --auth-key-file /auth_key_file.txt diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml deleted file mode 100644 index de052d4a5c541..0000000000000 --- a/.github/workflows/static-analysis.yml +++ /dev/null @@ -1,49 +0,0 @@ -# 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: Static Analysis - -#Run once a day -on: - schedule: - - cron: '20 02 * * *' - workflow_dispatch: - -permissions: - contents: read - -jobs: - coverity: - if: github.repository == 'openssl/openssl' - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: tool download - run: | - wget https://scan.coverity.com/download/linux64 \ - --post-data "token=${{ secrets.COVERITY_TOKEN }}&project=openssl%2Fopenssl" \ - --progress=dot:giga -O coverity_tool.tgz - - name: config - run: CC=gcc ./config --strict-warnings --banner=Configured --debug enable-lms enable-fips enable-rc5 enable-md2 enable-nextprotoneg enable-weak-ssl-ciphers enable-zlib enable-ec_nistp_64_gcc_128 no-shared enable-buildtest-c++ enable-external-tests -DPEDANTIC - - name: config dump - run: ./configdata.pm --dump - - name: tool install - run: tar xzf coverity_tool.tgz - - name: make - run: ./cov-analysis*/bin/cov-build --dir cov-int make -s -j4 - - name: archive - run: tar czvf openssl.tgz cov-int - - name: Coverity upload - run: | - curl --form token="${{ secrets.COVERITY_TOKEN }}" \ - --form email=openssl-commits@openssl.org \ - --form file=@openssl.tgz \ - --form version="`date -u -I` `git rev-parse --short HEAD`" \ - --form description="analysis of `git branch --show-current`" \ - https://scan.coverity.com/builds?project=openssl%2Fopenssl diff --git a/.github/workflows/style-checks.yml b/.github/workflows/style-checks.yml deleted file mode 100644 index b345ae5110998..0000000000000 --- a/.github/workflows/style-checks.yml +++ /dev/null @@ -1,30 +0,0 @@ -# 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: Coding style validation - -on: [pull_request] - -jobs: - check-style: - runs-on: ubuntu-latest - 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 }} - run: | - { - echo 'CHANGED_FILES<> "$GITHUB_ENV" - - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd #v3.0.1 - with: - extra_args: "--files $CHANGED_FILES" diff --git a/.github/workflows/valgrind-daily.yml b/.github/workflows/valgrind-daily.yml deleted file mode 100644 index ac5f7e052ef85..0000000000000 --- a/.github/workflows/valgrind-daily.yml +++ /dev/null @@ -1,66 +0,0 @@ -# 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 - -name: Test valgrind suppression file -# Jobs run daily - -on: - schedule: - - cron: '30 02 * * *' - workflow_dispatch: - -permissions: - contents: read - -jobs: - check-valgrind-suppressions: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: Install valgrind - run: | - sudo apt-get -y update - sudo apt-get -y install valgrind - - name: Get parse suppressions script - run: | - wget https://raw.githubusercontent.com/coqui-ai/STT/refs/tags/v1.4.0/parse_valgrind_suppressions.sh - echo "7414fcb9405f8bd1632442a0b66ffb35457994c6b8b49b2aa91530cf9a7ff645 ./parse_valgrind_suppressions.sh" > ./valgrind_suppressions.sha256 - sha256sum -c ./valgrind_suppressions.sha256 - chmod 755 ./parse_valgrind_suppressions.sh - - name: Configure - run: | - ./Configure -DOPENSSL_VALGRIND_TEST - ./configdata.pm --dump - - name: Make - run: | - make -j - - name: Make test - run: | - # The quic radix and multistream test times out under valgrind in ci - make TESTS="-test_quic_radix -test_quic_multistream" OSSL_USE_VALGRIND=yes test - - name: Check for leaks - run: | - set +e - NUM_LOGS=$(find . -name 'valgrind.log.*' | wc -l) - echo "Found $NUM_LOGS valgrind logs" - if [ $NUM_LOGS == 0 ]; then - echo "No logs found!" - exit 1 - fi - for i in $(find . -name 'valgrind.log.*'); do - ./parse_valgrind_suppressions.sh $i >> ./new_suppressions.txt - done - NEW_SUPPRESSION_LINES=$(cat ./new_suppressions.txt | wc -l) - if [ $NEW_SUPPRESSION_LINES != 0 ]; then - echo "New Suppressions Found that need to be addressed!" - cat ./new_suppressions.txt - exit 1 - fi - echo "No new suppressions found" - exit 0 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml deleted file mode 100644 index 8dfea360771ef..0000000000000 --- a/.github/workflows/windows.yml +++ /dev/null @@ -1,296 +0,0 @@ -# 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: Windows GitHub CI - -on: [pull_request, push] - -permissions: - contents: read - -jobs: - shared: - # Run a job for each of the specified target architectures: - strategy: - matrix: - platform: - - arch: amd64 - os: windows-2022 - config: enable-lms enable-fips - vcvars: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat - - arch: amd64 - os: windows-2025 - config: enable-lms enable-fips no-thread-pool no-quic - vcvars: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat - - arch: x86 - os: windows-2022 - config: no-fips enable-lms - vcvars: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars32.bat - runs-on: ${{ matrix.platform.os }} - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: install nasm - run: | - choco install nasm ${{ matrix.platform.arch == 'x86' && '--x86' || '' }} - "C:\Program Files${{ matrix.platform.arch == 'x86' && ' (x86)' || '' }}\NASM" | Out-File -FilePath "$env:GITHUB_PATH" -Append - - name: install jom - run: choco install jom - - name: prepare the build directory - run: mkdir _build - - name: config - working-directory: _build - shell: cmd - run: | - call "${{ matrix.platform.vcvars }}" - perl ..\Configure --banner=Configured --strict-warnings no-makedepend -DOSSL_WINCTX=openssl ${{ matrix.platform.config }} - perl configdata.pm --dump - - name: build - working-directory: _build - shell: cmd - run: | - call "${{ matrix.platform.vcvars }}" - jom /j4 /S - - name: download coreinfo - run: | - mkdir _build\coreinfo - Invoke-WebRequest -Uri "https://download.sysinternals.com/files/Coreinfo.zip" -outfile "_build\coreinfo\Coreinfo.zip" - - name: Gather openssl version info - working-directory: _build - run: | - apps/openssl.exe version -v - apps/openssl.exe version -v | %{($_ -split '\s+')[1]} - apps/openssl.exe version -v | %{($_ -split '\s+')[1] -replace '([0-9]+\.[0-9]+)(\..*)','$1'} - echo "OSSL_VERSION=$(apps/openssl.exe version -v | %{($_ -split '\s+')[1] -replace '([0-9]+\.[0-9]+)(\..*)','$1'})" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append - echo "OSSL_MAJOR=$(apps/openssl.exe version -v | %{($_ -split '\s+')[1] -replace '([0-9]+)\.[0-9]+(\..*)','$1'})" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append - - name: Set registry keys - working-directory: _build - run: | - echo ${Env:OSSL_VERSION} - reg.exe add HKLM\SOFTWARE\OpenSSL-${Env:OSSL_VERSION}-openssl /v OPENSSLDIR /t REG_EXPAND_SZ /d TESTOPENSSLDIR /reg:32 - reg.exe add HKLM\SOFTWARE\OpenSSL-${Env:OSSL_VERSION}-openssl /v MODULESDIR /t REG_EXPAND_SZ /d TESTOPENSSLDIR /reg:32 - reg.exe query HKLM\SOFTWARE\OpenSSL-${Env:OSSL_VERSION}-openssl /v OPENSSLDIR /reg:32 - - name: get cpu info - working-directory: _build - continue-on-error: true - run: | - 7z.exe x coreinfo/Coreinfo.zip - ./Coreinfo64.exe -accepteula -f - ./apps/openssl.exe version -c - - name: Check platform symbol usage - working-directory: _build - shell: cmd - run: | - call "${{ matrix.platform.vcvars }}" - perl ../util/checkplatformsyms.pl ../util/platform_symbols/windows-symbols.txt libcrypto-%OSSL_MAJOR%${{ matrix.platform.arch == 'amd64' && '-x64' || '' }}.dll ./libssl-%OSSL_MAJOR%${{ matrix.platform.arch == 'amd64' && '-x64' || '' }}.dll - - name: test - working-directory: _build - shell: cmd - run: | - call "${{ matrix.platform.vcvars }}" - jom test VERBOSE_FAILURE=yes TESTS=-test_fuzz* HARNESS_JOBS=4 - - name: install - # Run on 64 bit only as 32 bit is slow enough already - if: ${{ matrix.platform.arch == 'amd64' }} - working-directory: _build - shell: cmd - run: | - call "${{ matrix.platform.vcvars }}" - mkdir _dest - jom /j4 install DESTDIR=_dest - - plain: - runs-on: windows-2022 - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: prepare the build directory - run: mkdir _build - - name: install jom - run: choco install jom - - name: config - working-directory: _build - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - perl ..\Configure --banner=Configured --strict-warnings enable-demos no-makedepend no-shared no-fips enable-md2 enable-rc5 enable-weak-ssl-ciphers enable-trace enable-crypto-mdebug -DOSSL_WINCTX=openssl VC-WIN64A-masm - perl configdata.pm --dump - - name: build - working-directory: _build - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - jom /j4 /S - - name: download coreinfo - run: | - mkdir _build\coreinfo - Invoke-WebRequest -Uri "https://download.sysinternals.com/files/Coreinfo.zip" -outfile "_build\coreinfo\Coreinfo.zip" - - name: get cpu info - working-directory: _build - continue-on-error: true - run: | - 7z.exe x coreinfo/Coreinfo.zip - ./Coreinfo64.exe -accepteula -f - ./apps/openssl.exe version -c - - name: test - working-directory: _build - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - nmake test VERBOSE_FAILURE=yes HARNESS_JOBS=4 - - minimal: - runs-on: windows-2022 - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: prepare the build directory - run: mkdir _build - - name: install jom - run: choco install jom - - name: config - working-directory: _build - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - perl ..\Configure --banner=Configured --strict-warnings enable-demos no-makedepend no-bulk no-deprecated no-fips no-asm no-threads -DOPENSSL_SMALL_FOOTPRINT -DOSSL_WINCTX=openssl - perl configdata.pm --dump - - name: build - working-directory: _build - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - jom /j4 /S - - name: download coreinfo - run: | - mkdir _build\coreinfo - Invoke-WebRequest -Uri "https://download.sysinternals.com/files/Coreinfo.zip" -outfile "_build\coreinfo\Coreinfo.zip" - - name: get cpu info - working-directory: _build - continue-on-error: true - run: | - 7z.exe x coreinfo/Coreinfo.zip - ./Coreinfo64.exe -accepteula -f - ./apps/openssl.exe version -c - - name: test - working-directory: _build - shell: cmd - run: | - 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 - - cygwin: - # Run a job for each of the specified target architectures: - strategy: - matrix: - os: - - windows-2022 - platform: - - arch: win64 - config: -DCMAKE_C_COMPILER=gcc --strict-warnings enable-demos no-fips -# are we really learning sth new from win32? So let's save some CO2 for now disabling this -# - arch: win32 -# config: -DCMAKE_C_COMPILER=gcc --strict-warnings no-fips - runs-on: ${{ matrix.os }} - env: - CYGWIN_NOWINPATH: 1 - SHELLOPTS: igncr -# Don't overwhelm github CI VMs: - MAKE_PARAMS: -j 4 - steps: -# Checkout before cygwin can mess with PATH... - - uses: actions/checkout@v6 - with: - persist-credentials: false - - uses: cygwin/cygwin-install-action@f2009323764960f80959895c7bc3bb30210afe4d #v6 - with: - packages: perl git make gcc-core - - name: Check repo - run: cygcheck -V - - name: Full cygcheck status - run: cygcheck -s -v -r -h -# Activate this if checkout action fails: -# - name: Clone repo -# run: bash -c "pwd && git clone --branch ${{ github.ref_name }} --depth 1 https://github.com/${{ github.repository }}.git" - - name: Full build - shell: bash - run: | - gcc --version - ./config ${{ matrix.platform.config }} - make $MAKE_PARAMS -# Disable testing for now. TBD: Need local cygwin installation to debug . -# - name: Run openssl tests -# run: bash -c "cd openssl && make V=1 test" - - mingw64: - runs-on: ubuntu-latest - env: - CC: x86_64-w64-mingw32-gcc - CXX: x86_64-w64-mingw32-g++ - AR: x86_64-w64-mingw32-ar - RANLIB: x86_64-w64-mingw32-ranlib - RC: x86_64-w64-mingw32-windres - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: install MINGW64 - run: sudo apt-get install -y mingw-w64 - - name: config -# Once fixed, enable strict-warnings -# run: ./config --strict-warnings --banner=Configured mingw64 - run: ./config --banner=Configured mingw64 - - name: make - run: make -j4 -s - - msys2-mingw64: - runs-on: windows-latest - env: - MSYSTEM: UCRT64 - CHERE_INVOKING: 'yes' - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: install MSYS2 - run: | - $url = 'https://github.com/msys2/msys2-installer/releases/download/nightly-x86_64/msys2-base-x86_64-latest.sfx.exe' - (New-Object System.Net.WebClient).DownloadFile($url, 'msys2.exe') - # Remove preinstalled MSYS2 - if (Test-Path C:\msys64) { Remove-Item -Recurse -Force C:\msys64 } - .\msys2.exe -y -oC:\ - Remove-Item msys2.exe - - - name: update MSYS2 - run: | - C:\msys64\usr\bin\bash.exe -lc ' ' - # Update core and then normal update - C:\msys64\usr\bin\bash.exe -lc 'pacman --noconfirm -Syuu' - C:\msys64\usr\bin\bash.exe -lc 'pacman --noconfirm -Syuu' - - - name: install dependencies - run: C:\msys64\usr\bin\bash.exe -lc 'pacman --noconfirm -S --needed perl git make mingw-w64-ucrt-x86_64-gcc' - - - name: config -# Once fixed, enable strict-warnings -# run: C:\msys64\usr\bin\bash.exe -lc './config --strict-warnings --banner=Configured mingw64' - run: C:\msys64\usr\bin\bash.exe -lc './config --banner=Configured mingw64' - - - name: make - run: C:\msys64\usr\bin\bash.exe -lc 'make -j4 -s' -# Tests are broken for now -# - name: test -# run: C:\msys64\usr\bin\bash.exe -lc 'make test' diff --git a/.github/workflows/windows_comp.yml b/.github/workflows/windows_comp.yml deleted file mode 100644 index 09663c3225c47..0000000000000 --- a/.github/workflows/windows_comp.yml +++ /dev/null @@ -1,151 +0,0 @@ -# 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 - -name: Windows Compression GitHub CI - -on: - pull_request: - paths: - - 'crypto/comp/*.c' - - '.github/workflows/windows_comp.yml' - push: - paths: - - '**.c' - -permissions: - contents: read - -jobs: - zstd: - runs-on: windows-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: install nasm - run: | - choco install nasm - "C:\Program Files\NASM" | Out-File -FilePath "$env:GITHUB_PATH" -Append - - name: install jom - run: choco install jom - - name: prepare the build directory - run: mkdir _build - - name: Get zstd - run: | - vcpkg install zstd:x64-windows - "C:\vcpkg\packages\zstd_x64-windows\bin" | Out-File -FilePath "$env:GITHUB_PATH" -Append - - name: config - working-directory: _build - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - perl ..\Configure --strict-warnings enable-comp enable-zstd --with-zstd-include=C:\vcpkg\packages\zstd_x64-windows\include --with-zstd-lib=C:\vcpkg\packages\zstd_x64-windows\lib\zstd.lib no-makedepend -DOSSL_WINCTX=openssl VC-WIN64A - perl configdata.pm --dump - - name: build - working-directory: _build - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - jom /j4 /S - - name: Gather openssl version info - working-directory: _build - run: | - apps/openssl.exe version -v - apps/openssl.exe version -v | %{($_ -split '\s+')[1]} - apps/openssl.exe version -v | %{($_ -split '\s+')[1] -replace '([0-9]+\.[0-9]+)(\..*)','$1'} - echo "OSSL_VERSION=$(apps/openssl.exe version -v | %{($_ -split '\s+')[1] -replace '([0-9]+\.[0-9]+)(\..*)','$1'})" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append - - name: Set registry keys - working-directory: _build - run: | - echo ${Env:OSSL_VERSION} - reg.exe add HKLM\SOFTWARE\OpenSSL-${Env:OSSL_VERSION}-openssl /v OPENSSLDIR /t REG_EXPAND_SZ /d TESTOPENSSLDIR /reg:32 - reg.exe add HKLM\SOFTWARE\OpenSSL-${Env:OSSL_VERSION}-openssl /v MODULESDIR /t REG_EXPAND_SZ /d TESTOPENSSLDIR /reg:32 - reg.exe query HKLM\SOFTWARE\OpenSSL-${Env:OSSL_VERSION}-openssl /v OPENSSLDIR /reg:32 - - name: download coreinfo - run: | - mkdir _build\coreinfo - Invoke-WebRequest -Uri "https://download.sysinternals.com/files/Coreinfo.zip" -outfile "_build\coreinfo\Coreinfo.zip" - - name: get cpu info - working-directory: _build - continue-on-error: true - run: | - 7z.exe x coreinfo/Coreinfo.zip - ./Coreinfo64.exe -accepteula -f - ./apps/openssl.exe version -c - - name: test - working-directory: _build - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - jom test VERBOSE_FAILURE=yes TESTS="-test_fuzz* -test_fipsload" HARNESS_JOBS=4 - - brotli: - runs-on: windows-latest - steps: - - uses: actions/checkout@v6 - with: - persist-credentials: false - - name: checkout fuzz/corpora submodule - run: git submodule update --init --depth 1 fuzz/corpora - - name: install nasm - run: | - choco install nasm - "C:\Program Files\NASM" | Out-File -FilePath "$env:GITHUB_PATH" -Append - - name: install jom - run: choco install jom - - name: prepare the build directory - run: mkdir _build - - name: Get brotli - run: | - vcpkg install brotli:x64-windows - "C:\vcpkg\packages\brotli_x64-windows\bin" | Out-File -FilePath "$env:GITHUB_PATH" -Append - - name: config - working-directory: _build - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - perl ..\Configure --strict-warnings enable-comp enable-brotli --with-brotli-include=C:\vcpkg\packages\brotli_x64-windows\include --with-brotli-lib=C:\vcpkg\packages\brotli_x64-windows\lib no-makedepend -DOSSL_WINCTX=openssl VC-WIN64A - perl configdata.pm --dump - - name: build - working-directory: _build - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - jom /j4 /S - - name: Gather openssl version info - working-directory: _build - run: | - apps/openssl.exe version -v - apps/openssl.exe version -v | %{($_ -split '\s+')[1]} - apps/openssl.exe version -v | %{($_ -split '\s+')[1] -replace '([0-9]+\.[0-9]+)(\..*)','$1'} - echo "OSSL_VERSION=$(apps/openssl.exe version -v | %{($_ -split '\s+')[1] -replace '([0-9]+\.[0-9]+)(\..*)','$1'})" | Out-File -FilePath $Env:GITHUB_ENV -Encoding utf8 -Append - - name: Set registry keys - working-directory: _build - run: | - echo ${Env:OSSL_VERSION} - reg.exe add HKLM\SOFTWARE\OpenSSL-${Env:OSSL_VERSION}-openssl /v OPENSSLDIR /t REG_EXPAND_SZ /d TESTOPENSSLDIR /reg:32 - reg.exe add HKLM\SOFTWARE\OpenSSL-${Env:OSSL_VERSION}-openssl /v MODULESDIR /t REG_EXPAND_SZ /d TESTOPENSSLDIR /reg:32 - reg.exe query HKLM\SOFTWARE\OpenSSL-${Env:OSSL_VERSION}-openssl /v OPENSSLDIR /reg:32 - - name: download coreinfo - run: | - mkdir _build\coreinfo - Invoke-WebRequest -Uri "https://download.sysinternals.com/files/Coreinfo.zip" -outfile "_build\coreinfo\Coreinfo.zip" - - name: get cpu info - working-directory: _build - continue-on-error: true - run: | - 7z.exe x coreinfo/Coreinfo.zip - ./Coreinfo64.exe -accepteula -f - ./apps/openssl.exe version -c - - name: test - working-directory: _build - shell: cmd - run: | - call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" - jom test VERBOSE_FAILURE=yes TESTS="-test_fuzz* -test_fipsload" HARNESS_JOBS=4 diff --git a/CHANGES.md b/CHANGES.md index 049c0e7288710..f7ee59641cf2c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -31,6 +31,10 @@ OpenSSL Releases ### Changes between 4.0 and 4.1 [xx XXX xxxx] + * Added AVX512 optimized SHAKE x4 operations for ML-DSA on x86_64. + + *Marcel Cornu and Tomasz Kantecki* + * Added test framework for testing function memory allocation failures. *Jakub Zelenka* diff --git a/crypto/ml_dsa/ml_dsa_hash.h b/crypto/ml_dsa/ml_dsa_hash.h index 7625d3367d9c3..4280ef67c8897 100644 --- a/crypto/ml_dsa/ml_dsa_hash.h +++ b/crypto/ml_dsa/ml_dsa_hash.h @@ -7,6 +7,9 @@ * https://www.openssl.org/source/license.html */ +#ifndef OSSL_CRYPTO_ML_DSA_HASH_H +#define OSSL_CRYPTO_ML_DSA_HASH_H + #include static ossl_inline ossl_unused int @@ -39,3 +42,5 @@ shake_xof_3(EVP_MD_CTX *ctx, const EVP_MD *md, const uint8_t *in1, size_t in1_le && EVP_DigestUpdate(ctx, in3, in3_len) && EVP_DigestSqueeze(ctx, out, out_len); } + +#endif /* OSSL_CRYPTO_ML_DSA_HASH_H */ diff --git a/crypto/ml_dsa/ml_dsa_key.c b/crypto/ml_dsa/ml_dsa_key.c index 24fa7596e2f77..74488365c31f2 100644 --- a/crypto/ml_dsa/ml_dsa_key.c +++ b/crypto/ml_dsa/ml_dsa_key.c @@ -332,7 +332,7 @@ int ossl_ml_dsa_key_has(const ML_DSA_KEY *key, int selection) * @returns 1 on success, or 0 on failure. */ static int public_from_private(const ML_DSA_KEY *key, EVP_MD_CTX *md_ctx, - VECTOR *t1, VECTOR *t0) + const OSSL_ML_DSA_SAMPLE_OPS *sample_ops, VECTOR *t1, VECTOR *t0) { int ret = 0; const ML_DSA_PARAMS *params = key->params; @@ -351,7 +351,7 @@ static int public_from_private(const ML_DSA_KEY *key, EVP_MD_CTX *md_ctx, matrix_init(&a_ntt, s1_ntt.poly + l, k, l); /* Using rho generate A' = A in NTT form */ - if (!matrix_expand_A(md_ctx, key->shake128_md, key->rho, &a_ntt)) + if (!sample_ops->matrix_expand_A(md_ctx, key->shake128_md, key->rho, &a_ntt)) goto err; /* t = NTT_inv(A' * NTT(s1)) + s2 */ @@ -376,6 +376,7 @@ static int public_from_private(const ML_DSA_KEY *key, EVP_MD_CTX *md_ctx, int ossl_ml_dsa_key_public_from_private(ML_DSA_KEY *key) { int ret = 0; + const OSSL_ML_DSA_SAMPLE_OPS *sample_ops = ossl_ml_dsa_sample_ops(); VECTOR t0; EVP_MD_CTX *md_ctx = NULL; @@ -383,7 +384,7 @@ int ossl_ml_dsa_key_public_from_private(ML_DSA_KEY *key) return 0; ret = ((md_ctx = EVP_MD_CTX_new()) != NULL) && ossl_ml_dsa_key_pub_alloc(key) /* allocate space for t1 */ - && public_from_private(key, md_ctx, &key->t1, &t0) + && public_from_private(key, md_ctx, sample_ops, &key->t1, &t0) && vector_equal(&t0, &key->t0) /* compare the generated t0 to the expected */ && ossl_ml_dsa_pk_encode(key) && shake_xof(md_ctx, key->shake256_md, @@ -397,6 +398,7 @@ int ossl_ml_dsa_key_public_from_private(ML_DSA_KEY *key) int ossl_ml_dsa_key_pairwise_check(const ML_DSA_KEY *key) { int ret = 0; + const OSSL_ML_DSA_SAMPLE_OPS *sample_ops = ossl_ml_dsa_sample_ops(); VECTOR t1, t0; POLY *polys = NULL; uint32_t k = (uint32_t)key->params->k; @@ -414,7 +416,7 @@ int ossl_ml_dsa_key_pairwise_check(const ML_DSA_KEY *key) vector_init(&t1, polys, k); vector_init(&t0, polys + k, k); - if (!public_from_private(key, md_ctx, &t1, &t0)) + if (!public_from_private(key, md_ctx, sample_ops, &t1, &t0)) goto err; ret = vector_equal(&t1, &key->t1) && vector_equal(&t0, &key->t0); @@ -435,6 +437,7 @@ int ossl_ml_dsa_key_pairwise_check(const ML_DSA_KEY *key) static int keygen_internal(ML_DSA_KEY *out) { int ret = 0; + const OSSL_ML_DSA_SAMPLE_OPS *sample_ops = ossl_ml_dsa_sample_ops(); uint8_t augmented_seed[ML_DSA_SEED_BYTES + 2]; uint8_t expanded_seed[ML_DSA_RHO_BYTES + ML_DSA_PRIV_SEED_BYTES + ML_DSA_K_BYTES]; const uint8_t *const rho = expanded_seed; /* p = Public Random Seed */ @@ -461,8 +464,9 @@ static int keygen_internal(ML_DSA_KEY *out) memcpy(out->rho, rho, sizeof(out->rho)); memcpy(out->K, K, sizeof(out->K)); - ret = vector_expand_S(md_ctx, out->shake256_md, params->eta, priv_seed, &out->s1, &out->s2) - && public_from_private(out, md_ctx, &out->t1, &out->t0) + ret = sample_ops->vector_expand_S(md_ctx, out->shake256_md, params->eta, + priv_seed, &out->s1, &out->s2) + && public_from_private(out, md_ctx, sample_ops, &out->t1, &out->t0) && ossl_ml_dsa_pk_encode(out) && shake_xof(md_ctx, out->shake256_md, out->pub_encoding, out->params->pk_len, out->tr, sizeof(out->tr)) diff --git a/crypto/ml_dsa/ml_dsa_local.h b/crypto/ml_dsa/ml_dsa_local.h index bbaa6dafc75a9..34a83f8ffbe0e 100644 --- a/crypto/ml_dsa/ml_dsa_local.h +++ b/crypto/ml_dsa/ml_dsa_local.h @@ -59,10 +59,23 @@ typedef struct vector_st VECTOR; typedef struct matrix_st MATRIX; typedef struct ml_dsa_sig_st ML_DSA_SIG; -int ossl_ml_dsa_matrix_expand_A(EVP_MD_CTX *g_ctx, const EVP_MD *md, +typedef int(ML_DSA_MATRIX_EXPAND_A_FN)(EVP_MD_CTX *g_ctx, const EVP_MD *md, const uint8_t *rho, MATRIX *out); -int ossl_ml_dsa_vector_expand_S(EVP_MD_CTX *h_ctx, const EVP_MD *md, int eta, - const uint8_t *seed, VECTOR *s1, VECTOR *s2); +typedef int(ML_DSA_VECTOR_EXPAND_S_FN)(EVP_MD_CTX *h_ctx, const EVP_MD *md, + int eta, const uint8_t *seed, VECTOR *s1, VECTOR *s2); +typedef void(ML_DSA_VECTOR_EXPAND_MASK_FN)(VECTOR *out, const uint8_t *rho_prime, + size_t rho_prime_len, uint32_t kappa, uint32_t gamma1, + EVP_MD_CTX *h_ctx, const EVP_MD *md); + +typedef struct ossl_ml_dsa_sample_ops_st { + ML_DSA_MATRIX_EXPAND_A_FN *matrix_expand_A; + ML_DSA_VECTOR_EXPAND_S_FN *vector_expand_S; + ML_DSA_VECTOR_EXPAND_MASK_FN *vector_expand_mask; +} OSSL_ML_DSA_SAMPLE_OPS; + +const OSSL_ML_DSA_SAMPLE_OPS *ossl_ml_dsa_sample_ops(void); +const OSSL_ML_DSA_SAMPLE_OPS *ossl_ml_dsa_sample_generic_ops(void); +const OSSL_ML_DSA_SAMPLE_OPS *ossl_ml_dsa_sample_x86_64_ops(void); void ossl_ml_dsa_matrix_mult_vector(const MATRIX *matrix_kl, const VECTOR *vl, VECTOR *vk); int ossl_ml_dsa_poly_expand_mask(POLY *out, const uint8_t *seed, size_t seed_len, diff --git a/crypto/ml_dsa/ml_dsa_matrix.h b/crypto/ml_dsa/ml_dsa_matrix.h index 0352ecac7afc0..cd9005fc87177 100644 --- a/crypto/ml_dsa/ml_dsa_matrix.h +++ b/crypto/ml_dsa/ml_dsa_matrix.h @@ -35,10 +35,3 @@ matrix_mult_vector(const MATRIX *a, const VECTOR *s, VECTOR *t) { ossl_ml_dsa_matrix_mult_vector(a, s, t); } - -static ossl_inline ossl_unused int -matrix_expand_A(EVP_MD_CTX *g_ctx, const EVP_MD *md, const uint8_t *rho, - MATRIX *out) -{ - return ossl_ml_dsa_matrix_expand_A(g_ctx, md, rho, out); -} diff --git a/crypto/ml_dsa/ml_dsa_sample.c b/crypto/ml_dsa/ml_dsa_sample.c index 5d9dc84a54fa3..3eef3c0176b1b 100644 --- a/crypto/ml_dsa/ml_dsa_sample.c +++ b/crypto/ml_dsa/ml_dsa_sample.c @@ -8,6 +8,7 @@ */ #include +#include #include "ml_dsa_local.h" #include "ml_dsa_vector.h" #include "ml_dsa_matrix.h" @@ -35,6 +36,10 @@ typedef int(COEFF_FROM_NIBBLE_FUNC)(uint32_t nibble, uint32_t *out); static COEFF_FROM_NIBBLE_FUNC coeff_from_nibble_4; static COEFF_FROM_NIBBLE_FUNC coeff_from_nibble_2; +static ML_DSA_MATRIX_EXPAND_A_FN matrix_expand_A_scalar; +static ML_DSA_VECTOR_EXPAND_S_FN vector_expand_S_scalar; +static ML_DSA_VECTOR_EXPAND_MASK_FN vector_expand_mask_scalar; + /** * @brief Combine 3 bytes to form an coefficient. * See FIPS 204, Algorithm 14, CoeffFromThreeBytes() @@ -198,7 +203,7 @@ static int rej_bounded_poly(EVP_MD_CTX *h_ctx, const EVP_MD *md, * in the range of 0..q-1. * @returns 1 if the matrix was generated, or 0 on error. */ -int ossl_ml_dsa_matrix_expand_A(EVP_MD_CTX *g_ctx, const EVP_MD *md, +static int matrix_expand_A_scalar(EVP_MD_CTX *g_ctx, const EVP_MD *md, const uint8_t *rho, MATRIX *out) { int ret = 0; @@ -208,7 +213,6 @@ int ossl_ml_dsa_matrix_expand_A(EVP_MD_CTX *g_ctx, const EVP_MD *md, /* 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++) { for (j = 0; j < out->l; j++) { derived_seed[ML_DSA_RHO_BYTES + 1] = (uint8_t)i; @@ -241,7 +245,7 @@ int ossl_ml_dsa_matrix_expand_A(EVP_MD_CTX *g_ctx, const EVP_MD *md, * the range (q-eta)..0..eta * @returns 1 if s1 and s2 were successfully generated, or 0 otherwise. */ -int ossl_ml_dsa_vector_expand_S(EVP_MD_CTX *h_ctx, const EVP_MD *md, int eta, +static int vector_expand_S_scalar(EVP_MD_CTX *h_ctx, const EVP_MD *md, int eta, const uint8_t *seed, VECTOR *s1, VECTOR *s2) { int ret = 0; @@ -376,3 +380,57 @@ int ossl_ml_dsa_poly_sample_in_ball(POLY *out_c, const uint8_t *seed, int seed_l } return 1; } + +static void vector_expand_mask_scalar(VECTOR *out, const uint8_t *rho_prime, + size_t rho_prime_len, uint32_t kappa, uint32_t gamma1, + EVP_MD_CTX *h_ctx, const EVP_MD *md) +{ + size_t i; + uint8_t derived_seed[ML_DSA_RHO_PRIME_BYTES + 2]; + + (void)rho_prime_len; + + memcpy(derived_seed, rho_prime, ML_DSA_RHO_PRIME_BYTES); + + for (i = 0; i < out->num_poly; i++) { + size_t index = kappa + i; + + derived_seed[ML_DSA_RHO_PRIME_BYTES] = index & 0xFF; + derived_seed[ML_DSA_RHO_PRIME_BYTES + 1] = (index >> 8) & 0xFF; + poly_expand_mask(out->poly + i, derived_seed, sizeof(derived_seed), + gamma1, h_ctx, md); + } +} + +static const OSSL_ML_DSA_SAMPLE_OPS ml_dsa_sample_generic_meth = { + matrix_expand_A_scalar, + vector_expand_S_scalar, + vector_expand_mask_scalar +}; + +const OSSL_ML_DSA_SAMPLE_OPS *ossl_ml_dsa_sample_ops(void) +{ +#if defined(KECCAK1600_ASM) \ + && (defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)) \ + && !defined(OPENSSL_NO_ASM) + return ossl_ml_dsa_sample_x86_64_ops(); +#else + return ossl_ml_dsa_sample_generic_ops(); +#endif +} + +const OSSL_ML_DSA_SAMPLE_OPS *ossl_ml_dsa_sample_generic_ops(void) +{ + return &ml_dsa_sample_generic_meth; +} + +#if defined(KECCAK1600_ASM) \ + && (defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)) \ + && !defined(OPENSSL_NO_ASM) +#include "ml_dsa_sample_hw_x86_64.inc" +#else +const OSSL_ML_DSA_SAMPLE_OPS *ossl_ml_dsa_sample_x86_64_ops(void) +{ + return ossl_ml_dsa_sample_generic_ops(); +} +#endif diff --git a/crypto/ml_dsa/ml_dsa_sample_hw_x86_64.inc b/crypto/ml_dsa/ml_dsa_sample_hw_x86_64.inc new file mode 100644 index 0000000000000..cc36c489a761f --- /dev/null +++ b/crypto/ml_dsa/ml_dsa_sample_hw_x86_64.inc @@ -0,0 +1,310 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2026 Intel Corporation. All Rights Reserved. + * + * Licensed under 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 + */ + +#define ML_DSA_SHAKE_X4_BATCH_SIZE 4 +#define ML_DSA_SHAKE_X4_DONE_MASK ((1 << ML_DSA_SHAKE_X4_BATCH_SIZE) - 1) +#define ML_DSA_EXPAND_MASK_BYTES_PER_COEFF 32 +#define ML_DSA_EXPAND_MASK_COEFFS_GAMMA1_19 20 +#define ML_DSA_EXPAND_MASK_COEFFS_GAMMA1_17 18 +#define ML_DSA_EXPAND_MASK_BUF_SIZE_GAMMA1_19 \ + (ML_DSA_EXPAND_MASK_BYTES_PER_COEFF * ML_DSA_EXPAND_MASK_COEFFS_GAMMA1_19) +#define ML_DSA_EXPAND_MASK_BUF_SIZE_GAMMA1_17 \ + (ML_DSA_EXPAND_MASK_BYTES_PER_COEFF * ML_DSA_EXPAND_MASK_COEFFS_GAMMA1_17) +#define ML_DSA_EXPAND_MASK_BUF_SIZE(gamma1) \ + ((gamma1) == ML_DSA_GAMMA1_TWO_POWER_19 \ + ? ML_DSA_EXPAND_MASK_BUF_SIZE_GAMMA1_19 \ + : ML_DSA_EXPAND_MASK_BUF_SIZE_GAMMA1_17) + +static ossl_unused int rej_ntt_poly_mb(EVP_MD_CTX *g_ctx, const EVP_MD *md, + const uint8_t *seeds[ML_DSA_SHAKE_X4_BATCH_SIZE], const size_t seed_len, + POLY *outs[ML_DSA_SHAKE_X4_BATCH_SIZE], const size_t count) +{ + KECCAK1600_X4_CTX ctx; + uint8_t blocks[ML_DSA_SHAKE_X4_BATCH_SIZE][SHAKE128_BLOCKSIZE]; + int coeff_idx[ML_DSA_SHAKE_X4_BATCH_SIZE] = { 0, 0, 0, 0 }; + size_t done_mask = 0; + size_t lane; + + (void)g_ctx; + (void)md; + + for (lane = count; lane < ML_DSA_SHAKE_X4_BATCH_SIZE; lane++) + done_mask |= ((size_t)1 << lane); + + ossl_sha3_shake128_x4_inc_init(&ctx); + ossl_sha3_shake128_x4_inc_absorb(&ctx, seeds[0], seeds[1], + seeds[2], seeds[3], seed_len); + ossl_sha3_shake128_x4_inc_finalize(&ctx); + + while (done_mask != ML_DSA_SHAKE_X4_DONE_MASK) { + ossl_sha3_shake128_x4_inc_squeeze(blocks[0], blocks[1], + blocks[2], blocks[3], SHAKE128_BLOCKSIZE, &ctx); + + for (lane = 0; lane < ML_DSA_SHAKE_X4_BATCH_SIZE; lane++) { + if (done_mask & ((size_t)1 << lane)) + continue; + + const uint8_t *b = blocks[lane]; + const uint8_t *end = b + SHAKE128_BLOCKSIZE; + + for (; b < end && coeff_idx[lane] < ML_DSA_NUM_POLY_COEFFICIENTS; b += 3) { + uint32_t *coeff_ptr = &(outs[lane]->coeff[coeff_idx[lane]]); + + if (coeff_from_three_bytes(b, coeff_ptr)) + coeff_idx[lane]++; + } + + if (coeff_idx[lane] >= ML_DSA_NUM_POLY_COEFFICIENTS) + done_mask |= ((size_t)1 << lane); + } + } + + return 1; +} + +static void vector_expand_mask_mb(VECTOR *out, const uint8_t *rho_prime, + const size_t rho_prime_len, const uint32_t kappa, const uint32_t gamma1, + EVP_MD_CTX *h_ctx, const EVP_MD *md) +{ + size_t i; + const size_t num_polys = out->num_poly; + uint8_t derived_seeds[ML_DSA_SHAKE_X4_BATCH_SIZE][ML_DSA_RHO_PRIME_BYTES + 2]; + const size_t seed_len = sizeof(derived_seeds[0]); + const size_t buf_size = ML_DSA_EXPAND_MASK_BUF_SIZE(gamma1); + uint8_t buffers[ML_DSA_SHAKE_X4_BATCH_SIZE][ML_DSA_EXPAND_MASK_BUF_SIZE_GAMMA1_19]; + + (void)rho_prime_len; + (void)h_ctx; + (void)md; + + for (i = 0; i < ML_DSA_SHAKE_X4_BATCH_SIZE; i++) + memcpy(derived_seeds[i], rho_prime, ML_DSA_RHO_PRIME_BYTES); + + for (i = 0; i + (ML_DSA_SHAKE_X4_BATCH_SIZE - 1) < num_polys; i += ML_DSA_SHAKE_X4_BATCH_SIZE) { + size_t b; + + for (b = 0; b < ML_DSA_SHAKE_X4_BATCH_SIZE; b++) { + const size_t index = kappa + i + b; + + derived_seeds[b][ML_DSA_RHO_PRIME_BYTES] = index & 0xFF; + derived_seeds[b][ML_DSA_RHO_PRIME_BYTES + 1] = (index >> 8) & 0xFF; + } + + ossl_sha3_shake256_x4(buffers[0], buffers[1], buffers[2], buffers[3], buf_size, + derived_seeds[0], derived_seeds[1], derived_seeds[2], derived_seeds[3], seed_len); + + ossl_ml_dsa_poly_decode_expand_mask(&out->poly[i + 0], buffers[0], buf_size, gamma1); + ossl_ml_dsa_poly_decode_expand_mask(&out->poly[i + 1], buffers[1], buf_size, gamma1); + ossl_ml_dsa_poly_decode_expand_mask(&out->poly[i + 2], buffers[2], buf_size, gamma1); + ossl_ml_dsa_poly_decode_expand_mask(&out->poly[i + 3], buffers[3], buf_size, gamma1); + } + + if (i < num_polys) { + const size_t left = num_polys - i; + size_t b; + + for (b = 0; b < left; b++) { + const size_t index = kappa + i + b; + + derived_seeds[b][ML_DSA_RHO_PRIME_BYTES] = (uint8_t)index; + derived_seeds[b][ML_DSA_RHO_PRIME_BYTES + 1] = (uint8_t)(index >> 8); + } + + ossl_sha3_shake256_x4(buffers[0], buffers[1], buffers[2], buffers[3], buf_size, + derived_seeds[0], derived_seeds[1], derived_seeds[2], derived_seeds[3], seed_len); + + ossl_ml_dsa_poly_decode_expand_mask(&out->poly[i + 0], buffers[0], buf_size, gamma1); + + if ((i + 1) < num_polys) + ossl_ml_dsa_poly_decode_expand_mask(&out->poly[i + 1], buffers[1], buf_size, gamma1); + + if ((i + 2) < num_polys) + ossl_ml_dsa_poly_decode_expand_mask(&out->poly[i + 2], buffers[2], buf_size, gamma1); + } +} + +static ossl_unused int rej_bounded_poly_mb(EVP_MD_CTX *h_ctx, const EVP_MD *md, + COEFF_FROM_NIBBLE_FUNC *coef_from_nibble, + const uint8_t *seeds[ML_DSA_SHAKE_X4_BATCH_SIZE], const size_t seed_len, + POLY *outs[ML_DSA_SHAKE_X4_BATCH_SIZE], const size_t count) +{ + KECCAK1600_X4_CTX ctx; + uint8_t blocks[ML_DSA_SHAKE_X4_BATCH_SIZE][SHAKE256_BLOCKSIZE]; + int coeff_idx[ML_DSA_SHAKE_X4_BATCH_SIZE] = { 0, 0, 0, 0 }; + size_t done_mask = 0; + size_t lane; + + (void)h_ctx; + (void)md; + + for (lane = count; lane < ML_DSA_SHAKE_X4_BATCH_SIZE; lane++) + done_mask |= ((size_t)1 << lane); + + ossl_sha3_shake256_x4_inc_init(&ctx); + ossl_sha3_shake256_x4_inc_absorb(&ctx, seeds[0], seeds[1], + seeds[2], seeds[3], seed_len); + ossl_sha3_shake256_x4_inc_finalize(&ctx); + + while (done_mask != ML_DSA_SHAKE_X4_DONE_MASK) { + ossl_sha3_shake256_x4_inc_squeeze(blocks[0], blocks[1], + blocks[2], blocks[3], SHAKE256_BLOCKSIZE, &ctx); + + for (lane = 0; lane < ML_DSA_SHAKE_X4_BATCH_SIZE; lane++) { + if (done_mask & ((size_t)1 << lane)) + continue; + + const uint8_t *b = blocks[lane]; + const uint8_t *end = b + SHAKE256_BLOCKSIZE; + + for (; b < end && coeff_idx[lane] < ML_DSA_NUM_POLY_COEFFICIENTS; b++) { + uint32_t z0 = *b & 0x0F; + uint32_t z1 = *b >> 4; + + if (coef_from_nibble(z0, &outs[lane]->coeff[coeff_idx[lane]])) + coeff_idx[lane]++; + + if (coeff_idx[lane] >= ML_DSA_NUM_POLY_COEFFICIENTS) { + done_mask |= ((size_t)1 << lane); + break; + } + + if (coef_from_nibble(z1, &outs[lane]->coeff[coeff_idx[lane]])) + coeff_idx[lane]++; + + if (coeff_idx[lane] >= ML_DSA_NUM_POLY_COEFFICIENTS) { + done_mask |= ((size_t)1 << lane); + break; + } + } + } + } + + return 1; +} + +static int matrix_expand_A_mb(EVP_MD_CTX *g_ctx, const EVP_MD *md, + const uint8_t *rho, MATRIX *out) +{ + size_t b, idx; + uint8_t derived_seeds[ML_DSA_SHAKE_X4_BATCH_SIZE][ML_DSA_RHO_BYTES + 2]; + const size_t seed_len = sizeof(derived_seeds[0]); + const uint8_t *seeds[ML_DSA_SHAKE_X4_BATCH_SIZE]; + POLY *polys[ML_DSA_SHAKE_X4_BATCH_SIZE]; + POLY *poly = out->m_poly; + + 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) { + 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; + + derived_seeds[b][ML_DSA_RHO_BYTES] = (uint8_t)col; + derived_seeds[b][ML_DSA_RHO_BYTES + 1] = (uint8_t)row; + polys[b] = &poly[idx + b]; + } + + if (!rej_ntt_poly_mb(g_ctx, md, seeds, seed_len, polys, 4)) + return 0; + } + + if (idx < (out->k * out->l)) { + const size_t left = (out->k * out->l) - idx; + + for (b = 0; b < left; b++) { + const size_t row = (idx + b) / out->l; + const size_t col = (idx + b) % out->l; + + derived_seeds[b][ML_DSA_RHO_BYTES] = (uint8_t)col; + derived_seeds[b][ML_DSA_RHO_BYTES + 1] = (uint8_t)row; + polys[b] = &poly[idx + b]; + } + + if (!rej_ntt_poly_mb(g_ctx, md, seeds, seed_len, polys, left)) + return 0; + } + + return 1; +} + +static int vector_expand_S_mb(EVP_MD_CTX *h_ctx, const EVP_MD *md, const int eta, + const uint8_t *seed, VECTOR *s1, VECTOR *s2) +{ + size_t b, idx; + const size_t l = s1->num_poly; + const size_t total = l + s2->num_poly; + uint8_t derived_seeds[ML_DSA_SHAKE_X4_BATCH_SIZE][ML_DSA_PRIV_SEED_BYTES + 2]; + const uint8_t *seeds[ML_DSA_SHAKE_X4_BATCH_SIZE]; + const size_t seed_len = sizeof(derived_seeds[0]); + POLY *polys[ML_DSA_SHAKE_X4_BATCH_SIZE]; + COEFF_FROM_NIBBLE_FUNC *coef_from_nibble_fn = (eta == ML_DSA_ETA_4) ? coeff_from_nibble_4 : coeff_from_nibble_2; + + for (b = 0; b < ML_DSA_SHAKE_X4_BATCH_SIZE; b++) { + memcpy(derived_seeds[b], seed, ML_DSA_PRIV_SEED_BYTES); + seeds[b] = derived_seeds[b]; + } + + for (idx = 0; (idx + ML_DSA_SHAKE_X4_BATCH_SIZE - 1) < total; idx += ML_DSA_SHAKE_X4_BATCH_SIZE) { + for (b = 0; b < ML_DSA_SHAKE_X4_BATCH_SIZE; b++) { + const size_t poly_idx = idx + b; + + derived_seeds[b][ML_DSA_PRIV_SEED_BYTES] = (uint8_t)(poly_idx); + derived_seeds[b][ML_DSA_PRIV_SEED_BYTES + 1] = (uint8_t)(poly_idx >> 8); + + if (poly_idx < l) + polys[b] = &s1->poly[poly_idx]; + else + polys[b] = &s2->poly[poly_idx - l]; + } + + if (!rej_bounded_poly_mb(h_ctx, md, coef_from_nibble_fn, + seeds, seed_len, polys, ML_DSA_SHAKE_X4_BATCH_SIZE)) + return 0; + } + + if (idx < total) { + const size_t batch_count = total - idx; + + for (b = 0; b < batch_count; b++) { + const size_t poly_idx = idx + b; + + derived_seeds[b][ML_DSA_PRIV_SEED_BYTES] = (uint8_t)(poly_idx); + derived_seeds[b][ML_DSA_PRIV_SEED_BYTES + 1] = (uint8_t)(poly_idx >> 8); + + if (poly_idx < l) + polys[b] = &s1->poly[poly_idx]; + else + polys[b] = &s2->poly[poly_idx - l]; + } + + if (!rej_bounded_poly_mb(h_ctx, md, coef_from_nibble_fn, + seeds, seed_len, polys, batch_count)) + return 0; + } + + return 1; +} + +static const OSSL_ML_DSA_SAMPLE_OPS ml_dsa_sample_x86_64 = { + matrix_expand_A_mb, + vector_expand_S_mb, + vector_expand_mask_mb +}; + +const OSSL_ML_DSA_SAMPLE_OPS *ossl_ml_dsa_sample_x86_64_ops(void) +{ + if (SHA3_avx512vl_capable()) + return &ml_dsa_sample_x86_64; + return ossl_ml_dsa_sample_generic_ops(); +} diff --git a/crypto/ml_dsa/ml_dsa_sign.c b/crypto/ml_dsa/ml_dsa_sign.c index 51c2709ddbaf9..b42323266aad4 100644 --- a/crypto/ml_dsa/ml_dsa_sign.c +++ b/crypto/ml_dsa/ml_dsa_sign.c @@ -164,6 +164,7 @@ static int ml_dsa_sign_internal(const ML_DSA_KEY *priv, uint8_t *out_sig) { int ret = 0; + const OSSL_ML_DSA_SAMPLE_OPS *sample_ops = ossl_ml_dsa_sample_ops(); const ML_DSA_PARAMS *params = priv->params; EVP_MD_CTX *md_ctx = NULL; uint32_t k = (uint32_t)params->k, l = (uint32_t)params->l; @@ -232,7 +233,7 @@ static int ml_dsa_sign_internal(const ML_DSA_KEY *priv, CONSTTIME_SECRET_VECTOR(priv->s2); CONSTTIME_SECRET_VECTOR(priv->t0); - if (!matrix_expand_A(md_ctx, priv->shake128_md, priv->rho, &a_ntt)) + if (!sample_ops->matrix_expand_A(md_ctx, priv->shake128_md, priv->rho, &a_ntt)) goto err; /* @@ -263,8 +264,8 @@ static int ml_dsa_sign_internal(const ML_DSA_KEY *priv, VECTOR *ct0 = &w1; uint32_t z_max, r0_max, ct0_max, h_ones; - vector_expand_mask(&y, rho_prime, sizeof(rho_prime), (uint32_t)kappa, - gamma1, md_ctx, priv->shake256_md); + sample_ops->vector_expand_mask(&y, rho_prime, sizeof(rho_prime), + (uint32_t)kappa, gamma1, md_ctx, priv->shake256_md); vector_copy(y_ntt, &y); vector_ntt(y_ntt); @@ -380,6 +381,7 @@ static int ml_dsa_verify_internal(const ML_DSA_KEY *pub, const uint8_t *sig_enc, size_t sig_enc_len) { int ret = 0; + const OSSL_ML_DSA_SAMPLE_OPS *sample_ops = ossl_ml_dsa_sample_ops(); uint8_t *alloc = NULL, *w1_encoded; POLY *p, *c_ntt; MATRIX a_ntt; @@ -428,7 +430,7 @@ static int ml_dsa_verify_internal(const ML_DSA_KEY *pub, vector_init(&ct1_ntt, p + k, k); if (!ossl_ml_dsa_sig_decode(&sig, sig_enc, sig_enc_len, pub->params) - || !matrix_expand_A(md_ctx, pub->shake128_md, pub->rho, &a_ntt)) + || !sample_ops->matrix_expand_A(md_ctx, pub->shake128_md, pub->rho, &a_ntt)) goto err; /* Compute verifiers challenge c_ntt = NTT(SampleInBall(c_tilde)) */ diff --git a/crypto/ml_dsa/ml_dsa_vector.h b/crypto/ml_dsa/ml_dsa_vector.h index 0693eb6e3c30c..389c0ed045338 100644 --- a/crypto/ml_dsa/ml_dsa_vector.h +++ b/crypto/ml_dsa/ml_dsa_vector.h @@ -149,33 +149,6 @@ vector_mult_scalar(const VECTOR *lhs, const POLY *rhs, VECTOR *out) ossl_ml_dsa_poly_ntt_mult(lhs->poly + i, rhs, out->poly + i); } -static ossl_inline ossl_unused int -vector_expand_S(EVP_MD_CTX *h_ctx, const EVP_MD *md, int eta, - const uint8_t *seed, VECTOR *s1, VECTOR *s2) -{ - return ossl_ml_dsa_vector_expand_S(h_ctx, md, eta, seed, s1, s2); -} - -static ossl_inline ossl_unused void -vector_expand_mask(VECTOR *out, const uint8_t *rho_prime, size_t rho_prime_len, - uint32_t kappa, uint32_t gamma1, - EVP_MD_CTX *h_ctx, const EVP_MD *md) -{ - size_t i; - uint8_t derived_seed[ML_DSA_RHO_PRIME_BYTES + 2]; - - memcpy(derived_seed, rho_prime, ML_DSA_RHO_PRIME_BYTES); - - for (i = 0; i < out->num_poly; i++) { - size_t index = kappa + i; - - derived_seed[ML_DSA_RHO_PRIME_BYTES] = index & 0xFF; - derived_seed[ML_DSA_RHO_PRIME_BYTES + 1] = (index >> 8) & 0xFF; - poly_expand_mask(out->poly + i, derived_seed, sizeof(derived_seed), - gamma1, h_ctx, md); - } -} - /* Scale back previously rounded value */ static ossl_inline ossl_unused void vector_scale_power2_round_ntt(const VECTOR *in, VECTOR *out) diff --git a/crypto/sha/asm/keccak1600x4-avx512vl.pl b/crypto/sha/asm/keccak1600x4-avx512vl.pl new file mode 100755 index 0000000000000..cf52b190407e8 --- /dev/null +++ b/crypto/sha/asm/keccak1600x4-avx512vl.pl @@ -0,0 +1,2343 @@ +#!/usr/bin/env perl +# +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# Copyright (c) 2026 Intel Corporation. All Rights Reserved. +# +# Licensed under 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 + +############################################################################### +# Keccak x4 AVX512VL SHA3/SHAKE Assembly Routines +# +# Description: +# This file emits x86_64 assembly for AVX512VL accelerated Keccak-f[1600] +# processing of 4 independent states in parallel ("x4"). +# +# It provides the core 24-round Keccak permutation and x4 helper routines +# used by SHA3 and SHAKE absorb/finalize/squeeze paths. Data from four +# input/output lanes is packed across YMM registers so lane-local operations +# execute in SIMD. +# +############################################################################### + +# $output is the last argument if it looks like a file (it has an extension) +# $flavour is the first argument if it doesn't look like a file +$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$/); + +$avx512vl = 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"; + +# Check for AVX512VL support in assembler +if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` =~ /GNU assembler version (\d+)\.(\d+)/) { + my ($gas_major, $gas_minor) = ($1, $2); + $avx512vl = ($gas_major > 2 || ($gas_major == 2 && $gas_minor >= 26)); +} + +if (!$avx512vl + && $win64 + && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) + && `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)(?:\.([0-9]+))?/) +{ + $avx512vl = ($1 >= 2.12); +} + +if (!$avx512vl && `$ENV{CC} -v 2>&1` =~ /((?:clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) { + $avx512vl = ($2>=3.9); +} + +open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"" + or die "can't call $xlate: $!"; +*STDOUT=*OUT; + +$arg1="%rdi"; +$arg2="%rsi"; +$arg3="%rdx"; +$arg4="%rcx"; +$arg5="%r8"; +$arg6="%r9"; +$roundn="%r13d"; +$tblptr="%r14"; + +# Define SHAKE rates +$SHAKE128_RATE="\$168"; +$SHAKE256_RATE="\$136"; + +# Stack frame offsets for SHAKE x4 wrapper functions +$STATE_SIZE="808"; # (25 * 8 * 4) + 8 = 808 bytes +$sf_arg1="0"; +$sf_arg2="8"; +$sf_arg3="16"; +$sf_arg4="24"; +$sf_arg5="32"; +$sf_state_ptr="40"; +$sf_state_x4="48"; +$sf_size="856"; # 48 + 808 = 856 bytes + +# Emit an internal helper call used by one-shot wrappers. +# - Win64: call the provided *_internal shim and bracket it with 32-byte +# shadow space so shim entry can use xlate-compatible [rsp+8]/[rsp+16]. +# - non-Win64: call the public API symbol (same base name without _internal). +# The argument must be the shim/internal symbol name, e.g. +# SHA3_shake128_x4_inc_squeeze_avx512vl_internal +sub call_internal { + my ($shim_name) = @_; + my $external_name = $shim_name; + + $external_name =~ s/_internal$//; + + return <<___ if ($win64); + sub \$32, %rsp + call $shim_name + add \$32, %rsp +___ + + return <<___; + call $external_name +___ +} + +if ($avx512vl>0) {{{ + +# AVX512VL feature bit (bit 31 in OPENSSL_ia32cap_P+8) +my $avx512vl_mask = (1<<31); + +$code .= <<___; +.text + +.extern OPENSSL_ia32cap_P + +.globl SHA3_avx512vl_capable +.type SHA3_avx512vl_capable,\@abi-omnipotent +.align 32 +SHA3_avx512vl_capable: + mov OPENSSL_ia32cap_P+8(%rip), %rcx + xor %eax, %eax + and \$$avx512vl_mask, %ecx + cmovnz %ecx, %eax + ret +.size SHA3_avx512vl_capable, .-SHA3_avx512vl_capable +___ + +$code.=<<___; +.text + +# Perform Keccak permutation +# +# YMM registers 0 to 24 are used as Keccak state registers. +# This function, as is, can work on 1 to 4 independent states at the same time. +# +# There is no clear boundary between Theta, Rho, Pi, Chi and Iota steps. +# Instructions corresponding to these steps overlap for better efficiency. +# +# Arguments: +# ymm0-ymm24 [in/out] Keccak state registers (one SIMD per one state register) +# ymm25-ymm31 [clobbered] temporary SIMD registers +# $roundn [clobbered] used for round tracking +# $tblptr [clobbered] used for access to SHA3 constant table +.type keccak_1600_permute,\@abi-omnipotent +.align 32 +keccak_1600_permute: +.cfi_startproc + mov \$24, $roundn # 24 rounds + lea iotas(%rip), $tblptr # Load the address of the SHA3 round constants + +.align 32 +.Lkeccak_rnd_loop: + # Theta step + + # Compute column parities + # C[5] = [0, 0, 0, 0, 0] + # for x in 0 to 4: + # C[x] = state[x][0] XOR state[x][1] XOR state[x][2] XOR state[x][3] XOR state[x][4] + + vmovdqa64 %ymm0, %ymm25 + vpternlogq \$0x96, %ymm5, %ymm10, %ymm25 + vmovdqa64 %ymm1, %ymm26 + vpternlogq \$0x96, %ymm11, %ymm6, %ymm26 + vmovdqa64 %ymm2, %ymm27 + vpternlogq \$0x96, %ymm12, %ymm7, %ymm27 + + vmovdqa64 %ymm3, %ymm28 + vpternlogq \$0x96, %ymm13, %ymm8, %ymm28 + vmovdqa64 %ymm4, %ymm29 + vpternlogq \$0x96, %ymm14, %ymm9, %ymm29 + vpternlogq \$0x96, %ymm20, %ymm15, %ymm25 + + vpternlogq \$0x96, %ymm21, %ymm16, %ymm26 + vpternlogq \$0x96, %ymm22, %ymm17, %ymm27 + vpternlogq \$0x96, %ymm23, %ymm18, %ymm28 + + # Start computing D values and keep computing column parity + # D[5] = [0, 0, 0, 0, 0] + # for x in 0 to 4: + # D[x] = C[(x+4) mod 5] XOR ROTATE_LEFT(C[(x+1) mod 5], 1) + + vprolq \$1, %ymm26, %ymm30 + vprolq \$1, %ymm27, %ymm31 + vpternlogq \$0x96, %ymm24, %ymm19, %ymm29 + + # Continue computing D values and apply Theta + # for x in 0 to 4: + # for y in 0 to 4: + # state[x][y] = state[x][y] XOR D[x] + + vpternlogq \$0x96, %ymm30, %ymm29, %ymm0 + vpternlogq \$0x96, %ymm30, %ymm29, %ymm10 + vpternlogq \$0x96, %ymm30, %ymm29, %ymm20 + + vpternlogq \$0x96, %ymm30, %ymm29, %ymm5 + vpternlogq \$0x96, %ymm30, %ymm29, %ymm15 + vprolq \$1, %ymm28, %ymm30 + + vpternlogq \$0x96, %ymm31, %ymm25, %ymm6 + vpternlogq \$0x96, %ymm31, %ymm25, %ymm16 + vpternlogq \$0x96, %ymm31, %ymm25, %ymm1 + + vpternlogq \$0x96, %ymm31, %ymm25, %ymm11 + vpternlogq \$0x96, %ymm31, %ymm25, %ymm21 + vprolq \$1, %ymm29, %ymm31 + + vpbroadcastq ($tblptr), %ymm29 # Load the round constant into ymm29 (Iota) + add \$8, $tblptr # Increment the pointer to the next round constant + + vpternlogq \$0x96, %ymm30, %ymm26, %ymm12 + vpternlogq \$0x96, %ymm30, %ymm26, %ymm7 + vpternlogq \$0x96, %ymm30, %ymm26, %ymm22 + + vpternlogq \$0x96, %ymm30, %ymm26, %ymm17 + vpternlogq \$0x96, %ymm30, %ymm26, %ymm2 + vprolq \$1, %ymm25, %ymm30 + + # Rho step + # Keep applying Theta and start Rho step + # + # ROTATION_OFFSETS[5][5] = [ + # [0, 1, 62, 28, 27], + # [36, 44, 6, 55, 20], + # [3, 10, 43, 25, 39], + # [41, 45, 15, 21, 8], + # [18, 2, 61, 56, 14] ] + # + # for x in 0 to 4: + # for y in 0 to 4: + # state[x][y] = ROTATE_LEFT(state[x][y], ROTATION_OFFSETS[x][y]) + + vpternlogq \$0x96, %ymm31, %ymm27, %ymm3 + vpternlogq \$0x96, %ymm31, %ymm27, %ymm13 + vpternlogq \$0x96, %ymm31, %ymm27, %ymm23 + + vprolq \$44, %ymm6, %ymm6 + vpternlogq \$0x96, %ymm31, %ymm27, %ymm18 + vpternlogq \$0x96, %ymm31, %ymm27, %ymm8 + + vprolq \$43, %ymm12, %ymm12 + vprolq \$21, %ymm18, %ymm18 + vpternlogq \$0x96, %ymm30, %ymm28, %ymm24 + + vprolq \$14, %ymm24, %ymm24 + vprolq \$28, %ymm3, %ymm3 + vpternlogq \$0x96, %ymm30, %ymm28, %ymm9 + + vprolq \$20, %ymm9, %ymm9 + vprolq \$3, %ymm10, %ymm10 + vpternlogq \$0x96, %ymm30, %ymm28, %ymm19 + + vprolq \$45, %ymm16, %ymm16 + vprolq \$61, %ymm22, %ymm22 + vpternlogq \$0x96, %ymm30, %ymm28, %ymm4 + + vprolq \$1, %ymm1, %ymm1 + vprolq \$6, %ymm7, %ymm7 + vpternlogq \$0x96, %ymm30, %ymm28, %ymm14 + + # Continue with Rho and start Pi and Chi steps at the same time + # Ternary logic 0xD2 is used for Chi step + # + # for x in 0 to 4: + # for y in 0 to 4: + # state[x][y] = state[x][y] XOR ((NOT state[(x+1) mod 5][y]) AND state[(x+2) mod 5][y]) + + vprolq \$25, %ymm13, %ymm13 + vprolq \$8, %ymm19, %ymm19 + vmovdqa64 %ymm0, %ymm30 + vpternlogq \$0xD2, %ymm12, %ymm6, %ymm30 + + vprolq \$18, %ymm20, %ymm20 + vprolq \$27, %ymm4, %ymm4 + vpxorq %ymm29, %ymm30, %ymm30 # Iota step + + vprolq \$36, %ymm5, %ymm5 + vprolq \$10, %ymm11, %ymm11 + vmovdqa64 %ymm6, %ymm31 + vpternlogq \$0xD2, %ymm18, %ymm12, %ymm31 + + vprolq \$15, %ymm17, %ymm17 + vprolq \$56, %ymm23, %ymm23 + vpternlogq \$0xD2, %ymm24, %ymm18, %ymm12 + + vprolq \$62, %ymm2, %ymm2 + vprolq \$55, %ymm8, %ymm8 + vpternlogq \$0xD2, %ymm0, %ymm24, %ymm18 + + vprolq \$39, %ymm14, %ymm14 + vprolq \$41, %ymm15, %ymm15 + vpternlogq \$0xD2, %ymm6, %ymm0, %ymm24 + vmovdqa64 %ymm30, %ymm0 + vmovdqa64 %ymm31, %ymm6 + + vprolq \$2, %ymm21, %ymm21 + vmovdqa64 %ymm3, %ymm30 + vpternlogq \$0xD2, %ymm10, %ymm9, %ymm30 + vmovdqa64 %ymm9, %ymm31 + vpternlogq \$0xD2, %ymm16, %ymm10, %ymm31 + + vpternlogq \$0xD2, %ymm22, %ymm16, %ymm10 + vpternlogq \$0xD2, %ymm3, %ymm22, %ymm16 + vpternlogq \$0xD2, %ymm9, %ymm3, %ymm22 + vmovdqa64 %ymm30, %ymm3 + vmovdqa64 %ymm31, %ymm9 + + vmovdqa64 %ymm1, %ymm30 + vpternlogq \$0xD2, %ymm13, %ymm7, %ymm30 + vmovdqa64 %ymm7, %ymm31 + vpternlogq \$0xD2, %ymm19, %ymm13, %ymm31 + vpternlogq \$0xD2, %ymm20, %ymm19, %ymm13 + + vpternlogq \$0xD2, %ymm1, %ymm20, %ymm19 + vpternlogq \$0xD2, %ymm7, %ymm1, %ymm20 + vmovdqa64 %ymm30, %ymm1 + vmovdqa64 %ymm31, %ymm7 + vmovdqa64 %ymm4, %ymm30 + vpternlogq \$0xD2, %ymm11, %ymm5, %ymm30 + + vmovdqa64 %ymm5, %ymm31 + vpternlogq \$0xD2, %ymm17, %ymm11, %ymm31 + vpternlogq \$0xD2, %ymm23, %ymm17, %ymm11 + vpternlogq \$0xD2, %ymm4, %ymm23, %ymm17 + + vpternlogq \$0xD2, %ymm5, %ymm4, %ymm23 + vmovdqa64 %ymm30, %ymm4 + vmovdqa64 %ymm31, %ymm5 + vmovdqa64 %ymm2, %ymm30 + vpternlogq \$0xD2, %ymm14, %ymm8, %ymm30 + vmovdqa64 %ymm8, %ymm31 + vpternlogq \$0xD2, %ymm15, %ymm14, %ymm31 + + vpternlogq \$0xD2, %ymm21, %ymm15, %ymm14 + vpternlogq \$0xD2, %ymm2, %ymm21, %ymm15 + vpternlogq \$0xD2, %ymm8, %ymm2, %ymm21 + vmovdqa64 %ymm30, %ymm2 + vmovdqa64 %ymm31, %ymm8 + + # Complete the steps and get updated state registers in ymm0 to ymm24 + vmovdqa64 %ymm3, %ymm30 + vmovdqa64 %ymm18, %ymm3 + vmovdqa64 %ymm17, %ymm18 + vmovdqa64 %ymm11, %ymm17 + vmovdqa64 %ymm7, %ymm11 + vmovdqa64 %ymm10, %ymm7 + vmovdqa64 %ymm1, %ymm10 + vmovdqa64 %ymm6, %ymm1 + vmovdqa64 %ymm9, %ymm6 + vmovdqa64 %ymm22, %ymm9 + vmovdqa64 %ymm14, %ymm22 + vmovdqa64 %ymm20, %ymm14 + vmovdqa64 %ymm2, %ymm20 + vmovdqa64 %ymm12, %ymm2 + vmovdqa64 %ymm13, %ymm12 + vmovdqa64 %ymm19, %ymm13 + vmovdqa64 %ymm23, %ymm19 + vmovdqa64 %ymm15, %ymm23 + vmovdqa64 %ymm4, %ymm15 + vmovdqa64 %ymm24, %ymm4 + vmovdqa64 %ymm21, %ymm24 + vmovdqa64 %ymm8, %ymm21 + vmovdqa64 %ymm16, %ymm8 + vmovdqa64 %ymm5, %ymm16 + vmovdqa64 %ymm30, %ymm5 + + dec $roundn # Decrement the round counter + jnz .Lkeccak_rnd_loop # Jump to the start of the loop if r13d is not zero + ret +.cfi_endproc +.size keccak_1600_permute,.-keccak_1600_permute + +# Initialize YMM registers 0-24 to zero +.globl keccak_1600_init_state +.type keccak_1600_init_state,\@abi-omnipotent +.align 32 +keccak_1600_init_state: +.cfi_startproc + vpxorq %ymm0, %ymm0, %ymm0 + vmovdqa64 %ymm0, %ymm1 + vmovdqa64 %ymm0, %ymm2 + vmovdqa64 %ymm0, %ymm3 + vmovdqa64 %ymm0, %ymm4 + vmovdqa64 %ymm0, %ymm5 + vmovdqa64 %ymm0, %ymm6 + vmovdqa64 %ymm0, %ymm7 + vmovdqa64 %ymm0, %ymm8 + vmovdqa64 %ymm0, %ymm9 + vmovdqa64 %ymm0, %ymm10 + vmovdqa64 %ymm0, %ymm11 + vmovdqa64 %ymm0, %ymm12 + vmovdqa64 %ymm0, %ymm13 + vmovdqa64 %ymm0, %ymm14 + vmovdqa64 %ymm0, %ymm15 + vmovdqa64 %ymm0, %ymm16 + vmovdqa64 %ymm0, %ymm17 + vmovdqa64 %ymm0, %ymm18 + vmovdqa64 %ymm0, %ymm19 + vmovdqa64 %ymm0, %ymm20 + vmovdqa64 %ymm0, %ymm21 + vmovdqa64 %ymm0, %ymm22 + vmovdqa64 %ymm0, %ymm23 + vmovdqa64 %ymm0, %ymm24 + ret +.cfi_endproc +.size keccak_1600_init_state,.-keccak_1600_init_state + +.globl keccak_1600_load_state_x4 +.type keccak_1600_load_state_x4,\@abi-omnipotent +.align 32 +keccak_1600_load_state_x4: +.cfi_startproc + vmovdqu64 32*0($arg1), %ymm0 + vmovdqu64 32*1($arg1), %ymm1 + vmovdqu64 32*2($arg1), %ymm2 + vmovdqu64 32*3($arg1), %ymm3 + vmovdqu64 32*4($arg1), %ymm4 + vmovdqu64 32*5($arg1), %ymm5 + vmovdqu64 32*6($arg1), %ymm6 + vmovdqu64 32*7($arg1), %ymm7 + vmovdqu64 32*8($arg1), %ymm8 + vmovdqu64 32*9($arg1), %ymm9 + vmovdqu64 32*10($arg1), %ymm10 + vmovdqu64 32*11($arg1), %ymm11 + vmovdqu64 32*12($arg1), %ymm12 + vmovdqu64 32*13($arg1), %ymm13 + vmovdqu64 32*14($arg1), %ymm14 + vmovdqu64 32*15($arg1), %ymm15 + vmovdqu64 32*16($arg1), %ymm16 + vmovdqu64 32*17($arg1), %ymm17 + vmovdqu64 32*18($arg1), %ymm18 + vmovdqu64 32*19($arg1), %ymm19 + vmovdqu64 32*20($arg1), %ymm20 + vmovdqu64 32*21($arg1), %ymm21 + vmovdqu64 32*22($arg1), %ymm22 + vmovdqu64 32*23($arg1), %ymm23 + vmovdqu64 32*24($arg1), %ymm24 + ret +.cfi_endproc +.size keccak_1600_load_state_x4,.-keccak_1600_load_state_x4 + + +.globl keccak_1600_save_state_x4 +.type keccak_1600_save_state_x4,\@abi-omnipotent +.align 32 +keccak_1600_save_state_x4: +.cfi_startproc + vmovdqu64 %ymm0, 32*0($arg1) + vmovdqu64 %ymm1, 32*1($arg1) + vmovdqu64 %ymm2, 32*2($arg1) + vmovdqu64 %ymm3, 32*3($arg1) + vmovdqu64 %ymm4, 32*4($arg1) + vmovdqu64 %ymm5, 32*5($arg1) + vmovdqu64 %ymm6, 32*6($arg1) + vmovdqu64 %ymm7, 32*7($arg1) + vmovdqu64 %ymm8, 32*8($arg1) + vmovdqu64 %ymm9, 32*9($arg1) + vmovdqu64 %ymm10, 32*10($arg1) + vmovdqu64 %ymm11, 32*11($arg1) + vmovdqu64 %ymm12, 32*12($arg1) + vmovdqu64 %ymm13, 32*13($arg1) + vmovdqu64 %ymm14, 32*14($arg1) + vmovdqu64 %ymm15, 32*15($arg1) + vmovdqu64 %ymm16, 32*16($arg1) + vmovdqu64 %ymm17, 32*17($arg1) + vmovdqu64 %ymm18, 32*18($arg1) + vmovdqu64 %ymm19, 32*19($arg1) + vmovdqu64 %ymm20, 32*20($arg1) + vmovdqu64 %ymm21, 32*21($arg1) + vmovdqu64 %ymm22, 32*22($arg1) + vmovdqu64 %ymm23, 32*23($arg1) + vmovdqu64 %ymm24, 32*24($arg1) + ret +.cfi_endproc +.size keccak_1600_save_state_x4,.-keccak_1600_save_state_x4 + + +# Add input data to state when message length is less than rate +# Arguments: +# r10: state pointer to absorb into (clobbered) +# arg2 (rsi): message pointer lane 0 (updated on output) +# arg3 (rdx): message pointer lane 1 (updated on output) +# arg4 (rcx): message pointer lane 2 (updated on output) +# arg5 (r8): message pointer lane 3 (updated on output) +# r12: length in bytes (clobbered on output) +# Clobbers: r9, rbx, r15, k1, ymm31-ymm29 +.globl keccak_1600_partial_add_x4 +.type keccak_1600_partial_add_x4,\@abi-omnipotent +.align 32 +keccak_1600_partial_add_x4: +.cfi_startproc + mov 8*100(%r10), %r9 + test \$7, %r9d + jz .Lstart_aligned_to_4x8 + + # Start offset is not aligned to register size + mov %r9, %r15 # %r15 = s[100] + + and \$7, %r9d + neg %r9d + add \$8, %r9d # register capacity = 8 - (offset % 8) + cmp %r9d, %r12d + cmovnae %r12d, %r9d # %r9d = min(register capacity, length) + + lea byte_kmask_0_to_7(%rip), %rbx + kmovb (%rbx,%r9), %k1 # message load mask + + mov %r15, %rbx + and \$~7, %ebx + lea (%r10,%rbx,4), %r10 # get to state starting register + + mov %r15, %rbx + and \$7, %ebx + + vmovdqu8 (%r10), %ymm31 # load & store / allocate SB for the register + vmovdqu8 %ymm31, (%r10) + + vmovdqu8 ($arg2), %xmm31{%k1}{z} # Read 1 to 7 bytes from lane 0 + vmovdqu8 8*0(%r10,%rbx), %xmm30{%k1}{z} # Read 1 to 7 bytes from state reg lane 0 + vpxorq %xmm30, %xmm31, %xmm31 + vmovdqu8 %xmm31, 8*0(%r10,%rbx){%k1} # Write 1 to 7 bytes to state reg lane 0 + + vmovdqu8 ($arg3), %xmm31{%k1}{z} # Read 1 to 7 bytes from lane 1 + vmovdqu8 8*1(%r10,%rbx), %xmm30{%k1}{z} # Read 1 to 7 bytes from state reg lane 1 + vpxorq %xmm30, %xmm31, %xmm31 + vmovdqu8 %xmm31, 8*1(%r10,%rbx){%k1} # Write 1 to 7 bytes to state reg lane 1 + + vmovdqu8 ($arg4), %xmm31{%k1}{z} # Read 1 to 7 bytes from lane 2 + vmovdqu8 8*2(%r10,%rbx), %xmm30{%k1}{z} # Read 1 to 7 bytes from state reg lane 2 + vpxorq %xmm30, %xmm31, %xmm31 + vmovdqu8 %xmm31, 8*2(%r10,%rbx){%k1} # Write 1 to 7 bytes to state reg lane 2 + + vmovdqu8 ($arg5), %xmm31{%k1}{z} # Read 1 to 7 bytes from lane 3 + vmovdqu8 8*3(%r10,%rbx), %xmm30{%k1}{z} # Read 1 to 7 bytes from state reg lane 3 + vpxorq %xmm30, %xmm31, %xmm31 + vmovdqu8 %xmm31, 8*3(%r10,%rbx){%k1} # Write 1 to 7 bytes to state reg lane 3 + + sub %r9, %r12 + jz .Lzero_bytes + + add %r9, $arg2 + add %r9, $arg3 + add %r9, $arg4 + add %r9, $arg5 + add \$32, %r10 + xor %r9, %r9 + jmp .Lymm_loop + +.Lstart_aligned_to_4x8: + lea (%r10,%r9,4), %r10 + xor %r9, %r9 + +.align 32 +.Lymm_loop: + cmp \$8, %r12d + jb .Llt_8_bytes + + vmovq ($arg2,%r9), %xmm31 # Read 8 bytes from lane 0 + vpinsrq \$1, ($arg3,%r9), %xmm31, %xmm31 # Read 8 bytes from lane 1 + vmovq ($arg4,%r9), %xmm30 # Read 8 bytes from lane 2 + vpinsrq \$1, ($arg5,%r9),%xmm30, %xmm30 # Read 8 bytes from lane 3 + vinserti32x4 \$1, %xmm30, %ymm31, %ymm31 + vpxorq (%r10,%r9,4), %ymm31, %ymm31 # Add data with the state + vmovdqu64 %ymm31, (%r10,%r9,4) + add \$8, %r9 + sub \$8, %r12 + jz .Lzero_bytes + + jmp .Lymm_loop + +.align 32 +.Lzero_bytes: + add %r9, $arg2 + add %r9, $arg3 + add %r9, $arg4 + add %r9, $arg5 + ret + +.align 32 +.Llt_8_bytes: + add %r9, $arg2 + add %r9, $arg3 + add %r9, $arg4 + add %r9, $arg5 + lea (%r10,%r9,4), %r10 + + lea byte_kmask_0_to_7(%rip), %rbx + kmovb (%rbx,%r12), %k1 # message load mask + + vmovdqu8 ($arg2), %xmm31{%k1}{z} # Read 1 to 7 bytes from lane 0 + vmovdqu8 ($arg3), %xmm30{%k1}{z} # Read 1 to 7 bytes from lane 1 + vpunpcklqdq %xmm30, %xmm31, %xmm31 # Interleave data from lane 0 and lane 1 + vmovdqu8 ($arg4), %xmm30{%k1}{z} # Read 1 to 7 bytes from lane 2 + vmovdqu8 ($arg5), %xmm29{%k1}{z} # Read 1 to 7 bytes from lane 3 + vpunpcklqdq %xmm29, %xmm30, %xmm30 # Interleave data from lane 2 and lane 3 + vinserti32x4 \$1, %xmm30, %ymm31, %ymm31 + + vpxorq (%r10), %ymm31, %ymm31 # Add data to the state + vmovdqu64 %ymm31, (%r10) # Update state in memory + + add %r12, $arg2 # increment message pointer lane 0 + add %r12, $arg3 # increment message pointer lane 1 + add %r12, $arg4 # increment message pointer lane 2 + add %r12, $arg5 # increment message pointer lane 3 + ret +.cfi_endproc +.size keccak_1600_partial_add_x4,.-keccak_1600_partial_add_x4 + + +# Extract bytes from state and write to outputs +# Arguments: +# r10: state pointer to start extracting from (clobbered) +# arg1 (rdi): output pointer lane 0 (updated on output) +# arg2 (rsi): output pointer lane 1 (updated on output) +# arg3 (rdx): output pointer lane 2 (updated on output) +# arg4 (rcx): output pointer lane 3 (updated on output) +# r12: length in bytes (clobbered on output) +# r11: state offset to start extract from +.globl keccak_1600_extract_bytes_x4 +.type keccak_1600_extract_bytes_x4,\@abi-omnipotent +.align 32 +keccak_1600_extract_bytes_x4: +.cfi_startproc + or %r12, %r12 + jz .Lextract_zero_bytes + + test \$7, %r11d + jz .Lextract_start_aligned_to_4x8 + + # Extract offset is not aligned to the register size (8 bytes) + mov %r11, %r9 + + and \$7, %r9d + neg %r9d + add \$8, %r9d # register capacity = 8 - (offset % 8) + cmp %r9d, %r12d + cmovnae %r12d, %r9d # %r9d = min(register capacity, length) + + lea byte_kmask_0_to_7(%rip), %rbx + kmovb (%rbx,%r9), %k1 # message store mask + + mov %r11, %rbx + and \$~7, %ebx + lea (%r10,%rbx,4), %r10 # get to state starting register + + mov %r11, %rbx + and \$7, %ebx + + vmovdqu8 8*0(%r10,%rbx), %xmm31{%k1}{z} # Read 1-7 bytes from state reg lane 0 + vmovdqu8 %xmm31, ($arg1){%k1} # Write 1-7 bytes to lane 0 output + + vmovdqu8 8*1(%r10,%rbx), %xmm31{%k1}{z} # Read 1-7 bytes from state reg lane 1 + vmovdqu8 %xmm31, ($arg2){%k1} # Write 1-7 bytes to lane 1 output + + vmovdqu8 8*2(%r10,%rbx), %xmm31{%k1}{z} # Read 1-7 bytes from state reg lane 2 + vmovdqu8 %xmm31, ($arg3){%k1} # Write 1-7 bytes to lane 2 output + + vmovdqu8 8*3(%r10,%rbx), %xmm31{%k1}{z} # Read 1-7 bytes from state reg lane 3 + vmovdqu8 %xmm31, ($arg4){%k1} # Write 1-7 bytes to lane 3 output + + # Increment output registers + add %r9, $arg1 + add %r9, $arg2 + add %r9, $arg3 + add %r9, $arg4 + + # Decrement length to extract + sub %r9, %r12 + jz .Lextract_zero_bytes + + # More data to extract, update state register pointer + add \$32, %r10 + xor %r9, %r9 + jmp .Lextract_ymm_loop + +.Lextract_start_aligned_to_4x8: + lea (%r10,%r11,4), %r10 + xor %r9, %r9 + +.align 32 +.Lextract_ymm_loop: + cmp \$8, %r12 + jb .Lextract_lt_8_bytes + + vmovdqu64 (%r10), %xmm31 + vmovdqu64 16(%r10), %xmm30 + vmovq %xmm31, ($arg1,%r9) + vpextrq \$1, %xmm31, ($arg2,%r9) + vmovq %xmm30, ($arg3,%r9) + vpextrq \$1, %xmm30, ($arg4,%r9) + add \$8, %r9 + sub \$8, %r12 + jz .Lzero_bytes_left + + add \$32, %r10 + jmp .Lextract_ymm_loop + +.align 32 +.Lzero_bytes_left: + # Increment output pointers + add %r9, $arg1 + add %r9, $arg2 + add %r9, $arg3 + add %r9, $arg4 +.Lextract_zero_bytes: + ret + +.align 32 +.Lextract_lt_8_bytes: + add %r9, $arg1 + add %r9, $arg2 + add %r9, $arg3 + add %r9, $arg4 + + lea byte_kmask_0_to_7(%rip), %r9 + kmovb (%r9,%r12), %k1 # k1 is the mask of message bytes to read + + vmovq 0*8(%r10), %xmm31 # Read 8 bytes from state lane 0 + vmovdqu8 %xmm31, ($arg1){%k1} # Extract 1-7 bytes into output 0 + vmovq 1*8(%r10), %xmm31 # Read 8 bytes from state lane 1 + vmovdqu8 %xmm31, ($arg2){%k1} # Extract 1-7 bytes into output 1 + vmovq 2*8(%r10), %xmm31 # Read 8 bytes from state lane 2 + vmovdqu8 %xmm31, ($arg3){%k1} # Extract 1-7 bytes into output 2 + vmovq 3*8(%r10), %xmm31 # Read 8 bytes from state lane 3 + vmovdqu8 %xmm31, ($arg4){%k1} # Extract 1-7 bytes into output 3 + + # Increment output pointers + add %r12, $arg1 + add %r12, $arg2 + add %r12, $arg3 + add %r12, $arg4 + ret +.cfi_endproc +.size keccak_1600_extract_bytes_x4,.-keccak_1600_extract_bytes_x4 + + +# SHAKE128 x4 multi-buffer functions +# These functions process 4 independent SHAKE128 streams in parallel using AVX-512VL +# State layout: 25 ymm registers (200 bytes each) + 1 qword = 808 bytes per context +# Rate: 168 bytes for SHAKE128 + +# SHA3_shake128_x4_avx512vl +# One-shot SHAKE-128 x4 function: init + absorb + finalize + squeeze +# Arguments: +# arg1 (rdi): pointer to output lane 0 +# arg2 (rsi): pointer to output lane 1 +# arg3 (rdx): pointer to output lane 2 +# arg4 (rcx): pointer to output lane 3 +# arg5 (r8): output length in bytes (must be same for all lanes) +# arg6 (r9): pointer to input lane 0 +# [stack+0]: pointer to input lane 1 +# [stack+8]: pointer to input lane 2 +# [stack+16]: pointer to input lane 3 +# [stack+24]: input length in bytes (must be same for all lanes) +# Returns: void +.globl SHA3_shake128_x4_avx512vl +.type SHA3_shake128_x4_avx512vl,\@function,10 +.align 32 +SHA3_shake128_x4_avx512vl: +.cfi_startproc + push %rbp +.cfi_push %rbp + mov %rsp, %rbp + push %rbx +.cfi_push %rbx +___ +$code .= <<___ if ($win64); + sub \$160, %rsp + vmovups %xmm6, 0(%rsp) + vmovups %xmm7, 16(%rsp) + vmovups %xmm8, 32(%rsp) + vmovups %xmm9, 48(%rsp) + vmovups %xmm10, 64(%rsp) + vmovups %xmm11, 80(%rsp) + vmovups %xmm12, 96(%rsp) + vmovups %xmm13, 112(%rsp) + vmovups %xmm14, 128(%rsp) + vmovups %xmm15, 144(%rsp) +___ +$code.=<<___; + + sub \$$sf_size, %rsp + mov %rsp, %rbx + +.Lshake128_x4_body: + mov $arg1, $sf_arg1(%rbx) + mov $arg2, $sf_arg2(%rbx) + mov $arg3, $sf_arg3(%rbx) + mov $arg4, $sf_arg4(%rbx) + mov $arg5, $sf_arg5(%rbx) + + lea $sf_state_x4(%rbx), $arg1 # start of x4 state on the stack frame + mov $arg1, $sf_state_ptr(%rbx) + + # Initialize the state array to zero + call keccak_1600_init_state + + call keccak_1600_save_state_x4 + + movq \$0, 8*100($arg1) # clear s[100] + + mov $sf_state_ptr(%rbx), $arg1 + mov $arg6, $arg2 +___ +$code .= <<___ if ($win64); + # xlate prologue handles up to six arguments. For one-shot x4 wrappers + # (10 args), the remaining four stay in Win64 stack slots. + mov 64(%rbp), $arg3 # arg7 from stack + mov 72(%rbp), $arg4 # arg8 from stack + mov 80(%rbp), $arg5 # arg9 from stack + mov 88(%rbp), $arg6 # arg10 from stack +___ +$code .= <<___ if (!$win64); + mov 16(%rbp), $arg3 # arg7 from stack + mov 24(%rbp), $arg4 # arg8 from stack + mov 32(%rbp), $arg5 # arg9 from stack + mov 40(%rbp), $arg6 # arg10 from stack +___ +$code.=<<___; + # Internal entry avoids Win64 xlate prologue argument remapping. +___ +$code .= call_internal("SHA3_shake128_x4_inc_absorb_avx512vl_internal"); +$code.=<<___; + + mov $sf_state_ptr(%rbx), $arg1 + call .L_SHA3_shake128_x4_inc_finalize_avx512vl + + # squeeze + mov $sf_arg1(%rbx), $arg1 + mov $sf_arg2(%rbx), $arg2 + mov $sf_arg3(%rbx), $arg3 + mov $sf_arg4(%rbx), $arg4 + mov $sf_arg5(%rbx), $arg5 + mov $sf_state_ptr(%rbx), $arg6 +___ +$code .= call_internal("SHA3_shake128_x4_inc_squeeze_avx512vl_internal"); +$code.=<<___; + + # Clear the temporary buffer + lea $sf_state_x4(%rbx), %r9 + vpxorq %ymm31, %ymm31, %ymm31 + vmovdqu64 %ymm31, 32*0(%r9) + vmovdqu64 %ymm31, 32*1(%r9) + vmovdqu64 %ymm31, 32*2(%r9) + vmovdqu64 %ymm31, 32*3(%r9) + vmovdqu64 %ymm31, 32*4(%r9) + vmovdqu64 %ymm31, 32*5(%r9) + vmovdqu64 %ymm31, 32*6(%r9) + vmovdqu64 %ymm31, 32*7(%r9) + vmovdqu64 %ymm31, 32*8(%r9) + vmovdqu64 %ymm31, 32*9(%r9) + vmovdqu64 %ymm31, 32*10(%r9) + vmovdqu64 %ymm31, 32*11(%r9) + vmovdqu64 %ymm31, 32*12(%r9) + vmovdqu64 %ymm31, 32*13(%r9) + vmovdqu64 %ymm31, 32*14(%r9) + vmovdqu64 %ymm31, 32*15(%r9) + vmovdqu64 %ymm31, 32*16(%r9) + vmovdqu64 %ymm31, 32*17(%r9) + vmovdqu64 %ymm31, 32*18(%r9) + vmovdqu64 %ymm31, 32*19(%r9) + vmovdqu64 %ymm31, 32*20(%r9) + vmovdqu64 %ymm31, 32*21(%r9) + vmovdqu64 %ymm31, 32*22(%r9) + vmovdqu64 %ymm31, 32*23(%r9) + vmovdqu64 %ymm31, 32*24(%r9) + vmovq %xmm31, 32*25(%r9) + +.Lshake128_x4_epilogue: +___ +$code .= <<___ if ($win64); + vmovups $sf_size+0(%rsp), %xmm6 + vmovups $sf_size+16(%rsp), %xmm7 + vmovups $sf_size+32(%rsp), %xmm8 + vmovups $sf_size+48(%rsp), %xmm9 + vmovups $sf_size+64(%rsp), %xmm10 + vmovups $sf_size+80(%rsp), %xmm11 + vmovups $sf_size+96(%rsp), %xmm12 + vmovups $sf_size+112(%rsp), %xmm13 + vmovups $sf_size+128(%rsp), %xmm14 + vmovups $sf_size+144(%rsp), %xmm15 + add \$160, %rsp +___ +$code.=<<___; + add \$$sf_size, %rsp + pop %rbx +.cfi_pop %rbx + pop %rbp +.cfi_pop %rbp + ret +.cfi_endproc +.size SHA3_shake128_x4_avx512vl,.-SHA3_shake128_x4_avx512vl + +___ + +$code .= <<___ if ($win64); +# Internal Win64 shim for absorb entry. It establishes xlate-compatible +# unwind state and then jumps to the function entry after the prologue. +# This is required for internal calls since the xlate ABI conversion +# is already done in the caller function. +.type SHA3_shake128_x4_inc_absorb_avx512vl_internal,\@abi-omnipotent +.align 32 +.LSEH_begin_SHA3_shake128_x4_inc_absorb_avx512vl_internal: +SHA3_shake128_x4_inc_absorb_avx512vl_internal: + mov %rsp, %rax + mov $arg1, 8(%rsp) + mov $arg2, 16(%rsp) + jmp .L_SHA3_shake128_x4_inc_absorb_avx512vl +.LSEH_end_SHA3_shake128_x4_inc_absorb_avx512vl_internal: +.size SHA3_shake128_x4_inc_absorb_avx512vl_internal,.-SHA3_shake128_x4_inc_absorb_avx512vl_internal +___ +$code.=<<___; + +# SHA3_shake128_x4_inc_absorb_avx512vl +# Absorb input data into 4 parallel SHAKE128 states +# Arguments: +# arg1 (rdi): pointer to state context (808 bytes) +# arg2 (rsi): pointer to lane 0 input data +# arg3 (rdx): pointer to lane 1 input data +# arg4 (rcx): pointer to lane 2 input data +# arg5 (r8): pointer to lane 3 input data +# arg6 (r9): input length in bytes (must be same for all lanes) +# Returns: void +# Note: Input is XORed into state and Keccak permutation is applied for each rate-sized block +.globl SHA3_shake128_x4_inc_absorb_avx512vl +.type SHA3_shake128_x4_inc_absorb_avx512vl,\@function,6 +.align 32 +SHA3_shake128_x4_inc_absorb_avx512vl: +.L_SHA3_shake128_x4_inc_absorb_avx512vl: +.cfi_startproc + push %rbp +.cfi_push %rbp + push %rbx +.cfi_push %rbx + push %r12 +.cfi_push %r12 + push %r13 +.cfi_push %r13 + push %r14 +.cfi_push %r14 + push %r15 +.cfi_push %r15 +___ +$code .= <<___ if ($win64); + sub \$160, %rsp + vmovups %xmm6, 0(%rsp) + vmovups %xmm7, 16(%rsp) + vmovups %xmm8, 32(%rsp) + vmovups %xmm9, 48(%rsp) + vmovups %xmm10, 64(%rsp) + vmovups %xmm11, 80(%rsp) + vmovups %xmm12, 96(%rsp) + vmovups %xmm13, 112(%rsp) + vmovups %xmm14, 128(%rsp) + vmovups %xmm15, 144(%rsp) +___ +$code.=<<___; + +.Lshake128_absorb_body: + # check for partially processed block + mov 8*100($arg1), %r14 + or %r14, %r14 # s[100] == 0? + je .Lshake128_absorb_main_loop_start + + # process remaining bytes if message long enough + mov \$168, %r12 # SHAKE128_RATE = 168 + sub %r14, %r12 # %r12 = capacity + + cmp %r12, $arg6 # if mlen <= capacity then no permute + jbe .Lshake128_absorb_skip_permute + + sub %r12, $arg6 + mov $arg6, %r11 # preserve remaining length across helper calls + + # r10/state, arg2-arg5/inputs, r12/length + mov $arg1, %r10 # %r10 = state + call keccak_1600_partial_add_x4 # arg2-arg5 are updated + + call keccak_1600_load_state_x4 + + call keccak_1600_permute + + movq \$0, 8*100($arg1) # clear s[100] + jmp .Lshake128_absorb_partial_block_done + +.Lshake128_absorb_skip_permute: + # r10/state, arg2-arg5/inputs, r12/length + mov $arg1, %r10 + mov $arg6, %r12 + mov $arg6, %r11 # preserve input length across helper call + call keccak_1600_partial_add_x4 + + lea (%r11,%r14), %r15 + mov %r15, 8*100($arg1) # s[100] += inlen + + cmp \$168, %r15 # check s[100] below SHAKE128_RATE + jb .Lshake128_absorb_exit + + call keccak_1600_load_state_x4 + + call keccak_1600_permute + + call keccak_1600_save_state_x4 + + movq \$0, 8*100($arg1) # clear s[100] + jmp .Lshake128_absorb_exit + +.Lshake128_absorb_main_loop_start: + call keccak_1600_load_state_x4 + mov $arg6, %r11 # full input length when no prior partial block + +.Lshake128_absorb_partial_block_done: + xor %r12, %r12 # zero message offset + + # Process the input message in blocks +.align 32 +.Lshake128_absorb_while_loop: + cmp \$168, %r11 # compare mlen to SHAKE128_RATE + jb .Lshake128_absorb_while_loop_done + + # Inline absorb_bytes_x4 for SHAKE128_RATE (168 bytes = 21 ymm registers) +___ + +# Generate absorb code for SHAKE128 rate (168 bytes) +for (my $i = 0; $i < 21; $i++) { + my $offset = $i * 8; + $code.=<<___; + vmovq $offset($arg2,%r12), %xmm31 + vpinsrq \$1, $offset($arg3,%r12), %xmm31, %xmm31 + vmovq $offset($arg4,%r12), %xmm30 + vpinsrq \$1, $offset($arg5,%r12), %xmm30, %xmm30 + vinserti32x4 \$1, %xmm30, %ymm31, %ymm31 + vpxorq %ymm31, %ymm$i, %ymm$i +___ +} + +$code.=<<___; + sub \$168, %r11 # Subtract the rate from the remaining length + add \$168, %r12 # Adjust offset to next block + call keccak_1600_permute # Perform the Keccak permutation + + jmp .Lshake128_absorb_while_loop + +.align 32 +.Lshake128_absorb_while_loop_done: + call keccak_1600_save_state_x4 + + mov %r11, 8*100($arg1) # update s[100] + or %r11, %r11 + jz .Lshake128_absorb_exit + + movq \$0, 8*100($arg1) # clear s[100] + + # r10/state, arg2-arg5/input, r12/length + mov $arg1, %r10 + add %r12, $arg2 + add %r12, $arg3 + add %r12, $arg4 + add %r12, $arg5 + mov %r11, %r12 + call keccak_1600_partial_add_x4 + + mov %r11, 8*100($arg1) # update s[100] + +.Lshake128_absorb_exit: + # Clear sensitive registers + vpxorq %xmm16, %xmm16, %xmm16 + vmovdqa64 %ymm16, %ymm17 + vmovdqa64 %ymm16, %ymm18 + vmovdqa64 %ymm16, %ymm19 + vmovdqa64 %ymm16, %ymm20 + vmovdqa64 %ymm16, %ymm21 + vmovdqa64 %ymm16, %ymm22 + vmovdqa64 %ymm16, %ymm23 + vmovdqa64 %ymm16, %ymm24 + vmovdqa64 %ymm16, %ymm25 + vmovdqa64 %ymm16, %ymm26 + vmovdqa64 %ymm16, %ymm27 + vmovdqa64 %ymm16, %ymm28 + vmovdqa64 %ymm16, %ymm29 + vmovdqa64 %ymm16, %ymm30 + vmovdqa64 %ymm16, %ymm31 +.Lshake128_absorb_epilogue: + vzeroall +___ +$code .= <<___ if ($win64); + vmovups 0(%rsp), %xmm6 + vmovups 16(%rsp), %xmm7 + vmovups 32(%rsp), %xmm8 + vmovups 48(%rsp), %xmm9 + vmovups 64(%rsp), %xmm10 + vmovups 80(%rsp), %xmm11 + vmovups 96(%rsp), %xmm12 + vmovups 112(%rsp), %xmm13 + vmovups 128(%rsp), %xmm14 + vmovups 144(%rsp), %xmm15 + add \$160, %rsp +___ +$code.=<<___; + + pop %r15 +.cfi_pop %r15 + pop %r14 +.cfi_pop %r14 + pop %r13 +.cfi_pop %r13 + pop %r12 +.cfi_pop %r12 + pop %rbx +.cfi_pop %rbx + pop %rbp +.cfi_pop %rbp + ret +.cfi_endproc +.size SHA3_shake128_x4_inc_absorb_avx512vl,.-SHA3_shake128_x4_inc_absorb_avx512vl + + +# SHA3_shake128_x4_inc_finalize_avx512vl +# Finalize absorption phase for 4 parallel SHAKE-128 states +# Adds padding and terminator bytes and clears the absorb offset +# Arguments: +# arg1 (rdi): pointer to state context (808 bytes) +# Returns: void +# Note: After this call, state is ready for squeezing output +.globl SHA3_shake128_x4_inc_finalize_avx512vl +.type SHA3_shake128_x4_inc_finalize_avx512vl,\@function,1 +.align 32 +SHA3_shake128_x4_inc_finalize_avx512vl: +.L_SHA3_shake128_x4_inc_finalize_avx512vl: +.cfi_startproc + mov 8*100($arg1), %r11 # load state offset from s[100] + mov %r11, %r10 + and \$~7, %r10d # offset to the state register + and \$7, %r11d # offset within the register + + # add EOM byte right after the message + vmovdqu32 ($arg1,%r10,4), %ymm31 + lea shake_msg_pad_x4(%rip), %r9 + sub %r11, %r9 + vmovdqu32 (%r9), %ymm30 + vpxorq %ymm30, %ymm31, %ymm31 + vmovdqu32 %ymm31, ($arg1,%r10,4) + + # add terminating byte at offset equal to rate - 1 (SHAKE128_RATE = 168) + vmovdqu32 640($arg1), %ymm31 # 168*4 - 32 = 672 - 32 = 640 + vmovdqa32 shake_terminator_byte_x4(%rip), %ymm30 + vpxorq %ymm30, %ymm31, %ymm31 + vmovdqu32 %ymm31, 640($arg1) + + movq \$0, 8*100($arg1) # clear s[100] + vpxorq %ymm31, %ymm31, %ymm31 + ret +.cfi_endproc +.size SHA3_shake128_x4_inc_finalize_avx512vl,.-SHA3_shake128_x4_inc_finalize_avx512vl + +___ + +$code .= <<___ if ($win64); +# Internal Win64 shim for squeeze entry. It establishes xlate-compatible +# unwind state and then jumps to the function entry after the prologue. +# This is required for internal calls since the xlate ABI conversion +# is already done in the caller function. +.type SHA3_shake128_x4_inc_squeeze_avx512vl_internal,\@abi-omnipotent +.align 32 +.LSEH_begin_SHA3_shake128_x4_inc_squeeze_avx512vl_internal: +SHA3_shake128_x4_inc_squeeze_avx512vl_internal: + mov %rsp, %rax + mov $arg1, 8(%rsp) + mov $arg2, 16(%rsp) + jmp .L_SHA3_shake128_x4_inc_squeeze_avx512vl +.LSEH_end_SHA3_shake128_x4_inc_squeeze_avx512vl_internal: +.size SHA3_shake128_x4_inc_squeeze_avx512vl_internal,.-SHA3_shake128_x4_inc_squeeze_avx512vl_internal +___ +$code.=<<___; + +# SHA3_shake128_x4_inc_squeeze_avx512vl +# Squeeze output from 4 parallel SHAKE128 states +# Arguments: +# arg1 (rdi): pointer to lane 0 output buffer +# arg2 (rsi): pointer to lane 1 output buffer +# arg3 (rdx): pointer to lane 2 output buffer +# arg4 (rcx): pointer to lane 3 output buffer +# arg5 (r8): output length in bytes (must be same for all lanes) +# arg6 (r9): pointer to state context (808 bytes) +# Returns: void +# Note: Can be called multiple times to generate arbitrary-length output +.globl SHA3_shake128_x4_inc_squeeze_avx512vl +.type SHA3_shake128_x4_inc_squeeze_avx512vl,\@function,6 +.align 32 +SHA3_shake128_x4_inc_squeeze_avx512vl: +.L_SHA3_shake128_x4_inc_squeeze_avx512vl: +.cfi_startproc + push %rbp +.cfi_push %rbp + push %rbx +.cfi_push %rbx + push %r12 +.cfi_push %r12 + push %r13 +.cfi_push %r13 + push %r14 +.cfi_push %r14 + push %r15 +.cfi_push %r15 +___ +$code .= <<___ if ($win64); + sub \$160, %rsp + vmovups %xmm6, 0(%rsp) + vmovups %xmm7, 16(%rsp) + vmovups %xmm8, 32(%rsp) + vmovups %xmm9, 48(%rsp) + vmovups %xmm10, 64(%rsp) + vmovups %xmm11, 80(%rsp) + vmovups %xmm12, 96(%rsp) + vmovups %xmm13, 112(%rsp) + vmovups %xmm14, 128(%rsp) + vmovups %xmm15, 144(%rsp) +___ +$code.=<<___; + +.Lshake128_squeeze_body: + or $arg5, $arg5 + jz .Lshake128_squeeze_done + + # check for partially processed block + mov 8*100($arg6), %r15 # s[100] - capacity + or %r15, %r15 + jnz .Lshake128_squeeze_no_init_permute + + mov $arg1, %r14 + mov $arg6, $arg1 + call keccak_1600_load_state_x4 + + mov %r14, $arg1 + + xor %rbp, %rbp + jmp .Lshake128_squeeze_loop + +.align 32 +.Lshake128_squeeze_no_init_permute: + # extract bytes: r10 - state/src, arg1-arg4 - output/dst, r12 - length = min(capacity, outlen), r11 - offset + mov $arg6, %r10 + mov $arg6, %r14 # preserve state pointer across extract helper + + mov %r15, %r12 + cmp %r15, $arg5 + cmovnae $arg5, %r12 # %r12 = min(capacity, outlen) + + sub %r12, $arg5 # outlen -= length + + mov \$168, %r11d # SHAKE128_RATE + sub %r15, %r11 # state offset + + sub %r12, %r15 # capacity -= length + mov %r15, 8*100($arg6) # update s[100] + + call keccak_1600_extract_bytes_x4 + mov %r14, $arg6 # restore state pointer after helper clobbers + + or %r15, %r15 + jnz .Lshake128_squeeze_done # check s[100] not zero + + mov $arg1, %r13 # preserve arg1 + mov %r14, $arg1 + call keccak_1600_load_state_x4 + + mov %r13, $arg1 + xor %rbp, %rbp + +.align 32 +.Lshake128_squeeze_loop: + cmp \$168, $arg5 # outlen > SHAKE128_RATE + jb .Lshake128_squeeze_final_extract + + call keccak_1600_permute + + # Extract SHAKE128 rate bytes (168 bytes = 21 x 8 bytes) inline +___ + +# Generate extract code for SHAKE128 rate (168 bytes = 21 ymm registers) +for (my $i = 0; $i < 21; $i++) { + my $offset = $i * 8; + $code.=<<___; + vextracti64x2 \$1, %ymm$i, %xmm31 + vmovq %xmm$i, $offset($arg1,%rbp) + vpextrq \$1, %xmm$i, $offset($arg2,%rbp) + vmovq %xmm31, $offset($arg3,%rbp) + vpextrq \$1, %xmm31, $offset($arg4,%rbp) +___ +} + +$code.=<<___; + add \$168, %rbp # dst offset += SHAKE128_RATE + sub \$168, $arg5 # outlen -= SHAKE128_RATE + jmp .Lshake128_squeeze_loop + +.align 32 +.Lshake128_squeeze_final_extract: + or $arg5, $arg5 + jz .Lshake128_squeeze_no_end_permute + + # update output pointers + add %rbp, $arg1 + add %rbp, $arg2 + add %rbp, $arg3 + add %rbp, $arg4 + + mov \$168, %r15d # SHAKE128_RATE + sub $arg5, %r15 + mov %r15, 8*100($arg6) # s[100] = capacity + + call keccak_1600_permute + + mov $arg1, %r14 + mov $arg6, $arg1 + call keccak_1600_save_state_x4 + + mov %r14, $arg1 + + # extract bytes: r10 - state/src, arg1-arg4 - output/dst, r12 - length, r11 - offset = 0 + mov $arg6, %r10 + mov $arg5, %r12 + xor %r11, %r11 + call keccak_1600_extract_bytes_x4 + + jmp .Lshake128_squeeze_done + +.Lshake128_squeeze_no_end_permute: + movq \$0, 8*100($arg6) # s[100] = 0 + mov $arg6, $arg1 + call keccak_1600_save_state_x4 + +.Lshake128_squeeze_done: + # Clear sensitive registers + vpxorq %xmm16, %xmm16, %xmm16 + vmovdqa64 %ymm16, %ymm17 + vmovdqa64 %ymm16, %ymm18 + vmovdqa64 %ymm16, %ymm19 + vmovdqa64 %ymm16, %ymm20 + vmovdqa64 %ymm16, %ymm21 + vmovdqa64 %ymm16, %ymm22 + vmovdqa64 %ymm16, %ymm23 + vmovdqa64 %ymm16, %ymm24 + vmovdqa64 %ymm16, %ymm25 + vmovdqa64 %ymm16, %ymm26 + vmovdqa64 %ymm16, %ymm27 + vmovdqa64 %ymm16, %ymm28 + vmovdqa64 %ymm16, %ymm29 + vmovdqa64 %ymm16, %ymm30 + vmovdqa64 %ymm16, %ymm31 +.Lshake128_squeeze_epilogue: + vzeroall +___ +$code .= <<___ if ($win64); + vmovups 0(%rsp), %xmm6 + vmovups 16(%rsp), %xmm7 + vmovups 32(%rsp), %xmm8 + vmovups 48(%rsp), %xmm9 + vmovups 64(%rsp), %xmm10 + vmovups 80(%rsp), %xmm11 + vmovups 96(%rsp), %xmm12 + vmovups 112(%rsp), %xmm13 + vmovups 128(%rsp), %xmm14 + vmovups 144(%rsp), %xmm15 + add \$160, %rsp +___ +$code.=<<___; + + pop %r15 +.cfi_pop %r15 + pop %r14 +.cfi_pop %r14 + pop %r13 +.cfi_pop %r13 + pop %r12 +.cfi_pop %r12 + pop %rbx +.cfi_pop %rbx + pop %rbp +.cfi_pop %rbp + ret +.cfi_endproc +.size SHA3_shake128_x4_inc_squeeze_avx512vl,.-SHA3_shake128_x4_inc_squeeze_avx512vl + + +# SHAKE256 x4 multi-buffer functions +# These functions process 4 independent SHAKE256 streams in parallel using AVX-512VL +# State layout: 25 ymm registers (200 bytes each) + 1 qword = 808 bytes per context +# Rate: 136 bytes for SHAKE256 + +# SHA3_shake256_x4_avx512vl +# One-shot SHAKE-256 x4 function: init + absorb + finalize + squeeze +# Arguments: +# arg1 (rdi): pointer to output lane 0 +# arg2 (rsi): pointer to output lane 1 +# arg3 (rdx): pointer to output lane 2 +# arg4 (rcx): pointer to output lane 3 +# arg5 (r8): output length in bytes (must be same for all lanes) +# arg6 (r9): pointer to input lane 0 +# [stack+0]: pointer to input lane 1 +# [stack+8]: pointer to input lane 2 +# [stack+16]: pointer to input lane 3 +# [stack+24]: input length in bytes (must be same for all lanes) +# Returns: void +.globl SHA3_shake256_x4_avx512vl +.type SHA3_shake256_x4_avx512vl,\@function,10 +.align 32 +SHA3_shake256_x4_avx512vl: +.cfi_startproc + push %rbp +.cfi_push %rbp + mov %rsp, %rbp + push %rbx +.cfi_push %rbx +___ +$code .= <<___ if ($win64); + sub \$160, %rsp + vmovups %xmm6, 0(%rsp) + vmovups %xmm7, 16(%rsp) + vmovups %xmm8, 32(%rsp) + vmovups %xmm9, 48(%rsp) + vmovups %xmm10, 64(%rsp) + vmovups %xmm11, 80(%rsp) + vmovups %xmm12, 96(%rsp) + vmovups %xmm13, 112(%rsp) + vmovups %xmm14, 128(%rsp) + vmovups %xmm15, 144(%rsp) +___ +$code.=<<___; + + sub \$$sf_size, %rsp + mov %rsp, %rbx + +.Lshake256_x4_body: + mov $arg1, $sf_arg1(%rbx) + mov $arg2, $sf_arg2(%rbx) + mov $arg3, $sf_arg3(%rbx) + mov $arg4, $sf_arg4(%rbx) + mov $arg5, $sf_arg5(%rbx) + + lea $sf_state_x4(%rbx), $arg1 # start of x4 state on the stack frame + mov $arg1, $sf_state_ptr(%rbx) + + # Initialize the state array to zero + call keccak_1600_init_state + + call keccak_1600_save_state_x4 + + movq \$0, 8*100($arg1) # clear s[100] + + mov $sf_state_ptr(%rbx), $arg1 + mov $arg6, $arg2 +___ +$code .= <<___ if ($win64); + # xlate prologue handles up to six arguments. For one-shot x4 wrappers + # (10 args), the remaining four stay in Win64 stack slots. + mov 64(%rbp), $arg3 # arg7 from stack + mov 72(%rbp), $arg4 # arg8 from stack + mov 80(%rbp), $arg5 # arg9 from stack + mov 88(%rbp), $arg6 # arg10 from stack +___ +$code .= <<___ if (!$win64); + mov 16(%rbp), $arg3 # arg7 from stack + mov 24(%rbp), $arg4 # arg8 from stack + mov 32(%rbp), $arg5 # arg9 from stack + mov 40(%rbp), $arg6 # arg10 from stack +___ +$code.=<<___; + # Internal entry avoids Win64 xlate prologue argument remapping. +___ +$code .= call_internal("SHA3_shake256_x4_inc_absorb_avx512vl_internal"); +$code.=<<___; + + mov $sf_state_ptr(%rbx), $arg1 + call .L_SHA3_shake256_x4_inc_finalize_avx512vl + + # squeeze + mov $sf_arg1(%rbx), $arg1 + mov $sf_arg2(%rbx), $arg2 + mov $sf_arg3(%rbx), $arg3 + mov $sf_arg4(%rbx), $arg4 + mov $sf_arg5(%rbx), $arg5 + mov $sf_state_ptr(%rbx), $arg6 +___ +$code .= call_internal("SHA3_shake256_x4_inc_squeeze_avx512vl_internal"); +$code.=<<___; + + # Clear the temporary buffer + lea $sf_state_x4(%rbx), %r9 + vpxorq %ymm31, %ymm31, %ymm31 + vmovdqu64 %ymm31, 32*0(%r9) + vmovdqu64 %ymm31, 32*1(%r9) + vmovdqu64 %ymm31, 32*2(%r9) + vmovdqu64 %ymm31, 32*3(%r9) + vmovdqu64 %ymm31, 32*4(%r9) + vmovdqu64 %ymm31, 32*5(%r9) + vmovdqu64 %ymm31, 32*6(%r9) + vmovdqu64 %ymm31, 32*7(%r9) + vmovdqu64 %ymm31, 32*8(%r9) + vmovdqu64 %ymm31, 32*9(%r9) + vmovdqu64 %ymm31, 32*10(%r9) + vmovdqu64 %ymm31, 32*11(%r9) + vmovdqu64 %ymm31, 32*12(%r9) + vmovdqu64 %ymm31, 32*13(%r9) + vmovdqu64 %ymm31, 32*14(%r9) + vmovdqu64 %ymm31, 32*15(%r9) + vmovdqu64 %ymm31, 32*16(%r9) + vmovdqu64 %ymm31, 32*17(%r9) + vmovdqu64 %ymm31, 32*18(%r9) + vmovdqu64 %ymm31, 32*19(%r9) + vmovdqu64 %ymm31, 32*20(%r9) + vmovdqu64 %ymm31, 32*21(%r9) + vmovdqu64 %ymm31, 32*22(%r9) + vmovdqu64 %ymm31, 32*23(%r9) + vmovdqu64 %ymm31, 32*24(%r9) + vmovq %xmm31, 32*25(%r9) + +.Lshake256_x4_epilogue: +___ +$code .= <<___ if ($win64); + vmovups $sf_size+0(%rsp), %xmm6 + vmovups $sf_size+16(%rsp), %xmm7 + vmovups $sf_size+32(%rsp), %xmm8 + vmovups $sf_size+48(%rsp), %xmm9 + vmovups $sf_size+64(%rsp), %xmm10 + vmovups $sf_size+80(%rsp), %xmm11 + vmovups $sf_size+96(%rsp), %xmm12 + vmovups $sf_size+112(%rsp), %xmm13 + vmovups $sf_size+128(%rsp), %xmm14 + vmovups $sf_size+144(%rsp), %xmm15 + add \$160, %rsp +___ +$code.=<<___; + add \$$sf_size, %rsp + pop %rbx +.cfi_pop %rbx + pop %rbp +.cfi_pop %rbp + ret +.cfi_endproc +.size SHA3_shake256_x4_avx512vl,.-SHA3_shake256_x4_avx512vl + +___ + +$code .= <<___ if ($win64); +# Internal Win64 shim for absorb entry. It establishes xlate-compatible +# unwind state and then jumps to the function entry after the prologue. +# This is required for internal calls since the xlate ABI conversion +# is already done in the caller function. +.type SHA3_shake256_x4_inc_absorb_avx512vl_internal,\@abi-omnipotent +.align 32 +.LSEH_begin_SHA3_shake256_x4_inc_absorb_avx512vl_internal: +SHA3_shake256_x4_inc_absorb_avx512vl_internal: + mov %rsp, %rax + mov $arg1, 8(%rsp) + mov $arg2, 16(%rsp) + jmp .L_SHA3_shake256_x4_inc_absorb_avx512vl +.LSEH_end_SHA3_shake256_x4_inc_absorb_avx512vl_internal: +.size SHA3_shake256_x4_inc_absorb_avx512vl_internal,.-SHA3_shake256_x4_inc_absorb_avx512vl_internal +___ +$code.=<<___; + +# SHA3_shake256_x4_inc_absorb_avx512vl +# Absorb input data into 4 parallel SHAKE256 states +# Arguments: +# arg1 (rdi): pointer to state context (808 bytes) +# arg2 (rsi): pointer to lane 0 input data +# arg3 (rdx): pointer to lane 1 input data +# arg4 (rcx): pointer to lane 2 input data +# arg5 (r8): pointer to lane 3 input data +# arg6 (r9): input length in bytes (must be same for all lanes) +# Returns: void +# Note: Input is XORed into state and Keccak permutation is applied for each rate-sized block +.globl SHA3_shake256_x4_inc_absorb_avx512vl +.type SHA3_shake256_x4_inc_absorb_avx512vl,\@function,6 +.align 32 +SHA3_shake256_x4_inc_absorb_avx512vl: +.L_SHA3_shake256_x4_inc_absorb_avx512vl: +.cfi_startproc + push %rbp +.cfi_push %rbp + push %rbx +.cfi_push %rbx + push %r12 +.cfi_push %r12 + push %r13 +.cfi_push %r13 + push %r14 +.cfi_push %r14 + push %r15 +.cfi_push %r15 +___ +$code .= <<___ if ($win64); + sub \$160, %rsp + vmovups %xmm6, 0(%rsp) + vmovups %xmm7, 16(%rsp) + vmovups %xmm8, 32(%rsp) + vmovups %xmm9, 48(%rsp) + vmovups %xmm10, 64(%rsp) + vmovups %xmm11, 80(%rsp) + vmovups %xmm12, 96(%rsp) + vmovups %xmm13, 112(%rsp) + vmovups %xmm14, 128(%rsp) + vmovups %xmm15, 144(%rsp) +___ +$code.=<<___; + +.Lshake256_absorb_body: + # check for partially processed block + mov 8*100($arg1), %r14 + or %r14, %r14 # s[100] == 0? + je .Lshake256_absorb_main_loop_start + + # process remaining bytes if message long enough + mov \$136, %r12 # SHAKE256_RATE = 136 + sub %r14, %r12 # %r12 = capacity + + cmp %r12, $arg6 # if mlen <= capacity then no permute + jbe .Lshake256_absorb_skip_permute + + sub %r12, $arg6 + mov $arg6, %r11 # preserve remaining length across helper calls + + # r10/state, arg2-arg5/inputs, r12/length + mov $arg1, %r10 # %r10 = state + call keccak_1600_partial_add_x4 # arg2-arg5 are updated + + call keccak_1600_load_state_x4 + + call keccak_1600_permute + + movq \$0, 8*100($arg1) # clear s[100] + jmp .Lshake256_absorb_partial_block_done + +.Lshake256_absorb_skip_permute: + # r10/state, arg2-arg5/inputs, r12/length + mov $arg1, %r10 + mov $arg6, %r12 + mov $arg6, %r11 # preserve input length across helper call + call keccak_1600_partial_add_x4 + + lea (%r11,%r14), %r15 + mov %r15, 8*100($arg1) # s[100] += inlen + + cmp \$136, %r15 # check s[100] below SHAKE256_RATE + jb .Lshake256_absorb_exit + + call keccak_1600_load_state_x4 + + call keccak_1600_permute + + call keccak_1600_save_state_x4 + + movq \$0, 8*100($arg1) # clear s[100] + jmp .Lshake256_absorb_exit + +.Lshake256_absorb_main_loop_start: + call keccak_1600_load_state_x4 + mov $arg6, %r11 # full input length when no prior partial block + +.Lshake256_absorb_partial_block_done: + xor %r12, %r12 # zero message offset + + # Process the input message in blocks +.align 32 +.Lshake256_absorb_while_loop: + cmp \$136, %r11 # compare mlen to SHAKE256_RATE + jb .Lshake256_absorb_while_loop_done + + # Inline absorb_bytes_x4 for SHAKE256_RATE (136 bytes = 17 ymm registers) +___ + +# Generate absorb code for SHAKE256 rate (136 bytes) +for (my $i = 0; $i < 17; $i++) { + my $offset = $i * 8; + $code.=<<___; + vmovq $offset($arg2,%r12), %xmm31 + vpinsrq \$1, $offset($arg3,%r12), %xmm31, %xmm31 + vmovq $offset($arg4,%r12), %xmm30 + vpinsrq \$1, $offset($arg5,%r12), %xmm30, %xmm30 + vinserti32x4 \$1, %xmm30, %ymm31, %ymm31 + vpxorq %ymm31, %ymm$i, %ymm$i +___ +} + +$code.=<<___; + sub \$136, %r11 # Subtract the rate from the remaining length + add \$136, %r12 # Adjust offset to next block + call keccak_1600_permute # Perform the Keccak permutation + + jmp .Lshake256_absorb_while_loop + +.align 32 +.Lshake256_absorb_while_loop_done: + call keccak_1600_save_state_x4 + + mov %r11, 8*100($arg1) # update s[100] + or %r11, %r11 + jz .Lshake256_absorb_exit + + movq \$0, 8*100($arg1) # clear s[100] + + # r10/state, arg2-arg5/input, r12/length + mov $arg1, %r10 + add %r12, $arg2 + add %r12, $arg3 + add %r12, $arg4 + add %r12, $arg5 + mov %r11, %r12 + call keccak_1600_partial_add_x4 + + mov %r11, 8*100($arg1) # update s[100] + +.Lshake256_absorb_exit: + # Clear sensitive registers + vpxorq %xmm16, %xmm16, %xmm16 + vmovdqa64 %ymm16, %ymm17 + vmovdqa64 %ymm16, %ymm18 + vmovdqa64 %ymm16, %ymm19 + vmovdqa64 %ymm16, %ymm20 + vmovdqa64 %ymm16, %ymm21 + vmovdqa64 %ymm16, %ymm22 + vmovdqa64 %ymm16, %ymm23 + vmovdqa64 %ymm16, %ymm24 + vmovdqa64 %ymm16, %ymm25 + vmovdqa64 %ymm16, %ymm26 + vmovdqa64 %ymm16, %ymm27 + vmovdqa64 %ymm16, %ymm28 + vmovdqa64 %ymm16, %ymm29 + vmovdqa64 %ymm16, %ymm30 + vmovdqa64 %ymm16, %ymm31 +.Lshake256_absorb_epilogue: +___ +$code .= <<___ if ($win64); + vmovups 0(%rsp), %xmm6 + vmovups 16(%rsp), %xmm7 + vmovups 32(%rsp), %xmm8 + vmovups 48(%rsp), %xmm9 + vmovups 64(%rsp), %xmm10 + vmovups 80(%rsp), %xmm11 + vmovups 96(%rsp), %xmm12 + vmovups 112(%rsp), %xmm13 + vmovups 128(%rsp), %xmm14 + vmovups 144(%rsp), %xmm15 + add \$160, %rsp +___ +$code.=<<___; + + pop %r15 +.cfi_pop %r15 + pop %r14 +.cfi_pop %r14 + pop %r13 +.cfi_pop %r13 + pop %r12 +.cfi_pop %r12 + pop %rbx +.cfi_pop %rbx + pop %rbp +.cfi_pop %rbp + vzeroall + ret +.cfi_endproc +.size SHA3_shake256_x4_inc_absorb_avx512vl,.-SHA3_shake256_x4_inc_absorb_avx512vl + + +# SHA3_shake256_x4_inc_finalize_avx512vl +# Finalize absorption phase for 4 parallel SHAKE-256 states +# Adds padding and terminator bytes and clears the absorb offset +# Arguments: +# arg1 (rdi): pointer to state context (808 bytes) +# Returns: void +# Note: After this call, state is ready for squeezing output +.globl SHA3_shake256_x4_inc_finalize_avx512vl +.type SHA3_shake256_x4_inc_finalize_avx512vl,\@function,1 +.align 32 +SHA3_shake256_x4_inc_finalize_avx512vl: +.L_SHA3_shake256_x4_inc_finalize_avx512vl: +.cfi_startproc + mov 8*100($arg1), %r11 # load state offset from s[100] + mov %r11, %r10 + and \$~7, %r10d # offset to the state register + and \$7, %r11d # offset within the register + + # add EOM byte right after the message + vmovdqu32 ($arg1,%r10,4), %ymm31 + lea shake_msg_pad_x4(%rip), %r9 + sub %r11, %r9 + vmovdqu32 (%r9), %ymm30 + vpxorq %ymm30, %ymm31, %ymm31 + vmovdqu32 %ymm31, ($arg1,%r10,4) + + # add terminating byte at offset equal to rate - 1 (SHAKE256_RATE = 136) + vmovdqu32 512($arg1), %ymm31 # 136*4 - 32 = 544 - 32 = 512 + vmovdqa32 shake_terminator_byte_x4(%rip), %ymm30 + vpxorq %ymm30, %ymm31, %ymm31 + vmovdqu32 %ymm31, 512($arg1) + + movq \$0, 8*100($arg1) # clear s[100] + vpxorq %ymm31, %ymm31, %ymm31 + ret +.cfi_endproc +.size SHA3_shake256_x4_inc_finalize_avx512vl,.-SHA3_shake256_x4_inc_finalize_avx512vl + +___ + +$code .= <<___ if ($win64); +# Internal Win64 shim for squeeze entry. It establishes xlate-compatible +# unwind state and then jumps to the function entry after the prologue. +# This is required for internal calls since the xlate ABI conversion +# is already done in the caller function. +.type SHA3_shake256_x4_inc_squeeze_avx512vl_internal,\@abi-omnipotent +.align 32 +.LSEH_begin_SHA3_shake256_x4_inc_squeeze_avx512vl_internal: +SHA3_shake256_x4_inc_squeeze_avx512vl_internal: + mov %rsp, %rax + mov $arg1, 8(%rsp) + mov $arg2, 16(%rsp) + jmp .L_SHA3_shake256_x4_inc_squeeze_avx512vl +.LSEH_end_SHA3_shake256_x4_inc_squeeze_avx512vl_internal: +.size SHA3_shake256_x4_inc_squeeze_avx512vl_internal,.-SHA3_shake256_x4_inc_squeeze_avx512vl_internal +___ +$code.=<<___; + +# SHA3_shake256_x4_inc_squeeze_avx512vl +# Squeeze output from 4 parallel SHAKE256 states +# Arguments: +# arg1 (rdi): pointer to lane 0 output buffer +# arg2 (rsi): pointer to lane 1 output buffer +# arg3 (rdx): pointer to lane 2 output buffer +# arg4 (rcx): pointer to lane 3 output buffer +# arg5 (r8): output length in bytes (must be same for all lanes) +# arg6 (r9): pointer to state context (808 bytes) +# Returns: void +# Note: Can be called multiple times to generate arbitrary-length output +.globl SHA3_shake256_x4_inc_squeeze_avx512vl +.type SHA3_shake256_x4_inc_squeeze_avx512vl,\@function,6 +.align 32 +SHA3_shake256_x4_inc_squeeze_avx512vl: +.L_SHA3_shake256_x4_inc_squeeze_avx512vl: +.cfi_startproc + push %rbp +.cfi_push %rbp + push %rbx +.cfi_push %rbx + push %r12 +.cfi_push %r12 + push %r13 +.cfi_push %r13 + push %r14 +.cfi_push %r14 + push %r15 +.cfi_push %r15 +___ +$code .= <<___ if ($win64); + sub \$160, %rsp + vmovups %xmm6, 0(%rsp) + vmovups %xmm7, 16(%rsp) + vmovups %xmm8, 32(%rsp) + vmovups %xmm9, 48(%rsp) + vmovups %xmm10, 64(%rsp) + vmovups %xmm11, 80(%rsp) + vmovups %xmm12, 96(%rsp) + vmovups %xmm13, 112(%rsp) + vmovups %xmm14, 128(%rsp) + vmovups %xmm15, 144(%rsp) +___ +$code.=<<___; + +.Lshake256_squeeze_body: + or $arg5, $arg5 + jz .Lshake256_squeeze_done + + # check for partially processed block + mov 8*100($arg6), %r15 # s[100] - capacity + or %r15, %r15 + jnz .Lshake256_squeeze_no_init_permute + + mov $arg1, %r14 + mov $arg6, $arg1 + call keccak_1600_load_state_x4 + + mov %r14, $arg1 + + xor %rbp, %rbp + jmp .Lshake256_squeeze_loop + +.align 32 +.Lshake256_squeeze_no_init_permute: + # extract bytes: r10 - state/src, arg1-arg4 - output/dst, r12 - length = min(capacity, outlen), r11 - offset + mov $arg6, %r10 + mov $arg6, %r14 # preserve state pointer across extract helper + + mov %r15, %r12 + cmp %r15, $arg5 + cmovnae $arg5, %r12 # %r12 = min(capacity, outlen) + + sub %r12, $arg5 # outlen -= length + + mov \$136, %r11d # SHAKE256_RATE + sub %r15, %r11 # state offset + + sub %r12, %r15 # capacity -= length + mov %r15, 8*100($arg6) # update s[100] + + call keccak_1600_extract_bytes_x4 + mov %r14, $arg6 # restore state pointer after helper clobbers + + or %r15, %r15 + jnz .Lshake256_squeeze_done # check s[100] not zero + + mov $arg1, %r13 # preserve arg1 + mov %r14, $arg1 + call keccak_1600_load_state_x4 + + mov %r13, $arg1 + xor %rbp, %rbp + +.align 32 +.Lshake256_squeeze_loop: + cmp \$136, $arg5 # outlen > SHAKE256_RATE + jb .Lshake256_squeeze_final_extract + + call keccak_1600_permute + + # Extract SHAKE256 rate bytes (136 bytes = 17 x 8 bytes) inline +___ + +# Generate extract code for SHAKE256 rate (136 bytes = 17 ymm registers) +for (my $i = 0; $i < 17; $i++) { + my $offset = $i * 8; + $code.=<<___; + vextracti64x2 \$1, %ymm$i, %xmm31 + vmovq %xmm$i, $offset($arg1,%rbp) + vpextrq \$1, %xmm$i, $offset($arg2,%rbp) + vmovq %xmm31, $offset($arg3,%rbp) + vpextrq \$1, %xmm31, $offset($arg4,%rbp) +___ +} + +$code.=<<___; + add \$136, %rbp # dst offset += SHAKE256_RATE + sub \$136, $arg5 # outlen -= SHAKE256_RATE + jmp .Lshake256_squeeze_loop + +.align 32 +.Lshake256_squeeze_final_extract: + or $arg5, $arg5 + jz .Lshake256_squeeze_no_end_permute + + # update output pointers + add %rbp, $arg1 + add %rbp, $arg2 + add %rbp, $arg3 + add %rbp, $arg4 + + mov \$136, %r15d # SHAKE256_RATE + sub $arg5, %r15 + mov %r15, 8*100($arg6) # s[100] = capacity + + call keccak_1600_permute + + mov $arg1, %r14 + mov $arg6, $arg1 + call keccak_1600_save_state_x4 + + mov %r14, $arg1 + + # extract bytes: r10 - state/src, arg1-arg4 - output/dst, r12 - length, r11 - offset = 0 + mov $arg6, %r10 + mov $arg5, %r12 + xor %r11, %r11 + call keccak_1600_extract_bytes_x4 + + jmp .Lshake256_squeeze_done + +.Lshake256_squeeze_no_end_permute: + movq \$0, 8*100($arg6) # s[100] = 0 + mov $arg6, $arg1 + call keccak_1600_save_state_x4 + +.Lshake256_squeeze_done: + # Clear sensitive registers + vpxorq %xmm16, %xmm16, %xmm16 + vmovdqa64 %ymm16, %ymm17 + vmovdqa64 %ymm16, %ymm18 + vmovdqa64 %ymm16, %ymm19 + vmovdqa64 %ymm16, %ymm20 + vmovdqa64 %ymm16, %ymm21 + vmovdqa64 %ymm16, %ymm22 + vmovdqa64 %ymm16, %ymm23 + vmovdqa64 %ymm16, %ymm24 + vmovdqa64 %ymm16, %ymm25 + vmovdqa64 %ymm16, %ymm26 + vmovdqa64 %ymm16, %ymm27 + vmovdqa64 %ymm16, %ymm28 + vmovdqa64 %ymm16, %ymm29 + vmovdqa64 %ymm16, %ymm30 + vmovdqa64 %ymm16, %ymm31 +.Lshake256_squeeze_epilogue: + vzeroall +___ +$code .= <<___ if ($win64); + vmovups 0(%rsp), %xmm6 + vmovups 16(%rsp), %xmm7 + vmovups 32(%rsp), %xmm8 + vmovups 48(%rsp), %xmm9 + vmovups 64(%rsp), %xmm10 + vmovups 80(%rsp), %xmm11 + vmovups 96(%rsp), %xmm12 + vmovups 112(%rsp), %xmm13 + vmovups 128(%rsp), %xmm14 + vmovups 144(%rsp), %xmm15 + add \$160, %rsp +___ +$code.=<<___; + + pop %r15 +.cfi_pop %r15 + pop %r14 +.cfi_pop %r14 + pop %r13 +.cfi_pop %r13 + pop %r12 +.cfi_pop %r12 + pop %rbx +.cfi_pop %rbx + pop %rbp +.cfi_pop %rbp + ret +.cfi_endproc +.size SHA3_shake256_x4_inc_squeeze_avx512vl,.-SHA3_shake256_x4_inc_squeeze_avx512vl +___ + +if ($win64) { +my $context = "%r8"; +my $disp = "%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type keccak_se_handler,\@abi-omnipotent +.align 16 +keccak_se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64, %rsp + + mov 120($context), %rax # context->Rax = original %rsp from xlate prologue + mov 248($context), %rbx # context->Rip + + mov 8($disp), %rsi # disp->ImageBase + mov 56($disp), %r11 # disp->HandlerData + + mov 0(%r11), %r10d # HandlerData[0]: body label (rva) + lea (%rsi,%r10), %r10 + cmp %r10, %rbx # Rip < body? + jb .Lkeccak_in_prologue + + mov 4(%r11), %r10d # HandlerData[1]: epilogue label (rva) + lea (%rsi,%r10), %r10 + cmp %r10, %rbx # Rip >= epilogue? + jae .Lkeccak_in_epilogue + + # In function body: + # HandlerData[2]: delta from context->Rsp(body) to original %rsp + # HandlerData[3]: offset of XMM6 save area from context->Rsp(body), -1 if none + # HandlerData[4]: number of saved non-volatiles in stack frame layout (2 or 6) + # HandlerData[5]: delta from context->Rsp(epilogue) to original %rsp + mov 152($context), %rdx # body rsp + mov 8(%r11), %r10d + lea (%rdx,%r10), %rax # original rsp + jmp .Lkeccak_restore_body_or_epilogue + +.Lkeccak_in_epilogue: + mov 152($context), %rdx # epilogue rsp + mov 20(%r11), %r10d + lea (%rdx,%r10), %rax # original rsp + +.Lkeccak_restore_body_or_epilogue: + mov 8(%rax), %rcx # xlate shadow save of original rdi + mov 16(%rax), %rsi # xlate shadow save of original rsi + mov %rax, 152($context) # context->Rsp = original rsp + mov %rsi, 168($context) # context->Rsi + mov %rcx, 176($context) # context->Rdi + + mov 16(%r11), %r10d # gpr save count + cmp \$6, %r10d + jne .Lkeccak_restore_two + + mov -24(%rax), %r12 + mov -32(%rax), %r13 + mov -40(%rax), %r14 + mov -48(%rax), %r15 + mov %r12, 216($context) # context->R12 + mov %r13, 224($context) # context->R13 + mov %r14, 232($context) # context->R14 + mov %r15, 240($context) # context->R15 + +.Lkeccak_restore_two: + mov -8(%rax), %rbp + mov -16(%rax), %rbx + mov %rbp, 160($context) # context->Rbp + mov %rbx, 144($context) # context->Rbx + + mov 12(%r11), %r10d # xmm save offset from body rsp + cmp \$-1, %r10d + je .Lkeccak_in_prologue + + lea (%rdx,%r10), %rsi # source = xmm save area + lea 512($context), %rdi # &context->Xmm6 + mov \$20, %ecx # 10 XMM * 2 qwords + .long 0xa548f3fc # cld; rep movsq + +.Lkeccak_in_prologue: + mov 8(%rax), %rcx + mov 16(%rax), %rdx + mov %rcx, 176($context) # context->Rdi + mov %rdx, 168($context) # context->Rsi + mov %rax, 152($context) # context->Rsp = original rsp + + mov 40($disp), %rdi # disp->ContextRecord + mov $context, %rsi + mov \$154, %ecx # sizeof(CONTEXT)/8 + .long 0xa548f3fc # cld; rep movsq + + mov $disp, %rsi + xor %rcx, %rcx # UNW_FLAG_NHANDLER + mov 8(%rsi), %rdx # disp->ImageBase + mov 0(%rsi), %r8 # disp->ControlPc + mov 16(%rsi), %r9 # disp->FunctionEntry + mov 40(%rsi), %r10 # disp->ContextRecord + lea 56(%rsi), %r11 # &disp->HandlerData + lea 24(%rsi), %r12 # &disp->EstablisherFrame + mov %r10, 32(%rsp) + mov %r11, 40(%rsp) + mov %r12, 48(%rsp) + mov %rcx, 56(%rsp) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1, %eax # ExceptionContinueSearch + add \$64, %rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size keccak_se_handler,.-keccak_se_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_SHA3_shake128_x4_avx512vl + .rva .LSEH_end_SHA3_shake128_x4_avx512vl + .rva .LSEH_info_SHA3_shake128_x4_avx512vl + .rva .LSEH_begin_SHA3_shake128_x4_inc_absorb_avx512vl_internal + .rva .LSEH_end_SHA3_shake128_x4_inc_absorb_avx512vl_internal + .rva .LSEH_info_SHA3_shake128_x4_inc_absorb_avx512vl_internal + .rva .LSEH_begin_SHA3_shake128_x4_inc_absorb_avx512vl + .rva .LSEH_end_SHA3_shake128_x4_inc_absorb_avx512vl + .rva .LSEH_info_SHA3_shake128_x4_inc_absorb_avx512vl + .rva .LSEH_begin_SHA3_shake128_x4_inc_squeeze_avx512vl_internal + .rva .LSEH_end_SHA3_shake128_x4_inc_squeeze_avx512vl_internal + .rva .LSEH_info_SHA3_shake128_x4_inc_squeeze_avx512vl_internal + .rva .LSEH_begin_SHA3_shake128_x4_inc_squeeze_avx512vl + .rva .LSEH_end_SHA3_shake128_x4_inc_squeeze_avx512vl + .rva .LSEH_info_SHA3_shake128_x4_inc_squeeze_avx512vl + .rva .LSEH_begin_SHA3_shake256_x4_avx512vl + .rva .LSEH_end_SHA3_shake256_x4_avx512vl + .rva .LSEH_info_SHA3_shake256_x4_avx512vl + .rva .LSEH_begin_SHA3_shake256_x4_inc_absorb_avx512vl_internal + .rva .LSEH_end_SHA3_shake256_x4_inc_absorb_avx512vl_internal + .rva .LSEH_info_SHA3_shake256_x4_inc_absorb_avx512vl_internal + .rva .LSEH_begin_SHA3_shake256_x4_inc_absorb_avx512vl + .rva .LSEH_end_SHA3_shake256_x4_inc_absorb_avx512vl + .rva .LSEH_info_SHA3_shake256_x4_inc_absorb_avx512vl + .rva .LSEH_begin_SHA3_shake256_x4_inc_squeeze_avx512vl_internal + .rva .LSEH_end_SHA3_shake256_x4_inc_squeeze_avx512vl_internal + .rva .LSEH_info_SHA3_shake256_x4_inc_squeeze_avx512vl_internal + .rva .LSEH_begin_SHA3_shake256_x4_inc_squeeze_avx512vl + .rva .LSEH_end_SHA3_shake256_x4_inc_squeeze_avx512vl + .rva .LSEH_info_SHA3_shake256_x4_inc_squeeze_avx512vl + +.section .xdata +.align 8 +.LSEH_info_SHA3_shake128_x4_avx512vl: + .byte 9,0,0,0 + .rva keccak_se_handler + .rva .Lshake128_x4_body,.Lshake128_x4_epilogue + .long 1032,856,2,1032 +.LSEH_info_SHA3_shake128_x4_inc_absorb_avx512vl: + .byte 9,0,0,0 + .rva keccak_se_handler + .rva .Lshake128_absorb_body,.Lshake128_absorb_epilogue + .long 208,0,6,208 +.LSEH_info_SHA3_shake128_x4_inc_absorb_avx512vl_internal: + .byte 9,0,0,0 + .rva keccak_se_handler + .rva .Lshake128_absorb_body,.Lshake128_absorb_epilogue + .long 208,0,6,208 +.LSEH_info_SHA3_shake128_x4_inc_squeeze_avx512vl: + .byte 9,0,0,0 + .rva keccak_se_handler + .rva .Lshake128_squeeze_body,.Lshake128_squeeze_epilogue + .long 208,0,6,208 +.LSEH_info_SHA3_shake128_x4_inc_squeeze_avx512vl_internal: + .byte 9,0,0,0 + .rva keccak_se_handler + .rva .Lshake128_squeeze_body,.Lshake128_squeeze_epilogue + .long 208,0,6,208 +.LSEH_info_SHA3_shake256_x4_avx512vl: + .byte 9,0,0,0 + .rva keccak_se_handler + .rva .Lshake256_x4_body,.Lshake256_x4_epilogue + .long 1032,856,2,1032 +.LSEH_info_SHA3_shake256_x4_inc_absorb_avx512vl: + .byte 9,0,0,0 + .rva keccak_se_handler + .rva .Lshake256_absorb_body,.Lshake256_absorb_epilogue + .long 208,0,6,208 +.LSEH_info_SHA3_shake256_x4_inc_absorb_avx512vl_internal: + .byte 9,0,0,0 + .rva keccak_se_handler + .rva .Lshake256_absorb_body,.Lshake256_absorb_epilogue + .long 208,0,6,208 +.LSEH_info_SHA3_shake256_x4_inc_squeeze_avx512vl: + .byte 9,0,0,0 + .rva keccak_se_handler + .rva .Lshake256_squeeze_body,.Lshake256_squeeze_epilogue + .long 208,0,6,208 +.LSEH_info_SHA3_shake256_x4_inc_squeeze_avx512vl_internal: + .byte 9,0,0,0 + .rva keccak_se_handler + .rva .Lshake256_squeeze_body,.Lshake256_squeeze_epilogue + .long 208,0,6,208 +___ +} + +$code.=<<___; + +.section .rodata align=128 +.align 128 +.type iotas,\@object +iotas: + .quad 0x0000000000000001 + .quad 0x0000000000008082 + .quad 0x800000000000808a + .quad 0x8000000080008000 + .quad 0x000000000000808b + .quad 0x0000000080000001 + .quad 0x8000000080008081 + .quad 0x8000000000008009 + .quad 0x000000000000008a + .quad 0x0000000000000088 + .quad 0x0000000080008009 + .quad 0x000000008000000a + .quad 0x000000008000808b + .quad 0x800000000000008b + .quad 0x8000000000008089 + .quad 0x8000000000008003 + .quad 0x8000000000008002 + .quad 0x8000000000000080 + .quad 0x000000000000800a + .quad 0x800000008000000a + .quad 0x8000000080008081 + .quad 0x8000000000008080 + .quad 0x0000000080000001 + .quad 0x8000000080008008 +.size iotas,.-iotas + +.align 8 +byte_kmask_0_to_7: + .byte 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f + +.align 32 +shake_terminator_byte_x4: + .byte 0, 0, 0, 0, 0, 0, 0, 0x80 + .byte 0, 0, 0, 0, 0, 0, 0, 0x80 + .byte 0, 0, 0, 0, 0, 0, 0, 0x80 + .byte 0, 0, 0, 0, 0, 0, 0, 0x80 + +.align 8 + .byte 0, 0, 0, 0, 0, 0, 0, 0 +shake_msg_pad_x4: + .byte 0x1F, 0, 0, 0, 0, 0, 0, 0 + .byte 0x1F, 0, 0, 0, 0, 0, 0, 0 + .byte 0x1F, 0, 0, 0, 0, 0, 0, 0 + .byte 0x1F, 0, 0, 0, 0, 0, 0, 0 + +.asciz "Keccak-1600 absorb and squeeze for AVX512VL, CRYPTOGAMS by " +___ + +}}} else {{{ + +# When AVX512VL is not available, output stub functions +# The capable function returns 0, and the operation functions are not defined (will use C fallback) + +$code .= <<___; +.text + +.globl SHA3_avx512vl_capable +.type SHA3_avx512vl_capable,\@abi-omnipotent +SHA3_avx512vl_capable: + xor %eax, %eax + ret +.size SHA3_avx512vl_capable, .-SHA3_avx512vl_capable + +.globl SHA3_shake128_x4_inc_absorb_avx512vl +.globl SHA3_shake256_x4_inc_absorb_avx512vl +.globl SHA3_shake128_x4_inc_finalize_avx512vl +.globl SHA3_shake256_x4_inc_finalize_avx512vl +.globl SHA3_shake128_x4_inc_squeeze_avx512vl +.globl SHA3_shake256_x4_inc_squeeze_avx512vl +.globl SHA3_shake128_x4_avx512vl +.globl SHA3_shake256_x4_avx512vl +.type SHA3_shake128_x4_inc_absorb_avx512vl,\@abi-omnipotent +SHA3_shake128_x4_inc_absorb_avx512vl: +SHA3_shake256_x4_inc_absorb_avx512vl: +SHA3_shake128_x4_inc_finalize_avx512vl: +SHA3_shake256_x4_inc_finalize_avx512vl: +SHA3_shake128_x4_inc_squeeze_avx512vl: +SHA3_shake256_x4_inc_squeeze_avx512vl: +SHA3_shake128_x4_avx512vl: +SHA3_shake256_x4_avx512vl: + .byte 0x0f,0x0b # ud2 + ret +.size SHA3_shake128_x4_inc_absorb_avx512vl, .-SHA3_shake128_x4_inc_absorb_avx512vl +___ +}}} + +print $code; +close STDOUT or die "error closing STDOUT: $!"; diff --git a/crypto/sha/build.info b/crypto/sha/build.info index 457ac8d06ab7b..fd192a66dda4c 100644 --- a/crypto/sha/build.info +++ b/crypto/sha/build.info @@ -65,7 +65,7 @@ ENDIF $KECCAK1600ASM=keccak1600.c IF[{- !$disabled{asm} -}] $KECCAK1600ASM_x86= - $KECCAK1600ASM_x86_64=keccak1600-x86_64.s + $KECCAK1600ASM_x86_64=keccak1600-x86_64.s keccak1600x4-avx512vl.s $KECCAK1600ASM_s390x=keccak1600-s390x.S @@ -83,8 +83,8 @@ IF[{- !$disabled{asm} -}] ENDIF $COMMON=sha1dgst.c sha256.c sha512.c sha3.c sha3_encode.c $SHA1ASM $KECCAK1600ASM -SOURCE[../../libcrypto]=$COMMON sha1_one.c -SOURCE[../../providers/libfips.a]= $COMMON +SOURCE[../../libcrypto]=$COMMON sha1_one.c sha3_x4.c +SOURCE[../../providers/libfips.a]= $COMMON sha3_x4.c # Implementations are now spread across several libraries, so the defines # need to be applied to all affected libraries and modules. @@ -198,4 +198,8 @@ GENERATE[keccak1600-avx512vl.S]=asm/keccak1600-avx512vl.pl GENERATE[keccak1600-mmx.S]=asm/keccak1600-mmx.pl GENERATE[keccak1600p8-ppc.S]=asm/keccak1600p8-ppc.pl +# keccak1600x4-avx512vl.s supports multi-squeeze +# Currently only used in ML-DSA on x86_64 with AVX-512VL support +GENERATE[keccak1600x4-avx512vl.s]=asm/keccak1600x4-avx512vl.pl + GENERATE[sha1-thumb.S]=asm/sha1-thumb.pl diff --git a/crypto/sha/sha3_x4.c b/crypto/sha/sha3_x4.c new file mode 100644 index 0000000000000..1d993c326c0a5 --- /dev/null +++ b/crypto/sha/sha3_x4.c @@ -0,0 +1,202 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2026 Intel Corporation. All Rights Reserved. + * + * Licensed under 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 + */ + +/* + * SHAKE x4 multi-buffer implementation for AVX-512VL + * + * This file provides incremental API wrappers around the AVX-512VL + * assembly implementations for processing 4 SHAKE instances in parallel. + * + * Callers should check SHA3_avx512vl_capable() before calling. + */ + +#include "internal/sha3.h" +#include + +#if defined(KECCAK1600_ASM) \ + && (defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)) \ + && !defined(OPENSSL_NO_ASM) + +/* External assembly function declarations */ +extern void SHA3_shake128_x4_inc_absorb_avx512vl( + uint64_t *state, + const void *in0, const void *in1, + const void *in2, const void *in3, + size_t inlen); + +extern void SHA3_shake256_x4_inc_absorb_avx512vl( + uint64_t *state, + const void *in0, const void *in1, + const void *in2, const void *in3, + size_t inlen); + +extern void SHA3_shake128_x4_inc_finalize_avx512vl(uint64_t *state); +extern void SHA3_shake256_x4_inc_finalize_avx512vl(uint64_t *state); + +extern void SHA3_shake128_x4_inc_squeeze_avx512vl( + void *out0, void *out1, + void *out2, void *out3, + size_t outlen, + uint64_t *state); + +extern void SHA3_shake256_x4_inc_squeeze_avx512vl( + void *out0, void *out1, + void *out2, void *out3, + size_t outlen, + uint64_t *state); + +/* One-shot assembly function declarations */ +extern void SHA3_shake128_x4_avx512vl( + void *out0, void *out1, + void *out2, void *out3, + size_t outlen, + const void *in0, const void *in1, + const void *in2, const void *in3, + size_t inlen); + +extern void SHA3_shake256_x4_avx512vl( + void *out0, void *out1, + void *out2, void *out3, + size_t outlen, + const void *in0, const void *in1, + const void *in2, const void *in3, + size_t inlen); + +/* + * SHAKE-128 x4 Implementation + */ + +void ossl_sha3_shake128_x4_inc_init(KECCAK1600_X4_CTX *ctx) +{ + memset(ctx->A, 0, sizeof(ctx->A)); + ctx->rate = 168; /* SHAKE-128 rate in bytes */ + ctx->finalized = 0; +} + +void ossl_sha3_shake128_x4_inc_absorb( + KECCAK1600_X4_CTX *ctx, + const void *in0, const void *in1, + const void *in2, const void *in3, + size_t inlen) +{ + if (ctx->finalized) { + /* Error: cannot absorb after finalize */ + return; + } + + SHA3_shake128_x4_inc_absorb_avx512vl( + ctx->A, in0, in1, in2, in3, inlen); +} + +void ossl_sha3_shake128_x4_inc_finalize(KECCAK1600_X4_CTX *ctx) +{ + if (ctx->finalized) { + return; /* Already finalized */ + } + + SHA3_shake128_x4_inc_finalize_avx512vl(ctx->A); + ctx->finalized = 1; +} + +void ossl_sha3_shake128_x4_inc_squeeze( + void *out0, void *out1, + void *out2, void *out3, + size_t outlen, + KECCAK1600_X4_CTX *ctx) +{ + if (!ctx->finalized) { + /* Auto-finalize on first squeeze */ + ossl_sha3_shake128_x4_inc_finalize(ctx); + } + + SHA3_shake128_x4_inc_squeeze_avx512vl( + out0, out1, out2, out3, outlen, ctx->A); +} + +/* + * SHAKE-256 x4 Implementation + */ + +void ossl_sha3_shake256_x4_inc_init(KECCAK1600_X4_CTX *ctx) +{ + memset(ctx->A, 0, sizeof(ctx->A)); + ctx->rate = 136; /* SHAKE-256 rate in bytes */ + ctx->finalized = 0; +} + +void ossl_sha3_shake256_x4_inc_absorb( + KECCAK1600_X4_CTX *ctx, + const void *in0, const void *in1, + const void *in2, const void *in3, + size_t inlen) +{ + if (ctx->finalized) { + /* Error: cannot absorb after finalize */ + return; + } + + SHA3_shake256_x4_inc_absorb_avx512vl( + ctx->A, in0, in1, in2, in3, inlen); +} + +void ossl_sha3_shake256_x4_inc_finalize(KECCAK1600_X4_CTX *ctx) +{ + if (ctx->finalized) { + return; /* Already finalized */ + } + + SHA3_shake256_x4_inc_finalize_avx512vl(ctx->A); + ctx->finalized = 1; +} + +void ossl_sha3_shake256_x4_inc_squeeze( + void *out0, void *out1, + void *out2, void *out3, + size_t outlen, + KECCAK1600_X4_CTX *ctx) +{ + if (!ctx->finalized) { + /* Auto-finalize on first squeeze */ + ossl_sha3_shake256_x4_inc_finalize(ctx); + } + + SHA3_shake256_x4_inc_squeeze_avx512vl( + out0, out1, out2, out3, outlen, ctx->A); +} + +/* + * Single-call wrapper APIs + */ + +void ossl_sha3_shake128_x4( + void *out0, void *out1, + void *out2, void *out3, + size_t outlen, + const void *in0, const void *in1, + const void *in2, const void *in3, + size_t inlen) +{ + SHA3_shake128_x4_avx512vl(out0, out1, out2, out3, outlen, + in0, in1, in2, in3, inlen); +} + +void ossl_sha3_shake256_x4( + void *out0, void *out1, + void *out2, void *out3, + size_t outlen, + const void *in0, const void *in1, + const void *in2, const void *in3, + size_t inlen) +{ + SHA3_shake256_x4_avx512vl(out0, out1, out2, out3, outlen, + in0, in1, in2, in3, inlen); +} + +#endif /* KECCAK1600_ASM && x86_64 && !OPENSSL_NO_ASM */ diff --git a/include/internal/sha3.h b/include/internal/sha3.h index f91d00a74f838..82a7ec158b1a7 100644 --- a/include/internal/sha3.h +++ b/include/internal/sha3.h @@ -65,4 +65,75 @@ int ossl_shake_squeeze_default(KECCAK1600_CTX *ctx, unsigned char *out, size_t o size_t SHA3_absorb(uint64_t A[5][5], const unsigned char *inp, size_t len, size_t r); +/* Multi-buffer (x4) Keccak-f[1600] context and API */ +#if defined(KECCAK1600_ASM) \ + && (defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)) \ + && !defined(OPENSSL_NO_ASM) + +/* Runtime capability check for AVX512VL */ +int SHA3_avx512vl_capable(void); + +/* Context for 4-way parallel SHAKE operations */ +typedef struct { + /* 4 interleaved Keccak states (800 bytes) + plus 8 bytes to store the number of + already absorbed or not yet squeezed bytes */ + uint64_t A[(25 * 4) + 1]; + size_t rate; /* Rate in bytes: 168 (SHAKE-128) or 136 (SHAKE-256) */ + unsigned finalized; /* Has finalize been called? 0=no, 1=yes */ +} KECCAK1600_X4_CTX; + +/* SHAKE-128 x4 incremental API */ +void ossl_sha3_shake128_x4_inc_init(KECCAK1600_X4_CTX *ctx); + +void ossl_sha3_shake128_x4_inc_absorb( + KECCAK1600_X4_CTX *ctx, + const void *in0, const void *in1, + const void *in2, const void *in3, + size_t inlen); + +void ossl_sha3_shake128_x4_inc_finalize(KECCAK1600_X4_CTX *ctx); + +void ossl_sha3_shake128_x4_inc_squeeze( + void *out0, void *out1, + void *out2, void *out3, + size_t outlen, + KECCAK1600_X4_CTX *ctx); + +/* SHAKE-256 x4 incremental API */ +void ossl_sha3_shake256_x4_inc_init(KECCAK1600_X4_CTX *ctx); + +void ossl_sha3_shake256_x4_inc_absorb( + KECCAK1600_X4_CTX *ctx, + const void *in0, const void *in1, + const void *in2, const void *in3, + size_t inlen); + +void ossl_sha3_shake256_x4_inc_finalize(KECCAK1600_X4_CTX *ctx); + +void ossl_sha3_shake256_x4_inc_squeeze( + void *out0, void *out1, + void *out2, void *out3, + size_t outlen, + KECCAK1600_X4_CTX *ctx); + +/* Single-call SHAKE x4 APIs (wrapper functions) */ +void ossl_sha3_shake128_x4( + void *out0, void *out1, + void *out2, void *out3, + size_t outlen, + const void *in0, const void *in1, + const void *in2, const void *in3, + size_t inlen); + +void ossl_sha3_shake256_x4( + void *out0, void *out1, + void *out2, void *out3, + size_t outlen, + const void *in0, const void *in1, + const void *in2, const void *in3, + size_t inlen); + +#endif /* KECCAK1600_ASM && x86_64 && !OPENSSL_NO_ASM */ + #endif /* OSSL_INTERNAL_SHA3_H */ diff --git a/test/build.info b/test/build.info index f599b3aff8c61..d6a36ba9ba035 100644 --- a/test/build.info +++ b/test/build.info @@ -915,6 +915,8 @@ IF[{- !$disabled{tests} -}] PROGRAMS{noinst}=cmactest ENDIF + PROGRAMS{noinst}=sha3_x4_internal_test + SOURCE[poly1305_internal_test]=poly1305_internal_test.c INCLUDE[poly1305_internal_test]=.. ../include ../apps/include DEPEND[poly1305_internal_test]=../libcrypto.a libtestutil.a @@ -923,6 +925,10 @@ IF[{- !$disabled{tests} -}] INCLUDE[chacha_internal_test]=.. ../include ../apps/include DEPEND[chacha_internal_test]=../libcrypto.a libtestutil.a + SOURCE[sha3_x4_internal_test]=sha3_x4_internal_test.c + INCLUDE[sha3_x4_internal_test]=.. ../include ../apps/include + DEPEND[sha3_x4_internal_test]=../libcrypto.a libtestutil.a + SOURCE[asn1_internal_test]=asn1_internal_test.c INCLUDE[asn1_internal_test]=.. ../include ../apps/include DEPEND[asn1_internal_test]=../libcrypto.a libtestutil.a diff --git a/test/recipes/03-test_sha3_x4_internal.t b/test/recipes/03-test_sha3_x4_internal.t new file mode 100644 index 0000000000000..9e5793aaf3cd3 --- /dev/null +++ b/test/recipes/03-test_sha3_x4_internal.t @@ -0,0 +1,16 @@ +#! /usr/bin/env perl +# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. +# Copyright (c) 2026 Intel Corporation. All Rights Reserved. +# +# Licensed under 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 OpenSSL::Test; +use OpenSSL::Test::Simple; + +setup("test_sha3_x4_internal"); + +simple_test("test_sha3_x4_internal", "sha3_x4_internal_test"); diff --git a/test/sha3_x4_internal_test.c b/test/sha3_x4_internal_test.c new file mode 100644 index 0000000000000..e387b6f51ae46 --- /dev/null +++ b/test/sha3_x4_internal_test.c @@ -0,0 +1,432 @@ +/* + * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2026 Intel Corporation. All Rights Reserved. + * + * Licensed under 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 + */ + +/* + * Internal cross-validation tests for the SHAKE x4 multi-buffer API. + * + * Each test computes SHAKE-128 or SHAKE-256 on four independent inputs + * using the x4 (AVX-512VL) path and compares every lane's output to the + * equivalent result produced by the scalar ossl_sha3_* API. + * + * Tests cover: + * - Single-call (ossl_sha3_shake{128,256}_x4) for many (inlen, outlen) pairs + * - Incremental init/absorb/squeeze for the same (inlen, outlen) pairs + * - Multi-absorb: input split at every possible block boundary + * - Multi-squeeze: output produced in two successive squeeze calls + */ + +#include +#include "testutil.h" + +/* + * KECCAK1600_ASM is only added to the library compilation flags by the build + * system, not to test binaries. Since the x4 declarations in internal/sha3.h + * are guarded by that macro, we define it here before the include so that the + * KECCAK1600_X4_CTX type and function prototypes are visible. The symbols + * themselves live in libcrypto.a which is always compiled with the flag set. + * We additionally gate all x4 code on x86_64 (GCC/Clang: __x86_64__, + * MSVC: _M_AMD64/_M_X64) and !OPENSSL_NO_ASM so that the test still + * compiles on other platforms or in no-asm builds. + */ +#if (defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)) \ + && !defined(OPENSSL_NO_ASM) +#ifndef KECCAK1600_ASM +#define KECCAK1600_ASM +#endif +#endif +#include "internal/sha3.h" + +/* + * A single deterministic 1024-byte message. Each of the four lanes receives + * a different slice of this buffer, with lane base pointers spaced 64 bytes + * apart, so their inputs are distinct yet entirely self-contained. + */ +#define MSG_BUF_SIZE 1024 +#define LANE_STRIDE 64 /* byte offset between lane base pointers */ +#define NUM_LANES 4 + +static unsigned char msg[MSG_BUF_SIZE]; + +/* Maximum output length used in this file – must fit chunk1 + chunk2. */ +#define MAX_OUT 640 + +#if defined(KECCAK1600_ASM) \ + && (defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)) \ + && !defined(OPENSSL_NO_ASM) + +/* + * Input lengths exercising: empty, tiny, sub-block, block boundary ±1, + * multiple blocks and a longer message for SHAKE-128 (rate=168) and + * SHAKE-256 (rate=136). + */ +static const size_t input_sizes[] = { + 0, 1, 17, 100, 135, 136, 137, 168, 169, 200, 400 +}; +#define NUM_INPUT_SIZES (sizeof(input_sizes) / sizeof(input_sizes[0])) + +/* Output lengths chosen to straddle rate boundaries for both variants. */ +static const size_t output_sizes[] = { + 16, 32, 64, 136, 168, 256, 512 +}; +#define NUM_OUTPUT_SIZES (sizeof(output_sizes) / sizeof(output_sizes[0])) + +/* Helpers functions */ + +/* + * Compute a scalar SHAKE-128 or SHAKE-256 digest. + * bitlen: 128 or 256. Returns 1 on success, 0 on failure. + */ +static int scalar_shake(const unsigned int bitlen, + const unsigned char *in, const size_t inlen, + unsigned char *out, const size_t outlen) +{ + KECCAK1600_CTX ctx; + + if (!ossl_sha3_init(&ctx, 0x1f, bitlen)) + return 0; + /* ossl_sha3_init does not populate the method vtable; do it here. */ + ctx.meth.absorb = ossl_sha3_absorb_default; + ctx.meth.final = ossl_sha3_final_default; + ctx.meth.squeeze = ossl_shake_squeeze_default; + return ossl_sha3_absorb(&ctx, in, inlen) + && ossl_sha3_squeeze(&ctx, out, outlen); +} + +/* + * Encode (inlen_idx, outlen_idx) into a single test index and back. + * test index n = inlen_idx * NUM_OUTPUT_SIZES + outlen_idx + */ +static void decode_idx(const int n, size_t *inlen, size_t *outlen) +{ + *inlen = input_sizes[n / (int)NUM_OUTPUT_SIZES]; + *outlen = output_sizes[n % (int)NUM_OUTPUT_SIZES]; +} + +/* One-shot tests */ + +static int test_shake_x4_oneshot(const unsigned int bitlen, const int n) +{ + size_t inlen, outlen; + const unsigned char *in[NUM_LANES]; + unsigned char x4_out[NUM_LANES][MAX_OUT]; + unsigned char ref_out[NUM_LANES][MAX_OUT]; + int i; + + decode_idx(n, &inlen, &outlen); + + for (i = 0; i < NUM_LANES; i++) + in[i] = msg + i * LANE_STRIDE; + + /* Ensure the lane inputs fit within the message buffer. */ + if (!TEST_size_t_le(inlen + (NUM_LANES - 1) * LANE_STRIDE, MSG_BUF_SIZE)) + return 0; + if (!TEST_size_t_le(outlen, MAX_OUT)) + return 0; + + /* x4 single-call */ + if (bitlen == 128) + ossl_sha3_shake128_x4(x4_out[0], x4_out[1], x4_out[2], x4_out[3], + outlen, + in[0], in[1], in[2], in[3], inlen); + else + ossl_sha3_shake256_x4(x4_out[0], x4_out[1], x4_out[2], x4_out[3], + outlen, + in[0], in[1], in[2], in[3], inlen); + + /* scalar reference */ + for (i = 0; i < NUM_LANES; i++) + if (!TEST_true(scalar_shake(bitlen, in[i], inlen, ref_out[i], outlen))) + return 0; + + /* compare */ + for (i = 0; i < NUM_LANES; i++) { + if (!TEST_mem_eq(x4_out[i], outlen, ref_out[i], outlen)) { + TEST_info("SHAKE-%u x4 oneshot lane %d: inlen=%zu outlen=%zu", + bitlen, i, inlen, outlen); + return 0; + } + } + return 1; +} + +static int test_shake128_x4_oneshot(const int n) +{ + return test_shake_x4_oneshot(128, n); +} + +static int test_shake256_x4_oneshot(const int n) +{ + return test_shake_x4_oneshot(256, n); +} + +/* Incremental (init / absorb / finalize / squeeze) tests */ + +static int test_shake_x4_incremental(const unsigned int bitlen, const int n) +{ + size_t inlen, outlen; + const unsigned char *in[NUM_LANES]; + unsigned char x4_out[NUM_LANES][MAX_OUT]; + unsigned char ref_out[NUM_LANES][MAX_OUT]; + KECCAK1600_X4_CTX ctx; + int i; + + decode_idx(n, &inlen, &outlen); + + for (i = 0; i < NUM_LANES; i++) + in[i] = msg + i * LANE_STRIDE; + + if (!TEST_size_t_le(inlen + (NUM_LANES - 1) * LANE_STRIDE, MSG_BUF_SIZE)) + return 0; + + /* x4 incremental */ + if (bitlen == 128) { + ossl_sha3_shake128_x4_inc_init(&ctx); + ossl_sha3_shake128_x4_inc_absorb(&ctx, in[0], in[1], in[2], in[3], + inlen); + ossl_sha3_shake128_x4_inc_finalize(&ctx); + ossl_sha3_shake128_x4_inc_squeeze(x4_out[0], x4_out[1], + x4_out[2], x4_out[3], outlen, &ctx); + } else { + ossl_sha3_shake256_x4_inc_init(&ctx); + ossl_sha3_shake256_x4_inc_absorb(&ctx, in[0], in[1], in[2], in[3], + inlen); + ossl_sha3_shake256_x4_inc_finalize(&ctx); + ossl_sha3_shake256_x4_inc_squeeze(x4_out[0], x4_out[1], + x4_out[2], x4_out[3], outlen, &ctx); + } + + /* scalar reference */ + for (i = 0; i < NUM_LANES; i++) + if (!TEST_true(scalar_shake(bitlen, in[i], inlen, ref_out[i], outlen))) + return 0; + + for (i = 0; i < NUM_LANES; i++) { + if (!TEST_mem_eq(x4_out[i], outlen, ref_out[i], outlen)) { + TEST_info("SHAKE-%u x4 incremental lane %d: inlen=%zu outlen=%zu", + bitlen, i, inlen, outlen); + return 0; + } + } + return 1; +} + +static int test_shake128_x4_incremental(const int n) +{ + return test_shake_x4_incremental(128, n); +} + +static int test_shake256_x4_incremental(const int n) +{ + return test_shake_x4_incremental(256, n); +} + +/* Multi-absorb tests */ + +/* + * Split the input at every tested input size, absorbing the two halves + * in separate calls. The split length is chosen as input_sizes[n] so that + * we exercise sub-block, at-block and multi-block split points. + * + * Full message length is fixed at the largest tested input size so that + * every split index is meaningful. + */ +static int test_shake_x4_multi_absorb(const unsigned int bitlen, const int n) +{ + const size_t total = input_sizes[NUM_INPUT_SIZES - 1]; + const size_t split = input_sizes[n]; + const size_t outlen = 64; /* fixed output length for this sub-test */ + const unsigned char *in[NUM_LANES]; + unsigned char x4_out[NUM_LANES][MAX_OUT]; + unsigned char ref_out[NUM_LANES][MAX_OUT]; + KECCAK1600_X4_CTX ctx; + int i; + + if (split > total) + return 1; /* nothing to test */ + + for (i = 0; i < NUM_LANES; i++) + in[i] = msg + i * LANE_STRIDE; + + if (!TEST_size_t_le(total + (NUM_LANES - 1) * LANE_STRIDE, MSG_BUF_SIZE)) + return 0; + + /* x4 split absorb */ + if (bitlen == 128) { + ossl_sha3_shake128_x4_inc_init(&ctx); + ossl_sha3_shake128_x4_inc_absorb(&ctx, + in[0], in[1], in[2], in[3], split); + ossl_sha3_shake128_x4_inc_absorb(&ctx, + in[0] + split, in[1] + split, in[2] + split, in[3] + split, + total - split); + ossl_sha3_shake128_x4_inc_squeeze(x4_out[0], x4_out[1], + x4_out[2], x4_out[3], outlen, &ctx); + } else { + ossl_sha3_shake256_x4_inc_init(&ctx); + ossl_sha3_shake256_x4_inc_absorb(&ctx, + in[0], in[1], in[2], in[3], split); + ossl_sha3_shake256_x4_inc_absorb(&ctx, + in[0] + split, in[1] + split, in[2] + split, in[3] + split, + total - split); + ossl_sha3_shake256_x4_inc_squeeze(x4_out[0], x4_out[1], + x4_out[2], x4_out[3], outlen, &ctx); + } + + /* scalar reference (single absorb of full message) */ + for (i = 0; i < NUM_LANES; i++) + if (!TEST_true(scalar_shake(bitlen, in[i], total, ref_out[i], outlen))) + return 0; + + for (i = 0; i < NUM_LANES; i++) { + if (!TEST_mem_eq(x4_out[i], outlen, ref_out[i], outlen)) { + TEST_info("SHAKE-%u x4 multi-absorb lane %d: total=%zu split=%zu", + bitlen, i, total, split); + return 0; + } + } + return 1; +} + +static int test_shake128_x4_multi_absorb(const int n) +{ + return test_shake_x4_multi_absorb(128, n); +} + +static int test_shake256_x4_multi_absorb(const int n) +{ + return test_shake_x4_multi_absorb(256, n); +} + +/* Multi-squeeze tests */ + +/* + * Squeeze in two successive calls and verify that the concatenated output + * matches a single scalar squeeze of the same total length. + * Parameterized over output_sizes[] for the first chunk; the second chunk + * is always 64 bytes so the total length varies. + */ +static int test_shake_x4_multi_squeeze(const unsigned int bitlen, const int n) +{ + const size_t inlen = 200; /* fixed input length */ + const size_t chunk1 = output_sizes[n]; + const size_t chunk2 = 64; + const size_t total = chunk1 + chunk2; + const unsigned char *in[NUM_LANES]; + unsigned char x4_a[NUM_LANES][MAX_OUT]; /* first chunk */ + unsigned char x4_b[NUM_LANES][MAX_OUT]; /* second chunk */ + unsigned char ref_out[NUM_LANES][MAX_OUT]; + KECCAK1600_X4_CTX ctx; + int i; + + if (!TEST_size_t_le(total, MAX_OUT)) + return 0; + if (!TEST_size_t_le(inlen + (NUM_LANES - 1) * LANE_STRIDE, MSG_BUF_SIZE)) + return 0; + + for (i = 0; i < NUM_LANES; i++) + in[i] = msg + i * LANE_STRIDE; + + /* x4 two-shot squeeze */ + if (bitlen == 128) { + ossl_sha3_shake128_x4_inc_init(&ctx); + ossl_sha3_shake128_x4_inc_absorb(&ctx, in[0], in[1], in[2], in[3], + inlen); + /* first squeeze */ + ossl_sha3_shake128_x4_inc_squeeze(x4_a[0], x4_a[1], x4_a[2], x4_a[3], + chunk1, &ctx); + /* second squeeze – context carries state from previous call */ + ossl_sha3_shake128_x4_inc_squeeze(x4_b[0], x4_b[1], x4_b[2], x4_b[3], + chunk2, &ctx); + } else { + ossl_sha3_shake256_x4_inc_init(&ctx); + ossl_sha3_shake256_x4_inc_absorb(&ctx, in[0], in[1], in[2], in[3], + inlen); + ossl_sha3_shake256_x4_inc_squeeze(x4_a[0], x4_a[1], x4_a[2], x4_a[3], + chunk1, &ctx); + ossl_sha3_shake256_x4_inc_squeeze(x4_b[0], x4_b[1], x4_b[2], x4_b[3], + chunk2, &ctx); + } + + /* scalar reference – squeeze the full total in one call */ + for (i = 0; i < NUM_LANES; i++) + if (!TEST_true(scalar_shake(bitlen, in[i], inlen, ref_out[i], total))) + return 0; + + /* check first chunk, then second chunk */ + for (i = 0; i < NUM_LANES; i++) { + if (!TEST_mem_eq(x4_a[i], chunk1, ref_out[i], chunk1)) { + TEST_info("SHAKE-%u x4 multi-squeeze lane %d chunk1: " + "inlen=%zu chunk1=%zu chunk2=%zu", + bitlen, i, inlen, chunk1, chunk2); + return 0; + } + if (!TEST_mem_eq(x4_b[i], chunk2, ref_out[i] + chunk1, chunk2)) { + TEST_info("SHAKE-%u x4 multi-squeeze lane %d chunk2: " + "inlen=%zu chunk1=%zu chunk2=%zu", + bitlen, i, inlen, chunk1, chunk2); + return 0; + } + } + return 1; +} + +static int test_shake128_x4_multi_squeeze(const int n) +{ + return test_shake_x4_multi_squeeze(128, n); +} + +static int test_shake256_x4_multi_squeeze(const int n) +{ + return test_shake_x4_multi_squeeze(256, n); +} + +#endif /* KECCAK1600_ASM && x86_64 && !OPENSSL_NO_ASM */ + +/* Test entry point */ + +int setup_tests(void) +{ + size_t i; + + /* Fill the message buffer with a deterministic non-zero pattern. */ + for (i = 0; i < MSG_BUF_SIZE; i++) + msg[i] = (unsigned char)(251 * i + 17); + +#ifdef OPENSSL_CPUID_OBJ + OPENSSL_cpuid_setup(); +#endif + +#if !defined(KECCAK1600_ASM) \ + || !(defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)) \ + || defined(OPENSSL_NO_ASM) + return TEST_skip("SHAKE x4 API not available in this build"); +#else + if (!SHA3_avx512vl_capable()) { + return TEST_skip("AVX-512VL not available; skipping SHAKE x4 tests"); + } + + ADD_ALL_TESTS(test_shake128_x4_oneshot, + (int)(NUM_INPUT_SIZES * NUM_OUTPUT_SIZES)); + ADD_ALL_TESTS(test_shake256_x4_oneshot, + (int)(NUM_INPUT_SIZES * NUM_OUTPUT_SIZES)); + + ADD_ALL_TESTS(test_shake128_x4_incremental, + (int)(NUM_INPUT_SIZES * NUM_OUTPUT_SIZES)); + ADD_ALL_TESTS(test_shake256_x4_incremental, + (int)(NUM_INPUT_SIZES * NUM_OUTPUT_SIZES)); + + ADD_ALL_TESTS(test_shake128_x4_multi_absorb, (int)NUM_INPUT_SIZES); + ADD_ALL_TESTS(test_shake256_x4_multi_absorb, (int)NUM_INPUT_SIZES); + + ADD_ALL_TESTS(test_shake128_x4_multi_squeeze, (int)NUM_OUTPUT_SIZES); + ADD_ALL_TESTS(test_shake256_x4_multi_squeeze, (int)NUM_OUTPUT_SIZES); +#endif + + return 1; +}